@datalayer/lexical-loro 0.1.0 → 0.2.1
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 +1 -1
- package/package.json +7 -7
- package/lib/App.d.ts +0 -2
- package/lib/App.js +0 -141
- package/lib/Editor.d.ts +0 -2
- package/lib/Editor.js +0 -111
- package/lib/Settings.d.ts +0 -2
- package/lib/Settings.js +0 -57
- package/lib/appSettings.d.ts +0 -36
- package/lib/appSettings.js +0 -44
- package/lib/collab/loro/Bindings.d.ts +0 -41
- package/lib/collab/loro/Bindings.js +0 -95
- package/lib/collab/loro/Debug.d.ts +0 -33
- package/lib/collab/loro/Debug.js +0 -448
- package/lib/collab/loro/LexicalCollaborationContext.d.ts +0 -19
- package/lib/collab/loro/LexicalCollaborationContext.js +0 -48
- package/lib/collab/loro/LexicalCollaborationPlugin.d.ts +0 -24
- package/lib/collab/loro/LexicalCollaborationPlugin.js +0 -83
- package/lib/collab/loro/State.d.ts +0 -53
- package/lib/collab/loro/State.js +0 -90
- package/lib/collab/loro/components/LoroCollaborationUI.d.ts +0 -13
- package/lib/collab/loro/components/LoroCollaborationUI.js +0 -9
- package/lib/collab/loro/components/LoroCollaborators.d.ts +0 -8
- package/lib/collab/loro/components/LoroCollaborators.js +0 -97
- package/lib/collab/loro/components/index.d.ts +0 -2
- package/lib/collab/loro/components/index.js +0 -2
- package/lib/collab/loro/index.d.ts +0 -6
- package/lib/collab/loro/index.js +0 -6
- package/lib/collab/loro/integrators/BaseIntegrator.d.ts +0 -14
- package/lib/collab/loro/integrators/BaseIntegrator.js +0 -1
- package/lib/collab/loro/integrators/CounterIntegrator.d.ts +0 -23
- package/lib/collab/loro/integrators/CounterIntegrator.js +0 -40
- package/lib/collab/loro/integrators/ListIntegrator.d.ts +0 -23
- package/lib/collab/loro/integrators/ListIntegrator.js +0 -49
- package/lib/collab/loro/integrators/MapIntegrator.d.ts +0 -24
- package/lib/collab/loro/integrators/MapIntegrator.js +0 -177
- package/lib/collab/loro/integrators/TextIntegrator.d.ts +0 -25
- package/lib/collab/loro/integrators/TextIntegrator.js +0 -51
- package/lib/collab/loro/integrators/TreeIntegrator.d.ts +0 -25
- package/lib/collab/loro/integrators/TreeIntegrator.js +0 -201
- package/lib/collab/loro/nodes/NodeFactory.d.ts +0 -8
- package/lib/collab/loro/nodes/NodeFactory.js +0 -105
- package/lib/collab/loro/nodes/NodesMapper.d.ts +0 -111
- package/lib/collab/loro/nodes/NodesMapper.js +0 -258
- package/lib/collab/loro/propagators/DecoratorNodePropagator.d.ts +0 -60
- package/lib/collab/loro/propagators/DecoratorNodePropagator.js +0 -302
- package/lib/collab/loro/propagators/ElementNodePropagator.d.ts +0 -62
- package/lib/collab/loro/propagators/ElementNodePropagator.js +0 -335
- package/lib/collab/loro/propagators/LineBreakNodePropagator.d.ts +0 -57
- package/lib/collab/loro/propagators/LineBreakNodePropagator.js +0 -196
- package/lib/collab/loro/propagators/RootNodePropagator.d.ts +0 -55
- package/lib/collab/loro/propagators/RootNodePropagator.js +0 -168
- package/lib/collab/loro/propagators/TextNodePropagator.d.ts +0 -60
- package/lib/collab/loro/propagators/TextNodePropagator.js +0 -434
- package/lib/collab/loro/propagators/index.d.ts +0 -49
- package/lib/collab/loro/propagators/index.js +0 -32
- package/lib/collab/loro/provider/websocket.d.ts +0 -116
- package/lib/collab/loro/provider/websocket.js +0 -907
- 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 +0 -5
- package/lib/collab/loro/servers/ws/callback.js +0 -85
- package/lib/collab/loro/servers/ws/server.d.ts +0 -2
- package/lib/collab/loro/servers/ws/server.js +0 -25
- package/lib/collab/loro/servers/ws/utils.d.ts +0 -40
- package/lib/collab/loro/servers/ws/utils.js +0 -513
- package/lib/collab/loro/sync/SyncCursors.d.ts +0 -32
- package/lib/collab/loro/sync/SyncCursors.js +0 -435
- package/lib/collab/loro/sync/SyncLexicalToLoro.d.ts +0 -4
- package/lib/collab/loro/sync/SyncLexicalToLoro.js +0 -80
- package/lib/collab/loro/sync/SyncLoroToLexical.d.ts +0 -5
- package/lib/collab/loro/sync/SyncLoroToLexical.js +0 -96
- package/lib/collab/loro/types/LexicalNodeData.d.ts +0 -32
- package/lib/collab/loro/types/LexicalNodeData.js +0 -71
- package/lib/collab/loro/useCollaboration.d.ts +0 -12
- package/lib/collab/loro/useCollaboration.js +0 -248
- package/lib/collab/loro/utils/InitialContent.d.ts +0 -64
- package/lib/collab/loro/utils/InitialContent.js +0 -109
- package/lib/collab/loro/utils/LexicalToLoro.d.ts +0 -18
- package/lib/collab/loro/utils/LexicalToLoro.js +0 -96
- package/lib/collab/loro/utils/Utils.d.ts +0 -44
- package/lib/collab/loro/utils/Utils.js +0 -153
- package/lib/collab/loro/wsProvider.d.ts +0 -8
- package/lib/collab/loro/wsProvider.js +0 -31
- package/lib/collab/utils/invariant.d.ts +0 -1
- package/lib/collab/utils/invariant.js +0 -11
- package/lib/collab/utils/simpleDiffWithCursor.d.ts +0 -5
- package/lib/collab/utils/simpleDiffWithCursor.js +0 -31
- package/lib/collab/yjs/Bindings.d.ts +0 -23
- package/lib/collab/yjs/Bindings.js +0 -26
- package/lib/collab/yjs/Debug.d.ts +0 -23
- package/lib/collab/yjs/Debug.js +0 -213
- package/lib/collab/yjs/LexicalCollaborationContext.d.ts +0 -10
- package/lib/collab/yjs/LexicalCollaborationContext.js +0 -37
- package/lib/collab/yjs/LexicalCollaborationPlugin.d.ts +0 -21
- package/lib/collab/yjs/LexicalCollaborationPlugin.js +0 -63
- package/lib/collab/yjs/State.d.ts +0 -51
- package/lib/collab/yjs/State.js +0 -35
- package/lib/collab/yjs/nodes/AnyCollabNode.d.ts +0 -5
- package/lib/collab/yjs/nodes/AnyCollabNode.js +0 -1
- package/lib/collab/yjs/nodes/CollabDecoratorNode.d.ts +0 -22
- package/lib/collab/yjs/nodes/CollabDecoratorNode.js +0 -64
- package/lib/collab/yjs/nodes/CollabElementNode.d.ts +0 -40
- package/lib/collab/yjs/nodes/CollabElementNode.js +0 -462
- package/lib/collab/yjs/nodes/CollabLineBreakNode.d.ts +0 -19
- package/lib/collab/yjs/nodes/CollabLineBreakNode.js +0 -44
- package/lib/collab/yjs/nodes/CollabTextNode.d.ts +0 -25
- package/lib/collab/yjs/nodes/CollabTextNode.js +0 -103
- package/lib/collab/yjs/provider/websocket.d.ts +0 -88
- package/lib/collab/yjs/provider/websocket.js +0 -415
- 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 +0 -5
- package/lib/collab/yjs/servers/ws/callback.js +0 -72
- package/lib/collab/yjs/servers/ws/server.d.ts +0 -2
- package/lib/collab/yjs/servers/ws/server.js +0 -25
- package/lib/collab/yjs/servers/ws/utils.d.ts +0 -49
- package/lib/collab/yjs/servers/ws/utils.js +0 -284
- package/lib/collab/yjs/sync/SyncCursors.d.ts +0 -39
- package/lib/collab/yjs/sync/SyncCursors.js +0 -351
- package/lib/collab/yjs/sync/SyncEditorStates.d.ts +0 -10
- package/lib/collab/yjs/sync/SyncEditorStates.js +0 -200
- package/lib/collab/yjs/useCollaboration.d.ts +0 -12
- package/lib/collab/yjs/useCollaboration.js +0 -255
- package/lib/collab/yjs/utils/Utils.d.ts +0 -25
- package/lib/collab/yjs/utils/Utils.js +0 -402
- package/lib/collab/yjs/wsProvider.d.ts +0 -3
- package/lib/collab/yjs/wsProvider.js +0 -21
- package/lib/commenting/index.d.ts +0 -41
- package/lib/commenting/index.js +0 -324
- package/lib/context/FlashMessageContext.d.ts +0 -7
- package/lib/context/FlashMessageContext.js +0 -24
- package/lib/context/SettingsContext.d.ts +0 -12
- package/lib/context/SettingsContext.js +0 -38
- package/lib/context/SharedHistoryContext.d.ts +0 -11
- package/lib/context/SharedHistoryContext.js +0 -11
- package/lib/context/ToolbarContext.d.ts +0 -65
- package/lib/context/ToolbarContext.js +0 -84
- package/lib/demo.d.ts +0 -12
- package/lib/demo.js +0 -41
- package/lib/hooks/useFlashMessage.d.ts +0 -2
- package/lib/hooks/useFlashMessage.js +0 -4
- package/lib/hooks/useModal.d.ts +0 -5
- package/lib/hooks/useModal.js +0 -26
- package/lib/hooks/useReport.d.ts +0 -1
- package/lib/hooks/useReport.js +0 -46
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -1
- package/lib/nodes/AutocompleteNode.d.ts +0 -27
- package/lib/nodes/AutocompleteNode.js +0 -56
- package/lib/nodes/CounterComponent.d.ts +0 -6
- package/lib/nodes/CounterComponent.js +0 -137
- package/lib/nodes/CounterNode.d.ts +0 -23
- package/lib/nodes/CounterNode.js +0 -47
- package/lib/nodes/DateTimeNode/DateTimeComponent.d.ts +0 -8
- package/lib/nodes/DateTimeNode/DateTimeComponent.js +0 -119
- package/lib/nodes/DateTimeNode/DateTimeNode.d.ts +0 -27
- package/lib/nodes/DateTimeNode/DateTimeNode.js +0 -82
- package/lib/nodes/EmojiNode.d.ts +0 -18
- package/lib/nodes/EmojiNode.js +0 -50
- package/lib/nodes/EquationComponent.d.ts +0 -9
- package/lib/nodes/EquationComponent.js +0 -75
- package/lib/nodes/EquationNode.d.ts +0 -26
- package/lib/nodes/EquationNode.js +0 -109
- package/lib/nodes/ExcalidrawNode/ExcalidrawComponent.d.ts +0 -8
- package/lib/nodes/ExcalidrawNode/ExcalidrawComponent.js +0 -110
- package/lib/nodes/ExcalidrawNode/ExcalidrawImage.d.ts +0 -50
- package/lib/nodes/ExcalidrawNode/ExcalidrawImage.js +0 -55
- package/lib/nodes/ExcalidrawNode/index.d.ts +0 -32
- package/lib/nodes/ExcalidrawNode/index.js +0 -117
- package/lib/nodes/FigmaNode.d.ts +0 -20
- package/lib/nodes/FigmaNode.js +0 -52
- package/lib/nodes/ImageComponent.d.ts +0 -16
- package/lib/nodes/ImageComponent.js +0 -272
- package/lib/nodes/ImageNode.d.ts +0 -50
- package/lib/nodes/ImageNode.js +0 -151
- package/lib/nodes/InlineImageNode/InlineImageComponent.d.ts +0 -26
- package/lib/nodes/InlineImageNode/InlineImageComponent.js +0 -161
- package/lib/nodes/InlineImageNode/InlineImageNode.d.ts +0 -59
- package/lib/nodes/InlineImageNode/InlineImageNode.js +0 -162
- package/lib/nodes/KeywordNode.d.ts +0 -14
- package/lib/nodes/KeywordNode.js +0 -33
- package/lib/nodes/LayoutContainerNode.d.ts +0 -24
- package/lib/nodes/LayoutContainerNode.js +0 -91
- package/lib/nodes/LayoutItemNode.d.ts +0 -16
- package/lib/nodes/LayoutItemNode.js +0 -65
- package/lib/nodes/MentionNode.d.ts +0 -20
- package/lib/nodes/MentionNode.js +0 -81
- package/lib/nodes/PageBreakNode/index.d.ts +0 -17
- package/lib/nodes/PageBreakNode/index.js +0 -83
- package/lib/nodes/PlaygroundNodes.d.ts +0 -3
- package/lib/nodes/PlaygroundNodes.js +0 -71
- package/lib/nodes/PollComponent.d.ts +0 -9
- package/lib/nodes/PollComponent.js +0 -85
- package/lib/nodes/PollNode.d.ts +0 -43
- package/lib/nodes/PollNode.js +0 -153
- package/lib/nodes/SpecialTextNode.d.ts +0 -24
- package/lib/nodes/SpecialTextNode.js +0 -50
- package/lib/nodes/StickyComponent.d.ts +0 -10
- package/lib/nodes/StickyComponent.js +0 -162
- package/lib/nodes/StickyNode.d.ts +0 -31
- package/lib/nodes/StickyNode.js +0 -76
- package/lib/nodes/TweetNode.d.ts +0 -21
- package/lib/nodes/TweetNode.js +0 -119
- package/lib/nodes/YouTubeNode.d.ts +0 -22
- package/lib/nodes/YouTubeNode.js +0 -84
- package/lib/plugins/ActionsPlugin/index.d.ts +0 -5
- package/lib/plugins/ActionsPlugin/index.js +0 -168
- package/lib/plugins/AutoEmbedPlugin/index.d.ts +0 -19
- package/lib/plugins/AutoEmbedPlugin/index.js +0 -158
- package/lib/plugins/AutoLinkPlugin/index.d.ts +0 -2
- package/lib/plugins/AutoLinkPlugin/index.js +0 -15
- package/lib/plugins/AutocompletePlugin/index.d.ts +0 -10
- package/lib/plugins/AutocompletePlugin/index.js +0 -2473
- package/lib/plugins/CodeActionMenuPlugin/components/CopyButton/index.d.ts +0 -7
- package/lib/plugins/CodeActionMenuPlugin/components/CopyButton/index.js +0 -42
- package/lib/plugins/CodeActionMenuPlugin/components/PrettierButton/index.d.ts +0 -17
- package/lib/plugins/CodeActionMenuPlugin/components/PrettierButton/index.js +0 -111
- package/lib/plugins/CodeActionMenuPlugin/index.d.ts +0 -5
- package/lib/plugins/CodeActionMenuPlugin/index.js +0 -104
- package/lib/plugins/CodeActionMenuPlugin/utils.d.ts +0 -1
- package/lib/plugins/CodeActionMenuPlugin/utils.js +0 -18
- package/lib/plugins/CodeHighlightPrismPlugin/index.d.ts +0 -2
- package/lib/plugins/CodeHighlightPrismPlugin/index.js +0 -10
- package/lib/plugins/CodeHighlightShikiPlugin/index.d.ts +0 -2
- package/lib/plugins/CodeHighlightShikiPlugin/index.js +0 -10
- package/lib/plugins/CollapsiblePlugin/CollapsibleContainerNode.d.ts +0 -25
- package/lib/plugins/CollapsiblePlugin/CollapsibleContainerNode.js +0 -131
- package/lib/plugins/CollapsiblePlugin/CollapsibleContentNode.d.ts +0 -16
- package/lib/plugins/CollapsiblePlugin/CollapsibleContentNode.js +0 -79
- package/lib/plugins/CollapsiblePlugin/CollapsibleTitleNode.d.ts +0 -16
- package/lib/plugins/CollapsiblePlugin/CollapsibleTitleNode.js +0 -81
- package/lib/plugins/CollapsiblePlugin/CollapsibleUtils.d.ts +0 -2
- package/lib/plugins/CollapsiblePlugin/CollapsibleUtils.js +0 -8
- package/lib/plugins/CollapsiblePlugin/index.d.ts +0 -3
- package/lib/plugins/CollapsiblePlugin/index.js +0 -128
- package/lib/plugins/CommentPlugin/index.d.ts +0 -9
- package/lib/plugins/CommentPlugin/index.js +0 -460
- package/lib/plugins/ComponentPickerPlugin/index.d.ts +0 -2
- package/lib/plugins/ComponentPickerPlugin/index.js +0 -276
- package/lib/plugins/ContextMenuPlugin/index.d.ts +0 -2
- package/lib/plugins/ContextMenuPlugin/index.js +0 -112
- package/lib/plugins/CounterPlugin/index.d.ts +0 -3
- package/lib/plugins/CounterPlugin/index.js +0 -20
- package/lib/plugins/DatalayerPlugin/index.d.ts +0 -2
- package/lib/plugins/DatalayerPlugin/index.js +0 -218
- package/lib/plugins/DateTimePlugin/index.d.ts +0 -8
- package/lib/plugins/DateTimePlugin/index.js +0 -24
- package/lib/plugins/DocsPlugin/index.d.ts +0 -2
- package/lib/plugins/DocsPlugin/index.js +0 -4
- package/lib/plugins/DragDropPastePlugin/index.d.ts +0 -1
- package/lib/plugins/DragDropPastePlugin/index.js +0 -33
- package/lib/plugins/DraggableBlockPlugin/index.d.ts +0 -12
- package/lib/plugins/DraggableBlockPlugin/index.js +0 -36
- package/lib/plugins/EmojiPickerPlugin/index.d.ts +0 -1
- package/lib/plugins/EmojiPickerPlugin/index.js +0 -80
- package/lib/plugins/EmojisPlugin/index.d.ts +0 -2
- package/lib/plugins/EmojisPlugin/index.js +0 -52
- package/lib/plugins/EquationsPlugin/index.d.ts +0 -14
- package/lib/plugins/EquationsPlugin/index.js +0 -34
- package/lib/plugins/ExcalidrawPlugin/index.d.ts +0 -5
- package/lib/plugins/ExcalidrawPlugin/index.js +0 -44
- package/lib/plugins/FigmaPlugin/index.d.ts +0 -4
- package/lib/plugins/FigmaPlugin/index.js +0 -20
- package/lib/plugins/FloatingLinkEditorPlugin/index.d.ts +0 -15
- package/lib/plugins/FloatingLinkEditorPlugin/index.js +0 -280
- package/lib/plugins/FloatingTextFormatToolbarPlugin/index.d.ts +0 -7
- package/lib/plugins/FloatingTextFormatToolbarPlugin/index.js +0 -219
- package/lib/plugins/ImagesPlugin/index.d.ts +0 -24
- package/lib/plugins/ImagesPlugin/index.js +0 -195
- package/lib/plugins/InlineImagePlugin/index.d.ts +0 -17
- package/lib/plugins/InlineImagePlugin/index.js +0 -180
- package/lib/plugins/KeywordsPlugin/index.d.ts +0 -2
- package/lib/plugins/KeywordsPlugin/index.js +0 -31
- package/lib/plugins/LayoutPlugin/InsertLayoutDialog.d.ts +0 -6
- package/lib/plugins/LayoutPlugin/InsertLayoutDialog.js +0 -21
- package/lib/plugins/LayoutPlugin/LayoutPlugin.d.ts +0 -7
- package/lib/plugins/LayoutPlugin/LayoutPlugin.js +0 -131
- package/lib/plugins/LinkPlugin/index.d.ts +0 -6
- package/lib/plugins/LinkPlugin/index.js +0 -11
- package/lib/plugins/MarkdownShortcutPlugin/index.d.ts +0 -2
- package/lib/plugins/MarkdownShortcutPlugin/index.js +0 -6
- package/lib/plugins/MarkdownTransformers/index.d.ts +0 -8
- package/lib/plugins/MarkdownTransformers/index.js +0 -234
- package/lib/plugins/MaxLengthPlugin/index.d.ts +0 -3
- package/lib/plugins/MaxLengthPlugin/index.js +0 -37
- package/lib/plugins/MentionsPlugin/index.d.ts +0 -2
- package/lib/plugins/MentionsPlugin/index.js +0 -564
- package/lib/plugins/PageBreakPlugin/index.d.ts +0 -4
- package/lib/plugins/PageBreakPlugin/index.js +0 -27
- package/lib/plugins/PasteLogPlugin/index.d.ts +0 -2
- package/lib/plugins/PasteLogPlugin/index.js +0 -27
- package/lib/plugins/PollPlugin/index.d.ts +0 -8
- package/lib/plugins/PollPlugin/index.js +0 -38
- package/lib/plugins/ShortcutsPlugin/index.d.ts +0 -6
- package/lib/plugins/ShortcutsPlugin/index.js +0 -112
- package/lib/plugins/ShortcutsPlugin/shortcuts.d.ts +0 -59
- package/lib/plugins/ShortcutsPlugin/shortcuts.js +0 -169
- package/lib/plugins/SpecialTextPlugin/index.d.ts +0 -2
- package/lib/plugins/SpecialTextPlugin/index.js +0 -46
- package/lib/plugins/SpeechToTextPlugin/index.d.ts +0 -5
- package/lib/plugins/SpeechToTextPlugin/index.js +0 -82
- package/lib/plugins/StickyPlugin/index.d.ts +0 -2
- package/lib/plugins/StickyPlugin/index.js +0 -12
- package/lib/plugins/TabFocusPlugin/index.d.ts +0 -1
- package/lib/plugins/TabFocusPlugin/index.js +0 -34
- package/lib/plugins/TableActionMenuPlugin/index.d.ts +0 -5
- package/lib/plugins/TableActionMenuPlugin/index.js +0 -492
- package/lib/plugins/TableCellResizer/index.d.ts +0 -3
- package/lib/plugins/TableCellResizer/index.js +0 -297
- package/lib/plugins/TableHoverActionsPlugin/index.d.ts +0 -4
- package/lib/plugins/TableHoverActionsPlugin/index.js +0 -188
- package/lib/plugins/TableOfContentsPlugin/index.d.ts +0 -2
- package/lib/plugins/TableOfContentsPlugin/index.js +0 -116
- package/lib/plugins/TablePlugin.d.ts +0 -31
- package/lib/plugins/TablePlugin.js +0 -63
- package/lib/plugins/TestRecorderPlugin/index.d.ts +0 -3
- package/lib/plugins/TestRecorderPlugin/index.js +0 -346
- package/lib/plugins/ToolbarPlugin/fontSize.d.ts +0 -9
- package/lib/plugins/ToolbarPlugin/fontSize.js +0 -80
- package/lib/plugins/ToolbarPlugin/index.d.ts +0 -9
- package/lib/plugins/ToolbarPlugin/index.js +0 -500
- package/lib/plugins/ToolbarPlugin/utils.d.ts +0 -26
- package/lib/plugins/ToolbarPlugin/utils.js +0 -243
- package/lib/plugins/TreeViewPlugin/index.d.ts +0 -2
- package/lib/plugins/TreeViewPlugin/index.js +0 -7
- package/lib/plugins/TwitterPlugin/index.d.ts +0 -4
- package/lib/plugins/TwitterPlugin/index.js +0 -20
- package/lib/plugins/TypingPerfPlugin/index.d.ts +0 -2
- package/lib/plugins/TypingPerfPlugin/index.js +0 -93
- package/lib/plugins/YouTubePlugin/index.d.ts +0 -4
- package/lib/plugins/YouTubePlugin/index.js +0 -20
- package/lib/server/validation.d.ts +0 -1
- package/lib/server/validation.js +0 -111
- package/lib/setupEnv.d.ts +0 -2
- package/lib/setupEnv.js +0 -25
- package/lib/themes/CommentEditorTheme.d.ts +0 -4
- package/lib/themes/CommentEditorTheme.js +0 -7
- package/lib/themes/PlaygroundEditorTheme.d.ts +0 -4
- package/lib/themes/PlaygroundEditorTheme.js +0 -120
- package/lib/themes/StickyEditorTheme.d.ts +0 -4
- package/lib/themes/StickyEditorTheme.js +0 -7
- package/lib/tyes.dt.d.ts +0 -12
- package/lib/tyes.dt.js +0 -0
- package/lib/ui/Button.d.ts +0 -12
- package/lib/ui/Button.js +0 -6
- package/lib/ui/ColorPicker.d.ts +0 -14
- package/lib/ui/ColorPicker.js +0 -219
- package/lib/ui/ContentEditable.d.ts +0 -9
- package/lib/ui/ContentEditable.js +0 -6
- package/lib/ui/Dialog.d.ts +0 -10
- package/lib/ui/Dialog.js +0 -8
- package/lib/ui/DropDown.d.ts +0 -18
- package/lib/ui/DropDown.js +0 -133
- package/lib/ui/DropdownColorPicker.d.ts +0 -13
- package/lib/ui/DropdownColorPicker.js +0 -6
- package/lib/ui/EquationEditor.d.ts +0 -8
- package/lib/ui/EquationEditor.js +0 -11
- package/lib/ui/ExcalidrawModal.d.ts +0 -42
- package/lib/ui/ExcalidrawModal.js +0 -103
- package/lib/ui/FileInput.d.ts +0 -10
- package/lib/ui/FileInput.js +0 -5
- package/lib/ui/FlashMessage.d.ts +0 -7
- package/lib/ui/FlashMessage.js +0 -6
- package/lib/ui/ImageResizer.d.ts +0 -17
- package/lib/ui/ImageResizer.js +0 -171
- package/lib/ui/KatexEquationAlterer.d.ts +0 -8
- package/lib/ui/KatexEquationAlterer.js +0 -23
- package/lib/ui/KatexRenderer.d.ts +0 -6
- package/lib/ui/KatexRenderer.js +0 -24
- package/lib/ui/Modal.d.ts +0 -9
- package/lib/ui/Modal.js +0 -48
- package/lib/ui/Select.d.ts +0 -8
- package/lib/ui/Select.js +0 -5
- package/lib/ui/Switch.d.ts +0 -8
- package/lib/ui/Switch.js +0 -6
- package/lib/ui/TextInput.d.ts +0 -13
- package/lib/ui/TextInput.js +0 -7
- package/lib/utils/docSerialization.d.ts +0 -3
- package/lib/utils/docSerialization.js +0 -56
- package/lib/utils/emoji-list.d.ts +0 -20
- package/lib/utils/emoji-list.js +0 -16605
- package/lib/utils/getDOMRangeRect.d.ts +0 -8
- package/lib/utils/getDOMRangeRect.js +0 -22
- package/lib/utils/getSelectedNode.d.ts +0 -2
- package/lib/utils/getSelectedNode.js +0 -24
- package/lib/utils/getThemeSelector.d.ts +0 -2
- package/lib/utils/getThemeSelector.js +0 -10
- package/lib/utils/isMobileWidth.d.ts +0 -7
- package/lib/utils/isMobileWidth.js +0 -7
- package/lib/utils/joinClasses.d.ts +0 -1
- package/lib/utils/joinClasses.js +0 -3
- package/lib/utils/setFloatingElemPosition.d.ts +0 -1
- package/lib/utils/setFloatingElemPosition.js +0 -55
- package/lib/utils/setFloatingElemPositionForLinkEditor.d.ts +0 -1
- package/lib/utils/setFloatingElemPositionForLinkEditor.js +0 -32
- package/lib/utils/swipe.d.ts +0 -4
- package/lib/utils/swipe.js +0 -90
- package/lib/utils/url.d.ts +0 -2
- package/lib/utils/url.js +0 -27
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import type { BaseSelection, NodeKey } from 'lexical';
|
|
2
|
-
import type { Binding } from '../Bindings';
|
|
3
|
-
import { Provider, UserState } from '../State';
|
|
4
|
-
/*****************************************************************************/
|
|
5
|
-
export type CursorSelection = {
|
|
6
|
-
anchor: {
|
|
7
|
-
key: NodeKey;
|
|
8
|
-
offset: number;
|
|
9
|
-
};
|
|
10
|
-
caret: HTMLElement;
|
|
11
|
-
color: string;
|
|
12
|
-
focus: {
|
|
13
|
-
key: NodeKey;
|
|
14
|
-
offset: number;
|
|
15
|
-
};
|
|
16
|
-
name: HTMLSpanElement;
|
|
17
|
-
selections: Array<HTMLElement>;
|
|
18
|
-
};
|
|
19
|
-
export type CollabCursor = {
|
|
20
|
-
color: string;
|
|
21
|
-
name: string;
|
|
22
|
-
selection: null | CursorSelection;
|
|
23
|
-
};
|
|
24
|
-
export type SyncCursorPositionsOptions = {
|
|
25
|
-
getAwarenessStates?: (binding: Binding, provider: Provider) => Map<number, UserState>;
|
|
26
|
-
};
|
|
27
|
-
export type SyncCursorPositionsFn = (binding: Binding, provider: Provider, options?: SyncCursorPositionsOptions) => void;
|
|
28
|
-
/*****************************************************************************/
|
|
29
|
-
export declare function syncCursorPositions(binding: Binding, provider: Provider, options?: SyncCursorPositionsOptions): void;
|
|
30
|
-
export declare function syncLexicalSelectionToLoro(binding: Binding, provider: Provider, prevSelection: null | BaseSelection, nextSelection: null | BaseSelection): void;
|
|
31
|
-
/*****************************************************************************/
|
|
32
|
-
export declare function $syncLocalCursorPosition(binding: Binding, provider: Provider): void;
|
|
@@ -1,435 +0,0 @@
|
|
|
1
|
-
import { $getNodeByKey, $getSelection, $isElementNode, $isLineBreakNode, $isRangeSelection, $isTextNode, } from 'lexical';
|
|
2
|
-
import { createDOMRange, createRectsFromDOMRange } from '@lexical/selection';
|
|
3
|
-
/*****************************************************************************/
|
|
4
|
-
// Helper function to find Loro tree node for a Lexical NodeKey
|
|
5
|
-
function findLoroTreeNodeForLexicalKey(nodeKey, binding) {
|
|
6
|
-
try {
|
|
7
|
-
// Use NodeMapper to get the corresponding Loro tree node
|
|
8
|
-
const nodeMapper = binding.nodeMapper;
|
|
9
|
-
const treeNode = nodeMapper.getLoroNodeByLexicalKey(nodeKey);
|
|
10
|
-
return treeNode;
|
|
11
|
-
}
|
|
12
|
-
catch (error) {
|
|
13
|
-
console.warn('Failed to find Loro tree node for Lexical key:', nodeKey, error);
|
|
14
|
-
return null;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
// Helper function to convert a Lexical Point to a Loro Cursor
|
|
18
|
-
function convertLexicalPointToCursor(point, binding) {
|
|
19
|
-
try {
|
|
20
|
-
const node = $getNodeByKey(point.key);
|
|
21
|
-
if (!node) {
|
|
22
|
-
return null;
|
|
23
|
-
}
|
|
24
|
-
// For text nodes, we need to find the corresponding text container in Loro tree
|
|
25
|
-
if ($isTextNode(node)) {
|
|
26
|
-
// 1. Find the Loro tree node corresponding to this Lexical node
|
|
27
|
-
const treeNode = findLoroTreeNodeForLexicalKey(point.key, binding);
|
|
28
|
-
if (!treeNode) {
|
|
29
|
-
console.warn('Could not find corresponding Loro tree node for Lexical key:', point.key);
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
// 2. Get text content and validate offset
|
|
33
|
-
const textContent = node.getTextContent();
|
|
34
|
-
const offset = Math.min(point.offset, textContent.length);
|
|
35
|
-
// 3. Note: Some tree nodes may not have textContent stored in Loro yet
|
|
36
|
-
// This is normal during the sync process - we use Lexical node text as fallback
|
|
37
|
-
// 4. Create position data that can be used for collaborative selection
|
|
38
|
-
// Since we need to transmit cursor data through EphemeralStore, we use a simple structure
|
|
39
|
-
const cursor = {
|
|
40
|
-
treeId: treeNode.id,
|
|
41
|
-
offset: offset,
|
|
42
|
-
type: 'text',
|
|
43
|
-
nodeKey: point.key // Keep for debugging/validation
|
|
44
|
-
}; // We'll cast to LoroCursor when needed
|
|
45
|
-
return cursor;
|
|
46
|
-
}
|
|
47
|
-
// Handle element nodes (paragraphs, headings, etc.)
|
|
48
|
-
if ($isElementNode(node)) {
|
|
49
|
-
// For element nodes, we need to find the text child at the given offset
|
|
50
|
-
const children = node.getChildren();
|
|
51
|
-
let currentOffset = 0;
|
|
52
|
-
for (const child of children) {
|
|
53
|
-
if ($isTextNode(child)) {
|
|
54
|
-
const childText = child.getTextContent();
|
|
55
|
-
if (point.offset <= currentOffset + childText.length) {
|
|
56
|
-
// The cursor is within this text child
|
|
57
|
-
const relativeOffset = point.offset - currentOffset;
|
|
58
|
-
// Get the corresponding Loro tree node for this text child
|
|
59
|
-
const childTreeNode = findLoroTreeNodeForLexicalKey(child.getKey(), binding);
|
|
60
|
-
if (childTreeNode) {
|
|
61
|
-
return {
|
|
62
|
-
treeId: childTreeNode.id,
|
|
63
|
-
offset: Math.min(relativeOffset, childText.length),
|
|
64
|
-
type: 'text',
|
|
65
|
-
nodeKey: child.getKey()
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
currentOffset += childText.length;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
// If we get here, the offset is at the end of the element
|
|
73
|
-
// Find the last text child
|
|
74
|
-
for (let i = children.length - 1; i >= 0; i--) {
|
|
75
|
-
const child = children[i];
|
|
76
|
-
if ($isTextNode(child)) {
|
|
77
|
-
const childTreeNode = findLoroTreeNodeForLexicalKey(child.getKey(), binding);
|
|
78
|
-
if (childTreeNode) {
|
|
79
|
-
const childText = child.getTextContent();
|
|
80
|
-
return {
|
|
81
|
-
treeId: childTreeNode.id,
|
|
82
|
-
offset: childText.length, // At the end
|
|
83
|
-
type: 'text',
|
|
84
|
-
nodeKey: child.getKey()
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return null;
|
|
91
|
-
}
|
|
92
|
-
catch (error) {
|
|
93
|
-
console.warn('Failed to convert Lexical point to Loro cursor:', error);
|
|
94
|
-
return null;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
// Helper function to convert Loro cursor data back to Lexical selection
|
|
98
|
-
function convertLoroSelectionToLexical(anchorCursor, focusCursor, binding) {
|
|
99
|
-
try {
|
|
100
|
-
if (!anchorCursor || !focusCursor) {
|
|
101
|
-
return null;
|
|
102
|
-
}
|
|
103
|
-
// Convert cursor data back to Lexical positions using our custom structure
|
|
104
|
-
const anchor = anchorCursor;
|
|
105
|
-
const focus = focusCursor;
|
|
106
|
-
// If we have nodeKey stored, use it directly (this is our temporary approach)
|
|
107
|
-
if (anchor.nodeKey && focus.nodeKey) {
|
|
108
|
-
return {
|
|
109
|
-
anchorKey: anchor.nodeKey,
|
|
110
|
-
anchorOffset: anchor.offset,
|
|
111
|
-
focusKey: focus.nodeKey,
|
|
112
|
-
focusOffset: focus.offset,
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
// Alternative: Use NodeMapper to reverse-map from TreeID to NodeKey
|
|
116
|
-
const nodeMapper = binding.nodeMapper;
|
|
117
|
-
let anchorKey = null;
|
|
118
|
-
let focusKey = null;
|
|
119
|
-
if (anchor.treeId) {
|
|
120
|
-
anchorKey = nodeMapper.getLexicalKeyByLoroId(anchor.treeId);
|
|
121
|
-
}
|
|
122
|
-
if (focus.treeId) {
|
|
123
|
-
focusKey = nodeMapper.getLexicalKeyByLoroId(focus.treeId);
|
|
124
|
-
}
|
|
125
|
-
if (!anchorKey || !focusKey) {
|
|
126
|
-
console.warn('Could not find Lexical keys for Loro cursor TreeIDs');
|
|
127
|
-
return null;
|
|
128
|
-
}
|
|
129
|
-
return {
|
|
130
|
-
anchorKey: anchorKey,
|
|
131
|
-
anchorOffset: anchor.offset || 0,
|
|
132
|
-
focusKey: focusKey,
|
|
133
|
-
focusOffset: focus.offset || 0,
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
catch (error) {
|
|
137
|
-
console.warn('Failed to convert Loro cursors to Lexical selection:', error);
|
|
138
|
-
return null;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
// Helper function to set a point in Lexical selection
|
|
142
|
-
function $setPoint(point, key, offset) {
|
|
143
|
-
if (point.key !== key || point.offset !== offset) {
|
|
144
|
-
let anchorNode = $getNodeByKey(key);
|
|
145
|
-
if (anchorNode !== null &&
|
|
146
|
-
!$isElementNode(anchorNode) &&
|
|
147
|
-
!$isTextNode(anchorNode)) {
|
|
148
|
-
const parent = anchorNode.getParentOrThrow();
|
|
149
|
-
key = parent.getKey();
|
|
150
|
-
offset = anchorNode.getIndexWithinParent();
|
|
151
|
-
anchorNode = parent;
|
|
152
|
-
}
|
|
153
|
-
point.set(key, offset, $isElementNode(anchorNode) ? 'element' : 'text');
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
// Helper functions for cursor UI management
|
|
157
|
-
function createCollabCursor(name, color) {
|
|
158
|
-
return {
|
|
159
|
-
color: color,
|
|
160
|
-
name: name,
|
|
161
|
-
selection: null,
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
function createCursorSelection(cursor, anchorKey, anchorOffset, focusKey, focusOffset, isCurrentUser = false) {
|
|
165
|
-
const color = cursor.color;
|
|
166
|
-
// Helper function to convert color to rgba with opacity
|
|
167
|
-
const getColorWithOpacity = (color, opacity) => {
|
|
168
|
-
if (color.startsWith('#')) {
|
|
169
|
-
const hex = color.slice(1);
|
|
170
|
-
const r = parseInt(hex.slice(0, 2), 16);
|
|
171
|
-
const g = parseInt(hex.slice(2, 4), 16);
|
|
172
|
-
const b = parseInt(hex.slice(4, 6), 16);
|
|
173
|
-
return `rgba(${r}, ${g}, ${b}, ${opacity})`;
|
|
174
|
-
}
|
|
175
|
-
return color;
|
|
176
|
-
};
|
|
177
|
-
const caretColor = isCurrentUser ? getColorWithOpacity(color, 0.6) : color;
|
|
178
|
-
const nameBackgroundColor = isCurrentUser ? getColorWithOpacity(color, 0.7) : color;
|
|
179
|
-
const caret = document.createElement('span');
|
|
180
|
-
caret.style.cssText = `position:absolute;top:0;bottom:0;right:-1px;width:1px;background-color:${caretColor};z-index:10;${isCurrentUser ? 'opacity:0.8;' : ''}`;
|
|
181
|
-
const name = document.createElement('span');
|
|
182
|
-
name.textContent = cursor.name;
|
|
183
|
-
name.style.cssText = `position:absolute;left:-2px;top:-16px;background-color:${nameBackgroundColor};color:#fff;line-height:12px;font-size:12px;padding:2px;font-family:Arial;font-weight:bold;white-space:nowrap;${isCurrentUser ? 'opacity:0.9;' : ''}`;
|
|
184
|
-
caret.appendChild(name);
|
|
185
|
-
return {
|
|
186
|
-
anchor: { key: anchorKey, offset: anchorOffset },
|
|
187
|
-
focus: { key: focusKey, offset: focusOffset },
|
|
188
|
-
caret,
|
|
189
|
-
color: cursor.color,
|
|
190
|
-
name,
|
|
191
|
-
selections: [],
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
function destroyCursor(binding, cursor) {
|
|
195
|
-
const selection = cursor.selection;
|
|
196
|
-
if (selection !== null) {
|
|
197
|
-
destroySelection(binding, selection);
|
|
198
|
-
cursor.selection = null;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
function destroySelection(binding, selection) {
|
|
202
|
-
const cursorsContainer = binding.cursorsContainer;
|
|
203
|
-
if (cursorsContainer !== null) {
|
|
204
|
-
const selections = selection.selections;
|
|
205
|
-
const selectionsLength = selections.length;
|
|
206
|
-
for (let i = 0; i < selectionsLength; i++) {
|
|
207
|
-
cursorsContainer.removeChild(selections[i]);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
/*****************************************************************************/
|
|
212
|
-
export function syncCursorPositions(binding, provider, options) {
|
|
213
|
-
const { getAwarenessStates = getAwarenessStatesDefault } = options ?? {};
|
|
214
|
-
const awarenessStates = Array.from(getAwarenessStates(binding, provider));
|
|
215
|
-
const localClientID = binding.clientID;
|
|
216
|
-
const cursors = binding.cursors;
|
|
217
|
-
const editor = binding.editor;
|
|
218
|
-
const nodeMap = editor._editorState._nodeMap;
|
|
219
|
-
const visitedClientIDs = new Set();
|
|
220
|
-
// Process all cursor positions from awareness (including local user)
|
|
221
|
-
for (let i = 0; i < awarenessStates.length; i++) {
|
|
222
|
-
const awarenessState = awarenessStates[i];
|
|
223
|
-
const [clientID, awareness] = awarenessState;
|
|
224
|
-
visitedClientIDs.add(clientID);
|
|
225
|
-
const { name, color, focusing } = awareness;
|
|
226
|
-
const isCurrentUser = clientID === localClientID;
|
|
227
|
-
let selection = null;
|
|
228
|
-
let cursor = cursors.get(clientID);
|
|
229
|
-
if (cursor === undefined) {
|
|
230
|
-
// Add "(Me)" label for current user's cursor
|
|
231
|
-
const cursorName = isCurrentUser ? `${name} (Me)` : name;
|
|
232
|
-
cursor = createCollabCursor(cursorName, color);
|
|
233
|
-
cursors.set(clientID, cursor);
|
|
234
|
-
console.log('Added new cursor:', { clientID, name: cursorName, color, isCurrentUser, totalCursors: cursors.size });
|
|
235
|
-
}
|
|
236
|
-
if (focusing) {
|
|
237
|
-
const { anchorPos, focusPos } = awareness;
|
|
238
|
-
if (anchorPos !== null && focusPos !== null) {
|
|
239
|
-
const selectionInfo = convertLoroSelectionToLexical(anchorPos, focusPos, binding);
|
|
240
|
-
if (selectionInfo) {
|
|
241
|
-
const { anchorKey, anchorOffset, focusKey, focusOffset } = selectionInfo;
|
|
242
|
-
selection = cursor.selection;
|
|
243
|
-
if (selection === null) {
|
|
244
|
-
selection = createCursorSelection(cursor, anchorKey, anchorOffset, focusKey, focusOffset, isCurrentUser);
|
|
245
|
-
}
|
|
246
|
-
else {
|
|
247
|
-
// Update existing selection
|
|
248
|
-
const anchor = selection.anchor;
|
|
249
|
-
const focus = selection.focus;
|
|
250
|
-
anchor.key = anchorKey;
|
|
251
|
-
anchor.offset = anchorOffset;
|
|
252
|
-
focus.key = focusKey;
|
|
253
|
-
focus.offset = focusOffset;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
updateCursor(binding, cursor, selection, nodeMap, isCurrentUser);
|
|
259
|
-
}
|
|
260
|
-
// Clean up cursors for clients that are no longer present
|
|
261
|
-
const allClientIDs = Array.from(cursors.keys());
|
|
262
|
-
for (let i = 0; i < allClientIDs.length; i++) {
|
|
263
|
-
const clientID = allClientIDs[i];
|
|
264
|
-
if (!visitedClientIDs.has(clientID)) {
|
|
265
|
-
const cursor = cursors.get(clientID);
|
|
266
|
-
if (cursor !== undefined) {
|
|
267
|
-
destroyCursor(binding, cursor);
|
|
268
|
-
cursors.delete(clientID);
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
// Default function to get awareness states from provider
|
|
274
|
-
function getAwarenessStatesDefault(binding, provider) {
|
|
275
|
-
return provider.awareness.getStates();
|
|
276
|
-
}
|
|
277
|
-
// Function to update cursor visualization in the DOM
|
|
278
|
-
function updateCursor(binding, cursor, nextSelection, nodeMap, // LexicalEditor NodeMap type
|
|
279
|
-
isCurrentUser = false) {
|
|
280
|
-
const editor = binding.editor;
|
|
281
|
-
const rootElement = editor.getRootElement();
|
|
282
|
-
const cursorsContainer = binding.cursorsContainer;
|
|
283
|
-
if (cursorsContainer === null || rootElement === null) {
|
|
284
|
-
return;
|
|
285
|
-
}
|
|
286
|
-
const cursorsContainerOffsetParent = cursorsContainer.offsetParent;
|
|
287
|
-
if (cursorsContainerOffsetParent === null) {
|
|
288
|
-
return;
|
|
289
|
-
}
|
|
290
|
-
const containerRect = cursorsContainerOffsetParent.getBoundingClientRect();
|
|
291
|
-
const prevSelection = cursor.selection;
|
|
292
|
-
if (nextSelection === null) {
|
|
293
|
-
if (prevSelection === null) {
|
|
294
|
-
return;
|
|
295
|
-
}
|
|
296
|
-
else {
|
|
297
|
-
cursor.selection = null;
|
|
298
|
-
destroySelection(binding, prevSelection);
|
|
299
|
-
return;
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
else {
|
|
303
|
-
cursor.selection = nextSelection;
|
|
304
|
-
}
|
|
305
|
-
const caret = nextSelection.caret;
|
|
306
|
-
const color = nextSelection.color;
|
|
307
|
-
const selections = nextSelection.selections;
|
|
308
|
-
const anchor = nextSelection.anchor;
|
|
309
|
-
const focus = nextSelection.focus;
|
|
310
|
-
const anchorKey = anchor.key;
|
|
311
|
-
const focusKey = focus.key;
|
|
312
|
-
const anchorNode = nodeMap.get(anchorKey);
|
|
313
|
-
const focusNode = nodeMap.get(focusKey);
|
|
314
|
-
if (anchorNode == null || focusNode == null) {
|
|
315
|
-
return;
|
|
316
|
-
}
|
|
317
|
-
let selectionRects;
|
|
318
|
-
// Handle collapsed selection on a linebreak
|
|
319
|
-
if (anchorNode === focusNode && $isLineBreakNode(anchorNode)) {
|
|
320
|
-
const brRect = editor.getElementByKey(anchorKey).getBoundingClientRect();
|
|
321
|
-
selectionRects = [brRect];
|
|
322
|
-
}
|
|
323
|
-
else {
|
|
324
|
-
const range = createDOMRange(editor, anchorNode, anchor.offset, focusNode, focus.offset);
|
|
325
|
-
if (range === null) {
|
|
326
|
-
return;
|
|
327
|
-
}
|
|
328
|
-
selectionRects = createRectsFromDOMRange(editor, range);
|
|
329
|
-
}
|
|
330
|
-
const selectionsLength = selections.length;
|
|
331
|
-
const selectionRectsLength = selectionRects.length;
|
|
332
|
-
for (let i = 0; i < selectionRectsLength; i++) {
|
|
333
|
-
const selectionRect = selectionRects[i];
|
|
334
|
-
let selection = selections[i];
|
|
335
|
-
if (selection === undefined) {
|
|
336
|
-
selection = document.createElement('span');
|
|
337
|
-
selections[i] = selection;
|
|
338
|
-
const selectionBg = document.createElement('span');
|
|
339
|
-
selection.appendChild(selectionBg);
|
|
340
|
-
cursorsContainer.appendChild(selection);
|
|
341
|
-
}
|
|
342
|
-
const top = selectionRect.top - containerRect.top;
|
|
343
|
-
const left = selectionRect.left - containerRect.left;
|
|
344
|
-
const style = `position:absolute;top:${top}px;left:${left}px;height:${selectionRect.height}px;width:${selectionRect.width}px;pointer-events:none;z-index:5;`;
|
|
345
|
-
selection.style.cssText = style;
|
|
346
|
-
// Adjust opacity for current user selections to be more transparent
|
|
347
|
-
const selectionOpacity = isCurrentUser ? 0.15 : 0.3;
|
|
348
|
-
selection.firstChild.style.cssText = `${style}left:0;top:0;background-color:${color};opacity:${selectionOpacity};`;
|
|
349
|
-
if (i === selectionRectsLength - 1) {
|
|
350
|
-
if (caret.parentNode !== selection) {
|
|
351
|
-
selection.appendChild(caret);
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
for (let i = selectionsLength - 1; i >= selectionRectsLength; i--) {
|
|
356
|
-
const selection = selections[i];
|
|
357
|
-
cursorsContainer.removeChild(selection);
|
|
358
|
-
selections.pop();
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
export function syncLexicalSelectionToLoro(binding, provider, prevSelection, nextSelection) {
|
|
362
|
-
const awareness = provider.awareness;
|
|
363
|
-
const localState = awareness.getLocalState();
|
|
364
|
-
if (localState === null) {
|
|
365
|
-
return;
|
|
366
|
-
}
|
|
367
|
-
const { anchorPos: currentAnchorPos, focusPos: currentFocusPos, name, color, focusing, awarenessData, } = localState;
|
|
368
|
-
let anchorPos = null;
|
|
369
|
-
let focusPos = null;
|
|
370
|
-
// Check if we should clear the selection
|
|
371
|
-
if (nextSelection === null ||
|
|
372
|
-
(currentAnchorPos !== null && !nextSelection.is(prevSelection))) {
|
|
373
|
-
if (prevSelection === null) {
|
|
374
|
-
return;
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
// Convert Lexical selection to Loro cursors if we have a range selection
|
|
378
|
-
if ($isRangeSelection(nextSelection)) {
|
|
379
|
-
anchorPos = convertLexicalPointToCursor(nextSelection.anchor, binding);
|
|
380
|
-
focusPos = convertLexicalPointToCursor(nextSelection.focus, binding);
|
|
381
|
-
}
|
|
382
|
-
// Check if cursor positions have actually changed
|
|
383
|
-
const shouldUpdate = shouldUpdatePosition(currentAnchorPos, anchorPos) ||
|
|
384
|
-
shouldUpdatePosition(currentFocusPos, focusPos);
|
|
385
|
-
if (shouldUpdate) {
|
|
386
|
-
// Update the local state in EphemeralStore via awareness
|
|
387
|
-
awareness.setLocalState({
|
|
388
|
-
...localState,
|
|
389
|
-
anchorPos,
|
|
390
|
-
awarenessData,
|
|
391
|
-
color,
|
|
392
|
-
focusPos,
|
|
393
|
-
focusing,
|
|
394
|
-
name,
|
|
395
|
-
});
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
// Helper function to determine if cursor position should be updated
|
|
399
|
-
function shouldUpdatePosition(currentPos, pos) {
|
|
400
|
-
if (currentPos == null) {
|
|
401
|
-
return pos != null;
|
|
402
|
-
}
|
|
403
|
-
else if (pos == null) {
|
|
404
|
-
return true;
|
|
405
|
-
}
|
|
406
|
-
else {
|
|
407
|
-
// For now, do a simple comparison - in full implementation would compare Loro Cursor objects properly
|
|
408
|
-
const current = currentPos;
|
|
409
|
-
const next = pos;
|
|
410
|
-
return current.nodeKey !== next.nodeKey || current.offset !== next.offset;
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
/*****************************************************************************/
|
|
414
|
-
export function $syncLocalCursorPosition(binding, provider) {
|
|
415
|
-
const awareness = provider.awareness;
|
|
416
|
-
const localState = awareness.getLocalState();
|
|
417
|
-
if (localState === null) {
|
|
418
|
-
return;
|
|
419
|
-
}
|
|
420
|
-
const { anchorPos, focusPos } = localState;
|
|
421
|
-
// Convert Loro cursors back to Lexical selection
|
|
422
|
-
if (anchorPos !== null && focusPos !== null) {
|
|
423
|
-
const selectionInfo = convertLoroSelectionToLexical(anchorPos, focusPos, binding);
|
|
424
|
-
if (selectionInfo) {
|
|
425
|
-
const { anchorKey, anchorOffset, focusKey, focusOffset } = selectionInfo;
|
|
426
|
-
const selection = $getSelection();
|
|
427
|
-
if (!$isRangeSelection(selection)) {
|
|
428
|
-
return;
|
|
429
|
-
}
|
|
430
|
-
// Update the Lexical selection to match the cursor positions
|
|
431
|
-
$setPoint(selection.anchor, anchorKey, anchorOffset);
|
|
432
|
-
$setPoint(selection.focus, focusKey, focusOffset);
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
}
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { RootNode, ElementNode, TextNode, LineBreakNode, DecoratorNode, $getSelection } from 'lexical';
|
|
2
|
-
import { propagateRootNode } from '../propagators/RootNodePropagator';
|
|
3
|
-
import { propagateLineBreakNode } from '../propagators/LineBreakNodePropagator';
|
|
4
|
-
import { propagateElementNode } from '../propagators/ElementNodePropagator';
|
|
5
|
-
import { propagateTextNode } from '../propagators/TextNodePropagator';
|
|
6
|
-
import { propagateDecoratorNode } from '../propagators/DecoratorNodePropagator';
|
|
7
|
-
import { isClassExtending, generateClientID } from '../utils/Utils';
|
|
8
|
-
import { syncLexicalSelectionToLoro } from './SyncCursors';
|
|
9
|
-
// import { scheduleAsyncCommit } from '../Bindings';
|
|
10
|
-
// import { syncCursorPositions, SyncCursorPositionsFn } from './SyncCursors';
|
|
11
|
-
export function syncLexicalToLoro(binding, provider, update) {
|
|
12
|
-
const { mutatedNodes, prevEditorState, editorState: currEditorState, } = update;
|
|
13
|
-
if (mutatedNodes) {
|
|
14
|
-
const tree = binding.tree;
|
|
15
|
-
// Ensure we have a numeric peerId for TreeID format
|
|
16
|
-
const peerId = generateClientID(binding.doc);
|
|
17
|
-
// Create options object for mutators
|
|
18
|
-
const mutatorOptions = {
|
|
19
|
-
binding,
|
|
20
|
-
tree,
|
|
21
|
-
peerId
|
|
22
|
-
};
|
|
23
|
-
// Process mutations in proper dependency order: containers before children
|
|
24
|
-
// 1. First process RootNode, ElementNodes (containers)
|
|
25
|
-
// 2. Then process TextNodes, LineBreakNodes, DecoratorNodes (children)
|
|
26
|
-
const containerClasses = [RootNode, ElementNode];
|
|
27
|
-
const childClasses = [TextNode, LineBreakNode, DecoratorNode];
|
|
28
|
-
// Process containers first to ensure parent mappings exist
|
|
29
|
-
containerClasses.forEach(targetClass => {
|
|
30
|
-
mutatedNodes.forEach((nodeMap, Klass) => {
|
|
31
|
-
if (isClassExtending(Klass, targetClass)) {
|
|
32
|
-
nodeMap.forEach((mutation, nodeKey) => {
|
|
33
|
-
if (isClassExtending(Klass, RootNode)) {
|
|
34
|
-
propagateRootNode(update, mutation, nodeKey, mutatorOptions);
|
|
35
|
-
}
|
|
36
|
-
else if (isClassExtending(Klass, ElementNode)) {
|
|
37
|
-
propagateElementNode(update, mutation, nodeKey, mutatorOptions);
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
// Then process children to ensure their parents are already mapped
|
|
44
|
-
childClasses.forEach(targetClass => {
|
|
45
|
-
mutatedNodes.forEach((nodeMap, Klass) => {
|
|
46
|
-
if (isClassExtending(Klass, targetClass)) {
|
|
47
|
-
nodeMap.forEach((mutation, nodeKey) => {
|
|
48
|
-
if (isClassExtending(Klass, TextNode)) {
|
|
49
|
-
propagateTextNode(update, mutation, nodeKey, mutatorOptions);
|
|
50
|
-
}
|
|
51
|
-
else if (isClassExtending(Klass, LineBreakNode)) {
|
|
52
|
-
propagateLineBreakNode(update, mutation, nodeKey, mutatorOptions);
|
|
53
|
-
}
|
|
54
|
-
else if (isClassExtending(Klass, DecoratorNode)) {
|
|
55
|
-
propagateDecoratorNode(update, mutation, nodeKey, mutatorOptions);
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
// Option 1 - commit directly.
|
|
62
|
-
binding.doc.commit({ origin: binding.doc.peerIdStr });
|
|
63
|
-
// Option 2 - Schedule an async commit instead of immediate synchronous commit.
|
|
64
|
-
// This reduces latency for large documents by debouncing commits.
|
|
65
|
-
// scheduleAsyncCommit(binding);
|
|
66
|
-
// Option 3 - Schedule an async commit instead of immediate synchronous commit.
|
|
67
|
-
// This reduces latency for large documents by debouncing commits.
|
|
68
|
-
/*
|
|
69
|
-
const doCommit = () => requestIdleCallback(() => {
|
|
70
|
-
binding.doc.commit({ origin: binding.doc.peerIdStr });
|
|
71
|
-
}, { timeout: 2000 });
|
|
72
|
-
doCommit();
|
|
73
|
-
*/
|
|
74
|
-
currEditorState.read(() => {
|
|
75
|
-
const selection = $getSelection();
|
|
76
|
-
const prevSelection = prevEditorState._selection;
|
|
77
|
-
syncLexicalSelectionToLoro(binding, provider, prevSelection, selection);
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { LoroEventBatch } from 'loro-crdt';
|
|
2
|
-
import { Binding } from '../Bindings';
|
|
3
|
-
import { Provider } from '../State';
|
|
4
|
-
import { SyncCursorPositionsFn } from './SyncCursors';
|
|
5
|
-
export declare function syncLoroToLexical(binding: Binding, provider: Provider, eventBatch: LoroEventBatch, isFromUndoManger: boolean, syncCursorPositionsFn?: SyncCursorPositionsFn): void;
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { $addUpdateTag, $createParagraphNode, $getRoot, $getSelection, $isRangeSelection, $setSelection, SKIP_COLLAB_TAG, SKIP_SCROLL_INTO_VIEW_TAG } from 'lexical';
|
|
2
|
-
import { $syncLocalCursorPosition, syncCursorPositions, syncLexicalSelectionToLoro } from './SyncCursors';
|
|
3
|
-
// Import the new diff integrators
|
|
4
|
-
import { TreeIntegrator } from '../integrators/TreeIntegrator';
|
|
5
|
-
import { MapIntegrator } from '../integrators/MapIntegrator';
|
|
6
|
-
import { ListIntegrator } from '../integrators/ListIntegrator';
|
|
7
|
-
import { TextIntegrator } from '../integrators/TextIntegrator';
|
|
8
|
-
import { CounterIntegrator } from '../integrators/CounterIntegrator';
|
|
9
|
-
import { $moveSelectionToPreviousNode, doesSelectionNeedRecovering } from '../utils/Utils';
|
|
10
|
-
// Create singleton instances of the diff integrators (created once, reused across calls)
|
|
11
|
-
const treeIntegrator = new TreeIntegrator();
|
|
12
|
-
const mapIntegrator = new MapIntegrator();
|
|
13
|
-
const listIntegrator = new ListIntegrator();
|
|
14
|
-
const textIntegrator = new TextIntegrator();
|
|
15
|
-
const counterIntegrator = new CounterIntegrator();
|
|
16
|
-
export function syncLoroToLexical(binding, provider, eventBatch, isFromUndoManger, syncCursorPositionsFn = syncCursorPositions) {
|
|
17
|
-
const editor = binding.editor;
|
|
18
|
-
const currentEditorState = editor._editorState;
|
|
19
|
-
// Batch all events into a single discrete editor.update() to avoid race conditions
|
|
20
|
-
// Using discrete: true ensures immediate synchronous commit before other operations
|
|
21
|
-
binding.editor.update(() => {
|
|
22
|
-
// Clear selection temporarily to avoid cursor position conflicts during text updates
|
|
23
|
-
const currentSelection = $getSelection();
|
|
24
|
-
if (currentSelection) {
|
|
25
|
-
$setSelection(null);
|
|
26
|
-
}
|
|
27
|
-
// Process Loro events and apply them to Lexical using the appropriate integrators
|
|
28
|
-
eventBatch.events.forEach((event, index) => {
|
|
29
|
-
switch (event.diff.type) {
|
|
30
|
-
case 'tree':
|
|
31
|
-
// Call internal method that doesn't wrap in editor.update()
|
|
32
|
-
treeIntegrator.integrateInternal(event.diff, binding, provider);
|
|
33
|
-
break;
|
|
34
|
-
case 'map':
|
|
35
|
-
// Call internal method that doesn't wrap in editor.update()
|
|
36
|
-
if (event.target) {
|
|
37
|
-
mapIntegrator.integrateWithContextInternal(event.diff, event.target, binding, provider);
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
mapIntegrator.integrateInternal(event.diff, binding, provider);
|
|
41
|
-
}
|
|
42
|
-
break;
|
|
43
|
-
case 'list':
|
|
44
|
-
listIntegrator.integrateInternal(event.diff, binding, provider);
|
|
45
|
-
break;
|
|
46
|
-
case 'text':
|
|
47
|
-
textIntegrator.integrateInternal(event.diff, binding, provider);
|
|
48
|
-
break;
|
|
49
|
-
case 'counter':
|
|
50
|
-
counterIntegrator.integrateInternal(event.diff, binding, provider);
|
|
51
|
-
break;
|
|
52
|
-
default:
|
|
53
|
-
throw new Error(`Unsupported event diff type: ${event.diff.type}. Supported types are: 'tree', 'map', 'list', 'text', 'counter'.`);
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
const selection = $getSelection();
|
|
57
|
-
if ($isRangeSelection(selection)) {
|
|
58
|
-
if (doesSelectionNeedRecovering(selection)) {
|
|
59
|
-
const prevSelection = currentEditorState._selection;
|
|
60
|
-
if ($isRangeSelection(prevSelection)) {
|
|
61
|
-
$syncLocalCursorPosition(binding, provider);
|
|
62
|
-
if (doesSelectionNeedRecovering(selection)) {
|
|
63
|
-
// If the selected node is deleted, move the selection to the previous or parent node.
|
|
64
|
-
const anchorNodeKey = selection.anchor.key;
|
|
65
|
-
$moveSelectionToPreviousNode(anchorNodeKey, currentEditorState);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
syncLexicalSelectionToLoro(binding, provider, prevSelection, $getSelection());
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
$syncLocalCursorPosition(binding, provider);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
if (!isFromUndoManger) {
|
|
75
|
-
// If it is an external change, we don't want the current scroll position to get changed
|
|
76
|
-
// since the user might've intentionally scrolled somewhere else in the document.
|
|
77
|
-
$addUpdateTag(SKIP_SCROLL_INTO_VIEW_TAG);
|
|
78
|
-
}
|
|
79
|
-
}, {
|
|
80
|
-
onUpdate: () => {
|
|
81
|
-
syncCursorPositionsFn(binding, provider);
|
|
82
|
-
// If there was a collision on the top level paragraph
|
|
83
|
-
// we need to re-add a paragraph. To ensure this insertion properly syncs with other clients,
|
|
84
|
-
// it must be placed outside of the update block above that has tags 'collaboration' or 'historic'.
|
|
85
|
-
editor.update(() => {
|
|
86
|
-
if ($getRoot().getChildrenSize() === 0) {
|
|
87
|
-
$getRoot().append($createParagraphNode());
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
},
|
|
91
|
-
// discrete: true,
|
|
92
|
-
skipTransforms: true,
|
|
93
|
-
// tag: isFromUndoManger ? HISTORIC_TAG : COLLABORATION_TAG,
|
|
94
|
-
tag: SKIP_COLLAB_TAG
|
|
95
|
-
});
|
|
96
|
-
}
|