script/dom/
domrect.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use 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    // https://drafts.fxtf.org/geometry/#dom-domrect-domrect
67    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    // https://drafts.fxtf.org/geometry/#dom-domrect-fromrect
82    #[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    // https://drafts.fxtf.org/geometry/#dom-domrect-x
90    fn X(&self) -> f64 {
91        self.rect.X()
92    }
93
94    // https://drafts.fxtf.org/geometry/#dom-domrect-x
95    fn SetX(&self, value: f64) {
96        self.rect.set_x(value);
97    }
98
99    // https://drafts.fxtf.org/geometry/#dom-domrect-y
100    fn Y(&self) -> f64 {
101        self.rect.Y()
102    }
103
104    // https://drafts.fxtf.org/geometry/#dom-domrect-y
105    fn SetY(&self, value: f64) {
106        self.rect.set_y(value);
107    }
108
109    // https://drafts.fxtf.org/geometry/#dom-domrect-width
110    fn Width(&self) -> f64 {
111        self.rect.Width()
112    }
113
114    // https://drafts.fxtf.org/geometry/#dom-domrect-width
115    fn SetWidth(&self, value: f64) {
116        self.rect.set_width(value);
117    }
118
119    // https://drafts.fxtf.org/geometry/#dom-domrect-height
120    fn Height(&self) -> f64 {
121        self.rect.Height()
122    }
123
124    // https://drafts.fxtf.org/geometry/#dom-domrect-height
125    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}