From d568be6536369a1bc1e844fb9728bceb0ef47af6 Mon Sep 17 00:00:00 2001 From: Abdullah Atta Date: Sun, 16 Apr 2023 01:54:47 +0500 Subject: [PATCH] editor: fix crash while editing links on mobile --- packages/editor/src/toolbar/tools/link.tsx | 7 ++++++- packages/editor/src/toolbar/tools/web-clip.tsx | 14 ++++++++------ packages/editor/src/utils/prosemirror.ts | 15 ++++++++++----- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/packages/editor/src/toolbar/tools/link.tsx b/packages/editor/src/toolbar/tools/link.tsx index 42dd695ac..0d998d456 100644 --- a/packages/editor/src/toolbar/tools/link.tsx +++ b/packages/editor/src/toolbar/tools/link.tsx @@ -105,6 +105,8 @@ export function EditLink(props: ToolProps) { const onDone = useCallback( (link: LinkDefinition) => { + if (!selectedNode.current) return; + const { href, text, isImage } = link; const { from, node, to } = selectedNode.current; if (!href || !editor.current || !node) return; @@ -117,6 +119,7 @@ export function EditLink(props: ToolProps) { let commandChain = editor.current.chain(); if (!isImage) { + console.log(from, to); commandChain = commandChain.command(({ tr }) => { tr.removeMark(from, to, mark.type); tr.insertText( @@ -161,6 +164,8 @@ export function EditLink(props: ToolProps) { isEditing onDone={onDone} onClick={() => { + if (!selectedNode.current) return; + const { node } = selectedNode.current; if (!node) return; @@ -202,7 +207,7 @@ export function OpenLink(props: ToolProps) { const selectedNode = useRefValue( _selectedNode || selectionToOffset(editor.state) ); - const { node } = selectedNode.current; + const { node } = selectedNode.current || {}; const link = node ? findMark(node, "link") : null; if (!link) return null; const href = link?.attrs.href; diff --git a/packages/editor/src/toolbar/tools/web-clip.tsx b/packages/editor/src/toolbar/tools/web-clip.tsx index 7c076ad16..f99968d26 100644 --- a/packages/editor/src/toolbar/tools/web-clip.tsx +++ b/packages/editor/src/toolbar/tools/web-clip.tsx @@ -46,9 +46,10 @@ export function WebClipFullScreen(props: ToolProps) { {...props} toggled={false} onClick={() => { - const dom = editor.current?.view.nodeDOM( - selectionToOffset(editor.state).from - ); + const offset = selectionToOffset(editor.state); + if (!offset) return; + + const dom = editor.current?.view.nodeDOM(offset.from); if (!dom || !(dom instanceof HTMLElement)) return; const iframe = dom.querySelector("iframe"); @@ -70,9 +71,10 @@ export function WebClipOpenExternal(props: ToolProps) { {...props} toggled={false} onClick={async () => { - const dom = editor.current?.view.nodeDOM( - selectionToOffset(editor.state).from - ); + const offset = selectionToOffset(editor.state); + if (!offset) return; + + const dom = editor.current?.view.nodeDOM(offset.from); if (!dom || !(dom instanceof HTMLElement)) return; const iframe = dom.querySelector("iframe"); diff --git a/packages/editor/src/utils/prosemirror.ts b/packages/editor/src/utils/prosemirror.ts index e3db85d8b..c37bafc3f 100644 --- a/packages/editor/src/utils/prosemirror.ts +++ b/packages/editor/src/utils/prosemirror.ts @@ -120,12 +120,17 @@ export function findMark( return mark; } -export function selectionToOffset(state: EditorState): NodeWithOffset { - const { $from, from } = state.selection; +export function selectionToOffset( + state: EditorState +): NodeWithOffset | undefined { + const { from, $from } = state.selection; + const node = state.doc.nodeAt(from); + if (!node) return; + return { - node: state.doc.nodeAt(from) || undefined, - from, - to: from + $from.node().nodeSize + node, + from: from - $from.textOffset, + to: from - $from.textOffset + node.nodeSize }; }