Bug 1781046 - Make ResizeObserver::mCallback Variant. r=emilio

So that it can accept a callback function implemented in C++.

Analogous to what D61436 did for DOMIntersectionObserver.

Differential Revision: https://phabricator.services.mozilla.com/D154324
This commit is contained in:
Oriol Brufau 2022-08-12 15:06:42 +00:00
Родитель 0a993f3a94
Коммит 285f6f3ee9
2 изменённых файлов: 35 добавлений и 7 удалений

Просмотреть файл

@ -202,14 +202,23 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(ResizeObserver)
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(ResizeObserver)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ResizeObserver)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner, mDocument, mCallback,
mActiveTargets, mObservationMap);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner, mDocument, mActiveTargets,
mObservationMap);
if (tmp->mCallback.is<RefPtr<ResizeObserverCallback>>()) {
ImplCycleCollectionTraverse(
cb, tmp->mCallback.as<RefPtr<ResizeObserverCallback>>(), "mCallback",
0);
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ResizeObserver)
tmp->Disconnect();
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner, mDocument, mCallback, mActiveTargets,
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner, mDocument, mActiveTargets,
mObservationMap);
if (tmp->mCallback.is<RefPtr<ResizeObserverCallback>>()) {
ImplCycleCollectionUnlink(
tmp->mCallback.as<RefPtr<ResizeObserverCallback>>());
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
@ -220,6 +229,14 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ResizeObserver)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
ResizeObserver::ResizeObserver(Document& aDocument, NativeCallback aCallback)
: mOwner(aDocument.GetInnerWindow()),
mDocument(&aDocument),
mCallback(aCallback) {
MOZ_ASSERT(mOwner, "Need a non-null owner window");
MOZ_ASSERT(mDocument == mOwner->GetExtantDoc());
}
already_AddRefed<ResizeObserver> ResizeObserver::Constructor(
const GlobalObject& aGlobal, ResizeObserverCallback& aCb,
ErrorResult& aRv) {
@ -383,8 +400,13 @@ uint32_t ResizeObserver::BroadcastActiveObservations() {
}
}
RefPtr<ResizeObserverCallback> callback(mCallback);
callback->Call(this, entries, *this);
if (mCallback.is<RefPtr<ResizeObserverCallback>>()) {
RefPtr<ResizeObserverCallback> callback(
mCallback.as<RefPtr<ResizeObserverCallback>>());
callback->Call(this, entries, *this);
} else {
mCallback.as<NativeCallback>()(entries, *this);
}
mActiveTargets.Clear();
mHasSkippedTargets = false;

Просмотреть файл

@ -115,13 +115,19 @@ class ResizeObservation final : public LinkedListElement<ResizeObservation> {
* https://drafts.csswg.org/resize-observer/#api
*/
class ResizeObserver final : public nsISupports, public nsWrapperCache {
using NativeCallback = void (*)(
const Sequence<OwningNonNull<ResizeObserverEntry>>&, ResizeObserver&);
ResizeObserver(Document& aDocument, NativeCallback aCallback);
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ResizeObserver)
ResizeObserver(nsCOMPtr<nsPIDOMWindowInner>&& aOwner, Document* aDocument,
ResizeObserverCallback& aCb)
: mOwner(std::move(aOwner)), mDocument(aDocument), mCallback(&aCb) {
: mOwner(std::move(aOwner)),
mDocument(aDocument),
mCallback(RefPtr<ResizeObserverCallback>(&aCb)) {
MOZ_ASSERT(mOwner, "Need a non-null owner window");
MOZ_ASSERT(mDocument, "Need a non-null doc");
MOZ_ASSERT(mDocument == mOwner->GetExtantDoc());
@ -180,7 +186,7 @@ class ResizeObserver final : public nsISupports, public nsWrapperCache {
nsCOMPtr<nsPIDOMWindowInner> mOwner;
// The window's document at the time of ResizeObserver creation.
RefPtr<Document> mDocument;
RefPtr<ResizeObserverCallback> mCallback;
Variant<RefPtr<ResizeObserverCallback>, NativeCallback> mCallback;
nsTArray<RefPtr<ResizeObservation>> mActiveTargets;
// The spec uses a list to store the skipped targets. However, it seems what
// we want is to check if there are any skipped targets (i.e. existence).