script/dom/html/embedded_content/
htmlobjectelement.rs1use std::default::Default;
6
7use dom_struct::dom_struct;
8use html5ever::{LocalName, Prefix, local_name};
9use js::context::{JSContext, NoGC};
10use js::rust::HandleObject;
11use pixels::RasterImage;
12use script_bindings::cell::DomRefCell;
13use servo_arc::Arc;
14use style::attr::{AttrValue, LengthOrPercentageOrAuto};
15
16use crate::dom::bindings::codegen::Bindings::HTMLObjectElementBinding::HTMLObjectElementMethods;
17use crate::dom::bindings::inheritance::Castable;
18use crate::dom::bindings::root::{DomRoot, LayoutDom, MutNullableDom};
19use crate::dom::bindings::str::DOMString;
20use crate::dom::document::Document;
21use crate::dom::element::attributes::storage::AttrRef;
22use crate::dom::element::{AttributeMutation, Element};
23use crate::dom::html::htmlelement::HTMLElement;
24use crate::dom::html::htmlformelement::{FormControl, HTMLFormElement};
25use crate::dom::node::virtualmethods::VirtualMethods;
26use crate::dom::node::{Node, NodeTraits};
27use crate::dom::validation::Validatable;
28use crate::dom::validitystate::ValidityState;
29
30#[dom_struct]
31pub(crate) struct HTMLObjectElement {
32 htmlelement: HTMLElement,
33 #[no_trace]
34 #[conditional_malloc_size_of]
35 image: DomRefCell<Option<Arc<RasterImage>>>,
36 form_owner: MutNullableDom<HTMLFormElement>,
37 validity_state: MutNullableDom<ValidityState>,
38}
39
40impl HTMLObjectElement {
41 fn new_inherited(
42 local_name: LocalName,
43 prefix: Option<Prefix>,
44 document: &Document,
45 ) -> HTMLObjectElement {
46 HTMLObjectElement {
47 htmlelement: HTMLElement::new_inherited(local_name, prefix, document),
48 image: DomRefCell::new(None),
49 form_owner: Default::default(),
50 validity_state: Default::default(),
51 }
52 }
53
54 pub(crate) fn new(
55 cx: &mut js::context::JSContext,
56 local_name: LocalName,
57 prefix: Option<Prefix>,
58 document: &Document,
59 proto: Option<HandleObject>,
60 ) -> DomRoot<HTMLObjectElement> {
61 Node::reflect_node_with_proto(
62 cx,
63 Box::new(HTMLObjectElement::new_inherited(
64 local_name, prefix, document,
65 )),
66 document,
67 proto,
68 )
69 }
70}
71
72trait ProcessDataURL {
73 fn process_data_url(&self);
74}
75
76impl ProcessDataURL for &HTMLObjectElement {
77 fn process_data_url(&self) {
80 let element = self.upcast::<Element>();
81
82 if let (None, Some(_uri)) = (
84 element.get_attribute_string_value(&local_name!("type")),
85 element.get_attribute_string_value(&local_name!("data")),
86 ) {
87 }
89 }
90}
91
92impl HTMLObjectElementMethods<crate::DomTypeHolder> for HTMLObjectElement {
93 make_getter!(Type, "type");
95
96 make_setter!(SetType, "type");
98
99 make_getter!(UseMap, "usemap");
101
102 make_setter!(SetUseMap, "usemap");
104
105 make_getter!(Width, "width");
107 make_dimension_setter!(SetWidth, "width");
109
110 make_getter!(Height, "height");
112 make_dimension_setter!(SetHeight, "height");
114
115 make_dimension_uint_getter!(Hspace, "hspace");
117 make_dimension_uint_setter!(SetHspace, "hspace");
119
120 make_dimension_uint_getter!(Vspace, "vspace");
122 make_dimension_uint_setter!(SetVspace, "vspace");
124
125 fn GetForm(&self) -> Option<DomRoot<HTMLFormElement>> {
127 self.form_owner()
128 }
129
130 fn WillValidate(&self, no_gc: &NoGC) -> bool {
132 self.is_instance_validatable(no_gc)
133 }
134
135 fn Validity(&self, cx: &mut JSContext) -> DomRoot<ValidityState> {
137 self.validity_state(cx)
138 }
139
140 fn CheckValidity(&self, cx: &mut JSContext) -> bool {
142 self.check_validity(cx)
143 }
144
145 fn ReportValidity(&self, cx: &mut JSContext) -> bool {
147 self.report_validity(cx)
148 }
149
150 fn ValidationMessage(&self, cx: &mut JSContext) -> DOMString {
152 self.validation_message(cx)
153 }
154
155 fn SetCustomValidity(&self, cx: &mut JSContext, error: DOMString) {
157 self.validity_state(cx).set_custom_error_message(cx, error);
158 }
159}
160
161impl Validatable for HTMLObjectElement {
162 fn as_element(&self) -> &Element {
163 self.upcast()
164 }
165
166 fn validity_state(&self, cx: &mut JSContext) -> DomRoot<ValidityState> {
167 self.validity_state
168 .or_init(|| ValidityState::new(cx, &self.owner_window(), self.upcast()))
169 }
170
171 fn is_instance_validatable(&self, _no_gc: &NoGC) -> bool {
172 false
174 }
175}
176
177impl VirtualMethods for HTMLObjectElement {
178 fn super_type(&self) -> Option<&dyn VirtualMethods> {
179 Some(self.upcast::<HTMLElement>() as &dyn VirtualMethods)
180 }
181
182 fn attribute_mutated(
183 &self,
184 cx: &mut js::context::JSContext,
185 attr: AttrRef<'_>,
186 mutation: AttributeMutation,
187 ) {
188 self.super_type()
189 .unwrap()
190 .attribute_mutated(cx, attr, mutation);
191 match *attr.local_name() {
192 local_name!("data") => {
193 if let AttributeMutation::Set(_) = mutation {
194 self.process_data_url();
195 }
196 },
197 local_name!("form") => {
198 self.form_attribute_mutated(cx, mutation);
199 },
200 _ => {},
201 }
202 }
203
204 fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue {
205 match *name {
206 local_name!("width") |
207 local_name!("height") |
208 local_name!("hspace") |
209 local_name!("vspace") => AttrValue::from_dimension(value.into()),
210 _ => self
211 .super_type()
212 .unwrap()
213 .parse_plain_attribute(name, value),
214 }
215 }
216
217 fn attribute_affects_presentational_hints(&self, attr: AttrRef<'_>) -> bool {
218 match attr.local_name() {
219 &local_name!("width") |
220 &local_name!("height") |
221 &local_name!("hspace") |
222 &local_name!("vspace") => true,
223 _ => self
224 .super_type()
225 .unwrap()
226 .attribute_affects_presentational_hints(attr),
227 }
228 }
229}
230
231impl FormControl for HTMLObjectElement {
232 fn form_owner(&self) -> Option<DomRoot<HTMLFormElement>> {
233 self.form_owner.get()
234 }
235
236 fn set_form_owner(&self, _cx: &mut JSContext, form: Option<&HTMLFormElement>) {
237 self.form_owner.set(form);
238 }
239
240 fn to_html_element(&self) -> &HTMLElement {
241 self.upcast::<HTMLElement>()
242 }
243}
244
245impl LayoutDom<'_, HTMLObjectElement> {
246 pub(crate) fn width(self) -> LengthOrPercentageOrAuto {
247 self.upcast::<Element>()
248 .dimension_attr_value(local_name!("width"))
249 }
250
251 pub(crate) fn height(self) -> LengthOrPercentageOrAuto {
252 self.upcast::<Element>()
253 .dimension_attr_value(local_name!("height"))
254 }
255
256 pub(crate) fn margin_right_left(self) -> LengthOrPercentageOrAuto {
257 self.upcast::<Element>()
258 .dimension_attr_value(local_name!("hspace"))
259 }
260
261 pub(crate) fn margin_top_bottom(self) -> LengthOrPercentageOrAuto {
262 self.upcast::<Element>()
263 .dimension_attr_value(local_name!("vspace"))
264 }
265}