From 0f03183b9a2374ed3198d2b9ec8348fa819b11b4 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 9 Feb 2021 03:03:48 -0500 Subject: fixed drawing link lines between everything except textanchor - to - textanchor. --- .../CollectionFreeFormLinkView.tsx | 45 ++++++++++------------ .../CollectionFreeFormLinksView.tsx | 29 ++++++-------- src/client/views/nodes/DocumentView.tsx | 9 +++-- src/client/views/nodes/LinkAnchorBox.tsx | 2 +- 4 files changed, 39 insertions(+), 46 deletions(-) (limited to 'src/client/views') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index ae5688b48..51cb9387a 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -41,44 +41,41 @@ export class CollectionFreeFormLinkView extends React.Component this._opacity = 1), 0); // since the render code depends on querying the Dom through getBoudndingClientRect, we need to delay triggering render() setTimeout(action(() => (!LinkDocs.length || !linkDoc.linkDisplay) && (this._opacity = 0.05)), 750); // this will unhighlight the link line. if (!linkDoc.linkAutoMove) return; - const acont = A.props.Document.type === DocumentType.LINK ? A.ContentDiv.getElementsByClassName("linkAnchorBox-cont") : []; - const bcont = B.props.Document.type === DocumentType.LINK ? B.ContentDiv.getElementsByClassName("linkAnchorBox-cont") : []; - const adiv = (acont.length ? acont[0] : A.ContentDiv); - const bdiv = (bcont.length ? bcont[0] : B.ContentDiv); + const acont = A.rootDoc.type === DocumentType.LINK ? A.ContentDiv.getElementsByClassName("linkAnchorBox-cont") : []; + const bcont = B.rootDoc.type === DocumentType.LINK ? B.ContentDiv.getElementsByClassName("linkAnchorBox-cont") : []; + const adiv = acont.length ? acont[0] : A.ContentDiv; + const bdiv = bcont.length ? bcont[0] : B.ContentDiv; const a = adiv.getBoundingClientRect(); const b = bdiv.getBoundingClientRect(); const { left: aleft, top: atop, width: awidth, height: aheight } = adiv.parentElement!.getBoundingClientRect(); const { left: bleft, top: btop, width: bwidth, height: bheight } = bdiv.parentElement!.getBoundingClientRect(); const apt = Utils.closestPtBetweenRectangles(aleft, atop, awidth, aheight, bleft, btop, bwidth, bheight, a.left + a.width / 2, a.top + a.height / 2); const bpt = Utils.closestPtBetweenRectangles(bleft, btop, bwidth, bheight, aleft, atop, awidth, aheight, apt.point.x, apt.point.y); - const afield = A.props.LayoutTemplateString?.indexOf("anchor1") === -1 ? "anchor2" : "anchor1"; - const bfield = afield === "anchor1" ? "anchor2" : "anchor1"; // really hacky stuff to make the LinkAnchorBox display where we want it to: - // if there's an element in the DOM with a classname containing the link's id and a data-targetids attribute containing the other end of the link, + // if there's an element in the DOM with a classname containing a link anchor's id, // then that DOM element is a hyperlink source for the current anchor and we want to place our link box at it's top right // otherwise, we just use the computed nearest point on the document boundary to the target Document - const linkEles = Array.from(window.document.getElementsByClassName(linkDoc[Id])); - const targetAhyperlink = linkEles.find((ele: any) => ele.dataset.targetids?.includes((linkDoc[afield] as Doc)[Id])); - const targetBhyperlink = linkEles.find((ele: any) => ele.dataset.targetids?.includes((linkDoc[bfield] as Doc)[Id])); + const targetAhyperlink = Array.from(window.document.getElementsByClassName((linkDoc.anchor1 as Doc)[Id])).lastElement(); + const targetBhyperlink = Array.from(window.document.getElementsByClassName((linkDoc.anchor2 as Doc)[Id])).lastElement(); if ((!targetAhyperlink && !a.width) || (!targetBhyperlink && !b.width)) return; - if (!targetBhyperlink) { - A.rootDoc[afield + "_x"] = (apt.point.x - aleft) / awidth * 100; - A.rootDoc[afield + "_y"] = (apt.point.y - atop) / aheight * 100; + if (!targetAhyperlink) { + linkDoc.anchor1_x = (apt.point.x - aleft) / awidth * 100; + linkDoc.anchor1_y = (apt.point.y - atop) / aheight * 100; } else { - const m = targetBhyperlink.getBoundingClientRect(); + const m = targetAhyperlink.getBoundingClientRect(); const mp = A.props.ScreenToLocalTransform().transformPoint(m.right, m.top + 5); - A.rootDoc[afield + "_x"] = Math.min(1, mp[0] / A.props.PanelWidth()) * 100; - A.rootDoc[afield + "_y"] = Math.min(1, mp[1] / A.props.PanelHeight()) * 100; + linkDoc.anchor1_x = Math.min(1, mp[0] / A.props.PanelWidth()) * 100; + linkDoc.anchor1_y = Math.min(1, mp[1] / A.props.PanelHeight()) * 100; } - if (!targetAhyperlink) { - B.rootDoc[bfield + "_x"] = (bpt.point.x - bleft) / bwidth * 100; - B.rootDoc[bfield + "_y"] = (bpt.point.y - btop) / bheight * 100; + if (!targetBhyperlink) { + linkDoc.anchor2_x = (bpt.point.x - bleft) / bwidth * 100; + linkDoc.anchor2_y = (bpt.point.y - btop) / bheight * 100; } else { - const m = targetAhyperlink.getBoundingClientRect(); + const m = targetBhyperlink.getBoundingClientRect(); const mp = B.props.ScreenToLocalTransform().transformPoint(m.right, m.top + 5); - B.rootDoc[bfield + "_x"] = Math.min(1, mp[0] / B.props.PanelWidth()) * 100; - B.rootDoc[bfield + "_y"] = Math.min(1, mp[1] / B.props.PanelHeight()) * 100; + linkDoc.anchor2_x = Math.min(1, mp[0] / B.props.PanelWidth()) * 100; + linkDoc.anchor2_y = Math.min(1, mp[1] / B.props.PanelHeight()) * 100; } } @@ -162,8 +159,8 @@ export class CollectionFreeFormLinkView extends React.Component { - if (!drawnPairs.reduce((found, drawnPair) => { - const match1 = (connection.a === drawnPair.a && connection.b === drawnPair.b); - const match2 = (connection.a === drawnPair.b && connection.b === drawnPair.a); - const match = match1 || match2; - if (match && !drawnPair.l.reduce((found, link) => found || link[Id] === connection.l[Id], false)) { - drawnPair.l.push(connection.l); - } - return match || found; - }, false)) { - drawnPairs.push({ a: connection.a, b: connection.b, l: [connection.l] }); - } - return drawnPairs; - }, [] as { a: DocumentView, b: DocumentView, l: Doc[] }[]); - return connections.filter(c => c.a.props.Document.type === DocumentType.LINK) - .map(c => ); + const connections = DocumentManager.Instance.LinkedDocumentViews + .filter(c => c.a.props.Document.type === DocumentType.LINK || c.b.props.Document.type === DocumentType.LINK) + .reduce((drawnPairs, connection) => { + const matchingPairs = drawnPairs.filter(pair => connection.a === pair.a && connection.b === pair.b); + matchingPairs.forEach(drawnPair => drawnPair.l.add(connection.l)); + if (!matchingPairs.length) drawnPairs.push({ a: connection.a, b: connection.b, l: new Set([connection.l]) }); + return drawnPairs; + }, [] as { a: DocumentView, b: DocumentView, l: Set }[]); + const set = new Map(); + connections.map(c => !set.has(Array.from(c.l)[0]) && set.set(Array.from(c.l)[0], { a: c.a, b: c.b, l: Array.from(c.l) })); + return Array.from(set.values()).map(c => ); } render() { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 463e59bd1..bfdacdb45 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -759,18 +759,19 @@ export class DocumentViewInternal extends DocComponent !d.hidden); - return filtered.map((d, i) => + // need to use allLinks for RTF since embedded linked text anchors are not rendered with DocumentViews. All other documents render their anchors with nested DocumentViews so we just need to render the directLinks here + const filtered = DocUtils.FilterDocs(this.rootDoc.type === DocumentType.RTF ? this.allLinks : this.directLinks, this.props.docFilters(), []).filter(d => !d.hidden); + return filtered.map((link, i) =>
+ LayoutTemplateString={LinkAnchorBox.LayoutString(`anchor${Doc.LinkEndpoint(link, this.rootDoc)}`)} />
); } diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx index d86dfd7b1..ca6c71ea3 100644 --- a/src/client/views/nodes/LinkAnchorBox.tsx +++ b/src/client/views/nodes/LinkAnchorBox.tsx @@ -134,7 +134,7 @@ export class LinkAnchorBox extends ViewBoxBaseComponent} ); - return
LinkDocPreview.LinkInfo = undefined)} onPointerEnter={action(e => LinkDocPreview.LinkInfo = { docprops: this.props, -- cgit v1.2.3-70-g09d2