diff --git a/.yarn/cache/@lexical-clipboard-npm-0.11.2-f4f664a06b-ab102ac6bf.zip b/.yarn/cache/@lexical-clipboard-npm-0.11.3-584d250409-0a630b6301.zip similarity index 91% rename from .yarn/cache/@lexical-clipboard-npm-0.11.2-f4f664a06b-ab102ac6bf.zip rename to .yarn/cache/@lexical-clipboard-npm-0.11.3-584d250409-0a630b6301.zip index 0384665a6..d965db869 100644 Binary files a/.yarn/cache/@lexical-clipboard-npm-0.11.2-f4f664a06b-ab102ac6bf.zip and b/.yarn/cache/@lexical-clipboard-npm-0.11.3-584d250409-0a630b6301.zip differ diff --git a/.yarn/cache/@lexical-code-npm-0.11.2-b15572c988-af715151a7.zip b/.yarn/cache/@lexical-code-npm-0.11.3-a1ec741899-35494f71c7.zip similarity index 92% rename from .yarn/cache/@lexical-code-npm-0.11.2-b15572c988-af715151a7.zip rename to .yarn/cache/@lexical-code-npm-0.11.3-a1ec741899-35494f71c7.zip index c9cba36f6..3bd3476de 100644 Binary files a/.yarn/cache/@lexical-code-npm-0.11.2-b15572c988-af715151a7.zip and b/.yarn/cache/@lexical-code-npm-0.11.3-a1ec741899-35494f71c7.zip differ diff --git a/.yarn/cache/@lexical-dragon-npm-0.11.2-23b1712709-1926f48f08.zip b/.yarn/cache/@lexical-dragon-npm-0.11.3-c6e9ffc58f-8bafde2d36.zip similarity index 81% rename from .yarn/cache/@lexical-dragon-npm-0.11.2-23b1712709-1926f48f08.zip rename to .yarn/cache/@lexical-dragon-npm-0.11.3-c6e9ffc58f-8bafde2d36.zip index 5fe6d0725..51091aa16 100644 Binary files a/.yarn/cache/@lexical-dragon-npm-0.11.2-23b1712709-1926f48f08.zip and b/.yarn/cache/@lexical-dragon-npm-0.11.3-c6e9ffc58f-8bafde2d36.zip differ diff --git a/.yarn/cache/@lexical-hashtag-npm-0.11.2-18969b1c8c-34dbe2a803.zip b/.yarn/cache/@lexical-hashtag-npm-0.11.3-6817f8aedc-db68da4165.zip similarity index 87% rename from .yarn/cache/@lexical-hashtag-npm-0.11.2-18969b1c8c-34dbe2a803.zip rename to .yarn/cache/@lexical-hashtag-npm-0.11.3-6817f8aedc-db68da4165.zip index 61c98e064..71d0e2d98 100644 Binary files a/.yarn/cache/@lexical-hashtag-npm-0.11.2-18969b1c8c-34dbe2a803.zip and b/.yarn/cache/@lexical-hashtag-npm-0.11.3-6817f8aedc-db68da4165.zip differ diff --git a/.yarn/cache/@lexical-headless-npm-0.11.2-3084f3ef8c-abc8b7602b.zip b/.yarn/cache/@lexical-headless-npm-0.11.3-01980f0207-9bbabea457.zip similarity index 90% rename from .yarn/cache/@lexical-headless-npm-0.11.2-3084f3ef8c-abc8b7602b.zip rename to .yarn/cache/@lexical-headless-npm-0.11.3-01980f0207-9bbabea457.zip index 582522164..368f7b531 100644 Binary files a/.yarn/cache/@lexical-headless-npm-0.11.2-3084f3ef8c-abc8b7602b.zip and b/.yarn/cache/@lexical-headless-npm-0.11.3-01980f0207-9bbabea457.zip differ diff --git a/.yarn/cache/@lexical-history-npm-0.11.2-1abb3c5c1e-a63562baa2.zip b/.yarn/cache/@lexical-history-npm-0.11.3-3617ede957-59d828f647.zip similarity index 90% rename from .yarn/cache/@lexical-history-npm-0.11.2-1abb3c5c1e-a63562baa2.zip rename to .yarn/cache/@lexical-history-npm-0.11.3-3617ede957-59d828f647.zip index bbe38f004..533c3ecca 100644 Binary files a/.yarn/cache/@lexical-history-npm-0.11.2-1abb3c5c1e-a63562baa2.zip and b/.yarn/cache/@lexical-history-npm-0.11.3-3617ede957-59d828f647.zip differ diff --git a/.yarn/cache/@lexical-html-npm-0.11.2-e3e36b7631-32aa097370.zip b/.yarn/cache/@lexical-html-npm-0.11.3-3e16d87c66-08ecd189fc.zip similarity index 87% rename from .yarn/cache/@lexical-html-npm-0.11.2-e3e36b7631-32aa097370.zip rename to .yarn/cache/@lexical-html-npm-0.11.3-3e16d87c66-08ecd189fc.zip index de704b991..e6fbc7aa2 100644 Binary files a/.yarn/cache/@lexical-html-npm-0.11.2-e3e36b7631-32aa097370.zip and b/.yarn/cache/@lexical-html-npm-0.11.3-3e16d87c66-08ecd189fc.zip differ diff --git a/.yarn/cache/@lexical-link-npm-0.11.2-6d30d1b6d6-78a71053f7.zip b/.yarn/cache/@lexical-link-npm-0.11.3-4fde460830-f0b91dcb00.zip similarity index 94% rename from .yarn/cache/@lexical-link-npm-0.11.2-6d30d1b6d6-78a71053f7.zip rename to .yarn/cache/@lexical-link-npm-0.11.3-4fde460830-f0b91dcb00.zip index cc5dbe0f9..a4d177d62 100644 Binary files a/.yarn/cache/@lexical-link-npm-0.11.2-6d30d1b6d6-78a71053f7.zip and b/.yarn/cache/@lexical-link-npm-0.11.3-4fde460830-f0b91dcb00.zip differ diff --git a/.yarn/cache/@lexical-list-npm-0.11.2-b16b88e2c7-c94f35ec62.zip b/.yarn/cache/@lexical-list-npm-0.11.3-c9d56b3d4e-59bf95dc1f.zip similarity index 94% rename from .yarn/cache/@lexical-list-npm-0.11.2-b16b88e2c7-c94f35ec62.zip rename to .yarn/cache/@lexical-list-npm-0.11.3-c9d56b3d4e-59bf95dc1f.zip index c7e0cd582..803f99da9 100644 Binary files a/.yarn/cache/@lexical-list-npm-0.11.2-b16b88e2c7-c94f35ec62.zip and b/.yarn/cache/@lexical-list-npm-0.11.3-c9d56b3d4e-59bf95dc1f.zip differ diff --git a/.yarn/cache/@lexical-mark-npm-0.11.2-f61a1e982d-e7edadd085.zip b/.yarn/cache/@lexical-mark-npm-0.11.3-1bcfbfc0b0-e323b1d614.zip similarity index 84% rename from .yarn/cache/@lexical-mark-npm-0.11.2-f61a1e982d-e7edadd085.zip rename to .yarn/cache/@lexical-mark-npm-0.11.3-1bcfbfc0b0-e323b1d614.zip index 238fcfd16..6240969eb 100644 Binary files a/.yarn/cache/@lexical-mark-npm-0.11.2-f61a1e982d-e7edadd085.zip and b/.yarn/cache/@lexical-mark-npm-0.11.3-1bcfbfc0b0-e323b1d614.zip differ diff --git a/.yarn/cache/@lexical-markdown-npm-0.11.2-b5ca7824e4-89bb22134d.zip b/.yarn/cache/@lexical-markdown-npm-0.11.3-1d285f8863-c43e2fff7e.zip similarity index 96% rename from .yarn/cache/@lexical-markdown-npm-0.11.2-b5ca7824e4-89bb22134d.zip rename to .yarn/cache/@lexical-markdown-npm-0.11.3-1d285f8863-c43e2fff7e.zip index 7e73108bc..d054f4491 100644 Binary files a/.yarn/cache/@lexical-markdown-npm-0.11.2-b5ca7824e4-89bb22134d.zip and b/.yarn/cache/@lexical-markdown-npm-0.11.3-1d285f8863-c43e2fff7e.zip differ diff --git a/.yarn/cache/@lexical-offset-npm-0.11.2-c91edf2f55-4d1093bc0a.zip b/.yarn/cache/@lexical-offset-npm-0.11.3-89cfd439c8-bdc1f8fc04.zip similarity index 94% rename from .yarn/cache/@lexical-offset-npm-0.11.2-c91edf2f55-4d1093bc0a.zip rename to .yarn/cache/@lexical-offset-npm-0.11.3-89cfd439c8-bdc1f8fc04.zip index d22dda0e9..93d8ce58b 100644 Binary files a/.yarn/cache/@lexical-offset-npm-0.11.2-c91edf2f55-4d1093bc0a.zip and b/.yarn/cache/@lexical-offset-npm-0.11.3-89cfd439c8-bdc1f8fc04.zip differ diff --git a/.yarn/cache/@lexical-overflow-npm-0.11.2-244ee0a981-a6751df598.zip b/.yarn/cache/@lexical-overflow-npm-0.11.3-c91052ff24-d0f74582cc.zip similarity index 82% rename from .yarn/cache/@lexical-overflow-npm-0.11.2-244ee0a981-a6751df598.zip rename to .yarn/cache/@lexical-overflow-npm-0.11.3-c91052ff24-d0f74582cc.zip index 1dac1827d..591b63e0d 100644 Binary files a/.yarn/cache/@lexical-overflow-npm-0.11.2-244ee0a981-a6751df598.zip and b/.yarn/cache/@lexical-overflow-npm-0.11.3-c91052ff24-d0f74582cc.zip differ diff --git a/.yarn/cache/@lexical-plain-text-npm-0.11.2-63bf773115-ddc0ac63f1.zip b/.yarn/cache/@lexical-plain-text-npm-0.11.3-b83bc0f318-7d0929b87c.zip similarity index 91% rename from .yarn/cache/@lexical-plain-text-npm-0.11.2-63bf773115-ddc0ac63f1.zip rename to .yarn/cache/@lexical-plain-text-npm-0.11.3-b83bc0f318-7d0929b87c.zip index a9495c407..3c9dcec5c 100644 Binary files a/.yarn/cache/@lexical-plain-text-npm-0.11.2-63bf773115-ddc0ac63f1.zip and b/.yarn/cache/@lexical-plain-text-npm-0.11.3-b83bc0f318-7d0929b87c.zip differ diff --git a/.yarn/cache/@lexical-react-npm-0.11.2-dbad90e06e-8fdc60712c.zip b/.yarn/cache/@lexical-react-npm-0.11.3-875efb3874-a58c1ae508.zip similarity index 93% rename from .yarn/cache/@lexical-react-npm-0.11.2-dbad90e06e-8fdc60712c.zip rename to .yarn/cache/@lexical-react-npm-0.11.3-875efb3874-a58c1ae508.zip index 73d4d7d67..959011df6 100644 Binary files a/.yarn/cache/@lexical-react-npm-0.11.2-dbad90e06e-8fdc60712c.zip and b/.yarn/cache/@lexical-react-npm-0.11.3-875efb3874-a58c1ae508.zip differ diff --git a/.yarn/cache/@lexical-rich-text-npm-0.11.2-74aa0b844b-78d50a506b.zip b/.yarn/cache/@lexical-rich-text-npm-0.11.3-23d487cbdc-e3491a14f8.zip similarity index 95% rename from .yarn/cache/@lexical-rich-text-npm-0.11.2-74aa0b844b-78d50a506b.zip rename to .yarn/cache/@lexical-rich-text-npm-0.11.3-23d487cbdc-e3491a14f8.zip index 723f91aca..fec1f46ca 100644 Binary files a/.yarn/cache/@lexical-rich-text-npm-0.11.2-74aa0b844b-78d50a506b.zip and b/.yarn/cache/@lexical-rich-text-npm-0.11.3-23d487cbdc-e3491a14f8.zip differ diff --git a/.yarn/cache/@lexical-selection-npm-0.11.2-2c06112187-7b1f30331d.zip b/.yarn/cache/@lexical-selection-npm-0.11.2-2c06112187-7b1f30331d.zip deleted file mode 100644 index 0c008bbe2..000000000 Binary files a/.yarn/cache/@lexical-selection-npm-0.11.2-2c06112187-7b1f30331d.zip and /dev/null differ diff --git a/.yarn/cache/@lexical-selection-npm-0.11.3-e55f51010c-e57ca9a08f.zip b/.yarn/cache/@lexical-selection-npm-0.11.3-e55f51010c-e57ca9a08f.zip new file mode 100644 index 000000000..a1f588cf2 Binary files /dev/null and b/.yarn/cache/@lexical-selection-npm-0.11.3-e55f51010c-e57ca9a08f.zip differ diff --git a/.yarn/cache/@lexical-table-npm-0.11.2-f3dad2156d-9ee3cd3363.zip b/.yarn/cache/@lexical-table-npm-0.11.2-f3dad2156d-9ee3cd3363.zip deleted file mode 100644 index ef6b488d3..000000000 Binary files a/.yarn/cache/@lexical-table-npm-0.11.2-f3dad2156d-9ee3cd3363.zip and /dev/null differ diff --git a/.yarn/cache/@lexical-table-npm-0.11.3-7283eb895d-d1aa2fc8d1.zip b/.yarn/cache/@lexical-table-npm-0.11.3-7283eb895d-d1aa2fc8d1.zip new file mode 100644 index 000000000..1753555e6 Binary files /dev/null and b/.yarn/cache/@lexical-table-npm-0.11.3-7283eb895d-d1aa2fc8d1.zip differ diff --git a/.yarn/cache/@lexical-text-npm-0.11.2-c05c7b8c8e-ee7e0859d7.zip b/.yarn/cache/@lexical-text-npm-0.11.3-91ee5d167b-48b3e0e54f.zip similarity index 90% rename from .yarn/cache/@lexical-text-npm-0.11.2-c05c7b8c8e-ee7e0859d7.zip rename to .yarn/cache/@lexical-text-npm-0.11.3-91ee5d167b-48b3e0e54f.zip index 849f5ff2c..84295a85f 100644 Binary files a/.yarn/cache/@lexical-text-npm-0.11.2-c05c7b8c8e-ee7e0859d7.zip and b/.yarn/cache/@lexical-text-npm-0.11.3-91ee5d167b-48b3e0e54f.zip differ diff --git a/.yarn/cache/@lexical-utils-npm-0.11.2-4ce431e2fd-182f915084.zip b/.yarn/cache/@lexical-utils-npm-0.11.3-8f373c407f-f7e185ee8f.zip similarity index 95% rename from .yarn/cache/@lexical-utils-npm-0.11.2-4ce431e2fd-182f915084.zip rename to .yarn/cache/@lexical-utils-npm-0.11.3-8f373c407f-f7e185ee8f.zip index 47657857c..1ba284272 100644 Binary files a/.yarn/cache/@lexical-utils-npm-0.11.2-4ce431e2fd-182f915084.zip and b/.yarn/cache/@lexical-utils-npm-0.11.3-8f373c407f-f7e185ee8f.zip differ diff --git a/.yarn/cache/@lexical-yjs-npm-0.11.2-439d0a0716-a886ed415f.zip b/.yarn/cache/@lexical-yjs-npm-0.11.3-0548286735-f201fc07c8.zip similarity index 96% rename from .yarn/cache/@lexical-yjs-npm-0.11.2-439d0a0716-a886ed415f.zip rename to .yarn/cache/@lexical-yjs-npm-0.11.3-0548286735-f201fc07c8.zip index 09d4381e6..1d6438789 100644 Binary files a/.yarn/cache/@lexical-yjs-npm-0.11.2-439d0a0716-a886ed415f.zip and b/.yarn/cache/@lexical-yjs-npm-0.11.3-0548286735-f201fc07c8.zip differ diff --git a/.yarn/cache/lexical-npm-0.11.2-f90a6a0933-85ec66227b.zip b/.yarn/cache/lexical-npm-0.11.3-bfc63d8643-89fa276db6.zip similarity index 76% rename from .yarn/cache/lexical-npm-0.11.2-f90a6a0933-85ec66227b.zip rename to .yarn/cache/lexical-npm-0.11.3-bfc63d8643-89fa276db6.zip index 052d14a94..6d774571c 100644 Binary files a/.yarn/cache/lexical-npm-0.11.2-f90a6a0933-85ec66227b.zip and b/.yarn/cache/lexical-npm-0.11.3-bfc63d8643-89fa276db6.zip differ diff --git a/packages/web/package.json b/packages/web/package.json index f36a5bb74..ca5c6fd51 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -15,7 +15,7 @@ "lint": "eslint src/javascripts && yarn tsc", "lint:fix": "eslint src/javascripts --fix", "start": "webpack-dev-server --config web.webpack.dev.js", - "start-secure": "yarn start --server-type https", + "start-secure": "yarn start --https", "test": "jest --config jest.config.js", "tsc": "tsc --project tsconfig.json", "upgrade:snjs": "ncu -u '@standardnotes/*'", @@ -28,7 +28,7 @@ "@babel/plugin-transform-react-jsx": "^7.19.0", "@babel/preset-env": "*", "@babel/preset-typescript": "^7.21.5", - "@lexical/react": "0.11.2", + "@lexical/react": "0.11.3", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.10", "@simplewebauthn/browser": "^7.1.0", "@standardnotes/authenticator": "^2.4.0", @@ -76,7 +76,7 @@ "identity-obj-proxy": "^3.0.0", "jest": "^29.3.1", "jest-environment-jsdom": "^29.3.1", - "lexical": "0.11.2", + "lexical": "0.11.3", "lint-staged": ">=13", "mini-css-extract-plugin": "^2.7.2", "minimatch": "^5.1.1", @@ -109,7 +109,7 @@ }, "dependencies": { "@ariakit/react": "^0.2.8", - "@lexical/headless": "0.11.2", + "@lexical/headless": "0.11.3", "@radix-ui/react-slot": "^1.0.1", "fast-diff": "^1.3.0" } diff --git a/packages/web/src/javascripts/Components/SuperEditor/BlocksEditor.tsx b/packages/web/src/javascripts/Components/SuperEditor/BlocksEditor.tsx index c99faf59b..c3634bcaf 100644 --- a/packages/web/src/javascripts/Components/SuperEditor/BlocksEditor.tsx +++ b/packages/web/src/javascripts/Components/SuperEditor/BlocksEditor.tsx @@ -20,7 +20,6 @@ import CollapsiblePlugin from './Plugins/CollapsiblePlugin' import DraggableBlockPlugin from './Plugins/DraggableBlockPlugin' import CodeHighlightPlugin from './Plugins/CodeHighlightPlugin' import FloatingTextFormatToolbarPlugin from './Plugins/FloatingTextFormatToolbarPlugin' -import FloatingLinkEditorPlugin from './Plugins/FloatingLinkEditorPlugin' import { TabIndentationPlugin } from './Plugins/TabIndentationPlugin' import { handleEditorChange } from './Utils' import { SuperEditorContentId } from './Constants' @@ -109,7 +108,6 @@ export const BlocksEditor: FunctionComponent = ({ {!readonly && floatingAnchorElem && ( <> - )} diff --git a/packages/web/src/javascripts/Components/SuperEditor/Plugins/MobileToolbarPlugin/MobileToolbarPlugin.tsx b/packages/web/src/javascripts/Components/SuperEditor/Plugins/MobileToolbarPlugin/MobileToolbarPlugin.tsx index d539fedc7..13d431642 100644 --- a/packages/web/src/javascripts/Components/SuperEditor/Plugins/MobileToolbarPlugin/MobileToolbarPlugin.tsx +++ b/packages/web/src/javascripts/Components/SuperEditor/Plugins/MobileToolbarPlugin/MobileToolbarPlugin.tsx @@ -11,11 +11,15 @@ import { CAN_UNDO_COMMAND, COMMAND_PRIORITY_CRITICAL, FORMAT_TEXT_COMMAND, + GridSelection, + NodeSelection, REDO_COMMAND, + RangeSelection, + SELECTION_CHANGE_COMMAND, UNDO_COMMAND, } from 'lexical' import { mergeRegister } from '@lexical/utils' -import { $isLinkNode, TOGGLE_LINK_COMMAND } from '@lexical/link' +import { $isLinkNode, $isAutoLinkNode, TOGGLE_LINK_COMMAND } from '@lexical/link' import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { GetAlignmentBlocks } from '../Blocks/Alignment' import { GetBulletedListBlock } from '../Blocks/BulletedList' @@ -38,6 +42,7 @@ import { SUPER_TOGGLE_SEARCH } from '@standardnotes/ui-services' import { useApplication } from '@/Components/ApplicationProvider' import { GetRemoteImageBlock } from '../Blocks/RemoteImage' import { InsertRemoteImageDialog } from '../RemoteImagePlugin/RemoteImagePlugin' +import LinkEditor from '../FloatingLinkEditorPlugin/LinkEditor' const MobileToolbarPlugin = () => { const application = useApplication() @@ -45,10 +50,12 @@ const MobileToolbarPlugin = () => { const [modal, showModal] = useModal() const [isInEditor, setIsInEditor] = useState(false) + const [isInLinkEditor, setIsInLinkEditor] = useState(false) const [isInToolbar, setIsInToolbar] = useState(false) const isMobile = useMediaQuery(MutuallyExclusiveMediaQueryBreakpoints.sm) const toolbarRef = useRef(null) + const linkEditorRef = useRef(null) const backspaceButtonRef = useRef(null) const insertLink = useCallback(() => { @@ -214,8 +221,10 @@ const MobileToolbarPlugin = () => { const handleBlur = (event: FocusEvent) => { const elementToBeFocused = event.relatedTarget as Node const toolbarContainsElementToFocus = toolbarRef.current && toolbarRef.current.contains(elementToBeFocused) + const linkEditorContainsElementToFocus = + linkEditorRef.current && linkEditorRef.current.contains(elementToBeFocused) const willFocusBackspaceButton = backspaceButtonRef.current && elementToBeFocused === backspaceButtonRef.current - if (toolbarContainsElementToFocus || willFocusBackspaceButton) { + if (toolbarContainsElementToFocus || linkEditorContainsElementToFocus || willFocusBackspaceButton) { return } setIsInEditor(false) @@ -231,31 +240,116 @@ const MobileToolbarPlugin = () => { }, [editor]) useEffect(() => { - if (!toolbarRef.current) { - return - } - const toolbar = toolbarRef.current + const linkEditor = linkEditorRef.current - const handleFocus = () => setIsInToolbar(true) - const handleBlur = (event: FocusEvent) => { + const handleToolbarFocus = () => setIsInToolbar(true) + const handleLinkEditorFocus = () => setIsInLinkEditor(true) + const handleToolbarBlur = (event: FocusEvent) => { const elementToBeFocused = event.relatedTarget as Node if (elementToBeFocused === backspaceButtonRef.current) { return } setIsInToolbar(false) } + const handleLinkEditorBlur = (event: FocusEvent) => { + const elementToBeFocused = event.relatedTarget as Node + if (elementToBeFocused === backspaceButtonRef.current) { + return + } + setIsInLinkEditor(false) + } - toolbar.addEventListener('focus', handleFocus) - toolbar.addEventListener('blur', handleBlur) + if (toolbar) { + toolbar.addEventListener('focus', handleToolbarFocus) + toolbar.addEventListener('blur', handleToolbarBlur) + } + + if (linkEditor) { + linkEditor.addEventListener('focus', handleLinkEditorFocus) + linkEditor.addEventListener('blur', handleLinkEditorBlur) + } return () => { - toolbar?.removeEventListener('focus', handleFocus) - toolbar?.removeEventListener('blur', handleBlur) + toolbar?.removeEventListener('focus', handleToolbarFocus) + toolbar?.removeEventListener('blur', handleToolbarBlur) + linkEditor?.removeEventListener('focus', handleLinkEditorFocus) + linkEditor?.removeEventListener('blur', handleLinkEditorBlur) } }, []) - const isFocusInEditorOrToolbar = isInEditor || isInToolbar + const [isSelectionLink, setIsSelectionLink] = useState(false) + const [isSelectionAutoLink, setIsSelectionAutoLink] = useState(false) + const [linkUrl, setLinkUrl] = useState('') + const [isLinkEditMode, setIsLinkEditMode] = useState(false) + const [lastSelection, setLastSelection] = useState(null) + + const updateEditorSelection = useCallback(() => { + editor.getEditorState().read(() => { + const selection = $getSelection() + const nativeSelection = window.getSelection() + const activeElement = document.activeElement + const rootElement = editor.getRootElement() + + if (!$isRangeSelection(selection)) { + return + } + + const node = getSelectedNode(selection) + const parent = node.getParent() + + if ($isLinkNode(parent) || $isLinkNode(node)) { + setIsSelectionLink(true) + } else { + setIsSelectionLink(false) + } + + if ($isAutoLinkNode(parent) || $isAutoLinkNode(node)) { + setIsSelectionAutoLink(true) + } else { + setIsSelectionAutoLink(false) + } + + if ($isLinkNode(parent)) { + setLinkUrl(parent.getURL()) + } else if ($isLinkNode(node)) { + setLinkUrl(node.getURL()) + } else { + setLinkUrl('') + } + + if ( + selection !== null && + nativeSelection !== null && + rootElement !== null && + rootElement.contains(nativeSelection.anchorNode) + ) { + setLastSelection(selection) + } else if (!activeElement || activeElement.id !== 'link-input') { + setLastSelection(null) + setIsLinkEditMode(false) + setLinkUrl('') + } + }) + }, [editor]) + + useEffect(() => { + return mergeRegister( + editor.registerCommand( + SELECTION_CHANGE_COMMAND, + () => { + updateEditorSelection() + return false + }, + COMMAND_PRIORITY_CRITICAL, + ), + editor.registerUpdateListener(() => { + updateEditorSelection() + }), + ) + }, [editor, updateEditorSelection]) + + const isFocusInEditorOrToolbar = isInEditor || isInToolbar || isInLinkEditor if (!isMobile || !isFocusInEditorOrToolbar) { return null } @@ -263,32 +357,46 @@ const MobileToolbarPlugin = () => { return ( <> {modal} -
-
- {items.map((item) => { - return ( - - ) - })} +
+ {isSelectionLink && ( +
+ +
+ )} +
+
+ {items.map((item) => { + return ( + + ) + })} +
+
-
) diff --git a/yarn.lock b/yarn.lock index f9952bc04..785a536b7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2911,255 +2911,255 @@ __metadata: languageName: node linkType: hard -"@lexical/clipboard@npm:0.11.2": - version: 0.11.2 - resolution: "@lexical/clipboard@npm:0.11.2" +"@lexical/clipboard@npm:0.11.3": + version: 0.11.3 + resolution: "@lexical/clipboard@npm:0.11.3" dependencies: - "@lexical/html": 0.11.2 - "@lexical/list": 0.11.2 - "@lexical/selection": 0.11.2 - "@lexical/utils": 0.11.2 + "@lexical/html": 0.11.3 + "@lexical/list": 0.11.3 + "@lexical/selection": 0.11.3 + "@lexical/utils": 0.11.3 peerDependencies: - lexical: 0.11.2 - checksum: ab102ac6bf803fe61e48b9ef19576af1db9fb39e0eb8af0501882337e69f41324243b8f95094f958f8181c1ef27816cba1c1eaaa71eb2d09e9b323ea0b6ee7f6 + lexical: 0.11.3 + checksum: 0a630b630197a8f7f8118049993c1aecee603272733c0c0e2a40e699f79efc11f93e8e1b65e8835a5ebbf22aa6af559dfe60f3d4b214cbea323d3902ed69a923 languageName: node linkType: hard -"@lexical/code@npm:0.11.2": - version: 0.11.2 - resolution: "@lexical/code@npm:0.11.2" +"@lexical/code@npm:0.11.3": + version: 0.11.3 + resolution: "@lexical/code@npm:0.11.3" dependencies: - "@lexical/utils": 0.11.2 + "@lexical/utils": 0.11.3 prismjs: ^1.27.0 peerDependencies: - lexical: 0.11.2 - checksum: af715151a741c1a74b8e5fe338329541c08635398c07b7c4078d8c8d8160be62416ac2c5995a032cad4308cf8db98deaf5029e1547c9a377660803e358e78ccb + lexical: 0.11.3 + checksum: 35494f71c7f102c61a8737880762f64087b6345a1c069e8a13aa0c30a7ffaca433e192e70d1e891571e53cb3854e2ec18643615f18d693c9e3b0bf5cd6542624 languageName: node linkType: hard -"@lexical/dragon@npm:0.11.2": - version: 0.11.2 - resolution: "@lexical/dragon@npm:0.11.2" +"@lexical/dragon@npm:0.11.3": + version: 0.11.3 + resolution: "@lexical/dragon@npm:0.11.3" peerDependencies: - lexical: 0.11.2 - checksum: 1926f48f08ededfee416c3ce6ffade01010156510fd8eb04b7c8d68f9d37b7196ce0356c4e5d1c863d582831a69204858d9df5d2804c606880b1afdcc5a7c903 + lexical: 0.11.3 + checksum: 8bafde2d36d67c04d2d21f45def17a7b21834260b2366c7ca0f6c5bb12d64ed5d5b24bf1190347fb03b5e10cc5f2b57e9726eba52ca1f5f517fcbb87eff7ab07 languageName: node linkType: hard -"@lexical/hashtag@npm:0.11.2": - version: 0.11.2 - resolution: "@lexical/hashtag@npm:0.11.2" +"@lexical/hashtag@npm:0.11.3": + version: 0.11.3 + resolution: "@lexical/hashtag@npm:0.11.3" dependencies: - "@lexical/utils": 0.11.2 + "@lexical/utils": 0.11.3 peerDependencies: - lexical: 0.11.2 - checksum: 34dbe2a803739239b0ab3f60dbb1ab7f13c30a7614d4e5a62c5b498a8a07babe014eda309786cde96a050e0afa056cad5f99e3748c4d8cb1d2a29dcd7480b57c + lexical: 0.11.3 + checksum: db68da41653eb74765197b9630e1f78b7d1e5785b331f88f4578da707f44bf0afdcc6e076186400bac02dfda8c47751ecb57ad69a42cad59c79f9f8f346cd7d9 languageName: node linkType: hard -"@lexical/headless@npm:0.11.2": - version: 0.11.2 - resolution: "@lexical/headless@npm:0.11.2" +"@lexical/headless@npm:0.11.3": + version: 0.11.3 + resolution: "@lexical/headless@npm:0.11.3" peerDependencies: - lexical: 0.11.2 - checksum: abc8b7602b29da48a767470a8dc0c680404214fc615f1689dc1188d17b1667391a13cbe53aa56b004047ba9f62dbeea912cb8e6d35871818fc666d0147e9c1bf + lexical: 0.11.3 + checksum: 9bbabea45714a69deff7a6df7df55033c71904ffcee7398b8713e6178aace28f2fd75e111ca1f4113b13b2161498413ec82d90587f6289b35ab0de355494ebd2 languageName: node linkType: hard -"@lexical/history@npm:0.11.2": - version: 0.11.2 - resolution: "@lexical/history@npm:0.11.2" +"@lexical/history@npm:0.11.3": + version: 0.11.3 + resolution: "@lexical/history@npm:0.11.3" dependencies: - "@lexical/utils": 0.11.2 + "@lexical/utils": 0.11.3 peerDependencies: - lexical: 0.11.2 - checksum: a63562baa20cf11412004601978846da059b87506f64f498b2fcb5b1401f48c1e3048dc531aa3dcb813e1dd377164beeb651ac46180f618f3727838dfa89389f + lexical: 0.11.3 + checksum: 59d828f647193f99ac6c8e04b8be7faa10f9862ff99efb5a24a2c4c5dd881b5da677a9531774f77737b9fe38015463588f5f6ea81d3d6c6ba5d47d5731ddd3c6 languageName: node linkType: hard -"@lexical/html@npm:0.11.2": - version: 0.11.2 - resolution: "@lexical/html@npm:0.11.2" +"@lexical/html@npm:0.11.3": + version: 0.11.3 + resolution: "@lexical/html@npm:0.11.3" dependencies: - "@lexical/selection": 0.11.2 + "@lexical/selection": 0.11.3 peerDependencies: - lexical: 0.11.2 - checksum: 32aa097370188fe825dc61fe7750ee2162f94cd8204e1f4f501eeecb7b437b7b1f22bc834a093cde49657a26c97bd57b3a4cd7c365a95c0365400389751fe8d3 + lexical: 0.11.3 + checksum: 08ecd189fc4ebc0c9e598658b07035f8905dd5ea8c254e01e4e655296453a4d03796f354fb9e8febdddadb8f3c29f57bbf2ef15a013d1a1bb69cf41853276936 languageName: node linkType: hard -"@lexical/link@npm:0.11.2": - version: 0.11.2 - resolution: "@lexical/link@npm:0.11.2" +"@lexical/link@npm:0.11.3": + version: 0.11.3 + resolution: "@lexical/link@npm:0.11.3" dependencies: - "@lexical/utils": 0.11.2 + "@lexical/utils": 0.11.3 peerDependencies: - lexical: 0.11.2 - checksum: 78a71053f73c3c659f786e3aa8a9e6332f019cf7d9e90ffbf64bd6466f842bb9a9dcba770454ed30fff646aa3d5abe016c80a7364b38349e0987a1891d9bec0b + lexical: 0.11.3 + checksum: f0b91dcb00c7d2419763ba3ea0c02dff8dc669a343f7ef8aaeef5025a048556b223f501ad20c54f3848c936489eb74e41e51e3cbd1653f70d365fa6b80f87cc3 languageName: node linkType: hard -"@lexical/list@npm:0.11.2": - version: 0.11.2 - resolution: "@lexical/list@npm:0.11.2" +"@lexical/list@npm:0.11.3": + version: 0.11.3 + resolution: "@lexical/list@npm:0.11.3" dependencies: - "@lexical/utils": 0.11.2 + "@lexical/utils": 0.11.3 peerDependencies: - lexical: 0.11.2 - checksum: c94f35ec62a980c7af66582a4b1c9c0d8d7af3e4a9bdcff0323626882dd8a2a80ca0e2a8a212b09e6066741e207ebbeb743e0817950d14216ad55d9e22d8bd61 + lexical: 0.11.3 + checksum: 59bf95dc1f23c7a86a55caa435bc7861194ff271ea20444f888aaff201d3972722c43fb311e60b6cab9331910bb3afed45e71e7275555e0965d2af193c4aef60 languageName: node linkType: hard -"@lexical/mark@npm:0.11.2": - version: 0.11.2 - resolution: "@lexical/mark@npm:0.11.2" +"@lexical/mark@npm:0.11.3": + version: 0.11.3 + resolution: "@lexical/mark@npm:0.11.3" dependencies: - "@lexical/utils": 0.11.2 + "@lexical/utils": 0.11.3 peerDependencies: - lexical: 0.11.2 - checksum: e7edadd085ebcff1b4ad6c4467d2a63c6c417b48ac76bd63e64659d30e63d7ec5e86fc56f7a3480b50582f069cd6c81a8ea28afa2a4df96fb7dfab4dda878408 + lexical: 0.11.3 + checksum: e323b1d614975507b3bcc7ad6a5c48551c96c5986b09efc483914a1b1d2f481a1a99d6420042e992520e4f60827aa2b401ba22f60a7ef81d7f84387f241305f1 languageName: node linkType: hard -"@lexical/markdown@npm:0.11.2": - version: 0.11.2 - resolution: "@lexical/markdown@npm:0.11.2" +"@lexical/markdown@npm:0.11.3": + version: 0.11.3 + resolution: "@lexical/markdown@npm:0.11.3" dependencies: - "@lexical/code": 0.11.2 - "@lexical/link": 0.11.2 - "@lexical/list": 0.11.2 - "@lexical/rich-text": 0.11.2 - "@lexical/text": 0.11.2 - "@lexical/utils": 0.11.2 + "@lexical/code": 0.11.3 + "@lexical/link": 0.11.3 + "@lexical/list": 0.11.3 + "@lexical/rich-text": 0.11.3 + "@lexical/text": 0.11.3 + "@lexical/utils": 0.11.3 peerDependencies: - lexical: 0.11.2 - checksum: 89bb22134d3c1835a7936c7b2aa63df7d70cac8a369b4a5bdae96de72181d23db1ffe31c6d1b6e6d1b648a0bde6f177d665f48953a4ae43ab0eebaf6b3602d3e + lexical: 0.11.3 + checksum: c43e2fff7ee7aad174e829923aa4df1bfd480ab1f645f24e22e8728bf5178995e31b465aed71e7e1aa82152aba748cf71cbf7f5e927da80d6e19d1a63e731485 languageName: node linkType: hard -"@lexical/offset@npm:0.11.2": - version: 0.11.2 - resolution: "@lexical/offset@npm:0.11.2" +"@lexical/offset@npm:0.11.3": + version: 0.11.3 + resolution: "@lexical/offset@npm:0.11.3" peerDependencies: - lexical: 0.11.2 - checksum: 4d1093bc0afa4f2f51d45c4b36b21779e6fa2b17b9a8d5d95c9ca0482b8759aca026dba7fae5ac2d695e7e22d9262b828b9157b4a7a266a1f7861848cd3520a4 + lexical: 0.11.3 + checksum: bdc1f8fc040d2213d16233140e719b951932f3d22a6c7528aadd5867bca9be7e487cfa5c45d96ff7ce7bc1e4fabea17b4ce31dc331fede657323125ae01335e3 languageName: node linkType: hard -"@lexical/overflow@npm:0.11.2": - version: 0.11.2 - resolution: "@lexical/overflow@npm:0.11.2" +"@lexical/overflow@npm:0.11.3": + version: 0.11.3 + resolution: "@lexical/overflow@npm:0.11.3" peerDependencies: - lexical: 0.11.2 - checksum: a6751df5984be024bfc60414e92bee1fc6336bf647234d30b4197b8bf972bbd0c81f61fd15449399fdc06f0de4ae03001431aacb90356097293cd149c8c07551 + lexical: 0.11.3 + checksum: d0f74582cc71bada93bb5c5653c7a425922d1bb8f69e782676ad2c52560a5d4a4f97ab4b2234d3047c9895ae8bdc4bed8f8d064ea23b756e2dbc4dafb2d4663c languageName: node linkType: hard -"@lexical/plain-text@npm:0.11.2": - version: 0.11.2 - resolution: "@lexical/plain-text@npm:0.11.2" +"@lexical/plain-text@npm:0.11.3": + version: 0.11.3 + resolution: "@lexical/plain-text@npm:0.11.3" peerDependencies: - "@lexical/clipboard": 0.11.2 - "@lexical/selection": 0.11.2 - "@lexical/utils": 0.11.2 - lexical: 0.11.2 - checksum: ddc0ac63f19652134473d287279c7bac06948e78e0d9e2549d6fed8472b3eb40ff6966c0f358e4e085b46bcd1b95822bd6d865bc848e576aed0ec8339675517d + "@lexical/clipboard": 0.11.3 + "@lexical/selection": 0.11.3 + "@lexical/utils": 0.11.3 + lexical: 0.11.3 + checksum: 7d0929b87c6ba1658537163df6f8e58f0df7234e4b356aa612f793b845b594786235c78aaab59dbca93860f5d3d6a3b438622b368dfa270443857422fc811c66 languageName: node linkType: hard -"@lexical/react@npm:0.11.2": - version: 0.11.2 - resolution: "@lexical/react@npm:0.11.2" +"@lexical/react@npm:0.11.3": + version: 0.11.3 + resolution: "@lexical/react@npm:0.11.3" dependencies: - "@lexical/clipboard": 0.11.2 - "@lexical/code": 0.11.2 - "@lexical/dragon": 0.11.2 - "@lexical/hashtag": 0.11.2 - "@lexical/history": 0.11.2 - "@lexical/link": 0.11.2 - "@lexical/list": 0.11.2 - "@lexical/mark": 0.11.2 - "@lexical/markdown": 0.11.2 - "@lexical/overflow": 0.11.2 - "@lexical/plain-text": 0.11.2 - "@lexical/rich-text": 0.11.2 - "@lexical/selection": 0.11.2 - "@lexical/table": 0.11.2 - "@lexical/text": 0.11.2 - "@lexical/utils": 0.11.2 - "@lexical/yjs": 0.11.2 + "@lexical/clipboard": 0.11.3 + "@lexical/code": 0.11.3 + "@lexical/dragon": 0.11.3 + "@lexical/hashtag": 0.11.3 + "@lexical/history": 0.11.3 + "@lexical/link": 0.11.3 + "@lexical/list": 0.11.3 + "@lexical/mark": 0.11.3 + "@lexical/markdown": 0.11.3 + "@lexical/overflow": 0.11.3 + "@lexical/plain-text": 0.11.3 + "@lexical/rich-text": 0.11.3 + "@lexical/selection": 0.11.3 + "@lexical/table": 0.11.3 + "@lexical/text": 0.11.3 + "@lexical/utils": 0.11.3 + "@lexical/yjs": 0.11.3 react-error-boundary: ^3.1.4 peerDependencies: - lexical: 0.11.2 + lexical: 0.11.3 react: ">=17.x" react-dom: ">=17.x" - checksum: 8fdc60712c248c9c242b717f39fe0c359b4db73a512b7ed7f7ac761061a789d4992cc533664f5ae6229384c4f426fe92f465f6b73b013c072dd3b7b057a5ec1d + checksum: a58c1ae508b9422a0ee542e62a28cbccf10b24b9029966de8b79c091cf4b697e9cfa23e05aa280a613d0dca3bd858480eb00ba5180868c55cc65381a0debcdec languageName: node linkType: hard -"@lexical/rich-text@npm:0.11.2": - version: 0.11.2 - resolution: "@lexical/rich-text@npm:0.11.2" +"@lexical/rich-text@npm:0.11.3": + version: 0.11.3 + resolution: "@lexical/rich-text@npm:0.11.3" peerDependencies: - "@lexical/clipboard": 0.11.2 - "@lexical/selection": 0.11.2 - "@lexical/utils": 0.11.2 - lexical: 0.11.2 - checksum: 78d50a506b8431d33f99e1dc6041b68645f44791c6012490f5de62cc78214f546d8518ce495c8e887cf77ab57d010c8ff82841e5cb76bc4d61021da66cd1c9fd + "@lexical/clipboard": 0.11.3 + "@lexical/selection": 0.11.3 + "@lexical/utils": 0.11.3 + lexical: 0.11.3 + checksum: e3491a14f8a880e7fa0fad91c5e9a242a8d2977d1bbfec4ac807300249623c074c882dae30924c68c9f46263eaf816f1fb0a063180631bb045f0df1d4996b54a languageName: node linkType: hard -"@lexical/selection@npm:0.11.2": - version: 0.11.2 - resolution: "@lexical/selection@npm:0.11.2" +"@lexical/selection@npm:0.11.3": + version: 0.11.3 + resolution: "@lexical/selection@npm:0.11.3" peerDependencies: - lexical: 0.11.2 - checksum: 7b1f30331de349df9d5aab936b962676c1ffa8dd15b03049851c0bf8a232a0a747998b83656cf970279ea3e6f426e429ae5db2e0e4180c0a94f9f900c6c4070c + lexical: 0.11.3 + checksum: e57ca9a08f1e302f62349245e44949f71235ac48e297cb0390b6dff3db4aeb475fced62e78d81692f1e2974a0766dd25c0f83e6130870e848de0f5f0554af4f5 languageName: node linkType: hard -"@lexical/table@npm:0.11.2": - version: 0.11.2 - resolution: "@lexical/table@npm:0.11.2" +"@lexical/table@npm:0.11.3": + version: 0.11.3 + resolution: "@lexical/table@npm:0.11.3" dependencies: - "@lexical/utils": 0.11.2 + "@lexical/utils": 0.11.3 peerDependencies: - lexical: 0.11.2 - checksum: 9ee3cd33631dcf85956990fe27489c6d2eee554505d4e0c5dd7a57c19f2d4fa878448bb3d7ae8083e4db633ed05d02f305f4c4a298b9dd7e499be4646b69613b + lexical: 0.11.3 + checksum: d1aa2fc8d192830aec4fe2e8d2f6a64b4e061b70a618c166478ee889fc561c28487351e7dba8b7463053dc67c85faeb1f44cf0984ca3e15e6e41aa483063a40e languageName: node linkType: hard -"@lexical/text@npm:0.11.2": - version: 0.11.2 - resolution: "@lexical/text@npm:0.11.2" +"@lexical/text@npm:0.11.3": + version: 0.11.3 + resolution: "@lexical/text@npm:0.11.3" peerDependencies: - lexical: 0.11.2 - checksum: ee7e0859d7f4119a5bee9ee2f8255845ce32b16997cc353087976c8f65967e620494d31c63dc54b6001003534d0682418ccd407f61af53bd3bf7836da1d3b474 + lexical: 0.11.3 + checksum: 48b3e0e54f2dc08958872dd59ad4806c8fe20ab5bc832241ad7811ea36159366b58ea201b97cf96ce9c383f3b534aa1627b713bd3777cc3bff292a1a92bde6d2 languageName: node linkType: hard -"@lexical/utils@npm:0.11.2": - version: 0.11.2 - resolution: "@lexical/utils@npm:0.11.2" +"@lexical/utils@npm:0.11.3": + version: 0.11.3 + resolution: "@lexical/utils@npm:0.11.3" dependencies: - "@lexical/list": 0.11.2 - "@lexical/selection": 0.11.2 - "@lexical/table": 0.11.2 + "@lexical/list": 0.11.3 + "@lexical/selection": 0.11.3 + "@lexical/table": 0.11.3 peerDependencies: - lexical: 0.11.2 - checksum: 182f9150843b4ada726c31732afca2fa9465c9e08372fd6fbc91e676768a01866d3878247c12ee1f9a94f6397e3b0dfea462c0a35139bce174c773b95400c08b + lexical: 0.11.3 + checksum: f7e185ee8f50398b7533a4f1e0f495c803a6ac4b350af30e1791013b63b2ee45465e65f6338ceea72bee894076fe9e46d33a40ae3c5e5fbaebda6eb3daf261b9 languageName: node linkType: hard -"@lexical/yjs@npm:0.11.2": - version: 0.11.2 - resolution: "@lexical/yjs@npm:0.11.2" +"@lexical/yjs@npm:0.11.3": + version: 0.11.3 + resolution: "@lexical/yjs@npm:0.11.3" dependencies: - "@lexical/offset": 0.11.2 + "@lexical/offset": 0.11.3 peerDependencies: - lexical: 0.11.2 + lexical: 0.11.3 yjs: ">=13.5.22" - checksum: a886ed415f845f9bd1e724dede42b10611f48b7bd6acef6781219e3d6220b3e984abcd7017e3ada636355558dd298c5cd4c202e0b87fb7f3c5fb36a494d7a4e9 + checksum: f201fc07c863aea24043d9add6f3b98a871ef1811fca8a3ca90d6b36cc5aa56ab164728e9bbf007dd3401598bdc75fc68daf0b9bcb027b4fd7584da8b3d3e2d1 languageName: node linkType: hard @@ -5086,8 +5086,8 @@ __metadata: "@babel/plugin-transform-react-jsx": ^7.19.0 "@babel/preset-env": "*" "@babel/preset-typescript": ^7.21.5 - "@lexical/headless": 0.11.2 - "@lexical/react": 0.11.2 + "@lexical/headless": 0.11.3 + "@lexical/react": 0.11.3 "@pmmmwh/react-refresh-webpack-plugin": ^0.5.10 "@radix-ui/react-slot": ^1.0.1 "@simplewebauthn/browser": ^7.1.0 @@ -5137,7 +5137,7 @@ __metadata: identity-obj-proxy: ^3.0.0 jest: ^29.3.1 jest-environment-jsdom: ^29.3.1 - lexical: 0.11.2 + lexical: 0.11.3 lint-staged: ">=13" mini-css-extract-plugin: ^2.7.2 minimatch: ^5.1.1 @@ -15316,10 +15316,10 @@ __metadata: languageName: node linkType: hard -"lexical@npm:0.11.2": - version: 0.11.2 - resolution: "lexical@npm:0.11.2" - checksum: 85ec66227b38e60c430e4a4be489b483022477fc4b815229fc96ab71e30b059f8ff443e2e10e2c68f1d731d856027e4e1a86a4fed2730fbde1267a0156676b84 +"lexical@npm:0.11.3": + version: 0.11.3 + resolution: "lexical@npm:0.11.3" + checksum: 89fa276db6e253c1b52f097155e6bd6402c4292845a37a0910b992c9051e339df5186d41f3f35eb3040ad8f322716c63c22b5e154b04e698814f5f4a02e49635 languageName: node linkType: hard