Files
uai-editor/src/components/menus/toolbar/Classic.ts
T
2025-02-19 23:10:31 +08:00

573 lines
24 KiB
TypeScript

// Copyright (c) 2024-present AI-Labs
// @ ts-nocheck
import { EditorEvents } from "@tiptap/core";
import { UAIEditorEventListener, UAIEditorOptions } from "../../../core/UAIEditor.ts";
import menuIcon from "../../../assets/icons/menu.svg";
import { ScrollableDiv } from "./ScrollableDiv.ts";
import { FontSizeIncrease } from "../common/FontSizeIncrease.ts";
import { FontSizeDecrease } from "../common/FontSizeDecrease.ts";
import { Bold } from "../common/Bold.ts";
import { Italic } from "../common/Italic.ts";
import { Underline } from "../common/Underline.ts";
import { Strike } from "../common/Strike.ts";
import { Subscript } from "../common/Subscript.ts";
import { Superscript } from "../common/Superscript.ts";
import { FontColor } from "../common/FontColor.ts";
import { Highlight } from "../common/Highlight.ts";
import { AlignLeft } from "../common/AlignLeft.ts";
import { AlignCenter } from "../common/AlignCenter.ts";
import { AlignRight } from "../common/AlignRight.ts";
import { AlignJustify } from "../common/AlignJustify.ts";
import { AlignDistributed } from "../common/AlignDistributed.ts";
import { Redo } from "./base/Redo.ts";
import { Undo } from "./base/Undo.ts";
import { FormatPainter } from "./base/FormatPainter.ts";
import { ClearFormat } from "./base/ClearFormat.ts";
import { FontFamily } from "./base/FontFamily.ts";
import { FontSize } from "./base/FontSize.ts";
import { OrderedList } from "./base/OrderedList.ts";
import { BulletList } from "./base/BulletList.ts";
import { TaskList } from "./base/TaskList.ts";
import { Indent } from "./base/Indent.ts";
import { Outdent } from "./base/Outdent.ts";
import { LineHeight } from "./base/LineHeight.ts";
import { BlockQuote } from "./base/BlockQuote.ts";
import { CodeBlock } from "./base/CodeBlock.ts";
import { Print } from "./base/Print.ts";
import { Link } from "./insert/Link.ts";
import { Image } from "./insert/Image.ts";
import { Video } from "./insert/Video.ts";
import { Audio } from "./insert/Audio.ts";
import { HardBreak } from "./insert/HardBreak.ts";
import { Emoji } from "./insert/Emoji.ts";
import { Symbol } from "./insert/Symbol.ts";
import { Math } from "./insert/Math.ts";
import { Toc } from "./insert/Toc.ts";
import { InsertTable } from "./table/InsertTable.ts";
import { AddColumnAfter } from "./table/AddColumnAfter.ts";
import { AddColumnBefore } from "./table/AddColumnBefore.ts";
import { DeleteColumn } from "./table/DeleteColumn.ts";
import { AddRowAfter } from "./table/AddRowAfter.ts";
import { AddRowBefore } from "./table/AddRowBefore.ts";
import { DeleteRow } from "./table/DeleteRow.ts";
import { DeleteTable } from "./table/DeleteTable.ts";
import { Diagrams } from "./tools/Diagrams.ts";
import { ToggleToc } from "./page/ToggleToc.ts";
/**
* 传统菜单栏
*/
export class Classic extends HTMLElement implements UAIEditorEventListener {
defaultToolbarMenus!: Record<string, any>[];
eventComponents: UAIEditorEventListener[] = [];
// 传统菜单栏容器
classicMenu!: HTMLElement;
classicScrollableContainer!: HTMLElement;
// 基础菜单容器
classicMenuBaseScrollable!: ScrollableDiv;
classicMenuBaseGroup!: HTMLElement;
// 插入菜单容器
classicMenuInsertScrollable!: ScrollableDiv;
classicMenuInsertGroup!: HTMLElement;
// 表格菜单容器
classicMenuTableScrollable!: ScrollableDiv;
classicMenuTableGroup!: HTMLElement;
// 工具菜单容器
classicMenuToolScrollable!: ScrollableDiv;
classicMenuToolGroup!: HTMLElement;
// 页面菜单容器
classicMenuPageScrollable!: ScrollableDiv;
classicMenuPageGroup!: HTMLElement;
// 基础菜单
baseMenuUndo!: Undo;
baseMenuRedo!: Redo;
baseMenuFormatPainter!: FormatPainter;
baseMenuClearFormat!: ClearFormat;
baseMenuFontFamily!: FontFamily;
baseMenuFontSize!: FontSize;
baseMenuFontSizeIncrease!: FontSizeIncrease;
baseMenuFontSizeDecrease!: FontSizeDecrease;
baseMenuBold!: Bold;
baseMenuItalic!: Italic;
baseMenuUnderline!: Underline;
baseMenuStrike!: Strike;
baseMenuSubscript!: Subscript;
baseMenuSuperscript!: Superscript;
baseMenuFontColor!: FontColor;
baseMenuHighlight!: Highlight;
baseMenuOrderedList!: OrderedList;
baseMenuBulletList!: BulletList;
baseMenuTaskList!: TaskList;
baseMenuIndent!: Indent;
baseMenuOutdent!: Outdent;
baseMenuLineHeight!: LineHeight;
baseMenuAlignLeft!: AlignLeft;
baseMenuAlignCenter!: AlignCenter;
baseMenuAlignRight!: AlignRight;
baseMenuAlignJustify!: AlignJustify;
baseMenuAlignDistributed!: AlignDistributed;
baseMenuBlockQuote!: BlockQuote;
baseMenuCodeBlock!: CodeBlock;
baseMenuPrint!: Print;
// 插入菜单
insertMenuLink!: Link;
insertMenuImage!: Image;
insertMenuVideo!: Video;
insertMenuAudio!: Audio;
insertMenuHardBreak!: HardBreak;
insertMenuEmoji!: Emoji;
insertMenuSymbol!: Symbol;
insertMenuMath!: Math;
insertMenuToc!: Toc;
// 表格菜单
tableMenuInsertTable!: InsertTable;
tableMenuAddColumnAfter!: AddColumnAfter;
tableMenuAddColumnBefore!: AddColumnBefore;
tableMenuDeleteColumn!: DeleteColumn;
tableMenuAddRowAfter!: AddRowAfter;
tableMenuAddRowBefore!: AddRowBefore;
tableMenuDeleteRow!: DeleteRow;
tableMenuDeleteTable!: DeleteTable;
// 工具菜单
toolsMenuDiagrams!: Diagrams;
// 页面菜单
pageMenuToggleToc!: ToggleToc;
constructor(defaultToolbarMenus: Record<string, any>[]) {
super();
this.defaultToolbarMenus = defaultToolbarMenus;
// 初始化菜单
this.initMenus();
}
/**
* 定义创建方法
* @param event
* @param options
*/
onCreate(event: EditorEvents["create"], options: UAIEditorOptions) {
this.eventComponents.forEach(component => {
component.onCreate(event, options);
})
// 创建菜单容器
this.classicScrollableContainer = document.createElement("div");
this.classicScrollableContainer.classList.add("uai-classic-scrollable-container");
this.appendChild(this.classicScrollableContainer);
this.classicMenu = document.createElement("div");
this.classicMenu.classList.add("uai-classic-menu");
this.classicScrollableContainer.appendChild(this.classicMenu);
const selectDiv = document.createElement("div");
selectDiv.classList.add("uai-classic-virtual-group");
selectDiv.classList.add("uai-editor-menu-select-3");
selectDiv.innerHTML = `<img src="${menuIcon}" width="16" />`;
this.classicMenu.appendChild(selectDiv);
const selectMuenus = document.createElement("select");
selectDiv.appendChild(selectMuenus);
this.defaultToolbarMenus.forEach(menu => {
const option = document.createElement("option");
option.label = menu.label;
option.value = menu.value;
selectMuenus.options.add(option);
});
// 添加事件,处理菜单分组切换、界面元素切换
selectMuenus.addEventListener("change", () => {
const menu = selectMuenus.selectedOptions[0].value;
this.classicMenuBaseScrollable.style.display = "none";
this.classicMenuInsertScrollable.style.display = "none";
this.classicMenuTableScrollable.style.display = "none";
this.classicMenuToolScrollable.style.display = "none";
this.classicMenuPageScrollable.style.display = "none";
if (menu === "base") {
this.classicMenuBaseScrollable.style.display = "flex";
}
if (menu === "insert") {
this.classicMenuInsertScrollable.style.display = "flex";
}
if (menu === "table") {
this.classicMenuTableScrollable.style.display = "flex";
}
if (menu === "tools") {
this.classicMenuToolScrollable.style.display = "flex";
}
if (menu === "page") {
this.classicMenuPageScrollable.style.display = "flex";
}
})
// 创建分组菜单
this.createBaseMenu(event, options);
this.createInsertMenu(event, options);
this.createTableMenu(event, options);
this.createToolMenu(event, options);
this.createPageMenu(event, options);
this.classicMenuBaseScrollable.style.display = "flex";
}
/**
* 定义Transaction监听方法
* @param event
* @param options
*/
onTransaction(event: EditorEvents["transaction"], options: UAIEditorOptions) {
this.eventComponents.forEach(component => {
component.onTransaction(event, options);
})
}
onEditableChange(editable: boolean) {
this.eventComponents.forEach(component => {
component.onEditableChange(editable);
})
}
/**
* 初始化菜单
*/
initMenus() {
this.baseMenuUndo = new Undo({ menuType: "button", enable: true, hideText: false });
this.eventComponents.push(this.baseMenuUndo);
this.baseMenuRedo = new Redo({ menuType: "button", enable: true });
this.eventComponents.push(this.baseMenuRedo);
this.baseMenuFormatPainter = new FormatPainter({ menuType: "button", enable: true });
this.eventComponents.push(this.baseMenuFormatPainter);
this.baseMenuClearFormat = new ClearFormat({ menuType: "button", enable: true });
this.eventComponents.push(this.baseMenuClearFormat);
this.baseMenuFontFamily = new FontFamily({ menuType: "select", enable: true });
this.eventComponents.push(this.baseMenuFontFamily);
this.baseMenuFontSize = new FontSize({ menuType: "select", enable: true });
this.eventComponents.push(this.baseMenuFontSize);
this.baseMenuFontSizeIncrease = new FontSizeIncrease({ menuType: "button", enable: true });
this.eventComponents.push(this.baseMenuFontSizeIncrease);
this.baseMenuFontSizeDecrease = new FontSizeDecrease({ menuType: "button", enable: true });
this.eventComponents.push(this.baseMenuFontSizeDecrease);
this.baseMenuBold = new Bold({ menuType: "button", enable: true });
this.eventComponents.push(this.baseMenuBold);
this.baseMenuItalic = new Italic({ menuType: "button", enable: true });
this.eventComponents.push(this.baseMenuItalic);
this.baseMenuUnderline = new Underline({ menuType: "button", enable: true });
this.eventComponents.push(this.baseMenuUnderline);
this.baseMenuStrike = new Strike({ menuType: "button", enable: true });
this.eventComponents.push(this.baseMenuStrike);
this.baseMenuSubscript = new Subscript({ menuType: "button", enable: true });
this.eventComponents.push(this.baseMenuSubscript);
this.baseMenuSuperscript = new Superscript({ menuType: "button", enable: true });
this.eventComponents.push(this.baseMenuSuperscript);
this.baseMenuFontColor = new FontColor({ menuType: "color", enable: true });
this.eventComponents.push(this.baseMenuFontColor);
this.baseMenuHighlight = new Highlight({ menuType: "color", enable: true });
this.eventComponents.push(this.baseMenuHighlight);
this.baseMenuOrderedList = new OrderedList({ menuType: "popup", enable: true });
this.eventComponents.push(this.baseMenuOrderedList);
this.baseMenuBulletList = new BulletList({ menuType: "popup", enable: true });
this.eventComponents.push(this.baseMenuBulletList);
this.baseMenuTaskList = new TaskList({ menuType: "popup", enable: true });
this.eventComponents.push(this.baseMenuTaskList);
this.baseMenuIndent = new Indent({ menuType: "button", enable: true });
this.eventComponents.push(this.baseMenuIndent);
this.baseMenuOutdent = new Outdent({ menuType: "button", enable: true });
this.eventComponents.push(this.baseMenuOutdent);
this.baseMenuLineHeight = new LineHeight({ menuType: "popup", enable: true });
this.eventComponents.push(this.baseMenuLineHeight);
this.baseMenuAlignLeft = new AlignLeft({ menuType: "button", enable: true });
this.eventComponents.push(this.baseMenuAlignLeft);
this.baseMenuAlignCenter = new AlignCenter({ menuType: "button", enable: true });
this.eventComponents.push(this.baseMenuAlignCenter);
this.baseMenuAlignRight = new AlignRight({ menuType: "button", enable: true });
this.eventComponents.push(this.baseMenuAlignRight);
this.baseMenuAlignJustify = new AlignJustify({ menuType: "button", enable: true });
this.eventComponents.push(this.baseMenuAlignJustify);
this.baseMenuAlignDistributed = new AlignDistributed({ menuType: "button", enable: true });
this.eventComponents.push(this.baseMenuAlignDistributed);
this.baseMenuBlockQuote = new BlockQuote({ menuType: "button", enable: true });
this.eventComponents.push(this.baseMenuBlockQuote);
this.baseMenuCodeBlock = new CodeBlock({ menuType: "button", enable: true });
this.eventComponents.push(this.baseMenuCodeBlock);
this.baseMenuPrint = new Print({ menuType: "button", enable: true, header: "classic", hideText: false });
this.eventComponents.push(this.baseMenuPrint);
this.insertMenuLink = new Link({ menuType: "button", enable: true, header: "classic", hideText: false });
this.eventComponents.push(this.insertMenuLink);
this.insertMenuImage = new Image({ menuType: "button", enable: true, header: "classic", hideText: false });
this.eventComponents.push(this.insertMenuImage);
this.insertMenuVideo = new Video({ menuType: "button", enable: true, header: "classic", hideText: false });
this.eventComponents.push(this.insertMenuVideo);
this.insertMenuAudio = new Audio({ menuType: "button", enable: true, header: "classic", hideText: false });
this.eventComponents.push(this.insertMenuAudio);
this.insertMenuHardBreak = new HardBreak({ menuType: "button", enable: true, header: "classic", hideText: false });
this.eventComponents.push(this.insertMenuHardBreak);
this.insertMenuEmoji = new Emoji({ menuType: "popup", enable: true, header: "classic", hideText: false });
this.eventComponents.push(this.insertMenuEmoji);
this.insertMenuSymbol = new Symbol({ menuType: "popup", enable: true, header: "classic", hideText: false });
this.eventComponents.push(this.insertMenuSymbol);
this.insertMenuMath = new Math({ menuType: "button", enable: true, header: "classic", hideText: false });
this.eventComponents.push(this.insertMenuMath);
this.insertMenuToc = new Toc({ menuType: "button", enable: true, header: "classic", hideText: false });
this.eventComponents.push(this.insertMenuToc);
this.tableMenuInsertTable = new InsertTable({ menuType: "popup", enable: true, header: "classic", hideText: false });
this.eventComponents.push(this.tableMenuInsertTable);
this.tableMenuAddColumnAfter = new AddColumnAfter({ menuType: "button", enable: true, header: "classic", hideText: false });
this.eventComponents.push(this.tableMenuAddColumnAfter);
this.tableMenuAddColumnBefore = new AddColumnBefore({ menuType: "button", enable: true, header: "classic", hideText: false });
this.eventComponents.push(this.tableMenuAddColumnBefore);
this.tableMenuDeleteColumn = new DeleteColumn({ menuType: "button", enable: true, header: "classic", hideText: false });
this.eventComponents.push(this.tableMenuDeleteColumn);
this.tableMenuAddRowAfter = new AddRowAfter({ menuType: "button", enable: true, header: "classic", hideText: false });
this.eventComponents.push(this.tableMenuAddRowAfter);
this.tableMenuAddRowBefore = new AddRowBefore({ menuType: "button", enable: true, header: "classic", hideText: false });
this.eventComponents.push(this.tableMenuAddRowBefore);
this.tableMenuDeleteRow = new DeleteRow({ menuType: "button", enable: true, header: "classic", hideText: false });
this.eventComponents.push(this.tableMenuDeleteRow);
this.tableMenuDeleteTable = new DeleteTable({ menuType: "button", enable: true, header: "classic", hideText: false });
this.eventComponents.push(this.tableMenuDeleteTable);
this.toolsMenuDiagrams = new Diagrams({ menuType: "button", enable: true, header: "classic", hideText: false });
this.eventComponents.push(this.toolsMenuDiagrams);
this.pageMenuToggleToc = new ToggleToc({ menuType: "button", enable: true, header: "classic", hideText: false });
this.eventComponents.push(this.pageMenuToggleToc);
}
/**
* 创建基础菜单
* @param event
* @param options
*/
createBaseMenu(event: EditorEvents["create"], options: UAIEditorOptions) {
this.classicMenuBaseGroup = document.createElement("div");
this.classicMenuBaseGroup.style.display = "flex";
this.classicMenuBaseScrollable = new ScrollableDiv(this.classicMenuBaseGroup);
this.classicMenuBaseScrollable.style.display = "none";
this.classicMenu.appendChild(this.classicMenuBaseScrollable);
this.classicMenuBaseScrollable.onCreate(event, options);
const group1 = document.createElement("div");
group1.classList.add("uai-classic-virtual-group");
this.classicMenuBaseGroup.appendChild(group1);
group1.appendChild(this.baseMenuUndo);
group1.appendChild(this.baseMenuRedo);
group1.appendChild(this.baseMenuFormatPainter);
group1.appendChild(this.baseMenuClearFormat);
const group2 = document.createElement("div");
group2.classList.add("uai-classic-virtual-group");
this.classicMenuBaseGroup.appendChild(group2);
group2.appendChild(this.baseMenuFontFamily);
group2.appendChild(this.baseMenuFontSize);
group2.appendChild(this.baseMenuFontSizeIncrease);
group2.appendChild(this.baseMenuFontSizeDecrease);
group2.appendChild(this.baseMenuBold);
group2.appendChild(this.baseMenuItalic);
group2.appendChild(this.baseMenuUnderline);
group2.appendChild(this.baseMenuStrike);
group2.appendChild(this.baseMenuSubscript);
group2.appendChild(this.baseMenuSuperscript);
group2.appendChild(this.baseMenuFontColor);
group2.appendChild(this.baseMenuHighlight);
const group3 = document.createElement("div");
group3.classList.add("uai-classic-virtual-group");
this.classicMenuBaseGroup.appendChild(group3);
group3.appendChild(this.baseMenuOrderedList);
group3.appendChild(this.baseMenuBulletList);
group3.appendChild(this.baseMenuTaskList);
group3.appendChild(this.baseMenuIndent);
group3.appendChild(this.baseMenuOutdent);
group3.appendChild(this.baseMenuLineHeight);
group3.appendChild(this.baseMenuAlignLeft);
group3.appendChild(this.baseMenuAlignCenter);
group3.appendChild(this.baseMenuAlignRight);
group3.appendChild(this.baseMenuAlignJustify);
group3.appendChild(this.baseMenuAlignDistributed);
group3.appendChild(this.baseMenuBlockQuote);
group3.appendChild(this.baseMenuCodeBlock);
const group4 = document.createElement("div");
group4.classList.add("uai-classic-virtual-group");
this.classicMenuBaseGroup.appendChild(group4);
group4.appendChild(this.baseMenuPrint);
}
/**
* 创建插入菜单
* @param event
* @param options
*/
createInsertMenu(event: EditorEvents["create"], options: UAIEditorOptions) {
this.classicMenuInsertGroup = document.createElement("div");
this.classicMenuInsertGroup.style.display = "flex";
this.classicMenuInsertScrollable = new ScrollableDiv(this.classicMenuInsertGroup);
this.classicMenuInsertScrollable.style.display = "none";
this.classicMenu.appendChild(this.classicMenuInsertScrollable);
this.classicMenuInsertScrollable.onCreate(event, options);
const group1 = document.createElement("div");
group1.classList.add("uai-classic-virtual-group");
this.classicMenuInsertGroup.appendChild(group1);
group1.appendChild(this.insertMenuLink);
group1.appendChild(this.insertMenuImage);
group1.appendChild(this.insertMenuVideo);
group1.appendChild(this.insertMenuAudio);
const group2 = document.createElement("div");
group2.classList.add("uai-classic-virtual-group");
this.classicMenuInsertGroup.appendChild(group2);
group2.appendChild(this.insertMenuHardBreak);
group2.appendChild(this.insertMenuEmoji);
group2.appendChild(this.insertMenuSymbol);
group2.appendChild(this.insertMenuMath);
const group3 = document.createElement("div");
group3.classList.add("uai-classic-virtual-group");
this.classicMenuInsertGroup.appendChild(group3);
group3.appendChild(this.insertMenuToc);
}
/**
* 创建表格菜单
* @param event
* @param options
*/
createTableMenu(event: EditorEvents["create"], options: UAIEditorOptions) {
this.classicMenuTableGroup = document.createElement("div");
this.classicMenuTableGroup.style.display = "flex";
this.classicMenuTableScrollable = new ScrollableDiv(this.classicMenuTableGroup);
this.classicMenuTableScrollable.style.display = "none";
this.classicMenu.appendChild(this.classicMenuTableScrollable);
this.classicMenuTableScrollable.onCreate(event, options);
const group1 = document.createElement("div");
group1.classList.add("uai-classic-virtual-group");
this.classicMenuTableGroup.appendChild(group1);
group1.appendChild(this.tableMenuInsertTable);
const group2 = document.createElement("div");
group2.classList.add("uai-classic-virtual-group");
this.classicMenuTableGroup.appendChild(group2);
group2.appendChild(this.tableMenuAddColumnBefore);
group2.appendChild(this.tableMenuAddColumnAfter);
group2.appendChild(this.tableMenuDeleteColumn);
group2.appendChild(this.tableMenuAddRowBefore);
group2.appendChild(this.tableMenuAddRowAfter);
group2.appendChild(this.tableMenuDeleteRow);
const group3 = document.createElement("div");
group3.classList.add("uai-classic-virtual-group");
this.classicMenuTableGroup.appendChild(group3);
group3.appendChild(this.tableMenuDeleteTable);
}
/**
* 创建工具菜单
* @param event
* @param options
*/
createToolMenu(event: EditorEvents["create"], options: UAIEditorOptions) {
this.classicMenuToolGroup = document.createElement("div");
this.classicMenuToolGroup.style.display = "flex";
this.classicMenuToolScrollable = new ScrollableDiv(this.classicMenuToolGroup);
this.classicMenuToolScrollable.style.display = "none";
this.classicMenu.appendChild(this.classicMenuToolScrollable);
this.classicMenuToolScrollable.onCreate(event, options);
const group1 = document.createElement("div");
group1.classList.add("uai-classic-virtual-group");
this.classicMenuToolGroup.appendChild(group1);
group1.appendChild(this.toolsMenuDiagrams);
}
/**
* 创建页面菜单
* @param event
* @param options
*/
createPageMenu(event: EditorEvents["create"], options: UAIEditorOptions) {
this.classicMenuPageGroup = document.createElement("div");
this.classicMenuPageGroup.style.display = "flex";
this.classicMenuPageScrollable = new ScrollableDiv(this.classicMenuPageGroup);
this.classicMenuPageScrollable.style.display = "none";
this.classicMenu.appendChild(this.classicMenuPageScrollable);
this.classicMenuPageScrollable.onCreate(event, options);
const group1 = document.createElement("div");
group1.classList.add("uai-classic-virtual-group");
this.classicMenuPageGroup.appendChild(group1);
group1.appendChild(this.pageMenuToggleToc);
}
}