Reading Documents CSS in Chrome Extension

Reading documents CSS in Chrome Extension

Well thats the Why, but for fun and interest (never done anything with style sheets before) I thought Id do a How....

manifest.json

{
"name": "Get all css rules in stylesheets",
"content_scripts": [
{
"matches": ["<all_urls>"],
"js" : ["myscript.js"],
"run_at":"document_end"
}
],
"permissions": [
"tabs", "<all_urls>"
],
"version":"1.0"
}

myscript.js

// Create the div we use for communication
var comDiv = document.createElement('div');
comDiv.setAttribute("id", "myCustomEventDiv");
document.body.appendChild(comDiv);

// Utitlity function to insert some js into the page, execute it and then remove it
function exec(fn) {
var script = document.createElement('script');
script.setAttribute("type", "application/javascript");
script.textContent = '(' + fn + ')();';
document.body.appendChild(script); // run the script
document.body.removeChild(script); // clean up
}

// function that gets inserted into the page
// iterates through all style sheets and collects their rules
// then sticks them in the comDiv and dispatchs the event that the content script listens for
getCSS=function (){
var rules = '';

// Create the event that the content script listens for
var customEvent = document.createEvent('Event');
customEvent.initEvent('myCustomEvent', true, true);

var hiddenDiv = document.getElementById('myCustomEventDiv');
var rules ='';
var allSheets = document.styleSheets;
for (var i = 0; i < allSheets.length; ++i) {
var sheet = allSheets[i];
for (var z = 0; z <= sheet.cssRules.length-1; z++) {
rules = rules +'\n'+ sheet.cssRules[z].cssText;
}
}
hiddenDiv.innerText = rules;
hiddenDiv.dispatchEvent(customEvent);
}

// puts the rules back in the page in a style sheet that the content script can iterate through
// youd probably do most of this in the injected script normally and pass your results back through the comDiv....Im just having fun
document.getElementById('myCustomEventDiv').addEventListener('myCustomEvent', function() {
var eventData = document.getElementById('myCustomEventDiv').innerText;
document.getElementById('myCustomEventDiv').innerText='';

var style = document.createElement('style');
style.type = 'text/css';
style.innerText=eventData;
style = document.head.appendChild(style);
var sheet = document.styleSheets[document.styleSheets.length-1];
for (var z = 0; z <= sheet.cssRules.length-1; z++) {
console.log(sheet.cssRules[z].selectorText +' {\n');
for (var y = 0; y <= sheet.cssRules[z].style.length-1; y++) {
console.log(' '+sheet.cssRules[z].style[y] + ' : ' + sheet.cssRules[z].style.getPropertyValue(sheet.cssRules[z].style[y])+';\n');
};
console.log('}\n');
};

// Clean up
document.head.removeChild(style);
document.body.removeChild(document.getElementById('myCustomEventDiv'));
});

exec(getCSS);

In the case of this question Id prolly do most of the checks in the injected script and then pass the results back through the div and its event. But I wanted to see if I could use the dom methods in the content script to go through the css and this was the only way I could figure to do it. I dont like the idea of inserting the rules back into the page, but couldnt figure any other way of doing it.

How to inject CSS using content script file in Chrome extension?

You could add to the manifest's permissions field; See web_accessible_resources. So you would add this to the manifest:

    , "web_accessible_resources": [
"fix.css"
]

See also "Programmatic injection". and insertCSS().

For most applications, forget all that createElement code and just add the CSS file to the manifest:

"content_scripts": [
{
"matches": ["http://www.google.com/*"],
"css": ["fix.css"],
"js": ["script.js"]
}
],

although I understand that you don't want to do that in this exact instance.

Using Chrome Extension to inject CSS into the Document Inspector

I don't think Webkit allows you to inject CSS or Javascript into the developer tools. There is an experimental API for Chrome which allows you to add tabs and a few other things: http://code.google.com/chrome/extensions/trunk/experimental.devtools.html

linking css file to chrome extension

Solved! (kind of)
I think there was maybe a caching issue on my machine...? I had been working on this late into the night yesterday and added in the !important command as one of my last steps to be sure my inline rules weren't taking precedence over the CSS.

When I came back to this project in the evening today it all worked!
The power of walking away did it again.
I am new at posting here, so not sure if best practice is to delete the question entirely, but I am tempted to leave it to remind others in the future that taking a break is sometimes the answer :)

Some of the lines added into my manifest.json file above weren't necessary to use my .css file

This is the version I have now that it is working as hoped:

{
"manifest_version": 2,
"name": "food project",
"version": "0.1",
"description": "My cool extension.",
"content_scripts": [
{
"css": ["./content.css"],
"matches": ["https://www.target.com/*"],
"js": ["./content.js"]
}
],
"permissions": ["tabs"],
"browser_action": {
"default_popup": "popup.html",
"default_title": "Demo extention",
"default_icon": "/images/logo.png",
"default_badge": "Media Rep"
}
}

How to view css stylesheet injected by a Google Chrome extension using dev tools?

Looks like there's no way to do this if you inject the CSS via content_scripts. I filed a bug here: https://crbug.com/800070

When the extension is in your control, Paul Irish suggests using this code pattern in order to make your styles inspectable: https://github.com/lateral/chrome-extension-blogpost/compare/master...paulirish:master

For other people's extensions, as far as I can tell there's no way to view the source code of the injected stylesheets in DevTools, if you go the content_scripts route.

How to include HTML and CSS files in a chrome extension?

See https://developer.chrome.com/extensions/content_scripts for the specification of the content_scripts property in manifest.json. There's no "html" property in content_scripts. If it did allow injecting HTML, where would it put it, since the original page already has its own HTML? You can only add Javascript and CSS.

If you want to add HTML to the page, you'll need to do it in your Javascript, using DOM manipulation functions, which allow you to specify where the new elements should go.

chrome extension modify CSS in document_start

The comment is correct and it is not OK to modify the CSS of the page you inject into in document_start.

When a script is injected with run_at = document_start it can modify only the CSS it itself injected. It does not have access to the DOM including CSS until some point later (probably after the head is created).

However you can modify the CSS of the page before it is shown by using an observer like this:

const convertCSS = () => {
if (!convertCSS.nSheets) convertCSS.nSheets=0;
if (convertCSS.nSheets===window.document.styleSheets.length) return;
convertCSS.nSheets=window.document.styleSheets.length;

for (const styleSheet of window.document.styleSheets) {
const classes = styleSheet.rules || styleSheet.cssRules;
if (!classes) continue;

for (const cssRule of classes) {
if (cssRule.type !== 1 || !cssRule.style) continue;
const selector = cssRule.selectorText, style=cssRule.style;
if (!selector || !style.cssText) continue;
for (let i=0; i<style.length; i++) {
const propertyName=style.item(i), propertyValue=style.getPropertyValue(propertyName);
// YOUR LOGIC HERE ie:
// if (propertyName==='background-color') cssRule.style.setProperty(propertyName, 'yellow', style.getPropertyPriority(propertyName));
}
}
}
}

const observer =new MutationObserver((mutations, observer) => convertCSS());
observer.observe(document, { childList: true, subtree:true });

If you don't need to modify the CSS on new elements once the page is loaded add :

document.addEventListener("DOMContentLoaded", e => observer.disconnect());

Also you probably want "all_frames": true in your manifest.

Add CSS to pages through a CSS file

Your manifest file must contain a content script pointing to a CSS file, that will load when a url matches your selected url fields...

"content_scripts": [ {
"css": [ "scrollbars.css" ],
"matches": [ "http://www.google.com/*" ]
} ],

This is the same method you would use to inject javascript code, except you would point to a js file instead...

More information here...



Related Topics



Leave a reply



Submit