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