From 2ae91501a3195da9dcbc02e180b108983cd1d8af Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sun, 16 Feb 2020 21:47:28 -0500
Subject: got rid of unneeded ignoreAspect field.   other cleanup.

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

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

diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index e1c5fd27f..a2aec699f 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -52,7 +52,7 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
         this._initialScale = this.props.ScreenToLocalTransform().Scale;
         const nw = this.Document._nativeWidth = NumCast(this.dataDoc[this.props.fieldKey + "-nativeWidth"], NumCast(this.Document._nativeWidth, 927));
         const nh = this.Document._nativeHeight = NumCast(this.dataDoc[this.props.fieldKey + "-nativeHeight"], NumCast(this.Document._nativeHeight, 1200));
-        !this.Document._fitWidth && !this.Document.ignoreAspect && (this.Document._height = this.Document[WidthSym]() * (nh / nw));
+        !this.Document._fitWidth && (this.Document._height = this.Document[WidthSym]() * (nh / nw));
 
         const backup = "oldPath";
         const { Document } = this.props;
@@ -93,7 +93,7 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
         this.dataDoc[this.props.fieldKey + "-numPages"] = np;
         this.dataDoc[this.props.fieldKey + "-nativeWidth"] = this.Document._nativeWidth = nw * 96 / 72;
         this.dataDoc[this.props.fieldKey + "-nativeHeight"] = this.Document._nativeHeight = nh * 96 / 72;
-        !this.Document._fitWidth && !this.Document.ignoreAspect && (this.Document._height = this.Document[WidthSym]() * (nh / nw));
+        !this.Document._fitWidth && (this.Document._height = this.Document[WidthSym]() * (nh / nw));
     }
 
     public search(string: string, fwd: boolean) { this._pdfViewer && this._pdfViewer.search(string, fwd); }
-- 
cgit v1.2.3-70-g09d2


From ba9351bc009b6f78ca9815b481bc5643f8af96e0 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sun, 16 Feb 2020 22:59:36 -0500
Subject: fixed warnings

---
 src/Utils.ts                                       |  4 +-
 src/client/util/RichTextRules.ts                   |  2 +-
 src/client/views/DocumentButtonBar.tsx             |  1 -
 src/client/views/DocumentDecorations.tsx           |  2 +-
 .../views/collections/CollectionDockingView.tsx    |  2 +-
 .../views/collections/CollectionSchemaHeaders.tsx  |  4 +-
 .../views/collections/CollectionViewChromes.tsx    |  2 +-
 .../CollectionFreeFormLayoutEngines.tsx            | 38 ++++++------
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  2 +-
 .../caption_toggle/DetailedCaptionToggle.tsx       | 72 ----------------------
 .../document_templates/image_card/ImageCard.tsx    | 15 -----
 .../views/nodes/ContentFittingDocumentView.tsx     |  2 +-
 src/client/views/nodes/DocumentView.tsx            |  2 +-
 src/client/views/nodes/FormattedTextBox.tsx        |  4 +-
 src/client/views/nodes/PDFBox.tsx                  |  2 +-
 src/client/views/pdf/PDFViewer.tsx                 |  7 +--
 src/new_fields/util.ts                             |  2 +-
 17 files changed, 38 insertions(+), 125 deletions(-)
 delete mode 100644 src/client/views/document_templates/caption_toggle/DetailedCaptionToggle.tsx
 delete mode 100644 src/client/views/document_templates/image_card/ImageCard.tsx

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

diff --git a/src/Utils.ts b/src/Utils.ts
index 6a0b3fad8..9162771aa 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -495,7 +495,7 @@ export function setupMoveUpEvents(
         (target as any)._lastX = e.clientX;
         (target as any)._lastY = e.clientY;
         e.stopPropagation();
-    }
+    };
     const _upEvent = (e: PointerEvent): void => {
         upEvent(e);
         if (Math.abs(e.clientX - (target as any)._downX) < 4 || Math.abs(e.clientY - (target as any)._downY) < 4) {
@@ -503,7 +503,7 @@ export function setupMoveUpEvents(
         }
         document.removeEventListener("pointermove", _moveEvent);
         document.removeEventListener("pointerup", _upEvent);
-    }
+    };
     e.stopPropagation();
     document.removeEventListener("pointermove", _moveEvent);
     document.removeEventListener("pointerup", _upEvent);
diff --git a/src/client/util/RichTextRules.ts b/src/client/util/RichTextRules.ts
index de0f46202..a4f1ff22c 100644
--- a/src/client/util/RichTextRules.ts
+++ b/src/client/util/RichTextRules.ts
@@ -298,5 +298,5 @@ export class RichTextRules {
                     return null;
                 }),
         ]
-    }
+    };
 }
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index ec1f879c2..5d289c5e5 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -318,7 +318,6 @@ export class DocumentButtonBar extends React.Component<{ views: (DocumentView |
         const isText = this.view0.props.Document.data instanceof RichTextField; // bcz: Todo - can't assume layout is using the 'data' field.  need to add fieldKey to DocumentView
         const considerPull = isText && this.considerGoogleDocsPull;
         const considerPush = isText && this.considerGoogleDocsPush;
-        Doc.UserDoc().pr
         return <div className="documentButtonBar">
             <div className="documentButtonBar-button">
                 {this.linkButton}
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index cc7388a61..44e8a3a48 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -109,7 +109,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                 UndoManager.RunInBatch(() => selectionTitleFieldKey && SelectionManager.SelectedDocuments().forEach(d => {
                     const value = typeof d.props.Document[selectionTitleFieldKey] === "number" ? +this._accumulatedTitle : this._accumulatedTitle;
                     didAnything = didAnything || d.props.Document[selectionTitleFieldKey] !== value;
-                    Doc.SetInPlace(d.props.Document, selectionTitleFieldKey, value, true)
+                    Doc.SetInPlace(d.props.Document, selectionTitleFieldKey, value, true);
                 }), "title blur");
                 if (!didAnything) UndoManager.Undo();
             }
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index bf0333d55..902016365 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -434,7 +434,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
                 tab.titleElement[0].onchange = (e: any) => {
                     tab.titleElement[0].size = e.currentTarget.value.length + 1;
                     Doc.SetInPlace(doc, "title", e.currentTarget.value, true);
-                }
+                };
                 tab.titleElement[0].size = StrCast(doc.title).length + 1;
                 tab.titleElement[0].value = doc.title;
                 const gearSpan = document.createElement("span");
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index 92dc8780e..c585506b3 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -5,11 +5,13 @@ import "./CollectionSchemaView.scss";
 import { faPlus, faFont, faHashtag, faAlignJustify, faCheckSquare, faToggleOn, faSortAmountDown, faSortAmountUp, faTimes } from '@fortawesome/free-solid-svg-icons';
 import { library, IconProp } from "@fortawesome/fontawesome-svg-core";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { Flyout, anchorPoints } from "../DocumentDecorations";
 import { ColumnType } from "./CollectionSchemaView";
 import { faFile } from "@fortawesome/free-regular-svg-icons";
 import { SchemaHeaderField, PastelSchemaPalette } from "../../../new_fields/SchemaHeaderField";
 import { undoBatch } from "../../util/UndoManager";
+const higflyout = require("@hig/flyout");
+export const { anchorPoints } = higflyout;
+export const Flyout = higflyout.default;
 
 library.add(faPlus, faFont, faHashtag, faAlignJustify, faCheckSquare, faToggleOn, faFile as any, faSortAmountDown, faSortAmountUp, faTimes);
 
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index a21e78188..0378c818c 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -179,7 +179,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
     @action closeViewSpecs = () => {
         this._viewSpecsOpen = false;
         document.removeEventListener("pointerdown", this.closeViewSpecs);
-    };
+    }
 
     @action
     openDatePicker = (e: React.PointerEvent) => {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index 671a3e0c4..8132d2f7c 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -27,15 +27,15 @@ export interface ViewDefBounds {
 }
 
 export interface PoolData {
-    x?: number,
-    y?: number,
-    z?: number,
-    zIndex?: number,
-    width?: number,
-    height?: number,
-    color?: string,
-    transition?: string,
-    highlight?: boolean,
+    x?: number;
+    y?: number;
+    z?: number;
+    zIndex?: number;
+    width?: number;
+    height?: number;
+    color?: string;
+    transition?: string;
+    highlight?: boolean;
 }
 
 export interface ViewDefResult {
@@ -63,16 +63,16 @@ function toLabel(target: FieldResult<Field>) {
  */
 function getTextWidth(text: string, font: string): number {
     // re-use canvas object for better performance
-    var canvas = (getTextWidth as any).canvas || ((getTextWidth as any).canvas = document.createElement("canvas"));
-    var context = canvas.getContext("2d");
+    const canvas = (getTextWidth as any).canvas || ((getTextWidth as any).canvas = document.createElement("canvas"));
+    const context = canvas.getContext("2d");
     context.font = font;
-    var metrics = context.measureText(text);
+    const metrics = context.measureText(text);
     return metrics.width;
 }
 
-interface pivotColumn {
-    docs: Doc[],
-    filters: string[]
+interface PivotColumn {
+    docs: Doc[];
+    filters: string[];
 }
 
 
@@ -86,7 +86,7 @@ export function computePivotLayout(
     viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[]
 ) {
     const fieldKey = "data";
-    const pivotColumnGroups = new Map<FieldResult<Field>, pivotColumn>();
+    const pivotColumnGroups = new Map<FieldResult<Field>, PivotColumn>();
 
     const pivotFieldKey = toLabel(pivotDoc._pivotField);
     for (const doc of filterDocs) {
@@ -123,7 +123,7 @@ export function computePivotLayout(
     const desc = `${fontSize}px ${getComputedStyle(document.body).fontFamily}`;
     const textlen = Array.from(pivotColumnGroups.keys()).map(c => getTextWidth(toLabel(c), desc)).reduce((p, c) => Math.max(p, c), 0 as number);
     const max_text = Math.min(Math.ceil(textlen / 120) * 28, panelDim[1] / 2);
-    let maxInColumn = Array.from(pivotColumnGroups.values()).reduce((p, s) => Math.max(p, s.docs.length), 1);
+    const maxInColumn = Array.from(pivotColumnGroups.values()).reduce((p, s) => Math.max(p, s.docs.length), 1);
 
     const colWidth = panelDim[0] / pivotColumnGroups.size;
     const colHeight = panelDim[1] - max_text;
@@ -223,7 +223,7 @@ export function computeTimelineLayout(
     const findStack = (time: number, stack: number[]) => {
         const index = stack.findIndex(val => val === undefined || val < x);
         return index === -1 ? stack.length : index;
-    }
+    };
 
     let minTime = minTimeReq === undefined ? Number.MAX_VALUE : minTimeReq;
     let maxTime = maxTimeReq === undefined ? -Number.MAX_VALUE : maxTimeReq;
@@ -266,7 +266,7 @@ export function computeTimelineLayout(
     }
 
     const pivotAxisWidth = NumCast(pivotDoc.pivotTimeWidth, panelDim[1] / 2.5);
-    let stacking: number[] = [];
+    const stacking: number[] = [];
     let zind = 0;
     sortedKeys.forEach(key => {
         if (curTime !== undefined && curTime > prevKey && curTime <= key) {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 427a8d9fe..60410544b 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -856,7 +856,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         });
         return rangeFilteredDocs;
     }
-    childLayoutDocFunc = () => this.props.childLayoutTemplate?.() || Cast(this.props.Document.childLayoutTemplate, Doc, null) as Doc;
+    childLayoutDocFunc = () => this.props.childLayoutTemplate?.() || Cast(this.props.Document.childLayoutTemplate, Doc, null);
     get doLayoutComputation() {
         const { newPool, computedElementData } = this.doInternalLayoutComputation;
         runInAction(() =>
diff --git a/src/client/views/document_templates/caption_toggle/DetailedCaptionToggle.tsx b/src/client/views/document_templates/caption_toggle/DetailedCaptionToggle.tsx
deleted file mode 100644
index 3aaf4120c..000000000
--- a/src/client/views/document_templates/caption_toggle/DetailedCaptionToggle.tsx
+++ /dev/null
@@ -1,72 +0,0 @@
-import * as React from 'react';
-import { FontStyleProperty, ColorProperty } from 'csstype';
-import { observer } from 'mobx-react';
-import { observable, action, runInAction } from 'mobx';
-import { FormattedTextBox } from '../../nodes/FormattedTextBox';
-import { FieldViewProps } from '../../nodes/FieldView';
-
-interface DetailedCaptionDataProps {
-    captionFieldKey?: string;
-    detailsFieldKey?: string;
-}
-
-interface DetailedCaptionStylingProps {
-    sharedFontColor?: ColorProperty;
-    captionFontStyle?: FontStyleProperty;
-    detailsFontStyle?: FontStyleProperty;
-    toggleSize?: number;
-}
-
-@observer
-export default class DetailedCaptionToggle extends React.Component<DetailedCaptionDataProps & DetailedCaptionStylingProps & FieldViewProps> {
-    @observable loaded: boolean = false;
-    @observable detailsExpanded: boolean = false;
-
-    @action toggleDetails = (e: React.MouseEvent<HTMLDivElement>) => {
-        e.preventDefault();
-        e.stopPropagation();
-        this.detailsExpanded = !this.detailsExpanded;
-    }
-
-    componentDidMount() {
-        runInAction(() => this.loaded = true);
-    }
-
-    render() {
-        const size = this.props.toggleSize || 20;
-        return (
-            <div style={{
-                transition: "0.5s opacity ease",
-                opacity: this.loaded ? 1 : 0,
-                bottom: 0,
-                fontSize: 14,
-                width: "100%",
-                position: "absolute"
-            }}>
-                {/* caption */}
-                <div style={{ opacity: this.detailsExpanded ? 0 : 1, transition: "opacity 0.3s ease" }}>
-                    <FormattedTextBox {...this.props} fieldKey={this.props.captionFieldKey || "caption"} />
-                </div>
-                {/* details */}
-                <div style={{ opacity: this.detailsExpanded ? 1 : 0, transition: "opacity 0.3s ease" }}>
-                    <FormattedTextBox {...this.props} fieldKey={this.props.detailsFieldKey || "captiondetails"} />
-                </div>
-                {/* toggle */}
-                <div
-                    style={{
-                        width: size,
-                        height: size,
-                        borderRadius: "50%",
-                        backgroundColor: "red",
-                        zIndex: 3,
-                        cursor: "pointer"
-                    }}
-                    onClick={this.toggleDetails}
-                >
-                    <span style={{ color: "white" }}></span>
-                </div>
-            </div>
-        );
-    }
-
-}
diff --git a/src/client/views/document_templates/image_card/ImageCard.tsx b/src/client/views/document_templates/image_card/ImageCard.tsx
deleted file mode 100644
index 868afc423..000000000
--- a/src/client/views/document_templates/image_card/ImageCard.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import * as React from 'react';
-import { FieldViewProps } from '../../nodes/FieldView';
-import { ImageBox } from '../../nodes/ImageBox';
-
-export default class ImageCard extends React.Component<FieldViewProps> {
-
-    render() {
-        return (
-            <div style={{ padding: 30, borderRadius: 15 }}>
-                <ImageBox {...this.props} />
-            </div>
-        );
-    }
-
-}
\ No newline at end of file
diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx
index 387da88f5..73fe4fb5d 100644
--- a/src/client/views/nodes/ContentFittingDocumentView.tsx
+++ b/src/client/views/nodes/ContentFittingDocumentView.tsx
@@ -55,7 +55,7 @@ export class ContentFittingDocumentView extends React.Component<ContentFittingDo
     private contentScaling = () => this.scaling;
 
     private PanelWidth = () => this.panelWidth;
-    private PanelHeight = () => this.panelHeight;;
+    private PanelHeight = () => this.panelHeight;
 
     @computed get panelWidth() { return this.nativeWidth && (!this.props.Document || !this.props.Document._fitWidth) ? this.nativeWidth * this.contentScaling() : this.props.PanelWidth(); }
     @computed get panelHeight() { return this.nativeHeight && (!this.props.Document || !this.props.Document._fitWidth) ? this.nativeHeight * this.contentScaling() : this.props.PanelHeight(); }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 330410a92..704da3c74 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -271,7 +271,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             }
             preventDefault && e.preventDefault();
         }
-    };
+    }
 
     buttonClick = async (altKey: boolean, ctrlKey: boolean) => {
         const linkDocs = DocListCast(this.props.Document.links);
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 30be64040..c2f1c9ac7 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -369,7 +369,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
 
     specificContextMenu = (e: React.MouseEvent): void => {
         const funcs: ContextMenuProps[] = [];
-        funcs.push({ description: "Toggle Sidebar", event: () => { e.stopPropagation(); this.props.Document._showSidebar = !this.props.Document._showSidebar }, icon: "expand-arrows-alt" });
+        funcs.push({ description: "Toggle Sidebar", event: () => { e.stopPropagation(); this.props.Document._showSidebar = !this.props.Document._showSidebar; }, icon: "expand-arrows-alt" });
         funcs.push({ description: "Record Bullet", event: () => { e.stopPropagation(); this.recordBullet(); }, icon: "expand-arrows-alt" });
         ["My Text", "Text from Others", "Todo Items", "Important Items", "Ignore Items", "Disagree Items", "By Recent Minute", "By Recent Hour"].forEach(option =>
             funcs.push({
@@ -1067,7 +1067,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
     }
 
     @computed get sidebarWidthPercent() { return StrCast(this.props.Document.sidebarWidthPercent, "0%"); }
-    sidebarWidth = () => { return Number(this.sidebarWidthPercent.substring(0, this.sidebarWidthPercent.length - 1)) / 100 * this.props.PanelWidth(); }
+    sidebarWidth = () => Number(this.sidebarWidthPercent.substring(0, this.sidebarWidthPercent.length - 1)) / 100 * this.props.PanelWidth();
     sidebarScreenToLocal = () => this.props.ScreenToLocalTransform().translate(-(this.props.PanelWidth() - this.sidebarWidth()), 0);
     @computed get sidebarColor() { return StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "transparent")); }
     render() {
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index a2aec699f..a96a26b61 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -259,7 +259,7 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
             if (!this._pdfjsRequested) {
                 this._pdfjsRequested = true;
                 const promise = Pdfjs.getDocument(pdfUrl.url.href).promise;
-                promise.then(pdf => { runInAction(() => { this._pdf = pdf; console.log("promise"); }) });
+                promise.then(action(pdf => { this._pdf = pdf; console.log("promise"); }));
 
             }
         }
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 4f50be5b0..a9b8c6bbe 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -127,9 +127,8 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
         // change the address to be the file address of the PNG version of each page
         // file address of the pdf
         const { url: { href } } = Cast(this.props.Document[this.props.fieldKey], PdfField)!;
-        this._coverPath = href.startsWith(window.location.origin) ?
-            JSON.parse(await rp.get(Utils.prepend(`/thumbnail${this.props.url.substring("files/pdfs/".length, this.props.url.length - ".pdf".length)}-${(this.Document.curPage || 1)}.png`))) :
-            { width: 100, height: 100, path: "" };
+        const addr = Utils.prepend(`/thumbnail${this.props.url.substring("files/pdfs/".length, this.props.url.length - ".pdf".length)}-${(this.Document.curPage || 1)}.png`);
+        this._coverPath = href.startsWith(window.location.origin) ? JSON.parse(await rp.get(addr)) : { width: 100, height: 100, path: "" };
         runInAction(() => this._showWaiting = this._showCover = true);
         this.props.startupLive && this.setupPdfJsViewer();
         this._searchReactionDisposer = reaction(() => this.Document.searchMatch, search => {
@@ -623,7 +622,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
         TraceMobx();
         return <div className="pdfViewer-annotationLayer" style={{ height: NumCast(this.Document.nativeHeight), transform: `scale(${this._zoomed})` }} ref={this._annotationLayer}>
             {this.nonDocAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map((anno, index) =>
-                <Annotation {...this.props} focus={this.props.focus} dataDoc={this.dataDoc!} fieldKey={this.props.fieldKey} anno={anno} key={`${anno[Id]}-annotation`} />)}
+                <Annotation {...this.props} focus={this.props.focus} dataDoc={this.dataDoc} fieldKey={this.props.fieldKey} anno={anno} key={`${anno[Id]}-annotation`} />)}
         </div>;
     }
     overlayTransform = () => this.scrollXf().scale(1 / this._zoomed);
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
index ebc0a1272..6d7f6b56e 100644
--- a/src/new_fields/util.ts
+++ b/src/new_fields/util.ts
@@ -100,7 +100,7 @@ export function makeEditable() {
     _setter = _setterImpl;
 }
 
-let layoutProps = ["panX", "panY", "width", "height", "nativeWidth", "nativeHeight", "fitWidth", "fitToBox",
+const layoutProps = ["panX", "panY", "width", "height", "nativeWidth", "nativeHeight", "fitWidth", "fitToBox",
     "LODdisable", "chromeStatus", "viewType", "gridGap", "xMargin", "yMargin", "autoHeight"];
 export function setter(target: any, in_prop: string | symbol | number, value: any, receiver: any): boolean {
     let prop = in_prop;
-- 
cgit v1.2.3-70-g09d2


From 710ff9dbfd255fc0d9a19957c8413423a6e9c65a Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Mon, 17 Feb 2020 17:29:07 -0500
Subject: fixed fwd/back pdf buttons and selection

---
 package-lock.json                  | 95 +++++++++++++++-----------------------
 src/client/views/nodes/PDFBox.scss | 22 ++++++++-
 src/client/views/nodes/PDFBox.tsx  |  8 ++--
 3 files changed, 63 insertions(+), 62 deletions(-)

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

diff --git a/package-lock.json b/package-lock.json
index 2636d7113..a09df33da 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -657,7 +657,7 @@
         },
         "@types/passport": {
             "version": "1.0.2",
-            "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.2.tgz",
+            "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.0.tgz",
             "integrity": "sha512-Pf39AYKf8q+YoONym3150cEwfUD66dtwHJWvbeOzKxnA0GZZ/vAXhNWv9vMhKyRQBQZiQyWQnhYBEBlKW6G8wg==",
             "requires": {
                 "@types/express": "*"
@@ -1997,7 +1997,7 @@
                 },
                 "util": {
                     "version": "0.10.3",
-                    "resolved": "http://registry.npmjs.org/util/-/util-0.10.3.tgz",
+                    "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
                     "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
                     "dev": true,
                     "requires": {
@@ -2585,7 +2585,7 @@
         },
         "browserify-aes": {
             "version": "1.2.0",
-            "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+            "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
             "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
             "requires": {
                 "buffer-xor": "^1.0.3",
@@ -2619,7 +2619,7 @@
         },
         "browserify-rsa": {
             "version": "4.0.1",
-            "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+            "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
             "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
             "requires": {
                 "bn.js": "^4.1.0",
@@ -2783,7 +2783,7 @@
         },
         "camelcase-keys": {
             "version": "2.1.0",
-            "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+            "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
             "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
             "requires": {
                 "camelcase": "^2.0.0",
@@ -3576,7 +3576,7 @@
         },
         "create-hash": {
             "version": "1.2.0",
-            "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+            "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
             "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
             "requires": {
                 "cipher-base": "^1.0.1",
@@ -3588,7 +3588,7 @@
         },
         "create-hmac": {
             "version": "1.1.7",
-            "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+            "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
             "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
             "requires": {
                 "cipher-base": "^1.0.3",
@@ -4126,7 +4126,7 @@
         },
         "diffie-hellman": {
             "version": "5.0.3",
-            "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+            "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
             "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
             "requires": {
                 "bn.js": "^4.1.0",
@@ -5406,8 +5406,7 @@
                 },
                 "ansi-regex": {
                     "version": "2.1.1",
-                    "bundled": true,
-                    "optional": true
+                    "bundled": true
                 },
                 "aproba": {
                     "version": "1.2.0",
@@ -5425,13 +5424,11 @@
                 },
                 "balanced-match": {
                     "version": "1.0.0",
-                    "bundled": true,
-                    "optional": true
+                    "bundled": true
                 },
                 "brace-expansion": {
                     "version": "1.1.11",
                     "bundled": true,
-                    "optional": true,
                     "requires": {
                         "balanced-match": "^1.0.0",
                         "concat-map": "0.0.1"
@@ -5444,18 +5441,15 @@
                 },
                 "code-point-at": {
                     "version": "1.1.0",
-                    "bundled": true,
-                    "optional": true
+                    "bundled": true
                 },
                 "concat-map": {
                     "version": "0.0.1",
-                    "bundled": true,
-                    "optional": true
+                    "bundled": true
                 },
                 "console-control-strings": {
                     "version": "1.1.0",
-                    "bundled": true,
-                    "optional": true
+                    "bundled": true
                 },
                 "core-util-is": {
                     "version": "1.0.2",
@@ -5558,8 +5552,7 @@
                 },
                 "inherits": {
                     "version": "2.0.4",
-                    "bundled": true,
-                    "optional": true
+                    "bundled": true
                 },
                 "ini": {
                     "version": "1.3.5",
@@ -5569,7 +5562,6 @@
                 "is-fullwidth-code-point": {
                     "version": "1.0.0",
                     "bundled": true,
-                    "optional": true,
                     "requires": {
                         "number-is-nan": "^1.0.0"
                     }
@@ -5582,20 +5574,17 @@
                 "minimatch": {
                     "version": "3.0.4",
                     "bundled": true,
-                    "optional": true,
                     "requires": {
                         "brace-expansion": "^1.1.7"
                     }
                 },
                 "minimist": {
                     "version": "0.0.8",
-                    "bundled": true,
-                    "optional": true
+                    "bundled": true
                 },
                 "minipass": {
                     "version": "2.9.0",
                     "bundled": true,
-                    "optional": true,
                     "requires": {
                         "safe-buffer": "^5.1.2",
                         "yallist": "^3.0.0"
@@ -5612,7 +5601,6 @@
                 "mkdirp": {
                     "version": "0.5.1",
                     "bundled": true,
-                    "optional": true,
                     "requires": {
                         "minimist": "0.0.8"
                     }
@@ -5693,8 +5681,7 @@
                 },
                 "number-is-nan": {
                     "version": "1.0.1",
-                    "bundled": true,
-                    "optional": true
+                    "bundled": true
                 },
                 "object-assign": {
                     "version": "4.1.1",
@@ -5704,7 +5691,6 @@
                 "once": {
                     "version": "1.4.0",
                     "bundled": true,
-                    "optional": true,
                     "requires": {
                         "wrappy": "1"
                     }
@@ -5780,8 +5766,7 @@
                 },
                 "safe-buffer": {
                     "version": "5.1.2",
-                    "bundled": true,
-                    "optional": true
+                    "bundled": true
                 },
                 "safer-buffer": {
                     "version": "2.1.2",
@@ -5811,7 +5796,6 @@
                 "string-width": {
                     "version": "1.0.2",
                     "bundled": true,
-                    "optional": true,
                     "requires": {
                         "code-point-at": "^1.0.0",
                         "is-fullwidth-code-point": "^1.0.0",
@@ -5829,7 +5813,6 @@
                 "strip-ansi": {
                     "version": "3.0.1",
                     "bundled": true,
-                    "optional": true,
                     "requires": {
                         "ansi-regex": "^2.0.0"
                     }
@@ -5868,13 +5851,11 @@
                 },
                 "wrappy": {
                     "version": "1.0.2",
-                    "bundled": true,
-                    "optional": true
+                    "bundled": true
                 },
                 "yallist": {
                     "version": "3.1.1",
-                    "bundled": true,
-                    "optional": true
+                    "bundled": true
                 }
             }
         },
@@ -6994,7 +6975,7 @@
         },
         "is-accessor-descriptor": {
             "version": "0.1.6",
-            "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+            "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
             "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
             "requires": {
                 "kind-of": "^3.0.2"
@@ -7049,7 +7030,7 @@
         },
         "is-data-descriptor": {
             "version": "0.1.4",
-            "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+            "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
             "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
             "requires": {
                 "kind-of": "^3.0.2"
@@ -7736,7 +7717,7 @@
         },
         "load-json-file": {
             "version": "1.1.0",
-            "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+            "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
             "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
             "requires": {
                 "graceful-fs": "^4.1.2",
@@ -8054,7 +8035,7 @@
         },
         "media-typer": {
             "version": "0.3.0",
-            "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+            "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
             "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
         },
         "mem": {
@@ -8086,7 +8067,7 @@
         },
         "meow": {
             "version": "3.7.0",
-            "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+            "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
             "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
             "requires": {
                 "camelcase-keys": "^2.0.0",
@@ -8261,7 +8242,7 @@
         },
         "mkdirp": {
             "version": "0.5.1",
-            "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+            "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
             "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
             "requires": {
                 "minimist": "0.0.8"
@@ -8594,7 +8575,7 @@
         },
         "next-tick": {
             "version": "1.0.0",
-            "resolved": "http://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
+            "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
             "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw="
         },
         "nice-try": {
@@ -8677,7 +8658,7 @@
                 },
                 "semver": {
                     "version": "5.3.0",
-                    "resolved": "http://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
+                    "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
                     "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8="
                 },
                 "tar": {
@@ -12277,7 +12258,7 @@
         },
         "os-homedir": {
             "version": "1.0.2",
-            "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+            "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
             "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
         },
         "os-locale": {
@@ -12290,7 +12271,7 @@
         },
         "os-tmpdir": {
             "version": "1.0.2",
-            "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+            "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
             "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
         },
         "osenv": {
@@ -12530,7 +12511,7 @@
         },
         "path-is-absolute": {
             "version": "1.0.1",
-            "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+            "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
             "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
         },
         "path-is-inside": {
@@ -13925,7 +13906,7 @@
         },
         "readable-stream": {
             "version": "2.3.6",
-            "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
             "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
             "requires": {
                 "core-util-is": "~1.0.0",
@@ -14367,7 +14348,7 @@
         },
         "safe-regex": {
             "version": "1.1.0",
-            "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+            "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
             "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
             "requires": {
                 "ret": "~0.1.10"
@@ -14642,7 +14623,7 @@
         },
         "sha.js": {
             "version": "2.4.11",
-            "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+            "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
             "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
             "requires": {
                 "inherits": "^2.0.1",
@@ -15499,7 +15480,7 @@
         },
         "string_decoder": {
             "version": "1.1.1",
-            "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
             "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
             "requires": {
                 "safe-buffer": "~5.1.0"
@@ -15529,7 +15510,7 @@
         },
         "strip-ansi": {
             "version": "3.0.1",
-            "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+            "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
             "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
             "requires": {
                 "ansi-regex": "^2.0.0"
@@ -15545,7 +15526,7 @@
         },
         "strip-eof": {
             "version": "1.0.0",
-            "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+            "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
             "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="
         },
         "strip-indent": {
@@ -16317,7 +16298,7 @@
         },
         "tty-browserify": {
             "version": "0.0.0",
-            "resolved": "http://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
+            "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
             "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=",
             "dev": true
         },
@@ -17770,7 +17751,7 @@
         },
         "wrap-ansi": {
             "version": "2.1.0",
-            "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+            "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
             "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
             "requires": {
                 "string-width": "^1.0.1",
diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss
index c7d6f988c..7a3d2e92b 100644
--- a/src/client/views/nodes/PDFBox.scss
+++ b/src/client/views/nodes/PDFBox.scss
@@ -46,7 +46,27 @@
                 border-radius: 3px;
                 pointer-events: all;
              }
-         }
+        }
+        .pdfBox-overlayButton-fwd, 
+        .pdfBox-overlayButton-back {
+            background: #121721;
+            height: 25px;
+            width: 25px;
+            display: flex;
+            position: relative;
+            align-items: center;
+            justify-content: center;
+            border-radius: 3px;
+            pointer-events: all;
+            position: absolute;
+            top: 5;
+        }
+        .pdfBox-overlayButton-fwd {
+            left: 45;
+        }
+        .pdfBox-overlayButton-back {
+            left: 25;
+        }
 
          .pdfBox-nextIcon, 
          .pdfBox-prevIcon {
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index a96a26b61..593f40f10 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -140,12 +140,12 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
 
     settingsPanel() {
         const pageBtns = <>
-            <button className="pdfBox-overlayButton-iconCont" key="back" title="Page Back"
-                onPointerDown={e => e.stopPropagation()} onClick={e => this.backPage()} style={{ left: 45, top: 5 }}>
+            <button className="pdfBox-overlayButton-back" key="back" title="Page Back"
+                onPointerDown={e => e.stopPropagation()} onClick={e => this.backPage()} >
                 <FontAwesomeIcon style={{ color: "white" }} icon={"arrow-left"} size="sm" />
             </button>
-            <button className="pdfBox-overlayButton-iconCont" key="fwd" title="Page Forward"
-                onPointerDown={e => e.stopPropagation()} onClick={e => this.forwardPage()} style={{ left: 45, top: 5 }}>
+            <button className="pdfBox-overlayButton-fwd" key="fwd" title="Page Forward"
+                onPointerDown={e => e.stopPropagation()} onClick={e => this.forwardPage()} >
                 <FontAwesomeIcon style={{ color: "white" }} icon={"arrow-right"} size="sm" />
             </button>
         </>;
-- 
cgit v1.2.3-70-g09d2


From cad4ca15ec12808915b7aa901859e349144d8a50 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Mon, 2 Mar 2020 14:42:23 -0500
Subject: fixed pdfs to sort of support region clippings.

---
 package-lock.json                                  | 79 +++++++++++++---------
 src/client/documents/Documents.ts                  |  3 +-
 src/client/util/DocumentManager.ts                 |  2 +-
 src/client/util/DragManager.ts                     |  2 +-
 src/client/util/RichTextSchema.tsx                 | 17 ++---
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  4 +-
 src/client/views/nodes/DocumentView.tsx            |  7 +-
 src/client/views/nodes/PDFBox.tsx                  | 18 +++--
 src/client/views/pdf/PDFViewer.tsx                 | 50 ++++++++------
 9 files changed, 103 insertions(+), 79 deletions(-)

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

diff --git a/package-lock.json b/package-lock.json
index 375b41a01..827fb05b8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2226,7 +2226,7 @@
                 },
                 "util": {
                     "version": "0.10.3",
-                    "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
+                    "resolved": "http://registry.npmjs.org/util/-/util-0.10.3.tgz",
                     "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
                     "dev": true,
                     "requires": {
@@ -2846,7 +2846,7 @@
         },
         "browserify-aes": {
             "version": "1.2.0",
-            "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+            "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
             "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
             "requires": {
                 "buffer-xor": "^1.0.3",
@@ -2880,7 +2880,7 @@
         },
         "browserify-rsa": {
             "version": "4.0.1",
-            "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+            "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
             "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
             "requires": {
                 "bn.js": "^4.1.0",
@@ -3051,7 +3051,7 @@
         },
         "camelcase-keys": {
             "version": "2.1.0",
-            "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+            "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
             "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
             "requires": {
                 "camelcase": "^2.0.0",
@@ -3844,7 +3844,7 @@
         },
         "create-hash": {
             "version": "1.2.0",
-            "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+            "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
             "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
             "requires": {
                 "cipher-base": "^1.0.1",
@@ -3856,7 +3856,7 @@
         },
         "create-hmac": {
             "version": "1.1.7",
-            "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+            "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
             "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
             "requires": {
                 "cipher-base": "^1.0.3",
@@ -4398,7 +4398,7 @@
         },
         "diffie-hellman": {
             "version": "5.0.3",
-            "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+            "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
             "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
             "requires": {
                 "bn.js": "^4.1.0",
@@ -5697,7 +5697,8 @@
                 },
                 "ansi-regex": {
                     "version": "2.1.1",
-                    "bundled": true
+                    "bundled": true,
+                    "optional": true
                 },
                 "aproba": {
                     "version": "1.2.0",
@@ -5734,7 +5735,8 @@
                 },
                 "code-point-at": {
                     "version": "1.1.0",
-                    "bundled": true
+                    "bundled": true,
+                    "optional": true
                 },
                 "concat-map": {
                     "version": "0.0.1",
@@ -5743,7 +5745,8 @@
                 },
                 "console-control-strings": {
                     "version": "1.1.0",
-                    "bundled": true
+                    "bundled": true,
+                    "optional": true
                 },
                 "core-util-is": {
                     "version": "1.0.2",
@@ -5846,7 +5849,8 @@
                 },
                 "inherits": {
                     "version": "2.0.4",
-                    "bundled": true
+                    "bundled": true,
+                    "optional": true
                 },
                 "ini": {
                     "version": "1.3.5",
@@ -5856,6 +5860,7 @@
                 "is-fullwidth-code-point": {
                     "version": "1.0.0",
                     "bundled": true,
+                    "optional": true,
                     "requires": {
                         "number-is-nan": "^1.0.0"
                     }
@@ -5881,6 +5886,7 @@
                 "minipass": {
                     "version": "2.9.0",
                     "bundled": true,
+                    "optional": true,
                     "requires": {
                         "safe-buffer": "^5.1.2",
                         "yallist": "^3.0.0"
@@ -5897,6 +5903,7 @@
                 "mkdirp": {
                     "version": "0.5.1",
                     "bundled": true,
+                    "optional": true,
                     "requires": {
                         "minimist": "0.0.8"
                     }
@@ -5988,6 +5995,7 @@
                 "once": {
                     "version": "1.4.0",
                     "bundled": true,
+                    "optional": true,
                     "requires": {
                         "wrappy": "1"
                     }
@@ -6063,7 +6071,8 @@
                 },
                 "safe-buffer": {
                     "version": "5.1.2",
-                    "bundled": true
+                    "bundled": true,
+                    "optional": true
                 },
                 "safer-buffer": {
                     "version": "2.1.2",
@@ -6093,6 +6102,7 @@
                 "string-width": {
                     "version": "1.0.2",
                     "bundled": true,
+                    "optional": true,
                     "requires": {
                         "code-point-at": "^1.0.0",
                         "is-fullwidth-code-point": "^1.0.0",
@@ -6110,6 +6120,7 @@
                 "strip-ansi": {
                     "version": "3.0.1",
                     "bundled": true,
+                    "optional": true,
                     "requires": {
                         "ansi-regex": "^2.0.0"
                     }
@@ -6148,11 +6159,13 @@
                 },
                 "wrappy": {
                     "version": "1.0.2",
-                    "bundled": true
+                    "bundled": true,
+                    "optional": true
                 },
                 "yallist": {
                     "version": "3.1.1",
-                    "bundled": true
+                    "bundled": true,
+                    "optional": true
                 }
             }
         },
@@ -7370,7 +7383,7 @@
         },
         "is-accessor-descriptor": {
             "version": "0.1.6",
-            "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+            "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
             "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
             "requires": {
                 "kind-of": "^3.0.2"
@@ -7425,7 +7438,7 @@
         },
         "is-data-descriptor": {
             "version": "0.1.4",
-            "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+            "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
             "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
             "requires": {
                 "kind-of": "^3.0.2"
@@ -8156,7 +8169,7 @@
         },
         "load-json-file": {
             "version": "1.1.0",
-            "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+            "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
             "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
             "requires": {
                 "graceful-fs": "^4.1.2",
@@ -8493,7 +8506,7 @@
         },
         "media-typer": {
             "version": "0.3.0",
-            "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+            "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
             "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
         },
         "mem": {
@@ -8525,7 +8538,7 @@
         },
         "meow": {
             "version": "3.7.0",
-            "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+            "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
             "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
             "requires": {
                 "camelcase-keys": "^2.0.0",
@@ -8700,7 +8713,7 @@
         },
         "mkdirp": {
             "version": "0.5.1",
-            "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+            "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
             "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
             "requires": {
                 "minimist": "0.0.8"
@@ -9038,7 +9051,7 @@
         },
         "next-tick": {
             "version": "1.0.0",
-            "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
+            "resolved": "http://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
             "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw="
         },
         "nice-try": {
@@ -9121,7 +9134,7 @@
                 },
                 "semver": {
                     "version": "5.3.0",
-                    "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
+                    "resolved": "http://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
                     "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8="
                 },
                 "tar": {
@@ -12772,7 +12785,7 @@
         },
         "os-homedir": {
             "version": "1.0.2",
-            "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+            "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
             "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
         },
         "os-locale": {
@@ -12785,7 +12798,7 @@
         },
         "os-tmpdir": {
             "version": "1.0.2",
-            "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+            "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
             "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
         },
         "osenv": {
@@ -13025,7 +13038,7 @@
         },
         "path-is-absolute": {
             "version": "1.0.1",
-            "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+            "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
             "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
         },
         "path-is-inside": {
@@ -14451,7 +14464,7 @@
         },
         "readable-stream": {
             "version": "2.3.6",
-            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+            "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
             "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
             "requires": {
                 "core-util-is": "~1.0.0",
@@ -14893,7 +14906,7 @@
         },
         "safe-regex": {
             "version": "1.1.0",
-            "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+            "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
             "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
             "requires": {
                 "ret": "~0.1.10"
@@ -15173,7 +15186,7 @@
         },
         "sha.js": {
             "version": "2.4.11",
-            "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+            "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
             "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
             "requires": {
                 "inherits": "^2.0.1",
@@ -16035,7 +16048,7 @@
         },
         "string_decoder": {
             "version": "1.1.1",
-            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+            "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
             "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
             "requires": {
                 "safe-buffer": "~5.1.0"
@@ -16065,7 +16078,7 @@
         },
         "strip-ansi": {
             "version": "3.0.1",
-            "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+            "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
             "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
             "requires": {
                 "ansi-regex": "^2.0.0"
@@ -16081,7 +16094,7 @@
         },
         "strip-eof": {
             "version": "1.0.0",
-            "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+            "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
             "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="
         },
         "strip-indent": {
@@ -16898,7 +16911,7 @@
         },
         "tty-browserify": {
             "version": "0.0.0",
-            "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
+            "resolved": "http://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
             "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=",
             "dev": true
         },
@@ -18370,7 +18383,7 @@
         },
         "wrap-ansi": {
             "version": "2.1.0",
-            "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+            "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
             "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
             "requires": {
                 "string-width": "^1.0.1",
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index d0385918c..abef72f21 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -75,6 +75,7 @@ export interface DocumentOptions {
     _showTitleHover?: string; // 
     _showTitle?: string; // which field to display in the title area.  leave empty to have no title
     _showCaption?: string; // which field to display in the caption area.  leave empty to have no caption
+    _scrollTop?: number; // scroll location for pdfs
     _chromeStatus?: string;
     _viewType?: number;
     _gridGap?: number; // gap between items in masonry view
@@ -420,7 +421,7 @@ export namespace Docs {
 
         const delegateKeys = ["x", "y", "layoutKey", "_width", "_height", "_panX", "_panY", "_viewType", "_nativeWidth", "_nativeHeight", "dropAction", "childDropAction", "_annotationOn",
             "_chromeStatus", "_forceActive", "_autoHeight", "_fitWidth", "_LODdisable", "_itemIndex", "_showSidebar", "_showTitle", "_showCaption", "_showTitleHover", "_backgroundColor",
-            "_xMargin", "_yMargin", "_xPadding", "_yPadding", "_singleLine",
+            "_xMargin", "_yMargin", "_xPadding", "_yPadding", "_singleLine", "_scrollTop",
             "_color", "isButton", "isBackground", "removeDropProperties", "treeViewOpen"];
 
         /**
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index c639f07f5..4f721cb77 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -195,7 +195,7 @@ export class DocumentManager {
         const linkFollowDocContexts = first.length ? [await first[0].anchor2Context as Doc, await first[0].anchor1Context as Doc] : second.length ? [await second[0].anchor1Context as Doc, await second[0].anchor2Context as Doc] : [undefined, undefined];
         const linkFollowTimecodes = first.length ? [NumCast(first[0].anchor2Timecode), NumCast(first[0].anchor1Timecode)] : second.length ? [NumCast(second[0].anchor1Timecode), NumCast(second[0].anchor2Timecode)] : [undefined, undefined];
         if (linkFollowDocs && linkDoc) {
-            const maxLocation = StrCast(linkFollowDocs[0].maximizeLocation, "inTab");
+            const maxLocation = StrCast(linkDoc.maximizeLocation, "inTab");
             const targetContext = !Doc.AreProtosEqual(linkFollowDocContexts[reverse ? 1 : 0], currentContext) ? linkFollowDocContexts[reverse ? 1 : 0] : undefined;
             const target = linkFollowDocs[reverse ? 1 : 0];
             target.currentTimecode !== undefined && (target.currentTimecode = linkFollowTimecodes[reverse ? 1 : 0]);
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 1cfebf414..42ae704dd 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -387,8 +387,8 @@ export namespace DragManager {
             hideDragShowOriginalElements();
             dispatchDrag(eles, e, dragData, options, finishDrag);
             SelectionManager.SetIsDragging(false);
-            options?.dragComplete?.(new DragCompleteEvent(false, dragData));
             endDrag();
+            options?.dragComplete?.(new DragCompleteEvent(false, dragData));
         };
         document.addEventListener("pointermove", moveHandler, true);
         document.addEventListener("pointerup", upHandler);
diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx
index 4a80a1af8..b2ee7320a 100644
--- a/src/client/util/RichTextSchema.tsx
+++ b/src/client/util/RichTextSchema.tsx
@@ -796,15 +796,8 @@ export class DashDocView {
     }
     doRender(dashDoc: Doc, removeDoc: any, node: any, view: any, getPos: any) {
         this._dashDoc = dashDoc;
-        if (node.attrs.width !== dashDoc._width + "px" || node.attrs.height !== dashDoc._height + "px") {
-            try { // bcz: an exception will be thrown if two aliases are open at the same time when a doc view comment is made
-                view.dispatch(view.state.tr.setNodeMarkup(getPos(), null, { ...node.attrs, width: dashDoc._width + "px", height: dashDoc._height + "px" }));
-            } catch (e) {
-                console.log(e);
-            }
-        }
         const self = this;
-        const finalLayout = Doc.expandTemplateLayout(dashDoc, !Doc.AreProtosEqual(this._textBox.dataDoc, this._textBox.Document) ? this._textBox.dataDoc : undefined);
+        const finalLayout = this._textBox.props.Document instanceof Doc && (Doc.expandTemplateLayout(dashDoc, !Doc.AreProtosEqual(this._textBox.dataDoc, this._textBox.props.Document) ? this._textBox.dataDoc : undefined));
         if (!finalLayout) setTimeout(() => self.doRender(dashDoc, removeDoc, node, view, getPos), 0);
         else {
             const layoutKey = StrCast(finalLayout.layoutKey);
@@ -846,9 +839,17 @@ export class DashDocView {
                 ContainingCollectionDoc={undefined}
                 ContentScaling={this.contentScaling}
             />, this._dashSpan);
+            if (node.attrs.width !== dashDoc._width + "px" || node.attrs.height !== dashDoc._height + "px") {
+                try { // bcz: an exception will be thrown if two aliases are open at the same time when a doc view comment is made
+                    view.dispatch(view.state.tr.setNodeMarkup(getPos(), null, { ...node.attrs, width: dashDoc._width + "px", height: dashDoc._height + "px" }));
+                } catch (e) {
+                    console.log(e);
+                }
+            }
         }
     }
     destroy() {
+        ReactDOM.unmountComponentAtNode(this._dashSpan);
         this._reactionDisposer?.();
     }
 }
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index a73e601fd..055be7f86 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -817,6 +817,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
                 const offset = annotOn && (contextHgt / 2 * 96 / 72);
                 this.props.Document.scrollY = NumCast(doc.y) - offset;
             }
+
+            afterFocus && setTimeout(() => afterFocus?.(), 1000);
         } else {
             const layoutdoc = Doc.Layout(doc);
             const newPanX = NumCast(doc.x) + NumCast(layoutdoc._width) / 2;
@@ -834,7 +836,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             Doc.linkFollowHighlight(doc);
 
             afterFocus && setTimeout(() => {
-                if (afterFocus && afterFocus()) {
+                if (afterFocus?.()) {
                     this.Document._panX = savedState.px;
                     this.Document._panY = savedState.py;
                     this.Document.scale = savedState.s;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 850225652..64d85589f 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -217,7 +217,10 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         this.multiTouchDisposer && this.multiTouchDisposer();
         this.holdDisposer && this.holdDisposer();
         Doc.UnBrushDoc(this.props.Document);
-        !this.props.dontRegisterView && DocumentManager.Instance.DocumentViews.splice(DocumentManager.Instance.DocumentViews.indexOf(this), 1);
+        if (!this.props.dontRegisterView) {
+            const index = DocumentManager.Instance.DocumentViews.indexOf(this);
+            index !== -1 && DocumentManager.Instance.DocumentViews.splice(index, 1);
+        }
     }
 
     startDragging(x: number, y: number, dropAction: dropActionType) {
@@ -829,7 +832,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
             if (!this.topMost) {
                 // DocumentViews should stop propagation of this event
-                me?.stopPropagation();
+                e.stopPropagation();
             }
             ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15);
             if (!SelectionManager.IsSelected(this, true)) {
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 593f40f10..7b545eee5 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -56,7 +56,7 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
 
         const backup = "oldPath";
         const { Document } = this.props;
-        const { url: { href } } = Cast(Document[this.props.fieldKey], PdfField)!;
+        const { url: { href } } = Cast(this.dataDoc[this.props.fieldKey], PdfField)!;
         const pathCorrectionTest = /upload\_[a-z0-9]{32}.(.*)/g;
         const matches = pathCorrectionTest.exec(href);
         console.log("\nHere's the { url } being fed into the outer regex:");
@@ -78,9 +78,7 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
         }
     }
 
-    componentWillUnmount() {
-        this._selectReactionDisposer && this._selectReactionDisposer();
-    }
+    componentWillUnmount() { this._selectReactionDisposer?.(); }
     componentDidMount() {
         this._selectReactionDisposer = reaction(() => this.props.isSelected(),
             () => {
@@ -96,11 +94,11 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
         !this.Document._fitWidth && (this.Document._height = this.Document[WidthSym]() * (nh / nw));
     }
 
-    public search(string: string, fwd: boolean) { this._pdfViewer && this._pdfViewer.search(string, fwd); }
-    public prevAnnotation() { this._pdfViewer && this._pdfViewer.prevAnnotation(); }
-    public nextAnnotation() { this._pdfViewer && this._pdfViewer.nextAnnotation(); }
-    public backPage() { this._pdfViewer!.gotoPage((this.Document.curPage || 1) - 1); }
-    public forwardPage() { this._pdfViewer!.gotoPage((this.Document.curPage || 1) + 1); }
+    public search = (string: string, fwd: boolean) => { this._pdfViewer?.search(string, fwd); }
+    public prevAnnotation = () => { this._pdfViewer?.prevAnnotation(); }
+    public nextAnnotation = () => { this._pdfViewer?.nextAnnotation(); }
+    public backPage = () => { this._pdfViewer!.gotoPage((this.Document.curPage || 1) - 1); }
+    public forwardPage = () => { this._pdfViewer!.gotoPage((this.Document.curPage || 1) + 1); }
     public gotoPage = (p: number) => { this._pdfViewer!.gotoPage(p); };
 
     @undoBatch
@@ -233,7 +231,7 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
     isChildActive = (outsideReaction?: boolean) => this._isChildActive;
     @computed get renderPdfView() {
         const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField);
-        return <div className={"pdfBox"} onContextMenu={this.specificContextMenu}>
+        return <div className={"pdfBox"} onContextMenu={this.specificContextMenu} style={{ height: this.props.Document._scrollTop ? NumCast(this.Document._height) * this.props.PanelWidth() / NumCast(this.Document._width) : undefined }}>
             <PDFViewer {...this.props} pdf={this._pdf!} url={pdfUrl!.url.pathname} active={this.props.active} loaded={this.loaded}
                 setPdfViewer={this.setPdfViewer} ContainingCollectionView={this.props.ContainingCollectionView}
                 renderDepth={this.props.renderDepth} PanelHeight={this.props.PanelHeight} PanelWidth={this.props.PanelWidth}
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 198aeb856..b110aa172 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -4,7 +4,7 @@ import * as Pdfjs from "pdfjs-dist";
 import "pdfjs-dist/web/pdf_viewer.css";
 import { Dictionary } from "typescript-collections";
 import { Doc, DocListCast, FieldResult, WidthSym, Opt, HeightSym } from "../../../new_fields/Doc";
-import { Id } from "../../../new_fields/FieldSymbols";
+import { Id, Copy } from "../../../new_fields/FieldSymbols";
 import { List } from "../../../new_fields/List";
 import { makeInterface, createSchema } from "../../../new_fields/Schema";
 import { ScriptField } from "../../../new_fields/ScriptField";
@@ -31,6 +31,7 @@ import { InkingControl } from "../InkingControl";
 import { InkTool } from "../../../new_fields/InkField";
 import { TraceMobx } from "../../../new_fields/util";
 import { PdfField } from "../../../new_fields/URLField";
+import { PDFBox } from "../nodes/PDFBox";
 const PDFJSViewer = require("pdfjs-dist/web/pdf_viewer");
 const pdfjsLib = require("pdfjs-dist");
 
@@ -101,6 +102,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
     private _reactionDisposer?: IReactionDisposer;
     private _selectionReactionDisposer?: IReactionDisposer;
     private _annotationReactionDisposer?: IReactionDisposer;
+    private _scrollTopReactionDisposer?: IReactionDisposer;
     private _filterReactionDisposer?: IReactionDisposer;
     private _searchReactionDisposer?: IReactionDisposer;
     private _viewer: React.RefObject<HTMLDivElement> = React.createRef();
@@ -126,7 +128,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
         !this.props.Document.lockedTransform && (this.props.Document.lockedTransform = true);
         // change the address to be the file address of the PNG version of each page
         // file address of the pdf
-        const { url: { href } } = Cast(this.props.Document[this.props.fieldKey], PdfField)!;
+        const { url: { href } } = Cast(this.dataDoc[this.props.fieldKey], PdfField)!;
         const addr = Utils.prepend(`/thumbnail${this.props.url.substring("files/pdfs/".length, this.props.url.length - ".pdf".length)}-${(this.Document.curPage || 1)}.png`);
         this._coverPath = href.startsWith(window.location.origin) ? JSON.parse(await rp.get(addr)) : { width: 100, height: 100, path: "" };
         runInAction(() => this._showWaiting = this._showCover = true);
@@ -162,10 +164,11 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
 
     componentWillUnmount = () => {
         this._reactionDisposer && this._reactionDisposer();
-        this._annotationReactionDisposer && this._annotationReactionDisposer();
-        this._filterReactionDisposer && this._filterReactionDisposer();
-        this._selectionReactionDisposer && this._selectionReactionDisposer();
-        this._searchReactionDisposer && this._searchReactionDisposer();
+        this._scrollTopReactionDisposer?.();
+        this._annotationReactionDisposer?.();
+        this._filterReactionDisposer?.();
+        this._selectionReactionDisposer?.();
+        this._searchReactionDisposer?.();
         document.removeEventListener("copy", this.copy);
     }
 
@@ -206,6 +209,13 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
         this.props.setPdfViewer(this);
         await this.initialLoad();
 
+        this._scrollTopReactionDisposer = reaction(() => Cast(this.props.Document._scrollTop, "number", null),
+            (stop) => {
+                if (stop !== undefined) {
+                    const offset = this.visibleHeight() / 2 * 96 / 72;
+                    this._mainCont.current && smoothScroll(500, this._mainCont.current, stop);
+                }
+            }, { fireImmediately: true });
         this._annotationReactionDisposer = reaction(
             () => DocListCast(this.dataDoc[this.props.fieldKey + "-annotations"]),
             annotations => annotations?.length && (this._annotations = annotations),
@@ -267,7 +277,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
         let minY = Number.MAX_VALUE;
         if ((this._savedAnnotations.values()[0][0] as any).marqueeing) {
             const anno = this._savedAnnotations.values()[0][0];
-            const annoDoc = Docs.Create.FreeformDocument([], { backgroundColor: color, title: "Annotation on " + this.Document.title });
+            const annoDoc = Docs.Create.FreeformDocument([], { backgroundColor: color, _LODdisable: true, title: "Annotation on " + this.Document.title });
             if (anno.style.left) annoDoc.x = parseInt(anno.style.left);
             if (anno.style.top) annoDoc.y = parseInt(anno.style.top);
             if (anno.style.height) annoDoc._height = parseInt(anno.style.height);
@@ -558,28 +568,23 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
         e.preventDefault();
         e.stopPropagation();
         const targetDoc = Docs.Create.TextDocument("", { _width: 200, _height: 200, title: "Note linked to " + this.props.Document.title });
+        Doc.GetProto(targetDoc).snipped = this.dataDoc[this.props.fieldKey][Copy]();
+        const snipLayout = Docs.Create.PdfDocument("http://www.msn.com", { title: "snippetView", isTemplateDoc: true, isTemplateForField: "snipped", _fitWidth: true, _width: this.marqueeWidth(), _height: this.marqueeHeight(), _scrollTop: this.marqueeY() });
+        Doc.GetProto(snipLayout).layout = PDFBox.LayoutString("snipped");
+        Doc.GetProto(targetDoc).layout_snipped = snipLayout;
         const annotationDoc = this.highlight("rgba(146, 245, 95, 0.467)"); // yellowish highlight color when dragging out a text selection
         if (annotationDoc) {
             DragManager.StartPdfAnnoDrag([ele], new DragManager.PdfAnnoDragData(this.props.Document, annotationDoc, targetDoc), e.pageX, e.pageY, {
-                dragComplete: e => !e.aborted && e.annoDragData && !e.annoDragData.linkedToDoc &&
-                    DocUtils.MakeLink({ doc: annotationDoc }, { doc: e.annoDragData.dropDocument, ctx: e.annoDragData.targetContext }, `Annotation from ${this.Document.title}`, "link from PDF")
+                dragComplete: e => {
+                    if (!e.aborted && e.annoDragData && !e.annoDragData.linkedToDoc) {
+                        const link = DocUtils.MakeLink({ doc: annotationDoc }, { doc: e.annoDragData.dropDocument, ctx: e.annoDragData.targetContext }, `Annotation from ${this.Document.title}`, "link from PDF");
+                        if (link) link.maximizeLocation = "onRight";
+                    }
+                }
             });
         }
     }
 
-    createSnippet = (marquee: { left: number, top: number, width: number, height: number }): void => {
-        const view = Doc.MakeAlias(this.props.Document);
-        const data = Doc.MakeDelegate(Doc.GetProto(this.props.Document));
-        data.title = StrCast(data.title) + "_snippet";
-        view.proto = data;
-        view._nativeHeight = marquee.height;
-        view._height = (this.Document[WidthSym]() / (this.Document._nativeWidth || 1)) * marquee.height;
-        view._nativeWidth = this.Document._nativeWidth;
-        view.startY = marquee.top;
-        view._width = this.Document[WidthSym]();
-        DragManager.StartDocumentDrag([], new DragManager.DocumentDragData([view]), 0, 0);
-    }
-
     scrollXf = () => {
         return this._mainCont.current ? this.props.ScreenToLocalTransform().translate(0, this._scrollTop) : this.props.ScreenToLocalTransform();
     }
@@ -643,6 +648,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
                 select={emptyFunction}
                 active={this.annotationsActive}
                 ContentScaling={this.contentZoom}
+                bringToFront={emptyFunction}
                 whenActiveChanged={this.whenActiveChanged}
                 removeDocument={this.removeDocument}
                 moveDocument={this.moveDocument}
-- 
cgit v1.2.3-70-g09d2


From 2556a754404cc622629ca12bddcd163f53b69060 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Mon, 2 Mar 2020 17:34:37 -0500
Subject: changed clippings to use slide template.  fixed issues on startup

---
 src/client/util/DocumentManager.ts  |  2 +-
 src/client/views/nodes/PDFBox.tsx   |  4 ++--
 src/client/views/pdf/PDFViewer.scss |  8 ++++----
 src/client/views/pdf/PDFViewer.tsx  | 40 +++++++++++++++++++++----------------
 4 files changed, 30 insertions(+), 24 deletions(-)

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

diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 4f721cb77..6bd2fd016 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -134,7 +134,7 @@ export class DocumentManager {
             finalDocView && Doc.linkFollowHighlight(finalDocView.props.Document);
         };
         const docView = DocumentManager.Instance.getFirstDocumentView(targetDoc, originatingDoc);
-        let annotatedDoc = await Cast(docView?.props.Document.annotationOn, Doc);
+        let annotatedDoc = await Cast(targetDoc.annotationOn, Doc);
         if (annotatedDoc) {
             const first = DocumentManager.Instance.getFirstDocumentView(annotatedDoc);
             if (first) annotatedDoc = first.props.Document;
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 7b545eee5..f47620c24 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -241,7 +241,7 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
                 ScreenToLocalTransform={this.props.ScreenToLocalTransform} select={this.props.select}
                 isSelected={this.props.isSelected} whenActiveChanged={this.whenActiveChanged}
                 isChildActive={this.isChildActive}
-                fieldKey={this.props.fieldKey} startupLive={this._initialScale < 2.5 ? true : false} />
+                fieldKey={this.props.fieldKey} startupLive={this._initialScale < 2.5 || this.props.Document._scrollTop ? true : false} />
             {this.settingsPanel()}
         </div>;
     }
@@ -250,7 +250,7 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
     render() {
         const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField, null);
         if (this.props.isSelected() || this.props.Document.scrollY !== undefined) this._everActive = true;
-        if (pdfUrl && (this._everActive || (this.dataDoc[this.props.fieldKey + "-nativeWidth"] && this.props.ScreenToLocalTransform().Scale < 2.5))) {
+        if (pdfUrl && (this._everActive || this.props.Document._scrollTop || (this.dataDoc[this.props.fieldKey + "-nativeWidth"] && this.props.ScreenToLocalTransform().Scale < 2.5))) {
             if (pdfUrl instanceof PdfField && this._pdf) {
                 return this.renderPdfView;
             }
diff --git a/src/client/views/pdf/PDFViewer.scss b/src/client/views/pdf/PDFViewer.scss
index 4f81c6f70..5cd2c4fe4 100644
--- a/src/client/views/pdf/PDFViewer.scss
+++ b/src/client/views/pdf/PDFViewer.scss
@@ -1,6 +1,5 @@
  
-.pdfViewer, .pdfViewer-zoomed {
-    pointer-events: all;
+.pdfViewer, .pdfViewer-interactive {
     width: 100%;
     height: 100%;
     position: absolute;
@@ -91,7 +90,8 @@
         z-index: 10;
     }
 }
-.pdfViewer-zoomed {
-    overflow-x: scroll;
+
+.pdfViewer-interactive {
+    pointer-events: all;
 }
    
\ No newline at end of file
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index b110aa172..0607dfda5 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -32,6 +32,7 @@ import { InkTool } from "../../../new_fields/InkField";
 import { TraceMobx } from "../../../new_fields/util";
 import { PdfField } from "../../../new_fields/URLField";
 import { PDFBox } from "../nodes/PDFBox";
+import { FormattedTextBox } from "../nodes/FormattedTextBox";
 const PDFJSViewer = require("pdfjs-dist/web/pdf_viewer");
 const pdfjsLib = require("pdfjs-dist");
 
@@ -210,12 +211,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
         await this.initialLoad();
 
         this._scrollTopReactionDisposer = reaction(() => Cast(this.props.Document._scrollTop, "number", null),
-            (stop) => {
-                if (stop !== undefined) {
-                    const offset = this.visibleHeight() / 2 * 96 / 72;
-                    this._mainCont.current && smoothScroll(500, this._mainCont.current, stop);
-                }
-            }, { fireImmediately: true });
+            (stop) => (stop !== undefined) && this._mainCont.current && smoothScroll(500, this._mainCont.current, stop) , { fireImmediately: true });
         this._annotationReactionDisposer = reaction(
             () => DocListCast(this.dataDoc[this.props.fieldKey + "-annotations"]),
             annotations => annotations?.length && (this._annotations = annotations),
@@ -237,6 +233,12 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
         this.createPdfViewer();
     }
 
+    pagesinit = action(() => {
+        this._pdfViewer.currentScaleValue = this._zoomed = 1;
+        this.gotoPage(this.Document.curPage || 1);
+        document.removeEventListener("pagesinit", this.pagesinit);
+    })
+
     createPdfViewer() {
         if (!this._mainCont.current) { // bcz: I don't think this is ever triggered or needed
             if (this._retries < 5) {
@@ -247,10 +249,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
         }
         document.removeEventListener("copy", this.copy);
         document.addEventListener("copy", this.copy);
-        document.addEventListener("pagesinit", action(() => {
-            this._pdfViewer.currentScaleValue = this._zoomed = 1;
-            this.gotoPage(this.Document.curPage || 1);
-        }));
+        document.addEventListener("pagesinit", this.pagesinit);
         document.addEventListener("pagerendered", action(() => this._showCover = this._showWaiting = false));
         const pdfLinkService = new PDFJSViewer.PDFLinkService();
         const pdfFindController = new PDFJSViewer.PDFFindController({ linkService: pdfLinkService });
@@ -330,7 +329,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
 
     @action
     gotoPage = (p: number) => {
-        this._pdfViewer && this._pdfViewer.scrollPageIntoView({ pageNumber: Math.min(Math.max(1, p), this._pageSizes.length) });
+        this._pdfViewer?.scrollPageIntoView({ pageNumber: Math.min(Math.max(1, p), this._pageSizes.length) });
     }
 
     @action
@@ -564,14 +563,20 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
      * start a drag event and create or put the necessary info into the drag event.
      */
     @action
-    startDrag = (e: PointerEvent, ele: HTMLElement): void => {
+    startDrag = async (e: PointerEvent, ele: HTMLElement) => {
         e.preventDefault();
         e.stopPropagation();
+
+        const clipDoc = Docs.Create.PdfDocument(Cast(this.dataDoc[this.props.fieldKey], PdfField, null)?.url.href || "http://www.msn.com", { title: "snippetView", _fitWidth: true, _width: this.marqueeWidth(), _height: this.marqueeHeight(), _scrollTop: this.marqueeY() });
         const targetDoc = Docs.Create.TextDocument("", { _width: 200, _height: 200, title: "Note linked to " + this.props.Document.title });
-        Doc.GetProto(targetDoc).snipped = this.dataDoc[this.props.fieldKey][Copy]();
-        const snipLayout = Docs.Create.PdfDocument("http://www.msn.com", { title: "snippetView", isTemplateDoc: true, isTemplateForField: "snipped", _fitWidth: true, _width: this.marqueeWidth(), _height: this.marqueeHeight(), _scrollTop: this.marqueeY() });
-        Doc.GetProto(snipLayout).layout = PDFBox.LayoutString("snipped");
-        Doc.GetProto(targetDoc).layout_snipped = snipLayout;
+        Doc.GetProto(targetDoc).layout = FormattedTextBox.LayoutString("contents");
+        Doc.GetProto(targetDoc).data = new List<Doc>([clipDoc]);
+        Doc.GetProto(targetDoc).layout_slideView = (await Cast(Doc.UserDoc().slidesBtn, Doc))?.dragFactory;
+        targetDoc.layoutKey = "layout_slideView";
+        // const targetDoc = Docs.Create.TextDocument("", { _width: 200, _height: 200, title: "Note linked to " + this.props.Document.title });
+        // Doc.GetProto(targetDoc).snipped = this.dataDoc[this.props.fieldKey][Copy]();
+        // const snipLayout = Docs.Create.PdfDocument("http://www.msn.com", { title: "snippetView", isTemplateDoc: true, isTemplateForField: "snipped", _fitWidth: true, _width: this.marqueeWidth(), _height: this.marqueeHeight(), _scrollTop: this.marqueeY() });
+        // Doc.GetProto(snipLayout).layout = PDFBox.LayoutString("snipped");
         const annotationDoc = this.highlight("rgba(146, 245, 95, 0.467)"); // yellowish highlight color when dragging out a text selection
         if (annotationDoc) {
             DragManager.StartPdfAnnoDrag([ele], new DragManager.PdfAnnoDragData(this.props.Document, annotationDoc, targetDoc), e.pageX, e.pageY, {
@@ -679,9 +684,10 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
     contentZoom = () => this._zoomed;
     render() {
         TraceMobx();
-        return <div className={"pdfViewer" + (this._zoomed !== 1 ? "-zoomed" : "")} ref={this._mainCont}
+        return <div className={"pdfViewer" + (this.active() ? "-interactive" : "")} ref={this._mainCont}
             onScroll={this.onScroll} onWheel={this.onZoomWheel} onPointerDown={this.onPointerDown} onClick={this.onClick}
             style={{
+                overflowX: this._zoomed !== 1 ? "scroll" : undefined,
                 width: !this.props.Document._fitWidth ? NumCast(this.props.Document._nativeWidth) : `${100 / this.contentScaling}%`,
                 height: !this.props.Document._fitWidth ? NumCast(this.props.Document._nativeHeight) : `${100 / this.contentScaling}%`,
                 transform: `scale(${this.props.ContentScaling()})`
-- 
cgit v1.2.3-70-g09d2


From 636e6880a52d3a1a3e24437f47194a902731401d Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Mon, 9 Mar 2020 16:39:42 -0400
Subject: cleanup of warnings

---
 src/client/cognitive_services/CognitiveServices.ts   |  8 ++++----
 src/client/util/DocumentManager.ts                   |  2 +-
 src/client/util/DragManager.ts                       |  2 +-
 src/client/util/ProsemirrorExampleTransfer.ts        |  2 +-
 src/client/util/RichTextSchema.tsx                   | 14 +++++++-------
 src/client/util/SearchUtil.ts                        |  4 ++--
 src/client/views/KeyphraseQueryView.tsx              |  4 ++--
 .../views/collections/CollectionDockingView.tsx      |  4 ++--
 src/client/views/collections/CollectionSubView.tsx   |  2 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx    |  2 +-
 .../CollectionMulticolumnView.tsx                    |  2 +-
 src/client/views/linking/LinkEditor.tsx              |  4 ++--
 src/client/views/nodes/AudioBox.tsx                  |  6 ++----
 src/client/views/nodes/DocuLinkBox.tsx               |  4 ++--
 src/client/views/nodes/DocumentView.tsx              | 14 +++++++-------
 src/client/views/nodes/FormattedTextBox.tsx          | 20 ++++++++------------
 src/client/views/nodes/PDFBox.tsx                    | 10 +++++-----
 17 files changed, 49 insertions(+), 55 deletions(-)

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

diff --git a/src/client/cognitive_services/CognitiveServices.ts b/src/client/cognitive_services/CognitiveServices.ts
index ce829eb1e..542ccf04d 100644
--- a/src/client/cognitive_services/CognitiveServices.ts
+++ b/src/client/cognitive_services/CognitiveServices.ts
@@ -371,9 +371,9 @@ export namespace CognitiveServices {
                 let args = { method: 'POST', uri: Utils.prepend("/recommender"), body: { keyphrases: keyterms }, json: true };
                 await requestPromise.post(args).then(async (wordvecs) => {
                     if (wordvecs) {
-                        let indices = Object.keys(wordvecs);
+                        const indices = Object.keys(wordvecs);
                         console.log("successful vectorization!");
-                        var vectorValues = new List<number>();
+                        const vectorValues = new List<number>();
                         indices.forEach((ind: any) => {
                             //console.log(wordvec.word);
                             vectorValues.push(wordvecs[ind]);
@@ -389,9 +389,9 @@ export namespace CognitiveServices {
             }
 
             export const analyzer = async (dataDoc: Doc, target: Doc, keys: string[], data: string, converter: TextConverter, isMainDoc: boolean = false, isInternal: boolean = true) => {
-                let results = await ExecuteQuery(Service.Text, Manager, data);
+                const results = await ExecuteQuery(Service.Text, Manager, data);
                 console.log("Cognitive Services keyphrases: ", results);
-                let { keyterms, external_recommendations, kp_string } = await converter(results, data);
+                const { keyterms, external_recommendations, kp_string } = await converter(results, data);
                 target[keys[0]] = keyterms;
                 if (isInternal) {
                     //await vectorize([data], dataDoc, isMainDoc);
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 162a8fffe..c41304b9f 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -209,7 +209,7 @@ export class DocumentManager {
             const maxLocation = StrCast(linkDoc.maximizeLocation, "inTab");
             const targetContext = !Doc.AreProtosEqual(linkFollowDocContexts[reverse ? 1 : 0], currentContext) ? linkFollowDocContexts[reverse ? 1 : 0] : undefined;
             const target = linkFollowDocs[reverse ? 1 : 0];
-            let annotatedDoc = await Cast(target.annotationOn, Doc);
+            const annotatedDoc = await Cast(target.annotationOn, Doc);
             if (annotatedDoc) {
                 annotatedDoc.currentTimecode !== undefined && (target.currentTimecode = linkFollowTimecodes[reverse ? 1 : 0]);
             } else {
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index dab5c842c..c11675894 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -198,7 +198,7 @@ export namespace DragManager {
             dropDoc && !dropDoc.creationDate && (dropDoc.creationDate = new DateField);
             dropDoc instanceof Doc && AudioBox.ActiveRecordings.map(d => DocUtils.MakeLink({ doc: dropDoc }, { doc: d }, "audio link", "audio timeline"));
             return dropDoc;
-        }
+        };
         const finishDrag = (e: DragCompleteEvent) => {
             e.docDragData && (e.docDragData.droppedDocuments =
                 dragData.draggedDocuments.map(d => !dragData.isSelectionMove && !dragData.userDropAction && ScriptCast(d.onDragStart) ? addAudioTag(ScriptCast(d.onDragStart).script.run({ this: d }).result) :
diff --git a/src/client/util/ProsemirrorExampleTransfer.ts b/src/client/util/ProsemirrorExampleTransfer.ts
index ec5d1e72a..5cbf401d4 100644
--- a/src/client/util/ProsemirrorExampleTransfer.ts
+++ b/src/client/util/ProsemirrorExampleTransfer.ts
@@ -180,7 +180,7 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, props: any
             return true;
         }
         return false;
-    }
+    };
     bind("Alt-Enter", (state: EditorState<S>, dispatch: (tx: Transaction<Schema<any, any>>) => void) => {
         return addTextOnRight(true);
     });
diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx
index 0adf060ec..31935df3e 100644
--- a/src/client/util/RichTextSchema.tsx
+++ b/src/client/util/RichTextSchema.tsx
@@ -889,10 +889,10 @@ export class DashFieldView {
             e.stopPropagation();
             const collview = await Doc.addFieldEnumerations(self._textBoxDoc, node.attrs.fieldKey, [{ title: self._fieldSpan.innerText }]);
             collview instanceof Doc && tbox.props.addDocTab(collview, "onRight");
-        }
+        };
         const updateText = (forceMatch: boolean) => {
             self._enumerables.style.display = "none";
-            let newText = self._fieldSpan.innerText.startsWith(":=") || self._fieldSpan.innerText.startsWith("=:=") ? ":=-computed-" : self._fieldSpan.innerText;
+            const newText = self._fieldSpan.innerText.startsWith(":=") || self._fieldSpan.innerText.startsWith("=:=") ? ":=-computed-" : self._fieldSpan.innerText;
 
             // look for a document whose id === the fieldKey being displayed.  If there's a match, then that document
             // holds the different enumerated values for the field in the titles of its collected documents.
@@ -909,12 +909,12 @@ export class DashFieldView {
 
                 // if the text starts with a ':=' then treat it as an expression by making a computed field from its value storing it in the key
                 if (self._fieldSpan.innerText.startsWith(":=") && self._dashDoc) {
-                    self._dashDoc![self._fieldKey] = ComputedField.MakeFunction(self._fieldSpan.innerText.substring(2));
+                    self._dashDoc[self._fieldKey] = ComputedField.MakeFunction(self._fieldSpan.innerText.substring(2));
                 } else if (self._fieldSpan.innerText.startsWith("=:=") && self._dashDoc) {
                     Doc.Layout(tbox.props.Document)[self._fieldKey] = ComputedField.MakeFunction(self._fieldSpan.innerText.substring(3));
                 }
             });
-        }
+        };
 
         this._fieldSpan = document.createElement("div");
         this._fieldSpan.id = Utils.GenerateGuid();
@@ -926,14 +926,14 @@ export class DashFieldView {
         this._fieldSpan.onkeypress = function (e: any) { e.stopPropagation(); };
         this._fieldSpan.onkeyup = function (e: any) { e.stopPropagation(); };
         this._fieldSpan.onmousedown = function (e: any) { e.stopPropagation(); self._enumerables.style.display = "inline-block"; };
-        this._fieldSpan.onblur = function (e: any) { updateText(false); }
+        this._fieldSpan.onblur = function (e: any) { updateText(false); };
 
         const setDashDoc = (doc: Doc) => {
             self._dashDoc = doc;
             if (self._dashDoc && self._options?.length && !self._dashDoc[node.attrs.fieldKey]) {
                 self._dashDoc[node.attrs.fieldKey] = StrCast(self._options[0].title);
             }
-        }
+        };
         this._fieldSpan.onkeydown = function (e: any) {
             e.stopPropagation();
             if ((e.key === "a" && e.ctrlKey) || (e.key === "a" && e.metaKey)) {
@@ -976,7 +976,7 @@ export class DashFieldView {
                 alias._pivotField = self._fieldKey;
                 tbox.props.addDocTab(alias, "onRight");
             }
-        }
+        };
         this._labelSpan.innerHTML = `${node.attrs.fieldKey}: `;
         if (node.attrs.docid) {
             DocServer.GetRefField(node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && runInAction(() => setDashDoc(dashDoc)));
diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts
index 64874b994..2d9c807dd 100644
--- a/src/client/util/SearchUtil.ts
+++ b/src/client/util/SearchUtil.ts
@@ -121,12 +121,12 @@ export namespace SearchUtil {
 
     export async function GetAllDocs() {
         const query = "*";
-        let response = await rp.get(Utils.prepend('/search'), {
+        const response = await rp.get(Utils.prepend('/search'), {
             qs:
                 { start: 0, rows: 10000, q: query },
 
         });
-        let result: IdSearchResult = JSON.parse(response);
+        const result: IdSearchResult = JSON.parse(response);
         const { ids, numFound, highlighting } = result;
         //console.log(ids.length);
         const docMap = await DocServer.GetRefFields(ids);
diff --git a/src/client/views/KeyphraseQueryView.tsx b/src/client/views/KeyphraseQueryView.tsx
index a9dafc4a4..1dc156968 100644
--- a/src/client/views/KeyphraseQueryView.tsx
+++ b/src/client/views/KeyphraseQueryView.tsx
@@ -15,8 +15,8 @@ export class KeyphraseQueryView extends React.Component<KP_Props>{
     }
 
     render() {
-        let kps = this.props.keyphrases.toString();
-        let keyterms = this.props.keyphrases.split(',');
+        const kps = this.props.keyphrases.toString();
+        const keyterms = this.props.keyphrases.split(',');
         return (
             <div>
                 <h5>Select queries to send:</h5>
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index db8f7d5e4..00e22d6fb 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -138,8 +138,8 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
                 }
             }
             return false;
-        }
-        let retVal = !instance?._goldenLayout.root.contentItems[0].isRow ? false :
+        };
+        const retVal = !instance?._goldenLayout.root.contentItems[0].isRow ? false :
             Array.from(instance._goldenLayout.root.contentItems[0].contentItems).some((child: any) => Array.from(child.contentItems).some(tryClose));
 
         retVal && instance.stateChanged();
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 527623ad4..b995fc7d5 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -107,7 +107,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
         get childLayoutPairs(): { layout: Doc; data: Doc; }[] {
             const { Document, DataDoc } = this.props;
             const validPairs = this.childDocs.map(doc => Doc.GetLayoutDataDocPair(Document, !this.props.annotationsKey ? DataDoc : undefined, doc)).filter(pair => pair.layout);
-            return validPairs.map(({ data, layout }) => ({ data: data!, layout: layout! })); // this mapping is a bit of a hack to coerce types
+            return validPairs.map(({ data, layout }) => ({ data, layout: layout! })); // this mapping is a bit of a hack to coerce types
         }
         get childDocList() {
             return Cast(this.dataField, listSpec(Doc));
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 28f8bc048..7adafea0e 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -801,7 +801,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
                 this.props.Document.scrollY = NumCast(doc.y) - offset;
             }
 
-            afterFocus && setTimeout(() => afterFocus?.(), 1000);
+            afterFocus && setTimeout(afterFocus, 1000);
         } else {
             const layoutdoc = Doc.Layout(doc);
             const newPanX = NumCast(doc.x) + NumCast(layoutdoc._width) / 2;
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
index bd20781dc..aa8e1fb43 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
@@ -223,7 +223,7 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu
      */
     @computed
     private get contents(): JSX.Element[] | null {
-        let { childLayoutPairs } = this;
+        const { childLayoutPairs } = this;
         const { Document, PanelHeight } = this.props;
         const collector: JSX.Element[] = [];
         for (let i = 0; i < childLayoutPairs.length; i++) {
diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx
index ac4f8a3cf..b7f3dd995 100644
--- a/src/client/views/linking/LinkEditor.tsx
+++ b/src/client/views/linking/LinkEditor.tsx
@@ -253,8 +253,8 @@ export class LinkGroupEditor extends React.Component<LinkGroupEditorProps> {
     render() {
         const groupType = StrCast(this.props.groupDoc.linkRelationship);
         // if ((groupType && LinkManager.Instance.getMetadataKeysInGroup(groupType).length > 0) || groupType === "") {
-        let buttons = <button className="linkEditor-button" disabled={groupType === ""} onClick={() => this.deleteGroup(groupType)} title="Delete Relationship from all links"><FontAwesomeIcon icon="trash" size="sm" /></button>;
-        let addButton = <button className="linkEditor-addbutton" onClick={() => this.addMetadata(groupType)} disabled={groupType === ""} title="Add metadata to relationship"><FontAwesomeIcon icon="plus" size="sm" /></button>;
+        const buttons = <button className="linkEditor-button" disabled={groupType === ""} onClick={() => this.deleteGroup(groupType)} title="Delete Relationship from all links"><FontAwesomeIcon icon="trash" size="sm" /></button>;
+        const addButton = <button className="linkEditor-addbutton" onClick={() => this.addMetadata(groupType)} disabled={groupType === ""} title="Add metadata to relationship"><FontAwesomeIcon icon="plus" size="sm" /></button>;
 
         return (
             <div className="linkEditor-group">
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 3c8b1c3b8..47883db4e 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -50,7 +50,6 @@ export class AudioBox extends DocExtendableComponent<FieldViewProps, AudioDocume
     _recordStart = 0;
     _stream: MediaStream | undefined;
 
-    public static START = 0;
     @observable private static _scrubTime = 0;
     @computed get audioState(): undefined | "recording" | "paused" | "playing" { return this.dataDoc.audioState as (undefined | "recording" | "paused" | "playing"); }
     set audioState(value) { this.dataDoc.audioState = value; }
@@ -146,8 +145,7 @@ export class AudioBox extends DocExtendableComponent<FieldViewProps, AudioDocume
         }).then(function (stream) {
             self._stream = stream;
             self._recorder = new MediaRecorder(stream);
-            self.dataDoc[self.props.fieldKey + "-recordingStart"] = new DateField(new Date());
-            AudioBox.START = new DateField(new Date()).date.getTime();
+            self.dataDoc[self.props.fieldKey + "-recordingStart"] = new DateField(new Date()); \
             AudioBox.ActiveRecordings.push(self.props.Document);
             self._recorder.ondataavailable = async function (e: any) {
                 const formData = new FormData();
@@ -208,7 +206,7 @@ export class AudioBox extends DocExtendableComponent<FieldViewProps, AudioDocume
             _width: NumCast(this.props.Document._width), _height: 3 * NumCast(this.props.Document._height)
         });
         Doc.GetProto(newDoc).recordingSource = this.dataDoc;
-        Doc.GetProto(newDoc).recordingStart = 0;
+        Doc.GetProto(newDoc).recordingStart = ComputedField.MakeFunction(`this.recordingSource[${this.props.fieldKey}+"-recordingStart"]`);
         Doc.GetProto(newDoc).audioState = ComputedField.MakeFunction("this.recordingSource.audioState");
         this.props.addDocument?.(newDoc);
         e.stopPropagation();
diff --git a/src/client/views/nodes/DocuLinkBox.tsx b/src/client/views/nodes/DocuLinkBox.tsx
index a0f5b3152..bc663d084 100644
--- a/src/client/views/nodes/DocuLinkBox.tsx
+++ b/src/client/views/nodes/DocuLinkBox.tsx
@@ -113,7 +113,7 @@ export class DocuLinkBox extends DocComponent<FieldViewProps, DocLinkSchema>(Doc
     openLinkEditor = action((e: React.MouseEvent) => {
         SelectionManager.DeselectAll();
         this._editing = this._forceOpen = true;
-    })
+    });
 
     specificContextMenu = (e: React.MouseEvent): void => {
         const funcs: ContextMenuProps[] = [];
@@ -135,7 +135,7 @@ export class DocuLinkBox extends DocComponent<FieldViewProps, DocLinkSchema>(Doc
         const targetTitle = StrCast((this.props.Document[anchor]! as Doc).title) + (timecode !== undefined ? ":" + timecode : "");
         const flyout = (
             <div className="docuLinkBox-flyout" title=" " onPointerOver={() => Doc.UnBrushDoc(this.props.Document)}>
-                <LinkEditor sourceDoc={Cast(this.props.Document[this.props.fieldKey], Doc, null)!} hideback={true} linkDoc={this.props.Document} showLinks={action(() => { })} />
+                <LinkEditor sourceDoc={Cast(this.props.Document[this.props.fieldKey], Doc, null)} hideback={true} linkDoc={this.props.Document} showLinks={action(() => { })} />
                 {!this._forceOpen ? (null) : <div className="docuLinkBox-linkCloser" onPointerDown={action(() => this._isOpen = this._editing = this._forceOpen = false)}>
                     <FontAwesomeIcon color="dimGray" icon={"times"} size={"sm"} />
                 </div>}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 63c6b9f88..a1cba4c2e 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -571,9 +571,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             else if (de.complete.docDragData.draggedDocuments[0].type === "text") {
                 const text = Cast(de.complete.docDragData.draggedDocuments[0].data, RichTextField)?.Text;
                 if (text && text[0] === "{" && text[text.length - 1] === "}" && text.includes(":")) {
-                    let loc = text.indexOf(":");
-                    let key = text.slice(1, loc);
-                    let value = text.slice(loc + 1, text.length - 1);
+                    const loc = text.indexOf(":");
+                    const key = text.slice(1, loc);
+                    const value = text.slice(loc + 1, text.length - 1);
                     console.log(key);
                     console.log(value);
                     console.log(this.props.Document);
@@ -756,7 +756,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             // a.download = `DocExport-${this.props.Document[Id]}.zip`;
             // a.click();
         });
-        let recommender_subitems: ContextMenuProps[] = [];
+        const recommender_subitems: ContextMenuProps[] = [];
 
         recommender_subitems.push({
             description: "Internal recommendations",
@@ -764,7 +764,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             icon: "brain"
         });
 
-        let ext_recommender_subitems: ContextMenuProps[] = [];
+        const ext_recommender_subitems: ContextMenuProps[] = [];
 
         ext_recommender_subitems.push({
             description: "arXiv",
@@ -872,7 +872,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             }
         }));
         const doclist = ClientRecommender.Instance.computeSimilarities("cosine");
-        let recDocs: { preview: Doc, score: number }[] = [];
+        const recDocs: { preview: Doc, score: number }[] = [];
         // tslint:disable-next-line: prefer-for-of
         for (let i = 0; i < doclist.length; i++) {
             recDocs.push({ preview: doclist[i].actualDoc, score: doclist[i].score });
@@ -1113,7 +1113,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             </> :
                 this.innards}
         </div>;
-        { this._showKPQuery ? <KeyphraseQueryView keyphrases={this._queries}></KeyphraseQueryView> : undefined }
+        { this._showKPQuery ? <KeyphraseQueryView keyphrases={this._queries}></KeyphraseQueryView> : undefined; }
     }
 }
 
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 7f5f8538a..1fa603cbd 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -20,7 +20,7 @@ import { InkTool } from '../../../new_fields/InkField';
 import { RichTextField } from "../../../new_fields/RichTextField";
 import { RichTextUtils } from '../../../new_fields/RichTextUtils';
 import { createSchema, makeInterface } from "../../../new_fields/Schema";
-import { Cast, NumCast, StrCast, BoolCast } from "../../../new_fields/Types";
+import { Cast, NumCast, StrCast, BoolCast, DateCast } from "../../../new_fields/Types";
 import { TraceMobx } from '../../../new_fields/util';
 import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, numberRange, returnOne, Utils, returnTrue } from '../../../Utils';
 import { GoogleApiClientUtils, Pulls, Pushes } from '../../apis/google_docs/GoogleApiClientUtils';
@@ -420,11 +420,11 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
             //this._editorView!.focus();
         });
     }
-    stopDictation = (abort: boolean) => { DictationManager.Controls.stop(!abort); }
+    stopDictation = (abort: boolean) => { DictationManager.Controls.stop(!abort); };
 
     @action
     toggleMenubar = () => {
-        this.props.Document._chromeStatus = this.props.Document._chromeStatus == "disabled" ? "enabled" : "disabled";
+        this.props.Document._chromeStatus = this.props.Document._chromeStatus === "disabled" ? "enabled" : "disabled";
     }
 
     recordBullet = async () => {
@@ -444,12 +444,8 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
 
     setCurrentBulletContent = (value: string) => {
         if (this._editorView) {
-            let state = this._editorView.state;
-            let now = Date.now();
-            if (NumCast(this.props.Document.recordingStart, -1) === 0) {
-                this.props.Document.recordingStart = now = AudioBox.START;
-            }
-            console.log("NOW = " + (now - AudioBox.START) / 1000);
+            const state = this._editorView.state;
+            const now = Date.now();
             let mark = schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(now / 1000) });
             if (!this._break && state.selection.to !== state.selection.from) {
                 for (let i = state.selection.from; i <= state.selection.to; i++) {
@@ -461,9 +457,9 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
                     }
                 }
             }
+            const recordingStart = DateCast(this.props.Document.recordingStart).date.getTime();
             this._break = false;
-            console.log("start = " + (mark.attrs.modified * 1000 - AudioBox.START) / 1000);
-            value = "" + (mark.attrs.modified * 1000 - AudioBox.START) / 1000 + value;
+            value = "" + (mark.attrs.modified * 1000 - recordingStart) / 1000 + value;
             const from = state.selection.from;
             const inserted = state.tr.insertText(value).addMark(from, from + value.length + 1, mark);
             this._editorView.dispatch(inserted.setSelection(TextSelection.create(inserted.doc, from, from + value.length + 1)));
@@ -867,7 +863,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
         if (this._recording && !e.ctrlKey && e.button === 0) {
             this.stopDictation(true);
             this._break = true;
-            let state = this._editorView!.state;
+            const state = this._editorView!.state;
             const to = state.selection.to;
             const updated = TextSelection.create(state.doc, to, to);
             this._editorView!.dispatch(this._editorView!.state.tr.setSelection(updated).insertText("\n", to));
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index f47620c24..4076128b2 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -94,11 +94,11 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
         !this.Document._fitWidth && (this.Document._height = this.Document[WidthSym]() * (nh / nw));
     }
 
-    public search = (string: string, fwd: boolean) => { this._pdfViewer?.search(string, fwd); }
-    public prevAnnotation = () => { this._pdfViewer?.prevAnnotation(); }
-    public nextAnnotation = () => { this._pdfViewer?.nextAnnotation(); }
-    public backPage = () => { this._pdfViewer!.gotoPage((this.Document.curPage || 1) - 1); }
-    public forwardPage = () => { this._pdfViewer!.gotoPage((this.Document.curPage || 1) + 1); }
+    public search = (string: string, fwd: boolean) => { this._pdfViewer?.search(string, fwd); };
+    public prevAnnotation = () => { this._pdfViewer?.prevAnnotation(); };
+    public nextAnnotation = () => { this._pdfViewer?.nextAnnotation(); };
+    public backPage = () => { this._pdfViewer!.gotoPage((this.Document.curPage || 1) - 1); };
+    public forwardPage = () => { this._pdfViewer!.gotoPage((this.Document.curPage || 1) + 1); };
     public gotoPage = (p: number) => { this._pdfViewer!.gotoPage(p); };
 
     @undoBatch
-- 
cgit v1.2.3-70-g09d2


From 4ae6b564896dd216c37fa38ffeee70ba0e671221 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sat, 28 Mar 2020 02:40:17 -0400
Subject: simplified linkDocs to not keep a context -- instead, link are made
 between aliases which have a context.  fixed clippings of PDFs to scroll
 correctly and resize in slideViews.  fixed slideViews to render 'text' and
 'data' instead of 'contents' and 'data'

---
 src/client/documents/Documents.ts                      |  6 ++----
 src/client/util/DocumentManager.ts                     |  2 +-
 src/client/views/DocumentButtonBar.tsx                 |  2 --
 src/client/views/collections/CollectionView.tsx        |  4 +++-
 .../collections/collectionFreeForm/MarqueeView.tsx     |  4 ++--
 src/client/views/nodes/DocuLinkBox.tsx                 |  3 ++-
 src/client/views/nodes/DocumentView.tsx                |  7 +++----
 src/client/views/nodes/FormattedTextBox.tsx            |  4 ++--
 src/client/views/nodes/PDFBox.tsx                      |  2 +-
 src/client/views/nodes/PresBox.tsx                     |  2 +-
 src/client/views/pdf/PDFViewer.tsx                     | 18 +++++++++++-------
 src/server/authentication/models/current_user_utils.ts |  2 +-
 12 files changed, 29 insertions(+), 27 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index b5cffaddd..dbea8062e 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -558,15 +558,13 @@ export namespace Docs {
             const linkDocProto = Doc.GetProto(doc);
             linkDocProto.anchor1 = source.doc;
             linkDocProto.anchor2 = target.doc;
-            linkDocProto.anchor1_context = source.ctx;
-            linkDocProto.anchor2_context = target.ctx;
             linkDocProto.anchor1_timecode = source.doc.currentTimecode || source.doc.displayTimecode;
             linkDocProto.anchor2_timecode = target.doc.currentTimecode || source.doc.displayTimecode;
 
             if (linkDocProto.layout_key1 === undefined) {
                 Cast(linkDocProto.proto, Doc, null).layout_key1 = DocuLinkBox.LayoutString("anchor1");
                 Cast(linkDocProto.proto, Doc, null).layout_key2 = DocuLinkBox.LayoutString("anchor2");
-                Cast(linkDocProto.proto, Doc, null).linkBoxExcludedKeys = new List(["treeViewExpandedView", "treeViewHideTitle", "removeDropProperties", "linkBoxExcludedKeys", "treeViewOpen", "proto", "aliasNumber", "isPrototype", "lastOpened", "creationDate", "author"]);
+                Cast(linkDocProto.proto, Doc, null).linkBoxExcludedKeys = new List(["treeViewExpandedView", "treeViewHideTitle", "removeDropProperties", "linkBoxExcludedKeys", "treeViewOpen", "aliasNumber", "isPrototype", "lastOpened", "creationDate", "author"]);
                 Cast(linkDocProto.proto, Doc, null).layoutKey = undefined;
             }
 
@@ -926,7 +924,7 @@ export namespace DocUtils {
         });
     }
 
-    export function MakeLink(source: { doc: Doc, ctx?: Doc }, target: { doc: Doc, ctx?: Doc }, linkRelationship: string = "", id?: string) {
+    export function MakeLink(source: { doc: Doc }, target: { doc: Doc }, linkRelationship: string = "", id?: string) {
         const sv = DocumentManager.Instance.getDocumentView(source.doc);
         if (sv && sv.props.ContainingCollectionDoc === target.doc) return;
         if (target.doc === CurrentUserUtils.UserDocument) return undefined;
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index c41304b9f..0c410c4ce 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -203,7 +203,7 @@ export class DocumentManager {
         const second = secondDocWithoutView ? [secondDocWithoutView] : secondDocs;
         const linkDoc = first.length ? first[0] : second.length ? second[0] : undefined;
         const linkFollowDocs = first.length ? [await first[0].anchor2 as Doc, await first[0].anchor1 as Doc] : second.length ? [await second[0].anchor1 as Doc, await second[0].anchor2 as Doc] : undefined;
-        const linkFollowDocContexts = first.length ? [await first[0].anchor2_context as Doc, await first[0].anchor1_context as Doc] : second.length ? [await second[0].anchor1_context as Doc, await second[0].anchor2_context as Doc] : [undefined, undefined];
+        const linkFollowDocContexts = first.length ? [await first[0].context as Doc, await first[0].context as Doc] : second.length ? [await second[0].context as Doc, await second[0].context as Doc] : [undefined, undefined];
         const linkFollowTimecodes = first.length ? [NumCast(first[0].anchor2_timecode), NumCast(first[0].anchor1_timecode)] : second.length ? [NumCast(second[0].anchor1_timecode), NumCast(second[0].anchor2_timecode)] : [undefined, undefined];
         if (linkFollowDocs && linkDoc) {
             const maxLocation = StrCast(linkDoc.maximizeLocation, "inTab");
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 8a33232b4..ef1d20e44 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -120,8 +120,6 @@ export class DocumentButtonBar extends React.Component<{ views: (DocumentView |
                 dragComplete: dropEv => {
                     const linkDoc = dropEv.linkDragData?.linkDocument as Doc; // equivalent to !dropEve.aborted since linkDocument is only assigned on a completed drop
                     if (this.view0 && linkDoc) {
-                        const proto = Doc.GetProto(linkDoc);
-                        proto.anchor1_context = this.view0.props.ContainingCollectionDoc;
                         Doc.GetProto(linkDoc).linkRelationship = "hyperlink";
 
                         const anchor2Title = linkDoc.anchor2 instanceof Doc ? StrCast(linkDoc.anchor2.title) : "-untitled-";
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 2386f2d5d..1542988e7 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -127,6 +127,7 @@ export class CollectionView extends Touchable<FieldViewProps> {
         const docList = DocListCast(targetDataDoc[this.props.fieldKey]);
         !docList.includes(doc) && (targetDataDoc[this.props.fieldKey] = new List<Doc>([...docList, doc]));  // DocAddToList may write to targetdataDoc's parent ... we don't want this. should really change GetProto to GetDataDoc and test for resolvedDataDoc there
         // Doc.AddDocToList(targetDataDoc, this.props.fieldKey, doc);
+        doc.context = this.props.Document;
         targetDataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now()));
         Doc.GetProto(doc).lastOpened = new DateField;
         return true;
@@ -141,7 +142,8 @@ export class CollectionView extends Touchable<FieldViewProps> {
         let index = value.reduce((p, v, i) => (v instanceof Doc && v === doc) ? i : p, -1);
         index = index !== -1 ? index : value.reduce((p, v, i) => (v instanceof Doc && Doc.AreProtosEqual(v, doc)) ? i : p, -1);
 
-        ContextMenu.Instance && ContextMenu.Instance.clearItems();
+        doc.context = undefined;
+        ContextMenu.Instance?.clearItems();
         if (index !== -1) {
             value.splice(index, 1);
             targetDataDoc[this.props.fieldKey] = new List<Doc>(value);
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 17bba9568..0f94bffd6 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -111,7 +111,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
             const template = FormattedTextBox.DefaultLayout;
             if (template instanceof Doc) {
                 tbox._width = NumCast(template._width);
-                tbox.layoutKey = "layout_"+StrCast(template.title);
+                tbox.layoutKey = "layout_" + StrCast(template.title);
                 tbox[StrCast(tbox.layoutKey)] = template;
             }
             this.props.addLiveTextDocument(tbox);
@@ -448,7 +448,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
         summary._backgroundColor = "#e2ad32";
         portal.layoutKey = "layout_portal";
         portal.title = "document collection";
-        DocUtils.MakeLink({ doc: summary, ctx: this.props.ContainingCollectionDoc }, { doc: portal }, "summarizing");
+        DocUtils.MakeLink({ doc: summary }, { doc: portal }, "summarizing");
 
         this.props.addLiveTextDocument(summary);
         MarqueeOptionsMenu.Instance.fadeOut(true);
diff --git a/src/client/views/nodes/DocuLinkBox.tsx b/src/client/views/nodes/DocuLinkBox.tsx
index bc663d084..81cf90f92 100644
--- a/src/client/views/nodes/DocuLinkBox.tsx
+++ b/src/client/views/nodes/DocuLinkBox.tsx
@@ -84,9 +84,10 @@ export class DocuLinkBox extends DocComponent<FieldViewProps, DocLinkSchema>(Doc
         if (!this._doubleTap) {
             this._editing = true;
             this.props.ContainingCollectionDoc && this.props.bringToFront(this.props.ContainingCollectionDoc, false);
+            const {clientX, clientY} = e;
             if (!this.props.Document.onClick && !this._isOpen) {
                 this._timeout = setTimeout(action(() => {
-                    if (Math.abs(e.clientX - this._downX) < 3 && Math.abs(e.clientY - this._downY) < 3 && (e.button !== 2 && !e.ctrlKey && this.props.Document.isButton)) {
+                    if (Math.abs(clientX - this._downX) < 3 && Math.abs(clientY - this._downY) < 3 && (e.button !== 2 && !e.ctrlKey && this.props.Document.isButton)) {
                         DocumentManager.Instance.FollowLink(this.props.Document, this.props.ContainingCollectionDoc as Doc, document => this.props.addDocTab(document, StrCast(this.props.Document.linkOpenLocation, "inTab")), false);
                     }
                     this._editing = false;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 544c0a961..4968dd7fc 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -229,7 +229,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             dragData.dropAction = dropAction;
             dragData.moveDocument = this.props.moveDocument;//  this.Document.onDragStart ? undefined : this.props.moveDocument;
             dragData.dragDivName = this.props.dragDivName;
-            this.props.Document.anchor1_context = this.props.ContainingCollectionDoc; // bcz: !! shouldn't need this ... use search find the document's context dynamically
             DragManager.StartDocumentDrag([this._mainCont.current], dragData, x, y, { hideSource: !dropAction && !this.Document.onDragStart });
         }
     }
@@ -582,7 +581,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             e.stopPropagation();
             de.complete.annoDragData.linkedToDoc = true;
 
-            DocUtils.MakeLink({ doc: de.complete.annoDragData.annotationDocument }, { doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, "link");
+            DocUtils.MakeLink({ doc: de.complete.annoDragData.annotationDocument }, { doc: this.props.Document }, "link");
         }
         if (de.complete.docDragData) {
             if (de.complete.docDragData.applyAsTemplate) {
@@ -613,7 +612,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             // const views = docs.map(d => DocumentManager.Instance.getDocumentView(d)).filter(d => d).map(d => d as DocumentView);
             de.complete.linkDragData.linkSourceDocument !== this.props.Document &&
                 (de.complete.linkDragData.linkDocument = DocUtils.MakeLink({ doc: de.complete.linkDragData.linkSourceDocument },
-                    { doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, `link`)); // TODODO this is where in text links get passed
+                    { doc: this.props.Document }, `link`)); // TODODO this is where in text links get passed
         }
     }
 
@@ -639,7 +638,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         const portalLink = DocListCast(this.Document.links).find(d => d.anchor1 === this.props.Document);
         if (!portalLink) {
             const portal = Docs.Create.FreeformDocument([], { _width: (this.layoutDoc._width || 0) + 10, _height: this.layoutDoc._height || 0, title: StrCast(this.props.Document.title) + ".portal" });
-            DocUtils.MakeLink({ doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, { doc: portal }, "portal to");
+            DocUtils.MakeLink({ doc: this.props.Document }, { doc: portal }, "portal to");
         }
         this.Document.isButton = true;
     }
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index e7c9e5e6b..f83beade3 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -155,7 +155,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
                     this.dataDoc[key] = doc || Docs.Create.FreeformDocument([], { title: value, _width: 500, _height: 500 }, value);
                     DocUtils.Publish(this.dataDoc[key] as Doc, value, this.props.addDocument, this.props.removeDocument);
                     if (linkDoc) { (linkDoc as Doc).anchor2 = this.dataDoc[key] as Doc; }
-                    else DocUtils.MakeLink({ doc: this.dataDoc, ctx: this.props.ContainingCollectionDoc }, { doc: this.dataDoc[key] as Doc }, "link to named target", id);
+                    else DocUtils.MakeLink({ doc: this.props.Document }, { doc: this.dataDoc[key] as Doc }, "link to named target", id);
                 });
             });
         });
@@ -748,7 +748,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
                             targetAnnotations?.push(pdfRegion);
                         });
 
-                        const link = DocUtils.MakeLink({ doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, { doc: pdfRegion, ctx: pdfDoc }, "PDF pasted");
+                        const link = DocUtils.MakeLink({ doc: this.props.Document }, { doc: pdfRegion }, "PDF pasted");
                         if (link) {
                             cbe.clipboardData!.setData("dash/linkDoc", link[Id]);
                             const linkId = link[Id];
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 4076128b2..f8c008a2d 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -231,7 +231,7 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
     isChildActive = (outsideReaction?: boolean) => this._isChildActive;
     @computed get renderPdfView() {
         const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField);
-        return <div className={"pdfBox"} onContextMenu={this.specificContextMenu} style={{ height: this.props.Document._scrollTop ? NumCast(this.Document._height) * this.props.PanelWidth() / NumCast(this.Document._width) : undefined }}>
+        return <div className={"pdfBox"} onContextMenu={this.specificContextMenu} style={{ height: this.props.Document._scrollTop && !this.Document._fitWidth ? NumCast(this.Document._height) * this.props.PanelWidth() / NumCast(this.Document._width) : undefined }}>
             <PDFViewer {...this.props} pdf={this._pdf!} url={pdfUrl!.url.pathname} active={this.props.active} loaded={this.loaded}
                 setPdfViewer={this.setPdfViewer} ContainingCollectionView={this.props.ContainingCollectionView}
                 renderDepth={this.props.renderDepth} PanelHeight={this.props.PanelHeight} PanelWidth={this.props.PanelWidth}
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index ea3b7f12b..a39c337ca 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -164,7 +164,7 @@ export class PresBox extends React.Component<FieldViewProps> {
 
         //docToJump stayed same meaning, it was not in the group or was the last element in the group
         const aliasOf = await Cast(docToJump.aliasOf, Doc);
-        const srcContext = aliasOf && await Cast(aliasOf.anchor1_context, Doc);
+        const srcContext = aliasOf && await Cast(aliasOf.context, Doc);
         if (docToJump === curDoc) {
             //checking if curDoc has navigation open
             const target = await Cast(curDoc.presentationTargetDoc, Doc);
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index af06a2646..a1e7d5c2a 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -7,7 +7,7 @@ import { Doc, DocListCast, FieldResult, WidthSym, Opt, HeightSym } from "../../.
 import { Id, Copy } from "../../../new_fields/FieldSymbols";
 import { List } from "../../../new_fields/List";
 import { makeInterface, createSchema } from "../../../new_fields/Schema";
-import { ScriptField } from "../../../new_fields/ScriptField";
+import { ScriptField, ComputedField } from "../../../new_fields/ScriptField";
 import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
 import { smoothScroll, Utils, emptyFunction, returnOne, intersectRect, addStyleSheet, addStyleSheetRule, clearStyleSheetRules } from "../../../Utils";
 import { Docs, DocUtils } from "../../documents/Documents";
@@ -33,6 +33,7 @@ import { TraceMobx } from "../../../new_fields/util";
 import { PdfField } from "../../../new_fields/URLField";
 import { PDFBox } from "../nodes/PDFBox";
 import { FormattedTextBox } from "../nodes/FormattedTextBox";
+import { DocumentView } from "../nodes/DocumentView";
 const PDFJSViewer = require("pdfjs-dist/web/pdf_viewer");
 const pdfjsLib = require("pdfjs-dist");
 
@@ -210,7 +211,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
         this.props.setPdfViewer(this);
         await this.initialLoad();
 
-        this._scrollTopReactionDisposer = reaction(() => Cast(this.props.Document._scrollTop, "number", null),
+        this._scrollTopReactionDisposer = reaction(() => Cast(this.layoutDoc._scrollTop, "number", null),
             (stop) => (stop !== undefined) && this._mainCont.current && smoothScroll(500, this._mainCont.current, stop), { fireImmediately: true });
         this._annotationReactionDisposer = reaction(
             () => DocListCast(this.dataDoc[this.props.fieldKey + "-annotations"]),
@@ -567,12 +568,14 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
         e.preventDefault();
         e.stopPropagation();
 
-        const clipDoc = Docs.Create.PdfDocument(Cast(this.dataDoc[this.props.fieldKey], PdfField, null)?.url.href || "http://www.msn.com", { title: "snippetView", _fitWidth: true, _width: this.marqueeWidth(), _height: this.marqueeHeight(), _scrollTop: this.marqueeY() });
+        const clipDoc = Doc.MakeAlias(this.dataDoc);
+        clipDoc._fitWidth = true;
+        clipDoc._width = this.marqueeWidth();
+        clipDoc._height = this.marqueeHeight();
+        clipDoc._scrollTop = this.marqueeY();
         const targetDoc = Docs.Create.TextDocument("", { _width: 200, _height: 200, title: "Note linked to " + this.props.Document.title });
-        Doc.GetProto(targetDoc).layout = FormattedTextBox.LayoutString("contents");
         Doc.GetProto(targetDoc).data = new List<Doc>([clipDoc]);
-        Doc.GetProto(targetDoc).layout_slideView = (await Cast(Doc.UserDoc().slidesBtn, Doc))?.dragFactory;
-        targetDoc.layoutKey = "layout_slideView";
+        DocumentView.makeCustomViewClicked(targetDoc, undefined, Docs.Create.StackingDocument, "slideView", undefined);
         // const targetDoc = Docs.Create.TextDocument("", { _width: 200, _height: 200, title: "Note linked to " + this.props.Document.title });
         // Doc.GetProto(targetDoc).snipped = this.dataDoc[this.props.fieldKey][Copy]();
         // const snipLayout = Docs.Create.PdfDocument("http://www.msn.com", { title: "snippetView", isTemplateDoc: true, isTemplateForField: "snipped", _fitWidth: true, _width: this.marqueeWidth(), _height: this.marqueeHeight(), _scrollTop: this.marqueeY() });
@@ -582,7 +585,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
             DragManager.StartPdfAnnoDrag([ele], new DragManager.PdfAnnoDragData(this.props.Document, annotationDoc, targetDoc), e.pageX, e.pageY, {
                 dragComplete: e => {
                     if (!e.aborted && e.annoDragData && !e.annoDragData.linkedToDoc) {
-                        const link = DocUtils.MakeLink({ doc: annotationDoc }, { doc: e.annoDragData.dropDocument, ctx: e.annoDragData.targetContext }, "Annotation");
+                        const link = DocUtils.MakeLink({ doc: annotationDoc }, { doc: e.annoDragData.dropDocument }, "Annotation");
                         if (link) link.maximizeLocation = "onRight";
                     }
                 }
@@ -646,6 +649,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
                 setPreviewCursor={this.setPreviewCursor}
                 PanelHeight={this.panelWidth}
                 PanelWidth={this.panelHeight}
+                dropAction={"alias"}
                 VisibleHeight={this.visibleHeight}
                 focus={this.props.focus}
                 isSelected={this.props.isSelected}
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts
index cfa13cb44..cb2b8846b 100644
--- a/src/server/authentication/models/current_user_utils.ts
+++ b/src/server/authentication/models/current_user_utils.ts
@@ -265,7 +265,7 @@ export class CurrentUserUtils {
         const slideTemplate = Docs.Create.MultirowDocument(
             [
                 Docs.Create.MulticolumnDocument([], { title: "data", _height: 200 }),
-                Docs.Create.TextDocument("", { title: "contents", _height: 100 })
+                Docs.Create.TextDocument("", { title: "text", _height: 100 })
             ],
             { _width: 400, _height: 300, title: "slideView", _chromeStatus: "disabled", _xMargin: 3, _yMargin: 3, _autoHeight: false });
         slideTemplate.isTemplateDoc = makeTemplate(slideTemplate);
-- 
cgit v1.2.3-70-g09d2

