script/dom/
customstateset.rs1use std::cell::Ref;
6
7use dom_struct::dom_struct;
8use indexmap::IndexSet;
9use script_bindings::codegen::GenericBindings::ElementInternalsBinding::CustomStateSetMethods;
10use script_bindings::like::Setlike;
11use script_bindings::root::{Dom, DomRoot};
12use script_bindings::script_runtime::CanGc;
13use script_bindings::str::DOMString;
14use script_bindings::trace::CustomTraceable;
15use style::values::AtomIdent;
16
17use crate::dom::bindings::cell::DomRefCell;
18use crate::dom::bindings::inheritance::Castable;
19use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
20use crate::dom::html::htmlelement::HTMLElement;
21use crate::dom::node::{Node, NodeDamage};
22use crate::dom::window::Window;
23
24#[dom_struct]
26pub(crate) struct CustomStateSet {
27 reflector: Reflector,
28 internal: DomRefCell<IndexSet<DOMString>>,
29 owner_element: Dom<HTMLElement>,
30}
31
32impl CustomStateSet {
33 fn new_inherited(element: &HTMLElement) -> Self {
34 Self {
35 reflector: Reflector::new(),
36 internal: DomRefCell::new(Default::default()),
37 owner_element: Dom::from_ref(element),
38 }
39 }
40
41 pub(crate) fn new(window: &Window, element: &HTMLElement, can_gc: CanGc) -> DomRoot<Self> {
42 reflect_dom_object(Box::new(Self::new_inherited(element)), window, can_gc)
43 }
44
45 pub(crate) fn for_each_state<F>(&self, mut callback: F)
46 where
47 F: FnMut(&AtomIdent),
48 {
49 for state in self.internal.borrow().iter() {
51 callback(&AtomIdent::from(&*state.str()));
52 }
53 }
54
55 pub(crate) fn set<'a>(&'a self) -> Ref<'a, IndexSet<DOMString>> {
56 self.internal.borrow()
57 }
58
59 fn states_did_change(&self) {
60 self.owner_element.upcast::<Node>().dirty(NodeDamage::Other);
61 }
62}
63
64impl Setlike for CustomStateSet {
65 type Key = DOMString;
66
67 #[inline(always)]
68 fn get_index(&self, index: u32) -> Option<Self::Key> {
69 self.internal.get_index(index)
70 }
71
72 #[inline(always)]
73 fn size(&self) -> u32 {
74 self.internal.size()
75 }
76
77 #[inline(always)]
78 fn add(&self, key: Self::Key) {
79 self.internal.add(key);
80 self.states_did_change();
81 }
82
83 #[inline(always)]
84 fn has(&self, key: Self::Key) -> bool {
85 self.internal.has(key)
86 }
87
88 #[inline(always)]
89 fn clear(&self) {
90 let old_size = self.internal.size();
91 self.internal.clear();
92 if old_size != 0 {
93 self.states_did_change();
94 }
95 }
96
97 #[inline(always)]
98 fn delete(&self, key: Self::Key) -> bool {
99 if self.internal.delete(key) {
100 self.states_did_change();
101 true
102 } else {
103 false
104 }
105 }
106}
107
108impl CustomStateSetMethods<crate::DomTypeHolder> for CustomStateSet {
109 fn Size(&self) -> u32 {
111 self.internal.size()
112 }
113}