Reading documents CSS in Chrome Extension

css, google-chrome, google-chrome-extension

Solution

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.

Problem

I am trying to read the pages CSS using a chrome extension. This is what i have in my content script : ``` var allSheets = document.styleSheets; for (var i = 0; i < allSheets.length; ++i) { var sheet = allSheets[i]; var src = sheet.href; var rules = sheet.cssRules || sheet.rules; } ``` For some reason the rules are always empty. I do get all the CSS files used in the 'src' variable. But the rules always come as null.. Its working when I try it as a separate javascript on a HTML page. But fails when I put it up in the content script of my chrome extension. Can somebody lemme know why?

Original source