script: Use an implemented pseudo-element to fortype=color ::color-swatch (#37427)

Implement internal pseudo element, which would be resolved as a
"Implemented Pseudo Element" within style computation. This is an
concrete element that would has a primary style after the style
computation, but could match and style resolved like an pseudo element.
Therefore, it would have a different behavior compared to how does
`pseudo`s that `ServoLayoutNode` had. Where they would not have a
concrete element behind it. Note that, due to the nature of these pseudo
elements residing inside a UA widget, these pseudo elements would
therefore not be accessible in JavaScript by default.

This kind of element is required in order to implement the [form control
pseudo element](https://drafts.csswg.org/css-forms-1/#pseudo-elements)
like `::placeholder`, `::color-swatch`, `::field-text`, etc.
 
See [this docs](https://hackmd.io/@ChaKweTiau/BJ3zRdLQlg) for more
details of the implementation.

Then, the implemented pseudo element is utilized to implement style
matching for input `type=text`.

Servo's side of: https://github.com/servo/stylo/pull/212

Testing: No WPT regression.

---------

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>
This commit is contained in:
Steven Novaryo 2025-07-09 23:36:58 +08:00 committed by GitHub
parent d2ccf419c3
commit 378c4648e4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 201 additions and 163 deletions

View file

@ -13,9 +13,6 @@ use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::HTMLDetailsElementBinding::HTMLDetailsElementMethods;
use crate::dom::bindings::codegen::Bindings::HTMLSlotElementBinding::HTMLSlotElement_Binding::HTMLSlotElementMethods;
use crate::dom::bindings::codegen::Bindings::NodeBinding::Node_Binding::NodeMethods;
use crate::dom::bindings::codegen::Bindings::ShadowRootBinding::{
ShadowRootMode, SlotAssignmentMode,
};
use crate::dom::bindings::codegen::UnionTypes::ElementOrText;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::refcounted::Trusted;
@ -26,7 +23,6 @@ use crate::dom::eventtarget::EventTarget;
use crate::dom::htmlelement::HTMLElement;
use crate::dom::htmlslotelement::HTMLSlotElement;
use crate::dom::node::{BindContext, ChildrenMutation, Node, NodeDamage, NodeTraits};
use crate::dom::shadowroot::IsUserAgentWidget;
use crate::dom::text::Text;
use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
@ -103,18 +99,11 @@ impl HTMLDetailsElement {
fn create_shadow_tree(&self, can_gc: CanGc) {
let document = self.owner_document();
// TODO(stevennovaryo): Reimplement details styling so that it would not
// mess the cascading and require some reparsing.
let root = self
.upcast::<Element>()
.attach_shadow(
IsUserAgentWidget::Yes,
ShadowRootMode::Closed,
false,
false,
false,
SlotAssignmentMode::Manual,
can_gc,
)
.expect("Attaching UA shadow root failed");
.attach_ua_shadow_root(false, can_gc);
let summary = HTMLSlotElement::new(local_name!("slot"), None, &document, None, can_gc);
root.upcast::<Node>()