From 2beec2fd2075f210054095dcd028c056dab48e28 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 8 Mar 2021 14:53:44 -0500 Subject: minimal cleanup of formattedtextBox. --- .../views/nodes/formattedText/FormattedTextBox.tsx | 28 ++++++---------------- 1 file changed, 7 insertions(+), 21 deletions(-) (limited to 'src/client/views/nodes/formattedText') diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 0f669a544..e741c3496 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -205,9 +205,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(this.rootDoc, this.getAnchor, targetCreator), e.pageX, e.pageY); }); - const coordsT = this._editorView!.coordsAtPos(this._editorView!.state.selection.to); const coordsB = this._editorView!.coordsAtPos(this._editorView!.state.selection.to); - this.props.isSelected(true) && AnchorMenu.Instance.jumpTo(Math.min(coordsT.left, coordsB.left), Math.max(coordsT.bottom, coordsB.bottom)); + this.props.isSelected(true) && AnchorMenu.Instance.jumpTo(coordsB.left, coordsB.bottom); } dispatchTransaction = (tx: Transaction) => { @@ -407,8 +406,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp // embed document when dragg marked as embed } else if (de.embedKey) { const target = dragData.droppedDocuments[0]; - // const link = DocUtils.MakeLink({ doc: this.dataDoc, ctx: this.props.ContainingCollectionDoc }, { doc: target }, "Embedded Doc:" + target.title); - // if (link) { target._fitToBox = true; const node = schema.nodes.dashDoc.create({ width: target[WidthSym](), height: target[HeightSym](), @@ -418,7 +415,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const view = this._editorView!; view.dispatch(view.state.tr.insert(view.posAtCoords({ left: de.x, top: de.y })!.pos, node)); e.stopPropagation(); - // } } // otherwise, fall through to outer collection to handle drop } } @@ -551,7 +547,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp }, icon: "expand-arrows-alt" })); - const uicontrols: ContextMenuProps[] = []; uicontrols.push({ description: `${FormattedTextBox.CanAnnotate ? "Hide" : "Show"} Annotation Bar`, event: () => FormattedTextBox.CanAnnotate = !FormattedTextBox.CanAnnotate, icon: "expand-arrows-alt" }); uicontrols.push({ description: !this.Document._noSidebar ? "Hide Sidebar Handle" : "Show Sidebar Handle", event: () => this.layoutDoc._noSidebar = !this.layoutDoc._noSidebar, icon: "expand-arrows-alt" }); @@ -612,10 +607,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp if (results && [DictationManager.Controls.Infringed].includes(results)) { DictationManager.Controls.stop(); } - //this._editorView!.focus(); }); } - stopDictation = (abort: boolean) => { DictationManager.Controls.stop(!abort); }; + stopDictation = (abort: boolean) => DictationManager.Controls.stop(!abort); setDictationContent = (value: string) => { if (this._editorView) { @@ -692,10 +686,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp return anchorDoc ?? this.rootDoc; } - IsActive = () => { - return this.active();//this.props.isSelected() || this._isChildActive || this.props.renderDepth === 0; - } - scrollFocus = (doc: Doc, smooth: boolean) => { const anchorId = doc[Id]; const findAnchorFrag = (frag: Fragment, editor: EditorView) => { @@ -753,7 +743,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp componentDidMount() { this.props.setContentView?.(this); // this tells the DocumentView that this AudioBox is the "content" of the document. this allows the DocumentView to indirectly call getAnchor() on the AudioBox when making a link. - this.props.contentsActive?.(this.IsActive); + this.props.contentsActive?.(this.active); this._cachedLinks = DocListCast(this.Document.links); this._disposers.autoHeight = reaction(() => ({ scrollHeight: this.scrollHeight, autoHeight: this.autoHeight, width: NumCast(this.layoutDoc._width) }), ({ width, autoHeight, scrollHeight }) => width && autoHeight && this.resetNativeHeight(scrollHeight) @@ -801,8 +791,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp () => { if (!DocumentButtonBar.hasPulledHack) { DocumentButtonBar.hasPulledHack = true; - const unchanged = this.dataDoc.unchanged; - this.pullFromGoogleDoc(unchanged ? this.checkState : this.updateState); + this.pullFromGoogleDoc(this.dataDoc.unchanged ? this.checkState : this.updateState); } } ); @@ -1094,7 +1083,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp selectAll(this._editorView!.state, this._editorView?.dispatch); this.startUndoTypingBatch(); } - } selectOnLoad && this._editorView!.focus(); // add user mark for any first character that was typed since the user mark that gets set in KeyPress won't have been called yet. @@ -1189,7 +1177,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp FormattedTextBoxComment.textBox = this; if (e.button === 0 && this.props.isSelected(true) && !e.altKey && !e.ctrlKey && !e.metaKey) { if (e.clientX < this.ProseRef!.getBoundingClientRect().right) { // stop propagation if not in sidebar - e.stopPropagation(); // if the text box is selected, then it consumes all down events + e.stopPropagation(); // if the text box is selected, then it consumes all click events } } if (e.button === 2 || (e.button === 0 && e.ctrlKey)) { @@ -1230,7 +1218,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } } 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 + // if a text note is selected and scrollable, stop event to prevent, say, outer collection from zooming. if ((this.props.rootSelected(true) || this.props.isSelected(true)) || e.currentTarget.scrollHeight > e.currentTarget.clientHeight) { e.stopPropagation(); } @@ -1414,7 +1402,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp this._ignoreScroll = false; } } - tryUpdateScrollHeight() { const proseHeight = this.ProseRef?.scrollHeight || 0; const scrollHeight = this.ProseRef && Math.min(NumCast(this.layoutDoc.docMaxAutoHeight, proseHeight), proseHeight); @@ -1425,7 +1412,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } else setTimeout(setScrollHeight, 10); // if we have a template that hasn't been resolved yet, we can't set the height or we'd be setting it on the unresolved template. So set a timeout and hope its arrived... } } - fitToBox = () => this.props.Document._fitToBox; sidebarContentScaling = () => (this.props.scaling?.() || 1) * NumCast(this.layoutDoc._viewScale, 1); sidebarAddDocument = (doc: Doc | Doc[]) => this.addDocument(doc, this.SidebarKey); @@ -1489,7 +1475,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const scale = this.props.hideOnLeave ? 1 : (this.props.scaling?.() || 1) * NumCast(this.layoutDoc._viewScale, 1); const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : ""; const interactive = (Doc.GetSelectedTool() === InkTool.None || SnappingManager.GetIsDragging()) && (this.layoutDoc.z || this.props.layerProvider?.(this.layoutDoc) !== false); - if (!selected && FormattedTextBoxComment.textBox === this) setTimeout(() => FormattedTextBoxComment.Hide()); + if (!selected && FormattedTextBoxComment.textBox === this) setTimeout(FormattedTextBoxComment.Hide); const minimal = this.props.ignoreAutoHeight; const margins = NumCast(this.layoutDoc._yMargin, this.props.yMargin || 0); const selPad = Math.min(margins, 10); -- cgit v1.2.3-70-g09d2 From 8fcb1a23224762233ebf3e519b13bc72cdfdf3c5 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 9 Mar 2021 09:49:03 -0500 Subject: got rid of DocHolderBox. changed dontRegisterChildViews to childDontRegisterViews for consistency. --- src/client/documents/Documents.ts | 11 +- src/client/util/CurrentUserUtils.ts | 12 +- .../views/collections/CollectionStackingView.tsx | 2 +- .../views/collections/CollectionTreeView.tsx | 2 +- src/client/views/collections/TreeView.tsx | 2 +- .../collections/collectionFreeForm/MarqueeView.tsx | 8 +- src/client/views/nodes/DocHolderBox.scss | 15 -- src/client/views/nodes/DocHolderBox.tsx | 212 --------------------- src/client/views/nodes/DocumentContentsView.tsx | 3 +- src/client/views/nodes/DocumentView.tsx | 6 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 5 +- src/fields/documentSchemas.ts | 3 +- 12 files changed, 20 insertions(+), 261 deletions(-) delete mode 100644 src/client/views/nodes/DocHolderBox.scss delete mode 100644 src/client/views/nodes/DocHolderBox.tsx (limited to 'src/client/views/nodes/formattedText') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 0da80d2c4..db7cbef69 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -35,7 +35,6 @@ import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveIn import { AudioBox } from "../views/nodes/AudioBox"; import { ColorBox } from "../views/nodes/ColorBox"; import { ComparisonBox } from "../views/nodes/ComparisonBox"; -import { DocHolderBox } from "../views/nodes/DocHolderBox"; import { DocFocusOptions } from "../views/nodes/DocumentView"; import { FilterBox } from "../views/nodes/FilterBox"; import { FontIconBox } from "../views/nodes/FontIconBox"; @@ -169,6 +168,7 @@ export class DocumentOptions { childLimitHeight?: number; // whether to limit the height of colleciton children. 0 - means height can be no bigger than width childLayoutTemplate?: Doc; // template for collection to use to render its children (see PresBox or Buxton layout in tree view) childLayoutString?: string; // template string for collection to use to render its children + childDontRegisterViews?: boolean; hideLinkButton?: boolean; // whether the blue link counter button should be hidden hideAllLinks?: boolean; // whether all individual blue anchor dots should be hidden isTemplateForField?: string; // the field key for which the containing document is a rendering template @@ -191,7 +191,6 @@ export class DocumentOptions { presProgressivize?: boolean; borderRounding?: string; boxShadow?: string; - dontRegisterChildViews?: boolean; dontRegisterView?: boolean; lookupField?: ScriptField; // script that returns the value of a field. This script is passed the rootDoc, layoutDoc, field, and container of the document. see PresBox. "onDoubleClick-rawScript"?: string; // onDoubleClick script in raw text form @@ -334,10 +333,6 @@ export namespace Docs { layout: { view: KeyValueBox, dataField: defaultDataKey }, options: { _height: 150 } }], - [DocumentType.DOCHOLDER, { - layout: { view: DocHolderBox, dataField: defaultDataKey }, - options: { _height: 250 } - }], [DocumentType.VID, { layout: { view: VideoBox, dataField: defaultDataKey }, options: { _currentTimecode: 0 }, @@ -768,7 +763,7 @@ export namespace Docs { export function LinkDocument(source: { doc: Doc, ctx?: Doc }, target: { doc: Doc, ctx?: Doc }, options: DocumentOptions = {}, id?: string) { const doc = InstanceFromProto(Prototypes.get(DocumentType.LINK), undefined, { - dontRegisterChildViews: true, + childDontRegisterViews: true, isLinkButton: true, treeViewHideTitle: true, backgroundColor: "lightblue", // lightblue is default color for linking dot and link documents text comment area treeViewExpandedView: "fields", removeDropProperties: new List(["_layerTags", "isLinkButton"]), ...options }, id); @@ -876,7 +871,7 @@ export namespace Docs { } export function TreeDocument(documents: Array, options: DocumentOptions, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", _fitWidth: true, dontRegisterChildViews: true, ...options, _viewType: CollectionViewType.Tree }, id); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", _fitWidth: true, childDontRegisterViews: true, ...options, _viewType: CollectionViewType.Tree }, id); } export function StackingDocument(documents: Array, options: DocumentOptions, id?: string, protoId?: string) { diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index ccdfeed5f..7d533bc63 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -747,7 +747,7 @@ export class CurrentUserUtils { title: "My Dashboards", _height: 400, treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias", treeViewTruncateTitleWidth: 150, treeViewPreventOpen: false, ignoreClick: true, - _lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true + _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true })); const newDashboard = ScriptField.MakeScript(`createNewDashboard(Doc.UserDoc())`); (doc.myDashboards as any as Doc).contextMenuScripts = new List([newDashboard!]); @@ -763,7 +763,7 @@ export class CurrentUserUtils { title: "My Presentations", _height: 100, treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias", treeViewTruncateTitleWidth: 150, treeViewPreventOpen: false, ignoreClick: true, - _lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true + _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true })); const newPresentations = ScriptField.MakeScript(`createNewPresentation()`); (doc.myPresentations as any as Doc).contextMenuScripts = new List([newPresentations!]); @@ -783,7 +783,7 @@ export class CurrentUserUtils { treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias", treeViewTruncateTitleWidth: 150, treeViewPreventOpen: false, ignoreClick: true, isFolder: true, treeViewType: "fileSystem", - _lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "proto", system: true + _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "proto", system: true })); } return doc.myFilesystem as any as Doc; @@ -796,7 +796,7 @@ export class CurrentUserUtils { title: "Recently Closed", treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias", treeViewTruncateTitleWidth: 150, treeViewPreventOpen: false, ignoreClick: true, - _lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true + _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true })); const clearAll = ScriptField.MakeScript(`getProto(self).data = new List([])`); (doc.myRecentlyClosedDocs as any as Doc).contextMenuScripts = new List([clearAll!]); @@ -811,7 +811,7 @@ export class CurrentUserUtils { title: "FilterDoc", treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "none", treeViewTruncateTitleWidth: 150, treeViewPreventOpen: false, ignoreClick: true, - _lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true + _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true })); } const clearAll = ScriptField.MakeScript(`getProto(self).data = new List([]); scriptContext._docFilters = scriptContext._docRangeFilters = undefined;`, { scriptContext: Doc.name }); @@ -827,7 +827,7 @@ export class CurrentUserUtils { doc.myUserDoc = new PrefetchProxy(Docs.Create.TreeDocument([doc], { treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, title: "My UserDoc", treeViewTruncateTitleWidth: 150, treeViewPreventOpen: false, ignoreClick: true, - _lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true + _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true })) as any as Doc; } } diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 95a95b10d..5bb3c0403 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -224,7 +224,7 @@ export class CollectionStackingView extends CollectionSubView this.props.treeViewHideHeaderFields || BoolCast(this.doc.treeViewHideHeaderFields), BoolCast(this.doc.treeViewPreventOpen), [], this.props.onCheckedClick, - this.onChildClick, this.props.treeViewSkipFields, true, this.whenActiveChanged, this.props.dontRegisterView || Cast(this.props.Document.dontRegisterChildViews, "boolean", null), this); + this.onChildClick, this.props.treeViewSkipFields, true, this.whenActiveChanged, this.props.dontRegisterView || Cast(this.props.Document.childDontRegisterViews, "boolean", null), this); } @computed get titleBar() { const hideTitle = this.props.treeViewHideTitle || this.doc.treeViewHideTitle; diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 106129127..7674b1451 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -608,7 +608,7 @@ export class TreeView extends React.Component { whenActiveChanged={this.props.whenActiveChanged} bringToFront={emptyFunction} cantBrush={this.props.treeView.props.cantBrush} - dontRegisterView={BoolCast(this.props.treeView.props.Document.dontRegisterChildViews)} + dontRegisterView={BoolCast(this.props.treeView.props.Document.childDontRegisterViews)} docFilters={returnEmptyFilter} docRangeFilters={returnEmptyFilter} searchFilterDocs={returnEmptyDoclist} diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 2a30e5fd0..e625b5b4b 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -323,11 +323,9 @@ export class MarqueeView extends React.Component; -const DocHolderBoxDocument = makeInterface(documentSchema, collectionSchema); - -@observer -export class DocHolderBox extends ViewBoxAnnotatableComponent(DocHolderBoxDocument) { - public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DocHolderBox, fieldKey); } - _prevSelectionDisposer: IReactionDisposer | undefined; - _dropDisposer?: DragManager.DragDropDisposer; - _selections: Doc[] = []; - _contRef = React.createRef(); - _curSelection = -1; - componentDidMount() { - this._prevSelectionDisposer = reaction(() => this.dataDoc[this.fieldKey], (data) => { - if (data instanceof Doc && !this.isSelectionLocked()) { - this._selections.indexOf(data) !== -1 && this._selections.splice(this._selections.indexOf(data), 1); - this._selections.push(data); - this._curSelection = this._selections.length - 1; - } - }); - } - componentWillUnmount() { - this._prevSelectionDisposer?.(); - } - specificContextMenu = (e: React.MouseEvent): void => { - const funcs: ContextMenuProps[] = []; - funcs.push({ description: (this.isSelectionLocked() ? "Show" : "Lock") + " Selection", event: () => this.toggleLockSelection, icon: "expand-arrows-alt" }); - funcs.push({ description: (this.layoutDoc.excludeCollections ? "Include" : "Exclude") + " Collections", event: () => this.layoutDoc.excludeCollections = !this.layoutDoc.excludeCollections, icon: "expand-arrows-alt" }); - funcs.push({ description: `${this.layoutDoc.forceActive ? "Select" : "Force"} Contents Active`, event: () => this.layoutDoc.forceActive = !this.layoutDoc.forceActive, icon: "project-diagram" }); - funcs.push({ description: `Show ${this.layoutDoc.childLayoutTemplateName !== "keyValue" ? "key values" : "contents"}`, event: () => this.layoutDoc.childLayoutString = this.layoutDoc.childLayoutString ? undefined : "", icon: "project-diagram" }); - - ContextMenu.Instance.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" }); - } - lockSelection = () => { - this.dataDoc[this.fieldKey] = this.dataDoc[this.fieldKey]; - } - showSelection = () => { - this.dataDoc[this.fieldKey] = ComputedField.MakeFunction(`selectedDocs(self,this.excludeCollections,[_last_])?.[0]`); - } - isSelectionLocked = () => { - const kvpstring = Field.toKeyValueString(this.dataDoc, this.fieldKey); - return !kvpstring || kvpstring.includes("DOC"); - } - toggleLockSelection = () => { - !this.isSelectionLocked() ? this.lockSelection() : this.showSelection(); - return true; - } - prevSelection = () => { - this.lockSelection(); - if (this._curSelection > 0) { - this.dataDoc[this.fieldKey] = this._selections[--this._curSelection]; - return true; - } - } - nextSelection = () => { - if (this._curSelection < this._selections.length - 1 && this._selections.length) { - this.dataDoc[this.fieldKey] = this._selections[++this._curSelection]; - return true; - } - } - onPointerDown = (e: React.PointerEvent) => { - if (this.active() && e.button === 0 && !e.ctrlKey) { - e.stopPropagation(); - } - } - onLockClick = (e: React.MouseEvent) => { - this.toggleLockSelection(); - (e.nativeEvent as any).formattedHandled = true; - e.stopPropagation(); - } - get xPad() { return NumCast(this.rootDoc._xPadding); } - get yPad() { return NumCast(this.rootDoc._yPadding); } - onClick = (e: React.MouseEvent) => { - let hitWidget: boolean | undefined = false; - if (this._contRef.current!.getBoundingClientRect().top + this.yPad > e.clientY) hitWidget = (() => { this.props.select(false); return true; })(); - else if (this._contRef.current!.getBoundingClientRect().bottom - this.yPad < e.clientY) hitWidget = (() => { this.props.select(false); return true; })(); - else { - if (this._contRef.current!.getBoundingClientRect().left + this.xPad > e.clientX) hitWidget = this.prevSelection(); - if (this._contRef.current!.getBoundingClientRect().right - this.xPad < e.clientX) hitWidget = this.nextSelection(); - } - if (hitWidget) { - (e.nativeEvent as any).formattedHandled = true; - e.stopPropagation(); - } - } - pwidth = () => this.props.PanelWidth() - 2 * this.xPad; - pheight = () => this.props.PanelHeight() - 2 * this.yPad; - getTransform = () => this.props.ScreenToLocalTransform().translate(-this.xPad, -this.yPad); - isActive = (outsideReaction: boolean) => this.active(outsideReaction) || this.props.renderDepth <= 1; - layoutTemplateDoc = () => Cast(this.layoutDoc.childLayoutTemplate, Doc, null); - get renderContents() { - const containedDoc = Cast(this.dataDoc[this.fieldKey], Doc, null); - const layoutTemplate = StrCast(this.layoutDoc.childLayoutString); - const contents = !(containedDoc instanceof Doc) || - Cast(containedDoc[Doc.LayoutFieldKey(containedDoc)], listSpec(Doc), null)?.includes(this.rootDoc) - ? (null) : this.layoutDoc.childLayoutString || this.layoutTemplateDoc() ? - : - ; - return contents; - } - render() { - const containedDoc = Cast(this.dataDoc[this.fieldKey], Doc, null); - TraceMobx(); - return !containedDoc ? (null) :
- {this.renderContents} -
- -
-
; - } - - @undoBatch - @action - drop = (e: Event, de: DragManager.DropEvent) => { - const docDragData = de.complete.docDragData; - if (docDragData?.draggedDocuments[0].type === DocumentType.FONTICON) { - const doc = Cast(docDragData.draggedDocuments[0].dragFactory, Doc, null); - this.layoutDoc.childLayoutTemplate = doc; - } - } - protected createDropTarget = (ele: HTMLDivElement) => { - this._dropDisposer?.(); - ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this), this.rootDoc)); - } - -} diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 32542d056..2f7923574 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -16,7 +16,6 @@ import { FunctionPlotBox } from "./FunctionPlotBox"; import { SliderBox } from "./SliderBox"; import { LinkBox } from "./LinkBox"; import { ScriptingBox } from "./ScriptingBox"; -import { DocHolderBox } from "./DocHolderBox"; import { DocumentViewProps } from "./DocumentView"; import "./DocumentView.scss"; import { FontIconBox } from "./FontIconBox"; @@ -225,7 +224,7 @@ export class DocumentContentsView extends React.Component) => { - if ((e as any).formattedHandled) { e.stopPropagation; return; } if (e.cancelBubble && this.active) { this.removeMoveListeners(); } @@ -473,7 +472,7 @@ export class DocumentViewInternal extends DocComponent 0)) { // onDragStart implies a button doc that we don't want to select when clicking. RootDocument & isTemplaetForField implies we're clicking on part of a template instance and we want to select the whole template, not the part @@ -515,13 +514,10 @@ export class DocumentViewInternal extends DocComponent { - if ((e as any).formattedHandled) { e.stopPropagation(); return; } if ((InteractionUtils.IsType(e, InteractionUtils.PENTYPE) || Doc.GetSelectedTool() === InkTool.Highlighter || Doc.GetSelectedTool() === InkTool.Pen)) return; if (e.cancelBubble && this.active) { document.removeEventListener("pointermove", this.onPointerMove); // stop listening to pointerMove if something else has stopPropagated it (e.g., the MarqueeView) diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index e741c3496..f32af53d3 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1290,8 +1290,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp if (selectOrderedList || (!collapse && listNode.attrs.visibility)) { this._editorView.dispatch(this._editorView.state.tr.setSelection(new NodeSelection(selectOrderedList ? $olistPos! : listPos!))); } else if (!listNode.attrs.visibility || downNode === listNode) { - this._editorView.dispatch(this._editorView.state.tr.setNodeMarkup(clickPos.pos, listNode.type, { ...listNode.attrs, visibility: !listNode.attrs.visibility })); - this._editorView.dispatch(this._editorView.state.tr.setSelection(TextSelection.create(this._editorView.state.doc, clickPos.pos))); + const tr = this._editorView.state.tr.setNodeMarkup(clickPos.pos, listNode.type, { ...listNode.attrs, visibility: !listNode.attrs.visibility }); + this._editorView.dispatch(tr.setSelection(TextSelection.create(tr.doc, clickPos.pos))); } } addStyleSheetRule(FormattedTextBox._bulletStyleSheet, olistNode.attrs.mapStyle + olistNode.attrs.bulletStyle + ":hover:before", { background: "lightgray" }); @@ -1309,7 +1309,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp view.root.removeEventListener("mouseup", originalUpHandler); view.mouseDown.up = (e: MouseEvent) => { !(e as any).formattedHandled && originalUpHandler(e); - // e.stopPropagation(); (e as any).formattedHandled = true; }; view.root.addEventListener("mouseup", view.mouseDown.up); diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts index 4d8b6b55c..0bf942474 100644 --- a/src/fields/documentSchemas.ts +++ b/src/fields/documentSchemas.ts @@ -109,11 +109,10 @@ export const documentSchema = createSchema({ export const collectionSchema = createSchema({ - childLayoutTemplateName: "string", // the name of a template to use to override the layoutKey when rendering a document -- ONLY used in DocHolderBox childLayoutTemplate: Doc, // layout template to use to render children of a collecion childLayoutString: "string", //layout string to use to render children of a collection childClickedOpenTemplateView: Doc, // layout template to apply to a child when its clicked on in a collection and opened (requires onChildClick or other script to read this value and apply template) - dontRegisterChildViews: "boolean", // whether views made of this document are registered so that they can be found when drawing links + childDontRegisterViews: "boolean", // whether views made of this document are registered so that they can be found when drawing links onChildClick: ScriptField, // script to run for each child when its clicked onChildDoubleClick: ScriptField, // script to run for each child when its clicked onCheckedClick: ScriptField, // script to run when a checkbox is clicked next to a child in a tree view -- cgit v1.2.3-70-g09d2 From 72f9988e5750f38d725aa0dd78e9af39a8794808 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 9 Mar 2021 10:50:15 -0500 Subject: fixed following portal link to reset camera position. prevent warning errors in loading screen. hide textsidebar until text is selected. fixed link titles to handle case when link anchor is the link document and not infinitely recurse. --- deploy/index.html | 29 +++++++--------------- src/client/documents/Documents.ts | 11 ++++++-- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 2 +- 4 files changed, 20 insertions(+), 24 deletions(-) (limited to 'src/client/views/nodes/formattedText') diff --git a/deploy/index.html b/deploy/index.html index f2eb5e2aa..dda0c6457 100644 --- a/deploy/index.html +++ b/deploy/index.html @@ -125,26 +125,15 @@ let load = getCookie("loadtime"); document.startLoad = Date.now(); console.log("Last Load = " + load); - setTimeout(() => { - document.getElementById("dash-progress").style.width = "10%" - document.getElementById("dash-loader-text").innerHTML = "Loading Dash..." - }, load / 10); - setTimeout(() => { - document.getElementById("dash-progress").style.width = "33%" - document.getElementById("dash-loader-text").innerHTML = "Preparing dashboards..." - }, load / 3); - setTimeout(() => { - document.getElementById("dash-progress").style.width = "50%" - document.getElementById("dash-loader-text").innerHTML = "Initializing scripts..." - }, load / 2); - setTimeout(() => { - document.getElementById("dash-progress").style.width = "75%" - document.getElementById("dash-loader-text").innerHTML = "Fetching documents..." - }, load / 4 * 3); - setTimeout(() => { - document.getElementById("dash-progress").style.width = "100%" - document.getElementById("dash-loader-text").innerHTML = "Finalising setup..." - }, load); + let dashmesg = (width, msg) => { + if (document.getElementById("dash-progress")) document.getElementById("dash-progress").style.width = width + if (document.getElementById("dash-progress")) document.getElementById("dash-progress").innerHTML = msg + } + setTimeout(() => dashmesg("10%", "Loading Dash..."), load / 10); + setTimeout(() => dashmesg("33%", "Preparing dashboards..."), load / 3); + setTimeout(() => dashmesg("50%", "Initializing scripts..."), load / 2); + setTimeout(() => dashmesg("75%", "Fetching documents..."), load / 4 * 3); + setTimeout(() => dashmesg("100%", "Finalising setup..."), load);
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 0da80d2c4..754a0d0f8 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -59,6 +59,7 @@ import { DashWebRTCVideo } from "../views/webcam/DashWebRTCVideo"; import { DocumentType } from "./DocumentTypes"; import { EquationBox } from "../views/nodes/EquationBox"; import { FunctionPlotBox } from "../views/nodes/FunctionPlotBox"; +import { script } from "googleapis/build/src/apis/script"; const path = require('path'); const defaultNativeImageDim = Number(DFLT_IMAGE_NATIVE_DIM.replace("px", "")); @@ -1135,7 +1136,7 @@ export namespace DocUtils { linkDoc.hidden = true; Doc.GetProto(linkDoc)["acl-Public"] = linkDoc["acl-Public"] = SharingPermissions.Add; linkDoc.layout_linkView = Cast(Cast(Doc.UserDoc()["template-button-link"], Doc, null).dragFactory, Doc, null); - Doc.GetProto(linkDoc).title = ComputedField.MakeFunction('self.anchor1?.title +" (" + (self.linkRelationship||"to") +") " + self.anchor2?.title'); + Doc.GetProto(linkDoc).title = ComputedField.MakeFunction("generateLinkTitle(self)"); showPopup && makeLink(linkDoc, showPopup); return linkDoc; } @@ -1416,4 +1417,10 @@ export namespace DocUtils { } Scripting.addGlobal("Docs", Docs); -Scripting.addGlobal(function makeDelegate(proto: any) { const d = Docs.Create.DelegateDocument(proto, { title: "child of " + proto.title }); return d; }); \ No newline at end of file +Scripting.addGlobal(function makeDelegate(proto: any) { const d = Docs.Create.DelegateDocument(proto, { title: "child of " + proto.title }); return d; }); +Scripting.addGlobal(function generateLinkTitle(self: Doc) { + const anchor1title = self.anchor1 && self.anchor1 !== self ? Cast(self.anchor1, Doc, null).title : ""; + const anchor2title = self.anchor2 && self.anchor2 !== self ? Cast(self.anchor2, Doc, null).title : ""; + const relation = self.linkRelationship || "to"; + return `${anchor1title} (${relation}) ${anchor2title}`; +}) \ No newline at end of file diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 660790b11..ec5cb8a61 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -950,7 +950,7 @@ export class CollectionFreeFormView extends CollectionSubView d?.author).length; - return
Date: Tue, 9 Mar 2021 20:56:29 -0500 Subject: changed field unchanged -> googleDocUnchanged. cleaned up some other code. --- src/client/views/DocumentButtonBar.tsx | 6 +- src/client/views/PropertiesButtons.tsx | 6 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 138 +++++++++------------ src/client/views/pdf/Annotation.tsx | 17 +-- src/client/views/pdf/PDFViewer.tsx | 109 +++++++--------- 5 files changed, 117 insertions(+), 159 deletions(-) (limited to 'src/client/views/nodes/formattedText') diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index a9cd7b4a9..5ebf29603 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -131,7 +131,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV const title = (() => { switch (this.openHover) { default: - case UtilityButtonState.Default: return `${!dataDoc?.unchanged ? "Pull from" : "Fetch"} Google Docs`; + case UtilityButtonState.Default: return `${!dataDoc?.googleDocUnchanged ? "Pull from" : "Fetch"} Google Docs`; case UtilityButtonState.OpenRight: return "Open in Right Split"; case UtilityButtonState.OpenExternally: return "Open in new Browser Tab"; } @@ -167,7 +167,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV this.clearPullColor(); DocumentButtonBar.hasPulledHack = false; targetDoc[Pulls] = NumCast(targetDoc[Pulls]) + 1; - dataDoc.unchanged && runInAction(() => this.isAnimatingFetch = true); + dataDoc.googleDocUnchanged && runInAction(() => this.isAnimatingFetch = true); } }}> (DocumentV icon={(() => { switch (this.openHover) { default: - case UtilityButtonState.Default: return dataDoc.unchanged === false ? (this.pullIcon as any) : fetch; + case UtilityButtonState.Default: return dataDoc.googleDocUnchanged === false ? (this.pullIcon as any) : fetch; case UtilityButtonState.OpenRight: return "arrow-alt-circle-right"; case UtilityButtonState.OpenExternally: return "share"; } diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index e418a6f3c..bf72dbdba 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -131,7 +131,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { const title = (() => { switch (this.openHover) { default: - case UtilityButtonState.Default: return `${!dataDoc?.unchanged ? "Pull from" : "Fetch"} Google Docs`; + case UtilityButtonState.Default: return `${!dataDoc?.googleDocUnchanged ? "Pull from" : "Fetch"} Google Docs`; case UtilityButtonState.OpenRight: return "Open in Right Split"; case UtilityButtonState.OpenExternally: return "Open in new Browser Tab"; } @@ -165,7 +165,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { this.clearPullColor(); PropertiesButtons.hasPulledHack = false; targetDoc[Pulls] = NumCast(targetDoc[Pulls]) + 1; - dataDoc.unchanged && runInAction(() => this.isAnimatingFetch = true); + dataDoc.googleDocUnchanged && runInAction(() => this.isAnimatingFetch = true); } }}> { icon={(() => { switch (this.openHover) { default: - case UtilityButtonState.Default: return dataDoc.unchanged === false ? (this.pullIcon as any) : fetch; + case UtilityButtonState.Default: return dataDoc.googleDocUnchanged === false ? (this.pullIcon as any) : fetch; case UtilityButtonState.OpenRight: return "arrow-alt-circle-right"; case UtilityButtonState.OpenExternally: return "share"; } diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 29f6e2bd8..89df7a98a 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -15,7 +15,7 @@ import { DataSym, Doc, DocListCast, DocListCastAsync, Field, HeightSym, Opt, Wid import { documentSchema } from '../../../../fields/documentSchemas'; import applyDevTools = require("prosemirror-dev-tools"); import { removeMarkWithAttrs } from "./prosemirrorPatches"; -import { Id, Copy } from '../../../../fields/FieldSymbols'; +import { Id } from '../../../../fields/FieldSymbols'; import { InkTool } from '../../../../fields/InkField'; import { PrefetchProxy } from '../../../../fields/Proxy'; import { RichTextField } from "../../../../fields/RichTextField"; @@ -90,8 +90,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp public static get DefaultLayout() { return Cast(Doc.UserDoc().defaultTextLayout, Doc, null) || StrCast(Doc.UserDoc().defaultTextLayout, null); } - public static CanAnnotate = true; public static Instance: FormattedTextBox; + static _highlights: string[] = ["Audio Tags", "Text from Others", "Todo Items", "Important Items", "Disagree Items", "Ignore Items"]; + static _highlightStyleSheet: any = addStyleSheet(); + static _bulletStyleSheet: any = addStyleSheet(); + static _userStyleSheet: any = addStyleSheet(); + static _canAnnotate = true; + static _hadSelection: boolean = false; + public static LiveTextUndo: UndoManager.Batch | undefined; public ProseRef?: HTMLDivElement; public get EditorView() { return this._editorView; } public get SidebarKey() { return this.fieldKey + "-sidebar"; } @@ -111,6 +117,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp private _focusSpeed: Opt; private _keymap: any = undefined; private _rules: RichTextRules | undefined; + private _forceUncollapse = true; // if the cursor doesn't move between clicks, then the selection will disappear for some reason. This flags the 2nd click as happening on a selection which allows bullet points to toggle + private _forceDownNode: Node | undefined; + private _downEvent: any; + private _downX = 0; + private _downY = 0; + private _break = false; @computed get sidebarWidthPercent() { return StrCast(this.layoutDoc._sidebarWidthPercent, "0%"); } @computed get sidebarColor() { return StrCast(this.layoutDoc.sidebarColor, StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "#e4e4e4")); } @@ -121,10 +133,26 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp @computed get titleHeight() { return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HeaderMargin) || 0; } @computed get _recording() { return this.dataDoc?.audioState === "recording"; } set _recording(value) { this.dataDoc.audioState = value ? "recording" : undefined; } + @computed get config() { + this._keymap = buildKeymap(schema, this.props); + this._rules = new RichTextRules(this.props.Document, this); + return { + schema, + plugins: [ + inputRules(this._rules.inpRules), + this.richTextMenuPlugin(), + history(), + keymap(this._keymap), + keymap(baseKeymap), + new Plugin({ props: { attributes: { class: "ProseMirror-example-setup-style" } } }), + new Plugin({ view(editorView) { return new FormattedTextBoxComment(editorView); } }) + ] + }; + } public static FocusedBox: FormattedTextBox | undefined; - public static SelectOnLoad = ""; public static PasteOnLoad: ClipboardEvent | undefined; + public static SelectOnLoad = ""; public static SelectOnLoadChar = ""; public static IsFragment(html: string) { return html.indexOf("data-pm-slice") !== -1; } public static GetHref(html: string): string { @@ -314,7 +342,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } // needs a better API for taking in a set of words with target documents instead of just one target - public hyperlinkTerms = (terms: string[], target: Doc) => { + hyperlinkTerms = (terms: string[], target: Doc) => { if (this._editorView && (this._editorView as any).docView && terms.some(t => t)) { const res1 = terms.filter(t => t).map(term => this.findInNode(this._editorView!, this._editorView!.state.doc, term)); let tr = this._editorView.state.tr; @@ -334,7 +362,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp this._editorView.dispatch(tr); } } - public highlightSearchTerms = (terms: string[], backward: boolean) => { + highlightSearchTerms = (terms: string[], backward: boolean) => { if (this._editorView && (this._editorView as any).docView && terms.some(t => t)) { const mark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight); const activeMark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight, { selected: true }); @@ -363,7 +391,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } } - public unhighlightSearchTerms = () => { + unhighlightSearchTerms = () => { if (window.screen.width < 600) null; else if (this._editorView && (this._editorView as any).docView) { const mark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight); @@ -409,7 +437,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp target._fitToBox = true; const node = schema.nodes.dashDoc.create({ width: target[WidthSym](), height: target[HeightSym](), - title: "dashDoc", docid: target[Id], + title: "dashDoc", + docid: target[Id], float: "right" }); const view = this._editorView!; @@ -463,7 +492,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp return ret; } - static _highlights: string[] = ["Audio Tags", "Text from Others", "Todo Items", "Important Items", "Disagree Items", "Ignore Items"]; updateHighlights = () => { clearStyleSheetRules(FormattedTextBox._userStyleSheet); if (FormattedTextBox._highlights.indexOf("Audio Tags") === -1) { @@ -548,7 +576,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp })); const uicontrols: ContextMenuProps[] = []; - uicontrols.push({ description: `${FormattedTextBox.CanAnnotate ? "Hide" : "Show"} Annotation Bar`, event: () => FormattedTextBox.CanAnnotate = !FormattedTextBox.CanAnnotate, icon: "expand-arrows-alt" }); + uicontrols.push({ description: `${FormattedTextBox._canAnnotate ? "Hide" : "Show"} Annotation Bar`, event: () => FormattedTextBox._canAnnotate = !FormattedTextBox._canAnnotate, icon: "expand-arrows-alt" }); uicontrols.push({ description: !this.Document._noSidebar ? "Hide Sidebar Handle" : "Show Sidebar Handle", event: () => this.layoutDoc._noSidebar = !this.layoutDoc._noSidebar, icon: "expand-arrows-alt" }); uicontrols.push({ description: `${this.layoutDoc._showAudio ? "Hide" : "Show"} Dictation Icon`, event: () => this.layoutDoc._showAudio = !this.layoutDoc._showAudio, icon: "expand-arrows-alt" }); uicontrols.push({ description: "Show Highlights...", noexpand: true, subitems: highlighting, icon: "hand-point-right" }); @@ -637,26 +665,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } } - @computed get config() { - this._keymap = buildKeymap(schema, this.props); - this._rules = new RichTextRules(this.props.Document, this); - return { - schema, - plugins: [ - inputRules(this._rules.inpRules), - this.richTextMenuPlugin(), - history(), - keymap(this._keymap), - keymap(baseKeymap), - new Plugin({ - props: { - attributes: { class: "ProseMirror-example-setup-style" } - } - }), new Plugin({ view(editorView) { return new FormattedTextBoxComment(editorView); } }) - ] - }; - } - makeLinkAnchor(anchorDoc?: Doc, location?: string, targetHref?: string, title?: string) { const state = this._editorView?.state; if (state) { @@ -761,7 +769,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp instance => { if (instance) { this.pullFromGoogleDoc(this.checkState); - this.dataDoc[GoogleRef] && this.dataDoc.unchanged && runInAction(() => instance.isAnimatingFetch = true); + this.dataDoc[GoogleRef] && this.dataDoc.googleDocUnchanged && runInAction(() => instance.isAnimatingFetch = true); } } ); @@ -791,7 +799,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp () => { if (!DocumentButtonBar.hasPulledHack) { DocumentButtonBar.hasPulledHack = true; - this.pullFromGoogleDoc(this.dataDoc.unchanged ? this.checkState : this.updateState); + this.pullFromGoogleDoc(this.dataDoc.googleDocUnchanged ? this.checkState : this.updateState); } } ); @@ -866,7 +874,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const response = await GoogleApiClientUtils.Docs.write({ reference, content, mode }); response && (this.dataDoc[GoogleRef] = response.documentId); const pushSuccess = response !== undefined && !("errors" in response); - dataDoc.unchanged = pushSuccess; + dataDoc.googleDocUnchanged = pushSuccess; DocumentButtonBar.Instance.startPushOutcome(pushSuccess); } }; @@ -911,7 +919,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp }, 0); dataDoc.title = exportState.title; this.dataDoc["title-custom"] = true; - dataDoc.unchanged = true; + dataDoc.googleDocUnchanged = true; } else { delete dataDoc[GoogleRef]; } @@ -923,7 +931,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const equalContent = isEqual(this._editorView.state.doc, exportState.state.doc); const equalTitles = dataDoc.title === exportState.title; const unchanged = equalContent && equalTitles; - dataDoc.unchanged = unchanged; + dataDoc.googleDocUnchanged = unchanged; DocumentButtonBar.Instance.setPullState(unchanged); } } @@ -1100,11 +1108,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp FormattedTextBoxComment.tooltip && (FormattedTextBoxComment.tooltip.style.display = "none"); } - _downEvent: any; - _downX = 0; - _downY = 0; - _break = false; - _collapsed = false; onPointerDown = (e: React.PointerEvent): void => { if ((e.target as any).tagName === "AUDIOTAG") { e.preventDefault(); @@ -1152,9 +1155,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp document.removeEventListener("pointerup", this.onSelectEnd); document.removeEventListener("pointermove", this.onSelectMove); } - onPointerUp = (e: React.PointerEvent): void => { - if (!this._editorView?.state.selection.empty && FormattedTextBox.CanAnnotate) this.setupAnchorMenu(); + if (!this._editorView?.state.selection.empty && FormattedTextBox._canAnnotate) this.setupAnchorMenu(); if (!this._downEvent) return; this._downEvent = false; if (!(e.nativeEvent as any).formattedHandled && this.active(true)) { @@ -1171,7 +1173,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp e.stopPropagation(); } } - @action onDoubleClick = (e: React.MouseEvent): void => { FormattedTextBoxComment.textBox = this; @@ -1191,7 +1192,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp e.stopPropagation(); } } - @action onFocused = (e: React.FocusEvent): void => { FormattedTextBox.FocusedBox = this; @@ -1223,12 +1223,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp e.stopPropagation(); } } - - static _highlightStyleSheet: any = addStyleSheet(); - static _bulletStyleSheet: any = addStyleSheet(); - static _userStyleSheet: any = addStyleSheet(); - _forceUncollapse = true; // if the cursor doesn't move between clicks, then the selection will disappear for some reason. This flags the 2nd click as happening on a selection which allows bullet points to toggle - _forceDownNode: Node | undefined; onClick = (e: React.MouseEvent): void => { if (Math.abs(e.clientX - this._downX) > 4 || Math.abs(e.clientY - this._downY) > 4) { this._forceDownNode = undefined; @@ -1264,7 +1258,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp this._forceUncollapse = !(this._editorView!.root as any).getSelection().isCollapsed; this._forceDownNode = (this._editorView!.state.selection as NodeSelection)?.node; } - // this hackiness handles clicking on the list item bullets to do expand/collapse. the bullets are ::before pseudo elements so there's no real way to hit test against them. hitBulletTargets(x: number, y: number, collapse: boolean, highlightOnly: boolean, downNode: Node | undefined = undefined, selectOrderedList: boolean = false) { this._forceUncollapse = false; @@ -1314,24 +1307,20 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp view.root.addEventListener("mouseup", view.mouseDown.up); } } - - public startUndoTypingBatch() { + startUndoTypingBatch() { !this._undoTyping && (this._undoTyping = UndoManager.StartBatch("undoTyping")); } - public endUndoTypingBatch() { const wasUndoing = this._undoTyping; this._undoTyping?.end(); this._undoTyping = undefined; return wasUndoing; } - public static LiveTextUndo: UndoManager.Batch | undefined; - public static HadSelection: boolean = false; onBlur = (e: any) => { if (RichTextMenu.Instance?.view === this._editorView && !this.props.isSelected(true)) { RichTextMenu.Instance?.updateMenu(undefined, undefined, undefined); } - FormattedTextBox.HadSelection = window.getSelection()?.toString() !== ""; + FormattedTextBox._hadSelection = window.getSelection()?.toString() !== ""; this.endUndoTypingBatch(); FormattedTextBox.LiveTextUndo?.end(); @@ -1350,7 +1339,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp this._lastText = curText; } } - onKeyDown = (e: React.KeyboardEvent) => { // single line text boxes need to pass through tab/enter/backspace so that their containers can respond (eg, an outline container) if (this.rootDoc._singleLine && ((e.key === "Backspace" && !this.dataDoc[this.fieldKey]?.Text) || ["Tab", "Enter"].includes(e.key))) { @@ -1372,29 +1360,27 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp this._rules!.EnteringStyle = false; } e.stopPropagation(); - if (e.key === "Escape") { - this._editorView!.dispatch(state.tr.setSelection(TextSelection.create(state.doc, state.selection.from, state.selection.from))); - (document.activeElement as any).blur?.(); - SelectionManager.DeselectAll(); - RichTextMenu.Instance.updateMenu(undefined, undefined, undefined); - } else { - if (e.key === "Tab" || e.key === "Enter") { - if (e.key === "Enter") this.insertTime(); - e.preventDefault(); - } - if (e.key === " " || this._lastTimedMark?.attrs.userid !== Doc.CurrentUserEmail) { - const mark = schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) }); - this._editorView!.dispatch(this._editorView!.state.tr.removeStoredMark(schema.marks.user_mark.create({})).addStoredMark(mark)); - } - this.startUndoTypingBatch(); + switch (e.key) { + case "Escape": + this._editorView!.dispatch(state.tr.setSelection(TextSelection.create(state.doc, state.selection.from, state.selection.from))); + (document.activeElement as any).blur?.(); + SelectionManager.DeselectAll(); + RichTextMenu.Instance.updateMenu(undefined, undefined, undefined); + return; + case "Enter": this.insertTime(); + case "Tab": e.preventDefault(); break; + default: if (this._lastTimedMark?.attrs.userid === Doc.CurrentUserEmail) break; + case " ": + this._editorView!.dispatch(this._editorView!.state.tr.removeStoredMark(schema.marks.user_mark.create({})) + .addStoredMark(schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) }))); } + this.startUndoTypingBatch(); } - - ondrop = (eve: React.DragEvent) => { + ondrop = (e: React.DragEvent) => { this._editorView!.dispatch(updateBullets(this._editorView!.state.tr, this._editorView!.state.schema)); - eve.stopPropagation(); // drag n drop of text within text note will generate a new note if not caughst, as will dragging in from outside of Dash. + e.stopPropagation(); // drag n drop of text within text note will generate a new note if not caughst, as will dragging in from outside of Dash. } - onScroll = (ev: React.UIEvent) => { + onScroll = (e: React.UIEvent) => { if (!LinkDocPreview.LinkInfo && this._scrollRef.current) { this._ignoreScroll = true; this.layoutDoc._scrollTop = this._scrollRef.current.scrollTop; diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx index 913cfdcc2..05d81f40f 100644 --- a/src/client/views/pdf/Annotation.tsx +++ b/src/client/views/pdf/Annotation.tsx @@ -1,7 +1,7 @@ import React = require("react"); import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; -import { Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../fields/Doc"; +import { Doc, DocListCast, Opt } from "../../../fields/Doc"; import { Id } from "../../../fields/FieldSymbols"; import { List } from "../../../fields/List"; import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types"; @@ -21,16 +21,11 @@ interface IAnnotationProps extends FieldViewProps { export class Annotation extends React.Component { render() { - return DocListCast(this.props.anno.textInlineAnnotations).map(a => - ); + return DocListCast(this.props.anno.textInlineAnnotations).map(a => ); } } interface IRegionAnnotationProps extends IAnnotationProps { - x: number; - y: number; - width: number; - height: number; document: Doc; } @observer @@ -96,10 +91,10 @@ class RegionAnnotation extends React.Component { render() { return (
this.props.showInfo(this.props.anno)} onPointerLeave={() => this.props.showInfo(undefined)} onPointerDown={this.onPointerDown} ref={this._mainCont} style={{ - top: this.props.y, - left: this.props.x, - width: this.props.width, - height: this.props.height, + left: NumCast(this.props.document.x), + top: NumCast(this.props.document.y), + width: NumCast(this.props.document._width), + height: NumCast(this.props.document._height), opacity: this._brushed ? 0.5 : undefined, backgroundColor: this._brushed ? "orange" : StrCast(this.props.document.backgroundColor), }} > diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 28d7b0954..73aea9737 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -8,8 +8,7 @@ import { documentSchema } from "../../../fields/documentSchemas"; import { Id } from "../../../fields/FieldSymbols"; import { InkTool } from "../../../fields/InkField"; import { createSchema, makeInterface } from "../../../fields/Schema"; -import { ScriptField } from "../../../fields/ScriptField"; -import { Cast, NumCast, StrCast } from "../../../fields/Types"; +import { Cast, NumCast, StrCast, ScriptCast } from "../../../fields/Types"; import { PdfField } from "../../../fields/URLField"; import { TraceMobx } from "../../../fields/util"; import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, OmitKeys, smoothScroll, Utils } from "../../../Utils"; @@ -66,12 +65,12 @@ export class PDFViewer extends ViewBoxAnnotatableComponent = new Dictionary(); @observable private _script: CompiledScript = CompileScript("return true") as CompiledScript; - @observable private Index: number = -1; @observable private _marqueeing: number[] | undefined; @observable private _showWaiting = true; @observable private _showCover = false; @observable private _zoomed = 1; @observable private _overlayAnnoInfo: Opt; + @observable private Index: number = -1; private _pdfViewer: any; private _styleRule: any; // stylesheet rule for making hyperlinks clickable @@ -89,7 +88,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent; - private _smoothScrolling = true; + private _forcedScroll = true; @computed get allAnnotations() { return DocUtils.FilterDocs(DocListCast(this.dataDoc[this.props.fieldKey + "-annotations"]), this.props.docFilters(), this.props.docRangeFilters(), undefined); @@ -158,12 +157,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent { if (this.active() && e.clipboardData) { - //const annoDoc = this.makeAnnotationDocument("rgba(3,144,152,0.3)"); // copied text markup color (blueish) - //if (annoDoc) { e.clipboardData.setData("text/plain", this._selectionText); - // e.clipboardData.setData("dash/pdfOrigin", this.props.Document[Id]); - // e.clipboardData.setData("dash/pdfRegion", annoDoc[Id]); - //} e.preventDefault(); } } @@ -174,12 +168,13 @@ export class PDFViewer extends ViewBoxAnnotatableComponent(this.props.pdf.numPages); await Promise.all(this._pageSizes.map>((val, i) => this.props.pdf.getPage(i + 1).then(action((page: Pdfjs.PDFPageProxy) => { + const page0or180 = page.rotate === 0 || page.rotate === 180; this._pageSizes.splice(i, 1, { - width: (page.view[page.rotate === 0 || page.rotate === 180 ? 2 : 3] - page.view[page.rotate === 0 || page.rotate === 180 ? 0 : 1]), - height: (page.view[page.rotate === 0 || page.rotate === 180 ? 3 : 2] - page.view[page.rotate === 0 || page.rotate === 180 ? 1 : 0]) + width: (page.view[page0or180 ? 2 : 3] - page.view[page0or180 ? 0 : 1]), + height: (page.view[page0or180 ? 3 : 2] - page.view[page0or180 ? 1 : 0]) }); - i === this.props.pdf.numPages - 1 && this.props.loaded?.((page.view[page.rotate === 0 || page.rotate === 180 ? 2 : 3] - page.view[page.rotate === 0 || page.rotate === 180 ? 0 : 1]), - (page.view[page.rotate === 0 || page.rotate === 180 ? 3 : 2] - page.view[page.rotate === 0 || page.rotate === 180 ? 1 : 0]), i); + i === this.props.pdf.numPages - 1 && this.props.loaded?.((page.view[page0or180 ? 2 : 3] - page.view[page0or180 ? 0 : 1]), + (page.view[page0or180 ? 3 : 2] - page.view[page0or180 ? 1 : 0]), i); })))); this.Document.scrollHeight = this._pageSizes.reduce((size, page) => size + page.height, 0) * 96 / 72; } @@ -207,13 +202,13 @@ export class PDFViewer extends ViewBoxAnnotatableComponent { if (this._viewerIsSetup) return; - else this._viewerIsSetup = true; + this._viewerIsSetup = true; this._showWaiting = true; this.props.setPdfViewer(this); await this.initialLoad(); this._disposers.filterScript = reaction( - () => Cast(this.Document.filterScript, ScriptField), + () => ScriptCast(this.Document.filterScript), action(scriptField => { const oldScript = this._script.originalScript; this._script = scriptField?.script.compiled ? scriptField.script : CompileScript("return true") as CompiledScript; @@ -234,25 +229,23 @@ export class PDFViewer extends ViewBoxAnnotatableComponent NumCast(this.Document._scrollTop), + () => Math.abs(NumCast(this.Document._scrollTop)), (pos) => { if (!this._ignoreScroll) { (this._showCover || this._showWaiting) && this.setupPdfJsViewer(); const viewTrans = quickScroll ?? StrCast(this.Document._viewTransition); - const delay = this._mainCont.current ? 0 : 250; // wait for mainCont and try again to scroll const durationMiliStr = viewTrans.match(/([0-9]*)ms/); const durationSecStr = viewTrans.match(/([0-9.]*)s/); const duration = durationMiliStr ? Number(durationMiliStr[1]) : durationSecStr ? Number(durationSecStr[1]) * 1000 : 0; + this._forcedScroll = true; if (duration) { - this._smoothScrolling = true; setTimeout(() => { - this._mainCont.current && smoothScroll(duration, this._mainCont.current, Math.abs(pos || 0)); - setTimeout(() => this._smoothScrolling = false, duration); - }, delay); + this._mainCont.current && smoothScroll(duration, this._mainCont.current, pos); + setTimeout(() => this._forcedScroll = false, duration); + }, this._mainCont.current ? 0 : 250); // wait for mainCont and try again to scroll } else { - this._smoothScrolling = true; - this._mainCont.current?.scrollTo({ top: Math.abs(pos || 0) }); - this._smoothScrolling = false; + this._mainCont.current?.scrollTo({ top: pos }); + this._forcedScroll = false; } } }, @@ -267,8 +260,10 @@ export class PDFViewer extends ViewBoxAnnotatableComponent this.createPdfViewer(), 1000); } return; @@ -277,9 +272,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent { - this._showWaiting = false; - })); + eventBus._on("pagerendered", action(() => this._showWaiting = false)); const pdfLinkService = new PDFJSViewer.PDFLinkService({ eventBus }); const pdfFindController = new PDFJSViewer.PDFFindController({ linkService: pdfLinkService, eventBus }); this._pdfViewer = new PDFJSViewer.PDFViewer({ @@ -324,8 +317,8 @@ export class PDFViewer extends ViewBoxAnnotatableComponent) => { - if (this._mainCont.current && !this._smoothScrolling) { - this._ignoreScroll = true; + if (this._mainCont.current && !this._forcedScroll) { + this._ignoreScroll = true; // the pdf scrolled, so we need to tell the Doc to scroll but we don't want the doc to then try to set the PDF scroll pos (which would interfere with the smooth scroll animation) if (!LinkDocPreview.LinkInfo) { this.layoutDoc._scrollTop = this._mainCont.current.scrollTop; } @@ -343,32 +336,24 @@ export class PDFViewer extends ViewBoxAnnotatableComponent { + const findOpts = { + caseSensitive: false, + findPrevious: !fwd, + highlightAll: true, + phraseSearch: true, + query: searchString + }; if (clear) { this._pdfViewer?.findController.executeCommand('reset', { query: "" }); } else if (!searchString) { fwd ? this.nextAnnotation() : this.prevAnnotation(); } else if (this._pdfViewer?.pageViewsReady) { - this._pdfViewer.findController.executeCommand('findagain', { - caseSensitive: false, - findPrevious: !fwd, - highlightAll: true, - phraseSearch: true, - query: searchString - }); + this._pdfViewer.findController.executeCommand('findagain', findOpts); } else if (this._mainCont.current) { - const executeFind = () => { - this._pdfViewer.findController.executeCommand('find', { - caseSensitive: false, - findPrevious: !fwd, - highlightAll: true, - phraseSearch: true, - query: searchString - }); - }; + const executeFind = () => this._pdfViewer.findController.executeCommand('find', findOpts); this._mainCont.current.addEventListener("pagesloaded", executeFind); this._mainCont.current.addEventListener("pagerendered", executeFind); } @@ -376,7 +361,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent { - const hit = document.elementFromPoint(e.clientX, e.clientY); + // const hit = document.elementFromPoint(e.clientX, e.clientY); // bcz: Change. drag selecting requires that preventDefault is NOT called. This used to happen in DocumentView, // but that's changed, so this shouldn't be needed. // if (hit && hit.localName === "span" && this.annotationsActive(true)) { // drag selecting text stops propagation @@ -414,11 +399,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent { - // if (e.target && (e.target as any).parentElement === this._mainCont.current) - e.stopPropagation(); - } + onSelectMove = (e: PointerEvent) => e.stopPropagation(); @action onSelectEnd = (e: PointerEvent): void => { @@ -429,8 +410,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent {this.inlineTextAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map(anno => ) -- cgit v1.2.3-70-g09d2 From 5fd9a0d6285d425363f820426d447343bc54f518 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 9 Mar 2021 21:11:18 -0500 Subject: from last --- .../views/nodes/formattedText/FormattedTextBox.tsx | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'src/client/views/nodes/formattedText') diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 89df7a98a..ad11d55bf 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -91,16 +91,13 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp return Cast(Doc.UserDoc().defaultTextLayout, Doc, null) || StrCast(Doc.UserDoc().defaultTextLayout, null); } public static Instance: FormattedTextBox; + public static LiveTextUndo: UndoManager.Batch | undefined; static _highlights: string[] = ["Audio Tags", "Text from Others", "Todo Items", "Important Items", "Disagree Items", "Ignore Items"]; static _highlightStyleSheet: any = addStyleSheet(); static _bulletStyleSheet: any = addStyleSheet(); static _userStyleSheet: any = addStyleSheet(); static _canAnnotate = true; static _hadSelection: boolean = false; - public static LiveTextUndo: UndoManager.Batch | undefined; - public ProseRef?: HTMLDivElement; - public get EditorView() { return this._editorView; } - public get SidebarKey() { return this.fieldKey + "-sidebar"; } private _ref: React.RefObject = React.createRef(); private _scrollRef: React.RefObject = React.createRef(); private _editorView: Opt; @@ -123,6 +120,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp private _downX = 0; private _downY = 0; private _break = false; + public ProseRef?: HTMLDivElement; + public get EditorView() { return this._editorView; } + public get SidebarKey() { return this.fieldKey + "-sidebar"; } @computed get sidebarWidthPercent() { return StrCast(this.layoutDoc._sidebarWidthPercent, "0%"); } @computed get sidebarColor() { return StrCast(this.layoutDoc.sidebarColor, StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "#e4e4e4")); } @@ -879,14 +879,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } }; const undo = () => { - if (!exportState) { - return; - } - const content: GoogleApiClientUtils.Docs.Content = { - text: exportState.text, - requests: [] - }; - if (reference && content) { + if (exportState && reference) { + const content: GoogleApiClientUtils.Docs.Content = { + text: exportState.text, + requests: [] + }; GoogleApiClientUtils.Docs.write({ reference, content, mode }); } }; -- cgit v1.2.3-70-g09d2