Skip to content

Commit

Permalink
LexicalBlockNormalizer
Browse files Browse the repository at this point in the history
  • Loading branch information
zurfyx committed May 4, 2024
1 parent 3e117f8 commit 54d7282
Show file tree
Hide file tree
Showing 13 changed files with 859 additions and 12 deletions.
1 change: 1 addition & 0 deletions .flowconfig
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ module.name_mapper='^@lexical/plain-text$' -> '<PROJECT_ROOT>/packages/lexical-p
module.name_mapper='^@lexical/react/LexicalAutoEmbedPlugin$' -> '<PROJECT_ROOT>/packages/lexical-react/flow/LexicalAutoEmbedPlugin.js.flow'
module.name_mapper='^@lexical/react/LexicalAutoFocusPlugin$' -> '<PROJECT_ROOT>/packages/lexical-react/flow/LexicalAutoFocusPlugin.js.flow'
module.name_mapper='^@lexical/react/LexicalAutoLinkPlugin$' -> '<PROJECT_ROOT>/packages/lexical-react/flow/LexicalAutoLinkPlugin.js.flow'
module.name_mapper='^@lexical/react/LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL$' -> '<PROJECT_ROOT>/packages/lexical-react/flow/LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL.js.flow'
module.name_mapper='^@lexical/react/LexicalBlockWithAlignableContents$' -> '<PROJECT_ROOT>/packages/lexical-react/flow/LexicalBlockWithAlignableContents.js.flow'
module.name_mapper='^@lexical/react/LexicalCharacterLimitPlugin$' -> '<PROJECT_ROOT>/packages/lexical-react/flow/LexicalCharacterLimitPlugin.js.flow'
module.name_mapper='^@lexical/react/LexicalCheckListPlugin$' -> '<PROJECT_ROOT>/packages/lexical-react/flow/LexicalCheckListPlugin.js.flow'
Expand Down
3 changes: 3 additions & 0 deletions packages/lexical-devtools/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
"@lexical/react/LexicalAutoLinkPlugin": [
"../lexical-react/src/LexicalAutoLinkPlugin.ts"
],
"@lexical/react/LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL": [
"../lexical-react/src/LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL.tsx"
],
"@lexical/react/LexicalBlockWithAlignableContents": [
"../lexical-react/src/LexicalBlockWithAlignableContents.tsx"
],
Expand Down
10 changes: 4 additions & 6 deletions packages/lexical-playground/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ import {SharedAutocompleteContext} from './context/SharedAutocompleteContext';
import {SharedHistoryContext} from './context/SharedHistoryContext';
import Editor from './Editor';
import logo from './images/logo.svg';
import PlaygroundNodes from './nodes/PlaygroundNodes';
import {NODES} from './nodes/PlaygroundNodes';
import DocsPlugin from './plugins/DocsPlugin';
import PasteLogPlugin from './plugins/PasteLogPlugin';
import {TableContext} from './plugins/TablePlugin';
import TestRecorderPlugin from './plugins/TestRecorderPlugin';
import TypingPerfPlugin from './plugins/TypingPerfPlugin';
import Settings from './Settings';
import PlaygroundEditorTheme from './themes/PlaygroundEditorTheme';
import onError from './utils/onError';

console.warn(
'If you are profiling the playground app, please ensure you turn off the debug view. You can disable it by pressing on the settings control in the bottom-left of your screen and toggling the debug view setting.',
Expand Down Expand Up @@ -124,10 +125,8 @@ function App(): JSX.Element {
? undefined
: prepopulatedRichText,
namespace: 'Playground',
nodes: [...PlaygroundNodes],
onError: (error: Error) => {
throw error;
},
nodes: [...NODES],
onError,
theme: PlaygroundEditorTheme,
};

Expand All @@ -148,7 +147,6 @@ function App(): JSX.Element {
{isDevPlayground ? <DocsPlugin /> : null}
{isDevPlayground ? <PasteLogPlugin /> : null}
{isDevPlayground ? <TestRecorderPlugin /> : null}

{measureTypingPerf ? <TypingPerfPlugin /> : null}
</SharedAutocompleteContext>
</TableContext>
Expand Down
8 changes: 7 additions & 1 deletion packages/lexical-playground/src/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

import {AutoFocusPlugin} from '@lexical/react/LexicalAutoFocusPlugin';
import {LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL} from '@lexical/react/LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL';
import {CharacterLimitPlugin} from '@lexical/react/LexicalCharacterLimitPlugin';
import {CheckListPlugin} from '@lexical/react/LexicalCheckListPlugin';
import {ClearEditorPlugin} from '@lexical/react/LexicalClearEditorPlugin';
Expand All @@ -29,6 +30,7 @@ import {CAN_USE_DOM} from 'shared/canUseDOM';
import {createWebsocketProvider} from './collaboration';
import {useSettings} from './context/SettingsContext';
import {useSharedHistoryContext} from './context/SharedHistoryContext';
import {BLOCK_NODES} from './nodes/PlaygroundNodes';
import ActionsPlugin from './plugins/ActionsPlugin';
import AutocompletePlugin from './plugins/AutocompletePlugin';
import AutoEmbedPlugin from './plugins/AutoEmbedPlugin';
Expand Down Expand Up @@ -70,6 +72,7 @@ import TwitterPlugin from './plugins/TwitterPlugin';
import YouTubePlugin from './plugins/YouTubePlugin';
import ContentEditable from './ui/ContentEditable';
import Placeholder from './ui/Placeholder';
import onError from './utils/onError';

const skipCollaborationInit =
// @ts-expect-error
Expand Down Expand Up @@ -142,7 +145,6 @@ export default function Editor(): JSX.Element {
<ComponentPickerPlugin />
<EmojiPickerPlugin />
<AutoEmbedPlugin />

<MentionsPlugin />
<EmojisPlugin />
<HashtagPlugin />
Expand All @@ -152,6 +154,10 @@ export default function Editor(): JSX.Element {
<CommentPlugin
providerFactory={isCollab ? createWebsocketProvider : undefined}
/>
<LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL
blockNodes={BLOCK_NODES}
onError={onError}
/>
{isRichText ? (
<>
{isCollab ? (
Expand Down
19 changes: 17 additions & 2 deletions packages/lexical-playground/src/nodes/PlaygroundNodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ import {AutoLinkNode, LinkNode} from '@lexical/link';
import {ListItemNode, ListNode} from '@lexical/list';
import {MarkNode} from '@lexical/mark';
import {OverflowNode} from '@lexical/overflow';
import {BlockNodeKlass} from '@lexical/react/LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL';
import {HorizontalRuleNode} from '@lexical/react/LexicalHorizontalRuleNode';
import {HeadingNode, QuoteNode} from '@lexical/rich-text';
import {TableCellNode, TableNode, TableRowNode} from '@lexical/table';
import {DecoratorNode, ElementNode} from 'lexical';

import {CollapsibleContainerNode} from '../plugins/CollapsiblePlugin/CollapsibleContainerNode';
import {CollapsibleContentNode} from '../plugins/CollapsiblePlugin/CollapsibleContentNode';
Expand All @@ -38,7 +40,7 @@ import {StickyNode} from './StickyNode';
import {TweetNode} from './TweetNode';
import {YouTubeNode} from './YouTubeNode';

const PlaygroundNodes: Array<Klass<LexicalNode>> = [
export const NODES: Array<Klass<LexicalNode>> = [
HeadingNode,
ListNode,
ListItemNode,
Expand Down Expand Up @@ -75,4 +77,17 @@ const PlaygroundNodes: Array<Klass<LexicalNode>> = [
LayoutItemNode,
];

export default PlaygroundNodes;
export const BLOCK_NODES: Array<BlockNodeKlass<JSX.Element>> = [];
// The below snippet assumes that for every node, node.isInline() is hardcoded to either true or
// false, Lexical's recommendation.
for (const Node of NODES) {
if (
(Node === ElementNode ||
Node.prototype instanceof ElementNode ||
Node === DecoratorNode ||
Node.prototype instanceof DecoratorNode) &&
!Node.prototype.isInline()
) {
BLOCK_NODES.push(Node as BlockNodeKlass<JSX.Element>);
}
}
14 changes: 14 additions & 0 deletions packages/lexical-playground/src/utils/onError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/

export default function onError(error: Error | string) {
if (typeof error === 'string') {
throw new Error(error);
}
throw error;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict
*/

import type {ElementNode, DecoratorNode} from 'lexical';
import {LexicalEditor} from 'lexical';
import * as React from 'react';

export type BlockNode<T> = ElementNode | DecoratorNode<T>;
export type BlockNodeKlass<T> = Class<BlockNode<T>>;

declare export function LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL(props: {
onError?: (message: string) => void;
onInfo?: (message: string) => void;
blockNodes: Array<Class<React.Node>>;
}): React$Node;

declare export function registerBlockNodeNormalizerPlugin__EXPERIMENTAL<T>(
editor: LexicalEditor,
nodes: Array<Class<T>>, {
onError?: (message: string) => void;
onInfo?: (message: string) => void;
},
): () => void;
30 changes: 30 additions & 0 deletions packages/lexical-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,36 @@
"default": "./LexicalAutoLinkPlugin.js"
}
},
"./LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL": {
"import": {
"types": "./LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL.d.ts",
"development": "./LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL.dev.mjs",
"production": "./LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL.prod.mjs",
"node": "./LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL.node.mjs",
"default": "./LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL.mjs"
},
"require": {
"types": "./LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL.d.ts",
"development": "./LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL.dev.js",
"production": "./LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL.prod.js",
"default": "./LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL.js"
}
},
"./LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL.js": {
"import": {
"types": "./LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL.d.ts",
"development": "./LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL.dev.mjs",
"production": "./LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL.prod.mjs",
"node": "./LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL.node.mjs",
"default": "./LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL.mjs"
},
"require": {
"types": "./LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL.d.ts",
"development": "./LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL.dev.js",
"production": "./LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL.prod.js",
"default": "./LexicalBlockNodeNormalizerPlugin__EXPERIMENTAL.js"
}
},
"./LexicalBlockWithAlignableContents": {
"import": {
"types": "./LexicalBlockWithAlignableContents.d.ts",
Expand Down
Loading

0 comments on commit 54d7282

Please sign in to comment.