Skip to content

feat: improve unknown at-rule parsing with RAW prelude and conditiona…#169

Merged
bartveneman merged 1 commit intomainfrom
feat/parse-unknown-atrules
Mar 10, 2026
Merged

feat: improve unknown at-rule parsing with RAW prelude and conditiona…#169
bartveneman merged 1 commit intomainfrom
feat/parse-unknown-atrules

Conversation

@bartveneman
Copy link
Member

…l block

Previously, unknown at-rules had two problems:

  1. Their prelude was wrapped in AT_RULE_PRELUDE even though the prelude parser returned no structured children — a RAW node is more accurate.
  2. Their block was parsed as rules-only, so declarations like @custom { color: red } were silently dropped.

Prelude: the node type is now decided by what the prelude parser returns. If parse_prelude() produces structured nodes, AT_RULE_PRELUDE is used. If it returns [] (unknown at-rule), a RAW node is used instead. No hardcoded list required — the prelude parser already knows what it handles.

Block: the "rules-only" else branch is replaced with the conditional branch (declarations + rules + at-rules). This is safe for @Keyframes because parse_declaration() returns null for frame selectors without consuming tokens, producing an identical AST.

Examples:
@Custom prelude; → prelude is RAW (was AT_RULE_PRELUDE)
@Custom { color: red } → block contains DECLARATION (was dropped)
@Custom { .a { } } → block contains STYLE_RULE (unchanged)
@Custom { @media { } } → block contains AT_RULE (was dropped)
@Keyframes foo { from {} } → prelude still AT_RULE_PRELUDE (unchanged)

Removes CONDITIONAL_AT_RULES set and atrule_is_conditional() method as dead code after the block-parsing simplification.

…l block

Previously, unknown at-rules had two problems:
1. Their prelude was wrapped in AT_RULE_PRELUDE even though the prelude
   parser returned no structured children — a RAW node is more accurate.
2. Their block was parsed as rules-only, so declarations like
   `@custom { color: red }` were silently dropped.

Prelude: the node type is now decided by what the prelude parser returns.
If `parse_prelude()` produces structured nodes, AT_RULE_PRELUDE is used.
If it returns [] (unknown at-rule), a RAW node is used instead. No
hardcoded list required — the prelude parser already knows what it handles.

Block: the "rules-only" else branch is replaced with the conditional branch
(declarations + rules + at-rules). This is safe for @Keyframes because
`parse_declaration()` returns null for frame selectors without consuming
tokens, producing an identical AST.

Examples:
  @Custom prelude;          → prelude is RAW (was AT_RULE_PRELUDE)
  @Custom { color: red }   → block contains DECLARATION (was dropped)
  @Custom { .a { } }       → block contains STYLE_RULE (unchanged)
  @Custom { @media { } }   → block contains AT_RULE (was dropped)
  @Keyframes foo { from {} } → prelude still AT_RULE_PRELUDE (unchanged)

Removes CONDITIONAL_AT_RULES set and atrule_is_conditional() method
as dead code after the block-parsing simplification.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@codecov-commenter
Copy link

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.99%. Comparing base (3c310a9) to head (0e30c93).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #169      +/-   ##
==========================================
+ Coverage   94.97%   94.99%   +0.01%     
==========================================
  Files          16       16              
  Lines        2887     2876      -11     
  Branches      807      804       -3     
==========================================
- Hits         2742     2732      -10     
+ Misses        145      144       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@codecov-commenter
Copy link

Bundle Report

Changes will decrease total bundle size by 405 bytes (-0.25%) ⬇️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
@projectwallace/css-parser-esm 159.09kB -405 bytes (-0.25%) ⬇️

Affected Assets, Files, and Routes:

view changes for bundle: @projectwallace/css-parser-esm

Assets Changed:

Asset Name Size Change Total Size Change (%)
parse.js -372 bytes 10.19kB -3.52%
parse.d.ts -33 bytes 1.25kB -2.57%

Files in parse.js:

  • ./src/parse.ts → Total Size: 9.8kB

@bartveneman bartveneman merged commit f503f0c into main Mar 10, 2026
4 checks passed
@bartveneman bartveneman deleted the feat/parse-unknown-atrules branch March 10, 2026 09:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants