Question

I am asking this question after looking at several related questions on stackoverflow. I started with how to detect if an extension is installed. I opted for the method where I add a div to body using content scripts on some pages. Here is how I did it...

manifest.json

{
    "name": "Install Check",
    "content_scripts": [
        {
            "matches": ["http://host.com/*"],
            "js" : ["insert_node.js"]
        }
    ],
    "permissions": [
        "tabs", "host.com/*"
    ]
}

insert_node.js (content script)

var insert_node = document.createElement('div');
insert_node.id = "HOST_SITE";
document.body.appendChild(insert_node);

host page

<html>
<head>
</head>
<body>
    <h1>This is a host site. Welcome!!!</h1>
    <script src="jquery.js"></script>
    <script src="notification.js"></script>
</body>
</html>

extension install script

$(document).ready(function() {
    if ($('#HOST_SITE').length > 0) {
        alert("you have our extension installed");
    } else {
        alert("not installed");
    }
});

My problem is that the alert with message not_installed always pops up before the chrome can inject the node in DOM. I read about run_at attribute in manifest.json over here. But that didn't solve the problem either. I tried all the three document_start, document_idle, document_end values. What am I doing wrong over here?

Was it helpful?

Solution

It looks like your own the extension and website, in which case it would be much easier to use Inline Installation.

if (typeof chrome !== "undefined" && typeof chrome.app !== "undefined" && chrome.app.isInstalled) {
  // extension is installed.
}

OTHER TIPS

Im not sure how to do this with JQuery as $("#something") only seems to search the head and body?...and we need document.documentElement. Reason being that we are inserting something at document_start and there's no body/head then, but there is documentElement.

manifest.json

{
    "name": "Install Check",
    "content_scripts": [
        {
            "matches": ["HOST"],
            "js" : ["myscript.js"],
            "run_at":"document_start"
        }
    ],
    "permissions": [
        "tabs", "HOST"
    ],
    "version":"1.0"
}

myscript.js

var insert_node = document.createElement('div');
insert_node.id = "HOST_SITE";
document.documentElement.appendChild(insert_node);

notification.js

if (document.documentElement.querySelector("#HOST_SITE")) {
    alert("Installed");
} else {
    alert("Not Installed");
};

I got this working...

  • Make the extension insert content script after DOM loads but before other resources like images are loaded

manifest.json (added "run_at": "document_end")

{
    "name": "Install Check",
    "content_scripts": [
        {
            "matches": ["http://host.com/*"],
            "js" : ["insert_node.js"],
            "run_at": "document_end"
        }
    ],
    "permissions": [
        "tabs", "host.com/*"
    ]
}
  • use window.onload instead of $(document).ready

insert_node.js (changed the $(document).ready to window.onload)

window.onload = function() {
    if ($('#HOST_SITE').length > 0) {
        alert("you have our extension installed");
    } else {
        alert("not installed");
    }
};

However, I don't completely understand why using window.onload works and $(document).ready does not.

May be someone can shed some light on that?

Also I agree with @abraham that using chrome.app.isInstalled is a better way to do this (answer to my comment would be the icing on cake) :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top