/** * @description config interface * @author wangfupeng */ import type { ImageElement } from 'packages/basic-modules/src/modules/image/custom-types'; import type { VideoElement } from 'packages/video-module/src/module/custom-types'; import type { Descendant, Node, NodeEntry, Range } from 'slate'; import type { IDomEditor } from '../editor/interface'; import type { IMenuGroup } from '../menus/interface'; import type { IUploadConfig } from '../upload'; import type { DOMElement } from '../utils/dom'; interface IHoverbarConf { [key: string]: { match?: (editor: IDomEditor, n: Node) => boolean; menuKeys: string[]; }; } export type AlertType = 'success' | 'info' | 'warning' | 'error'; export type TextStyleMode = 'inline' | 'class'; export type ClassStylePolicy = 'preserve-data' | 'fallback-inline' | 'strict'; export type StyleClassTokenType = 'color' | 'bgColor' | 'fontSize' | 'fontFamily' | 'textAlign' | 'lineHeight' | 'indent'; export interface IClassStyleUnsupportedPayload { type: string; value: string; scene: 'render' | 'toHtml'; fallback: 'preserve-data' | 'inline' | 'throw'; message: string; } /** * EditorEvents 包含所有编辑器的生命周期事件。 * * @property {string} CREATED - 编辑器创建后触发,用于初始化操作。 * @property {string} DESTROYED - 编辑器销毁时触发,用于清理操作。 * @property {string} CHANGE - 编辑器内容发生变化时触发,通常用于监听输入或变动。 * @property {string} SCROLL - 编辑器滚动时触发,用于同步滚动状态或执行相关操作。 * @property {string} FULLSCREEN - 编辑器进入全屏时触发,通常用于调整布局或容器尺寸。 * @property {string} UNFULLSCREEN - 编辑器退出全屏时触发,恢复原始布局状态。 * @property {string} MODALORPANELSHOW - 弹窗或面板显示时触发,用于执行相关操作。 * @property {string} MODALORPANELHIDE - 弹窗或面板隐藏时触发,用于执行相关操作。 */ export declare const EditorEvents: { readonly CREATED: "created"; readonly DESTROYED: "destroyed"; readonly CHANGE: "change"; readonly SCROLL: "scroll"; readonly FULLSCREEN: "fullscreen"; readonly UNFULLSCREEN: "unFullScreen"; readonly MODALORPANELSHOW: "modalOrPanelShow"; readonly MODALORPANELHIDE: "modalOrPanelHide"; }; export type EditorEventType = typeof EditorEvents[keyof typeof EditorEvents]; export interface ISingleMenuConfig { [key: string]: any; iconSvg?: string; } interface IColorConfig { colors: string[]; } interface IFontSizeItem { name: string; value: string; } interface IFontSizeConfig { fontSizeList: (string | IFontSizeItem)[]; } interface IFontFamilyItem { name: string; value: string; } interface IFontFamilyConfig { fontFamilyList: (string | IFontFamilyItem)[]; } interface ILineHeightConfig { lineHeightList: string[]; } interface IImageMenuBaseConfig { checkImage?: (src: string, alt: string, url: string) => boolean | undefined | string; parseImageSrc?: (src: string) => string; } interface IInsertImageConfig extends IImageMenuBaseConfig { onInsertedImage?: (imageNode: ImageElement | null) => void; } interface IEditImageConfig extends IImageMenuBaseConfig { onUpdatedImage?: (imageNode: ImageElement | null) => void; } interface IEmotionConfig { emotions: string[]; } interface IInsertTableConfig { minWidth: number; tableHeader: { selected: boolean; }; tableFullWidth: { selected: boolean; }; } interface ILinkConfig { checkLink: (text: string, url: string) => string | boolean | undefined; parseLinkUrl: (url: string) => string; } interface IInsertVideoConfig { onInsertedVideo: (videoNode: VideoElement) => NodeEntry | Range; checkVideo: (src: string, poster: string) => string | boolean | undefined; parseVideoSrc: (url: string) => string; } export type IUploadVideoConfig = IUploadConfig; export type IUploadImageConfig = IUploadConfig & { base64LimitSize: number; }; interface ICodeLangConfig { codeLangs: { text: string; value: string; selected?: boolean; }[]; } export interface IMenuConfig { bold: ISingleMenuConfig; underline: ISingleMenuConfig; italic: ISingleMenuConfig; through: ISingleMenuConfig; code: ISingleMenuConfig; sub: ISingleMenuConfig; sup: ISingleMenuConfig; clearStyle: ISingleMenuConfig; color: IColorConfig; bgColor: IColorConfig; fontSize: IFontSizeConfig; fontFamily: IFontFamilyConfig; indent: ISingleMenuConfig; delIndent: ISingleMenuConfig; justifyLeft: ISingleMenuConfig; justifyRight: ISingleMenuConfig; justifyCenter: ISingleMenuConfig; justifyJustify: ISingleMenuConfig; lineHeight: ILineHeightConfig; insertImage: IInsertImageConfig; deleteImage: ISingleMenuConfig; editImage: IEditImageConfig; viewImageLink: ISingleMenuConfig; imageWidth30: ISingleMenuConfig; imageWidth50: ISingleMenuConfig; imageWidth100: ISingleMenuConfig; editorImageSizeMenu: ISingleMenuConfig; divider: ISingleMenuConfig; emotion: IEmotionConfig; insertLink: ILinkConfig; editLink: ILinkConfig; unLink: ISingleMenuConfig; viewLink: ISingleMenuConfig; codeBlock: ISingleMenuConfig; blockquote: ISingleMenuConfig; headerSelect: ISingleMenuConfig; header1: ISingleMenuConfig; header2: ISingleMenuConfig; header3: ISingleMenuConfig; header4: ISingleMenuConfig; header5: ISingleMenuConfig; header6: ISingleMenuConfig; todo: ISingleMenuConfig; formatPainter: ISingleMenuConfig; redo: ISingleMenuConfig; undo: ISingleMenuConfig; fullScreen: ISingleMenuConfig; enter: ISingleMenuConfig; bulletedList: ISingleMenuConfig; numberedList: ISingleMenuConfig; insertTable: ISingleMenuConfig; deleteTable: ISingleMenuConfig; insertTableRow: IInsertTableConfig; deleteTableRow: ISingleMenuConfig; insertTableCol: ISingleMenuConfig; deleteTableCol: ISingleMenuConfig; tableHeader: ISingleMenuConfig; tableFullWidth: ISingleMenuConfig; mergeTableCell: ISingleMenuConfig; splitTableCell: ISingleMenuConfig; setTableProperty: ISingleMenuConfig; setTableCellProperty: ISingleMenuConfig; insertVideo: IInsertVideoConfig; uploadVideo: IUploadVideoConfig; editVideoSize: ISingleMenuConfig; editVideoSrc: ISingleMenuConfig; uploadImage: IUploadImageConfig; codeSelectLang: ICodeLangConfig; } export type IMenuConfigUpdate = { [K in keyof IMenuConfig]?: Partial; }; /** * editor config */ export interface IEditorConfig { customAlert: (info: string, type: AlertType) => void; onCreated?: (editor: IDomEditor) => void; onChange?: (editor: IDomEditor) => void; onDestroyed?: (editor: IDomEditor) => void; onMaxLength?: (editor: IDomEditor) => void; onFocus?: (editor: IDomEditor) => void; onBlur?: (editor: IDomEditor) => void; /** * 自定义粘贴。返回 true 则继续粘贴,返回 false 则自行实现粘贴,阻止默认粘贴 */ customPaste?: (editor: IDomEditor, e: ClipboardEvent) => boolean; /** * 自定义复制。拦截 event 添加或修改 clipboardData 数据 */ customCopy?: (editor: IDomEditor, e: ClipboardEvent) => void; /** * 自定义 HTML 清洗逻辑。在 setHtml / 初始化 html / 默认粘贴 HTML 前执行。 * 返回值会继续进入编辑器的 HTML 解析流程。 */ sanitizeHtml?: (html: string) => string; /** * 文本/段落样式(color/bgColor/fontSize/fontFamily/textAlign/lineHeight/indent)导出模式。 * - `inline`: 输出 style 属性(默认) * - `class`: 输出 class + data-w-e-*,便于严格 CSP 场景使用 */ textStyleMode?: TextStyleMode; /** * class 模式遇到“不在受支持样式 token 集合中”的值时的处理策略。 * - `preserve-data`(默认):保留 data-w-e-*,不输出 class/inline,确保可回读但可能不展示 * - `fallback-inline`:回退为 inline style,优先保证展示 * - `strict`:直接抛错,阻止静默降级 */ classStylePolicy?: ClassStylePolicy; /** * class 模式遇到未知值时的通知回调。 */ onClassStyleUnsupported?: (payload: IClassStyleUnsupportedPayload) => void; /** * class 模式下允许输出 class 的样式 token 注册表。 * 用于扩展默认 token(需配合业务方自行提供对应 CSS)。 */ styleClassTokens?: Partial>; scroll: boolean; placeholder?: string; readOnly: boolean; autoFocus: boolean; decorate?: (nodeEntry: NodeEntry) => Range[]; maxLength?: number; MENU_CONF?: IMenuConfigUpdate; hoverbarKeys?: IHoverbarConf; EXTEND_CONF?: any; skipCacheTypes?: string[]; } export interface IInsertKeysConfig { index: number; keys: string | Array; replaceFn?: (config: string | IMenuGroup) => string | IMenuGroup; } /** * toolbar config */ export interface IToolbarConfig { toolbarKeys: Array; insertKeys: IInsertKeysConfig | Array; excludeKeys: Array; modalAppendToBody: boolean; } type PluginFnType = (editor: T) => T; export interface ICreateOption { selector: string | DOMElement; config: Partial; content?: Descendant[]; html?: string; plugins: PluginFnType[]; } export {};