- 前端
- UI组件
【免费下载链接】ckeditor4
The best enterprise-grade WYSIWYG editor. Fully customizable with countless features and plugins.
本文以 CKEditor 4 仓库中的手动测试文档 nestedimage.md 为核心骨架,围绕 Table Selection(tableselection)插件与 Image(image)插件在嵌套表格场景下的交互,完整解读其两个验证场景,并结合 plugins/tableselection/plugin.js 与 plugins/image/plugin.js 的源码实现,还原 #2235 缺陷的成因、修复方式与自动化回归测试,帮助开发者理解表格选区与图片编辑之间的边界处理。
测试文档定位:一个针对 #2235 缺陷回归的手动测试
tests/plugins/tableselection/manual/integrations/image/nestedimage.md是 CKEditor 4 的 Bender 手动测试用例,其文件头部的元数据明确了它的身份与验证目标:
@bender-ui: collapsed @bender-tags: bug, 2235, 4.12.0 @bender-ckeditor-plugins: wysiwygarea, tableselection, image, undo@bender-tags: bug, 2235, 4.12.0:表明该用例是bug 回归测试,对应缺陷编号#2235,自4.12.0版本起纳入验证范围。@bender-ckeditor-plugins: wysiwygarea, tableselection, image, undo:声明测试所需的插件集合——经典的wysiwygarea编辑区、本测试的主角tableselection(表格选区)、image(图片)以及undo(撤销)。undo的存在说明该场景还关注删除操作的可撤销性。
该缺陷在 CHANGES.md 的 4.12.0 版本发布说明中有明确记载:
Fixed: An Image in a table cell has an empty URL field when edited from the context menu opened by right-click when the Table Selection plugin is in use.
翻译过来即:当 Table Selection 插件启用时,通过右键打开上下文菜单编辑表格单元格内的图片,会出现URL 字段为空的异常。本手动测试就是用来验证该修复是否生效,以及是否引入了新的回归。
测试场景一:右键图片编辑"图片属性"
文档的第一个场景验证的是 #2235 的核心症状——上下文菜单编辑图片时 URL 丢失:
操作步骤:
- 右键点击图片,打开上下文菜单(Context menu)。
- 选择
Image properties(图片属性)。
期望结果(Expected result):
- URL 字段应已填充(即当前图片的
src应显示在对话框中); - 预览区域应能看到图片。
异常结果(Unexpected result):
- URL 字段为空;
- 或预览区域无法显示图片。
场景一的缺陷成因:表格选区"吞掉"了图片选择
要理解为什么会出现"URL 字段为空",需要回到 Table Selection 插件的行为。该插件通过给选中单元格添加cke_table-faked-selection类来模拟"假选中"(fake selection),从而支持跨单元格的选区、复制、删除等操作。
在 plugins/tableselection/plugin.js 的fakeSelectionChangeHandler中,有这样一个关键判断:
var enclosedNode = ranges && ranges[ 0 ].getEnclosedNode(), isEnclosedNodeAnImage = enclosedNode && ( enclosedNode.type == CKEDITOR.NODE_ELEMENT ) && enclosedNode.is( 'img' ), ... // Don't perform fake selection when image is selected (#2235). if ( isEnclosedNodeAnImage ) { editor.getSelection().reset(); return; }修复前的行为是:当用户选中表格单元格里的图片时,selectionCheck事件触发后,tableselection 会把整格做成 fake selection(给单元格加cke_table-faked-selection类)。此时编辑器"真正的选择"被重置为单元格级的伪选区,图片元素本身不再处于被选中状态。于是当用户在图片上右键打开上下文菜单并选择Image properties时,Image 插件的对话框读取不到当前的图片元素,URL 字段自然就是空的。
修复后,fakeSelectionChangeHandler会先检查选区封闭节点(enclosed node)是否为img元素:若是,则放弃 fake selection(editor.getSelection().reset()后直接返回),把真正的选择权交还给图片本身。这样 Image 对话框就能正确读取src并填充 URL 字段与预览。
配套的自动化回归测试位于 tests/plugins/tableselection/integrations/image/imageurl.js,其测试夹具 imageurl.html 构建了同样的嵌套表格结构,断言:
'Is whole cell fake selected when img inside is selected': function() { ... assert.isFalse( editor.getSelection().getSelectedElement().hasClass( 'cke_table-faked-selection' ) ); }即:当图片被选中时,整格不应被加上 fake selection 类——这正是场景一期望结果在源码层的直接体现。
场景一的菜单来源:Image 插件的上下文菜单注册
Image properties菜单项并非 tableselection 提供,而是 Image 插件在 plugins/image/plugin.js 中注册的:
// If the "menu" plugin is loaded, register the menu items. if ( editor.addMenuItems ) { editor.addMenuItems( { image: { label: editor.lang.image.menu, command: 'image', group: 'image' } } ); } // If the "contextmenu" plugin is loaded, register the listeners. if ( editor.contextMenu ) { editor.contextMenu.addListener( function( element ) { if ( getSelectedImage( editor, element ) ) return { image: CKEDITOR.TRISTATE_OFF }; } ); }菜单项image对应的命令正是image(一个CKEDITOR.dialogCommand,由同文件 L38-L45 注册),执行后打开dialogs/image.js中的图片属性对话框。上下文菜单监听器通过getSelectedImage( editor, element )判断右键目标是否为可编辑图片,命中则激活菜单项。而getSelectedImage依赖编辑器当前的选区状态——这再次印证了上一节的分析:只有图片真正处于选中状态,对话框才能拿到正确的图片元素并回填 URL。
测试场景二:删除外层表格行后图片仍可被选中
文档的第二个场景验证的是修复方案不能引入的回归:
操作步骤:
- 选中外层表格的第一行并删除。
- 再次点击图片。
期望结果(Expected result):
- 图片能够被选中。
异常结果(Unexpected result):
- 图片无法被选中。
场景二的源码逻辑:删除命令与选区的联动
场景二涉及 Table Selection 与表格行删除命令的交互。在 plugins/tableselection/plugin.js 中,插件对cellDelete(单元格删除)命令做了定制化包装:
customizeTableCommand( editor, [ 'cellDelete' ], function( editor ) { clearFakeCellSelection( editor, true ); } );customizeTableCommand(plugin.js)通过在beforeCommandExec与afterCommandExec钩子中记录selectedCells并执行回调,让表格命令与 fake selection 状态保持同步。行删除(rowDelete)同样走这一机制(L1247-L1256 附近的命令列表包含行插入/删除类命令,统一在afterCommandExec中调用fakeSelectCells重建选区)。
删除外层表格第一行后,若 fake selection 标记(cke_table-faked-selection类、cke_table-faked-selection-table数据属性)残留或选择状态错乱,后续点击图片时可能无法正确建立选区,导致"图片无法选中"。文档要求验证删除操作后图片点击行为仍正常,本质上是验证fake selection 的清理与重建链路在嵌套表格结构下的健壮性。
嵌套表格的特殊性:被当作"同一张表"
场景二特意使用嵌套表格,是因为 Table Selection 对嵌套表格有一套特殊处理。在 plugins/tableselection/plugin.js 的鼠标处理器中:
// Nested tables should be treated as the same one (e.g. user starts dragging from outer table // and ends in inner one). function isSameTable( selectedTable, table ) { if ( !selectedTable || !table ) { return false; } return selectedTable.equals( table ) || selectedTable.contains( table ) || table.contains( selectedTable ) || selectedTable.getCommonAncestor( table ).is( tableElements ); }isSameTable允许选中范围跨越外层表与内层表(只要二者存在包含关系或共享表格类祖先),并在mouseup时通过restoreFakeSelection( editor )(L366-L373)重建选区。此外,getCellsBetween(L24-L92)也专门注释了"支持从外层表开始、在内层表结束的选区"(L38-L42)。这些设计都是为了保证嵌套表格场景下 fake selection 的起止位置正确,从而让删除行等操作不会破坏后续的图片点击选中行为。
同目录下的自动化测试 tests/plugins/tableselection/integrations/core/selection.js 也覆盖了相关边界:L883-L924 的'test simulating opening context menu in the nested table'模拟在嵌套表格中打开上下文菜单,断言 fake selection 状态与多选区完整;L1056 起还专门为 WebKit/macOS 编写了变体用例,因为 WebKit 系浏览器在上下文菜单点击时会折叠选区并锚定到文本节点。这些测试与手动测试文档互相印证,共同保障嵌套表格场景的稳定。
测试夹具:nestedimage.html 中的嵌套表格结构
手动测试对应的 HTML 夹具位于 tests/plugins/tableselection/manual/integrations/image/nestedimage.html,结构为外层 2×2 表格 + 内层 2×2 表格:
<div id="editor"> <table border="1" cellpadding="5" cellspacing="5" style="width:500px"> <tbody> <tr> <td> </td> <td> </td> </tr> <tr> <td> <table border="1" cellpadding="5" cellspacing="5" style="width:300px"> <tbody> <tr> <td><img alt="" src="%BASE_PATH%_assets/lena.jpg" style="height:100px; width:100px"/></td> <td> </td> </tr> <tr> <td> </td> <td> </td> </tr> </tbody> </table> <p> </p> </td> <td> </td> </tr> </tbody> </table> </div>关键细节:
- 图片位于内层表格左上角单元格,
src指向测试资产%BASE_PATH%_assets/lena.jpg(tests/_assets/lena.jpg),并显式设置了height:100px; width:100px; - 内层表格嵌套在外层表格左下角单元格内,正是场景二"删除外层表格第一行"后结构变化的基础;
- 夹具末尾(L30-L35)包含环境判断:Table Selection 插件在 IE 11 以下不可用(与
isSupportedEnvironment中!( CKEDITOR.env.ie && CKEDITOR.env.version < 11 )的声明一致),因此 IE < 11 环境下直接bender.ignore()跳过测试。
如何运行该手动测试
本用例是 Bender 手动测试(manual test),运行方式遵循仓库的 Bender 测试体系:
- 仓库根目录的 bender.js 是 Bender 配置入口,声明了测试框架(YUI)、插件列表(
benderjs-yui、benderjs-sinon、benderjs-jquery等)以及测试分组与路径; - 启动 Bender 服务后,手动测试会以独立页面形式在浏览器中打开,由测试人员按文档步骤操作并人工核对"期望结果 / 异常结果";
- 由于手动测试依赖真实浏览器交互(右键菜单、鼠标点击),无法被自动化断言完全替代,因此文档中每个场景都同时给出了期望与异常两条判据,供测试人员对照判定。
自动化层面,tests/plugins/tableselection/integrations/下的imageurl.js、selection.js、clipboard/pastenested.js(嵌套表格粘贴用例)等组成了该功能的自动化回归网络,与手动用例形成互补。
小结
nestedimage.md虽是一份简短的 Bender 手动测试文档,但它精准锚定了 CKEditor 4 中两个插件协同时的关键边界问题:
- 场景一验证 #2235 修复——选中图片时不得触发表格 fake selection,保证 Image 对话框能正确回填 URL 与预览,其修复落实在 plugins/tableselection/plugin.js 的图片节点检测分支;
- 场景二验证删除外层表格行后图片仍可选中,确保表格命令(
cellDelete/rowDelete)与 fake selection 清理、重建逻辑在嵌套表格下不产生残留状态。
结合 CHANGES.md 中 4.12.0 的修复记录、imageurl.js的自动化断言以及selection.js中嵌套表格上下文菜单模拟测试,可以完整还原该缺陷的来龙去脉:Table Selection 的"整格选中"策略必须为图片等内联可编辑元素让路,这正是本文档所承载的回归验证意义。
- 前端
- UI组件
【免费下载链接】ckeditor4
The best enterprise-grade WYSIWYG editor. Fully customizable with countless features and plugins.
相关推荐
CKEditor 4 菜单右键点击焦点回归测试指南:基于 2858 修复的 Bender.js 手动测试解析
CKEditor 4 菜单右键点击焦点回归测试指南:基于 2858 修复的 Bender.js 手动测试解析 本篇技术指南以 CKEditor 4 官方仓库中的
前端UI组件CKEditor 4 嵌套表格跨表鼠标选中的修复机制:tableselection 手动测试用例深度解析
CKEditor 4 嵌套表格跨表鼠标选中的修复机制:tableselection 手动测试用例深度解析 导读 本文围绕 CKEditor 4 tablesel
前端UI组件CKEditor 4 全选粘贴与表格选区集成修复(875):tableselection 手动测试指南与源码原理剖析
CKEditor 4 全选粘贴与表格选区集成修复( 875):tableselection 手动测试指南与源码原理剖析 本文以 CKEditor 4 仓库中 t
前端UI组件
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考