Fixes #711 - border fuzzy matching.
authorJakub Pawlowicz <contact@jakubpawlowicz.com>
Sun, 3 Jan 2016 11:44:45 +0000 (11:44 +0000)
committerJakub Pawlowicz <contact@jakubpawlowicz.com>
Sun, 3 Jan 2016 15:30:34 +0000 (15:30 +0000)
When trying to fuzzy match border values exclude non-matching values
so a best fit can be selected.

History.md
lib/properties/break-up.js
lib/properties/can-override.js
lib/properties/validator.js
test/properties/break-up-test.js
test/properties/override-compacting-test.js

index 8ce7458..91fd257 100644 (file)
@@ -7,6 +7,7 @@
 ==================
 
 * Fixed issue [#693](https://github.com/jakubpawlowicz/clean-css/issues/693) - restructuring edge case.
+* Fixed issue [#711](https://github.com/jakubpawlowicz/clean-css/issues/711) - border fuzzy matching.
 
 [3.4.8 / 2015-11-13](https://github.com/jakubpawlowicz/clean-css/compare/v3.4.7...v3.4.8)
 ==================
index d803536..9add0ef 100644 (file)
@@ -11,7 +11,7 @@ function _colorFilter(validator) {
 
 function _styleFilter(validator) {
   return function (value) {
-    return value[0] != 'inherit' && validator.isValidStyle(value[0]);
+    return value[0] != 'inherit' && validator.isValidStyle(value[0]) && !validator.isValidColorValue(value[0]);
   };
 }
 
@@ -27,7 +27,7 @@ function _wrapDefault(name, property, compactable) {
 
 function _widthFilter(validator) {
   return function (value) {
-    return value[0] != 'inherit' && validator.isValidWidth(value[0]);
+    return value[0] != 'inherit' && validator.isValidWidth(value[0]) && !validator.isValidStyleKeyword(value[0]) && !validator.isValidColorValue(value[0]);
   };
 }
 
index 88857d7..3482b82 100644 (file)
@@ -40,6 +40,11 @@ function color(property1, property2, validator) {
   var color1 = property1.value[0][0];
   var color2 = property2.value[0][0];
 
+  if (!validator.colorOpacity && (validator.isValidRgbaColor(color1) || validator.isValidHslaColor(color1)))
+    return false;
+  if (!validator.colorOpacity && (validator.isValidRgbaColor(color2) || validator.isValidHslaColor(color2)))
+    return false;
+
   // (hex | named)
   if (validator.isValidNamedColor(color2) || validator.isValidHexColor(color2))
     return true;
index 2e8356c..db4ee89 100644 (file)
@@ -38,6 +38,8 @@ function Validator(compatibility) {
   var compatibleCssUnitRegexStr = '(\\-?\\.?\\d+\\.?\\d*(' + validUnits.join('|') + '|)|auto|inherit)';
   this.compatibleCssUnitRegex = new RegExp('^' + compatibleCssUnitRegexStr + '$', 'i');
   this.compatibleCssUnitAnyRegex = new RegExp('^(none|' + widthKeywords.join('|') + '|' + compatibleCssUnitRegexStr + '|' + cssVariableRegexStr + '|' + cssFunctionNoVendorRegexStr + '|' + cssFunctionVendorRegexStr + ')$', 'i');
+
+  this.colorOpacity = compatibility.colors.opacity;
 }
 
 Validator.prototype.isValidHexColor = function (s) {
@@ -65,13 +67,17 @@ Validator.prototype.isValidVariable = function (s) {
 
 Validator.prototype.isValidColor = function (s) {
   return this.isValidNamedColor(s) ||
-    this.isValidHexColor(s) ||
-    this.isValidRgbaColor(s) ||
-    this.isValidHslaColor(s) ||
+    this.isValidColorValue(s) ||
     this.isValidVariable(s) ||
     this.isValidVendorPrefixedValue(s);
 };
 
+Validator.prototype.isValidColorValue = function (s) {
+  return this.isValidHexColor(s) ||
+    this.isValidRgbaColor(s) ||
+    this.isValidHslaColor(s);
+};
+
 Validator.prototype.isValidUrl = function (s) {
   // NOTE: at this point all URLs are replaced with placeholders by clean-css, so we check for those placeholders
   return s.indexOf('__ESCAPED_URL_CLEAN_CSS') === 0;
@@ -159,11 +165,19 @@ Validator.prototype.isValidListStylePosition = function (s) {
 };
 
 Validator.prototype.isValidStyle = function (s) {
-  return styleKeywords.indexOf(s) >= 0 || this.isValidVariable(s);
+  return this.isValidStyleKeyword(s) || this.isValidVariable(s);
+};
+
+Validator.prototype.isValidStyleKeyword = function (s) {
+  return styleKeywords.indexOf(s) >= 0;
 };
 
 Validator.prototype.isValidWidth = function (s) {
-  return this.isValidUnit(s) || widthKeywords.indexOf(s) >= 0 || this.isValidVariable(s);
+  return this.isValidUnit(s) || this.isValidWidthKeyword(s) || this.isValidVariable(s);
+};
+
+Validator.prototype.isValidWidthKeyword = function (s) {
+  return widthKeywords.indexOf(s) >= 0;
 };
 
 Validator.prototype.isValidVendorPrefixedValue = function (s) {
index e9f68ce..ad92d0c 100644 (file)
@@ -280,6 +280,26 @@ vows.describe(breakUp)
           assert.deepEqual(components[2].name, 'border-color');
           assert.deepEqual(components[2].value, [['red']]);
         }
+      },
+      'missing width': {
+        'topic': function () {
+          return _breakUp([[['border'], ['solid'], ['rgba(0,0,0,0)']]]);
+        },
+        'has 3 components': function (components) {
+          assert.lengthOf(components, 3);
+        },
+        'has border-width': function (components) {
+          assert.deepEqual(components[0].name, 'border-width');
+          assert.deepEqual(components[0].value, [['medium']]);
+        },
+        'has border-style': function (components) {
+          assert.deepEqual(components[1].name, 'border-style');
+          assert.deepEqual(components[1].value, [['solid']]);
+        },
+        'has border-color': function (components) {
+          assert.deepEqual(components[2].name, 'border-color');
+          assert.deepEqual(components[2].value, [['rgba(0,0,0,0)']]);
+        }
       }
     },
     'border radius': {
index ff9c2dd..f0b5185 100644 (file)
@@ -81,7 +81,7 @@ vows.describe(optimize)
         ]);
       }
     },
-    'longhand then shorthand - with unprefixed function 123': {
+    'longhand then shorthand - with unprefixed function': {
       'topic': 'p{background-color:red;background:linear-gradient(red,blue)}',
       'into': function (topic) {
         assert.deepEqual(_optimize(topic), [
@@ -167,6 +167,23 @@ vows.describe(optimize)
         ]);
       }
     },
+    'shorthand then longhand - border with rgba() and color opacity on': {
+      'topic': 'p{border:solid rgba(0,0,0,0);border-color:transparent}',
+      'into': function (topic) {
+        assert.deepEqual(_optimize(topic, { colors: { opacity: true } }), [
+          [['border'], ['solid'], ['transparent']]
+        ]);
+      }
+    },
+    'shorthand then longhand - border with rgba() and color opacity off': {
+      'topic': 'p{border:solid rgba(0,0,0,0);border-color:transparent}',
+      'into': function (topic) {
+        assert.deepEqual(_optimize(topic, { colors: { opacity: false } }), [
+          [['border'], ['solid'], ['rgba(0,0,0,0)']],
+          [['border-color'], ['transparent']]
+        ]);
+      }
+    },
     'shorthand then longhand - color into a color - with merging off': {
       'topic': 'p{background:white;background-color:red}',
       'into': function (topic) {