CKEditor 5 编辑器在粘贴纯文本时,并没有将换行符转换成段落,而是转换成一个 <br/> 标签,导致整篇文章成为一个段落。这样,在修改段落格式时会带来一些问题。比如你想修改其中一个段落的对齐方式,修改之后,你会发现整篇文章的对齐方式都变了。
关于这个问题,官方文档中找到了一个相关说明,具体请参见 Pasting plain text 。
Pasting plain text with a double line break will turn the break into a paragraph. A single line break will instead be turned into a soft break upon pasting.
翻译过来就是,在粘贴纯文本时,两个换行符才会转换成段落,一个换行符只会转换成一个软换行。软换行在html里就是一个<br/>标签。
这种处理方式不太符合人们的使用习惯,要想修改这种处理方式,将每个换行符都转换成段落,只能自己编写插件,官方没有提供相关的配置选项。
下面是我写的插件,有需要的同学可以拿去用。
import {Plugin} from '@ckeditor/ckeditor5-core';
import ClipboardPipeline from '@ckeditor/ckeditor5-clipboard/src/clipboardpipeline'
import ClipboardObserver from '@ckeditor/ckeditor5-clipboard/src/clipboardobserver'
function plainTextToHtml(text) {
text = text
// Encode <>.
.replace(/</g, '<')
.replace(/>/g, '>')
// Creates a paragraph for each single line break.
.replace(/\r?\n/g, '</p><p>')
// Preserve trailing spaces (only the first and last one – the rest is handled below).
.replace(/^\s/, ' ')
.replace(/\s$/, ' ')
// Preserve other subsequent spaces now.
.replace(/\s\s/g, ' ');
if (text.includes('</p><p>')) {
// If we created paragraphs above, add the trailing ones.
text = `<p>${text}</p>`;
}
// TODO:
// * What about '\nfoo' vs ' foo'?
return text;
}
/**
* CKEditor在粘贴纯文本时,默认将1个换行符转换成<br/>标签,两个换行符才转换成段落,不太符合我们的使用习惯。
* 本插件将把所有换行符均转换成段落。
*/
export default class PastPlainTextFormatting extends Plugin {
static get requires() {
return [ClipboardPipeline];
}
static get pluginName() {
return 'PastPlainTextFormatting';
}
init() {
const editor = this.editor;
const view = editor.editing.view;
const viewDocument = view.document;
view.addObserver(ClipboardObserver);
this.listenTo(viewDocument, 'clipboardInput', (evt, data) => {
const dataTransfer = data.dataTransfer;
let content = data.content || '';
if (!content && dataTransfer.getData('text/plain')) {
content = plainTextToHtml(dataTransfer.getData('text/plain'));
data.content = this.editor.data.htmlProcessor.toView(content);
}
})
}
}