From ee53c138015fcf232e424b61a4a9e5521e49ada9 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 18 Mar 2021 14:36:33 -0400
Subject: extended Doc.setFilter to allow replacing/appending a filter. fixed
 anchor unhighlighting in WebBox.  reorged some properties on baseProtos
 (usLInkSmallAnchor etc)

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

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

diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 0dbe0c917..d9c0fab02 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -101,8 +101,6 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
     getAnchor = () => {
         const anchor = Docs.Create.TextanchorDocument({
             title: StrCast(this.rootDoc.title + " " + this.layoutDoc._scrollTop),
-            useLinkSmallAnchor: true,
-            hideLinkButton: true,
             annotationOn: this.rootDoc,
             y: NumCast(this.layoutDoc._scrollTop),
         });
@@ -144,7 +142,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
     renderTag = (tag: string) => {
         const active = StrListCast(this.rootDoc[this.sidebarKey() + "-docFilters"]).includes(`${tag}:${tag}:check`);
         return <div key={tag} className={`pdfbox-filterTag${active ? "-active" : ""}`}
-            onClick={e => Doc.setDocFilter(this.rootDoc, tag, tag, "check", true, this.sidebarKey())}>
+            onClick={e => Doc.setDocFilter(this.rootDoc, tag, tag, "check", true, this.sidebarKey(), e.shiftKey)}>
             {tag}
         </div>;
     }
-- 
cgit v1.2.3-70-g09d2


From 5845674720497f87c5ccada7a188817f3c912c6e Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 18 Mar 2021 15:42:13 -0400
Subject: preparing to break sidebar out into its own component

---
 src/client/documents/Documents.ts |   2 +-
 src/client/views/nodes/PDFBox.tsx |  52 ++++----
 src/client/views/nodes/WebBox.tsx | 258 ++++++++++++++++++--------------------
 3 files changed, 152 insertions(+), 160 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 89071f75b..86ca50316 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -642,7 +642,7 @@ export namespace Docs {
          * only when creating a DockDocument from the current user's already existing
          * main document.
          */
-        export function InstanceFromProto(proto: Doc, data: Field | undefined, options: DocumentOptions, delegId?: string, fieldKey: string = "data", protoId?: string) {
+        function InstanceFromProto(proto: Doc, data: Field | undefined, options: DocumentOptions, delegId?: string, fieldKey: string = "data", protoId?: string) {
             const viewKeys = ["x", "y", "system"]; // keys that should be addded to the view document even though they don't begin with an "_"
             const { omit: dataProps, extract: viewProps } = OmitKeys(options, viewKeys, "^_");
 
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index d9c0fab02..37341253d 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -38,7 +38,7 @@ const PdfDocument = makeInterface(documentSchema, panZoomSchema, pageSchema);
 export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocument>(PdfDocument) {
     public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PDFBox, fieldKey); }
     private _searchString: string = "";
-    private _initialScale: number = 0;  // the initial scale of the PDF when first rendered which determines whether the document will be live on startup or not.  Getting bigger after startup won't make it automatically be live.
+    private _initialScrollTarget: Opt<Doc>;
     private _displayPdfLive = false; // has this box ever had its contents activated -- if so, stop drawing the overlay title
     private _pdfViewer: PDFViewer | undefined;
     private _searchRef = React.createRef<HTMLInputElement>();
@@ -50,7 +50,6 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
 
     constructor(props: any) {
         super(props);
-        this._initialScale = this.props.ScreenToLocalTransform().Scale;
         const nw = Doc.NativeWidth(this.Document, this.dataDoc) || 927;
         const nh = Doc.NativeHeight(this.Document, this.dataDoc) || 1200;
         !this.Document._fitWidth && (this.Document._height = this.Document[WidthSym]() * (nh / nw));
@@ -87,7 +86,16 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
         }
     }
 
-    initialScrollTarget: Opt<Doc>;
+    componentWillUnmount() { this._selectReactionDisposer?.(); }
+    componentDidMount() {
+        this.props.setContentView?.(this);
+        this._selectReactionDisposer = reaction(() => this.props.isSelected(),
+            () => {
+                document.removeEventListener("keydown", this.onKeyDown);
+                this.props.isSelected(true) && document.addEventListener("keydown", this.onKeyDown);
+            }, { fireImmediately: true });
+    }
+
     scrollFocus = (doc: Doc, smooth: boolean) => {
         if (DocListCast(this.rootDoc[this.sidebarKey()]).includes(doc)) {
             if (this.layoutDoc["_" + this.sidebarKey() + "-docFilters"]) {
@@ -95,7 +103,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
                 return 1;
             }
         }
-        this.initialScrollTarget = doc;
+        this._initialScrollTarget = doc;
         return this._pdfViewer?.scrollFocus(doc, smooth);
     }
     getAnchor = () => {
@@ -107,15 +115,6 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
         this.addDocument(anchor);
         return anchor;
     }
-    componentWillUnmount() { this._selectReactionDisposer?.(); }
-    componentDidMount() {
-        this.props.setContentView?.(this);
-        this._selectReactionDisposer = reaction(() => this.props.isSelected(),
-            () => {
-                document.removeEventListener("keydown", this.onKeyDown);
-                this.props.isSelected(true) && document.addEventListener("keydown", this.onKeyDown);
-            }, { fireImmediately: true });
-    }
 
     @action
     loaded = (nw: number, nh: number, np: number) => {
@@ -125,6 +124,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
         this.layoutDoc._height = this.layoutDoc[WidthSym]() / (Doc.NativeAspect(this.dataDoc) || 1);
         !this.Document._fitWidth && (this.Document._height = this.Document[WidthSym]() * (nh / nw));
     }
+
     sidebarKey = () => this.fieldKey + "-sidebar";
     sidebarFiltersHeight = () => 50;
     sidebarTransform = () => this.props.ScreenToLocalTransform().translate(Doc.NativeWidth(this.dataDoc), 0).scale(this.props.scaling?.() || 1);
@@ -134,19 +134,19 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
     sidebarMoveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean) => this.moveDocument(doc, targetCollection, addDocument, this.sidebarKey());
     sidebarRemDocument = (doc: Doc | Doc[]) => this.removeDocument(doc, this.sidebarKey());
     sidebarDocFilters = () => [...StrListCast(this.layoutDoc._docFilters), ...StrListCast(this.layoutDoc[this.sidebarKey() + "-docFilters"])];
-    @computed get allTags() {
+    @computed get sidebarAllTags() {
         const keys = new Set<string>();
         DocListCast(this.rootDoc[this.sidebarKey()]).forEach(doc => SearchBox.documentKeys(doc).forEach(key => keys.add(key)));
         return Array.from(keys.keys()).filter(key => key[0]).filter(key => !key.startsWith("_") && (key[0] === "#" || key[0] === key[0].toUpperCase())).sort();
     }
-    renderTag = (tag: string) => {
-        const active = StrListCast(this.rootDoc[this.sidebarKey() + "-docFilters"]).includes(`${tag}:${tag}:check`);
-        return <div key={tag} className={`pdfbox-filterTag${active ? "-active" : ""}`}
-            onClick={e => Doc.setDocFilter(this.rootDoc, tag, tag, "check", true, this.sidebarKey(), e.shiftKey)}>
-            {tag}
-        </div>;
-    }
     @computed get sidebarOverlay() {
+        const renderTag = (tag: string) => {
+            const active = StrListCast(this.rootDoc[this.sidebarKey() + "-docFilters"]).includes(`${tag}:${tag}:check`);
+            return <div key={tag} className={`pdfbox-filterTag${active ? "-active" : ""}`}
+                onClick={e => Doc.setDocFilter(this.rootDoc, tag, tag, "check", true, this.sidebarKey(), e.shiftKey)}>
+                {tag}
+            </div>;
+        }
         return !this.layoutDoc._showSidebar ? (null) :
             <div style={{
                 position: "absolute", pointerEvents: this.active() ? "all" : undefined, top: 0, right: 0,
@@ -183,7 +183,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
                     />
                 </div>
                 <div className="pdfBox-tagList" style={{ height: this.sidebarFiltersHeight(), width: this.sidebarWidth() }}>
-                    {this.allTags.map(tag => this.renderTag(tag))}
+                    {this.sidebarAllTags.map(renderTag)}
                 </div>
             </div>;
     }
@@ -217,9 +217,9 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
 
     setPdfViewer = (pdfViewer: PDFViewer) => {
         this._pdfViewer = pdfViewer;
-        if (this.initialScrollTarget) {
-            this.scrollFocus(this.initialScrollTarget, false);
-            this.initialScrollTarget = undefined;
+        if (this._initialScrollTarget) {
+            this.scrollFocus(this._initialScrollTarget, false);
+            this._initialScrollTarget = undefined;
         }
     }
     searchStringChanged = (e: React.ChangeEvent<HTMLInputElement>) => this._searchString = e.currentTarget.value;
@@ -303,7 +303,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
         });
         FormattedTextBox.SelectOnLoad = target[Id];
         FormattedTextBox.DontSelectInitialText = true;
-        this.allTags.map(tag => target[tag] = tag);
+        this.sidebarAllTags.map(tag => target[tag] = tag);
         DocUtils.MakeLink({ doc: anchor }, { doc: target }, "inline markup", "annotation");
         this.sidebarAddDocument(target);
     }
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 78bd6cbf6..df50f7b90 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -44,15 +44,15 @@ const WebDocument = makeInterface(documentSchema);
 @observer
 export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocument>(WebDocument) {
     public static LayoutString(fieldKey: string) { return FieldView.LayoutString(WebBox, fieldKey); }
+    private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean) => void);
     private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
     private _outerRef: React.RefObject<HTMLDivElement> = React.createRef();
     private _disposers: { [name: string]: IReactionDisposer } = {};
     private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef();
     private _keyInput = React.createRef<HTMLInputElement>();
-    @observable _scrollTimer: any;
-    @observable private _overlayAnnoInfo: Opt<Doc>;
     private _initialScroll: Opt<number>;
-    private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean) => void);
+    @observable private _scrollTimer: any;
+    @observable private _overlayAnnoInfo: Opt<Doc>;
     @observable private _marqueeing: number[] | undefined;
     @observable private _url: string = "hello";
     @observable private _isAnnotating = false;
@@ -60,11 +60,13 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
     @observable private _savedAnnotations = new ObservableMap<number, HTMLDivElement[]>();
     @observable private _scrollHeight = 1500;
     @computed get scrollHeight() { return this._scrollHeight; }
+    @computed get allAnnotations() { return DocListCast(this.dataDoc[this.annotationKey]); }
     @computed get inlineTextAnnotations() { return this.allAnnotations.filter(a => a.textInlineAnnotations); }
+    @computed get webField() { return Cast(this.dataDoc[this.props.fieldKey], WebField)?.url; }
 
     constructor(props: any) {
         super(props);
-        if (this.dataDoc[this.fieldKey] instanceof WebField) {
+        if (this.webField) {
             Doc.SetNativeWidth(this.dataDoc, Doc.NativeWidth(this.dataDoc) || 850);
             Doc.SetNativeHeight(this.dataDoc, Doc.NativeHeight(this.dataDoc) || this.Document[HeightSym]() / this.Document[WidthSym]() * 850);
         }
@@ -74,6 +76,58 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
         this._annotationKey = "annotations-" + this.urlHash(this._url);
     }
 
+    async componentDidMount() {
+        this.props.setContentView?.(this); // this tells the DocumentView that this AudioBox is the "content" of the document.  this allows the DocumentView to indirectly call getAnchor() on the AudioBox when making a link.
+
+        runInAction(() => this._url = this.webField?.toString() || "");
+
+        this._disposers.selection = reaction(() => this.props.isSelected(),
+            selected => !selected && setTimeout(() => {
+                Array.from(this._savedAnnotations.values()).forEach(v => v.forEach(a => a.remove()));
+                this._savedAnnotations.clear();
+            }));
+
+        if (this.webField?.href.indexOf("youtube") !== -1) {
+            const youtubeaspect = 400 / 315;
+            const nativeWidth = Doc.NativeWidth(this.layoutDoc);
+            const nativeHeight = Doc.NativeHeight(this.layoutDoc);
+            if (this.webField) {
+                if (!nativeWidth || !nativeHeight || Math.abs(nativeWidth / nativeHeight - youtubeaspect) > 0.05) {
+                    if (!nativeWidth) Doc.SetNativeWidth(this.layoutDoc, 600);
+                    Doc.SetNativeHeight(this.layoutDoc, (nativeWidth || 600) / youtubeaspect);
+                    this.layoutDoc._height = this.layoutDoc[WidthSym]() / youtubeaspect;
+                }
+            } // else it's an HTMLfield
+        } else if (this.webField && !this.dataDoc.text) {
+            const result = await WebRequest.get(Utils.CorsProxy(this.webField.href));
+            if (result) {
+                this.dataDoc.text = htmlToText.fromString(result.content);
+            }
+        }
+
+        var quickScroll = true;
+        this._disposers.scrollReaction = reaction(() => NumCast(this.layoutDoc._scrollTop),
+            (scrollTop) => {
+                if (quickScroll) {
+                    this._initialScroll = scrollTop;
+                }
+                else {
+                    const viewTrans = StrCast(this.Document._viewTransition);
+                    const durationMiliStr = viewTrans.match(/([0-9]*)ms/);
+                    const durationSecStr = viewTrans.match(/([0-9.]*)s/);
+                    const duration = durationMiliStr ? Number(durationMiliStr[1]) : durationSecStr ? Number(durationSecStr[1]) * 1000 : 0;
+                    this.goTo(scrollTop, duration);
+                }
+            },
+            { fireImmediately: true }
+        );
+        quickScroll = false;
+    }
+    componentWillUnmount() {
+        Object.values(this._disposers).forEach(disposer => disposer?.());
+        this._iframe?.removeEventListener('wheel', this.iframeWheel, true);
+    }
+
     @action
     createTextAnnotation = (sel: Selection, selRange: Range) => {
         if (this._mainCont.current) {
@@ -102,6 +156,32 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
         }
     }
 
+    menuControls = () => this.urlEditor; // controls to be added to the top bar when a document of this type is selected
+
+    scrollFocus = (doc: Doc, smooth: boolean) => {
+        if (doc !== this.rootDoc && this._outerRef.current) {
+            const scrollTo = doc.type === DocumentType.TEXTANCHOR ? NumCast(doc.y) : Utils.scrollIntoView(NumCast(doc.y), doc[HeightSym](), NumCast(this.layoutDoc._scrollTop), this.props.PanelHeight() / (this.props.scaling?.() || 1));
+            if (scrollTo !== undefined) {
+                const focusSpeed = smooth ? 500 : 0;
+                this._initialScroll !== undefined && (this._initialScroll = scrollTo);
+                this.goTo(scrollTo, focusSpeed);
+                return focusSpeed;
+            }
+        }
+        this._initialScroll = NumCast(doc.y);
+        return 0;
+    }
+
+    getAnchor = () => {
+        const anchor = Docs.Create.TextanchorDocument({
+            title: StrCast(this.rootDoc.title + " " + this.layoutDoc._scrollTop),
+            annotationOn: this.rootDoc,
+            y: NumCast(this.layoutDoc._scrollTop),
+        });
+        this.addDocument(anchor);
+        return anchor;
+    }
+
     @action
     iframeUp = (e: PointerEvent) => {
         if (this._iframe?.contentWindow && this._iframe.contentDocument && !this._iframe.contentWindow.getSelection()?.isCollapsed) {
@@ -151,8 +231,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
                 for (let ele = e.target; ele; ele = ele.parentElement) {
                     href = (typeof (ele.href) === "string" ? ele.href : ele.href?.baseVal) || ele.parentElement?.href || href;
                 }
-                if (href) {
-                    this.submitURL(href.replace(Utils.prepend(""), Cast(this.dataDoc[this.fieldKey], WebField, null)?.url.origin));
+                if (href && this.webField?.origin) {
+                    this.submitURL(href.replace(Utils.prepend(""), this.webField?.origin));
                     if (this._outerRef.current) {
                         this._outerRef.current.scrollTop = NumCast(this.layoutDoc._scrollTop);
                         this._outerRef.current.scrollLeft = 0;
@@ -164,6 +244,13 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
         }
     }
 
+    @action
+    iframeWheel = (e: any) => {
+        if (!this._scrollTimer) {
+            this._scrollTimer = setTimeout(action(() => this._scrollTimer = undefined), 250); // this turns events off on the iframe which allows scrolling to change direction smoothly
+        }
+    }
+
     @action
     setDashScrollTop = (scrollTop: number, timeout: number = 250) => {
         const iframeHeight = Math.max(1000, this._scrollHeight - this.panelHeight());
@@ -177,90 +264,6 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
             }
         }), timeout);
     }
-    @action
-    iframeWheel = (e: any) => {
-        if (!this._scrollTimer) {
-            this._scrollTimer = setTimeout(action(() => this._scrollTimer = undefined), 250); // this turns events off on the iframe which allows scrolling to change direction smoothly
-        }
-    }
-    onWheel = (e: any) => {
-        e.stopPropagation();
-        e.preventDefault();
-    }
-    onScroll = (e: any) => this.setDashScrollTop(this._outerRef.current?.scrollTop || 0);
-    scrollFocus = (doc: Doc, smooth: boolean) => {
-        if (doc !== this.rootDoc && this._outerRef.current) {
-            const scrollTo = doc.type === DocumentType.TEXTANCHOR ? NumCast(doc.y) : Utils.scrollIntoView(NumCast(doc.y), doc[HeightSym](), NumCast(this.layoutDoc._scrollTop), this.props.PanelHeight() / (this.props.scaling?.() || 1));
-            if (scrollTo !== undefined) {
-                const focusSpeed = smooth ? 500 : 0;
-                this._initialScroll !== undefined && (this._initialScroll = scrollTo);
-                this.goTo(scrollTo, focusSpeed);
-                return focusSpeed;
-            }
-        }
-        this._initialScroll = NumCast(doc.y);
-        return 0;
-    }
-
-    getAnchor = () => {
-        const anchor = Docs.Create.TextanchorDocument({
-            title: StrCast(this.rootDoc.title + " " + this.layoutDoc._scrollTop),
-            annotationOn: this.rootDoc,
-            y: NumCast(this.layoutDoc._scrollTop),
-        });
-        this.addDocument(anchor);
-        return anchor;
-    }
-
-    async componentDidMount() {
-        this.props.setContentView?.(this); // this tells the DocumentView that this AudioBox is the "content" of the document.  this allows the DocumentView to indirectly call getAnchor() on the AudioBox when making a link.
-
-        const urlField = Cast(this.dataDoc[this.props.fieldKey], WebField);
-        runInAction(() => this._url = urlField?.url.toString() || "");
-
-        this._disposers.selection = reaction(() => this.props.isSelected(),
-            selected => !selected && setTimeout(() => {
-                Array.from(this._savedAnnotations.values()).forEach(v => v.forEach(a => a.remove()));
-                this._savedAnnotations.clear();
-            }));
-
-        const field = Cast(this.rootDoc[this.props.fieldKey], WebField);
-        if (field?.url.href.indexOf("youtube") !== -1) {
-            const youtubeaspect = 400 / 315;
-            const nativeWidth = Doc.NativeWidth(this.layoutDoc);
-            const nativeHeight = Doc.NativeHeight(this.layoutDoc);
-            if (field) {
-                if (!nativeWidth || !nativeHeight || Math.abs(nativeWidth / nativeHeight - youtubeaspect) > 0.05) {
-                    if (!nativeWidth) Doc.SetNativeWidth(this.layoutDoc, 600);
-                    Doc.SetNativeHeight(this.layoutDoc, (nativeWidth || 600) / youtubeaspect);
-                    this.layoutDoc._height = this.layoutDoc[WidthSym]() / youtubeaspect;
-                }
-            } // else it's an HTMLfield
-        } else if (field?.url && !this.dataDoc.text) {
-            const result = await WebRequest.get(Utils.CorsProxy(field.url.href));
-            if (result) {
-                this.dataDoc.text = htmlToText.fromString(result.content);
-            }
-        }
-
-        var quickScroll = true;
-        this._disposers.scrollReaction = reaction(() => NumCast(this.layoutDoc._scrollTop),
-            (scrollTop) => {
-                if (quickScroll) {
-                    this._initialScroll = scrollTop;
-                }
-                else {
-                    const viewTrans = StrCast(this.Document._viewTransition);
-                    const durationMiliStr = viewTrans.match(/([0-9]*)ms/);
-                    const durationSecStr = viewTrans.match(/([0-9.]*)s/);
-                    const duration = durationMiliStr ? Number(durationMiliStr[1]) : durationSecStr ? Number(durationSecStr[1]) * 1000 : 0;
-                    this.goTo(scrollTop, duration);
-                }
-            },
-            { fireImmediately: true }
-        );
-        quickScroll = false;
-    }
 
     goTo = (scrollTop: number, duration: number) => {
         if (this._outerRef.current) {
@@ -275,11 +278,6 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
         }
     }
 
-    componentWillUnmount() {
-        Object.values(this._disposers).forEach(disposer => disposer?.());
-        this._iframe?.removeEventListener('wheel', this.iframeWheel, true);
-    }
-
     @action
     forward = () => {
         const future = Cast(this.dataDoc[this.fieldKey + "-future"], listSpec("string"), null);
@@ -312,12 +310,13 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
     }
 
     @action
-    submitURL = (newUrl: string) => {
+    submitURL = (newUrl?: string) => {
+        if (!newUrl) return;
         if (!newUrl.startsWith("http")) newUrl = "http://" + newUrl;
         try {
             const future = Cast(this.dataDoc[this.fieldKey + "-future"], listSpec("string"), null);
             const history = Cast(this.dataDoc[this.fieldKey + "-history"], listSpec("string"), null);
-            const url = Cast(this.dataDoc[this.fieldKey], WebField, null)?.url.toString();
+            const url = this.webField?.toString();
             if (url) {
                 if (history === undefined) {
                     this.dataDoc[this.fieldKey + "-history"] = new List<string>([url]);
@@ -336,7 +335,6 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
         return true;
     }
 
-    menuControls = () => this.urlEditor;
     onWebUrlDrop = (e: React.DragEvent) => {
         const { dataTransfer } = e;
         const html = dataTransfer.getData("text/html");
@@ -371,12 +369,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
                     <button className="submitUrl" onClick={() => this.submitURL(this._keyInput.current!.value)} onDragOver={e => e.stopPropagation()} onDrop={this.onWebUrlDrop}>
                         GO
                     </button>
-                    <button className="submitUrl" onClick={this.back}>
-                        <FontAwesomeIcon icon="caret-left" size="lg"></FontAwesomeIcon>
-                    </button>
-                    <button className="submitUrl" onClick={this.forward}>
-                        <FontAwesomeIcon icon="caret-right" size="lg"></FontAwesomeIcon>
-                    </button>
+                    <button className="submitUrl" onClick={this.back}> <FontAwesomeIcon icon="caret-left" size="lg" /> </button>
+                    <button className="submitUrl" onClick={this.forward}> <FontAwesomeIcon icon="caret-right" size="lg" />  </button>
                 </div>
             </div>
         );
@@ -391,6 +385,19 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
         cm.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" });
     }
 
+    @action
+    onMarqueeDown = (e: React.PointerEvent) => {
+        if (!e.altKey && e.button === 0 && this.active(true)) {
+            this._marqueeing = [e.clientX, e.clientY];
+            this.props.select(false);
+        }
+    }
+    @action finishMarquee = (x?: number, y?: number) => {
+        this._marqueeing = undefined;
+        this._isAnnotating = false;
+        x !== undefined && y !== undefined && this._setPreviewCursor?.(x, y, false);
+    }
+
     @computed
     get urlContent() {
         const field = this.dataDoc[this.props.fieldKey];
@@ -424,7 +431,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
         });
         FormattedTextBox.SelectOnLoad = target[Id];
         FormattedTextBox.DontSelectInitialText = true;
-        this.allTags.map(tag => target[tag] = tag);
+        this.sidebarAllTags.map(tag => target[tag] = tag);
         DocUtils.MakeLink({ doc: anchor }, { doc: target }, "inline markup", "annotation");
         this.sidebarAddDocument(target);
     }
@@ -445,19 +452,19 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
     sidebarMoveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean) => this.moveDocument(doc, targetCollection, addDocument, this.sidebarKey());
     sidebarRemDocument = (doc: Doc | Doc[]) => this.removeDocument(doc, this.sidebarKey());
     sidebarDocFilters = () => [...StrListCast(this.layoutDoc._docFilters), ...StrListCast(this.layoutDoc[this.sidebarKey() + "-docFilters"])];
-    @computed get allTags() {
+    @computed get sidebarAllTags() {
         const keys = new Set<string>();
         DocListCast(this.rootDoc[this.sidebarKey()]).forEach(doc => SearchBox.documentKeys(doc).forEach(key => keys.add(key)));
         return Array.from(keys.keys()).filter(key => key[0]).filter(key => !key.startsWith("_") && (key[0] === "#" || key[0] === key[0].toUpperCase())).sort();
     }
-    renderTag = (tag: string) => {
-        const active = StrListCast(this.rootDoc[this.sidebarKey() + "-docFilters"]).includes(`${tag}:${tag}:check`);
-        return <div className={`webBox-filterTag${active ? "-active" : ""}`}
-            onClick={e => Doc.setDocFilter(this.rootDoc, tag, tag, "check", true, this.sidebarKey(), e.shiftKey)}>
-            {tag}
-        </div>;
-    }
     @computed get sidebarOverlay() {
+        const renderTag = (tag: string) => {
+            const active = StrListCast(this.rootDoc[this.sidebarKey() + "-docFilters"]).includes(`${tag}:${tag}:check`);
+            return <div className={`webBox-filterTag${active ? "-active" : ""}`}
+                onClick={e => Doc.setDocFilter(this.rootDoc, tag, tag, "check", true, this.sidebarKey(), e.shiftKey)}>
+                {tag}
+            </div>;
+        }
         return !this.layoutDoc._showSidebar ? (null) :
             <div style={{
                 position: "absolute", pointerEvents: this.active() ? "all" : undefined, top: 0, right: 0,
@@ -494,21 +501,18 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
                     />
                 </div>
                 <div className="webBox-tagList" style={{ height: this.sidebarFiltersHeight(), width: this.sidebarWidth() }}>
-                    {this.allTags.map(tag => this.renderTag(tag))}
+                    {this.sidebarAllTags.map(renderTag)}
                 </div>
             </div>;
     }
 
-    @computed
-    get content() {
+    @computed get content() {
         return <div className={"webBox-cont" + (this.active() && CurrentUserUtils.SelectedTool === InkTool.None && !DocumentDecorations.Instance?.Interacting ? "-interactive" : "")}
             style={{ width: NumCast(this.layoutDoc[this.fieldKey + "-contentWidth"]) || `${100 / (this.props.scaling?.() || 1)}%`, }}>
             {this.urlContent}
         </div>;
     }
 
-    showInfo = action((anno: Opt<Doc>) => this._overlayAnnoInfo = anno);
-    @computed get allAnnotations() { return DocListCast(this.dataDoc[this.annotationKey]); }
     @computed get annotationLayer() {
         TraceMobx();
         return <div className="webBox-annotationLayer" style={{ height: Doc.NativeHeight(this.Document) || undefined }} ref={this._annotationLayer}>
@@ -518,20 +522,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
         </div>;
     }
 
-    @action
-    onMarqueeDown = (e: React.PointerEvent) => {
-        if (!e.altKey && e.button === 0 && this.active(true)) {
-            this._marqueeing = [e.clientX, e.clientY];
-            this.props.select(false);
-        }
-    }
+    showInfo = action((anno: Opt<Doc>) => this._overlayAnnoInfo = anno);
     setPreviewCursor = (func?: (x: number, y: number, drag: boolean) => void) => this._setPreviewCursor = func;
-    @action finishMarquee = (x?: number, y?: number) => {
-        this._marqueeing = undefined;
-        this._isAnnotating = false;
-        x !== undefined && y !== undefined && this._setPreviewCursor?.(x, y, false);
-    }
-
     panelWidth = () => this.props.PanelWidth() / (this.props.scaling?.() || 1) - this.sidebarWidth(); // (this.Document.scrollHeight || Doc.NativeHeight(this.Document) || 0);
     panelHeight = () => this.props.PanelHeight() / (this.props.scaling?.() || 1); // () => this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : Doc.NativeWidth(this.Document);
     scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._scrollTop));
@@ -551,8 +543,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
                             transform: `scale(${scale})`,
                             pointerEvents: inactiveLayer ? "none" : undefined
                         }}
-                        onWheel={this.onWheel}
-                        onScroll={this.onScroll}
+                        onWheel={e => { e.stopPropagation(); e.preventDefault(); }} // block wheel events from propagating since they're handled by the iframe
+                        onScroll={e => this.setDashScrollTop(this._outerRef.current?.scrollTop || 0)}
                         onPointerDown={this.onMarqueeDown}
                     >
                         <div className={"webBox-innerContent"} style={{
-- 
cgit v1.2.3-70-g09d2


From 05bcab12516e48ef08f9c7243a5e0acd3c650f20 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 18 Mar 2021 16:27:17 -0400
Subject: broke sidebarAnnos into its own component

---
 src/client/views/SidebarAnnos.scss |  20 +++++++
 src/client/views/SidebarAnnos.tsx  | 104 +++++++++++++++++++++++++++++++++++++
 src/client/views/nodes/PDFBox.scss |  21 +-------
 src/client/views/nodes/PDFBox.tsx  | 101 ++++++++---------------------------
 src/client/views/nodes/WebBox.scss |  20 -------
 src/client/views/nodes/WebBox.tsx  |  80 ++++++----------------------
 6 files changed, 163 insertions(+), 183 deletions(-)
 create mode 100644 src/client/views/SidebarAnnos.scss
 create mode 100644 src/client/views/SidebarAnnos.tsx

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

diff --git a/src/client/views/SidebarAnnos.scss b/src/client/views/SidebarAnnos.scss
new file mode 100644
index 000000000..9eea83d59
--- /dev/null
+++ b/src/client/views/SidebarAnnos.scss
@@ -0,0 +1,20 @@
+.sidebarAnnos-tagList {
+    display: flex;
+    flex-direction: row;
+    overflow: auto;
+    flex-flow: row;
+    flex-wrap: wrap;
+    .sidebarAnnos-filterTag, .sidebarAnnos-filterTag-active {
+        font-weight: bold;
+        padding-left: 6;
+        padding-right: 6;
+        box-shadow: black 1px 1px 4px;
+        border-radius: 5;
+        margin: 2; 
+        height: 20;
+        background-color: lightgrey;
+    }
+    .sidebarAnnos-filterTag-active {
+        background-color: white;
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx
new file mode 100644
index 000000000..026942999
--- /dev/null
+++ b/src/client/views/SidebarAnnos.tsx
@@ -0,0 +1,104 @@
+import { computed } from 'mobx';
+import { observer } from "mobx-react";
+import { Doc, DocListCast, StrListCast } from "../../fields/Doc";
+import { List } from '../../fields/List';
+import { NumCast } from '../../fields/Types';
+import { emptyFunction, OmitKeys, returnOne, returnTrue, returnZero } from '../../Utils';
+import { Transform } from '../util/Transform';
+import { CollectionStackingView } from './collections/CollectionStackingView';
+import { CollectionViewType } from './collections/CollectionView';
+import { FieldViewProps } from './nodes/FieldView';
+import { SearchBox } from './search/SearchBox';
+import "./SidebarAnnos.scss";
+import { StyleProp } from './StyleProvider';
+import React = require("react");
+
+interface extraProps {
+    fieldKey: string;
+    layoutDoc: Doc;
+    rootDoc: Doc;
+    dataDoc: Doc;
+    annotationsActive: (outsideReaction: boolean) => boolean;
+    whenActiveChanged: (isActive: boolean) => void;
+    ScreenToLocalTransform: () => Transform;
+    addDocument: (doc: (Doc | Doc[]), suffix: string) => boolean;
+    removeDocument: (doc: (Doc | Doc[]), suffix: string) => boolean;
+    moveDocument: (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean, annotationKey?: string) => boolean;
+}
+@observer
+export class SidebarAnnos extends React.Component<FieldViewProps & extraProps> {
+    @computed get allHashtags() {
+        const keys = new Set<string>();
+        DocListCast(this.props.rootDoc[this.sidebarKey()]).forEach(doc => SearchBox.documentKeys(doc).forEach(key => keys.add(key)));
+        return Array.from(keys.keys()).filter(key => key[0]).filter(key => !key.startsWith("_") && (key[0] === "#" || key[0] === key[0].toUpperCase())).sort();
+    }
+    get filtersKey() { return "_" + this.sidebarKey() + "-docFilters"; }
+
+    makeDocUnfiltered = (doc: Doc) => {
+        if (DocListCast(this.props.rootDoc[this.sidebarKey()]).includes(doc)) {
+            if (this.props.layoutDoc[this.filtersKey]) {
+                this.props.layoutDoc[this.filtersKey] = new List<string>();
+                return true;
+            }
+        }
+        return false;
+    }
+    sidebarKey = () => this.props.fieldKey + "-sidebar";
+    filtersHeight = () => 50;
+    screenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(Doc.NativeWidth(this.props.dataDoc), 0).scale(this.props.scaling?.() || 1);
+    panelWidth = () => !this.props.layoutDoc._showSidebar ? 0 : (NumCast(this.props.layoutDoc.nativeWidth) - Doc.NativeWidth(this.props.dataDoc)) * this.props.PanelWidth() / NumCast(this.props.layoutDoc.nativeWidth);
+    panelHeight = () => this.props.PanelHeight() - this.filtersHeight() - 20;
+    addDocument = (doc: Doc | Doc[]) => this.props.addDocument(doc, this.sidebarKey());
+    moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean) => this.props.moveDocument(doc, targetCollection, addDocument, this.sidebarKey());
+    removeDocument = (doc: Doc | Doc[]) => this.props.removeDocument(doc, this.sidebarKey());
+    docFilters = () => [...StrListCast(this.props.layoutDoc._docFilters), ...StrListCast(this.props.layoutDoc[this.filtersKey])];
+
+    render() {
+        const renderTag = (tag: string) => {
+            const active = StrListCast(this.props.rootDoc[this.filtersKey]).includes(`${tag}:${tag}:check`);
+            return <div key={tag} className={`sidebarAnnos-filterTag${active ? "-active" : ""}`}
+                onClick={e => Doc.setDocFilter(this.props.rootDoc, tag, tag, "check", true, this.sidebarKey(), e.shiftKey)}>
+                {tag}
+            </div>;
+        }
+        return !this.props.layoutDoc._showSidebar ? (null) :
+            <div style={{
+                position: "absolute", pointerEvents: this.props.active() ? "all" : undefined, top: 0, right: 0,
+                background: this.props.styleProvider?.(this.props.rootDoc, this.props, StyleProp.WidgetColor),
+                width: `${this.panelWidth()}px`,
+                height: "100%"
+            }}>
+                <div style={{ width: "100%", height: this.panelHeight(), position: "relative" }}>
+                    <CollectionStackingView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit}
+                        NativeWidth={returnZero}
+                        NativeHeight={returnZero}
+                        PanelHeight={this.panelHeight}
+                        PanelWidth={this.panelWidth}
+                        xMargin={0}
+                        yMargin={0}
+                        docFilters={this.docFilters}
+                        chromeStatus={"enabled"}
+                        scaleField={this.sidebarKey() + "-scale"}
+                        isAnnotationOverlay={false}
+                        select={emptyFunction}
+                        active={this.props.annotationsActive}
+                        scaling={returnOne}
+                        whenActiveChanged={this.props.whenActiveChanged}
+                        childHideDecorationTitle={returnTrue}
+                        removeDocument={this.removeDocument}
+                        moveDocument={this.moveDocument}
+                        addDocument={this.addDocument}
+                        CollectionView={undefined}
+                        ScreenToLocalTransform={this.screenToLocalTransform}
+                        renderDepth={this.props.renderDepth + 1}
+                        viewType={CollectionViewType.Stacking}
+                        fieldKey={this.sidebarKey()}
+                        pointerEvents={"all"}
+                    />
+                </div>
+                <div className="sidebarAnnos-tagList" style={{ height: this.filtersHeight(), width: this.panelWidth() }}>
+                    {this.allHashtags.map(renderTag)}
+                </div>
+            </div>;
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss
index 564873cf5..d1dca5c68 100644
--- a/src/client/views/nodes/PDFBox.scss
+++ b/src/client/views/nodes/PDFBox.scss
@@ -189,26 +189,7 @@
         }
     }
 
-    .pdfBox-tagList {
-        display: flex;
-        flex-direction: row;
-        overflow: auto;
-        flex-flow: row;
-        flex-wrap: wrap;
-        .pdfBox-filterTag, .pdfBox-filterTag-active {
-            font-weight: bold;
-            padding-left: 6;
-            padding-right: 6;
-            box-shadow: black 1px 1px 4px;
-            border-radius: 5;
-            margin: 2; 
-            height: 20;
-            background-color: lightgrey;
-        }
-        .pdfBox-filterTag-active {
-            background-color: white;
-        }
-    }
+    
     .pdfBox-title-outer {
         width: 100%;
         height: 100%;
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 37341253d..81ef2472a 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -6,30 +6,27 @@ import "pdfjs-dist/web/pdf_viewer.css";
 import { Doc, DocListCast, Opt, StrListCast, WidthSym } from "../../../fields/Doc";
 import { documentSchema } from '../../../fields/documentSchemas';
 import { Id } from '../../../fields/FieldSymbols';
+import { List } from '../../../fields/List';
 import { makeInterface } from "../../../fields/Schema";
 import { Cast, NumCast, StrCast } from '../../../fields/Types';
 import { PdfField } from "../../../fields/URLField";
 import { TraceMobx } from '../../../fields/util';
-import { emptyFunction, OmitKeys, returnOne, returnTrue, returnZero, Utils } from '../../../Utils';
+import { Utils } from '../../../Utils';
 import { Docs, DocUtils } from '../../documents/Documents';
 import { KeyCodes } from '../../util/KeyCodes';
 import { undoBatch } from '../../util/UndoManager';
 import { panZoomSchema } from '../collections/collectionFreeForm/CollectionFreeFormView';
-import { CollectionStackingView } from '../collections/CollectionStackingView';
 import { CollectionViewType } from '../collections/CollectionView';
 import { ContextMenu } from '../ContextMenu';
 import { ContextMenuProps } from '../ContextMenuItem';
 import { ViewBoxAnnotatableComponent } from "../DocComponent";
 import { PDFViewer } from "../pdf/PDFViewer";
-import { SearchBox } from '../search/SearchBox';
-import { StyleProp } from '../StyleProvider';
+import { SidebarAnnos } from '../SidebarAnnos';
 import { FieldView, FieldViewProps } from './FieldView';
 import { FormattedTextBox } from './formattedText/FormattedTextBox';
 import { pageSchema } from "./ImageBox";
 import "./PDFBox.scss";
 import React = require("react");
-import { DocFocusOptions } from './DocumentView';
-import { List } from '../../../fields/List';
 
 type PdfDocument = makeInterface<[typeof documentSchema, typeof panZoomSchema, typeof pageSchema]>;
 const PdfDocument = makeInterface(documentSchema, panZoomSchema, pageSchema);
@@ -43,6 +40,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
     private _pdfViewer: PDFViewer | undefined;
     private _searchRef = React.createRef<HTMLInputElement>();
     private _selectReactionDisposer: IReactionDisposer | undefined;
+    private _sidebarRef = React.createRef<SidebarAnnos>();
 
     @observable private _searching: boolean = false;
     @observable private _pdf: Opt<Pdfjs.PDFDocumentProxy>;
@@ -97,12 +95,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
     }
 
     scrollFocus = (doc: Doc, smooth: boolean) => {
-        if (DocListCast(this.rootDoc[this.sidebarKey()]).includes(doc)) {
-            if (this.layoutDoc["_" + this.sidebarKey() + "-docFilters"]) {
-                this.layoutDoc["_" + this.sidebarKey() + "-docFilters"] = new List<string>();
-                return 1;
-            }
-        }
+        if (this._sidebarRef?.current?.makeDocUnfiltered(doc)) return 1;
         this._initialScrollTarget = doc;
         return this._pdfViewer?.scrollFocus(doc, smooth);
     }
@@ -125,69 +118,6 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
         !this.Document._fitWidth && (this.Document._height = this.Document[WidthSym]() * (nh / nw));
     }
 
-    sidebarKey = () => this.fieldKey + "-sidebar";
-    sidebarFiltersHeight = () => 50;
-    sidebarTransform = () => this.props.ScreenToLocalTransform().translate(Doc.NativeWidth(this.dataDoc), 0).scale(this.props.scaling?.() || 1);
-    sidebarWidth = () => !this.layoutDoc._showSidebar ? 0 : (NumCast(this.layoutDoc.nativeWidth) - Doc.NativeWidth(this.dataDoc)) * this.props.PanelWidth() / NumCast(this.layoutDoc.nativeWidth);
-    sidebarHeight = () => this.props.PanelHeight() - this.sidebarFiltersHeight() - 20;
-    sidebarAddDocument = (doc: Doc | Doc[]) => this.addDocument(doc, this.sidebarKey());
-    sidebarMoveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean) => this.moveDocument(doc, targetCollection, addDocument, this.sidebarKey());
-    sidebarRemDocument = (doc: Doc | Doc[]) => this.removeDocument(doc, this.sidebarKey());
-    sidebarDocFilters = () => [...StrListCast(this.layoutDoc._docFilters), ...StrListCast(this.layoutDoc[this.sidebarKey() + "-docFilters"])];
-    @computed get sidebarAllTags() {
-        const keys = new Set<string>();
-        DocListCast(this.rootDoc[this.sidebarKey()]).forEach(doc => SearchBox.documentKeys(doc).forEach(key => keys.add(key)));
-        return Array.from(keys.keys()).filter(key => key[0]).filter(key => !key.startsWith("_") && (key[0] === "#" || key[0] === key[0].toUpperCase())).sort();
-    }
-    @computed get sidebarOverlay() {
-        const renderTag = (tag: string) => {
-            const active = StrListCast(this.rootDoc[this.sidebarKey() + "-docFilters"]).includes(`${tag}:${tag}:check`);
-            return <div key={tag} className={`pdfbox-filterTag${active ? "-active" : ""}`}
-                onClick={e => Doc.setDocFilter(this.rootDoc, tag, tag, "check", true, this.sidebarKey(), e.shiftKey)}>
-                {tag}
-            </div>;
-        }
-        return !this.layoutDoc._showSidebar ? (null) :
-            <div style={{
-                position: "absolute", pointerEvents: this.active() ? "all" : undefined, top: 0, right: 0,
-                background: this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.WidgetColor),
-                width: `${this.sidebarWidth()}px`,
-                height: "100%"
-            }}>
-                <div style={{ width: "100%", height: this.sidebarHeight(), position: "relative" }}>
-                    <CollectionStackingView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit}
-                        NativeWidth={returnZero}
-                        NativeHeight={returnZero}
-                        PanelHeight={this.sidebarHeight}
-                        PanelWidth={this.sidebarWidth}
-                        xMargin={0}
-                        yMargin={0}
-                        docFilters={this.sidebarDocFilters}
-                        chromeStatus={"enabled"}
-                        scaleField={this.sidebarKey() + "-scale"}
-                        isAnnotationOverlay={false}
-                        select={emptyFunction}
-                        active={this.annotationsActive}
-                        scaling={returnOne}
-                        whenActiveChanged={this.whenActiveChanged}
-                        childHideDecorationTitle={returnTrue}
-                        removeDocument={this.sidebarRemDocument}
-                        moveDocument={this.sidebarMoveDocument}
-                        addDocument={this.sidebarAddDocument}
-                        CollectionView={undefined}
-                        ScreenToLocalTransform={this.sidebarTransform}
-                        renderDepth={this.props.renderDepth + 1}
-                        viewType={CollectionViewType.Stacking}
-                        fieldKey={this.sidebarKey()}
-                        pointerEvents={"all"}
-                    />
-                </div>
-                <div className="pdfBox-tagList" style={{ height: this.sidebarFiltersHeight(), width: this.sidebarWidth() }}>
-                    {this.sidebarAllTags.map(renderTag)}
-                </div>
-            </div>;
-    }
-
     public search = (string: string, fwd: boolean) => { this._pdfViewer?.search(string, fwd); };
     public prevAnnotation = () => { this._pdfViewer?.prevAnnotation(); };
     public nextAnnotation = () => { this._pdfViewer?.nextAnnotation(); };
@@ -281,6 +211,8 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
                 </button>
             </div>);
     }
+    sidebarWidth = () => !this.layoutDoc._showSidebar ? 0 : (NumCast(this.layoutDoc.nativeWidth) - Doc.NativeWidth(this.dataDoc)) * this.props.PanelWidth() / NumCast(this.layoutDoc.nativeWidth);
+
 
     specificContextMenu = (e: React.MouseEvent): void => {
         const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField);
@@ -294,7 +226,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
     }
 
     anchorMenuClick = (anchor: Doc) => {
-        this.Document._showSidebar = true;
+        this.props.Document._showSidebar = true;
         const startup = StrListCast(this.rootDoc.docFilters).map(filter => filter.split(":")[0]).join(" ");
         const target = Docs.Create.TextDocument(startup, {
             title: "anno",
@@ -303,9 +235,9 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
         });
         FormattedTextBox.SelectOnLoad = target[Id];
         FormattedTextBox.DontSelectInitialText = true;
-        this.sidebarAllTags.map(tag => target[tag] = tag);
+        //this.sidebarAllTags.map(tag => target[tag] = tag);
         DocUtils.MakeLink({ doc: anchor }, { doc: target }, "inline markup", "annotation");
-        this.sidebarAddDocument(target);
+        this._sidebarRef.current?.addDocument(target);
     }
 
     @computed get renderTitleBox() {
@@ -316,6 +248,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
             </div>
         </div>;
     }
+
     @computed get renderPdfView() {
         TraceMobx();
         const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField);
@@ -335,7 +268,17 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
                 ContentScaling={this.props.scaling}
                 sidebarWidth={this.sidebarWidth}
             />
-            {this.sidebarOverlay}
+            <SidebarAnnos ref={this._sidebarRef}
+                {...this.props}
+                annotationsActive={this.annotationsActive}
+                rootDoc={this.rootDoc}
+                layoutDoc={this.layoutDoc}
+                dataDoc={this.dataDoc}
+                addDocument={this.addDocument}
+                moveDocument={this.moveDocument}
+                removeDocument={this.removeDocument}
+                active={this.active}
+            />
             {this.settingsPanel()}
         </div>;
     }
diff --git a/src/client/views/nodes/WebBox.scss b/src/client/views/nodes/WebBox.scss
index cdff4aa74..ca82c049c 100644
--- a/src/client/views/nodes/WebBox.scss
+++ b/src/client/views/nodes/WebBox.scss
@@ -18,26 +18,6 @@
         border-radius: 3px;
         pointer-events: all;
     }
-    .webBox-tagList {
-        display: flex;
-        flex-direction: row;
-        overflow: auto;
-        flex-flow: row;
-        flex-wrap: wrap;
-        .webBox-filterTag, .webBox-filterTag-active {
-            font-weight: bold;
-            padding-left: 6;
-            padding-right: 6;
-            box-shadow: black 1px 1px 4px;
-            border-radius: 5;
-            margin: 2; 
-            height: 20;
-            background-color: lightgrey;
-        }
-        .webBox-filterTag-active {
-            background-color: white;
-        }
-    }
 
     .pdfViewerDash-dragAnnotationBox {
         position: absolute;
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index df50f7b90..2a0fc47b4 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -36,6 +36,7 @@ import { FormattedTextBox } from "./formattedText/FormattedTextBox";
 import { LinkDocPreview } from "./LinkDocPreview";
 import "./WebBox.scss";
 import React = require("react");
+import { SidebarAnnos } from "../SidebarAnnos";
 const htmlToText = require("html-to-text");
 
 type WebDocument = makeInterface<[typeof documentSchema]>;
@@ -51,6 +52,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
     private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef();
     private _keyInput = React.createRef<HTMLInputElement>();
     private _initialScroll: Opt<number>;
+    private _sidebarRef = React.createRef<SidebarAnnos>();
     @observable private _scrollTimer: any;
     @observable private _overlayAnnoInfo: Opt<Doc>;
     @observable private _marqueeing: number[] | undefined;
@@ -159,6 +161,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
     menuControls = () => this.urlEditor; // controls to be added to the top bar when a document of this type is selected
 
     scrollFocus = (doc: Doc, smooth: boolean) => {
+        if (this._sidebarRef?.current?.makeDocUnfiltered(doc)) return 1;
         if (doc !== this.rootDoc && this._outerRef.current) {
             const scrollTo = doc.type === DocumentType.TEXTANCHOR ? NumCast(doc.y) : Utils.scrollIntoView(NumCast(doc.y), doc[HeightSym](), NumCast(this.layoutDoc._scrollTop), this.props.PanelHeight() / (this.props.scaling?.() || 1));
             if (scrollTo !== undefined) {
@@ -431,9 +434,9 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
         });
         FormattedTextBox.SelectOnLoad = target[Id];
         FormattedTextBox.DontSelectInitialText = true;
-        this.sidebarAllTags.map(tag => target[tag] = tag);
+        //this.sidebarAllTags.map(tag => target[tag] = tag);
         DocUtils.MakeLink({ doc: anchor }, { doc: target }, "inline markup", "annotation");
-        this.sidebarAddDocument(target);
+        this._sidebarRef.current?.addDocument(target);
     }
     toggleSidebar = () => {
         if (this.layoutDoc.nativeWidth === this.layoutDoc[this.fieldKey + "-nativeWidth"]) {
@@ -443,68 +446,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
         }
         this.layoutDoc._width = NumCast(this.layoutDoc._nativeWidth) * (NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]) / NumCast(this.layoutDoc[this.fieldKey + "-nativeHeight"]));
     }
-    sidebarKey = () => this.fieldKey + "-sidebar";
-    sidebarFiltersHeight = () => 50;
-    sidebarTransform = () => this.props.ScreenToLocalTransform().translate(Doc.NativeWidth(this.dataDoc), 0).scale(this.props.scaling?.() || 1);
     sidebarWidth = () => !this.layoutDoc._showSidebar ? 0 : (NumCast(this.layoutDoc.nativeWidth) - Doc.NativeWidth(this.dataDoc)) * this.props.PanelWidth() / NumCast(this.layoutDoc.nativeWidth);
-    sidebarHeight = () => this.props.PanelHeight() - this.sidebarFiltersHeight() - 20;
-    sidebarAddDocument = (doc: Doc | Doc[]) => this.addDocument(doc, this.sidebarKey());
-    sidebarMoveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean) => this.moveDocument(doc, targetCollection, addDocument, this.sidebarKey());
-    sidebarRemDocument = (doc: Doc | Doc[]) => this.removeDocument(doc, this.sidebarKey());
-    sidebarDocFilters = () => [...StrListCast(this.layoutDoc._docFilters), ...StrListCast(this.layoutDoc[this.sidebarKey() + "-docFilters"])];
-    @computed get sidebarAllTags() {
-        const keys = new Set<string>();
-        DocListCast(this.rootDoc[this.sidebarKey()]).forEach(doc => SearchBox.documentKeys(doc).forEach(key => keys.add(key)));
-        return Array.from(keys.keys()).filter(key => key[0]).filter(key => !key.startsWith("_") && (key[0] === "#" || key[0] === key[0].toUpperCase())).sort();
-    }
-    @computed get sidebarOverlay() {
-        const renderTag = (tag: string) => {
-            const active = StrListCast(this.rootDoc[this.sidebarKey() + "-docFilters"]).includes(`${tag}:${tag}:check`);
-            return <div className={`webBox-filterTag${active ? "-active" : ""}`}
-                onClick={e => Doc.setDocFilter(this.rootDoc, tag, tag, "check", true, this.sidebarKey(), e.shiftKey)}>
-                {tag}
-            </div>;
-        }
-        return !this.layoutDoc._showSidebar ? (null) :
-            <div style={{
-                position: "absolute", pointerEvents: this.active() ? "all" : undefined, top: 0, right: 0,
-                background: this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.WidgetColor),
-                width: `${this.sidebarWidth()}px`,
-                height: "100%"
-            }}>
-                <div style={{ width: "100%", height: this.sidebarHeight(), position: "relative" }}>
-                    <CollectionStackingView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit}
-                        NativeWidth={returnZero}
-                        NativeHeight={returnZero}
-                        PanelHeight={this.sidebarHeight}
-                        PanelWidth={this.sidebarWidth}
-                        xMargin={0}
-                        yMargin={0}
-                        docFilters={this.sidebarDocFilters}
-                        chromeStatus={"enabled"}
-                        scaleField={this.sidebarKey() + "-scale"}
-                        isAnnotationOverlay={false}
-                        select={emptyFunction}
-                        active={this.annotationsActive}
-                        scaling={returnOne}
-                        whenActiveChanged={this.whenActiveChanged}
-                        childHideDecorationTitle={returnTrue}
-                        removeDocument={this.sidebarRemDocument}
-                        moveDocument={this.sidebarMoveDocument}
-                        addDocument={this.sidebarAddDocument}
-                        CollectionView={undefined}
-                        ScreenToLocalTransform={this.sidebarTransform}
-                        renderDepth={this.props.renderDepth + 1}
-                        viewType={CollectionViewType.Stacking}
-                        fieldKey={this.sidebarKey()}
-                        pointerEvents={"all"}
-                    />
-                </div>
-                <div className="webBox-tagList" style={{ height: this.sidebarFiltersHeight(), width: this.sidebarWidth() }}>
-                    {this.sidebarAllTags.map(renderTag)}
-                </div>
-            </div>;
-    }
 
     @computed get content() {
         return <div className={"webBox-cont" + (this.active() && CurrentUserUtils.SelectedTool === InkTool.None && !DocumentDecorations.Instance?.Interacting ? "-interactive" : "")}
@@ -592,7 +534,17 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
                     onPointerDown={e => e.stopPropagation()} onClick={e => this.toggleSidebar()} >
                     <FontAwesomeIcon style={{ color: "white" }} icon={"chevron-left"} size="sm" />
                 </button>
-                {this.sidebarOverlay}
+                <SidebarAnnos ref={this._sidebarRef}
+                    {...this.props}
+                    annotationsActive={this.annotationsActive}
+                    rootDoc={this.rootDoc}
+                    layoutDoc={this.layoutDoc}
+                    dataDoc={this.dataDoc}
+                    addDocument={this.addDocument}
+                    moveDocument={this.moveDocument}
+                    removeDocument={this.removeDocument}
+                    active={this.active}
+                />
             </div>);
     }
 }
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 95048247c59ae04b7c35db70e9888f7bc851a3dc Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 18 Mar 2021 23:12:42 -0400
Subject: more cleanup of webbox/pdfbox/sidebarAnnos

---
 src/client/views/SidebarAnnos.tsx  |  23 +++++-
 src/client/views/nodes/PDFBox.scss |  11 ++-
 src/client/views/nodes/PDFBox.tsx  | 153 +++++++++++++++----------------------
 src/client/views/nodes/WebBox.tsx  |  67 +++++-----------
 src/client/views/pdf/PDFViewer.tsx |   2 +-
 5 files changed, 111 insertions(+), 145 deletions(-)

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

diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx
index 026942999..bbe874eac 100644
--- a/src/client/views/SidebarAnnos.tsx
+++ b/src/client/views/SidebarAnnos.tsx
@@ -1,13 +1,16 @@
 import { computed } from 'mobx';
 import { observer } from "mobx-react";
 import { Doc, DocListCast, StrListCast } from "../../fields/Doc";
+import { Id } from '../../fields/FieldSymbols';
 import { List } from '../../fields/List';
-import { NumCast } from '../../fields/Types';
+import { NumCast, StrCast } from '../../fields/Types';
 import { emptyFunction, OmitKeys, returnOne, returnTrue, returnZero } from '../../Utils';
+import { Docs, DocUtils } from '../documents/Documents';
 import { Transform } from '../util/Transform';
 import { CollectionStackingView } from './collections/CollectionStackingView';
 import { CollectionViewType } from './collections/CollectionView';
 import { FieldViewProps } from './nodes/FieldView';
+import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
 import { SearchBox } from './search/SearchBox';
 import "./SidebarAnnos.scss";
 import { StyleProp } from './StyleProvider';
@@ -27,6 +30,7 @@ interface extraProps {
 }
 @observer
 export class SidebarAnnos extends React.Component<FieldViewProps & extraProps> {
+    _stackRef = React.createRef<CollectionStackingView>();
     @computed get allHashtags() {
         const keys = new Set<string>();
         DocListCast(this.props.rootDoc[this.sidebarKey()]).forEach(doc => SearchBox.documentKeys(doc).forEach(key => keys.add(key)));
@@ -34,6 +38,21 @@ export class SidebarAnnos extends React.Component<FieldViewProps & extraProps> {
     }
     get filtersKey() { return "_" + this.sidebarKey() + "-docFilters"; }
 
+    anchorMenuClick = (anchor: Doc) => {
+        this.props.layoutDoc._showSidebar = true;
+        const startup = StrListCast(this.props.rootDoc.docFilters).map(filter => filter.split(":")[0]).join(" ");
+        const target = Docs.Create.TextDocument(startup, {
+            title: "anno",
+            annotationOn: this.props.rootDoc, _width: 200, _height: 50, _fitWidth: true, _autoHeight: true, _fontSize: StrCast(Doc.UserDoc().fontSize),
+            _fontFamily: StrCast(Doc.UserDoc().fontFamily)
+        });
+        FormattedTextBox.SelectOnLoad = target[Id];
+        FormattedTextBox.DontSelectInitialText = true;
+        this.allHashtags.map(tag => target[tag] = tag);
+        DocUtils.MakeLink({ doc: anchor }, { doc: target }, "inline markup", "annotation");
+        this.addDocument(target);
+        this._stackRef.current?.focusDocument(target);
+    }
     makeDocUnfiltered = (doc: Doc) => {
         if (DocListCast(this.props.rootDoc[this.sidebarKey()]).includes(doc)) {
             if (this.props.layoutDoc[this.filtersKey]) {
@@ -69,7 +88,7 @@ export class SidebarAnnos extends React.Component<FieldViewProps & extraProps> {
                 height: "100%"
             }}>
                 <div style={{ width: "100%", height: this.panelHeight(), position: "relative" }}>
-                    <CollectionStackingView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit}
+                    <CollectionStackingView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit} ref={this._stackRef}
                         NativeWidth={returnZero}
                         NativeHeight={returnZero}
                         PanelHeight={this.panelHeight}
diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss
index d1dca5c68..0f46da294 100644
--- a/src/client/views/nodes/PDFBox.scss
+++ b/src/client/views/nodes/PDFBox.scss
@@ -18,11 +18,12 @@
         top: 0;
         left: 0;
 
-        .pdfBox-overlayButton-sidebar {
+        .pdfBox-sidebarBtn {
             background: #121721;
             height: 25px;
             width: 25px;
             right: 0;
+            color: white;
             display: flex;
             position: absolute;
             align-items: center;
@@ -39,8 +40,7 @@
             left: 5px;
             top: 5px;
 
-            .pdfBox-overlayButton-fwd,
-            .pdfBox-overlayButton-back {
+            .pdfBox-fwdBtn, .pdfBox-backBtn {
                 background: #121721;
                 height: 25px;
                 width: 25px;
@@ -63,6 +63,9 @@
             padding: 0;
             position: absolute;
             pointer-events: all;
+            color: white;
+            bottom: 0;
+            right: 0;
 
             .pdfBox-overlayButton-arrow {
                 width: 0;
@@ -89,6 +92,7 @@
         .pdfBox-nextIcon,
         .pdfBox-prevIcon {
             background: #121721;
+            color: white;
             height: 20px;
             width: 25px;
             display: flex;
@@ -311,6 +315,7 @@
         font-size: 30px;
         width: 50px;
         height: 50px;
+        color: white;
     }
 
     .pdfBox .pdfBox-ui .pdfBox-nextIcon,
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 81ef2472a..2342ef019 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -3,27 +3,23 @@ import { action, computed, IReactionDisposer, observable, reaction, runInAction
 import { observer } from "mobx-react";
 import * as Pdfjs from "pdfjs-dist";
 import "pdfjs-dist/web/pdf_viewer.css";
-import { Doc, DocListCast, Opt, StrListCast, WidthSym } from "../../../fields/Doc";
+import { Doc, Opt, WidthSym } from "../../../fields/Doc";
 import { documentSchema } from '../../../fields/documentSchemas';
-import { Id } from '../../../fields/FieldSymbols';
-import { List } from '../../../fields/List';
 import { makeInterface } from "../../../fields/Schema";
 import { Cast, NumCast, StrCast } from '../../../fields/Types';
 import { PdfField } from "../../../fields/URLField";
 import { TraceMobx } from '../../../fields/util';
 import { Utils } from '../../../Utils';
-import { Docs, DocUtils } from '../../documents/Documents';
+import { Docs } from '../../documents/Documents';
 import { KeyCodes } from '../../util/KeyCodes';
 import { undoBatch } from '../../util/UndoManager';
 import { panZoomSchema } from '../collections/collectionFreeForm/CollectionFreeFormView';
-import { CollectionViewType } from '../collections/CollectionView';
 import { ContextMenu } from '../ContextMenu';
 import { ContextMenuProps } from '../ContextMenuItem';
 import { ViewBoxAnnotatableComponent } from "../DocComponent";
 import { PDFViewer } from "../pdf/PDFViewer";
 import { SidebarAnnos } from '../SidebarAnnos';
 import { FieldView, FieldViewProps } from './FieldView';
-import { FormattedTextBox } from './formattedText/FormattedTextBox';
 import { pageSchema } from "./ImageBox";
 import "./PDFBox.scss";
 import React = require("react");
@@ -36,7 +32,6 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
     public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PDFBox, fieldKey); }
     private _searchString: string = "";
     private _initialScrollTarget: Opt<Doc>;
-    private _displayPdfLive = false; // has this box ever had its contents activated -- if so, stop drawing the overlay title
     private _pdfViewer: PDFViewer | undefined;
     private _searchRef = React.createRef<HTMLInputElement>();
     private _selectReactionDisposer: IReactionDisposer | undefined;
@@ -46,21 +41,20 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
     @observable private _pdf: Opt<Pdfjs.PDFDocumentProxy>;
     @observable private _pageControls = false;
 
+    @computed get pdfUrl() { return Cast(this.dataDoc[this.props.fieldKey], PdfField); }
+
     constructor(props: any) {
         super(props);
         const nw = Doc.NativeWidth(this.Document, this.dataDoc) || 927;
         const nh = Doc.NativeHeight(this.Document, this.dataDoc) || 1200;
         !this.Document._fitWidth && (this.Document._height = this.Document[WidthSym]() * (nh / nw));
-        const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField);
-        if (pdfUrl) {
-            if (PDFBox.pdfcache.get(pdfUrl.url.href)) runInAction(() => this._pdf = PDFBox.pdfcache.get(pdfUrl.url.href));
-            else if (PDFBox.pdfpromise.get(pdfUrl.url.href)) PDFBox.pdfpromise.get(pdfUrl.url.href)?.then(action(pdf => this._pdf = pdf));
+        if (this.pdfUrl) {
+            if (PDFBox.pdfcache.get(this.pdfUrl.url.href)) runInAction(() => this._pdf = PDFBox.pdfcache.get(this.pdfUrl!.url.href));
+            else if (PDFBox.pdfpromise.get(this.pdfUrl.url.href)) PDFBox.pdfpromise.get(this.pdfUrl.url.href)?.then(action(pdf => this._pdf = pdf));
         }
 
         const backup = "oldPath";
-        const { Document } = this.props;
-        const pdf = Cast(this.dataDoc[this.props.fieldKey], PdfField);
-        const href = pdf?.url?.href;
+        const href = this.pdfUrl?.url.href;
         if (href) {
             const pathCorrectionTest = /upload\_[a-z0-9]{32}.(.*)/g;
             const matches = pathCorrectionTest.exec(href);
@@ -72,7 +66,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
                 //console.log(properPath);
                 if (!properPath.includes(href)) {
                     console.log(`The two (url and proper path) were not equal`);
-                    const proto = Doc.GetProto(Document);
+                    const proto = Doc.GetProto(this.props.Document);
                     proto[this.props.fieldKey] = new PdfField(properPath);
                     proto[backup] = href;
                 } else {
@@ -118,26 +112,24 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
         !this.Document._fitWidth && (this.Document._height = this.Document[WidthSym]() * (nh / nw));
     }
 
-    public search = (string: string, fwd: boolean) => { this._pdfViewer?.search(string, fwd); };
-    public prevAnnotation = () => { this._pdfViewer?.prevAnnotation(); };
-    public nextAnnotation = () => { this._pdfViewer?.nextAnnotation(); };
+    public search = (string: string, fwd: boolean) => this._pdfViewer?.search(string, fwd);
+    public prevAnnotation = () => this._pdfViewer?.prevAnnotation();
+    public nextAnnotation = () => this._pdfViewer?.nextAnnotation();
     public backPage = () => { this.Document._curPage = (this.Document._curPage || 1) - 1; return true; };
     public forwardPage = () => { this.Document._curPage = (this.Document._curPage || 1) + 1; return true; };
-    public gotoPage = (p: number) => { this.Document._curPage = p; };
+    public gotoPage = (p: number) => this.Document._curPage = p;
 
     @undoBatch
     onKeyDown = action((e: KeyboardEvent) => {
         let processed = false;
-        if (e.key === "f" && e.ctrlKey) {
-            this._searching = true;
-            setTimeout(() => this._searchRef.current && this._searchRef.current.focus(), 100);
-            processed = true;
-        }
-        if (e.key === "PageDown") processed = this.forwardPage();
-        if (e.key === "PageUp") processed = this.backPage();
-        if (e.target instanceof HTMLInputElement || this.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Freeform) {
-            if (e.key === "ArrowDown" || e.key === "ArrowRight") processed = this.forwardPage();
-            if (e.key === "ArrowUp" || e.key === "ArrowLeft") processed = this.backPage();
+        switch (e.key) {
+            case "f": if (e.ctrlKey) {
+                setTimeout(() => this._searchRef.current?.focus(), 100);
+                this._searching = processed = true;
+            }
+                break;
+            case "PageDown": processed = this.forwardPage(); break;
+            case "PageUp": processed = this.backPage(); break;
         }
         if (processed) {
             e.stopImmediatePropagation();
@@ -154,92 +146,72 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
     }
     searchStringChanged = (e: React.ChangeEvent<HTMLInputElement>) => this._searchString = e.currentTarget.value;
     toggleSidebar = () => {
-        if (this.layoutDoc.nativeWidth === this.layoutDoc[this.fieldKey + "-nativeWidth"]) {
-            this.layoutDoc.nativeWidth = 250 + NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]);
-        } else {
-            this.layoutDoc.nativeWidth = NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]);
-        }
-        this.layoutDoc._width = NumCast(this.layoutDoc._nativeWidth) * (NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]) / NumCast(this.layoutDoc[this.fieldKey + "-nativeHeight"]));
+        const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]);
+        const nativeHeight = NumCast(this.layoutDoc[this.fieldKey + "-nativeHeight"]);
+        this.layoutDoc.nativeWidth = nativeWidth + (this.layoutDoc.nativeWidth === nativeWidth ? 250 : 0);
+        this.layoutDoc._width = NumCast(this.layoutDoc._nativeWidth) * (nativeWidth / nativeHeight);
     }
     settingsPanel() {
         const pageBtns = <>
-            <button className="pdfBox-overlayButton-back" key="back" title="Page Back"
-                onPointerDown={e => e.stopPropagation()} onClick={e => this.backPage()} >
+            <button className="pdfBox-backBtn" key="back" title="Page Back"
+                onPointerDown={e => e.stopPropagation()} onClick={this.backPage} >
                 <FontAwesomeIcon style={{ color: "white" }} icon={"arrow-left"} size="sm" />
             </button>
-            <button className="pdfBox-overlayButton-fwd" key="fwd" title="Page Forward"
-                onPointerDown={e => e.stopPropagation()} onClick={e => this.forwardPage()} >
+            <button className="pdfBox-fwdBtn" key="fwd" title="Page Forward"
+                onPointerDown={e => e.stopPropagation()} onClick={this.forwardPage} >
                 <FontAwesomeIcon style={{ color: "white" }} icon={"arrow-right"} size="sm" />
             </button>
         </>;
         const searchTitle = `${!this._searching ? "Open" : "Close"} Search Bar`;
         const curPage = this.Document._curPage || 1;
         return !this.active() ? (null) :
-            (<div className="pdfBox-ui" onKeyDown={e => e.keyCode === KeyCodes.BACKSPACE || e.keyCode === KeyCodes.DELETE ? e.stopPropagation() : true}
+            <div className="pdfBox-ui" onKeyDown={e => [KeyCodes.BACKSPACE, KeyCodes.DELETE].includes(e.keyCode) ? e.stopPropagation() : true}
                 onPointerDown={e => e.stopPropagation()} style={{ display: this.active() ? "flex" : "none" }}>
-                <div className="pdfBox-overlayCont" key="cont" onPointerDown={(e) => e.stopPropagation()} style={{ left: `${this._searching ? 0 : 100}%` }}>
+                <div className="pdfBox-overlayCont" onPointerDown={(e) => e.stopPropagation()} style={{ left: `${this._searching ? 0 : 100}%` }}>
                     <button className="pdfBox-overlayButton" title={searchTitle} />
-                    <input className="pdfBox-searchBar" placeholder="Search" ref={this._searchRef} onChange={this.searchStringChanged} onKeyDown={e => e.keyCode === KeyCodes.ENTER && this.search(this._searchString, !e.shiftKey)} />
+                    <input className="pdfBox-searchBar" placeholder="Search" ref={this._searchRef} onChange={this.searchStringChanged}
+                        onKeyDown={e => e.keyCode === KeyCodes.ENTER && this.search(this._searchString, !e.shiftKey)} />
                     <button className="pdfBox-search" title="Search" onClick={e => this.search(this._searchString, !e.shiftKey)}>
-                        <FontAwesomeIcon icon="search" size="sm" color="white" /></button>
-                    <button className="pdfBox-prevIcon " title="Previous Annotation" onClick={this.prevAnnotation} >
-                        <FontAwesomeIcon style={{ color: "white" }} icon={"arrow-up"} size="lg" />
+                        <FontAwesomeIcon icon="search" size="sm" />
+                    </button>
+                    <button className="pdfBox-prevIcon" title="Previous Annotation" onClick={this.prevAnnotation} >
+                        <FontAwesomeIcon icon={"arrow-up"} size="lg" />
                     </button>
                     <button className="pdfBox-nextIcon" title="Next Annotation" onClick={this.nextAnnotation} >
-                        <FontAwesomeIcon style={{ color: "white" }} icon={"arrow-down"} size="lg" />
+                        <FontAwesomeIcon icon={"arrow-down"} size="lg" />
                     </button>
                 </div>
-                <button className="pdfBox-overlayButton" key="search" onClick={action(() => {
-                    this._searching = !this._searching;
-                    this.search("mxytzlaf", true);
-                })} title={searchTitle} style={{ bottom: 0, right: 0 }}>
-                    <div className="pdfBox-overlayButton-arrow" onPointerDown={(e) => e.stopPropagation()}></div>
+                <button className="pdfBox-overlayButton" title={searchTitle}
+                    onClick={action(() => { this._searching = !this._searching; this.search("mxytzlaf", true); })} >
+                    <div className="pdfBox-overlayButton-arrow" onPointerDown={(e) => e.stopPropagation()} />
                     <div className="pdfBox-overlayButton-iconCont" onPointerDown={(e) => e.stopPropagation()}>
-                        <FontAwesomeIcon style={{ color: "white" }} icon={this._searching ? "times" : "search"} size="lg" /></div>
+                        <FontAwesomeIcon icon={this._searching ? "times" : "search"} size="lg" />
+                    </div>
                 </button>
 
                 <div className="pdfBox-pageNums">
-                    <input value={curPage}
+                    <input value={curPage} style={{ width: `${curPage > 99 ? 4 : 3}ch`, pointerEvents: "all" }}
                         onChange={e => this.Document._curPage = Number(e.currentTarget.value)}
-                        style={{ width: `${curPage > 99 ? 4 : 3}ch`, pointerEvents: "all" }}
                         onClick={action(() => this._pageControls = !this._pageControls)} />
                     {this._pageControls ? pageBtns : (null)}
                 </div>
-                <button className="pdfBox-overlayButton-sidebar" key="sidebar" title="Toggle Sidebar" style={{ right: this.sidebarWidth() + 7 }}
+                <button className="pdfBox-sidebarBtn" title="Toggle Sidebar" style={{ right: this.sidebarWidth() + 7 }}
                     onPointerDown={e => e.stopPropagation()} onClick={e => this.toggleSidebar()} >
-                    <FontAwesomeIcon style={{ color: "white" }} icon={"chevron-left"} size="sm" />
+                    <FontAwesomeIcon icon={"chevron-left"} size="sm" />
                 </button>
-            </div>);
+            </div>;
     }
     sidebarWidth = () => !this.layoutDoc._showSidebar ? 0 : (NumCast(this.layoutDoc.nativeWidth) - Doc.NativeWidth(this.dataDoc)) * this.props.PanelWidth() / NumCast(this.layoutDoc.nativeWidth);
 
-
     specificContextMenu = (e: React.MouseEvent): void => {
-        const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField);
         const funcs: ContextMenuProps[] = [];
-        pdfUrl && funcs.push({ description: "Copy path", event: () => Utils.CopyText(pdfUrl.url.pathname), icon: "expand-arrows-alt" });
+        funcs.push({ description: "Copy path", event: () => this.pdfUrl && Utils.CopyText(this.pdfUrl.url.pathname), icon: "expand-arrows-alt" });
         funcs.push({ description: "Toggle Fit Width " + (this.Document._fitWidth ? "Off" : "On"), event: () => this.Document._fitWidth = !this.Document._fitWidth, icon: "expand-arrows-alt" });
         funcs.push({ description: "Toggle Annotation View ", event: () => this.Document._showSidebar = !this.Document._showSidebar, icon: "expand-arrows-alt" });
         funcs.push({ description: "Toggle Sidebar ", event: () => this.toggleSidebar(), icon: "expand-arrows-alt" });
-
         ContextMenu.Instance.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" });
     }
 
-    anchorMenuClick = (anchor: Doc) => {
-        this.props.Document._showSidebar = true;
-        const startup = StrListCast(this.rootDoc.docFilters).map(filter => filter.split(":")[0]).join(" ");
-        const target = Docs.Create.TextDocument(startup, {
-            title: "anno",
-            annotationOn: this.rootDoc, _width: 200, _height: 50, _fitWidth: true, _autoHeight: true, _fontSize: StrCast(Doc.UserDoc().fontSize),
-            _fontFamily: StrCast(Doc.UserDoc().fontFamily)
-        });
-        FormattedTextBox.SelectOnLoad = target[Id];
-        FormattedTextBox.DontSelectInitialText = true;
-        //this.sidebarAllTags.map(tag => target[tag] = tag);
-        DocUtils.MakeLink({ doc: anchor }, { doc: target }, "inline markup", "annotation");
-        this._sidebarRef.current?.addDocument(target);
-    }
-
     @computed get renderTitleBox() {
         const classname = "pdfBox" + (this.active() ? "-interactive" : "");
         return <div className={classname} >
@@ -251,15 +223,17 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
 
     @computed get renderPdfView() {
         TraceMobx();
-        const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField);
         return <div className={"pdfBox"} onContextMenu={this.specificContextMenu}
-            style={{ height: this.props.Document._scrollTop && !this.Document._fitWidth && (window.screen.width > 600) ? NumCast(this.Document._height) * this.props.PanelWidth() / NumCast(this.Document._width) : undefined }}>
+            style={{
+                height: this.props.Document._scrollTop && !this.Document._fitWidth && (window.screen.width > 600) ?
+                    NumCast(this.Document._height) * this.props.PanelWidth() / NumCast(this.Document._width) : undefined
+            }}>
             <div className="pdfBox-background" />
             <PDFViewer {...this.props}
                 pdf={this._pdf!}
-                url={pdfUrl!.url.pathname}
+                url={this.pdfUrl!.url.pathname}
                 active={this.active}
-                anchorMenuClick={this.anchorMenuClick}
+                anchorMenuClick={this._sidebarRef.current?.anchorMenuClick}
                 loaded={!Doc.NativeAspect(this.dataDoc) ? this.loaded : undefined}
                 setPdfViewer={this.setPdfViewer}
                 addDocument={this.addDocument}
@@ -287,19 +261,14 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
     static pdfpromise = new Map<string, Pdfjs.PDFPromise<Pdfjs.PDFDocumentProxy>>();
     render() {
         TraceMobx();
-        if (true) {//this.props.isSelected() || (this.props.active() && this.props.renderDepth === 0)) {
-            this._displayPdfLive = true;
-        }
-        if (this._displayPdfLive) {
-            if (this._pdf) return this.renderPdfView;
+        if (this._pdf) return this.renderPdfView;
 
-            const href = Cast(this.dataDoc[this.props.fieldKey], PdfField, null)?.url.href;
-            if (href) {
-                if (PDFBox.pdfcache.get(href)) setTimeout(action(() => this._pdf = PDFBox.pdfcache.get(href)));
-                else {
-                    if (!PDFBox.pdfpromise.get(href)) PDFBox.pdfpromise.set(href, Pdfjs.getDocument(href).promise);
-                    PDFBox.pdfpromise.get(href)?.then(action(pdf => PDFBox.pdfcache.set(href, this._pdf = pdf)));
-                }
+        const href = this.pdfUrl?.url.href;
+        if (href) {
+            if (PDFBox.pdfcache.get(href)) setTimeout(action(() => this._pdf = PDFBox.pdfcache.get(href)));
+            else {
+                if (!PDFBox.pdfpromise.get(href)) PDFBox.pdfpromise.set(href, Pdfjs.getDocument(href).promise);
+                PDFBox.pdfpromise.get(href)?.then(action(pdf => PDFBox.pdfcache.set(href, this._pdf = pdf)));
             }
         }
         return this.renderTitleBox;
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 2a0fc47b4..adfe5d694 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -8,19 +8,17 @@ import { Id } from "../../../fields/FieldSymbols";
 import { HtmlField } from "../../../fields/HtmlField";
 import { InkTool } from "../../../fields/InkField";
 import { List } from "../../../fields/List";
-import { listSpec, makeInterface } from "../../../fields/Schema";
+import { makeInterface } from "../../../fields/Schema";
 import { Cast, NumCast, StrCast } from "../../../fields/Types";
 import { WebField } from "../../../fields/URLField";
 import { TraceMobx } from "../../../fields/util";
-import { emptyFunction, getWordAtPoint, OmitKeys, returnOne, returnTrue, returnZero, smoothScroll, Utils } from "../../../Utils";
-import { Docs, DocUtils } from "../../documents/Documents";
+import { emptyFunction, getWordAtPoint, OmitKeys, returnOne, smoothScroll, Utils } from "../../../Utils";
+import { Docs } from "../../documents/Documents";
 import { DocumentType } from '../../documents/DocumentTypes';
 import { CurrentUserUtils } from "../../util/CurrentUserUtils";
 import { SnappingManager } from "../../util/SnappingManager";
 import { undoBatch } from "../../util/UndoManager";
 import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView";
-import { CollectionStackingView } from "../collections/CollectionStackingView";
-import { CollectionViewType } from "../collections/CollectionView";
 import { ContextMenu } from "../ContextMenu";
 import { ContextMenuProps } from "../ContextMenuItem";
 import { ViewBoxAnnotatableComponent } from "../DocComponent";
@@ -29,14 +27,11 @@ import { LightboxView } from "../LightboxView";
 import { MarqueeAnnotator } from "../MarqueeAnnotator";
 import { AnchorMenu } from "../pdf/AnchorMenu";
 import { Annotation } from "../pdf/Annotation";
-import { SearchBox } from "../search/SearchBox";
-import { StyleProp } from "../StyleProvider";
+import { SidebarAnnos } from "../SidebarAnnos";
 import { FieldView, FieldViewProps } from './FieldView';
-import { FormattedTextBox } from "./formattedText/FormattedTextBox";
 import { LinkDocPreview } from "./LinkDocPreview";
 import "./WebBox.scss";
 import React = require("react");
-import { SidebarAnnos } from "../SidebarAnnos";
 const htmlToText = require("html-to-text");
 
 type WebDocument = makeInterface<[typeof documentSchema]>;
@@ -110,9 +105,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
         var quickScroll = true;
         this._disposers.scrollReaction = reaction(() => NumCast(this.layoutDoc._scrollTop),
             (scrollTop) => {
-                if (quickScroll) {
-                    this._initialScroll = scrollTop;
-                }
+                if (quickScroll) this._initialScroll = scrollTop;
                 else {
                     const viewTrans = StrCast(this.Document._viewTransition);
                     const durationMiliStr = viewTrans.match(/([0-9]*)ms/);
@@ -151,11 +144,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
         //this._selectionText = selRange.cloneContents().textContent || "";
 
         // clear selection
-        if (sel.empty) {  // Chrome
-            sel.empty();
-        } else if (sel.removeAllRanges) {  // Firefox
-            sel.removeAllRanges();
-        }
+        if (sel.empty) sel.empty();// Chrome
+        else if (sel.removeAllRanges) sel.removeAllRanges();  // Firefox
     }
 
     menuControls = () => this.urlEditor; // controls to be added to the top bar when a document of this type is selected
@@ -283,8 +273,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
 
     @action
     forward = () => {
-        const future = Cast(this.dataDoc[this.fieldKey + "-future"], listSpec("string"), null);
-        const history = Cast(this.dataDoc[this.fieldKey + "-history"], listSpec("string"), null);
+        const future = StrListCast(this.dataDoc[this.fieldKey + "-future"]);
+        const history = StrListCast(this.dataDoc[this.fieldKey + "-history"]);
         if (future.length) {
             history.push(this._url);
             this.dataDoc[this.fieldKey] = new WebField(new URL(this._url = future.pop()!));
@@ -296,8 +286,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
 
     @action
     back = () => {
-        const future = Cast(this.dataDoc[this.fieldKey + "-future"], listSpec("string"), null);
-        const history = Cast(this.dataDoc[this.fieldKey + "-history"], listSpec("string"), null);
+        const future = StrListCast(this.dataDoc[this.fieldKey + "-future"]);
+        const history = StrListCast(this.dataDoc[this.fieldKey + "-history"]);
         if (history.length) {
             if (future === undefined) this.dataDoc[this.fieldKey + "-future"] = new List<string>([this._url]);
             else future.push(this._url);
@@ -317,8 +307,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
         if (!newUrl) return;
         if (!newUrl.startsWith("http")) newUrl = "http://" + newUrl;
         try {
-            const future = Cast(this.dataDoc[this.fieldKey + "-future"], listSpec("string"), null);
-            const history = Cast(this.dataDoc[this.fieldKey + "-history"], listSpec("string"), null);
+            const future = StrListCast(this.dataDoc[this.fieldKey + "-future"]);
+            const history = StrListCast(this.dataDoc[this.fieldKey + "-history"]);
             const url = this.webField?.toString();
             if (url) {
                 if (history === undefined) {
@@ -409,7 +399,6 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
             view = <span className="webBox-htmlSpan" dangerouslySetInnerHTML={{ __html: field.html }} />;
         } else if (field instanceof WebField) {
             const url = this.layoutDoc.useCors ? Utils.CorsProxy(field.url.href) : field.url.href;
-            //    view = <iframe className="webBox-iframe" src={url} onLoad={e => { e.currentTarget.before((e.currentTarget.contentDocument?.body || e.currentTarget.contentDocument)?.children[0]!); e.currentTarget.remove(); }}
             view = <iframe className="webBox-iframe" enable-annotation={"true"}
                 style={{ pointerEvents: this._scrollTimer ? "none" : undefined }}
                 ref={action((r: HTMLIFrameElement | null) => this._iframe = r)} src={url} onLoad={this.iframeLoaded}
@@ -424,27 +413,11 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
         return view;
     }
 
-    anchorMenuClick = (anchor: Doc) => {
-        this.Document._showSidebar = true;
-        const startup = StrListCast(this.rootDoc.docFilters).map(filter => filter.split(":")[0]).join(" ");
-        const target = Docs.Create.TextDocument(startup, {
-            title: "anno",
-            annotationOn: this.rootDoc, _width: 200, _height: 50, _fitWidth: true, _autoHeight: true, _fontSize: StrCast(Doc.UserDoc().fontSize),
-            _fontFamily: StrCast(Doc.UserDoc().fontFamily)
-        });
-        FormattedTextBox.SelectOnLoad = target[Id];
-        FormattedTextBox.DontSelectInitialText = true;
-        //this.sidebarAllTags.map(tag => target[tag] = tag);
-        DocUtils.MakeLink({ doc: anchor }, { doc: target }, "inline markup", "annotation");
-        this._sidebarRef.current?.addDocument(target);
-    }
     toggleSidebar = () => {
-        if (this.layoutDoc.nativeWidth === this.layoutDoc[this.fieldKey + "-nativeWidth"]) {
-            this.layoutDoc.nativeWidth = 250 + NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]);
-        } else {
-            this.layoutDoc.nativeWidth = NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]);
-        }
-        this.layoutDoc._width = NumCast(this.layoutDoc._nativeWidth) * (NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]) / NumCast(this.layoutDoc[this.fieldKey + "-nativeHeight"]));
+        const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]);
+        const nativeHeight = NumCast(this.layoutDoc[this.fieldKey + "-nativeHeight"]);
+        this.layoutDoc.nativeWidth = nativeWidth + (this.layoutDoc.nativeWidth === nativeWidth ? 250 : 0);
+        this.layoutDoc._width = NumCast(this.layoutDoc._nativeWidth) * (nativeWidth / nativeHeight);
     }
     sidebarWidth = () => !this.layoutDoc._showSidebar ? 0 : (NumCast(this.layoutDoc.nativeWidth) - Doc.NativeWidth(this.dataDoc)) * this.props.PanelWidth() / NumCast(this.layoutDoc.nativeWidth);
 
@@ -513,14 +486,14 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
                                 ScreenToLocalTransform={this.scrollXf}
                                 renderDepth={this.props.renderDepth + 1}
                                 scaling={returnOne}
-                                //pointerEvents={this._isAnnotating || SnappingManager.GetIsDragging() ? "all" : "none"}
-                                childPointerEvents={true} />
+                                childPointerEvents={true}
+                                pointerEvents={this._isAnnotating || SnappingManager.GetIsDragging() ? "all" : "none"} />
                             {this.annotationLayer}
                         </div>
                     </div>
                     {!this._marqueeing || !this._mainCont.current || !this._annotationLayer.current ? (null) :
                         <MarqueeAnnotator rootDoc={this.rootDoc}
-                            anchorMenuClick={this.anchorMenuClick}
+                            anchorMenuClick={this._sidebarRef.current?.anchorMenuClick}
                             scrollTop={0}
                             down={this._marqueeing} scaling={returnOne}
                             addDocument={this.addDocument}
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 0a46b2120..163336e3e 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -55,7 +55,7 @@ interface IViewerProps extends FieldViewProps {
     setPdfViewer: (view: PDFViewer) => void;
     ContentScaling?: () => number;
     sidebarWidth: () => number;
-    anchorMenuClick: (anchor: Doc) => void;
+    anchorMenuClick?: (anchor: Doc) => void;
 }
 
 /**
-- 
cgit v1.2.3-70-g09d2


From f7e9d374d2b397a395da48af412323f61538b7d9 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Sat, 20 Mar 2021 12:09:14 -0400
Subject: cleanup of sidebars for pdf/web - toggle open/close without sizing
 artifacts - open automatically when adding a note.

---
 src/client/views/DocumentDecorations.tsx |  2 +-
 src/client/views/SidebarAnnos.tsx        |  6 ++----
 src/client/views/nodes/PDFBox.tsx        | 22 +++++++++++++++-------
 src/client/views/nodes/WebBox.tsx        | 24 +++++++++++++++---------
 4 files changed, 33 insertions(+), 21 deletions(-)

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

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 6d8bd30be..50065c17a 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -433,7 +433,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b
             if (node.className === "mainView-mainContent") inMainMenuPanel = true;
         }
         const leftBounds = inMainMenuPanel ? 0 : this.props.boundsLeft;
-        const topBounds = this.props.boundsTop;
+        const topBounds = LightboxView.LightboxDoc ? 0 : this.props.boundsTop;
         bounds.x = Math.max(leftBounds, bounds.x - this._resizeBorderWidth / 2) + this._resizeBorderWidth / 2;
         bounds.y = Math.max(topBounds, bounds.y - this._resizeBorderWidth / 2 - this._titleHeight) + this._resizeBorderWidth / 2 + this._titleHeight;
         const borderRadiusDraggerWidth = 15;
diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx
index f3cc30389..2d49938a9 100644
--- a/src/client/views/SidebarAnnos.tsx
+++ b/src/client/views/SidebarAnnos.tsx
@@ -24,7 +24,7 @@ interface ExtraProps {
     annotationsActive: (outsideReaction: boolean) => boolean;
     whenActiveChanged: (isActive: boolean) => void;
     ScreenToLocalTransform: () => Transform;
-    addDocument: (doc: (Doc | Doc[]), suffix: string) => boolean;
+    sidebarAddDocument: (doc: (Doc | Doc[]), suffix: string) => boolean;
     removeDocument: (doc: (Doc | Doc[]), suffix: string) => boolean;
     moveDocument: (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean, annotationKey?: string) => boolean;
 }
@@ -39,7 +39,6 @@ export class SidebarAnnos extends React.Component<FieldViewProps & ExtraProps> {
     get filtersKey() { return "_" + this.sidebarKey() + "-docFilters"; }
 
     anchorMenuClick = (anchor: Doc) => {
-        this.props.layoutDoc._showSidebar = true;
         const startup = StrListCast(this.props.rootDoc.docFilters).map(filter => filter.split(":")[0]).join(" ");
         const target = Docs.Create.TextDocument(startup, {
             title: "anno",
@@ -67,7 +66,7 @@ export class SidebarAnnos extends React.Component<FieldViewProps & ExtraProps> {
     screenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(Doc.NativeWidth(this.props.dataDoc), 0).scale(this.props.scaling?.() || 1);
     panelWidth = () => !this.props.layoutDoc._showSidebar ? 0 : (NumCast(this.props.layoutDoc.nativeWidth) - Doc.NativeWidth(this.props.dataDoc)) * this.props.PanelWidth() / NumCast(this.props.layoutDoc.nativeWidth);
     panelHeight = () => this.props.PanelHeight() - this.filtersHeight() - 20;
-    addDocument = (doc: Doc | Doc[]) => this.props.addDocument(doc, this.sidebarKey());
+    addDocument = (doc: Doc | Doc[]) => this.props.sidebarAddDocument(doc, this.sidebarKey());
     moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean) => this.props.moveDocument(doc, targetCollection, addDocument, this.sidebarKey());
     removeDocument = (doc: Doc | Doc[]) => this.props.removeDocument(doc, this.sidebarKey());
     docFilters = () => [...StrListCast(this.props.layoutDoc._docFilters), ...StrListCast(this.props.layoutDoc[this.filtersKey])];
@@ -80,7 +79,6 @@ export class SidebarAnnos extends React.Component<FieldViewProps & ExtraProps> {
                 {tag}
             </div>;
         };
-        console.log(this.props.dataDoc.title, this.sidebarKey(), this.props.dataDoc[this.sidebarKey()])
         return !this.props.layoutDoc._showSidebar ? (null) :
             <div style={{
                 position: "absolute", pointerEvents: this.props.active() ? "all" : undefined, top: 0, right: 0,
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 2342ef019..f27a34e36 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -145,12 +145,19 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
         }
     }
     searchStringChanged = (e: React.ChangeEvent<HTMLInputElement>) => this._searchString = e.currentTarget.value;
-    toggleSidebar = () => {
-        const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]);
-        const nativeHeight = NumCast(this.layoutDoc[this.fieldKey + "-nativeHeight"]);
-        this.layoutDoc.nativeWidth = nativeWidth + (this.layoutDoc.nativeWidth === nativeWidth ? 250 : 0);
-        this.layoutDoc._width = NumCast(this.layoutDoc._nativeWidth) * (nativeWidth / nativeHeight);
+
+    sidebarAddDocument = (doc: Doc | Doc[], sidebarKey?: string) => {
+        if (!this.layoutDoc._showSidebar) this.toggleSidebar();
+        return this.addDocument(doc, sidebarKey);
     }
+    toggleSidebar = action(() => {
+        const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]);
+        const ratio = ((!this.layoutDoc.nativeWidth || this.layoutDoc.nativeWidth === nativeWidth ? 250 : 0) + nativeWidth) / nativeWidth;
+        const curNativeWidth = NumCast(this.layoutDoc.nativeWidth, nativeWidth);
+        this.layoutDoc.nativeWidth = nativeWidth * ratio;
+        this.layoutDoc._width = this.layoutDoc[WidthSym]() * nativeWidth * ratio / curNativeWidth;
+        this.layoutDoc._showSidebar = nativeWidth !== this.layoutDoc._nativeWidth;
+    });
     settingsPanel() {
         const pageBtns = <>
             <button className="pdfBox-backBtn" key="back" title="Page Back"
@@ -195,7 +202,8 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
                         onClick={action(() => this._pageControls = !this._pageControls)} />
                     {this._pageControls ? pageBtns : (null)}
                 </div>
-                <button className="pdfBox-sidebarBtn" title="Toggle Sidebar" style={{ right: this.sidebarWidth() + 7 }}
+                <button className="pdfBox-sidebarBtn" title="Toggle Sidebar"
+                    style={{ right: this.sidebarWidth() + 7, display: !this.active() ? "none" : undefined }}
                     onPointerDown={e => e.stopPropagation()} onClick={e => this.toggleSidebar()} >
                     <FontAwesomeIcon icon={"chevron-left"} size="sm" />
                 </button>
@@ -248,7 +256,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
                 rootDoc={this.rootDoc}
                 layoutDoc={this.layoutDoc}
                 dataDoc={this.dataDoc}
-                addDocument={this.addDocument}
+                sidebarAddDocument={this.sidebarAddDocument}
                 moveDocument={this.moveDocument}
                 removeDocument={this.removeDocument}
                 active={this.active}
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 81810fbd1..3337865a5 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -310,7 +310,6 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
     }
 
     urlHash = (s: string) => {
-        console.log("Hash: " + s + "=" + this._url + " => " + s.split('').reduce((a: any, b: any) => { a = ((a << 5) - a) + b.charCodeAt(0); return a & a; }, 0))
         return s.split('').reduce((a: any, b: any) => { a = ((a << 5) - a) + b.charCodeAt(0); return a & a; }, 0);
     }
 
@@ -426,12 +425,18 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
         return view;
     }
 
-    toggleSidebar = () => {
-        const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]);
-        const nativeHeight = NumCast(this.layoutDoc[this.fieldKey + "-nativeHeight"]);
-        this.layoutDoc.nativeWidth = nativeWidth + (this.layoutDoc.nativeWidth === nativeWidth ? 250 : 0);
-        this.layoutDoc._width = NumCast(this.layoutDoc._nativeWidth) * (nativeWidth / nativeHeight);
+    sidebarAddDocument = (doc: Doc | Doc[], sidebarKey?: string) => {
+        if (!this.layoutDoc._showSidebar) this.toggleSidebar();
+        return this.addDocument(doc, sidebarKey);
     }
+    toggleSidebar = action(() => {
+        const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]);
+        const ratio = ((!this.layoutDoc.nativeWidth || this.layoutDoc.nativeWidth === nativeWidth ? 250 : 0) + nativeWidth) / nativeWidth;
+        const curNativeWidth = NumCast(this.layoutDoc.nativeWidth, nativeWidth);
+        this.layoutDoc.nativeWidth = nativeWidth * ratio;
+        this.layoutDoc._width = this.layoutDoc[WidthSym]() * nativeWidth * ratio / curNativeWidth;
+        this.layoutDoc._showSidebar = nativeWidth !== this.layoutDoc._nativeWidth;
+    });
     sidebarWidth = () => !this.layoutDoc._showSidebar ? 0 : (NumCast(this.layoutDoc.nativeWidth) - Doc.NativeWidth(this.dataDoc)) * this.props.PanelWidth() / NumCast(this.layoutDoc.nativeWidth);
 
     @computed get content() {
@@ -494,7 +499,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
                                 whenActiveChanged={this.whenActiveChanged}
                                 removeDocument={this.removeDocument}
                                 moveDocument={this.moveDocument}
-                                addDocument={this.addDocument}
+                                addDocument={this.sidebarAddDocument}
                                 CollectionView={undefined}
                                 ScreenToLocalTransform={this.scrollXf}
                                 renderDepth={this.props.renderDepth + 1}
@@ -518,7 +523,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
                             annotationLayer={this._annotationLayer.current}
                             mainCont={this._mainCont.current} />}
                 </div >
-                <button className="webBox-overlayButton-sidebar" key="sidebar" title="Toggle Sidebar" style={{ right: this.sidebarWidth() + 7 }}
+                <button className="webBox-overlayButton-sidebar" key="sidebar" title="Toggle Sidebar"
+                    style={{ right: this.sidebarWidth() + 7, display: !this.active() ? "none" : undefined }}
                     onPointerDown={e => e.stopPropagation()} onClick={e => this.toggleSidebar()} >
                     <FontAwesomeIcon style={{ color: "white" }} icon={"chevron-left"} size="sm" />
                 </button>
@@ -529,7 +535,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
                     rootDoc={this.rootDoc}
                     layoutDoc={this.layoutDoc}
                     dataDoc={this.dataDoc}
-                    addDocument={this.addDocument}
+                    sidebarAddDocument={this.sidebarAddDocument}
                     moveDocument={this.moveDocument}
                     removeDocument={this.removeDocument}
                     active={this.active}
-- 
cgit v1.2.3-70-g09d2

