Recently I have been working on a project where a user can change some values inside a UI widget via form elements like input fields, range, etc. that would in turn change CSS code inside a CodeMirror editor which would reflect changes inside an iframe sandbox (like cssdeck, jsfiddle, etc.).
The Complexity
I hope you can imagine the complexity of this task. Altering CSS property-value in an editor (from some UI interaction) which is editable by the user! The code written by the user could just be in any format with comments here and there, and I would need to parse them with a parser accurately enough -> change values and/or properties -> build properly indented CSS back to show in the editor.
I started off doing the auto manipulation using regex in client-side JS but unfortunately failed, It’s just not that easy and the project had to be done in a few days so writing a parser myself was not viable.
What's the one thing every developer wants? More screens! Enhance your coding experience with an external monitor to increase screen real estate.
Finding the Parser
On googling and searching a lot I came across these projects, tried each and all of them lacked some feature or the other or worked in a weird manner that made them pretty much unusable in my case –
- http://www.glazman.org/JSCSSP/
- https://github.com/tabatkins/css-parser
- https://github.com/NV/CSSOM
- https://github.com/visionmedia/css
The one from Visionmedia is pretty neat and lightweight but cannot can preserve comments.
On further searching, thanks to some guy on IRC I found THE awesome CSS Parser written in Javascript – Gonzales. It is fast, really easy to use and the AST (Abstract Syntax Tree) format is also well documented. This tool just works like a charm.
It was also super easy to port it from server-side Node.js to client-side using browserify. I just installed the module with npm and in a script file wrote this –
var gonzales = require('gonzales'); window.gonzales = gonzales;
Then from the command line –
$ browserify script.js > gonzales.js
Finally, loaded gonzales.js
via script
tags inside my webpage.
So basically, after generating the AST from the gonzales.srcToCSSP(src)
method, I just had to understand the format a bit, make appropriate changes to it from the user’s interaction with the UI widget and then convert the AST back to well indented source using gonzales.csspToSrc(ast)
. It can also handle CSS3 just fine!
If you’re looking for a PHP or Ruby based CSS parser then these might be good –
Thankfully my project is in Node.js and porting Gonzales to client-side is super easy. Executing in the browser (over making XHR requests) means the parsing and changing values in the editor is really fast.
Hey, check out our version : https://github.com/jotform/css.js
It also preserves comments between selectors!
Hey, there’s a new fork of Gonzales with Preprocessors support https://github.com/tonyganch/gonzales-pe and I’m trying to use Browserify (as I already did with Gonzales following your tutorial) and it doesn’t seem to work. Could you by any chance try if it works for you? I can’t see what I’m doing wrong.
Thanks!