Skip to content

Commit d71cf33

Browse files
Recognize case-insensitive import and layer at-rule names (#615)
Co-authored-by: Ryan Zimmerman <opensrc@ryanzim.com>
1 parent f9bb3d6 commit d71cf33

3 files changed

Lines changed: 47 additions & 4 deletions

File tree

‎lib/parse-statements.js‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ module.exports = function parseStatements(result, styles, conditions, from) {
1414
styles.each(node => {
1515
let stmt
1616
if (node.type === "atrule") {
17-
if (node.name === "import")
17+
if (node.name.toLowerCase() === "import")
1818
stmt = parseImport(result, node, conditions, from)
1919
else if (node.name === "charset")
2020
stmt = parseCharset(result, node, conditions, from)
2121
else if (
22-
node.name === "layer" &&
22+
node.name.toLowerCase() === "layer" &&
2323
!encounteredNonImportNodes &&
2424
!node.nodes
2525
)
@@ -78,7 +78,7 @@ function parseImport(result, atRule, conditions, from) {
7878
do {
7979
if (
8080
prev.type === "comment" ||
81-
(prev.type === "atrule" && prev.name === "import")
81+
(prev.type === "atrule" && prev.name.toLowerCase() === "import")
8282
) {
8383
prev = prev.prev()
8484
continue
@@ -95,7 +95,8 @@ function parseImport(result, atRule, conditions, from) {
9595
if (
9696
prev.type === "comment" ||
9797
(prev.type === "atrule" &&
98-
(prev.name === "charset" || (prev.name === "layer" && !prev.nodes)))
98+
(prev.name === "charset" ||
99+
(prev.name.toLowerCase() === "layer" && !prev.nodes)))
99100
) {
100101
prev = prev.prev()
101102
continue

‎test/at-rule-case.js‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"use strict"
2+
3+
const path = require("path")
4+
const { default: test } = require("ava")
5+
const postcss = require("postcss")
6+
const atImport = require("..")
7+
8+
for (const input of [
9+
'@IMPORT "a.css";',
10+
'@ImPoRt "a.css"; @import "b.css";',
11+
'@LAYER base; @IMPORT "a.css";',
12+
]) {
13+
test(`should recognize case-insensitive at-rule names: ${input}`, async t => {
14+
const result = await postcss([
15+
atImport({
16+
resolve: id => path.resolve(id),
17+
load: () => "a { color: red; }",
18+
}),
19+
]).process(input, { from: undefined })
20+
21+
t.is(result.warnings().length, 0)
22+
t.false(/@import/i.test(result.css))
23+
t.true(result.css.includes("color: red"))
24+
if (input.startsWith("@LAYER"))
25+
t.true(result.css.startsWith("@LAYER base;"))
26+
})
27+
}

‎test/lint.js‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,21 @@ const atImport = require("..")
88

99
const processor = postcss().use(atImport())
1010

11+
test("should warn if uppercase @CHARSET before @import", async t => {
12+
const result = await processor.process(
13+
'@CHARSET "utf-8"; @IMPORT "test/fixtures/imports/foo.css";',
14+
{
15+
from: undefined,
16+
},
17+
)
18+
const warnings = result.warnings()
19+
t.is(warnings.length, 1)
20+
t.is(
21+
warnings[0].text,
22+
"@import statements must precede all other statements (besides @charset or empty @layer) and be consecutive",
23+
)
24+
})
25+
1126
test("should warn when not @charset and not @import statement before", t => {
1227
return Promise.all([
1328
processor.process(`a {} @import "";`, { from: undefined }),

0 commit comments

Comments
 (0)