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/. */
7 #ifndef DOMIntersectionObserver_h
8 #define DOMIntersectionObserver_h
10 #include "mozilla/Attributes.h"
11 #include "mozilla/dom/IntersectionObserverBinding.h"
12 #include "mozilla/ServoStyleConsts.h"
13 #include "mozilla/Variant.h"
14 #include "nsDOMNavigationTiming.h"
16 #include "nsTHashSet.h"
21 class DOMIntersectionObserver
;
23 class DOMIntersectionObserverEntry final
: public nsISupports
,
24 public nsWrapperCache
{
25 ~DOMIntersectionObserverEntry() = default;
28 DOMIntersectionObserverEntry(nsISupports
* aOwner
, DOMHighResTimeStamp aTime
,
29 RefPtr
<DOMRect
> aRootBounds
,
30 RefPtr
<DOMRect
> aBoundingClientRect
,
31 RefPtr
<DOMRect
> aIntersectionRect
,
32 bool aIsIntersecting
, Element
* aTarget
,
33 double aIntersectionRatio
)
36 mRootBounds(std::move(aRootBounds
)),
37 mBoundingClientRect(std::move(aBoundingClientRect
)),
38 mIntersectionRect(std::move(aIntersectionRect
)),
39 mIsIntersecting(aIsIntersecting
),
41 mIntersectionRatio(aIntersectionRatio
) {}
42 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
43 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMIntersectionObserverEntry
)
45 nsISupports
* GetParentObject() const { return mOwner
; }
47 JSObject
* WrapObject(JSContext
* aCx
,
48 JS::Handle
<JSObject
*> aGivenProto
) override
{
49 return IntersectionObserverEntry_Binding::Wrap(aCx
, this, aGivenProto
);
52 DOMHighResTimeStamp
Time() const { return mTime
; }
54 DOMRect
* GetRootBounds() { return mRootBounds
; }
56 DOMRect
* BoundingClientRect() { return mBoundingClientRect
; }
58 DOMRect
* IntersectionRect() { return mIntersectionRect
; }
60 bool IsIntersecting() const { return mIsIntersecting
; }
62 double IntersectionRatio() const { return mIntersectionRatio
; }
64 Element
* Target() { return mTarget
; }
67 nsCOMPtr
<nsISupports
> mOwner
;
68 DOMHighResTimeStamp mTime
;
69 RefPtr
<DOMRect
> mRootBounds
;
70 RefPtr
<DOMRect
> mBoundingClientRect
;
71 RefPtr
<DOMRect
> mIntersectionRect
;
73 RefPtr
<Element
> mTarget
;
74 double mIntersectionRatio
;
77 #define NS_DOM_INTERSECTION_OBSERVER_IID \
79 0x8570a575, 0xe303, 0x4d18, { \
80 0xb6, 0xb1, 0x4d, 0x2b, 0x49, 0xd8, 0xef, 0x94 \
84 class DOMIntersectionObserver final
: public nsISupports
,
85 public nsWrapperCache
{
86 virtual ~DOMIntersectionObserver() { Disconnect(); }
88 using NativeCallback
= void (*)(
89 const Sequence
<OwningNonNull
<DOMIntersectionObserverEntry
>>& aEntries
);
90 DOMIntersectionObserver(Document
&, NativeCallback
);
93 DOMIntersectionObserver(already_AddRefed
<nsPIDOMWindowInner
>&& aOwner
,
94 dom::IntersectionCallback
& aCb
);
95 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
96 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMIntersectionObserver
)
97 NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOM_INTERSECTION_OBSERVER_IID
)
99 static already_AddRefed
<DOMIntersectionObserver
> Constructor(
100 const GlobalObject
&, dom::IntersectionCallback
&, ErrorResult
&);
101 static already_AddRefed
<DOMIntersectionObserver
> Constructor(
102 const GlobalObject
&, dom::IntersectionCallback
&,
103 const IntersectionObserverInit
&, ErrorResult
&);
105 JSObject
* WrapObject(JSContext
* aCx
,
106 JS::Handle
<JSObject
*> aGivenProto
) override
{
107 return IntersectionObserver_Binding::Wrap(aCx
, this, aGivenProto
);
110 nsISupports
* GetParentObject() const;
112 nsINode
* GetRoot() const { return mRoot
; }
114 void GetRootMargin(nsACString
&);
115 bool SetRootMargin(const nsACString
&);
117 void GetThresholds(nsTArray
<double>& aRetVal
);
118 void Observe(Element
& aTarget
);
119 void Unobserve(Element
& aTarget
);
121 void UnlinkTarget(Element
& aTarget
);
124 void TakeRecords(nsTArray
<RefPtr
<DOMIntersectionObserverEntry
>>& aRetVal
);
126 void Update(Document
* aDocument
, DOMHighResTimeStamp time
);
127 MOZ_CAN_RUN_SCRIPT
void Notify();
129 static already_AddRefed
<DOMIntersectionObserver
> CreateLazyLoadObserver(
131 static already_AddRefed
<DOMIntersectionObserver
>
132 CreateLazyLoadObserverViewport(Document
&);
136 void QueueIntersectionObserverEntry(Element
* aTarget
,
137 DOMHighResTimeStamp time
,
138 const Maybe
<nsRect
>& aRootRect
,
139 const nsRect
& aTargetRect
,
140 const Maybe
<nsRect
>& aIntersectionRect
,
141 bool aIsIntersecting
,
142 double aIntersectionRatio
);
144 nsCOMPtr
<nsPIDOMWindowInner
> mOwner
;
145 RefPtr
<Document
> mDocument
;
146 Variant
<RefPtr
<dom::IntersectionCallback
>, NativeCallback
> mCallback
;
147 RefPtr
<nsINode
> mRoot
;
148 StyleRect
<LengthPercentage
> mRootMargin
;
149 nsTArray
<double> mThresholds
;
151 // These hold raw pointers which are explicitly cleared by UnlinkTarget().
153 // We keep a set and an array because we need ordered access, but also
154 // constant time lookup.
155 nsTArray
<Element
*> mObservationTargets
;
156 nsTHashSet
<Element
*> mObservationTargetSet
;
158 nsTArray
<RefPtr
<DOMIntersectionObserverEntry
>> mQueuedEntries
;
162 NS_DEFINE_STATIC_IID_ACCESSOR(DOMIntersectionObserver
,
163 NS_DOM_INTERSECTION_OBSERVER_IID
)
166 } // namespace mozilla