Tuesday, 18 February 2014

jsmin.js keeping important comments unchanged

More than dozen years ago Douglas Crockford, the JavaScript guru, has presented his JavaScript Minifier. This tool obfuscates the JavaScript code, removing extra whitespaces and comments. Later, Franck Marcia has adapted the C-written program to JavaScript. See his implementation at the page JS Minifier.

Still later, Billy Hoffman has patched the script and added the support of important comments. Important comments are specially formed comments (in practice, denoted with /*!) that are not removed by minifier. What he has done we can find out from his article JSMin, Important Comments, and Copyright Violations. The main goal to support important comments was to retain copyrights and licensing information intact.

Important comments are very useful also to keep some sensitive data within (for example, resources used by the script). Unfortunately, they are not supported completely because TAB and asterisk characters are changed (TABs are converted to SPACEs, and asterisks are eaten by the minifier). To fix this issue I have made some changes to the latest version of jsmin.js.

You can find the updated version of the jsmin.js at the GitHub. Also you can apply the following patch for the existing on your computer copy of the original script:
1a2,9
> jsmin.js - 2014-02-04
> Author: Ildar Shaimordanov
> This version was patched to keep important comments (denoted with /*!) 
> unchanged. The previous version of jsmin.js ate asterisk symbols and 
> modified some characters as well (for example TAB was replaced by SPACE). 
> Sometimes, comments should stay unchanged (for example, a function could 
> keep its resources within comments). So this version does it. 
> 
128,131c136
<     if(c >= ' ' || c == '\n' || c == '\r') {
<       return c;
<     }
<     return ' ';
---
>     return c;
141a147,150
>   function peekIC() {
>     theLookahead = getcIC();
>     return theLookahead;
>   }
173,174c182,183
<                   if(peek() == '/') {
<                     getc();
---
>                   if(peekIC() == '/') {
>                     getcIC();
176a186
>                   d += c;