首页 > 解决方案 > 在 CKEditor5 中插入带有类和 id 的跨度在粘贴时会产生错误

问题描述

我正在开发一个 CKEditor5 插件,它需要我插入一个带有 id 和一些类的跨度。

这是我允许的代码:

editor.model.schema.register('span', {
    inheritAllFrom: '$block',
    allowIn: ['paragraph'],
    allowAttributes: ['id', 'class']
});
editor.conversion.elementToElement({model: 'span', view: 'span'});          
editor.conversion.attributeToAttribute({model: 'class', view: 'class'});
editor.conversion.attributeToAttribute({model: {name: 'span', key: 'id'}, view: 'id'});

这使我可以毫无问题地插入跨度。我的问题是,如果我粘贴一些带有跨度的内容(例如,在 FontBackGroundColor 插件中设置了背景颜色的文本),然后按退格键,我会收到此错误:

VM28478:5 Uncaught CKEditorError: move-operation-node-into-itself: Trying to move a range of nodes into one of nodes from that range. Read more: https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/error-codes.html#error-move-operation-node-into-itself

    at cc._validate (<anonymous>:5:277330)
    at Jc.on.priority (<anonymous>:5:324234)
    at Jc.fire (<anonymous>:5:101659)
    at Jc.(anonymous function) [as applyOperation] (<anonymous>:5:115956)
    at gc.move (<anonymous>:5:289708)
    at gc.insert (<anonymous>:5:287384)
    at t (<anonymous>:5:319802)
    at <anonymous>:5:319915
    at Jc.change (<anonymous>:5:324808)
    at Nc (<anonymous>:5:318986)

我的方法正确吗?我试图阅读文档,但我认为我没有完全正确。

标签: javascriptckeditor5

解决方案


这种方法不是最适合 CKEditor 5。在 CKEditor 5 中实现了一个自定义模型,它将某些功能的视图与它在模型中的存储方式分开。因此,在为 CKEditor 5 功能实现模型时,您应该考虑它解决了什么问题,而不是它在 HTML 中的表示方式。这种方法在定义模型行为时需要做更多的工作,但这种设计使 CKEditor 5 能够协同工作。

话虽如此,在很多情况下,人们只想保留所有<span>样式、类和自定义属性。在 CKEditor 5 中,您应该将一些样式、类或属性映射到模型元素或$text节点属性以匹配特征语义——而不是 HTML 数据。

请记住,这不是 CKEditor 的理想解决方案,您应该

  1. 通过扩展内置的$text.

    editor.model.schema.extend( '$text', {
        allowAttributes: [ 'spanId', 'spanClass' ]
    } );
    
  2. 提供向上转换(视图到模型)和向下转换(模型到视图)的转换,将您映射<span>到模型文本属性。您可以在转换指南中阅读更多相关信息。但是像下面这样的东西应该可以工作:

    editor.conversion.for( 'upcast' ).elementToAttribute( {
        view: {
            name: 'span',
            attributes: {
                'id': /.+/
            }
        },
        model: {
            key: 'spanId',
            value: viewElement => viewElement.getAttribute( 'id' )
        }
    } );
    
    editor.conversion.for( 'downcast' ).attributeToElement( {
        model: 'spanId',
        view: ( modelAttributeValue, viewWriter ) => {
            return viewWriter.createAttributeElement( 'span', {
                id: modelAttributeValue
            } );
        }
    } );
    

现在,您的设置不起作用的原因是您将块插入另一个块 - CKEditor 5 模型不支持。大多数 HTML 内联元素通常会转换为某些文本属性,因此需要element-to-attribute转换。


推荐阅读