首页 / API 参考

API 参考

全部配置项、实例方法、事件、指令集与可独立使用的工具函数。包内自带 TypeScript 声明,import KEditor from 'kyle-editor' 即有完整提示。

创建实例

两种等价写法
import { KEditor } from 'kyle-editor'

const editor = new KEditor('#editor', { /* options */ })

// 或工厂方法;el 可以是选择器 / HTMLElement / Vue ref.$el
const editor = KEditor.create(el, options)

配置项 options

配置类型默认值说明
valuestring''初始 HTML;留空时取挂载节点的 innerHTML
placeholderstring'开始撰写内容…'空内容占位文案
heightnumber \| 'auto'0内容区高度:0 / 'auto' / 不写 = 随内容自动撑开(整页滚动);填 px 才固定高度并内部滚动
minHeightnumber320纸张最小高度
paperWidthnumber677版心基准宽度(与公众号一致);fluid 模式下它是最小宽度
paperMode'fluid' \| 'fixed''fluid'宽屏时版心随容器生长(两侧留白恒定)/ 恒定 paperWidth + 64
paperGapnumber24fluid 模式下单侧留白(px)
paperMaxWidthnumber0fluid 模式下版心最大宽度,0 = 不限
primaryColorstring'#07c160'主题色(CSS 变量 --ke-primary)
toolbarstring[] \| falseDEFAULT_TOOLBAR工具栏项,见 工具栏项;false 隐藏
customButtonsCustomButtonSpec[][]自定义工具栏按钮,见 自定义工具栏按钮
hideToolbarbooleanfalse隐藏工具栏
hideStatusbarbooleanfalse隐藏底部状态栏
readOnlybooleanfalse只读
autofocusbooleanfalse创建后自动聚焦
maxLengthnumber0超出后提示(软限制,不截断输入)
wordCountbooleantrue底部字数 / 媒体统计
sanitizebooleantrue初始化与 setContent 时净化 HTML
historyLimitnumber60撤销栈深度
uploader string \| object \| fn \| SimpleUploader 'mock' 普通上传(整个文件一次请求):直接给接口地址(如 '/api/upload')即可;也可 {type:'http', url} / 自定义 adapter / 函数。只配本项时不启用分片上传
chunkUploader string \| object \| fn \| ChunkUploader 'mock' 分片上传(切片并发,只打一个接口,响应里 url 非空即成功);null 表示不启用分片。与 uploader 都配置时按 upload.mode 选路;只配本项时 mode 自动为 'chunk'
upload object {mode:'auto', chunkThreshold:5MB, chunkSize:1MB, concurrency:3, retries:2, fingerprint:'fast'} 链路与分片参数;mode 为 'auto'(按体积)/ 'normal'(只普通)/ 'chunk'(只分片),另支持 completeOnUrl 覆盖「响应带 url 即成功」判定
image.compressobject\|false{maxWidth:1440, quality:0.85, minSize:300KB}上传前大图压缩
maxImageSizenumber20MB图片体积上限,超限拦截
maxVideoSizenumber512MB视频体积上限
imageAccept / videoAcceptstring常见图/视频类型文件选择器 accept
code.languagesstring[][]代码块可选语言(主名或别名,如 ['js','mysql','yml']);留空 = 全部 20 种
code.defaultLanguagestring'plaintext'新建代码块的默认语言;不在 languages 内会落到清单第一项
code.highlightbooleantrue是否语法高亮;false 时只保留纯文本(语言标记照写)
markdown.insertMode'replace'\|'append'\|'cursor''replace'Markdown 导入默认落点:替换全文 / 追加文末 / 插入光标(面板里可临时改)
markdown.maxSizenumber5MB单个 Markdown 文件体积上限(字节),0 = 不限制
markdown.gfmbooleantrueGFM 扩展:表格 / 删除线 / 任务列表 / 裸链接
markdown.breaksbooleanfalse段落内单换行是否转 <br>
markdown.linkTargetboolean\|stringfalse外链自动加 target + rel="noopener noreferrer"
markdown.frontMatterbooleantrue丢弃开头的 YAML front matter
paste.enabledbooleantrue接管粘贴
paste.cleanbooleantrue粘贴内容净化(Word/WPS 自动清洗)
paste.uploadFilesbooleantrue粘贴截图/文件即上传
paste.localizeImagesbooleanfalse尝试把外链图片下载后本地化

回调

回调签名说明
onChange(html, editor)内容变化(160ms 防抖)
onReady(editor)实例可用
onError(error)内部异常
onUpload({stage, file, kind, url, percent, info})uploadstart / uploaddone / uploaderror / uploadcancel
beforeUpload(file, kind)返回 File 改写、false 拦截(加水印、二次校验等)

工具栏项

可用的内置名字:

内置工具栏项
undo  redo  heading  fontsize  bold  italic  underline  strike  foreColor  backColor
alignLeft  alignCenter  alignRight  alignJustify  ul  ol  quote  link  image  video
table  code  markdown  hr  clear  source  preview  fullscreen

|        分隔符
:tail    右对齐标记(其后的按钮吸附在工具栏右端)

此外可放入 customButtons 里定义的按钮 name(如 toolbar: ['bold', '|', 'tpl'])。未传 toolbar 时,自定义按钮会自动插入工具栏:写了 position 按 position 放,没写则追加到主区末尾(插在 :tail 之前)。

自定义工具栏
toolbar: ['undo', 'redo', '|', 'bold', 'italic', '|', 'image', 'video', ':tail', 'source']

工具栏始终单行显示,放不下时可左右滑动,并有四重提示保证可发现性:

提示作用
常显滚动条静止时也能从滑块长度看出「还有更多工具」
尾部左缘渐隐 + 阴影明确表达「有工具正藏在这块底下」,滑到最右自动消失
左缘渐隐已向右滑出时提示左边还有内容
首次引导气泡「工具栏可左右滑动」,3.8s 后或首次滑动后消失,localStorage 记忆不重复弹

鼠标还可直接按住拖动平移工具栏(光标变为抓握状);触屏沿用系统原生滑动。:tail 之后的「导入MD / 源码 / 全屏」(以及 position:'tail' 的自定义按钮)始终吸附在右端可见。

下拉面板一览

按钮点击行为面板内容
heading展开「段落样式」面板正文 / 标题一 / 标题二 / 标题三,每档给出真实字号预览 + 用途说明,按钮文案跟随当前段落
fontsize展开「字号」面板12–32px 网格,当前字号高亮
foreColor一次点击直接展开颜色面板最近使用(本次会话)+ 主题颜色 + 标准颜色,色块带中文名称 tooltip,底部为取色器 + HEX 输入 + 应用;右上角「恢复默认」清除上色
backColor同上(底色)推荐底色 + 主题颜色 + 自定义;按钮上的「A」用当前底色做高亮示意
image / video展开插入面板两个页签:本地上传(点击或拖拽到虚线区)/ 网络链接(粘贴地址即可插入,附带可访问性校验提示)
table展开网格10×8 规格选择,实时显示「N 列 × M 行」
link展开表单文字 / 地址 / 新窗口打开,已链接时提供「移除链接」
code展开「插入代码块 / 代码块语言」面板20 种语言列表(含一句话说明),支持按名称/别名搜索与键盘回车;光标不在代码块内=插入新块,光标在块内=改写该块语言
markdown展开「导入 Markdown」面板(按钮文案:导入MD)两个页签:选择文件(点击或拖拽到虚线区,.md/.markdown/.txt,自动识别编码)/ 粘贴文本;下方为三种落点 + 实时转换预览与结构统计;标题栏显示字符数,底部「导入到正文」

面板统一样式:圆角卡片 + 标题栏 + 分区小标题 + 入场动画;打开时会自动记录正文选区,操作后还原,因此先选文字再点颜色一定生效。

图片缩放与对齐

点击正文中的图片会浮出气泡工具条(对齐 / 宽度 30%·60%·100% / 圆角 / 查看大图 / 替换 / 删除),同时图片右下角出现圆形拖拽把手:

  • 按住把手左右拖动,实时按容器宽度百分比等比缩放,顶部浮层显示当前宽度(如 58%)
  • 范围限制 15%–100%,不会拖出正文版心;松开即写入撤销栈,可 ⌘/Ctrl+Z 回退
  • 把手与浮层挂在编辑器容器上,不进入内容区,不会污染 getHTML() 导出与历史快照
  • 视频卡片不支持拖拽缩放(保持固定比例),可用气泡工具条的「窄版 / 宽版」切换

选中图片后,工具栏的「左对齐 / 居中 / 右对齐」与气泡工具条的对齐按钮效果完全一致 —— 都作用于图片本身(img 为块级元素,靠 margin:auto 定位),而非所在段落。图片宽度为 100% 时居中无视觉差异,先缩小再居中即可看到效果。

快捷键

快捷键作用
⌘/Ctrl + B / I / U加粗 / 斜体 / 下划线
⌘/Ctrl + K插入链接
⌘/Ctrl + Shift + K切换 HTML 源码模式
⌘/Ctrl + Z / Shift + Z / Y撤销 / 重做
⌘/Ctrl + S触发 save 事件
Esc关闭面板 / 退出预览

自定义工具栏按钮

一个 customButtons 条目 = 一个工具栏按钮。type: 'select'(默认,下拉选择)或 type: 'button'(普通按钮)。

CustomButtonSpec

字段类型默认说明
namestring—必填,唯一标识;在 toolbar 数组里用它定位,也是事件载荷的 name
positionnumber \| 'start' \| 'end' \| 'tail' \| string \| {before} \| {after}'end'按钮在工具栏中的位置,见下表(别名:at / before / after / index)
type'select' \| 'button''select'下拉选择 / 普通按钮
titlestringtext按钮 tooltip,同时作为面板标题
textstring''按钮文字;下拉按钮选中后会换成选项文字
placeholderstringtext未选中时的按钮文字
iconstring''内置图标名(link/image/plus…)或原始 SVG 字符串
widthnumber自适应面板宽度 px(限定 200–420)
searchablebooleanfalse面板内搜索框(对 label/desc/value/group 客户端过滤)
notestring''面板右上角说明文字(未搜索时显示)
emptyTextstring'暂无数据'空数据提示
cachebooleantrue缓存接口结果;面板右上角刷新按钮可强制重拉
keepValuebooleantrue记住选中项并回显到按钮文字
optionsOption[]—数据源① 静态配置
load(editor) => Option[] \| Promise—数据源② 自定义函数(优先级最高)
urlstring—数据源③ 接口地址,内部 fetch
fetchOptionsobject{}{method, headers, body, credentials, timeout, fetch, parser};timeout 默认 10000ms
pick(payload, editor) => any[]自动从响应里提取数组
link见下—跳转链接配置
insert'auto' \| 'link' \| 'html' \| 'text' \| false'auto'插入方式;auto = 链接 > item.html > 纯文本;false 不改正文
onSelect(item, ctx) => any—选中回调;返回 false 则跳过默认插入
onClick({editor, name}) => any—type:'button' 的点击回调
active / enabled(state, editor) => boolean—按钮高亮 / 可用条件

数据源优先级:load > url > options。同时配置多项时只生效优先级最高的那个。

按钮位置 position

写法效果
不写 / 'end'主区末尾,插在右侧吸附尾栏之前(多个未定位按钮共用一个分隔符)
'start'工具栏第一位
'tail'尾栏末尾(与「导入MD / 源码 / 全屏」同区;未启用 :tail 时回退主区末尾)
number第 n 个按钮之前(0 起,按视觉顺序,分隔符不计数)
'image' 等按钮名插到该按钮之前
{ before: name } / { after: name }显式锚点;锚点可以是内置按钮,也可以是另一个自定义按钮
  • 锚点找不到 → 自动回退主区末尾,不报错、不丢按钮。
  • toolbar 数组里已写过该 name → 以数组位置为准(position 忽略)。
  • 显式定位不插入额外分隔符;仅默认追加时会带一个 |。
  • 运行时可用 editor.moveButton(name, where) 移动任意按钮(包括内置按钮)。

选项对象

字段自动归一,接口原始结构一般无需转换:

字段别名(自动识别)说明
valueid key val code唯一值,用于占位符与 setButtonValue
labeltext name title主标题
descdescription sub subtitle tip副标题说明
urlhref link jumpUrl jump该项自带地址(link: true 时使用)
group—分组名,同组归到一个小标题下
html—选中后直接插入的 HTML(insert: 'html')
disabled—置灰不可选

也支持纯字符串数组:options: ['开场白', '结束语']。

数据源写法

三种数据源
// 方式 A:静态数组(也支持纯字符串、或接口原始对象,字段自动归一)
{ options: [{ value: 'a', label: '选项 A', desc: '说明', url: 'https://x.com/a' }] }
{ options: ['选项 A', '选项 B'] }

// 方式 B:自定义函数(可异步,能用编辑器实例与闭包里的 axios / 鉴权头)
{ load: async () => (await fetch('/api/tags').then((r) => r.json()))
    .map((t) => ({ value: t.id, label: t.name })) }

// 方式 C:直接给接口地址
{
  url: '/api/columns',
  fetchOptions: { method: 'POST', headers: { Authorization: 'Bearer x' }, body: '{}', timeout: 8000 },
  pick: (json) => json.result.records,   // 结构特殊时手动提取数组
}
  • 缓存:默认只请求一次,面板右上角的刷新按钮可强制重新拉取;cache: false 则每次打开都请求
  • 加载态:面板自动显示 spinner + 骨架屏;失败时显示错误文案与「重试」按钮;空数据可用 emptyText 自定义提示
  • 在编辑器外部拿数据(Vue / React 里自己请求):editor.setButtonOptions('column', list)

link 写法

写法效果
link: true用每项自带地址(url/href 字段)
link: 'https://x.com/{value}'地址模板
link: { url, text, target, mode, title }完整配置
link: (item, editor) => ({ url, text, target })完全动态
  • mode: 'insert'(默认)在光标处插入 <a>;target: '_blank'(默认)时自动加 rel="noopener noreferrer"
  • mode: 'open' 直接 window.open(url, '_blank', 'noopener,noreferrer'),不改动正文
  • 模板占位符 {value} {label} 以及选项的任意字段都会被替换(取自原始对象)
  • 安全:地址经白名单校验,javascript: / vbscript: / file: / 危险 data: 一律不生成链接(退化为插入纯文本)

onSelect 的 ctx

ctx 提供的能力
onSelect: (item, ctx) => {
  ctx.editor                 // 编辑器实例
  ctx.item                   // 选中项(归一后)
  ctx.link                   // 解析后的链接,无链接时为 null
  ctx.insertLink(override)   // 插入链接(可覆盖字段)
  ctx.insertHtml(html)       // 插入 HTML
  ctx.insertText(text)       // 插入纯文本
  ctx.open(url, target)      // 新窗口打开
  return false               // 已自行处理,跳过默认插入
}

示例

三种典型按钮
KEditor.create('#editor', {
  customButtons: [
    { name: 'column', text: '栏目', searchable: true, url: '/api/columns', link: true, insert: 'link' },
    {
      name: 'tpl', text: '模板', icon: 'plus',
      options: [{ value: 'opening', label: '开场白', desc: '问候 + 导读', group: '通用' }],
      link: { url: 'https://mp.weixin.qq.com/s/tpl-{value}', text: '【{label}】' },
      onSelect: (item) => track('tpl', item.value),
    },
    {
      name: 'date', type: 'button', text: '日期',
      onClick: ({ editor }) => editor.commands.insertHTML('<p>2026-10-13</p>'),
    },
  ],
})

代码块(语言 + 语法高亮)

内置 20 种语言(plaintext javascript typescript html css json python java go rust c csharp php ruby sql bash yaml ini markdown diff),并支持别名(js ts py golang yml sh md c++ cs mysql toml …)。

代码块 API
// 插入(lang 可省,用 options.code.defaultLanguage)
editor.insertCode('const a = 1', 'js')
// => <pre data-k-lang="javascript"><code class="language-javascript">…</code></pre>

// 改写光标所在块的语言(返回生效语言;不在代码块内返回 null)
editor.setCodeLanguage('sql')
editor.getCodeLanguage()                    // 'sql';不在块内为 ''

editor.codeLanguages()                      // [{ value, label, hint }, …](受 options.code.languages 裁剪)
editor.highlightCode()                      // 手动重跑全量高亮,返回处理的代码块数量
editor.lastCodeLang                         // 最近一次选择的语言(下次插入默认沿用)
editor.getState().inCode                    // 光标是否在代码块内

标记与产物约定:

  • 语言同时写在 <pre data-k-lang="javascript"> 与 <code class="language-javascript">;外部 HTML 只带 class="language-xxx" 也能识别并补上标记
  • 块右上角显示语言角标(data-k-lang,plaintext 不显示),纯 CSS 实现,不进入 getHTML()
  • 高亮只在编辑器/预览里显示:getHTML()、源码模式、复制出去的 HTML 都是不含 token <span> 的干净代码,重新导入会自动重新高亮;预览面板走 getHTML({ clean: 'preview' })(同样清理内部属性,但保留高亮)
  • 在块内打字会(防抖 140ms)重新高亮并保持块内光标;输入法组字期间跳过;单块超过 60 KB 退化为纯文本
  • 样式类名 ke-tok-{kw,str,com,num,typ,fn,op,var,tag,attr,sel,prop,key,bool,meta,ins,del},作用域限定在 .ke-content 内,宿主可覆盖配色

导入 Markdown

尾栏「导入MD」按钮打开导入面板(选文件 / 粘文本 + 实时预览 + 结构统计 + 三种落点);把 .md / .markdown / .txt 文件拖进正文也会自动转换(默认替换全文)。转换产物就是正文规范里的普通 HTML,围栅代码块会带上 data-k-lang 并高亮。

纯函数(不依赖实例)
markdownToHtml('# 标题\n\n正文', { gfm: true })  // => '<h1>标题</h1>\n<p>正文</p>'

markdownSummary(html)
// => { headings, paragraphs, lists, items, codeBlocks, quotes, tables, images, links }

isMarkdownFile({ name: 'a.md', type: '' })       // => true(按 MIME + 扩展名,.txt 也算)
readMarkdownFile(file)                           // => 文本(严格 UTF-8 失败时回退 gb18030 / gbk / big5)
normalizeInsertMode('append')                    // => 'append'(非法值 => 'replace')
MARKDOWN_ACCEPT                                  // <input accept> 用

实例方法见 实例属性与方法 中的 importMarkdown / setMarkdown / insertMarkdown / appendMarkdown / markdownOptions;导入成功会触发 markdownimport 事件。

实例属性与方法

实例属性
editor.id                     // 实例 id
editor.el                     // 最外层容器
editor.root                   // contenteditable 节点
editor.options                // 合并后的配置
editor.commands               // 指令集(可程序化调用)
editor.media                  // 上传/媒体管理
editor.uploader               // UploadPipeline:按 upload.mode / 体积自动选路(.pick(file) 可查询)
editor.uploaders              // { normal: SimpleUploader, chunk: ChunkUploader | null }
editor.history                // 撤销栈
editor.readOnly / sourceMode / previewMode / fullscreen
editor.lastCodeLang           // 最近选择的代码块语言
方法说明
getHTML({clean?})取当前 HTML,默认剔除编辑器内部属性、未完成占位块;clean: false 取原始 HTML(调试用),clean: 'preview' 保留代码高亮
getText()纯文本
getJSON(){html, text, counts}
setContent(html, {sanitize?, silent?})覆盖内容
appendHTML(html)在光标处插入
clear()清空并取消所有上传
focus() / blur()聚焦 / 失焦
setReadOnly(bool)切换只读
undo() / redo()撤销 / 重做(含光标位置恢复)
insertImage(url, alt?) / insertVideo(url, label?)按地址插入媒体(等同工具栏「网络链接」页签)
insertCode(code?, lang?)插入代码块,光标落在块内(lang 省则用 options.code.defaultLanguage)
setCodeLanguage(lang, target?)改写代码块语言并重新高亮(target 省则取光标所在块);返回生效语言,未命中返回 null
getCodeLanguage()光标所在代码块的语言,不在块内返回 ''
codeLanguages()语言清单 [{value,label,hint}](受 options.code.languages 裁剪)
highlightCode()手动重跑正文全量高亮,返回处理的代码块数量
importMarkdown(source, {mode?, silent?})导入 Markdown(source 可为文本 / File / {name,content})并转为 HTML,返回 {ok, html, summary, mode, chars, name};失败为 {ok:false, reason:'readonly'\|'error'}
setMarkdown(source) / insertMarkdown(source) / appendMarkdown(source)导入并分别替换全文 / 插入光标处 / 追加文末(等价于 importMarkdown + 指定 mode),均可 await
markdownOptions()当前导入配置 {insertMode, maxSize, auto}
moveCaretToEnd()光标 / 选区移到正文末尾(追加导入前的落点)
upload(file, kind?)手动触发一次上传(自动判断图片/视频)
cancelUploads()取消全部进行中任务
counts(){chars, words, images, videos, uploading}
enterSource() / exitSource() / toggleSource()源码模式
openPreview() / closePreview() / togglePreview()预览模式(默认工具栏已无预览按钮,走 API 或自行配置 toolbar)
toggleFullscreen()全屏编辑
addButton(spec, place?) / moveButton(name, where) / removeButton(name)工具栏按钮增 / 移 / 删
setButtonOptions(name, items)外部灌入数据(成为权威数据,不被旧请求覆盖)
getButtonValue(name) / setButtonValue(name, value)读 / 设当前选中项(按钮文案同步)
toolbar.openCustom(name) / toolbar.openCode()用代码打开自定义面板 / 代码块语言面板
toolbar.buttonNodes()当前工具栏按钮节点(按视觉顺序,不含分隔符)
setPaper({width?, mode?, gap?, maxWidth?}) / paperOptions()运行时改版心(宽屏留白策略)
setHeight(px \| 0 \| 'auto') / heightOptions()运行时切换内容区高度(固定 / 自适应),{height, auto}
on(type, fn) / off(type, fn)事件订阅,返回取消函数
destroy()卸载实例、清理监听与临时 URL

事件

事件载荷触发时机
ready{editor}实例挂载完成
change{html, text}内容变化
focus / blur—编辑区聚焦 / 失焦
save{html}⌘/Ctrl + S
uploadstart{file, kind}开始上传
uploaddone{file, kind, url}上传完成
uploaderror{file, kind, error}失败(已重试后)
uploadcancel{file, kind}取消
insertmedia{kind, url, node}通过「网络链接」页签插入图片/视频
sourcechange{mode: 'source'\|'visual'}源码模式切换
customselect{name, item, link, action, editor}自定义下拉按钮选中一项;action 为 'link'\|'html'\|'text'\|'open'\|'none'
customclick{name, editor}type:'button' 自定义按钮被点击
markdownimport{mode, name, summary, chars}Markdown 导入成功(mode 为实际落点,name 为文件名/空串)
error{type, error, message}内部异常(如自定义按钮 onSelect 抛错),同时走 onError

指令集 commands

程序化调用
editor.commands.toggleMark('bold' | 'italic' | 'underline' | 'strike')
editor.commands.setFontSize(18)
editor.commands.setColor('fore' | 'back', '#07c160')   // color = null 恢复默认
editor.commands.setAlign('left' | 'center' | 'right' | 'justify')
editor.commands.toggleList('ordered' | 'unordered')
editor.commands.setHeading('p' | 'h1' | 'h2' | 'h3')
editor.commands.toggleBlockquote()
editor.commands.createLink({ url, text, target })
editor.commands.removeLink()
editor.commands.insertTable(3, 2)                      // 列, 行
editor.commands.insertCodeBlock('const a = 1', 'js')   // 第二参为语言(可省)
editor.commands.setCodeLanguage('python')              // 改写光标所在块语言
editor.commands.currentCodeLang()                      // 光标所在块语言('' = 不在块内)
editor.commands.insertDivider()
editor.commands.insertHTML('<p>富文本片段</p>')
editor.commands.clearFormat()

editor.getState()   // 当前选区状态(工具栏高亮用)

独立可用的工具函数

按需导入
import {
  sanitizeHtml, formatHtml, escapeHtml, isSafeUrl, cleanWordHtml,
  mockAdapter, httpAdapter, simpleAdapter, ChunkUploader,
} from 'kyle-editor'

import {
  highlightCode, listLanguages, normalizeLang, languageLabel, isCodeBlock, LANGUAGES,
} from 'kyle-editor'

sanitizeHtml(dirtyHtml)      // 白名单净化,返回安全 HTML
formatHtml(html)             // 缩进美化(编辑器源码模式同款)
cleanWordHtml(wordHtml)      // 粘贴前的 Word/WPS 清洗
isSafeUrl('javascript:1')    // => false

highlightCode('const a = 1', 'js')
// => '<span class="ke-tok-kw">const</span> a <span class="ke-tok-op">=</span> …'(已转义)

listLanguages(['js', 'mysql'])   // => [{ value:'javascript', … }, { value:'sql', … }]
normalizeLang('MySQL')           // => 'sql'(未知语言 => 'plaintext')
languageLabel('js')              // => 'JavaScript'
isCodeBlock(preElement)          // => true(<pre> 且带 data-k-lang 或内含 <code>)

UMD / 默认导出上的静态成员

<script> 引入时直接可用:

window.KEditor
KEditor.version                 // '1.0.10'
KEditor.create(el, options)    // 工厂方法,等价于 new KEditor(...)

// 净化 / 格式化
KEditor.sanitizeHtml(html)
KEditor.formatHtml(html)
KEditor.cleanWordHtml(html)

// 上传适配器
KEditor.mockAdapter({speed})                 // 分片 put() + 整包 upload() 都支持
KEditor.httpAdapter(config)                  // 真实后端适配器(只认一个 url)
KEditor.simpleAdapter(fn)                    // 把「一个文件一次请求」包成普通上传适配器
KEditor.createSimpleUploader(option, uploadOptions)  // 造一个 SimpleUploader
KEditor.createChunkUploader(option, uploadOptions)   // 造一个 ChunkUploader
KEditor.SimpleUploader / KEditor.ChunkUploader / KEditor.UploadPipeline

// 代码高亮
KEditor.highlightCode(code, lang)
KEditor.listLanguages(only?)
KEditor.normalizeLang / KEditor.languageLabel / KEditor.isCodeBlock
KEditor.LANGUAGES                // 全部内置语言(value/label/aliases/hint)

// Markdown
KEditor.markdownToHtml / KEditor.markdownSummary
KEditor.isMarkdownFile / KEditor.readMarkdownFile
KEditor.normalizeInsertMode / KEditor.MARKDOWN_ACCEPT

KEditor.utils                    // { uid, escapeHtml }
KEditor.plugin                   // Vue 3 插件(仅 keditor-vue.umd.js)

TypeScript

包内自带 types/index.d.ts 与 types/vue.d.ts,import KEditor from 'kyle-editor' 即有完整提示,无需额外安装 @types。

类型直接可用
import KEditor, { type KEditorOptions, type KEditorInstance } from 'kyle-editor'

const options: KEditorOptions = {
  placeholder: '开始撰写内容…',
  height: 0,
}

const editor: KEditorInstance = KEditor.create('#editor', options)
editor.on('change', ({ html }) => console.log(html))

安全说明

  • 所有进入编辑器的外部 HTML(value、setContent、粘贴)都会经过 sanitizeHtml:标签 / 属性双白名单、on* 事件属性剔除、javascript: / vbscript: / file: / 非法 data: 协议拦截、style 声明逐条过滤(丢弃 expression、behavior 等)。
  • Markdown 转换产物在最后一步同样走一遍白名单净化,<script> 会被清掉或转义。
  • 自定义按钮的跳转地址经白名单校验,危险协议不生成链接(退化为插入纯文本)。

getHTML({clean: false}) 会返回含编辑器内部属性的原始 HTML,请仅在调试时使用;入库前建议再跑一次 sanitizeHtml。