Parsing CSS with jQuery and JSS

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;
 }
  1. sanitize() - all the work here is done by the two regular expressions contained in the c variable; this method removes new lines and CSS comments
  2. parse() - this method first calls sanitize() to get a cleaned CSS input stream, then separates out selectors with a regular expression, and eventually loop through selectors and parses attributes
  3. parseSelectorName() - extracts the selector from a CSS rule by using a regular expression with the match function which returns an array of matches
  4. parseAttributes() - 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.

Leave a Reply

Note: Only a member of this blog may post a comment.