Warm tip: This article is reproduced from serverfault.com, please click

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

发布于 2020-12-12 09:57:57

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.

Questioner
johnniepop
Viewed
0
johnniepop 2021-01-05 07:09:43

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 used onInit prop. onReady didn't work for me.
  • The data in the paste event is divided in elements (like html ones) and is being accessed a bit weirdly.

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.