前端UI组件【免费下载链接】ckeditor4The best enterprise-grade WYSIWYG editor. Fully customizable with countless features and plugins.项目地址https://gitcode.com/gh_mirrors/ck/ckeditor4点击查看免费下载CKEditor 4 的对话框Dialog中文本输入框textInput / textarea支持通过快捷键快速切换文本方向Right-to-Left 或 Left-to-Right并且这一方向会随输入值一起保存、在下一次打开对话框时自动恢复。本文以tests/plugins/dialogui/manual/inputdirsave.md手动测试为线索完整讲解该功能的操作方式、bidi属性配置、\u202A/\u202B方向标记的实现原理以及setDirectionMarker()/getDirectionMarker()等 API 的底层行为并给出在自定义插件对话框中启用该能力的实战方法。功能来源与定位该能力由 dialogui 插件Dialog User Interface提供在 CKEditor 4.5.0 中随工单 #10986 引入“支持通过 ShiftAltHome/End 快捷键改变对话框输入框与 textarea 的文本方向”。方向信息不会丢失而是以 Unicode 隐式定向字符Implicit Directional Characters前置到输入值中随字段值一起存取从而保证“下一次打开对话框时恢复相同的文本方向”。在仓库中这一功能同时被三处文件覆盖形成完整的“文档 → 实现 → 测试”闭环手动测试用例inputdirsave.md保存方向与 inputdirtoggle.md切换方向自动化单元测试dirmarker.js核心实现dialogui/plugin.js。实测操作以表格对话框的 Summary 输入框为例手动测试用例 inputdirsave.md 使用表格Table对话框中的“Summary”摘要输入框来验证方向保存行为。运行前提是编辑器加载了wysiwygarea, toolbar, table, contextmenu这些插件对应 Bender 元数据bender-ckeditor-plugins测试页面本身只是一个替换了#editor的普通编辑器实例见 inputdirsave.html。完整操作流程如下打开表格对话框点击工具栏上的 Table 按钮。聚焦 “Summary” 输入框。按ALT SHIFT END切换方向键盘没有 END 键时使用FN ALT SHIFT RIGHT ARROW。预期结果Summary 输入框的方向变为 RTL。可通过两种方式验证检查输入框元素应带有dirrtl属性直接输入文本或使用方向键会发现字符/光标行为发生反向具体表现取决于浏览器。输入一些文本。提交对话框插入一张表格。再次点击工具栏的表格按钮新建表格的对话框。预期结果Summary 输入框的方向为 LTR新建表格没有初始值方向回到默认。关闭该对话框不提交。打开第一张表格的属性对话框。预期结果Summary 输入框的方向恢复为 RTL。这套步骤的精髓在于验证了三个关键行为切换快捷键能实时改变输入框方向步骤 3–4保存方向随值存入summary属性提交后再打开同一表格时方向被恢复步骤 6、10–11隔离无初始值的新对话框使用默认方向 LTR不会被上一次的方向“污染”步骤 7–8。方向切换的快捷键与事件绑定快捷键处理逻辑位于 dialogui/plugin.js 的toggleBidiKeyUpHandler函数// context {CKEDITOR.dialog.uiElement} UI element (textarea or textInput) // param {CKEDITOR.dom.event} evt toggleBidiKeyUpHandler function( evt ) { var keystroke evt.data.getKeystroke(); // ALT SHIFT Home for LTR direction. if ( keystroke CKEDITOR.SHIFT CKEDITOR.ALT 36 ) this.setDirectionMarker( ltr ); // ALT SHIFT End for RTL direction. else if ( keystroke CKEDITOR.SHIFT CKEDITOR.ALT 35 ) this.setDirectionMarker( rtl ); };两个快捷键对应的键码分别是36Home和35End叠加SHIFT ALT修饰键。可见ALT SHIFT Home→ 切换为LTRALT SHIFT End→ 切换为RTL。该处理器只对声明了bidi: true的控件生效。对单行文本输入框textInput事件绑定发生在 plugin.js对话框load时给输入元素挂上keydown/keyup监听其中keyup中通过if ( me.bidi )判断后才调用toggleBidiKeyUpHandler。对多行文本域textarea同理见 plugin.jsif ( me.bidi ) { dialog.on( load, function() { me.getInputElement().on( keyup, toggleBidiKeyUpHandler ); }, me ); }注意keyup监听在 textInput 上注册时使用了较低的优先级null, null, 1000这是为了避免与对话框 OK 按钮的 Enter 键提交逻辑冲突对应工单 #3749见 plugin.js 的注释。bidi 属性如何在对话框定义中启用方向切换方向切换并非默认开启开发者需要在对话框字段定义中显式声明bidi: true。API 文档定义于 dialogDefinition.js要点如下ShiftAltEnd—— 切换为 RTLShiftAltHome—— 切换为 LTR默认情况下输入框不设置任何文本方向即继承编辑器自身的文本方向editor 的lang.dir一旦设置了方向会在该字段每个非空值前前置一个方向标记\u202ARTL或\u202BLTR该标记的作用正是“在下次打开对话框时恢复相同的文本方向”。仓库中的典型用例是表格对话框的 Summary 字段定义于 table/dialogs/table.js{ type: text, id: txtSummary, bidi: true, requiredContent: table[summary], label: editor.lang.table.summary, setup: function( selectedTable ) { this.setValue( selectedTable.getAttribute( summary ) || ); }, commit: function( data, selectedTable ) { if ( this.getValue() ) selectedTable.setAttribute( summary, this.getValue() ); else selectedTable.removeAttribute( summary ); } }这里的bidi: true让 Summary 输入框获得方向切换能力setup在对话框打开时把表格已有的summary属性值可能带方向标记灌入输入框commit在提交时把值含方向标记写回table元素。同时 table/plugin.js 的allowedContent声明了table{width,height,border-collapse}[align,border,cellpadding,cellspacing,summary]保证summary属性在内容过滤时不被剥离。方向标记的存储与恢复setValue / getValue 的魔法方向之所以能在对话框重开时“自动恢复”关键在于 dialogui 对setValue()与getValue()的重写——它们负责把方向标记从值中“剥离/注入”。setValue()plugin.js当字段bidi: true时检查值的首字符是否为标记setValue: function( value ) { if ( this.bidi ) { var marker value value.charAt( 0 ), dir ( marker \u202A ? ltr : marker \u202B ? rtl : null ); if ( dir ) { value value.slice( 1 ); } // Set the marker or reset it (if dirnull). this.setDirectionMarker( dir ); } if ( !value ) { value ; } return CKEDITOR.ui.dialog.uiElement.prototype.setValue.apply( this, arguments ); },首字符为\u202A→ 方向判定为ltr首字符为\u202B→ 方向判定为rtl其余情况方向为null无标记。随后标记字符被slice(1)剥离只把“纯文本”写入真实的inputDOM同时调用setDirectionMarker()把方向同步到dir属性上。这正是手动测试中“检查输入框应带有dir属性”的依据。getValue()plugin.js反向操作取值时若存在方向标记则把标记重新前置到值上getValue: function() { var value CKEDITOR.ui.dialog.uiElement.prototype.getValue.call( this ); if ( this.bidi value ) { var dir this.getDirectionMarker(); if ( dir ) { value ( dir ltr ? \u202A : \u202B ) value; } } return value; },这一来一回形成了方向保存的完整闭环用户在对话框里按ALTSHIFTEND把方向切为 RTL输入文本内容提交时commit调用getValue()得到\u202B 内容存入表格的summary属性下次打开该表格对话框setup调用setValue(\u202B内容)setValue识别出\u202B标记 → 恢复 RTL 方向 → 输入框显示纯文本内容。这解释了手动测试第 10–11 步“打开第一张表格对话框时方向应为 RTL”的原因而第 7–8 步新建表格因为没有summary初始值setValue()得到dir null方向回落为默认的 LTR。setDirectionMarker 与 getDirectionMarkerdir 与>/** * Sets the text direction marker and the dir attribute of the input element. * since 4.5.0 * param {String} dir The text direction. Pass null to reset. */ setDirectionMarker: function( dir ) { var inputElement this.getInputElement(); if ( dir ) { inputElement.setAttributes( { dir: dir, data-cke-dir-marker: dir } ); // Dont remove the dir attribute if this field hasnt got the marker, // because the dir attribute could be set independently. } else if ( this.getDirectionMarker() ) { inputElement.removeAttributes( [ dir, data-cke-dir-marker ] ); } }, /** * Gets the value of the text direction marker. * since 4.5.0 * returns {String} ltr, rtl or null if the marker is not set. */ getDirectionMarker: function() { return this.getInputElement().data( cke-dir-marker ); },需要特别说明的细节写入方向时同时设置两个属性dir用于浏览器的实际渲染/光标行为和data-cke-dir-markerCKEditor 内部用于识别“该方向是用户显式设置的”getDirectionMarker()读取的正是data-cke-dir-marker清除方向时只有当字段已有方向标记即getDirectionMarker()非空才移除dir和data-cke-dir-marker。注释明确说明原因dir属性可能被独立设置例如在字段定义中直接写dir: rtl见 plugin.js 对 textarea 的处理不能因为“本次没有标记”就误删用户显式配置的dir。自动化测试佐证dirmarker.js功能的行为边界在 dirmarker.js 中被完整固化其主要断言覆盖了真实输入值不含标记setValue(\u202Bhello!)后底层input的原始值通过CKEDITOR.ui.dialog.uiElement.prototype.getValue.call( field )读取不应包含\u202BgetValue 注入标记对 RTL 字段调用getValue()后结果首字符应为\u202B对 LTR 应为\u202AgetDirectionMarker 返回值分别验证rtl、ltr、null三种状态无标记字段原样传递未声明bidi的字段无论setValue传入什么值getValue()都原样返回标记不会被剥离或注入且getDirectionMarker()始终为null空值与纯标记空字符串不会产生标记只含标记的值\u202B会被剥成空字符串getValue()同样返回空串setDirectionMarker 的 DOM 效果传入rtl/ltr时data-cke-dir-marker与dir两个属性同步存在且值一致传入空值时两个属性都被移除。这些断言与手动测试inputdirsave.md的验证方式检查dir属性、观察光标/字符反向互为印证一个验证 DOM 表现一个验证数据流逻辑。在自己插件中启用该能力若要在自定义对话框字段中支持 RTL/LTR 切换与保存只需两步在字段定义中声明bidi: true适用于type: text、password、tel、textarea它们都由 dialogui 的textBuilder/commonBuilder构建见 plugin.js 与末尾的addUIElement注册 plugin.js在commit回调中使用this.getValue()自动携带标记写入数据源在setup回调中使用this.setValue(已有值)自动剥离标记并恢复方向回填输入框。一个最小示例CKEDITOR.dialog.add( myDialog, function( editor ) { return { title: My Dialog, contents: [ { id: info, elements: [ { type: text, id: myField, label: My Field, bidi: true, setup: function( widget ) { this.setValue( widget.data.myField || ); }, commit: function( widget ) { widget.setData( myField, this.getValue() ); } } ] } ] }; } );这样最终写入数据的字符串中会自然携带\u202A/\u202B前缀下次打开对话框时方向即可无损恢复——与表格对话框 Summary 字段的行为完全一致。小结CKEditor 4 对话框输入框的双向文本方向功能本质上是一套“DOM 属性 值内标记”的双通道机制dir/data-cke-dir-marker属性负责即时渲染与方向识别\u202A/\u202B标记负责跨会话持久化。理解setValue/getValue的剥标记、注标记逻辑以及setDirectionMarker/getDirectionMarker的属性读写规则是掌握并复用它无论是排查表格 Summary 字段类问题还是为自定义对话框接入 RTL 支持的关键。赞分享前端UI组件【免费下载链接】ckeditor4The best enterprise-grade WYSIWYG editor. Fully customizable with countless features and plugins.项目地址https://gitcode.com/gh_mirrors/ck/ckeditor4点击查看免费下载相关推荐Angular Material 双向文本方向Bidirectionality指南用 CDK Bidi 让你的组件自动适配 LTR/RTLAngular Material 双向文本方向Bidirectionality指南用 CDK Bidi 让你的组件自动适配 LTR/RTL 本文基于 An前端UI组件设计系统Notepads 文本方向切换完全指南LTR 与 RTL 支持的终极教程Notepads 文本方向切换完全指南LTR 与 RTL 支持的终极教程 Notepads 作为一款现代化的轻量级文本编辑器提供了全面的 文本方向切换功能桌面应用uni-app x 中的 CSS direction 属性从 LTR 到 RTL 的文本方向控制与跨端兼容实践uni app x 中的 CSS direction 属性从 LTR 到 RTL 的文本方向控制与跨端兼容实践 导读 direction 是控制文本水平溢出方示例工程前端移动开发跨平台上一篇knowledge-work-plugins 小企业插件 content-strategy 技能避坑指南从销售数据分析到 30 天内容简报的八大 Gotchas 实战手册下一篇基于 Rube MCP 自动化 Idea Scale 任务awesome-codex-skills 中的 Composio 集成实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考