Skip to content

Instantly share code, notes, and snippets.

@jonathantneal
Created July 31, 2012 16:02
Show Gist options
  • Save jonathantneal/3218076 to your computer and use it in GitHub Desktop.
Save jonathantneal/3218076 to your computer and use it in GitHub Desktop.
css.js // parse, vendor-prefix, and render CSS; get vendor details
(function (global) {
function clean(css) {
return css
.replace(/\/\*[\W\w]*?\*\//g, "") // remove comments
.replace(/^\s+|\s+$/g, "") // remove trailing spaces
.replace(/\s*([:;{}])\s*/g, "$1") // remove trailing separator spaces
.replace(/\};+/g, "}") // remove unnecessary separators
.replace(/([^:;{}])}/g, "$1;}") // add trailing separators
}
function refine(css, isBlock) {
return /^@/.test(css) ? (css = css.split(" ")) && {
"identifier": css.shift().substr(1).toLowerCase(),
"parameters": css.join(" ")
} : (isBlock ? /:$/ : /:/).test(css) ? (css = css.split(":")) && {
"property": css.shift(),
"value": css.join(":")
} : css;
}
function parse(css, regExp, object) {
for (var m; (m = regExp.exec(css)) != null;) {
if (m[2] == "{") object.block.push(object = {
"selector": refine(m[1], true),
"block": [],
"parent": object
});
else if (m[2] == "}") object = object.parent;
else if (m[2] == ";") object.block.push(refine(m[1]));
}
}
global.parseCSS = function (css) {
return parse(clean(css), /([^{};]*)([;{}])/g, css = { block: [] }), css;
};
global.vendorCSS = function (css) {
var newCSS = {}, block, i, e;
if (css.selector) newCSS.selector = css.selector;
if (css.property) newCSS.property = global.vendor.property[css.property] || css.property;
if (css.value) {
newCSS.value = css.value;
for (i in global.vendor.value) {
e = global.vendor.value[i];
i = new RegExp(i, "g");
if (newCSS.value.match(i)) newCSS.value = newCSS.value.replace(i, e);
}
}
if (css.block) for (newCSS.block = [], i = 0; css.block[i]; ++i) newCSS.block[i] = global.vendorCSS(css.block[i]);
return newCSS;
};
global.renderCSS = function (css) {
var str = "", i;
if (css.selector) str += css.selector + "{";
if (css.property) str += css.property + ":" + css.value + ";";
for (i = 0; css.block && css.block[i]; ++i) str += global.renderCSS(css.block[i]);
if (css.selector) str += "}";
return str;
};
global.vendor = function (vendorObject, vendorPrefixRe, camelToDashedRe, camelToDashedFn, style, linearGradient, e, m) {
for (e in style) if (m = e.match(vendorPrefixRe)) {
vendorObject.prefix = m[1].toLowerCase();
break;
}
for (e in style) if (m = e.match(vendorPrefixRe)) vendorObject.property[e[m[1].length].toLowerCase() + e.slice(m[1].length + 1).replace(camelToDashedRe, camelToDashedFn)] = e.replace(camelToDashedRe, camelToDashedFn);
style.backgroundImage = "-" + vendorObject.prefix + "-" + linearGradient + "(red, red)", vendorObject.value[linearGradient] = style.backgroundImage ? "-" + vendorObject.prefix + "-" + linearGradient : linearGradient;
return vendorObject;
}({
property: {},
value: {}
}, /^(O|Moz|ms|webkit)[A-Z]/, /[A-Z]/g, function (e) {
return "-" + e.toLowerCase()
}, document.createElement("x-element").style, "linear-gradient");
})(this);
(function(e){function t(e){return e.replace(/\/\*[\W\w]*?\*\//g,"").replace(/^\s+|\s+$/g,"").replace(/\s*([:;{}])\s*/g,"$1").replace(/\};+/g,"}").replace(/([^:;{}])}/g,"$1;}")}function n(e,t){return/^@/.test(e)?(e=e.split(" "))&&{identifier:e.shift().substr(1).toLowerCase(),parameters:e.join(" ")}:(t?/:$/:/:/).test(e)?(e=e.split(":"))&&{property:e.shift(),value:e.join(":")}:e}function r(e,t,r){for(var i;(i=t.exec(e))!=null;)i[2]=="{"?r.block.push(r={selector:n(i[1],!0),block:[],parent:r}):i[2]=="}"?r=r.parent:i[2]==";"&&r.block.push(n(i[1]))}e.parseCSS=function(e){return r(t(e),/([^{};]*)([;{}])/g,e={block:[]}),e},e.vendorCSS=function(t){var n={},r,i,s;t.selector&&(n.selector=t.selector),t.property&&(n.property=e.vendor.property[t.property]||t.property);if(t.value){n.value=t.value;for(i in e.vendor.value)s=e.vendor.value[i],i=new RegExp(i,"g"),n.value.match(i)&&(n.value=n.value.replace(i,s))}if(t.block)for(n.block=[],i=0;t.block[i];++i)n.block[i]=e.vendorCSS(t.block[i]);return n},e.renderCSS=function(t){var n="",r;t.selector&&(n+=t.selector+"{"),t.property&&(n+=t.property+":"+t.value+";");for(r=0;t.block&&t.block[r];++r)n+=e.renderCSS(t.block[r]);return t.selector&&(n+="}"),n},e.vendor=function(e,t,n,r,i,s,o,u){for(o in i)if(u=o.match(t)){e.prefix=u[1].toLowerCase();break}for(o in i)if(u=o.match(t))e.property[o[u[1].length].toLowerCase()+o.slice(u[1].length+1).replace(n,r)]=o.replace(n,r);return i.backgroundImage="-"+e.prefix+"-"+s+"(red, red)",e.value[s]=i.backgroundImage?"-"+e.prefix+"-"+s:s,e}({property:{},value:{}},/^(O|Moz|ms|webkit)[A-Z]/,/[A-Z]/g,function(e){return"-"+e.toLowerCase()},document.createElement("x-element").style,"linear-gradient")})(this)
@jonathantneal
Copy link
Author

css.min.js is 805 bytes gzipped

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment