简体   繁体   中英

ProseMirror -> A Text Rich Text Editor - Trigger an event pure js

I am implementing a chrome extension that fills a form basically.

This form has ProseMirror rich text editor in it.

I want to trigger Ctrl+V or paste operation on the text editor, but I couldn't find any solution to this. these are the things I've tried so far:

let el = document.querySelector('[contenteditable="true"]')
el.focus()

navigator.clipboard.readText().then((clipText) => {
    // el.innerText = clipText doesn't work
    // el.innerHTML = clipText doesnt't work
    // this.document.execCommand("insertText", false, clipText) doesnt work
})
document.dispatchEvent(new KeyboardEvent({key:'V', ctrlKey: true})) // doesnt work

When I do the pasting operation manually, the prose mirror component automatically converts it to a pretty table.

If you want to try -> copy a table then paste it here https://prosemirror-tables.netlify.app/

在此处输入图像描述

How do I trigger the paste event so it would look like as expected case?

Eventhough, this case is related to prose mirror, we may consider this problem for other rich text editors as well.

If I just copy an image and paste it into a rich text editor, picture will be uploaded but it won't work If I try to paste it programmatically


Additional screenshot to be clearer在此处输入图像描述

It look like this If I paste it manually: 在此处输入图像描述

I've tested the following code in Chromium 107.0.5304.121 (Official Build) Arch Linux (64-Bit), and it does what you require.

Notes:

  • Without the "clipboardRead" permission, document.execCommand("paste") doesn't paste the clipboard contents, and returns false.
  • The while loop removes all text from the div, so that it only contains the clipboard contents when the content script has finished.
  • The div element must be focused to receive the clipboard contents during the paste operation, that's why element.focus(); is necessary.
  • Without the zero-millisecond delay, the removed child nodes re-appear after the paste. This probably has something to do with the task queue.
  • Document.execCommand() is deprecated, so you should avoid using it if possible. Before you ask "Is there any other way to solve this problem, without using Document.execCommand()?"--- Not to my knowledge, or I would've posted it here. But maybe someone else has a better solution.
  • You could probably use Native Messaging to simulate the user pressing Ctrl-V. That's more complicated, but doesn't use any deprecated features.

manifest.json

{
    "manifest_version": 3,
    "name": "Paste",
    "version": "1.0",
    "action": {
    },
    "background": {
        "service_worker": "background.js"
    },
    "content_scripts": [
        {
            "matches": ["*://*/*"],
            "js": ["content_script.js"]
        }
    ],
    "permissions": [ "clipboardRead" ]
}

background.js

console.log("background.js");

content_script.js

let element = document.querySelector('[contenteditable="true"]');
if (element) {
    console.log("element.hasChildNodes()", element.hasChildNodes());
    while (element.hasChildNodes()) {
        element.removeChild(element.lastChild)
    }
    element.focus();
    setTimeout(() => {
        let result = document.execCommand("paste");
        console.log("result", result);
    }, 0);
}
else {
    console.log('No elements with contenteditable="true"');
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM