From cdc9c7e293a656573d49c4265b5867e34e8db7c8 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Fri, 5 Jun 2020 18:30:56 -0400
Subject: changed all scroll behaviors to be _scrollTop to go to a scroll and
 _scrollY to animate to it.

---
 src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx')

diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index d47ae63af..59a6045ab 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -183,7 +183,7 @@ export class FormattedTextBoxComment {
                             const anchor = FieldValue(Doc.AreProtosEqual(FieldValue(Cast(linkDoc.anchor1, Doc)), textBox.dataDoc) ? Cast(linkDoc.anchor2, Doc) : (Cast(linkDoc.anchor1, Doc)) || linkDoc);
                             const target = anchor?.annotationOn ? await DocCastAsync(anchor.annotationOn) : anchor;
                             if (anchor !== target && anchor && target) {
-                                target.scrollY = NumCast(anchor?.y);
+                                target._scrollY = NumCast(anchor?.y);
                             }
                             if (target) {
                                 ReactDOM.render(<ContentFittingDocumentView
-- 
cgit v1.2.3-70-g09d2


From 1b65063a3cce0123215c914af6328a8a81ece33f Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sat, 13 Jun 2020 20:53:31 -0400
Subject: fixed text sidebar when text is scaled.  started to add multiple
 links to a text selection

---
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 25 +++++++------
 .../collections/collectionFreeForm/MarqueeView.tsx |  2 +-
 .../nodes/formattedText/FormattedTextBox.scss      | 43 ++++++++++++++++++++++
 .../views/nodes/formattedText/FormattedTextBox.tsx | 18 ++++++---
 .../formattedText/FormattedTextBoxComment.tsx      | 19 +++++-----
 src/client/views/nodes/formattedText/marks_rts.ts  | 11 +++++-
 6 files changed, 90 insertions(+), 28 deletions(-)

(limited to 'src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx')

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 678ad2a53..67356bff7 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -52,7 +52,6 @@ library.add(faEye as any, faTable, faPaintBrush, faExpandArrowsAlt, faCompressAr
 export const panZoomSchema = createSchema({
     _panX: "number",
     _panY: "number",
-    scale: "number",
     currentTimecode: "number",
     displayTimecode: "number",
     currentFrame: "number",
@@ -76,6 +75,7 @@ export type collectionFreeformViewProps = {
     forceScaling?: boolean; // whether to force scaling of content (needed by ImageBox)
     viewDefDivClick?: ScriptField;
     childPointerEvents?: boolean;
+    scaleField?: string;
 };
 
 @observer
@@ -108,6 +108,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
     @computed get nativeWidth() { return this.fitToContent ? 0 : NumCast(this.Document._nativeWidth, this.props.NativeWidth()); }
     @computed get nativeHeight() { return this.fitToContent ? 0 : NumCast(this.Document._nativeHeight, this.props.NativeHeight()); }
     private get isAnnotationOverlay() { return this.props.isAnnotationOverlay; }
+    private get scaleFieldKey() { return this.props.scaleField || "scale"; }
     private get borderWidth() { return this.isAnnotationOverlay ? 0 : COLLECTION_BORDER_WIDTH; }
     private easing = () => this.props.Document.panTransformType === "Ease";
     private panX = () => this.fitToContent ? (this.contentBounds.x + this.contentBounds.r) / 2 : this.Document._panX || 0;
@@ -115,14 +116,14 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
     private zoomScaling = () => (this.fitToContentScaling / this.parentScaling) * (this.fitToContent ?
         Math.min(this.props.PanelHeight() / (this.contentBounds.b - this.contentBounds.y),
             this.props.PanelWidth() / (this.contentBounds.r - this.contentBounds.x)) :
-        this.Document.scale || 1)
+        NumCast(this.Document[this.scaleFieldKey], 1));
 
     @computed get cachedCenteringShiftX(): number {
-        const scaling = this.fitToContent ? 1 : this.contentScaling;
+        const scaling = this.fitToContent || !this.contentScaling ? 1 : this.contentScaling;
         return !this.isAnnotationOverlay ? this.props.PanelWidth() / 2 / this.parentScaling / scaling : 0;  // shift so pan position is at center of window for non-overlay collections
     }
     @computed get cachedCenteringShiftY(): number {
-        const scaling = this.fitToContent ? 1 : this.contentScaling;
+        const scaling = this.fitToContent || !this.contentScaling ? 1 : this.contentScaling;
         return !this.isAnnotationOverlay ? this.props.PanelHeight() / 2 / this.parentScaling / scaling : 0;// shift so pan position is at center of window for non-overlay collections
     }
     @computed get cachedGetLocalTransform(): Transform {
@@ -779,7 +780,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
 
         if (localTransform.Scale >= 0.15 || localTransform.Scale > this.zoomScaling()) {
             const safeScale = Math.min(Math.max(0.15, localTransform.Scale), 40);
-            this.props.Document.scale = Math.abs(safeScale);
+            this.props.Document[this.scaleFieldKey] = Math.abs(safeScale);
             this.setPan(-localTransform.TranslateX / safeScale, -localTransform.TranslateY / safeScale);
         }
     }
@@ -795,7 +796,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
             if (!e.ctrlKey && MarqueeView.DragMarquee) this.setPan(this.panX() + e.deltaX, this.panY() + e.deltaY, "None", true);
             else this.zoom(e.clientX, e.clientY, e.deltaY);
         }
-        this.props.Document.targetScale = NumCast(this.props.Document.scale);
+        this.props.Document.targetScale = NumCast(this.props.Document[this.scaleFieldKey]);
     }
 
     @action
@@ -852,7 +853,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
     scaleAtPt(docpt: number[], scale: number) {
         const screenXY = this.getTransform().inverse().transformPoint(docpt[0], docpt[1]);
         this.Document.panTransformType = "Ease";
-        this.layoutDoc.scale = scale;
+        this.layoutDoc[this.scaleFieldKey] = scale;
         const newScreenXY = this.getTransform().inverse().transformPoint(docpt[0], docpt[1]);
         const scrDelta = { x: screenXY[0] - newScreenXY[0], y: screenXY[1] - newScreenXY[1] };
         const newpan = this.getTransform().transformDirection(scrDelta.x, scrDelta.y);
@@ -896,7 +897,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
             newState.initializers![this.Document[Id]] = { panX: newPanX, panY: newPanY };
             HistoryUtil.pushState(newState);
 
-            const savedState = { px: this.Document._panX, py: this.Document._panY, s: this.Document.scale, pt: this.Document.panTransformType };
+            const savedState = { px: this.Document._panX, py: this.Document._panY, s: this.Document[this.scaleFieldKey], pt: this.Document.panTransformType };
 
             // if (!willZoom && DocumentView._focusHack.length) {
             //     Doc.BrushDoc(this.props.Document);
@@ -915,7 +916,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
                 if (afterFocus?.()) {
                     this.Document._panX = savedState.px;
                     this.Document._panY = savedState.py;
-                    this.Document.scale = savedState.s;
+                    this.Document[this.scaleFieldKey] = savedState.s;
                     this.Document.panTransformType = savedState.pt;
                 }
             }, 500);
@@ -924,7 +925,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
     }
 
     setScaleToZoom = (doc: Doc, scale: number = 0.75) => {
-        this.Document.scale = scale * Math.min(this.props.PanelWidth() / NumCast(doc._width), this.props.PanelHeight() / NumCast(doc._height));
+        this.Document[this.scaleFieldKey] = scale * Math.min(this.props.PanelWidth() / NumCast(doc._width), this.props.PanelHeight() / NumCast(doc._height));
     }
 
     @computed get libraryPath() { return this.props.LibraryPath ? [...this.props.LibraryPath, this.props.Document] : []; }
@@ -1125,7 +1126,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
             }));
 
         if (this.props.isAnnotationOverlay) {
-            this.props.Document.scale = Math.max(1, NumCast(this.props.Document.scale));
+            this.props.Document[this.scaleFieldKey] = Math.max(1, NumCast(this.props.Document[this.scaleFieldKey]));
         }
 
         return elements;
@@ -1206,7 +1207,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
         const options = ContextMenu.Instance.findByDescription("Options...");
         const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : [];
 
-        optionItems.push({ description: "reset view", event: () => { this.props.Document._panX = this.props.Document._panY = 0; this.props.Document.scale = 1; }, icon: "compress-arrows-alt" });
+        optionItems.push({ description: "reset view", event: () => { this.props.Document._panX = this.props.Document._panY = 0; this.props.Document[this.scaleFieldKey] = 1; }, icon: "compress-arrows-alt" });
         optionItems.push({ description: "toggle snap line display", event: () => Doc.UserDoc().showSnapLines = !Doc.UserDoc().showSnapLines, icon: "compress-arrows-alt" });
         optionItems.push({ description: "Reset default note style", event: () => Doc.UserDoc().defaultTextLayout = undefined, icon: "eye" });
         optionItems.push({ description: (!this.layoutDoc._nativeWidth || !this.layoutDoc._nativeHeight ? "Freeze" : "Unfreeze") + " Aspect", event: this.toggleNativeDimensions, icon: "snowflake" });
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 085625e69..5f09fa0ee 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -122,7 +122,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
                 FormattedTextBox.SelectOnLoadChar = FormattedTextBox.DefaultLayout ? e.key : "";
                 const tbox = Docs.Create.TextDocument("", {
                     _width: 200, _height: 100, x: x, y: y, _autoHeight: true, _fontSize: NumCast(Doc.UserDoc().fontSize),
-                    _fontFamily: StrCast(Doc.UserDoc().fontFamily), _backgroundColor: StrCast(Doc.UserDoc().backgroundColor),
+                    _fontFamily: StrCast(Doc.UserDoc().fontFamily),
                     title: "-typed text-"
                 });
                 const template = FormattedTextBox.DefaultLayout;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.scss b/src/client/views/nodes/formattedText/FormattedTextBox.scss
index 49114d967..df4a05dd7 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.scss
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.scss
@@ -67,6 +67,7 @@
     display: inline-block;
     position: absolute;
     right: 0;
+    overflow: hidden;
 
     .collectionfreeformview-container {
         position: relative;
@@ -232,6 +233,48 @@ footnote::after {
     }
 }
 
+.prosemirror-anchor {
+    overflow:hidden;
+    display:inline-grid;
+}
+.prosemirror-linkBtn {
+    background:unset;
+    color:unset;
+    padding:0;
+    text-transform: unset;
+    letter-spacing: unset;
+    font-size:unset;
+}
+.prosemirror-links {
+    display: none;
+    position: absolute;
+    background-color: gray;
+    padding-bottom: 10px;
+    margin-top: 1em;
+    z-index: 1;
+  }
+  .prosemirror-hrefoptions{
+      width:0px;
+      border:unset;
+      padding:0px;
+
+  }
+  
+  .prosemirror-links a {
+    float: left;
+    color: white;
+    text-decoration: none;
+  }
+  
+  .prosemirror-links a:hover {
+    background-color: #eee;
+    color: black;
+  }
+  
+  .prosemirror-anchor:hover .prosemirror-links {
+    display: grid;
+  }
+
 .ProseMirror {
     touch-action: none;
     span {
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 1fab54d7e..a8f5b7827 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -585,9 +585,16 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
 
     makeLinkToSelection(linkDocId: string, title: string, location: string, targetDocId: string) {
         if (this._editorView) {
-            const link = this._editorView.state.schema.marks.link.create({ href: Utils.prepend("/doc/" + linkDocId), title: title, location: location, linkId: linkDocId, targetId: targetDocId });
-            this._editorView.dispatch(this._editorView.state.tr.removeMark(this._editorView.state.selection.from, this._editorView.state.selection.to, this._editorView.state.schema.marks.link).
-                addMark(this._editorView.state.selection.from, this._editorView.state.selection.to, link));
+            const newRef = Utils.prepend("/doc/" + linkDocId);
+            const allHrefs = [{ href: newRef, title }];
+            let child: any = null;
+            const sel = this._editorView.state.selection;
+            this._editorView.state.doc.nodesBetween(sel.from, sel.to, (node: any, pos: number, parent: any) => !child && node.marks.length && (child = node));
+            if (child) {
+                allHrefs.push(...(child.marks.find((m: Mark) => m.type.name === schema.marks.link.name)?.attrs.allHrefs ?? []));
+            }
+            const link = this._editorView.state.schema.marks.link.create({ href: newRef, allHrefs, title, location, linkId: linkDocId, targetId: targetDocId });
+            this._editorView.dispatch(this._editorView.state.tr.addMark(this._editorView.state.selection.from, this._editorView.state.selection.to, link));
         }
     }
     componentDidMount() {
@@ -987,7 +994,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         FormattedTextBox._downEvent = false;
         if (!(e.nativeEvent as any).formattedHandled) {
             FormattedTextBoxComment.textBox = this;
-            FormattedTextBoxComment.update(this._editorView!);
+            FormattedTextBoxComment.update(this._editorView!, undefined, (e.target as any)?.className === "prosemirror-dropdownlink" ? (e.target as any).href : "");
         }
         (e.nativeEvent as any).formattedHandled = true;
 
@@ -1205,7 +1212,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
 
     @computed get sidebarWidthPercent() { return StrCast(this.layoutDoc._sidebarWidthPercent, "0%"); }
     sidebarWidth = () => Number(this.sidebarWidthPercent.substring(0, this.sidebarWidthPercent.length - 1)) / 100 * this.props.PanelWidth();
-    sidebarScreenToLocal = () => this.props.ScreenToLocalTransform().translate(-(this.props.PanelWidth() - this.sidebarWidth()), 0);
+    sidebarScreenToLocal = () => this.props.ScreenToLocalTransform().translate(-(this.props.PanelWidth() - this.sidebarWidth()) / this.props.ContentScaling(), 0);
     @computed get sidebarColor() { return StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "transparent")); }
     render() {
         TraceMobx();
@@ -1273,6 +1280,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                                 PanelWidth={this.sidebarWidth}
                                 NativeHeight={returnZero}
                                 NativeWidth={returnZero}
+                                scaleField={this.annotationKey + "-scale"}
                                 annotationsKey={this.annotationKey}
                                 isAnnotationOverlay={false}
                                 focus={this.props.focus}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index 59a6045ab..dde7cc0c1 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -115,7 +115,7 @@ export class FormattedTextBoxComment {
         FormattedTextBoxComment.tooltip && (FormattedTextBoxComment.tooltip.style.display = "");
     }
 
-    static update(view: EditorView, lastState?: EditorState) {
+    static update(view: EditorView, lastState?: EditorState, forceUrl: string = "") {
         const state = view.state;
         // Don't do anything if the document/selection didn't change
         if (lastState && lastState.doc.eq(state.doc) &&
@@ -160,25 +160,26 @@ export class FormattedTextBoxComment {
             let child: any = null;
             state.doc.nodesBetween(state.selection.from, state.selection.to, (node: any, pos: number, parent: any) => !child && node.marks.length && (child = node));
             const mark = child && findLinkMark(child.marks);
-            if (mark && child && nbef && naft && mark.attrs.showPreview) {
-                FormattedTextBoxComment.tooltipText.textContent = "external => " + mark.attrs.href;
-                (FormattedTextBoxComment.tooltipText as any).href = mark.attrs.href;
-                if (mark.attrs.href.startsWith("https://en.wikipedia.org/wiki/")) {
-                    wiki().page(mark.attrs.href.replace("https://en.wikipedia.org/wiki/", "")).then(page => page.summary().then(summary => FormattedTextBoxComment.tooltipText.textContent = summary.substring(0, 500)));
+            const href = mark?.attrs.href || forceUrl;
+            if (forceUrl || (href && child && nbef && naft && mark?.attrs.showPreview)) {
+                FormattedTextBoxComment.tooltipText.textContent = "external => " + href;
+                (FormattedTextBoxComment.tooltipText as any).href = href;
+                if (href.startsWith("https://en.wikipedia.org/wiki/")) {
+                    wiki().page(href.replace("https://en.wikipedia.org/wiki/", "")).then(page => page.summary().then(summary => FormattedTextBoxComment.tooltipText.textContent = summary.substring(0, 500)));
                 } else {
                     FormattedTextBoxComment.tooltipText.style.whiteSpace = "pre";
                     FormattedTextBoxComment.tooltipText.style.overflow = "hidden";
                 }
-                if (mark.attrs.href.indexOf(Utils.prepend("/doc/")) === 0) {
+                if (href.indexOf(Utils.prepend("/doc/")) === 0) {
                     FormattedTextBoxComment.tooltipText.textContent = "target not found...";
                     (FormattedTextBoxComment.tooltipText as any).href = "";
-                    const docTarget = mark.attrs.href.replace(Utils.prepend("/doc/"), "").split("?")[0];
+                    const docTarget = href.replace(Utils.prepend("/doc/"), "").split("?")[0];
                     try {
                         ReactDOM.unmountComponentAtNode(FormattedTextBoxComment.tooltipText);
                     } catch (e) { }
                     docTarget && DocServer.GetRefField(docTarget).then(async linkDoc => {
                         if (linkDoc instanceof Doc) {
-                            (FormattedTextBoxComment.tooltipText as any).href = mark.attrs.href;
+                            (FormattedTextBoxComment.tooltipText as any).href = href;
                             FormattedTextBoxComment.linkDoc = linkDoc;
                             const anchor = FieldValue(Doc.AreProtosEqual(FieldValue(Cast(linkDoc.anchor1, Doc)), textBox.dataDoc) ? Cast(linkDoc.anchor2, Doc) : (Cast(linkDoc.anchor1, Doc)) || linkDoc);
                             const target = anchor?.annotationOn ? await DocCastAsync(anchor.annotationOn) : anchor;
diff --git a/src/client/views/nodes/formattedText/marks_rts.ts b/src/client/views/nodes/formattedText/marks_rts.ts
index ebaa23e99..b42fa6755 100644
--- a/src/client/views/nodes/formattedText/marks_rts.ts
+++ b/src/client/views/nodes/formattedText/marks_rts.ts
@@ -15,6 +15,7 @@ export const marks: { [index: string]: MarkSpec } = {
     link: {
         attrs: {
             href: {},
+            allHrefs: { default: [] as { href: string, title: string }[] },
             targetId: { default: "" },
             linkId: { default: "" },
             showPreview: { default: true },
@@ -31,7 +32,15 @@ export const marks: { [index: string]: MarkSpec } = {
         toDOM(node: any) {
             return node.attrs.docref && node.attrs.title ?
                 ["div", ["span", `"`], ["span", 0], ["span", `"`], ["br"], ["a", { ...node.attrs, class: "prosemirror-attribution", title: `${node.attrs.title}` }, node.attrs.title], ["br"]] :
-                ["a", { ...node.attrs, id: node.attrs.linkId + node.attrs.targetId, title: `${node.attrs.title}` }, 0];
+                node.attrs.allHrefs.length === 1 ?
+                    ["a", { ...node.attrs, id: node.attrs.linkId + node.attrs.targetId, title: `${node.attrs.title}` }, 0] :
+                    ["div", { class: "prosemirror-anchor" },
+                        ["button", { class: "prosemirror-linkBtn" },
+                            ["a", { ...node.attrs, id: node.attrs.linkId + node.attrs.targetId, title: `${node.attrs.title}` }, 0],
+                            ["input", { class: "fa fa-caret-down prosemirror-hrefoptions" }],
+                        ],
+                        ["div", { class: "prosemirror-links" }, ...node.attrs.allHrefs.map((item: { href: string, title: string }) => ["a", { class: "prosemirror-dropdownlink", href: item.href }, item.title])]
+                    ]
         }
     },
 
-- 
cgit v1.2.3-70-g09d2


From e2423815ef608f35fdb9c1625d7de0bf5a5fe206 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sat, 13 Jun 2020 23:19:27 -0400
Subject: fixes to make link lines work correctly with text anchors that have
 more than one link.  fixed problem making a text link anchor by adding dummy
 mark to split the selection first.

---
 .../CollectionFreeFormLinkView.tsx                 | 11 ++++++---
 .../views/nodes/formattedText/FormattedTextBox.tsx | 24 ++++++++++---------
 .../formattedText/FormattedTextBoxComment.tsx      |  2 +-
 .../formattedText/ProsemirrorExampleTransfer.ts    |  1 -
 .../views/nodes/formattedText/RichTextMenu.tsx     |  8 +++----
 src/client/views/nodes/formattedText/marks_rts.ts  | 27 ++++++++++++++--------
 src/fields/RichTextUtils.ts                        |  2 +-
 7 files changed, 45 insertions(+), 30 deletions(-)

(limited to 'src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx')

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
index f3fc04752..8ab00bb29 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -46,10 +46,15 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
                 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 the id of the opposite anchor, 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
+                //   if there's an element in the DOM with a classname containing the link's id and a targetids attribute containing the other end of the link, 
+                //   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 targetAhyperlink = window.document.getElementById(this.props.LinkDocs[0][Id] + (this.props.LinkDocs[0][afield] as Doc)[Id]);
-                const targetBhyperlink = window.document.getElementById(this.props.LinkDocs[0][Id] + (this.props.LinkDocs[0][bfield] as Doc)[Id]);
+                const linkId = this.props.LinkDocs[0][Id]; // this link's Id
+                const AanchorId = (this.props.LinkDocs[0][afield] as Doc)[Id]; // anchor a's id
+                const BanchorId = (this.props.LinkDocs[0][bfield] as Doc)[Id]; // anchor b's id
+                const linkEles = Array.from(window.document.getElementsByClassName(linkId))
+                const targetAhyperlink = linkEles.find((ele: any) => ele.getAttribute("targetids")?.includes(AanchorId));
+                const targetBhyperlink = linkEles.find((ele: any) => ele.getAttribute("targetids")?.includes(BanchorId));
                 if (!targetBhyperlink) {
                     this.props.A.props.Document[afield + "_x"] = (apt.point.x - abounds.left) / abounds.width * 100;
                     this.props.A.props.Document[afield + "_y"] = (apt.point.y - abounds.top) / abounds.height * 100;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 95d36c994..ffab1d1e1 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -583,20 +583,22 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         };
     }
 
-    makeLinkToSelection(linkDocId: string, title: string, location: string, targetId: string) {
-        if (this._editorView) {
-            const href = Utils.prepend("/doc/" + linkDocId);
-            const sel = this._editorView.state.selection;
-            let tr = this._editorView!.state.tr;
-            sel.from !== sel.to && this._editorView.state.doc.nodesBetween(sel.from, sel.to, (node: any, pos: number, parent: any) => {
-                if (node.firstChild === null) {
-                    const allHrefs = [{ href, title }];
+    makeLinkToSelection(linkId: string, title: string, location: string, targetId: string) {
+        const state = this._editorView?.state;
+        if (state) {
+            const href = Utils.prepend("/doc/" + linkId);
+            const sel = state.selection;
+            const splitter = state.schema.marks.splitter.create({ id: Utils.GenerateGuid() });
+            let tr = state.tr.addMark(sel.from, sel.to, splitter);
+            sel.from !== sel.to && tr.doc.nodesBetween(sel.from, sel.to, (node: any, pos: number, parent: any) => {
+                if (node.firstChild === null && node.marks.find((m: Mark) => m.type.name === schema.marks.splitter.name)) {
+                    const allHrefs = [{ href, title, targetId, linkId }];
                     allHrefs.push(...(node.marks.find((m: Mark) => m.type.name === schema.marks.link.name)?.attrs.allHrefs ?? []));
-                    const link = this._editorView!.state.schema.marks.link.create({ href, allHrefs, title, location, linkId: linkDocId, targetId });
+                    const link = state.schema.marks.link.create({ href, allHrefs, title, location, linkId, targetId });
                     tr = tr.addMark(pos, pos + node.nodeSize, link);
                 }
             });
-            this._editorView.dispatch(tr);
+            this._editorView!.dispatch(tr.removeMark(sel.from, sel.to, splitter));
         }
     }
     componentDidMount() {
@@ -704,7 +706,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                     }
                     const marks = [...node.marks];
                     const linkIndex = marks.findIndex(mark => mark.type === editor.state.schema.marks.link);
-                    return linkIndex !== -1 && scrollToLinkID === marks[linkIndex].attrs.href.replace(/.*\/doc\//, "") ? node : undefined;
+                    return linkIndex !== -1 && marks[linkIndex].attrs.allRefs.find((item: { href: string }) => scrollToLinkID === item.href.replace(/.*\/doc\//, "")) ? node : undefined;
                 };
 
                 let start = 0;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index dde7cc0c1..7513c881d 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -160,7 +160,7 @@ export class FormattedTextBoxComment {
             let child: any = null;
             state.doc.nodesBetween(state.selection.from, state.selection.to, (node: any, pos: number, parent: any) => !child && node.marks.length && (child = node));
             const mark = child && findLinkMark(child.marks);
-            const href = mark?.attrs.href || forceUrl;
+            const href = mark?.attrs.allHrefs.find((item: { href: string }) => item.href)?.href || forceUrl;
             if (forceUrl || (href && child && nbef && naft && mark?.attrs.showPreview)) {
                 FormattedTextBoxComment.tooltipText.textContent = "external => " + href;
                 (FormattedTextBoxComment.tooltipText as any).href = href;
diff --git a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
index 0e3e7f91e..77b93b9d2 100644
--- a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
+++ b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
@@ -6,7 +6,6 @@ import { liftListItem, sinkListItem } from "./prosemirrorPatches.js";
 import { splitListItem, wrapInList, } from "prosemirror-schema-list";
 import { EditorState, Transaction, TextSelection } from "prosemirror-state";
 import { SelectionManager } from "../../../util/SelectionManager";
-import { Docs } from "../../../documents/Documents";
 import { NumCast, BoolCast, Cast, StrCast } from "../../../../fields/Types";
 import { Doc } from "../../../../fields/Doc";
 import { FormattedTextBox } from "./FormattedTextBox";
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index fd1b26208..03d393cde 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -631,7 +631,7 @@ export default class RichTextMenu extends AntimodeMenu {
         const node = this.view.state.selection.$from.nodeAfter;
         const link = node && node.marks.find(m => m.type.name === "link");
         if (link) {
-            const href = link.attrs.href;
+            const href = link.attrs.allHrefs.length > 0 ? link.attrs.allHrefs[0].href : undefined;
             if (href) {
                 if (href.indexOf(Utils.prepend("/doc/")) === 0) {
                     const linkclicked = href.replace(Utils.prepend("/doc/"), "").split("?")[0];
@@ -677,7 +677,7 @@ export default class RichTextMenu extends AntimodeMenu {
 
         const node = this.view.state.selection.$from.nodeAfter;
         const link = node && node.marks.find(m => m.type === this.view!.state.schema.marks.link);
-        const href = link!.attrs.href;
+        const href = link!.attrs.allHrefs.length > 0 ? link!.attrs.allHrefs[0].href : undefined;
         if (href) {
             if (href.indexOf(Utils.prepend("/doc/")) === 0) {
                 const linkclicked = href.replace(Utils.prepend("/doc/"), "").split("?")[0];
@@ -705,8 +705,8 @@ export default class RichTextMenu extends AntimodeMenu {
         let startIndex = $start.index();
         let endIndex = $start.indexAfter();
 
-        while (startIndex > 0 && $start.parent.child(startIndex - 1).marks.filter(m => m.type === mark && m.attrs.href === href).length) startIndex--;
-        while (endIndex < $start.parent.childCount && $start.parent.child(endIndex).marks.filter(m => m.type === mark && m.attrs.href === href).length) endIndex++;
+        while (startIndex > 0 && $start.parent.child(startIndex - 1).marks.filter(m => m.type === mark && m.attrs.allHrefs.find((item: { href: string }) => item.href === href)).length) startIndex--;
+        while (endIndex < $start.parent.childCount && $start.parent.child(endIndex).marks.filter(m => m.type === mark && m.attrs.allHrefs.find((item: { href: string }) => item.href === href)).length) endIndex++;
 
         let startPos = $start.start();
         let endPos = startPos;
diff --git a/src/client/views/nodes/formattedText/marks_rts.ts b/src/client/views/nodes/formattedText/marks_rts.ts
index b42fa6755..9c279a88f 100644
--- a/src/client/views/nodes/formattedText/marks_rts.ts
+++ b/src/client/views/nodes/formattedText/marks_rts.ts
@@ -9,15 +9,20 @@ const codeDOM: DOMOutputSpecArray = ["code", 0];
 
 // :: Object [Specs](#model.MarkSpec) for the marks in the schema.
 export const marks: { [index: string]: MarkSpec } = {
+    splitter: {
+        attrs: {
+            id: { default: "" }
+        },
+        toDOM(node: any) {
+            return ["div", { className: "dummy" }, 0];
+        }
+    },
     // :: MarkSpec A link. Has `href` and `title` attributes. `title`
     // defaults to the empty string. Rendered and parsed as an `<a>`
     // element.
     link: {
         attrs: {
-            href: {},
-            allHrefs: { default: [] as { href: string, title: string }[] },
-            targetId: { default: "" },
-            linkId: { default: "" },
+            allHrefs: { default: [] as { href: string, title: string, linkId: string, targetId: string }[] },
             showPreview: { default: true },
             location: { default: null },
             title: { default: null },
@@ -26,20 +31,24 @@ export const marks: { [index: string]: MarkSpec } = {
         inclusive: false,
         parseDOM: [{
             tag: "a[href]", getAttrs(dom: any) {
-                return { href: dom.getAttribute("href"), location: dom.getAttribute("location"), title: dom.getAttribute("title"), targetId: dom.getAttribute("id") };
+                return { allHrefs: [{ href: dom.getAttribute("href"), title: dom.getAttribute("title"), linkId: dom.getAttribute("linkids"), targetId: dom.getAttribute("targetids") }], location: dom.getAttribute("location"), };
             }
         }],
         toDOM(node: any) {
+            const targetids = node.attrs.allHrefs.reduce((p: string, item: { href: string, title: string, targetId: string, linkId: string }) => p + " " + item.targetId, "");
+            const linkids = node.attrs.allHrefs.reduce((p: string, item: { href: string, title: string, targetId: string, linkId: string }) => p + " " + item.linkId, "");
             return node.attrs.docref && node.attrs.title ?
                 ["div", ["span", `"`], ["span", 0], ["span", `"`], ["br"], ["a", { ...node.attrs, class: "prosemirror-attribution", title: `${node.attrs.title}` }, node.attrs.title], ["br"]] :
                 node.attrs.allHrefs.length === 1 ?
-                    ["a", { ...node.attrs, id: node.attrs.linkId + node.attrs.targetId, title: `${node.attrs.title}` }, 0] :
+                    ["a", { ...node.attrs, class: linkids, targetids, title: `${node.attrs.title}`, href: node.attrs.allHrefs[0].href }, 0] :
                     ["div", { class: "prosemirror-anchor" },
                         ["button", { class: "prosemirror-linkBtn" },
-                            ["a", { ...node.attrs, id: node.attrs.linkId + node.attrs.targetId, title: `${node.attrs.title}` }, 0],
-                            ["input", { class: "fa fa-caret-down prosemirror-hrefoptions" }],
+                            ["a", { ...node.attrs, class: linkids, targetids, title: `${node.attrs.title}` }, 0],
+                            ["input", { class: "prosemirror-hrefoptions" }],
                         ],
-                        ["div", { class: "prosemirror-links" }, ...node.attrs.allHrefs.map((item: { href: string, title: string }) => ["a", { class: "prosemirror-dropdownlink", href: item.href }, item.title])]
+                        ["div", { class: "prosemirror-links" }, ...node.attrs.allHrefs.map((item: { href: string, title: string }) =>
+                            ["a", { class: "prosemirror-dropdownlink", href: item.href }, item.title]
+                        )]
                     ]
         }
     },
diff --git a/src/fields/RichTextUtils.ts b/src/fields/RichTextUtils.ts
index f81ec8c6d..66959882d 100644
--- a/src/fields/RichTextUtils.ts
+++ b/src/fields/RichTextUtils.ts
@@ -392,7 +392,7 @@ export namespace RichTextUtils {
                     const { attrs } = mark;
                     switch (converted) {
                         case "link":
-                            let url = attrs.href;
+                            let url = attrs.allHrefs.length ? attrs.allHrefs[0].href : "";
                             const delimiter = "/doc/";
                             const alreadyShared = "?sharing=true";
                             if (new RegExp(window.location.origin + delimiter).test(url) && !url.endsWith(alreadyShared)) {
-- 
cgit v1.2.3-70-g09d2


From 182aef3ef47a3005e1b8a60bad8195769ce07733 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Mon, 15 Jun 2020 18:00:25 -0400
Subject: fixed acls for text hyperlinks (mostly) by not allowing links to be
 traversed

---
 src/client/DocServer.ts                            |  7 +++-
 src/client/views/nodes/DocumentView.tsx            | 14 ++++++-
 .../formattedText/FormattedTextBoxComment.tsx      | 46 +++++++++++++---------
 src/fields/Doc.ts                                  | 20 ++--------
 4 files changed, 49 insertions(+), 38 deletions(-)

(limited to 'src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx')

diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index c6b3fa61f..c7dfb0b23 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -1,6 +1,6 @@
 import * as io from 'socket.io-client';
 import { MessageStore, YoutubeQueryTypes, GestureContent, MobileInkOverlayContent, UpdateMobileInkOverlayPositionContent, MobileDocumentUploadContent } from "./../server/Message";
-import { Opt, Doc } from '../fields/Doc';
+import { Opt, Doc, fetchProto } from '../fields/Doc';
 import { Utils, emptyFunction } from '../Utils';
 import { SerializationHelper } from './util/SerializationHelper';
 import { RefField } from '../fields/RefField';
@@ -244,7 +244,10 @@ export namespace DocServer {
             return cached;
         } else {
             // CACHED => great, let's just return the cached field we have
-            return Promise.resolve(cached);
+            return Promise.resolve(cached).then(field => {
+                (field instanceof Doc) && fetchProto(field);
+                return field;
+            });
         }
     };
     const _GetCachedRefFieldImpl = (id: string): Opt<RefField> => {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 35bf5344e..8a067b806 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -687,7 +687,18 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     @undoBatch
     @action
     setAcl = (acl: "readOnly" | "addOnly" | "ownerOnly") => {
-        this.layoutDoc.ACL = this.dataDoc.ACL = acl;
+        this.dataDoc.ACL = this.props.Document.ACL = acl;
+        DocListCast(this.dataDoc[Doc.LayoutFieldKey(this.dataDoc)]).map(d => {
+            if (d.author === Doc.CurrentUserEmail) d.ACL = acl;
+            const data = d[DataSym];
+            if (data && data.author === Doc.CurrentUserEmail) data.ACL = acl;
+        });
+    }
+    @undoBatch
+    @action
+    testAcl = (acl: "readOnly" | "addOnly" | "ownerOnly") => {
+        this.dataDoc.author = this.props.Document.author = "ADMIN";
+        this.dataDoc.ACL = this.props.Document.ACL = acl;
         DocListCast(this.dataDoc[Doc.LayoutFieldKey(this.dataDoc)]).map(d => {
             if (d.author === Doc.CurrentUserEmail) d.ACL = acl;
             const data = d[DataSym];
@@ -758,6 +769,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         moreItems.push({ description: "Make Add Only", event: () => this.setAcl("addOnly"), icon: "concierge-bell" });
         moreItems.push({ description: "Make Read Only", event: () => this.setAcl("readOnly"), icon: "concierge-bell" });
         moreItems.push({ description: "Make Private", event: () => this.setAcl("ownerOnly"), icon: "concierge-bell" });
+        moreItems.push({ description: "Test Private", event: () => this.testAcl("ownerOnly"), icon: "concierge-bell" });
         moreItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc), icon: "concierge-bell" });
         moreItems.push({ description: `${this.Document._chromeStatus !== "disabled" ? "Hide" : "Show"} Chrome`, event: () => this.Document._chromeStatus = (this.Document._chromeStatus !== "disabled" ? "disabled" : "enabled"), icon: "project-diagram" });
         moreItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" });
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index 7513c881d..5ac173602 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -84,11 +84,13 @@ export class FormattedTextBoxComment {
                 const keep = e.target && (e.target as any).type === "checkbox" ? true : false;
                 const textBox = FormattedTextBoxComment.textBox;
                 if (FormattedTextBoxComment.linkDoc && !keep && textBox) {
-                    if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) {
-                        textBox.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "inTab" : "onRight");
-                    } else {
-                        DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, textBox.props.Document,
-                            (doc: Doc, followLinkLocation: string) => textBox.props.addDocTab(doc, e.ctrlKey ? "inTab" : followLinkLocation));
+                    if (FormattedTextBoxComment.linkDoc.author) {
+                        if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) {
+                            textBox.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "inTab" : "onRight");
+                        } else {
+                            DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, textBox.props.Document,
+                                (doc: Doc, followLinkLocation: string) => textBox.props.addDocTab(doc, e.ctrlKey ? "inTab" : followLinkLocation));
+                        }
                     }
                 } else if (textBox && (FormattedTextBoxComment.tooltipText as any).href) {
                     textBox.props.addDocTab(Docs.Create.WebDocument((FormattedTextBoxComment.tooltipText as any).href, { title: (FormattedTextBoxComment.tooltipText as any).href, _width: 200, _height: 400, UseCors: true }), "onRight");
@@ -115,6 +117,23 @@ export class FormattedTextBoxComment {
         FormattedTextBoxComment.tooltip && (FormattedTextBoxComment.tooltip.style.display = "");
     }
 
+    static showCommentbox(set: string, view: EditorView, nbef: number) {
+        const state = view.state;
+        if (set !== "none") {
+            // These are in screen coordinates
+            // let start = view.coordsAtPos(state.selection.from), end = view.coordsAtPos(state.selection.to);
+            const start = view.coordsAtPos(state.selection.from - nbef), end = view.coordsAtPos(state.selection.from - nbef);
+            // The box in which the tooltip is positioned, to use as base
+            const box = (document.getElementsByClassName("mainView-container") as any)[0].getBoundingClientRect();
+            // Find a center-ish x position from the selection endpoints (when
+            // crossing lines, end may be more to the left)
+            const left = Math.max((start.left + end.left) / 2, start.left + 3);
+            FormattedTextBoxComment.tooltip.style.left = (left - box.left) + "px";
+            FormattedTextBoxComment.tooltip.style.bottom = (box.bottom - start.top) + "px";
+        }
+        FormattedTextBoxComment.tooltip && (FormattedTextBoxComment.tooltip.style.display = set);
+    }
+
     static update(view: EditorView, lastState?: EditorState, forceUrl: string = "") {
         const state = view.state;
         // Don't do anything if the document/selection didn't change
@@ -186,7 +205,8 @@ export class FormattedTextBoxComment {
                             if (anchor !== target && anchor && target) {
                                 target._scrollY = NumCast(anchor?.y);
                             }
-                            if (target) {
+                            if (target?.author) {
+                                FormattedTextBoxComment.showCommentbox("", view, nbef);
                                 ReactDOM.render(<ContentFittingDocumentView
                                     Document={target}
                                     LibraryPath={emptyPath}
@@ -224,19 +244,7 @@ export class FormattedTextBoxComment {
                 set = "";
             }
         }
-        if (set !== "none") {
-            // These are in screen coordinates
-            // let start = view.coordsAtPos(state.selection.from), end = view.coordsAtPos(state.selection.to);
-            const start = view.coordsAtPos(state.selection.from - nbef), end = view.coordsAtPos(state.selection.from - nbef);
-            // The box in which the tooltip is positioned, to use as base
-            const box = (document.getElementsByClassName("mainView-container") as any)[0].getBoundingClientRect();
-            // Find a center-ish x position from the selection endpoints (when
-            // crossing lines, end may be more to the left)
-            const left = Math.max((start.left + end.left) / 2, start.left + 3);
-            FormattedTextBoxComment.tooltip.style.left = (left - box.left) + "px";
-            FormattedTextBoxComment.tooltip.style.bottom = (box.bottom - start.top) + "px";
-        }
-        FormattedTextBoxComment.tooltip && (FormattedTextBoxComment.tooltip.style.display = set);
+        FormattedTextBoxComment.showCommentbox(set, view, nbef);
     }
 
     destroy() { }
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index a72088d04..b205a4a10 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -100,7 +100,7 @@ export const UpdatingFromServer = Symbol("UpdatingFromServer");
 const CachedUpdates = Symbol("Cached updates");
 
 
-function fetchProto(doc: Doc) {
+export function fetchProto(doc: Doc) {
     if (doc.author !== Doc.CurrentUserEmail) {
         const acl = Doc.Get(doc, "ACL", true);
         switch (acl) {
@@ -116,21 +116,9 @@ function fetchProto(doc: Doc) {
         }
     }
 
-    const proto = doc.proto;
-    if (proto instanceof Promise) {
-        proto.then(proto => {
-            if (proto.author !== Doc.CurrentUserEmail) {
-                if (proto.ACL === "ownerOnly") {
-                    proto[AclSym] = doc[AclSym] = AclPrivate;
-                    return undefined;
-                } else if (proto.ACL === "readOnly") {
-                    proto[AclSym] = doc[AclSym] = AclReadonly;
-                } else if (proto.ACL === "addOnly") {
-                    proto[AclSym] = doc[AclSym] = AclAddonly;
-                }
-            }
-        });
-        return proto;
+    if (doc.proto instanceof Promise) {
+        doc.proto.then(proto => fetchProto(proto));
+        return doc.proto;
     }
 }
 
-- 
cgit v1.2.3-70-g09d2


From 997035dfaf78ec0bcb4ec1b85e2e3f7dae410ca0 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Tue, 16 Jun 2020 12:40:21 -0400
Subject: cleaned up some of the prosemirror plugin views.

---
 .../nodes/formattedText/DashDocCommentView.tsx     |  38 +++---
 .../views/nodes/formattedText/DashFieldView.tsx    |   7 +-
 .../views/nodes/formattedText/FootnoteView.tsx     |  17 +--
 .../views/nodes/formattedText/FormattedTextBox.tsx |   8 +-
 .../formattedText/FormattedTextBoxComment.tsx      |   7 +-
 .../views/nodes/formattedText/RichTextSchema.tsx   |  96 +-------------
 .../views/nodes/formattedText/SummaryView.tsx      | 144 +++++++--------------
 7 files changed, 86 insertions(+), 231 deletions(-)

(limited to 'src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx')

diff --git a/src/client/views/nodes/formattedText/DashDocCommentView.tsx b/src/client/views/nodes/formattedText/DashDocCommentView.tsx
index 2d4e360a8..ad204f3df 100644
--- a/src/client/views/nodes/formattedText/DashDocCommentView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocCommentView.tsx
@@ -4,6 +4,10 @@ import { Doc } from "../../../../fields/Doc";
 import { DocServer } from "../../../DocServer";
 import React = require("react");
 
+
+// creates an inline comment in a note when '>>' is typed.
+// the comment sits on the right side of the note and vertically aligns with its anchor in the text.
+// the comment can be toggled on/off with the '<-' text anchor.
 export class DashDocCommentView {
     _fieldWrapper: HTMLDivElement; // container for label and value
 
@@ -19,11 +23,7 @@ export class DashDocCommentView {
         this._fieldWrapper.onkeyup = function (e: any) { e.stopPropagation(); };
         this._fieldWrapper.onmousedown = function (e: any) { e.stopPropagation(); };
 
-        ReactDOM.render(<DashDocCommentViewInternal
-            node={node}
-            view={view}
-            getPos={getPos}
-        />, this._fieldWrapper);
+        ReactDOM.render(<DashDocCommentViewInternal view={view} getPos={getPos} docid={node.attrs.docid} />, this._fieldWrapper);
         (this as any).dom = this._fieldWrapper;
     }
 
@@ -35,12 +35,11 @@ export class DashDocCommentView {
 }
 
 interface IDashDocCommentViewInternal {
-    node: any;
+    docid: string;
     view: any;
     getPos: any;
 }
 
-
 export class DashDocCommentViewInternal extends React.Component<IDashDocCommentViewInternal>{
 
     constructor(props: IDashDocCommentViewInternal) {
@@ -51,18 +50,14 @@ export class DashDocCommentViewInternal extends React.Component<IDashDocCommentV
         this.onPointerDownCollapsed = this.onPointerDownCollapsed.bind(this)
     }
 
-    getId() {
-        return this.props.node.attrs.docid
-    }
-
     onPointerLeaveCollapsed(e: any) {
-        DocServer.GetRefField(this.props.node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowUnhighlight());
+        DocServer.GetRefField(this.props.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowUnhighlight());
         e.preventDefault();
         e.stopPropagation();
     };
 
     onPointerEnterCollapsed(e: any) {
-        DocServer.GetRefField(this.props.node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc, false));
+        DocServer.GetRefField(this.props.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc, false));
         e.preventDefault();
         e.stopPropagation();
     };
@@ -75,7 +70,7 @@ export class DashDocCommentViewInternal extends React.Component<IDashDocCommentV
             const tr = this.props.view.state.tr.setNodeMarkup(target.pos, undefined, { ...target.node.attrs, hidden: target.node.attrs.hidden ? false : true });
             this.props.view.dispatch(tr.setSelection(TextSelection.create(tr.doc, this.props.getPos() + (expand ? 2 : 1)))); // update the attrs
             setTimeout(() => {
-                expand && DocServer.GetRefField(this.props.node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc));
+                expand && DocServer.GetRefField(this.props.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc));
                 try { this.props.view.dispatch(this.props.view.state.tr.setSelection(TextSelection.create(this.props.view.state.tr.doc, this.props.getPos() + (expand ? 2 : 1)))); } catch (e) { }
             }, 0);
         }
@@ -87,16 +82,17 @@ export class DashDocCommentViewInternal extends React.Component<IDashDocCommentV
     };
 
     targetNode = () => {  // search forward in the prosemirror doc for the attached dashDocNode that is the target of the comment anchor
-        for (let i = this.props.getPos() + 1; i < this.props.view.state.doc.content.size; i++) {
-            const m = this.props.view.state.doc.nodeAt(i);
-            if (m && m.type === this.props.view.state.schema.nodes.dashDoc && m.attrs.docid === this.props.node.attrs.docid) {
+        const state = this.props.view.state;
+        for (let i = this.props.getPos() + 1; i < state.doc.content.size; i++) {
+            const m = state.doc.nodeAt(i);
+            if (m && m.type === state.schema.nodes.dashDoc && m.attrs.docid === this.props.docid) {
                 return { node: m, pos: i, hidden: m.attrs.hidden } as { node: any, pos: number, hidden: boolean };
             }
         }
 
-        const dashDoc = this.props.view.state.schema.nodes.dashDoc.create({ width: 75, height: 35, title: "dashDoc", docid: this.props.node.attrs.docid, float: "right" });
-        this.props.view.dispatch(this.props.view.state.tr.insert(this.props.getPos() + 1, dashDoc));
-        setTimeout(() => { try { this.props.view.dispatch(this.props.view.state.tr.setSelection(TextSelection.create(this.props.view.state.tr.doc, this.props.getPos() + 2))); } catch (e) { } }, 0);
+        const dashDoc = state.schema.nodes.dashDoc.create({ width: 75, height: 35, title: "dashDoc", docid: this.props.docid, float: "right" });
+        this.props.view.dispatch(state.tr.insert(this.props.getPos() + 1, dashDoc));
+        setTimeout(() => { try { this.props.view.dispatch(state.tr.setSelection(TextSelection.create(state.tr.doc, this.props.getPos() + 2))); } catch (e) { } }, 0);
         return undefined;
     };
 
@@ -104,7 +100,7 @@ export class DashDocCommentViewInternal extends React.Component<IDashDocCommentV
         return (
             <span
                 className="formattedTextBox-inlineComment"
-                id={"DashDocCommentView-" + this.getId}
+                id={"DashDocCommentView-" + this.props.docid}
                 onPointerLeave={this.onPointerLeaveCollapsed}
                 onPointerEnter={this.onPointerEnterCollapsed}
                 onPointerUp={this.onPointerUpCollapsed}
diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx
index 60a9c2a27..8c16f4a1a 100644
--- a/src/client/views/nodes/formattedText/DashFieldView.tsx
+++ b/src/client/views/nodes/formattedText/DashFieldView.tsx
@@ -14,7 +14,6 @@ import "./DashFieldView.scss";
 import { observer } from "mobx-react";
 import { DocUtils } from "../../../documents/Documents";
 
-
 export class DashFieldView {
     _fieldWrapper: HTMLDivElement; // container for label and value
 
@@ -40,12 +39,10 @@ export class DashFieldView {
         />, this._fieldWrapper);
         (this as any).dom = this._fieldWrapper;
     }
-    destroy() {
-        ReactDOM.unmountComponentAtNode(this._fieldWrapper);
-    }
+    destroy() { ReactDOM.unmountComponentAtNode(this._fieldWrapper); }
     selectNode() { }
-
 }
+
 interface IDashFieldViewInternal {
     fieldKey: string;
     docid: string;
diff --git a/src/client/views/nodes/formattedText/FootnoteView.tsx b/src/client/views/nodes/formattedText/FootnoteView.tsx
index 1d21f2ae9..1683cc972 100644
--- a/src/client/views/nodes/formattedText/FootnoteView.tsx
+++ b/src/client/views/nodes/formattedText/FootnoteView.tsx
@@ -28,15 +28,11 @@ export class FootnoteView {
     }
 
     selectNode() {
-        const attrs = { ...this.node.attrs };
-        attrs.visibility = true;
         this.dom.classList.add("ProseMirror-selectednode");
         if (!this.innerView) this.open();
     }
 
     deselectNode() {
-        const attrs = { ...this.node.attrs };
-        attrs.visibility = false;
         this.dom.classList.remove("ProseMirror-selectednode");
         if (this.innerView) this.close();
     }
@@ -78,7 +74,7 @@ export class FootnoteView {
                 }) as any
             }
         });
-        setTimeout(() => this.innerView && this.innerView.docView.setSelection(0, 0, this.innerView.root, true), 0);
+        setTimeout(() => this.innerView?.docView.setSelection(0, 0, this.innerView.root, true), 0);
     }
 
     ignore = (e: PointerEvent) => {
@@ -88,13 +84,11 @@ export class FootnoteView {
 
     toggle = () => {
         if (this.innerView) this.close();
-        else {
-            this.open();
-        }
+        else this.open();
     }
 
     close() {
-        this.innerView && this.innerView.destroy();
+        this.innerView?.destroy();
         this.innerView = null;
         this.dom.textContent = "";
     }
@@ -106,8 +100,7 @@ export class FootnoteView {
         if (!tr.getMeta("fromOutside")) {
             const outerTr = this.outerView.state.tr, offsetMap = StepMap.offset(this.getPos() + 1);
             for (const transaction of transactions) {
-                const steps = transaction.steps;
-                for (const step of steps) {
+                for (const step of transaction.steps) {
                     outerTr.step(step.map(offsetMap));
                 }
             }
@@ -139,7 +132,7 @@ export class FootnoteView {
     }
 
     stopEvent(event: any) {
-        return this.innerView && this.innerView.dom.contains(event.target);
+        return this.innerView?.dom.contains(event.target);
     }
 
     ignoreMutation() {
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 99cd503ec..ba36a1618 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -35,8 +35,8 @@ import buildKeymap from "./ProsemirrorExampleTransfer";
 import RichTextMenu from './RichTextMenu';
 import { RichTextRules } from "./RichTextRules";
 
-import { DashDocView } from "./DashDocView";
-// import { DashDocView } from "./RichTextSchema";
+//import { DashDocView } from "./DashDocView";
+import { DashDocView } from "./RichTextSchema";
 
 import { DashDocCommentView } from "./DashDocCommentView";
 import { DashFieldView } from "./DashFieldView";
@@ -903,9 +903,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                 },
                 dispatchTransaction: this.dispatchTransaction,
                 nodeViews: {
-                    dashComment(node, view, getPos) { console.log("rendering dashComment"); return new DashDocCommentView(node, view, getPos); },
-                    dashField(node, view, getPos) { return new DashFieldView(node, view, getPos, self); },
+                    dashComment(node, view, getPos) { return new DashDocCommentView(node, view, getPos); },
                     dashDoc(node, view, getPos) { return new DashDocView(node, view, getPos, self); },
+                    dashField(node, view, getPos) { return new DashFieldView(node, view, getPos, self); },
                     summary(node, view, getPos) { return new SummaryView(node, view, getPos); },
                     ordered_list(node, view, getPos) { return new OrderedListView(); },
                     footnote(node, view, getPos) { return new FootnoteView(node, view, getPos); }
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index 5ac173602..000b3c2e5 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -50,7 +50,9 @@ export function findEndOfMark(rpos: ResolvedPos, view: EditorView, finder: (mark
     return after;
 }
 
-
+// this view appears when clicking on text that has a hyperlink which is configured to show a preview of its target.
+// this will also display metadata information about text when the view is configured to display things like other people who authored text.
+// 
 export class FormattedTextBoxComment {
     static tooltip: HTMLElement;
     static tooltipText: HTMLElement;
@@ -235,9 +237,6 @@ export class FormattedTextBoxComment {
                                 FormattedTextBoxComment.tooltip.style.width = NumCast(target._width) ? `${NumCast(target._width)}` : "100%";
                                 FormattedTextBoxComment.tooltip.style.height = NumCast(target._height) ? `${NumCast(target._height)}` : "100%";
                             }
-                            // let ext = (target && target.type !== DocumentType.PDFANNO && Doc.fieldExtensionDoc(target, "data")) || target; // try guessing that the target doc's data is in the 'data' field.  probably need an 'overviewLayout' and then just display the target Document ....
-                            // let text = ext && StrCast(ext.text);
-                            // ext && (FormattedTextBoxComment.tooltipText.textContent = (target && target.type === DocumentType.PDFANNO ? "Quoted from " : "") + "=> " + (text || StrCast(ext.title)));
                         }
                     });
                 }
diff --git a/src/client/views/nodes/formattedText/RichTextSchema.tsx b/src/client/views/nodes/formattedText/RichTextSchema.tsx
index 79abfa995..05557e22a 100644
--- a/src/client/views/nodes/formattedText/RichTextSchema.tsx
+++ b/src/client/views/nodes/formattedText/RichTextSchema.tsx
@@ -1,95 +1,20 @@
-import { IReactionDisposer, observable, reaction, runInAction } from "mobx";
-import { baseKeymap, toggleMark } from "prosemirror-commands";
-import { redo, undo } from "prosemirror-history";
-import { keymap } from "prosemirror-keymap";
-import { DOMOutputSpecArray, Fragment, MarkSpec, Node, NodeSpec, Schema, Slice } from "prosemirror-model";
-import { bulletList, listItem, orderedList } from 'prosemirror-schema-list';
-import { EditorState, NodeSelection, Plugin, TextSelection } from "prosemirror-state";
-import { StepMap } from "prosemirror-transform";
-import { EditorView } from "prosemirror-view";
+import { IReactionDisposer, reaction } from "mobx";
+import { NodeSelection } from "prosemirror-state";
 import * as ReactDOM from 'react-dom';
-import { Doc, DocListCast, Field, HeightSym, WidthSym } from "../../../../fields/Doc";
+import { Doc, HeightSym, WidthSym } from "../../../../fields/Doc";
 import { Id } from "../../../../fields/FieldSymbols";
-import { List } from "../../../../fields/List";
 import { ObjectField } from "../../../../fields/ObjectField";
-import { listSpec } from "../../../../fields/Schema";
-import { SchemaHeaderField } from "../../../../fields/SchemaHeaderField";
 import { ComputedField } from "../../../../fields/ScriptField";
-import { BoolCast, Cast, NumCast, StrCast, FieldValue } from "../../../../fields/Types";
-import { emptyFunction, returnEmptyString, returnFalse, returnOne, Utils, returnZero } from "../../../../Utils";
+import { BoolCast, Cast, NumCast, StrCast } from "../../../../fields/Types";
+import { emptyFunction, returnEmptyString, returnFalse, returnZero, Utils } from "../../../../Utils";
 import { DocServer } from "../../../DocServer";
 import { Docs, DocUtils } from "../../../documents/Documents";
-import { CollectionViewType } from "../../collections/CollectionView";
+import { Transform } from "../../../util/Transform";
 import { DocumentView } from "../DocumentView";
 import { FormattedTextBox } from "./FormattedTextBox";
-import { DocumentManager } from "../../../util/DocumentManager";
-import { Transform } from "../../../util/Transform";
 import React = require("react");
 
 
-
-// export class DashDocCommentView {
-//     _collapsed: HTMLElement;
-//     _view: any;
-//     constructor(node: any, view: any, getPos: any) {
-
-//         console.log("DashDocCommentView constructor");
-
-//         //moved
-//         this._collapsed = document.createElement("span");
-//         this._collapsed.className = "formattedTextBox-inlineComment";
-//         this._collapsed.id = "DashDocCommentView-" + node.attrs.docid;
-//         this._view = view;
-//         //moved
-//         const targetNode = () => {  // search forward in the prosemirror doc for the attached dashDocNode that is the target of the comment anchor
-//             for (let i = getPos() + 1; i < view.state.doc.content.size; i++) {
-//                 const m = view.state.doc.nodeAt(i);
-//                 if (m && m.type === view.state.schema.nodes.dashDoc && m.attrs.docid === node.attrs.docid) {
-//                     return { node: m, pos: i, hidden: m.attrs.hidden } as { node: any, pos: number, hidden: boolean };
-//                 }
-//             }
-//             const dashDoc = view.state.schema.nodes.dashDoc.create({ width: 75, height: 35, title: "dashDoc", docid: node.attrs.docid, float: "right" });
-//             view.dispatch(view.state.tr.insert(getPos() + 1, dashDoc));
-//             setTimeout(() => { try { view.dispatch(view.state.tr.setSelection(TextSelection.create(view.state.tr.doc, getPos() + 2))); } catch (e) { } }, 0);
-//             return undefined;
-//         };
-//         //moved
-//         this._collapsed.onpointerdown = (e: any) => {
-//             e.stopPropagation();
-//         };
-//         //moved
-//         this._collapsed.onpointerup = (e: any) => {
-//             const target = targetNode();
-//             if (target) {
-//                 const expand = target.hidden;
-//                 const tr = view.state.tr.setNodeMarkup(target.pos, undefined, { ...target.node.attrs, hidden: target.node.attrs.hidden ? false : true });
-//                 view.dispatch(tr.setSelection(TextSelection.create(tr.doc, getPos() + (expand ? 2 : 1)))); // update the attrs
-//                 setTimeout(() => {
-//                     expand && DocServer.GetRefField(node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc));
-//                     try { view.dispatch(view.state.tr.setSelection(TextSelection.create(view.state.tr.doc, getPos() + (expand ? 2 : 1)))); } catch (e) { }
-//                 }, 0);
-//             }
-//             e.stopPropagation();
-//         };
-//         //moved
-//         this._collapsed.onpointerenter = (e: any) => {
-//             DocServer.GetRefField(node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc, false));
-//             e.preventDefault();
-//             e.stopPropagation();
-//         };
-//         //moved
-//         this._collapsed.onpointerleave = (e: any) => {
-//             DocServer.GetRefField(node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowUnhighlight());
-//             e.preventDefault();
-//             e.stopPropagation();
-//         };
-
-//         (this as any).dom = this._collapsed;
-//     }
-//     //moved
-//     selectNode() { }
-// }
-
 export class DashDocView {
     _dashSpan: HTMLDivElement;
     _outer: HTMLElement;
@@ -132,10 +57,6 @@ export class DashDocView {
         this._dashSpan.style.whiteSpace = "normal";
 
         this._dashSpan.onpointerleave = () => {
-
-            console.log("DashDocView_dashSpan.onpointerleave");  // SMM
-            console.log("DashDocCommentView-id=", node.attrs.docid);  // SMM
-
             const ele = document.getElementById("DashDocCommentView-" + node.attrs.docid);
             if (ele) {
                 (ele as HTMLDivElement).style.backgroundColor = "";
@@ -143,9 +64,6 @@ export class DashDocView {
         };
 
         this._dashSpan.onpointerenter = () => {
-            console.log("DashDocView_dashSpan.onpointerenter"); // SMM
-            console.log("DashDocCommentView-id=", node.attrs.docid);  // SMM
-
             const ele = document.getElementById("DashDocCommentView-" + node.attrs.docid);
             if (ele) {
                 (ele as HTMLDivElement).style.backgroundColor = "orange";
@@ -208,7 +126,7 @@ export class DashDocView {
                 this._dashSpan.style.height = this._outer.style.height = Math.max(20, dim[1]) + "px";
                 this._outer.style.border = "1px solid " + StrCast(finalLayout.color, (Cast(Doc.UserDoc().activeWorkspace, Doc, null).darkScheme ? "dimGray" : "lightGray"));
             }, { fireImmediately: true });
-            
+
             const doReactRender = (finalLayout: Doc, resolvedDataDoc: Doc) => {
                 ReactDOM.unmountComponentAtNode(this._dashSpan);
 
diff --git a/src/client/views/nodes/formattedText/SummaryView.tsx b/src/client/views/nodes/formattedText/SummaryView.tsx
index e5328496c..922285bd0 100644
--- a/src/client/views/nodes/formattedText/SummaryView.tsx
+++ b/src/client/views/nodes/formattedText/SummaryView.tsx
@@ -1,108 +1,45 @@
-import { IReactionDisposer, observable, computed, action } from "mobx";
-import { Fragment, Node, Slice } from "prosemirror-model";
 import { TextSelection } from "prosemirror-state";
+import { Fragment, Node, Slice } from "prosemirror-model";
 import * as ReactDOM from 'react-dom';
 import React = require("react");
-// import { dom } from "@fortawesome/fontawesome-svg-core";
-// import { observer } from "mobx-react";
 
+// an elidable textblock that collapses when its '<-' is clicked and expands when its '...' anchor is clicked.
+// this node actively edits prosemirror (as opposed to just changing how things are rendered) and thus doesn't
+// really need a react view.  However, it would be cleaner to figure out how to do this just as a react rendering
+// method instead of changing prosemirror's text when the expand/elide buttons are clicked.
 export class SummaryView {
-
-    _fieldWrapper: HTMLDivElement; // container for label 
+    _fieldWrapper: HTMLSpanElement; // container for label and value
 
     constructor(node: any, view: any, getPos: any) {
-        console.log("You are here")
-        this._fieldWrapper = document.createElement("div");
-        this._fieldWrapper.style.fontWeight = "bold";
-        this._fieldWrapper.style.position = "relative";
-        this._fieldWrapper.style.display = "inline-block";
+        const self = this;
+        this._fieldWrapper = document.createElement("span");
+        this._fieldWrapper.className = this.className(node.attrs.visibility);
+        this._fieldWrapper.onpointerdown = function (e: any) { self.onPointerDown(e, node, view, getPos); }
+        this._fieldWrapper.onkeypress = function (e: any) { e.stopPropagation(); };
+        this._fieldWrapper.onkeydown = function (e: any) { e.stopPropagation(); };
+        this._fieldWrapper.onkeyup = function (e: any) { e.stopPropagation(); };
+        this._fieldWrapper.onmousedown = function (e: any) { e.stopPropagation(); };
 
         const js = node.toJSON;
-        node.toJSON = function () {
-            return js.apply(this, arguments);
-        };
+        node.toJSON = function () { return js.apply(this, arguments); };
 
-        console.log("rendering new SummaryViewInternal")
-        ReactDOM.render(<SummaryViewInternal
-            view={view}
-            getPos={getPos}
-            node={node}
-
-        />, this._fieldWrapper);
+        ReactDOM.render(<SummaryViewInternal />, this._fieldWrapper);
         (this as any).dom = this._fieldWrapper;
     }
 
+    className = (visible: boolean) => "formattedTextBox-summarizer" + (visible ? "" : "-collapsed");
+    destroy() { ReactDOM.unmountComponentAtNode(this._fieldWrapper); }
     selectNode() { }
-    deselectNode() { }
-
-    destroy() {
-        ReactDOM.unmountComponentAtNode(this._fieldWrapper);
-    }
-}
-
-interface ISummaryViewInternal {
-    node: any;
-    view: any;
-    getPos: any;
-}
-
-export class SummaryViewInternal extends React.Component<ISummaryViewInternal>{
-    _className: any;
-    _view: any;
-    _reactionDisposer: IReactionDisposer | undefined;
-
-    constructor(props: ISummaryViewInternal) {
-        super(props);
-
-        this._className = this.className(this.props.node.attrs.visibility);
-        this._view = this.props.view;
 
-        this.onPointerDownCollapsed = this.onPointerDownCollapsed.bind(this);
-        this.updateSummarizedText = this.updateSummarizedText.bind(this);
-    }
-
-    componentWillUnmount() {
-        this._reactionDisposer?.();
-    }
-
-
-    className(visible: boolean) {
-        return "formattedTextBox-summarizer" + (visible ? "" : "-collapsed");
-    }
-
-    onPointerDownCollapsed(e: any) {
-        const visible = !this.props.node.attrs.visibility;
-        const attrs = { ...this.props.node.attrs, visibility: visible };
-        let textSelection = TextSelection.create(this.props.view.state.doc, this.props.getPos() + 1);
-
-
-        if (!visible) { // update summarized text and save in attrs
-            textSelection = this.updateSummarizedText(this.props.getPos() + 1);
-            attrs.text = textSelection.content();
-            attrs.textslice = attrs.text.toJSON();
-        }
-
-        this.props.view.dispatch(this.props.view.state.tr.
-            setSelection(textSelection). // select the current summarized text (or where it will be if its collapsed)
-            replaceSelection(!visible ? new Slice(Fragment.fromArray([]), 0, 0) : this.props.node.attrs.text). // collapse/expand it
-            setNodeMarkup(this.props.getPos(), undefined, attrs)); // update the attrs
-
-        e.preventDefault();
-        e.stopPropagation();
-
-        this._className = this.className(visible);
-
-    }
-
-    updateSummarizedText(start?: any) {
-        const mtype = this.props.view.state.schema.marks.summarize;
-        const mtypeInc = this.props.view.state.schema.marks.summarizeInclusive;
+    updateSummarizedText(start: any, view: any) {
+        const mtype = view.state.schema.marks.summarize;
+        const mtypeInc = view.state.schema.marks.summarizeInclusive;
         let endPos = start;
 
         const visited = new Set();
-        for (let i: number = start + 1; i < this.props.view.state.doc.nodeSize - 1; i++) {
+        for (let i: number = start + 1; i < view.state.doc.nodeSize - 1; i++) {
             let skip = false;
-            this.props.view.state.doc.nodesBetween(start, i, (node: Node, pos: number, parent: Node, index: number) => {
+            view.state.doc.nodesBetween(start, i, (node: Node, pos: number, parent: Node, index: number) => {
                 if (node.isLeaf && !visited.has(node) && !skip) {
                     if (node.marks.find((m: any) => m.type === mtype || m.type === mtypeInc)) {
                         visited.add(node);
@@ -112,18 +49,33 @@ export class SummaryViewInternal extends React.Component<ISummaryViewInternal>{
                 }
             });
         }
-        return TextSelection.create(this.props.view.state.doc, start, endPos);
+        return TextSelection.create(view.state.doc, start, endPos);
     }
 
-    render() {
-        return (
-            <span
-                className={this._className}
-                onPointerDown={this.onPointerDownCollapsed}>
-
-            </span>
-        );
-
+    onPointerDown = (e: any, node: any, view: any, getPos: any) => {
+        const visible = !node.attrs.visibility;
+        const attrs = { ...node.attrs, visibility: visible };
+        let textSelection = TextSelection.create(view.state.doc, getPos() + 1);
+        if (!visible) { // update summarized text and save in attrs
+            textSelection = this.updateSummarizedText(getPos() + 1, view);
+            attrs.text = textSelection.content();
+            attrs.textslice = attrs.text.toJSON();
+        }
+        view.dispatch(view.state.tr.
+            setSelection(textSelection). // select the current summarized text (or where it will be if its collapsed)
+            replaceSelection(!visible ? new Slice(Fragment.fromArray([]), 0, 0) : node.attrs.text). // collapse/expand it
+            setNodeMarkup(getPos(), undefined, attrs)); // update the attrs
+        e.preventDefault();
+        e.stopPropagation();
+        this._fieldWrapper.className = this.className(visible);
     }
+}
 
+interface ISummaryView {
 }
+// currently nothing needs to be rendered for the internal view of a summary.
+export class SummaryViewInternal extends React.Component<ISummaryView> {
+    render() {
+        return <> </>;
+    }
+}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 1a03c645e5801fe0cfe71e1b1744313a41523de6 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Wed, 17 Jun 2020 20:07:44 -0400
Subject: made docFilters a prop on everything

---
 src/Utils.ts                                                     | 2 ++
 src/client/views/GestureOverlay.tsx                              | 3 ++-
 src/client/views/GlobalKeyHandler.ts                             | 4 ++--
 src/client/views/MainView.tsx                                    | 6 +++++-
 src/client/views/OverlayView.tsx                                 | 3 ++-
 src/client/views/Palette.tsx                                     | 3 ++-
 src/client/views/RecommendationsBox.tsx                          | 3 ++-
 src/client/views/TemplateMenu.tsx                                | 3 ++-
 src/client/views/collections/CollectionDockingView.tsx           | 4 ++--
 src/client/views/collections/CollectionLinearView.tsx            | 1 +
 src/client/views/collections/CollectionSchemaCells.tsx           | 3 ++-
 src/client/views/collections/CollectionSchemaView.tsx            | 1 +
 src/client/views/collections/CollectionStackingView.tsx          | 1 +
 src/client/views/collections/CollectionSubView.tsx               | 9 +++++++--
 src/client/views/collections/CollectionTreeView.tsx              | 6 ++++--
 src/client/views/collections/CollectionView.tsx                  | 3 ++-
 .../collections/collectionFreeForm/CollectionFreeFormView.tsx    | 1 +
 .../collectionMulticolumn/CollectionMulticolumnView.tsx          | 1 +
 .../collections/collectionMulticolumn/CollectionMultirowView.tsx | 1 +
 src/client/views/nodes/DocHolderBox.tsx                          | 2 ++
 src/client/views/nodes/DocumentView.tsx                          | 2 ++
 src/client/views/nodes/FieldView.tsx                             | 1 +
 src/client/views/nodes/ImageBox.tsx                              | 1 +
 src/client/views/nodes/KeyValuePair.tsx                          | 3 ++-
 src/client/views/nodes/PDFBox.tsx                                | 2 +-
 src/client/views/nodes/VideoBox.tsx                              | 1 +
 src/client/views/nodes/WebBox.tsx                                | 1 +
 src/client/views/nodes/formattedText/DashDocView.tsx             | 3 ++-
 src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx | 3 ++-
 src/client/views/nodes/formattedText/RichTextSchema.tsx          | 1 +
 src/client/views/pdf/PDFViewer.tsx                               | 1 +
 src/client/views/presentationview/PresElementBox.tsx             | 1 +
 src/client/views/search/SearchItem.tsx                           | 3 ++-
 src/mobile/MobileInterface.tsx                                   | 5 ++++-
 34 files changed, 66 insertions(+), 22 deletions(-)

(limited to 'src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx')

diff --git a/src/Utils.ts b/src/Utils.ts
index e527634fd..dba802f98 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -395,6 +395,8 @@ export function returnZero() { return 0; }
 
 export function returnEmptyString() { return ""; }
 
+export function returnEmptyFilter() { return [] as string[]; }
+
 export let emptyPath = [];
 
 export function emptyFunction() { }
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 79d407c7a..aeac1d4a9 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -8,7 +8,7 @@ import MobileInkOverlay from "../../mobile/MobileInkOverlay";
 import MobileInterface from "../../mobile/MobileInterface";
 import { GestureUtils } from "../../pen-gestures/GestureUtils";
 import { MobileInkOverlayContent } from "../../server/Message";
-import { emptyFunction, emptyPath, returnEmptyString, returnFalse, returnOne, returnTrue, returnZero } from "../../Utils";
+import { emptyFunction, emptyPath, returnEmptyString, returnFalse, returnOne, returnTrue, returnZero, returnEmptyFilter } from "../../Utils";
 import { CognitiveServices } from "../cognitive_services/CognitiveServices";
 import { DocServer } from "../DocServer";
 import { DocUtils } from "../documents/Documents";
@@ -845,6 +845,7 @@ export default class GestureOverlay extends Touchable {
                 parentActive={returnTrue}
                 whenActiveChanged={emptyFunction}
                 bringToFront={emptyFunction}
+                docFilters={returnEmptyFilter}
                 ContainingCollectionView={undefined}
                 ContainingCollectionDoc={undefined}
             />;
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index fead46301..f5adeeb00 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -267,8 +267,8 @@ export default class KeyManager {
                     const text = `__DashDocId(${pt?.[0] || 0},${pt?.[1] || 0}):` + SelectionManager.SelectedDocuments().map(dv => dv.Document[Id]).join(":");
                     SelectionManager.SelectedDocuments().length && navigator.clipboard.writeText(text);
                     stopPropagation = false;
-                    preventDefault = false;
-                } else preventDefault = false
+                }
+                preventDefault = false;
                 break;
         }
 
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 2f68004f9..4a09f9ff3 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -20,7 +20,7 @@ import { listSpec } from '../../fields/Schema';
 import { BoolCast, Cast, FieldValue, StrCast } from '../../fields/Types';
 import { TraceMobx } from '../../fields/util';
 import { CurrentUserUtils } from '../util/CurrentUserUtils';
-import { emptyFunction, emptyPath, returnFalse, returnOne, returnZero, returnTrue, Utils } from '../../Utils';
+import { emptyFunction, emptyPath, returnFalse, returnOne, returnZero, returnTrue, Utils, returnEmptyFilter } from '../../Utils';
 import GoogleAuthenticationManager from '../apis/GoogleAuthenticationManager';
 import { DocServer } from '../DocServer';
 import { Docs, DocumentOptions } from '../documents/Documents';
@@ -310,6 +310,7 @@ export class MainView extends React.Component {
             parentActive={returnTrue}
             whenActiveChanged={emptyFunction}
             bringToFront={emptyFunction}
+            docFilters={returnEmptyFilter}
             ContainingCollectionView={undefined}
             ContainingCollectionDoc={undefined}
         />;
@@ -412,6 +413,7 @@ export class MainView extends React.Component {
                     parentActive={returnTrue}
                     whenActiveChanged={emptyFunction}
                     bringToFront={emptyFunction}
+                    docFilters={returnEmptyFilter}
                     ContainingCollectionView={undefined}
                     ContainingCollectionDoc={undefined} />
             </div>
@@ -438,6 +440,7 @@ export class MainView extends React.Component {
                     parentActive={returnTrue}
                     whenActiveChanged={emptyFunction}
                     bringToFront={emptyFunction}
+                    docFilters={returnEmptyFilter}
                     ContainingCollectionView={undefined}
                     ContainingCollectionDoc={undefined} />
                 <button className="mainView-settings" key="settings" onClick={() => SettingsManager.Instance.open()}>
@@ -529,6 +532,7 @@ export class MainView extends React.Component {
                     renderDepth={0}
                     focus={emptyFunction}
                     whenActiveChanged={emptyFunction}
+                    docFilters={returnEmptyFilter}
                     ContainingCollectionView={undefined}
                     ContainingCollectionDoc={undefined} />
             </div>;
diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx
index f6e5e1705..37d8dd23b 100644
--- a/src/client/views/OverlayView.tsx
+++ b/src/client/views/OverlayView.tsx
@@ -4,7 +4,7 @@ import * as React from "react";
 import { Doc, DocListCast, Opt } from "../../fields/Doc";
 import { Id } from "../../fields/FieldSymbols";
 import { NumCast, Cast } from "../../fields/Types";
-import { emptyFunction, emptyPath, returnEmptyString, returnFalse, returnOne, returnTrue, returnZero, Utils, setupMoveUpEvents } from "../../Utils";
+import { emptyFunction, emptyPath, returnEmptyString, returnFalse, returnOne, returnTrue, returnZero, Utils, setupMoveUpEvents, returnEmptyFilter } from "../../Utils";
 import { Transform } from "../util/Transform";
 import { CollectionFreeFormLinksView } from "./collections/collectionFreeForm/CollectionFreeFormLinksView";
 import { DocumentView } from "./nodes/DocumentView";
@@ -202,6 +202,7 @@ export class OverlayView extends React.Component {
                     backgroundColor={returnEmptyString}
                     addDocTab={returnFalse}
                     pinToPres={emptyFunction}
+                    docFilters={returnEmptyFilter}
                     ContainingCollectionView={undefined}
                     ContainingCollectionDoc={undefined} />
             </div>;
diff --git a/src/client/views/Palette.tsx b/src/client/views/Palette.tsx
index 108eb83d6..0a4334302 100644
--- a/src/client/views/Palette.tsx
+++ b/src/client/views/Palette.tsx
@@ -3,7 +3,7 @@ import { observer } from "mobx-react";
 import * as React from "react";
 import { Doc } from "../../fields/Doc";
 import { NumCast } from "../../fields/Types";
-import { emptyFunction, emptyPath, returnEmptyString, returnZero, returnFalse, returnOne, returnTrue } from "../../Utils";
+import { emptyFunction, emptyPath, returnEmptyString, returnZero, returnFalse, returnOne, returnTrue, returnEmptyFilter } from "../../Utils";
 import { Transform } from "../util/Transform";
 import { DocumentView } from "./nodes/DocumentView";
 import "./Palette.scss";
@@ -59,6 +59,7 @@ export default class Palette extends React.Component<PaletteProps> {
                             parentActive={returnTrue}
                             whenActiveChanged={emptyFunction}
                             bringToFront={emptyFunction}
+                            docFilters={returnEmptyFilter}
                             ContainingCollectionView={undefined}
                             ContainingCollectionDoc={undefined} />
                         <div className="palette-cover" style={{ transform: `translate(${Math.max(0, this._selectedIndex) * 50.75 + 23}px, 0px)` }}></div>
diff --git a/src/client/views/RecommendationsBox.tsx b/src/client/views/RecommendationsBox.tsx
index c98363214..cdde32c21 100644
--- a/src/client/views/RecommendationsBox.tsx
+++ b/src/client/views/RecommendationsBox.tsx
@@ -6,7 +6,7 @@ import "./RecommendationsBox.scss";
 import { Doc, DocListCast, WidthSym, HeightSym } from "../../fields/Doc";
 import { DocumentIcon } from "./nodes/DocumentIcon";
 import { StrCast, NumCast } from "../../fields/Types";
-import { returnFalse, emptyFunction, returnEmptyString, returnOne, emptyPath, returnZero } from "../../Utils";
+import { returnFalse, emptyFunction, returnEmptyString, returnOne, emptyPath, returnZero, returnEmptyFilter } from "../../Utils";
 import { Transform } from "../util/Transform";
 import { ObjectField } from "../../fields/ObjectField";
 import { DocumentView } from "./nodes/DocumentView";
@@ -82,6 +82,7 @@ export class RecommendationsBox extends React.Component<FieldViewProps> {
                 parentActive={returnFalse}
                 whenActiveChanged={returnFalse}
                 bringToFront={emptyFunction}
+                docFilters={returnEmptyFilter}
                 ContainingCollectionView={undefined}
                 ContainingCollectionDoc={undefined}
                 ContentScaling={scale}
diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx
index f135823a8..916e631d0 100644
--- a/src/client/views/TemplateMenu.tsx
+++ b/src/client/views/TemplateMenu.tsx
@@ -10,7 +10,7 @@ import { Doc, DocListCast } from "../../fields/Doc";
 import { Docs, DocUtils, } from "../documents/Documents";
 import { StrCast, Cast } from "../../fields/Types";
 import { CollectionTreeView } from "./collections/CollectionTreeView";
-import { returnTrue, emptyFunction, returnFalse, returnOne, emptyPath, returnZero } from "../../Utils";
+import { returnTrue, emptyFunction, returnFalse, returnOne, emptyPath, returnZero, returnEmptyFilter } from "../../Utils";
 import { Transform } from "../util/Transform";
 import { ScriptField, ComputedField } from "../../fields/ScriptField";
 import { Scripting } from "../util/Scripting";
@@ -140,6 +140,7 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
                 CollectionView={undefined}
                 ContainingCollectionDoc={undefined}
                 ContainingCollectionView={undefined}
+                docFilters={returnEmptyFilter}
                 rootSelected={returnFalse}
                 onCheckedClick={this.scriptField!}
                 onChildClick={this.scriptField!}
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 1c0b60b2b..a969e302d 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -8,11 +8,10 @@ import * as GoldenLayout from "../../../client/goldenLayout";
 import { DateField } from '../../../fields/DateField';
 import { Doc, DocListCast, Field, Opt, DataSym } from "../../../fields/Doc";
 import { Id } from '../../../fields/FieldSymbols';
-import { List } from '../../../fields/List';
 import { FieldId } from "../../../fields/RefField";
 import { Cast, NumCast, StrCast } from "../../../fields/Types";
 import { TraceMobx } from '../../../fields/util';
-import { emptyFunction, returnOne, returnTrue, Utils, returnZero } from "../../../Utils";
+import { emptyFunction, returnOne, returnTrue, Utils, returnZero, returnEmptyFilter } from "../../../Utils";
 import { DocServer } from "../../DocServer";
 import { Docs } from '../../documents/Documents';
 import { DocumentManager } from '../../util/DocumentManager';
@@ -843,6 +842,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
             backgroundColor={CollectionDockingView.Instance.props.backgroundColor}
             addDocTab={this.addDocTab}
             pinToPres={DockedFrameRenderer.PinDoc}
+            docFilters={returnEmptyFilter}
             ContainingCollectionView={undefined}
             ContainingCollectionDoc={undefined} />;
     }
diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx
index f1002044a..f38eeaf41 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/CollectionLinearView.tsx
@@ -124,6 +124,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
                                 parentActive={returnTrue}
                                 whenActiveChanged={emptyFunction}
                                 bringToFront={emptyFunction}
+                                docFilters={this.props.docFilters}
                                 ContainingCollectionView={undefined}
                                 ContainingCollectionDoc={undefined} />
                         </div>;
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index baf9d4156..2b8110e27 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -3,7 +3,7 @@ import { action, observable, trace } from "mobx";
 import { observer } from "mobx-react";
 import { CellInfo } from "react-table";
 import "react-table/react-table.css";
-import { emptyFunction, returnFalse, returnZero, returnOne } from "../../../Utils";
+import { emptyFunction, returnFalse, returnZero, returnOne, returnEmptyFilter } from "../../../Utils";
 import { Doc, DocListCast, Field, Opt } from "../../../fields/Doc";
 import { Id } from "../../../fields/FieldSymbols";
 import { KeyCodes } from "../../util/KeyCodes";
@@ -159,6 +159,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
             bringToFront: emptyFunction,
             rootSelected: returnFalse,
             fieldKey: this.props.rowProps.column.id as string,
+            docFilters: returnEmptyFilter,
             ContainingCollectionView: this.props.CollectionView,
             ContainingCollectionDoc: this.props.CollectionView && this.props.CollectionView.props.Document,
             isSelected: returnFalse,
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 6dbee217a..56a2a517c 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -133,6 +133,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
                     PanelWidth={this.previewWidth}
                     PanelHeight={this.previewHeight}
                     ScreenToLocalTransform={this.getPreviewTransform}
+                    docFilters={this.docFilters}
                     ContainingCollectionDoc={this.props.CollectionView?.props.Document}
                     ContainingCollectionView={this.props.CollectionView}
                     moveDocument={this.props.moveDocument}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 9289c4cf6..4aab43b08 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -217,6 +217,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument)
             ScreenToLocalTransform={dxf}
             opacity={opacity}
             focus={this.focusDocument}
+            docFilters={this.docFilters}
             ContainingCollectionDoc={this.props.CollectionView?.props.Document}
             ContainingCollectionView={this.props.CollectionView}
             addDocument={this.props.addDocument}
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 93d20c475..00d6d59c8 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -10,7 +10,7 @@ import { WebField } from "../../../fields/URLField";
 import { Cast, ScriptCast, NumCast } from "../../../fields/Types";
 import { GestureUtils } from "../../../pen-gestures/GestureUtils";
 import { Upload } from "../../../server/SharedMediaTypes";
-import { Utils, returnFalse } from "../../../Utils";
+import { Utils, returnFalse, returnEmptyFilter } from "../../../Utils";
 import { DocServer } from "../../DocServer";
 import { Networking } from "../../Network";
 import { ImageUtils } from "../../util/Import & Export/ImageUtils";
@@ -101,8 +101,13 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
         get childDocList() {
             return Cast(this.dataField, listSpec(Doc));
         }
+        docFilters = () => {
+            return this.props.ignoreFields?.includes("_docFilters") ? [] :
+                this.props.docFilters !== returnEmptyFilter ? this.props.docFilters() :
+                    Cast(this.props.Document._docFilters, listSpec("string"), []);
+        }
         @computed get childDocs() {
-            const docFilters = this.props.ignoreFields?.includes("_docFilters") ? [] : Cast(this.props.Document._docFilters, listSpec("string"), []);
+            const docFilters = this.docFilters();
             const docRangeFilters = this.props.ignoreFields?.includes("_docRangeFilters") ? [] : Cast(this.props.Document._docRangeFilters, listSpec("string"), []);
             const filterFacets: { [key: string]: { [value: string]: string } } = {};  // maps each filter key to an object with value=>modifier fields
             for (let i = 0; i < docFilters.length; i += 3) {
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index d75aed0cd..747eb36a1 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -8,7 +8,7 @@ import { PrefetchProxy } from '../../../fields/Proxy';
 import { Document, listSpec } from '../../../fields/Schema';
 import { ComputedField, ScriptField } from '../../../fields/ScriptField';
 import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
-import { emptyFunction, emptyPath, returnFalse, returnOne, returnTrue, returnZero, simulateMouseClick, Utils } from '../../../Utils';
+import { emptyFunction, emptyPath, returnFalse, returnOne, returnTrue, returnZero, simulateMouseClick, Utils, returnEmptyFilter } from '../../../Utils';
 import { Docs, DocUtils } from '../../documents/Documents';
 import { DocumentType } from "../../documents/DocumentTypes";
 import { DocumentManager } from '../../util/DocumentManager';
@@ -355,6 +355,7 @@ class TreeView extends React.Component<TreeViewProps> {
                     PanelHeight={panelHeight}
                     focus={returnFalse}
                     ScreenToLocalTransform={this.docTransform}
+                    docFilters={returnEmptyFilter}
                     ContainingCollectionDoc={this.props.containingCollection}
                     ContainingCollectionView={undefined}
                     addDocument={returnFalse}
@@ -472,6 +473,7 @@ class TreeView extends React.Component<TreeViewProps> {
                         whenActiveChanged={emptyFunction}
                         bringToFront={emptyFunction}
                         dontRegisterView={BoolCast(this.props.treeViewId.dontRegisterChildViews)}
+                        docFilters={returnEmptyFilter}
                         ContainingCollectionView={undefined}
                         ContainingCollectionDoc={this.props.containingCollection}
                     />}
@@ -490,7 +492,7 @@ class TreeView extends React.Component<TreeViewProps> {
                 <div className="treeViewItem-header" ref={this._header} onClick={e => {
                     if (this.props.active(true)) {
                         e.stopPropagation();
-                        e.preventDefault()
+                        e.preventDefault();
                         SelectionManager.DeselectAll();
                     }
                 }}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 2f38fb4b4..33615cc68 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -17,7 +17,7 @@ import { ComputedField, ScriptField } from '../../../fields/ScriptField';
 import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
 import { ImageField } from '../../../fields/URLField';
 import { TraceMobx } from '../../../fields/util';
-import { emptyFunction, emptyPath, returnFalse, returnOne, returnZero, setupMoveUpEvents, Utils } from '../../../Utils';
+import { emptyFunction, emptyPath, returnFalse, returnOne, returnZero, setupMoveUpEvents, Utils, returnEmptyFilter } from '../../../Utils';
 import { Docs } from '../../documents/Documents';
 import { DocumentType } from '../../documents/DocumentTypes';
 import { CurrentUserUtils } from '../../util/CurrentUserUtils';
@@ -467,6 +467,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
                         DataDoc={facetCollection}
                         fieldKey={`${this.props.fieldKey}-filter`}
                         CollectionView={this}
+                        docFilters={returnEmptyFilter}
                         ContainingCollectionDoc={this.props.ContainingCollectionDoc}
                         ContainingCollectionView={this.props.ContainingCollectionView}
                         PanelWidth={this.facetWidth}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 571b5bf5c..00260745d 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -958,6 +958,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
             ContentScaling: returnOne,
             ContainingCollectionView: this.props.CollectionView,
             ContainingCollectionDoc: this.props.Document,
+            docFilters: this.docFilters,
             focus: this.focusDocument,
             backgroundColor: this.getClusterColor,
             backgroundHalo: this.backgroundHalo,
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
index c0e1a0232..776266ce6 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
@@ -234,6 +234,7 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu
             onDoubleClick={this.onChildDoubleClickHandler}
             ScreenToLocalTransform={dxf}
             focus={this.props.focus}
+            docFilters={this.docFilters}
             ContainingCollectionDoc={this.props.CollectionView?.props.Document}
             ContainingCollectionView={this.props.CollectionView}
             addDocument={this.props.addDocument}
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
index 602246d07..1703ff4dc 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
@@ -233,6 +233,7 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument)
             onDoubleClick={this.onChildDoubleClickHandler}
             ScreenToLocalTransform={dxf}
             focus={this.props.focus}
+            docFilters={this.docFilters}
             ContainingCollectionDoc={this.props.CollectionView?.props.Document}
             ContainingCollectionView={this.props.CollectionView}
             addDocument={this.props.addDocument}
diff --git a/src/client/views/nodes/DocHolderBox.tsx b/src/client/views/nodes/DocHolderBox.tsx
index a4c4663dd..0cf5505cc 100644
--- a/src/client/views/nodes/DocHolderBox.tsx
+++ b/src/client/views/nodes/DocHolderBox.tsx
@@ -119,6 +119,7 @@ export class DocHolderBox extends ViewBoxAnnotatableComponent<FieldViewProps, Do
                     Document={containedDoc}
                     DataDoc={undefined}
                     LibraryPath={emptyPath}
+                    docFilters={this.props.docFilters}
                     ContainingCollectionView={this as any} // bcz: hack!  need to pass a prop that can be used to select the container (ie, 'this') when the up selector in document decorations is clicked.  currently, the up selector allows only a containing collection to be selected
                     ContainingCollectionDoc={undefined}
                     fitToBox={true}
@@ -147,6 +148,7 @@ export class DocHolderBox extends ViewBoxAnnotatableComponent<FieldViewProps, Do
                     Document={containedDoc}
                     DataDoc={undefined}
                     LibraryPath={emptyPath}
+                    docFilters={this.props.docFilters}
                     ContainingCollectionView={this as any} // bcz: hack!  need to pass a prop that can be used to select the container (ie, 'this') when the up selector in document decorations is clicked.  currently, the up selector allows only a containing collection to be selected
                     ContainingCollectionDoc={undefined}
                     fitToBox={true}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index ffadc6edf..3205e3050 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -51,6 +51,7 @@ export type DocFocusFunc = () => boolean;
 export interface DocumentViewProps {
     ContainingCollectionView: Opt<CollectionView>;
     ContainingCollectionDoc: Opt<Doc>;
+    docFilters: () => string[];
     FreezeDimensions?: boolean;
     NativeWidth: () => number;
     NativeHeight: () => number;
@@ -996,6 +997,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         TraceMobx();
         return (<>
             <DocumentContentsView key={1}
+                docFilters={this.props.docFilters}
                 ContainingCollectionView={this.props.ContainingCollectionView}
                 ContainingCollectionDoc={this.props.ContainingCollectionDoc}
                 NativeWidth={this.NativeWidth}
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index e9dc43bd8..305c04a90 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -27,6 +27,7 @@ export interface FieldViewProps {
     LibraryPath: Doc[];
     onClick?: ScriptField;
     dropAction: dropActionType;
+    docFilters: () => string[];
     isSelected: (outsideReaction?: boolean) => boolean;
     select: (isCtrlPressed: boolean) => void;
     rootSelected: (outsideReaction?: boolean) => boolean;
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 69cffb6c2..84d49681c 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -473,6 +473,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD
                 CollectionView={undefined}
                 ScreenToLocalTransform={this.screenToLocalTransform}
                 renderDepth={this.props.renderDepth + 1}
+                docFilters={this.props.docFilters}
                 ContainingCollectionDoc={this.props.ContainingCollectionDoc}>
                 {this.contentFunc}
             </CollectionFreeFormView>
diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx
index 3cbe3e494..4568a6b16 100644
--- a/src/client/views/nodes/KeyValuePair.tsx
+++ b/src/client/views/nodes/KeyValuePair.tsx
@@ -1,7 +1,7 @@
 import { action, observable } from 'mobx';
 import { observer } from "mobx-react";
 import { Doc, Field, Opt } from '../../../fields/Doc';
-import { emptyFunction, returnFalse, returnOne, returnZero } from '../../../Utils';
+import { emptyFunction, returnFalse, returnOne, returnZero, returnEmptyFilter } from '../../../Utils';
 import { Docs } from '../../documents/Documents';
 import { Transform } from '../../util/Transform';
 import { undoBatch } from '../../util/UndoManager';
@@ -56,6 +56,7 @@ export class KeyValuePair extends React.Component<KeyValuePairProps> {
             Document: this.props.doc,
             DataDoc: this.props.doc,
             LibraryPath: [],
+            docFilters:returnEmptyFilter,
             ContainingCollectionView: undefined,
             ContainingCollectionDoc: undefined,
             fieldKey: this.props.keyName,
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index fae216f17..aabaac39e 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -234,7 +234,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
             <PDFViewer {...this.props} pdf={this._pdf!} url={pdfUrl!.url.pathname} active={this.props.active} loaded={this.loaded}
                 setPdfViewer={this.setPdfViewer} ContainingCollectionView={this.props.ContainingCollectionView}
                 renderDepth={this.props.renderDepth} PanelHeight={this.props.PanelHeight} PanelWidth={this.props.PanelWidth}
-                addDocTab={this.props.addDocTab} focus={this.props.focus}
+                addDocTab={this.props.addDocTab} focus={this.props.focus} docFilters={this.props.docFilters}
                 pinToPres={this.props.pinToPres} addDocument={this.addDocument}
                 Document={this.props.Document} DataDoc={this.dataDoc} ContentScaling={this.props.ContentScaling}
                 ScreenToLocalTransform={this.props.ScreenToLocalTransform} select={this.props.select}
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index e4dbceca6..71556bfd3 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -383,6 +383,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
                     CollectionView={undefined}
                     ScreenToLocalTransform={this.props.ScreenToLocalTransform}
                     renderDepth={this.props.renderDepth + 1}
+                    docFilters={this.props.docFilters}
                     ContainingCollectionDoc={this.props.ContainingCollectionDoc}>
                     {this.contentFunc}
                 </CollectionFreeFormView>
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index fb9e57b51..b726a6df9 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -488,6 +488,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
                         CollectionView={undefined}
                         ScreenToLocalTransform={this.scrollXf}
                         renderDepth={this.props.renderDepth + 1}
+                        docFilters={this.props.docFilters}
                         ContainingCollectionDoc={this.props.ContainingCollectionDoc}>
                     </CollectionFreeFormView>
                 </div>
diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx
index 55b3f6f1e..5c3f3dcc9 100644
--- a/src/client/views/nodes/formattedText/DashDocView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocView.tsx
@@ -5,7 +5,7 @@ import { Id } from "../../../../fields/FieldSymbols";
 import { ObjectField } from "../../../../fields/ObjectField";
 import { ComputedField } from "../../../../fields/ScriptField";
 import { BoolCast, Cast, NumCast, StrCast } from "../../../../fields/Types";
-import { emptyFunction, returnEmptyString, returnFalse, Utils, returnZero } from "../../../../Utils";
+import { emptyFunction, returnEmptyString, returnFalse, Utils, returnZero, returnEmptyFilter } from "../../../../Utils";
 import { DocServer } from "../../../DocServer";
 import { Docs, DocUtils } from "../../../documents/Documents";
 import { DocumentView } from "../DocumentView";
@@ -254,6 +254,7 @@ export class DashDocView extends React.Component<IDashDocView> {
                             whenActiveChanged={returnFalse}
                             bringToFront={emptyFunction}
                             dontRegisterView={false}
+                            docFilters={this.props.tbox?.props.docFilters||returnEmptyFilter}
                             ContainingCollectionView={this._textBox.props.ContainingCollectionView}
                             ContainingCollectionDoc={this._textBox.props.ContainingCollectionDoc}
                             ContentScaling={this.contentScaling}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index 000b3c2e5..7c697033c 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -4,7 +4,7 @@ import { EditorView } from "prosemirror-view";
 import * as ReactDOM from 'react-dom';
 import { Doc, DocCastAsync } from "../../../../fields/Doc";
 import { Cast, FieldValue, NumCast } from "../../../../fields/Types";
-import { emptyFunction, returnEmptyString, returnFalse, Utils, emptyPath, returnZero, returnOne } from "../../../../Utils";
+import { emptyFunction, returnEmptyString, returnFalse, Utils, emptyPath, returnZero, returnOne, returnEmptyFilter } from "../../../../Utils";
 import { DocServer } from "../../../DocServer";
 import { DocumentManager } from "../../../util/DocumentManager";
 import { schema } from "./schema_rts";
@@ -222,6 +222,7 @@ export class FormattedTextBoxComment {
                                     addDocTab={returnFalse}
                                     pinToPres={returnFalse}
                                     dontRegisterView={true}
+                                    docFilters={returnEmptyFilter}
                                     ContainingCollectionDoc={undefined}
                                     ContainingCollectionView={undefined}
                                     renderDepth={1}
diff --git a/src/client/views/nodes/formattedText/RichTextSchema.tsx b/src/client/views/nodes/formattedText/RichTextSchema.tsx
index 05557e22a..a989abd6a 100644
--- a/src/client/views/nodes/formattedText/RichTextSchema.tsx
+++ b/src/client/views/nodes/formattedText/RichTextSchema.tsx
@@ -152,6 +152,7 @@ export class DashDocView {
                     whenActiveChanged={returnFalse}
                     bringToFront={emptyFunction}
                     dontRegisterView={false}
+                    docFilters={this._textBox.props.docFilters}
                     ContainingCollectionView={this._textBox.props.ContainingCollectionView}
                     ContainingCollectionDoc={this._textBox.props.ContainingCollectionDoc}
                     ContentScaling={this.contentScaling}
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index c02dd6786..516774f44 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -51,6 +51,7 @@ interface IViewerProps {
     fieldKey: string;
     Document: Doc;
     DataDoc?: Doc;
+    docFilters: () => string[];
     ContainingCollectionView: Opt<CollectionView>;
     PanelWidth: () => number;
     PanelHeight: () => number;
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index caee06d8f..6b59a0563 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -194,6 +194,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                     whenActiveChanged={returnFalse}
                     bringToFront={returnFalse}
                     opacity={returnOne}
+                    docFilters={this.props.docFilters}
                     ContainingCollectionView={undefined}
                     ContainingCollectionDoc={undefined}
                     ContentScaling={returnOne}
diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx
index 24d6e9d6f..74262d81a 100644
--- a/src/client/views/search/SearchItem.tsx
+++ b/src/client/views/search/SearchItem.tsx
@@ -7,7 +7,7 @@ import { observer } from "mobx-react";
 import { Doc } from "../../../fields/Doc";
 import { Id } from "../../../fields/FieldSymbols";
 import { Cast, NumCast, StrCast } from "../../../fields/Types";
-import { emptyFunction, emptyPath, returnFalse, Utils, returnTrue, returnOne, returnZero } from "../../../Utils";
+import { emptyFunction, emptyPath, returnFalse, Utils, returnTrue, returnOne, returnZero, returnEmptyString, returnEmptyFilter } from "../../../Utils";
 import { DocumentType } from "../../documents/DocumentTypes";
 import { DocumentManager } from "../../util/DocumentManager";
 import { DragManager, SetupDrag } from "../../util/DragManager";
@@ -164,6 +164,7 @@ export class SearchItem extends React.Component<SearchItemProps> {
                     removeDocument={returnFalse}
                     addDocTab={returnFalse}
                     pinToPres={returnFalse}
+                    docFilters={returnEmptyFilter}
                     ContainingCollectionDoc={undefined}
                     ContainingCollectionView={undefined}
                     ScreenToLocalTransform={Transform.Identity}
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index da14ffc88..a50ec103e 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -22,7 +22,7 @@ import { listSpec } from '../fields/Schema';
 import { Cast, FieldValue } from '../fields/Types';
 import { WebField } from "../fields/URLField";
 import { CurrentUserUtils } from '../client/util/CurrentUserUtils';
-import { emptyFunction, emptyPath, returnEmptyString, returnFalse, returnOne, returnTrue, returnZero } from '../Utils';
+import { emptyFunction, emptyPath, returnEmptyString, returnFalse, returnOne, returnTrue, returnZero, returnEmptyFilter } from '../Utils';
 import "./MobileInterface.scss";
 import { CollectionView } from '../client/views/collections/CollectionView';
 import { InkingStroke } from '../client/views/InkingStroke';
@@ -126,6 +126,7 @@ export default class MobileInterface extends React.Component {
                 parentActive={returnTrue}
                 whenActiveChanged={emptyFunction}
                 bringToFront={emptyFunction}
+                docFilters={returnEmptyFilter}
                 ContainingCollectionView={undefined}
                 ContainingCollectionDoc={undefined} />;
         }
@@ -205,6 +206,7 @@ export default class MobileInterface extends React.Component {
                         whenActiveChanged={returnFalse}
                         ScreenToLocalTransform={Transform.Identity}
                         renderDepth={0}
+                        docFilters={returnEmptyFilter}
                         ContainingCollectionView={undefined}
                         ContainingCollectionDoc={undefined}
                         rootSelected={returnTrue}>
@@ -293,6 +295,7 @@ export default class MobileInterface extends React.Component {
                         parentActive={returnTrue}
                         whenActiveChanged={emptyFunction}
                         bringToFront={emptyFunction}
+                        docFilters={returnEmptyFilter}
                         ContainingCollectionView={undefined}
                         ContainingCollectionDoc={undefined} />
                 </div>
-- 
cgit v1.2.3-70-g09d2


From c8bec95f09273c9e1f71f454bb0430247a619252 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Fri, 19 Jun 2020 08:24:05 -0400
Subject: fixed LOD for pdfs.  fixed linking to collection annotation on
 pdf/image etc to not create text box.  fixed textbox popup to display
 contents at renderDepth 0 so that PDFs will display

---
 .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx     | 2 +-
 src/client/views/nodes/PDFBox.tsx                                       | 2 +-
 src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx        | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

(limited to 'src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx')

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index c0c88d540..d9d5c1bb3 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -239,7 +239,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
     @undoBatch
     @action
     internalLinkDrop(e: Event, de: DragManager.DropEvent, linkDragData: DragManager.LinkDragData, xp: number, yp: number) {
-        if (linkDragData.linkSourceDocument === this.props.Document) return false;
+        if (linkDragData.linkSourceDocument === this.props.Document || this.props.Document.annotationOn) return false;
         const source = Docs.Create.TextDocument("", { _width: 200, _height: 75, x: xp, y: yp, title: "dropped annotation" });
         this.props.addDocument(source);
         linkDragData.linkDocument = DocUtils.MakeLink({ doc: source }, { doc: linkDragData.linkSourceDocument }, "doc annotation"); // TODODO this is where in text links get passed
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 3f6fc07a1..985fb4363 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -252,7 +252,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
     _pdfjsRequested = false;
     render() {
         const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField, null);
-        if (this.props.isSelected() || this.props.renderDepth <= 1 || this.props.Document._scrollY !== undefined) this._everActive = true;
+        if (this.props.isSelected() || this.props.renderDepth === 0 || this.props.Document._scrollY !== undefined) this._everActive = true;
         if (pdfUrl && (this._everActive || this.props.Document._scrollTop || (this.dataDoc[this.props.fieldKey + "-nativeWidth"] && this.props.ScreenToLocalTransform().Scale < 2.5))) {
             if (pdfUrl instanceof PdfField && this._pdf) {
                 return this.renderPdfView;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index 7c697033c..0d8e22251 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -225,7 +225,7 @@ export class FormattedTextBoxComment {
                                     docFilters={returnEmptyFilter}
                                     ContainingCollectionDoc={undefined}
                                     ContainingCollectionView={undefined}
-                                    renderDepth={1}
+                                    renderDepth={0}
                                     PanelWidth={() => Math.min(350, NumCast(target._width, 350))}
                                     PanelHeight={() => Math.min(250, NumCast(target._height, 250))}
                                     focus={emptyFunction}
-- 
cgit v1.2.3-70-g09d2

