diff --git a/lib/options/sort-order.js b/lib/options/sort-order.js index 98e5083f..5af60b57 100644 --- a/lib/options/sort-order.js +++ b/lib/options/sort-order.js @@ -69,6 +69,11 @@ module.exports = { return false; } + // Remove any empty lines: + if (currentNode[0] === 's') { + currentNode[1] = currentNode[1].replace(/\n[\s\t\n\r]*\n/, '\n'); + } + // If the node is declaration or @-rule, stop and return all // found nodes with spaces and comments (if there are any): if (SC.indexOf(currentNode[0]) === -1) break; @@ -102,6 +107,11 @@ module.exports = { // If there is no node, or it is nor spaces neither comment, stop: if (!currentNode || SC.indexOf(currentNode[0]) === -1) break; + // Remove any empty lines: + if (currentNode[0] === 's') { + currentNode[1] = currentNode[1].replace(/\n[\s\t\n\r]*\n/, '\n'); + } + if (['commentML', 'commentSL'].indexOf(currentNode[0]) > -1) { sc.push(currentNode); d.push(i + 1); @@ -146,6 +156,7 @@ module.exports = { var orderProperty = order[propertyName]; extendedNode = { + i: i, node: currentNode, sc0: sc0, delim: [] @@ -249,7 +260,12 @@ module.exports = { // If a and b have the same group index, and a's property index is // higher than b's property index, in a sorted list a appears after // b: - return a.propertyIndex - b.propertyIndex; + if (a.propertyIndex !== b.propertyIndex) return a.propertyIndex - b.propertyIndex; + + // If a and b have the same group index and the same property index, + // in a sorted list they appear in the same order they were in + // original array: + return a.i - b.i; }); // Build all nodes back together. First go sorted declarations, then diff --git a/test/integral.expect.css b/test/integral.expect.css index c15d9c9d..cf2d68de 100644 --- a/test/integral.expect.css +++ b/test/integral.expect.css @@ -8,7 +8,6 @@ background: -moz-linear-gradient(top, rgba(0,0,0,.2) 0, rgba(0,0,0,.4) 100%); background: -o-linear-gradient(top, rgba(0,0,0,.2) 0,rgba(0,0,0,.4) 100%); background: linear-gradient(to bottom, rgba(0,0,0,.2) 0,rgba(0,0,0,.4) 100%); - -moz-box-shadow: 0 1px 0 rgba(0,0,0,.07); box-shadow: 0 1px 0 rgba(0,0,0,.07); } diff --git a/test/sort-order.js b/test/sort-order.js index bd787c5d..5dd4ffcf 100644 --- a/test/sort-order.js +++ b/test/sort-order.js @@ -120,4 +120,34 @@ describe('options/sort-order', function() { assert.equal(input, expected); }); + + it('Issue 94. Test 1', function() { + var config = comb.getConfig('csscomb'); + + var input = readFile('issue-94-1.css'); + var expected = readFile('issue-94-1.expected.css'); + + comb.configure(config); + assert.equal(comb.processString(input), expected); + }); + + it('Issue 94. Test 2', function() { + var config = comb.getConfig('csscomb'); + + var input = readFile('issue-94-2.css'); + var expected = readFile('issue-94-2.expected.css'); + + comb.configure(config); + assert.equal(comb.processString(input), expected); + }); + + it('Issue 94. Test 3', function() { + var config = comb.getConfig('csscomb'); + + var input = readFile('issue-94-3.css'); + var expected = readFile('issue-94-3.expected.css'); + + comb.configure(config); + assert.equal(comb.processString(input), expected); + }); }); diff --git a/test/sort-order/issue-94-1.css b/test/sort-order/issue-94-1.css new file mode 100644 index 00000000..54131c51 --- /dev/null +++ b/test/sort-order/issue-94-1.css @@ -0,0 +1,18 @@ +.test +{ + position: absolute; + top: -1px; + right: -1px; + bottom: -1px; + left: -1px; + + border: 1px solid transparent; + border-color: rgba(0,0,0,0.38) rgba(0,0,0,0.27) rgba(0,0,0,0.16); + + background: -webkit-linear-gradient(#fff, #fff); + background: linear-gradient(#fff, #fff); + background-clip: padding-box; + background-size: 16px 16px; + + -webkit-appearance: textfield; +} diff --git a/test/sort-order/issue-94-1.expected.css b/test/sort-order/issue-94-1.expected.css new file mode 100644 index 00000000..0943808b --- /dev/null +++ b/test/sort-order/issue-94-1.expected.css @@ -0,0 +1,17 @@ +.test +{ + position: absolute; + top: -1px; + right: -1px; + bottom: -1px; + left: -1px; + + border: 1px solid transparent; + border-color: rgba(0,0,0,.38) rgba(0,0,0,.27) rgba(0,0,0,.16); + background: -webkit-linear-gradient(#fff, #fff); + background: linear-gradient(#fff, #fff); + background-clip: padding-box; + background-size: 16px 16px; + + -webkit-appearance: textfield; +} diff --git a/test/sort-order/issue-94-2.css b/test/sort-order/issue-94-2.css new file mode 100644 index 00000000..0365913c --- /dev/null +++ b/test/sort-order/issue-94-2.css @@ -0,0 +1,19 @@ +.test +{ + width: 0; + width: 100%; + height: 0; + + background: #fff; + color: #000; + + display: -moz-inline-stack; + display: inline-block; + + position: absolute; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; +} diff --git a/test/sort-order/issue-94-2.expected.css b/test/sort-order/issue-94-2.expected.css new file mode 100644 index 00000000..85e618de --- /dev/null +++ b/test/sort-order/issue-94-2.expected.css @@ -0,0 +1,19 @@ +.test +{ + position: absolute; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + + display: -moz-inline-stack; + display: inline-block; + + width: 0; + width: 100%; + height: 0; + + color: #000; + background: #fff; +} diff --git a/test/sort-order/issue-94-3.css b/test/sort-order/issue-94-3.css new file mode 100644 index 00000000..872eddcf --- /dev/null +++ b/test/sort-order/issue-94-3.css @@ -0,0 +1,21 @@ +.input-view { + position: absolute; + -webkit-appearance: none; + right: -1px; + bottom: -1px; + left: -1px; + + border: 1px solid transparent; + + top: -1px; + + background: -webkit-linear-gradient(#FFF, #FFF); + background: linear-gradient(#FFF, #FFF); + background-clip: padding-box; + background-size: 16px 16px; + box-shadow: 0 1px 0 rgba(255,255,255,0.2), inset 0 1px 1px rgba(0,0,0,0.1); + + border-color: rgba(0,0,0,0.27); + border-top-color: rgba(0,0,0,0.38); + border-bottom-color: rgba(0,0,0,0.16); +} diff --git a/test/sort-order/issue-94-3.expected.css b/test/sort-order/issue-94-3.expected.css new file mode 100644 index 00000000..92f29432 --- /dev/null +++ b/test/sort-order/issue-94-3.expected.css @@ -0,0 +1,20 @@ +.input-view +{ + position: absolute; + top: -1px; + right: -1px; + bottom: -1px; + left: -1px; + + border: 1px solid transparent; + border-color: rgba(0,0,0,.27); + border-top-color: rgba(0,0,0,.38); + border-bottom-color: rgba(0,0,0,.16); + background: -webkit-linear-gradient(#fff, #fff); + background: linear-gradient(#fff, #fff); + background-clip: padding-box; + background-size: 16px 16px; + box-shadow: 0 1px 0 rgba(255,255,255,.2), inset 0 1px 1px rgba(0,0,0,.1); + + -webkit-appearance: none; +}