Implement CSS Nesting (& selector and nested style rules)#218
Open
jhaygood86 wants to merge 1 commit into
Open
Implement CSS Nesting (& selector and nested style rules)#218jhaygood86 wants to merge 1 commit into
jhaygood86 wants to merge 1 commit into
Conversation
Parse nested style rules and the & nesting selector (CSS Nesting 1),
resolving each nested rule at parse time into an ordinary flat rule with an
absolute selector (& -> :is(parent)), exposed on the object model via
IStyleRule.NestedRules so the parser needs no matcher/cascade awareness.
- StylesheetComposer classifies a declaration-block construct as a nested
rule vs a declaration by scanning bracket-aware for the first top-level {
(vs ;/}), with a -- custom-property guard. On the declaration branch it
rewinds the lexer (LexerBase.RewindTo, a faithful source-index restore --
not the InsertionPoint setter, whose BackNative loop mis-counts across \r\n)
and re-lexes cleanly in value mode, avoiding the hex-color value-mode
tokenization hazard a token buffer would hit.
- Nested selectors resolve against the enclosing rule's SelectorText and parse
via Parser.ParseSelector; the & substitution is string-aware so a & inside an
attribute-value string is preserved. StyleRule gains a NestedRules list.
Ported from PeachPDF, which vendors ExCSS.
jhaygood86
marked this pull request as ready for review
July 24, 2026 20:00
jhaygood86
marked this pull request as draft
July 24, 2026 20:35
jhaygood86
marked this pull request as ready for review
July 24, 2026 20:35
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements CSS Nesting 1: the
&nesting selector and nested style rules inside a declaration block.Nested rules are resolved at parse time into ordinary flat rules with an absolute selector (
&→:is(parent)), so the object model and any downstream matcher/cascade need no nesting awareness. Each parentStyleRuleexposes its resolved children via a newIStyleRule.NestedRules.How it works
StylesheetComposerclassifies a declaration-block construct as a nested rule vs a declaration by scanning bracket-aware for the first top-level{(vs;/}), with a--custom-property guard. Function tokens are opaque (their parens are already balanced), so only bare round/square brackets count toward depth. This resolves thediv { }(type selector, first token is an Ident) anda:hover { }(ambiguous witha: hover) cases via{-before-;.LexerBase.RewindTo, a faithful raw-source-index restore) and lets the unchanged declaration path re-lex in value mode. This is deliberately not a token pushback buffer, which would corrupt a#rrggbbvalue (the lexer tokenizes#123456differently in value vs non-value mode).&substitution is string-aware (a char scanner tracking quote state), so a&inside an attribute-value string ([data-x="a&b"]) is preserved and doesn't flip the rule off the descendant branch.Tests
CssNestingTests— 11 OM-level cases: implicit descendant,&-compound, type-selector nesting, no-&scoping, leading child combinator, hex-color regression (nested value not corrupted), top-level-unaffected, declaration-after-nested-rule, custom-property guard, multi-level nesting, and&-inside-attribute-string preservation. Full suite green.Ported from PeachPDF, which vendors ExCSS.