Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .changeset/at-value-parser-with-value-parser.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
'@css-modules-kit/core': minor
---

refactor(core): parse `@value` with postcss-value-parser

The `@value` parser is reimplemented on top of postcss-value-parser. Behavior for syntax supported by css-loader is unchanged.

For syntax that css-loader does not support (where css-modules-kit does not guarantee a specific behavior), the result changed:

- `@value \\c: #000;` and `@value \'d: #000;` are now parsed as a token declaration instead of reporting an error.
- `@value \31 e: #000;` is now read as the token name `\31` instead of `e`.
86 changes: 63 additions & 23 deletions packages/core/src/parser/at-value-parser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { fakeAtValues, fakeRoot } from '../test/ast.js';
import { parseAtValue } from './at-value-parser.js';

describe('parseAtValue', () => {
test('valid', () => {
test('parses syntax supported by css-loader', () => {
const atValues = fakeAtValues(
fakeRoot(dedent`
@value basic: #000;
Expand Down Expand Up @@ -411,10 +411,14 @@ describe('parseAtValue', () => {
]
`);
});
test('invalid', () => {
// NOTE: These test cases are invalid as the syntax of @value. The behavior when using
// these syntaxes is undefined. A diagnostic like "`@value` is a invalid syntax." may
// or may not be reported.
test('parses syntax unsupported by css-loader', () => {
// NOTE: These syntaxes are not supported by css-loader, so css-modules-kit does not
// guarantee any specific behavior for them. The snapshots below document how the current
// implementation parses them rather than a behavior we commit to.
//
// The `@value \31 e` case is tokenized as `\31` and `e` instead of a single ident `1e`,
// because postcss-value-parser does not interpret CSS escape sequences in identifiers.
// This is a known bug: https://github.com/postcss/postcss-value-parser/issues/64
const atValues = fakeAtValues(
fakeRoot(dedent`
@value;
Expand Down Expand Up @@ -494,38 +498,74 @@ describe('parseAtValue', () => {
"category": "error",
"length": 0,
"start": {
"column": 8,
"column": 10,
"line": 2,
},
"text": "\`\` is invalid syntax.",
},
],
},
{
"diagnostics": [
{
"category": "error",
"length": 17,
"atValue": {
"declarationLoc": {
"end": {
"column": 17,
"line": 3,
"offset": 53,
},
"start": {
"column": 1,
"line": 3,
"offset": 37,
},
"text": "\`@value \\\\c: #000\` is a invalid syntax.",
},
],
"loc": {
"end": {
"column": 11,
"line": 3,
"offset": 47,
},
"start": {
"column": 8,
"line": 3,
"offset": 44,
},
},
"name": "\\\\c",
"type": "valueDeclaration",
},
"diagnostics": [],
},
{
"diagnostics": [
{
"category": "error",
"length": 17,
"atValue": {
"declarationLoc": {
"end": {
"column": 17,
"line": 4,
"offset": 71,
},
"start": {
"column": 1,
"line": 4,
"offset": 55,
},
"text": "\`@value \\'d: #000\` is a invalid syntax.",
},
],
"loc": {
"end": {
"column": 11,
"line": 4,
"offset": 65,
},
"start": {
"column": 8,
"line": 4,
"offset": 62,
},
},
"name": "\\'d",
"type": "valueDeclaration",
},
"diagnostics": [],
},
{
"atValue": {
Expand All @@ -543,17 +583,17 @@ describe('parseAtValue', () => {
},
"loc": {
"end": {
"column": 13,
"column": 11,
"line": 5,
"offset": 85,
"offset": 83,
},
"start": {
"column": 12,
"column": 8,
"line": 5,
"offset": 84,
"offset": 80,
},
},
"name": "e",
"name": "\\31",
"type": "valueDeclaration",
},
"diagnostics": [],
Expand Down
Loading