import SyntaxBase from '../src/core/SyntaxBase';
export interface Cherry {
options: CherryOptions;
}
export interface CherryOptions {
/** 第三方依赖 */
externals: CherryExternalsOptions;
/** 引擎配置 */
engine: CherryEngineOptions;
/** 编辑区域配置 */
editor: CherryEditorOptions;
/** 工具栏区域配置 */
toolbars: CherryToolbarOptions;
/** 文件上传回调 */
fileUpload: CherryFileUploadHandler;
/** 上传文件的时候用来指定文件类型 */
fileTypeLimitMap: {
video: string,
audio: string,
image: string,
word: string,
pdf: string,
};
/** 有哪些主题 */
theme: {className: string, label: string}[];
callback: {
/** 编辑器内容改变并完成渲染后触发 */
afterChange: CherryLifecycle;
/** 编辑器完成初次渲染后触发 */
afterInit: CherryLifecycle;
/** img 标签挂载前触发,可用于懒加载等场景 */
beforeImageMounted: (srcProp: string, src: string) => { srcProp: string; src: string };
onClickPreview: (e: MouseEvent) => void;
onCopyCode: (e: ClipboardEvent, code: string) => string|false;
changeString2Pinyin: (str: string) => string;
};
/** 预览区域配置 */
previewer: CherryPreviewerOptions;
/** 是否开启仅预览模式 */
isPreviewOnly: boolean;
/** 预览区域跟随编辑器光标自动滚动 */
autoScrollByCursor: boolean;
/** 外层容器不存在时,是否强制输出到body上 */
forceAppend: boolean;
/** 挂载DOM节点ID,引擎模式下不生效 */
id?: string;
/** 挂载DOM节点,引擎模式下不生效 */
el?: HTMLElement;
/** 初始内容,引擎模式下不生效 */
value: string;
instanceId?: string;
}
export interface CherryExternalsOptions {
[key: string]: any;
}
/**
* 自定义语法注册配置
*/
export interface CustomSyntaxRegConfig {
/** 语法class */
syntaxClass: typeof SyntaxBase;
/** 在某个hook前执行,填入hookName */
before?: string;
/** 在某个hook后执行,填入hookName */
after?: string;
/** 强制覆盖同名hook */
force?: boolean;
}
export interface CherryEngineOptions {
/** 引擎的全局配置 */
global?: {
/**
* 是否启用经典换行逻辑
* true:一个换行会被忽略,两个以上连续换行会分割成段落,
* false: 一个换行会转成
,两个连续换行会分割成段落,三个以上连续换行会转成
并分割段落
*/
classicBr?: boolean;
/**
* 全局的URL处理器,返回值将填充到编辑区域
* @param url 来源url
* @param srcType 来源类型
*/
urlProcessor?: (url: string, srcType: 'image' | 'audio' | 'video' | 'autolink' | 'link') => string;
/**
* 额外允许渲染的html标签
* 标签以英文竖线分隔,如:htmlWhiteList: 'iframe|script|style'
* 默认为空,默认允许渲染的html见src/utils/sanitize.js whiteList 属性
* 需要注意:
* - 启用iframe、script等标签后,会产生xss注入,请根据实际场景判断是否需要启用
* - 一般编辑权限可控的场景(如api文档系统)可以允许iframe、script等标签
*/
htmlWhiteList?: string;
};
/** 内置语法配置 */
syntax?: Record | false>;
/** 自定义语法 */
customSyntax?: Record;
}
export type EditorMode =
/** 仅编辑 */
| 'editOnly'
/** 仅预览 */
| 'previewOnly'
/** 双栏编辑 */
| 'edit&preview';
export interface CherryEditorOptions {
/** depends on codemirror theme name: https://codemirror.net/demo/theme.htm */
theme?: string;
/** 编辑器的高度,默认100%,如果挂载点存在内联设置的height则以内联样式为主 */
height?: string;
/** 编辑器初始化后的模式 */
defaultModel?: EditorMode;
/** 粘贴时是否自动将html转成markdown */
convertWhenPaste?: boolean;
/** 透传给codemirror的配置项 */
codemirror?: object;
}
export type CherryLifecycle = (text: string, html: string) => void;
export interface CherryPreviewerOptions {
dom: HTMLDivElement | false;
/** 预览区域的DOM className */
className: string;
enablePreviewerBubble: boolean;
// 配置图片懒加载的逻辑
lazyLoadImg: {
// 加载图片时如果需要展示loaing图,则配置loading图的地址
loadingImgPath: string;
// 同一时间最多有几个图片请求,最大同时加载6张图片
maxNumPerTime: 1 | 2 | 3 | 4 | 5 | 6,
// 不进行懒加载处理的图片数量,如果为0,即所有图片都进行懒加载处理, 如果设置为-1,则所有图片都不进行懒加载处理
noLoadImgNum: number,
// 首次自动加载几张图片(不论图片是否滚动到视野内),autoLoadImgNum = -1 表示会自动加载完所有图片
autoLoadImgNum: -1 | number;
// 针对加载失败的图片 或 beforeLoadOneImgCallback 返回false 的图片,最多尝试加载几次,为了防止死循环,最多5次。以图片的src为纬度统计重试次数
maxTryTimesPerSrc: 0 | 1 | 2 | 3 | 4 | 5,
// 加载一张图片之前的回调函数,函数return false 会终止加载操作
beforeLoadOneImgCallback: (img: HTMLImageElement) => void | boolean;
// 加载一张图片失败之后的回调函数
failLoadOneImgCallback: (img: HTMLImageElement) => void;
// 加载一张图片之后的回调函数,如果图片加载失败,则不会回调该函数
afterLoadOneImgCallback: (img: HTMLImageElement) => void;
// 加载完所有图片后调用的回调函数
afterLoadAllImgCallback: () => void;
};
}
export type CherryToolbarSeparator = '|';
export type CherryCustomToolbar = string;
export type CherryDefaultToolbar =
| CherryInsertToolbar
| CherryToolbarSeparator
| 'bold'
| 'italic'
| 'strikethrough'
| 'color'
| 'header'
| 'list'
| 'image'
| 'audio'
| 'video'
| 'link'
| 'hr'
| 'br'
| 'code'
| 'formula'
| 'toc'
| 'table'
| 'pdf'
| 'word'
| 'graph'
| 'settings';
export type CherryInsertToolbar = {
insert: string[];
};
export type CherryDefaultBubbleToolbar =
| CherryToolbarSeparator
| 'bold'
| 'italic'
| 'strikethrough'
| 'sub'
| 'sup'
| 'size'
| 'color';
export type CherryDefaultFloatToolbar =
| CherryToolbarSeparator
| 'h1'
| 'h2'
| 'h3'
| 'checklist'
| 'quote'
| 'quickTable'
| 'code';
export interface CherryToolbarOptions {
theme: 'light' | 'dark';
toolbar?:
| (CherryCustomToolbar | CherryDefaultBubbleToolbar | CherryDefaultBubbleToolbar | CherryDefaultToolbar)[]
| false;
/** 是否展示顶部工具栏 */
showToolbar?: boolean;
/** 侧边栏配置 */
sidebar?: any[] | false;
/** 选中悬停菜单配置 */
bubble?: any[] | false;
/** 新行悬停菜单配置 */
float?: any[] | false;
customMenu?: Record;
}
export interface CherryFileUploadHandler {
/**
* @param file 用户上传的文件对象
* @param callback 回调函数,接收最终的文件url
*/
(file: File,
/**
* @param params.name 回填的alt信息
* @param params.poster 封面图片地址(视频的场景下生效)
* @param params.isBorder 是否有边框样式(图片场景下生效)
* @param params.isShadow 是否有阴影样式(图片场景下生效)
* @param params.isRadius 是否有圆角样式(图片场景下生效)
* @param params.width 设置宽度,可以是像素、也可以是百分比(图片、视频场景下生效)
* @param params.height 设置高度,可以是像素、也可以是百分比(图片、视频场景下生效)
*/
callback: (url: string, params?: {name?: string, poster?: string, isBorder?: boolean, isShadow?: boolean, isRadius?: boolean; width?: string, height?: string}
) => void): void;
}