From 12ae56962397a786397158af9e442a955883d16f Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 22 Sep 2021 03:30:58 -0400
Subject: fixed runtime bug inside toggleBold().  removed print statements.

---
 .../views/nodes/formattedText/RichTextMenu.tsx     | 186 +++++++++++----------
 1 file changed, 95 insertions(+), 91 deletions(-)

(limited to 'src/client/views/nodes/formattedText/RichTextMenu.tsx')

diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index 9904a7939..23a3d80a4 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -1,8 +1,7 @@
 import React = require("react");
-import { IconProp } from '@fortawesome/fontawesome-svg-core';
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { Tooltip } from "@material-ui/core";
-import { action, IReactionDisposer, observable, reaction, runInAction } from "mobx";
+import { action, IReactionDisposer, observable, reaction, runInAction, computed } from "mobx";
 import { observer } from "mobx-react";
 import { lift, wrapIn } from "prosemirror-commands";
 import { Mark, MarkType, Node as ProsNode, NodeType, ResolvedPos } from "prosemirror-model";
@@ -10,10 +9,7 @@ import { wrapInList } from "prosemirror-schema-list";
 import { EditorState, NodeSelection, TextSelection } from "prosemirror-state";
 import { EditorView } from "prosemirror-view";
 import { Doc } from "../../../../fields/Doc";
-import { DarkPastelSchemaPalette, PastelSchemaPalette } from '../../../../fields/SchemaHeaderField';
 import { Cast, StrCast } from "../../../../fields/Types";
-import { TraceMobx } from "../../../../fields/util";
-import { unimplementedFunction, Utils } from "../../../../Utils";
 import { DocServer } from "../../../DocServer";
 import { LinkManager } from "../../../util/LinkManager";
 import { SelectionManager } from "../../../util/SelectionManager";
@@ -29,7 +25,7 @@ const { toggleMark } = require("prosemirror-commands");
 
 @observer
 export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps>   {
-    static Instance: RichTextMenu;
+    @observable static Instance: RichTextMenu;
     public overMenu: boolean = false; // kind of hacky way to prevent selects not being selectable
     private _linkToRef = React.createRef<HTMLInputElement>();
 
@@ -39,22 +35,22 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps>   {
     public _brushMap: Map<string, Set<Mark>> = new Map();
 
     @observable private collapsed: boolean = false;
-    @observable private boldActive: boolean = false;
-    @observable private italicsActive: boolean = false;
-    @observable private underlineActive: boolean = false;
-    @observable private strikethroughActive: boolean = false;
-    @observable private subscriptActive: boolean = false;
-    @observable private superscriptActive: boolean = false;
-
-    @observable private activeFontSize: string = "";
-    @observable private activeFontFamily: string = "";
+    @observable private _boldActive: boolean = false;
+    @observable private _italicsActive: boolean = false;
+    @observable private _underlineActive: boolean = false;
+    @observable private _strikethroughActive: boolean = false;
+    @observable private _subscriptActive: boolean = false;
+    @observable private _superscriptActive: boolean = false;
+
+    @observable private _activeFontSize: string = "13px";
+    @observable private _activeFontFamily: string = "";
     @observable private activeListType: string = "";
     @observable private activeAlignment: string = "left";
 
     @observable private brushMarks: Set<Mark> = new Set();
     @observable private showBrushDropdown: boolean = false;
 
-    @observable private activeFontColor: string = "black";
+    @observable private _activeFontColor: string = "black";
     @observable private showColorDropdown: boolean = false;
 
     @observable private activeHighlightColor: string = "transparent";
@@ -67,10 +63,12 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps>   {
     _delayHide = false;
     constructor(props: Readonly<{}>) {
         super(props);
-        RichTextMenu.Instance = this;
-        this._canFade = false;
-        //this.Pinned = BoolCast(Doc.UserDoc()["menuRichText-pinned"]);
-        runInAction(() => this.Pinned = true);
+        runInAction(() => {
+            RichTextMenu.Instance = this;
+            this._canFade = false;
+            //this.Pinned = BoolCast(Doc.UserDoc()["menuRichText-pinned"]);
+            this.Pinned = true;
+        });
     }
 
     componentDidMount() {
@@ -81,6 +79,14 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps>   {
         this._reaction?.();
     }
 
+    @computed get bold() { return this._boldActive; }
+    @computed get underline() { return this._underlineActive; }
+    @computed get italics() { return this._italicsActive; }
+    @computed get strikeThrough() { return this._strikethroughActive; }
+    @computed get fontColor() { return this._activeFontColor; }
+    @computed get fontFamily() { return this._activeFontFamily; }
+    @computed get fontSize() { return this._activeFontSize; }
+
     public delayHide = () => this._delayHide = true;
 
     @action
@@ -110,10 +116,10 @@ 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 ? "13px" : activeSizes.length === 1 ? String(activeSizes[0]) : "...";
-        this.activeFontColor = !activeColors.length ? "black" : activeColors.length === 1 ? String(activeColors[0]) : "...";
-        this.activeHighlightColor = !activeHighlights.length ? "" : activeHighlights.length === 1 ? String(activeHighlights[0]) : "...";
+        this._activeFontFamily = !activeFamilies.length ? "Arial" : activeFamilies.length === 1 ? String(activeFamilies[0]) : "various";
+        this._activeFontSize = !activeSizes.length ? "13px" : activeSizes[0];
+        this._activeFontColor = !activeColors.length ? "black" : activeColors.length > 0 ? String(activeColors[0]) : "...";
+        this.activeHighlightColor = !activeHighlights.length ? "" : activeHighlights.length > 0 ? String(activeHighlights[0]) : "...";
 
         // update link in current selection
         this.getTextLinkTargetTitle().then(targetTitle => this.setCurrentLink(targetTitle));
@@ -125,7 +131,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps>   {
             if (node?.type === schema.nodes.ordered_list) {
                 let attrs = node.attrs;
                 if (mark.type === schema.marks.pFontFamily) attrs = { ...attrs, fontFamily: mark.attrs.family };
-                if (mark.type === schema.marks.pFontSize) attrs = { ...attrs, fontSize: `${mark.attrs.fontSize}px` };
+                if (mark.type === schema.marks.pFontSize) attrs = { ...attrs, fontSize: mark.attrs.fontSize };
                 if (mark.type === schema.marks.pFontColor) attrs = { ...attrs, fontColor: mark.attrs.color };
                 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))));
@@ -142,17 +148,6 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps>   {
         }
     }
 
-    getBoldStatus() {
-        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) {
-                    return path[i].attrs.strong;
-                }
-            }
-        }
-    }
-
     // finds font sizes and families in selection
     getActiveAlignment() {
         if (this.view && this.TextView.props.isSelected(true)) {
@@ -193,25 +188,23 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps>   {
         if (this.TextView.props.isSelected(true)) {
             const state = this.view.state;
             const pos = this.view.state.selection.$from;
-            const ref_node = this.reference_node(pos);
-            if (ref_node && ref_node !== this.view.state.doc && ref_node.isText) {
-                const marks = Array.from(ref_node.marks);
-                marks.push(...(this.view.state.storedMarks as any));
-                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(String(m.attrs.fontSize) + "px");
-                    m.type === state.schema.marks.marker && activeHighlights.push(String(m.attrs.highlight));
+            const marks: Mark<any>[] = [];
+            if (state.selection.empty) {
+                const ref_node = this.reference_node(pos);
+                marks.push(...[...(ref_node !== this.view.state.doc && ref_node?.isText ?
+                    [...(state.storedMarks ?? []), ...Array.from(ref_node.marks)] : [])]);
+            } else {
+                state.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos, parent, index) => {
+                    node.marks?.filter(mark => !mark.isInSet(marks)).map(mark => marks.push(mark));
                 });
             }
-            !activeFamilies.length && (activeFamilies.push(StrCast(this.TextView.layoutDoc._fontFamily, StrCast(Doc.UserDoc().fontFamily))));
-            !activeSizes.length && (activeSizes.push(StrCast(this.TextView.layoutDoc._fontSize, StrCast(Doc.UserDoc().fontSize))));
-            !activeColors.length && (activeColors.push(StrCast(this.TextView.layoutDoc.color, StrCast(Doc.UserDoc().fontColor))));
+            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));
+            });
         }
-        !activeFamilies.length && (activeFamilies.push(StrCast(Doc.UserDoc().fontFamily)));
-        !activeSizes.length && (activeSizes.push(StrCast(Doc.UserDoc().fontSize)));
-        !activeColors.length && (activeColors.push(StrCast(Doc.UserDoc().fontColor, "black")));
-        !activeHighlights.length && (activeHighlights.push(StrCast(Doc.UserDoc().fontHighlight, "")));
         return { activeFamilies, activeSizes, activeColors, activeHighlights };
     }
 
@@ -251,11 +244,12 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps>   {
                     return [];
                 }
                 activeMarks = markGroup.filter(mark_type => {
-                    if (mark_type === state.schema.marks.pFontSize) {
-                        return ref_node.marks.some(m => m.type.name === state.schema.marks.pFontSize.name);
-                    }
+                    // if (mark_type === state.schema.marks.pFontSize) {
+                    //     return mark.isINSet
+                    //     ref_node.marks.some(m => m.type.name === state.schema.marks.pFontSize.name);
+                    // }
                     const mark = state.schema.mark(mark_type);
-                    return ref_node.marks.includes(mark);
+                    return mark.isInSet(ref_node.marks);
                 });
             }
         }
@@ -270,56 +264,66 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps>   {
     setActiveMarkButtons(activeMarks: MarkType[] | undefined) {
         if (!activeMarks) return;
 
-        this.boldActive = false;
-        this.italicsActive = false;
-        this.underlineActive = false;
-        this.strikethroughActive = false;
-        this.subscriptActive = false;
-        this.superscriptActive = false;
+        this._boldActive = false;
+        this._italicsActive = false;
+        this._underlineActive = false;
+        this._strikethroughActive = false;
+        this._subscriptActive = false;
+        this._superscriptActive = false;
 
         activeMarks.forEach(mark => {
             switch (mark.name) {
-                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 "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;
             }
         });
     }
 
-    toggleBold = (view: EditorView, forceBool?: boolean) => {
-        const mark = view.state.schema.mark(view.state.schema.marks.strong, { strong: forceBool });
-        this.setMark(mark, view.state, view.dispatch, false);
-        view.focus();
+    toggleBold = () => {
+        if (this.view) {
+            const mark = this.view.state.schema.mark(this.view.state.schema.marks.strong);
+            this.setMark(mark, this.view.state, this.view.dispatch, false);
+            this.view.focus();
+        }
     }
 
-    toggleUnderline = (view: EditorView, forceBool?: boolean) => {
-        const mark = view.state.schema.mark(view.state.schema.marks.underline, { underline: forceBool });
-        this.setMark(mark, view.state, view.dispatch, false);
-        view.focus();
+    toggleUnderline = () => {
+        if (this.view) {
+            const mark = this.view.state.schema.mark(this.view.state.schema.marks.underline);
+            this.setMark(mark, this.view.state, this.view.dispatch, false);
+            this.view.focus();
+        }
     }
 
-    toggleItalic = (view: EditorView, forceBool?: boolean) => {
-        const mark = view.state.schema.mark(view.state.schema.marks.em, { em: forceBool });
-        this.setMark(mark, view.state, view.dispatch, false);
-        view.focus();
+    toggleItalics = () => {
+        if (this.view) {
+            const mark = this.view.state.schema.mark(this.view.state.schema.marks.em);
+            this.setMark(mark, this.view.state, this.view.dispatch, false);
+            this.view.focus();
+        }
     }
 
 
-    setFontSize = (size: number, view: EditorView) => {
-        const fmark = view.state.schema.marks.pFontSize.create({ fontSize: size });
-        this.setMark(fmark, view.state, (tx: any) => view.dispatch(tx.addStoredMark(fmark)), true);
-        view.focus();
-        this.updateMenu(view, undefined, this.props);
+    setFontSize = (fontSize: string) => {
+        if (this.view) {
+            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);
+        }
     }
 
-    setFontFamily = (family: string, view: EditorView) => {
-        const fmark = view.state.schema.marks.pFontFamily.create({ family: family });
-        this.setMark(fmark, view.state, (tx: any) => view.dispatch(tx.addStoredMark(fmark)), true);
-        view.focus();
-        this.updateMenu(view, undefined, this.props);
+    setFontFamily = (family: string) => {
+        if (this.view) {
+            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);
+        }
     }
 
     setHighlight(color: String, view: EditorView, dispatch: any) {
@@ -330,7 +334,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps>   {
     }
 
     setColor(color: String, view: EditorView, dispatch: any) {
-        const colorMark = view.state.schema.mark(view.state.schema.marks.pFontColor, { color: color });
+        const colorMark = view.state.schema.mark(view.state.schema.marks.pFontColor, { color });
         if (view.state.selection.empty) {
             dispatch(view.state.tr.addStoredMark(colorMark));
             return false;
-- 
cgit v1.2.3-70-g09d2

