Skip to content

Commit 563eedd

Browse files
committed
Merge pull request #12 from css-modules/fixed-composes
fixed incorrect composes behavior
2 parents 4b322b3 + f3129e1 commit 563eedd

File tree

24 files changed

+151
-45
lines changed

24 files changed

+151
-45
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
},
3535
"homepage": "https://github.com/geelen/postcss-modules-scope",
3636
"dependencies": {
37-
"css-selector-tokenizer": "^0.3.1",
37+
"css-selector-tokenizer": "^0.5.0",
3838
"postcss": "^4.1.11"
3939
},
4040
"devDependencies": {

src/index.js

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import postcss from 'postcss';
22
import Tokenizer from 'css-selector-tokenizer';
33

4+
let hasOwnProperty = Object.prototype.hasOwnProperty;
5+
46
function getSingleLocalNamesForComposes(selectors) {
57
return selectors.nodes.map((node) => {
68
if(node.type !== 'selector' || node.nodes.length !== 1) {
@@ -75,6 +77,16 @@ const processor = postcss.plugin('postcss-modules-scope', function(options) {
7577
return node;
7678
}
7779

80+
// Find any :import and remember imported names
81+
let importedNames = {};
82+
css.eachRule(rule => {
83+
if(/^:import\(.+\)$/.test(rule.selector)) {
84+
rule.eachDecl(decl => {
85+
importedNames[decl.prop] = true;
86+
});
87+
}
88+
});
89+
7890
// Find any :local classes
7991
css.eachRule(rule => {
8092
let selector = Tokenizer.parse(rule.selector);
@@ -84,9 +96,19 @@ const processor = postcss.plugin('postcss-modules-scope', function(options) {
8496
let localNames = getSingleLocalNamesForComposes(selector);
8597
let classes = decl.value.split(/\s+/);
8698
classes.forEach((className) => {
87-
localNames.forEach((exportedName) => {
88-
exports[exportedName].push(className);
89-
});
99+
if(hasOwnProperty.call(importedNames, className)) {
100+
localNames.forEach((exportedName) => {
101+
exports[exportedName].push(className);
102+
});
103+
} else if(hasOwnProperty.call(exports, className)) {
104+
localNames.forEach((exportedName) => {
105+
exports[className].forEach((item) => {
106+
exports[exportedName].push(item);
107+
});
108+
});
109+
} else {
110+
throw decl.error("referenced class name \"" + className + "\" in composes not found");
111+
}
90112
});
91113
decl.removeSelf();
92114
});
@@ -121,7 +143,7 @@ const processor = postcss.plugin('postcss-modules-scope', function(options) {
121143
// If we found any :locals, insert an :export rule
122144
let exportedNames = Object.keys(exports);
123145
if (exportedNames.length > 0) {
124-
css.prepend(postcss.rule({
146+
css.append(postcss.rule({
125147
selector: `:export`,
126148
nodes: exportedNames.map(exportedName => postcss.decl({
127149
prop: exportedName,
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
referenced class name "otherClassName" in composes not found
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
:local(.className) {
2+
composes: otherClassName;
3+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
._input__simple {
2+
color: red;
3+
}
4+
5+
._input__simple h1 {
6+
color: blue;
7+
}
8+
9+
:export {
10+
simple: _input__simple;
11+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
:local(.simple) {
2+
color: red;
3+
}
4+
5+
:local(.simple) h1 {
6+
color: blue;
7+
}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
:export {
2-
exportName: _lib_components_button__exportName;
3-
}
41
._lib_components_button__exportName {
52
color: green;
63
}
4+
:export {
5+
exportName: _lib_components_button__exportName;
6+
}

test/test-cases/export-class/expected.css

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
:export {
2-
exportName: _input__exportName;
3-
newExport: _input__newExport;
4-
}
5-
61
._input__exportName {
72
color: green;
83
}
@@ -21,3 +16,8 @@
2116
color: blue;
2217
}
2318
}
19+
20+
:export {
21+
exportName: _input__exportName;
22+
newExport: _input__newExport;
23+
}

test/test-cases/export-difficult/expected.css

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
1-
:export {
2-
fadeIn: _input__fadeIn;
3-
fade-in: _input__fade-in;
4-
fade-out: _input__fade-out;
5-
}
6-
71
@keyframes _input__fade-in {
82
from {
93
opacity: 0;
@@ -21,3 +15,9 @@
2115
_input__fade-out 1s :local(wrong);
2216
content: _input__fade-in, wrong, "difficult, :local(wrong)" :local(wrong);
2317
}
18+
19+
:export {
20+
fadeIn: _input__fadeIn;
21+
fade-in: _input__fade-in;
22+
fade-out: _input__fade-out;
23+
}
Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
:export {
2-
fadeIn: _input__fadeIn;
3-
fade-in: _input__fade-in;
4-
}
5-
61
@keyframes _input__fade-in {
72
from {
83
opacity: 0;
94
}
5+
100% {
6+
opacity: 1;
7+
}
108
}
119

1210
@keyframes fade {
@@ -18,3 +16,8 @@
1816
._input__fadeIn {
1917
animation-name: _input__fade-in;
2018
}
19+
20+
:export {
21+
fadeIn: _input__fadeIn;
22+
fade-in: _input__fade-in;
23+
}

0 commit comments

Comments
 (0)