Unifies wrappers for simple & advanced optimizations.
authorJakub Pawlowicz <contact@jakubpawlowicz.com>
Fri, 10 Jul 2015 06:54:06 +0000 (07:54 +0100)
committerJakub Pawlowicz <contact@jakubpawlowicz.com>
Wed, 22 Jul 2015 07:00:42 +0000 (08:00 +0100)
Previously we had two wrappings, one for simple optimizations (just importance
and hacks), and other for advanced optimizations.

Right now it's just one (the latter) with simple optimizations adapted to
use the wrapping. This way it's more readable & prepares us for simplifying
the code further.

24 files changed:
History.md
lib/clean.js
lib/properties/optimizer.js
lib/properties/override-compactor.js
lib/properties/restore-from-optimizing.js [new file with mode: 0644]
lib/properties/restore-shorthands.js [deleted file]
lib/properties/shorthand-compactor.js
lib/properties/wrap-for-optimizing.js
lib/selectors/optimization-metadata.js [deleted file]
lib/selectors/simple.js
lib/stringifier/helpers.js
test/properties/longhand-overriding-test.js
test/properties/optimizer-test.js
test/properties/override-compacting-test.js
test/properties/populate-components-test.js
test/properties/restore-from-optimizing-test.js [new file with mode: 0644]
test/properties/restore-shorthands-test.js [deleted file]
test/properties/shorthand-compacting-source-maps-test.js
test/properties/shorthand-compacting-test.js
test/properties/wrap-for-optimizing-test.js
test/selectors/extractor-test.js
test/selectors/optimization-metadata-test.js [deleted file]
test/selectors/simple-test.js
test/test-helper.js

index 773b871..c6c8727 100644 (file)
@@ -1,6 +1,7 @@
 [3.4.0 / 2015-xx-xx](https://github.com/jakubpawlowicz/clean-css/compare/v3.3.6...master)
 ==================
 
+* Unifies wrappers for simple & advanced optimizations.
 * Fixed issue [#599](https://github.com/jakubpawlowicz/clean-css/issues/599) - support for inlined source maps.
 
 [3.3.6 / 2015-07-14](https://github.com/jakubpawlowicz/clean-css/compare/v3.3.5...v3.3.6)
index 5ca4634..aa47cd1 100644 (file)
@@ -11,7 +11,6 @@ var rebaseUrls = require('./urls/rebase');
 var tokenize = require('./tokenizer/tokenize');
 var simpleOptimize = require('./selectors/simple');
 var advancedOptimize = require('./selectors/advanced');
-var addOptimizationMetadata = require('./selectors/optimization-metadata');
 
 var simpleStringify = require('./stringifier/simple');
 var sourceMapStringify = require('./stringifier/source-maps');
@@ -201,8 +200,6 @@ function minify(context, data) {
 
   var tokens = tokenize(data, context);
 
-  addOptimizationMetadata(tokens);
-
   simpleOptimize(tokens, options);
 
   if (options.advanced)
index d632214..54c7c12 100644 (file)
@@ -4,7 +4,7 @@ var populateComponents = require('./populate-components');
 var compactOverrides = require('./override-compactor');
 var compactShorthands = require('./shorthand-compactor');
 var removeUnused = require('./remove-unused');
-var restoreShorthands = require('./restore-shorthands');
+var restoreFromOptimizing = require('./restore-from-optimizing');
 var stringifyProperty = require('../stringifier/one-time').property;
 
 var shorthands = {
@@ -193,7 +193,7 @@ function optimize(selector, properties, mergeAdjacent, withCompacting, options,
     compactShorthands(_properties, options.sourceMap, validator);
   }
 
-  restoreShorthands(_properties);
+  restoreFromOptimizing(_properties);
   removeUnused(_properties);
 }
 
index 8f5c869..a8a1eb9 100644 (file)
@@ -3,7 +3,7 @@ var compactable = require('./compactable');
 var deepClone = require('./clone').deep;
 var shallowClone = require('./clone').shallow;
 var hasInherit = require('./has-inherit');
-var restoreShorthands = require('./restore-shorthands');
+var restoreFromOptimizing = require('./restore-from-optimizing');
 var everyCombination = require('./every-combination');
 var sameVendorPrefixesIn = require('./vendor-prefixes').same;
 
@@ -152,10 +152,10 @@ function wouldResultInLongerValue(left, right) {
   var component;
 
   var multiplexClone = deepClone(multiplex);
-  restoreShorthands([multiplexClone]);
+  restoreFromOptimizing([multiplexClone]);
 
   var simpleClone = deepClone(simple);
-  restoreShorthands([simpleClone]);
+  restoreFromOptimizing([simpleClone]);
 
   var lengthBefore = lengthOf(multiplexClone) + 1 + lengthOf(simpleClone);
 
@@ -168,7 +168,7 @@ function wouldResultInLongerValue(left, right) {
     overrideByMultiplex(component, multiplexClone);
   }
 
-  restoreShorthands([simpleClone]);
+  restoreFromOptimizing([simpleClone]);
 
   var lengthAfter = lengthOf(simpleClone);
 
diff --git a/lib/properties/restore-from-optimizing.js b/lib/properties/restore-from-optimizing.js
new file mode 100644 (file)
index 0000000..da0cbf6
--- /dev/null
@@ -0,0 +1,57 @@
+var compactable = require('./compactable');
+
+var BACKSLASH_HACK = '\\9';
+var IMPORTANT_TOKEN = '!important';
+var STAR_HACK = '*';
+var UNDERSCORE_HACK = '_';
+
+function restoreImportant(property) {
+  property.value[property.value.length - 1][0] += IMPORTANT_TOKEN;
+}
+
+function restoreHack(property) {
+  if (property.hack == 'underscore')
+    property.name = UNDERSCORE_HACK + property.name;
+  else if (property.hack == 'star')
+    property.name = STAR_HACK + property.name;
+  else if (property.hack == 'suffix')
+    property.value[property.value.length - 1][0] += BACKSLASH_HACK;
+}
+
+function restoreFromOptimizing(properties, simpleMode) {
+  for (var i = properties.length - 1; i >= 0; i--) {
+    var property = properties[i];
+    var descriptor = compactable[property.name];
+    var restored;
+
+    if (property.unused)
+      continue;
+
+    if (!property.dirty && !property.important && !property.hack)
+      continue;
+
+    if (!simpleMode && descriptor && descriptor.shorthand) {
+      restored = descriptor.restore(property, compactable);
+      property.value = restored;
+    } else {
+      restored = property.value;
+    }
+
+    if (property.important)
+      restoreImportant(property);
+
+    if (property.hack)
+      restoreHack(property);
+
+    if (!('all' in property))
+      continue;
+
+    var current = property.all[property.position];
+    current[0][0] = property.name;
+
+    current.splice(1, current.length - 1);
+    Array.prototype.push.apply(current, restored);
+  }
+}
+
+module.exports = restoreFromOptimizing;
diff --git a/lib/properties/restore-shorthands.js b/lib/properties/restore-shorthands.js
deleted file mode 100644 (file)
index eff2f86..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-var compactable = require('./compactable');
-
-function restoreShorthands(properties) {
-  for (var i = properties.length - 1; i >= 0; i--) {
-    var property = properties[i];
-    var descriptor = compactable[property.name];
-
-    if (descriptor && descriptor.shorthand && property.dirty && !property.unused) {
-      var restored = descriptor.restore(property, compactable);
-      property.value = restored;
-
-      if (!('all' in property))
-        continue;
-
-      var current = property.all[property.position];
-      current.splice(1, current.length - 1);
-
-      Array.prototype.push.apply(current, restored);
-    }
-  }
-}
-
-module.exports = restoreShorthands;
index be22088..e378ba3 100644 (file)
@@ -35,7 +35,7 @@ function componentSourceMaps(components) {
 
 function replaceWithShorthand(properties, candidateComponents, name, sourceMaps, validator) {
   var descriptor = compactable[name];
-  var newValuePlaceholder = [[name, false, false], [descriptor.defaultValue]];
+  var newValuePlaceholder = [[name], [descriptor.defaultValue]];
   var all;
 
   var newProperty = wrapSingle(newValuePlaceholder);
@@ -73,7 +73,6 @@ function replaceWithShorthand(properties, candidateComponents, name, sourceMaps,
   newProperty.position = all.length;
   newProperty.all = all;
   newProperty.all.push(newValuePlaceholder);
-  newValuePlaceholder[0][1] = newProperty.important;
 
   properties.push(newProperty);
 }
index 650521f..aa4b67b 100644 (file)
@@ -1,3 +1,8 @@
+var BACKSLASH_HACK = '\\';
+var IMPORTANT_TOKEN = '!important';
+var STAR_HACK = '*';
+var UNDERSCORE_HACK = '_';
+
 function wrapAll(properties) {
   var wrapped = [];
 
@@ -23,12 +28,63 @@ function isMultiplex(property) {
   return false;
 }
 
+function hackType(property) {
+  var type = false;
+  var name = property[0][0];
+  var lastValue = property[property.length - 1];
+
+  if (name[0] == UNDERSCORE_HACK) {
+    type = 'underscore';
+  } else if (name[0] == STAR_HACK) {
+    type = 'star';
+  } else if (lastValue[0].indexOf(BACKSLASH_HACK) > 0 && lastValue[0].indexOf(BACKSLASH_HACK) == lastValue[0].length - BACKSLASH_HACK.length - 1) {
+    type = 'suffix';
+  } else if (lastValue[0].indexOf(BACKSLASH_HACK) === 0 && lastValue[0].length == 2) {
+    type = 'suffix';
+  }
+
+  return type;
+}
+
+function isImportant(property) {
+  return property.length > 1 ?
+    property[property.length - 1][0].indexOf(IMPORTANT_TOKEN) > 0 :
+    false;
+}
+
+function stripImportant(property) {
+  if (property.length > 0)
+    property[property.length - 1][0] = property[property.length - 1][0].replace(IMPORTANT_TOKEN, '');
+}
+
+function stripPrefixHack(property) {
+  property[0][0] = property[0][0].substring(1);
+}
+
+function stripSuffixHack(property) {
+  var lastValue = property[property.length - 1];
+  lastValue[0] = lastValue[0].substring(0, lastValue[0].length - BACKSLASH_HACK.length - 1);
+
+  if (lastValue[0].length === 0)
+    property.pop();
+}
+
 function wrapSingle(property) {
+  var _isImportant = isImportant(property);
+  if (_isImportant)
+    stripImportant(property);
+
+  var _hackType = hackType(property);
+  if (_hackType == 'star' || _hackType == 'underscore')
+    stripPrefixHack(property);
+  else if (_hackType == 'suffix')
+    stripSuffixHack(property);
+
   return {
     components: [],
     dirty: false,
-    hack: property[0][2],
-    important: property[0][1],
+    hack: _hackType,
+    important: _isImportant,
     name: property[0][0],
     multiplex: property.length > 2 ? isMultiplex(property) : false,
     position: 0,
diff --git a/lib/selectors/optimization-metadata.js b/lib/selectors/optimization-metadata.js
deleted file mode 100644 (file)
index 566b9e3..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-// TODO: we should wrap it under `wrap for optimizing`
-
-var BACKSLASH_HACK = '\\';
-var IMPORTANT = '!important';
-var STAR_HACK = '*';
-var UNDERSCORE_HACK = '_';
-
-function addOptimizationMetadata(tokens) {
-  for (var i = tokens.length - 1; i >= 0; i--) {
-    var token = tokens[i];
-
-    switch (token[0]) {
-      case 'flat-block':
-      case 'selector':
-        addToProperties(token[2]);
-        break;
-      case 'block':
-        addOptimizationMetadata(token[2]);
-        break;
-    }
-  }
-}
-
-function addToProperties(properties) {
-  for (var i = properties.length - 1; i >= 0; i--) {
-    if (typeof properties[i] != 'string')
-      addToProperty(properties[i]);
-  }
-}
-
-function addToProperty(property) {
-  var name = property[0][0];
-  var lastValue = property[property.length - 1];
-  var isImportant = lastValue[0].indexOf(IMPORTANT) > 0;
-  var hackType = false;
-
-  if (name[0] == UNDERSCORE_HACK) {
-    property[0][0] = name.substring(1);
-    hackType = 'underscore';
-  } else if (name[0] == STAR_HACK) {
-    property[0][0] = name.substring(1);
-    hackType = 'star';
-  } else if (lastValue[0].indexOf(BACKSLASH_HACK) > 0 && lastValue[0].indexOf(BACKSLASH_HACK) == lastValue[0].length - BACKSLASH_HACK.length - 1) {
-    lastValue[0] = lastValue[0].substring(0, lastValue[0].length - BACKSLASH_HACK.length - 1);
-    hackType = 'suffix';
-  } else if (lastValue[0].indexOf(BACKSLASH_HACK) === 0 && lastValue[0].length == 2) {
-    property.pop();
-    hackType = 'suffix';
-  }
-
-  // TODO: this should be done at tokenization step
-  // with adding importance info
-  if (isImportant)
-    lastValue[0] = lastValue[0].substring(0, lastValue[0].length - IMPORTANT.length);
-
-  property[0].splice(1, 0, isImportant, hackType);
-}
-
-module.exports = addOptimizationMetadata;
index 71e42cd..87af093 100644 (file)
@@ -7,6 +7,10 @@ var RGB = require('../colors/rgb');
 var HSL = require('../colors/hsl');
 var HexNameShortener = require('../colors/hex-name-shortener');
 
+var wrapForOptimizing = require('../properties/wrap-for-optimizing').all;
+var restoreFromOptimizing = require('../properties/restore-from-optimizing');
+var removeUnused = require('../properties/remove-unused');
+
 var DEFAULT_ROUNDING_PRECISION = 2;
 var CHARSET_TOKEN = '@charset';
 var CHARSET_REGEXP = new RegExp('^' + CHARSET_TOKEN, 'i');
@@ -17,7 +21,7 @@ var FONT_NAME_WEIGHTS_WITHOUT_NORMAL = ['bold', 'bolder', 'lighter'];
 
 var valueMinifiers = {
   'background': function (value, index, total) {
-    return index == 1 && total == 2 && (value == 'none' || value == 'transparent') ? '0 0' : value;
+    return index === 0 && total == 1 && (value == 'none' || value == 'transparent') ? '0 0' : value;
   },
   'font-weight': function (value) {
     if (value == 'normal')
@@ -28,12 +32,12 @@ var valueMinifiers = {
       return value;
   },
   'outline': function (value, index, total) {
-    return index == 1 && total == 2 && value == 'none' ? '0' : value;
+    return index === 0 && total == 1 && value == 'none' ? '0' : value;
   }
 };
 
 function isNegative(property, idx) {
-  return property[idx] && property[idx][0][0] == '-' && parseFloat(property[idx][0]) < 0;
+  return property.value[idx] && property.value[idx][0][0] == '-' && parseFloat(property.value[idx][0]) < 0;
 }
 
 function zeroMinifier(name, value) {
@@ -102,11 +106,19 @@ function unitMinifier(name, value, unitsRegexp) {
 }
 
 function multipleZerosMinifier(property) {
-  if (property.length == 5 && property[1][0] === '0' && property[2][0] === '0' && property[3][0] === '0' && property[4][0] === '0') {
-    if (property[0][0].indexOf('box-shadow') > -1)
-      property.splice(3);
+  var values = property.value;
+  var spliceAt;
+
+  if (values.length == 4 && values[0][0] === '0' && values[1][0] === '0' && values[2][0] === '0' && values[3][0] === '0') {
+    if (property.name.indexOf('box-shadow') > -1)
+      spliceAt = 2;
     else
-      property.splice(2);
+      spliceAt = 1;
+  }
+
+  if (spliceAt) {
+    property.value.splice(spliceAt);
+    property.dirty = true;
   }
 }
 
@@ -156,99 +168,98 @@ function colorMininifier(_, value, compatibility) {
 }
 
 function minifyBorderRadius(property) {
-  if (property.length == 4 && property[2][0] == '/' && property[1][0] == property[3][0])
-    property.splice(2);
-  else if (property.length == 6 && property[3][0] == '/' && property[1][0] == property[4][0] && property[2][0] == property[5][0])
-    property.splice(3);
-  else if (property.length == 8 && property[4][0] == '/' && property[1][0] == property[5][0] && property[2][0] == property[6][0] && property[3][0] == property[7][0])
-    property.splice(4);
-  else if (property.length == 10 && property[5][0] == '/' && property[1][0] == property[6][0] && property[2][0] == property[7][0] && property[3][0] == property[8][0] && property[4][0] == property[9][0])
-    property.splice(5);
+  var values = property.value;
+  var spliceAt;
+
+  if (values.length == 3 && values[1][0] == '/' && values[0][0] == values[2][0])
+    spliceAt = 1;
+  else if (values.length == 5 && values[2][0] == '/' && values[0][0] == values[3][0] && values[1][0] == values[4][0])
+    spliceAt = 2;
+  else if (values.length == 7 && values[3][0] == '/' && values[0][0] == values[4][0] && values[1][0] == values[5][0] && values[2][0] == values[6][0])
+    spliceAt = 3;
+  else if (values.length == 9 && values[4][0] == '/' && values[0][0] == values[5][0] && values[1][0] == values[6][0] && values[2][0] == values[7][0] && values[3][0] == values[8][0])
+    spliceAt = 4;
+
+  if (spliceAt) {
+    property.value.splice(spliceAt);
+    property.dirty = true;
+  }
 }
 
 function minifyFilter(property) {
-  if (property.length < 3) {
-    property[1][0] = property[1][0].replace(/progid:DXImageTransform\.Microsoft\.(Alpha|Chroma)(\W)/, function (match, filter, suffix) {
+  if (property.value.length == 1) {
+    property.value[0][0] = property.value[0][0].replace(/progid:DXImageTransform\.Microsoft\.(Alpha|Chroma)(\W)/, function (match, filter, suffix) {
       return filter.toLowerCase() + suffix;
     });
   }
 
-  property[1][0] = property[1][0]
+  property.value[0][0] = property.value[0][0]
     .replace(/,(\S)/g, ', $1')
     .replace(/ ?= ?/g, '=');
 }
 
 function minifyFont(property) {
-  var hasNumeral = FONT_NUMERAL_WEIGHTS.indexOf(property[1][0]) > -1 ||
-    property[2] && FONT_NUMERAL_WEIGHTS.indexOf(property[2][0]) > -1 ||
-    property[3] && FONT_NUMERAL_WEIGHTS.indexOf(property[3][0]) > -1;
+  var values = property.value;
+  var hasNumeral = FONT_NUMERAL_WEIGHTS.indexOf(values[0][0]) > -1 ||
+    values[1] && FONT_NUMERAL_WEIGHTS.indexOf(values[1][0]) > -1 ||
+    values[2] && FONT_NUMERAL_WEIGHTS.indexOf(values[2][0]) > -1;
 
   if (hasNumeral)
     return;
 
-  if (property[2] == '/')
+  if (values[1] == '/')
     return;
 
   var normalCount = 0;
-  if (property[1][0] == 'normal')
+  if (values[0][0] == 'normal')
     normalCount++;
-  if (property[2] && property[2][0] == 'normal')
+  if (values[1] && values[1][0] == 'normal')
     normalCount++;
-  if (property[3] && property[3][0] == 'normal')
+  if (values[2] && values[2][0] == 'normal')
     normalCount++;
 
   if (normalCount > 1)
     return;
 
   var toOptimize;
-  if (FONT_NAME_WEIGHTS_WITHOUT_NORMAL.indexOf(property[1][0]) > -1)
+  if (FONT_NAME_WEIGHTS_WITHOUT_NORMAL.indexOf(values[0][0]) > -1)
+    toOptimize = 0;
+  else if (values[1] && FONT_NAME_WEIGHTS_WITHOUT_NORMAL.indexOf(values[1][0]) > -1)
     toOptimize = 1;
-  else if (property[2] && FONT_NAME_WEIGHTS_WITHOUT_NORMAL.indexOf(property[2][0]) > -1)
+  else if (values[2] && FONT_NAME_WEIGHTS_WITHOUT_NORMAL.indexOf(values[2][0]) > -1)
     toOptimize = 2;
-  else if (property[3] && FONT_NAME_WEIGHTS_WITHOUT_NORMAL.indexOf(property[3][0]) > -1)
-    toOptimize = 3;
-  else if (FONT_NAME_WEIGHTS.indexOf(property[1][0]) > -1)
+  else if (FONT_NAME_WEIGHTS.indexOf(values[0][0]) > -1)
+    toOptimize = 0;
+  else if (values[1] && FONT_NAME_WEIGHTS.indexOf(values[1][0]) > -1)
     toOptimize = 1;
-  else if (property[2] && FONT_NAME_WEIGHTS.indexOf(property[2][0]) > -1)
+  else if (values[2] && FONT_NAME_WEIGHTS.indexOf(values[2][0]) > -1)
     toOptimize = 2;
-  else if (property[3] && FONT_NAME_WEIGHTS.indexOf(property[3][0]) > -1)
-    toOptimize = 3;
 
-  if (toOptimize)
-    property[toOptimize][0] = valueMinifiers['font-weight'](property[toOptimize][0]);
+  if (toOptimize !== undefined) {
+    property.value[toOptimize][0] = valueMinifiers['font-weight'](values[toOptimize][0]);
+    property.dirty = true;
+  }
 }
 
 function optimizeBody(properties, options) {
-  var property, name, value, unused;
-
-  for (var i = 0, l = properties.length; i < l; i++) {
-    unused = false;
-    property = properties[i];
+  var property, name, value;
+  var _properties = wrapForOptimizing(properties);
 
-    // FIXME: the check should be gone with #407
-    if (typeof property == 'string' && property.indexOf('__ESCAPED_') === 0)
-      continue;
-
-    name = property[0][0];
+  for (var i = 0, l = _properties.length; i < l; i++) {
+    property = _properties[i];
+    name = property.name;
 
-    var hackType = property[0][2];
-    if (hackType) {
-      if ((hackType == 'star' || hackType == 'underscore') && !options.compatibility.properties.iePrefixHack || hackType == 'suffix' && !options.compatibility.properties.ieSuffixHack)
-        unused = true;
-    }
+    if (property.hack && ((property.hack == 'star' || property.hack == 'underscore') && !options.compatibility.properties.iePrefixHack || property.hack == 'suffix' && !options.compatibility.properties.ieSuffixHack))
+      property.unused = true;
 
-    if (name.indexOf('padding') === 0 && (isNegative(property, 1) || isNegative(property, 2) || isNegative(property, 3) || isNegative(property, 4)))
-      unused = true;
+    if (name.indexOf('padding') === 0 && (isNegative(property, 0) || isNegative(property, 1) || isNegative(property, 2) || isNegative(property, 3)))
+      property.unused = true;
 
-    if (unused) {
-      properties.splice(i, 1);
-      i--;
-      l--;
+    if (property.unused)
       continue;
-    }
 
-    for (var j = 1, m = property.length; j < m; j++) {
-      value = property[j][0];
+    for (var j = 0, m = property.value.length; j < m; j++) {
+      value = property.value[j][0];
 
       if (valueMinifiers[name])
         value = valueMinifiers[name](value, j, m);
@@ -263,7 +274,7 @@ function optimizeBody(properties, options) {
       if (options.compatibility.properties.colors)
         value = colorMininifier(name, value, options.compatibility);
 
-      property[j][0] = value;
+      property.value[j][0] = value;
     }
 
     multipleZerosMinifier(property);
@@ -275,6 +286,9 @@ function optimizeBody(properties, options) {
     else if (name == 'font')
       minifyFont(property);
   }
+
+  removeUnused(_properties);
+  restoreFromOptimizing(_properties, true);
 }
 
 function cleanupCharsets(tokens) {
index beef602..0786c24 100644 (file)
@@ -1,9 +1,5 @@
 var lineBreak = require('os').EOL;
 
-var STAR_HACK = '*';
-var SUFFIX_HACK = '\\9';
-var UNDERSCORE_HACK = '_';
-
 function hasMoreProperties(tokens, index) {
   for (var i = index, l = tokens.length; i < l; i++) {
     if (typeof tokens[i] != 'string')
@@ -53,14 +49,6 @@ function inSpecialContext(token, valueIndex, context) {
     afterComma(token, valueIndex);
 }
 
-function storePrefixHack(name, context) {
-  var hackType = name[2];
-  if (hackType == 'underscore')
-    context.store(UNDERSCORE_HACK, context);
-  else if (hackType == 'star')
-    context.store(STAR_HACK, context);
-}
-
 function selectors(tokens, context) {
   var store = context.store;
 
@@ -85,7 +73,6 @@ function property(tokens, position, isLast, context) {
   if (typeof token == 'string') {
     store(token, context);
   } else {
-    storePrefixHack(token[0], context);
     store(token[0], context);
     store(':', context);
     value(tokens, position, isLast, context);
@@ -95,17 +82,10 @@ function property(tokens, position, isLast, context) {
 function value(tokens, position, isLast, context) {
   var store = context.store;
   var token = tokens[position];
-  var isImportant = token[0][1];
-  var hackType = token[0][2];
 
   for (var j = 1, m = token.length; j < m; j++) {
     store(token[j], context);
 
-    if (j == m - 1 && hackType == 'suffix')
-      store(SUFFIX_HACK, context);
-    if (j == m - 1 && isImportant)
-      store('!important', context);
-
     if (j < m - 1 && (inFilter(token) || !inSpecialContext(token, j, context))) {
       store(' ', context);
     } else if (j == m - 1 && !isLast && hasMoreProperties(tokens, position + 1)) {
index fc3d01f..80c7141 100644 (file)
@@ -7,7 +7,6 @@ var tokenize = require('../../lib/tokenizer/tokenize');
 var SourceTracker = require('../../lib/utils/source-tracker');
 var Compatibility = require('../../lib/utils/compatibility');
 var Validator = require('../../lib/properties/validator');
-var addOptimizationMetadata = require('../../lib/selectors/optimization-metadata');
 
 function _optimize(source) {
   var tokens = tokenize(source, {
@@ -16,8 +15,6 @@ function _optimize(source) {
     warnings: []
   });
 
-  addOptimizationMetadata(tokens);
-
   var compatibility = new Compatibility().toOptions();
   var validator = new Validator(compatibility);
   optimize(tokens[0][1], tokens[0][2], false, true, { compatibility: compatibility, aggressiveMerging: true, shorthandCompacting: true }, validator);
@@ -34,7 +31,7 @@ function longhandFirst(prefixedLonghand, prefixedShorthand, zeroValue) {
       assert.lengthOf(body, 1);
     },
     'has zero value only': function (body) {
-      assert.deepEqual(body[0][0], [prefixedShorthand, false, false]);
+      assert.deepEqual(body[0][0], [prefixedShorthand]);
       assert.deepEqual(body[0][1], [zeroValue]);
     }
   };
@@ -49,11 +46,11 @@ function shorthandFirst(prefixedLonghand, prefixedShorthand, zeroValue) {
       assert.lengthOf(body, 2);
     },
     'first is shorthand': function (body) {
-      assert.deepEqual(body[0][0], [prefixedShorthand, false, false]);
+      assert.deepEqual(body[0][0], [prefixedShorthand]);
       assert.deepEqual(body[0][1], [zeroValue]);
     },
     'second is longhand': function (body) {
-      assert.deepEqual(body[1][0], [prefixedLonghand, false, false]);
+      assert.deepEqual(body[1][0], [prefixedLonghand]);
       assert.deepEqual(body[1][1], ['inherit']);
     }
   };
index 2933e11..565e91d 100644 (file)
@@ -7,8 +7,6 @@ var tokenize = require('../../lib/tokenizer/tokenize');
 var SourceTracker = require('../../lib/utils/source-tracker');
 var Compatibility = require('../../lib/utils/compatibility');
 var Validator = require('../../lib/properties/validator');
-var addOptimizationMetadata = require('../../lib/selectors/optimization-metadata');
-
 
 function _optimize(source, mergeAdjacent, aggressiveMerging, compatibilityOptions) {
   var compatibility = new Compatibility(compatibilityOptions).toOptions();
@@ -20,7 +18,6 @@ function _optimize(source, mergeAdjacent, aggressiveMerging, compatibilityOption
     warnings: []
   });
 
-  addOptimizationMetadata(tokens);
   optimize(tokens[0][1], tokens[0][2], mergeAdjacent, true, { compatibility: compatibility, aggressiveMerging: aggressiveMerging }, validator);
 
   return tokens[0][2];
@@ -32,8 +29,8 @@ vows.describe(optimize)
       'topic': 'a{display:-moz-inline-box;display:inline-block}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['display', false, false], ['-moz-inline-box']],
-          [['display', false, false], ['inline-block']]
+          [['display'], ['-moz-inline-box']],
+          [['display'], ['inline-block']]
         ]);
       }
     },
@@ -41,8 +38,8 @@ vows.describe(optimize)
       'topic': 'a{display:inline-block;color:red;display:block}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['color', false , false], ['red']],
-          [['display', false , false], ['block']]
+          [['color'], ['red']],
+          [['display'], ['block']]
         ]);
       }
     },
@@ -50,8 +47,8 @@ vows.describe(optimize)
       'topic': 'a{display:inline-block!important;color:red;display:block}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['display', true , false], ['inline-block']],
-          [['color', false , false], ['red']]
+          [['display'], ['inline-block!important']],
+          [['color'], ['red']]
         ]);
       }
     },
@@ -59,8 +56,8 @@ vows.describe(optimize)
       'topic': 'a{display:inline-block;color:red;display:block!important}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['color', false , false], ['red']],
-          [['display', true , false], ['block']]
+          [['color'], ['red']],
+          [['display'], ['block!important']]
         ]);
       }
     },
@@ -68,8 +65,8 @@ vows.describe(optimize)
       'topic': 'a{display:inline-block!important;color:red;display:block!important}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['color', false , false], ['red']],
-          [['display', true , false], ['block']]
+          [['color'], ['red']],
+          [['display'], ['block!important']]
         ]);
       }
     },
@@ -77,10 +74,10 @@ vows.describe(optimize)
       'topic': 'a{display:inline-block;color:red;font-weight:bolder;font-weight:700;display:block!important;color:#fff}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['font-weight', false , false], ['bolder']],
-          [['font-weight', false , false], ['700']],
-          [['display', true , false], ['block']],
-          [['color', false , false], ['#fff']]
+          [['font-weight'], ['bolder']],
+          [['font-weight'], ['700']],
+          [['display'], ['block!important']],
+          [['color'], ['#fff']]
         ]);
       }
     },
@@ -88,8 +85,8 @@ vows.describe(optimize)
       'topic': 'p{display:block;display:-moz-inline-box;color:red;display:table-cell}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['color', false , false], ['red']],
-          [['display', false , false], ['table-cell']]
+          [['color'], ['red']],
+          [['display'], ['table-cell']]
         ]);
       }
     },
@@ -97,10 +94,10 @@ vows.describe(optimize)
       'topic': 'p{background:-moz-linear-gradient();background:-webkit-linear-gradient();filter:"progid:DXImageTransform";background:linear-gradient()}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['background', false , false], ['-moz-linear-gradient()']],
-          [['background', false , false], ['-webkit-linear-gradient()']],
-          [['filter', false , false], ['"progid:DXImageTransform"']],
-          [['background', false , false], ['linear-gradient()']]
+          [['background'], ['-moz-linear-gradient()']],
+          [['background'], ['-webkit-linear-gradient()']],
+          [['filter'], ['"progid:DXImageTransform"']],
+          [['background'], ['linear-gradient()']]
         ]);
       }
     },
@@ -108,10 +105,10 @@ vows.describe(optimize)
       'topic': 'p{background-image:-moz-linear-gradient();background-image:-webkit-linear-gradient();filter:"progid:DXImageTransform";background-image:linear-gradient()}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['background-image', false , false], ['-moz-linear-gradient()']],
-          [['background-image', false , false], ['-webkit-linear-gradient()']],
-          [['filter', false , false], ['"progid:DXImageTransform"']],
-          [['background-image', false , false], ['linear-gradient()']]
+          [['background-image'], ['-moz-linear-gradient()']],
+          [['background-image'], ['-webkit-linear-gradient()']],
+          [['filter'], ['"progid:DXImageTransform"']],
+          [['background-image'], ['linear-gradient()']]
         ]);
       }
     },
@@ -119,10 +116,10 @@ vows.describe(optimize)
       'topic': 'p{background:-moz-linear-gradient();background:-webkit-linear-gradient();-ms-filter:"progid:DXImageTransform";background:linear-gradient()}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['background', false , false], ['-moz-linear-gradient()']],
-          [['background', false , false], ['-webkit-linear-gradient()']],
-          [['-ms-filter', false , false], ['"progid:DXImageTransform"']],
-          [['background', false , false], ['linear-gradient()']]
+          [['background'], ['-moz-linear-gradient()']],
+          [['background'], ['-webkit-linear-gradient()']],
+          [['-ms-filter'], ['"progid:DXImageTransform"']],
+          [['background'], ['linear-gradient()']]
         ]);
       }
     },
@@ -130,10 +127,10 @@ vows.describe(optimize)
       'topic': 'p{background-image:-moz-linear-gradient();background-image:-webkit-linear-gradient();-ms-filter:"progid:DXImageTransform";background-image:linear-gradient()}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['background-image', false , false], ['-moz-linear-gradient()']],
-          [['background-image', false , false], ['-webkit-linear-gradient()']],
-          [['-ms-filter', false , false], ['"progid:DXImageTransform"']],
-          [['background-image', false , false], ['linear-gradient()']]
+          [['background-image'], ['-moz-linear-gradient()']],
+          [['background-image'], ['-webkit-linear-gradient()']],
+          [['-ms-filter'], ['"progid:DXImageTransform"']],
+          [['background-image'], ['linear-gradient()']]
         ]);
       }
     },
@@ -141,7 +138,7 @@ vows.describe(optimize)
       'topic': 'p{border-left-style:solid;border:1px dotted red}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['border', false , false], ['1px'], ['dotted'], ['red']]
+          [['border'], ['1px'], ['dotted'], ['red']]
         ]);
       }
     },
@@ -149,8 +146,8 @@ vows.describe(optimize)
       'topic': 'p{border-left-style:solid!important;border:1px dotted red}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['border-left-style', true, false], ['solid']],
-          [['border', false , false], ['1px'], ['dotted'], ['red']]
+          [['border-left-style'], ['solid!important']],
+          [['border'], ['1px'], ['dotted'], ['red']]
         ]);
       }
     },
@@ -158,8 +155,8 @@ vows.describe(optimize)
       'topic': 'p{background:url(image.png);background-image:#fff}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['background', false , false], ['url(image.png)']],
-          [['background-image', false , false], ['#fff']]
+          [['background'], ['url(image.png)']],
+          [['background-image'], ['#fff']]
         ]);
       }
     }
@@ -169,7 +166,7 @@ vows.describe(optimize)
       'topic': 'p{list-style:inside none}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['list-style', false , false], ['none'], ['inside']]
+          [['list-style'], ['none'], ['inside']]
         ]);
       }
     }
@@ -179,9 +176,9 @@ vows.describe(optimize)
       'topic': 'p{color:red;display:none;color:#fff\\9}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['color', false , false], ['red']],
-          [['display', false , false], ['none']],
-          [['color', false , 'suffix'], ['#fff']]
+          [['color'], ['red']],
+          [['display'], ['none']],
+          [['color'], ['#fff\\9']]
         ]);
       }
     },
@@ -189,9 +186,9 @@ vows.describe(optimize)
       'topic': 'p{color:red\\9;display:none;color:#fff}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['color', false , 'suffix'], ['red']],
-          [['display', false , false], ['none']],
-          [['color', false , false], ['#fff']]
+          [['color'], ['red\\9']],
+          [['display'], ['none']],
+          [['color'], ['#fff']]
         ]);
       }
     },
@@ -199,8 +196,8 @@ vows.describe(optimize)
       'topic': 'p{color:red\\9;display:none;color:#fff\\9}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['display', false , false], ['none']],
-          [['color', false , 'suffix'], ['#fff']]
+          [['display'], ['none']],
+          [['color'], ['#fff\\9']]
         ]);
       }
     }
@@ -210,7 +207,7 @@ vows.describe(optimize)
       'topic': 'p{display:block;display:inline-block}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, true, true), [
-          [['display', false , false], ['inline-block']]
+          [['display'], ['inline-block']]
         ]);
       }
     },
@@ -218,8 +215,8 @@ vows.describe(optimize)
       'topic': 'p{display:block;display:inline-block}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['display', false , false], ['block']],
-          [['display', false , false], ['inline-block']]
+          [['display'], ['block']],
+          [['display'], ['inline-block']]
         ]);
       }
     },
@@ -227,9 +224,9 @@ vows.describe(optimize)
       'topic': 'p{display:block;display:inline-block;color:red}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, [2], true), [
-          [['display', false , false], ['block']],
-          [['display', false , false], ['inline-block']],
-          [['color', false , false], ['red']]
+          [['display'], ['block']],
+          [['display'], ['inline-block']],
+          [['color'], ['red']]
         ]);
       }
     },
@@ -237,8 +234,8 @@ vows.describe(optimize)
       'topic': 'p{display:block;display:inline-block;color:red}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, [1], true), [
-          [['display', false , false], ['inline-block']],
-          [['color', false , false], ['red']]
+          [['display'], ['inline-block']],
+          [['color'], ['red']]
         ]);
       }
     }
@@ -247,10 +244,10 @@ vows.describe(optimize)
     'aggressive off - (yet) not overriddable': {
       'topic': 'a{display:inline-block;color:red;display:-moz-block}',
       'into': function (topic) {
-        assert.deepEqual(_optimize(topic, false, false), [
-          [['display', false , false], ['inline-block']],
-          [['color', false , false], ['red']],
-          [['display', false , false], ['-moz-block']]
+        assert.deepEqual(_optimize(topic, false), [
+          [['display'], ['inline-block']],
+          [['color'], ['red']],
+          [['display'], ['-moz-block']]
         ]);
       }
     }
@@ -260,9 +257,9 @@ vows.describe(optimize)
       'topic': 'a{color:red!important;display:block;color:rgba(0,255,0,.5)!important}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['color', true , false], ['red']],
-          [['display', false , false], ['block']],
-          [['color', true , false], ['rgba(0,255,0,.5)']]
+          [['color'], ['red!important']],
+          [['display'], ['block']],
+          [['color'], ['rgba(0,255,0,.5)!important']]
         ]);
       }
     },
@@ -270,8 +267,8 @@ vows.describe(optimize)
       'topic': 'a{color:rgba(0,255,0,.5)!important;display:block;color:red!important}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['display', false , false], ['block']],
-          [['color', true , false], ['red']]
+          [['display'], ['block']],
+          [['color'], ['red!important']]
         ]);
       }
     },
@@ -279,8 +276,8 @@ vows.describe(optimize)
       'topic': 'a{background:red!important;background:rgba(0,255,0,.5)!important}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['background', true , false], ['red']],
-          [['background', true , false], ['rgba(0,255,0,.5)']]
+          [['background'], ['red!important']],
+          [['background'], ['rgba(0,255,0,.5)!important']]
         ]);
       }
     },
@@ -288,8 +285,8 @@ vows.describe(optimize)
       'topic': 'a{background:rgba(0,255,0,.5)!important;background:red!important}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['background', true , false], ['rgba(0,255,0,.5)']],
-          [['background', true , false], ['red']]
+          [['background'], ['rgba(0,255,0,.5)!important']],
+          [['background'], ['red!important']]
         ]);
       }
     },
@@ -297,8 +294,8 @@ vows.describe(optimize)
       'topic': 'div{-ms-transform:translate(0,0);-ms-transform:translate3d(0,0,0)}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['-ms-transform', false , false], ['translate(0,0)']],
-          [['-ms-transform', false , false], ['translate3d(0,0,0)']]
+          [['-ms-transform'], ['translate(0,0)']],
+          [['-ms-transform'], ['translate3d(0,0,0)']]
         ]);
       }
     },
@@ -306,9 +303,9 @@ vows.describe(optimize)
       'topic': 'div{-ms-transform:translate(0,0);-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0)}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['-ms-transform', false , false], ['translate(0,0)']],
-          [['-webkit-transform', false , false], ['translate3d(0,0,0)']],
-          [['-ms-transform', false , false], ['translate3d(0,0,0)']]
+          [['-ms-transform'], ['translate(0,0)']],
+          [['-webkit-transform'], ['translate3d(0,0,0)']],
+          [['-ms-transform'], ['translate3d(0,0,0)']]
         ]);
       }
     },
@@ -316,8 +313,8 @@ vows.describe(optimize)
       'topic': 'div{transform:translate(0,0);transform:translate3d(0,0,0)}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['transform', false , false], ['translate(0,0)']],
-          [['transform', false , false], ['translate3d(0,0,0)']]
+          [['transform'], ['translate(0,0)']],
+          [['transform'], ['translate3d(0,0,0)']]
         ]);
       }
     },
@@ -325,9 +322,9 @@ vows.describe(optimize)
       'topic': 'div{transform:translate(0,0);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['transform', false , false], ['translate(0,0)']],
-          [['-webkit-transform', false , false], ['translate3d(0,0,0)']],
-          [['transform', false , false], ['translate3d(0,0,0)']]
+          [['transform'], ['translate(0,0)']],
+          [['-webkit-transform'], ['translate3d(0,0,0)']],
+          [['transform'], ['translate3d(0,0,0)']]
         ]);
       }
     },
@@ -335,8 +332,8 @@ vows.describe(optimize)
       'topic': 'a{border:1px solid #fff;border:1px solid rgba(1,0,0,.5)}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['border', false , false], ['1px'], ['solid'], ['#fff']],
-          [['border', false , false], ['1px'], ['solid'], ['rgba(1,0,0,.5)']]
+          [['border'], ['1px'], ['solid'], ['#fff']],
+          [['border'], ['1px'], ['solid'], ['rgba(1,0,0,.5)']]
         ]);
       }
     },
@@ -344,8 +341,8 @@ vows.describe(optimize)
       'topic': 'a{border:1px solid #fff;border:1px solid rgba(1,0,0,.5)!important}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['border', false , false], ['1px'], ['solid'], ['#fff']],
-          [['border', true , false], ['1px'], ['solid'], ['rgba(1,0,0,.5)']]
+          [['border'], ['1px'], ['solid'], ['#fff']],
+          [['border'], ['1px'], ['solid'], ['rgba(1,0,0,.5)!important']]
         ]);
       }
     },
@@ -353,8 +350,8 @@ vows.describe(optimize)
       'topic': 'a{border:1px solid #fff!important;display:block;border:1px solid #fff}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['border', true , false], ['1px'], ['solid'], ['#fff']],
-          [['display', false , false], ['block']]
+          [['border'], ['1px'], ['solid'], ['#fff!important']],
+          [['display'], ['block']]
         ]);
       }
     },
@@ -362,8 +359,8 @@ vows.describe(optimize)
       'topic': 'a{border:1px solid #fff;display:block;border:1px solid #fff!important}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['display', false , false], ['block']],
-          [['border', true , false], ['1px'], ['solid'], ['#fff']]
+          [['display'], ['block']],
+          [['border'], ['1px'], ['solid'], ['#fff!important']]
         ]);
       }
     },
@@ -371,8 +368,8 @@ vows.describe(optimize)
       'topic': 'a{border-top-width:calc(100%);display:block;border-top-width:1px}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['display', false , false], ['block']],
-          [['border-top-width', false , false], ['1px']]
+          [['display'], ['block']],
+          [['border-top-width'], ['1px']]
         ]);
       }
     },
@@ -380,9 +377,9 @@ vows.describe(optimize)
       'topic': 'a{border-top-width:1px;display:block;border-top-width:calc(100%)}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['border-top-width', false , false], ['1px']],
-          [['display', false , false], ['block']],
-          [['border-top-width', false , false], ['calc(100%)']]
+          [['border-top-width'], ['1px']],
+          [['display'], ['block']],
+          [['border-top-width'], ['calc(100%)']]
         ]);
       }
     },
@@ -390,20 +387,20 @@ vows.describe(optimize)
       'topic': 'a{margin-top:100px;padding-top:30px;margin-top:10vmin}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true), [
-          [['padding-top', false , false], ['30px']],
-          [['margin-top', false , false], ['10vmin']]
+          [['padding-top'], ['30px']],
+          [['margin-top'], ['10vmin']]
         ]);
       }
     }
   })
   .addBatch({
-    'understandable - non adjacent units in IE8 mode 123': {
+    'understandable - non adjacent units in IE8 mode': {
       'topic': 'a{margin-top:100px;padding-top:30px;margin-top:10vmin}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, false, true, 'ie8'), [
-          [['margin-top', false , false], ['100px']],
-          [['padding-top', false , false], ['30px']],
-          [['margin-top', false , false], ['10vmin']]
+          [['margin-top'], ['100px']],
+          [['padding-top'], ['30px']],
+          [['margin-top'], ['10vmin']]
         ]);
       }
     }
index f916daf..ec9b07d 100644 (file)
@@ -7,7 +7,6 @@ var tokenize = require('../../lib/tokenizer/tokenize');
 var SourceTracker = require('../../lib/utils/source-tracker');
 var Compatibility = require('../../lib/utils/compatibility');
 var Validator = require('../../lib/properties/validator');
-var addOptimizationMetadata = require('../../lib/selectors/optimization-metadata');
 
 function _optimize(source, compatibility, aggressiveMerging) {
   var tokens = tokenize(source, {
@@ -23,7 +22,6 @@ function _optimize(source, compatibility, aggressiveMerging) {
     compatibility: compatibility,
     shorthandCompacting: true
   };
-  addOptimizationMetadata(tokens);
   optimize(tokens[0][1], tokens[0][2], false, true, options, validator);
 
   return tokens[0][2];
@@ -35,8 +33,8 @@ vows.describe(optimize)
       'topic': 'p{background-color:-ms-linear-gradient(top,red,#000);background-color:linear-gradient(top,red,#000)}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background-color', false , false], ['-ms-linear-gradient(top,red,#000)']],
-          [['background-color', false , false], ['linear-gradient(top,red,#000)']]
+          [['background-color'], ['-ms-linear-gradient(top,red,#000)']],
+          [['background-color'], ['linear-gradient(top,red,#000)']]
         ]);
       }
     },
@@ -44,7 +42,7 @@ vows.describe(optimize)
       'topic': 'p{background-image:none;background:__ESCAPED_URL_CLEAN_CSS0__}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['__ESCAPED_URL_CLEAN_CSS0__']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']]
         ]);
       }
     },
@@ -52,8 +50,8 @@ vows.describe(optimize)
       'topic': 'p{background-image:none!important;background:__ESCAPED_URL_CLEAN_CSS0__}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background-image', true , false], ['none']],
-          [['background', false , false], ['__ESCAPED_URL_CLEAN_CSS0__']]
+          [['background-image'], ['none!important']],
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']]
         ]);
       }
     },
@@ -61,8 +59,8 @@ vows.describe(optimize)
       'topic': 'p{background-color:red;background:-ms-linear-gradient(top,red,#000)}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background-color', false, false], ['red']],
-          [['background', false, false], ['-ms-linear-gradient(top,red,#000)']],
+          [['background-color'], ['red']],
+          [['background'], ['-ms-linear-gradient(top,red,#000)']],
         ]);
       }
     },
@@ -70,7 +68,7 @@ vows.describe(optimize)
       'topic': 'p{background-image:-ms-linear-gradient(bottom,black,white);background:-ms-linear-gradient(top,red,#000)}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false, false], ['-ms-linear-gradient(top,red,#000)']],
+          [['background'], ['-ms-linear-gradient(top,red,#000)']],
         ]);
       }
     },
@@ -78,8 +76,8 @@ vows.describe(optimize)
       'topic': 'p{background-image:linear-gradient(bottom,black,white);background:-ms-linear-gradient(top,red,#000)}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background-image', false, false], ['linear-gradient(bottom,black,white)']],
-          [['background', false, false], ['-ms-linear-gradient(top,red,#000)']],
+          [['background-image'], ['linear-gradient(bottom,black,white)']],
+          [['background'], ['-ms-linear-gradient(top,red,#000)']],
         ]);
       }
     },
@@ -87,7 +85,7 @@ vows.describe(optimize)
       'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__ repeat;background-repeat:no-repeat}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['__ESCAPED_URL_CLEAN_CSS0__'], ['no-repeat']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['no-repeat']]
         ]);
       }
     },
@@ -95,7 +93,7 @@ vows.describe(optimize)
       'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__ repeat!important;background-repeat:no-repeat}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', true , false], ['__ESCAPED_URL_CLEAN_CSS0__'], ['no-repeat']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['no-repeat!important']]
         ]);
       }
     },
@@ -103,8 +101,8 @@ vows.describe(optimize)
       'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__ repeat;background-repeat:no-repeat!important}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['__ESCAPED_URL_CLEAN_CSS0__']],
-          [['background-repeat', true , false], ['no-repeat']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']],
+          [['background-repeat'], ['no-repeat!important']]
         ]);
       }
     },
@@ -112,8 +110,8 @@ vows.describe(optimize)
       'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__;background-size:50%}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, { properties: { backgroundSizeMerging: false } }), [
-          [['background', false , false], ['__ESCAPED_URL_CLEAN_CSS0__']],
-          [['background-size', false , false], ['50%']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']],
+          [['background-size'], ['50%']]
         ]);
       }
     },
@@ -121,8 +119,8 @@ vows.describe(optimize)
       'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__;background-clip:padding-box}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, { properties: { backgroundClipMerging: false } }), [
-          [['background', false , false], ['__ESCAPED_URL_CLEAN_CSS0__']],
-          [['background-clip', false , false], ['padding-box']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']],
+          [['background-clip'], ['padding-box']]
         ]);
       }
     },
@@ -130,7 +128,7 @@ vows.describe(optimize)
       'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__;background-clip:padding-box}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, { properties: { backgroundClipMerging: true } }), [
-          [['background', false , false], ['__ESCAPED_URL_CLEAN_CSS0__'], ['padding-box']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['padding-box']]
         ]);
       }
     },
@@ -138,8 +136,8 @@ vows.describe(optimize)
       'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__;background-origin:border-box}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, { properties: { backgroundOriginMerging: false } }), [
-          [['background', false , false], ['__ESCAPED_URL_CLEAN_CSS0__']],
-          [['background-origin', false , false], ['border-box']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']],
+          [['background-origin'], ['border-box']]
         ]);
       }
     },
@@ -147,7 +145,7 @@ vows.describe(optimize)
       'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__;background-origin:border-box}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, { properties: { backgroundOriginMerging: true } }), [
-          [['background', false , false], ['__ESCAPED_URL_CLEAN_CSS0__'], ['border-box']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['border-box']]
         ]);
       }
     },
@@ -155,8 +153,8 @@ vows.describe(optimize)
       'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__;background-color:none}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['__ESCAPED_URL_CLEAN_CSS0__']],
-          [['background-color', false , false], ['none']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']],
+          [['background-color'], ['none']]
         ]);
       }
     },
@@ -164,7 +162,7 @@ vows.describe(optimize)
       'topic': 'p{background:white;background-color:red}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, { properties: { merging: false } }), [
-          [['background', false , false], ['red']]
+          [['background'], ['red']]
         ]);
       }
     },
@@ -172,8 +170,8 @@ vows.describe(optimize)
       'topic': 'p{background:linear-gradient();background-color:red}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, { properties: { merging: false } }), [
-          [['background', false , false], ['linear-gradient()']],
-          [['background-color', false , false], ['red']]
+          [['background'], ['linear-gradient()']],
+          [['background-color'], ['red']]
         ]);
       }
     },
@@ -181,9 +179,9 @@ vows.describe(optimize)
       'topic': 'p{background:-webkit-linear-gradient();background:linear-gradient();background-repeat:repeat-x}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['-webkit-linear-gradient()']],
-          [['background', false , false], ['linear-gradient()']],
-          [['background-repeat', false , false], ['repeat-x']]
+          [['background'], ['-webkit-linear-gradient()']],
+          [['background'], ['linear-gradient()']],
+          [['background-repeat'], ['repeat-x']]
         ]);
       }
     },
@@ -191,9 +189,9 @@ vows.describe(optimize)
       'topic': 'p{background:-webkit-linear-gradient();background:linear-gradient();background-repeat:repeat}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['-webkit-linear-gradient()']],
-          [['background', false , false], ['linear-gradient()']],
-          [['background-repeat', false , false], ['repeat']]
+          [['background'], ['-webkit-linear-gradient()']],
+          [['background'], ['linear-gradient()']],
+          [['background-repeat'], ['repeat']]
         ]);
       }
     },
@@ -201,8 +199,8 @@ vows.describe(optimize)
       'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__;background:__ESCAPED_URL_CLEAN_CSS1__;background-repeat:repeat-x}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['__ESCAPED_URL_CLEAN_CSS1__']],
-          [['background-repeat', false , false], ['repeat-x']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS1__']],
+          [['background-repeat'], ['repeat-x']]
         ]);
       }
     },
@@ -210,8 +208,8 @@ vows.describe(optimize)
       'topic': 'p{background:linear-gradient();background-color:red}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['linear-gradient()']],
-          [['background-color', false , false], ['red']]
+          [['background'], ['linear-gradient()']],
+          [['background-color'], ['red']]
         ]);
       }
     },
@@ -219,8 +217,8 @@ vows.describe(optimize)
       'topic': 'p{background:repeat-x;background-image:-webkit-linear-gradient()}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['repeat-x']],
-          [['background-image', false , false], ['-webkit-linear-gradient()']]
+          [['background'], ['repeat-x']],
+          [['background-image'], ['-webkit-linear-gradient()']]
         ]);
       }
     },
@@ -228,7 +226,7 @@ vows.describe(optimize)
       'topic': 'p{background:red;background:red}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['red']]
+          [['background'], ['red']]
         ]);
       }
     },
@@ -236,7 +234,7 @@ vows.describe(optimize)
       'topic': 'p{background:repeat red;background:red}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['red']]
+          [['background'], ['red']]
         ]);
       }
     },
@@ -244,8 +242,8 @@ vows.describe(optimize)
       'topic': 'p{background:linear-gradient();background:-webkit-gradient()}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['linear-gradient()']],
-          [['background', false , false], ['-webkit-gradient()']]
+          [['background'], ['linear-gradient()']],
+          [['background'], ['-webkit-gradient()']]
         ]);
       }
     },
@@ -253,7 +251,7 @@ vows.describe(optimize)
       'topic': 'p{background:linear-gradient();background:__ESCAPED_URL_CLEAN_CSS0__}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['__ESCAPED_URL_CLEAN_CSS0__']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']]
         ]);
       }
     },
@@ -261,8 +259,8 @@ vows.describe(optimize)
       'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__;background:linear-gradient()}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['__ESCAPED_URL_CLEAN_CSS0__']],
-          [['background', false , false], ['linear-gradient()']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']],
+          [['background'], ['linear-gradient()']]
         ]);
       }
     },
@@ -270,7 +268,7 @@ vows.describe(optimize)
       'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__ no-repeat!important;background:__ESCAPED_URL_CLEAN_CSS1__ repeat red}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', true , false], ['__ESCAPED_URL_CLEAN_CSS0__'], ['no-repeat']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['no-repeat!important']]
         ]);
       }
     },
@@ -278,7 +276,7 @@ vows.describe(optimize)
       'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__ no-repeat;background:__ESCAPED_URL_CLEAN_CSS1__ repeat red!important}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', true , false], ['__ESCAPED_URL_CLEAN_CSS1__'], ['red']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS1__'], ['red!important']]
         ]);
       }
     },
@@ -286,8 +284,8 @@ vows.describe(optimize)
       'topic': 'a{background:white;color:red;background:red}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic, null, false), [
-          [['background', false , false], ['red']],
-          [['color', false , false], ['red']]
+          [['background'], ['red']],
+          [['color'], ['red']]
         ]);
       }
     }
@@ -297,7 +295,7 @@ vows.describe(optimize)
       'topic': 'a{border:1px solid red;border-style:dotted}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['border', false , false], ['1px'], ['dotted'], ['red']]
+          [['border'], ['1px'], ['dotted'], ['red']]
         ]);
       }
     },
@@ -305,8 +303,8 @@ vows.describe(optimize)
       'topic': 'a{border:1px solid red;border-style:dotted solid}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['border', false , false], ['1px'], ['solid'], ['red']],
-          [['border-style', false , false], ['dotted'], ['solid']]
+          [['border'], ['1px'], ['solid'], ['red']],
+          [['border-style'], ['dotted'], ['solid']]
         ]);
       }
     },
@@ -314,8 +312,8 @@ vows.describe(optimize)
       'topic': 'a{border:1px solid red;border-style:dotted!important}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['border', false , false], ['1px'], ['solid'], ['red']],
-          [['border-style', true , false], ['dotted']]
+          [['border'], ['1px'], ['solid'], ['red']],
+          [['border-style'], ['dotted!important']]
         ]);
       }
     },
@@ -323,7 +321,7 @@ vows.describe(optimize)
       'topic': 'a{border:1px solid red!important;border-style:dotted}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['border', true , false], ['1px'], ['solid'], ['red']]
+          [['border'], ['1px'], ['solid'], ['red!important']]
         ]);
       }
     },
@@ -331,7 +329,7 @@ vows.describe(optimize)
       'topic': 'a{border:1px solid red!important;border-style:dotted!important}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['border', true , false], ['1px'], ['dotted'], ['red']]
+          [['border'], ['1px'], ['dotted'], ['red!important']]
         ]);
       }
     },
@@ -339,8 +337,8 @@ vows.describe(optimize)
       'topic': 'a{border:1px solid #000;border-color:rgba(255,0,0,.5)}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['border', false, false], ['1px'], ['solid'], ['#000']],
-          [['border-color', false, false], ['rgba(255,0,0,.5)']]
+          [['border'], ['1px'], ['solid'], ['#000']],
+          [['border-color'], ['rgba(255,0,0,.5)']]
         ]);
       }
     },
@@ -348,8 +346,8 @@ vows.describe(optimize)
       'topic': 'a{border-color:#000;border-color:rgba(255,0,0,.5)}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['border-color', false, false], ['#000']],
-          [['border-color', false, false], ['rgba(255,0,0,.5)']]
+          [['border-color'], ['#000']],
+          [['border-color'], ['rgba(255,0,0,.5)']]
         ]);
       }
     },
@@ -357,7 +355,7 @@ vows.describe(optimize)
       'topic': 'a{border-color:rgba(255,0,0,.5);border-color:#000}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['border-color', false, false], ['#000']]
+          [['border-color'], ['#000']]
         ]);
       }
     },
@@ -365,8 +363,8 @@ vows.describe(optimize)
       'topic': 'a{border-color:red;border-color:#000 rgba(255,0,0,.5)}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['border-color', false, false], ['red']],
-          [['border-color', false, false], ['#000'], ['rgba(255,0,0,.5)']]
+          [['border-color'], ['red']],
+          [['border-color'], ['#000'], ['rgba(255,0,0,.5)']]
         ]);
       }
     }
@@ -376,7 +374,7 @@ vows.describe(optimize)
       'topic': 'a{-moz-border-radius:2px;-moz-border-top-left-radius:3px}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['-moz-border-radius', false , false], ['3px'], ['2px'], ['2px']]
+          [['-moz-border-radius'], ['3px'], ['2px'], ['2px']]
         ]);
       }
     },
@@ -384,8 +382,8 @@ vows.describe(optimize)
       'topic': 'a{-moz-border-radius:2px;border-top-left-radius:3px}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['-moz-border-radius', false , false], ['2px']],
-          [['border-top-left-radius', false , false], ['3px']]
+          [['-moz-border-radius'], ['2px']],
+          [['border-top-left-radius'], ['3px']]
         ]);
       }
     },
@@ -393,7 +391,7 @@ vows.describe(optimize)
       'topic': 'a{border-width:2px 3px 2px 1px;border-left-width:3px}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['border-width', false , false], ['2px'], ['3px']]
+          [['border-width'], ['2px'], ['3px']]
         ]);
       }
     },
@@ -401,7 +399,7 @@ vows.describe(optimize)
       'topic': 'a{list-style:circle inside;list-style-image:__ESCAPED_URL_CLEAN_CSS0__}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['list-style', false , false], ['circle'], ['inside'], ['__ESCAPED_URL_CLEAN_CSS0__']]
+          [['list-style'], ['circle'], ['inside'], ['__ESCAPED_URL_CLEAN_CSS0__']]
         ]);
       }
     },
@@ -409,7 +407,7 @@ vows.describe(optimize)
       'topic': 'a{margin:10px 20px;margin-left:25px}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['margin', false , false], ['10px'], ['20px'], ['10px'], ['25px']]
+          [['margin'], ['10px'], ['20px'], ['10px'], ['25px']]
         ]);
       }
     },
@@ -417,7 +415,7 @@ vows.describe(optimize)
       'topic': 'a{outline:red solid 1px;outline-width:3px}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['outline', false , false], ['red'], ['solid'], ['3px']]
+          [['outline'], ['red'], ['solid'], ['3px']]
         ]);
       }
     },
@@ -425,7 +423,7 @@ vows.describe(optimize)
       'topic': 'a{padding:10px;padding-right:20px;padding-left:20px}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['padding', false , false], ['10px'], ['20px']]
+          [['padding'], ['10px'], ['20px']]
         ]);
       }
     }
@@ -435,7 +433,7 @@ vows.describe(optimize)
       'topic': 'a{color:red;color:#fff;color:blue}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['color', false , false], ['blue']]
+          [['color'], ['blue']]
         ]);
       }
     },
@@ -443,8 +441,8 @@ vows.describe(optimize)
       'topic': 'a{color:red;color:#fff;color:blue;color:rgba(1,2,3,.4)}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['color', false , false], ['blue']],
-          [['color', false , false], ['rgba(1,2,3,.4)']]
+          [['color'], ['blue']],
+          [['color'], ['rgba(1,2,3,.4)']]
         ]);
       }
     },
@@ -452,7 +450,7 @@ vows.describe(optimize)
       'topic': 'a{color:red;color:#fff;color:blue;color:rgba(1,2,3,.4);color:red}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['color', false , false], ['red']]
+          [['color'], ['red']]
         ]);
       }
     },
@@ -460,7 +458,7 @@ vows.describe(optimize)
       'topic': 'a{color:#fff!important;color:rgba(1,2,3,.4)}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['color', true , false], ['#fff']]
+          [['color'], ['#fff!important']]
         ]);
       }
     },
@@ -468,8 +466,8 @@ vows.describe(optimize)
       'topic': 'a{color:#fff;color:rgba(1,2,3,.4)!important}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['color', false , false], ['#fff']],
-          [['color', true , false], ['rgba(1,2,3,.4)']]
+          [['color'], ['#fff']],
+          [['color'], ['rgba(1,2,3,.4)!important']]
         ]);
       }
     }
@@ -479,7 +477,7 @@ vows.describe(optimize)
       'topic': 'p{background:top left;background-repeat:no-repeat,no-repeat}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['top'], ['left'], ['no-repeat'], [','], ['top'], ['left'], ['no-repeat']]
+          [['background'], ['top'], ['left'], ['no-repeat'], [','], ['top'], ['left'], ['no-repeat']]
         ]);
       }
     },
@@ -487,7 +485,7 @@ vows.describe(optimize)
       'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__,__ESCAPED_URL_CLEAN_CSS1__;background-repeat:no-repeat}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['__ESCAPED_URL_CLEAN_CSS0__'], ['no-repeat'], [','], ['__ESCAPED_URL_CLEAN_CSS1__'], ['no-repeat']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['no-repeat'], [','], ['__ESCAPED_URL_CLEAN_CSS1__'], ['no-repeat']]
         ]);
       }
     },
@@ -495,7 +493,7 @@ vows.describe(optimize)
       'topic': 'p{background-repeat:no-repeat;background:__ESCAPED_URL_CLEAN_CSS0__,__ESCAPED_URL_CLEAN_CSS1__}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['__ESCAPED_URL_CLEAN_CSS0__'], [','], ['__ESCAPED_URL_CLEAN_CSS1__']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], [','], ['__ESCAPED_URL_CLEAN_CSS1__']]
         ]);
       }
     },
@@ -503,7 +501,7 @@ vows.describe(optimize)
       'topic': 'p{background-repeat:no-repeat,no-repeat;background:__ESCAPED_URL_CLEAN_CSS0__}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['__ESCAPED_URL_CLEAN_CSS0__']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']]
         ]);
       }
     },
@@ -511,7 +509,7 @@ vows.describe(optimize)
       'topic': 'p{background:no-repeat,no-repeat;background-position:top left,bottom left}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['top'], ['left'], ['no-repeat'], [','], ['bottom'], ['left'], ['no-repeat']]
+          [['background'], ['top'], ['left'], ['no-repeat'], [','], ['bottom'], ['left'], ['no-repeat']]
         ]);
       }
     },
@@ -519,8 +517,8 @@ vows.describe(optimize)
       'topic': 'p{background:url(1.png),-webkit-linear-gradient();background:url(1.png),linear-gradient()}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['url(1.png)'], [','], ['-webkit-linear-gradient()']],
-          [['background', false , false], ['url(1.png)'], [','], ['linear-gradient()']]
+          [['background'], ['url(1.png)'], [','], ['-webkit-linear-gradient()']],
+          [['background'], ['url(1.png)'], [','], ['linear-gradient()']]
         ]);
       }
     },
@@ -528,7 +526,7 @@ vows.describe(optimize)
       'topic': 'p{background:top left;background-repeat:no-repeat,no-repeat}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['top'], ['left'], ['no-repeat'], [','], ['top'], ['left'], ['no-repeat']]
+          [['background'], ['top'], ['left'], ['no-repeat'], [','], ['top'], ['left'], ['no-repeat']]
         ]);
       }
     },
@@ -536,7 +534,7 @@ vows.describe(optimize)
       'topic': 'p{background:repeat content-box;background-repeat:no-repeat,no-repeat}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['no-repeat'], ['content-box'], [','], ['no-repeat'], ['content-box']]
+          [['background'], ['no-repeat'], ['content-box'], [','], ['no-repeat'], ['content-box']]
         ]);
       }
     },
@@ -544,7 +542,7 @@ vows.describe(optimize)
       'topic': 'p{background:top left;background-repeat:no-repeat,no-repeat;background-image:__ESCAPED_URL_CLEAN_CSS0__,__ESCAPED_URL_CLEAN_CSS1__}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['__ESCAPED_URL_CLEAN_CSS0__'], ['top'], ['left'], ['no-repeat'], [','], ['__ESCAPED_URL_CLEAN_CSS1__'], ['top'], ['left'], ['no-repeat']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['top'], ['left'], ['no-repeat'], [','], ['__ESCAPED_URL_CLEAN_CSS1__'], ['top'], ['left'], ['no-repeat']]
         ]);
       }
     },
@@ -552,8 +550,8 @@ vows.describe(optimize)
       'topic': 'p{background:top left;background-repeat:no-repeat,no-repeat;background-image:__ESCAPED_URL_CLEAN_CSS0__}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['__ESCAPED_URL_CLEAN_CSS0__'], ['top'], ['left']],
-          [['background-repeat', false , false], ['no-repeat'], [','], ['no-repeat']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['top'], ['left']],
+          [['background-repeat'], ['no-repeat'], [','], ['no-repeat']]
         ]);
       }
     },
@@ -561,8 +559,8 @@ vows.describe(optimize)
       'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__;background-repeat:no-repeat,no-repeat}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['__ESCAPED_URL_CLEAN_CSS0__']],
-          [['background-repeat', false , false], ['no-repeat'], [','], ['no-repeat']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']],
+          [['background-repeat'], ['no-repeat'], [','], ['no-repeat']]
         ]);
       }
     },
@@ -570,8 +568,8 @@ vows.describe(optimize)
       'topic': 'p{background:content-box padding-box;background-repeat:no-repeat,no-repeat}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['content-box'], ['padding-box']],
-          [['background-repeat', false , false], ['no-repeat'], [','], ['no-repeat']]
+          [['background'], ['content-box'], ['padding-box']],
+          [['background-repeat'], ['no-repeat'], [','], ['no-repeat']]
         ]);
       }
     },
@@ -579,8 +577,8 @@ vows.describe(optimize)
       'topic': 'p{background:top left / 20px 20px;background-repeat:no-repeat,no-repeat}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['top'], ['left'], ['/'], ['20px'], ['20px']],
-          [['background-repeat', false , false], ['no-repeat'], [','], ['no-repeat']]
+          [['background'], ['top'], ['left'], ['/'], ['20px'], ['20px']],
+          [['background-repeat'], ['no-repeat'], [','], ['no-repeat']]
         ]);
       }
     },
@@ -588,7 +586,7 @@ vows.describe(optimize)
       'topic': 'p{background:red;background-repeat:__ESCAPED_URL_CLEAN_CSS0__,__ESCAPED_URL_CLEAN_CSS1__}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['__ESCAPED_URL_CLEAN_CSS0__'], [','], ['__ESCAPED_URL_CLEAN_CSS1__'], ['red']],
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], [','], ['__ESCAPED_URL_CLEAN_CSS1__'], ['red']],
         ]);
       }
     },
@@ -596,8 +594,8 @@ vows.describe(optimize)
       'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__;background:__ESCAPED_URL_CLEAN_CSS1__,none}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['__ESCAPED_URL_CLEAN_CSS0__']],
-          [['background', false , false], ['__ESCAPED_URL_CLEAN_CSS1__'], [','], ['none']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']],
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS1__'], [','], ['none']]
         ]);
       }
     },
@@ -605,8 +603,8 @@ vows.describe(optimize)
       'topic': 'p{background:__ESCAPED_URL_CLEAN_CSS0__;background:none,__ESCAPED_URL_CLEAN_CSS1__}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false , false], ['__ESCAPED_URL_CLEAN_CSS0__']],
-          [['background', false , false], ['0 0'], [','], ['__ESCAPED_URL_CLEAN_CSS1__']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__']],
+          [['background'], ['0 0'], [','], ['__ESCAPED_URL_CLEAN_CSS1__']]
         ]);
       }
     },
@@ -614,8 +612,8 @@ vows.describe(optimize)
       'topic': 'p{background-image:__ESCAPED_URL_CLEAN_CSS0__;background-image: __ESCAPED_URL_CLEAN_CSS1__,none}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background-image', false , false], ['__ESCAPED_URL_CLEAN_CSS0__']],
-          [['background-image', false , false], ['__ESCAPED_URL_CLEAN_CSS1__'], [','], ['none']]
+          [['background-image'], ['__ESCAPED_URL_CLEAN_CSS0__']],
+          [['background-image'], ['__ESCAPED_URL_CLEAN_CSS1__'], [','], ['none']]
         ]);
       }
     }
@@ -625,9 +623,9 @@ vows.describe(optimize)
       'topic': 'a{color:red!important;display:block;*color:#fff}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['color', true , false], ['red']],
-          [['display', false , false], ['block']],
-          [['color', false , 'star'], ['#fff']]
+          [['color'], ['red!important']],
+          [['display'], ['block']],
+          [['*color'], ['#fff']]
         ]);
       }
     },
@@ -635,9 +633,9 @@ vows.describe(optimize)
       'topic': 'a{color:red!important;display:block;_color:#fff}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['color', true , false], ['red']],
-          [['display', false , false], ['block']],
-          [['color', false , 'underscore'], ['#fff']]
+          [['color'], ['red!important']],
+          [['display'], ['block']],
+          [['_color'], ['#fff']]
         ]);
       }
     },
@@ -645,8 +643,8 @@ vows.describe(optimize)
       'topic': 'a{color:red!important;display:block;color:#fff\\0}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['color', true , false], ['red']],
-          [['display', false , false], ['block']]
+          [['color'], ['red!important']],
+          [['display'], ['block']]
         ]);
       }
     }
index b8a48dd..dc47369 100644 (file)
@@ -8,7 +8,7 @@ vows.describe(populateComponents)
   .addBatch({
     'shorthand': {
       'topic': function () {
-        var wrapped = wrapForOptimizing([[['margin', false, false], ['0px'], ['1px'], ['2px'], ['3px']]]);
+        var wrapped = wrapForOptimizing([[['margin'], ['0px'], ['1px'], ['2px'], ['3px']]]);
 
         populateComponents(wrapped);
         return wrapped;
@@ -44,7 +44,7 @@ vows.describe(populateComponents)
     },
     'longhand': {
       'topic': function () {
-        var wrapped = wrapForOptimizing([[['margin-top', false, false], ['0px']]]);
+        var wrapped = wrapForOptimizing([[['margin-top'], ['0px']]]);
 
         populateComponents(wrapped);
         return wrapped;
@@ -58,7 +58,7 @@ vows.describe(populateComponents)
     },
     'no value': {
       'topic': function () {
-        var wrapped = wrapForOptimizing([[['margin', false, false]]]);
+        var wrapped = wrapForOptimizing([[['margin']]]);
 
         populateComponents(wrapped);
         return wrapped;
diff --git a/test/properties/restore-from-optimizing-test.js b/test/properties/restore-from-optimizing-test.js
new file mode 100644 (file)
index 0000000..19bb268
--- /dev/null
@@ -0,0 +1,170 @@
+var vows = require('vows');
+var assert = require('assert');
+
+var wrapForOptimizing = require('../../lib/properties/wrap-for-optimizing').all;
+var populateComponents = require('../../lib/properties/populate-components');
+var shallowClone = require('../../lib/properties/clone').shallow;
+
+var restoreFromOptimizing = require('../../lib/properties/restore-from-optimizing');
+
+var Compatibility = require('../../lib/utils/compatibility');
+var Validator = require('../../lib/properties/validator');
+
+var validator = new Validator(new Compatibility().toOptions());
+
+vows.describe(restoreFromOptimizing)
+  .addBatch({
+    'without descriptor': {
+      'topic': function () {
+        var properties = [[['margin-top'], ['0']]];
+        var _properties = wrapForOptimizing(properties);
+        restoreFromOptimizing(_properties);
+
+        return properties;
+      },
+      'is same as source': function (properties) {
+        assert.deepEqual(properties, [[['margin-top'], ['0']]]);
+      }
+    },
+    'with changed value but without descriptor': {
+      'topic': function () {
+        var properties = [[['margin-top'], ['0']]];
+        var _properties = wrapForOptimizing(properties);
+        _properties[0].value = [['1px']];
+        _properties[0].dirty = true;
+        restoreFromOptimizing(_properties);
+
+        return properties;
+      },
+      'has right output': function (properties) {
+        assert.deepEqual(properties, [[['margin-top'], ['1px']]]);
+      }
+    },
+    'longhands': {
+      'topic': function () {
+        var properties = ['/*comment */', [['margin-top'], ['0']]];
+        var _properties = wrapForOptimizing(properties);
+        populateComponents(_properties, validator);
+        restoreFromOptimizing(_properties);
+
+        return properties;
+      },
+      'is same as source': function (properties) {
+        assert.deepEqual(properties, ['/*comment */', [['margin-top'], ['0']]]);
+      }
+    },
+    'shorthands': {
+      'topic': function () {
+        var properties = ['/*comment */', [['background'], ['url(image.png)']]];
+        var _properties = wrapForOptimizing(properties);
+        populateComponents(_properties, validator);
+
+        properties[1].pop();
+        _properties[0].dirty = true;
+
+        restoreFromOptimizing(_properties);
+        return properties;
+      },
+      'is same as source': function (properties) {
+        assert.deepEqual(properties, ['/*comment */', [['background'], ['url(image.png)']]]);
+      }
+    },
+    'shorthands in simple mode': {
+      'topic': function () {
+        var properties = [[['margin'], ['1px'], ['2px']]];
+        var _properties = wrapForOptimizing(properties);
+
+        _properties[0].dirty = true;
+
+        restoreFromOptimizing(_properties, true);
+        return properties;
+      },
+      'is same as source': function (properties) {
+        assert.deepEqual(properties, [[['margin'], ['1px'], ['2px']]]);
+      }
+    },
+    'values': {
+      'topic': function () {
+        var properties = [[['background'], ['url(image.png)']]];
+        var _properties = wrapForOptimizing(properties);
+        populateComponents(_properties, validator);
+
+        _properties[0].value = [];
+        _properties[0].dirty = true;
+
+        restoreFromOptimizing(_properties);
+        return _properties;
+      },
+      'updates value': function (_properties) {
+        assert.deepEqual(_properties[0].value, [['url(image.png)']]);
+      }
+    },
+    'in cloned without reference to `all`': {
+      'topic': function () {
+        var properties = [[['background'], ['url(image.png)']]];
+        var _properties = wrapForOptimizing(properties);
+        populateComponents(_properties, validator);
+
+        var cloned = shallowClone(_properties[0]);
+        cloned.components = _properties[0].components;
+        cloned.dirty = true;
+
+        restoreFromOptimizing([cloned]);
+        return cloned;
+      },
+      'does not fail': function (cloned) {
+        assert.deepEqual(cloned.value, [['url(image.png)']]);
+      }
+    }
+  })
+  .addBatch({
+    'important': {
+      'topic': function () {
+        var properties = [[['color'], ['red!important']]];
+        var _properties = wrapForOptimizing(properties);
+
+        restoreFromOptimizing(_properties, true);
+        return properties;
+      },
+      'restores important': function (properties) {
+        assert.deepEqual(properties, [[['color'], ['red!important']]]);
+      }
+    },
+    'underscore hack': {
+      'topic': function () {
+        var properties = [[['_color'], ['red']]];
+        var _properties = wrapForOptimizing(properties);
+
+        restoreFromOptimizing(_properties, true);
+        return properties;
+      },
+      'restores hack': function (properties) {
+        assert.deepEqual(properties, [[['_color'], ['red']]]);
+      }
+    },
+    'star hack': {
+      'topic': function () {
+        var properties = [[['*color'], ['red']]];
+        var _properties = wrapForOptimizing(properties);
+
+        restoreFromOptimizing(_properties, true);
+        return properties;
+      },
+      'restores hack': function (properties) {
+        assert.deepEqual(properties, [[['*color'], ['red']]]);
+      }
+    },
+    'suffix hack': {
+      'topic': function () {
+        var properties = [[['color'], ['red\\9']]];
+        var _properties = wrapForOptimizing(properties);
+
+        restoreFromOptimizing(_properties, true);
+        return properties;
+      },
+      'restores hack': function (properties) {
+        assert.deepEqual(properties, [[['color'], ['red\\9']]]);
+      }
+    }
+  })
+  .export(module);
diff --git a/test/properties/restore-shorthands-test.js b/test/properties/restore-shorthands-test.js
deleted file mode 100644 (file)
index c7ede63..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-var vows = require('vows');
-var assert = require('assert');
-
-var wrapForOptimizing = require('../../lib/properties/wrap-for-optimizing').all;
-var populateComponents = require('../../lib/properties/populate-components');
-var shallowClone = require('../../lib/properties/clone').shallow;
-
-var restoreShorthands = require('../../lib/properties/restore-shorthands');
-
-var Compatibility = require('../../lib/utils/compatibility');
-var Validator = require('../../lib/properties/validator');
-
-var validator = new Validator(new Compatibility().toOptions());
-
-vows.describe(restoreShorthands)
-  .addBatch({
-    'longhands': {
-      'topic': function () {
-        var properties = ['/*comment */', [['margin-top', false, false], ['0']]];
-        var _properties = wrapForOptimizing(properties);
-        populateComponents(_properties, validator);
-        restoreShorthands(_properties);
-
-        return properties;
-      },
-      'is same as source': function (properties) {
-        assert.deepEqual(properties, ['/*comment */', [['margin-top', false, false], ['0']]]);
-      }
-    },
-    'shorthands': {
-      'topic': function () {
-        var properties = ['/*comment */', [['background', false, false], ['url(image.png)']]];
-        var _properties = wrapForOptimizing(properties);
-        populateComponents(_properties, validator);
-
-        properties[1].pop();
-        _properties[0].dirty = true;
-
-        restoreShorthands(_properties);
-        return properties;
-      },
-      'is same as source': function (properties) {
-        assert.deepEqual(properties, ['/*comment */', [['background', false, false], ['url(image.png)']]]);
-      }
-    },
-    'values': {
-      'topic': function () {
-        var properties = [[['background', false, false], ['url(image.png)']]];
-        var _properties = wrapForOptimizing(properties);
-        populateComponents(_properties, validator);
-
-        _properties[0].value = [];
-        _properties[0].dirty = true;
-
-        restoreShorthands(_properties);
-        return _properties;
-      },
-      'updates value': function (_properties) {
-        assert.deepEqual(_properties[0].value, [['url(image.png)']]);
-      }
-    },
-    'in cloned without reference to `all`': {
-      'topic': function () {
-        var properties = [[['background', false, false], ['url(image.png)']]];
-        var _properties = wrapForOptimizing(properties);
-        populateComponents(_properties, validator);
-
-        var cloned = shallowClone(_properties[0]);
-        cloned.components = _properties[0].components;
-        cloned.dirty = true;
-
-        restoreShorthands([cloned]);
-        return cloned;
-      },
-      'does not fail': function (cloned) {
-        assert.deepEqual(cloned.value, [['url(image.png)']]);
-      }
-    }
-  })
-  .export(module);
index b7c6d40..9bd8d9b 100644 (file)
@@ -10,7 +10,6 @@ var InputSourceMapTracker = require('../../lib/utils/input-source-map-tracker');
 
 var Compatibility = require('../../lib/utils/compatibility');
 var Validator = require('../../lib/properties/validator');
-var addOptimizationMetadata = require('../../lib/selectors/optimization-metadata');
 
 function _optimize(source) {
   var inputSourceMapTracker = new InputSourceMapTracker({
@@ -34,7 +33,6 @@ function _optimize(source) {
     sourceMap: true,
     shorthandCompacting: true
   };
-  addOptimizationMetadata(tokens);
   optimize(tokens[0][1], tokens[0][2], false, true, options, validator);
 
   return tokens[0][2];
@@ -47,7 +45,7 @@ vows.describe(optimize)
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
           [
-            ['margin', false, false, [[1, 2, undefined], [1, 18, undefined], [1, 36, undefined], [1, 52, undefined]]],
+            ['margin', [[1, 2, undefined], [1, 18, undefined], [1, 36, undefined], [1, 52, undefined]]],
             [ '10px', [[1, 13, undefined]]],
             [ '5px', [[1, 65, undefined]]],
             [ '4px', [[1, 32, undefined]]]
index feb6a75..11893e1 100644 (file)
@@ -7,7 +7,6 @@ var tokenize = require('../../lib/tokenizer/tokenize');
 var SourceTracker = require('../../lib/utils/source-tracker');
 var Compatibility = require('../../lib/utils/compatibility');
 var Validator = require('../../lib/properties/validator');
-var addOptimizationMetadata = require('../../lib/selectors/optimization-metadata');
 
 function _optimize(source) {
   var tokens = tokenize(source, {
@@ -23,7 +22,6 @@ function _optimize(source) {
     compatibility: compatibility,
     shorthandCompacting: true
   };
-  addOptimizationMetadata(tokens);
   optimize(tokens[0][1], tokens[0][2], false, true, options, validator);
 
   return tokens[0][2];
@@ -35,7 +33,7 @@ vows.describe(optimize)
       'topic': 'p{background-color:#111;background-image:__ESCAPED_URL_CLEAN_CSS0__;background-repeat:repeat;background-position:0 0;background-attachment:scroll;background-size:auto;background-origin:padding-box;background-clip:border-box}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false, false], ['__ESCAPED_URL_CLEAN_CSS0__'], ['#111']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['#111']]
         ]);
       }
     },
@@ -43,7 +41,7 @@ vows.describe(optimize)
       'topic': 'p{background-color:#111;background-image:__ESCAPED_URL_CLEAN_CSS0__;background-repeat:no-repeat;background-position:0 0;background-attachment:scroll;background-size:auto;background-origin:padding-box;background-clip:border-box}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false, false], ['__ESCAPED_URL_CLEAN_CSS0__'], ['no-repeat'], ['#111']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['no-repeat'], ['#111']]
         ]);
       }
     },
@@ -51,7 +49,7 @@ vows.describe(optimize)
       'topic': 'p{background-color:#111!important;background-image:__ESCAPED_URL_CLEAN_CSS0__!important;background-repeat:repeat!important;background-position:0 0!important;background-attachment:scroll!important;background-size:auto!important;background-origin:padding-box!important;background-clip:border-box!important}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', true, false], ['__ESCAPED_URL_CLEAN_CSS0__'], ['#111']]
+          [['background'], ['__ESCAPED_URL_CLEAN_CSS0__'], ['#111!important']]
         ]);
       }
     },
@@ -59,7 +57,7 @@ vows.describe(optimize)
       'topic': 'p{border-top-width:7px;border-bottom-width:7px;border-left-width:4px;border-right-width:4px}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['border-width', false, false], ['7px'], ['4px']]
+          [['border-width'], ['7px'], ['4px']]
         ]);
       }
     },
@@ -67,7 +65,7 @@ vows.describe(optimize)
       'topic': 'p{border-top-color:#9fce00;border-bottom-color:#9fce00;border-left-color:#9fce00;border-right-color:#9fce00}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['border-color', false, false], ['#9fce00']]
+          [['border-color'], ['#9fce00']]
         ]);
       }
     },
@@ -75,7 +73,7 @@ vows.describe(optimize)
       'topic': 'p{border-right-color:#002;border-bottom-color:#003;border-top-color:#001;border-left-color:#004}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['border-color', false, false], ['#001'], ['#002'], ['#003'], ['#004']]
+          [['border-color'], ['#001'], ['#002'], ['#003'], ['#004']]
         ]);
       }
     },
@@ -83,7 +81,7 @@ vows.describe(optimize)
       'topic': 'p{border-top-left-radius:7px;border-bottom-right-radius:6px;border-bottom-left-radius:5px;border-top-right-radius:3px}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['border-radius', false, false], ['7px'], ['3px'], ['6px'], ['5px']]
+          [['border-radius'], ['7px'], ['3px'], ['6px'], ['5px']]
         ]);
       }
     },
@@ -91,7 +89,7 @@ vows.describe(optimize)
       'topic': 'a{list-style-type:circle;list-style-position:outside;list-style-image:__ESCAPED_URL_CLEAN_CSS0__}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['list-style', false, false], ['circle'], ['__ESCAPED_URL_CLEAN_CSS0__']]
+          [['list-style'], ['circle'], ['__ESCAPED_URL_CLEAN_CSS0__']]
         ]);
       }
     },
@@ -99,7 +97,7 @@ vows.describe(optimize)
       'topic': 'a{list-style-image:__ESCAPED_URL_CLEAN_CSS0__;list-style-type:circle;list-style-position:inside}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['list-style', false, false], ['circle'], ['inside'], ['__ESCAPED_URL_CLEAN_CSS0__']]
+          [['list-style'], ['circle'], ['inside'], ['__ESCAPED_URL_CLEAN_CSS0__']]
         ]);
       }
     },
@@ -107,7 +105,7 @@ vows.describe(optimize)
       'topic': 'a{margin-top:10px;margin-right:5px;margin-bottom:3px;margin-left:2px}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['margin', false, false], ['10px'], ['5px'], ['3px'], ['2px']]
+          [['margin'], ['10px'], ['5px'], ['3px'], ['2px']]
         ]);
       }
     },
@@ -115,7 +113,7 @@ vows.describe(optimize)
       'topic': 'a{padding-top:10px;padding-left:5px;padding-bottom:3px;padding-right:2px}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['padding', false, false], ['10px'], ['2px'], ['3px'], ['5px']]
+          [['padding'], ['10px'], ['2px'], ['3px'], ['5px']]
         ]);
       }
     },
@@ -123,8 +121,8 @@ vows.describe(optimize)
       'topic': 'a{padding-top:10px;margin-top:3px;padding-left:5px;margin-left:3px;padding-bottom:3px;margin-bottom:3px;padding-right:2px;margin-right:3px}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['padding', false, false], ['10px'], ['2px'], ['3px'], ['5px']],
-          [['margin', false, false], ['3px']]
+          [['padding'], ['10px'], ['2px'], ['3px'], ['5px']],
+          [['margin'], ['3px']]
         ]);
       }
     },
@@ -132,9 +130,9 @@ vows.describe(optimize)
       'topic': 'a{padding-top:10px;padding-left:5px;padding-bottom:3px;color:red;padding-right:2px;width:100px}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['color', false, false], ['red']],
-          [['width', false, false], ['100px']],
-          [['padding', false, false], ['10px'], ['2px'], ['3px'], ['5px']]
+          [['color'], ['red']],
+          [['width'], ['100px']],
+          [['padding'], ['10px'], ['2px'], ['3px'], ['5px']]
         ]);
       }
     },
@@ -142,10 +140,10 @@ vows.describe(optimize)
       'topic': 'a{padding-top:10px;padding-left:5px;padding-bottom:3px;_padding-right:2px}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['padding-top', false, false], ['10px']],
-          [['padding-left', false, false], ['5px']],
-          [['padding-bottom', false, false], ['3px']],
-          [['padding-right', false, 'underscore'], ['2px']]
+          [['padding-top'], ['10px']],
+          [['padding-left'], ['5px']],
+          [['padding-bottom'], ['3px']],
+          [['_padding-right'], ['2px']]
         ]);
       }
     },
@@ -153,7 +151,7 @@ vows.describe(optimize)
       'topic': 'a{background:inherit}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background', false, false], ['inherit']]
+          [['background'], ['inherit']]
         ]);
       }
     }
@@ -163,9 +161,9 @@ vows.describe(optimize)
       'topic': 'a{padding-top:10px;padding-left:5px;padding-bottom:3px}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['padding-top', false, false], ['10px']],
-          [['padding-left', false, false], ['5px']],
-          [['padding-bottom', false, false], ['3px']]
+          [['padding-top'], ['10px']],
+          [['padding-left'], ['5px']],
+          [['padding-bottom'], ['3px']]
         ]);
       }
     },
@@ -173,10 +171,10 @@ vows.describe(optimize)
       'topic': 'a{padding-top:10px;padding-left:5px;padding-bottom:3px;padding-right:inherit}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['padding-top', false, false], ['10px']],
-          [['padding-left', false, false], ['5px']],
-          [['padding-bottom', false, false], ['3px']],
-          [['padding-right', false, false], ['inherit']]
+          [['padding-top'], ['10px']],
+          [['padding-left'], ['5px']],
+          [['padding-bottom'], ['3px']],
+          [['padding-right'], ['inherit']]
         ]);
       }
     },
@@ -184,10 +182,10 @@ vows.describe(optimize)
       'topic': 'a{padding-top:10px;padding-left:5px;padding-bottom:3px;padding-right:2px!important}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['padding-top', false, false], ['10px']],
-          [['padding-left', false, false], ['5px']],
-          [['padding-bottom', false, false], ['3px']],
-          [['padding-right', true, false], ['2px']]
+          [['padding-top'], ['10px']],
+          [['padding-left'], ['5px']],
+          [['padding-bottom'], ['3px']],
+          [['padding-right'], ['2px!important']]
         ]);
       }
     },
@@ -195,10 +193,10 @@ vows.describe(optimize)
       'topic': 'a{padding-top:10px;padding-left:5px;padding-bottom:3px;padding-right:calc(100% - 20px)}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['padding-top', false, false], ['10px']],
-          [['padding-left', false, false], ['5px']],
-          [['padding-bottom', false, false], ['3px']],
-          [['padding-right', false, false], ['calc(100% - 20px)']]
+          [['padding-top'], ['10px']],
+          [['padding-left'], ['5px']],
+          [['padding-bottom'], ['3px']],
+          [['padding-right'], ['calc(100% - 20px)']]
         ]);
       }
     },
@@ -206,14 +204,14 @@ vows.describe(optimize)
       'topic': 'p{background-color:#111;background-image:linear-gradient(sth);background-repeat:repeat;background-position:0 0;background-attachment:scroll;background-size:auto;background-origin:padding-box;background-clip:border-box}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
-          [['background-color', false, false], ['#111']],
-          [['background-image', false, false], ['linear-gradient(sth)']],
-          [['background-repeat', false, false], ['repeat']],
-          [['background-position', false, false], ['0'], ['0']],
-          [['background-attachment', false, false], ['scroll']],
-          [['background-size', false, false], ['auto']],
-          [['background-origin', false, false], ['padding-box']],
-          [['background-clip', false, false], ['border-box']]
+          [['background-color'], ['#111']],
+          [['background-image'], ['linear-gradient(sth)']],
+          [['background-repeat'], ['repeat']],
+          [['background-position'], ['0'], ['0']],
+          [['background-attachment'], ['scroll']],
+          [['background-size'], ['auto']],
+          [['background-origin'], ['padding-box']],
+          [['background-clip'], ['border-box']]
         ]);
       }
     }
index 810b5c7..3beb90f 100644 (file)
@@ -7,7 +7,7 @@ vows.describe(wrapForOptimizing)
   .addBatch({
     'one': {
       'topic': function () {
-        return wrapForOptimizing([[['margin', false, false], ['0'], ['0']]]);
+        return wrapForOptimizing([[['margin'], ['0'], ['0']]]);
       },
       'has one wrap': function (wrapped) {
         assert.lengthOf(wrapped, 1);
@@ -42,21 +42,15 @@ vows.describe(wrapForOptimizing)
     },
     'two': {
       'topic': function () {
-        return wrapForOptimizing([[['margin', false, false], ['0'], ['0']], [['color', true, true], ['red']]]);
+        return wrapForOptimizing([[['margin'], ['0'], ['0']], [['color'], ['red']]]);
       },
       'has two wraps': function (wrapped) {
         assert.lengthOf(wrapped, 2);
-      },
-      'marks second as important': function (wrapped) {
-        assert.isTrue(wrapped[1].important);
-      },
-      'marks second as a hack': function (wrapped) {
-        assert.isTrue(wrapped[1].hack);
       }
     },
     'with comments': {
       'topic': function () {
-        return wrapForOptimizing([['/* comment */'], [['color', true, true], ['red']]]);
+        return wrapForOptimizing([['/* comment */'], [['color'], ['red']]]);
       },
       'has one wrap': function (wrapped) {
         assert.lengthOf(wrapped, 1);
@@ -67,7 +61,7 @@ vows.describe(wrapForOptimizing)
     },
     'longhand': {
       'topic': function () {
-        return wrapForOptimizing([[['border-radius-top-left', false, false], ['1px'], ['/'], ['2px']]]);
+        return wrapForOptimizing([[['border-radius-top-left'], ['1px'], ['/'], ['2px']]]);
       },
       'has one wrap': function (wrapped) {
         assert.lengthOf(wrapped, 1);
@@ -84,7 +78,7 @@ vows.describe(wrapForOptimizing)
     },
     'without value': {
       'topic': function () {
-        return wrapForOptimizing([[['margin', false, false]]]);
+        return wrapForOptimizing([[['margin']]]);
       },
       'has one wrap': function (wrapped) {
         assert.lengthOf(wrapped, 1);
@@ -93,13 +87,103 @@ vows.describe(wrapForOptimizing)
         assert.isTrue(wrapped[0].unused);
       }
     },
-    'hack': {
+    'important': {
+      'topic': function () {
+        return wrapForOptimizing([[['margin'], ['0!important']]]);
+      },
+      'has one wrap': function (wrapped) {
+        assert.lengthOf(wrapped, 1);
+      },
+      'has right value': function (wrapped) {
+        assert.deepEqual(wrapped[0].value, [['0']]);
+      },
+      'is important': function (wrapped) {
+        assert.isTrue(wrapped[0].important);
+      }
+    },
+    'underscore hack': {
+      'topic': function () {
+        return wrapForOptimizing([[['_color'], ['red']]]);
+      },
+      'has one wrap': function (wrapped) {
+        assert.lengthOf(wrapped, 1);
+      },
+      'has right name': function (wrapped) {
+        assert.deepEqual(wrapped[0].name, 'color');
+      },
+      'is a hack': function (wrapped) {
+        assert.equal(wrapped[0].hack, 'underscore');
+      }
+    },
+    'star hack': {
+      'topic': function () {
+        return wrapForOptimizing([[['*color'], ['red']]]);
+      },
+      'has one wrap': function (wrapped) {
+        assert.lengthOf(wrapped, 1);
+      },
+      'has right name': function (wrapped) {
+        assert.deepEqual(wrapped[0].name, 'color');
+      },
+      'is a hack': function (wrapped) {
+        assert.equal(wrapped[0].hack, 'star');
+      }
+    },
+    'backslash hack': {
+      'topic': function () {
+        return wrapForOptimizing([[['margin'], ['0\\9']]]);
+      },
+      'has one wrap': function (wrapped) {
+        assert.lengthOf(wrapped, 1);
+      },
+      'has right value': function (wrapped) {
+        assert.deepEqual(wrapped[0].value, [['0']]);
+      },
+      'is a hack': function (wrapped) {
+        assert.equal(wrapped[0].hack, 'suffix');
+      }
+    },
+    'backslash hack - single value': {
+      'topic': function () {
+        return wrapForOptimizing([[['margin'], ['0']]]);
+      },
+      'has one wrap': function (wrapped) {
+        assert.lengthOf(wrapped, 1);
+      },
+      'has right value': function (wrapped) {
+        assert.deepEqual(wrapped[0].value, [['0']]);
+      },
+      'is a hack': function (wrapped) {
+        assert.isFalse(wrapped[0].hack);
+      }
+    },
+    'backslash hack - space between values': {
       'topic': function () {
-        return wrapForOptimizing([[['margin', false, 'suffix']]]);
+        return wrapForOptimizing([[['margin'], ['0'], ['\\9']]]);
       },
       'has one wrap': function (wrapped) {
         assert.lengthOf(wrapped, 1);
       },
+      'has right value': function (wrapped) {
+        assert.deepEqual(wrapped[0].value, [['0']]);
+      },
+      'is a hack': function (wrapped) {
+        assert.equal(wrapped[0].hack, 'suffix');
+      }
+    },
+    'source map': {
+      'topic': function () {
+        return wrapForOptimizing([[['color', 1, 2, undefined], ['red\\9!important', 1, 2, undefined]]]);
+      },
+      'has one wrap': function (wrapped) {
+        assert.lengthOf(wrapped, 1);
+      },
+      'has right value': function (wrapped) {
+        assert.deepEqual(wrapped[0].value, [['red', 1, 2, undefined]]);
+      },
+      'is important': function (wrapped) {
+        assert.isTrue(wrapped[0].important);
+      },
       'is a hack': function (wrapped) {
         assert.equal(wrapped[0].hack, 'suffix');
       }
index fd65bb3..2348452 100644 (file)
@@ -59,10 +59,10 @@ vows.describe(extractor)
       }
     },
     'with source map info': {
-      'topic': extractor(['selector', [['a', 1, 0, undefined]], [[['color', false, false, 1, 3, undefined], ['red', 1, 9, undefined]]]]),
+      'topic': extractor(['selector', [['a', 1, 0, undefined]], [[['color', 1, 3, undefined], ['red', 1, 9, undefined]]]]),
       'has one property': function (tokens) {
         assert.deepEqual(tokens, [
-          ['color', 'red', 'color', [['color', false, false, 1, 3, undefined], ['red', 1, 9, undefined]], 'color:red', [['a', 1, 0, undefined]], true],
+          ['color', 'red', 'color', [['color', 1, 3, undefined], ['red', 1, 9, undefined]], 'color:red', [['a', 1, 0, undefined]], true],
         ]);
       }
     }
diff --git a/test/selectors/optimization-metadata-test.js b/test/selectors/optimization-metadata-test.js
deleted file mode 100644 (file)
index d8936ac..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-var vows = require('vows');
-var assert = require('assert');
-
-var addOptimizationMetadata = require('../../lib/selectors/optimization-metadata');
-
-vows.describe(addOptimizationMetadata)
-  .addBatch({
-    'comment': {
-      'topic': [['selector', ['a'], ['/* comment */']]],
-      'metadata': function (tokens) {
-        addOptimizationMetadata(tokens);
-        assert.deepEqual(tokens, [['selector', ['a'], ['/* comment */']]]);
-      }
-    },
-    'normal': {
-      'topic': [['selector', ['a'], [[['color'], ['red']]] ]],
-      'metadata': function (tokens) {
-        addOptimizationMetadata(tokens);
-        assert.deepEqual(tokens, [['selector', ['a'], [[['color', false, false], ['red']]] ]]);
-      }
-    },
-    'important': {
-      'topic': [['selector', ['a'], [[['color'], ['red!important']]] ]],
-      'metadata': function (tokens) {
-        addOptimizationMetadata(tokens);
-        assert.deepEqual(tokens, [['selector', ['a'], [[['color', true, false], ['red']]] ]]);
-      }
-    },
-    'flat block': {
-      'topic': [['flat-block', ['@font-face'], [[['font-family'], ['x']]] ]],
-      'metadata': function (tokens) {
-        addOptimizationMetadata(tokens);
-        assert.deepEqual(tokens, [['flat-block', ['@font-face'], [[['font-family', false, false], ['x']]] ]]);
-      }
-    },
-    'underscore hack': {
-      'topic': [['selector', ['a'], [[['_color'], ['red']]] ]],
-      'metadata': function (tokens) {
-        addOptimizationMetadata(tokens);
-        assert.deepEqual(tokens, [['selector', ['a'], [[['color', false, 'underscore'], ['red']]] ]]);
-      }
-    },
-    'star hack': {
-      'topic': [['selector', ['a'], [[['*color'], ['red']]] ]],
-      'metadata': function (tokens) {
-        addOptimizationMetadata(tokens);
-        assert.deepEqual(tokens, [['selector', ['a'], [[['color', false, 'star'], ['red']]] ]]);
-      }
-    },
-    'backslash hack': {
-      'topic': [['selector', ['a'], [[['color'], ['red\\9']]] ]],
-      'metadata': function (tokens) {
-        addOptimizationMetadata(tokens);
-        assert.deepEqual(tokens, [['selector', ['a'], [[['color', false, 'suffix'], ['red']]] ]]);
-      }
-    },
-    'backslash hack - value of length 1': {
-      'topic': [['selector', ['a'], [[['width'], ['0']]] ]],
-      'metadata': function (tokens) {
-        addOptimizationMetadata(tokens);
-        assert.deepEqual(tokens, [['selector', ['a'], [[['width', false, false], ['0']]] ]]);
-      }
-    },
-    'backslash hack - space between values123': {
-      'topic': [['selector', ['a'], [[['width'], ['0'], ['\\9']]] ]],
-      'metadata': function (tokens) {
-        addOptimizationMetadata(tokens);
-        assert.deepEqual(tokens, [['selector', ['a'], [[['width', false, 'suffix'], ['0']]] ]]);
-      }
-    }
-  })
-  .addBatch({
-    'source map': {
-      'topic': [['selector', ['a', 1, 0, undefined], [[['color', 1, 2, undefined], ['red', 1, 2, undefined]]] ]],
-      'metadata': function (tokens) {
-        addOptimizationMetadata(tokens);
-        assert.deepEqual(tokens, [['selector', ['a', 1, 0, undefined], [[['color', false, false, 1, 2, undefined], ['red', 1, 2, undefined]]] ]]);
-      }
-    }
-  })
-  .export(module);
index 10cbb2b..ad13745 100644 (file)
@@ -364,7 +364,7 @@ vows.describe('simple optimizations')
       ],
       'backslash': [
         'a{width:100px\\9}',
-        [['width', '100px']]
+        [['width', '100px\\9']]
       ]
     })
   )
@@ -372,15 +372,15 @@ vows.describe('simple optimizations')
     propertyContext('ie hacks in compatibility mode', {
       'underscore': [
         'a{_width:100px}',
-        [['width', '100px']]
+        [['_width', '100px']]
       ],
       'star': [
         'a{*width:100px}',
-        [['width', '100px']]
+        [['*width', '100px']]
       ],
       'backslash': [
         'a{width:100px\\9}',
-        [['width', '100px']]
+        [['width', '100px\\9']]
       ]
     }, { compatibility: 'ie8' })
   )
@@ -388,15 +388,15 @@ vows.describe('simple optimizations')
     propertyContext('important', {
       'minified': [
         'a{color:red!important}',
-        [['color', 'red']]
+        [['color', 'red!important']]
       ],
       'space before !': [
         'a{color:red !important}',
-        [['color', 'red']]
+        [['color', 'red!important']]
       ],
       'space after !': [
         'a{color:red! important}',
-        [['color', 'red']]
+        [['color', 'red!important']]
       ]
     }, { compatibility: 'ie8' })
   )
index 7ff5f0d..12e7a76 100644 (file)
@@ -4,7 +4,6 @@ var CleanCSS = require('../lib/clean');
 var tokenize = require('../lib/tokenizer/tokenize');
 var simpleOptimize = require('../lib/selectors/simple');
 var Compatibility = require('../lib/utils/compatibility');
-var addOptimizationMetadata = require('../lib/selectors/optimization-metadata');
 
 function optimizerContext(group, specs, options) {
   var context = {};
@@ -60,7 +59,6 @@ function propertyContext(group, specs, options) {
   function optimized(selectors) {
     return function (source) {
       var tokens = tokenize(source, { options: {} });
-      addOptimizationMetadata(tokens);
       simpleOptimize(tokens, options);
 
       var value = tokens[0] ?