From 48b0153d814cddad71caa8103e7ff4c761b66eaa Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 29 Nov 2023 19:48:32 -0500
Subject: fixed menu functions that referenced 'self' instead of 'this'

---
 src/client/views/collections/CollectionStackedTimeline.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/client/views/collections/CollectionStackedTimeline.tsx')

diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index 7bde2cb5f..552c19eb3 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -395,7 +395,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
         const anchor =
             docAnchor ??
             Docs.Create.LabelDocument({
-                title: ComputedField.MakeFunction(`self["${endTag}"] ? "#" + formatToTime(self["${startTag}"]) + "-" + formatToTime(self["${endTag}"]) : "#" + formatToTime(self["${startTag}"])`) as any,
+                title: ComputedField.MakeFunction(`this["${endTag}"] ? "#" + formatToTime(this["${startTag}"]) + "-" + formatToTime(this["${endTag}"]) : "#" + formatToTime(this["${startTag}"])`) as any,
                 _label_minFontSize: 12,
                 _label_maxFontSize: 24,
                 _dragOnlyWithinContainer: true,
-- 
cgit v1.2.3-70-g09d2


From c918198a37e4ad5306b70a90ca1b3fcab2e28f76 Mon Sep 17 00:00:00 2001
From: geireann <geireann.lindfield@gmail.com>
Date: Thu, 30 Nov 2023 16:00:13 -0500
Subject: fixed rootSelected prop  to be optional.  fixed fonticont toggle to
 pass 'self' even though it's deprecated.

---
 src/client/util/CurrentUserUtils.ts                |  2 +-
 src/client/views/GestureOverlay.tsx                |  1 -
 src/client/views/LightboxView.tsx                  |  1 -
 src/client/views/MainView.tsx                      |  6 ------
 src/client/views/OverlayView.tsx                   |  1 -
 src/client/views/PropertiesView.tsx                |  1 -
 src/client/views/TemplateMenu.tsx                  |  1 -
 src/client/views/collections/CollectionMenu.tsx    |  1 -
 .../collections/CollectionStackedTimeline.tsx      |  1 -
 .../views/collections/CollectionStackingView.tsx   |  2 +-
 src/client/views/collections/CollectionSubView.tsx |  4 ++--
 .../views/collections/CollectionTreeView.tsx       |  3 +--
 src/client/views/collections/TabDocView.tsx        |  2 --
 src/client/views/collections/TreeView.tsx          |  2 --
 .../collectionLinear/CollectionLinearView.tsx      |  2 +-
 .../collectionSchema/SchemaTableCell.tsx           |  1 -
 src/client/views/newlightbox/NewLightboxView.tsx   |  1 -
 src/client/views/nodes/DocumentView.tsx            |  2 +-
 src/client/views/nodes/FontIconBox/FontIconBox.tsx |  2 +-
 src/client/views/nodes/KeyValuePair.tsx            |  1 -
 src/client/views/nodes/LinkDocPreview.tsx          |  1 -
 src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx |  1 -
 .../views/nodes/formattedText/DashDocView.tsx      |  1 -
 .../views/nodes/formattedText/FormattedTextBox.tsx | 25 +++++++++++-----------
 .../views/nodes/formattedText/RichTextMenu.tsx     | 10 ++++-----
 src/client/views/nodes/trails/PresElementBox.tsx   |  1 -
 src/client/views/topbar/TopBar.tsx                 |  1 -
 src/mobile/MobileInterface.tsx                     |  1 -
 28 files changed, 25 insertions(+), 53 deletions(-)

(limited to 'src/client/views/collections/CollectionStackedTimeline.tsx')

diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index aba466d55..7070a47e8 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -480,7 +480,7 @@ export class CurrentUserUtils {
         const newDashboard = `createNewDashboard()`;
 
         const reqdBtnOpts:DocumentOptions = { _forceActive: true,  _width: 30, _height: 30, _dragOnlyWithinContainer: true, _layout_hideContextMenu: true,
-             title: "new dashboard", btnType: ButtonType.ClickButton, toolTip: "Create new dashboard", buttonText: "New trail", icon: "plus", isSystem: true };
+             title: "new Dash", btnType: ButtonType.ClickButton, toolTip: "Create new dashboard", buttonText: "New trail", icon: "plus", isSystem: true };
         const reqdBtnScript = {onClick: newDashboard,}
         const newDashboardButton = DocUtils.AssignScripts(DocUtils.AssignOpts(DocCast(myDashboards?.layout_headerButton), reqdBtnOpts) ?? Docs.Create.FontIconDocument(reqdBtnOpts), reqdBtnScript);
        
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 0882294a2..09be95542 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -469,7 +469,6 @@ export class GestureOverlay extends React.Component<React.PropsWithChildren<Gest
                 DataDoc={undefined}
                 addDocument={undefined}
                 addDocTab={returnFalse}
-                rootSelected={returnFalse}
                 pinToPres={emptyFunction}
                 removeDocument={undefined}
                 ScreenToLocalTransform={this.screenToLocalTransform}
diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx
index 98d30b625..15266071f 100644
--- a/src/client/views/LightboxView.tsx
+++ b/src/client/views/LightboxView.tsx
@@ -256,7 +256,6 @@ export class LightboxView extends React.Component<LightboxViewProps> {
                             styleProvider={DefaultStyleProvider}
                             ScreenToLocalTransform={this.lightboxScreenToLocal}
                             renderDepth={0}
-                            rootSelected={returnFalse}
                             docViewPath={returnEmptyDoclist}
                             childFilters={returnEmptyFilter}
                             childFiltersByRanges={returnEmptyFilter}
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index ce47a46c3..3b3b43469 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -604,7 +604,6 @@ export class MainView extends React.Component {
                     pinToPres={emptyFunction}
                     docViewPath={returnEmptyDoclist}
                     styleProvider={DefaultStyleProvider}
-                    rootSelected={returnFalse}
                     addDocument={this.addHeaderDoc}
                     removeDocument={this.removeHeaderDoc}
                     fitContentsToBox={returnTrue}
@@ -641,7 +640,6 @@ export class MainView extends React.Component {
                     pinToPres={emptyFunction}
                     docViewPath={returnEmptyDoclist}
                     styleProvider={this._hideUI ? DefaultStyleProvider : undefined}
-                    rootSelected={returnFalse}
                     isContentActive={returnTrue}
                     removeDocument={undefined}
                     ScreenToLocalTransform={this._hideUI ? this.mainScreenToLocalXf : Transform.Identity}
@@ -737,7 +735,6 @@ export class MainView extends React.Component {
                         pinToPres={TabDocView.PinDoc}
                         docViewPath={returnEmptyDoclist}
                         styleProvider={this._sidebarContent.proto === Doc.MyDashboards || this._sidebarContent.proto === Doc.MyFilesystem || this._sidebarContent.proto === Doc.MyTrails ? DashboardStyleProvider : DefaultStyleProvider}
-                        rootSelected={returnFalse}
                         removeDocument={returnFalse}
                         ScreenToLocalTransform={this.mainContainerXf}
                         PanelWidth={this.leftMenuFlyoutWidth}
@@ -766,7 +763,6 @@ export class MainView extends React.Component {
                     addDocument={undefined}
                     addDocTab={DocumentViewInternal.addDocTabFunc}
                     pinToPres={emptyFunction}
-                    rootSelected={returnFalse}
                     removeDocument={returnFalse}
                     ScreenToLocalTransform={this.sidebarScreenToLocal}
                     PanelWidth={this.leftMenuWidth}
@@ -906,7 +902,6 @@ export class MainView extends React.Component {
                     dropAction="embed"
                     setHeight={returnFalse}
                     styleProvider={DefaultStyleProvider}
-                    rootSelected={returnFalse}
                     bringToFront={emptyFunction}
                     select={emptyFunction}
                     isAnyChildContentActive={returnFalse}
@@ -993,7 +988,6 @@ export class MainView extends React.Component {
                 pinToPres={emptyFunction}
                 docViewPath={returnEmptyDoclist}
                 styleProvider={DefaultStyleProvider}
-                rootSelected={returnFalse}
                 addDocument={returnFalse}
                 removeDocument={returnFalse}
                 fitContentsToBox={returnTrue}
diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx
index fbcefd460..dd547c549 100644
--- a/src/client/views/OverlayView.tsx
+++ b/src/client/views/OverlayView.tsx
@@ -222,7 +222,6 @@ export class OverlayView extends React.Component {
                     style={{ top: d.type === DocumentType.PRES ? 0 : undefined, width: NumCast(d._width), height: NumCast(d._height), transform: `translate(${d.overlayX}px, ${d.overlayY}px)` }}>
                     <DocumentView
                         Document={d}
-                        rootSelected={returnFalse}
                         bringToFront={emptyFunction}
                         addDocument={undefined}
                         removeDocument={this.removeOverlayDoc}
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index 76ea9123d..5c7af65ee 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -296,7 +296,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
                         DataDoc={this.dataDoc}
                         renderDepth={1}
                         fitContentsToBox={returnTrue}
-                        rootSelected={returnFalse}
                         styleProvider={DefaultStyleProvider}
                         docViewPath={returnEmptyDoclist}
                         dontCenter={'y'}
diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx
index a3884c9eb..6da228417 100644
--- a/src/client/views/TemplateMenu.tsx
+++ b/src/client/views/TemplateMenu.tsx
@@ -119,7 +119,6 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
                     childFilters={returnEmptyFilter}
                     childFiltersByRanges={returnEmptyFilter}
                     searchFilterDocs={returnEmptyDoclist}
-                    rootSelected={returnFalse}
                     onCheckedClick={this.scriptField}
                     onChildClick={this.scriptField}
                     isAnyChildContentActive={returnFalse}
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 3c555e731..c3aba4754 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -102,7 +102,6 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> {
                     dropAction="embed"
                     setHeight={returnFalse}
                     styleProvider={DefaultStyleProvider}
-                    rootSelected={returnFalse}
                     bringToFront={emptyFunction}
                     select={emptyFunction}
                     isContentActive={returnTrue}
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index 552c19eb3..d4daf2baf 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -817,7 +817,6 @@ class StackedTimelineAnchor extends React.Component<StackedTimelineAnchorProps>
                     searchFilterDocs={returnEmptyDoclist}
                     childFilters={returnEmptyFilter}
                     childFiltersByRanges={returnEmptyFilter}
-                    rootSelected={returnFalse}
                     onClick={script}
                     onDoubleClick={this.props.layoutDoc.autoPlayAnchors ? undefined : doublescript}
                     ignoreAutoHeight={false}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 57ff7515e..582baa7b5 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -678,7 +678,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
                     addDocTab={this.props.addDocTab}
                     onBrowseClick={this.props.onBrowseClick}
                     pinToPres={emptyFunction}
-                    rootSelected={this.props.isSelected}
+                    rootSelected={this.rootSelected}
                     removeDocument={this.props.removeDocument}
                     ScreenToLocalTransform={Transform.Identity}
                     PanelWidth={this.return35}
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 8896e2d61..9dcd09b17 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -6,7 +6,7 @@ import { AclPrivate } from '../../../fields/DocSymbols';
 import { Id } from '../../../fields/FieldSymbols';
 import { List } from '../../../fields/List';
 import { listSpec } from '../../../fields/Schema';
-import { Cast, ScriptCast, StrCast } from '../../../fields/Types';
+import { BoolCast, Cast, ScriptCast, StrCast } from '../../../fields/Types';
 import { WebField } from '../../../fields/URLField';
 import { GetEffectiveAcl, TraceMobx } from '../../../fields/util';
 import { GestureUtils } from '../../../pen-gestures/GestureUtils';
@@ -60,7 +60,7 @@ export function CollectionSubView<X>(moreProps?: X) {
         }
 
         // this returns whether either the collection is selected, or the template that it is part of is selected
-        rootSelected = () => this.props.isSelected() || this.props.rootSelected();
+        rootSelected = () => this.props.isSelected() || BoolCast(this.Document.rootDocument && this.props.rootSelected?.());
 
         // The data field for rendering this collection will be on the this.props.Document unless we're rendering a template in which case we try to use props.DataDoc.
         // When a document has a DataDoc but it's not a template, then it contains its own rendering data, but needs to pass the DataDoc through
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 5bd5cef25..36ea14d92 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -236,7 +236,6 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
                 renderDepth={this.props.renderDepth + 1}
                 isContentActive={this.isContentActive}
                 isDocumentActive={this.isContentActive}
-                rootSelected={returnFalse}
                 forceAutoHeight={true} // needed to make the title resize even if the rest of the tree view is not layout_autoHeight
                 PanelWidth={this.documentTitleWidth}
                 PanelHeight={this.documentTitleHeight}
@@ -335,7 +334,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
                     removeDocument={this.props.removeDocument}
                     addDocTab={this.props.addDocTab}
                     pinToPres={this.props.pinToPres}
-                    rootSelected={this.props.isSelected}
+                    rootSelected={this.rootSelected}
                     ScreenToLocalTransform={Transform.Identity}
                     PanelWidth={this.return35}
                     PanelHeight={this.return35}
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 8abfddcd6..6f8476f10 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -460,7 +460,6 @@ export class TabDocView extends React.Component<TabDocViewProps> {
                     addDocTab={this.addDocTab}
                     ScreenToLocalTransform={this.ScreenToLocalTransform}
                     dontCenter={'y'}
-                    rootSelected={returnFalse}
                     whenChildContentsActiveChanged={this.whenChildContentActiveChanges}
                     focus={this.focusFunc}
                     docViewPath={returnEmptyDoclist}
@@ -599,7 +598,6 @@ export class TabMinimapView extends React.Component<TabMinimapViewProps> {
                     dontRegisterView={true}
                     fieldKey={Doc.LayoutFieldKey(this.props.document)}
                     bringToFront={emptyFunction}
-                    rootSelected={returnFalse}
                     addDocument={returnFalse}
                     moveDocument={returnFalse}
                     removeDocument={returnFalse}
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 03e82577e..ee5f9fd95 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -975,7 +975,6 @@ export class TreeView extends React.Component<TreeViewProps> {
                 treeViewDoc={this.props.treeView.props.Document}
                 addDocument={undefined}
                 addDocTab={this.props.addDocTab}
-                rootSelected={returnFalse}
                 pinToPres={this.props.treeView.props.pinToPres}
                 onClick={this.onChildClick}
                 onDoubleClick={this.onChildDoubleClick}
@@ -1081,7 +1080,6 @@ export class TreeView extends React.Component<TreeViewProps> {
                     ScreenToLocalTransform={this.docTransform}
                     renderDepth={this.props.renderDepth + 1}
                     treeViewDoc={this.props.treeView?.props.Document}
-                    rootSelected={returnFalse}
                     docViewPath={this.props.treeView.props.docViewPath}
                     childFilters={returnEmptyFilter}
                     childFiltersByRanges={returnEmptyFilter}
diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
index a06ed3a2d..96eabd88c 100644
--- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
+++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
@@ -177,7 +177,7 @@ export class CollectionLinearView extends CollectionSubView() {
                     addDocTab={this.props.addDocTab}
                     pinToPres={emptyFunction}
                     dragAction={(this.layoutDoc.childDragAction ?? this.props.childDragAction) as dropActionType}
-                    rootSelected={this.props.isSelected}
+                    rootSelected={this.rootSelected}
                     removeDocument={this.props.removeDocument}
                     ScreenToLocalTransform={docXf}
                     PanelWidth={doc[Width]}
diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
index 2c251d3cf..150b1b46e 100644
--- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
@@ -72,7 +72,6 @@ export class SchemaTableCell extends React.Component<SchemaTableCellProps> {
             searchFilterDocs: returnEmptyDoclist,
             styleProvider: DefaultStyleProvider,
             docViewPath: returnEmptyDoclist,
-            rootSelected: returnFalse,
             isSelected: returnFalse,
             setHeight: returnFalse,
             select: emptyFunction,
diff --git a/src/client/views/newlightbox/NewLightboxView.tsx b/src/client/views/newlightbox/NewLightboxView.tsx
index bde93c761..22b996809 100644
--- a/src/client/views/newlightbox/NewLightboxView.tsx
+++ b/src/client/views/newlightbox/NewLightboxView.tsx
@@ -302,7 +302,6 @@ export class NewLightboxView extends React.Component<LightboxViewProps> {
                         styleProvider={DefaultStyleProvider}
                         ScreenToLocalTransform={this.newLightboxScreenToLocal}
                         renderDepth={0}
-                        rootSelected={returnFalse}
                         docViewPath={returnEmptyDoclist}
                         childFilters={this.docFilters}
                         childFiltersByRanges={returnEmptyFilter}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 6e50a6b0f..b6e90cbf4 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -176,7 +176,7 @@ export interface DocumentViewSharedProps {
     searchFilterDocs: () => Doc[];
     layout_showTitle?: () => string;
     whenChildContentsActiveChanged: (isActive: boolean) => void;
-    rootSelected: () => boolean; // whether the root of a template has been selected
+    rootSelected?: () => 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[], annotationKey?: string) => boolean;
diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
index ba5370360..7119ae235 100644
--- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
@@ -324,7 +324,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
                 //background={SettingsManager.userBackgroundColor}
                 icon={this.Icon(color)!}
                 label={this.label}
-                onPointerDown={() => script.script.run({ this: this.Document, value: !toggleStatus, _readOnly_: false })}
+                onPointerDown={() => script.script.run({ this: this.Document, self:this.Document, value: !toggleStatus, _readOnly_: false })}
             />
         );
     }
diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx
index 6f99b7c28..39e0279fc 100644
--- a/src/client/views/nodes/KeyValuePair.tsx
+++ b/src/client/views/nodes/KeyValuePair.tsx
@@ -65,7 +65,6 @@ export class KeyValuePair extends React.Component<KeyValuePairProps> {
             styleProvider: DefaultStyleProvider,
             docViewPath: returnEmptyDoclist,
             fieldKey: this.props.keyName,
-            rootSelected: returnFalse,
             isSelected: returnFalse,
             setHeight: returnFalse,
             select: emptyFunction,
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index 7e4f1da8e..ad5324b3e 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -260,7 +260,6 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
                             }}
                             Document={this._targetDoc!}
                             moveDocument={returnFalse}
-                            rootSelected={returnFalse}
                             styleProvider={this.props.docProps?.styleProvider}
                             docViewPath={returnEmptyDoclist}
                             ScreenToLocalTransform={Transform.Identity}
diff --git a/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx b/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
index 66c47d131..9608e2dd0 100644
--- a/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
+++ b/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
@@ -68,7 +68,6 @@ export class MapBoxInfoWindow extends React.Component<MapBoxInfoWindowProps & Vi
                             NativeDimScaling={returnOne}
                             isContentActive={returnTrue}
                             chromeHidden={true}
-                            rootSelected={returnFalse}
                             childHideResizeHandles={returnTrue}
                             childHideDecorationTitle={returnTrue}
                             childLayoutFitWidth={this.childLayoutFitWidth}
diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx
index e8b9a98b7..95743a036 100644
--- a/src/client/views/nodes/formattedText/DashDocView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocView.tsx
@@ -202,7 +202,6 @@ export class DashDocViewInternal extends React.Component<IDashDocViewInternal> {
                 <DocumentView
                     Document={this._finalLayout}
                     addDocument={returnFalse}
-                    rootSelected={returnFalse} //{this._textBox.props.isSelected}
                     removeDocument={this.removeDoc}
                     isDocumentActive={returnFalse}
                     isContentActive={this.isContentActive}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 31c0545d4..252a7d884 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -318,7 +318,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
             DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(this.props.docViewPath().lastElement(), () => this.getAnchor(true), targetCreator), e.pageX, e.pageY);
         });
         const coordsB = this._editorView!.coordsAtPos(this._editorView!.state.selection.to);
-        this.props.rootSelected() && AnchorMenu.Instance.jumpTo(coordsB.left, coordsB.bottom);
+        this.props.rootSelected?.() && AnchorMenu.Instance.jumpTo(coordsB.left, coordsB.bottom);
         let ele: Opt<HTMLDivElement> = undefined;
         try {
             const contents = window.getSelection()?.getRangeAt(0).cloneContents();
@@ -390,7 +390,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
                     this._editorView.updateState(EditorState.fromJSON(this.config, json));
                 }
             }
-            if (window.getSelection()?.isCollapsed && this.props.rootSelected()) {
+            if (window.getSelection()?.isCollapsed && this.props.rootSelected?.()) {
                 AnchorMenu.Instance.fadeOut(true);
             }
         }
@@ -1258,7 +1258,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
         );
 
         this._disposers.selected = reaction(
-            () => this.props.rootSelected(),
+            () => this.props.rootSelected?.(),
             action(selected => {
                 //selected && setTimeout(() => this.prepareForTyping());
                 if (FormattedTextBox._globalHighlights.has('Bold Text')) {
@@ -1453,7 +1453,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
         const self = this;
         return new Plugin({
             view(newView) {
-                runInAction(() => self.props.rootSelected() && RichTextMenu.Instance && (RichTextMenu.Instance.view = newView));
+                runInAction(() => self.props.rootSelected?.() && RichTextMenu.Instance && (RichTextMenu.Instance.view = newView));
                 return new RichTextMenuPlugin({ editorProps: this.props });
             },
         });
@@ -1628,7 +1628,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
         this._downTime = Date.now();
         this._hadDownFocus = this.ProseRef?.children[0].className.includes('focused') ?? false;
         FormattedTextBoxComment.textBox = this;
-        if (e.button === 0 && (this.props.rootSelected() || this.props.rootSelected()) && !e.altKey && !e.ctrlKey && !e.metaKey) {
+        if (e.button === 0 && this.props.rootSelected?.() && !e.altKey && !e.ctrlKey && !e.metaKey) {
             if (e.clientX < this.ProseRef!.getBoundingClientRect().right) {
                 // stop propagation if not in sidebar, otherwise nested boxes will lose focus to outer boxes.
                 e.stopPropagation(); // if the text box's content is active, then it consumes all down events
@@ -1665,7 +1665,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
     @action
     onDoubleClick = (e: React.MouseEvent): void => {
         FormattedTextBoxComment.textBox = this;
-        if (e.button === 0 && this.props.rootSelected() && !e.altKey && !e.ctrlKey && !e.metaKey) {
+        if (e.button === 0 && this.props.rootSelected?.() && !e.altKey && !e.ctrlKey && !e.metaKey) {
             if (e.clientX < this.ProseRef!.getBoundingClientRect().right) {
                 // stop propagation if not in sidebar
                 e.stopPropagation(); // if the text box is selected, then it consumes all click events
@@ -1676,7 +1676,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
         }
         FormattedTextBoxComment.Hide();
 
-        if (e.buttons === 1 && this.props.rootSelected() && !e.altKey) {
+        if (e.buttons === 1 && this.props.rootSelected?.() && !e.altKey) {
             e.stopPropagation();
         }
     };
@@ -1687,7 +1687,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
     };
     @action
     onFocused = (e: React.FocusEvent): void => {
-        console.log('FOCUSED = ' + this.layoutDoc.title + ' ' + this.props.rootSelected());
+        console.log('FOCUSED = ' + this.layoutDoc.title + ' ' + this.props.rootSelected?.());
         //applyDevTools.applyDevTools(this._editorView);
         this.ProseRef?.children[0] === e.nativeEvent.target && this._editorView && RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this.props, this.layoutDoc);
         e.stopPropagation();
@@ -1723,7 +1723,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
                 this._editorView!.dispatch(this._editorView!.state.tr.setSelection(NodeSelection.create(this._editorView!.state.doc, pcords.pos)));
             }
         }
-        if (this.props.rootSelected()) {
+        if (this.props.rootSelected?.()) {
             // if text box is selected, then it consumes all click events
             (e.nativeEvent as any).handledByInnerReactInstance = true;
             this.hitBulletTargets(e.clientX, e.clientY, !this._editorView?.state.selection.empty || this._forceUncollapse, false, this._forceDownNode, e.shiftKey);
@@ -1737,7 +1737,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
         clearStyleSheetRules(FormattedTextBox._bulletStyleSheet);
         const clickPos = this._editorView!.posAtCoords({ left: x, top: y });
         let olistPos = clickPos?.pos;
-        if (clickPos && olistPos && this.props.rootSelected()) {
+        if (clickPos && olistPos && this.props.rootSelected?.()) {
             const clickNode = this._editorView?.state.doc.nodeAt(olistPos);
             const nodeBef = this._editorView?.state.doc.nodeAt(Math.max(0, olistPos - 1));
             olistPos = nodeBef?.type === this._editorView?.state.schema.nodes.ordered_list ? olistPos - 1 : olistPos;
@@ -1774,7 +1774,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
 
     @action
     onBlur = (e: any) => {
-        console.log('BLUREd = ' + this.layoutDoc.title + ' ' + this.props.rootSelected());
         if (this.ProseRef?.children[0] !== e.nativeEvent.target) return;
         if (!(this.EditorView?.state.selection instanceof NodeSelection) || this.EditorView.state.selection.node.type !== this.EditorView.state.schema.nodes.footnote) {
             const stordMarks = this._editorView?.state.storedMarks?.slice();
@@ -1787,7 +1786,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
                 tr && this._editorView.dispatch(tr);
             }
         }
-        if (RichTextMenu.Instance?.view === this._editorView && !this.props.rootSelected()) {
+        if (RichTextMenu.Instance?.view === this._editorView && !this.props.rootSelected?.()) {
             RichTextMenu.Instance?.updateMenu(undefined, undefined, undefined, undefined);
         }
         FormattedTextBox._hadSelection = window.getSelection()?.toString() !== '';
@@ -2088,7 +2087,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
             // prevent default if selected || child is active  but this doc isn't scrollable
             if (
                 (this._scrollRef.current?.scrollHeight ?? 0) <= Math.ceil((height ? height : this.props.PanelHeight()) / scale) && //
-                (this.props.rootSelected() || this.isAnyChildContentActive())
+                (this.props.rootSelected?.() || this.isAnyChildContentActive())
             ) {
                 e.preventDefault();
             }
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index 7f9bfe753..816a89489 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -186,7 +186,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
 
     // finds font sizes and families in selection
     getActiveAlignment() {
-        if (this.view && this.TextView?.props.rootSelected()) {
+        if (this.view && this.TextView?.props.rootSelected?.()) {
             const path = (this.view.state.selection.$from as any).path;
             for (let i = path.length - 3; i < path.length && i >= 0; i -= 3) {
                 if (path[i]?.type === this.view.state.schema.nodes.paragraph || path[i]?.type === this.view.state.schema.nodes.heading) {
@@ -199,7 +199,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
 
     // finds font sizes and families in selection
     getActiveListStyle() {
-        if (this.view && this.TextView?.props.rootSelected()) {
+        if (this.view && this.TextView?.props.rootSelected?.()) {
             const path = (this.view.state.selection.$from as any).path;
             for (let i = 0; i < path.length; i += 3) {
                 if (path[i].type === this.view.state.schema.nodes.ordered_list) {
@@ -219,7 +219,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
         const activeSizes = new Set<string>();
         const activeColors = new Set<string>();
         const activeHighlights = new Set<string>();
-        if (this.view && this.TextView?.props.rootSelected()) {
+        if (this.view && this.TextView?.props.rootSelected?.()) {
             const state = this.view.state;
             const pos = this.view.state.selection.$from;
             const marks: Mark[] = [...(state.storedMarks ?? [])];
@@ -254,7 +254,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
     //finds all active marks on selection in given group
     getActiveMarksOnSelection() {
         let activeMarks: MarkType[] = [];
-        if (!this.view || !this.TextView?.props.rootSelected()) return activeMarks;
+        if (!this.view || !this.TextView?.props.rootSelected?.()) return activeMarks;
 
         const markGroup = [schema.marks.noAutoLinkAnchor, schema.marks.strong, schema.marks.em, schema.marks.underline, schema.marks.strikethrough, schema.marks.superscript, schema.marks.subscript];
         if (this.view.state.storedMarks) return this.view.state.storedMarks.map(mark => mark.type);
@@ -447,7 +447,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
         this.layoutDoc && (this.layoutDoc.layout_centered = !this.layoutDoc.layout_centered);
     };
     align = (view: EditorView, dispatch: any, alignment: 'left' | 'right' | 'center') => {
-        if (this.TextView?.props.rootSelected()) {
+        if (this.TextView?.props.rootSelected?.()) {
             var tr = view.state.tr;
             view.state.doc.nodesBetween(view.state.selection.from, view.state.selection.to, (node, pos, parent, index) => {
                 if ([schema.nodes.paragraph, schema.nodes.heading].includes(node.type)) {
diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx
index 6a8edee0d..b104e8b70 100644
--- a/src/client/views/nodes/trails/PresElementBox.tsx
+++ b/src/client/views/nodes/trails/PresElementBox.tsx
@@ -116,7 +116,6 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
                     childFilters={this.props.childFilters}
                     childFiltersByRanges={this.props.childFiltersByRanges}
                     searchFilterDocs={this.props.searchFilterDocs}
-                    rootSelected={returnFalse}
                     addDocument={returnFalse}
                     removeDocument={returnFalse}
                     fitContentsToBox={returnTrue}
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index f1686a6ea..1dfcf174e 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -105,7 +105,6 @@ export class TopBar extends React.Component {
                     dropAction="embed"
                     setHeight={returnFalse}
                     styleProvider={DefaultStyleProvider}
-                    rootSelected={returnFalse}
                     bringToFront={emptyFunction}
                     select={emptyFunction}
                     isContentActive={returnTrue}
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 97f771c16..791ce8d8f 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -388,7 +388,6 @@ export class MobileInterface extends React.Component {
                     addDocument={returnFalse}
                     addDocTab={returnFalse}
                     pinToPres={emptyFunction}
-                    rootSelected={returnFalse}
                     removeDocument={undefined}
                     ScreenToLocalTransform={Transform.Identity}
                     PanelWidth={this.returnWidth}
-- 
cgit v1.2.3-70-g09d2


From 9ae07e29f41df9d64985c25b67054843a99a0224 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Fri, 1 Dec 2023 02:33:04 -0500
Subject: converted props.DataDoc to props.TemplateDataDocument and fixed so
 that it's always undefined unless it's a template.  converted references from
 rootDocument to props.TemplateDataDocument.

---
 src/client/documents/Documents.ts                  |  2 +-
 src/client/views/DocComponent.tsx                  | 13 +++----
 src/client/views/GestureOverlay.tsx                |  1 -
 src/client/views/LightboxView.tsx                  |  1 -
 src/client/views/MainView.tsx                      |  6 ----
 src/client/views/MarqueeAnnotator.tsx              |  2 +-
 src/client/views/PropertiesButtons.tsx             |  2 +-
 src/client/views/PropertiesView.tsx                |  2 +-
 src/client/views/SidebarAnnos.tsx                  |  2 +-
 src/client/views/StyleProvider.tsx                 | 21 ++++++-----
 .../views/collections/CollectionCarousel3DView.tsx |  4 +--
 .../views/collections/CollectionCarouselView.tsx   |  4 +--
 .../collections/CollectionMasonryViewFieldRow.tsx  |  2 +-
 src/client/views/collections/CollectionMenu.tsx    |  1 -
 .../views/collections/CollectionNoteTakingView.tsx | 10 +++---
 .../collections/CollectionNoteTakingViewColumn.tsx |  8 ++---
 .../collections/CollectionStackedTimeline.tsx      |  2 +-
 .../views/collections/CollectionStackingView.tsx   | 10 +++---
 .../CollectionStackingViewFieldColumn.tsx          |  8 ++---
 src/client/views/collections/CollectionSubView.tsx | 24 +++++++------
 .../views/collections/CollectionTreeView.tsx       |  8 ++---
 src/client/views/collections/TabDocView.tsx        |  2 +-
 src/client/views/collections/TreeView.tsx          |  4 +--
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 12 +++----
 .../collectionGrid/CollectionGridView.tsx          |  4 +--
 .../CollectionMulticolumnView.tsx                  |  2 +-
 .../CollectionMultirowView.tsx                     |  2 +-
 .../collectionSchema/CollectionSchemaView.tsx      |  2 --
 .../collectionSchema/SchemaTableCell.tsx           |  2 +-
 src/client/views/linking/LinkPopup.tsx             |  1 -
 src/client/views/newlightbox/NewLightboxView.tsx   |  1 -
 .../views/nodes/CollectionFreeFormDocumentView.tsx |  4 +--
 src/client/views/nodes/ComparisonBox.tsx           |  2 +-
 src/client/views/nodes/DocumentContentsView.tsx    | 41 ++++++++++++----------
 src/client/views/nodes/DocumentView.tsx            | 20 +++++------
 src/client/views/nodes/FieldView.tsx               |  1 -
 src/client/views/nodes/FontIconBox/FontIconBox.tsx | 30 ++++++++--------
 src/client/views/nodes/KeyValuePair.tsx            |  1 -
 src/client/views/nodes/LoadingBox.tsx              |  2 +-
 src/client/views/nodes/MapBox/MapBox.tsx           |  4 +--
 src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx | 14 ++++----
 src/client/views/nodes/ScreenshotBox.tsx           |  8 ++---
 .../views/nodes/formattedText/FormattedTextBox.tsx | 13 ++++---
 .../formattedText/ProsemirrorExampleTransfer.ts    |  4 +--
 .../views/nodes/importBox/ImportElementBox.tsx     |  1 -
 src/client/views/nodes/trails/PresElementBox.tsx   |  3 +-
 src/client/views/topbar/TopBar.tsx                 |  1 -
 src/fields/Doc.ts                                  | 12 +++----
 src/mobile/MobileInterface.tsx                     |  1 -
 49 files changed, 158 insertions(+), 169 deletions(-)

(limited to 'src/client/views/collections/CollectionStackedTimeline.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index dfb9f4327..929660ff4 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -1678,7 +1678,7 @@ export namespace DocUtils {
                         newDoc.x = x;
                         newDoc.y = y;
                         EquationBox.SelectOnLoad = newDoc[Id];
-                        if (newDoc.type === DocumentType.RTF) FormattedTextBox.SelectOnLoad = newDoc[Id];
+                        if (newDoc.type === DocumentType.RTF) FormattedTextBox.SetSelectOnLoad(newDoc);
                         if (pivotField) {
                             newDoc[pivotField] = pivotValue;
                         }
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 04956d974..d104eb90c 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -16,7 +16,6 @@ import { CollectionFreeFormView } from './collections/collectionFreeForm';
 ///  DocComponent returns a generic React base class used by views that don't have 'fieldKey' props (e.g.,CollectionFreeFormDocumentView, DocumentView)
 export interface DocComponentProps {
     Document: Doc;
-    fieldKey?: string;
     LayoutTemplate?: () => Opt<Doc>;
     LayoutTemplateString?: string;
 }
@@ -34,10 +33,6 @@ export function DocComponent<P extends DocComponentProps>() {
         @computed get dataDoc() {
             return this.props.Document[DocData] as Doc;
         }
-        // key where data is stored
-        @computed get fieldKey() {
-            return this.props.fieldKey;
-        }
     }
     return Component;
 }
@@ -45,7 +40,7 @@ export function DocComponent<P extends DocComponentProps>() {
 /// FieldViewBoxProps  -  a generic base class for field views that are not annotatable (e.g. InkingStroke, ColorBox)
 interface ViewBoxBaseProps {
     Document: Doc;
-    DataDoc?: Doc;
+    TemplateDataDocument?: Doc;
     DocumentView?: () => DocumentView;
     fieldKey: string;
     isSelected: () => boolean;
@@ -65,7 +60,7 @@ export function ViewBoxBaseComponent<P extends ViewBoxBaseProps>() {
         }
         // This is the data part of a document -- ie, the data that is constant across all views of the document
         @computed get dataDoc() {
-            return this.props.DataDoc && (this.props.Document.isTemplateForField || this.props.Document.isTemplateDoc) ? this.props.DataDoc : this.props.Document[DocData];
+            return this.props.Document.isTemplateForField || this.props.Document.isTemplateDoc ? this.props.TemplateDataDocument ?? this.props.Document[DocData] : this.props.Document[DocData];
         }
         // key where data is stored
         @computed get fieldKey() {
@@ -78,7 +73,7 @@ export function ViewBoxBaseComponent<P extends ViewBoxBaseProps>() {
 ///  DocAnnotatbleComponent -return a base class for React views of document fields that are annotatable *and* interactive when selected (e.g., pdf, image)
 export interface ViewBoxAnnotatableProps {
     Document: Doc;
-    DataDoc?: Doc;
+    TemplateDataDocument?: Doc;
     fieldKey: string;
     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)
     isContentActive: () => boolean | undefined;
@@ -102,7 +97,7 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps>()
         }
         // This is the data part of a document -- ie, the data that is constant across all views of the document
         @computed get dataDoc() {
-            return this.props.DataDoc && (this.props.Document.isTemplateForField || this.props.Document.isTemplateDoc) ? this.props.DataDoc : this.props.Document[DocData];
+            return this.props.Document.isTemplateForField || this.props.Document.isTemplateDoc ? this.props.TemplateDataDocument ?? this.props.Document[DocData] : this.props.Document[DocData];
         }
 
         // key where data is stored
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 508339efc..559f245d9 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -466,7 +466,6 @@ export class GestureOverlay extends React.Component<React.PropsWithChildren<Gest
         this._clipboardDoc = (
             <DocumentView
                 Document={doc}
-                DataDoc={undefined}
                 addDocument={undefined}
                 addDocTab={returnFalse}
                 pinToPres={emptyFunction}
diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx
index 15266071f..de2ce3189 100644
--- a/src/client/views/LightboxView.tsx
+++ b/src/client/views/LightboxView.tsx
@@ -247,7 +247,6 @@ export class LightboxView extends React.Component<LightboxViewProps> {
                         <DocumentView
                             ref={action((r: DocumentView | null) => (this._docView = r !== null ? r : undefined))}
                             Document={this._doc}
-                            DataDoc={undefined}
                             PanelWidth={this.lightboxWidth}
                             PanelHeight={this.lightboxHeight}
                             LayoutTemplate={this.lightboxDocTemplate}
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 3b3b43469..2e3817cb6 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -599,7 +599,6 @@ export class MainView extends React.Component {
                 <DocumentView
                     key="headerBarDoc"
                     Document={this.headerBarDoc}
-                    DataDoc={undefined}
                     addDocTab={DocumentViewInternal.addDocTabFunc}
                     pinToPres={emptyFunction}
                     docViewPath={returnEmptyDoclist}
@@ -634,7 +633,6 @@ export class MainView extends React.Component {
                 <DocumentView
                     key="main"
                     Document={this.mainContainer!}
-                    DataDoc={undefined}
                     addDocument={undefined}
                     addDocTab={DocumentViewInternal.addDocTabFunc}
                     pinToPres={emptyFunction}
@@ -729,7 +727,6 @@ export class MainView extends React.Component {
                 <div className="mainView-contentArea">
                     <DocumentView
                         Document={this._sidebarContent.proto || this._sidebarContent}
-                        DataDoc={undefined}
                         addDocument={undefined}
                         addDocTab={DocumentViewInternal.addDocTabFunc}
                         pinToPres={TabDocView.PinDoc}
@@ -759,7 +756,6 @@ export class MainView extends React.Component {
             <div key="menu" className="mainView-leftMenuPanel" style={{ background: SettingsManager.userBackgroundColor, display: LightboxView.LightboxDoc ? 'none' : undefined }}>
                 <DocumentView
                     Document={Doc.MyLeftSidebarMenu}
-                    DataDoc={undefined}
                     addDocument={undefined}
                     addDocTab={DocumentViewInternal.addDocTabFunc}
                     pinToPres={emptyFunction}
@@ -897,7 +893,6 @@ export class MainView extends React.Component {
             <div className="mainView-docButtons" style={{ background: SettingsManager.userBackgroundColor, color: SettingsManager.userColor }} ref={this._docBtnRef}>
                 <CollectionLinearView
                     Document={Doc.MyDockedBtns}
-                    DataDoc={undefined}
                     fieldKey="data"
                     dropAction="embed"
                     setHeight={returnFalse}
@@ -983,7 +978,6 @@ export class MainView extends React.Component {
                 select={returnFalse}
                 isSelected={returnFalse}
                 Document={this.headerBarDoc}
-                DataDoc={undefined}
                 addDocTab={returnFalse}
                 pinToPres={emptyFunction}
                 docViewPath={returnEmptyDoclist}
diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx
index b9b7e3f0b..70a44a08a 100644
--- a/src/client/views/MarqueeAnnotator.tsx
+++ b/src/client/views/MarqueeAnnotator.tsx
@@ -185,7 +185,7 @@ export class MarqueeAnnotator extends React.Component<MarqueeAnnotatorProps> {
 
             const targetCreator = (annotationOn: Doc | undefined) => {
                 const target = DocUtils.GetNewTextDoc('Note linked to ' + this.props.Document.title, 0, 0, 100, 100, undefined, annotationOn, undefined, 'yellow');
-                FormattedTextBox.SelectOnLoad = target[Id];
+                FormattedTextBox.SetSelectOnLoad(target);
                 return target;
             };
             DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(this.props.docView(), sourceAnchorCreator, targetCreator), e.pageX, e.pageY, {
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 7a8a0bfb9..6635aabf9 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -91,7 +91,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
                     //containerDoc._freeform_fitContentsToBox =
                     containerDoc._isLightbox = !containerDoc._isLightbox;
                     //containerDoc._xPadding = containerDoc._yPadding = containerDoc._isLightbox ? 10 : undefined;
-                    const containerContents = DocListCast(dv.dataDoc[dv.props.fieldKey ?? Doc.LayoutFieldKey(containerDoc)]);
+                    const containerContents = DocListCast(dv.dataDoc[Doc.LayoutFieldKey(containerDoc)]);
                     //dv.Docuemnt.onClick = ScriptField.MakeScript('{self.data = undefined; documentView.select(false)}', { documentView: 'any' });
                     containerContents.forEach(doc => LinkManager.Links(doc).forEach(link => (link.link_displayLine = false)));
                 });
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index cde7eeb08..c5b0528af 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -293,7 +293,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
                 <div ref={this.propertiesDocViewRef} style={{ pointerEvents: 'none', display: 'inline-block', height: panelHeight() }} key={this.selectedDoc[Id]}>
                     <DocumentView
                         Document={this.selectedDoc}
-                        DataDoc={this.dataDoc}
+                        TemplateDataDocument={Doc.AreProtosEqual(this.dataDoc, this.selectedDoc) ? undefined : this.dataDoc}
                         renderDepth={1}
                         fitContentsToBox={returnTrue}
                         styleProvider={DefaultStyleProvider}
diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx
index 9377aabe9..8e62ed999 100644
--- a/src/client/views/SidebarAnnos.tsx
+++ b/src/client/views/SidebarAnnos.tsx
@@ -77,7 +77,7 @@ export class SidebarAnnos extends React.Component<FieldViewProps & ExtraProps> {
             _text_fontSize: StrCast(Doc.UserDoc().fontSize),
             _text_fontFamily: StrCast(Doc.UserDoc().fontFamily),
         });
-        FormattedTextBox.SelectOnLoad = target[Id];
+        FormattedTextBox.SetSelectOnLoad(target);
         FormattedTextBox.DontSelectInitialText = true;
         const link = DocUtils.MakeLink(anchor, target, { link_relationship: 'inline comment:comment on' });
         link && (link.link_displayLine = false);
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index fa2768d79..2dd58fa80 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -64,6 +64,9 @@ function toggleLockedPosition(doc: Doc) {
 export function testDocProps(toBeDetermined: any): toBeDetermined is DocumentViewProps {
     return toBeDetermined?.isContentActive ? toBeDetermined : undefined;
 }
+export function testFieldProps(toBeDetermined: any): toBeDetermined is FieldViewProps {
+    return toBeDetermined?.isContentActive ? toBeDetermined : undefined;
+}
 
 export function wavyBorderPath(pw: number, ph: number, inset: number = 0.05) {
     return `M ${pw * 0.5} ${ph * inset}   C ${pw * 0.6} ${ph * inset} ${pw * (1 - 2 * inset)} 0 ${pw * (1 - inset)} ${ph * inset}   C ${pw} ${ph * (2 * inset)} ${pw * (1 - inset)} ${ph * 0.25} ${pw * (1 - inset)} ${ph * 0.3}   C ${
@@ -77,19 +80,20 @@ export function wavyBorderPath(pw: number, ph: number, inset: number = 0.05) {
 
 // a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab
 //
-export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string): any {
+export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps | FieldViewProps>, property: string): any {
     const remoteDocHeader = 'author;author_date;noMargin';
     const docProps = testDocProps(props) ? props : undefined;
+    const fieldProps = testFieldProps(props) ? props : undefined;
     const selected = property.includes(':selected');
     const isCaption = property.includes(':caption');
     const isAnchor = property.includes(':anchor');
     const isContent = property.includes(':content');
     const isAnnotated = property.includes(':annotated');
-    const isInk = () => doc?._layout_isSvg && !props?.LayoutTemplateString;
+    const isInk = () => doc?._layout_isSvg && !docProps?.LayoutTemplateString;
     const isOpen = property.includes(':open');
     const isEmpty = property.includes(':empty');
     const boxBackground = property.includes(':box');
-    const fieldKey = props?.fieldKey ? props.fieldKey + '_' : isCaption ? 'caption_' : '';
+    const fieldKey = fieldProps?.fieldKey ? fieldProps.fieldKey + '_' : isCaption ? 'caption_' : '';
     const lockedPosition = () => doc && BoolCast(doc._lockedPosition);
     const titleHeight = () => props?.styleProvider?.(doc, props, StyleProp.TitleHeight);
     const backgroundCol = () => props?.styleProvider?.(doc, props, StyleProp.BackgroundColor);
@@ -132,20 +136,21 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
             return  undefined;
         case StyleProp.DocContents:return undefined;
         case StyleProp.WidgetColor:return isAnnotated ? Colors.LIGHT_BLUE : 'dimgrey';
-        case StyleProp.Opacity:    return props?.LayoutTemplateString?.includes(KeyValueBox.name) ? 1 : doc?.text_inlineAnnotations ? 0 :  Cast(doc?._opacity, "number", Cast(doc?.opacity, 'number', null));
+        case StyleProp.Opacity:    return docProps?.LayoutTemplateString?.includes(KeyValueBox.name) ? 1 : doc?.text_inlineAnnotations ? 0 :  Cast(doc?._opacity, "number", Cast(doc?.opacity, 'number', null));
         case StyleProp.HideLinkBtn:return props?.hideLinkButton || (!selected && doc?.layout_hideLinkButton);
         case StyleProp.FontSize:   return StrCast(doc?.[fieldKey + 'fontSize'],   StrCast(doc?._text_fontSize,   StrCast(Doc.UserDoc().fontSize)));
         case StyleProp.FontFamily: return StrCast(doc?.[fieldKey + 'fontFamily'], StrCast(doc?._text_fontFamily, StrCast(Doc.UserDoc().fontFamily)));
         case StyleProp.FontWeight: return StrCast(doc?.[fieldKey + 'fontWeight'], StrCast(doc?._text_fontWeight, StrCast(Doc.UserDoc().fontWeight)));
         case StyleProp.FillColor:  return StrCast(doc?._fillColor, StrCast(doc?.fillColor, 'transparent'));
         case StyleProp.ShowCaption:return doc?._type_collection === CollectionViewType.Carousel || props?.hideCaptions ? undefined : StrCast(doc?._layout_showCaption);
-        case StyleProp.TitleHeight:return (props?.ScreenToLocalTransform().Scale ?? 1)*(props?.NativeDimScaling?.()??1) * NumCast(Doc.UserDoc().headerHeight,30)
+        case StyleProp.TitleHeight:
+            return (props?.ScreenToLocalTransform().Scale ?? 1)*(props?.NativeDimScaling?.()??1) * NumCast(Doc.UserDoc().headerHeight,30)
         case StyleProp.ShowTitle:
             return (
                 (doc &&
-                    !props?.LayoutTemplateString &&
+                    !docProps?.LayoutTemplateString &&
                     !doc.presentation_targetDoc &&
-                    !props?.LayoutTemplateString?.includes(KeyValueBox.name) &&
+                    !docProps?.LayoutTemplateString?.includes(KeyValueBox.name) &&
                     props?.layout_showTitle?.() !== '' &&
                     StrCast(
                         doc._layout_showTitle,
@@ -259,7 +264,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
             }
         }
         case StyleProp.PointerEvents:
-            if (StrCast(doc?.pointerEvents) && !props?.LayoutTemplateString?.includes(KeyValueBox.name)) return StrCast(doc!.pointerEvents); // honor pointerEvents field (set by lock button usually) if it's not a keyValue view of the Doc
+            if (StrCast(doc?.pointerEvents) && !docProps?.LayoutTemplateString?.includes(KeyValueBox.name)) return StrCast(doc!.pointerEvents); // honor pointerEvents field (set by lock button usually) if it's not a keyValue view of the Doc
             if (docProps?.DocumentView?.().ComponentView?.overridePointerEvents?.() !== undefined) return docProps?.DocumentView?.().ComponentView?.overridePointerEvents?.();
             if (DocumentView.ExploreMode || doc?.layout_unrendered) return isInk() ? 'visiblePainted' : 'all';
             if (props?.pointerEvents?.() === 'none') return 'none';
diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx
index b3d8874d0..6715e5675 100644
--- a/src/client/views/collections/CollectionCarousel3DView.tsx
+++ b/src/client/views/collections/CollectionCarousel3DView.tsx
@@ -61,6 +61,8 @@ export class CollectionCarousel3DView extends CollectionSubView() {
             return (
                 <DocumentView
                     {...this.props}
+                    Document={childPair.layout}
+                    TemplateDataDocument={childPair.data}
                     //suppressSetHeight={true}
                     NativeWidth={returnZero}
                     NativeHeight={returnZero}
@@ -70,8 +72,6 @@ export class CollectionCarousel3DView extends CollectionSubView() {
                     renderDepth={this.props.renderDepth + 1}
                     LayoutTemplate={this.props.childLayoutTemplate}
                     LayoutTemplateString={this.props.childLayoutString}
-                    Document={childPair.layout}
-                    DataDoc={childPair.data}
                     focus={this.focus}
                     ScreenToLocalTransform={this.childScreenToLocal}
                     isContentActive={this.isChildContentActive}
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index bcccf0044..c873ef891 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -71,7 +71,7 @@ export class CollectionCarouselView extends CollectionSubView() {
                         LayoutTemplate={this.props.childLayoutTemplate}
                         LayoutTemplateString={this.props.childLayoutString}
                         Document={curDoc.layout}
-                        DataDoc={curDoc.layout.resolvedDataDoc as Doc}
+                        TemplateDataDocument={curDoc.layout.resolvedDataDoc as Doc}
                         PanelHeight={this.panelHeight}
                         bringToFront={returnFalse}
                     />
@@ -87,7 +87,7 @@ export class CollectionCarouselView extends CollectionSubView() {
                         marginLeft: this.marginX,
                         width: `calc(100% - ${this.marginX * 2}px)`,
                     }}>
-                    <FormattedTextBox key={index} {...captionProps} fieldKey={show_captions} styleProvider={this.captionStyleProvider} Document={curDoc.layout} DataDoc={undefined} />
+                    <FormattedTextBox key={index} {...captionProps} fieldKey={show_captions} styleProvider={this.captionStyleProvider} Document={curDoc.layout} TemplateDataDocument={undefined} />
                 </div>
             </>
         );
diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index 06522b85e..a9b5f401d 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -155,7 +155,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
         const key = this.props.pivotField;
         const newDoc = Docs.Create.TextDocument('', { _layout_autoHeight: true, _width: 200, _layout_fitWidth: true, title: value });
         const onLayoutDoc = this.onLayoutDoc(key);
-        FormattedTextBox.SelectOnLoad = newDoc[Id];
+        FormattedTextBox.SetSelectOnLoad(newDoc);
         FormattedTextBox.SelectOnLoadChar = value;
         (onLayoutDoc ? newDoc : newDoc[DocData])[key] = this.getValue(this.props.heading);
         const docs = this.props.parent.childDocList;
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index c3aba4754..8b3531da8 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -97,7 +97,6 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> {
             <div className="collectionMenu-contMenuButtons" ref={this._docBtnRef} style={{ height: this.props.panelHeight() }}>
                 <CollectionLinearView
                     Document={selDoc}
-                    DataDoc={undefined}
                     fieldKey="data"
                     dropAction="embed"
                     setHeight={returnFalse}
diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx
index 01915f2f7..e92cb353f 100644
--- a/src/client/views/collections/CollectionNoteTakingView.tsx
+++ b/src/client/views/collections/CollectionNoteTakingView.tsx
@@ -221,7 +221,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
     blockPointerEventsWhenDragging = () => (this.docsDraggedRowCol.length ? 'none' : undefined);
     // getDisplayDoc returns the rules for displaying a document in this view (ie. DocumentView)
     getDisplayDoc(doc: Doc, width: () => number) {
-        const dataDoc = !doc.isTemplateDoc && !doc.isTemplateForField ? undefined : this.props.DataDoc;
+        const dataDoc = !doc.isTemplateDoc && !doc.isTemplateForField ? undefined : this.props.TemplateDataDocument;
         const height = () => this.getDocHeight(doc);
         let dref: Opt<DocumentView>;
         const noteTakingDocTransform = () => this.getDocTransform(doc, dref);
@@ -229,7 +229,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
             <DocumentView
                 ref={r => (dref = r || undefined)}
                 Document={doc}
-                DataDoc={dataDoc ?? (!Doc.AreProtosEqual(doc[DocData], doc) ? doc[DocData] : undefined)}
+                TemplateDataDocument={dataDoc ?? (!Doc.AreProtosEqual(doc[DocData], doc) ? doc[DocData] : undefined)}
                 pointerEvents={this.blockPointerEventsWhenDragging}
                 renderDepth={this.props.renderDepth + 1}
                 PanelWidth={width}
@@ -297,7 +297,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
     getDocHeight(d?: Doc) {
         if (!d || d.hidden) return 0;
         const childLayoutDoc = Doc.Layout(d, this.props.childLayoutTemplate?.());
-        const childDataDoc = !d.isTemplateDoc && !d.isTemplateForField ? undefined : this.props.DataDoc;
+        const childDataDoc = !d.isTemplateDoc && !d.isTemplateForField ? undefined : this.props.TemplateDataDocument;
         const maxHeight = (lim => (lim === 0 ? this.props.PanelWidth() : lim === -1 ? 10000 : lim))(NumCast(this.layoutDoc.childLimitHeight, -1));
         const nw = Doc.NativeWidth(childLayoutDoc, childDataDoc) || (!(childLayoutDoc._layout_fitWidth || this.props.childLayoutFitWidth?.(d)) ? NumCast(d._width) : 0);
         const nh = Doc.NativeHeight(childLayoutDoc, childDataDoc) || (!(childLayoutDoc._layout_fitWidth || this.props.childLayoutFitWidth?.(d)) ? NumCast(d._height) : 0);
@@ -411,7 +411,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
             e.stopPropagation?.();
             const newDoc = Doc.MakeCopy(docView.Document, true);
             Doc.GetProto(newDoc).text = undefined;
-            FormattedTextBox.SelectOnLoad = newDoc[Id];
+            FormattedTextBox.SetSelectOnLoad(newDoc);
             return this.addDocument?.(newDoc);
         }
     };
@@ -526,7 +526,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
                 chromeHidden={this.chromeHidden}
                 colHeaderData={this.colHeaderData}
                 Document={this.props.Document}
-                DataDoc={this.props.DataDoc}
+                TemplateDataDocument={this.props.TemplateDataDocument}
                 resizeColumns={this.resizeColumns}
                 renderChildren={this.children}
                 numGroupColumns={this.numGroupColumns}
diff --git a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
index 52cc21903..9e5f09479 100644
--- a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
+++ b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
@@ -25,7 +25,7 @@ import './CollectionNoteTakingView.scss';
 
 interface CSVFieldColumnProps {
     Document: Doc;
-    DataDoc: Opt<Doc>;
+    TemplateDataDocument: Opt<Doc>;
     docList: Doc[];
     heading: string;
     pivotField: string;
@@ -134,7 +134,7 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
         const newDoc = Docs.Create.TextDocument(value, { _height: 18, _width: 200, _layout_fitWidth: true, title: value, _layout_autoHeight: true });
         const colValue = this.getValue(this.props.heading);
         newDoc[key] = colValue;
-        FormattedTextBox.SelectOnLoad = newDoc[Id];
+        FormattedTextBox.SetSelectOnLoad(newDoc);
         FormattedTextBox.SelectOnLoadChar = forceEmptyNote ? '' : ' ';
         return this.props.addDocument?.(newDoc) || false;
     };
@@ -157,14 +157,14 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
         ContextMenu.Instance.clearItems();
         const layoutItems: ContextMenuProps[] = [];
         const docItems: ContextMenuProps[] = [];
-        const dataDoc = this.props.DataDoc || this.props.Document;
+        const dataDoc = this.props.TemplateDataDocument || this.props.Document;
         const pivotValue = this.getValue(this.props.heading);
 
         DocUtils.addDocumentCreatorMenuItems(
             doc => {
                 const key = this.props.pivotField;
                 doc[key] = this.getValue(this.props.heading);
-                FormattedTextBox.SelectOnLoad = doc[Id];
+                FormattedTextBox.SetSelectOnLoad(doc);
                 return this.props.addDocument?.(doc);
             },
             this.props.addDocument,
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index d4daf2baf..57ea777e4 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -799,7 +799,7 @@ class StackedTimelineAnchor extends React.Component<StackedTimelineAnchorProps>
                     NativeHeight={returnZero}
                     ref={action((r: DocumentView | null) => (anchor.view = r))}
                     Document={mark}
-                    DataDoc={undefined}
+                    TemplateDataDocument={undefined}
                     docViewPath={returnEmptyDoclist}
                     pointerEvents={this.noEvents ? returnNone : undefined}
                     styleProvider={this.props.styleProvider}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index c1333c90e..10ee01e0b 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -292,7 +292,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
                 newDoc[layout_fieldKey] = docView.Document[layout_fieldKey];
             }
             Doc.GetProto(newDoc).text = undefined;
-            FormattedTextBox.SelectOnLoad = newDoc[Id];
+            FormattedTextBox.SetSelectOnLoad(newDoc);
             return this.addDocument?.(newDoc);
         }
     };
@@ -313,7 +313,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
     // this is what renders the document that you see on the screen
     // called in Children: this actually adds a document to our children list
     getDisplayDoc(doc: Doc, width: () => number, count: number) {
-        const dataDoc = !doc.isTemplateDoc && !doc.isTemplateForField ? undefined : this.props.DataDoc;
+        const dataDoc = doc.isTemplateDoc || doc.isTemplateForField ? this.props.TemplateDataDocument : undefined;
         const height = () => this.getDocHeight(doc);
         const panelHeight = () => (this.isStackingView ? height() : Math.min(height(), this.props.PanelHeight()));
         const panelWidth = () => (this.isStackingView ? width() : this.columnWidth);
@@ -323,7 +323,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
             <DocumentView
                 ref={action((r: DocumentView) => r?.ContentDiv && this.docRefs.set(doc, r))}
                 Document={doc}
-                DataDoc={dataDoc ?? (!Doc.AreProtosEqual(doc[DocData], doc) ? doc[DocData] : undefined)}
+                TemplateDataDocument={dataDoc ?? (Doc.AreProtosEqual(doc[DocData], doc) ? undefined : doc[DocData])}
                 renderDepth={this.props.renderDepth + 1}
                 PanelWidth={panelWidth}
                 PanelHeight={panelHeight}
@@ -387,7 +387,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
     getDocHeight(d?: Doc) {
         if (!d || d.hidden) return 0;
         const childLayoutDoc = Doc.Layout(d, this.props.childLayoutTemplate?.());
-        const childDataDoc = !d.isTemplateDoc && !d.isTemplateForField ? undefined : this.props.DataDoc;
+        const childDataDoc = !d.isTemplateDoc && !d.isTemplateForField ? undefined : this.props.TemplateDataDocument;
         const maxHeight = (lim => (lim === 0 ? this.props.PanelWidth() : lim === -1 ? 10000 : lim))(NumCast(this.layoutDoc.childLimitHeight, -1));
         const nw = Doc.NativeWidth(childLayoutDoc, childDataDoc) || (!this.childFitWidth(childLayoutDoc) ? NumCast(d._width) : 0);
         const nh = Doc.NativeHeight(childLayoutDoc, childDataDoc) || (!this.childFitWidth(childLayoutDoc) ? NumCast(d._height) : 0);
@@ -558,7 +558,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
                 chromeHidden={this.chromeHidden}
                 colHeaderData={this.colHeaderData}
                 Document={this.props.Document}
-                DataDoc={this.props.DataDoc}
+                TemplateDataDocument={this.props.TemplateDataDocument}
                 renderChildren={this.children}
                 columnWidth={this.columnWidth}
                 numGroupColumns={this.numGroupColumns}
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 3598d548a..9bd412fb8 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -26,7 +26,7 @@ import { Id } from '../../../fields/FieldSymbols';
 // So this is how we are storing a column
 interface CSVFieldColumnProps {
     Document: Doc;
-    DataDoc: Opt<Doc>;
+    TemplateDataDocument: Opt<Doc>;
     docList: Doc[];
     heading: string;
     pivotField: string;
@@ -137,7 +137,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
         const maxHeading = this.props.docList.reduce((maxHeading, doc) => (NumCast(doc.heading) > maxHeading ? NumCast(doc.heading) : maxHeading), 0);
         const heading = maxHeading === 0 || this.props.docList.length === 0 ? 1 : maxHeading === 1 ? 2 : 3;
         newDoc.heading = heading;
-        FormattedTextBox.SelectOnLoad = newDoc[Id];
+        FormattedTextBox.SetSelectOnLoad(newDoc);
         FormattedTextBox.SelectOnLoadChar = forceEmptyNote ? '' : ' ';
         return this.props.addDocument?.(newDoc) || false;
     };
@@ -211,12 +211,12 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
         ContextMenu.Instance.clearItems();
         const layoutItems: ContextMenuProps[] = [];
         const docItems: ContextMenuProps[] = [];
-        const dataDoc = this.props.DataDoc || this.props.Document;
+        const dataDoc = this.props.TemplateDataDocument || this.props.Document;
         const width = this._ele ? Number(getComputedStyle(this._ele).width.replace('px', '')) : 0;
         const height = this._ele ? Number(getComputedStyle(this._ele).height.replace('px', '')) : 0;
         DocUtils.addDocumentCreatorMenuItems(
             doc => {
-                FormattedTextBox.SelectOnLoad = doc[Id];
+                FormattedTextBox.SetSelectOnLoad(doc);
                 return this.props.addDocument?.(doc);
             },
             this.props.addDocument,
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 43653ed75..f082ca0da 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -20,7 +20,7 @@ import { ImageUtils } from '../../util/Import & Export/ImageUtils';
 import { SelectionManager } from '../../util/SelectionManager';
 import { SnappingManager } from '../../util/SnappingManager';
 import { undoBatch, UndoManager } from '../../util/UndoManager';
-import { DocComponent } from '../DocComponent';
+import { ViewBoxBaseComponent } from '../DocComponent';
 import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
 import { LoadingBox } from '../nodes/LoadingBox';
 import { CollectionView, CollectionViewProps } from './CollectionView';
@@ -31,7 +31,7 @@ export interface SubCollectionViewProps extends CollectionViewProps {
 }
 
 export function CollectionSubView<X>(moreProps?: X) {
-    class CollectionSubView extends DocComponent<X & SubCollectionViewProps>() {
+    class CollectionSubView extends ViewBoxBaseComponent<X & SubCollectionViewProps>() {
         private dropDisposer?: DragManager.DragDropDisposer;
         private gestureDisposer?: GestureUtils.GestureEventDisposer;
         protected _mainCont?: HTMLDivElement;
@@ -56,14 +56,18 @@ export function CollectionSubView<X>(moreProps?: X) {
         }
 
         @computed get dataDoc() {
-            return this.props.DataDoc instanceof Doc && this.props.Document.isTemplateForField ? Doc.GetProto(this.props.DataDoc) : this.props.Document.resolvedDataDoc ? this.props.Document : Doc.GetProto(this.props.Document); // if the layout document has a resolvedDataDoc, then we don't want to get its parent which would be the unexpanded template
+            return this.props.TemplateDataDocument instanceof Doc && this.props.Document.isTemplateForField
+                ? Doc.GetProto(this.props.TemplateDataDocument)
+                : this.props.Document.resolvedDataDoc
+                ? this.props.Document
+                : Doc.GetProto(this.props.Document); // if the layout document has a resolvedDataDoc, then we don't want to get its parent which would be the unexpanded template
         }
 
         // this returns whether either the collection is selected, or the template that it is part of is selected
-        rootSelected = () => this.props.isSelected() || BoolCast(this.Document.rootDocument && this.props.rootSelected?.());
+        rootSelected = () => this.props.isSelected() || BoolCast(this.props.TemplateDataDocument && this.props.rootSelected?.());
 
-        // The data field for rendering this collection will be on the this.props.Document unless we're rendering a template in which case we try to use props.DataDoc.
-        // When a document has a DataDoc but it's not a template, then it contains its own rendering data, but needs to pass the DataDoc through
+        // The data field for rendering this collection will be on the this.props.Document unless we're rendering a template in which case we try to use props.TemplateDataDocument.
+        // When a document has a TemplateDataDoc but it's not a template, then it contains its own rendering data, but needs to pass the TemplateDataDoc through
         // to its children which may be templates.
         // If 'annotationField' is specified, then all children exist on that field of the extension document, otherwise, they exist directly on the data document under 'fieldKey'
         @computed get dataField() {
@@ -71,9 +75,9 @@ export function CollectionSubView<X>(moreProps?: X) {
         }
 
         @computed get childLayoutPairs(): { layout: Doc; data: Doc }[] {
-            const { Document, DataDoc } = this.props;
+            const { Document, TemplateDataDocument } = this.props;
             const validPairs = this.childDocs
-                .map(doc => Doc.GetLayoutDataDocPair(Document, !this.props.isAnnotationOverlay ? DataDoc : undefined, doc))
+                .map(doc => Doc.GetLayoutDataDocPair(Document, !this.props.isAnnotationOverlay ? TemplateDataDocument : undefined, doc))
                 .filter(pair => {
                     // filter out any documents that have a proto that we don't have permissions to
                     return !pair.layout?.hidden && pair.layout && (!pair.layout.proto || (pair.layout.proto instanceof Doc && GetEffectiveAcl(pair.layout.proto) !== AclPrivate));
@@ -104,8 +108,8 @@ export function CollectionSubView<X>(moreProps?: X) {
                 // Finally, if it's not a doc or a list and the document is a template, we try to render the root doc.
                 // For example, if an image doc is rendered with a slide template, the template will try to render the data field as a collection.
                 // Since the data field is actually an image, we set the list of documents to the singleton of root document's proto which will be an image.
-                const rootDocument = Cast(this.props.Document.rootDocument, Doc, null);
-                rawdocs = rootDocument && !this.props.isAnnotationOverlay ? [Doc.GetProto(rootDocument)] : [];
+                const templateRoot = this.props.TemplateDataDocument;
+                rawdocs = templateRoot && !this.props.isAnnotationOverlay ? [Doc.GetProto(templateRoot)] : [];
             }
 
             const childDocs = rawdocs.filter(d => !(d instanceof Promise) && GetEffectiveAcl(Doc.GetProto(d)) !== AclPrivate && (this.props.ignoreUnrendered || !d.layout_unrendered)).map(d => d as Doc);
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 36ea14d92..1315decb2 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -63,7 +63,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
         return this.props.Document;
     }
     @computed get dataDoc() {
-        return this.props.DataDoc || this.doc;
+        return this.props.TemplateDataDocument || this.doc;
     }
     @computed get treeViewtruncateTitleWidth() {
         return NumCast(this.doc.treeView_TruncateTitleWidth, this.panelWidth());
@@ -166,7 +166,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
             const prev = ind && DocListCast(targetDataDoc[this.props.fieldKey])[ind - 1];
             this.props.removeDocument?.(doc);
             if (ind > 0 && prev) {
-                FormattedTextBox.SelectOnLoad = prev[Id];
+                FormattedTextBox.SetSelectOnLoad(prev);
                 DocumentManager.Instance.getDocumentView(prev, this.props.DocumentView?.())?.select(false);
             }
             return true;
@@ -271,7 +271,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
             this,
             this,
             this.doc,
-            this.props.DataDoc,
+            this.props.TemplateDataDocument,
             undefined,
             undefined,
             addDoc,
@@ -326,7 +326,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
             <div className="buttonMenu-docBtn" style={{ width: NumCast(menuDoc._width, 30), height: NumCast(menuDoc._height, 30) }}>
                 <DocumentView
                     Document={menuDoc}
-                    DataDoc={menuDoc}
+                    TemplateDataDocument={menuDoc}
                     isContentActive={this.props.isContentActive}
                     isDocumentActive={returnTrue}
                     addDocument={this.props.addDocument}
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index a5cf89217..def4beca3 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -444,7 +444,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
                     LayoutTemplateString={this.props.keyValue ? KeyValueBox.LayoutString() : undefined}
                     hideTitle={this.props.keyValue}
                     Document={this._document}
-                    DataDoc={!Doc.AreProtosEqual(this._document[DocData], this._document) ? this._document[DocData] : undefined}
+                    TemplateDataDocument={!Doc.AreProtosEqual(this._document[DocData], this._document) ? this._document[DocData] : undefined}
                     onBrowseClick={DocumentView.exploreMode}
                     waitForDoubleClickToClick={this.waitForDoubleClick}
                     isContentActive={this.isContentActive}
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 6cd111ac4..a756007f8 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -964,7 +964,6 @@ export class TreeView extends React.Component<TreeViewProps> {
                     }
                 })}
                 Document={this.doc}
-                DataDoc={undefined} // or this.dataDoc?
                 layout_fitWidth={returnTrue}
                 scriptContext={this}
                 hideDecorationTitle={this.props.treeView.outlineMode}
@@ -1059,7 +1058,6 @@ export class TreeView extends React.Component<TreeViewProps> {
                     key={this.doc[Id]}
                     ref={action((r: DocumentView | null) => (this._dref = r))}
                     Document={this.doc}
-                    DataDoc={undefined}
                     layout_fitWidth={this.fitWidthFilter}
                     PanelWidth={this.embeddedPanelWidth}
                     PanelHeight={this.embeddedPanelHeight}
@@ -1249,7 +1247,7 @@ export class TreeView extends React.Component<TreeViewProps> {
                     const fieldKey = Doc.LayoutFieldKey(newParent);
                     if (remove && fieldKey && Cast(newParent[fieldKey], listSpec(Doc)) !== undefined) {
                         remove(child);
-                        FormattedTextBox.SelectOnLoad = child[Id];
+                        FormattedTextBox.SetSelectOnLoad(child);
                         TreeView._editTitleOnLoad = editTitle ? { id: child[Id], parent } : undefined;
                         Doc.AddDocToList(newParent, fieldKey, child, addAfter, false);
                         newParent.treeView_Open = true;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index fb29fb0d3..ab718c351 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -239,9 +239,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     ScreenToLocalXf = () => this.screenToLocalXf.copy();
     getActiveDocuments = () => this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map(pair => pair.layout);
     isAnyChildContentActive = () => this.props.isAnyChildContentActive();
-    addLiveTextBox = (newBox: Doc) => {
-        FormattedTextBox.SelectOnLoad = newBox[Id]; // track the new text box so we can give it a prop that tells it to focus itself when it's displayed
-        this.addDocument(newBox);
+    addLiveTextBox = (newDoc: Doc) => {
+        FormattedTextBox.SetSelectOnLoad(newDoc); // track the new text box so we can give it a prop that tells it to focus itself when it's displayed
+        this.addDocument(newDoc);
     };
     selectDocuments = (docs: Doc[]) => {
         SelectionManager.DeselectAll();
@@ -1177,7 +1177,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                 newDoc[layout_fieldKey] = docView.Document[layout_fieldKey];
             }
             Doc.GetProto(newDoc).text = undefined;
-            FormattedTextBox.SelectOnLoad = newDoc[Id];
+            FormattedTextBox.SetSelectOnLoad(newDoc);
             return this.addDocument?.(newDoc);
         }
     };
@@ -1204,8 +1204,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             <CollectionFreeFormDocumentViewWrapper
                 {...OmitKeys(entry, ['replica', 'pair']).omit}
                 key={childLayout[Id] + (entry.replica || '')}
-                DataDoc={childData}
                 Document={childLayout}
+                TemplateDataDocument={childData}
                 dragStarting={this.dragStarting}
                 dragEnding={this.dragEnding}
                 isGroupActive={this.props.isGroupActive}
@@ -1888,7 +1888,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                         <DocumentView
                             {...this.props}
                             Document={this._lightboxDoc}
-                            DataDoc={undefined}
+                            TemplateDataDocument={undefined}
                             PanelWidth={this.lightboxPanelWidth}
                             PanelHeight={this.lightboxPanelHeight}
                             NativeWidth={returnZero}
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
index be806d3cc..82f0171eb 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
@@ -192,7 +192,7 @@ export class CollectionGridView extends CollectionSubView() {
                 NativeHeight={returnZero}
                 setContentView={emptyFunction}
                 Document={layout}
-                DataDoc={layout.resolvedDataDoc as Doc}
+                TemplateDataDocument={layout.resolvedDataDoc as Doc}
                 isContentActive={this.isChildContentActive}
                 PanelWidth={width}
                 PanelHeight={height}
@@ -351,7 +351,7 @@ export class CollectionGridView extends CollectionSubView() {
                         undoBatch(
                             action(() => {
                                 const text = Docs.Create.TextDocument('', { _width: 150, _height: 50 });
-                                FormattedTextBox.SelectOnLoad = text[Id]; // track the new text box so we can give it a prop that tells it to focus itself when it's displayed
+                                FormattedTextBox.SetSelectOnLoad(text); // track the new text box so we can give it a prop that tells it to focus itself when it's displayed
                                 Doc.AddDocToList(this.props.Document, this.props.fieldKey, text);
                                 this.setLayoutList(this.addLayoutItem(this.savedLayoutList, this.makeLayoutItem(text, this.screenToCell(e.clientX, e.clientY))));
                             })
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
index 05ec0448b..043914985 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
@@ -253,7 +253,7 @@ export class CollectionMulticolumnView extends CollectionSubView() {
         return (
             <DocumentView
                 Document={childLayout}
-                DataDoc={childLayout.resolvedDataDoc as Doc}
+                TemplateDataDocument={childLayout.resolvedDataDoc as Doc}
                 styleProvider={this.props.styleProvider}
                 docViewPath={this.props.docViewPath}
                 LayoutTemplate={this.props.childLayoutTemplate}
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
index b4b62e635..2d4750de3 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
@@ -249,7 +249,7 @@ export class CollectionMultirowView extends CollectionSubView() {
         return (
             <DocumentView
                 Document={layout}
-                DataDoc={layout.resolvedDataDoc as Doc}
+                TemplateDataDocument={layout.resolvedDataDoc as Doc}
                 styleProvider={this.props.styleProvider}
                 docViewPath={this.props.docViewPath}
                 LayoutTemplate={this.props.childLayoutTemplate}
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
index 0b292a445..030f9953c 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
@@ -892,7 +892,6 @@ export class CollectionSchemaView extends CollectionSubView() {
                         {Array.from(this._selectedDocs).lastElement() && (
                             <DocumentView
                                 Document={Array.from(this._selectedDocs).lastElement()}
-                                DataDoc={undefined}
                                 fitContentsToBox={returnTrue}
                                 dontCenter={'y'}
                                 onClickScriptDisable="always"
@@ -971,7 +970,6 @@ class CollectionSchemaViewDoc extends React.Component<CollectionSchemaViewDocPro
                 LayoutTemplate={this.props.schema.props.childLayoutTemplate}
                 LayoutTemplateString={SchemaRowBox.LayoutString(this.props.schema.props.fieldKey, this.props.index)}
                 Document={this.props.doc}
-                DataDoc={undefined}
                 renderDepth={this.props.schema.props.renderDepth + 1}
                 PanelWidth={this.tableWidthFunc}
                 PanelHeight={this.props.rowHeight}
diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
index 150b1b46e..bd6d3bad6 100644
--- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
@@ -272,7 +272,7 @@ export class SchemaRTFCell extends React.Component<SchemaTableCellProps> {
         fieldProps.isContentActive = this.selectedFunc;
         return (
             <div className="schemaRTFCell" style={{ display: 'flex', fontStyle: this.selected ? undefined : 'italic', width: '100%', height: '100%', position: 'relative', color, textDecoration, cursor, pointerEvents }}>
-                {this.selected ? <FormattedTextBox {...fieldProps} DataDoc={this.props.Document} /> : (field => (field ? Field.toString(field) : ''))(FieldValue(fieldProps.Document[fieldProps.fieldKey]))}
+                {this.selected ? <FormattedTextBox {...fieldProps} /> : (field => (field ? Field.toString(field) : ''))(FieldValue(fieldProps.Document[fieldProps.fieldKey]))}
             </div>
         );
     }
diff --git a/src/client/views/linking/LinkPopup.tsx b/src/client/views/linking/LinkPopup.tsx
index f02a284da..a36c8d778 100644
--- a/src/client/views/linking/LinkPopup.tsx
+++ b/src/client/views/linking/LinkPopup.tsx
@@ -61,7 +61,6 @@ export class LinkPopup extends React.Component<LinkPopupProps> {
 
                     <SearchBox
                         Document={Doc.MySearcher}
-                        DataDoc={Doc.MySearcher}
                         linkFrom={linkDoc}
                         linkCreateAnchor={this.props.linkCreateAnchor}
                         linkSearch={true}
diff --git a/src/client/views/newlightbox/NewLightboxView.tsx b/src/client/views/newlightbox/NewLightboxView.tsx
index 22b996809..f3cde3f5a 100644
--- a/src/client/views/newlightbox/NewLightboxView.tsx
+++ b/src/client/views/newlightbox/NewLightboxView.tsx
@@ -293,7 +293,6 @@ export class NewLightboxView extends React.Component<LightboxViewProps> {
                     <DocumentView
                         ref={action((r: DocumentView | null) => (NewLightboxView._docView = r !== null ? r : undefined))}
                         Document={LightboxView.LightboxDoc}
-                        DataDoc={undefined}
                         PanelWidth={this.newLightboxWidth}
                         PanelHeight={this.newLightboxHeight}
                         LayoutTemplate={NewLightboxView.LightboxDocTemplate}
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index b7cd306ae..6195a155d 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -36,7 +36,7 @@ export interface CollectionFreeFormDocumentViewWrapperProps extends DocumentView
     CollectionFreeFormView: CollectionFreeFormView;
 }
 @observer
-export class CollectionFreeFormDocumentViewWrapper extends DocComponent<CollectionFreeFormDocumentViewWrapperProps>() implements CollectionFreeFormDocumentViewProps {
+export class CollectionFreeFormDocumentViewWrapper extends DocComponent<CollectionFreeFormDocumentViewWrapperProps & { fieldKey: string }>() implements CollectionFreeFormDocumentViewProps {
     @observable X = this.props.x;
     @observable Y = this.props.y;
     @observable Z = this.props.z;
@@ -115,7 +115,7 @@ export interface CollectionFreeFormDocumentViewProps {
 }
 
 @observer
-export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeFormDocumentViewProps & DocumentViewProps>() {
+export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeFormDocumentViewProps & DocumentViewProps & { fieldKey: string }>() {
     get displayName() { // this makes mobx trace() statements more descriptive
         return 'CollectionFreeFormDocumentView(' + this.Document.title + ')';
     } // prettier-ignore
diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx
index b050e3252..9fd4fbcaa 100644
--- a/src/client/views/nodes/ComparisonBox.tsx
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -173,7 +173,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
                     <DocumentView
                         {...this.props}
                         Document={targetDoc}
-                        DataDoc={undefined}
+                        TemplateDataDocument={undefined}
                         moveDocument={which.endsWith('1') ? this.moveDoc1 : this.moveDoc2}
                         removeDocument={which.endsWith('1') ? this.remDoc1 : this.remDoc2}
                         NativeWidth={returnZero}
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index eed787b6d..4b58bfe48 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -1,7 +1,8 @@
-import { computed, trace } from 'mobx';
+import { computed } from 'mobx';
 import { observer } from 'mobx-react';
+import { MouseEventHandler } from 'react-select';
 import { Doc, Opt } from '../../../fields/Doc';
-import { AclPrivate } from '../../../fields/DocSymbols';
+import { AclPrivate, DocData } from '../../../fields/DocSymbols';
 import { ScriptField } from '../../../fields/ScriptField';
 import { Cast, StrCast } from '../../../fields/Types';
 import { GetEffectiveAcl, TraceMobx } from '../../../fields/util';
@@ -36,6 +37,7 @@ import { LinkAnchorBox } from './LinkAnchorBox';
 import { LinkBox } from './LinkBox';
 import { LoadingBox } from './LoadingBox';
 import { MapBox } from './MapBox/MapBox';
+import { MapPushpinBox } from './MapBox/MapPushpinBox';
 import { PDFBox } from './PDFBox';
 import { PhysicsSimulationBox } from './PhysicsBox/PhysicsSimulationBox';
 import { RecordingBox } from './RecordingBox';
@@ -46,7 +48,6 @@ import { VideoBox } from './VideoBox';
 import { WebBox } from './WebBox';
 import React = require('react');
 import XRegExp = require('xregexp');
-import { MapPushpinBox } from './MapBox/MapPushpinBox';
 
 const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
 
@@ -117,10 +118,11 @@ export class HTMLtag extends React.Component<HTMLtagProps> {
 
 @observer
 export class DocumentContentsView extends React.Component<
-    DocumentViewProps & {
-        setHeight?: (height: number) => void;
-        layout_fieldKey: string;
-    }
+    DocumentViewProps &
+        FieldViewProps & {
+            setHeight?: (height: number) => void;
+            layout_fieldKey: string;
+        }
 > {
     @computed get layout(): string {
         TraceMobx();
@@ -137,10 +139,6 @@ export class DocumentContentsView extends React.Component<
         Object.keys(prevProps).forEach(pkey => (prevProps as any)[pkey] !== (this.props as any)[pkey] && console.log(pkey + ' ' + (prevProps as any)[pkey] + ' ' + (this.props as any)[pkey]));
     }
 
-    get dataDoc() {
-        const proto = this.props.DataDoc || Doc.GetProto(this.props.Document);
-        return proto instanceof Promise ? undefined : proto;
-    }
     get layoutDoc() {
         // bcz: replaced this with below : is it correct?  change was made to accommodate passing fieldKey's from a layout script
         // const template: Doc = this.props.LayoutTemplate?.() || Doc.Layout(this.props.Document, this.props.layout_fieldKey ? Cast(this.props.Document[this.props.layout_fieldKey], Doc, null) : undefined);
@@ -163,19 +161,24 @@ export class DocumentContentsView extends React.Component<
             'LayoutTemplate',
             'dontCenter',
             'contextMenuItems',
-            'onClick',
+            //'onClick', // don't need to omit this since it will be set
             'onDoubleClick',
             'onPointerDown',
             'onPointerUp',
         ];
-        const list = {
-            ...OmitKeys(this.props, [...docOnlyProps], '').omit,
-            Document: this.layoutDoc,
-            DataDoc: this.dataDoc,
-            onClick: onClick,
-            onInput: onInput,
+        const templateDataDoc = this.props.TemplateDataDocument ?? (this.layoutDoc !== this.props.Document ? this.props.Document[DocData] : undefined);
+        const list: BindingProps & React.DetailedHTMLProps<React.HtmlHTMLAttributes<HTMLDivElement>, HTMLDivElement> = {
+            ...this.props,
+            Document: this.layoutDoc ?? this.props.Document,
+            TemplateDataDocument: templateDataDoc instanceof Promise ? undefined : templateDataDoc,
+            onClick: onClick as any as MouseEventHandler, // pass onClick script as if it were a real function -- it will be interpreted properly in the HTMLtag
+            onInput: onInput as any as React.FormEventHandler,
+        };
+        return {
+            props: {
+                ...OmitKeys(list, [...docOnlyProps], '').omit,
+            },
         };
-        return { props: list };
     }
 
     // componentWillUpdate(oldProps: any, newState: any) {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index b21b22cd2..977a9bc54 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -5,7 +5,7 @@ import { observer } from 'mobx-react';
 import { computedFn } from 'mobx-utils';
 import { Bounce, Fade, Flip, LightSpeed, Roll, Rotate, Zoom } from 'react-reveal';
 import { Doc, DocListCast, Field, Opt, StrListCast } from '../../../fields/Doc';
-import { AclPrivate, Animation, AudioPlay, DocData, DocViews } from '../../../fields/DocSymbols';
+import { AclPrivate, Animation, AudioPlay, DocViews } from '../../../fields/DocSymbols';
 import { Id } from '../../../fields/FieldSymbols';
 import { InkTool } from '../../../fields/InkField';
 import { List } from '../../../fields/List';
@@ -109,7 +109,7 @@ export interface DocFocusOptions {
     easeFunc?: 'linear' | 'ease'; // transition method for scrolling
 }
 export type DocFocusFunc = (doc: Doc, options: DocFocusOptions) => Opt<number>;
-export type StyleProviderFunc = (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string) => any;
+export type StyleProviderFunc = (doc: Opt<Doc>, props: Opt<DocumentViewProps | FieldViewProps>, property: string) => any;
 export interface DocComponentView {
     updateIcon?: () => void; // updates the icon representation of the document
     getAnchor?: (addAsAnnotation: boolean, pinData?: PinProps) => Doc; // returns an Anchor Doc that represents the current state of the doc's componentview (e.g., the current playhead location of a an audio/video box)
@@ -150,11 +150,10 @@ export interface DocComponentView {
 }
 // These props are passed to both FieldViews and DocumentViews
 export interface DocumentViewSharedProps {
-    fieldKey?: string; // only used by FieldViews but helpful here to allow styleProviders to access fieldKey of FieldViewProps.  In priniciple, passing a fieldKey to a documentView could override or be the default fieldKey for fieldViews
     DocumentView?: () => DocumentView;
     renderDepth: number;
     Document: Doc;
-    DataDoc?: Doc;
+    TemplateDataDocument?: Doc;
     fitContentsToBox?: () => boolean; // used by freeformview to fit its contents to its panel. corresponds to _freeform_fitContentsToBox property on a Document
     isGroupActive?: () => string | undefined; // is this document part of a group that is active
     suppressSetHeight?: boolean;
@@ -506,7 +505,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
                     clickFunc = () => UndoManager.RunInBatch(func, 'click ' + this.Document.title);
                 } else {
                     // onDragStart implies a button doc that we don't want to select when clicking. RootDocument & isTemplateForField implies we're clicking on part of a template instance and we want to select the whole template, not the part
-                    if ((this.layoutDoc.onDragStart || this.props.Document.rootDocument) && !(e.ctrlKey || e.button > 0)) {
+                    if ((this.layoutDoc.onDragStart || this.props.TemplateDataDocument) && !(e.ctrlKey || e.button > 0)) {
                         stopPropagate = false; // don't stop propagation for field templates -- want the selection to propagate up to the root document of the template
                     }
                     preventDefault = false;
@@ -548,7 +547,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
         this._downX = e.clientX;
         this._downY = e.clientY;
         this._downTime = Date.now();
-        if ((Doc.ActiveTool === InkTool.None || this.props.addDocTab === returnFalse) && !(this.props.Document.rootDocument && !(e.ctrlKey || e.button > 0))) {
+        if ((Doc.ActiveTool === InkTool.None || this.props.addDocTab === returnFalse) && !(this.props.TemplateDataDocument && !(e.ctrlKey || e.button > 0))) {
             // click events stop here if the document is active and no modes are overriding it
             // if this is part of a template, let the event go up to the template root unless right/ctrl clicking
             if (
@@ -814,7 +813,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
             const moreItems = more && 'subitems' in more ? more.subitems : [];
             if (!Doc.IsSystem(this.Document)) {
                 if (!Doc.noviceMode) {
-                    moreItems.push({ description: 'Make View of Metadata Field', event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc), icon: 'concierge-bell' });
+                    moreItems.push({ description: 'Make View of Metadata Field', event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.TemplateDataDocument), icon: 'concierge-bell' });
                     moreItems.push({ description: `${this.Document._chromeHidden ? 'Show' : 'Hide'} Chrome`, event: () => (this.Document._chromeHidden = !this.Document._chromeHidden), icon: 'project-diagram' });
 
                     if (Cast(Doc.GetProto(this.props.Document).data, listSpec(Doc))) {
@@ -898,7 +897,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
     };
 
     @computed get _rootSelected() {
-        return this.props.isSelected() || BoolCast(this.Document.rootDocument && this.props.rootSelected?.());
+        return this.props.isSelected() || BoolCast(this.props.TemplateDataDocument && this.props.rootSelected?.());
     }
     rootSelected = () => this._rootSelected;
     panelHeight = () => this.props.PanelHeight() - this.headerMargin;
@@ -938,6 +937,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
                 <DocumentContentsView
                     key={1}
                     {...this.props}
+                    fieldKey=""
                     pointerEvents={this.contentPointerEvents}
                     docViewPath={this.props.viewPath}
                     setContentView={this.setContentView}
@@ -1462,10 +1462,10 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         return Doc.Layout(this.Document, this.props.LayoutTemplate?.());
     }
     @computed get nativeWidth() {
-        return this.docView?._componentView?.ignoreNativeDimScaling?.() ? 0 : returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, this.props.DataDoc, !this.layout_fitWidth));
+        return this.docView?._componentView?.ignoreNativeDimScaling?.() ? 0 : returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, this.props.TemplateDataDocument, !this.layout_fitWidth));
     }
     @computed get nativeHeight() {
-        return this.docView?._componentView?.ignoreNativeDimScaling?.() ? 0 : returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, this.props.DataDoc, !this.layout_fitWidth));
+        return this.docView?._componentView?.ignoreNativeDimScaling?.() ? 0 : returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, this.props.TemplateDataDocument, !this.layout_fitWidth));
     }
     @computed get shouldNotScale() {
         return this.props.shouldNotScale?.() || (this.layout_fitWidth && !this.nativeWidth) || [CollectionViewType.Docking].includes(this.Document._type_collection as any);
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index f7f94c546..219e3025a 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -16,7 +16,6 @@ import { DocumentViewSharedProps } from './DocumentView';
 export interface FieldViewProps extends DocumentViewSharedProps {
     // FieldView specific props that are not part of DocumentView props
     fieldKey: string;
-    scrollOverflow?: boolean; // bcz: would like to think this can be avoided -- need to look at further
 
     select: (isCtrlPressed: boolean) => void;
     isContentActive: (outsideReaction?: boolean) => boolean | undefined;
diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
index 0c360acf0..8f6550663 100644
--- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
@@ -13,7 +13,7 @@ import { SelectionManager } from '../../../util/SelectionManager';
 import { SettingsManager } from '../../../util/SettingsManager';
 import { undoable, UndoManager } from '../../../util/UndoManager';
 import { ContextMenu } from '../../ContextMenu';
-import { DocComponent } from '../../DocComponent';
+import { ViewBoxBaseComponent } from '../../DocComponent';
 import { EditableView } from '../../EditableView';
 import { SelectedDocView } from '../../selectedDoc';
 import { StyleProp } from '../../StyleProvider';
@@ -41,7 +41,7 @@ export interface ButtonProps extends FieldViewProps {
     type?: ButtonType;
 }
 @observer
-export class FontIconBox extends DocComponent<ButtonProps>() {
+export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
     public static LayoutString(fieldKey: string) {
         return FieldView.LayoutString(FontIconBox, fieldKey);
     }
@@ -130,7 +130,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
                 type = 'slider';
                 break;
         }
-        const numScript = (value?: number) => ScriptCast(this.Document.script).script.run({ this: this.Document, self:this.Document,value, _readOnly_: value === undefined });
+        const numScript = (value?: number) => ScriptCast(this.Document.script).script.run({ this: this.Document, self: this.Document, value, _readOnly_: value === undefined });
         const color = this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Color);
         // Script for checking the outcome of the toggle
         const checkResult = Number(Number(numScript().result ?? 0).toPrecision(NumCast(this.dataDoc.numPrecision, 3)));
@@ -157,7 +157,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
             this,
             e,
             (e: PointerEvent) => {
-                return ScriptCast(this.Document.onDragScript)?.script.run({ this: this.Document, self:this.Document,value: { doc: value, e } }).result;
+                return ScriptCast(this.Document.onDragScript)?.script.run({ this: this.Document, self: this.Document, value: { doc: value, e } }).result;
             },
             emptyFunction,
             emptyFunction
@@ -205,7 +205,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
             }
             noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Carousel3D, CollectionViewType.Stacking, CollectionViewType.NoteTaking];
         } else {
-            text = script?.script.run({ this: this.Document, self:this.Document,value: '', _readOnly_: true }).result;
+            text = script?.script.run({ this: this.Document, self: this.Document, value: '', _readOnly_: true }).result;
             // text = StrCast((RichTextMenu.Instance?.TextView?.EditorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily);
             getStyle = (val: string) => ({ fontFamily: val });
         }
@@ -223,7 +223,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
         return (
             <Dropdown
                 selectedVal={text}
-                setSelectedVal={undoable(value => script.script.run({ this: this.Document, self:this.Document,value }), `dropdown select ${this.label}`)}
+                setSelectedVal={undoable(value => script.script.run({ this: this.Document, self: this.Document, value }), `dropdown select ${this.label}`)}
                 color={SettingsManager.userColor}
                 background={SettingsManager.userVariantColor}
                 type={Type.TERT}
@@ -247,17 +247,17 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
      */
     @computed get colorButton() {
         const color = this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Color);
-        const curColor = this.colorScript?.script.run({ this: this.Document, self:this.Document,value: undefined, _readOnly_: true }).result ?? 'transparent';
+        const curColor = this.colorScript?.script.run({ this: this.Document, self: this.Document, value: undefined, _readOnly_: true }).result ?? 'transparent';
         const tooltip: string = StrCast(this.Document.toolTip);
 
         return (
             <ColorPicker
                 setSelectedColor={value => {
                     if (!this.colorBatch) this.colorBatch = UndoManager.StartBatch(`Set ${tooltip} color`);
-                    this.colorScript?.script.run({ this: this.Document, self:this.Document, value: value, _readOnly_: false });
+                    this.colorScript?.script.run({ this: this.Document, self: this.Document, value: value, _readOnly_: false });
                 }}
                 setFinalColor={value => {
-                    this.colorScript?.script.run({ this: this.Document, self:this.Document,value: value, _readOnly_: false });
+                    this.colorScript?.script.run({ this: this.Document, self: this.Document, value: value, _readOnly_: false });
                     this.colorBatch?.end();
                     this.colorBatch = undefined;
                 }}
@@ -277,7 +277,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
         const tooltip: string = StrCast(this.Document.toolTip);
 
         const script = ScriptCast(this.Document.onClick);
-        const toggleStatus = script ? script.script.run({ this: this.Document, self:this.Document, value: undefined, _readOnly_: true }).result : false;
+        const toggleStatus = script ? script.script.run({ this: this.Document, self: this.Document, value: undefined, _readOnly_: true }).result : false;
         // Colors
         const color = this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Color);
         const items = DocListCast(this.dataDoc.data);
@@ -308,7 +308,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
         const tooltip = StrCast(this.Document.toolTip);
 
         const script = ScriptCast(this.Document.onClick);
-        const toggleStatus = script ? script.script.run({ this: this.Document, self:this.Document,value: undefined, _readOnly_: true }).result : false;
+        const toggleStatus = script ? script.script.run({ this: this.Document, self: this.Document, value: undefined, _readOnly_: true }).result : false;
         // Colors
         const color = this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Color);
         const backgroundColor = this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor);
@@ -324,7 +324,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
                 //background={SettingsManager.userBackgroundColor}
                 icon={this.Icon(color)!}
                 label={this.label}
-                onPointerDown={() => script.script.run({ this: this.Document, self:this.Document, value: !toggleStatus, _readOnly_: false })}
+                onPointerDown={() => script.script.run({ this: this.Document, self: this.Document, value: !toggleStatus, _readOnly_: false })}
             />
         );
     }
@@ -344,9 +344,9 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
         // Script for running the toggle
         const script = ScriptCast(this.Document.script);
         // Function to run the script
-        const checkResult = script?.script.run({ this: this.Document, self:this.Document,value: '', _readOnly_: true }).result;
+        const checkResult = script?.script.run({ this: this.Document, self: this.Document, value: '', _readOnly_: true }).result;
 
-        const setValue = (value: string, shiftDown?: boolean): boolean => script?.script.run({ this: this.Document, self:this.Document,value, _readOnly_: false }).result;
+        const setValue = (value: string, shiftDown?: boolean): boolean => script?.script.run({ this: this.Document, self: this.Document, value, _readOnly_: false }).result;
 
         return <EditableText editing={false} setEditing={(editing: boolean) => {}} />;
 
@@ -354,7 +354,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
             <div className="menuButton editableText">
                 <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={'lock'} />
                 <div style={{ width: 'calc(100% - .875em)', paddingLeft: '4px' }}>
-                    <EditableView GetValue={() => script?.script.run({ this: this.Document, self:this.Document, value: '', _readOnly_: true }).result} SetValue={setValue} oneLine={true} contents={checkResult} />
+                    <EditableView GetValue={() => script?.script.run({ this: this.Document, self: this.Document, value: '', _readOnly_: true }).result} SetValue={setValue} oneLine={true} contents={checkResult} />
                 </div>
             </div>
         );
diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx
index 39e0279fc..577685636 100644
--- a/src/client/views/nodes/KeyValuePair.tsx
+++ b/src/client/views/nodes/KeyValuePair.tsx
@@ -58,7 +58,6 @@ export class KeyValuePair extends React.Component<KeyValuePairProps> {
     render() {
         const props: FieldViewProps = {
             Document: this.props.doc,
-            DataDoc: this.props.doc,
             childFilters: returnEmptyFilter,
             childFiltersByRanges: returnEmptyFilter,
             searchFilterDocs: returnEmptyDoclist,
diff --git a/src/client/views/nodes/LoadingBox.tsx b/src/client/views/nodes/LoadingBox.tsx
index 86c91ae3c..01dd830f8 100644
--- a/src/client/views/nodes/LoadingBox.tsx
+++ b/src/client/views/nodes/LoadingBox.tsx
@@ -78,7 +78,7 @@ export class LoadingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                 <div className="loadingBox-textContainer">
                     <span className="loadingBox-title">{StrCast(this.Document.title)}</span>
                     <p className="loadingBox-headerText">{StrCast(this.Document.loadingError, 'Loading ' + (this.progress.replace('[download]', '') || '(can take several minutes)'))}</p>
-                    {this.rootDDocumentoc.loadingError ? null : (
+                    {this.Document.loadingError ? null : (
                         <div className="loadingBox-spinner">
                             <ReactLoading type="spinningBubbles" color="blue" height={100} width={100} />
                         </div>
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index 14a8a387a..398d1255e 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -228,7 +228,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
 
         const targetCreator = (annotationOn: Doc | undefined) => {
             const target = DocUtils.GetNewTextDoc('Note linked to ' + this.Document.title, 0, 0, 100, 100, undefined, annotationOn, undefined, 'yellow');
-            FormattedTextBox.SelectOnLoad = target[Id];
+            FormattedTextBox.SetSelectOnLoad(target);
             return target;
         };
         const docView = this.props.DocumentView?.();
@@ -774,7 +774,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
                                           {...this.props}
                                           renderDepth={this.props.renderDepth + 1}
                                           Document={pushpin}
-                                          DataDoc={undefined}
+                                          TemplateDataDocument={undefined}
                                           PanelWidth={returnOne}
                                           PanelHeight={returnOne}
                                           NativeWidth={returnOne}
diff --git a/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx b/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
index 9608e2dd0..3713e93ce 100644
--- a/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
+++ b/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
@@ -32,9 +32,9 @@ export class MapBoxInfoWindow extends React.Component<MapBoxInfoWindowProps & Vi
 
     addNoteClick = (e: React.PointerEvent) => {
         setupMoveUpEvents(this, e, returnFalse, emptyFunction, e => {
-            const newBox = Docs.Create.TextDocument('Note', { _layout_autoHeight: true });
-            FormattedTextBox.SelectOnLoad = newBox[Id]; // track the new text box so we can give it a prop that tells it to focus itself when it's displayed
-            Doc.AddDocToList(this.props.place, 'data', newBox);
+            const newDoc = Docs.Create.TextDocument('Note', { _layout_autoHeight: true });
+            FormattedTextBox.SetSelectOnLoad(newDoc); // track the new text box so we can give it a prop that tells it to focus itself when it's displayed
+            Doc.AddDocToList(this.props.place, 'data', newDoc);
             this._stack?.scrollToBottom();
             e.stopPropagation();
             e.preventDefault();
@@ -47,9 +47,9 @@ export class MapBoxInfoWindow extends React.Component<MapBoxInfoWindowProps & Vi
     removeDoc = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((p, d) => p && Doc.RemoveDocFromList(this.props.place, 'data', d), true as boolean);
     render() {
         return (
-            <InfoWindow 
-            // anchor={this.props.markerMap[this.props.place[Id]]} 
-            onCloseClick={this.handleInfoWindowClose}>
+            <InfoWindow
+                // anchor={this.props.markerMap[this.props.place[Id]]}
+                onCloseClick={this.handleInfoWindowClose}>
                 <div className="mapbox-infowindow">
                     <div style={{ width: this.props.PanelWidth(), height: this.props.PanelHeight() }}>
                         <CollectionStackingView
@@ -57,7 +57,7 @@ export class MapBoxInfoWindow extends React.Component<MapBoxInfoWindowProps & Vi
                             {...this.props}
                             setContentView={emptyFunction}
                             Document={this.props.place}
-                            DataDoc={undefined}
+                            TemplateDataDocument={undefined}
                             fieldKey="data"
                             NativeWidth={returnZero}
                             NativeHeight={returnZero}
diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx
index 6caef0daa..c2e204eab 100644
--- a/src/client/views/nodes/ScreenshotBox.tsx
+++ b/src/client/views/nodes/ScreenshotBox.tsx
@@ -37,7 +37,7 @@ declare class MediaRecorder {
 //     setRaised: (r: { coord: Vector2, off: Vector3 }[]) => void;
 //     x: number;
 //     y: number;
-//     rootDoc: Doc;
+//     doc: Doc;
 //     color: string;
 // }
 
@@ -69,8 +69,8 @@ declare class MediaRecorder {
 //         const normals = new Float32Array(quad_normals);
 //         const uvs = new Float32Array(quad_uvs); // Each vertex has one uv coordinate for texture mapping
 //         const indices = new Uint32Array(quad_indices);          // Use the four vertices to draw the two triangles that make up the square.
-//         const popOut = () => NumCast(this.props.rootDoc.popOut);
-//         const popOff = () => NumCast(this.props.rootDoc.popOff);
+//         const popOut = () => NumCast(this.props.Document.popOut);
+//         const popOff = () => NumCast(this.props.Document.popOff);
 //         return (
 //             <mesh key={`mesh${topLeft[0]}${topLeft[1]}`} onClick={action(async e => {
 //                 this.props.setRaised([
@@ -207,7 +207,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
         //     const colors = ["yellow", "red", "orange", "brown", "maroon", "gray"];
         //     let count = 0;
         //     numberRange(this._numScreens).forEach(x => numberRange(this._numScreens).forEach(y => screens.push(
-        //         <VideoTile rootDoc={this.layoutDoc} color={colors[count++ % colors.length]} x={x} y={y} raised={this._raised} setRaised={this.setRaised} />)));
+        //         <VideoTile doc={this.layoutDoc} color={colors[count++ % colors.length]} x={x} y={y} raised={this._raised} setRaised={this.setRaised} />)));
         //     return <Canvas key="canvas" id="CANCAN" style={{ width: this.props.PanelWidth(), height: this.props.PanelHeight() }} gl={{ antialias: false }} colorManagement={false} onCreated={props => {
         //         this._camera = props.camera;
         //         props.camera.position.set(this._numScreens / 2, this._numScreens / 2, this._numScreens - 2);
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 8a927560d..42e8ace6e 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -15,7 +15,7 @@ import { EditorView } from 'prosemirror-view';
 import { BsMarkdownFill } from 'react-icons/bs';
 import { DateField } from '../../../../fields/DateField';
 import { Doc, DocListCast, Field, Opt } from '../../../../fields/Doc';
-import { AclAdmin, AclAugment, AclEdit, AclSelfEdit, DocCss, ForceServerWrite, UpdatingFromServer } from '../../../../fields/DocSymbols';
+import { AclAdmin, AclAugment, AclEdit, AclSelfEdit, DocCss, DocData, ForceServerWrite, UpdatingFromServer } from '../../../../fields/DocSymbols';
 import { Id } from '../../../../fields/FieldSymbols';
 import { InkTool } from '../../../../fields/InkField';
 import { List } from '../../../../fields/List';
@@ -190,7 +190,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
     private gptRes: string = '';
 
     public static PasteOnLoad: ClipboardEvent | undefined;
-    public static SelectOnLoad = '';
+    private static SelectOnLoad: Doc | undefined;
+    public static SetSelectOnLoad(doc: Doc) {
+        FormattedTextBox.SelectOnLoad = doc;
+    }
     public static DontSelectInitialText = false; // whether initial text should be selected or not
     public static SelectOnLoadChar = '';
     public static IsFragment(html: string) {
@@ -311,7 +314,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
             e.stopPropagation();
             const targetCreator = (annotationOn?: Doc) => {
                 const target = DocUtils.GetNewTextDoc('Note linked to ' + this.Document.title, 0, 0, 100, 100, undefined, annotationOn);
-                FormattedTextBox.SelectOnLoad = target[Id];
+                FormattedTextBox.SetSelectOnLoad(target);
                 return target;
             };
 
@@ -1511,10 +1514,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
             (this._editorView as any).TextView = this;
         }
 
-        const selectOnLoad = DocCast(this.Document.rootDocument, this.Document)[Id] === FormattedTextBox.SelectOnLoad && (!LightboxView.LightboxDoc || LightboxView.IsLightboxDocView(this.props.docViewPath()));
+        const selectOnLoad = Doc.AreProtosEqual(this.props.TemplateDataDocument ?? this.Document, FormattedTextBox.SelectOnLoad) && (!LightboxView.LightboxDoc || LightboxView.IsLightboxDocView(this.props.docViewPath()));
         if (this._editorView && selectOnLoad && !this.props.dontRegisterView && !this.props.dontSelectOnLoad && this.isActiveTab(this.ProseRef)) {
             const selLoadChar = FormattedTextBox.SelectOnLoadChar;
-            FormattedTextBox.SelectOnLoad = '';
+            FormattedTextBox.SelectOnLoad = undefined;
             this.props.select(false);
             if (selLoadChar) {
                 const $from = this._editorView.state.selection.anchor ? this._editorView.state.doc.resolve(this._editorView.state.selection.anchor - 1) : undefined;
diff --git a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
index ec11079b4..08bad2d57 100644
--- a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
+++ b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
@@ -47,7 +47,7 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
     }
 
     const canEdit = (state: any) => {
-        switch (GetEffectiveAcl(props.DataDoc)) {
+        switch (GetEffectiveAcl(props.TemplateDataDocument)) {
             case AclAugment:
                 const prevNode = state.selection.$cursor.nodeBefore;
                 const prevUser = !prevNode ? Doc.CurrentUserEmail : prevNode.marks[prevNode.marks.length - 1].attrs.userid;
@@ -334,7 +334,7 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
 
     //Command to create a blank space
     bind('Space', (state: EditorState, dispatch: (tx: Transaction) => void) => {
-        if (props.DataDoc && GetEffectiveAcl(props.DataDoc) != AclEdit && GetEffectiveAcl(props.DataDoc) != AclAugment && GetEffectiveAcl(props.DataDoc) != AclAdmin) return true;
+        if (props.TemplateDataDocument && GetEffectiveAcl(props.TemplateDataDocument) != AclEdit && GetEffectiveAcl(props.TemplateDataDocument) != AclAugment && GetEffectiveAcl(props.TemplateDataDocument) != AclAdmin) return true;
         const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
         dispatch(splitMetadata(marks, state.tr));
         return false;
diff --git a/src/client/views/nodes/importBox/ImportElementBox.tsx b/src/client/views/nodes/importBox/ImportElementBox.tsx
index 170626cd2..c4c89d8b1 100644
--- a/src/client/views/nodes/importBox/ImportElementBox.tsx
+++ b/src/client/views/nodes/importBox/ImportElementBox.tsx
@@ -24,7 +24,6 @@ export class ImportElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
                     LayoutTemplateString={undefined}
                     Document={this.Document}
                     isContentActive={returnFalse}
-                    DataDoc={undefined}
                     addDocument={returnFalse}
                     ScreenToLocalTransform={this.screenToLocalXf}
                     hideResizeHandles={true}
diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx
index b104e8b70..f8aebd021 100644
--- a/src/client/views/nodes/trails/PresElementBox.tsx
+++ b/src/client/views/nodes/trails/PresElementBox.tsx
@@ -56,7 +56,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
     // Since this node is being rendered with a template, this method retrieves
     // the actual slide being rendered from the auto-generated rendering template
     @computed get slideDoc() {
-        return Cast(this.Document.rootDocument, Doc, null) || this.props.Document;
+        return this.props.TemplateDataDocument ?? this.props.Document;
     }
 
     // this is the document in the workspaces that is targeted by the slide
@@ -104,7 +104,6 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
             <div className="presItem-embedded" style={{ height: this.embedHeight(), width: '50%' }}>
                 <DocumentView
                     Document={PresBox.targetRenderedDoc(this.slideDoc)}
-                    DataDoc={undefined} //this.targetDoc[DataSym] !== this.targetDoc && this.targetDoc[DataSym]}
                     PanelWidth={this.embedWidth}
                     PanelHeight={this.embedHeight}
                     isContentActive={this.props.isContentActive}
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index 1dfcf174e..7f71ee678 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -100,7 +100,6 @@ export class TopBar extends React.Component {
             <div className="collectionMenu-contMenuButtons" style={{ height: '100%' }}>
                 <CollectionLinearView
                     Document={selDoc}
-                    DataDoc={undefined}
                     fieldKey="data"
                     dropAction="embed"
                     setHeight={returnFalse}
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 24c18c232..525ff7ec0 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -751,7 +751,7 @@ export namespace Doc {
             });
     }
 
-    const _pendingMap: Map<string, boolean> = new Map();
+    const _pendingMap = new Set<string>();
     //
     // 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
@@ -773,19 +773,19 @@ export namespace Doc {
 
         if (templateLayoutDoc.resolvedDataDoc instanceof Promise) {
             expandedTemplateLayout = undefined;
-            _pendingMap.set(targetDoc[Id] + expandedLayoutFieldKey, true);
-        } else if (expandedTemplateLayout === undefined && !_pendingMap.get(targetDoc[Id] + expandedLayoutFieldKey)) {
-            if (templateLayoutDoc.resolvedDataDoc === (targetDoc.rootDocument || Doc.GetProto(targetDoc))) {
+            _pendingMap.add(targetDoc[Id] + expandedLayoutFieldKey);
+        } else if (expandedTemplateLayout === undefined && !_pendingMap.has(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 = DocCast(templateLayoutDoc.proto, 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, true);
+                    _pendingMap.add(targetDoc[Id] + expandedLayoutFieldKey);
                     setTimeout(
                         action(() => {
                             const newLayoutDoc = Doc.MakeDelegate(templateLayoutDoc, undefined, '[' + templateLayoutDoc.title + ']');
-                            newLayoutDoc.rootDocument = targetDoc;
                             const dataDoc = Doc.GetProto(targetDoc);
+                            newLayoutDoc.rootDocument = targetDoc;
                             newLayoutDoc.embedContainer = targetDoc;
                             newLayoutDoc.resolvedDataDoc = dataDoc;
                             newLayoutDoc['acl-Guest'] = SharingPermissions.Edit;
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 791ce8d8f..bdd657575 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -384,7 +384,6 @@ export class MobileInterface extends React.Component {
             <div style={{ position: 'relative', top: '198px', height: `calc(100% - 350px)`, width: '100%', left: '0%' }}>
                 <DocumentView
                     Document={this.mainContainer}
-                    DataDoc={undefined}
                     addDocument={returnFalse}
                     addDocTab={returnFalse}
                     pinToPres={emptyFunction}
-- 
cgit v1.2.3-70-g09d2


From 678abdfceaa25cb84c4232f44a7c161b6d39b546 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Fri, 1 Dec 2023 12:17:10 -0500
Subject: cleaning up documentview props.   got rid of special cases for
 keyValueBox.  made fitToContents work cleanly for native scaled docs.

---
 src/client/views/DocumentDecorations.tsx           |  3 -
 src/client/views/MainView.tsx                      |  4 +-
 src/client/views/SidebarAnnos.tsx                  |  2 +-
 src/client/views/StyleProvider.tsx                 |  2 +-
 .../views/collections/CollectionCarousel3DView.tsx |  1 -
 .../views/collections/CollectionCarouselView.tsx   | 36 +++++------
 .../views/collections/CollectionNoteTakingView.tsx |  5 +-
 .../collections/CollectionStackedTimeline.tsx      |  3 +-
 .../views/collections/CollectionStackingView.tsx   |  5 +-
 src/client/views/collections/CollectionView.tsx    | 14 ++--
 src/client/views/collections/TreeView.tsx          |  7 +-
 .../CollectionFreeFormLinkView.tsx                 |  4 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 21 +++---
 .../collectionGrid/CollectionGridView.tsx          |  1 -
 .../CollectionMulticolumnView.tsx                  |  5 +-
 .../CollectionMultirowView.tsx                     |  5 +-
 src/client/views/nodes/DocumentView.tsx            | 75 ++++++++--------------
 src/client/views/nodes/KeyValueBox.tsx             |  3 +-
 src/client/views/nodes/LabelBox.tsx                |  4 +-
 src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx |  4 +-
 20 files changed, 84 insertions(+), 120 deletions(-)

(limited to 'src/client/views/collections/CollectionStackedTimeline.tsx')

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 719055149..b9fcf5360 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -611,9 +611,6 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
     get selectionTitle(): string {
         if (SelectionManager.Views().length === 1) {
             const selected = SelectionManager.Views()[0];
-            if (selected.ComponentView?.getTitle?.()) {
-                return selected.ComponentView.getTitle();
-            }
             if (this._titleControlString.startsWith('=')) {
                 return ScriptField.MakeFunction(this._titleControlString.substring(1), { doc: Doc.name })!.script.run({ self: selected.Document, this: selected.layoutDoc }, console.log).result?.toString() || '';
             }
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 2e3817cb6..58c1570b2 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -609,7 +609,7 @@ export class MainView extends React.Component {
                     isDocumentActive={returnTrue} // headerBar is always documentActive (ie, the docView gets pointer events)
                     isContentActive={returnTrue} // headerBar is awlays contentActive which means its items are always documentActive
                     ScreenToLocalTransform={this.headerBarScreenXf}
-                    childHideResizeHandles={returnTrue}
+                    childHideResizeHandles={true}
                     childDragAction="move"
                     dontRegisterView={true}
                     hideResizeHandles={true}
@@ -988,7 +988,7 @@ export class MainView extends React.Component {
                 isDocumentActive={returnTrue} // headerBar is always documentActive (ie, the docView gets pointer events)
                 isContentActive={returnTrue} // headerBar is awlays contentActive which means its items are always documentActive
                 ScreenToLocalTransform={Transform.Identity}
-                childHideResizeHandles={returnTrue}
+                childHideResizeHandles={true}
                 childDragAction="move"
                 dontRegisterView={true}
                 PanelWidth={this.headerBarDocWidth}
diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx
index 8e62ed999..049ba4841 100644
--- a/src/client/views/SidebarAnnos.tsx
+++ b/src/client/views/SidebarAnnos.tsx
@@ -248,7 +248,7 @@ export class SidebarAnnos extends React.Component<FieldViewProps & ExtraProps> {
                         isAnyChildContentActive={returnFalse}
                         childDocumentsActive={this.props.isContentActive}
                         whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged}
-                        childHideDecorationTitle={returnTrue}
+                        childHideDecorationTitle={true}
                         removeDocument={this.removeDocument}
                         moveDocument={this.moveDocument}
                         addDocument={this.addDocument}
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 2dd58fa80..806c9c001 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -265,7 +265,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
         }
         case StyleProp.PointerEvents:
             if (StrCast(doc?.pointerEvents) && !docProps?.LayoutTemplateString?.includes(KeyValueBox.name)) return StrCast(doc!.pointerEvents); // honor pointerEvents field (set by lock button usually) if it's not a keyValue view of the Doc
-            if (docProps?.DocumentView?.().ComponentView?.overridePointerEvents?.() !== undefined) return docProps?.DocumentView?.().ComponentView?.overridePointerEvents?.();
+            if (docProps?.DocumentView?.().props.LayoutTemplateString?.includes(KeyValueBox.name)) return 'all';
             if (DocumentView.ExploreMode || doc?.layout_unrendered) return isInk() ? 'visiblePainted' : 'all';
             if (props?.pointerEvents?.() === 'none') return 'none';
             if (opacity() === 0) return 'none';
diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx
index 6715e5675..d6368464a 100644
--- a/src/client/views/collections/CollectionCarousel3DView.tsx
+++ b/src/client/views/collections/CollectionCarousel3DView.tsx
@@ -66,7 +66,6 @@ export class CollectionCarousel3DView extends CollectionSubView() {
                     //suppressSetHeight={true}
                     NativeWidth={returnZero}
                     NativeHeight={returnZero}
-                    shouldNotScale={undefined}
                     layout_fitWidth={undefined}
                     onDoubleClick={this.onChildDoubleClick}
                     renderDepth={this.props.renderDepth + 1}
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index c873ef891..299a4d5d3 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -4,7 +4,7 @@ import { observer } from 'mobx-react';
 import * as React from 'react';
 import { StopEvent, emptyFunction, returnFalse, returnOne, returnZero } from '../../../Utils';
 import { Doc, Opt } from '../../../fields/Doc';
-import { NumCast, ScriptCast, StrCast } from '../../../fields/Types';
+import { DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
 import { DragManager } from '../../util/DragManager';
 import { StyleProp } from '../StyleProvider';
 import { DocumentView, DocumentViewProps } from '../nodes/DocumentView';
@@ -51,7 +51,7 @@ export class CollectionCarouselView extends CollectionSubView() {
         const index = NumCast(this.layoutDoc._carousel_index);
         const curDoc = this.childLayoutPairs?.[index];
         const captionProps = { ...this.props, NativeScaling: returnOne, PanelWidth: this.captionWidth, fieldKey: 'caption', setHeight: undefined, setContentView: undefined };
-        const show_captions = StrCast(this.layoutDoc._layout_showCaption);
+        const carouselShowsCaptions = StrCast(this.layoutDoc._layout_showCaption);
         return !(curDoc?.layout instanceof Doc) ? null : (
             <>
                 <div className="collectionCarouselView-image" key="image">
@@ -59,36 +59,36 @@ export class CollectionCarouselView extends CollectionSubView() {
                         {...this.props}
                         NativeWidth={returnZero}
                         NativeHeight={returnZero}
-                        shouldNotScale={undefined}
                         layout_fitWidth={undefined}
                         setContentView={undefined}
                         onDoubleClick={this.onContentDoubleClick}
                         onClick={this.onContentClick}
                         isDocumentActive={this.props.childDocumentsActive?.() ? this.props.isDocumentActive : this.props.isContentActive}
                         isContentActive={this.props.childContentsActive ?? this.props.isContentActive() === false ? returnFalse : emptyFunction}
-                        hideCaptions={show_captions ? true : false}
+                        hideCaptions={!!carouselShowsCaptions} // hide captions if the carousel is configured to show the captions
                         renderDepth={this.props.renderDepth + 1}
                         LayoutTemplate={this.props.childLayoutTemplate}
                         LayoutTemplateString={this.props.childLayoutString}
                         Document={curDoc.layout}
-                        TemplateDataDocument={curDoc.layout.resolvedDataDoc as Doc}
+                        TemplateDataDocument={DocCast(curDoc.layout.resolvedDataDoc)}
                         PanelHeight={this.panelHeight}
                         bringToFront={returnFalse}
                     />
                 </div>
-                <div
-                    className="collectionCarouselView-caption"
-                    key="caption"
-                    onWheel={StopEvent}
-                    style={{
-                        display: show_captions ? undefined : 'none',
-                        borderRadius: this.props.styleProvider?.(this.layoutDoc, captionProps, StyleProp.BorderRounding),
-                        marginRight: this.marginX,
-                        marginLeft: this.marginX,
-                        width: `calc(100% - ${this.marginX * 2}px)`,
-                    }}>
-                    <FormattedTextBox key={index} {...captionProps} fieldKey={show_captions} styleProvider={this.captionStyleProvider} Document={curDoc.layout} TemplateDataDocument={undefined} />
-                </div>
+                {!carouselShowsCaptions ? null : (
+                    <div
+                        className="collectionCarouselView-caption"
+                        key="caption"
+                        onWheel={StopEvent}
+                        style={{
+                            borderRadius: this.props.styleProvider?.(this.layoutDoc, captionProps, StyleProp.BorderRounding),
+                            marginRight: this.marginX,
+                            marginLeft: this.marginX,
+                            width: `calc(100% - ${this.marginX * 2}px)`,
+                        }}>
+                        <FormattedTextBox key={index} {...captionProps} fieldKey={carouselShowsCaptions} styleProvider={this.captionStyleProvider} Document={curDoc.layout} TemplateDataDocument={undefined} />
+                    </div>
+                )}
             </>
         );
     }
diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx
index e92cb353f..ad5431c8e 100644
--- a/src/client/views/collections/CollectionNoteTakingView.tsx
+++ b/src/client/views/collections/CollectionNoteTakingView.tsx
@@ -257,9 +257,8 @@ export class CollectionNoteTakingView extends CollectionSubView() {
                 ScreenToLocalTransform={noteTakingDocTransform}
                 focus={this.focusDocument}
                 childFilters={this.childDocFilters}
-                hideDecorationTitle={this.props.childHideDecorationTitle?.()}
-                hideResizeHandles={this.props.childHideResizeHandles?.()}
-                hideTitle={this.props.childHideTitle?.()}
+                hideDecorationTitle={this.props.childHideDecorationTitle}
+                hideResizeHandles={this.props.childHideResizeHandles}
                 childFiltersByRanges={this.childDocRangeFilters}
                 searchFilterDocs={this.searchFilterDocs}
                 addDocument={this.props.addDocument}
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index 57ea777e4..7fee1cda6 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -17,7 +17,6 @@ import { DragManager } from '../../util/DragManager';
 import { FollowLinkScript, IsFollowLinkScript, LinkFollower } from '../../util/LinkFollower';
 import { LinkManager } from '../../util/LinkManager';
 import { ScriptingGlobals } from '../../util/ScriptingGlobals';
-import { SelectionManager } from '../../util/SelectionManager';
 import { SnappingManager } from '../../util/SnappingManager';
 import { Transform } from '../../util/Transform';
 import { undoBatch, UndoManager } from '../../util/UndoManager';
@@ -35,6 +34,7 @@ export type CollectionStackedTimelineProps = {
     playLink: (linkDoc: Doc, options: DocFocusOptions) => void;
     playFrom: (seekTimeInSeconds: number, endTime?: number) => void;
     playing: () => boolean;
+    thumbnails?: () => string[];
     setTime: (time: number) => void;
     startTag: string;
     endTag: string;
@@ -43,7 +43,6 @@ export type CollectionStackedTimelineProps = {
     rawDuration: number;
     dataFieldKey: string;
     fieldKey: string;
-    thumbnails?: () => string[];
 };
 
 // trimming state: shows full clip, current trim bounds, or not trimming
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 10ee01e0b..59e0c60b9 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -349,9 +349,8 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
                 ScreenToLocalTransform={stackedDocTransform}
                 focus={this.focusDocument}
                 childFilters={this.childDocFilters}
-                hideDecorationTitle={this.props.childHideDecorationTitle?.()}
-                hideResizeHandles={this.props.childHideResizeHandles?.()}
-                hideTitle={this.props.childHideTitle?.()}
+                hideDecorationTitle={this.props.childHideDecorationTitle}
+                hideResizeHandles={this.props.childHideResizeHandles}
                 childFiltersByRanges={this.childDocRangeFilters}
                 searchFilterDocs={this.searchFilterDocs}
                 xPadding={NumCast(this.layoutDoc._childXPadding, this.props.childXPadding)}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 898b453f4..2e4c5af6b 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -11,7 +11,6 @@ import { DocUtils } from '../../documents/Documents';
 import { CollectionViewType } from '../../documents/DocumentTypes';
 import { dropActionType } from '../../util/DragManager';
 import { ImageUtils } from '../../util/Import & Export/ImageUtils';
-import { InteractionUtils } from '../../util/InteractionUtils';
 import { ContextMenu } from '../ContextMenu';
 import { ContextMenuProps } from '../ContextMenuItem';
 import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComponent';
@@ -50,10 +49,9 @@ interface CollectionViewProps_ extends FieldViewProps {
     childlayout_showTitle?: () => string;
     childOpacity?: () => number;
     childContextMenuItems?: () => { script: ScriptField; label: string }[];
-    childHideTitle?: () => boolean; // whether to hide the documentdecorations title for children
-    childHideDecorationTitle?: () => boolean;
-    childHideResizeHandles?: () => boolean;
     childLayoutTemplate?: () => Doc | undefined; // specify a layout Doc template to use for children of the collection
+    childHideDecorationTitle?: boolean;
+    childHideResizeHandles?: boolean;
     childDragAction?: dropActionType;
     childXPadding?: number;
     childYPadding?: number;
@@ -230,8 +228,6 @@ export class CollectionView extends ViewBoxAnnotatableComponent<ViewBoxAnnotatab
 
     bodyPanelWidth = () => this.props.PanelWidth();
 
-    childHideResizeHandles = () => this.props.childHideResizeHandles?.() ?? BoolCast(this.Document.childHideResizeHandles);
-    childHideDecorationTitle = () => this.props.childHideDecorationTitle?.() ?? BoolCast(this.Document.childHideDecorationTitle);
     childLayoutTemplate = () => this.props.childLayoutTemplate?.() || Cast(this.Document.childLayoutTemplate, Doc, null);
     isContentActive = (outsideReaction?: boolean) => this._isContentActive;
 
@@ -244,14 +240,14 @@ export class CollectionView extends ViewBoxAnnotatableComponent<ViewBoxAnnotatab
             removeDocument: this.removeDocument,
             isContentActive: this.isContentActive,
             isAnyChildContentActive: this.isAnyChildContentActive,
-            whenChildContentsActiveChanged: this.whenChildContentsActiveChanged,
             PanelWidth: this.bodyPanelWidth,
             PanelHeight: this.props.PanelHeight,
             ScreenToLocalTransform: this.screenToLocalTransform,
             childLayoutTemplate: this.childLayoutTemplate,
+            whenChildContentsActiveChanged: this.whenChildContentsActiveChanged,
             childLayoutString: StrCast(this.Document.childLayoutString, this.props.childLayoutString),
-            childHideResizeHandles: this.childHideResizeHandles,
-            childHideDecorationTitle: this.childHideDecorationTitle,
+            childHideResizeHandles: this.props.childHideResizeHandles ?? BoolCast(this.Document.childHideResizeHandles),
+            childHideDecorationTitle: this.props.childHideDecorationTitle ?? BoolCast(this.Document.childHideDecorationTitle),
         };
         return (
             <div
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index a756007f8..ba4ed6074 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -199,10 +199,10 @@ export class TreeView extends React.Component<TreeViewProps> {
         this._disposers.selection?.();
         if (!docView) {
             this._editTitle = false;
-        } else if (docView.isSelected()) {
+        } else if (docView.SELECTED) {
             this._editTitle = true;
             this._disposers.selection = reaction(
-                () => docView.isSelected(),
+                () => docView.SELECTED,
                 isSel => !isSel && this.setEditTitle(undefined)
             );
         } else {
@@ -981,9 +981,8 @@ export class TreeView extends React.Component<TreeViewProps> {
                 moveDocument={this.move}
                 removeDocument={this.props.removeDoc}
                 ScreenToLocalTransform={this.getTransform}
-                NativeHeight={return18}
+                NativeHeight={returnZero}
                 NativeWidth={returnZero}
-                shouldNotScale={returnTrue}
                 PanelWidth={this.titleWidth}
                 PanelHeight={return18}
                 contextMenuItems={this.contextMenuItems}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
index 5e0cf1d23..0c0d45a30 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -223,8 +223,8 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
         const pt2normlen = Math.sqrt(pt2norm[0] * pt2norm[0] + pt2norm[1] * pt2norm[1]) || 1;
         const pt1normalized = [pt1norm[0] / pt1normlen, pt1norm[1] / pt1normlen];
         const pt2normalized = [pt2norm[0] / pt2normlen, pt2norm[1] / pt2normlen];
-        const aActive = A.isSelected() || A.Document[Brushed];
-        const bActive = B.isSelected() || B.Document[Brushed];
+        const aActive = A.SELECTED || A.Document[Brushed];
+        const bActive = B.SELECTED || B.Document[Brushed];
 
         const textX = (Math.min(pt1[0], pt2[0]) + Math.max(pt1[0], pt2[0])) / 2 + NumCast(LinkDocs[0].link_relationship_OffsetX);
         const textY = (pt1[1] + pt2[1]) / 2 + NumCast(LinkDocs[0].link_relationship_OffsetY);
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index ab718c351..d242b1356 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -122,12 +122,14 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         return renderableEles;
     }
     @computed get fitToContentVals() {
+        const hgt = this.contentBounds.b - this.contentBounds.y;
+        const wid = this.contentBounds.r - this.contentBounds.x;
         return {
-            bounds: { ...this.contentBounds, cx: (this.contentBounds.x + this.contentBounds.r) / 2, cy: (this.contentBounds.y + this.contentBounds.b) / 2 },
+            bounds: { ...this.contentBounds, cx: this.contentBounds.x + wid / 2, cy: this.contentBounds.y + hgt / 2 },
             scale:
-                !this.childDocs.length || !Number.isFinite(this.contentBounds.b - this.contentBounds.y) || !Number.isFinite(this.contentBounds.r - this.contentBounds.x)
-                    ? 1
-                    : Math.min(this.props.PanelHeight() / (this.contentBounds.b - this.contentBounds.y), this.props.PanelWidth() / (this.contentBounds.r - this.contentBounds.x)),
+                (!this.childDocs.length || !Number.isFinite(hgt) || !Number.isFinite(wid)
+                    ? 1 //
+                    : Math.min(this.props.PanelHeight() / hgt, this.props.PanelWidth() / wid)) / (this.props.NativeDimScaling?.() || 1),
         };
     }
     @computed get fitContentsToBox() {
@@ -144,19 +146,19 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
               );
     }
     @computed get nativeWidth() {
-        return this.props.NativeWidth?.() || (this.fitContentsToBox ? 0 : Doc.NativeWidth(this.Document, Cast(this.Document.resolvedDataDoc, Doc, null)));
+        return this.props.NativeWidth?.() || Doc.NativeWidth(this.Document, Cast(this.Document.resolvedDataDoc, Doc, null));
     }
     @computed get nativeHeight() {
-        return this.props.NativeHeight?.() || (this.fitContentsToBox ? 0 : Doc.NativeHeight(this.Document, Cast(this.Document.resolvedDataDoc, Doc, null)));
+        return this.props.NativeHeight?.() || Doc.NativeHeight(this.Document, Cast(this.Document.resolvedDataDoc, Doc, null));
     }
     @computed get cachedCenteringShiftX(): number {
-        const scaling = this.fitContentsToBox || !this.nativeDimScaling ? 1 : this.nativeDimScaling;
+        const scaling = !this.nativeDimScaling ? 1 : this.nativeDimScaling;
         return this.props.isAnnotationOverlay || this.props.originTopLeft ? 0 : this.props.PanelWidth() / 2 / scaling; // shift so pan position is at center of window for non-overlay collections
     }
     @computed get cachedCenteringShiftY(): number {
         const dv = this.props.DocumentView?.();
         const fitWidth = this.props.layout_fitWidth?.(this.Document) ?? dv?.layoutDoc.layout_fitWidth;
-        const scaling = this.fitContentsToBox || !this.nativeDimScaling ? 1 : this.nativeDimScaling;
+        const scaling = !this.nativeDimScaling ? 1 : this.nativeDimScaling;
         // if freeform has a native aspect, then the panel height needs to be adjusted to match it
         const aspect = dv?.nativeWidth && dv?.nativeHeight && !fitWidth ? dv.nativeHeight / dv.nativeWidth : this.props.PanelHeight() / this.props.PanelWidth();
         return this.props.isAnnotationOverlay || this.props.originTopLeft ? 0 : (aspect * this.props.PanelWidth()) / 2 / scaling; // shift so pan position is at center of window for non-overlay collections
@@ -221,14 +223,12 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     onChildDoubleClickHandler = () => this.props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick);
     elementFunc = () => this._layoutElements;
     fitContentOnce = () => {
-        if (this.props.DocumentView?.().nativeWidth) return;
         const vals = this.fitToContentVals;
         this.layoutDoc._freeform_panX = vals.bounds.cx;
         this.layoutDoc._freeform_panY = vals.bounds.cy;
         this.layoutDoc._freeform_scale = vals.scale;
     };
     freeformData = (force?: boolean) => (!this._firstRender && (this.fitContentsToBox || force) ? this.fitToContentVals : undefined);
-    ignoreNativeDimScaling = () => (this.fitContentsToBox ? true : false);
     // freeform_panx, freeform_pany, freeform_scale all attempt to get values first from the layout controller, then from the layout/dataDoc (or template layout doc), and finally from the resolved template data document.
     // this search order, for example, allows icons of cropped images to find the panx/pany/zoom on the cropped image's data doc instead of the usual layout doc because the zoom/panX/panY define the cropped image
     panX = () => this.freeformData()?.bounds.cx ?? NumCast(this.Document[this.panXFieldKey], NumCast(Cast(this.Document.resolvedDataDoc, Doc, null)?.freeform_panX, 1));
@@ -1244,7 +1244,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                 layout_showTitle={this.props.childlayout_showTitle}
                 dontRegisterView={this.props.dontRegisterView}
                 pointerEvents={this.childPointerEventsFunc}
-                //fitContentsToBox={this.props.fitContentsToBox || BoolCast(this.props.treeView_FreezeChildDimensions)} // bcz: check this
             />
         );
     }
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
index 82f0171eb..8daed9746 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
@@ -187,7 +187,6 @@ export class CollectionGridView extends CollectionSubView() {
         return (
             <DocumentView
                 {...this.props}
-                shouldNotScale={returnFalse}
                 NativeWidth={returnZero}
                 NativeHeight={returnZero}
                 setContentView={emptyFunction}
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
index 043914985..e7af91390 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
@@ -261,7 +261,6 @@ export class CollectionMulticolumnView extends CollectionSubView() {
                 renderDepth={this.props.renderDepth + 1}
                 PanelWidth={width}
                 PanelHeight={height}
-                shouldNotScale={shouldNotScale}
                 rootSelected={this.rootSelected}
                 dragAction={(this.props.Document.childDragAction ?? this.props.childDragAction) as dropActionType}
                 onClick={this.onChildClickHandler}
@@ -270,8 +269,8 @@ export class CollectionMulticolumnView extends CollectionSubView() {
                 ScreenToLocalTransform={dxf}
                 isContentActive={this.isChildContentActive}
                 isDocumentActive={this.props.childDocumentsActive?.() || this.Document._childDocumentsActive ? this.props.isDocumentActive : this.isContentActive}
-                hideResizeHandles={childLayout.layout_fitWidth || this.props.childHideResizeHandles?.() ? true : false}
-                hideDecorationTitle={this.props.childHideDecorationTitle?.()}
+                hideResizeHandles={childLayout.layout_fitWidth || this.props.childHideResizeHandles ? true : false}
+                hideDecorationTitle={this.props.childHideDecorationTitle}
                 fitContentsToBox={this.props.fitContentsToBox}
                 focus={this.props.focus}
                 childFilters={this.childDocFilters}
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
index 2d4750de3..ef66e8ce5 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
@@ -257,7 +257,6 @@ export class CollectionMultirowView extends CollectionSubView() {
                 renderDepth={this.props.renderDepth + 1}
                 PanelWidth={width}
                 PanelHeight={height}
-                shouldNotScale={shouldNotScale}
                 rootSelected={this.rootSelected}
                 dropAction={StrCast(this.Document.childDragAction) as dropActionType}
                 onClick={this.onChildClickHandler}
@@ -265,8 +264,8 @@ export class CollectionMultirowView extends CollectionSubView() {
                 ScreenToLocalTransform={dxf}
                 isContentActive={this.isChildContentActive}
                 isDocumentActive={this.props.childDocumentsActive?.() || this.Document._childDocumentsActive ? this.props.isDocumentActive : this.isContentActive}
-                hideResizeHandles={layout.layout_fitWidth || this.props.childHideResizeHandles?.() ? true : false}
-                hideDecorationTitle={this.props.childHideDecorationTitle?.()}
+                hideResizeHandles={layout.layout_fitWidth || this.props.childHideResizeHandles ? true : false}
+                hideDecorationTitle={this.props.childHideDecorationTitle}
                 fitContentsToBox={this.props.fitContentsToBox}
                 dragAction={this.props.childDragAction}
                 focus={this.props.focus}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 977a9bc54..bfbe3389f 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -111,6 +111,8 @@ export interface DocFocusOptions {
 export type DocFocusFunc = (doc: Doc, options: DocFocusOptions) => Opt<number>;
 export type StyleProviderFunc = (doc: Opt<Doc>, props: Opt<DocumentViewProps | FieldViewProps>, property: string) => any;
 export interface DocComponentView {
+    fieldKey?: string;
+    annotationKey?: string;
     updateIcon?: () => void; // updates the icon representation of the document
     getAnchor?: (addAsAnnotation: boolean, pinData?: PinProps) => Doc; // returns an Anchor Doc that represents the current state of the doc's componentview (e.g., the current playhead location of a an audio/video box)
     restoreView?: (viewSpec: Doc) => boolean;
@@ -119,10 +121,8 @@ export interface DocComponentView {
     getView?: (doc: Doc) => Promise<Opt<DocumentView>>; // returns a nested DocumentView for the specified doc or undefined
     addDocTab?: (doc: Doc, where: OpenWhere) => boolean; // determines how to add a document - used in following links to open the target ina local lightbox
     addDocument?: (doc: Doc | Doc[], annotationKey?: string) => boolean; // add a document (used only by collections)
-    ignoreNativeDimScaling?: () => boolean; // DocumentView's setup screenToLocal based on the doc having a nativeWidth/Height.  However, some content views (e.g., FreeFormView w/ fitContentsToBox set) may ignore the native dimensions so this flags the DocumentView to not do Nativre scaling.
     select?: (ctrlKey: boolean, shiftKey: boolean) => void;
     focus?: (textAnchor: Doc, options: DocFocusOptions) => Opt<number>;
-    menuControls?: () => JSX.Element; // controls to display in the top menu bar when the document is selected.
     isAnyChildContentActive?: () => boolean; // is any child content of the document active
     onClickScriptDisable?: () => 'never' | 'always'; // disable click scripts : never, always, or undefined = only when selected
     getKeyFrameEditing?: () => boolean; // whether the document is in keyframe editing mode (if it is, then all hidden documents that are not active at the keyframe time will still be shown)
@@ -136,11 +136,6 @@ export interface DocComponentView {
     componentUI?: (boundsLeft: number, boundsTop: number) => JSX.Element | null;
     dragStarting?: (snapToDraggedDoc: boolean, showGroupDragTarget: boolean, visited: Set<Doc>) => void;
     incrementalRendering?: () => void;
-    layout_fitWidth?: () => boolean; // whether the component always fits width (eg, KeyValueBox)
-    overridePointerEvents?: () => 'all' | 'none' | undefined; // if the conmponent overrides the pointer events for the document (e.g, KeyValueBox always allows pointer events)
-    fieldKey?: string;
-    annotationKey?: string;
-    getTitle?: () => string;
     getCenter?: (xf: Transform) => { X: number; Y: number };
     screenBounds?: () => Opt<{ left: number; top: number; right: number; bottom: number; center?: { X: number; Y: number } }>;
     ptToScreen?: (pt: { X: number; Y: number }) => { X: number; Y: number };
@@ -150,28 +145,24 @@ export interface DocComponentView {
 }
 // These props are passed to both FieldViews and DocumentViews
 export interface DocumentViewSharedProps {
-    DocumentView?: () => DocumentView;
     renderDepth: number;
     Document: Doc;
     TemplateDataDocument?: Doc;
+    scriptContext?: any; // can be assigned anything and will be passed as 'scriptContext' to any OnClick script that executes on this document
+    DocumentView?: () => DocumentView;
+    CollectionFreeFormDocumentView?: () => CollectionFreeFormDocumentView;
     fitContentsToBox?: () => boolean; // used by freeformview to fit its contents to its panel. corresponds to _freeform_fitContentsToBox property on a Document
     isGroupActive?: () => string | undefined; // is this document part of a group that is active
-    suppressSetHeight?: boolean;
     setContentView?: (view: DocComponentView) => any;
-    CollectionFreeFormDocumentView?: () => CollectionFreeFormDocumentView;
     PanelWidth: () => number;
     PanelHeight: () => number;
-    shouldNotScale?: () => boolean;
     docViewPath: () => DocumentView[];
-    childHideDecorationTitle?: () => boolean;
-    childHideResizeHandles?: () => boolean;
-    childDragAction?: dropActionType; // allows child documents to be dragged out of collection without holding the embedKey or dragging the doc decorations title bar.
+    childFilters: () => string[];
+    childFiltersByRanges: () => string[];
     styleProvider: Opt<StyleProviderFunc>;
     setTitleFocus?: () => void;
     focus: DocFocusFunc;
     layout_fitWidth?: (doc: Doc) => boolean | undefined;
-    childFilters: () => string[];
-    childFiltersByRanges: () => string[];
     searchFilterDocs: () => Doc[];
     layout_showTitle?: () => string;
     whenChildContentsActiveChanged: (isActive: boolean) => void;
@@ -184,26 +175,27 @@ export interface DocumentViewSharedProps {
     pinToPres: (document: Doc, pinProps: PinProps) => void;
     ScreenToLocalTransform: () => Transform;
     bringToFront: (doc: Doc, sendToBack?: boolean) => void;
-    dragAction?: dropActionType;
+    waitForDoubleClickToClick?: () => 'never' | 'always' | undefined;
+    defaultDoubleClick?: () => 'default' | 'ignore' | undefined;
+    pointerEvents?: () => Opt<string>;
     treeViewDoc?: Doc;
     xPadding?: number;
     yPadding?: number;
-    dropAction?: dropActionType;
     dontRegisterView?: boolean;
+    childHideDecorationTitle?: boolean;
+    childHideResizeHandles?: boolean;
+    childDragAction?: dropActionType; // allows child documents to be dragged out of collection without holding the embedKey or dragging the doc decorations title bar.
+    dropAction?: dropActionType;
+    dragAction?: dropActionType;
     dragWhenActive?: boolean;
+    dontHideOnDrag?: boolean;
     hideLinkButton?: boolean;
     hideCaptions?: boolean;
     ignoreAutoHeight?: boolean;
     forceAutoHeight?: boolean;
+    suppressSetHeight?: boolean;
     disableBrushing?: boolean; // should highlighting for this view be disabled when same document in another view is hovered over.
     onClickScriptDisable?: 'never' | 'always'; // undefined = only when selected
-    waitForDoubleClickToClick?: () => 'never' | 'always' | undefined;
-    defaultDoubleClick?: () => 'default' | 'ignore' | undefined;
-    pointerEvents?: () => Opt<string>;
-    scriptContext?: any; // can be assigned anything and will be passed as 'scriptContext' to any OnClick script that executes on this document
-    createNewFilterDoc?: () => void;
-    updateFilterDoc?: (doc: Doc) => void;
-    dontHideOnDrag?: boolean;
 }
 
 // these props are specific to DocuentViews
@@ -217,12 +209,11 @@ export interface DocumentViewProps extends DocumentViewSharedProps {
     hideOpenButton?: boolean;
     hideDeleteButton?: boolean;
     hideLinkAnchors?: boolean;
-    isDocumentActive?: () => boolean | undefined; // whether a document should handle pointer events
-    isContentActive: () => boolean | undefined; // whether document contents should handle pointer events
     contentPointerEvents?: 'none' | 'all' | undefined; // pointer events allowed for content of a document view.  eg. set to "none" in menuSidebar for sharedDocs so that you can select a document, but not interact with its contents
-    radialMenu?: String[];
     LayoutTemplateString?: string;
     dontCenter?: 'x' | 'y' | 'xy';
+    isDocumentActive?: () => boolean | undefined; // whether a document should handle pointer events
+    isContentActive: () => boolean | undefined; // whether document contents should handle pointer events
     NativeWidth?: () => number;
     NativeHeight?: () => number;
     NativeDimScaling?: () => number; // scaling the DocumentView does to transform its contents into its panel & needed by ScreenToLocal NOTE: Must also be added to FieldViewProps
@@ -240,8 +231,6 @@ export interface DocumentViewProps extends DocumentViewSharedProps {
 
 // these props are only available in DocumentViewIntenral
 export interface DocumentViewInternalProps extends DocumentViewProps {
-    NativeWidth: () => number;
-    NativeHeight: () => number;
     isSelected: () => boolean;
     select: (ctrlPressed: boolean, shiftPress?: boolean) => void;
     DocumentView: () => DocumentView;
@@ -325,12 +314,6 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
     @computed get finalLayoutKey() {
         return StrCast(this.Document.layout_fieldKey, 'layout');
     }
-    @computed get nativeWidth() {
-        return this.props.NativeWidth();
-    }
-    @computed get nativeHeight() {
-        return this.props.NativeHeight();
-    }
     @computed get disableClickScriptFunc() {
         const onScriptDisable = this.props.onClickScriptDisable ?? this._componentView?.onClickScriptDisable?.() ?? this.layoutDoc.onClickScriptDisable;
         // prettier-ignore
@@ -903,7 +886,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
     panelHeight = () => this.props.PanelHeight() - this.headerMargin;
     screenToLocal = () => this.props.ScreenToLocalTransform().translate(0, -this.headerMargin);
     onClickFunc: any = () => (this.disableClickScriptFunc ? undefined : this.onClickHandler);
-    setHeight = (height: number) => (this.layoutDoc._height = height);
+    setHeight = (height: number) => !this.props.suppressSetHeight && (this.layoutDoc._height = height);
     setContentView = action((view: { getAnchor?: (addAsAnnotation: boolean) => Doc; forward?: () => boolean; back?: () => boolean }) => (this._componentView = view));
     @observable _isContentActive: boolean | undefined;
 
@@ -943,12 +926,11 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
                     setContentView={this.setContentView}
                     childFilters={this.childFilters}
                     PanelHeight={this.panelHeight}
-                    setHeight={!this.props.suppressSetHeight ? this.setHeight : undefined}
+                    setHeight={this.setHeight}
                     isContentActive={this.isContentActive}
                     ScreenToLocalTransform={this.screenToLocal}
                     rootSelected={this.rootSelected}
                     onClick={this.onClickFunc}
-                    focus={this.props.focus}
                     setTitleFocus={this.setTitleFocus}
                     layout_fieldKey={this.finalLayoutKey}
                 />
@@ -1443,15 +1425,15 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         return this.docView?.LayoutFieldKey || 'layout';
     }
     @computed get layout_fitWidth() {
-        return this.docView?._componentView?.layout_fitWidth?.() ?? this.props.layout_fitWidth?.(this.layoutDoc) ?? this.layoutDoc?.layout_fitWidth;
+        return this.props.layout_fitWidth?.(this.layoutDoc) ?? this.layoutDoc?.layout_fitWidth;
     }
     @computed get anchorViewDoc() {
         return this.props.LayoutTemplateString?.includes('link_anchor_2') ? DocCast(this.Document['link_anchor_2']) : this.props.LayoutTemplateString?.includes('link_anchor_1') ? DocCast(this.Document['link_anchor_1']) : undefined;
     }
     @computed get hideLinkButton() {
-        return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HideLinkBtn + (this.isSelected() ? ':selected' : ''));
+        return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HideLinkBtn + (this.SELECTED ? ':selected' : ''));
     }
-    hideLinkCount = () => this.props.renderDepth === -1 || (this.isSelected() && this.props.renderDepth) || !this._isHovering || this.hideLinkButton;
+    hideLinkCount = () => this.props.renderDepth === -1 || (this.SELECTED && this.props.renderDepth) || !this._isHovering || this.hideLinkButton;
     @computed get linkCountView() {
         return <DocumentLinksButton hideCount={this.hideLinkCount} View={this} scaling={this.scaleToScreenSpace} OnHover={true} Bottom={this.topMost} ShowCount={true} />;
     }
@@ -1462,13 +1444,13 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         return Doc.Layout(this.Document, this.props.LayoutTemplate?.());
     }
     @computed get nativeWidth() {
-        return this.docView?._componentView?.ignoreNativeDimScaling?.() ? 0 : returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, this.props.TemplateDataDocument, !this.layout_fitWidth));
+        return this.props.LayoutTemplateString?.includes(KeyValueBox.name) ? 0 : returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, this.props.TemplateDataDocument, !this.layout_fitWidth));
     }
     @computed get nativeHeight() {
-        return this.docView?._componentView?.ignoreNativeDimScaling?.() ? 0 : returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, this.props.TemplateDataDocument, !this.layout_fitWidth));
+        return this.props.LayoutTemplateString?.includes(KeyValueBox.name) ? 0 : returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, this.props.TemplateDataDocument, !this.layout_fitWidth));
     }
     @computed get shouldNotScale() {
-        return this.props.shouldNotScale?.() || (this.layout_fitWidth && !this.nativeWidth) || [CollectionViewType.Docking].includes(this.Document._type_collection as any);
+        return (this.layout_fitWidth && !this.nativeWidth) || this.props.LayoutTemplateString?.includes(KeyValueBox.name) || [CollectionViewType.Docking].includes(this.Document._type_collection as any);
     }
     @computed get effectiveNativeWidth() {
         return this.shouldNotScale ? 0 : this.nativeWidth || NumCast(this.layoutDoc.width);
@@ -1589,7 +1571,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
     docViewPathFunc = () => this.docViewPath;
     isSelected = () => this.SELECTED;
     select = (extendSelection: boolean, focusSelection?: boolean) => {
-        if (this.isSelected() && SelectionManager.Views().length > 1) SelectionManager.DeselectView(this);
+        if (this.SELECTED && SelectionManager.Views().length > 1) SelectionManager.DeselectView(this);
         else {
             SelectionManager.SelectView(this, extendSelection);
             if (focusSelection) {
@@ -1684,7 +1666,6 @@ export class DocumentView extends React.Component<DocumentViewProps> {
                             {...this.props}
                             DocumentView={this.selfView}
                             viewPath={this.docViewPathFunc}
-                            shouldNotScale={this.ShouldNotScale}
                             PanelWidth={this.PanelWidth}
                             PanelHeight={this.PanelHeight}
                             NativeWidth={this.NativeWidth}
diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx
index 95d2a2667..0c6377c3a 100644
--- a/src/client/views/nodes/KeyValueBox.tsx
+++ b/src/client/views/nodes/KeyValueBox.tsx
@@ -41,10 +41,9 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
     componentDidMount() {
         this.props.setContentView?.(this);
     }
-    ignoreNativeDimScaling = returnTrue;
+    isKeyValueBox = returnTrue;
     able = returnAlways;
     layout_fitWidth = returnTrue;
-    overridePointerEvents = returnAll;
     onClickScriptDisable = returnAlways;
 
     @observable private rows: KeyValuePair[] = [];
diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx
index 0d7b2b0a4..e1421878b 100644
--- a/src/client/views/nodes/LabelBox.tsx
+++ b/src/client/views/nodes/LabelBox.tsx
@@ -36,7 +36,7 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps & LabelBoxProp
         this._timeout && clearTimeout(this._timeout);
     }
 
-    getTitle() {
+    @computed get Title() {
         return this.dataDoc.title_custom ? StrCast(this.Document.title) : this.props.label ? this.props.label : typeof this.dataDoc[this.fieldKey] === 'string' ? StrCast(this.dataDoc[this.fieldKey]) : StrCast(this.Document.title);
     }
 
@@ -119,7 +119,7 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps & LabelBoxProp
         const params = Cast(this.paramsDoc['onClick-paramFieldKeys'], listSpec('string'), []);
         const missingParams = params?.filter(p => !this.paramsDoc[p]);
         params?.map(p => DocListCast(this.paramsDoc[p])); // bcz: really hacky form of prefetching ...
-        const label = this.getTitle();
+        const label = this.Title;
         return (
             <div
                 className="labelBox-outerDiv"
diff --git a/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx b/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
index 3713e93ce..415a9d776 100644
--- a/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
+++ b/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
@@ -68,8 +68,8 @@ export class MapBoxInfoWindow extends React.Component<MapBoxInfoWindowProps & Vi
                             NativeDimScaling={returnOne}
                             isContentActive={returnTrue}
                             chromeHidden={true}
-                            childHideResizeHandles={returnTrue}
-                            childHideDecorationTitle={returnTrue}
+                            childHideResizeHandles={true}
+                            childHideDecorationTitle={true}
                             childLayoutFitWidth={this.childLayoutFitWidth}
                             // childDocumentsActive={returnFalse}
                             removeDocument={this.removeDoc}
-- 
cgit v1.2.3-70-g09d2

