Fixes #197 - merging borders by understandability.
authorJakub Pawlowicz <jakub@goalsmashers.com>
Sun, 1 Jun 2014 21:29:32 +0000 (22:29 +0100)
committerJakub Pawlowicz <jakub@goalsmashers.com>
Sun, 1 Jun 2014 21:34:57 +0000 (22:34 +0100)
* Adds border processor so all border declarations are reprocessed into: <width> <style> <color>.

History.md
lib/properties/processable.js
test/data/big-min.css
test/data/font-awesome-min.css
test/unit-test.js

index 76da275..5a843c2 100644 (file)
@@ -10,6 +10,7 @@
 * Fixed issue [#173](https://github.com/GoalSmashers/clean-css/issues/173) - merges same properties if grouped.
 * Fixed issue [#184](https://github.com/GoalSmashers/clean-css/issues/184) - uses `!important` for optimization opportunities.
 * Fixed issue [#190](https://github.com/GoalSmashers/clean-css/issues/190) - uses shorthand to override another shorthand.
+* Fixed issue [#197](https://github.com/GoalSmashers/clean-css/issues/197) - adds borders merging by understandability.
 * Fixed issue [#247](https://github.com/GoalSmashers/clean-css/issues/247) - removes deprecated `selectorsMergeMode` switch.
 * Refixed issue [#250](https://github.com/GoalSmashers/clean-css/issues/250) - based on new quotation marks removal.
 * Fixed issue [#275](https://github.com/GoalSmashers/clean-css/issues/275) - handling transform properties.
index 2218ce4..c39016c 100644 (file)
@@ -86,6 +86,12 @@ module.exports = (function () {
 
       // Functions with the same name can override each other; same values can override each other
       return canOverride.sameFunctionOrValue(val1, val2);
+    },
+    border: function(val1, val2) {
+      var brokenUp1 = breakUp.border(Token.tokenizeOne(val1));
+      var brokenUp2 = breakUp.border(Token.tokenizeOne(val2));
+
+      return canOverride.color(brokenUp1[2].value, brokenUp2[2].value);
     }
   };
   canOverride = Object.freeze(canOverride);
@@ -260,11 +266,16 @@ module.exports = (function () {
 
     return result;
   };
-  // Breaks up outline
-  breakUp.outline = function (token) {
+
+  breakUp._widthStyleColor = function(token, prefix, order) {
     // Default values
-    var result = Token.makeDefaults(['outline-color', 'outline-style', 'outline-width'], token.isImportant);
-    var color = result[0], style = result[1], width = result[2];
+    var components = order.map(function(prop) {
+      return prefix + '-' + prop;
+    });
+    var result = Token.makeDefaults(components, token.isImportant);
+    var color = result[order.indexOf('color')];
+    var style = result[order.indexOf('style')];
+    var width = result[order.indexOf('width')];
 
     // Take care of inherit
     if (token.value === 'inherit' || token.value === 'inherit inherit inherit') {
@@ -282,7 +293,7 @@ module.exports = (function () {
     }
 
     if (parts.length >= 1) {
-      // Try to find outline-width, excluding inherit because that can be anything
+      // Try to find -width, excluding inherit because that can be anything
       w = parts.filter(function(p) { return p !== 'inherit' && validator.isValidOutlineWidth(p); });
       if (w.length) {
         width.value = w[0];
@@ -290,7 +301,7 @@ module.exports = (function () {
       }
     }
     if (parts.length >= 1) {
-      // Try to find outline-style, excluding inherit because that can be anything
+      // Try to find -style, excluding inherit because that can be anything
       w = parts.filter(function(p) { return p !== 'inherit' && validator.isValidOutlineStyle(p); });
       if (w.length) {
         style.value = w[0];
@@ -298,7 +309,7 @@ module.exports = (function () {
       }
     }
     if (parts.length >= 1) {
-      // Find outline-color but this time can catch inherit
+      // Find -color but this time can catch inherit
       w = parts.filter(function(p) { return validator.isValidOutlineColor(p); });
       if (w.length) {
         color.value = w[0];
@@ -309,6 +320,14 @@ module.exports = (function () {
     return result;
   };
 
+  breakUp.outline = function(token) {
+    return breakUp._widthStyleColor(token, 'outline', ['color', 'style', 'width']);
+  };
+
+  breakUp.border = function(token) {
+    return breakUp._widthStyleColor(token, 'border', ['width', 'style', 'color']);
+  };
+
   // Contains functions that can put together shorthands from their components
   // NOTE: correct order of tokens is assumed inside these functions!
   var putTogether = {
@@ -536,6 +555,30 @@ module.exports = (function () {
       canOverride: canOverride.always,
       defaultValue: 'scroll'
     },
+    'border': {
+      breakUp: breakUp.border,
+      canOverride: canOverride.border,
+      components: [
+        'border-width',
+        'border-style',
+        'border-color'
+      ],
+      defaultValue: 'none',
+      putTogether: putTogether.takeCareOfInherit(putTogether.bySpacesOmitDefaults)
+    },
+    'border-color': {
+      canOverride: canOverride.color,
+      defaultValue: 'none'
+    },
+    'border-style': {
+      canOverride: canOverride.always,
+      defaultValue: 'none'
+    },
+    'border-width': {
+      canOverride: canOverride.unit,
+      defaultValue: 'medium',
+      shortestValue: '0'
+    },
     // list-style ------------------------------------------------------------------------------
     'list-style': {
       components: [
index 7f12fa9..6666340 100644 (file)
@@ -238,7 +238,7 @@ section article{margin:0 0 16px}
 .bord_top3_gris{border-top:3px solid #e9edf0;padding-top:15px}
 .bord_top3_politique{border-top:3px solid #1f0d67}
 .bord_bot3_gris{border-bottom:3px solid #e9edf0}
-.bord1_gris{border:solid 1px #eef1f5}
+.bord1_gris{border:1px solid #eef1f5}
 .bord_lrb1_gris_clair{border-left:1px solid #eef1f5;border-right:1px solid #eef1f5;border-bottom:1px solid #eef1f5}
 .bord_top1_gris{border-top:1px solid #e9edf0;padding-top:10px}
 .bord_bot1_gris{border-bottom:1px solid #e9edf0;padding-bottom:10px}
@@ -799,7 +799,7 @@ img[height="97"]+.ico29x29{bottom:6%;left:3.5%}
 #header_utilisateur #header_twitter_contenu .txt15_140{margin:0 0 5px;padding:0 0 5px;color:#000;border-bottom:solid 1px #d2d6db}
 #header_twitter_contenu .liste_img_lien{margin:9px 0 0;overflow:hidden;white-space:nowrap}
 #header_twitter_contenu .liste_img_lien .block{display:block;margin:0 0 5px}
-#header_twitter_contenu{padding:10px;border:solid 1px #d2d6db}
+#header_twitter_contenu{padding:10px;border:1px solid #d2d6db}
 #header_utilisateur .identifier{float:right;margin:3px 0 0}
 #header_utilisateur .nl{float:left;margin:7px 0 0}
 #header_utilisateur .nl:hover{background-position:right -20px}
@@ -847,7 +847,7 @@ label i{font-style:normal;display:none}
 .saisie_erreur label i{display:inline}
 .boite_formulaire .erreur{display:none}
 .loginbox .back{padding:0 15px;line-height:4rem;border-top:1px solid #d2d6db}
-.loginbox #login_error_email{background:#f2dede;border:solid 1px #c00;color:#c00;text-align:center}
+.loginbox #login_error_email{background:#f2dede;border:1px solid #c00;color:#c00;text-align:center}
 .loginbox .signup{float:left;width:180px;height:230px;padding:10px 40px 10px 15px;border-right:1px solid #fff;border-left:1px solid #e4e6e9;font-size:14px;line-height:140%}
 .loginbox .accroche{display:block;margin:20px 0 15px;color:#464f57}
 .loginbox .abonne_journal{position:relative;float:left;width:185px;height:235px;padding:10px 55px 10px 16px;font-size:14px;line-height:140%;background:url(/medias/web/img/elements_lm/login_box_journal.jpg) no-repeat right 130px;border-left:1px solid #e4e6e9}
@@ -1233,7 +1233,7 @@ label i{font-style:normal;display:none}
 .bloc_je .tt_dossier_meilleur_monde{background:url(/medias/www/img/tit/tt_dossiers_meilleur_monde.png) left center no-repeat;display:block;width:250px;margin:0 9px;font-size:13px;color:#222;text-indent:-9999px}
 .bloc_je .centrer{color:#747b83}
 .bloc_couvs{position:relative;margin:10px auto 3px}
-.bloc_couvs a{cursor:pointer;display:block;width:208px;left:35px;height:145px;overflow:hidden;border:solid 1px #e7e7e7;box-shadow:0 0 3px #e7e7e7;position:absolute}
+.bloc_couvs a{cursor:pointer;display:block;width:208px;left:35px;height:145px;overflow:hidden;border:1px solid #e7e7e7;box-shadow:0 0 3px #e7e7e7;position:absolute}
 .bloc_couvs.bloc_1_couv{height:145px}
 .bloc_couvs .couv_petite{width:146px;height:74px}
 .bloc_couvs b{top:146px;display:block;width:280px;height:44px;background:url(/medias/www/img/plus_une_lemonde.png) left center no-repeat;position:relative}
@@ -1512,7 +1512,7 @@ label i{font-style:normal;display:none}
 .boite_inline .boite_recherche>p,.une_edito .boite_recherche>p{display:inline}
 .une_edito .grid_12 .boite_recherche>p{display:block;margin:5px 0 0}
 .boite_inline .btn.adroite,.une_edito .btn.adroite{margin-top:5px}
-.reception_alertes_resultats{border:solid 1px #eef1f5}
+.reception_alertes_resultats{border:1px solid #eef1f5}
 .reception_alertes_resultats h1{border-top:solid 3px #1f0d67}
 .reception_alertes_resultats .conteneur_hors_grille{margin:16px 54px 54px}
 .reception_alertes_resultats .saisie{display:block;width:282px}
@@ -1522,7 +1522,7 @@ label i{font-style:normal;display:none}
 #alertes_confirmation_newsletter form *{vertical-align:top}
 #alertes_confirmation_newsletter form input{margin-top:3px}
 .reception_alertes_resultats .rnd4{overflow:hidden}
-.reception_alertes_resultats table td,.reception_alertes_resultats table th{padding:8px;border:solid 1px #b9c0c5}
+.reception_alertes_resultats table td,.reception_alertes_resultats table th{padding:8px;border:1px solid #b9c0c5}
 .reception_alertes_resultats table th{text-align:left;background:#f1f5f8}
 .reception_alertes_resultats td span{display:block;cursor:pointer}
 .reception_alertes_resultats .conteneur_autocompletion{width:282px}
index 2a1d290..afe73ac 100644 (file)
@@ -35,7 +35,7 @@ a [class*=" icon-"],a [class^=icon-]{display:inline-block}
 ul.icons{list-style-type:none;text-indent:-.75em}
 ul.icons li [class*=" icon-"],ul.icons li [class^=icon-]{width:.75em}
 .icon-muted{color:#eee}
-.icon-border{border:solid 1px #eee;padding:.2em .25em .15em;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}
+.icon-border{border:1px solid #eee;padding:.2em .25em .15em;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}
 .icon-2x{font-size:2em}
 .icon-2x.icon-border{border-width:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}
 .icon-3x{font-size:3em}
index 7f0aa6d..98743b5 100644 (file)
@@ -1394,7 +1394,16 @@ title']{display:block}",
     '-ms-transform with different values #1': 'div{-ms-transform:translate(0,0);-ms-transform:translate3d(0,0,0)}',
     '-ms-transform with different values #2': 'div{-ms-transform:translate(0,0);-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0)}',
     'transform with different values #1': 'div{transform:translate(0,0);transform:translate3d(0,0,0)}',
-    'transform with different values #2': 'div{transform:translate(0,0);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}'
+    'transform with different values #2': 'div{transform:translate(0,0);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}',
+    'border(hex) with border(rgba)': 'a{border:1px solid #fff;display:none;border:1px solid rgba(1,0,0,0)}',
+    'border(hex !important) with border(hex)': [
+      'a{border:1px solid #fff!important;display:none;border:1px solid #fff}',
+      'a{border:1px solid #fff!important;display:none}'
+    ],
+    'border(hex) with border(hex !important)': [
+      'a{border:1px solid #fff;display:none;border:1px solid #fff!important}',
+      'a{display:none;border:1px solid #fff!important}'
+    ]
   }),
   'same selectors': cssContext({
     'of two non-adjacent selectors': '.one{color:red}.two{color:#00f}.one{font-weight:700}',
@@ -1715,6 +1724,11 @@ title']{display:block}",
       'div{background:#111;background:#111 linear-gradient(aaa)}'
     ]
   }),
+  'cares about understandability of border components': cssContext({
+    'border(none) with border(rgba)': 'a{border:none;border:1px solid rgba(1,0,0,0)}',
+    'border(rgba) with border(none)': 'a{border:1px solid rgba(1,0,0,0);border:none}',
+    'border(hex) with border(rgba)': 'a{border:1px solid #fff;border:1px solid rgba(1,0,0,0)}'
+  }),
   'merge same properties sensibly': cssContext({
     'should merge color values with same understandability #1': [
       'p{color:red;color:#fff;color:blue}',