The basic idea would be
Listen to contextmenu
event in content scripts and record e.target
(This is needed because we don't know the actual DOM node for chrome context menu api, see Issue 39507) We could directly use document.activeElement
, since input elements get focused upon click
- In background page, send a message to content scripts when
getClickHandler
is triggered
- In content scripts, replace target.value with
"bar"
Sample code:
manifest.json
{
"manifest_version": 2,
"background" : { "scripts": ["background.js"] },
"permissions": [ "contextMenus", "http://*/*", "https://*/*" ],
"name": "test plugin",
"version": "0.1",
"content_scripts": [
{
"matches": [
"*://*/*"
],
"js": [
"content.js"
],
"all_frames": true
}
]
}
content.js
chrome.runtime.onMessage.addListener(function (request) {
replaceSelectedText(document.activeElement, request.text);
});
function replaceSelectedText(elem, text) {
var start = elem.selectionStart;
var end = elem.selectionEnd;
elem.value = elem.value.slice(0, start) + text + elem.value.substr(end);
elem.selectionStart = start + text.length;
elem.selectionEnd = elem.selectionStart;
}
background.js
function getClickHandler(info, tab) {
chrome.tabs.sendMessage(tab.id, {text: "bar"});
};
chrome.contextMenus.create({
"title" : "change to 'bar'",
"type" : "normal",
"contexts" : ["editable"],
"onclick" : getClickHandler
});
Updated
As @Xan has mentioned in the comments, if you just want to update <input>
field, then using input.value = xxx
is ok; however if you would like to manipulate arbitrary editable element, see Is there a flexible way to modify the contents of an editable element? for more ideas.