首页 / 资讯中心 / 文章详情

CKEditor 4 内容过滤如何驱动表格单元格属性对话框:从 allowedContent 手动测试到源码实现剖析

CKEditor 4 内容过滤如何驱动表格单元格属性对话框:从 allowedContent 手动测试到源码实现剖析 ★ FEATURED ARTICLE
前端UI组件【免费下载链接】ckeditor4The best enterprise-grade WYSIWYG editor. Fully customizable with countless features and plugins.项目地址https://gitcode.com/gh_mirrors/ck/ckeditor4点击查看免费下载导读本文围绕 CKEditor 4 仓库中的手动测试场景tests/plugins/tabletools/manual/allowedcontent.md展开深入剖析其背后的核心机制allowedContent内容过滤规则如何实时控制单元格属性Cell Properties对话框与右键上下文菜单的可用选项。读完本文你将掌握 CKEditor 4 内容过滤系统core/filter.js与表格工具插件plugins/tabletools/plugin.js的联动原理学会通过配置allowedContent精确裁剪单元格属性编辑能力并理解为何该手动测试需要反复销毁、重建编辑器。一、测试场景原文全貌关联文档tests/plugins/tabletools/manual/allowedcontent.md定义了一个清晰的手动验收场景其核心内容如下测试场景Test scenario使用复选框checkboxes选择允许的单元格属性allowed cell properties。在编辑器上使用上下文菜单context menu打开单元格属性cell properties。期望结果Expected单元格属性对话框中的选项与所勾选的复选框一一匹配。如果未勾选任何属性则单元格属性Cell Properties不会出现在上下文菜单中。意外情况Unexpected对话框选项与勾选的复选框不一致。注意事项Note勾选/取消勾选复选框会销毁并创建新的编辑器因此页面可能出现可见的闪烁flickering。这段描述虽然简短却浓缩了两个关键技术断言对话框选项由allowedContent动态裁剪以及上下文菜单项由过滤器门控。下面逐一拆解。二、配套页面复选框如何驱动 allowedContent该手动测试的实体页面为 tests/plugins/tabletools/manual/allowedcontent.html页面通过脚本动态生成复选框并建立了一张界面文案 → 过滤规则的映射表复选框文案对应过滤规则规则归属Width宽度widthtd的stylesHeight高度heighttd的stylesWord Wrap自动换行white-spacetd的stylesHorizontal Align水平对齐text-aligntd的stylesVertical Align垂直对齐vertical-aligntd的stylesCell Type单元格类型th元素本身Rows Span行跨度rowspantd的attributesCols Span列跨度colspantd的attributesBackground Color背景颜色background-colortd的stylesBorder Color边框颜色border-colortd的stylesColor Dialog颜色选择对话框colordialog额外插件extra plugin页面初始化一个基础allowedContent对象allowedContent { p: true, div: true, table: true, thead: true, tbody: true, tr: true, td: { styles: [], attributes: [] } }td的styles与attributes数组初始为空之后由复选框的changeIE8 下退化为click事件驱动增删case th: if ( state ) { allowedContent.th true; } else { delete allowedContent.th; } case rowspan: case colspan: addRemoveRule( rule, state, attributes ); break; default: addRemoveRule( rule, state, styles );addRemoveRule在数组中增删对应规则项。勾选变化后页面执行editor.destroy( true )并调用createEditor()用新的allowedContent重建编辑器function createEditor() { var config { allowedContent: allowedContent, plugins: wysiwygarea,toolbar,table,tabletools,sourcearea, extraPlugins: [] }; if ( CKEDITOR.document.findOne( input[namecolordialog] ).$.checked ) { config.extraPlugins.push( colordialog ); } return CKEDITOR.replace( editor1, config ); }值得注意的是编辑器固定加载table与tabletools插件并视复选框状态动态追加colordialog插件——这直接呼应了对话框中背景/边框颜色字段在安装颜色选择插件后才会多出取色按钮的行为。三、源码级原理对话框字段按 requiredContent 逐项过滤3.1 命令级 allowedContent 白名单cellProperties命令在 plugins/tabletools/plugin.js 中注册声明了两层过滤规则addCmd( cellProperties, new CKEDITOR.dialogCommand( cellProperties, createDef( { allowedContent: td th{width,height,border-color,background-color,white-space,vertical-align,text-align}[colspan,rowspan], requiredContent: requiredContent, ... } ) ) );其中requiredContent数组明确定义了单元格属性能力所需的全部规则var requiredContent [ td{width}, td{height}, td{border-color}, td{background-color}, td{white-space}, td{vertical-align}, td{text-align}, td[colspan], td[rowspan], th ];同时命令还注册了三组contentTransformations负责兼容旧式属性向新式样式的迁移background简写样式 →background-color旧valign属性 →vertical-align样式行级height样式 → 逐个单元格写入cke-row-height自定义属性再回写对应 #16818 的修复。3.2 对话框字段的逐项门控对话框定义位于 plugins/tabletools/dialogs/tableCell.js其中每个 UI 字段都声明了自己的requiredContent对话框字段对应requiredContentwidth / height尺寸td{width}/td{height}wordWrap自动换行td{white-space}hAlign水平对齐td{text-align}vAlign垂直对齐td{vertical-align}cellType单元格类型th[scope]rowSpan / colSpan跨行/跨列td[rowspan]/td[colspan]bgColor背景颜色td{background-color}borderColor边框颜色td{border-color}对话框构建时先对所有字段做一次过滤tableCell.jsitems CKEDITOR.tools.array.filter( items, function( item ) { var requiredContent item.requiredContent, ret; delete item.requiredContent; ret editor.filter.check( requiredContent ); if ( ret !item.isSpacer ) { itemsCount; } return ret; } );未通过的字段直接从定义中剔除再依据itemsCount 5决定对话框采用单列还是双列布局minWidth随之在 205 与 410 之间切换。除此之外plugins/dialog/plugin.js 中uiElement构造器还有第二道防线if ( elementDefinition.requiredContent !dialog.getParentEditor().filter.check( elementDefinition.requiredContent ) ) { styles.display none; this.notAllowed true; }即运行时仍以filter.check()复核不满足的字段直接隐藏并标记notAllowed。这正是自动化测试中item.notAllowed断言见下文所针对的机制。3.3 底层判定filter.check 与结果缓存上述所有门控最终都收敛到 core/filter.js 的filter.check()方法。该方法将测试规则字符串如td{width}构造成模拟元素后走一遍完整过滤流水线若元素被标记移除则返回false。其关键实现细节是结果缓存if ( typeof test string ) this._.cachedChecks[ cacheKey ] result;一旦某条规则的判定结果被缓存后续check直接命中缓存。这解释了手动测试页面源码中的一句注释// We need to recreate editor, because filter is caching checks. editor.destroy( true );——正因为过滤器缓存了判定结果修改allowedContent后必须重建编辑器或通过filter的重新加载机制才能让新规则生效。这也是勾选/取消复选框会销毁并重建编辑器、从而产生闪烁这一注意项的根本原因。四、源码级原理上下文菜单项由 filter.check 门控手动测试的第二个断言是如果未勾选任何属性则单元格属性不会出现在上下文菜单中。其实现位于 plugins/tabletools/plugin.js 的菜单项组装逻辑getItems: function() { var selection editor.getSelection(), cells getSelectedCells( selection ), items { /* 插入/删除/合并/拆分等条目固定出现 */ }; if ( editor.filter.check( requiredContent ) ) { items.tablecell_properties cells.length 0 ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED; } return items; }当编辑器当前过滤器不允许requiredContent数组中的任何一条规则例如allowedContent被配置为仅table;tbody;thead;tr;td;未放行任何td样式/属性时tablecell_properties条目就不会进入菜单对象于是右键菜单中找不到单元格属性入口反之若放行了部分规则该条目出现但具体字段仍由对话框级过滤进一步裁剪。这一上下文菜单出现与否的断言在自动化测试 tests/plugins/tabletools/allowedcontent.js 中有对应验证assert editor.name editor ? isFalse : isTrue ;五、自动化测试逐项组合验证字段显隐仓库在 tests/plugins/tabletools/allowedcontent.js 中提供了一套完备的自动化测试与手动测试场景互为印证。测试定义了一张filterMap将对话框字段映射到元素 → styles/attributes → 规则名var filterMap { width: [ td, styles, width ], height: [ td, styles, height ], wordWrap: [ td, styles, white-space ], hAlign: [ td, styles, text-align ], vAlign: [ td, styles, vertical-align ], cellType: [ th, attributes, scope ], rowSpan: [ td, attributes, rowspan ], colSpan: [ td, attributes, colspan ], bgColor: [ td, styles, background-color ], borderColor: [ td, styles, border-color ] };基准编辑器配置为allowedContent: table;tbody;thead;tr;td;然后为每个字段组合动态生成一个带extraAllowedContent的编辑器实例editor_index_allowed:key1,key2,...逐一断言字段被允许时对话框中出现对应选项未被允许时对应字段缺失或notAllowed。另一份测试 tests/plugins/tabletools/cellproperties.js 从反方向验证了同一机制test allowedContent rule: function() { // allowedContent: *[lang,dir]; table tbody thead tr th td tfoot // 断言 dialog.getContentElement( info, width ) 为 undefined字段被剔除 }, test disallowedContent rule: function() { // 默认编辑器配置下 // 断言 width / height / heightType 均 isVisible() }六、实战配置用 allowedContent 裁剪单元格属性能力理解了过滤机制后即可在实际项目中按需裁剪。以下配置组合可供直接参考1. 仅允许基础表格结构不允许任何单元格属性对应手动测试全不勾选态CKEDITOR.replace( editor1, { allowedContent: table;tbody;thead;tr;td; } );效果右键菜单不出现单元格属性即使通过 API 强行打开cellProperties对话框所有字段也均为空/隐藏。2. 只允许尺寸与合并属性禁止颜色与对齐设置CKEDITOR.replace( editor1, { allowedContent: { table: true, tbody: true, thead: true, tr: true, td: { styles: [ width, height ], attributes: [ colspan, rowspan ] } } } );效果对话框中仅保留宽度/高度/行跨度/列跨度字段其余字段被过滤菜单中的单元格属性条目仍会出现。3. 通过extraAllowedContent渐进式放行与自动化测试同思路CKEDITOR.replace( editor1, { allowedContent: table;tbody;thead;tr;td;, extraAllowedContent: { td: { styles: [ background-color ], attributes: [ rowspan ] }, th: true } } );效果仅背景颜色、行跨度、th元素被放行对应字段随之出现。注意extraAllowedContent的规则会与默认/自定义allowedContent合并后参与filter.check()判定。4. 颜色选择器联动当配置中未启用colordialog插件时背景/边框颜色字段退化为纯文本输入tableCell.js 依据editor.plugins.colordialog决定是否追加取色按钮启用后才会在字段旁出现取色按钮。七、总结与注意事项回顾整个机制链路allowedContent配置层→CKEDITOR.filter.check()判定层含结果缓存→ 对话框字段级requiredContent过滤与上下文菜单项门控表现层。手动测试场景正是用复选框直观演示了这条链路而自动化测试则从代码层面锁定了每一处行为。实际使用中需特别注意两点过滤器缓存filter.check()会缓存字符串规则的判定结果动态修改allowedContent后必须重建编辑器或显式重新加载过滤器才能生效——这正是手动测试编辑器被销毁重建、页面闪烁的来源属预期行为而非缺陷上下文菜单与对话框的过滤粒度不同菜单只看requiredContent数组整体是否至少有一条被放行对话框则逐字段过滤因此可能出现菜单有入口、但对话框内字段大幅缩减的中间状态配置时需结合两者综合考虑。进一步阅读命令与菜单定义见 plugins/tabletools/plugin.js对话框实现见 plugins/tabletools/dialogs/tableCell.js过滤判定核心见 core/filter.js自动化验证见 tests/plugins/tabletools/allowedcontent.js 与 tests/plugins/tabletools/cellproperties.js。赞分享前端UI组件【免费下载链接】ckeditor4The best enterprise-grade WYSIWYG editor. Fully customizable with countless features and plugins.项目地址https://gitcode.com/gh_mirrors/ck/ckeditor4点击查看免费下载相关推荐CKEditor 4 表格 Header 与 scope 属性联动机制解析从 manual 测试到源码实现CKEditor 4 表格 Header 与 scope 属性联动机制解析从 manual 测试到源码实现 导读 本文以 CKEditor 4 仓库中的手动测前端UI组件《Android 官方培训课程中文版》OpenGL ES 系列实战运用投影与相机视角Projection Camera View完整指南《Android 官方培训课程中文版》OpenGL ES 系列实战运用投影与相机视角Projection Camera View完整指南 本文基于本仓前端UI组件CKEditor 4 移动端粘贴对话框行为解析从 Bender 手动测试到 forcePasteDialog 源码实现CKEditor 4 移动端粘贴对话框行为解析从 Bender 手动测试到 forcePasteDialog 源码实现 导读 本文围绕 CKEditor 4前端UI组件上一篇MediaPipe 经典解决方案模型全景解析模型清单、变体选型与仓库落地指南下一篇async-stripe 支付集成实战PaymentIntent 从创建到确认的完整教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?
咨询建站