Adds an option to store escaped metadata to CommentsProcessor.
authorJakub Pawlowicz <contact@jakubpawlowicz.com>
Thu, 16 Oct 2014 18:27:36 +0000 (19:27 +0100)
committerJakub Pawlowicz <contact@jakubpawlowicz.com>
Sun, 7 Dec 2014 11:55:17 +0000 (11:55 +0000)
lib/text/comments-processor.js
test/text/comments-processor-test.js

index cb69d89..8aac101 100644 (file)
@@ -7,12 +7,13 @@ var COMMENT_SUFFIX = '*/';
 
 var lineBreak = require('os').EOL;
 
-var CommentsProcessor = function CommentsProcessor(context, keepSpecialComments, keepBreaks) {
+var CommentsProcessor = function CommentsProcessor(context, keepSpecialComments, keepBreaks, saveWaypoints) {
   this.comments = new EscapeStore('COMMENT');
   this.context = context;
   this.keepAll = keepSpecialComments == '*';
   this.keepOne = keepSpecialComments == '1' || keepSpecialComments === 1;
   this.keepBreaks = keepBreaks;
+  this.saveWaypoints = saveWaypoints;
 };
 
 function quoteScannerFor(data) {
@@ -36,7 +37,12 @@ CommentsProcessor.prototype.escape = function (data) {
   var nextStart = 0;
   var nextEnd = 0;
   var cursor = 0;
+  var indent = 0;
+  var breaksCount;
+  var lastBreakAt;
+  var newIndent;
   var isQuotedAt = quoteScannerFor(data);
+  var saveWaypoints = this.saveWaypoints;
 
   for (; nextEnd < data.length;) {
     nextStart = data.indexOf(COMMENT_PREFIX, cursor);
@@ -58,11 +64,23 @@ CommentsProcessor.prototype.escape = function (data) {
     tempData.push(data.substring(cursor, nextStart));
 
     var comment = data.substring(nextStart, nextEnd + COMMENT_SUFFIX.length);
-    if (comment.indexOf(SPECIAL_COMMENT_PREFIX) === 0) {
-      var placeholder = this.comments.store(comment);
+
+    if (saveWaypoints) {
+      breaksCount = comment.split(lineBreak).length - 1;
+      lastBreakAt = comment.lastIndexOf(lineBreak);
+      newIndent = lastBreakAt > 0 ?
+        comment.substring(lastBreakAt + lineBreak.length).length :
+        indent + comment.length;
+    }
+
+    if (saveWaypoints || comment.indexOf(SPECIAL_COMMENT_PREFIX) === 0) {
+      var metadata = saveWaypoints ? [breaksCount, newIndent] : null;
+      var placeholder = this.comments.store(comment, metadata);
       tempData.push(placeholder);
     }
 
+    if (saveWaypoints)
+      indent = newIndent + 1;
     cursor = nextEnd + COMMENT_SUFFIX.length;
   }
 
index 646e098..ba0144d 100644 (file)
@@ -5,19 +5,19 @@ var CommentsProcessor = require('../../lib/text/comments-processor');
 var lineBreak = require('os').EOL;
 var otherLineBreak = lineBreak == '\n' ? '\r\n' : '\n';
 
-function processorContext(name, context, keepSpecialComments, keepBreaks) {
+function processorContext(name, context, keepSpecialComments, keepBreaks, saveWaypoints) {
   var vowContext = {};
 
   function escaped (targetCSS) {
     return function (sourceCSS) {
-      var result = new CommentsProcessor(keepSpecialComments, keepBreaks).escape(sourceCSS);
+      var result = new CommentsProcessor(null, keepSpecialComments, keepBreaks, saveWaypoints).escape(sourceCSS);
       assert.equal(result, targetCSS);
     };
   }
 
   function restored (targetCSS) {
     return function (sourceCSS) {
-      var processor = new CommentsProcessor(null, keepSpecialComments, keepBreaks);
+      var processor = new CommentsProcessor(null, keepSpecialComments, keepBreaks, saveWaypoints);
       var result = processor.restore(processor.escape(sourceCSS));
       assert.equal(result, targetCSS);
     };
@@ -145,4 +145,43 @@ vows.describe(CommentsProcessor)
       ]
     }, '1', true)
   )
+  .addBatch(
+    processorContext('waypoints', {
+      'one comment': [
+        '/* some text */',
+        '__ESCAPED_COMMENT_CLEAN_CSS0(0,15)__',
+        ''
+      ],
+      'one special comment': [
+        '/*! some text */',
+        '__ESCAPED_COMMENT_CLEAN_CSS0(0,16)__',
+        '/*! some text */'
+      ],
+      'two comments': [
+        '/* one text *//* another text */',
+        '__ESCAPED_COMMENT_CLEAN_CSS0(0,14)____ESCAPED_COMMENT_CLEAN_CSS1(0,33)__',
+        ''
+      ],
+      'two same comments': [
+        '/* one text *//* one text */',
+        '__ESCAPED_COMMENT_CLEAN_CSS0(0,14)____ESCAPED_COMMENT_CLEAN_CSS0(0,29)__',
+        ''
+      ],
+      'two special comments': [
+        '/*! one text *//*! another text */',
+        '__ESCAPED_COMMENT_CLEAN_CSS0(0,15)____ESCAPED_COMMENT_CLEAN_CSS1(0,35)__',
+        '/*! one text *//*! another text */'
+      ],
+      'two special comments with line breaks': [
+        '/*! one text' + lineBreak + '*//*! another' + lineBreak + ' text' + lineBreak + ' */',
+        '__ESCAPED_COMMENT_CLEAN_CSS0(1,2)____ESCAPED_COMMENT_CLEAN_CSS1(2,3)__',
+        '/*! one text' + lineBreak + '*//*! another' + lineBreak + ' text' + lineBreak + ' */'
+      ],
+      'three special comments with line breaks and content in between': [
+        '/*! one text' + lineBreak + '*/a{}/*! ' + lineBreak + 'test */p{color:red}/*! another' + lineBreak + ' text' + lineBreak + lineBreak + '  */',
+        '__ESCAPED_COMMENT_CLEAN_CSS0(1,2)__a{}__ESCAPED_COMMENT_CLEAN_CSS1(1,7)__p{color:red}__ESCAPED_COMMENT_CLEAN_CSS2(3,4)__',
+        '/*! one text' + lineBreak + '*/a{}/*! ' + lineBreak + 'test */p{color:red}/*! another' + lineBreak + ' text' + lineBreak + lineBreak + '  */'
+      ]
+    }, '*', false, true)
+  )
   .export(module);