From 3573a81d334cf8cc13d19b04c6f2094c24c43932 Mon Sep 17 00:00:00 2001
From: Aubrey Li <Aubrey-Li>
Date: Thu, 3 Mar 2022 18:12:13 -0500
Subject: edit: lightbox opens tab in the same stack

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

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

diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 9fc4b7890..d78f55213 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -475,7 +475,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
                     UndoManager.RunInBatch(() => func().result?.select === true ? this.props.select(false) : "", "on double click");
                 } else if (!Doc.IsSystem(this.rootDoc)) {
                     UndoManager.RunInBatch(() =>
-                        LightboxView.AddDocTab(this.rootDoc, "lightbox", this.props.LayoutTemplate?.())
+                        LightboxView.AddDocTab(this.rootDoc, "lightbox", this.props.LayoutTemplate?.(), this.props.addDocTab)
                         , "double tap");
                     SelectionManager.DeselectAll();
                     Doc.UnBrushDoc(this.props.Document);
-- 
cgit v1.2.3-70-g09d2


From a801dd089a1d2420bca4e8aa9b6eb893d314ad24 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 2 Jun 2022 12:03:51 -0400
Subject: fixed highlighting of ink to not show bounding box.  stopped shift
 Tab from blocking bulleting.  moved presEffects to slide.

---
 src/client/views/InkingStroke.tsx                  |  4 +-
 .../collections/CollectionStackedTimeline.tsx      |  3 ++
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  2 +-
 src/client/views/nodes/DocumentView.tsx            | 12 ++++--
 .../views/nodes/formattedText/RichTextMenu.tsx     |  6 +--
 src/client/views/nodes/trails/PresBox.tsx          | 50 +++++++++++-----------
 6 files changed, 42 insertions(+), 35 deletions(-)

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

diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index f97b713dd..aa5a815ac 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -323,13 +323,13 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
             StrCast(this.layoutDoc.strokeLineJoin), StrCast(this.layoutDoc.strokeLineCap),
             StrCast(this.layoutDoc.strokeBezier), !closed ? "none" : fillColor === "transparent" ? "none" : fillColor, startMarker, endMarker,
             markerScale, StrCast(this.layoutDoc.strokeDash), inkScaleX, inkScaleY, "", "none", 1.0, false);
-        const highlightIndex = BoolCast(this.props.Document.isLinkButton) && Doc.isBrushedHighlightedDegree(this.props.Document); // bcz: Argh!! need to identify a tree view doc better than a LayoutTemlatString
+        const highlightIndex = /*BoolCast(this.props.Document.isLinkButton) && */ Doc.isBrushedHighlightedDegree(this.props.Document); // bcz: Argh!! need to identify a tree view doc better than a LayoutTemlatString
         const highlightColor = !highlightIndex ?
             StrCast(this.layoutDoc.strokeOutlineColor, !closed && fillColor && fillColor !== "transparent" ? StrCast(this.layoutDoc.color, "transparent") : "transparent") :
             ["transparent", "rgb(68, 118, 247)", "rgb(68, 118, 247)", "yellow", "magenta", "cyan", "orange"][highlightIndex];
         // Invisible polygonal line that enables the ink to be selected by the user.
         const clickableLine = (downHdlr?: (e: React.PointerEvent) => void, suppressFill: boolean = false) => InteractionUtils.CreatePolyline(inkData, inkLeft, inkTop, highlightColor,
-            inkStrokeWidth, inkStrokeWidth + (highlightIndex && closed && fillColor && (new Color(fillColor)).alpha() < 1 ? 6 : 15),
+            inkStrokeWidth, fillColor && closed && highlightIndex ? highlightIndex / 2 : inkStrokeWidth + (fillColor ? closed ? 0 : (highlightIndex + 2) : 0),
             StrCast(this.layoutDoc.strokeLineJoin), StrCast(this.layoutDoc.strokeLineCap),
             StrCast(this.layoutDoc.strokeBezier), !closed ? "none" : fillColor === "transparent" || suppressFill ? "none" : fillColor, startMarker, endMarker,
             markerScale, undefined, inkScaleX, inkScaleY, "", this.props.pointerEvents?.() ?? (this.rootDoc._lockedPosition ? "none" : "visiblepainted"), 0.0,
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index 683b6d51d..02b2248fb 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -434,6 +434,9 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
             title: ComputedField.MakeFunction(
                 `"#" + formatToTime(self["${startTag}"]) + "-" + formatToTime(self["${endTag}"])`
             ) as any,
+            _minFontSize: 12,
+            _maxFontSize: 24,
+            _singleLine: false,
             _stayInCollection: true,
             useLinkSmallAnchor: true,
             hideLinkButton: true,
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 259cc1ee5..0ba2ae1a2 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1166,7 +1166,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     @action
     onKeyDown = (e: React.KeyboardEvent, fieldProps: FieldViewProps) => {
         const docView = fieldProps.DocumentView?.();
-        if (docView && (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || docView.rootDoc._singleLine) && ["Tab", "Enter"].includes(e.key)) {
+        if (docView && (e.metaKey || e.ctrlKey || e.altKey || docView.rootDoc._singleLine) && ["Tab", "Enter"].includes(e.key)) {
             e.stopPropagation?.();
             const below = !e.altKey && e.key !== "Tab";
             const layoutKey = StrCast(docView.LayoutFieldKey);
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 6b0b92889..040ac7ae5 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -14,7 +14,7 @@ import { BoolCast, Cast, ImageCast, NumCast, ScriptCast, StrCast } from "../../.
 import { AudioField } from "../../../fields/URLField";
 import { GetEffectiveAcl, SharingPermissions, TraceMobx } from '../../../fields/util';
 import { MobileInterface } from '../../../mobile/MobileInterface';
-import { emptyFunction, hasDescendantTarget, lightOrDark, OmitKeys, returnEmptyString, returnTrue, returnVal, simulateMouseClick, Utils } from "../../../Utils";
+import { emptyFunction, hasDescendantTarget, lightOrDark, OmitKeys, returnEmptyString, returnTrue, returnFalse, returnVal, simulateMouseClick, Utils } from "../../../Utils";
 import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils';
 import { Docs, DocUtils } from "../../documents/Documents";
 import { DocumentType } from '../../documents/DocumentTypes';
@@ -961,6 +961,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
         return filtered.map((link, i) =>
             <div className="documentView-anchorCont" key={link[Id]}>
                 <DocumentView {...this.props}
+                    isContentActive={returnFalse}
                     Document={link}
                     PanelWidth={this.anchorPanelWidth}
                     PanelHeight={this.anchorPanelHeight}
@@ -1123,10 +1124,13 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
     }
     render() {
         TraceMobx();
-        const highlightIndex = this.props.LayoutTemplateString ? (Doc.IsHighlighted(this.props.Document) ? 6 : 0) : Doc.isBrushedHighlightedDegree(this.props.Document); // bcz: Argh!! need to identify a tree view doc better than a LayoutTemlatString
+        const highlightIndex = this.props.LayoutTemplateString ? (Doc.IsHighlighted(this.props.Document) ? 6 : Doc.DocBrushStatus.unbrushed) : Doc.isBrushedHighlightedDegree(this.props.Document); // bcz: Argh!! need to identify a tree view doc better than a LayoutTemlatString
+        if (highlightIndex === 6) {
+            console.log("")
+        }
         const highlightColor = ["transparent", "rgb(68, 118, 247)", "rgb(68, 118, 247)", "orange", "lightBlue"][highlightIndex];
         const highlightStyle = ["solid", "dashed", "solid", "solid", "solid"][highlightIndex];
-        const excludeTypes = !this.props.treeViewDoc && highlightIndex < 3 ? [DocumentType.FONTICON, DocumentType.INK] : [DocumentType.FONTICON];
+        const excludeTypes = !this.props.treeViewDoc ? [DocumentType.FONTICON, DocumentType.INK] : [DocumentType.FONTICON];
         let highlighting = !this.props.disableDocBrushing && highlightIndex && !excludeTypes.includes(this.layoutDoc.type as any) && this.layoutDoc._viewType !== CollectionViewType.Linear;
         highlighting = highlighting && this.props.focus !== emptyFunction && this.layoutDoc.title !== "[pres element template]";  // bcz: hack to turn off highlighting onsidebar panel documents.  need to flag a document as not highlightable in a more direct way
 
@@ -1251,7 +1255,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
     toggleNativeDimensions = () => this.docView && Doc.toggleNativeDimensions(this.layoutDoc, this.docView.ContentScale, this.props.PanelWidth(), this.props.PanelHeight());
     focus = (doc: Doc, options?: DocFocusOptions) => this.docView?.focus(doc, options);
     getBounds = () => {
-        if (!this.docView || !this.docView.ContentDiv || this.docView.props.treeViewDoc || Doc.AreProtosEqual(this.props.Document, Doc.UserDoc())) {
+        if (!this.docView || !this.docView.ContentDiv || this.props.Document.presBox || this.docView.props.treeViewDoc || Doc.AreProtosEqual(this.props.Document, Doc.UserDoc())) {
             return undefined;
         }
         const xf = (this.docView?.props.ScreenToLocalTransform().scale(this.nativeScaling)).inverse();
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index 3df1e45a5..9bc2e5628 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -1,15 +1,15 @@
 import React = require("react");
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { Tooltip } from "@material-ui/core";
-import { action, IReactionDisposer, observable, reaction, runInAction, computed } from "mobx";
+import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import { lift, wrapIn } from "prosemirror-commands";
-import { Mark, MarkType, Node as ProsNode, NodeType, ResolvedPos } from "prosemirror-model";
+import { Mark, MarkType, Node as ProsNode, ResolvedPos } from "prosemirror-model";
 import { wrapInList } from "prosemirror-schema-list";
 import { EditorState, NodeSelection, TextSelection } from "prosemirror-state";
 import { EditorView } from "prosemirror-view";
 import { Doc } from "../../../../fields/Doc";
-import { Cast, NumCast, StrCast } from "../../../../fields/Types";
+import { Cast, StrCast } from "../../../../fields/Types";
 import { DocServer } from "../../../DocServer";
 import { LinkManager } from "../../../util/LinkManager";
 import { SelectionManager } from "../../../util/SelectionManager";
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 64f5a296f..9641b403f 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -47,17 +47,17 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
      * @param renderDoc
      * @param layoutDoc
      */
-    static renderEffectsDoc(renderDoc: any, layoutDoc: Doc) {
+    static renderEffectsDoc(renderDoc: any, layoutDoc: Doc, presDoc: Doc) {
         const effectProps = {
-            left: layoutDoc.presEffectDirection === PresEffect.Left,
-            right: layoutDoc.presEffectDirection === PresEffect.Right,
-            top: layoutDoc.presEffectDirection === PresEffect.Top,
-            bottom: layoutDoc.presEffectDirection === PresEffect.Bottom,
+            left: presDoc.presEffectDirection === PresEffect.Left,
+            right: presDoc.presEffectDirection === PresEffect.Right,
+            top: presDoc.presEffectDirection === PresEffect.Top,
+            bottom: presDoc.presEffectDirection === PresEffect.Bottom,
             opposite: true,
-            delay: layoutDoc.presTransition,
+            delay: presDoc.presTransition,
             // when: this.layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc,
         };
-        switch (layoutDoc.presEffect) {
+        switch (presDoc.presEffect) {
             case PresEffect.Zoom: return (<Zoom {...effectProps}>{renderDoc}</Zoom>);
             case PresEffect.Fade: return (<Fade {...effectProps}>{renderDoc}</Fade>);
             case PresEffect.Flip: return (<Flip {...effectProps}>{renderDoc}</Flip>);
@@ -71,7 +71,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     }
     public static EffectsProvider(layoutDoc: Doc, renderDoc: any) {
         return PresBox.Instance && layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc ?
-            PresBox.renderEffectsDoc(renderDoc, layoutDoc)
+            PresBox.renderEffectsDoc(renderDoc, layoutDoc, PresBox.Instance.childDocs[PresBox.Instance.itemIndex])
             :
             renderDoc;
     }
@@ -1089,7 +1089,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     updateEffectDirection = (effect: any, all?: boolean) => {
         const array: any[] = all ? this.childDocs : Array.from(this._selectedArray.keys());
         array.forEach((doc) => {
-            const tagDoc = Cast(doc.presentationTargetDoc, Doc, null);
+            const tagDoc = doc;// Cast(doc.presentationTargetDoc, Doc, null);
             switch (effect) {
                 case PresEffect.Left:
                     tagDoc.presEffectDirection = PresEffect.Left;
@@ -1115,7 +1115,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     updateEffect = (effect: any, all?: boolean) => {
         const array: any[] = all ? this.childDocs : Array.from(this._selectedArray.keys());
         array.forEach((doc) => {
-            const tagDoc = Cast(doc.presentationTargetDoc, Doc, null);
+            const tagDoc = doc;//Cast(doc.presentationTargetDoc, Doc, null);
             switch (effect) {
                 case PresEffect.Bounce:
                     tagDoc.presEffect = PresEffect.Bounce;
@@ -1152,7 +1152,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
             const zoom = activeItem.presZoom ? NumCast(activeItem.presZoom) * 100 : 75;
             let duration = activeItem.presDuration ? NumCast(activeItem.presDuration) / 1000 : 2;
             if (activeItem.type === DocumentType.AUDIO) duration = NumCast(activeItem.duration);
-            const effect = targetDoc.presEffect ? targetDoc.presEffect : 'None';
+            const effect = this.activeItem.presEffect ? this.activeItem.presEffect : 'None';
             activeItem.presMovement = activeItem.presMovement ? activeItem.presMovement : 'Zoom';
             return (
                 <div className={`presBox-ribbon ${this.transitionTools && this.layoutDoc.presStatus === PresStatus.Edit ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onClick={action(e => { e.stopPropagation(); this.openMovementDropdown = false; this.openEffectDropdown = false; })}>
@@ -1274,12 +1274,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                             {effect}
                             <FontAwesomeIcon className='presBox-dropdownIcon' style={{ gridColumn: 2, color: this.openEffectDropdown ? Colors.MEDIUM_BLUE : 'black' }} icon={"angle-down"} />
                             <div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} style={{ display: this.openEffectDropdown ? "grid" : "none" }} onPointerDown={e => e.stopPropagation()}>
-                                <div className={`presBox-dropdownOption ${targetDoc.presEffect === PresEffect.None || !targetDoc.presEffect ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.None)}>None</div>
-                                <div className={`presBox-dropdownOption ${targetDoc.presEffect === PresEffect.Fade ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Fade)}>Fade In</div>
-                                <div className={`presBox-dropdownOption ${targetDoc.presEffect === PresEffect.Flip ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Flip)}>Flip</div>
-                                <div className={`presBox-dropdownOption ${targetDoc.presEffect === PresEffect.Rotate ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Rotate)}>Rotate</div>
-                                <div className={`presBox-dropdownOption ${targetDoc.presEffect === PresEffect.Bounce ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Bounce)}>Bounce</div>
-                                <div className={`presBox-dropdownOption ${targetDoc.presEffect === PresEffect.Roll ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Roll)}>Roll</div>
+                                <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.None || !this.activeItem.presEffect ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.None)}>None</div>
+                                <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.Fade ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Fade)}>Fade In</div>
+                                <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.Flip ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Flip)}>Flip</div>
+                                <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.Rotate ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Rotate)}>Rotate</div>
+                                <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.Bounce ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Bounce)}>Bounce</div>
+                                <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.Roll ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Roll)}>Roll</div>
                             </div>
                         </div>
                         <div className="ribbon-doubleButton" style={{ display: effect === 'None' ? "none" : "inline-flex" }}>
@@ -1289,11 +1289,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                             </div>
                         </div>
                         <div className="effectDirection" style={{ display: effect === 'None' ? "none" : "grid", width: 40 }}>
-                            <Tooltip title={<><div className="dash-tooltip">{"Enter from left"}</div></>}><div style={{ gridColumn: 1, gridRow: 2, justifySelf: 'center', color: targetDoc.presEffectDirection === PresEffect.Left ? Colors.LIGHT_BLUE : "black", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Left)}><FontAwesomeIcon icon={"angle-right"} /></div></Tooltip>
-                            <Tooltip title={<><div className="dash-tooltip">{"Enter from right"}</div></>}><div style={{ gridColumn: 3, gridRow: 2, justifySelf: 'center', color: targetDoc.presEffectDirection === PresEffect.Right ? Colors.LIGHT_BLUE : "black", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Right)}><FontAwesomeIcon icon={"angle-left"} /></div></Tooltip>
-                            <Tooltip title={<><div className="dash-tooltip">{"Enter from top"}</div></>}><div style={{ gridColumn: 2, gridRow: 1, justifySelf: 'center', color: targetDoc.presEffectDirection === PresEffect.Top ? Colors.LIGHT_BLUE : "black", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Top)}><FontAwesomeIcon icon={"angle-down"} /></div></Tooltip>
-                            <Tooltip title={<><div className="dash-tooltip">{"Enter from bottom"}</div></>}><div style={{ gridColumn: 2, gridRow: 3, justifySelf: 'center', color: targetDoc.presEffectDirection === PresEffect.Bottom ? Colors.LIGHT_BLUE : "black", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Bottom)}><FontAwesomeIcon icon={"angle-up"} /></div></Tooltip>
-                            <Tooltip title={<><div className="dash-tooltip">{"Enter from center"}</div></>}><div style={{ gridColumn: 2, gridRow: 2, width: 10, height: 10, alignSelf: 'center', justifySelf: 'center', border: targetDoc.presEffectDirection === PresEffect.Center || !targetDoc.presEffectDirection ? `solid 2px ${Colors.LIGHT_BLUE}` : "solid 2px black", borderRadius: "100%", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Center)}></div></Tooltip>
+                            <Tooltip title={<><div className="dash-tooltip">{"Enter from left"}</div></>}><div style={{ gridColumn: 1, gridRow: 2, justifySelf: 'center', color: this.activeItem.presEffectDirection === PresEffect.Left ? Colors.LIGHT_BLUE : "black", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Left)}><FontAwesomeIcon icon={"angle-right"} /></div></Tooltip>
+                            <Tooltip title={<><div className="dash-tooltip">{"Enter from right"}</div></>}><div style={{ gridColumn: 3, gridRow: 2, justifySelf: 'center', color: this.activeItem.presEffectDirection === PresEffect.Right ? Colors.LIGHT_BLUE : "black", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Right)}><FontAwesomeIcon icon={"angle-left"} /></div></Tooltip>
+                            <Tooltip title={<><div className="dash-tooltip">{"Enter from top"}</div></>}><div style={{ gridColumn: 2, gridRow: 1, justifySelf: 'center', color: this.activeItem.presEffectDirection === PresEffect.Top ? Colors.LIGHT_BLUE : "black", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Top)}><FontAwesomeIcon icon={"angle-down"} /></div></Tooltip>
+                            <Tooltip title={<><div className="dash-tooltip">{"Enter from bottom"}</div></>}><div style={{ gridColumn: 2, gridRow: 3, justifySelf: 'center', color: this.activeItem.presEffectDirection === PresEffect.Bottom ? Colors.LIGHT_BLUE : "black", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Bottom)}><FontAwesomeIcon icon={"angle-up"} /></div></Tooltip>
+                            <Tooltip title={<><div className="dash-tooltip">{"Enter from center"}</div></>}><div style={{ gridColumn: 2, gridRow: 2, width: 10, height: 10, alignSelf: 'center', justifySelf: 'center', border: this.activeItem.presEffectDirection === PresEffect.Center || !this.activeItem.presEffectDirection ? `solid 2px ${Colors.LIGHT_BLUE}` : "solid 2px black", borderRadius: "100%", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Center)}></div></Tooltip>
                         </div>
                     </div>}
                     <div className="ribbon-final-box">
@@ -1308,7 +1308,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
 
     @computed get effectDirection(): string {
         let effect = '';
-        switch (this.targetDoc.presEffectDirection) {
+        switch (this.activeItem.presEffectDirection) {
             case 'left': effect = "Enter from left"; break;
             case 'right': effect = "Enter from right"; break;
             case 'top': effect = "Enter from top"; break;
@@ -1324,8 +1324,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         const activeItem: Doc = this.activeItem;
         const targetDoc: Doc = this.targetDoc;
         this.updateMovement(activeItem.presMovement, true);
-        this.updateEffect(targetDoc.presEffect, true);
-        this.updateEffectDirection(targetDoc.presEffectDirection, true);
+        this.updateEffect(activeItem.presEffect, true);
+        this.updateEffectDirection(activeItem.presEffectDirection, true);
         array.forEach((doc) => {
             const curDoc = Cast(doc, Doc, null);
             const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null);
-- 
cgit v1.2.3-70-g09d2


From 8799738abd11a878579814e64163e0f8a95b5116 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Fri, 3 Jun 2022 08:10:42 -0400
Subject: fixed pushpin link toggling when zoom is not set.  fixed adding
 annotations to webBox's  without opening sidebar.  Made linkDoc preview
 always open

---
 .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx  | 2 +-
 src/client/views/nodes/DocumentView.tsx                              | 5 +++--
 src/client/views/nodes/LinkDocPreview.tsx                            | 2 +-
 src/client/views/nodes/WebBox.tsx                                    | 2 +-
 src/client/views/pdf/PDFViewer.tsx                                   | 2 +-
 5 files changed, 7 insertions(+), 6 deletions(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 0ba2ae1a2..09bb1526e 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1077,7 +1077,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             this.props.focus(doc, options);
         } else {
             const xfToCollection = options?.docTransform ?? Transform.Identity();
-            const savedState = { panX: NumCast(this.Document._panX), panY: NumCast(this.Document._panY), scale: this.Document[this.scaleFieldKey] };
+            const savedState = { panX: NumCast(this.Document._panX), panY: NumCast(this.Document._panY), scale: options?.willZoom ? this.Document[this.scaleFieldKey] : undefined };
             const newState = HistoryUtil.getState();
             const cantTransform = /*this.props.isAnnotationOverlay ||*/ ((this.rootDoc._isGroup || this.layoutDoc._lockedTransform) && !LightboxView.LightboxDoc);
             const { panX, panY, scale } = cantTransform ? savedState : this.calculatePanIntoView(doc, xfToCollection, options?.willZoom ? options?.scale || .75 : undefined);
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 040ac7ae5..9db4cbde3 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -480,6 +480,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
             (Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD && Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD)) {
             let stopPropagate = true;
             let preventDefault = true;
+            const isScriptBox = () => StrCast(Doc.LayoutField(this.layoutDoc))?.includes(ScriptingBox.name);
             (this.rootDoc._raiseWhenDragged === undefined ? Doc.UserDoc()._raiseWhenDragged : this.rootDoc._raiseWhenDragged) && this.props.bringToFront(this.rootDoc);
             if (this._doubleTap && (this.props.Document.type !== DocumentType.FONTICON || this.onDoubleClickHandler)) {// && !this.onClickHandler?.script) { // disable double-click to show full screen for things that have an on click behavior since clicking them twice can be misinterpreted as a double click
                 if (this._timeout) {
@@ -505,7 +506,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
                     SelectionManager.DeselectAll();
                     Doc.UnBrushDoc(this.props.Document);
                 }
-            } else if (this.onClickHandler?.script && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes(ScriptingBox.name)) { // bcz: hack? don't execute script if you're clicking on a scripting box itself
+            } else if (this.onClickHandler?.script && !isScriptBox()) { // bcz: hack? don't execute script if you're clicking on a scripting box itself
                 const { clientX, clientY, shiftKey } = e;
                 const func = () => this.onClickHandler.script.run({
                     this: this.layoutDoc,
@@ -521,7 +522,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
                     runInAction(() => this._pendingDoubleClick = true);
                     this._timeout = setTimeout(() => { this._timeout = undefined; clickFunc(); }, 350);
                 } else clickFunc();
-            } else if (this.allLinks && this.Document.type !== DocumentType.LINK && this.Document.isLinkButton && !e.shiftKey && !e.ctrlKey) {
+            } else if (this.allLinks && this.Document.type !== DocumentType.LINK && !isScriptBox() && this.Document.isLinkButton && !e.shiftKey && !e.ctrlKey) {
                 this.allLinks.length && LinkManager.FollowLink(undefined, this.props.Document, this.props, e.altKey);
             } else {
                 if ((this.layoutDoc.onDragStart || this.props.Document.rootDocument) && !(e.ctrlKey || e.button > 0)) {  // onDragStart implies a button doc that we don't want to select when clicking.   RootDocument & isTemplaetForField implies we're clicking on part of a template instance and we want to select the whole template, not the part
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index ba515fb89..b6a9cd49b 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -93,7 +93,7 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
                         } else {
                             this._linkSrc = anchor;
                             const linkTarget = LinkManager.getOppositeAnchor(this._linkDoc, this._linkSrc);
-                            this._targetDoc = linkTarget?.type === DocumentType.MARKER && linkTarget?.annotationOn ? Cast(linkTarget.annotationOn, Doc, null) ?? linkTarget : linkTarget;
+                            this._targetDoc = /*linkTarget?.type === DocumentType.MARKER &&*/ linkTarget?.annotationOn ? Cast(linkTarget.annotationOn, Doc, null) ?? linkTarget : linkTarget;
                         }
                         this._toolTipText = "";
                     }
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index dbbcdc9de..fea8ed0a4 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -756,7 +756,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
                 whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
                 removeDocument={this.removeDocument}
                 moveDocument={this.moveDocument}
-                addDocument={this.sidebarAddDocument}
+                addDocument={this.addDocument}
                 styleProvider={this.childStyleProvider}
                 childPointerEvents={this.props.isContentActive() ? "all" : undefined}
                 pointerEvents={this.annotationPointerEvents} />;
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 305b1fe68..6db36f36a 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -154,7 +154,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
         if (doc !== this.props.rootDoc && mainCont) {
             const windowHeight = this.props.PanelHeight() / (this.props.scaling?.() || 1);
             const scrollTo = doc.unrendered ? NumCast(doc.y) : Utils.scrollIntoView(NumCast(doc.y), doc[HeightSym](), NumCast(this.props.layoutDoc._scrollTop), windowHeight, .1 * windowHeight, NumCast(this.props.Document.scrollHeight));
-            if (scrollTo !== undefined) {
+            if (scrollTo !== undefined && scrollTo != this.props.layoutDoc._scrollTop) {
                 focusSpeed = 500;
 
                 if (!this._pdfViewer) this._initialScroll = scrollTo;
-- 
cgit v1.2.3-70-g09d2


From ba7824a91da113cc813c58b678719092c96d79a2 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Fri, 3 Jun 2022 16:02:24 -0400
Subject: fixed opening closed tabs from Files sidebar to re-use best Alias
 before making a new alias.

---
 src/.DS_Store                                      | Bin 8196 -> 8196 bytes
 src/client/util/CurrentUserUtils.ts                |   2 +-
 src/client/util/DocumentManager.ts                 |  28 ++++++++++-----------
 src/client/views/LightboxView.tsx                  |   5 ++--
 src/client/views/collections/TabDocView.tsx        |  15 ++++++++++-
 src/client/views/collections/TreeView.tsx          |   4 +--
 src/client/views/nodes/DocumentIcon.tsx            |   4 +--
 src/client/views/nodes/DocumentView.tsx            |   4 ---
 src/client/views/nodes/button/FontIconBox.tsx      |  11 ++++----
 .../views/nodes/formattedText/DashFieldView.tsx    |   6 ++---
 .../views/nodes/formattedText/FormattedTextBox.tsx |   2 +-
 src/client/views/nodes/trails/PresBox.tsx          |  14 ++---------
 src/client/views/pdf/PDFViewer.tsx                 |   2 +-
 13 files changed, 48 insertions(+), 49 deletions(-)

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

diff --git a/src/.DS_Store b/src/.DS_Store
index b0987293b..4bf9cdac7 100644
Binary files a/src/.DS_Store and b/src/.DS_Store differ
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 2ed6c3cbe..85ad58726 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -869,7 +869,7 @@ export class CurrentUserUtils {
                             Doc.AddDocToList(menuBtnDoc, "data", newSubMenuBtnDoc, after, false, !prevSub);
                         }
                         prevSub = params.title;
-                    })
+                    });
                 }
                 prev = params.title;
             });
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index aeddc3249..a82f99d5a 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -16,7 +16,7 @@ import { SelectionManager } from './SelectionManager';
 export class DocumentManager {
 
     //global holds all of the nodes (regardless of which collection they're in)
-    @observable public DocumentViews: DocumentView[] = [];
+    @observable public DocumentViews = new Set<DocumentView>();
     @observable public LinkAnchorBoxViews: DocumentView[] = [];
     @observable public RecordingEvent = 0;
     @observable public LinkedDocumentViews: { a: DocumentView, b: DocumentView, l: Doc }[] = [];
@@ -46,7 +46,7 @@ export class DocumentManager {
             // this.LinkedDocumentViews.forEach(view => console.log("  LV = " + view.a.props.Document.title + "/" + view.a.props.LayoutTemplateString + " --> " +
             //     view.b.props.Document.title + "/" + view.b.props.LayoutTemplateString));
         } else {
-            this.DocumentViews.push(view);
+            this.DocumentViews.add(view);
         }
     }
     public RemoveView = action((view: DocumentView) => {
@@ -61,8 +61,7 @@ export class DocumentManager {
             const index = this.LinkAnchorBoxViews.indexOf(view);
             this.LinkAnchorBoxViews.splice(index, 1);
         } else {
-            const index = this.DocumentViews.indexOf(view);
-            index !== -1 && this.DocumentViews.splice(index, 1);
+            this.DocumentViews.delete(view);
         }
         SelectionManager.DeselectView(view);
     });
@@ -70,13 +69,13 @@ export class DocumentManager {
     //gets all views
     public getDocumentViewsById(id: string) {
         const toReturn: DocumentView[] = [];
-        DocumentManager.Instance.DocumentViews.map(view => {
+        Array.from(DocumentManager.Instance.DocumentViews).map(view => {
             if (view.rootDoc[Id] === id) {
                 toReturn.push(view);
             }
         });
         if (toReturn.length === 0) {
-            DocumentManager.Instance.DocumentViews.map(view => {
+            Array.from(DocumentManager.Instance.DocumentViews).map(view => {
                 const doc = view.rootDoc.proto;
                 if (doc && doc[Id] && doc[Id] === id) {
                     toReturn.push(view);
@@ -96,14 +95,14 @@ export class DocumentManager {
         const passes = preferredCollection ? [preferredCollection, undefined] : [undefined];
 
         for (const pass of passes) {
-            DocumentManager.Instance.DocumentViews.map(view => {
+            Array.from(DocumentManager.Instance.DocumentViews).map(view => {
                 if (view.rootDoc[Id] === id && (!pass || view.props.ContainingCollectionView === preferredCollection)) {
                     toReturn = view;
                     return;
                 }
             });
             if (!toReturn) {
-                DocumentManager.Instance.DocumentViews.map(view => {
+                Array.from(DocumentManager.Instance.DocumentViews).map(view => {
                     const doc = view.rootDoc.proto;
                     if (doc && doc[Id] === id && (!pass || view.props.ContainingCollectionView === preferredCollection)) {
                         toReturn = view;
@@ -122,9 +121,8 @@ export class DocumentManager {
     }
 
     public getLightboxDocumentView = (toFind: Doc, originatingDoc: Opt<Doc> = undefined): DocumentView | undefined => {
-        const docViews = DocumentManager.Instance.DocumentViews;
         const views: DocumentView[] = [];
-        docViews.map(view => LightboxView.IsLightboxDocView(view.docViewPath) && Doc.AreProtosEqual(view.rootDoc, toFind) && views.push(view));
+        Array.from(DocumentManager.Instance.DocumentViews).map(view => LightboxView.IsLightboxDocView(view.docViewPath) && Doc.AreProtosEqual(view.rootDoc, toFind) && views.push(view));
         return views?.find(view => view.ContentDiv?.getBoundingClientRect().width && view.props.focus !== returnFalse) || views?.find(view => view.props.focus !== returnFalse) || (views.length ? views[0] : undefined);
     }
     public getFirstDocumentView = (toFind: Doc, originatingDoc: Opt<Doc> = undefined): DocumentView | undefined => {
@@ -133,8 +131,8 @@ export class DocumentManager {
     }
     public getDocumentViews(toFind: Doc): DocumentView[] {
         const toReturn: DocumentView[] = [];
-        const docViews = DocumentManager.Instance.DocumentViews.filter(view => !LightboxView.IsLightboxDocView(view.docViewPath));
-        const lightViews = DocumentManager.Instance.DocumentViews.filter(view => LightboxView.IsLightboxDocView(view.docViewPath));
+        const docViews = Array.from(DocumentManager.Instance.DocumentViews).filter(view => !LightboxView.IsLightboxDocView(view.docViewPath));
+        const lightViews = Array.from(DocumentManager.Instance.DocumentViews).filter(view => LightboxView.IsLightboxDocView(view.docViewPath));
 
         // heuristic to return the "best" documents first:
         //   choose a document in the lightbox first
@@ -290,7 +288,7 @@ export class DocumentManager {
         }
     }
 }
-export function DocFocusOrOpen(doc: any, collectionDoc?: Doc) {
+export function DocFocusOrOpen(doc: Doc, collectionDoc?: Doc) {
     const cv = collectionDoc && DocumentManager.Instance.getDocumentView(collectionDoc);
     const dv = DocumentManager.Instance.getDocumentView(doc, (cv?.ComponentView as CollectionFreeFormView)?.props.CollectionView);
     if (dv && Doc.AreProtosEqual(dv.props.Document, doc)) {
@@ -300,7 +298,9 @@ export function DocFocusOrOpen(doc: any, collectionDoc?: Doc) {
     else {
         const context = doc.context !== Doc.UserDoc().myFilesystem && Cast(doc.context, Doc, null);
         const showDoc = context || doc;
-        CollectionDockingView.AddSplit(showDoc === Doc.GetProto(showDoc) ? Doc.MakeAlias(showDoc) : showDoc, "right") && context &&
+        const bestAlias = showDoc === Doc.GetProto(showDoc) ? DocListCast(showDoc.aliases).find(doc => !doc.context && doc.author === Doc.CurrentUserEmail) : showDoc;
+
+        CollectionDockingView.AddSplit(bestAlias ? bestAlias : Doc.MakeAlias(showDoc), "right") && context &&
             setTimeout(() => DocumentManager.Instance.getDocumentView(Doc.GetProto(doc))?.focus(doc));
     }
 }
diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx
index ddfc8b249..3d2769f66 100644
--- a/src/client/views/LightboxView.tsx
+++ b/src/client/views/LightboxView.tsx
@@ -275,9 +275,8 @@ export class LightboxView extends React.Component<LightboxViewProps> {
                 <div className="lightboxView-tabBtn" title={"open in tab"}
                     onClick={e => {
                         e.stopPropagation();
-                        // CollectionDockingView.AddSplit(LightboxView._docTarget || LightboxView._doc!, "");
-                        LightboxView.openInTabFunc(LightboxView._docTarget || LightboxView._doc!, "inPlace");
-                        console.log("lightbox to tab triggered")
+                        CollectionDockingView.AddSplit(LightboxView._docTarget || LightboxView._doc!, "");
+                        //LightboxView.openInTabFunc(LightboxView._docTarget || LightboxView._doc!, "inPlace");
                         SelectionManager.DeselectAll();
                         LightboxView.SetLightboxDoc(undefined);
                     }}>
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 8d84e9a56..d64cb2fd7 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -66,6 +66,8 @@ export class TabDocView extends React.Component<TabDocViewProps> {
     get stack() { return (this.props as any).glContainer.parent.parent; }
     get tab() { return (this.props as any).glContainer.tab; }
     get view() { return this._view; }
+    _lastTab: any;
+    _lastView: DocumentView | undefined;
 
     @action
     init = (tab: any, doc: Opt<Doc>) => {
@@ -266,6 +268,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
 
     componentWillUnmount() {
         this._tabReaction?.();
+        this._view && DocumentManager.Instance.RemoveView(this._view);
         this.tab && CollectionDockingView.Instance.tabMap.delete(this.tab);
 
         this.props.glContainer.layoutManager.off("activeContentItemChanged", this.onActiveContentItemChanged);
@@ -353,7 +356,11 @@ export class TabDocView extends React.Component<TabDocViewProps> {
 
     @computed get docView() {
         return !this._activated || !this._document || this._document._viewType === CollectionViewType.Docking ? (null) :
-            <><DocumentView key={this._document[Id]} ref={action((r: DocumentView) => this._view = r)}
+            <><DocumentView key={this._document[Id]} ref={action((r: DocumentView) => {
+                this._lastView && DocumentManager.Instance.RemoveView(this._lastView);
+                this._view = r;
+                this._lastView = this._view;
+            })}
                 renderDepth={0}
                 Document={this._document}
                 DataDoc={!Doc.AreProtosEqual(this._document[DataSym], this._document) ? this._document[DataSym] : undefined}
@@ -409,6 +416,12 @@ export class TabDocView extends React.Component<TabDocViewProps> {
                 height: "100%", width: "100%"
             }} ref={ref => {
                 if (this._mainCont = ref) {
+                    if (this._lastTab) {
+                        console.log("DUP tab")
+                        this._view && DocumentManager.Instance.RemoveView(this._view);
+                        CollectionDockingView.Instance.tabMap.delete(this._lastTab);
+                    }
+                    this._lastTab = this.tab;
                     (this._mainCont as any).InitTab = (tab: any) => this.init(tab, this._document);
                     DocServer.GetRefField(this.props.documentId).then(action(doc => doc instanceof Doc && (this._document = doc) && this.tab && this.init(this.tab, this._document)));
                     new _global.ResizeObserver(action((entries: any) => this._forceInvalidateScreenToLocal++)).observe(ref);
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 661db7997..9de44fb00 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -183,7 +183,7 @@ export class TreeView extends React.Component<TreeViewProps> {
             this.treeViewOpen = !this.treeViewOpen;
         } else {
             // choose an appropriate alias or make one. --- choose the first alias that (1) user owns,  (2) has no context field ... otherwise make a new alias
-            const bestAlias = docView.props.Document.author === Doc.CurrentUserEmail ? docView.props.Document : DocListCast(this.props.document.aliases).find(doc => !doc.context && doc.author === Doc.CurrentUserEmail);
+            const bestAlias = docView.props.Document.author === Doc.CurrentUserEmail && !Doc.IsPrototype(docView.props.Document) ? docView.props.Document : DocListCast(this.props.document.aliases).find(doc => !doc.context && doc.author === Doc.CurrentUserEmail);
             const nextBestAlias = DocListCast(this.props.document.aliases).find(doc => doc.author === Doc.CurrentUserEmail);
             this.props.addDocTab(bestAlias ?? nextBestAlias ?? Doc.MakeAlias(this.props.document), "lightbox");
         }
@@ -609,7 +609,7 @@ export class TreeView extends React.Component<TreeViewProps> {
     // TODO: currently doc focus works, but can't seem to edit title
     // onChildClick = () => this.props.onChildClick?.() ?? (this._editTitleScript?.() || ScriptCast(this.doc.treeChildClick));
     onChildClick = () => {
-        return this.props.onChildClick?.() ?? (ScriptField.MakeFunction(`DocFocusOrOpen(self)`)! || this._editTitleScript?.())
+        return this.props.onChildClick?.() ?? (ScriptField.MakeFunction(`DocFocusOrOpen(self)`)! || this._editTitleScript?.());
     }
 
     onChildDoubleClick = () => (!this.props.treeView.outlineMode && this._openScript?.()) || ScriptCast(this.doc.treeChildDoubleClick);
diff --git a/src/client/views/nodes/DocumentIcon.tsx b/src/client/views/nodes/DocumentIcon.tsx
index a9c998757..56de2d1fc 100644
--- a/src/client/views/nodes/DocumentIcon.tsx
+++ b/src/client/views/nodes/DocumentIcon.tsx
@@ -52,7 +52,7 @@ export class DocumentIconContainer extends React.Component {
                 };
             },
             getVars() {
-                const docs = DocumentManager.Instance.DocumentViews;
+                const docs = Array.from(DocumentManager.Instance.DocumentViews);
                 const capturedVariables: { [name: string]: Field } = {};
                 usedDocuments.forEach(index => capturedVariables[`d${index}`] = docs[index].props.Document);
                 return { capturedVariables };
@@ -60,6 +60,6 @@ export class DocumentIconContainer extends React.Component {
         };
     }
     render() {
-        return DocumentManager.Instance.DocumentViews.map((dv, i) => <DocumentIcon key={i} index={i} view={dv} />);
+        return Array.from(DocumentManager.Instance.DocumentViews).map((dv, i) => <DocumentIcon key={i} index={i} view={dv} />);
     }
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 14ededaf8..6e4d6a52e 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -242,7 +242,6 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
     @computed get onPointerDownHandler() { return this.props.onPointerDown?.() ?? ScriptCast(this.Document.onPointerDown); }
     @computed get onPointerUpHandler() { return this.props.onPointerUp?.() ?? ScriptCast(this.Document.onPointerUp); }
 
-
     componentWillUnmount() { this.cleanupHandlers(true); }
     componentDidMount() { this.setupHandlers(); }
     //componentDidUpdate() { this.setupHandlers(); }
@@ -1126,9 +1125,6 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
     render() {
         TraceMobx();
         const highlightIndex = this.props.LayoutTemplateString ? (Doc.IsHighlighted(this.props.Document) ? 6 : Doc.DocBrushStatus.unbrushed) : Doc.isBrushedHighlightedDegree(this.props.Document); // bcz: Argh!! need to identify a tree view doc better than a LayoutTemlatString
-        if (highlightIndex === 6) {
-            console.log("")
-        }
         const highlightColor = ["transparent", "rgb(68, 118, 247)", "rgb(68, 118, 247)", "orange", "lightBlue"][highlightIndex];
         const highlightStyle = ["solid", "dashed", "solid", "solid", "solid"][highlightIndex];
         const excludeTypes = !this.props.treeViewDoc ? [DocumentType.FONTICON, DocumentType.INK] : [DocumentType.FONTICON];
diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx
index d29160458..b21a28d8e 100644
--- a/src/client/views/nodes/button/FontIconBox.tsx
+++ b/src/client/views/nodes/button/FontIconBox.tsx
@@ -231,7 +231,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
         const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
 
         const script = ScriptCast(this.rootDoc.script);
-        if (!script) { return null };
+        if (!script) { return null; }
 
         let noviceList: string[] = [];
         let text: string | undefined;
@@ -459,7 +459,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
         const buttonText = StrCast(this.rootDoc.buttonText);
 
         // TODO:glr Add label of button type
-        let button = this.defaultButton;
+        let button: JSX.Element | null = this.defaultButton;
 
         switch (this.type) {
             case ButtonType.TextButton:
@@ -527,9 +527,10 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
         }
 
         return !this.layoutDoc.toolTip || this.type === ButtonType.DropdownList || this.type === ButtonType.ColorButton || this.type === ButtonType.NumberButton || this.type === ButtonType.EditableText ? button :
-            <Tooltip title={<div className="dash-tooltip">{StrCast(this.layoutDoc.toolTip)}</div>}>
-                {button}
-            </Tooltip>;
+            button !== null ?
+                <Tooltip title={<div className="dash-tooltip">{StrCast(this.layoutDoc.toolTip)}</div>}>
+                    {button}
+                </Tooltip > : null
     }
 }
 
diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx
index 6a3f9ed00..bb3791f1e 100644
--- a/src/client/views/nodes/formattedText/DashFieldView.tsx
+++ b/src/client/views/nodes/formattedText/DashFieldView.tsx
@@ -86,7 +86,7 @@ export class DashFieldViewInternal extends React.Component<IDashFieldViewInterna
     public static fieldContent(textBoxDoc: Doc, dashDoc: Doc, fieldKey: string) {
         const dashVal = dashDoc[fieldKey] ?? dashDoc[DataSym][fieldKey] ?? (fieldKey === "PARAMS" ? textBoxDoc[fieldKey] : "");
         const fval = dashVal instanceof List ? dashVal.join(DashFieldViewInternal.multiValueDelimeter) : StrCast(dashVal).startsWith(":=") || dashVal === "" ? Doc.Layout(textBoxDoc)[fieldKey] : dashVal;
-        return { boolVal: Cast(fval, "boolean", null), strVal: Field.toString(fval as Field) || "" }
+        return { boolVal: Cast(fval, "boolean", null), strVal: Field.toString(fval as Field) || "" };
     }
 
     // set the display of the field's value (checkbox for booleans, span of text for strings)
@@ -241,8 +241,8 @@ export class DashFieldViewMenu extends AntimodeMenu<AntimodeMenuProps> {
         const hideMenu = () => {
             this.fadeOut(true);
             document.removeEventListener("pointerdown", hideMenu);
-        }
-        document.addEventListener("pointerdown", hideMenu)
+        };
+        document.addEventListener("pointerdown", hideMenu);
     }
     render() {
         const buttons = [
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index ce82821b6..434fccf8d 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1202,7 +1202,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                 const tr = this._editorView.state.tr.setStoredMarks(storedMarks).insertText(FormattedTextBox.SelectOnLoadChar, this._editorView.state.doc.content.size - 1, this._editorView.state.doc.content.size).setStoredMarks(storedMarks);
                 this._editorView.dispatch(tr.setSelection(new TextSelection(tr.doc.resolve(tr.doc.content.size))));
             } else if (this._editorView && curText && !FormattedTextBox.DontSelectInitialText) {
-                selectAll(this._editorView.state, this._editorView?.dispatch)
+                selectAll(this._editorView.state, this._editorView?.dispatch);
                 this.startUndoTypingBatch();
             } else if (this._editorView) {
                 this._editorView.dispatch(this._editorView.state.tr.addStoredMark(schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) })));
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index f4e792acd..0af7715fe 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -2435,9 +2435,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
             indexNum += (index[i] * (10 ** (-i)));
         }
         this._treeViewMap.set(indexNum, treeViewDoc);
-        console.log(String(index), treeViewDoc)
         this.props.Document.presentationLinearizedDocuments = new List<Doc>(this.sort(this._treeViewMap)); // this is a flat array of Docs
-        console.log(this.props.Document.presentationLinearizedDocuments)
         return this.childDocs;
     }
 
@@ -2447,21 +2445,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
             indexNum += (index[i] * (10 ** (-i)));
         }
         console.log(String(index), treeViewDoc)
-        this._treeViewMap.delete(indexNum)
+        this._treeViewMap.delete(indexNum);
         this.props.Document.presentationLinearizedDocuments = new List<Doc>(this.sort(this._treeViewMap));
         return this.childDocs;
     }
 
     // TODO: [AL] implement sort function for an array of numbers (e.g. arr[1,2,4] v arr[1,2,1])
-    sort = (treeViewMap: Map<number, Doc>): Doc[] => {
-        // TODO
-        const sortedMap = [...treeViewMap.entries()].sort();
-        var sortedDocs = [];
-        for (var kv of sortedMap) {
-            sortedDocs.push(kv[1]);
-        }
-        return sortedDocs;
-    }
+    sort = (treeViewMap: Map<number, Doc>) => [...treeViewMap.entries()].sort().map(kv => kv[1]);
 
     render() {
         // calling this method for keyEvents
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 6db36f36a..d5fd425ad 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -154,7 +154,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
         if (doc !== this.props.rootDoc && mainCont) {
             const windowHeight = this.props.PanelHeight() / (this.props.scaling?.() || 1);
             const scrollTo = doc.unrendered ? NumCast(doc.y) : Utils.scrollIntoView(NumCast(doc.y), doc[HeightSym](), NumCast(this.props.layoutDoc._scrollTop), windowHeight, .1 * windowHeight, NumCast(this.props.Document.scrollHeight));
-            if (scrollTo !== undefined && scrollTo != this.props.layoutDoc._scrollTop) {
+            if (scrollTo !== undefined && scrollTo !== this.props.layoutDoc._scrollTop) {
                 focusSpeed = 500;
 
                 if (!this._pdfViewer) this._initialScroll = scrollTo;
-- 
cgit v1.2.3-70-g09d2


From 4bf54cdb7d2568f718446ddf6b7f17ba6a54ba91 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Sun, 5 Jun 2022 10:56:03 -0400
Subject: fixed up drawing link lines to be less jittery and smoother looking. 
 changed documentView to use a margin: auto when fitting width for something
 that can't grow to the size of the panel so that it will be centered in the
 panel and not docked at the top.

---
 src/Utils.ts                                       |  8 +--
 .../CollectionFreeFormLinkView.tsx                 | 57 +++++-----------------
 src/client/views/nodes/DocumentView.tsx            |  1 +
 src/client/views/nodes/LinkDocPreview.scss         |  6 ++-
 src/client/views/nodes/LinkDocPreview.tsx          |  7 ++-
 5 files changed, 26 insertions(+), 53 deletions(-)

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

diff --git a/src/Utils.ts b/src/Utils.ts
index e6aa0ad8b..a99646731 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -219,14 +219,14 @@ export namespace Utils {
     }
 
     export function distanceBetweenHorizontalLines(xs: number, xe: number, y: number, xs2: number, xe2: number, y2: number): [number, number[]] {
-        if ((xs2 < xs && xe2 > xs) || (xs2 < xe && xe2 > xe) || (xs2 > xs && xe2 < xe)) return [Math.abs(y - y2), [Math.max(xs, xs2), y, Math.min(xe, xe2), y]];
-        if (xe2 < xs) return [Math.sqrt((xe2 - xs) * (xe2 - xs) + (y2 - y) * (y2 - y)), [xs, y, xs, y]];
+        if ((xs2 <= xs && xe2 >= xs) || (xs2 <= xe && xe2 >= xe) || (xs2 >= xs && xe2 <= xe)) return [Math.abs(y - y2), [Math.max(xs, xs2), y, Math.min(xe, xe2), y]];
+        if (xe2 <= xs) return [Math.sqrt((xe2 - xs) * (xe2 - xs) + (y2 - y) * (y2 - y)), [xs, y, xs, y]];
         //if (xs2 > xe) 
         return [Math.sqrt((xs2 - xe) * (xs2 - xe) + (y2 - y) * (y2 - y)), [xe, y, xe, y]];
     }
     export function distanceBetweenVerticalLines(x: number, ys: number, ye: number, x2: number, ys2: number, ye2: number): [number, number[]] {
-        if ((ys2 < ys && ye2 > ys) || (ys2 < ye && ye2 > ye) || (ys2 > ys && ye2 < ye)) return [Math.abs(x - x2), [x, Math.max(ys, ys2), x, Math.min(ye, ye2)]];
-        if (ye2 < ys) return [Math.sqrt((ye2 - ys) * (ye2 - ys) + (x2 - x) * (x2 - x)), [x, ys, x, ys]];
+        if ((ys2 <= ys && ye2 >= ys) || (ys2 <= ye && ye2 >= ye) || (ys2 >= ys && ye2 <= ye)) return [Math.abs(x - x2), [x, Math.max(ys, ys2), x, Math.min(ye, ye2)]];
+        if (ye2 <= ys) return [Math.sqrt((ye2 - ys) * (ye2 - ys) + (x2 - x) * (x2 - x)), [x, ys, x, ys]];
         //if (ys2 > ye) 
         return [Math.sqrt((ys2 - ye) * (ys2 - ye) + (x2 - x) * (x2 - x)), [x, ye, x, ye]];
     }
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
index fe849ee48..5f890c810 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -52,14 +52,10 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
         if (SnappingManager.GetIsDragging() || !A.ContentDiv || !B.ContentDiv) return;
         setTimeout(action(() => this._opacity = 0.75), 0); // since the render code depends on querying the Dom through getBoudndingClientRect, we need to delay triggering render()
         setTimeout(action(() => (!LinkDocs.length || !linkDoc.linkDisplay) && (this._opacity = 0.05)), 750); // this will unhighlight the link line.
-        const acont = A.ContentDiv.getElementsByClassName("linkAnchorBox-cont");
-        const bcont = B.ContentDiv.getElementsByClassName("linkAnchorBox-cont");
-        const adiv = acont.length ? acont[0] : A.ContentDiv;
-        const bdiv = bcont.length ? bcont[0] : B.ContentDiv;
-        const a = adiv.getBoundingClientRect();
-        const b = bdiv.getBoundingClientRect();
-        const { left: aleft, top: atop, width: awidth, height: aheight } = adiv.parentElement!.getBoundingClientRect();
-        const { left: bleft, top: btop, width: bwidth, height: bheight } = bdiv.parentElement!.getBoundingClientRect();
+        const a = A.ContentDiv.getBoundingClientRect();
+        const b = B.ContentDiv.getBoundingClientRect();
+        const { left: aleft, top: atop, width: awidth, height: aheight } = A.ContentDiv.parentElement!.getBoundingClientRect();
+        const { left: bleft, top: btop, width: bwidth, height: bheight } = B.ContentDiv.parentElement!.getBoundingClientRect();
         const apt = Utils.closestPtBetweenRectangles(aleft, atop, awidth, aheight, bleft, btop, bwidth, bheight, a.left + a.width / 2, a.top + a.height / 2);
         const bpt = Utils.closestPtBetweenRectangles(bleft, btop, bwidth, bheight, aleft, atop, awidth, aheight, apt.point.x, apt.point.y);
 
@@ -97,6 +93,8 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
             const mpy = mp[1] / B.props.PanelHeight();
             if (mpx >= 0 && mpx <= 1) linkDoc.anchor2_x = mpx * 100;
             if (mpy >= 0 && mpy <= 1) linkDoc.anchor2_y = mpy * 100;
+            if (getComputedStyle(targetBhyperlink).fontSize === "0px") linkDoc.opacity = 0;
+            else linkDoc.opacity = 1;
         }
     }
 
@@ -163,25 +161,6 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
         this.toggleProperties();
     }
 
-    // componentToHex = (c: number) => {
-    //     let hex = c.toString(16);
-    //     return hex.length == 1 ? "0" + hex : hex;
-    // }
-
-    // rgbToHex = (rgbString: string) => {
-    //     if (rgbString != "black") {
-    //         const splitString = rgbString.split(/rgb|\(|\)|,| /)
-    //         let values: number[] = []
-    //         splitString.forEach(elt => {
-    //             if (elt) {
-    //                 values.push(parseInt(elt))
-    //             }
-    //         })
-    //         return "#" + this.componentToHex(values[0]) + this.componentToHex(values[1]) + this.componentToHex(values[2]);
-    //     }
-    //     return "#000000"
-    // }
-
     @computed.struct get renderData() {
         this._start; SnappingManager.GetIsDragging();
         const { A, B, LinkDocs } = this.props;
@@ -199,32 +178,18 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
         if (!a.width || !b.width) return undefined;
         const aDocBounds = (A.props as any).DocumentView?.().getBounds() || { left: 0, right: 0, top: 0, bottom: 0 };
         const bDocBounds = (B.props as any).DocumentView?.().getBounds() || { left: 0, right: 0, top: 0, bottom: 0 };
-        const acentX = (a.left + a.right) / 2;
-        const acentY = (a.top + a.bottom) / 2;
-        const bcentX = (b.left + b.right) / 2;
-        const bcentY = (b.top + b.bottom) / 2;
-        const pt1Arc = ((acentX - aDocBounds.left) > 0.1 && (aDocBounds.right - acentX) > 0.1) ||
-            ((acentY - aDocBounds.top) > 0.1 && (aDocBounds.bottom - acentY) > 0.1);
-        const pt2Arc = ((bcentX - bDocBounds.left) > 0.1 && (bDocBounds.right - bcentX) > 0.1) ||
-            ((bcentY - bDocBounds.top) > 0.1 && (bDocBounds.bottom - bcentY) > 0.1);
-        const atop2 = this.visibleY(adiv);
-        const btop2 = this.visibleY(bdiv);
         const aleft = this.visibleX(adiv);
         const bleft = this.visibleX(bdiv);
         const clipped = aleft !== a.left || atop !== a.top || bleft !== b.left || btop !== b.top;
         const pt1 = [aleft + a.width / 2, atop + a.height / 2];
         const pt2 = [bleft + b.width / 2, btop + b.width / 2];
-        const pt1vec = [pt1[0] - (aDocBounds.left + aDocBounds.right) / 2, pt1[1] - (aDocBounds.top + aDocBounds.bottom) / 2];
-        const pt2vec = [pt2[0] - (bDocBounds.left + bDocBounds.right) / 2, pt2[1] - (bDocBounds.top + bDocBounds.bottom) / 2];
+        const pt1vec = [(bDocBounds.left + bDocBounds.right) / 2 - pt1[0], (bDocBounds.top + bDocBounds.bottom) / 2 - pt1[1]];
+        const pt2vec = [(aDocBounds.left + aDocBounds.right) / 2 - pt2[0], (aDocBounds.top + aDocBounds.bottom) / 2 - pt2[1]];
         const pt1len = Math.sqrt((pt1vec[0] * pt1vec[0]) + (pt1vec[1] * pt1vec[1]));
         const pt2len = Math.sqrt((pt2vec[0] * pt2vec[0]) + (pt2vec[1] * pt2vec[1]));
         const ptlen = Math.sqrt((pt1[0] - pt2[0]) * (pt1[0] - pt2[0]) + (pt1[1] - pt2[1]) * (pt1[1] - pt2[1])) / 2;
-        const pt1norm = clipped ? [0, 0] : !pt1Arc ? [pt1vec[0] / pt1len * ptlen, pt1vec[1] / pt1len * ptlen] :
-            Math.abs(acentY - aDocBounds.top) < 0.01 ||
-                Math.abs(acentY - aDocBounds.bottom) < 0.01 ? [0, (pt2[1] - pt1[1]) / 2] : [(pt2[0] - pt1[0]) / 2, 0];
-        const pt2norm = clipped ? [0, 0] : !pt2Arc ? [pt2vec[0] / pt2len * ptlen, pt2vec[1] / pt2len * ptlen] :
-            Math.abs(bcentY - bDocBounds.top) < 0.01 ||
-                Math.abs(bcentY - bDocBounds.bottom) < 0.01 ? [0, (pt1[1] - pt2[1]) / 2] : [(pt1[0] - pt2[0]) / 2, 0];
+        const pt1norm = clipped ? [0, 0] : [pt1vec[0] / pt1len * ptlen, pt1vec[1] / pt1len * ptlen];
+        const pt2norm = clipped ? [0, 0] : [pt2vec[0] / pt2len * ptlen, pt2vec[1] / pt2len * ptlen];
         const pt1normlen = Math.sqrt(pt1norm[0] * pt1norm[0] + pt1norm[1] * pt1norm[1]) || 1;
         const pt2normlen = Math.sqrt(pt2norm[0] * pt2norm[0] + pt2norm[1] * pt2norm[1]) || 1;
         const pt1normalized = [pt1norm[0] / pt1normlen, pt1norm[1] / pt1normlen];
@@ -262,7 +227,7 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
             this.props.LinkDocs[0].displayArrow = false;
         }
 
-        return !this.props.LinkDocs[0].opacity || !a.width || !b.width || ((!this.props.LinkDocs[0].linkDisplay) && !aActive && !bActive) ? (null) : (<>
+        return this.props.LinkDocs[0].opacity === 0 || !a.width || !b.width || ((!this.props.LinkDocs[0].linkDisplay) && !aActive && !bActive) ? (null) : (<>
             <defs>
                 <marker id="arrowhead" markerWidth="4" markerHeight="3"
                     refX="0" refY="1.5" orient="auto">
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 6e4d6a52e..e23bf24a9 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1341,6 +1341,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
                         transition: this.props.dataTransition,
                         position: this.props.Document.isInkMask ? "absolute" : undefined,
                         transform: isButton ? undefined : `translate(${this.centeringX}px, ${this.centeringY}px)`,
+                        margin: this.fitWidth && this.panelHeight >= (this.ComponentView?.getScrollHeight?.() ?? 0) ? "auto" : undefined,
                         width: isButton || isPresTreeElement ? "100%" : xshift() ?? `${100 * (this.props.PanelWidth() - this.Xshift * 2) / this.props.PanelWidth()}%`,
                         height: isButton || this.props.forceAutoHeight ? undefined : yshift() ?? (this.fitWidth ? `${this.panelHeight}px` :
                             `${100 * this.effectiveNativeHeight / this.effectiveNativeWidth * this.props.PanelWidth() / this.props.PanelHeight()}%`),
diff --git a/src/client/views/nodes/LinkDocPreview.scss b/src/client/views/nodes/LinkDocPreview.scss
index 06ae466f0..3febbcecb 100644
--- a/src/client/views/nodes/LinkDocPreview.scss
+++ b/src/client/views/nodes/LinkDocPreview.scss
@@ -1,4 +1,4 @@
- .linkDocPreview {
+.linkDocPreview {
     position: absolute;
     pointer-events: all;
     background-color: lightblue;
@@ -8,11 +8,14 @@
     border-bottom: 8px solid white;
     border-right: 8px solid white;
     z-index: 2004;
+
     .linkDocPreview-inner {
         background-color: white;
         width: 100%;
         height: 100%;
         pointer-events: none;
+        display: flex;
+        flex-direction: column;
 
         .linkDocPreview-info {
             height: 37px;
@@ -21,6 +24,7 @@
             .linkDocPreview-buttonBar {
                 float: right;
             }
+
             .linkDocPreview-title {
                 padding-right: 4px;
                 float: left;
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index b6a9cd49b..152288d8b 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -108,8 +108,11 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
     }
     nextHref = (e: React.PointerEvent) => {
         setupMoveUpEvents(this, e, returnFalse, emptyFunction, action(() => {
-            this._linkDoc = undefined;
-            this._hrefInd = (this._hrefInd + 1) % (this.props.hrefs?.length || 1);
+            const nextHrefInd = (this._hrefInd + 1) % (this.props.hrefs?.length || 1);
+            if (nextHrefInd !== this._hrefInd) {
+                this._linkDoc = undefined;
+                this._hrefInd = nextHrefInd;
+            }
         }), true);
     }
 
-- 
cgit v1.2.3-70-g09d2


From 69916b81701c61df6ac2bbdfdb518ba127e28c0b Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Sun, 5 Jun 2022 16:27:43 -0400
Subject: fixed screen to local for fitWidth views that are smaller in height
 than their panel

---
 src/client/views/nodes/DocumentView.tsx | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

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

diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index e23bf24a9..649340da7 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1307,7 +1307,9 @@ export class DocumentView extends React.Component<DocumentViewProps> {
     ContentScale = () => this.nativeScaling;
     selfView = () => this;
     screenToLocalTransform = () => {
-        return this.props.ScreenToLocalTransform().translate(-this.centeringX, -this.centeringY).scale(1 / this.nativeScaling);
+        const oshift = this.fitWidth && this.ComponentView instanceof FormattedTextBox;
+        const shift = oshift ? -(this.props.PanelHeight() - this.rootDoc[HeightSym]()) / 2 : 0;
+        return this.props.ScreenToLocalTransform().translate(-this.centeringX, -this.centeringY).translate(0, shift).scale(1 / this.nativeScaling);
     }
     componentDidMount() {
         this._disposers.reactionScript = reaction(
@@ -1341,7 +1343,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
                         transition: this.props.dataTransition,
                         position: this.props.Document.isInkMask ? "absolute" : undefined,
                         transform: isButton ? undefined : `translate(${this.centeringX}px, ${this.centeringY}px)`,
-                        margin: this.fitWidth && this.panelHeight >= (this.ComponentView?.getScrollHeight?.() ?? 0) ? "auto" : undefined,
+                        margin: this.fitWidth ? "auto" : undefined,
                         width: isButton || isPresTreeElement ? "100%" : xshift() ?? `${100 * (this.props.PanelWidth() - this.Xshift * 2) / this.props.PanelWidth()}%`,
                         height: isButton || this.props.forceAutoHeight ? undefined : yshift() ?? (this.fitWidth ? `${this.panelHeight}px` :
                             `${100 * this.effectiveNativeHeight / this.effectiveNativeWidth * this.props.PanelWidth() / this.props.PanelHeight()}%`),
-- 
cgit v1.2.3-70-g09d2


From 69fbc57e813b55963911629dba552f633928d10b Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 7 Jun 2022 10:08:25 -0400
Subject: simplified interaction between PresElementBox and PresBox for sharing
 presBox data.  fixed problem with miniView getting the wrong slide count.

---
 src/client/views/DocComponent.tsx                  |  3 --
 .../collections/collectionFreeForm/MarqueeView.tsx |  1 -
 src/client/views/nodes/DocumentView.tsx            |  2 +-
 src/client/views/nodes/trails/PresBox.tsx          | 52 +++++++++-------------
 src/client/views/nodes/trails/PresElementBox.tsx   | 10 ++---
 5 files changed, 25 insertions(+), 43 deletions(-)

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

diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 9c176a4fd..67f8c8585 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -60,12 +60,9 @@ export function ViewBoxBaseComponent<P extends ViewBoxBaseProps>() {
         @computed get layoutDoc() { return Doc.Layout(this.props.Document); }
         // 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[DataSym]; }
-
         // key where data is stored
         @computed get fieldKey() { return this.props.fieldKey; }
 
-        lookupField = (field: string) => ScriptCast(this.layoutDoc.lookupField)?.script.run({ self: this.layoutDoc, data: this.rootDoc, field: field, container: this.props.DocumentView?.().props.treeViewDoc ?? this.props.ContainingCollectionDoc }).result;
-
         isContentActive = (outsideReaction?: boolean) => (
             this.props.isContentActive?.() === false ? false :
                 (CurrentUserUtils.SelectedTool !== InkTool.None ||
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index efdcfd48e..3fac3350a 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -404,7 +404,6 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
     @undoBatch
     @action
     pinWithView = async () => {
-		console.log("pinWithView");
         const scale = Math.min(this.props.PanelWidth() / this.Bounds.width, this.props.PanelHeight() / this.Bounds.height);
 		const doc = this.props.Document;
 		const viewOptions:PinViewProps = {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 073f734c0..59a402e01 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -956,7 +956,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
     @computed get allLinkEndpoints() {  // the small blue dots that mark the endpoints of links
         TraceMobx();
         if (this.layoutDoc.unrendered || this.props.LayoutTemplateString?.includes(LinkAnchorBox.name)) return null;
-        if (this.layoutDoc.presBox || this.rootDoc.type === DocumentType.LINK || this.props.dontRegisterView) return (null);
+        if (this.rootDoc.type=== DocumentType.PRES || this.rootDoc.type === DocumentType.LINK || this.props.dontRegisterView) return (null);
         const filtered = DocUtils.FilterDocs(this.directLinks, this.props.docFilters?.() ?? [], []).filter(d => !d.hidden);
         return filtered.map((link, i) =>
             <div className="documentView-anchorCont" key={link[Id]}>
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index b6ce3e77a..980bdf4d6 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -10,17 +10,16 @@ import { InkTool } from "../../../../fields/InkField";
 import { List } from "../../../../fields/List";
 import { PrefetchProxy } from "../../../../fields/Proxy";
 import { listSpec } from "../../../../fields/Schema";
-import { ScriptField } from "../../../../fields/ScriptField";
 import { BoolCast, Cast, NumCast, StrCast } from "../../../../fields/Types";
 import { emptyFunction, returnFalse, returnOne, returnTrue, setupMoveUpEvents } from '../../../../Utils';
 import { Docs } from "../../../documents/Documents";
 import { DocumentType } from "../../../documents/DocumentTypes";
 import { CurrentUserUtils } from "../../../util/CurrentUserUtils";
 import { DocumentManager } from "../../../util/DocumentManager";
-import { ScriptingGlobals } from "../../../util/ScriptingGlobals";
 import { SelectionManager } from "../../../util/SelectionManager";
 import { undoBatch, UndoManager } from "../../../util/UndoManager";
 import { CollectionDockingView } from "../../collections/CollectionDockingView";
+import { MarqueeViewBounds } from "../../collections/collectionFreeForm";
 import { CollectionView, CollectionViewType } from "../../collections/CollectionView";
 import { TabDocView } from "../../collections/TabDocView";
 import { ViewBoxBaseComponent } from "../../DocComponent";
@@ -30,7 +29,6 @@ import { CollectionFreeFormDocumentView } from "../CollectionFreeFormDocumentVie
 import { FieldView, FieldViewProps } from '../FieldView';
 import "./PresBox.scss";
 import { PresEffect, PresMovement, PresStatus } from "./PresEnums";
-import { MarqueeViewBounds } from "../../collections/collectionFreeForm";
 
 export interface PinProps {
     audioRange?: boolean;
@@ -44,7 +42,6 @@ export interface PinViewProps {
   scale: number;
 }
 
-
 @observer
 export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PresBox, fieldKey); }
@@ -105,11 +102,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     @observable private openMovementDropdown: boolean = false;
     @observable private openEffectDropdown: boolean = false;
     @observable private presentTools: boolean = false;
-    // @computed get childDocs() { return DocListCast(this.rootDoc[this.fieldKey]); }
-    // TODO: [AL] add childDocs() and treeMap fields
-    // @computed get childDocs() { return DocListCast(this.rootDoc.presentationaLinearizedDocuments); }
-    //_treeViewMap:Map<number[], Doc>
-    @computed get childDocs() { return this.layoutDoc._viewType === CollectionViewType.Tree ? DocListCast(this.rootDoc.presentationLinearizedDocuments) : DocListCast(this.rootDoc[this.fieldKey]); }
+    @computed get isTreeOrStack() {return [CollectionViewType.Tree, CollectionViewType.Stacking].includes(StrCast(this.layoutDoc._viewType) as any) }
+    @computed get isTree() { return this.layoutDoc._viewType === CollectionViewType.Tree;}
+    @computed get presFieldKey() { return StrCast(this.dataDoc.presFieldKey); }
+    @computed get childDocs() { return DocListCast(this.rootDoc[this.presFieldKey]); }
     @observable _treeViewMap: Map<Doc, number> = new Map();
 
     @computed get tagDocs() {
@@ -139,12 +135,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
             Doc.UserDoc().presElement = new PrefetchProxy(Docs.Create.PresElementBoxDocument({
                 title: "pres element template", type: DocumentType.PRESELEMENT, _fitWidth: true, _xMargin: 0, isTemplateDoc: true, isTemplateForField: "data"
             }));
-            // this script will be called by each presElement to get rendering-specific info that the PresBox knows about but which isn't written to the PresElement
-            // this is a design choice -- we could write this data to the presElements which would require a reaction to keep it up to date, and it would prevent
-            // the preselement docs from being part of multiple presentations since they would all have the same field, or we'd have to keep per-presentation data
-            // stored on each pres element.
-            (this.presElement as Doc).lookupField = ScriptField.MakeFunction("lookupPresBoxField(container, field, data)",
-                { field: "string", data: Doc.name, container: Doc.name });
         }
         this.props.Document.presentationFieldKey = this.fieldKey; // provide info to the presElement script so that it can look up rendering information about the presBox
 
@@ -164,8 +154,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     }
     @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; }
 
+    _unmounting = false;
     @action
     componentWillUnmount() {
+        this._unmounting = true;
         document.removeEventListener("keydown", PresBox.keyEventsWrapper, true);
         this._presKeyEventsActive = false;
         this.resetPresentation();
@@ -176,7 +168,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
 
     @action
     componentDidMount() {
-        this.rootDoc.presBox = this.rootDoc;
+        this._unmounting = false;
         this.rootDoc._forceRenderEngine = "timeline";
         this.layoutDoc.presStatus = PresStatus.Edit;
         this.layoutDoc._gridGap = 0;
@@ -640,7 +632,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         // pivot field may be set by the user in timeline view (or some other way) -- need to reset it here
         [CollectionViewType.Tree || CollectionViewType.Stacking].includes(viewType) && (this.rootDoc._pivotField = undefined);
         this.rootDoc._viewType = viewType;
-        if ([CollectionViewType.Tree || CollectionViewType.Stacking].includes(viewType)) this.layoutDoc._gridGap = 0;
+        if (this.isTreeOrStack) {
+            this.layoutDoc.presFieldKey = this.fieldKey+(this.isTree ?"-linearized":"");
+            this.layoutDoc._gridGap = 0;
+        }
     });
 
     /**
@@ -714,7 +709,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         });
         return true;
     }
-    childLayoutTemplate = () => ![CollectionViewType.Stacking, CollectionViewType.Tree].includes(this.rootDoc._viewType as any) ? undefined : this.presElement;
+    childLayoutTemplate = () => !this.isTreeOrStack ? undefined : this.presElement;
     removeDocument = (doc: Doc) => Doc.RemoveDocFromList(this.rootDoc, this.fieldKey, doc);
     getTransform = () => this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight
     panelHeight = () => this.props.PanelHeight() - 40;
@@ -2468,14 +2463,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         }
         if (this._treeViewMap.get(treeViewDoc) !== indexNum) {
             this._treeViewMap.set(treeViewDoc, indexNum);
-            this.props.Document.presentationLinearizedDocuments = new List<Doc>(this.sort(this._treeViewMap)); // this is a flat array of Docs
+            this.dataDoc[this.presFieldKey] = new List<Doc>(this.sort(this._treeViewMap)); // this is a flat array of Docs
         }
         return this.childDocs;
     }
 
     RemFromMap = (treeViewDoc: Doc, index: number[]): Doc[] => {
-        this._treeViewMap.delete(treeViewDoc);
-        this.props.Document.presentationLinearizedDocuments = new List<Doc>(this.sort(this._treeViewMap));
+        if (!this._unmounting && this.isTree) {
+            this._treeViewMap.delete(treeViewDoc);
+            this.dataDoc[this.presFieldKey] = new List<Doc>(this.sort(this._treeViewMap));
+        }
         return this.childDocs;
     }
 
@@ -2536,8 +2533,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                                 removeDocument={returnFalse}
                                 dontRegisterView={true}
                                 focus={this.selectElement}
+                                scriptContext={this}
                                 ScreenToLocalTransform={this.getTransform}
-                                // TODO: [AL] implement AddToMap, RemFromMap functions (outside this)
                                 AddToMap={this.AddToMap}
                                 RemFromMap={this.RemFromMap}
                                 hierarchyIndex={[]}
@@ -2555,13 +2552,4 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 </div>
             </div>;
     }
-}
-// this func communicates with PresBoxElement to send information of the doc
-ScriptingGlobals.add(function lookupPresBoxField(presBoxDoc: Doc, field: string, presEleDoc: Doc) {
-    if (field === 'indexInPres') return DocListCast(presBoxDoc._viewType === CollectionViewType.Tree ? presBoxDoc.presentationLinearizedDocuments : presBoxDoc[StrCast(presBoxDoc.presentationFieldKey)]).indexOf(presEleDoc);
-    if (field === 'presCollapsedHeight') return [CollectionViewType.Tree, CollectionViewType.Stacking].includes(presBoxDoc._viewType as any) ? 35 : 31;
-    if (field === 'presStatus') return presBoxDoc.presStatus;
-    if (field === '_itemIndex') return presBoxDoc._itemIndex;
-    if (field === 'presBox') return presBoxDoc;
-    return undefined;
-});
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx
index 19435d22c..b9951eaae 100644
--- a/src/client/views/nodes/trails/PresElementBox.tsx
+++ b/src/client/views/nodes/trails/PresElementBox.tsx
@@ -34,12 +34,10 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
     _heightDisposer: IReactionDisposer | undefined;
 
     @observable _dragging = false;
-    // these fields are conditionally computed fields on the layout document that take this document as a parameter
-    @computed get indexInPres() { return Number(this.lookupField("indexInPres")); }  // the index field is where this document is in the presBox display list (since this value is different for each presentation element, the value can't be stored on the layout template which is used by all display elements)
-    @computed get collapsedHeight() { return Number(this.lookupField("presCollapsedHeight")); } // the collapsed height changes depending on the state of the presBox.  We could store this on the presentation element template if it's used by only one presentation - but if it's shared by multiple, then this value must be looked up
-    @computed get presStatus() { return StrCast(this.lookupField("presStatus")); }
-    @computed get itemIndex() { return NumCast(this.lookupField("_itemIndex")); }
-    @computed get presBox() { return Cast(this.lookupField("presBox"), Doc, null); }
+    @computed get indexInPres() { return DocListCast(this.presBox[StrCast(this.presBox.presFieldKey, "data")]).indexOf(this.rootDoc); }  // the index field is where this document is in the presBox display list (since this value is different for each presentation element, the value can't be stored on the layout template which is used by all display elements)
+    @computed get collapsedHeight() { return [CollectionViewType.Tree, CollectionViewType.Stacking].includes(this.presBox._viewType as any) ? 35 : 31; } // the collapsed height changes depending on the state of the presBox.  We could store this on the presentation element template if it's used by only one presentation - but if it's shared by multiple, then this value must be looked up
+    @computed get presStatus() { return this.presBox.presStatus; }
+    @computed get presBox() { return (this.props.DocumentView?.().props.treeViewDoc ?? this.props.ContainingCollectionDoc)!; }
     @computed get targetDoc() { return Cast(this.rootDoc.presentationTargetDoc, Doc, null) || this.rootDoc; }
 
     componentDidMount() {
-- 
cgit v1.2.3-70-g09d2


From ec2e780141fb41d3f70aa86b0312211e0b30257c Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 9 Jun 2022 10:39:14 -0400
Subject: fixed issues with pinWithView so that thumnails show the pinned area
 and navigating to the view shows the entire pinned area regardless of panel
 size.

---
 src/client/views/DocumentButtonBar.tsx             | 29 +------------------
 src/client/views/collections/TabDocView.tsx        | 33 ++++++++++++++++++++++
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 10 +++++--
 src/client/views/nodes/DocumentView.tsx            |  1 +
 src/client/views/nodes/trails/PresBox.tsx          | 20 +++++++++++--
 src/client/views/nodes/trails/PresElementBox.tsx   |  8 +++---
 6 files changed, 64 insertions(+), 37 deletions(-)

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

diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 103734b9b..41224b1c5 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -212,34 +212,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
 
     @undoBatch
     @action
-    pinWithView = (targetDoc: Doc) => {
-        const activeDoc = targetDoc && TabDocView.PinDoc(targetDoc);
-        if (activeDoc) {
-            const scrollable = [DocumentType.PDF, DocumentType.RTF, DocumentType.WEB].includes(targetDoc.type as any) || targetDoc._viewType === CollectionViewType.Stacking;
-            const pannable: boolean = ((targetDoc.type === DocumentType.COL && targetDoc._viewType === CollectionViewType.Freeform) || targetDoc.type === DocumentType.IMG);
-            if (scrollable) {
-                const scroll = targetDoc._scrollTop;
-                activeDoc.presPinView = true;
-                activeDoc.presPinViewScroll = scroll;
-            } else if ([DocumentType.AUDIO, DocumentType.VID].includes(targetDoc.type as any)) {
-                activeDoc.presPinView = true;
-                activeDoc.presStartTime = targetDoc._currentTimecode;
-                activeDoc.presEndTime = NumCast(targetDoc._currentTimecode) + 0.1;
-            } else if (pannable) {
-                const x = targetDoc._panX;
-                const y = targetDoc._panY;
-                const scale = targetDoc._viewScale;
-                activeDoc.presPinView = true;
-                activeDoc.presPinViewX = x;
-                activeDoc.presPinViewY = y;
-                activeDoc.presPinViewScale = scale;
-            } else if (targetDoc.type === DocumentType.COMPARISON) {
-                const width = targetDoc._clipWidth;
-                activeDoc.presPinClipWidth = width;
-                activeDoc.presPinView = true;
-            }
-        }
-    }
+    pinWithView = (targetDoc: Doc) =>  targetDoc && TabDocView.PinDoc(targetDoc, {pinDocView: true});
 
     @computed
     get pinWithViewButton() {
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 34fe572e3..f6a75e2db 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -227,6 +227,39 @@ export class TabDocView extends React.Component<TabDocViewProps> {
             	pinDoc.presPinViewX = viewProps.bounds.left + viewProps.bounds.width / 2;
             	pinDoc.presPinViewY = viewProps.bounds.top + viewProps.bounds.height / 2;
             	pinDoc.presPinViewScale = viewProps.scale;
+                pinDoc.contentBounds = new List<number>([viewProps.bounds.left, viewProps.bounds.top, viewProps.bounds.left+viewProps.bounds.width, viewProps.bounds.top+viewProps.bounds.height]);
+            }
+            if (pinProps?.pinDocView) {
+                const scrollable = [DocumentType.PDF, DocumentType.RTF, DocumentType.WEB].includes(pinDoc.type as any) || pinDoc._viewType === CollectionViewType.Stacking;
+                const pannable: boolean = ((pinDoc.type === DocumentType.COL && doc._viewType === CollectionViewType.Freeform) || doc.type === DocumentType.IMG);
+                if (scrollable) {
+                    const scroll = doc._scrollTop;
+                    pinDoc.presPinView = true;
+                    pinDoc.presPinViewScroll = scroll;
+                } else if ([DocumentType.AUDIO, DocumentType.VID].includes(doc.type as any)) {
+                    pinDoc.presPinView = true;
+                    pinDoc.presStartTime = doc._currentTimecode;
+                    pinDoc.presEndTime = NumCast(doc._currentTimecode) + 0.1;
+                } else if (pannable) {
+                    pinDoc.presPinView = true;
+                    pinDoc.presPinViewX = pinDoc._panX;
+                    pinDoc.presPinViewY = pinDoc._panY;
+                    pinDoc.presPinViewScale = pinDoc._viewScale;
+                    const pw = NumCast(pinProps.panelWidth);
+                    const ph = NumCast(pinProps.panelHeight);
+                    const ps = NumCast(pinDoc._viewScale);
+                    if (pw && ph && ps) {
+                        pinDoc.contentBounds = new List<number>([
+                            NumCast(pinDoc.panX)-pw/2/ps,
+                            NumCast(pinDoc.panY)-ph/2/ps,
+                            NumCast(pinDoc.panX)+pw/2/ps,
+                            NumCast(pinDoc.panY)+ph/2/ps]);
+                    }
+                } else if (doc.type === DocumentType.COMPARISON) {
+                    const width = doc._clipWidth;
+                    pinDoc.presPinClipWidth = width;
+                    pinDoc.presPinView = true;
+                }
 			}
             Doc.AddDocToList(curPres, "data", pinDoc, presSelected);
             if (!pinProps?.audioRange && duration !== undefined) {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 5f927a2a9..b70e6ff98 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -56,6 +56,7 @@ import "./CollectionFreeFormView.scss";
 import { MarqueeView } from "./MarqueeView";
 import React = require("react");
 import { FieldView, FieldViewProps } from "../../nodes/FieldView";
+import { TabDocView } from "../TabDocView";
 
 export const panZoomSchema = createSchema({
     _panX: "number",
@@ -138,7 +139,11 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         };
     }
     @computed get fitToContent() { return (this.props.fitContentsToDoc?.() || this.Document._fitToBox) && !this.isAnnotationOverlay; }
-    @computed get contentBounds() { return aggregateBounds(this._layoutElements.filter(e => e.bounds && !e.bounds.z).map(e => e.bounds!), NumCast(this.layoutDoc._xPadding, 10), NumCast(this.layoutDoc._yPadding, 10)); }
+    @computed get contentBounds() { 
+        const cb = Cast(this.rootDoc.contentBounds, listSpec("number"));
+        return cb ? {x:cb[0], y:cb[1], r:cb[2], b: cb[3]} : 
+            this.props.contentBounds?.() ?? aggregateBounds(this._layoutElements.filter(e => e.bounds && !e.bounds.z).map(e => e.bounds!), NumCast(this.layoutDoc._xPadding, 10), NumCast(this.layoutDoc._yPadding, 10)); 
+    }
     @computed get nativeWidth() { return this.fitToContent ? 0 : Doc.NativeWidth(this.Document); }
     @computed get nativeHeight() { return this.fitToContent ? 0 : Doc.NativeHeight(this.Document); }
     @computed get cachedCenteringShiftX(): number {
@@ -1612,7 +1617,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         appearanceItems.push({ description: "Reset View", event: () => { this.props.Document._panX = this.props.Document._panY = 0; this.props.Document[this.scaleFieldKey] = 1; }, icon: "compress-arrows-alt" });
         !Doc.UserDoc().noviceMode && Doc.UserDoc().defaultTextLayout && appearanceItems.push({ description: "Reset default note style", event: () => Doc.UserDoc().defaultTextLayout = undefined, icon: "eye" });
         appearanceItems.push({ description: `${this.fitToContent ? "Make Zoomable" : "Scale to Window"}`, event: () => this.Document._fitToBox = !this.fitToContent, icon: !this.fitToContent ? "expand-arrows-alt" : "compress-arrows-alt" });
-        appearanceItems.push({ description: `update icon`, event: this.updateIcon, icon: "compress-arrows-alt" });
+        appearanceItems.push({ description: `Pin View`, event: () => TabDocView.PinDoc(this.rootDoc, {pinDocView:true, panelWidth: this.props.PanelWidth(), panelHeight:this.props.PanelHeight()}), icon: "map-pin" });
+        //appearanceItems.push({ description: `update icon`, event: this.updateIcon, icon: "compress-arrows-alt" });
         this.props.ContainingCollectionView &&
             appearanceItems.push({ description: "Ungroup collection", event: this.promoteCollection, icon: "table" });
 
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 59a402e01..26dec3bd5 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -112,6 +112,7 @@ export interface DocumentViewSharedProps {
     renderDepth: number;
     Document: Doc;
     DataDoc?: Doc;
+    contentBounds?: () => (undefined|{x:number, y:number, r:number, b:number});
     fitContentsToDoc?: () => boolean; // used by freeformview to fit its contents to its panel. corresponds to _fitToBox property on a Document
     ContainingCollectionView: Opt<CollectionView>;
     ContainingCollectionDoc: Opt<Doc>;
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 591480023..6de04bd31 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -35,6 +35,9 @@ export interface PinProps {
     setPosition?: boolean;
     hidePresBox?: boolean;
     pinWithView?: PinViewProps;
+    pinDocView?: boolean;
+    panelWidth?: number;
+    panelHeight?: number
 }
 
 export interface PinViewProps {
@@ -339,10 +342,21 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
             } else if ([DocumentType.AUDIO, DocumentType.VID].includes(bestTarget.type as any)) {
                 bestTarget._currentTimecode = activeItem.presStartTime;
             } else {
+                const contentBounds= Cast(activeItem.contentBounds, listSpec("number"));
                 bestTarget._viewTransition = activeItem.presTransition ? `transform ${activeItem.presTransition}ms` : 'all 0.5s';
-                bestTarget._panX = activeItem.presPinViewX;
-                bestTarget._panY = activeItem.presPinViewY;
-                bestTarget._viewScale = activeItem.presPinViewScale;
+                if (contentBounds) {
+                    bestTarget._panX = (contentBounds[0] + contentBounds[2])/2;
+                    bestTarget._panY = (contentBounds[1] + contentBounds[3])/2;
+                    const dv = DocumentManager.Instance.getDocumentView(bestTarget);
+                    if (dv) {
+                        bestTarget._viewScale =  Math.min(dv.props.PanelHeight() / (contentBounds[3] - contentBounds[1]),
+                                dv.props.PanelWidth() / (contentBounds[2]- contentBounds[0]));
+                    };
+                } else {
+                    bestTarget._panX = activeItem.presPinViewX;
+                    bestTarget._panY = activeItem.presPinViewY;
+                    bestTarget._viewScale = activeItem.presPinViewScale;
+                }
             }
             this._navTimer = setTimeout(() => bestTarget._viewTransition = undefined, activeItem.presTransition ? NumCast(activeItem.presTransition) + 10 : 510);
         });
diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx
index b9951eaae..5eff47a86 100644
--- a/src/client/views/nodes/trails/PresElementBox.tsx
+++ b/src/client/views/nodes/trails/PresElementBox.tsx
@@ -2,7 +2,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { Tooltip } from "@material-ui/core";
 import { action, computed, IReactionDisposer, observable, reaction } from "mobx";
 import { observer } from "mobx-react";
-import { DataSym, Doc, DocListCast, Opt } from "../../../../fields/Doc";
+import { Doc, DocListCast, Opt } from "../../../../fields/Doc";
 import { Id } from "../../../../fields/FieldSymbols";
 import { BoolCast, Cast, NumCast, StrCast } from "../../../../fields/Types";
 import { emptyFunction, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents } from "../../../../Utils";
@@ -13,6 +13,7 @@ import { DocumentManager } from "../../../util/DocumentManager";
 import { DragManager } from "../../../util/DragManager";
 import { Transform } from "../../../util/Transform";
 import { undoBatch } from "../../../util/UndoManager";
+import { CollectionViewType } from "../../collections/CollectionView";
 import { ViewBoxBaseComponent } from '../../DocComponent';
 import { EditableView } from "../../EditableView";
 import { Colors } from "../../global/globalEnums";
@@ -23,7 +24,6 @@ import { PresBox } from "./PresBox";
 import "./PresElementBox.scss";
 import { PresMovement } from "./PresEnums";
 import React = require("react");
-import { CollectionViewType } from "../../collections/CollectionView";
 /**
  * This class models the view a document added to presentation will have in the presentation.
  * It involves some functionality for its buttons and options.
@@ -75,8 +75,8 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
         return !this.rootDoc.presExpandInlineButton || !this.targetDoc ? (null) :
             <div className="presItem-embedded" style={{ height: this.embedHeight(), width: this.embedWidth() }}>
                 <DocumentView
-                    Document={this.targetDoc}
-                    DataDoc={this.targetDoc[DataSym] !== this.targetDoc && this.targetDoc[DataSym]}
+                    Document={this.rootDoc}
+                    DataDoc={undefined}//this.targetDoc[DataSym] !== this.targetDoc && this.targetDoc[DataSym]}
                     styleProvider={this.styleProvider}
                     docViewPath={returnEmptyDoclist}
                     rootSelected={returnTrue}
-- 
cgit v1.2.3-70-g09d2


From 3213c24210d67af0a4b027863773ad383404a59c Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 9 Jun 2022 11:07:34 -0400
Subject: renamed fitToBox to fitContentsToBox.  fixed pinning multiple
 documents at same time to not bring up presBox multiple times.

---
 src/client/documents/Documents.ts                  |  3 +-
 src/client/views/DocumentButtonBar.tsx             | 21 ++----------
 src/client/views/LightboxView.tsx                  |  2 --
 src/client/views/MainView.tsx                      |  2 +-
 src/client/views/PropertiesButtons.tsx             |  2 +-
 src/client/views/PropertiesView.tsx                |  2 +-
 src/client/views/collections/CollectionMenu.tsx    |  4 +--
 .../views/collections/CollectionTimeView.tsx       |  2 +-
 src/client/views/collections/TabDocView.tsx        | 25 +++++++--------
 src/client/views/collections/TreeView.tsx          |  2 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 37 +++++++---------------
 .../collections/collectionFreeForm/MarqueeView.tsx |  2 +-
 .../CollectionMulticolumnView.tsx                  |  2 +-
 .../CollectionMultirowView.tsx                     |  2 +-
 .../collectionSchema/CollectionSchemaView.tsx      |  2 +-
 src/client/views/nodes/DocumentView.tsx            |  4 +--
 src/client/views/nodes/MapBox/MapBox.tsx           |  6 ++--
 .../views/nodes/formattedText/FormattedTextBox.tsx |  6 ++--
 src/client/views/nodes/trails/PresBox.tsx          | 14 ++++----
 src/client/views/nodes/trails/PresElementBox.tsx   |  2 +-
 src/fields/documentSchemas.ts                      |  6 ++--
 src/mobile/AudioUpload.tsx                         |  4 +--
 22 files changed, 60 insertions(+), 92 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index acc1e341a..144a3d9cf 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -113,7 +113,8 @@ export class DocumentOptions {
     _dimMagnitude?: NUMt = new NumInfo("magnitude of collectionMulti{row,col} element's width or height", true);
     _dimUnit?: DIMt = new DimInfo("units of collectionMulti{row,col} element's width or height - 'px' or '*' for pixels or relative units", true);
     _fitWidth?: BOOLt = new BoolInfo("whether document should scale its contents to fit its rendered width or not (e.g., for PDFviews)", true);
-    _fitToBox?: boolean; // whether a freeformview should zoom/scale to create a shrinkwrapped view of its contents
+    _fitContentsToBox?: boolean; // whether a freeformview should zoom/scale to create a shrinkwrapped view of its contents
+    _contentBounds?: List<number>; // the (forced) bounds of the document to display. format is: [left, top, right, bottom]
     _lockedPosition?: boolean; // lock the x,y coordinates of the document so that it can't be dragged
     _lockedTransform?: boolean; // lock the panx,pany and scale parameters of the document so that it be panned/zoomed
     _isPushpin?: boolean; // whether document, when clicked, toggles display of its link target
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 41224b1c5..0bbe473d7 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -204,27 +204,13 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
             <div className="dash-tooltip">{SelectionManager.Views().length > 1 ? "Pin multiple documents to presentation" : "Pin to presentation"}</div>}>
             <div className="documentButtonBar-icon"
                 style={{ color: "white" }}
-                onClick={undoBatch(e => this.props.views().map(view => view && this.pinWithView(view.props.Document)))}>
+                onClick={(e => TabDocView.PinDoc(this.props.views().filter(v => v).map(dv => dv!.rootDoc), {pinDocView: true}))}
+             >
                 <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin" />
             </div>
         </Tooltip>;
     }
 
-    @undoBatch
-    @action
-    pinWithView = (targetDoc: Doc) =>  targetDoc && TabDocView.PinDoc(targetDoc, {pinDocView: true});
-
-    @computed
-    get pinWithViewButton() {
-        const presPinWithViewIcon = <img src="/assets/pinWithView.png" style={{ margin: "auto", width: 17, transform: 'translate(0, 1px)' }} />;
-        const targetDoc = this.view0?.props.Document;
-        return !targetDoc ? (null) : <Tooltip title={<><div className="dash-tooltip">{"Pin with current view"}</div></>}>
-            <div className="documentButtonBar-icon" onClick={() => this.pinWithView(targetDoc)}>
-                {presPinWithViewIcon}
-            </div>
-        </Tooltip>;
-    }
-
     @computed
     get shareButton() {
         const targetDoc = this.view0?.props.Document;
@@ -349,9 +335,6 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
             <div className="documentButtonBar-button">
                 {this.pinButton}
             </div>
-            {/* <div className="documentButtonBar-button">
-                {this.pinWithViewButton}
-            </div> */}
             {!Doc.UserDoc()["documentLinksButton-fullMenu"] ? (null) : <div className="documentButtonBar-button">
                 {this.shareButton}
             </div>}
diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx
index f67f37bfb..fcc4aea13 100644
--- a/src/client/views/LightboxView.tsx
+++ b/src/client/views/LightboxView.tsx
@@ -207,7 +207,6 @@ export class LightboxView extends React.Component<LightboxViewProps> {
 
     future = () => LightboxView._future;
     tourMap = () => LightboxView._tourMap;
-    fitToBox = () => LightboxView._docTarget === LightboxView.LightboxDoc;
     render() {
         let downx = 0, downy = 0;
         return !LightboxView.LightboxDoc ? (null) :
@@ -241,7 +240,6 @@ export class LightboxView extends React.Component<LightboxViewProps> {
                         DataDoc={undefined}
                         LayoutTemplate={LightboxView.LightboxDocTemplate}
                         addDocument={undefined}
-                        // fitContentsToDoc={this.fitToBox} // bcz: why do we want this?  when we initially open a colletion, we shrinkwrap it which allows for user navigation.  if we later encounter a collection, it's not clear to me that we want to make it either shrinkwrap or fitContents...
                         isDocumentActive={returnFalse}
                         isContentActive={returnTrue}
                         addDocTab={this.addDocTab}
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 641178cd9..84a131a57 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -287,7 +287,7 @@ export class MainView extends React.Component {
                 styleProvider={DefaultStyleProvider}
                 rootSelected={returnTrue}
                 removeDocument={returnFalse}
-                fitContentsToDoc={returnTrue}
+                fitContentsToBox={returnTrue}
                 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}
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index f24ff09db..74055f057 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -71,7 +71,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
         return this.propertyToggleBtn("Lock\xA0View", "_lockedTransform", on => `${on ? "Unlock" : "Lock"} panning of view`, on => "lock");
     }
     @computed get fitContentButton() {
-        return this.propertyToggleBtn("View All", "_fitToBox", on => `${on ? "Don't" : "Do"} fit content to container visible area`, on => "eye");
+        return this.propertyToggleBtn("View All", "_fitContentsToBox", on => `${on ? "Don't" : "Do"} fit content to container visible area`, on => "eye");
     }
     @computed get fitWidthButton() {
         return this.propertyToggleBtn("Fit\xA0Width", "_fitWidth", on => `${on ? "Don't" : "Do"} fit content to width of container`, on => "arrows-alt-h");
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index bcfd2dd56..16eb95cf4 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -300,7 +300,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
                     Document={layoutDoc}
                     DataDoc={this.dataDoc}
                     renderDepth={1}
-                    fitContentsToDoc={returnTrue}
+                    fitContentsToBox={returnTrue}
                     rootSelected={returnFalse}
                     styleProvider={DefaultStyleProvider}
                     docViewPath={returnEmptyDoclist}
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 01e77f342..39f6466d6 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -252,8 +252,8 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
     };
     _clusterCommand = {
         params: ["target"], title: "fit content",
-        script: "self.target._fitToBox = !self.target._fitToBox;",
-        immediate: undoBatch((source: Doc[]) => this.target._fitToBox = !this.target._fitToBox),
+        script: "self.target._fitContentsToBox = !self.target._fitContentsToBox;",
+        immediate: undoBatch((source: Doc[]) => this.target._fitContentsToBox = !this.target._fitContentsToBox),
         initialize: emptyFunction
     };
     _fitContentCommand = {
diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx
index 4f6f45d2f..7573b938a 100644
--- a/src/client/views/collections/CollectionTimeView.tsx
+++ b/src/client/views/collections/CollectionTimeView.tsx
@@ -135,7 +135,7 @@ export class CollectionTimeView extends CollectionSubView() {
             onClick={this.contentsDown}>
             <CollectionFreeFormView {...this.props}
                 engineProps={{ pivotField: this.pivotField, docFilters: this.childDocFilters, docRangeFilters: this.childDocRangeFilters }}
-                fitContentsToDoc={returnTrue}
+                fitContentsToBox={returnTrue}
                 childClickScript={this._childClickedScript}
                 viewDefDivClick={this._viewDefDivClick}
                 childFreezeDimensions={true}
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index f6a75e2db..5cc92a305 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -192,15 +192,15 @@ export class TabDocView extends React.Component<TabDocViewProps> {
      * Adds a document to the presentation view
      **/
     @action
-    public static PinDoc(doc: Doc, pinProps?: PinProps) {
-        //add this new doc to props.Document
+    public static PinDoc(docs: Doc|Doc[], pinProps?: PinProps) {
+        const docList = ((docs instanceof Doc) ? [docs]: docs);
+        const batch = UndoManager.StartBatch("pinning doc");
 
         // all docs will be added to the ActivePresentation as stored on CurrentUserUtils
         const curPres = CurrentUserUtils.ActivePresentation;
-        if (curPres) {
+        curPres && docList.forEach(doc => {
             // Edge Case 1: Cannot pin document to itself
             if (doc === curPres) { alert("Cannot pin presentation document to itself"); return; }
-            const batch = UndoManager.StartBatch("pinning doc");
             const pinDoc = Doc.MakeAlias(doc);
             pinDoc.presentationTargetDoc = doc;
             pinDoc.title = doc.title + " - Slide";
@@ -279,17 +279,16 @@ export class TabDocView extends React.Component<TabDocViewProps> {
                 pinDoc.presMovement = PresMovement.None;
             }
             if (curPres.expandBoolean) pinDoc.presExpandInlineButton = true;
-            if (!Array.from(CollectionDockingView.Instance.tabMap).map(d => d.DashDoc).includes(curPres)) {
-                const docs = Cast(Cast(Doc.UserDoc().myOverlayDocs, Doc, null).data, listSpec(Doc), []);
-                if (docs.includes(curPres)) docs.splice(docs.indexOf(curPres), 1);
-                CollectionDockingView.AddSplit(curPres, "right");
-                setTimeout(() => DocumentManager.Instance.jumpToDocument(doc, false, undefined, []), 100); // keeps the pinned doc in view since the sidebar shifts things
-            }
             PresBox.Instance?._selectedArray.clear();
             pinDoc && PresBox.Instance?._selectedArray.set(pinDoc, undefined); //Update selected array
-            setTimeout(batch.end, 500); // need to wait until dockingview (goldenlayout) updates all its structurs
-            return pinDoc;
+        });
+        if (!Array.from(CollectionDockingView.Instance.tabMap).map(d => d.DashDoc).includes(curPres)) {
+            const docs = Cast(Cast(Doc.UserDoc().myOverlayDocs, Doc, null).data, listSpec(Doc), []);
+            if (docs.includes(curPres)) docs.splice(docs.indexOf(curPres), 1);
+            CollectionDockingView.AddSplit(curPres, "right");
+            setTimeout(() => DocumentManager.Instance.jumpToDocument(docList.lastElement(), false, undefined, []), 100); // keeps the pinned doc in view since the sidebar shifts things
         }
+        setTimeout(batch.end, 500); // need to wait until dockingview (goldenlayout) updates all its structurs
     }
 
     componentDidMount() {
@@ -572,7 +571,7 @@ export class TabMinimapView extends React.Component<TabMinimapViewProps> {
                     docFilters={CollectionDockingView.Instance.childDocFilters}
                     docRangeFilters={CollectionDockingView.Instance.childDocRangeFilters}
                     searchFilterDocs={CollectionDockingView.Instance.searchFilterDocs}
-                    fitContentsToDoc={returnTrue}
+                    fitContentsToBox={returnTrue}
                 />
                 <div className="miniOverlay" onPointerDown={this.miniDown} >
                     <div className="miniThumb" style={{ width: `${miniWidth}% `, height: `${miniHeight}% `, left: `${miniLeft}% `, top: `${miniTop}% `, }} />
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 09f05f69a..8824750a3 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -796,7 +796,7 @@ export class TreeView extends React.Component<TreeViewProps> {
             isDocumentActive={isActive}
             styleProvider={asText ? this.titleStyleProvider : this.embeddedStyleProvider}
             hideTitle={asText}
-            fitContentsToDoc={returnTrue}
+            fitContentsToBox={returnTrue}
             hideDecorationTitle={this.props.treeView.outlineMode}
             hideResizeHandles={this.props.treeView.outlineMode}
             onClick={this.onChildClick}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index b70e6ff98..ec3cf1fe8 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -9,7 +9,7 @@ import { InkData, InkField, InkTool, PointData, Segment } from "../../../../fiel
 import { List } from "../../../../fields/List";
 import { ObjectField } from "../../../../fields/ObjectField";
 import { RichTextField } from "../../../../fields/RichTextField";
-import { createSchema, listSpec } from "../../../../fields/Schema";
+import { listSpec } from "../../../../fields/Schema";
 import { ScriptField } from "../../../../fields/ScriptField";
 import { BoolCast, Cast, FieldValue, NumCast, ScriptCast, StrCast } from "../../../../fields/Types";
 import { ImageField } from "../../../../fields/URLField";
@@ -41,6 +41,7 @@ import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveIn
 import { LightboxView } from "../../LightboxView";
 import { CollectionFreeFormDocumentView } from "../../nodes/CollectionFreeFormDocumentView";
 import { DocFocusOptions, DocumentView, DocumentViewProps, ViewAdjustment, ViewSpecPrefix } from "../../nodes/DocumentView";
+import { FieldViewProps } from "../../nodes/FieldView";
 import { FormattedTextBox } from "../../nodes/formattedText/FormattedTextBox";
 import { PresBox } from "../../nodes/trails/PresBox";
 import { VideoBox } from "../../nodes/VideoBox";
@@ -50,27 +51,13 @@ import { CollectionDockingView } from "../CollectionDockingView";
 import { CollectionSubView } from "../CollectionSubView";
 import { TreeViewType } from "../CollectionTreeView";
 import { CollectionViewType } from "../CollectionView";
+import { TabDocView } from "../TabDocView";
 import { computePivotLayout, computerPassLayout, computerStarburstLayout, computeTimelineLayout, PoolData, ViewDefBounds, ViewDefResult } from "./CollectionFreeFormLayoutEngines";
 import { CollectionFreeFormRemoteCursors } from "./CollectionFreeFormRemoteCursors";
 import "./CollectionFreeFormView.scss";
 import { MarqueeView } from "./MarqueeView";
 import React = require("react");
-import { FieldView, FieldViewProps } from "../../nodes/FieldView";
-import { TabDocView } from "../TabDocView";
 
-export const panZoomSchema = createSchema({
-    _panX: "number",
-    _panY: "number",
-    _currentTimecode: "number",
-    _timecodeToShow: "number",
-    _currentFrame: "number",
-    _useClusters: "boolean",
-    _viewTransition: "string",
-    _xPadding: "number",         // pixels of padding on left/right of collectionfreeformview contents when fitToBox is set
-    _yPadding: "number",         // pixels of padding on left/right of collectionfreeformview contents when fitToBox is set
-    _fitToBox: "boolean",
-    scrollHeight: "number"    // this will be set when the collection is an annotation overlay for a PDF/Webpage
-});
 
 export type collectionFreeformViewProps = {
     annotationLayerHostsContent?: boolean; // whether to force scaling of content (needed by ImageBox)
@@ -138,20 +125,20 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                     this.props.PanelWidth() / (this.contentBounds.r - this.contentBounds.x))
         };
     }
-    @computed get fitToContent() { return (this.props.fitContentsToDoc?.() || this.Document._fitToBox) && !this.isAnnotationOverlay; }
+    @computed get fitContentsToBox() { return (this.props.fitContentsToBox?.() || this.Document._fitContentsToBox) && !this.isAnnotationOverlay; }
     @computed get contentBounds() { 
         const cb = Cast(this.rootDoc.contentBounds, listSpec("number"));
         return cb ? {x:cb[0], y:cb[1], r:cb[2], b: cb[3]} : 
             this.props.contentBounds?.() ?? aggregateBounds(this._layoutElements.filter(e => e.bounds && !e.bounds.z).map(e => e.bounds!), NumCast(this.layoutDoc._xPadding, 10), NumCast(this.layoutDoc._yPadding, 10)); 
     }
-    @computed get nativeWidth() { return this.fitToContent ? 0 : Doc.NativeWidth(this.Document); }
-    @computed get nativeHeight() { return this.fitToContent ? 0 : Doc.NativeHeight(this.Document); }
+    @computed get nativeWidth() { return this.fitContentsToBox ? 0 : Doc.NativeWidth(this.Document); }
+    @computed get nativeHeight() { return this.fitContentsToBox ? 0 : Doc.NativeHeight(this.Document); }
     @computed get cachedCenteringShiftX(): number {
-        const scaling = this.fitToContent || !this.contentScaling ? 1 : this.contentScaling;
+        const scaling = this.fitContentsToBox || !this.contentScaling ? 1 : this.contentScaling;
         return this.props.isAnnotationOverlay ? 0 : this.props.PanelWidth() / 2 / scaling;  // shift so pan position is at center of window for non-overlay collections
     }
     @computed get cachedCenteringShiftY(): number {
-        const scaling = this.fitToContent || !this.contentScaling ? 1 : this.contentScaling;
+        const scaling = this.fitContentsToBox || !this.contentScaling ? 1 : this.contentScaling;
         return this.props.isAnnotationOverlay ? 0 : this.props.PanelHeight() / 2 / scaling;// shift so pan position is at center of window for non-overlay collections
     }
     @computed get cachedGetLocalTransform(): Transform {
@@ -176,8 +163,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         this.layoutDoc._panY = vals.bounds.cy;
         this.layoutDoc._viewScale = vals.scale;
     }
-    freeformData = (force?: boolean) => !this._firstRender && (this.fitToContent || force) ? this.fitToContentVals : undefined;
-    reverseNativeScaling = () => this.fitToContent ? true : false;
+    freeformData = (force?: boolean) => !this._firstRender && (this.fitContentsToBox || force) ? this.fitToContentVals : undefined;
+    reverseNativeScaling = () => this.fitContentsToBox ? true : false;
     panX = () => this.freeformData()?.bounds.cx ?? NumCast(this.Document._panX);
     panY = () => this.freeformData()?.bounds.cy ?? NumCast(this.Document._panY);
     zoomScaling = () => (this.freeformData()?.scale ?? NumCast(this.Document[this.scaleFieldKey], 1));
@@ -1272,7 +1259,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             dontRegisterView={this.props.dontRenderDocuments || this.props.dontRegisterView}
             pointerEvents={this.pointerEvents}
             jitterRotation={this.props.styleProvider?.(childLayout, this.props, StyleProp.JitterRotation) || 0}
-        //fitToBox={this.props.fitToBox || BoolCast(this.props.freezeChildDimensions)} // bcz: check this
+        //fitContentsToBox={this.props.fitContentsToBox || BoolCast(this.props.freezeChildDimensions)} // bcz: check this
         />;
     }
     addDocTab = action((doc: Doc, where: string) => {
@@ -1616,7 +1603,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         const appearanceItems = appearance && "subitems" in appearance ? appearance.subitems : [];
         appearanceItems.push({ description: "Reset View", event: () => { this.props.Document._panX = this.props.Document._panY = 0; this.props.Document[this.scaleFieldKey] = 1; }, icon: "compress-arrows-alt" });
         !Doc.UserDoc().noviceMode && Doc.UserDoc().defaultTextLayout && appearanceItems.push({ description: "Reset default note style", event: () => Doc.UserDoc().defaultTextLayout = undefined, icon: "eye" });
-        appearanceItems.push({ description: `${this.fitToContent ? "Make Zoomable" : "Scale to Window"}`, event: () => this.Document._fitToBox = !this.fitToContent, icon: !this.fitToContent ? "expand-arrows-alt" : "compress-arrows-alt" });
+        appearanceItems.push({ description: `${this.fitContentsToBox ? "Make Zoomable" : "Scale to Window"}`, event: () => this.Document._fitContentsToBox = !this.fitContentsToBox, icon: !this.fitContentsToBox ? "expand-arrows-alt" : "compress-arrows-alt" });
         appearanceItems.push({ description: `Pin View`, event: () => TabDocView.PinDoc(this.rootDoc, {pinDocView:true, panelWidth: this.props.PanelWidth(), panelHeight:this.props.PanelHeight()}), icon: "map-pin" });
         //appearanceItems.push({ description: `update icon`, event: this.updateIcon, icon: "compress-arrows-alt" });
         this.props.ContainingCollectionView &&
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 3fac3350a..6df2bb102 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -516,7 +516,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
             d.y = NumCast(d.y) - this.Bounds.top;
             return d;
         });
-        const summary = Docs.Create.TextDocument("", { _backgroundColor: "#e2ad32", x: this.Bounds.left, y: this.Bounds.top, isPushpin: true, _width: 200, _height: 200, _fitToBox: true, _showSidebar: true, title: "overview" });
+        const summary = Docs.Create.TextDocument("", { _backgroundColor: "#e2ad32", x: this.Bounds.left, y: this.Bounds.top, isPushpin: true, _width: 200, _height: 200, _fitContentsToBox: true, _showSidebar: true, title: "overview" });
         const portal = Docs.Create.FreeformDocument(selected, { x: this.Bounds.left + 200, y: this.Bounds.top, isGroup: true, backgroundColor: "transparent" });
         DocUtils.MakeLink({ doc: summary }, { doc: portal }, "summary of:summarized by", "");
 
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
index e2dfb25e2..7147ae485 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
@@ -257,7 +257,7 @@ export class CollectionMulticolumnView extends CollectionSubView() {
             isDocumentActive={this.props.childDocumentsActive?.() ? this.props.isDocumentActive : this.isContentActive}
             hideResizeHandles={this.props.childHideResizeHandles?.()}
             hideDecorationTitle={this.props.childHideDecorationTitle?.()}
-            fitContentsToDoc={this.props.fitContentsToDoc}
+            fitContentsToBox={this.props.fitContentsToBox}
             PanelWidth={width}
             PanelHeight={height}
             rootSelected={this.rootSelected}
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
index 3010e36aa..3bda56c33 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
@@ -264,7 +264,7 @@ export class CollectionMultirowView extends CollectionSubView() {
             isDocumentActive={this.props.childDocumentsActive?.() ? this.props.isDocumentActive : this.isContentActive}
             hideResizeHandles={this.props.childHideResizeHandles?.()}
             hideDecorationTitle={this.props.childHideDecorationTitle?.()}
-            fitContentsToDoc={this.props.fitContentsToDoc}
+            fitContentsToBox={this.props.fitContentsToBox}
             focus={this.props.focus}
             docFilters={this.childDocFilters}
             docRangeFilters={this.childDocRangeFilters}
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
index b731479a5..f45068b6a 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
@@ -402,7 +402,7 @@ export class CollectionSchemaView extends CollectionSubView() {
                 <DocumentView
                     Document={this.previewDocument}
                     DataDoc={undefined}
-                    fitContentsToDoc={returnTrue}
+                    fitContentsToBox={returnTrue}
                     freezeDimensions={true}
                     dontCenter={"y"}
                     focus={DocUtils.DefaultFocus}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 26dec3bd5..2a518bb57 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -85,7 +85,7 @@ export interface DocComponentView {
     getAnchor?: () => 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)
     scrollFocus?: (doc: Doc, smooth: boolean) => Opt<number>; // returns the duration of the focus
     setViewSpec?: (anchor: Doc, preview: boolean) => void;  // sets viewing information for a componentview, typically when following a link. 'preview' tells the view to use the values without writing to the document
-    reverseNativeScaling?: () => boolean; // DocumentView's setup screenToLocal based on the doc having a nativeWidth/Height.  However, some content views (e.g., FreeFormView w/ fitToBox set) may ignore the native dimensions so this flags the DocumentView to not do Nativre scaling.
+    reverseNativeScaling?: () => 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.
     shrinkWrap?: () => void;  // requests a document to display all of its contents with no white space.  currently only implemented (needed?) for freeform views
     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
@@ -113,7 +113,7 @@ export interface DocumentViewSharedProps {
     Document: Doc;
     DataDoc?: Doc;
     contentBounds?: () => (undefined|{x:number, y:number, r:number, b:number});
-    fitContentsToDoc?: () => boolean; // used by freeformview to fit its contents to its panel. corresponds to _fitToBox property on a Document
+    fitContentsToBox?: () => boolean; // used by freeformview to fit its contents to its panel. corresponds to _fitContentsToBox property on a Document
     ContainingCollectionView: Opt<CollectionView>;
     ContainingCollectionDoc: Opt<Doc>;
     suppressSetHeight?: boolean;
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index 9f1c019fe..5f4c17ee6 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -259,7 +259,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
 
             if (this._loadPending && this._map.getBounds()) {
                 this._loadPending = false;
-                this.layoutDoc.fitToBox && this.fitBounds(this._map);
+                this.layoutDoc.fitContentsToBox && this.fitBounds(this._map);
             }
         }, 250);
         // listener to addmarker event
@@ -274,7 +274,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
     centered = () => {
         if (this._loadPending && this._map.getBounds()) {
             this._loadPending = false;
-            this.layoutDoc.fitToBox && this.fitBounds(this._map);
+            this.layoutDoc.fitContentsToBox && this.fitBounds(this._map);
         }
         this.dataDoc.mapLat = this._map.getCenter()?.lat();
         this.dataDoc.mapLng = this._map.getCenter()?.lng();
@@ -284,7 +284,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
     zoomChanged = () => {
         if (this._loadPending && this._map.getBounds()) {
             this._loadPending = false;
-            this.layoutDoc.fitToBox && this.fitBounds(this._map);
+            this.layoutDoc.fitContentsToBox && this.fitBounds(this._map);
         }
         this.dataDoc.mapZoom = this._map.getZoom();
     }
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 7d0302b26..4e431e7bd 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -495,7 +495,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                 // embed document when dragg marked as embed
             } else if (de.embedKey) {
                 const target = dragData.droppedDocuments[0];
-                target._fitToBox = true;
+                target._fitContentsToBox = true;
                 const node = schema.nodes.dashDoc.create({
                     width: target[WidthSym](),
                     height: target[HeightSym](),
@@ -1557,7 +1557,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
             }
         }
     }
-    fitToBox = () => this.props.Document._fitToBox;
+    fitContentsToBox = () => this.props.Document._fitContentsToBox;
     sidebarContentScaling = () => (this.props.scaling?.() || 1) * NumCast(this.layoutDoc._viewScale, 1);
     sidebarAddDocument = (doc: Doc | Doc[], sidebarKey?: string) => {
         if (!this.layoutDoc._showSidebar) this.toggleSidebar();
@@ -1632,7 +1632,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                     ScreenToLocalTransform={this.sidebarScreenToLocal}
                     renderDepth={this.props.renderDepth + 1}
                     setHeight={this.setSidebarHeight}
-                    fitContentsToDoc={this.fitToBox}
+                    fitContentsToBox={this.fitContentsToBox}
                     noSidebar={true}
                     fieldKey={this.layoutDoc.sidebarViewType === "translation" ? `${this.fieldKey}-translation` : `${this.fieldKey}-annotations`} />;
         };
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 6de04bd31..cebf9487a 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -35,8 +35,8 @@ export interface PinProps {
     setPosition?: boolean;
     hidePresBox?: boolean;
     pinWithView?: PinViewProps;
-    pinDocView?: boolean;
-    panelWidth?: number;
+    pinDocView?: boolean;  // whether the current view specs of the document should be saved the pinned document
+    panelWidth?: number;  // panel width and height of the document (used to compute the bounds of the pinned view area)
     panelHeight?: number
 }
 
@@ -997,7 +997,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     /**
      * Method called for viewing paths which adds a single line with
      * points at the center of each document added.
-     * Design choice: When this is called it sets _fitToBox as true so the
+     * Design choice: When this is called it sets _fitContentsToBox as true so the
      * user can have an overview of all of the documents in the collection.
      * (Design needed for when documents in presentation trail are in another
      * collection)
@@ -1800,16 +1800,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 doc = Docs.Create.FreeformDocument([], { title: input ? input : "Blank slide", _width: 400, _height: 225, x: x, y: y });
                 break;
             case 'title':
-                doc = Docs.Create.FreeformDocument([title, subtitle], { title: input ? input : "Title slide", _width: 400, _height: 225, _fitToBox: true, x: x, y: y });
+                doc = Docs.Create.FreeformDocument([title, subtitle], { title: input ? input : "Title slide", _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y });
                 break;
             case 'header':
-                doc = Docs.Create.FreeformDocument([header], { title: input ? input : "Section header", _width: 400, _height: 225, _fitToBox: true, x: x, y: y });
+                doc = Docs.Create.FreeformDocument([header], { title: input ? input : "Section header", _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y });
                 break;
             case 'content':
-                doc = Docs.Create.FreeformDocument([contentTitle, content], { title: input ? input : "Title and content", _width: 400, _height: 225, _fitToBox: true, x: x, y: y });
+                doc = Docs.Create.FreeformDocument([contentTitle, content], { title: input ? input : "Title and content", _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y });
                 break;
             case 'twoColumns':
-                doc = Docs.Create.FreeformDocument([contentTitle, content1, content2], { title: input ? input : "Title and two columns", _width: 400, _height: 225, _fitToBox: true, x: x, y: y });
+                doc = Docs.Create.FreeformDocument([contentTitle, content1, content2], { title: input ? input : "Title and two columns", _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y });
                 break;
             default:
                 break;
diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx
index 5eff47a86..ba0193e4b 100644
--- a/src/client/views/nodes/trails/PresElementBox.tsx
+++ b/src/client/views/nodes/trails/PresElementBox.tsx
@@ -85,7 +85,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
                     isContentActive={this.props.isContentActive}
                     addDocTab={returnFalse}
                     pinToPres={returnFalse}
-                    fitContentsToDoc={returnTrue}
+                    fitContentsToBox={returnTrue}
                     PanelWidth={this.embedWidth}
                     PanelHeight={this.embedHeight}
                     ScreenToLocalTransform={Transform.Identity}
diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts
index e532becb5..be39e0709 100644
--- a/src/fields/documentSchemas.ts
+++ b/src/fields/documentSchemas.ts
@@ -36,8 +36,8 @@ export const documentSchema = createSchema({
     _nativeHeight: "number",    // "
     _width: "number",           // width of document in its container's coordinate system
     _height: "number",          // "
-    _xPadding: "number",        // pixels of padding on left/right of collectionfreeformview contents when fitToBox is set
-    _yPadding: "number",        // pixels of padding on top/bottom of collectionfreeformview contents when fitToBox is set
+    _xPadding: "number",        // pixels of padding on left/right of collectionfreeformview contents when fitContentsToBox is set
+    _yPadding: "number",        // pixels of padding on top/bottom of collectionfreeformview contents when fitContentsToBox is set
     _xMargin: "number",         // margin added on left/right of most documents to add separation from their container
     _yMargin: "number",         // margin added on top/bottom of most documents to add separation from their container
     _overflow: "string",        // sets overflow behvavior for CollectionFreeForm views
@@ -59,7 +59,7 @@ export const documentSchema = createSchema({
     borderRounding: "string",   // border radius rounding of document
     boxShadow: "string",        // the amount of shadow around the perimeter of a document
     color: "string",            // foreground color of document
-    fitToBox: "boolean",        // whether freeform view contents should be zoomed/panned to fill the area of the document view
+    fitContentsToBox: "boolean",// whether freeform view contents should be zoomed/panned to fill the area of the document view box
     fontSize: "string",
     hidden: "boolean",          // whether a document should not be displayed
     isInkMask: "boolean",       // is the document a mask (ie, sits on top of other documents, has an unbounded width/height that is dark, and content uses 'hard-light' mix-blend-mode to let other documents pop through)
diff --git a/src/mobile/AudioUpload.tsx b/src/mobile/AudioUpload.tsx
index 418464f0e..64baa351c 100644
--- a/src/mobile/AudioUpload.tsx
+++ b/src/mobile/AudioUpload.tsx
@@ -19,7 +19,7 @@ import React = require('react');
 
 @observer
 export class AudioUpload extends React.Component {
-    @observable public _audioCol: Doc = FieldValue(Cast(Docs.Create.FreeformDocument([Cast(Docs.Create.AudioDocument(nullAudio, { title: "mobile audio", _width: 500, _height: 100 }), Doc) as Doc], { title: "mobile audio", _width: 300, _height: 300, _fitToBox: true, boxShadow: "0 0" }), Doc)) as Doc;
+    @observable public _audioCol: Doc = FieldValue(Cast(Docs.Create.FreeformDocument([Cast(Docs.Create.AudioDocument(nullAudio, { title: "mobile audio", _width: 500, _height: 100 }), Doc) as Doc], { title: "mobile audio", _width: 300, _height: 300, _fitContentsToBox: true, boxShadow: "0 0" }), Doc)) as Doc;
 
     /**
      * Handles the onclick functionality for the 'Restart' button
@@ -36,7 +36,7 @@ export class AudioUpload extends React.Component {
                     title: "mobile audio",
                     _width: 500,
                     _height: 100
-                }), Doc) as Doc], { title: "mobile audio", _width: 300, _height: 300, _fitToBox: true, boxShadow: "0 0" }), Doc)) as Doc;
+                }), Doc) as Doc], { title: "mobile audio", _width: 300, _height: 300, _fitContentsToBox: true, boxShadow: "0 0" }), Doc)) as Doc;
     }
 
     /** 
-- 
cgit v1.2.3-70-g09d2

