Skip to content

Instantly share code, notes, and snippets.

Created July 27, 2014 18:00
Show Gist options
  • Save srsudar/e9a41228f06f32f272a2 to your computer and use it in GitHub Desktop.
Save srsudar/e9a41228f06f32f272a2 to your computer and use it in GitHub Desktop.
Pasting from the system clipboard using a Chrome extension.
<!DOCTYPE html>
<script src="background.js"></script>
<textarea id="sandbox"></textarea>
'use strict';
// A gotcha of sorts with chrome extensions involving clipboard actions is that
// only the content scripts can interact with the page that a user loads. This
// means that we can't put our calls to actually paste into the page in the
// background file, because the background scripts are not able to paste into
// the dom of the page. However, only background pages are able to access the
// system clipboard. Therefore we have to do a little trickery to move between
// the two. We're going to define the functions here to actually read from the
// clipboard into a textarea we've defined in our background html, and then
// we'll get that pasted data from the background page and do the actual
// insertion in our content script. The idea of this comes from:
* Retrieve the current content of the system clipboard.
function getContentFromClipboard() {
var result = '';
var sandbox = document.getElementById('sandbox');
sandbox.value = '';;
if (document.execCommand('paste')) {
result = sandbox.value;
console.log('got value from sandbox: ' + result);
sandbox.value = '';
return result;
* Send the value that should be pasted to the content script.
function sendPasteToContentScript(toBePasted) {
// We first need to find the active tab and window and then send the data
// along. This is based on:
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {data: toBePasted});
* The function that will handle our context menu clicks.
function onClickHandler(info, tab) {
var clipboardContent = getContentFromClipboard();
console.log('clipboardContent: ' + clipboardContent);
if (info.menuItemId === 'pasteDemo') {
console.log('clicked paste demo');
// Register the click handler for our context menu.
// Set up the single one item "paste"
chrome.runtime.onInstalled.addListener(function(details) {
'title': 'Paste Demo',
'id': 'pasteDemo',
'contexts': ['editable']
'use strict';
* Insert the text at the cursor into the active element. Note that we're
* intentionally not appending or simply replacing the value of the editable
* field, as we want to allow normal pasting conventions. If you paste at the
* beginning, you shouldn't see all your text be replaced.
* Taken from:
function insertTextAtCursor(text) {
var el = document.activeElement;
var val = el.value;
var endIndex;
var range;
var doc = el.ownerDocument;
if (typeof el.selectionStart === 'number' &&
typeof el.selectionEnd === 'number') {
endIndex = el.selectionEnd;
el.value = val.slice(0, endIndex) + text + val.slice(endIndex);
el.selectionStart = el.selectionEnd = endIndex + text.length;
} else if (doc.selection !== 'undefined' && doc.selection.createRange) {
range = doc.selection.createRange();
range.text = text;;
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if ( {
"name": "Paste Demo",
"version": "0.0.1",
"manifest_version": 2,
"description": "Demonstration of how to paste in a Chrome extension",
"permissions": [
"background": {
"persistent": false,
"page": "background.html"
"content_scripts": [
"matches": [
"js": [
"run_at": "document_end",
"all_frames": false
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment