资讯动态

CKEditor 4 Autocomplete 组合使用 outputTemplate 与 followingSpace 的完整指南(含回归测试与源码解析)

发布时间:2026/10/15 3:27:31 来源:尧图企业网站定制
前端UI组件【免费下载链接】ckeditor4The best enterprise-grade WYSIWYG editor. Fully customizable with countless features and plugins.项目地址https://gitcode.com/gh_mirrors/ck/ckeditor4点击查看免费下载导读本文以 CKEditor 4 仓库中的手动测试用例 outputtemplatespace.md 为核心深入讲解 Autocomplete 插件中outputTemplate自定义插入内容的 HTML 模板与followingSpace确认匹配后自动补一个空格两个配置项的组合使用方式并还原该组合下的一个经典回归 Bug#2008在连续两次自动补全之间插入的文字被错误加粗或丢失斜体。读完本文你将掌握这两个配置项的完整语义、底层commit()插入流程、如何运行 Bender 手动测试复现该场景以及配套的自动化测试证据。一、场景还原连续两次自动补全之间的样式丢失该测试用例位于仓库的 Bender 手动测试目录测试说明outputtemplatespace.md测试页面outputtemplatespace.html测试页面通过CKEDITOR.replace初始化一个 600px 宽的经典编辑器并在instanceReady事件中创建一个 Autocomplete 实例配置如下div ideditor1 /div script // Ignore test due to IE issue (#2077). if ( CKEDITOR.env.ie CKEDITOR.env.version 11 ) { bender.ignore(); } CKEDITOR.replace( editor1, { width: 600, on: { instanceReady: function( evt ) { new CKEDITOR.plugins.autocomplete( evt.editor, { textTestCallback: autocompleteUtils.getTextTestCallback(), dataCallback: autocompleteUtils.getDataCallback(), outputTemplate: strong{name}/strong, followingSpace: true } ); } } } ); /script页面顶部还带有 Bender 元信息标签声明了该用例的身份、所需插件与依赖bender-tags: 4.20.0, bug, 2008 bender-ui: collapsed bender-ckeditor-plugins: wysiwygarea, toolbar, basicstyles, autocomplete, textmatch bender-include: _helpers/utils.js解读这些标签该测试针对 4.20.0 版本引入的followingSpace功能bug 编号 #2008需要wysiwygarea、toolbar、basicstyles、autocomplete、textmatch这些插件并包含 tests/plugins/autocomplete/manual/_helpers/utils.js 提供的测试辅助工具内置john、thomas、anna、cris、julia五条候选数据。手动复现步骤按测试说明依次操作聚焦编辑器Focus the editor。点击斜体italic样式按钮让后续输入的文字带上斜体样式。输入触发第一次自动补全。接受回车确认第一条候选项。输入and注意两端各有一个空格。再次输入触发第二次自动补全。再次接受第一条候选项。期望结果与异常现象对比项内容Expected result期望结果两次自动补全结果之间的文字and不应被加粗但应保持斜体Actual result异常现象Bug 修复前中间的文字被错误加粗或者丢失了斜体样式也就是说outputTemplate: strong{name}/strong本应只让被补全的候选值如john加粗但在此 Bug 影响下样式越界污染到了补全值之后的普通文本。二、两个核心配置项outputTemplate 与 followingSpaceoutputTemplate决定补全结果插入什么 HTML在 plugins/autocomplete/plugin.js 中outputTemplate被描述为作为自动补全项被确认commit时插入到编辑器中的标记模板支持通过候选数据项的属性做模板占位符插值例如var outputTemplate a href/tracker/{ticket}#{ticket} ({name})/a;其构造逻辑plugin.js/** * Template of markup to be inserted as the autocomplete item gets committed. * You can use {link CKEDITOR.plugins.autocomplete.model.item item} properties to customize the template. * property {CKEDITOR.template} [outputTemplatenull] */ this.outputTemplate config.outputTemplate ! undefined ? new CKEDITOR.template( config.outputTemplate ) : null;关键点未配置时默认值为null此时插入的就是候选数据项的name纯文本。配置后会被包装成CKEDITOR.template实例占位符{name}、{id}等会被替换为对应数据项属性值。模板输出前数据项会经过encodeItem()做 HTML 编码plugin.js避免注入风险。outputTemplate与候选列表里的itemTemplate是不同的itemTemplate决定下拉面板中每条候选如何渲染outputTemplate决定用户回车确认后候选值以何种 HTML 形式写入编辑器内容。followingSpace确认匹配后自动补一个空格followingSpace是 4.20.0 新增的配置项Bug #2008语义为在已接受匹配项的后面追加一个空格适合需要在补全后立即继续输入的场景。相关实现plugin.js/** * Indicates if a following space should be added after inserted match into an editor. * since 4.20.0 * readonly * property {Boolean} [followingSpace] */ this.followingSpace config.followingSpace;组合使用commit() 的完整插入流程两个配置项共同作用的代码路径在commit()方法中plugin.jscommit: function( itemId ) { if ( !this.model.isActive ) { return; } this.close(); if ( itemId null ) { itemId this.model.selectedItemId; // If non item is selected abort commit. if ( itemId null ) { return; } } var item this.model.getItemById( itemId ), editor this.editor, html this.getHtmlToInsert( item ); // Insert space after accepting match (#2008). html this.followingSpace ? nbsp; : ; editor.fire( saveSnapshot ); editor.getSelection().selectRanges( [ this.model.range ] ); editor.insertHtml( html, text ); if ( this.followingSpace ) { removeLeadingSpace( editor ); } editor.fire( saveSnapshot ); }流程拆解getHtmlToInsert( item )plugin.js决定基础 HTMLgetHtmlToInsert: function( item ) { var encodedItem encodeItem( item ); return this.outputTemplate ? this.outputTemplate.output( encodedItem ) : encodedItem.name; }即有outputTemplate用模板渲染结果没有则直接使用编码后的name。若followingSpace为真在 HTML 末尾追加nbsp;非断行空格而不是普通空格避免被浏览器折叠或触发意外的空白符处理。editor.insertHtml( html, text )将这段 HTML 插入到匹配文本所在的 range 中替换掉原来的查询文本例如john被替换成strongjohn/strongnbsp;。若followingSpace为真再调用removeLeadingSpace( editor )plugin.js清理插入点之后紧邻的已有空格防止空格加倍function removeLeadingSpace( editor ) { var selection editor.getSelection(), nextNode selection.getRanges()[ 0 ].getNextNode( function( node ) { return Boolean( node.type CKEDITOR.NODE_TEXT node.getText() ); } ); if ( nextNode nextNode.getText().match( /^\s/ ) ) { var range editor.createRange(); range.setStart( nextNode, 0 ); range.setEnd( nextNode, 1 ); range.deleteContents(); } }前后各触发一次saveSnapshot保证撤销栈正确。Bug 的根源与修复方向从 commit 流程可以看出nbsp;被直接拼在outputTemplate渲染出的 HTML 字符串末尾而editor.insertHtml在插入带内联样式如斜体的文本环境时会把插入点处的现有样式传播到新插入的内容上。在连续两次补全、中间夹着and这类普通文本的场景里第二个strong{name}/strong的样式边界一旦处理不当就会把中间的文本一起加粗反过来样式传播机制也可能把中间文本应有的斜体样式吃掉。这正是该手动测试用斜体按钮 两次补全复现的回归点——它验证的是修复后outputTemplate与followingSpace组合时nbsp;及周边文本的样式边界必须精确、可控。三、同一主题下的其他手动测试用例该目录下还有一组与followingSpace直接相关的手动测试相互印证1. 基础行为followingspace测试说明followingspace.md测试页面followingspace.html操作光标置于编辑器内容末尾 → 输入→ 回车。期望结果插入后自动追加一个空格形如john ^^表示光标。 异常结果没有追加空格形如john^。2. 已有空格时不重复existingspace测试说明existingspace.md操作光标置于两个单词之间已有空格如hello ^ world→ 输入→ 回车。期望结果不会重复添加空格光标落在已有空格之后形如hello john ^world。 异常结果空格被加倍hello john ^ world或光标紧贴插入文本hello john^ world。该用例验证的正是removeLeadingSpace的去重逻辑followingSpace追加的nbsp;与紧随其后的已有空格会合并只保留一个。3. 仅 outputTemplateoutputtemplate测试说明outputtemplate.md测试页面outputtemplate.html只配置了outputTemplate: strong{name}/strong没有followingSpace操作输入→ 等待下拉出现 → 回车。期望结果插入的名字被加粗。 异常结果插入的是纯文本。这个用例单独验证了outputTemplate的基础渲染能力是组合用例的单变量对照版。四、自动化测试从手动到断言除了手动测试仓库还提供了同名的自动化断言测试位于 tests/plugins/autocomplete/autocomplete.js与手动用例一一对应test following space is inserted after accepting match配置followingSpace: true后回车断言编辑器数据为pitem1nbsp;/p空格确实被插入。test following space is not doubled在已有空格前补全断言结果为pitem1nbsp;foo/p证明不会产生双空格。test following space with output template同时配置outputTemplate: strong{name}/strong与followingSpace: true断言结果为pstrongitem1/strongnbsp;foo/p。test following space with output template is not doubled在p^nbsp;foo/p上补全同样断言pstrongitem1/strongnbsp;foo/p。这四个测试组合在一起用自动化断言锁死了本文核心场景的行为契约有outputTemplate时加粗只作用于补全值本身strongitem1/strongnbsp;在 strong 之外有followingSpace时追加的空格不被重复。注意测试中还有// Ignore test due to IE issue (#2077)的跳过逻辑CKEDITOR.env.ie CKEDITOR.env.version 11IE 10 及以下时忽略因为老 IE 在插入带样式 HTML 时的行为与标准浏览器不一致——这与手动测试页面顶部的bender.ignore()完全对应。五、底层联动textmatch 与 commit 键理解该场景还需要知道补全动作如何被触发与确认触发textTestCallback借助 plugins/textmatch/plugin.js 的CKEDITOR.plugins.textMatch.match( range, callback )在 DOM 中定位光标左侧的匹配文本本测试用例中为\w*$正则见 tests/plugins/autocomplete/manual/_helpers/utils.js 的getTextTestCallback。确认回车/制表键触发commit()。默认提交按键由全局配置autocomplete_commitKeystrokes控制默认值为[ 9, 13 ]Tab 与 Enter见 plugin.js也可设为空数组来禁用。commit()内部selectRanges( [ this.model.range ] )insertHtml( html, text )的组合决定了插入内容会与周边文本的样式产生交互——这正是 outputtemplatespace 场景中样式边界问题的直接来源。六、生态联动mentions 与 emoji 中的 followingSpacefollowingSpace并非 autocomplete 独有它被集成进了基于 autocomplete 构建的两个官方插件Mentions 插件plugins/mentions/plugin.js 在configDefinition中透传followingSpace并在创建内部CKEDITOR.plugins.autocomplete实例时原样传给outputTemplate一起使用。Emoji 插件plugins/emoji/plugin.js 创建 autocomplete 实例时传入followingSpace: editor.config.emoji_followingSpace对应全局配置CKEDITOR.config.emoji_followingSpace false默认关闭见 plugins/emoji/plugin.js。启用方式config.emoji_followingSpace true;在 CHANGES.md 的 CKEditor 4.20 版本记录中该特性被官方描述为扩展了 Mentions 与 Emoji 插件新增在接受自动补全匹配后添加一个空格的功能选项为 Autocomplete 新增followingSpace选项让已接受的匹配以空格收尾。这解释了该配置的设计动机提及或:表情补全后用户通常需要立刻继续输入文字自动补空格能显著改善连续输入体验而outputTemplate则负责让这些补全内容在视觉上更丰富加粗、链接、图标等。两者组合时的样式边界问题正是 outputtemplatespace 用例存在的意义。七、如何运行这些手动测试这些manual/目录下的用例属于 Bender 手动测试体系仓库根目录的 bender.js 是其运行配置tests分组中Plugins组覆盖plugins/**路径。手动测试与自动化测试不同不会断言而是由测试人员在浏览器中按步骤操作、人工对照 Expected/Actual 结果。典型运行方式# 安装依赖后启动 bender 服务器并运行手动测试 bender server run # 在浏览器中访问 bender 提供的 manual tests 列表 # 找到 Plugins → Autocomplete → outputtemplatespace 用例按步骤验证自动化断言版则可直接随Plugins分组跑tests/plugins/autocomplete/autocomplete.js中的四个followingSpace用例会按上文第四节的断言自动验证行为是否符合契约。结语outputTemplate与followingSpace是 CKEditor 4 Autocomplete 中两个紧密配合的配置项前者决定补全结果以何种 HTML 落进正文后者决定是否自动追加一个空格。而 outputtemplatespace.md 这一手动用例精确捕捉了二者组合时的样式边界回归——中间的普通文本不该被nbsp;的样式传播波及而加粗也不该丢失已有的斜体。借助配套的 outputtemplate.md、followingspace.md、existingspace.md 手动用例以及 tests/plugins/autocomplete/autocomplete.js 的自动化断言开发者可以在自己的集成中完整复现、验证并规避这一类样式边界问题。赞分享前端UI组件【免费下载链接】ckeditor4The best enterprise-grade WYSIWYG editor. Fully customizable with countless features and plugins.项目地址https://gitcode.com/gh_mirrors/ck/ckeditor4点击查看免费下载相关推荐CKEditor 4 Autocomplete 的 followingSpace 与既有空格场景手动测试 existingspace 全解析CKEditor 4 Autocomplete 的 followingSpace 与既有空格场景手动测试 existingspace 全解析 导读 follo前端UI组件CKEditor 4 Autocomplete 异步回调清理机制手动测试用例与源码级修复解析CKEditor 4 Autocomplete 异步回调清理机制手动测试用例与源码级修复解析 本文以 CKEditor 4 仓库中 autocomplete前端UI组件CKEditor 4 Autocomplete 键盘导航手动测试用例解读与源码实现剖析CKEditor 4 Autocomplete 键盘导航手动测试用例解读与源码实现剖析 CKEditor 4 的 autocomplete 插件允许在输入特定前端UI组件上一篇Flagsmith CLI 实战指南从安装配置到 CI/CD 管道中的功能开关与特性评估下一篇从下载到畅玩4步上手Whisky让Mac流畅运行Windows软件创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑