From 8a1267faf796b2e2a30a6ba9f86879854e9ee983 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 11 Apr 2023 13:51:44 -0400
Subject: removed arrangeItems context button for collections to make it a
 funciton on drop instead of a reaction.  Converted isLinkButton to be an
 onClick script.  got rid of unused PARAMS field on templates.   fixed
 PresElementBox rendering of embedded docs.

---
 src/client/views/nodes/VideoBox.tsx | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

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

diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index e14ad4b05..83ad5628c 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -33,6 +33,7 @@ import { FieldView, FieldViewProps } from './FieldView';
 import { RecordingBox } from './RecordingBox';
 import { PinProps, PresBox } from './trails';
 import './VideoBox.scss';
+import { ScriptField } from '../../../fields/ScriptField';
 const path = require('path');
 
 /**
@@ -324,7 +325,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
                 _width: 150,
                 _height: 50,
                 title: (this.layoutDoc._currentTimecode || 0).toString(),
-                _isLinkButton: true,
+                onClick: ScriptField.MakeScript('followLink(this,altKey)', { altKey: 'boolean' }),
             });
             this.props.addDocument?.(b);
             DocUtils.MakeLink(b, this.rootDoc, { linkRelationship: 'video snapshot' });
@@ -368,7 +369,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
             _nativeHeight: Doc.NativeHeight(this.layoutDoc),
             x: NumCast(this.layoutDoc.x) + width,
             y: NumCast(this.layoutDoc.y),
-            _isLinkButton: true,
+            onClick: ScriptField.MakeScript('followLink(this,altKey)', { altKey: 'boolean' }),
             _width: 150,
             _height: (height / width) * 150,
             title: '--snapshot' + NumCast(this.layoutDoc._currentTimecode) + ' image-',
@@ -1010,7 +1011,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
         cropping._height = anchh * (this.props.NativeDimScaling?.() || 1);
         cropping.timecodeToHide = undefined;
         cropping.timecodeToShow = undefined;
-        cropping.isLinkButton = undefined;
+        cropping.onClick = undefined;
         const croppingProto = Doc.GetProto(cropping);
         croppingProto.annotationOn = undefined;
         croppingProto.isPrototype = true;
-- 
cgit v1.2.3-70-g09d2


From 5d1e3710a015d8915bd367ece753817d84d9d916 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 11 Apr 2023 14:43:54 -0400
Subject: exracted FollowLinkScript() function.  got rid of template parameters
 to simplify templating.

---
 src/client/documents/Documents.ts                  |  5 +--
 src/client/util/CurrentUserUtils.ts                |  3 +-
 src/client/util/LinkFollower.ts                    | 22 ++++++++----
 src/client/views/DocumentButtonBar.tsx             | 13 ++++---
 src/client/views/DocumentDecorations.tsx           |  6 ++--
 src/client/views/MarqueeAnnotator.tsx              |  3 +-
 src/client/views/PropertiesButtons.tsx             |  5 +--
 src/client/views/StyleProvider.tsx                 | 12 +++----
 .../collections/CollectionStackedTimeline.tsx      |  6 ++--
 src/client/views/nodes/DocumentContentsView.tsx    |  2 +-
 src/client/views/nodes/DocumentView.tsx            |  8 ++---
 src/client/views/nodes/VideoBox.tsx                |  5 +--
 .../views/nodes/formattedText/DashDocView.tsx      |  2 +-
 .../views/nodes/formattedText/FormattedTextBox.tsx |  3 +-
 src/fields/Doc.ts                                  | 41 +++++++---------------
 15 files changed, 65 insertions(+), 71 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 7600fcac9..8d97ce5af 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -21,6 +21,7 @@ import { Networking } from '../Network';
 import { DocumentManager } from '../util/DocumentManager';
 import { DragManager, dropActionType } from '../util/DragManager';
 import { DirectoryImportBox } from '../util/Import & Export/DirectoryImportBox';
+import { FollowLinkScript } from '../util/LinkFollower';
 import { LinkManager } from '../util/LinkManager';
 import { ScriptingGlobals } from '../util/ScriptingGlobals';
 import { undoBatch, UndoManager } from '../util/UndoManager';
@@ -507,7 +508,7 @@ export namespace Docs {
                     layout: { view: LinkBox, dataField: defaultDataKey },
                     options: {
                         childDontRegisterViews: true,
-                        onClick: ScriptField.MakeScript('followLink(this,altKey)', { altKey: 'boolean' }),
+                        onClick: FollowLinkScript(),
                         hideLinkAnchors: true,
                         _height: 150,
                         description: '',
@@ -1694,7 +1695,7 @@ export namespace DocUtils {
                 _width: 15,
                 _height: 15,
                 _xPadding: 0,
-                onClick: ScriptField.MakeScript('followLink(this,altKey)', { altKey: 'boolean' }),
+                onClick: FollowLinkScript(),
                 _timecodeToShow: Cast(doc._timecodeToShow, 'number', null),
             });
             Doc.AddDocToList(context, annotationField, pushpin);
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 3d0db04b4..76ea3e3ea 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -25,6 +25,7 @@ import { OpenWhere } from "../views/nodes/DocumentView";
 import { OverlayView } from "../views/OverlayView";
 import { DragManager } from "./DragManager";
 import { MakeTemplate } from "./DropConverter";
+import { FollowLinkScript } from "./LinkFollower";
 import { LinkManager } from "./LinkManager";
 import { ScriptingGlobals } from "./ScriptingGlobals";
 import { ColorScheme } from "./SettingsManager";
@@ -271,7 +272,7 @@ export class CurrentUserUtils {
             {key: "Map",        creator: opts => Docs.Create.MapDocument([], opts),         opts: { _width: 800, _height: 600, _fitWidth: true, _showSidebar: true,  }},
             {key: "Screengrab", creator: Docs.Create.ScreenshotDocument,                    opts: { _width: 400, _height: 200 }},
             {key: "WebCam",     creator: opts => Docs.Create.WebCamDocument("", opts),      opts: { _width: 400, _height: 200, recording:true, system: true, cloneFieldFilter: new List<string>(["system"]) }},
-            {key: "Button",     creator: Docs.Create.ButtonDocument,                        opts: { _width: 150, _height: 50, _xPadding: 10, _yPadding: 10, onClick: ScriptField.MakeScript("followLink(this,altKey)", {altKey:"boolean"}) }},
+            {key: "Button",     creator: Docs.Create.ButtonDocument,                        opts: { _width: 150, _height: 50, _xPadding: 10, _yPadding: 10, onClick: FollowLinkScript()}},
             {key: "Script",     creator: opts => Docs.Create.ScriptingDocument(null, opts), opts: { _width: 200, _height: 250, }},
             {key: "DataViz",    creator: opts => Docs.Create.DataVizDocument("/users/rz/Downloads/addresses.csv", opts),   opts: { _width: 300, _height: 300 }},
             {key: "Header",     creator: headerTemplate,                                    opts: { _width: 300, _height: 70, _headerPointerEvents: "all", _headerHeight: 12, _headerFontSize: 9, _autoHeight: true, treeViewHideUnrendered: true}},
diff --git a/src/client/util/LinkFollower.ts b/src/client/util/LinkFollower.ts
index f5aae6632..d4d7c66f5 100644
--- a/src/client/util/LinkFollower.ts
+++ b/src/client/util/LinkFollower.ts
@@ -1,9 +1,9 @@
-import { action, runInAction } from 'mobx';
-import { Doc, DocListCast, Opt } from '../../fields/Doc';
-import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../fields/Types';
+import { action, observable, runInAction } from 'mobx';
+import { Doc, DocListCast, Field, FieldResult, Opt } from '../../fields/Doc';
+import { ScriptField } from '../../fields/ScriptField';
+import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../fields/Types';
 import { DocumentType } from '../documents/DocumentTypes';
-import { DocumentDecorations } from '../views/DocumentDecorations';
-import { DocFocusOptions, DocumentViewSharedProps, OpenWhere } from '../views/nodes/DocumentView';
+import { DocFocusOptions, OpenWhere } from '../views/nodes/DocumentView';
 import { PresBox } from '../views/nodes/trails';
 import { DocumentManager } from './DocumentManager';
 import { LinkManager } from './LinkManager';
@@ -23,18 +23,19 @@ import { UndoManager } from './UndoManager';
  * - user defined kvps
  */
 export class LinkFollower {
+    @observable public static IsFollowing = false;
     // follows a link - if the target is on screen, it highlights/pans to it.
     // if the target isn't onscreen, then it will open up the target in the lightbox, or in place
     // depending on the followLinkLocation property of the source (or the link itself as a fallback);
     public static FollowLink = (linkDoc: Opt<Doc>, sourceDoc: Doc, altKey: boolean) => {
         const batch = UndoManager.StartBatch('follow link click');
-        runInAction(() => (DocumentDecorations.Instance.overrideBounds = true)); // turn off decoration bounds while following links since animations may occur, and DocDecorations is based on screenToLocal which is not always an observable value
+        runInAction(() => (LinkFollower.IsFollowing = true)); // turn off decoration bounds while following links since animations may occur, and DocDecorations is based on screenToLocal which is not always an observable value
         LinkFollower.traverseLink(
             linkDoc,
             sourceDoc,
             action(() => {
                 batch.end();
-                Doc.AddUnHighlightWatcher(action(() => (DocumentDecorations.Instance.overrideBounds = false)));
+                Doc.AddUnHighlightWatcher(action(() => (LinkFollower.IsFollowing = false)));
             }),
             altKey ? true : undefined
         );
@@ -124,3 +125,10 @@ ScriptingGlobals.add(function followLink(doc: Doc, altKey: boolean) {
     SelectionManager.DeselectAll();
     LinkFollower.FollowLink(undefined, doc, altKey);
 });
+
+export function FollowLinkScript() {
+    return ScriptField.MakeScript('followLink(this,altKey)', { altKey: 'boolean' });
+}
+export function IsFollowLinkScript(field: FieldResult<Field>) {
+    return ScriptCast(field)?.script.originalScript.includes('followLink(');
+}
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 7e1b32398..8c2ced55a 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -1,16 +1,17 @@
 import { IconProp } from '@fortawesome/fontawesome-svg-core';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Tooltip } from '@material-ui/core';
-import { action, computed, observable, runInAction, trace } from 'mobx';
+import { action, computed, observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import { Doc } from '../../fields/Doc';
 import { RichTextField } from '../../fields/RichTextField';
-import { Cast, DocCast, NumCast, ScriptCast } from '../../fields/Types';
+import { Cast, DocCast, NumCast } from '../../fields/Types';
 import { emptyFunction, returnFalse, setupMoveUpEvents, simulateMouseClick } from '../../Utils';
 import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager';
 import { Pulls, Pushes } from '../apis/google_docs/GoogleApiClientUtils';
 import { Docs, DocUtils } from '../documents/Documents';
 import { DragManager } from '../util/DragManager';
+import { IsFollowLinkScript } from '../util/LinkFollower';
 import { SelectionManager } from '../util/SelectionManager';
 import { SharingManager } from '../util/SharingManager';
 import { undoBatch, UndoManager } from '../util/UndoManager';
@@ -24,11 +25,9 @@ import { DocumentLinksButton } from './nodes/DocumentLinksButton';
 import { DocumentView, DocumentViewInternal, OpenWhere, OpenWhereMod } from './nodes/DocumentView';
 import { DashFieldView } from './nodes/formattedText/DashFieldView';
 import { GoogleRef } from './nodes/formattedText/FormattedTextBox';
+import { PinProps } from './nodes/trails';
 import { TemplateMenu } from './TemplateMenu';
 import React = require('react');
-import { DocumentType } from '../documents/DocumentTypes';
-import { FontIconBox } from './nodes/button/FontIconBox';
-import { PinProps } from './nodes/trails';
 const higflyout = require('@hig/flyout');
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -238,7 +237,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
                 </Tooltip>
             );
         };
-        const followLink = ScriptCast(targetDoc?.onClick)?.script.originalScript.includes('followLink(');
+        const followLink = IsFollowLinkScript(targetDoc?.onClick);
         return !targetDoc ? null : (
             <Tooltip title={<div className="dash-tooltip">Set onClick to follow primary link</div>}>
                 <div
@@ -594,7 +593,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
                         <LinkPopup
                             key="popup"
                             showPopup={this._showLinkPopup}
-                            linkCreated={link => (link.linkDisplay = !ScriptCast(this.props.views().lastElement()?.rootDoc.onClick)?.script.originalScript.includes('followLink('))}
+                            linkCreated={link => (link.linkDisplay = !IsFollowLinkScript(this.props.views().lastElement()?.rootDoc.onClick))}
                             linkCreateAnchor={() => this.props.views().lastElement()?.ComponentView?.getAnchor?.(true)}
                             linkFrom={() => this.props.views().lastElement()?.rootDoc}
                         />
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 9bc583ce5..9ffbe083f 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -32,6 +32,7 @@ import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
 import { ImageBox } from './nodes/ImageBox';
 import React = require('react');
 import { RichTextField } from '../../fields/RichTextField';
+import { LinkFollower } from '../util/LinkFollower';
 
 @observer
 export class DocumentDecorations extends React.Component<{ PanelWidth: number; PanelHeight: number; boundsLeft: number; boundsTop: number }, { value: string }> {
@@ -83,10 +84,9 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
         );
     }
 
-    @observable overrideBounds = false;
     @computed
     get Bounds() {
-        if (this.overrideBounds) return { x: 0, y: 0, r: 0, b: 0 };
+        if (LinkFollower.IsFollowing) return { x: 0, y: 0, r: 0, b: 0 };
         const views = SelectionManager.Views();
         return views
             .filter(dv => dv.props.renderDepth > 0)
@@ -908,7 +908,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
                                     {this._isRotating ? null : (
                                         <Tooltip enterDelay={750} title={<div className="dash-tooltip">tap to set rotate center, drag to rotate</div>}>
                                             <div className="documentDecorations-rotation" style={{ pointerEvents: 'all' }} onPointerDown={this.onRotateDown} onContextMenu={e => e.preventDefault()}>
-                                                <IconButton icon={<FaUndo />} isCircle={true} hoverStyle={'lighten'} backgroundColor={Colors.DARK_GRAY} color={Colors.LIGHT_GRAY} />
+                                                <IconButton icon={<FaUndo />} color={Colors.LIGHT_GRAY} />
                                             </div>
                                         </Tooltip>
                                     )}
diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx
index 6b4f8ad85..ede387927 100644
--- a/src/client/views/MarqueeAnnotator.tsx
+++ b/src/client/views/MarqueeAnnotator.tsx
@@ -15,6 +15,7 @@ import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
 import { AnchorMenu } from './pdf/AnchorMenu';
 import React = require('react');
 import { ScriptField } from '../../fields/ScriptField';
+import { FollowLinkScript } from '../util/LinkFollower';
 const _global = (window /* browser */ || global) /* node */ as any;
 
 export interface MarqueeAnnotatorProps {
@@ -148,7 +149,7 @@ export class MarqueeAnnotator extends React.Component<MarqueeAnnotatorProps> {
             const anno = savedAnnos[0];
             const containerOffset = this.props.containerOffset?.() || [0, 0];
             const marqueeAnno = Docs.Create.FreeformDocument([], {
-                onClick: isLinkButton ? ScriptField.MakeScript('followLink(this,altKey)', { altKey: 'boolean' }) : undefined,
+                onClick: isLinkButton ? FollowLinkScript() : undefined,
                 backgroundColor: color,
                 annotationOn: this.props.rootDoc,
                 title: 'Annotation on ' + this.props.rootDoc.title,
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 0723966e1..031d501ad 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -21,6 +21,7 @@ import { DocumentView, OpenWhere } from './nodes/DocumentView';
 import { pasteImageBitmap } from './nodes/WebBoxRenderer';
 import './PropertiesButtons.scss';
 import React = require('react');
+import { IsFollowLinkScript } from '../util/LinkFollower';
 const higflyout = require('@hig/flyout');
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -289,7 +290,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
             .filter(dv => dv.docView)
             .map(dv => dv.docView!)
             .forEach(docView => {
-                const linkButton = ScriptCast(docView.props.Document.onClick)?.script.originalScript.includes('followLink(');
+                const linkButton = IsFollowLinkScript(docView.props.Document.onClick);
                 docView.noOnClick();
                 switch (onClick) {
                     case 'enterPortal':
@@ -327,7 +328,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
         ];
         const list = buttonList.map(value => {
             const click = () => this.handleOptionChange(value[0]);
-            const linkButton = BoolCast(ScriptCast(this.selectedDoc.onClick)?.script.originalScript.includes('followLink('));
+            const linkButton = IsFollowLinkScript(this.selectedDoc.onClick);
             const followLoc = this.selectedDoc._followLinkLocation;
             const linkedToLightboxView = () => LinkManager.Links(this.selectedDoc).some(link => LinkManager.getOppositeAnchor(link, this.selectedDoc)?._isLightbox);
 
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 8d67f0528..b950b4860 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -1,13 +1,15 @@
 import { IconProp } from '@fortawesome/fontawesome-svg-core';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Tooltip } from '@material-ui/core';
 import { Shadows } from 'browndash-components';
 import { action, runInAction } from 'mobx';
 import { extname } from 'path';
 import { Doc, Opt, StrListCast } from '../../fields/Doc';
-import { BoolCast, Cast, ImageCast, NumCast, ScriptCast, StrCast } from '../../fields/Types';
+import { BoolCast, Cast, ImageCast, NumCast, StrCast } from '../../fields/Types';
 import { DashColor, lightOrDark, Utils } from '../../Utils';
 import { CollectionViewType, DocumentType } from '../documents/DocumentTypes';
 import { DocFocusOrOpen, DocumentManager } from '../util/DocumentManager';
+import { IsFollowLinkScript } from '../util/LinkFollower';
 import { LinkManager } from '../util/LinkManager';
 import { SelectionManager } from '../util/SelectionManager';
 import { ColorScheme, SettingsManager } from '../util/SettingsManager';
@@ -18,13 +20,10 @@ import { InkingStroke } from './InkingStroke';
 import { MainView } from './MainView';
 import { DocumentViewProps } from './nodes/DocumentView';
 import { FieldViewProps } from './nodes/FieldView';
+import { KeyValueBox } from './nodes/KeyValueBox';
 import { SliderBox } from './nodes/SliderBox';
 import './StyleProvider.scss';
 import React = require('react');
-import { KeyValueBox } from './nodes/KeyValueBox';
-import { listSpec } from '../../fields/Schema';
-import { AudioField } from '../../fields/URLField';
-import { Tooltip } from '@material-ui/core';
 
 export enum StyleProp {
     TreeViewIcon = 'treeViewIcon',
@@ -279,8 +278,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
         case StyleProp.BoxShadow: {
             if (!doc || opacity() === 0 || doc.noShadow) return undefined; // if it's not visible, then no shadow)
             if (doc.boxShadow === 'standard') return Shadows.STANDARD_SHADOW;
-            if (ScriptCast(doc?.onClick)?.script.originalScript.includes('followLink(') && LinkManager.Links(doc).length && ![DocumentType.LINK, DocumentType.INK].includes(doc.type as any))
-                return StrCast(doc?._linkButtonShadow, 'lightblue 0em 0em 1em');
+            if (IsFollowLinkScript(doc?.onClick) && LinkManager.Links(doc).length && ![DocumentType.LINK, DocumentType.INK].includes(doc.type as any)) return StrCast(doc?._linkButtonShadow, 'lightblue 0em 0em 1em');
             switch (doc?.type) {
                 case DocumentType.COL:
                     return StrCast(
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index 5891cfe78..bbd81d06d 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -14,7 +14,7 @@ import { Docs } from '../../documents/Documents';
 import { DocumentType } from '../../documents/DocumentTypes';
 import { DocumentManager } from '../../util/DocumentManager';
 import { DragManager } from '../../util/DragManager';
-import { LinkFollower } from '../../util/LinkFollower';
+import { FollowLinkScript, IsFollowLinkScript, LinkFollower } from '../../util/LinkFollower';
 import { LinkManager } from '../../util/LinkManager';
 import { ScriptingGlobals } from '../../util/ScriptingGlobals';
 import { SelectionManager } from '../../util/SelectionManager';
@@ -406,7 +406,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
                 backgroundColor: 'rgba(128, 128, 128, 0.5)',
                 useLinkSmallAnchor: true,
                 hideLinkButton: true,
-                onClick: ScriptField.MakeScript('followLink(this,altKey)', { altKey: 'boolean' }),
+                onClick: FollowLinkScript(),
                 annotationOn: rootDoc,
                 _timelineLabel: true,
                 borderRounding: anchorEndTime === undefined ? '100%' : undefined,
@@ -450,7 +450,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
 
     @action
     clickAnchor = (anchorDoc: Doc, clientX: number) => {
-        if (ScriptCast(anchorDoc.onClick)?.script.originalScript.includes('followLink(')) {
+        if (IsFollowLinkScript(anchorDoc.onClick)) {
             LinkFollower.FollowLink(undefined, anchorDoc, false);
         }
         const seekTimeInSeconds = this.anchorStart(anchorDoc) - 0.05;
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 2d12005fb..dbcfe43cf 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -146,7 +146,7 @@ export class DocumentContentsView extends React.Component<
             (this.props.LayoutTemplateString && this.props.Document) ||
             (this.props.layoutKey && StrCast(this.props.Document[this.props.layoutKey]) && this.props.Document) ||
             Doc.Layout(this.props.Document, this.props.layoutKey ? Cast(this.props.Document[this.props.layoutKey], Doc, null) : undefined);
-        return Doc.expandTemplateLayout(template, this.props.Document, this.props.layoutKey);
+        return Doc.expandTemplateLayout(template, this.props.Document);
     }
 
     CreateBindings(onClick: Opt<ScriptField>, onInput: Opt<ScriptField>): JsxBindings {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index a39c3cf8f..f161a7b9b 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -22,7 +22,7 @@ import { DictationManager } from '../../util/DictationManager';
 import { DocumentManager } from '../../util/DocumentManager';
 import { DragManager, dropActionType } from '../../util/DragManager';
 import { InteractionUtils } from '../../util/InteractionUtils';
-import { LinkFollower } from '../../util/LinkFollower';
+import { FollowLinkScript, LinkFollower } from '../../util/LinkFollower';
 import { LinkManager } from '../../util/LinkManager';
 import { ScriptingGlobals } from '../../util/ScriptingGlobals';
 import { SelectionManager } from '../../util/SelectionManager';
@@ -560,14 +560,14 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
     toggleFollowLink = (zoom?: boolean, setTargetToggle?: boolean): void => {
         const hadOnClick = this.rootDoc.onClick;
         this.noOnClick();
-        this.Document.onClick = hadOnClick ? undefined : ScriptField.MakeScript('followLink(this,altKey)', { altKey: 'boolean' });
+        this.Document.onClick = hadOnClick ? undefined : FollowLinkScript();
         this.Document.waitForDoubleClickToClick = hadOnClick ? undefined : 'never';
     };
     @undoBatch
     @action
     followLinkOnClick = (): void => {
         this.Document.ignoreClick = false;
-        this.Document.onClick = ScriptField.MakeScript('followLink(this,altKey)', { altKey: 'boolean' });
+        this.Document.onClick = FollowLinkScript();
         this.Document.followLinkToggle = false;
         this.Document.followLinkZoom = false;
         this.Document.followLinkLocation = undefined;
@@ -623,7 +623,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
             );
         }
         this.Document.followLinkLocation = OpenWhere.lightbox;
-        this.Document.onClick = ScriptField.MakeScript('followLink(this,altKey)', { altKey: 'boolean' });
+        this.Document.onClick = FollowLinkScript();
     };
 
     importDocument = () => {
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 83ad5628c..b144c9318 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -34,6 +34,7 @@ import { RecordingBox } from './RecordingBox';
 import { PinProps, PresBox } from './trails';
 import './VideoBox.scss';
 import { ScriptField } from '../../../fields/ScriptField';
+import { FollowLinkScript } from '../../util/LinkFollower';
 const path = require('path');
 
 /**
@@ -325,7 +326,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
                 _width: 150,
                 _height: 50,
                 title: (this.layoutDoc._currentTimecode || 0).toString(),
-                onClick: ScriptField.MakeScript('followLink(this,altKey)', { altKey: 'boolean' }),
+                onClick: FollowLinkScript(),
             });
             this.props.addDocument?.(b);
             DocUtils.MakeLink(b, this.rootDoc, { linkRelationship: 'video snapshot' });
@@ -369,7 +370,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
             _nativeHeight: Doc.NativeHeight(this.layoutDoc),
             x: NumCast(this.layoutDoc.x) + width,
             y: NumCast(this.layoutDoc.y),
-            onClick: ScriptField.MakeScript('followLink(this,altKey)', { altKey: 'boolean' }),
+            onClick: FollowLinkScript(),
             _width: 150,
             _height: (height / width) * 150,
             title: '--snapshot' + NumCast(this.layoutDoc._currentTimecode) + ' image-',
diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx
index 61345f891..c00ab6a7e 100644
--- a/src/client/views/nodes/formattedText/DashDocView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocView.tsx
@@ -77,7 +77,7 @@ export class DashDocViewInternal extends React.Component<IDashDocViewInternal> {
 
     updateDoc = action((dashDoc: Doc) => {
         this._dashDoc = dashDoc;
-        this._finalLayout = this.props.docId ? dashDoc : Doc.expandTemplateLayout(Doc.Layout(dashDoc), dashDoc, this.props.fieldKey);
+        this._finalLayout = this.props.docId ? dashDoc : Doc.expandTemplateLayout(Doc.Layout(dashDoc), dashDoc);
 
         if (this._finalLayout) {
             if (!Doc.AreProtosEqual(this._finalLayout, dashDoc)) {
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 809315963..677c4662b 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -64,6 +64,7 @@ import { schema } from './schema_rts';
 import { SummaryView } from './SummaryView';
 import applyDevTools = require('prosemirror-dev-tools');
 import React = require('react');
+import { IsFollowLinkScript } from '../../../util/LinkFollower';
 const translateGoogleApi = require('translate-google-api');
 
 export const GoogleRef = 'googleDocId';
@@ -1933,7 +1934,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
                                 paddingRight: StrCast(this.layoutDoc._textBoxPaddingX, `${paddingX - selPad}px`),
                                 paddingTop: StrCast(this.layoutDoc._textBoxPaddingY, `${paddingY - selPad}px`),
                                 paddingBottom: StrCast(this.layoutDoc._textBoxPaddingY, `${paddingY - selPad}px`),
-                                pointerEvents: !active && !SnappingManager.GetIsDragging() ? (ScriptCast(this.layoutDoc.onClick)?.script.originalScript.includes('followLink(') ? 'none' : undefined) : undefined,
+                                pointerEvents: !active && !SnappingManager.GetIsDragging() ? (IsFollowLinkScript(this.layoutDoc.onClick) ? 'none' : undefined) : undefined,
                             }}
                         />
                     </div>
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 3a5ba4f75..662792ff0 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -906,57 +906,40 @@ export namespace Doc {
             saveAs(content, doc.title + '.zip'); // glr: Possibly change the name of the document to match the title?
         });
     }
-    //
-    // Determines whether the layout needs to be expanded (as a template).
-    // template expansion is rquired when the layout is a template doc/field and there's a datadoc which isn't equal to the layout template
-    //
-    export function WillExpandTemplateLayout(layoutDoc: Doc, dataDoc?: Doc) {
-        return (layoutDoc.isTemplateForField || layoutDoc.isTemplateDoc) && dataDoc && layoutDoc !== dataDoc;
-    }
 
     const _pendingMap: Map<string, boolean> = new Map();
     //
     // Returns an expanded template layout for a target data document if there is a template relationship
     // between the two. If so, the layoutDoc is expanded into a new document that inherits the properties
     // of the original layout while allowing for individual layout properties to be overridden in the expanded layout.
-    // templateArgs should be equivalent to the layout key that generates the template since that's where the template parameters are stored in ()'s at the end of the key.
-    // NOTE:  the template will have references to "@params" -- the template arguments will be assigned to the '@params' field
-    // so that when the @params key is accessed, it will be rewritten as the key that is stored in the 'params' field and
-    // the derefence will then occur on the rootDocument (the original document).
-    // in the future, field references could be written as @<someparam> and then arguments would be passed in the layout key as:
-    //   layout_mytemplate(somparam=somearg).
-    // then any references to @someparam would be rewritten as accesses to 'somearg' on the rootDocument
-    export function expandTemplateLayout(templateLayoutDoc: Doc, targetDoc?: Doc, templateArgs?: string) {
-        const args = templateArgs?.match(/\(([a-zA-Z0-9._\-]*)\)/)?.[1].replace('()', '') || '';
-        if ((!args && !WillExpandTemplateLayout(templateLayoutDoc, targetDoc)) || !targetDoc) return templateLayoutDoc;
-
-        const templateField = StrCast(templateLayoutDoc.isTemplateForField); // the field that the template renders
+    export function expandTemplateLayout(templateLayoutDoc: Doc, targetDoc?: Doc) {
+        // nothing to do if the layout isn't a template or we don't have a target that's different than the template
+        if (!targetDoc || templateLayoutDoc === targetDoc || (!templateLayoutDoc.isTemplateForField && !templateLayoutDoc.isTemplateDoc)) {
+            return templateLayoutDoc;
+        }
+
+        const templateField = StrCast(templateLayoutDoc.isTemplateForField, Doc.LayoutFieldKey(templateLayoutDoc)); // the field that the template renders
         // First it checks if an expanded layout already exists -- if so it will be stored on the dataDoc
         // using the template layout doc's id as the field key.
         // If it doesn't find the expanded layout, then it makes a delegate of the template layout and
         // saves it on the data doc indexed by the template layout's id.
         //
-        const params = args.split('=').length > 1 ? args.split('=')[0] : '';
-        const layoutFielddKey = Doc.LayoutFieldKey(templateLayoutDoc);
-        const expandedLayoutFieldKey = (templateField || layoutFielddKey) + '-layout[' + templateLayoutDoc[Id] + (args ? `(${args})` : '') + ']';
+        const expandedLayoutFieldKey = templateField + '-layout[' + templateLayoutDoc[Id] + ']';
         let expandedTemplateLayout = targetDoc?.[expandedLayoutFieldKey];
 
         if (templateLayoutDoc.resolvedDataDoc instanceof Promise) {
             expandedTemplateLayout = undefined;
             _pendingMap.set(targetDoc[Id] + expandedLayoutFieldKey, true);
-        } else if (expandedTemplateLayout === undefined && !_pendingMap.get(targetDoc[Id] + expandedLayoutFieldKey + args)) {
+        } else if (expandedTemplateLayout === undefined && !_pendingMap.get(targetDoc[Id] + expandedLayoutFieldKey)) {
             if (templateLayoutDoc.resolvedDataDoc === (targetDoc.rootDocument || Doc.GetProto(targetDoc))) {
                 expandedTemplateLayout = templateLayoutDoc; // reuse an existing template layout if its for the same document with the same params
             } else {
                 templateLayoutDoc.resolvedDataDoc && (templateLayoutDoc = Cast(templateLayoutDoc.proto, Doc, null) || templateLayoutDoc); // if the template has already been applied (ie, a nested template), then use the template's prototype
                 if (!targetDoc[expandedLayoutFieldKey]) {
-                    _pendingMap.set(targetDoc[Id] + expandedLayoutFieldKey + args, true);
+                    _pendingMap.set(targetDoc[Id] + expandedLayoutFieldKey, true);
                     setTimeout(
                         action(() => {
                             const newLayoutDoc = Doc.MakeDelegate(templateLayoutDoc, undefined, '[' + templateLayoutDoc.title + ']');
-                            // the template's arguments are stored in params which is derefenced to find
-                            // the actual field key where the parameterized template data is stored.
-                            newLayoutDoc[params] = args !== '...' ? args : ''; // ... signifies the layout has sub template(s) -- so we have to expand the layout for them so that they can get the correct 'rootDocument' field, but we don't need to reassign their params.  it would be better if the 'rootDocument' field could be passed dynamically to avoid have to create instances
                             newLayoutDoc.rootDocument = targetDoc;
                             const dataDoc = Doc.GetProto(targetDoc);
                             newLayoutDoc.resolvedDataDoc = dataDoc;
@@ -965,7 +948,7 @@ export namespace Doc {
                             }
                             targetDoc[expandedLayoutFieldKey] = newLayoutDoc;
 
-                            _pendingMap.delete(targetDoc[Id] + expandedLayoutFieldKey + args);
+                            _pendingMap.delete(targetDoc[Id] + expandedLayoutFieldKey);
                         })
                     );
                 }
@@ -982,7 +965,7 @@ export namespace Doc {
             return { layout: childDoc, data: childDoc };
         }
         const resolvedDataDoc = Doc.AreProtosEqual(containerDataDoc, containerDoc) || (!childDoc.isTemplateDoc && !childDoc.isTemplateForField) ? undefined : containerDataDoc;
-        return { layout: Doc.expandTemplateLayout(childDoc, resolvedDataDoc, '()'), data: resolvedDataDoc };
+        return { layout: Doc.expandTemplateLayout(childDoc, resolvedDataDoc), data: resolvedDataDoc };
     }
 
     export function Overwrite(doc: Doc, overwrite: Doc, copyProto: boolean = false): Doc {
-- 
cgit v1.2.3-70-g09d2


From 650cc00d18c97f89aef77f50703aa9b525dd0368 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Fri, 14 Apr 2023 11:12:49 -0400
Subject: got rid of CollectionView prop.  fixed DocFocusOrOpen to toggle
 targets and zoom correctly.

---
 src/client/util/DocumentManager.ts                  | 12 +++++++-----
 .../util/Import & Export/DirectoryImportBox.tsx     |  2 +-
 src/client/util/LinkFollower.ts                     |  2 +-
 src/client/views/MainView.tsx                       |  1 -
 src/client/views/PropertiesDocBacklinksSelector.tsx |  2 +-
 src/client/views/PropertiesDocContextSelector.tsx   | 21 +--------------------
 src/client/views/SidebarAnnos.tsx                   |  1 -
 src/client/views/StyleProvider.tsx                  |  4 ++--
 src/client/views/TemplateMenu.tsx                   |  1 -
 src/client/views/collections/CollectionMenu.tsx     |  1 -
 .../views/collections/CollectionNoteTakingView.tsx  |  2 +-
 .../views/collections/CollectionStackingView.tsx    |  2 +-
 src/client/views/collections/CollectionSubView.tsx  |  6 +++---
 src/client/views/collections/CollectionTreeView.tsx |  6 +++---
 src/client/views/collections/CollectionView.tsx     |  1 -
 src/client/views/collections/TabDocView.tsx         |  1 -
 src/client/views/collections/TreeView.tsx           |  6 +++---
 .../collectionFreeForm/CollectionFreeFormView.tsx   | 11 +++++++----
 src/client/views/linking/LinkMenuItem.tsx           |  2 +-
 src/client/views/nodes/AudioBox.tsx                 |  1 -
 src/client/views/nodes/DocumentView.tsx             | 14 +++++++-------
 src/client/views/nodes/ImageBox.tsx                 |  1 -
 src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx  |  1 -
 src/client/views/nodes/PDFBox.tsx                   |  1 -
 src/client/views/nodes/ScreenshotBox.tsx            |  1 -
 src/client/views/nodes/VideoBox.tsx                 |  2 --
 src/client/views/nodes/WebBox.tsx                   |  1 -
 .../views/nodes/formattedText/FormattedTextBox.tsx  |  1 -
 src/client/views/pdf/PDFViewer.tsx                  |  1 -
 29 files changed, 39 insertions(+), 69 deletions(-)

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

diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index ad89e8653..e01457b4f 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -227,6 +227,7 @@ export class DocumentManager {
         let rootContextView = docViewPath.shift();
         await (rootContextView && this.focusViewsInPath(rootContextView, options, async () => ({ childDocView: docViewPath.shift(), viewSpec: undefined })));
         if (options.toggleTarget && (!options.didMove || targetDocView.rootDoc.hidden)) targetDocView.rootDoc.hidden = !targetDocView.rootDoc.hidden;
+        else if (options.openLocation?.startsWith(OpenWhere.toggle) && !options.didMove && rootContextView) MainView.addDocTabFunc(rootContextView.rootDoc, options.openLocation);
     };
 
     // shows a document by first:
@@ -246,10 +247,9 @@ export class DocumentManager {
             const viewIndex = docContextPath.findIndex(doc => this.getDocumentView(doc));
             if (viewIndex !== -1) return res(this.getDocumentView(docContextPath[viewIndex])!);
             options.didMove = true;
-            docContextPath.some(doc => TabDocView.Activate(doc)) || MainView.addDocTabFunc(docContextPath[0], options.openLocation as OpenWhere);
+            docContextPath.some(doc => TabDocView.Activate(doc)) || MainView.addDocTabFunc(docContextPath[0], options.openLocation ?? OpenWhere.addRight);
             this.AddViewRenderedCb(docContextPath[0], dv => res(dv));
         });
-
         docContextPath.shift();
         const childViewIterator = async (docView: DocumentView) => {
             const innerDoc = docContextPath.shift();
@@ -297,15 +297,17 @@ export class DocumentManager {
         }
     }
 }
-export function DocFocusOrOpen(doc: Doc, options: DocFocusOptions = { willZoomCentered: true, openLocation: OpenWhere.addRight }, containingDoc?: Doc) {
+export function DocFocusOrOpen(doc: Doc, options: DocFocusOptions = { willZoomCentered: true, zoomScale: 0, openLocation: OpenWhere.toggleRight }, containingDoc?: Doc) {
     const func = () => {
         const cv = DocumentManager.Instance.getDocumentView(containingDoc);
         const dv = DocumentManager.Instance.getDocumentView(doc, cv);
         if (dv && (!containingDoc || dv.props.docViewPath().lastElement()?.Document === containingDoc)) {
             DocumentManager.Instance.showDocumentView(dv, options).then(() => dv && Doc.linkFollowHighlight(dv.rootDoc));
         } else {
-            const showDoc = Doc.BestAlias(DocCast((containingDoc ?? doc.context) !== Doc.MyFilesystem ? containingDoc ?? doc.context : undefined, doc));
-            DocumentManager.Instance.showDocument(showDoc, { ...options, toggleTarget: undefined }, () => DocumentManager.Instance.showDocument(doc, options)).then(() => {
+            const container = DocCast(containingDoc ?? doc.context);
+            const showDoc = !Doc.IsSystem(container) ? container : doc;
+            options.toggleTarget = undefined;
+            DocumentManager.Instance.showDocument(showDoc, options, () => DocumentManager.Instance.showDocument(doc, { ...options, openLocation: undefined })).then(() => {
                 const cv = DocumentManager.Instance.getDocumentView(containingDoc);
                 const dv = DocumentManager.Instance.getDocumentView(doc, cv);
                 dv && Doc.linkFollowHighlight(dv.rootDoc);
diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx
index 76b1323c4..b9bb22564 100644
--- a/src/client/util/Import & Export/DirectoryImportBox.tsx	
+++ b/src/client/util/Import & Export/DirectoryImportBox.tsx	
@@ -157,7 +157,7 @@ export class DirectoryImportBox extends React.Component<FieldViewProps> {
             x: NumCast(doc.x),
             y: NumCast(doc.y) + offset,
         };
-        const parent = _.nth(this.props.docViewPath(), -2); // last element of path is this box's document view, 2nd to last is any collection or other document that may contain it.
+        const parent = this.props.DocumentView?.().props.docViewPath().lastElement();
         if (parent?.rootDoc.type === DocumentType.COL) {
             let importContainer: Doc;
             if (docs.length < 50) {
diff --git a/src/client/util/LinkFollower.ts b/src/client/util/LinkFollower.ts
index d4d7c66f5..ba2edb65c 100644
--- a/src/client/util/LinkFollower.ts
+++ b/src/client/util/LinkFollower.ts
@@ -75,7 +75,7 @@ export class LinkFollower {
                         zoomTime: NumCast(sourceDoc.followLinkTransitionTime, 500),
                         zoomScale: Cast(sourceDoc.followLinkZoomScale, 'number', null),
                         easeFunc: StrCast(sourceDoc.followLinkEase, 'ease') as any,
-                        openLocation: StrCast(sourceDoc.followLinkLocation, OpenWhere.lightbox),
+                        openLocation: StrCast(sourceDoc.followLinkLocation, OpenWhere.lightbox) as OpenWhere,
                         effect: sourceDoc,
                         zoomTextSelections: BoolCast(sourceDoc.followLinkZoomText),
                     };
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 0384d925e..ccc9a7215 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -883,7 +883,6 @@ export class MainView extends React.Component {
                     isSelected={returnFalse}
                     docViewPath={returnEmptyDoclist}
                     moveDocument={this.moveButtonDoc}
-                    CollectionView={undefined}
                     addDocument={this.addButtonDoc}
                     addDocTab={MainView.addDocTabFunc}
                     pinToPres={emptyFunction}
diff --git a/src/client/views/PropertiesDocBacklinksSelector.tsx b/src/client/views/PropertiesDocBacklinksSelector.tsx
index 00c3400cb..935d551c6 100644
--- a/src/client/views/PropertiesDocBacklinksSelector.tsx
+++ b/src/client/views/PropertiesDocBacklinksSelector.tsx
@@ -25,7 +25,7 @@ export class PropertiesDocBacklinksSelector extends React.Component<PropertiesDo
 
         if (otherdoc) {
             otherdoc.hidden = false;
-            this.props.addDocTab(Doc.IsPrototype(otherdoc) ? Doc.MakeDelegate(otherdoc) : otherdoc, (OpenWhere.toggle + ':' + OpenWhereMod.right) as OpenWhere);
+            this.props.addDocTab(Doc.IsPrototype(otherdoc) ? Doc.MakeDelegate(otherdoc) : otherdoc, OpenWhere.toggleRight);
         }
     };
 
diff --git a/src/client/views/PropertiesDocContextSelector.tsx b/src/client/views/PropertiesDocContextSelector.tsx
index 93eec61f3..c14d7ef73 100644
--- a/src/client/views/PropertiesDocContextSelector.tsx
+++ b/src/client/views/PropertiesDocContextSelector.tsx
@@ -49,26 +49,7 @@ export class PropertiesDocContextSelector extends React.Component<PropertiesDocC
     getOnClick = (col: Doc, target: Doc) => {
         if (!this.props.DocView) return;
         col = Doc.IsPrototype(col) ? Doc.MakeDelegate(col) : col;
-        if (col._viewType === CollectionViewType.Freeform) {
-            col._panX = NumCast(target.x) + NumCast(target._width) / 2;
-            col._panY = NumCast(target.y) + NumCast(target._height) / 2;
-        }
-        col.hidden = false;
-        //this.props.addDocTab(col, (OpenWhere.toggle + ':' + OpenWhereMod.right) as OpenWhere);
-        setTimeout(
-            () =>
-                this.props.DocView &&
-                DocFocusOrOpen(
-                    Doc.GetProto(this.props.DocView.props.Document),
-                    {
-                        //
-                        willZoomCentered: true,
-                        openLocation: (OpenWhere.toggle + ':' + OpenWhereMod.right) as OpenWhere,
-                    },
-                    col
-                ),
-            100
-        );
+        DocFocusOrOpen(Doc.GetProto(this.props.DocView.props.Document), undefined, col);
     };
 
     render() {
diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx
index 2d2b0f83e..b0aab968e 100644
--- a/src/client/views/SidebarAnnos.tsx
+++ b/src/client/views/SidebarAnnos.tsx
@@ -243,7 +243,6 @@ export class SidebarAnnos extends React.Component<FieldViewProps & ExtraProps> {
                         removeDocument={this.removeDocument}
                         moveDocument={this.moveDocument}
                         addDocument={this.addDocument}
-                        CollectionView={undefined}
                         ScreenToLocalTransform={this.screenToLocalTransform}
                         renderDepth={this.props.renderDepth + 1}
                         viewType={CollectionViewType.Stacking}
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 739d6d819..5f16e0ebd 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -5,7 +5,7 @@ import { Shadows } from 'browndash-components';
 import { action, runInAction } from 'mobx';
 import { extname } from 'path';
 import { Doc, Opt, StrListCast } from '../../fields/Doc';
-import { BoolCast, Cast, ImageCast, NumCast, StrCast } from '../../fields/Types';
+import { BoolCast, Cast, DocCast, ImageCast, NumCast, StrCast } from '../../fields/Types';
 import { DashColor, lightOrDark, Utils } from '../../Utils';
 import { CollectionViewType, DocumentType } from '../documents/DocumentTypes';
 import { DocFocusOrOpen, DocumentManager } from '../util/DocumentManager';
@@ -383,7 +383,7 @@ export function DashboardStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps
         return doc._viewType === CollectionViewType.Docking ? null : (
             <>
                 {DashboardToggleButton(doc, 'hidden', 'eye-slash', 'eye', () => {
-                    DocFocusOrOpen(doc, { toggleTarget: true, willPan: true, openLocation: OpenWhere.addRight }, props?.docViewPath().lastElement()?.rootDoc);
+                    DocFocusOrOpen(doc, { toggleTarget: true, willZoomCentered: true, zoomScale: 0 }, DocCast(doc?.context ?? doc?.annotationOn));
                 })}
             </>
         );
diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx
index c5a501aa6..1c816aa05 100644
--- a/src/client/views/TemplateMenu.tsx
+++ b/src/client/views/TemplateMenu.tsx
@@ -113,7 +113,6 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
                 {templateMenu}
                 <CollectionTreeView
                     Document={Doc.MyTemplates}
-                    CollectionView={undefined}
                     styleProvider={DefaultStyleProvider}
                     setHeight={returnFalse}
                     docViewPath={returnEmptyDoclist}
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 2007f73aa..5b631676e 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -120,7 +120,6 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> {
                     isSelected={returnFalse}
                     docViewPath={returnEmptyDoclist}
                     moveDocument={returnFalse}
-                    CollectionView={undefined}
                     addDocument={returnFalse}
                     addDocTab={returnFalse}
                     pinToPres={emptyFunction}
diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx
index 80e81bc1c..99d4d0bee 100644
--- a/src/client/views/collections/CollectionNoteTakingView.tsx
+++ b/src/client/views/collections/CollectionNoteTakingView.tsx
@@ -162,7 +162,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
     }
 
     @action
-    moveDocument = (doc: Doc, targetCollection: Doc | undefined, addDocument: (document: Doc) => boolean): boolean => {
+    moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[], annotationKey?: string) => boolean, annotationKey?: string): boolean => {
         return this.props.removeDocument?.(doc) && addDocument?.(doc) ? true : false;
     };
 
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 67f5dc9f4..bdad325d5 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -230,7 +230,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
     isAnyChildContentActive = () => this.props.isAnyChildContentActive();
 
     @action
-    moveDocument = (doc: Doc, targetCollection: Doc | undefined, addDocument: (document: Doc) => boolean): boolean => {
+    moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean): boolean => {
         return this.props.removeDocument?.(doc) && addDocument?.(doc) ? true : false;
     };
     createRef = (ele: HTMLDivElement | null) => {
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 132ed6fb6..5581ac8fe 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -19,7 +19,6 @@ import { DocComponent } from '../DocComponent';
 import React = require('react');
 
 export interface SubCollectionViewProps extends CollectionViewProps {
-    CollectionView: Opt<CollectionView>;
     isAnyChildContentActive: () => boolean;
 }
 
@@ -201,8 +200,9 @@ export function CollectionSubView<X>(moreProps?: X) {
             }
         }
 
-        addDocument = (doc: Doc | Doc[]) => this.props.addDocument?.(doc) || false;
-
+        addDocument = (doc: Doc | Doc[], annotationKey?: string) => this.props.addDocument?.(doc, annotationKey) || false;
+        removeDocument = (doc: Doc | Doc[], annotationKey?: string) => this.props.removeDocument?.(doc, annotationKey) || false;
+        moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[], annotationKey?: string) => boolean, annotationKey?: string) => this.props.moveDocument?.(doc, targetCollection, addDocument);
         @action
         protected onInternalDrop(e: Event, de: DragManager.DropEvent): boolean {
             const docDragData = de.complete.docDragData;
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 92932fb61..f81c17a7b 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -374,10 +374,10 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
     onChildClick = () => this.props.onChildClick?.() || ScriptCast(this.doc.onChildClick);
     panelWidth = () => Math.max(0, this.props.PanelWidth() - 2 * this.marginX() * (this.props.NativeDimScaling?.() || 1));
 
-    addAnnotationDocument = (doc: Doc | Doc[]) => this.props.CollectionView?.addDocument(doc, `${this.props.fieldKey}-annotations`) || false;
-    remAnnotationDocument = (doc: Doc | Doc[]) => this.props.CollectionView?.removeDocument(doc, `${this.props.fieldKey}-annotations`) || false;
+    addAnnotationDocument = (doc: Doc | Doc[]) => this.addDocument(doc, `${this.props.fieldKey}-annotations`) || false;
+    remAnnotationDocument = (doc: Doc | Doc[]) => this.removeDocument(doc, `${this.props.fieldKey}-annotations`) || false;
     moveAnnotationDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[], annotationKey?: string) => boolean) =>
-        this.props.CollectionView?.moveDocument(doc, targetCollection, addDocument, `${this.props.fieldKey}-annotations`) || false;
+        this.moveDocument(doc, targetCollection, addDocument, `${this.props.fieldKey}-annotations`) || false;
 
     @observable _headerHeight = 0;
     @computed get content() {
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 53fbcc3cc..d7a889362 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -276,7 +276,6 @@ export class CollectionView extends ViewBoxAnnotatableComponent<ViewBoxAnnotatab
             childLayoutString: this.childLayoutString,
             childHideResizeHandles: this.childHideResizeHandles,
             childHideDecorationTitle: this.childHideDecorationTitle,
-            CollectionView: this,
         };
         return (
             <div
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index ef8f395c5..4bbc3bb44 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -577,7 +577,6 @@ export class TabMinimapView extends React.Component<TabMinimapViewProps> {
             <div className="miniMap" style={{ width: miniSize, height: miniSize, background: this.props.background() }}>
                 <CollectionFreeFormView
                     Document={this.props.document}
-                    CollectionView={undefined}
                     docViewPath={returnEmptyDoclist}
                     childLayoutTemplate={this.childLayoutTemplate} // bcz: Ugh .. should probably be rendering a CollectionView or the minimap should be part of the collectionFreeFormView to avoid having to set stuff like this.
                     noOverlay={true} // don't render overlay Docs since they won't scale
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 8b1dfc767..8fb610b87 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -48,7 +48,7 @@ export interface TreeViewProps {
     addDocTab: (doc: Doc, where: OpenWhere) => boolean;
     panelWidth: () => number;
     panelHeight: () => number;
-    addDocument: (doc: Doc | Doc[], relativeTo?: Doc, before?: boolean) => boolean;
+    addDocument: (doc: Doc | Doc[], annotationKey?: string, relativeTo?: Doc, before?: boolean) => boolean;
     removeDoc: ((doc: Doc | Doc[]) => boolean) | undefined;
     moveDocument: DragManager.MoveFunction;
     isContentActive: (outsideReaction?: boolean) => boolean;
@@ -373,7 +373,7 @@ export class TreeView extends React.Component<TreeViewProps> {
 
     dropping: boolean = false;
     dropDocuments(droppedDocuments: Doc[], before: boolean, inside: number | boolean, dropAction: dropActionType, removeDocument: DragManager.RemoveFunction | undefined, moveDocument: DragManager.MoveFunction | undefined, forceAdd: boolean) {
-        const parentAddDoc = (doc: Doc | Doc[]) => this.props.addDocument(doc, undefined, before);
+        const parentAddDoc = (doc: Doc | Doc[]) => this.props.addDocument(doc, undefined, undefined, before);
         const localAdd = (doc: Doc | Doc[]) => {
             const innerAdd = (doc: Doc) => {
                 const dataIsComputed = ComputedField.WithoutComputed(() => FieldValue(this.dataDoc[this.fieldKey])) instanceof ComputedField;
@@ -1186,7 +1186,7 @@ export class TreeView extends React.Component<TreeViewProps> {
                 };
                 const indent = i === 0 ? undefined : (editTitle: boolean) => dentDoc(editTitle, docs[i - 1], undefined, treeViewRefs.get(docs[i - 1]));
                 const outdent = !parentCollectionDoc ? undefined : (editTitle: boolean) => dentDoc(editTitle, parentCollectionDoc, containerPrevSibling, parentTreeView instanceof TreeView ? parentTreeView.props.parentTreeView : undefined);
-                const addDocument = (doc: Doc | Doc[], relativeTo?: Doc, before?: boolean) => add(doc, relativeTo ?? docs[i], before !== undefined ? before : false);
+                const addDocument = (doc: Doc | Doc[], annotationKey?: string, relativeTo?: Doc, before?: boolean) => add(doc, relativeTo ?? docs[i], before !== undefined ? before : false);
                 const childLayout = Doc.Layout(pair.layout);
                 const rowHeight = () => {
                     const aspect = Doc.NativeAspect(childLayout);
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index a3f5e73fb..33fc2ddf3 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -311,7 +311,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         const xfToCollection = options?.docTransform ?? Transform.Identity();
         const savedState = { panX: NumCast(this.Document[this.panXFieldKey]), panY: NumCast(this.Document[this.panYFieldKey]), scale: options?.willZoomCentered ? this.Document[this.scaleFieldKey] : undefined };
         const cantTransform = this.fitContentsToBox || ((this.rootDoc._isGroup || this.layoutDoc._lockedTransform) && !LightboxView.LightboxDoc);
-        const { panX, panY, scale } = cantTransform || (!options.willPan && !options.willZoomCentered) ? savedState : this.calculatePanIntoView(anchor, xfToCollection, options?.willZoomCentered ? options?.zoomScale || 0.75 : undefined);
+        const { panX, panY, scale } = cantTransform || (!options.willPan && !options.willZoomCentered) ? savedState : this.calculatePanIntoView(anchor, xfToCollection, options?.willZoomCentered ? options?.zoomScale ?? 0.75 : undefined);
 
         // focus on the document in the collection
         const didMove = !cantTransform && !anchor.z && (panX !== savedState.panX || panY !== savedState.panY || scale !== savedState.scale);
@@ -319,7 +319,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         // glr: freeform transform speed can be set by adjusting presTransition field - needs a way of knowing when presentation is not active...
         if (didMove) {
             const focusTime = options?.instant ? 0 : options.zoomTime ?? 500;
-            (options.zoomScale || options.willZoomCentered) && scale && (this.Document[this.scaleFieldKey] = scale);
+            (options.zoomScale ?? options.willZoomCentered) && scale && (this.Document[this.scaleFieldKey] = scale);
             this.setPan(panX, panY, focusTime, true); // docs that are floating in their collection can't be panned to from their collection -- need to propagate the pan to a parent freeform somehow
             return focusTime;
         }
@@ -1181,9 +1181,12 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         const pt2 = xf.transformPoint(NumCast(doc.x) + layoutdoc[WidthSym](), NumCast(doc.y) + layoutdoc[HeightSym]());
         const bounds = { left: pt[0], right: pt2[0], top: pt[1], bot: pt2[1], width: pt2[0] - pt[0], height: pt2[1] - pt[1] };
 
-        if (scale) {
+        if (scale !== undefined) {
             const maxZoom = 5; // sets the limit for how far we will zoom. this is useful for preventing small text boxes from filling the screen. So probably needs to be more sophisticated to consider more about the target and context
-            const newScale = Math.min(maxZoom, (1 / (this.nativeDimScaling || 1)) * scale * Math.min(this.props.PanelWidth() / Math.abs(bounds.width), this.props.PanelHeight() / Math.abs(bounds.height)));
+            const newScale =
+                scale === 0
+                    ? NumCast(this.layoutDoc[this.scaleFieldKey])
+                    : Math.min(maxZoom, (1 / (this.nativeDimScaling || 1)) * scale * Math.min(this.props.PanelWidth() / Math.abs(bounds.width), this.props.PanelHeight() / Math.abs(bounds.height)));
             return {
                 panX: this.props.isAnnotationOverlay ? bounds.left - (Doc.NativeWidth(this.layoutDoc) / newScale - bounds.width) / 2 : (bounds.left + bounds.right) / 2,
                 panY: this.props.isAnnotationOverlay ? bounds.top - (Doc.NativeHeight(this.layoutDoc) / newScale - bounds.height) / 2 : (bounds.top + bounds.bot) / 2,
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index d703c9595..19d6c2ae2 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -45,7 +45,7 @@ export async function StartLinkTargetsDrag(dragEle: HTMLElement, docView: Docume
 
         const dragData = new DragManager.DocumentDragData(moddrag.length ? moddrag : draggedDocs);
         dragData.canEmbed = true;
-        dragData.moveDocument = (docView.props.docViewPath().lastElement()?.ComponentView as any)?.props.CollectionView?.moveDocument; // this is equal to docView.props.moveDocument, but moveDocument is not a defined prop of a DocumentView .. but maybe it should be?
+        dragData.dropAction = 'alias';
 
         DragManager.StartDocumentDrag([dragEle], dragData, downX, downY, undefined);
     }
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index a6acf882c..68fb19208 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -663,7 +663,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
                 startTag={'_timecodeToShow' /* audioStart */}
                 endTag={'_timecodeToHide' /* audioEnd */}
                 bringToFront={emptyFunction}
-                CollectionView={undefined}
                 playFrom={this.playFrom}
                 setTime={this.setPlayheadTime}
                 playing={this.playing}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index be07f1fe5..7107707d1 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -22,7 +22,7 @@ import { DictationManager } from '../../util/DictationManager';
 import { DocumentManager } from '../../util/DocumentManager';
 import { DragManager, dropActionType } from '../../util/DragManager';
 import { InteractionUtils } from '../../util/InteractionUtils';
-import { FollowLinkScript, LinkFollower } from '../../util/LinkFollower';
+import { FollowLinkScript } from '../../util/LinkFollower';
 import { LinkManager } from '../../util/LinkManager';
 import { ScriptingGlobals } from '../../util/ScriptingGlobals';
 import { SelectionManager } from '../../util/SelectionManager';
@@ -30,7 +30,6 @@ import { SharingManager } from '../../util/SharingManager';
 import { SnappingManager } from '../../util/SnappingManager';
 import { Transform } from '../../util/Transform';
 import { undoBatch, UndoManager } from '../../util/UndoManager';
-import { CollectionView } from '../collections/CollectionView';
 import { ContextMenu } from '../ContextMenu';
 import { ContextMenuProps } from '../ContextMenuItem';
 import { DocComponent } from '../DocComponent';
@@ -69,6 +68,7 @@ export enum OpenWhere {
     close = 'close',
     fullScreen = 'fullScreen',
     toggle = 'toggle',
+    toggleRight = 'toggle:right',
     replace = 'replace',
     replaceRight = 'replace:right',
     replaceLeft = 'replace:left',
@@ -87,7 +87,7 @@ export enum OpenWhereMod {
 
 export interface DocFocusOptions {
     willPan?: boolean; // determines whether to pan to target document
-    willZoomCentered?: boolean; // determines whether to zoom in on target document
+    willZoomCentered?: boolean; // determines whether to zoom in on target document.  if zoomScale is 0, this just centers the document
     zoomScale?: number; // percent of containing frame to zoom into document
     zoomTime?: number;
     didMove?: boolean; // whether a document was changed during the showDocument process
@@ -97,7 +97,7 @@ export interface DocFocusOptions {
     effect?: Doc; // animation effect for focus
     noSelect?: boolean; // whether target should be selected after focusing
     playAudio?: boolean; // whether to play audio annotation on focus
-    openLocation?: string; // where to open a missing document
+    openLocation?: OpenWhere; // where to open a missing document
     zoomTextSelections?: boolean; // whether to display a zoomed overlay of anchor text selections
     toggleTarget?: boolean; // whether to toggle target on and off
     anchorDoc?: Doc; // doc containing anchor info to apply at end of focus to target doc
@@ -170,9 +170,9 @@ export interface DocumentViewSharedProps {
     rootSelected: (outsideReaction?: boolean) => boolean; // whether the root of a template has been selected
     addDocTab: (doc: Doc, where: OpenWhere) => boolean;
     filterAddDocument?: (doc: Doc[]) => boolean; // allows a document that renders a Collection view to filter or modify any documents added to the collection (see PresBox for an example)
-    addDocument?: (doc: Doc | Doc[]) => boolean;
-    removeDocument?: (doc: Doc | Doc[]) => boolean;
-    moveDocument?: (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[]) => boolean) => boolean;
+    addDocument?: (doc: Doc | Doc[], annotationKey?: string) => boolean;
+    removeDocument?: (doc: Doc | Doc[], annotationKey?: string) => boolean;
+    moveDocument?: (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[], annotationKey?: string) => boolean) => boolean;
     pinToPres: (document: Doc, pinProps: PinProps) => void;
     ScreenToLocalTransform: () => Transform;
     bringToFront: (doc: Doc, sendToBack?: boolean) => void;
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 22ecaa299..7c98aa6e4 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -478,7 +478,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
                     renderDepth={this.props.renderDepth + 1}
                     fieldKey={this.annotationKey}
                     styleProvider={this.props.styleProvider}
-                    CollectionView={undefined}
                     isAnnotationOverlay={true}
                     annotationLayerHostsContent={true}
                     PanelWidth={this.props.PanelWidth}
diff --git a/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx b/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
index d65ef9c4c..7b437c7de 100644
--- a/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
+++ b/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
@@ -57,7 +57,6 @@ export class MapBoxInfoWindow extends React.Component<MapBoxInfoWindowProps & Vi
                             Document={this.props.place}
                             DataDoc={undefined}
                             fieldKey="data"
-                            CollectionView={undefined}
                             NativeWidth={returnZero}
                             NativeHeight={returnZero}
                             docFilters={returnEmptyFilter}
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 502811e35..8f87b9e08 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -547,7 +547,6 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
                         removeDocument={this.sidebarRemDocument}
                         moveDocument={this.sidebarMoveDocument}
                         addDocument={this.sidebarAddDocument}
-                        CollectionView={undefined}
                         ScreenToLocalTransform={this.sidebarScreenToLocal}
                         renderDepth={this.props.renderDepth + 1}
                         noSidebar={true}
diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx
index e015024fd..aa2b22e28 100644
--- a/src/client/views/nodes/ScreenshotBox.tsx
+++ b/src/client/views/nodes/ScreenshotBox.tsx
@@ -303,7 +303,6 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
                             removeDocument={returnFalse}
                             moveDocument={returnFalse}
                             addDocument={returnFalse}
-                            CollectionView={undefined}
                             ScreenToLocalTransform={this.props.ScreenToLocalTransform}
                             renderDepth={this.props.renderDepth + 1}>
                             <>
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index b144c9318..7a7d4fe37 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -963,7 +963,6 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
                     startTag={'_timecodeToShow' /* videoStart */}
                     endTag={'_timecodeToHide' /* videoEnd */}
                     bringToFront={emptyFunction}
-                    CollectionView={undefined}
                     playFrom={this.playFrom}
                     setTime={this.setPlayheadTime}
                     playing={this.playing}
@@ -1074,7 +1073,6 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
                             NativeHeight={returnZero}
                             renderDepth={this.props.renderDepth + 1}
                             fieldKey={this.annotationKey}
-                            CollectionView={undefined}
                             isAnnotationOverlay={true}
                             annotationLayerHostsContent={true}
                             PanelWidth={this.panelWidth}
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 66d0fd385..ef3aa1f47 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -915,7 +915,6 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
                 renderDepth={this.props.renderDepth + 1}
                 isAnnotationOverlay={true}
                 fieldKey={this.annotationKey}
-                CollectionView={undefined}
                 setPreviewCursor={this.setPreviewCursor}
                 setBrushViewer={this.setBrushViewer}
                 PanelWidth={this.panelWidth}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index bc2a5d797..5719ea83c 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1844,7 +1844,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
                         removeDocument={this.sidebarRemDocument}
                         moveDocument={this.sidebarMoveDocument}
                         addDocument={this.sidebarAddDocument}
-                        CollectionView={undefined}
                         ScreenToLocalTransform={this.sidebarScreenToLocal}
                         renderDepth={this.props.renderDepth + 1}
                         setHeight={this.setSidebarHeight}
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 6ab541207..d82a7d1ae 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -530,7 +530,6 @@ export class PDFViewer extends React.Component<IViewerProps> {
                 renderDepth={this.props.renderDepth + 1}
                 isAnnotationOverlay={true}
                 fieldKey={this.props.fieldKey + '-annotations'}
-                CollectionView={undefined}
                 getScrollHeight={this.getScrollHeight}
                 setPreviewCursor={this.setPreviewCursor}
                 setBrushViewer={this.setBrushViewer}
-- 
cgit v1.2.3-70-g09d2

