news 2026/10/16 2:57:58

CKEditor 4 Forms 插件:IE 下 Radio 按钮 checked 状态持久化修复(834)与 ieradiofix 手工回归测试

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CKEditor 4 Forms 插件:IE 下 Radio 按钮 checked 状态持久化修复(834)与 ieradiofix 手工回归测试
  • 前端
  • UI组件

【免费下载链接】ckeditor4

The best enterprise-grade WYSIWYG editor. Fully customizable with countless features and plugins.

项目地址:https://gitcode.com/gh_mirrors/ck/ckeditor4
点击查看免费下载

本文以 CKEditor 4 仓库中的手工测试文档 ieradiofix.md 为主线,讲解 Forms 插件在 IE9–11 下"创建/修改 radio 按钮时 selected 状态丢失"缺陷(ticket #834)的完整验证流程,并深入 radio 对话框 的源码,剖析该修复的实现策略与自动化测试的对应关系。读完后可掌握:如何用 bender 手工测试框架编写回归用例、如何从源码层面理解编辑器对表单控件checked属性的跨浏览器处理差异。

一、测试文档定位:一份 bender 手工回归测试

tests/plugins/forms/manual/ieradiofix.md 是 CKEditor 4 测试体系中典型的bender 手工测试(manual test)文档,其头部元数据声明了该用例的回归背景:

@bender-tags: bug, 4.8.0, forms, 834 @bender-ui: collapsed @bender-ckeditor-plugins: forms, wysiwygarea, toolbar, sourcearea

各标签的含义:

标签含义
bug, 834该用例针对缺陷 ticket #834("IE9-11 下编辑器不保存 Forms 插件插入的 radio 按钮选中状态")
4.8.0该缺陷在 CKEditor 4.8.0 中修复,用例用于 4.8.0 起各版本回归
forms属于 Forms 插件测试组
forms, wysiwygarea, toolbar, sourcearea测试页需加载这 4 个插件——wysiwygarea提供编辑区,toolbar提供 "Radio" 工具栏按钮,sourcearea提供"检查源码"能力

每个.md手工测试都配有一个同名.html宿主页面。ieradiofix.html 的内容非常简洁:

<body> <div id="editor"> <p>Example text</p> </div> <script> if ( !CKEDITOR.env.ie ) { bender.ignore(); } CKEDITOR.replace( 'editor' ); </script> </body>

注意其中的关键逻辑:在非 IE 浏览器中直接bender.ignore(),即该手工用例只在 IE 环境下执行——这正是"IE radio fix"的用意:其他浏览器走不同的代码分支(见下文源码分析),已有独立用例覆盖(如 checkboxradiochangestate.md 验证了 trac#12465 中 Webkit/Blink 分支的同类问题)。

测试框架侧,bender.js 将tests/plugins/**归入Plugins测试组,使用yui断言框架;根目录的 bender-runner.config.json 则面向 CI(默认在 Linux 上使用 Chrome/Firefox 跑自动化测试),而本用例属于手工测试,需人工在 IE 中逐步执行后判定通过与否。

二、手工验证步骤:从创建到修改的完整闭环

原文档定义了 7 步操作,覆盖了 radio 控件"新建"和"编辑"两条路径,务必完整执行:

  1. Click in the editor.(点击编辑器)
  2. Click "Radio" button.(点击工具栏 "Radio" 按钮)
  3. Check "Selected" field in the dialog and press "Ok" to create a radio button.(在对话框中勾选 "Selected",按 "Ok" 创建带选中状态的 radio 按钮)
  4. Check source in editor.(切换到源码模式检查内容)
  5. Double click the radio.(双击该 radio 控件重新打开对话框)
  6. Check "Selected" field in the dialog and press "Ok" to modify radio.(再次勾选 "Selected" 并 "Ok" 修改 radio)
  7. Check source in editor.(再次检查源码)

判定标准:

Expected(预期):

  • The state of radio button is changed according to settings.(radio 的选中状态随对话框设置变化)
  • In source mode appearscheckedattribute when radio button is marked as selected.(标记为选中时,源码模式中应出现checked属性)

Unexpected(缺陷表现,即 #834 的原始症状):

  • The state of radio button is not saved.checkedattribute isnot presentin source mode.(状态未保存,源码中缺失checked属性)

也就是说,该用例的验收口径是:对话框中勾选 "Selected" 后,生成的 HTML 必须持久化出checked属性,且这一行为在 IE 下与标准浏览器一致。

三、修复背景:ticket #834 与 CKEditor 4.8.0

仓库变更日志 CHANGES.md 中,4.8 版本的 Fixed Issues 一节明确记录了这一修复:

#834: [IE9-11] Fixed: The editor does not save the selected state of radio buttons inserted by the Form Elements plugin.

即缺陷影响范围为 IE9 至 IE11。这解释了为什么手工用例ieradiofix的宿主页面要主动跳过非 IE 环境,以及为什么标签中同时标注了4.8.0与834。

四、源码剖析:radio 对话框 commit 中的 IE 特判

用例的验证对象是 plugins/forms/dialogs/radio.js 中checked字段的commit逻辑(L90-L123)。该字段定义了三种浏览器分支:

commit: function( data ) { var element = data.element; if ( !CKEDITOR.env.ie ) { var value = this.getValue(); // Blink/Webkit needs to change checked property, not attribute. (trac#12465) if ( CKEDITOR.env.webkit ) { element.$.checked = value; } if ( value ) element.setAttribute( 'checked', 'checked' ); else element.removeAttribute( 'checked' ); } else { var isElementChecked = element.getAttribute( 'checked' ); var isChecked = !!this.getValue(); if ( isElementChecked != isChecked ) { var replace = CKEDITOR.dom.element.createFromHtml( '<input type="radio"' + ( isChecked ? ' checked="checked"' : '' ) + '></input>', editor.document ); element.copyAttributes( replace, { type: 1, checked: 1 } ); replace.replace( element ); // Ugly hack which fix IE issues with radiobuttons (#834). if ( isChecked ) { replace.setAttribute( 'checked', 'checked' ); } editor.getSelection().selectElement( replace ); data.element = replace; } } }

三个分支各有针对性:

  1. 非 IE 标准分支:直接setAttribute('checked','checked')/removeAttribute('checked')读写属性即可。
  2. Webkit/Blink 分支:源码注释指向 trac#12465——这类内核下仅改属性不足以反映真实选中态,还需同步原生element.$.checked属性。对应的独立手工用例是 checkboxradiochangestate.md。
  3. IE 分支(#834 修复本体):IE 下对已插入 DOM 的 radio 直接改checked属性并不可靠,策略是"换元素"——用createFromHtml新建一个目标状态的<input type="radio">,通过copyAttributes( replace, { type: 1, checked: 1 } )保留type与checked后replace( element )替换原节点。而if ( isChecked ) replace.setAttribute( 'checked', 'checked' )这一行被注释明确称为 "Ugly hack which fix IE issues with radiobuttons (#834)":IE 在替换 DOM 时会丢弃新节点的checked属性,必须在替换完成后再显式补写一次,才能保证源码输出中checked属性存在——这正是手工用例第 4、7 步"检查源码"要验证的最终结果。

checkbox对话框(plugins/forms/dialogs/checkbox.js)采用完全相同的"重建 + 替换"策略处理 IE 分支,说明这是针对 IE 表单控件属性写入缺陷的插件级统一应对模式。

五、插件侧配套:内容过滤、双击打开与 IE 数据清理

手工用例的每一步操作都对应 plugins/forms/plugin.js 中的注册逻辑:

  • 工具栏 "Radio" 按钮与命令(L86):addButtonCommand( 'Radio', 'radio', dialogPath + 'radio.js' )注册命令与对话框,用例第 2 步即由此触发。命令的 ACF(Advanced Content Filter)规则为(L41-L51):

    allowedContent = { radio: 'input[type,name,checked,required]', ... };

    checked被显式列入 radio 的允许属性——这是用例"源码中出现checked"能通过过滤的前提;若 ACF 未放行,即便 DOM 上写入了属性,getHtml输出仍会被剥离。

  • 双击打开对话框(L211-L243):编辑器doubleclick监听中,element.is('input')且type == 'radio'时设置evt.data.dialog = 'radio',即用例第 5 步"双击 radio"的实际入口。

  • IE 数据清理(L251-L268):afterInit中针对 IE 注册了htmlFilter规则,当checkbox/radio的value为 IE 默认注入的'on'时删除该属性(attrs.value == 'on' && delete attrs.value),并保证缺失type的输入框补为text。这保证了 IE 下源码输出不会混入编辑器外的脏属性,与 #834 修复共同构成"IE 表单属性可预测"的完整链路。

六、自动化测试的交叉印证

手工用例之外,仓库还有一套覆盖 radio 对话框的自动化测试 tests/plugins/forms/radio.js,其"fill fields"用例断言了对话框提交后的精确源码输出:

bot.dialog( 'radio', function( dialog ) { dialog.setValueOf( 'info', 'name', 'name' ); dialog.setValueOf( 'info', 'value', 'value' ); dialog.setValueOf( 'info', 'checked', 'checked' ); dialog.setValueOf( 'info', 'required', 'required' ); dialog.getButton( 'ok' ).click(); assert.areSame( '<input checked="checked" name="name" required="required" type="radio" value="value" />', bot.getData( false, true ) ); } );

该断言与手工用例的 Expected 一致:勾选 "Selected" 后源码必须包含checked="checked"。其余用例还包括:

  • test dialog model during radio creation/test dialog model with existing radio:验证 radio.js 中getModel在新建场景返回null(CREATION 模式)、选中已有 radio 时返回对应元素(EDITING 模式);
  • test empty fields:验证清空字段后属性被移除,其中专门注明了"IE is problematic: you cannot removevaluefrom the input"这一 IE 遗留限制;
  • 通过 tests/plugins/forms/_helpers/tools.js 的assertRequiredAttribute验证required布尔属性按 HTML 规范解析(存在即勾选,无论值为何)。

需要说明的适用前提:自动化测试在 CI 中面向 Chrome/Firefox 等现代浏览器(见 bender-runner.config.json 的browsers配置),而 IE 分支的回归保障正依赖ieradiofix这类在 IE 中手工执行的手工用例——两者互补,共同锁定 #834 不复发。

七、小结

  • ieradiofix.md 是一份针对 IE9–11 的回归手工用例:创建与修改 radio 两条路径均需验证源码中checked属性的持久化。
  • 修复本体位于 radio.js 的 IE 分支:以"重建元素并替换"规避 IE 属性写入缺陷,并在替换后显式补写checked属性(源码中自注为 #834 的 "Ugly hack")。
  • 验证链条完整闭环:ACF 放行checked属性 →commit写入 DOM →sourcearea源码可查 → 自动化断言(radio.js)与现代浏览器分支(trac#12465)分别兜底。
  • 前端
  • UI组件

【免费下载链接】ckeditor4

The best enterprise-grade WYSIWYG editor. Fully customizable with countless features and plugins.

项目地址:https://gitcode.com/gh_mirrors/ck/ckeditor4
点击查看免费下载

相关推荐

上一篇:Presto 0.128 版本发布详解:Worker 优雅停机(Graceful Shutdown)与关键修复
下一篇:Return YouTube Dislike 安全 FAQ 深度解析:隐私边界、反机器人机制与数据最小化设计

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/16 2:57:11

仓颉 ArkUI Badge 信息标记组件开发指南:用法、样式与实战示例

文档知识库教程OpenHarmony 【免费下载链接】CangjieCorpus 本仓库为仓颉编程语言语料库&#xff0c;聚焦 仓颉编程语言 核心知识体系&#xff0c;整合官方开发指南、API 文档、典型代码示例及语法规范等多维度资源&#xff0c;经结构化处理与专业标注&#xff0c;构建为支持 R…

作者头像 李华
网站建设 2026/10/16 2:57:09

ElasticSearch Suggest实现搜索提示:从映射设计到性能调优全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/16 2:56:23

Python FastAPI 介绍以及常用方法

FastAPI 完整使用指南 常用示例 FastAPI 是一个高性能、工程化的 Python Web API 框架&#xff0c;基于标准 Python 类型提示开发&#xff0c;底层依赖 Starlette&#xff08;ASGI 异步底层&#xff09; 和 Pydantic&#xff08;自动数据校验&#xff09;&#xff0c;原生支持…

作者头像 李华