diff --git a/src/index.js b/src/index.js index 380871a..c7e3ff4 100644 --- a/src/index.js +++ b/src/index.js @@ -107,7 +107,7 @@ const plugin = (options = {}) => { Once(root, { rule }) { const exports = Object.create(null); - function exportScopedName(name, rawName, node, needExport = true) { + function exportScopedName(name, rawName, node) { const scopedName = generateScopedName( rawName ? rawName : name, root.source.input.from, @@ -123,10 +123,6 @@ const plugin = (options = {}) => { ); const { key, value } = exportEntry; - if (!needExport) { - return scopedName; - } - exports[key] = exports[key] || []; if (exports[key].indexOf(value) < 0) { @@ -136,18 +132,17 @@ const plugin = (options = {}) => { return scopedName; } - function localizeNode(node, needExport = true) { + function localizeNode(node) { switch (node.type) { case "selector": - node.nodes = node.map((item) => localizeNode(item, needExport)); + node.nodes = node.map((item) => localizeNode(item)); return node; case "class": return selectorParser.className({ value: exportScopedName( node.value, node.raws && node.raws.value ? node.raws.value : null, - node, - needExport + node ), }); case "id": { @@ -155,8 +150,7 @@ const plugin = (options = {}) => { value: exportScopedName( node.value, node.raws && node.raws.value ? node.raws.value : null, - node, - needExport + node ), }); } @@ -166,7 +160,7 @@ const plugin = (options = {}) => { attribute: node.attribute, operator: node.operator, quoteMark: "'", - value: exportScopedName(node.value, null, null, needExport), + value: exportScopedName(node.value, null, null), }); } } @@ -236,35 +230,39 @@ const plugin = (options = {}) => { rule.selector = traverseNode(parsedSelector.clone()).toString(); - rule.walkDecls(/composes|compose-with/i, (decl) => { + rule.walkDecls(/^(composes|compose-with)$/i, (decl) => { const localNames = getSingleLocalNamesForComposes( parsedSelector, decl.parent ); - const classes = decl.value.split(/\s+/); + const multiple = decl.value.split(","); - classes.forEach((className) => { - const global = /^global\(([^)]+)\)$/.exec(className); + multiple.forEach((value) => { + const classes = value.trim().split(/\s+/); - if (global) { - localNames.forEach((exportedName) => { - exports[exportedName].push(global[1]); - }); - } else if (hasOwnProperty.call(importedNames, className)) { - localNames.forEach((exportedName) => { - exports[exportedName].push(className); - }); - } else if (hasOwnProperty.call(exports, className)) { - localNames.forEach((exportedName) => { - exports[className].forEach((item) => { - exports[exportedName].push(item); + classes.forEach((className) => { + const global = /^global\(([^)]+)\)$/.exec(className); + + if (global) { + localNames.forEach((exportedName) => { + exports[exportedName].push(global[1]); }); - }); - } else { - throw decl.error( - `referenced class name "${className}" in ${decl.prop} not found` - ); - } + } else if (hasOwnProperty.call(importedNames, className)) { + localNames.forEach((exportedName) => { + exports[exportedName].push(className); + }); + } else if (hasOwnProperty.call(exports, className)) { + localNames.forEach((exportedName) => { + exports[className].forEach((item) => { + exports[exportedName].push(item); + }); + }); + } else { + throw decl.error( + `referenced class name "${className}" in ${decl.prop} not found` + ); + } + }); }); decl.remove(); diff --git a/test/test-cases/composes-only-allowed/expected.css b/test/test-cases/composes-only-allowed/expected.css new file mode 100644 index 0000000..c3c9f70 --- /dev/null +++ b/test/test-cases/composes-only-allowed/expected.css @@ -0,0 +1,9 @@ +._input__class { + a-composes: global(c); + composes-b: global(d); + a-composes-b: global(e); + a-compose-with-b: global(b); +} +:export { + class: _input__class a b; +} diff --git a/test/test-cases/composes-only-allowed/source.css b/test/test-cases/composes-only-allowed/source.css new file mode 100644 index 0000000..9dbf562 --- /dev/null +++ b/test/test-cases/composes-only-allowed/source.css @@ -0,0 +1,8 @@ +:local(.class) { + composes: global(a); + compose-with: global(b); + a-composes: global(c); + composes-b: global(d); + a-composes-b: global(e); + a-compose-with-b: global(b); +} diff --git a/test/test-cases/multiple-composes/expected.css b/test/test-cases/multiple-composes/expected.css new file mode 100644 index 0000000..c3a404d --- /dev/null +++ b/test/test-cases/multiple-composes/expected.css @@ -0,0 +1,12 @@ +:import("path") { + i__i_a_0: a; + i__i_b_0: b; + i__i_c_0: c; + i__i_d_0: d; +} +._input__class { + color: red; +} +:export { + class: _input__class i__i_a_0 i__i_b_0 i__i_c_0 d e f i__i_d_0; +} diff --git a/test/test-cases/multiple-composes/source.css b/test/test-cases/multiple-composes/source.css new file mode 100644 index 0000000..cd5fe82 --- /dev/null +++ b/test/test-cases/multiple-composes/source.css @@ -0,0 +1,10 @@ +:import("path") { + i__i_a_0: a; + i__i_b_0: b; + i__i_c_0: c; + i__i_d_0: d; +} +:local(.class) { + composes: i__i_a_0 i__i_b_0, i__i_c_0, global(d) global(e), global(f), i__i_d_0; + color: red; +}