script/dom/intersectionobserverentry.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::cell::Cell;
6
7use dom_struct::dom_struct;
8use js::context::JSContext;
9use js::rust::HandleObject;
10use script_bindings::reflector::{Reflector, reflect_dom_object_with_proto_and_cx};
11
12use super::bindings::codegen::Bindings::IntersectionObserverEntryBinding::{
13 IntersectionObserverEntryInit, IntersectionObserverEntryMethods,
14};
15use super::bindings::num::Finite;
16use crate::dom::bindings::codegen::Bindings::DOMRectReadOnlyBinding::DOMRectInit;
17use crate::dom::bindings::root::{Dom, DomRoot};
18use crate::dom::domrectreadonly::DOMRectReadOnly;
19use crate::dom::element::Element;
20use crate::dom::window::Window;
21/// An individual IntersectionObserver entry.
22///
23/// <https://w3c.github.io/IntersectionObserver/#intersection-observer-entry>
24#[dom_struct]
25pub(crate) struct IntersectionObserverEntry {
26 reflector_: Reflector,
27 // <https://w3c.github.io/IntersectionObserver/#dom-intersectionobserverentry-time>
28 time: Cell<Finite<f64>>,
29 // <https://w3c.github.io/IntersectionObserver/#dom-intersectionobserverentry-rootbounds>
30 root_bounds: Option<Dom<DOMRectReadOnly>>,
31 // <https://w3c.github.io/IntersectionObserver/#dom-intersectionobserverentry-boundingclientrect>
32 bounding_client_rect: Dom<DOMRectReadOnly>,
33 // <https://w3c.github.io/IntersectionObserver/#dom-intersectionobserverentry-intersectionrect>
34 intersection_rect: Dom<DOMRectReadOnly>,
35 // <https://w3c.github.io/IntersectionObserver/#dom-intersectionobserverentry-isintersecting>
36 is_intersecting: Cell<bool>,
37 // <https://w3c.github.io/IntersectionObserver/#dom-intersectionobserverentry-isvisible>
38 is_visible: Cell<bool>,
39 // <https://w3c.github.io/IntersectionObserver/#dom-intersectionobserverentry-intersectionratio>
40 intersection_ratio: Cell<Finite<f64>>,
41 // <https://w3c.github.io/IntersectionObserver/#dom-intersectionobserverentry-target>
42 target: Dom<Element>,
43}
44
45impl IntersectionObserverEntry {
46 #[allow(clippy::too_many_arguments)]
47 fn new_inherited(
48 time: Finite<f64>,
49 root_bounds: Option<&DOMRectReadOnly>,
50 bounding_client_rect: &DOMRectReadOnly,
51 intersection_rect: &DOMRectReadOnly,
52 is_intersecting: bool,
53 is_visible: bool,
54 intersection_ratio: Finite<f64>,
55 target: &Element,
56 ) -> Self {
57 Self {
58 reflector_: Reflector::new(),
59 target: Dom::from_ref(target),
60 time: Cell::new(time),
61 root_bounds: root_bounds.map(Dom::from_ref),
62 bounding_client_rect: Dom::from_ref(bounding_client_rect),
63 intersection_rect: Dom::from_ref(intersection_rect),
64 is_intersecting: Cell::new(is_intersecting),
65 is_visible: Cell::new(is_visible),
66 intersection_ratio: Cell::new(intersection_ratio),
67 }
68 }
69
70 #[allow(clippy::too_many_arguments)]
71 pub(crate) fn new(
72 cx: &mut JSContext,
73 window: &Window,
74 proto: Option<HandleObject>,
75 time: Finite<f64>,
76 root_bounds: Option<&DOMRectReadOnly>,
77 bounding_client_rect: &DOMRectReadOnly,
78 intersection_rect: &DOMRectReadOnly,
79 is_intersecting: bool,
80 is_visible: bool,
81 intersection_ratio: Finite<f64>,
82 target: &Element,
83 ) -> DomRoot<Self> {
84 let observer = Box::new(Self::new_inherited(
85 time,
86 root_bounds,
87 bounding_client_rect,
88 intersection_rect,
89 is_intersecting,
90 is_visible,
91 intersection_ratio,
92 target,
93 ));
94 reflect_dom_object_with_proto_and_cx(observer, window, proto, cx)
95 }
96
97 fn new_from_dictionary(
98 cx: &mut JSContext,
99 window: &Window,
100 proto: Option<HandleObject>,
101 init: &IntersectionObserverEntryInit,
102 ) -> DomRoot<Self> {
103 let mut domrectreadonly_from_dictionary = |dictionary: &DOMRectInit| {
104 DOMRectReadOnly::new_from_dictionary(cx, window.as_global_scope(), proto, dictionary)
105 };
106 let observer = Box::new(Self::new_inherited(
107 init.time,
108 Some(&*domrectreadonly_from_dictionary(&init.rootBounds)),
109 &domrectreadonly_from_dictionary(&init.boundingClientRect),
110 &domrectreadonly_from_dictionary(&init.intersectionRect),
111 init.isIntersecting,
112 init.isVisible,
113 init.intersectionRatio,
114 &init.target,
115 ));
116 reflect_dom_object_with_proto_and_cx(observer, window, proto, cx)
117 }
118}
119
120impl IntersectionObserverEntryMethods<crate::DomTypeHolder> for IntersectionObserverEntry {
121 /// > The attribute must return a DOMHighResTimeStamp that corresponds to the time the
122 /// > intersection was recorded, relative to the time origin of the global object
123 /// > associated with the IntersectionObserver instance that generated the notification.
124 ///
125 /// <https://w3c.github.io/IntersectionObserver/#dom-intersectionobserverentry-time>
126 fn Time(&self) -> Finite<f64> {
127 self.time.get()
128 }
129
130 /// > For a same-origin-domain target, this will be the root intersection rectangle.
131 /// > Otherwise, this will be null. Note that if the target is in a different browsing
132 /// > context than the intersection root, this will be in a different coordinate system
133 /// > than boundingClientRect and intersectionRect.
134 ///
135 /// <https://w3c.github.io/IntersectionObserver/#dom-intersectionobserverentry-rootbounds>
136 fn GetRootBounds(&self) -> Option<DomRoot<DOMRectReadOnly>> {
137 self.root_bounds.as_ref().map(|rect| rect.as_rooted())
138 }
139
140 /// > A DOMRectReadOnly obtained by getting the bounding box for target.
141 ///
142 /// <https://w3c.github.io/IntersectionObserver/#dom-intersectionobserverentry-boundingclientrect>
143 fn BoundingClientRect(&self) -> DomRoot<DOMRectReadOnly> {
144 self.bounding_client_rect.as_rooted()
145 }
146
147 /// > boundingClientRect, intersected by each of target's ancestors' clip rects (up to
148 /// > but not including root), intersected with the root intersection rectangle. This
149 /// > value represents the portion of target that intersects with the root intersection
150 /// > rectangle.
151 ///
152 /// <https://w3c.github.io/IntersectionObserver/#dom-intersectionobserverentry-intersectionrect>
153 fn IntersectionRect(&self) -> DomRoot<DOMRectReadOnly> {
154 self.intersection_rect.as_rooted()
155 }
156
157 /// > True if the target intersects with the root; false otherwise. This flag makes it
158 /// > possible to distinguish between an IntersectionObserverEntry signalling the
159 /// > transition from intersecting to not-intersecting; and an IntersectionObserverEntry
160 /// > signalling a transition from not-intersecting to intersecting with a zero-area
161 /// > intersection rect (as will happen with edge-adjacent intersections, or when the
162 /// > boundingClientRect has zero area).
163 ///
164 /// <https://w3c.github.io/IntersectionObserver/#dom-intersectionobserverentry-isintersecting>
165 fn IsIntersecting(&self) -> bool {
166 self.is_intersecting.get()
167 }
168
169 /// > Contains the result of running the visibility algorithm on target.
170 ///
171 /// <https://w3c.github.io/IntersectionObserver/#dom-intersectionobserverentry-isvisible>
172 fn IsVisible(&self) -> bool {
173 self.is_visible.get()
174 }
175
176 /// > If the boundingClientRect has non-zero area, this will be the ratio of
177 /// > intersectionRect area to boundingClientRect area. Otherwise, this will be 1 if the
178 /// > isIntersecting is true, and 0 if not.
179 ///
180 /// <https://w3c.github.io/IntersectionObserver/#dom-intersectionobserverentry-intersectionratio>
181 fn IntersectionRatio(&self) -> Finite<f64> {
182 self.intersection_ratio.get()
183 }
184
185 /// > The Element whose intersection with the intersection root changed.
186 ///
187 /// <https://w3c.github.io/IntersectionObserver/#dom-intersectionobserverentry-target>
188 fn Target(&self) -> DomRoot<Element> {
189 self.target.as_rooted()
190 }
191
192 /// <https://w3c.github.io/IntersectionObserver/#dom-intersectionobserverentry-intersectionobserverentry>
193 fn Constructor(
194 cx: &mut JSContext,
195 window: &Window,
196 proto: Option<HandleObject>,
197 init: &IntersectionObserverEntryInit,
198 ) -> DomRoot<IntersectionObserverEntry> {
199 Self::new_from_dictionary(cx, window, proto, init)
200 }
201}