Fixes #316 - incorrect background processing.
authorJakub Pawlowicz <contact@jakubpawlowicz.com>
Mon, 21 Jul 2014 19:42:22 +0000 (20:42 +0100)
committerJakub Pawlowicz <contact@jakubpawlowicz.com>
Wed, 23 Jul 2014 22:43:41 +0000 (23:43 +0100)
* Reworks advanced processing for backgrounds so all properties are correctly identified.
* Fixes removing `0 0` background-position as it's default.

History.md
lib/properties/processable.js
lib/properties/validator.js
test/binary-test.js
test/data/big-min.css
test/unit-test.js

index 3e989ec..6ab8945 100644 (file)
@@ -1,3 +1,8 @@
+[2.2.9 / 2014-xx-xx](https://github.com/GoalSmashers/clean-css/compare/v2.2.8...v2.2.9)
+==================
+
+* Fixed issue [#316](https://github.com/GoalSmashers/clean-css/issues/316) - incorrect background processing.
+
 [2.2.8 / 2014-07-14](https://github.com/GoalSmashers/clean-css/compare/v2.2.7...v2.2.8)
 ==================
 
index 08bdd6a..c8f15a9 100644 (file)
@@ -132,14 +132,9 @@ module.exports = (function () {
       return result;
     };
   };
-  // Use this for properties with 4 unit values (like margin or padding)
-  // NOTE: it handles shorter forms of these properties too (like, only 1, 2, or 3 units)
-  breakUp.fourUnits = breakUp.takeCareOfFourValues(function (val) {
-    return val.match(new RegExp(validator.cssUnitAnyRegexStr, 'gi'));
-  });
   // Use this when you simply want to break up four values along spaces
   breakUp.fourBySpaces = breakUp.takeCareOfFourValues(function (val) {
-    return val.split(' ').filter(function (v) { return v; });
+    return new Splitter(' ').split(val).filter(function (v) { return v; });
   });
   // Use this for non-length values that can also contain functions
   breakUp.fourBySpacesOrFunctions = breakUp.takeCareOfFourValues(function (val) {
@@ -214,51 +209,36 @@ module.exports = (function () {
     }
 
     // Break the background up into parts
-    var parts = token.value.split(' ');
+    var parts = new Splitter(' ').split(token.value);
     if (parts.length === 0)
       return result;
 
-    // The trick here is that we start going through the parts from the end, then stop after background repeat,
-    // then start from the from the beginning until we find a valid color value. What remains will be treated as background-image.
-
-    var currentIndex = parts.length - 1;
-    var current = parts[currentIndex];
-    // Attachment
-    if (validator.isValidBackgroundAttachment(current)) {
-      // Found attachment
-      attachment.value = current;
-      currentIndex--;
-      current = parts[currentIndex];
-    }
-    // Position
-    var pos = parts[currentIndex - 1] + ' ' + parts[currentIndex];
-    if (currentIndex >= 1 && validator.isValidBackgroundPosition(pos)) {
-      // Found position (containing two parts)
-      position.value = pos;
-      currentIndex -= 2;
-      current = parts[currentIndex];
-    } else if (currentIndex >= 0 && validator.isValidBackgroundPosition(current)) {
-      // Found position (containing just one part)
-      position.value = current;
-      currentIndex--;
-      current = parts[currentIndex];
-    }
-    // Repeat
-    if (currentIndex >= 0 && validator.isValidBackgroundRepeat(current)) {
-      // Found repeat
-      repeat.value = current;
-      currentIndex--;
-      current = parts[currentIndex];
-    }
-    // Color
-    var fromBeginning = 0;
-    if (validator.isValidColor(parts[0])) {
-      // Found color
-      color.value = parts[0];
-      fromBeginning = 1;
+    // Iterate over all parts and try to fit them into positions
+    for (var i = parts.length - 1; i >= 0; i--) {
+      var currentPart = parts[i];
+
+      if (validator.isValidBackgroundAttachment(currentPart)) {
+        attachment.value = currentPart;
+      } else if (validator.isValidBackgroundPosition(currentPart)) {
+        if (i > 0) {
+          var repeatedPosition = parts[i - 1] + ' ' + currentPart;
+          if (validator.isValidBackgroundPosition(repeatedPosition)) {
+            i--;
+            position.value = repeatedPosition;
+          } else {
+            position.value = currentPart;
+          }
+        } else {
+          position.value = currentPart;
+        }
+      } else if (validator.isValidBackgroundRepeat(currentPart)) {
+        repeat.value = currentPart;
+      } else if (validator.isValidColor(currentPart)) {
+        color.value = currentPart;
+      } else if (validator.isValidUrl(currentPart) || validator.isValidFunction(currentPart)) {
+        image.value = currentPart;
+      }
     }
-    // Image
-    image.value = (parts.splice(fromBeginning, currentIndex - fromBeginning + 1).join(' ')) || 'none';
 
     return result;
   };
@@ -273,7 +253,7 @@ module.exports = (function () {
       return result;
     }
 
-    var parts = token.value.split(' ');
+    var parts = new Splitter(' ').split(token.value);
     var ci = 0;
 
     // Type
@@ -313,7 +293,7 @@ module.exports = (function () {
     // NOTE: usually users don't follow the required order of parts in this shorthand,
     // so we'll try to parse it caring as little about order as possible
 
-    var parts = token.value.split(' '), w;
+    var parts = new Splitter(' ').split(token.value), w;
 
     if (parts.length === 0) {
       return result;
@@ -358,7 +338,7 @@ module.exports = (function () {
   breakUp.borderRadius = function(token) {
     var parts = token.value.split('/');
     if (parts.length == 1)
-      return breakUp.fourUnits(token);
+      return breakUp.fourBySpaces(token);
 
     var horizontalPart = token.clone();
     var verticalPart = token.clone();
@@ -366,8 +346,8 @@ module.exports = (function () {
     horizontalPart.value = parts[0];
     verticalPart.value = parts[1];
 
-    var horizontalBreakUp = breakUp.fourUnits(horizontalPart);
-    var verticalBreakUp = breakUp.fourUnits(verticalPart);
+    var horizontalBreakUp = breakUp.fourBySpaces(horizontalPart);
+    var verticalBreakUp = breakUp.fourBySpaces(verticalPart);
 
     for (var i = 0; i < 4; i++) {
       horizontalBreakUp[i].value = [horizontalBreakUp[i].value, verticalBreakUp[i].value];
@@ -769,14 +749,14 @@ module.exports = (function () {
     options = options || {};
     processable[prop] = {
       components: components,
-      breakUp: options.breakUp || breakUp.fourUnits,
+      breakUp: options.breakUp || breakUp.fourBySpaces,
       putTogether: options.putTogether || putTogether.takeCareOfInherit(putTogether.fourUnits),
       defaultValue: options.defaultValue || '0',
       shortestValue: options.shortestValue
     };
     for (var i = 0; i < components.length; i++) {
       processable[components[i]] = {
-        breakUp: options.breakUp || breakUp.fourUnits,
+        breakUp: options.breakUp || breakUp.fourBySpaces,
         canOverride: options.canOverride || canOverride.unit,
         defaultValue: options.defaultValue || '0',
         shortestValue: options.shortestValue
index 0fa2a8c..714b066 100644 (file)
@@ -5,8 +5,8 @@ module.exports = (function () {
   // Regexes used for stuff
   var widthKeywords = ['thin', 'thick', 'medium', 'inherit', 'initial'];
   var cssUnitRegexStr = '(\\-?\\.?\\d+\\.?\\d*(px|%|em|rem|in|cm|mm|ex|pt|pc|vw|vh|vmin|vmax|)|auto|inherit)';
-  var cssFunctionNoVendorRegexStr = '[A-Z]+(\\-|[A-Z]|[0-9])+\\(([A-Z]|[0-9]|\\ |\\,|\\#|\\+|\\-|\\%|\\.)*\\)';
-  var cssFunctionVendorRegexStr = '\\-(\\-|[A-Z]|[0-9])+\\(([A-Z]|[0-9]|\\ |\\,|\\#|\\+|\\-|\\%|\\.)*\\)';
+  var cssFunctionNoVendorRegexStr = '[A-Z]+(\\-|[A-Z]|[0-9])+\\(([A-Z]|[0-9]|\\ |\\,|\\#|\\+|\\-|\\%|\\.|\\(|\\))*\\)';
+  var cssFunctionVendorRegexStr = '\\-(\\-|[A-Z]|[0-9])+\\(([A-Z]|[0-9]|\\ |\\,|\\#|\\+|\\-|\\%|\\.|\\(|\\))*\\)';
   var cssFunctionAnyRegexStr = '(' + cssFunctionNoVendorRegexStr + '|' + cssFunctionVendorRegexStr + ')';
   var cssUnitAnyRegexStr = '(none|' + widthKeywords.join('|') + '|' + cssUnitRegexStr + '|' + cssFunctionNoVendorRegexStr + '|' + cssFunctionVendorRegexStr + ')';
 
@@ -110,7 +110,6 @@ module.exports = (function () {
   validator.cssFunctionNoVendorRegexStr = cssFunctionNoVendorRegexStr;
   validator.cssFunctionVendorRegexStr = cssFunctionVendorRegexStr;
   validator.cssFunctionAnyRegexStr = cssFunctionAnyRegexStr;
-  validator.cssUnitAnyRegexStr = cssUnitAnyRegexStr;
 
   return validator;
 })();
index 3927e86..be2d415 100644 (file)
@@ -173,18 +173,18 @@ exports.commandsSuite = vows.describe('binary commands').addBatch({
   'relative image paths': {
     'no root & output': binaryContext('./test/data/partials-relative/base.css', {
       'should leave paths': function(error, stdout) {
-        assert.equal(stdout, 'a{background:url(../partials/extra/down.gif) 0 0 no-repeat}');
+        assert.equal(stdout, 'a{background:url(../partials/extra/down.gif) no-repeat}');
       }
     }),
     'root but no output': binaryContext('-r ./test ./test/data/partials-relative/base.css', {
       'should rewrite path relative to ./test': function(error, stdout) {
-        assert.equal(stdout, 'a{background:url(/data/partials/extra/down.gif) 0 0 no-repeat}');
+        assert.equal(stdout, 'a{background:url(/data/partials/extra/down.gif) no-repeat}');
       }
     }),
     'no root but output': binaryContext('-o ./base1-min.css ./test/data/partials-relative/base.css', {
       'should rewrite path relative to current path': function() {
         var minimized = readFile('./base1-min.css');
-        assert.equal(minimized, 'a{background:url(test/data/partials/extra/down.gif) 0 0 no-repeat}');
+        assert.equal(minimized, 'a{background:url(test/data/partials/extra/down.gif) no-repeat}');
       },
       teardown: function() {
         deleteFile('./base1-min.css');
@@ -193,7 +193,7 @@ exports.commandsSuite = vows.describe('binary commands').addBatch({
     'root and output': binaryContext('-r ./test/data -o ./base2-min.css ./test/data/partials-relative/base.css', {
       'should rewrite path relative to ./test/data/': function() {
         var minimized = readFile('./base2-min.css');
-        assert.equal(minimized, 'a{background:url(/partials/extra/down.gif) 0 0 no-repeat}');
+        assert.equal(minimized, 'a{background:url(/partials/extra/down.gif) no-repeat}');
       },
       teardown: function() {
         deleteFile('./base2-min.css');
index 0e54aea..04e5a6a 100644 (file)
@@ -451,7 +451,7 @@ article .liste_carre_999{margin-top:5px}
 .global.audience .container>div:first-child{margin-left:0}
 #carousel_footer_serviciel img:hover,.global.audience .container img:hover{opacity:.7;-ms-filter:"alpha(Opacity=70)"}
 .global.supp_partenaires .entete_deroule{padding:6px 16px;margin-bottom:0;text-align:left;font-weight:700;font-size:16px;font-family:arial,sans serif}
-.global.supp_partenaires .entete_deroule .logo{float:right;padding-left:40px;background:url(/medias/web/img/textes/marqueur_pub_gris43x5.png) 0 12px no-repeat}
+.global.supp_partenaires .entete_deroule .logo{float:right;padding-left:40px;background:url(/medias/web/img/textes/marqueur_pub_gris43x5.png) no-repeat 0 12px}
 .global.supp_partenaires .position_pub div{float:left;width:301px;padding:16px 12px 16px 16px;line-height:140%}
 .global.supp_partenaires .position_pub div~div{width:285px}
 .global.supp_partenaires .position_pub div~div~div{width:330px}
@@ -1195,7 +1195,7 @@ label i{font-style:normal;display:none}
 .col_droite .plus_partages .texte{float:left;width:190px;padding:0 10px 0 8px}
 .col_droite .sociaux .pictos{overflow:hidden;margin:10px 15px}
 .col_droite .sociaux .pictos span.text{float:left;width:130px;padding:0 15px 0 0;color:#464f57;line-height:120%}
-.col_droite .recherche_resultat_pres.bloc_base{background:#0b0423 url(/medias/web/img/evenementiel/presidentielle_2012/bg_recherche_elections_col_droite.png) center 0 no-repeat;color:#fff}
+.col_droite .recherche_resultat_pres.bloc_base{background:#0b0423 url(/medias/web/img/evenementiel/presidentielle_2012/bg_recherche_elections_col_droite.png) no-repeat center 0;color:#fff}
 .col_droite .boite_recherche{background:0 0;padding:8px 16px 10px}
 .col_droite .recherche_resultat_pres.bloc_base .entete{border-top:0!important;border-bottom:0!important;padding-top:16px}
 .col_droite .recherche_resultat_pres .entete span{display:inline-block;height:30px;background:url(/medias/web/img/textes/elections/bulle_2012_39x27_bg_fonce.png) no-repeat;padding-left:50px}
@@ -1229,17 +1229,17 @@ label i{font-style:normal;display:none}
 .bloc_je .annonce{display:block;padding:8px 9px;background:#2e3942;color:#fff}
 .bloc_je .annonce .intro{display:block;text-transform:uppercase;font-weight:700}
 .bloc_je .previsu .bt_blanc_gris_32{margin:20px 0 0}
-.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 .tt_dossier_meilleur_monde{background:url(/medias/www/img/tit/tt_dossiers_meilleur_monde.png) no-repeat left center;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: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}
+.bloc_couvs b{top:146px;display:block;width:280px;height:44px;background:url(/medias/www/img/plus_une_lemonde.png) no-repeat left center;position:relative}
 .bloc_couvs.bloc_2_couv{width:247px;height:185px}
 .bloc_couvs.bloc_2_couv a{left:0}
 .bloc_couvs.bloc_2_couv .couv_petite{left:auto;top:auto;right:0;bottom:0}
-.bloc_couvs.bloc_2_couv b{right:153px;top:153px;width:15px;height:15px;background:url(/medias/www/img/plus_une_lemonde.png) right center no-repeat;position:absolute}
+.bloc_couvs.bloc_2_couv b{right:153px;top:153px;width:15px;height:15px;background:url(/medias/www/img/plus_une_lemonde.png) no-repeat right center;position:absolute}
 .bloc_couvs.bloc_3_couv{width:280px;height:278px}
 .bloc_couvs.bloc_3_couv .couv_petite{width:125px;height:86px;right:auto;top:auto;left:0;bottom:0}
 .bloc_couvs.bloc_3_couv .couv_petite.petite_1{left:auto;right:0}
@@ -1500,7 +1500,7 @@ label i{font-style:normal;display:none}
 .col_droite .erreur{display:block;width:292px}
 #alerte_election_coldroite .conteneur_autocompletion,.col_droite .inscription_alerte_election .saisie{width:272px}
 #alerte_election_coldroite .contenu_bloc_droit{overflow:visible}
-.boite_recherche{background:#f8f9fb url(/medias/web/img/evenementiel/presidentielle_2012/bg_recherche_elections.png) center 0 no-repeat;overflow:visible;padding:16px 16px 10px;color:#fff}
+.boite_recherche{background:#f8f9fb url(/medias/web/img/evenementiel/presidentielle_2012/bg_recherche_elections.png) no-repeat center 0;overflow:visible;padding:16px 16px 10px;color:#fff}
 .boite_recherche .bord_double_gris_blanc{margin:0 4px;display:inline-block;line-height:20px;font-weight:700}
 .bord_top3_politique .boite_recherche input:first-child{width:265px}
 .boite_recherche .bord_double_gris_blanc span{padding:0 3px}
@@ -2026,11 +2026,11 @@ a.god:hover{background:#3c3c3c;color:#fff;text-decoration:none}
 #bar-liberation .other .god a{padding:5px;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}
 #bar-liberation .other .god a:hover{background-color:#ff0;color:#000}
 #bar-liberation .god .godenabled a{background:#3c3c3c;color:#fff}
-#bar-liberation .god a.godenter{background:url(http://s0.libe.com/libe/img/common/icon_godenter.png?9ffa63824b5c) no-repeat center center #fff}
-#bar-liberation .god a.godquit{background:url(http://s0.libe.com/libe/img/common/icon_godquit.png?a59104f30cfb) no-repeat center center #000}
-#bar-liberation .god a.godquit:hover{background:url(http://s0.libe.com/libe/img/common/icon_godenter.png?9ffa63824b5c) no-repeat center center #ff0}
-#bar-liberation .god a.jumptoadmin{background:url(http://s0.libe.com/back/img/icon_home.png?c1de55b52ccc) no-repeat center center #fff}
-#bar-liberation .god a.jumptoedit{background:url(http://s0.libe.com/back/img/icon_changelink.png?4a31d309d5db) no-repeat center center #fff}
+#bar-liberation .god a.godenter{background:#fff url(http://s0.libe.com/libe/img/common/icon_godenter.png?9ffa63824b5c) no-repeat center center}
+#bar-liberation .god a.godquit{background:#000 url(http://s0.libe.com/libe/img/common/icon_godquit.png?a59104f30cfb) no-repeat center center}
+#bar-liberation .god a.godquit:hover{background:#ff0 url(http://s0.libe.com/libe/img/common/icon_godenter.png?9ffa63824b5c) no-repeat center center}
+#bar-liberation .god a.jumptoadmin{background:#fff url(http://s0.libe.com/back/img/icon_home.png?c1de55b52ccc) no-repeat center center}
+#bar-liberation .god a.jumptoedit{background:#fff url(http://s0.libe.com/back/img/icon_changelink.png?4a31d309d5db) no-repeat center center}
 #mainContent .god{font-size:10px;padding:6px;border-radius:2px;-moz-border-radius:4px;-webkit-border-radius:4px}
 #core-liberation .block-partnership .block-content img.visual{display:block;float:left;width:140px;margin-top:4px;margin-bottom:10px}
 #core-liberation .block-partnership .block-content h4{font-family:Verdana,sans-serif;font-size:12px;font-weight:700;margin:0 0 11px 150px}
index 27d95f7..4090a81 100644 (file)
@@ -391,7 +391,6 @@ vows.describe('clean-units').addBatch({
       'a{outline:0}'
     ],
     'display:none not changed': 'a{display:none}',
-    'longer background declaration not changed': 'html{background:none repeat scroll 0 0 #fff}',
     'mixed zeros not changed': 'div{margin:0 0 1px 2px}',
     'mixed zeros not changed #2': 'div{padding:0 1px 0 3px}',
     'mixed zeros not changed #3': 'div{padding:10px 0 0 1px}',
@@ -862,7 +861,7 @@ vows.describe('clean-units').addBatch({
     'font-names': 'body{font-family:\\5FAE\\8F6F\\96C5\\9ED1,\\5B8B\\4F53,sans-serif}'
   }),
   'urls': cssContext({
-    'keep urls without parentheses unchanged': 'a{background:url(/images/blank.png) 0 0 no-repeat}',
+    'keep urls without parentheses unchanged': 'a{background:url(/images/blank.png)}',
     'keep non-encoded data URI unchanged': ".icon-logo{background-image:url('data:image/svg+xml;charset=US-ASCII')}",
     'strip quotes from base64 encoded PNG data URI': [
       ".icon-logo{background-image:url('data:image/png;base64,iVBORw0')}",
@@ -873,25 +872,25 @@ vows.describe('clean-units').addBatch({
       '.icon-logo{background-image:url(data:image/x-icon;base64,AAABAAEAEBA)}'
     ],
     'strip single parentheses': [
-      "a{background:url('/images/blank.png') 0 0 no-repeat}",
-      "a{background:url(/images/blank.png) 0 0 no-repeat}"
+      "a{background:url('/images/blank.png')}",
+      "a{background:url(/images/blank.png)}"
     ],
     'strip double parentheses': [
-      'a{background:url("/images/blank.png") 0 0 no-repeat}',
-      'a{background:url(/images/blank.png) 0 0 no-repeat}'
+      'a{background:url("/images/blank.png")}',
+      'a{background:url(/images/blank.png)}'
     ],
     'strip more': [
-      'p{background:url("/images/blank.png") 0 0 no-repeat}b{display:block}a{background:url("/images/blank2.png") 0 0 no-repeat}',
-      'p{background:url(/images/blank.png) 0 0 no-repeat}b{display:block}a{background:url(/images/blank2.png) 0 0 no-repeat}'
+      'p{background:url("/images/blank.png")}b{display:block}a{background:url("/images/blank2.png")}',
+      'p{background:url(/images/blank.png)}b{display:block}a{background:url(/images/blank2.png)}'
     ],
     'not strip comments if spaces inside': [
-      'p{background:url("/images/long image name.png") 0 0 no-repeat}b{display:block}a{background:url("/images/no-spaces.png") 0 0 no-repeat}',
-      'p{background:url("/images/long image name.png") 0 0 no-repeat}b{display:block}a{background:url(/images/no-spaces.png) 0 0 no-repeat}'
+      'p{background:url("/images/long image name.png")}b{display:block}a{background:url("/images/no-spaces.png")}',
+      'p{background:url("/images/long image name.png")}b{display:block}a{background:url(/images/no-spaces.png)}'
     ],
     'not add a space before url\'s hash': "a{background:url(/fonts/d90b3358-e1e2-4abb-ba96-356983a54c22.svg#d90b3358-e1e2-4abb-ba96-356983a54c22)}",
     'keep urls from being stripped down #1': 'a{background:url(/image-1.0.png)}',
     'keep urls from being stripped down #2': "a{background:url(/image-white.png)}",
-    'keep urls from being stripped down #3': "a{background:#eee url(/libraries/jquery-ui-1.10.1.custom/images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x}",
+    'keep urls from being stripped down #3': "a{background:#eee url(/libraries/jquery-ui-1.10.1.custom/images/ui-bg_highlight-soft_100_eeeeee_1x100.png) repeat-x 50% top}",
     'keep special markers in comments (so order is important)': '/*! __ESCAPED_URL_CLEAN_CSS0__ */a{display:block}',
     'strip new line in urls': [
       'a{background:url(/very/long/\
@@ -905,32 +904,32 @@ path")}',
     ]
   }),
   'urls rewriting - no root or target': cssContext({
-    'no @import': 'a{background:url(test/data/partials/extra/down.gif) 0 0 no-repeat}',
+    'no @import': 'a{background:url(test/data/partials/extra/down.gif) no-repeat}',
     'relative @import': [
       '@import url(test/data/partials-relative/base.css);',
-      'a{background:url(test/data/partials/extra/down.gif) 0 0 no-repeat}'
+      'a{background:url(test/data/partials/extra/down.gif) no-repeat}'
     ],
     'relative @import twice': [
       '@import url(test/data/partials-relative/extra/included.css);',
-      'a{background:url(test/data/partials/extra/down.gif) 0 0 no-repeat}'
+      'a{background:url(test/data/partials/extra/down.gif) no-repeat}'
     ],
     'absolute @import': [
       '@import url(/test/data/partials-relative/base.css);',
-      'a{background:url(test/data/partials/extra/down.gif) 0 0 no-repeat}'
+      'a{background:url(test/data/partials/extra/down.gif) no-repeat}'
     ]
   }),
   'urls rewriting - root but no target': cssContext({
     'no @import': [
-      'a{background:url(../partials/extra/down.gif) 0 0 no-repeat}',
-      'a{background:url(/test/data/partials/extra/down.gif) 0 0 no-repeat}'
+      'a{background:url(../partials/extra/down.gif) no-repeat}',
+      'a{background:url(/test/data/partials/extra/down.gif) no-repeat}'
     ],
     'relative @import': [
       '@import url(base.css);',
-      'a{background:url(/test/data/partials/extra/down.gif) 0 0 no-repeat}'
+      'a{background:url(/test/data/partials/extra/down.gif) no-repeat}'
     ],
     'absolute @import': [
       '@import url(/test/data/partials-relative/base.css);',
-      'a{background:url(/test/data/partials/extra/down.gif) 0 0 no-repeat}'
+      'a{background:url(/test/data/partials/extra/down.gif) no-repeat}'
     ]
   }, {
     root: process.cwd(),
@@ -938,16 +937,16 @@ path")}',
   }),
   'urls rewriting - no root but target': cssContext({
     'no @import': [
-      'a{background:url(../partials/extra/down.gif) 0 0 no-repeat}',
-      'a{background:url(test/data/partials/extra/down.gif) 0 0 no-repeat}'
+      'a{background:url(../partials/extra/down.gif) no-repeat}',
+      'a{background:url(test/data/partials/extra/down.gif) no-repeat}'
     ],
     'relative @import': [
       '@import url(base.css);',
-      'a{background:url(test/data/partials/extra/down.gif) 0 0 no-repeat}'
+      'a{background:url(test/data/partials/extra/down.gif) no-repeat}'
     ],
     'absolute @import': [
       '@import url(/test/data/partials-relative/base.css);',
-      'a{background:url(test/data/partials/extra/down.gif) 0 0 no-repeat}'
+      'a{background:url(test/data/partials/extra/down.gif) no-repeat}'
     ]
   }, {
     target: path.join(process.cwd(), 'test.css'),
@@ -955,16 +954,16 @@ path")}',
   }),
   'urls rewriting - root and target': cssContext({
     'no @import': [
-      'a{background:url(../partials/extra/down.gif) 0 0 no-repeat}',
-      'a{background:url(/test/data/partials/extra/down.gif) 0 0 no-repeat}'
+      'a{background:url(../partials/extra/down.gif) no-repeat}',
+      'a{background:url(/test/data/partials/extra/down.gif) no-repeat}'
     ],
     'relative @import': [
       '@import url(base.css);',
-      'a{background:url(/test/data/partials/extra/down.gif) 0 0 no-repeat}'
+      'a{background:url(/test/data/partials/extra/down.gif) no-repeat}'
     ],
     'absolute @import': [
       '@import url(/test/data/partials-relative/base.css);',
-      'a{background:url(/test/data/partials/extra/down.gif) 0 0 no-repeat}'
+      'a{background:url(/test/data/partials/extra/down.gif) no-repeat}'
     ]
   }, {
     root: process.cwd(),
@@ -2022,7 +2021,11 @@ title']{display:block}",
       'a{border-radius:1em 2em/1em 2em 3em}'
     ],
     'border radius expanded H+V with mixed values #2': 'a{border-radius:1em/1em 1em 1em 2em}',
-    'border radius H+V': 'a{border-radius:50%/100%}'
+    'border radius H+V': 'a{border-radius:50%/100%}',
+    'lost background position': [
+      '.one{background:50% no-repeat}.one{background-image:url(/img.png)}',
+      '.one{background:url(/img.png) no-repeat 50%}'
+    ]
   }),
   'viewport units': cssContext({
     'shorthand margin with viewport width not changed': 'div{margin:5vw}'