REGRESSION(r214194): Safari leaves a popup window open opened during before unload
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 30 Jun 2017 19:32:41 +0000 (19:32 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 30 Jun 2017 19:32:41 +0000 (19:32 +0000)
commitf489f8f90677a80b4b20ffa049eedad9c60133d9
treec53bc01ba3916d6c4c61be13eba467fc439c8fe0
parentaa89522a1396eed7871d66a52884f18dbd2a4d11
REGRESSION(r214194): Safari leaves a popup window open opened during before unload
https://bugs.webkit.org/show_bug.cgi?id=174016

Reviewed by Chris Dumez.

Source/WebCore:

The bug was caused by WebKit allowing the opening of a new window via window.open but disallowing
the initial navigation within the newly opened window while a beforeunload event is being dispatched.

Because some websites which opens a window during a beforeunload event relies on the opened page
to communicate back in order to close it. This resulted in a newly opened popup window with about:blank
being left out on those websites.

Fixed the bug by allowing the navigation of a new window as well as an existing another window.
More concretely, we disallow navigations within the same frame tree as the one in which a beforeunload
event is being dispatched, and allow navigations elsewhere (i.e. different window / page).
During the destruction of a frame-less document, disallow all the navigations.

Tests: fast/events/before-unload-navigate-different-window.html
       fast/events/before-unload-open-window.html
       fast/events/before-unload-sibling-frame.html

* WebCore.xcodeproj/project.pbxproj:
* dom/Document.cpp:
(WebCore::Document::prepareForDestruction):
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::isNavigationAllowed):
(WebCore::FrameLoader::shouldClose):
* loader/NavigationDisabler.h: Added. Extracted from NavigationScheduler.h
(WebCore::NavigationDisabler::NavigationDisabler): Increment the newly added counter on MainFrame unless
the frame is null (during the destruction of a frameless document) in which case we increment the global
disable count.
(WebCore::NavigationDisabler::~NavigationDisabler): Ditto for decrementation.
(WebCore::NavigationDisabler::isNavigationAllowed): Only allow the navigation when there is no frameless
document in destruction, and none of the frame in the same frame tree as the one given is currently in
the process of dispatching a beforeunload event.
* loader/NavigationScheduler.cpp:
(WebCore::NavigationScheduler::shouldScheduleNavigation):
* loader/NavigationScheduler.h:
(WebCore::NavigationDisabler): Moved to NavigationDisabler.h.
* page/MainFrame.h:
(WebCore::MainFrame): Added s_globalNavigationDisableCount.

LayoutTests:

Added regression tests for navigating a new window, a sibling iframe, and another existing window.

* fast/events/before-unload-navigate-different-window-expected.txt: Added.
* fast/events/before-unload-navigate-different-window.html: Added.
* fast/events/before-unload-open-window-expected.txt: Added.
* fast/events/before-unload-open-window.html: Added.
* fast/events/before-unload-sibling-frame-expected.txt: Added.
* fast/events/before-unload-sibling-frame.html: Added.
* fast/events/resources/message-opener.html: Added.
* fast/events/resources/message-top.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@219008 268f45cc-cd09-0410-ab3c-d52691b4dbfc
17 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/events/before-unload-navigate-different-window-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/before-unload-navigate-different-window.html [new file with mode: 0644]
LayoutTests/fast/events/before-unload-open-window-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/before-unload-open-window.html [new file with mode: 0644]
LayoutTests/fast/events/before-unload-sibling-frame-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/before-unload-sibling-frame.html [new file with mode: 0644]
LayoutTests/fast/events/resources/message-opener.html [new file with mode: 0644]
LayoutTests/fast/events/resources/message-top.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/dom/Document.cpp
Source/WebCore/loader/FrameLoader.cpp
Source/WebCore/loader/NavigationDisabler.h [new file with mode: 0644]
Source/WebCore/loader/NavigationScheduler.cpp
Source/WebCore/loader/NavigationScheduler.h
Source/WebCore/page/MainFrame.h