From 5adf15574ac6423e09617b3d756d98ea8cdc75c5 Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Mon, 17 Aug 2020 17:44:10 -0500
Subject: framework for web in top bar

---
 src/client/views/collections/CollectionMenu.tsx | 156 ++++++++++++++++++++++++
 1 file changed, 156 insertions(+)

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

diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 5119ff6c9..6fa907fc7 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -30,6 +30,7 @@ import { DocumentView } from "../nodes/DocumentView";
 import RichTextMenu from "../nodes/formattedText/RichTextMenu";
 import "./CollectionMenu.scss";
 import { CollectionViewType, COLLECTION_BORDER_WIDTH } from "./CollectionView";
+import { WebField } from "../../../fields/URLField";
 
 @observer
 export default class CollectionMenu extends AntimodeMenu {
@@ -605,6 +606,158 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu
             </div>;
     }
 
+    @action
+    onUrlDrop = (e: React.DragEvent) => {
+        const { dataTransfer } = e;
+        const html = dataTransfer.getData("text/html");
+        const uri = dataTransfer.getData("text/uri-list");
+        const url = uri || html || this._url;
+        this._url = url.startsWith(window.location.origin) ?
+            url.replace(window.location.origin, this._url.match(/http[s]?:\/\/[^\/]*/)?.[0] || "") : url;
+        this.submitURL();
+        e.stopPropagation();
+    }
+    onUrlDragover = (e: React.DragEvent) => {
+        e.preventDefault();
+    }
+
+    @computed get _url() {
+        return this.selectedDoc ? Cast(this.selectedDoc["data"], WebField, null)?.url.toString() : "hello";
+    }
+
+    set _url(value) { this.selectedDoc && (this.selectedDoc["data"] = value); }
+
+    @action
+    submitURL = () => {
+        if (!this._url.startsWith("http")) this._url = "http://" + this._url;
+        try {
+            const URLy = new URL(this._url);
+            const future = this.selectedDoc ? Cast(this.selectedDoc["data-future"], listSpec("string"), null) : null;
+            const history = this.selectedDoc ? Cast(this.selectedDoc["data-history"], listSpec("string"), null) : [];
+            const annos = this.selectedDoc ? DocListCast(this.selectedDoc["data-annotations"]) : undefined;
+            const url = this.selectedDoc ? Cast(this.selectedDoc["data"], WebField, null)?.url.toString() : null;
+            if (url) {
+                if (history === undefined) {
+                    this.selectedDoc && (this.selectedDoc["data-history"] = new List<string>([url]));
+
+                } else {
+                    history.push(url);
+                }
+                future && (future.length = 0);
+                this.selectedDoc && (this.selectedDoc["data-" + this.urlHash(url)] = new List<Doc>(annos));
+            }
+            this.selectedDoc && (this.selectedDoc["data"] = new WebField(URLy));
+            this.selectedDoc && (this.selectedDoc["data-annotations"] = new List<Doc>([]));
+        } catch (e) {
+            console.log("WebBox URL error:" + this._url);
+        }
+    }
+
+    urlHash(s: string) {
+        return s.split('').reduce((a: any, b: any) => { a = ((a << 5) - a) + b.charCodeAt(0); return a & a; }, 0);
+    }
+
+    toggleAnnotationMode = () => {
+        this.props.docView.layoutDoc.isAnnotating = !this.props.docView.layoutDoc.isAnnotating;
+    }
+
+    @action
+    onURLChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+        this._url = e.target.value;
+    }
+
+    onValueKeyDown = async (e: React.KeyboardEvent) => {
+        if (e.key === "Enter") {
+            this.submitURL();
+        }
+        e.stopPropagation();
+    }
+
+    @action
+    forward = () => {
+        const future = this.selectedDoc && (Cast(this.selectedDoc["data-future"], listSpec("string"), null));
+        const history = this.selectedDoc && Cast(this.selectedDoc["data-history"], listSpec("string"), null);
+        if (future?.length) {
+            history?.push(this._url);
+            this.selectedDoc && (this.selectedDoc["data-annotations-" + this.urlHash(this._url)] = new List<Doc>(DocListCast(this.selectedDoc["data-annotations"])));
+            this.selectedDoc && (this.selectedDoc["data"] = new WebField(new URL(this._url = future.pop()!)));
+            this.selectedDoc && (this.selectedDoc["data-annotations"] = new List<Doc>(DocListCast(this.selectedDoc["data-annotations" + "-" + this.urlHash(this._url)])));
+        }
+    }
+
+    @action
+    back = () => {
+        const future = this.selectedDoc && (Cast(this.selectedDoc["data-future"], listSpec("string"), null));
+        const history = this.selectedDoc && Cast(this.selectedDoc["data-history"], listSpec("string"), null);
+        if (history?.length) {
+            if (future === undefined) this.selectedDoc && (this.selectedDoc["data-future"] = new List<string>([this._url]));
+            else future.push(this._url);
+            this.selectedDoc && (this.selectedDoc["data-annotations" + "-" + this.urlHash(this._url)] = new List<Doc>(DocListCast(this.selectedDoc["data-annotations"])));
+            this.selectedDoc && (this.selectedDoc["data"] = new WebField(new URL(this._url = history.pop()!)));
+            this.selectedDoc && (this.selectedDoc["data-annotations"] = new List<Doc>(DocListCast(this.selectedDoc["data-annotations" + "-" + this.urlHash(this._url)])));
+        }
+    }
+
+    private _keyInput = React.createRef<HTMLInputElement>();
+
+    @computed get urlEditor() {
+        return (
+            <div className="webBox-urlEditor"
+                onDrop={this.onUrlDrop}
+                onDragOver={this.onUrlDragover} style={{ top: 0 }}>
+                <div className="urlEditor">
+                    <div className="editorBase">
+                        <div className="webBox-buttons"
+                            onDrop={this.onUrlDrop}
+                            onDragOver={this.onUrlDragover} style={{ display: "flex" }}>
+                            <div className="webBox-freeze" title={"Annotate"}
+                                style={{ background: this.props.docView.layoutDoc.isAnnotating ? "lightBlue" : "gray" }}
+                                onClick={this.toggleAnnotationMode} >
+                                <FontAwesomeIcon icon="pen" size={"2x"} />
+                            </div>
+                            <div className="webBox-freeze" title={"Select"}
+                                style={{ background: !this.props.docView.layoutDoc.isAnnotating ? "lightBlue" : "gray" }}
+                                onClick={this.toggleAnnotationMode} >
+                                <FontAwesomeIcon icon={"mouse-pointer"} size={"2x"} />
+                            </div>
+                            <input className="webpage-urlInput"
+                                placeholder="ENTER URL"
+                                value={this._url}
+                                onDrop={this.onUrlDrop}
+                                onDragOver={this.onUrlDragover}
+                                onChange={this.onURLChange}
+                                onKeyDown={this.onValueKeyDown}
+                                onClick={(e) => {
+                                    this._keyInput.current!.select();
+                                    e.stopPropagation();
+                                }}
+                                ref={this._keyInput}
+                            />
+                            <div style={{
+                                display: "flex",
+                                flexDirection: "row",
+                                justifyContent: "space-between",
+                                maxWidth: "120px",
+                            }}>
+                                <button className="submitUrl" onClick={this.submitURL}
+                                    onDragOver={this.onUrlDragover} onDrop={this.onUrlDrop}>
+                                    GO
+                                </button>
+                                <button className="submitUrl" onClick={this.back}>
+                                    <FontAwesomeIcon icon="caret-left" size="lg"></FontAwesomeIcon>
+                                </button>
+                                <button className="submitUrl" onClick={this.forward}>
+                                    <FontAwesomeIcon icon="caret-right" size="lg"></FontAwesomeIcon>
+                                </button>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        );
+    }
+
+
     @observable viewType = this.selectedDoc?._viewType;
 
     render() {
@@ -646,6 +799,9 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu
                         </button>
                     </Tooltip>
                 }
+                {/* {!this.props.isOverlay || this.document.type !== DocumentType.WEB || this.isText || this.props.isDoc ? (null) :
+                    this.urlEditor
+                } */}
                 {!this.isText ?
                     <>
                         {this.drawButtons}
-- 
cgit v1.2.3-70-g09d2


From 2473613caf8d9d397e3b132f95b136a0c26a1ebd Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 19 Aug 2020 19:06:31 -0400
Subject: fixed frame animations and added frames to bookmarked views.

---
 src/client/documents/Documents.ts                  |  2 --
 src/client/views/collections/CollectionMenu.tsx    | 21 +++++++++++----
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  4 +--
 .../views/nodes/CollectionFreeFormDocumentView.tsx | 31 +++++++++-------------
 src/client/views/nodes/PresBox.tsx                 | 26 +++++++++---------
 5 files changed, 44 insertions(+), 40 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index f07b718ba..7d114d417 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -144,8 +144,6 @@ export interface DocumentOptions {
     presTransition?: number; //the time taken for the transition TO a document
     presDuration?: number; //the duration of the slide in presentation view
     presProgressivize?: boolean;
-    // xArray?: number[];
-    // yArray?: number[];
     borderRounding?: string;
     boxShadow?: string;
     dontRegisterChildViews?: boolean;
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index b2e55adc7..28ba6945a 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -11,7 +11,6 @@ import { Id } from "../../../fields/FieldSymbols";
 import { InkTool } from "../../../fields/InkField";
 import { List } from "../../../fields/List";
 import { ObjectField } from "../../../fields/ObjectField";
-import { RichTextField } from "../../../fields/RichTextField";
 import { listSpec } from "../../../fields/Schema";
 import { ScriptField } from "../../../fields/ScriptField";
 import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types";
@@ -30,6 +29,7 @@ import { DocumentView } from "../nodes/DocumentView";
 import RichTextMenu from "../nodes/formattedText/RichTextMenu";
 import "./CollectionMenu.scss";
 import { CollectionViewType, COLLECTION_BORDER_WIDTH } from "./CollectionView";
+import { Scripting } from "../../util/Scripting";
 
 @observer
 export default class CollectionMenu extends AntimodeMenu<AntimodeMenuProps> {
@@ -161,9 +161,9 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
     };
     _viewCommand = {
         params: ["target"], title: "bookmark view",
-        script: "self.target._panX = self['target-panX']; self.target._panY = self['target-panY']; self.target._viewScale = self['target-viewScale'];",
-        immediate: undoBatch((source: Doc[]) => { this.target._panX = 0; this.target._panY = 0; this.target._viewScale = 1; }),
-        initialize: (button: Doc) => { button['target-panX'] = this.target._panX; button['target-panY'] = this.target._panY; button['target-viewScale'] = this.target._viewScale; },
+        script: "self.target._panX = self['target-panX']; self.target._panY = self['target-panY']; self.target._viewScale = self['target-viewScale']; gotoFrame(self.target, self['target-currentFrame']);",
+        immediate: undoBatch((source: Doc[]) => { this.target._panX = 0; this.target._panY = 0; this.target._viewScale = 1; this.target.currentFrame = 0; }),
+        initialize: (button: Doc) => { button['target-panX'] = this.target._panX; button['target-panY'] = this.target._panY; button['target-viewScale'] = this.target._viewScale; button['target-currentFrame'] = this.target.currentFrame; },
     };
     _clusterCommand = {
         params: ["target"], title: "fit content",
@@ -1078,4 +1078,15 @@ export class CollectionGridViewChrome extends React.Component<CollectionMenuProp
             </div>
         );
     }
-}
\ No newline at end of file
+}
+Scripting.addGlobal(function gotoFrame(doc: any, newFrame: any) {
+    const dataField = doc[Doc.LayoutFieldKey(doc)];
+    const childDocs = DocListCast(dataField);
+    const currentFrame = Cast(doc.currentFrame, "number", null);
+    if (currentFrame === undefined) {
+        doc.currentFrame = 0;
+        CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0);
+    }
+    CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0);
+    doc.currentFrame = Math.max(0, newFrame);
+});
\ No newline at end of file
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 5d6d7924e..f6bb375fc 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -179,7 +179,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
                 }
             }
             if (this.Document.currentFrame !== undefined && !this.props.isAnnotationOverlay) {
-                CollectionFreeFormDocumentView.setupKeyframes(newBoxes, this.Document.currentFrame);
+                CollectionFreeFormDocumentView.setupKeyframes(newBoxes, this.Document.currentFrame, true);
             }
         }
         return retVal;
@@ -214,7 +214,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
             const layoutDoc = Doc.Layout(d);
             if (this.Document.currentFrame !== undefined) {
                 const vals = CollectionFreeFormDocumentView.getValues(d, NumCast(d.activeFrame, 1000));
-                CollectionFreeFormDocumentView.setValues(this.Document.currentFrame, d, x + vals.x - dropPos[0], y + vals.y - dropPos[1], vals.h, vals.w, vals.opacity);
+                CollectionFreeFormDocumentView.setValues(this.Document.currentFrame, d, x + vals.x - dropPos[0], y + vals.y - dropPos[1], vals.h, vals.w, vals.scroll, vals.opacity);
             } else {
                 d.x = x + NumCast(d.x) - dropPos[0];
                 d.y = y + NumCast(d.y) - dropPos[1];
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 52f6a66c8..e1661039e 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -123,7 +123,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
         setTimeout(() => doc.dataTransition = "inherit", 1010);
     }
 
-    public static setupScroll(doc: Doc, timecode: number, scrollProgressivize: boolean = false) {
+    public static setupScroll(doc: Doc, timecode: number) {
         const scrollList = new List<number>();
         scrollList[timecode] = NumCast(doc._scrollTop);
         doc["scroll-indexed"] = scrollList;
@@ -165,7 +165,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
     }
 
 
-    public static setupZoom(doc: Doc, targDoc: Doc, zoomProgressivize: boolean = false) {
+    public static setupZoom(doc: Doc, targDoc: Doc) {
         const width = new List<number>();
         const height = new List<number>();
         const top = new List<number>();
@@ -180,31 +180,24 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
         doc["viewfinder-left-indexed"] = left;
     }
 
-    public static setupKeyframes(docs: Doc[], timecode: number, progressivize: boolean = false) {
-        docs.forEach((doc, i) => {
-            if (doc.appearFrame === undefined) doc.appearFrame = i;
-            const curTimecode = progressivize ? i : timecode;
-            const xlist = new List<number>(numberRange(timecode + 1).map(i => undefined) as any as number[]);
-            const ylist = new List<number>(numberRange(timecode + 1).map(i => undefined) as any as number[]);
-            const wlist = new List<number>(numberRange(timecode + 1).map(i => undefined) as any as number[]);
-            const hlist = new List<number>(numberRange(timecode + 1).map(i => undefined) as any as number[]);
-            const olist = new List<number>(numberRange(timecode + 1).map(t => progressivize && t < (doc.appearFrame ? doc.appearFrame : i) ? 0 : 1));
-            const oarray = olist;
-            oarray.fill(0, 0, NumCast(doc.appearFrame) - 1);
-            oarray.fill(1, NumCast(doc.appearFrame), timecode);
-            // oarray.fill(0, 0, NumCast(doc.appearFrame) - 1);
-            // oarray.fill(1, NumCast(doc.appearFrame), timecode);\
+    public static setupKeyframes(docs: Doc[], currTimecode: number, makeAppear: boolean = false) {
+        docs.forEach(doc => {
+            if (doc.appearFrame === undefined) doc.appearFrame = currTimecode;
+            const curTimecode = currTimecode;
+            const xlist = new List<number>(numberRange(currTimecode + 1).map(i => undefined) as any as number[]);
+            const ylist = new List<number>(numberRange(currTimecode + 1).map(i => undefined) as any as number[]);
+            const wlist = new List<number>(numberRange(currTimecode + 1).map(i => undefined) as any as number[]);
+            const hlist = new List<number>(numberRange(currTimecode + 1).map(i => undefined) as any as number[]);
+            const olist = new List<number>(numberRange(currTimecode + 1).map(t => !doc.z && makeAppear && t < NumCast(doc.appearFrame) ? 0 : 1));
             wlist[curTimecode] = NumCast(doc._width);
             hlist[curTimecode] = NumCast(doc._height);
             xlist[curTimecode] = NumCast(doc.x);
             ylist[curTimecode] = NumCast(doc.y);
-            doc.xArray = xlist;
-            doc.yArray = ylist;
             doc["x-indexed"] = xlist;
             doc["y-indexed"] = ylist;
             doc["w-indexed"] = wlist;
             doc["h-indexed"] = hlist;
-            doc["opacity-indexed"] = oarray;
+            doc["opacity-indexed"] = olist;
             doc.activeFrame = ComputedField.MakeFunction("self.context?.currentFrame||0");
             doc._height = ComputedField.MakeInterpolated("h", "activeFrame");
             doc._width = ComputedField.MakeInterpolated("w", "activeFrame");
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 5fc76223d..f39413e9f 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -1052,15 +1052,17 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         if (layout) doc = this.createTemplate(layout);
         if (freeform && layout) doc = this.createTemplate(layout, title);
         if (!freeform && !layout) doc = Docs.Create.TextDocument("", { _nativeWidth: 400, _width: 225, title: title });
-        const presCollection = Cast(this.layoutDoc.presCollection, Doc, null);
-        const data = Cast(presCollection?.data, listSpec(Doc));
-        const presData = Cast(this.rootDoc.data, listSpec(Doc));
-        if (data && doc && presData) {
-            data.push(doc);
-            DockedFrameRenderer.PinDoc(doc, false);
-            this.gotoDocument(this.childDocs.length, this.itemIndex);
-        } else {
-            this.props.addDocTab(doc as Doc, "onRight");
+        if (doc) {
+            const presCollection = Cast(this.layoutDoc.presCollection, Doc, null);
+            const data = Cast(presCollection?.data, listSpec(Doc));
+            const presData = Cast(this.rootDoc.data, listSpec(Doc));
+            if (data && presData) {
+                data.push(doc);
+                DockedFrameRenderer.PinDoc(doc, false);
+                this.gotoDocument(this.childDocs.length, this.itemIndex);
+            } else {
+                this.props.addDocTab(doc as Doc, "onRight");
+            }
         }
     }
 
@@ -1341,7 +1343,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         activeItem.scrollProgressivize = !activeItem.scrollProgressivize;
         const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
         targetDoc.scrollProgressivize = !targetDoc.scrollProgressivize;
-        CollectionFreeFormDocumentView.setupScroll(targetDoc, NumCast(targetDoc.currentFrame), true);
+        CollectionFreeFormDocumentView.setupScroll(targetDoc, NumCast(targetDoc.currentFrame));
         if (targetDoc.editScrollProgressivize) {
             targetDoc.editScrollProgressivize = false;
             targetDoc.currentFrame = 0;
@@ -1357,7 +1359,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         activeItem.zoomProgressivize = !activeItem.zoomProgressivize;
         const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
         targetDoc.zoomProgressivize = !targetDoc.zoomProgressivize;
-        CollectionFreeFormDocumentView.setupZoom(activeItem, targetDoc, true);
+        CollectionFreeFormDocumentView.setupZoom(activeItem, targetDoc);
         if (activeItem.editZoomProgressivize) {
             activeItem.editZoomProgressivize = false;
             targetDoc.currentFrame = 0;
@@ -1390,7 +1392,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             activeItem.presProgressivize = true;
             targetDoc.presProgressivize = true;
             targetDoc.currentFrame = 0;
-            CollectionFreeFormDocumentView.setupKeyframes(docs, docs.length, true);
+            docs.forEach((doc, i) => CollectionFreeFormDocumentView.setupKeyframes([doc], i, true));
             targetDoc.lastFrame = docs.length - 1;
         } else {
             targetDoc.editProgressivize = false;
-- 
cgit v1.2.3-70-g09d2


From da8901bef2d4a0362354c69fe486076a67f8efc4 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 19 Aug 2020 22:39:51 -0400
Subject: cleaning lint errors

---
 src/client/views/PropertiesButtons.tsx                    |  2 +-
 src/client/views/collections/CollectionMenu.tsx           | 12 ++++++------
 src/client/views/collections/CollectionSchemaCells.tsx    | 11 ++---------
 src/client/views/collections/CollectionSchemaHeaders.tsx  |  2 +-
 src/client/views/collections/SchemaTable.tsx              |  2 +-
 src/client/views/nodes/DocumentView.tsx                   |  2 +-
 src/client/views/nodes/PresBox.tsx                        |  2 +-
 src/client/views/nodes/formattedText/FormattedTextBox.tsx | 10 ++++++----
 src/fields/Doc.ts                                         | 10 +++++-----
 9 files changed, 24 insertions(+), 29 deletions(-)

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

diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index e352db562..9e776c652 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -301,7 +301,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
             const dragData = new DragManager.DocumentDragData([this.selectedDoc]);
             const [left, top] = [e.clientX, e.clientY];
             dragData.dropAction = "alias";
-            DragManager.StartDocumentDrag([this._dragRef.current!], dragData, left, top, {
+            DragManager.StartDocumentDrag([this._dragRef.current], dragData, left, top, {
                 offsetX: dragData.offset[0],
                 offsetY: dragData.offset[1],
                 hideSource: false
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index cf053e1ca..388eda2b3 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -624,10 +624,10 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu
     }
 
     @computed get _url() {
-        return this.selectedDoc ? Cast(this.selectedDoc["data"], WebField, null)?.url.toString() : "hello";
+        return this.selectedDoc ? Cast(this.selectedDoc.data, WebField, null)?.url.toString() : "hello";
     }
 
-    set _url(value) { this.selectedDoc && (this.selectedDoc["data"] = value); }
+    set _url(value) { this.selectedDoc && (this.selectedDoc.data = value); }
 
     @action
     submitURL = () => {
@@ -637,7 +637,7 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu
             const future = this.selectedDoc ? Cast(this.selectedDoc["data-future"], listSpec("string"), null) : null;
             const history = this.selectedDoc ? Cast(this.selectedDoc["data-history"], listSpec("string"), null) : [];
             const annos = this.selectedDoc ? DocListCast(this.selectedDoc["data-annotations"]) : undefined;
-            const url = this.selectedDoc ? Cast(this.selectedDoc["data"], WebField, null)?.url.toString() : null;
+            const url = this.selectedDoc ? Cast(this.selectedDoc.data, WebField, null)?.url.toString() : null;
             if (url) {
                 if (history === undefined) {
                     this.selectedDoc && (this.selectedDoc["data-history"] = new List<string>([url]));
@@ -648,7 +648,7 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu
                 future && (future.length = 0);
                 this.selectedDoc && (this.selectedDoc["data-" + this.urlHash(url)] = new List<Doc>(annos));
             }
-            this.selectedDoc && (this.selectedDoc["data"] = new WebField(URLy));
+            this.selectedDoc && (this.selectedDoc.data = new WebField(URLy));
             this.selectedDoc && (this.selectedDoc["data-annotations"] = new List<Doc>([]));
         } catch (e) {
             console.log("WebBox URL error:" + this._url);
@@ -682,7 +682,7 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu
         if (future?.length) {
             history?.push(this._url);
             this.selectedDoc && (this.selectedDoc["data-annotations-" + this.urlHash(this._url)] = new List<Doc>(DocListCast(this.selectedDoc["data-annotations"])));
-            this.selectedDoc && (this.selectedDoc["data"] = new WebField(new URL(this._url = future.pop()!)));
+            this.selectedDoc && (this.selectedDoc.data = new WebField(new URL(this._url = future.pop()!)));
             this.selectedDoc && (this.selectedDoc["data-annotations"] = new List<Doc>(DocListCast(this.selectedDoc["data-annotations" + "-" + this.urlHash(this._url)])));
         }
     }
@@ -695,7 +695,7 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu
             if (future === undefined) this.selectedDoc && (this.selectedDoc["data-future"] = new List<string>([this._url]));
             else future.push(this._url);
             this.selectedDoc && (this.selectedDoc["data-annotations" + "-" + this.urlHash(this._url)] = new List<Doc>(DocListCast(this.selectedDoc["data-annotations"])));
-            this.selectedDoc && (this.selectedDoc["data"] = new WebField(new URL(this._url = history.pop()!)));
+            this.selectedDoc && (this.selectedDoc.data = new WebField(new URL(this._url = history.pop()!)));
             this.selectedDoc && (this.selectedDoc["data-annotations"] = new List<Doc>(DocListCast(this.selectedDoc["data-annotations" + "-" + this.urlHash(this._url)])));
         }
     }
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index 626ddf288..ea786800c 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -778,17 +778,10 @@ export class CollectionSchemaListCell extends CollectionSchemaCell {
     @observable private _text = "select an item";
     @observable private _selectedNum = 0;
 
-    @action
-    toggleOpened(open: boolean) {
-        this._opened = open;
-    }
-
     @action
     onSetValue = (value: string) => {
-        this._text = value;
-
         // change if its a document
-        this._optionsList[this._selectedNum] = this._text;
+        this._optionsList[this._selectedNum] = this._text = value;
 
         (this.prop.Document[this.prop.fieldKey] as List<any>).splice(this._selectedNum, 1, value);
     }
@@ -854,7 +847,7 @@ export class CollectionSchemaListCell extends CollectionSchemaCell {
                     <div className="collectionSchemaView-cellContents" key={this._document[Id]} ref={reference}>
                         <div className="collectionSchemaView-dropDownWrapper">
                             <button type="button" className="collectionSchemaView-dropdownButton" style={{ right: "length", position: "relative" }}
-                                onClick={e => this.toggleOpened(!this._opened)} >
+                                onClick={action(e => this._opened = !this._opened)} >
                                 <FontAwesomeIcon icon={this._opened ? "caret-up" : "caret-down"} size="lg" />
                             </button>
                             <div className="collectionSchemaView-dropdownText"> {link ? plainText : textarea} </div>
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index 73f319e9b..34a8bfa24 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -275,7 +275,7 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
         document.removeEventListener("pointerdown", this.detectClick);
         const filters = Cast(this.props.Document._docFilters, listSpec("string"));
         if (filters?.includes(this._key)) {
-            runInAction(() => { this.closeResultsVisibility = "contents" });
+            runInAction(() => this.closeResultsVisibility = "contents");
         }
     }
 
diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx
index 489c5e540..6ec9783e2 100644
--- a/src/client/views/collections/SchemaTable.tsx
+++ b/src/client/views/collections/SchemaTable.tsx
@@ -415,7 +415,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     createRow = action(() => {
         this.props.addDocument(Docs.Create.TextDocument("", { title: "", _width: 100, _height: 30 }));
         this._focusedCell = { row: this.childDocs.length, col: this._focusedCell.col };
-    })
+    });
 
     @undoBatch
     @action
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 7cf6b0f39..590befd86 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -713,7 +713,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         }
 
         const cm = ContextMenu.Instance;
-        if (!cm || ((e as any)?.nativeEvent as any)?.SchemaHandled) return;
+        if (!cm || (e?.nativeEvent as any)?.SchemaHandled) return;
 
         const customScripts = Cast(this.props.Document.contextMenuScripts, listSpec(ScriptField), []);
         Cast(this.props.Document.contextMenuLabels, listSpec("string"), []).forEach((label, i) =>
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index f39413e9f..d30ea03b1 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -1061,7 +1061,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                 DockedFrameRenderer.PinDoc(doc, false);
                 this.gotoDocument(this.childDocs.length, this.itemIndex);
             } else {
-                this.props.addDocTab(doc as Doc, "onRight");
+                this.props.addDocTab(doc, "onRight");
             }
         }
     }
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index d58d75226..6b4115e53 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -510,10 +510,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
             let index = 0, foundAt;
             const ep = this.getNodeEndpoints(pm.state.doc, node);
             const regexp = find.replace("*", "");
-            if (regexp) while (ep && (foundAt = node.textContent.slice(index).search(regexp, "i")) > -1) {
-                const sel = new TextSelection(pm.state.doc.resolve(ep.from + index + foundAt + 1), pm.state.doc.resolve(ep.from + index + foundAt + find.length + 1));
-                ret.push(sel);
-                index = index + foundAt + find.length;
+            if (regexp) {
+                while (ep && (foundAt = node.textContent.slice(index).search(regexp)) > -1) {
+                    const sel = new TextSelection(pm.state.doc.resolve(ep.from + index + foundAt + 1), pm.state.doc.resolve(ep.from + index + foundAt + find.length + 1));
+                    ret.push(sel);
+                    index = index + foundAt + find.length;
+                }
             }
         } else {
             node.content.forEach((child, i) => ret = ret.concat(this.findInNode(pm, child, find)));
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 4797fb4cb..3fdeb8e71 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -206,11 +206,11 @@ export class Doc extends RefField {
 
     private [Self] = this;
     private [SelfProxy]: any;
-    public [FieldsSym] = (clear?: boolean) => { return clear ? this.___fields = this.___fieldKeys = {} : this.___fields; }
-    public [WidthSym] = () => { return NumCast(this[SelfProxy]._width); }
-    public [HeightSym] = () => { return NumCast(this[SelfProxy]._height); }
-    public [ToScriptString] = () => { return `DOC-"${this[Self][Id]}"-`; }
-    public [ToString] = () => { return `Doc(${GetEffectiveAcl(this) === AclPrivate ? "-inaccessible-" : this.title})`; }
+    public [FieldsSym] = (clear?: boolean) => clear ? this.___fields = this.___fieldKeys = {} : this.___fields;
+    public [WidthSym] = () => NumCast(this[SelfProxy]._width);
+    public [HeightSym] = () => NumCast(this[SelfProxy]._height);
+    public [ToScriptString] = () => `DOC-"${this[Self][Id]}"-`;
+    public [ToString] = () => `Doc(${GetEffectiveAcl(this) === AclPrivate ? "-inaccessible-" : this.title})`;
     public get [LayoutSym]() { return this[SelfProxy].__LAYOUT__; }
     public get [DataSym]() {
         const self = this[SelfProxy];
-- 
cgit v1.2.3-70-g09d2

