fix(trace): capture attribute mutations after a popup document swap#41086
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| ensureCachedData(mutation.target).attributesCached = undefined; | ||
| } | ||
|
|
||
| private _ensureObservingCurrentDocument() { |
There was a problem hiding this comment.
Hmm... We already have a mechanism that tries to achieve this in _refreshListenersWhenNeeded(). Is it wrong? Should we update both? Should we unify both?
There was a problem hiding this comment.
Good catch — they target different failure modes, so I unified them rather than leaving two parallel detectors.
_refreshListenersWhenNeeded() recovers the target-marking listeners across a documentElement replacement within the same document object — its childList observer stays valid because the document node is unchanged. It cannot handle a full document-object swap (a popup's initial about:blank being replaced by the navigated document while the window is reused), because both that childList observer and the main attribute observer were bound to the now-discarded document.
So I made the capture-time swap check the single entry point: the constructor now goes through _ensureObservingCurrentDocument() too, and on a swap it re-binds the attribute observer and re-runs _refreshListenersWhenNeeded(), which re-arms the documentElement watcher on the live document. The existing watcher couldn't self-recover from a swap since it relied on an observer bound to the swapped-away document.
A popup reuses its initial about:blank document, so the snapshotter's MutationObserver could stay bound to the stale document after navigation and never report attribute mutations (e.g. a hiding CSS class added via classList.add/setAttribute) for the live one. Re-bind the observer to the current document before each capture. Fixes: microsoft#40895
Route both the constructor setup and the capture-time re-binding through _ensureObservingCurrentDocument(), and on a document swap re-run _refreshListenersWhenNeeded() so the documentElement watcher is re-armed on the live document too. The existing watcher cannot recover on its own because it relies on a MutationObserver bound to the swapped-away document.
Test results for "MCP"7230 passed, 1103 skipped Merge workflow run. |
Test results for "tests 1"39523 passed, 775 skipped Merge workflow run. |
Summary
about:blankdocument; after it navigates, the snapshotter'sMutationObserverstayed bound to the stale document and never reported attribute mutations (e.g. a hiding CSS class added viaclassList.add/setAttribute), so DOM snapshots showed stale attributes.Fixes #40895