From f3c32e67988c2d0bc05dbf5ad9c296b6bea5eced Mon Sep 17 00:00:00 2001 From: Jakub Pawlowicz Date: Fri, 1 Jan 2016 19:03:52 +0000 Subject: [PATCH] Fixes #693 - restructuring edge case. In case of same properties from different selectors being moved, all selectors should be carried forward as at some point it may not be possible to move them any further. --- History.md | 5 +++++ lib/selectors/restructure.js | 21 +++++++++++++++++++-- test/selectors/restructure-test.js | 4 ++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/History.md b/History.md index 81fb3ec5..8ce74580 100644 --- a/History.md +++ b/History.md @@ -3,6 +3,11 @@ * Requires Node.js 4.0+ to run. +[3.4.9 / 2016-xx-xx](https://github.com/jakubpawlowicz/clean-css/compare/v3.4.8...3.4) +================== + +* Fixed issue [#693](https://github.com/jakubpawlowicz/clean-css/issues/693) - restructuring edge case. + [3.4.8 / 2015-11-13](https://github.com/jakubpawlowicz/clean-css/compare/v3.4.7...v3.4.8) ================== diff --git a/lib/selectors/restructure.js b/lib/selectors/restructure.js index 88cfc04e..c3e17f12 100644 --- a/lib/selectors/restructure.js +++ b/lib/selectors/restructure.js @@ -4,11 +4,19 @@ var stringifyBody = require('../stringifier/one-time').body; var stringifySelectors = require('../stringifier/one-time').selectors; var cleanUpSelectorDuplicates = require('./clean-up').selectorDuplicates; var isSpecial = require('./is-special'); +var cloneArray = require('../utils/clone-array'); function naturalSorter(a, b) { return a > b; } +function cloneAndMergeSelectors(propertyA, propertyB) { + var cloned = cloneArray(propertyA); + cloned[5] = cloned[5].concat(propertyB[5]); + + return cloned; +} + function restructure(tokens, options) { var movableTokens = {}; var movedProperties = []; @@ -273,6 +281,7 @@ function restructure(tokens, options) { var token = tokens[i]; var isSelector; var j, k, m; + var samePropertyAt; if (token[0] == 'selector') { isSelector = true; @@ -314,8 +323,13 @@ function restructure(tokens, options) { } } - if (!movedSameProperty) + if (!movedSameProperty) { movedSameProperty = property[0] == movedProperty[0] && property[1] == movedProperty[1]; + + if (movedSameProperty) { + samePropertyAt = k; + } + } } if (!isSelector || unmovableInCurrentToken.indexOf(j) > -1) @@ -325,8 +339,11 @@ function restructure(tokens, options) { movableTokens[key] = movableTokens[key] || []; movableTokens[key].push(token); - if (!movedSameProperty) + if (movedSameProperty) { + movedProperties[samePropertyAt] = cloneAndMergeSelectors(movedProperties[samePropertyAt], property); + } else { movedProperties.push(property); + } } movedToBeDropped = movedToBeDropped.sort(naturalSorter); diff --git a/test/selectors/restructure-test.js b/test/selectors/restructure-test.js index 48d11224..32b234d2 100644 --- a/test/selectors/restructure-test.js +++ b/test/selectors/restructure-test.js @@ -108,6 +108,10 @@ vows.describe('restructure') '.one{overflow:hidden;border-right:1px solid;border-color:#d4d4d4}.one:last-child{border-right:0}.two{overflow:hidden;border-right:1px solid;border-color:#d4d4d4}', '.one,.two{overflow:hidden}.one{border-right:1px solid;border-color:#d4d4d4}.one:last-child{border-right:0}.two{border-right:1px solid;border-color:#d4d4d4}' ], + 'multiple - over redefined property': [ + 'a,div{text-decoration:none}a{text-decoration:underline;color:#00f}p{text-decoration:underline}', + 'a,div{text-decoration:none}a,p{text-decoration:underline}a{color:#00f}' + ], 'granular two level deep': [ '.one{border:1px solid red;border-right-width:0}.two{border:1px solid red}', '.one{border:1px solid red;border-right-width:0}.two{border:1px solid red}' -- 2.34.1