aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts3
-rw-r--r--src/client/goldenLayout.js2
-rw-r--r--src/client/util/RichTextSchema.tsx1
-rw-r--r--src/client/util/TooltipTextMenu.tsx14
-rw-r--r--src/client/views/linking/LinkFollowBox.tsx12
-rw-r--r--src/client/views/linking/LinkMenuItem.tsx4
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx66
7 files changed, 89 insertions, 13 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 2fa0d2dcb..b2a320517 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -638,7 +638,7 @@ export namespace DocUtils {
});
}
export function MakeLink(source: Doc, target: Doc, targetContext?: Doc, title: string = "", description: string = "", sourceContext?: Doc, id?: string, anchored1?: boolean) {
- if (LinkManager.Instance.doesLinkExist(source, target)) return undefined;
+ // if (LinkManager.Instance.doesLinkExist(source, target)) return undefined;
let sv = DocumentManager.Instance.getDocumentView(source);
if (sv && sv.props.ContainingCollectionDoc === target) return;
if (target === CurrentUserUtils.UserDocument) return undefined;
@@ -651,7 +651,6 @@ export namespace DocUtils {
linkDocProto.sourceContext = sourceContext;
linkDocProto.title = title === "" ? source.title + " to " + target.title : title;
linkDocProto.linkDescription = description;
- linkDocProto.type = DocumentType.LINK;
linkDocProto.anchor1 = source;
linkDocProto.anchor1Page = source.curPage;
diff --git a/src/client/goldenLayout.js b/src/client/goldenLayout.js
index ad78139c1..29b750720 100644
--- a/src/client/goldenLayout.js
+++ b/src/client/goldenLayout.js
@@ -377,7 +377,7 @@
this._nOriginalY = coordinates.y;
this._oDocument.on('mousemove touchmove', this._fMove);
- this._oDocument.one('mouseup touchend', this._fUp);
+ this._oDocument.on('mouseup touchend', this._fUp);
this._timeout = setTimeout(lm.utils.fnBind(this._startDrag, this), this._nDelay);
}
diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx
index ba4b92a25..ea31671ac 100644
--- a/src/client/util/RichTextSchema.tsx
+++ b/src/client/util/RichTextSchema.tsx
@@ -253,6 +253,7 @@ export const marks: { [index: string]: MarkSpec } = {
href: {},
location: { default: null },
title: { default: null },
+ guid: { default: null },
docref: { default: false }
},
inclusive: false,
diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx
index b6de048e4..a2653855c 100644
--- a/src/client/util/TooltipTextMenu.tsx
+++ b/src/client/util/TooltipTextMenu.tsx
@@ -303,11 +303,13 @@ export class TooltipTextMenu {
handlers: {
dragComplete: action(() => {
let linkDoc = dragData.linkDocument;
+ let guid = Utils.GenerateGuid();
let proto = Doc.GetProto(linkDoc);
if (proto && docView) {
proto.sourceContext = docView.props.ContainingCollectionDoc;
}
- linkDoc instanceof Doc && this.makeLink(Utils.prepend("/doc/" + linkDoc[Id]), ctrlKey ? "onRight" : "inTab");
+ linkDoc.guid = guid;
+ linkDoc instanceof Doc && this.makeLink(Utils.prepend("/doc/" + linkDoc[Id]), ctrlKey ? "onRight" : "inTab", guid);
}),
},
hideSource: false
@@ -389,13 +391,13 @@ export class TooltipTextMenu {
}
}
- makeLinkWithState = (state: EditorState, target: string, location: string) => {
- let link = state.schema.mark(state.schema.marks.link, { href: target, location: location });
- }
+ // makeLinkWithState = (state: EditorState, target: string, location: string) => {
+ // let link = state.schema.mark(state.schema.marks.link, { href: target, location: location });
+ // }
- makeLink = (target: string, location: string) => {
+ makeLink = (target: string, location: string, guid?: string) => {
let node = this.view.state.selection.$from.nodeAfter;
- let link = this.view.state.schema.mark(this.view.state.schema.marks.link, { href: target, location: location });
+ let link = this.view.state.schema.mark(this.view.state.schema.marks.link, { href: target, location: location, guid: guid });
this.view.dispatch(this.view.state.tr.removeMark(this.view.state.selection.from, this.view.state.selection.to, this.view.state.schema.marks.link));
this.view.dispatch(this.view.state.tr.addMark(this.view.state.selection.from, this.view.state.selection.to, link));
node = this.view.state.selection.$from.nodeAfter;
diff --git a/src/client/views/linking/LinkFollowBox.tsx b/src/client/views/linking/LinkFollowBox.tsx
index 81b0249dd..1280ae28b 100644
--- a/src/client/views/linking/LinkFollowBox.tsx
+++ b/src/client/views/linking/LinkFollowBox.tsx
@@ -18,6 +18,7 @@ import { DocServer } from "../../DocServer";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faTimes } from '@fortawesome/free-solid-svg-icons';
import { docs_v1 } from "googleapis";
+import { Utils } from "../../../Utils";
enum FollowModes {
OPENTAB = "Open in Tab",
@@ -242,6 +243,7 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
let proto = Doc.GetProto(LinkFollowBox.linkDoc);
let targetContext = await Cast(proto.targetContext, Doc);
let sourceContext = await Cast(proto.sourceContext, Doc);
+ let guid = StrCast(LinkFollowBox.linkDoc.guid);
const shouldZoom = options ? options.shouldZoom : false;
let dockingFunc = (document: Doc) => { (this._addDocTab || this.props.addDocTab)(document, undefined, "inTab"); SelectionManager.DeselectAll(); };
@@ -251,6 +253,16 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
}
else if (LinkFollowBox.destinationDoc === LinkFollowBox.linkDoc.anchor1 && sourceContext) {
DocumentManager.Instance.jumpToDocument(jumpToDoc, shouldZoom, false, document => dockingFunc(sourceContext!));
+ if (LinkFollowBox.sourceDoc && LinkFollowBox.destinationDoc) {
+ if (guid) {
+ LinkFollowBox.destinationDoc.guid = guid;
+ } else {
+ jumpToDoc.linkHref = Utils.prepend("/doc/" + StrCast(LinkFollowBox.linkDoc[Id]));
+ let newguid = Utils.GenerateGuid();
+ LinkFollowBox.linkDoc.guid = newguid;
+ LinkFollowBox.destinationDoc.guid = newguid;
+ }
+ }
}
else if (DocumentManager.Instance.getDocumentView(jumpToDoc)) {
DocumentManager.Instance.jumpToDocument(jumpToDoc, shouldZoom, undefined, undefined,
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index 82fe3df23..835554ac0 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -28,9 +28,7 @@ interface LinkMenuItemProps {
export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
private _drag = React.createRef<HTMLDivElement>();
@observable private _showMore: boolean = false;
- @action toggleShowMore() {
- this._showMore = !this._showMore;
- }
+ @action toggleShowMore() { this._showMore = !this._showMore; }
onEdit = (e: React.PointerEvent): void => {
e.stopPropagation();
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;
}