javascript - 将 CKeditor 5 与 rtl 结合使用

标签 javascript html ckeditor

我想知道如何将 CKeditor 5 设置为 RTL? 我在他们的网站上找不到这个。

如果不可能,什么是好的 rtl 编辑器?

谢谢!

最佳答案

我面对这个问题两周了,最后,根据我的经验,我通过在 ckeditor.js 中编码解决了它,添加 CKEditor 5 组件的最佳方法是,首先,你应该去 https://ckeditor.com/ckeditor-5/online-builder/并通过 5 个简单步骤。 那么你应该将它添加到你的项目中。此外,还可以向此构建组件添加 RTL 方向。然而,主要问题是它只是将 rtl 方向添加为默认值,并且无法根据您的需要在文本中更改它。因此你必须自己做一些编码。我做到了,并且在 Angular 8 中完美运行

如果您仔细按照以下步骤操作,方向选择将轻松添加到您的项目中。

  1. 转到@ckeditor/ckeditor5-build-classic/build并打开ckeditor.js文件

  2. 然后尝试从 min js 文件中提取它 - 你可以通过谷歌搜索找到太多在线工具。

  3. 那么首先你需要找到下面的 block 代码

class Ak extends ok {
        static get requires() {
          return [pk, xk];
        }
        static get pluginName() {
          return "Alignment";
        }
      }

  • 现在,在此 block 代码之后,您应该添加以下代码(只需将其从此处复制到您的文件中)
  • // Removes the direction attribute from blocks.
          // @private
          function removeDirectionFromSelection(blocks, writer) {
            for (const block of blocks) {
              writer.removeAttribute(DIRECTION, block);
            }
          }
    
          // Sets the direction attribute on blocks.
          // @private
          function setDirectionOnSelection(blocks, writer, direction) {
            for (const block of blocks) {
              writer.setAttribute(DIRECTION, direction, block);
            }
          }
          const DIRECTION = 'direction';
          class DirectionCommand extends sk {
            refresh() {
              const firstBlock = ck(this.editor.model.document.selection.getSelectedBlocks());
    
              // As first check whether to enable or disable the command as the value will always be false if the command cannot be enabled.
              this.isEnabled = !!firstBlock && this._canBeAligned(firstBlock);
              this.value = (this.isEnabled && firstBlock.hasAttribute('direction')) ? firstBlock.getAttribute('direction') : 'rtl';
            }
            execute(options = {}) {
              const editor = this.editor;
              const model = editor.model;
              const doc = model.document;
              const value = options.value;
              model.change(writer => {
                // Get only those blocks from selected that can have direction set
                const blocks = Array.from(doc.selection.getSelectedBlocks()).filter(block => this._canBeAligned(block));
                const currentDirection = blocks[0].getAttribute('direction');
    
                // Remove direction attribute if current direction is:
                // - default (should not be stored in model as it will bloat model data)
                // - equal to currently set
                // - or no value is passed - denotes default direction.
                const removeDirection = isDefault(value) || currentDirection === value || !value;
    
                if (removeDirection) {
                  removeDirectionFromSelection(blocks, writer);
                } else {
                  setDirectionOnSelection(blocks, writer, value);
                }
              });
            }
    
            _canBeAligned(block) {
              return this.editor.model.schema.checkAttribute(block, DIRECTION);
            }
          }
    
    
    
    
          const supportedOptions = ['ltr', 'rtl'];
          class DirectionEditing extends ok {
    
            constructor(editor) {
              super(editor);
    
              editor.config.define('direction', {
                options: [...supportedOptions]
              });
            }
    
            init() {
              const editor = this.editor;
              const schema = editor.model.schema;
    
              // Filter out unsupported options.
              const enabledOptions = editor.config.get('direction.options').filter(isSupported);
    
              // Allow direction attribute on all blocks.
              schema.extend('$block', { allowAttributes: 'direction' });
              editor.model.schema.setAttributeProperties('direction', { isFormatting: true });
    
              const definition = _buildDefinition(enabledOptions.filter(option => !isDefault(option)));
    
              editor.conversion.attributeToAttribute(definition);
    
              editor.commands.add('direction', new DirectionCommand(editor));
            }
          }
          function isSupported(option) {
            return supportedOptions.includes(option);
          }
          function _buildDefinition(options) {
            const definition = {
              model: {
                key: 'direction',
                values: options.slice()
              },
              view: {}
            };
    
            for (const option of options) {
              definition.view[option] = {
                key: 'style',
                value: {
                  'direction': option
                }
              };
            }
    
            return definition;
          }
          function isDefault(direction) {
            // Right now only LTR is supported so the 'ltr' value is always the default one.
            return direction === 'rtl';
          }
          class DirectionUI extends ok {
            get localizedOptionTitles() {
              const t = this.editor.t;
    
              return {
                'ltr': t('چپ چین کردن متن'),
                'rtl': t('راست چین کردن متن'),
              };
            }
    
            static get pluginName() {
              return 'DirectionUI';
            }
    
            init() {
              const editor = this.editor;
              const componentFactory = editor.ui.componentFactory;
              const t = editor.t;
              const options = editor.config.get('direction.options');
    
              options
                .filter(isSupported)
                .forEach(option => this._addButton(option));
    
              componentFactory.add('direction', locale => {
                const dropdownView = jw(locale);
    
                // Add existing direction buttons to dropdown's toolbar.
                const buttons = options.map(option => componentFactory.create(`direction:${option}`));
                Fw(dropdownView, buttons);
    
                // Configure dropdown properties an behavior.
                dropdownView.buttonView.set({
                  label: t('چپ چین راست چین'),
                  tooltip: true
                });
    
                dropdownView.toolbarView.isVertical = true;
    
                dropdownView.extendTemplate({
                  attributes: {
                    class: 'ck-direction-dropdown'
                  }
                });
    
                // The default icon is align left as we do not support RTL yet (see #3).
                const defaultIcon = alignLeftIcon;
    
                // Change icon to reflect current selection's direction.
                dropdownView.buttonView.bind('icon').toMany(buttons, 'isOn', (...areActive) => {
                  // Get the index of an active button.
                  const index = areActive.findIndex(value => value);
    
                  // If none of the commands is active, display either defaultIcon or the first button's icon.
                  if (index < 0) {
                    return defaultIcon;
                  }
    
                  // Return active button's icon.
                  return buttons[index].icon;
                });
    
                // Enable button if any of the buttons is enabled.
                dropdownView.bind('isEnabled').toMany(buttons, 'isEnabled', (...areEnabled) => areEnabled.some(isEnabled => isEnabled));
    
                return dropdownView;
              });
            }
    
    
            _addButton(option) {
              const editor = this.editor;
    
              editor.ui.componentFactory.add(`direction:${option}`, locale => {
                const command = editor.commands.get('direction');
                const buttonView = new Ew(locale);
    
                buttonView.set({
                  label: this.localizedOptionTitles[option],
                  icon: icons.get(option),
                  tooltip: true
                });
    
                // Bind button model to command.
                buttonView.bind('isEnabled').to(command);
                buttonView.bind('isOn').to(command, 'value', value => value === option);
    
                // Execute command.
                this.listenTo(buttonView, 'execute', () => {
                  editor.execute('direction', { value: option });
                  editor.editing.view.focus();
                });
    
                return buttonView;
              });
            }
          }
          const alignLeftIcon = '<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M 10 0.199219 C 7.292969 0.199219 5.101562 2.394531 5.101562 5.101562 C 5.101562 7.804688 7.292969 10 10 10 L 10 19.800781 L 12.449219 19.800781 L 12.449219 2.648438 L 14.898438 2.648438 L 14.898438 19.800781 L 17.351562 19.800781 L 17.351562 2.648438 L 19.800781 2.648438 L 19.800781 0.199219 Z M 0.199219 13.675781 L 5.101562 8.777344 L 0.199219 3.875 Z M 0.199219 13.675781"/></svg>';
          const alignRightIcon = '<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M 5.101562 0.199219 C 2.394531 0.199219 0.199219 2.394531 0.199219 5.101562 C 0.199219 7.804688 2.394531 10 5.101562 10 L 5.101562 19.800781 L 7.550781 19.800781 L 7.550781 2.648438 L 10 2.648438 L 10 19.800781 L 12.449219 19.800781 L 12.449219 2.648438 L 14.898438 2.648438 L 14.898438 0.199219 Z M 19.800781 3.875 L 14.898438 8.777344 L 19.800781 13.675781 Z M 19.800781 3.875"/></svg>';
    
          const icons = new Map([
            ['ltr', alignLeftIcon],
            ['rtl', alignRightIcon],
          ]);
          class Direction extends ok {
    
            static get requires() {
              return [DirectionEditing, DirectionUI];
            }
    
            static get pluginName() {
              return 'Direction';
            }
          }

  • 现在您需要找到“EL.builtinPlugins[....]”代码块,然后您应该将“Direction”添加到其数组中。
  • 在您的 ckeditor 配置中添加工具栏项目的组件中,您需要在项目中添加“方向”(请注意其单词大小写敏感性)。
  • 恭喜。您现在将在工具栏中看到方向按钮。 享受

    关于javascript - 将 CKeditor 5 与 rtl 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47238886/

    相关文章:

    javascript - Meteor 本地服务器可以访问数据库,但客户端不能

    JavaScript中的数值转换操作

    javascript - NoUiSlider 无法正常工作

    javascript - 单击事件后范围属性未反射(reflect)在 View 中

    javascript - 如何使用组合键使用 'key' 事件在 CK Editor 中调用自定义方法

    javascript - 如何在 JavaScript 中删除 JSON 字符串中的第一个和最后一个双引号?

    javascript - 将 jQuery 代码放在 head 标记中时不起作用

    html - 内联 block div 下一个包含图像的 div 被下推

    php - CKEditor 未与 Sonata Formatter(Sonata Admin Bundle)一起显示

    javascript - 正则表达式:从可能包含多个 '{' 和 '}' 的字符串中提取子字符串