From f95cb06255263ad269b9f98d61ccab604eb9e707 Mon Sep 17 00:00:00 2001 From: Jakub Pawlowicz Date: Sun, 3 Jan 2016 11:44:45 +0000 Subject: [PATCH] Fixes #711 - border fuzzy matching. When trying to fuzzy match border values exclude non-matching values so a best fit can be selected. --- History.md | 1 + lib/properties/break-up.js | 4 ++-- lib/properties/can-override.js | 5 +++++ lib/properties/validator.js | 24 ++++++++++++++++----- test/properties/break-up-test.js | 20 +++++++++++++++++ test/properties/override-compacting-test.js | 19 +++++++++++++++- 6 files changed, 65 insertions(+), 8 deletions(-) diff --git a/History.md b/History.md index 8ce74580..91fd2572 100644 --- a/History.md +++ b/History.md @@ -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) ================== diff --git a/lib/properties/break-up.js b/lib/properties/break-up.js index d803536a..9add0ef7 100644 --- a/lib/properties/break-up.js +++ b/lib/properties/break-up.js @@ -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]); }; } diff --git a/lib/properties/can-override.js b/lib/properties/can-override.js index 88857d70..3482b827 100644 --- a/lib/properties/can-override.js +++ b/lib/properties/can-override.js @@ -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; diff --git a/lib/properties/validator.js b/lib/properties/validator.js index 2e8356cf..db4ee892 100644 --- a/lib/properties/validator.js +++ b/lib/properties/validator.js @@ -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) { diff --git a/test/properties/break-up-test.js b/test/properties/break-up-test.js index e9f68ceb..ad92d0c7 100644 --- a/test/properties/break-up-test.js +++ b/test/properties/break-up-test.js @@ -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': { diff --git a/test/properties/override-compacting-test.js b/test/properties/override-compacting-test.js index ff9c2ddf..f0b51855 100644 --- a/test/properties/override-compacting-test.js +++ b/test/properties/override-compacting-test.js @@ -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) { -- 2.34.1