1use std::collections::HashMap;
6
7use base::id::{DomRectId, DomRectIndex};
8use constellation_traits::DomRect;
9use dom_struct::dom_struct;
10use js::rust::HandleObject;
11
12use crate::dom::bindings::codegen::Bindings::DOMRectBinding::DOMRectMethods;
13use crate::dom::bindings::codegen::Bindings::DOMRectReadOnlyBinding::{
14 DOMRectInit, DOMRectReadOnlyMethods,
15};
16use crate::dom::bindings::error::Fallible;
17use crate::dom::bindings::reflector::{reflect_dom_object, reflect_dom_object_with_proto};
18use crate::dom::bindings::root::DomRoot;
19use crate::dom::bindings::serializable::Serializable;
20use crate::dom::bindings::structuredclone::StructuredData;
21use crate::dom::domrectreadonly::{DOMRectReadOnly, create_a_domrectreadonly_from_the_dictionary};
22use crate::dom::globalscope::GlobalScope;
23use crate::script_runtime::CanGc;
24
25#[dom_struct]
26pub(crate) struct DOMRect {
27 rect: DOMRectReadOnly,
28}
29
30impl DOMRect {
31 fn new_inherited(x: f64, y: f64, width: f64, height: f64) -> DOMRect {
32 DOMRect {
33 rect: DOMRectReadOnly::new_inherited(x, y, width, height),
34 }
35 }
36
37 pub(crate) fn new(
38 global: &GlobalScope,
39 x: f64,
40 y: f64,
41 width: f64,
42 height: f64,
43 can_gc: CanGc,
44 ) -> DomRoot<DOMRect> {
45 Self::new_with_proto(global, None, x, y, width, height, can_gc)
46 }
47
48 fn new_with_proto(
49 global: &GlobalScope,
50 proto: Option<HandleObject>,
51 x: f64,
52 y: f64,
53 width: f64,
54 height: f64,
55 can_gc: CanGc,
56 ) -> DomRoot<DOMRect> {
57 reflect_dom_object_with_proto(
58 Box::new(DOMRect::new_inherited(x, y, width, height)),
59 global,
60 proto,
61 can_gc,
62 )
63 }
64}
65
66impl DOMRectMethods<crate::DomTypeHolder> for DOMRect {
67 fn Constructor(
69 global: &GlobalScope,
70 proto: Option<HandleObject>,
71 can_gc: CanGc,
72 x: f64,
73 y: f64,
74 width: f64,
75 height: f64,
76 ) -> Fallible<DomRoot<DOMRect>> {
77 Ok(DOMRect::new_with_proto(
78 global, proto, x, y, width, height, can_gc,
79 ))
80 }
81
82 #[cfg_attr(crown, allow(crown::unrooted_must_root))]
84 fn FromRect(global: &GlobalScope, other: &DOMRectInit, can_gc: CanGc) -> DomRoot<DOMRect> {
85 let rect = create_a_domrectreadonly_from_the_dictionary(other);
86
87 reflect_dom_object(Box::new(Self { rect }), global, can_gc)
88 }
89
90 fn X(&self) -> f64 {
92 self.rect.X()
93 }
94
95 fn SetX(&self, value: f64) {
97 self.rect.set_x(value);
98 }
99
100 fn Y(&self) -> f64 {
102 self.rect.Y()
103 }
104
105 fn SetY(&self, value: f64) {
107 self.rect.set_y(value);
108 }
109
110 fn Width(&self) -> f64 {
112 self.rect.Width()
113 }
114
115 fn SetWidth(&self, value: f64) {
117 self.rect.set_width(value);
118 }
119
120 fn Height(&self) -> f64 {
122 self.rect.Height()
123 }
124
125 fn SetHeight(&self, value: f64) {
127 self.rect.set_height(value);
128 }
129}
130
131impl Serializable for DOMRect {
132 type Index = DomRectIndex;
133 type Data = DomRect;
134
135 fn serialize(&self) -> Result<(DomRectId, Self::Data), ()> {
136 let serialized = DomRect {
137 x: self.X(),
138 y: self.Y(),
139 width: self.Width(),
140 height: self.Height(),
141 };
142 Ok((DomRectId::new(), serialized))
143 }
144
145 fn deserialize(
146 owner: &GlobalScope,
147 serialized: Self::Data,
148 can_gc: CanGc,
149 ) -> Result<DomRoot<Self>, ()>
150 where
151 Self: Sized,
152 {
153 Ok(Self::new(
154 owner,
155 serialized.x,
156 serialized.y,
157 serialized.width,
158 serialized.height,
159 can_gc,
160 ))
161 }
162
163 fn serialized_storage<'a>(
164 data: StructuredData<'a, '_>,
165 ) -> &'a mut Option<HashMap<DomRectId, Self::Data>> {
166 match data {
167 StructuredData::Reader(reader) => &mut reader.rects,
168 StructuredData::Writer(writer) => &mut writer.rects,
169 }
170 }
171}