reactjseventsckeditorpaste

How to mange a paste event within CKEdit 5 React component?


When you employ the CKEditor, the user might try to be edgy and paste several thousand lines at once. The browser wouldn't like that. One strategy would be to intercept the paste event and trim the data to a more manageable chunk. Looking around I found this question - this is basically the same situation, I only can't get my head around how to achieve the same with the React component. I'd also appreciate different and more insightful strategies.


Solution

  • In short, I posed a question directly in the developer's github issue tracker. With a lot of trail and error in the Javascript console and their eventual answer I managed to control the text coming in the CKEditor with a paste event.

    Key points:

    I guess the best way to explain what I did would be to just show the code, so:

    <CKEditor
        id={id}
        editor={ClassicEditor}
        data={value}
        onInit={editor => {
            const documentView = editor.editing.view.document
            documentView.on('paste', (event, data) => {
                editor.plugins.get('Clipboard').on('inputTransformation', (event, data) => {
                    let accumulated = editor.getData()
                    for (const element of data.content.getChildren()) {
                        if (element._textData !== undefined) {
                           accumulated += element._textData
                        } else {
                           accumulated += element.getChild(0)._textData
                        }
                        if (accumulated.length >= SOME_LENGTH) {
                           event.stop()
                           editor.setData('')
                           editor.setData(accumulated.slice(0, SOME_LENGTH))
                           break
                        }
                     }
                  })
               })
            }}
            onChange={(event, editor) => {
               const data = editor.getData()
               inputOnChange(data)
            }}
         />
    

    So that's it. I hope this shortens someone else's struggle a bit.