JSS is a powerful jQuery plugin written by Andy Kent that serves as a really handy CSS parser in many contexts. Since I'm still looking for a good JavaScript CSS parser that honors the Flex syntax used by the W3C specifications, I've found this plugin really useful for learning something new. For example, all parsing is handled by four methods, sanitize()
, parse()
, parseSelectorName()
and parseAttributes()
. They are as follows:
// --- // ultra lightweight CSS parser, only works with 100% valid css files, no support for hacks etc. // --- sanitize: function(content) { if(!content) return ''; var c = content.replace(/[\n\r]/gi,''); // remove newlines c = c.replace(/\/\*.+?\*\//gi,''); // remove comments return c; }, parse: function(content){ var c = this.sanitize(content); var tree = []; // this is the css tree that is built up c = c.match(/.+?\{.+?\}/gi); // seperate out selectors if(!c) return []; for(var i=0;i<c.length;i++) // loop through the selectors & parse the attributes if(c[i]) tree.push( { selector: this.parseSelectorName(c[i]), attributes: this.parseAttributes(c[i]) } ); return tree; }, parseSelectorName: function(content){ return $.trim(content.match(/^.+?\{/)[0].replace('{','')); // extract the selector }, parseAttributes: function(content){ var attributes = {}; c = content.match(/\{.+?\}/)[0].replace(/[\{\}]/g,'').split(';').slice(0,-1); for(var i=0;i<c.length; i++){ if(c[i]){ c[i] = c[i].split(':'); attributes[$.trim(c[i][0])] = $.trim(c[i][1]); }; }; return attributes; }
sanitize()
- all the work here is done by the two regular expressions contained in thec
variable; this method removes new lines and CSS commentsparse()
- this method first callssanitize()
to get a cleaned CSS input stream, then separates out selectors with a regular expression, and eventually loop through selectors and parses attributesparseSelectorName()
- extracts the selector from a CSS rule by using a regular expression with thematch
function which returns an array of matchesparseAttributes()
- returns an array containing all attributes found in a CSS rule.
This is a string-based parsing with regular expressions, an approach that I followed myself a couple of months ago. Honestly, I didn't find the correct regular expressions, though. I wonder if it's possible to use a different approach, for example a stream-based approach like the JSON parsing used by Douglas Crockford in its json.js library. When I have more spare time, I'll surely make some tests.