Skip to content

LibWeb: Unload content documents when a navigable container is removed - #10890

Open
sideshowbarker wants to merge 1 commit into
LadybirdBrowser:masterfrom
sideshowbarker:iframe-removal-visibility
Open

LibWeb: Unload content documents when a navigable container is removed#10890
sideshowbarker wants to merge 1 commit into
LadybirdBrowser:masterfrom
sideshowbarker:iframe-removal-visibility

Conversation

@sideshowbarker

@sideshowbarker sideshowbarker commented Jul 27, 2026

Copy link
Copy Markdown
Member

Make our implementation of the HTML spec’s “destroy a child navigable” unload the content document and descendants — not just destroy them. That ensures each completed-loading page gets pagehide, visibility state set to “hidden” (firing visibilitychange), and unload — in that order. That matches Gecko, WebKit, and Blink. Also, run the unload algorithm’s visibility state update for pages that are ready for post-load tasks — rather than only for “page showing” ones. Thus, the never-navigated initial about:blank documents of child navigables — which engines treat as completely loaded — also become hidden, and fire visibilitychange. Fixes #9893.

whatwg/html#12288 has already been raised to report the misalignment between the spec as currently written and the actual Gecko/WebKit/Blink behavior.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 16e90c27-285c-4c31-bc1d-85cced831de6

📥 Commits

Reviewing files that changed from the base of the PR and between f2ac9fa and dbd9079.

📒 Files selected for processing (1)
  • Libraries/LibWeb/DOM/Document.cpp
🚧 Files skipped from review as they are similar to previous changes (1)
  • Libraries/LibWeb/DOM/Document.cpp

📝 Walkthrough

Walkthrough

Iframe removal now unloads active child documents and descendants before cleanup. Ready documents become hidden, including documents that were not page-showing. Tests cover lifecycle event ordering, nested iframes, and view-transition rejection.

Sequence Diagram(s)

sequenceDiagram
  participant IframeTest
  participant NavigableContainer
  participant ChildDocument
  IframeTest->>NavigableContainer: remove iframe
  NavigableContainer->>ChildDocument: unload document and descendants
  ChildDocument-->>IframeTest: pagehide, visibilitychange, unload
  IframeTest->>ChildDocument: assert visibilityState is hidden
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The description directly explains the unload, visibility, and lifecycle event changes implemented by this pull request.
Linked Issues check ✅ Passed The changes address issue #9893 by unloading removed child documents and descendants and setting their visibility state to hidden.
Out of Scope Changes check ✅ Passed The implementation and added tests directly support the linked issue and stated unload and visibility objectives.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@Tests/LibWeb/Text/input/HTML/view-transition-in-removed-iframe-is-skipped.html`:
- Around line 11-14: Replace the fixed 50 ms sleep in the iframe removal test
with event-driven synchronization: install a visibilitychange listener on
childDocument before iframe.remove(), remove the iframe, and await the event
until childDocument.visibilityState is hidden. Preserve the subsequent
visibility logging and startViewTransition assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4b48864e-94c8-40f1-a3e5-c6e1d1db9d47

📥 Commits

Reviewing files that changed from the base of the PR and between 8262e85 and 7b900b9.

📒 Files selected for processing (10)
  • Libraries/LibWeb/DOM/Document.cpp
  • Libraries/LibWeb/HTML/NavigableContainer.cpp
  • Tests/LibWeb/TestConfig.ini
  • Tests/LibWeb/Text/expected/HTML/iframe-removal-sets-visibility-state-hidden.txt
  • Tests/LibWeb/Text/expected/HTML/view-transition-in-removed-iframe-is-skipped.txt
  • Tests/LibWeb/Text/expected/wpt-import/page-visibility/iframe-unload.txt
  • Tests/LibWeb/Text/input/HTML/iframe-removal-sets-visibility-state-hidden.html
  • Tests/LibWeb/Text/input/HTML/view-transition-in-removed-iframe-is-skipped.html
  • Tests/LibWeb/Text/input/wpt-import/page-visibility/iframe-unload.html
  • Tests/LibWeb/Text/input/wpt-import/page-visibility/resources/iframe-with-subframes.html

@sideshowbarker
sideshowbarker force-pushed the iframe-removal-visibility branch from 7b900b9 to 89c0640 Compare July 27, 2026 12:17
@sideshowbarker
sideshowbarker force-pushed the iframe-removal-visibility branch from 89c0640 to 0be384f Compare August 5, 2026 07:45
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@github-actions github-actions Bot added the conflicts Pull request has merge conflicts that need resolution label Aug 9, 2026
@sideshowbarker
sideshowbarker force-pushed the iframe-removal-visibility branch from 0be384f to f2ac9fa Compare August 9, 2026 22:22
@LadybirdBrowser LadybirdBrowser deleted a comment from github-actions Bot Aug 9, 2026
@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@github-actions github-actions Bot removed the conflicts Pull request has merge conflicts that need resolution label Aug 9, 2026
Make our implementation of the HTML spec’s “destroy a child navigable”
*unload* the content document and descendants — not just destroy them.
That ensures each completed-loading page gets pagehide, visibility state
set to “hidden” (firing visibilitychange), and unload — in that order.
That matches Gecko, WebKit, and Blink. Also, run the unload algorithm’s
visibility state update for pages that are ready for post-load tasks –
rather than only for “page showing” ones. Thus, the never-navigated
initial about:blank documents of child navigables — which engines treat
as completely loaded — also become hidden, and fire visibilitychange.

Fixes LadybirdBrowser#9893
@sideshowbarker
sideshowbarker force-pushed the iframe-removal-visibility branch from f2ac9fa to dbd9079 Compare August 10, 2026 15:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Removing iframe does not set visibility state to hidden

1 participant