mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
Ignore consecutive semicolons in the CSS parser (#18532)
Fixes #18523 I swear I'd already landed this but apparently not.
This commit is contained in:
parent
e0eac192ff
commit
798a7bf905
@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Detect classes inside Elixir charlist, word list, and string sigils ([#18432](https://github.com/tailwindlabs/tailwindcss/pull/18432))
|
||||
- Track source locations through `@plugin` and `@config` ([#18345](https://github.com/tailwindlabs/tailwindcss/pull/18345))
|
||||
- Handle when `process.env.DEBUG` is a boolean in `@tailwindcss/node` ([#18485](https://github.com/tailwindlabs/tailwindcss/pull/18485))
|
||||
- Ignore consecutive semicolons in the CSS parser ([#18532](https://github.com/tailwindlabs/tailwindcss/pull/18532))
|
||||
|
||||
## [4.1.11] - 2025-06-26
|
||||
|
||||
|
||||
@ -1078,6 +1078,38 @@ describe.each(['Unix', 'Windows'])('Line endings: %s', (lineEndings) => {
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
it('should ignore consecutive semicolons', () => {
|
||||
expect(parse(';;;')).toEqual([])
|
||||
})
|
||||
|
||||
it('should ignore semicolons after an at-rule with a body', () => {
|
||||
expect(parse('@plugin "foo" {} ;')).toEqual([
|
||||
{
|
||||
kind: 'at-rule',
|
||||
name: '@plugin',
|
||||
params: '"foo"',
|
||||
nodes: [],
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
it('should ignore consecutive semicolons a declaration', () => {
|
||||
expect(parse('.foo { color: red;;; }')).toEqual([
|
||||
{
|
||||
kind: 'rule',
|
||||
selector: '.foo',
|
||||
nodes: [
|
||||
{
|
||||
kind: 'declaration',
|
||||
property: 'color',
|
||||
value: 'red',
|
||||
important: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
describe('errors', () => {
|
||||
@ -1163,22 +1195,6 @@ describe.each(['Unix', 'Windows'])('Line endings: %s', (lineEndings) => {
|
||||
`[Error: Invalid declaration: \`bar\`]`,
|
||||
)
|
||||
})
|
||||
|
||||
it('should error when a semicolon exists after an at-rule with a body', () => {
|
||||
expect(() => parse('@plugin "foo" {} ;')).toThrowErrorMatchingInlineSnapshot(
|
||||
`[Error: Unexpected semicolon]`,
|
||||
)
|
||||
})
|
||||
|
||||
it('should error when consecutive semicolons exist', () => {
|
||||
expect(() => parse(';;;')).toThrowErrorMatchingInlineSnapshot(`[Error: Unexpected semicolon]`)
|
||||
})
|
||||
|
||||
it('should error when consecutive semicolons exist after a declaration', () => {
|
||||
expect(() => parse('.foo { color: red;;; }')).toThrowErrorMatchingInlineSnapshot(
|
||||
`[Error: Unexpected semicolon]`,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
it('ignores BOM at the beginning of a file', () => {
|
||||
|
||||
@ -333,7 +333,7 @@ export function parse(input: string, opts?: ParseOptions) {
|
||||
) {
|
||||
let declaration = parseDeclaration(buffer)
|
||||
if (!declaration) {
|
||||
if (buffer.length === 0) throw new Error('Unexpected semicolon')
|
||||
if (buffer.length === 0) continue
|
||||
throw new Error(`Invalid declaration: \`${buffer.trim()}\``)
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user