From ef94ad7df2a087141ddb8d347d3e3c484ff7609b Mon Sep 17 00:00:00 2001
From: Sam Wilkins <samwilkins333@gmail.com>
Date: Tue, 3 Dec 2019 01:46:36 -0500
Subject: const linter rule and restored google docs push, fixed routing

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

(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 c64741769..38e10e99a 100644
--- a/src/client/views/pdf/PDFMenu.tsx
+++ b/src/client/views/pdf/PDFMenu.tsx
@@ -128,7 +128,7 @@ export default class PDFMenu extends AntimodeMenu {
     }
 
     render() {
-        let buttons = this.Status === "pdf" || this.Status === "snippet" ?
+        const buttons = this.Status === "pdf" || this.Status === "snippet" ?
             [
                 <button key="1" className="antimodeMenu-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>,
-- 
cgit v1.2.3-70-g09d2


From 56e384f2d97d2c399adf21fcf58143773fe3fd53 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sat, 14 Dec 2019 01:51:13 -0500
Subject: fixes to make nativewidth/height more robust for PDFs.  fixes for
 search - filter out extension docs.

---
 src/client/documents/Documents.ts                  | 11 ++++---
 src/client/util/DragManager.ts                     | 23 ++++++++------
 .../util/Import & Export/DirectoryImportBox.tsx    |  7 +----
 src/client/util/SearchUtil.ts                      |  4 +--
 src/client/views/DocComponent.tsx                  |  1 +
 src/client/views/collections/CollectionSubView.tsx |  4 +--
 .../views/collections/ParentDocumentSelector.tsx   |  2 +-
 src/client/views/nodes/PDFBox.tsx                  | 34 ++++++++++++--------
 src/client/views/pdf/PDFMenu.tsx                   | 36 ++--------------------
 src/client/views/pdf/PDFViewer.tsx                 |  4 +--
 src/client/views/search/SearchBox.tsx              |  5 ++-
 src/new_fields/Doc.ts                              | 11 +++++--
 12 files changed, 61 insertions(+), 81 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 7df08c7e6..4ba45ac30 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -112,7 +112,7 @@ export interface DocumentOptions {
     dropConverter?: ScriptField; // script to run when documents are dropped on this Document.
     strokeWidth?: number;
     color?: string;
-    limitHeight?:number; // maximum height for newly created (eg, from pasting) text documents
+    limitHeight?: number; // maximum height for newly created (eg, from pasting) text documents
     // [key: string]: Opt<Field>;
 }
 
@@ -181,7 +181,7 @@ export namespace Docs {
             }],
             [DocumentType.PDF, {
                 layout: { view: PDFBox, dataField: data },
-                options: { nativeWidth: 1200, curPage: 1 }
+                options: { curPage: 1 }
             }],
             [DocumentType.ICON, {
                 layout: { view: IconBox, dataField: data },
@@ -644,17 +644,20 @@ export namespace Docs {
             let ctor: ((path: string, options: DocumentOptions) => (Doc | Promise<Doc | undefined>)) | undefined = undefined;
             if (type.indexOf("image") !== -1) {
                 ctor = Docs.Create.ImageDocument;
+                if (!options.width) options.width = 300;
             }
             if (type.indexOf("video") !== -1) {
                 ctor = Docs.Create.VideoDocument;
+                if (!options.width) options.width = 600;
+                if (!options.height) options.height = options.width * 2 / 3;
             }
             if (type.indexOf("audio") !== -1) {
                 ctor = Docs.Create.AudioDocument;
             }
             if (type.indexOf("pdf") !== -1) {
                 ctor = Docs.Create.PdfDocument;
-                options.nativeWidth = 927;
-                options.nativeHeight = 1200;
+                if (!options.width) options.width = 400;
+                if (!options.height) options.height = options.width * 1200 / 927;
             }
             if (type.indexOf("excel") !== -1) {
                 ctor = Docs.Create.DBDocument;
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 326262895..2631a1e3c 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -18,7 +18,7 @@ import { convertDropDataToButtons } from "./DropConverter";
 export type dropActionType = "alias" | "copy" | undefined;
 export function SetupDrag(
     _reference: React.RefObject<HTMLElement>,
-    docFunc: () => Doc | Promise<Doc>,
+    docFunc: () => Doc | Promise<Doc> | undefined,
     moveFunc?: DragManager.MoveFunction,
     dropAction?: dropActionType,
     treeViewId?: string,
@@ -32,13 +32,15 @@ export function SetupDrag(
         document.removeEventListener("pointermove", onRowMove);
         document.removeEventListener('pointerup', onRowUp);
         const doc = await docFunc();
-        const dragData = new DragManager.DocumentDragData([doc]);
-        dragData.dropAction = dropAction;
-        dragData.moveDocument = moveFunc;
-        dragData.treeViewId = treeViewId;
-        dragData.dontHideOnDrop = dontHideOnDrop;
-        DragManager.StartDocumentDrag([_reference.current!], dragData, e.x, e.y);
-        dragStarted && dragStarted();
+        if (doc) {
+            const dragData = new DragManager.DocumentDragData([doc]);
+            dragData.dropAction = dropAction;
+            dragData.moveDocument = moveFunc;
+            dragData.treeViewId = treeViewId;
+            dragData.dontHideOnDrop = dontHideOnDrop;
+            DragManager.StartDocumentDrag([_reference.current!], dragData, e.x, e.y);
+            dragStarted && dragStarted();
+        }
     };
     const onRowUp = (): void => {
         document.removeEventListener("pointermove", onRowMove);
@@ -49,12 +51,13 @@ export function SetupDrag(
             e.stopPropagation();
             if (e.shiftKey && CollectionDockingView.Instance) {
                 e.persist();
-                CollectionDockingView.Instance.StartOtherDrag({
+                let dragDoc = await docFunc();
+                dragDoc && CollectionDockingView.Instance.StartOtherDrag({
                     pageX: e.pageX,
                     pageY: e.pageY,
                     preventDefault: emptyFunction,
                     button: 0
-                }, [await docFunc()]);
+                }, [dragDoc]);
             } else {
                 document.addEventListener("pointermove", onRowMove);
                 document.addEventListener("pointerup", onRowUp);
diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx
index e6a215b2c..5b5bffd8c 100644
--- a/src/client/util/Import & Export/DirectoryImportBox.tsx	
+++ b/src/client/util/Import & Export/DirectoryImportBox.tsx	
@@ -122,12 +122,7 @@ export default class DirectoryImportBox extends React.Component<FieldViewProps>
 
         await Promise.all(uploads.map(async ({ name, type, clientAccessPath, exifData }) => {
             const path = Utils.prepend(clientAccessPath);
-            const options = {
-                nativeWidth: 300,
-                width: 300,
-                title: name
-            };
-            const document = await Docs.Get.DocumentFromType(type, path, options);
+            const document = await Docs.Get.DocumentFromType(type, path, { width: 300, title: name });
             const { data, error } = exifData;
             if (document) {
                 Doc.GetProto(document).exif = error || Docs.Get.DocumentHierarchyFromJson(data);
diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts
index 7a9176bec..1fda82880 100644
--- a/src/client/util/SearchUtil.ts
+++ b/src/client/util/SearchUtil.ts
@@ -64,7 +64,7 @@ export namespace SearchUtil {
         const textDocs = newIds.map((id: string) => textDocMap[id]).map(doc => doc as Doc);
         for (let i = 0; i < textDocs.length; i++) {
             const testDoc = textDocs[i];
-            if (testDoc instanceof Doc && testDoc.type !== DocumentType.KVP && theDocs.findIndex(d => Doc.AreProtosEqual(d, testDoc)) === -1) {
+            if (testDoc instanceof Doc && testDoc.type !== DocumentType.KVP && testDoc.type !== DocumentType.EXTENSION && theDocs.findIndex(d => Doc.AreProtosEqual(d, testDoc)) === -1) {
                 theDocs.push(Doc.GetProto(testDoc));
                 theLines.push(newLines[i].map(line => line.replace(query, query.toUpperCase())));
             }
@@ -74,7 +74,7 @@ export namespace SearchUtil {
         const docs = ids.map((id: string) => docMap[id]).map(doc => doc as Doc);
         for (let i = 0; i < ids.length; i++) {
             const testDoc = docs[i];
-            if (testDoc instanceof Doc && testDoc.type !== DocumentType.KVP && (options.allowAliases || theDocs.findIndex(d => Doc.AreProtosEqual(d, testDoc)) === -1)) {
+            if (testDoc instanceof Doc && testDoc.type !== DocumentType.KVP && testDoc.type !== DocumentType.EXTENSION && (options.allowAliases || theDocs.findIndex(d => Doc.AreProtosEqual(d, testDoc)) === -1)) {
                 theDocs.push(testDoc);
                 theLines.push([]);
             }
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index c7ddee7ea..7fbad4638 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -59,6 +59,7 @@ export function DocAnnotatableComponent<P extends DocAnnotatableProps, T>(schema
         @computed get layoutDoc() { return Doc.Layout(this.props.Document); }
         @computed get dataDoc() { return (this.props.DataDoc && this.props.Document.isTemplateField ? this.props.DataDoc : Doc.GetProto(this.props.Document)) as Doc; }
         @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); }
+        @computed get extensionDocSync() { return Doc.fieldExtensionDocSync(this.dataDoc, this.props.fieldKey); }
         @computed get annotationsKey() { return "annotations"; }
 
         @action.bound
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 5c7794cc0..062521690 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -262,7 +262,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
                         .then(result => {
                             const type = result["content-type"];
                             if (type) {
-                                Docs.Get.DocumentFromType(type, str, { ...options, width: 300, nativeWidth: type.indexOf("video") !== -1 ? 600 : 300 })
+                                Docs.Get.DocumentFromType(type, str, options)
                                     .then(doc => doc && this.props.addDocument(doc));
                             }
                         });
@@ -281,7 +281,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
                     const dropFileName = file ? file.name : "-empty-";
                     promises.push(Networking.PostFormDataToServer("/upload", formData).then(results => {
                         results.map(action(({ clientAccessPath }: any) => {
-                            const full = { ...options, nativeWidth: type.indexOf("video") !== -1 ? 600 : 300, width: 300, title: dropFileName };
+                            const full = { ...options, width: 300, title: dropFileName };
                             const pathname = Utils.prepend(clientAccessPath);
                             Docs.Get.DocumentFromType(type, pathname, full).then(doc => {
                                 doc && (Doc.GetProto(doc).fileUpload = basename(pathname).replace("upload_", "").replace(/\.[a-z0-9]*$/, ""));
diff --git a/src/client/views/collections/ParentDocumentSelector.tsx b/src/client/views/collections/ParentDocumentSelector.tsx
index 5208f65c4..31f19d42d 100644
--- a/src/client/views/collections/ParentDocumentSelector.tsx
+++ b/src/client/views/collections/ParentDocumentSelector.tsx
@@ -81,7 +81,7 @@ export class SelectorContextMenu extends React.Component<SelectorProps> {
 @observer
 export class ParentDocSelector extends React.Component<SelectorProps> {
     render() {
-        let flyout = (
+        const flyout = (
             <div className="parentDocumentSelector-flyout" style={{}} title=" ">
                 <SelectorContextMenu {...this.props} />
             </div>
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 9f67f3eab..2f1e1832e 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -3,7 +3,7 @@ import { action, observable, runInAction, reaction, IReactionDisposer, trace, un
 import { observer } from "mobx-react";
 import * as Pdfjs from "pdfjs-dist";
 import "pdfjs-dist/web/pdf_viewer.css";
-import { Opt, WidthSym, Doc } from "../../../new_fields/Doc";
+import { Opt, WidthSym, Doc, HeightSym } from "../../../new_fields/Doc";
 import { makeInterface } from "../../../new_fields/Schema";
 import { ScriptField } from '../../../new_fields/ScriptField';
 import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
@@ -49,6 +49,9 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
     constructor(props: any) {
         super(props);
         this._initialScale = this.props.ScreenToLocalTransform().Scale;
+        const nw = this.Document.nativeWidth = NumCast(this.extensionDocSync.nativeWidth, NumCast(this.Document.nativeWidth, 927));
+        const nh = this.Document.nativeHeight = NumCast(this.extensionDocSync.nativeHeight, NumCast(this.Document.nativeHeight, 1200));
+        !this.Document.fitWidth && !this.Document.ignoreAspect && (this.Document.height = this.Document[WidthSym]() * (nh / nw));
 
         const backup = "oldPath";
         const { Document } = this.props;
@@ -78,10 +81,6 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
         this._selectReactionDisposer && this._selectReactionDisposer();
     }
     componentDidMount() {
-        const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField);
-        if (pdfUrl instanceof PdfField) {
-            Pdfjs.getDocument(pdfUrl.url.href).promise.then(pdf => runInAction(() => this._pdf = pdf));
-        }
         this._selectReactionDisposer = reaction(() => this.props.isSelected(),
             () => {
                 document.removeEventListener("keydown", this.onKeyDown);
@@ -90,9 +89,9 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
     }
 
     loaded = (nw: number, nh: number, np: number) => {
-        this.dataDoc.numPages = np;
-        this.Document.nativeWidth = nw * 96 / 72;
-        this.Document.nativeHeight = nh * 96 / 72;
+        this.extensionDocSync.numPages = np;
+        this.extensionDocSync.nativeWidth = this.Document.nativeWidth = nw * 96 / 72;
+        this.extensionDocSync.nativeHeight = this.Document.nativeHeight = nh * 96 / 72;
         !this.Document.fitWidth && !this.Document.ignoreAspect && (this.Document.height = this.Document[WidthSym]() * (nh / nw));
     }
 
@@ -220,9 +219,9 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
     @computed get renderTitleBox() {
         const classname = "pdfBox" + (this.active() ? "-interactive" : "");
         return <div className={classname} style={{
-            width: !this.props.Document.fitWidth ? NumCast(this.props.Document.nativeWidth) : `${100 / this.contentScaling}%`,
-            height: !this.props.Document.fitWidth ? NumCast(this.props.Document.nativeHeight) : `${100 / this.contentScaling}%`,
-            transform: `scale(${this.props.ContentScaling()})`
+            width: !this.props.Document.fitWidth ? this.Document.nativeWidth || 0 : `${100 / this.contentScaling}%`,
+            height: !this.props.Document.fitWidth ? this.Document.nativeHeight || 0 : `${100 / this.contentScaling}%`,
+            transform: `scale(${this.contentScaling})`
         }}  >
             <div className="pdfBox-title-outer">
                 <strong className="pdfBox-title" >{this.props.Document.title}</strong>
@@ -248,10 +247,19 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
         </div>;
     }
 
+    _pdfjsRequested = false;
     render() {
         const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField, null);
         if (this.props.isSelected() || this.props.Document.scrollY !== undefined) this._everActive = true;
-        return !pdfUrl || !this._pdf || !this.extensionDoc || (!this._everActive && this.props.ScreenToLocalTransform().Scale > 2.5) ?
-            this.renderTitleBox : this.renderPdfView;
+        if (pdfUrl && this.extensionDoc && (this._everActive || (this.extensionDoc.nativeWidth && this.props.ScreenToLocalTransform().Scale < 2.5))) {
+            if (pdfUrl instanceof PdfField && this._pdf) {
+                return this.renderPdfView;
+            }
+            if (!this._pdfjsRequested) {
+                this._pdfjsRequested = true;
+                Pdfjs.getDocument(pdfUrl.url.href).promise.then(pdf => runInAction(() => this._pdf = pdf));
+            }
+        }
+        return this.renderTitleBox;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/pdf/PDFMenu.tsx b/src/client/views/pdf/PDFMenu.tsx
index 38e10e99a..503696ae9 100644
--- a/src/client/views/pdf/PDFMenu.tsx
+++ b/src/client/views/pdf/PDFMenu.tsx
@@ -12,19 +12,17 @@ export default class PDFMenu extends AntimodeMenu {
     static Instance: PDFMenu;
 
     private _commentCont = React.createRef<HTMLButtonElement>();
-    private _snippetButton: React.RefObject<HTMLButtonElement> = React.createRef();
 
     @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 Status: "pdf" | "annotation" | "" = "";
 
     public StartDrag: (e: PointerEvent, ele: HTMLElement) => void = unimplementedFunction;
     public Highlight: (color: string) => Opt<Doc> = (color: string) => undefined;
     public Delete: () => void = unimplementedFunction;
-    public Snippet: (marquee: { left: number, top: number, width: number, height: number }) => void = unimplementedFunction;
     public AddTag: (key: string, value: string) => boolean = returnFalse;
     public PinToPres: () => void = unimplementedFunction;
     public Marquee: { left: number; top: number; width: number; height: number; } | undefined;
@@ -80,34 +78,6 @@ export default class PDFMenu extends AntimodeMenu {
         this.Delete();
     }
 
-    snippetStart = (e: React.PointerEvent) => {
-        document.removeEventListener("pointermove", this.snippetDrag);
-        document.addEventListener("pointermove", this.snippetDrag);
-        document.removeEventListener("pointerup", this.snippetEnd);
-        document.addEventListener("pointerup", this.snippetEnd);
-
-        e.stopPropagation();
-        e.preventDefault();
-    }
-
-    snippetDrag = (e: PointerEvent) => {
-        e.stopPropagation();
-        e.preventDefault();
-        if (!this._dragging) {
-            this._dragging = true;
-
-            this.Marquee && this.Snippet(this.Marquee);
-        }
-    }
-
-    snippetEnd = (e: PointerEvent) => {
-        this._dragging = false;
-        document.removeEventListener("pointermove", this.snippetDrag);
-        document.removeEventListener("pointerup", this.snippetEnd);
-        e.stopPropagation();
-        e.preventDefault();
-    }
-
     @action
     keyChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
         this._keyValue = e.currentTarget.value;
@@ -128,14 +98,12 @@ export default class PDFMenu extends AntimodeMenu {
     }
 
     render() {
-        const buttons = this.Status === "pdf" || this.Status === "snippet" ?
+        const buttons = this.Status === "pdf"  ?
             [
                 <button key="1" className="antimodeMenu-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="antimodeMenu-button" title="Drag to Annotate" ref={this._commentCont} onPointerDown={this.pointerDown}>
                     <FontAwesomeIcon icon="comment-alt" size="lg" /></button>,
-                <button key="3" className="antimodeMenu-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="antimodeMenu-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>
             ] : [
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index e34d353f4..1a09991d2 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -417,7 +417,6 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
             // clear out old marquees and initialize menu for new selection
             PDFMenu.Instance.StartDrag = this.startDrag;
             PDFMenu.Instance.Highlight = this.highlight;
-            PDFMenu.Instance.Snippet = this.createSnippet;
             PDFMenu.Instance.Status = "pdf";
             PDFMenu.Instance.fadeOut(true);
             this._savedAnnotations.values().forEach(v => v.forEach(a => a.remove()));
@@ -515,7 +514,6 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
                 }
 
                 if (!e.ctrlKey) {
-                    PDFMenu.Instance.Status = "snippet";
                     PDFMenu.Instance.Marquee = { left: this._marqueeX, top: this._marqueeY, width: this._marqueeWidth, height: this._marqueeHeight };
                 }
                 PDFMenu.Instance.jumpTo(e.clientX, e.clientY);
@@ -599,7 +597,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
         if (!this.props.Document[HeightSym]() || !this.props.Document.nativeHeight) {
             setTimeout((() => {
                 this.Document.height = this.Document[WidthSym]() * this._coverPath.height / this._coverPath.width;
-                this.Document.nativeHeight = nativeWidth * this._coverPath.height / this._coverPath.width;
+                this.Document.nativeHeight = (this.Document.nativeWidth || 0) * this._coverPath.height / this._coverPath.width;
             }).bind(this), 0);
         }
         const nativeWidth = (this.Document.nativeWidth || 0);
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index b80c3bb54..2f28ebf76 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -234,8 +234,7 @@ export class SearchBox extends React.Component {
                 y += 300;
             }
         }
-        return Docs.Create.FreeformDocument(docs, { width: 400, height: 400, panX: 175, panY: 175, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` });
-
+        return Docs.Create.TreeDocument(docs, { width: 200, height: 400, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` });
     }
 
     @action.bound
@@ -341,7 +340,7 @@ export class SearchBox extends React.Component {
         return (
             <div className="searchBox-container" onPointerDown={e => { e.stopPropagation(); e.preventDefault(); }}>
                 <div className="searchBox-bar">
-                    <span className="searchBox-barChild searchBox-collection" onPointerDown={SetupDrag(this.collectionRef, this.startDragCollection)} ref={this.collectionRef} title="Drag Results as Collection">
+                    <span className="searchBox-barChild searchBox-collection" onPointerDown={SetupDrag(this.collectionRef, () => this._searchString ? this.startDragCollection() : undefined)} ref={this.collectionRef} title="Drag Results as Collection">
                         <FontAwesomeIcon icon="object-group" size="lg" />
                     </span>
                     <input value={this._searchString} onChange={this.onChange} type="text" placeholder="Search..." id="search-input" ref={this.inputRef}
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 17c1b7e16..aa33d4c8b 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -467,9 +467,14 @@ export namespace Doc {
     // to store annotations, ink, and other data.
     //
     export function fieldExtensionDoc(doc: Doc, fieldKey: string) {
-        const extension = doc[fieldKey + "_ext"] as Doc;
-        (extension === undefined) && setTimeout(() => CreateDocumentExtensionForField(doc, fieldKey), 0);
-        return extension ? extension : undefined;
+        const extension = doc[fieldKey + "_ext"];
+        if (extension === undefined) {
+            setTimeout(() => CreateDocumentExtensionForField(doc, fieldKey), 0);
+        }
+        return extension ? extension as Doc : undefined;
+    }
+    export function fieldExtensionDocSync(doc: Doc, fieldKey: string) {
+        return (doc[fieldKey + "_ext"] as Doc) ||  CreateDocumentExtensionForField(doc, fieldKey);
     }
 
     export function CreateDocumentExtensionForField(doc: Doc, fieldKey: string) {
-- 
cgit v1.2.3-70-g09d2

