Last active
January 29, 2019 21:29
-
-
Save jamlfy/98c9324e1494c0968e8fb3f3fce1fce0 to your computer and use it in GitHub Desktop.
Compressor the rules in CSS
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
const css = require('css'); | |
const fs = require('fs'); | |
const path = require('path'); | |
const fileIn = path.join(__dirname, 'style.css'); | |
const fileOut = path.join(__dirname, 'out.css'); | |
Object.fromEntries = Object.fromEntries || ((x) => x.reduce((p,c) => {p[c[0]]=c[1];return p;},{})); | |
fs.readFile(fileIn, {encoding: 'utf-8'}, function(err,data){ | |
if (!err) { | |
let cssIn = css.parse(data); | |
let cssOut = JSON.parse(JSON.stringify(cssIn)); | |
let exlcude = []; | |
cssOut.stylesheet.rules = []; | |
for (let i = 0; i < cssIn.stylesheet.rules.length; i++) { | |
if(cssIn.stylesheet.rules[i].type == 'rule' ){ | |
if(!exlcude.find(e => JSON.stringify(e) == JSON.stringify(cssIn.stylesheet.rules[i]))){ | |
let style = cssIn.stylesheet.rules[i].selectors.sort((a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0); | |
let same = cssIn.stylesheet.rules.filter(rule => JSON.stringify( | |
(rule.selectors || [] ).sort((a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0)) === JSON.stringify(style)); | |
cssOut.stylesheet.rules.push({ | |
type: 'rule', | |
declarations : [].concat.apply([], same.map(e => e.declarations )), | |
selectors : cssIn.stylesheet.rules[i].selectors | |
}); | |
exlcude = exlcude.concat(same); | |
} | |
} else { | |
cssOut.stylesheet.rules.push(cssIn.stylesheet.rules[i]); | |
} | |
} | |
console.log("css:same", cssIn.stylesheet.rules.length, cssOut.stylesheet.rules.length); | |
cssIn = JSON.parse(JSON.stringify(cssOut)); | |
cssOut = JSON.parse(JSON.stringify(cssOut)); | |
exlcude = []; | |
cssOut.stylesheet.rules = []; | |
for (let i = 0; i < cssIn.stylesheet.rules.length; i++) { | |
if(cssIn.stylesheet.rules[i].type == 'rule' ){ | |
if(!exlcude.find(e => JSON.stringify(e) == JSON.stringify(cssIn.stylesheet.rules[i]))){ | |
let style = Object.fromEntries(cssIn.stylesheet.rules[i].declarations.map(e => ([ e.property, e.value ])).sort((a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0)); | |
let same = cssIn.stylesheet.rules.filter(rule => JSON.stringify(Object.fromEntries( | |
(rule.declarations || [] ).map( | |
e => ([ e.property, e.value ])).sort((a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0))) === JSON.stringify(style)); | |
cssOut.stylesheet.rules.push({ | |
type: 'rule', | |
declarations : cssIn.stylesheet.rules[i].declarations, | |
selectors : [].concat.apply([], same.map(e => e.selectors )) | |
}); | |
exlcude = exlcude.concat(same); | |
} | |
} else { | |
cssOut.stylesheet.rules.push(cssIn.stylesheet.rules[i]); | |
} | |
} | |
console.log("css:rules", cssIn.stylesheet.rules.length, cssOut.stylesheet.rules.length); | |
cssIn = JSON.parse(JSON.stringify(cssOut)); | |
cssOut = JSON.parse(JSON.stringify(cssOut)); | |
exlcude = 0; | |
let exlcd = 0; | |
cssOut.stylesheet.rules = []; | |
for (let i = 0; i < cssIn.stylesheet.rules.length; i++) { | |
if(cssIn.stylesheet.rules[i].type == 'rule' ){ | |
var declarations = []; | |
exlcude += cssIn.stylesheet.rules[i].declarations.length ; | |
for (let z = cssIn.stylesheet.rules[i].declarations.length - 1; z >= 0; z--) { | |
if(!declarations.find(e => e.property === cssIn.stylesheet.rules[i].declarations[z].property)){ | |
declarations.push( cssIn.stylesheet.rules[i].declarations[z] ); | |
} else { | |
exlcd++; | |
} | |
} | |
cssOut.stylesheet.rules.push({ | |
...cssIn.stylesheet.rules[i], | |
declarations, | |
}); | |
} else { | |
cssOut.stylesheet.rules.push(cssIn.stylesheet.rules[i]); | |
} | |
} | |
console.log("css:declarations", exlcude, exlcd); | |
fs.writeFile(fileOut, css.stringify(cssOut), function(err) { | |
if(err) { | |
return console.log(err); | |
} | |
console.log("The file was saved!"); | |
}); | |
} else { | |
console.log(err); | |
} | |
}); |
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
const browserless = require('browserless')(); | |
const DOMAIN = 'http://URL.EXT/'; | |
const AMP = 'amp'; | |
const URLS = [ | |
'my-url-test' | |
]; | |
var result = {}; | |
var testers = [ | |
(line) => /\{$/.test(line), | |
(line) => !/^\@media/.test(line), | |
(line) => !/\/\*/.test(line) | |
]; | |
var clean = [ | |
(line) => line.split(/\,/gim), | |
(line) => line.replace(/\{$/gim, ''), | |
(line) => line.replace(/\:\w+/gim, ''), | |
(line) => [ line ].concat(line.split(/\,|\s|\>|\+|\~/gim)) | |
]; | |
const nextOpen = browserless | |
.evaluate(async (page, response) => { | |
Array.concatAll = (args) => { | |
return (args) = [].concat(...args); | |
} | |
Array.Flatten = (arr) => { | |
return Array.concatAll(arr.map(x => Array.isArray(x) ? Array.Flatten(x) : x )) | |
}; | |
try { | |
const styleHandle = await page.$('style[amp-custom]'); | |
const innerHTML = await page.evaluate(body => body.innerHTML, styleHandle); | |
const file = innerHTML.split(/\n/gim); | |
let lines = []; | |
for (let line = 0; line < file.length; line++) { | |
if(testers.every(e => e(file[line]))){ | |
let select = [ file[line] ]; | |
let last = []; | |
for (let i = clean.length - 1; i >= 0; i--) { | |
let array = select.map((e) => clean[i](e)); | |
select = Array.Flatten(array.filter((e, i) => e && array.indexOf(e) == i )); | |
} | |
let invalids = 0; | |
for (var i = select.length - 1; i >= 0; i--) { | |
try { | |
result[select[i]] = result[select[i]] || 1; | |
let me = await page.$(select[i]); | |
if(me){ | |
result[select[i]]++; | |
} | |
} catch(e){ | |
invalids++; | |
//console.log("catch"); | |
} finally { | |
//console.log("finally"); | |
} | |
} | |
lines.push(invalids); | |
} | |
} | |
return Promise.resolve(lines); | |
} catch(e){ | |
console.log("log", e); | |
return Promise.resolve([]); | |
} | |
}); | |
;(async () => { | |
for (var i = URLS.length - 1; i >= 0; i--) { | |
try { | |
const info = await nextOpen( DOMAIN + URLS[i] + AMP); | |
console.log("Info", URLS[i], info.reduce((accumulator, currentValue) => accumulator + currentValue, 0)); | |
} catch(e) { | |
console.log("Fail", URLS[i]); | |
} | |
} | |
console.log('--- Result ---'); | |
console.log(JSON.stringify(result, null, '\t')); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment