From 74b5ef7cd5f91d4483a407585bca0f6b93883208 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 3 Dec 2020 15:21:52 -0500
Subject: fixed background lock icon

---
 src/client/views/collections/TabDocView.tsx | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

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

diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 1026f043c..61650da6c 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -32,7 +32,6 @@ import React = require("react");
 import { List } from '../../../fields/List';
 import { DocumentType } from '../../documents/DocumentTypes';
 import Color = require('color');
-import { InkTool } from '../../../fields/InkField';
 const _global = (window /* browser */ || global /* node */) as any;
 
 interface TabDocViewProps {
@@ -417,9 +416,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
         }
     }
 
-    @undoBatch
-    @action
-    static toggleBackground = (doc: Doc) => {
+    static toggleBackground = undoBatch(action((doc: Doc) => {
         const layers = StrListCast(doc.layers);
         if (!layers.includes("background")) {
             if (!layers.length) doc.layers = new List<string>(["background"]);
@@ -434,7 +431,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
             // Doc.SetNativeWidth(this.props.Document[DataSym], wid);
             // Doc.SetNativeHeight(this.props.Document[DataSym], hgt);
         }
-    }
+    }))
     //
     // a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab
     // 
-- 
cgit v1.2.3-70-g09d2


From ff791402919478bf153179a6629752f2066edc29 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 7 Dec 2020 14:03:46 -0500
Subject: fixed lists to allow multiple null-value entries & be able to edit in
 KeyValuePane.  cleaned up a lot of stuff with animation frames and got
 working again.  fixed previews of links to text selections to preview
 properly.

---
 src/client/views/ScriptBox.tsx                     |   1 -
 src/client/views/collections/TabDocView.tsx        |   2 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |   7 +-
 .../views/nodes/CollectionFreeFormDocumentView.tsx | 144 +++++++--------------
 src/client/views/nodes/LinkDocPreview.tsx          |   8 +-
 .../views/nodes/formattedText/FormattedTextBox.tsx | 140 ++++++++++++--------
 src/fields/Doc.ts                                  |   1 +
 src/fields/ScriptField.ts                          |  17 ++-
 src/server/websocket.ts                            |   4 +-
 9 files changed, 159 insertions(+), 165 deletions(-)

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

diff --git a/src/client/views/ScriptBox.tsx b/src/client/views/ScriptBox.tsx
index 2c185be86..e2b5d8dc3 100644
--- a/src/client/views/ScriptBox.tsx
+++ b/src/client/views/ScriptBox.tsx
@@ -12,7 +12,6 @@ import { CompileScript } from "../util/Scripting";
 import { ScriptField } from "../../fields/ScriptField";
 import { DragManager } from "../util/DragManager";
 import { EditableView } from "./EditableView";
-import { getEffectiveTypeRoots } from "typescript";
 
 export interface ScriptBoxProps {
     onSave: (text: string, onError: (error: string) => void) => void;
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 61650da6c..a8a95bf08 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -431,7 +431,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
             // Doc.SetNativeWidth(this.props.Document[DataSym], wid);
             // Doc.SetNativeHeight(this.props.Document[DataSym], hgt);
         }
-    }))
+    }));
     //
     // a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab
     // 
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index ab0c3964b..fa84e5539 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -222,14 +222,17 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
         const zsorted = this.childLayoutPairs.map(pair => pair.layout).slice().sort((doc1, doc2) => NumCast(doc1.zIndex) - NumCast(doc2.zIndex));
         zsorted.forEach((doc, index) => doc.zIndex = doc.isInkMask ? 5000 : index + 1);
         const dvals = CollectionFreeFormDocumentView.getValues(refDoc, NumCast(refDoc.activeFrame, 1000));
-        const dropPos = this.Document._currentFrame !== undefined ? [dvals.x, dvals.y] : [NumCast(refDoc.x), NumCast(refDoc.y)];
+        const dropPos = this.Document._currentFrame !== undefined ? [dvals.x || 0, dvals.y || 0] : [NumCast(refDoc.x), NumCast(refDoc.y)];
         for (let i = 0; i < docDragData.droppedDocuments.length; i++) {
             const d = docDragData.droppedDocuments[i];
             const layoutDoc = Doc.Layout(d);
             if (this.Document._currentFrame !== undefined) {
                 CollectionFreeFormDocumentView.setupKeyframes([d], this.Document._currentFrame, false);
                 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, this.Document.editScrollProgressivize ? vals.scroll : undefined, vals.opacity);
+                vals.x = x + (vals.x || 0) - dropPos[0];
+                vals.y = y + (vals.y || 0) - dropPos[1];
+                vals._scrollTop = this.Document.editScrollProgressivize ? vals._scrollTop : undefined;
+                CollectionFreeFormDocumentView.setValues(this.Document._currentFrame, d, vals);
             } 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 94793ffff..942182191 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -1,25 +1,23 @@
-import { computed, IReactionDisposer, observable, reaction, trace, action } from "mobx";
+import { action, computed, observable } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, HeightSym, WidthSym } from "../../../fields/Doc";
+import { Bounce, Fade, Flip, LightSpeed, Roll, Rotate, Zoom } from 'react-reveal';
+import { Doc, HeightSym, WidthSym, Opt } from "../../../fields/Doc";
+import { Document } from "../../../fields/documentSchemas";
+import { List } from "../../../fields/List";
+import { listSpec } from "../../../fields/Schema";
+import { ComputedField } from "../../../fields/ScriptField";
 import { Cast, NumCast, StrCast } from "../../../fields/Types";
+import { TraceMobx } from "../../../fields/util";
+import { numberRange, returnVal } from "../../../Utils";
+import { DocumentType } from "../../documents/DocumentTypes";
 import { Transform } from "../../util/Transform";
 import { DocComponent } from "../DocComponent";
+import { InkingStroke } from "../InkingStroke";
 import "./CollectionFreeFormDocumentView.scss";
-import { DocumentView, DocumentViewProps } from "./DocumentView";
-import React = require("react");
-import { Document } from "../../../fields/documentSchemas";
-import { TraceMobx } from "../../../fields/util";
 import { ContentFittingDocumentView } from "./ContentFittingDocumentView";
-import { List } from "../../../fields/List";
-import { numberRange, smoothScroll, returnVal } from "../../../Utils";
-import { ComputedField } from "../../../fields/ScriptField";
-import { listSpec } from "../../../fields/Schema";
-import { DocumentType } from "../../documents/DocumentTypes";
-import { Zoom, Fade, Flip, Rotate, Bounce, Roll, LightSpeed } from 'react-reveal';
+import { DocumentView, DocumentViewProps } from "./DocumentView";
 import { PresBox, PresEffect } from "./PresBox";
-import { InkingStroke } from "../InkingStroke";
-import { SnappingManager } from "../../util/SnappingManager";
-import { InkTool } from "../../../fields/InkField";
+import React = require("react");
 
 export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
     dataProvider?: (doc: Doc, replica: string) => { x: number, y: number, zIndex?: number, opacity?: number, highlight?: boolean, z: number, transition?: string } | undefined;
@@ -62,46 +60,24 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
     @computed get nativeWidth() { return returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, undefined, this.freezeDimensions)); }
     @computed get nativeHeight() { return returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, undefined, this.freezeDimensions)); }
 
+    static animFields = ["_height", "_width", "x", "y", "_scrollTop", "opacity"];
     public static getValues(doc: Doc, time: number) {
-        const timecode = Math.round(time);
-        return ({
-            h: Cast(doc["h-indexed"], listSpec("number"), [NumCast(doc._height)]).reduce((p, h, i) => (i <= timecode && h !== undefined) || p === undefined ? h : p, undefined as any as number),
-            w: Cast(doc["w-indexed"], listSpec("number"), [NumCast(doc._width)]).reduce((p, w, i) => (i <= timecode && w !== undefined) || p === undefined ? w : p, undefined as any as number),
-            x: Cast(doc["x-indexed"], listSpec("number"), [NumCast(doc.x)]).reduce((p, x, i) => (i <= timecode && x !== undefined) || p === undefined ? x : p, undefined as any as number),
-            y: Cast(doc["y-indexed"], listSpec("number"), [NumCast(doc.y)]).reduce((p, y, i) => (i <= timecode && y !== undefined) || p === undefined ? y : p, undefined as any as number),
-            scroll: Cast(doc["scroll-indexed"], listSpec("number"), [NumCast(doc._scrollTop, 0)]).reduce((p, s, i) => (i <= timecode && s !== undefined) || p === undefined ? s : p, undefined as any as number),
-            opacity: Cast(doc["opacity-indexed"], listSpec("number"), [NumCast(doc.opacity, 1)]).reduce((p, o, i) => i <= timecode || p === undefined ? o : p, undefined as any as number),
-        });
+        return CollectionFreeFormDocumentView.animFields.reduce((p, val) => {
+            p[val] = Cast(`${val}-indexed`, listSpec("number"), [NumCast(doc[val])]).reduce((p, v, i) => (i <= Math.round(time) && v !== undefined) || p === undefined ? v : p, undefined as any as number);
+            return p;
+        }, {} as { [val: string]: Opt<number> });
     }
 
-    public static setValues(time: number, d: Doc, x?: number, y?: number, h?: number, w?: number, scroll?: number, opacity?: number) {
+    public static setValues(time: number, d: Doc, vals: { [val: string]: Opt<number> }) {
         const timecode = Math.round(time);
-        const hindexed = Cast(d["h-indexed"], listSpec("number"), []).slice();
-        const windexed = Cast(d["w-indexed"], listSpec("number"), []).slice();
-        const xindexed = Cast(d["x-indexed"], listSpec("number"), []).slice();
-        const yindexed = Cast(d["y-indexed"], listSpec("number"), []).slice();
-        const oindexed = Cast(d["opacity-indexed"], listSpec("number"), []).slice();
-        const scrollIndexed = Cast(d["scroll-indexed"], listSpec("number"), []).slice();
-        xindexed[timecode] = x as any as number;
-        yindexed[timecode] = y as any as number;
-        hindexed[timecode] = h as any as number;
-        windexed[timecode] = w as any as number;
-        oindexed[timecode] = opacity as any as number;
-        if (scroll) scrollIndexed[timecode] = scroll as any as number;
-        d["x-indexed"] = new List<number>(xindexed);
-        d["y-indexed"] = new List<number>(yindexed);
-        d["h-indexed"] = new List<number>(hindexed);
-        d["w-indexed"] = new List<number>(windexed);
-        d["opacity-indexed"] = new List<number>(oindexed);
-        d["scroll-indexed"] = new List<number>(scrollIndexed);
-        if (d.appearFrame) {
-            if (d.appearFrame === timecode + 1) {
-                d["text-color"] = "red";
-            } else if (d.appearFrame < timecode + 1) {
-                d["text-color"] = "grey";
-            } else { d["text-color"] = "black"; }
-        } else if (d.appearFrame === 0) {
-        }
+        Object.keys(vals).forEach(val => {
+            const findexed = Cast(d[`${val}-indexed`], listSpec("number"), []).slice();
+            findexed[timecode] = vals[val] as any as number;
+            d[`${val}-indexed`] = new List<number>(findexed);
+        });
+        d.appearFrame && (d["text-color"] =
+            d.appearFrame === timecode + 1 ? "red" :
+                d.appearFrame < timecode + 1 ? "grey" : "black");
     }
 
     // public static updateScrollframe(doc: Doc, time: number) {
@@ -123,37 +99,26 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
 
     public static updateKeyframe(docs: Doc[], time: number, targetDoc?: Doc) {
         const timecode = Math.round(time);
-        docs.forEach(doc => {
-            const xindexed = Cast(doc['x-indexed'], listSpec("number"), null);
-            const yindexed = Cast(doc['y-indexed'], listSpec("number"), null);
-            const hindexed = Cast(doc['h-indexed'], listSpec("number"), null);
-            const windexed = Cast(doc['w-indexed'], listSpec("number"), null);
-            const opacityindexed = Cast(doc['opacity-indexed'], listSpec("number"), null);
-            hindexed?.length <= timecode + 1 && hindexed.push(undefined as any as number);
-            windexed?.length <= timecode + 1 && windexed.push(undefined as any as number);
-            xindexed?.length <= timecode + 1 && xindexed.push(undefined as any as number);
-            yindexed?.length <= timecode + 1 && yindexed.push(undefined as any as number);
-            opacityindexed?.length <= timecode + 1 && opacityindexed.push(undefined as any as number);
-            if (doc.appearFrame && targetDoc) {
-                if (doc.appearFrame === timecode + 1) {
-                    doc["text-color"] = StrCast(targetDoc["pres-text-color"]);
-                } else if (doc.appearFrame < timecode + 1) {
-                    doc["text-color"] = StrCast(targetDoc["pres-text-viewed-color"]);
-                } else { doc["text-color"] = "black"; }
-            } else if (doc.appearFrame === 0) {
-                doc["text-color"] = "black";
-            }
-            doc.dataTransition = "all 1s";
-        });
-        setTimeout(() => docs.forEach(doc => doc.dataTransition = "inherit"), 1010);
+        docs.forEach(action(doc => {
+            doc._viewTransition = doc.dataTransition = "all 1s";
+            doc["text-color"] =
+                !doc.appearFrame || !targetDoc ? "black" :
+                    doc.appearFrame === timecode + 1 ? StrCast(targetDoc["pres-text-color"]) :
+                        doc.appearFrame < timecode + 1 ? StrCast(targetDoc["pres-text-viewed-color"]) :
+                            "black";
+            CollectionFreeFormDocumentView.animFields.forEach(val => {
+                const findexed = Cast(doc[`${val}-indexed`], listSpec("number"), null);
+                findexed?.length <= timecode + 1 && findexed.push(undefined as any as number);
+            });
+        }));
+        setTimeout(() => docs.forEach(doc => { doc._viewTransition = undefined; doc.dataTransition = "inherit"; }), 1010);
     }
 
     public static gotoKeyframe(docs: Doc[]) {
-        docs.forEach(doc => doc.dataTransition = "all 1s");
-        setTimeout(() => docs.forEach(doc => doc.dataTransition = "inherit"), 1010);
+        docs.forEach(doc => doc._viewTransition = doc.dataTransition = "all 1s");
+        setTimeout(() => docs.forEach(doc => { doc._viewTransition = undefined; doc.dataTransition = "inherit" }), 1010);
     }
 
-
     public static setupZoom(doc: Doc, targDoc: Doc) {
         const width = new List<number>();
         const height = new List<number>();
@@ -172,27 +137,12 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
     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["x-indexed"] = xlist;
-            doc["y-indexed"] = ylist;
-            doc["w-indexed"] = wlist;
-            doc["h-indexed"] = hlist;
-            doc["opacity-indexed"] = olist;
+            if (!doc["opacity-indexed"]) { // opacity is unlike other fields because it's value should not be undefined before it appears to enable it to fade-in
+                const olist = new List<number>(numberRange(currTimecode + 1).map(t => !doc.z && makeAppear && t < NumCast(doc.appearFrame) ? 0 : 1));
+                doc["opacity-indexed"] = olist;
+            }
+            CollectionFreeFormDocumentView.animFields.forEach(val => doc[val] = ComputedField.MakeInterpolated(val, "activeFrame", doc, currTimecode));
             doc.activeFrame = ComputedField.MakeFunction("self.context?._currentFrame||0");
-            doc._height = ComputedField.MakeInterpolated("h", "activeFrame");
-            doc._width = ComputedField.MakeInterpolated("w", "activeFrame");
-            doc.x = ComputedField.MakeInterpolated("x", "activeFrame");
-            doc.y = ComputedField.MakeInterpolated("y", "activeFrame");
-            doc.opacity = ComputedField.MakeInterpolated("opacity", "activeFrame");
             doc.dataTransition = "inherit";
         });
     }
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index 0256d394e..c4bb2b8d8 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -12,6 +12,7 @@ import { ContentFittingDocumentView } from "./ContentFittingDocumentView";
 import { DocumentLinksButton } from './DocumentLinksButton';
 import React = require("react");
 import { DocumentViewProps } from './DocumentView';
+import { Id } from '../../../fields/FieldSymbols';
 
 interface Props {
     linkDoc?: Doc;
@@ -64,8 +65,11 @@ export class LinkDocPreview extends React.Component<Props> {
             runInAction(() => {
                 this._toolTipText = "";
                 LinkDocPreview.TargetDoc = this._targetDoc = target;
-                if (anchor !== this._targetDoc && anchor && this._targetDoc) {
-                    this._targetDoc._scrollPreviewY = NumCast(anchor?.y);
+                if (this._targetDoc) {
+                    this._targetDoc._scrollToPreviewLinkID = linkDoc?.[Id];
+                    if (anchor !== this._targetDoc && anchor) {
+                        this._targetDoc._scrollPreviewY = NumCast(anchor?.y);
+                    }
                 }
             });
         }
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 125447f28..6768acce4 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -61,6 +61,7 @@ import { DocumentManager } from '../../../util/DocumentManager';
 import { CollectionStackingView } from '../../collections/CollectionStackingView';
 import { CollectionViewType } from '../../collections/CollectionView';
 import { SnappingManager } from '../../../util/SnappingManager';
+import { LinkDocPreview } from '../LinkDocPreview';
 
 export interface FormattedTextBoxProps {
     makeLink?: () => Opt<Doc>;  // bcz: hack: notifies the text document when the container has made a link.  allows the text doc to react and setup a hyeprlink for any selected text
@@ -98,6 +99,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
     private _currentTime: number = 0;
     private _linkTime: number | null = null;
     private _pause: boolean = false;
+    private _animatingScroll: numher = 0; // hack to prevent scroll values from being written to document when scroll is animating
 
     @computed get _recording() { return this.dataDoc?.audioState === "recording"; }
     set _recording(value) {
@@ -815,6 +817,50 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         return this.active();//this.props.isSelected() || this._isChildActive || this.props.renderDepth === 0;
     }
 
+    scrollToLinkId = (linkId: string) => {
+        const findLinkFrag = (frag: Fragment, editor: EditorView) => {
+            const nodes: Node[] = [];
+            let hadStart = start !== 0;
+            frag.forEach((node, index) => {
+                const examinedNode = findLinkNode(node, editor);
+                if (examinedNode?.node.textContent) {
+                    nodes.push(examinedNode.node);
+                    !hadStart && (start = index + examinedNode.start);
+                    hadStart = true;
+                }
+            });
+            return { frag: Fragment.fromArray(nodes), start };
+        };
+        const findLinkNode = (node: Node, editor: EditorView) => {
+            if (!node.isText) {
+                const content = findLinkFrag(node.content, editor);
+                return { node: node.copy(content.frag), start: content.start };
+            }
+            const marks = [...node.marks];
+            const linkIndex = marks.findIndex(mark => mark.type === editor.state.schema.marks.linkAnchor);
+            return linkIndex !== -1 && marks[linkIndex].attrs.allLinks.find((item: { href: string }) => linkId === item.href.replace(/.*\/doc\//, "")) ? { node, start: 0 } : undefined;
+        };
+
+        let start = 0;
+        if (this._editorView && linkId) {
+            const editor = this._editorView;
+            const ret = findLinkFrag(editor.state.doc.content, editor);
+
+            if (ret.frag.size > 2 && ret.start >= 0) {
+                let selection = TextSelection.near(editor.state.doc.resolve(ret.start)); // default to near the start
+                if (ret.frag.firstChild) {
+                    selection = TextSelection.between(editor.state.doc.resolve(ret.start), editor.state.doc.resolve(ret.start + ret.frag.firstChild.nodeSize)); // bcz: looks better to not have the target selected
+                }
+                editor.dispatch(editor.state.tr.setSelection(new TextSelection(selection.$from, selection.$from)).scrollIntoView());
+                const mark = editor.state.schema.mark(this._editorView.state.schema.marks.search_highlight);
+                setTimeout(() => editor.dispatch(editor.state.tr.addMark(selection.from, selection.to, mark)), 0);
+                setTimeout(() => this.unhighlightSearchTerms(), 2000);
+            }
+            Doc.SetInPlace(this.layoutDoc, "scrollToLinkID", undefined, false);
+            Doc.SetInPlace(this.layoutDoc, "_scrollToPreviewLinkID", undefined, false);
+        }
+    }
+
     componentDidMount() {
         this.props.contentsActive?.(this.IsActive);
         this._cachedLinks = DocListCast(this.Document.links);
@@ -910,7 +956,13 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
             search => search ? this.highlightSearchTerms([Doc.SearchQuery()], search.searchMatch < 0) : this.unhighlightSearchTerms(),
             { fireImmediately: Doc.IsSearchMatchUnmemoized(this.rootDoc) ? true : false });
 
-        this._disposers.selected = reaction(() => this.props.isSelected(), action(() => this._recording = false));
+        this._disposers.selected = reaction(() => this.props.isSelected(),
+            action((selected) => {
+                this._recording = false;
+                if (RichTextMenu.Instance?.view === this._editorView && !selected) {
+                    RichTextMenu.Instance?.updateMenu(undefined, undefined, undefined);
+                }
+            }));
 
         if (!this.props.dontRegisterView) {
             this._disposers.record = reaction(() => this._recording,
@@ -924,65 +976,36 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                 }
             );
         }
-        this._disposers.scrollToRegion = reaction(
-            () => StrCast(this.layoutDoc.scrollToLinkID),
-            async (scrollToLinkID) => {
-                const findLinkFrag = (frag: Fragment, editor: EditorView) => {
-                    const nodes: Node[] = [];
-                    let hadStart = start !== 0;
-                    frag.forEach((node, index) => {
-                        const examinedNode = findLinkNode(node, editor);
-                        if (examinedNode?.node.textContent) {
-                            nodes.push(examinedNode.node);
-                            !hadStart && (start = index + examinedNode.start);
-                            hadStart = true;
-                        }
-                    });
-                    return { frag: Fragment.fromArray(nodes), start };
-                };
-                const findLinkNode = (node: Node, editor: EditorView) => {
-                    if (!node.isText) {
-                        const content = findLinkFrag(node.content, editor);
-                        return { node: node.copy(content.frag), start: content.start };
-                    }
-                    const marks = [...node.marks];
-                    const linkIndex = marks.findIndex(mark => mark.type === editor.state.schema.marks.linkAnchor);
-                    return linkIndex !== -1 && marks[linkIndex].attrs.allLinks.find((item: { href: string }) => scrollToLinkID === item.href.replace(/.*\/doc\//, "")) ? { node, start: 0 } : undefined;
-                };
-
-                let start = 0;
-                if (this._editorView && scrollToLinkID) {
-                    const editor = this._editorView;
-                    const ret = findLinkFrag(editor.state.doc.content, editor);
-
-                    if (ret.frag.size > 2 && ret.start >= 0) {
-                        let selection = TextSelection.near(editor.state.doc.resolve(ret.start)); // default to near the start
-                        if (ret.frag.firstChild) {
-                            selection = TextSelection.between(editor.state.doc.resolve(ret.start), editor.state.doc.resolve(ret.start + ret.frag.firstChild.nodeSize)); // bcz: looks better to not have the target selected
-                        }
-                        editor.dispatch(editor.state.tr.setSelection(new TextSelection(selection.$from, selection.$from)).scrollIntoView());
-                        const mark = editor.state.schema.mark(this._editorView.state.schema.marks.search_highlight);
-                        setTimeout(() => editor.dispatch(editor.state.tr.addMark(selection.from, selection.to, mark)), 0);
-                        setTimeout(() => this.unhighlightSearchTerms(), 2000);
-                    }
-                    Doc.SetInPlace(this.layoutDoc, "scrollToLinkID", undefined, false);
-                }
-
-            },
-            { fireImmediately: true }
+        this._disposers.previewScrollToRegion = reaction(() => StrCast(this.layoutDoc._scrollToPreviewLinkID),
+            scrollToLinkID => this.props.renderDepth === -1 && scrollToLinkID && this.scrollToLinkId(scrollToLinkID), { fireImmediately: true }
+        );
+        this._disposers.scrollToRegion = reaction(() => StrCast(this.layoutDoc.scrollToLinkID),
+            scrollToLinkID => scrollToLinkID && this.scrollToLinkId(scrollToLinkID), { fireImmediately: true }
         );
         this._disposers.scroll = reaction(() => NumCast(this.layoutDoc._scrollTop),
-            pos => this._scrollRef.current?.scrollTo({ top: pos }), { fireImmediately: true }
+            pos => {
+                const durationMiliStr = StrCast(this.Document._viewTransition).match(/([0-9]*)ms/);
+                const durationSecStr = StrCast(this.Document._viewTransition).match(/([0-9.]*)s/);
+                const duration = durationMiliStr ? Number(durationMiliStr[1]) : durationSecStr ? Number(durationSecStr[1]) * 1000 : 0;
+                if (duration) {
+                    this._animatingScroll++;
+                    this._scrollRef.current && smoothScroll(duration, this._scrollRef.current, Math.abs(pos || 0));
+                    setTimeout(() => this._animatingScroll--, duration);
+                } else {
+                    this._scrollRef.current?.scrollTo({ top: pos });
+                }
+            }, { fireImmediately: true }
         );
         this._disposers.scrollY = reaction(() => Cast(this.layoutDoc._scrollY, "number", null),
-            scrollY => {
-                if (scrollY !== undefined) {
-                    const delay = this._scrollRef.current ? 0 : 250; // wait for mainCont and try again to scroll
-                    const durationStr = StrCast(this.Document._viewTransition).match(/([0-9]*)ms/);
-                    const duration = durationStr ? Number(durationStr[1]) : 1000;
-                    setTimeout(() => this._scrollRef.current && smoothScroll(duration, this._scrollRef.current, Math.abs(scrollY || 0)), delay);
-                    setTimeout(() => { this.Document._scrollTop = scrollY; this.Document._scrollY = undefined; }, duration + delay);
-                }
+            pos => {
+                this.Document._scrollY = undefined;
+                pos !== undefined && setTimeout(() => this.layoutDoc._scrollTop = pos, this._scrollRef.current ? 0 : 250);
+            }, { fireImmediately: true }
+        );
+        this._disposers.scrollPreviewY = reaction(() => Cast(this.layoutDoc.scrollPreviewY, "number", null),
+            pos => {
+                this.Document.scrollPreviewY = undefined;
+                pos !== undefined && setTimeout(() => this.layoutDoc._scrollTop = pos, this._scrollRef.current ? 0 : 250);
             }, { fireImmediately: true }
         );
 
@@ -1233,6 +1256,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
 
     componentWillUnmount() {
         this.endUndoTypingBatch();
+        this.unhighlightSearchTerms();
         Object.values(this._disposers).forEach(disposer => disposer?.());
         this._editorView?.destroy();
         FormattedTextBoxComment.tooltip && (FormattedTextBoxComment.tooltip.style.display = "none");
@@ -1529,7 +1553,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         eve.stopPropagation(); // drag n drop of text within text note will generate a new note if not caughst, as will dragging in from outside of Dash.
     }
     onscrolled = (ev: React.UIEvent) => {
-        this.layoutDoc._scrollTop = this._scrollRef.current!.scrollTop;
+        if (!LinkDocPreview.TargetDoc && !FormattedTextBoxComment.linkDoc && !this._animatingScroll) {
+            this.layoutDoc._scrollTop = this._scrollRef.current!.scrollTop;
+        }
     }
     @action
     tryUpdateHeight(limitHeight?: number) {
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index ffb1bbf83..fdea47c84 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -36,6 +36,7 @@ export namespace Field {
     export function toScriptString(field: Field): string {
         if (typeof field === "string") return `"${field}"`;
         if (typeof field === "number" || typeof field === "boolean") return String(field);
+        if (field === undefined || field === null) return "null";
         return field[ToScriptString]();
     }
     export function toString(field: Field): string {
diff --git a/src/fields/ScriptField.ts b/src/fields/ScriptField.ts
index 024017302..c949e0791 100644
--- a/src/fields/ScriptField.ts
+++ b/src/fields/ScriptField.ts
@@ -7,7 +7,9 @@ import { Doc, Field, Opt } from "./Doc";
 import { Plugins, setter } from "./util";
 import { computedFn } from "mobx-utils";
 import { ProxyField } from "./Proxy";
-import { Cast } from "./Types";
+import { Cast, NumCast } from "./Types";
+import { List } from "./List";
+import { numberRange } from "../Utils";
 
 function optional(propSchema: PropSchema) {
     return custom(value => {
@@ -188,12 +190,21 @@ export class ComputedField extends ScriptField {
         const compiled = ScriptField.CompileScript(script, params, true, capturedVariables);
         return compiled.compiled ? new ComputedField(compiled) : undefined;
     }
-    public static MakeInterpolated(fieldKey: string, interpolatorKey: string) {
+    public static MakeInterpolated(fieldKey: string, interpolatorKey: string, doc: Doc, curTimecode: number) {
+        if (!doc[`${fieldKey}-indexed`]) {
+            const flist = new List<number>(numberRange(curTimecode + 1).map(i => undefined) as any as number[]);
+            flist[curTimecode] = NumCast(doc[fieldKey]);
+            doc[`${fieldKey}-indexed`] = flist;
+        }
         const getField = ScriptField.CompileScript(`getIndexVal(self['${fieldKey}-indexed'], self.${interpolatorKey})`, {}, true, {});
-        const setField = ScriptField.CompileScript(`(self['${fieldKey}-indexed'])[self.${interpolatorKey}] = value`, { value: "any" }, true, {});
+        const setField = ScriptField.CompileScript(`setIndexVal(self['${fieldKey}-indexed'], self.${interpolatorKey}, value)`, { value: "any" }, true, {});
         return getField.compiled ? new ComputedField(getField, setField?.compiled ? setField : undefined) : undefined;
     }
 }
+Scripting.addGlobal(function setIndexVal(list: any[], index: number, value: any) {
+    while (list.length <= index) list.push(undefined);
+    list[index] = value;
+}, "sets the value at a given index of a list", "(list: any[], index: number, value: any)");
 
 Scripting.addGlobal(function getIndexVal(list: any[], index: number) {
     return list?.reduce((p, x, i) => (i <= index && x !== undefined) || p === undefined ? x : p, undefined as any);
diff --git a/src/server/websocket.ts b/src/server/websocket.ts
index 7d111f359..6850f0601 100644
--- a/src/server/websocket.ts
+++ b/src/server/websocket.ts
@@ -279,13 +279,13 @@ export namespace WebSocket {
         const updatefield = Array.from(Object.keys(diff.diff.$set))[0];
         const newListItems = diff.diff.$set[updatefield].fields;
         const curList = (curListItems as any)?.fields?.[updatefield.replace("fields.", "")]?.fields.filter((item: any) => item !== undefined) || [];
-        diff.diff.$set[updatefield].fields = [...curList, ...newListItems.filter((newItem: any) => newItem && !curList.some((curItem: any) => curItem.fieldId ? curItem.fieldId === newItem.fieldId : curItem.heading ? curItem.heading === newItem.heading : curItem === newItem))];
+        diff.diff.$set[updatefield].fields = [...curList, ...newListItems.filter((newItem: any) => newItem === null || !curList.some((curItem: any) => curItem.fieldId ? curItem.fieldId === newItem.fieldId : curItem.heading ? curItem.heading === newItem.heading : curItem === newItem))];
         const sendBack = diff.diff.length !== diff.diff.$set[updatefield].fields.length;
         delete diff.diff.length;
         Database.Instance.update(diff.id, diff.diff,
             () => {
                 if (sendBack) {
-                    console.log("RET BACK");
+                    console.log("Warning: list modified during update. Composite list is being returned.");
                     const id = socket.id;
                     socket.id = "";
                     socket.broadcast.emit(MessageStore.UpdateField.Message, diff);
-- 
cgit v1.2.3-70-g09d2


From 8bbe55468f2ea222ed8c4dc513e65707c8835737 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 7 Dec 2020 17:15:09 -0500
Subject: got rid of LibraryPath.  Fixed collectionFreeFormDocViews to use pres
 Effects whenever doc is selected

---
 src/client/views/GestureOverlay.tsx                |  1 -
 src/client/views/MainView.tsx                      |  9 +--
 src/client/views/OverlayView.tsx                   |  1 -
 src/client/views/Palette.tsx                       |  1 -
 src/client/views/PropertiesView.tsx                |  1 -
 src/client/views/TemplateMenu.tsx                  |  1 -
 .../views/collections/CollectionDockingView.tsx    |  2 +-
 .../views/collections/CollectionLinearView.tsx     |  1 -
 .../views/collections/CollectionSchemaView.tsx     |  1 -
 .../views/collections/CollectionStackingView.tsx   |  1 -
 .../views/collections/CollectionTreeView.tsx       |  1 -
 src/client/views/collections/SchemaTable.tsx       |  1 -
 src/client/views/collections/TabDocView.tsx        |  4 +-
 src/client/views/collections/TreeView.tsx          |  4 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  6 +-
 .../CollectionMulticolumnView.tsx                  |  1 -
 .../CollectionMultirowView.tsx                     |  1 -
 .../views/nodes/CollectionFreeFormDocumentView.tsx | 90 ++++++++++------------
 .../views/nodes/ContentFittingDocumentView.tsx     |  1 -
 src/client/views/nodes/DocHolderBox.tsx            |  2 -
 src/client/views/nodes/DocumentView.tsx            |  6 +-
 src/client/views/nodes/FieldView.tsx               |  1 -
 src/client/views/nodes/FilterBox.tsx               |  1 -
 src/client/views/nodes/KeyValuePair.tsx            |  1 -
 src/client/views/nodes/LinkDocPreview.tsx          |  1 -
 .../views/nodes/formattedText/DashDocView.tsx      |  1 -
 .../views/nodes/formattedText/FormattedTextBox.tsx |  2 +-
 .../formattedText/FormattedTextBoxComment.tsx      |  1 -
 .../views/nodes/formattedText/RichTextSchema.tsx   |  1 -
 src/client/views/pdf/PDFViewer.tsx                 |  1 -
 .../views/presentationview/PresElementBox.tsx      |  1 -
 src/mobile/AudioUpload.tsx                         |  1 -
 src/mobile/MobileInterface.tsx                     |  1 -
 33 files changed, 51 insertions(+), 98 deletions(-)

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

diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 35dedf016..c60060095 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -889,7 +889,6 @@ export class GestureOverlay extends Touchable {
             <DocumentView
                 Document={doc}
                 DataDoc={undefined}
-                LibraryPath={emptyPath}
                 addDocument={undefined}
                 addDocTab={returnFalse}
                 rootSelected={returnTrue}
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 747bde64d..9b3d5c6ae 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -244,7 +244,6 @@ export class MainView extends React.Component {
         return <DocumentView
             Document={this.mainContainer!}
             DataDoc={undefined}
-            LibraryPath={emptyPath}
             addDocument={undefined}
             addDocTab={this.addDocTabFunc}
             pinToPres={emptyFunction}
@@ -294,7 +293,7 @@ export class MainView extends React.Component {
     flyoutWidthFunc = () => this._flyoutWidth;
     sidebarScreenToLocal = () => new Transform(0, -this.topOffset, 1);
     mainContainerXf = () => this.sidebarScreenToLocal().translate(-this.leftOffset, 0);
-    addDocTabFunc = (doc: Doc, where: string, libraryPath?: Doc[]): boolean => {
+    addDocTabFunc = (doc: Doc, where: string): boolean => {
         return where === "close" ? CollectionDockingView.CloseSplit(doc) :
             doc.dockingConfig ? CurrentUserUtils.openDashboard(Doc.UserDoc(), doc) : CollectionDockingView.AddSplit(doc, "right");
     }
@@ -308,7 +307,6 @@ export class MainView extends React.Component {
                     <DocumentView
                         Document={this._sidebarContent.proto || this._sidebarContent}
                         DataDoc={undefined}
-                        LibraryPath={emptyPath}
                         addDocument={undefined}
                         addDocTab={this.addDocTabFunc}
                         pinToPres={emptyFunction}
@@ -342,7 +340,6 @@ export class MainView extends React.Component {
             <DocumentView
                 Document={Doc.UserDoc().menuStack as Doc}
                 DataDoc={undefined}
-                LibraryPath={emptyPath}
                 addDocument={undefined}
                 addDocTab={this.addDocTabFunc}
                 pinToPres={emptyFunction}
@@ -457,7 +454,6 @@ export class MainView extends React.Component {
                 <CollectionLinearView
                     Document={this.userDoc.dockedBtns}
                     DataDoc={undefined}
-                    LibraryPath={emptyPath}
                     fieldKey={"data"}
                     dropAction={"alias"}
                     annotationsKey={""}
@@ -532,7 +528,6 @@ export class MainView extends React.Component {
                 isSelected={returnTrue}
                 active={returnTrue}
                 select={this.select}
-                LibraryPath={emptyPath}
                 addDocument={undefined}
                 addDocTab={this.addDocTabFunc}
                 pinToPres={emptyFunction}
@@ -565,7 +560,6 @@ export class MainView extends React.Component {
                     ContainingCollectionView={undefined}
                     ContainingCollectionDoc={undefined}
                     Document={DocumentLinksButton.invisibleWebDoc}
-                    LibraryPath={emptyPath}
                     dropAction={"move"}
                     isSelected={returnFalse}
                     select={returnFalse}
@@ -632,7 +626,6 @@ export class MainView extends React.Component {
                             ContainingCollectionView={undefined}
                             ContainingCollectionDoc={undefined}
                             Document={invisibleDoc}
-                            LibraryPath={emptyPath}
                             dropAction={"move"}
                             isSelected={returnFalse}
                             select={returnFalse}
diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx
index 37e5b55eb..b7bd88344 100644
--- a/src/client/views/OverlayView.tsx
+++ b/src/client/views/OverlayView.tsx
@@ -182,7 +182,6 @@ export class OverlayView extends React.Component {
             return <div className="overlayView-doc" ref={dref} key={d[Id]} onPointerDown={onPointerDown} style={{ top: d.type === 'presentation' ? 0 : undefined, width: NumCast(d._width), height: NumCast(d._height), transform: `translate(${d.x}px, ${d.y}px)` }}>
                 <DocumentView
                     Document={d}
-                    LibraryPath={emptyPath}
                     ChromeHeight={returnZero}
                     rootSelected={returnTrue}
                     bringToFront={emptyFunction}
diff --git a/src/client/views/Palette.tsx b/src/client/views/Palette.tsx
index 536af2776..b31cfd7d2 100644
--- a/src/client/views/Palette.tsx
+++ b/src/client/views/Palette.tsx
@@ -40,7 +40,6 @@ export default class Palette extends React.Component<PaletteProps> {
                         <DocumentView
                             Document={this.props.thumbDoc}
                             DataDoc={undefined}
-                            LibraryPath={emptyPath}
                             addDocument={undefined}
                             addDocTab={returnFalse}
                             rootSelected={returnTrue}
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index 13377d189..9f1b8dad3 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -267,7 +267,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
                 <ContentFittingDocumentView
                     Document={layoutDoc}
                     DataDoc={this.dataDoc}
-                    LibraryPath={emptyPath}
                     renderDepth={1}
                     rootSelected={returnFalse}
                     treeViewDoc={undefined}
diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx
index 68f30d58c..9c5c70c60 100644
--- a/src/client/views/TemplateMenu.tsx
+++ b/src/client/views/TemplateMenu.tsx
@@ -136,7 +136,6 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
                 rootSelected={returnFalse}
                 onCheckedClick={this.scriptField}
                 onChildClick={this.scriptField}
-                LibraryPath={emptyPath}
                 dropAction={undefined}
                 active={returnTrue}
                 parentActive={returnFalse}
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 57b038c73..eee939c07 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -90,7 +90,7 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
     }
 
     @undoBatch
-    public static OpenFullScreen(doc: Doc, libraryPath?: Doc[]) {
+    public static OpenFullScreen(doc: Doc) {
         const instance = CollectionDockingView.Instance;
         if (doc._viewType === CollectionViewType.Docking && doc.layoutKey === "layout") {
             return CurrentUserUtils.openDashboard(Doc.UserDoc(), doc);
diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx
index b427e35c3..c7c510306 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/CollectionLinearView.tsx
@@ -140,7 +140,6 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
                             <ContentFittingDocumentView
                                 Document={pair.layout}
                                 DataDoc={pair.data}
-                                LibraryPath={this.props.LibraryPath}
                                 addDocument={this.props.addDocument}
                                 moveDocument={this.props.moveDocument}
                                 addDocTab={this.props.addDocTab}
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index a1df9d214..8ae70ce20 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -404,7 +404,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
                     FreezeDimensions={true}
                     dontCenter={"y"}
                     focus={emptyFunction}
-                    LibraryPath={this.props.LibraryPath}
                     renderDepth={this.props.renderDepth}
                     rootSelected={this.rootSelected}
                     PanelWidth={this.previewWidth}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 4b3393e14..0e4029764 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -195,7 +195,6 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
             styleProvider={this.props.styleProvider}
             LayoutTemplate={this.props.ChildLayoutTemplate}
             LayoutTemplateString={this.props.ChildLayoutString}
-            LibraryPath={this.props.LibraryPath}
             FreezeDimensions={this.props.freezeChildDimensions}
             renderDepth={this.props.renderDepth + 1}
             PanelWidth={width}
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 5ad820a4e..ac01536c9 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -163,7 +163,6 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
                 Document={this.doc}
                 DataDoc={undefined}
                 LayoutTemplateString={FormattedTextBox.LayoutString("text")}
-                LibraryPath={emptyPath}
                 renderDepth={this.props.renderDepth + 1}
                 rootSelected={returnTrue}
                 treeViewDoc={undefined}
diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx
index 087d106c5..664b6115a 100644
--- a/src/client/views/collections/SchemaTable.tsx
+++ b/src/client/views/collections/SchemaTable.tsx
@@ -573,7 +573,6 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
                         fitToBox={true}
                         FreezeDimensions={true}
                         focus={emptyFunction}
-                        LibraryPath={emptyPath}
                         renderDepth={this.props.renderDepth}
                         rootSelected={() => false}
                         PanelWidth={() => 150}
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index a8a95bf08..45658418c 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -288,7 +288,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
     //                                  "replace:right" - will replace the stack on the right named "right" if it exists, or create a stack on the right with that name, 
     //                                   "replace:monkeys" - will replace any tab that has the label 'monkeys', or a tab with that label will be created by default on the right
     //  inPlace - will add the document to any collection along the path from the document to the docking view that has a field isInPlaceContainer. if none is found, inPlace adds a tab to current stack
-    addDocTab = (doc: Doc, location: string, libraryPath?: Doc[]) => {
+    addDocTab = (doc: Doc, location: string) => {
         SelectionManager.DeselectAll();
         const locationFields = doc._viewType === CollectionViewType.Docking ? ["dashboard"] : location.split(":");
         const locationParams = locationFields.length > 1 ? locationFields[1] : "";
@@ -335,7 +335,6 @@ export class TabDocView extends React.Component<TabDocViewProps> {
             <div className="miniMap" style={{ width: miniSize, height: miniSize, background: this.tabColor }}>
                 <CollectionFreeFormView
                     Document={this._document!}
-                    LibraryPath={emptyPath}
                     CollectionView={undefined}
                     ContainingCollectionView={undefined}
                     ContainingCollectionDoc={undefined}
@@ -507,7 +506,6 @@ export class TabDocView extends React.Component<TabDocViewProps> {
         TraceMobx();
         return !this._activated || !this._document || this._document._viewType === CollectionViewType.Docking ? (null) :
             <><DocumentView key={this._document[Id]}
-                LibraryPath={emptyPath}
                 Document={this._document}
                 getView={this.setView}
                 DataDoc={!Doc.AreProtosEqual(this._document[DataSym], this._document) ? this._document[DataSym] : undefined}
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 7b8dcc9f3..675ba60c0 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -39,7 +39,7 @@ export interface TreeViewProps {
     removeDoc: ((doc: Doc | Doc[]) => boolean) | undefined;
     moveDocument: DragManager.MoveFunction;
     dropAction: dropActionType;
-    addDocTab: (doc: Doc, where: string, libraryPath?: Doc[]) => boolean;
+    addDocTab: (doc: Doc, where: string) => boolean;
     pinToPres: (document: Doc) => void;
     panelWidth: () => number;
     panelHeight: () => number;
@@ -521,7 +521,6 @@ export class TreeView extends React.Component<TreeViewProps> {
                 Document={this.doc}
                 DataDoc={undefined}
                 treeViewDoc={this.props.treeView.props.Document}
-                LibraryPath={emptyPath}
                 addDocument={undefined}
                 addDocTab={this.props.addDocTab}
                 rootSelected={returnTrue}
@@ -598,7 +597,6 @@ export class TreeView extends React.Component<TreeViewProps> {
             focus={asText ? this.refocus : returnFalse}
             dontRegisterView={asText ? undefined : this.props.dontRegisterView}
             ScreenToLocalTransform={this.docTransform}
-            LibraryPath={emptyPath}
             renderDepth={this.props.renderDepth + 1}
             rootSelected={returnTrue}
             treeViewDoc={undefined}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index fa84e5539..652b926ce 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -12,7 +12,7 @@ import { ScriptField } from "../../../../fields/ScriptField";
 import { BoolCast, Cast, FieldValue, NumCast, ScriptCast, StrCast } from "../../../../fields/Types";
 import { TraceMobx } from "../../../../fields/util";
 import { GestureUtils } from "../../../../pen-gestures/GestureUtils";
-import { aggregateBounds, intersectRect, returnFalse, returnOne, returnZero, setupMoveUpEvents, Utils, returnVal } from "../../../../Utils";
+import { aggregateBounds, intersectRect, returnFalse, returnOne, returnZero, setupMoveUpEvents, Utils, returnVal, returnTrue } from "../../../../Utils";
 import { CognitiveServices } from "../../../cognitive_services/CognitiveServices";
 import { DocServer } from "../../../DocServer";
 import { Docs, DocUtils } from "../../../documents/Documents";
@@ -982,11 +982,10 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
         pw && ph && (this.Document[this.scaleFieldKey] = scale * Math.min(pw / NumCast(doc._width), ph / NumCast(doc._height)));
     }
 
-    @computed get libraryPath() { return this.props.LibraryPath ? [...this.props.LibraryPath, this.props.Document] : []; }
     @computed get backgroundActive() { return this.props.layerProvider?.(this.layoutDoc) === false && (this.props.ContainingCollectionView?.active() || this.props.active()); }
     onChildClickHandler = () => this.props.childClickScript || ScriptCast(this.Document.onChildClick);
     onChildDoubleClickHandler = () => this.props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick);
-    backgroundHalo = computedFn(function (doc: Doc) { return BoolCast(this.Document._useClusters) || (NumCast(doc.group, -1) !== -1); }).bind(this);
+    backgroundHalo = this.Document._useClusters ? returnTrue : computedFn(function (doc: Doc) { return NumCast(doc.group, -1) !== -1; });
     parentActive = (outsideReaction: boolean) => this.props.active(outsideReaction) || this.props.parentActive?.(outsideReaction) || this.backgroundActive || this.layoutDoc._viewType === CollectionViewType.Pile ? true : false;
     getChildDocumentViewProps(childLayout: Doc, childData?: Doc): DocumentViewProps {
         return {
@@ -999,7 +998,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
             fitToBox: false,
             DataDoc: childData,
             Document: childLayout,
-            LibraryPath: this.libraryPath,
             LayoutTemplate: childLayout.z ? undefined : this.props.ChildLayoutTemplate,
             LayoutTemplateString: childLayout.z ? undefined : this.props.ChildLayoutString,
             FreezeDimensions: this.props.freezeChildDimensions,
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
index 2e7cdf6d0..7ce269c92 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
@@ -219,7 +219,6 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu
             styleProvider={this.props.styleProvider}
             LayoutTemplate={this.props.ChildLayoutTemplate}
             LayoutTemplateString={this.props.ChildLayoutString}
-            LibraryPath={this.props.LibraryPath}
             FreezeDimensions={this.props.freezeChildDimensions}
             renderDepth={this.props.renderDepth + 1}
             PanelWidth={width}
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
index 4206a5171..7700ea128 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
@@ -219,7 +219,6 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument)
             styleProvider={this.props.styleProvider}
             LayoutTemplate={this.props.ChildLayoutTemplate}
             LayoutTemplateString={this.props.ChildLayoutString}
-            LibraryPath={this.props.LibraryPath}
             FreezeDimensions={this.props.freezeChildDimensions}
             renderDepth={this.props.renderDepth + 1}
             PanelWidth={width}
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 942182191..a17816705 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -116,7 +116,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
 
     public static gotoKeyframe(docs: Doc[]) {
         docs.forEach(doc => doc._viewTransition = doc.dataTransition = "all 1s");
-        setTimeout(() => docs.forEach(doc => { doc._viewTransition = undefined; doc.dataTransition = "inherit" }), 1010);
+        setTimeout(() => docs.forEach(doc => { doc._viewTransition = undefined; doc.dataTransition = "inherit"; }), 1010);
     }
 
     public static setupZoom(doc: Doc, targDoc: Doc) {
@@ -153,41 +153,41 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
     }
 
     @computed get freeformNodeDiv() {
-        const node = <DocumentView {...this.props}
-            nudge={this.nudge}
-            dragDivName={"collectionFreeFormDocumentView-container"}
-            ContentScaling={this.contentScaling}
-            ScreenToLocalTransform={this.getTransform}
-            styleProvider={this.props.styleProvider}
-            opacity={this.opacity}
-            layerProvider={this.props.layerProvider}
-            NativeHeight={this.NativeHeight}
-            NativeWidth={this.NativeWidth}
-            PanelWidth={this.panelWidth}
-            PanelHeight={this.panelHeight} />;
-        if (PresBox.Instance && this.layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc) {
-            const effectProps = {
-                left: this.layoutDoc.presEffectDirection === PresEffect.Left,
-                right: this.layoutDoc.presEffectDirection === PresEffect.Right,
-                top: this.layoutDoc.presEffectDirection === PresEffect.Top,
-                bottom: this.layoutDoc.presEffectDirection === PresEffect.Bottom,
-                opposite: true,
-                delay: this.layoutDoc.presTransition,
-                // when: this.layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc,
-            };
-            switch (this.layoutDoc.presEffect) {
-                case "Zoom": return (<Zoom {...effectProps}>{node}</Zoom>); break;
-                case PresEffect.Fade: return (<Fade {...effectProps}>{node}</Fade>); break;
-                case PresEffect.Flip: return (<Flip {...effectProps}>{node}</Flip>); break;
-                case PresEffect.Rotate: return (<Rotate {...effectProps}>{node}</Rotate>); break;
-                case PresEffect.Bounce: return (<Bounce {...effectProps}>{node}</Bounce>); break;
-                case PresEffect.Roll: return (<Roll {...effectProps}>{node}</Roll>); break;
-                case "LightSpeed": return (<LightSpeed {...effectProps}>{node}</LightSpeed>); break;
-                case PresEffect.None: return node; break;
-                default: return node; break;
-            }
-        } else {
-            return node;
+        const divProps = {
+            ...this.props,
+            nudge: this.nudge,
+            dragDivName: "collectionFreeFormDocumentView-container",
+            opacity: this.opacity,
+            ScreenToLocalTransform: this.getTransform,
+            NativeHeight: this.NativeHeight,
+            NativeWidth: this.NativeWidth,
+            PanelWidth: this.panelWidth,
+            PanelHeight: this.panelHeight
+        };
+        return this.props.fitToBox ?
+            <ContentFittingDocumentView {...divProps} ref={action((r: ContentFittingDocumentView | null) => this._contentView = r)} /> :
+            <DocumentView {...divProps} ContentScaling={this.contentScaling} />;
+    }
+    @computed get effectsNodeDiv() {
+        const effectProps = {
+            left: this.layoutDoc.presEffectDirection === PresEffect.Left,
+            right: this.layoutDoc.presEffectDirection === PresEffect.Right,
+            top: this.layoutDoc.presEffectDirection === PresEffect.Top,
+            bottom: this.layoutDoc.presEffectDirection === PresEffect.Bottom,
+            opposite: true,
+            delay: this.layoutDoc.presTransition,
+            // when: this.layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc,
+        };
+        switch (this.layoutDoc.presEffect) {
+            case "Zoom": return (<Zoom {...effectProps}>{this.freeformNodeDiv}</Zoom>);
+            case PresEffect.Fade: return (<Fade {...effectProps}>{this.freeformNodeDiv}</Fade>);
+            case PresEffect.Flip: return (<Flip {...effectProps}>{this.freeformNodeDiv}</Flip>);
+            case PresEffect.Rotate: return (<Rotate {...effectProps}>{this.freeformNodeDiv}</Rotate>);
+            case PresEffect.Bounce: return (<Bounce {...effectProps}>{this.freeformNodeDiv}</Bounce>);
+            case PresEffect.Roll: return (<Roll {...effectProps}>{this.freeformNodeDiv}</Roll>);
+            case "LightSpeed": return (<LightSpeed {...effectProps}>{this.freeformNodeDiv}</LightSpeed>);
+            case PresEffect.None:
+            default: return this.freeformNodeDiv;
         }
     }
 
@@ -207,6 +207,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
         TraceMobx();
         const backgroundColor = this.props.styleProvider?.(this.Document, this.props, "backgroundColor", this.props.layerProvider);
         const borderRounding = StrCast(Doc.Layout(this.layoutDoc).borderRounding) || StrCast(this.layoutDoc.borderRounding) || StrCast(this.Document.borderRounding) || undefined;
+
         return <div className="collectionFreeFormDocumentView-container"
             style={{
                 boxShadow:
@@ -236,18 +237,11 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
                     </svg>
                 </div>}
 
-            {!this.props.fitToBox ?
-                <>{this.freeformNodeDiv}</>
-                : <ContentFittingDocumentView {...this.props}
-                    ref={action((r: ContentFittingDocumentView | null) => this._contentView = r)}
-                    ContainingCollectionDoc={this.props.ContainingCollectionDoc}
-                    DataDoc={this.props.DataDoc}
-                    ScreenToLocalTransform={this.getTransform}
-                    NativeHeight={this.NativeHeight}
-                    NativeWidth={this.NativeWidth}
-                    PanelWidth={this.panelWidth}
-                    PanelHeight={this.panelHeight}
-                />}
+            {PresBox.Instance && this.layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc ?
+                this.effectsNodeDiv
+                :
+                this.freeformNodeDiv
+            }
         </div>;
     }
 }
diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx
index a54479f55..74d7cb24e 100644
--- a/src/client/views/nodes/ContentFittingDocumentView.tsx
+++ b/src/client/views/nodes/ContentFittingDocumentView.tsx
@@ -71,7 +71,6 @@ export class ContentFittingDocumentView extends React.Component<DocumentViewProp
                         DataDoc={this.props.DataDoc}
                         LayoutTemplate={this.props.LayoutTemplate}
                         LayoutTemplateString={this.props.LayoutTemplateString}
-                        LibraryPath={this.props.LibraryPath}
                         PanelWidth={this.PanelWidth}
                         PanelHeight={this.PanelHeight}
                         ContentScaling={returnOne}
diff --git a/src/client/views/nodes/DocHolderBox.tsx b/src/client/views/nodes/DocHolderBox.tsx
index f0a1a3278..8231cf89e 100644
--- a/src/client/views/nodes/DocHolderBox.tsx
+++ b/src/client/views/nodes/DocHolderBox.tsx
@@ -118,7 +118,6 @@ export class DocHolderBox extends ViewBoxAnnotatableComponent<FieldViewProps, Do
                 <DocumentView
                     Document={containedDoc}
                     DataDoc={undefined}
-                    LibraryPath={emptyPath}
                     docFilters={this.props.docFilters}
                     docRangeFilters={this.props.docRangeFilters}
                     searchFilterDocs={this.props.searchFilterDocs}
@@ -147,7 +146,6 @@ export class DocHolderBox extends ViewBoxAnnotatableComponent<FieldViewProps, Do
                 <ContentFittingDocumentView
                     Document={containedDoc}
                     DataDoc={undefined}
-                    LibraryPath={emptyPath}
                     docFilters={this.props.docFilters}
                     docRangeFilters={this.props.docRangeFilters}
                     searchFilterDocs={this.props.searchFilterDocs}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 126f330ab..53d6c0ddb 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -62,7 +62,6 @@ export interface DocumentViewProps {
     getView?: (view: DocumentView) => any;
     LayoutTemplateString?: string;
     LayoutTemplate?: () => Opt<Doc>;
-    LibraryPath: Doc[];
     fitToBox?: boolean;
     ignoreAutoHeight?: boolean;
     contextMenuItems?: () => { script: ScriptField, label: string }[];
@@ -90,7 +89,7 @@ export interface DocumentViewProps {
     parentActive: (outsideReaction: boolean) => boolean;
     whenActiveChanged: (isActive: boolean) => void;
     bringToFront: (doc: Doc, sendToBack?: boolean) => void;
-    addDocTab: (doc: Doc, where: string, libraryPath?: Doc[]) => boolean;
+    addDocTab: (doc: Doc, where: string) => boolean;
     pinToPres: (document: Doc) => void;
     backgroundHalo?: (doc: Doc) => boolean;
     styleProvider?: (doc: Opt<Doc>, props: DocumentViewProps, property: string, layerProvider?: (doc: Doc, assign?: boolean) => boolean) => any;
@@ -386,7 +385,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     // depending on the followLinkLocation property of the source (or the link itself as a fallback);
     public static followLinkClick = async (linkDoc: Opt<Doc>, sourceDoc: Doc, docView: {
         focus: DocFocusFunc,
-        addDocTab: (doc: Doc, where: string, libraryPath?: Doc[]) => boolean,
+        addDocTab: (doc: Doc, where: string) => boolean,
         ContainingCollectionDoc?: Doc
     }, shiftKey: boolean, altKey: boolean) => {
         const batch = UndoManager.StartBatch("follow link click");
@@ -933,7 +932,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 backgroundHalo={this.props.backgroundHalo}
                 dontRegisterView={this.props.dontRegisterView}
                 fitToBox={this.props.fitToBox}
-                LibraryPath={this.props.LibraryPath}
                 addDocument={this.props.addDocument}
                 removeDocument={this.props.removeDocument}
                 moveDocument={this.props.moveDocument}
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index ed91cf47d..f2fdf7a6b 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -25,7 +25,6 @@ export interface FieldViewProps {
     ContainingCollectionDoc: Opt<Doc>;
     Document: Doc;
     DataDoc?: Doc;
-    LibraryPath: Doc[];
     layerProvider?: (doc: Doc, assign?: boolean) => boolean;
     contentsActive?: (setActive: () => boolean) => void;
     onClick?: () => ScriptField;
diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx
index 6f0828a7d..0161f51fd 100644
--- a/src/client/views/nodes/FilterBox.tsx
+++ b/src/client/views/nodes/FilterBox.tsx
@@ -193,7 +193,6 @@ export class FilterBox extends ViewBoxBaseComponent<FieldViewProps, FilterBoxDoc
                     ContainingCollectionView={this.props.ContainingCollectionView}
                     PanelWidth={this.props.PanelWidth}
                     PanelHeight={this.props.PanelHeight}
-                    LibraryPath={emptyPath}
                     rootSelected={this.props.rootSelected}
                     renderDepth={1}
                     dropAction={this.props.dropAction}
diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx
index 5e1f8fcea..aaf544c50 100644
--- a/src/client/views/nodes/KeyValuePair.tsx
+++ b/src/client/views/nodes/KeyValuePair.tsx
@@ -55,7 +55,6 @@ export class KeyValuePair extends React.Component<KeyValuePairProps> {
         const props: FieldViewProps = {
             Document: this.props.doc,
             DataDoc: this.props.doc,
-            LibraryPath: [],
             docFilters: returnEmptyFilter,
             docRangeFilters: returnEmptyFilter,
             searchFilterDocs: returnEmptyDoclist,
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index c4bb2b8d8..5017b3a71 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -94,7 +94,6 @@ export class LinkDocPreview extends React.Component<Props> {
             :
             <ContentFittingDocumentView
                 Document={this._targetDoc}
-                LibraryPath={emptyPath}
                 fitToBox={true}
                 moveDocument={returnFalse}
                 rootSelected={returnFalse}
diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx
index 67bfd435b..450f0b6bc 100644
--- a/src/client/views/nodes/formattedText/DashDocView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocView.tsx
@@ -228,7 +228,6 @@ export class DashDocView extends React.Component<IDashDocView> {
                         <DocumentView
                             Document={finalLayout}
                             DataDoc={resolvedDataDoc}
-                            LibraryPath={this._textBox.props.LibraryPath}
                             fitToBox={BoolCast(dashDoc._fitToBox)}
                             addDocument={returnFalse}
                             rootSelected={this._textBox.props.isSelected}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 6768acce4..59909cea1 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -99,7 +99,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
     private _currentTime: number = 0;
     private _linkTime: number | null = null;
     private _pause: boolean = false;
-    private _animatingScroll: numher = 0; // hack to prevent scroll values from being written to document when scroll is animating
+    private _animatingScroll: number = 0; // hack to prevent scroll values from being written to document when scroll is animating
 
     @computed get _recording() { return this.dataDoc?.audioState === "recording"; }
     set _recording(value) {
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index 3e5a40084..1d7b7ec91 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -297,7 +297,6 @@ export class FormattedTextBoxComment {
                                     <div className="FormattedTextBoxComment-preview-wrapper">
                                         <ContentFittingDocumentView
                                             Document={target}
-                                            LibraryPath={emptyPath}
                                             fitToBox={true}
                                             moveDocument={returnFalse}
                                             rootSelected={returnFalse}
diff --git a/src/client/views/nodes/formattedText/RichTextSchema.tsx b/src/client/views/nodes/formattedText/RichTextSchema.tsx
index b5d984aac..bb544e5e8 100644
--- a/src/client/views/nodes/formattedText/RichTextSchema.tsx
+++ b/src/client/views/nodes/formattedText/RichTextSchema.tsx
@@ -136,7 +136,6 @@ export class DashDocView {
                 ReactDOM.render(<DocumentView
                     Document={finalLayout}
                     DataDoc={resolvedDataDoc}
-                    LibraryPath={this._textBox.props.LibraryPath}
                     fitToBox={BoolCast(dashDoc._fitToBox)}
                     addDocument={returnFalse}
                     rootSelected={this._textBox.props.isSelected}
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 48c7b1762..9b689eb6b 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -736,7 +736,6 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
                 transform: `scale(${this._zoomed})`
             }}>
             <CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
-                LibraryPath={this.props.ContainingCollectionView?.props.LibraryPath ?? emptyPath}
                 annotationsKey={this.annotationKey}
                 setPreviewCursor={this.setPreviewCursor}
                 PanelHeight={this.panelWidth}
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index 608740b46..9742faa2b 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -86,7 +86,6 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                 <ContentFittingDocumentView
                     Document={this.targetDoc}
                     DataDoc={this.targetDoc[DataSym] !== this.targetDoc && this.targetDoc[DataSym]}
-                    LibraryPath={emptyPath}
                     fitToBox={true}
                     styleProvider={this.props.styleProvider}
                     rootSelected={returnTrue}
diff --git a/src/mobile/AudioUpload.tsx b/src/mobile/AudioUpload.tsx
index 604c9a5ab..21c156ac0 100644
--- a/src/mobile/AudioUpload.tsx
+++ b/src/mobile/AudioUpload.tsx
@@ -81,7 +81,6 @@ export class AudioUpload extends React.Component {
                     <DocumentView
                         Document={this._audioCol}
                         DataDoc={undefined}
-                        LibraryPath={emptyPath}
                         addDocument={undefined}
                         addDocTab={returnFalse}
                         pinToPres={emptyFunction}
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index ae88a2eaf..3d5c70ff7 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -202,7 +202,6 @@ export class MobileInterface extends React.Component {
                 <DocumentView
                     Document={this.mainContainer}
                     DataDoc={undefined}
-                    LibraryPath={emptyPath}
                     addDocument={returnFalse}
                     addDocTab={returnFalse}
                     pinToPres={emptyFunction}
-- 
cgit v1.2.3-70-g09d2


From cae3cd5b324084986a631348626d0230561f34a7 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 8 Dec 2020 12:55:54 -0500
Subject: simplified styleProvider arguments.   fixed useClusters

---
 src/client/views/PropertiesView.tsx                 |  2 +-
 .../views/collections/CollectionCarouselView.tsx    |  2 +-
 src/client/views/collections/CollectionTreeView.tsx |  2 +-
 src/client/views/collections/CollectionView.tsx     |  2 +-
 src/client/views/collections/TabDocView.tsx         | 12 ++++++------
 .../collectionFreeForm/CollectionFreeFormView.tsx   |  7 ++++---
 .../views/nodes/CollectionFreeFormDocumentView.tsx  |  6 +++---
 src/client/views/nodes/DocHolderBox.tsx             |  2 +-
 src/client/views/nodes/DocumentView.tsx             | 21 +++++++++------------
 src/client/views/nodes/FieldView.tsx                |  2 +-
 src/client/views/nodes/FontIconBox.tsx              |  2 +-
 src/client/views/nodes/LinkBox.tsx                  |  2 +-
 src/client/views/nodes/LinkDocPreview.tsx           |  2 +-
 .../views/nodes/formattedText/FormattedTextBox.tsx  |  2 +-
 .../views/presentationview/PresElementBox.tsx       |  2 +-
 15 files changed, 33 insertions(+), 35 deletions(-)

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

diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index 9f1b8dad3..08394cd97 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -37,7 +37,7 @@ const _global = (window /* browser */ || global /* node */) as any;
 interface PropertiesViewProps {
     width: number;
     height: number;
-    styleProvider?: (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string, layerProvider?: (doc: Doc, assign?: boolean) => boolean) => any;
+    styleProvider?: (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string) => any;
 }
 
 @observer
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index 62c1bce3f..16ccdc6f4 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -65,7 +65,7 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument)
                 </div>
                 <div className="collectionCarouselView-caption" key="caption"
                     style={{
-                        background: StrCast(this.layoutDoc._captionBackgroundColor, this.props.styleProvider?.(this.props.Document, this.props, "backgroundColor", this.props.layerProvider)),
+                        background: StrCast(this.layoutDoc._captionBackgroundColor, this.props.styleProvider?.(this.props.Document, this.props, "backgroundColor")),
                         color: StrCast(this.layoutDoc._captionColor, StrCast(this.layoutDoc.color)),
                         borderRadius: StrCast(this.layoutDoc._captionBorderRounding),
                     }}>
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index ac01536c9..681584cc5 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -215,7 +215,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
     render() {
         TraceMobx();
         if (!(this.doc instanceof Doc)) return (null);
-        const background = this.props.styleProvider?.(this.doc, this.props, "backgroundColor", this.props.layerProvider);
+        const background = this.props.styleProvider?.(this.doc, this.props, "backgroundColor");
         const paddingX = `${NumCast(this.doc._xPadding, 10)}px`;
         const paddingTop = `${NumCast(this.doc._yPadding, 20)}px`;
         const pointerEvents = !this.props.active() && !SnappingManager.GetIsDragging() && !this._isChildActive ? "none" : undefined;
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 0a9eeab50..8f402c427 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -399,7 +399,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
             ChildLayoutString: this.childLayoutString,
         };
         const boxShadow = Doc.UserDoc().renderStyle === "comic" || this.props.Document.treeViewOutlineMode || this.collectionViewType === CollectionViewType.Linear ? undefined :
-            this.props.styleProvider?.(this.props.Document, this.props, "boxShadow", this.props.layerProvider);
+            this.props.styleProvider?.(this.props.Document, this.props, "boxShadow");
         return (<div className={"collectionView"} onContextMenu={this.onContextMenu}
             style={{ pointerEvents: this.props.layerProvider?.(this.props.Document) === false ? "none" : undefined, boxShadow }}>
             {this.showIsTagged()}
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 45658418c..e1fd47592 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -434,7 +434,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
     //
     // a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab
     // 
-    public static styleProvider = (doc: Opt<Doc>, props: DocumentViewProps | undefined, property: string, layerProvider?: (doc: Doc, assign?: boolean) => boolean): any => {
+    public static styleProvider = (doc: Opt<Doc>, props: DocumentViewProps | undefined, property: string): any => {
         switch (property) {
             case "backgroundColor": {
                 if (Doc.UserDoc().renderStyle === "comic") return undefined;
@@ -456,11 +456,11 @@ export class TabDocView extends React.Component<TabDocViewProps> {
                         default: docColor = TabDocView.darkScheme ? "black" : "white"; break;
                     }
                 }
-                if (docColor && (!doc || layerProvider?.(doc) === false)) docColor = Color(docColor).fade(0.5).toString();
+                if (docColor && (!doc || props?.layerProvider?.(doc) === false)) docColor = Color(docColor).fade(0.5).toString();
                 return docColor;
             }
             case "widgetColor": return TabDocView.darkScheme ? "lightgrey" : "dimgrey";
-            case "hidden": return (BoolCast(doc?.hidden) /* || layerProvider?.(doc) === false*/);
+            case "hidden": return (BoolCast(doc?.hidden) /* || props?.layerProvider?.(doc) === false*/);
             case "boxShadow": {
                 switch (doc?.type) {
                     case DocumentType.COL: return StrListCast(doc.layers).includes("background") ? undefined :
@@ -471,7 +471,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
             case "docContents": return undefined;
             default:
                 if (property.startsWith("pointerEvents")) {
-                    const layer = doc && layerProvider?.(doc);
+                    const layer = doc && props?.layerProvider?.(doc);
                     if (doc?.Opacity === 0 || doc?.type === DocumentType.INK || doc?.isInkMask) return "none";
                     if (layer === false && !property.includes(":selected") && !SnappingManager.GetIsDragging()) return "none";
                     if (doc?.type !== DocumentType.INK && layer === true) return "all";
@@ -488,7 +488,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
                 }
         }
     }
-    public static miniStyleProvider = (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string, layerProvider?: (doc: Doc, assign?: boolean) => boolean): any => {
+    public static miniStyleProvider = (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string): any => {
         if (doc) {
             switch (property) {
                 case "docContents":
@@ -498,7 +498,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
                     return <div style={{ width: doc[WidthSym](), height: doc[HeightSym](), position: "absolute", display: "block", background }} />;
                 default:
                     if (property.startsWith("pointerEvents")) return "none";
-                    return TabDocView.styleProvider(doc, props, property, layerProvider);
+                    return TabDocView.styleProvider(doc, props, property);
             }
         }
     }
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 652b926ce..136600164 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -396,8 +396,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
         }
     }
 
-    getClusterColor = (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string, layerProvider?: (doc: Doc, assign?: boolean) => boolean) => {
-        let clusterColor = this.props.styleProvider?.(doc, props, property, layerProvider);  // bcz: check 'props'  used to be renderDepth + 1
+    getClusterColor = (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string) => {
+        let clusterColor = this.props.styleProvider?.(doc, props, property);  // bcz: check 'props'  used to be renderDepth + 1
         if (property !== "backgroundColor") return clusterColor;
         const cluster = NumCast(doc?.cluster);
         if (this.Document._useClusters) {
@@ -985,7 +985,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
     @computed get backgroundActive() { return this.props.layerProvider?.(this.layoutDoc) === false && (this.props.ContainingCollectionView?.active() || this.props.active()); }
     onChildClickHandler = () => this.props.childClickScript || ScriptCast(this.Document.onChildClick);
     onChildDoubleClickHandler = () => this.props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick);
-    backgroundHalo = this.Document._useClusters ? returnTrue : computedFn(function (doc: Doc) { return NumCast(doc.group, -1) !== -1; });
+    // @ts-ignore
+    backgroundHalo = computedFn(function (doc: Doc) { return this.Document._useClusters || NumCast(doc.group, -1) !== -1; }).bind(this);
     parentActive = (outsideReaction: boolean) => this.props.active(outsideReaction) || this.props.parentActive?.(outsideReaction) || this.backgroundActive || this.layoutDoc._viewType === CollectionViewType.Pile ? true : false;
     getChildDocumentViewProps(childLayout: Doc, childData?: Doc): DocumentViewProps {
         return {
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 51ed49df3..b4b887617 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -142,11 +142,11 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
     NativeHeight = () => this.nativeHeight;
     @computed get pointerEvents() {
         if (this.props.pointerEvents === "none") return "none";
-        return this.props.styleProvider?.(this.Document, this.props, !this._contentView?.docView?.isSelected() ? "pointerEvents:selected" : "pointerEvents", this.props.layerProvider);
+        return this.props.styleProvider?.(this.Document, this.props, !this._contentView?.docView?.isSelected() ? "pointerEvents:selected" : "pointerEvents");
     }
     render() {
         TraceMobx();
-        const backgroundColor = this.props.styleProvider?.(this.Document, this.props, "backgroundColor", this.props.layerProvider);
+        const backgroundColor = this.props.styleProvider?.(this.Document, this.props, "backgroundColor");
         const borderRounding = StrCast(Doc.Layout(this.layoutDoc).borderRounding) || StrCast(this.layoutDoc.borderRounding) || StrCast(this.Document.borderRounding) || undefined;
 
         const divProps = {
@@ -165,7 +165,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
                 boxShadow:
                     this.Opacity === 0 ? undefined :  // if it's not visible, then no shadow
                         this.layoutDoc.z ? `#9c9396  ${StrCast(this.layoutDoc.boxShadow, "10px 10px 0.9vw")}` :  // if it's a floating doc, give it a big shadow
-                            this.props.backgroundHalo?.(this.props.Document) && this.props.Document.type !== DocumentType.INK ? (`${this.props.styleProvider?.(this.props.Document, this.props, "backgroundColor", this.props.layerProvider)} ${StrCast(this.layoutDoc.boxShadow, `0vw 0vw ${(Cast(this.layoutDoc.layers, listSpec("string"), []).includes("background") ? 100 : 50) / this.props.ContentScaling()}px`)}`) :  // if it's just in a cluster, make the shadown roughly match the cluster border extent
+                            this.props.backgroundHalo?.(this.props.Document) && this.props.Document.type !== DocumentType.INK ? (`${this.props.styleProvider?.(this.props.Document, this.props, "backgroundColor")} ${StrCast(this.layoutDoc.boxShadow, `0vw 0vw ${(Cast(this.layoutDoc.layers, listSpec("string"), []).includes("background") ? 100 : 50) / this.props.ContentScaling()}px`)}`) :  // if it's just in a cluster, make the shadown roughly match the cluster border extent
                                 Cast(this.layoutDoc.layers, listSpec("string"), []).includes('background') ? undefined :  // if it's a background & has a cluster color, make the shadow spread really big
                                     StrCast(this.layoutDoc.boxShadow, ""),
                 borderRadius: borderRounding,
diff --git a/src/client/views/nodes/DocHolderBox.tsx b/src/client/views/nodes/DocHolderBox.tsx
index 8231cf89e..e14093e70 100644
--- a/src/client/views/nodes/DocHolderBox.tsx
+++ b/src/client/views/nodes/DocHolderBox.tsx
@@ -182,7 +182,7 @@ export class DocHolderBox extends ViewBoxAnnotatableComponent<FieldViewProps, Do
             onContextMenu={this.specificContextMenu}
             onPointerDown={this.onPointerDown} onClick={this.onClick}
             style={{
-                background: this.props.styleProvider?.(containedDoc, this.props, "backgroundColor", this.props.layerProvider),
+                background: this.props.styleProvider?.(containedDoc, this.props, "backgroundColor"),
                 border: `#00000021 solid ${this.xPad}px`,
                 borderTop: `#0000005e solid ${this.yPad}px`,
                 borderBottom: `#0000005e solid ${this.yPad}px`,
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 903e7e478..5ed49185b 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -91,7 +91,7 @@ export interface DocumentViewProps {
     addDocTab: (doc: Doc, where: string) => boolean;
     pinToPres: (document: Doc) => void;
     backgroundHalo?: (doc: Doc) => boolean;
-    styleProvider?: (doc: Opt<Doc>, props: DocumentViewProps, property: string, layerProvider?: (doc: Doc, assign?: boolean) => boolean) => any;
+    styleProvider?: (doc: Opt<Doc>, props: DocumentViewProps, property: string) => any;
     forceHideLinkButton?: () => boolean;
     opacity?: () => number | undefined;
     ChromeHeight?: () => number;
@@ -1062,7 +1062,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     }
     @computed get pointerEvents() {
         if (this.props.pointerEvents === "none") return "none";
-        return this.props.styleProvider?.(this.Document, this.props, this.isSelected() ? "pointerEvents:selected" : "pointerEvents", this.props.layerProvider);
+        return this.props.styleProvider?.(this.Document, this.props, this.isSelected() ? "pointerEvents:selected" : "pointerEvents");
     }
     @undoBatch
     @action
@@ -1086,8 +1086,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         TraceMobx();
         if (!(this.props.Document instanceof Doc)) return (null);
         if (GetEffectiveAcl(this.props.Document[DataSym]) === AclPrivate) return (null);
-        if (this.props.styleProvider?.(this.layoutDoc, this.props, "hidden", this.props.layerProvider)) return null;
-        const backgroundColor = this.props.styleProvider?.(this.layoutDoc, this.props, "backgroundColor", this.props.layerProvider);
+        if (this.props.styleProvider?.(this.layoutDoc, this.props, "hidden")) return null;
+        const backgroundColor = this.props.styleProvider?.(this.layoutDoc, this.props, "backgroundColor");
         const opacity = Cast(this.layoutDoc._opacity, "number", Cast(this.layoutDoc.opacity, "number", Cast(this.Document.opacity, "number", null)));
         const finalOpacity = this.props.opacity ? this.props.opacity() : opacity;
         const finalColor = this.layoutDoc.type === DocumentType.FONTICON || this.layoutDoc._viewType === CollectionViewType.Linear ? undefined : backgroundColor;
@@ -1101,14 +1101,14 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         let highlighting = fullDegree && this.layoutDoc.type !== DocumentType.FONTICON && this.layoutDoc._viewType !== CollectionViewType.Linear && this.props.Document.type !== DocumentType.INK;
         highlighting = highlighting && this.props.focus !== emptyFunction && this.layoutDoc.title !== "[pres element template]";  // bcz: hack to turn off highlighting onsidebar panel documents.  need to flag a document as not highlightable in a more direct way
         const topmost = this.topMost ? "-topmost" : "";
-        return this.props.styleProvider?.(this.rootDoc, this.props, "docContents", this.props.layerProvider) ?? <div className={`documentView-node${topmost}`}
+        return this.props.styleProvider?.(this.rootDoc, this.props, "docContents") ?? <div className={`documentView-node${topmost}`}
             id={this.props.Document[Id]}
             onKeyDown={this.onKeyDown}
             onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown} onClick={this.onClick}
             onPointerEnter={action(e => !SnappingManager.GetIsDragging() && Doc.BrushDoc(this.props.Document))}
             onPointerLeave={action(e => {
                 let entered = false;
-                for (let child = document.elementFromPoint(e.nativeEvent.x, e.nativeEvent.y); child; child = child.parentElement) {
+                for (let child = document.elementFromPoint(e.nativeEvent.x, e.nativeEvent.y); !entered && child; child = child.parentElement) {
                     entered = entered || child === this.ContentDiv;
                 }
                 !entered && Doc.UnBrushDoc(this.props.Document);
@@ -1131,12 +1131,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 fontFamily: StrCast(this.Document._fontFamily, "inherit"),
                 fontSize: !this.props.treeViewDoc ? Cast(this.Document._fontSize, "string", null) : undefined,
             }}>
-            {this.onClickHandler && this.props.ContainingCollectionView?.props.Document._viewType === CollectionViewType.Time ? <>
-                {this.innards}
-                <div className="documentView-contentBlocker" />
-            </> :
-                this.innards}
-            {!this.props.treeViewDoc && this.props.styleProvider?.(this.rootDoc, this.props, this.isSelected() ? "decorations:selected" : "decorations", this.props.layerProvider) || (null)}
+            {this.innards}
+            {this.onClickHandler && this.props.ContainingCollectionView?.props.Document._viewType === CollectionViewType.Time ? <div className="documentView-contentBlocker" /> : (null)}
+            {!this.props.treeViewDoc && this.props.styleProvider?.(this.rootDoc, this.props, this.isSelected() ? "decorations:selected" : "decorations") || (null)}
         </div>;
     }
     render() {
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index f2fdf7a6b..5cd752fdb 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -42,7 +42,7 @@ export interface FieldViewProps {
     pinToPres: (document: Doc) => void;
     removeDocument?: (document: Doc | Doc[]) => boolean;
     moveDocument?: (document: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[]) => boolean) => boolean;
-    styleProvider?: (document: Opt<Doc>, props: Opt<DocumentViewProps>, property: string, layerProvider?: (doc: Doc, assign?: boolean) => boolean) => any;
+    styleProvider?: (document: Opt<Doc>, props: Opt<DocumentViewProps>, property: string) => any;
     ScreenToLocalTransform: () => Transform;
     bringToFront: (doc: Doc, sendToBack?: boolean) => void;
     parentActive: (outsideReaction: boolean) => boolean;
diff --git a/src/client/views/nodes/FontIconBox.tsx b/src/client/views/nodes/FontIconBox.tsx
index c9ee4126e..a1bb0604e 100644
--- a/src/client/views/nodes/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox.tsx
@@ -61,7 +61,7 @@ export class FontIconBox extends DocComponent<FieldViewProps, FontIconDocument>(
     render() {
         const label = StrCast(this.rootDoc.label, StrCast(this.rootDoc.title));
         const color = StrCast(this.layoutDoc.color, this._foregroundColor);
-        const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, "backgroundColor", this.props.layerProvider);
+        const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, "backgroundColor");
         const shape = StrCast(this.layoutDoc.iconShape, label ? "round" : "circle");
         const icon = StrCast(this.dataDoc.icon, "user") as any;
         const presSize = shape === 'round' ? 25 : 30;
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx
index 1b181cef1..bf19457da 100644
--- a/src/client/views/nodes/LinkBox.tsx
+++ b/src/client/views/nodes/LinkBox.tsx
@@ -17,7 +17,7 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps, LinkDocument>(
     public static LayoutString(fieldKey: string) { return FieldView.LayoutString(LinkBox, fieldKey); }
     render() {
         return <div className={`linkBox-container${this.active() ? "-interactive" : ""}`}
-            style={{ background: this.props.styleProvider?.(this.props.Document, this.props, "backgroundColor", this.props.layerProvider) }} >
+            style={{ background: this.props.styleProvider?.(this.props.Document, this.props, "backgroundColor") }} >
 
             <CollectionTreeView {...this.props}
                 ChromeHeight={returnZero}
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index 5017b3a71..f66811098 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -18,7 +18,7 @@ interface Props {
     linkDoc?: Doc;
     linkSrc?: Doc;
     href?: string;
-    styleProvider?: (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string, layerProvider?: (doc: Doc, assign?: boolean) => boolean) => any;
+    styleProvider?: (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string) => any;
     addDocTab: (document: Doc, where: string) => boolean;
     location: number[];
 }
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 59909cea1..22e3ac1e9 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1598,7 +1598,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         const annotated = DocListCast(this.dataDoc[this.annotationKey]).filter(d => d?.author).length;
         return !this.props.isSelected() && !(annotated && !this.sidebarWidth()) ? (null) :
             <div className="formattedTextBox-sidebar-handle"
-                style={{ left: `max(0px, calc(100% - ${this.sidebarWidthPercent} ${this.sidebarWidth() ? "- 5px" : "- 10px"}))`, background: annotated ? "lightBlue" : this.props.styleProvider?.(this.props.Document, this.props, "widgetColor", this.props.layerProvider) }}
+                style={{ left: `max(0px, calc(100% - ${this.sidebarWidthPercent} ${this.sidebarWidth() ? "- 5px" : "- 10px"}))`, background: annotated ? "lightBlue" : this.props.styleProvider?.(this.props.Document, this.props, "widgetColor") }}
                 onPointerDown={this.sidebarDown}
             />;
     }
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index 9742faa2b..37752d6ee 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -322,7 +322,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                     </div>}
                 {miniView ? (null) : <div ref={miniView ? null : this._dragRef} className={`presItem-slide ${isSelected ? "active" : ""}`}
                     style={{
-                        backgroundColor: this.props.styleProvider?.(this.layoutDoc, this.props, "color", this.props.layerProvider),
+                        backgroundColor: this.props.styleProvider?.(this.layoutDoc, this.props, "color"),
                         boxShadow: presBoxColor && presBoxColor !== "white" && presBoxColor !== "transparent" ? isSelected ? "0 0 0px 1.5px" + presBoxColor : undefined : undefined
                     }}>
                     <div className="presItem-name" style={{ maxWidth: showMore ? (toolbarWidth - 195) : toolbarWidth - 105, cursor: isSelected ? 'text' : 'grab' }}>
-- 
cgit v1.2.3-70-g09d2

