From 3ebdcd51a27e07c25e28e7675db8cbb3c528b2f0 Mon Sep 17 00:00:00 2001 From: Evilebot Tnawi Date: Wed, 28 Nov 2018 17:45:51 +0300 Subject: [PATCH] fix: handle uppercase `URL` in `import` at-rules (#818) --- lib/plugins/postcss-import-parser.js | 72 +++++++++++-------- test/__snapshots__/import-option.test.js.snap | 9 +-- 2 files changed, 46 insertions(+), 35 deletions(-) diff --git a/lib/plugins/postcss-import-parser.js b/lib/plugins/postcss-import-parser.js index cde65b4f..15a42045 100644 --- a/lib/plugins/postcss-import-parser.js +++ b/lib/plugins/postcss-import-parser.js @@ -1,9 +1,46 @@ const postcss = require('postcss'); +const valueParser = require('postcss-value-parser'); const loaderUtils = require('loader-utils'); -const Tokenizer = require('css-selector-tokenizer'); const pluginName = 'postcss-import-parser'; +function getArg(nodes) { + return nodes.length !== 0 && nodes[0].type === 'string' + ? nodes[0].value + : valueParser.stringify(nodes); +} + +function getUrl(node) { + if (node.type === 'function' && node.value.toLowerCase() === 'url') { + return getArg(node.nodes); + } + + if (node.type === 'string') { + return node.value; + } + + return ''; +} + +function parseImport(params) { + const { nodes } = valueParser(params); + + if (nodes.length === 0) { + return null; + } + + const url = getUrl(nodes[0]); + + if (url.trim().length === 0) { + return null; + } + + return { + url, + media: valueParser.stringify(nodes.slice(1)).trim(), + }; +} + module.exports = postcss.plugin( pluginName, (options) => @@ -25,43 +62,22 @@ module.exports = postcss.plugin( return; } - const values = Tokenizer.parseValues(atrule.params); - let [url] = values.nodes[0].nodes; + const parsed = parseImport(atrule.params); - if (url && url.type === 'url') { - ({ url } = url); - } else if (url && url.type === 'string') { - url = url.value; - } else { - result.warn(`Unable to find uri in '${atrule.toString()}'`, { + if (!parsed) { + // eslint-disable-next-line consistent-return + return result.warn(`Unable to find uri in '${atrule.toString()}'`, { node: atrule, }); - - return; } - if (!url.replace(/\s/g, '').length) { - result.warn(`Unable to find uri in '${atrule.toString()}'`, { - node: atrule, - }); - - return; - } - - values.nodes[0].nodes.shift(); - - const mediaQuery = Tokenizer.stringifyValues(values); - - url = url.trim(); + let { url } = parsed; if (loaderUtils.isUrlRequest(url)) { url = loaderUtils.urlToRequest(url); } - importItems.push({ - url, - mediaQuery, - }); + importItems.push({ url, mediaQuery: parsed.media }); atrule.remove(); }); diff --git a/test/__snapshots__/import-option.test.js.snap b/test/__snapshots__/import-option.test.js.snap index 10945f03..f4505bca 100644 --- a/test/__snapshots__/import-option.test.js.snap +++ b/test/__snapshots__/import-option.test.js.snap @@ -184,8 +184,7 @@ Array [ ], Array [ 1, - "@import URL(test.css); -@import url(); + "@import url(); @import url(''); @import url(\\"\\"); @import ''; @@ -234,7 +233,7 @@ exports.i(require(\\"-!../../../index.js??ref--4-0!./query.css?foo=1&bar=1\\"), exports.i(require(\\"-!../../../index.js??ref--4-0!./other-query.css?foo=1&bar=1#hash\\"), \\"\\"); // module -exports.push([module.id, \\"@import URL(test.css);\\\\n@import url();\\\\n@import url('');\\\\n@import url(\\\\\\"\\\\\\");\\\\n@import '';\\\\n@import \\\\\\"\\\\\\";\\\\n@import \\\\\\" \\\\\\";\\\\n@import \\\\\\"\\\\n\\\\\\";\\\\n@import url();\\\\n@import url('');\\\\n@import url(\\\\\\"\\\\\\");\\\\n@import ;\\\\n@import foo-bar;\\\\n@import-normalize;\\\\n@import url('http://') :root {}\\\\n\\\\n.class {\\\\n a: b c d;\\\\n}\\\\n\\\\n.foo {\\\\n @import 'path.css';\\\\n}\\\\n\\", \\"\\"]); +exports.push([module.id, \\"@import url();\\\\n@import url('');\\\\n@import url(\\\\\\"\\\\\\");\\\\n@import '';\\\\n@import \\\\\\"\\\\\\";\\\\n@import \\\\\\" \\\\\\";\\\\n@import \\\\\\"\\\\n\\\\\\";\\\\n@import url();\\\\n@import url('');\\\\n@import url(\\\\\\"\\\\\\");\\\\n@import ;\\\\n@import foo-bar;\\\\n@import-normalize;\\\\n@import url('http://') :root {}\\\\n\\\\n.class {\\\\n a: b c d;\\\\n}\\\\n\\\\n.foo {\\\\n @import 'path.css';\\\\n}\\\\n\\", \\"\\"]); // exports " @@ -295,9 +294,5 @@ Warning Warning (40:1) It looks like you didn't end your @import statement correctly. Child nodes are attached to it.", - "ModuleWarning: Module Warning (from \`replaced original path\`): -Warning - -(5:1) Unable to find uri in '@import URL(test.css)'", ] `;