From 04dd74dddbb35a8048c593c7145347bb12b3e7ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20W=C3=BClker?= Date: Wed, 27 Aug 2025 19:25:16 +0200 Subject: [PATCH] script: Support custom element states (#38564) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also adds support for `:state`. Testing: Covered by existing tests --------- Signed-off-by: Simon Wülker --- Cargo.lock | 42 +++---- .../script/dom/customelementregistry.rs | 23 ++-- components/script/dom/customstateset.rs | 107 ++++++++++++++++++ components/script/dom/element.rs | 26 ++++- components/script/dom/elementinternals.rs | 20 ++++ components/script/dom/htmlelement.rs | 1 + components/script/dom/mod.rs | 1 + components/script/layout_dom/element.rs | 11 +- .../script_bindings/codegen/Bindings.conf | 2 +- .../webidls/ElementInternals.webidl | 8 ++ .../pseudo-classes-after-part.html.ini | 3 - .../selectors/parsing/parse-state.html.ini | 33 ------ .../state/ElementInternals-states.html.ini | 9 -- .../custom-state-set-strong-ref.html.ini | 3 - .../state/state-css-selector-nth-of.html.ini | 6 +- .../state/state-css-selector.html.ini | 24 ---- .../state/state-pseudo-class.html.ini | 15 --- .../meta/html/dom/idlharness.https.html.ini | 24 ---- tests/wpt/mozilla/meta/MANIFEST.json | 2 +- .../tests/mozilla/interfaces.https.html | 1 + 20 files changed, 209 insertions(+), 152 deletions(-) create mode 100644 components/script/dom/customstateset.rs delete mode 100644 tests/wpt/meta/css/selectors/parsing/parse-state.html.ini delete mode 100644 tests/wpt/meta/custom-elements/state/custom-state-set-strong-ref.html.ini diff --git a/Cargo.lock b/Cargo.lock index 92eba3cd870..674891baf64 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -384,7 +384,7 @@ dependencies = [ "objc2-foundation 0.3.1", "parking_lot", "percent-encoding", - "windows-sys 0.52.0", + "windows-sys 0.59.0", "x11rb", ] @@ -2529,7 +2529,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3153,7 +3153,7 @@ dependencies = [ "gobject-sys", "libc", "system-deps 7.0.5", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4658,7 +4658,7 @@ checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4963,7 +4963,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.48.5", ] [[package]] @@ -7192,7 +7192,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -7205,7 +7205,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.9.4", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -7553,7 +7553,7 @@ dependencies = [ [[package]] name = "selectors" version = "0.31.0" -source = "git+https://github.com/servo/stylo?branch=2025-08-01#8a6763eb2a66d3c93860313fba37fc3f09c7f70f" +source = "git+https://github.com/servo/stylo?branch=2025-08-01#35cd8025bb3d5c4cc50db80cb65f9b1840e5ac5a" dependencies = [ "bitflags 2.9.3", "cssparser", @@ -7872,7 +7872,7 @@ dependencies = [ [[package]] name = "servo_arc" version = "0.4.1" -source = "git+https://github.com/servo/stylo?branch=2025-08-01#8a6763eb2a66d3c93860313fba37fc3f09c7f70f" +source = "git+https://github.com/servo/stylo?branch=2025-08-01#35cd8025bb3d5c4cc50db80cb65f9b1840e5ac5a" dependencies = [ "serde", "stable_deref_trait", @@ -8351,7 +8351,7 @@ dependencies = [ [[package]] name = "stylo" version = "0.6.0" -source = "git+https://github.com/servo/stylo?branch=2025-08-01#8a6763eb2a66d3c93860313fba37fc3f09c7f70f" +source = "git+https://github.com/servo/stylo?branch=2025-08-01#35cd8025bb3d5c4cc50db80cb65f9b1840e5ac5a" dependencies = [ "app_units", "arrayvec", @@ -8408,7 +8408,7 @@ dependencies = [ [[package]] name = "stylo_atoms" version = "0.6.0" -source = "git+https://github.com/servo/stylo?branch=2025-08-01#8a6763eb2a66d3c93860313fba37fc3f09c7f70f" +source = "git+https://github.com/servo/stylo?branch=2025-08-01#35cd8025bb3d5c4cc50db80cb65f9b1840e5ac5a" dependencies = [ "string_cache", "string_cache_codegen", @@ -8417,12 +8417,12 @@ dependencies = [ [[package]] name = "stylo_config" version = "0.6.0" -source = "git+https://github.com/servo/stylo?branch=2025-08-01#8a6763eb2a66d3c93860313fba37fc3f09c7f70f" +source = "git+https://github.com/servo/stylo?branch=2025-08-01#35cd8025bb3d5c4cc50db80cb65f9b1840e5ac5a" [[package]] name = "stylo_derive" version = "0.6.0" -source = "git+https://github.com/servo/stylo?branch=2025-08-01#8a6763eb2a66d3c93860313fba37fc3f09c7f70f" +source = "git+https://github.com/servo/stylo?branch=2025-08-01#35cd8025bb3d5c4cc50db80cb65f9b1840e5ac5a" dependencies = [ "darling", "proc-macro2", @@ -8434,7 +8434,7 @@ dependencies = [ [[package]] name = "stylo_dom" version = "0.6.0" -source = "git+https://github.com/servo/stylo?branch=2025-08-01#8a6763eb2a66d3c93860313fba37fc3f09c7f70f" +source = "git+https://github.com/servo/stylo?branch=2025-08-01#35cd8025bb3d5c4cc50db80cb65f9b1840e5ac5a" dependencies = [ "bitflags 2.9.3", "stylo_malloc_size_of", @@ -8443,7 +8443,7 @@ dependencies = [ [[package]] name = "stylo_malloc_size_of" version = "0.6.0" -source = "git+https://github.com/servo/stylo?branch=2025-08-01#8a6763eb2a66d3c93860313fba37fc3f09c7f70f" +source = "git+https://github.com/servo/stylo?branch=2025-08-01#35cd8025bb3d5c4cc50db80cb65f9b1840e5ac5a" dependencies = [ "app_units", "cssparser", @@ -8460,12 +8460,12 @@ dependencies = [ [[package]] name = "stylo_static_prefs" version = "0.6.0" -source = "git+https://github.com/servo/stylo?branch=2025-08-01#8a6763eb2a66d3c93860313fba37fc3f09c7f70f" +source = "git+https://github.com/servo/stylo?branch=2025-08-01#35cd8025bb3d5c4cc50db80cb65f9b1840e5ac5a" [[package]] name = "stylo_traits" version = "0.6.0" -source = "git+https://github.com/servo/stylo?branch=2025-08-01#8a6763eb2a66d3c93860313fba37fc3f09c7f70f" +source = "git+https://github.com/servo/stylo?branch=2025-08-01#35cd8025bb3d5c4cc50db80cb65f9b1840e5ac5a" dependencies = [ "app_units", "bitflags 2.9.3", @@ -8654,7 +8654,7 @@ dependencies = [ "getrandom 0.3.3", "once_cell", "rustix 1.0.8", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -8880,7 +8880,7 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "to_shmem" version = "0.2.0" -source = "git+https://github.com/servo/stylo?branch=2025-08-01#8a6763eb2a66d3c93860313fba37fc3f09c7f70f" +source = "git+https://github.com/servo/stylo?branch=2025-08-01#35cd8025bb3d5c4cc50db80cb65f9b1840e5ac5a" dependencies = [ "cssparser", "servo_arc", @@ -8893,7 +8893,7 @@ dependencies = [ [[package]] name = "to_shmem_derive" version = "0.1.0" -source = "git+https://github.com/servo/stylo?branch=2025-08-01#8a6763eb2a66d3c93860313fba37fc3f09c7f70f" +source = "git+https://github.com/servo/stylo?branch=2025-08-01#35cd8025bb3d5c4cc50db80cb65f9b1840e5ac5a" dependencies = [ "darling", "proc-macro2", @@ -10182,7 +10182,7 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] diff --git a/components/script/dom/customelementregistry.rs b/components/script/dom/customelementregistry.rs index c0595dad429..577e8a3f938 100644 --- a/components/script/dom/customelementregistry.rs +++ b/components/script/dom/customelementregistry.rs @@ -343,7 +343,7 @@ impl CustomElementRegistryMethods for CustomElementRegistr rooted!(in(*cx) let constructor = constructor_.callback()); let name = LocalName::from(&*name); - // Step 1 + // Step 1. If IsConstructor(constructor) is false, then throw a TypeError. // We must unwrap the constructor as all wrappers are constructable if they are callable. rooted!(in(*cx) let unwrapped_constructor = unsafe { UnwrapObjectStatic(constructor.get()) }); @@ -358,17 +358,19 @@ impl CustomElementRegistryMethods for CustomElementRegistr )); } - // Step 2 + // Step 2. If name is not a valid custom element name, then throw a "SyntaxError" DOMException. if !is_valid_custom_element_name(&name) { return Err(Error::Syntax); } - // Step 3 + // Step 3. If this's custom element definition set contains an item with name name, + // then throw a "NotSupportedError" DOMException. if self.definitions.borrow().contains_key(&name) { return Err(Error::NotSupported); } - // Step 4 + // Step 4. If this's custom element definition set contains an + // item with constructor constructor, then throw a "NotSupportedError" DOMException. if self .definitions .borrow() @@ -378,24 +380,29 @@ impl CustomElementRegistryMethods for CustomElementRegistr return Err(Error::NotSupported); } - // Step 6 + // Step 6. Let extends be options["extends"] if it exists; otherwise null. let extends = &options.extends; // Steps 5, 7 let local_name = if let Some(ref extended_name) = *extends { - // Step 7.1 + // TODO Step 7.1 If this's is scoped is true, then throw a "NotSupportedError" DOMException. + + // Step 7.2 If extends is a valid custom element name, then throw a "NotSupportedError" DOMException. if is_valid_custom_element_name(extended_name) { return Err(Error::NotSupported); } - // Step 7.2 + // Step 7.3 If the element interface for extends and the HTML namespace is HTMLUnknownElement + // (e.g., if extends does not indicate an element definition in this specification) + // then throw a "NotSupportedError" DOMException. if !is_extendable_element_interface(extended_name) { return Err(Error::NotSupported); } + // Step 7.4 Set localName to extends. LocalName::from(&**extended_name) } else { - // Step 7.3 + // Step 5. Let localName be name. name.clone() }; diff --git a/components/script/dom/customstateset.rs b/components/script/dom/customstateset.rs new file mode 100644 index 00000000000..6001be2b089 --- /dev/null +++ b/components/script/dom/customstateset.rs @@ -0,0 +1,107 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +use dom_struct::dom_struct; +use indexmap::IndexSet; +use script_bindings::codegen::GenericBindings::ElementInternalsBinding::CustomStateSetMethods; +use script_bindings::like::Setlike; +use script_bindings::root::{Dom, DomRoot}; +use script_bindings::script_runtime::CanGc; +use script_bindings::str::DOMString; +use script_bindings::trace::CustomTraceable; +use style::values::AtomIdent; + +use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::inheritance::Castable; +use crate::dom::bindings::reflector::{Reflector, reflect_dom_object}; +use crate::dom::htmlelement::HTMLElement; +use crate::dom::node::{Node, NodeDamage}; +use crate::dom::window::Window; + +/// +#[dom_struct] +pub(crate) struct CustomStateSet { + reflector: Reflector, + internal: DomRefCell>, + owner_element: Dom, +} + +impl CustomStateSet { + fn new_inherited(element: &HTMLElement) -> Self { + Self { + reflector: Reflector::new(), + internal: DomRefCell::new(Default::default()), + owner_element: Dom::from_ref(element), + } + } + + pub(crate) fn new(window: &Window, element: &HTMLElement, can_gc: CanGc) -> DomRoot { + reflect_dom_object(Box::new(Self::new_inherited(element)), window, can_gc) + } + + pub(crate) fn for_each_state(&self, mut callback: F) + where + F: FnMut(&AtomIdent), + { + // FIXME: This creates new atoms whenever it is called, which is not optimal. + for state in self.internal.borrow().iter() { + callback(&AtomIdent::from(state.str())); + } + } + + fn states_did_change(&self) { + self.owner_element.upcast::().dirty(NodeDamage::Other); + } +} + +impl Setlike for CustomStateSet { + type Key = DOMString; + + #[inline(always)] + fn get_index(&self, index: u32) -> Option { + self.internal.get_index(index) + } + + #[inline(always)] + fn size(&self) -> u32 { + self.internal.size() + } + + #[inline(always)] + fn add(&self, key: Self::Key) { + self.internal.add(key); + self.states_did_change(); + } + + #[inline(always)] + fn has(&self, key: Self::Key) -> bool { + self.internal.has(key) + } + + #[inline(always)] + fn clear(&self) { + let old_size = self.internal.size(); + self.internal.clear(); + if old_size != 0 { + self.states_did_change(); + } + } + + #[inline(always)] + fn delete(&self, key: Self::Key) -> bool { + if self.internal.delete(key) { + self.states_did_change(); + true + } else { + false + } + } +} + +impl CustomStateSetMethods for CustomStateSet { + /// + fn Size(&self) -> u32 { + self.internal.size() + } +} diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index ec55304e474..a10eb558273 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -1325,6 +1325,9 @@ pub(crate) trait LayoutElementHelpers<'dom> { ) -> Option<&'dom AttrValue>; fn get_attr_val_for_layout(self, namespace: &Namespace, name: &LocalName) -> Option<&'dom str>; fn get_attr_vals_for_layout(self, name: &LocalName) -> Vec<&'dom AttrValue>; + fn each_custom_state(self, callback: F) + where + F: FnMut(&AtomIdent); } impl LayoutDom<'_, Element> { @@ -1819,6 +1822,13 @@ impl<'dom> LayoutElementHelpers<'dom> for LayoutDom<'dom, Element> { }) .collect() } + + fn each_custom_state(self, callback: F) + where + F: FnMut(&AtomIdent), + { + self.unsafe_get().each_custom_state(callback) + } } impl Element { @@ -5196,12 +5206,24 @@ impl SelectorsElement for SelectorWrapper<'_> { true } - fn has_custom_state(&self, _name: &AtomIdent) -> bool { - false + fn has_custom_state(&self, name: &AtomIdent) -> bool { + let mut has_state = false; + self.each_custom_state(|state| has_state |= state == name); + + has_state } } impl Element { + fn each_custom_state(&self, callback: F) + where + F: FnMut(&AtomIdent), + { + self.get_element_internals() + .and_then(|internals| internals.custom_states()) + .inspect(|states| states.for_each_state(callback)); + } + fn client_rect(&self) -> Rect { let doc = self.node.owner_doc(); diff --git a/components/script/dom/elementinternals.rs b/components/script/dom/elementinternals.rs index d2f019b4001..d0fd6ba4663 100644 --- a/components/script/dom/elementinternals.rs +++ b/components/script/dom/elementinternals.rs @@ -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, form_owner: MutNullableDom, labels_node_list: MutNullableDom, + + /// + states: MutNullableDom, } 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> { + self.states.get() + } } impl ElementInternalsMethods for ElementInternals { @@ -354,6 +363,17 @@ impl ElementInternalsMethods for ElementInternals { } Ok(self.report_validity(can_gc)) } + + /// + fn States(&self, can_gc: CanGc) -> DomRoot { + 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. diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs index 233e62fe53a..d0683607609 100644 --- a/components/script/dom/htmlelement.rs +++ b/components/script/dom/htmlelement.rs @@ -604,6 +604,7 @@ impl HTMLElementMethods for HTMLElement { // TODO: https://github.com/servo/servo/issues/12776 false } + /// fn AttachInternals(&self, can_gc: CanGc) -> Fallible> { let element = self.as_element(); diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 8389ee77647..e27afd6c47e 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -273,6 +273,7 @@ pub(crate) mod cssstylevalue; pub(crate) mod csssupportsrule; pub(crate) mod customelementregistry; pub(crate) mod customevent; +pub(crate) mod customstateset; pub(crate) mod datatransfer; pub(crate) mod datatransferitem; pub(crate) mod datatransferitemlist; diff --git a/components/script/layout_dom/element.rs b/components/script/layout_dom/element.rs index 6f1059af15d..8f0eba8d911 100644 --- a/components/script/layout_dom/element.rs +++ b/components/script/layout_dom/element.rs @@ -560,10 +560,11 @@ impl<'dom> style::dom::TElement for ServoLayoutElement<'dom> { .intersection(ElementSelectorFlags::RELATIVE_SELECTOR_SEARCH_DIRECTION_ANCESTOR_SIBLING) } - fn each_custom_state(&self, _callback: F) + fn each_custom_state(&self, callback: F) where F: FnMut(&AtomIdent), { + self.element.each_custom_state(callback); } /// Returns the implicit scope root for given sheet index and host. @@ -960,8 +961,12 @@ impl<'dom> ::selectors::Element for ServoLayoutElement<'dom> { true } - fn has_custom_state(&self, _name: &AtomIdent) -> bool { - false + fn has_custom_state(&self, name: &AtomIdent) -> bool { + let mut has_state = false; + self.element + .each_custom_state(|state| has_state |= state == name); + + has_state } } diff --git a/components/script_bindings/codegen/Bindings.conf b/components/script_bindings/codegen/Bindings.conf index 33e5f777b9d..22b006265a7 100644 --- a/components/script_bindings/codegen/Bindings.conf +++ b/components/script_bindings/codegen/Bindings.conf @@ -244,7 +244,7 @@ DOMInterfaces = { }, 'ElementInternals': { - 'canGc': ['CheckValidity', 'GetLabels', 'SetValidity', 'ReportValidity'], + 'canGc': ['CheckValidity', 'GetLabels', 'SetValidity', 'ReportValidity', 'States'], }, 'EventSource': { diff --git a/components/script_bindings/webidls/ElementInternals.webidl b/components/script_bindings/webidls/ElementInternals.webidl index b69436e1570..21a89825ccd 100644 --- a/components/script_bindings/webidls/ElementInternals.webidl +++ b/components/script_bindings/webidls/ElementInternals.webidl @@ -26,6 +26,9 @@ interface ElementInternals { [Throws] boolean reportValidity(); [Throws] readonly attribute NodeList labels; + + // Custom state pseudo-class + [SameObject] readonly attribute CustomStateSet states; }; // https://html.spec.whatwg.org/multipage/#elementinternals @@ -42,3 +45,8 @@ dictionary ValidityStateFlags { boolean customError = false; }; +// https://html.spec.whatwg.org/multipage/#customstateset +[Exposed=Window] +interface CustomStateSet { + setlike; +}; diff --git a/tests/wpt/meta/css/css-shadow-parts/pseudo-classes-after-part.html.ini b/tests/wpt/meta/css/css-shadow-parts/pseudo-classes-after-part.html.ini index d8bc08b193e..28d2da6f900 100644 --- a/tests/wpt/meta/css/css-shadow-parts/pseudo-classes-after-part.html.ini +++ b/tests/wpt/meta/css/css-shadow-parts/pseudo-classes-after-part.html.ini @@ -35,8 +35,5 @@ ["::part(mypart):playing" should be a valid selector] expected: FAIL - ["::part(mypart):state(mystate)" should be a valid selector] - expected: FAIL - ["::part(mypart):xr-overlay" should be a valid selector] expected: FAIL diff --git a/tests/wpt/meta/css/selectors/parsing/parse-state.html.ini b/tests/wpt/meta/css/selectors/parsing/parse-state.html.ini deleted file mode 100644 index d4069801d24..00000000000 --- a/tests/wpt/meta/css/selectors/parsing/parse-state.html.ini +++ /dev/null @@ -1,33 +0,0 @@ -[parse-state.html] - [":state(--foo)" should be a valid selector] - expected: FAIL - - [":state(bar)" should be a valid selector] - expected: FAIL - - [":state(--)" should be a valid selector] - expected: FAIL - - [":state(--0)" should be a valid selector] - expected: FAIL - - [":host(:state(--foo))" should be a valid selector] - expected: FAIL - - ["my-input[type=\\"foo\\"\]:state(checked)" should be a valid selector] - expected: FAIL - - ["my-input[type=\\"foo\\"\]:state(--0)::before" should be a valid selector] - expected: FAIL - - ["my-input[type=\\"foo\\"\]:state(--0)::part(inner)" should be a valid selector] - expected: FAIL - - ["my-input[type=\\"foo\\"\]:state(--0)::part(inner):state(bar)" should be a valid selector] - expected: FAIL - - ["::part(inner):state(bar)::before" should be a valid selector] - expected: FAIL - - ["::part(inner):state(bar)::after" should be a valid selector] - expected: FAIL diff --git a/tests/wpt/meta/custom-elements/state/ElementInternals-states.html.ini b/tests/wpt/meta/custom-elements/state/ElementInternals-states.html.ini index 16a0c952b9b..476467c7510 100644 --- a/tests/wpt/meta/custom-elements/state/ElementInternals-states.html.ini +++ b/tests/wpt/meta/custom-elements/state/ElementInternals-states.html.ini @@ -1,12 +1,3 @@ [ElementInternals-states.html] - [CustomStateSet behavior of ElementInternals.states: Initial state] - expected: FAIL - - [CustomStateSet behavior of ElementInternals.states: Exceptions] - expected: FAIL - - [CustomStateSet behavior of ElementInternals.states: Modifications] - expected: FAIL - [Updating a CustomStateSet while iterating it should work] expected: FAIL diff --git a/tests/wpt/meta/custom-elements/state/custom-state-set-strong-ref.html.ini b/tests/wpt/meta/custom-elements/state/custom-state-set-strong-ref.html.ini deleted file mode 100644 index 4f6b5158b75..00000000000 --- a/tests/wpt/meta/custom-elements/state/custom-state-set-strong-ref.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[custom-state-set-strong-ref.html] - [customstateset doesn't crash after GC on detached node] - expected: FAIL diff --git a/tests/wpt/meta/custom-elements/state/state-css-selector-nth-of.html.ini b/tests/wpt/meta/custom-elements/state/state-css-selector-nth-of.html.ini index 4a4b300ec94..5044695b053 100644 --- a/tests/wpt/meta/custom-elements/state/state-css-selector-nth-of.html.ini +++ b/tests/wpt/meta/custom-elements/state/state-css-selector-nth-of.html.ini @@ -1,10 +1,6 @@ [state-css-selector-nth-of.html] - expected: ERROR [state selector has influence on nth-of when state is applied] expected: FAIL - [state selector only applies on given ident] - expected: NOTRUN - [style is invalided on clear()] - expected: NOTRUN + expected: FAIL diff --git a/tests/wpt/meta/custom-elements/state/state-css-selector.html.ini b/tests/wpt/meta/custom-elements/state/state-css-selector.html.ini index b7071c87760..cabdb97a357 100644 --- a/tests/wpt/meta/custom-elements/state/state-css-selector.html.ini +++ b/tests/wpt/meta/custom-elements/state/state-css-selector.html.ini @@ -1,30 +1,6 @@ [state-css-selector.html] - [state selector has no influence when state is not applied] - expected: FAIL - - [state selector has no influence on sibling selectors when not applied] - expected: FAIL - - [state selector has influence when state is applied] - expected: FAIL - [state selector influences siblings when state is applied] expected: FAIL [state selector influences has() when state is applied] expected: FAIL - - [state selector only applies on given ident] - expected: FAIL - - [state selector only applies to siblings on given ident] - expected: FAIL - - [state selector only applies to has() on given ident] - expected: FAIL - - [states added multiple times counts as one] - expected: FAIL - - [style is invalided on clear()] - expected: FAIL diff --git a/tests/wpt/meta/custom-elements/state/state-pseudo-class.html.ini b/tests/wpt/meta/custom-elements/state/state-pseudo-class.html.ini index cf2fce2458b..8b38a9606cd 100644 --- a/tests/wpt/meta/custom-elements/state/state-pseudo-class.html.ini +++ b/tests/wpt/meta/custom-elements/state/state-pseudo-class.html.ini @@ -1,18 +1,3 @@ [state-pseudo-class.html] - [:state() parsing passes] - expected: FAIL - - [:state(foo) serialization] - expected: FAIL - - [:state(foo) in simple cases] - expected: FAIL - [:state(foo) and other pseudo classes] expected: FAIL - - [:state(foo) and ::part()] - expected: FAIL - - [:state(foo) and :host()] - expected: FAIL diff --git a/tests/wpt/meta/html/dom/idlharness.https.html.ini b/tests/wpt/meta/html/dom/idlharness.https.html.ini index cce32646d7d..f68350462ff 100644 --- a/tests/wpt/meta/html/dom/idlharness.https.html.ini +++ b/tests/wpt/meta/html/dom/idlharness.https.html.ini @@ -4394,30 +4394,6 @@ [OffscreenCanvasRenderingContext2D interface: operation roundRect(unrestricted double, unrestricted double, unrestricted double, unrestricted double, optional (unrestricted double or DOMPointInit or sequence<(unrestricted double or DOMPointInit)>))] expected: FAIL - [ElementInternals interface: attribute states] - expected: FAIL - - [CustomStateSet interface: existence and properties of interface object] - expected: FAIL - - [CustomStateSet interface object length] - expected: FAIL - - [CustomStateSet interface object name] - expected: FAIL - - [CustomStateSet interface: existence and properties of interface prototype object] - expected: FAIL - - [CustomStateSet interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - - [CustomStateSet interface: existence and properties of interface prototype object's @@unscopables property] - expected: FAIL - - [CustomStateSet interface: setlike] - expected: FAIL - [UserActivation interface: existence and properties of interface object] expected: FAIL diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json index c866150f461..09a4ab03d1b 100644 --- a/tests/wpt/mozilla/meta/MANIFEST.json +++ b/tests/wpt/mozilla/meta/MANIFEST.json @@ -13749,7 +13749,7 @@ ] ], "interfaces.https.html": [ - "a9447edae08028bd992e3aa7c9e7a2a483baa446", + "1397b723a1cb001521ac1b2032c380f1e02cf1f0", [ null, {} diff --git a/tests/wpt/mozilla/tests/mozilla/interfaces.https.html b/tests/wpt/mozilla/tests/mozilla/interfaces.https.html index a9447edae08..1397b723a1c 100644 --- a/tests/wpt/mozilla/tests/mozilla/interfaces.https.html +++ b/tests/wpt/mozilla/tests/mozilla/interfaces.https.html @@ -62,6 +62,7 @@ test_interfaces([ "CSSStyleRule", "CSSStyleSheet", "CSSSupportsRule", + "CustomStateSet", "DataTransfer", "DataTransferItem", "DataTransferItemList",