@datalayer/lexical-loro 0.0.3 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -137
- package/lib/App.d.ts +2 -0
- package/lib/App.js +141 -0
- package/lib/Editor.d.ts +2 -0
- package/lib/Editor.js +111 -0
- package/lib/Settings.d.ts +2 -0
- package/lib/Settings.js +57 -0
- package/lib/appSettings.d.ts +36 -0
- package/lib/appSettings.js +44 -0
- package/lib/collab/loro/Bindings.d.ts +41 -0
- package/lib/collab/loro/Bindings.js +95 -0
- package/lib/collab/loro/Debug.d.ts +33 -0
- package/lib/collab/loro/Debug.js +448 -0
- package/lib/collab/loro/LexicalCollaborationContext.d.ts +19 -0
- package/lib/collab/loro/LexicalCollaborationContext.js +48 -0
- package/lib/collab/loro/LexicalCollaborationPlugin.d.ts +24 -0
- package/lib/collab/loro/LexicalCollaborationPlugin.js +83 -0
- package/lib/collab/loro/State.d.ts +53 -0
- package/lib/collab/loro/State.js +90 -0
- package/lib/collab/loro/components/LoroCollaborationUI.d.ts +13 -0
- package/lib/collab/loro/components/LoroCollaborationUI.js +9 -0
- package/lib/collab/loro/components/LoroCollaborators.d.ts +8 -0
- package/lib/collab/loro/components/LoroCollaborators.js +97 -0
- package/lib/collab/loro/components/index.d.ts +2 -0
- package/lib/collab/loro/components/index.js +2 -0
- package/lib/collab/loro/index.d.ts +6 -0
- package/lib/collab/loro/index.js +6 -0
- package/lib/collab/loro/integrators/BaseIntegrator.d.ts +14 -0
- package/lib/collab/loro/integrators/BaseIntegrator.js +1 -0
- package/lib/collab/loro/integrators/CounterIntegrator.d.ts +23 -0
- package/lib/collab/loro/integrators/CounterIntegrator.js +40 -0
- package/lib/collab/loro/integrators/ListIntegrator.d.ts +23 -0
- package/lib/collab/loro/integrators/ListIntegrator.js +49 -0
- package/lib/collab/loro/integrators/MapIntegrator.d.ts +24 -0
- package/lib/collab/loro/integrators/MapIntegrator.js +177 -0
- package/lib/collab/loro/integrators/TextIntegrator.d.ts +25 -0
- package/lib/collab/loro/integrators/TextIntegrator.js +51 -0
- package/lib/collab/loro/integrators/TreeIntegrator.d.ts +25 -0
- package/lib/collab/loro/integrators/TreeIntegrator.js +201 -0
- package/lib/collab/loro/nodes/NodeFactory.d.ts +8 -0
- package/lib/collab/loro/nodes/NodeFactory.js +105 -0
- package/lib/collab/loro/nodes/NodesMapper.d.ts +111 -0
- package/lib/collab/loro/nodes/NodesMapper.js +258 -0
- package/lib/collab/loro/propagators/DecoratorNodePropagator.d.ts +60 -0
- package/lib/collab/loro/propagators/DecoratorNodePropagator.js +302 -0
- package/lib/collab/loro/propagators/ElementNodePropagator.d.ts +62 -0
- package/lib/collab/loro/propagators/ElementNodePropagator.js +335 -0
- package/lib/collab/loro/propagators/LineBreakNodePropagator.d.ts +57 -0
- package/lib/collab/loro/propagators/LineBreakNodePropagator.js +196 -0
- package/lib/collab/loro/propagators/RootNodePropagator.d.ts +55 -0
- package/lib/collab/loro/propagators/RootNodePropagator.js +168 -0
- package/lib/collab/loro/propagators/TextNodePropagator.d.ts +60 -0
- package/lib/collab/loro/propagators/TextNodePropagator.js +434 -0
- package/lib/collab/loro/propagators/index.d.ts +49 -0
- package/lib/collab/loro/propagators/index.js +32 -0
- package/lib/collab/loro/provider/websocket.d.ts +116 -0
- package/lib/collab/loro/provider/websocket.js +907 -0
- package/lib/collab/loro/servers/index.d.ts +0 -0
- package/lib/collab/loro/servers/index.js +0 -0
- package/lib/collab/loro/servers/ws/callback.d.ts +5 -0
- package/lib/collab/loro/servers/ws/callback.js +85 -0
- package/lib/collab/loro/servers/ws/server.d.ts +2 -0
- package/lib/collab/loro/servers/ws/server.js +25 -0
- package/lib/collab/loro/servers/ws/utils.d.ts +40 -0
- package/lib/collab/loro/servers/ws/utils.js +513 -0
- package/lib/collab/loro/sync/SyncCursors.d.ts +32 -0
- package/lib/collab/loro/sync/SyncCursors.js +435 -0
- package/lib/collab/loro/sync/SyncLexicalToLoro.d.ts +4 -0
- package/lib/collab/loro/sync/SyncLexicalToLoro.js +80 -0
- package/lib/collab/loro/sync/SyncLoroToLexical.d.ts +5 -0
- package/lib/collab/loro/sync/SyncLoroToLexical.js +96 -0
- package/lib/collab/loro/types/LexicalNodeData.d.ts +32 -0
- package/lib/collab/loro/types/LexicalNodeData.js +71 -0
- package/lib/collab/loro/useCollaboration.d.ts +12 -0
- package/lib/collab/loro/useCollaboration.js +248 -0
- package/lib/collab/loro/utils/InitialContent.d.ts +64 -0
- package/lib/collab/loro/utils/InitialContent.js +109 -0
- package/lib/collab/loro/utils/LexicalToLoro.d.ts +18 -0
- package/lib/collab/loro/utils/LexicalToLoro.js +96 -0
- package/lib/collab/loro/utils/Utils.d.ts +44 -0
- package/lib/collab/loro/utils/Utils.js +153 -0
- package/lib/collab/loro/wsProvider.d.ts +8 -0
- package/lib/collab/loro/wsProvider.js +31 -0
- package/lib/collab/utils/invariant.d.ts +1 -0
- package/lib/collab/utils/invariant.js +11 -0
- package/lib/collab/utils/simpleDiffWithCursor.d.ts +5 -0
- package/lib/collab/utils/simpleDiffWithCursor.js +31 -0
- package/lib/collab/yjs/Bindings.d.ts +23 -0
- package/lib/collab/yjs/Bindings.js +26 -0
- package/lib/collab/yjs/Debug.d.ts +23 -0
- package/lib/collab/yjs/Debug.js +213 -0
- package/lib/collab/yjs/LexicalCollaborationContext.d.ts +10 -0
- package/lib/collab/yjs/LexicalCollaborationContext.js +37 -0
- package/lib/collab/yjs/LexicalCollaborationPlugin.d.ts +21 -0
- package/lib/collab/yjs/LexicalCollaborationPlugin.js +63 -0
- package/lib/collab/yjs/State.d.ts +51 -0
- package/lib/collab/yjs/State.js +35 -0
- package/lib/collab/yjs/nodes/AnyCollabNode.d.ts +5 -0
- package/lib/collab/yjs/nodes/AnyCollabNode.js +1 -0
- package/lib/collab/yjs/nodes/CollabDecoratorNode.d.ts +22 -0
- package/lib/collab/yjs/nodes/CollabDecoratorNode.js +64 -0
- package/lib/collab/yjs/nodes/CollabElementNode.d.ts +40 -0
- package/lib/collab/yjs/nodes/CollabElementNode.js +462 -0
- package/lib/collab/yjs/nodes/CollabLineBreakNode.d.ts +19 -0
- package/lib/collab/yjs/nodes/CollabLineBreakNode.js +44 -0
- package/lib/collab/yjs/nodes/CollabTextNode.d.ts +25 -0
- package/lib/collab/yjs/nodes/CollabTextNode.js +103 -0
- package/lib/collab/yjs/provider/websocket.d.ts +88 -0
- package/lib/collab/yjs/provider/websocket.js +415 -0
- package/lib/collab/yjs/servers/index.d.ts +0 -0
- package/lib/collab/yjs/servers/index.js +0 -0
- package/lib/collab/yjs/servers/ws/callback.d.ts +5 -0
- package/lib/collab/yjs/servers/ws/callback.js +72 -0
- package/lib/collab/yjs/servers/ws/server.d.ts +2 -0
- package/lib/collab/yjs/servers/ws/server.js +25 -0
- package/lib/collab/yjs/servers/ws/utils.d.ts +49 -0
- package/lib/collab/yjs/servers/ws/utils.js +284 -0
- package/lib/collab/yjs/sync/SyncCursors.d.ts +39 -0
- package/lib/collab/yjs/sync/SyncCursors.js +351 -0
- package/lib/collab/yjs/sync/SyncEditorStates.d.ts +10 -0
- package/lib/collab/yjs/sync/SyncEditorStates.js +200 -0
- package/lib/collab/yjs/useCollaboration.d.ts +12 -0
- package/lib/collab/yjs/useCollaboration.js +255 -0
- package/lib/collab/yjs/utils/Utils.d.ts +25 -0
- package/lib/collab/yjs/utils/Utils.js +402 -0
- package/lib/collab/yjs/wsProvider.d.ts +3 -0
- package/lib/collab/yjs/wsProvider.js +21 -0
- package/lib/commenting/index.d.ts +41 -0
- package/lib/commenting/index.js +324 -0
- package/lib/context/FlashMessageContext.d.ts +7 -0
- package/lib/context/FlashMessageContext.js +24 -0
- package/lib/context/SettingsContext.d.ts +12 -0
- package/lib/context/SettingsContext.js +38 -0
- package/lib/context/SharedHistoryContext.d.ts +11 -0
- package/lib/context/SharedHistoryContext.js +11 -0
- package/lib/context/ToolbarContext.d.ts +65 -0
- package/lib/context/ToolbarContext.js +84 -0
- package/lib/demo.d.ts +12 -0
- package/lib/demo.js +41 -0
- package/lib/hooks/useFlashMessage.d.ts +2 -0
- package/lib/hooks/useFlashMessage.js +4 -0
- package/lib/hooks/useModal.d.ts +5 -0
- package/lib/hooks/useModal.js +26 -0
- package/lib/hooks/useReport.d.ts +1 -0
- package/lib/hooks/useReport.js +46 -0
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -5
- package/lib/nodes/AutocompleteNode.d.ts +27 -0
- package/lib/nodes/AutocompleteNode.js +56 -0
- package/lib/nodes/CounterComponent.d.ts +6 -0
- package/lib/nodes/CounterComponent.js +137 -0
- package/lib/nodes/CounterNode.d.ts +23 -0
- package/lib/nodes/CounterNode.js +47 -0
- package/lib/nodes/DateTimeNode/DateTimeComponent.d.ts +8 -0
- package/lib/nodes/DateTimeNode/DateTimeComponent.js +119 -0
- package/lib/nodes/DateTimeNode/DateTimeNode.d.ts +27 -0
- package/lib/nodes/DateTimeNode/DateTimeNode.js +82 -0
- package/lib/nodes/EmojiNode.d.ts +18 -0
- package/lib/nodes/EmojiNode.js +50 -0
- package/lib/nodes/EquationComponent.d.ts +9 -0
- package/lib/nodes/EquationComponent.js +75 -0
- package/lib/nodes/EquationNode.d.ts +26 -0
- package/lib/nodes/EquationNode.js +109 -0
- package/lib/nodes/ExcalidrawNode/ExcalidrawComponent.d.ts +8 -0
- package/lib/nodes/ExcalidrawNode/ExcalidrawComponent.js +110 -0
- package/lib/nodes/ExcalidrawNode/ExcalidrawImage.d.ts +50 -0
- package/lib/nodes/ExcalidrawNode/ExcalidrawImage.js +55 -0
- package/lib/nodes/ExcalidrawNode/index.d.ts +32 -0
- package/lib/nodes/ExcalidrawNode/index.js +117 -0
- package/lib/nodes/FigmaNode.d.ts +20 -0
- package/lib/nodes/FigmaNode.js +52 -0
- package/lib/nodes/ImageComponent.d.ts +16 -0
- package/lib/nodes/ImageComponent.js +272 -0
- package/lib/nodes/ImageNode.d.ts +50 -0
- package/lib/nodes/ImageNode.js +151 -0
- package/lib/nodes/InlineImageNode/InlineImageComponent.d.ts +26 -0
- package/lib/nodes/InlineImageNode/InlineImageComponent.js +161 -0
- package/lib/nodes/InlineImageNode/InlineImageNode.d.ts +59 -0
- package/lib/nodes/InlineImageNode/InlineImageNode.js +162 -0
- package/lib/nodes/KeywordNode.d.ts +14 -0
- package/lib/nodes/KeywordNode.js +33 -0
- package/lib/nodes/LayoutContainerNode.d.ts +24 -0
- package/lib/nodes/LayoutContainerNode.js +91 -0
- package/lib/nodes/LayoutItemNode.d.ts +16 -0
- package/lib/nodes/LayoutItemNode.js +65 -0
- package/lib/nodes/MentionNode.d.ts +20 -0
- package/lib/nodes/MentionNode.js +81 -0
- package/lib/nodes/PageBreakNode/index.d.ts +17 -0
- package/lib/nodes/PageBreakNode/index.js +83 -0
- package/lib/nodes/PlaygroundNodes.d.ts +3 -0
- package/lib/nodes/PlaygroundNodes.js +71 -0
- package/lib/nodes/PollComponent.d.ts +9 -0
- package/lib/nodes/PollComponent.js +85 -0
- package/lib/nodes/PollNode.d.ts +43 -0
- package/lib/nodes/PollNode.js +153 -0
- package/lib/nodes/SpecialTextNode.d.ts +24 -0
- package/lib/nodes/SpecialTextNode.js +50 -0
- package/lib/nodes/StickyComponent.d.ts +10 -0
- package/lib/nodes/StickyComponent.js +162 -0
- package/lib/nodes/StickyNode.d.ts +31 -0
- package/lib/nodes/StickyNode.js +76 -0
- package/lib/nodes/TweetNode.d.ts +21 -0
- package/lib/nodes/TweetNode.js +119 -0
- package/lib/nodes/YouTubeNode.d.ts +22 -0
- package/lib/nodes/YouTubeNode.js +84 -0
- package/lib/plugins/ActionsPlugin/index.d.ts +5 -0
- package/lib/plugins/ActionsPlugin/index.js +168 -0
- package/lib/plugins/AutoEmbedPlugin/index.d.ts +19 -0
- package/lib/plugins/AutoEmbedPlugin/index.js +158 -0
- package/lib/plugins/AutoLinkPlugin/index.d.ts +2 -0
- package/lib/plugins/AutoLinkPlugin/index.js +15 -0
- package/lib/plugins/AutocompletePlugin/index.d.ts +10 -0
- package/lib/plugins/AutocompletePlugin/index.js +2473 -0
- package/lib/plugins/CodeActionMenuPlugin/components/CopyButton/index.d.ts +7 -0
- package/lib/plugins/CodeActionMenuPlugin/components/CopyButton/index.js +42 -0
- package/lib/plugins/CodeActionMenuPlugin/components/PrettierButton/index.d.ts +17 -0
- package/lib/plugins/CodeActionMenuPlugin/components/PrettierButton/index.js +111 -0
- package/lib/plugins/CodeActionMenuPlugin/index.d.ts +5 -0
- package/lib/plugins/CodeActionMenuPlugin/index.js +104 -0
- package/lib/plugins/CodeActionMenuPlugin/utils.d.ts +1 -0
- package/lib/plugins/CodeActionMenuPlugin/utils.js +18 -0
- package/lib/plugins/CodeHighlightPrismPlugin/index.d.ts +2 -0
- package/lib/plugins/CodeHighlightPrismPlugin/index.js +10 -0
- package/lib/plugins/CodeHighlightShikiPlugin/index.d.ts +2 -0
- package/lib/plugins/CodeHighlightShikiPlugin/index.js +10 -0
- package/lib/plugins/CollapsiblePlugin/CollapsibleContainerNode.d.ts +25 -0
- package/lib/plugins/CollapsiblePlugin/CollapsibleContainerNode.js +131 -0
- package/lib/plugins/CollapsiblePlugin/CollapsibleContentNode.d.ts +16 -0
- package/lib/plugins/CollapsiblePlugin/CollapsibleContentNode.js +79 -0
- package/lib/plugins/CollapsiblePlugin/CollapsibleTitleNode.d.ts +16 -0
- package/lib/plugins/CollapsiblePlugin/CollapsibleTitleNode.js +81 -0
- package/lib/plugins/CollapsiblePlugin/CollapsibleUtils.d.ts +2 -0
- package/lib/plugins/CollapsiblePlugin/CollapsibleUtils.js +8 -0
- package/lib/plugins/CollapsiblePlugin/index.d.ts +3 -0
- package/lib/plugins/CollapsiblePlugin/index.js +128 -0
- package/lib/plugins/CommentPlugin/index.d.ts +9 -0
- package/lib/plugins/CommentPlugin/index.js +460 -0
- package/lib/plugins/ComponentPickerPlugin/index.d.ts +2 -0
- package/lib/plugins/ComponentPickerPlugin/index.js +276 -0
- package/lib/plugins/ContextMenuPlugin/index.d.ts +2 -0
- package/lib/plugins/ContextMenuPlugin/index.js +112 -0
- package/lib/plugins/CounterPlugin/index.d.ts +3 -0
- package/lib/plugins/CounterPlugin/index.js +20 -0
- package/lib/plugins/DatalayerPlugin/index.d.ts +2 -0
- package/lib/plugins/DatalayerPlugin/index.js +218 -0
- package/lib/plugins/DateTimePlugin/index.d.ts +8 -0
- package/lib/plugins/DateTimePlugin/index.js +24 -0
- package/lib/plugins/DocsPlugin/index.d.ts +2 -0
- package/lib/plugins/DocsPlugin/index.js +4 -0
- package/lib/plugins/DragDropPastePlugin/index.d.ts +1 -0
- package/lib/plugins/DragDropPastePlugin/index.js +33 -0
- package/lib/plugins/DraggableBlockPlugin/index.d.ts +12 -0
- package/lib/plugins/DraggableBlockPlugin/index.js +36 -0
- package/lib/plugins/EmojiPickerPlugin/index.d.ts +1 -0
- package/lib/plugins/EmojiPickerPlugin/index.js +80 -0
- package/lib/plugins/EmojisPlugin/index.d.ts +2 -0
- package/lib/plugins/EmojisPlugin/index.js +52 -0
- package/lib/plugins/EquationsPlugin/index.d.ts +14 -0
- package/lib/plugins/EquationsPlugin/index.js +34 -0
- package/lib/plugins/ExcalidrawPlugin/index.d.ts +5 -0
- package/lib/plugins/ExcalidrawPlugin/index.js +44 -0
- package/lib/plugins/FigmaPlugin/index.d.ts +4 -0
- package/lib/plugins/FigmaPlugin/index.js +20 -0
- package/lib/plugins/FloatingLinkEditorPlugin/index.d.ts +15 -0
- package/lib/plugins/FloatingLinkEditorPlugin/index.js +280 -0
- package/lib/plugins/FloatingTextFormatToolbarPlugin/index.d.ts +7 -0
- package/lib/plugins/FloatingTextFormatToolbarPlugin/index.js +219 -0
- package/lib/plugins/ImagesPlugin/index.d.ts +24 -0
- package/lib/plugins/ImagesPlugin/index.js +195 -0
- package/lib/plugins/InlineImagePlugin/index.d.ts +17 -0
- package/lib/plugins/InlineImagePlugin/index.js +180 -0
- package/lib/plugins/KeywordsPlugin/index.d.ts +2 -0
- package/lib/plugins/KeywordsPlugin/index.js +31 -0
- package/lib/plugins/LayoutPlugin/InsertLayoutDialog.d.ts +6 -0
- package/lib/plugins/LayoutPlugin/InsertLayoutDialog.js +21 -0
- package/lib/plugins/LayoutPlugin/LayoutPlugin.d.ts +7 -0
- package/lib/plugins/LayoutPlugin/LayoutPlugin.js +131 -0
- package/lib/plugins/LinkPlugin/index.d.ts +6 -0
- package/lib/plugins/LinkPlugin/index.js +11 -0
- package/lib/plugins/MarkdownShortcutPlugin/index.d.ts +2 -0
- package/lib/plugins/MarkdownShortcutPlugin/index.js +6 -0
- package/lib/plugins/MarkdownTransformers/index.d.ts +8 -0
- package/lib/plugins/MarkdownTransformers/index.js +234 -0
- package/lib/plugins/MaxLengthPlugin/index.d.ts +3 -0
- package/lib/plugins/MaxLengthPlugin/index.js +37 -0
- package/lib/plugins/MentionsPlugin/index.d.ts +2 -0
- package/lib/plugins/MentionsPlugin/index.js +564 -0
- package/lib/plugins/PageBreakPlugin/index.d.ts +4 -0
- package/lib/plugins/PageBreakPlugin/index.js +27 -0
- package/lib/plugins/PasteLogPlugin/index.d.ts +2 -0
- package/lib/plugins/PasteLogPlugin/index.js +27 -0
- package/lib/plugins/PollPlugin/index.d.ts +8 -0
- package/lib/plugins/PollPlugin/index.js +38 -0
- package/lib/plugins/ShortcutsPlugin/index.d.ts +6 -0
- package/lib/plugins/ShortcutsPlugin/index.js +112 -0
- package/lib/plugins/ShortcutsPlugin/shortcuts.d.ts +59 -0
- package/lib/plugins/ShortcutsPlugin/shortcuts.js +169 -0
- package/lib/plugins/SpecialTextPlugin/index.d.ts +2 -0
- package/lib/plugins/SpecialTextPlugin/index.js +46 -0
- package/lib/plugins/SpeechToTextPlugin/index.d.ts +5 -0
- package/lib/plugins/SpeechToTextPlugin/index.js +82 -0
- package/lib/plugins/StickyPlugin/index.d.ts +2 -0
- package/lib/plugins/StickyPlugin/index.js +12 -0
- package/lib/plugins/TabFocusPlugin/index.d.ts +1 -0
- package/lib/plugins/TabFocusPlugin/index.js +34 -0
- package/lib/plugins/TableActionMenuPlugin/index.d.ts +5 -0
- package/lib/plugins/TableActionMenuPlugin/index.js +492 -0
- package/lib/plugins/TableCellResizer/index.d.ts +3 -0
- package/lib/plugins/TableCellResizer/index.js +297 -0
- package/lib/plugins/TableHoverActionsPlugin/index.d.ts +4 -0
- package/lib/plugins/TableHoverActionsPlugin/index.js +188 -0
- package/lib/plugins/TableOfContentsPlugin/index.d.ts +2 -0
- package/lib/plugins/TableOfContentsPlugin/index.js +116 -0
- package/lib/plugins/TablePlugin.d.ts +31 -0
- package/lib/plugins/TablePlugin.js +63 -0
- package/lib/plugins/TestRecorderPlugin/index.d.ts +3 -0
- package/lib/plugins/TestRecorderPlugin/index.js +346 -0
- package/lib/plugins/ToolbarPlugin/fontSize.d.ts +9 -0
- package/lib/plugins/ToolbarPlugin/fontSize.js +80 -0
- package/lib/plugins/ToolbarPlugin/index.d.ts +9 -0
- package/lib/plugins/ToolbarPlugin/index.js +500 -0
- package/lib/plugins/ToolbarPlugin/utils.d.ts +26 -0
- package/lib/plugins/ToolbarPlugin/utils.js +243 -0
- package/lib/plugins/TreeViewPlugin/index.d.ts +2 -0
- package/lib/plugins/TreeViewPlugin/index.js +7 -0
- package/lib/plugins/TwitterPlugin/index.d.ts +4 -0
- package/lib/plugins/TwitterPlugin/index.js +20 -0
- package/lib/plugins/TypingPerfPlugin/index.d.ts +2 -0
- package/lib/plugins/TypingPerfPlugin/index.js +93 -0
- package/lib/plugins/YouTubePlugin/index.d.ts +4 -0
- package/lib/plugins/YouTubePlugin/index.js +20 -0
- package/lib/server/validation.d.ts +1 -0
- package/lib/server/validation.js +111 -0
- package/lib/setupEnv.d.ts +2 -0
- package/lib/setupEnv.js +25 -0
- package/lib/themes/CommentEditorTheme.d.ts +4 -0
- package/lib/themes/CommentEditorTheme.js +7 -0
- package/lib/themes/PlaygroundEditorTheme.d.ts +4 -0
- package/lib/themes/PlaygroundEditorTheme.js +120 -0
- package/lib/themes/StickyEditorTheme.d.ts +4 -0
- package/lib/themes/StickyEditorTheme.js +7 -0
- package/lib/tyes.dt.d.ts +12 -0
- package/lib/tyes.dt.js +0 -0
- package/lib/ui/Button.d.ts +12 -0
- package/lib/ui/Button.js +6 -0
- package/lib/ui/ColorPicker.d.ts +14 -0
- package/lib/ui/ColorPicker.js +219 -0
- package/lib/ui/ContentEditable.d.ts +9 -0
- package/lib/ui/ContentEditable.js +6 -0
- package/lib/ui/Dialog.d.ts +10 -0
- package/lib/ui/Dialog.js +8 -0
- package/lib/ui/DropDown.d.ts +18 -0
- package/lib/ui/DropDown.js +133 -0
- package/lib/ui/DropdownColorPicker.d.ts +13 -0
- package/lib/ui/DropdownColorPicker.js +6 -0
- package/lib/ui/EquationEditor.d.ts +8 -0
- package/lib/ui/EquationEditor.js +11 -0
- package/lib/ui/ExcalidrawModal.d.ts +42 -0
- package/lib/ui/ExcalidrawModal.js +103 -0
- package/lib/ui/FileInput.d.ts +10 -0
- package/lib/ui/FileInput.js +5 -0
- package/lib/ui/FlashMessage.d.ts +7 -0
- package/lib/ui/FlashMessage.js +6 -0
- package/lib/ui/ImageResizer.d.ts +17 -0
- package/lib/ui/ImageResizer.js +171 -0
- package/lib/ui/KatexEquationAlterer.d.ts +8 -0
- package/lib/ui/KatexEquationAlterer.js +23 -0
- package/lib/ui/KatexRenderer.d.ts +6 -0
- package/lib/ui/KatexRenderer.js +24 -0
- package/lib/ui/Modal.d.ts +9 -0
- package/lib/ui/Modal.js +48 -0
- package/lib/ui/Select.d.ts +8 -0
- package/lib/ui/Select.js +5 -0
- package/lib/ui/Switch.d.ts +8 -0
- package/lib/ui/Switch.js +6 -0
- package/lib/ui/TextInput.d.ts +13 -0
- package/lib/ui/TextInput.js +7 -0
- package/lib/utils/docSerialization.d.ts +3 -0
- package/lib/utils/docSerialization.js +56 -0
- package/lib/utils/emoji-list.d.ts +20 -0
- package/lib/utils/emoji-list.js +16605 -0
- package/lib/utils/getDOMRangeRect.d.ts +8 -0
- package/lib/utils/getDOMRangeRect.js +22 -0
- package/lib/utils/getSelectedNode.d.ts +2 -0
- package/lib/utils/getSelectedNode.js +24 -0
- package/lib/utils/getThemeSelector.d.ts +2 -0
- package/lib/utils/getThemeSelector.js +10 -0
- package/lib/utils/isMobileWidth.d.ts +7 -0
- package/lib/utils/isMobileWidth.js +7 -0
- package/lib/utils/joinClasses.d.ts +1 -0
- package/lib/utils/joinClasses.js +3 -0
- package/lib/utils/setFloatingElemPosition.d.ts +1 -0
- package/lib/utils/setFloatingElemPosition.js +55 -0
- package/lib/utils/setFloatingElemPositionForLinkEditor.d.ts +1 -0
- package/lib/utils/setFloatingElemPositionForLinkEditor.js +32 -0
- package/lib/utils/swipe.d.ts +4 -0
- package/lib/utils/swipe.js +90 -0
- package/lib/utils/url.d.ts +2 -0
- package/lib/utils/url.js +27 -0
- package/package.json +84 -50
- package/lib/LoroCollaborativePlugin.d.ts +0 -16
- package/lib/LoroCollaborativePlugin.js +0 -2503
package/README.md
CHANGED
|
@@ -305,151 +305,38 @@ The examples include:
|
|
|
305
305
|
|
|
306
306
|
See `src/examples/README.md` for detailed example documentation.
|
|
307
307
|
|
|
308
|
-
## Project Structure
|
|
309
|
-
|
|
310
|
-
### Core Components
|
|
311
|
-
|
|
312
|
-
```
|
|
313
|
-
src/
|
|
314
|
-
├── LoroCollaborativePlugin.tsx # Main Lexical plugin for collaboration
|
|
315
|
-
└── vite-env.d.ts # TypeScript definitions
|
|
316
|
-
|
|
317
|
-
lexical_loro/ # Python WebSocket server package
|
|
318
|
-
├── __init__.py # Package exports
|
|
319
|
-
├── server.py # WebSocket server implementation
|
|
320
|
-
├── cli.py # Command line interface
|
|
321
|
-
├── model/
|
|
322
|
-
│ └── lexical_model.py # Standalone LexicalModel library
|
|
323
|
-
└── tests/ # Python test suite
|
|
324
|
-
|
|
325
|
-
docs/
|
|
326
|
-
└── LEXICAL_MODEL_GUIDE.md # Comprehensive library documentation
|
|
327
|
-
|
|
328
|
-
examples/
|
|
329
|
-
├── memory_only_example.py # Basic LexicalModel usage
|
|
330
|
-
├── file_sync_example.py # File persistence example
|
|
331
|
-
├── collaboration_example.py # Collaborative editing simulation
|
|
332
|
-
└── README.md # Examples documentation
|
|
333
|
-
|
|
334
|
-
pyproject.toml # Python package configuration
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
### Examples Directory
|
|
338
|
-
|
|
339
|
-
```
|
|
340
|
-
src/examples/ # Complete demo application
|
|
341
|
-
├── App.tsx # Demo app with dual editors
|
|
342
|
-
├── LexicalCollaborativeEditor.tsx # Rich text editor example
|
|
343
|
-
├── TextAreaCollaborativeEditor.tsx # Simple text editor example
|
|
344
|
-
├── ServerSelector.tsx # Server selection UI
|
|
345
|
-
├── LexicalToolbar.tsx # Rich text toolbar
|
|
346
|
-
├── main.tsx # Demo app entry point
|
|
347
|
-
└── *.css # Styling for examples
|
|
348
|
-
|
|
349
|
-
servers/
|
|
350
|
-
└── server.ts # Node.js server (for comparison)
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
### Archive
|
|
354
|
-
|
|
355
|
-
```
|
|
356
|
-
src/archive/ # Historical plugin implementations
|
|
357
|
-
├── LoroCollaborativePlugin0.tsx # Previous versions for reference
|
|
358
|
-
├── LoroCollaborativePlugin1.tsx
|
|
359
|
-
├── LoroCollaborativePlugin2.tsx
|
|
360
|
-
├── LoroCollaborativePlugin3.tsx
|
|
361
|
-
├── LoroCollaborativePlugin4.tsx
|
|
362
|
-
└── LoroCollaborativePlugin5.tsx
|
|
363
|
-
```
|
|
364
|
-
|
|
365
308
|
## Architecture
|
|
366
309
|
|
|
367
|
-
For detailed architecture documentation, see [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md).
|
|
368
|
-
|
|
369
|
-
### System Overview
|
|
370
|
-
|
|
371
|
-
The collaboration system consists of three main components:
|
|
372
|
-
|
|
373
|
-
1. **LoroCollaborativePlugin** (Client-side) - Lexical integration
|
|
374
|
-
2. **LoroWebSocketServer** (Server-side) - Real-time synchronization
|
|
375
|
-
3. **LexicalModel** (Standalone Library) - Independent document model
|
|
376
|
-
|
|
377
|
-
### Data Flow
|
|
378
|
-
|
|
379
310
|
```
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
311
|
+
EDITOR 1 EDITOR 2
|
|
312
|
+
|
|
313
|
+
loro loro
|
|
314
|
+
- node(data: root(1)) - node(data: root(12))
|
|
315
|
+
- node(data: element(2)) - node(data: element(22))
|
|
316
|
+
- node(data: text(3)) - node(data: text(13))
|
|
317
|
+
- node(data: counter(4)) - node(data: counter(4))
|
|
318
|
+
|
|
319
|
+
<---- loro updates via websocket ------>
|
|
320
|
+
<---- loro node ids are the same ------>
|
|
321
|
+
<---- lexical node keys are different ------>
|
|
322
|
+
|
|
323
|
+
lexical lexical
|
|
324
|
+
- root(1) - root(12)
|
|
325
|
+
- element(2) - element(22)
|
|
326
|
+
- text(3) - text(13)
|
|
327
|
+
- counter(4) - counter(49)
|
|
383
328
|
```
|
|
384
329
|
|
|
385
|
-
##
|
|
386
|
-
|
|
387
|
-
For detailed configuration options, see [`docs/API.md`](docs/API.md).
|
|
388
|
-
|
|
389
|
-
### Quick Configuration
|
|
390
|
-
|
|
391
|
-
```tsx
|
|
392
|
-
// Plugin configuration
|
|
393
|
-
<LoroCollaborativePlugin
|
|
394
|
-
websocketUrl="ws://localhost:8081"
|
|
395
|
-
docId="my-document"
|
|
396
|
-
username="user123"
|
|
397
|
-
debug={true}
|
|
398
|
-
/>
|
|
399
|
-
```
|
|
400
|
-
|
|
401
|
-
```bash
|
|
402
|
-
# Server configuration
|
|
403
|
-
lexical-loro-server --port 8081 --log-level DEBUG
|
|
404
|
-
```
|
|
405
|
-
|
|
406
|
-
## Development
|
|
407
|
-
|
|
408
|
-
For comprehensive development guidelines, see [`docs/DEVELOPMENT.md`](docs/DEVELOPMENT.md).
|
|
409
|
-
|
|
410
|
-
### Quick Start
|
|
411
|
-
|
|
412
|
-
```bash
|
|
413
|
-
# Install dependencies
|
|
414
|
-
npm install
|
|
415
|
-
pip install -e ".[dev]"
|
|
416
|
-
|
|
417
|
-
# Run tests
|
|
418
|
-
npm test
|
|
419
|
-
npm run test:py
|
|
420
|
-
|
|
421
|
-
# Start development server
|
|
422
|
-
lexical-loro-server --log-level DEBUG
|
|
423
|
-
```
|
|
424
|
-
|
|
425
|
-
## Contributing
|
|
426
|
-
|
|
427
|
-
We welcome contributions! Please see [`docs/DEVELOPMENT.md`](docs/DEVELOPMENT.md) for detailed guidelines.
|
|
428
|
-
|
|
429
|
-
### Quick Contributing Guide
|
|
430
|
-
|
|
431
|
-
1. Fork the repository
|
|
432
|
-
2. Create a feature branch
|
|
433
|
-
3. Focus changes on core components
|
|
434
|
-
4. Add tests for new functionality
|
|
435
|
-
5. Update documentation as needed
|
|
436
|
-
6. Submit a pull request
|
|
330
|
+
## Examples
|
|
437
331
|
|
|
438
|
-
|
|
332
|
+
Loro examples
|
|
439
333
|
|
|
440
|
-
-
|
|
441
|
-
- **[Initialization Guide](docs/INITIALIZATION_GUIDE.md)** - Best practices for setup
|
|
442
|
-
- **[Architecture](docs/ARCHITECTURE.md)** - System design and data flow
|
|
443
|
-
- **[Development Guide](docs/DEVELOPMENT.md)** - Contributing and development setup
|
|
444
|
-
- **[LexicalModel Guide](docs/LEXICAL_MODEL_GUIDE.md)** - Standalone library documentation
|
|
334
|
+
- http://localhost:3000/?isCollab=true
|
|
445
335
|
|
|
446
|
-
|
|
336
|
+
- http://localhost:3000/split/?isCollab=true
|
|
447
337
|
|
|
448
|
-
|
|
338
|
+
Y.js examples (for reference)
|
|
449
339
|
|
|
450
|
-
|
|
340
|
+
- http://localhost:3000/?isCollab=true&useYjs=true
|
|
451
341
|
|
|
452
|
-
-
|
|
453
|
-
- [Lexical](https://lexical.dev/) - Facebook's extensible text editor framework
|
|
454
|
-
- [React](https://reactjs.org/) - UI library for plugin hooks
|
|
455
|
-
- [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) - Real-time communication
|
|
342
|
+
- http://localhost:3000/split/?isCollab=true&useYjs=true
|
package/lib/App.d.ts
ADDED
package/lib/App.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { $createLinkNode } from '@lexical/link';
|
|
3
|
+
import { $createListItemNode, $createListNode } from '@lexical/list';
|
|
4
|
+
import { LexicalComposer } from '@lexical/react/LexicalComposer';
|
|
5
|
+
import { $createHeadingNode, $createQuoteNode } from '@lexical/rich-text';
|
|
6
|
+
import { $createParagraphNode, $createTextNode, $getRoot, $isTextNode, TextNode, } from 'lexical';
|
|
7
|
+
import { isDevPlayground } from './appSettings';
|
|
8
|
+
import { FlashMessageContext } from './context/FlashMessageContext';
|
|
9
|
+
import { SettingsContext, useSettings } from './context/SettingsContext';
|
|
10
|
+
import { SharedHistoryContext } from './context/SharedHistoryContext';
|
|
11
|
+
import { ToolbarContext } from './context/ToolbarContext';
|
|
12
|
+
import Editor from './Editor';
|
|
13
|
+
import PlaygroundNodes from './nodes/PlaygroundNodes';
|
|
14
|
+
import DocsPlugin from './plugins/DocsPlugin';
|
|
15
|
+
import PasteLogPlugin from './plugins/PasteLogPlugin';
|
|
16
|
+
import { TableContext } from './plugins/TablePlugin';
|
|
17
|
+
import TestRecorderPlugin from './plugins/TestRecorderPlugin';
|
|
18
|
+
import { parseAllowedFontSize } from './plugins/ToolbarPlugin/fontSize';
|
|
19
|
+
import TypingPerfPlugin from './plugins/TypingPerfPlugin';
|
|
20
|
+
import Settings from './Settings';
|
|
21
|
+
import PlaygroundEditorTheme from './themes/PlaygroundEditorTheme';
|
|
22
|
+
import { parseAllowedColor } from './ui/ColorPicker';
|
|
23
|
+
import logo from './images/logo.svg';
|
|
24
|
+
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.');
|
|
25
|
+
function $prepopulatedRichText() {
|
|
26
|
+
const root = $getRoot();
|
|
27
|
+
if (root.getFirstChild() === null) {
|
|
28
|
+
const heading = $createHeadingNode('h1');
|
|
29
|
+
heading.append($createTextNode('Welcome to the playground'));
|
|
30
|
+
root.append(heading);
|
|
31
|
+
const quote = $createQuoteNode();
|
|
32
|
+
quote.append($createTextNode(`In case you were wondering what the black box at the bottom is – it's the debug view, showing the current state of the editor. ` +
|
|
33
|
+
`You can disable it by pressing on the settings control in the bottom-left of your screen and toggling the debug view setting.`));
|
|
34
|
+
root.append(quote);
|
|
35
|
+
const paragraph = $createParagraphNode();
|
|
36
|
+
paragraph.append($createTextNode('The playground is a demo environment built with '), $createTextNode('@lexical/react').toggleFormat('code'), $createTextNode('.'), $createTextNode(' Try typing in '), $createTextNode('some text').toggleFormat('bold'), $createTextNode(' with '), $createTextNode('different').toggleFormat('italic'), $createTextNode(' formats.'));
|
|
37
|
+
root.append(paragraph);
|
|
38
|
+
const paragraph2 = $createParagraphNode();
|
|
39
|
+
paragraph2.append($createTextNode('Make sure to check out the various plugins in the toolbar. You can also use #hashtags or @-mentions too!'));
|
|
40
|
+
root.append(paragraph2);
|
|
41
|
+
const paragraph3 = $createParagraphNode();
|
|
42
|
+
paragraph3.append($createTextNode(`If you'd like to find out more about Lexical, you can:`));
|
|
43
|
+
root.append(paragraph3);
|
|
44
|
+
const list = $createListNode('bullet');
|
|
45
|
+
list.append($createListItemNode().append($createTextNode(`Visit the `), $createLinkNode('https://lexical.dev/').append($createTextNode('Lexical website')), $createTextNode(` for documentation and more information.`)), $createListItemNode().append($createTextNode(`Check out the code on our `), $createLinkNode('https://github.com/facebook/lexical').append($createTextNode('GitHub repository')), $createTextNode(`.`)), $createListItemNode().append($createTextNode(`Playground code can be found `), $createLinkNode('https://github.com/facebook/lexical/tree/main/packages/lexical-playground').append($createTextNode('here')), $createTextNode(`.`)), $createListItemNode().append($createTextNode(`Join our `), $createLinkNode('https://discord.com/invite/KmG4wQnnD9').append($createTextNode('Discord Server')), $createTextNode(` and chat with the team.`)));
|
|
46
|
+
root.append(list);
|
|
47
|
+
const paragraph4 = $createParagraphNode();
|
|
48
|
+
paragraph4.append($createTextNode(`Lastly, we're constantly adding cool new features to this playground. So make sure you check back here when you next get a chance :).`));
|
|
49
|
+
root.append(paragraph4);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function getExtraStyles(element) {
|
|
53
|
+
// Parse styles from pasted input, but only if they match exactly the
|
|
54
|
+
// sort of styles that would be produced by exportDOM
|
|
55
|
+
let extraStyles = '';
|
|
56
|
+
const fontSize = parseAllowedFontSize(element.style.fontSize);
|
|
57
|
+
const backgroundColor = parseAllowedColor(element.style.backgroundColor);
|
|
58
|
+
const color = parseAllowedColor(element.style.color);
|
|
59
|
+
if (fontSize !== '' && fontSize !== '15px') {
|
|
60
|
+
extraStyles += `font-size: ${fontSize};`;
|
|
61
|
+
}
|
|
62
|
+
if (backgroundColor !== '' && backgroundColor !== 'rgb(255, 255, 255)') {
|
|
63
|
+
extraStyles += `background-color: ${backgroundColor};`;
|
|
64
|
+
}
|
|
65
|
+
if (color !== '' && color !== 'rgb(0, 0, 0)') {
|
|
66
|
+
extraStyles += `color: ${color};`;
|
|
67
|
+
}
|
|
68
|
+
return extraStyles;
|
|
69
|
+
}
|
|
70
|
+
function buildImportMap() {
|
|
71
|
+
const importMap = {};
|
|
72
|
+
// Wrap all TextNode importers with a function that also imports
|
|
73
|
+
// the custom styles implemented by the playground
|
|
74
|
+
for (const [tag, fn] of Object.entries(TextNode.importDOM() || {})) {
|
|
75
|
+
importMap[tag] = (importNode) => {
|
|
76
|
+
const importer = fn(importNode);
|
|
77
|
+
if (!importer) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
...importer,
|
|
82
|
+
conversion: (element) => {
|
|
83
|
+
const output = importer.conversion(element);
|
|
84
|
+
if (output === null ||
|
|
85
|
+
output.forChild === undefined ||
|
|
86
|
+
output.after !== undefined ||
|
|
87
|
+
output.node !== null) {
|
|
88
|
+
return output;
|
|
89
|
+
}
|
|
90
|
+
const extraStyles = getExtraStyles(element);
|
|
91
|
+
if (extraStyles) {
|
|
92
|
+
const { forChild } = output;
|
|
93
|
+
return {
|
|
94
|
+
...output,
|
|
95
|
+
forChild: (child, parent) => {
|
|
96
|
+
const textNode = forChild(child, parent);
|
|
97
|
+
if ($isTextNode(textNode)) {
|
|
98
|
+
textNode.setStyle(textNode.getStyle() + extraStyles);
|
|
99
|
+
}
|
|
100
|
+
return textNode;
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
return output;
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
return importMap;
|
|
110
|
+
}
|
|
111
|
+
function App() {
|
|
112
|
+
const { settings: { isCollab, emptyEditor, measureTypingPerf }, } = useSettings();
|
|
113
|
+
const initialConfig = {
|
|
114
|
+
editorState: isCollab
|
|
115
|
+
? null
|
|
116
|
+
: emptyEditor
|
|
117
|
+
? undefined
|
|
118
|
+
: $prepopulatedRichText,
|
|
119
|
+
html: { import: buildImportMap() },
|
|
120
|
+
namespace: 'Lexical Loro Playground',
|
|
121
|
+
nodes: [...PlaygroundNodes],
|
|
122
|
+
onError: (error) => {
|
|
123
|
+
throw error;
|
|
124
|
+
},
|
|
125
|
+
theme: PlaygroundEditorTheme,
|
|
126
|
+
};
|
|
127
|
+
return (_jsx(LexicalComposer, { initialConfig: initialConfig, children: _jsx(SharedHistoryContext, { children: _jsx(TableContext, { children: _jsxs(ToolbarContext, { children: [_jsx("header", { children: _jsx("a", { href: "https://lexical.dev", target: "_blank", rel: "noreferrer", children: _jsx("img", { src: logo, alt: "Lexical Logo" }) }) }), _jsx("div", { className: "editor-shell", children: _jsx(Editor, {}) }), _jsx(Settings, {}), isDevPlayground ? _jsx(DocsPlugin, {}) : null, isDevPlayground ? _jsx(PasteLogPlugin, {}) : null, isDevPlayground ? _jsx(TestRecorderPlugin, {}) : null, measureTypingPerf ? _jsx(TypingPerfPlugin, {}) : null] }) }) }) }));
|
|
128
|
+
}
|
|
129
|
+
export default function PlaygroundApp() {
|
|
130
|
+
return (_jsxs(SettingsContext, { children: [_jsx(FlashMessageContext, { children: _jsx(App, {}) }), _jsx("a", { href: "https://github.com/facebook/lexical/tree/main/packages/lexical-playground", className: "github-corner", "aria-label": "View source on GitHub", children: _jsxs("svg", { width: "80", height: "80", viewBox: "0 0 250 250", style: {
|
|
131
|
+
border: '0',
|
|
132
|
+
color: '#eee',
|
|
133
|
+
fill: '#222',
|
|
134
|
+
left: '0',
|
|
135
|
+
position: 'absolute',
|
|
136
|
+
top: '0',
|
|
137
|
+
transform: 'scale(-1,1)',
|
|
138
|
+
}, "aria-hidden": "true", children: [_jsx("path", { d: "M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z" }), _jsx("path", { d: "M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2", fill: "currentColor", style: {
|
|
139
|
+
transformOrigin: '130px 106px',
|
|
140
|
+
}, className: "octo-arm" }), _jsx("path", { d: "M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z", fill: "currentColor", className: "octo-body" })] }) })] }));
|
|
141
|
+
}
|
package/lib/Editor.d.ts
ADDED
package/lib/Editor.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { AutoFocusPlugin } from '@lexical/react/LexicalAutoFocusPlugin';
|
|
4
|
+
import { CharacterLimitPlugin } from '@lexical/react/LexicalCharacterLimitPlugin';
|
|
5
|
+
import { CheckListPlugin } from '@lexical/react/LexicalCheckListPlugin';
|
|
6
|
+
import { ClearEditorPlugin } from '@lexical/react/LexicalClearEditorPlugin';
|
|
7
|
+
import { ClickableLinkPlugin } from '@lexical/react/LexicalClickableLinkPlugin';
|
|
8
|
+
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
9
|
+
import { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';
|
|
10
|
+
import { HashtagPlugin } from '@lexical/react/LexicalHashtagPlugin';
|
|
11
|
+
import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin';
|
|
12
|
+
import { HorizontalRulePlugin } from '@lexical/react/LexicalHorizontalRulePlugin';
|
|
13
|
+
import { ListPlugin } from '@lexical/react/LexicalListPlugin';
|
|
14
|
+
import { PlainTextPlugin } from '@lexical/react/LexicalPlainTextPlugin';
|
|
15
|
+
import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';
|
|
16
|
+
import { SelectionAlwaysOnDisplay } from '@lexical/react/LexicalSelectionAlwaysOnDisplay';
|
|
17
|
+
import { TabIndentationPlugin } from '@lexical/react/LexicalTabIndentationPlugin';
|
|
18
|
+
import { TablePlugin } from '@lexical/react/LexicalTablePlugin';
|
|
19
|
+
import { useLexicalEditable } from '@lexical/react/useLexicalEditable';
|
|
20
|
+
import { CAN_USE_DOM } from '@lexical/utils';
|
|
21
|
+
import { useSettings } from './context/SettingsContext';
|
|
22
|
+
import { useSharedHistoryContext } from './context/SharedHistoryContext';
|
|
23
|
+
import ActionsPlugin from './plugins/ActionsPlugin';
|
|
24
|
+
import AutocompletePlugin from './plugins/AutocompletePlugin';
|
|
25
|
+
import AutoEmbedPlugin from './plugins/AutoEmbedPlugin';
|
|
26
|
+
import AutoLinkPlugin from './plugins/AutoLinkPlugin';
|
|
27
|
+
import CodeActionMenuPlugin from './plugins/CodeActionMenuPlugin';
|
|
28
|
+
import CodeHighlightPrismPlugin from './plugins/CodeHighlightPrismPlugin';
|
|
29
|
+
import CodeHighlightShikiPlugin from './plugins/CodeHighlightShikiPlugin';
|
|
30
|
+
import CollapsiblePlugin from './plugins/CollapsiblePlugin';
|
|
31
|
+
import CommentPlugin from './plugins/CommentPlugin';
|
|
32
|
+
import ComponentPickerPlugin from './plugins/ComponentPickerPlugin';
|
|
33
|
+
import ContextMenuPlugin from './plugins/ContextMenuPlugin';
|
|
34
|
+
import CounterPlugin from './plugins/CounterPlugin';
|
|
35
|
+
import DateTimePlugin from './plugins/DateTimePlugin';
|
|
36
|
+
import DragDropPaste from './plugins/DragDropPastePlugin';
|
|
37
|
+
import DraggableBlockPlugin from './plugins/DraggableBlockPlugin';
|
|
38
|
+
import EmojiPickerPlugin from './plugins/EmojiPickerPlugin';
|
|
39
|
+
import EmojisPlugin from './plugins/EmojisPlugin';
|
|
40
|
+
import EquationsPlugin from './plugins/EquationsPlugin';
|
|
41
|
+
import ExcalidrawPlugin from './plugins/ExcalidrawPlugin';
|
|
42
|
+
import FigmaPlugin from './plugins/FigmaPlugin';
|
|
43
|
+
import FloatingLinkEditorPlugin from './plugins/FloatingLinkEditorPlugin';
|
|
44
|
+
import FloatingTextFormatToolbarPlugin from './plugins/FloatingTextFormatToolbarPlugin';
|
|
45
|
+
import ImagesPlugin from './plugins/ImagesPlugin';
|
|
46
|
+
import InlineImagePlugin from './plugins/InlineImagePlugin';
|
|
47
|
+
import KeywordsPlugin from './plugins/KeywordsPlugin';
|
|
48
|
+
import { LayoutPlugin } from './plugins/LayoutPlugin/LayoutPlugin';
|
|
49
|
+
import LinkPlugin from './plugins/LinkPlugin';
|
|
50
|
+
import MarkdownShortcutPlugin from './plugins/MarkdownShortcutPlugin';
|
|
51
|
+
import { MaxLengthPlugin } from './plugins/MaxLengthPlugin';
|
|
52
|
+
import MentionsPlugin from './plugins/MentionsPlugin';
|
|
53
|
+
import PageBreakPlugin from './plugins/PageBreakPlugin';
|
|
54
|
+
import PollPlugin from './plugins/PollPlugin';
|
|
55
|
+
import ShortcutsPlugin from './plugins/ShortcutsPlugin';
|
|
56
|
+
import SpecialTextPlugin from './plugins/SpecialTextPlugin';
|
|
57
|
+
import SpeechToTextPlugin from './plugins/SpeechToTextPlugin';
|
|
58
|
+
import TabFocusPlugin from './plugins/TabFocusPlugin';
|
|
59
|
+
import TableCellActionMenuPlugin from './plugins/TableActionMenuPlugin';
|
|
60
|
+
import TableCellResizer from './plugins/TableCellResizer';
|
|
61
|
+
import TableHoverActionsPlugin from './plugins/TableHoverActionsPlugin';
|
|
62
|
+
import TableOfContentsPlugin from './plugins/TableOfContentsPlugin';
|
|
63
|
+
import ToolbarPlugin from './plugins/ToolbarPlugin';
|
|
64
|
+
import TreeViewPlugin from './plugins/TreeViewPlugin';
|
|
65
|
+
import TwitterPlugin from './plugins/TwitterPlugin';
|
|
66
|
+
import YouTubePlugin from './plugins/YouTubePlugin';
|
|
67
|
+
import ContentEditable from './ui/ContentEditable';
|
|
68
|
+
import DatalayerPlugin from './plugins/DatalayerPlugin';
|
|
69
|
+
import { LoroCollaborationPlugin as LoroCollaborationPlugin } from './collab/loro/LexicalCollaborationPlugin';
|
|
70
|
+
import { createWebsocketProvider as createLoroWebsocketProvider } from './collab/loro/wsProvider';
|
|
71
|
+
import { CollaborationPlugin as YjsCollaborationPlugin } from './collab/yjs/LexicalCollaborationPlugin';
|
|
72
|
+
import { createWebsocketProvider as createYjsWebsocketProvider } from './collab/yjs/wsProvider';
|
|
73
|
+
const skipCollaborationInit =
|
|
74
|
+
// @ts-expect-error
|
|
75
|
+
window.parent != null && window.parent.frames.right === window;
|
|
76
|
+
export default function Editor() {
|
|
77
|
+
const { historyState } = useSharedHistoryContext();
|
|
78
|
+
const { settings: { useYjs, isCodeHighlighted, isCodeShiki, isCollab, isAutocomplete, isMaxLength, isCharLimit, hasLinkAttributes, isCharLimitUtf8, isRichText, showTreeView, showTableOfContents, shouldUseLexicalContextMenu, shouldPreserveNewLinesInMarkdown, tableCellMerge, tableCellBackgroundColor, tableHorizontalScroll, shouldAllowHighlightingWithBrackets, selectionAlwaysOnDisplay, listStrictIndent, }, } = useSettings();
|
|
79
|
+
const isEditable = useLexicalEditable();
|
|
80
|
+
const placeholder = isCollab
|
|
81
|
+
? 'Enter some collaborative rich text...'
|
|
82
|
+
: isRichText
|
|
83
|
+
? 'Enter some rich text...'
|
|
84
|
+
: 'Enter some plain text...';
|
|
85
|
+
const [floatingAnchorElem, setFloatingAnchorElem] = useState(null);
|
|
86
|
+
const [isSmallWidthViewport, setIsSmallWidthViewport] = useState(false);
|
|
87
|
+
const [editor] = useLexicalComposerContext();
|
|
88
|
+
const [activeEditor, setActiveEditor] = useState(editor);
|
|
89
|
+
const [isLinkEditMode, setIsLinkEditMode] = useState(false);
|
|
90
|
+
const onRef = (_floatingAnchorElem) => {
|
|
91
|
+
if (_floatingAnchorElem !== null) {
|
|
92
|
+
setFloatingAnchorElem(_floatingAnchorElem);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
useEffect(() => {
|
|
96
|
+
const updateViewPortWidth = () => {
|
|
97
|
+
const isNextSmallWidthViewport = CAN_USE_DOM && window.matchMedia('(max-width: 1025px)').matches;
|
|
98
|
+
if (isNextSmallWidthViewport !== isSmallWidthViewport) {
|
|
99
|
+
setIsSmallWidthViewport(isNextSmallWidthViewport);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
updateViewPortWidth();
|
|
103
|
+
window.addEventListener('resize', updateViewPortWidth);
|
|
104
|
+
return () => {
|
|
105
|
+
window.removeEventListener('resize', updateViewPortWidth);
|
|
106
|
+
};
|
|
107
|
+
}, [isSmallWidthViewport]);
|
|
108
|
+
return (_jsxs(_Fragment, { children: [isRichText && (_jsx(ToolbarPlugin, { editor: editor, activeEditor: activeEditor, setActiveEditor: setActiveEditor, setIsLinkEditMode: setIsLinkEditMode })), isRichText && (_jsx(ShortcutsPlugin, { editor: activeEditor, setIsLinkEditMode: setIsLinkEditMode })), _jsxs("div", { className: `editor-container ${showTreeView ? 'tree-view' : ''} ${!isRichText ? 'plain-text' : ''}`, children: [isMaxLength && _jsx(MaxLengthPlugin, { maxLength: 30 }), _jsx(DragDropPaste, {}), _jsx(DatalayerPlugin, {}), _jsx(AutoFocusPlugin, {}), selectionAlwaysOnDisplay && _jsx(SelectionAlwaysOnDisplay, {}), _jsx(ClearEditorPlugin, {}), _jsx(ComponentPickerPlugin, {}), _jsx(EmojiPickerPlugin, {}), _jsx(AutoEmbedPlugin, {}), _jsx(MentionsPlugin, {}), _jsx(EmojisPlugin, {}), _jsx(HashtagPlugin, {}), _jsx(KeywordsPlugin, {}), _jsx(SpeechToTextPlugin, {}), _jsx(AutoLinkPlugin, {}), _jsx(DateTimePlugin, {}), useYjs &&
|
|
109
|
+
_jsx(CommentPlugin, { providerFactory: isCollab ? createYjsWebsocketProvider : undefined }), isRichText ? (_jsxs(_Fragment, { children: [isCollab ? (useYjs ? (_jsx(YjsCollaborationPlugin, { id: "main", providerFactory: createYjsWebsocketProvider, shouldBootstrap: !skipCollaborationInit })) : (_jsx(LoroCollaborationPlugin, { id: "main", providerFactory: createLoroWebsocketProvider, shouldBootstrap: !skipCollaborationInit }))) : (_jsx(HistoryPlugin, { externalHistoryState: historyState })), _jsx(RichTextPlugin, { contentEditable: _jsx("div", { className: "editor-scroller", children: _jsx("div", { className: "editor", ref: onRef, children: _jsx(ContentEditable, { placeholder: placeholder }) }) }), ErrorBoundary: LexicalErrorBoundary }), _jsx(MarkdownShortcutPlugin, {}), isCodeHighlighted &&
|
|
110
|
+
(isCodeShiki ? (_jsx(CodeHighlightShikiPlugin, {})) : (_jsx(CodeHighlightPrismPlugin, {}))), _jsx(ListPlugin, { hasStrictIndent: listStrictIndent }), _jsx(CheckListPlugin, {}), _jsx(TablePlugin, { hasCellMerge: tableCellMerge, hasCellBackgroundColor: tableCellBackgroundColor, hasHorizontalScroll: tableHorizontalScroll }), _jsx(TableCellResizer, {}), _jsx(ImagesPlugin, {}), _jsx(InlineImagePlugin, {}), _jsx(LinkPlugin, { hasLinkAttributes: hasLinkAttributes }), _jsx(PollPlugin, {}), _jsx(TwitterPlugin, {}), _jsx(YouTubePlugin, {}), _jsx(FigmaPlugin, {}), _jsx(ClickableLinkPlugin, { disabled: isEditable }), _jsx(HorizontalRulePlugin, {}), _jsx(EquationsPlugin, {}), _jsx(ExcalidrawPlugin, {}), _jsx(TabFocusPlugin, {}), _jsx(TabIndentationPlugin, { maxIndent: 7 }), _jsx(CollapsiblePlugin, {}), _jsx(CounterPlugin, {}), _jsx(PageBreakPlugin, {}), _jsx(LayoutPlugin, {}), floatingAnchorElem && (_jsxs(_Fragment, { children: [_jsx(FloatingLinkEditorPlugin, { anchorElem: floatingAnchorElem, isLinkEditMode: isLinkEditMode, setIsLinkEditMode: setIsLinkEditMode }), _jsx(TableCellActionMenuPlugin, { anchorElem: floatingAnchorElem, cellMerge: true })] })), floatingAnchorElem && !isSmallWidthViewport && (_jsxs(_Fragment, { children: [_jsx(DraggableBlockPlugin, { anchorElem: floatingAnchorElem }), _jsx(CodeActionMenuPlugin, { anchorElem: floatingAnchorElem }), _jsx(TableHoverActionsPlugin, { anchorElem: floatingAnchorElem }), _jsx(FloatingTextFormatToolbarPlugin, { anchorElem: floatingAnchorElem, setIsLinkEditMode: setIsLinkEditMode })] }))] })) : (_jsxs(_Fragment, { children: [_jsx(PlainTextPlugin, { contentEditable: _jsx(ContentEditable, { placeholder: placeholder }), ErrorBoundary: LexicalErrorBoundary }), _jsx(HistoryPlugin, { externalHistoryState: historyState })] })), (isCharLimit || isCharLimitUtf8) && (_jsx(CharacterLimitPlugin, { charset: isCharLimit ? 'UTF-16' : 'UTF-8', maxLength: 5 })), isAutocomplete && _jsx(AutocompletePlugin, {}), _jsx("div", { children: showTableOfContents && _jsx(TableOfContentsPlugin, {}) }), shouldUseLexicalContextMenu && _jsx(ContextMenuPlugin, {}), shouldAllowHighlightingWithBrackets && _jsx(SpecialTextPlugin, {}), _jsx(ActionsPlugin, { isRichText: isRichText, shouldPreserveNewLinesInMarkdown: shouldPreserveNewLinesInMarkdown })] }), showTreeView && _jsx(TreeViewPlugin, {})] }));
|
|
111
|
+
}
|
package/lib/Settings.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { CAN_USE_BEFORE_INPUT } from '@lexical/utils';
|
|
3
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
4
|
+
import { INITIAL_SETTINGS, isDevPlayground } from './appSettings';
|
|
5
|
+
import { useSettings } from './context/SettingsContext';
|
|
6
|
+
import Switch from './ui/Switch';
|
|
7
|
+
export default function Settings() {
|
|
8
|
+
const windowLocation = window.location;
|
|
9
|
+
const { setOption, settings: { measureTypingPerf, isCollab, isRichText, isMaxLength, hasLinkAttributes, isCharLimit, isCharLimitUtf8, isAutocomplete, showTreeView, showNestedEditorTreeView,
|
|
10
|
+
// disableBeforeInput,
|
|
11
|
+
showTableOfContents, shouldUseLexicalContextMenu, shouldPreserveNewLinesInMarkdown, shouldAllowHighlightingWithBrackets,
|
|
12
|
+
// tableHorizontalScroll,
|
|
13
|
+
selectionAlwaysOnDisplay, isCodeHighlighted, isCodeShiki, useYjs, }, } = useSettings();
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
if (INITIAL_SETTINGS.disableBeforeInput && CAN_USE_BEFORE_INPUT) {
|
|
16
|
+
console.error(`Legacy events are enabled (disableBeforeInput) but CAN_USE_BEFORE_INPUT is true`);
|
|
17
|
+
}
|
|
18
|
+
}, []);
|
|
19
|
+
const [showSettings, setShowSettings] = useState(false);
|
|
20
|
+
const [isSplitScreen, search] = useMemo(() => {
|
|
21
|
+
const parentWindow = window.parent;
|
|
22
|
+
const _search = windowLocation.search;
|
|
23
|
+
const _isSplitScreen = parentWindow && parentWindow.location.pathname === '/split/';
|
|
24
|
+
return [_isSplitScreen, _search];
|
|
25
|
+
}, [windowLocation]);
|
|
26
|
+
return (_jsxs(_Fragment, { children: [_jsx("button", { id: "options-button", className: `editor-dev-button ${showSettings ? 'active' : ''}`, onClick: () => setShowSettings(!showSettings) }), showSettings ? (_jsxs("div", { className: "switches", children: [isRichText && isDevPlayground && (_jsx(Switch, { onClick: () => {
|
|
27
|
+
setOption('isCollab', !isCollab);
|
|
28
|
+
window.location.reload();
|
|
29
|
+
}, checked: isCollab, text: "Collaboration" })), isRichText && isDevPlayground && isCollab && (_jsx(Switch, { onClick: () => {
|
|
30
|
+
setOption('useYjs', !useYjs);
|
|
31
|
+
window.location.reload();
|
|
32
|
+
}, checked: useYjs, text: "Use Y.js (vs Loro)" })), isDevPlayground && (_jsx(Switch, { onClick: () => {
|
|
33
|
+
if (isSplitScreen) {
|
|
34
|
+
window.parent.location.href = `/${search}`;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
window.location.href = `/split/${search}`;
|
|
38
|
+
}
|
|
39
|
+
}, checked: isSplitScreen, text: "Split Screen" })), _jsx(Switch, { onClick: () => setOption('measureTypingPerf', !measureTypingPerf), checked: measureTypingPerf, text: "Measure Perf" }), _jsx(Switch, { onClick: () => setOption('showTreeView', !showTreeView), checked: showTreeView, text: "Debug View" }), _jsx(Switch, { onClick: () => setOption('showNestedEditorTreeView', !showNestedEditorTreeView), checked: showNestedEditorTreeView, text: "Nested Editors Debug View" }), _jsx(Switch, { onClick: () => {
|
|
40
|
+
setOption('isRichText', !isRichText);
|
|
41
|
+
setOption('isCollab', false);
|
|
42
|
+
}, checked: isRichText, text: "Rich Text" }), _jsx(Switch, { onClick: () => setOption('isCharLimit', !isCharLimit), checked: isCharLimit, text: "Char Limit" }), _jsx(Switch, { onClick: () => setOption('isCharLimitUtf8', !isCharLimitUtf8), checked: isCharLimitUtf8, text: "Char Limit (UTF-8)" }), _jsx(Switch, { onClick: () => setOption('hasLinkAttributes', !hasLinkAttributes), checked: hasLinkAttributes, text: "Link Attributes" }), _jsx(Switch, { onClick: () => setOption('isMaxLength', !isMaxLength), checked: isMaxLength, text: "Max Length" }), _jsx(Switch, { onClick: () => setOption('isAutocomplete', !isAutocomplete), checked: isAutocomplete, text: "Autocomplete" }), _jsx(Switch, { onClick: () => {
|
|
43
|
+
setOption('showTableOfContents', !showTableOfContents);
|
|
44
|
+
}, checked: showTableOfContents, text: "Table Of Contents" }), _jsx(Switch, { onClick: () => {
|
|
45
|
+
setOption('shouldUseLexicalContextMenu', !shouldUseLexicalContextMenu);
|
|
46
|
+
}, checked: shouldUseLexicalContextMenu, text: "Use Lexical Context Menu" }), _jsx(Switch, { onClick: () => {
|
|
47
|
+
setOption('shouldPreserveNewLinesInMarkdown', !shouldPreserveNewLinesInMarkdown);
|
|
48
|
+
}, checked: shouldPreserveNewLinesInMarkdown, text: "Preserve newlines in Markdown" }), _jsx(Switch, { onClick: () => {
|
|
49
|
+
setOption('shouldAllowHighlightingWithBrackets', !shouldAllowHighlightingWithBrackets);
|
|
50
|
+
}, checked: shouldAllowHighlightingWithBrackets, text: "Use Brackets for Highlighting" }), _jsx(Switch, { onClick: () => {
|
|
51
|
+
setOption('selectionAlwaysOnDisplay', !selectionAlwaysOnDisplay);
|
|
52
|
+
}, checked: selectionAlwaysOnDisplay, text: "Retain selection" }), _jsx(Switch, { onClick: () => {
|
|
53
|
+
setOption('isCodeHighlighted', !isCodeHighlighted);
|
|
54
|
+
}, checked: isCodeHighlighted, text: "Enable Code Highlighting" }), _jsx(Switch, { onClick: () => {
|
|
55
|
+
setOption('isCodeShiki', !isCodeShiki);
|
|
56
|
+
}, checked: isCodeShiki, text: "Use Shiki for Code Highlighting" })] })) : null] }));
|
|
57
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export declare const isDevPlayground: boolean;
|
|
2
|
+
export declare const DEFAULT_SETTINGS: {
|
|
3
|
+
readonly useYjs: false;
|
|
4
|
+
readonly disableBeforeInput: false;
|
|
5
|
+
readonly emptyEditor: boolean;
|
|
6
|
+
readonly hasLinkAttributes: false;
|
|
7
|
+
readonly isAutocomplete: false;
|
|
8
|
+
readonly isCharLimit: false;
|
|
9
|
+
readonly isCharLimitUtf8: false;
|
|
10
|
+
readonly isCodeHighlighted: true;
|
|
11
|
+
readonly isCodeShiki: false;
|
|
12
|
+
readonly isCollab: true;
|
|
13
|
+
readonly isMaxLength: false;
|
|
14
|
+
readonly isRichText: true;
|
|
15
|
+
readonly listStrictIndent: false;
|
|
16
|
+
readonly measureTypingPerf: false;
|
|
17
|
+
readonly selectionAlwaysOnDisplay: false;
|
|
18
|
+
readonly shouldAllowHighlightingWithBrackets: false;
|
|
19
|
+
readonly shouldPreserveNewLinesInMarkdown: false;
|
|
20
|
+
readonly shouldUseLexicalContextMenu: false;
|
|
21
|
+
readonly showNestedEditorTreeView: false;
|
|
22
|
+
readonly showTableOfContents: false;
|
|
23
|
+
readonly showTreeView: true;
|
|
24
|
+
readonly tableCellBackgroundColor: true;
|
|
25
|
+
readonly tableCellMerge: true;
|
|
26
|
+
readonly tableHorizontalScroll: true;
|
|
27
|
+
readonly debug: false;
|
|
28
|
+
};
|
|
29
|
+
export declare const INITIAL_SETTINGS: Record<SettingName, boolean>;
|
|
30
|
+
export type SettingName = keyof typeof DEFAULT_SETTINGS;
|
|
31
|
+
export type Settings = typeof INITIAL_SETTINGS;
|
|
32
|
+
/**
|
|
33
|
+
* Check if debug mode is enabled via URL parameter
|
|
34
|
+
* @returns true if ?debug=true is in the URL, false otherwise
|
|
35
|
+
*/
|
|
36
|
+
export declare function isDebugEnabled(): boolean;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const hostName = window.location.hostname;
|
|
2
|
+
export const isDevPlayground = hostName !== 'playground.lexical.dev' &&
|
|
3
|
+
hostName !== 'lexical-playground.vercel.app';
|
|
4
|
+
export const DEFAULT_SETTINGS = {
|
|
5
|
+
useYjs: false,
|
|
6
|
+
disableBeforeInput: false,
|
|
7
|
+
emptyEditor: isDevPlayground,
|
|
8
|
+
hasLinkAttributes: false,
|
|
9
|
+
isAutocomplete: false,
|
|
10
|
+
isCharLimit: false,
|
|
11
|
+
isCharLimitUtf8: false,
|
|
12
|
+
isCodeHighlighted: true,
|
|
13
|
+
isCodeShiki: false,
|
|
14
|
+
isCollab: true, // Enable collaboration by default for testing
|
|
15
|
+
isMaxLength: false,
|
|
16
|
+
isRichText: true,
|
|
17
|
+
listStrictIndent: false,
|
|
18
|
+
measureTypingPerf: false,
|
|
19
|
+
selectionAlwaysOnDisplay: false,
|
|
20
|
+
shouldAllowHighlightingWithBrackets: false,
|
|
21
|
+
shouldPreserveNewLinesInMarkdown: false,
|
|
22
|
+
shouldUseLexicalContextMenu: false,
|
|
23
|
+
showNestedEditorTreeView: false,
|
|
24
|
+
showTableOfContents: false,
|
|
25
|
+
showTreeView: true,
|
|
26
|
+
tableCellBackgroundColor: true,
|
|
27
|
+
tableCellMerge: true,
|
|
28
|
+
tableHorizontalScroll: true,
|
|
29
|
+
debug: false, // Enable Loro debugging utilities
|
|
30
|
+
};
|
|
31
|
+
// These are mutated in setupEnv
|
|
32
|
+
export const INITIAL_SETTINGS = {
|
|
33
|
+
...DEFAULT_SETTINGS,
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Check if debug mode is enabled via URL parameter
|
|
37
|
+
* @returns true if ?debug=true is in the URL, false otherwise
|
|
38
|
+
*/
|
|
39
|
+
export function isDebugEnabled() {
|
|
40
|
+
if (typeof window === 'undefined')
|
|
41
|
+
return false;
|
|
42
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
43
|
+
return urlParams.get('debug') === 'true';
|
|
44
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { LexicalEditor } from 'lexical';
|
|
2
|
+
import { Klass, LexicalNode } from 'lexical';
|
|
3
|
+
import type { LoroDoc, LoroTree } from 'loro-crdt';
|
|
4
|
+
import type { CollabCursor } from './sync/SyncCursors';
|
|
5
|
+
import { NodeMapper } from './nodes/NodesMapper';
|
|
6
|
+
import { Provider } from './State';
|
|
7
|
+
export type ClientID = number;
|
|
8
|
+
export type Binding = {
|
|
9
|
+
tree: LoroTree;
|
|
10
|
+
clientID: ClientID;
|
|
11
|
+
cursors: Map<ClientID, CollabCursor>;
|
|
12
|
+
cursorsContainer: null | HTMLElement;
|
|
13
|
+
doc: LoroDoc;
|
|
14
|
+
docMap: Map<string, LoroDoc>;
|
|
15
|
+
editor: LexicalEditor;
|
|
16
|
+
id: string;
|
|
17
|
+
nodeProperties: Map<string, Array<string>>;
|
|
18
|
+
excludedProperties: ExcludedProperties;
|
|
19
|
+
nodeMapper: NodeMapper;
|
|
20
|
+
commitTimeout?: NodeJS.Timeout | null;
|
|
21
|
+
pendingCommit?: boolean;
|
|
22
|
+
};
|
|
23
|
+
export type ExcludedProperties = Map<Klass<LexicalNode>, Set<string>>;
|
|
24
|
+
export declare function createBinding(editor: LexicalEditor, provider: Provider, id: string, doc: LoroDoc | null | undefined, docMap: Map<string, LoroDoc>, excludedProperties?: ExcludedProperties): Binding;
|
|
25
|
+
/**
|
|
26
|
+
* Schedules an asynchronous commit for the binding to reduce latency with large documents.
|
|
27
|
+
* Uses debouncing to prevent excessive commits during rapid mutations.
|
|
28
|
+
*
|
|
29
|
+
* @param binding - The binding to commit
|
|
30
|
+
* @param delay - Debounce delay in milliseconds (default: 100ms)
|
|
31
|
+
*/
|
|
32
|
+
export declare function scheduleAsyncCommit(binding: Binding, delay?: number): void;
|
|
33
|
+
/**
|
|
34
|
+
* Forces an immediate commit if there are pending changes.
|
|
35
|
+
* Useful for ensuring changes are committed before important operations.
|
|
36
|
+
*
|
|
37
|
+
* @param binding - The binding to commit
|
|
38
|
+
*/
|
|
39
|
+
export declare function flushPendingCommit(binding: Binding): void;
|
|
40
|
+
export { LoroCollaborators, type LoroCollaboratorsProps, LoroCollaborationUI, type LoroCollaborationUIProps } from './components';
|
|
41
|
+
export { setupLoroDebugging, addDebugPanel, logTreeStructure, verifyTreeStructure } from './Debug';
|