Bug 1781046 - Add internal ResizeObserver for last remembered size. r=emilio

In a follow-up, it will take care of updating the last remembered size
as described in https://drafts.csswg.org/css-sizing-4/#last-remembered

Differential Revision: https://phabricator.services.mozilla.com/D154325
This commit is contained in:
Oriol Brufau
2022-08-12 15:06:43 +00:00
parent d89d19a97b
commit eaa7bf5309
4 changed files with 60 additions and 0 deletions

View File

@@ -2521,6 +2521,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(Document)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOnloadBlocker)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLazyLoadImageObserver)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLazyLoadImageObserverViewport)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLastRememberedSizeObserver)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMImplementation)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImageMaps)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOrientationPendingPromise)
@@ -2640,6 +2641,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Document)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDisplayDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mLazyLoadImageObserver)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mLazyLoadImageObserverViewport)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mLastRememberedSizeObserver)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFontFaceSet)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mReadyForIdle)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentL10n)
@@ -15789,6 +15791,27 @@ void Document::IncLazyLoadImageReachViewport(bool aLoading) {
}
}
ResizeObserver& Document::EnsureLastRememberedSizeObserver() {
if (!mLastRememberedSizeObserver) {
mLastRememberedSizeObserver =
ResizeObserver::CreateLastRememberedSizeObserver(*this);
}
return *mLastRememberedSizeObserver;
}
void Document::ObserveForLastRememberedSize(Element& aElement) {
// Options are initialized with ResizeObserverBoxOptions::Content_box by
// default, which is what we want.
static ResizeObserverOptions options;
EnsureLastRememberedSizeObserver().Observe(aElement, options);
}
void Document::UnobserveForLastRememberedSize(Element& aElement) {
if (mLastRememberedSizeObserver) {
mLastRememberedSizeObserver->Unobserve(aElement);
}
}
void Document::NotifyLayerManagerRecreated() {
NotifyActivityChanged();
EnumerateSubDocuments([](Document& aSubDoc) {

View File

@@ -3748,6 +3748,13 @@ class Document : public nsINode,
void IncLazyLoadImageStarted() { ++mLazyLoadImageStarted; }
void IncLazyLoadImageReachViewport(bool aLoading);
ResizeObserver* GetLastRememberedSizeObserver() {
return mLastRememberedSizeObserver;
}
ResizeObserver& EnsureLastRememberedSizeObserver();
void ObserveForLastRememberedSize(Element&);
void UnobserveForLastRememberedSize(Element&);
// Dispatch a runnable related to the document.
nsresult Dispatch(TaskCategory aCategory,
already_AddRefed<nsIRunnable>&& aRunnable) final;
@@ -5113,6 +5120,10 @@ class Document : public nsINode,
// Used to measure how effective the lazyload thresholds are.
RefPtr<DOMIntersectionObserver> mLazyLoadImageObserverViewport;
// ResizeObserver for storing and removing the last remembered size.
// @see {@link https://drafts.csswg.org/css-sizing-4/#last-remembered}
RefPtr<ResizeObserver> mLastRememberedSizeObserver;
// Stack of top layer elements.
nsTArray<nsWeakPtr> mTopLayer;

View File

@@ -295,6 +295,18 @@ void ResizeObserver::Observe(Element& aTarget,
observation =
new ResizeObservation(aTarget, *this, aOptions.mBox,
frame ? frame->GetWritingMode() : WritingMode());
if (this == mDocument->GetLastRememberedSizeObserver()) {
// Resize observations are initialized with a (0, 0) mLastReportedSize,
// this means that the callback won't be called if the element is 0x0.
// But we need it called for handling the last remembered size, so set
// mLastReportedSize to an invalid size to ensure IsActive() is true
// for the current element size.
// See https://github.com/w3c/csswg-drafts/issues/3664 about doing this in
// the general case, then we won't need this hack for the last remembered
// size, and will have consistency with IntersectionObserver.
observation->UpdateLastReportedSize(gfx::Size(-1, -1));
MOZ_ASSERT(observation->IsActive());
}
mObservationList.insertBack(observation);
// Per the spec, we need to trigger notification in event loop that
@@ -491,6 +503,17 @@ void ResizeObserverEntry::SetDevicePixelContentSize(const gfx::Size& aSize) {
mDevicePixelContentBoxSize = new ResizeObserverSize(mOwner, aSize, wm);
}
static void LastRememberedSizeCallback(
const Sequence<OwningNonNull<ResizeObserverEntry>>& aEntries,
ResizeObserver& aObserver) {
// TODO.
}
/* static */ already_AddRefed<ResizeObserver>
ResizeObserver::CreateLastRememberedSizeObserver(Document& aDocument) {
return do_AddRef(new ResizeObserver(aDocument, LastRememberedSizeCallback));
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ResizeObserverSize, mOwner)
NS_IMPL_CYCLE_COLLECTING_ADDREF(ResizeObserverSize)
NS_IMPL_CYCLE_COLLECTING_RELEASE(ResizeObserverSize)

View File

@@ -180,6 +180,9 @@ class ResizeObserver final : public nsISupports, public nsWrapperCache {
*/
MOZ_CAN_RUN_SCRIPT uint32_t BroadcastActiveObservations();
static already_AddRefed<ResizeObserver> CreateLastRememberedSizeObserver(
Document&);
protected:
~ResizeObserver() { Disconnect(); }