@liveblocks/react-lexical 2.18.3 → 2.18.4-uns2
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/dist/{classnames.mjs → classnames.cjs} +4 -2
- package/dist/{classnames.mjs.map → classnames.cjs.map} +1 -1
- package/dist/classnames.js +1 -3
- package/dist/classnames.js.map +1 -1
- package/dist/comments/{anchored-threads.mjs → anchored-threads.cjs} +44 -41
- package/dist/comments/{anchored-threads.mjs.map → anchored-threads.cjs.map} +1 -1
- package/dist/comments/anchored-threads.js +40 -43
- package/dist/comments/anchored-threads.js.map +1 -1
- package/dist/comments/{comment-plugin-provider.mjs → comment-plugin-provider.cjs} +62 -55
- package/dist/comments/{comment-plugin-provider.mjs.map → comment-plugin-provider.cjs.map} +1 -1
- package/dist/comments/comment-plugin-provider.js +54 -61
- package/dist/comments/comment-plugin-provider.js.map +1 -1
- package/dist/comments/{floating-composer.mjs → floating-composer.cjs} +68 -64
- package/dist/comments/{floating-composer.mjs.map → floating-composer.cjs.map} +1 -1
- package/dist/comments/floating-composer.js +63 -67
- package/dist/comments/floating-composer.js.map +1 -1
- package/dist/comments/{floating-threads.mjs → floating-threads.cjs} +51 -48
- package/dist/comments/{floating-threads.mjs.map → floating-threads.cjs.map} +1 -1
- package/dist/comments/floating-threads.js +47 -50
- package/dist/comments/floating-threads.js.map +1 -1
- package/dist/comments/get-thread-mark-ids.cjs +23 -0
- package/dist/comments/{get-thread-mark-ids.mjs.map → get-thread-mark-ids.cjs.map} +1 -1
- package/dist/comments/get-thread-mark-ids.js +6 -8
- package/dist/comments/get-thread-mark-ids.js.map +1 -1
- package/dist/comments/{thread-mark-node.mjs → thread-mark-node.cjs} +10 -6
- package/dist/comments/{thread-mark-node.mjs.map → thread-mark-node.cjs.map} +1 -1
- package/dist/comments/thread-mark-node.js +5 -9
- package/dist/comments/thread-mark-node.js.map +1 -1
- package/dist/comments/{unwrap-thread-mark-node.mjs → unwrap-thread-mark-node.cjs} +4 -2
- package/dist/comments/unwrap-thread-mark-node.cjs.map +1 -0
- package/dist/comments/unwrap-thread-mark-node.js +1 -3
- package/dist/comments/unwrap-thread-mark-node.js.map +1 -1
- package/dist/comments/{wrap-selection-in-thread-mark-node.mjs → wrap-selection-in-thread-mark-node.cjs} +12 -10
- package/dist/comments/{wrap-selection-in-thread-mark-node.mjs.map → wrap-selection-in-thread-mark-node.cjs.map} +1 -1
- package/dist/comments/wrap-selection-in-thread-mark-node.js +9 -11
- package/dist/comments/wrap-selection-in-thread-mark-node.js.map +1 -1
- package/dist/{create-dom-range.mjs → create-dom-range.cjs} +7 -5
- package/dist/{create-dom-range.mjs.map → create-dom-range.cjs.map} +1 -1
- package/dist/create-dom-range.js +4 -6
- package/dist/create-dom-range.js.map +1 -1
- package/dist/{create-rects-from-dom-range.mjs → create-rects-from-dom-range.cjs} +4 -2
- package/dist/{create-rects-from-dom-range.mjs.map → create-rects-from-dom-range.cjs.map} +1 -1
- package/dist/create-rects-from-dom-range.js +1 -3
- package/dist/create-rects-from-dom-range.js.map +1 -1
- package/dist/index.cjs +33 -0
- package/dist/{index.mjs.map → index.cjs.map} +1 -1
- package/dist/index.js +14 -31
- package/dist/index.js.map +1 -1
- package/dist/{is-block-node-active.mjs → is-block-node-active.cjs} +12 -10
- package/dist/{is-block-node-active.mjs.map → is-block-node-active.cjs.map} +1 -1
- package/dist/is-block-node-active.js +9 -11
- package/dist/is-block-node-active.js.map +1 -1
- package/dist/is-command-registered.cjs +11 -0
- package/dist/{is-command-registered.mjs.map → is-command-registered.cjs.map} +1 -1
- package/dist/is-command-registered.js +3 -5
- package/dist/is-command-registered.js.map +1 -1
- package/dist/is-text-format-active.cjs +16 -0
- package/dist/{is-text-format-active.mjs.map → is-text-format-active.cjs.map} +1 -1
- package/dist/is-text-format-active.js +4 -6
- package/dist/is-text-format-active.js.map +1 -1
- package/dist/liveblocks-config.cjs +17 -0
- package/dist/{liveblocks-config.mjs.map → liveblocks-config.cjs.map} +1 -1
- package/dist/liveblocks-config.js +4 -6
- package/dist/liveblocks-config.js.map +1 -1
- package/dist/liveblocks-plugin-provider.cjs +151 -0
- package/dist/liveblocks-plugin-provider.cjs.map +1 -0
- package/dist/liveblocks-plugin-provider.js +43 -47
- package/dist/liveblocks-plugin-provider.js.map +1 -1
- package/dist/mentions/{avatar.mjs → avatar.cjs} +16 -14
- package/dist/mentions/avatar.cjs.map +1 -0
- package/dist/mentions/avatar.js +13 -15
- package/dist/mentions/avatar.js.map +1 -1
- package/dist/mentions/mention-component.cjs +51 -0
- package/dist/mentions/{mention-component.mjs.map → mention-component.cjs.map} +1 -1
- package/dist/mentions/mention-component.js +14 -16
- package/dist/mentions/mention-component.js.map +1 -1
- package/dist/mentions/{mention-node.mjs → mention-node.cjs} +16 -12
- package/dist/mentions/{mention-node.mjs.map → mention-node.cjs.map} +1 -1
- package/dist/mentions/mention-node.js +11 -15
- package/dist/mentions/mention-node.js.map +1 -1
- package/dist/mentions/{mention-plugin.mjs → mention-plugin.cjs} +81 -78
- package/dist/mentions/{mention-plugin.mjs.map → mention-plugin.cjs.map} +1 -1
- package/dist/mentions/mention-plugin.js +77 -80
- package/dist/mentions/mention-plugin.js.map +1 -1
- package/dist/mentions/{suggestions.mjs → suggestions.cjs} +43 -37
- package/dist/mentions/{suggestions.mjs.map → suggestions.cjs.map} +1 -1
- package/dist/mentions/suggestions.js +36 -42
- package/dist/mentions/suggestions.js.map +1 -1
- package/dist/mentions/user.cjs +26 -0
- package/dist/mentions/{user.mjs.map → user.cjs.map} +1 -1
- package/dist/mentions/user.js +11 -13
- package/dist/mentions/user.js.map +1 -1
- package/dist/toolbar/{floating-toolbar.mjs → floating-toolbar.cjs} +73 -70
- package/dist/toolbar/{floating-toolbar.mjs.map → floating-toolbar.cjs.map} +1 -1
- package/dist/toolbar/floating-toolbar.js +69 -72
- package/dist/toolbar/floating-toolbar.js.map +1 -1
- package/dist/toolbar/shared.cjs +36 -0
- package/dist/toolbar/{shared.mjs.map → shared.cjs.map} +1 -1
- package/dist/toolbar/shared.js +12 -15
- package/dist/toolbar/shared.js.map +1 -1
- package/dist/toolbar/toolbar.cjs +433 -0
- package/dist/toolbar/{toolbar.mjs.map → toolbar.cjs.map} +1 -1
- package/dist/toolbar/toolbar.js +131 -156
- package/dist/toolbar/toolbar.js.map +1 -1
- package/dist/use-root-element.cjs +21 -0
- package/dist/use-root-element.cjs.map +1 -0
- package/dist/use-root-element.js +7 -9
- package/dist/use-root-element.js.map +1 -1
- package/dist/version-history/{history-version-preview.mjs → history-version-preview.cjs} +52 -50
- package/dist/version-history/{history-version-preview.mjs.map → history-version-preview.cjs.map} +1 -1
- package/dist/version-history/history-version-preview.js +49 -51
- package/dist/version-history/history-version-preview.js.map +1 -1
- package/dist/version.cjs +10 -0
- package/dist/{version.mjs.map → version.cjs.map} +1 -1
- package/dist/version.js +3 -7
- package/dist/version.js.map +1 -1
- package/package.json +18 -17
- package/styles.css.d.cts +1 -0
- package/dist/comments/get-thread-mark-ids.mjs +0 -21
- package/dist/comments/unwrap-thread-mark-node.mjs.map +0 -1
- package/dist/index.mjs +0 -16
- package/dist/is-command-registered.mjs +0 -9
- package/dist/is-text-format-active.mjs +0 -14
- package/dist/liveblocks-config.mjs +0 -15
- package/dist/liveblocks-plugin-provider.mjs +0 -147
- package/dist/liveblocks-plugin-provider.mjs.map +0 -1
- package/dist/mentions/avatar.mjs.map +0 -1
- package/dist/mentions/mention-component.mjs +0 -49
- package/dist/mentions/user.mjs +0 -24
- package/dist/toolbar/shared.mjs +0 -33
- package/dist/toolbar/toolbar.mjs +0 -408
- package/dist/use-root-element.mjs +0 -19
- package/dist/use-root-element.mjs.map +0 -1
- package/dist/version.mjs +0 -6
- /package/dist/{index.d.mts → index.d.cts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"floating-threads.js","sources":["../../src/comments/floating-threads.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { BaseMetadata, ThreadData } from \"@liveblocks/client\";\nimport type { DM } from \"@liveblocks/core\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport {\n Thread as DefaultThread,\n type ThreadProps,\n} from \"@liveblocks/react-ui\";\nimport {\n $getSelection,\n COMMAND_PRIORITY_HIGH,\n KEY_ESCAPE_COMMAND,\n} from \"lexical\";\nimport {\n type ComponentType,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useState,\n} from \"react\";\nimport { useSyncExternalStore } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { classNames } from \"../classnames\";\nimport { compareNodes } from \"./anchored-threads\";\nimport {\n ActiveThreadsContext,\n type ThreadToNodesMap,\n} from \"./comment-plugin-provider\";\nimport { ThreadToNodesContext } from \"./comment-plugin-provider\";\n\ntype ThreadPanelComponents = {\n Thread: ComponentType<ThreadProps>;\n};\n\nexport interface FloatingThreadsProps<M extends BaseMetadata = DM>\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n /**\n * The threads to display.\n */\n threads: ThreadData<M>[];\n\n /**\n * Override the component's components.\n */\n components?: Partial<ThreadPanelComponents>;\n}\n\nexport function FloatingThreads({\n threads,\n components,\n ...props\n}: FloatingThreadsProps) {\n const activeThreads = useActiveThreads();\n\n const Thread = components?.Thread ?? DefaultThread;\n\n const [editor] = useLexicalComposerContext();\n const nodes = useThreadToNodes(); // A map of thread ids to a set of thread mark nodes associated with the thread\n\n const [range, setRange] = useState<{\n range: Range;\n threads: ThreadData[];\n } | null>(null);\n\n const handleUpdateRange = useCallback(() => {\n function getActiveRange(): Range | null {\n function getActiveElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const thread of activeThreads) {\n const keys = nodes.get(thread);\n if (keys === undefined) continue;\n\n for (const key of keys) {\n const element = editor.getElementByKey(key);\n if (element === null) continue;\n activeElements.add(element);\n }\n }\n return activeElements;\n }\n\n const activeElements = getActiveElements();\n\n const sortedElements = Array.from(activeElements).sort(compareNodes);\n if (sortedElements.length === 0) return null;\n\n const range = document.createRange();\n range.setStartBefore(sortedElements[0]);\n range.setEndAfter(sortedElements[sortedElements.length - 1]);\n\n return range;\n }\n\n const active = (threads ?? []).filter((thread) =>\n activeThreads.includes(thread.id)\n );\n\n const range = getActiveRange();\n if (range === null) {\n setRange(null);\n return;\n }\n\n setRange({ range, threads: active });\n }, [activeThreads, nodes, editor, threads]);\n\n useEffect(() => {\n handleUpdateRange();\n }, [handleUpdateRange]);\n\n useEffect(() => {\n return editor.registerUpdateListener(handleUpdateRange);\n }, [editor, handleUpdateRange]);\n\n const handleEscapeKeydown = useCallback((): boolean => {\n if (range === null) return false;\n setRange(null);\n return true;\n }, [range]);\n\n useEffect(() => {\n return editor.registerCommand(\n KEY_ESCAPE_COMMAND,\n handleEscapeKeydown,\n COMMAND_PRIORITY_HIGH\n );\n }, [editor, handleEscapeKeydown]);\n\n const isCollapsed = useIsSelectionCollapsed();\n\n if (range === null || isCollapsed === null || !isCollapsed) return null;\n\n return (\n <FloatingThreadPortal\n range={range.range}\n container={document.body}\n {...props}\n >\n {range.threads.map((thread) => (\n <ThreadWrapper\n key={thread.id}\n thread={thread}\n Thread={Thread}\n onEscapeKeydown={handleEscapeKeydown}\n className=\"lb-lexical-floating-threads-thread\"\n />\n ))}\n </FloatingThreadPortal>\n );\n}\n\ninterface FloatingThreadPortalProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n range: Range;\n container: HTMLElement;\n children: ReactNode;\n}\n\nexport const FLOATING_THREAD_COLLISION_PADDING = 10;\n\nfunction FloatingThreadPortal({\n container,\n range,\n children,\n className,\n style,\n ...props\n}: FloatingThreadPortalProps) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"absolute\",\n placement: \"bottom\",\n middleware: [\n flip({ padding: FLOATING_THREAD_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_THREAD_COLLISION_PADDING }),\n shift({\n padding: FLOATING_THREAD_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({\n padding: FLOATING_THREAD_COLLISION_PADDING,\n apply({ availableWidth, availableHeight, elements }) {\n elements.floating.style.setProperty(\n \"--lb-lexical-floating-threads-available-width\",\n `${availableWidth}px`\n );\n elements.floating.style.setProperty(\n \"--lb-lexical-floating-threads-available-height\",\n `${availableHeight}px`\n );\n },\n }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n setReference({\n getBoundingClientRect: () => range.getBoundingClientRect(),\n });\n }, [setReference, range]);\n\n return createPortal(\n <div\n ref={setFloating}\n {...props}\n style={{\n ...style,\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n className={classNames(\n \"lb-root lb-portal lb-elevation lb-lexical-floating lb-lexical-floating-threads\",\n className\n )}\n >\n {children}\n </div>,\n container\n );\n}\n\ninterface ThreadWrapperProps extends ThreadProps {\n thread: ThreadData;\n Thread: ComponentType<ThreadProps>;\n onEscapeKeydown: () => void;\n}\n\nfunction ThreadWrapper({\n thread,\n Thread,\n onEscapeKeydown,\n onKeyDown,\n ...threadProps\n}: ThreadWrapperProps) {\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n\n // TODO: Add ability to preventDefault on keydown to override the default behavior, e.g. to show an alert dialog\n if (event.key === \"Escape\") {\n onEscapeKeydown();\n }\n },\n [onEscapeKeydown, onKeyDown]\n );\n\n return <Thread thread={thread} onKeyDown={handleKeyDown} {...threadProps} />;\n}\n\nfunction useThreadToNodes(): ThreadToNodesMap {\n const threadToNodes = useContext(ThreadToNodesContext);\n if (threadToNodes === null) {\n throw new Error(\n \"FloatingThreads component must be used within a LiveblocksPlugin component.\"\n );\n }\n return threadToNodes;\n}\n\nfunction useIsSelectionCollapsed(): boolean | null {\n const [editor] = useLexicalComposerContext();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n return editor.registerUpdateListener(onStoreChange);\n },\n [editor]\n );\n\n const getSnapshot = useCallback(() => {\n return editor.getEditorState().read(() => {\n const selection = $getSelection();\n if (selection === null) return null;\n return selection.isCollapsed();\n });\n }, [editor]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nfunction useActiveThreads() {\n const activeThreads = useContext(ActiveThreadsContext);\n if (activeThreads === null) {\n throw new Error(\n \"FloatingThreads component must be used within LiveblocksPlugin.\"\n );\n }\n\n return activeThreads;\n}\n"],"names":["DefaultThread","useLexicalComposerContext","useState","useCallback","activeElements","compareNodes","range","useEffect","KEY_ESCAPE_COMMAND","COMMAND_PRIORITY_HIGH","jsx","useFloating","flip","offset","hide","shift","limitShift","size","autoUpdate","useLayoutEffect","createPortal","classNames","useContext","ThreadToNodesContext","$getSelection","useSyncExternalStore","ActiveThreadsContext"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"floating-threads.js","sources":["../../src/comments/floating-threads.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { BaseMetadata, ThreadData } from \"@liveblocks/client\";\nimport type { DM } from \"@liveblocks/core\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport {\n Thread as DefaultThread,\n type ThreadProps,\n} from \"@liveblocks/react-ui\";\nimport {\n $getSelection,\n COMMAND_PRIORITY_HIGH,\n KEY_ESCAPE_COMMAND,\n} from \"lexical\";\nimport {\n type ComponentType,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useState,\n} from \"react\";\nimport { useSyncExternalStore } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { classNames } from \"../classnames\";\nimport { compareNodes } from \"./anchored-threads\";\nimport {\n ActiveThreadsContext,\n type ThreadToNodesMap,\n} from \"./comment-plugin-provider\";\nimport { ThreadToNodesContext } from \"./comment-plugin-provider\";\n\ntype ThreadPanelComponents = {\n Thread: ComponentType<ThreadProps>;\n};\n\nexport interface FloatingThreadsProps<M extends BaseMetadata = DM>\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n /**\n * The threads to display.\n */\n threads: ThreadData<M>[];\n\n /**\n * Override the component's components.\n */\n components?: Partial<ThreadPanelComponents>;\n}\n\nexport function FloatingThreads({\n threads,\n components,\n ...props\n}: FloatingThreadsProps) {\n const activeThreads = useActiveThreads();\n\n const Thread = components?.Thread ?? DefaultThread;\n\n const [editor] = useLexicalComposerContext();\n const nodes = useThreadToNodes(); // A map of thread ids to a set of thread mark nodes associated with the thread\n\n const [range, setRange] = useState<{\n range: Range;\n threads: ThreadData[];\n } | null>(null);\n\n const handleUpdateRange = useCallback(() => {\n function getActiveRange(): Range | null {\n function getActiveElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const thread of activeThreads) {\n const keys = nodes.get(thread);\n if (keys === undefined) continue;\n\n for (const key of keys) {\n const element = editor.getElementByKey(key);\n if (element === null) continue;\n activeElements.add(element);\n }\n }\n return activeElements;\n }\n\n const activeElements = getActiveElements();\n\n const sortedElements = Array.from(activeElements).sort(compareNodes);\n if (sortedElements.length === 0) return null;\n\n const range = document.createRange();\n range.setStartBefore(sortedElements[0]);\n range.setEndAfter(sortedElements[sortedElements.length - 1]);\n\n return range;\n }\n\n const active = (threads ?? []).filter((thread) =>\n activeThreads.includes(thread.id)\n );\n\n const range = getActiveRange();\n if (range === null) {\n setRange(null);\n return;\n }\n\n setRange({ range, threads: active });\n }, [activeThreads, nodes, editor, threads]);\n\n useEffect(() => {\n handleUpdateRange();\n }, [handleUpdateRange]);\n\n useEffect(() => {\n return editor.registerUpdateListener(handleUpdateRange);\n }, [editor, handleUpdateRange]);\n\n const handleEscapeKeydown = useCallback((): boolean => {\n if (range === null) return false;\n setRange(null);\n return true;\n }, [range]);\n\n useEffect(() => {\n return editor.registerCommand(\n KEY_ESCAPE_COMMAND,\n handleEscapeKeydown,\n COMMAND_PRIORITY_HIGH\n );\n }, [editor, handleEscapeKeydown]);\n\n const isCollapsed = useIsSelectionCollapsed();\n\n if (range === null || isCollapsed === null || !isCollapsed) return null;\n\n return (\n <FloatingThreadPortal\n range={range.range}\n container={document.body}\n {...props}\n >\n {range.threads.map((thread) => (\n <ThreadWrapper\n key={thread.id}\n thread={thread}\n Thread={Thread}\n onEscapeKeydown={handleEscapeKeydown}\n className=\"lb-lexical-floating-threads-thread\"\n />\n ))}\n </FloatingThreadPortal>\n );\n}\n\ninterface FloatingThreadPortalProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n range: Range;\n container: HTMLElement;\n children: ReactNode;\n}\n\nexport const FLOATING_THREAD_COLLISION_PADDING = 10;\n\nfunction FloatingThreadPortal({\n container,\n range,\n children,\n className,\n style,\n ...props\n}: FloatingThreadPortalProps) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"absolute\",\n placement: \"bottom\",\n middleware: [\n flip({ padding: FLOATING_THREAD_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_THREAD_COLLISION_PADDING }),\n shift({\n padding: FLOATING_THREAD_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({\n padding: FLOATING_THREAD_COLLISION_PADDING,\n apply({ availableWidth, availableHeight, elements }) {\n elements.floating.style.setProperty(\n \"--lb-lexical-floating-threads-available-width\",\n `${availableWidth}px`\n );\n elements.floating.style.setProperty(\n \"--lb-lexical-floating-threads-available-height\",\n `${availableHeight}px`\n );\n },\n }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n setReference({\n getBoundingClientRect: () => range.getBoundingClientRect(),\n });\n }, [setReference, range]);\n\n return createPortal(\n <div\n ref={setFloating}\n {...props}\n style={{\n ...style,\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n className={classNames(\n \"lb-root lb-portal lb-elevation lb-lexical-floating lb-lexical-floating-threads\",\n className\n )}\n >\n {children}\n </div>,\n container\n );\n}\n\ninterface ThreadWrapperProps extends ThreadProps {\n thread: ThreadData;\n Thread: ComponentType<ThreadProps>;\n onEscapeKeydown: () => void;\n}\n\nfunction ThreadWrapper({\n thread,\n Thread,\n onEscapeKeydown,\n onKeyDown,\n ...threadProps\n}: ThreadWrapperProps) {\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n\n // TODO: Add ability to preventDefault on keydown to override the default behavior, e.g. to show an alert dialog\n if (event.key === \"Escape\") {\n onEscapeKeydown();\n }\n },\n [onEscapeKeydown, onKeyDown]\n );\n\n return <Thread thread={thread} onKeyDown={handleKeyDown} {...threadProps} />;\n}\n\nfunction useThreadToNodes(): ThreadToNodesMap {\n const threadToNodes = useContext(ThreadToNodesContext);\n if (threadToNodes === null) {\n throw new Error(\n \"FloatingThreads component must be used within a LiveblocksPlugin component.\"\n );\n }\n return threadToNodes;\n}\n\nfunction useIsSelectionCollapsed(): boolean | null {\n const [editor] = useLexicalComposerContext();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n return editor.registerUpdateListener(onStoreChange);\n },\n [editor]\n );\n\n const getSnapshot = useCallback(() => {\n return editor.getEditorState().read(() => {\n const selection = $getSelection();\n if (selection === null) return null;\n return selection.isCollapsed();\n });\n }, [editor]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nfunction useActiveThreads() {\n const activeThreads = useContext(ActiveThreadsContext);\n if (activeThreads === null) {\n throw new Error(\n \"FloatingThreads component must be used within LiveblocksPlugin.\"\n );\n }\n\n return activeThreads;\n}\n"],"names":["Thread","DefaultThread","activeElements","range"],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var lexical = require('lexical');
|
|
4
|
+
var threadMarkNode = require('./thread-mark-node.cjs');
|
|
5
|
+
|
|
6
|
+
function $getThreadMarkIds(node, offset) {
|
|
7
|
+
let currentNode = node;
|
|
8
|
+
while (currentNode !== null) {
|
|
9
|
+
if (threadMarkNode.$isThreadMarkNode(currentNode)) {
|
|
10
|
+
return currentNode.getIDs();
|
|
11
|
+
} else if (lexical.$isTextNode(currentNode) && offset === currentNode.getTextContentSize()) {
|
|
12
|
+
const nextSibling = currentNode.getNextSibling();
|
|
13
|
+
if (threadMarkNode.$isThreadMarkNode(nextSibling)) {
|
|
14
|
+
return nextSibling.getIDs();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
currentNode = currentNode.getParent();
|
|
18
|
+
}
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
module.exports = $getThreadMarkIds;
|
|
23
|
+
//# sourceMappingURL=get-thread-mark-ids.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-thread-mark-ids.
|
|
1
|
+
{"version":3,"file":"get-thread-mark-ids.cjs","sources":["../../src/comments/get-thread-mark-ids.ts"],"sourcesContent":["import type { LexicalNode, TextNode } from \"lexical\";\nimport { $isTextNode } from \"lexical\";\n\nimport { $isThreadMarkNode } from \"./thread-mark-node\";\n\nexport default function $getThreadMarkIds(\n node: TextNode,\n offset: number\n): null | Array<string> {\n let currentNode: LexicalNode | null = node;\n while (currentNode !== null) {\n if ($isThreadMarkNode(currentNode)) {\n return currentNode.getIDs();\n } else if (\n $isTextNode(currentNode) &&\n offset === currentNode.getTextContentSize()\n ) {\n const nextSibling = currentNode.getNextSibling();\n if ($isThreadMarkNode(nextSibling)) {\n return nextSibling.getIDs();\n }\n }\n currentNode = currentNode.getParent();\n }\n return null;\n}\n"],"names":["$isThreadMarkNode","$isTextNode"],"mappings":";;;;;AAKwB,SAAA,iBAAA,CACtB,MACA,MACsB,EAAA;AACtB,EAAA,IAAI,WAAkC,GAAA,IAAA,CAAA;AACtC,EAAA,OAAO,gBAAgB,IAAM,EAAA;AAC3B,IAAI,IAAAA,gCAAA,CAAkB,WAAW,CAAG,EAAA;AAClC,MAAA,OAAO,YAAY,MAAO,EAAA,CAAA;AAAA,eAE1BC,mBAAY,CAAA,WAAW,KACvB,MAAW,KAAA,WAAA,CAAY,oBACvB,EAAA;AACA,MAAM,MAAA,WAAA,GAAc,YAAY,cAAe,EAAA,CAAA;AAC/C,MAAI,IAAAD,gCAAA,CAAkB,WAAW,CAAG,EAAA;AAClC,QAAA,OAAO,YAAY,MAAO,EAAA,CAAA;AAAA,OAC5B;AAAA,KACF;AACA,IAAA,WAAA,GAAc,YAAY,SAAU,EAAA,CAAA;AAAA,GACtC;AACA,EAAO,OAAA,IAAA,CAAA;AACT;;;;"}
|
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
var lexical = require('lexical');
|
|
4
|
-
var threadMarkNode = require('./thread-mark-node.js');
|
|
1
|
+
import { $isTextNode } from 'lexical';
|
|
2
|
+
import { $isThreadMarkNode } from './thread-mark-node.js';
|
|
5
3
|
|
|
6
4
|
function $getThreadMarkIds(node, offset) {
|
|
7
5
|
let currentNode = node;
|
|
8
6
|
while (currentNode !== null) {
|
|
9
|
-
if (
|
|
7
|
+
if ($isThreadMarkNode(currentNode)) {
|
|
10
8
|
return currentNode.getIDs();
|
|
11
|
-
} else if (
|
|
9
|
+
} else if ($isTextNode(currentNode) && offset === currentNode.getTextContentSize()) {
|
|
12
10
|
const nextSibling = currentNode.getNextSibling();
|
|
13
|
-
if (
|
|
11
|
+
if ($isThreadMarkNode(nextSibling)) {
|
|
14
12
|
return nextSibling.getIDs();
|
|
15
13
|
}
|
|
16
14
|
}
|
|
@@ -19,5 +17,5 @@ function $getThreadMarkIds(node, offset) {
|
|
|
19
17
|
return null;
|
|
20
18
|
}
|
|
21
19
|
|
|
22
|
-
|
|
20
|
+
export { $getThreadMarkIds as default };
|
|
23
21
|
//# sourceMappingURL=get-thread-mark-ids.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-thread-mark-ids.js","sources":["../../src/comments/get-thread-mark-ids.ts"],"sourcesContent":["import type { LexicalNode, TextNode } from \"lexical\";\nimport { $isTextNode } from \"lexical\";\n\nimport { $isThreadMarkNode } from \"./thread-mark-node\";\n\nexport default function $getThreadMarkIds(\n node: TextNode,\n offset: number\n): null | Array<string> {\n let currentNode: LexicalNode | null = node;\n while (currentNode !== null) {\n if ($isThreadMarkNode(currentNode)) {\n return currentNode.getIDs();\n } else if (\n $isTextNode(currentNode) &&\n offset === currentNode.getTextContentSize()\n ) {\n const nextSibling = currentNode.getNextSibling();\n if ($isThreadMarkNode(nextSibling)) {\n return nextSibling.getIDs();\n }\n }\n currentNode = currentNode.getParent();\n }\n return null;\n}\n"],"names":[
|
|
1
|
+
{"version":3,"file":"get-thread-mark-ids.js","sources":["../../src/comments/get-thread-mark-ids.ts"],"sourcesContent":["import type { LexicalNode, TextNode } from \"lexical\";\nimport { $isTextNode } from \"lexical\";\n\nimport { $isThreadMarkNode } from \"./thread-mark-node\";\n\nexport default function $getThreadMarkIds(\n node: TextNode,\n offset: number\n): null | Array<string> {\n let currentNode: LexicalNode | null = node;\n while (currentNode !== null) {\n if ($isThreadMarkNode(currentNode)) {\n return currentNode.getIDs();\n } else if (\n $isTextNode(currentNode) &&\n offset === currentNode.getTextContentSize()\n ) {\n const nextSibling = currentNode.getNextSibling();\n if ($isThreadMarkNode(nextSibling)) {\n return nextSibling.getIDs();\n }\n }\n currentNode = currentNode.getParent();\n }\n return null;\n}\n"],"names":[],"mappings":";;;AAKwB,SAAA,iBAAA,CACtB,MACA,MACsB,EAAA;AACtB,EAAA,IAAI,WAAkC,GAAA,IAAA,CAAA;AACtC,EAAA,OAAO,gBAAgB,IAAM,EAAA;AAC3B,IAAI,IAAA,iBAAA,CAAkB,WAAW,CAAG,EAAA;AAClC,MAAA,OAAO,YAAY,MAAO,EAAA,CAAA;AAAA,eAE1B,WAAY,CAAA,WAAW,KACvB,MAAW,KAAA,WAAA,CAAY,oBACvB,EAAA;AACA,MAAM,MAAA,WAAA,GAAc,YAAY,cAAe,EAAA,CAAA;AAC/C,MAAI,IAAA,iBAAA,CAAkB,WAAW,CAAG,EAAA;AAClC,QAAA,OAAO,YAAY,MAAO,EAAA,CAAA;AAAA,OAC5B;AAAA,KACF;AACA,IAAA,WAAA,GAAc,YAAY,SAAU,EAAA,CAAA;AAAA,GACtC;AACA,EAAO,OAAA,IAAA,CAAA;AACT;;;;"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
var lexical = require('lexical');
|
|
4
|
+
|
|
5
|
+
class ThreadMarkNode extends lexical.ElementNode {
|
|
4
6
|
__ids;
|
|
5
7
|
static getType() {
|
|
6
8
|
return "lb-thread-mark";
|
|
@@ -94,7 +96,7 @@ class ThreadMarkNode extends ElementNode {
|
|
|
94
96
|
return true;
|
|
95
97
|
}
|
|
96
98
|
extractWithChild(_, selection, destination) {
|
|
97
|
-
if (
|
|
99
|
+
if (!lexical.$isRangeSelection(selection) || destination === "html") {
|
|
98
100
|
return false;
|
|
99
101
|
}
|
|
100
102
|
const anchor = selection.anchor;
|
|
@@ -110,11 +112,13 @@ class ThreadMarkNode extends ElementNode {
|
|
|
110
112
|
}
|
|
111
113
|
}
|
|
112
114
|
function $createThreadMarkNode(ids) {
|
|
113
|
-
return
|
|
115
|
+
return lexical.$applyNodeReplacement(new ThreadMarkNode(ids));
|
|
114
116
|
}
|
|
115
117
|
function $isThreadMarkNode(node) {
|
|
116
118
|
return node instanceof ThreadMarkNode;
|
|
117
119
|
}
|
|
118
120
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
+
exports.$createThreadMarkNode = $createThreadMarkNode;
|
|
122
|
+
exports.$isThreadMarkNode = $isThreadMarkNode;
|
|
123
|
+
exports.ThreadMarkNode = ThreadMarkNode;
|
|
124
|
+
//# sourceMappingURL=thread-mark-node.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thread-mark-node.
|
|
1
|
+
{"version":3,"file":"thread-mark-node.cjs","sources":["../../src/comments/thread-mark-node.ts"],"sourcesContent":["import type {\n BaseSelection,\n LexicalNode,\n NodeKey,\n RangeSelection,\n SerializedElementNode,\n Spread,\n} from \"lexical\";\nimport { $applyNodeReplacement, $isRangeSelection, ElementNode } from \"lexical\";\n\nexport type SerializedThreadMarkNode = Spread<\n {\n ids: Array<string>;\n },\n SerializedElementNode\n>;\n\nexport class ThreadMarkNode extends ElementNode {\n /** @internal */\n __ids: Array<string>; // The ids of the threads that this mark is associated with\n\n static getType(): string {\n return \"lb-thread-mark\";\n }\n\n static clone(node: ThreadMarkNode): ThreadMarkNode {\n return new ThreadMarkNode(Array.from(node.__ids), node.__key);\n }\n\n static importDOM(): null {\n return null;\n }\n\n static importJSON(serializedNode: SerializedThreadMarkNode): ThreadMarkNode {\n const node = $createThreadMarkNode(serializedNode.ids);\n node.setFormat(serializedNode.format);\n node.setIndent(serializedNode.indent);\n node.setDirection(serializedNode.direction);\n return node;\n }\n\n exportJSON(): SerializedThreadMarkNode {\n return {\n ...super.exportJSON(),\n ids: this.getIDs(),\n type: \"lb-thread-mark\",\n version: 1,\n };\n }\n\n constructor(ids: Array<string>, key?: NodeKey) {\n super(key);\n this.__ids = ids || [];\n }\n\n createDOM(): HTMLElement {\n const element = document.createElement(\"span\");\n return element;\n }\n\n updateDOM(): boolean {\n return false;\n }\n\n hasID(id: string): boolean {\n const ids = this.getIDs();\n for (let i = 0; i < ids.length; i++) {\n if (id === ids[i]) {\n return true;\n }\n }\n return false;\n }\n\n getIDs(): Array<string> {\n const self = this.getLatest();\n return $isThreadMarkNode(self) ? self.__ids : [];\n }\n\n addID(id: string): void {\n const self = this.getWritable();\n if ($isThreadMarkNode(self)) {\n const ids = self.__ids;\n self.__ids = ids;\n for (let i = 0; i < ids.length; i++) {\n // If we already have it, don't add again\n if (id === ids[i]) {\n return;\n }\n }\n ids.push(id);\n }\n }\n\n deleteID(id: string): void {\n const self = this.getWritable();\n if ($isThreadMarkNode(self)) {\n const ids = self.__ids;\n self.__ids = ids;\n for (let i = 0; i < ids.length; i++) {\n if (id === ids[i]) {\n ids.splice(i, 1);\n return;\n }\n }\n }\n }\n\n insertNewAfter(\n _: RangeSelection,\n restoreSelection = true\n ): null | ElementNode {\n const markNode = $createThreadMarkNode(this.__ids);\n this.insertAfter(markNode, restoreSelection);\n return markNode;\n }\n\n canInsertTextBefore(): false {\n return false;\n }\n\n canInsertTextAfter(): false {\n return false;\n }\n\n canBeEmpty(): false {\n return false;\n }\n\n isInline(): true {\n return true;\n }\n\n extractWithChild(\n _: LexicalNode,\n selection: BaseSelection,\n destination: \"clone\" | \"html\"\n ): boolean {\n if (!$isRangeSelection(selection) || destination === \"html\") {\n return false;\n }\n const anchor = selection.anchor;\n const focus = selection.focus;\n const anchorNode = anchor.getNode();\n const focusNode = focus.getNode();\n const isBackward = selection.isBackward();\n const selectionLength = isBackward\n ? anchor.offset - focus.offset\n : focus.offset - anchor.offset;\n return (\n this.isParentOf(anchorNode) &&\n this.isParentOf(focusNode) &&\n this.getTextContent().length === selectionLength\n );\n }\n\n excludeFromCopy(destination: \"clone\" | \"html\"): boolean {\n return destination !== \"clone\";\n }\n}\n\nexport function $createThreadMarkNode(ids: Array<string>): ThreadMarkNode {\n return $applyNodeReplacement(new ThreadMarkNode(ids));\n}\n\nexport function $isThreadMarkNode(\n node: LexicalNode | null\n): node is ThreadMarkNode {\n return node instanceof ThreadMarkNode;\n}\n"],"names":["ElementNode","$isRangeSelection","$applyNodeReplacement"],"mappings":"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"}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { ElementNode, $isRangeSelection, $applyNodeReplacement } from 'lexical';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class ThreadMarkNode extends lexical.ElementNode {
|
|
3
|
+
class ThreadMarkNode extends ElementNode {
|
|
6
4
|
__ids;
|
|
7
5
|
static getType() {
|
|
8
6
|
return "lb-thread-mark";
|
|
@@ -96,7 +94,7 @@ class ThreadMarkNode extends lexical.ElementNode {
|
|
|
96
94
|
return true;
|
|
97
95
|
}
|
|
98
96
|
extractWithChild(_, selection, destination) {
|
|
99
|
-
if (
|
|
97
|
+
if (!$isRangeSelection(selection) || destination === "html") {
|
|
100
98
|
return false;
|
|
101
99
|
}
|
|
102
100
|
const anchor = selection.anchor;
|
|
@@ -112,13 +110,11 @@ class ThreadMarkNode extends lexical.ElementNode {
|
|
|
112
110
|
}
|
|
113
111
|
}
|
|
114
112
|
function $createThreadMarkNode(ids) {
|
|
115
|
-
return
|
|
113
|
+
return $applyNodeReplacement(new ThreadMarkNode(ids));
|
|
116
114
|
}
|
|
117
115
|
function $isThreadMarkNode(node) {
|
|
118
116
|
return node instanceof ThreadMarkNode;
|
|
119
117
|
}
|
|
120
118
|
|
|
121
|
-
|
|
122
|
-
exports.$isThreadMarkNode = $isThreadMarkNode;
|
|
123
|
-
exports.ThreadMarkNode = ThreadMarkNode;
|
|
119
|
+
export { $createThreadMarkNode, $isThreadMarkNode, ThreadMarkNode };
|
|
124
120
|
//# sourceMappingURL=thread-mark-node.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thread-mark-node.js","sources":["../../src/comments/thread-mark-node.ts"],"sourcesContent":["import type {\n BaseSelection,\n LexicalNode,\n NodeKey,\n RangeSelection,\n SerializedElementNode,\n Spread,\n} from \"lexical\";\nimport { $applyNodeReplacement, $isRangeSelection, ElementNode } from \"lexical\";\n\nexport type SerializedThreadMarkNode = Spread<\n {\n ids: Array<string>;\n },\n SerializedElementNode\n>;\n\nexport class ThreadMarkNode extends ElementNode {\n /** @internal */\n __ids: Array<string>; // The ids of the threads that this mark is associated with\n\n static getType(): string {\n return \"lb-thread-mark\";\n }\n\n static clone(node: ThreadMarkNode): ThreadMarkNode {\n return new ThreadMarkNode(Array.from(node.__ids), node.__key);\n }\n\n static importDOM(): null {\n return null;\n }\n\n static importJSON(serializedNode: SerializedThreadMarkNode): ThreadMarkNode {\n const node = $createThreadMarkNode(serializedNode.ids);\n node.setFormat(serializedNode.format);\n node.setIndent(serializedNode.indent);\n node.setDirection(serializedNode.direction);\n return node;\n }\n\n exportJSON(): SerializedThreadMarkNode {\n return {\n ...super.exportJSON(),\n ids: this.getIDs(),\n type: \"lb-thread-mark\",\n version: 1,\n };\n }\n\n constructor(ids: Array<string>, key?: NodeKey) {\n super(key);\n this.__ids = ids || [];\n }\n\n createDOM(): HTMLElement {\n const element = document.createElement(\"span\");\n return element;\n }\n\n updateDOM(): boolean {\n return false;\n }\n\n hasID(id: string): boolean {\n const ids = this.getIDs();\n for (let i = 0; i < ids.length; i++) {\n if (id === ids[i]) {\n return true;\n }\n }\n return false;\n }\n\n getIDs(): Array<string> {\n const self = this.getLatest();\n return $isThreadMarkNode(self) ? self.__ids : [];\n }\n\n addID(id: string): void {\n const self = this.getWritable();\n if ($isThreadMarkNode(self)) {\n const ids = self.__ids;\n self.__ids = ids;\n for (let i = 0; i < ids.length; i++) {\n // If we already have it, don't add again\n if (id === ids[i]) {\n return;\n }\n }\n ids.push(id);\n }\n }\n\n deleteID(id: string): void {\n const self = this.getWritable();\n if ($isThreadMarkNode(self)) {\n const ids = self.__ids;\n self.__ids = ids;\n for (let i = 0; i < ids.length; i++) {\n if (id === ids[i]) {\n ids.splice(i, 1);\n return;\n }\n }\n }\n }\n\n insertNewAfter(\n _: RangeSelection,\n restoreSelection = true\n ): null | ElementNode {\n const markNode = $createThreadMarkNode(this.__ids);\n this.insertAfter(markNode, restoreSelection);\n return markNode;\n }\n\n canInsertTextBefore(): false {\n return false;\n }\n\n canInsertTextAfter(): false {\n return false;\n }\n\n canBeEmpty(): false {\n return false;\n }\n\n isInline(): true {\n return true;\n }\n\n extractWithChild(\n _: LexicalNode,\n selection: BaseSelection,\n destination: \"clone\" | \"html\"\n ): boolean {\n if (!$isRangeSelection(selection) || destination === \"html\") {\n return false;\n }\n const anchor = selection.anchor;\n const focus = selection.focus;\n const anchorNode = anchor.getNode();\n const focusNode = focus.getNode();\n const isBackward = selection.isBackward();\n const selectionLength = isBackward\n ? anchor.offset - focus.offset\n : focus.offset - anchor.offset;\n return (\n this.isParentOf(anchorNode) &&\n this.isParentOf(focusNode) &&\n this.getTextContent().length === selectionLength\n );\n }\n\n excludeFromCopy(destination: \"clone\" | \"html\"): boolean {\n return destination !== \"clone\";\n }\n}\n\nexport function $createThreadMarkNode(ids: Array<string>): ThreadMarkNode {\n return $applyNodeReplacement(new ThreadMarkNode(ids));\n}\n\nexport function $isThreadMarkNode(\n node: LexicalNode | null\n): node is ThreadMarkNode {\n return node instanceof ThreadMarkNode;\n}\n"],"names":[
|
|
1
|
+
{"version":3,"file":"thread-mark-node.js","sources":["../../src/comments/thread-mark-node.ts"],"sourcesContent":["import type {\n BaseSelection,\n LexicalNode,\n NodeKey,\n RangeSelection,\n SerializedElementNode,\n Spread,\n} from \"lexical\";\nimport { $applyNodeReplacement, $isRangeSelection, ElementNode } from \"lexical\";\n\nexport type SerializedThreadMarkNode = Spread<\n {\n ids: Array<string>;\n },\n SerializedElementNode\n>;\n\nexport class ThreadMarkNode extends ElementNode {\n /** @internal */\n __ids: Array<string>; // The ids of the threads that this mark is associated with\n\n static getType(): string {\n return \"lb-thread-mark\";\n }\n\n static clone(node: ThreadMarkNode): ThreadMarkNode {\n return new ThreadMarkNode(Array.from(node.__ids), node.__key);\n }\n\n static importDOM(): null {\n return null;\n }\n\n static importJSON(serializedNode: SerializedThreadMarkNode): ThreadMarkNode {\n const node = $createThreadMarkNode(serializedNode.ids);\n node.setFormat(serializedNode.format);\n node.setIndent(serializedNode.indent);\n node.setDirection(serializedNode.direction);\n return node;\n }\n\n exportJSON(): SerializedThreadMarkNode {\n return {\n ...super.exportJSON(),\n ids: this.getIDs(),\n type: \"lb-thread-mark\",\n version: 1,\n };\n }\n\n constructor(ids: Array<string>, key?: NodeKey) {\n super(key);\n this.__ids = ids || [];\n }\n\n createDOM(): HTMLElement {\n const element = document.createElement(\"span\");\n return element;\n }\n\n updateDOM(): boolean {\n return false;\n }\n\n hasID(id: string): boolean {\n const ids = this.getIDs();\n for (let i = 0; i < ids.length; i++) {\n if (id === ids[i]) {\n return true;\n }\n }\n return false;\n }\n\n getIDs(): Array<string> {\n const self = this.getLatest();\n return $isThreadMarkNode(self) ? self.__ids : [];\n }\n\n addID(id: string): void {\n const self = this.getWritable();\n if ($isThreadMarkNode(self)) {\n const ids = self.__ids;\n self.__ids = ids;\n for (let i = 0; i < ids.length; i++) {\n // If we already have it, don't add again\n if (id === ids[i]) {\n return;\n }\n }\n ids.push(id);\n }\n }\n\n deleteID(id: string): void {\n const self = this.getWritable();\n if ($isThreadMarkNode(self)) {\n const ids = self.__ids;\n self.__ids = ids;\n for (let i = 0; i < ids.length; i++) {\n if (id === ids[i]) {\n ids.splice(i, 1);\n return;\n }\n }\n }\n }\n\n insertNewAfter(\n _: RangeSelection,\n restoreSelection = true\n ): null | ElementNode {\n const markNode = $createThreadMarkNode(this.__ids);\n this.insertAfter(markNode, restoreSelection);\n return markNode;\n }\n\n canInsertTextBefore(): false {\n return false;\n }\n\n canInsertTextAfter(): false {\n return false;\n }\n\n canBeEmpty(): false {\n return false;\n }\n\n isInline(): true {\n return true;\n }\n\n extractWithChild(\n _: LexicalNode,\n selection: BaseSelection,\n destination: \"clone\" | \"html\"\n ): boolean {\n if (!$isRangeSelection(selection) || destination === \"html\") {\n return false;\n }\n const anchor = selection.anchor;\n const focus = selection.focus;\n const anchorNode = anchor.getNode();\n const focusNode = focus.getNode();\n const isBackward = selection.isBackward();\n const selectionLength = isBackward\n ? anchor.offset - focus.offset\n : focus.offset - anchor.offset;\n return (\n this.isParentOf(anchorNode) &&\n this.isParentOf(focusNode) &&\n this.getTextContent().length === selectionLength\n );\n }\n\n excludeFromCopy(destination: \"clone\" | \"html\"): boolean {\n return destination !== \"clone\";\n }\n}\n\nexport function $createThreadMarkNode(ids: Array<string>): ThreadMarkNode {\n return $applyNodeReplacement(new ThreadMarkNode(ids));\n}\n\nexport function $isThreadMarkNode(\n node: LexicalNode | null\n): node is ThreadMarkNode {\n return node instanceof ThreadMarkNode;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
1
3
|
function $unwrapThreadMarkNode(node) {
|
|
2
4
|
const children = node.getChildren();
|
|
3
5
|
let target = null;
|
|
@@ -13,5 +15,5 @@ function $unwrapThreadMarkNode(node) {
|
|
|
13
15
|
node.remove();
|
|
14
16
|
}
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
//# sourceMappingURL=unwrap-thread-mark-node.
|
|
18
|
+
module.exports = $unwrapThreadMarkNode;
|
|
19
|
+
//# sourceMappingURL=unwrap-thread-mark-node.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unwrap-thread-mark-node.cjs","sources":["../../src/comments/unwrap-thread-mark-node.ts"],"sourcesContent":["import type { ThreadMarkNode } from \"./thread-mark-node\";\n\nexport default function $unwrapThreadMarkNode(node: ThreadMarkNode): void {\n const children = node.getChildren();\n let target = null;\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if (target === null) {\n node.insertBefore(child);\n } else {\n target.insertAfter(child);\n }\n target = child;\n }\n node.remove();\n}\n"],"names":[],"mappings":";;AAEA,SAAwB,sBAAsB,IAA4B,EAAA;AACxE,EAAM,MAAA,QAAA,GAAW,KAAK,WAAY,EAAA,CAAA;AAClC,EAAA,IAAI,MAAS,GAAA,IAAA,CAAA;AACb,EAAA,KAAA,IAAS,CAAI,GAAA,CAAA,EAAG,CAAI,GAAA,QAAA,CAAS,QAAQ,CAAK,EAAA,EAAA;AACxC,IAAA,MAAM,QAAQ,QAAS,CAAA,CAAA,CAAA,CAAA;AACvB,IAAA,IAAI,WAAW,IAAM,EAAA;AACnB,MAAA,IAAA,CAAK,aAAa,KAAK,CAAA,CAAA;AAAA,KAClB,MAAA;AACL,MAAA,MAAA,CAAO,YAAY,KAAK,CAAA,CAAA;AAAA,KAC1B;AACA,IAAS,MAAA,GAAA,KAAA,CAAA;AAAA,GACX;AACA,EAAA,IAAA,CAAK,MAAO,EAAA,CAAA;AACd;;;;"}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
1
|
function $unwrapThreadMarkNode(node) {
|
|
4
2
|
const children = node.getChildren();
|
|
5
3
|
let target = null;
|
|
@@ -15,5 +13,5 @@ function $unwrapThreadMarkNode(node) {
|
|
|
15
13
|
node.remove();
|
|
16
14
|
}
|
|
17
15
|
|
|
18
|
-
|
|
16
|
+
export { $unwrapThreadMarkNode as default };
|
|
19
17
|
//# sourceMappingURL=unwrap-thread-mark-node.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unwrap-thread-mark-node.js","sources":["../../src/comments/unwrap-thread-mark-node.ts"],"sourcesContent":["import type { ThreadMarkNode } from \"./thread-mark-node\";\n\nexport default function $unwrapThreadMarkNode(node: ThreadMarkNode): void {\n const children = node.getChildren();\n let target = null;\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if (target === null) {\n node.insertBefore(child);\n } else {\n target.insertAfter(child);\n }\n target = child;\n }\n node.remove();\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"unwrap-thread-mark-node.js","sources":["../../src/comments/unwrap-thread-mark-node.ts"],"sourcesContent":["import type { ThreadMarkNode } from \"./thread-mark-node\";\n\nexport default function $unwrapThreadMarkNode(node: ThreadMarkNode): void {\n const children = node.getChildren();\n let target = null;\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if (target === null) {\n node.insertBefore(child);\n } else {\n target.insertAfter(child);\n }\n target = child;\n }\n node.remove();\n}\n"],"names":[],"mappings":"AAEA,SAAwB,sBAAsB,IAA4B,EAAA;AACxE,EAAM,MAAA,QAAA,GAAW,KAAK,WAAY,EAAA,CAAA;AAClC,EAAA,IAAI,MAAS,GAAA,IAAA,CAAA;AACb,EAAA,KAAA,IAAS,CAAI,GAAA,CAAA,EAAG,CAAI,GAAA,QAAA,CAAS,QAAQ,CAAK,EAAA,EAAA;AACxC,IAAA,MAAM,QAAQ,QAAS,CAAA,CAAA,CAAA,CAAA;AACvB,IAAA,IAAI,WAAW,IAAM,EAAA;AACnB,MAAA,IAAA,CAAK,aAAa,KAAK,CAAA,CAAA;AAAA,KAClB,MAAA;AACL,MAAA,MAAA,CAAO,YAAY,KAAK,CAAA,CAAA;AAAA,KAC1B;AACA,IAAS,MAAA,GAAA,KAAA,CAAA;AAAA,GACX;AACA,EAAA,IAAA,CAAK,MAAO,EAAA,CAAA;AACd;;;;"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var lexical = require('lexical');
|
|
4
|
+
var threadMarkNode = require('./thread-mark-node.cjs');
|
|
3
5
|
|
|
4
6
|
function $wrapSelectionInThreadMarkNode(selection, isBackward, id, createNode) {
|
|
5
7
|
const nodes = selection.getNodes();
|
|
@@ -12,13 +14,13 @@ function $wrapSelectionInThreadMarkNode(selection, isBackward, id, createNode) {
|
|
|
12
14
|
let lastCreatedMarkNode;
|
|
13
15
|
for (let i = 0; i < nodesLength; i++) {
|
|
14
16
|
const node = nodes[i];
|
|
15
|
-
if (
|
|
17
|
+
if (lexical.$isElementNode(lastCreatedMarkNode) && lastCreatedMarkNode.isParentOf(node)) {
|
|
16
18
|
continue;
|
|
17
19
|
}
|
|
18
20
|
const isFirstNode = i === 0;
|
|
19
21
|
const isLastNode = i === nodesLength - 1;
|
|
20
22
|
let targetNode = null;
|
|
21
|
-
if (
|
|
23
|
+
if (lexical.$isTextNode(node)) {
|
|
22
24
|
const textContentSize = node.getTextContentSize();
|
|
23
25
|
const startTextOffset = isFirstNode ? startOffset : 0;
|
|
24
26
|
const endTextOffset = isLastNode ? endOffset : textContentSize;
|
|
@@ -27,9 +29,9 @@ function $wrapSelectionInThreadMarkNode(selection, isBackward, id, createNode) {
|
|
|
27
29
|
}
|
|
28
30
|
const splitNodes = node.splitText(startTextOffset, endTextOffset);
|
|
29
31
|
targetNode = splitNodes.length > 1 && (splitNodes.length === 3 || isFirstNode && !isLastNode || endTextOffset === textContentSize) ? splitNodes[1] : splitNodes[0];
|
|
30
|
-
} else if (
|
|
32
|
+
} else if (threadMarkNode.$isThreadMarkNode(node)) {
|
|
31
33
|
continue;
|
|
32
|
-
} else if (
|
|
34
|
+
} else if (lexical.$isElementNode(node) && node.isInline()) {
|
|
33
35
|
targetNode = node;
|
|
34
36
|
}
|
|
35
37
|
if (targetNode !== null) {
|
|
@@ -42,7 +44,7 @@ function $wrapSelectionInThreadMarkNode(selection, isBackward, id, createNode) {
|
|
|
42
44
|
}
|
|
43
45
|
currentNodeParent = parentNode;
|
|
44
46
|
if (lastCreatedMarkNode === void 0) {
|
|
45
|
-
const createMarkNode = createNode ||
|
|
47
|
+
const createMarkNode = createNode || threadMarkNode.$createThreadMarkNode;
|
|
46
48
|
lastCreatedMarkNode = createMarkNode([id]);
|
|
47
49
|
targetNode.insertBefore(lastCreatedMarkNode);
|
|
48
50
|
}
|
|
@@ -52,10 +54,10 @@ function $wrapSelectionInThreadMarkNode(selection, isBackward, id, createNode) {
|
|
|
52
54
|
lastCreatedMarkNode = void 0;
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
|
-
if (
|
|
57
|
+
if (lexical.$isElementNode(lastCreatedMarkNode)) {
|
|
56
58
|
isBackward ? lastCreatedMarkNode.selectStart() : lastCreatedMarkNode.selectEnd();
|
|
57
59
|
}
|
|
58
60
|
}
|
|
59
61
|
|
|
60
|
-
|
|
61
|
-
//# sourceMappingURL=wrap-selection-in-thread-mark-node.
|
|
62
|
+
module.exports = $wrapSelectionInThreadMarkNode;
|
|
63
|
+
//# sourceMappingURL=wrap-selection-in-thread-mark-node.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wrap-selection-in-thread-mark-node.
|
|
1
|
+
{"version":3,"file":"wrap-selection-in-thread-mark-node.cjs","sources":["../../src/comments/wrap-selection-in-thread-mark-node.ts"],"sourcesContent":["/**\n * MIT License\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport type { LexicalNode, RangeSelection } from \"lexical\";\nimport { $isElementNode, $isTextNode } from \"lexical\";\n\nimport type { ThreadMarkNode } from \"./thread-mark-node\";\nimport { $createThreadMarkNode, $isThreadMarkNode } from \"./thread-mark-node\";\n\nexport default function $wrapSelectionInThreadMarkNode(\n selection: RangeSelection,\n isBackward: boolean,\n id: string,\n createNode?: (ids: Array<string>) => ThreadMarkNode\n): void {\n const nodes = selection.getNodes();\n const anchorOffset = selection.anchor.offset;\n const focusOffset = selection.focus.offset;\n const nodesLength = nodes.length;\n const startOffset = isBackward ? focusOffset : anchorOffset;\n const endOffset = isBackward ? anchorOffset : focusOffset;\n let currentNodeParent;\n let lastCreatedMarkNode;\n\n // We only want wrap adjacent text nodes, line break nodes\n // and inline element nodes. For decorator nodes and block\n // element nodes, we step out of their boundary and start\n // again after, if there are more nodes.\n for (let i = 0; i < nodesLength; i++) {\n const node = nodes[i];\n if (\n $isElementNode(lastCreatedMarkNode) &&\n lastCreatedMarkNode.isParentOf(node)\n ) {\n // If the current node is a child of the last created mark node, there is nothing to do here\n continue;\n }\n const isFirstNode = i === 0;\n const isLastNode = i === nodesLength - 1;\n let targetNode: LexicalNode | null = null;\n\n if ($isTextNode(node)) {\n // Case 1: The node is a text node and we can split it\n const textContentSize = node.getTextContentSize();\n const startTextOffset = isFirstNode ? startOffset : 0;\n const endTextOffset = isLastNode ? endOffset : textContentSize;\n if (startTextOffset === 0 && endTextOffset === 0) {\n continue;\n }\n const splitNodes = node.splitText(startTextOffset, endTextOffset);\n targetNode =\n splitNodes.length > 1 &&\n (splitNodes.length === 3 ||\n (isFirstNode && !isLastNode) ||\n endTextOffset === textContentSize)\n ? splitNodes[1]\n : splitNodes[0];\n } else if ($isThreadMarkNode(node)) {\n // Case 2: the node is a mark node and we can ignore it as a target,\n // moving on to its children. Note that when we make a mark inside\n // another mark, it may utlimately be unnested by a call to\n // `registerNestedElementResolver<MarkNode>` somewhere else in the\n // codebase.\n\n continue;\n } else if ($isElementNode(node) && node.isInline()) {\n // Case 3: inline element nodes can be added in their entirety to the new\n // mark\n targetNode = node;\n }\n\n if (targetNode !== null) {\n // Now that we have a target node for wrapping with a mark, we can run\n // through special cases.\n if (targetNode && targetNode.is(currentNodeParent)) {\n // The current node is a child of the target node to be wrapped, there\n // is nothing to do here.\n continue;\n }\n const parentNode = targetNode.getParent();\n if (parentNode === null || !parentNode.is(currentNodeParent)) {\n // If the parent node is not the current node's parent node, we can\n // clear the last created mark node.\n lastCreatedMarkNode = undefined;\n }\n\n currentNodeParent = parentNode;\n\n if (lastCreatedMarkNode === undefined) {\n // If we don't have a created mark node, we can make one\n const createMarkNode = createNode || $createThreadMarkNode;\n lastCreatedMarkNode = createMarkNode([id]);\n targetNode.insertBefore(lastCreatedMarkNode);\n }\n\n // Add the target node to be wrapped in the latest created mark node\n lastCreatedMarkNode.append(targetNode);\n } else {\n // If we don't have a target node to wrap we can clear our state and\n // continue on with the next node\n currentNodeParent = undefined;\n lastCreatedMarkNode = undefined;\n }\n }\n // Make selection collapsed at the end\n if ($isElementNode(lastCreatedMarkNode)) {\n // eslint-disable-next-line no-unused-expressions\n isBackward\n ? lastCreatedMarkNode.selectStart()\n : lastCreatedMarkNode.selectEnd();\n }\n}\n"],"names":["$isElementNode","$isTextNode","$isThreadMarkNode","$createThreadMarkNode"],"mappings":"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"}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
var lexical = require('lexical');
|
|
4
|
-
var threadMarkNode = require('./thread-mark-node.js');
|
|
1
|
+
import { $isElementNode, $isTextNode } from 'lexical';
|
|
2
|
+
import { $isThreadMarkNode, $createThreadMarkNode } from './thread-mark-node.js';
|
|
5
3
|
|
|
6
4
|
function $wrapSelectionInThreadMarkNode(selection, isBackward, id, createNode) {
|
|
7
5
|
const nodes = selection.getNodes();
|
|
@@ -14,13 +12,13 @@ function $wrapSelectionInThreadMarkNode(selection, isBackward, id, createNode) {
|
|
|
14
12
|
let lastCreatedMarkNode;
|
|
15
13
|
for (let i = 0; i < nodesLength; i++) {
|
|
16
14
|
const node = nodes[i];
|
|
17
|
-
if (
|
|
15
|
+
if ($isElementNode(lastCreatedMarkNode) && lastCreatedMarkNode.isParentOf(node)) {
|
|
18
16
|
continue;
|
|
19
17
|
}
|
|
20
18
|
const isFirstNode = i === 0;
|
|
21
19
|
const isLastNode = i === nodesLength - 1;
|
|
22
20
|
let targetNode = null;
|
|
23
|
-
if (
|
|
21
|
+
if ($isTextNode(node)) {
|
|
24
22
|
const textContentSize = node.getTextContentSize();
|
|
25
23
|
const startTextOffset = isFirstNode ? startOffset : 0;
|
|
26
24
|
const endTextOffset = isLastNode ? endOffset : textContentSize;
|
|
@@ -29,9 +27,9 @@ function $wrapSelectionInThreadMarkNode(selection, isBackward, id, createNode) {
|
|
|
29
27
|
}
|
|
30
28
|
const splitNodes = node.splitText(startTextOffset, endTextOffset);
|
|
31
29
|
targetNode = splitNodes.length > 1 && (splitNodes.length === 3 || isFirstNode && !isLastNode || endTextOffset === textContentSize) ? splitNodes[1] : splitNodes[0];
|
|
32
|
-
} else if (
|
|
30
|
+
} else if ($isThreadMarkNode(node)) {
|
|
33
31
|
continue;
|
|
34
|
-
} else if (
|
|
32
|
+
} else if ($isElementNode(node) && node.isInline()) {
|
|
35
33
|
targetNode = node;
|
|
36
34
|
}
|
|
37
35
|
if (targetNode !== null) {
|
|
@@ -44,7 +42,7 @@ function $wrapSelectionInThreadMarkNode(selection, isBackward, id, createNode) {
|
|
|
44
42
|
}
|
|
45
43
|
currentNodeParent = parentNode;
|
|
46
44
|
if (lastCreatedMarkNode === void 0) {
|
|
47
|
-
const createMarkNode = createNode ||
|
|
45
|
+
const createMarkNode = createNode || $createThreadMarkNode;
|
|
48
46
|
lastCreatedMarkNode = createMarkNode([id]);
|
|
49
47
|
targetNode.insertBefore(lastCreatedMarkNode);
|
|
50
48
|
}
|
|
@@ -54,10 +52,10 @@ function $wrapSelectionInThreadMarkNode(selection, isBackward, id, createNode) {
|
|
|
54
52
|
lastCreatedMarkNode = void 0;
|
|
55
53
|
}
|
|
56
54
|
}
|
|
57
|
-
if (
|
|
55
|
+
if ($isElementNode(lastCreatedMarkNode)) {
|
|
58
56
|
isBackward ? lastCreatedMarkNode.selectStart() : lastCreatedMarkNode.selectEnd();
|
|
59
57
|
}
|
|
60
58
|
}
|
|
61
59
|
|
|
62
|
-
|
|
60
|
+
export { $wrapSelectionInThreadMarkNode as default };
|
|
63
61
|
//# sourceMappingURL=wrap-selection-in-thread-mark-node.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wrap-selection-in-thread-mark-node.js","sources":["../../src/comments/wrap-selection-in-thread-mark-node.ts"],"sourcesContent":["/**\n * MIT License\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport type { LexicalNode, RangeSelection } from \"lexical\";\nimport { $isElementNode, $isTextNode } from \"lexical\";\n\nimport type { ThreadMarkNode } from \"./thread-mark-node\";\nimport { $createThreadMarkNode, $isThreadMarkNode } from \"./thread-mark-node\";\n\nexport default function $wrapSelectionInThreadMarkNode(\n selection: RangeSelection,\n isBackward: boolean,\n id: string,\n createNode?: (ids: Array<string>) => ThreadMarkNode\n): void {\n const nodes = selection.getNodes();\n const anchorOffset = selection.anchor.offset;\n const focusOffset = selection.focus.offset;\n const nodesLength = nodes.length;\n const startOffset = isBackward ? focusOffset : anchorOffset;\n const endOffset = isBackward ? anchorOffset : focusOffset;\n let currentNodeParent;\n let lastCreatedMarkNode;\n\n // We only want wrap adjacent text nodes, line break nodes\n // and inline element nodes. For decorator nodes and block\n // element nodes, we step out of their boundary and start\n // again after, if there are more nodes.\n for (let i = 0; i < nodesLength; i++) {\n const node = nodes[i];\n if (\n $isElementNode(lastCreatedMarkNode) &&\n lastCreatedMarkNode.isParentOf(node)\n ) {\n // If the current node is a child of the last created mark node, there is nothing to do here\n continue;\n }\n const isFirstNode = i === 0;\n const isLastNode = i === nodesLength - 1;\n let targetNode: LexicalNode | null = null;\n\n if ($isTextNode(node)) {\n // Case 1: The node is a text node and we can split it\n const textContentSize = node.getTextContentSize();\n const startTextOffset = isFirstNode ? startOffset : 0;\n const endTextOffset = isLastNode ? endOffset : textContentSize;\n if (startTextOffset === 0 && endTextOffset === 0) {\n continue;\n }\n const splitNodes = node.splitText(startTextOffset, endTextOffset);\n targetNode =\n splitNodes.length > 1 &&\n (splitNodes.length === 3 ||\n (isFirstNode && !isLastNode) ||\n endTextOffset === textContentSize)\n ? splitNodes[1]\n : splitNodes[0];\n } else if ($isThreadMarkNode(node)) {\n // Case 2: the node is a mark node and we can ignore it as a target,\n // moving on to its children. Note that when we make a mark inside\n // another mark, it may utlimately be unnested by a call to\n // `registerNestedElementResolver<MarkNode>` somewhere else in the\n // codebase.\n\n continue;\n } else if ($isElementNode(node) && node.isInline()) {\n // Case 3: inline element nodes can be added in their entirety to the new\n // mark\n targetNode = node;\n }\n\n if (targetNode !== null) {\n // Now that we have a target node for wrapping with a mark, we can run\n // through special cases.\n if (targetNode && targetNode.is(currentNodeParent)) {\n // The current node is a child of the target node to be wrapped, there\n // is nothing to do here.\n continue;\n }\n const parentNode = targetNode.getParent();\n if (parentNode === null || !parentNode.is(currentNodeParent)) {\n // If the parent node is not the current node's parent node, we can\n // clear the last created mark node.\n lastCreatedMarkNode = undefined;\n }\n\n currentNodeParent = parentNode;\n\n if (lastCreatedMarkNode === undefined) {\n // If we don't have a created mark node, we can make one\n const createMarkNode = createNode || $createThreadMarkNode;\n lastCreatedMarkNode = createMarkNode([id]);\n targetNode.insertBefore(lastCreatedMarkNode);\n }\n\n // Add the target node to be wrapped in the latest created mark node\n lastCreatedMarkNode.append(targetNode);\n } else {\n // If we don't have a target node to wrap we can clear our state and\n // continue on with the next node\n currentNodeParent = undefined;\n lastCreatedMarkNode = undefined;\n }\n }\n // Make selection collapsed at the end\n if ($isElementNode(lastCreatedMarkNode)) {\n // eslint-disable-next-line no-unused-expressions\n isBackward\n ? lastCreatedMarkNode.selectStart()\n : lastCreatedMarkNode.selectEnd();\n }\n}\n"],"names":[
|
|
1
|
+
{"version":3,"file":"wrap-selection-in-thread-mark-node.js","sources":["../../src/comments/wrap-selection-in-thread-mark-node.ts"],"sourcesContent":["/**\n * MIT License\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport type { LexicalNode, RangeSelection } from \"lexical\";\nimport { $isElementNode, $isTextNode } from \"lexical\";\n\nimport type { ThreadMarkNode } from \"./thread-mark-node\";\nimport { $createThreadMarkNode, $isThreadMarkNode } from \"./thread-mark-node\";\n\nexport default function $wrapSelectionInThreadMarkNode(\n selection: RangeSelection,\n isBackward: boolean,\n id: string,\n createNode?: (ids: Array<string>) => ThreadMarkNode\n): void {\n const nodes = selection.getNodes();\n const anchorOffset = selection.anchor.offset;\n const focusOffset = selection.focus.offset;\n const nodesLength = nodes.length;\n const startOffset = isBackward ? focusOffset : anchorOffset;\n const endOffset = isBackward ? anchorOffset : focusOffset;\n let currentNodeParent;\n let lastCreatedMarkNode;\n\n // We only want wrap adjacent text nodes, line break nodes\n // and inline element nodes. For decorator nodes and block\n // element nodes, we step out of their boundary and start\n // again after, if there are more nodes.\n for (let i = 0; i < nodesLength; i++) {\n const node = nodes[i];\n if (\n $isElementNode(lastCreatedMarkNode) &&\n lastCreatedMarkNode.isParentOf(node)\n ) {\n // If the current node is a child of the last created mark node, there is nothing to do here\n continue;\n }\n const isFirstNode = i === 0;\n const isLastNode = i === nodesLength - 1;\n let targetNode: LexicalNode | null = null;\n\n if ($isTextNode(node)) {\n // Case 1: The node is a text node and we can split it\n const textContentSize = node.getTextContentSize();\n const startTextOffset = isFirstNode ? startOffset : 0;\n const endTextOffset = isLastNode ? endOffset : textContentSize;\n if (startTextOffset === 0 && endTextOffset === 0) {\n continue;\n }\n const splitNodes = node.splitText(startTextOffset, endTextOffset);\n targetNode =\n splitNodes.length > 1 &&\n (splitNodes.length === 3 ||\n (isFirstNode && !isLastNode) ||\n endTextOffset === textContentSize)\n ? splitNodes[1]\n : splitNodes[0];\n } else if ($isThreadMarkNode(node)) {\n // Case 2: the node is a mark node and we can ignore it as a target,\n // moving on to its children. Note that when we make a mark inside\n // another mark, it may utlimately be unnested by a call to\n // `registerNestedElementResolver<MarkNode>` somewhere else in the\n // codebase.\n\n continue;\n } else if ($isElementNode(node) && node.isInline()) {\n // Case 3: inline element nodes can be added in their entirety to the new\n // mark\n targetNode = node;\n }\n\n if (targetNode !== null) {\n // Now that we have a target node for wrapping with a mark, we can run\n // through special cases.\n if (targetNode && targetNode.is(currentNodeParent)) {\n // The current node is a child of the target node to be wrapped, there\n // is nothing to do here.\n continue;\n }\n const parentNode = targetNode.getParent();\n if (parentNode === null || !parentNode.is(currentNodeParent)) {\n // If the parent node is not the current node's parent node, we can\n // clear the last created mark node.\n lastCreatedMarkNode = undefined;\n }\n\n currentNodeParent = parentNode;\n\n if (lastCreatedMarkNode === undefined) {\n // If we don't have a created mark node, we can make one\n const createMarkNode = createNode || $createThreadMarkNode;\n lastCreatedMarkNode = createMarkNode([id]);\n targetNode.insertBefore(lastCreatedMarkNode);\n }\n\n // Add the target node to be wrapped in the latest created mark node\n lastCreatedMarkNode.append(targetNode);\n } else {\n // If we don't have a target node to wrap we can clear our state and\n // continue on with the next node\n currentNodeParent = undefined;\n lastCreatedMarkNode = undefined;\n }\n }\n // Make selection collapsed at the end\n if ($isElementNode(lastCreatedMarkNode)) {\n // eslint-disable-next-line no-unused-expressions\n isBackward\n ? lastCreatedMarkNode.selectStart()\n : lastCreatedMarkNode.selectEnd();\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var lexical = require('lexical');
|
|
2
4
|
|
|
3
5
|
function getDOMTextNode(element) {
|
|
4
6
|
let node = element;
|
|
@@ -25,10 +27,10 @@ function createDOMRange(editor, anchorNode, _anchorOffset, focusNode, _focusOffs
|
|
|
25
27
|
let focusDOM = editor.getElementByKey(focusKey);
|
|
26
28
|
let anchorOffset = _anchorOffset;
|
|
27
29
|
let focusOffset = _focusOffset;
|
|
28
|
-
if (
|
|
30
|
+
if (lexical.$isTextNode(anchorNode)) {
|
|
29
31
|
anchorDOM = getDOMTextNode(anchorDOM);
|
|
30
32
|
}
|
|
31
|
-
if (
|
|
33
|
+
if (lexical.$isTextNode(focusNode)) {
|
|
32
34
|
focusDOM = getDOMTextNode(focusDOM);
|
|
33
35
|
}
|
|
34
36
|
if (anchorNode === void 0 || focusNode === void 0 || anchorDOM === null || focusDOM === null) {
|
|
@@ -57,5 +59,5 @@ function createDOMRange(editor, anchorNode, _anchorOffset, focusNode, _focusOffs
|
|
|
57
59
|
return range;
|
|
58
60
|
}
|
|
59
61
|
|
|
60
|
-
|
|
61
|
-
//# sourceMappingURL=create-dom-range.
|
|
62
|
+
exports.createDOMRange = createDOMRange;
|
|
63
|
+
//# sourceMappingURL=create-dom-range.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-dom-range.
|
|
1
|
+
{"version":3,"file":"create-dom-range.cjs","sources":["../src/create-dom-range.ts"],"sourcesContent":["/**\n * MIT License\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport type { LexicalEditor, LexicalNode } from \"lexical\";\nimport { $isTextNode } from \"lexical\";\n\nfunction getDOMTextNode(element: Node | null): Text | null {\n let node = element;\n\n while (node !== null) {\n if (node.nodeType === Node.TEXT_NODE) {\n return node as Text;\n }\n\n node = node.firstChild;\n }\n\n return null;\n}\n\nfunction getDOMIndexWithinParent(node: ChildNode): [ParentNode, number] {\n const parent = node.parentNode;\n\n if (parent === null) {\n throw new Error(\"Should never happen\");\n }\n\n return [parent, Array.from(parent.childNodes).indexOf(node)];\n}\n\n/**\n * Creates a selection range for the DOM.\n * @param editor - The lexical editor.\n * @param anchorNode - The anchor node of a selection.\n * @param _anchorOffset - The amount of space offset from the anchor to the focus.\n * @param focusNode - The current focus.\n * @param _focusOffset - The amount of space offset from the focus to the anchor.\n * @returns The range of selection for the DOM that was created.\n */\nexport function createDOMRange(\n editor: LexicalEditor,\n anchorNode: LexicalNode,\n _anchorOffset: number,\n focusNode: LexicalNode,\n _focusOffset: number\n): Range | null {\n const anchorKey = anchorNode.getKey();\n const focusKey = focusNode.getKey();\n const range = document.createRange();\n let anchorDOM: Node | Text | null = editor.getElementByKey(anchorKey);\n let focusDOM: Node | Text | null = editor.getElementByKey(focusKey);\n let anchorOffset = _anchorOffset;\n let focusOffset = _focusOffset;\n\n if ($isTextNode(anchorNode)) {\n anchorDOM = getDOMTextNode(anchorDOM);\n }\n\n if ($isTextNode(focusNode)) {\n focusDOM = getDOMTextNode(focusDOM);\n }\n\n if (\n anchorNode === undefined ||\n focusNode === undefined ||\n anchorDOM === null ||\n focusDOM === null\n ) {\n return null;\n }\n\n if (anchorDOM.nodeName === \"BR\") {\n [anchorDOM, anchorOffset] = getDOMIndexWithinParent(anchorDOM as ChildNode);\n }\n\n if (focusDOM.nodeName === \"BR\") {\n [focusDOM, focusOffset] = getDOMIndexWithinParent(focusDOM as ChildNode);\n }\n\n const firstChild = anchorDOM.firstChild;\n\n if (\n anchorDOM === focusDOM &&\n firstChild !== null &&\n firstChild.nodeName === \"BR\" &&\n anchorOffset === 0 &&\n focusOffset === 0\n ) {\n focusOffset = 1;\n }\n\n try {\n range.setStart(anchorDOM, anchorOffset);\n range.setEnd(focusDOM, focusOffset);\n } catch (e) {\n return null;\n }\n\n if (\n range.collapsed &&\n (anchorOffset !== focusOffset || anchorKey !== focusKey)\n ) {\n // Range is backwards, we need to reverse it\n range.setStart(focusDOM, focusOffset);\n range.setEnd(anchorDOM, anchorOffset);\n }\n\n return range;\n}\n"],"names":["$isTextNode"],"mappings":"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"}
|