script: Support custom element states (#38564)

Also adds support for `:state`.

Testing: Covered by existing tests

---------

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This commit is contained in:
Simon Wülker 2025-08-27 19:25:16 +02:00 committed by GitHub
parent dcd25072d3
commit 04dd74dddb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 209 additions and 152 deletions

View file

@ -17,6 +17,7 @@ use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom};
use crate::dom::bindings::str::{DOMString, USVString};
use crate::dom::customstateset::CustomStateSet;
use crate::dom::element::Element;
use crate::dom::file::File;
use crate::dom::htmlelement::HTMLElement;
@ -69,6 +70,9 @@ pub(crate) struct ElementInternals {
state: DomRefCell<SubmissionValue>,
form_owner: MutNullableDom<HTMLFormElement>,
labels_node_list: MutNullableDom<NodeList>,
/// <https://html.spec.whatwg.org/multipage/#dom-elementinternals-states>
states: MutNullableDom<CustomStateSet>,
}
impl ElementInternals {
@ -85,6 +89,7 @@ impl ElementInternals {
state: DomRefCell::new(SubmissionValue::None),
form_owner: MutNullableDom::new(None),
labels_node_list: MutNullableDom::new(None),
states: MutNullableDom::new(None),
}
}
@ -186,6 +191,10 @@ impl ElementInternals {
self.is_instance_validatable() &&
!self.satisfies_constraints()
}
pub(crate) fn custom_states(&self) -> Option<DomRoot<CustomStateSet>> {
self.states.get()
}
}
impl ElementInternalsMethods<crate::DomTypeHolder> for ElementInternals {
@ -354,6 +363,17 @@ impl ElementInternalsMethods<crate::DomTypeHolder> for ElementInternals {
}
Ok(self.report_validity(can_gc))
}
/// <https://html.spec.whatwg.org/multipage/#dom-elementinternals-states>
fn States(&self, can_gc: CanGc) -> DomRoot<CustomStateSet> {
self.states.or_init(|| {
CustomStateSet::new(
&self.target_element.owner_window(),
&self.target_element,
can_gc,
)
})
}
}
// Form-associated custom elements also need the Validatable trait.