diff options
Diffstat (limited to 'src/client/views/nodes/FormattedTextBox.tsx')
-rw-r--r-- | src/client/views/nodes/FormattedTextBox.tsx | 66 |
1 files changed, 65 insertions, 1 deletions
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index eb4718581..53f28ac00 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -138,6 +138,69 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe if (this.props.isOverlay) { DragManager.StartDragFunctions.push(() => FormattedTextBox.InputBoxOverlay = undefined); } + + this.props.Document.guid = undefined; + this.props.Document.linkHref = undefined; + + reaction( + () => StrCast(this.props.Document.guid), + async (guid) => { + let start = -1; + let href = this.props.Document.linkHref; + + if (this._editorView && guid) { + let editor = this._editorView; + let ret = findLinkFrag(editor.state.doc.content, editor); + + if (ret.frag.size > 2) { + let tr; + if (ret.frag.firstChild) { + let between = TextSelection.between(editor.state.doc.resolve(ret.start + 2), editor.state.doc.resolve(ret.start + ret.frag.firstChild.nodeSize)); + tr = editor.state.tr.setSelection(between); + } else { + let near = TextSelection.near(editor.state.doc.resolve(ret.start)); + tr = editor.state.tr.setSelection(near); + } + + editor.focus(); + editor.dispatch(tr.scrollIntoView()); + editor.dispatch(tr.scrollIntoView()); // bcz: sometimes selection doesn't fully scroll into view on smaller text boxes <5 lines visibility -- hopefully avoidable by ppl just not using small boxes...? + + this.props.Document.guid = undefined; + this.props.Document.linkHref = undefined; + } + } + + function findLinkFrag(frag: Fragment, editor: EditorView) { + const nodes: Node[] = []; + frag.forEach((node, index) => { + let examinedNode = findLinkNode(node, editor); + if (examinedNode && examinedNode.textContent !== "") { + nodes.push(examinedNode); + start += index; + } + }); + return { frag: Fragment.fromArray(nodes), start: start }; + } + function findLinkNode(node: Node, editor: EditorView) { + if (!node.isText) { + const content = findLinkFrag(node.content, editor); + return node.copy(content.frag); + } + const marks = [...node.marks]; + const linkIndex = marks.findIndex(mark => mark.type.name === "link"); + if (linkIndex !== -1) { + if (guid === marks[linkIndex].attrs.guid) { + return node; + } else if (href && href === marks[linkIndex].attrs.href) { // retroactively fixing old in-text links by adding guid + marks[linkIndex].attrs.guid = guid; + return node; + } + } + return undefined; + } + } + ); } public get CurrentDiv(): HTMLDivElement { return this._ref.current!; } @@ -760,6 +823,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe let ctrlKey = e.ctrlKey; if (e.button === 0 && ((!this.props.isSelected() && !e.ctrlKey) || (this.props.isSelected() && e.ctrlKey)) && !e.metaKey && e.target) { let href = (e.target as any).href; + let guid = (e.target as any).guid; let location: string; if ((e.target as any).attributes.location) { location = (e.target as any).attributes.location.value; @@ -783,9 +847,9 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe let proto = Doc.GetProto(linkDoc); let targetContext = await Cast(proto.targetContext, Doc); let jumpToDoc = await Cast(linkDoc.anchor2, Doc); + if (jumpToDoc) { if (DocumentManager.Instance.getDocumentView(jumpToDoc)) { - DocumentManager.Instance.jumpToDocument(jumpToDoc, e.altKey, undefined, undefined, NumCast((jumpToDoc === linkDoc.anchor2 ? linkDoc.anchor2Page : linkDoc.anchor1Page))); return; } |