Skip to content

Preserve watchElementForClose state across bfcache#129

Open
nikrom17 wants to merge 5 commits intomainfrom
feature/bfcache
Open

Preserve watchElementForClose state across bfcache#129
nikrom17 wants to merge 5 commits intomainfrom
feature/bfcache

Conversation

@nikrom17
Copy link
Member

Summary

Add event.persisted guard to the sacrificial iframe's pagehide listener in watchElementForClose, preventing false-positive element close detection when the page enters bfcache.

Problem

watchElementForClose uses a sacrificial iframe to detect when a DOM element is removed. The iframe listens for pagehide (or unload in legacy browsers) as one of its detection strategies. When a page
enters bfcache, the sacrificial iframe's pagehide fires with event.persisted = true, triggering elementClosed() even though the element is still in the DOM. This causes a frozen promise that resumes on
bfcache restore, leading to unnecessary cleanup or re-render in consumers like zoid.

Fix

Wrap the sacrificial iframe's termination event listener in a new elementClosedOnTermination function that checks event.persisted before calling elementClosed():

  • When terminationEvent === "pagehide" and event.persisted === true → skip (page entering bfcache, element is not actually removed)
  • Otherwise → call elementClosed() as before (real navigation or legacy unload)

Only the sacrificial iframe listener is affected. The MutationObserver and polling strategies continue to use elementClosed directly.

Changes

src/dom.jswatchElementForClose:

  • Add elementClosedOnTermination wrapper with event.persisted guard
  • Update addEventListener (Strategy 2) to use elementClosedOnTermination
  • Update removeEventListener in cancel() to match

Test plan

  • bfcache: navigate away → back button → watchElementForClose does NOT fire (sacrificial iframe pagehide is skipped)
  • Real navigation: watchElementForClose fires normally, element close is detected
  • DOM removal: MutationObserver and poller strategies still detect element removal
  • Legacy browsers: unload event (no persisted property) — guard is skipped, elementClosed fires normally

@nikrom17 nikrom17 requested a review from a team as a code owner February 20, 2026 15:33
@nikrom17 nikrom17 changed the title Update zoid behvaior to support bfcache Preserve watchElementForClose state across bfcache Feb 20, 2026
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.

1 participant