Moves quotation matching into a QuoteScanner class.
authorJakub Pawlowicz <jakub@goalsmashers.com>
Sat, 1 Mar 2014 04:46:18 +0000 (04:46 +0000)
committerJakub Pawlowicz <jakub@goalsmashers.com>
Sat, 1 Mar 2014 23:35:12 +0000 (23:35 +0000)
History.md
lib/text/free.js
lib/text/quote-scanner.js [new file with mode: 0644]

index 245ba2c..83281c2 100644 (file)
@@ -2,6 +2,7 @@
 ==================
 
 * Adds a better non-adjacent optimizer compatible with the upcoming new property optimizer.
+* Moves quotation matching into a QuoteScanner class.
 * Fixed issue [#247](https://github.com/GoalSmashers/clean-css/issues/247) - removes deprecated `selectorsMergeMode` switch.
 
 [2.1.4 / 2014-03-01](https://github.com/GoalSmashers/clean-css/compare/v2.1.3...v2.1.4)
index ea30368..97f24e5 100644 (file)
@@ -1,76 +1,26 @@
-var EscapeStore = require('./escape-store');
+(function() {
+  var EscapeStore = require('./escape-store');
+  var QuoteScanner = require('./quote-scanner');
 
-module.exports = function Free() {
-  var texts = new EscapeStore('FREE_TEXT');
-
-  var findNonEscapedEnd = function(data, matched, start) {
-    var end = start;
-    while (true) {
-      end = data.indexOf(matched, end);
-
-      if (end > -1 && data[end - 1] == '\\') {
-        end += 1;
-        continue;
-      } else {
-        break;
-      }
-    }
-
-    return end;
+  var Free = function Free() {
+    this.matches = new EscapeStore('FREE_TEXT');
   };
 
-  return {
-    // Strip content tags by replacing them by the a special
-    // marker for further restoring. It's done via string scanning
-    // instead of regexps to speed up the process.
-    escape: function(data) {
-      var tempData = [];
-      var nextStart = 0;
-      var nextEnd = 0;
-      var cursor = 0;
-      var matchedParenthesis = null;
-      var singleParenthesis = '\'';
-      var doubleParenthesis = '"';
-      var dataLength = data.length;
-
-      for (; nextEnd < data.length;) {
-        var nextStartSingle = data.indexOf(singleParenthesis, nextEnd + 1);
-        var nextStartDouble = data.indexOf(doubleParenthesis, nextEnd + 1);
-
-        if (nextStartSingle == -1)
-          nextStartSingle = dataLength;
-        if (nextStartDouble == -1)
-          nextStartDouble = dataLength;
-
-        if (nextStartSingle < nextStartDouble) {
-          nextStart = nextStartSingle;
-          matchedParenthesis = singleParenthesis;
-        } else {
-          nextStart = nextStartDouble;
-          matchedParenthesis = doubleParenthesis;
-        }
+  // Strip content tags by replacing them by the a special
+  // marker for further restoring. It's done via string scanning
+  // instead of regexps to speed up the process.
+  Free.prototype.escape = function(data) {
+    var self = this;
 
-        if (nextStart == -1)
-          break;
-
-        nextEnd = findNonEscapedEnd(data, matchedParenthesis, nextStart + 1);
-        if (nextEnd == -1)
-          break;
-
-        var text = data.substring(nextStart, nextEnd + 1);
-        var placeholder = texts.store(text);
-        tempData.push(data.substring(cursor, nextStart));
-        tempData.push(placeholder);
-        cursor = nextEnd + 1;
-      }
-
-      return tempData.length > 0 ?
-        tempData.join('') + data.substring(cursor, data.length) :
-        data;
-    },
+    return new QuoteScanner(data).each(function(match, store) {
+      var placeholder = self.matches.store(match);
+      store.push(placeholder);
+    });
+  };
 
-    restore: function(data) {
-      return data.replace(texts.placeholderRegExp, texts.restore);
-    }
+  Free.prototype.restore = function(data) {
+    return data.replace(this.matches.placeholderRegExp, this.matches.restore);
   };
-};
+
+  module.exports = Free;
+})();
diff --git a/lib/text/quote-scanner.js b/lib/text/quote-scanner.js
new file mode 100644 (file)
index 0000000..4bab694
--- /dev/null
@@ -0,0 +1,70 @@
+(function() {
+  var QuoteScanner = function QuoteScanner(data) {
+    this.data = data;
+  };
+
+  var findNonEscapedEnd = function(data, matched, start) {
+    var end = start;
+    while (true) {
+      end = data.indexOf(matched, end);
+
+      if (end > -1 && data[end - 1] == '\\') {
+        end += 1;
+        continue;
+      } else {
+        break;
+      }
+    }
+
+    return end;
+  };
+
+  QuoteScanner.prototype.each = function(callback) {
+    var data = this.data;
+    var tempData = [];
+    var nextStart = 0;
+    var nextEnd = 0;
+    var cursor = 0;
+    var matchedMark = null;
+    var singleMark = '\'';
+    var doubleMark = '"';
+    var dataLength = data.length;
+
+    for (; nextEnd < data.length;) {
+      var nextStartSingle = data.indexOf(singleMark, nextEnd + 1);
+      var nextStartDouble = data.indexOf(doubleMark, nextEnd + 1);
+
+      if (nextStartSingle == -1)
+        nextStartSingle = dataLength;
+      if (nextStartDouble == -1)
+        nextStartDouble = dataLength;
+
+      if (nextStartSingle < nextStartDouble) {
+        nextStart = nextStartSingle;
+        matchedMark = singleMark;
+      } else {
+        nextStart = nextStartDouble;
+        matchedMark = doubleMark;
+      }
+
+      if (nextStart == -1)
+        break;
+
+      nextEnd = findNonEscapedEnd(data, matchedMark, nextStart + 1);
+      if (nextEnd == -1)
+        break;
+
+      var text = data.substring(nextStart, nextEnd + 1);
+      tempData.push(data.substring(cursor, nextStart));
+      callback(text, tempData);
+
+      cursor = nextEnd + 1;
+    }
+
+    return tempData.length > 0 ?
+      tempData.join('') + data.substring(cursor, data.length) :
+      data;
+  };
+
+  module.exports = QuoteScanner;
+})();