I'm new to writing extensions for Google Chrome. I want to make an extension that only runs on a few pages (that I'll choose) and re-renders their CSS after the page has loaded (ideally I would like something similar to what you can do with GM_addStyle in greasemonkey scripts).
How can I accomplish this in a Chrome extension?
You can use Content scripts that have access to the pages DOM.
In your manifest.json you could have:
"content_scripts": [
{
"matches": ["http://www.google.com/*"],
"css": ["mystyles.css"],
"run_at": "document_end"
}
],
This will inject the css file mystyles in to any google page after the DOM has loaded. This doesn't completely overwrite the styles, but you will be able craft your CSS so it replaces their styles.
More information can be found on code.google.com. It also includes information about how to programmatically inject CSS into a page.
Related
I am making a chrome extension that inserts multiple css and javascript files.
I was previously using content scripts but now I want to insert the script and css onClick.
I tried just injecting my main script script.js in my background and keeping the rest of my css files associated with this script in my content script section in manifest. However, when I tried this in my extension it did not work. Should I execute and insert all my content and css in my background and if so in what order because one script or css has to be inserted or executed inside another.
I looked at " Injecting multiple scripts through executeScript in Google Chrome" however I don't know if their is a easier way in my situation and I do not know if that articles applies to css.
Here's part of my manifest:
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"css": ["styles.css", "tipped.css"],
"js": ["jquery-1.9.1.js", "jquery-highlight1.js", "spinners.min.js", "tipped.js","script.js"],
"run_at": "document_end"
}
],
"permissions":[
"activeTab"
],
Here is my background script:
chrome.browserAction.onClicked.addListener(function(activeTab) {
chrome.tabs.executeScript(null, {file: "script.js"});
});
I am trying to inject a div into the body of webpages, it works perfectly on all pages that I have tried, except certain sites, namely bbc.co.uk, nytimes.com and stackoverflow.com. I suspect its because the body hasn't loaded but that doesn't really make sense as I am doing it in $(document).ready().
$(document).ready(function() {
$('body').prepend('<div id="tilda"></div>');
});
As I say this works fine as a Chrome extension injecting into most pages, just some that seem to be immune?
EDIT DUE TO COMMENT:
My inject.js file looks like:
$(document).ready(function() {
$('body').prepend('<div id="tilda"></div>');
console.log($('body'))
});
I am including the js files like so:
"content_scripts": [
{
"matches": ["https://*/*"],
"js": ["js/jquery-1.9.1.min.js", "src/inject/inject.js"]
}
]
Some websites somehow block that injection into the dom from an extension. Very confused how!
My extension reformats an ugly page that I visit often. Currently, the page first loads un-fixed, then there is a ~100ms delay, then my JS formats the html.
How do I prevent the uncorrected html from ever displaying?
My JS file is defined in the manifest as follows:
,"content_scripts": [{
"matches": ["*://*.<url goes here>.com/*"],
"js": ["js/1.js"]
}]
You need to adjust the run_at parameter.
By default, content scripts are executed after the page is fully loaded (at "document_idle").
Try adding "document_end" first and see if it improves the delay.
In the case of "document_end", the files are injected immediately after the DOM is complete, but before subresources like images and frames have loaded.
"content_scripts": [{
"matches": ["*://*.example.com/*"],
"js": ["js/1.js"],
"run_at": "document_end"
}]
This may still be too late. There's a final option, "document_start", that you can use, but beware - it executes really early, before any of the DOM is ready. There's nothing yet for you to correct.
You can wait for an element to appear and correct it immediately though, for instance.
You may also try to correct things with CSS injection. This can be safely inserted at "document_start" with no extra tricks.
P.S. Or, for example, use Gael's answer - add a CSS rule to hide the body, wait until the page is loaded (for instance, with DOMContentLoaded event), correcting it and then removing/overriding the CSS rule.
You can set run_at: "document_start" in your manifest. Add a rule to hide the page, and differ your current script in a window.onload event.
If you are visiting often this page, you could even load first your template/redesign, and then integrate the page data that you want from a cache or from the source.
I need to be able to inject a content script into an iframe that is within an action's popup.html of another extension.
Previously, before an update to this extension in question, the extension injected the iframe into the active tab. I was able to configure my manifest like this:
"content_scripts": [{
"matches": ["https://*.domain.com/*"],
"js": ["content.js"],
"all_frames": true
}],
It worked fine, the content script was injected into the iframe. Now this extension has the iframe in the action's popup.html and I can't get this to work.
Is there any way to accomplish this?
In general, you can't do this because chrome-extension: is not/no-longer a valid scheme.
However, if you can target the popup.html without using wildcards, you might be able to get to work by setting a "bad flag" in the Chrome://flags page.
Obviously, this will only work for your own personal browser.
I'm trying to write a Chrome Extension that just adds a CSS file to the end of a page's css definitions.
Google's documentation says that I can just use the function chrome.tabs.insertCSS() to add css to a page, but running it from a content_script included javascript file does nothing.
I'm trying two separate methods as documented on Google's site. I have an alert() statement to tell me where in the script I am, but it never runs the final alert. This makes me think that my script may be crashing somewhere in the middle.
Here are my source files:
manifest.json
{
"name": "Custom CSS to GOOGLE",
"version": "1.0",
"description": "The first extension that I made.",
"content_scripts": [
{
"matches": ["http://*/*"],
//"js": ["style_injector.js"],
"js": ["inject.js"],
"css": ["newstyle.css"]
}
],
"permissions": [
"tabs", "http://*/*"
]
}
inject.css
alert("newpage");
chrome.tabs.executeScript(null, {code:"document.body.bgColor='red'"});
chrome.tabs.insertCSS(
null,
{
code:"body{background:red;}"
}
);
alert("finishpage");
You can't call chrome.tabs.* API from a content script. You need to do it from a background page. If you need to communicate between a content script and a background page there is message passing available.
PS. Things like "This makes me think that my script may be crashing somewhere in the middle." could be easily checked by looking at the console (for content scripts it is just a regular console in a tab, Ctrl+J).
"I'm trying to write a Chrome Extension that just adds a CSS file to the end of a page's css definitions"
You might need to add the !important flag to the css you are changing:
When the browser is displaying an HTTP page and the user clicks this extension's browser action, the extension sets the page's bgcolor property to 'red'. The result, unless the page has CSS that sets the background color, is that the page turns red.
...the !important flag is the only way to change some things but you may have to write js to override other styles, check this
As serg said, the background.html page is where you use the injectCSS api:
/* in background.html */
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(null,
{code:"document.body.bgColor='red'"});
});
/*in manifest.json */
"permissions": [
"tabs", "http://\*/*"
],