Skip to content

Fix parsing of pseudo-elements and pseudo-classes after ::details-content - #1308

Open
rorshopping wants to merge 1 commit into
parcel-bundler:masterfrom
rorshopping:fix/details-content-before
Open

Fix parsing of pseudo-elements and pseudo-classes after ::details-content#1308
rorshopping wants to merge 1 commit into
parcel-bundler:masterfrom
rorshopping:fix/details-content-before

Conversation

@rorshopping

Copy link
Copy Markdown

Fixes #1244

Problem

Selectors chaining pseudo-elements off ::details-content\ fail to parse:

\\css
::details-content::before { color: red } /* error: Invalid state */
details::details-content::after { content: '' }
\\

Root cause

::details-content\ is an element-backed pseudo-element: it behaves like a type selector, so other pseudo-elements and pseudo-classes may follow it. The parser did not model this distinction, and treated every known pseudo-element the same way as ::before\ (which cannot be followed by further pseudo-elements).

Changes

  • Add \is_element_backed()\ to the \PseudoElement\ trait (default \ alse), implemented for ::details-content\ in lightningcss.
  • Track a new \AFTER_ELEMENT_BACKED_PSEUDO_ELEMENT\ parsing state; element-backed pseudo-elements continue to reject type selectors, classes, ids and combinators after them, but allow further pseudo-elements and pseudo-classes.
  • Allow functional pseudo-classes (e.g. :lang(), :dir()) after ::part()\ and element-backed pseudo-elements, matching upstream selectors (Firefox bug 1960561) and the spec.

Now all of these parse:

\\css
::details-content::before { color: red }
::details-content::after { content: '' }
::details-content::marker { color: red }
details::details-content::before { color: red }
details::details-content:lang(en)::before { content: '' }
::part(foo):lang(en) { color: red }
\\

while these remain errors (matching browsers):

\\css
::details-content div { color: red } /* error /
::details-content.foo { color: red } /
error /
::details-content::part(x) { color: red } /
error /
::details-content::slotted(div) { color: red } /
error /
::details-content::before::after { color: red } /
error */
\\

Tests

  • selectors: \ est_pseudo_on_element_backed_pseudo\ (iterating ::details-content::before), mirroring the upstream selectors test.
  • lightningcss: minify tests for ::details-content::before/after/marker\ and \details::details-content::before, plus an error test for ::details-content::part(foo).

Note: the selectors crate has a pre-existing \ est_parsing\ failure (the test asserts ::target-text\ / ::search-text\ parse, but \DummyParser\ does not implement those pseudo-elements); it is unrelated to this change.

Element-backed pseudo-elements such as ::details-content behave like a
type selector, and can be followed by other pseudo-elements and
pseudo-classes:

  ::details-content::before { color: red }
  details::details-content::after { content: '' }

This matches the css-pseudo-4 spec section on element-backed
pseudo-elements and the behavior of browsers (Firefox, Chrome).

Also allow functional pseudo-classes such as :lang() and :dir() after
::part() and element-backed pseudo-elements, matching upstream selectors
(Firefox bug 1960561).
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.

Selecting ::details-content::before pseudo element errors

1 participant