前端UI组件【免费下载链接】ckeditor4The best enterprise-grade WYSIWYG editor. Fully customizable with countless features and plugins.项目地址https://gitcode.com/gh_mirrors/ck/ckeditor4点击查看免费下载本手册针对 CKEditor 4 的 Table Resize表格列宽拖拽调整插件在窄容器编辑器横向滚动后列边框上的缩放光标发生错位这一已知缺陷issue #4889随 4.20.0 版本修复给出基于 Bender 手动测试Manual Test的完整复现步骤、预期/非预期行为判定标准并结合插件源码与自动化测试从pillar柱线缓存失效的角度剖析缺陷根因与修复机制。读完本文你将掌握如何定位 Table Resize 的坐标计算核心、理解其滚动场景下的缓存失效问题并学会用仓库内置的 manual test 与 bender 自动化用例双重验证此类交互缺陷。一、手册定位一份bug 型手动测试文档本文所依据的文档是 scrollupdate.md它是 CKEditor 4 测试体系中典型的manual test手动测试说明文档与同目录下的 scrollupdate.html 页面配套使用。其文档头部的 Bender 指令完整描述了该用例的属性bender-ui: collapsed bender-tags: bug, 4.20.0, 4889 bender-ckeditor-plugins: wysiwygarea, toolbar, table, tableresize, tabletools, floatingspacebender-ui: collapsed手动测试页面以折叠collapsed方式嵌入 Bender 手动测试运行器 UI 中避免页面干扰操作bender-tags: bug, 4.20.0, 4889明确这是一个bug 回归用例对应 GitHub issue #4889修复随4.20.0版本发布见 CHANGES.md 中 Fixed: Incorrect position of the Table Resize cursor after scrolling the editor horizontallybender-ckeditor-plugins声明该用例需要加载wysiwygarea、toolbar、table、tableresize、tabletools、floatingspace等插件——注意tableresize插件本身在 plugin.js 中声明了requires: tabletools因此tabletools是其依赖项。这样的文档结构意味着它不讲解功能如何使用而是规定了一套可执行的缺陷复现流程。这是 CKEditor 4 质量保障体系中回归测试必须可复现、可判定原则的直接体现。二、缺陷背景Table Resize 的光标与 pillar 机制要理解这个 bug需要先了解 Table Resize 插件的工作方式。在 plugin.js 中插件通过buildTableColumnPillars()为表格的每一列边框计算一个pillar柱线即列边框的可拖拽命中区域其核心字段如下plugin.jspillar { table: table, index: pillarIndex, x: pillarLeft, // 柱线左边界基于 getDocumentPosition() 计算 y: pillarPosition.y, width: pillarWidth, // 最小为 3pxMath.max(pillarRight - pillarLeft, 3) height: pillarHeight, rtl: rtl };pillar 的x/y坐标全部来自CKEDITOR.dom.element.getDocumentPosition()——这是一个相对于文档的绝对坐标而不是相对于视口的坐标。当鼠标移动时mousemove处理器通过evt.getPageOffset()取得页面级坐标再调用getPillarAtPosition()判断鼠标是否落在某个 pillar 范围内plugin.js。为了提高性能插件把每次计算出的 pillars 缓存到表格的自定义数据_cke_table_pillars上plugin.js并只在mouseout/mousedown时通过clearPillarsCache()清除缓存plugin.js。滚动为何导致错位缺陷的根源在于pillar 坐标是相对文档的绝对坐标而getPageOffset()取到的鼠标位置会随着编辑区域滚动而变化。当编辑区域inline/divarea 容器或 iframe 文档发生横向滚动后页面级鼠标坐标已经变化但缓存的 pillars 中记录的是滚动前计算的文档坐标未随滚动失效于是getPillarAtPosition()命中了一个坐标过期的 pillarcolumnResizer.attachTo()据此把缩放条resizer定位到错误位置plugin.js表现为缩放光标从列边框上偏移。值得注意的是手动测试文档特别注明了一个细节The bug does not occur when dragging the scrollbar.用鼠标滚轮或触控板手势滚动时出现拖动滚动条时不出现。这与浏览器事件模型一致——拖动滚动条不会触发容器/文档的scroll事件流或鼠标位置计算路径不同而滚轮/手势滚动才会让编辑器内表格的文档坐标与页面鼠标坐标产生错位。三、复现步骤原文档核心操作流程以下步骤完整继承自 scrollupdate.md并结合 scrollupdate.html 的测试页面结构给出补充说明。测试页面包含三种编辑器形态共 3 个待测实例编辑器创建方式容器特征Inline editorCKEDITOR.inline( inline )250px 宽、overflow: auto的可编辑 divdiv-based editorCKEDITOR.replace( div, { extraPlugins: divarea, width: 250 } )250px 宽、overflow: auto的 div 编辑区iframe-based editorCKEDITOR.replace( iframe, { width: 250 } )250px 宽的标准 iframe 编辑区每个实例内部都是一张stylewidth:500px、border1的 5 行 4 列表格——即表格宽度500px远超容器宽度250px必然产生横向滚动条这是触发本 bug 的前提条件。此外 scrollupdate.html 中还有if ( bender.tools.env.mobile ) { bender.ignore(); }表示移动端环境自动跳过该用例。操作步骤将编辑器滚动到最右端再稍微向左回滚一点。⚠️注意必须使用鼠标滚轮或触控板手势滚动拖动滚动条无法复现该 bug原因见上文第二节。尝试拖拽调整最后一列将鼠标悬停到最右侧列边框上出现col-resize光标后按下拖拽。对页面上的全部 3 个编辑器inline、div-based、iframe-based重复上述过程。预期结果Expected缩放光标位于正确的位置即恰好贴合最后一列的边框线拖拽后列宽调整正常生效。非预期结果Unexpected缩放光标从列的边框上偏移——由于 pillar 缓存未随滚动失效resizer 被定位到了滚动前的位置鼠标指针看起来悬空在边框之外无法准确拖拽最后一列。四、修复原理scroll 事件触发 pillar 缓存重置针对 #4889plugin.js 中新增了如下修复逻辑// Reset pillars position on scroll (#4889). editable.attachListener( listenerTarget, scroll, function() { var tables editable.find( table ).toArray(); CKEDITOR.tools.array.forEach( tables, CKEDITOR.tools.debounce( function( table ) { table.removeCustomData( _cke_table_pillars ); }, 200 ) ); } );关键设计有三点监听目标的选择listenerTarget在 init 时被确定为——inline 编辑器用editable本身经典编辑器用editor.documentplugin.js。这样无论滚动发生在可编辑容器还是 iframe 文档上都能捕获到scroll事件。批量失效滚动发生时遍历 editable 内的所有表格逐一移除_cke_table_pillars缓存数据。下次鼠标移动时buildTableColumnPillars()会重新按最新文档坐标计算 pillars光标位置随即恢复正确。防抖debounce用CKEDITOR.tools.debounce( ..., 200 )将清除动作延迟 200ms 合并执行避免连续滚动造成频繁重算兼顾正确性与性能。与此同时自动化测试 tableresize.js 中也新增了两个断言用例test pillars are resetted on scroll (inline)对 inline 编辑器触发editable.fire( scroll, {} )等待 210ms超过 200ms 防抖窗口后断言table.getCustomData( _cke_table_pillars )为nulltest pillars are resetted on scroll (classic)对经典编辑器触发editor.document.fire( scroll, {} )同样断言缓存被清空。这两个用例与手动测试文档形成了自动化 人工双重验证的闭环自动化用例用 mock 事件验证缓存失效行为手动用例验证真实浏览器滚动交互下的最终用户体验。测试还定义了inlineOverflow/classicOverflow两个带横向溢出场景的编辑器实例tableresize.js与 manual test 页面的窄容器设置相互印证。五、如何运行该手动测试本仓库使用 Bender.js 作为测试运行框架其tests配置中Plugins分组以tests/为 basePath 覆盖plugins/**见 bender.js依赖由 package.json 中的benderjs系列包提供。运行全部手动测试bender run manual手动测试文档通过bender-ui等标记被 Bender 识别为 manual test 分组定位本用例运行后选择Plugins分组下的tableresize即可在页面列表中找到scrollupdate用例按第三节的步骤逐条验证。由于仓库只读本文仅介绍查看与运行方式实际验证时请在你的开发副本中安装依赖并启动 Bender 服务器然后按上述流程在真实浏览器中操作。六、小结从一份 manual test 学到什么通过这份 scrollupdate.md可以提炼出三条可复用的工程经验坐标缓存类交互缺陷的复现要点凡是基于文档绝对坐标 缓存的交互pillar、tooltip、浮动面板等都必须验证滚动、缩放等位移场景且复现方式滚轮 vs 拖滚动条可能影响 bug 是否出现测试文档必须写清楚修复的标准姿势监听scroll事件 → 失效相关缓存 → 用 debounce 控制频率是 CKEditor 4 中处理滚动导致缓存坐标过期类问题的通用模式见 plugin.js回归测试的双轨验证manual test真实交互体验 自动化断言缓存状态变化组合既保证用户视角正确又保证实现细节正确这在 tableresize.js 中体现得尤为清晰。如果需要继续深入 Table Resize 插件可阅读同目录下的其他手动测试如 pillar.mdpillar 高度与整表等高、mergedcells.md合并单元格边界命中、maximizeddivarea.md最大化后缩放等它们共同覆盖了该插件的坐标计算与交互边界场景。赞分享前端UI组件【免费下载链接】ckeditor4The best enterprise-grade WYSIWYG editor. Fully customizable with countless features and plugins.项目地址https://gitcode.com/gh_mirrors/ck/ckeditor4点击查看免费下载相关推荐CKEditor 4 Copy Formatting 与 Table Resize 光标冲突修复从手动测试到源码原理CKEditor 4 Copy Formatting 与 Table Resize 光标冲突修复从手动测试到源码原理 Copy Formatting复制格式前端UI组件CKEditor 4 Table Resize 插件合并单元格Rowspan缩放修复解析与手动回归测试指南CKEditor 4 Table Resize 插件合并单元格Rowspan缩放修复解析与手动回归测试指南 本篇技术指南以 CKEditor 4 仓库中的手前端UI组件CKEditor 4 Table Resize 插件IE 下 border-collapse 表格右边界无法调整2823的修复原理与手动验证CKEditor 4 Table Resize 插件IE 下 border collapse 表格右边界无法调整 2823的修复原理与手动验证 本文以 C前端UI组件上一篇PyQt-SiliconUI基于PyQt5的终极UI框架让你的桌面应用瞬间灵动优雅下一篇Django-Treebeard 完全指南打造高效树形结构的终极解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考