aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/util/RichTextRules.ts18
-rw-r--r--src/client/util/RichTextSchema.tsx2
-rw-r--r--src/client/views/EditableView.tsx2
-rw-r--r--src/client/views/OverlayView.tsx4
-rw-r--r--src/client/views/collections/CollectionTreeView.scss1
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx10
-rw-r--r--src/client/views/nodes/DocumentView.tsx22
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx21
-rw-r--r--src/client/views/nodes/FormattedTextBoxComment.tsx4
-rw-r--r--src/client/views/presentationview/PresElementBox.tsx4
-rw-r--r--src/client/views/search/SearchItem.tsx4
-rw-r--r--src/server/authentication/models/user_model.ts7
12 files changed, 66 insertions, 33 deletions
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/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx
index 4a75d6e49..f41846038 100644
--- a/src/client/util/RichTextSchema.tsx
+++ b/src/client/util/RichTextSchema.tsx
@@ -762,7 +762,7 @@ export class DashDocView {
}
});
const self = this;
- this._dashSpan.onkeydown = function (e: any) { e.stopPropagation(); };
+ this._dashSpan.onkeydown = function (e: any) { };
this._dashSpan.onkeypress = function (e: any) { e.stopPropagation(); };
this._dashSpan.onwheel = function (e: any) { e.preventDefault(); };
this._dashSpan.onkeyup = function (e: any) { e.stopPropagation(); };
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/OverlayView.tsx b/src/client/views/OverlayView.tsx
index 9b42d199c..cd330d492 100644
--- a/src/client/views/OverlayView.tsx
+++ b/src/client/views/OverlayView.tsx
@@ -1,7 +1,7 @@
import * as React from "react";
import { observer } from "mobx-react";
import { observable, action, trace, computed } from "mobx";
-import { Utils, emptyFunction, returnOne, returnTrue, returnEmptyString, returnZero, returnFalse } from "../../Utils";
+import { Utils, emptyFunction, returnOne, returnTrue, returnEmptyString, returnZero, returnFalse, emptyPath } from "../../Utils";
import './OverlayView.scss';
import { CurrentUserUtils } from "../../server/authentication/models/current_user_utils";
@@ -174,7 +174,7 @@ export class OverlayView extends React.Component {
return <div className="overlayView-doc" key={d[Id]} onPointerDown={onPointerDown} style={{ transform: `translate(${d.x}px, ${d.y}px)`, display: d.isMinimized ? "none" : "" }}>
<DocumentView
Document={d}
- LibraryPath={[]}
+ LibraryPath={emptyPath}
ChromeHeight={returnZero}
// isSelected={returnFalse}
// select={emptyFunction}
diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss
index 8b12395a7..0b9dc2eb2 100644
--- a/src/client/views/collections/CollectionTreeView.scss
+++ b/src/client/views/collections/CollectionTreeView.scss
@@ -15,6 +15,7 @@
background: $light-color-secondary;
font-size: 13px;
overflow: auto;
+ user-select: none;
cursor: default;
ul {
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index bf612e4f1..a0ddc8884 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -9,7 +9,7 @@ import { List } from '../../../new_fields/List';
import { Document, listSpec } from '../../../new_fields/Schema';
import { ComputedField, ScriptField } from '../../../new_fields/ScriptField';
import { BoolCast, Cast, NumCast, StrCast } from '../../../new_fields/Types';
-import { emptyFunction, Utils, returnFalse } from '../../../Utils';
+import { emptyFunction, Utils, returnFalse, emptyPath } from '../../../Utils';
import { Docs, DocUtils } from '../../documents/Documents';
import { DocumentType } from "../../documents/DocumentTypes";
import { DocumentManager } from '../../util/DocumentManager';
@@ -344,8 +344,8 @@ class TreeView extends React.Component<TreeViewProps> {
<ContentFittingDocumentView
Document={layoutDoc}
DataDocument={this.templateDataDoc}
- LibraryPath={[]}
- renderDepth={this.props.renderDepth}
+ LibraryPath={emptyPath}
+ renderDepth={this.props.renderDepth + 1}
showOverlays={this.noOverlays}
ruleProvider={this.props.document.isRuleProvider && layoutDoc.type !== DocumentType.TEXT ? this.props.document : this.props.ruleProvider}
fitToBox={this.boundsOfCollectionDocument !== undefined}
@@ -626,8 +626,8 @@ export class CollectionTreeView extends CollectionSubView(Document) {
const addDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before, false, false, false);
const moveDoc = (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc);
return !this.childDocs ? (null) : (
- <div id="body" className="collectionTreeView-dropTarget"
- style={{ overflow: "auto", background: StrCast(this.props.Document.backgroundColor, "lightgray"), paddingTop: `${NumCast(this.props.Document.yMargin, 20)}px` }}
+ <div className="collectionTreeView-dropTarget" id="body"
+ style={{ background: StrCast(this.props.Document.backgroundColor, "lightgray"), paddingTop: `${NumCast(this.props.Document.yMargin, 20)}px` }}
onContextMenu={this.onContextMenu}
onWheel={(e: React.WheelEvent) => this._mainEle && this._mainEle.scrollHeight > this._mainEle.clientHeight && e.stopPropagation()}
onDrop={this.onTreeDrop}
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/client/views/nodes/FormattedTextBoxComment.tsx b/src/client/views/nodes/FormattedTextBoxComment.tsx
index ed98d9db6..409229c1a 100644
--- a/src/client/views/nodes/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/FormattedTextBoxComment.tsx
@@ -4,7 +4,7 @@ import { EditorView } from "prosemirror-view";
import * as ReactDOM from 'react-dom';
import { Doc } from "../../../new_fields/Doc";
import { Cast, FieldValue, NumCast } from "../../../new_fields/Types";
-import { emptyFunction, returnEmptyString, returnFalse, Utils } from "../../../Utils";
+import { emptyFunction, returnEmptyString, returnFalse, Utils, emptyPath } from "../../../Utils";
import { DocServer } from "../../DocServer";
import { DocumentManager } from "../../util/DocumentManager";
import { schema } from "../../util/RichTextSchema";
@@ -179,7 +179,7 @@ export class FormattedTextBoxComment {
if (target) {
ReactDOM.render(<ContentFittingDocumentView
Document={target}
- LibraryPath={[]}
+ LibraryPath={emptyPath}
fitToBox={true}
moveDocument={returnFalse}
getTransform={Transform.Identity}
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index cfb9319bb..37c837414 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -9,7 +9,7 @@ import { documentSchema } from '../../../new_fields/documentSchemas';
import { Id } from "../../../new_fields/FieldSymbols";
import { createSchema, makeInterface } from '../../../new_fields/Schema';
import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
-import { emptyFunction, returnFalse } from "../../../Utils";
+import { emptyFunction, returnFalse, emptyPath } from "../../../Utils";
import { DocumentType } from "../../documents/DocumentTypes";
import { Transform } from "../../util/Transform";
import { CollectionViewType } from '../collections/CollectionView';
@@ -171,7 +171,7 @@ export class PresElementBox extends DocComponent<FieldViewProps, PresDocument>(P
}}>
<ContentFittingDocumentView
Document={this.targetDoc}
- LibraryPath={[]}
+ LibraryPath={emptyPath}
fitToBox={StrCast(this.targetDoc.type).indexOf(DocumentType.COL) !== -1}
addDocument={returnFalse}
removeDocument={returnFalse}
diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx
index 0be583358..1007102f6 100644
--- a/src/client/views/search/SearchItem.tsx
+++ b/src/client/views/search/SearchItem.tsx
@@ -7,7 +7,7 @@ import { observer } from "mobx-react";
import { Doc } from "../../../new_fields/Doc";
import { Id } from "../../../new_fields/FieldSymbols";
import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
-import { emptyFunction, returnEmptyString, returnFalse, returnOne, Utils } from "../../../Utils";
+import { emptyFunction, returnEmptyString, returnFalse, returnOne, Utils, emptyPath } from "../../../Utils";
import { DocumentType } from "../../documents/DocumentTypes";
import { DocumentManager } from "../../util/DocumentManager";
import { DragManager, SetupDrag } from "../../util/DragManager";
@@ -160,7 +160,7 @@ export class SearchItem extends React.Component<SearchItemProps> {
onPointerLeave={action(() => this._displayDim = 50)} >
<DocumentView
Document={this.props.doc}
- LibraryPath={[]}
+ LibraryPath={emptyPath}
fitToBox={StrCast(this.props.doc.type).indexOf(DocumentType.COL) !== -1}
addDocument={returnFalse}
removeDocument={returnFalse}
diff --git a/src/server/authentication/models/user_model.ts b/src/server/authentication/models/user_model.ts
index 0bb89772a..78e39dbc1 100644
--- a/src/server/authentication/models/user_model.ts
+++ b/src/server/authentication/models/user_model.ts
@@ -73,8 +73,11 @@ userSchema.pre("save", function save(next) {
});
const comparePassword: comparePasswordFunction = function (this: DashUserModel, candidatePassword, cb) {
- return cb(null, true);
- // bcrypt.compare(candidatePassword, this.password, cb);
+ // Choose one of the following bodies for authentication logic.
+ // secure
+ bcrypt.compare(candidatePassword, this.password, cb);
+ // bypass password
+ // cb(undefined, true);
};
userSchema.methods.comparePassword = comparePassword;