Skip to content

Commit 7bc7697

Browse files
committed
Made the postcss plugin only process the right nodes
Fixes #22
1 parent 0a39b1b commit 7bc7697

File tree

6 files changed

+154
-27
lines changed

6 files changed

+154
-27
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# CHANGELOG
22

3+
## 1.2.5 (2017-03-25)
4+
5+
- Fixed a bug where the postcss plugin processed nodes it shouldn't have
6+
37
## 1.2.4 (2017-03-20)
48

59
- Fixed a bug where initialiseAllContainers didn't trigger adjust calls on dom

__mocks__/Node.js

+12
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,35 @@
11
/**
22
* @class
33
* @property {string} selector
4+
* @property {string} params
45
* @property {string} name
56
* @property {string} type
67
* @property {string} prop
78
* @property {string} value
89
* @property {Node[]} nodes
10+
* @property {Node} parent
911
*/
1012
export default class Node {
1113
/**
1214
* @param {{
1315
* [selector]: string,
16+
* [params]: string,
1417
* [name]: string,
1518
* [type]: string,
1619
* [prop]: string,
1720
* [value]: string,
21+
* [parent]: { type: string },
1822
* }} props
1923
*/
2024
constructor (props) {
2125
this.nodes = [];
2226
this.selector = props.selector;
27+
this.params = props.params;
2328
this.name = props.name;
2429
this.type = props.type;
2530
this.prop = props.prop;
2631
this.value = props.value;
32+
this.parent = props.parent;
2733
}
2834

2935
/**
@@ -32,6 +38,8 @@ export default class Node {
3238
* @returns {Node}
3339
*/
3440
addNode (node) {
41+
node.parent = this;
42+
3543
this.nodes.push(node);
3644

3745
return this;
@@ -40,4 +48,8 @@ export default class Node {
4048
error (message) {
4149
throw new Error(message);
4250
}
51+
52+
remove () {
53+
// ...
54+
}
4355
}

__mocks__/Root.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,16 @@
44
*/
55
export default class Root {
66
/**
7-
* @param {Object} source
7+
* @param {Object} [source]
88
*/
99
constructor (source) {
10+
this.type = 'root';
1011
this.nodes = [];
11-
this.source = source;
12+
this.source = {
13+
input: {
14+
file: 'non/existent/file/path.css',
15+
},
16+
};
1217
}
1318

1419
/**
@@ -17,6 +22,8 @@ export default class Root {
1722
* @returns {Node}
1823
*/
1924
addNode (node) {
25+
node.parent = this;
26+
2027
this.nodes.push(node);
2128

2229
return this;

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@zeecoder/container-query",
3-
"version": "1.2.4",
3+
"version": "1.2.5",
44
"description": "A PostCSS plugin and Javascript runtime combination, which allows you to write @container queries in your CSS the same way you would write @media queries.",
55
"main": "index.js",
66
"author": "Viktor Hubert <[email protected]>",

src/postcss/containerQuery.js

+22-3
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,28 @@ function addStylesToDefaultQuery (defaultElementRef, styles, keepValues = false)
1616
}
1717
}
1818

19+
/**
20+
* Process only rules having "root", @media or @container as the parent.
21+
*
22+
* @param {Node} node
23+
*/
24+
function shouldProcessNode (node) {
25+
return (
26+
node.parent.type === 'root' ||
27+
(
28+
node.parent.type === 'atrule' &&
29+
[ 'container', 'media' ].indexOf(node.parent.name) !== -1
30+
)
31+
);
32+
}
33+
1934
/**
2035
* @param {{ getJSON: function }} options
2136
*/
2237
function containerQuery (options = {}) {
2338
const getJSON = options.getJSON || saveJSON;
2439

25-
return function (css) {
40+
return function (root) {
2641
let containers = {};
2742
let currentContainerSelector = null;
2843
let currentDefaultQuery = null;
@@ -59,7 +74,11 @@ function containerQuery (options = {}) {
5974
currentContainerSelector = newContainer;
6075
}
6176

62-
css.walk((/** Node */ node) => {
77+
root.walk((/** Node */ node) => {
78+
if (!shouldProcessNode(node)) {
79+
return;
80+
}
81+
6382
if (node.type === 'rule') {
6483
// Check if there's a new container declared in the rule node
6584
const newContainer = detectContainerDefinition(node);
@@ -123,7 +142,7 @@ function containerQuery (options = {}) {
123142

124143
flushCurrentContainerData();
125144

126-
getJSON(css.source.input.file, containers);
145+
getJSON(root.source.input.file, containers);
127146
};
128147

129148
}

src/postcss/containerQuery.spec.js

+106-21
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,13 @@ test('should use the default json saving function if none was supplied', () => {
1616

1717
const pluginInstance = containerQuery();
1818

19-
pluginInstance(
20-
(new Root({
21-
input: {
22-
file: 'file/path.css'
23-
}
24-
}))
25-
);
19+
pluginInstance(new Root());
2620

2721
expect(saveJSON).toHaveBeenCalledTimes(1);
2822
});
2923

3024
test('missing container declaration', () => {
31-
const pluginInstance = containerQuery({ getJson: () => {} });
25+
const pluginInstance = containerQuery();
3226

3327
expect(() => {
3428
pluginInstance(
@@ -44,21 +38,112 @@ test('missing container declaration', () => {
4438
}).toThrowError(new RegExp(`^A @container query was found, without a preceding @${DEFINE_CONTAINER_NAME} declaration.$`));
4539
});
4640

47-
test('A container should not be able to ', () => {
48-
const pluginInstance = containerQuery({ getJson: () => {} });
41+
test('should ignore unrecognised at-rules, like @keyframes', (done) => {
42+
const pluginInstance = containerQuery({
43+
getJSON: (path, json) => {
44+
expect(json).toEqual({
45+
'.container': {
46+
selector: '.container',
47+
queries: [
48+
{
49+
elements: [
50+
{
51+
selector: '.container',
52+
styles: { fontSize: '', lineHeight: `100${HEIGHT_UNIT}px` },
53+
},
54+
],
55+
},
56+
{
57+
conditions: [ [ [ 'orientation', ':', 'landscape' ] ] ],
58+
elements: [
59+
{
60+
selector: '.container',
61+
styles: { fontSize: '24px' },
62+
}
63+
],
64+
},
65+
],
66+
},
67+
});
68+
done();
69+
},
70+
});
4971

50-
expect(() => {
51-
pluginInstance(
52-
(new Root())
53-
.addNode(
54-
new Node({
72+
pluginInstance(
73+
(new Root())
74+
.addNode(
75+
new Node({
76+
type: 'rule',
77+
selector: '.container',
78+
})
79+
.addNode(new Node({
80+
type: 'decl',
81+
prop: 'line-height',
82+
value: `100${HEIGHT_UNIT}px`,
83+
}))
84+
.addNode(new Node({
85+
type: 'decl',
86+
prop: 'font-size',
87+
value: '42px',
88+
}))
89+
.addNode(new Node({
5590
type: 'atrule',
56-
name: 'container',
57-
params: '(orientation: landscape)',
58-
})
59-
)
60-
)
61-
}).toThrowError(new RegExp(`^A @container query was found, without a preceding @${DEFINE_CONTAINER_NAME} declaration.$`));
91+
name: DEFINE_CONTAINER_NAME,
92+
}))
93+
.addNode(new Node({
94+
type: 'decl',
95+
prop: 'border',
96+
value: 'none',
97+
}))
98+
)
99+
.addNode(
100+
new Node({
101+
type: 'atrule',
102+
name: 'keyframes',
103+
params: 'Expand',
104+
})
105+
.addNode(
106+
new Node({
107+
type: 'rule',
108+
selector: '0%',
109+
})
110+
.addNode(new Node({
111+
type: 'decl',
112+
prop: 'opacity',
113+
value: '0%',
114+
}))
115+
)
116+
.addNode(
117+
new Node({
118+
type: 'rule',
119+
selector: '100%',
120+
})
121+
.addNode(new Node({
122+
type: 'decl',
123+
prop: 'opacity',
124+
value: '100%',
125+
}))
126+
)
127+
)
128+
.addNode(
129+
new Node({
130+
type: 'atrule',
131+
name: 'container',
132+
params: '(orientation: landscape)',
133+
})
134+
.addNode(
135+
new Node({
136+
type: 'rule',
137+
selector: '.container',
138+
})
139+
.addNode({
140+
type: 'decl',
141+
prop: 'font-size',
142+
value: '24px',
143+
})
144+
)
145+
)
146+
);
62147
});
63148

64149
test('proper json and css output', () => {

0 commit comments

Comments
 (0)