Files
uai-editor/src/core/UAIExtensions.ts
T

218 lines
6.7 KiB
TypeScript
Raw Normal View History

2024-12-20 21:35:42 +08:00
// Copyright (c) 2024-present AI-Labs
// @ ts-nocheck
2025-01-04 21:41:32 +08:00
import { Extension, Extensions, getTextBetween } from "@tiptap/core";
2024-12-20 21:35:42 +08:00
import { UAIEditor, UAIEditorOptions } from "./UAIEditor";
import { StarterKit } from "@tiptap/starter-kit";
2024-12-22 20:13:47 +08:00
import { Color } from "@tiptap/extension-color";
2024-12-21 20:15:22 +08:00
import { FontFamily } from "@tiptap/extension-font-family";
2024-12-22 20:13:47 +08:00
import { Highlight } from "@tiptap/extension-highlight";
2024-12-24 21:02:21 +08:00
import { Link } from "@tiptap/extension-link";
2024-12-21 22:43:17 +08:00
import { Subscript } from "@tiptap/extension-subscript";
import { Superscript } from "@tiptap/extension-superscript";
2025-01-01 20:23:52 +08:00
import { Table } from "@tiptap/extension-table";
import { TableCell } from "@tiptap/extension-table-cell";
import { TableHeader } from "@tiptap/extension-table-header";
import { TableRow } from "@tiptap/extension-table-row";
2024-12-23 21:45:56 +08:00
import { TaskItem } from "@tiptap/extension-task-item";
import { TaskList } from "@tiptap/extension-task-list";
2024-12-23 22:12:31 +08:00
import { TextAlign } from "@tiptap/extension-text-align";
2024-12-21 20:15:22 +08:00
import { TextStyle } from "@tiptap/extension-text-style";
2024-12-21 22:43:17 +08:00
import { Underline } from "@tiptap/extension-underline";
2024-12-24 21:02:21 +08:00
2025-01-03 21:25:56 +08:00
import { Export } from '@tiptap-pro/extension-export';
2024-12-29 20:26:15 +08:00
import { Mathematics } from '@tiptap-pro/extension-mathematics';
2024-12-30 20:53:12 +08:00
import { TableOfContents, getHierarchicalIndexes } from '@tiptap-pro/extension-table-of-contents'
2024-12-29 20:26:15 +08:00
2024-12-23 22:12:31 +08:00
import BulletList from "../extensions/BulletList.ts";
2024-12-21 20:15:22 +08:00
import FontSize from "../extensions/FontSize.ts";
2024-12-25 20:52:31 +08:00
import Image from "../extensions/Image.ts";
2024-12-23 21:43:26 +08:00
import Indent from "../extensions/Indent.ts";
2024-12-23 22:12:31 +08:00
import LineHeight from "../extensions/LineHeight.ts"
import NodeAlign from "../extensions/NodeAlign.ts";
2024-12-23 21:43:26 +08:00
import OrderedList from "../extensions/OrderedList.ts";
2024-12-25 20:52:31 +08:00
import SelectFile from "../extensions/SelectFile.ts";
2025-01-05 22:21:31 +08:00
import Selection from "../extensions/Selection.ts";
2024-12-25 21:36:38 +08:00
import Video from "../extensions/Video.ts";
2024-12-25 21:56:18 +08:00
import Audio from "../extensions/Audio.ts";
2024-12-30 20:53:12 +08:00
import { uuid } from "../utils/UUID.ts";
import Toc from "../extensions/Toc.ts";
2024-12-20 21:35:42 +08:00
2025-01-04 21:41:32 +08:00
import { BubbleMenuPluginOptions, BubbleMenuPlugin } from "../components/menus/bubble/BubbleMenuPlugin.ts";
import { TextSelectionBubbleMenu } from "../components/menus/bubble/TextSelectionBubbleMenu.ts";
2025-01-05 22:21:31 +08:00
import { ImageBubbleMenu } from "../components/menus/bubble/ImageBubbleMenu.ts";
2025-01-04 21:41:32 +08:00
/**
* 创建浮动菜单功能
* @param name
* @param options
* @returns
*/
function createBubbleMenu(name: string, options: BubbleMenuPluginOptions) {
return Extension.create<BubbleMenuPluginOptions>({
name: name,
addOptions() {
return {
...options
}
},
addProseMirrorPlugins() {
if (!this.options.element) {
return []
}
return [
BubbleMenuPlugin({
pluginKey: this.options.pluginKey,
editor: this.editor,
element: this.options.element,
tippyOptions: this.options.tippyOptions,
shouldShow: this.options.shouldShow,
}),
]
},
})
}
/**
* 创建文本内容的浮动菜单
* @param uaiEditor
* @returns
*/
const createTextSelectionBubbleMenu = (uaiEditor: UAIEditor) => {
const container = new TextSelectionBubbleMenu(uaiEditor);
return createBubbleMenu("textSelectionBubbleMenu", {
pluginKey: 'textSelectionBubbleMenu',
element: container,
tippyOptions: {
appendTo: uaiEditor.editor.editorContainer,
arrow: false,
interactive: true,
hideOnClick: false,
placement: 'top',
},
shouldShow: ({ editor }) => {
if (!editor.isEditable) {
return false;
}
const { state: { selection } } = editor;
return !selection.empty && getTextBetween(editor.state.doc, {
from: selection.from,
to: selection.to
}).trim().length > 0
&& !editor.isActive("image");
}
})
}
2025-01-05 22:21:31 +08:00
/**
* 创建图片内容的浮动菜单
* @param uaiEditor
* @returns
*/
const createImageBubbleMenu = (uaiEditor: UAIEditor) => {
const container = new ImageBubbleMenu(uaiEditor);
return createBubbleMenu("imageBubbleMenu", {
pluginKey: 'imageBubbleMenu',
element: container,
tippyOptions: {
appendTo: uaiEditor.editor.editorContainer,
arrow: false,
interactive: true,
hideOnClick: false,
placement: 'top',
},
shouldShow: ({ editor }) => {
if (!editor.isEditable) {
return false;
}
return editor.isActive("image")
}
})
}
2024-12-20 21:35:42 +08:00
/**
* 定义编辑器的所有自定义扩展组件
* @param uaiEditor
* @param _options
* @returns
*/
export const allExtensions = (uaiEditor: UAIEditor, _options: UAIEditorOptions): Extensions => {
let extensions: Extensions = [
StarterKit.configure({
bulletList: false,
orderedList: false,
}),
2024-12-25 21:56:18 +08:00
Audio,
2024-12-23 21:43:26 +08:00
BulletList,
2024-12-22 20:13:47 +08:00
Color,
2025-01-03 21:25:56 +08:00
Export.configure({
appId: process.env.TIPTAP_APP_ID,
token: process.env.TIPTAP_JWT_TOKEN,
}),
2024-12-21 20:15:22 +08:00
FontFamily,
FontSize.configure({
2024-12-22 20:13:47 +08:00
}),
Highlight.configure({
multicolor: true
2024-12-21 20:15:22 +08:00
}),
2024-12-25 20:52:31 +08:00
Image,
2024-12-23 21:43:26 +08:00
Indent,
LineHeight,
2024-12-24 21:02:21 +08:00
Link,
2024-12-29 20:26:15 +08:00
Mathematics.configure({
shouldRender: (state, pos, node) => {
const $pos = state.doc.resolve(pos)
return node.type.name === 'text' && $pos.parent.type.name !== 'codeBlock'
}
}),
2024-12-23 22:12:31 +08:00
NodeAlign,
2024-12-23 21:43:26 +08:00
OrderedList,
2024-12-25 20:52:31 +08:00
SelectFile.configure({
allowedMimeTypes: []
}),
2025-01-05 22:21:31 +08:00
Selection,
2024-12-21 22:43:17 +08:00
Subscript,
Superscript,
2025-01-01 20:23:52 +08:00
Table.configure({
resizable: true,
lastColumnResizable: true,
allowTableNodeSelection: true,
}),
TableCell,
TableHeader,
TableRow,
2024-12-30 20:53:12 +08:00
TableOfContents.configure({
getIndex: getHierarchicalIndexes,
onUpdate: (content) => {
uaiEditor.tableOfContents = content;
uaiEditor.tocContainer.renderContents(uaiEditor);
},
scrollParent: () =>
document.querySelector(
".uai-main",
) as HTMLElement,
getId: () => uuid(),
}),
2024-12-23 21:45:56 +08:00
TaskList,
TaskItem.configure({
nested: true,
}),
2024-12-23 22:12:31 +08:00
TextAlign.configure({
types: ['heading', 'paragraph'],
}),
2024-12-21 20:15:22 +08:00
TextStyle,
2024-12-30 20:53:12 +08:00
Toc,
2024-12-21 22:43:17 +08:00
Underline,
2024-12-25 21:36:38 +08:00
Video,
2025-01-04 21:41:32 +08:00
createTextSelectionBubbleMenu(uaiEditor),
2025-01-05 22:21:31 +08:00
createImageBubbleMenu(uaiEditor),
2024-12-20 21:35:42 +08:00
];
return extensions;
}