5

Say, in my Chrome extension I need to copy a user formatted HTML text on to Clipboard. The text (in its HTML form) may be something like this:

This is a <b>test</b><div><br></div>
<div>And this is too</div><div><br></div><div>Thank you</div>

If I use this JavaScript example, all I get copied is HTML markup from above. But I'm wondering, can I copy it as formatted text, or this?

This is a test
And this is too
Thank you

Community
  • 1
  • 1
c00000fd
  • 20,994
  • 29
  • 177
  • 400

1 Answers1

3

Once crbug.com/395376 is fixed, you can declare the clipboardWrite permission in your manifest file and simply use the folllowing code from yuor content script:

var element = document.body; // Example, select the "whole" document
// Change selected area
var r = document.createRange();
r.selectNode(element);
var s = window.getSelection();
s.removeAllRanges();
s.addRange(r);
// Copy - requires clipboardWrite permission + crbug.com/395376 must be fixed
document.execCommand('copy');

Until the previous bug is fixed, you have to pass the data to the background page and copy the message from there. This solution is not optimal because you're going to insert untrusted HTML in your background page. See https://stackoverflow.com/a/25275151 for examples on how using innerHTML for copying can be abused.

If you understand the risks associated with using innerHTML, and you're accepting its consequences, then you could use the following code to copy rich text:

// content script
var element = document.body; // Example
chrome.runtime.sendMessage({
    html: 'copyhtml',
    text: element.outerHTML
});

background page:

chrome.runtime.onMessage.addListener(function(message) {
    if (message && message.type == 'copyhtml') {
        var wrapper = document.createElement('div');
        // WARNING: Potentially insecure!
        wrapper.innerHTML = message.html;
        document.body.appendChild(wrapper);
        var range = document.createRange();
        r.selectNode(wrapper);
        var s = window.getSelection();
        s.removeAllRanges();
        s.addRange(r);
        // Copy - requires clipboardWrite permission
        document.execCommand('copy');
        wrapper.remove();
    }
});

(if the reader wants to copy text instead of rich text, see Clipboard Copy / Paste on Content script (Chrome Extension))

Rob W
  • 341,306
  • 83
  • 791
  • 678
  • Thanks. That's a good point. Just curious, can we remove all ` – c00000fd Sep 04 '14 at 17:12
  • @c00000fd Inline scripts and external scripts will be blocked by the extension's default [content security policy](https://developer.chrome.com/extensions/contentSecurityPolicy). Iframes won't be rendered, because the HTML is synchronously removed. So, the attacker does not gain any scripting capabilities in the context of the extension. – Rob W Sep 04 '14 at 17:30
  • I'm actually doing it from a popup window script. – c00000fd Sep 04 '14 at 17:41
  • @c00000fd If you're running the code from an extension popup (page action/browser action), then you can simply use the snippet at the top of my answer, because the `clipboardWrite` permission *does* apply to pages that run in the extension's process, such as the extension popup. – Rob W Sep 04 '14 at 17:43
  • You know, speaking of `clipboardWrite` permission. I might be doing something wrong, but that permission doesn't seem to make any difference. I can copy text from a popup window script with or without it. What is the case here? – c00000fd Sep 04 '14 at 17:49
  • 1
    @c00000fd [Historically, extensions could always put data on the clipboard regardless of whether they have the permission](https://chromium.googlesource.com/chromium/src/+/1fd62287247ebcda39054f331fde44da74e8a0c2/chrome/browser/renderer_host/chrome_extension_message_filter.cc#143). That's why an extension can copy data to the clipboard. This "feature" is not documented anywhere besides Chromium's source code, so you should not rely on it and properly declare the `clipboardWrite` permission. – Rob W Sep 04 '14 at 17:54
  • Nice! Reference to the source code. Thanks for your help. – c00000fd Sep 04 '14 at 18:10