-
Star
(599)
You must be signed in to star a gist -
Fork
(150)
You must be signed in to fork a gist
-
-
Save PaulKinlan/6284142 to your computer and use it in GitHub Desktop.
| (function() { | |
| var CSSCriticalPath = function(w, d, opts) { | |
| var opt = opts || {}; | |
| var css = {}; | |
| var pushCSS = function(r) { | |
| if(!!css[r.selectorText] === false) css[r.selectorText] = {}; | |
| var styles = r.style.cssText.split(/;(?![A-Za-z0-9])/); | |
| for(var i = 0; i < styles.length; i++) { | |
| if(!!styles[i] === false) continue; | |
| var pair = styles[i].split(": "); | |
| pair[0] = pair[0].trim(); | |
| pair[1] = pair[1].trim(); | |
| css[r.selectorText][pair[0]] = pair[1]; | |
| } | |
| }; | |
| var parseTree = function() { | |
| // Get a list of all the elements in the view. | |
| var height = w.innerHeight; | |
| var walker = d.createTreeWalker(d, NodeFilter.SHOW_ELEMENT, function(node) { return NodeFilter.FILTER_ACCEPT; }, true); | |
| while(walker.nextNode()) { | |
| var node = walker.currentNode; | |
| var rect = node.getBoundingClientRect(); | |
| if(rect.top < height || opt.scanFullPage) { | |
| var rules = w.getMatchedCSSRules(node); | |
| if(!!rules) { | |
| for(var r = 0; r < rules.length; r++) { | |
| pushCSS(rules[r]); | |
| } | |
| } | |
| } | |
| } | |
| }; | |
| this.generateCSS = function() { | |
| var finalCSS = ""; | |
| for(var k in css) { | |
| finalCSS += k + " { "; | |
| for(var j in css[k]) { | |
| finalCSS += j + ": " + css[k][j] + "; "; | |
| } | |
| finalCSS += "}\n"; | |
| } | |
| return finalCSS; | |
| }; | |
| parseTree(); | |
| }; | |
| var cp = new CSSCriticalPath(window, document); | |
| var css = cp.generateCSS(); | |
| console.log(css); | |
| })(); |
FWIW I also made a version of the bookmarklet, and I even accounted for some cases where the cssRules or rules property threw an error on access.
I get Uncaught TypeError: w.getMatchedCSSRules is not a function , using Chrome
I get
Uncaught TypeError: w.getMatchedCSSRules is not a function, using Chrome
My re-fashioning used a polyfill for that; getMatchedCSSRules was never standardized, and it was removed from Chrome starting with version 63.
I was able to get it working by replacing getMatchedCSSRules with the script below. However doesn't work if css is from a different domain.
var getCSS = function(el) {
var sheets = document.styleSheets, ret = [];
el.matches = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector
|| el.msMatchesSelector || el.oMatchesSelector;
for (var i in sheets) {
var rules;
try {
rules = sheets[i].rules;
} catch {
console.log("Error reading rules: ");
try{
rules = sheets[i].cssRules;
} catch {
console.log("Error reading cssRules: ");
}
}
```
this library is probably the way to go: https://www.brothercake.com/site/resources/scripts/cssutilities/
Your example script was not complete, but I imagine the rest of the way you'd do it is to test the element against each rule to see whether it matches.
got it! Now what I see is not wrapped in <style></style> tags, and I believe I am supposed to put what is wrapped in those style tags in the AO inline and defer css box. I don't want to crash my site (which I have managed to do before on things like this), so I want to be sure I have extracted the correct code to put in that AO field....