Last active
September 5, 2016 11:26
-
-
Save raininglemons/89fbfe32ffcd30d9c8536ef890269694 to your computer and use it in GitHub Desktop.
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
(() => { | |
class CSSReader { | |
constructor(input) { | |
const rules = input.split('\n') //.match(/((#|\.)?[\[\]\(\)a-zA-Z0-9_\-:]+,?\s*)+{.+}/g); | |
this.rules = rules.map((rule, i) => { | |
// console.log(`Processing ${i} of ${rules.length}`); | |
if (rule.substr(0, 1) === '@') { | |
// Strip out media queries... | |
rule = rule.substr(rule.indexOf('{')); | |
} | |
try { | |
return new Rule(rule); | |
} catch (e) { | |
// console.error(e); | |
return null; | |
} | |
}).filter(rule => rule !== null); | |
this.hashes = this.rules.reduce((hashes, rule) => { | |
if (!hashes[rule.hash]) { | |
hashes[rule.hash] = []; | |
} | |
hashes[rule.hash].push(rule); | |
return hashes; | |
}, {}); | |
this.duplicates = Object.keys(this.hashes).filter(hash => this.hashes[hash].length > 1) | |
.reduce((duplicates, hash) => { | |
duplicates[hash] = this.hashes[hash]; | |
return duplicates; | |
}, {}) | |
} | |
} | |
const regex = { | |
selector: /((#|\.?[\[\]\(\)a-zA-Z0-9_\-:\,\s]+)\s*)+/, | |
rules: /([a-zA-Z\-]+):([^;]+)/g, | |
split: /^(.+?):(.+)$/, | |
} | |
class Rule { | |
constructor(rule) { | |
this.selector = rule.match(regex.selector)[0]; | |
const rules = rule.match(/{(.+)}/)[1]; | |
const parsedRules = rules.match(regex.rules); | |
this.rules = parsedRules.map(rule => rule.match(regex.split)) | |
.sort((a, b) => { | |
const la = a[1].toLowerCase(); | |
const lb = b[1].toLowerCase(); | |
if (la < lb) { | |
return -1; | |
} else if (la > lb) { | |
return 1; | |
} else { | |
return 0; | |
} | |
}) | |
.reduce((obj, rule) => { | |
obj[rule[1]] = rule[2]; | |
return obj; | |
}, {}); | |
this.hash = this.hash(JSON.stringify({ selector: this.selector, rules: this.rules })); | |
} | |
hash(val) { | |
var hash = 0, i, chr, len; | |
if (val.length === 0) return hash; | |
for (i = 0, len = val.length; i < len; i++) { | |
chr = val.charCodeAt(i); | |
hash = ((hash << 5) - hash) + chr; | |
hash |= 0; // Convert to 32bit integer | |
} | |
return hash; | |
} | |
toString() { | |
return this.selector + '{' + | |
Object.keys(this.rules) | |
.map(rule => rule + ':' + this.rules[rule]) | |
.join(';') | |
+ '}'; | |
} | |
} | |
const rules = new CSSReader(document.body.innerText); | |
Object.keys(rules.duplicates).sort((a, b) => rules.duplicates[b].length - rules.duplicates[a].length).forEach(hash => console.log(`${rules.duplicates[hash].length} occurences for \`${rules.duplicates[hash][0]}\``)); | |
window.rules = rules; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment