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

index 02e72ea..5a5139f 100644 (file)
@@ -7,6 +7,8 @@ var EXPRESSION_PREFIX = EXPRESSION_NAME + EXPRESSION_START;
 var BODY_START = '{';
 var BODY_END = '}';
 
+var lineBreak = require('os').EOL;
+
 function findEnd(data, start) {
   var end = start + EXPRESSION_NAME.length;
   var level = 0;
@@ -44,8 +46,9 @@ function findEnd(data, start) {
   return end;
 }
 
-var ExpressionsProcessor = function ExpressionsProcessor() {
+var ExpressionsProcessor = function ExpressionsProcessor(saveWaypoints) {
   this.expressions = new EscapeStore('EXPRESSION');
+  this.saveWaypoints = saveWaypoints;
 };
 
 ExpressionsProcessor.prototype.escape = function (data) {
@@ -53,6 +56,11 @@ ExpressionsProcessor.prototype.escape = function (data) {
   var nextEnd = 0;
   var cursor = 0;
   var tempData = [];
+  var indent = 0;
+  var breaksCount;
+  var lastBreakAt;
+  var newIndent;
+  var saveWaypoints = this.saveWaypoints;
 
   for (; nextEnd < data.length;) {
     nextStart = data.indexOf(EXPRESSION_PREFIX, nextEnd);
@@ -62,10 +70,21 @@ ExpressionsProcessor.prototype.escape = function (data) {
     nextEnd = findEnd(data, nextStart);
 
     var expression = data.substring(nextStart, nextEnd);
-    var placeholder = this.expressions.store(expression);
+    if (saveWaypoints) {
+      breaksCount = expression.split(lineBreak).length - 1;
+      lastBreakAt = expression.lastIndexOf(lineBreak);
+      newIndent = lastBreakAt > 0 ?
+        expression.substring(lastBreakAt + lineBreak.length).length :
+        indent + expression.length;
+    }
+
+    var metadata = saveWaypoints ? [breaksCount, newIndent] : null;
+    var placeholder = this.expressions.store(expression, metadata);
     tempData.push(data.substring(cursor, nextStart));
     tempData.push(placeholder);
 
+    if (saveWaypoints)
+      indent = newIndent + 1;
     cursor = nextEnd;
   }
 
index 798de3b..44a0eb3 100644 (file)
@@ -2,26 +2,28 @@ var vows = require('vows');
 var assert = require('assert');
 var ExpressionsProcessor = require('../../lib/text/expressions-processor');
 
-function processorContext(context) {
+var lineBreak = require('os').EOL;
+
+function processorContext(name, context, saveWaypoints) {
   var vowContext = {};
 
   function escaped (targetCSS) {
     return function (sourceCSS) {
-      var result = new ExpressionsProcessor().escape(sourceCSS);
+      var result = new ExpressionsProcessor(saveWaypoints).escape(sourceCSS);
       assert.equal(result, targetCSS);
     };
   }
 
   function restored (targetCSS) {
     return function (sourceCSS) {
-      var processor = new ExpressionsProcessor();
+      var processor = new ExpressionsProcessor(saveWaypoints);
       var result = processor.restore(processor.escape(sourceCSS));
       assert.equal(result, targetCSS);
     };
   }
 
   for (var key in context) {
-    vowContext[key] = {
+    vowContext[name + ' - ' + key] = {
       topic: context[key][0],
       escaped: escaped(context[key][1]),
       restored: restored(context[key][2])
@@ -33,7 +35,7 @@ function processorContext(context) {
 
 vows.describe(ExpressionsProcessor)
   .addBatch(
-    processorContext({
+    processorContext('basic', {
       'empty': [
         'a{color:expression()}',
         'a{color:__ESCAPED_EXPRESSION_CLEAN_CSS0__}',
@@ -81,4 +83,23 @@ vows.describe(ExpressionsProcessor)
       ]
     })
   )
+  .addBatch(
+    processorContext('waypoints', {
+      'empty': [
+        'a{color:expression()}',
+        'a{color:__ESCAPED_EXPRESSION_CLEAN_CSS0(0,12)__}',
+        'a{color:expression()}'
+      ],
+      'method call': [
+        'a{color:expression(this.parentNode.currentStyle.color)}',
+        'a{color:__ESCAPED_EXPRESSION_CLEAN_CSS0(0,46)__}',
+        'a{color:expression(this.parentNode.currentStyle.color)}'
+      ],
+      'line break call': [
+        'a{color:expression(' + lineBreak + 'this.parentNode.currentStyle.color)}',
+        'a{color:__ESCAPED_EXPRESSION_CLEAN_CSS0(1,35)__}',
+        'a{color:expression(' + lineBreak + 'this.parentNode.currentStyle.color)}'
+      ]
+    }, true)
+  )
   .export(module);