Skip to content

Fix rule detection with offset CSS (Svelte embedded styles)#61

Merged
bartveneman merged 2 commits intomainfrom
claude/fix-svelte-css-offsets-x3opH
Mar 22, 2026
Merged

Fix rule detection with offset CSS (Svelte embedded styles)#61
bartveneman merged 2 commits intomainfrom
claude/fix-svelte-css-offsets-x3opH

Conversation

@bartveneman
Copy link
Copy Markdown
Member

Summary

Fixed two stylelint rules to correctly detect violations when CSS is embedded in other file formats (e.g., Svelte <style> blocks) where source offsets don't match the extracted CSS.

Key Changes

  • no-property-browserhacks: Refactored to parse CSS directly using @projectwallace/css-parser instead of relying on PostCSS declaration offsets, which may be misaligned when CSS is extracted from a larger file
  • no-useless-custom-property-assignment: Applied the same fix to use direct CSS parsing and manual offset calculation based on root.source.start.line
  • Both rules now calculate line/column positions using line_offset to account for CSS that starts at a non-zero line in the source file
  • Updated both rules to report against root node with explicit start/end positions instead of relying on declaration node positions

Implementation Details

  • Changed from using root.walkDecls() with declaration-level offsets to parsing the full CSS string and walking the AST directly
  • Line offset is calculated as (root.source?.start?.line ?? 1) - 1 to handle embedded CSS scenarios
  • Added test cases for both rules that simulate Svelte's custom syntax behavior where input.css contains the full file while parsed offsets are relative to extracted CSS

https://claude.ai/code/session_01C6WsJo4uG4ksJ97bjx7StZ

claude added 2 commits March 22, 2026 11:07
…custom-property-assignment

Both rules used `root.source.input.css.substring(start, end)` to extract raw
declaration text. In Svelte files, `input.css` contains the full file while
declaration offsets are relative to the extracted CSS, causing incorrect
substring extraction.

- `no-useless-custom-property-assignment`: Replace substring with
  `${declaration.prop}: ${declaration.value}` (same fix as PR #60).

- `no-property-browserhacks`: PostCSS strips hack prefixes (`*`, `_`) from
  `declaration.prop` and stores them at the end of `declaration.raws.before`.
  Extract the hack prefix from `raws.before` and prepend it when reconstructing
  the declaration string, so `parse_declaration` can still detect browserhacks
  without relying on source offsets.

Add Svelte offset mismatch tests for both rules using a custom PostCSS syntax
that prepends fake HTML content to `input.css` to simulate Svelte's behavior.

https://claude.ai/code/session_01C6WsJo4uG4ksJ97bjx7StZ
…gnment to use full css-parser parse + walk

Instead of running parse_declaration() per-declaration from PostCSS's walkDecls,
parse the entire CSS once with parse() from @projectwallace/css-parser and walk
the resulting AST to find DECLARATION nodes. This is more reliable because:

- No dependency on per-declaration string reconstruction
- The css-parser's DECLARATION nodes expose is_browserhack and property directly
- Positions come from the css-parser AST (line/column), adjusted by the PostCSS
  root's start line to correctly resolve absolute positions in Svelte/Vue files

https://claude.ai/code/session_01C6WsJo4uG4ksJ97bjx7StZ
@codecov-commenter
Copy link
Copy Markdown

Bundle Report

Changes will increase total bundle size by 554 bytes (1.52%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
stylelintPlugin-esm 36.91kB 554 bytes (1.52%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: stylelintPlugin-esm

Assets Changed:

Asset Name Size Change Total Size Change (%)
index.mjs 554 bytes 35.03kB 1.61%

Files in index.mjs:

  • ./src/rules/no-useless-custom-property-assignment/index.ts → Total Size: 2.19kB

  • ./src/rules/no-property-browserhacks/index.ts → Total Size: 1.42kB

@bartveneman bartveneman merged commit 61be2bc into main Mar 22, 2026
4 of 5 checks passed
@bartveneman bartveneman deleted the claude/fix-svelte-css-offsets-x3opH branch March 22, 2026 11:23
bartveneman pushed a commit that referenced this pull request Mar 22, 2026
Extended the approach from PR #61 to all other rules in the plugin:

- Fix max-lines-of-code: use root.toString() instead of root.source.input.css
  so only the extracted CSS is analyzed (not the surrounding file in Svelte etc.)

- Convert max-selector-complexity, no-anonymous-layers,
  no-static-container-query, no-static-media-query,
  no-unreachable-media-conditions, and no-unused-layers to use
  parse() + walk() from @projectwallace/css-parser with line_offset
  (report against root node with explicit start/end positions)

- Add Svelte-simulation test cases to all 11 remaining rules
  (no-unknown-custom-property, no-unused-custom-properties,
  no-undeclared-container-names, no-unused-container-names,
  and all rules converted above) to prevent regressions

https://claude.ai/code/session_01MBEABGmrwEbK5Ad8p6Qvy3
@codecov-commenter
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.35%. Comparing base (d60d1e0) to head (905e414).
⚠️ Report is 8 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #61      +/-   ##
==========================================
+ Coverage   97.33%   97.35%   +0.02%     
==========================================
  Files          18       18              
  Lines         563      568       +5     
  Branches      163      167       +4     
==========================================
+ Hits          548      553       +5     
  Misses         12       12              
  Partials        3        3              

☔ 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.

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.

3 participants