How to check if Chrome extension has fully installed - javascript

Using Chrome Web Store inline installation ( https://developers.google.com/chrome/web-store/docs/inline_installation ) it is possible to specify a callback for chrome.webstore.install() that will be executed when the extension is successfully installed.
Through some very tedious debugging I've learned that extensions are not neccessarily 100% installed when the callback is executed - maybe the background hasn't been loaded or content scripts aren't yet available.
In my particular case the problem presents itself in this way:
User clicks install button with chrome.webstore.install() bound to onclick event.
Success callback injects an iFrame.
Content script is defined for the iFrame and injected to do some finishing work
Content script returns with a completed installation dialog.
Step 3 is the problem. Some times the iFrame will be injected before content script is fully loaded and thus no script will be injected (content scripts are only injected inside newly created iFrames, not iFrames already existing when the extension is installed/enabled).
I know there are possible workarounds such as having the extension itself inject the iFrame or a simple setTimeout(), but for the sake of helping others I think it's worth asking the question:
How can I be certain that the extension is 100% installed, when the chrome.webstore.install() callback doesn't ensure it?
Using the famous <img> load method described in Checking if user has a certain extension installed doesn't work reliably (for those thinking that'd be a solution).

This is the way to do it :
http://code.google.com/chrome/extensions/extension.html#global-events
As mentioned in the last link below , you should be able to do :
var myPort=chrome.extension.connect('yourextensionid_qwerqweroijwefoijwef', some_object_to_send_on_connect);
You can also check Checking if an item is already installed section in the next link :
https://developers.google.com/chrome/web-store/docs/inline_installation
or you can follow what have been done in this post:
Check whether user has a Chrome extension installed
I also saw solutions talking about background page and localstorage:
http://developer.chrome.com/extensions/background_pages.html
Chrome extension post-install hook/API function: does it exist?

You sure your content script's work needs to be done from the same page where the user installed the extension? If not, simply have your extension call chrome.tabs.update or chrome.tabs.create (two of the few tabs methods that don't require the tabs permission) to open a page where your content script can be injected.
Otherwise, your extension can use programmatic injection to inject a content script which can communicate with your page. You can use chrome.tabs.query to make sure you're injecting into the correct tab.

Related

Check if user has a third party Chrome extension installed

I am currently trying to detect if a user has a certain Chrome extension installed. The Chrome extension is not my own and I do not have the source code to it. I have tried methods in numerous posts but they all fail. What I've tried and why it failed is detailed below.
This results in 'cannot read property connect of undefined' when executed:
var myPort=chrome.extension.connect('idldbjenlmipmpigmfamdlfifkkeaplc', some_object_to_send_on_connect);
Trying to load a resource of the extension as follows to test if it's there but going to this URL in browser results in 'your file was not found' Chrome error page (note that I found this path by going to C:\Users\\AppData\Local\Google\Chrome\User Data\Default\Extensions\idldbjenlmipmpigmfamdlfifkkeaplc\1.0.0.1_0\ on my Windows local machine):
chrome-extension://idldbjenlmipmpigmfamdlfifkkeaplc/1.0.0.1_0/icon_16.png
Using Chrome management but this results in console error 'cannot read property get of undefined' when executed
chrome.management.get("idldbjenlmipmpigmfamdlfifkkeaplc", function(a){console.log(a);});
And most other answers I've come across seem to involve the extension being written by the same person who is trying to check for it.
Assuming you need it from a website
connect/message method implies that the extension specifically listed your website in the list of origins it expects connection from. This is unlikely unless you wrote this extension yourself, as this cannot be a wildcard domain.
Referring to files within the extension from web context will return 404 simulate a network error unless the extension declared them as web-accessible. This used to work before 2012, but Google closed that as a fingerprinting method - now extensions have to explicitly list resources that can be accessed. The extension you specifically mention doesn't list any files as web-accessible, so this route is closed as well.
chrome.management is an extension API; websites cannot use it at all.
Lastly, if an extension has a content script that somehow modifies the DOM of your webpage, you may detect those changes. But it's not very reliable, as content scripts can change their logic. Again, in your specific case the extension listens to a DOM event, but does not anyhow make clear the event is received - so this route is closed.
Note that, in general, you cannot determine that content script code runs alongside yours, as it runs in an isolated context.
All in all, there is no magic solution to that problem. The extension has to cooperate to be discoverable, and you cannot bypass that.
Assuming you need it from another extension
Origins whitelisted for connect/message method default to all extensions; however, for this to work the target extension needs to listen to onConnectExternal or onMessageExternal event, which is not common.
Web-accessible resources have the same restrictions for access from other extensions, so the situation is not better.
Observing a page for changes with your own content script is possible, but again there may be no observable ones and you cannot rely on those changes being always the same.
Similar to extension-webpage interaction, content scripts from different extensions run in isolated context, so it's not possible to directly "catch"code being run.
chrome.management API from an extension is the only surefire way to detect a 3rd party extension being installed, but note that it requires "management" permission with its scary warnings.

Open chrome extension in html

I used this code to open chrome extension but not opened
<li class="bms-item">bms</li>
Web context cannot open chrome-extension:// or chrome:// links due to security restrictions. The idea is that simply opening the page may perform some action with higher privileges than the webpage.
As mentioned by wOxxOm in comments, you should use externally_connectable (assuming you control both the extension and the webpage). There's a handy guide in the documentation, but the schema is as follows:
You declare in your extension's manifest that your domain, https://example.com/, can call the extension.
From your webpage code, you check that chrome.runtime.sendMessage is available - that means an extension that is ready to listen is installed.
You then call chrome.runtime.sendMessage with the extension ID and the request to do something (i.e. open an extension page).
In the extension's background page, receive the message with chrome.runtime.onMessageExternal and do something, e.g. open the page with chrome.tabs API.
If you control the extension, but not the website, and you're adding the button from a content script, you should assign a handler that calls chrome.runtime.sendMessage and, again, handle it from the background page (which can open an extension page, unlike the content script). This time though it's going to be chrome.runtime.onMessage event.
Alternatively, declaring the page as web-accessible should help (untested).
If you don't control the extension, there's nothing you can do for the security reason above.

Firefox Add-on SDK reload extension only upon restart

I'm currently having an issue with an extension I'm developing using the Firefox Add-on SDK. For some basic context, the extension executes content scripts using the page-mod api in the sdk. On each of the content scripts some additional javascript is injected into the page itself (we'll call them page scripts). In order to do some complex tasks, the javascript injected into the page can communicate with the content script and which will then in turn make requests to the background process of the extension. Due to the complexity of the extension, when it is auto-updated, it is possible to get into a state where multiple page-scripts running the same code are running on the given content-script.
What I'm wondering is if it's possible for extensions built using the Add-on SDK can be forced to update itself only upon restart. This would mean that the extension won't get reloaded even if the auto-update occurs until a user restarts their Firefox Browser.
If this is not possible, any other solutions would be great.
Though I agree with #Noitidart's comment, you can choose to inject your content scripts from main.js only on restart like so:
const { loadReason } = require('sdk/self');
if (loadReason==='startup') {
//Inject the scripts
}
You'll have to make sure that your old version's content scripts can communicate with the new background scripts without breaking, which will be a pain to test. See here for the other load reasons.

Disable chrome extension conflicting with my site

I work on a web site, using jQuery-1.8 , and found out, a certain extension ( on the CEO-s laptop ) is using jQuery-1.7 as a content script. This content script overwrites my script. Is there a way I can block at least some certain extensions from loading on the chrome tab my web app is using? A meta tag maybe?
No. Unless the said extension is cooperative (that is it looks for the meta tag, or a specific URL, to disconnect itself), you have no way of disabling it.
You might find a way dependent on the extension but you'd need the extension's code to look for it.
In your specific case the problem seems to be that jQuery is overwritten. Can't you simply wrap your code in order to use the specific jQuery you need ?
(function($) {
// here $ is protected :
// it has the value it had when the page was loaded
})($);
This behavior by an extension is not really acceptable, you should contact the extension developers to get it fixed. If they can't be reached, then you should request removal from the Chrome Web Store.

How to change content after page is loaded (JS)?

I would like a javascript to run after a page is loaded , like on the example below with a delay of 6seconds. Right after the page loads the rest of JS is lost (obvious)...
Got any ideea how change content after page is loaded without clicking a button?
javascript:window.location = "http://example.com";
setTimeout(function() {
document.getElementById('lightbox').style.display = 'none';
}, 6000);
Once you set window.location the original page will be unloaded before the new page is loaded by the browser. This means your script will be gone before the new page start loading and thus can't modify the new HTML anymore.
This behavior is inherent to the security model of the browser. Without it you could inject any JavaScript into any web site of your choosing, which would be a huge security risk. What you are asking for is so-called XSS (for cross site scripting), which is prevented by the browser applying a so-called SOP (for same-original policy).
There are some common ways to work around this limitation in a safe way:
Set up a proxy to serve both your JavaScript and the original site. This way both your script and the original site come from the same domain and satisfy the browser's same-original policy (SOP). You could run the original site in an iframe with your custom script occupying the top-level window. Alternatively you could inject your script into the HTML as it is being retrieved through your proxy.
Run your script as a browser add-on or user-script. If you choose to do this, the user will have to specifically grant your script the rights to run locally with elevated rights. Greasemonkey popularized client-side scripts for Firefox a few years ago, but recently they seem to have lost momentum.
Ask the site owner to include your script. I doubt this is a valid option for your situation. But if it is a valid option it is definitely the simplest one.
Ask the user to run your script after the site has loaded. This one is probably also not valid for you, but if valid it would once again be a very simple solution.
Your example shows that you are first redirecting and then attempting to hide #lightbox. This script would not work, because you are redirecting the browser to another site before #lightbox gets hidden.
In short, you cannot have Javascript of a previous page manipulate DOM of the next page if you redirect the user to another URL (or even the same URL). Only Javascript that is 'on currently open page' can manipulate currently open page and no other pages.
I have not understood what you are saying. JS is lost? Please be more clear.
I think what you are talking about is the jquery ready function which runs after the DOM is ready. Or in the other case, try using window.onload() function.
This should do the job:
$(window).bind('load', function() {
// your code here
});
Then simply add the delay to your added code with .delay("6000");
The inserted code will only run when your page is completely loaded.

Categories

Resources