From 2500204978e2dd15c439adfc400388b7bb3caa01 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sat, 8 Jun 2019 20:48:10 -0400
Subject: several fixes to templates and a fix for link dragging.

---
 src/client/views/Templates.tsx | 48 +++++++++++++++++++++++++-----------------
 1 file changed, 29 insertions(+), 19 deletions(-)

(limited to 'src/client/views/Templates.tsx')

diff --git a/src/client/views/Templates.tsx b/src/client/views/Templates.tsx
index 0cd367bcb..8943bbcaf 100644
--- a/src/client/views/Templates.tsx
+++ b/src/client/views/Templates.tsx
@@ -47,42 +47,52 @@ export namespace Templates {
             </div>
         </div>` );
 
-    export const TitleOverlay = new Template("TitleOverlay", TemplatePosition.InnerTop,
-        `<div>
+    export const ImageTitle = new Template("Image Title", TemplatePosition.InnerTop,
+        `<div style="height:100%">
             <div style="height:100%; width:100%;position:absolute;">{layout}</div>
             <div style="height:25px; width:100%; position:absolute; top: 0; background-color: rgba(0, 0, 0, .4); color: white; ">
                 <span style="text-align:center;width:100%;font-size:20px;position:absolute;overflow:hidden;white-space:nowrap;text-overflow:ellipsis">{props.Document.title}</span>
             </div>
         </div>` );
 
-    export const Title = new Template("Title", TemplatePosition.InnerTop,
-        `<div>
-            <div style="height:calc(100% - 25px); margin-top: 25px; width:100%;position:absolute;">{layout}</div>
-            <div style="height:25px; width:100%; position:absolute; top: 0; background-color: rgba(0, 0, 0, .4); color: white; ">
+    export const TextTitle = new Template("Text Title", TemplatePosition.InnerTop,
+        `<div style="height:100%">
+            <div style="height:25px; width:100%; background-color: rgba(0, 0, 0, .4); color: white; ">
                 <span style="text-align:center;width:100%;font-size:20px;position:absolute;overflow:hidden;white-space:nowrap;text-overflow:ellipsis">{props.Document.title}</span>
             </div>
+            <div style="display:flex; flex-direction:column; height:calc(100% - 25px);">
+                <div style="height:min-content; width:100%;overflow:auto">{layout}</div>
+            </div>
         </div>` );
 
-    export const Bullet = new Template("Bullet", TemplatePosition.InnerTop,
-        `<div>
-            <div style="height:100%; width:100%;position:absolute;">{layout}</div>
-            <div id="isExpander" style="height:15px; width:15px; margin-left:-16px; pointer-events:all; position:absolute; top: 0; background-color: rgba(0, 0, 0, .4); color: white;">
-                <img  id="isExpander"  src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAZlBMVEX///8AAABmZmb7+/tYWFhgYGBFRUVSUlL4+Pg/Pz9jY2N5eXmcnJyioqKBgYFzc3NtbW1LS0s3NzfW1taWlpaOjo6IiIgvLy9WVlampqZcXFw5OTlvb28mJiYxMTHe3t7l5eUjIyMY8kIZAAAD2UlEQVR4nO2d61biMBRGW1FBEVHxfp15/5ecOVa5lHxtArmck/Xtn1BotjtNoXQtm4YQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEFIrX6UHEA1gsmrneceRjHm7cj28attKFOf/TRyKIliH4vzbZE+xE2zbZYkxRWX5Y9JT/BW0X3G+NtlR3Ahar7jcMtlS3Ba0XXG+Y7JW3BW0XHHZM/lR7AvaVewL/ijuC1pV3Bf8VnQJ2lR0CYriq/Nxg4puwfa1aZ7dz9yUHnEgN26NZ3luWkPFd7fEtHsWVDwpO+YgTgYKCuYn6tAU7TBecaygcGpZEQie7m5luKJPQQFUvCwx5iAuvQoK4KShvSIoOHVtCz7dnOUecxBn7kG/urc2eCz6T9EOcxXDCgpAUetyAwoOCBqrGF5QMKR4mCA8L+pTBIJwkRl95eifJjPHTDYTFQ8vePyrs3BsBfXLzfFHkvKKMY4j1ctNnCmmuGKslfCQT0RZiPdFVmnFmOcy36sDWYn7DU9hxdifRkKuEGQh/pWW0K/QiUlxtUxVxTTXyhQtN6kuI6mpmO5qpxJFIBjl1yMVimmvV4PfrnIq3iYsKICTRj7F9L84gIq38fYwCCj4HnMfRY/FPL8ZFayYo6BQbLlJeZrYpVDFXAUFcMtKWkUgmOhmnwKKOQsK4NaxdIp5CwqZj8X8gv27jNecJ9nZuXtnie/SzjhRQcHkt6Fnq1imoAAUY1csVVDIUrFcQSGDIhC8jriLQZIrli0oXKdVLF1QSFqxfEEBVLyI8NYXCgoKySaqhinakajimxrBRBX1FBQSVNRyDP4SXVGbYHRFfYJN8xhTESwyj5HHHEjEihoLCqDiXfAb3aksKESqCAoqEIxUUW9BAS03E+93mOhcZDYcXVF3QeHBPcI3v4qo4EPiUQcBKr75vHaiv6AAKt6NV0SCqgoKqOKYovpFZgOo+DmsOHkyUlA4ZKKamaIdQPEJK5oqKKCKM7D9zFZBIayiuYICWm5cFWef7o3vs486CP8VdQIEVRcU7sFE7VecgSmqvKDgVxEJqi8ogIof2xVnH2YLCuMT1fAU7RirOPtrXHCsovmCwlDFCgoKWNH4IrMBTdQ/NUzRjiu3CeCq9HAPAVSspaDgX9FkQcG3ollB34qGBf0UTQv6KBoXHFc0LzimWIFg0ywGBBelBxcHXLGKggKqWElBwV2xIkF3xaoEXYqVCe4rVifYV3wpPZwULOouKLzUXVBY1F1QeKm7oLCoXVAqVi7YNM7/F0YIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCG+/ANh4i1CHdc63QAAAABJRU5ErkJggg==" 
-                width="15px" height="15px"/>
+    export const Header = new Template("Header", TemplatePosition.InnerTop,
+        `< div style = "display:flex; flex-direction:column; height:100%;" >
+            <div style="width:100%; background-color: rgba(0, 0, 0, .4); color: white; ">
+                <FormattedTextBox {...props} height={"min-content"} color={"white"} fieldKey={"header"} />
             </div>
-        </div>`
+            <div style="width:100%;height:min-content;overflow:auto;">{layout}</div>
+        </div > ` );
+
+    export const Bullet = new Template("Bullet", TemplatePosition.InnerTop,
+        `< div >
+        <div style="height:100%; width:100%;position:absolute;">{layout}</div>
+        <div id="isExpander" style="height:15px; width:15px; margin-left:-16px; pointer-events:all; position:absolute; top: 0; background-color: rgba(0, 0, 0, .4); color: white;">
+            <img id="isExpander" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAZlBMVEX///8AAABmZmb7+/tYWFhgYGBFRUVSUlL4+Pg/Pz9jY2N5eXmcnJyioqKBgYFzc3NtbW1LS0s3NzfW1taWlpaOjo6IiIgvLy9WVlampqZcXFw5OTlvb28mJiYxMTHe3t7l5eUjIyMY8kIZAAAD2UlEQVR4nO2d61biMBRGW1FBEVHxfp15/5ecOVa5lHxtArmck/Xtn1BotjtNoXQtm4YQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEFIrX6UHEA1gsmrneceRjHm7cj28attKFOf/TRyKIliH4vzbZE+xE2zbZYkxRWX5Y9JT/BW0X3G+NtlR3Ahar7jcMtlS3Ba0XXG+Y7JW3BW0XHHZM/lR7AvaVewL/ijuC1pV3Bf8VnQJ2lR0CYriq/Nxg4puwfa1aZ7dz9yUHnEgN26NZ3luWkPFd7fEtHsWVDwpO+YgTgYKCuYn6tAU7TBecaygcGpZEQie7m5luKJPQQFUvCwx5iAuvQoK4KShvSIoOHVtCz7dnOUecxBn7kG/urc2eCz6T9EOcxXDCgpAUetyAwoOCBqrGF5QMKR4mCA8L+pTBIJwkRl95eifJjPHTDYTFQ8vePyrs3BsBfXLzfFHkvKKMY4j1ctNnCmmuGKslfCQT0RZiPdFVmnFmOcy36sDWYn7DU9hxdifRkKuEGQh/pWW0K/QiUlxtUxVxTTXyhQtN6kuI6mpmO5qpxJFIBjl1yMVimmvV4PfrnIq3iYsKICTRj7F9L84gIq38fYwCCj4HnMfRY/FPL8ZFayYo6BQbLlJeZrYpVDFXAUFcMtKWkUgmOhmnwKKOQsK4NaxdIp5CwqZj8X8gv27jNecJ9nZuXtnie/SzjhRQcHkt6Fnq1imoAAUY1csVVDIUrFcQSGDIhC8jriLQZIrli0oXKdVLF1QSFqxfEEBVLyI8NYXCgoKySaqhinakajimxrBRBX1FBQSVNRyDP4SXVGbYHRFfYJN8xhTESwyj5HHHEjEihoLCqDiXfAb3aksKESqCAoqEIxUUW9BAS03E+93mOhcZDYcXVF3QeHBPcI3v4qo4EPiUQcBKr75vHaiv6AAKt6NV0SCqgoKqOKYovpFZgOo+DmsOHkyUlA4ZKKamaIdQPEJK5oqKKCKM7D9zFZBIayiuYICWm5cFWef7o3vs486CP8VdQIEVRcU7sFE7VecgSmqvKDgVxEJqi8ogIof2xVnH2YLCuMT1fAU7RirOPtrXHCsovmCwlDFCgoKWNH4IrMBTdQ/NUzRjiu3CeCq9HAPAVSspaDgX9FkQcG3ollB34qGBf0UTQv6KBoXHFc0LzimWIFg0ywGBBelBxcHXLGKggKqWElBwV2xIkF3xaoEXYqVCe4rVifYV3wpPZwULOouKLzUXVBY1F1QeKm7oLCoXVAqVi7YNM7/F0YIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCG+/ANh4i1CHdc63QAAAABJRU5ErkJggg=="
+                width="15px" height="15px" />
+        </div>
+        </div > `
     );
 
     export function ImageOverlay(width: number, height: number, field: string = "thumbnail") {
-        return (`<div>
-                <div style="height:100%; width:100%; position:absolute;">{layout}</div>
-                <div style="height:auto; width:${width}px; bottom:0; right:0; background:rgba(0,0,0,0.25); position:absolute;overflow:hidden;">
-                    <ImageBox id="isExpander" {...props} style="width:100%; height=auto;" PanelWidth={${width}} fieldKey={"${field}"} />
+        return (`< div >
+        <div style="height:100%; width:100%; position:absolute;">{layout}</div>
+        <div style="height:auto; width:${width}px; bottom:0; right:0; background:rgba(0,0,0,0.25); position:absolute;overflow:hidden;">
+            <ImageBox id="isExpander" {...props} style="width:100%; height=auto;" PanelWidth={${width}} fieldKey={"${field}"} />
                 </div>
-            </div>`);
+            </div > `);
     }
 
-    export const TemplateList: Template[] = [Title, TitleOverlay, Caption, Bullet];
+    export const TemplateList: Template[] = [TextTitle, Header, ImageTitle, Caption, Bullet];
 
     export function sortTemplates(a: Template, b: Template) {
         if (a.Position < b.Position) { return -1; }
-- 
cgit v1.2.3-70-g09d2


From c56851026c4054cde26ea36a9a24db14fac6c49c Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Mon, 10 Jun 2019 13:03:47 -0400
Subject: fixes for treeview highlighting, templates, field deletion,
 overlaytext box positioning

---
 src/Utils.ts                                       |  2 +-
 src/client/util/DragManager.ts                     |  6 ++++--
 src/client/util/SelectionManager.ts                |  9 +++++---
 src/client/views/MainOverlayTextBox.tsx            |  8 +++++---
 src/client/views/Templates.tsx                     | 16 ++++-----------
 .../views/collections/CollectionTreeView.tsx       | 24 ++++++++++++++--------
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  3 +--
 src/client/views/nodes/DocumentView.tsx            |  6 +++---
 src/new_fields/util.ts                             |  4 ++--
 9 files changed, 42 insertions(+), 36 deletions(-)

(limited to 'src/client/views/Templates.tsx')

diff --git a/src/Utils.ts b/src/Utils.ts
index 611c61135..e8a80bdc3 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -15,7 +15,7 @@ export class Utils {
         return v5(seed, v5.URL);
     }
 
-    public static GetScreenTransform(ele: HTMLElement): { scale: number, translateX: number, translateY: number } {
+    public static GetScreenTransform(ele?: HTMLElement): { scale: number, translateX: number, translateY: number } {
         if (!ele) {
             return { scale: 1, translateX: 1, translateY: 1 };
         }
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 4c9f798a8..8ee1ad2af 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -1,9 +1,10 @@
-import { action, runInAction } from "mobx";
+import { action, runInAction, observable } from "mobx";
 import { Doc, DocListCastAsync } from "../../new_fields/Doc";
 import { Cast } from "../../new_fields/Types";
 import { emptyFunction } from "../../Utils";
 import { CollectionDockingView } from "../views/collections/CollectionDockingView";
 import * as globalCssVariables from "../views/globalCssVariables.scss";
+import { SelectionManager } from "./SelectionManager";
 
 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) {
@@ -194,7 +195,7 @@ export namespace DragManager {
             dragDiv.style.pointerEvents = "none";
             DragManager.Root().appendChild(dragDiv);
         }
-
+        SelectionManager.SetIsDragging(true);
         let scaleXs: number[] = [];
         let scaleYs: number[] = [];
         let xs: number[] = [];
@@ -293,6 +294,7 @@ export namespace DragManager {
         };
 
         let hideDragElements = () => {
+            SelectionManager.SetIsDragging(false);
             dragElements.map(dragElement => dragElement.parentNode === dragDiv && dragDiv.removeChild(dragElement));
             eles.map(ele => (ele.hidden = false));
         };
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 0e22d576c..ddad4b818 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -1,4 +1,4 @@
-import { observable, action } from "mobx";
+import { observable, action, runInAction } from "mobx";
 import { Doc } from "../../new_fields/Doc";
 import { DocumentView } from "../views/nodes/DocumentView";
 import { FormattedTextBox } from "../views/nodes/FormattedTextBox";
@@ -6,8 +6,8 @@ import { NumCast } from "../../new_fields/Types";
 
 export namespace SelectionManager {
     class Manager {
-        @observable
-        SelectedDocuments: Array<DocumentView> = [];
+        @observable IsDragging: boolean = false;
+        @observable SelectedDocuments: Array<DocumentView> = [];
 
         @action
         SelectDoc(doc: DocumentView, ctrlPressed: boolean): void {
@@ -51,6 +51,9 @@ export namespace SelectionManager {
         if (found) manager.SelectDoc(found, false);
     }
 
+    export function SetIsDragging(dragging: boolean) { runInAction(() => manager.IsDragging = dragging); }
+    export function GetIsDragging() { return manager.IsDragging; }
+
     export function SelectedDocuments(): Array<DocumentView> {
         return manager.SelectedDocuments;
     }
diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx
index 6bbd70a25..0eb3e9707 100644
--- a/src/client/views/MainOverlayTextBox.tsx
+++ b/src/client/views/MainOverlayTextBox.tsx
@@ -1,7 +1,7 @@
 import { action, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
-import { emptyFunction, returnTrue, returnZero } from '../../Utils';
+import { emptyFunction, returnTrue, returnZero, Utils } from '../../Utils';
 import { DragManager } from '../util/DragManager';
 import { Transform } from '../util/Transform';
 import "normalize.css";
@@ -29,7 +29,8 @@ export class MainOverlayTextBox extends React.Component<MainOverlayTextBoxProps>
         MainOverlayTextBox.Instance = this;
         reaction(() => FormattedTextBox.InputBoxOverlay,
             (box?: FormattedTextBox) => {
-                if (box) this.setTextDoc(box.props.fieldKey, box.CurrentDiv, box.props.ScreenToLocalTransform);
+                let sxf = Utils.GetScreenTransform(box ? box.CurrentDiv : undefined);
+                if (box) this.setTextDoc(box.props.fieldKey, box.CurrentDiv, () => new Transform(-sxf.translateX, -sxf.translateY, 1 / sxf.scale));
                 else this.setTextDoc();
             });
     }
@@ -93,9 +94,10 @@ export class MainOverlayTextBox extends React.Component<MainOverlayTextBoxProps>
         if (FormattedTextBox.InputBoxOverlay && this._textTargetDiv) {
             let textRect = this._textTargetDiv.getBoundingClientRect();
             let s = this._textXf().Scale;
+            let auto = FormattedTextBox.InputBoxOverlay.props.height;
             return <div className="mainOverlayTextBox-textInput" style={{ transform: `translate(${textRect.left}px, ${textRect.top}px) scale(${1 / s},${1 / s})`, width: "auto", height: "auto" }} >
                 <div className="mainOverlayTextBox-textInput" onPointerDown={this.textBoxDown} ref={this._textProxyDiv} onScroll={this.textScroll}
-                    style={{ width: `${textRect.width * s}px`, height: `${textRect.height * s}px` }}>
+                    style={{ width: `${textRect.width * s}px`, height: auto ? "auto" : `${textRect.height * s}px` }}>
                     <FormattedTextBox color={`${this._textColor}`} fieldKey={this._textFieldKey} hideOnLeave={this._textHideOnLeave} isOverlay={true} Document={FormattedTextBox.InputBoxOverlay.props.Document} isSelected={returnTrue} select={emptyFunction} isTopMost={true}
                         selectOnLoad={true} ContainingCollectionView={undefined} whenActiveChanged={emptyFunction} active={returnTrue}
                         ScreenToLocalTransform={this._textXf} PanelWidth={returnZero} PanelHeight={returnZero} focus={emptyFunction} addDocTab={this.addDocTab} />
diff --git a/src/client/views/Templates.tsx b/src/client/views/Templates.tsx
index 8943bbcaf..3cd525afa 100644
--- a/src/client/views/Templates.tsx
+++ b/src/client/views/Templates.tsx
@@ -41,21 +41,13 @@ export namespace Templates {
 
     export const Caption = new Template("Caption", TemplatePosition.OutterBottom,
         `<div>
-            <div style="height:100%; width:100%;position:absolute;">{layout}</div>
+            <div style="height:100%; width:100%;">{layout}</div>
             <div style="bottom: 0; font-size:14px; width:100%; position:absolute">
-                <FormattedTextBox {...props} fieldKey={"caption"} hideOnLeave={"true"} />
+                <FormattedTextBox {...props} height="min-content" fieldKey={"caption"} hideOnLeave={"true"} />
             </div>
         </div>` );
 
-    export const ImageTitle = new Template("Image Title", TemplatePosition.InnerTop,
-        `<div style="height:100%">
-            <div style="height:100%; width:100%;position:absolute;">{layout}</div>
-            <div style="height:25px; width:100%; position:absolute; top: 0; background-color: rgba(0, 0, 0, .4); color: white; ">
-                <span style="text-align:center;width:100%;font-size:20px;position:absolute;overflow:hidden;white-space:nowrap;text-overflow:ellipsis">{props.Document.title}</span>
-            </div>
-        </div>` );
-
-    export const TextTitle = new Template("Text Title", TemplatePosition.InnerTop,
+    export const Title = new Template("Title", TemplatePosition.InnerTop,
         `<div style="height:100%">
             <div style="height:25px; width:100%; background-color: rgba(0, 0, 0, .4); color: white; ">
                 <span style="text-align:center;width:100%;font-size:20px;position:absolute;overflow:hidden;white-space:nowrap;text-overflow:ellipsis">{props.Document.title}</span>
@@ -92,7 +84,7 @@ export namespace Templates {
             </div > `);
     }
 
-    export const TemplateList: Template[] = [TextTitle, Header, ImageTitle, Caption, Bullet];
+    export const TemplateList: Template[] = [Title, Header, Caption, Bullet];
 
     export function sortTemplates(a: Template, b: Template) {
         if (a.Position < b.Position) { return -1; }
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 8dc10bcd1..8a6764c58 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -20,6 +20,7 @@ import { CollectionSubView } from "./CollectionSubView";
 import "./CollectionTreeView.scss";
 import React = require("react");
 import { Transform } from '../../util/Transform';
+import { SelectionManager } from '../../util/SelectionManager';
 
 
 export interface TreeViewProps {
@@ -32,6 +33,7 @@ export interface TreeViewProps {
     ScreenToLocalTransform: () => Transform;
     treeViewId: string;
     parentKey: string;
+    active: () => boolean;
 }
 
 export enum BulletType {
@@ -69,7 +71,7 @@ class TreeView extends React.Component<TreeViewProps> {
     @action onMouseLeave = () => { this._isOver = false; }
 
     onPointerEnter = (e: React.PointerEvent): void => {
-        this.props.document.libraryBrush = true;
+        this.props.active() && (this.props.document.libraryBrush = true);
         if (e.buttons === 1) {
             this._header!.current!.className = "treeViewItem-header";
             document.addEventListener("pointermove", this.onDragMove, true);
@@ -149,7 +151,10 @@ class TreeView extends React.Component<TreeViewProps> {
             </div>);
         return (
             <div className="docContainer" id={`docContainer-${this.props.parentKey}`} ref={reference} onPointerDown={onItemDown} onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}
-                style={{ background: BoolCast(this.props.document.protoBrush, false) ? "#06123232" : BoolCast(this.props.document.libraryBrush, false) ? "#06121212" : "0" }}
+                style={{
+                    background: BoolCast(this.props.document.protoBrush, false) ? "#06123232" : BoolCast(this.props.document.libraryBrush, false) ? "#06121212" : "0",
+                    pointerEvents: this.props.active() || SelectionManager.GetIsDragging() ? "all" : "none"
+                }}
             >
                 {editableView(StrCast(this.props.document.title))}
                 {openRight}
@@ -225,18 +230,19 @@ class TreeView extends React.Component<TreeViewProps> {
             while (keys.indexOf("proto") !== -1) keys.splice(keys.indexOf("proto"), 1);
         }
         keys.map(key => {
-            let docList = DocListCast(this.props.document[key]);
+            let docList = Cast(this.props.document[key], listSpec(Doc));
             let remDoc = (doc: Doc) => this.remove(doc, key);
             let addDoc = (doc: Doc, addBefore?: Doc, before?: boolean) => TreeView.AddDocToList(this.props.document, key, doc, addBefore, before);
             let doc = Cast(this.props.document[key], Doc);
-            if (doc instanceof Doc || docList.length) {
+            if (doc instanceof Doc || docList) {
                 if (!this._collapsed) {
                     bulletType = BulletType.Collapsible;
                     contentElement.push(<ul key={key + "more"}>
                         {(key === "data") ? (null) :
                             <span className="collectionTreeView-keyHeader" style={{ display: "block", marginTop: "7px" }} key={key}>{key}</span>}
                         <div style={{ display: "block" }}>
-                            {TreeView.GetChildElements(doc instanceof Doc ? [doc] : docList, this.props.treeViewId, key, addDoc, remDoc, this.move, this.props.dropAction, this.props.addDocTab, this.props.ScreenToLocalTransform)}
+                            {TreeView.GetChildElements(doc instanceof Doc ? [doc] : DocListCast(docList), this.props.treeViewId, key, addDoc, remDoc, this.move,
+                                this.props.dropAction, this.props.addDocTab, this.props.ScreenToLocalTransform, this.props.active)}
                         </div>
                     </ul >);
                 } else {
@@ -266,11 +272,12 @@ class TreeView extends React.Component<TreeViewProps> {
         move: DragManager.MoveFunction,
         dropAction: dropActionType,
         addDocTab: (doc: Doc, where: string) => void,
-        screenToLocalXf: () => Transform
+        screenToLocalXf: () => Transform,
+        active: () => boolean
     ) {
         return docs.filter(child => !child.excludeFromLibrary && (key !== "data" || !child.isMinimized)).map(child =>
             <TreeView document={child} treeViewId={treeViewId} key={child[Id]} deleteDoc={remove} addDocument={add} moveDocument={move}
-                dropAction={dropAction} addDocTab={addDocTab} ScreenToLocalTransform={screenToLocalXf} parentKey={key} />);
+                dropAction={dropAction} addDocTab={addDocTab} ScreenToLocalTransform={screenToLocalXf} parentKey={key} active={active} />);
     }
 }
 
@@ -309,7 +316,8 @@ export class CollectionTreeView extends CollectionSubView(Document) {
         }
         let addDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => TreeView.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before);
         let moveDoc = (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc);
-        let childElements = TreeView.GetChildElements(this.childDocs, this.props.Document[Id], this.props.fieldKey, addDoc, this.remove, moveDoc, dropAction, this.props.addDocTab, this.props.ScreenToLocalTransform);
+        let childElements = TreeView.GetChildElements(this.childDocs, this.props.Document[Id], this.props.fieldKey, addDoc, this.remove,
+            moveDoc, dropAction, this.props.addDocTab, this.props.ScreenToLocalTransform, this.props.active);
 
         return (
             <div id="body" className="collectionTreeView-dropTarget"
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index d23bef2d3..63f24ff53 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -6,7 +6,6 @@ import { InkField, StrokeData } from "../../../../new_fields/InkField";
 import { createSchema, makeInterface } from "../../../../new_fields/Schema";
 import { BoolCast, Cast, FieldValue, NumCast } from "../../../../new_fields/Types";
 import { emptyFunction, returnOne } from "../../../../Utils";
-import { DocServer } from "../../../DocServer";
 import { DocumentManager } from "../../../util/DocumentManager";
 import { DragManager } from "../../../util/DragManager";
 import { HistoryUtil } from "../../../util/History";
@@ -26,7 +25,6 @@ import "./CollectionFreeFormView.scss";
 import { MarqueeView } from "./MarqueeView";
 import React = require("react");
 import v5 = require("uuid/v5");
-import { Docs } from "../../../documents/Documents";
 
 export const panZoomSchema = createSchema({
     panX: "number",
@@ -218,6 +216,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
     @action
     setPan(panX: number, panY: number) {
+
         this.props.Document.panTransformType = "None";
         var scale = this.getLocalTransform().inverse().Scale;
         const newPanX = Math.min((1 - 1 / scale) * this.nativeWidth, Math.max(0, panX));
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 2ac6d12bf..19f5c7d36 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -349,9 +349,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 dst.nativeHeight = src.nativeHeight;
             }
             else {
-                const docs = await SearchUtil.Search(`data_l:"${destDoc[Id]}"`, true);
-                const views = docs.map(d => DocumentManager.Instance.getDocumentView(d)).filter(d => d).map(d => d as DocumentView);
-                DocUtils.MakeLink(sourceDoc, destDoc, views.length ? views[0].props.Document : undefined);
+                // const docs = await SearchUtil.Search(`data_l:"${destDoc[Id]}"`, true);
+                // const views = docs.map(d => DocumentManager.Instance.getDocumentView(d)).filter(d => d).map(d => d as DocumentView);
+                DocUtils.MakeLink(sourceDoc, destDoc, this.props.ContainingCollectionView ? this.props.ContainingCollectionView.props.Document : undefined);
                 de.data.droppedDocuments.push(destDoc);
             }
         }
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
index fe0da2e7a..8cb1db953 100644
--- a/src/new_fields/util.ts
+++ b/src/new_fields/util.ts
@@ -6,7 +6,7 @@ import { FieldValue } from "./Types";
 import { RefField } from "./RefField";
 import { ObjectField } from "./ObjectField";
 import { action } from "mobx";
-import { Parent, OnUpdate, Update, Id } from "./FieldSymbols";
+import { Parent, OnUpdate, Update, Id, SelfProxy } from "./FieldSymbols";
 import { ComputedField } from "../fields/ScriptField";
 
 export const setter = action(function (target: any, prop: string | symbol | number, value: any, receiver: any): boolean {
@@ -86,7 +86,7 @@ export function deleteProperty(target: any, prop: string | number | symbol) {
         delete target[prop];
         return true;
     }
-    target[prop] = undefined;
+    target[SelfProxy][prop] = undefined;
     return true;
 }
 
-- 
cgit v1.2.3-70-g09d2


From 0cd0f5afdef91740fecdedaaecb2ed6be054eee5 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Mon, 17 Jun 2019 18:13:36 -0400
Subject: somewhat fixed problem of titles & text boxes

---
 src/client/views/MainOverlayTextBox.tsx | 4 ++++
 src/client/views/Templates.tsx          | 8 ++++----
 2 files changed, 8 insertions(+), 4 deletions(-)

(limited to 'src/client/views/Templates.tsx')

diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx
index 23e90ece5..4e983c906 100644
--- a/src/client/views/MainOverlayTextBox.tsx
+++ b/src/client/views/MainOverlayTextBox.tsx
@@ -10,6 +10,7 @@ import { Transform } from '../util/Transform';
 import { CollectionDockingView } from './collections/CollectionDockingView';
 import "./MainOverlayTextBox.scss";
 import { FormattedTextBox } from './nodes/FormattedTextBox';
+import { For } from 'babel-types';
 
 interface MainOverlayTextBoxProps {
 }
@@ -25,6 +26,7 @@ export class MainOverlayTextBox extends React.Component<MainOverlayTextBoxProps>
     private _textProxyDiv: React.RefObject<HTMLDivElement>;
     private _textBottom: boolean | undefined;
     private _textAutoHeight: boolean | undefined;
+    private _textBox: FormattedTextBox | undefined;
     @observable public TextDoc?: Doc;
 
     constructor(props: MainOverlayTextBoxProps) {
@@ -33,6 +35,7 @@ export class MainOverlayTextBox extends React.Component<MainOverlayTextBoxProps>
         MainOverlayTextBox.Instance = this;
         reaction(() => FormattedTextBox.InputBoxOverlay,
             (box?: FormattedTextBox) => {
+                this._textBox = box;
                 if (box) {
                     this.TextDoc = box.props.Document;
                     let sxf = Utils.GetScreenTransform(box ? box.CurrentDiv : undefined);
@@ -68,6 +71,7 @@ export class MainOverlayTextBox extends React.Component<MainOverlayTextBoxProps>
     textScroll = (e: React.UIEvent) => {
         if (this._textProxyDiv.current && this._textTargetDiv) {
             this._textTargetDiv.scrollTop = (e as any)._targetInst.stateNode.scrollTop;
+            console.log(this._textTargetDiv.scrollTop + " != " + (e as any)._targetInst.stateNode.scrollTop + " != " + (this._textBox!.CurrentDiv ? this._textBox!.CurrentDiv.scrollTop : -1));
         }
     }
 
diff --git a/src/client/views/Templates.tsx b/src/client/views/Templates.tsx
index 3cd525afa..3d5f7b6ea 100644
--- a/src/client/views/Templates.tsx
+++ b/src/client/views/Templates.tsx
@@ -48,12 +48,12 @@ export namespace Templates {
         </div>` );
 
     export const Title = new Template("Title", TemplatePosition.InnerTop,
-        `<div style="height:100%">
+        `<div>
             <div style="height:25px; width:100%; background-color: rgba(0, 0, 0, .4); color: white; ">
                 <span style="text-align:center;width:100%;font-size:20px;position:absolute;overflow:hidden;white-space:nowrap;text-overflow:ellipsis">{props.Document.title}</span>
             </div>
-            <div style="display:flex; flex-direction:column; height:calc(100% - 25px);">
-                <div style="height:min-content; width:100%;overflow:auto">{layout}</div>
+            <div style="height:calc(100% - 25px);">
+                <div style="width:100%;overflow:auto">{layout}</div>
             </div>
         </div>` );
 
@@ -62,7 +62,7 @@ export namespace Templates {
             <div style="width:100%; background-color: rgba(0, 0, 0, .4); color: white; ">
                 <FormattedTextBox {...props} height={"min-content"} color={"white"} fieldKey={"header"} />
             </div>
-            <div style="width:100%;height:min-content;overflow:auto;">{layout}</div>
+            <div style="width:100%;height:100%;overflow:auto;">{layout}</div>
         </div > ` );
 
     export const Bullet = new Template("Bullet", TemplatePosition.InnerTop,
-- 
cgit v1.2.3-70-g09d2


From ce54e04c09ee0f7549d436f6ffe1f9f9b9efd7b5 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Fri, 21 Jun 2019 01:00:32 -0400
Subject: user assignable templates

---
 src/client/views/DocumentDecorations.tsx             | 20 +++++++++++++++++++-
 src/client/views/Templates.tsx                       | 12 +++++++++++-
 src/client/views/collections/CollectionView.tsx      |  5 +++--
 .../collectionFreeForm/CollectionFreeFormView.tsx    | 12 ++++++------
 src/client/views/nodes/FormattedTextBox.tsx          |  4 ++--
 5 files changed, 41 insertions(+), 12 deletions(-)

(limited to 'src/client/views/Templates.tsx')

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 2c0e18bbb..d6010ec33 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -3,7 +3,7 @@ import { faLink } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, computed, observable, reaction, runInAction } from "mobx";
 import { observer } from "mobx-react";
-import { Doc } from "../../new_fields/Doc";
+import { Doc, WidthSym, HeightSym } from "../../new_fields/Doc";
 import { List } from "../../new_fields/List";
 import { listSpec } from "../../new_fields/Schema";
 import { Cast, NumCast, StrCast, BoolCast } from "../../new_fields/Types";
@@ -25,6 +25,7 @@ import { TemplateMenu } from "./TemplateMenu";
 import { Template, Templates } from "./Templates";
 import React = require("react");
 import { URLField } from '../../new_fields/URLField';
+import { templateLiteral } from 'babel-types';
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -73,6 +74,23 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
             if (text[0] === '#') {
                 this._fieldKey = text.slice(1, text.length);
                 this._title = this.selectionTitle;
+                let first = SelectionManager.SelectedDocuments()[0].props.Document!;
+                let collection = SelectionManager.SelectedDocuments()[0].props.ContainingCollectionView!.props.Document;
+                Doc.GetProto(collection)[this._fieldKey] = "Testing";
+                let template = Doc.MakeAlias(collection);
+                template.title = "FIELD-" + this._fieldKey;
+                template.layout = FormattedTextBox.LayoutString(this._fieldKey);
+                template.x = NumCast(first.x);
+                template.y = NumCast(first.y);
+                template.width = first[WidthSym]();
+                template.height = first[HeightSym]();
+                //{props.DataDoc.${fieldKey}}
+                template.templates = new List<string>([Templates.TitleBar(this._fieldKey)]);
+                Doc.AddDocToList(collection, "data", template);
+                SelectionManager.SelectedDocuments().map(dv => dv.props.removeDocument && dv.props.removeDocument(dv.props.Document));
+
+                // let template = SelectionManager.SelectedDocuments()[0].props.Document; template.proto = Doc.GetProto(collection)
+                // template.layout = FormattedTextBox.LayoutString(this._fieldKey);
             }
             else {
                 if (SelectionManager.SelectedDocuments().length > 0) {
diff --git a/src/client/views/Templates.tsx b/src/client/views/Templates.tsx
index a227faa71..0904b03b0 100644
--- a/src/client/views/Templates.tsx
+++ b/src/client/views/Templates.tsx
@@ -50,7 +50,7 @@ export namespace Templates {
     export const Title = new Template("Title", TemplatePosition.InnerTop,
         `<div>
             <div style="height:25px; width:100%; background-color: rgba(0, 0, 0, .4); color: white; z-index: 100">
-                <span style="text-align:center;width:100%;font-size:20px;position:absolute;overflow:hidden;white-space:nowrap;text-overflow:ellipsis">{props.Document.title}</span>
+                <span style="text-align:center;width:100%;font-size:20px;position:absolute;overflow:hidden;white-space:nowrap;text-overflow:ellipsis">{props.DataDoc.title}</span>
             </div>
             <div style="height:calc(100% - 25px);">
                 <div style="width:100%;overflow:auto">{layout}</div>
@@ -84,6 +84,16 @@ export namespace Templates {
             </div > `);
     }
 
+    export function TitleBar(titlestr: string) {
+        return (`<div>
+            <div style="height:25px; width:100%; background-color: rgba(0, 0, 0, .4); color: white; z-index: 100">
+                <span style="text-align:center;width:100%;font-size:20px;position:absolute;overflow:hidden;white-space:nowrap;text-overflow:ellipsis">${titlestr}</span>
+            </div>
+            <div style="height:calc(100% - 25px);">
+                <div style="width:100%;overflow:auto">{layout}</div>
+            </div>
+        </div>` );
+    }
     export const TemplateList: Template[] = [Title, Header, Caption, Bullet];
 
     export function sortTemplates(a: Template, b: Template) {
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 6d3301ce4..e24466d57 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -60,8 +60,9 @@ export class CollectionView extends React.Component<FieldViewProps> {
             ContextMenu.Instance.addItem({ description: "View Modes...", subitems: subItems });
             ContextMenu.Instance.addItem({
                 description: "Add Description Template", event: undoBatch(() => {
-                    Doc.GetProto(this.props.Document).description = "my first templated box";
-                    let template = Doc.MakeAlias(this.props.Document);
+                    let collection = this.props.Document;
+                    Doc.GetProto(collection).description = "my first templated box";
+                    let template = Doc.MakeAlias(collection);
                     template.layout = FormattedTextBox.LayoutString("description");
                     template.x = 0;
                     template.y = 0;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index bf47195d9..5c2ea3ef0 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -294,18 +294,18 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     }
 
 
-    getDocumentViewProps(document: Doc): DocumentViewProps {
+    getDocumentViewProps(layoutDoc: Doc): DocumentViewProps {
         return {
-            Document: document,
-            DataDoc: this.props.DataDoc,
+            DataDoc: this.props.DataDoc !== this.props.Document ? this.props.DataDoc : layoutDoc,
+            Document: layoutDoc,
             addDocument: this.props.addDocument,
             removeDocument: this.props.removeDocument,
             moveDocument: this.props.moveDocument,
             ScreenToLocalTransform: this.getTransform,
             isTopMost: false,
-            selectOnLoad: document[Id] === this._selectOnLoaded,
-            PanelWidth: document[WidthSym],
-            PanelHeight: document[HeightSym],
+            selectOnLoad: layoutDoc[Id] === this._selectOnLoaded,
+            PanelWidth: layoutDoc[WidthSym],
+            PanelHeight: layoutDoc[HeightSym],
             ContentScaling: returnOne,
             ContainingCollectionView: this.props.CollectionView,
             focus: this.focusDocument,
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 8231cc089..92835ba39 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -104,7 +104,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
         }
     }
 
-    @computed get dataDoc() { return this.props.DataDoc; }
+    @computed get dataDoc() { return this.props.DataDoc ? this.props.DataDoc : this.props.Document; }
 
     dispatchTransaction = (tx: Transaction) => {
         if (this._editorView) {
@@ -112,7 +112,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
             this._editorView.updateState(state);
             this._applyingChange = true;
             Doc.SetOnPrototype(this.dataDoc, this.props.fieldKey, new RichTextField(JSON.stringify(state.toJSON())));
-            Doc.SetOnPrototype(this.dataDoc, "documentText", state.doc.textBetween(0, state.doc.content.size, "\n\n"));
+            Doc.SetOnPrototype(this.dataDoc, this.props.fieldKey + "_text", state.doc.textBetween(0, state.doc.content.size, "\n\n"));
             this._applyingChange = false;
             let title = StrCast(this.dataDoc.title);
             if (title && title.startsWith("-") && this._editorView) {
-- 
cgit v1.2.3-70-g09d2


From 5483c3353b99e7993f358e3d212b1717bf21fec6 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Fri, 21 Jun 2019 10:44:15 -0400
Subject: more template improvements for treeview

---
 src/client/views/DocumentDecorations.tsx           | 14 ++++----
 src/client/views/Templates.tsx                     |  4 +--
 .../views/collections/CollectionDockingView.tsx    |  4 +--
 .../views/collections/CollectionStackingView.tsx   |  2 +-
 .../views/collections/CollectionTreeView.tsx       | 37 +++++++++++++++++++---
 src/client/views/collections/CollectionView.tsx    | 27 ----------------
 src/client/views/nodes/KeyValuePair.tsx            |  1 +
 7 files changed, 45 insertions(+), 44 deletions(-)

(limited to 'src/client/views/Templates.tsx')

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index b3f5340d9..3a366b4d2 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -74,24 +74,22 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
             if (text[0] === '#') {
                 this._fieldKey = text.slice(1, text.length);
                 this._title = this.selectionTitle;
+            } else if (text[0] === ">") {
+                let metaKey = text.slice(1, text.length);
                 let first = SelectionManager.SelectedDocuments()[0].props.Document!;
                 let collection = SelectionManager.SelectedDocuments()[0].props.ContainingCollectionView!.props.Document;
-                Doc.GetProto(collection)[this._fieldKey] = "Testing";
+                Doc.GetProto(collection)[metaKey] = "-empty field-";
                 let template = Doc.MakeAlias(collection);
-                template.title = "FIELD-" + this._fieldKey;
-                template.layout = FormattedTextBox.LayoutString(this._fieldKey);
+                template.title = metaKey;
+                template.layout = FormattedTextBox.LayoutString(metaKey);
                 template.isTemplate = true;
                 template.x = NumCast(first.x);
                 template.y = NumCast(first.y);
                 template.width = first[WidthSym]();
                 template.height = first[HeightSym]();
-                //{props.DataDoc.${fieldKey}}
-                template.templates = new List<string>([Templates.TitleBar(this._fieldKey)]);
+                template.templates = new List<string>([Templates.TitleBar(metaKey)]);//`{props.DataDoc.${metaKey}_text}`)]);
                 Doc.AddDocToList(collection, "data", template);
                 SelectionManager.SelectedDocuments().map(dv => dv.props.removeDocument && dv.props.removeDocument(dv.props.Document));
-
-                // let template = SelectionManager.SelectedDocuments()[0].props.Document; template.proto = Doc.GetProto(collection)
-                // template.layout = FormattedTextBox.LayoutString(this._fieldKey);
             }
             else {
                 if (SelectionManager.SelectedDocuments().length > 0) {
diff --git a/src/client/views/Templates.tsx b/src/client/views/Templates.tsx
index 0904b03b0..5bb8d454a 100644
--- a/src/client/views/Templates.tsx
+++ b/src/client/views/Templates.tsx
@@ -84,10 +84,10 @@ export namespace Templates {
             </div > `);
     }
 
-    export function TitleBar(titlestr: string) {
+    export function TitleBar(datastring: string) {
         return (`<div>
             <div style="height:25px; width:100%; background-color: rgba(0, 0, 0, .4); color: white; z-index: 100">
-                <span style="text-align:center;width:100%;font-size:20px;position:absolute;overflow:hidden;white-space:nowrap;text-overflow:ellipsis">${titlestr}</span>
+                <span style="text-align:center;width:100%;font-size:20px;position:absolute;overflow:hidden;white-space:nowrap;text-overflow:ellipsis">${datastring}</span>
             </div>
             <div style="height:calc(100% - 25px);">
                 <div style="width:100%;overflow:auto">{layout}</div>
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 05c3cdac6..79a0d18df 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -261,8 +261,8 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
         this._isPointerDown = true;
         let onPointerUp = action(() => {
             window.removeEventListener("pointerup", onPointerUp)
-            this._isPointerDown = false
-        })
+            this._isPointerDown = false;
+        });
         window.addEventListener("pointerup", onPointerUp);
         var className = (e.target as any).className;
         if (className === "messageCounter") {
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index a1e84302b..19a9a1208 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -100,7 +100,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             let dref = React.createRef<HTMLDivElement>();
             let dxf = () => this.getDocTransform(d, dref.current!).scale(this.columnWidth / d[WidthSym]());
             let width = () => d.nativeWidth ? Math.min(d[WidthSym](), this.columnWidth) : this.columnWidth;
-            let height = () => aspect ? width() / aspect : d[HeightSym]()
+            let height = () => aspect ? width() / aspect : d[HeightSym]();
             let rowSpan = Math.ceil((height() + this.gridGap) / (this._gridSize + this.gridGap));
             return (<div className="collectionStackingView-masonryDoc"
                 key={d[Id]}
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 7528bc29d..18d6751c6 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -25,10 +25,13 @@ import { CollectionSchemaPreview } from './CollectionSchemaView';
 import { CollectionSubView } from "./CollectionSubView";
 import "./CollectionTreeView.scss";
 import React = require("react");
+import { FormattedTextBox } from '../nodes/FormattedTextBox';
 
 
 export interface TreeViewProps {
     document: Doc;
+    dataDoc: Doc;
+    containingCollection: Doc;
     deleteDoc: (doc: Doc) => boolean;
     moveDocument: DragManager.MoveFunction;
     dropAction: "alias" | "copy" | undefined;
@@ -142,7 +145,29 @@ class TreeView extends React.Component<TreeViewProps> {
         height={36}
         fontStyle={style}
         GetValue={() => StrCast(this.props.document[key])}
-        SetValue={(value: string) => (Doc.GetProto(this.props.document)[key] = value) ? true : true}
+        SetValue={(value: string) => {
+            let res = (Doc.GetProto(this.props.document)[key] = value) ? true : true;
+
+            if (value.startsWith(">")) {
+                let metaKey = value.slice(1, value.length);
+                let collection = this.props.containingCollection;
+                Doc.GetProto(collection)[metaKey] = "-empty field-";
+                let template = Doc.MakeAlias(collection);
+                template.title = metaKey;
+                template.embed = true;
+                template.layout = FormattedTextBox.LayoutString(metaKey);
+                template.x = 0;
+                template.y = 0;
+                template.width = 100;
+                template.height = 50;
+                template.isTemplate = true;
+                template.templates = new List<string>([Templates.TitleBar(metaKey)]);//`{props.DataDoc.${metaKey}_text}`)]);
+                Doc.AddDocToList(collection, "data", template);
+                this.delete();
+            }
+
+            return res;
+        }}
         OnFillDown={(value: string) => {
             Doc.GetProto(this.props.document)[key] = value;
             let doc = Docs.FreeformDocument([], { title: "", x: 0, y: 0, width: 100, height: 25, templates: new List<string>([Templates.Title.Layout]) });
@@ -269,14 +294,14 @@ class TreeView extends React.Component<TreeViewProps> {
         if (!this._collapsed) {
             if (!this.props.document.embed) {
                 contentElement = <ul key={this._chosenKey + "more"}>
-                    {TreeView.GetChildElements(doc instanceof Doc ? [doc] : DocListCast(docList), this.props.treeViewId, this._chosenKey, addDoc, remDoc, this.move,
+                    {TreeView.GetChildElements(doc instanceof Doc ? [doc] : DocListCast(docList), this.props.treeViewId, this.props.document, this.props.dataDoc, this._chosenKey, addDoc, remDoc, this.move,
                         this.props.dropAction, this.props.addDocTab, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, this.props.panelWidth)}
                 </ul >;
             } else {
                 contentElement = <div ref={this._dref} style={{ display: "inline-block", height: this.props.panelHeight() }} key={this.props.document[Id]}>
                     <CollectionSchemaPreview
                         Document={this.props.document}
-                        DataDocument={this.props.document}
+                        DataDocument={this.props.dataDoc}
                         width={docWidth}
                         height={this.props.panelHeight}
                         getTransform={this.docTransform}
@@ -307,6 +332,8 @@ class TreeView extends React.Component<TreeViewProps> {
     public static GetChildElements(
         docs: Doc[],
         treeViewId: string,
+        containingCollection: Doc,
+        dataDoc: Doc,
         key: string,
         add: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean,
         remove: ((doc: Doc) => boolean),
@@ -338,6 +365,8 @@ class TreeView extends React.Component<TreeViewProps> {
             };
             return <TreeView
                 document={child}
+                dataDoc={dataDoc}
+                containingCollection={containingCollection}
                 treeViewId={treeViewId}
                 key={child[Id]}
                 indentDocument={indent}
@@ -419,7 +448,7 @@ export class CollectionTreeView extends CollectionSubView(Document) {
                 </div>
                 <ul className="no-indent">
                     {
-                        TreeView.GetChildElements(this.childDocs, this.props.Document[Id], this.props.fieldKey, addDoc, this.remove,
+                        TreeView.GetChildElements(this.childDocs, this.props.Document[Id], this.props.Document, this.props.DataDoc, this.props.fieldKey, addDoc, this.remove,
                             moveDoc, dropAction, this.props.addDocTab, this.props.ScreenToLocalTransform, this.outerXf, this.props.active, this.props.PanelWidth)
                     }
                 </ul>
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index f254e6005..89e5ad74c 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -58,33 +58,6 @@ export class CollectionView extends React.Component<FieldViewProps> {
             subItems.push({ description: "Treeview", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.Tree), icon: "tree" });
             subItems.push({ description: "Stacking", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.Stacking), icon: "th-list" });
             ContextMenu.Instance.addItem({ description: "View Modes...", subitems: subItems });
-            ContextMenu.Instance.addItem({
-                description: "Add Description Template", event: undoBatch(() => {
-                    let collection = this.props.Document;
-                    Doc.GetProto(collection).description = "my first templated box";
-                    let template = Doc.MakeAlias(collection);
-                    template.layout = FormattedTextBox.LayoutString("description");
-                    template.isTemplate = true;
-                    template.x = 0;
-                    template.y = 0;
-                    template.width = 100;
-                    template.height = 25;
-                    Doc.AddDocToList(this.props.Document, "data", template);
-                }), icon: "project-diagram"
-            });
-            ContextMenu.Instance.addItem({
-                description: "Add Summary Template", event: undoBatch(() => {
-                    Doc.GetProto(this.props.Document).summary = "my first templated box";
-                    let template = Doc.MakeAlias(this.props.Document);
-                    template.layout = FormattedTextBox.LayoutString("summary");
-                    template.isTemplate = true;
-                    template.x = 0;
-                    template.y = 0;
-                    template.width = 100;
-                    template.height = 25;
-                    Doc.AddDocToList(this.props.Document, "data", template);
-                }), icon: "project-diagram"
-            });
             ContextMenu.Instance.addItem({
                 description: "Apply Template", event: undoBatch(() => {
                     let otherdoc = Docs.TextDocument({ width: 100, height: 50, title: "applied template" });
diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx
index 420a1ad94..d3bd9c875 100644
--- a/src/client/views/nodes/KeyValuePair.tsx
+++ b/src/client/views/nodes/KeyValuePair.tsx
@@ -28,6 +28,7 @@ export class KeyValuePair extends React.Component<KeyValuePairProps> {
     render() {
         let props: FieldViewProps = {
             Document: this.props.doc,
+            DataDoc: this.props.doc,
             ContainingCollectionView: undefined,
             fieldKey: this.props.keyName,
             isSelected: returnFalse,
-- 
cgit v1.2.3-70-g09d2


From 16822d88f981e7a86729d942a92b6ad8590680e4 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Mon, 1 Jul 2019 22:32:44 -0400
Subject: fixed title template view issue

---
 src/client/views/TemplateMenu.tsx                      | 8 ++++++++
 src/client/views/Templates.tsx                         | 4 ++--
 src/client/views/collections/CollectionDockingView.tsx | 2 +-
 src/client/views/nodes/DocumentView.tsx                | 5 +++++
 4 files changed, 16 insertions(+), 3 deletions(-)

(limited to 'src/client/views/Templates.tsx')

diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx
index d63f45e5a..1b32f0ddd 100644
--- a/src/client/views/TemplateMenu.tsx
+++ b/src/client/views/TemplateMenu.tsx
@@ -64,6 +64,13 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
         }
     }
 
+    @undoBatch
+    @action
+    clearTemplates = (event: React.MouseEvent) => {
+        this.props.docs.map(d => d.clearTemplates());
+        Array.from(this.props.templates.keys()).map(t => this.props.templates.set(t, false));
+    }
+
     @action
     componentWillReceiveProps(nextProps: TemplateMenuProps) {
         // this._templates = nextProps.templates;
@@ -84,6 +91,7 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
                 <div title="Template Options" className="templating-button" onClick={() => this.toggleTemplateActivity()}>+</div>
                 <ul id="template-list" style={{ display: this._hidden ? "none" : "block" }}>
                     {templateMenu}
+                    <button style={{ display: this._hidden ? "none" : "block" }} onClick={this.clearTemplates}>Clear</button>
                 </ul>
             </div>
         );
diff --git a/src/client/views/Templates.tsx b/src/client/views/Templates.tsx
index 5bb8d454a..4843a70a6 100644
--- a/src/client/views/Templates.tsx
+++ b/src/client/views/Templates.tsx
@@ -50,7 +50,7 @@ export namespace Templates {
     export const Title = new Template("Title", TemplatePosition.InnerTop,
         `<div>
             <div style="height:25px; width:100%; background-color: rgba(0, 0, 0, .4); color: white; z-index: 100">
-                <span style="text-align:center;width:100%;font-size:20px;position:absolute;overflow:hidden;white-space:nowrap;text-overflow:ellipsis">{props.DataDoc.title}</span>
+                <span style="text-align:center;width:100%;font-size:20px;position:absolute;overflow:hidden;white-space:nowrap;text-overflow:ellipsis">{props.Document.title}</span>
             </div>
             <div style="height:calc(100% - 25px);">
                 <div style="width:100%;overflow:auto">{layout}</div>
@@ -58,7 +58,7 @@ export namespace Templates {
         </div>` );
 
     export const Header = new Template("Header", TemplatePosition.InnerTop,
-        `< div style = "display:flex; flex-direction:column; height:100%;" >
+        `<div style = "display:flex; flex-direction:column; height:100%;" >
             <div style="width:100%; background-color: rgba(0, 0, 0, .4); color: white; ">
                 <FormattedTextBox {...props} height={"min-content"} color={"white"} fieldKey={"header"} />
             </div>
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index ad5472a4a..8724216f5 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -269,7 +269,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
         var cur = this._containerRef.current;
 
         // bcz: since GoldenLayout isn't a React component itself, we need to notify it to resize when its document container's size has changed
-        this._goldenLayout.updateSize(cur!.getBoundingClientRect().width, cur!.getBoundingClientRect().height);
+        this._goldenLayout && this._goldenLayout.updateSize(cur!.getBoundingClientRect().width, cur!.getBoundingClientRect().height);
     }
 
     @action
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 687c7f73d..3673cb0e2 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -473,6 +473,11 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         }
         this.templates = this.templates;
     }
+    @action
+    clearTemplates = () => {
+        this.templates.length = 0;
+        this.templates = this.templates;
+    }
 
     @undoBatch
     @action
-- 
cgit v1.2.3-70-g09d2


From 336266551d363df8c4958d485170846b478f1787 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Fri, 5 Jul 2019 11:54:39 -0400
Subject: fixed templates (old style) a bit.

---
 deploy/assets/downarrow.png                              | Bin 0 -> 3363 bytes
 src/client/views/Templates.tsx                           |   3 +--
 .../collectionFreeForm/CollectionFreeFormView.tsx        |   4 ++--
 src/client/views/nodes/DocumentContentsView.tsx          |   5 ++++-
 4 files changed, 7 insertions(+), 5 deletions(-)
 create mode 100644 deploy/assets/downarrow.png

(limited to 'src/client/views/Templates.tsx')

diff --git a/deploy/assets/downarrow.png b/deploy/assets/downarrow.png
new file mode 100644
index 000000000..3c59ff5b1
Binary files /dev/null and b/deploy/assets/downarrow.png differ
diff --git a/src/client/views/Templates.tsx b/src/client/views/Templates.tsx
index 4843a70a6..236704fa2 100644
--- a/src/client/views/Templates.tsx
+++ b/src/client/views/Templates.tsx
@@ -69,8 +69,7 @@ export namespace Templates {
         `< div >
         <div style="height:100%; width:100%;position:absolute;">{layout}</div>
         <div id="isExpander" style="height:15px; width:15px; margin-left:-16px; pointer-events:all; position:absolute; top: 0; background-color: rgba(0, 0, 0, .4); color: white;">
-            <img id="isExpander" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAZlBMVEX///8AAABmZmb7+/tYWFhgYGBFRUVSUlL4+Pg/Pz9jY2N5eXmcnJyioqKBgYFzc3NtbW1LS0s3NzfW1taWlpaOjo6IiIgvLy9WVlampqZcXFw5OTlvb28mJiYxMTHe3t7l5eUjIyMY8kIZAAAD2UlEQVR4nO2d61biMBRGW1FBEVHxfp15/5ecOVa5lHxtArmck/Xtn1BotjtNoXQtm4YQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEFIrX6UHEA1gsmrneceRjHm7cj28attKFOf/TRyKIliH4vzbZE+xE2zbZYkxRWX5Y9JT/BW0X3G+NtlR3Ahar7jcMtlS3Ba0XXG+Y7JW3BW0XHHZM/lR7AvaVewL/ijuC1pV3Bf8VnQJ2lR0CYriq/Nxg4puwfa1aZ7dz9yUHnEgN26NZ3luWkPFd7fEtHsWVDwpO+YgTgYKCuYn6tAU7TBecaygcGpZEQie7m5luKJPQQFUvCwx5iAuvQoK4KShvSIoOHVtCz7dnOUecxBn7kG/urc2eCz6T9EOcxXDCgpAUetyAwoOCBqrGF5QMKR4mCA8L+pTBIJwkRl95eifJjPHTDYTFQ8vePyrs3BsBfXLzfFHkvKKMY4j1ctNnCmmuGKslfCQT0RZiPdFVmnFmOcy36sDWYn7DU9hxdifRkKuEGQh/pWW0K/QiUlxtUxVxTTXyhQtN6kuI6mpmO5qpxJFIBjl1yMVimmvV4PfrnIq3iYsKICTRj7F9L84gIq38fYwCCj4HnMfRY/FPL8ZFayYo6BQbLlJeZrYpVDFXAUFcMtKWkUgmOhmnwKKOQsK4NaxdIp5CwqZj8X8gv27jNecJ9nZuXtnie/SzjhRQcHkt6Fnq1imoAAUY1csVVDIUrFcQSGDIhC8jriLQZIrli0oXKdVLF1QSFqxfEEBVLyI8NYXCgoKySaqhinakajimxrBRBX1FBQSVNRyDP4SXVGbYHRFfYJN8xhTESwyj5HHHEjEihoLCqDiXfAb3aksKESqCAoqEIxUUW9BAS03E+93mOhcZDYcXVF3QeHBPcI3v4qo4EPiUQcBKr75vHaiv6AAKt6NV0SCqgoKqOKYovpFZgOo+DmsOHkyUlA4ZKKamaIdQPEJK5oqKKCKM7D9zFZBIayiuYICWm5cFWef7o3vs486CP8VdQIEVRcU7sFE7VecgSmqvKDgVxEJqi8ogIof2xVnH2YLCuMT1fAU7RirOPtrXHCsovmCwlDFCgoKWNH4IrMBTdQ/NUzRjiu3CeCq9HAPAVSspaDgX9FkQcG3ollB34qGBf0UTQv6KBoXHFc0LzimWIFg0ywGBBelBxcHXLGKggKqWElBwV2xIkF3xaoEXYqVCe4rVifYV3wpPZwULOouKLzUXVBY1F1QeKm7oLCoXVAqVi7YNM7/F0YIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCG+/ANh4i1CHdc63QAAAABJRU5ErkJggg=="
-                width="15px" height="15px" />
+            <img id="isExpander" src="/assets/downarrow.png" width="15px" height="15px" />
         </div>
         </div > `
     );
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 4b7d462e5..7c0591600 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -468,8 +468,6 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             description: "Add freeform arrangement",
             event: () => {
                 let addOverlay = (key: "arrangeScript" | "arrangeInit", options: OverlayElementOptions, params?: Record<string, string>, requiredType?: string) => {
-                    const docs = DocListCast(this.Document[this.props.fieldKey]);
-                    docs.map(d => d.transition = "transform 1s");
                     let overlayDisposer: () => void;
                     const script = this.Document[key];
                     let originalText: string | undefined = undefined;
@@ -484,6 +482,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
                             onError(script.errors.map(error => error.messageText).join("\n"));
                             return;
                         }
+                        const docs = DocListCast(this.Document[this.props.fieldKey]);
+                        docs.map(d => d.transition = "transform 1s");
                         this.Document[key] = new ScriptField(script);
                         overlayDisposer();
                         setTimeout(() => docs.map(d => d.transition = undefined), 1200);
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 0da4888a1..51d0c83cd 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -24,6 +24,7 @@ import { Without, OmitKeys } from "../../../Utils";
 import { Cast, StrCast, NumCast } from "../../../new_fields/Types";
 import { List } from "../../../new_fields/List";
 import { Doc } from "../../../new_fields/Doc";
+import { CollectionViewType } from "../collections/CollectionBaseView";
 const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
 
 type BindingProps = Without<FieldViewProps, 'fieldKey'>;
@@ -82,7 +83,8 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
         // by checking the layoutKey.  This should probably be moved into
         // a prop so that the overlay can explicitly turn off templates.
         if ((this.props.layoutKey === "overlayLayout" && StrCast(this.props.Document.layout).indexOf("CollectionView") !== -1) ||
-            (this.props.layoutKey === "layout" && StrCast(this.props.Document.layout).indexOf("CollectionView") === -1)) {
+            (this.props.layoutKey === "layout" && StrCast(this.props.Document.layout).indexOf("CollectionView") === -1) ||
+            (this.props.layoutKey === "layout" && NumCast(this.props.Document.viewType)) !== CollectionViewType.Freeform) {
             this.templates.forEach(template => {
                 let self = this;
                 // this scales constants in the markup by the scaling applied to the document, but caps the constants to be smaller
@@ -103,6 +105,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
     }
 
     render() {
+        console.log(this.props.Document.title);
         if (this.props.renderDepth > 7) return (null);
         if (!this.layout && (this.props.layoutKey !== "overlayLayout" || !this.templates.length)) return (null);
         return <ObserverJsxParser
-- 
cgit v1.2.3-70-g09d2

