diff --git a/dom/base/ResizeObserver.cpp b/dom/base/ResizeObserver.cpp index 30d029b99aba3..7a47c9541448a 100644 --- a/dom/base/ResizeObserver.cpp +++ b/dom/base/ResizeObserver.cpp @@ -168,7 +168,13 @@ ResizeObservation::ResizeObservation(Element& aTarget, ResizeObserver& aObserver, ResizeObserverBoxOptions aBox, WritingMode aWm) - : mTarget(&aTarget), mObserver(&aObserver), mObservedBox(aBox) { + : mTarget(&aTarget), + mObserver(&aObserver), + mObservedBox(aBox), + mLastReportedSize( + aWm, StaticPrefs::dom_resize_observer_last_reported_size_invalid() + ? gfx::Size(-1, -1) + : gfx::Size()) { aTarget.BindObject(mObserver); } @@ -295,7 +301,8 @@ void ResizeObserver::Observe(Element& aTarget, observation = new ResizeObservation(aTarget, *this, aOptions.mBox, frame ? frame->GetWritingMode() : WritingMode()); - if (this == mDocument->GetLastRememberedSizeObserver()) { + if (!StaticPrefs::dom_resize_observer_last_reported_size_invalid() && + 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 diff --git a/dom/base/ResizeObserver.h b/dom/base/ResizeObserver.h index f9e07d68fc33a..c83bfb0b96fa8 100644 --- a/dom/base/ResizeObserver.h +++ b/dom/base/ResizeObserver.h @@ -105,8 +105,6 @@ class ResizeObservation final : public LinkedListElement { // The latest recorded of observed target. // This will be CSS pixels for border-box/content-box, or device pixels for // device-pixel-content-box. - // Note: We use default constructor for this because we want to start with a - // (0, 0) size, per the spec. LogicalPixelSize mLastReportedSize; }; diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index 36d0c87ce32a3..79ab2d5bb008d 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -4581,6 +4581,13 @@ value: 5 mirror: always +# Initialize Resize Observer's last reported size to -1x-1, and not 0x0, +# as per CSSWG resolution: https://github.com/w3c/csswg-drafts/issues/3664 +- name: dom.resize_observer.last_reported_size_invalid + type: bool + value: true + mirror: always + #--------------------------------------------------------------------------- # Prefs starting with "editor" #--------------------------------------------------------------------------- diff --git a/testing/web-platform/tests/resize-observer/notify.html b/testing/web-platform/tests/resize-observer/notify.html index d5888515d5a08..7f0e448540465 100644 --- a/testing/web-platform/tests/resize-observer/notify.html +++ b/testing/web-platform/tests/resize-observer/notify.html @@ -194,27 +194,38 @@ function test6() { let helper = new ResizeTestHelper( - "test6: inline element does not notify", + "test6: inline element notifies once with 0x0.", [ { setup: observer => { observer.observe(inline); - observer.observe(t1); - t1.style.width = "66px"; - inline.style.width = "66px"; }, notify: (entries, observer) => { - assert_equals(entries.length, 1, "inline elements must not trigger notifications"); - assert_equals(entries[0].target, t1, "inline elements must not trigger notifications"); + assert_equals(entries.length, 1, "observing inline element triggers notification"); + assert_equals(entries[0].target, inline, "observing inline element triggers notification"); + assert_equals(entries[0].contentRect.width, 0); + assert_equals(entries[0].contentRect.height, 0); return true; // Delay next step } }, + { + setup: observer => { + inline.style.width = "66px"; + }, + notify: (entries, observer) => { + assert_unreached("resizing inline element should not cause resize notifications"); + }, + timeout: () => { + // expected + } + }, { // "inline element that becomes block should notify", setup: observer => { inline.style.display = "block"; }, notify: (entries, observer) => { - assert_equals(entries[0].target, inline); + assert_equals(entries.length, 1, "inline element becoming a non-zero sized block triggers a notification"); + assert_equals(entries[0].target, inline, "inline element becoming a non-zero sized block triggers a notification"); } } ]); diff --git a/testing/web-platform/tests/resize-observer/observe.html b/testing/web-platform/tests/resize-observer/observe.html index a3bf784b62cfc..f6015bef78825 100644 --- a/testing/web-platform/tests/resize-observer/observe.html +++ b/testing/web-platform/tests/resize-observer/observe.html @@ -719,16 +719,26 @@ let helper = new ResizeTestHelper( // See: https://drafts.csswg.org/resize-observer/#intro. - "test16: observations do not fire for non-replaced inline elements", + "test16: observations fire once with 0x0 size for non-replaced inline elements", [ { setup: observer => { observer.observe(t); }, notify: entries => { - assert_unreached("No observation should fire for non box element") - }, - timeout: () => {} + assert_equals(entries.length, 1, "1 pending notification"); + assert_equals(entries[0].target, t, "target is t"); + assert_equals(entries[0].contentRect.width, 0, "target width"); + assert_equals(entries[0].contentRect.height, 0, "target height"); + assert_equals(entries[0].contentBoxSize[0].inlineSize, 0, + "target content-box inline size"); + assert_equals(entries[0].contentBoxSize[0].blockSize, 0, + "target content-box block size"); + assert_equals(entries[0].borderBoxSize[0].inlineSize, 0, + "target border-box inline size"); + assert_equals(entries[0].borderBoxSize[0].blockSize, 0, + "target border-box block size"); + } } ]); diff --git a/testing/web-platform/tests/resize-observer/svg.html b/testing/web-platform/tests/resize-observer/svg.html index 08c1cf9a37349..6511afc8b000a 100644 --- a/testing/web-platform/tests/resize-observer/svg.html +++ b/testing/web-platform/tests/resize-observer/svg.html @@ -345,10 +345,10 @@ observer.observe(view); }, notify: (entries, observer) => { - assert_unreached("no entries should be observed on Element"); - }, - timeout: () => { - // expected + assert_equals(entries.length, 1); + assert_equals(entries[0].target, view); + assert_equals(entries[0].contentRect.width, 0); + assert_equals(entries[0].contentRect.height, 0); } }, { @@ -356,10 +356,10 @@ observer.observe(stop); }, notify: (entries, observer) => { - assert_unreached("no entries should be observed on Element"); - }, - timeout: () => { - // expected + assert_equals(entries.length, 1); + assert_equals(entries[0].target, stop); + assert_equals(entries[0].contentRect.width, 0); + assert_equals(entries[0].contentRect.height, 0); } }, ]);