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 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    // https://drafts.fxtf.org/geometry/#dom-domrect-domrect
68    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    // https://drafts.fxtf.org/geometry/#dom-domrect-fromrect
83    #[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    // https://drafts.fxtf.org/geometry/#dom-domrect-x
91    fn X(&self) -> f64 {
92        self.rect.X()
93    }
94
95    // https://drafts.fxtf.org/geometry/#dom-domrect-x
96    fn SetX(&self, value: f64) {
97        self.rect.set_x(value);
98    }
99
100    // https://drafts.fxtf.org/geometry/#dom-domrect-y
101    fn Y(&self) -> f64 {
102        self.rect.Y()
103    }
104
105    // https://drafts.fxtf.org/geometry/#dom-domrect-y
106    fn SetY(&self, value: f64) {
107        self.rect.set_y(value);
108    }
109
110    // https://drafts.fxtf.org/geometry/#dom-domrect-width
111    fn Width(&self) -> f64 {
112        self.rect.Width()
113    }
114
115    // https://drafts.fxtf.org/geometry/#dom-domrect-width
116    fn SetWidth(&self, value: f64) {
117        self.rect.set_width(value);
118    }
119
120    // https://drafts.fxtf.org/geometry/#dom-domrect-height
121    fn Height(&self) -> f64 {
122        self.rect.Height()
123    }
124
125    // https://drafts.fxtf.org/geometry/#dom-domrect-height
126    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}