Преглед на файлове

:art: https://github.com/siyuan-note/siyuan/issues/8621

Vanessa преди 2 години
родител
ревизия
b36c420063
променени са 4 файла, в които са добавени 210 реда и са изтрити 71 реда
  1. 1 0
      app/src/assets/scss/component/_menu.scss
  2. 9 8
      app/src/assets/scss/mobile.scss
  3. 185 52
      app/src/mobile/util/keyboardToolbar.ts
  4. 15 11
      app/src/protyle/toolbar/Font.ts

+ 1 - 0
app/src/assets/scss/component/_menu.scss

@@ -53,6 +53,7 @@
         box-shadow: none;
         border: 0;
         padding: 24px 0;
+        border-radius: 0;
 
         & > .b3-menu__item:first-child {
           border-top: .5px solid var(--b3-theme-background-light);

+ 9 - 8
app/src/assets/scss/mobile.scss

@@ -327,27 +327,28 @@
   &__slash {
     &-title {
       height: 24px;
+      padding: 0 8px;
+      line-height: 24px;
+      color: var(--b3-theme-on-surface);
     }
 
     &-block {
       display: flex;
-      padding: 0px 0 8px 8px;
+      padding-left: 8px;
+      flex-wrap: wrap;
     }
 
     &-item {
       background-color: var(--b3-theme-background);
       border-radius: var(--b3-border-radius);
-      flex: 1;
+      width: calc(50% - 8px);
       display: flex;
       align-items: center;
-      margin-right: 8px;
+      margin: 4px 8px 4px 0;
       position: relative;
       box-shadow: inset 0 0 0 .6px var(--b3-theme-on-surface);
-    }
-
-    &-empty {
-      flex: 1;
-      margin-right: 8px;
+      border: 0;
+      color: var(--b3-theme-on-background);
     }
 
     &-icon {

+ 185 - 52
app/src/mobile/util/keyboardToolbar.ts

@@ -9,6 +9,7 @@ import {moveToDown, moveToUp} from "../../protyle/wysiwyg/move";
 import {Constants} from "../../constants";
 import {focusByRange, getSelectionPosition} from "../../protyle/util/selection";
 import {getCurrentEditor} from "../editor";
+import {fontEvent, getFontNodeElements} from "../../protyle/toolbar/Font";
 
 let renderKeyboardToolbarTimeout: number;
 let showUtil = false;
@@ -26,6 +27,158 @@ const getSlashItem = (value: string, icon: string, text: string, focus = "false"
 </div>`;
 };
 
+const renderTextMenu = (protyle: IProtyle, toolbarElement: Element) => {
+    let colorHTML = "";
+    ["var(--b3-font-color1)", "var(--b3-font-color2)", "var(--b3-font-color3)", "var(--b3-font-color4)",
+        "var(--b3-font-color5)", "var(--b3-font-color6)", "var(--b3-font-color7)", "var(--b3-font-color8)",
+        "var(--b3-font-color9)", "var(--b3-font-color10)", "var(--b3-font-color11)", "var(--b3-font-color12)",
+        "var(--b3-font-color13)"].forEach((item, index) => {
+        colorHTML += `<button class="keyboard__slash-item" data-type="color">
+    <span class="keyboard__slash-icon" style="color:${item}">A</span>
+    <span class="keyboard__slash-text">${window.siyuan.languages.colorFont} ${index + 1}</span>
+</button>`;
+    });
+    let bgHTML = "";
+    ["var(--b3-font-background1)", "var(--b3-font-background2)", "var(--b3-font-background3)", "var(--b3-font-background4)",
+        "var(--b3-font-background5)", "var(--b3-font-background6)", "var(--b3-font-background7)", "var(--b3-font-background8)",
+        "var(--b3-font-background9)", "var(--b3-font-background10)", "var(--b3-font-background11)", "var(--b3-font-background12)",
+        "var(--b3-font-background13)"].forEach((item, index) => {
+        bgHTML += `<button class="keyboard__slash-item" data-type="backgroundColor">
+    <span class="keyboard__slash-icon" style="background-color:${item}">A</span>
+    <span class="keyboard__slash-text">${window.siyuan.languages.colorPrimary} ${index + 1}</span>
+</button>`;
+    });
+
+    let lastColorHTML = "";
+    const lastFonts = window.siyuan.storage[Constants.LOCAL_FONTSTYLES];
+    if (lastFonts.length > 0) {
+        lastColorHTML = `<div class="keyboard__slash-title">
+    ${window.siyuan.languages.lastUsed}
+</div>
+<div class="keyboard__slash-block">`;
+        lastFonts.forEach((item: string) => {
+            const lastFontStatus = item.split(Constants.ZWSP);
+            switch (lastFontStatus[0]) {
+                case "color":
+                    lastColorHTML += `<button class="keyboard__slash-item" data-type="${lastFontStatus[0]}">
+    <span class="keyboard__slash-icon" style="color:${lastFontStatus[1]}">A</span>
+    <span class="keyboard__slash-text">${window.siyuan.languages.colorFont} ${parseInt(lastFontStatus[1].replace("var(--b3-font-color", "")) + 1}</span>
+</button>`;
+                    break;
+                case "backgroundColor":
+                    lastColorHTML += `<button class="keyboard__slash-item" data-type="${lastFontStatus[0]}">
+    <span class="keyboard__slash-icon" style="background-color:${lastFontStatus[1]}">A</span>
+    <span class="keyboard__slash-text">${window.siyuan.languages.colorPrimary} ${parseInt(lastFontStatus[1].replace("var(--b3-font-background", "")) + 1}</span>
+</button>`;
+                    break;
+                case "style2":
+                    lastColorHTML += `<button class="keyboard__slash-item" data-type="${lastFontStatus[0]}">
+    <span class="keyboard__slash-text" style="-webkit-text-stroke: 0.2px var(--b3-theme-on-background);-webkit-text-fill-color : transparent;">${window.siyuan.languages.hollow}</span>
+</button>`;
+                    break;
+                case "style4":
+                    lastColorHTML += `<button class="keyboard__slash-item" data-type="${lastFontStatus[0]}">
+    <span class="keyboard__slash-text" style="text-shadow: 1px 1px var(--b3-theme-surface-lighter), 2px 2px var(--b3-theme-surface-lighter), 3px 3px var(--b3-theme-surface-lighter), 4px 4px var(--b3-theme-surface-lighter)">${window.siyuan.languages.shadow}</span>
+</button>`;
+                    break;
+                case "fontSize":
+                    lastColorHTML += `<button class="keyboard__slash-item" data-type="${lastFontStatus[0]}">
+    <span class="keyboard__slash-text">${lastFontStatus[1]}</span>
+</button>`;
+                    break;
+                case "style1":
+                    lastColorHTML += `<button class="keyboard__slash-item" data-type="${lastFontStatus[0]}">
+    <span class="keyboard__slash-icon" style="background-color:${lastFontStatus[1]};color:${lastFontStatus[2]}">A</span>
+    <span class="keyboard__slash-text">${window.siyuan.languages[lastFontStatus[2].replace("var(--b3-card-", "").replace("-color)", "") + "Style"]}</span>
+</button>`;
+                    break;
+                case "clear":
+                    lastColorHTML += `<button class="keyboard__slash-item" data-type="${lastFontStatus[0]}">
+    <span class="keyboard__slash-text">${window.siyuan.languages.clearFontStyle}</span>
+</button>`;
+                    break;
+            }
+        });
+        lastColorHTML += "</div>";
+    }
+    let textElement: HTMLElement;
+    let fontSize = "16px";
+    const nodeElements = getFontNodeElements(protyle);
+    if (nodeElements && nodeElements.length > 0) {
+        textElement = nodeElements[0];
+    } else {
+        textElement = protyle.toolbar.range.cloneContents().querySelector('[data-type~="text"]') as HTMLElement;
+        if (!textElement) {
+            textElement = hasClosestByAttribute(protyle.toolbar.range.startContainer, "data-type", "text") as HTMLElement;
+        }
+    }
+    if (textElement) {
+        fontSize = textElement.style.fontSize || "16px";
+    }
+    const utilElement = toolbarElement.querySelector(".keyboard__util") as HTMLElement;
+    utilElement.innerHTML = `${lastColorHTML}
+<div class="keyboard__slash-title">${window.siyuan.languages.color}</div>
+<div class="keyboard__slash-block">
+    <button class="keyboard__slash-item" data-type="style1">
+        <span class="keyboard__slash-icon" style="color: var(--b3-card-error-color);background-color: var(--b3-card-error-background);">A</span>
+        <span class="keyboard__slash-text">${window.siyuan.languages.errorStyle}</span>
+    </button>
+    <button class="keyboard__slash-item" data-type="style1">
+        <span class="keyboard__slash-icon" style="color: var(--b3-card-warning-color);background-color: var(--b3-card-warning-background);">A</span>
+        <span class="keyboard__slash-text">${window.siyuan.languages.warningStyle}</span>
+    </button>
+    <button class="keyboard__slash-item" data-type="style1">
+        <span class="keyboard__slash-icon" style="color: var(--b3-card-info-color);background-color: var(--b3-card-info-background);">A</span>
+        <span class="keyboard__slash-text">${window.siyuan.languages.infoStyle}</span>
+    </button>
+    <button class="keyboard__slash-item" data-type="style1">
+        <span class="keyboard__slash-icon" style="color: var(--b3-card-success-color);background-color: var(--b3-card-success-background);">A</span>
+        <span class="keyboard__slash-text">${window.siyuan.languages.successStyle}</span>
+    </button>
+</div>
+<div class="keyboard__slash-title">${window.siyuan.languages.colorFont}</div>
+<div class="keyboard__slash-block">
+    ${colorHTML}
+</div>
+<div class="keyboard__slash-title">${window.siyuan.languages.colorPrimary}</div>
+<div class="keyboard__slash-block">
+    ${bgHTML}
+</div>
+<div class="keyboard__slash-title">${window.siyuan.languages.fontStyle}</div>
+<div class="keyboard__slash-block">
+    <button class="keyboard__slash-item" data-type="style2">
+        <span class="keyboard__slash-text" style="-webkit-text-stroke: 0.2px var(--b3-theme-on-background);-webkit-text-fill-color : transparent;">${window.siyuan.languages.hollow}</span>
+    </button>
+    <button class="keyboard__slash-item" data-type="style4">
+        <span class="keyboard__slash-text" style="text-shadow: 1px 1px var(--b3-theme-surface-lighter), 2px 2px var(--b3-theme-surface-lighter), 3px 3px var(--b3-theme-surface-lighter), 4px 4px var(--b3-theme-surface-lighter)">${window.siyuan.languages.shadow}</span>
+    </button>
+    <button class="keyboard__slash-item" data-type="clear">
+        <svg class="keyboard__slash-icon"><use xlink:href="#iconTrashcan"></use></svg>
+        <span class="keyboard__slash-text">${window.siyuan.languages.clearFontStyle}</span>
+    </button>
+</div>
+<div class="keyboard__slash-title">${window.siyuan.languages.fontSize}</div>
+<div class="keyboard__slash-block">
+    <select class="b3-select fn__block" style="width: calc(50% - 8px);margin: 4px 0 8px 0;">
+        <option ${fontSize === "12px" ? "selected" : ""} value="12px">12px</option>
+        <option ${fontSize === "13px" ? "selected" : ""} value="13px">13px</option>
+        <option ${fontSize === "14px" ? "selected" : ""} value="14px">14px</option>
+        <option ${fontSize === "15px" ? "selected" : ""} value="15px">15px</option>
+        <option ${fontSize === "16px" ? "selected" : ""} value="16px">16px</option>
+        <option ${fontSize === "19px" ? "selected" : ""} value="19px">19px</option>
+        <option ${fontSize === "22px" ? "selected" : ""} value="22px">22px</option>
+        <option ${fontSize === "24px" ? "selected" : ""} value="24px">24px</option>
+        <option ${fontSize === "29px" ? "selected" : ""} value="29px">29px</option>
+        <option ${fontSize === "32px" ? "selected" : ""} value="32px">32px</option>
+        <option ${fontSize === "40px" ? "selected" : ""} value="40px">40px</option>
+        <option ${fontSize === "48px" ? "selected" : ""} value="48px">48px</option>
+    </select>
+</div>`;
+    utilElement.querySelector("select").addEventListener("change", function (event: Event) {
+        fontEvent(protyle, nodeElements, "fontSize", (event.target as HTMLSelectElement).value);
+    });
+};
+
 const renderSlashMenu = (protyle: IProtyle, toolbarElement: Element) => {
     protyle.hint.splitChar = "/";
     protyle.hint.lastIndex = -1;
@@ -34,74 +187,42 @@ const renderSlashMenu = (protyle: IProtyle, toolbarElement: Element) => {
 <div class="keyboard__slash-block">
     ${getSlashItem(Constants.ZWSP, "iconMarkdown", window.siyuan.languages.template)}
     ${getSlashItem(Constants.ZWSP + 1, "iconBoth", window.siyuan.languages.widget)}
-</div>
-<div class="keyboard__slash-block">
     ${getSlashItem(Constants.ZWSP + 2, "iconImage", window.siyuan.languages.assets)}
     ${getSlashItem("((", "iconRef", window.siyuan.languages.ref, "true")}
-</div>
-<div class="keyboard__slash-block">
     ${getSlashItem("{{", "iconSQL", window.siyuan.languages.blockEmbed, "true")}
     ${getSlashItem(Constants.ZWSP + 5, "iconSparkles", "AI Chat")}
-</div>
-<div class="keyboard__slash-block">
     ${getSlashItem(Constants.ZWSP + 4, "iconFile", window.siyuan.languages.newFile)}
-    <div class="keyboard__slash-empty"></div>
 </div>
 <div class="keyboard__slash-title"></div>
 <div class="keyboard__slash-block">
     ${getSlashItem("# " + Lute.Caret, "iconH1", window.siyuan.languages.heading1, "true")}
     ${getSlashItem("## " + Lute.Caret, "iconH2", window.siyuan.languages.heading2, "true")}
-</div>
-<div class="keyboard__slash-block">
     ${getSlashItem("### " + Lute.Caret, "iconH3", window.siyuan.languages.heading3, "true")}
     ${getSlashItem("#### " + Lute.Caret, "iconH4", window.siyuan.languages.heading4, "true")}
-</div>
-<div class="keyboard__slash-block">
     ${getSlashItem("##### " + Lute.Caret, "iconH5", window.siyuan.languages.heading5, "true")}
     ${getSlashItem("###### " + Lute.Caret, "iconH6", window.siyuan.languages.heading6, "true")}
-</div>
-<div class="keyboard__slash-block">
     ${getSlashItem("* " + Lute.Caret, "iconList", window.siyuan.languages.list, "true")}
     ${getSlashItem("1. " + Lute.Caret, "iconOrderedList", window.siyuan.languages["ordered-list"], "true")}
-</div>
-<div class="keyboard__slash-block">
     ${getSlashItem("* [ ] " + Lute.Caret, "iconCheck", window.siyuan.languages.check, "true")}
     ${getSlashItem("> " + Lute.Caret, "iconQuote", window.siyuan.languages.quote, "true")}
-</div>
-<div class="keyboard__slash-block">
     ${getSlashItem("```", "iconCode", window.siyuan.languages.code, "true")}
     ${getSlashItem(`| ${Lute.Caret} |  |  |\n| --- | --- | --- |\n|  |  |  |\n|  |  |  |`, "iconTable", window.siyuan.languages.table, "true")}
-</div>
-<div class="keyboard__slash-block">
     ${getSlashItem("---", "iconLine", window.siyuan.languages.line, "true")}
     ${getSlashItem("$$", "iconMath", window.siyuan.languages.math)}
-</div>
-<div class="keyboard__slash-block">
     ${getSlashItem("<div>", "iconHTML5", "HTML")}
-    <div class="keyboard__slash-empty"></div>
 </div>
 <div class="keyboard__slash-title"></div>
 <div class="keyboard__slash-block">
     ${getSlashItem("emoji", "iconEmoji", window.siyuan.languages.emoji, "true")}
     ${getSlashItem("a", "iconLink", window.siyuan.languages.link)}
-</div>
-<div class="keyboard__slash-block">
     ${getSlashItem("strong", "iconBold", window.siyuan.languages.bold, "true")}
     ${getSlashItem("em", "iconItalic", window.siyuan.languages.italic, "true")}
-</div>
-<div class="keyboard__slash-block">
     ${getSlashItem("u", "iconUnderline", window.siyuan.languages.underline, "true")}
     ${getSlashItem("s", "iconStrike", window.siyuan.languages.strike, "true")}
-</div>
-<div class="keyboard__slash-block">
     ${getSlashItem("mark", "iconMark", window.siyuan.languages.mark, "true")}
     ${getSlashItem("sup", "iconSup", window.siyuan.languages.sup, "true")}
-</div>
-<div class="keyboard__slash-block">
     ${getSlashItem("sub", "iconSub", window.siyuan.languages.sub, "true")}
     ${getSlashItem("tag", "iconTags", window.siyuan.languages.tag, "true")}
-</div>
-<div class="keyboard__slash-block">
     ${getSlashItem("code", "iconInlineCode", window.siyuan.languages["inline-code"], "true")}
     ${getSlashItem("inline-math", "iconMath", window.siyuan.languages["inline-math"])}
 </div>
@@ -109,44 +230,27 @@ const renderSlashMenu = (protyle: IProtyle, toolbarElement: Element) => {
 <div class="keyboard__slash-block">
     ${getSlashItem(Constants.ZWSP + 3, "iconDownload", window.siyuan.languages.insertAsset + '<input class="b3-form__upload" type="file"' + (protyle.options.upload.accept ? (' multiple="' + protyle.options.upload.accept + '"') : "") + "/>", "true")}
     ${getSlashItem('<iframe sandbox="allow-forms allow-presentation allow-same-origin allow-scripts allow-modals" src="" border="0" frameborder="no" framespacing="0" allowfullscreen="true"></iframe>', "iconLanguage", window.siyuan.languages.insertIframeURL, "true")}
-</div>
-<div class="keyboard__slash-block">
     ${getSlashItem("![]()", "iconImage", window.siyuan.languages.insertImgURL, "true")}
     ${getSlashItem('<video controls="controls" src=""></video>', "iconVideo", window.siyuan.languages.insertVideoURL, "true")}
-</div>
-<div class="keyboard__slash-block">
     ${getSlashItem('<audio controls="controls" src=""></audio>', "iconRecord", window.siyuan.languages.insertAudioURL, "true")}
-    <div class="keyboard__slash-empty"></div>
 </div>
 <div class="keyboard__slash-title"></div>
 <div class="keyboard__slash-block">
     ${getSlashItem("```abc\n```", "", window.siyuan.languages.staff, "true")}
     ${getSlashItem("```echarts\n```", "", window.siyuan.languages.chart, "true")}
-</div>
-<div class="keyboard__slash-block">
     ${getSlashItem("```flowchart\n```", "", "Flow Chart", "true")}
     ${getSlashItem("```graphviz\n```", "", "Graph", "true")}
-</div>
-<div class="keyboard__slash-block">
     ${getSlashItem("```mermaid\n```", "", "Mermaid", "true")}
     ${getSlashItem("```mindmap\n```", "", window.siyuan.languages.mindmap, "true")}
-</div>
-<div class="keyboard__slash-block">
     ${getSlashItem("```plantuml\n```", "", "UML", "true")}
-    <div class="keyboard__slash-empty"></div>
 </div>
 <div class="keyboard__slash-title"></div>
 <div class="keyboard__slash-block">
     ${getSlashItem(`style${Constants.ZWSP}color: var(--b3-card-info-color);background-color: var(--b3-card-info-background);`, '<div style="color: var(--b3-card-info-color);background-color: var(--b3-card-info-background);" class="keyboard__slash-icon">A</div>', window.siyuan.languages.infoStyle, "true")}
     ${getSlashItem(`style${Constants.ZWSP}color: var(--b3-card-success-color);background-color: var(--b3-card-success-background);`, '<div style="color: var(--b3-card-success-color);background-color: var(--b3-card-success-background);" class="keyboard__slash-icon">A</div>', window.siyuan.languages.successStyle, "true")}
-</div>
-<div class="keyboard__slash-block">
     ${getSlashItem(`style${Constants.ZWSP}color: var(--b3-card-warning-color);background-color: var(--b3-card-warning-background);`, '<div style="color: var(--b3-card-warning-color);background-color: var(--b3-card-warning-background);" class="keyboard__slash-icon">A</div>', window.siyuan.languages.warningStyle, "true")}
     ${getSlashItem(`style${Constants.ZWSP}color: var(--b3-card-error-color);background-color: var(--b3-card-error-background);`, '<div style="color: var(--b3-card-error-color);background-color: var(--b3-card-error-background);" class="keyboard__slash-icon">A</div>', window.siyuan.languages.errorStyle, "true")}
-</div>
-<div class="keyboard__slash-block">
     ${getSlashItem(`style${Constants.ZWSP}`, '<div class="keyboard__slash-icon">A</div>', window.siyuan.languages.clearFontStyle, "true")}
-    <div class="keyboard__slash-empty"></div>
 </div>`;
     protyle.hint.bindUploadEvent(protyle, utilElement);
 };
@@ -179,6 +283,7 @@ const hideKeyboardToolbarUtil = () => {
         editor.protyle.element.parentElement.style.paddingBottom = "42px";
     }
     toolbarElement.querySelector('.keyboard__action[data-type="add"]').classList.remove("protyle-toolbar__item--current");
+    toolbarElement.querySelector('.keyboard__action[data-type="text"]').classList.remove("protyle-toolbar__item--current");
     toolbarElement.querySelector('.keyboard__action[data-type="done"] use').setAttribute("xlink:href", "#iconKeyboardHide");
 };
 
@@ -387,7 +492,7 @@ export const initKeyboardToolbar = () => {
         const target = event.target as HTMLElement;
         const slashBtnElement = hasClosestByClassName(event.target as HTMLElement, "keyboard__slash-item");
         const protyle = getCurrentEditor().protyle;
-        if (slashBtnElement) {
+        if (slashBtnElement && !slashBtnElement.getAttribute("data-type")) {
             const dataValue = decodeURIComponent(slashBtnElement.getAttribute("data-value"));
             protyle.hint.fill(dataValue, protyle, false);   // 点击后 range 会改变
             if (dataValue !== Constants.ZWSP + 3) {
@@ -453,16 +558,28 @@ export const initKeyboardToolbar = () => {
             dynamicElements[0].classList.add("fn__none");
             focusByRange(range);
             return;
-        } else if (["a", "block-ref", "inline-math", "inline-memo", "text"].includes(type)) {
+        } else if (["a", "block-ref", "inline-math", "inline-memo"].includes(type)) {
             if (!hasClosestByAttribute(range.startContainer, "data-type", "NodeCodeBlock")) {
                 protyle.toolbar.element.querySelector(`[data-type="${type}"]`).dispatchEvent(new CustomEvent("click"));
             }
             return;
-        } else if (["strong", "em", "s", "code", "mark", "tag", "u", "sup", "clear", "sub", "kbd"].includes(type)) {
+        } else if (buttonElement.classList.contains("keyboard__action") && ["strong", "em", "s", "code", "mark", "tag", "u", "sup", "clear", "sub", "kbd"].includes(type)) {
             if (!hasClosestByAttribute(range.startContainer, "data-type", "NodeCodeBlock")) {
                 protyle.toolbar.setInlineMark(protyle, type, "toolbar");
             }
             return;
+        } else if (type === "text") {
+            if (buttonElement.classList.contains("protyle-toolbar__item--current")) {
+                hideKeyboardToolbarUtil();
+                focusByRange(range);
+            } else {
+                buttonElement.classList.add("protyle-toolbar__item--current");
+                toolbarElement.querySelector('.keyboard__action[data-type="done"] use').setAttribute("xlink:href", "#iconCloseRound");
+                const oldScrollTop = protyle.contentElement.scrollTop;
+                renderTextMenu(protyle, toolbarElement);
+                showKeyboardToolbarUtil(oldScrollTop);
+            }
+            return;
         } else if (type === "moveup") {
             moveToUp(protyle, nodeElement, range);
             focusByRange(range);
@@ -504,6 +621,22 @@ export const initKeyboardToolbar = () => {
         } else if (type === "indent") {
             listIndent(protyle, [nodeElement.parentElement], range);
             focusByRange(range);
+            return;
+        }
+        // appearance
+        if (["clear", "style2", "style4", "color", "backgroundColor", "fontSize", "style1"].includes(type)) {
+            const nodeElements = getFontNodeElements(protyle)
+            if (type === "style1") {
+                fontEvent(protyle, nodeElements, type, buttonElement.firstElementChild.style.backgroundColor + Constants.ZWSP + buttonElement.firstElementChild.style.color);
+            } else if (type === "fontSize") {
+                fontEvent(protyle, nodeElements, type, buttonElement.firstElementChild.textContent.trim());
+            } else if (type === "backgroundColor") {
+                fontEvent(protyle, nodeElements, type, buttonElement.firstElementChild.style.backgroundColor);
+            } else if (type === "color") {
+                fontEvent(protyle, nodeElements, type, buttonElement.firstElementChild.style.color);
+            } else {
+                fontEvent(protyle, nodeElements, type);
+            }
         }
     });
 };

+ 15 - 11
app/src/protyle/toolbar/Font.ts

@@ -12,21 +12,11 @@ export class Font extends ToolbarItem {
     constructor(protyle: IProtyle, menuItem: IMenuItem) {
         super(protyle, menuItem);
         this.element.addEventListener("click", () => {
-            let nodeElements: Element[];
-            if (protyle.toolbar.range.toString() === "") {
-                nodeElements = Array.from(protyle.wysiwyg.element.querySelectorAll(".protyle-wysiwyg--select"));
-                if (nodeElements.length === 0) {
-                    const nodeElement = hasClosestBlock(protyle.toolbar.range.startContainer);
-                    if (nodeElement) {
-                        nodeElements = [nodeElement];
-                    }
-                }
-            }
             protyle.toolbar.element.classList.add("fn__none");
             protyle.toolbar.subElement.innerHTML = "";
             protyle.toolbar.subElement.style.width = "";
             protyle.toolbar.subElement.style.padding = "";
-            protyle.toolbar.subElement.append(appearanceMenu(protyle, nodeElements));
+            protyle.toolbar.subElement.append(appearanceMenu(protyle, getFontNodeElements()));
             protyle.toolbar.subElement.classList.remove("fn__none");
             protyle.toolbar.subElementCloseCB = undefined;
             focusByRange(protyle.toolbar.range);
@@ -418,3 +408,17 @@ export const hasSameTextStyle = (currentElement: HTMLElement, sideElement: HTMLE
     }
     return true; // 清除字体样式会使用 "text" 作为标识
 };
+
+export const getFontNodeElements = (protyle: IProtyle) => {
+    let nodeElements: Element[];
+    if (protyle.toolbar.range.toString() === "") {
+        nodeElements = Array.from(protyle.wysiwyg.element.querySelectorAll(".protyle-wysiwyg--select"));
+        if (nodeElements.length === 0) {
+            const nodeElement = hasClosestBlock(protyle.toolbar.range.startContainer);
+            if (nodeElement) {
+                nodeElements = [nodeElement];
+            }
+        }
+    }
+    return nodeElements;
+}