首页 > 解决方案 > CKEditor 5 set style on Element

问题描述

we are trying to "hack" CKEditor 5 font-family a bit. We would like set font-style to parent element (for example <p>), when you select whole text in element. Resulting syntax would be much cleaner instead of unnecessary <span> tag inside <p>

But when trying to setAttribute on Element it doesn't work, however the attribute is set in Model. But resulting text is unchanged. Also we haven't found addStyle method on Element

Here is our current modification of fontcommand.js (note line with if(range.start.isAtStart && range.end.isAtEnd){):

model.change( writer => {
            if ( selection.isCollapsed ) {
                if ( value ) {
                    writer.setSelectionAttribute( this.attributeKey, value );
                } else {
                    writer.removeSelectionAttribute( this.attributeKey );
                }
            } else {
                const ranges = model.schema.getValidRanges( selection.getRanges(), this.attributeKey );

                for ( const range of ranges ) {
                    if ( value ) {
                        if(range.start.isAtStart && range.end.isAtEnd){
                            writer.setAttribute( this.attributeKey, value, range.start.parent );
                        } else {
                            writer.setAttribute( this.attributeKey, value, range );
                        }
                    } else {
                        writer.removeAttribute( this.attributeKey, range );
                    }
                }
            }
        } );

Having <p>something</p> we would like to get <p style="font-family: Arial">something</p> when choosing font-style.

Anyone willing to give us a hint?

Thanks.

标签: javascriptckeditorckeditor5

解决方案


快速回答

以可靠的方式实现这一点所需的工作量(在所有可能的情况下如何以及如何应用字体系列)不值得更清晰的输出。

长答案

首先,您需要了解编辑器的模型是如何工作的。它是富文本内容的抽象表示(您不会在其中找到样式,只有通用属性),稍后会转换为类似DOM 的视图

因此,回答为什么尽管您更改了模型中的某些属性,但字体系列样式并未在 DOM 中呈现 - 那是因为您没有为该属性提供转换器。默认情况下,字体插件仅提供文本属性的转换器(是的,在模型中,内联样式表示为文本属性)。

现在,让我们考虑您提供了正确的转换器。现在做什么?

用户将字体系列应用于整个段落——因此您更改该段落的此属性。它被渲染为<p style=...>.

但是随后,用户更改了该段落中部分文本的字体系列。如果你不做某事,你最终会得到:

<p style="font-family:x">foo <span style="font-family:y">bar</span></p>

很快你就会有这个:

<p style="font-family:x"><span style="font-family:y">bar</span></p>

不再是更清洁的输出,对吧?

因此,您需要做的是观察模型中的所有更改,并在某个时候从段落中删除此属性。实际上,甚至还有一个可以用于此类工作的后置修复器的概念。但它变得复杂,不是吗?

另一种选择是使用 CKEditor 5 中的转换(模型和视图之间)非常强大的事实。您应该能够将模型的文本属性转换为(有条件地):

  • 如果该属性存在于该元素的全部内容中,则为视图元素的属性;
  • <span>或使用默认转换器(在文本上创建s)。

代码在哪里?我懒得写了。并测试它。IMO,这种改进是不值得的。

编辑:很抱歉最后一句话的语气,但这就是我对调整这些事情的感受。作为开发人员,我们倾向于迂腐,但从数据的角度来看,它并没有太大的区别(在这种情况下)。


推荐阅读