Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CKEditor 5 paste as plain text

Is there an option to paste always from the clipboard as plain text?

I tried it that way, but that does not work:

$(document).ready(function () {

    ClassicEditor.create(document.querySelector('#text'), {
        toolbar: [
            'heading',
            'bold',
            'italic',
            'link',
            'bulletedList',
            'numberedList',
            'blockQuote',
            'undo',
            'redo'
        ]
    }).then(function (editor) {

        this.listenTo(editor.editing.view, 'clipboardInput', function (event, data) {
            // No log.
            console.log('hello');
        });

    }).catch(function (error) {

    });

});

https://docs.ckeditor.com/ckeditor5/latest/api/module_clipboard_clipboard-Clipboard.html

https://docs.ckeditor.com/ckeditor5/latest/api/clipboard.html

https://docs.ckeditor.com/ckeditor5/latest/api/module_engine_view_document-Document.html#event-event:paste

like image 789
Thomas Müller Avatar asked Apr 07 '18 15:04

Thomas Müller


1 Answers

The clipboardInput event is fired on the Document, not the View. So the first thing will be to listen on the right object.

The second thing is ensuring that the content inserted into the editor is a plain text. This can be done in two ways:

  • HTML taken from the clipboard can be "plain-textified". But this is hard.
  • We can take plain-text from the clipboard and insert that into the editor. However, the editor expects HTML to be pasted, so you need to "HTMLize" this plain-text. CKEditor 5 offers a function for that – plainTextToHtml().

To override the editor's default behaviour we'll need to override this callback: https://github.com/ckeditor/ckeditor5-clipboard/blob/a7819b9e6e2bfd64cc27f65d8e56b0d26423d156/src/clipboard.js#L137-L158

To do that, we'll listen to the same event (with a higher priority), do all the same things, but ignore text/html flavour of the clipboard data. Finally, we 'll call evt.stop() to block the default listener from being executed and ruining our job:

import plainTextToHtml from '@ckeditor/ckeditor5-clipboard/src/utils/plaintexttohtml';

// ...

const clipboardPlugin = editor.plugins.get( 'Clipboard' );
const editingView = editor.editing.view;

editingView.document.on( 'clipboardInput', ( evt, data ) => {
    if ( editor.isReadOnly ) {
        return;
    }

    const dataTransfer = data.dataTransfer;

    let content = plainTextToHtml( dataTransfer.getData( 'text/plain' ) );

    content = clipboardPlugin._htmlDataProcessor.toView( content );

    clipboardPlugin.fire( 'inputTransformation', { content, dataTransfer } );

    editingView.scrollToTheSelection();

    evt.stop();
} );

EDIT:

Starting from CKEditor 27.0.0 the code has changed (you can read more about it here https://ckeditor.com/docs/ckeditor5/latest/builds/guides/migration/migration-to-27.html#clipboard-input-pipeline-integration)

import plainTextToHtml from '@ckeditor/ckeditor5-clipboard/src/utils/plaintexttohtml';
//...
const clipboardPlugin = editor.plugins.get( 'ClipboardPipeline' );
const editingView = editor.editing.view;

editingView.document.on( 'clipboardInput', ( evt, data ) => {
    if ( editor.isReadOnly ) {
        return;
    }
    const dataTransfer = data.dataTransfer;
    let content = plainTextToHtml( dataTransfer.getData( 'text/plain' ) );
    data.content = editor.data.htmlProcessor.toView( content );
                
    editingView.scrollToTheSelection();
}, { priority: 'high' } );
like image 90
Reinmar Avatar answered Oct 23 '22 23:10

Reinmar