Skip to content

Commit 62f4010

Browse files
committed
Ensure @charset statements are first
1 parent f7157cf commit 62f4010

File tree

2 files changed

+27
-12
lines changed

2 files changed

+27
-12
lines changed

lib/parse-statements.js

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ function parseMedia(result, atRule) {
6666
}
6767

6868
function parseCharset(result, atRule) {
69+
if (atRule.prev()) {
70+
return result.warn("@charset must precede all other statements", {
71+
node: atRule,
72+
})
73+
}
6974
return {
7075
type: "charset",
7176
node: atRule,
@@ -74,19 +79,20 @@ function parseCharset(result, atRule) {
7479
}
7580

7681
function parseImport(result, atRule) {
77-
let prev = getPrev(atRule)
82+
let prev = atRule.prev()
7883
if (prev) {
7984
do {
8085
if (
81-
prev.type !== "atrule" ||
82-
(prev.name !== "import" && prev.name !== "charset")
86+
prev.type !== "comment" &&
87+
(prev.type !== "atrule" ||
88+
(prev.name !== "import" && prev.name !== "charset"))
8389
) {
8490
return result.warn(
8591
"@import must precede all other statements (besides @charset)",
8692
{ node: atRule }
8793
)
8894
}
89-
prev = getPrev(prev)
95+
prev = prev.prev()
9096
} while (prev)
9197
}
9298

@@ -137,11 +143,3 @@ function parseImport(result, atRule) {
137143

138144
return stmt
139145
}
140-
141-
function getPrev(item) {
142-
let prev = item.prev()
143-
while (prev && prev.type === "comment") {
144-
prev = prev.prev()
145-
}
146-
return prev
147-
}

test/lint.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,23 @@ test("should not warn when @charset or @import statement before", t => {
7878
})
7979
})
8080

81+
test("should warn when @charset is not first", t => {
82+
return Promise.all([
83+
processor.process(`a {} @charset "utf-8";`, { from: undefined }),
84+
processor.process(`@media {} @charset "utf-8";`, { from: undefined }),
85+
processor.process(`/* foo */ @charset "utf-8";`, { from: undefined }),
86+
processor.process(`@import "bar.css"; @charset "utf-8";`, {
87+
from: "test/fixtures/imports/foo.css",
88+
}),
89+
]).then(results => {
90+
results.forEach(result => {
91+
const warnings = result.warnings()
92+
t.is(warnings.length, 1)
93+
t.is(warnings[0].text, "@charset must precede all other statements")
94+
})
95+
})
96+
})
97+
8198
test("should warn when a user didn't close an import with ;", t => {
8299
return processor
83100
.process(`@import url('http://') :root{}`, { from: undefined })

0 commit comments

Comments
 (0)