跳到正文
QuireKit
Core 开发文档
Alpha · API 持续演进

编写行为扩展

从一个插入问候语的命令开始,理解配置、storage、命令与生命周期。

假设你的产品需要一个“插入问候语”按钮。它只插入普通文字,不增加文档结构,因此使用 Extension。本章从已装有 StarterKit 的 Editor 开始;尚未创建编辑器时,先完成快速开始。

1. 区分配置、运行状态和正文

数据放在哪里会随 JSON 保存吗
按钮要插入的问候语addOptions(),由 .configure() 设置不会
本次会话收到多少次内容更新addStorage()不会
插入后的文字命令产生的正文会

需要刷新后恢复的业务数据应进入节点或标记属性,不能只存在 storage。扩展对象会缓存自己的 storage;为每个 Editor 创建一个新扩展,避免两个编辑器共享可变状态。

2. 提供一个有类型的命令

createGreeting() 定义 insertGreeting()。命令内部使用现有 insertContent() 插入文本节点,所以 <b>Hello</b> 也是字面文字。它不把宿主提供的字符串当成 HTML。

core/behavior/greeting.tsts

文件中的 declare module 为 editor.commands、chain() 和 can() 补充同一个命令类型。声明只帮助 TypeScript;实际功能仍要安装扩展才存在。

3. 安装并调用

创建 Editor 时加入 extensionsts

按钮点击时调用 editor.chain().focus().insertGreeting().run();按钮可用性读取 editor.can().insertGreeting()。输入焦点不是权限检查,应用仍需确认当前用户可以修改文档。

命令必须支持 can():不发请求、不改 storage、不操作 DOM。例程把插入交给现有命令,内容真正更新后才由 onUpdate 增加计数。查询按钮可用性不会增加它。

4. 配置与继承分别做什么

.configure({ text: '欢迎' }) 调整已有公开选项;.extend({ ... }) 修改扩展定义,例如覆盖快捷键。覆盖已有钩子又需要原行为时,通过该钩子的 this.parent?.() 调用父实现。

只安装最终扩展。把原扩展与同名的 .extend() 结果一起装入,会造成名称、Schema 或命令冲突。priority 可以调整扩展处理顺序,数值越大越早;不要用优先级掩盖两个模块争用同一功能的问题。

5. 如何验证

调用 can() 后正文与 storage 应不变;执行命令后应出现问候语,撤销后消失。创建两个 Editor,分别传入两个 createGreeting() 结果,一个编辑器的计数不应影响另一个。计数也不会出现在下载的 JSON 中。

复杂命令应通过传入的 tr、commands 与 chain 组合,避免在命令内另起 editor.commands 事务。链中后续步骤返回 false 不会回滚之前已写入的步骤,详见命令与事务。

接下来学习输入规则与状态插件,或为可持久内容添加节点与布局。完整钩子在扩展 API查询。

QuireKitQuireKit · Core、插件与 Classic 文档