From 3bcc0e3a8ce4ab67dff4b3d62191c346764aa351 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Thu, 23 Jul 2020 11:56:05 -0400
Subject: got rid of lots of console.logs().  fixed fonticon box to show a
 'label' if defined otherwise 'title'.  if neither, then it shows no tooltip.

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

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

diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 05355caba..39bb7c01d 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -189,7 +189,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
             this.dataDoc[this.fieldKey] = new WebField(URLy);
             this.dataDoc[this.annotationKey] = new List<Doc>([]);
         } catch (e) {
-            console.log("Error in URL :" + this._url);
+            console.log("WebBox URL error:" + this._url);
         }
     }
 
-- 
cgit v1.2.3-70-g09d2


From afdb653478692083bfe4a1318413ae68da7b4ec2 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sun, 26 Jul 2020 17:23:21 -0400
Subject: added UseCors menu option for WebBox.  fixed webbox css so that link
 button is in riht place.

---
 src/client/views/nodes/WebBox.scss | 219 +++++++++++++++++++------------------
 src/client/views/nodes/WebBox.tsx  | 106 +++++++++---------
 2 files changed, 166 insertions(+), 159 deletions(-)

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

diff --git a/src/client/views/nodes/WebBox.scss b/src/client/views/nodes/WebBox.scss
index 4623444b9..4b2f3cc1a 100644
--- a/src/client/views/nodes/WebBox.scss
+++ b/src/client/views/nodes/WebBox.scss
@@ -1,135 +1,140 @@
 @import "../globalCssVariables.scss";
 
 
-.webBox-container, .webBox-container-dragging {
-    transform-origin: top left;
-    width: 100%;
-    height: 100%;
-
-    .webBox-htmlSpan {
-        position: absolute;
-        top: 0;
-        left: 0;
-    }
-    .webBox-cont {
-        pointer-events: none;
-    }
-    .webBox-cont, .webBox-cont-interactive {
-        padding: 0vw;
-        position: absolute;
-        top: 0;
-        left: 0;
+.webBox {
+    height:100%;
+    position: relative;
+    display: flex;
+    .webBox-container, .webBox-container-dragging {
+        transform-origin: top left;
         width: 100%;
         height: 100%;
-        transform-origin: top left;
-        overflow: auto;
-        .webBox-iframe {
+
+        .webBox-htmlSpan {
+            position: absolute;
+            top: 0;
+            left: 0;
+        }
+        .webBox-cont {
+            pointer-events: none;
+        }
+        .webBox-cont, .webBox-cont-interactive {
+            padding: 0vw;
+            position: absolute;
+            top: 0;
+            left: 0;
+            width: 100%;
+            height: 100%;
+            transform-origin: top left;
+            overflow: auto;
+            .webBox-iframe {
+                width: 100%;
+                height: 100%;
+                position: absolute;
+                top:0;
+            }
+        }
+        .webBox-cont-interactive {
+            span {
+                user-select: text !important;
+            }
+        }
+        .webBox-outerContent {
             width: 100%;
             height: 100%;
             position: absolute;
-            top:0;
+            top: 0;
+            left: 0;
+            overflow: auto;
+            .webBox-innerContent { 
+                width:100%;
+            }
         }
-    }
-    .webBox-cont-interactive {
-        span {
-            user-select: text !important;
+        div.webBox-outerContent::-webkit-scrollbar-thumb {
+            display:none;
         }
     }
-    .webBox-outerContent {
+
+
+    .webBox-overlay {
         width: 100%;
         height: 100%;
         position: absolute;
-        top: 0;
-        left: 0;
-        overflow: auto;
-        .webBox-innerContent { 
-            width:100%;
-        }
-    }
-    div.webBox-outerContent::-webkit-scrollbar-thumb {
-        display:none;
     }
-}
-
-
-.webBox-overlay {
-    width: 100%;
-    height: 100%;
-    position: absolute;
-}
 
-.webBox-buttons {
-    margin-left: 44;
-    background:lightGray;
-    width: 100%;
-}
-.webBox-freeze {
-    display: flex;
-    align-items: center; 
-    justify-content: center;
-    margin-right: 5px;
-    width: 30px;
-}
-
-.webBox-urlEditor {
-    position: relative;
-    opacity: 0.9;
-    z-index: 9001;
-    transition: top .5s;
-
-    .urlEditor {
-        display: grid;
-        grid-template-columns: 1fr auto;
-        padding-bottom: 10px;
-        overflow: hidden;
-
-        .editorBase {
-            display: flex;
-
-            .editor-collapse {
-                transition: all .5s, opacity 0.3s;
-                position: absolute;
-                width: 40px;
-                transform-origin: top left;
-            }
+    .webBox-buttons {
+        margin-left: 44;
+        background:lightGray;
+        width: 100%;
+    }
+    .webBox-freeze {
+        display: flex;
+        align-items: center; 
+        justify-content: center;
+        margin-right: 5px;
+        width: 30px;
+    }
 
-            .switchToText {
-                color: $main-accent;
+    .webBox-urlEditor {
+        position: relative;
+        opacity: 0.9;
+        z-index: 9001;
+        transition: top .5s;
+
+        .urlEditor {
+            display: grid;
+            grid-template-columns: 1fr auto;
+            padding-bottom: 10px;
+            overflow: hidden;
+
+            .editorBase {
+                display: flex;
+
+                .editor-collapse {
+                    transition: all .5s, opacity 0.3s;
+                    position: absolute;
+                    width: 40px;
+                    transform-origin: top left;
+                }
+
+                .switchToText {
+                    color: $main-accent;
+                }
+
+                .switchToText:hover {
+                    color: $dark-color;
+                }
             }
 
-            .switchToText:hover {
-                color: $dark-color;
+            button:hover {
+                transform: scale(1);
             }
         }
+    }
 
-        button:hover {
-            transform: scale(1);
-        }
+    .webpage-urlInput {
+        padding: 12px 10px 11px 10px;
+        border: 0px;
+        color: grey;
+        letter-spacing: 2px;
+        outline-color: black;
+        background: rgb(238, 238, 238);
+        width: 100%;
+        margin-right: 10px;
+        height: 100%;
     }
-}
-
-.webpage-urlInput {
-    padding: 12px 10px 11px 10px;
-    border: 0px;
-    color: grey;
-    letter-spacing: 2px;
-    outline-color: black;
-    background: rgb(238, 238, 238);
-    width: 100%;
-    margin-right: 10px;
-    height: 100%;
-}
-
-.touch-iframe-overlay {
-    width: 100%;
-    height: 100%;
-    position: absolute;
-
-    .indicator {
+
+    .touch-iframe-overlay {
+        width: 100%;
+        height: 100%;
         position: absolute;
 
-        &.active {
-            background-color: rgba(0, 0, 0, 0.1);
+        .indicator {
+            position: absolute;
+
+            &.active {
+                background-color: rgba(0, 0, 0, 0.1);
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 39bb7c01d..5ae23f982 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -399,7 +399,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
     specificContextMenu = (e: React.MouseEvent): void => {
         const cm = ContextMenu.Instance;
         const funcs: ContextMenuProps[] = [];
-        funcs.push({ description: (!this.layoutDoc._nativeWidth || !this.layoutDoc._nativeHeight ? "Freeze" : "Unfreeze") + " Aspect", event: this.toggleNativeDimensions, icon: "snowflake" });
+        funcs.push({ description: (this.layoutDoc.UseCors ? "Don't Use" : "Use") + " Cors", event: () => this.layoutDoc.UseCors = !this.layoutDoc.UseCors, icon: "snowflake" });
         cm.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" });
 
     }
@@ -446,58 +446,60 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
     }
     scrollXf = () => this.props.ScreenToLocalTransform().translate(NumCast(this.layoutDoc._scrollLeft), NumCast(this.layoutDoc._scrollTop));
     render() {
-        return (<div className={`webBox-container`}
-            style={{
-                transform: `scale(${this.props.ContentScaling()})`,
-                width: Number.isFinite(this.props.ContentScaling()) ? `${100 / this.props.ContentScaling()}%` : "100%",
-                height: Number.isFinite(this.props.ContentScaling()) ? `${100 / this.props.ContentScaling()}%` : "100%",
-                pointerEvents: this.layoutDoc.isBackground ? "none" : undefined
-            }}
-            onContextMenu={this.specificContextMenu}>
-            <base target="_blank" />
-            {this.content}
-            <div className={"webBox-outerContent"} ref={this._outerRef}
-                style={{ pointerEvents: this.layoutDoc.isAnnotating && !this.layoutDoc.isBackground ? "all" : "none" }}
-                onWheel={e => e.stopPropagation()}
-                onScroll={e => {
-                    const iframe = this._iframeRef?.current?.contentDocument;
-                    const outerFrame = this._outerRef.current;
-                    if (iframe && outerFrame) {
-                        if (iframe.children[0].scrollTop !== outerFrame.scrollTop) {
-                            iframe.children[0].scrollTop = outerFrame.scrollTop;
+        return (<div className="webBox" style={{ width: Number.isFinite(this.props.ContentScaling()) ? `${100 / this.props.ContentScaling()}%` : "100%" }}>
+            <div className={`webBox-container`}
+                style={{
+                    transform: `scale(${this.props.ContentScaling()})`,
+                    width: Number.isFinite(this.props.ContentScaling()) ? `${100 / this.props.ContentScaling()}%` : "100%",
+                    height: Number.isFinite(this.props.ContentScaling()) ? `${100 / this.props.ContentScaling()}%` : "100%",
+                    pointerEvents: this.layoutDoc.isBackground ? "none" : undefined
+                }}
+                onContextMenu={this.specificContextMenu}>
+                <base target="_blank" />
+                {this.content}
+                <div className={"webBox-outerContent"} ref={this._outerRef}
+                    style={{ pointerEvents: this.layoutDoc.isAnnotating && !this.layoutDoc.isBackground ? "all" : "none" }}
+                    onWheel={e => e.stopPropagation()}
+                    onScroll={e => {
+                        const iframe = this._iframeRef?.current?.contentDocument;
+                        const outerFrame = this._outerRef.current;
+                        if (iframe && outerFrame) {
+                            if (iframe.children[0].scrollTop !== outerFrame.scrollTop) {
+                                iframe.children[0].scrollTop = outerFrame.scrollTop;
+                            }
+                            if (iframe.children[0].scrollLeft !== outerFrame.scrollLeft) {
+                                iframe.children[0].scrollLeft = outerFrame.scrollLeft;
+                            }
                         }
-                        if (iframe.children[0].scrollLeft !== outerFrame.scrollLeft) {
-                            iframe.children[0].scrollLeft = outerFrame.scrollLeft;
-                        }
-                    }
-                    //this._outerRef.current!.scrollTop !== this._scrollTop && (this._outerRef.current!.scrollTop = this._scrollTop)
-                }}>
-                <div className={"webBox-innerContent"} style={{ height: NumCast(this.layoutDoc.scrollHeight), width: 4000 }}>
-                    <CollectionFreeFormView {...this.props}
-                        PanelHeight={this.props.PanelHeight}
-                        PanelWidth={this.props.PanelWidth}
-                        annotationsKey={this.annotationKey}
-                        NativeHeight={returnZero}
-                        NativeWidth={returnZero}
-                        focus={this.props.focus}
-                        setPreviewCursor={this.setPreviewCursor}
-                        isSelected={this.props.isSelected}
-                        isAnnotationOverlay={true}
-                        select={emptyFunction}
-                        active={this.active}
-                        ContentScaling={returnOne}
-                        whenActiveChanged={this.whenActiveChanged}
-                        removeDocument={this.removeDocument}
-                        moveDocument={this.moveDocument}
-                        addDocument={this.addDocument}
-                        CollectionView={undefined}
-                        ScreenToLocalTransform={this.scrollXf}
-                        renderDepth={this.props.renderDepth + 1}
-                        docFilters={this.props.docFilters}
-                        ContainingCollectionDoc={this.props.ContainingCollectionDoc}>
-                    </CollectionFreeFormView>
+                        //this._outerRef.current!.scrollTop !== this._scrollTop && (this._outerRef.current!.scrollTop = this._scrollTop)
+                    }}>
+                    <div className={"webBox-innerContent"} style={{ height: NumCast(this.layoutDoc.scrollHeight), width: 4000 }}>
+                        <CollectionFreeFormView {...this.props}
+                            PanelHeight={this.props.PanelHeight}
+                            PanelWidth={this.props.PanelWidth}
+                            annotationsKey={this.annotationKey}
+                            NativeHeight={returnZero}
+                            NativeWidth={returnZero}
+                            focus={this.props.focus}
+                            setPreviewCursor={this.setPreviewCursor}
+                            isSelected={this.props.isSelected}
+                            isAnnotationOverlay={true}
+                            select={emptyFunction}
+                            active={this.active}
+                            ContentScaling={returnOne}
+                            whenActiveChanged={this.whenActiveChanged}
+                            removeDocument={this.removeDocument}
+                            moveDocument={this.moveDocument}
+                            addDocument={this.addDocument}
+                            CollectionView={undefined}
+                            ScreenToLocalTransform={this.scrollXf}
+                            renderDepth={this.props.renderDepth + 1}
+                            docFilters={this.props.docFilters}
+                            ContainingCollectionDoc={this.props.ContainingCollectionDoc}>
+                        </CollectionFreeFormView>
+                    </div>
                 </div>
-            </div>
-        </div >);
+            </div >
+        </div>);
     }
 }
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 139d58d68f022c308664ef9e0ba19df851801afb Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sun, 26 Jul 2020 17:48:36 -0400
Subject: from last

---
 src/client/views/nodes/WebBox.tsx | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

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

diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 5ae23f982..52e8b92a1 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -446,12 +446,12 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
     }
     scrollXf = () => this.props.ScreenToLocalTransform().translate(NumCast(this.layoutDoc._scrollLeft), NumCast(this.layoutDoc._scrollTop));
     render() {
-        return (<div className="webBox" style={{ width: Number.isFinite(this.props.ContentScaling()) ? `${100 / this.props.ContentScaling()}%` : "100%" }}>
+        return (<div className="webBox" style={{ width: Number.isFinite(this.props.ContentScaling()) ? `${Math.max(100, 100 / this.props.ContentScaling())} % ` : "100%" }}>
             <div className={`webBox-container`}
                 style={{
                     transform: `scale(${this.props.ContentScaling()})`,
-                    width: Number.isFinite(this.props.ContentScaling()) ? `${100 / this.props.ContentScaling()}%` : "100%",
-                    height: Number.isFinite(this.props.ContentScaling()) ? `${100 / this.props.ContentScaling()}%` : "100%",
+                    width: Number.isFinite(this.props.ContentScaling()) ? `${100 / this.props.ContentScaling()}% ` : "100%",
+                    height: Number.isFinite(this.props.ContentScaling()) ? `${100 / this.props.ContentScaling()}% ` : "100%",
                     pointerEvents: this.layoutDoc.isBackground ? "none" : undefined
                 }}
                 onContextMenu={this.specificContextMenu}>
-- 
cgit v1.2.3-70-g09d2


From a904a5fd2d33fd4783a45b3411c9309cc25ad0fd Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sun, 26 Jul 2020 18:07:54 -0400
Subject: from last

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

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

diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 52e8b92a1..724044295 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -446,7 +446,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
     }
     scrollXf = () => this.props.ScreenToLocalTransform().translate(NumCast(this.layoutDoc._scrollLeft), NumCast(this.layoutDoc._scrollTop));
     render() {
-        return (<div className="webBox" style={{ width: Number.isFinite(this.props.ContentScaling()) ? `${Math.max(100, 100 / this.props.ContentScaling())} % ` : "100%" }}>
+        return (<div className="webBox" style={{ width: Number.isFinite(this.props.ContentScaling()) ? `${Math.max(100, 100 / this.props.ContentScaling())}% ` : "100%" }}>
             <div className={`webBox-container`}
                 style={{
                     transform: `scale(${this.props.ContentScaling()})`,
-- 
cgit v1.2.3-70-g09d2


From 49fcb0f6613344fb62db618c0b466c6155c20eb0 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Mon, 27 Jul 2020 00:32:50 -0400
Subject: extended pdfviewer interactions to WebBox's.

---
 src/client/views/DocComponent.tsx  |   2 +-
 src/client/views/nodes/WebBox.scss |  21 ++-
 src/client/views/nodes/WebBox.tsx  | 262 ++++++++++++++++++++++++++++++++++---
 src/client/views/pdf/PDFViewer.tsx |   8 +-
 4 files changed, 265 insertions(+), 28 deletions(-)

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

diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index cfabae8a1..9fd406407 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -122,7 +122,7 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps, T
         @action.bound
         removeDocument(doc: Doc | Doc[]): boolean {
             const docs = doc instanceof Doc ? [doc] : doc;
-            docs.map(doc => doc.annotationOn = undefined);
+            docs.map(doc => doc.isPushpin = doc.annotationOn = undefined);
             const targetDataDoc = this.dataDoc;
             const value = DocListCast(targetDataDoc[this.annotationKey]);
             const toRemove = value.filter(v => docs.includes(v));
diff --git a/src/client/views/nodes/WebBox.scss b/src/client/views/nodes/WebBox.scss
index 4b2f3cc1a..f5c8745e7 100644
--- a/src/client/views/nodes/WebBox.scss
+++ b/src/client/views/nodes/WebBox.scss
@@ -5,6 +5,24 @@
     height:100%;
     position: relative;
     display: flex;
+
+    .pdfViewerDash-dragAnnotationBox {
+        position:absolute;
+        background-color: transparent;
+        opacity: 0.1;
+    }
+    .webBox-annotationLayer {
+        position: absolute;
+        transform-origin: left top;
+        top: 0;
+        width: 100%;
+        pointer-events: none;
+        mix-blend-mode: multiply; // bcz: makes text fuzzy!
+    }
+    .webBox-annotationBox {
+        position: absolute;
+        background-color: rgba(245, 230, 95, 0.616);
+    }
     .webBox-container, .webBox-container-dragging {
         transform-origin: top left;
         width: 100%;
@@ -46,9 +64,6 @@
             top: 0;
             left: 0;
             overflow: auto;
-            .webBox-innerContent { 
-                width:100%;
-            }
         }
         div.webBox-outerContent::-webkit-scrollbar-thumb {
             display:none;
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 724044295..bc30b15e6 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -1,46 +1,62 @@
-import { library } from "@fortawesome/fontawesome-svg-core";
-import { faStickyNote, faPen, faMousePointer } from '@fortawesome/free-solid-svg-icons';
-import { action, computed, observable, trace, IReactionDisposer, reaction, runInAction } from "mobx";
+import { faMousePointer, faPen, faStickyNote } from '@fortawesome/free-solid-svg-icons';
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, FieldResult, DocListCast } from "../../../fields/Doc";
+import { Dictionary } from "typescript-collections";
+import * as WebRequest from 'web-request';
+import { Doc, DocListCast, Opt } from "../../../fields/Doc";
 import { documentSchema } from "../../../fields/documentSchemas";
+import { Id } from "../../../fields/FieldSymbols";
 import { HtmlField } from "../../../fields/HtmlField";
 import { InkTool } from "../../../fields/InkField";
-import { makeInterface, listSpec } from "../../../fields/Schema";
-import { Cast, NumCast, BoolCast, StrCast } from "../../../fields/Types";
+import { List } from "../../../fields/List";
+import { listSpec, makeInterface } from "../../../fields/Schema";
+import { Cast, NumCast, StrCast } from "../../../fields/Types";
 import { WebField } from "../../../fields/URLField";
-import { Utils, returnOne, emptyFunction, returnZero } from "../../../Utils";
-import { Docs } from "../../documents/Documents";
+import { TraceMobx } from "../../../fields/util";
+import { addStyleSheet, clearStyleSheetRules, emptyFunction, returnOne, returnZero, Utils } from "../../../Utils";
+import { Docs, DocUtils } from "../../documents/Documents";
 import { DragManager } from "../../util/DragManager";
 import { ImageUtils } from "../../util/Import & Export/ImageUtils";
+import { undoBatch } from "../../util/UndoManager";
+import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView";
+import { ContextMenu } from "../ContextMenu";
+import { ContextMenuProps } from "../ContextMenuItem";
 import { ViewBoxAnnotatableComponent } from "../DocComponent";
 import { DocumentDecorations } from "../DocumentDecorations";
+import Annotation from "../pdf/Annotation";
+import PDFMenu from "../pdf/PDFMenu";
+import { PdfViewerMarquee } from "../pdf/PDFViewer";
 import { FieldView, FieldViewProps } from './FieldView';
 import "./WebBox.scss";
+import "../pdf/PDFViewer.scss";
 import React = require("react");
-import * as WebRequest from 'web-request';
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView";
-import { ContextMenu } from "../ContextMenu";
-import { ContextMenuProps } from "../ContextMenuItem";
-import { undoBatch } from "../../util/UndoManager";
-import { List } from "../../../fields/List";
 const htmlToText = require("html-to-text");
 
-library.add(faStickyNote);
-
 type WebDocument = makeInterface<[typeof documentSchema]>;
 const WebDocument = makeInterface(documentSchema);
 
 @observer
 export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocument>(WebDocument) {
 
+    private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef();
+    static _annotationStyle: any = addStyleSheet();
+    private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
+    private _startX: number = 0;
+    private _startY: number = 0;
+    @observable private _marqueeX: number = 0;
+    @observable private _marqueeY: number = 0;
+    @observable private _marqueeWidth: number = 0;
+    @observable private _marqueeHeight: number = 0;
+    @observable private _marqueeing: boolean = false;
     public static LayoutString(fieldKey: string) { return FieldView.LayoutString(WebBox, fieldKey); }
     get _collapsed() { return StrCast(this.layoutDoc._chromeStatus) !== "enabled"; }
     set _collapsed(value) { this.layoutDoc._chromeStatus = !value ? "enabled" : "disabled"; }
     @observable private _url: string = "hello";
     @observable private _pressX: number = 0;
     @observable private _pressY: number = 0;
+    @observable private _savedAnnotations: Dictionary<number, HTMLDivElement[]> = new Dictionary<number, HTMLDivElement[]>();
+    private _selectionReactionDisposer?: IReactionDisposer;
     private _keyInput = React.createRef<HTMLInputElement>();
     private _longPressSecondsHack?: NodeJS.Timeout;
     private _outerRef = React.createRef<HTMLDivElement>();
@@ -75,6 +91,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
             { fireImmediately: true }
         );
     });
+
     setPreviewCursor = (func?: (x: number, y: number, drag: boolean) => void) => this._setPreviewCursor = func;
     iframedown = (e: PointerEvent) => {
         this._setPreviewCursor?.(e.screenX, e.screenY, false);
@@ -89,6 +106,17 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
         const urlField = Cast(this.dataDoc[this.props.fieldKey], WebField);
         runInAction(() => this._url = urlField?.url.toString() || "");
 
+
+        this._selectionReactionDisposer = reaction(() => this.props.isSelected(),
+            selected => {
+                if (!selected) {
+                    this._savedAnnotations.values().forEach(v => v.forEach(a => a.remove()));
+                    this._savedAnnotations.keys().forEach(k => this._savedAnnotations.setValue(k, []));
+                    PDFMenu.Instance.fadeOut(true);
+                }
+            },
+            { fireImmediately: true });
+
         document.addEventListener("pointerup", this.onLongPressUp);
         document.addEventListener("pointermove", this.onLongPressMove);
         const field = Cast(this.rootDoc[this.props.fieldKey], WebField);
@@ -112,6 +140,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
     }
 
     componentWillUnmount() {
+        this._selectionReactionDisposer?.();
         this._reactionDisposer?.();
         document.removeEventListener("pointerup", this.onLongPressUp);
         document.removeEventListener("pointermove", this.onLongPressMove);
@@ -267,11 +296,14 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
         );
     }
 
+
     @action
     toggleCollapse = () => {
         this._collapsed = !this._collapsed;
     }
 
+
+
     _ignore = 0;
     onPreWheel = (e: React.WheelEvent) => {
         this._ignore = e.timeStamp;
@@ -284,6 +316,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
             e.stopPropagation();
         }
     }
+
     onPostWheel = (e: React.WheelEvent) => {
         if (this._ignore !== e.timeStamp) {
             e.stopPropagation();
@@ -430,6 +463,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
 
         return (<>
             <div className={"webBox-cont" + (this.props.isSelected() && Doc.GetSelectedTool() === InkTool.None && !decInteracting ? "-interactive" : "")}
+                style={{ width: Number.isFinite(this.props.ContentScaling()) ? `${Math.max(100, 100 / this.props.ContentScaling())}% ` : "100%" }}
                 onWheel={this.onPostWheel} onPointerDown={this.onPostPointer} onPointerMove={this.onPostPointer} onPointerUp={this.onPostPointer}>
                 {view}
             </div>;
@@ -444,9 +478,188 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
             {this.urlEditor()}
         </>);
     }
+
+
+
+    @computed get allAnnotations() { return DocListCast(this.dataDoc[this.props.fieldKey + "-annotations"]); }
+    @computed get nonDocAnnotations() { return this.allAnnotations.filter(a => a.annotations); }
+
+    @undoBatch
+    @action
+    makeAnnotationDocument = (color: string): Opt<Doc> => {
+        if (this._savedAnnotations.size() === 0) return undefined;
+        const anno = this._savedAnnotations.values()[0][0];
+        const annoDoc = Docs.Create.FreeformDocument([], { backgroundColor: color, annotationOn: this.props.Document, title: "Annotation on " + this.Document.title });
+        if (anno.style.left) annoDoc.x = parseInt(anno.style.left);
+        if (anno.style.top) annoDoc.y = NumCast(this.layoutDoc._scrollTop) + parseInt(anno.style.top);
+        if (anno.style.height) annoDoc._height = parseInt(anno.style.height);
+        if (anno.style.width) annoDoc._width = parseInt(anno.style.width);
+        anno.remove();
+        this._savedAnnotations.clear();
+        return annoDoc;
+    }
+    @computed get annotationLayer() {
+        TraceMobx();
+        return <div className="webBox-annotationLayer" style={{ height: NumCast(this.Document._nativeHeight) }} ref={this._annotationLayer}>
+            {this.nonDocAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map(anno =>
+                <Annotation {...this.props} focus={this.props.focus} dataDoc={this.dataDoc} fieldKey={this.props.fieldKey} anno={anno} key={`${anno[Id]}-annotation`} />)
+            }
+        </div>;
+    }
+    @action
+    createAnnotation = (div: HTMLDivElement, page: number) => {
+        if (this._annotationLayer.current) {
+            if (div.style.top) {
+                div.style.top = (parseInt(div.style.top)).toString();
+            }
+            this._annotationLayer.current.append(div);
+            div.style.backgroundColor = "#ACCEF7";
+            div.style.opacity = "0.5";
+            const savedPage = this._savedAnnotations.getValue(page);
+            if (savedPage) {
+                savedPage.push(div);
+                this._savedAnnotations.setValue(page, savedPage);
+            }
+            else {
+                this._savedAnnotations.setValue(page, [div]);
+            }
+        }
+    }
+
+    @action
+    highlight = (color: string) => {
+        // creates annotation documents for current highlights
+        const annotationDoc = this.makeAnnotationDocument(color);
+        annotationDoc && Doc.AddDocToList(this.props.Document, this.annotationKey, annotationDoc);
+        return annotationDoc;
+    }
+    /**
+     * This is temporary for creating annotations from highlights. It will
+     * start a drag event and create or put the necessary info into the drag event.
+     */
+    @action
+    startDrag = async (e: PointerEvent, ele: HTMLElement) => {
+        e.preventDefault();
+        e.stopPropagation();
+
+        const clipDoc = Doc.MakeAlias(this.dataDoc);
+        clipDoc._fitWidth = true;
+        clipDoc._width = this.marqueeWidth();
+        clipDoc._height = this.marqueeHeight();
+        clipDoc._scrollTop = this.marqueeY();
+        const targetDoc = Docs.Create.TextDocument("", { _width: 200, _height: 200, title: "Note linked to " + this.props.Document.title });
+        Doc.GetProto(targetDoc).data = new List<Doc>([clipDoc]);
+        clipDoc.rootDocument = targetDoc;
+        targetDoc.layoutKey = "layout";
+        const annotationDoc = this.highlight("rgba(146, 245, 95, 0.467)"); // yellowish highlight color when dragging out a text selection
+        if (annotationDoc) {
+            DragManager.StartPdfAnnoDrag([ele], new DragManager.PdfAnnoDragData(this.props.Document, annotationDoc, targetDoc), e.pageX, e.pageY, {
+                dragComplete: e => {
+                    if (!e.aborted && e.annoDragData && !e.annoDragData.linkedToDoc) {
+                        DocUtils.MakeLink({ doc: annotationDoc }, { doc: e.annoDragData.dropDocument }, "Annotation");
+                        annotationDoc.isLinkButton = true;
+                        e.annoDragData.dropDocument.isPushpin = true;
+                        e.annoDragData.dropDocument.isLinkButton = true;
+                    }
+                }
+            });
+        }
+    }
+    @action
+    onMarqueeDown = (e: React.PointerEvent) => {
+        this._marqueeing = false;
+        if (!e.altKey && e.button === 0 && this.active(true)) {
+            // clear out old marquees and initialize menu for new selection
+            PDFMenu.Instance.StartDrag = this.startDrag;
+            PDFMenu.Instance.Highlight = this.highlight;
+            PDFMenu.Instance.Status = "pdf";
+            PDFMenu.Instance.fadeOut(true);
+            this._savedAnnotations.values().forEach(v => v.forEach(a => a.remove()));
+            this._savedAnnotations.keys().forEach(k => this._savedAnnotations.setValue(k, []));
+            if ((e.target as any)?.parentElement.className === "textLayer") {
+                // start selecting text if mouse down on textLayer spans
+            }
+            else if (this._mainCont.current) {
+                // set marquee x and y positions to the spatially transformed position
+                const boundingRect = this._mainCont.current.getBoundingClientRect();
+                this._startX = (e.clientX - boundingRect.left) / boundingRect.width * (this.Document._nativeWidth || 1);
+                this._startY = (e.clientY - boundingRect.top) / boundingRect.height * (this.Document._nativeHeight || 1);
+                this._marqueeHeight = this._marqueeWidth = 0;
+                this._marqueeing = true;
+            }
+            document.removeEventListener("pointermove", this.onSelectMove);
+            document.addEventListener("pointermove", this.onSelectMove);
+            document.removeEventListener("pointerup", this.onSelectEnd);
+            document.addEventListener("pointerup", this.onSelectEnd);
+        }
+    }
+    @action
+    onSelectMove = (e: PointerEvent): void => {
+        if (this._marqueeing && this._mainCont.current) {
+            // transform positions and find the width and height to set the marquee to
+            const boundingRect = this._mainCont.current.getBoundingClientRect();
+            const curX = (e.clientX - boundingRect.left) / boundingRect.width * (this.Document._nativeWidth || 1);
+            const curY = (e.clientY - boundingRect.top) / boundingRect.height * (this.Document._nativeHeight || 1);
+            this._marqueeWidth = curX - this._startX;
+            this._marqueeHeight = curY - this._startY;
+            this._marqueeX = Math.min(this._startX, this._startX + this._marqueeWidth);
+            this._marqueeY = Math.min(this._startY, this._startY + this._marqueeHeight);
+            this._marqueeWidth = Math.abs(this._marqueeWidth);
+            this._marqueeHeight = Math.abs(this._marqueeHeight);
+            e.stopPropagation();
+            e.preventDefault();
+        }
+        else if (e.target && (e.target as any).parentElement === this._mainCont.current) {
+            e.stopPropagation();
+        }
+    }
+
+    @action
+    onSelectEnd = (e: PointerEvent): void => {
+        clearStyleSheetRules(WebBox._annotationStyle);
+        this._savedAnnotations.clear();
+        if (this._marqueeWidth > 10 || this._marqueeHeight > 10) {
+            const marquees = this._mainCont.current!.getElementsByClassName("pdfViewerDash-dragAnnotationBox");
+            if (marquees?.length) { // copy the marquee and convert it to a permanent annotation.
+                const style = (marquees[0] as HTMLDivElement).style;
+                const copy = document.createElement("div");
+                copy.style.left = style.left;
+                copy.style.top = style.top;
+                copy.style.width = style.width;
+                copy.style.height = style.height;
+                copy.style.border = style.border;
+                copy.style.opacity = style.opacity;
+                (copy as any).marqueeing = true;
+                copy.className = "webBox-annotationBox";
+                this.createAnnotation(copy, 0);
+            }
+
+            if (!e.ctrlKey) {
+                PDFMenu.Instance.Marquee = { left: this._marqueeX, top: this._marqueeY, width: this._marqueeWidth, height: this._marqueeHeight };
+            }
+            PDFMenu.Instance.jumpTo(e.clientX, e.clientY);
+        }
+        //this._marqueeing = false;
+
+        if (PDFMenu.Instance.Highlighting) {// when highlighter has been toggled when menu is pinned, we auto-highlight immediately on mouse up
+            this.highlight("rgba(245, 230, 95, 0.616)");  // yellowish highlight color for highlighted text (should match PDFMenu's highlight color)
+        }
+        else {
+            PDFMenu.Instance.StartDrag = this.startDrag;
+            PDFMenu.Instance.Highlight = this.highlight;
+        }
+        document.removeEventListener("pointermove", this.onSelectMove);
+        document.removeEventListener("pointerup", this.onSelectEnd);
+    }
+
+    marqueeWidth = () => this._marqueeWidth;
+    marqueeHeight = () => this._marqueeHeight;
+    marqueeX = () => this._marqueeX;
+    marqueeY = () => this._marqueeY;
+    marqueeing = () => this._marqueeing;
     scrollXf = () => this.props.ScreenToLocalTransform().translate(NumCast(this.layoutDoc._scrollLeft), NumCast(this.layoutDoc._scrollTop));
     render() {
-        return (<div className="webBox" style={{ width: Number.isFinite(this.props.ContentScaling()) ? `${Math.max(100, 100 / this.props.ContentScaling())}% ` : "100%" }}>
+        return (<div className="webBox" ref={this._mainCont} >
             <div className={`webBox-container`}
                 style={{
                     transform: `scale(${this.props.ContentScaling()})`,
@@ -458,8 +671,12 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
                 <base target="_blank" />
                 {this.content}
                 <div className={"webBox-outerContent"} ref={this._outerRef}
-                    style={{ pointerEvents: this.layoutDoc.isAnnotating && !this.layoutDoc.isBackground ? "all" : "none" }}
+                    style={{
+                        width: Number.isFinite(this.props.ContentScaling()) ? `${100 / this.props.ContentScaling()}% ` : "100%",
+                        pointerEvents: this.layoutDoc.isAnnotating && !this.layoutDoc.isBackground ? "all" : "none"
+                    }}
                     onWheel={e => e.stopPropagation()}
+                    onPointerDown={this.onMarqueeDown}
                     onScroll={e => {
                         const iframe = this._iframeRef?.current?.contentDocument;
                         const outerFrame = this._outerRef.current;
@@ -473,7 +690,10 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
                         }
                         //this._outerRef.current!.scrollTop !== this._scrollTop && (this._outerRef.current!.scrollTop = this._scrollTop)
                     }}>
-                    <div className={"webBox-innerContent"} style={{ height: NumCast(this.layoutDoc.scrollHeight), width: 4000 }}>
+                    <div className={"webBox-innerContent"} style={{
+                        height: NumCast(this.layoutDoc.scrollHeight),
+                        pointerEvents: this.layoutDoc.isBackground ? "none" : undefined
+                    }}>
                         <CollectionFreeFormView {...this.props}
                             PanelHeight={this.props.PanelHeight}
                             PanelWidth={this.props.PanelWidth}
@@ -499,6 +719,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
                         </CollectionFreeFormView>
                     </div>
                 </div>
+                {this.annotationLayer}
+                <PdfViewerMarquee isMarqueeing={this.marqueeing} width={this.marqueeWidth} height={this.marqueeHeight} x={this.marqueeX} y={this.marqueeY} />
             </div >
         </div>);
     }
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 30c51d9ca..5ed842ab7 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -521,7 +521,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
         if (this._marqueeing) {
             if (this._marqueeWidth > 10 || this._marqueeHeight > 10) {
                 const marquees = this._mainCont.current!.getElementsByClassName("pdfViewerDash-dragAnnotationBox");
-                if (marquees && marquees.length) { // copy the marquee and convert it to a permanent annotation.
+                if (marquees?.length) { // copy the marquee and convert it to a permanent annotation.
                     const style = (marquees[0] as HTMLDivElement).style;
                     const copy = document.createElement("div");
                     copy.style.left = style.left;
@@ -544,7 +544,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
         }
         else {
             const sel = window.getSelection();
-            if (sel && sel.type === "Range") {
+            if (sel?.type === "Range") {
                 const selRange = sel.getRangeAt(0);
                 this.createTextAnnotation(sel, selRange);
                 PDFMenu.Instance.jumpTo(e.clientX, e.clientY);
@@ -726,7 +726,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
     }
 }
 
-interface PdfViewerMarqueeProps {
+export interface PdfViewerMarqueeProps {
     isMarqueeing: () => boolean;
     width: () => number;
     height: () => number;
@@ -735,7 +735,7 @@ interface PdfViewerMarqueeProps {
 }
 
 @observer
-class PdfViewerMarquee extends React.Component<PdfViewerMarqueeProps> {
+export class PdfViewerMarquee extends React.Component<PdfViewerMarqueeProps> {
     render() {
         return !this.props.isMarqueeing() ? (null) : <div className="pdfViewerDash-dragAnnotationBox"
             style={{
-- 
cgit v1.2.3-70-g09d2

