Reputation: 561
I've developed a Chrome extension that injects a button into the toolbar of a rich-text editor of a specific web page, code available here. This basic extension is based on the concept of the "content script" and works well because the toolbar is present as soon as the page has loaded.
Now, however, I'm confronted by another page where I cannot simply inject my button as soon as the page loads because the user needs to interact with the page first (make a selection or press a button) before the toolbar appears.
So I'm looking for a way to track any changes in the active tab (I have a URL pattern for the page). I don't want or need a browser action (i.e. the little button on the right-hand side of the omnibox), so I was hoping to get away with a background.js
event page where I can declare an event listener for certain user-originated events but somehow it's not working.
To explain: I've got my manifest.json
, great:
{
"name": "basic tab test",
"description": "blah di blah",
"version": "1.0",
"permissions": [
"activeTab"
],
"background": {
"scripts": ["background.js"], // background script shown below
"persistent": false
},
"content_scripts": [
{
"matches": [
"file://*" // for testing only, of course
],
"js": [
"contentscript.js" // <-- content script shown below
]
}
],
"manifest_version": 2
}
The background.js
script looks like this at the moment:
console.log("in background.js");
chrome.tabs.getCurrent(function(tab) {
tab.onActivated.addListener(function(){
console.log("GOT HERE onActivated (inside tab)");
});
});
chrome.tabs.getCurrent(function(tab) {
tab.onZoomChange.addListener(function(){
console.log("GOT HERE onZoomChange (inside tab)");
});
});
// this is actually part of the message passing test
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
console.log(sender.tab ?
"from a content script:" + sender.tab.url :
"from the extension");
if (request.greeting == "hello")
sendResponse({farewell: "goodbye"});
});
Of course, these are just tests, but none of the above events actually ever fire. Becoming slightly desperate, I then thought 'well, let's use the message passing method' to send messages from the contentscript.js
to the background.js
whenever the user presses a button. The contentscript.js
looks like this:
document.addEventListener("DOMContentLoaded", function(event) {
console.log("just a canary - got here...");
var btn = document.getElementById("button");
if (btn) {
console.log("there is a button!");
} else {
console.log("there is NO button!");
}
btn.addEventListener("click", function () {
console.log("clicked the button!!!!");
chrome.runtime.sendMessage({greeting: "hello"}, function(response) {
console.log(response.farewell);
});
})
});
Also, we never arrive inside this event handler (but why oh why?! this is standard jquery-less code for when the DOM is completely loaded). So, this is when I thought I might ask the assembled experts for advice.
TL;DR: I want to track events on the activeTab and if a given DOM element makes its appearance manipulate it (by injecting an element).
Upvotes: 0
Views: 1153
Reputation: 10897
By default, "run_at"
property for Content Script is "document_idle"
, which means you scripts will be injected after window.onload
event fires, and obviously later than DOMContentLoaded
event. So in fact your code in content script is not executed at all.
To make your code work, either:
Remove the outer DOMContentLoaded
event listener
Or add "run_at": "document_start"
part in your manifest.json
You could take a look at run_at part fore more details.
Upvotes: 1