Editor.js 配置项完全解读:基于 test/testcases.md 的初始化行为规范与源码验证
【免费下载链接】editor.jsA block-style editor with clean JSON output项目地址: https://gitcode.com/gh_mirrors/ed/editor.js
Editor.js 是一个以 Block 为单位、输出干净 JSON 的开源富文本编辑器。本文以仓库内 test/testcases.md 中 "Configuration" 章节定义的测试规范为骨架,逐项讲解holder、autofocus、placeholder、minHeight、logLevel、defaultBlock、sanitizer、tools、onReady、onChange、data、readOnly、i18n等全部配置项的预期行为,并对照 src/components/core.ts 与 types/configs/editor-config.d.ts 给出源码级验证。读完本文,你将完整掌握 Editor.js 初始化配置的每一个参数语义、默认值与边界行为,可直接作为集成开发与编写自动化测试的参考手册。
文档定位:一份按模块组织的功能验收规范
test/testcases.md是 Editor.js 的功能测试用例清单,其组织方式与官方文档不同:它不讲解 API 用法,而是用"行为描述"的方式罗列每一个配置项在给定输入下应当产生的可观测结果,并由勾选框(- [ ])标记是否已由自动化测试覆盖。这使它非常适合转化为两份资产:
- 配置参考手册——每个勾选项都是一条精确的规格说明;
- 测试设计清单——每条勾选项都可以映射为一个 Cypress 用例。
仓库中实际存在的测试(如 test/cypress/tests/initialization.cy.ts)与文档高度对应。例如readOnly用例中,通过断言div.ce-paragraph的contenteditable属性为false来验证只读模式生效:
cy.createEditor({ readOnly: true }).as('editorInstance'); cy.get('[data-cy=editorjs]') .get('div.codex-editor') .get('div.ce-paragraph') .invoke('attr', 'contenteditable') .should('eq', 'false');下文将文档中的每条规格按模块展开,并给出源码依据。
零配置初始化(Zero Configuration)
文档要求 Editor.js 在不传任何配置时具备以下默认行为:
- 在默认 id 为
editorjs的元素上初始化; - 当页面中不存在 id 为
editorjs的元素时抛出错误; - 仅使用 Paragraph 工具初始化;
- Paragraph 的内联工具栏包含全部默认 Inline Tool:
bold、italic、link。
源码 src/components/core.ts 印证了默认 holder 的兜底逻辑:
/** * If holder is empty then set a default value */ if (this.config.holder == null) { this.config.holder = 'editorjs'; }而 holder 元素缺失时的抛错逻辑位于同文件(src/components/core.ts):
if (_.isString(holder) && !$.get(holder)) { throw Error(`element with ID «${holder}» is missing. Pass correct holder's ID.`); } if (holder && _.isObject(holder) && !$.isElement(holder)) { throw Error('«holder» value must be an Element node'); }可见:字符串形式的 holder 必须是页面中存在的元素 id,对象形式的 holder 必须是 Element 节点,否则分别抛出 "element with ID ... is missing" 与 "«holder» value must be an Element node" 错误。
零配置初始化的 UI 可见性由 test/cypress/tests/initialization.cy.ts 覆盖:使用空配置对象{}创建实例后,断言div.codex-editor可见。
holder / holderId:指定挂载元素
| 输入 | 预期行为 |
|---|---|
传入holder | 在指定元素上初始化 |
传入的holder不是 Element 节点 | 抛出错误 |
同时传入holderId与holder | 抛出错误 |
| 都不传 | 默认使用 id 为editorjs的元素 |
在类型定义 types/configs/editor-config.d.ts 中,holder接受string | HTMLElement,而holderId已被标记为@deprecated,将在下一个大版本移除,官方建议统一使用holder:
/** * Element where Editor will be appended */ holder?: string | HTMLElement;core.ts 中同时给出了兼容与冲突处理(src/components/core.ts):
_.deprecationAssert(!!this.config.holderId, 'config.holderId', 'config.holder'); if (this.config.holderId && !this.config.holder) { this.config.holder = this.config.holderId; this.config.holderId = null; }若两者同时传入,会直接抛出«holderId» and «holder» param can't assign at the same time.(src/components/core.ts)。
autofocus:初始化后是否自动聚焦
文档按编辑器是否为空划分了两组行为:
空编辑器:
true:光标放入第一个空 Block;false:不放置光标;- 省略:不放置光标。
非空编辑器:
true:光标放到最后一个 Block 的末尾;false/ 省略:不放置光标。
core.ts 中的实现逻辑(src/components/core.ts)额外要求 autofocus 仅在非只读模式下生效:
if ((this.configuration as EditorConfig).autofocus === true && this.configuration.readOnly !== true) {即autofocus: true与readOnly: true同时存在时不会自动聚焦。Placeholders 测试(test/cypress/tests/ui/Placeholders.cy.ts)也使用了autofocus: true组合来验证占位符显示,说明二者可正常协同工作。
placeholder:首个空 Block 的占位符
- 传入
string:该字符串作为第一个空 Block的占位符; - 传入
false或省略:第一个空 Block 不显示占位符。
类型定义(types/configs/editor-config.d.ts)明确placeholder?: string|false,即显式false是合法的关闭方式。core.ts 中默认值兜底为(src/components/core.ts):
this.config.placeholder = this.config.placeholder || false;Placeholders 的 Cypress 测试(test/cypress/tests/ui/Placeholders.cy.ts)给出了非常完整的占位符行为矩阵,可作为验收基准:
- 传入配置后,占位符显示在
.ce-paragraph的::before伪元素中; - 在可聚焦(autofocus)状态下依旧显示;
- 用户点击聚焦后依旧显示;
- 用户全选并删除全部文本后恢复显示;
- 用户开始输入后隐藏(伪元素内容变为
none); - 用户输入纯空白字符后同样隐藏。
minHeight:编辑器底部可点击区域高度
- 传入
number:最后一个 Block 下方留出该高度的可聚焦区域; - 省略:使用默认值
300(单位 px)。
core.ts 的默认值逻辑(src/components/core.ts):
this.config.minHeight = this.config.minHeight !== undefined ? this.config.minHeight : 300;注意这里使用!== undefined判断,因此显式传入0也会被接受。该属性对应类型定义中的注释"Height of Editor's bottom area that allows to set focus on the last Block"(types/configs/editor-config.d.ts)。
logLevel:控制台日志级别
文档定义的日志过滤矩阵:
| logLevel | 输出内容 |
|---|---|
VERBOSE | 输出全部消息 |
INFO | 输出 info 与 debug 消息 |
WARN | 仅输出警告 |
ERROR | 仅输出错误 |
| 省略 | 输出全部消息(等价于VERBOSE) |
可用的级别枚举定义在 types/configs/log-levels.d.ts:
export enum LogLevels { VERBOSE = 'VERBOSE', INFO = 'INFO', WARN = 'WARN', ERROR = 'ERROR', }core.ts 的默认与生效逻辑(src/components/core.ts):
if (!this.config.logLevel) { this.config.logLevel = _.LogLevels.VERBOSE; } _.setLogLevel(this.config.logLevel);即省略时默认VERBOSE(全量输出),并在初始化时通过setLogLevel应用。开发排障时可临时调高到VERBOSE,生产环境可设为WARN或ERROR以减少控制台噪音。
defaultBlock(含 deprecated 的 initialBlock):默认 Block 工具
- 传入
string且在tools中存在同名工具:该工具作为默认工具; - 传入
string但tools中没有:回退为 Paragraph 工具; - 省略:使用 Paragraph 工具。
core.ts 的解析逻辑同时处理了新旧两个属性名(src/components/core.ts):
_.deprecationAssert(Boolean(this.config.initialBlock), 'config.initialBlock', 'config.defaultBlock'); this.config.defaultBlock = this.config.defaultBlock || this.config.initialBlock || 'paragraph';initialBlock已废弃,统一迁移到defaultBlock(类型定义见 types/configs/editor-config.d.ts);- 最终的兜底工具名是内置的
paragraph; - 空编辑器初始化时会用该默认工具生成第一个 Block(src/components/core.ts):
const defaultBlockData = { type: this.config.defaultBlock, // ... };测试中 test/cypress/tests/modules/Tools.cy.ts 与 test/cypress/tests/tools/ToolsFactory.cy.ts 均通过defaultBlock指定默认工具进行行为验证。
sanitizer:默认净化规则
- 传入
object:按传入配置清洗 HTML 标签; - 省略:使用内置默认净化配置,允许
paragraph、anchor、bold等标签。
类型定义(types/configs/editor-config.d.ts)指向SanitizerConfig(见 types/configs/sanitizer-config.d.ts)。需要说明的是,净化策略分为两层:粘贴/导入内容时依据 sanitizer 配置过滤;默认配置是"允许段落、链接、加粗等基础标签"的白名单策略。该属性与 docs/sanitizer.md 中描述的净化机制一脉相承,可在集成富文本粘贴功能时按需定制白名单。
tools:工具注册
这是文档中最为细化的配置项,逐条规格如下:
整体行为:
- 省略:仅初始化 Paragraph 工具;
- 传入对象:初始化所有传入的工具;
- 对象中的 key 在输出 JSON 中作为对应 Block 的
type字段; - value 为 JavaScript 类时,直接作为工具类使用。
value 为对象时(ToolSettings):
| 子属性 | 行为 |
|---|---|
class省略 | 跳过该工具并在控制台输出警告 |
class存在 | 使用该类的实例作为工具 |
config传对象 | 初始化工具时将该对象作为构造器config参数传入 |
shortcut传字符串 | 按下对应组合键时创建该工具 |
inlineToolbar传true | 显示内联工具栏,使用通用默认工具与顺序 |
inlineToolbar传false | 不显示内联工具栏 |
inlineToolbar传数组 | 显示内联工具栏,工具列表与顺序由数组指定 |
inlineToolbar省略 | 不显示内联工具栏 |
toolbox.title | 用作工具在工具箱中的标题 |
toolbox.icon | 用作工具图标,支持内联 HTML/SVG |
类型定义中的对应结构(types/configs/editor-config.d.ts):
tools?: { [toolName: string]: ToolConstructable|ToolSettings; }ToolConstructable | ToolSettings二选一的联合类型正是文档中"类直接使用、对象走配置"两种分支的类型化表达。完整的 ToolSettings 定义可进一步查阅 types/tools/tool-settings.d.ts,其中包含class、config、shortcut、inlineToolbar、toolbox等字段的详细类型注释。
onReady 与 onChange:生命周期回调
onReady传入函数:编辑器就绪后调用;onChange传入函数:DOM 发生变化时调用;- 两者省略:不影响初始化。
类型签名(types/configs/editor-config.d.ts):
onReady?(): void; onChange?(api: API, event: BlockMutationEvent | BlockMutationEvent[]): void;注意onChange的签名细节:第二个参数是描述变更的自定义事件对象,若同一时刻发生多次变更会被批处理为一个事件数组。对应的行为测试集中在 test/cypress/tests/onchange.cy.ts,事件类型定义见 types/events/block/index.ts(如 BlockAdded、BlockChanged、BlockRemoved、BlockMoved 等)。
data:初始数据渲染
- 省略:仅初始化工具,编辑器为空(后续由默认 Block 补入首块);
- 传入
{ blocks: [...] }:- 数组中的每个对象按
type找到对应工具并渲染对应 Block; - 若
type未在tools中注册,抛出错误; - 省略
blocks:仅初始化工具,编辑器为空。
- 数组中的每个对象按
data的类型为OutputData(types/configs/editor-config.d.ts),其结构定义在 types/data-formats/output-data.d.ts,即{ time, blocks, version }的标准 JSON 输出格式。这意味着editor.save()的结果可以直接作为下一次初始化的data传入,实现"保存即回显"的闭环。
readOnly:只读模式
true:- 若任一工具未定义
readOnlygetter,抛出错误; - 否则以只读模式初始化(不可编辑,但可正常渲染与交互);
- 若任一工具未定义
false或省略:正常可编辑模式。
文档与 test/cypress/tests/initialization.cy.ts 中的测试一致:只读模式下.ce-paragraph的contenteditable为false。同时,前面提到 autofocus 在只读模式下会被跳过(src/components/core.ts)。readOnly的完整运行时行为(包括工具适配器对 readOnly getter 的校验)可参考 src/modules/readonly.ts 与对应的 test/cypress/tests/readOnly.cy.ts。
i18n:国际化配置
文档以- [ ] i18n property占位,表示该模块的完整用例清单尚待补全。但仓库中已存在可确认的事实:
- 配置类型为
I18nConfig(types/configs/editor-config.d.ts),定义于 types/configs/i18n-config.d.ts; - 核心通过 src/components/modules/api/i18n.ts 与 src/components/i18n/index.ts 实现消息字典的合并与翻译;
- 仓库内置英文消息字典 src/components/i18n/locales/en/messages.json;
- 端到端测试覆盖位于 test/cypress/tests/i18n.cy.ts。
从源码结构可以推断,i18n 配置支持传入messages字典(可覆盖内置英文包)与autoRTL等选项,具体字段以 types/configs/i18n-dictionary.d.ts 与 types/configs/i18n-config.d.ts 为准。
文档中尚未展开、但值得关注的配置项
除test/testcases.md已列出的属性外,EditorConfig中还包含若干补充配置,可在集成时一并了解(见 types/configs/editor-config.d.ts):
hideToolbar:为true时不显示工具栏;inlineToolbar(顶层):为所有未单独声明的工具定义默认内联工具栏(string[] | boolean);tunes:追加到所有未自定义 tunes 的 Block 的公共 Block Tunes 列表;style.nonce:配合 CSPstyle-src策略使用的随机值,nonce会被写入编辑器注入的<style>标签(对应 test/cypress/tests/initialization.cy.ts 中的验证)。
结语:把规格文档变成可执行的验收清单
test/testcases.md的价值在于它把 Editor.js 的配置行为"规格化"了。结合 src/components/core.ts 中的默认值兜底(holder 默认editorjs、logLevel 默认VERBOSE、minHeight 默认300、defaultBlock 默认paragraph)与 types/configs/editor-config.d.ts 中的类型约束,你可以:
- 快速查证每个配置项的可选值与默认行为;
- 对照 test/cypress/tests 下的测试用例为自研工具或自定义配置补充回归用例;
- 在升级 Editor.js 时,用这份清单逐项验证既有集成没有发生行为回退。
后续如有兴趣,可继续阅读 docs/tools.md、docs/api.md 与 docs/sanitizer.md,它们分别从工具开发、公开 API 与内容净化三个方向补全 Editor.js 的完整技术图景。
【免费下载链接】editor.jsA block-style editor with clean JSON output项目地址: https://gitcode.com/gh_mirrors/ed/editor.js
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考