From 7edce1af91621b7724e4763a5afabb4ab86d183c Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sat, 14 Dec 2019 21:49:09 -0500
Subject: make %@ portal hyperlink creation create a link as well.

---
 src/client/views/nodes/FormattedTextBox.tsx | 1 +
 1 file changed, 1 insertion(+)

(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 a298fd6af..e40c00e54 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -822,6 +822,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
                 clipboardTextSerializer: this.clipboardTextSerializer,
                 handlePaste: this.handlePaste,
             });
+            (this._editorView.state.schema as any).Document = this.props.Document;
             if (startup && this._editorView) {
                 Doc.GetProto(doc).documentText = undefined;
                 this._editorView.dispatch(this._editorView.state.tr.insertText(startup));
-- 
cgit v1.2.3-70-g09d2


From 877a6f481a06e2454ff9d8eabe43acb0e58a2676 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sun, 15 Dec 2019 10:38:23 -0500
Subject: writing selectedDocs to user doc to allow selection to be part of
 scripting

---
 src/client/util/DragManager.ts              |  2 +-
 src/client/util/SelectionManager.ts         |  3 +++
 src/client/views/nodes/FormattedTextBox.tsx |  2 +-
 src/client/views/nodes/KeyValueBox.tsx      |  3 ++-
 src/new_fields/Doc.ts                       | 12 +++++++++---
 5 files changed, 16 insertions(+), 6 deletions(-)

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

diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 2631a1e3c..df2f5fe3c 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -51,7 +51,7 @@ export function SetupDrag(
             e.stopPropagation();
             if (e.shiftKey && CollectionDockingView.Instance) {
                 e.persist();
-                let dragDoc = await docFunc();
+                const dragDoc = await docFunc();
                 dragDoc && CollectionDockingView.Instance.StartOtherDrag({
                     pageX: e.pageX,
                     pageY: e.pageY,
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index e01216e0f..d9283de35 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -2,6 +2,8 @@ import { observable, action, runInAction, ObservableMap } from "mobx";
 import { Doc } from "../../new_fields/Doc";
 import { DocumentView } from "../views/nodes/DocumentView";
 import { computedFn } from "mobx-utils";
+import { CurrentUserUtils } from "../../server/authentication/models/current_user_utils";
+import { List } from "../../new_fields/List";
 
 export namespace SelectionManager {
 
@@ -27,6 +29,7 @@ export namespace SelectionManager {
                 manager.SelectedDocuments.clear();
                 manager.SelectedDocuments.set(docView, true);
             }
+            Doc.UserDoc().SelectedDocs = new List(SelectionManager.SelectedDocuments().map(dv => dv.props.Document));
         }
         @action
         DeselectDoc(docView: DocumentView): void {
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index e40c00e54..3efbd434e 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -822,7 +822,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
                 clipboardTextSerializer: this.clipboardTextSerializer,
                 handlePaste: this.handlePaste,
             });
-            (this._editorView.state.schema as any).Document = this.props.Document;
+            this._editorView.state.schema.Document = this.props.Document;
             if (startup && this._editorView) {
                 Doc.GetProto(doc).documentText = undefined;
                 this._editorView.dispatch(this._editorView.state.tr.insertText(startup));
diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx
index 322d639dc..07d6d6f5e 100644
--- a/src/client/views/nodes/KeyValueBox.tsx
+++ b/src/client/views/nodes/KeyValueBox.tsx
@@ -57,7 +57,8 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
         value = eq ? value.substr(1) : value;
         const dubEq = value.startsWith(":=") ? "computed" : value.startsWith(";=") ? "script" : false;
         value = dubEq ? value.substr(2) : value;
-        const options: ScriptOptions = { addReturn: true, params: { this: "Doc" } };
+        const editable = value.includes("selectedDocs"); // bcz: Argh TODO - need a UI mechanism for letting user know that a function can't be run read-only. e.g., selectedDocs() wants to cache its old value so it can't be run read-only
+        const options: ScriptOptions = { addReturn: true, params: { this: "Doc" }, editable: editable };
         if (dubEq) options.typecheck = false;
         const script = CompileScript(value, options);
         if (!script.compiled) {
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index aa33d4c8b..a22b289bb 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -1,4 +1,4 @@
-import { observable, ObservableMap, runInAction, action } from "mobx";
+import { observable, ObservableMap, runInAction, action, untracked } from "mobx";
 import { alias, map, serializable } from "serializr";
 import { DocServer } from "../client/DocServer";
 import { DocumentType } from "../client/documents/DocumentTypes";
@@ -474,7 +474,7 @@ export namespace Doc {
         return extension ? extension as Doc : undefined;
     }
     export function fieldExtensionDocSync(doc: Doc, fieldKey: string) {
-        return (doc[fieldKey + "_ext"] as Doc) ||  CreateDocumentExtensionForField(doc, fieldKey);
+        return (doc[fieldKey + "_ext"] as Doc) || CreateDocumentExtensionForField(doc, fieldKey);
     }
 
     export function CreateDocumentExtensionForField(doc: Doc, fieldKey: string) {
@@ -753,4 +753,10 @@ Scripting.addGlobal(function aliasDocs(field: any) { return new List<Doc>(field.
 Scripting.addGlobal(function docList(field: any) { return DocListCast(field); });
 Scripting.addGlobal(function sameDocs(doc1: any, doc2: any) { return Doc.AreProtosEqual(doc1, doc2); });
 Scripting.addGlobal(function undo() { return UndoManager.Undo(); });
-Scripting.addGlobal(function redo() { return UndoManager.Redo(); });
\ No newline at end of file
+Scripting.addGlobal(function redo() { return UndoManager.Redo(); });
+Scripting.addGlobal(function selectedDocs(container: Doc, excludeCollections: boolean) {
+    let docs = DocListCast(Doc.UserDoc().SelectedDocs).filter(d => (!excludeCollections || !Cast(d.data, listSpec(Doc), null)) && d.type !== DocumentType.KVP && !Doc.AreProtosEqual(d, container));
+    if (docs.length) untracked(() => container && (container.cachedSelection = new List(docs)));
+    else docs = untracked(() => DocListCast(container.cachedSelection));
+    return new List(docs);
+});
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 96ada41d4c3c411be63bd656da65bba7894a4224 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Tue, 17 Dec 2019 18:21:22 -0500
Subject: fixed up interactions with documentBox contents.

---
 src/client/views/DocComponent.tsx                  |  1 +
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  2 +-
 .../views/nodes/ContentFittingDocumentView.tsx     |  2 +-
 src/client/views/nodes/DocumentBox.scss            | 12 ++++++---
 src/client/views/nodes/DocumentBox.tsx             | 29 +++++++++++++---------
 src/client/views/nodes/DocumentView.tsx            |  4 +--
 src/client/views/nodes/FormattedTextBox.tsx        |  2 +-
 7 files changed, 32 insertions(+), 20 deletions(-)

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

diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 7fbad4638..7c8e130b5 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -47,6 +47,7 @@ interface DocAnnotatableProps {
     Document: Doc;
     DataDoc?: Doc;
     fieldKey: string;
+    active: () => boolean;
     whenActiveChanged: (isActive: boolean) => void;
     isSelected: (outsideReaction?: boolean) => boolean;
     renderDepth: number;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index ddd4fea56..22983e730 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -911,7 +911,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             <div className={"collectionfreeformview-container"} ref={this.createDropTarget} onWheel={this.onPointerWheel}//pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined,
                 style={{ pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined, height: this.isAnnotationOverlay ? (this.props.Document.scrollHeight ? this.Document.scrollHeight : "100%") : this.props.PanelHeight() }}
                 onPointerDown={this.onPointerDown} onPointerMove={this.onCursorMove} onDrop={this.onDrop.bind(this)} onContextMenu={this.onContextMenu} onTouchStart={this.onTouchStart}>
-                {!BoolCast(this.Document.LODdisable) && !this.props.isAnnotationOverlay && this.props.renderDepth > 0 &&
+                {!BoolCast(this.Document.LODdisable) && !this.props.isAnnotationOverlay && this.props.renderDepth > 0 && this.props.CollectionView &&
                     this.Document[WidthSym]() * this.Document[HeightSym]() / this.props.ScreenToLocalTransform().Scale / this.props.ScreenToLocalTransform().Scale <
                     NumCast(this.Document.LODarea, 100000) ?
                     this.placeholder : this.marqueeView}
diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx
index e15790c9d..2f8142a44 100644
--- a/src/client/views/nodes/ContentFittingDocumentView.tsx
+++ b/src/client/views/nodes/ContentFittingDocumentView.tsx
@@ -111,7 +111,7 @@ export class ContentFittingDocumentView extends React.Component<ContentFittingDo
                         pinToPres={this.props.pinToPres}
                         parentActive={this.props.active}
                         ScreenToLocalTransform={this.getTransform}
-                        renderDepth={this.props.renderDepth + 1}
+                        renderDepth={this.props.renderDepth}
                         ContentScaling={this.contentScaling}
                         PanelWidth={this.PanelWidth}
                         PanelHeight={this.PanelHeight}
diff --git a/src/client/views/nodes/DocumentBox.scss b/src/client/views/nodes/DocumentBox.scss
index c70b324de..b7d06b364 100644
--- a/src/client/views/nodes/DocumentBox.scss
+++ b/src/client/views/nodes/DocumentBox.scss
@@ -3,7 +3,13 @@
     height: 100%;
     pointer-events: all;
     background: gray;
-    border: gray solid 15px;
-    border-top: #aaaaa3 inset 15px;
-    border-bottom: #aaaaa3 outset 15px;
+    border: #00000021 solid 15px;
+    border-top: #0000005e inset 15px;
+    border-bottom: #0000005e outset 15px;
+    .documentBox-lock {
+        margin: auto;
+        color: white;
+        margin-top: -15px;
+        position: absolute;
+    }
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/DocumentBox.tsx b/src/client/views/nodes/DocumentBox.tsx
index e23b7a38b..6be0289d7 100644
--- a/src/client/views/nodes/DocumentBox.tsx
+++ b/src/client/views/nodes/DocumentBox.tsx
@@ -5,12 +5,13 @@ import { documentSchema } from "../../../new_fields/documentSchemas";
 import { List } from "../../../new_fields/List";
 import { makeInterface } from "../../../new_fields/Schema";
 import { ComputedField } from "../../../new_fields/ScriptField";
-import { Cast, StrCast } from "../../../new_fields/Types";
+import { Cast, StrCast, BoolCast } from "../../../new_fields/Types";
 import { emptyFunction, emptyPath } from "../../../Utils";
 import { ContextMenu } from "../ContextMenu";
 import { ContextMenuProps } from "../ContextMenuItem";
 import { DocComponent } from "../DocComponent";
 import { ContentFittingDocumentView } from "./ContentFittingDocumentView";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import "./DocumentBox.scss";
 import { FieldView, FieldViewProps } from "./FieldView";
 import React = require("react");
@@ -34,9 +35,8 @@ export class DocumentBox extends DocComponent<FieldViewProps, DocBoxSchema>(DocB
     }
     specificContextMenu = (e: React.MouseEvent): void => {
         const funcs: ContextMenuProps[] = [];
-        funcs.push({ description: "Auto Show Selected", event: () => this.showSelection, icon: "expand-arrows-alt" });
-        funcs.push({ description: "Prev Selection", event: () => this.prevSelection, icon: "expand-arrows-alt" });
-        funcs.push({ description: "Lock Selection", event: () => this.lockSelection, icon: "expand-arrows-alt" });
+        funcs.push({ description: (this.isSelectionLocked() ? "Show" : "Lock") + " Selection", event: () => this.toggleLockSelection, icon: "expand-arrows-alt" });
+        funcs.push({ description: `${this.props.Document.forceActive ? "Select" : "Force"} Contents Active`, event: () => this.props.Document.forceActive = !this.props.Document.forceActive, icon: "project-diagram" });
 
         ContextMenu.Instance.addItem({ description: "DocumentBox Funcs...", subitems: funcs, icon: "asterisk" });
     }
@@ -46,9 +46,12 @@ export class DocumentBox extends DocComponent<FieldViewProps, DocBoxSchema>(DocB
     showSelection = () => {
         Doc.GetProto(this.props.Document)[this.props.fieldKey] = ComputedField.MakeFunction("selectedDocs(this,true,[_last_])?.[0]");
     }
-    toggleLockSelection = () => {
+    isSelectionLocked = () => {
         const kvpstring = Field.toKeyValueString(this.props.Document, this.props.fieldKey);
-        (kvpstring.startsWith("=") || kvpstring.startsWith(":=")) ? this.lockSelection() : this.showSelection();
+        return !(kvpstring.startsWith("=") || kvpstring.startsWith(":="));
+    }
+    toggleLockSelection = () => {
+        !this.isSelectionLocked() ? this.lockSelection() : this.showSelection();
     }
     prevSelection = () => {
         if (this._curSelection > 0) {
@@ -61,9 +64,6 @@ export class DocumentBox extends DocComponent<FieldViewProps, DocBoxSchema>(DocB
         }
     }
     onPointerDown = (e: React.PointerEvent) => {
-        if (e.button === 0 && !e.altKey) {
-            e.stopPropagation();
-        }
     }
     onClick = (e: React.MouseEvent) => {
         if (this._contRef.current!.getBoundingClientRect().top + 15 > e.clientY) this.toggleLockSelection();
@@ -78,9 +78,14 @@ export class DocumentBox extends DocComponent<FieldViewProps, DocBoxSchema>(DocB
     getTransform = () => this.props.ScreenToLocalTransform().translate(-15, -15);
     render() {
         const containedDoc = this.props.Document[this.props.fieldKey] as Doc;
-        return <div className="documentBox-container" ref={this._contRef} onContextMenu={this.specificContextMenu} onPointerDown={this.onPointerDown} onClick={this.onClick}
+        return <div className="documentBox-container" ref={this._contRef}
+            onContextMenu={this.specificContextMenu}
+            onPointerDown={this.onPointerDown} onClick={this.onClick}
             style={{ background: StrCast(this.props.Document.backgroundColor) }}>
-            {!containedDoc ? (null) : <ContentFittingDocumentView
+            <div className="documentBox-lock">
+                <FontAwesomeIcon icon={this.isSelectionLocked() ? "lock" : "unlock"} size="sm" />
+            </div>
+            {!(containedDoc instanceof Doc) ? (null) : <ContentFittingDocumentView
                 Document={containedDoc}
                 DataDocument={undefined}
                 LibraryPath={emptyPath}
@@ -92,7 +97,7 @@ export class DocumentBox extends DocComponent<FieldViewProps, DocBoxSchema>(DocB
                 addDocTab={this.props.addDocTab}
                 pinToPres={this.props.pinToPres}
                 getTransform={this.getTransform}
-                renderDepth={this.props.renderDepth + 1}
+                renderDepth={this.props.Document.forceActive ? 0 : this.props.renderDepth + 1} // bcz: really need to have an 'alwaysSelected' prop that's not conflated with renderDepth
                 PanelWidth={this.pwidth}
                 PanelHeight={this.pheight}
                 focus={this.props.focus}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 9688c6ad4..8d3c3126d 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -137,7 +137,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         }
     }
 
-     public static FloatDoc(topDocView:DocumentView, x:number, y:number) {
+    public static FloatDoc(topDocView: DocumentView, x: number, y: number) {
         const topDoc = topDocView.props.Document;
         const de = new DragManager.DocumentDragData([topDoc]);
         de.dragDivName = topDocView.props.dragDivName;
@@ -171,7 +171,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 }
             } else if (e.key === "f") {
                 const ex = (e.nativeEvent.target! as any).getBoundingClientRect().left;
-                const ey = (e.nativeEvent.target!as any).getBoundingClientRect().top;
+                const ey = (e.nativeEvent.target! as any).getBoundingClientRect().top;
                 DocumentView.FloatDoc(this, ex, ey);
             }
         }
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 3efbd434e..b19729811 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -873,7 +873,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
         if (this.props.onClick && e.button === 0) {
             e.preventDefault();
         }
-        if (e.button === 0 && this.props.isSelected(true) && !e.altKey && !e.ctrlKey && !e.metaKey) {
+        if (e.button === 0 && this.active(true) && !e.altKey && !e.ctrlKey && !e.metaKey) {
             e.stopPropagation();
         }
         if (e.button === 2 || (e.button === 0 && e.ctrlKey)) {
-- 
cgit v1.2.3-70-g09d2

