← Back to release summary

Deprecate and stop firing events during subframe removal

Category
DOM
Type
Feature removal
Status
In developer trial (Behind a flag) (Chrome In developer trial (Behind a flag))
Intent stage
Origin Trial

WPT details: Blink web tests in fast/frames/subframe-detachment-events-on-removal.html (covering same-origin, cross-origin/opaque, sandboxed with/without allow-same-origin, and A1->B->A2 cross-origin sandwich removals).

Summary

Stop synchronously firing pagehide, visibilitychange, and unload events when a subframe that has script access to an ancestor frame's DOM is removed from the DOM. Per the HTML Standard, destroying a child navigable on DOM removal does not fire these events, and firing them synchronously enables ancestor DOM re-entrancy during node removal.

Motivation

When an <iframe> (or frame-hosting <object>/<embed>) is removed from the DOM, Blink historically dispatched pagehide, visibilitychange, and unload synchronously during ContainerNode::RemoveChild / Node::RemovedFrom. The HTML Standard's 'destroy a child navigable' algorithm does not fire unload or pagehide events on DOM removal. Firing these events synchronously during node removal allows script in a subframe that can access an ancestor LocalFrame's DOM (SecurityOrigin::CanAccess) to re-enter and mutate the ancestor DOM mid-removal, leading to crashes and inconsistent DOM state. Under OmitSubframeDetachmentEventsOnRemoval, subframes that can script an ancestor LocalFrame silently clean up on DOM removal without synchronously firing pagehide, visibilitychange, or unload.

Standards & signals

Ecosystem

Explainers: https://github.com/whatwg/html/issues/10194 https://gist.github.com/noamr/f80676a616444de7efb5be671692e919

View on chromestatus.com