Skip to content

Commit 8247cb5

Browse files
committed
Fix icss-composed contract
1 parent 1a5c786 commit 8247cb5

File tree

2 files changed

+123
-24
lines changed

2 files changed

+123
-24
lines changed

src/index.js

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -128,16 +128,24 @@ const isValue = (messages, name) =>
128128
const isRedeclared = (messages, name) =>
129129
messages.find(msg => msg.type === "icss-scoped" && msg.name === name);
130130

131-
const getComposed = (messages, name) =>
132-
messages
133-
.filter(msg => msg.type === "icss-composed" && msg.name === name)
134-
.map(msg => msg.value);
131+
const flatten = array => array.reduce((acc, item) => [...acc, ...item], []);
132+
133+
const getComposed = (name, messages, root) => [
134+
name,
135+
...flatten(
136+
messages
137+
.filter(msg => msg.name === name && msg.value !== root)
138+
.map(msg => getComposed(msg.value, messages, root))
139+
)
140+
];
135141

136142
const composeAliases = (aliases, messages) =>
137143
Object.keys(aliases).reduce(
138144
(acc, name) =>
139145
Object.assign({}, acc, {
140-
[name]: [aliases[name], ...getComposed(messages, name)].join(" ")
146+
[name]: getComposed(name, messages, name)
147+
.map(value => aliases[value] || value)
148+
.join(" ")
141149
}),
142150
{}
143151
);
@@ -147,6 +155,9 @@ module.exports = postcss.plugin(plugin, (options = {}) => (css, result) => {
147155
options.generateScopedName ||
148156
genericNames("[name]__[local]---[hash:base64:5]");
149157
const input = (css && css.source && css.source.input) || {};
158+
const composedMessages = result.messages.filter(
159+
msg => msg.type === "icss-composed"
160+
);
150161
const aliases = {};
151162
walkRules(css, rule => {
152163
const getAlias = name => {
@@ -177,5 +188,5 @@ module.exports = postcss.plugin(plugin, (options = {}) => (css, result) => {
177188
});
178189
result.messages.push(...getMessages(aliases));
179190
// icss-composed contract
180-
addExports(css, composeAliases(aliases, result.messages));
191+
addExports(css, composeAliases(aliases, composedMessages));
181192
});

test/test.js

Lines changed: 106 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -761,24 +761,9 @@ test("icss-scoped contract", () => {
761761

762762
test("icss-composed contract", () => {
763763
const inputMessages = [
764-
{
765-
plugin: "previous-plugin",
766-
type: "icss-composed",
767-
name: "foo",
768-
value: "__compose__foo1"
769-
},
770-
{
771-
plugin: "previous-plugin",
772-
type: "icss-composed",
773-
name: "foo",
774-
value: "__compose__foo2"
775-
},
776-
{
777-
plugin: "previous-plugin",
778-
type: "icss-composed",
779-
name: "bar",
780-
value: "__compose__bar"
781-
}
764+
{ type: "icss-composed", name: "foo", value: "__compose__foo1" },
765+
{ type: "icss-composed", name: "foo", value: "__compose__foo2" },
766+
{ type: "icss-composed", name: "bar", value: "__compose__bar" }
782767
];
783768
return runMessages({
784769
fixture: `
@@ -825,6 +810,109 @@ test("icss-composed contract", () => {
825810
});
826811
});
827812

813+
test("icss-composed contract with local dependencies", () => {
814+
const inputMessages = [
815+
{ type: "icss-composed", name: "bar", value: "foo" },
816+
{ type: "icss-composed", name: "tar", value: "baz" },
817+
{ type: "icss-composed", name: "doo", value: "bar" },
818+
{ type: "icss-composed", name: "doo", value: "tar" }
819+
];
820+
return runMessages({
821+
fixture: `
822+
.foo {}
823+
.bar {}
824+
.baz {}
825+
.tar {}
826+
.doo {}
827+
`,
828+
expected: `
829+
:export {
830+
foo: __scope__foo;
831+
bar: __scope__bar __scope__foo;
832+
baz: __scope__baz;
833+
tar: __scope__tar __scope__baz;
834+
doo: __scope__doo __scope__bar __scope__foo __scope__tar __scope__baz
835+
}
836+
.__scope__foo {}
837+
.__scope__bar {}
838+
.__scope__baz {}
839+
.__scope__tar {}
840+
.__scope__doo {}
841+
`,
842+
inputMessages,
843+
outputMessages: [
844+
...inputMessages,
845+
{
846+
plugin: "postcss-icss-selectors",
847+
type: "icss-scoped",
848+
name: "foo",
849+
value: "__scope__foo"
850+
},
851+
{
852+
plugin: "postcss-icss-selectors",
853+
type: "icss-scoped",
854+
name: "bar",
855+
value: "__scope__bar"
856+
},
857+
{
858+
plugin: "postcss-icss-selectors",
859+
type: "icss-scoped",
860+
name: "baz",
861+
value: "__scope__baz"
862+
},
863+
{
864+
plugin: "postcss-icss-selectors",
865+
type: "icss-scoped",
866+
name: "tar",
867+
value: "__scope__tar"
868+
},
869+
{
870+
plugin: "postcss-icss-selectors",
871+
type: "icss-scoped",
872+
name: "doo",
873+
value: "__scope__doo"
874+
}
875+
]
876+
});
877+
});
878+
879+
test("icss-composed contract with recursive local composition", () => {
880+
const inputMessages = [
881+
{ type: "icss-composed", name: "foo", value: "bar" },
882+
{ type: "icss-composed", name: "bar", value: "foo" }
883+
];
884+
return runMessages({
885+
fixture: `
886+
.foo {}
887+
.bar {}
888+
`,
889+
expected: `
890+
:export {
891+
foo: __scope__foo __scope__bar;
892+
bar: __scope__bar __scope__foo
893+
}
894+
.__scope__foo {}
895+
.__scope__bar {}
896+
`,
897+
inputMessages,
898+
outputMessages: [
899+
...inputMessages,
900+
{
901+
plugin: "postcss-icss-selectors",
902+
type: "icss-scoped",
903+
name: "foo",
904+
value: "__scope__foo"
905+
},
906+
{
907+
plugin: "postcss-icss-selectors",
908+
type: "icss-scoped",
909+
name: "bar",
910+
value: "__scope__bar"
911+
}
912+
]
913+
});
914+
});
915+
828916
test("icss-value contract", () => {
829917
const inputMessages = [
830918
{

0 commit comments

Comments
 (0)