From eb50e46332c2f0b48c7cb165d55245aab317ef08 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 21 Sep 2021 19:43:32 -0400
Subject: fixed up some darkScheme css, enabled comic mode for developers,
 enabled opening up fields on dashboards in myDocuments

---
 src/client/views/MainView.tsx | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index d854f118f..c99ba447c 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -26,7 +26,7 @@ import { HistoryUtil } from '../util/History';
 import { Hypothesis } from '../util/HypothesisUtils';
 import { Scripting } from '../util/Scripting';
 import { SelectionManager } from '../util/SelectionManager';
-import { SettingsManager } from '../util/SettingsManager';
+import { SettingsManager, ColorScheme } from '../util/SettingsManager';
 import { SharingManager } from '../util/SharingManager';
 import { SnappingManager } from '../util/SnappingManager';
 import { Transform } from '../util/Transform';
@@ -88,7 +88,7 @@ export class MainView extends React.Component {
     @computed private get topOfMainDocContent() { return this.topOfMainDoc + this.dashboardTabHeight; }
     @computed private get leftScreenOffsetOfMainDocView() { return this.leftMenuWidth() - 2; }
     @computed private get userDoc() { return Doc.UserDoc(); }
-    @computed private get darkScheme() { return BoolCast(CurrentUserUtils.ActiveDashboard?.darkScheme); }
+    @computed private get colorScheme() { return StrCast(CurrentUserUtils.ActiveDashboard?.colorScheme); }
     @computed private get mainContainer() { return this.userDoc ? CurrentUserUtils.ActiveDashboard : CurrentUserUtils.GuestDashboard; }
     @computed public get mainFreeform(): Opt<Doc> { return (docs => (docs?.length > 1) ? docs[1] : undefined)(DocListCast(this.mainContainer!.data)); }
 
@@ -430,10 +430,10 @@ export class MainView extends React.Component {
         const transform = this._leftMenuFlyoutWidth ? 'translate(-28px, 0px)' : undefined;
         return <>
             {this.leftMenuPanel}
-            <div key="inner" className={`mainView-innerContent${this.darkScheme ? "-dark" : ""}`}>
+            <div key="inner" className={`mainView-innerContent${this.colorScheme}`}>
                 {this.flyout}
                 <div className="mainView-libraryHandle" style={{ display: !this._leftMenuFlyoutWidth ? "none" : undefined }} onPointerDown={this.onFlyoutPointerDown} >
-                    <FontAwesomeIcon icon="chevron-left" color={this.darkScheme ? "white" : "black"} style={{ opacity: "50%" }} size="sm" />
+                    <FontAwesomeIcon icon="chevron-left" color={this.colorScheme === ColorScheme.Dark ? "white" : "black"} style={{ opacity: "50%" }} size="sm" />
                 </div>
                 <div className="mainView-innerContainer" style={{ width: `calc(100% - ${width}px)`, transform: transform }}>
                     <CollectionMenu panelWidth={this.topMenuWidth} panelHeight={this.topMenuHeight} />
@@ -441,7 +441,7 @@ export class MainView extends React.Component {
                     {this.dockingContent}
 
                     <div className="mainView-propertiesDragger" key="props" onPointerDown={this.onPropertiesPointerDown} style={{ right: this._leftMenuFlyoutWidth ? 0 : this.propertiesWidth() - 1 }}>
-                        <FontAwesomeIcon icon={this.propertiesWidth() < 10 ? "chevron-left" : "chevron-right"} color={this.darkScheme ? Colors.WHITE : Colors.BLACK} size="sm" />
+                        <FontAwesomeIcon icon={this.propertiesWidth() < 10 ? "chevron-left" : "chevron-right"} color={this.colorScheme === ColorScheme.Dark ? Colors.WHITE : Colors.BLACK} size="sm" />
                     </div>
                     <div className="properties-container">
                         {this.propertiesWidth() < 10 ? (null) : <PropertiesView styleProvider={DefaultStyleProvider} width={this.propertiesWidth()} height={this.propertiesHeight()} />}
@@ -459,7 +459,7 @@ export class MainView extends React.Component {
                     this._dashUIHeight = r.getBoundingClientRect().height;
                 })).observe(r);
             }} style={{
-                color: this.darkScheme ? "rgb(205,205,205)" : "black",
+                color: this.colorScheme === ColorScheme.Dark ? "rgb(205,205,205)" : "black",
                 height: `calc(100% - ${this.topOfDashUI}px)`,
                 width: "100%",
             }} >
@@ -601,7 +601,7 @@ export class MainView extends React.Component {
     }
 
     render() {
-        return (<div className={"mainView-container" + (this.darkScheme ? "-dark" : "")}
+        return (<div className={`mainView-container${this.colorScheme}`}
             onScroll={() => ((ele) => ele.scrollTop = ele.scrollLeft = 0)(document.getElementById("root")!)}
             ref={r => {
                 r && new _global.ResizeObserver(action(() => { this._windowWidth = r.getBoundingClientRect().width; this._windowHeight = r.getBoundingClientRect().height; })).observe(r);
-- 
cgit v1.2.3-70-g09d2


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.

---
 src/client/documents/Documents.ts                  |   3 +-
 src/client/util/CurrentUserUtils.ts                |   3 +-
 src/client/views/MainView.tsx                      |   1 -
 .../collectionLinear/CollectionLinearView.tsx      |   1 -
 src/client/views/nodes/button/FontIconBox.tsx      | 126 +++++---------
 .../views/nodes/formattedText/FormattedTextBox.tsx |  11 +-
 .../views/nodes/formattedText/RichTextMenu.tsx     | 186 +++++++++++----------
 src/client/views/nodes/formattedText/marks_rts.ts  |   6 +-
 8 files changed, 153 insertions(+), 184 deletions(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 206f65bfd..8ac647b99 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -141,8 +141,8 @@ export class DocumentOptions {
     _columnWidth?: number;
     _columnsHideIfEmpty?: boolean; // whether stacking view column headings should be hidden
     _fontSize?: string;
-    _fontWeight?: number;
     _fontFamily?: string;
+    _fontWeight?: string;
     _pivotField?: string; // field key used to determine headings for sections in stacking, masonry, pivot views
     _curPage?: number; // current page of a PDF or other? paginated document
     _currentTimecode?: number; // the current timecode of a time-based document (e.g., current time of a video)  value is in seconds
@@ -1188,7 +1188,6 @@ export namespace DocUtils {
                 description: ":" + StrCast(note.title),
                 event: undoBatch((args: { x: number, y: number }) => {
                     const textDoc = Docs.Create.TextDocument("", {
-                        _fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize),
                         _width: 200, x, y, _autoHeight: note._autoHeight !== false,
                         title: StrCast(note.title) + "#" + (note.aliasCount = NumCast(note.aliasCount) + 1)
                     });
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 5683a8c21..297d4b241 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -1535,8 +1535,7 @@ export class CurrentUserUtils {
     public static GetNewTextDoc(title: string, x: number, y: number, width?: number, height?: number, noMargins?: boolean, annotationOn?: Doc, maxHeight?: number, backgroundColor?: string) {
         const tbox = Docs.Create.TextDocument("", {
             _xMargin: noMargins ? 0 : undefined, _yMargin: noMargins ? 0 : undefined, annotationOn, docMaxAutoHeight: maxHeight, backgroundColor: backgroundColor,
-            _width: width || 200, _height: height || 100, x: x, y: y, _fitWidth: true, _autoHeight: true, _fontSize: StrCast(Doc.UserDoc().fontSize),
-            _fontFamily: StrCast(Doc.UserDoc().fontFamily), title
+            _width: width || 200, _height: height || 100, x: x, y: y, _fitWidth: true, _autoHeight: true, title
         });
         const template = Doc.UserDoc().defaultTextLayout;
         if (template instanceof Doc) {
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index c99ba447c..fbd3fece2 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -471,7 +471,6 @@ export class MainView extends React.Component {
         this._leftMenuFlyoutWidth = (this._leftMenuFlyoutWidth || 250);
         this._sidebarContent.proto = button.target as any;
         this.LastButton = button;
-        console.log(button.title);
     });
 
     closeFlyout = action(() => {
diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
index 7fe95fef0..18a715edf 100644
--- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
+++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
@@ -109,7 +109,6 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
     }
 
     myContextMenu = (e: React.MouseEvent) => {
-        console.log("STOPPING");
         e.stopPropagation();
         e.preventDefault();
     }
diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx
index 520034c3c..6a782b105 100644
--- a/src/client/views/nodes/button/FontIconBox.tsx
+++ b/src/client/views/nodes/button/FontIconBox.tsx
@@ -113,7 +113,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
 
         // Script for checking the outcome of the toggle
         const checkScript: string = StrCast(this.rootDoc.script) + "(0, true)";
-        const checkResult: number = ScriptField.MakeScript(checkScript)?.script.run().result;
+        const checkResult: number = ScriptField.MakeScript(checkScript)?.script.run().result || 0;
 
 
         if (numBtnType === NumButtonType.Slider) {
@@ -158,7 +158,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
                 <div
                     className={`menuButton ${this.type} ${numBtnType}`}
                 >
-                    <div className={`button`} onClick={action((e) => setValue(checkResult - 1))}>
+                    <div className={`button`} onClick={action((e) => setValue(Number(checkResult) - 1))}>
                         <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={"minus"} />
                     </div>
                     <div
@@ -177,7 +177,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
                             onChange={action((e) => setValue(Number(e.target.value)))}
                         />
                     </div>
-                    <div className={`button`} onClick={action((e) => setValue(checkResult + 1))}>
+                    <div className={`button`} onClick={action((e) => setValue(Number(checkResult) + 1))}>
                         <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={"plus"} />
                     </div>
 
@@ -261,8 +261,8 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
             }
             noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Stacking];
         } else if (script === 'setFont') {
-            const selected = SelectionManager.Docs().lastElement();
-            text = StrCast((selected?.type === DocumentType.RTF ? selected : Doc.UserDoc())._fontFamily);
+            const editorView = RichTextMenu.Instance?.TextView?.EditorView;
+            text = StrCast((editorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily);
             noviceList = ["Roboto", "Times New Roman", "Arial", "Georgia",
                 "Comic Sans MS", "Tahoma", "Impact", "Crimson Text"];
         }
@@ -337,7 +337,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
         const colorBox = (func: (color: ColorState) => void) => <SketchPicker
             disableAlpha={false}
             onChange={func}
-            color={boolResult ? boolResult : "#FFFFFF"}
+            color={boolResult ?? "transparent"}
             presetColors={colorOptions} />;
         const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
             <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor, position: "absolute" }}>
@@ -360,7 +360,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
                 onClick={() => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen}
                 onPointerDown={e => e.stopPropagation()}>
                 <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
-                <div className="colorButton-color" style={{ backgroundColor: boolResult ? boolResult : "#FFFFFF" }} />
+                <div className="colorButton-color" style={{ backgroundColor: boolResult ?? "transparent" }} />
                 {label}
                 {/* {dropdownCaret} */}
                 {this.rootDoc.dropDownOpen ?
@@ -387,7 +387,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
 
         // Button label
         const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
-            <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor, position: "absolute" }}>
+            <div className="fontIconBox-label" style={{ color, backgroundColor, position: "absolute" }}>
                 {this.label}
             </div>;
 
@@ -406,7 +406,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
         } else {
             return (
                 <div className={`menuButton ${this.type}`}
-                    style={{ opacity: 1, backgroundColor: backgroundColor, color: color }}>
+                    style={{ opacity: 1, backgroundColor, color }}>
                     <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
                     {label}
                 </div>
@@ -571,11 +571,7 @@ Scripting.addGlobal(function setView(view: string) {
 Scripting.addGlobal(function setBackgroundColor(color?: string, checkResult?: boolean) {
     const selected = SelectionManager.Docs().lastElement();
     if (checkResult) {
-        if (selected) {
-            return selected._backgroundColor;
-        } else {
-            return "#FFFFFF";
-        }
+        return selected?._backgroundColor ?? "transparent";
     }
     if (selected) selected._backgroundColor = color;
     Doc.UserDoc()._fontColor = color;
@@ -596,7 +592,7 @@ Scripting.addGlobal(function toggleOverlay(checkResult?: boolean) {
     const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined;
     if (checkResult && selected) {
         if (NumCast(selected.Document.z) >= 1) return Colors.MEDIUM_BLUE;
-        else return "transparent";
+        return "transparent";
     }
     selected ? selected.props.CollectionFreeFormDocumentView?.().float() : console.log("[FontIconBox.tsx] toggleOverlay failed");
 });
@@ -617,16 +613,18 @@ Scripting.addGlobal(function toggleOverlay(checkResult?: boolean) {
 Scripting.addGlobal(function setFont(font: string, checkResult?: boolean) {
     SelectionManager.Docs().map(doc => doc._fontFamily = font);
     const editorView = RichTextMenu.Instance.TextView?.EditorView;
-    editorView?.state && RichTextMenu.Instance.setFontFamily(font, editorView);
-    Doc.UserDoc()._fontFamily = font;
-    return Doc.UserDoc()._fontFamily;
+    if (checkResult) {
+        return StrCast((editorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily);
+    }
+    if (editorView) RichTextMenu.Instance.setFontFamily(font);
+    else Doc.UserDoc().fontFamily = font;
 });
 
 Scripting.addGlobal(function getActiveTextInfo(info: "family" | "size" | "color" | "highlight") {
     const editorView = RichTextMenu.Instance.TextView?.EditorView;
     const style = editorView?.state && RichTextMenu.Instance.getActiveFontStylesOnSelection();
     switch (info) {
-        case "family": return style?.activeColors[0];
+        case "family": return style?.activeFamilies[0];
         case "size": return style?.activeSizes[0];
         case "color": return style?.activeColors[0];
         case "highlight": return style?.activeHighlights[0];
@@ -643,7 +641,7 @@ Scripting.addGlobal(function setAlignment(align: "left" | "right" | "center", ch
             active = StrCast(Doc.UserDoc().textAlign);
         }
         if (active === align) return Colors.MEDIUM_BLUE;
-        else return "transparent";
+        return "transparent";
     }
     SelectionManager.Docs().map(doc => doc.textAlign = align);
     switch (align) {
@@ -667,38 +665,25 @@ Scripting.addGlobal(function setBulletList(mapStyle: "bullet" | "decimal", check
     if (checkResult) {
         const active = editorView?.state && RichTextMenu.Instance.getActiveListStyle();
         if (active === mapStyle) return Colors.MEDIUM_BLUE;
-        else return "transparent";
+        return "transparent";
     }
     if (editorView) {
         const active = editorView?.state && RichTextMenu.Instance.getActiveListStyle();
-        if (active === mapStyle) {
-            editorView?.state && RichTextMenu.Instance.changeListType(editorView.state.schema.nodes.ordered_list.create({ mapStyle: "" }));
-        } else {
-            editorView?.state && RichTextMenu.Instance.changeListType(editorView.state.schema.nodes.ordered_list.create({ mapStyle: mapStyle }));
-        }
+        editorView?.state && RichTextMenu.Instance.changeListType(
+            editorView.state.schema.nodes.ordered_list.create({ mapStyle: active === mapStyle ? "" : mapStyle }));
     }
 });
 
 // toggle: Set overlay status of selected document
 Scripting.addGlobal(function setFontColor(color?: string, checkResult?: boolean) {
-    const selected = SelectionManager.Docs().lastElement();
     const editorView = RichTextMenu.Instance.TextView?.EditorView;
 
     if (checkResult) {
-        if (selected) {
-            return selected._fontColor;
-        } else {
-            return Doc.UserDoc()._fontColor;
-        }
+        return editorView ? RichTextMenu.Instance.fontColor : Doc.UserDoc().fontColor;
     }
 
-    if (selected) {
-        selected._fontColor = color;
-        if (color) {
-            editorView?.state && RichTextMenu.Instance.setColor(color, editorView, editorView?.dispatch);
-        }
-    }
-    Doc.UserDoc()._fontColor = color;
+    if (editorView) color && RichTextMenu.Instance.setColor(color, editorView, editorView?.dispatch);
+    else Doc.UserDoc()._fontColor = color;
 });
 
 // toggle: Set overlay status of selected document
@@ -707,11 +692,7 @@ Scripting.addGlobal(function setFontHighlight(color?: string, checkResult?: bool
     const editorView = RichTextMenu.Instance.TextView?.EditorView;
 
     if (checkResult) {
-        if (selected) {
-            return selected._fontHighlight;
-        } else {
-            return Doc.UserDoc()._fontHighlight;
-        }
+        return (selected ?? Doc.UserDoc())._fontHighlight;
     }
     if (selected) {
         selected._fontColor = color;
@@ -722,62 +703,43 @@ Scripting.addGlobal(function setFontHighlight(color?: string, checkResult?: bool
     Doc.UserDoc()._fontHighlight = color;
 });
 
-
-
 // toggle: Set overlay status of selected document
-Scripting.addGlobal(function setFontSize(size: string, checkResult?: boolean) {
+Scripting.addGlobal(function setFontSize(size: string | number, checkResult?: boolean) {
+    if (typeof size === "number") size = size.toString();
+    if (size && Number(size).toString() === size) size += "px";
+    const editorView = RichTextMenu.Instance.TextView?.EditorView;
     if (checkResult) {
-        const size: number = parseInt(StrCast(Doc.UserDoc()._fontSize), 10);
-        return size;
+        return (editorView ? RichTextMenu.Instance.fontSize : StrCast(Doc.UserDoc().fontSize, "10px")).replace("px", "");
     }
-    const editorView = RichTextMenu.Instance.TextView?.EditorView;
-    editorView?.state && RichTextMenu.Instance.setFontSize(Number(size), editorView);
-    Doc.UserDoc()._fontSize = size + "px";
+    if (editorView) RichTextMenu.Instance.setFontSize(size);
+    else Doc.UserDoc()._fontSize = size;
 });
 
 Scripting.addGlobal(function toggleBold(checkResult?: boolean) {
+    const editorView = RichTextMenu.Instance?.TextView?.EditorView;
     if (checkResult) {
-        const editorView = RichTextMenu.Instance.TextView?.EditorView;
-        if (editorView) {
-            const bold: boolean = editorView?.state && RichTextMenu.Instance.getBoldStatus();
-            if (bold) return Colors.MEDIUM_BLUE;
-            else return "transparent";
-        }
-        else return "transparent";
+        return (editorView ? RichTextMenu.Instance.bold : Doc.UserDoc().fontWeight === "bold") ? Colors.MEDIUM_BLUE : "transparent";
     }
-    const editorView = RichTextMenu.Instance.TextView?.EditorView;
-    if (editorView) {
-        editorView?.state && RichTextMenu.Instance.toggleBold(editorView, true);
-    }
-    SelectionManager.Docs().filter(doc => StrCast(doc.type) === DocumentType.RTF).map(doc => doc.bold = !doc.bold);
-    Doc.UserDoc().bold = !Doc.UserDoc().bold;
-    return Doc.UserDoc().bold;
+    if (editorView) RichTextMenu.Instance?.toggleBold();
+    else Doc.UserDoc().fontWeight = Doc.UserDoc().fontWeight === "bold" ? undefined : "bold";
 });
 
 Scripting.addGlobal(function toggleUnderline(checkResult?: boolean) {
+    const editorView = RichTextMenu.Instance?.TextView?.EditorView;
     if (checkResult) {
-        return "transparent";
-    }
-    const editorView = RichTextMenu.Instance.TextView?.EditorView;
-    if (editorView) {
-        editorView?.state && RichTextMenu.Instance.toggleUnderline(editorView, true);
+        return (editorView ? RichTextMenu.Instance.underline : Doc.UserDoc().textDecoration === "underline") ? Colors.MEDIUM_BLUE : "transparent";
     }
-    SelectionManager.Docs().filter(doc => StrCast(doc.type) === DocumentType.RTF).map(doc => doc.underline = !doc.underline);
-    Doc.UserDoc().underline = !Doc.UserDoc().underline;
-    return Doc.UserDoc().underline;
+    if (editorView) RichTextMenu.Instance?.toggleUnderline();
+    else Doc.UserDoc().textDecoration = Doc.UserDoc().textDecoration === "underline" ? undefined : "underline";
 });
 
 Scripting.addGlobal(function toggleItalic(checkResult?: boolean) {
+    const editorView = RichTextMenu.Instance?.TextView?.EditorView;
     if (checkResult) {
-        return "transparent";
-    }
-    const editorView = RichTextMenu.Instance.TextView?.EditorView;
-    if (editorView) {
-        editorView?.state && RichTextMenu.Instance.toggleItalic(editorView, true);
+        return (editorView ? RichTextMenu.Instance.italics : Doc.UserDoc().fontStyle === "italics") ? Colors.MEDIUM_BLUE : "transparent";
     }
-    SelectionManager.Docs().filter(doc => StrCast(doc.type) === DocumentType.RTF).map(doc => doc.italic = !doc.italic);
-    Doc.UserDoc().italic = !Doc.UserDoc().italic;
-    return Doc.UserDoc().italic;
+    if (editorView) RichTextMenu.Instance?.toggleItalics();
+    else Doc.UserDoc().fontStyle = Doc.UserDoc().fontStyle === "italics" ? undefined : "italics";
 });
 
 
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 617fa0bee..16aa4de6c 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1168,7 +1168,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         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.
         if (this._editorView && !this._editorView.state.storedMarks?.some(mark => mark.type === schema.marks.user_mark)) {
-            this._editorView.state.storedMarks = [...(this._editorView.state.storedMarks ?? []), schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) })];
+            this._editorView.state.storedMarks = [...(this._editorView.state.storedMarks ?? []),
+            schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) }),
+            ...(Doc.UserDoc().fontColor !== "transparent" && Doc.UserDoc().fontColor ? [schema.mark(schema.marks.pFontColor, { color: StrCast(Doc.UserDoc().fontColor) })] : []),
+            ...(Doc.UserDoc().fontStyle === "italics" ? [schema.mark(schema.marks.em)] : []),
+            ...(Doc.UserDoc().textDecoration === "underline" ? [schema.mark(schema.marks.underline)] : []),
+            ...(Doc.UserDoc().fontFamily ? [schema.mark(schema.marks.pFontFamily, { family: StrCast(Doc.UserDoc().fontFamily) })] : []),
+            ...(Doc.UserDoc().fontSize ? [schema.mark(schema.marks.pFontSize, { fontSize: StrCast(Doc.UserDoc().fontSize, "") })] : []),
+            ...(Doc.UserDoc().fontWeight === "bold" ? [schema.mark(schema.marks.strong)] : [])];
         }
     }
 
@@ -1596,7 +1603,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                         background: this.props.background ? this.props.background : this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor),
                         color: this.props.color ? this.props.color : this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Color),
                         fontSize: this.props.fontSize ? this.props.fontSize : this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.FontSize),
-                        fontWeight: Cast(this.layoutDoc._fontWeight, "number", null),
+                        fontWeight: Cast(this.layoutDoc._fontWeight, "string", null) as any,
                         fontFamily: StrCast(this.layoutDoc._fontFamily, "inherit"),
                         pointerEvents: interactive ? undefined : "none",
                     }}
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;
diff --git a/src/client/views/nodes/formattedText/marks_rts.ts b/src/client/views/nodes/formattedText/marks_rts.ts
index 655ee7e44..6103a28d6 100644
--- a/src/client/views/nodes/formattedText/marks_rts.ts
+++ b/src/client/views/nodes/formattedText/marks_rts.ts
@@ -61,13 +61,13 @@ export const marks: { [index: string]: MarkSpec } = {
 
     /** FONT SIZES */
     pFontSize: {
-        attrs: { fontSize: { default: 10 } },
+        attrs: { fontSize: { default: "10px" } },
         parseDOM: [{
             tag: "span", getAttrs(dom: any) {
-                return { fontSize: dom.style.fontSize ? Number(dom.style.fontSize.replace("px", "")) : "" };
+                return { fontSize: dom.style.fontSize ? dom.style.fontSize.toString() : "" };
             }
         }],
-        toDOM: (node) => node.attrs.fontSize ? ['span', { style: `font-size: ${node.attrs.fontSize}px;` }] : ['span', 0]
+        toDOM: (node) => node.attrs.fontSize ? ['span', { style: `font-size: ${node.attrs.fontSize};` }] : ['span', 0]
     },
 
     /* FONTS */
-- 
cgit v1.2.3-70-g09d2


From 13ec8c89d7fb809a9ceefa3c25e332b0f4457593 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 22 Sep 2021 11:28:46 -0400
Subject: fixed dropdowns to be over documentdecorations by moving top menu bar
 out of maincontent area and giving it a higher z-index than DocDecorations. 
 fixed toggle behavior of shape drawing modes.  made color dropdown state be
 runtime only (doesn't write to data model) -- need to decide if that's what
 we want.

---
 src/client/views/MainView.tsx                 | 14 +++---
 src/client/views/nodes/button/FontIconBox.tsx | 68 +++++++++++++--------------
 2 files changed, 42 insertions(+), 40 deletions(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index fbd3fece2..35c5801e5 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -12,7 +12,7 @@ import { Doc, DocListCast, Opt } from '../../fields/Doc';
 import { List } from '../../fields/List';
 import { PrefetchProxy } from '../../fields/Proxy';
 import { ScriptField } from '../../fields/ScriptField';
-import { BoolCast, PromiseValue, StrCast } from '../../fields/Types';
+import { PromiseValue, StrCast } from '../../fields/Types';
 import { TraceMobx } from '../../fields/util';
 import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, returnZero, setupMoveUpEvents, simulateMouseClick, Utils } from '../../Utils';
 import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager';
@@ -26,7 +26,7 @@ import { HistoryUtil } from '../util/History';
 import { Hypothesis } from '../util/HypothesisUtils';
 import { Scripting } from '../util/Scripting';
 import { SelectionManager } from '../util/SelectionManager';
-import { SettingsManager, ColorScheme } from '../util/SettingsManager';
+import { ColorScheme, SettingsManager } from '../util/SettingsManager';
 import { SharingManager } from '../util/SharingManager';
 import { SnappingManager } from '../util/SnappingManager';
 import { Transform } from '../util/Transform';
@@ -101,7 +101,7 @@ export class MainView extends React.Component {
     propertiesWidth = () => Math.max(0, Math.min(this._dashUIWidth - 50, CurrentUserUtils.propertiesWidth || 0));
     propertiesHeight = () => this._dashUIHeight;
     mainDocViewWidth = () => this._dashUIWidth - this.propertiesWidth() - this.leftMenuWidth();
-    mainDocViewHeight = () => this._dashUIHeight - this.topMenuHeight();
+    mainDocViewHeight = () => this._dashUIHeight;
 
     componentDidMount() {
         document.getElementById("root")?.addEventListener("scroll", e => ((ele) => ele.scrollLeft = ele.scrollTop = 0)(document.getElementById("root")!));
@@ -436,7 +436,6 @@ export class MainView extends React.Component {
                     <FontAwesomeIcon icon="chevron-left" color={this.colorScheme === ColorScheme.Dark ? "white" : "black"} style={{ opacity: "50%" }} size="sm" />
                 </div>
                 <div className="mainView-innerContainer" style={{ width: `calc(100% - ${width}px)`, transform: transform }}>
-                    <CollectionMenu panelWidth={this.topMenuWidth} panelHeight={this.topMenuHeight} />
 
                     {this.dockingContent}
 
@@ -460,7 +459,7 @@ export class MainView extends React.Component {
                 })).observe(r);
             }} style={{
                 color: this.colorScheme === ColorScheme.Dark ? "rgb(205,205,205)" : "black",
-                height: `calc(100% - ${this.topOfDashUI}px)`,
+                height: `calc(100% - ${this.topOfDashUI + this.topMenuHeight()}px)`,
                 width: "100%",
             }} >
                 {this.mainInnerContent}
@@ -613,11 +612,14 @@ export class MainView extends React.Component {
             <GroupManager />
             <GoogleAuthenticationManager />
             <DocumentDecorations boundsLeft={this.leftScreenOffsetOfMainDocView} boundsTop={this.topOfMainDoc} PanelWidth={this._windowWidth} PanelHeight={this._windowHeight} />
-            <ComponentDecorations boundsLeft={this.leftScreenOffsetOfMainDocView} boundsTop={this.topOfMainDocContent} />
+            <ComponentDecorations boundsLeft={0} boundsTop={this.topOfMainDocContent} />
             {this.topbar}
             {LinkDescriptionPopup.descriptionPopup ? <LinkDescriptionPopup /> : null}
             {DocumentLinksButton.LinkEditorDocView ? <LinkMenu docView={DocumentLinksButton.LinkEditorDocView} changeFlyout={emptyFunction} /> : (null)}
             {LinkDocPreview.LinkInfo ? <LinkDocPreview {...LinkDocPreview.LinkInfo} /> : (null)}
+            <div style={{ position: "relative", display: LightboxView.LightboxDoc ? "none" : undefined, zIndex: 2001 }} >
+                <CollectionMenu panelWidth={this.topMenuWidth} panelHeight={this.topMenuHeight} />
+            </div>
             <GestureOverlay >
                 {this.mainDashboardArea}
             </GestureOverlay>
diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx
index 368699dea..511df8786 100644
--- a/src/client/views/nodes/button/FontIconBox.tsx
+++ b/src/client/views/nodes/button/FontIconBox.tsx
@@ -5,7 +5,7 @@ import { action, computed, observable } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { ColorState, SketchPicker } from 'react-color';
-import { Doc, StrListCast } from '../../../../fields/Doc';
+import { Doc, StrListCast, WidthSym, HeightSym } from '../../../../fields/Doc';
 import { InkTool } from '../../../../fields/InkField';
 import { createSchema, makeInterface } from '../../../../fields/Schema';
 import { ScriptField } from '../../../../fields/ScriptField';
@@ -318,35 +318,35 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
         );
     }
 
+    @observable colorPickerClosed: boolean = true;
     @computed get colorScript() {
         const script = StrCast(this.rootDoc.script);
         return ScriptField.MakeScript(script + '(colValue, checkResult)', { colValue: "string", checkResult: "boolean" });
     }
-    colorPicker = (boolResult: string) => {
-        const click = (value: ColorState) => {
+
+    colorPicker = (curColor: string) => {
+        const change = (value: ColorState) => {
             const s = this.colorScript;
             s && undoBatch(() => s.script.run({ colValue: Utils.colorString(value), checkResult: false }).result)();
         };
-        const colorOptions: string[] = ['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505',
+        const presets = ['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505',
             '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B',
             '#FFFFFF', '#f1efeb', "transparent"];
         return <SketchPicker
-            disableAlpha={false}
-            onChange={click}
-            color={boolResult}
-            presetColors={colorOptions} />;
+            onChange={change}
+            color={curColor}
+            presetColors={presets} />
     }
     /**
      * Color button
      */
     @computed get colorButton() {
-        const active = StrCast(this.rootDoc.dropDownOpen);
         const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
         const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
-        const boolResult = this.colorScript?.script.run({ colValue: undefined, checkResult: true }).result;
+        const curColor = this.colorScript?.script.run({ colValue: undefined, checkResult: true }).result ?? "transparent";
 
         const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
-            <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor, position: "absolute" }}>
+            <div className="fontIconBox-label" style={{ color, backgroundColor, position: "absolute" }}>
                 {this.label}
             </div>;
 
@@ -355,26 +355,27 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
             style={{ borderBottomRightRadius: this.dropdown ? 0 : undefined }}>
             <FontAwesomeIcon icon={'caret-down'} color={color} size="sm" />
         </div>;
-
+        setTimeout(() => this.colorPicker(curColor)); // cause an update to the color picker rendered in MainView
         return (
-            <div className={`menuButton ${this.type} ${active}`}
+            <div className={`menuButton ${this.type} ${this.colorPickerClosed}`}
                 style={{ color: color, borderBottomLeftRadius: this.dropdown ? 0 : undefined }}
-                onClick={() => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen}
+                onClick={action(() => this.colorPickerClosed = !this.colorPickerClosed)}
                 onPointerDown={e => e.stopPropagation()}>
                 <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
-                <div className="colorButton-color" style={{ backgroundColor: boolResult ?? "transparent" }} />
+                <div className="colorButton-color" style={{ backgroundColor: curColor }} />
                 {label}
                 {/* {dropdownCaret} */}
-                {this.rootDoc.dropDownOpen ?
+                {this.colorPickerClosed ? (null) :
                     <div>
                         <div className="menuButton-dropdownBox"
                             onPointerDown={e => e.stopPropagation()}
                             onClick={e => e.stopPropagation()}>
-                            {this.colorPicker(boolResult ?? "transparent")}
+                            {this.colorPicker(curColor)}
                         </div>
-                        <div className="dropbox-background" onClick={(e) => { e.stopPropagation(); this.rootDoc.dropDownOpen = false; }} />
-                    </div>
-                    : null}
+                        <div className="dropbox-background" onClick={action((e) => {
+                            e.stopPropagation(); this.colorPickerClosed = true;
+                        })} />
+                    </div>}
             </div>
         );
     }
@@ -754,24 +755,23 @@ Scripting.addGlobal(function toggleItalic(checkResult?: boolean) {
 
 Scripting.addGlobal(function setActiveInkTool(tool: string, checkResult?: boolean) {
     if (checkResult) {
-        if (Doc.UserDoc().activeInkTool === tool && GestureOverlay.Instance.InkShape === "" || GestureOverlay.Instance.InkShape === tool) return Colors.MEDIUM_BLUE;
-        else return "transparent";
+        return (Doc.UserDoc().activeInkTool === tool && GestureOverlay.Instance?.InkShape === "" || GestureOverlay.Instance?.InkShape === tool) ?
+            Colors.MEDIUM_BLUE : "transparent";
     }
-    if (tool === "circle") {
-        Doc.UserDoc().activeInkTool = "pen";
-        GestureOverlay.Instance.InkShape = tool;
-    } else if (tool === "square") {
-        Doc.UserDoc().activeInkTool = "pen";
-        GestureOverlay.Instance.InkShape = tool;
-    } else if (tool === "line") {
-        Doc.UserDoc().activeInkTool = "pen";
-        GestureOverlay.Instance.InkShape = tool;
-    } else if (tool) {
-        if (Doc.UserDoc().activeInkTool === tool && GestureOverlay.Instance.InkShape === "" || GestureOverlay.Instance.InkShape === tool) {
-            GestureOverlay.Instance.InkShape = "";
+    if (["circle", "square", "line"].includes(tool)) {
+        if (GestureOverlay.Instance.InkShape === tool) {
+            Doc.UserDoc().activeInkTool = InkTool.None;
+            GestureOverlay.Instance.InkShape = InkTool.None;
+        } else {
+            Doc.UserDoc().activeInkTool = InkTool.Pen;
+            GestureOverlay.Instance.InkShape = tool;
+        }
+    } else if (tool) { // pen
+        if (Doc.UserDoc().activeInkTool === tool && !GestureOverlay.Instance.InkShape) {
             Doc.UserDoc().activeInkTool = InkTool.None;
         } else {
             Doc.UserDoc().activeInkTool = tool;
+            GestureOverlay.Instance.InkShape = "";
         }
     } else {
         Doc.UserDoc().activeInkTool = InkTool.None;
-- 
cgit v1.2.3-70-g09d2

