From 088eec96750fcbdfc30b42f24e8b57926441f4e5 Mon Sep 17 00:00:00 2001
From: yipstanley <stanley_yip@brown.edu>
Date: Thu, 27 Jun 2019 12:29:55 -0400
Subject: pdf fixes

---
 .../collectionFreeForm/CollectionFreeFormView.tsx           | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 996032b1d..15185ecb0 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -239,8 +239,17 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         var scale = this.getLocalTransform().inverse().Scale;
         const newPanX = Math.min((1 - 1 / scale) * this.nativeWidth, Math.max(0, panX));
         const newPanY = Math.min((1 - 1 / scale) * this.nativeHeight, Math.max(0, panY));
-        this.props.Document.panX = this.isAnnotationOverlay ? newPanX : panX;
-        this.props.Document.panY = this.isAnnotationOverlay ? newPanY : panY;
+        // this.props.Document.panX = this.isAnnotationOverlay ? newPanX : panX;
+        // this.props.Document.panY = this.isAnnotationOverlay ? newPanY : panY;
+        this.props.Document.panX = panX;
+        if (this.props.Document.scrollY) {
+            this.props.Document.scrollY = panY;
+            this.props.Document.panY = panY;
+        }
+        else {
+
+            this.props.Document.panY = panY;
+        }
     }
 
     @action
-- 
cgit v1.2.3-70-g09d2


From dc4b658639beb21e73fc2411abd147ff6716ba3d Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Fri, 28 Jun 2019 03:00:30 -0400
Subject: added expansion of templates on demand

---
 package.json                                       |  2 +-
 src/client/views/DocumentDecorations.tsx           |  7 ++++
 .../views/collections/CollectionTreeView.tsx       |  2 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  5 ++-
 src/client/views/nodes/DocumentView.tsx            |  2 +-
 src/client/views/nodes/FieldView.tsx               |  7 +++-
 src/client/views/nodes/ImageBox.tsx                | 44 ++++++++++++++++------
 src/new_fields/Doc.ts                              | 13 +++++++
 8 files changed, 64 insertions(+), 18 deletions(-)

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

diff --git a/package.json b/package.json
index dc829a045..51d1bab5d 100644
--- a/package.json
+++ b/package.json
@@ -196,4 +196,4 @@
         "uuid": "^3.3.2",
         "xoauth2": "^1.2.0"
     }
-}
\ No newline at end of file
+}
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index db10007f4..fdfff86db 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -85,11 +85,18 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                 let metaKey = text.slice(1, text.length);
                 let metaKeyProp = `fieldKey={"${metaKey}"}`;
 
+                let layoutProto = Doc.GetProto(field.props.Document);
                 let template = Doc.MakeAlias(field.props.Document);
                 template.proto = collection;
                 template.title = metaKey;
                 template.nativeWidth = Cast(field.nativeWidth, "number");
                 template.nativeHeight = Cast(field.nativeHeight, "number");
+                template.width = NumCast(field.props.Document.width);
+                template.height = NumCast(field.props.Document.height);
+                template.panX = NumCast(field.props.Document.panX);
+                template.panY = NumCast(field.props.Document.panY);
+                template.x = NumCast(field.props.Document.x);
+                template.y = NumCast(field.props.Document.y);
                 template.embed = true;
                 template.isTemplate = true;
                 template.templates = new List<string>([Templates.TitleBar(metaKey)]);
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 5c80fbd38..ccd0e92af 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -233,7 +233,7 @@ class TreeView extends React.Component<TreeViewProps> {
     onWorkspaceContextMenu = (e: React.MouseEvent): void => {
         if (!e.isPropagationStopped()) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7
             ContextMenu.Instance.addItem({ description: "Open as Workspace", event: undoBatch(() => MainView.Instance.openWorkspace(this.resolvedDataDoc)) });
-            ContextMenu.Instance.addItem({ description: "Open Fields", event: () => { let kvp = Docs.KVPDocument(this.props.document, { width: 300, height: 300 }); this.props.addDocTab(kvp, kvp, "onRight"); }, icon: "layer-group" });
+            ContextMenu.Instance.addItem({ description: "Open Fields", event: () => { let kvp = Docs.KVPDocument(this.props.document, { width: 300, height: 300 }); this.props.addDocTab(kvp, this.props.dataDoc ? this.props.dataDoc : kvp, "onRight"); }, icon: "layer-group" });
             if (NumCast(this.props.document.viewType) !== CollectionViewType.Docking) {
                 ContextMenu.Instance.addItem({ description: "Open Tab", event: () => this.props.addDocTab(this.props.document, this.resolvedDataDoc, "inTab"), icon: "folder" });
                 ContextMenu.Instance.addItem({ description: "Open Right", event: () => this.props.addDocTab(this.props.document, this.resolvedDataDoc, "onRight"), icon: "caret-square-right" });
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 15185ecb0..128525a48 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -28,6 +28,7 @@ import { MarqueeView } from "./MarqueeView";
 import React = require("react");
 import v5 = require("uuid/v5");
 
+
 export const panZoomSchema = createSchema({
     panX: "number",
     panY: "number",
@@ -334,11 +335,13 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         return 1;
     }
 
-
     getDocumentViewProps(layoutDoc: Doc): DocumentViewProps {
         let datadoc = BoolCast(this.props.Document.isTemplate) || this.props.DataDoc === this.props.Document ? undefined : this.props.DataDoc;
         if (Cast(layoutDoc.layout, Doc) instanceof Doc) { // if this document is using a template to render, then set the dataDoc for the template to be this document
             datadoc = layoutDoc;
+        } else if (datadoc && datadoc !== layoutDoc) {  // if this view has a dataDocument and it's not the same as the view document
+            // then map the view document to an instance of itself (ie, expand the template).  This allows the view override the template's properties and be referenceable as  document.
+            layoutDoc = Doc.expandTemplateLayout(layoutDoc, datadoc);
         }
         return {
             DataDoc: datadoc,
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 4ac43ef4d..2ee694225 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -393,7 +393,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     }
 
     deleteClicked = (): void => { this.props.removeDocument && this.props.removeDocument(this.props.Document); };
-    fieldsClicked = (): void => { let kvp = Docs.KVPDocument(this.props.Document, { width: 300, height: 300 }); this.props.addDocTab(kvp, kvp, "onRight"); };
+    fieldsClicked = (): void => { let kvp = Docs.KVPDocument(this.props.Document, { width: 300, height: 300 }); this.props.addDocTab(kvp, this.dataDoc, "onRight"); };
     makeBtnClicked = (): void => {
         let doc = Doc.GetProto(this.props.Document);
         doc.isButton = !BoolCast(doc.isButton, false);
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 55f61ddff..7c8509722 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -18,6 +18,8 @@ import { ImageBox } from "./ImageBox";
 import { PDFBox } from "./PDFBox";
 import { VideoBox } from "./VideoBox";
 import { Id } from "../../../new_fields/FieldSymbols";
+import { BoolCast, Cast } from "../../../new_fields/Types";
+import { DarpaDatasetDoc } from "../../northstar/model/idea/idea";
 
 
 //
@@ -28,6 +30,7 @@ import { Id } from "../../../new_fields/FieldSymbols";
 export interface FieldViewProps {
     fieldKey: string;
     fieldExt: string;
+    leaveNativeSize?: boolean;
     ContainingCollectionView: Opt<CollectionView | CollectionPDFView | CollectionVideoView>;
     Document: Doc;
     DataDoc?: Doc;
@@ -72,7 +75,7 @@ export class FieldView extends React.Component<FieldViewProps> {
             return <FormattedTextBox {...this.props} />;
         }
         else if (field instanceof ImageField) {
-            return <ImageBox {...this.props} />;
+            return <ImageBox {...this.props} leaveNativeSize={true} />;
         }
         else if (field instanceof IconField) {
             return <IconBox {...this.props} />;
@@ -86,7 +89,7 @@ export class FieldView extends React.Component<FieldViewProps> {
             return <p>{field.date.toLocaleString()}</p>;
         }
         else if (field instanceof Doc) {
-            return <p><b>{field.title + " + " + field[Id]}</b></p>;
+            return <p><b>{field.title + " : id= " + field[Id]}</b></p>;
             // let returnHundred = () => 100;
             // return (
             //     <DocumentContentsView Document={field}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 5c00d9d44..378b13b0d 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -20,6 +20,8 @@ import { positionSchema } from './DocumentView';
 import { FieldView, FieldViewProps } from './FieldView';
 import "./ImageBox.scss";
 import React = require("react");
+import { RouteStore } from '../../../server/RouteStore';
+var requestImageSize = require('../../util/request-image-size');
 var path = require('path');
 
 
@@ -27,7 +29,7 @@ library.add(faImage);
 
 
 export const pageSchema = createSchema({
-    curPage: "number"
+    curPage: "number",
 });
 
 type ImageDocument = makeInterface<[typeof pageSchema, typeof positionSchema]>;
@@ -41,7 +43,6 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
     private _downX: number = 0;
     private _downY: number = 0;
     private _lastTap: number = 0;
-    @observable private _photoIndex: number = 0;
     @observable private _isOpen: boolean = false;
     private dropDisposer?: DragManager.DragDropDisposer;
 
@@ -115,20 +116,21 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
         e.stopPropagation();
     }
 
+    @action
     lightbox = (images: string[]) => {
         if (this._isOpen) {
             return (<Lightbox
-                mainSrc={images[this._photoIndex]}
-                nextSrc={images[(this._photoIndex + 1) % images.length]}
-                prevSrc={images[(this._photoIndex + images.length - 1) % images.length]}
+                mainSrc={images[this.Document.curPage || 0]}
+                nextSrc={images[((this.Document.curPage || 0) + 1) % images.length]}
+                prevSrc={images[((this.Document.curPage || 0) + images.length - 1) % images.length]}
                 onCloseRequest={action(() =>
                     this._isOpen = false
                 )}
                 onMovePrevRequest={action(() =>
-                    this._photoIndex = (this._photoIndex + images.length - 1) % images.length
+                    this.Document.curPage = ((this.Document.curPage || 0) + images.length - 1) % images.length
                 )}
                 onMoveNextRequest={action(() =>
-                    this._photoIndex = (this._photoIndex + 1) % images.length
+                    this.Document.curPage = ((this.Document.curPage || 0) + 1) % images.length
                 )}
             />);
         }
@@ -160,7 +162,6 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
 
     @action
     onDotDown(index: number) {
-        this._photoIndex = index;
         this.Document.curPage = index;
     }
 
@@ -170,7 +171,7 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
         let left = (nativeWidth - paths.length * dist) / 2;
         return paths.map((p, i) =>
             <div className="imageBox-placer" key={i} >
-                <div className="imageBox-dot" style={{ background: (i === this._photoIndex ? "black" : "gray"), transform: `translate(${i * dist + left}px, 0px)` }} onPointerDown={(e: React.PointerEvent) => { e.stopPropagation(); this.onDotDown(i); }} />
+                <div className="imageBox-dot" style={{ background: (i === this.Document.curPage ? "black" : "gray"), transform: `translate(${i * dist + left}px, 0px)` }} onPointerDown={(e: React.PointerEvent) => { e.stopPropagation(); this.onDotDown(i); }} />
             </div>
         );
     }
@@ -199,6 +200,22 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
         }
     }
     _curSuffix = "_m";
+
+    resize(srcpath: string, layoutdoc: Doc) {
+        requestImageSize(window.origin + RouteStore.corsProxy + "/" + srcpath)
+            .then((size: any) => {
+                let aspect = size.height / size.width;
+                if (layoutdoc[HeightSym]() / layoutdoc[WidthSym]() != aspect) {
+                    setTimeout(action(() => {
+                        layoutdoc.height = layoutdoc[WidthSym]() * aspect;
+                        layoutdoc.nativeHeight = size.height;
+                        layoutdoc.nativeWidth = size.width;
+                    }), 0);
+                }
+            })
+            .catch((err: any) => console.log(err));
+    }
+
     render() {
         // let transform = this.props.ScreenToLocalTransform().inverse();
         let pw = typeof this.props.PanelWidth === "function" ? this.props.PanelWidth() : typeof this.props.PanelWidth === "number" ? (this.props.PanelWidth as any) as number : 50;
@@ -212,6 +229,7 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
         let paths: string[] = ["http://www.cs.brown.edu/~bcz/noImage.png"];
         // this._curSuffix = "";
         // if (w > 20) {
+        Doc.UpdateDocumentExtensionForField(this.extensionDoc, this.props.fieldKey);
         let alts = DocListCast(this.extensionDoc.Alternates);
         let altpaths: string[] = alts.filter(doc => doc.data instanceof ImageField).map(doc => this.choosePath((doc.data as ImageField).url));
         let field = this.dataDoc[this.props.fieldKey];
@@ -225,8 +243,10 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
         let rotation = NumCast(this.dataDoc.rotation, 0);
         let aspect = (rotation % 180) ? this.dataDoc[HeightSym]() / this.dataDoc[WidthSym]() : 1;
         let shift = (rotation % 180) ? (nativeHeight - nativeWidth / aspect) / 2 : 0;
-        Doc.UpdateDocumentExtensionForField(this.extensionDoc, this.props.fieldKey);
-        let srcpath = paths[Math.min(paths.length, this._photoIndex)];
+        let srcpath = paths[Math.min(paths.length, this.Document.curPage || 0)];
+
+        if (!this.props.Document.ignoreAspect && !this.props.leaveNativeSize) this.resize(srcpath, this.props.Document);
+
         return (
             <div id={id} className={`imageBox-cont${interactive}`} style={{ background: "transparent" }}
                 onPointerDown={this.onPointerDown}
@@ -235,7 +255,7 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
                     key={this._smallRetryCount + (this._mediumRetryCount << 4) + (this._largeRetryCount << 8)} // force cache to update on retrys
                     src={srcpath}
                     style={{ transform: `translate(0px, ${shift}px) rotate(${rotation}deg) scale(${aspect})` }}
-                    // style={{ objectFit: (this._photoIndex === 0 ? undefined : "contain") }}
+                    // style={{ objectFit: (this.Document.curPage === 0 ? undefined : "contain") }}
                     width={nativeWidth}
                     ref={this._imgRef}
                     onError={this.onError} />
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index b0184dd4e..d552ddd2d 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -280,6 +280,19 @@ export namespace Doc {
         return new Doc;
     }
 
+    export function expandTemplateLayout(templateLayoutDoc: Doc, dataDoc: Doc) {
+        let expandedTemplateLayout = templateLayoutDoc["_expanded_" + dataDoc[Id]];
+        if (expandedTemplateLayout instanceof Doc) {
+            return expandedTemplateLayout;
+        }
+        if (expandedTemplateLayout === undefined)
+            setTimeout(() => {
+                templateLayoutDoc["_expanded_" + dataDoc[Id]] = Doc.MakeDelegate(templateLayoutDoc);
+                (templateLayoutDoc["_expanded_" + dataDoc[Id]] as Doc).title = templateLayoutDoc.title + " applied to " + dataDoc.title;
+            }, 0);
+        return templateLayoutDoc;
+    }
+
     export function MakeCopy(doc: Doc, copyProto: boolean = false): Doc {
         const copy = new Doc;
         Object.keys(doc).forEach(key => {
-- 
cgit v1.2.3-70-g09d2


From 09042b933c843d24a715e8c58414976133b19e41 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Fri, 28 Jun 2019 14:28:47 -0400
Subject: fixed template application to create expanded documents

---
 src/client/views/DocumentDecorations.tsx           | 55 ++++++++++------------
 .../views/collections/CollectionSchemaView.tsx     | 14 +++++-
 .../views/collections/CollectionStackingView.tsx   | 12 +++--
 .../views/collections/CollectionTreeView.tsx       | 18 ++++---
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 41 +++++++++++-----
 src/client/views/nodes/FormattedTextBox.tsx        |  8 +++-
 src/client/views/nodes/ImageBox.tsx                |  2 +-
 src/new_fields/Doc.ts                              | 10 +++-
 8 files changed, 101 insertions(+), 59 deletions(-)

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

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index fdfff86db..76c2d71e8 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -26,6 +26,7 @@ import { Template, Templates } from "./Templates";
 import React = require("react");
 import { RichTextField } from '../../new_fields/RichTextField';
 import { LinkManager } from '../util/LinkManager';
+import { ObjectField } from '../../new_fields/ObjectField';
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -77,39 +78,31 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                 this._fieldKey = text.slice(1, text.length);
                 this._title = this.selectionTitle;
             } else if (text.startsWith(">")) {
-                let field = SelectionManager.SelectedDocuments()[0];
-                let collection = field.props.ContainingCollectionView!.props.Document;
-
-                let collectionKey = field.props.ContainingCollectionView!.props.fieldKey;
-                let collectionKeyProp = `fieldKey={"${collectionKey}"}`;
+                let fieldTemplateView = SelectionManager.SelectedDocuments()[0];
+                SelectionManager.DeselectAll();
+                let fieldTemplate = fieldTemplateView.props.Document;
+                let docTemplate = fieldTemplateView.props.ContainingCollectionView!.props.Document;
                 let metaKey = text.slice(1, text.length);
-                let metaKeyProp = `fieldKey={"${metaKey}"}`;
-
-                let layoutProto = Doc.GetProto(field.props.Document);
-                let template = Doc.MakeAlias(field.props.Document);
-                template.proto = collection;
-                template.title = metaKey;
-                template.nativeWidth = Cast(field.nativeWidth, "number");
-                template.nativeHeight = Cast(field.nativeHeight, "number");
-                template.width = NumCast(field.props.Document.width);
-                template.height = NumCast(field.props.Document.height);
-                template.panX = NumCast(field.props.Document.panX);
-                template.panY = NumCast(field.props.Document.panY);
-                template.x = NumCast(field.props.Document.x);
-                template.y = NumCast(field.props.Document.y);
-                template.embed = true;
-                template.isTemplate = true;
-                template.templates = new List<string>([Templates.TitleBar(metaKey)]);
-                if (field.props.Document.backgroundLayout) {
-                    let metaAnoKeyProp = `fieldKey={"${metaKey}"} fieldExt={"annotations"}`;
-                    let collectionAnoKeyProp = `fieldKey={"annotations"}`;
-                    template.layout = StrCast(field.props.Document.layout).replace(collectionAnoKeyProp, metaAnoKeyProp);
-                    template.backgroundLayout = StrCast(field.props.Document.backgroundLayout).replace(collectionKeyProp, metaKeyProp);
-                } else {
-                    template.layout = StrCast(field.props.Document.layout).replace(collectionKeyProp, metaKeyProp);
+
+                // move data doc fields to layout doc as needed (nativeWidth/nativeHeight, data, ??)
+                let backgroundLayout = StrCast(fieldTemplate.backgroundLayout);
+                let layout = StrCast(fieldTemplate.layout).replace(/fieldKey={"[^"]*"}/, `fieldKey={"${metaKey}"}`);
+                if (backgroundLayout) {
+                    layout = StrCast(fieldTemplate.layout).replace(/fieldKey={"annotations"}/, `fieldKey={"${metaKey}"} fieldExt={"annotations"}`);
+                    backgroundLayout = backgroundLayout.replace(/fieldKey={"[^"]*"}/, `fieldKey={"${metaKey}"}`);
                 }
-                Doc.AddDocToList(collection, collectionKey, template);
-                SelectionManager.SelectedDocuments().map(dv => dv.props.removeDocument && dv.props.removeDocument(dv.props.Document));
+                let nw = Cast(fieldTemplate.nativeWidth, "number");
+                let nh = Cast(fieldTemplate.nativeHeight, "number");
+
+                fieldTemplate.title = metaKey;
+                fieldTemplate.layout = layout;
+                fieldTemplate.backgroundLayout = backgroundLayout;
+                fieldTemplate.nativeWidth = nw;
+                fieldTemplate.nativeHeight = nh;
+                fieldTemplate.embed = true;
+                fieldTemplate.isTemplate = true;
+                fieldTemplate.templates = new List<string>([Templates.TitleBar(metaKey)]);
+                fieldTemplate.proto = Doc.GetProto(docTemplate);
             }
             else {
                 if (SelectionManager.SelectedDocuments().length > 0) {
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 98bf513bb..5562676e9 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -349,12 +349,22 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
             <div className="collectionSchemaView-dividerDragger" onPointerDown={this.onDividerDown} style={{ width: `${this.DIVIDER_WIDTH}px` }} />;
     }
 
+
     @computed
     get previewPanel() {
+        // let layoutDoc = this.previewDocument;
+        // let resolvedDataDoc = (layoutDoc !== this.props.DataDoc) ? this.props.DataDoc : undefined;
+        // if (layoutDoc && !(Cast(layoutDoc.layout, Doc) instanceof Doc) &&
+        //     resolvedDataDoc && resolvedDataDoc !== layoutDoc) {
+        //     // ... so change the layout to be an expanded view of the template layout.  This allows the view override the template's properties and be referenceable as its own document.
+        //     layoutDoc = Doc.expandTemplateLayout(layoutDoc, resolvedDataDoc);
+        // }
+
+        let layoutDoc = this.previewDocument ? Doc.expandTemplateLayout(this.previewDocument, this.props.DataDoc) : undefined;
         return <div ref={this.createTarget}>
             <CollectionSchemaPreview
-                Document={this.previewDocument}
-                DataDocument={BoolCast(this.props.Document.isTemplate) ? this.previewDocument : this.props.DataDoc}
+                Document={layoutDoc}
+                DataDocument={this.previewDocument !== this.props.DataDoc ? this.props.DataDoc : undefined}
                 childDocs={this.childDocs}
                 renderDepth={this.props.renderDepth}
                 width={this.previewWidth}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 6c4ea18a1..088a9bae8 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -4,12 +4,13 @@ import { action, computed, IReactionDisposer, reaction } from "mobx";
 import { observer } from "mobx-react";
 import { Doc, HeightSym, WidthSym } from "../../../new_fields/Doc";
 import { Id } from "../../../new_fields/FieldSymbols";
-import { BoolCast, NumCast } from "../../../new_fields/Types";
+import { BoolCast, NumCast, Cast } from "../../../new_fields/Types";
 import { emptyFunction, Utils } from "../../../Utils";
 import { ContextMenu } from "../ContextMenu";
 import { CollectionSchemaPreview } from "./CollectionSchemaView";
 import "./CollectionStackingView.scss";
 import { CollectionSubView } from "./CollectionSubView";
+import { resolve } from "bluebird";
 
 @observer
 export class CollectionStackingView extends CollectionSubView(doc => doc) {
@@ -66,17 +67,18 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     get singleColumnChildren() {
         let children = this.childDocs.filter(d => !d.isMinimized);
         return children.map((d, i) => {
+            let layoutDoc = Doc.expandTemplateLayout(d, this.props.DataDoc);
             let dref = React.createRef<HTMLDivElement>();
-            let dxf = () => this.getDocTransform(d, dref.current!).scale(this.columnWidth / d[WidthSym]());
+            let dxf = () => this.getDocTransform(layoutDoc, dref.current!).scale(this.columnWidth / d[WidthSym]());
             let width = () => d.nativeWidth ? Math.min(d[WidthSym](), this.columnWidth) : this.columnWidth;
-            let height = () => this.singleColDocHeight(d);
+            let height = () => this.singleColDocHeight(layoutDoc);
             return <div className="collectionStackingView-columnDoc"
                 key={d[Id]}
                 ref={dref}
                 style={{ width: width(), height: height() }} >
                 <CollectionSchemaPreview
-                    Document={d}
-                    DataDocument={this.props.Document.layout instanceof Doc ? this.props.Document : this.props.DataDoc}
+                    Document={layoutDoc}
+                    DataDocument={d != this.props.DataDoc ? this.props.DataDoc : undefined}
                     renderDepth={this.props.renderDepth}
                     width={width}
                     height={height}
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index ccd0e92af..9e0130281 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -183,16 +183,20 @@ class TreeView extends React.Component<TreeViewProps> {
         let keys = Array.from(Object.keys(this.resolvedDataDoc));
         if (this.resolvedDataDoc.proto instanceof Doc) {
             keys.push(...Array.from(Object.keys(this.resolvedDataDoc.proto)));
-            while (keys.indexOf("proto") !== -1) keys.splice(keys.indexOf("proto"), 1);
         }
-        let keyList: string[] = keys.reduce((l, key) => Cast(this.resolvedDataDoc[key], listSpec(Doc)) ? [...l, key] : l, [] as string[]);
+        let keyList: string[] = keys.reduce((l, key) => {
+            let listspec = DocListCast(this.resolvedDataDoc[key]);
+            if (listspec && listspec.length)
+                return [...l, key];
+            return l;
+        }, [] as string[]);
         keys.map(key => Cast(this.resolvedDataDoc[key], Doc) instanceof Doc && keyList.push(key));
         if (LinkManager.Instance.getAllRelatedLinks(this.props.document).length > 0) keyList.push("links");
         if (keyList.indexOf(this.fieldKey) !== -1) {
             keyList.splice(keyList.indexOf(this.fieldKey), 1);
         }
         keyList.splice(0, 0, this.fieldKey);
-        return keyList;
+        return keyList.filter((item, index) => keyList.indexOf(item) >= index);
     }
     /**
      * Renders the EditableView title element for placement into the tree.
@@ -322,14 +326,14 @@ class TreeView extends React.Component<TreeViewProps> {
                             this.props.dropAction, this.props.addDocTab, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, this.props.panelWidth, this.props.renderDepth)}
                 </ul >;
             } else {
-                console.log("PW = " + this.props.panelWidth());
-                contentElement = <div ref={this._dref} style={{ display: "inline-block", height: this.props.panelHeight() }} key={this.props.document[Id]}>
+                let layoutDoc = Doc.expandTemplateLayout(this.props.document, this.props.dataDoc);
+                contentElement = <div ref={this._dref} style={{ display: "inline-block", height: layoutDoc[HeightSym]() }} key={this.props.document[Id]}>
                     <CollectionSchemaPreview
-                        Document={this.props.document}
+                        Document={layoutDoc}
                         DataDocument={this.resolvedDataDoc}
                         renderDepth={this.props.renderDepth}
                         width={docWidth}
-                        height={this.props.panelHeight}
+                        height={layoutDoc[HeightSym]}
                         getTransform={this.docTransform}
                         CollectionView={undefined}
                         addDocument={emptyFunction as any}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 128525a48..bbec33ba3 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -335,16 +335,12 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         return 1;
     }
 
-    getDocumentViewProps(layoutDoc: Doc): DocumentViewProps {
-        let datadoc = BoolCast(this.props.Document.isTemplate) || this.props.DataDoc === this.props.Document ? undefined : this.props.DataDoc;
-        if (Cast(layoutDoc.layout, Doc) instanceof Doc) { // if this document is using a template to render, then set the dataDoc for the template to be this document
-            datadoc = layoutDoc;
-        } else if (datadoc && datadoc !== layoutDoc) {  // if this view has a dataDocument and it's not the same as the view document
-            // then map the view document to an instance of itself (ie, expand the template).  This allows the view override the template's properties and be referenceable as  document.
-            layoutDoc = Doc.expandTemplateLayout(layoutDoc, datadoc);
-        }
+
+    getChildDocumentViewProps(childDocLayout: Doc): DocumentViewProps {
+        let resolvedDataDoc = this.props.DataDoc !== this.props.Document ? this.props.DataDoc : undefined;
+        let layoutDoc = Doc.expandTemplateLayout(childDocLayout, resolvedDataDoc);
         return {
-            DataDoc: datadoc,
+            DataDoc: resolvedDataDoc !== layoutDoc && resolvedDataDoc ? resolvedDataDoc : layoutDoc,
             Document: layoutDoc,
             addDocument: this.props.addDocument,
             removeDocument: this.props.removeDocument,
@@ -365,6 +361,29 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             getScale: this.getScale
         };
     }
+    getDocumentViewProps(layoutDoc: Doc): DocumentViewProps {
+        return {
+            DataDoc: this.props.DataDoc,
+            Document: this.props.Document,
+            addDocument: this.props.addDocument,
+            removeDocument: this.props.removeDocument,
+            moveDocument: this.props.moveDocument,
+            ScreenToLocalTransform: this.getTransform,
+            renderDepth: this.props.renderDepth + 1,
+            selectOnLoad: layoutDoc[Id] === this._selectOnLoaded,
+            PanelWidth: layoutDoc[WidthSym],
+            PanelHeight: layoutDoc[HeightSym],
+            ContentScaling: returnOne,
+            ContainingCollectionView: this.props.CollectionView,
+            focus: this.focusDocument,
+            parentActive: this.props.active,
+            whenActiveChanged: this.props.whenActiveChanged,
+            bringToFront: this.bringToFront,
+            addDocTab: this.props.addDocTab,
+            zoomToScale: this.zoomToScale,
+            getScale: this.getScale
+        };
+    }
 
     @computed.struct
     get views() {
@@ -375,7 +394,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             if (Math.round(page) === Math.round(curPage) || page === -1) {
                 let minim = BoolCast(doc.isMinimized, false);
                 if (minim === undefined || !minim) {
-                    prev.push(<CollectionFreeFormDocumentView key={doc[Id]} {...this.getDocumentViewProps(doc)} />);
+                    prev.push(<CollectionFreeFormDocumentView key={doc[Id]} {...this.getChildDocumentViewProps(doc)} />);
                 }
             }
             return prev;
@@ -419,7 +438,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     }
 
     private childViews = () => [
-        <CollectionFreeFormBackgroundView key="backgroundView" {...this.props} {...this.getDocumentViewProps(this.props.Document)} DataDoc={this.props.DataDoc} />,
+        <CollectionFreeFormBackgroundView key="backgroundView" {...this.props} {...this.getDocumentViewProps(this.props.Document)} />,
         ...this.views
     ]
     render() {
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 2a45aeb43..ba6808737 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -211,7 +211,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
                 const field = this.dataDoc ? Cast(this.dataDoc[this.props.fieldKey], RichTextField) : undefined;
                 return field ? field.Data : `{"doc":{"type":"doc","content":[]},"selection":{"type":"text","anchor":0,"head":0}}`;
             },
-            field => this._editorView && !this._applyingChange &&
+            field => this._editorView && !this._applyingChange && this.props.Document[this.props.fieldKey] instanceof RichTextField &&
                 this._editorView.updateState(EditorState.fromJSON(config, JSON.parse(field)))
         );
         this.setupEditor(config, this.dataDoc, this.props.fieldKey);
@@ -247,6 +247,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
         if (this.props.selectOnLoad) {
             if (!this.props.isOverlay) this.props.select(false);
             else this._editorView!.focus();
+            this.tryUpdateHeight();
         }
     }
 
@@ -382,6 +383,11 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
         if (!this._undoTyping) {
             this._undoTyping = UndoManager.StartBatch("undoTyping");
         }
+        this.tryUpdateHeight();
+    }
+
+    @action
+    tryUpdateHeight() {
         if (this.props.isOverlay && this.props.Document.autoHeight) {
             let xf = this._ref.current!.getBoundingClientRect();
             let scrBounds = this.props.ScreenToLocalTransform().transformBounds(0, 0, xf.width, xf.height);
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 378b13b0d..06bf65f73 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -205,7 +205,7 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
         requestImageSize(window.origin + RouteStore.corsProxy + "/" + srcpath)
             .then((size: any) => {
                 let aspect = size.height / size.width;
-                if (layoutdoc[HeightSym]() / layoutdoc[WidthSym]() != aspect) {
+                if (Math.abs(layoutdoc[HeightSym]() / layoutdoc[WidthSym]() - aspect) > 0.01) {
                     setTimeout(action(() => {
                         layoutdoc.height = layoutdoc[WidthSym]() * aspect;
                         layoutdoc.nativeHeight = size.height;
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index d552ddd2d..27dcfba08 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -280,7 +280,15 @@ export namespace Doc {
         return new Doc;
     }
 
-    export function expandTemplateLayout(templateLayoutDoc: Doc, dataDoc: Doc) {
+    export function expandTemplateLayout(templateLayoutDoc: Doc, dataDoc?: Doc) {
+        let resolvedDataDoc = (templateLayoutDoc !== dataDoc) ? dataDoc : undefined;
+        if (!dataDoc || !(templateLayoutDoc && !(Cast(templateLayoutDoc.layout, Doc) instanceof Doc) && resolvedDataDoc && resolvedDataDoc !== templateLayoutDoc)) {
+            return templateLayoutDoc;
+        }
+        // if we have a data doc that doesn't match the layout, then we're rendering a template.
+        // ... which means we change the layout to be an expanded view of the template layout.  
+        // This allows the view override the template's properties and be referenceable as its own document.
+
         let expandedTemplateLayout = templateLayoutDoc["_expanded_" + dataDoc[Id]];
         if (expandedTemplateLayout instanceof Doc) {
             return expandedTemplateLayout;
-- 
cgit v1.2.3-70-g09d2


From 6b9131637c242dafba429460f5d1bf2aa31e136f Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Fri, 28 Jun 2019 21:49:48 -0400
Subject: fixed a bunch of things related to issues with templates.

---
 src/client/views/MainOverlayTextBox.tsx                     |  2 +-
 src/client/views/collections/CollectionDockingView.tsx      | 13 +++++++------
 src/client/views/collections/CollectionSchemaView.tsx       |  2 +-
 src/client/views/collections/CollectionTreeView.tsx         |  6 +++---
 src/client/views/collections/CollectionView.tsx             |  2 +-
 src/client/views/collections/ParentDocumentSelector.tsx     |  4 ++--
 .../collectionFreeForm/CollectionFreeFormView.tsx           |  2 +-
 src/client/views/nodes/DocumentView.tsx                     |  8 ++++----
 src/client/views/nodes/FieldView.tsx                        |  2 +-
 src/client/views/nodes/FormattedTextBox.tsx                 |  2 +-
 10 files changed, 22 insertions(+), 21 deletions(-)

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

diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx
index 1933ab94b..d31319429 100644
--- a/src/client/views/MainOverlayTextBox.tsx
+++ b/src/client/views/MainOverlayTextBox.tsx
@@ -108,7 +108,7 @@ export class MainOverlayTextBox extends React.Component<MainOverlayTextBoxProps>
         document.removeEventListener('pointerup', this.textBoxUp);
     }
 
-    addDocTab = (doc: Doc, dataDoc: Doc, location: string) => {
+    addDocTab = (doc: Doc, dataDoc: Doc | undefined, location: string) => {
         if (true) { // location === "onRight") { need to figure out stack to add "inTab"
             CollectionDockingView.Instance.AddRightSplit(doc, dataDoc);
         }
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index e675e82fc..938674c48 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -66,7 +66,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
         this.hack = true;
         this.undohack = UndoManager.StartBatch("goldenDrag");
         dragDocs.map((dragDoc, i) =>
-            this.AddRightSplit(dragDoc, dragDataDocs ? dragDataDocs[i] : dragDoc, true).contentItems[0].tab._dragListener.
+            this.AddRightSplit(dragDoc, dragDataDocs ? dragDataDocs[i] : undefined, true).contentItems[0].tab._dragListener.
                 onMouseDown({ pageX: e.pageX, pageY: e.pageY, preventDefault: emptyFunction, button: 0 }));
     }
 
@@ -167,7 +167,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
         return newContentItem;
     }
     @action
-    public AddTab = (stack: any, document: Doc, dataDocument: Doc) => {
+    public AddTab = (stack: any, document: Doc, dataDocument: Doc | undefined) => {
         let docs = Cast(this.props.Document.data, listSpec(Doc));
         if (docs) {
             docs.push(document);
@@ -469,7 +469,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
     constructor(props: any) {
         super(props);
         DocServer.GetRefField(this.props.documentId).then(action((f: Opt<Field>) => {
-            this._dataDoc = this._document = f as Doc;
+            this._document = f as Doc;
             if (this.props.dataDocumentId && this.props.documentId !== this.props.dataDocumentId) {
                 DocServer.GetRefField(this.props.dataDocumentId).then(action((f: Opt<Field>) => this._dataDoc = f as Doc));
             }
@@ -510,7 +510,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
     }
     get previewPanelCenteringOffset() { return (this._panelWidth - this.nativeWidth() * this.contentScaling()) / 2; }
 
-    addDocTab = (doc: Doc, dataDoc: Doc, location: string) => {
+    addDocTab = (doc: Doc, dataDoc: Doc | undefined, location: string) => {
         if (doc.dockingConfig) {
             MainView.Instance.openWorkspace(doc);
         } else if (location === "onRight") {
@@ -520,15 +520,16 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
         }
     }
     get content() {
-        if (!this._document || !this._dataDoc) {
+        if (!this._document) {
             return (null);
         }
+        let resolvedDataDoc = this._document.layout instanceof Doc ? this._document : this._dataDoc;
         return (
             <div className="collectionDockingView-content" ref={this._mainCont}
                 style={{ transform: `translate(${this.previewPanelCenteringOffset}px, 0px) scale(${this.scaleToFitMultiplier})` }}>
                 <DocumentView key={this._document[Id]}
                     Document={this._document}
-                    DataDoc={this._dataDoc}
+                    DataDoc={resolvedDataDoc}
                     bringToFront={emptyFunction}
                     addDocument={undefined}
                     removeDocument={undefined}
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 5562676e9..6529074f8 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -414,7 +414,7 @@ interface CollectionSchemaPreviewProps {
     removeDocument: (document: Doc) => boolean;
     active: () => boolean;
     whenActiveChanged: (isActive: boolean) => void;
-    addDocTab: (document: Doc, dataDoc: Doc, where: string) => void;
+    addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => void;
     setPreviewScript: (script: string) => void;
     previewScript?: string;
 }
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 9e0130281..dd165e90c 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -36,7 +36,7 @@ export interface TreeViewProps {
     deleteDoc: (doc: Doc) => boolean;
     moveDocument: DragManager.MoveFunction;
     dropAction: "alias" | "copy" | undefined;
-    addDocTab: (doc: Doc, dataDoc: Doc, where: string) => void;
+    addDocTab: (doc: Doc, dataDoc: Doc | undefined, where: string) => void;
     panelWidth: () => number;
     panelHeight: () => number;
     addDocument: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean;
@@ -97,7 +97,7 @@ class TreeView extends React.Component<TreeViewProps> {
     }
 
     @undoBatch delete = () => this.props.deleteDoc(this.resolvedDataDoc);
-    @undoBatch openRight = async () => this.props.addDocTab(this.props.document, this.props.document, "onRight");
+    @undoBatch openRight = async () => this.props.addDocTab(this.props.document, undefined, "onRight");
 
     onPointerDown = (e: React.PointerEvent) => e.stopPropagation();
     onPointerEnter = (e: React.PointerEvent): void => {
@@ -369,7 +369,7 @@ class TreeView extends React.Component<TreeViewProps> {
         remove: ((doc: Doc) => boolean),
         move: DragManager.MoveFunction,
         dropAction: dropActionType,
-        addDocTab: (doc: Doc, dataDoc: Doc, where: string) => void,
+        addDocTab: (doc: Doc, dataDoc: Doc | undefined, where: string) => void,
         screenToLocalXf: () => Transform,
         outerXf: () => { translateX: number, translateY: number },
         active: () => boolean,
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 0517c17bf..e500e5c70 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -63,7 +63,7 @@ export class CollectionView extends React.Component<FieldViewProps> {
                     otherdoc.height = 50;
                     Doc.GetProto(otherdoc).title = "applied(" + this.props.Document.title + ")";
                     Doc.GetProto(otherdoc).layout = Doc.MakeDelegate(this.props.Document);
-                    this.props.addDocTab && this.props.addDocTab(otherdoc, otherdoc, "onRight");
+                    this.props.addDocTab && this.props.addDocTab(otherdoc, undefined, "onRight");
                 }), icon: "project-diagram"
             });
         }
diff --git a/src/client/views/collections/ParentDocumentSelector.tsx b/src/client/views/collections/ParentDocumentSelector.tsx
index fa7058d5a..b29a30069 100644
--- a/src/client/views/collections/ParentDocumentSelector.tsx
+++ b/src/client/views/collections/ParentDocumentSelector.tsx
@@ -9,7 +9,7 @@ import { CollectionDockingView } from "./CollectionDockingView";
 import { NumCast } from "../../../new_fields/Types";
 import { CollectionViewType } from "./CollectionBaseView";
 
-type SelectorProps = { Document: Doc, addDocTab(doc: Doc, dataDoc: Doc, location: string): void };
+type SelectorProps = { Document: Doc, addDocTab(doc: Doc, dataDoc: Doc | undefined, location: string): void };
 @observer
 export class SelectorContextMenu extends React.Component<SelectorProps> {
     @observable private _docs: { col: Doc, target: Doc }[] = [];
@@ -43,7 +43,7 @@ export class SelectorContextMenu extends React.Component<SelectorProps> {
                 col.panX = newPanX;
                 col.panY = newPanY;
             }
-            this.props.addDocTab(col, col, "inTab"); // bcz: dataDoc?
+            this.props.addDocTab(col, undefined, "inTab"); // bcz: dataDoc?
         };
     }
 
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index bbec33ba3..4c8fe3c26 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -340,7 +340,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         let resolvedDataDoc = this.props.DataDoc !== this.props.Document ? this.props.DataDoc : undefined;
         let layoutDoc = Doc.expandTemplateLayout(childDocLayout, resolvedDataDoc);
         return {
-            DataDoc: resolvedDataDoc !== layoutDoc && resolvedDataDoc ? resolvedDataDoc : layoutDoc,
+            DataDoc: resolvedDataDoc !== layoutDoc && resolvedDataDoc ? resolvedDataDoc : undefined,
             Document: layoutDoc,
             addDocument: this.props.addDocument,
             removeDocument: this.props.removeDocument,
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 2ee694225..ada28d57b 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -84,7 +84,7 @@ export interface DocumentViewProps {
     parentActive: () => boolean;
     whenActiveChanged: (isActive: boolean) => void;
     bringToFront: (doc: Doc) => void;
-    addDocTab: (doc: Doc, dataDoc: Doc, where: string) => void;
+    addDocTab: (doc: Doc, dataDoc: Doc | undefined, where: string) => void;
     collapseToPoint?: (scrpt: number[], expandedDocs: Doc[] | undefined) => void;
     zoomToScale: (scale: number) => void;
     getScale: () => number;
@@ -254,7 +254,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 DocumentView._undoBatch = UndoManager.StartBatch("iconAnimating");
             }
             let isMinimized: boolean | undefined;
-            expandedDocs.map(d => Doc.GetProto(d)).map(maximizedDoc => {
+            expandedDocs.map(maximizedDoc => {
                 let iconAnimating = Cast(maximizedDoc.isIconAnimating, List);
                 if (!iconAnimating || (Date.now() - iconAnimating[2] > 1000)) {
                     if (isMinimized === undefined) {
@@ -321,7 +321,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                         if (dataDocs) {
                             expandedDocs.forEach(maxDoc =>
                                 (!CollectionDockingView.Instance.CloseRightSplit(Doc.GetProto(maxDoc)) &&
-                                    this.props.addDocTab(getDispDoc(maxDoc), getDispDoc(maxDoc), maxLocation)));
+                                    this.props.addDocTab(getDispDoc(maxDoc), undefined, maxLocation)));
                         }
                     } else {
                         let scrpt = this.props.ScreenToLocalTransform().scale(this.props.ContentScaling()).inverse().transformPoint(NumCast(this.Document.width) / 2, NumCast(this.Document.height) / 2);
@@ -351,7 +351,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                     //     if (!linkedFwdDocs.some(l => l instanceof Promise)) {
                     //         let maxLocation = StrCast(linkedFwdDocs[altKey ? 1 : 0].maximizeLocation, "inTab");
                     //         let targetContext = !Doc.AreProtosEqual(linkedFwdContextDocs[altKey ? 1 : 0], this.props.ContainingCollectionView && this.props.ContainingCollectionView.props.Document) ? linkedFwdContextDocs[altKey ? 1 : 0] : undefined;
-                    //         DocumentManager.Instance.jumpToDocument(linkedFwdDocs[altKey ? 1 : 0], ctrlKey, false, document => this.props.addDocTab(document, document, maxLocation), linkedFwdPage[altKey ? 1 : 0], targetContext);
+                    //         DocumentManager.Instance.jumpToDocument(linkedFwdDocs[altKey ? 1 : 0], ctrlKey, false, document => this.props.addDocTab(document, undefined, maxLocation), linkedFwdPage[altKey ? 1 : 0], targetContext);
                     //     }
                 }
             }
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 7c8509722..89a8cad56 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -39,7 +39,7 @@ export interface FieldViewProps {
     renderDepth: number;
     selectOnLoad: boolean;
     addDocument?: (document: Doc, allowDuplicates?: boolean) => boolean;
-    addDocTab: (document: Doc, dataDoc: Doc, where: string) => void;
+    addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => void;
     removeDocument?: (document: Doc) => boolean;
     moveDocument?: (document: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean;
     ScreenToLocalTransform: () => Transform;
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index ba6808737..07cd43ce3 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -281,7 +281,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
                     this._linkClicked = href.replace(DocServer.prepend("/doc/"), "").split("?")[0];
                     if (this._linkClicked) {
                         DocServer.GetRefField(this._linkClicked).then(f => {
-                            (f instanceof Doc) && DocumentManager.Instance.jumpToDocument(f, ctrlKey, false, document => this.props.addDocTab(document, document, "inTab"));
+                            (f instanceof Doc) && DocumentManager.Instance.jumpToDocument(f, ctrlKey, false, document => this.props.addDocTab(document, undefined, "inTab"));
                         });
                         e.stopPropagation();
                         e.preventDefault();
-- 
cgit v1.2.3-70-g09d2


From 70c7532c8a6472f61eedd4661a172d70bc50184e Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sun, 30 Jun 2019 01:48:47 -0400
Subject: added drag off of context search results. add fit to contents for
 preview of collections in search.

---
 src/client/util/DragManager.ts                     | 28 +++++---
 .../views/collections/CollectionSchemaView.tsx     |  4 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  7 +-
 src/client/views/globalCssVariables.scss           |  2 +
 src/client/views/globalCssVariables.scss.d.ts      |  1 +
 src/client/views/nodes/DocumentView.tsx            |  1 +
 src/client/views/nodes/FieldView.tsx               |  1 +
 src/client/views/search/FilterBox.tsx              |  4 +-
 src/client/views/search/SearchBox.tsx              |  1 -
 src/client/views/search/SearchItem.scss            |  8 ++-
 src/client/views/search/SearchItem.tsx             | 83 ++++++++++++++--------
 11 files changed, 90 insertions(+), 50 deletions(-)

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

diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index a6bba3656..7dc48fb78 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -1,18 +1,24 @@
-import { action, runInAction, observable } from "mobx";
-import { Doc, DocListCastAsync } from "../../new_fields/Doc";
-import { Cast, StrCast } from "../../new_fields/Types";
+import { action, runInAction } from "mobx";
+import { Doc } from "../../new_fields/Doc";
+import { Cast } from "../../new_fields/Types";
+import { URLField } from "../../new_fields/URLField";
 import { emptyFunction } from "../../Utils";
 import { CollectionDockingView } from "../views/collections/CollectionDockingView";
 import * as globalCssVariables from "../views/globalCssVariables.scss";
+import { DocumentManager } from "./DocumentManager";
 import { LinkManager } from "./LinkManager";
-import { URLField } from "../../new_fields/URLField";
 import { SelectionManager } from "./SelectionManager";
-import { Docs, DocUtils } from "../documents/Documents";
-import { DocumentManager } from "./DocumentManager";
-import { Id } from "../../new_fields/FieldSymbols";
 
 export type dropActionType = "alias" | "copy" | undefined;
-export function SetupDrag(_reference: React.RefObject<HTMLElement>, docFunc: () => Doc | Promise<Doc>, moveFunc?: DragManager.MoveFunction, dropAction?: dropActionType, options?: any, dontHideOnDrop?: boolean) {
+export function SetupDrag(
+    _reference: React.RefObject<HTMLElement>,
+    docFunc: () => Doc | Promise<Doc>,
+    moveFunc?: DragManager.MoveFunction,
+    dropAction?: dropActionType,
+    options?: any,
+    dontHideOnDrop?: boolean,
+    dragStarted?: () => void
+) {
     let onRowMove = async (e: PointerEvent) => {
         e.stopPropagation();
         e.preventDefault();
@@ -20,12 +26,13 @@ export function SetupDrag(_reference: React.RefObject<HTMLElement>, docFunc: ()
         document.removeEventListener("pointermove", onRowMove);
         document.removeEventListener('pointerup', onRowUp);
         let doc = await docFunc();
-        var dragData = new DragManager.DocumentDragData([doc], [doc]);
+        var dragData = new DragManager.DocumentDragData([doc], [undefined]);
         dragData.dropAction = dropAction;
         dragData.moveDocument = moveFunc;
         dragData.options = options;
         dragData.dontHideOnDrop = dontHideOnDrop;
         DragManager.StartDocumentDrag([_reference.current!], dragData, e.x, e.y);
+        dragStarted && dragStarted();
     };
     let onRowUp = (): void => {
         document.removeEventListener("pointermove", onRowMove);
@@ -34,6 +41,7 @@ export function SetupDrag(_reference: React.RefObject<HTMLElement>, docFunc: ()
     let onItemDown = async (e: React.PointerEvent) => {
         if (e.button === 0) {
             e.stopPropagation();
+            e.preventDefault();
             if (e.shiftKey && CollectionDockingView.Instance) {
                 CollectionDockingView.Instance.StartOtherDrag(e, [await docFunc()]);
             } else {
@@ -111,6 +119,8 @@ export namespace DragManager {
 
         hideSource: boolean | (() => boolean);
 
+        dragHasStarted?: () => void;
+
         withoutShiftDrag?: boolean;
     }
 
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 6529074f8..b0d46953c 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -119,8 +119,8 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
         let fieldContentView = <FieldView {...props} />;
         let reference = React.createRef<HTMLDivElement>();
         let onItemDown = (e: React.PointerEvent) => {
-            (this.props.CollectionView.props.isSelected() ?
-                SetupDrag(reference, () => props.Document, this.props.moveDocument, this.props.Document.schemaDoc ? "copy" : undefined)(e) : undefined);
+            (!this.props.CollectionView.props.isSelected() ? undefined :
+                SetupDrag(reference, () => props.Document, this.props.moveDocument, this.props.Document.schemaDoc ? "copy" : undefined)(e));
         };
         let applyToDoc = (doc: Doc, run: (args?: { [name: string]: any }) => any) => {
             const res = run({ this: doc });
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 4c8fe3c26..b1aba10bf 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -50,9 +50,9 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     @computed get nativeHeight() { return this.Document.nativeHeight || 0; }
     public get isAnnotationOverlay() { return this.props.fieldKey === "annotations" || this.props.fieldExt === "annotations"; }
     private get borderWidth() { return this.isAnnotationOverlay ? 0 : COLLECTION_BORDER_WIDTH; }
-    private panX = () => this.Document.panX || 0;
-    private panY = () => this.Document.panY || 0;
-    private zoomScaling = () => this.Document.scale || 1;
+    private panX = () => this.props.fitToBox ? this.props.fitToBox[0] : this.Document.panX || 0;
+    private panY = () => this.props.fitToBox ? this.props.fitToBox[1] : this.Document.panY || 0;
+    private zoomScaling = () => this.props.fitToBox ? this.props.fitToBox[2] : this.Document.scale || 1;
     private centeringShiftX = () => !this.nativeWidth ? this._pwidth / 2 : 0;  // shift so pan position is at center of window for non-overlay collections
     private centeringShiftY = () => !this.nativeHeight ? this._pheight / 2 : 0;// shift so pan position is at center of window for non-overlay collections
     private getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.borderWidth + 1, -this.borderWidth + 1).translate(-this.centeringShiftX(), -this.centeringShiftY()).transform(this.getLocalTransform());
@@ -444,6 +444,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     render() {
         const containerName = `collectionfreeformview${this.isAnnotationOverlay ? "-overlay" : "-container"}`;
         const easing = () => this.props.Document.panTransformType === "Ease";
+
         if (this.props.fieldExt) Doc.UpdateDocumentExtensionForField(this.extensionDoc, this.props.fieldKey);
         return (
             <div className={containerName} ref={this.createDropTarget} onWheel={this.onPointerWheel}
diff --git a/src/client/views/globalCssVariables.scss b/src/client/views/globalCssVariables.scss
index cfbf4aab8..fec105516 100644
--- a/src/client/views/globalCssVariables.scss
+++ b/src/client/views/globalCssVariables.scss
@@ -19,6 +19,7 @@ $serif: "Crimson Text", serif;
 // misc values
 $border-radius: 0.3em;
 //
+$search-thumnail-size: 175;
 
                             // dragged items
 $contextMenu-zindex: 1000;  // context menu shows up over everything
@@ -33,4 +34,5 @@ $MAX_ROW_HEIGHT: 44px;
     COLLECTION_BORDER_WIDTH: $COLLECTION_BORDER_WIDTH;
     MINIMIZED_ICON_SIZE: $MINIMIZED_ICON_SIZE;
     MAX_ROW_HEIGHT: $MAX_ROW_HEIGHT;
+    SEARCH_THUMBNAIL_SIZE: $search-thumnail-size;
 }
\ No newline at end of file
diff --git a/src/client/views/globalCssVariables.scss.d.ts b/src/client/views/globalCssVariables.scss.d.ts
index 9788d31f7..d95cec9d8 100644
--- a/src/client/views/globalCssVariables.scss.d.ts
+++ b/src/client/views/globalCssVariables.scss.d.ts
@@ -4,6 +4,7 @@ interface IGlobalScss {
     COLLECTION_BORDER_WIDTH: string;
     MINIMIZED_ICON_SIZE: string;
     MAX_ROW_HEIGHT: string;
+    SEARCH_THUMBNAIL_SIZE: string;
 }
 declare const globalCssVariables: IGlobalScss;
 
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 1d03fa04d..9edde896f 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -71,6 +71,7 @@ export interface DocumentViewProps {
     ContainingCollectionView: Opt<CollectionView | CollectionPDFView | CollectionVideoView>;
     Document: Doc;
     DataDoc?: Doc;
+    fitToBox?: number[];
     addDocument?: (doc: Doc, allowDuplicates?: boolean) => boolean;
     removeDocument?: (doc: Doc) => boolean;
     moveDocument?: (doc: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean;
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 89a8cad56..3f5a2e744 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -31,6 +31,7 @@ export interface FieldViewProps {
     fieldKey: string;
     fieldExt: string;
     leaveNativeSize?: boolean;
+    fitToBox?: number[];
     ContainingCollectionView: Opt<CollectionView | CollectionPDFView | CollectionVideoView>;
     Document: Doc;
     DataDoc?: Doc;
diff --git a/src/client/views/search/FilterBox.tsx b/src/client/views/search/FilterBox.tsx
index cc1feeaf7..c39ec1145 100644
--- a/src/client/views/search/FilterBox.tsx
+++ b/src/client/views/search/FilterBox.tsx
@@ -3,7 +3,7 @@ import { observer } from 'mobx-react';
 import { observable, action } from 'mobx';
 import "./SearchBox.scss";
 import { faTimes } from '@fortawesome/free-solid-svg-icons';
-import { library} from '@fortawesome/fontawesome-svg-core';
+import { library } from '@fortawesome/fontawesome-svg-core';
 import { Doc } from '../../../new_fields/Doc';
 import { Id } from '../../../new_fields/FieldSymbols';
 import { DocTypes } from '../../documents/Documents';
@@ -57,7 +57,7 @@ export class FilterBox extends React.Component {
 
     componentDidMount = () => {
         document.addEventListener("pointerdown", (e) => {
-            if (e.timeStamp !== this._pointerTime) {
+            if (!e.defaultPrevented && e.timeStamp !== this._pointerTime) {
                 SearchBox.Instance.closeSearch();
             }
         });
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index f53a4e34f..a2556133b 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -15,7 +15,6 @@ import { Id } from '../../../new_fields/FieldSymbols';
 import { SearchUtil } from '../../util/SearchUtil';
 import { RouteStore } from '../../../server/RouteStore';
 import { FilterBox } from './FilterBox';
-import { Pager } from './Pager';
 
 @observer
 export class SearchBox extends React.Component {
diff --git a/src/client/views/search/SearchItem.scss b/src/client/views/search/SearchItem.scss
index b3472ddec..fa4c9cb38 100644
--- a/src/client/views/search/SearchItem.scss
+++ b/src/client/views/search/SearchItem.scss
@@ -122,7 +122,6 @@
 
                     .search-label {
                         font-size: 10;
-                        padding: 5px;
                         position: relative;
                         right: 0px;
                         text-transform: capitalize;
@@ -174,10 +173,15 @@
         -webkit-transform: scale(0);
         -ms-transform: scale(0);
         transform: scale(0);
-        // height: 100%
     }
 
 }
 .search-overview:hover {
     z-index: 1;
+}
+.collection {
+    display:flex;
+}
+.collection-item {
+    width:35px;
 }
\ No newline at end of file
diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx
index d992d0fd1..b72f8c814 100644
--- a/src/client/views/search/SearchItem.tsx
+++ b/src/client/views/search/SearchItem.tsx
@@ -1,29 +1,26 @@
 import React = require("react");
 import { library } from '@fortawesome/fontawesome-svg-core';
-import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faMusic, faLink, faChartBar, faGlobeAsia } from '@fortawesome/free-solid-svg-icons';
+import { faCaretUp, faChartBar, faFilePdf, faFilm, faGlobeAsia, faImage, faLink, faMusic, faObjectGroup, faStickyNote } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { action, computed, observable, runInAction } from "mobx";
+import { observer } from "mobx-react";
+import { Doc, DocListCast, HeightSym, WidthSym } from "../../../new_fields/Doc";
+import { Id } from "../../../new_fields/FieldSymbols";
 import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
-import { observable, runInAction, computed, action } from "mobx";
-import { listSpec } from "../../../new_fields/Schema";
-import { Doc, WidthSym } from "../../../new_fields/Doc";
+import { emptyFunction, returnFalse, returnOne } from "../../../Utils";
+import { DocTypes } from "../../documents/Documents";
 import { DocumentManager } from "../../util/DocumentManager";
 import { SetupDrag } from "../../util/DragManager";
+import { LinkManager } from "../../util/LinkManager";
 import { SearchUtil } from "../../util/SearchUtil";
-import { Id } from "../../../new_fields/FieldSymbols";
-import { CollectionDockingView } from "../collections/CollectionDockingView";
-import { observer } from "mobx-react";
-import "./SearchItem.scss";
+import { Transform } from "../../util/Transform";
+import { SEARCH_THUMBNAIL_SIZE } from "../../views/globalCssVariables.scss";
 import { CollectionViewType } from "../collections/CollectionBaseView";
-import { DocTypes } from "../../documents/Documents";
-import { FilterBox } from "./FilterBox";
+import { CollectionDockingView } from "../collections/CollectionDockingView";
 import { DocumentView } from "../nodes/DocumentView";
-import "./SelectorContextMenu.scss";
 import { SearchBox } from "./SearchBox";
-import { LinkManager } from "../../util/LinkManager";
-import { DocumentContentsView } from "../nodes/DocumentContentsView";
-import { ImageBox } from "../nodes/ImageBox";
-import { emptyFunction, returnFalse, returnOne } from "../../../Utils";
-import { Transform } from "../../util/Transform";
+import "./SearchItem.scss";
+import "./SelectorContextMenu.scss";
 
 export interface SearchItemProps {
     doc: Doc;
@@ -74,13 +71,21 @@ export class SelectorContextMenu extends React.Component<SearchItemProps> {
             CollectionDockingView.Instance.AddRightSplit(col, undefined);
         };
     }
-
     render() {
         return (
-            < div className="parents">
+            <div className="parents">
                 <p className="contexts">Contexts:</p>
-                {this._docs.map(doc => <div className="collection"><a className="title" onClick={this.getOnClick(doc)}>{doc.col.title}</a></div>)}
-                {this._otherDocs.map(doc => <div className="collection"><a className="title" onClick={this.getOnClick(doc)}>{doc.col.title}</a></div>)}
+                {[...this._docs, ...this._otherDocs].map(doc => {
+                    let item = React.createRef<HTMLDivElement>();
+                    return <div className="collection" key={doc.col[Id] + doc.target[Id]} ref={item}>
+                        <div className="collection-item" onPointerDown={
+                            SetupDrag(item, () => doc.col, undefined, undefined, undefined, undefined, () => SearchBox.Instance.closeSearch())}>
+                            <FontAwesomeIcon icon={faStickyNote} />
+                        </div>
+                        <a className="title" onClick={this.getOnClick(doc)}>{doc.col.title}</a>
+                    </div>
+                }
+                )}
             </div>
         );
     }
@@ -101,14 +106,30 @@ export class SearchItem extends React.Component<SearchItemProps> {
     public get DocumentIcon() {
         let layoutresult = StrCast(this.props.doc.type);
         if (!this._useIcons) {
-            let returnXDimension = () => this._useIcons ? 50 : 250;
+            let renderDoc = this.props.doc;
+            let box: number[] = [];
+            if (layoutresult.indexOf(DocTypes.COL) !== -1) {
+                renderDoc = Doc.MakeDelegate(renderDoc);
+                let bounds = DocListCast(renderDoc.data).reduce((bounds, doc) => {
+                    var [sptX, sptY] = [NumCast(doc.x), NumCast(doc.y)]
+                    let [bptX, bptY] = [sptX + doc[WidthSym](), sptY + doc[HeightSym]()];
+                    return {
+                        x: Math.min(sptX, bounds.x), y: Math.min(sptY, bounds.y),
+                        r: Math.max(bptX, bounds.r), b: Math.max(bptY, bounds.b)
+                    };
+                }, { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: Number.MIN_VALUE, b: Number.MIN_VALUE });
+                box = [(bounds.x + bounds.r) / 2, (bounds.y + bounds.b) / 2, Number(SEARCH_THUMBNAIL_SIZE) / (bounds.r - bounds.x), this._displayDim];
+            }
+            let returnXDimension = () => this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE);
             let returnYDimension = () => this._displayDim;
-            let scale = () => returnXDimension() / NumCast(this.props.doc.nativeWidth, returnXDimension());
+            let scale = () => returnXDimension() / NumCast(renderDoc.nativeWidth, returnXDimension());
             return <div
-                onPointerEnter={action(() => this._displayDim = this._useIcons ? 50 : 250)}
-                onPointerLeave={action(() => this._displayDim = this._useIcons ? 50 : 250)} >
+                onPointerDown={action(() => { this._useIcons = !this._useIcons; this._displayDim = this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE) })}
+                onPointerEnter={action(() => this._displayDim = this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE))}
+                onPointerLeave={action(() => this._displayDim = 50)} >
                 <DocumentView
-                    Document={this.props.doc}
+                    fitToBox={box}
+                    Document={renderDoc}
                     addDocument={returnFalse}
                     removeDocument={returnFalse}
                     ScreenToLocalTransform={Transform.Identity}
@@ -139,7 +160,9 @@ export class SearchItem extends React.Component<SearchItemProps> {
                                     layoutresult.indexOf(DocTypes.HIST) !== -1 ? faChartBar :
                                         layoutresult.indexOf(DocTypes.WEB) !== -1 ? faGlobeAsia :
                                             faCaretUp;
-        return <FontAwesomeIcon icon={button} size="2x" />;
+        return <div onPointerDown={action(() => { this._useIcons = false; this._displayDim = Number(SEARCH_THUMBNAIL_SIZE) })} >
+            <FontAwesomeIcon icon={button} size="2x" />
+        </div>;
     }
 
     collectionRef = React.createRef<HTMLDivElement>();
@@ -166,7 +189,7 @@ export class SearchItem extends React.Component<SearchItemProps> {
     }
 
     @action
-    pointerDown = (e: React.PointerEvent) => { this._useIcons = !this._useIcons; SearchBox.Instance.openSearch(e); };
+    pointerDown = (e: React.PointerEvent) => SearchBox.Instance.openSearch(e);
 
     highlightDoc = (e: React.PointerEvent) => {
         if (this.props.doc.type === DocTypes.LINK) {
@@ -205,10 +228,8 @@ export class SearchItem extends React.Component<SearchItemProps> {
     render() {
         return (
             <div className="search-overview" onPointerDown={this.pointerDown}>
-                <div className="search-item" onPointerEnter={this.highlightDoc} onPointerLeave={this.unHighlightDoc} ref={this.collectionRef} id="result" onClick={this.onClick} onPointerDown={() => {
-                    this.pointerDown;
-                    SetupDrag(this.collectionRef, this.startDocDrag);
-                }} >
+                <div className="search-item" onPointerEnter={this.highlightDoc} onPointerLeave={this.unHighlightDoc} ref={this.collectionRef} id="result"
+                    onClick={this.onClick} onPointerDown={this.pointerDown} >
                     <div className="main-search-info">
                         <div className="search-title" id="result" >{this.props.doc.title}</div>
                         <div className="search-info" style={{ width: this._useIcons ? "15%" : "400px" }}>
-- 
cgit v1.2.3-70-g09d2

