From a37faf30652c6c593923198ad34e54377e670caf Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Wed, 5 Jun 2019 08:09:10 -0400
Subject: fixed full screen text bug.  cleaned up imports

---
 src/client/views/nodes/FormattedTextBox.tsx | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

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

diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 5c635cc0c..53ab7c35e 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -7,11 +7,12 @@ import { history } from "prosemirror-history";
 import { keymap } from "prosemirror-keymap";
 import { EditorState, Plugin, Transaction } from "prosemirror-state";
 import { EditorView } from "prosemirror-view";
-import { Doc, Field, Opt, WidthSym, HeightSym } from "../../../new_fields/Doc";
+import { Doc, Opt } from "../../../new_fields/Doc";
 import { RichTextField } from "../../../new_fields/RichTextField";
 import { createSchema, makeInterface } from "../../../new_fields/Schema";
 import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
 import { DocServer } from "../../DocServer";
+import { DocUtils } from '../../documents/Documents';
 import { DocumentManager } from "../../util/DocumentManager";
 import { DragManager } from "../../util/DragManager";
 import buildKeymap from "../../util/ProsemirrorKeymap";
@@ -21,14 +22,11 @@ import { SelectionManager } from "../../util/SelectionManager";
 import { TooltipLinkingMenu } from "../../util/TooltipLinkingMenu";
 import { TooltipTextMenu } from "../../util/TooltipTextMenu";
 import { undoBatch, UndoManager } from "../../util/UndoManager";
-import { ContextMenu } from "../../views/ContextMenu";
-import { CollectionDockingView } from "../collections/CollectionDockingView";
 import { DocComponent } from "../DocComponent";
 import { InkingControl } from "../InkingControl";
 import { FieldView, FieldViewProps } from "./FieldView";
 import "./FormattedTextBox.scss";
 import React = require("react");
-import { DocUtils } from '../../documents/Documents';
 
 library.add(faEdit);
 library.add(faSmile);
-- 
cgit v1.2.3-70-g09d2


From 6cd80efe5a467ce3f4eef31db589f6ccddd84f49 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Wed, 5 Jun 2019 09:26:10 -0400
Subject: follow text links on pointer up. prevent web page changing when
 dropping URL onto Dash.

---
 src/client/views/MainView.tsx               |  8 +++++++-
 src/client/views/nodes/FormattedTextBox.tsx | 28 ++++++++++++++++------------
 2 files changed, 23 insertions(+), 13 deletions(-)

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

diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index a093ffdec..42d5929bf 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -170,6 +170,12 @@ export class MainView extends React.Component {
         }
     }
 
+    onDrop = (e: React.DragEvent<HTMLDivElement>) => {
+        e.preventDefault();
+        e.stopPropagation();
+        console.log("Drop");
+    }
+
     @action
     onResize = (r: any) => {
         this.pwidth = r.offset.width;
@@ -203,7 +209,7 @@ export class MainView extends React.Component {
         const pres = mainCont ? FieldValue(Cast(mainCont.presentationView, Doc)) : undefined;
         return <Measure offset onResize={this.onResize}>
             {({ measureRef }) =>
-                <div ref={measureRef} id="mainContent-div">
+                <div ref={measureRef} id="mainContent-div" onDrop={this.onDrop}>
                     {content}
                     {pres ? <PresentationView Document={pres} key="presentation" /> : null}
                 </div>
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 5c635cc0c..9affa0730 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -21,8 +21,6 @@ import { SelectionManager } from "../../util/SelectionManager";
 import { TooltipLinkingMenu } from "../../util/TooltipLinkingMenu";
 import { TooltipTextMenu } from "../../util/TooltipTextMenu";
 import { undoBatch, UndoManager } from "../../util/UndoManager";
-import { ContextMenu } from "../../views/ContextMenu";
-import { CollectionDockingView } from "../collections/CollectionDockingView";
 import { DocComponent } from "../DocComponent";
 import { InkingControl } from "../InkingControl";
 import { FieldView, FieldViewProps } from "./FieldView";
@@ -223,6 +221,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
         }
     }
 
+    _linkClicked = "";
     onPointerDown = (e: React.PointerEvent): void => {
         if (e.button === 0 && this.props.isSelected() && !e.altKey && !e.ctrlKey && !e.metaKey) {
             e.stopPropagation();
@@ -230,23 +229,17 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
                 this._toolTipTextMenu.tooltip.style.opacity = "0";
             }
         }
-        let ctrlKey = e.ctrlKey;
+        this._linkClicked = "";
         if (e.button === 0 && ((!this.props.isSelected() && !e.ctrlKey) || (this.props.isSelected() && e.ctrlKey)) && !e.metaKey && e.target) {
             let href = (e.target as any).href;
             for (let parent = (e.target as any).parentNode; !href && parent; parent = parent.parentNode) {
                 href = parent.childNodes[0].href;
             }
-            if (href) {
-                if (href.indexOf(DocServer.prepend("/doc/")) === 0) {
-                    let docid = href.replace(DocServer.prepend("/doc/"), "").split("?")[0];
-                    DocServer.GetRefField(docid).then(f => {
-                        (f instanceof Doc) && DocumentManager.Instance.jumpToDocument(f, ctrlKey, document => this.props.addDocTab(document, "inTab"))
-                    });
-                }
+            if (href && href.indexOf(DocServer.prepend("/doc/")) === 0) {
+                this._linkClicked = href.replace(DocServer.prepend("/doc/"), "").split("?")[0];
                 e.stopPropagation();
                 e.preventDefault();
             }
-
         }
         if (e.button === 2 || (e.button === 0 && e.ctrlKey)) {
             this._gotDown = true;
@@ -257,6 +250,14 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
         if (this._toolTipTextMenu && this._toolTipTextMenu.tooltip) {
             this._toolTipTextMenu.tooltip.style.opacity = "1";
         }
+        let ctrlKey = e.ctrlKey;
+        if (this._linkClicked) {
+            DocServer.GetRefField(this._linkClicked).then(f => {
+                (f instanceof Doc) && DocumentManager.Instance.jumpToDocument(f, ctrlKey, document => this.props.addDocTab(document, "inTab"));
+            });
+            e.stopPropagation();
+            e.preventDefault();
+        }
         if (e.buttons === 1 && this.props.isSelected() && !e.altKey) {
             e.stopPropagation();
         }
@@ -280,6 +281,10 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
 
     onClick = (e: React.MouseEvent): void => {
         this._proseRef.current!.focus();
+        if (this._linkClicked) {
+            e.preventDefault();
+            e.stopPropagation();
+        }
     }
     onMouseDown = (e: React.MouseEvent): void => {
         if (!this.props.isSelected()) { // preventing default allows the onClick to be generated instead of being swallowed by the text box itself
@@ -363,7 +368,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
                 onPointerUp={this.onPointerUp}
                 onPointerDown={this.onPointerDown}
                 onMouseDown={this.onMouseDown}
-                onContextMenu={this.specificContextMenu}
                 // tfs: do we need this event handler
                 onWheel={this.onPointerWheel}
                 onPointerEnter={this.onPointerEnter}
-- 
cgit v1.2.3-70-g09d2


From e24bf03dd4edab2e5be2d73a6dc7f9c01fc5da85 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Wed, 5 Jun 2019 13:04:58 -0400
Subject: cleaned up handling of dropped urls and prosemirror clippings.

---
 src/client/views/collections/CollectionSubView.tsx | 23 ++++++++---
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 20 +--------
 src/client/views/nodes/FormattedTextBox.tsx        | 47 +++++++++++++++++-----
 3 files changed, 56 insertions(+), 34 deletions(-)

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

diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 31e662da5..06d77fec5 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -17,6 +17,7 @@ import { CollectionPDFView } from "./CollectionPDFView";
 import { CollectionVideoView } from "./CollectionVideoView";
 import { CollectionView } from "./CollectionView";
 import React = require("react");
+import { FormattedTextBox } from "../nodes/FormattedTextBox";
 
 export interface CollectionViewProps extends FieldViewProps {
     addDocument: (document: Doc, allowDuplicates?: boolean) => boolean;
@@ -166,11 +167,23 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
             e.stopPropagation();
             e.preventDefault();
 
-            if (html && html.indexOf(document.location.origin)) { // prosemirror text containing link to dash document
-                let start = html.indexOf(window.location.origin);
-                let path = html.substr(start, html.length - start);
-                let docid = path.substr(0, path.indexOf("\">")).replace(DocServer.prepend("/doc/"), "").split("?")[0];
-                DocServer.GetRefField(docid).then(f => (f instanceof Doc) && this.props.addDocument(f, false));
+            if (html && FormattedTextBox.IsFragment(html)) {
+                let href = FormattedTextBox.GetHref(html);
+                if (href) {
+                    let docid = FormattedTextBox.GetDocFromUrl(href);
+                    if (docid) { // prosemirror text containing link to dash document
+                        DocServer.GetRefField(docid).then(f => {
+                            if (f instanceof Doc) {
+                                if (options.x || options.y) { f.x = options.x; f.y = options.y; } // should be in CollectionFreeFormView
+                                (f instanceof Doc) && this.props.addDocument(f, false);
+                            }
+                        });
+                    } else {
+                        this.props.addDocument && this.props.addDocument(Docs.WebDocument(href, options));
+                    }
+                } else if (text) {
+                    this.props.addDocument && this.props.addDocument(Docs.TextDocument({ ...options, documentText: "@@@" + text }), false);
+                }
                 return;
             }
             if (html && html.indexOf("<img") !== 0 && !html.startsWith("<a")) {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 2b43c76c6..634b4dfa0 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -26,6 +26,7 @@ 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",
@@ -229,24 +230,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     @action
     onDrop = (e: React.DragEvent): void => {
         var pt = this.getTransform().transformPoint(e.pageX, e.pageY);
-        let html = e.dataTransfer.getData("text/html");
-        if (html && html.indexOf(document.location.origin)) {  // prosemirror text containing link to dash document
-            e.stopPropagation();
-            e.preventDefault();
-            let start = html.indexOf(window.location.origin);
-            let path = html.substr(start, html.length - start);
-            let docid = path.substr(0, path.indexOf("\">")).replace(DocServer.prepend("/doc/"), "").split("?")[0];
-            DocServer.GetRefField(docid).then(f => {
-                if (f instanceof Doc) {
-                    f.x = pt[0];
-                    f.y = pt[1];
-                    (f instanceof Doc) && this.props.addDocument(f, false);
-                }
-            });
-            return;
-        } else {
-            super.onDrop(e, { x: pt[0], y: pt[1] });
-        }
+        super.onDrop(e, { x: pt[0], y: pt[1] });
     }
 
     onDragOver = (): void => {
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 9eef38e0a..478e7ce93 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -12,7 +12,7 @@ import { RichTextField } from "../../../new_fields/RichTextField";
 import { createSchema, makeInterface } from "../../../new_fields/Schema";
 import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
 import { DocServer } from "../../DocServer";
-import { DocUtils } from '../../documents/Documents';
+import { DocUtils, Docs } from '../../documents/Documents';
 import { DocumentManager } from "../../util/DocumentManager";
 import { DragManager } from "../../util/DragManager";
 import buildKeymap from "../../util/ProsemirrorKeymap";
@@ -27,6 +27,7 @@ import { InkingControl } from "../InkingControl";
 import { FieldView, FieldViewProps } from "./FieldView";
 import "./FormattedTextBox.scss";
 import React = require("react");
+import { Id } from '../../../new_fields/FieldSymbols';
 
 library.add(faEdit);
 library.add(faSmile);
@@ -68,15 +69,40 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
     private _ref: React.RefObject<HTMLDivElement>;
     private _proseRef: React.RefObject<HTMLDivElement>;
     private _editorView: Opt<EditorView>;
-    private _gotDown: boolean = false;
+    private _toolTipTextMenu: TooltipTextMenu | undefined = undefined;
+    private _lastState: any = undefined;
+    private _applyingChange: boolean = false;
     private _dropDisposer?: DragManager.DragDropDisposer;
+    private _linkClicked = "";
     private _reactionDisposer: Opt<IReactionDisposer>;
     private _inputReactionDisposer: Opt<IReactionDisposer>;
     private _proxyReactionDisposer: Opt<IReactionDisposer>;
     public get CurrentDiv(): HTMLDivElement { return this._ref.current!; }
+    @observable _entered = false;
 
     @observable public static InputBoxOverlay?: FormattedTextBox = undefined;
     public static InputBoxOverlayScroll: number = 0;
+    public static IsFragment(html: string) {
+        return html.indexOf("data-pm-slice") !== -1;
+    }
+    public static GetHref(html: string): string {
+        let parser = new DOMParser();
+        let parsedHtml = parser.parseFromString(html, 'text/html');
+        if (parsedHtml.body.childNodes.length === 1 && parsedHtml.body.childNodes[0].childNodes.length === 1 &&
+            (parsedHtml.body.childNodes[0].childNodes[0] as any).href) {
+            return (parsedHtml.body.childNodes[0].childNodes[0] as any).href;
+        }
+        return "";
+    }
+    public static GetDocFromUrl(url: string) {
+        if (url.startsWith(document.location.origin)) {
+            let start = url.indexOf(window.location.origin);
+            let path = url.substr(start, url.length - start);
+            let docid = path.replace(DocServer.prepend("/doc/"), "").split("?")[0];
+            return docid;
+        }
+        return "";
+    }
 
     constructor(props: FieldViewProps) {
         super(props);
@@ -88,9 +114,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
         }
     }
 
-    _applyingChange: boolean = false;
 
-    _lastState: any = undefined;
     dispatchTransaction = (tx: Transaction) => {
         if (this._editorView) {
             const state = this._lastState = this._editorView.state.apply(tx);
@@ -221,7 +245,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
         }
     }
 
-    _linkClicked = "";
     onPointerDown = (e: React.PointerEvent): void => {
         if (e.button === 0 && this.props.isSelected() && !e.altKey && !e.ctrlKey && !e.metaKey) {
             e.stopPropagation();
@@ -235,14 +258,19 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
             for (let parent = (e.target as any).parentNode; !href && parent; parent = parent.parentNode) {
                 href = parent.childNodes[0].href;
             }
-            if (href && href.indexOf(DocServer.prepend("/doc/")) === 0) {
-                this._linkClicked = href.replace(DocServer.prepend("/doc/"), "").split("?")[0];
+            if (href) {
+                if (href.indexOf(DocServer.prepend("/doc/")) === 0) {
+                    this._linkClicked = href.replace(DocServer.prepend("/doc/"), "").split("?")[0];
+                } else {
+                    let webDoc = Docs.WebDocument(href, { x: NumCast(this.props.Document.x, 0) + NumCast(this.props.Document.width, 0), y: NumCast(this.props.Document.y) });
+                    this.props.addDocument && this.props.addDocument(webDoc);
+                    this._linkClicked = webDoc[Id];
+                }
                 e.stopPropagation();
                 e.preventDefault();
             }
         }
         if (e.button === 2 || (e.button === 0 && e.ctrlKey)) {
-            this._gotDown = true;
             e.preventDefault();
         }
     }
@@ -302,7 +330,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
         });
     }
 
-    _toolTipTextMenu: TooltipTextMenu | undefined = undefined;
     tooltipLinkingMenuPlugin() {
         let myprops = this.props;
         return new Plugin({
@@ -338,8 +365,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
         }
     }
 
-    @observable
-    _entered = false;
     @action
     onPointerEnter = (e: React.PointerEvent) => {
         this._entered = true;
-- 
cgit v1.2.3-70-g09d2


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/util/DragManager.ts              |  1 +
 src/client/views/MainOverlayTextBox.tsx     |  2 +-
 src/client/views/Templates.tsx              | 48 +++++++++++++++++------------
 src/client/views/nodes/DocumentView.tsx     | 16 ++++++++--
 src/client/views/nodes/FormattedTextBox.tsx | 15 ++++++---
 5 files changed, 55 insertions(+), 27 deletions(-)

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

diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 32476b785..4c9f798a8 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -269,6 +269,7 @@ export namespace DragManager {
         let lastX = downX;
         let lastY = downY;
         const moveHandler = (e: PointerEvent) => {
+            e.preventDefault(); // required or dragging text menu link item ends up dragging the link button as native drag/drop
             if (dragData instanceof DocumentDragData) {
                 dragData.userDropAction = e.ctrlKey || e.altKey ? "alias" : undefined;
             }
diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx
index d1224febe..6bbd70a25 100644
--- a/src/client/views/MainOverlayTextBox.tsx
+++ b/src/client/views/MainOverlayTextBox.tsx
@@ -96,7 +96,7 @@ export class MainOverlayTextBox extends React.Component<MainOverlayTextBoxProps>
             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` }}>
-                    <FormattedTextBox fieldKey={this._textFieldKey} hideOnLeave={this._textHideOnLeave} isOverlay={true} Document={FormattedTextBox.InputBoxOverlay.props.Document} isSelected={returnTrue} select={emptyFunction} isTopMost={true}
+                    <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} />
                 </div>
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; }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index ff2b9842f..85b8a5596 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1,6 +1,6 @@
 import { library } from '@fortawesome/fontawesome-svg-core';
 import { faAlignCenter, faCaretSquareRight, faCompressArrowsAlt, faExpandArrowsAlt, faLayerGroup, faSquare, faTrash, faConciergeBell, faFolder, faMapPin, faLink, faFingerprint, faCrosshairs, faDesktop } from '@fortawesome/free-solid-svg-icons';
-import { action, computed, IReactionDisposer, reaction, trace } from "mobx";
+import { action, computed, IReactionDisposer, reaction, trace, observable } from "mobx";
 import { observer } from "mobx-react";
 import { Doc, DocListCast, HeightSym, Opt, WidthSym, DocListCastAsync } from "../../../new_fields/Doc";
 import { List } from "../../../new_fields/List";
@@ -123,6 +123,12 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     set templates(templates: List<string>) { this.props.Document.templates = templates; }
     screenRect = (): ClientRect | DOMRect => this._mainCont.current ? this._mainCont.current.getBoundingClientRect() : new DOMRect();
 
+    constructor(props: DocumentViewProps) {
+        super(props);
+        this.selectOnLoad = props.selectOnLoad;
+    }
+
+
     _reactionDisposer?: IReactionDisposer;
     @action
     componentDidMount() {
@@ -429,11 +435,15 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     onPointerLeave = (e: React.PointerEvent): void => { this.props.Document.libraryBrush = false; };
 
     isSelected = () => SelectionManager.IsSelected(this);
-    select = (ctrlPressed: boolean) => SelectionManager.SelectDoc(this, ctrlPressed);
+    @action select = (ctrlPressed: boolean) => { this.selectOnLoad = false; SelectionManager.SelectDoc(this, ctrlPressed); }
 
+    @observable selectOnLoad: boolean = false;
     @computed get nativeWidth() { return this.Document.nativeWidth || 0; }
     @computed get nativeHeight() { return this.Document.nativeHeight || 0; }
-    @computed get contents() { return (<DocumentContentsView {...this.props} isSelected={this.isSelected} select={this.select} layoutKey={"layout"} />); }
+    @computed get contents() {
+        return (
+            <DocumentContentsView {...this.props} isSelected={this.isSelected} select={this.select} selectOnLoad={this.selectOnLoad} layoutKey={"layout"} />);
+    }
 
     render() {
         var scaling = this.props.ContentScaling();
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 478e7ce93..559a9fbfc 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -52,6 +52,8 @@ library.add(faSmile);
 export interface FormattedTextBoxProps {
     isOverlay?: boolean;
     hideOnLeave?: boolean;
+    height?: string;
+    color?: string;
 }
 
 const richTextSchema = createSchema({
@@ -206,6 +208,11 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
 
     private setupEditor(config: any, doc?: Doc) {
         let field = doc ? Cast(doc[this.props.fieldKey], RichTextField) : undefined;
+        let startup = StrCast(this.props.Document.documentText);
+        startup = startup.startsWith("@@@") ? startup.replace("@@@", "") : "";
+        if (!startup && !field && doc) {
+            startup = StrCast(doc[this.props.fieldKey]);
+        }
         if (this._proseRef.current) {
             this._editorView = new EditorView(this._proseRef.current, {
                 state: field && field.Data ? EditorState.fromJSON(config, JSON.parse(field.Data)) : EditorState.create(config),
@@ -214,10 +221,9 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
                     image(node, view, getPos) { return new ImageResizeView(node, view, getPos); }
                 }
             });
-            let text = StrCast(this.props.Document.documentText);
-            if (text.startsWith("@@@")) {
+            if (startup) {
                 this.props.Document.proto!.documentText = undefined;
-                this._editorView.dispatch(this._editorView.state.tr.insertText(text.replace("@@@", "")));
+                this._editorView.dispatch(this._editorView.state.tr.insertText(startup));
             }
         }
 
@@ -380,9 +386,10 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
         return (
             <div className={`formattedTextBox-cont-${style}`} ref={this._ref}
                 style={{
+                    height: this.props.height ? this.props.height : undefined,
                     background: this.props.hideOnLeave ? "rgba(0,0,0,0.4)" : undefined,
                     opacity: this.props.hideOnLeave ? (this._entered || this.props.isSelected() || this.props.Document.libraryBrush ? 1 : 0.1) : 1,
-                    color: this.props.hideOnLeave ? "white" : "initial",
+                    color: this.props.color ? this.props.color : this.props.hideOnLeave ? "white" : "initial",
                     pointerEvents: interactive ? "all" : "none",
                 }}
                 // onKeyDown={this.onKeyPress}
-- 
cgit v1.2.3-70-g09d2


From df9aef6a2026a05c02c9b6b4b1e0a7b10b4ba244 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Mon, 10 Jun 2019 13:48:04 -0400
Subject: fixed text overlay from lingering

---
 src/client/views/MainOverlayTextBox.tsx     | 20 ++++++++++++++------
 src/client/views/nodes/FormattedTextBox.tsx | 18 +++++++++++-------
 2 files changed, 25 insertions(+), 13 deletions(-)

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

diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx
index 0eb3e9707..a0359419b 100644
--- a/src/client/views/MainOverlayTextBox.tsx
+++ b/src/client/views/MainOverlayTextBox.tsx
@@ -17,11 +17,12 @@ interface MainOverlayTextBoxProps {
 export class MainOverlayTextBox extends React.Component<MainOverlayTextBoxProps> {
     public static Instance: MainOverlayTextBox;
     @observable _textXf: () => Transform = () => Transform.Identity();
-    private _textFieldKey: string = "data";
+    public TextFieldKey: string = "data";
     private _textColor: string | null = null;
     private _textHideOnLeave?: boolean;
     private _textTargetDiv: HTMLDivElement | undefined;
     private _textProxyDiv: React.RefObject<HTMLDivElement>;
+    public TextDoc?: Doc;
 
     constructor(props: MainOverlayTextBoxProps) {
         super(props);
@@ -29,9 +30,16 @@ export class MainOverlayTextBox extends React.Component<MainOverlayTextBoxProps>
         MainOverlayTextBox.Instance = this;
         reaction(() => FormattedTextBox.InputBoxOverlay,
             (box?: FormattedTextBox) => {
-                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();
+                if (box) {
+                    this.TextDoc = box.props.Document;
+                    let sxf = Utils.GetScreenTransform(box ? box.CurrentDiv : undefined);
+                    let xf = () => { box.props.ScreenToLocalTransform(); return new Transform(-sxf.translateX, -sxf.translateY, 1 / sxf.scale); };
+                    this.setTextDoc(box.props.fieldKey, box.CurrentDiv, xf)
+                }
+                else {
+                    this.TextDoc = undefined;
+                    this.setTextDoc();
+                }
             });
     }
 
@@ -40,7 +48,7 @@ export class MainOverlayTextBox extends React.Component<MainOverlayTextBoxProps>
         if (this._textTargetDiv) {
             this._textTargetDiv.style.color = this._textColor;
         }
-        this._textFieldKey = textFieldKey!;
+        this.TextFieldKey = textFieldKey!;
         this._textXf = tx ? tx : () => Transform.Identity();
         this._textTargetDiv = div;
         this._textHideOnLeave = FormattedTextBox.InputBoxOverlay && FormattedTextBox.InputBoxOverlay.props.hideOnLeave;
@@ -98,7 +106,7 @@ export class MainOverlayTextBox extends React.Component<MainOverlayTextBoxProps>
             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: 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}
+                    <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} />
                 </div>
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 559a9fbfc..4325fd48c 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -28,6 +28,7 @@ import { FieldView, FieldViewProps } from "./FieldView";
 import "./FormattedTextBox.scss";
 import React = require("react");
 import { Id } from '../../../new_fields/FieldSymbols';
+import { MainOverlayTextBox } from '../MainOverlayTextBox';
 
 library.add(faEdit);
 library.add(faSmile);
@@ -181,7 +182,9 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
                     if (this._editorView) {
                         this._editorView.destroy();
                     }
-                    this.setupEditor(config, this.props.Document);// MainOverlayTextBox.Instance.TextDoc); // bcz: not sure why, but the order of events is such that this.props.Document hasn't updated yet, so without forcing the editor to the MainOverlayTextBox, it will display the previously focused textbox
+                    this.setupEditor(config, // bcz: not sure why, but the order of events is such that this.props.Document hasn't updated yet, so without forcing the editor to the MainOverlayTextBox, it will display the previously focused textbox
+                        MainOverlayTextBox.Instance.TextDoc ? MainOverlayTextBox.Instance.TextDoc : this.props.Document,
+                        MainOverlayTextBox.Instance.TextFieldKey ? MainOverlayTextBox.Instance.TextFieldKey : this.props.fieldKey);
                 }
             );
         } else {
@@ -203,15 +206,15 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
             field => field && this._editorView && !this._applyingChange &&
                 this._editorView.updateState(EditorState.fromJSON(config, JSON.parse(field)))
         );
-        this.setupEditor(config, this.props.Document);
+        this.setupEditor(config, this.props.Document, this.props.fieldKey);
     }
 
-    private setupEditor(config: any, doc?: Doc) {
-        let field = doc ? Cast(doc[this.props.fieldKey], RichTextField) : undefined;
-        let startup = StrCast(this.props.Document.documentText);
+    private setupEditor(config: any, doc: Doc, fieldKey: string) {
+        let field = doc ? Cast(doc[fieldKey], RichTextField) : undefined;
+        let startup = StrCast(doc.documentText);
         startup = startup.startsWith("@@@") ? startup.replace("@@@", "") : "";
         if (!startup && !field && doc) {
-            startup = StrCast(doc[this.props.fieldKey]);
+            startup = StrCast(doc[fieldKey]);
         }
         if (this._proseRef.current) {
             this._editorView = new EditorView(this._proseRef.current, {
@@ -222,12 +225,13 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
                 }
             });
             if (startup) {
-                this.props.Document.proto!.documentText = undefined;
+                Doc.GetProto(doc).documentText = undefined;
                 this._editorView.dispatch(this._editorView.state.tr.insertText(startup));
             }
         }
 
         if (this.props.selectOnLoad) {
+            console.log("Sel on load " + this.props.Document.title + " " + doc!.title);
             this.props.select(false);
             this._editorView!.focus();
         }
-- 
cgit v1.2.3-70-g09d2


From 06d5bb5c65da6f4a115ebf8118989115420bccef Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Tue, 11 Jun 2019 10:21:42 -0400
Subject: cleaned up some drop() code with text.  fixed linkview titling. 
 changed dragging to not deselect source collection.

---
 src/client/util/SelectionManager.ts                | 23 ++++++++++++++++------
 .../views/collections/CollectionBaseView.tsx       |  5 +++--
 .../CollectionFreeFormLinkView.tsx                 |  5 +++--
 src/client/views/nodes/FormattedTextBox.tsx        | 22 ---------------------
 4 files changed, 23 insertions(+), 32 deletions(-)

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

diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index ddad4b818..b26032b04 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -10,15 +10,23 @@ export namespace SelectionManager {
         @observable SelectedDocuments: Array<DocumentView> = [];
 
         @action
-        SelectDoc(doc: DocumentView, ctrlPressed: boolean): void {
+        SelectDoc(docView: DocumentView, ctrlPressed: boolean): void {
             // if doc is not in SelectedDocuments, add it
             if (!ctrlPressed) {
                 this.DeselectAll();
             }
 
-            if (manager.SelectedDocuments.indexOf(doc) === -1) {
-                manager.SelectedDocuments.push(doc);
-                doc.props.whenActiveChanged(true);
+            if (manager.SelectedDocuments.indexOf(docView) === -1) {
+                manager.SelectedDocuments.push(docView);
+                docView.props.whenActiveChanged(true);
+            }
+        }
+        @action
+        DeselectDoc(docView: DocumentView): void {
+            let ind = manager.SelectedDocuments.indexOf(docView);
+            if (ind !== -1) {
+                manager.SelectedDocuments.splice(ind, 1);
+                docView.props.whenActiveChanged(false);
             }
         }
         @action
@@ -31,8 +39,11 @@ export namespace SelectionManager {
 
     const manager = new Manager();
 
-    export function SelectDoc(doc: DocumentView, ctrlPressed: boolean): void {
-        manager.SelectDoc(doc, ctrlPressed);
+    export function DeselectDoc(docView: DocumentView): void {
+        manager.DeselectDoc(docView);
+    }
+    export function SelectDoc(docView: DocumentView, ctrlPressed: boolean): void {
+        manager.SelectDoc(docView, ctrlPressed);
     }
 
     export function IsSelected(doc: DocumentView): boolean {
diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx
index d120c3a0c..5238ad114 100644
--- a/src/client/views/collections/CollectionBaseView.tsx
+++ b/src/client/views/collections/CollectionBaseView.tsx
@@ -10,6 +10,7 @@ import { SelectionManager } from '../../util/SelectionManager';
 import { ContextMenu } from '../ContextMenu';
 import { FieldViewProps } from '../nodes/FieldView';
 import './CollectionBaseView.scss';
+import { DocumentManager } from '../../util/DocumentManager';
 
 export enum CollectionViewType {
     Invalid,
@@ -129,7 +130,8 @@ export class CollectionBaseView extends React.Component<CollectionViewProps> {
 
     @action.bound
     removeDocument(doc: Doc): boolean {
-        SelectionManager.DeselectAll();
+        let docView = DocumentManager.Instance.getDocumentView(doc, this.props.ContainingCollectionView)
+        docView && SelectionManager.DeselectDoc(docView);
         const props = this.props;
         //TODO This won't create the field if it doesn't already exist
         const value = Cast(props.Document[props.fieldKey], listSpec(Doc), []);
@@ -163,7 +165,6 @@ export class CollectionBaseView extends React.Component<CollectionViewProps> {
             return true;
         }
         if (this.removeDocument(doc)) {
-            SelectionManager.DeselectAll();
             return addDocument(doc);
         }
         return false;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
index ca7c99f28..ba7e6cf9e 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -44,8 +44,9 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
         let x2 = NumCast(b.x) + (BoolCast(b.isMinimized, false) ? 5 : NumCast(b.width) / NumCast(b.zoomBasis, 1) / 2);
         let y2 = NumCast(b.y) + (BoolCast(b.isMinimized, false) ? 5 : NumCast(b.height) / NumCast(b.zoomBasis, 1) / 2);
         let text = "";
-        this.props.LinkDocs.map(l => text += StrCast(l.title) + "(" + StrCast(l.linkDescription) + "), ");
-        text = text.substr(0, text.length - 2);
+        let first = this.props.LinkDocs[0];
+        if (this.props.LinkDocs.length === 1) text += first.title + (first.linkDescription ? "(" + StrCast(first.linkDescription) + ")" : "");
+        else text = "-multiple-";
         return (
             <>
                 <line key="linkLine" className="collectionfreeformlinkview-linkLine"
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 4325fd48c..2923fd378 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -75,7 +75,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
     private _toolTipTextMenu: TooltipTextMenu | undefined = undefined;
     private _lastState: any = undefined;
     private _applyingChange: boolean = false;
-    private _dropDisposer?: DragManager.DragDropDisposer;
     private _linkClicked = "";
     private _reactionDisposer: Opt<IReactionDisposer>;
     private _inputReactionDisposer: Opt<IReactionDisposer>;
@@ -136,25 +135,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
         }
     }
 
-    @undoBatch
-    @action
-    drop = async (e: Event, de: DragManager.DropEvent) => {
-        if (de.data instanceof DragManager.LinkDragData) {
-            let sourceDoc = de.data.linkSourceDocument;
-            let destDoc = this.props.Document;
-
-            DocUtils.MakeLink(sourceDoc, destDoc);
-            de.data.droppedDocuments.push(destDoc);
-            e.stopPropagation();
-        }
-    }
-
     componentDidMount() {
-        if (this._ref.current) {
-            this._dropDisposer = DragManager.MakeDropTarget(this._ref.current, {
-                handlers: { drop: this.drop.bind(this) }
-            });
-        }
         const config = {
             schema,
             inpRules, //these currently don't do anything, but could eventually be helpful
@@ -250,9 +231,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
         if (this._proxyReactionDisposer) {
             this._proxyReactionDisposer();
         }
-        if (this._dropDisposer) {
-            this._dropDisposer();
-        }
     }
 
     onPointerDown = (e: React.PointerEvent): void => {
-- 
cgit v1.2.3-70-g09d2


From fcae0da16f9413059d03638ba10ab30cdc460a42 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Tue, 11 Jun 2019 16:45:48 -0400
Subject: fixed text input to allow typing from the bottom (caption) and to
 allow text boxes to grow vertically (autoHeight)

---
 src/client/documents/Documents.ts                  |  2 +-
 src/client/views/DocumentDecorations.tsx           |  7 +++---
 src/client/views/MainOverlayTextBox.tsx            | 22 ++++++++++++------
 .../collectionFreeForm/CollectionFreeFormView.scss |  1 +
 .../collections/collectionFreeForm/MarqueeView.tsx |  3 ++-
 src/client/views/nodes/DocumentView.tsx            |  8 +++----
 src/client/views/nodes/FormattedTextBox.tsx        | 27 +++++++++++++++++++---
 7 files changed, 51 insertions(+), 19 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 2ae127e21..b1df89dbd 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -166,7 +166,7 @@ export namespace Docs {
     }
     function CreateTextPrototype(): Doc {
         let textProto = setupPrototypeOptions(textProtoId, "TEXT_PROTO", FormattedTextBox.LayoutString(),
-            { x: 0, y: 0, width: 300, height: 150, backgroundColor: "#f1efeb" });
+            { x: 0, y: 0, width: 300, backgroundColor: "#f1efeb" });
         return textProto;
     }
     function CreatePdfPrototype(): Doc {
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 7260b00cf..1111cd2f5 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -442,11 +442,11 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                 let actualdH = Math.max(height + (dH * scale), 20);
                 doc.x = (doc.x || 0) + dX * (actualdW - width);
                 doc.y = (doc.y || 0) + dY * (actualdH - height);
-                let proto = Doc.GetProto(doc);
+                let proto = Doc.GetProto(element.props.Document);
                 let fixedAspect = e.ctrlKey || (!BoolCast(proto.ignoreAspect, false) && nwidth && nheight);
                 if (fixedAspect && (!nwidth || !nheight)) {
-                    proto.nativeWidth = doc.width;
-                    proto.nativeHeight = doc.height;
+                    proto.nativeWidth = nwidth = doc.width || 0;
+                    proto.nativeHeight = nheight = doc.height || 0;
                     proto.ignoreAspect = true;
                 }
                 if (nwidth > 0 && nheight > 0) {
@@ -469,6 +469,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                 } else {
                     doc.width = zoomBasis * actualdW;
                     doc.height = zoomBasis * actualdH;
+                    proto.autoHeight = undefined;
                 }
             }
         });
diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx
index a0359419b..afa72d56e 100644
--- a/src/client/views/MainOverlayTextBox.tsx
+++ b/src/client/views/MainOverlayTextBox.tsx
@@ -9,6 +9,8 @@ import "./MainOverlayTextBox.scss";
 import { FormattedTextBox } from './nodes/FormattedTextBox';
 import { CollectionDockingView } from './collections/CollectionDockingView';
 import { Doc } from '../../new_fields/Doc';
+import { BoolCast } from '../../new_fields/Types';
+import { auto } from 'async';
 
 interface MainOverlayTextBoxProps {
 }
@@ -22,6 +24,7 @@ export class MainOverlayTextBox extends React.Component<MainOverlayTextBoxProps>
     private _textHideOnLeave?: boolean;
     private _textTargetDiv: HTMLDivElement | undefined;
     private _textProxyDiv: React.RefObject<HTMLDivElement>;
+    private _textBottom: boolean | undefined;
     public TextDoc?: Doc;
 
     constructor(props: MainOverlayTextBoxProps) {
@@ -49,10 +52,12 @@ export class MainOverlayTextBox extends React.Component<MainOverlayTextBoxProps>
             this._textTargetDiv.style.color = this._textColor;
         }
         this.TextFieldKey = textFieldKey!;
-        this._textXf = tx ? tx : () => Transform.Identity();
+        let txf = tx ? tx : () => Transform.Identity();
+        this._textXf = txf;
         this._textTargetDiv = div;
         this._textHideOnLeave = FormattedTextBox.InputBoxOverlay && FormattedTextBox.InputBoxOverlay.props.hideOnLeave;
         if (div) {
+            this._textBottom = textFieldKey === "caption" ? true : false; // (getComputedStyle(div) as any).bottom;
             this._textColor = (getComputedStyle(div) as any).color;
             div.style.color = "transparent";
         }
@@ -102,13 +107,16 @@ 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" }} >
+            let bottom = this._textBottom ? textRect.bottom : textRect.top;
+            let hgt = 0;
+            return <div className="mainOverlayTextBox-textInput" style={{ transform: `translate(${textRect.left}px, ${bottom}px) scale(${1 / s},${1 / s})`, width: "auto", height: hgt }} >
                 <div className="mainOverlayTextBox-textInput" onPointerDown={this.textBoxDown} ref={this._textProxyDiv} onScroll={this.textScroll}
-                    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} />
+                    style={{ width: `${textRect.width * s}px`, height: hgt }}>
+                    <div style={{ height: "auto", width: "100%", position: "absolute", bottom: this._textBottom ? "0px" : undefined }}>
+                        <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} />
+                    </div>
                 </div>
             </ div>;
         }
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
index e10ba9d7e..5ac2e1f9c 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
@@ -57,6 +57,7 @@
     }
     
     >.jsx-parser {
+        position:absolute;
         z-index:0;
     }
 
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index c699b3437..01bbbba4c 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -93,7 +93,8 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
                 }
             });
         } else if (!e.ctrlKey) {
-            let newBox = Docs.TextDocument({ width: 200, height: 100, x: x, y: y, title: "-typed text-" });
+            let newBox = Docs.TextDocument({ width: 200, height: 30, x: x, y: y, title: "-typed text-" });
+            newBox.proto!.autoHeight = true;
             this.props.addLiveTextDocument(newBox);
         }
         e.stopPropagation();
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 19f5c7d36..2428103d1 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -317,13 +317,13 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     makeBtnClicked = (): void => {
         let doc = Doc.GetProto(this.props.Document);
         doc.isButton = !BoolCast(doc.isButton, false);
-        if (StrCast(doc.layout).indexOf("Formatted") !== -1) { // only need to freeze the dimensions of text boxes since they don't have a native width and height naturally
-            if (doc.isButton && !doc.nativeWidth) {
+        if (doc.isButton) {
+            if (!doc.nativeWidth) {
                 doc.nativeWidth = this.props.Document[WidthSym]();
                 doc.nativeHeight = this.props.Document[HeightSym]();
-            } else {
-                doc.nativeWidth = doc.nativeHeight = undefined;
             }
+        } else {
+            doc.nativeWidth = doc.nativeHeight = undefined;
         }
     }
     fullScreenClicked = (): void => {
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 2923fd378..20e175031 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -10,7 +10,7 @@ import { EditorView } from "prosemirror-view";
 import { Doc, Opt } from "../../../new_fields/Doc";
 import { RichTextField } from "../../../new_fields/RichTextField";
 import { createSchema, makeInterface } from "../../../new_fields/Schema";
-import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
+import { Cast, NumCast, StrCast, BoolCast } from "../../../new_fields/Types";
 import { DocServer } from "../../DocServer";
 import { DocUtils, Docs } from '../../documents/Documents';
 import { DocumentManager } from "../../util/DocumentManager";
@@ -29,6 +29,9 @@ import "./FormattedTextBox.scss";
 import React = require("react");
 import { Id } from '../../../new_fields/FieldSymbols';
 import { MainOverlayTextBox } from '../MainOverlayTextBox';
+import { Utils } from '../../../Utils';
+import { ContextMenuProps } from '../ContextMenuItem';
+import { ContextMenu } from '../ContextMenu';
 
 library.add(faEdit);
 library.add(faSmile);
@@ -212,8 +215,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
         }
 
         if (this.props.selectOnLoad) {
-            console.log("Sel on load " + this.props.Document.title + " " + doc!.title);
-            this.props.select(false);
+            //this.props.select(false);
             this._editorView!.focus();
         }
     }
@@ -351,6 +353,15 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
         if (!this._undoTyping) {
             this._undoTyping = UndoManager.StartBatch("undoTyping");
         }
+        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);
+            let nh = NumCast(this.props.Document.nativeHeight, 0);
+            let dh = NumCast(this.props.Document.height, 0);
+            let sh = scrBounds.height;
+            this.props.Document.height = nh ? dh / nh * sh : sh;
+            this.props.Document.proto!.nativeHeight = nh ? sh : undefined;
+        }
     }
 
     @action
@@ -361,6 +372,15 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
     onPointerLeave = (e: React.PointerEvent) => {
         this._entered = false;
     }
+
+    specificContextMenu = (e: React.MouseEvent): void => {
+        let subitems: ContextMenuProps[] = [];
+        subitems.push({
+            description: BoolCast(this.props.Document.autoHeight, false) ? "Manual Height" : "Auto Height",
+            event: action(() => this.props.Document.autoHeight = !BoolCast(this.props.Document.autoHeight, false)), icon: "expand-arrows-alt"
+        });
+        ContextMenu.Instance.addItem({ description: "Text Funcs...", subitems: subitems });
+    }
     render() {
         let style = this.props.isOverlay ? "scroll" : "hidden";
         let rounded = NumCast(this.props.Document.borderRounding) < 0 ? "-rounded" : "";
@@ -378,6 +398,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
                 onKeyPress={this.onKeyPress}
                 onFocus={this.onFocused}
                 onClick={this.onClick}
+                onContextMenu={this.specificContextMenu}
                 onBlur={this.onBlur}
                 onPointerUp={this.onPointerUp}
                 onPointerDown={this.onPointerDown}
-- 
cgit v1.2.3-70-g09d2


From a638c12cde39a3ea5193a8038f72a55d706d9af8 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Wed, 12 Jun 2019 10:32:45 -0400
Subject: a bunch of cleanup and fixes to formattedtextbox & mainoverlaytextbox

---
 src/client/util/SelectionManager.ts                |  8 +--
 src/client/views/MainOverlayTextBox.tsx            | 16 +++---
 src/client/views/collections/CollectionSubView.tsx |  2 +-
 src/client/views/nodes/DocumentView.tsx            |  7 +--
 src/client/views/nodes/FormattedTextBox.tsx        | 60 +++++-----------------
 5 files changed, 28 insertions(+), 65 deletions(-)

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

diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index b26032b04..09bccb1a0 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -12,11 +12,11 @@ export namespace SelectionManager {
         @action
         SelectDoc(docView: DocumentView, ctrlPressed: boolean): void {
             // if doc is not in SelectedDocuments, add it
-            if (!ctrlPressed) {
-                this.DeselectAll();
-            }
-
             if (manager.SelectedDocuments.indexOf(docView) === -1) {
+                if (!ctrlPressed) {
+                    this.DeselectAll();
+                }
+
                 manager.SelectedDocuments.push(docView);
                 docView.props.whenActiveChanged(true);
             }
diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx
index 1b35fd40e..23e90ece5 100644
--- a/src/client/views/MainOverlayTextBox.tsx
+++ b/src/client/views/MainOverlayTextBox.tsx
@@ -1,15 +1,15 @@
 import { action, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
+import "normalize.css";
 import * as React from 'react';
+import { Doc } from '../../new_fields/Doc';
+import { BoolCast } from '../../new_fields/Types';
 import { emptyFunction, returnTrue, returnZero, Utils } from '../../Utils';
 import { DragManager } from '../util/DragManager';
 import { Transform } from '../util/Transform';
-import "normalize.css";
+import { CollectionDockingView } from './collections/CollectionDockingView';
 import "./MainOverlayTextBox.scss";
 import { FormattedTextBox } from './nodes/FormattedTextBox';
-import { CollectionDockingView } from './collections/CollectionDockingView';
-import { Doc } from '../../new_fields/Doc';
-import { BoolCast } from '../../new_fields/Types';
 
 interface MainOverlayTextBoxProps {
 }
@@ -25,7 +25,7 @@ export class MainOverlayTextBox extends React.Component<MainOverlayTextBoxProps>
     private _textProxyDiv: React.RefObject<HTMLDivElement>;
     private _textBottom: boolean | undefined;
     private _textAutoHeight: boolean | undefined;
-    public TextDoc?: Doc;
+    @observable public TextDoc?: Doc;
 
     constructor(props: MainOverlayTextBoxProps) {
         super(props);
@@ -105,6 +105,7 @@ export class MainOverlayTextBox extends React.Component<MainOverlayTextBoxProps>
         }
     }
     render() {
+        this.TextDoc;
         if (FormattedTextBox.InputBoxOverlay && this._textTargetDiv) {
             let textRect = this._textTargetDiv.getBoundingClientRect();
             let s = this._textXf().Scale;
@@ -114,8 +115,9 @@ export class MainOverlayTextBox extends React.Component<MainOverlayTextBoxProps>
                 <div className="mainOverlayTextBox-textInput" onPointerDown={this.textBoxDown} ref={this._textProxyDiv} onScroll={this.textScroll}
                     style={{ width: `${textRect.width * s}px`, height: "0px" }}>
                     <div style={{ height: hgt, width: "100%", position: "absolute", bottom: this._textBottom ? "0px" : undefined }}>
-                        <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}
+                        <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} />
                     </div>
                 </div>
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 762955a08..93a1a8cda 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -170,7 +170,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
                         this.props.addDocument && this.props.addDocument(Docs.WebDocument(href, options));
                     }
                 } else if (text) {
-                    this.props.addDocument && this.props.addDocument(Docs.TextDocument({ ...options, documentText: "@@@" + text }), false);
+                    this.props.addDocument && this.props.addDocument(Docs.TextDocument({ ...options, width: 100, height: 25, documentText: "@@@" + text }), false);
                 }
                 return;
             }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 2428103d1..051940cc4 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -125,10 +125,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
     constructor(props: DocumentViewProps) {
         super(props);
-        this.selectOnLoad = props.selectOnLoad;
     }
 
-
     _reactionDisposer?: IReactionDisposer;
     @action
     componentDidMount() {
@@ -442,14 +440,13 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     onPointerLeave = (e: React.PointerEvent): void => { this.props.Document.libraryBrush = false; };
 
     isSelected = () => SelectionManager.IsSelected(this);
-    @action select = (ctrlPressed: boolean) => { this.selectOnLoad = false; SelectionManager.SelectDoc(this, ctrlPressed); }
+    @action select = (ctrlPressed: boolean) => { SelectionManager.SelectDoc(this, ctrlPressed); }
 
-    @observable selectOnLoad: boolean = false;
     @computed get nativeWidth() { return this.Document.nativeWidth || 0; }
     @computed get nativeHeight() { return this.Document.nativeHeight || 0; }
     @computed get contents() {
         return (
-            <DocumentContentsView {...this.props} isSelected={this.isSelected} select={this.select} selectOnLoad={this.selectOnLoad} layoutKey={"layout"} />);
+            <DocumentContentsView {...this.props} isSelected={this.isSelected} select={this.select} selectOnLoad={this.props.selectOnLoad} layoutKey={"layout"} />);
     }
 
     render() {
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 20e175031..6a51db4ac 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -8,11 +8,12 @@ import { keymap } from "prosemirror-keymap";
 import { EditorState, Plugin, Transaction } from "prosemirror-state";
 import { EditorView } from "prosemirror-view";
 import { Doc, Opt } from "../../../new_fields/Doc";
+import { Id } from '../../../new_fields/FieldSymbols';
 import { RichTextField } from "../../../new_fields/RichTextField";
 import { createSchema, makeInterface } from "../../../new_fields/Schema";
-import { Cast, NumCast, StrCast, BoolCast } from "../../../new_fields/Types";
+import { BoolCast, Cast, NumCast, StrCast } from "../../../new_fields/Types";
 import { DocServer } from "../../DocServer";
-import { DocUtils, Docs } from '../../documents/Documents';
+import { Docs } from '../../documents/Documents';
 import { DocumentManager } from "../../util/DocumentManager";
 import { DragManager } from "../../util/DragManager";
 import buildKeymap from "../../util/ProsemirrorKeymap";
@@ -21,37 +22,20 @@ import { ImageResizeView, schema } from "../../util/RichTextSchema";
 import { SelectionManager } from "../../util/SelectionManager";
 import { TooltipLinkingMenu } from "../../util/TooltipLinkingMenu";
 import { TooltipTextMenu } from "../../util/TooltipTextMenu";
-import { undoBatch, UndoManager } from "../../util/UndoManager";
+import { UndoManager } from "../../util/UndoManager";
+import { ContextMenu } from '../ContextMenu';
+import { ContextMenuProps } from '../ContextMenuItem';
 import { DocComponent } from "../DocComponent";
 import { InkingControl } from "../InkingControl";
 import { FieldView, FieldViewProps } from "./FieldView";
 import "./FormattedTextBox.scss";
 import React = require("react");
-import { Id } from '../../../new_fields/FieldSymbols';
-import { MainOverlayTextBox } from '../MainOverlayTextBox';
-import { Utils } from '../../../Utils';
-import { ContextMenuProps } from '../ContextMenuItem';
-import { ContextMenu } from '../ContextMenu';
 
 library.add(faEdit);
 library.add(faSmile);
 
 // FormattedTextBox: Displays an editable plain text node that maps to a specified Key of a Document
 //
-//  HTML Markup:  <FormattedTextBox Doc={Document's ID} FieldKey={Key's name}
-//
-//  In Code, the node's HTML is specified in the document's parameterized structure as:
-//        document.SetField(KeyStore.Layout,  "<FormattedTextBox doc={doc} fieldKey={<KEYNAME>Key} />");
-//  and the node's binding to the specified document KEYNAME as:
-//        document.SetField(KeyStore.LayoutKeys, new ListField([KeyStore.<KEYNAME>]));
-//  The Jsx parser at run time will bind:
-//        'fieldKey' property to the Key stored in LayoutKeys
-//    and 'doc' property to the document that is being rendered
-//
-//  When rendered() by React, this extracts the TextController from the Document stored at the
-//  specified Key and assigns it to an HTML input node.  When changes are made to this node,
-//  this will edit the document and assign the new value to that field.
-//]
 
 export interface FormattedTextBoxProps {
     isOverlay?: boolean;
@@ -76,11 +60,9 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
     private _proseRef: React.RefObject<HTMLDivElement>;
     private _editorView: Opt<EditorView>;
     private _toolTipTextMenu: TooltipTextMenu | undefined = undefined;
-    private _lastState: any = undefined;
     private _applyingChange: boolean = false;
     private _linkClicked = "";
     private _reactionDisposer: Opt<IReactionDisposer>;
-    private _inputReactionDisposer: Opt<IReactionDisposer>;
     private _proxyReactionDisposer: Opt<IReactionDisposer>;
     public get CurrentDiv(): HTMLDivElement { return this._ref.current!; }
     @observable _entered = false;
@@ -119,10 +101,9 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
         }
     }
 
-
     dispatchTransaction = (tx: Transaction) => {
         if (this._editorView) {
-            const state = this._lastState = this._editorView.state.apply(tx);
+            const state = this._editorView.state.apply(tx);
             this._editorView.updateState(state);
             this._applyingChange = true;
             Doc.SetOnPrototype(this.props.Document, this.props.fieldKey, new RichTextField(JSON.stringify(state.toJSON())));
@@ -160,18 +141,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
                 ]
         };
 
-        if (this.props.isOverlay) {
-            this._inputReactionDisposer = reaction(() => FormattedTextBox.InputBoxOverlay,
-                () => {
-                    if (this._editorView) {
-                        this._editorView.destroy();
-                    }
-                    this.setupEditor(config, // bcz: not sure why, but the order of events is such that this.props.Document hasn't updated yet, so without forcing the editor to the MainOverlayTextBox, it will display the previously focused textbox
-                        MainOverlayTextBox.Instance.TextDoc ? MainOverlayTextBox.Instance.TextDoc : this.props.Document,
-                        MainOverlayTextBox.Instance.TextFieldKey ? MainOverlayTextBox.Instance.TextFieldKey : this.props.fieldKey);
-                }
-            );
-        } else {
+        if (!this.props.isOverlay) {
             this._proxyReactionDisposer = reaction(() => this.props.isSelected(),
                 () => {
                     if (this.props.isSelected()) {
@@ -181,13 +151,12 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
                 });
         }
 
-
         this._reactionDisposer = reaction(
             () => {
                 const field = this.props.Document ? Cast(this.props.Document[this.props.fieldKey], RichTextField) : undefined;
-                return field ? field.Data : undefined;
+                return field ? field.Data : `{"doc":{"type":"doc","content":[]},"selection":{"type":"text","anchor":0,"head":0}}`;
             },
-            field => field && this._editorView && !this._applyingChange &&
+            field => this._editorView && !this._applyingChange &&
                 this._editorView.updateState(EditorState.fromJSON(config, JSON.parse(field)))
         );
         this.setupEditor(config, this.props.Document, this.props.fieldKey);
@@ -215,8 +184,8 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
         }
 
         if (this.props.selectOnLoad) {
-            //this.props.select(false);
-            this._editorView!.focus();
+            if (!this.props.isOverlay) this.props.select(false);
+            else this._editorView!.focus();
         }
     }
 
@@ -227,9 +196,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
         if (this._reactionDisposer) {
             this._reactionDisposer();
         }
-        if (this._inputReactionDisposer) {
-            this._inputReactionDisposer();
-        }
         if (this._proxyReactionDisposer) {
             this._proxyReactionDisposer();
         }
@@ -394,7 +360,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
                     color: this.props.color ? this.props.color : this.props.hideOnLeave ? "white" : "initial",
                     pointerEvents: interactive ? "all" : "none",
                 }}
-                // onKeyDown={this.onKeyPress}
                 onKeyPress={this.onKeyPress}
                 onFocus={this.onFocused}
                 onClick={this.onClick}
@@ -403,7 +368,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
                 onPointerUp={this.onPointerUp}
                 onPointerDown={this.onPointerDown}
                 onMouseDown={this.onMouseDown}
-                // tfs: do we need this event handler
                 onWheel={this.onPointerWheel}
                 onPointerEnter={this.onPointerEnter}
                 onPointerLeave={this.onPointerLeave}
-- 
cgit v1.2.3-70-g09d2

