From ba3b3f6f261074bd3f35012bde8730f5d4a36905 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 29 Nov 2023 10:02:34 -0500 Subject: numerous changes to fix bugs and to fix/remove old or hacky code. fixed doc dec resizing. moving this.rootDoc => this.Document . fixing template artifacts. --- .../views/nodes/formattedText/FormattedTextBox.tsx | 53 ++++++++++++---------- .../views/nodes/formattedText/RichTextMenu.tsx | 46 ++++++++++--------- .../views/nodes/formattedText/RichTextRules.ts | 2 +- 3 files changed, 55 insertions(+), 46 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 b65c440d1..dd4be7fcd 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -316,7 +316,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent this.getAnchor(true), targetCreator), e.pageX, e.pageY); }); const coordsB = this._editorView!.coordsAtPos(this._editorView!.state.selection.to); - this.props.isSelected() && AnchorMenu.Instance.jumpTo(coordsB.left, coordsB.bottom); + this.props.rootSelected() && AnchorMenu.Instance.jumpTo(coordsB.left, coordsB.bottom); let ele: Opt = undefined; try { const contents = window.getSelection()?.getRangeAt(0).cloneContents(); @@ -388,7 +388,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent; + if ([AclEdit, AclAdmin, AclSelfEdit].includes(effectiveAcl)) { // replace text contents when dragging with Alt if (de.altKey) { const fieldKey = Doc.LayoutFieldKey(draggedDoc); @@ -613,8 +613,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent this.props.isSelected(), + () => this.props.rootSelected(), action(selected => { //selected && setTimeout(() => this.prepareForTyping()); if (FormattedTextBox._globalHighlights.has('Bold Text')) { this.layoutDoc[DocCss] = this.layoutDoc[DocCss] + 1; // css change happens outside of mobx/react, so this will notify anyone interested in the layout that it has changed } if (RichTextMenu.Instance?.view === this._editorView && !selected) { - RichTextMenu.Instance?.updateMenu(undefined, undefined, undefined); + RichTextMenu.Instance?.updateMenu(undefined, undefined, undefined, undefined); } if (this._editorView && selected) { - RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this.props); + RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this.props, this.layoutDoc); setTimeout(this.autoLink, 20); } }), @@ -1451,7 +1451,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent self.props.isSelected() && RichTextMenu.Instance && (RichTextMenu.Instance.view = newView)); + runInAction(() => self.props.rootSelected() && RichTextMenu.Instance && (RichTextMenu.Instance.view = newView)); return new RichTextMenuPlugin({ editorProps: this.props }); }, }); @@ -1588,7 +1588,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { FormattedTextBoxComment.textBox = this; - if (e.button === 0 && this.props.isSelected() && !e.altKey && !e.ctrlKey && !e.metaKey) { + if (e.button === 0 && this.props.rootSelected() && !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 click events @@ -1669,7 +1669,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { + console.log('FOCUSED = ' + this.layoutDoc.title + ' ' + this.props.rootSelected()); //applyDevTools.applyDevTools(this._editorView); - this.ProseRef?.children[0] === e.nativeEvent.target && this._editorView && RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this.props); + this.ProseRef?.children[0] === e.nativeEvent.target && this._editorView && RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this.props, this.layoutDoc); e.stopPropagation(); }; @@ -1715,7 +1716,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { + console.log('BLUREd = ' + this.layoutDoc.title + ' ' + this.props.rootSelected()); if (this.ProseRef?.children[0] !== e.nativeEvent.target) return; if (!(this.EditorView?.state.selection instanceof NodeSelection) || this.EditorView.state.selection.node.type !== this.EditorView.state.schema.nodes.footnote) { const stordMarks = this._editorView?.state.storedMarks?.slice(); @@ -1778,8 +1780,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent + const height = Number(styleFromLayoutString.height?.replace('px', '')); // prevent default if selected || child is active but this doc isn't scrollable if ( - (this._scrollRef.current?.scrollHeight ?? 0) <= Math.ceil(this.props.PanelHeight() / (this.props.NativeDimScaling?.() || 1)) && // - (this.props.isSelected() || this.isAnyChildContentActive()) + (this._scrollRef.current?.scrollHeight ?? 0) <= Math.ceil((height ? height : this.props.PanelHeight()) / scale) && // + (this.props.rootSelected() || this.isAnyChildContentActive()) ) { e.preventDefault(); } @@ -2103,7 +2108,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent !this.props.isContentActive() && FormattedTextBoxComment.textBox === this && FormattedTextBoxComment.Hide); const paddingX = NumCast(this.layoutDoc._xMargin, this.props.xPadding || 0); const paddingY = NumCast(this.layoutDoc._yMargin, this.props.yPadding || 0); - const styleFromLayoutString = Doc.styleFromLayoutString(this.rootDoc, this.layoutDoc, this.props, scale); // this converts any expressions in the format string to style props. e.g., + const styleFromLayoutString = Doc.styleFromLayoutString(this.Document, this.props, scale); // this converts any expressions in the format string to style props. e.g., return styleFromLayoutString?.height === '0px' ? null : (
{ public overMenu: boolean = false; // kind of hacky way to prevent selects not being selectable private _linkToRef = React.createRef(); + layoutDoc: Doc | undefined; @observable public view?: EditorView; public editorProps: FieldViewProps | undefined; @@ -66,7 +67,7 @@ export class RichTextMenu extends AntimodeMenu { super(props); runInAction(() => { RichTextMenu.Instance = this; - this.updateMenu(undefined, undefined, props); + this.updateMenu(undefined, undefined, props, this.layoutDoc); this._canFade = false; this.Pinned = true; }); @@ -102,11 +103,14 @@ export class RichTextMenu extends AntimodeMenu { @computed get textAlign() { return this._activeAlignment; } + @computed get textVcenter() { + return BoolCast(this.layoutDoc?.layout_centered); + } _disposer: IReactionDisposer | undefined; componentDidMount() { this._disposer = reaction( () => SelectionManager.Views().slice(), - views => this.updateMenu(undefined, undefined, undefined) + views => this.updateMenu(undefined, undefined, undefined, undefined) ); } componentWillUnmount() { @@ -114,11 +118,12 @@ export class RichTextMenu extends AntimodeMenu { } @action - public updateMenu(view: EditorView | undefined, lastState: EditorState | undefined, props: any) { + public updateMenu(view: EditorView | undefined, lastState: EditorState | undefined, props: any, layoutDoc: Doc | undefined) { if (this._linkToRef.current?.getBoundingClientRect().width) { return; } this.view = view; + this.layoutDoc = layoutDoc; props && (this.editorProps = props); // Don't do anything if the document/selection didn't change @@ -181,7 +186,7 @@ export class RichTextMenu extends AntimodeMenu { // finds font sizes and families in selection getActiveAlignment() { - if (this.view && this.TextView?.props.isSelected()) { + if (this.view && this.TextView?.props.rootSelected()) { const path = (this.view.state.selection.$from as any).path; for (let i = path.length - 3; i < path.length && i >= 0; i -= 3) { if (path[i]?.type === this.view.state.schema.nodes.paragraph || path[i]?.type === this.view.state.schema.nodes.heading) { @@ -194,7 +199,7 @@ export class RichTextMenu extends AntimodeMenu { // finds font sizes and families in selection getActiveListStyle() { - if (this.view && this.TextView?.props.isSelected()) { + if (this.view && this.TextView?.props.rootSelected()) { const path = (this.view.state.selection.$from as any).path; for (let i = 0; i < path.length; i += 3) { if (path[i].type === this.view.state.schema.nodes.ordered_list) { @@ -214,7 +219,7 @@ export class RichTextMenu extends AntimodeMenu { const activeSizes = new Set(); const activeColors = new Set(); const activeHighlights = new Set(); - if (this.view && this.TextView?.props.isSelected()) { + if (this.view && this.TextView?.props.rootSelected()) { const state = this.view.state; const pos = this.view.state.selection.$from; const marks: Mark[] = [...(state.storedMarks ?? [])]; @@ -249,7 +254,7 @@ export class RichTextMenu extends AntimodeMenu { //finds all active marks on selection in given group getActiveMarksOnSelection() { let activeMarks: MarkType[] = []; - if (!this.view || !this.TextView?.props.isSelected()) return activeMarks; + if (!this.view || !this.TextView?.props.rootSelected()) return activeMarks; const markGroup = [schema.marks.noAutoLinkAnchor, schema.marks.strong, schema.marks.em, schema.marks.underline, schema.marks.strikethrough, schema.marks.superscript, schema.marks.subscript]; if (this.view.state.storedMarks) return this.view.state.storedMarks.map(mark => mark.type); @@ -285,10 +290,6 @@ export class RichTextMenu extends AntimodeMenu { return activeMarks; } - destroy() { - !this.TextView?.props.isSelected() && this.fadeOut(true); - } - @action setActiveMarkButtons(activeMarks: MarkType[] | undefined) { if (!activeMarks) return; @@ -360,7 +361,7 @@ export class RichTextMenu extends AntimodeMenu { } else if (SelectionManager.Views().some(dv => dv.ComponentView instanceof EquationBox)) { SelectionManager.Views().forEach(dv => (dv.rootDoc._text_fontSize = fontSize)); } else Doc.UserDoc().fontSize = fontSize; - this.updateMenu(this.view, undefined, this.props); + this.updateMenu(this.view, undefined, this.props, this.layoutDoc); }; setFontFamily = (family: string) => { @@ -369,7 +370,7 @@ export class RichTextMenu extends AntimodeMenu { this.setMark(fmark, this.view.state, (tx: any) => this.view!.dispatch(tx.addStoredMark(fmark)), true); this.view.focus(); } else Doc.UserDoc().fontFamily = family; - this.updateMenu(this.view, undefined, this.props); + this.updateMenu(this.view, undefined, this.props, this.layoutDoc); }; setHighlight(color: string) { @@ -378,7 +379,7 @@ export class RichTextMenu extends AntimodeMenu { this.setMark(highlightMark, this.view.state, (tx: any) => this.view!.dispatch(tx.addStoredMark(highlightMark)), true); this.view.focus(); } else Doc.UserDoc()._fontHighlight = color; - this.updateMenu(this.view, undefined, this.props); + this.updateMenu(this.view, undefined, this.props, this.layoutDoc); } setColor(color: string) { @@ -387,7 +388,7 @@ export class RichTextMenu extends AntimodeMenu { this.setMark(colorMark, this.view.state, (tx: any) => this.view!.dispatch(tx.addStoredMark(colorMark)), true); this.view.focus(); } else Doc.UserDoc().fontColor = color; - this.updateMenu(this.view, undefined, this.props); + this.updateMenu(this.view, undefined, this.props, this.layoutDoc); } // TODO: remove doesn't work @@ -428,7 +429,7 @@ export class RichTextMenu extends AntimodeMenu { } } this.view.focus(); - this.updateMenu(this.view, undefined, this.props); + this.updateMenu(this.view, undefined, this.props, this.layoutDoc); }; insertSummarizer(state: EditorState, dispatch: any) { @@ -442,8 +443,11 @@ export class RichTextMenu extends AntimodeMenu { return true; } + vcenterToggle = (view: EditorView, dispatch: any) => { + this.layoutDoc && (this.layoutDoc.layout_centered = !this.layoutDoc.layout_centered); + }; align = (view: EditorView, dispatch: any, alignment: 'left' | 'right' | 'center') => { - if (this.TextView?.props.isSelected()) { + if (this.TextView?.props.rootSelected()) { var tr = view.state.tr; view.state.doc.nodesBetween(view.state.selection.from, view.state.selection.to, (node, pos, parent, index) => { if ([schema.nodes.paragraph, schema.nodes.heading].includes(node.type)) { @@ -875,6 +879,6 @@ export class RichTextMenuPlugin extends React.Component return null; } update(view: EditorView, lastState: EditorState | undefined) { - RichTextMenu.Instance?.updateMenu(view, lastState, this.props.editorProps); + RichTextMenu.Instance?.updateMenu(view, lastState, this.props.editorProps, (view as any).TextView?.layoutDoc); } } diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts index 3e2afd2ce..701ee4053 100644 --- a/src/client/views/nodes/formattedText/RichTextRules.ts +++ b/src/client/views/nodes/formattedText/RichTextRules.ts @@ -95,7 +95,7 @@ export class RichTextRules { textDocInline.title_custom = true; // And make sure that it's 'custom' so that editing text doesn't change the title of the containing doc textDocInline.isTemplateForField = inlineFieldKey; // this is needed in case the containing text doc is converted to a template at some point textDocInline.proto = textDoc; // make the annotation inherit from the outer text doc so that it can resolve any nested field references, e.g., [[field]] - textDocInline._textContext = ComputedField.MakeFunction(`copyField(self.${inlineFieldKey})`); + textDocInline._textContext = ComputedField.MakeFunction(`copyField(this.${inlineFieldKey})`); textDoc[inlineLayoutKey] = FormattedTextBox.LayoutString(inlineFieldKey); // create a layout string for the layout key that will render the annotation text textDoc[inlineFieldKey] = ''; // set a default value for the annotation const node = (state.doc.resolve(start) as any).nodeAfter; -- cgit v1.2.3-70-g09d2