1use html5ever::{LocalName, ns};
6use js::context::JSContext;
7use style::attr::AttrValue;
8use stylo_atoms::Atom;
9
10use crate::dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
11use crate::dom::bindings::codegen::UnionTypes::{TrustedHTMLOrString, TrustedScriptURLOrUSVString};
12use crate::dom::bindings::str::{DOMString, USVString};
13use crate::dom::element::Element;
14use crate::dom::node::NodeTraits;
15use crate::script_runtime::CanGc;
16
17impl Element {
18 pub(crate) fn get_int_attribute(&self, local_name: &LocalName, default: i32) -> i32 {
19 match self.get_attribute(local_name) {
20 Some(ref attribute) => match *attribute.value() {
21 AttrValue::Int(_, value) => value,
22 _ => unreachable!("Expected an AttrValue::Int: implement parse_plain_attribute"),
23 },
24 None => default,
25 }
26 }
27
28 pub(crate) fn set_atomic_attribute(
29 &self,
30 local_name: &LocalName,
31 value: DOMString,
32 can_gc: CanGc,
33 ) {
34 self.set_attribute(local_name, AttrValue::from_atomic(value.into()), can_gc);
35 }
36
37 pub(crate) fn set_bool_attribute(&self, local_name: &LocalName, value: bool, can_gc: CanGc) {
38 if self.has_attribute(local_name) == value {
39 return;
40 }
41 if value {
42 self.set_string_attribute(local_name, DOMString::new(), can_gc);
43 } else {
44 self.remove_attribute(&ns!(), local_name, can_gc);
45 }
46 }
47
48 pub(crate) fn get_url_attribute(&self, local_name: &LocalName) -> USVString {
49 let Some(attribute) = self.get_attribute(local_name) else {
50 return Default::default();
51 };
52 let value = &**attribute.value();
53 self.owner_document()
54 .encoding_parse_a_url(value)
55 .map(|parsed| USVString(parsed.into_string()))
56 .unwrap_or_else(|_| USVString(value.to_owned()))
57 }
58
59 pub(crate) fn set_url_attribute(
60 &self,
61 local_name: &LocalName,
62 value: USVString,
63 can_gc: CanGc,
64 ) {
65 self.set_attribute(local_name, AttrValue::String(value.to_string()), can_gc);
66 }
67
68 pub(crate) fn get_trusted_type_url_attribute(
69 &self,
70 local_name: &LocalName,
71 ) -> TrustedScriptURLOrUSVString {
72 let Some(attribute) = self.get_attribute(local_name) else {
73 return TrustedScriptURLOrUSVString::USVString(USVString::default());
74 };
75 let value = &**attribute.value();
76 self.owner_document()
77 .encoding_parse_a_url(value)
78 .map(|parsed| TrustedScriptURLOrUSVString::USVString(USVString(parsed.into_string())))
79 .unwrap_or_else(|_| TrustedScriptURLOrUSVString::USVString(USVString(value.to_owned())))
80 }
81
82 pub(crate) fn get_trusted_html_attribute(&self, local_name: &LocalName) -> TrustedHTMLOrString {
83 TrustedHTMLOrString::String(self.get_string_attribute(local_name))
84 }
85
86 pub(crate) fn get_string_attribute(&self, local_name: &LocalName) -> DOMString {
87 self.get_attribute(local_name)
88 .map(|attribute| attribute.Value())
89 .unwrap_or_default()
90 }
91
92 pub(crate) fn set_string_attribute(
93 &self,
94 local_name: &LocalName,
95 value: DOMString,
96 can_gc: CanGc,
97 ) {
98 self.set_attribute(local_name, AttrValue::String(value.into()), can_gc);
99 }
100
101 pub(crate) fn get_nullable_string_attribute(
104 &self,
105 local_name: &LocalName,
106 ) -> Option<DOMString> {
107 if self.has_attribute(local_name) {
108 Some(self.get_string_attribute(local_name))
109 } else {
110 None
111 }
112 }
113
114 pub(crate) fn set_nullable_string_attribute(
117 &self,
118 cx: &mut JSContext,
119 local_name: &LocalName,
120 value: Option<DOMString>,
121 ) {
122 match value {
123 Some(val) => {
124 self.set_string_attribute(local_name, val, CanGc::from_cx(cx));
125 },
126 None => {
127 self.remove_attribute(&ns!(), local_name, CanGc::from_cx(cx));
128 },
129 }
130 }
131
132 pub(crate) fn get_tokenlist_attribute(&self, local_name: &LocalName) -> Vec<Atom> {
133 self.get_attribute(local_name)
134 .map(|attribute| attribute.value().as_tokens().to_vec())
135 .unwrap_or_default()
136 }
137
138 pub(crate) fn set_tokenlist_attribute(
139 &self,
140 local_name: &LocalName,
141 value: DOMString,
142 can_gc: CanGc,
143 ) {
144 self.set_attribute(
145 local_name,
146 AttrValue::from_serialized_tokenlist(value.into()),
147 can_gc,
148 );
149 }
150
151 pub(crate) fn set_atomic_tokenlist_attribute(
152 &self,
153 local_name: &LocalName,
154 tokens: Vec<Atom>,
155 can_gc: CanGc,
156 ) {
157 self.set_attribute(local_name, AttrValue::from_atomic_tokens(tokens), can_gc);
158 }
159
160 pub(crate) fn set_int_attribute(&self, local_name: &LocalName, value: i32, can_gc: CanGc) {
161 self.set_attribute(local_name, AttrValue::Int(value.to_string(), value), can_gc);
162 }
163
164 pub(crate) fn get_uint_attribute(&self, local_name: &LocalName, default: u32) -> u32 {
165 match self.get_attribute(local_name) {
166 Some(ref attribute) => match *attribute.value() {
167 AttrValue::UInt(_, value) => value,
168 _ => unreachable!("Expected an AttrValue::UInt: implement parse_plain_attribute"),
169 },
170 None => default,
171 }
172 }
173
174 pub(crate) fn set_uint_attribute(&self, local_name: &LocalName, value: u32, can_gc: CanGc) {
175 self.set_attribute(
176 local_name,
177 AttrValue::UInt(value.to_string(), value),
178 can_gc,
179 );
180 }
181}