Created
November 27, 2015 14:23
-
-
Save hallvors/b0be544c17c1dac413d4 to your computer and use it in GitHub Desktop.
CSS -webkit- style enumeration script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function(){ | |
/* | |
Analyses applied CSS and sums up findings | |
We want to return a list of objects referring to elements | |
in the page with the following details: | |
selector: a CSS selector that will match the element (not necessarily the one in the CSS) | |
index: the index of the element in the selection you get | |
if you do document.querySelectorAll(selector) | |
coords: {x: y: width: height: } | |
problems: [ {property: value: } ] | |
*/ | |
/*TODO: | |
Perhaps unsurprising, a major issue with this approach is performance. | |
It might not seem like a big problem for something that can run by itself | |
and record data at leisure, but slow performance makes it time consuming to | |
test and develop.. | |
*/ | |
var ts1 = new Date; | |
var list = []; | |
var neutralFrame = document.body.appendChild(document.createElement('iframe')); | |
var comparisonStyle = cloneobj(neutralFrame.contentWindow.getComputedStyle(neutralFrame.contentDocument.body)); | |
document.body.removeChild(neutralFrame); | |
console.log('Before qsa' + ((new Date)-ts1)); | |
var elms = document.querySelectorAll('*'); | |
var css_properties = ['webkitAnimation', 'webkitTransition', 'webkitTransform']; | |
var css_values = ['-webkit-gradient', '-webkit-flex', '-webkit-box']; | |
for (var i =0, elm; elm = elms[i]; i++) { | |
console.log('Før elm: ' + elm.tagName + ' ' + ((new Date)-ts1)); | |
var coords = elm.getBoundingClientRect(); | |
var tmp = createCSSSelector(elm); | |
var obj = {selector:tmp[0].join(' '), index: tmp[1], coords: cloneobj(coords), problems: []} | |
// console.log(elm.outerHTML.substr(0,30) +' ' + JSON.stringify(obj)); | |
var style = getComputedStyle(elm); | |
// property test | |
for(var j = 0, css; css = css_properties[j]; j++){ | |
// This is where we should figure out if the value is set or default.. | |
if(style[css] !== comparisonStyle[css]){ | |
obj.problems.push({property:css, value: style[css]}); | |
} | |
} | |
// value test | |
for(var prop in style){ | |
if(isNaN(parseInt(prop)) && prop !== 'cssText'){// We skip the numerical lists of properties | |
for(var j = 0, css; css = css_values[j]; j++){ | |
if(style[prop] && style[prop].toString().indexOf(css) > -1){ | |
obj.problems.push({property: prop, value: style[prop]}); | |
} | |
} | |
} | |
} | |
if(obj.problems.length){ | |
list.push(obj); | |
} | |
console.log((new Date)-ts1); | |
}; | |
return JSON.stringify(list, null, 2); | |
function createCSSSelector(elm){ | |
var desc = '', descParts = [], origElm = elm; | |
while(elm){ | |
descParts.unshift(descElm(elm)); | |
desc = descParts.join(' '); | |
try{document.querySelectorAll(desc)}catch(e){console.log('FAILED generated selector: ' + desc + '\n' + e)} | |
if(document.querySelectorAll(desc).length === 1 || descParts.length > 5){ | |
break; | |
} | |
elm = elm.parentElement; | |
} | |
var elms = document.querySelectorAll(desc), idx; | |
for(var i = 0; i<elms.length; i++){ | |
if(elms[i] === origElm){ | |
idx = i; | |
break; | |
} | |
} | |
return [descParts, i]; | |
} | |
function descElm(elm){ | |
var desc = elm.tagName.toLowerCase(); | |
if(elm.id){ | |
desc += '#' + CSS.escape(elm.id); | |
} | |
if(elm.classList.length){ | |
[].forEach.call(elm.classList, function(theClass){ | |
desc += '.' + CSS.escape(theClass); | |
}); | |
// desc += '.' + [].join.call(elm.classList, '.'); | |
} | |
if(elm.href){ | |
//desc += '[href="' + elm.href + '"]'; | |
} | |
return desc; | |
} | |
function cloneobj(rect){ | |
var obj = {}; | |
for(var prop in rect){ | |
obj[prop] = rect[prop]; | |
} | |
return obj; | |
} | |
/*! https://mths.be/cssescape v0.2.1 by @mathias | MIT license */ | |
;(function(root) { | |
if (!root.CSS) { | |
root.CSS = {}; | |
} | |
var CSS = root.CSS; | |
var InvalidCharacterError = function(message) { | |
this.message = message; | |
}; | |
InvalidCharacterError.prototype = new Error; | |
InvalidCharacterError.prototype.name = 'InvalidCharacterError'; | |
if (!CSS.escape) { | |
// http://dev.w3.org/csswg/cssom/#serialize-an-identifier | |
CSS.escape = function(value) { | |
var string = String(value); | |
var length = string.length; | |
var index = -1; | |
var codeUnit; | |
var result = ''; | |
var firstCodeUnit = string.charCodeAt(0); | |
while (++index < length) { | |
codeUnit = string.charCodeAt(index); | |
// Note: there’s no need to special-case astral symbols, surrogate | |
// pairs, or lone surrogates. | |
// If the character is NULL (U+0000), then throw an | |
// `InvalidCharacterError` exception and terminate these steps. | |
if (codeUnit == 0x0000) { | |
throw new InvalidCharacterError( | |
'Invalid character: the input contains U+0000.' | |
); | |
} | |
if ( | |
// If the character is in the range [\1-\1F] (U+0001 to U+001F) or is | |
// U+007F, […] | |
(codeUnit >= 0x0001 && codeUnit <= 0x001F) || codeUnit == 0x007F || | |
// If the character is the first character and is in the range [0-9] | |
// (U+0030 to U+0039), […] | |
(index == 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039) || | |
// If the character is the second character and is in the range [0-9] | |
// (U+0030 to U+0039) and the first character is a `-` (U+002D), […] | |
( | |
index == 1 && | |
codeUnit >= 0x0030 && codeUnit <= 0x0039 && | |
firstCodeUnit == 0x002D | |
) | |
) { | |
// http://dev.w3.org/csswg/cssom/#escape-a-character-as-code-point | |
result += '\\' + codeUnit.toString(16) + ' '; | |
continue; | |
} | |
// If the character is not handled by one of the above rules and is | |
// greater than or equal to U+0080, is `-` (U+002D) or `_` (U+005F), or | |
// is in one of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to | |
// U+005A), or [a-z] (U+0061 to U+007A), […] | |
if ( | |
codeUnit >= 0x0080 || | |
codeUnit == 0x002D || | |
codeUnit == 0x005F || | |
codeUnit >= 0x0030 && codeUnit <= 0x0039 || | |
codeUnit >= 0x0041 && codeUnit <= 0x005A || | |
codeUnit >= 0x0061 && codeUnit <= 0x007A | |
) { | |
// the character itself | |
result += string.charAt(index); | |
continue; | |
} | |
// Otherwise, the escaped character. | |
// http://dev.w3.org/csswg/cssom/#escape-a-character | |
result += '\\' + string.charAt(index); | |
} | |
return result; | |
}; | |
} | |
}(typeof global != 'undefined' ? global : this)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment