Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chrome Extension Replace word in current textarea

I'm trying to make a chrome extension that replaces the last word typed in the current <textarea> when the user makes a certain keydown event fire. So I've tried this but it doesn't really work.

Here are the files of my extension:

My extension's manifest.json:

{
  "name": "Test",
  "description": "test",
  "version": "0.0.1",
  "permissions": [
    "activeTab"
  ],
  "background": {
    "scripts": ["background.js"],
    "persistent": false
  },
 "browser_action": {
    "default_title": "replace test"
  },
  "manifest_version": 2
}

Its background.js:

chrome.tabs.executeScript(null, {file: "content_script.js"});

And its content_script.js:

    document.onkeydown = replacePrevWord;  

// Azerty: Ctrl + ² 
// Qwerty: Ctrl + '
function KeyPress(e) {
    var evtobj = window.event? event : e
    if (evtobj.keyCode == 222 && evtobj.ctrlKey)
        return true;
}


function getCaretPosition(ctrl) {
    var CaretPos = 0;   // IE Support
    if (document.selection) {
        ctrl.focus();
        var Sel = document.selection.createRange();
        Sel.moveStart('character', -ctrl.value.length);
        CaretPos = Sel.text.length;
    }
    // Firefox support
    else if (ctrl.selectionStart || ctrl.selectionStart == '0')
        CaretPos = ctrl.selectionStart;
        return (CaretPos);
}


function returnWord(text, caretPos) {
    var index = text.indexOf(caretPos);
    var preText = text.substring(0, caretPos);
    if (preText.indexOf(" ") > 0) {
        var words = preText.split(" ");
        return words[words.length - 1]; //return last word
    }
    else {
        return preText;
    }
}


function replacePrevWord() {
    if(KeyPress()){
        var text = document.activeElement;
        var caretPos = getCaretPosition(text)
        var word = returnWord(text.value, caretPos);
        if (word != null) {
            text.value =  text.value.replace(word,"replaced");
        }
    }
}

This works fine on JSFiddle (http://jsfiddle.net/cyo646cr/3/), but I don't know how to do this in a Chrome extension.

Any ideas?

Thanks.

like image 205
JossVAMOS Avatar asked Sep 29 '22 15:09

JossVAMOS


1 Answers

NOTE: since January 2021, use Manifest V3 with chrome.scripting.executeScript() and the scripting permission and move <all_urls> to host_permissions instead of using the deprecated chrome.tabs.executeScript() with the tabs permission.

Issue

You are not injecting the script correctly. It's easy to say, because calling this simple line

chrome.tabs.executeScript(null, {file: "content_script.js"});

in your background.js will result in injecting the script only one time and in the current tab (because no tabId is specified). Therefore your script will run only once for every session of Google Chrome in the first tab you open.

Take a look at the documentation for chrome.tabs.executeScript.

Work around

To work around this problem you've got two options:

  1. Declare the "content_scripts" field in your manifest.json so it will be injected in any page that matches a pattern.
  2. Add a listener with the chrome.tabs.onUpdated.addListener method and inject the script on the tab.

Option 1

Declare the "content_scripts" field in your manifest.json like this:

...
"content_scripts": [
    {
        "matches": ["<all_urls>"],
        "js": ["content_script.js"],
        "run_at": "document_idle",
        "all_frames": true
    }
],
...

Now your content script will be injected in every page (because "<all_urls>" will match all the pages) and in all the frames of the pages. You can find helpful informations about the "content_scripts" here.

Option 2

Request the permissions for the chrome.tabs API and the URLs you want in your manifest.json:

...
"permissions": [
    "activeTab",
    "tabs",
    "<all_urls>"
]
...

In your background.js, add a listener to chrome.tabs.onUpdated, which will fire on every tab update (i.e. url update), and inject your script using chrome.tabs.executeScript, like this:

chrome.tabs.onUpdated.addListener(function(tabID, info, tab) {
    chrome.tabs.executeScript(tabID, {file: "content_script.js"});
});

See the documentation for chrome.tabs.onUpdated.

like image 111
Marco Bonelli Avatar answered Oct 02 '22 15:10

Marco Bonelli