diff options
Diffstat (limited to 'src/client/views/nodes/formattedText/RichTextMenu.tsx')
-rw-r--r-- | src/client/views/nodes/formattedText/RichTextMenu.tsx | 104 |
1 files changed, 42 insertions, 62 deletions
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index 0cbe60c0c..6c6d26af5 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -64,6 +64,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> { super(props); runInAction(() => { RichTextMenu.Instance = this; + this.updateMenu(undefined, undefined, props); this._canFade = false; this.Pinned = true; }); @@ -103,13 +104,12 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> { return; } this.view = view; - if (!view || !view.hasFocus()) { - return; - } props && (this.editorProps = props); // Don't do anything if the document/selection didn't change - if (lastState?.doc.eq(view.state.doc) && lastState.selection.eq(view.state.selection)) return; + if (view && view.hasFocus()) { + if (lastState?.doc.eq(view.state.doc) && lastState.selection.eq(view.state.selection)) return; + } // update active marks const activeMarks = this.getActiveMarksOnSelection(); @@ -124,9 +124,9 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> { this.activeListType = this.getActiveListStyle(); this._activeAlignment = this.getActiveAlignment(); - this._activeFontFamily = !activeFamilies.length ? 'Arial' : activeFamilies.length === 1 ? String(activeFamilies[0]) : 'various'; - this._activeFontSize = !activeSizes.length ? StrCast(this.TextView.Document.fontSize, StrCast(Doc.UserDoc().fontSize, '10px')) : activeSizes[0]; - this._activeFontColor = !activeColors.length ? 'black' : activeColors.length > 0 ? String(activeColors[0]) : '...'; + this._activeFontFamily = !activeFamilies.length ? StrCast(this.TextView?.Document.fontFamily, StrCast(Doc.UserDoc().fontFamily, 'Arial')) : activeFamilies.length === 1 ? String(activeFamilies[0]) : 'various'; + this._activeFontSize = !activeSizes.length ? StrCast(this.TextView?.Document.fontSize, StrCast(Doc.UserDoc().fontSize, '10px')) : activeSizes[0]; + this._activeFontColor = !activeColors.length ? StrCast(this.TextView?.Document.fontColor, StrCast(Doc.UserDoc().fontColor, 'black')) : activeColors.length > 0 ? String(activeColors[0]) : '...'; this.activeHighlightColor = !activeHighlights.length ? '' : activeHighlights.length > 0 ? String(activeHighlights[0]) : '...'; // update link in current selection @@ -144,13 +144,8 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> { const tr = updateBullets(state.tr.setNodeMarkup(state.selection.from, node.type, attrs), state.schema); dispatch(tr.setSelection(new NodeSelection(tr.doc.resolve(state.selection.from)))); } else if (dontToggle) { - toggleMark(mark.type, mark.attrs)(state, (tx: any) => { - const { from, $from, to, empty } = tx.selection; - if (!tx.doc.rangeHasMark(from, to, mark.type)) { - // hack -- should have just set the mark in the first place - toggleMark(mark.type, mark.attrs)({ tr: tx, doc: tx.doc, selection: tx.selection, storedMarks: tx.storedMarks }, dispatch); - } else dispatch(tx); - }); + const tr = state.tr.addMark(state.selection.from, state.selection.to, mark); + dispatch(tr.setSelection(new TextSelection(tr.doc.resolve(state.selection.from), tr.doc.resolve(state.selection.to)))); // bcz: need to redo the selection because ctrl-a selections disappear otherwise } else { toggleMark(mark.type, mark.attrs)(state, dispatch); } @@ -159,7 +154,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> { // finds font sizes and families in selection getActiveAlignment() { - if (this.view && this.TextView.props.isSelected(true)) { + if (this.view && this.TextView?.props.isSelected(true)) { 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) { @@ -172,7 +167,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> { // finds font sizes and families in selection getActiveListStyle() { - if (this.view && this.TextView.props.isSelected(true)) { + if (this.view && this.TextView?.props.isSelected(true)) { 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) { @@ -188,17 +183,16 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> { // finds font sizes and families in selection getActiveFontStylesOnSelection() { - if (!this.view) return { activeFamilies: [], activeSizes: [], activeColors: [], activeHighlights: [] }; - - const activeFamilies: string[] = []; - const activeSizes: string[] = []; - const activeColors: string[] = []; - const activeHighlights: string[] = []; - if (this.TextView.props.isSelected(true)) { + const activeFamilies = new Set<string>(); + const activeSizes = new Set<string>(); + const activeColors = new Set<string>(); + const activeHighlights = new Set<string>(); + if (this.view && this.TextView?.props.isSelected(true)) { const state = this.view.state; const pos = this.view.state.selection.$from; const marks: Mark[] = [...(state.storedMarks ?? [])]; - if (state.selection.empty) { + if (state.storedMarks !== null) { + } else if (state.selection.empty) { const ref_node = this.reference_node(pos); marks.push(...(ref_node !== this.view.state.doc && ref_node?.isText ? Array.from(ref_node.marks) : [])); } else { @@ -207,13 +201,13 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> { }); } marks.forEach(m => { - m.type === state.schema.marks.pFontFamily && activeFamilies.push(m.attrs.family); - m.type === state.schema.marks.pFontColor && activeColors.push(m.attrs.color); - m.type === state.schema.marks.pFontSize && activeSizes.push(m.attrs.fontSize); - m.type === state.schema.marks.marker && activeHighlights.push(String(m.attrs.highlight)); + m.type === state.schema.marks.pFontFamily && activeFamilies.add(m.attrs.family); + m.type === state.schema.marks.pFontColor && activeColors.add(m.attrs.color); + m.type === state.schema.marks.pFontSize && activeSizes.add(m.attrs.fontSize); + m.type === state.schema.marks.marker && activeHighlights.add(String(m.attrs.highlight)); }); } - return { activeFamilies, activeSizes, activeColors, activeHighlights }; + return { activeFamilies: Array.from(activeFamilies), activeSizes: Array.from(activeSizes), activeColors: Array.from(activeColors), activeHighlights: Array.from(activeHighlights) }; } getMarksInSelection(state: EditorState) { @@ -226,7 +220,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> { //finds all active marks on selection in given group getActiveMarksOnSelection() { let activeMarks: MarkType[] = []; - if (!this.view || !this.TextView.props.isSelected(true)) return activeMarks; + if (!this.view || !this.TextView?.props.isSelected(true)) 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); @@ -279,28 +273,15 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> { this._superscriptActive = false; activeMarks.forEach(mark => { + // prettier-ignore switch (mark.name) { - case 'noAutoLinkAnchor': - this._noLinkActive = true; - break; - case 'strong': - this._boldActive = true; - break; - case 'em': - this._italicsActive = true; - break; - case 'underline': - this._underlineActive = true; - break; - case 'strikethrough': - this._strikethroughActive = true; - break; - case 'subscript': - this._subscriptActive = true; - break; - case 'superscript': - this._superscriptActive = true; - break; + case 'noAutoLinkAnchor': this._noLinkActive = true; break; + case 'strong': this._boldActive = true; break; + case 'em': this._italicsActive = true; break; + case 'underline': this._underlineActive = true; break; + case 'strikethrough': this._strikethroughActive = true; break; + case 'subscript': this._subscriptActive = true; break; + case 'superscript': this._superscriptActive = true; break; } }); } @@ -342,14 +323,13 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> { if (this.view.state.selection.from === 1 && this.view.state.selection.empty && (!this.view.state.doc.nodeAt(1) || !this.view.state.doc.nodeAt(1)?.marks.some(m => m.type.name === fontSize))) { this.TextView.dataDoc.fontSize = fontSize; this.view.focus(); - this.updateMenu(this.view, undefined, this.props); } else { const fmark = this.view.state.schema.marks.pFontSize.create({ fontSize }); this.setMark(fmark, this.view.state, (tx: any) => this.view!.dispatch(tx.addStoredMark(fmark)), true); this.view.focus(); - this.updateMenu(this.view, undefined, this.props); } - } + } else Doc.UserDoc()._fontSize = fontSize; + this.updateMenu(this.view, undefined, this.props); }; setFontFamily = (family: string) => { @@ -357,8 +337,8 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> { const fmark = this.view.state.schema.marks.pFontFamily.create({ family: family }); this.setMark(fmark, this.view.state, (tx: any) => this.view!.dispatch(tx.addStoredMark(fmark)), true); this.view.focus(); - this.updateMenu(this.view, undefined, this.props); - } + } else Doc.UserDoc()._fontFamily = family; + this.updateMenu(this.view, undefined, this.props); }; setHighlight(color: String, view: EditorView, dispatch: any) { @@ -368,13 +348,13 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> { this.setMark(highlightMark, view.state, dispatch, false); } - setColor(color: String, view: EditorView, dispatch: any) { + setColor(color: string) { if (this.view) { - const colorMark = view.state.schema.mark(view.state.schema.marks.pFontColor, { color }); + const colorMark = this.view.state.schema.mark(this.view.state.schema.marks.pFontColor, { color }); this.setMark(colorMark, this.view.state, (tx: any) => this.view!.dispatch(tx.addStoredMark(colorMark)), true); - view.focus(); - this.updateMenu(this.view, undefined, this.props); - } + this.view.focus(); + } else Doc.UserDoc().fontColor = color; + this.updateMenu(this.view, undefined, this.props); } // TODO: remove doesn't work @@ -430,7 +410,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> { } align = (view: EditorView, dispatch: any, alignment: 'left' | 'right' | 'center') => { - if (this.TextView.props.isSelected(true)) { + if (this.TextView?.props.isSelected(true)) { 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)) { |