Skip to content

fix(parser): don't drop @container/@layer at-rules on CSS parse (#5969)#6788

Open
TowyTowy wants to merge 1 commit into
GrapesJS:devfrom
TowyTowy:fix/5969-container-atrule-space
Open

fix(parser): don't drop @container/@layer at-rules on CSS parse (#5969)#6788
TowyTowy wants to merge 1 commit into
GrapesJS:devfrom
TowyTowy:fix/5969-container-atrule-space

Conversation

@TowyTowy

Copy link
Copy Markdown

Problem

Closes #5969. @container (and other nestable at-rules like @layer) are silently dropped by the CSS parser on engines that expose a real numeric CSSRule.type.

parseNode in BrowserParserCss only entered the nestable-at-rule branch when the legacy type was falsy: (!type && getNestableAtRule(node)). Chrome reports type === 0 for these newer rules so it happened to work there, but any engine that returns a numeric type (jsdom returns 17 for CSSContainerRule) fell through every branch and the entire rule — selectors, styles and condition — was discarded. When the rule survived at all, this is what produced the reported invalid export @container portable(max-width: 639px) with the missing space.

Solution

Detect nestable at-rules with getNestableAtRule(node) regardless of the numeric type. getNestableAtRule only matches when the rule's cssText starts with the exact @<name>, so normal style/keyframe rules are untouched. The parsed condition keeps the container name and query separated by a space, so the exported CSS is valid again: @container somename (min-width: 300px){...}.

Tests

  • Un-skipped and corrected the pre-existing Parse rule with @container at-rule spec (its output no longer includes selectorsAdd: '', matching the @media specs). It fails before this change (the rule is dropped) and passes after.
  • Added an anonymous @container parse spec and a toCSS spec asserting the space is preserved on export.
  • Full parser / css_composer / code_manager / dom_components / selector_manager / style_manager suites pass with no regressions (792 passing).

Disclosure

Prepared with assistance from Claude (AI); the change and tests were reviewed and verified locally by the author (pnpm test, eslint, prettier --check all clean).

The browser CSS parser only recognised nestable at-rules (@container,
@layer, ...) when the CSSOM reported a falsy rule `type`. That happened
to work in Chrome, where the legacy `CSSRule.type` is `0` for newer
at-rules, but engines that expose a real numeric type (jsdom reports
`17` for `CSSContainerRule`) fell through every branch and the whole
rule — selectors, styles and condition — was silently discarded.

Detect nestable at-rules via `getNestableAtRule` regardless of the
numeric `type`. `getNestableAtRule` already matches only when the rule's
`cssText` starts with the exact `@<name>`, so normal style/keyframe
rules are unaffected. The parsed condition keeps the container name and
its query separated by a space, so the exported CSS is valid again
(e.g. `@container somename (min-width: 300px){...}`).

Fixes GrapesJS#5969

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

BUG: Name of @container directive is missing a space when exporting CSS

1 participant