Open Bug 2084270 Opened 8 days ago Updated 2 days ago

Lazy-loaded menu icons are missing outside clipped embedding documents

Categories

(Core :: Layout, defect)

Firefox 146
defect

Tracking

()

REOPENED
Tracking Status
firefox-esr115 --- unaffected
firefox-esr153 --- wontfix
firefox158 --- wontfix
firefox159 --- wontfix
firefox160 --- wontfix

People

(Reporter: welpy-cw, Assigned: welpy-cw, NeedInfo)

References

(Blocks 1 open bug, Regression)

Details

(Keywords: regression)

Attachments

(1 external file)

Reported in Thunderbird bug 2080460; investigation identified a Gecko IntersectionObserver clipping issue that can be reproduced without extension code.

Steps to reproduce:

  1. In Thunderbird, install an extension that creates submenu items with icons, such as the example in bug 2080460.
  2. Open its context-menu submenu so that some menu icons lie outside the main window.
  3. Compare the icons inside and outside the window. See bug 2080460 for screenshots and the original reproduction details.

Actual results:
Icons outside the window can remain blank. Their lazy-loading intersection calculation reports them as non-intersecting even though the popup is visible.

Expected results:
Visible popup images should load outside the bounds of their embedding document. Images scrolled out of the popup should remain clipped.

Root cause:
Bug 1979338 exposed the popup ancestor-clipping problem by making menu icons lazy-loaded. The underlying IntersectionObserver clipping error may predate that change.

Bug 1991410 exempted targets inside popups from the final intersection-root rectangle clip. However, ComputeTheIntersection() in dom/base/DOMIntersectionObserver.cpp still applies intermediate ancestor clips before that exemption, including clipped ancestors and subdocument viewports outside the popup.

Proposed fix:
Stop the ancestor clipping walk after processing the popup frame. This preserves overflow clipping on the popup itself and clipping by scroll containers inside it, while skipping clips belonging to ancestors outside the popup.

Validation:
A local browser regression test constructs a XUL popup in a clipped subdocument and observes its lazy-loaded images. It reproduces the original failure without extension code. Additional cases cover scrollport geometry, the popup overflow clip, explicit roots, and ordinary images that should remain clipped. The original early-break variant also failed the popup overflow-clip case; processing the popup before stopping fixes it.

Compilation and local Linux headless tests passed with the following fix. The new Gecko regression test was run through a temporary Thunderbird browser-test loader alongside the existing extension menu-icon tests: 59 assertions passed, with four expected todos and no failures. Windows and macOS have not been tested locally.

Bug 2009279 bypassed the visibility calculation by forcing eager loading of extension menu icons. Removing that workaround should be verified separately after this Gecko fix is available on the relevant Thunderbird branches.

Bug 1991410 skipped the final intersection-root clip for popup targets,
but ComputeTheIntersection can still clip them to intermediate ancestors,
including subdocument viewports, before reaching that check.

Stop traversing clipping ancestors after processing the popup frame.
Preserve both the popup's own overflow clip and scrollport clipping inside
it, allowing visible lazy-loaded menu images to load outside the embedding
document's viewport.

Add regression coverage for popup images in clipped subdocuments, scrolling
menus, the popup's own overflow clip, explicit intersection roots, and
ordinary images that should remain clipped. Assert the popup geometry so
incorrect placement cannot silently invalidate the test.

Assignee: nobody → h.w.forms
Status: NEW → ASSIGNED

Set release status flags based on info from the regressing bug 1979338

Pushed by ealvarez@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/50a9f61b8325 https://hg.mozilla.org/integration/autoland/rev/62f28182f0aa Stop applying ancestor clips outside popups in intersection observations. r=emilio,layout-reviewers
Pushed by smolnar@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/27948cb96b5e https://hg.mozilla.org/integration/autoland/rev/f022ed180f31 Revert "Bug 2084270 - Stop applying ancestor clips outside popups in intersection observations. r=emilio,layout-reviewers" for causing mochitest failures @ test_intersectionobserver_popup

Backed out for causing mochitest failures @ test_intersectionobserver_popup

Backout link: https://hg.mozilla.org/integration/autoland/rev/f022ed180f319fd15def9f51ab5879609f8cbc88

Push with failures

Failure log

[task 2026-10-21T01:48:40.391+00:00] 01:48:40     INFO - Buffered messages finished
[task 2026-10-21T01:48:40.395+00:00] 01:48:40     INFO - TEST-UNEXPECTED-FAIL | dom/base/test/chrome/test_intersectionobserver_popup.xhtml | The popup should be outside the embedding document viewport
[task 2026-10-21T01:48:40.395+00:00] 01:48:40     INFO - SimpleTest.ok@chrome://mochikit/content/tests/SimpleTest/SimpleTest.js:424:16
[task 2026-10-21T01:48:40.395+00:00] 01:48:40     INFO - test_popup_outside_subdocument@chrome://mochitests/content/chrome/dom/base/test/chrome/test_intersectionobserver_popup.xhtml:30:5
[task 2026-10-21T01:48:40.395+00:00] 01:48:40     INFO - async*add_task/nextTick/<@chrome://mochikit/content/tests/SimpleTest/SimpleTest.js:2219:34
[task 2026-10-21T01:48:40.395+00:00] 01:48:40     INFO - nextTick@chrome://mochikit/content/tests/SimpleTest/SimpleTest.js:2263:11
[task 2026-10-21T01:48:40.395+00:00] 01:48:40     INFO - setTimeout handler*SimpleTest_setTimeoutShim@chrome://mochikit/content/tests/SimpleTest/SimpleTest.js:925:41
[task 2026-10-21T01:48:40.395+00:00] 01:48:40     INFO - nextTick@chrome://mochikit/content/tests/SimpleTest/SimpleTest.js:2177:21
[task 2026-10-21T01:48:40.395+00:00] 01:48:40     INFO - setTimeout handler*SimpleTest_setTimeoutShim@chrome://mochikit/content/tests/SimpleTest/SimpleTest.js:925:41
[task 2026-10-21T01:48:40.395+00:00] 01:48:40     INFO - nextTick@chrome://mochikit/content/tests/SimpleTest/SimpleTest.js:2177:21
[task 2026-10-21T01:48:40.395+00:00] 01:48:40     INFO - setTimeout handler*SimpleTest_setTimeoutShim@chrome://mochikit/content/tests/SimpleTest/SimpleTest.js:925:41
[task 2026-10-21T01:48:40.395+00:00] 01:48:40     INFO - nextTick@chrome://mochikit/content/tests/SimpleTest/SimpleTest.js:2177:21
[task 2026-10-21T01:48:40.395+00:00] 01:48:40     INFO - setTimeout handler*SimpleTest_setTimeoutShim@chrome://mochikit/content/tests/SimpleTest/SimpleTest.js:925:41
[task 2026-10-21T01:48:40.395+00:00] 01:48:40     INFO - nextTick@chrome://mochikit/content/tests/SimpleTest/SimpleTest.js:2177:21
[task 2026-10-21T01:48:40.395+00:00] 01:48:40     INFO - setTimeout handler*SimpleTest_setTimeoutShim@chrome://mochikit/content/tests/SimpleTest/SimpleTest.js:925:41
[task 2026-10-21T01:48:40.395+00:00] 01:48:40     INFO - add_task@chrome://mochikit/content/tests/SimpleTest/SimpleTest.js:2161:17
[task 2026-10-21T01:48:40.395+00:00] 01:48:40     INFO - @chrome://mochitests/content/chrome/dom/base/test/chrome/test_intersectionobserver_popup.xhtml:15:9
[task 2026-10-21T01:48:40.395+00:00] 01:48:40     INFO - TEST-PASS | dom/base/test/chrome/test_intersectionobserver_popup.xhtml | The popup content should intersect outside the subdocument viewport
[task 2026-10-21T01:48:40.396+00:00] 01:48:40     INFO - TEST-PASS | dom/base/test/chrome/test_intersectionobserver_popup.xhtml | The popup content should be fully visible
[task 2026-10-21T01:48:40.396+00:00] 01:48:40     INFO - add_task | Leaving test_popup_outside_subdocument
[task 2026-10-21T01:48:40.397+00:00] 01:48:40     INFO - GECKO(32450) | MEMORY STAT vsizeMaxContiguous not supported in this build configuration.
[task 2026-10-21T01:48:40.398+00:00] 01:48:40     INFO - GECKO(32450) | MEMORY STAT | vsize 12539MB | residentFast 667MB | heapAllocated 334MB
[task 2026-10-21T01:48:40.488+00:00] 01:48:40     INFO - Not taking screenshot here: see the one that was previously logged
[task 2026-10-21T01:48:40.488+00:00] 01:48:40     INFO - TEST-UNEXPECTED-FAIL | dom/base/test/chrome/test_intersectionobserver_popup.xhtml | profile uploaded in profile_test_intersectionobserver_popup-2.xhtml.json.gz
[task 2026-10-21T01:48:40.489+00:00] 01:48:40     INFO - Not taking screenshot here: see the one that was previously logged
[task 2026-10-21T01:48:40.490+00:00] 01:48:40     INFO - TEST-UNEXPECTED-FAIL | dom/base/test/chrome/test_intersectionobserver_popup.xhtml | Finished in 147ms
[task 2026-10-21T01:48:40.490+00:00] 01:48:40     INFO - {'runtime': 147}
Flags: needinfo?(h.w.forms)
Pushed by ealvarez@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/09284977af1b https://hg.mozilla.org/integration/autoland/rev/5c69f54ccef9 Stop applying ancestor clips outside popups in intersection observations. r=emilio,layout-reviewers
Pushed by smolnar@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/d9098b3e11c2 https://hg.mozilla.org/integration/autoland/rev/6394817c482c Revert "Bug 2084270 - Stop applying ancestor clips outside popups in intersection observations. r=emilio,layout-reviewers" for causing mochitest failures @ test_intersectionobserver_popup.xhtml

Authored by https://github.com/Welpy-cw
https://github.com/mozilla/enterprise-firefox/commit/09284977af1bf2ecb3db36b8d6d5fd2d6fc2bb9a
[enterprise-main] Bug 2084270 - Stop applying ancestor clips outside popups in intersection observations. r=emilio,layout-reviewers

Authored by https://github.com/smolnar-sheriff
https://github.com/mozilla/enterprise-firefox/commit/d9098b3e11c2fbc2b2d84e53a3c784814cbdab3e
[enterprise-main] Revert "Bug 2084270 - Stop applying ancestor clips outside popups in intersection observations. r=emilio,layout-reviewers" for causing mochitest failures @ test_intersectionobserver_popup.xhtml

(via GitHub webhook, authenticated as shared-secret)

Status: ASSIGNED → RESOLVED
Closed: 2 days ago
Resolution: --- → FIXED

This seems wrong, the patch got backed out... Flo do you know who knows about this automation with enterprise? It shouldn't have closed the bug.

Status: RESOLVED → REOPENED
Flags: needinfo?(fmerz)
Resolution: FIXED → ---
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: