Yeah, so the real issue here seems to be that we're firing pagehide *before* pageshow (because we redirect during onload, due to the sync XHR which synchronously spins the event loop). In testcases that trigger the assertion failure, here's what happens: (1) onload fires for the initial document (from nsDocumentViewer::LoadComplete), which triggers JS that does a redirect + then spins the event loop via sync XHR. (2) During the event-loop-spin, we start honoring the redirect, which makes us call nsDocShell::CreateContentViewer, which calls FirePageHideNotification for the old document. **This fires pagehide for the first doc. Note that we have not yet fired pageshow.** (3) When we pop back up the stack to nsDocumentViewer::LoadComplete, we now fire pageshow for the already-replaced document. So we end up with a soon-to-be-destroyed document that thinks it's visible, which causes the fatal assertion failure reported here, along with these ones afterwards if I let us get past that one: ###!!! ASSERTION: Destroying a currently-showing document: '!mIsShowing', file dom/base/Document.cpp, line 1398 ###!!! ASSERTION: Expecting to be paused for pagehide before disconnect: 'mPauseState & SMILTimeContainer::PAUSE_PAGEHIDE', file dom/smil/SMILAnimationController.cpp, line 69
Bug 1535388 Comment 20 Edit History
Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.
Yeah, so the real issue here seems to be that we're firing pagehide *before* pageshow (because we redirect during onload, due to the sync XHR which synchronously spins the event loop). In testcases that trigger the assertion failure, here's what happens: (1) onload fires for the initial document (from nsDocumentViewer::LoadComplete), which triggers JS that does a redirect + then spins the event loop via sync XHR. (2) During the event-loop-spin, we start honoring the redirect, which makes us call nsDocShell::CreateContentViewer, which calls FirePageHideNotification for the old document. **This fires `pagehide` for the first doc. Note that we have not yet fired `pageshow` for that document!.** (3) When we pop back up the stack to nsDocumentViewer::LoadComplete, we now fire pageshow for the already-replaced document. So we end up with a soon-to-be-destroyed document that thinks it's visible, which causes the fatal assertion failure reported here, along with these ones afterwards if I let us get past that one: ###!!! ASSERTION: Destroying a currently-showing document: '!mIsShowing', file dom/base/Document.cpp, line 1398 ###!!! ASSERTION: Expecting to be paused for pagehide before disconnect: 'mPauseState & SMILTimeContainer::PAUSE_PAGEHIDE', file dom/smil/SMILAnimationController.cpp, line 69
Yeah, so the real issue here seems to be that we're firing pagehide *before* pageshow (because we redirect during onload, due to the sync XHR which synchronously spins the event loop). In testcases that trigger the assertion failure, here's what happens: (1) onload fires for the initial document (from nsDocumentViewer::LoadComplete), which triggers JS that does a redirect + then spins the event loop via sync XHR. (2) During the event-loop-spin, we start honoring the redirect, which makes us call nsDocShell::CreateContentViewer, which calls FirePageHideNotification for the old document. **This fires `pagehide` for the first doc. Note that we have not yet fired `pageshow` for that document!.** (3) When we pop back up the stack to nsDocumentViewer::LoadComplete, we now fire `pageshow` for the already-replaced document. So we end up with a soon-to-be-destroyed document that thinks it's visible, which causes the fatal assertion failure reported here, along with these ones afterwards if I let us get past that one: `###!!! ASSERTION: Destroying a currently-showing document: '!mIsShowing', file dom/base/Document.cpp, line 1398` `###!!! ASSERTION: Expecting to be paused for pagehide before disconnect: 'mPauseState & SMILTimeContainer::PAUSE_PAGEHIDE', file dom/smil/SMILAnimationController.cpp, line 69`
Yeah, so the real issue here seems to be that we're firing pagehide *before* pageshow (because we redirect during onload, due to the sync XHR which synchronously spins the event loop). In testcases that trigger the assertion failure, here's what happens: (1) onload fires for the initial document (from nsDocumentViewer::LoadComplete), which triggers JS that does a redirect + then spins the event loop via sync XHR. (2) During the event-loop-spin, we start honoring the redirect, which makes us call `nsDocShell::CreateContentViewer`, which calls `FirePageHideNotification` for the old document. **This fires `pagehide` for the first doc. Note that we have not yet fired `pageshow` for that document!** (3) When we pop back up the stack to nsDocumentViewer::LoadComplete, we now fire `pageshow` for the already-replaced document. So we end up with a soon-to-be-destroyed document that thinks it's visible, which causes the fatal assertion failure reported here, along with these ones afterwards if I let us get past that one: `###!!! ASSERTION: Destroying a currently-showing document: '!mIsShowing', file dom/base/Document.cpp, line 1398` `###!!! ASSERTION: Expecting to be paused for pagehide before disconnect: 'mPauseState & SMILTimeContainer::PAUSE_PAGEHIDE', file dom/smil/SMILAnimationController.cpp, line 69`