Support ::part selector (#37307)

This is pretty much just wiring up the necessary stylo methods. Note
that the `exportparts` attribute is not yet supported, I'll do that in a
followup change

Testing: Covered by existing web platform tests.
This is the first half of https://github.com/servo/servo/issues/35349

Fixes https://github.com/servo/servo/issues/37325

---------

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This commit is contained in:
Simon Wülker 2025-06-09 12:17:28 +02:00 committed by GitHub
parent 73ee36be00
commit 0fa3de3937
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
36 changed files with 119 additions and 348 deletions

View file

@ -1,7 +1,4 @@
[highlight-pseudos.html]
["::part(my-part)::selection" should be a valid selector]
expected: FAIL
["::target-text" should be a valid selector]
expected: FAIL

View file

@ -1,6 +0,0 @@
[all-hosts.html]
[::part with host selector styles in first host]
expected: FAIL
[::part with host selector styles in second host]
expected: FAIL

View file

@ -1,2 +1,2 @@
[animation-part.html]
expected: FAIL
expected: TIMEOUT

View file

@ -1,3 +0,0 @@
[complex-matching.html]
[Complex selector for host works]
expected: FAIL

View file

@ -1,12 +1,3 @@
[grouping-with-checked.html]
[Styles applied to ::part(...)]
expected: FAIL
[Styles applied to ::part(...):checked]
expected: FAIL
[Styles applied via grouped selector including matched ::part(...):checked]
expected: FAIL
[Styles applied via grouped selector including unmatched ::part(...):checked]
expected: FAIL

View file

@ -1,12 +0,0 @@
[grouping-with-disabled.html]
[Styles applied to ::part(...)]
expected: FAIL
[Styles applied to ::part(...):disabled]
expected: FAIL
[Styles applied via grouped selector including matched ::part(...):disabled]
expected: FAIL
[Styles applied via grouped selector including unmatched ::part(...):disabled]
expected: FAIL

View file

@ -1,3 +0,0 @@
[host-part-001.html]
[:host::part works]
expected: FAIL

View file

@ -1,3 +0,0 @@
[host-part-002.html]
[:host::part has correct cascading behavior]
expected: FAIL

View file

@ -1,3 +0,0 @@
[host-part-nesting.html]
[:host::part works in nesting]
expected: FAIL

View file

@ -1,12 +0,0 @@
[idlharness.html]
[Element interface: attribute part]
expected: FAIL
[Element interface: element must inherit property "part" with the proper type]
expected: FAIL
[Element interface: htmlElement must inherit property "part" with the proper type]
expected: FAIL
[Element interface: svgElement must inherit property "part" with the proper type]
expected: FAIL

View file

@ -1,3 +0,0 @@
[inner-host.html]
[Part in outer host is styled by document style sheet]
expected: FAIL

View file

@ -1,16 +1,7 @@
[interaction-with-pseudo-elements.html]
[::before in selected host is styled]
expected: FAIL
[::after in selected host is styled]
expected: FAIL
[::placeholder in selected host is styled]
expected: FAIL
[::selection in selected host is styled]
expected: FAIL
[::first-line in selected host is styled]
expected: FAIL

View file

@ -1,3 +0,0 @@
[invalidation-change-part-name-idl-domtokenlist.html]
[Part in selected host changed color via part IDL DOMTokenList attribute.]
expected: FAIL

View file

@ -1,3 +0,0 @@
[invalidation-change-part-name-idl-setter.html]
[Part in selected host changed color via part IDL attribute setter.]
expected: FAIL

View file

@ -1,3 +0,0 @@
[invalidation-complex-selector.html]
[Part in selected host changed color]
expected: FAIL

View file

@ -1,3 +0,0 @@
[multiple-parts.html]
[Double-part in selected host is styled]
expected: FAIL

View file

@ -1,12 +0,0 @@
[part-name-idl.html]
[Access to .part returns an empty DOMTokenList.]
expected: FAIL
[Multiple names give a DOMTokenList with multiple entries.]
expected: FAIL
[DOMTokenList created by access is persisted.]
expected: FAIL
[Changes in DOMTokenList are refected in attribute.]
expected: FAIL

View file

@ -1,2 +0,0 @@
[part-nested-pseudo.html]
expected: FAIL

View file

@ -1,82 +1,28 @@
[pseudo-classes-after-part.html]
["::part(mypart):active" should be a valid selector]
expected: FAIL
["::part(mypart):active-view-transition" should be a valid selector]
expected: FAIL
["::part(mypart):active-view-transition-type(mytype)" should be a valid selector]
expected: FAIL
["::part(mypart):any-link" should be a valid selector]
expected: FAIL
["::part(mypart):autofill" should be a valid selector]
expected: FAIL
["::part(mypart):checked" should be a valid selector]
expected: FAIL
["::part(mypart):default" should be a valid selector]
expected: FAIL
["::part(mypart):defined" should be a valid selector]
expected: FAIL
["::part(mypart):dir(ltr)" should be a valid selector]
expected: FAIL
["::part(mypart):disabled" should be a valid selector]
expected: FAIL
["::part(mypart):enabled" should be a valid selector]
expected: FAIL
["::part(mypart):focus" should be a valid selector]
expected: FAIL
["::part(mypart):focus-visible" should be a valid selector]
expected: FAIL
["::part(mypart):focus-within" should be a valid selector]
expected: FAIL
["::part(mypart):fullscreen" should be a valid selector]
expected: FAIL
["::part(mypart):future" should be a valid selector]
expected: FAIL
["::part(mypart):hover" should be a valid selector]
expected: FAIL
["::part(mypart):indeterminate" should be a valid selector]
expected: FAIL
["::part(mypart):in-range" should be a valid selector]
expected: FAIL
["::part(mypart):invalid" should be a valid selector]
expected: FAIL
["::part(mypart):lang(en)" should be a valid selector]
expected: FAIL
["::part(mypart):link" should be a valid selector]
expected: FAIL
["::part(mypart):modal" should be a valid selector]
expected: FAIL
["::part(mypart):open" should be a valid selector]
expected: FAIL
["::part(mypart):optional" should be a valid selector]
expected: FAIL
["::part(mypart):out-of-range" should be a valid selector]
expected: FAIL
["::part(mypart):past" should be a valid selector]
expected: FAIL
@ -86,56 +32,11 @@
["::part(mypart):picture-in-picture" should be a valid selector]
expected: FAIL
["::part(mypart):placeholder-shown" should be a valid selector]
expected: FAIL
["::part(mypart):playing" should be a valid selector]
expected: FAIL
["::part(mypart):popover-open" should be a valid selector]
expected: FAIL
["::part(mypart):read-only" should be a valid selector]
expected: FAIL
["::part(mypart):read-write" should be a valid selector]
expected: FAIL
["::part(mypart):required" should be a valid selector]
expected: FAIL
["::part(mypart):state(mystate)" should be a valid selector]
expected: FAIL
["::part(mypart):target" should be a valid selector]
expected: FAIL
["::part(mypart):user-invalid" should be a valid selector]
expected: FAIL
["::part(mypart):user-valid" should be a valid selector]
expected: FAIL
["::part(mypart):valid" should be a valid selector]
expected: FAIL
["::part(mypart):visited" should be a valid selector]
expected: FAIL
["::part(mypart):xr-overlay" should be a valid selector]
expected: FAIL
["::part(mypart):not(:hover)" should be a valid selector]
expected: FAIL
["::part(mypart):is(:hover)" should be a valid selector]
expected: FAIL
["::part(mypart):where(:hover)" should be a valid selector]
expected: FAIL
["::part(mypart):is(:first-child)" should be a valid selector]
expected: FAIL
["::part(mypart):where(:first-child)" should be a valid selector]
expected: FAIL

View file

@ -1,13 +1,4 @@
[pseudo-elements-after-part.html]
["::part(mypart)::after" should be a valid selector]
expected: FAIL
["::part(mypart)::backdrop" should be a valid selector]
expected: FAIL
["::part(mypart)::before" should be a valid selector]
expected: FAIL
["::part(mypart)::cue" should be a valid selector]
expected: FAIL
@ -29,18 +20,12 @@
["::part(mypart)::highlight(myhighlight)" should be a valid selector]
expected: FAIL
["::part(mypart)::marker" should be a valid selector]
expected: FAIL
["::part(mypart)::placeholder" should be a valid selector]
expected: FAIL
["::part(mypart)::search-text" should be a valid selector]
expected: FAIL
["::part(mypart)::selection" should be a valid selector]
expected: FAIL
["::part(mypart)::spelling-error" should be a valid selector]
expected: FAIL
@ -95,21 +80,12 @@
[computed style for ::part()::search-text]
expected: FAIL
[computed style for ::part()::selection]
expected: FAIL
[computed style for ::part()::spelling-error]
expected: FAIL
[computed style for ::part()::target-text]
expected: FAIL
[::part styles with ::part(mypart)::after {\n display: block;\n content: "";\n height: 77px;\n } and <div part='mypart'></div>]
expected: FAIL
[::part styles with ::part(mypart)::before {\n display: block;\n content: "";\n height: 46px;\n } and <div part='mypart'></div>]
expected: FAIL
[::part styles with ::part(mypart)::details-content {\n height: 371px;\n } and <details part='mypart'><summary style="height:47px">summary</summary>details</details>]
expected: FAIL
@ -121,6 +97,3 @@
[::part styles with ::part(mypart) {\n font: 20px/1 Ahem;\n }\n ::part(mypart)::first-line {\n font-size: 86px;\n } and <div part=mypart>X<br>X</div>]
expected: FAIL
[::part styles with ::part(mypart)::marker {\n font: 63px/1.0 Ahem;\n content: "X";\n } and <li style="list-style-position: inside" part="mypart"></li>]
expected: FAIL

View file

@ -1,9 +0,0 @@
[serialization.html]
[Escape start parenthesis in ::part name.]
expected: FAIL
[Escape start space in ::part name.]
expected: FAIL
[Collapse spaces in ::part names list.]
expected: FAIL

View file

@ -1,3 +0,0 @@
[simple-inline.html]
[Part in selected host is styled]
expected: FAIL

View file

@ -1,3 +0,0 @@
[simple.html]
[Part in selected host is styled]
expected: FAIL

View file

@ -1,3 +0,0 @@
[style-sharing.html]
[Part in selected host does not incorrectly share style with non-part]
expected: FAIL

View file

@ -1,2 +0,0 @@
[part-pseudo.html]
expected: FAIL

View file

@ -1,12 +0,0 @@
[parse-is-where.html]
["::part(foo):is(:hover)" should be a valid selector]
expected: FAIL
["::part(foo):where(:hover)" should be a valid selector]
expected: FAIL
["::part(foo):is([attr='value'\])" should be a valid selector]
expected: FAIL
["::part(foo):where([attr='value'\])" should be a valid selector]
expected: FAIL

View file

@ -1,37 +1,4 @@
[parse-part.html]
["::part(--foo)" should be a valid selector]
expected: FAIL
["::part(bar)" should be a valid selector]
expected: FAIL
["::part(--)" should be a valid selector]
expected: FAIL
["::part(--0)" should be a valid selector]
expected: FAIL
["::part(foo bar)" should be a valid selector]
expected: FAIL
["::part(-foo bar)" should be a valid selector]
expected: FAIL
["::part(foo):focus" should be a valid selector]
expected: FAIL
["::part(foo):hover" should be a valid selector]
expected: FAIL
["::part(foo):focus-within" should be a valid selector]
expected: FAIL
["::part(foo)::before" should be a valid selector]
expected: FAIL
["::part(foo)::after" should be a valid selector]
expected: FAIL
["::part(foo)::placeholder" should be a valid selector]
expected: FAIL
@ -44,12 +11,6 @@
["::part(foo)::file-selector-button" should be a valid selector]
expected: FAIL
["::part(foo):is(:focus)" should be a valid selector]
expected: FAIL
[":lang(en)::part(foo)" should be a valid selector]
expected: FAIL
[":dir(ltr)::part(foo)" should be a valid selector]
expected: FAIL
@ -58,21 +19,3 @@
["::part(foo):dir(ltr)" should be a valid selector]
expected: FAIL
["::part(foo):is(ul)" should be a valid selector]
expected: FAIL
["::part(foo):is(nav ul)" should be a valid selector]
expected: FAIL
["::part(foo):where(ul)" should be a valid selector]
expected: FAIL
["::part(foo):where(nav ul)" should be a valid selector]
expected: FAIL
["::part(foo):disabled" should be a valid selector]
expected: FAIL
["::part(foo):checked" should be a valid selector]
expected: FAIL

View file

@ -0,0 +1,6 @@
[offsetParent-across-shadow-boundaries.html]
[offsetParent must find the first offset parent which is a shadow-including ancestor of the context object even some shadow tree of open mode did not have any offset parent]
expected: FAIL
[offsetParent must find the first offset parent which is a shadow-including ancestor of the context object even some shadow tree of closed mode did not have any offset parent]
expected: FAIL