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.
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.
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
.
To work around this problem you've got two options:
"content_scripts"
field in your manifest.json
so it will be injected in any page that matches a pattern.chrome.tabs.onUpdated.addListener
method and inject the script on the tab.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.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With