1

I am looking for a simple solution to change input field value with context menu trigger.

Let's say changing to bar will be enough, I'll try to add some processing later.

This is how it should work

manifest.json:

{
  "manifest_version": 2,
  "background" : { "scripts": ["background.js"] },
  "permissions": [ "contextMenus", "http://*/*", "https://*/*" ],
  "name": "test plugin",
  "version": "0.1"
}

background.js:

function getClickHandler() {
  //magic here
};

chrome.contextMenus.create({
  "title" : "change to 'bar'",
  "type" : "normal",
  "contexts" : ["editable"],
  "onclick" : getClickHandler()
});
koop
  • 11
  • 2

1 Answers1

4

The basic idea would be

  1. 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
  2. In background page, send a message to content scripts when getClickHandler is triggered
  3. 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.

Haibara Ai
  • 10,703
  • 2
  • 31
  • 47
  • Advanced reading: https://stackoverflow.com/questions/28055887/is-there-a-flexible-way-to-modify-the-contents-of-an-editable-element – Xan Jul 06 '16 at 11:12