Firefox WebExtension: Check if MY extension exists
Asked Answered
H

1

3

Porting extension from Chrome into FF

Followed this tutorial (which works fine in Chrome): http://www.codingscripts.com/check-whether-user-has-a-chrome-extension-installed/

Sending message from webpage to extension: In (web)pagescript.js this has:

function IsExist(extensionId,callback){
chrome.runtime.sendMessage(extensionId, { message: "installed" },
function (reply) {
   if (reply) {
      callback(true);
   }else{
      callback(false);
   }
});
}

IsExist("Your extension id",function(installed){
if(!installed){
   alert("Please install extension ");
}
});

Receiving message from webpage in extension:

chrome.runtime.onMessageExternal.addListener(
function(req, sender, callback) {
if (req) {
if (req.message) {
   if (req.message == "installed") {
    callback(true);
   }
 }
}
return true;
});

What I'm trying to achieve

A couple of html pages on my website need to redirect back to the homepage when the extension is NOT installed. So those pages need to be able to figure out (on their own) if the extension is installed or not.

Error I'm getting when I open webpage

ReferenceError : chrome is not defined. (I also tried with browser.runtime.onMessageExternal but then it throws "browser" is not defined). Is there no way to do this similar to what can be done in Chrome ?

Headwork answered 16/6, 2017 at 15:11 Comment(11)
When I change chrome.runtime.onMessageExternal to browser.runtime.onMessageExternal I'm getting the same error but with "browser is not defined" in stead of "chrome is not defined".Headwork
Hmm, do you have "externally_connectable" in manifest? I'm not an expert on FF so all I can say is that it's not listed in supported keys.Intracranial
yes, I've added my domain in "externally_connectable". I've edited my post and added a "what I'm trying to achieve" , to better frame the purpose of my question and why I need browser.runtime.sendMessage in my webpage , and not in the extension content script. (cause I know it works there)Headwork
What Firefox version are you using? It looks like that feature has just been implemented bugzilla.mozilla.org/show_bug.cgi?id=1258360Strainer
Sorry, external messages from web pages are not implemented yet bugzilla.mozilla.org/show_bug.cgi?id=1319168Strainer
@Strainer - how about through Window.postMessage() ? Would that be able to achieve what I'm trying to accomplish as described in my OP ? developer.mozilla.org/en-US/docs/Web/API/Window/postMessageHeadwork
Yes, you would need to inject a content script on your page to receive the message and post another one in reply.Strainer
An alternate, simple, way of implementing this, assuming that you are only checking for the existence of your extension, would be to just have your extension change something in the webpage context prior to your code checking for it. Then, your check can be something like if(typeof myExtensionExists !== 'undefined') {}. This simplifies your logic, removes the asynchronous call and only requires you to add a very simple content script that runs at document_start on the pages in your website.Discounter
@Discounter thanks for putting me on the right track. You meant document_end or document_idle tho , no ? I can't change anything in the DOM on document_start. So I would add a class to <body> with my Extension script (set to run at document_end) and then on in my page js script's window.on load I could sniff if that class exists or not.Headwork
@Wayfarer, If you use document_start, then your extension code is guaranteed to execute prior to your webpage's scripts. At that point the <body> and <head> don't exist (are null). When interacting with the DOM at that time you often will use document.documentElement. My description implied a content script: document.documentElement.appendChild(document.createElement('script')).textContent='var myExtensionExists = true;'; You can wait for the body to exist, if you want (e.g. using a MutationObserver; I've done this in a user script to add a <style> after the <body>).Discounter
Using document_idle or document_end makes it indeterminate (in the general case) as to your webpage scripts or your extension executing first, as those run_at declarations don't have guaranteed times (order wrt. page scripts) that they execute (what happens depends on the content of your webpage). In this case, or at least as general advice, my preference would be document_start, as that guarantees the extension's flag will exist when you check for it in your webpage scritps. Obviously, there are other ways to guarantee this, but that just seams easiest to me.Discounter
H
2

Thanks to all the comments this is what I came up with. (I had to go for document_end (altho comments advise document_start) cause I had other things going on in content_script.js

In my add-on's content_script.js

document.body.classList.add("plugininstalledblabla");

In my add-on's manifest.json

 "content_scripts":
  [
    {
      "matches": ["*://*/*"],
      "all_frames": true,
      "js": ["content_script.js"],
      "run_at": "document_end"
    }
  ]

in my website's main.js script

$(window).on("load", function() { // !! Window onLoad cause : document_end -> DOM should be loaded here

    // Set
    $body = $('body');
    if(document.body.classList.contains("plugininstalledblabla")){
       console.log('addon is installed');
    } 
});
Headwork answered 19/6, 2017 at 13:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.