CKEditor 5 源码编辑功能(Source Editing)完整指南:安装、配置、限制与源码剖析
2026/9/17 7:00:04 网站建设 项目流程

CKEditor 5 源码编辑功能(Source Editing)完整指南:安装、配置、限制与源码剖析

【免费下载链接】ckeditor5Powerful rich text editor framework with a modular architecture, modern integrations, and features like collaborative editing.项目地址: https://gitcode.com/GitHub_Trending/ck/ckeditor5

导读

本文基于 CKEditor 5 开源仓库中的@ckeditor/ckeditor5-source-editing包,系统讲解「源码编辑」功能的完整使用方案。该功能允许你在富文本编辑器中直接查看和修改文档的 HTML(或 Markdown)源码,适用于需要精细控制文档结构、批量调整标签、粘贴/导出源码等场景。读完本文,你将掌握该功能的安装方式、工具栏与菜单栏配置、Markdown 源码模式、与协作/审阅类插件的兼容性边界,并能从源码层面理解其「textarea 替换编辑区」的底层实现原理。

功能概述

源码编辑(source code editing)是 CKEditor 5 提供的基础开源能力,它让你可以查看并编辑文档的源码。它属于底层文档编辑手段,直接作用于文档数据源,因此与一些高度依赖编辑器架构的插件存在兼容性限制(详见后文)。

从当前仓库的元数据看(packages/ckeditor5-source-editing/ckeditor5-metadata.json),该功能被归类为source-code-editing类别,当前版本为 48.5.0(见 packages/ckeditor5-source-editing/package.json)。其入口模块在 packages/ckeditor5-source-editing/src/index.ts,对外导出SourceEditing插件类与SourceEditingConfig配置类型。

适用编辑器类型

需要特别说明:当前开源版本的源码编辑功能仅支持 Classic Editor(经典编辑器)。从源码_isAllowedToHandleSourceEditingMode()方法(sourceediting.ts)可以看出,该插件只有在可编辑区域属于编辑器自身 DOM 树(即editable.hasExternalElement === false)时才会自行接管源码模式的切换逻辑。若要在其他编辑器类型或外部可编辑元素中使用,官方文档建议监听change:isSourceEditingMode事件自行处理(源码 sourceediting.ts 中有明确注释说明这一点)。

安装

该插件属于ckeditor5聚合包的一部分。安装整个ckeditor5包即可使用:

npm install ckeditor5

安装后,在编辑器配置中引入插件并加入工具栏:

import { ClassicEditor, SourceEditing } from 'ckeditor5'; ClassicEditor .create( { licenseKey: '<YOUR_LICENSE_KEY>', // 或者 'GPL'。 plugins: [ SourceEditing, /* ... */ ], toolbar: [ 'sourceEditing', /* ... */ ] } ) .then( /* ... */ ) .catch( /* ... */ );

按钮注册细节

从源码 sourceediting.ts 可以看到,该插件通过editor.ui.componentFactory注册了两个 UI 组件:

  • sourceEditing:工具栏按钮,显示文本为 "Source",带图标与 tooltip(label: t( 'Source' ),使用IconSource图标,样式类ck-source-editing-button);
  • menuBar:sourceEditing:菜单栏项,显示 "Show source",并设置了role: 'menuitemcheckbox'角色(源码 sourceediting.ts)。

因此你既可以把它放进toolbar配置,也可以放进menuBar配置。按钮是**可切换(toggleable)**的,其选中状态(isOn)与isSourceEditingMode属性绑定(源码 sourceediting.ts)。

Markdown 源码模式

源码编辑插件与 Markdown 输出插件配合良好:只要把 Markdown 插件一并加入编辑器,源码模式就会显示Markdown 而非 HTML,无需任何额外配置:

import { ClassicEditor, SourceEditing, Markdown } from 'ckeditor5'; ClassicEditor .create( { licenseKey: '<YOUR_LICENSE_KEY>', // 或者 'GPL'。 plugins: [ SourceEditing, Markdown, /* ... */ ], toolbar: [ 'sourceEditing', /* ... */ ] } ) .then( /* ... */ ) .catch( /* ... */ );

官方文档也指出(见 docs/features/source-editing.md):Markdown 语法简单,不能覆盖所有富文本特性。CKEditor 5 的部分功能(无论是原生还是由 GHS 特性引入的)没有 Markdown 等价表示,在 Markdown 源码视图中会被剥离、仅能以原生 HTML 呈现。包内测试对「SourceEditing 与 Markdown 集成」也有专门覆盖(见 tests/sourceediting.js)。

源码格式化逻辑

进入源码模式时,插件会对文档数据做格式化处理(formatSource(),源码 sourceediting.ts):

  • 若数据以<开头(判定为 HTML,见isHtml()sourceediting.ts),则调用formatHtml进行格式化,提升可读性;
  • 非 HTML 源码(如 Markdown)则原样返回,不做改动。

配置项详解

该功能的配置通过sourceEditing键提供,类型为SourceEditingConfig(见 src/sourceeditingconfig.ts),并通过模块增强注册到EditorConfig上(见 src/augmentation.ts)。

allowCollaborationFeatures

ClassicEditor .create( { sourceEditing: { allowCollaborationFeatures: true } } ) .then( /* ... */ ) .catch( /* ... */ );
配置项类型默认值说明
sourceEditing.allowCollaborationFeaturesbooleanfalse设为true以允许源码编辑与实时协作编辑(real-time collaboration)一起使用

该配置在插件构造函数中通过editor.config.define( 'sourceEditing.allowCollaborationFeatures', false )设置了默认值false(源码 sourceediting.ts)。需要强调的是:官方明确警告源码编辑与实时协作并非完全兼容,强行组合使用可能导致数据丢失(sourceeditingconfig.ts)。

限制与不兼容性(务必阅读)

源码编辑是一种低层级的文档编辑方式,允许直接改动文档数据源,因此与一些高度依赖编辑器架构的功能存在不兼容。使用前请逐条核对你的编辑器配置是否受影响。

实时协作(Real-time collaboration)

这是最严重的风险场景:

  • 切换到源码编辑后,远端用户产生的变更不会反映在源码中
  • 切回普通模式(保存源码)时,期间其他用户的所有更改都会被覆盖,且这种数据丢失难以被用户察觉和理解。

因此,默认情况下两者不允许同时启用。若同时加入编辑器,插件会在初始化时抛出source-editing-incompatible-with-real-time-collaboration错误(源码 sourceediting.ts,_checkCompatibility()方法)。测试用例中也对该错误场景做了覆盖(见 tests/sourceediting.js)。

只有当你明确知悉风险后,才应通过设置sourceEditing.allowCollaborationFeatures: true来显式启用两者共存。

评论与修订(Comments 与 Track changes)

评论和修订功能使用markers(标记)来标识文档中被影响的部分。在源码模式下,用户可能修改这些标记的边界——例如改变一条评论或修订的范围,甚至直接删除它们,这带来权限相关的潜在问题

当这些插件与源码编辑同时加载时,编辑器会在浏览器控制台输出警告(源码 sourceediting.ts)。若希望关闭警告,同样设置sourceEditing.allowCollaborationFeatures: true

各类 HTML 元素的支持

编辑器只保存它「理解」的更改——即仅当某个已加载插件能识别给定语法(HTML 或 Markdown)时,源码中的改动才会被保留,所有不支持的语法都会被过滤掉。

典型例子:若编辑器未加载 horizontal line 插件,你在源码中手动添加的<hr>标签,在退出源码模式后会被移除。因此:

  • 请确保编辑器配置中已包含处理各类 HTML 标签所必需的插件;
  • 若需要通过源码编辑实现高级改动,往往还需要启用HTML embedGeneral HTML support(GHS)功能,或自行编写支持某标签/属性的插件。

HTML 规范化(Normalization)

当编辑器读取源码数据时,会将其转换为规范化的、高层级的抽象数据模型(data model)再行操作。这个结构与原始 HTML 或 Markdown 代码不同。

同一个文档「状态」可能用不同 HTML 写法描述。例如:

  • <strong><em>Foo</em></strong><i><b>Foo</b></i>都会产生带加粗与斜体的 "Foo" 文本;
  • 两者在载入内部数据模型后被同等表示;
  • 当模型再被转换回源码数据时,输出会被规范化,无论原始输入是什么<i><b>Foo</b></i>最终会变成<strong><em>Foo</em></strong>

这是编辑器核心架构的直接结果,无法绕过。虽然可以修改编辑器的最终输出格式,但输入数据总是会被规范化为该输出格式。

对编辑器 UI 的影响

编辑器功能依赖高层级 API,而这些 API 在源码编辑激活时不可用。因此切换源码模式后:

  • 所有工具栏按钮都会变为禁用状态(源码中_disableCommands()对每个命令调用forceDisabled( 'SourceEditingMode' ),见 sourceediting.ts);
  • 所有对话框都会被关闭_hideVisibleDialog(),sourceediting.ts);
  • 可编辑元素会被隐藏并替换为 DOM 中的<textarea>

若你用 CSS 设置了编辑器高度,需要额外规则来保证源码模式下的高度一致。

按钮的禁用条件可从源码 sourceediting.ts 归纳为三点:

  1. 插件自身被禁用;
  2. 编辑器处于只读模式;
  3. 存在已排队的 pending action(可能修改模型,需等模型最终确定后再改动源码)。

修订历史(Revision history)

保存修改后的文档源码,内部是通过「用新数据替换旧数据」执行的。因此,该操作在修订历史中会表现为整体替换变更(插入 + 删除)。当修订历史与源码编辑一起加载时,编辑器会输出控制台警告;关闭警告同样依赖allowCollaborationFeatures配置。

受限编辑(Restricted editing)

受限编辑在源码模式下不生效:用户可以编辑文档的任何部分,也可以删除标识受限区域边界的 markers。当两者同时加载时,编辑器会输出控制台警告(源码 sourceediting.ts)。

源码级原理剖析

核心状态与依赖

SourceEditing插件(src/sourceediting.ts)依赖PendingActions插件,并声明isSourceEditingMode作为可观察状态属性(@observable),用于标识文档源码模式是否激活(sourceediting.ts)。

进入源码模式的工作流

_showSourceEditing()(sourceediting.ts)的核心流程如下:

  1. 清空模型选区(writer.setSelection( null )),避免渲染器尝试在不可见的 DOM root 中渲染选区;
  2. 遍历所有编辑根(当前仅支持 Classic Editor 单一主根,但代码按多根通用方式编写,便于外部集成复用);
  3. 对每个根:取editor.data.get( { rootName } )数据并格式化,创建<textarea>(带aria-label: 'Source code editing area')与包裹div(类名ck-source-editing-area);
  4. 将 textarea 值绑定到包裹元素的data-value属性,input事件同步更新并触发editor.ui.update()
  5. 处理原生撤销/重做:拦截Ctrl/Cmd+ZCtrl/Cmd+Y(keydown 监听),其中在 macOS 上手动调用execCommand( 'redo' )以支持Cmd+Y(参考 issue #13700,sourceediting.ts);
  6. elementReplacer.replace()用包裹元素替换 DOM 编辑根,同时给视图根添加ck-hidden类;
  7. 将 textarea 注册为可聚焦元素(editor.ui.setEditableElement( 'sourceEditing:' + rootName, textarea )),使其支持 Alt+F10 与 Esc 键盘导航;
  8. 隐藏文档大纲(若配置)、刷新批注可见性、聚焦 textarea。

自动扩展高度的 textarea 技巧

普通<textarea>无法根据内容自动扩展高度。该插件的解决方案(见源码注释 sourceediting.ts 及样式 theme/sourceediting.css):

  • 包裹元素是一个CSS grid 容器,textarea 与其::after伪元素占据同一个 grid 单元格
  • ::after的内容通过content: attr(data-value) " "设置为与 textarea 相同的文本(可见性为hidden),用于把 grid 拉伸到与内容匹配的高度;
  • 由于两个子元素占据同一单元格,两者高度始终一致,从而让 textarea 看起来像普通 div 一样随内容自动扩展,无需滚动条(resize: none; overflow: hidden;)。

退出源码模式与数据回写

_hideSourceEditing()(sourceediting.ts)与updateEditorData()(sourceediting.ts)负责数据回写:

  • 退出前先调用updateEditorData():对比新旧数据,仅在发生实际变更时才调用editor.data.set()写入模型(batchType 设为可撤销),避免空操作产生多余撤销步骤;
  • 随后移除ck-hidden类、恢复 DOM 根、清空内部映射、恢复文档大纲与批注可见性,并将焦点还给编辑视图。

与 getData() 的协同

插件在editor.data.on( 'get', ... )上挂载了高优先级监听(sourceediting.ts):当处于源码模式时调用editor.getData(),会先执行updateEditorData()将 textarea 中的最新源码回写,保证取到的数据是用户最新编辑的内容。

只读模式联动

_handleReadOnlyMode()(sourceediting.ts)会在编辑器进入只读状态时为所有 textarea 设置readOnly属性;插件同时监听change:isEnabled与编辑器change:isReadOnly事件(sourceediting.ts)。

常用 API 与调试建议

SourceEditing插件注册的公开 API:

  • 'sourceEditing'UI 按钮组件(工具栏);
  • 'menuBar:sourceEditing'菜单栏项(见前述源码注册逻辑);
  • 可观察属性isSourceEditingMode:切换布尔值即可进入/退出源码模式;
  • updateEditorData():将源码数据回写到所有隐藏编辑根。

建议使用官方 CKEditor 5 inspector 进行开发与调试,它可以帮助你直观了解编辑器内部数据结构、选区、命令状态等大量有用信息。

相关联的其他功能

如需更丰富的源码编辑能力,可以参考仓库中相关的配套功能(详见 docs/features/source-editing.md):

  • Enhanced source code editing(高级源码编辑):在模态窗口中提供带语法高亮、自动补全的源码编辑,兼容所有编辑器类型(付费插件);
  • General HTML support(GHS):允许启用未被其他专用插件覆盖的 HTML 元素、属性、类与样式;
  • Full page HTML:允许用 CKEditor 5 编辑完整 HTML 页面(从<html></html>,含页面元数据);
  • HTML embed:在编辑器中嵌入任意 HTML 片段;
  • Markdown output:以 Markdown 而非 HTML 作为输出格式。

结语

源码编辑是 CKEditor 5 中一个「小而精」的基础能力:它在经典编辑器中用简洁的 textarea 替换方案实现了对 HTML/Markdown 源码的直接查看与编辑。使用时务必记住其边界——实时协作默认互斥、未加载插件对应的标签会被过滤、HTML 输入会被规范化。理解这些限制与其底层实现(元素替换、grid 伪元素高度技巧、数据回写时机),可以帮助你在实际项目中正确集成,并为自定义外部集成(监听isSourceEditingMode)打下基础。

【免费下载链接】ckeditor5Powerful rich text editor framework with a modular architecture, modern integrations, and features like collaborative editing.项目地址: https://gitcode.com/GitHub_Trending/ck/ckeditor5

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询