diff --git a/lib/parse-statements.js b/lib/parse-statements.js index 5e812fe..f806a0e 100644 --- a/lib/parse-statements.js +++ b/lib/parse-statements.js @@ -14,12 +14,12 @@ module.exports = function parseStatements(result, styles, conditions, from) { styles.each(node => { let stmt if (node.type === "atrule") { - if (node.name === "import") + if (node.name.toLowerCase() === "import") stmt = parseImport(result, node, conditions, from) else if (node.name === "charset") stmt = parseCharset(result, node, conditions, from) else if ( - node.name === "layer" && + node.name.toLowerCase() === "layer" && !encounteredNonImportNodes && !node.nodes ) @@ -78,7 +78,7 @@ function parseImport(result, atRule, conditions, from) { do { if ( prev.type === "comment" || - (prev.type === "atrule" && prev.name === "import") + (prev.type === "atrule" && prev.name.toLowerCase() === "import") ) { prev = prev.prev() continue @@ -95,7 +95,8 @@ function parseImport(result, atRule, conditions, from) { if ( prev.type === "comment" || (prev.type === "atrule" && - (prev.name === "charset" || (prev.name === "layer" && !prev.nodes))) + (prev.name === "charset" || + (prev.name.toLowerCase() === "layer" && !prev.nodes))) ) { prev = prev.prev() continue diff --git a/test/at-rule-case.js b/test/at-rule-case.js new file mode 100644 index 0000000..1404246 --- /dev/null +++ b/test/at-rule-case.js @@ -0,0 +1,27 @@ +"use strict" + +const path = require("path") +const { default: test } = require("ava") +const postcss = require("postcss") +const atImport = require("..") + +for (const input of [ + '@IMPORT "a.css";', + '@ImPoRt "a.css"; @import "b.css";', + '@LAYER base; @IMPORT "a.css";', +]) { + test(`should recognize case-insensitive at-rule names: ${input}`, async t => { + const result = await postcss([ + atImport({ + resolve: id => path.resolve(id), + load: () => "a { color: red; }", + }), + ]).process(input, { from: undefined }) + + t.is(result.warnings().length, 0) + t.false(/@import/i.test(result.css)) + t.true(result.css.includes("color: red")) + if (input.startsWith("@LAYER")) + t.true(result.css.startsWith("@LAYER base;")) + }) +} diff --git a/test/lint.js b/test/lint.js index ffd3602..d437dec 100644 --- a/test/lint.js +++ b/test/lint.js @@ -8,6 +8,21 @@ const atImport = require("..") const processor = postcss().use(atImport()) +test("should warn if uppercase @CHARSET before @import", async t => { + const result = await processor.process( + '@CHARSET "utf-8"; @IMPORT "test/fixtures/imports/foo.css";', + { + from: undefined, + }, + ) + const warnings = result.warnings() + t.is(warnings.length, 1) + t.is( + warnings[0].text, + "@import statements must precede all other statements (besides @charset or empty @layer) and be consecutive", + ) +}) + test("should warn when not @charset and not @import statement before", t => { return Promise.all([ processor.process(`a {} @import "";`, { from: undefined }),