Skip to content

Commit a97507b

Browse files
committed
refactor the logic to make the behaviour a bit more linear
1 parent 45801b4 commit a97507b

File tree

3 files changed

+78
-56
lines changed

3 files changed

+78
-56
lines changed

lib/index.js

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ var createImportedName = options && options.createImportedName || function (impo
2626
};
2727

2828
exports['default'] = function (css) {
29-
/* Find any @value statements that define locals */
30-
var translations = {};
31-
css.walkAtRules('value', function (atRule) {
32-
if (matchImports.exec(atRule.params)) return;
29+
var importAliases = [];
30+
var definitions = {};
31+
32+
var addDefinition = function addDefinition(atRule) {
3333
var matches = undefined;
3434
while (matches = matchLet.exec(atRule.params)) {
3535
var _matches = matches;
@@ -39,25 +39,12 @@ exports['default'] = function (css) {
3939
var /*match*/key = _matches2[1];
4040
var value = _matches2[2];
4141

42-
translations[key] = value;
42+
definitions[key] = value;
4343
atRule.remove();
4444
}
45-
});
46-
47-
/* We want to export anything defined by now, but don't add it to the CSS yet or
48-
it well get picked up by the replacement stuff */
49-
var exportDeclarations = Object.keys(translations).map(function (key) {
50-
return _postcss2['default'].decl({
51-
value: translations[key],
52-
prop: key,
53-
before: "\n ",
54-
_autoprefixerDisabled: true
55-
});
56-
});
45+
};
5746

58-
/* Treat @value statements that import them as defining ICSS tmp vars */
59-
var importAliases = [];
60-
css.walkAtRules('value', function (atRule) {
47+
var addImport = function addImport(atRule) {
6148
var matches = matchImports.exec(atRule.params);
6249
if (matches) {
6350
var _matches3 = _slicedToArray(matches, 3);
@@ -66,7 +53,7 @@ exports['default'] = function (css) {
6653
var path = _matches3[2];
6754

6855
// We can use constants for path names
69-
if (translations[path]) path = translations[path];
56+
if (definitions[path]) path = definitions[path];
7057
var imports = aliases.split(/\s*,\s*/).map(function (alias) {
7158
var tokens = matchImport.exec(alias);
7259
if (tokens) {
@@ -77,7 +64,7 @@ exports['default'] = function (css) {
7764
var myName = _tokens$2 === undefined ? theirName : _tokens$2;
7865

7966
var importedName = createImportedName(myName);
80-
translations[myName] = importedName;
67+
definitions[myName] = importedName;
8168
return { theirName: theirName, importedName: importedName };
8269
} else {
8370
throw new Error('@import statement "' + alias + '" is invalid!');
@@ -86,13 +73,33 @@ exports['default'] = function (css) {
8673
importAliases.push({ path: path, imports: imports });
8774
atRule.remove();
8875
}
76+
};
77+
78+
/* Look at all the @value statements and treat them as locals or as imports */
79+
css.walkAtRules('value', function (atRule) {
80+
if (matchImports.exec(atRule.params)) {
81+
addImport(atRule);
82+
} else {
83+
addDefinition(atRule);
84+
}
85+
});
86+
87+
/* We want to export anything defined by now, but don't add it to the CSS yet or
88+
it well get picked up by the replacement stuff */
89+
var exportDeclarations = Object.keys(definitions).map(function (key) {
90+
return _postcss2['default'].decl({
91+
value: definitions[key],
92+
prop: key,
93+
before: "\n ",
94+
_autoprefixerDisabled: true
95+
});
8996
});
9097

91-
/* If we have no translations, don't continue */
92-
if (!Object.keys(translations).length) return;
98+
/* If we have no definitions, don't continue */
99+
if (!Object.keys(definitions).length) return;
93100

94101
/* Perform replacements */
95-
(0, _icssReplaceSymbols2['default'])(css, translations);
102+
(0, _icssReplaceSymbols2['default'])(css, definitions);
96103

97104
/* Add import rules */
98105
importAliases.forEach(function (_ref) {

src/index.js

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,41 +9,30 @@ let importIndex = 0
99
let createImportedName = options && options.createImportedName || ((importName/*, path*/) => `i__const_${importName.replace(/\W/g, '_')}_${importIndex++}`)
1010

1111
export default css => {
12-
/* Find any @value statements that define locals */
13-
let translations = {}
14-
css.walkAtRules('value', atRule => {
15-
if (matchImports.exec(atRule.params)) return
12+
let importAliases = []
13+
let definitions = {}
14+
15+
const addDefinition = atRule => {
1616
let matches
1717
while (matches = matchLet.exec(atRule.params)) {
1818
let [/*match*/, key, value] = matches
19-
translations[key] = value
19+
definitions[key] = value
2020
atRule.remove()
2121
}
22-
})
23-
24-
/* We want to export anything defined by now, but don't add it to the CSS yet or
25-
it well get picked up by the replacement stuff */
26-
let exportDeclarations = Object.keys(translations).map(key => postcss.decl({
27-
value: translations[key],
28-
prop: key,
29-
before: "\n ",
30-
_autoprefixerDisabled: true
31-
}))
22+
}
3223

33-
/* Treat @value statements that import them as defining ICSS tmp vars */
34-
let importAliases = []
35-
css.walkAtRules('value', atRule => {
24+
const addImport = atRule => {
3625
let matches = matchImports.exec(atRule.params)
3726
if (matches) {
3827
let [/*match*/, aliases, path] = matches
3928
// We can use constants for path names
40-
if (translations[path]) path = translations[path]
29+
if (definitions[path]) path = definitions[path]
4130
let imports = aliases.split(/\s*,\s*/).map(alias => {
4231
let tokens = matchImport.exec(alias)
4332
if (tokens) {
4433
let [/*match*/, theirName, myName = theirName] = tokens
4534
let importedName = createImportedName(myName)
46-
translations[myName] = importedName
35+
definitions[myName] = importedName
4736
return {theirName, importedName}
4837
} else {
4938
throw new Error(`@import statement "${alias}" is invalid!`)
@@ -52,13 +41,31 @@ export default css => {
5241
importAliases.push({path, imports})
5342
atRule.remove()
5443
}
44+
}
45+
46+
/* Look at all the @value statements and treat them as locals or as imports */
47+
css.walkAtRules('value', atRule => {
48+
if (matchImports.exec(atRule.params)) {
49+
addImport(atRule)
50+
} else {
51+
addDefinition(atRule)
52+
}
5553
})
5654

57-
/* If we have no translations, don't continue */
58-
if (!Object.keys(translations).length) return
55+
/* We want to export anything defined by now, but don't add it to the CSS yet or
56+
it well get picked up by the replacement stuff */
57+
let exportDeclarations = Object.keys(definitions).map(key => postcss.decl({
58+
value: definitions[key],
59+
prop: key,
60+
before: "\n ",
61+
_autoprefixerDisabled: true
62+
}))
63+
64+
/* If we have no definitions, don't continue */
65+
if (!Object.keys(definitions).length) return
5966

6067
/* Perform replacements */
61-
replaceSymbols(css, translations)
68+
replaceSymbols(css, definitions)
6269

6370
/* Add import rules */
6471
importAliases.forEach(({path, imports}) => {

test/index.js

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,28 @@ describe('constants', () => {
2727
test('@value blue red; .foo { color: blue; }', ':export {\n blue: red;\n}\n.foo { color: red; }')
2828
})
2929

30-
it('should import a simple constant', () => {
31-
test('@value red from "./colors.css";', ':import("./colors.css") {\n i__const_red_0: red\n}')
30+
it('should import and re-export a simple constant', () => {
31+
test('@value red from "./colors.css";', ':export {\n red: i__const_red_0\n}\n:import("./colors.css") {\n i__const_red_0: red\n}')
3232
})
3333

3434
it('should import a simple constant and replace usages', () => {
35-
test('@value red from "./colors.css"; .foo { color: red; }', ':import("./colors.css") {\n i__const_red_1: red;\n}\n.foo { color: i__const_red_1; }')
35+
test('@value red from "./colors.css"; .foo { color: red; }', ':export {\n red: i__const_red_1;\n}\n:import("./colors.css") {\n i__const_red_1: red;\n}\n.foo { color: i__const_red_1; }')
3636
})
3737

3838
it('should import and alias a constant and replace usages', () => {
39-
test('@value blue as red from "./colors.css"; .foo { color: red; }', ':import("./colors.css") {\n i__const_red_2: blue;\n}\n.foo { color: i__const_red_2; }')
39+
test('@value blue as red from "./colors.css"; .foo { color: red; }', ':export {\n red: i__const_red_2;\n}\n:import("./colors.css") {\n i__const_red_2: blue;\n}\n.foo { color: i__const_red_2; }')
4040
})
4141

4242
it('should import multiple from a single file', () => {
4343
test(
4444
`@value blue, red from "./colors.css";
4545
.foo { color: red; }
4646
.bar { color: blue }`,
47-
`:import("./colors.css") {
47+
`:export {
48+
blue: i__const_blue_3;
49+
red: i__const_red_4;
50+
}
51+
:import("./colors.css") {
4852
i__const_blue_3: blue;
4953
i__const_red_4: red;
5054
}
@@ -55,13 +59,17 @@ describe('constants', () => {
5559
it('should import from a definition', () => {
5660
test(
5761
'@value colors: "./colors.css"; @value red from colors;',
58-
':export {\n colors: "./colors.css"\n}\n' +
62+
':export {\n colors: "./colors.css";\n red: i__const_red_5\n}\n' +
5963
':import("./colors.css") {\n i__const_red_5: red\n}'
6064
)
6165
})
6266

63-
it('should import a simple constant with import-value', () => {
64-
test('@value red from "./colors.css";', ':import("./colors.css") {\n i__const_red_6: red\n}')
67+
it('should only allow values for paths if defined in the right order', () => {
68+
test(
69+
'@value red from colors; @value colors: "./colors.css";',
70+
':export {\n red: i__const_red_6;\n colors: "./colors.css"\n}\n' +
71+
':import(colors) {\n i__const_red_6: red\n}'
72+
)
6573
})
6674
})
6775

0 commit comments

Comments
 (0)