Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 : * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #ifndef DOMIntersectionObserver_h
8 : #define DOMIntersectionObserver_h
9 :
10 : #include "mozilla/dom/IntersectionObserverBinding.h"
11 : #include "nsCSSValue.h"
12 : #include "nsTArray.h"
13 :
14 : using mozilla::dom::DOMRect;
15 : using mozilla::dom::Element;
16 :
17 : namespace mozilla {
18 : namespace dom {
19 :
20 : class DOMIntersectionObserver;
21 :
22 : class DOMIntersectionObserverEntry final : public nsISupports,
23 : public nsWrapperCache
24 : {
25 0 : ~DOMIntersectionObserverEntry() {}
26 :
27 : public:
28 0 : DOMIntersectionObserverEntry(nsISupports* aOwner,
29 : DOMHighResTimeStamp aTime,
30 : RefPtr<DOMRect> aRootBounds,
31 : RefPtr<DOMRect> aBoundingClientRect,
32 : RefPtr<DOMRect> aIntersectionRect,
33 : bool aIsIntersecting,
34 : Element* aTarget,
35 : double aIntersectionRatio)
36 0 : : mOwner(aOwner),
37 : mTime(aTime),
38 : mRootBounds(aRootBounds),
39 : mBoundingClientRect(aBoundingClientRect),
40 : mIntersectionRect(aIntersectionRect),
41 : mIsIntersecting(aIsIntersecting),
42 : mTarget(aTarget),
43 0 : mIntersectionRatio(aIntersectionRatio)
44 : {
45 0 : }
46 : NS_DECL_CYCLE_COLLECTING_ISUPPORTS
47 0 : NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMIntersectionObserverEntry)
48 :
49 0 : nsISupports* GetParentObject() const
50 : {
51 0 : return mOwner;
52 : }
53 :
54 0 : virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
55 : {
56 0 : return mozilla::dom::IntersectionObserverEntryBinding::Wrap(aCx, this, aGivenProto);
57 : }
58 :
59 0 : DOMHighResTimeStamp Time()
60 : {
61 0 : return mTime;
62 : }
63 :
64 0 : DOMRect* GetRootBounds()
65 : {
66 0 : return mRootBounds;
67 : }
68 :
69 0 : DOMRect* BoundingClientRect()
70 : {
71 0 : return mBoundingClientRect;
72 : }
73 :
74 0 : DOMRect* IntersectionRect()
75 : {
76 0 : return mIntersectionRect;
77 : }
78 :
79 0 : bool IsIntersecting()
80 : {
81 0 : return mIsIntersecting;
82 : }
83 :
84 0 : double IntersectionRatio()
85 : {
86 0 : return mIntersectionRatio;
87 : }
88 :
89 0 : Element* Target()
90 : {
91 0 : return mTarget;
92 : }
93 :
94 : protected:
95 : nsCOMPtr<nsISupports> mOwner;
96 : DOMHighResTimeStamp mTime;
97 : RefPtr<DOMRect> mRootBounds;
98 : RefPtr<DOMRect> mBoundingClientRect;
99 : RefPtr<DOMRect> mIntersectionRect;
100 : bool mIsIntersecting;
101 : RefPtr<Element> mTarget;
102 : double mIntersectionRatio;
103 : };
104 :
105 : #define NS_DOM_INTERSECTION_OBSERVER_IID \
106 : { 0x8570a575, 0xe303, 0x4d18, \
107 : { 0xb6, 0xb1, 0x4d, 0x2b, 0x49, 0xd8, 0xef, 0x94 } }
108 :
109 : class DOMIntersectionObserver final : public nsISupports,
110 : public nsWrapperCache
111 : {
112 0 : virtual ~DOMIntersectionObserver() {
113 0 : Disconnect();
114 0 : }
115 :
116 : public:
117 0 : DOMIntersectionObserver(already_AddRefed<nsPIDOMWindowInner>&& aOwner,
118 : mozilla::dom::IntersectionCallback& aCb)
119 0 : : mOwner(aOwner), mDocument(mOwner->GetExtantDoc()), mCallback(&aCb), mConnected(false)
120 : {
121 0 : }
122 : NS_DECL_CYCLE_COLLECTING_ISUPPORTS
123 0 : NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMIntersectionObserver)
124 : NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOM_INTERSECTION_OBSERVER_IID)
125 :
126 : static already_AddRefed<DOMIntersectionObserver>
127 : Constructor(const mozilla::dom::GlobalObject& aGlobal,
128 : mozilla::dom::IntersectionCallback& aCb,
129 : mozilla::ErrorResult& aRv);
130 : static already_AddRefed<DOMIntersectionObserver>
131 : Constructor(const mozilla::dom::GlobalObject& aGlobal,
132 : mozilla::dom::IntersectionCallback& aCb,
133 : const mozilla::dom::IntersectionObserverInit& aOptions,
134 : mozilla::ErrorResult& aRv);
135 :
136 0 : virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
137 : {
138 0 : return mozilla::dom::IntersectionObserverBinding::Wrap(aCx, this, aGivenProto);
139 : }
140 :
141 0 : nsISupports* GetParentObject() const
142 : {
143 0 : return mOwner;
144 : }
145 :
146 0 : Element* GetRoot() const {
147 0 : return mRoot;
148 : }
149 :
150 : void GetRootMargin(mozilla::dom::DOMString& aRetVal);
151 : void GetThresholds(nsTArray<double>& aRetVal);
152 : void Observe(Element& aTarget);
153 : void Unobserve(Element& aTarget);
154 :
155 : void UnlinkTarget(Element& aTarget);
156 : void Disconnect();
157 :
158 : void TakeRecords(nsTArray<RefPtr<DOMIntersectionObserverEntry>>& aRetVal);
159 :
160 0 : mozilla::dom::IntersectionCallback* IntersectionCallback() { return mCallback; }
161 :
162 : bool SetRootMargin(const nsAString& aString);
163 :
164 : void Update(nsIDocument* aDocument, DOMHighResTimeStamp time);
165 : void Notify();
166 :
167 : protected:
168 : void Connect();
169 : void QueueIntersectionObserverEntry(Element* aTarget,
170 : DOMHighResTimeStamp time,
171 : const Maybe<nsRect>& aRootRect,
172 : const nsRect& aTargetRect,
173 : const Maybe<nsRect>& aIntersectionRect,
174 : double aIntersectionRatio);
175 :
176 : nsCOMPtr<nsPIDOMWindowInner> mOwner;
177 : RefPtr<nsIDocument> mDocument;
178 : RefPtr<mozilla::dom::IntersectionCallback> mCallback;
179 : RefPtr<Element> mRoot;
180 : nsCSSRect mRootMargin;
181 : nsTArray<double> mThresholds;
182 :
183 : // Holds raw pointers which are explicitly cleared by UnlinkTarget().
184 : nsTArray<Element*> mObservationTargets;
185 :
186 : nsTArray<RefPtr<DOMIntersectionObserverEntry>> mQueuedEntries;
187 : bool mConnected;
188 : };
189 :
190 : NS_DEFINE_STATIC_IID_ACCESSOR(DOMIntersectionObserver, NS_DOM_INTERSECTION_OBSERVER_IID)
191 :
192 : } // namespace dom
193 : } // namespace mozilla
194 :
195 : #endif
|