Chrome content script not executing on Ember site - javascript

I've got a Google Chrome extension which has the following content script syntax in it's manifest.json:
"content_scripts": [
{
"matches": [
"https://example.com/*"
],
"js": ["js/jquery-2.1.1.js", "js/custom.js"],
"run_at": "document_end",
"all_frames": true
}
],
When testing this extension on an Ember site, it runs on initial page load but after changing the page, it does not get injected again.
For non-Ember users, Ember can update the URL and page content without performing an entire page reload which appears to be causing this issue.
Is anyone aware of a work-around for examples like this?

This was fixed by using chrome.WebNavigation.onHistoryStateChanged which fires every time the page updates.

Related

Loading libraries for use in a content script

I created a Firefox extension that works, for the most part. I am having a hard time importing jQuery. I have downloaded it locally. I am getting no errors. So, sometimes the extension will work and jQuery will load. Sometimes it won't. Other times I have to reload the page 5 or 6 times to get it to work.
I am not a JavaScript developer and this is my first time attempting an extension. I have Googled and tried a bunch of things with no luck.
Below is my manifest.json
"web_accessible_resources" : ["/jquery-3.2.1.min.js","/jquery.csv.min.js","/ui.js"],
"icons": {
"128": "icon_128px.png",
"48": "icon_48px.png"
},
"browser_action": {
"default_icon": "icon_48px.png"
},
"content_scripts": [
{
"matches": ["https://*****.com/*"],
"js": ["content.js"],
"run_at": "document_end"
}
],
"permissions":[
"activeTab"
],
"homepage_url": "https://*****.com"
}
content.js
function injectJs(link) {
var scr = document.createElement("script");
scr.type="text/javascript";
scr.src=link;
(document.head || document.body || document.documentElement).appendChild(scr);
}
injectJs(chrome.extension.getURL("/jquery-3.2.1.min.js"));
injectJs(chrome.extension.getURL("/jquery.csv.min.js"));
injectJs(chrome.extension.getURL("/ui.js"));
Normally, you would load jQuery by including it within the js key in your manifest.json content_scripts entry. For example:
"content_scripts": [
{
"matches": ["https://example.com/*"],
"js": ["jquery-3.2.1.min.js", "jquery.csv.min.js", "ui.js", "content.js"]
}
]
Scripts are loaded in the order listed. So, you need to list the libraries which depend on others after the ones they depend upon (e.g. "jquery-3.2.1.min.js" before "jquery.csv.min.js").
What you were doing
The way that you were doing it inserted the scripts into the page context using <script> tags. Such tags are loaded asynchronously. Thus, there was no guarantee that your scripts which depended on jQuery were actually loaded after jQuery. For what you are doing, you don't want to be loading the scripts into the page context, which is separate from the content script context where your content scripts normally run. If you want more information as to how you can do that successfully, you can see my answer to How to sequentially insert scripts into the page context using tags, which has fully functional code to insert multiple dependent libraries into the page context.
Use .tabs.executeScript() to dynamically load scripts when they are not used 100% of the time
However, if you are loading your content script into a large number of pages (e.g. matches being "<all_urls>", *://*/*, etc.), then you should use a manifest.json content_scripts entry to load only the bare minimum needed to show the initial portion of your user interface (i.e. just the static portion seen prior to the user interacting). Only once the user begins interacting with your user interface should you then send a message, using .runtime.sendMessage(), to your background script, received using .runtime.onMessage(), to instruct your background script to inject the rest of the files needed for your complete user interface. You background script would then use .tabs.executeScript() to load the additional scripts you need and, perhaps, tabs.insertCSS() to inject any additional CSS which you may need.
The point of doing the above is to minimize the impact your extension has on the user/browser during the time which the user is not actively using your extension, which is most of the time under most conditions.

Can I determine when to install webextensions firefox addon to a page?

I wrote a firefox addon use webextensions tech. By default firefox load the addon when the page loaded over. But some pages hava slowly loaded js,like some ads or statistics code, so the addon will not load if I stop the unnecessary page load. Or wait a long time before the addon loaded.
So can I setup the addon loaded time? (example: Before the page loaded)
Check out the run_at option in the content_scripts' manifest options. For example, you may use the following options:
content_scripts": [
{
"js": ["my-script.js"],
"matches": ["https://example.org/"],
"match_about_blank": true,
"run_at": "document_start"
}
]

Chrome extension - loading file from localhost to content_scripts

I'm developing Chrome Extension and I need to load a javascript file to content scripts, but that file is being served via webpack-dev-server. So it's approachable only on localhost.
I tried to change my manifest.json:
"content_scripts": [
{
"matches": [
"http://*/*",
"https://*/*"
],
"js": [
"http://localhost:3000/scripts/content_bundle.js"
],
"run_at": "document_end",
"all_frames": false
}
But then I got an error in Chrome Extensions window:
Only local files can be specified in "content_scripts" section.
Solution:
add "permissions": ["http://localhost:3000/scripts/*", "tabs"] to manifest.json
download the script using XMLHttpRequest (there are many examples) in your background script (or better an event page script) when needed
save it in chrome.storage.local or localStorage (so you can load it on every extension start from the storage without redownloading)
inject the script:
add a tabs.onUpdated listener and inject the script using tabs.executeScript
alternatively use declarativeContent API with RequestContentScript action (despite the warning on the doc page it should be actually supported in the Stable channel but of course do some tests first).

How to redirect to an extension page in chrome?

In my web application i want to put a code that upon that execution it should redirect the current tab to some extension page?
If i do
window.location = 'chrome-extension://idgpnmonknjnojddfkpgkljpfnnfcklj';
it redirects me to 'about://blank' not on that particular extension page.
Can some one help me out how to achieve the same.
First of all you need to put all the resources of your chrome extension to the web_accessible_resources.
You also need to trigger redirect behavior. You can do it with content_scripts and you will need permissions for the specific domain.
Eventually you will have mainfest.json like:
"permissions": [
"*://example.com/*"
],
"content_scripts": [{
"js": ["injection.js"],
"matches": ["*://www.example.com/*", "*://example.com/*"]
}],
"web_accessible_resources" : [
"index.html",
"main.js",
"favicon.ico"
],
And injection.js like:
location = 'chrome-extension://'+chrome.runtime.id+'/index.html';

Why content.js load twice or more when in facebook.com with chrome extension?

I have a chrome extension.
The manifest.json is
"content_scripts": [
{
"all_frames": true,
"js": [ "content.js" ],
"css": ["style.css"],
"matches": [ "*://www.facebook.com/*"],
"run_at": "document_start"
},
The content.js just is
console.log("say hi");
And console is
Please see this picture http://i.imgur.com/SuBnbnT.png
It called four times. It just happened in facebook.com, not happened in other website such as www.google.com. Any idea? Thanks.
I'm not sure if Facebook uses frames, but if it does it is possible that there are four frames that are executing your code once each. Chrome console doesn't give any visual indication that this is what is happening. Try setting all_frames to false so that it only executes on the top frame.
You've specified all_frames: true. There's likely a few iframes on the page causing content.js to be executed multiple times.

Categories

Resources