From 956628a22c2d8ae21eb76c70f8f0a5a4edc9ae75 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 10 Feb 2022 17:12:19 -0500
Subject: switched scripts to use a cache to avoid recompiling. simplified some
 things with documentView and zooming to avoid invalidations.

---
 src/client/views/nodes/button/FontIconBox.tsx | 139 +++++++++++---------------
 1 file changed, 56 insertions(+), 83 deletions(-)

(limited to 'src/client/views/nodes/button/FontIconBox.tsx')

diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx
index bd103dcf7..91365121f 100644
--- a/src/client/views/nodes/button/FontIconBox.tsx
+++ b/src/client/views/nodes/button/FontIconBox.tsx
@@ -1,7 +1,7 @@
 import { IconProp } from '@fortawesome/fontawesome-svg-core';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Tooltip } from '@material-ui/core';
-import { action, computed, observable } from 'mobx';
+import { action, computed, observable, trace } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { ColorState, SketchPicker } from 'react-color';
@@ -9,7 +9,7 @@ import { Doc, StrListCast, WidthSym, HeightSym } from '../../../../fields/Doc';
 import { InkTool } from '../../../../fields/InkField';
 import { createSchema, makeInterface } from '../../../../fields/Schema';
 import { ScriptField } from '../../../../fields/ScriptField';
-import { BoolCast, Cast, NumCast, StrCast } from '../../../../fields/Types';
+import { BoolCast, Cast, NumCast, StrCast, ScriptCast } from '../../../../fields/Types';
 import { WebField } from '../../../../fields/URLField';
 import { DocumentType } from '../../../documents/DocumentTypes';
 import { Scripting } from "../../../util/Scripting";
@@ -105,16 +105,11 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
      */
     @computed get numberButton() {
         const numBtnType: string = StrCast(this.rootDoc.numBtnType);
-        const setValue = (value: number) => {
-            // Script for running the toggle
-            const script: string = StrCast(this.rootDoc.script) + "(" + value + ")";
-            ScriptField.MakeScript(script)?.script.run();
-        };
+        const numScript = ScriptCast(this.rootDoc.script);
+        const setValue = (value: number) => numScript?.script.run({ value, _readOnly_: false });
 
         // 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 || 0;
-
+        const checkResult: number = numScript?.script.run({ value: 0, _readOnly_: true }).result || 0;
 
         if (numBtnType === NumButtonType.Slider) {
             const dropdown =
@@ -237,34 +232,37 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
         const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
         const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
 
-        const script: string = StrCast(this.rootDoc.script);
+        const script = ScriptCast(this.rootDoc.script);
 
         let noviceList: string[] = [];
         let text: string | undefined;
         let dropdown = true;
         let icon: IconProp = "caret-down";
-
-        if (script === 'setView') {
-            const selected = SelectionManager.Docs().lastElement();
-            if (selected) {
-                if (StrCast(selected.type) === DocumentType.COL) {
-                    text = StrCast(selected._viewType);
+        try {
+            if (script.script.originalScript.startsWith('setView')) {
+                const selected = SelectionManager.Docs().lastElement();
+                if (selected) {
+                    if (StrCast(selected.type) === DocumentType.COL) {
+                        text = StrCast(selected._viewType);
+                    } else {
+                        dropdown = false;
+                        text = selected.type === DocumentType.RTF ? "Text" : StrCast(selected.type);
+                        icon = Doc.toIcon(selected);
+                    }
                 } else {
                     dropdown = false;
-                    text = selected.type === DocumentType.RTF ? "Text" : StrCast(selected.type);
-                    icon = Doc.toIcon(selected);
+                    icon = "globe-asia";
+                    text = "User Default";
                 }
-            } else {
-                dropdown = false;
-                icon = "globe-asia";
-                text = "User Default";
+                noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Stacking];
+            } else if (script.script.originalScript.startsWith('setFont')) {
+                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"];
             }
-            noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Stacking];
-        } else if (script === 'setFont') {
-            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"];
+        } catch (e) {
+            console.log(e);
         }
 
         // Get items to place into the list
@@ -272,18 +270,12 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
             if (Doc.UserDoc().noviceMode && !noviceList.includes(value)) {
                 return;
             }
-            const click = () => {
-                const s = ScriptField.MakeScript(script + '("' + value + '")');
-                if (s) {
-                    s.script.run().result;
-                }
-            };
             return <div className="list-item" key={`${value}`}
                 style={{
-                    fontFamily: script === 'setFont' ? value : undefined,
+                    fontFamily: script.script.originalScript.startsWith('setFont') ? value : undefined,
                     backgroundColor: value === text ? Colors.LIGHT_BLUE : undefined
                 }}
-                onClick={click}>
+                onClick={() => script.script.run({ value }).result}>
                 {value[0].toUpperCase() + value.slice(1)}
             </div>;
         });
@@ -319,15 +311,12 @@ 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" });
-    }
+    @computed get colorScript() { return ScriptCast(this.rootDoc.script); }
 
     colorPicker = (curColor: string) => {
         const change = (value: ColorState) => {
             const s = this.colorScript;
-            s && undoBatch(() => s.script.run({ colValue: Utils.colorString(value), checkResult: false }).result)();
+            s && undoBatch(() => s.script.run({ value: Utils.colorString(value), _readOnly_: false }).result)();
         };
         const presets = ['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505',
             '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B',
@@ -343,7 +332,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
     @computed get colorButton() {
         const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
         const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
-        const curColor = this.colorScript?.script.run({ colValue: undefined, checkResult: true }).result ?? "transparent";
+        const curColor = this.colorScript?.script.run({ value: undefined, _readOnly_: true }).result ?? "transparent";
 
         const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
             <div className="fontIconBox-label" style={{ color, backgroundColor, position: "absolute" }}>
@@ -439,52 +428,34 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
 
     @computed get editableText() {
         // Script for running the toggle
-        const script: string = StrCast(this.rootDoc.script);
-
-        // Script for checking the outcome of the toggle
-        const checkScript: string = StrCast(this.rootDoc.script) + "('', true)";
-
+        const script = ScriptCast(this.rootDoc.script);
         // Function to run the script
-        const checkResult = ScriptField.MakeScript(checkScript)?.script.run().result;
+        const checkResult = script?.script.run({ value: "", _readOnly_: true }).result;
 
-        const setValue = (value: string, shiftDown?: boolean): boolean => {
-            ScriptField.MakeScript(script + "('" + value + "')")?.script.run();
-            return true;
-        };
+        const setValue = (value: string, shiftDown?: boolean): boolean => script?.script.run({ value, _readOnly_: false }).result;
         return (
             <div className="menuButton editableText">
                 <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={"lock"} />
                 <div style={{ width: "calc(100% - .875em)", paddingLeft: "4px" }}>
-                    <EditableView GetValue={() => checkResult} SetValue={setValue} contents={checkResult} />
+                    <EditableView GetValue={() => script?.script.run({ value: "", _readOnly_: true }).result} SetValue={setValue} contents={checkResult} />
                 </div>
             </div>
         );
     }
 
-
     render() {
         const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
         const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
-
         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>;
 
         const menuLabel = !this.label || !Doc.UserDoc()._showMenuLabel ? (null) :
-            <div className="fontIconBox-label" style={{ color: color, backgroundColor: "transparent" }}>
+            <div className="fontIconBox-label" style={{ color, backgroundColor: "transparent" }}>
                 {this.label}
             </div>;
 
-        const buttonProps: IButtonProps = {
-            type: this.type,
-            rootDoc: this.rootDoc,
-            label: label,
-            backgroundColor: backgroundColor,
-            icon: this.icon,
-            color: color
-        };
-
         const buttonText = StrCast(this.rootDoc.buttonText);
 
         // TODO:glr Add label of button type
@@ -493,7 +464,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
         switch (this.type) {
             case ButtonType.TextButton:
                 button = (
-                    <div className={`menuButton ${this.type}`} style={{ color: color, backgroundColor: backgroundColor, opacity: 1, gridAutoColumns: `${NumCast(this.rootDoc._height)} auto` }}>
+                    <div className={`menuButton ${this.type}`} style={{ color, backgroundColor, opacity: 1, gridAutoColumns: `${NumCast(this.rootDoc._height)} auto` }}>
                         <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
                         {buttonText ?
                             <div className="button-text">
@@ -522,7 +493,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
                 break;
             case ButtonType.ToolButton:
                 button = (
-                    <div className={`menuButton ${this.type}`} style={{ opacity: 1, backgroundColor: backgroundColor, color: color }}>
+                    <div className={`menuButton ${this.type}`} style={{ opacity: 1, backgroundColor, color }}>
                         <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
                         {label}
                     </div>
@@ -534,7 +505,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
                 break;
             case ButtonType.ClickButton:
                 button = (
-                    <div className={`menuButton ${this.type}`} style={{ color: color, backgroundColor: backgroundColor, opacity: 1 }}>
+                    <div className={`menuButton ${this.type}`} style={{ color, backgroundColor, opacity: 1 }}>
                         <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
                         {label}
                     </div>
@@ -544,7 +515,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
                 const trailsIcon = <img src={`/assets/${"presTrails.png"}`}
                     style={{ width: 30, height: 30, filter: `invert(${color === Colors.DARK_GRAY ? "0%" : "100%"})` }} />;
                 button = (
-                    <div className={`menuButton ${this.type}`} style={{ color: color, backgroundColor: backgroundColor }}>
+                    <div className={`menuButton ${this.type}`} style={{ color, backgroundColor }}>
                         {this.icon === "pres-trail" ? trailsIcon : <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />}
                         {menuLabel}
                         <FontIconBadge collection={Cast(this.rootDoc.watchedDocuments, Doc, null)} />
@@ -658,7 +629,7 @@ Scripting.addGlobal(function setBulletList(mapStyle: "bullet" | "decimal", check
 
 // toggle: Set overlay status of selected document
 Scripting.addGlobal(function setFontColor(color?: string, checkResult?: boolean) {
-    const editorView = RichTextMenu.Instance.TextView?.EditorView;
+    const editorView = RichTextMenu.Instance?.TextView?.EditorView;
 
     if (checkResult) {
         return editorView ? RichTextMenu.Instance.fontColor : Doc.UserDoc().fontColor;
@@ -687,12 +658,12 @@ Scripting.addGlobal(function setFontHighlight(color?: string, checkResult?: bool
 
 // toggle: Set overlay status of selected document
 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;
+    const editorView = RichTextMenu.Instance?.TextView?.EditorView;
     if (checkResult) {
         return (editorView ? RichTextMenu.Instance.fontSize : StrCast(Doc.UserDoc().fontSize, "10px")).replace("px", "");
     }
+    if (typeof size === "number") size = size.toString();
+    if (size && Number(size).toString() === size) size += "px";
     if (editorView) RichTextMenu.Instance.setFontSize(size);
     else Doc.UserDoc()._fontSize = size;
 });
@@ -810,17 +781,19 @@ Scripting.addGlobal(function webSetURL(url: string, checkResult?: boolean) {
         //selected.rootDoc.data = new WebField(url);
     }
 });
-Scripting.addGlobal(function webForward() {
-    const selected = SelectionManager.Views().lastElement();
-    if (selected?.rootDoc.type === DocumentType.WEB) {
-        (selected.ComponentView as WebBox).forward();
+Scripting.addGlobal(function webForward(checkResult?: boolean) {
+    const selected = (SelectionManager.Views().lastElement()?.ComponentView as WebBox);
+    if (checkResult) {
+        return selected?.forward(checkResult) ? undefined : "lightGray";
     }
+    selected?.forward();
 });
-Scripting.addGlobal(function webBack() {
-    const selected = SelectionManager.Views().lastElement();
-    if (selected?.rootDoc.type === DocumentType.WEB) {
-        (selected.ComponentView as WebBox).back();
+Scripting.addGlobal(function webBack(checkResult?: boolean) {
+    const selected = (SelectionManager.Views().lastElement()?.ComponentView as WebBox);
+    if (checkResult) {
+        return selected?.back(checkResult) ? undefined : "lightGray";
     }
+    selected?.back();
 });
 
 
-- 
cgit v1.2.3-70-g09d2

