Accessing Operating System Clipboard in Chromium (Chrome) Extensions

Earlier this year, Webkit disabled clipboard access of web pages by default for security reasons (see this changelog and this bug report). Programming-wise, this means good old document.execCommand(‘Copy’) and document.execCommand(‘Paste’) will always return false. This is indeed quite understandable, and very useful for protecting the average surfer’s privacy.

Unfortunately, when this change was carried over into Webkit-based Chromium and Chrome browsers, quite many extension developers’ got annoyed because their extensions suddenly stopped working as a result of the new restriction. Chromium and Chrome extensions run locally and usually require explicit permissions from users to access remote sites. It is generally safe to allow extensions to access the OS clipboard, which is used by many extensions to do various tricks. With the new change in the underlying Webkit code, they were no longer able to do so.

Chromium developers soon came to notice this issue and implemented a fix. But it was a partial fix: only background.html and popup.html are allowed clipboard access, content scripts as well as other pages including options page are still not permitted to access system clipboard. The devs also quickly realized the problem, but sinceĀ  fixing the problem was non-trivial and Chromium-native clipboard API was already experimental anyway, they decided not to do anything about it (see this issue).

For the time being, extensions requiring access to OS clipboard will have to resort to the following workaround, as suggested by Chromium devs:

In background.html, insert a placeholder for the copy/paste content. For example:

<textarea id="clipboardholder" style="display:none;"></textarea>

In content scripts or wherever required, manipulate the content and visibility of the background page placeholder and call execCommand on the background page to copy/paste. For example:

bg = chrome.extension.getBackgroundPage();

clipboardholder= bg.document.getElementById("clipboardholder");

clipboardholder.style.display = "block";

clipboardholder.value = "content to be copied into OS clipboard";

clipboardholder.select();

bg.document.execCommand("Copy");

clipboardholder.style.display = "none";

alert("Content copied to clipboard!");

This does not look very pretty or elegant. However, this workaround is necessary before Chromium-native clipboard API becomes non-experimental. Even after that, this will have to be used conditionally to maintain backward compatibility.

This entry was posted in Chromium extension and tagged , , , , , . Bookmark the permalink.