【问题标题】:Custom Element (Web Component) won't accept keyboard input when inserted by a CKEditor 5 plugin由 CKEditor 5 插件插入时,自定义元素(Web 组件)将不接受键盘输入
【发布时间】:2021-06-04 10:31:33
【问题描述】:

我正处于开发插件的初始阶段,该插件允许用户将占位符元素插入 HTML 内容中,这些内容将在服务器端进行处理,并用于将一些简单的逻辑合并到生成的 PDF 文档中。为此,我尝试插入一个使用 Web 组件 API 定义的自定义元素。

class NSLoop extends HTMLElement {
    constructor() {
        super();
    }

    get source() {
        return this.getAttribute('source');
    }

    get as() {
        return this.getAttribute('as');
    }
}

window.customElements.define('ns-loop', NSLoop);

loopediting.js的内容:

import Plugin from "@ckeditor/ckeditor5-core/src/plugin";
import Widget from "@ckeditor/ckeditor5-widget/src/widget";
import {viewToModelPositionOutsideModelElement} from "@ckeditor/ckeditor5-widget/src/utils";
import LoopCommand from "./loopcommand";

export default class LoopEditing extends Plugin {
    static get requires() {
        return [Widget];
    }

    constructor(editor) {
        super(editor);
    }

    init() {
        this._defineSchema();
        this._defineConverters();

        this.editor.commands.add('loop', new LoopCommand(this.editor));

        this.editor.editing.mapper.on('viewToModelPosition', viewToModelPositionOutsideModelElement(this.editor.model, viewElement => viewElement.is('element', 'ns-loop')));
    }

    _defineSchema() {
        const schema = this.editor.model.schema;

        schema.register('loop', {
            isBlock: false,
            isLimit: false,
            isObject: false,
            isInline: false,
            isSelectable: false,
            isContent: false,
            allowWhere: '$block',
            allowAttributes: ['for', 'as'],
        });

        schema.extend( '$text', {
            allowIn: 'loop'
        } );

        schema.extend( '$block', {
            allowIn: 'loop'
        } );
    }

    _defineConverters() {
        const conversion = this.editor.conversion;

        conversion.for('upcast').elementToElement({
            view:  {
                name:    'ns-loop',
            },
            model: (viewElement, {write: modelWriter}) => {
                const source = viewElement.getAttribute('for');
                const as     = viewElement.getAttribute('as');

                return modelWriter.createElement('loop', {source: source, as: as});
            }
        });

        conversion.for('editingDowncast').elementToElement({
            model: 'loop',
            view:  (modelItem, {writer: viewWriter}) => {
                const widgetElement = createLoopView(modelItem, viewWriter);
                return widgetElement;
            }
        });

        function createLoopView(modelItem, viewWriter) {
            const source = modelItem.getAttribute('source');
            const as     = modelItem.getAttribute('as');
            const loopElement = viewWriter.createContainerElement('ns-loop', {'for': source, 'as': as});

            return loopElement;
        }
    }
}

此代码有效,因为<ns-loop> 元素已成功插入到编辑器内容中;但是,我无法编辑此元素的内容。任何键盘输入都插入到<p> 元素之前的<ns-loop> 元素中,并且一旦鼠标停止移动,任何文本选择都会消失。此外,只能将光标放在元素的开头。

如果我只是将“ns-loop”替换为“div”或“p”的标记名称,我可以在元素内输入而不会出现问题,所以我怀疑我在架构定义中遗漏了一些东西让 CKEditor 意识到这个元素是“允许”输入的,但是我不知道我可能错过了什么——据我所知,这就是我应该通过schema.extend() 调用实现的目标。

我在架构定义中尝试了无数种 allowedIn、allowedWhere、inheritAllFrom、isBlock、isLimit 等,但行为没有明显变化。

谁能提供任何见解?

编辑: 我刚刚注意到的一些附加信息 - 当光标位于 <ns-loop> 元素内时,标题/段落下拉菜单为空。这可能是相关的。

编辑 2: 我发现罪魁祸首正盯着我的脸。

this.editor.editing.mapper.on('viewToModelPosition', viewToModelPositionOutsideModelElement(this.editor.model, viewElement => viewElement.is('element', 'ns-loop')));

我是 CKE5 插件领域的新手,并且正在使用其他插件作为参考点,我想我从另一个插件中复制了该代码。删除该代码可以解决问题。

【问题讨论】:

    标签: javascript ckeditor ckeditor5 ckeditor5-plugin


    【解决方案1】:

    如第二次编辑中所述,罪魁祸首是代码,

    this.editor.editing.mapper.on('viewToModelPosition', viewToModelPositionOutsideModelElement(this.editor.model, viewElement => viewElement.is('element', 'ns-loop')));
    

    我显然是从另一个我用来参考的插件中复制的。删除此代码解决了眼前的问题。

    我会接受这个答案并在 2 天计时器到时关闭问题。

    【讨论】:

      猜你喜欢
      • 2011-09-03
      • 2017-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-11
      相关资源
      最近更新 更多