<template>
  <div class="canvas-editor-wrapper">
    <div class="canvas-container">
      <el-container style="height: 100%">
        <el-header>
          <div class="menu" editor-component="menu">
            <div class="menu-item">
              <div class="menu-item__save" title="保存">
                <i class="el-icon-s-claim" style="color: #646464"></i>
              </div>
              <div class="menu-item__undo">
                <i></i>
              </div>
              <div class="menu-item__redo">
                <i></i>
              </div>
              <div class="menu-item__painter" title="格式刷(双击可连续使用)">
                <i></i>
              </div>
              <div class="menu-item__format" title="清除格式">
                <i></i>
              </div>
            </div>
            <div class="menu-divider"></div>
            <div class="menu-item">
              <div class="menu-item__font">
                <span class="select" title="字体">微软雅黑</span>
                <div class="options">
                  <ul>
                    <li
                      data-family="Microsoft YaHei"
                      style="font-family: 'Microsoft YaHei'"
                    >
                      微软雅黑
                    </li>
                    <li data-family="宋体" style="font-family: '宋体'">宋体</li>
                    <li data-family="黑体" style="font-family: '黑体'">黑体</li>
                    <li data-family="仿宋" style="font-family: '仿宋'">仿宋</li>
                    <li data-family="楷体" style="font-family: '楷体'">楷体</li>
                    <li data-family="等线" style="font-family: '等线'">等线</li>
                    <!-- <li data-family="华文琥珀" style="font-family:'华文琥珀';">华文琥珀</li>
                <li data-family="华文楷体" style="font-family:'华文楷体';">华文楷体</li>
                <li data-family="华文隶书" style="font-family:'华文隶书';">华文隶书</li>
                <li data-family="华文新魏" style="font-family:'华文新魏';">华文新魏</li>
                <li data-family="华文行楷" style="font-family:'华文行楷';">华文行楷</li>
                <li data-family="华文中宋" style="font-family:'华文中宋';">华文中宋</li>
                <li data-family="华文彩云" style="font-family:'华文彩云';">华文彩云</li> -->
                    <li data-family="Arial" style="font-family: 'Arial'">
                      Arial
                    </li>
                    <li data-family="Segoe UI" style="font-family: 'Segoe UI'">
                      Segoe UI
                    </li>
                    <li data-family="Ink Free" style="font-family: 'Ink Free'">
                      Ink Free
                    </li>
                    <li data-family="Fantasy" style="font-family: 'Fantasy'">
                      Fantasy
                    </li>
                  </ul>
                </div>
              </div>
              <div class="menu-item__size">
                <span class="select" title="字体">小四</span>
                <div class="options">
                  <ul>
                    <li data-size="56">初号</li>
                    <li data-size="48">小初</li>
                    <li data-size="34">一号</li>
                    <li data-size="32">小一</li>
                    <li data-size="29">二号</li>
                    <li data-size="24">小二</li>
                    <li data-size="21">三号</li>
                    <li data-size="20">小三</li>
                    <li data-size="18">四号</li>
                    <li data-size="16">小四</li>
                    <li data-size="14">五号</li>
                    <li data-size="12">小五</li>
                    <li data-size="10">六号</li>
                    <li data-size="8">小六</li>
                    <li data-size="7">七号</li>
                    <li data-size="6">八号</li>
                  </ul>
                </div>
              </div>
              <div class="menu-item__size-add">
                <i></i>
              </div>
              <div class="menu-item__size-minus">
                <i></i>
              </div>
              <div class="menu-item__bold">
                <i></i>
              </div>
              <div class="menu-item__italic">
                <i></i>
              </div>
              <div class="menu-item__underline">
                <i></i>
              </div>
              <div class="menu-item__strikeout" title="删除线(Ctrl+Shift+X)">
                <i></i>
              </div>
              <div class="menu-item__superscript">
                <i></i>
              </div>
              <div class="menu-item__subscript">
                <i></i>
              </div>
              <div class="menu-item__color" title="字体颜色">
                <i></i>
                <div class="options">
                  <div class="color-section">
                    <div class="section-title">主题颜色</div>
                    <ul>
                      <!-- 第一行 -->
                      <li data-color="#000000" title="黑色" style="background-color: #000000"></li>
                      <li data-color="#2B579A" title="深蓝色" style="background-color: #2B579A"></li>
                      <li data-color="#4472C4" title="蓝色" style="background-color: #4472C4"></li>
                      <li data-color="#70AD47" title="绿色" style="background-color: #70AD47"></li>
                      <li data-color="#FFC000" title="黄色" style="background-color: #FFC000"></li>
                      <li data-color="#ED7D31" title="橙色" style="background-color: #ED7D31"></li>
                      <li data-color="#C00000" title="红色" style="background-color: #C00000"></li>
                      <li data-color="#7030A0" title="紫色" style="background-color: #7030A0"></li>
                      <li data-color="#FFFFFF" title="白色" style="background-color: #FFFFFF"></li>

                      <!-- 灰度行 -->
                      <li data-color="#7F7F7F" title="深灰色" style="background-color: #7F7F7F"></li>
                      <li data-color="#A5A5A5" title="灰色" style="background-color: #A5A5A5"></li>
                      <li data-color="#D0D0D0" title="浅灰色" style="background-color: #D0D0D0"></li>

                      <!-- 蓝色系列 -->
                      <li data-color="#D6E3F3" title="浅蓝色-1" style="background-color: #D6E3F3"></li>
                      <li data-color="#B4C7E7" title="浅蓝色-2" style="background-color: #B4C7E7"></li>
                      <li data-color="#8EAADB" title="浅蓝色-3" style="background-color: #8EAADB"></li>
                      <li data-color="#2E75B6" title="深蓝色-1" style="background-color: #2E75B6"></li>
                      <li data-color="#1F4E79" title="深蓝色-2" style="background-color: #1F4E79"></li>
                    </ul>
                  </div>
                  <div class="color-section">
                    <div class="section-title">标准色</div>
                    <ul>
                      <li data-color="#FF0000" title="红色" style="background-color: #FF0000"></li>
                      <li data-color="#FF6600" title="橙色" style="background-color: #FF6600"></li>
                      <li data-color="#FFFF00" title="黄色" style="background-color: #FFFF00"></li>
                      <li data-color="#00FF00" title="绿色" style="background-color: #00FF00"></li>
                      <li data-color="#00FFFF" title="青色" style="background-color: #00FFFF"></li>
                      <li data-color="#0000FF" title="蓝色" style="background-color: #0000FF"></li>
                      <li data-color="#FF00FF" title="紫色" style="background-color: #FF00FF"></li>
                    </ul>
                  </div>
                </div>
              </div>
              <div class="menu-item__highlight" title="高亮">
                <i></i>
                <div class="options">
                  <ul>
                    <!-- 第一行 -->
                    <li data-color="transparent" title="无" style="background-color: transparent">✓</li>
                    <li data-color="#ffff00" title="黄色" style="background-color: #ffff00"></li>
                    <li data-color="#00ff00" title="绿色" style="background-color: #00ff00"></li>
                    <li data-color="#00ffff" title="青色" style="background-color: #00ffff"></li>
                    <li data-color="#ff00ff" title="粉色" style="background-color: #ff00ff"></li>
                    <li data-color="#0000ff" title="蓝色" style="background-color: #0000ff"></li>
                    
                    <!-- 第二行 -->
                    <li data-color="#800000" title="深红色" style="background-color: #800000"></li>
                    <li data-color="#ff0000" title="红色" style="background-color: #ff0000"></li>
                    <li data-color="#808000" title="橄榄色" style="background-color: #808000"></li>
                    <li data-color="#008000" title="深绿色" style="background-color: #008000"></li>
                    <li data-color="#008080" title="青灰色" style="background-color: #008080"></li>
                    <li data-color="#000080" title="深蓝色" style="background-color: #000080"></li>
                    
                    <!-- 第三行 -->
                    <li data-color="#000000" title="黑色" style="background-color: #000000"></li>
                    <li data-color="#808080" title="深灰色" style="background-color: #808080"></li>
                    <li data-color="#c0c0c0" title="灰色" style="background-color: #c0c0c0"></li>
                  </ul>
                </div>
              </div>
            </div>
            <div class="menu-divider"></div>
            <div class="menu-item">
              <div class="menu-item__title">
                <i></i>
                <span class="select" title="切换标题">正文</span>
                <div class="options">
                  <ul>
                    <li style="font-size: 16px">正文</li>
                    <li data-level="first" style="font-size: 26px">标题1</li>
                    <li data-level="second" style="font-size: 24px">标题2</li>
                    <li data-level="third" style="font-size: 22px">标题3</li>
                    <li data-level="fourth" style="font-size: 20px">标题4</li>
                    <li data-level="fifth" style="font-size: 18px">标题5</li>
                    <li data-level="sixth" style="font-size: 16px">标题6</li>
                  </ul>
                </div>
              </div>
              <div class="menu-item__left">
                <i></i>
              </div>
              <div class="menu-item__center">
                <i></i>
              </div>
              <div class="menu-item__right">
                <i></i>
              </div>
              <div class="menu-item__alignment">
                <i></i>
              </div>
              <div class="menu-item__row-margin">
                <i title="行间距"></i>
                <div class="options">
                  <ul>
                    <li data-rowmargin="1">1</li>
                    <li data-rowmargin="1.25">1.25</li>
                    <li data-rowmargin="1.5">1.5</li>
                    <li data-rowmargin="1.75">1.75</li>
                    <li data-rowmargin="2">2</li>
                    <li data-rowmargin="2.5">2.5</li>
                    <li data-rowmargin="3">3</li>
                  </ul>
                </div>
              </div>
              <div class="menu-item__list">
                <i></i>
                <div class="options">
                  <ul>
                    <li>
                      <label>取消列表</label>
                    </li>
                    <li data-list-type="ol" data-list-style="decimal">
                      <label>有序列表：</label>
                      <ol>
                        <li>________</li>
                      </ol>
                    </li>
                    <li data-list-type="ul" data-list-style="disc">
                      <label>实心圆点列表：</label>
                      <ul style="list-style-type: disc">
                        <li>________</li>
                      </ul>
                    </li>
                    <li data-list-type="ul" data-list-style="circle">
                      <label>空心圆点列表：</label>
                      <ul style="list-style-type: circle">
                        <li>________</li>
                      </ul>
                    </li>
                    <li data-list-type="ul" data-list-style="square">
                      <label>空心方块列表：</label>
                      <ul style="list-style-type: square">
                        <li>________</li>
                      </ul>
                    </li>
                  </ul>
                </div>
              </div>
            </div>
            <div class="menu-divider"></div>
            <div class="menu-item">
              <div class="menu-item__table">
                <i title="表格"></i>
              </div>
              <div class="menu-item__table__collapse">
                <div class="table-close">×</div>
                <div class="table-title">
                  <span class="table-select">插入</span>
                  <span>表格</span>
                </div>
                <div class="table-panel"></div>
              </div>
              <div class="menu-item__image">
                <i title="图片"></i>
                <input
                  type="file"
                  id="image"
                  accept=".png, .jpg, .jpeg, .svg, .gif"
                />
              </div>
              <div class="menu-item__hyperlink">
                <i title="超链接"></i>
              </div>
              <div class="menu-item__separator">
                <i title="分割线"></i>
                <div class="options">
                  <ul>
                    <li data-separator="0,0">
                      <i></i>
                    </li>
                    <li data-separator="1,1">
                      <i></i>
                    </li>
                    <li data-separator="3,1">
                      <i></i>
                    </li>
                    <li data-separator="4,4">
                      <i></i>
                    </li>
                    <li data-separator="7,3,3,3">
                      <i></i>
                    </li>
                    <li data-separator="6,2,2,2,2,2">
                      <i></i>
                    </li>
                  </ul>
                </div>
              </div>
              <!-- <div class="menu-item__watermark">
            <i title="水印(添加、删除)"></i>
            <div class="options">
              <ul>
                <li data-menu="add">添加水印</li>
                <li data-menu="delete">删除水印</li>
              </ul>
            </div>
          </div>
          <div class="menu-item__codeblock" title="代码块">
            <i></i>
          </div>
          <div class="menu-item__page-break" title="分页符">
            <i></i>
          </div>
          <div class="menu-item__control">
            <i title="控件"></i>
            <div class="options">
              <ul>
                <li data-control='text'>文本</li>
                <li data-control="select">列举</li>
                <li data-control="checkbox">复选框</li>
              </ul>
            </div>
          </div>
          <div class="menu-item__checkbox" title="复选框">
            <i></i>
          </div>
          <div class="menu-item__latex" title="LateX">
            <i></i>
          </div>
          <div class="menu-item__date">
            <i title="日期"></i>
            <div class="options">
              <ul>
                <li data-format="yyyy-MM-dd"></li>
                <li data-format="yyyy-MM-dd hh:mm:ss"></li>
              </ul>
            </div>
          </div>
          <div class="menu-item__block" title="内容块">
            <i></i>
          </div> -->
            </div>
            <div class="menu-divider"></div>
            <div class="menu-item">
              <div class="menu-item__search" data-menu="search">
                <i></i>
              </div>
              <div class="menu-item__search__collapse" data-menu="search">
                <div class="menu-item__search__collapse__search">
                  <input type="text" />
                  <label class="search-result"></label>
                  <div class="arrow-left">
                    <i></i>
                  </div>
                  <div class="arrow-right">
                    <i></i>
                  </div>
                  <span>×</span>
                </div>
                <div class="menu-item__search__collapse__replace">
                  <input type="text" />
                  <button>替换</button>
                </div>
              </div>
              <!-- <div class="menu-item__print" data-menu="print">
            <i></i>
          </div> -->
            </div>
          </div>
        </el-header>

        <el-main class="content">
          <!-- <div class="catalog" editor-component="catalog">
          <div class="catalog__header">
            <span>目录</span>
            <div class="catalog__header__close">
              <i></i>
            </div>
          </div>
          <div class="catalog__main"></div>
        </div> -->
          <div
            id="canvasEditor"
            class="canvas-editor"
            editor-component="main"
          ></div>
          <!-- <div class="comment" editor-component="comment"></div> -->
        </el-main>
        <el-footer style="height: 30px">
          <div class="footer" editor-component="footer">
            <div>
              <!-- <div class="catalog-mode" title="目录">
              <i></i>
            </div> -->
              <div class="page-mode">
                <i title="页面模式(分页、连页)"></i>
                <div class="options">
                  <ul>
                    <li data-page-mode="paging" class="active">分页</li>
                    <li data-page-mode="continuity">连页</li>
                  </ul>
                </div>
              </div>
              <span>可见页码：<span class="page-no-list">1</span></span>
              <span
                >页面：<span class="page-no">1</span>/<span class="page-size"
                  >1</span
                ></span
              >
              <span>字数：<span class="word-count">0</span></span>
            </div>
            <div class="editor-mode" title="编辑模式(编辑、清洁、只读、表单)">
              编辑模式
            </div>
            <div>
              <div class="page-scale-minus" title="缩小(Ctrl+-)">
                <i></i>
              </div>
              <span
                class="page-scale-percentage"
                title="显示比例(点击可复原Ctrl+0)"
                >100%</span
              >
              <div class="page-scale-add" title="放大(Ctrl+=)">
                <i></i>
              </div>
              <div class="paper-size">
                <i title="纸张类型"></i>
                <div class="options">
                  <ul>
                    <li data-paper-size="794*1123" class="active">A4</li>
                    <li data-paper-size="1593*2251">A2</li>
                    <li data-paper-size="1125*1593">A3</li>
                    <li data-paper-size="565*796">A5</li>
                    <li data-paper-size="412*488">5号信封</li>
                    <li data-paper-size="450*866">6号信封</li>
                    <li data-paper-size="609*862">7号信封</li>
                    <li data-paper-size="862*1221">9号信封</li>
                    <li data-paper-size="813*1266">法律用纸</li>
                    <li data-paper-size="813*1054">信纸</li>
                  </ul>
                </div>
              </div>
              <div class="paper-direction">
                <i title="纸张方向"></i>
                <div class="options">
                  <ul>
                    <li data-paper-direction="vertical" class="active">纵向</li>
                    <li data-paper-direction="horizontal">横向</li>
                  </ul>
                </div>
              </div>
              <div class="paper-margin" title="页边距">
                <i></i>
              </div>
              <div class="fullscreen" title="全屏显示">
                <i></i>
              </div>
            </div>
          </div>
        </el-footer>
      </el-container>
    </div>
  </div>
</template>

<script>
import Editor from "@hufe921/canvas-editor";
import { Dialog } from "./components/dialog/Dialog";
import { Signature } from "./components/signature/Signature";
import { IEditorOption, ITableOption, IHeader, IFooter } from "./option";

import {
  BlockType,
  Command,
  ControlType,
  EditorMode,
  EditorZone,
  ElementType,
  IBlock,
  ICatalogItem,
  IElement,
  KeyMap,
  ListStyle,
  ListType,
  PageMode,
  PaperDirection,
  RowFlex,
  TitleLevel,
  splitText,
} from "@hufe921/canvas-editor";

export default {
  name: "CanvasEditor", // 确保设置了组件名称
  data() {
    return {
      editorRef: null,
      isApple:
        typeof navigator !== "undefined" &&
        /Mac OS X/.test(navigator.userAgent),
      // 编辑模式
      modeList: [
        {
          mode: EditorMode.READONLY,
          name: "只读模式",
        },
        {
          mode: EditorMode.EDIT,
          name: "编辑模式",
        },
      ],
      header: [], // 页眉配置
      main: [], // 主要编辑内容
      footer: [], // 页脚信息
      options: IEditorOption,
      // 批注 TODO
      commentList: [],
    };
  },
  props: {
    // 编辑模式
    editMode: {
      type: String,
      default: 'edit'
    },
    // html数据
    htmlData: {
      type: String,
      default: ''
    },
    // 后端传过来的保存html的JSON数据（用于回显）
    docJson: {
      type: [Object, String],
      default: null
    },
  },
  watch: {
    // 监听父组件传过来的编辑模式，设置模式
    editMode: {
      handler(val) {
        if (this.editorRef) {
          this.editorRef.command.executeMode(val);
          // 设置模式
          const modeElement = document.querySelector(".editor-mode");
          modeElement.innerText =
            this.modeList
              .filter((item) => item.mode == val)
              .map((data) => data.name) || "";
          // 设置菜单栏权限视觉反馈
          const isReadonly = val === EditorMode.READONLY;
          const enableMenuList = ["search", "print"];
          document.querySelectorAll(".menu-item>div").forEach((dom) => {
            const menu = dom.dataset.menu;
            isReadonly && (!menu || !enableMenuList.includes(menu))
              ? dom.classList.add("disable")
              : dom.classList.remove("disable");
          });
        }
      },
      deep: true,
    },
  },
  methods: {
    debounce(func, delay) {
      let timer;
      return function (...args) {
        if (timer) {
          window.clearTimeout(timer);
        }
        timer = window.setTimeout(() => {
          func.apply(this, args);
        }, delay);
      };
    },
    getValue() {
      // 返回当前编辑器的内容
      return this.editor?.getData() || '';
    },
    
    insertHtml(html) {
      // 插入 HTML 内容
      if (this.editor) {
        this.editor.insertHtml(html);
      }
    },
    
    setContent(content) {
      // 设置编辑器内容
      if (this.editor) {
        this.editor.setData(content);
      }
    }
  },
  mounted() {
    const isApple =
      typeof navigator !== "undefined" && /Mac OS X/.test(navigator.userAgent);
    const instance = new Editor(
      document.querySelector(".canvas-editor"),
      {
        header: this.header,
        main: this.main,
        footer: this.footer,
      },
      this.options
    );
    this.editorRef = instance;
    // cypress使用
    Reflect.set(window, "editor", instance);

    // 回显编辑器数据
    if (this.docJson !== null) {
      // 通过getValue来的数据回显页面（因为用html回显页面会丢掉font-family，官网git issue有解释）
      instance.command.executeSetValue({ main: JSON.parse(this.docJson) });
    } else {
      // 处理后端返回的html字符串
      // 先替换 \r\n 为 空格，以统一处理空格问题
      let step1 = this.htmlData.replace(/\r\n/g, " ");
      // 然后替换 \\\" 为 \" ，确保样式字符串内的引号正确
      let step2 = step1.replace(/\\\"/g, '"');
      // 接着替换 \\ 为 空字符，去掉其他不必要的转义
      let cleanedHtml = step2.replace(/\\+/g, "");
      // 设置Word模板数据
      instance.command.executeSetHTML({ main: cleanedHtml });
    }

    // 菜单弹窗销毁
    window.addEventListener(
      "click",
      (evt) => {
        const visibleDom = document.querySelector(".visible");
        if (!visibleDom || visibleDom.contains(evt.target)) return;
        visibleDom.classList.remove("visible");
      },
      {
        capture: true,
      }
    );
    /*
        工具栏方法
      */

    // 1.保存（自定义）
    const saveDom = document.querySelector(".menu-item__save");
    saveDom.title = `保存(${this.isApple ? "⌘" : "Ctrl"}+S)`;
    saveDom.onclick = () => {
      const value = instance.command.getValue(this.options);
      const htmlVal = instance.command.getHTML();
      this.$emit("save", htmlVal); // 保存数据传给父组件
    };
    // 快捷键保存
    instance.listener.saved = (payload) => {
      console.log("elementList: ", payload);
      this.$emit("save", htmlVal); // 保存数据传给父组件
    };

    // 2. | 撤销 | 重做 | 格式刷 | 清除格式 |
    const undoDom = document.querySelector(".menu-item__undo");
    undoDom.title = `撤销(${isApple ? "⌘" : "Ctrl"}+Z)`;
    undoDom.onclick = function () {
      console.log("undo");
      instance.command.executeUndo();
    };

    const redoDom = document.querySelector(".menu-item__redo");
    redoDom.title = `重做(${isApple ? "⌘" : "Ctrl"}+Y)`;
    redoDom.onclick = function () {
      console.log("redo");
      instance.command.executeRedo();
    };

    const painterDom = document.querySelector(".menu-item__painter");
    painterDom.onclick = function () {
      console.log("painter");
      instance.command.executePainter({
        isDblclick: false,
      });
    };
    painterDom.ondblclick = function () {
      console.log("painter");
      instance.command.executePainter({
        isDblclick: true,
      });
    };

    document.querySelector(".menu-item__format").onclick = function () {
      console.log("format");
      instance.command.executeFormat();
    };

    // 3. | 字体 | 字体变大 | 字体变小 | 加粗 | 斜体 | 下划线 | 删除线 | 上标 | 下标 | 字体颜色 | 背景色 |
    const fontDom = document.querySelector(".menu-item__font");
    const fontSelectDom = fontDom.querySelector(".select");
    const fontOptionDom = fontDom.querySelector(".options");
    fontDom.onclick = function () {
      console.log("font");
      fontOptionDom.classList.toggle("visible");
    };
    fontOptionDom.onclick = function (evt) {
      const li = evt.target;
      instance.command.executeFont(li.dataset.family);
    };

    const sizeSetDom = document.querySelector(".menu-item__size");
    const sizeSelectDom = sizeSetDom.querySelector(".select");
    const sizeOptionDom = sizeSetDom.querySelector(".options");
    sizeSetDom.title = `设置字号`;
    sizeSetDom.onclick = function () {
      console.log("size");
      sizeOptionDom.classList.toggle("visible");
    };
    sizeOptionDom.onclick = function (evt) {
      const li = evt.target;
      instance.command.executeSize(Number(li.dataset.size));
    };

    const sizeAddDom = document.querySelector(".menu-item__size-add");
    sizeAddDom.title = `增大字号(${this.isApple ? "⌘" : "Ctrl"}+[)`;
    sizeAddDom.onclick = function () {
      console.log("size-add");
      instance.command.executeSizeAdd();
    };

    const sizeMinusDom = document.querySelector(".menu-item__size-minus");
    sizeMinusDom.title = `减小字号(${this.isApple ? "⌘" : "Ctrl"}+])`;
    sizeMinusDom.onclick = function () {
      console.log("size-minus");
      instance.command.executeSizeMinus();
    };

    const boldDom = document.querySelector(".menu-item__bold");
    boldDom.title = `加粗(${this.isApple ? "⌘" : "Ctrl"}+B)`;
    boldDom.onclick = function () {
      console.log("bold");
      instance.command.executeBold();
    };

    const italicDom = document.querySelector(".menu-item__italic");
    italicDom.title = `斜体(${this.isApple ? "⌘" : "Ctrl"}+I)`;
    italicDom.onclick = function () {
      console.log("italic");
      instance.command.executeItalic();
    };

    const underlineDom = document.querySelector(".menu-item__underline");
    underlineDom.title = `下划线(${this.isApple ? "⌘" : "Ctrl"}+U)`;
    underlineDom.onclick = function () {
      console.log("underline");
      instance.command.executeUnderline();
    };

    const strikeoutDom = document.querySelector(".menu-item__strikeout");
    strikeoutDom.onclick = function () {
      console.log("strikeout");
      instance.command.executeStrikeout();
    };

    const superscriptDom = document.querySelector(".menu-item__superscript");
    superscriptDom.title = `上标(${this.isApple ? "⌘" : "Ctrl"}+Shift+,)`;
    superscriptDom.onclick = function () {
      console.log("superscript");
      instance.command.executeSuperscript();
    };

    const subscriptDom = document.querySelector(".menu-item__subscript");
    subscriptDom.title = `下标(${this.isApple ? "⌘" : "Ctrl"}+Shift+.)`;
    subscriptDom.onclick = function () {
      console.log("subscript");
      instance.command.executeSubscript();
    };

    const colorDom = document.querySelector('.menu-item__color');
    const colorOptionDom = colorDom.querySelector('.options');
    colorDom.onclick = function() {
      console.log('color');
      colorOptionDom.classList.toggle('visible');
    };
    colorOptionDom.onclick = function(evt) {
      const li = evt.target;
      const color = li.dataset.color;
      if (color) {
        instance.command.executeColor(color);
      }
    };

    // 高亮功能代码
    const highlightDom = document.querySelector('.menu-item__highlight');
    const highlightOptionDom = highlightDom.querySelector('.options');
    highlightDom.onclick = function() {
      console.log('highlight');
      highlightOptionDom.classList.toggle('visible');
    };
    highlightOptionDom.onclick = function(evt) {
      const li = evt.target;
      const color = li.dataset.color;
      if (color) {
        // 如果选择"无"，则清除高亮
        if (color === 'transparent') {
          instance.command.executeHighlight(null);
        } else {
          instance.command.executeHighlight(color);
        }
      }
    };

    const titleDom = document.querySelector(".menu-item__title");
    const titleSelectDom = titleDom.querySelector(".select");
    const titleOptionDom = titleDom.querySelector(".options");
    titleOptionDom.querySelectorAll("li").forEach((li, index) => {
      li.title = `Ctrl+${this.isApple ? "Option" : "Alt"}+${index}`;
    });

    titleDom.onclick = function () {
      console.log("title");
      titleOptionDom.classList.toggle("visible");
    };
    titleOptionDom.onclick = function (evt) {
      const li = evt.target;
      const level = li.dataset.level;
      instance.command.executeTitle(level || null);
    };

    const leftDom = document.querySelector(".menu-item__left");
    leftDom.title = `左对齐(${this.isApple ? "⌘" : "Ctrl"}+L)`;
    leftDom.onclick = function () {
      console.log("left");
      instance.command.executeRowFlex(RowFlex.LEFT);
    };

    const centerDom = document.querySelector(".menu-item__center");
    centerDom.title = `居中对齐(${this.isApple ? "⌘" : "Ctrl"}+E)`;
    centerDom.onclick = function () {
      console.log("center");
      instance.command.executeRowFlex(RowFlex.CENTER);
    };

    const rightDom = document.querySelector(".menu-item__right");
    rightDom.title = `右对齐(${this.isApple ? "⌘" : "Ctrl"}+R)`;
    rightDom.onclick = function () {
      console.log("right");
      instance.command.executeRowFlex(RowFlex.RIGHT);
    };

    const alignmentDom = document.querySelector(".menu-item__alignment");
    alignmentDom.title = `两端对齐(${this.isApple ? "⌘" : "Ctrl"}+J)`;
    alignmentDom.onclick = function () {
      console.log("alignment");
      instance.command.executeRowFlex(RowFlex.ALIGNMENT);
    };

    const rowMarginDom = document.querySelector(".menu-item__row-margin");
    const rowOptionDom = rowMarginDom.querySelector(".options");
    rowMarginDom.onclick = function () {
      console.log("row-margin");
      rowOptionDom.classList.toggle("visible");
    };
    rowOptionDom.onclick = function (evt) {
      const li = evt.target;
      instance.command.executeRowMargin(Number(li.dataset.rowmargin));
    };

    const listDom = document.querySelector(".menu-item__list");
    listDom.title = `列表(${this.isApple ? "⌘" : "Ctrl"}+Shift+U)`;
    const listOptionDom = listDom.querySelector(".options");
    listDom.onclick = function () {
      console.log("list");
      listOptionDom.classList.toggle("visible");
    };
    listOptionDom.onclick = function (evt) {
      const li = evt.target;
      const listType = li.dataset.listType || null;
      const listStyle = li.dataset.listStyle;
      instance.command.executeList(listType, listStyle);
    };

    // 4. | 表格 | 图片 | 超链接 | 分割线 | 水印 | 代码块 | 分隔符 | 控件 | 复选框 | LaTeX | 日期选择器
    const tableDom = document.querySelector(".menu-item__table");
    const tablePanelContainer = document.querySelector(
      ".menu-item__table__collapse"
    );
    const tableClose = document.querySelector(".table-close");
    const tableTitle = document.querySelector(".table-select");
    const tablePanel = document.querySelector(".table-panel");
    // 绘制行列
    const tableCellList = [];
    for (let i = 0; i < 10; i++) {
      const tr = document.createElement("tr");
      tr.classList.add("table-row");
      const trCellList = [];
      for (let j = 0; j < 10; j++) {
        const td = document.createElement("td");
        td.classList.add("table-cel");
        tr.append(td);
        trCellList.push(td);
      }
      tablePanel.append(tr);
      tableCellList.push(trCellList);
    }
    let colIndex = 0;
    let rowIndex = 0;
    // 移除所有格选择
    function removeAllTableCellSelect() {
      tableCellList.forEach((tr) => {
        tr.forEach((td) => td.classList.remove("active"));
      });
    }
    // 设置标题内容
    function setTableTitle(payload) {
      tableTitle.innerText = payload;
    }
    // 恢复初始状态
    function recoveryTable() {
      // 还原选择样式、标题、选择行列
      removeAllTableCellSelect();
      setTableTitle("插入");
      colIndex = 0;
      rowIndex = 0;
      // 隐藏panel
      tablePanelContainer.style.display = "none";
    }
    tableDom.onclick = function () {
      console.log("table");
      tablePanelContainer.style.display = "block";
    };
    tablePanel.onmousemove = function (evt) {
      const celSize = 16;
      const rowMarginTop = 10;
      const celMarginRight = 6;
      const { offsetX, offsetY } = evt;
      // 移除所有选择
      removeAllTableCellSelect();
      colIndex = Math.ceil(offsetX / (celSize + celMarginRight)) || 1;
      rowIndex = Math.ceil(offsetY / (celSize + rowMarginTop)) || 1;
      // 改变选择样式
      tableCellList.forEach((tr, trIndex) => {
        tr.forEach((td, tdIndex) => {
          if (tdIndex < colIndex && trIndex < rowIndex) {
            td.classList.add("active");
          }
        });
      });
      // 改变表格标题
      setTableTitle(`${rowIndex}×${colIndex}`);
    };
    tableClose.onclick = function () {
      recoveryTable();
    };
    tablePanel.onclick = function () {
      // 应用选择
      instance.command.executeInsertTable(rowIndex, colIndex);
      recoveryTable();
    };

    const imageDom = document.querySelector(".menu-item__image");
    const imageFileDom = document.querySelector("#image");
    imageDom.onclick = function () {
      imageFileDom.click();
    };
    imageFileDom.onchange = function () {
      const file = imageFileDom.files[0];
      const fileReader = new FileReader();
      fileReader.readAsDataURL(file);
      fileReader.onload = function () {
        // 计算宽高
        const image = new Image();
        const value = String(fileReader.result);
        image.src = value;
        image.onload = function () {
          instance.command.executeImage({
            value,
            width: image.width,
            height: image.height,
          });
          imageFileDom.value = "";
        };
      };
    };

    const hyperlinkDom = document.querySelector(".menu-item__hyperlink");
    hyperlinkDom.onclick = function () {
      console.log("hyperlink");
      new Dialog({
        title: "超链接",
        data: [
          {
            type: "text",
            label: "文本",
            name: "name",
            required: true,
            placeholder: "请输入文本",
            value: instance.command.getRangeText(),
          },
          {
            type: "text",
            label: "链接",
            name: "url",
            required: true,
            placeholder: "请输入链接",
          },
        ],
        onConfirm: (payload) => {
          const name = payload.find((p) => p.name === "name")?.value;
          if (!name) return;
          const url = payload.find((p) => p.name === "url")?.value;
          if (!url) return;
          instance.command.executeHyperlink({
            type: ElementType.HYPERLINK,
            value: "",
            url,
            valueList: splitText(name).map((n) => ({
              value: n,
              size: 16,
            })),
          });
        },
      });
    };

    const separatorDom = document.querySelector(".menu-item__separator");
    const separatorOptionDom = separatorDom.querySelector(".options");
    separatorDom.onclick = function () {
      console.log("separator");
      separatorOptionDom.classList.toggle("visible");
    };
    separatorOptionDom.onmousedown = function (evt) {
      let payload = [];
      const li = evt.target;
      const separatorDash = li.dataset.separator?.split(",").map(Number);
      if (separatorDash) {
        const isSingleLine = separatorDash.every((d) => d === 0);
        if (!isSingleLine) {
          payload = separatorDash;
        }
      }
      instance.command.executeSeparator(payload);
    };

    // const pageBreakDom = document.querySelector(
    //   '.menu-item__page-break'
    // )
    // pageBreakDom.onclick = function () {
    //   console.log('pageBreak')
    //   instance.command.executePageBreak()
    // }

    // const watermarkDom = document.querySelector(
    //   '.menu-item__watermark'
    // )
    // const watermarkOptionDom =
    //   watermarkDom.querySelector('.options')
    // watermarkDom.onclick = function () {
    //   console.log('watermark')
    //   watermarkOptionDom.classList.toggle('visible')
    // }
    // watermarkOptionDom.onmousedown = function (evt) {
    //   const li = evt.target
    //   const menu = li.dataset.menu
    //   watermarkOptionDom.classList.toggle('visible')
    //   if (menu === 'add') {
    //     new Dialog({
    //       title: '水印',
    //       data: [
    //         {
    //           type: 'text',
    //           label: '内容',
    //           name: 'data',
    //           required: true,
    //           placeholder: '请输入内容'
    //         },
    //         {
    //           type: 'color',
    //           label: '颜色',
    //           name: 'color',
    //           required: true,
    //           value: '#AEB5C0'
    //         },
    //         {
    //           type: 'number',
    //           label: '字体大小',
    //           name: 'size',
    //           required: true,
    //           value: '120'
    //         }
    //       ],
    //       onConfirm: payload => {
    //         const nullableIndex = payload.findIndex(p => !p.value)
    //         if (~nullableIndex) return
    //         const watermark = payload.reduce((pre, cur) => {
    //           pre[cur.name] = cur.value
    //           return pre
    //         }, {})
    //         instance.command.executeAddWatermark({
    //           data: watermark.data,
    //           color: watermark.color,
    //           size: Number(watermark.size)
    //         })
    //       }
    //     })
    //   } else {
    //     instance.command.executeDeleteWatermark()
    //   }
    // }

    // const codeblockDom = document.querySelector(
    //   '.menu-item__codeblock'
    // )
    // codeblockDom.onclick = function () {
    //   console.log('codeblock')
    //   new Dialog({
    //     title: '代码块',
    //     data: [
    //       {
    //         type: 'textarea',
    //         name: 'codeblock',
    //         placeholder: '请输入代码',
    //         width: 500,
    //         height: 300
    //       }
    //     ],
    //     onConfirm: payload => {
    //       const codeblock = payload.find(p => p.name === 'codeblock')?.value
    //       if (!codeblock) return
    //       const tokenList = prism.tokenize(codeblock, prism.languages.javascript)
    //       const formatTokenList = formatPrismToken(tokenList)
    //       const elementList = []
    //       for (let i = 0; i < formatTokenList.length; i++) {
    //         const formatToken = formatTokenList[i]
    //         const tokenStringList = splitText(formatToken.content)
    //         for (let j = 0; j < tokenStringList.length; j++) {
    //           const value = tokenStringList[j]
    //           const element = {
    //             value
    //           }
    //           if (formatToken.color) {
    //             element.color = formatToken.color
    //           }
    //           if (formatToken.bold) {
    //             element.bold = true
    //           }
    //           if (formatToken.italic) {
    //             element.italic = true
    //           }
    //           elementList.push(element)
    //         }
    //       }
    //       elementList.unshift({
    //         value: '\n'
    //       })
    //       instance.command.executeInsertElementList(elementList)
    //     }
    //   })
    // }

    // const controlDom = document.querySelector(
    //   '.menu-item__control'
    // )
    // const controlOptionDom = controlDom.querySelector('.options')
    // controlDom.onclick = function () {
    //   console.log('control')
    //   controlOptionDom.classList.toggle('visible')
    // }
    // controlOptionDom.onmousedown = function (evt) {
    //   controlOptionDom.classList.toggle('visible')
    //   const li = evt.target
    //   const type = li.dataset.control
    //   switch (type) {
    //     case ControlType.TEXT:
    //       new Dialog({
    //         title: '文本控件',
    //         data: [
    //           {
    //             type: 'text',
    //             label: '占位符',
    //             name: 'placeholder',
    //             required: true,
    //             placeholder: '请输入占位符'
    //           },
    //           {
    //             type: 'text',
    //             label: '默认值',
    //             name: 'value',
    //             placeholder: '请输入默认值'
    //           }
    //         ],
    //         onConfirm: payload => {
    //           const placeholder = payload.find(
    //             p => p.name === 'placeholder'
    //           )?.value
    //           if (!placeholder) return
    //           const value = payload.find(p => p.name === 'value')?.value || ''
    //           instance.command.executeInsertElementList([
    //             {
    //               type: ElementType.CONTROL,
    //               value: '',
    //               control: {
    //                 type,
    //                 value: value
    //                   ? [
    //                       {
    //                         value
    //                       }
    //                     ]
    //                   : null,
    //                 placeholder
    //               }
    //             }
    //           ])
    //         }
    //       })
    //       break
    //     case ControlType.SELECT:
    //       new Dialog({
    //         title: '列举控件',
    //         data: [
    //           {
    //             type: 'text',
    //             label: '占位符',
    //             name: 'placeholder',
    //             required: true,
    //             placeholder: '请输入占位符'
    //           },
    //           {
    //             type: 'text',
    //             label: '默认值',
    //             name: 'code',
    //             placeholder: '请输入默认值'
    //           },
    //           {
    //             type: 'textarea',
    //             label: '值集',
    //             name: 'valueSets',
    //             required: true,
    //             height: 100,
    //             placeholder: `请输入值集JSON，例：\n[{\n"value":"有",\n"code":"98175"\n}]`
    //           }
    //         ],
    //         onConfirm: payload => {
    //           const placeholder = payload.find(
    //             p => p.name === 'placeholder'
    //           )?.value
    //           if (!placeholder) return
    //           const valueSets = payload.find(p => p.name === 'valueSets')?.value
    //           if (!valueSets) return
    //           const code = payload.find(p => p.name === 'code')?.value
    //           instance.command.executeInsertElementList([
    //             {
    //               type: ElementType.CONTROL,
    //               value: '',
    //               control: {
    //                 type,
    //                 code,
    //                 value: null,
    //                 placeholder,
    //                 valueSets: JSON.parse(valueSets)
    //               }
    //             }
    //           ])
    //         }
    //       })
    //       break
    //     case ControlType.CHECKBOX:
    //       new Dialog({
    //         title: '复选框控件',
    //         data: [
    //           {
    //             type: 'text',
    //             label: '默认值',
    //             name: 'code',
    //             placeholder: '请输入默认值，多个值以英文逗号分割'
    //           },
    //           {
    //             type: 'textarea',
    //             label: '值集',
    //             name: 'valueSets',
    //             required: true,
    //             height: 100,
    //             placeholder: `请输入值集JSON，例：\n[{\n"value":"有",\n"code":"98175"\n}]`
    //           }
    //         ],
    //         onConfirm: payload => {
    //           const valueSets = payload.find(p => p.name === 'valueSets')?.value
    //           if (!valueSets) return
    //           const code = payload.find(p => p.name === 'code')?.value
    //           instance.command.executeInsertElementList([
    //             {
    //               type: ElementType.CONTROL,
    //               value: '',
    //               control: {
    //                 type,
    //                 code,
    //                 value: null,
    //                 valueSets: JSON.parse(valueSets)
    //               }
    //             }
    //           ])
    //         }
    //       })
    //       break
    //     default:
    //       break
    //   }
    // }

    // const checkboxDom = document.querySelector(
    //   '.menu-item__checkbox'
    // )
    // checkboxDom.onclick = function () {
    //   console.log('checkbox')
    //   instance.command.executeInsertElementList([
    //     {
    //       type: ElementType.CHECKBOX,
    //       checkbox: {
    //         value: false
    //       },
    //       value: ''
    //     }
    //   ])
    // }

    // const latexDom = document.querySelector('.menu-item__latex')
    // latexDom.onclick = function () {
    //   console.log('LaTeX')
    //   new Dialog({
    //     title: 'LaTeX',
    //     data: [
    //       {
    //         type: 'textarea',
    //         height: 100,
    //         name: 'value',
    //         placeholder: '请输入LaTeX文本'
    //       }
    //     ],
    //     onConfirm: payload => {
    //       const value = payload.find(p => p.name === 'value')?.value
    //       if (!value) return
    //       instance.command.executeInsertElementList([
    //         {
    //           type: ElementType.LATEX,
    //           value
    //         }
    //       ])
    //     }
    //   })
    // }

    // const dateDom = document.querySelector('.menu-item__date')
    // const dateDomOptionDom = dateDom.querySelector('.options')
    // dateDom.onclick = function () {
    //   console.log('date')
    //   dateDomOptionDom.classList.toggle('visible')
    //   // 定位调整
    //   const bodyRect = document.body.getBoundingClientRect()
    //   const dateDomOptionRect = dateDomOptionDom.getBoundingClientRect()
    //   if (dateDomOptionRect.left + dateDomOptionRect.width > bodyRect.width) {
    //     dateDomOptionDom.style.right = '0px'
    //     dateDomOptionDom.style.left = 'unset'
    //   } else {
    //     dateDomOptionDom.style.right = 'unset'
    //     dateDomOptionDom.style.left = '0px'
    //   }
    //   // 当前日期
    //   const date = new Date()
    //   const year = date.getFullYear().toString()
    //   const month = (date.getMonth() + 1).toString().padStart(2, '0')
    //   const day = date.getDate().toString().padStart(2, '0')
    //   const hour = date.getHours().toString().padStart(2, '0')
    //   const minute = date.getMinutes().toString().padStart(2, '0')
    //   const second = date.getSeconds().toString().padStart(2, '0')
    //   const dateString = `${year}-${month}-${day}`
    //   const dateTimeString = `${dateString} ${hour}:${minute}:${second}`
    //   dateDomOptionDom.querySelector('li:first-child').innerText = dateString
    //   dateDomOptionDom.querySelector('li:last-child').innerText = dateTimeString
    // }
    // dateDomOptionDom.onmousedown = function (evt) {
    //   const li = evt.target
    //   const dateFormat = li.dataset.format
    //   dateDomOptionDom.classList.toggle('visible')
    //   instance.command.executeInsertElementList([
    //     {
    //       type: ElementType.DATE,
    //       value: '',
    //       dateFormat,
    //       valueList: [
    //         {
    //           value: li.innerText.trim()
    //         }
    //       ]
    //     }
    //   ])
    // }

    // const blockDom = document.querySelector('.menu-item__block')
    // blockDom.onclick = function () {
    //   console.log('block')
    //   new Dialog({
    //     title: '内容块',
    //     data: [
    //       {
    //         type: 'select',
    //         label: '类型',
    //         name: 'type',
    //         value: 'iframe',
    //         required: true,
    //         options: [
    //           {
    //             label: '网址',
    //             value: 'iframe'
    //           },
    //           {
    //             label: '视频',
    //             value: 'video'
    //           }
    //         ]
    //       },
    //       {
    //         type: 'number',
    //         label: '宽度',
    //         name: 'width',
    //         placeholder: '请输入宽度（默认页面内宽度）'
    //       },
    //       {
    //         type: 'number',
    //         label: '高度',
    //         name: 'height',
    //         required: true,
    //         placeholder: '请输入高度'
    //       },
    //       {
    //         type: 'textarea',
    //         label: '地址',
    //         height: 100,
    //         name: 'value',
    //         required: true,
    //         placeholder: '请输入地址'
    //       }
    //     ],
    //     onConfirm: payload => {
    //       const type = payload.find(p => p.name === 'type')?.value
    //       if (!type) return
    //       const value = payload.find(p => p.name === 'value')?.value
    //       if (!value) return
    //       const width = payload.find(p => p.name === 'width')?.value
    //       const height = payload.find(p => p.name === 'height')?.value
    //       if (!height) return
    //       const block = {
    //         type: null
    //       }
    //       if (block.type === BlockType.IFRAME) {
    //         block.iframeBlock = {
    //           src: value
    //         }
    //       } else if (block.type === BlockType.VIDEO) {
    //         block.videoBlock = {
    //           src: value
    //         }
    //       }
    //       const blockElemen = {
    //         type: ElementType.BLOCK,
    //         value: '',
    //         height: Number(height),
    //         block
    //       }
    //       if (width) {
    //         blockElement.width = Number(width)
    //       }
    //       instance.command.executeInsertElementList([blockElement])
    //     }
    //   })
    // }

    // 5. | 搜索&替换 | 打印 |
    const searchCollapseDom = document.querySelector(
      ".menu-item__search__collapse"
    );
    const searchInputDom = document.querySelector(
      ".menu-item__search__collapse__search input"
    );
    const replaceInputDom = document.querySelector(
      ".menu-item__search__collapse__replace input"
    );
    const searchDom = document.querySelector(".menu-item__search");
    searchDom.title = `搜索与替换(${isApple ? "⌘" : "Ctrl"}+F)`;
    const searchResultDom = searchCollapseDom.querySelector(".search-result");
    function setSearchResult() {
      const result = instance.command.getSearchNavigateInfo();
      if (result) {
        const { index, count } = result;
        searchResultDom.innerText = `${index}/${count}`;
      } else {
        searchResultDom.innerText = "";
      }
    }
    searchDom.onclick = function () {
      console.log("search");
      searchCollapseDom.style.display = "block";
      const bodyRect = document.body.getBoundingClientRect();
      const searchRect = searchDom.getBoundingClientRect();
      const searchCollapseRect = searchCollapseDom.getBoundingClientRect();
      if (searchRect.left + searchCollapseRect.width > bodyRect.width) {
        searchCollapseDom.style.right = "0px";
        searchCollapseDom.style.left = "unset";
      } else {
        searchCollapseDom.style.right = "unset";
      }
      searchInputDom.focus();
    };
    searchCollapseDom.querySelector("span").onclick = function () {
      searchCollapseDom.style.display = "none";
      searchInputDom.value = "";
      replaceInputDom.value = "";
      instance.command.executeSearch(null);
      setSearchResult();
    };
    searchInputDom.oninput = function () {
      instance.command.executeSearch(searchInputDom.value || null);
      setSearchResult();
    };
    searchInputDom.onkeydown = function (evt) {
      if (evt.key === "Enter") {
        instance.command.executeSearch(searchInputDom.value || null);
        setSearchResult();
      }
    };
    searchCollapseDom.querySelector("button").onclick = function () {
      const searchValue = searchInputDom.value;
      const replaceValue = replaceInputDom.value;
      if (searchValue && replaceValue && searchValue !== replaceValue) {
        instance.command.executeReplace(replaceValue);
      }
    };
    searchCollapseDom.querySelector(".arrow-left").onclick = function () {
      instance.command.executeSearchNavigatePre();
      setSearchResult();
    };
    searchCollapseDom.querySelector(".arrow-right").onclick = function () {
      instance.command.executeSearchNavigateNext();
      setSearchResult();
    };

    // const printDom = document.querySelector('.menu-item__print')
    // printDom.title = `打印(${isApple ? '⌘' : 'Ctrl'}+P)`
    // printDom.onclick = function () {
    //   console.log('print')
    //   instance.command.executePrint()
    // }

    // 6. 目录显隐 | 页面模式 | 纸张缩放 | 纸张大小 | 纸张方向 | 页边距 | 全屏
    // async function updateCatalog() {
    //   const catalog = await instance.command.getCatalog()
    //   const catalogMainDom =
    //     document.querySelector('.catalog__main')
    //   catalogMainDom.innerHTML = ''
    //   if (catalog) {
    //     const appendCatalog = (
    //       parent,
    //       catalogItems
    //     ) => {
    //       for (let c = 0; c < catalogItems.length; c++) {
    //         const catalogItem = catalogItems[c]
    //         const catalogItemDom = document.createElement('div')
    //         catalogItemDom.classList.add('catalog-item')
    //         // 渲染
    //         const catalogItemContentDom = document.createElement('div')
    //         catalogItemContentDom.classList.add('catalog-item__content')
    //         const catalogItemContentSpanDom = document.createElement('span')
    //         catalogItemContentSpanDom.innerText = catalogItem.name
    //         catalogItemContentDom.append(catalogItemContentSpanDom)
    //         // 定位
    //         catalogItemContentDom.onclick = () => {
    //           instance.command.executeLocationCatalog(catalogItem.id)
    //         }
    //         catalogItemDom.append(catalogItemContentDom)
    //         if (catalogItem.subCatalog && catalogItem.subCatalog.length) {
    //           appendCatalog(catalogItemDom, catalogItem.subCatalog)
    //         }
    //         // 追加
    //         parent.append(catalogItemDom)
    //       }
    //     }
    //     appendCatalog(catalogMainDom, catalog)
    //   }
    // }
    // let isCatalogShow = true
    // const catalogDom = document.querySelector('.catalog')
    // const catalogModeDom =
    //   document.querySelector('.catalog-mode')
    // const catalogHeaderCloseDom = document.querySelector(
    //   '.catalog__header__close'
    // )
    // const switchCatalog = () => {
    //   console.log('目录', isCatalogShow)
    //   isCatalogShow = !isCatalogShow
    //   if (isCatalogShow) {
    //     console.log('目录', isCatalogShow)
    //     catalogDom.style.display = 'block'
    //     updateCatalog()
    //   } else {
    //     catalogDom.style.display = 'none'
    //   }
    // }
    // catalogModeDom.onclick = switchCatalog
    // catalogHeaderCloseDom.onclick = switchCatalog

    const pageModeDom = document.querySelector(".page-mode");
    const pageModeOptionsDom = pageModeDom.querySelector(".options");
    pageModeDom.onclick = function () {
      pageModeOptionsDom.classList.toggle("visible");
    };
    pageModeOptionsDom.onclick = function (evt) {
      const li = evt.target;
      instance.command.executePageMode(li.dataset.pageMode);
    };

    document.querySelector(".page-scale-percentage").onclick = function () {
      console.log("page-scale-recovery");
      instance.command.executePageScaleRecovery();
    };

    document.querySelector(".page-scale-minus").onclick = function () {
      console.log("page-scale-minus");
      instance.command.executePageScaleMinus();
    };

    document.querySelector(".page-scale-add").onclick = function () {
      console.log("page-scale-add");
      instance.command.executePageScaleAdd();
    };

    // 纸张大小
    const paperSizeDom = document.querySelector(".paper-size");
    const paperSizeDomOptionsDom = paperSizeDom.querySelector(".options");
    paperSizeDom.onclick = function () {
      paperSizeDomOptionsDom.classList.toggle("visible");
    };
    paperSizeDomOptionsDom.onclick = function (evt) {
      const li = evt.target;
      const paperType = li.dataset.paperSize;
      const [width, height] = paperType.split("*").map(Number);
      instance.command.executePaperSize(width, height);
      // 纸张状态回显
      paperSizeDomOptionsDom
        .querySelectorAll("li")
        .forEach((child) => child.classList.remove("active"));
      li.classList.add("active");
    };

    // 纸张方向
    const paperDirectionDom = document.querySelector(".paper-direction");
    const paperDirectionDomOptionsDom =
      paperDirectionDom.querySelector(".options");
    paperDirectionDom.onclick = function () {
      paperDirectionDomOptionsDom.classList.toggle("visible");
    };
    paperDirectionDomOptionsDom.onclick = function (evt) {
      const li = evt.target;
      const paperDirection = li.dataset.paperDirection;
      instance.command.executePaperDirection(paperDirection);
      // 纸张方向状态回显
      paperDirectionDomOptionsDom
        .querySelectorAll("li")
        .forEach((child) => child.classList.remove("active"));
      li.classList.add("active");
    };

    // 页面边距
    const paperMarginDom = document.querySelector(".paper-margin");
    paperMarginDom.onclick = function () {
      const [topMargin, rightMargin, bottomMargin, leftMargin] =
        instance.command.getPaperMargin();
      new Dialog({
        title: "页边距",
        data: [
          {
            type: "text",
            label: "上边距",
            name: "top",
            required: true,
            value: `${topMargin}`,
            placeholder: "请输入上边距",
          },
          {
            type: "text",
            label: "下边距",
            name: "bottom",
            required: true,
            value: `${bottomMargin}`,
            placeholder: "请输入下边距",
          },
          {
            type: "text",
            label: "左边距",
            name: "left",
            required: true,
            value: `${leftMargin}`,
            placeholder: "请输入左边距",
          },
          {
            type: "text",
            label: "右边距",
            name: "right",
            required: true,
            value: `${rightMargin}`,
            placeholder: "请输入右边距",
          },
        ],
        onConfirm: (payload) => {
          const top = payload.find((p) => p.name === "top")?.value;
          if (!top) return;
          const bottom = payload.find((p) => p.name === "bottom")?.value;
          if (!bottom) return;
          const left = payload.find((p) => p.name === "left")?.value;
          if (!left) return;
          const right = payload.find((p) => p.name === "right")?.value;
          if (!right) return;
          instance.command.executeSetPaperMargin([
            Number(top),
            Number(right),
            Number(bottom),
            Number(left),
          ]);
        },
      });
    };

    // 全屏
    const fullscreenDom = document.querySelector(".fullscreen");
    fullscreenDom.onclick = toggleFullscreen;
    window.addEventListener("keydown", (evt) => {
      if (evt.key === "F11") {
        toggleFullscreen();
        evt.preventDefault();
      }
    });
    document.addEventListener("fullscreenchange", () => {
      fullscreenDom.classList.toggle("exist");
    });
    function toggleFullscreen() {
      console.log("fullscreen");
      if (!document.fullscreenElement) {
        document.documentElement.requestFullscreen();
      } else {
        document.exitFullscreen();
      }
    }

    // 7. 编辑器使用模式
    let modeIndex = 1;
    const modeList = [
      {
        mode: EditorMode.READONLY,
        name: "只读模式",
      },
      {
        mode: EditorMode.EDIT,
        name: "编辑模式",
      },
      {
        mode: EditorMode.CLEAN,
        name: "清洁模式",
      },

      {
        mode: EditorMode.FORM,
        name: "表单模式",
      },
      {
        mode: EditorMode.PRINT,
        name: "打印模式",
      },
    ];
    const modeElement = document.querySelector(".editor-mode");
    // 初始设置只读模式
    const { name, mode } = modeList[modeIndex];
    modeElement.innerText = name;
    instance.command.executeMode(mode);
    // 设置菜单栏权限视觉反馈
    const isReadonly = mode === EditorMode.READONLY;
    const enableMenuList = ["search", "print"];
    document.querySelectorAll(".menu-item>div").forEach((dom) => {
      const menu = dom.dataset.menu;
      isReadonly && (!menu || !enableMenuList.includes(menu))
        ? dom.classList.add("disable")
        : dom.classList.remove("disable");
    });
    modeElement.onclick = function () {
      // 模式选择循环
      modeIndex === modeList.length - 1 ? (modeIndex = 0) : modeIndex++;
      // 设置模式
      const { name, mode } = modeList[modeIndex];
      modeElement.innerText = name;
      console.log(1212, name);
      instance.command.executeMode(mode);
      // 设置菜单栏权限视觉反馈
      const isReadonly = mode === EditorMode.READONLY;
      const enableMenuList = ["search", "print"];
      document.querySelectorAll(".menu-item>div").forEach((dom) => {
        const menu = dom.dataset.menu;
        isReadonly && (!menu || !enableMenuList.includes(menu))
          ? dom.classList.add("disable")
          : dom.classList.remove("disable");
      });
    };

    // 模拟批注
    // const commentDom = document.querySelector('.comment')
    // const updateComment = async() => {
    //   const groupIds = await instance.command.getGroupIds()
    //   for (const comment of this.commentList) {
    //     const activeCommentDom = commentDom.querySelector(
    //       `.comment-item[data-id='${comment.id}']`
    //     )
    //     // 编辑器是否存在对应成组id
    //     if (!groupIds.includes(comment.id)) {
    //       // 当前dom是否存在-不存在则追加
    //       if (!activeCommentDom) {
    //         const commentItem = document.createElement('div')
    //         commentItem.classList.add('comment-item')
    //         commentItem.setAttribute('data-id', comment.id)
    //         commentItem.onclick = () => {
    //           instance.command.executeLocationGroup(comment.id)
    //         }
    //         commentDom.append(commentItem)
    //         // 选区信息
    //         const commentItemTitle = document.createElement('div')
    //         commentItemTitle.classList.add('comment-item__title')
    //         commentItemTitle.append(document.createElement('span'))
    //         const commentItemTitleContent = document.createElement('span')
    //         commentItemTitleContent.innerText = comment.rangeText
    //         commentItemTitle.append(commentItemTitleContent)
    //         const closeDom = document.createElement('i')
    //         closeDom.onclick = () => {
    //           instance.command.executeDeleteGroup(comment.id)
    //         }
    //         commentItemTitle.append(closeDom)
    //         commentItem.append(commentItemTitle)
    //         // 基础信息
    //         const commentItemInfo = document.createElement('div')
    //         commentItemInfo.classList.add('comment-item__info')
    //         const commentItemInfoName = document.createElement('span')
    //         commentItemInfoName.innerText = comment.userName
    //         const commentItemInfoDate = document.createElement('span')
    //         commentItemInfoDate.innerText = comment.createdDate
    //         commentItemInfo.append(commentItemInfoName)
    //         commentItemInfo.append(commentItemInfoDate)
    //         commentItem.append(commentItemInfo)
    //         // 详细评论
    //         const commentItemContent = document.createElement('div')
    //         commentItemContent.classList.add('comment-item__content')
    //         commentItemContent.innerText = comment.content
    //         commentItem.append(commentItemContent)
    //         commentDom.append(commentItem)
    //       }
    //     } else {
    //       // 编辑器内不存在对应成组id则dom则移除
    //       activeCommentDom?.remove()
    //     }
    //   }
    // }
    // 8. 内部事件监听
    instance.listener.rangeStyleChange = function (payload) {
      // 控件类型
      payload.type === ElementType.SUBSCRIPT
        ? subscriptDom.classList.add("active")
        : subscriptDom.classList.remove("active");
      payload.type === ElementType.SUPERSCRIPT
        ? superscriptDom.classList.add("active")
        : superscriptDom.classList.remove("active");
      payload.type === ElementType.SEPARATOR
        ? separatorDom.classList.add("active")
        : separatorDom.classList.remove("active");
      separatorOptionDom
        .querySelectorAll("li")
        .forEach((li) => li.classList.remove("active"));
      if (payload.type === ElementType.SEPARATOR) {
        const separator = payload.dashArray.join(",") || "0,0";
        const curSeparatorDom = separatorOptionDom.querySelector(
          `[data-separator='${separator}']`
        );
        if (curSeparatorDom) {
          curSeparatorDom.classList.add("active");
        }
      }

      // 富文本
      fontOptionDom
        .querySelectorAll("li")
        .forEach((li) => li.classList.remove("active"));
      const curFontDom = fontOptionDom.querySelector(
        `[data-family='${payload.font}']`
      );
      if (curFontDom) {
        fontSelectDom.innerText = curFontDom.innerText;
        fontSelectDom.style.fontFamily = payload.font;
        curFontDom.classList.add("active");
      }
      sizeOptionDom
        .querySelectorAll("li")
        .forEach((li) => li.classList.remove("active"));
      const curSizeDom = sizeOptionDom.querySelector(
        `[data-size='${payload.size}']`
      );
      if (curSizeDom) {
        sizeSelectDom.innerText = curSizeDom.innerText;
        curSizeDom.classList.add("active");
      } else {
        sizeSelectDom.innerText = `${payload.size}`;
      }
      payload.bold
        ? boldDom.classList.add("active")
        : boldDom.classList.remove("active");
      payload.italic
        ? italicDom.classList.add("active")
        : italicDom.classList.remove("active");
      payload.underline
        ? underlineDom.classList.add("active")
        : underlineDom.classList.remove("active");
      payload.strikeout
        ? strikeoutDom.classList.add("active")
        : strikeoutDom.classList.remove("active");
      if (payload.color) {
        colorDom.classList.add("active");
        const colorSpan = colorDom.querySelector('span');
        if (colorSpan) {
          colorSpan.style.backgroundColor = payload.color;
        }
      } else {
        colorDom.classList.remove("active");
        const colorSpan = colorDom.querySelector('span');
        if (colorSpan) {
          colorSpan.style.backgroundColor = "#000000";
        }
      }
      if (payload.highlight) {
        highlightDom.classList.add("active");
      } else {
        highlightDom.classList.remove("active");
      }

      // 行布局
      leftDom.classList.remove("active");
      centerDom.classList.remove("active");
      rightDom.classList.remove("active");
      alignmentDom.classList.remove("active");
      if (payload.rowFlex && payload.rowFlex === "right") {
        rightDom.classList.add("active");
      } else if (payload.rowFlex && payload.rowFlex === "center") {
        centerDom.classList.add("active");
      } else if (payload.rowFlex && payload.rowFlex === "alignment") {
        alignmentDom.classList.add("active");
      } else {
        leftDom.classList.add("active");
      }

      // 行间距
      rowOptionDom
        .querySelectorAll("li")
        .forEach((li) => li.classList.remove("active"));
      const curRowMarginDom = rowOptionDom.querySelector(
        `[data-rowmargin='${payload.rowMargin}']`
      );
      curRowMarginDom.classList.add("active");

      // 功能
      payload.undo
        ? undoDom.classList.remove("no-allow")
        : undoDom.classList.add("no-allow");
      payload.redo
        ? redoDom.classList.remove("no-allow")
        : redoDom.classList.add("no-allow");
      payload.painter
        ? painterDom.classList.add("active")
        : painterDom.classList.remove("active");

      // 标题
      titleOptionDom
        .querySelectorAll("li")
        .forEach((li) => li.classList.remove("active"));
      if (payload.level) {
        const curTitleDom = titleOptionDom.querySelector(
          `[data-level='${payload.level}']`
        );
        titleSelectDom.innerText = curTitleDom.innerText;
        curTitleDom.classList.add("active");
      } else {
        titleSelectDom.innerText = "正文";
        titleOptionDom.querySelector("li:first-child").classList.add("active");
      }

      // 列表
      listOptionDom
        .querySelectorAll("li")
        .forEach((li) => li.classList.remove("active"));
      if (payload.listType) {
        listDom.classList.add("active");
        const listType = payload.listType;
        const listStyle =
          payload.listType === ListType.OL
            ? ListStyle.DECIMAL
            : payload.listType;
        const curListDom = listOptionDom.querySelector(
          `[data-list-type='${listType}'][data-list-style='${listStyle}']`
        );
        if (curListDom) {
          curListDom.classList.add("active");
        }
      } else {
        listDom.classList.remove("active");
      }

      // 批注
      // commentDom
      //   .querySelectorAll('.comment-item')
      //   .forEach(commentItemDom => {
      //     commentItemDom.classList.remove('active')
      //   })
      // if (payload.groupIds) {
      //   const [id] = payload.groupIds
      //   const activeCommentDom = commentDom.querySelector(
      //     `.comment-item[data-id='${id}']`
      //   )
      //   if (activeCommentDom) {
      //     activeCommentDom.classList.add('active')
      //     scrollIntoView(commentDom, activeCommentDom)
      //   }
      // }
    };

    instance.listener.visiblePageNoListChange = function (payload) {
      const text = payload.map((i) => i + 1).join("、");
      document.querySelector(".page-no-list").innerText = text;
    };

    instance.listener.pageSizeChange = function (payload) {
      if (document.querySelector(".page-size")) {
        document.querySelector(".page-size").innerText = payload.toString();
      }
    };

    instance.listener.intersectionPageNoChange = function (payload) {
      document.querySelector(".page-no").innerText = `${payload + 1}`;
    };

    instance.listener.pageScaleChange = function (payload) {
      document.querySelector(
        ".page-scale-percentage"
      ).innerText = `${Math.floor(payload * 10 * 10)}%`;
    };

    instance.listener.controlChange = function (payload) {
      const disableMenusInControlContext = [
        "table",
        "hyperlink",
        "separator",
        "page-break",
      ];
      // 菜单操作权限
      disableMenusInControlContext.forEach((menu) => {
        const menuDom = document.querySelector(`.menu-item__${menu}`);
        payload
          ? menuDom.classList.add("disable")
          : menuDom.classList.remove("disable");
      });
    };

    instance.listener.pageModeChange = function (payload) {
      const activeMode = pageModeOptionsDom.querySelector(
        `[data-page-mode='${payload}']`
      );
      pageModeOptionsDom
        .querySelectorAll("li")
        .forEach((li) => li.classList.remove("active"));
      activeMode.classList.add("active");
    };

    const handleContentChange = async () => {
      this.$emit("isSave", true);
      // 字数
      const wordCount = await instance.command.getWordCount();
      document.querySelector(".word-count").innerText = `${wordCount || 0}`;
      // 目录
      // if (isCatalogShow) {
      //   this.$nextTick(() => {
      //     updateCatalog()
      //   })
      // }
      // // 批注
      // this.$nextTick(() => {
      //   updateComment()
      // })
    };
    instance.listener.contentChange = this.debounce(handleContentChange, 200);
    handleContentChange();

    // 9. 右键菜单注册
    instance.register.contextMenuList([
      {
        name: "批注",
        when: (payload) => {
          return (
            !payload.isReadonly &&
            payload.editorHasSelection &&
            payload.zone === EditorZone.MAIN
          );
        },
        callback: (command) => {
          new Dialog({
            title: "批注",
            data: [
              {
                type: "textarea",
                label: "批注",
                height: 100,
                name: "value",
                required: true,
                placeholder: "请输入批注",
              },
            ],
            onConfirm: (payload) => {
              const value = payload.find((p) => p.name === "value")?.value;
              if (!value) return;
              const groupId = command.executeSetGroup();
              if (!groupId) return;
              commentList.push({
                id: groupId,
                content: value,
                userName: "Hufe",
                rangeText: command.getRangeText(),
                createdDate: new Date().toLocaleString(),
              });
            },
          });
        },
      },
      {
        name: "签名",
        icon: "signature",
        when: (payload) => {
          return !payload.isReadonly && payload.editorTextFocus;
        },
        callback: (command) => {
          new Signature({
            onConfirm(payload) {
              if (!payload) return;
              const { value, width, height } = payload;
              if (!value || !width || !height) return;
              command.executeInsertElementList([
                {
                  value,
                  width,
                  height,
                  type: ElementType.IMAGE,
                },
              ]);
            },
          });
        },
      },
      {
        name: "格式整理",
        icon: "word-tool",
        when: (payload) => {
          return !payload.isReadonly;
        },
        callback: (command) => {
          command.executeWordTool();
        },
      },
    ]);

    // 10. 快捷键注册
    instance.register.shortcutList([
      {
        key: KeyMap.P,
        mod: true,
        isGlobal: true,
        callback: (command) => {
          command.executePrint();
        },
      },
      {
        key: KeyMap.F,
        mod: true,
        isGlobal: true,
        callback: (command) => {
          const text = command.getRangeText();
          searchDom.click();
          if (text) {
            searchInputDom.value = text;
            instance.command.executeSearch(text);
            setSearchResult();
          }
        },
      },
      {
        key: KeyMap.MINUS,
        ctrl: true,
        isGlobal: true,
        callback: (command) => {
          command.executePageScaleMinus();
        },
      },
      {
        key: KeyMap.EQUAL,
        ctrl: true,
        isGlobal: true,
        callback: (command) => {
          command.executePageScaleAdd();
        },
      },
      {
        key: KeyMap.ZERO,
        ctrl: true,
        isGlobal: true,
        callback: (command) => {
          command.executePageScaleRecovery();
        },
      },
    ]);
  },
};
</script>

<style lang="scss" >
@import url("./components/dialog/dialog.css");
@import url("./components/signature/signature.css");
/*  @import url("./styles.scss");  */
.canvas-editor-wrapper {
  position: relative;
  height: 100%; // 添加固定高度
  overflow: hidden; // 防止内容溢出
  .canvas-container {
    .footer {
      position: static;
    }
    .menu {
      position: absolute;
      top: 0;
      left: 0;
    }
    .el-footer {
      background-color: #f2f4f7;
      text-align: center;
      line-height: 30px !important; /* 调整footer高度 */
    }
    .content {
      position: static;
      display: flex;
      flex-direction: column;
      max-height: 600px;//calc(100% - 90px); /* 减去header和footer的高度 */
      background-color: #f2f4f7;
      overflow: auto; /* 仅让Main区域可滚动 */
      flex-grow: 1; /* 让Main区域占据剩余空间 */
    }
    @media (max-width: 1220px) {
      .menu {
        display: flex;
        align-items: center;
        flex-wrap: wrap;
        justify-content: flex-start;
      }
    }
    #canvasEditor {
      display: flex;
      justify-content: center;
      background: #f2f4f7;
    }
    .el-header {
      position: relative;
    }
    .canvas-container {
      height: 100%;
      margin-top: 10px;
    }
    ::-webkit-scrollbar {
      height: 16px;
      width: 16px;
      overflow: visible;
    }

    ::-webkit-scrollbar-button {
      width: 0;
      height: 0;
    }

    ::-webkit-scrollbar-corner {
      background: transparent;
    }

    ::-webkit-scrollbar-thumb {
      background-color: #ddd;
      background-clip: padding-box;
      border: 4px solid #f2f4f7;
      border-radius: 8px;
      min-height: 24px;
    }

    ::-webkit-scrollbar-thumb:hover {
      background-color: #c9c9c9;
    }

    ::-webkit-scrollbar-track {
      background: #f2f4f7;
      background-clip: padding-box;
    }

    * {
      margin: 0;
      padding: 0;
    }

    ul {
      list-style: none;
    }

    .menu {
      width: 100%;
      height: 60px;
      top: 0;
      z-index: 9;
      position: absolute;
      display: flex;
      align-items: center;
      justify-content: center;
      background: #f2f4f7;
      box-shadow: 0 2px 4px 0 transparent;
    }

    .menu-divider {
      width: 1px;
      height: 16px;
      margin: 0 8px;
      display: inline-block;
      background-color: #cfd2d8;
    }

    .menu-item {
      height: 24px;
      display: flex;
      align-items: center;
      position: relative;
    }

    .menu-item > div {
      width: 24px;
      height: 24px;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      margin: 0 2px;
    }

    .menu-item > div:hover {
      background: rgba(25, 55, 88, 0.04);
    }

    .menu-item > div.active {
      background: rgba(25, 55, 88, 0.08);
    }

    .menu-item i {
      width: 16px;
      height: 16px;
      display: inline-block;
      background-repeat: no-repeat;
      background-size: 100% 100%;
    }

    .menu-item > div > span {
      width: 16px;
      height: 3px;
      display: inline-block;
      border: 1px solid #e2e6ed;
    }

    .menu-item .select {
      border: none;
      font-size: 12px;
      line-height: 24px;
      user-select: none;
    }

    .menu-item .select::after {
      position: absolute;
      content: "";
      top: 11px;
      width: 0;
      height: 0;
      right: 2px;
      border-color: #767c85 transparent transparent;
      border-style: solid solid none;
      border-width: 3px 3px 0;
    }

    .menu-item .options {
      width: 70px;
      position: absolute;
      //left: 0;
      top: 25px;
      padding: 10px;
      background: #fff;
      font-size: 14px;
      box-shadow: 0 2px 12px 0 rgb(56 56 56 / 20%);
      border: 1px solid #e2e6ed;
      border-radius: 2px;
      display: none;
    }

    .menu-item .options.visible {
      display: block;
    }

    .menu-item .options li {
      padding: 5px;
      margin: 5px 0;
      user-select: none;
      transition: all 0.3s;
    }

    .menu-item .options li:hover {
      background-color: #ebecef;
    }

    .menu-item .options li.active {
      background-color: #e2e6ed;
    }

    .menu-item .menu-item__font {
      width: 65px;
      position: relative;
    }

    .menu-item .menu-item__size {
      width: 50px;
      text-align: center;
      position: relative;
    }

    .menu-item__font .select,
    .menu-item__size .select {
      width: 100%;
      height: 100%;
    }

    .menu-item__undo.no-allow,
    .menu-item__redo.no-allow,
    .menu-item > div.disable {
      color: #c0c4cc;
      cursor: not-allowed;
      opacity: 0.4;
      pointer-events: none;
    }

    .menu-item__undo i {
      background-image: url("./assets/images/undo.svg");
    }

    .menu-item__redo i {
      background-image: url("./assets/images/redo.svg");
    }

    .menu-item__painter i {
      background-image: url("./assets/images/painter.svg");
    }

    .menu-item__format i {
      background-image: url("./assets/images/format.svg");
    }

    .menu-item__size-add i {
      background-image: url("./assets/images/size-add.svg");
    }

    .menu-item__size-minus i {
      background-image: url("./assets/images/size-minus.svg");
    }

    .menu-item__bold i {
      background-image: url("./assets/images/bold.svg");
    }

    .menu-item__italic i {
      background-image: url("./assets/images/italic.svg");
    }

    .menu-item .menu-item__underline {
      width: 30px;
      position: relative;
    }

    .menu-item__underline > i {
      flex-shrink: 0;
      background-image: url("./assets/images/underline.svg");
    }

    .menu-item__underline .select {
      width: 100%;
      height: 100%;
    }

    .menu-item .menu-item__underline .options {
      width: 128px;
    }

    .menu-item .menu-item__underline li {
      padding: 1px 5px;
    }

    .menu-item__underline li i {
      pointer-events: none;
    }

    .menu-item__underline li[data-decoration-style="solid"] {
      background-image: url("./assets/images/line-single.svg");
    }

    .menu-item__underline li[data-decoration-style="double"] {
      background-image: url("./assets/images/line-double.svg");
    }

    .menu-item__underline li[data-decoration-style="dashed"] {
      background-image: url("./assets/images/line-dash-small-gap.svg");
    }

    .menu-item__underline li[data-decoration-style="dotted"] {
      background-image: url("./assets/images/line-dot.svg");
    }

    .menu-item__underline li[data-decoration-style="wavy"] {
      background-image: url("./assets/images/line-wavy.svg");
    }

    .menu-item__strikeout i {
      background-image: url("./assets/images/strikeout.svg");
    }

    .menu-item__superscript i {
      background-image: url("./assets/images/superscript.svg");
    }

    .menu-item__subscript i {
      background-image: url("./assets/images/subscript.svg");
    }

    .menu-item__color,
    .menu-item__highlight {
      display: flex;
      flex-direction: column;
    }

    .menu-item__color #color,
    .menu-item__highlight #highlight {
      width: 1px;
      height: 1px;
      visibility: hidden;
      outline: none;
      appearance: none;
    }

    .menu-item__color i {
      background-image: url("./assets/images/color.svg");
    }

    .menu-item__color span {
      background-color: #000000;
    }

    .menu-item__highlight i {
      background-image: url("./assets/images/highlight.svg");
    }

    .menu-item__highlight span {
      background-color: #ffff00;
    }

    .menu-item .menu-item__title {
      width: 60px;
      position: relative;
    }

    .menu-item__title .select {
      width: calc(100% - 20px);
      height: 100%;
    }

    .menu-item__title i {
      transform: translateX(-5px);
      background-image: url("./assets/images/title.svg");
    }

    .menu-item__title .options {
      width: 80px;
    }

    .menu-item__left i {
      background-image: url("./assets/images/left.svg");
    }

    .menu-item__center i {
      background-image: url("./assets/images/center.svg");
    }

    .menu-item__right i {
      background-image: url("./assets/images/right.svg");
    }

    .menu-item__alignment i {
      background-image: url("./assets/images/alignment.svg");
    }

    .menu-item__justify i {
      background-image: url("./assets/images/justify.svg");
    }

    .menu-item__row-margin {
      position: relative;
    }

    .menu-item__row-margin i {
      background-image: url("./assets/images/row-margin.svg");
    }

    .menu-item__list {
      position: relative;
    }

    .menu-item__list i {
      background-image: url("./assets/images/list.svg");
    }

    .menu-item__list .options {
      width: 110px;
    }

    .menu-item__list .options > ul > li * {
      pointer-events: none;
    }

    .menu-item__list .options > ul > li li {
      margin-left: 18px;
    }

    .menu-item__list .options > ul > li[data-list-style="checkbox"] li::marker {
      font-size: 11px;
    }

    .menu-item__image i {
      background-image: url("./assets/images/image.svg");
    }

    .menu-item__image input {
      display: none;
    }

    .menu-item__table {
      position: relative;
    }

    .menu-item__table i {
      background-image: url("./assets/images/table.svg");
    }

    .menu-item .menu-item__table__collapse {
      width: 270px;
      height: 310px;
      background: #fff;
      box-shadow: 0 2px 12px 0 rgb(56 56 56 / 20%);
      border: 1px solid #e2e6ed;
      box-sizing: border-box;
      border-radius: 2px;
      position: absolute;
      display: none;
      z-index: 99;
      top: 25px;
      left: 0;
      padding: 14px 27px;
      cursor: auto;
    }

    .menu-item .menu-item__table__collapse .table-close {
      position: absolute;
      right: 10px;
      top: 5px;
      cursor: pointer;
    }

    .menu-item .menu-item__table__collapse .table-close:hover {
      color: #7d7e80;
    }

    .menu-item .menu-item__table__collapse:hover {
      background: #fff;
    }

    .menu-item .menu-item__table__collapse .table-title {
      display: flex;
      justify-content: flex-start;
      padding-bottom: 5px;
      border-bottom: 1px solid #e2e6ed;
    }

    .table-title span {
      font-size: 12px;
      color: #3d4757;
      display: inline;
      margin: 0;
    }

    .table-panel {
      cursor: pointer;
    }

    .table-panel .table-row {
      display: flex;
      flex-wrap: nowrap;
      margin-top: 10px;
      pointer-events: none;
    }

    .table-panel .table-cel {
      width: 16px;
      height: 16px;
      box-sizing: border-box;
      border: 1px solid #e2e6ed;
      background: #fff;
      position: relative;
      margin-right: 6px;
      pointer-events: none;
    }

    .table-panel .table-cel.active {
      border: 1px solid rgba(73, 145, 242, 0.2);
      background: rgba(73, 145, 242, 0.15);
    }

    .table-panel .table-row .table-cel:last-child {
      margin-right: 0;
    }

    .menu-item__hyperlink i {
      background-image: url("./assets/images/hyperlink.svg");
    }

    .menu-item__separator {
      position: relative;
    }

    .menu-item__separator > i {
      background-image: url("./assets/images/separator.svg");
    }

    .menu-item .menu-item__separator .options {
      width: 128px;
    }

    .menu-item .menu-item__separator li {
      padding: 1px 5px;
    }

    .menu-item__separator li i {
      pointer-events: none;
    }

    .menu-item__separator li[data-separator="0,0"] {
      background-image: url("./assets/images/line-single.svg");
    }

    .menu-item__separator li[data-separator="1,1"] {
      background-image: url("./assets/images/line-dot.svg");
    }

    .menu-item__separator li[data-separator="3,1"] {
      background-image: url("./assets/images/line-dash-small-gap.svg");
    }

    .menu-item__separator li[data-separator="4,4"] {
      background-image: url("./assets/images/line-dash-large-gap.svg");
    }

    .menu-item__separator li[data-separator="7,3,3,3"] {
      background-image: url("./assets/images/line-dash-dot.svg");
    }

    .menu-item__separator li[data-separator="6,2,2,2,2,2"] {
      background-image: url("./assets/images/line-dash-dot-dot.svg");
    }

    .menu-item__watermark > i {
      background-image: url("./assets/images/watermark.svg");
    }

    .menu-item__watermark {
      position: relative;
    }

    .menu-item__codeblock i {
      background-image: url("./assets/images/codeblock.svg");
    }

    .menu-item__page-break i {
      background-image: url("./assets/images/page-break.svg");
    }

    .menu-item__control {
      position: relative;
    }

    .menu-item__control i {
      background-image: url("./assets/images/control.svg");
    }

    .menu-item__checkbox i {
      background-image: url("./assets/images/checkbox.svg");
    }

    .menu-item__radio i {
      background-image: url("./assets/images/radio.svg");
    }

    .menu-item__latex i {
      background-image: url("./assets/images/latex.svg");
    }

    .menu-item__date {
      position: relative;
    }

    .menu-item__date i {
      background-image: url("./assets/images/date.svg");
    }

    .menu-item__date .options {
      width: 160px;
    }

    .menu-item__block i {
      background-image: url("./assets/images/block.svg");
    }

    .menu-item .menu-item__control .options {
      width: 55px;
    }

    .menu-item__search {
      position: relative;
    }

    .menu-item__search i {
      background-image: url("./assets/images/search.svg");
    }

    .menu-item .menu-item__search__collapse {
      width: 260px;
      height: 72px;
      box-sizing: border-box;
      position: absolute;
      display: none;
      z-index: 99;
      top: 25px;
      left: 0;
      background: #ffffff;
      box-shadow: 0px 5px 5px #e3dfdf;
    }

    .menu-item .menu-item__search__collapse:hover {
      background: #ffffff;
    }

    .menu-item .menu-item__search__collapse > div {
      width: 250px;
      height: 36px;
      padding: 0 5px;
      line-height: 36px;
      display: flex;
      align-items: center;
      justify-content: space-between;
      border-radius: 4px;
    }

    .menu-item .menu-item__search__collapse > div input {
      width: 205px;
      height: 27px;
      appearance: none;
      background-color: #fff;
      background-image: none;
      border-radius: 4px;
      border: 1px solid #ebebeb;
      box-sizing: border-box;
      color: #606266;
      display: inline-block;
      line-height: 27px;
      outline: none;
      padding: 0 5px;
    }

    .menu-item .menu-item__search__collapse > div span {
      height: 100%;
      color: #dcdfe6;
      font-size: 25px;
      display: inline-block;
      border: 0;
      padding: 0 10px;
    }

    .menu-item .menu-item__search__collapse__replace button {
      display: inline-block;
      border: 1px solid #e2e6ed;
      border-radius: 2px;
      background: #fff;
      line-height: 22px;
      padding: 0 6px;
      white-space: nowrap;
      margin-left: 4px;
      cursor: pointer;
      font-size: 12px;
    }

    .menu-item .menu-item__search__collapse__replace button:hover {
      background: rgba(25, 55, 88, 0.04);
    }

    .menu-item .menu-item__search__collapse__search {
      position: relative;
    }

    .menu-item .menu-item__search__collapse__search label {
      right: 110px;
      font-size: 12px;
      color: #3d4757;
      position: absolute;
    }

    .menu-item .menu-item__search__collapse__search > input {
      padding: 5px 90px 5px 5px !important;
    }

    .menu-item .menu-item__search__collapse__search > div {
      width: 28px;
      height: 27px;
      display: flex;
      justify-content: center;
      align-items: center;
      position: absolute;
      border-left: 1px solid #e2e6ed;
      transition: all 0.5s;
    }

    .menu-item .menu-item__search__collapse__search > div:hover {
      background-color: rgba(25, 55, 88, 0.04);
    }

    .menu-item .menu-item__search__collapse__search i {
      width: 6px;
      height: 8px;
      transform: translateY(1px);
    }

    .menu-item .menu-item__search__collapse__search .arrow-left {
      right: 76px;
    }

    .menu-item .menu-item__search__collapse__search .arrow-left i {
      background: url(./assets/images/arrow-left.svg) no-repeat;
    }

    .menu-item .menu-item__search__collapse__search .arrow-right {
      right: 48px;
    }

    .menu-item .menu-item__search__collapse__search .arrow-right i {
      background: url(./assets/images/arrow-right.svg) no-repeat;
    }

    .menu-item__print i {
      background-image: url("./assets/images/print.svg");
    }

    .catalog {
      width: 250px;
      position: absolute;
      left: 0;
      bottom: 0;
      top: 100px;
      padding: 0 20px 40px 20px;
    }

    .catalog .catalog__header {
      height: 48px;
      display: flex;
      align-items: center;
      justify-content: space-between;
      border-bottom: 1px solid #e2e6ed;
    }

    .catalog .catalog__header span {
      color: #3d4757;
      font-size: 14px;
      font-weight: bold;
    }

    .catalog .catalog__header i {
      width: 16px;
      height: 16px;
      cursor: pointer;
      display: inline-block;
      background: url(./assets/images/close.svg) no-repeat;
      transition: all 0.2s;
    }

    .catalog .catalog__header > div:hover {
      background: rgba(235, 238, 241);
    }

    .catalog__main {
      height: calc(100% - 60px);
      padding: 10px 0;
      overflow-y: auto;
      overflow-x: hidden;
    }

    .catalog__main .catalog-item {
      width: 100%;
      padding-left: 10px;
      box-sizing: border-box;
    }

    .catalog__main > .catalog-item {
      padding-left: 0;
    }

    .catalog__main .catalog-item .catalog-item__content {
      width: 100%;
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
    }

    .catalog__main .catalog-item .catalog-item__content:hover > span {
      color: #4991f2;
    }

    .catalog__main .catalog-item .catalog-item__content span {
      color: #3d4757;
      line-height: 30px;
      font-size: 12px;
      white-space: nowrap;
      cursor: pointer;
      user-select: none;
    }

    .editor > div {
      margin: 80px auto;
    }

    .ce-page-container canvas {
      box-shadow: rgb(158 161 165 / 40%) 0px 2px 12px 0px;
    }

    .comment {
      width: 250px;
      height: 650px;
      position: absolute;
      transform: translateX(420px);
      top: 200px;
      left: 50%;
      overflow-y: auto;
    }

    .comment-item {
      background: #ffffff;
      border: 1px solid #e2e6ed;
      position: relative;
      border-radius: 8px;
      padding: 15px;
      font-size: 14px;
      margin-bottom: 20px;
      cursor: pointer;
      transition: all 0.5s;
    }

    .comment-item:hover {
      border-color: #c0c6cf;
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    }

    .comment-item.active {
      border-color: #e99d00;
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    }

    .comment-item__title {
      height: 22px;
      position: relative;
      display: flex;
      align-items: center;
      color: #c1c6ce;
    }

    .comment-item__title span:first-child {
      background-color: #dbdbdb;
      width: 4px;
      height: 16px;
      margin-right: 5px;
      display: inline-block;
      border-radius: 999px;
    }

    .comment-item__title span:nth-child(2) {
      width: 200px;
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
    }

    .comment-item__title i {
      width: 16px;
      height: 16px;
      cursor: pointer;
      position: absolute;
      right: -8px;
      top: -8px;
      background: url(./assets/images/close.svg) no-repeat;
    }

    .comment-item__title i:hover {
      opacity: 0.6;
    }

    .comment-item__info {
      height: 28px;
      display: flex;
      align-items: center;
      justify-content: space-between;
    }

    .comment-item__info > span:first-child {
      font-weight: 600;
    }

    .comment-item__info > span:last-child {
      color: #c1c6ce;
    }

    .comment-item__content {
      line-height: 22px;
    }

    .footer {
      width: 100%;
      height: 30px;
      display: flex;
      align-items: center;
      justify-content: space-between;
      background: #f2f4f7;
      z-index: 9;
      position: absolute;
      bottom: 0;
      left: 0;
      font-size: 12px;
      padding: 0 4px 0 20px;
      box-sizing: border-box;
    }

    .footer > div:first-child {
      display: flex;
      align-items: center;
    }

    .footer .catalog-mode {
      padding: 1px;
      position: relative;
    }

    .footer .catalog-mode i {
      width: 16px;
      height: 16px;
      margin-right: 5px;
      cursor: pointer;
      display: inline-block;
      background-image: url("./assets/images/catalog.svg");
    }

    .footer .page-mode {
      padding: 1px;
      position: relative;
    }

    .footer .page-mode i {
      width: 16px;
      height: 16px;
      margin-right: 5px;
      cursor: pointer;
      display: inline-block;
      background-image: url("./assets/images/page-mode.svg");
    }

    .footer .options {
      width: 70px;
      position: absolute;
      left: 0;
      bottom: 25px;
      padding: 10px;
      background: #fff;
      font-size: 14px;
      box-shadow: 0 2px 12px 0 rgb(56 56 56 / 20%);
      border: 1px solid #e2e6ed;
      border-radius: 2px;
      display: none;
    }

    .footer .options.visible {
      display: block;
    }

    .footer .options li {
      padding: 5px;
      margin: 5px 0;
      user-select: none;
      transition: all 0.3s;
      text-align: center;
      cursor: pointer;
    }

    .footer .options li:hover {
      background-color: #ebecef;
    }

    .footer .options li.active {
      background-color: #e2e6ed;
    }

    .footer > div:first-child > span {
      display: inline-block;
      margin-right: 5px;
      letter-spacing: 1px;
    }

    .footer > div:last-child {
      display: flex;
      align-items: center;
      justify-content: space-between;
    }

    .footer > div:last-child > div {
      width: 24px;
      height: 24px;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .footer > div:last-child > div:hover {
      background: rgba(25, 55, 88, 0.04);
    }

    .footer > div:last-child i {
      width: 16px;
      height: 16px;
      display: inline-block;
      cursor: pointer;
    }

    .footer .editor-option i {
      background-image: url("./assets/images/option.svg");
    }

    .footer .page-scale-minus i {
      background-image: url("./assets/images/page-scale-minus.svg");
    }

    .footer .page-scale-add i {
      background-image: url("./assets/images/page-scale-add.svg");
    }

    .footer .page-scale-percentage {
      cursor: pointer;
      user-select: none;
    }

    .footer .fullscreen i {
      background-image: url("./assets/images/request-fullscreen.svg");
    }

    .footer .fullscreen.exist i {
      background-image: url("./assets/images/exit-fullscreen.svg");
    }

    .footer .paper-margin i {
      background-image: url("./assets/images/paper-margin.svg");
    }

    .footer .editor-mode {
      cursor: pointer;
      user-select: none;
    }

    .footer .paper-size {
      position: relative;
    }

    .footer .paper-size i {
      background-image: url("./assets/images/paper-size.svg");
    }

    .footer .paper-size .options {
      right: 0;
      left: unset;
    }

    .footer .paper-direction {
      position: relative;
    }

    .footer .paper-direction i {
      background-image: url("./assets/images/paper-direction.svg");
    }

    .footer .paper-direction .options {
      right: 0;
      left: unset;
    }

    .ce-contextmenu-signature {
      background-image: url("./assets/images/signature.svg");
    }

    .ce-contextmenu-word-tool {
      background-image: url("./assets/images/word-tool.svg");
    }

    .menu-item__color .options {
      width: 220px;
      padding: 8px;
    }

    .menu-item__color .color-section {
      margin-bottom: 10px;
    }

    .menu-item__color .section-title {
      font-size: 12px;
      color: #666;
      margin-bottom: 5px;
      padding-left: 2px;
    }

    .menu-item__color .options ul {
      display: flex;
      flex-wrap: wrap;
      gap: 2px;
    }

    .menu-item__color .options li {
      width: 18px;
      height: 18px;
      border: 1px solid #ddd;
      cursor: pointer;
      margin: 0;
      position: relative;
    }

    .menu-item__color .options li:hover {
      border-color: #000;
    }

    .menu-item__color .options li[data-color="#FFFFFF"] {
      border: 1px solid #ddd;
    }

    // 添加悬浮提示样式
    .menu-item__color .options li:hover::after {
      content: attr(title);
      position: absolute;
      bottom: 100%;
      left: 50%;
      transform: translateX(-50%);
      padding: 4px 8px;
      background-color: #333;
      color: white;
      font-size: 12px;
      border-radius: 4px;
      white-space: nowrap;
      z-index: 1000;
    }

    .menu-item__highlight .options {
      width: 180px;
      padding: 5px;
    }

    .menu-item__highlight .options ul {
      display: grid;
      grid-template-columns: repeat(6, 1fr);
      gap: 2px;
    }

    .menu-item__highlight .options li {
      width: 24px;
      height: 24px;
      border: 1px solid #ddd;
      cursor: pointer;
      margin: 0;
      position: relative;
      display: flex;
      align-items: center;
      justify-content: center;
      color: #666;
    }

    /* 特殊处理"无"选项 */
    .menu-item__highlight .options li[data-color="transparent"] {
      background: white;
      font-size: 16px;
    }

    .menu-item__highlight .options li:hover {
      border-color: #000;
    }

    .menu-item__highlight .options li:hover::after {
      content: attr(title);
      position: absolute;
      bottom: 100%;
      left: 50%;
      transform: translateX(-50%);
      padding: 4px 8px;
      background-color: #333;
      color: white;
      font-size: 12px;
      border-radius: 4px;
      white-space: nowrap;
      z-index: 1000;
    }
  }
}
</style>