From 3be42131bc08024f06e0daec8d09e45bf3f1ddab Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Mon, 13 May 2019 16:21:28 -0400
Subject: a bunch of fixes to schemas, marquees, and an experimental feature to
 set a document's data with linking UI

---
 .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx   | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index dc86f38b6..c36c708db 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -339,7 +339,7 @@ class CollectionFreeFormOverlayView extends React.Component<DocumentViewProps &
             isTopMost={this.props.isTopMost} isSelected={this.props.isSelected} select={emptyFunction} />);
     }
     render() {
-        return this.overlayView;
+        return this.props.Document.overlayLayout ? this.overlayView : (null);
     }
 }
 
@@ -350,7 +350,7 @@ class CollectionFreeFormBackgroundView extends React.Component<DocumentViewProps
             isTopMost={this.props.isTopMost} isSelected={this.props.isSelected} select={emptyFunction} />);
     }
     render() {
-        return this.backgroundView;
+        return this.props.Document.backgroundLayout ? this.backgroundView : (null);
     }
 }
 
-- 
cgit v1.2.3-70-g09d2


From 1ae0370e6a116404085f6864c8b644fcde80f460 Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Tue, 14 May 2019 19:59:23 -0400
Subject: Added History module and ability to go back and forward when
 following links

---
 src/client/util/History.ts                         | 122 +++++++++++++++++++++
 src/client/views/Main.tsx                          |  19 +---
 .../views/collections/CollectionDockingView.tsx    |   2 -
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  36 +++++-
 src/new_fields/Doc.ts                              |   7 +-
 5 files changed, 159 insertions(+), 27 deletions(-)
 create mode 100644 src/client/util/History.ts

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

diff --git a/src/client/util/History.ts b/src/client/util/History.ts
new file mode 100644
index 000000000..92d2b2b44
--- /dev/null
+++ b/src/client/util/History.ts
@@ -0,0 +1,122 @@
+import { Doc, Opt, Field } from "../../new_fields/Doc";
+import { DocServer } from "../DocServer";
+import { Main } from "../views/Main";
+import { RouteStore } from "../../server/RouteStore";
+
+export namespace HistoryUtil {
+    export interface DocInitializerList {
+        [key: string]: string | number;
+    }
+
+    export interface DocUrl {
+        type: "doc";
+        docId: string;
+        initializers: {
+            [docId: string]: DocInitializerList;
+        };
+    }
+
+    export type ParsedUrl = DocUrl;
+
+    // const handlers: ((state: ParsedUrl | null) => void)[] = [];
+    function onHistory(e: PopStateEvent) {
+        if (window.location.pathname !== RouteStore.home) {
+            const url = e.state as ParsedUrl || parseUrl(window.location.pathname);
+            if (url) {
+                switch (url.type) {
+                    case "doc":
+                        onDocUrl(url);
+                        break;
+                }
+            }
+        }
+        // for (const handler of handlers) {
+        //     handler(e.state);
+        // }
+    }
+
+    export function pushState(state: ParsedUrl) {
+        history.pushState(state, "", createUrl(state));
+    }
+
+    export function replaceState(state: ParsedUrl) {
+        history.replaceState(state, "", createUrl(state));
+    }
+
+    function copyState(state: ParsedUrl): ParsedUrl {
+        return JSON.parse(JSON.stringify(state));
+    }
+
+    export function getState(): ParsedUrl {
+        return copyState(history.state);
+    }
+
+    // export function addHandler(handler: (state: ParsedUrl | null) => void) {
+    //     handlers.push(handler);
+    // }
+
+    // export function removeHandler(handler: (state: ParsedUrl | null) => void) {
+    //     const index = handlers.indexOf(handler);
+    //     if (index !== -1) {
+    //         handlers.splice(index, 1);
+    //     }
+    // }
+
+    export function parseUrl(pathname: string): ParsedUrl | undefined {
+        let pathnameSplit = pathname.split("/");
+        if (pathnameSplit.length !== 2) {
+            return undefined;
+        }
+        const type = pathnameSplit[0];
+        const data = pathnameSplit[1];
+
+        if (type === "doc") {
+            const s = data.split("?");
+            if (s.length < 1 || s.length > 2) {
+                return undefined;
+            }
+            const docId = s[0];
+            const initializers = s.length === 2 ? JSON.parse(decodeURIComponent(s[1])) : {};
+            return {
+                type: "doc",
+                docId,
+                initializers
+            };
+        }
+
+        return undefined;
+    }
+
+    export function createUrl(params: ParsedUrl): string {
+        let baseUrl = DocServer.prepend(`/${params.type}`);
+        switch (params.type) {
+            case "doc":
+                const initializers = encodeURIComponent(JSON.stringify(params.initializers));
+                const id = params.docId;
+                let url = baseUrl + `/${id}`;
+                if (Object.keys(params.initializers).length) {
+                    url += `?${initializers}`;
+                }
+                return url;
+        }
+        return "";
+    }
+
+    export async function initDoc(id: string, initializer: DocInitializerList) {
+        const doc = await DocServer.GetRefField(id);
+        if (!(doc instanceof Doc)) {
+            return;
+        }
+        Doc.assign(doc, initializer);
+    }
+
+    async function onDocUrl(url: DocUrl) {
+        const field = await DocServer.GetRefField(url.docId);
+        await Promise.all(Object.keys(url.initializers).map(id => initDoc(id, url.initializers[id])));
+        if (field instanceof Doc) {
+            Main.Instance.openWorkspace(field, true);
+        }
+    }
+
+    window.onpopstate = onHistory;
+}
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 66205f8ca..55252ab1d 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -38,6 +38,8 @@ import { Cast, FieldValue, StrCast } from '../../new_fields/Types';
 import { DocServer } from '../DocServer';
 import { listSpec } from '../../new_fields/Schema';
 import { Id } from '../../new_fields/RefField';
+import { HistoryUtil } from '../util/History';
+
 
 @observer
 export class Main extends React.Component {
@@ -95,21 +97,6 @@ export class Main extends React.Component {
         // }
     }
 
-    componentDidMount() { window.onpopstate = this.onHistory; }
-
-    componentWillUnmount() { window.onpopstate = null; }
-
-    onHistory = () => {
-        if (window.location.pathname !== RouteStore.home) {
-            let pathname = window.location.pathname.split("/");
-            DocServer.GetRefField(pathname[pathname.length - 1]).then(action((field: Opt<Field>) => {
-                if (field instanceof Doc) {
-                    this.openWorkspace(field, true);
-                }
-            }));
-        }
-    }
-
     initEventListeners = () => {
         // window.addEventListener("pointermove", (e) => this.reportLocation(e))
         window.addEventListener("drop", (e) => e.preventDefault(), false); // drop event handler
@@ -165,7 +152,7 @@ export class Main extends React.Component {
     openWorkspace = async (doc: Doc, fromHistory = false) => {
         CurrentUserUtils.MainDocId = doc[Id];
         this.mainContainer = doc;
-        fromHistory || window.history.pushState(null, StrCast(doc.title), "/doc/" + doc[Id]);
+        fromHistory || HistoryUtil.pushState({ type: "doc", docId: doc[Id], initializers: {} });
         const col = await Cast(CurrentUserUtils.UserDocument.optionalRightCollection, Doc);
         // if there is a pending doc, and it has new data, show it (syip: we use a timeout to prevent collection docking view from being uninitialized)
         setTimeout(async () => {
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 6651a834d..58f1e33a1 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -190,7 +190,6 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
     }
     reactionDisposer?: Lambda;
     componentDidMount: () => void = () => {
-        console.log("Docking mount");
         if (this._containerRef.current) {
             this.reactionDisposer = reaction(
                 () => StrCast(this.props.Document.dockingConfig),
@@ -207,7 +206,6 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
         }
     }
     componentWillUnmount: () => void = () => {
-        console.log("Docking unmount");
         try {
             this._goldenLayout.unbind('itemDropped', this.itemDropped);
             this._goldenLayout.unbind('tabCreated', this.tabCreated);
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index c36c708db..e60bb2fb2 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -24,6 +24,7 @@ import { FieldValue, Cast, NumCast } from "../../../../new_fields/Types";
 import { pageSchema } from "../../nodes/ImageBox";
 import { Id } from "../../../../new_fields/RefField";
 import { InkField, StrokeData } from "../../../../new_fields/InkField";
+import { HistoryUtil } from "../../../util/History";
 
 export const panZoomSchema = createSchema({
     panX: "number",
@@ -219,6 +220,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
     @action
     setPan(panX: number, panY: number) {
+        this.panDisposer && clearTimeout(this.panDisposer);
+        this.props.Document.panTransformType = "None";
         var scale = this.getLocalTransform().inverse().Scale;
         const newPanX = Math.min((1 - 1 / scale) * this.nativeWidth, Math.max(0, panX));
         const newPanY = Math.min((1 - 1 / scale) * this.nativeHeight, Math.max(0, panY));
@@ -245,16 +248,37 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         doc.zIndex = docs.length + 1;
     }
 
+    panDisposer?: NodeJS.Timeout;
     focusDocument = (doc: Doc) => {
+        const panX = this.Document.panX;
+        const panY = this.Document.panY;
+        const id = this.Document[Id];
+        const state = HistoryUtil.getState();
+        // TODO This technically isn't correct if type !== "doc", as 
+        // currently nothing is done, but we should probably push a new state
+        if (state.type === "doc" && panX !== undefined && panY !== undefined) {
+            const init = state.initializers[id];
+            if (!init) {
+                state.initializers[id] = {
+                    panX, panY
+                };
+                HistoryUtil.pushState(state);
+            } else if (init.panX !== panX || init.panY !== panY) {
+                init.panX = panX;
+                init.panY = panY;
+                HistoryUtil.pushState(state);
+            }
+        }
         SelectionManager.DeselectAll();
+        const newPanX = NumCast(doc.x) + NumCast(doc.width) / 2;
+        const newPanY = NumCast(doc.y) + NumCast(doc.height) / 2;
+        const newState = HistoryUtil.getState();
+        newState.initializers[id] = { panX: newPanX, panY: newPanY };
+        HistoryUtil.pushState(newState);
+        this.setPan(newPanX, newPanY);
         this.props.Document.panTransformType = "Ease";
-        this.setPan(
-            NumCast(doc.x) + NumCast(doc.width) / 2,
-            NumCast(doc.y) + NumCast(doc.height) / 2);
         this.props.focus(this.props.Document);
-        if (this.props.Document.panTransformType === "Ease") {
-            setTimeout(() => this.props.Document.panTransformType = "None", 2000);  // wait 3 seconds, then reset to false
-        }
+        this.panDisposer = setTimeout(() => this.props.Document.panTransformType = "None", 2000);  // wait 3 seconds, then reset to false
     }
 
 
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 89901490d..d6043ef7a 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -159,9 +159,10 @@ export namespace Doc {
         for (const key in fields) {
             if (fields.hasOwnProperty(key)) {
                 const value = fields[key];
-                if (value !== undefined) {
-                    doc[key] = value;
-                }
+                // Do we want to filter out undefineds?
+                // if (value !== undefined) {
+                doc[key] = value;
+                // }
             }
         }
         return doc;
-- 
cgit v1.2.3-70-g09d2


From 89556cce212e8d8d2678e628f3bba5ca1768c902 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Wed, 15 May 2019 00:53:40 -0400
Subject: tweaks.

---
 .../collectionFreeForm/CollectionFreeFormView.tsx    | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index e60bb2fb2..eaa91fd74 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -20,7 +20,7 @@ import React = require("react");
 import v5 = require("uuid/v5");
 import { createSchema, makeInterface, listSpec } from "../../../../new_fields/Schema";
 import { Doc, WidthSym, HeightSym } from "../../../../new_fields/Doc";
-import { FieldValue, Cast, NumCast } from "../../../../new_fields/Types";
+import { FieldValue, Cast, NumCast, BoolCast } from "../../../../new_fields/Types";
 import { pageSchema } from "../../nodes/ImageBox";
 import { Id } from "../../../../new_fields/RefField";
 import { InkField, StrokeData } from "../../../../new_fields/InkField";
@@ -44,16 +44,16 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     private get _pwidth() { return this.props.PanelWidth(); }
     private get _pheight() { return this.props.PanelHeight(); }
 
-    @computed get nativeWidth() { return NumCast(this.Document.nativeWidth, 0); }
-    @computed get nativeHeight() { return NumCast(this.Document.nativeHeight, 0); }
+    @computed get nativeWidth() { return this.Document.nativeWidth || 0; }
+    @computed get nativeHeight() { return this.Document.nativeHeight || 0; }
     private get borderWidth() { return this.isAnnotationOverlay ? 0 : COLLECTION_BORDER_WIDTH; }
     private get isAnnotationOverlay() { return this.props.fieldKey && this.props.fieldKey === "annotations"; }
-    private panX = () => FieldValue(this.Document.panX, 0);
-    private panY = () => FieldValue(this.Document.panY, 0);
-    private zoomScaling = () => FieldValue(this.Document.scale, 1);
+    private panX = () => this.Document.panX || 0;
+    private panY = () => this.Document.panY || 0;
+    private zoomScaling = () => this.Document.scale || 1;
     private centeringShiftX = () => !this.nativeWidth ? this._pwidth / 2 : 0;  // shift so pan position is at center of window for non-overlay collections
     private centeringShiftY = () => !this.nativeHeight ? this._pheight / 2 : 0;// shift so pan position is at center of window for non-overlay collections
-    private getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.borderWidth, -this.borderWidth).translate(-this.centeringShiftX(), -this.centeringShiftY()).transform(this.getLocalTransform());
+    private getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.borderWidth + 1, -this.borderWidth + 1).translate(-this.centeringShiftX(), -this.centeringShiftY()).transform(this.getLocalTransform());
     private getContainerTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.borderWidth, -this.borderWidth);
     private getLocalTransform = (): Transform => Transform.Identity().scale(1 / this.zoomScaling()).translate(this.panX(), this.panY());
     private addLiveTextBox = (newBox: Doc) => {
@@ -134,8 +134,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     @action
     onPointerMove = (e: PointerEvent): void => {
         if (!e.cancelBubble) {
-            let x = NumCast(this.props.Document.panX);
-            let y = NumCast(this.props.Document.panY);
+            let x = this.props.Document.panX || 0;
+            let y = this.props.Document.panY || 0;
             let docs = this.children || [];
             let [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
             if (!this.isAnnotationOverlay) {
@@ -310,7 +310,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             if (!(doc instanceof Doc)) return prev;
             var page = NumCast(doc.page, -1);
             if (page === curPage || page === -1) {
-                let minim = Cast(doc.isMinimized, "boolean");
+                let minim = BoolCast(doc.isMinimized, false);
                 if (minim === undefined || !minim) {
                     prev.push(<CollectionFreeFormDocumentView key={doc[Id]} {...this.getDocumentViewProps(doc)} />);
                 }
-- 
cgit v1.2.3-70-g09d2


From 53351f6c5b448b93f2865eb38868bddb95ec4c1d Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Wed, 15 May 2019 22:02:39 -0400
Subject: fixed templates on images.

---
 src/client/views/Templates.tsx                                     | 7 +++++--
 .../collections/collectionFreeForm/CollectionFreeFormView.tsx      | 2 +-
 src/client/views/nodes/DocumentContentsView.tsx                    | 2 +-
 3 files changed, 7 insertions(+), 4 deletions(-)

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

diff --git a/src/client/views/Templates.tsx b/src/client/views/Templates.tsx
index a98870b04..ca0c04d1b 100644
--- a/src/client/views/Templates.tsx
+++ b/src/client/views/Templates.tsx
@@ -40,8 +40,11 @@ export namespace Templates {
     // export const BasicLayout = new Template("Basic layout", "{layout}");
 
     export const Caption = new Template("Caption", TemplatePosition.OutterBottom,
-        `<div id="screenSpace" style="top: 100%; font-size:14px; background:yellow; width:100%; position:absolute">
-            <FormattedTextBox {...props} fieldKey={"caption"} />
+        `<div>
+            <div style="height:100%; width:100%;position:absolute;">{layout}</div>
+            <div id="screenSpace" style="top: 100%; font-size:14px; background:yellow; width:100%; position:absolute">
+                <FormattedTextBox {...props} fieldKey={"caption"} />
+            </div>
         </div>` );
 
     export const TitleOverlay = new Template("TitleOverlay", TemplatePosition.InnerTop,
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index eaa91fd74..b8bed795d 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -363,7 +363,7 @@ class CollectionFreeFormOverlayView extends React.Component<DocumentViewProps &
             isTopMost={this.props.isTopMost} isSelected={this.props.isSelected} select={emptyFunction} />);
     }
     render() {
-        return this.props.Document.overlayLayout ? this.overlayView : (null);
+        return this.overlayView;
     }
 }
 
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 3ddf8eb00..f3d76c49b 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -64,7 +64,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
         return new List<string>();
     }
     @computed get finalLayout() {
-        const baseLayout = this.layout;
+        const baseLayout = this.props.layoutKey === "overlayLayout" ? "<div/>" : this.layout;
         let base = baseLayout;
         let layout = baseLayout;
 
-- 
cgit v1.2.3-70-g09d2


From 33c7af8d3e09e5add3ae56d5c7a697acee4104c3 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Thu, 16 May 2019 10:27:19 -0400
Subject: running into performance problems.   fixed some things about
 summaries.

---
 src/client/views/PreviewCursor.tsx                 |  8 ++-
 src/client/views/Templates.tsx                     |  2 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  4 +-
 .../collections/collectionFreeForm/MarqueeView.tsx | 70 +++++++++++-----------
 4 files changed, 42 insertions(+), 42 deletions(-)

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

diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx
index 4218ea7c9..7c1d00eb0 100644
--- a/src/client/views/PreviewCursor.tsx
+++ b/src/client/views/PreviewCursor.tsx
@@ -22,9 +22,11 @@ export class PreviewCursor extends React.Component<{}> {
     }
     paste = (e: ClipboardEvent) => {
         console.log(e.clipboardData);
-        console.log(e.clipboardData.getData("text/html"));
-        console.log(e.clipboardData.getData("text/csv"));
-        console.log(e.clipboardData.getData("text/plain"));
+        if (e.clipboardData) {
+            console.log(e.clipboardData.getData("text/html"));
+            console.log(e.clipboardData.getData("text/csv"));
+            console.log(e.clipboardData.getData("text/plain"));
+        }
     }
 
     @action
diff --git a/src/client/views/Templates.tsx b/src/client/views/Templates.tsx
index f0ee2856b..8d6bfbefd 100644
--- a/src/client/views/Templates.tsx
+++ b/src/client/views/Templates.tsx
@@ -73,7 +73,7 @@ export namespace Templates {
 
     export function ImageOverlay(width: number, height: number, field: string = "thumbnail") {
         return (`<div>
-                <div style="height:100%; position:absolute;">{layout}</div>
+                <div style="height:100%; width:100%; position:absolute;">{layout}</div>
                 <div style="height:${height}px; top:0; right:0; background:rgba(0,0,0,0.25); position:absolute;overflow:hidden;">
                     <ImageBox id="isExpander" {...props} PanelWidth={${width}} fieldKey={"${field}"} />
                 </div>
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index b8bed795d..6e4c79e62 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -134,8 +134,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     @action
     onPointerMove = (e: PointerEvent): void => {
         if (!e.cancelBubble) {
-            let x = this.props.Document.panX || 0;
-            let y = this.props.Document.panY || 0;
+            let x = this.Document.panX || 0;
+            let y = this.Document.panY || 0;
             let docs = this.children || [];
             let [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
             if (!this.isAnnotationOverlay) {
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index c063115e7..17d0a533e 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -223,27 +223,21 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
             this.cleanupInteractions(false);
             e.stopPropagation();
         }
-        if (e.key === "c" || e.key === "r" || e.key === "s" || e.key === "e" || e.key === "p") {
+        if (e.key === "c" || e.key === "s" || e.key === "e" || e.key === "p") {
             this._commandExecuted = true;
             e.stopPropagation();
             (e as any).propagationIsStopped = true;
             let bounds = this.Bounds;
-            let selected = this.marqueeSelect().map(d => {
-                if (e.key === "s") {
-                    let dCopy = Doc.MakeCopy(d);
-                    dCopy.x = NumCast(d.x) - bounds.left - bounds.width / 2;
-                    dCopy.y = NumCast(d.y) - bounds.top - bounds.height / 2;
-                    dCopy.page = -1;
-                    return dCopy;
-                }
-                else if (e.key !== "r") {
+            let selected = this.marqueeSelect();
+            if (e.key === "c") {
+                selected.map(d => {
                     this.props.removeDocument(d);
                     d.x = NumCast(d.x) - bounds.left - bounds.width / 2;
                     d.y = NumCast(d.y) - bounds.top - bounds.height / 2;
                     d.page = -1;
-                }
-                return d;
-            });
+                    return d;
+                });
+            }
             let ink = Cast(this.props.container.props.Document.ink, InkField);
             let inkData = ink ? ink.inkData : undefined;
             let zoomBasis = NumCast(this.props.container.props.Document.scale, 1);
@@ -257,36 +251,40 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
                 width: bounds.width * zoomBasis,
                 height: bounds.height * zoomBasis,
                 ink: inkData ? new InkField(this.marqueeInkSelect(inkData)) : undefined,
-                title: e.key === "s" ? "-summary-" : e.key === "r" ? "-replacement-" : e.key === "p" ? "-summary-" : "a nested collection",
+                title: e.key === "s" ? "-summary-" : e.key === "p" ? "-summary-" : "a nested collection",
             });
-
             this.marqueeInkDelete(inkData);
-            // SelectionManager.DeselectAll();
-            if (e.key === "s" || e.key === "r" || e.key === "p") {
-                e.preventDefault();
-                let summary = Docs.TextDocument({ x: bounds.left, y: bounds.top, width: 300, height: 100, backgroundColor: "yellow", title: "-summary-" });
 
-                let dataUrl = await htmlToImage.toPng(this._mainCont.current!, { width: bounds.width, height: bounds.height, quality: 1 });
-                summary.proto!.thumbnail = new ImageField(new URL(dataUrl));
+            if (e.key === "s" || e.key === "p") {
 
-                summary.proto!.templates = new List<string>([Templates.ImageOverlay(Math.min(50, bounds.width), bounds.height * Math.min(50, bounds.width) / bounds.width, "thumbnail")]);
-                if (e.key === "s" || e.key === "p") {
-                    // summary.proto!.maximizeOnRight = true;
+                htmlToImage.toPng(this._mainCont.current!, { width: bounds.width, height: bounds.height, quality: 1 }).then((dataUrl) => {
+                    selected.map(d => {
+                        this.props.removeDocument(d);
+                        d.x = NumCast(d.x) - bounds.left - bounds.width / 2;
+                        d.y = NumCast(d.y) - bounds.top - bounds.height / 2;
+                        d.page = -1;
+                        return d;
+                    });
+                    let summary = Docs.TextDocument({ x: bounds.left, y: bounds.top, width: 300, height: 100, backgroundColor: "yellow", title: "-summary-" });
+                    summary.proto!.thumbnail = new ImageField(new URL(dataUrl));
+                    summary.proto!.templates = new List<string>([Templates.ImageOverlay(Math.min(50, bounds.width), bounds.height * Math.min(50, bounds.width) / bounds.width, "thumbnail")]);
                     newCollection.proto!.summaryDoc = summary;
                     selected = [newCollection];
-                    newCollection.proto!.isMinimized = true;
+                    newCollection.x = bounds.left + bounds.width;
                     this.props.addDocument(newCollection, false);
-                }
-                summary.proto!.summarizedDocs = new List<Doc>(selected.map(s => s.proto!));
-                //summary.proto!.isButton = true;
-                let scrpt = this.props.getTransform().inverse().transformPoint(bounds.left, bounds.top);
-                selected.map(summarizedDoc => {
-                    let maxx = NumCast(summarizedDoc.x, undefined);
-                    let maxy = NumCast(summarizedDoc.y, undefined);
-                    let maxw = NumCast(summarizedDoc.width, undefined);
-                    let maxh = NumCast(summarizedDoc.height, undefined);
-                });
-                this.props.addLiveTextDocument(summary);
+                    summary.proto!.summarizedDocs = new List<Doc>(selected.map(s => s.proto!));
+                    //summary.proto!.maximizeOnRight = true;
+                    //summary.proto!.isButton = true;
+                    //let scrpt = this.props.getTransform().inverse().transformPoint(bounds.left, bounds.top);
+                    // selected.map(summarizedDoc => {
+                    //     let maxx = NumCast(summarizedDoc.x, undefined);
+                    //     let maxy = NumCast(summarizedDoc.y, undefined);
+                    //     let maxw = NumCast(summarizedDoc.width, undefined);
+                    //     let maxh = NumCast(summarizedDoc.height, undefined);
+                    //     summarizedDoc.isIconAnimating = new List<number>([scrpt[0], scrpt[1], maxx, maxy, maxw, maxh, Date.now(), 0]);
+                    // });
+                    this.props.addLiveTextDocument(summary);
+                })
             }
             else {
                 this.props.addDocument(newCollection, false);
-- 
cgit v1.2.3-70-g09d2


From 9d17f2aaaf8ffc229c7b02006070380b0b35e7d3 Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Thu, 16 May 2019 21:38:38 -0400
Subject: Small change

---
 src/client/views/collections/CollectionSchemaView.tsx        |  2 +-
 src/client/views/collections/CollectionSubView.tsx           |  2 +-
 src/client/views/collections/CollectionTreeView.tsx          |  4 ++--
 .../collectionFreeForm/CollectionFreeFormView.tsx            | 12 ++++++------
 src/new_fields/Doc.ts                                        |  2 +-
 5 files changed, 11 insertions(+), 11 deletions(-)

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

diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 497dfde88..a975d3fef 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -357,7 +357,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
     render() {
         library.add(faCog);
         library.add(faPlus);
-        const children = this.children;
+        const children = this.childDocs;
         return (
             <div className="collectionSchemaView-container" onPointerDown={this.onPointerDown} onWheel={this.onWheel}
                 onDrop={(e: React.DragEvent) => this.onDrop(e, {})} onContextMenu={this.onContextMenu} ref={this.createTarget}>
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index ffd3e0659..864fdfa4b 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -47,7 +47,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
             this.createDropTarget(ele);
         }
 
-        get children() {
+        get childDocs() {
             //TODO tfs: This might not be what we want?
             //This linter error can't be fixed because of how js arguments work, so don't switch this to filter(FieldValue)
             return DocListCast(this.props.Document[this.props.fieldKey]);
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 3fcc2bc70..35a9f34cf 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -223,10 +223,10 @@ export class CollectionTreeView extends CollectionSubView(Document) {
     }
     render() {
         let dropAction = StrCast(this.props.Document.dropAction, "alias") as dropActionType;
-        if (!this.children) {
+        if (!this.childDocs) {
             return (null);
         }
-        let childElements = TreeView.GetChildElements(this.children, false, this.remove, this.props.moveDocument, dropAction);
+        let childElements = TreeView.GetChildElements(this.childDocs, false, this.remove, this.props.moveDocument, dropAction);
 
         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 6e4c79e62..ccc81f1ad 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -72,7 +72,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     }
     public getActiveDocuments = () => {
         const curPage = FieldValue(this.Document.curPage, -1);
-        return this.children.filter(doc => {
+        return this.childDocs.filter(doc => {
             var page = NumCast(doc.page, -1);
             return page === curPage || page === -1;
         });
@@ -90,7 +90,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
                 let y = yp - de.data.yOffset / zoom;
                 let dropX = NumCast(de.data.droppedDocuments[0].x);
                 let dropY = NumCast(de.data.droppedDocuments[0].y);
-                de.data.droppedDocuments.map(d => {
+                de.data.droppedDocuments.forEach(d => {
                     d.x = x + NumCast(d.x) - dropX;
                     d.y = y + NumCast(d.y) - dropY;
                     if (!NumCast(d.width)) {
@@ -136,7 +136,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         if (!e.cancelBubble) {
             let x = this.Document.panX || 0;
             let y = this.Document.panY || 0;
-            let docs = this.children || [];
+            let docs = this.childDocs || [];
             let [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
             if (!this.isAnnotationOverlay) {
                 let minx = docs.length ? NumCast(docs[0].x) : 0;
@@ -180,7 +180,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         // if (!this.props.active()) {
         //     return;
         // }
-        let childSelected = this.children.some(doc => {
+        let childSelected = this.childDocs.some(doc => {
             var dv = DocumentManager.Instance.getDocumentView(doc);
             return dv && SelectionManager.IsSelected(dv) ? true : false;
         });
@@ -239,7 +239,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     }
 
     bringToFront = (doc: Doc) => {
-        const docs = this.children;
+        const docs = this.childDocs;
         docs.slice().sort((doc1, doc2) => {
             if (doc1 === doc) return 1;
             if (doc2 === doc) return -1;
@@ -306,7 +306,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     @computed.struct
     get views() {
         let curPage = FieldValue(this.Document.curPage, -1);
-        let docviews = this.children.reduce((prev, doc) => {
+        let docviews = this.childDocs.reduce((prev, doc) => {
             if (!(doc instanceof Doc)) return prev;
             var page = NumCast(doc.page, -1);
             if (page === curPage || page === -1) {
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index c898f697b..f76999627 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -43,7 +43,7 @@ export function DocListCastAsync(field: FieldResult, defaultValue?: Doc[]) {
 }
 
 export function DocListCast(field: FieldResult): Doc[] {
-    return Cast(field, listSpec(Doc), []).filter(d => d && d instanceof Doc) as Doc[];
+    return Cast(field, listSpec(Doc), []).filter(d => d instanceof Doc) as Doc[];
 }
 
 @Deserializable("doc").withFields(["id"])
-- 
cgit v1.2.3-70-g09d2


From 4e244951b7b18d7973360f423e8de80c42466228 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Fri, 17 May 2019 19:50:32 -0400
Subject: added right-click "open Tab" and double-click open tab

---
 src/client/views/Main.tsx                            |  1 +
 .../views/collections/CollectionDockingView.tsx      | 20 ++++++++++++++++++--
 .../collectionFreeForm/CollectionFreeFormView.tsx    |  1 +
 .../views/nodes/CollectionFreeFormDocumentView.tsx   | 19 +++++++++++++++++++
 src/client/views/nodes/DocumentView.tsx              |  2 ++
 src/client/views/nodes/FieldView.tsx                 |  2 ++
 src/client/views/nodes/ImageBox.tsx                  |  4 +++-
 7 files changed, 46 insertions(+), 3 deletions(-)

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

diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 51ad0aa49..177047a9a 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -166,6 +166,7 @@ export class Main extends React.Component {
             <DocumentView Document={mainCont}
                 toggleMinimized={emptyFunction}
                 addDocument={undefined}
+                addDocTab={emptyFunction}
                 removeDocument={undefined}
                 ScreenToLocalTransform={Transform.Identity}
                 ContentScaling={returnOne}
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index deec64225..28624e020 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -107,7 +107,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
     @action
     layoutChanged(removed?: Doc) {
         this._goldenLayout.root.callDownwards('setSize', [this._goldenLayout.width, this._goldenLayout.height]);
-        this._goldenLayout.emit('sbcreteChanged');
+        this._goldenLayout.emit('stateChanged');
         this._ignoreStateChange = JSON.stringify(this._goldenLayout.toConfig());
         if (removed) CollectionDockingView.Instance._removedDocs.push(removed);
         this.stateChanged();
@@ -153,6 +153,17 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
 
         return newContentItem;
     }
+    @action
+    public AddTab(stack: any, document: Doc) {
+        let docs = Cast(this.props.Document.data, listSpec(Doc));
+        if (docs) {
+            docs.push(document);
+        }
+        let docContentConfig = CollectionDockingView.makeDocumentConfig(document);
+        var newContentItem = stack.layoutManager.createContentItem(docContentConfig, this._goldenLayout);
+        stack.addChild(newContentItem.contentItems[0], undefined);
+        this.layoutChanged();
+    }
 
     setupGoldenLayout() {
         var config = StrCast(this.props.Document.dockingConfig);
@@ -395,9 +406,10 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
     @observable private _panelWidth = 0;
     @observable private _panelHeight = 0;
     @observable private _document: Opt<Doc>;
-
+    _stack: any;
     constructor(props: any) {
         super(props);
+        this._stack = (this.props as any).glContainer.parent.parent;
         DocServer.GetRefField(this.props.documentId).then(action((f: Opt<Field>) => this._document = f as Doc));
     }
 
@@ -420,6 +432,9 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
     }
     get previewPanelCenteringOffset() { return (this._panelWidth - this.nativeWidth() * this.contentScaling()) / 2; }
 
+    addDocTab = (doc: Doc) => {
+        CollectionDockingView.Instance.AddTab(this._stack, doc);
+    }
     get content() {
         if (!this._document) {
             return (null);
@@ -441,6 +456,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
                     parentActive={returnTrue}
                     whenActiveChanged={emptyFunction}
                     focus={emptyFunction}
+                    addDocTab={this.addDocTab}
                     ContainingCollectionView={undefined} />
             </div >);
     }
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 6e4c79e62..ad32f70dc 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -300,6 +300,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             parentActive: this.props.active,
             whenActiveChanged: this.props.whenActiveChanged,
             bringToFront: this.bringToFront,
+            addDocTab: this.props.addDocTab,
         };
     }
 
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 00aa71656..a0efc3154 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -159,6 +159,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
             }, 500);
         }
     }
+    private _lastTap: number = 0;
     static _undoBatch?: UndoManager.Batch = undefined;
     onPointerDown = (e: React.PointerEvent): void => {
         this._downX = e.clientX;
@@ -166,6 +167,24 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
         if (e.button === 0 && e.altKey) {
             e.stopPropagation(); // prevents panning from happening on collection if shift is pressed after a document drag has started
         } // allow pointer down to go through otherwise so that marquees can be drawn starting over a document 
+        if (Date.now() - this._lastTap < 300) {
+            if (e.buttons === 1) {
+                this._downX = e.clientX;
+                this._downY = e.clientY;
+                document.removeEventListener("pointerup", this.onPointerUp);
+                document.addEventListener("pointerup", this.onPointerUp);
+            }
+        } else {
+            this._lastTap = Date.now();
+        }
+    }
+    onPointerUp = (e: PointerEvent): void => {
+
+        document.removeEventListener("pointerup", this.onPointerUp);
+        if (Math.abs(e.clientX - this._downX) < 2 && Math.abs(e.clientY - this._downY) < 2) {
+            this.props.addDocTab(this.props.Document);
+        }
+        e.stopPropagation();
     }
     onClick = async (e: React.MouseEvent) => {
         e.stopPropagation();
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 5264773b0..9a5d21b49 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -57,6 +57,7 @@ export interface DocumentViewProps {
     whenActiveChanged: (isActive: boolean) => void;
     toggleMinimized: () => void;
     bringToFront: (doc: Doc) => void;
+    addDocTab: (doc: Doc) => void;
 }
 
 const schema = createSchema({
@@ -307,6 +308,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         cm.addItem({ description: this.props.Document.isButton ? "Remove Button" : "Make Button", event: this.makeButton });
         cm.addItem({ description: "Fields", event: this.fieldsClicked });
         cm.addItem({ description: "Center", event: () => this.props.focus(this.props.Document) });
+        cm.addItem({ description: "Open Tab", event: () => this.props.addDocTab && this.props.addDocTab(this.props.Document) });
         cm.addItem({ description: "Open Right", event: () => CollectionDockingView.Instance.AddRightSplit(this.props.Document) });
         cm.addItem({
             description: "Find aliases", event: async () => {
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 34b6c5e70..b5dfd18eb 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -35,6 +35,7 @@ export interface FieldViewProps {
     isTopMost: boolean;
     selectOnLoad: boolean;
     addDocument?: (document: Doc, allowDuplicates?: boolean) => boolean;
+    addDocTab: (document: Doc) => boolean;
     removeDocument?: (document: Doc) => boolean;
     moveDocument?: (document: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean;
     ScreenToLocalTransform: () => Transform;
@@ -87,6 +88,7 @@ export class FieldView extends React.Component<FieldViewProps> {
             return (
                 <DocumentContentsView Document={field}
                     addDocument={undefined}
+                    addDocTab={this.props.addDocTab}
                     removeDocument={undefined}
                     ScreenToLocalTransform={Transform.Identity}
                     ContentScaling={returnOne}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index a06adfcf0..49c2f1b44 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -166,7 +166,9 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
         let interactive = InkingControl.Instance.selectedTool ? "" : "-interactive";
         let id = (this.props as any).id; // bcz: used to set id = "isExpander" in templates.tsx
         return (
-            <div id={id} className={`imageBox-cont${interactive}`} onPointerDown={this.onPointerDown} onDrop={this.onDrop} ref={this.createDropTarget} onContextMenu={this.specificContextMenu}>
+            <div id={id} className={`imageBox-cont${interactive}`}
+                // onPointerDown={this.onPointerDown}
+                onDrop={this.onDrop} ref={this.createDropTarget} onContextMenu={this.specificContextMenu}>
                 <img id={id} src={paths[Math.min(paths.length, this._photoIndex)]}
                     style={{ objectFit: (this._photoIndex === 0 ? undefined : "contain") }}
                     width={nativeWidth}
-- 
cgit v1.2.3-70-g09d2


From c627be793938188ebcb16d2ca3db93728b609116 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Fri, 17 May 2019 22:35:43 -0400
Subject: fixed shift-drag of main collection.

---
 .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 2 +-
 src/client/views/nodes/DocumentView.tsx                             | 6 +-----
 2 files changed, 2 insertions(+), 6 deletions(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index ad32f70dc..b44a2f527 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -116,7 +116,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             (((e.button === 2 && (!this.isAnnotationOverlay || this.zoomScaling() !== 1)) ||
                 (e.button === 0 && e.altKey)) && this.props.active())) ||
             (!CollectionFreeFormView.RIGHT_BTN_DRAG &&
-                ((e.button === 0 && !e.altKey && (!this.isAnnotationOverlay || this.zoomScaling() !== 1)) && this.props.active()))) {
+                ((e.button === 0 && !e.shiftKey && !e.altKey && (!this.isAnnotationOverlay || this.zoomScaling() !== 1)) && this.props.active()))) {
             document.removeEventListener("pointermove", this.onPointerMove);
             document.removeEventListener("pointerup", this.onPointerUp);
             document.addEventListener("pointermove", this.onPointerMove);
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 9a5d21b49..b7d8eda9c 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -181,11 +181,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         }
         this._hitExpander = DocListCast(this.props.Document.subBulletDocs).length > 0;
         if (e.shiftKey && e.buttons === 1) {
-            if (this.props.isTopMost) {
-                this.startDragging(e.pageX, e.pageY, e.altKey || e.ctrlKey ? "alias" : undefined, this._hitExpander);
-            } else if (this.props.Document) {
-                CollectionDockingView.Instance.StartOtherDrag([Doc.MakeAlias(this.props.Document)], e);
-            }
+            CollectionDockingView.Instance.StartOtherDrag([Doc.MakeAlias(this.props.Document)], e);
             e.stopPropagation();
         } else if (this.active) {
             //e.stopPropagation(); // bcz: doing this will block click events from CollectionFreeFormDocumentView which are needed for iconifying,etc
-- 
cgit v1.2.3-70-g09d2


From 8b647aec9184f92364d396d755f4b32bd47af67c Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Sat, 18 May 2019 17:33:26 -0400
Subject: more debugging

---
 .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 264c89d67..63c090d84 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -138,7 +138,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             let y = this.Document.panY || 0;
             let docs = this.childDocs || [];
             let [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
-            if (!this.isAnnotationOverlay) {
+            if (false && !this.isAnnotationOverlay) {
                 let minx = docs.length ? NumCast(docs[0].x) : 0;
                 let maxx = docs.length ? NumCast(docs[0].width) + minx : minx;
                 let miny = docs.length ? NumCast(docs[0].y) : 0;
-- 
cgit v1.2.3-70-g09d2


From 20a1c2a1e59c02b29bbe744c57df6022952e2741 Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Sat, 18 May 2019 18:10:31 -0400
Subject: more debugging

---
 src/client/views/collections/CollectionTreeView.tsx                    | 3 +--
 .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx    | 2 +-
 src/server/index.ts                                                    | 3 ---
 3 files changed, 2 insertions(+), 6 deletions(-)

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

diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 4cc4ae6b6..72fa69cb1 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -17,7 +17,6 @@ import { undoBatch } from '../../util/UndoManager';
 import { CurrentUserUtils } from '../../../server/authentication/models/current_user_utils';
 import { CollectionDockingView } from './CollectionDockingView';
 import { DocumentManager } from '../../util/DocumentManager';
-import { List } from '../../../new_fields/List';
 import { Docs } from '../../documents/Documents';
 import { MainView } from '../MainView';
 
@@ -232,7 +231,7 @@ export class CollectionTreeView extends CollectionSubView(Document) {
             <div id="body" className="collectionTreeView-dropTarget"
                 style={{ borderRadius: "inherit" }}
                 onContextMenu={this.onContextMenu}
-                onWheel={(e: React.WheelEvent) => e.stopPropagation()}
+                onWheel={(e: React.WheelEvent) => this.props.isSelected() && e.stopPropagation()}
                 onDrop={(e: React.DragEvent) => this.onDrop(e, {})} ref={this.createDropTarget}>
                 <div className="coll-title">
                     <EditableView
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 63c090d84..264c89d67 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -138,7 +138,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             let y = this.Document.panY || 0;
             let docs = this.childDocs || [];
             let [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
-            if (false && !this.isAnnotationOverlay) {
+            if (!this.isAnnotationOverlay) {
                 let minx = docs.length ? NumCast(docs[0].x) : 0;
                 let maxx = docs.length ? NumCast(docs[0].width) + minx : minx;
                 let miny = docs.length ? NumCast(docs[0].y) : 0;
diff --git a/src/server/index.ts b/src/server/index.ts
index 9696dab94..d19c65e0a 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -278,7 +278,6 @@ function getFields([ids, callback]: [string[], (result: Transferable[]) => void]
 }
 
 function setField(socket: Socket, newValue: Transferable) {
-    return;
     Database.Instance.update(newValue.id, newValue, () =>
         socket.broadcast.emit(MessageStore.SetField.Message, newValue));
     if (newValue.type === Types.Text) {
@@ -347,7 +346,6 @@ function getSuffix(value: string | [string, any]): string {
 }
 
 function UpdateField(socket: Socket, diff: Diff) {
-    return;
     Database.Instance.update(diff.id, diff.diff,
         () => socket.broadcast.emit(MessageStore.UpdateField.Message, diff), false, "newDocuments");
     const docfield = diff.diff.$set;
@@ -374,7 +372,6 @@ function UpdateField(socket: Socket, diff: Diff) {
 }
 
 function CreateField(newValue: any) {
-    return;
     Database.Instance.insert(newValue, "newDocuments");
 }
 
-- 
cgit v1.2.3-70-g09d2


From 130b5c55f954a011e91355c79ade4b9f91bd84e9 Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Sat, 18 May 2019 18:17:39 -0400
Subject: clamped scale and reverted safe mode

---
 src/client/views/collections/CollectionBaseView.tsx        | 14 +++++++-------
 .../collectionFreeForm/CollectionFreeFormView.tsx          |  2 +-
 2 files changed, 8 insertions(+), 8 deletions(-)

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

diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx
index 73eb1fbbc..2da8c4e40 100644
--- a/src/client/views/collections/CollectionBaseView.tsx
+++ b/src/client/views/collections/CollectionBaseView.tsx
@@ -16,7 +16,7 @@ export enum CollectionViewType {
     Schema,
     Docking,
     Tree,
-    RealFreeform
+    // RealFreeform
 }
 
 export interface CollectionRenderProps {
@@ -40,12 +40,12 @@ export class CollectionBaseView extends React.Component<CollectionViewProps> {
     get collectionViewType(): CollectionViewType | undefined {
         let Document = this.props.Document;
         let viewField = Cast(Document.viewType, "number");
-        if (viewField === CollectionViewType.Freeform) {
-            return CollectionViewType.Tree;
-        }
-        if (viewField === CollectionViewType.RealFreeform) {
-            return CollectionViewType.Freeform;
-        }
+        // if (viewField === CollectionViewType.Freeform) {
+        //     return CollectionViewType.Tree;
+        // }
+        // if (viewField === CollectionViewType.RealFreeform) {
+        //     return CollectionViewType.Freeform;
+        // }
         if (viewField !== undefined) {
             return viewField;
         } else {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 264c89d67..956a5668a 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -211,7 +211,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             let [x, y] = this.getTransform().transformPoint(e.clientX, e.clientY);
             let localTransform = this.getLocalTransform().inverse().scaleAbout(deltaScale, x, y);
 
-            let safeScale = Math.abs(localTransform.Scale);
+            let safeScale = Math.max(0.002, localTransform.Scale);
             this.props.Document.scale = Math.abs(safeScale);
             this.setPan(-localTransform.TranslateX / safeScale, -localTransform.TranslateY / safeScale);
             e.stopPropagation();
-- 
cgit v1.2.3-70-g09d2


From 3be734d7bca7276e173a9c50a1163c697143bb64 Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Sat, 18 May 2019 19:28:42 -0400
Subject: Clamped scale of collections

---
 .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 956a5668a..33521528f 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -211,7 +211,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             let [x, y] = this.getTransform().transformPoint(e.clientX, e.clientY);
             let localTransform = this.getLocalTransform().inverse().scaleAbout(deltaScale, x, y);
 
-            let safeScale = Math.max(0.002, localTransform.Scale);
+            let safeScale = Math.min(Math.max(0.15, localTransform.Scale), 40);
             this.props.Document.scale = Math.abs(safeScale);
             this.setPan(-localTransform.TranslateX / safeScale, -localTransform.TranslateY / safeScale);
             e.stopPropagation();
-- 
cgit v1.2.3-70-g09d2


From ff3ef22630ad9c32b4ed1b0872bbc8b5753761eb Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sat, 18 May 2019 23:16:36 -0400
Subject: fixed zoomBasis issues with wrapping, text size, and normalizing
 outlines.

---
 src/client/views/DocumentDecorations.tsx           | 34 ++++++++++------------
 .../views/collections/CollectionBaseView.tsx       |  2 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  8 ++---
 3 files changed, 21 insertions(+), 23 deletions(-)

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

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index d440ed898..5ec090f05 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -431,31 +431,29 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
         SelectionManager.SelectedDocuments().forEach(element => {
             const rect = element.ContentDiv ? element.ContentDiv.getBoundingClientRect() : new DOMRect();
 
-            if (rect.width !== 0) {
+            if (rect.width !== 0 && (dX != 0 || dY != 0 || dW != 0 || dH != 0)) {
                 let doc = PositionDocument(element.props.Document);
-                let width = FieldValue(doc.width, 0);
-                let nwidth = FieldValue(doc.nativeWidth, 0);
-                let nheight = FieldValue(doc.nativeHeight, 0);
-                let height = FieldValue(doc.height, nwidth ? nheight / nwidth * width : 0);
-                let x = FieldValue(doc.x, 0);
-                let y = FieldValue(doc.y, 0);
+                let nwidth = doc.nativeWidth || 0;
+                let nheight = doc.nativeHeight || 0;
+                let zoomBasis = NumCast(doc.zoomBasis, 1);
+                let width = (doc.width || 0) / zoomBasis;
+                let height = (doc.height || (nheight / nwidth * width)) / zoomBasis;
                 let scale = width / rect.width;
                 let actualdW = Math.max(width + (dW * scale), 20);
                 let actualdH = Math.max(height + (dH * scale), 20);
-                x += dX * (actualdW - width);
-                y += dY * (actualdH - height);
-                doc.x = x;
-                doc.y = y;
-                var nativeWidth = FieldValue(doc.nativeWidth, 0);
-                var nativeHeight = FieldValue(doc.nativeHeight, 0);
-                if (nativeWidth > 0 && nativeHeight > 0) {
+                doc.x = (doc.x || 0) + dX * (actualdW - width);
+                doc.y = (doc.y || 0) + dY * (actualdH - height);
+                if (nwidth > 0 && nheight > 0) {
                     if (Math.abs(dW) > Math.abs(dH)) {
-                        actualdH = nativeHeight / nativeWidth * actualdW;
+                        doc.zoomBasis = zoomBasis * width / actualdW;
                     }
-                    else actualdW = nativeWidth / nativeHeight * actualdH;
+                    else {
+                        doc.zoomBasis = zoomBasis * height / actualdH;
+                    }
+                } else {
+                    doc.width = zoomBasis * actualdW;
+                    doc.height = zoomBasis * actualdH;
                 }
-                doc.width = actualdW;
-                doc.height = actualdH;
             }
         });
     }
diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx
index 2da8c4e40..76270f2e8 100644
--- a/src/client/views/collections/CollectionBaseView.tsx
+++ b/src/client/views/collections/CollectionBaseView.tsx
@@ -114,7 +114,7 @@ export class CollectionBaseView extends React.Component<CollectionViewProps> {
             }
             // set the ZoomBasis only if hasn't already been set -- bcz: maybe set/resetting the ZoomBasis should be a parameter to addDocument?
             if (!alreadyAdded && (this.collectionViewType === CollectionViewType.Freeform || this.collectionViewType === CollectionViewType.Invalid)) {
-                let zoom = NumCast(this.props.Document.scale, 1);
+                let zoom = NumCast(this.props.Document.scale, 1) / this.props.ScreenToLocalTransform().Scale;// ;
                 Doc.SetOnPrototype(doc, "zoomBasis", zoom);
             }
         }
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 33521528f..b4b811da4 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -140,14 +140,14 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             let [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
             if (!this.isAnnotationOverlay) {
                 let minx = docs.length ? NumCast(docs[0].x) : 0;
-                let maxx = docs.length ? NumCast(docs[0].width) + minx : minx;
+                let maxx = docs.length ? NumCast(docs[0].width) / NumCast(docs[0].zoomBasis) + minx : minx;
                 let miny = docs.length ? NumCast(docs[0].y) : 0;
-                let maxy = docs.length ? NumCast(docs[0].height) + miny : miny;
+                let maxy = docs.length ? NumCast(docs[0].height) / NumCast(docs[0].zoomBasis) + miny : miny;
                 let ranges = docs.filter(doc => doc).reduce((range, doc) => {
                     let x = NumCast(doc.x);
-                    let xe = x + NumCast(doc.width);
+                    let xe = x + NumCast(doc.width) / NumCast(doc.zoomBasis);
                     let y = NumCast(doc.y);
-                    let ye = y + NumCast(doc.height);
+                    let ye = y + NumCast(doc.height) / NumCast(doc.zoomBasis);
                     return [[range[0][0] > x ? x : range[0][0], range[0][1] < xe ? xe : range[0][1]],
                     [range[1][0] > y ? y : range[1][0], range[1][1] < ye ? ye : range[1][1]]];
                 }, [[minx, maxx], [miny, maxy]]);
-- 
cgit v1.2.3-70-g09d2


From 12796ace87581ffeac9d67fa5d7ebff8cecd1a52 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sun, 19 May 2019 11:33:42 -0400
Subject: added opaque background for non-annotation collections.  fixed
 marquee view when there's zoomBasis, fixed double-click opening to
 stopPropagation. got rid of RIGHT_BTN_DRAG stuff.

---
 .../views/collections/CollectionBaseView.tsx       |  4 ++--
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 11 +++--------
 .../collections/collectionFreeForm/MarqueeView.tsx | 23 ++++++++--------------
 .../views/nodes/CollectionFreeFormDocumentView.tsx |  3 ++-
 src/client/views/nodes/DocumentView.tsx            |  5 +----
 5 files changed, 16 insertions(+), 30 deletions(-)

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

diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx
index 76270f2e8..54e76fd5e 100644
--- a/src/client/views/collections/CollectionBaseView.tsx
+++ b/src/client/views/collections/CollectionBaseView.tsx
@@ -89,7 +89,7 @@ export class CollectionBaseView extends React.Component<CollectionViewProps> {
         }
         return false;
     }
-    @computed get isAnnotationOverlay() { return this.props.fieldKey && this.props.fieldKey === "annotations"; }
+    @computed get isAnnotationOverlay() { return this.props.fieldKey === "annotations"; }
 
     @action.bound
     addDocument(doc: Doc, allowDuplicates: boolean = false): boolean {
@@ -114,7 +114,7 @@ export class CollectionBaseView extends React.Component<CollectionViewProps> {
             }
             // set the ZoomBasis only if hasn't already been set -- bcz: maybe set/resetting the ZoomBasis should be a parameter to addDocument?
             if (!alreadyAdded && (this.collectionViewType === CollectionViewType.Freeform || this.collectionViewType === CollectionViewType.Invalid)) {
-                let zoom = NumCast(this.props.Document.scale, 1) / this.props.ScreenToLocalTransform().Scale;// ;
+                let zoom = NumCast(this.props.Document.scale, 1);
                 Doc.SetOnPrototype(doc, "zoomBasis", zoom);
             }
         }
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index b4b811da4..9cb8443f4 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -37,7 +37,6 @@ const PanZoomDocument = makeInterface(panZoomSchema, positionSchema, pageSchema)
 
 @observer
 export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
-    public static RIGHT_BTN_DRAG = false;
     private _selectOnLoaded: string = ""; // id of document that should be selected once it's loaded (used for click-to-type)
     private _lastX: number = 0;
     private _lastY: number = 0;
@@ -46,8 +45,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
     @computed get nativeWidth() { return this.Document.nativeWidth || 0; }
     @computed get nativeHeight() { return this.Document.nativeHeight || 0; }
+    public get isAnnotationOverlay() { return this.props.fieldKey && this.props.fieldKey === "annotations"; }
     private get borderWidth() { return this.isAnnotationOverlay ? 0 : COLLECTION_BORDER_WIDTH; }
-    private get isAnnotationOverlay() { return this.props.fieldKey && this.props.fieldKey === "annotations"; }
     private panX = () => this.Document.panX || 0;
     private panY = () => this.Document.panY || 0;
     private zoomScaling = () => this.Document.scale || 1;
@@ -66,7 +65,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         return true;
     }
     private selectDocuments = (docs: Doc[]) => {
-        SelectionManager.DeselectAll;
+        SelectionManager.DeselectAll();
         docs.map(doc => DocumentManager.Instance.getDocumentView(doc)).filter(dv => dv).map(dv =>
             SelectionManager.SelectDoc(dv!, true));
     }
@@ -112,11 +111,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
     @action
     onPointerDown = (e: React.PointerEvent): void => {
-        if ((CollectionFreeFormView.RIGHT_BTN_DRAG &&
-            (((e.button === 2 && (!this.isAnnotationOverlay || this.zoomScaling() !== 1)) ||
-                (e.button === 0 && e.altKey)) && this.props.active())) ||
-            (!CollectionFreeFormView.RIGHT_BTN_DRAG &&
-                ((e.button === 0 && !e.shiftKey && !e.altKey && (!this.isAnnotationOverlay || this.zoomScaling() !== 1)) && this.props.active()))) {
+        if (e.button === 0 && !e.shiftKey && !e.altKey && (!this.isAnnotationOverlay || this.zoomScaling() !== 1) && this.props.active()) {
             document.removeEventListener("pointermove", this.onPointerMove);
             document.removeEventListener("pointerup", this.onPointerUp);
             document.addEventListener("pointermove", this.onPointerMove);
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index d102c8af2..4587c2227 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -132,17 +132,18 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
         this._downY = this._lastY = e.pageY;
         this._commandExecuted = false;
         PreviewCursor.Visible = false;
-        if ((CollectionFreeFormView.RIGHT_BTN_DRAG && e.button === 0 && !e.altKey && !e.metaKey && this.props.container.props.active()) ||
-            (!CollectionFreeFormView.RIGHT_BTN_DRAG && (e.button === 2 || (e.button === 0 && e.altKey)) && this.props.container.props.active())) {
+        if (e.button === 2 || (e.button === 0 && e.altKey)) {
+            if (!this.props.container.props.active()) this.props.selectDocuments([this.props.container.props.Document]);
             document.addEventListener("pointermove", this.onPointerMove, true);
             document.addEventListener("pointerup", this.onPointerUp, true);
             document.addEventListener("keydown", this.marqueeCommand, true);
-            // bcz: do we need this?   it kills the context menu on the main collection
+            if (e.altKey) {
+                e.stopPropagation();
+                e.preventDefault();
+            }
+            // bcz: do we need this?   it kills the context menu on the main collection if !altKey
             // e.stopPropagation();
         }
-        if (e.altKey) {
-            e.preventDefault();
-        }
     }
 
     @action
@@ -248,6 +249,7 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
                 panX: 0,
                 panY: 0,
                 borderRounding: e.key === "e" ? -1 : undefined,
+                backgroundColor: this.props.container.isAnnotationOverlay ? undefined : "white",
                 scale: zoomBasis,
                 width: bounds.width * zoomBasis,
                 height: bounds.height * zoomBasis,
@@ -275,15 +277,6 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
                     //this.props.addDocument(newCollection, false);
                     summary.proto!.summarizedDocs = new List<Doc>(selected);
                     summary.proto!.maximizeLocation = "inTab";  // or "inPlace", or "onRight"
-                    //summary.proto!.isButton = true;
-                    //let scrpt = this.props.getTransform().inverse().transformPoint(bounds.left, bounds.top);
-                    // selected.map(summarizedDoc => {
-                    //     let maxx = NumCast(summarizedDoc.x, undefined);
-                    //     let maxy = NumCast(summarizedDoc.y, undefined);
-                    //     let maxw = NumCast(summarizedDoc.width, undefined);
-                    //     let maxh = NumCast(summarizedDoc.height, undefined);
-                    //     summarizedDoc.isIconAnimating = new List<number>([scrpt[0], scrpt[1], maxx, maxy, maxw, maxh, Date.now(), 0]);
-                    // });
                     this.props.addLiveTextDocument(summary);
                 });
             }
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 7cb4c1dfe..8851e4b93 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -180,8 +180,9 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
     }
     onPointerUp = (e: PointerEvent): void => {
         document.removeEventListener("pointerup", this.onPointerUp);
-        if (Math.abs(e.clientX - this._downX) < 2 && Math.abs(e.clientY - this._downY) < 2) {
+        if (!(e as any).propagationIsStopped && Math.abs(e.clientX - this._downX) < 2 && Math.abs(e.clientY - this._downY) < 2) {
             this.props.addDocTab(this.props.Document, "inTab");
+            (e as any).propagationIsStopped = true;
         }
         e.stopPropagation();
     }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 760e31b49..bb5daaf4e 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -187,9 +187,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     onPointerDown = (e: React.PointerEvent): void => {
         this._downX = e.clientX;
         this._downY = e.clientY;
-        if (CollectionFreeFormView.RIGHT_BTN_DRAG && (e.button === 2 || (e.button === 0 && e.altKey)) && !this.isSelected()) {
-            return;
-        }
         this._hitExpander = DocListCast(this.props.Document.subBulletDocs).length > 0;
         if (e.shiftKey && e.buttons === 1) {
             CollectionDockingView.Instance.StartOtherDrag([Doc.MakeAlias(this.props.Document)], e);
@@ -207,7 +204,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) {
                 document.removeEventListener("pointermove", this.onPointerMove);
                 document.removeEventListener("pointerup", this.onPointerUp);
-                if (!e.altKey && !this.topMost && (!CollectionFreeFormView.RIGHT_BTN_DRAG && e.buttons === 1) || (CollectionFreeFormView.RIGHT_BTN_DRAG && e.buttons === 2)) {
+                if (!e.altKey && !this.topMost && e.buttons === 1) {
                     this.startDragging(this._downX, this._downY, e.ctrlKey || e.altKey ? "alias" : undefined, this._hitExpander);
                 }
             }
-- 
cgit v1.2.3-70-g09d2

