CKEditor 4 Mentions 插件变音符(Diacritic)字符匹配:从 2491 缺陷修复到源码与测试验证 前端UI组件【免费下载链接】ckeditor4The best enterprise-grade WYSIWYG editor. Fully customizable with countless features and plugins.项目地址https://gitcode.com/gh_mirrors/ck/ckeditor4点击查看免费下载本篇技术指南以仓库内手动测试用例 tests/plugins/mentions/manual/diacritic.md 为核心脉络剖析 CKEditor 4 Mentions 插件在匹配带变音符字符如trąba_时的工作原理、历史缺陷Issue #2491与修复方式。读完你将掌握如何复现与验证该缺陷、默认查询正则的字符集边界、mentions全部配置项的语义以及对应的自动化测试用例从而能在自己的集成场景中正确配置 Mentions 并规避同类字符匹配问题。一、从一份手动测试用例说起仓库中tests/plugins/mentions/manual/diacritic.md是一份典型的 Bender 手动测试manual test用例用于人工验证一个真实缺陷Mentions 插件无法匹配带变音符diacritic的字符。其完整的用例元数据与操作步骤如下bender-tags: 4.11.0, 2491, bug, mentions bender-ui: collapsed bender-ckeditor-plugins: wysiwygarea, toolbar, basicstyles, mentions 1. Set Polish keyboard on your OS. 2. Focus the editor. 3. Type trąba_. ## Expected Dropdown with trąba_bomba entry shows up. ## Unexpected Nothing happens. 4. Play with the rest of the names available after typing to check if diacritic characters matching.Bender 标签bender-tags揭示了这份用例的定位4.11.0缺陷在 CKEditor 4.11.0 版本中被修复2491对应 GitHub Issue #2491详见下文 CHANGES.md 的变更记录bug, mentions这是 Mentions 插件的一个缺陷回归测试bender-ckeditor-plugins: wysiwygarea, toolbar, basicstyles, mentions手动测试页面需要加载的编辑器插件集合其中mentions依赖autocomplete、textmatch、ajax三个插件见 plugins/mentions/plugin.js 中requires声明。复现要点在于将操作系统键盘切换为波兰语Polish keyboard后输入触发 Mentions 提及随后键入trąba_—— 其中ąU0105a 下方带 ogonek 的变音符字母是关键。预期行为是下拉框立即出现trąba_bomba候选项而缺陷未修复时什么都不发生Nothing happens。二、手动测试对应的页面配置该手动测试配套的 HTML 页面 tests/plugins/mentions/manual/diacritic.html 给出了完整的编辑器初始化代码它是理解测试数据源的直接入口textarea ideditor/textarea script var editor CKEDITOR.replace( editor, { mentions: [ { feed: [ bączek, ćwikła, trąba_bomba ], minChars: 0 } ] } ); bender.tools.ignoreUnsupportedEnvironment( mentions, editor ); /script这里展示了 Mentions 最简单的数据源形态——数组 feed同步数据源feed是一个字符串数组包含三个带变音符的候选项bączek、ćwikła、trąba_bombaminChars: 0表示触发提及的最小字符数为 0即输入后立即开始匹配。三、缺陷根因#2491 与默认查询正则的字符集缺陷3.1 修复前的默认正则Mentions 插件在构造时若用户未显式提供pattern配置会调用内部函数createPattern( marker, minChars )生成默认查询正则见 plugins/mentions/plugin.jsfunction createPattern( marker, minChars ) { // Match also diacritic characters (#2491). var pattern \\ marker [_a-zA-Z0-9À-ž]; if ( minChars ) { pattern { minChars ,}; } else { pattern *; } pattern $; return new RegExp( pattern ); }修复后的默认正则等价于/[_a-zA-Z0-9À-ž]{2,}$/ // minChars 为 2默认值时 /[_a-zA-Z0-9À-ž]*$/ // minChars 为 0 时正则语义解读\\marker转义后的触发标记符默认是marker默认为见 plugins/mentions/plugin.js[_a-zA-Z0-9À-ž]匹配一个提及字符字符类由四部分构成_下划线保证trąba_bomba这类含下划线的用户名可被整体匹配a-zA-Z0-9ASCII 字母与数字À-ž拉丁扩展字符区间U00C0 至 U017E覆盖 Latin-1 Supplement 与 Latin Extended-A 中的全部带变音符字母如ą、ć、ę、ł、ń、ó、ś、ź、ż波兰语以及à、é、ü、ñ、ç、ş、ţ等欧洲语言字符{minChars,}/*最小字符数量词。注意minChars默认值为 2见 plugins/mentions/plugin.js即触发匹配至少需要后跟 2 个字符设为0时退化为*$锚定到光标前文本的末尾确保匹配的是正在输入中的最后一个提及片段。3.2 修复前的问题修复前默认正则字符类只覆盖 ASCII 字母与数字大致形如[_\w]或[a-zA-Z0-9_]。当用户键入trąba_时正则无法把ą识别为合法的提及字符导致整个trąba_片段无法被 textmatch 匹配Mentions 下拉框自然不出现——这正是手动测试用例中标记为Unexpected的 Nothing happens。该修复在 CKEditor 4.11.0 的变更记录中有明确记载见 CHANGES.md#2491: Fixed: The Mentions plugin is not matching diacritic characters.四、匹配链路textmatch 与 caseSensitive 过滤理解变音符匹配还需要看清从键入字符到下拉框出现的完整调用链。Mentions 实例在构造时把三个回调交给 autocomplete 插件见 plugins/mentions/plugin.jsthis._autocomplete new CKEDITOR.plugins.autocomplete( editor, { textTestCallback: getTextTestCallback( this.marker, this.minChars, this.pattern ), dataCallback: getDataCallback( feed, this ), itemTemplate: config.itemTemplate, outputTemplate: config.outputTemplate, throttle: this.throttle, itemsLimit: config.itemsLimit, followingSpace: this.followingSpace } );链路分两段第一段——文本探测textTestCallback。getTextTestCallback返回的回调基于 plugins/textmatch/plugin.js 提供的CKEDITOR.plugins.textMatch.match服务它把光标位置左侧的整段文本取出并剔除浏览器填充字符序列FILLING_CHAR_SEQUENCE再交给内部matchCallback用默认正则去匹配光标前紧邻的片段见 plugins/mentions/plugin.js。同时还有一个重要守卫匹配片段的前一个字符若存在且不是空白符则放弃匹配避免匹配到单词中间的子串。正则字符类是否包含ą直接决定这一段的成败——这正是 #2491 的病灶所在。第二段——数据过滤dataCallback。命中文本后getDataCallback把查询串交给 feed 处理见 plugins/mentions/plugin.js。对于数组 feed过滤逻辑是function createArrayFeed() { var data indexArrayFeed( feed ).filter( function( item ) { var itemName item.name; if ( !mentions.caseSensitive ) { itemName itemName.toLowerCase(); query query.toLowerCase(); } return itemName.indexOf( query ) 0; } ); resolveCallbackData( data ); }即数组 feed 默认不区分大小写caseSensitive默认false先将候选名与查询串都toLowerCase()再判断候选名是否以查询串开头indexOf( query ) 0。这就是为什么键入trąba_时trąba_bomba能被命中——查询串trąba_是候选名trąba_bomba的前缀。若将caseSensitive设为true则跳过小写归一化直接做前缀比较见 plugins/mentions/plugin.js。需要注意的是大小写不敏感toLowerCase只对数组 feed 生效。若使用 URL 或函数 feed结果预期已在服务端/回调中完成过滤caseSensitive不参与处理源码注释明确说明这一点。五、Mentions 配置项全解析围绕上述匹配机制Mentions 的全部配置项语义如下定义见 plugins/mentions/plugin.js 中的configDefinition配置项默认值说明feed无必填数据源支持三种形式字符串数组、后端 URL 字符串、函数marker触发自动补全的标记字符minChars2标记符后触发 Mentions 所需的最小字符数caseSensitivefalse数组 feed 是否区分大小写URL/函数 feed 无效cachetrue是否缓存 URL feed 的 HTTP 响应全局共享缓存throttle200自动补全请求的节流毫秒数autocomplete 插件默认20Mentions 覆写为200pattern内置正则自定义查询匹配正则可完全接管默认字符集itemTemplate无下拉列表中单个候选项的渲染模板outputTemplate无选中候选项后插入编辑器的 HTML 模板itemsLimit0不限下拉框最多显示的候选项数量followingSpace无选中后是否在插入内容后追加一个不换行空格nbsp;4.20.0 引入5.1 feed 的三种数据源形态数组 feed同步最简单插件自动为每一项生成id从 1 递增并做大小写不敏感的前缀匹配var definition { feed: [ Anna, Thomas, John ], minChars: 0 };URL feed异步每次键入匹配文本时向服务端发起 Ajax 请求URL 中可用{encodedQuery}占位符承载查询串。例如查询anna、URL 为/users?name{encodedQuery}时实际请求/users?nameanna。响应需为 JSON 数组。响应默认被全局缓存以避免重复请求var definition { feed: /users?query{encodedQuery} };函数 feed异步最高自由度函数接收options含query与marker和callback两个参数自行决定数据来源var definition { feed: function( opts, callback ) { var xhr new XMLHttpRequest(); xhr.onreadystatechange function() { if ( xhr.readyState 4 ) { if ( xhr.status 200 ) { callback( JSON.parse( this.responseText ) ); } else { callback( [] ); } } } xhr.open( GET, /users?name opts.query ); xhr.send(); } };使用异步 feed 时返回的候选项应为{ id, name, ... }结构name用于展示与匹配最终插入时会被自动加上marker前缀。完整的多实例配置示例来自 plugins/mentions/plugin.jsconfig.mentions [ { feed: [ Anna, Thomas, Jack ], minChars: 0 }, { feed: backendApiFunction, marker: # }, { feed: /users?query{encodedQuery}, marker: $ } ];5.2 自定义 pattern变音符的进阶控制若默认的À-ž区间仍不满足需求例如需要匹配拉丁扩展-B、希腊文、西里尔字母等更宽泛的字符可通过pattern完全自定义匹配规则例如只匹配以a开头的单词源码注释中的示例var pattern /^a\w*$/;自定义pattern会取代createPattern的默认结果因此必须自行包含marker、字符类与锚定逻辑建议以$结尾并限定在光标前文本内匹配。六、自动化测试#2491 的回归验证除手动测试外仓库还提供了与 #2491 一一对应的单元测试位于 tests/plugins/mentions/mentions.js共三个用例// (#2491) test matching diacritic characters: function() { var diacritics áàâäãéèëêíìïîóòöôõúùüûñçăşţ; this.editorBot.setHtmlWithSelection( p diacritics ^/p ); testView( this.createMentionsInstance( { feed: [ diacritics ] } ), [ diacritics ] ); }, // (#2491) test matching underscore character: function() { var expected john_doe; this.editorBot.setHtmlWithSelection( p expected ^/p ); testView( this.createMentionsInstance( { feed: [ expected ] } ), [ expected ] ); }, // (#2491) test not matching special characters: function() { ... var specialCharacters ~!#$%^*()-/.,\?|\\/[]{}.split( ), mentions this.createMentionsInstance( { feed: specialCharacters, throttle: 0, minChars: 0 } ); ... }三个用例从正反两面锁死字符集边界变音符字符必须匹配áàâäãéèëêíìïîóòöôõúùüûñçăşţ这一串拉丁变音符字母全部应被默认正则识别并触发下拉框下划线必须匹配john_doe这类含_的用户名是 Mentions 的常见场景对应手动用例中的trąba_bomba特殊字符不得匹配~!#$%^*()-/.,?|[]{} 等标点与符号不应被当作提及字符避免下拉框在无意义的输入下误触发。测试通过this.editorBot.setHtmlWithSelection( p diacritics ^/p )把光标^定位在之后再断言testView中下拉框应展示的候选项。测试文件头部声明了/* bender-ckeditor-plugins: mentions */运行前会通过bender.tools.ignoreUnsupportedEnvironment跳过不支持的环境见 tests/plugins/mentions/mentions.js。七、总结变音符匹配的正确姿势结合手动测试、源码与自动化测试可以归纳出在 CKEditor 4 中正确使用带变音符的 Mentions 提及功能的三条要点默认即支持从 4.11.0 起Mentions 默认正则的字符类[_a-zA-Z0-9À-ž]已覆盖绝大多数欧洲语言的变音符字母ą ć ę ł ń ó ś ź ż、à é ü ñ ç ş ţ等波兰键盘场景下的trąba_可直接命中trąba_bomba边界牢记下划线被视为提及字符的一部分而标点、空格与特殊符号会中断或阻止匹配minChars决定后至少需要多少个字符才触发数据源决定过滤语义数组 feed 默认大小写不敏感的前缀匹配caseSensitive仅对数组 feed 生效URL/函数 feed 的过滤由服务端或回调自行负责。若需验证或回归该行为可运行手动用例 tests/plugins/mentions/manual/diacritic.md配合其页面 diacritic.html或对应的自动化用例 tests/plugins/mentions/mentions.js。如需深入阅读实现核心逻辑集中在 plugins/mentions/plugin.js文本匹配机制见 plugins/textmatch/plugin.js自动补全宿主框架见 plugins/autocomplete/plugin.js。赞分享前端UI组件【免费下载链接】ckeditor4The best enterprise-grade WYSIWYG editor. Fully customizable with countless features and plugins.项目地址https://gitcode.com/gh_mirrors/ck/ckeditor4点击查看免费下载相关推荐CKEditor 4 Mentions 插件 caseSensitive 配置详解从源码到手动测试用例的完整指南CKEditor 4 Mentions 插件 caseSensitive 配置详解从源码到手动测试用例的完整指南 CKEditor 4 的 Mentions前端UI组件CKEditor 4 Auto Grow「失控高度」缺陷复盘从 14413 手动回归测试到插件源码解析CKEditor 4 Auto Grow「失控高度」缺陷复盘从 14413 手动回归测试到插件源码解析 本文以 CKEditor 4 仓库中 tests/pl前端UI组件CKEditor 4 Auto Link 插件源码模式兼容性修复解析2756 缺陷、根因与 Bender 回归测试CKEditor 4 Auto Link 插件源码模式兼容性修复解析 2756 缺陷、根因与 Bender 回归测试 Auto Link 是 CKEditor前端UI组件上一篇cangjie_stdx log 包实战从 getGlobalLogger 到自定义 Logger 与敏感字段过滤下一篇ImageJ完整指南免费开源的科学图像处理与分析神器创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考