aboutsummaryrefslogtreecommitdiff
path: root/src/client/util/LinkFollower.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/util/LinkFollower.ts')
-rw-r--r--src/client/util/LinkFollower.ts42
1 files changed, 22 insertions, 20 deletions
diff --git a/src/client/util/LinkFollower.ts b/src/client/util/LinkFollower.ts
index ba2edb65c..f74409e42 100644
--- a/src/client/util/LinkFollower.ts
+++ b/src/client/util/LinkFollower.ts
@@ -12,8 +12,8 @@ import { SelectionManager } from './SelectionManager';
import { UndoManager } from './UndoManager';
/*
* link doc:
- * - anchor1: doc
- * - anchor2: doc
+ * - link_anchor_1: doc
+ * - link_anchor_2: doc
*
* group doc:
* - type: string representing the group type/name/category
@@ -28,7 +28,7 @@ export class LinkFollower {
// if the target isn't onscreen, then it will open up the target in the lightbox, or in place
// depending on the followLinkLocation property of the source (or the link itself as a fallback);
public static FollowLink = (linkDoc: Opt<Doc>, sourceDoc: Doc, altKey: boolean) => {
- const batch = UndoManager.StartBatch('follow link click');
+ const batch = UndoManager.StartBatch('Follow Link');
runInAction(() => (LinkFollower.IsFollowing = true)); // turn off decoration bounds while following links since animations may occur, and DocDecorations is based on screenToLocal which is not always an observable value
LinkFollower.traverseLink(
linkDoc,
@@ -42,26 +42,28 @@ export class LinkFollower {
};
public static traverseLink(link: Opt<Doc>, sourceDoc: Doc, finished?: () => void, traverseBacklink?: boolean) {
+ const getView = (doc: Doc) => DocumentManager.Instance.getFirstDocumentView(DocCast(doc.layout_unrendered ? doc.annotationOn : doc));
+ const isAnchor = (sourceDoc: Doc, anchor: Doc) => Doc.AreProtosEqual(anchor, sourceDoc) || Doc.AreProtosEqual(anchor.annotationOn as Doc, sourceDoc);
const linkDocs = link ? [link] : LinkManager.Links(sourceDoc);
- const firstDocs = linkDocs.filter(linkDoc => Doc.AreProtosEqual(linkDoc.anchor1 as Doc, sourceDoc) || Doc.AreProtosEqual((linkDoc.anchor1 as Doc).annotationOn as Doc, sourceDoc)); // link docs where 'doc' is anchor1
- const secondDocs = linkDocs.filter(linkDoc => Doc.AreProtosEqual(linkDoc.anchor2 as Doc, sourceDoc) || Doc.AreProtosEqual((linkDoc.anchor2 as Doc).annotationOn as Doc, sourceDoc)); // link docs where 'doc' is anchor2
- const fwdLinkWithoutTargetView = firstDocs.find(d => DocumentManager.Instance.getDocumentViews((d.anchor2 as Doc).type === DocumentType.MARKER ? DocCast((d.anchor2 as Doc).annotationOn) : (d.anchor2 as Doc)).length === 0);
- const backLinkWithoutTargetView = secondDocs.find(d => DocumentManager.Instance.getDocumentViews((d.anchor1 as Doc).type === DocumentType.MARKER ? DocCast((d.anchor1 as Doc).annotationOn) : (d.anchor1 as Doc)).length === 0);
- const linkWithoutTargetDoc = traverseBacklink === undefined ? fwdLinkWithoutTargetView || backLinkWithoutTargetView : traverseBacklink ? backLinkWithoutTargetView : fwdLinkWithoutTargetView;
- const linkDocList = linkWithoutTargetDoc && !sourceDoc.followAllLinks ? [linkWithoutTargetDoc] : traverseBacklink === undefined ? firstDocs.concat(secondDocs) : traverseBacklink ? secondDocs : firstDocs;
+ const fwdLinks = linkDocs.filter(l => isAnchor(sourceDoc, l.link_anchor_1 as Doc)); // link docs where 'sourceDoc' is link_anchor_1
+ const backLinks = linkDocs.filter(l => isAnchor(sourceDoc, l.link_anchor_2 as Doc)); // link docs where 'sourceDoc' is link_anchor_2
+ const fwdLinkWithoutTargetView = fwdLinks.find(l => !getView(DocCast(l.link_anchor_2)));
+ const backLinkWithoutTargetView = backLinks.find(l => !getView(DocCast(l.link_anchor_1)));
+ const linkWithoutTargetDoc = traverseBacklink === undefined ? fwdLinkWithoutTargetView ?? backLinkWithoutTargetView : traverseBacklink ? backLinkWithoutTargetView : fwdLinkWithoutTargetView;
+ const linkDocList = linkWithoutTargetDoc && !sourceDoc.followAllLinks ? [linkWithoutTargetDoc] : traverseBacklink === undefined ? fwdLinks.concat(backLinks) : traverseBacklink ? backLinks : fwdLinks;
const followLinks = sourceDoc.followLinkToggle || sourceDoc.followAllLinks ? linkDocList : linkDocList.slice(0, 1);
var count = 0;
const allFinished = () => ++count === followLinks.length && finished?.();
if (!followLinks.length) finished?.();
followLinks.forEach(async linkDoc => {
const target = (
- sourceDoc === linkDoc.anchor1
- ? linkDoc.anchor2
- : sourceDoc === linkDoc.anchor2
- ? linkDoc.anchor1
- : Doc.AreProtosEqual(sourceDoc, linkDoc.anchor1 as Doc) || Doc.AreProtosEqual((linkDoc.anchor1 as Doc).annotationOn as Doc, sourceDoc)
- ? linkDoc.anchor2
- : linkDoc.anchor1
+ sourceDoc === linkDoc.link_anchor_1
+ ? linkDoc.link_anchor_2
+ : sourceDoc === linkDoc.link_anchor_2
+ ? linkDoc.link_anchor_1
+ : Doc.AreProtosEqual(sourceDoc, linkDoc.link_anchor_1 as Doc) || Doc.AreProtosEqual((linkDoc.link_anchor_1 as Doc).annotationOn as Doc, sourceDoc)
+ ? linkDoc.link_anchor_2
+ : linkDoc.link_anchor_1
) as Doc;
if (target) {
const doFollow = (canToggle?: boolean) => {
@@ -92,16 +94,16 @@ export class LinkFollower {
};
let movedTarget = false;
if (sourceDoc.followLinkLocation === OpenWhere.inParent) {
- const sourceDocParent = DocCast(sourceDoc.context);
- if (target.context instanceof Doc && target.context !== sourceDocParent) {
- Doc.RemoveDocFromList(target.context, Doc.LayoutFieldKey(target.context), target);
+ const sourceDocParent = DocCast(sourceDoc.embedContainer);
+ if (target.embedContainer instanceof Doc && target.embedContainer !== sourceDocParent) {
+ Doc.RemoveDocFromList(target.embedContainer, Doc.LayoutFieldKey(target.embedContainer), target);
movedTarget = true;
}
if (!DocListCast(sourceDocParent[Doc.LayoutFieldKey(sourceDocParent)]).includes(target)) {
Doc.AddDocToList(sourceDocParent, Doc.LayoutFieldKey(sourceDocParent), target);
movedTarget = true;
}
- target.context = sourceDocParent;
+ target.embedContainer = sourceDocParent;
const moveTo = [NumCast(sourceDoc.x) + NumCast(sourceDoc.followLinkXoffset), NumCast(sourceDoc.y) + NumCast(sourceDoc.followLinkYoffset)];
if (sourceDoc.followLinkXoffset !== undefined && moveTo[0] !== target.x) {
target.x = moveTo[0];