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

添加自己的内容类型

以提示组为例,逐步理解节点、插入命令、显示和选区。

假设你在做知识库,需要一种“提示组”:里面可以有多个段落,用户能输入、选中、复制,并把它和正文一起保存。这已经超出了给段落换个颜色的范围——提示组是文档中一种有名称、有子内容的新结构。

本章把这种结构命名为 docsNote。先理解内容和命令,再看 Canvas/SVG 额外需要的显示与选区配置。

1. 定义它保存什么

在 feature/node.ts 中通过 Node.create() 定义提示组。下面是决定文档结构的部分:

feature/node.ts · 节点结构ts

name 是保存到 JSON 中的节点名。group: 'block' 让它像段落一样出现在正文中。content: 'block+' 表示里面至少有一个块级节点,例如段落;isolating 则让通用编辑操作尊重这个容器的边界。

完整文件还定义了 HTML 的读取与输出规则:提示组对应 aside[data-docs-note],子内容放在其中。这样复制为 HTML 时保留它的结构。以上片段只解释结构字段,完整定义在本页末尾按文件查阅。

2. 提供一个插入命令

界面应当调用“插入提示组”,不需要知道它内部如何拼接 JSON。在 feature/extension.ts 中提供 insertDocsNote(text),命令的关键部分是:

feature/extension.ts · 插入内容ts

它复用 insertContent(),所以仍经过 Core 的事务与撤销历史。完整文件为命令补充 TypeScript 声明,并通过 addExtensions() 安装节点。安装 DocsNoteFeature 后,按钮可以这样调用:

在按钮中调用ts

现在,“新增节点”和“通过界面插入它”已经连起来了。can().insertDocsNote(...) 也可以用来检查按钮是否可用。

3. 告诉 Canvas/SVG 怎样排列子内容

DOM 可以根据 HTML 生成页面元素;Canvas/SVG 使用 QuireKit 的排版结果,所以仅有 renderHTML() 还不够。提示组还需要一个布局提供者(layout provider)。

feature/layout.ts 使用引擎已有的子块排版服务:先在可用宽度内排列子段落,再把这些段落放进提示组的区域。它不自己测量浏览器 DOM,也不重新实现文字排版。addLayoutProviders() 把这项能力交给编辑器。

这一步使提示组在 Canvas 和 SVG 中都能显示。布局接口涉及尺寸、文档范围和分页,完整参数在 扩展 API中查阅;第一次接入可以先沿用此例的普通容器布局。

4. 让选区理解容器边界

用户在组内拖选时,应该像选择普通文字一样工作;从组外拖到组内时,编辑器还要知道哪些子节点属于这次选择。

feature/selection.ts 定义这两种行为:组内交给文字选区,跨越边界时按子节点处理。addSelectionAdapters() 注册它。显示与选择分开定义,才能让复制、替换和跨容器选择使用相同的内容范围。

试用并检查结果

点击“插入提示组”,在里面输入文字,拖选组内和组外的内容,再撤销。切到 SVG 后内容应继续存在;下载 JSON 可以看到 docsNote 和它包含的段落。

正在准备示例…

按职责查阅完整文件

文件什么时候看它负责什么
feature/node.ts要增加字段或修改允许的子内容节点结构、HTML 读取与输出
feature/extension.ts要安装功能或调整插入动作命令类型、命令实现、能力注册
feature/layout.ts要改变容器的排列方式Canvas/SVG 中子内容的尺寸和位置
feature/selection.ts要改变跨容器选择行为容器内部与边界的选区规则

下面一次只显示你选择的文件。先读 node.ts 和 extension.ts,需要调整排版时再读另外两个。

product/feature/extension.tsts

保存与其他格式

提示组的 JSON 与正文一起保存,恢复时必须再次安装此扩展。本例没有实现 DOCX 转换或 AI 能力;需要这些功能时,要分别通过 addDocx() 和 addAiCapabilities() 补充规则。能保存 JSON 并不代表其他文件格式已经认识这种节点。

如果你的需求是增加工具栏或侧栏,而不是新的正文结构,继续阅读产品插件。

QuireKitQuireKit · Core、插件与 Classic 文档