You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
useTypingObserver: capture the window reference for cleanup (#78772)
* useTypingObserver: guard against null defaultView during cleanup
When the block editor is hosted inside an iframe, React can fire the
useRefEffect cleanup after the iframe document has been detached from
its window. At that point document.defaultView === null, so the
unguarded `node.ownerDocument.defaultView.clearTimeout( timerId )`
inside the cleanup throws, which also aborts the removeEventListener
calls that follow it (leaking those listeners on the unmounting node).
Optional-chain the defaultView access in the cleanup, plus the matching
setTimeout in stopTypingOnNonTextField and getSelection in
stopTypingOnSelectionUncollapse, so the hook never assumes the iframe's
window is still attached.
* useTypingObserver: add regression test for null defaultView cleanup
Mounts the hook in the isTyping state so the cleanup branch that touches
`defaultView` is reached, overrides `ownerDocument.defaultView` to null
to simulate the iframe being detached from its window, then unmounts.
Asserts both that the cleanup does not throw and that the
`selectionchange`, `focus`, and `keydown` listeners are still removed in
that scenario — the leak path the original throw was masking.
* Re-trigger CI (unrelated flake in CustomSelectControl test)
* Remove null-defaultView cleanup test.
The test mocked an internal edge case (manually nulling `ownerDocument.defaultView`) that doesn't correspond to a reachable real-world state, so it asserted against a synthetic condition rather than observable behavior.
* Use top-level timers so cleanup survives a detached frame.
The cleanup function called `node.ownerDocument.defaultView.clearTimeout()`. When the editor canvas iframe is detached from its window before React runs the ref cleanup, `defaultView` is `null` and the access throws, aborting the rest of the cleanup and leaking the `focus`, `keydown`, and `selectionchange` listeners.
The typing timer never needed the iframe's window in the first place, so set and clear it on the top-level `setTimeout`/`clearTimeout` instead. The timer id stays valid regardless of the frame's state, and the cleanup no longer touches `defaultView`.
* Update CHANGELOG
* Fix comment
* Re-trigger CI (flaky @swc native binding load in Storybook smoke tests)
---------
Co-authored-by: Xavier Lozano Carreras <xavier.lozano.carreras@a8c.com>
Co-authored-by: Jarda Snajdr <jsnajdr@gmail.com>
Copy file name to clipboardExpand all lines: packages/block-editor/CHANGELOG.md
+5-1Lines changed: 5 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,10 +2,14 @@
2
2
3
3
## Unreleased
4
4
5
+
### Bug Fixes
6
+
7
+
-`useTypingObserver`: Capture the window reference at mount and reuse it during cleanup so the ref cleanup no longer reads `node.ownerDocument.defaultView` (which is `null` once the iframe-hosted editor has been detached from its window) and throws, which was also leaking the `removeEventListener` calls that follow it ([#78772](https://github.com/WordPress/gutenberg/pull/78772)).
8
+
5
9
### Breaking Changes
6
10
7
11
- The `__next40pxDefaultSize` prop is now true by default. The prop can be safely removed from the following:
0 commit comments