aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/FormattedTextBox.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/FormattedTextBox.tsx')
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx66
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;
}