Created
July 27, 2014 18:00
-
-
Save srsudar/e9a41228f06f32f272a2 to your computer and use it in GitHub Desktop.
Pasting from the system clipboard using a Chrome extension.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<script src="background.js"></script> | |
</head> | |
<body> | |
<textarea id="sandbox"></textarea> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'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: | |
// http://stackoverflow.com/questions/7144702/the-proper-use-of-execcommandpaste-in-a-chrome-extension | |
/** | |
* Retrieve the current content of the system clipboard. | |
*/ | |
function getContentFromClipboard() { | |
var result = ''; | |
var sandbox = document.getElementById('sandbox'); | |
sandbox.value = ''; | |
sandbox.select(); | |
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: | |
// https://developer.chrome.com/extensions/messaging | |
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'); | |
sendPasteToContentScript(clipboardContent); | |
} | |
} | |
// Register the click handler for our context menu. | |
chrome.contextMenus.onClicked.addListener(onClickHandler); | |
// Set up the single one item "paste" | |
chrome.runtime.onInstalled.addListener(function(details) { | |
chrome.contextMenus.create( | |
{ | |
'title': 'Paste Demo', | |
'id': 'pasteDemo', | |
'contexts': ['editable'] | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'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: | |
* http://stackoverflow.com/questions/7404366/how-do-i-insert-some-text-where-the-cursor-is | |
*/ | |
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) { | |
el.focus(); | |
range = doc.selection.createRange(); | |
range.collapse(false); | |
range.text = text; | |
range.select(); | |
} | |
} | |
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { | |
if (request.data) { | |
insertTextAtCursor(request.data); | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "Paste Demo", | |
"version": "0.0.1", | |
"manifest_version": 2, | |
"description": "Demonstration of how to paste in a Chrome extension", | |
"permissions": [ | |
"clipboardRead", | |
"contextMenus" | |
], | |
"background": { | |
"persistent": false, | |
"page": "background.html" | |
}, | |
"content_scripts": [ | |
{ | |
"matches": [ | |
"http://*/*", | |
"https://*/*" | |
], | |
"js": [ | |
"contentscript.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