为什么我可以在不修改模式的情况下将自定义元素插入 ckeditor

Why can I insert a custom element into ckeditor without modifing the schema

当我使用以下 javascript 代码时,一个自定义节点被插入到模型中。但我不明白为什么当该类型 (mtnote) 尚未在架构中注册时这会起作用。

    model.change(writer => {
        const noteElement=writer.createElement('mtnote',{ 'noteText': 'Hello first note' } );
                const insertNotePos=model.document.selection.getFirstPosition();
                writer.append(noteElement,insertNotePos);
});

我知道节点已插入,因为我在遍历模型时可以看到它,如果我添加 editor.conversion.for('downcast') 我可以将 mtnote 元素向下转换为任何查看我想要的元素。

所以 writer.append 没有检查模式,还是我误解了模式应该做什么?

你是对的 – Writer 不检查架构。

原因是它是一个非常低级的工具,它实现了在模型上执行原子操作的方法(好吧,我说的是这个,因为下面还有一个更低的级别,用 operations 自己,但这是受保护的 API)。反正作者水平很低

现在,当您实施命令或任何其他功能时,您可能需要执行多个操作才能完成所有必要的更改。同时(在这些原子操作之间)的状态可能不正确。作者必须允许。

例如,您需要将 <foo><$root> 移动到 <bar> 并(同时)将其重命名为 <oof>。但是架构定义 <$root> 中不允许 <oof><bar> 中不允许 <foo>。如果作者检查架构,它会抱怨,而不管 renamemove 操作的顺序如何。

但是假设我们可以通过检查该块末尾 change() block (it works like a transaction – the state needs to be correct at the end of it). In fact, we plan to strip disallowed attributes 末尾的模式来解决这个问题。

不过还是有问题:

  • 事务提交后如何修复内容?从用户的角度来看,不可能实施不会破坏内容的合理启发式方法。
  • 模型在协作更改期间可能会失效。操作转换虽然由我们以非常丰富的形式实现(有 11 种类型的操作而不是基本的 3 种)确保冲突解决和最终一致性,但不是模型的有效性。

因此,我们选择使用更具表现力和灵活性的方式来处理这种情况的个案post fixers。此外,我们将检查架构的责任转移到了功能上。在进行更改之前,他们可以做出更好的先验决策。