Skip to content

Commit a205e5a

Browse files
erikthalenMadLittleMods
authored andcommitted
Added option to preserve at-rule order
Fix MadLittleMods#30
1 parent fe5c821 commit a205e5a

8 files changed

+111
-8
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,13 @@ postcss([
394394
```
395395

396396

397+
### `preserveAtRulesOrder` (default: `false`)
398+
399+
Keeps your at-rules like media queries in the order to defined them.
400+
401+
Ideally, this would be defaulted to `true` and it will be in the next major version. All of the tests expecations need to be updated and probably just drop support for `preserveAtRulesOrder: false`
402+
403+
397404
# Quick Reference/Notes
398405

399406
- This plugin was spawned out of a [discussion on the `cssnext` repo](https://github.com/cssnext/cssnext/issues/99).

index.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,10 @@ var defaults = {
6565
variables: {},
6666
// Preserve variables injected via JS with the `variables` option above
6767
// before serializing to CSS (`false` will remove these variables from output)
68-
preserveInjectedVariables: true
68+
preserveInjectedVariables: true,
69+
// Will write media queries in the same order as in the original file.
70+
// Currently defaulted to false for legacy behavior. We can update to `true` in a major version
71+
preserveAtRulesOrder: false
6972
};
7073

7174
module.exports = postcss.plugin('postcss-css-variables', function(options) {
@@ -249,7 +252,7 @@ module.exports = postcss.plugin('postcss-css-variables', function(options) {
249252
ruleToWorkOn.nodes.slice(0).forEach(function(node) {
250253
if(node.type === 'decl') {
251254
var decl = node;
252-
resolveDecl(decl, map, opts.preserve, logResolveValueResult);
255+
resolveDecl(decl, map, opts.preserve, opts.preserveAtRulesOrder, logResolveValueResult);
253256
}
254257
});
255258
});

lib/resolve-decl.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,9 @@ function eachMapItemDependencyOfDecl(variablesUsedList, map, decl, cb) {
7171

7272
// Resolve the decl with the computed value
7373
// Also add in any media queries that change the value as necessary
74-
function resolveDecl(decl, map, /*optional*/shouldPreserve, /*optional*/logResolveValueResult) {
74+
function resolveDecl(decl, map, /*optional*/shouldPreserve, /*optional*/preserveAtRulesOrder, /*optional*/logResolveValueResult) {
7575
shouldPreserve = shouldPreserve || false;
76+
preserveAtRulesOrder = preserveAtRulesOrder || false;
7677

7778
// Make it chainable
7879
var _logResolveValueResult = function(valueResults) {
@@ -93,6 +94,7 @@ function resolveDecl(decl, map, /*optional*/shouldPreserve, /*optional*/logResol
9394
// Resolve the cascade dependencies
9495
// Now find any at-rule declarations that need to be added below each rule
9596
//console.log('resolveDecl 2');
97+
var previousAtRuleNode;
9698
eachMapItemDependencyOfDecl(valueResults.variablesUsed, map, decl, function(mimicDecl, mapItem) {
9799
var ruleClone = shallowCloneNode(decl.parent);
98100
var declClone = decl.clone();
@@ -129,14 +131,19 @@ function resolveDecl(decl, map, /*optional*/shouldPreserve, /*optional*/logResol
129131
currentAtRuleNode = currentAtRuleNode.parent;
130132
}
131133

132-
// Put the atRuleStructure after the declaration's rule
133-
decl.parent.parent.insertAfter(decl.parent, parentAtRuleNode);
134+
// Put the first atRuleStructure after the declaration's rule,
135+
// and after that, put them right after the previous one
136+
decl.parent.parent.insertAfter(preserveAtRulesOrder && previousAtRuleNode || decl.parent, parentAtRuleNode);
137+
138+
// Save referance of previous atRuleStructure
139+
previousAtRuleNode = parentAtRuleNode
134140
}
135141
else {
136142
ruleClone.selector = mimicDecl.parent.selector;
137143

138-
// Put the atRuleStructure after the declaration's rule
139-
decl.parent.parent.insertAfter(decl.parent, ruleClone);
144+
// Put the first atRuleStructure after the declaration's rule,
145+
// and after that, put them right after the previous one
146+
decl.parent.parent.insertAfter(preserveAtRulesOrder && previousAtRuleNode || decl.parent, ruleClone);
140147
}
141148
});
142149

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
:root {
2+
--width: 150px;
3+
}
4+
5+
@media print {
6+
@media (min-width: 1000px) {
7+
:root {
8+
--width: 300px;
9+
}
10+
11+
@media (min-width: 1250px) {
12+
:root {
13+
--width: 450px;
14+
}
15+
}
16+
}
17+
}
18+
19+
.box {
20+
width: var(--width);
21+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
.box {
2+
width: 150px;
3+
}
4+
5+
@media print {
6+
7+
@media (min-width: 1000px) {
8+
9+
.box{
10+
width: 300px;
11+
}
12+
}
13+
}
14+
15+
@media print {
16+
17+
@media (min-width: 1000px) {
18+
19+
@media (min-width: 1250px) {
20+
21+
.box {
22+
width: 450px;
23+
}
24+
}
25+
}
26+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
:root {
2+
--width: 150px;
3+
}
4+
5+
@media (min-width: 1000px) {
6+
:root {
7+
--width: 300px;
8+
}
9+
}
10+
11+
@media (min-width: 1250px) {
12+
:root {
13+
--width: 450px;
14+
}
15+
}
16+
17+
.box {
18+
width: var(--width);
19+
20+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
.box {
2+
width: 150px;
3+
}
4+
5+
@media (min-width: 1000px) {
6+
.box {
7+
width: 300px;
8+
}
9+
}
10+
11+
@media (min-width: 1250px) {
12+
.box {
13+
width: 450px;
14+
}
15+
}

test/test.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,11 @@ describe('postcss-css-variables', function() {
135135
test('should add rule declaration of property in @media', 'media-query');
136136
test('should add rule declaration of property in @support', 'support-directive');
137137

138-
test('should work with nested @media', 'media-query-nested');
138+
test('should work with @media, preserving rule order', 'media-query-preserve-rule-order', { preserveAtRulesOrder: true });
139+
140+
test('should work with nested @media', 'media-query-nested', { preserveAtRulesOrder: false });
141+
test('should work with nested @media, preserving rule order', 'media-query-nested-preserver-rule-order', { preserveAtRulesOrder: true });
142+
139143

140144
test('should cascade to nested rules', 'cascade-on-nested-rules');
141145

0 commit comments

Comments
 (0)