From 9419693f37ad53fcc0763a118d2cb865659a2ff4 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Tue, 6 Aug 2019 14:08:59 -0400
Subject: multiple changes to PDF related code -- mostly clean up

---
 src/client/views/pdf/PDFMenu.tsx | 123 +++++++++++++++++----------------------
 1 file changed, 55 insertions(+), 68 deletions(-)

(limited to 'src/client/views/pdf/PDFMenu.tsx')

diff --git a/src/client/views/pdf/PDFMenu.tsx b/src/client/views/pdf/PDFMenu.tsx
index 27c2a8f1a..7b3d5bfae 100644
--- a/src/client/views/pdf/PDFMenu.tsx
+++ b/src/client/views/pdf/PDFMenu.tsx
@@ -11,36 +11,34 @@ import { handleBackspace } from "../nodes/PDFBox";
 export default class PDFMenu extends React.Component {
     static Instance: PDFMenu;
 
+    private _offsetY: number = 0;
+    private _offsetX: number = 0;
+    private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
+    private _commentCont = React.createRef<HTMLButtonElement>();
+    private _snippetButton: React.RefObject<HTMLButtonElement> = React.createRef();
+    private _dragging: boolean = false;
+
     @observable private _top: number = -300;
     @observable private _left: number = -300;
     @observable private _opacity: number = 1;
     @observable private _transition: string = "opacity 0.5s";
     @observable private _transitionDelay: string = "";
-
-
-    StartDrag: (e: PointerEvent, ele: HTMLElement) => void = emptyFunction;
-    Highlight: (d: Doc | undefined, color: string | undefined) => void = emptyFunction;
-    Delete: () => void = emptyFunction;
-    Snippet: (marquee: { left: number, top: number, width: number, height: number }) => void = emptyFunction;
-    AddTag: (key: string, value: string) => boolean = returnFalse;
-    PinToPres: () => void = emptyFunction;
+    @observable private _keyValue: string = "";
+    @observable private _valueValue: string = "";
+    @observable private _added: boolean = false;
 
     @observable public Highlighting: boolean = false;
     @observable public Status: "pdf" | "annotation" | "snippet" | "" = "";
     @observable public Pinned: boolean = false;
 
+    public StartDrag: (e: PointerEvent, ele: HTMLElement) => void = emptyFunction;
+    public Highlight: (d: Doc | undefined, color: string | undefined) => void = emptyFunction;
+    public Delete: () => void = emptyFunction;
+    public Snippet: (marquee: { left: number, top: number, width: number, height: number }) => void = emptyFunction;
+    public AddTag: (key: string, value: string) => boolean = returnFalse;
+    public PinToPres: () => void = emptyFunction;
     public Marquee: { left: number; top: number; width: number; height: number; } | undefined;
 
-    private _offsetY: number = 0;
-    private _offsetX: number = 0;
-    private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
-    private _commentCont = React.createRef<HTMLButtonElement>();
-    private _snippetButton: React.RefObject<HTMLButtonElement> = React.createRef();
-    private _dragging: boolean = false;
-    @observable private _keyValue: string = "";
-    @observable private _valueValue: string = "";
-    @observable private _added: boolean = false;
-
     constructor(props: Readonly<{}>) {
         super(props);
 
@@ -61,12 +59,10 @@ export default class PDFMenu extends React.Component {
         e.stopPropagation();
         e.preventDefault();
 
-        if (this._dragging) {
-            return;
+        if (!this._dragging) {
+            this.StartDrag(e, this._commentCont.current!);
+            this._dragging = true;
         }
-
-        this.StartDrag(e, this._commentCont.current!);
-        this._dragging = true;
     }
 
     pointerUp = (e: PointerEvent) => {
@@ -126,9 +122,20 @@ export default class PDFMenu extends React.Component {
     @action
     togglePin = (e: React.MouseEvent) => {
         this.Pinned = !this.Pinned;
-        if (!this.Pinned) {
-            this.Highlighting = false;
-        }
+        !this.Pinned && (this.Highlighting = false);
+    }
+
+    dragStart = (e: React.PointerEvent) => {
+        document.removeEventListener("pointermove", this.dragging);
+        document.addEventListener("pointermove", this.dragging);
+        document.removeEventListener("pointerup", this.dragEnd);
+        document.addEventListener("pointerup", this.dragEnd);
+
+        this._offsetX = this._mainCont.current!.getBoundingClientRect().width - e.nativeEvent.offsetX;
+        this._offsetY = e.nativeEvent.offsetY;
+
+        e.stopPropagation();
+        e.preventDefault();
     }
 
     @action
@@ -147,19 +154,6 @@ export default class PDFMenu extends React.Component {
         e.preventDefault();
     }
 
-    dragStart = (e: React.PointerEvent) => {
-        document.removeEventListener("pointermove", this.dragging);
-        document.addEventListener("pointermove", this.dragging);
-        document.removeEventListener("pointerup", this.dragEnd);
-        document.addEventListener("pointerup", this.dragEnd);
-
-        this._offsetX = this._mainCont.current!.getBoundingClientRect().width - e.nativeEvent.offsetX;
-        this._offsetY = e.nativeEvent.offsetY;
-
-        e.stopPropagation();
-        e.preventDefault();
-    }
-
     @action
     highlightClicked = (e: React.MouseEvent) => {
         if (!this.Pinned) {
@@ -193,13 +187,10 @@ export default class PDFMenu extends React.Component {
     snippetDrag = (e: PointerEvent) => {
         e.stopPropagation();
         e.preventDefault();
-        if (this._dragging) {
-            return;
-        }
-        this._dragging = true;
+        if (!this._dragging) {
+            this._dragging = true;
 
-        if (this.Marquee) {
-            this.Snippet(this.Marquee);
+            this.Marquee && this.Snippet(this.Marquee);
         }
     }
 
@@ -226,36 +217,32 @@ export default class PDFMenu extends React.Component {
         if (this._keyValue.length > 0 && this._valueValue.length > 0) {
             this._added = this.AddTag(this._keyValue, this._valueValue);
 
-            setTimeout(
-                () => {
-                    runInAction(() => {
-                        this._added = false;
-                    });
-                }, 1000
-            );
+            setTimeout(action(() => this._added = false), 1000);
         }
     }
 
     render() {
-        let buttons = this.Status === "pdf" || this.Status === "snippet" ? [
-            <button key="1" className="pdfMenu-button" title="Click to Highlight" onClick={this.highlightClicked}
-                style={this.Highlighting ? { backgroundColor: "#121212" } : {}}>
-                <FontAwesomeIcon icon="highlighter" size="lg" style={{ transition: "transform 0.1s", transform: this.Highlighting ? "" : "rotate(-45deg)" }} />
-            </button>,
-            <button className="pdfMenu-button" title="Drag to Annotate" ref={this._commentCont} onPointerDown={this.pointerDown}><FontAwesomeIcon icon="comment-alt" size="lg" key="2" /></button>,
-            this.Status === "snippet" ? <button className="pdfMenu-button" title="Drag to Snippetize Selection" onPointerDown={this.snippetStart} ref={this._snippetButton}><FontAwesomeIcon icon="cut" size="lg" /></button> : undefined,
-            <button key="3" className="pdfMenu-button" title="Pin Menu" onClick={this.togglePin}
-                style={this.Pinned ? { backgroundColor: "#121212" } : {}}>
-                <FontAwesomeIcon icon="thumbtack" size="lg" style={{ transition: "transform 0.1s", transform: this.Pinned ? "rotate(45deg)" : "" }} />
-            </button>
-        ] : [
-                <button key="4" className="pdfMenu-button" title="Delete Anchor" onPointerDown={this.deleteClicked}><FontAwesomeIcon icon="trash-alt" size="lg" key="1" /></button>,
-                <button key="5" className="pdfMenu-button" title="Pin to Presentation" onPointerDown={this.PinToPres}><FontAwesomeIcon icon="map-pin" size="lg" key="2" /></button>,
-                <div className="pdfMenu-addTag" key="3">
+        let buttons = this.Status === "pdf" || this.Status === "snippet" ?
+            [
+                <button key="1" className="pdfMenu-button" title="Click to Highlight" onClick={this.highlightClicked} style={this.Highlighting ? { backgroundColor: "#121212" } : {}}>
+                    <FontAwesomeIcon icon="highlighter" size="lg" style={{ transition: "transform 0.1s", transform: this.Highlighting ? "" : "rotate(-45deg)" }} /></button>,
+                <button key="2" className="pdfMenu-button" title="Drag to Annotate" ref={this._commentCont} onPointerDown={this.pointerDown}>
+                    <FontAwesomeIcon icon="comment-alt" size="lg" /></button>,
+                <button key="3" className="pdfMenu-button" title="Drag to Snippetize Selection" style={{ display: this.Status === "snippet" ? "" : "none" }} onPointerDown={this.snippetStart} ref={this._snippetButton}>
+                    <FontAwesomeIcon icon="cut" size="lg" /></button>,
+                <button key="4" className="pdfMenu-button" title="Pin Menu" onClick={this.togglePin} style={this.Pinned ? { backgroundColor: "#121212" } : {}}>
+                    <FontAwesomeIcon icon="thumbtack" size="lg" style={{ transition: "transform 0.1s", transform: this.Pinned ? "rotate(45deg)" : "" }} /> </button>
+            ] : [
+                <button key="5" className="pdfMenu-button" title="Delete Anchor" onPointerDown={this.deleteClicked}>
+                    <FontAwesomeIcon icon="trash-alt" size="lg" /></button>,
+                <button key="6" className="pdfMenu-button" title="Pin to Presentation" onPointerDown={this.PinToPres}>
+                    <FontAwesomeIcon icon="map-pin" size="lg" /></button>,
+                <div key="7" className="pdfMenu-addTag" >
                     <input onKeyDown={handleBackspace} onChange={this.keyChanged} placeholder="Key" style={{ gridColumn: 1 }} />
                     <input onKeyDown={handleBackspace} onChange={this.valueChanged} placeholder="Value" style={{ gridColumn: 3 }} />
                 </div>,
-                <button key="6" className="pdfMenu-button" title={`Add tag: ${this._keyValue} with value: ${this._valueValue}`} onPointerDown={this.addTag}><FontAwesomeIcon style={{ transition: "all .2s" }} color={this._added ? "#42f560" : "white"} icon="check" size="lg" key="4" /></button>,
+                <button key="8" className="pdfMenu-button" title={`Add tag: ${this._keyValue} with value: ${this._valueValue}`} onPointerDown={this.addTag}>
+                    <FontAwesomeIcon style={{ transition: "all .2s" }} color={this._added ? "#42f560" : "white"} icon="check" size="lg" /></button>,
             ];
 
         return (
-- 
cgit v1.2.3-70-g09d2


From acbe0ced15150d15d81110cd2259b99e942d02e6 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Tue, 6 Aug 2019 18:17:48 -0400
Subject: pdf css cleanup

---
 src/client/views/nodes/PDFBox.scss   |  64 +++---------
 src/client/views/pdf/Annotation.scss |   5 +-
 src/client/views/pdf/Annotation.tsx  |   2 +-
 src/client/views/pdf/PDFMenu.tsx     |   2 +-
 src/client/views/pdf/PDFViewer.scss  | 186 ++++++++++++++---------------------
 src/client/views/pdf/PDFViewer.tsx   |  37 +++----
 src/client/views/pdf/Page.scss       |  31 ++++++
 src/client/views/pdf/Page.tsx        |  32 +++---
 8 files changed, 161 insertions(+), 198 deletions(-)
 create mode 100644 src/client/views/pdf/Page.scss

(limited to 'src/client/views/pdf/PDFMenu.tsx')

diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss
index e7655d598..a1bab0409 100644
--- a/src/client/views/nodes/PDFBox.scss
+++ b/src/client/views/nodes/PDFBox.scss
@@ -1,37 +1,3 @@
-.react-pdf__Page {
-    transform-origin: left top;
-    position: absolute;
-    top: 0;
-    left: 0;
-}
-
-.react-pdf__Page__textContent span {
-    user-select: text;
-}
-
-.react-pdf__Document {
-    position: absolute;
-}
-
-.pdfBox-buttonTray {
-    position: absolute;
-    top: 0;
-    left: 0;
-    z-index: 25;
-    pointer-events: all;
-}
-
-.pdfBox-thumbnail {
-    position: absolute;
-    width: 100%;
-}
-
-.pdfButton {
-    pointer-events: all;
-    width: 100px;
-    height: 100px;
-}
-
 .pdfBox-cont,
 .pdfBox-cont-interactive {
     display: flex;
@@ -43,26 +9,17 @@
 
 .pdfBox-cont {
     pointer-events: none;
-
-    .textlayer {
-        pointer-events: none;
-
+    .pdfPage-textlayer {
         span {
             pointer-events: none !important;
+            user-select: none; 
         }
     }
-
-    .page-cont {
-        pointer-events: none;
-    }
 }
 
 .pdfBox-cont-interactive {
     pointer-events: all;
-    display: flex;
-    flex-direction: row;
-
-    .textlayer {
+    .pdfPage-textlayer {
         span {
             pointer-events: all !important;
             user-select: text;
@@ -70,11 +27,22 @@
     }
 }
 
-.pdfBox-contentContainer {
-    position: absolute;
+.react-pdf__Page {
     transform-origin: left top;
+    position: absolute;
+    top: 0;
+    left: 0;
+}
+
+.react-pdf__Page__textContent span {
+    user-select: text;
+}
+
+.react-pdf__Document {
+    position: absolute;
 }
 
+
 .pdfBox-settingsCont {
     position: absolute;
     right: 0;
diff --git a/src/client/views/pdf/Annotation.scss b/src/client/views/pdf/Annotation.scss
index 0ea85d522..817115690 100644
--- a/src/client/views/pdf/Annotation.scss
+++ b/src/client/views/pdf/Annotation.scss
@@ -1,4 +1,7 @@
-.pdfViewer-annotationBox {
+.pdfAnnotation {
     pointer-events: all;
     user-select: none;
+    position: absolute;
+    background-color: pink;
+    opacity: 0.1;
 }
\ No newline at end of file
diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx
index 9d68a86b8..947f5a2e8 100644
--- a/src/client/views/pdf/Annotation.tsx
+++ b/src/client/views/pdf/Annotation.tsx
@@ -130,7 +130,7 @@ class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
 
     render() {
         return (
-            <div className="pdfViewer-annotationBox" onPointerDown={this.onPointerDown} ref={this._mainCont}
+            <div className="pdfAnnotation" onPointerDown={this.onPointerDown} ref={this._mainCont}
                 style={{
                     top: this.props.y * scale,
                     left: this.props.x * scale,
diff --git a/src/client/views/pdf/PDFMenu.tsx b/src/client/views/pdf/PDFMenu.tsx
index 7b3d5bfae..3ed81faef 100644
--- a/src/client/views/pdf/PDFMenu.tsx
+++ b/src/client/views/pdf/PDFMenu.tsx
@@ -32,7 +32,7 @@ export default class PDFMenu extends React.Component {
     @observable public Pinned: boolean = false;
 
     public StartDrag: (e: PointerEvent, ele: HTMLElement) => void = emptyFunction;
-    public Highlight: (d: Doc | undefined, color: string | undefined) => void = emptyFunction;
+    public Highlight: (d: Doc | undefined, color: string) => void = emptyFunction;
     public Delete: () => void = emptyFunction;
     public Snippet: (marquee: { left: number, top: number, width: number, height: number }) => void = emptyFunction;
     public AddTag: (key: string, value: string) => boolean = returnFalse;
diff --git a/src/client/views/pdf/PDFViewer.scss b/src/client/views/pdf/PDFViewer.scss
index 41efb0c00..a2f3911c5 100644
--- a/src/client/views/pdf/PDFViewer.scss
+++ b/src/client/views/pdf/PDFViewer.scss
@@ -1,131 +1,93 @@
 
-.textLayer {
-    div {
-        user-select: text;
-    }
-}
-.viewer-button-cont {
-    position: absolute;
-    display: flex;
-    justify-content: space-evenly;
-    align-items: center;
-}
-
-.viewer-previousPage,
-.viewer-nextPage {
-    background: grey;
-    font-weight: bold;
-    opacity: 0.5;
-    padding: 0 10px;
-    border-radius: 5px;
-}
-
-.textLayer {
-    user-select: auto;
-}
 .pdfViewer-viewer {
     pointer-events:inherit;
     width: 100%;
-}
-
-.pdfViewer-text {
-    transform: scale(1.5);
-    transform-origin: top left;
-    .page {
-        .canvasWrapper {
-            display: none;
-        }
-
-        .textLayer {
-            position: relative;
-            user-select: none;
+    .pdfViewer-visibleElements {
+        .pdfPage-cont {
+            .pdfPage-textLayer {
+                div {
+                    user-select: text;
+                }
+                span {
+                    color: transparent;
+                    position: absolute;
+                    white-space: pre;
+                    cursor: text;
+                    -webkit-transform-origin: 0% 0%;
+                    transform-origin: 0% 0%;
+                }
+            }
         }
     }
-}
-
-.page-cont {
-    .textLayer {
-        user-select: auto;
-
-        div {
-            user-select: text;
-        }
+    .pdfViewer-text {
+        transform: scale(1.5);
+        transform-origin: top left;
     }
-}
-
-.pdfViewer-overlayCont {
-    position: absolute;
-    width: 100%;
-    height: 100px;
-    background: #121721;
-    bottom: 0;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    padding: 20px;
-    overflow: hidden;
-    transition: left .5s;
-}
 
-.pdfViewer-overlaySearchBar {
-    width: 20%;
-    height: 100%;
-    font-size: 30px;
-    padding: 5px;
-}
-
-.pdfViewer-overlayButton {
-    border-bottom-left-radius: 50%;
-    display: flex;
-    justify-content: space-evenly;
-    align-items: center;
-    height: 70px;
-    background: none;
-    padding: 0;
-    position: absolute;
-
-    .pdfViewer-overlayButton-arrow {
-        width: 0;
-        height: 0;
-        border-top: 25px solid transparent;
-        border-bottom: 25px solid transparent;
-        border-right: 25px solid #121721;
-        transition: all 0.5s;
+    .pdfViewer-annotationLayer {
+        position: absolute;
+        top: 0;
+        width: 100%;
+        pointer-events: none;
+        .pdfPage-annotationBox {
+            position: absolute;
+            background-color: red;
+            opacity: 0.1;
+        }
     }
 
-    .pdfViewer-overlayButton-iconCont {
+    .pdfViewer-overlayCont {
+        position: absolute;
+        width: 100%;
+        height: 100px;
         background: #121721;
-        height: 50px;
-        width: 70px;
+        bottom: 0;
         display: flex;
         justify-content: center;
         align-items: center;
-        margin-left: -2px;
-        border-radius: 3px;
+        padding: 20px;
+        overflow: hidden;
+        transition: left .5s;
+        .pdfViewer-overlaySearchBar {
+            width: 20%;
+            height: 100%;
+            font-size: 30px;
+            padding: 5px;
+        }
     }
-}
 
-.pdfViewer-overlayButton:hover {
-    background: none;
-}
+    .pdfViewer-overlayButton {
+        border-bottom-left-radius: 50%;
+        display: flex;
+        justify-content: space-evenly;
+        align-items: center;
+        height: 70px;
+        background: none;
+        padding: 0;
+        position: absolute;
+
+        .pdfViewer-overlayButton-arrow {
+            width: 0;
+            height: 0;
+            border-top: 25px solid transparent;
+            border-bottom: 25px solid transparent;
+            border-right: 25px solid #121721;
+            transition: all 0.5s;
+        }
 
-.pdfViewer-annotationBox {
-    position: absolute;
-    background-color: red;
-    opacity: 0.1;
-}
+        .pdfViewer-overlayButton-iconCont {
+            background: #121721;
+            height: 50px;
+            width: 70px;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            margin-left: -2px;
+            border-radius: 3px;
+        }
+    }
 
-.pdfViewer-annotationLayer {
-    position: absolute;
-    top: 0;
-         width: 100%;
-        pointer-events: none;
+    .pdfViewer-overlayButton:hover {
+        background: none;
+    }
 }
-
-
-
-.pdfViewer-pinAnnotation {
-    background-color: red;
-    position: absolute;
-    border-radius: 100%;
-}
\ No newline at end of file
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 524bb0420..9abb22553 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -427,14 +427,13 @@ export class PDFViewer extends React.Component<IViewerProps> {
 
         if (this._searching) {
             let container = this._mainCont.current;
-            let viewer = this._viewer.current;
 
             if (!this._pdfFindController) {
-                if (container && viewer) {
+                if (container && this._viewer.current) {
                     let simpleLinkService = new SimpleLinkService();
                     this._pdfViewer = new PDFJSViewer.PDFViewer({
                         container: container,
-                        viewer: viewer,
+                        viewer: this._viewer.current,
                         linkService: simpleLinkService
                     });
                     simpleLinkService.setPdf(this.props.pdf);
@@ -483,25 +482,23 @@ export class PDFViewer extends React.Component<IViewerProps> {
     render() {
         return (
             <div className="pdfViewer-viewer" ref={this._mainCont} >
-                <div className="viewer" style={this._searching ? { position: "absolute", top: 0 } : {}}>
+                <div className="pdfViewer-visibleElements" style={this._searching ? { position: "absolute", top: 0 } : {}}>
                     {this._visibleElements}
                 </div>
                 <div className="pdfViewer-text" ref={this._viewer} />
-                <div className="pdfViewer-annotationLayer" style={{ height: NumCast(this.props.Document.nativeHeight) }}>
-                    <div className="pdfViewer-annotationLayer-subCont" ref={this._annotationLayer}>
-                        {this._annotations.filter(anno => {
-                            if (this._script && this._script.compiled) {
-                                let run = this._script.run({ this: anno });
-                                if (run.success) {
-                                    return run.result;
-                                }
+                <div className="pdfViewer-annotationLayer" style={{ height: NumCast(this.props.Document.nativeHeight) }} ref={this._annotationLayer}>
+                    {this._annotations.filter(anno => {
+                        if (this._script && this._script.compiled) {
+                            let run = this._script.run({ this: anno });
+                            if (run.success) {
+                                return run.result;
                             }
-                            return true;
-                        }).sort((a: Doc, b: Doc) => NumCast(a.y) - NumCast(b.y))
-                            .map((anno: Doc, index: number) =>
-                                <Annotation anno={anno} scrollTo={this.props.scrollTo} fieldExtensionDoc={this.props.fieldExtensionDoc} ParentIndex={this.getIndex} addDocTab={this.props.addDocTab} index={index} key={`${anno[Id]}-annotation`} />
-                            )}
-                    </div>
+                        }
+                        return true;
+                    }).sort((a: Doc, b: Doc) => NumCast(a.y) - NumCast(b.y))
+                        .map((anno: Doc, index: number) =>
+                            <Annotation anno={anno} scrollTo={this.props.scrollTo} fieldExtensionDoc={this.props.fieldExtensionDoc} ParentIndex={this.getIndex} addDocTab={this.props.addDocTab} index={index} key={`${anno[Id]}-annotation`} />
+                        )}
                 </div>
                 <div className="pdfViewer-overlayCont" onPointerDown={(e) => e.stopPropagation()}
                     style={{
@@ -509,9 +506,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
                         left: `${this._searching ? 0 : 100}%`
                     }}>
                     <button className="pdfViewer-overlayButton" title="Open Search Bar"></button>
-                    {/* <button title="Previous Result" onClick={() => this.search(this._searchString)}><FontAwesomeIcon icon="arrow-up" size="3x" color="white" /></button>
-                    <button title="Next Result" onClick={this.nextResult}><FontAwesomeIcon icon="arrow-down" size="3x" color="white" /></button> */}
-                    <input onKeyDown={(e: React.KeyboardEvent) => e.keyCode === KeyCodes.ENTER ? this.search(this._searchString) : e.keyCode === KeyCodes.BACKSPACE ? e.stopPropagation() : true} placeholder="Search" className="pdfViewer-overlaySearchBar" onChange={this.searchStringChanged} />
+                    <input className="pdfViewer-overlaySearchBar" onKeyDown={(e: React.KeyboardEvent) => e.keyCode === KeyCodes.ENTER ? this.search(this._searchString) : e.keyCode === KeyCodes.BACKSPACE ? e.stopPropagation() : true} placeholder="Search" onChange={this.searchStringChanged} />
                     <button title="Search" onClick={() => this.search(this._searchString)}><FontAwesomeIcon icon="search" size="3x" color="white" /></button>
                 </div>
                 <button className="pdfViewer-overlayButton" onClick={this.prevAnnotation} title="Previous Annotation"
diff --git a/src/client/views/pdf/Page.scss b/src/client/views/pdf/Page.scss
new file mode 100644
index 000000000..6467c4979
--- /dev/null
+++ b/src/client/views/pdf/Page.scss
@@ -0,0 +1,31 @@
+
+.pdfPage-cont {
+
+    .pdfPage-dragAnnotationBox {
+        position: absolute;
+        background-color: transparent;
+        opacity: 0.1;
+    }
+    .pdfPage-annotationLayer {
+        pointer-events: none;
+        width: 100%;
+        height: 100%;
+        position: relative;
+        top: -100%;
+    }
+
+    .PdfPage-textLayer {
+        position: relative;
+        div {
+            user-select: text;
+        }
+        span {
+            color: transparent;
+            position: absolute;
+            white-space: pre;
+            cursor: text;
+            -webkit-transform-origin: 0% 0%;
+            transform-origin: 0% 0%;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/pdf/Page.tsx b/src/client/views/pdf/Page.tsx
index 1da41bca1..47f2e7b56 100644
--- a/src/client/views/pdf/Page.tsx
+++ b/src/client/views/pdf/Page.tsx
@@ -8,7 +8,7 @@ import { Docs, DocUtils } from "../../documents/Documents";
 import { DragManager } from "../../util/DragManager";
 import PDFMenu from "./PDFMenu";
 import { scale } from "./PDFViewer";
-import "./PDFViewer.scss";
+import "./Page.scss";
 import React = require("react");
 
 
@@ -43,7 +43,6 @@ export default class Page extends React.Component<IPageProps> {
 
     private _canvas: React.RefObject<HTMLCanvasElement> = React.createRef();
     private _textLayer: React.RefObject<HTMLDivElement> = React.createRef();
-    private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef();
     private _marquee: React.RefObject<HTMLDivElement> = React.createRef();
     private _marqueeing: boolean = false;
     private _reactionDisposer?: IReactionDisposer;
@@ -95,7 +94,7 @@ export default class Page extends React.Component<IPageProps> {
     }
 
     @action
-    highlight = (targetDoc?: Doc, color: string = "red") => {
+    highlight = (targetDoc: Doc | undefined, color: string) => {
         // creates annotation documents for current highlights
         let annotationDoc = this.props.makeAnnotationDocuments(targetDoc, scale, color, false);
         Doc.GetProto(annotationDoc).annotationOn = this.props.Document;
@@ -114,7 +113,7 @@ export default class Page extends React.Component<IPageProps> {
         if (this._textLayer.current) {
             let targetDoc = Docs.Create.TextDocument({ width: 200, height: 200, title: "New Annotation" });
             targetDoc.targetPage = this.props.page;
-            let annotationDoc = this.highlight(undefined, "red");
+            let annotationDoc = this.highlight(undefined, "pink");
             annotationDoc.linkedToDoc = false;
             let dragData = new DragManager.AnnotationDragData(this.props.Document, annotationDoc, targetDoc);
             DragManager.StartAnnotationDrag([ele], dragData, e.pageX, e.pageY, {
@@ -196,7 +195,6 @@ export default class Page extends React.Component<IPageProps> {
             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._marquee.current && (this._marquee.current.style.background = "red");
             e.stopPropagation();
             e.preventDefault();
         }
@@ -219,10 +217,9 @@ export default class Page extends React.Component<IPageProps> {
                 copy.style.height = style.height;
 
                 // apply the appropriate background, opacity, and transform
-                copy.style.background = "red";
                 copy.style.border = style.border;
                 copy.style.opacity = style.opacity;
-                copy.className = this._marquee.current.className;
+                copy.className = "pdfPage-annotationBox";
                 this.props.createAnnotation(copy, this.props.page);
                 this._marquee.current.style.opacity = "0";
             }
@@ -266,7 +263,7 @@ export default class Page extends React.Component<IPageProps> {
                 let rect = clientRects.item(i);
                 if (rect && rect.width !== this._textLayer.current.getBoundingClientRect().width && rect.height !== this._textLayer.current.getBoundingClientRect().height) {
                     let annoBox = document.createElement("div");
-                    annoBox.className = "pdfViewer-annotationBox";
+                    annoBox.className = "pdfPage-annotationBox";
                     // transforms the positions from screen onto the pdf div
                     annoBox.style.top = ((rect.top - boundingRect.top) * (this._textLayer.current.offsetHeight / boundingRect.height)).toString();
                     annoBox.style.left = ((rect.left - boundingRect.left) * (this._textLayer.current.offsetWidth / boundingRect.width)).toString();
@@ -295,16 +292,23 @@ export default class Page extends React.Component<IPageProps> {
 
     render() {
         return (
-            <div onPointerDown={this.onPointerDown} onDoubleClick={this.doubleClick} className={"page-cont"} style={{ "width": this._width, "height": this._height }}>
-                <div className="canvasContainer">
+            <div className={"pdfPage-cont"} onPointerDown={this.onPointerDown} onDoubleClick={this.doubleClick} style={{ "width": this._width, "height": this._height }}>
+                <div className="PdfPage-canvasContainer">
                     <canvas ref={this._canvas} />
                 </div>
-                <div className="pdfInkingLayer-cont" ref={this._annotationLayer} style={{ width: "100%", height: "100%", position: "relative", top: "-100%" }}>
-                    <div className="pdfViewer-annotationBox" ref={this._marquee}
-                        style={{ left: `${this._marqueeX}px`, top: `${this._marqueeY}px`, width: `${this._marqueeWidth}px`, height: `${this._marqueeHeight}px`, background: "red", border: `${this._marqueeWidth === 0 ? "" : "10px dashed black"}` }}>
+                <div className="pdfPage-annotationLayer">
+                    <div className="pdfPage-dragAnnotationBox" ref={this._marquee}
+                        style={{
+                            left: `${this._marqueeX}px`, top: `${this._marqueeY}px`,
+                            width: `${this._marqueeWidth}px`, height: `${this._marqueeHeight}px`,
+                            border: `${this._marqueeWidth === 0 ? "" : "10px dashed black"}`
+                        }}>
                     </div>
                 </div>
-                <div className="textlayer" ref={this._textLayer} style={{ "position": "relative", "top": `-${2 * this._height}px`, "height": `${this._height}px` }} />
+                <div className="pdfPage-textlayer"
+                    ref={this._textLayer}
+                    style={{ top: `-${2 * this._height}px`, height: `${this._height}px` }}
+                />
             </div>
         );
     }
-- 
cgit v1.2.3-70-g09d2

