fune/dom/base/DOMIntersectionObserver.h
Emilio Cobos Álvarez 8101ae2ea8 Bug 1523071 - Use Rust lengths for margin / padding / inset. r=jwatt
Also for the intersection observer root margin, since it was easier to fix it
up and clean it up than not doing it.

This is the first big step to get rid of nscoord. It duplicates a bit of logic
in nsLayoutUtils since for now max/min-width/height are still represented with
nsStyleCoord, but I think I prefer to land this incrementally.

I didn't add helpers for the physical accessors of the style rect sides that
nsStyleSides has (top/bottom/left/right) since I think we generally should
encourage the logical versions, but let me know if you want me to do that.

Differential Revision: https://phabricator.services.mozilla.com/D17739
2019-02-10 04:11:58 +01:00

166 lines
5.8 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef DOMIntersectionObserver_h
#define DOMIntersectionObserver_h
#include "mozilla/dom/IntersectionObserverBinding.h"
#include "nsStyleCoord.h"
#include "nsTArray.h"
using mozilla::dom::DOMRect;
using mozilla::dom::Element;
namespace mozilla {
namespace dom {
class DOMIntersectionObserver;
class DOMIntersectionObserverEntry final : public nsISupports,
public nsWrapperCache {
~DOMIntersectionObserverEntry() {}
public:
DOMIntersectionObserverEntry(nsISupports* aOwner, DOMHighResTimeStamp aTime,
RefPtr<DOMRect> aRootBounds,
RefPtr<DOMRect> aBoundingClientRect,
RefPtr<DOMRect> aIntersectionRect,
bool aIsIntersecting, Element* aTarget,
double aIntersectionRatio)
: mOwner(aOwner),
mTime(aTime),
mRootBounds(aRootBounds),
mBoundingClientRect(aBoundingClientRect),
mIntersectionRect(aIntersectionRect),
mIsIntersecting(aIsIntersecting),
mTarget(aTarget),
mIntersectionRatio(aIntersectionRatio) {}
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMIntersectionObserverEntry)
nsISupports* GetParentObject() const { return mOwner; }
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override {
return mozilla::dom::IntersectionObserverEntry_Binding::Wrap(aCx, this,
aGivenProto);
}
DOMHighResTimeStamp Time() { return mTime; }
DOMRect* GetRootBounds() { return mRootBounds; }
DOMRect* BoundingClientRect() { return mBoundingClientRect; }
DOMRect* IntersectionRect() { return mIntersectionRect; }
bool IsIntersecting() { return mIsIntersecting; }
double IntersectionRatio() { return mIntersectionRatio; }
Element* Target() { return mTarget; }
protected:
nsCOMPtr<nsISupports> mOwner;
DOMHighResTimeStamp mTime;
RefPtr<DOMRect> mRootBounds;
RefPtr<DOMRect> mBoundingClientRect;
RefPtr<DOMRect> mIntersectionRect;
bool mIsIntersecting;
RefPtr<Element> mTarget;
double mIntersectionRatio;
};
#define NS_DOM_INTERSECTION_OBSERVER_IID \
{ \
0x8570a575, 0xe303, 0x4d18, { \
0xb6, 0xb1, 0x4d, 0x2b, 0x49, 0xd8, 0xef, 0x94 \
} \
}
class DOMIntersectionObserver final : public nsISupports,
public nsWrapperCache {
virtual ~DOMIntersectionObserver() { Disconnect(); }
public:
DOMIntersectionObserver(already_AddRefed<nsPIDOMWindowInner>&& aOwner,
mozilla::dom::IntersectionCallback& aCb)
: mOwner(aOwner),
mDocument(mOwner->GetExtantDoc()),
mCallback(&aCb),
mConnected(false) {}
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMIntersectionObserver)
NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOM_INTERSECTION_OBSERVER_IID)
static already_AddRefed<DOMIntersectionObserver> Constructor(
const mozilla::dom::GlobalObject& aGlobal,
mozilla::dom::IntersectionCallback& aCb, mozilla::ErrorResult& aRv);
static already_AddRefed<DOMIntersectionObserver> Constructor(
const mozilla::dom::GlobalObject& aGlobal,
mozilla::dom::IntersectionCallback& aCb,
const mozilla::dom::IntersectionObserverInit& aOptions,
mozilla::ErrorResult& aRv);
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override {
return mozilla::dom::IntersectionObserver_Binding::Wrap(aCx, this,
aGivenProto);
}
nsISupports* GetParentObject() const { return mOwner; }
Element* GetRoot() const { return mRoot; }
void GetRootMargin(mozilla::dom::DOMString& aRetVal);
void GetThresholds(nsTArray<double>& aRetVal);
void Observe(Element& aTarget);
void Unobserve(Element& aTarget);
void UnlinkTarget(Element& aTarget);
void Disconnect();
void TakeRecords(nsTArray<RefPtr<DOMIntersectionObserverEntry>>& aRetVal);
mozilla::dom::IntersectionCallback* IntersectionCallback() {
return mCallback;
}
bool SetRootMargin(const nsAString& aString);
void Update(Document* aDocument, DOMHighResTimeStamp time);
void Notify();
protected:
void Connect();
void QueueIntersectionObserverEntry(Element* aTarget,
DOMHighResTimeStamp time,
const Maybe<nsRect>& aRootRect,
const nsRect& aTargetRect,
const Maybe<nsRect>& aIntersectionRect,
double aIntersectionRatio);
nsCOMPtr<nsPIDOMWindowInner> mOwner;
RefPtr<Document> mDocument;
RefPtr<mozilla::dom::IntersectionCallback> mCallback;
RefPtr<Element> mRoot;
StyleRect<LengthPercentage> mRootMargin;
nsTArray<double> mThresholds;
// Holds raw pointers which are explicitly cleared by UnlinkTarget().
nsTArray<Element*> mObservationTargets;
nsTArray<RefPtr<DOMIntersectionObserverEntry>> mQueuedEntries;
bool mConnected;
};
NS_DEFINE_STATIC_IID_ACCESSOR(DOMIntersectionObserver,
NS_DOM_INTERSECTION_OBSERVER_IID)
} // namespace dom
} // namespace mozilla
#endif