Reputation: 1733
I'm porting my Chrome extension to a Firefox WebExtension, so far so good, I manage to communicate smoothly with my content, background scripts and my executable.
I would like now to check the existence of my extension. This is actually the way I do it :
Browser script
// browser-script.js
var isExtensionHere = false;
$("#is-extension-here").click(function(){
console.log("Check the existence of the extension");
window.postMessage({
direction: "from-page-script",
message: "areYouThere"
}, "*");
});
window.addEventListener("message", function(event) {
if (event.source == window &&
event.data.direction &&
event.data.direction == "from-content-script") {
if(event.data.message == "OK") {
isExtensionHere = true;
}
}
});
Content Script
// content-script.js
window.addEventListener("message", function(event) {
if (event.source == window &&
event.data.direction &&
event.data.direction == "from-page-script") {
if(event.data.message == "areYouThere") {
window.postMessage({
direction: "from-content-script",
message: "OK"
}, "*");
}
}
});
It works fine when the extension is here. But when it is not, obviously I don't get an answer from my extension. How can I know then how to trigger a popup or a message when the extension is not here ?
Upvotes: 0
Views: 223
Reputation: 77591
You can reverse the logic: make the page listen for a ping from the extension. You need to be mindful of when scripts execute (e.g. depending on run_at
parameter) in relation to each other, so that you don't accidentally send a message before the page starts listening.
You can use another method of announcing presence to the page: a content script can add an invisible DOM element with a known ID, and you can check for its presence from the page.
If you want to keep the current approach, you can set a timer for the response to happen. Something like, say, 200ms should be more than enough.
You can implement this as a Promise, since it can only be resolved once:
var isExtensionHere = new Promise((resolve, reject) => {
const listener = (event) => {
if (
event.source == window && event.data.direction
&& event.data.direction == "from-content-script"
&& event.data.message == "OK"
) {
resolve(true);
}
}
setTimeout(() => {
window.removeEventListener("message", listener);
resolve(false); // Will have no effect if already called with true
}, 200);
window.addEventListener("message", listener);
window.postMessage({
direction: "from-page-script",
message: "areYouThere"
}, "*");
});
// Sometime later
isExtensionHere.then((result) => { /* ... */ });
If you want to dynamically re-check, make isExtensionHere
a function that returns a new Promise every time.
Upvotes: 1