前端UI组件【免费下载链接】ckeditor4The best enterprise-grade WYSIWYG editor. Fully customizable with countless features and plugins.项目地址https://gitcode.com/gh_mirrors/ck/ckeditor4点击查看免费下载导读本文以 CKEditor 4 仓库中的手动测试用例 cellpropertiescelltype.md 为骨架深入讲解“单元格属性Cell Properties”对话框中Cell Type单元格类型字段的实现原理与验证方法。该功能由tabletools插件提供并在 CKEditor 4.20.0issue #5084中引入config.tabletools_scopedHeaders配置用于区分Data、Column Header、Row Header三种单元格类型及其底层td/thscope属性映射。读完本文你将掌握该手动测试的完整操作步骤、预期结果判读方式以及从 tableCell.js 源码层面理解类型字段的读写setup/commit机制和存量内容迁移方法。一、功能背景单元格类型为什么需要“作用域表头”在 HTML 表格语义中th元素用于表头单元格而scope属性用于显式声明该表头作用于整列scopecol、整行scoperow还是列组/行组这对屏幕阅读器等无障碍工具正确建立“表头—数据”关联至关重要。CKEditor 4 的tabletools插件requires: table,dialog,contextmenu见 plugin.js在其“单元格属性”对话框中提供了一个Cell Type单元格类型下拉框。在未开启 scoped 表头功能时它只提供两个选项Datatd与Headerth。而从 4.20.0 开始当配置项config.tabletools_scopedHeaders设为true后下拉框扩展为三个选项Datatd无scope属性Column Headerth scopecolRow Headerth scoperow这一行为由 CHANGES.md 的 4.20.0 发布说明明确记载新增config.tabletools_scopedHeaders配置项用于控制带/不带[scope]属性的表头单元格的行为。二、手动测试用例结构与运行环境本文对应的关联文档位于 tests/plugins/tabletools/manual/cellpropertiescelltype.md配套的测试夹具为 cellpropertiescelltype.html。该 HTML 文件头部声明了 Bender 测试所需的信息bender-tags: 4.20.0, 5084, feature bender-ui: collapsed bender-ckeditor-plugins: wysiwygarea, toolbar, table, tabletools, sourcearea版本标签4.20.0与5084表明该用例对应 4.20.0 版本引入的 issue #5084 功能。插件集合wysiwygarea所见即所得编辑区、toolbar工具栏、table表格基础、tabletools表格工具、sourcearea源码模式用于核验生成的 HTML 结构。编辑器初始化CKEDITOR.replace( editor, { language: en, tabletools_scopedHeaders: true } )即显式开启 scoped 表头功能这是本用例与默认行为最关键的差异点。初始内容一个border1的 2×2 表格四个单元格均为tdCell 1Cell 4没有任何th。移动端处理代码中通过bender.tools.env.mobile检测到移动环境时执行bender.ignore()跳过该用例因此本用例只针对桌面端浏览器运行。该测试在 Bender 手动测试框架bender-ui: collapsed下运行操作路径是右键点击任意单元格 → 弹出上下文菜单 →Cell→Cell Properties打开对话框。三、逐步操作与预期结果完整继承原文档原文档的验证流程共七步其核心思路是在“单元格属性”对话框中反复切换单元格类型并通过打开/关闭对话框与源码模式核验每一次类型切换后底层 HTML 是否与预期一致。完整步骤如下右键点击任意单元格选择Cell→Cell Properties。预期Cell Type 字段当前值为Data因为初始单元格是td。将单元格类型改为Column Header。预期该单元格变为th类型且带有scope属性其值为col。再次右键该单元格选择Cell→Cell Properties重新打开对话框。预期Cell Type 字段回显为Column Header说明修改已被正确保存并可被重新读取。将单元格类型改为Row Header。预期该单元格变为th类型且带有scope属性其值为row。再次右键该单元格打开Cell Properties。预期Cell Type 字段回显为Row Header。将单元格类型改回Data。预期该单元格变为td类型且不再带有scope属性。继续在各种单元格类型之间来回切换逐一确认显示的类型与实际生成的 HTML 结构始终一致。原文档特别给出了核验手段的提示“Please verify cell structure via togglingSourcemode.”即每次操作完成后切换到源码模式sourcearea插件提供查看实际输出例如Column Header应对应th scopecolRow Header应对应th scoperowData应对应td且无scope。这是本用例区别于纯 UI 测试的关键——它要求从“对话框显示值”与“真实 DOM 结构”两个层面双重复核。四、源码级原理Cell Type 字段的读写映射为什么对话框能正确回显Column Header/Row Header并在提交时写出th scopecol/th scoperow答案在“单元格属性”对话框定义文件 plugins/tabletools/dialogs/tableCell.js 中。4.1 选项列表由配置决定对话框通过getAvailableCellTypes( editor )函数tableCell.js生成 Cell Type 下拉框的选项function getAvailableCellTypes( editor ) { if ( editor.config.tabletools_scopedHeaders ) { return [ [ langCell.data, td ], [ langCell.columnHeader, thc ], [ langCell.rowHeader, thr ] ]; } return [ [ langCell.data, td ], [ langCell.header, th ] ]; }可以看到开启tabletools_scopedHeaders时三个选项的内部值分别为td、thcColumn Header、thrRow Header未开启时仅两个选项td与th普通 Header。这正解释了为什么本用例开启了 scoped 配置中能够看到Column Header和Row Header两个独立选项而默认配置下只会看到单一的Header。4.2 setup把 DOM 读成对话框值Cell Type 字段的setup回调tableCell.js负责在对话框打开时把选中单元格的真实状态回显为下拉框的值setup: setupCells( function( selectedCell ) { var cellName selectedCell.getName(), scope selectedCell.getAttribute( scope ); if ( cellName td ) { return td; } switch ( scope ) { case row: return thr; case col: return thc; default: return th; } } ),映射规则非常清晰单元格实际状态setup 返回值下拉框显示tdtdDatathscoperowthrRow HeaderthscopecolthcColumn Headerth无scopethHeaderscoped 开启时对应空值场景详见下文 4.44.3 commit把对话框值写回 DOMcommit回调tableCell.js负责在点击对话框“确定”后把选择的值写回每个选中的单元格commit: function( selectedCell ) { var nameToProps { td: { name: td }, th: { name: th }, thc: { name: th, scope: col }, thr: { name: th, scope: row } }, selectedProps nameToProps[ this.getValue() ]; selectedCell.renameNode( selectedProps.name ); if ( selectedProps.scope ) { selectedCell.setAttribute( scope, selectedProps.scope ); } else { selectedCell.removeAttribute( scope ); } }关键细节有三点改名用renameNodetd与th之间通过 DOM 节点重命名完成而不是删除重建写scope用setAttributethc/thr分别写出scopecol/scoperow切回Data时必须删除scopetd选项在nameToProps中没有scope属性因此 commit 会执行removeAttribute( scope )——这正是原文档第 6 步“改为 Data 后不带有 scope 属性”的底层保证。4.4 无 scope 的存量th与迁移方案tabletools_scopedHeaders配置项的默认值为false其完整文档位于 plugin.jsCKEDITOR.config.tabletools_scopedHeaders false;文档注释plugin.js明确指出一个重要注意事项如果启用该配置而编辑器内容中恰好存在不带scope属性的th元素那么这些单元格的 “Cell Type” 值会被显示为空值。为避免该问题带th元素的旧内容需要被“迁移”——即手动或自动为其补上scope属性。仓库给出的推荐迁移方式是使用内容过滤器变换filter transformations为所有无scope的th自动补上scopecoleditor.filter.addTransformations( [ [ { element: th, left: function( el ) { return !el.attributes.scope; }, right: function( el ) { el.attributes.scope col; } } ] ] );该变换通过CKEDITOR.filter#addTransformations注册left判断“当前th没有 scope”right执行“补上scopecol”。配套的手动测试 scopedheaders.md 正是验证这一边界场景开启 scoped 表头后无scope的th在 Cell Type 下拉框中显示为空选项且可用选项仅为Data、Column Header、Row Header。五、对话框的多单元格处理与提交流程除了类型字段本身的映射tabletools的单元格属性对话框对“多选单元格”场景也有专门设计理解这一点有助于更完整地执行本文的验证读取模型对话框通过CKEDITOR.plugins.tabletools.getSelectedCells( editor.getSelection() )获取当前选中的所有单元格tableCell.js。多单元格回显字段的setup统一由setupCells包装tableCell.js。其逻辑是取第一个单元格的值若其余单元格该属性值与之不同则该字段置空避免误导用户“所有选中单元格都相同”。这也意味着在验证第 2、4、6 步时若一次性选中了多个单元格只有它们类型一致时下拉框才会显示具体值。只提交变更对话框onLoad会把每个字段的setup/commit包装为“记录打开时的值仅当提交值与打开值不同时才真正写回”tableCell.js对应历史 ticket 11439 的修复。因此重复打开对话框而不改动任何值不会对内容造成多余写入。提交后刷新选择onOk中对所有选中单元格逐一commitContent随后执行editor.forceNextSelectionCheck()、selection.selectBookmarks( bookmarks )与editor.selectionChange()tableCell.js确保操作后选择状态与工具栏命令状态同步刷新。命令注册cellProperties命令在 plugin.js 注册为对话框命令声明了allowedContent: td th{width,height,border-color,background-color,white-space,vertical-align,text-align}[colspan,rowspan]与包含th的requiredContent并设置了contextSensitive刷新逻辑——只有当光标路径位于td或th内时才处于可用状态plugin.js。六、自动化测试佐证除了手动测试用例仓库还提供了对应的自动化测试 tests/plugins/tabletools/cellproperties.js。该测试文件同时注册了三个编辑器实例bender.editors { basic: { name: basic }, scopedHeadersOn: { name: scopedHeadersOn, config: { tabletools_scopedHeaders: true } }, scopedHeadersOff: { name: scopedHeadersOff, config: { tabletools_scopedHeaders: false } } };即分别用“默认”“开启 scoped”“关闭 scoped”三种配置验证对话框各字段宽高、单位、自动换行、行列合并、对齐、颜色等的加载与提交行为与手动用例形成互补。手动用例聚焦 UI 交互与 HTML 结构核验自动化用例则从 API 层面断言dialog.getValueOf/setValueOf的结果。七、如何在本地复现与验证要复现本手动测试需要在仓库根目录下基于 Bender 测试框架运行手动测试集。仓库根目录提供了 bender.js、bender.ci.js 与 bender-runner.config.json 等配置文件。运行方式概述如下按仓库文档安装 Bender 相关依赖并启动 Bender 服务器在 Bender 界面中定位到tests/plugins/tabletools/manual目录下的cellpropertiescelltype用例桌面端浏览器按第三节的七步流程操作每步切换类型后打开Source模式核对 HTMLColumn Header→th scopecolRow Header→th scoperowData→td无scope如需验证默认配置的对照行为可参照 scopedheaders.html该用例在同一页面分别用tabletools_scopedHeaders: true与false初始化多个编辑器进行对比。八、总结围绕 cellpropertiescelltype.md 这份手动测试可以提炼出本功能的完整技术画像功能入口右键单元格 →Cell→Cell Properties对话框中的 Cell Type 下拉框配置开关config.tabletools_scopedHeaders默认false开启后提供Data/Column Header/Row Header三种类型plugin.js底层映射td、th、th scopecol、th scoperow四态与对话框内部值td/th/thc/thr一一对应由 tableCell.js 的 setup/commit 保证双向一致存量迁移无scope的th在 scoped 模式下会被显示为空选项需要借助filter.addTransformations补写scope属性完成迁移验证手段通过源码模式核验真实 HTML是确保“对话框显示”与“实际 DOM”一致的最直接手段。对于任何需要提升表格无障碍性让屏幕阅读器准确理解表头与数据单元格的关联的 CKEditor 4 集成场景本文的配置说明、源码映射与验证流程均可直接作为实施与测试依据。赞分享前端UI组件【免费下载链接】ckeditor4The best enterprise-grade WYSIWYG editor. Fully customizable with countless features and plugins.项目地址https://gitcode.com/gh_mirrors/ck/ckeditor4点击查看免费下载相关推荐CKEditor 4 表格表头作用域scoped headerstabletools_scopedHeaders 配置与“单元格属性”对话框的 Cell Type 实战指南CKEditor 4 表格表头作用域scoped headers tabletools_scopedHeaders 配置与“单元格属性”对话框的 Cell前端UI组件CKEditor 4 表格工具与 File Browser 插件集成回归测试指南基于 Bender 手动测试的 Cell Properties 对话框故障排查CKEditor 4 表格工具与 File Browser 插件集成回归测试指南基于 Bender 手动测试的 Cell Properties 对话框故障排查前端UI组件CKEditor 4 表格单元格与行删除deleteCells / deleteRows手动测试指南tableselection 与 tabletools 集成验证CKEditor 4 表格单元格与行删除deleteCells / deleteRows手动测试指南tableselection 与 tabletools前端UI组件上一篇深度解析MAA助手Arknights基于计算机视觉与自动化架构的游戏辅助系统实现下一篇SD WebUI内存释放终极指南彻底解决显存泄露问题创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考