
TinyMCE 8.5.0 版本全解析content_language 语言属性新选项与多项健壮性修复【免费下载链接】tinymceThe worlds #1 JavaScript library for rich text editing. Available for React, Vue and Angular项目地址: https://gitcode.com/gh_mirrors/ti/tinymce本文基于开源仓库 tinymce 的版本变更日志 .changes/tinymce/8.5.0.md发布日期 2026-04-29展开。8.5.0 是 TinyMCE 的一个功能与稳定性双修版本新增了用于控制编辑区lang属性的content_language选项改善了 Suggested Edits 与 TinyMCE AI 插件的内联 diff 高亮视觉并修复了 DomPurify 误删元素、列表切换异常、非 Latin-1 字符 URI 报错、屏幕阅读器播报缺失等 6 类问题。阅读本文后你将掌握content_language的配置方法与底层实现原理并了解各修复项的成因、代码位置与验证方式为升级或排查 8.5.0 相关问题提供直接依据。一、版本概览8.5.0 的变更日志结构清晰分为Added新增、Improved改进与Fixed修复三部分共涉及 1 项新功能、1 项视觉改进和 6 项问题修复对应 TinyMCE JIRA 工单号 TINY-11214、TINY-13958、TINY-9655、TINY-14070、TINY-14149、TINY-13938、TINY-13812类别工单内容摘要AddedTINY-11214新增content_language选项设置 iframe 编辑器html元素或内联编辑器目标元素的lang属性ImprovedTINY-13958改进 Suggested Edits 与 TinyMCE AI 插件中内联 diff 高亮的视觉样式FixedTINY-9655DomPurify 误删 schema 中合法且有效的script、style元素FixedTINY-9655DomPurify 误删带子元素的iframe元素FixedTINY-14070列表中特定div组合导致关闭列表turn off lists异常FixedTINY-14149特定选择操作误删编辑器 bodyFixedTINY-13938含非 Latin-1 字符的 URI 返回错误FixedTINY-13812部分屏幕阅读器未正确播报 alert 与 confirm 对话框下文按此结构逐项展开并结合仓库源码给出实现证据。二、新增功能content_language 选项TINY-112142.1 功能定位content_language是本版本最重要的新功能它允许开发者显式指定编辑内容的语言TinyMCE 会据此在编辑区根元素上设置标准的lang属性。这对于拼写检查与语法检查浏览器和第三方服务可依据lang属性选择正确的语言词典屏幕阅读器无障碍读屏软件能按lang属性选择合适的语音引擎与发音规则多语言站点内容管理区分正文语言与 UI 语言后者由已有的language/language_url选项控制见 Options.ts。content_language与既有的language选项职责不同language控制的是 TinyMCE 界面UI的本地化语言而content_language声明的是编辑区内容的语言。仓库中还定义了content_langs选项类型为ContentLanguage[]见 OptionTypes.ts用于在 UI 上提供语言下拉列表content_language则直接指定实际生效的语言代码。2.2 配置方式在初始化配置中加入字符串类型的语言标签即可取值遵循 BCP 47 语言标签规范例如fr、en-US、zh-CNtinymce.init({ selector: textarea, // 将 html langfr 设置在 iframe 编辑器文档上 content_language: fr });对于内联编辑器inline: true该值会设置到目标元素本身而非 iframetinymce.init({ selector: #my-editable-div, inline: true, content_language: en-US });2.3 底层实现原理从源码结构看content_language的实现分三层选项注册在 Options.ts 中通过registerOption(content_language, { processor: string })注册处理器限定为字符串类型读取端使用getContentLanguage option(content_language)Options.ts并在 Options.ts 导出供初始化流程调用。类型定义content_language?: string位于 OptionTypes.ts。属性写入核心逻辑在编辑器内容 body 加载完成的contentBodyLoaded函数中InitContentBody.tsconst contentLanguage Options.getContentLanguage(editor); if (contentLanguage) { const langTarget editor.inline ? targetElm : doc.documentElement; DOM.setAttrib(langTarget, lang, contentLanguage); }代码明确区分两种模式内联编辑器editor.inline为真将lang设置到targetElm即editor.getElement()返回的目标元素见同文件 L414iframe 模式则设置到doc.documentElement即 iframe 文档的html元素——这与变更日志的描述完全一致。只有当选项值存在非空字符串时才写入因此默认不配置时不会对现有页面产生任何影响。测试验证仓库提供了专门的浏览器测试 InitEditorContentLanguageTest.ts。该测试对 iframe 与 inline 两种模式分别断言以content_language: fr初始化编辑器后lang属性值必须为friframe 模式检查documentElementinline 模式检查目标元素见测试文件 L10-L27。这为升级后的行为提供了可复现的验证基准。三、改进内联 diff 高亮视觉优化TINY-139583.1 变更内容8.5.0 改进了Suggested Edits建议编辑与TinyMCE AI 插件中内联 diff 高亮的视觉样式使新增added、修改modified、删除removed三类注释在行内呈现时更加清晰、可区分。3.2 样式实现相关样式定义在 oxide 主题的内容样式目录 diff.less 中其核心是通过.diff-content(...)混入mixin为不同注释状态生成样式tox-{plugin}__annotation--added底部线性渐变 成功色color-success下划线选中态显示整块背景色与上下轮廓阴影见 diff.lesstox-{plugin}__annotation--modified使用主题色color-tint渐变选中态同理diff.lesstox-{plugin}__annotation--removedline-through删除线 错误色color-error渐变diff.less。针对行内ins/del元素样式使用calc(1lh 3px)的背景尺寸实现更贴合行高的选中态外框避免整行背景遮挡文字见 diff.less。三类注释还提供了--hidden隐藏态diff.less以及包含 iframe 的容器注释的内边距处理diff.less说明本次优化兼顾了多行块级注释与行内注释两类场景的选中态表现。四、修复DomPurify 误删合法元素TINY-96554.1 问题现象TinyMCE 使用 DOMPurifydompurify库对粘贴/插入的 HTML 进行安全清洗。8.5.0 修复了两个相关缺陷当script或style元素在 schema 中被判定为合法例如开发者通过valid_elements/custom_elements显式放行时它们的内容仍会被 DomPurify 错误移除带子元素的iframe元素如包含 fallback 内容的 iframe会被 DomPurify 整体删除。4.2 修复原理修复位于核心 HTML 清洗模块 Sanitization.ts。处理逻辑为在 DomPurify 的元素级钩子uponSanitizeElement回调中对符合条件的目标元素先做内容预处理// TINY-9655: Preserve the content of script and style tags if they are valid elements in the schema const shouldKeepContent (ElementType.isScript(element) schema.isValid(script)) || (ElementType.isStyle(element) schema.isValid(style)); if (shouldKeepContent) { Optional.from(TextContent.get(element)).each((content) Attribute.set(element, data-mce-tmp, content)); } // TINY-9655: Clear innerHTML of script and iframe tags to prevent DOMPurify from removing them entirely const shouldClearContent ElementType.isIframe(element) schema.isValid(iframe); if (shouldKeepContent || shouldClearContent) { Remove.empty(element); }即在清洗前对 schema 合法的script/style先把文本内容暂存到data-mce-tmp属性中对 schema 合法的iframe清空其 innerHTML连同前一类情况以阻止 DomPurify 因内容异常而删除整个元素清洗完成后再恢复内容。这是典型的先保护、后恢复策略保证安全清洗与 schema 许可并存。4.3 相关测试该修复在 DomParserTest.ts 与 SerializerTest.ts 中均有覆盖文件内引用Sanitization相关行为回归验证了合法 script/style 内容保留与iframe 不再被整体删除。五、修复列表关闭异常与 body 误删TINY-14070 / TINY-141495.1 列表中 div 组合导致关闭列表异常TINY-14070在嵌套列表或包含块级div的复杂列表结构中关闭列表turn off lists操作即再次点击列表按钮取消列表格式可能产生错误的 DOM 结果。该逻辑属于核心列表模块入口为 ToggleList.ts 的toggleList它先判断选区是否处于不可编辑列表内isWithinNonEditableList再检查是否存在多个选中的子列表Selection.getSelectedSubLists分别走toggleMultipleLists或toggleSingleList分支在toggleSingleList中若父列表与目标列表类型一致且无样式细节则执行flattenListSelection将列表扁平化ToggleList.ts。本版本修复了该流程中div与列表项组合时的边界情况确保取消列表后内容结构正确。5.2 特定选择操作误删编辑器 bodyTINY-14149某些选区操作如全选后执行删除在极端情况下会删除编辑器内容根元素body导致编辑区损坏。TinyMCE 的选择系统在设计上通过bodyElement、_editableRoot等状态见 InitContentBody.ts保护内容根节点本次修复进一步加固了选区边界判断避免 body 被当作普通内容删除。六、修复非 Latin-1 字符 URI 报错TINY-139386.1 问题现象当 data URI例如粘贴的data:image/svgxml,...中包含非 Latin-1 字符如带 BOM 的 UTF-8 编码内容字符码大于 255时TinyMCE 处理 blob 缓存的过程会抛出异常导致粘贴/插入失败。6.2 修复与验证修复位于图片/文件处理模块 BlobCacheUtils.ts 的processDataUriL18-L20该函数解析 data URI 并生成BlobInfo。仓库提供了专门的原子测试 BlobCacheUtilsTest.tsit(TINY-13938: processDataUri should not throw error with URIs with Byte Order Mark (BOM), () { let result ; assert.doesNotThrow(() processDataUri(data:image/svgxml,%EF%BB%BF%3Csvg, false, (base64) { result base64; return Optional.none(); })); assert.equal(result, 77u/PHN2Zw); });测试使用带 BOM%EF%BB%BF的 SVG data URI断言调用不再抛错且能正确转换为 Base64。从实现上看BlobCacheUtils.ts 使用TextEncoder进行 UTF-8 编码规避了原先基于 Latin-1 假设的字符处理路径。七、修复屏幕阅读器未播报 alert/confirmTINY-138127.1 问题现象通过editor.windowManager.alert(...)与editor.windowManager.confirm(...)弹出的对话框在部分屏幕阅读器如 NVDA/JAWS 组合下不会被自动播报影响无障碍体验。7.2 修复方式alert 与 confirm 对话框由 Silver 主题实现入口在 WindowManager.tsalert委托给AlertDialog.openconfirm委托给confirmDialog.open。对话框渲染采用 Alloy 的ModalDialog并将对话框角色声明为role: alertdialog见 AlertDialog.ts同时通过AriaDescribe等机制为对话框关联可访问名称。本次修复完善了这些对话框在打开时的 ARIA 播报时机与属性设置使屏幕阅读器能及时读出提示内容对话框头部使用隐藏标题Dialogs.hiddenHeader保证视觉简洁的同时保留无障碍语义AlertDialog.ts。八、升级与验证建议若需要使用content_language按 2.2 节示例配置即可注意它与 UI 语言选项language相互独立如需在界面提供语言选择下拉可配合content_langs使用。可以运行 InitEditorContentLanguageTest.ts 作为行为基准。若自定义了允许script/style/iframe的 schema升级后请回归粘贴与插入场景确认内容不再被清洗删除相关逻辑见 Sanitization.ts。无障碍回归使用屏幕阅读器检查windowManager.alert/confirm的播报实现见 WindowManager.ts。URI 粘贴回归包含 BOM 或非 Latin-1 字符的 data URI 粘贴场景可参考 BlobCacheUtilsTest.ts 的用例进行验证。总结TinyMCE 8.5.0 是一个小而实的版本content_language为多语言内容编辑补上了标准化的语言声明能力核心实现与测试分别位于 InitContentBody.ts 与 InitEditorContentLanguageTest.ts6 项修复则覆盖了 HTML 清洗、列表操作、选区安全、URI 处理与无障碍播报等高频风险点每一处都有对应的源码位置或测试用例可供核查。对于正在升级或排查相关问题的开发者本文给出的文件路径与工单号可直接作为问题定位的起点。【免费下载链接】tinymceThe worlds #1 JavaScript library for rich text editing. Available for React, Vue and Angular项目地址: https://gitcode.com/gh_mirrors/ti/tinymce创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考