From 1c7c38868978b0f68dbad8a9e07d3d30967c23e1 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Tue, 10 Dec 2019 11:22:58 -0500
Subject: fixes to text box inlines for selection.

---
 src/client/views/nodes/FormattedTextBox.tsx | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

(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 6d3c1434a..42723b44b 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -828,7 +828,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
                 clipboardTextSerializer: this.clipboardTextSerializer,
                 handlePaste: this.handlePaste,
             });
-            if (startup) {
+            if (startup && this._editorView) {
                 Doc.GetProto(doc).documentText = undefined;
                 this._editorView.dispatch(this._editorView.state.tr.insertText(startup));
             }
@@ -869,7 +869,10 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
         this._buttonBarReactionDisposer && this._buttonBarReactionDisposer();
         this._editorView && this._editorView.destroy();
     }
+
+    static _downEvent: any;
     onPointerDown = (e: React.PointerEvent): void => {
+        FormattedTextBox._downEvent = true;
         FormattedTextBoxComment.textBox = this;
         const pos = this._editorView!.posAtCoords({ left: e.clientX, top: e.clientY });
         pos && (this._nodeClicked = this._editorView!.state.doc.nodeAt(pos.pos));
@@ -885,6 +888,8 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
     }
 
     onPointerUp = (e: React.PointerEvent): void => {
+        if (!FormattedTextBox._downEvent) return;
+        FormattedTextBox._downEvent = false;
         if (!(e.nativeEvent as any).formattedHandled) {
             FormattedTextBoxComment.textBox = this;
             FormattedTextBoxComment.update(this._editorView!);
-- 
cgit v1.2.3-70-g09d2


From fe06511da85a9483c10353f0cc5d54b70a265079 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Tue, 10 Dec 2019 15:54:01 -0500
Subject: added alt-t for toggle between editing title and text

---
 src/client/util/RichTextRules.ts               | 18 +++++++++---------
 src/client/views/EditableView.tsx              |  2 ++
 src/client/views/nodes/DocumentView.tsx        | 22 ++++++++++++++++++++--
 src/client/views/nodes/FormattedTextBox.tsx    | 21 +++++++++++++++------
 src/server/authentication/models/user_model.ts |  2 +-
 5 files changed, 47 insertions(+), 18 deletions(-)

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

diff --git a/src/client/util/RichTextRules.ts b/src/client/util/RichTextRules.ts
index 4e60976d5..5f2d67a3e 100644
--- a/src/client/util/RichTextRules.ts
+++ b/src/client/util/RichTextRules.ts
@@ -64,10 +64,10 @@ export const inpRules = {
             new RegExp(/^#([0-9]+)\s$/),
             (state, match, start, end) => {
                 const size = Number(match[1]);
-                const ruleProvider = FormattedTextBox.InputBoxOverlay!.props.ruleProvider;
-                const heading = NumCast(FormattedTextBox.InputBoxOverlay!.props.Document.heading);
+                const ruleProvider = FormattedTextBox.FocusedBox!.props.ruleProvider;
+                const heading = NumCast(FormattedTextBox.FocusedBox!.props.Document.heading);
                 if (ruleProvider && heading) {
-                    (Cast(FormattedTextBox.InputBoxOverlay!.props.Document, Doc) as Doc).heading = size;
+                    (Cast(FormattedTextBox.FocusedBox!.props.Document, Doc) as Doc).heading = size;
                     return state.tr.deleteRange(start, end);
                 }
                 return state.tr.deleteRange(start, end).addStoredMark(schema.marks.pFontSize.create({ fontSize: size }));
@@ -163,8 +163,8 @@ export const inpRules = {
             (state, match, start, end) => {
                 const node = (state.doc.resolve(start) as any).nodeAfter;
                 const sm = state.storedMarks || undefined;
-                const ruleProvider = FormattedTextBox.InputBoxOverlay!.props.ruleProvider;
-                const heading = NumCast(FormattedTextBox.InputBoxOverlay!.props.Document.heading);
+                const ruleProvider = FormattedTextBox.FocusedBox!.props.ruleProvider;
+                const heading = NumCast(FormattedTextBox.FocusedBox!.props.Document.heading);
                 if (ruleProvider && heading) {
                     ruleProvider["ruleAlign_" + heading] = "center";
                     return node ? state.tr.deleteRange(start, end).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr;
@@ -178,8 +178,8 @@ export const inpRules = {
             (state, match, start, end) => {
                 const node = (state.doc.resolve(start) as any).nodeAfter;
                 const sm = state.storedMarks || undefined;
-                const ruleProvider = FormattedTextBox.InputBoxOverlay!.props.ruleProvider;
-                const heading = NumCast(FormattedTextBox.InputBoxOverlay!.props.Document.heading);
+                const ruleProvider = FormattedTextBox.FocusedBox!.props.ruleProvider;
+                const heading = NumCast(FormattedTextBox.FocusedBox!.props.Document.heading);
                 if (ruleProvider && heading) {
                     ruleProvider["ruleAlign_" + heading] = "left";
                     return node ? state.tr.deleteRange(start, end).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr;
@@ -193,8 +193,8 @@ export const inpRules = {
             (state, match, start, end) => {
                 const node = (state.doc.resolve(start) as any).nodeAfter;
                 const sm = state.storedMarks || undefined;
-                const ruleProvider = FormattedTextBox.InputBoxOverlay!.props.ruleProvider;
-                const heading = NumCast(FormattedTextBox.InputBoxOverlay!.props.Document.heading);
+                const ruleProvider = FormattedTextBox.FocusedBox!.props.ruleProvider;
+                const heading = NumCast(FormattedTextBox.FocusedBox!.props.Document.heading);
                 if (ruleProvider && heading) {
                     ruleProvider["ruleAlign_" + heading] = "right";
                     return node ? state.tr.deleteRange(start, end).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr;
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index ea9d548a1..d0cecf03d 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -120,7 +120,9 @@ export class EditableView extends React.Component<EditableProps> {
 
     @action
     setIsFocused = (value: boolean) => {
+        let wasFocused = this._editing;
         this._editing = value;
+        return wasFocused !== this._editing;
     }
 
     render() {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index c6b134d6c..9219da80b 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -92,6 +92,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     private _hitTemplateDrag = false;
     private _mainCont = React.createRef<HTMLDivElement>();
     private _dropDisposer?: DragManager.DragDropDisposer;
+    private _titleRef = React.createRef<EditableView>();
 
     public get displayName() { return "DocumentView(" + this.props.Document.title + ")"; } // this makes mobx trace() statements more descriptive
     public get ContentDiv() { return this._mainCont.current; }
@@ -138,6 +139,23 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         }
     }
 
+    onKeyDown = (e: React.KeyboardEvent) => {
+        if (e.altKey && e.key === "t" && !(e.nativeEvent as any).StopPropagationForReal) {
+            (e.nativeEvent as any).StopPropagationForReal = true; // e.stopPropagation() doesn't seem to work...
+            e.stopPropagation();
+            if (!StrCast(this.Document.showTitle)) this.Document.showTitle = "title";
+            if (!this._titleRef.current) setTimeout(() => this._titleRef.current?.setIsFocused(true), 0);
+            else if (!this._titleRef.current.setIsFocused(true)) { // if focus didn't change, focus on interior text...
+                {
+                    this._titleRef.current?.setIsFocused(false);
+                    let any = (this._mainCont.current?.getElementsByClassName("ProseMirror")?.[0] as any);
+                    any.keeplocation = true;
+                    any?.focus();
+                }
+            }
+        }
+    }
+
     onClick = async (e: React.MouseEvent) => {
         if (!e.nativeEvent.cancelBubble && !this.Document.ignoreClick && CurrentUserUtils.MainDocId !== this.props.Document[Id] &&
             (Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD && Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD)) {
@@ -622,7 +640,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 position: showTextTitle ? "relative" : "absolute",
                 pointerEvents: SelectionManager.GetIsDragging() ? "none" : "all",
             }}>
-                <EditableView
+                <EditableView ref={this._titleRef}
                     contents={this.Document[showTitle]}
                     display={"block"} height={72} fontSize={12}
                     GetValue={() => StrCast(this.Document[showTitle])}
@@ -694,7 +712,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         const highlightColors = ["transparent", "maroon", "maroon", "yellow", "magenta", "cyan", "orange"];
         const highlightStyles = ["solid", "dashed", "solid", "solid", "solid", "solid", "solid"];
         const highlighting = fullDegree && this.layoutDoc.type !== DocumentType.FONTICON && this.layoutDoc.viewType !== CollectionViewType.Linear;
-        return <div className={`documentView-node${this.topMost ? "-topmost" : ""}`} ref={this._mainCont}
+        return <div className={`documentView-node${this.topMost ? "-topmost" : ""}`} ref={this._mainCont} onKeyDown={this.onKeyDown}
             onDrop={this.onDrop} onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown} onClick={this.onClick}
             onPointerEnter={e => Doc.BrushDoc(this.props.Document)} onPointerLeave={e => Doc.UnBrushDoc(this.props.Document)}
             style={{
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 42723b44b..70fa4974d 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -80,7 +80,6 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
     private _proseRef?: HTMLDivElement;
     private _editorView: Opt<EditorView>;
     private _applyingChange: boolean = false;
-    private _nodeClicked: any;
     private _searchIndex = 0;
     private _sidebarMovement = 0;
     private _lastX = 0;
@@ -101,6 +100,8 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
     @observable private _ruleFontFamily = "Arial";
     @observable private _fontAlign = "";
     @observable private _entered = false;
+
+    public static FocusedBox: FormattedTextBox | undefined;
     public static SelectOnLoad = "";
     public static IsFragment(html: string) {
         return html.indexOf("data-pm-slice") !== -1;
@@ -874,8 +875,6 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
     onPointerDown = (e: React.PointerEvent): void => {
         FormattedTextBox._downEvent = true;
         FormattedTextBoxComment.textBox = this;
-        const pos = this._editorView!.posAtCoords({ left: e.clientX, top: e.clientY });
-        pos && (this._nodeClicked = this._editorView!.state.doc.nodeAt(pos.pos));
         if (this.props.onClick && e.button === 0) {
             e.preventDefault();
         }
@@ -901,11 +900,17 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
         }
     }
 
-    static InputBoxOverlay: FormattedTextBox | undefined;
     @action
     onFocused = (e: React.FocusEvent): void => {
-        FormattedTextBox.InputBoxOverlay = this;
+        FormattedTextBox.FocusedBox = this;
         this.tryUpdateHeight();
+
+        // see if we need to preserve the insertion point
+        let prosediv = this._proseRef?.children?.[0] as any;
+        let keeplocation = prosediv?.keeplocation;
+        prosediv && (prosediv.keeplocation = undefined);
+        let pos = this._editorView?.state.selection.$from.pos || 1;
+        keeplocation && setTimeout(() => this._editorView?.dispatch(this._editorView?.state.tr.setSelection(TextSelection.create(this._editorView.state.doc, pos))));
     }
     onPointerWheel = (e: React.WheelEvent): void => {
         // if a text note is not selected and scrollable, this prevents us from being able to scroll and zoom out at the same time
@@ -1048,10 +1053,14 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
             this._undoTyping.end();
             this._undoTyping = undefined;
         }
-        this.doLinkOnDeselect();
+        this.doLinkOnDeselect(); 6
     }
 
     onKeyPress = (e: React.KeyboardEvent) => {
+        if (e.altKey) {
+            e.preventDefault();
+            return;
+        }
         if (!this._editorView!.state.selection.empty && e.key === "%") {
             (this._editorView!.state as any).EnteringStyle = true;
             e.preventDefault();
diff --git a/src/server/authentication/models/user_model.ts b/src/server/authentication/models/user_model.ts
index 48910b612..6b71397dc 100644
--- a/src/server/authentication/models/user_model.ts
+++ b/src/server/authentication/models/user_model.ts
@@ -73,8 +73,8 @@ userSchema.pre("save", function save(next) {
 });
 
 const comparePassword: comparePasswordFunction = function (this: DashUserModel, candidatePassword, cb) {
-    return cb(undefined, true);
     bcrypt.compare(candidatePassword, this.password, cb);
+    // return cb(undefined, true);  // use this to bypass passwords
 };
 
 userSchema.methods.comparePassword = comparePassword;
-- 
cgit v1.2.3-70-g09d2

