Hey, when users paste plaintext content, I need to run some tests on the text first and only if it does not contain X, Y and Z, I want to let it be pasted as it would have been without tests. Unfortunately these tests work asynchronously. I think I have a working solution, but it feels a bit hacky as I needed to copy some code from the ProseMirror repositories and import a function only exported for testing. Suggestions are appreciated.
First I added a transformPastedText
property to a plugin. It takes the text, sends it to the async handler, and always returns an empty string.
Then, once the async handler receives a response, and we found out that it indeed needs to be treated as plain text, we run this insertText function, which basically is trying to turn the text into an HTMl paste instead and then tries to emulate the steps that an HTML paste would take:
insertText() {
// Inserts text as if it was pasted. We do that by converting it to html and inserting it that way.
// Adapted from prosemirror-view/src/input.js
let dom = document.createElement("div")
this.text.trim().split(/(?:\r\n?|\n)+/).forEach(block => {
dom.appendChild(document.createElement("p")).textContent = block
})
let html = dom.innerHTML
let slice = __parseFromClipboard(this.view, '', html, this.view.shiftKey, this.view.state.selection.$from)
if (!slice) {
return
}
let singleNode = this.sliceSingleNode(slice)
let tr = singleNode ? this.view.state.tr.replaceSelectionWith(singleNode, this.view.shiftKey) : this.view.state.tr.replaceSelection(slice)
this.view.dispatch(tr.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste"))
}
Most of this is directly copied from ProseMirror so I wonder if there is a more elegant solution out there.