diff options
-rw-r--r-- | src/client/util/RichTextRules.ts | 18 | ||||
-rw-r--r-- | src/client/util/RichTextSchema.tsx | 2 | ||||
-rw-r--r-- | src/client/views/EditableView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/OverlayView.tsx | 4 | ||||
-rw-r--r-- | src/client/views/collections/CollectionTreeView.scss | 1 | ||||
-rw-r--r-- | src/client/views/collections/CollectionTreeView.tsx | 10 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 22 | ||||
-rw-r--r-- | src/client/views/nodes/FormattedTextBox.tsx | 21 | ||||
-rw-r--r-- | src/client/views/nodes/FormattedTextBoxComment.tsx | 4 | ||||
-rw-r--r-- | src/client/views/presentationview/PresElementBox.tsx | 4 | ||||
-rw-r--r-- | src/client/views/search/SearchItem.tsx | 4 | ||||
-rw-r--r-- | src/server/authentication/models/user_model.ts | 7 |
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; |