Bug 1792217 - Let last remembered size take all fragments into account regardless of pref. r=emilio
authorOriol Brufau <oriol-bugzilla@hotmail.com>
Fri, 23 Sep 2022 23:41:34 +0000
changeset 636385 4676713ac80822b5a6f7bef376003b76dee0c0f6
parent 636384 c7e6bf99e7f74ed9e98776e7b8f1a89ca85766ba
child 636386 8b438fac729bbd32ba68d531a7e24385c3a1924a
push id40262
push usermlaza@mozilla.com
push dateSat, 24 Sep 2022 09:33:46 +0000
treeherdermozilla-central@50f72898d7b8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs1792217
milestone107.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1792217 - Let last remembered size take all fragments into account regardless of pref. r=emilio ResizeObserver only handles multiple fragments when the preference dom.resize_observer.support_fragments is true. That's because this experimental behavior may have compat problems. But the last remembered size uses an internal ResizeObserver, so changing the signature of the callback is not a problem. Differential Revision: https://phabricator.services.mozilla.com/D158034
dom/base/ResizeObserver.cpp
dom/base/ResizeObserver.h
testing/web-platform/meta/css/css-sizing/contain-intrinsic-size/__dir__.ini
--- a/dom/base/ResizeObserver.cpp
+++ b/dom/base/ResizeObserver.cpp
@@ -69,17 +69,18 @@ static nsSize GetContentRectSize(const n
 /**
  * Returns |aTarget|'s size in the form of gfx::Size (in pixels).
  * If the target is an SVG that does not participate in CSS layout,
  * its width and height are determined from bounding box.
  *
  * https://www.w3.org/TR/resize-observer-1/#calculate-box-size
  */
 static AutoTArray<LogicalPixelSize, 1> CalculateBoxSize(
-    Element* aTarget, ResizeObserverBoxOptions aBox) {
+    Element* aTarget, ResizeObserverBoxOptions aBox,
+    const ResizeObserver& aObserver) {
   nsIFrame* frame = aTarget->GetPrimaryFrame();
 
   if (!frame) {
     // TODO: Should this return an empty array instead?
     // https://github.com/w3c/csswg-drafts/issues/7734
     return {LogicalPixelSize()};
   }
 
@@ -152,17 +153,18 @@ static AutoTArray<LogicalPixelSize, 1> C
         return rect.Size().ToUnknownSize();
       }
       case ResizeObserverBoxOptions::Content_box:
       default:
         break;
     }
     return CSSPixel::FromAppUnits(GetContentRectSize(*aFrame)).ToUnknownSize();
   };
-  if (!StaticPrefs::dom_resize_observer_support_fragments()) {
+  if (!StaticPrefs::dom_resize_observer_support_fragments() &&
+      !aObserver.HasNativeCallback()) {
     return {LogicalPixelSize(frame->GetWritingMode(), GetFrameSize(frame))};
   }
   AutoTArray<LogicalPixelSize, 1> size;
   for (nsIFrame* cur = frame; cur; cur = cur->GetNextContinuation()) {
     const WritingMode wm = cur->GetWritingMode();
     size.AppendElement(LogicalPixelSize(wm, GetFrameSize(cur)));
   }
   return size;
@@ -208,17 +210,18 @@ void ResizeObservation::Unlink(RemoveFro
 bool ResizeObservation::IsActive() const {
   // As detailed in the css-contain specification, if the target is hidden by
   // `content-visibility` it should not call its ResizeObservation callbacks.
   nsIFrame* frame = mTarget->GetPrimaryFrame();
   if (frame && frame->IsHiddenByContentVisibilityOnAnyAncestor()) {
     return false;
   }
 
-  return mLastReportedSize != CalculateBoxSize(mTarget, mObservedBox);
+  return mLastReportedSize !=
+         CalculateBoxSize(mTarget, mObservedBox, *mObserver);
 }
 
 void ResizeObservation::UpdateLastReportedSize(
     const nsTArray<LogicalPixelSize>& aSize) {
   mLastReportedSize.Assign(aSize);
 }
 
 // Only needed for refcounted objects.
@@ -392,21 +395,21 @@ uint32_t ResizeObserver::BroadcastActive
   }
 
   Sequence<OwningNonNull<ResizeObserverEntry>> entries;
 
   for (auto& observation : mActiveTargets) {
     Element* target = observation->Target();
 
     auto borderBoxSize =
-        CalculateBoxSize(target, ResizeObserverBoxOptions::Border_box);
+        CalculateBoxSize(target, ResizeObserverBoxOptions::Border_box, *this);
     auto contentBoxSize =
-        CalculateBoxSize(target, ResizeObserverBoxOptions::Content_box);
+        CalculateBoxSize(target, ResizeObserverBoxOptions::Content_box, *this);
     auto devicePixelContentBoxSize = CalculateBoxSize(
-        target, ResizeObserverBoxOptions::Device_pixel_content_box);
+        target, ResizeObserverBoxOptions::Device_pixel_content_box, *this);
     RefPtr<ResizeObserverEntry> entry =
         new ResizeObserverEntry(mOwner, *target, borderBoxSize, contentBoxSize,
                                 devicePixelContentBoxSize);
 
     if (!entries.AppendElement(entry.forget(), fallible)) {
       // Out of memory.
       break;
     }
--- a/dom/base/ResizeObserver.h
+++ b/dom/base/ResizeObserver.h
@@ -174,17 +174,17 @@ class ResizeObserver final : public nsIS
    * Returns whether this ResizeObserver has any skipped observations
    * since last GatherActiveObservations().
    */
   bool HasSkippedObservations() const { return mHasSkippedTargets; }
 
   /**
    * Returns whether this is an internal ResizeObserver with a native callback.
    */
-  bool HasNativeCallback() { return mCallback.is<NativeCallback>(); }
+  bool HasNativeCallback() const { return mCallback.is<NativeCallback>(); }
 
   /**
    * Invoke the callback function in JavaScript for all active observations
    * and pass the sequence of ResizeObserverEntry so JavaScript can access them.
    * The active observations' mLastReportedSize fields will be updated, and
    * mActiveTargets will be cleared. It also returns the shallowest depth of
    * elements from active observations or numeric_limits<uint32_t>::max() if
    * there are not any active observations.
--- a/testing/web-platform/meta/css/css-sizing/contain-intrinsic-size/__dir__.ini
+++ b/testing/web-platform/meta/css/css-sizing/contain-intrinsic-size/__dir__.ini
@@ -1,1 +1,1 @@
-prefs: [layout.css.content-visibility.enabled:true, dom.resize_observer.support_fragments:true]
+prefs: [layout.css.content-visibility.enabled:true]