# 扩展 API

扩展钩子、预设、输入规则、容器及其控制协议。

本页签名从公共包导出生成，中文说明与当前 JSDoc 同步校验。代码标识保持原名。

## 扩展定义

配置项决定功能如何安装；逐步用法见 [扩展模型](/concepts/extensions)。

### ExtensionConfig

Extension、Node 与 Mark 共用的声明式钩子；不接受 ProseMirror schema 字段。

```ts
export interface ExtensionConfig<Options extends object = Record<string, never>, Storage = Record<string, never>> {
    readonly history?: "effects";
    addSourceProvider?(this: ExtensionContext<Options, Storage, () => MsfeSourceProvider>): MsfeSourceProvider;
    readonly name?: string;
    readonly priority?: number;
    readonly requires?: readonly string[];
    addOptions?(this: OptionsContext<Options>): Options;
    addStorage?(this: ExtensionContext<Options, Storage, () => Storage>): Storage;
    addState?(this: ExtensionContext<Options, Storage, () => readonly StateSlot<unknown>[]>): readonly StateSlot<unknown>[];
    addExtensions?(this: ExtensionContext<Options, Storage, () => readonly AnyExtension[]>): readonly AnyExtension[];
    addCommands?(this: ExtensionContext<Options, Storage, () => Partial<RawCommands>>): Partial<RawCommands>;
    addAiCapabilities?(this: ExtensionContext<Options, Storage, () => readonly unknown[]>): readonly unknown[];
    addKeyboardShortcuts?(this: ExtensionContext<Options, Storage, () => Record<string, () => boolean>>): Record<string, () => boolean>;
    addEditingBoundaries?(this: ExtensionContext<Options, Storage, () => readonly EditingBoundaryRule[]>): readonly EditingBoundaryRule[];
    addBlockInput?(this: ExtensionContext<Options, Storage, () => readonly BlockInputRule[]>): readonly BlockInputRule[];
    addInputRules?(this: ExtensionContext<Options, Storage, () => readonly InputRule[]>): readonly InputRule[];
    addPasteRules?(this: ExtensionContext<Options, Storage, () => readonly PasteRule[]>): readonly PasteRule[];
    addSource?(this: ExtensionContext<Options, Storage, () => SourceSpec>): SourceSpec;
    addAttributes?(this: ExtensionContext<Options, Storage, () => Attributes>): Attributes;
    addNodeView?(this: ExtensionContext<Options, Storage, () => MsfeNodeViewRenderer>): MsfeNodeViewRenderer;
    addMarkdownExtensions?(this: ExtensionContext<Options, Storage, () => MarkdownExtension>): MarkdownExtension;
    addProjections?(this: ExtensionContext<Options, Storage, () => readonly MsfeProjection[]>): readonly MsfeProjection[];
    addProjectionLayers?(this: ExtensionContext<Options, Storage, () => readonly ProjectionLayer[]>): readonly ProjectionLayer[];
    addCodeMirrorExtensions?(this: ExtensionContext<Options, Storage, () => CodeMirrorExtension>): CodeMirrorExtension;
    onBeforeCreate?(this: ExtensionContext<Options, Storage>): void;
    onCreate?(this: ExtensionContext<Options, Storage, () => void | (() => void)>): void | (() => void);
    onUpdate?(this: ExtensionContext<Options, Storage, (event: MsfeChangeEvent) => void>, event: MsfeChangeEvent): void;
    onTransaction?(this: ExtensionContext<Options, Storage, (event: TransactionEvent) => void>, event: TransactionEvent): void;
    onSelectionUpdate?(this: ExtensionContext<Options, Storage, (event: TransactionEvent) => void>, event: TransactionEvent): void;
    onFocus?(this: ExtensionContext<Options, Storage, (event: FocusEvent) => void>, event: FocusEvent): void;
    onBlur?(this: ExtensionContext<Options, Storage, (event: FocusEvent) => void>, event: FocusEvent): void;
    onDestroy?(this: ExtensionContext<Options, Storage>): void;
}
```

**history** — 高级后端扩展对 CodeMirror 逆向 effect 历史的要求。

**addSourceProvider** — 返回：已准备的源码与历史权威；此钩子不得分配资源或建立连接。

**name** — 稳定且唯一的名称；extend 省略时继承原名。

**priority** — 依赖满足后，数值越大的扩展越先安装。

**requires** — 必须已安装的扩展名称。

**addOptions** — 返回默认配置，可通过 this.parent() 合并父级默认值。

**addStorage** — 返回每次安装独立分配的可变存储。

**addState** — 返回文档级事务状态槽及其显式历史策略。

**addExtensions** — 返回预设包含的子扩展。

**addCommands** — 返回柯里化的源码命令；嵌套命令共用同一草稿。

**addAiCapabilities** — 返回向 AI 核心描述本扩展的能力事实，类型来自 `@quirekit/ai-contract`；只在接入 AI 时读取。

**addKeyboardShortcuts** — 返回以 CodeMirror 快捷键名称为键的命令映射。

**addEditingBoundaries** — 返回导航、选区与原生编辑共同使用的隐藏源码范围规则。

**addBlockInput** — 返回：块拥有的纯回车行为，经公共防护与原子历史统一分派。

**addInputRules** — 返回针对原生输入有界后缀的转换规则。

**addPasteRules** — 返回仅作用于本次粘贴文本的转换规则。

**addSource** — 返回源码 codec；源码始终是唯一持久化依据。

**addAttributes** — 返回可持久字段、默认值和校验；精确编码由 codec 决定。

**addNodeView** — 返回组件渲染器覆盖，继续继承原有 codec。

**addMarkdownExtensions** — 返回 Lezer Markdown 解析扩展。

**addProjections** — 返回底层 CodeMirror 视觉投影。

**addProjectionLayers** — 返回声明了更新依赖和布局归属的投影层。

**addCodeMirrorExtensions** — 返回 CodeMirror 扩展，例如语法主题。

**onBeforeCreate** — 配置和状态创建后、编辑器 DOM 挂载前执行。

**onCreate** — 可返回清理函数；清理先于 onDestroy 执行。

**onUpdate** — 参数 event：已接受的源码增量变化，不包含全文序列化。

**onTransaction** — 参数 event：每笔已接受事务，包括选区和效果变化。

**onSelectionUpdate** — 参数 event：选区与前一状态不同时的已接受事务。

**onFocus** — 参数 event：原生编辑器获得焦点事件。

**onBlur** — 参数 event：原生编辑器失去焦点事件。

**onDestroy** — 销毁时按安装顺序逆序执行一次。

## 基础预设

每项接受一个扩展定义或 false；数组不是在这里追加同名功能的入口。

### StarterKitOptions

按功能覆盖或禁用预设；仍会诊断重复安装的语义归属。

```ts
export interface StarterKitOptions {
    readonly heading?: AnyExtension | false;
    readonly bold?: AnyExtension | false;
    readonly link?: AnyExtension | false;
    readonly codeBlock?: AnyExtension | false;
    readonly image?: AnyExtension | false;
    readonly emphasis?: AnyExtension | false;
    readonly inlineCode?: AnyExtension | false;
    readonly strikethrough?: AnyExtension | false;
    readonly horizontalRule?: AnyExtension | false;
    readonly blockquote?: AnyExtension | false;
    readonly listMarkers?: AnyExtension | false;
    readonly taskItem?: AnyExtension | false;
    readonly table?: AnyExtension | false;
    readonly textLiterals?: AnyExtension | false;
    readonly dataUrlFold?: AnyExtension | false;
}
```

**heading** — 标题扩展；false 表示禁用。

**bold** — 粗体扩展；false 表示禁用。

**link** — 链接扩展；false 表示禁用。

**codeBlock** — 代码块扩展，可带组件覆盖；false 表示禁用。

**image** — 图片扩展，可带资源解析和组件覆盖；false 表示禁用。

**emphasis** — 强调扩展；false 表示禁用。

**inlineCode** — 行内代码扩展；false 表示禁用。

**strikethrough** — GFM 删除线扩展；false 表示禁用。

**horizontalRule** — 主题分隔线扩展；false 表示禁用。

**blockquote** — 引用正文及前缀扩展，也可替换为带控件的宿主扩展。

**listMarkers** — 原生列表前缀扩展；false 表示禁用。

**taskItem** — 任务复选框扩展，可带 Vue 或 React 覆盖；false 表示禁用。

**table** — GFM 原生表格呈现；false 表示禁用。

**textLiterals** — 实体、转义和换行呈现；false 表示禁用。

**dataUrlFold** — 把超长的 base64 data URL 折叠成显示大小的小标签，原文不变；false 表示禁用。

## 输入规则

`InputRule` / `PasteRule` 都使用此配置；完整模块见 [输入规则](/extensions/input-rules)。

### RuleConfig

原生源码转换规则；输出是精确 Markdown 文本。

```ts
export interface RuleConfig {
    readonly find: RegExp;
    readonly handler: (context: RuleMatch) => string | null;
}
```

**find** — 对有界输入上下文匹配的正则表达式。

**handler** — 参数 context：匹配、源码坐标和只读访问。返回替换文本，或 null 保留输入。

## 容器选项

数组整体替换；controls 只管理折叠 UI，正文仍由源码编辑。

### ContainerOptions

已注册名称的容器配置；语法不包含 HTML 属性或可执行渲染函数。

```ts
export interface ContainerOptions {
    readonly types: readonly string[];
    readonly detailsOpen: boolean;
    readonly controls?: ComponentViewRenderer<ContainerControlProps>;
    readonly toggleLabel: (expanded: boolean, title: string) => string;
}
```

**types** — 允许的名称；未知名称继续按普通 Markdown 显示。

**detailsOpen** — details 初始展开状态，换文档时重置。

**controls** — 宿主组件库提供的控件；省略时使用原生无障碍按钮。

**toggleLabel** — 参数 expanded：当前状态；title：字面标题或容器名。返回本地化动作名称。

## 折叠控件

组件接收 view 属性；toggle 不改写 Markdown。

### ContainerControlProps

不改写源码的折叠控件，不引入第二份正文或选区。

```ts
export interface ContainerControlProps {
    readonly expanded: boolean;
    readonly label: string;
    readonly toggle: () => void;
}
```

**expanded** — 当前实际可见状态。

**label** — 宿主本地化的无障碍动作名称。

**toggle** — 请求一笔不改变源码的视图事务。
