WebKit policy delegate should suggest if a navigation should be allowed to open URLs...
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 2 Jun 2015 18:43:13 +0000 (18:43 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 2 Jun 2015 18:43:13 +0000 (18:43 +0000)
rdar://problem/21025301 and https://bugs.webkit.org/show_bug.cgi?id=145280
Source/WebCore:

Reviewed by Alex Christensen.

Tests: loader/navigation-policy/should-open-external-urls/main-frame-click.html
       loader/navigation-policy/should-open-external-urls/main-frame-navigated-programatically-by-subframe.html
       loader/navigation-policy/should-open-external-urls/main-frame-with-flag-progamatic.html
       loader/navigation-policy/should-open-external-urls/main-frame-without-flag-programatic.html
       loader/navigation-policy/should-open-external-urls/subframe-click-target-self.html
       loader/navigation-policy/should-open-external-urls/subframe-click-target-top.html
       loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag-from-subframe.html
       loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag.html
       loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag-from-subframe.html
       loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag.html
       loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag-from-subframe.html
       loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag.html
       loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag-from-subframe.html
       loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag.html
       loader/navigation-policy/should-open-external-urls/window-open-with-flag-from-subframe.html
       loader/navigation-policy/should-open-external-urls/window-open-with-flag.html
       loader/navigation-policy/should-open-external-urls/window-open-without-flag-from-subframe.html
       loader/navigation-policy/should-open-external-urls/window-open-without-flag.html

The "should open external URLs" flag is only for main frames.
It doesn't enforce any sort of policy internal to WebKit, but rather is for notifications to the policy delegate.

It is set from one of two places:
1 - A main frame is navigated by any frame as the result of a user gesture.
2 - WebKit2 API explicitly states the flag is true.

The flag value propagates when:
1 - When a main frame document is navigated to a new main frame document.
2 - When a new window is opened from a page whose main frame had the flag set.
3 - When a new window is opened as the result of a user gesture.

The flag resets to false when:
1 - A subframe navigates a main frame without a user gesture.

This patch is large, but does little more than the following:
1 - Adds a ShouldOpenExternalURLs flag to both FrameLoadRequest and NavigationAction.
2 - Makes sure anybody who creates either of those objects sets a sensible for that flag.
3 - When FrameLoader creates a new DocumentLoader, it sets its flag based on whether or not the load is in a main frame,
    whether or not the load is from a user gesture, and based on the initiator's value of the flag.

* dom/Document.cpp:
(WebCore::Document::processHttpEquiv):
(WebCore::Document::shouldOpenExternalURLsPolicyToPropagate):
* dom/Document.h:

* html/HTMLAnchorElement.cpp:
(WebCore::HTMLAnchorElement::handleClick):

* html/HTMLLinkElement.cpp:
(WebCore::HTMLLinkElement::handleClick):

* html/parser/XSSAuditorDelegate.cpp:
(WebCore::XSSAuditorDelegate::didBlockScript):

* inspector/InspectorFrontendClientLocal.cpp:
(WebCore::InspectorFrontendClientLocal::openInNewTab):

* inspector/InspectorPageAgent.cpp:
(WebCore::InspectorPageAgent::navigate):

* loader/DocumentLoader.cpp:
(WebCore::DocumentLoader::setTriggeringAction):
(WebCore::DocumentLoader::shouldOpenExternalURLsPolicyToPropagate):
* loader/DocumentLoader.h:
(WebCore::DocumentLoader::shouldOpenExternalURLsPolicy): Deleted.

* loader/FrameLoadRequest.cpp:
(WebCore::FrameLoadRequest::FrameLoadRequest):
* loader/FrameLoadRequest.h:
(WebCore::FrameLoadRequest::FrameLoadRequest):

* loader/FrameLoader.cpp:
(WebCore::FrameLoader::urlSelected):
(WebCore::FrameLoader::receivedFirstData):
(WebCore::FrameLoader::loadURLIntoChildFrame):
(WebCore::FrameLoader::loadURL):
(WebCore::FrameLoader::load):
(WebCore::FrameLoader::loadWithNavigationAction):
(WebCore::FrameLoader::reloadWithOverrideEncoding):
(WebCore::FrameLoader::reload):
(WebCore::FrameLoader::loadPostRequest):
(WebCore::FrameLoader::continueLoadAfterNewWindowPolicy):
(WebCore::FrameLoader::applyShouldOpenExternalURLsPolicyToNewDocumentLoader):
* loader/FrameLoader.h:

* loader/NavigationAction.cpp:
(WebCore::NavigationAction::NavigationAction):
(WebCore::NavigationAction::copyWithShouldOpenExternalURLsPolicy):
* loader/NavigationAction.h:
(WebCore::NavigationAction::setShouldOpenExternalURLsPolicy): Deleted.

* loader/NavigationScheduler.cpp:
(WebCore::ScheduledURLNavigation::ScheduledURLNavigation):
(WebCore::ScheduledRedirect::ScheduledRedirect):
(WebCore::ScheduledLocationChange::ScheduledLocationChange):
(WebCore::ScheduledRefresh::ScheduledRefresh):
(WebCore::ScheduledFormSubmission::ScheduledFormSubmission):
(WebCore::NavigationScheduler::scheduleRedirect):
(WebCore::NavigationScheduler::scheduleLocationChange):
(WebCore::NavigationScheduler::scheduleRefresh):
* loader/NavigationScheduler.h:

* loader/PolicyChecker.cpp:
(WebCore::PolicyChecker::checkNavigationPolicy):

* loader/SubframeLoader.cpp:
(WebCore::SubframeLoader::loadOrRedirectSubframe):

* loader/appcache/ApplicationCacheGroup.cpp:
(WebCore::ApplicationCacheGroup::selectCache):

* page/ContextMenuController.cpp:
(WebCore::openNewWindow):
(WebCore::ContextMenuController::contextMenuItemSelected):

* page/DOMWindow.cpp:
(WebCore::DOMWindow::setLocation):
(WebCore::DOMWindow::createWindow):
(WebCore::DOMWindow::open):

* page/DragController.cpp:
(WebCore::DragController::performDragOperation):

* page/Location.cpp:
(WebCore::Location::reload):

* replay/ReplayInputDispatchMethods.cpp:
(WebCore::InitialNavigation::dispatch):

* svg/SVGAElement.cpp:
(WebCore::SVGAElement::defaultEventHandler):

Source/WebKit/ios:

Reviewed by Alex Christensen.

* WebView/WebPDFViewPlaceholder.mm:
(-[WebPDFViewPlaceholder simulateClickOnLinkToURL:]):

Source/WebKit/mac:

Reviewed by Alex Christensen.

* Plugins/WebPluginController.mm:
(-[WebPluginController webPlugInContainerLoadRequest:inFrame:]):

* WebView/WebFrame.mm:
(-[WebFrame loadRequest:]):
(-[WebFrame _loadData:MIMEType:textEncodingName:baseURL:unreachableURL:]):

* WebView/WebPDFView.mm:
(-[WebPDFView PDFViewWillClickOnLink:withURL:]):

Source/WebKit/win:

Reviewed by Alex Christensen.

* Plugins/PluginView.cpp:
(WebCore::PluginView::start):
(WebCore::PluginView::performRequest):
(WebCore::PluginView::getURLNotify):
(WebCore::PluginView::getURL):
(WebCore::PluginView::handlePost):

* WebCoreSupport/WebContextMenuClient.cpp:
(WebContextMenuClient::searchWithGoogle):

* WebFrame.cpp:
(WebFrame::loadRequest):
(WebFrame::loadData):

Source/WebKit2:

Reviewed by Alex Christensen.

* WebProcess/Plugins/PDF/PDFPlugin.mm:
(WebKit::PDFPlugin::clickedLink):

* WebProcess/Plugins/PluginView.cpp:
(WebKit::PluginView::performFrameLoadURLRequest):
(WebKit::PluginView::loadURL):

* WebProcess/WebCoreSupport/WebContextMenuClient.cpp:
(WebKit::WebContextMenuClient::searchWithGoogle):

* WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
(WebKit::WebFrameLoaderClient::dispatchCreatePage):

* WebProcess/WebPage/WebInspector.cpp:
(WebKit::WebInspector::openInNewTab):

* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::loadURLInFrame):
(WebKit::WebPage::loadRequest):
(WebKit::WebPage::loadDataImpl):
(WebKit::WebPage::navigateToPDFLinkWithSimulatedClick):

LayoutTests:

Reviewed by Alex Christensen.

* loader/navigation-policy/should-open-external-urls/main-frame-click-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/main-frame-click.html: Added.
* loader/navigation-policy/should-open-external-urls/main-frame-navigated-programatically-by-subframe-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/main-frame-navigated-programatically-by-subframe.html: Added.
* loader/navigation-policy/should-open-external-urls/main-frame-with-flag-progamatic-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/main-frame-with-flag-progamatic.html: Added.
* loader/navigation-policy/should-open-external-urls/main-frame-without-flag-programatic-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/main-frame-without-flag-programatic.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/click-notify-done-in-main.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/iframe-click-notify-done-target-self.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/iframe-click-notify-done-target-top.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/main-frame-with-subframe-click-targets-subframe.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/main-frame-with-subframe-programatically-navigates-main.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/programatically-navigate-to-notify-done-target-top.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/programatically-navigate-to-notify-done.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/user-gesture-target-blank-to-notify-done-from-subframe.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/user-gesture-target-blank-to-notify-done.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/user-gesture-window-open-to-notify-done-from-subframe.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/user-gesture-window-open-to-notify-done.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/window-open-to-notify-done-from-subframe.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/window-open-to-notify-done.html: Added.
* loader/navigation-policy/should-open-external-urls/subframe-click-target-self-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/subframe-click-target-self.html: Added.
* loader/navigation-policy/should-open-external-urls/subframe-click-target-top-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/subframe-click-target-top.html: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag-from-subframe-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag-from-subframe.html: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag.html: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag-from-subframe-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag-from-subframe.html: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag.html: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag-from-subframe-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag-from-subframe.html: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag.html: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag-from-subframe-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag-from-subframe.html: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag.html: Added.
* loader/navigation-policy/should-open-external-urls/window-open-with-flag-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/window-open-with-flag-from-subframe-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/window-open-with-flag-from-subframe.html: Added.
* loader/navigation-policy/should-open-external-urls/window-open-with-flag.html: Added.
* loader/navigation-policy/should-open-external-urls/window-open-without-flag-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/window-open-without-flag-from-subframe-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/window-open-without-flag-from-subframe.html: Added.
* loader/navigation-policy/should-open-external-urls/window-open-without-flag.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@185111 268f45cc-cd09-0410-ab3c-d52691b4dbfc

94 files changed:
LayoutTests/ChangeLog
LayoutTests/loader/navigation-policy/should-open-external-urls/main-frame-click-expected.txt [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/main-frame-click.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/main-frame-navigated-programatically-by-subframe-expected.txt [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/main-frame-navigated-programatically-by-subframe.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/main-frame-with-flag-progamatic-expected.txt [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/main-frame-with-flag-progamatic.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/main-frame-without-flag-programatic-expected.txt [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/main-frame-without-flag-programatic.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/resources/click-notify-done-in-main.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/resources/iframe-click-notify-done-target-self.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/resources/iframe-click-notify-done-target-top.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/resources/main-frame-with-subframe-click-targets-subframe.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/resources/main-frame-with-subframe-programatically-navigates-main.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/resources/programatically-navigate-to-notify-done-target-top.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/resources/programatically-navigate-to-notify-done.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/resources/user-gesture-target-blank-to-notify-done-from-subframe.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/resources/user-gesture-target-blank-to-notify-done.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/resources/user-gesture-window-open-to-notify-done-from-subframe.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/resources/user-gesture-window-open-to-notify-done.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/resources/window-open-to-notify-done-from-subframe.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/resources/window-open-to-notify-done.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/subframe-click-target-self-expected.txt [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/subframe-click-target-self.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/subframe-click-target-top-expected.txt [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/subframe-click-target-top.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag-expected.txt [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag-from-subframe-expected.txt [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag-from-subframe.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag-expected.txt [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag-from-subframe-expected.txt [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag-from-subframe.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag-expected.txt [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag-from-subframe-expected.txt [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag-from-subframe.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag-expected.txt [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag-from-subframe-expected.txt [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag-from-subframe.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/window-open-with-flag-expected.txt [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/window-open-with-flag-from-subframe-expected.txt [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/window-open-with-flag-from-subframe.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/window-open-with-flag.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/window-open-without-flag-expected.txt [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/window-open-without-flag-from-subframe-expected.txt [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/window-open-without-flag-from-subframe.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/window-open-without-flag.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/html/HTMLAnchorElement.cpp
Source/WebCore/html/HTMLLinkElement.cpp
Source/WebCore/html/parser/XSSAuditorDelegate.cpp
Source/WebCore/inspector/InspectorFrontendClientLocal.cpp
Source/WebCore/inspector/InspectorPageAgent.cpp
Source/WebCore/loader/DocumentLoader.cpp
Source/WebCore/loader/DocumentLoader.h
Source/WebCore/loader/FrameLoadRequest.cpp
Source/WebCore/loader/FrameLoadRequest.h
Source/WebCore/loader/FrameLoader.cpp
Source/WebCore/loader/FrameLoader.h
Source/WebCore/loader/NavigationAction.cpp
Source/WebCore/loader/NavigationAction.h
Source/WebCore/loader/NavigationScheduler.cpp
Source/WebCore/loader/NavigationScheduler.h
Source/WebCore/loader/PolicyChecker.cpp
Source/WebCore/loader/SubframeLoader.cpp
Source/WebCore/loader/appcache/ApplicationCacheGroup.cpp
Source/WebCore/page/ContextMenuController.cpp
Source/WebCore/page/DOMWindow.cpp
Source/WebCore/page/DragController.cpp
Source/WebCore/page/Location.cpp
Source/WebCore/replay/ReplayInputDispatchMethods.cpp
Source/WebCore/svg/SVGAElement.cpp
Source/WebKit/ios/ChangeLog
Source/WebKit/ios/WebView/WebPDFViewPlaceholder.mm
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/Plugins/WebPluginController.mm
Source/WebKit/mac/WebView/WebFrame.mm
Source/WebKit/mac/WebView/WebPDFView.mm
Source/WebKit/win/ChangeLog
Source/WebKit/win/Plugins/PluginView.cpp
Source/WebKit/win/WebCoreSupport/WebContextMenuClient.cpp
Source/WebKit/win/WebFrame.cpp
Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.mm
Source/WebKit2/WebProcess/Plugins/PluginView.cpp
Source/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.cpp
Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
Source/WebKit2/WebProcess/WebPage/WebInspector.cpp
Source/WebKit2/WebProcess/WebPage/WebPage.cpp

index e39a176..5b3c792 100644 (file)
@@ -1,3 +1,60 @@
+2015-06-02  Brady Eidson  <beidson@apple.com>
+
+        WebKit policy delegate should suggest if a navigation should be allowed to open URLs externally.
+        rdar://problem/21025301 and https://bugs.webkit.org/show_bug.cgi?id=145280
+
+        Reviewed by Alex Christensen.
+
+        * loader/navigation-policy/should-open-external-urls/main-frame-click-expected.txt: Added.
+        * loader/navigation-policy/should-open-external-urls/main-frame-click.html: Added.
+        * loader/navigation-policy/should-open-external-urls/main-frame-navigated-programatically-by-subframe-expected.txt: Added.
+        * loader/navigation-policy/should-open-external-urls/main-frame-navigated-programatically-by-subframe.html: Added.
+        * loader/navigation-policy/should-open-external-urls/main-frame-with-flag-progamatic-expected.txt: Added.
+        * loader/navigation-policy/should-open-external-urls/main-frame-with-flag-progamatic.html: Added.
+        * loader/navigation-policy/should-open-external-urls/main-frame-without-flag-programatic-expected.txt: Added.
+        * loader/navigation-policy/should-open-external-urls/main-frame-without-flag-programatic.html: Added.
+        * loader/navigation-policy/should-open-external-urls/resources/click-notify-done-in-main.html: Added.
+        * loader/navigation-policy/should-open-external-urls/resources/iframe-click-notify-done-target-self.html: Added.
+        * loader/navigation-policy/should-open-external-urls/resources/iframe-click-notify-done-target-top.html: Added.
+        * loader/navigation-policy/should-open-external-urls/resources/main-frame-with-subframe-click-targets-subframe.html: Added.
+        * loader/navigation-policy/should-open-external-urls/resources/main-frame-with-subframe-programatically-navigates-main.html: Added.
+        * loader/navigation-policy/should-open-external-urls/resources/programatically-navigate-to-notify-done-target-top.html: Added.
+        * loader/navigation-policy/should-open-external-urls/resources/programatically-navigate-to-notify-done.html: Added.
+        * loader/navigation-policy/should-open-external-urls/resources/user-gesture-target-blank-to-notify-done-from-subframe.html: Added.
+        * loader/navigation-policy/should-open-external-urls/resources/user-gesture-target-blank-to-notify-done.html: Added.
+        * loader/navigation-policy/should-open-external-urls/resources/user-gesture-window-open-to-notify-done-from-subframe.html: Added.
+        * loader/navigation-policy/should-open-external-urls/resources/user-gesture-window-open-to-notify-done.html: Added.
+        * loader/navigation-policy/should-open-external-urls/resources/window-open-to-notify-done-from-subframe.html: Added.
+        * loader/navigation-policy/should-open-external-urls/resources/window-open-to-notify-done.html: Added.
+        * loader/navigation-policy/should-open-external-urls/subframe-click-target-self-expected.txt: Added.
+        * loader/navigation-policy/should-open-external-urls/subframe-click-target-self.html: Added.
+        * loader/navigation-policy/should-open-external-urls/subframe-click-target-top-expected.txt: Added.
+        * loader/navigation-policy/should-open-external-urls/subframe-click-target-top.html: Added.
+        * loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag-expected.txt: Added.
+        * loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag-from-subframe-expected.txt: Added.
+        * loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag-from-subframe.html: Added.
+        * loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag.html: Added.
+        * loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag-expected.txt: Added.
+        * loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag-from-subframe-expected.txt: Added.
+        * loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag-from-subframe.html: Added.
+        * loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag.html: Added.
+        * loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag-expected.txt: Added.
+        * loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag-from-subframe-expected.txt: Added.
+        * loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag-from-subframe.html: Added.
+        * loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag.html: Added.
+        * loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag-expected.txt: Added.
+        * loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag-from-subframe-expected.txt: Added.
+        * loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag-from-subframe.html: Added.
+        * loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag.html: Added.
+        * loader/navigation-policy/should-open-external-urls/window-open-with-flag-expected.txt: Added.
+        * loader/navigation-policy/should-open-external-urls/window-open-with-flag-from-subframe-expected.txt: Added.
+        * loader/navigation-policy/should-open-external-urls/window-open-with-flag-from-subframe.html: Added.
+        * loader/navigation-policy/should-open-external-urls/window-open-with-flag.html: Added.
+        * loader/navigation-policy/should-open-external-urls/window-open-without-flag-expected.txt: Added.
+        * loader/navigation-policy/should-open-external-urls/window-open-without-flag-from-subframe-expected.txt: Added.
+        * loader/navigation-policy/should-open-external-urls/window-open-without-flag-from-subframe.html: Added.
+        * loader/navigation-policy/should-open-external-urls/window-open-without-flag.html: Added.
+
 2015-06-01  Myles C. Maxfield  <mmaxfield@apple.com>
 
         [SVG -> OTF Converter] Remove unnecessary hacks
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/main-frame-click-expected.txt b/LayoutTests/loader/navigation-policy/should-open-external-urls/main-frame-click-expected.txt
new file mode 100644 (file)
index 0000000..1aa2ab1
--- /dev/null
@@ -0,0 +1,5 @@
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL resources/click-notify-done-in-main.html, main document URL resources/click-notify-done-in-main.html, http method GET> is main frame - yes should open URLs externally - no
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL notify-done.html, main document URL notify-done.html, http method GET> is main frame - yes should open URLs externally - yes
+
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/main-frame-click.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/main-frame-click.html
new file mode 100644 (file)
index 0000000..60db959
--- /dev/null
@@ -0,0 +1,19 @@
+<script>
+
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpPolicyDelegateCallbacks();
+    testRunner.waitUntilDone();
+}
+
+function runTest()
+{
+    window.location.href = "resources/click-notify-done-in-main.html";
+}
+
+</script>
+<body onload="runTest();">
+This main frame load starts with the should-open-external-urls flag set to false.<br>
+It loads a new page programmatically, leaving the flag false.<br>
+That new page clicks a link, which should set the flag to true.
+</body>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/main-frame-navigated-programatically-by-subframe-expected.txt b/LayoutTests/loader/navigation-policy/should-open-external-urls/main-frame-navigated-programatically-by-subframe-expected.txt
new file mode 100644 (file)
index 0000000..ffe0782
--- /dev/null
@@ -0,0 +1,7 @@
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL resources/main-frame-with-subframe-programatically-navigates-main.html, main document URL resources/main-frame-with-subframe-programatically-navigates-main.html, http method GET> is main frame - yes should open URLs externally - yes
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL programatically-navigate-to-notify-done-target-top.html, main document URL main-frame-with-subframe-programatically-navigates-main.html, http method GET> is main frame - no should open URLs externally - no
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL notify-done.html, main document URL notify-done.html, http method GET> is main frame - yes should open URLs externally - no
+
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/main-frame-navigated-programatically-by-subframe.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/main-frame-navigated-programatically-by-subframe.html
new file mode 100644 (file)
index 0000000..3ba3e3d
--- /dev/null
@@ -0,0 +1,13 @@
+<script>
+
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpPolicyDelegateCallbacks();
+    testRunner.queueLoad("resources/main-frame-with-subframe-programatically-navigates-main.html", "", true);
+}
+
+</script>
+This page has does not have the "should open external URLs" flag set.<br>
+It navigates to a 2nd page that does have the flag set.<br>
+That 2nd page contains an iframe which programatically navigates the main frame to a 3rd page.<br>
+The "should open external URLs" flag should be unset because the subframe->main frame navigation was programatic.<br>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/main-frame-with-flag-progamatic-expected.txt b/LayoutTests/loader/navigation-policy/should-open-external-urls/main-frame-with-flag-progamatic-expected.txt
new file mode 100644 (file)
index 0000000..2641add
--- /dev/null
@@ -0,0 +1,5 @@
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL resources/programatically-navigate-to-notify-done.html, main document URL resources/programatically-navigate-to-notify-done.html, http method GET> is main frame - yes should open URLs externally - yes
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL notify-done.html, main document URL notify-done.html, http method GET> is main frame - yes should open URLs externally - yes
+
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/main-frame-with-flag-progamatic.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/main-frame-with-flag-progamatic.html
new file mode 100644 (file)
index 0000000..9e3de38
--- /dev/null
@@ -0,0 +1,12 @@
+<script>
+
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpPolicyDelegateCallbacks();
+    testRunner.queueLoad("resources/programatically-navigate-to-notify-done.html", "", true);
+}
+
+</script>
+This page navigates to a 2nd page using the API that sets the "should open external URLs" flag to true.<br>
+That page then programatically redirects to a 3rd page.<br>
+That navigation from the 2nd page to the 3rd page should still have the flag set, because the flag propagates through main frame loads.<br>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/main-frame-without-flag-programatic-expected.txt b/LayoutTests/loader/navigation-policy/should-open-external-urls/main-frame-without-flag-programatic-expected.txt
new file mode 100644 (file)
index 0000000..3c4980a
--- /dev/null
@@ -0,0 +1,5 @@
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL resources/programatically-navigate-to-notify-done.html, main document URL resources/programatically-navigate-to-notify-done.html, http method GET> is main frame - yes should open URLs externally - no
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL notify-done.html, main document URL notify-done.html, http method GET> is main frame - yes should open URLs externally - no
+
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/main-frame-without-flag-programatic.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/main-frame-without-flag-programatic.html
new file mode 100644 (file)
index 0000000..4b59800
--- /dev/null
@@ -0,0 +1,12 @@
+<script>
+
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpPolicyDelegateCallbacks();
+    testRunner.queueLoad("resources/programatically-navigate-to-notify-done.html");
+}
+
+</script>
+This page navigates to a 2nd page with the "should open external URLs" flag set to false.<br>
+That page then programatically redirects to a 3rd page.<br>
+During the navigation from the 2nd page to the 3rd page the flag should still be false, because no user gesture was involved.<br>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/click-notify-done-in-main.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/click-notify-done-in-main.html
new file mode 100644 (file)
index 0000000..02701d7
--- /dev/null
@@ -0,0 +1,14 @@
+<script>
+function runTest()
+{
+    if (window.eventSender) {
+        var a = document.getElementById("a");
+        eventSender.mouseMoveTo(a.offsetLeft + 2, a.offsetTop + 2);
+        eventSender.mouseDown();
+        eventSender.mouseUp();
+    }
+}
+</script>
+<body onload="runTest();">
+<a id="a" href="notify-done.html" target="_top">Click for notify done in main frame</a>
+</body>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/iframe-click-notify-done-target-self.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/iframe-click-notify-done-target-self.html
new file mode 100644 (file)
index 0000000..5e00251
--- /dev/null
@@ -0,0 +1,18 @@
+<script>
+
+function runTest()
+{
+    if (!window.eventSender)
+        return;
+
+    var a = document.getElementById("a");
+    var iframe = window.parent.document.getElementsByTagName("iframe")[0];
+    eventSender.mouseMoveTo(a.offsetLeft + iframe.offsetLeft + 2, a.offsetTop + iframe.offsetTop + 2);
+    eventSender.mouseDown();
+    eventSender.mouseUp();
+}
+
+</script>
+<body onload="runTest();">
+<a id="a" href="notify-done.html" target="_self">Click for notify done in this frame</a>
+</body>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/iframe-click-notify-done-target-top.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/iframe-click-notify-done-target-top.html
new file mode 100644 (file)
index 0000000..56a8fa1
--- /dev/null
@@ -0,0 +1,18 @@
+<script>
+
+function runTest()
+{
+    if (!window.eventSender)
+        return;
+
+    var a = document.getElementById("a");
+    var iframe = window.parent.document.getElementsByTagName("iframe")[0];
+    eventSender.mouseMoveTo(a.offsetLeft + iframe.offsetLeft + 2, a.offsetTop + iframe.offsetTop + 2);
+    eventSender.mouseDown();
+    eventSender.mouseUp();
+}
+
+</script>
+<body onload="runTest();">
+<a id="a" href="notify-done.html" target="_top">Click for notify done in the main frame</a>
+</body>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/main-frame-with-subframe-click-targets-subframe.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/main-frame-with-subframe-click-targets-subframe.html
new file mode 100644 (file)
index 0000000..b113015
--- /dev/null
@@ -0,0 +1,5 @@
+This page contains a subframe.<br>
+Clicking the link in the subframe navigates the subframe.<br>
+The "should open external URLs" flag on that navigation should be false. Even though it was a link click, it was within a subframe which should never get the flag set to true.<br>
+<iframe src="click-notify-done-in-self.html"></iframe>
\ No newline at end of file
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/main-frame-with-subframe-programatically-navigates-main.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/main-frame-with-subframe-programatically-navigates-main.html
new file mode 100644 (file)
index 0000000..8666382
--- /dev/null
@@ -0,0 +1,6 @@
+<script>
+if (window.testRunner)
+    testRunner.waitUntilDone();
+</script>
+
+<iframe src="programatically-navigate-to-notify-done-target-top.html"></iframe>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/programatically-navigate-to-notify-done-target-top.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/programatically-navigate-to-notify-done-target-top.html
new file mode 100644 (file)
index 0000000..197a432
--- /dev/null
@@ -0,0 +1,14 @@
+<script>
+
+if (window.testRunner)
+    testRunner.waitUntilDone();
+    
+function loaded()
+{
+    window.top.location.href = "notify-done.html";
+}
+
+</script>
+<body onload="loaded();">
+This page does a javascript client redirect to notify-done.html in the main frame.
+</body>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/programatically-navigate-to-notify-done.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/programatically-navigate-to-notify-done.html
new file mode 100644 (file)
index 0000000..b59b9bb
--- /dev/null
@@ -0,0 +1,14 @@
+<script>
+
+if (window.testRunner)
+    testRunner.waitUntilDone();
+    
+function loaded()
+{
+    window.location.href = "notify-done.html";
+}
+
+</script>
+<body onload="loaded();">
+This page does a javascript client redirect to notify-done.html.
+</body>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/user-gesture-target-blank-to-notify-done-from-subframe.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/user-gesture-target-blank-to-notify-done-from-subframe.html
new file mode 100644 (file)
index 0000000..02c7435
--- /dev/null
@@ -0,0 +1 @@
+<iframe src="user-gesture-target-blank-to-notify-done.html"></iframe>
\ No newline at end of file
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/user-gesture-target-blank-to-notify-done.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/user-gesture-target-blank-to-notify-done.html
new file mode 100644 (file)
index 0000000..b39dd8f
--- /dev/null
@@ -0,0 +1,28 @@
+<script>
+
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.setCanOpenWindows();
+}
+
+function loaded()
+{
+    if (!window.eventSender)
+        return;
+
+    var a = document.getElementById("a");
+    var iframe = window.parent.document.getElementsByTagName("iframe")[0];
+
+    if (iframe)
+        eventSender.mouseMoveTo(a.offsetLeft + iframe.offsetLeft + 2, a.offsetTop + iframe.offsetTop + 2);
+    else
+        eventSender.mouseMoveTo(a.offsetLeft + 2, a.offsetTop + 2);
+
+    eventSender.mouseDown();
+    eventSender.mouseUp();
+}
+
+</script>
+<body onload="loaded();">
+<a id="a" href="notify-done.html" target="_blank">Click to open link in new window.</a>
+</body>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/user-gesture-window-open-to-notify-done-from-subframe.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/user-gesture-window-open-to-notify-done-from-subframe.html
new file mode 100644 (file)
index 0000000..50fc6ef
--- /dev/null
@@ -0,0 +1 @@
+<iframe src="user-gesture-window-open-to-notify-done.html"></iframe>
\ No newline at end of file
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/user-gesture-window-open-to-notify-done.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/user-gesture-window-open-to-notify-done.html
new file mode 100644 (file)
index 0000000..29638c4
--- /dev/null
@@ -0,0 +1,33 @@
+<script>
+
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.setCanOpenWindows();
+}
+
+function loaded()
+{
+    if (!window.eventSender)
+        return;
+
+    var a = document.getElementById("a");
+    var iframe = window.parent.document.getElementsByTagName("iframe")[0];
+
+    if (iframe)
+        eventSender.mouseMoveTo(a.offsetLeft + iframe.offsetLeft + 2, a.offsetTop + iframe.offsetTop + 2);
+    else
+        eventSender.mouseMoveTo(a.offsetLeft + 2, a.offsetTop + 2);
+
+    eventSender.mouseDown();
+    eventSender.mouseUp();
+}
+
+function clicked()
+{
+    window.open("notify-done.html");
+}
+
+</script>
+<body onload="loaded();">
+<a id="a" onclick="clicked();">Click to do a window.open</a>
+</body>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/window-open-to-notify-done-from-subframe.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/window-open-to-notify-done-from-subframe.html
new file mode 100644 (file)
index 0000000..cedd517
--- /dev/null
@@ -0,0 +1 @@
+<iframe src="window-open-to-notify-done.html"></iframe>
\ No newline at end of file
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/window-open-to-notify-done.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/window-open-to-notify-done.html
new file mode 100644 (file)
index 0000000..7d2d090
--- /dev/null
@@ -0,0 +1,15 @@
+<script>
+
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.setCanOpenWindows();
+}
+
+function loaded()
+{
+    window.open("notify-done.html");
+}
+
+</script>
+<body onload="loaded();">
+</body>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/subframe-click-target-self-expected.txt b/LayoutTests/loader/navigation-policy/should-open-external-urls/subframe-click-target-self-expected.txt
new file mode 100644 (file)
index 0000000..3055533
--- /dev/null
@@ -0,0 +1,9 @@
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL about:blank, main document URL subframe-click-target-self.html, http method GET> is main frame - no should open URLs externally - no
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL resources/iframe-click-notify-done-target-self.html, main document URL subframe-click-target-self.html, http method GET> is main frame - no should open URLs externally - no
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL resources/notify-done.html, main document URL subframe-click-target-self.html, http method GET> is main frame - no should open URLs externally - no
+This page has a subframe with a link.
+Then a link is clicked in that subframe that navigates inside that subframe, and that navigation should have the "should open external urls" flag set to false even though it was from a user gesture.
+
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/subframe-click-target-self.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/subframe-click-target-self.html
new file mode 100644 (file)
index 0000000..94ed7de
--- /dev/null
@@ -0,0 +1,19 @@
+<script>
+
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpPolicyDelegateCallbacks();
+    testRunner.waitUntilDone();
+}
+
+function runTest()
+{
+    window.frames[0].location = "resources/iframe-click-notify-done-target-self.html";
+}
+
+</script>
+<body onload="runTest();">
+This page has a subframe with a link.<br>
+Then a link is clicked in that subframe that navigates inside that subframe, and that navigation should have the "should open external urls" flag set to false even though it was from a user gesture.<br>
+<iframe></iframe>
+</body>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/subframe-click-target-top-expected.txt b/LayoutTests/loader/navigation-policy/should-open-external-urls/subframe-click-target-top-expected.txt
new file mode 100644 (file)
index 0000000..9b5d3f4
--- /dev/null
@@ -0,0 +1,7 @@
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL about:blank, main document URL subframe-click-target-top.html, http method GET> is main frame - no should open URLs externally - no
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL resources/iframe-click-notify-done-target-top.html, main document URL subframe-click-target-top.html, http method GET> is main frame - no should open URLs externally - no
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL resources/notify-done.html, main document URL resources/notify-done.html, http method GET> is main frame - yes should open URLs externally - yes
+
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/subframe-click-target-top.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/subframe-click-target-top.html
new file mode 100644 (file)
index 0000000..cb2a6aa
--- /dev/null
@@ -0,0 +1,19 @@
+<script>
+
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpPolicyDelegateCallbacks();
+    testRunner.waitUntilDone();
+}
+
+function runTest()
+{
+    window.frames[0].location = "resources/iframe-click-notify-done-target-top.html";
+}
+
+</script>
+<body onload="runTest();">
+This page has a subframe with a link.<br>
+Then a link is clicked in that subframe that navigates the main frame, and that navigation should have the "should open external urls" flag set to true because it was from a user gesture.<br>
+<iframe></iframe>
+</body>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag-expected.txt b/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag-expected.txt
new file mode 100644 (file)
index 0000000..ef0069b
--- /dev/null
@@ -0,0 +1,5 @@
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL resources/user-gesture-target-blank-to-notify-done.html, main document URL resources/user-gesture-target-blank-to-notify-done.html, http method GET> is main frame - yes should open URLs externally - yes
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL notify-done.html, main document URL notify-done.html, http method GET> is main frame - yes should open URLs externally - yes
+Click to open link in new window.
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag-from-subframe-expected.txt b/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag-from-subframe-expected.txt
new file mode 100644 (file)
index 0000000..299483c
--- /dev/null
@@ -0,0 +1,7 @@
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL resources/user-gesture-target-blank-to-notify-done-from-subframe.html, main document URL resources/user-gesture-target-blank-to-notify-done-from-subframe.html, http method GET> is main frame - yes should open URLs externally - yes
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL user-gesture-target-blank-to-notify-done.html, main document URL user-gesture-target-blank-to-notify-done-from-subframe.html, http method GET> is main frame - no should open URLs externally - no
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL notify-done.html, main document URL user-gesture-target-blank-to-notify-done-from-subframe.html, http method GET> is main frame - yes should open URLs externally - yes
+
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag-from-subframe.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag-from-subframe.html
new file mode 100644 (file)
index 0000000..5efb896
--- /dev/null
@@ -0,0 +1,10 @@
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpPolicyDelegateCallbacks();
+    testRunner.queueLoad("resources/user-gesture-target-blank-to-notify-done-from-subframe.html", "", true);
+}
+</script>
+This page opens a 2nd page with the "should open external URLs" flag set to true.<br>
+That page has a subframe with a link that - when clicked - opens a link to a 3rd page in a new window.<br>
+That 3rd page should have the flag set to true because it was from a user gesture.<br>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag.html
new file mode 100644 (file)
index 0000000..0c87f43
--- /dev/null
@@ -0,0 +1,10 @@
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpPolicyDelegateCallbacks();
+    testRunner.queueLoad("resources/user-gesture-target-blank-to-notify-done.html", "", true);
+}
+</script>
+This page opens a 2nd page with the "should open external URLs" flag set to true.<br>
+That page has a link that - when clicked - opens a link to a 3rd page in a new window.<br>
+That 3rd page should have the flag set to true because it was from a user gesture.<br>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag-expected.txt b/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag-expected.txt
new file mode 100644 (file)
index 0000000..c737132
--- /dev/null
@@ -0,0 +1,5 @@
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL resources/user-gesture-target-blank-to-notify-done.html, main document URL resources/user-gesture-target-blank-to-notify-done.html, http method GET> is main frame - yes should open URLs externally - no
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL notify-done.html, main document URL notify-done.html, http method GET> is main frame - yes should open URLs externally - yes
+Click to open link in new window.
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag-from-subframe-expected.txt b/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag-from-subframe-expected.txt
new file mode 100644 (file)
index 0000000..dd51e3f
--- /dev/null
@@ -0,0 +1,7 @@
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL resources/user-gesture-target-blank-to-notify-done-from-subframe.html, main document URL resources/user-gesture-target-blank-to-notify-done-from-subframe.html, http method GET> is main frame - yes should open URLs externally - no
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL user-gesture-target-blank-to-notify-done.html, main document URL user-gesture-target-blank-to-notify-done-from-subframe.html, http method GET> is main frame - no should open URLs externally - no
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL notify-done.html, main document URL user-gesture-target-blank-to-notify-done-from-subframe.html, http method GET> is main frame - yes should open URLs externally - yes
+
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag-from-subframe.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag-from-subframe.html
new file mode 100644 (file)
index 0000000..d486827
--- /dev/null
@@ -0,0 +1,10 @@
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpPolicyDelegateCallbacks();
+    testRunner.queueLoad("resources/user-gesture-target-blank-to-notify-done-from-subframe.html");
+}
+</script>
+This page opens a 2nd page with the "should open external URLs" flag set to false.<br>
+That page has a subframe with a link that - when clicked - opens a link to a 3rd page in a new window.<br>
+That 3rd page should have the flag set to true because it was from a user gesture.<br>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag.html
new file mode 100644 (file)
index 0000000..604bee4
--- /dev/null
@@ -0,0 +1,10 @@
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpPolicyDelegateCallbacks();
+    testRunner.queueLoad("resources/user-gesture-target-blank-to-notify-done.html");
+}
+</script>
+This page opens a 2nd page with the "should open external URLs" flag set to false.<br>
+That page has a link that - when clicked - opens a link to a 3rd page in a new window.<br>
+That 3rd page should have the flag set to true because it was from a user gesture.<br>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag-expected.txt b/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag-expected.txt
new file mode 100644 (file)
index 0000000..ac539b7
--- /dev/null
@@ -0,0 +1,5 @@
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL resources/user-gesture-window-open-to-notify-done.html, main document URL resources/user-gesture-window-open-to-notify-done.html, http method GET> is main frame - yes should open URLs externally - yes
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL notify-done.html, main document URL notify-done.html, http method GET> is main frame - yes should open URLs externally - yes
+Click to do a window.open
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag-from-subframe-expected.txt b/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag-from-subframe-expected.txt
new file mode 100644 (file)
index 0000000..8f4569a
--- /dev/null
@@ -0,0 +1,7 @@
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL resources/user-gesture-window-open-to-notify-done-from-subframe.html, main document URL resources/user-gesture-window-open-to-notify-done-from-subframe.html, http method GET> is main frame - yes should open URLs externally - yes
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL user-gesture-window-open-to-notify-done.html, main document URL user-gesture-window-open-to-notify-done-from-subframe.html, http method GET> is main frame - no should open URLs externally - no
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL notify-done.html, main document URL notify-done.html, http method GET> is main frame - yes should open URLs externally - yes
+
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag-from-subframe.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag-from-subframe.html
new file mode 100644 (file)
index 0000000..9782732
--- /dev/null
@@ -0,0 +1,10 @@
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpPolicyDelegateCallbacks();
+    testRunner.queueLoad("resources/user-gesture-window-open-to-notify-done-from-subframe.html", "", true);
+}
+</script>
+This page opens a 2nd page with the "should open external URLs" flag set to true.<br>
+That page has a subframe with a link that - when clicked - calls window.open to a 3rd page.<br>
+That 3rd page should have the flag set to true because it was from a user gesture.<br>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag.html
new file mode 100644 (file)
index 0000000..8c44e7a
--- /dev/null
@@ -0,0 +1,10 @@
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpPolicyDelegateCallbacks();
+    testRunner.queueLoad("resources/user-gesture-window-open-to-notify-done.html", "", true);
+}
+</script>
+This page opens a 2nd page with the "should open external URLs" flag set to true.<br>
+That page has a link that - when clicked - does a window.open to open a 3rd page.<br>
+That 3rd page should have the flag set to true because it was from a user gesture.<br>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag-expected.txt b/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag-expected.txt
new file mode 100644 (file)
index 0000000..77466fc
--- /dev/null
@@ -0,0 +1,5 @@
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL resources/user-gesture-window-open-to-notify-done.html, main document URL resources/user-gesture-window-open-to-notify-done.html, http method GET> is main frame - yes should open URLs externally - no
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL notify-done.html, main document URL notify-done.html, http method GET> is main frame - yes should open URLs externally - yes
+Click to do a window.open
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag-from-subframe-expected.txt b/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag-from-subframe-expected.txt
new file mode 100644 (file)
index 0000000..ccfe5da
--- /dev/null
@@ -0,0 +1,7 @@
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL resources/user-gesture-window-open-to-notify-done-from-subframe.html, main document URL resources/user-gesture-window-open-to-notify-done-from-subframe.html, http method GET> is main frame - yes should open URLs externally - no
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL user-gesture-window-open-to-notify-done.html, main document URL user-gesture-window-open-to-notify-done-from-subframe.html, http method GET> is main frame - no should open URLs externally - no
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL notify-done.html, main document URL notify-done.html, http method GET> is main frame - yes should open URLs externally - yes
+
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag-from-subframe.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag-from-subframe.html
new file mode 100644 (file)
index 0000000..494b4fa
--- /dev/null
@@ -0,0 +1,10 @@
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpPolicyDelegateCallbacks();
+    testRunner.queueLoad("resources/user-gesture-window-open-to-notify-done-from-subframe.html");
+}
+</script>
+This page opens a 2nd page with the "should open external URLs" flag set to false.<br>
+That page has a subframe with a link that - when clicked - calls window.open to a 3rd page.<br>
+That 3rd page should have the flag set to true because it was from a user gesture.<br>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag.html
new file mode 100644 (file)
index 0000000..5870888
--- /dev/null
@@ -0,0 +1,10 @@
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpPolicyDelegateCallbacks();
+    testRunner.queueLoad("resources/user-gesture-window-open-to-notify-done.html");
+}
+</script>
+This page opens a 2nd page with the "should open external URLs" flag set to false.<br>
+That page has a link that - when clicked - does a window.open to open a 3rd page.<br>
+That 3rd page should have the flag set to true because it was from a user gesture.<br>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/window-open-with-flag-expected.txt b/LayoutTests/loader/navigation-policy/should-open-external-urls/window-open-with-flag-expected.txt
new file mode 100644 (file)
index 0000000..0df9020
--- /dev/null
@@ -0,0 +1,5 @@
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL resources/window-open-to-notify-done.html, main document URL resources/window-open-to-notify-done.html, http method GET> is main frame - yes should open URLs externally - yes
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL notify-done.html, main document URL notify-done.html, http method GET> is main frame - yes should open URLs externally - yes
+
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/window-open-with-flag-from-subframe-expected.txt b/LayoutTests/loader/navigation-policy/should-open-external-urls/window-open-with-flag-from-subframe-expected.txt
new file mode 100644 (file)
index 0000000..2cbef64
--- /dev/null
@@ -0,0 +1,7 @@
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL resources/window-open-to-notify-done-from-subframe.html, main document URL resources/window-open-to-notify-done-from-subframe.html, http method GET> is main frame - yes should open URLs externally - yes
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL window-open-to-notify-done.html, main document URL window-open-to-notify-done-from-subframe.html, http method GET> is main frame - no should open URLs externally - no
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL notify-done.html, main document URL notify-done.html, http method GET> is main frame - yes should open URLs externally - no
+
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/window-open-with-flag-from-subframe.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/window-open-with-flag-from-subframe.html
new file mode 100644 (file)
index 0000000..81a57f7
--- /dev/null
@@ -0,0 +1,10 @@
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpPolicyDelegateCallbacks();
+    testRunner.queueLoad("resources/window-open-to-notify-done-from-subframe.html", "", true);
+}
+</script>
+This page opens a 2nd page with the "should open external URLs" flag set to true.<br>
+That page has a subframe which calls window.open to a 3rd page.<br>
+That 3rd page should have the flag set to false because the subframe initiated the load.<br>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/window-open-with-flag.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/window-open-with-flag.html
new file mode 100644 (file)
index 0000000..ce3d949
--- /dev/null
@@ -0,0 +1,10 @@
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpPolicyDelegateCallbacks();
+    testRunner.queueLoad("resources/window-open-to-notify-done.html", "", true);
+}
+</script>
+This page opens a 2nd page with the "should open external URLs" flag set to true.<br>
+That page does a window.open to open a 3rd page.<br>
+That 3rd page should have the flag set to true because it should propagate from main frame to main frame.<br>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/window-open-without-flag-expected.txt b/LayoutTests/loader/navigation-policy/should-open-external-urls/window-open-without-flag-expected.txt
new file mode 100644 (file)
index 0000000..d68c88a
--- /dev/null
@@ -0,0 +1,5 @@
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL resources/window-open-to-notify-done.html, main document URL resources/window-open-to-notify-done.html, http method GET> is main frame - yes should open URLs externally - no
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL notify-done.html, main document URL notify-done.html, http method GET> is main frame - yes should open URLs externally - no
+
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/window-open-without-flag-from-subframe-expected.txt b/LayoutTests/loader/navigation-policy/should-open-external-urls/window-open-without-flag-from-subframe-expected.txt
new file mode 100644 (file)
index 0000000..9c8442e
--- /dev/null
@@ -0,0 +1,7 @@
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL resources/window-open-to-notify-done-from-subframe.html, main document URL resources/window-open-to-notify-done-from-subframe.html, http method GET> is main frame - yes should open URLs externally - no
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL window-open-to-notify-done.html, main document URL window-open-to-notify-done-from-subframe.html, http method GET> is main frame - no should open URLs externally - no
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL notify-done.html, main document URL notify-done.html, http method GET> is main frame - yes should open URLs externally - no
+
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/window-open-without-flag-from-subframe.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/window-open-without-flag-from-subframe.html
new file mode 100644 (file)
index 0000000..97e53b5
--- /dev/null
@@ -0,0 +1,10 @@
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpPolicyDelegateCallbacks();
+    testRunner.queueLoad("resources/window-open-to-notify-done-from-subframe.html");
+}
+</script>
+This page opens a 2nd page with the "should open external URLs" flag set to false.<br>
+That page has a subframe which calls window.open to a 3rd page.<br>
+That 3rd page should have the flag set to false because the subframe initiated the load, *and* because the main frame did not have the flag set.<br>
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/window-open-without-flag.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/window-open-without-flag.html
new file mode 100644 (file)
index 0000000..80017d0
--- /dev/null
@@ -0,0 +1,10 @@
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpPolicyDelegateCallbacks();
+    testRunner.queueLoad("resources/window-open-to-notify-done.html");
+}
+</script>
+This page opens a 2nd page with the "should open external URLs" flag set to false.<br>
+That page does a window.open to open a 3rd page.<br>
+That 3rd page should also have the flag set to false.<br>
index ec6302f..56e1bf8 100644 (file)
@@ -1,3 +1,142 @@
+2015-06-02  Brady Eidson  <beidson@apple.com>
+
+        WebKit policy delegate should suggest if a navigation should be allowed to open URLs externally.
+        rdar://problem/21025301 and https://bugs.webkit.org/show_bug.cgi?id=145280
+
+        Reviewed by Alex Christensen.
+
+        Tests: loader/navigation-policy/should-open-external-urls/main-frame-click.html
+               loader/navigation-policy/should-open-external-urls/main-frame-navigated-programatically-by-subframe.html
+               loader/navigation-policy/should-open-external-urls/main-frame-with-flag-progamatic.html
+               loader/navigation-policy/should-open-external-urls/main-frame-without-flag-programatic.html
+               loader/navigation-policy/should-open-external-urls/subframe-click-target-self.html
+               loader/navigation-policy/should-open-external-urls/subframe-click-target-top.html
+               loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag-from-subframe.html
+               loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag.html
+               loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag-from-subframe.html
+               loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag.html
+               loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag-from-subframe.html
+               loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag.html
+               loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag-from-subframe.html
+               loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag.html
+               loader/navigation-policy/should-open-external-urls/window-open-with-flag-from-subframe.html
+               loader/navigation-policy/should-open-external-urls/window-open-with-flag.html
+               loader/navigation-policy/should-open-external-urls/window-open-without-flag-from-subframe.html
+               loader/navigation-policy/should-open-external-urls/window-open-without-flag.html
+
+        The "should open external URLs" flag is only for main frames.
+        It doesn't enforce any sort of policy internal to WebKit, but rather is for notifications to the policy delegate.
+        
+        It is set from one of two places:
+        1 - A main frame is navigated by any frame as the result of a user gesture.
+        2 - WebKit2 API explicitly states the flag is true.
+        
+        The flag value propagates when:
+        1 - When a main frame document is navigated to a new main frame document.
+        2 - When a new window is opened from a page whose main frame had the flag set.
+        3 - When a new window is opened as the result of a user gesture.
+        
+        The flag resets to false when:
+        1 - A subframe navigates a main frame without a user gesture.
+        
+        This patch is large, but does little more than the following:
+        1 - Adds a ShouldOpenExternalURLs flag to both FrameLoadRequest and NavigationAction.
+        2 - Makes sure anybody who creates either of those objects sets a sensible for that flag.
+        3 - When FrameLoader creates a new DocumentLoader, it sets its flag based on whether or not the load is in a main frame,
+            whether or not the load is from a user gesture, and based on the initiator's value of the flag. 
+            
+        * dom/Document.cpp:
+        (WebCore::Document::processHttpEquiv):
+        (WebCore::Document::shouldOpenExternalURLsPolicyToPropagate):
+        * dom/Document.h:
+        
+        * html/HTMLAnchorElement.cpp:
+        (WebCore::HTMLAnchorElement::handleClick):
+        
+        * html/HTMLLinkElement.cpp:
+        (WebCore::HTMLLinkElement::handleClick):
+        
+        * html/parser/XSSAuditorDelegate.cpp:
+        (WebCore::XSSAuditorDelegate::didBlockScript):
+        
+        * inspector/InspectorFrontendClientLocal.cpp:
+        (WebCore::InspectorFrontendClientLocal::openInNewTab):
+        
+        * inspector/InspectorPageAgent.cpp:
+        (WebCore::InspectorPageAgent::navigate):
+        
+        * loader/DocumentLoader.cpp:
+        (WebCore::DocumentLoader::setTriggeringAction):
+        (WebCore::DocumentLoader::shouldOpenExternalURLsPolicyToPropagate):
+        * loader/DocumentLoader.h:
+        (WebCore::DocumentLoader::shouldOpenExternalURLsPolicy): Deleted.
+        
+        * loader/FrameLoadRequest.cpp:
+        (WebCore::FrameLoadRequest::FrameLoadRequest):
+        * loader/FrameLoadRequest.h:
+        (WebCore::FrameLoadRequest::FrameLoadRequest):
+        
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::urlSelected):
+        (WebCore::FrameLoader::receivedFirstData):
+        (WebCore::FrameLoader::loadURLIntoChildFrame):
+        (WebCore::FrameLoader::loadURL):
+        (WebCore::FrameLoader::load):
+        (WebCore::FrameLoader::loadWithNavigationAction):
+        (WebCore::FrameLoader::reloadWithOverrideEncoding):
+        (WebCore::FrameLoader::reload):
+        (WebCore::FrameLoader::loadPostRequest):
+        (WebCore::FrameLoader::continueLoadAfterNewWindowPolicy):
+        (WebCore::FrameLoader::applyShouldOpenExternalURLsPolicyToNewDocumentLoader):
+        * loader/FrameLoader.h:
+        
+        * loader/NavigationAction.cpp:
+        (WebCore::NavigationAction::NavigationAction):
+        (WebCore::NavigationAction::copyWithShouldOpenExternalURLsPolicy):
+        * loader/NavigationAction.h:
+        (WebCore::NavigationAction::setShouldOpenExternalURLsPolicy): Deleted.
+        
+        * loader/NavigationScheduler.cpp:
+        (WebCore::ScheduledURLNavigation::ScheduledURLNavigation):
+        (WebCore::ScheduledRedirect::ScheduledRedirect):
+        (WebCore::ScheduledLocationChange::ScheduledLocationChange):
+        (WebCore::ScheduledRefresh::ScheduledRefresh):
+        (WebCore::ScheduledFormSubmission::ScheduledFormSubmission):
+        (WebCore::NavigationScheduler::scheduleRedirect):
+        (WebCore::NavigationScheduler::scheduleLocationChange):
+        (WebCore::NavigationScheduler::scheduleRefresh):
+        * loader/NavigationScheduler.h:
+        
+        * loader/PolicyChecker.cpp:
+        (WebCore::PolicyChecker::checkNavigationPolicy):
+        
+        * loader/SubframeLoader.cpp:
+        (WebCore::SubframeLoader::loadOrRedirectSubframe):
+        
+        * loader/appcache/ApplicationCacheGroup.cpp:
+        (WebCore::ApplicationCacheGroup::selectCache):
+        
+        * page/ContextMenuController.cpp:
+        (WebCore::openNewWindow):
+        (WebCore::ContextMenuController::contextMenuItemSelected):
+        
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::setLocation):
+        (WebCore::DOMWindow::createWindow):
+        (WebCore::DOMWindow::open):
+        
+        * page/DragController.cpp:
+        (WebCore::DragController::performDragOperation):
+        
+        * page/Location.cpp:
+        (WebCore::Location::reload):
+        
+        * replay/ReplayInputDispatchMethods.cpp:
+        (WebCore::InitialNavigation::dispatch):
+        
+        * svg/SVGAElement.cpp:
+        (WebCore::SVGAElement::defaultEventHandler):
+
 2015-06-02  Yusuke Suzuki  <utatane.tea@gmail.com>
 
         Heap-use-after-free read of size 4 in JavaScriptCore: WTF::StringImpl::isSymbol() (StringImpl.h:496)
index 46a13d5..fefa9b6 100644 (file)
@@ -3049,7 +3049,7 @@ void Document::processHttpEquiv(const String& equiv, const String& content)
             else
                 completedURL = completeURL(urlString);
             if (!protocolIsJavaScript(completedURL))
-                frame->navigationScheduler().scheduleRedirect(delay, completedURL);
+                frame->navigationScheduler().scheduleRedirect(this, delay, completedURL);
             else {
                 String message = "Refused to refresh " + m_url.stringCenterEllipsizedToLength() + " to a javascript: URL";
                 addConsoleMessage(MessageSource::Security, MessageLevel::Error, message);
@@ -3087,7 +3087,7 @@ void Document::processHttpEquiv(const String& equiv, const String& content)
                 // Stopping the loader isn't enough, as we're already parsing the document; to honor the header's
                 // intent, we must navigate away from the possibly partially-rendered document to a location that
                 // doesn't inherit the parent's SecurityOrigin.
-                frame->navigationScheduler().scheduleLocationChange(securityOrigin(), SecurityOrigin::urlWithUniqueSecurityOrigin(), String());
+                frame->navigationScheduler().scheduleLocationChange(this, securityOrigin(), SecurityOrigin::urlWithUniqueSecurityOrigin(), String());
                 addConsoleMessage(MessageSource::Security, MessageLevel::Error, message, requestIdentifier);
             }
         }
@@ -6648,4 +6648,12 @@ void Document::setShouldPlayToPlaybackTarget(uint64_t clientId, bool shouldPlay)
 }
 #endif // ENABLE(WIRELESS_PLAYBACK_TARGET)
 
+ShouldOpenExternalURLsPolicy Document::shouldOpenExternalURLsPolicyToPropagate() const
+{
+    if (DocumentLoader* documentLoader = loader())
+        return documentLoader->shouldOpenExternalURLsPolicyToPropagate();
+
+    return ShouldOpenExternalURLsPolicy::ShouldNotAllow;
+}
+
 } // namespace WebCore
index ac3999a..baa2c4f 100644 (file)
@@ -165,6 +165,8 @@ class XPathExpression;
 class XPathNSResolver;
 class XPathResult;
 
+enum class ShouldOpenExternalURLsPolicy;
+
 #if ENABLE(XSLT)
 class TransformSource;
 #endif
@@ -1254,6 +1256,8 @@ public:
     void setShouldPlayToPlaybackTarget(uint64_t, bool);
 #endif
 
+    ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicyToPropagate() const;
+
 protected:
     enum ConstructionFlags { Synthesized = 1, NonRenderedPlaceholder = 1 << 1 };
     Document(Frame*, const URL&, unsigned = DefaultDocumentClass, unsigned constructionFlags = 0);
index 5490473..5bd7e58 100644 (file)
@@ -558,7 +558,8 @@ void HTMLAnchorElement::handleClick(Event* event)
         frame->loader().client().startDownload(request, fastGetAttribute(downloadAttr));
     } else
 #endif
-        frame->loader().urlSelected(kurl, target(), event, LockHistory::No, LockBackForwardList::No, hasRel(RelationNoReferrer) ? NeverSendReferrer : MaybeSendReferrer);
+
+    frame->loader().urlSelected(kurl, target(), event, LockHistory::No, LockBackForwardList::No, hasRel(RelationNoReferrer) ? NeverSendReferrer : MaybeSendReferrer, document().shouldOpenExternalURLsPolicyToPropagate());
 
     sendPings(kurl);
 }
index 1edffd0..a6f795b 100644 (file)
@@ -441,7 +441,7 @@ void HTMLLinkElement::handleClick(Event& event)
     Frame* frame = document().frame();
     if (!frame)
         return;
-    frame->loader().urlSelected(url, target(), &event, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer);
+    frame->loader().urlSelected(url, target(), &event, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, document().shouldOpenExternalURLsPolicyToPropagate());
 }
 
 URL HTMLLinkElement::href() const
index 04dd043..f54d92a 100644 (file)
@@ -112,7 +112,7 @@ void XSSAuditorDelegate::didBlockScript(const XSSInfo& xssInfo)
     }
 
     if (xssInfo.m_didBlockEntirePage)
-        m_document.frame()->navigationScheduler().scheduleLocationChange(m_document.securityOrigin(), SecurityOrigin::urlWithUniqueSecurityOrigin(), String());
+        m_document.frame()->navigationScheduler().scheduleLocationChange(&m_document, m_document.securityOrigin(), SecurityOrigin::urlWithUniqueSecurityOrigin(), String());
 }
 
 } // namespace WebCore
index 374dcc1..bc394d3 100644 (file)
@@ -210,7 +210,7 @@ void InspectorFrontendClientLocal::openInNewTab(const String& url)
 {
     UserGestureIndicator indicator(DefinitelyProcessingUserGesture);
     Frame& mainFrame = m_inspectorController->inspectedPage().mainFrame();
-    FrameLoadRequest request(mainFrame.document()->securityOrigin(), ResourceRequest(), "_blank", LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ReplaceDocumentIfJavaScriptURL);
+    FrameLoadRequest request(mainFrame.document()->securityOrigin(), ResourceRequest(), "_blank", LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ReplaceDocumentIfJavaScriptURL, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
 
     bool created;
     WindowFeatures windowFeatures;
@@ -223,7 +223,7 @@ void InspectorFrontendClientLocal::openInNewTab(const String& url)
 
     // FIXME: Why does one use mainFrame and the other frame?
     ResourceRequest resourceRequest(frame->document()->completeURL(url));
-    FrameLoadRequest frameRequest(mainFrame.document()->securityOrigin(), resourceRequest, emptyString(), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ReplaceDocumentIfJavaScriptURL);
+    FrameLoadRequest frameRequest(mainFrame.document()->securityOrigin(), resourceRequest, emptyString(), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ReplaceDocumentIfJavaScriptURL, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
     frame->loader().changeLocation(frameRequest);
 }
 
index 716f40f..18c0433 100644 (file)
@@ -419,7 +419,7 @@ void InspectorPageAgent::navigate(ErrorString&, const String& url)
     Frame& frame = m_page->mainFrame();
 
     ResourceRequest resourceRequest(frame.document()->completeURL(url));
-    FrameLoadRequest frameRequest(frame.document()->securityOrigin(), resourceRequest, emptyString(), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, ShouldReplaceDocumentIfJavaScriptURL::ReplaceDocumentIfJavaScriptURL);
+    FrameLoadRequest frameRequest(frame.document()->securityOrigin(), resourceRequest, emptyString(), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, ShouldReplaceDocumentIfJavaScriptURL::ReplaceDocumentIfJavaScriptURL, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
     frame.loader().changeLocation(frameRequest);
 }
 
index cb198cb..52f60f5 100644 (file)
@@ -1549,9 +1549,15 @@ void DocumentLoader::handledOnloadEvents()
 
 void DocumentLoader::setTriggeringAction(const NavigationAction& action)
 {
-    m_triggeringAction = action;
-    if (!m_triggeringAction.isEmpty())
-        m_triggeringAction.setShouldOpenExternalURLsPolicy(m_shouldOpenExternalURLsPolicy);
+    m_triggeringAction = action.copyWithShouldOpenExternalURLsPolicy(m_frame ? shouldOpenExternalURLsPolicyToPropagate() : m_shouldOpenExternalURLsPolicy);
+}
+
+ShouldOpenExternalURLsPolicy DocumentLoader::shouldOpenExternalURLsPolicyToPropagate() const
+{
+    if (!m_frame || !m_frame->isMainFrame())
+        return ShouldOpenExternalURLsPolicy::ShouldNotAllow;
+
+    return m_shouldOpenExternalURLsPolicy;
 }
 
 #if ENABLE(CONTENT_EXTENSIONS)
index 64bf35a..935e881 100644 (file)
@@ -276,7 +276,7 @@ namespace WebCore {
 #endif
 
         void setShouldOpenExternalURLsPolicy(ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy) { m_shouldOpenExternalURLsPolicy = shouldOpenExternalURLsPolicy; }
-        ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy() const { return m_shouldOpenExternalURLsPolicy; }
+        ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicyToPropagate() const;
 
     protected:
         WEBCORE_EXPORT DocumentLoader(const ResourceRequest&, const SubstituteData&);
index 7b974b0..5d9926f 100644 (file)
@@ -36,7 +36,7 @@
 
 namespace WebCore {
 
-FrameLoadRequest::FrameLoadRequest(Frame* frame, const ResourceRequest& resourceRequest, const SubstituteData& substituteData)
+FrameLoadRequest::FrameLoadRequest(Frame* frame, const ResourceRequest& resourceRequest, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, const SubstituteData& substituteData)
     : m_requester(frame->document()->securityOrigin())
     , m_resourceRequest(resourceRequest)
     , m_shouldCheckNewWindowPolicy(false)
@@ -47,6 +47,7 @@ FrameLoadRequest::FrameLoadRequest(Frame* frame, const ResourceRequest& resource
     , m_allowNavigationToInvalidURL(AllowNavigationToInvalidURL::Yes)
     , m_newFrameOpenerPolicy(NewFrameOpenerPolicy::Allow)
     , m_shouldReplaceDocumentIfJavaScriptURL(ReplaceDocumentIfJavaScriptURL)
+    , m_shouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicy)
 {
 }
 
index 2c8159e..95189ec 100644 (file)
@@ -36,7 +36,7 @@ class Frame;
 
 struct FrameLoadRequest {
 public:
-    FrameLoadRequest(SecurityOrigin* requester, LockHistory lockHistory, LockBackForwardList lockBackForwardList, ShouldSendReferrer shouldSendReferrer, AllowNavigationToInvalidURL allowNavigationToInvalidURL, NewFrameOpenerPolicy newFrameOpenerPolicy)
+    FrameLoadRequest(SecurityOrigin* requester, LockHistory lockHistory, LockBackForwardList lockBackForwardList, ShouldSendReferrer shouldSendReferrer, AllowNavigationToInvalidURL allowNavigationToInvalidURL, NewFrameOpenerPolicy newFrameOpenerPolicy, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy)
         : m_requester(requester)
         , m_shouldCheckNewWindowPolicy(false)
         , m_lockHistory(lockHistory)
@@ -45,10 +45,11 @@ public:
         , m_allowNavigationToInvalidURL(allowNavigationToInvalidURL)
         , m_newFrameOpenerPolicy(newFrameOpenerPolicy)
         , m_shouldReplaceDocumentIfJavaScriptURL(ReplaceDocumentIfJavaScriptURL)
+        , m_shouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicy)
     {
     }
 
-    FrameLoadRequest(SecurityOrigin* requester, const ResourceRequest& resourceRequest, LockHistory lockHistory, LockBackForwardList lockBackForwardList, ShouldSendReferrer shouldSendReferrer, AllowNavigationToInvalidURL allowNavigationToInvalidURL, NewFrameOpenerPolicy newFrameOpenerPolicy)
+    FrameLoadRequest(SecurityOrigin* requester, const ResourceRequest& resourceRequest, LockHistory lockHistory, LockBackForwardList lockBackForwardList, ShouldSendReferrer shouldSendReferrer, AllowNavigationToInvalidURL allowNavigationToInvalidURL, NewFrameOpenerPolicy newFrameOpenerPolicy, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy)
         : m_requester(requester)
         , m_resourceRequest(resourceRequest)
         , m_shouldCheckNewWindowPolicy(false)
@@ -58,10 +59,11 @@ public:
         , m_allowNavigationToInvalidURL(allowNavigationToInvalidURL)
         , m_newFrameOpenerPolicy(newFrameOpenerPolicy)
         , m_shouldReplaceDocumentIfJavaScriptURL(ReplaceDocumentIfJavaScriptURL)
+        , m_shouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicy)
     {
     }
 
-    FrameLoadRequest(SecurityOrigin* requester, const ResourceRequest& resourceRequest, const String& frameName, LockHistory lockHistory, LockBackForwardList lockBackForwardList, ShouldSendReferrer shouldSendReferrer, AllowNavigationToInvalidURL allowNavigationToInvalidURL, NewFrameOpenerPolicy newFrameOpenerPolicy, ShouldReplaceDocumentIfJavaScriptURL shouldReplaceDocumentIfJavaScriptURL)
+    FrameLoadRequest(SecurityOrigin* requester, const ResourceRequest& resourceRequest, const String& frameName, LockHistory lockHistory, LockBackForwardList lockBackForwardList, ShouldSendReferrer shouldSendReferrer, AllowNavigationToInvalidURL allowNavigationToInvalidURL, NewFrameOpenerPolicy newFrameOpenerPolicy, ShouldReplaceDocumentIfJavaScriptURL shouldReplaceDocumentIfJavaScriptURL, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy)
         : m_requester(requester)
         , m_resourceRequest(resourceRequest)
         , m_frameName(frameName)
@@ -72,10 +74,11 @@ public:
         , m_allowNavigationToInvalidURL(allowNavigationToInvalidURL)
         , m_newFrameOpenerPolicy(newFrameOpenerPolicy)
         , m_shouldReplaceDocumentIfJavaScriptURL(shouldReplaceDocumentIfJavaScriptURL)
+        , m_shouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicy)
     {
     }
 
-    WEBCORE_EXPORT FrameLoadRequest(Frame*, const ResourceRequest&, const SubstituteData& = SubstituteData());
+    WEBCORE_EXPORT FrameLoadRequest(Frame*, const ResourceRequest&, ShouldOpenExternalURLsPolicy, const SubstituteData& = SubstituteData());
 
     bool isEmpty() const { return m_resourceRequest.isEmpty(); }
 
index 6521a3c..c9c5913 100644 (file)
@@ -317,11 +317,11 @@ void FrameLoader::changeLocation(const FrameLoadRequest& request)
     urlSelected(request, nullptr);
 }
 
-void FrameLoader::urlSelected(const URL& url, const String& passedTarget, Event* triggeringEvent, LockHistory lockHistory, LockBackForwardList lockBackForwardList, ShouldSendReferrer shouldSendReferrer)
+void FrameLoader::urlSelected(const URL& url, const String& passedTarget, Event* triggeringEvent, LockHistory lockHistory, LockBackForwardList lockBackForwardList, ShouldSendReferrer shouldSendReferrer, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy)
 {
     NewFrameOpenerPolicy newFrameOpenerPolicy = shouldSendReferrer == NeverSendReferrer ? NewFrameOpenerPolicy::Suppress : NewFrameOpenerPolicy::Allow;
 
-    urlSelected(FrameLoadRequest(m_frame.document()->securityOrigin(), ResourceRequest(url), passedTarget, lockHistory, lockBackForwardList, shouldSendReferrer, AllowNavigationToInvalidURL::Yes, newFrameOpenerPolicy, DoNotReplaceDocumentIfJavaScriptURL), triggeringEvent);
+    urlSelected(FrameLoadRequest(m_frame.document()->securityOrigin(), ResourceRequest(url), passedTarget, lockHistory, lockBackForwardList, shouldSendReferrer, AllowNavigationToInvalidURL::Yes, newFrameOpenerPolicy, DoNotReplaceDocumentIfJavaScriptURL, shouldOpenExternalURLsPolicy), triggeringEvent);
 }
 
 void FrameLoader::urlSelected(const FrameLoadRequest& passedRequest, Event* triggeringEvent)
@@ -671,7 +671,7 @@ void FrameLoader::receivedFirstData()
         completedURL = m_frame.document()->completeURL(urlString);
 
     if (!protocolIsJavaScript(completedURL))
-        m_frame.navigationScheduler().scheduleRedirect(delay, completedURL);
+        m_frame.navigationScheduler().scheduleRedirect(m_frame.document(), delay, completedURL);
     else {
         String message = "Refused to refresh " + m_frame.document()->url().stringCenterEllipsizedToLength() + " to a javascript: URL";
         m_frame.document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, message);
@@ -915,7 +915,7 @@ void FrameLoader::loadURLIntoChildFrame(const URL& url, const String& referer, F
         }
     }
 
-    FrameLoadRequest frameLoadRequest(m_frame.document()->securityOrigin(), ResourceRequest(url), "_self", LockHistory::No, LockBackForwardList::Yes, ShouldSendReferrer::MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress, ReplaceDocumentIfJavaScriptURL);
+    FrameLoadRequest frameLoadRequest(m_frame.document()->securityOrigin(), ResourceRequest(url), "_self", LockHistory::No, LockBackForwardList::Yes, ShouldSendReferrer::MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress, ReplaceDocumentIfJavaScriptURL, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
     childFrame->loader().loadURL(frameLoadRequest, referer, FrameLoadType::RedirectWithLockedBackForwardList, 0, 0);
 }
 
@@ -1230,7 +1230,7 @@ void FrameLoader::loadURL(const FrameLoadRequest& frameLoadRequest, const String
     if (m_pageDismissalEventBeingDispatched != NoDismissal)
         return;
 
-    NavigationAction action(request, newLoadType, isFormSubmission, event);
+    NavigationAction action(request, newLoadType, isFormSubmission, event, frameLoadRequest.shouldOpenExternalURLsPolicy());
 
     if (!targetFrame && !frameName.isEmpty()) {
         policyChecker().checkNewWindowPolicy(action, request, formState.release(), frameName, [this, allowNavigationToInvalidURL, openerPolicy](const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName, const NavigationAction& action, bool shouldContinue) {
@@ -1304,7 +1304,8 @@ void FrameLoader::load(const FrameLoadRequest& passedRequest)
     }
 
     if (request.shouldCheckNewWindowPolicy()) {
-        policyChecker().checkNewWindowPolicy(NavigationAction(request.resourceRequest(), NavigationType::Other), request.resourceRequest(), nullptr, request.frameName(), [this](const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName, const NavigationAction& action, bool shouldContinue) {
+        NavigationAction action(request.resourceRequest(), NavigationType::Other, passedRequest.shouldOpenExternalURLsPolicy());
+        policyChecker().checkNewWindowPolicy(action, request.resourceRequest(), nullptr, request.frameName(), [this](const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName, const NavigationAction& action, bool shouldContinue) {
             continueLoadAfterNewWindowPolicy(request, formState, frameName, action, shouldContinue, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress);
         });
 
@@ -1315,8 +1316,7 @@ void FrameLoader::load(const FrameLoadRequest& passedRequest)
         request.setSubstituteData(defaultSubstituteDataForURL(request.resourceRequest().url()));
 
     RefPtr<DocumentLoader> loader = m_client.createDocumentLoader(request.resourceRequest(), request.substituteData());
-    if (m_frame.isMainFrame())
-        loader->setShouldOpenExternalURLsPolicy(request.shouldOpenExternalURLsPolicy());
+    applyShouldOpenExternalURLsPolicyToNewDocumentLoader(*loader, request.shouldOpenExternalURLsPolicy());
 
     load(loader.get());
 }
@@ -1324,6 +1324,8 @@ void FrameLoader::load(const FrameLoadRequest& passedRequest)
 void FrameLoader::loadWithNavigationAction(const ResourceRequest& request, const NavigationAction& action, LockHistory lockHistory, FrameLoadType type, PassRefPtr<FormState> formState, AllowNavigationToInvalidURL allowNavigationToInvalidURL)
 {
     RefPtr<DocumentLoader> loader = m_client.createDocumentLoader(request, defaultSubstituteDataForURL(request.url()));
+    applyShouldOpenExternalURLsPolicyToNewDocumentLoader(*loader, action.shouldOpenExternalURLsPolicy());
+
     if (lockHistory == LockHistory::Yes && m_documentLoader)
         loader->setClientRedirectSourceForHistory(m_documentLoader->didCreateGlobalHistoryEntry() ? m_documentLoader->urlForHistory().string() : m_documentLoader->clientRedirectSourceForHistory());
 
@@ -1543,6 +1545,8 @@ void FrameLoader::reloadWithOverrideEncoding(const String& encoding)
     request.setCachePolicy(ReturnCacheDataElseLoad);
 
     RefPtr<DocumentLoader> loader = m_client.createDocumentLoader(request, defaultSubstituteDataForURL(request.url()));
+    applyShouldOpenExternalURLsPolicyToNewDocumentLoader(*loader, m_documentLoader->shouldOpenExternalURLsPolicyToPropagate());
+
     setPolicyDocumentLoader(loader.get());
 
     loader->setOverrideEncoding(encoding);
@@ -1569,6 +1573,7 @@ void FrameLoader::reload(bool endToEndReload)
     // Create a new document loader for the reload, this will become m_documentLoader eventually,
     // but first it has to be the "policy" document loader, and then the "provisional" document loader.
     RefPtr<DocumentLoader> loader = m_client.createDocumentLoader(initialRequest, defaultSubstituteDataForURL(initialRequest.url()));
+    applyShouldOpenExternalURLsPolicyToNewDocumentLoader(*loader, m_documentLoader->shouldOpenExternalURLsPolicyToPropagate());
 
     ResourceRequest& request = loader->request();
 
@@ -2643,7 +2648,7 @@ void FrameLoader::loadPostRequest(const FrameLoadRequest& request, const String&
     workingResourceRequest.setHTTPContentType(contentType);
     addExtraFieldsToRequest(workingResourceRequest, loadType, true);
 
-    NavigationAction action(workingResourceRequest, loadType, true, event);
+    NavigationAction action(workingResourceRequest, loadType, true, event, request.shouldOpenExternalURLsPolicy());
 
     if (!frameName.isEmpty()) {
         // The search for a target frame is done earlier in the case of form submission.
@@ -2991,7 +2996,9 @@ void FrameLoader::continueLoadAfterNewWindowPolicy(const ResourceRequest& reques
         mainFrame->loader().setOpener(frame.ptr());
         mainFrame->document()->setReferrerPolicy(frame->document()->referrerPolicy());
     }
-    mainFrame->loader().loadWithNavigationAction(request, NavigationAction(request), LockHistory::No, FrameLoadType::Standard, formState, allowNavigationToInvalidURL);
+
+    NavigationAction newAction(request, action.shouldOpenExternalURLsPolicy());
+    mainFrame->loader().loadWithNavigationAction(request, newAction, LockHistory::No, FrameLoadType::Standard, formState, allowNavigationToInvalidURL);
 }
 
 void FrameLoader::requestFromDelegate(ResourceRequest& request, unsigned long& identifier, ResourceError& error)
@@ -3425,6 +3432,16 @@ void FrameLoader::clearTestingOverrides()
     m_overrideResourceLoadPriorityForTesting = Nullopt;
 }
 
+void FrameLoader::applyShouldOpenExternalURLsPolicyToNewDocumentLoader(DocumentLoader& documentLoader, ShouldOpenExternalURLsPolicy propagatedPolicy)
+{
+    if (!m_frame.isMainFrame())
+        documentLoader.setShouldOpenExternalURLsPolicy(ShouldOpenExternalURLsPolicy::ShouldNotAllow);
+    else if (ScriptController::processingUserGesture())
+        documentLoader.setShouldOpenExternalURLsPolicy(ShouldOpenExternalURLsPolicy::ShouldAllow);
+    else
+        documentLoader.setShouldOpenExternalURLsPolicy(propagatedPolicy);
+}
+
 bool FrameLoaderClient::hasHTMLView() const
 {
     return true;
index abef843..3eab3f9 100644 (file)
@@ -119,7 +119,7 @@ public:
     unsigned long loadResourceSynchronously(const ResourceRequest&, StoredCredentials, ClientCredentialPolicy, ResourceError&, ResourceResponse&, RefPtr<SharedBuffer>& data);
 
     void changeLocation(const FrameLoadRequest&);
-    WEBCORE_EXPORT void urlSelected(const URL&, const String& target, Event*, LockHistory, LockBackForwardList, ShouldSendReferrer);
+    WEBCORE_EXPORT void urlSelected(const URL&, const String& target, Event*, LockHistory, LockBackForwardList, ShouldSendReferrer, ShouldOpenExternalURLsPolicy);
     void submitForm(PassRefPtr<FormSubmission>);
 
     WEBCORE_EXPORT void reload(bool endToEndReload = false);
@@ -378,6 +378,8 @@ private:
 
     void dispatchGlobalObjectAvailableInAllWorlds();
 
+    void applyShouldOpenExternalURLsPolicyToNewDocumentLoader(DocumentLoader&, ShouldOpenExternalURLsPolicy propagatedPolicy);
+
     Frame& m_frame;
     FrameLoaderClient& m_client;
 
index 6d3e46e..7c10dcf 100644 (file)
@@ -67,6 +67,11 @@ NavigationAction::NavigationAction(const ResourceRequest& resourceRequest)
 {
 }
 
+NavigationAction::NavigationAction(const ResourceRequest& resourceRequest, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy)
+    : NavigationAction(resourceRequest, NavigationType::Other, nullptr, shouldOpenExternalURLsPolicy)
+{
+}
+
 NavigationAction::NavigationAction(const ResourceRequest& resourceRequest, NavigationType type)
     : NavigationAction(resourceRequest, type, nullptr, ShouldOpenExternalURLsPolicy::ShouldNotAllow)
 {
@@ -92,4 +97,16 @@ NavigationAction::NavigationAction(const ResourceRequest& resourceRequest, Frame
 {
 }
 
+NavigationAction::NavigationAction(const ResourceRequest& resourceRequest, FrameLoadType frameLoadType, bool isFormSubmission, Event* event, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy)
+    : NavigationAction(resourceRequest, navigationType(frameLoadType, isFormSubmission, event), event, shouldOpenExternalURLsPolicy)
+{
+}
+
+NavigationAction NavigationAction::copyWithShouldOpenExternalURLsPolicy(ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy) const
+{
+    NavigationAction result(*this);
+    result.m_shouldOpenExternalURLsPolicy = shouldOpenExternalURLsPolicy;
+    return WTF::move(result);
+}
+
 }
index 9b5030c..48e8732 100644 (file)
@@ -43,10 +43,15 @@ public:
     WEBCORE_EXPORT explicit NavigationAction(const ResourceRequest&);
     WEBCORE_EXPORT NavigationAction(const ResourceRequest&, NavigationType);
     WEBCORE_EXPORT NavigationAction(const ResourceRequest&, FrameLoadType, bool isFormSubmission);
+
+    NavigationAction(const ResourceRequest&, ShouldOpenExternalURLsPolicy);
     NavigationAction(const ResourceRequest&, NavigationType, Event*);
     NavigationAction(const ResourceRequest&, NavigationType, Event*, ShouldOpenExternalURLsPolicy);
     NavigationAction(const ResourceRequest&, NavigationType, ShouldOpenExternalURLsPolicy);
     NavigationAction(const ResourceRequest&, FrameLoadType, bool isFormSubmission, Event*);
+    NavigationAction(const ResourceRequest&, FrameLoadType, bool isFormSubmission, Event*, ShouldOpenExternalURLsPolicy);
+
+    NavigationAction copyWithShouldOpenExternalURLsPolicy(ShouldOpenExternalURLsPolicy) const;
 
     bool isEmpty() const { return m_resourceRequest.url().isEmpty(); }
 
@@ -59,7 +64,6 @@ public:
     bool processingUserGesture() const { return m_processingUserGesture; }
 
     ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy() const { return m_shouldOpenExternalURLsPolicy; }
-    void setShouldOpenExternalURLsPolicy(ShouldOpenExternalURLsPolicy policy) { m_shouldOpenExternalURLsPolicy = policy; }
 
 private:
     ResourceRequest m_resourceRequest;
index cf7bdab..d95cedb 100644 (file)
@@ -87,6 +87,8 @@ public:
 protected:
     void clearUserGesture() { m_wasUserGesture = false; }
 
+    ShouldOpenExternalURLsPolicy m_shouldOpenExternalURLsPolicy { ShouldOpenExternalURLsPolicy::ShouldNotAllow };
+
 private:
     double m_delay;
     LockHistory m_lockHistory;
@@ -98,13 +100,15 @@ private:
 
 class ScheduledURLNavigation : public ScheduledNavigation {
 protected:
-    ScheduledURLNavigation(double delay, SecurityOrigin* securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList, bool duringLoad, bool isLocationChange)
+    ScheduledURLNavigation(Document* initiatingDocument, double delay, SecurityOrigin* securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList, bool duringLoad, bool isLocationChange)
         : ScheduledNavigation(delay, lockHistory, lockBackForwardList, duringLoad, isLocationChange)
         , m_securityOrigin(securityOrigin)
         , m_url(url)
         , m_referrer(referrer)
         , m_haveToldClient(false)
     {
+        if (initiatingDocument)
+            m_shouldOpenExternalURLsPolicy = initiatingDocument->shouldOpenExternalURLsPolicyToPropagate();
     }
 
     virtual void fire(Frame& frame) override
@@ -112,7 +116,7 @@ protected:
         UserGestureIndicator gestureIndicator(wasUserGesture() ? DefinitelyProcessingUserGesture : DefinitelyNotProcessingUserGesture);
 
         ResourceRequest resourceRequest(m_url, m_referrer, UseProtocolCachePolicy);
-        FrameLoadRequest frameRequest(m_securityOrigin.get(), resourceRequest, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow);
+        FrameLoadRequest frameRequest(m_securityOrigin.get(), resourceRequest, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, m_shouldOpenExternalURLsPolicy);
 
         frame.loader().changeLocation(frameRequest);
     }
@@ -154,8 +158,8 @@ private:
 
 class ScheduledRedirect : public ScheduledURLNavigation {
 public:
-    ScheduledRedirect(double delay, SecurityOrigin* securityOrigin, const URL& url, LockHistory lockHistory, LockBackForwardList lockBackForwardList)
-        : ScheduledURLNavigation(delay, securityOrigin, url, String(), lockHistory, lockBackForwardList, false, false)
+    ScheduledRedirect(Document* initiatingDocument, double delay, SecurityOrigin* securityOrigin, const URL& url, LockHistory lockHistory, LockBackForwardList lockBackForwardList)
+        : ScheduledURLNavigation(initiatingDocument, delay, securityOrigin, url, String(), lockHistory, lockBackForwardList, false, false)
     {
         clearUserGesture();
     }
@@ -170,7 +174,7 @@ public:
         UserGestureIndicator gestureIndicator(wasUserGesture() ? DefinitelyProcessingUserGesture : DefinitelyNotProcessingUserGesture);
         bool refresh = equalIgnoringFragmentIdentifier(frame.document()->url(), url());
         ResourceRequest resourceRequest(url(), referrer(), refresh ? ReloadIgnoringCacheData : UseProtocolCachePolicy);
-        FrameLoadRequest frameRequest(securityOrigin(), resourceRequest, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow);
+        FrameLoadRequest frameRequest(securityOrigin(), resourceRequest, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, m_shouldOpenExternalURLsPolicy);
 
         frame.loader().changeLocation(frameRequest);
     }
@@ -178,23 +182,23 @@ public:
 
 class ScheduledLocationChange : public ScheduledURLNavigation {
 public:
-    ScheduledLocationChange(SecurityOrigin* securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList, bool duringLoad)
-        : ScheduledURLNavigation(0.0, securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad, true) { }
+    ScheduledLocationChange(Document* initiatingDocument, SecurityOrigin* securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList, bool duringLoad)
+        : ScheduledURLNavigation(initiatingDocument, 0.0, securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad, true) { }
 
     virtual void fire(Frame& frame) override
     {
         UserGestureIndicator gestureIndicator(wasUserGesture() ? DefinitelyProcessingUserGesture : DefinitelyNotProcessingUserGesture);
 
         ResourceRequest resourceRequest(url(), referrer(), UseProtocolCachePolicy);
-        FrameLoadRequest frameRequest(securityOrigin(), resourceRequest, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow);
+        FrameLoadRequest frameRequest(securityOrigin(), resourceRequest, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, m_shouldOpenExternalURLsPolicy);
         frame.loader().changeLocation(frameRequest);
     }
 };
 
 class ScheduledRefresh : public ScheduledURLNavigation {
 public:
-    ScheduledRefresh(SecurityOrigin* securityOrigin, const URL& url, const String& referrer)
-        : ScheduledURLNavigation(0.0, securityOrigin, url, referrer, LockHistory::Yes, LockBackForwardList::Yes, false, true)
+    ScheduledRefresh(Document* initiatingDocument, SecurityOrigin* securityOrigin, const URL& url, const String& referrer)
+        : ScheduledURLNavigation(initiatingDocument, 0.0, securityOrigin, url, referrer, LockHistory::Yes, LockBackForwardList::Yes, false, true)
     {
     }
 
@@ -203,7 +207,7 @@ public:
         UserGestureIndicator gestureIndicator(wasUserGesture() ? DefinitelyProcessingUserGesture : DefinitelyNotProcessingUserGesture);
 
         ResourceRequest resourceRequest(url(), referrer(), ReloadIgnoringCacheData);
-        FrameLoadRequest frameRequest(securityOrigin(), resourceRequest, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow);
+        FrameLoadRequest frameRequest(securityOrigin(), resourceRequest, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, m_shouldOpenExternalURLsPolicy);
         frame.loader().changeLocation(frameRequest);
     }
 };
@@ -223,7 +227,7 @@ public:
         if (!m_historySteps) {
             // Special case for go(0) from a frame -> reload only the frame
             // To follow Firefox and IE's behavior, history reload can only navigate the self frame.
-            frame.loader().urlSelected(frame.document()->url(), "_self", 0, lockHistory(), lockBackForwardList(), MaybeSendReferrer);
+            frame.loader().urlSelected(frame.document()->url(), "_self", 0, lockHistory(), lockBackForwardList(), MaybeSendReferrer, m_shouldOpenExternalURLsPolicy);
             return;
         }
         
@@ -244,6 +248,9 @@ public:
         , m_haveToldClient(false)
     {
         ASSERT(m_submission->state());
+
+        if (Document* document = m_submission->state()->sourceDocument())
+            m_shouldOpenExternalURLsPolicy = document->shouldOpenExternalURLsPolicyToPropagate();
     }
 
     virtual void fire(Frame& frame) override
@@ -257,7 +264,7 @@ public:
         Document* requestingDocument = m_submission->state()->sourceDocument();
         if (!requestingDocument->canNavigate(&frame))
             return;
-        FrameLoadRequest frameRequest(requestingDocument->securityOrigin(), lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow);
+        FrameLoadRequest frameRequest(requestingDocument->securityOrigin(), lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, m_shouldOpenExternalURLsPolicy);
         m_submission->populateFrameLoadRequest(frameRequest);
         frame.loader().loadFrameRequest(frameRequest, m_submission->event(), m_submission->state());
     }
@@ -303,7 +310,7 @@ public:
     void fire(Frame& frame) override
     {
         UserGestureIndicator gestureIndicator { wasUserGesture() ? DefinitelyProcessingUserGesture : DefinitelyNotProcessingUserGesture };
-        frame.loader().load(FrameLoadRequest { &frame, m_baseURL, m_substituteData });
+        frame.loader().load(FrameLoadRequest { &frame, m_baseURL, m_shouldOpenExternalURLsPolicy, m_substituteData });
     }
 
 private:
@@ -353,7 +360,7 @@ inline bool NavigationScheduler::shouldScheduleNavigation(const URL& url) const
     return NavigationDisablerForBeforeUnload::isNavigationAllowed();
 }
 
-void NavigationScheduler::scheduleRedirect(double delay, const URL& url)
+void NavigationScheduler::scheduleRedirect(Document* initiatingDocument, double delay, const URL& url)
 {
     if (!shouldScheduleNavigation(url))
         return;
@@ -365,7 +372,7 @@ void NavigationScheduler::scheduleRedirect(double delay, const URL& url)
     // We want a new back/forward list item if the refresh timeout is > 1 second.
     if (!m_redirect || delay <= m_redirect->delay()) {
         LockBackForwardList lockBackForwardList = delay <= 1 ? LockBackForwardList::Yes : LockBackForwardList::No;
-        schedule(std::make_unique<ScheduledRedirect>(delay, m_frame.document()->securityOrigin(), url, LockHistory::Yes, lockBackForwardList));
+        schedule(std::make_unique<ScheduledRedirect>(initiatingDocument, delay, m_frame.document()->securityOrigin(), url, LockHistory::Yes, lockBackForwardList));
     }
 }
 
@@ -387,7 +394,7 @@ LockBackForwardList NavigationScheduler::mustLockBackForwardList(Frame& targetFr
     return LockBackForwardList::No;
 }
 
-void NavigationScheduler::scheduleLocationChange(SecurityOrigin* securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList)
+void NavigationScheduler::scheduleLocationChange(Document* initiatingDocument, SecurityOrigin* securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList)
 {
     if (!shouldScheduleNavigation(url))
         return;
@@ -401,7 +408,10 @@ void NavigationScheduler::scheduleLocationChange(SecurityOrigin* securityOrigin,
     // fragment part, we don't need to schedule the location change.
     if (url.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(m_frame.document()->url(), url)) {
         ResourceRequest resourceRequest(m_frame.document()->completeURL(url), referrer, UseProtocolCachePolicy);
-        FrameLoadRequest frameRequest(securityOrigin, resourceRequest, emptyString(), lockHistory, lockBackForwardList, MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, ReplaceDocumentIfJavaScriptURL);
+        ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy = ShouldOpenExternalURLsPolicy::ShouldNotAllow;
+        if (initiatingDocument)
+            shouldOpenExternalURLsPolicy = initiatingDocument->shouldOpenExternalURLsPolicyToPropagate();
+        FrameLoadRequest frameRequest(securityOrigin, resourceRequest, emptyString(), lockHistory, lockBackForwardList, MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, ReplaceDocumentIfJavaScriptURL, shouldOpenExternalURLsPolicy);
         loader.changeLocation(frameRequest);
         return;
     }
@@ -410,7 +420,7 @@ void NavigationScheduler::scheduleLocationChange(SecurityOrigin* securityOrigin,
     // This may happen when a frame changes the location of another frame.
     bool duringLoad = !loader.stateMachine().committedFirstRealDocumentLoad();
 
-    schedule(std::make_unique<ScheduledLocationChange>(securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad));
+    schedule(std::make_unique<ScheduledLocationChange>(initiatingDocument, securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad));
 }
 
 void NavigationScheduler::scheduleFormSubmission(PassRefPtr<FormSubmission> submission)
@@ -436,7 +446,7 @@ void NavigationScheduler::scheduleFormSubmission(PassRefPtr<FormSubmission> subm
     schedule(std::make_unique<ScheduledFormSubmission>(submission, lockBackForwardList, duringLoad));
 }
 
-void NavigationScheduler::scheduleRefresh()
+void NavigationScheduler::scheduleRefresh(Document* initiatingDocument)
 {
     if (!shouldScheduleNavigation())
         return;
@@ -444,7 +454,7 @@ void NavigationScheduler::scheduleRefresh()
     if (url.isEmpty())
         return;
 
-    schedule(std::make_unique<ScheduledRefresh>(m_frame.document()->securityOrigin(), url, m_frame.loader().outgoingReferrer()));
+    schedule(std::make_unique<ScheduledRefresh>(initiatingDocument, m_frame.document()->securityOrigin(), url, m_frame.loader().outgoingReferrer()));
 }
 
 void NavigationScheduler::scheduleHistoryNavigation(int steps)
index 4ae5b10..dd61a76 100644 (file)
@@ -37,6 +37,7 @@
 
 namespace WebCore {
 
+class Document;
 class FormSubmission;
 class Frame;
 class ScheduledNavigation;
@@ -69,10 +70,10 @@ public:
     bool redirectScheduledDuringLoad();
     bool locationChangePending();
 
-    void scheduleRedirect(double delay, const URL&);
-    void scheduleLocationChange(SecurityOrigin*, const URL&, const String& referrer, LockHistory = LockHistory::Yes, LockBackForwardList = LockBackForwardList::Yes);
+    void scheduleRedirect(Document* initiatingDocument, double delay, const URL&);
+    void scheduleLocationChange(Document* initiatingDocument, SecurityOrigin*, const URL&, const String& referrer, LockHistory = LockHistory::Yes, LockBackForwardList = LockBackForwardList::Yes);
     void scheduleFormSubmission(PassRefPtr<FormSubmission>);
-    void scheduleRefresh();
+    void scheduleRefresh(Document* initiatingDocument);
     void scheduleHistoryNavigation(int steps);
     void scheduleSubstituteDataLoad(const URL& baseURL, const SubstituteData&);
 
index 1bb99a6..a216e50 100644 (file)
@@ -65,7 +65,7 @@ void PolicyChecker::checkNavigationPolicy(const ResourceRequest& request, Docume
 {
     NavigationAction action = loader->triggeringAction();
     if (action.isEmpty()) {
-        action = NavigationAction(request, NavigationType::Other, loader->shouldOpenExternalURLsPolicy());
+        action = NavigationAction(request, NavigationType::Other, loader->shouldOpenExternalURLsPolicyToPropagate());
         loader->setTriggeringAction(action);
     }
 
index b0fd52f..7f0cf07 100644 (file)
@@ -284,7 +284,7 @@ Frame* SubframeLoader::loadOrRedirectSubframe(HTMLFrameOwnerElement& ownerElemen
 {
     Frame* frame = ownerElement.contentFrame();
     if (frame)
-        frame->navigationScheduler().scheduleLocationChange(m_frame.document()->securityOrigin(), url, m_frame.loader().outgoingReferrer(), lockHistory, lockBackForwardList);
+        frame->navigationScheduler().scheduleLocationChange(m_frame.document(), m_frame.document()->securityOrigin(), url, m_frame.loader().outgoingReferrer(), lockHistory, lockBackForwardList);
     else
         frame = loadSubframe(ownerElement, url, frameName, m_frame.loader().outgoingReferrer());
 
index 768f4f9..627c0fe 100644 (file)
@@ -173,7 +173,7 @@ void ApplicationCacheGroup::selectCache(Frame* frame, const URL& passedManifestU
             // Restart the current navigation from the top of the navigation algorithm, undoing any changes that were made
             // as part of the initial load.
             // The navigation will not result in the same resource being loaded, because "foreign" entries are never picked during navigation.
-            frame->navigationScheduler().scheduleLocationChange(frame->document()->securityOrigin(), documentLoader->url(), frame->loader().referrer());
+            frame->navigationScheduler().scheduleLocationChange(frame->document(), frame->document()->securityOrigin(), documentLoader->url(), frame->loader().referrer());
         }
         
         return;
index 3892d64..d24fb31 100644 (file)
@@ -190,13 +190,13 @@ void ContextMenuController::showContextMenu(Event* event)
     event->setDefaultHandled();
 }
 
-static void openNewWindow(const URL& urlToLoad, Frame* frame)
+static void openNewWindow(const URL& urlToLoad, Frame* frame, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy)
 {
     Page* oldPage = frame->page();
     if (!oldPage)
         return;
-    
-    FrameLoadRequest request(frame->document()->securityOrigin(), ResourceRequest(urlToLoad, frame->loader().outgoingReferrer()), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress);
+
+    FrameLoadRequest request(frame->document()->securityOrigin(), ResourceRequest(urlToLoad, frame->loader().outgoingReferrer()), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress, shouldOpenExternalURLsPolicy);
 
     Page* newPage = oldPage->chrome().createWindow(frame, request, WindowFeatures(), NavigationAction(request.resourceRequest()));
     if (!newPage)
@@ -238,7 +238,7 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
 
     switch (item->action()) {
     case ContextMenuItemTagOpenLinkInNewWindow:
-        openNewWindow(m_context.hitTestResult().absoluteLinkURL(), frame);
+        openNewWindow(m_context.hitTestResult().absoluteLinkURL(), frame, ShouldOpenExternalURLsPolicy::ShouldAllow);
         break;
     case ContextMenuItemTagDownloadLinkToDisk:
         // FIXME: Some day we should be able to do this from within WebCore. (Bug 117709)
@@ -248,7 +248,7 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
         frame->editor().copyURL(m_context.hitTestResult().absoluteLinkURL(), m_context.hitTestResult().textContent());
         break;
     case ContextMenuItemTagOpenImageInNewWindow:
-        openNewWindow(m_context.hitTestResult().absoluteImageURL(), frame);
+        openNewWindow(m_context.hitTestResult().absoluteImageURL(), frame, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
         break;
     case ContextMenuItemTagDownloadImageToDisk:
         // FIXME: Some day we should be able to do this from within WebCore. (Bug 117709)
@@ -265,7 +265,7 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
         break;
 #endif
     case ContextMenuItemTagOpenMediaInNewWindow:
-        openNewWindow(m_context.hitTestResult().absoluteMediaURL(), frame);
+        openNewWindow(m_context.hitTestResult().absoluteMediaURL(), frame, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
         break;
     case ContextMenuItemTagDownloadMediaToDisk:
         // FIXME: Some day we should be able to do this from within WebCore. (Bug 117709)
@@ -295,9 +295,9 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
     case ContextMenuItemTagOpenFrameInNewWindow: {
         DocumentLoader* loader = frame->loader().documentLoader();
         if (!loader->unreachableURL().isEmpty())
-            openNewWindow(loader->unreachableURL(), frame);
+            openNewWindow(loader->unreachableURL(), frame, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
         else
-            openNewWindow(loader->url(), frame);
+            openNewWindow(loader->url(), frame, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
         break;
     }
     case ContextMenuItemTagCopy:
@@ -401,12 +401,12 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
         break;
     case ContextMenuItemTagOpenLink:
         if (Frame* targetFrame = m_context.hitTestResult().targetFrame())
-            targetFrame->loader().loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(m_context.hitTestResult().absoluteLinkURL(), frame->loader().outgoingReferrer()), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress), nullptr, nullptr);
+            targetFrame->loader().loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(m_context.hitTestResult().absoluteLinkURL(), frame->loader().outgoingReferrer()), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress, targetFrame->isMainFrame() ? ShouldOpenExternalURLsPolicy::ShouldAllow : ShouldOpenExternalURLsPolicy::ShouldNotAllow), nullptr, nullptr);
         else
-            openNewWindow(m_context.hitTestResult().absoluteLinkURL(), frame);
+            openNewWindow(m_context.hitTestResult().absoluteLinkURL(), frame, ShouldOpenExternalURLsPolicy::ShouldAllow);
         break;
     case ContextMenuItemTagOpenLinkInThisWindow:
-        frame->loader().loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(m_context.hitTestResult().absoluteLinkURL(), frame->loader().outgoingReferrer()), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress), nullptr, nullptr);
+        frame->loader().loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(m_context.hitTestResult().absoluteLinkURL(), frame->loader().outgoingReferrer()), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress, ShouldOpenExternalURLsPolicy::ShouldAllow), nullptr, nullptr);
         break;
     case ContextMenuItemTagBold:
         frame->editor().command("ToggleBold").execute();
index b2a7d7c..3639d6b 100644 (file)
@@ -1992,7 +1992,7 @@ void DOMWindow::setLocation(const String& urlString, DOMWindow& activeWindow, DO
     // We want a new history item if we are processing a user gesture.
     LockHistory lockHistory = (locking != LockHistoryBasedOnGestureState || !ScriptController::processingUserGesture()) ? LockHistory::Yes : LockHistory::No;
     LockBackForwardList lockBackForwardList = (locking != LockHistoryBasedOnGestureState) ? LockBackForwardList::Yes : LockBackForwardList::No;
-    m_frame->navigationScheduler().scheduleLocationChange(activeDocument->securityOrigin(),
+    m_frame->navigationScheduler().scheduleLocationChange(activeDocument, activeDocument->securityOrigin(),
         // FIXME: What if activeDocument()->frame() is 0?
         completedURL, activeDocument->frame()->loader().outgoingReferrer(),
         lockHistory, lockBackForwardList);
@@ -2078,6 +2078,10 @@ RefPtr<Frame> DOMWindow::createWindow(const String& urlString, const AtomicStrin
     if (!activeFrame)
         return nullptr;
 
+    Document* activeDocument = activeWindow.document();
+    if (!activeDocument)
+        return nullptr;
+
     URL completedURL = urlString.isEmpty() ? URL(ParsedURLString, emptyString()) : firstFrame.document()->completeURL(urlString);
     if (!completedURL.isEmpty() && !completedURL.isValid()) {
         // Don't expose client code to invalid URLs.
@@ -2090,7 +2094,7 @@ RefPtr<Frame> DOMWindow::createWindow(const String& urlString, const AtomicStrin
 
     ResourceRequest request(completedURL, referrer);
     FrameLoader::addHTTPOriginIfNeeded(request, firstFrame.loader().outgoingOrigin());
-    FrameLoadRequest frameRequest(activeWindow.document()->securityOrigin(), request, frameName, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ReplaceDocumentIfJavaScriptURL);
+    FrameLoadRequest frameRequest(activeDocument->securityOrigin(), request, frameName, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ReplaceDocumentIfJavaScriptURL, activeDocument->shouldOpenExternalURLsPolicyToPropagate());
 
     // We pass the opener frame for the lookupFrame in case the active frame is different from
     // the opener frame, and the name references a frame relative to the opener frame.
@@ -2110,11 +2114,11 @@ RefPtr<Frame> DOMWindow::createWindow(const String& urlString, const AtomicStrin
 
     if (created) {
         ResourceRequest resourceRequest(completedURL, referrer, UseProtocolCachePolicy);
-        FrameLoadRequest frameRequest(activeWindow.document()->securityOrigin(), resourceRequest, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow);
+        FrameLoadRequest frameRequest(activeWindow.document()->securityOrigin(), resourceRequest, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, activeDocument->shouldOpenExternalURLsPolicyToPropagate());
         newFrame->loader().changeLocation(frameRequest);
     } else if (!urlString.isEmpty()) {
         LockHistory lockHistory = ScriptController::processingUserGesture() ? LockHistory::No : LockHistory::Yes;
-        newFrame->navigationScheduler().scheduleLocationChange(activeWindow.document()->securityOrigin(), completedURL, referrer, lockHistory, LockBackForwardList::No);
+        newFrame->navigationScheduler().scheduleLocationChange(activeWindow.document(), activeWindow.document()->securityOrigin(), completedURL, referrer, lockHistory, LockBackForwardList::No);
     }
 
     // Navigating the new frame could result in it being detached from its page by a navigation policy delegate.
@@ -2129,9 +2133,11 @@ PassRefPtr<DOMWindow> DOMWindow::open(const String& urlString, const AtomicStrin
 {
     if (!isCurrentlyDisplayedInFrame())
         return nullptr;
+
     Document* activeDocument = activeWindow.document();
     if (!activeDocument)
         return nullptr;
+
     Frame* firstFrame = firstWindow.frame();
     if (!firstFrame)
         return nullptr;
@@ -2183,7 +2189,7 @@ PassRefPtr<DOMWindow> DOMWindow::open(const String& urlString, const AtomicStrin
         // For whatever reason, Firefox uses the first window rather than the active window to
         // determine the outgoing referrer. We replicate that behavior here.
         LockHistory lockHistory = ScriptController::processingUserGesture() ? LockHistory::No : LockHistory::Yes;
-        targetFrame->navigationScheduler().scheduleLocationChange(activeDocument->securityOrigin(), completedURL, firstFrame->loader().outgoingReferrer(),
+        targetFrame->navigationScheduler().scheduleLocationChange(activeDocument, activeDocument->securityOrigin(), completedURL, firstFrame->loader().outgoingReferrer(),
             lockHistory, LockBackForwardList::No);
         return targetFrame->document()->domWindow();
     }
index 283d23a..1e3f43c 100644 (file)
@@ -216,6 +216,11 @@ DragOperation DragController::dragUpdated(DragData& dragData)
 bool DragController::performDragOperation(DragData& dragData)
 {
     m_documentUnderMouse = m_page.mainFrame().documentAtPoint(dragData.clientPosition());
+
+    ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy = ShouldOpenExternalURLsPolicy::ShouldNotAllow;
+    if (m_documentUnderMouse)
+        shouldOpenExternalURLsPolicy = m_documentUnderMouse->shouldOpenExternalURLsPolicyToPropagate();
+
     if ((m_dragDestinationAction & DragDestinationActionDHTML) && m_documentIsHandlingDrag) {
         m_client.willPerformDragDestinationAction(DragDestinationActionDHTML, dragData);
         Ref<MainFrame> mainFrame(m_page.mainFrame());
@@ -245,7 +250,7 @@ bool DragController::performDragOperation(DragData& dragData)
         return false;
 
     m_client.willPerformDragDestinationAction(DragDestinationActionLoad, dragData);
-    m_page.mainFrame().loader().load(FrameLoadRequest(&m_page.mainFrame(), ResourceRequest(dragData.asURL())));
+    m_page.mainFrame().loader().load(FrameLoadRequest(&m_page.mainFrame(), ResourceRequest(dragData.asURL()), shouldOpenExternalURLsPolicy));
     return true;
 }
 
index 44f5220..4317d80 100644 (file)
@@ -258,7 +258,7 @@ void Location::reload(DOMWindow& activeWindow)
     }
     if (protocolIsJavaScript(m_frame->document()->url()))
         return;
-    m_frame->navigationScheduler().scheduleRefresh();
+    m_frame->navigationScheduler().scheduleRefresh(activeWindow.document());
 }
 
 void Location::setLocation(const String& url, DOMWindow& activeWindow, DOMWindow& firstWindow)
index 6454a48..84752a2 100644 (file)
@@ -50,7 +50,8 @@ void EndSegmentSentinel::dispatch(ReplayController&)
 // Navigation inputs.
 void InitialNavigation::dispatch(ReplayController& controller)
 {
-    controller.page().mainFrame().navigationScheduler().scheduleLocationChange(m_securityOrigin.get(), m_url, m_referrer);
+    Frame& frame = controller.page().mainFrame();
+    frame.navigationScheduler().scheduleLocationChange(frame.document(), m_securityOrigin.get(), m_url, m_referrer);
 }
 
 void HandleKeyPress::dispatch(ReplayController& controller)
index 1a2846b..e5ce513 100644 (file)
@@ -145,7 +145,7 @@ void SVGAElement::defaultEventHandler(Event* event)
             Frame* frame = document().frame();
             if (!frame)
                 return;
-            frame->loader().urlSelected(document().completeURL(url), target, event, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer);
+            frame->loader().urlSelected(document().completeURL(url), target, event, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, document().shouldOpenExternalURLsPolicyToPropagate());
             return;
         }
     }
index ae4f6fc..d77f9bf 100644 (file)
@@ -1,3 +1,13 @@
+2015-06-02  Brady Eidson  <beidson@apple.com>
+
+        WebKit policy delegate should suggest if a navigation should be allowed to open URLs externally.
+        rdar://problem/21025301 and https://bugs.webkit.org/show_bug.cgi?id=145280
+
+        Reviewed by Alex Christensen.
+
+        * WebView/WebPDFViewPlaceholder.mm:
+        (-[WebPDFViewPlaceholder simulateClickOnLinkToURL:]):
+
 2015-05-25  Dan Bernstein  <mitz@apple.com>
 
         ASSERT_MAIN_THREAD and DOM_ASSERT_MAIN_THREAD are unnecessary no-ops
index a805710..3da4421 100644 (file)
@@ -475,7 +475,7 @@ static const float PAGE_HEIGHT_INSET = 4.0f * 2.0f;
 
     // Call to the frame loader because this is where our security checks are made.
     Frame* frame = core([_dataSource webFrame]);
-    frame->loader().loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(URL), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow), event.get(), nullptr);
+    frame->loader().loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(URL), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow), event.get(), nullptr);
 }
 
 @end
index e669c68..b895b91 100644 (file)
@@ -1,3 +1,20 @@
+2015-06-02  Brady Eidson  <beidson@apple.com>
+
+        WebKit policy delegate should suggest if a navigation should be allowed to open URLs externally.
+        rdar://problem/21025301 and https://bugs.webkit.org/show_bug.cgi?id=145280
+
+        Reviewed by Alex Christensen.
+
+        * Plugins/WebPluginController.mm:
+        (-[WebPluginController webPlugInContainerLoadRequest:inFrame:]):
+        
+        * WebView/WebFrame.mm:
+        (-[WebFrame loadRequest:]):
+        (-[WebFrame _loadData:MIMEType:textEncodingName:baseURL:unreachableURL:]):
+        
+        * WebView/WebPDFView.mm:
+        (-[WebPDFView PDFViewWillClickOnLink:withURL:]):
+
 2015-06-01  Anders Carlsson  <andersca@apple.com>
 
         WAKScrollView.h cannot be imported standalone
index 8db02f7..77e9a8f 100644 (file)
@@ -516,7 +516,7 @@ static void cancelOutstandingCheck(const void *item, void *context)
             LOG_ERROR("could not load URL %@", [request URL]);
             return;
         }
-        FrameLoadRequest frameRequest(core(frame), request);
+        FrameLoadRequest frameRequest(core(frame), request, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
         frameRequest.setFrameName(target);
         frameRequest.setShouldCheckNewWindowPolicy(true);
         core(frame)->loader().load(frameRequest);
index 629fa8e..799a4b6 100644 (file)
@@ -2479,7 +2479,7 @@ static bool needsMicrosoftMessengerDOMDocumentWorkaround()
     if (!resourceRequest.url().isValid() && !resourceRequest.url().isEmpty())
         resourceRequest.setURL([NSURL URLWithString:[@"file:" stringByAppendingString:[[request URL] absoluteString]]]);
 
-    coreFrame->loader().load(FrameLoadRequest(coreFrame, resourceRequest));
+    coreFrame->loader().load(FrameLoadRequest(coreFrame, resourceRequest, ShouldOpenExternalURLsPolicy::ShouldNotAllow));
 }
 
 static NSURL *createUniqueWebDataURL()
@@ -2511,7 +2511,7 @@ static NSURL *createUniqueWebDataURL()
     if (shouldUseQuickLookForMIMEType(MIMEType)) {
         NSURL *quickLookURL = responseURL ? responseURL : baseURL;
         if (auto request = registerQLPreviewConverterIfNeeded(quickLookURL, MIMEType, data)) {
-            _private->coreFrame->loader().load(FrameLoadRequest(_private->coreFrame, request.get()));
+            _private->coreFrame->loader().load(FrameLoadRequest(_private->coreFrame, request.get(), ShouldOpenExternalURLsPolicy::ShouldNotAllow));
             return;
         }
     }
@@ -2527,7 +2527,7 @@ static NSURL *createUniqueWebDataURL()
     ResourceResponse response(responseURL, MIMEType, [data length], encodingName);
     SubstituteData substituteData(WebCore::SharedBuffer::wrapNSData(data), [unreachableURL absoluteURL], response, SubstituteData::SessionHistoryVisibility::Hidden);
 
-    _private->coreFrame->loader().load(FrameLoadRequest(_private->coreFrame, request, substituteData));
+    _private->coreFrame->loader().load(FrameLoadRequest(_private->coreFrame, request, ShouldOpenExternalURLsPolicy::ShouldNotAllow, substituteData));
 }
 
 - (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)baseURL
index 5e7bb14..1ef1af0 100644 (file)
@@ -1037,7 +1037,7 @@ static BOOL isFrameInRange(WebFrame *frame, DOMRange *range)
 
     // Call to the frame loader because this is where our security checks are made.
     Frame* frame = core([dataSource webFrame]);
-    frame->loader().loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(URL), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow), event.get(), nullptr);
+    frame->loader().loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(URL), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow), event.get(), nullptr);
 }
 
 - (void)PDFViewOpenPDFInNativeApplication:(PDFView *)sender
index 42a5b54..73a33de 100644 (file)
@@ -1,3 +1,24 @@
+2015-06-02  Brady Eidson  <beidson@apple.com>
+
+        WebKit policy delegate should suggest if a navigation should be allowed to open URLs externally.
+        rdar://problem/21025301 and https://bugs.webkit.org/show_bug.cgi?id=145280
+
+        Reviewed by Alex Christensen.
+
+        * Plugins/PluginView.cpp:
+        (WebCore::PluginView::start):
+        (WebCore::PluginView::performRequest):
+        (WebCore::PluginView::getURLNotify):
+        (WebCore::PluginView::getURL):
+        (WebCore::PluginView::handlePost):
+        
+        * WebCoreSupport/WebContextMenuClient.cpp:
+        (WebContextMenuClient::searchWithGoogle):
+        
+        * WebFrame.cpp:
+        (WebFrame::loadRequest):
+        (WebFrame::loadData):
+
 2015-05-26  Jon Honeycutt  <jhoneycutt@apple.com>
 
         [iOS] When viewing an MJPEG stream as the main resource, only the first
index bfbefe6..59420b9 100644 (file)
@@ -249,7 +249,7 @@ bool PluginView::start()
     m_isStarted = true;
 
     if (!m_url.isEmpty() && !m_loadManually) {
-        FrameLoadRequest frameLoadRequest(m_parentFrame->document()->securityOrigin(), LockHistory::No, LockBackForwardList::No, ShouldSendReferrer::MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow);
+        FrameLoadRequest frameLoadRequest(m_parentFrame->document()->securityOrigin(), LockHistory::No, LockBackForwardList::No, ShouldSendReferrer::MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
         frameLoadRequest.resourceRequest().setHTTPMethod("GET");
         frameLoadRequest.resourceRequest().setURL(m_url);
         load(frameLoadRequest, false, 0);
@@ -413,7 +413,7 @@ void PluginView::performRequest(PluginRequest* request)
             // PluginView, so we protect it. <rdar://problem/6991251>
             RefPtr<PluginView> protect(this);
 
-            FrameLoadRequest frameRequest(m_parentFrame.get(), request->frameLoadRequest().resourceRequest());
+            FrameLoadRequest frameRequest(m_parentFrame.get(), request->frameLoadRequest().resourceRequest(), ShouldOpenExternalURLsPolicy::ShouldNotAllow);
             frameRequest.setFrameName(targetFrameName);
             frameRequest.setShouldCheckNewWindowPolicy(true);
             m_parentFrame->loader().load(frameRequest);
@@ -523,7 +523,7 @@ static URL makeURL(const URL& baseURL, const char* relativeURLString)
 
 NPError PluginView::getURLNotify(const char* url, const char* target, void* notifyData)
 {
-    FrameLoadRequest frameLoadRequest(m_parentFrame->document()->securityOrigin(), LockHistory::No, LockBackForwardList::No, ShouldSendReferrer::MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow);
+    FrameLoadRequest frameLoadRequest(m_parentFrame->document()->securityOrigin(), LockHistory::No, LockBackForwardList::No, ShouldSendReferrer::MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
 
     frameLoadRequest.setFrameName(target);
     frameLoadRequest.resourceRequest().setHTTPMethod("GET");
@@ -534,7 +534,7 @@ NPError PluginView::getURLNotify(const char* url, const char* target, void* noti
 
 NPError PluginView::getURL(const char* url, const char* target)
 {
-    FrameLoadRequest frameLoadRequest(m_parentFrame->document()->securityOrigin(), LockHistory::No, LockBackForwardList::No, ShouldSendReferrer::MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow);
+    FrameLoadRequest frameLoadRequest(m_parentFrame->document()->securityOrigin(), LockHistory::No, LockBackForwardList::No, ShouldSendReferrer::MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
 
     frameLoadRequest.setFrameName(target);
     frameLoadRequest.resourceRequest().setHTTPMethod("GET");
@@ -1036,7 +1036,7 @@ NPError PluginView::handlePost(const char* url, const char* target, uint32_t len
     if (!url || !len || !buf)
         return NPERR_INVALID_PARAM;
 
-    FrameLoadRequest frameLoadRequest(m_parentFrame->document()->securityOrigin(), LockHistory::No, LockBackForwardList::No, ShouldSendReferrer::MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow);
+    FrameLoadRequest frameLoadRequest(m_parentFrame->document()->securityOrigin(), LockHistory::No, LockBackForwardList::No, ShouldSendReferrer::MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
 
     HTTPHeaderMap headerFields;
     Vector<char> buffer;
index b261b97..374fe6e 100644 (file)
@@ -120,7 +120,7 @@ void WebContextMenuClient::searchWithGoogle(const Frame* frame)
 
     if (Page* page = frame->page()) {
         UserGestureIndicator indicator(DefinitelyProcessingUserGesture);
-        page->mainFrame().loader().urlSelected(URL(ParsedURLString, url), String(), 0, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer);
+        page->mainFrame().loader().urlSelected(URL(ParsedURLString, url), String(), 0, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
     }
 }
 
index b758d0d..f476470 100644 (file)
@@ -546,7 +546,7 @@ HRESULT STDMETHODCALLTYPE WebFrame::loadRequest(
     if (!coreFrame)
         return E_FAIL;
 
-    coreFrame->loader().load(FrameLoadRequest(coreFrame, requestImpl->resourceRequest()));
+    coreFrame->loader().load(FrameLoadRequest(coreFrame, requestImpl->resourceRequest(), ShouldOpenExternalURLsPolicy::ShouldNotAllow));
     return S_OK;
 }
 
@@ -571,7 +571,7 @@ void WebFrame::loadData(PassRefPtr<WebCore::SharedBuffer> data, BSTR mimeType, B
 
     // This method is only called from IWebFrame methods, so don't ASSERT that the Frame pointer isn't null.
     if (Frame* coreFrame = core(this))
-        coreFrame->loader().load(FrameLoadRequest(coreFrame, request, substituteData));
+        coreFrame->loader().load(FrameLoadRequest(coreFrame, request, ShouldOpenExternalURLsPolicy::ShouldNotAllow, substituteData));
 }
 
 
index db9584d..8e49ca3 100644 (file)
@@ -1,3 +1,32 @@
+2015-06-02  Brady Eidson  <beidson@apple.com>
+
+        WebKit policy delegate should suggest if a navigation should be allowed to open URLs externally.
+        rdar://problem/21025301 and https://bugs.webkit.org/show_bug.cgi?id=145280
+        
+        Reviewed by Alex Christensen.
+
+        * WebProcess/Plugins/PDF/PDFPlugin.mm:
+        (WebKit::PDFPlugin::clickedLink):
+        
+        * WebProcess/Plugins/PluginView.cpp:
+        (WebKit::PluginView::performFrameLoadURLRequest):
+        (WebKit::PluginView::loadURL):
+        
+        * WebProcess/WebCoreSupport/WebContextMenuClient.cpp:
+        (WebKit::WebContextMenuClient::searchWithGoogle):
+        
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+        (WebKit::WebFrameLoaderClient::dispatchCreatePage):
+        
+        * WebProcess/WebPage/WebInspector.cpp:
+        (WebKit::WebInspector::openInNewTab):
+        
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::loadURLInFrame):
+        (WebKit::WebPage::loadRequest):
+        (WebKit::WebPage::loadDataImpl):
+        (WebKit::WebPage::navigateToPDFLinkWithSimulatedClick):
+
 2015-06-02  Gyuyoung Kim  <gyuyoung.kim@webkit.org>
 
         REGRESSION(r185091): Crash happens on indexdb tests
index c7a5e7e..dccc541 100644 (file)
@@ -1591,7 +1591,7 @@ void PDFPlugin::clickedLink(NSURL *url)
     if (m_lastMouseEvent.type() != WebEvent::NoType)
         coreEvent = MouseEvent::create(eventNames().clickEvent, frame->document()->defaultView(), platform(m_lastMouseEvent), 0, 0);
 
-    frame->loader().urlSelected(coreURL, emptyString(), coreEvent.get(), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer);
+    frame->loader().urlSelected(coreURL, emptyString(), coreEvent.get(), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, ShouldOpenExternalURLsPolicy::ShouldAllow);
 }
 
 void PDFPlugin::setActiveAnnotation(PDFAnnotation *annotation)
index 94940ff..3018d63 100644 (file)
@@ -1176,7 +1176,7 @@ void PluginView::performFrameLoadURLRequest(URLRequest* request)
     Frame* targetFrame = frame->loader().findFrameForNavigation(request->target());
     if (!targetFrame) {
         // We did not find a target frame. Ask our frame to load the page. This may or may not create a popup window.
-        FrameLoadRequest frameRequest(frame, request->request());
+        FrameLoadRequest frameRequest(frame, request->request(), ShouldOpenExternalURLsPolicy::ShouldNotAllow);
         frameRequest.setFrameName(request->target());
         frameRequest.setShouldCheckNewWindowPolicy(true);
         frame->loader().load(frameRequest);
@@ -1188,7 +1188,7 @@ void PluginView::performFrameLoadURLRequest(URLRequest* request)
     }
 
     // Now ask the frame to load the request.
-    targetFrame->loader().load(FrameLoadRequest(targetFrame, request->request()));
+    targetFrame->loader().load(FrameLoadRequest(targetFrame, request->request(), ShouldOpenExternalURLsPolicy::ShouldNotAllow));
 
     auto* targetWebFrame = WebFrame::fromCoreFrame(*targetFrame);
     ASSERT(targetWebFrame);
@@ -1367,7 +1367,7 @@ String PluginView::userAgent()
 
 void PluginView::loadURL(uint64_t requestID, const String& method, const String& urlString, const String& target, const HTTPHeaderMap& headerFields, const Vector<uint8_t>& httpBody, bool allowPopups)
 {
-    FrameLoadRequest frameLoadRequest(m_pluginElement->document().securityOrigin(), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow);
+    FrameLoadRequest frameLoadRequest(m_pluginElement->document().securityOrigin(), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
     frameLoadRequest.resourceRequest().setHTTPMethod(method);
     frameLoadRequest.resourceRequest().setURL(m_pluginElement->document().completeURL(urlString));
     frameLoadRequest.resourceRequest().setHTTPHeaderFields(headerFields);
index 40a60d8..6569486 100644 (file)
@@ -86,7 +86,7 @@ void WebContextMenuClient::searchWithGoogle(const Frame* frame)
 
     if (Page* page = frame->page()) {
         UserGestureIndicator indicator(DefinitelyProcessingUserGesture);
-        page->mainFrame().loader().urlSelected(URL(ParsedURLString, url), String(), 0, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer);
+        page->mainFrame().loader().urlSelected(URL(ParsedURLString, url), String(), 0, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
     }
 }
 #endif
index d65b105..61b14ec 100644 (file)
@@ -650,7 +650,7 @@ Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction& navigati
         return 0;
 
     // Just call through to the chrome client.
-    FrameLoadRequest request(m_frame->coreFrame()->document()->securityOrigin(), navigationAction.resourceRequest(), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow);
+    FrameLoadRequest request(m_frame->coreFrame()->document()->securityOrigin(), navigationAction.resourceRequest(), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, navigationAction.shouldOpenExternalURLsPolicy());
     Page* newPage = webPage->corePage()->chrome().createWindow(m_frame->coreFrame(), request, WindowFeatures(), navigationAction);
     if (!newPage)
         return 0;
index 1ea9128..2d0c254 100644 (file)
@@ -138,7 +138,7 @@ void WebInspector::openInNewTab(const String& urlString)
         return;
 
     Frame& inspectedMainFrame = inspectedPage->mainFrame();
-    FrameLoadRequest request(inspectedMainFrame.document()->securityOrigin(), ResourceRequest(urlString), "_blank", LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ReplaceDocumentIfJavaScriptURL);
+    FrameLoadRequest request(inspectedMainFrame.document()->securityOrigin(), ResourceRequest(urlString), "_blank", LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ReplaceDocumentIfJavaScriptURL, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
 
     Page* newPage = inspectedPage->chrome().createWindow(&inspectedMainFrame, request, WindowFeatures(), NavigationAction(request.resourceRequest(), NavigationType::LinkClicked));
     if (!newPage)
index d81db8e..61080d4 100644 (file)
@@ -1011,7 +1011,7 @@ void WebPage::loadURLInFrame(const String& url, uint64_t frameID)
     if (!frame)
         return;
 
-    frame->coreFrame()->loader().load(FrameLoadRequest(frame->coreFrame(), ResourceRequest(URL(URL(), url))));
+    frame->coreFrame()->loader().load(FrameLoadRequest(frame->coreFrame(), ResourceRequest(URL(URL(), url)), ShouldOpenExternalURLsPolicy::ShouldNotAllow));
 }
 
 void WebPage::loadRequest(uint64_t navigationID, const ResourceRequest& request, const SandboxExtension::Handle& sandboxExtensionHandle, uint64_t shouldOpenExternalURLsPolicy, const UserData& userData)
@@ -1027,7 +1027,7 @@ void WebPage::loadRequest(uint64_t navigationID, const ResourceRequest& request,
     m_loaderClient.willLoadURLRequest(this, request, WebProcess::singleton().transformHandlesToObjects(userData.object()).get());
 
     // Initate the load in WebCore.
-    FrameLoadRequest frameLoadRequest(m_mainFrame->coreFrame(), request);
+    FrameLoadRequest frameLoadRequest(m_mainFrame->coreFrame(), request, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
     ShouldOpenExternalURLsPolicy externalURLsPolicy = static_cast<ShouldOpenExternalURLsPolicy>(shouldOpenExternalURLsPolicy);
     frameLoadRequest.setShouldOpenExternalURLsPolicy(externalURLsPolicy);
 
@@ -1051,7 +1051,7 @@ void WebPage::loadDataImpl(uint64_t navigationID, PassRefPtr<SharedBuffer> share
     m_loaderClient.willLoadDataRequest(this, request, const_cast<SharedBuffer*>(substituteData.content()), substituteData.mimeType(), substituteData.textEncoding(), substituteData.failingURL(), WebProcess::singleton().transformHandlesToObjects(userData.object()).get());
 
     // Initate the load in WebCore.
-    m_mainFrame->coreFrame()->loader().load(FrameLoadRequest(m_mainFrame->coreFrame(), request, substituteData));
+    m_mainFrame->coreFrame()->loader().load(FrameLoadRequest(m_mainFrame->coreFrame(), request, ShouldOpenExternalURLsPolicy::ShouldNotAllow, substituteData));
 }
 
 void WebPage::loadString(uint64_t navigationID, const String& htmlString, const String& MIMEType, const URL& baseURL, const URL& unreachableURL, const UserData& userData)
@@ -1108,7 +1108,8 @@ void WebPage::navigateToPDFLinkWithSimulatedClick(const String& url, IntPoint do
 
     const int singleClick = 1;
     RefPtr<MouseEvent> mouseEvent = MouseEvent::create(eventNames().clickEvent, true, true, currentTime(), nullptr, singleClick, screenPoint.x(), screenPoint.y(), documentPoint.x(), documentPoint.y(), false, false, false, false, 0, nullptr, 0, nullptr);
-    mainFrame->loader().urlSelected(mainFrameDocument->completeURL(url), emptyString(), mouseEvent.get(), LockHistory::No, LockBackForwardList::No, ShouldSendReferrer::MaybeSendReferrer);
+
+    mainFrame->loader().urlSelected(mainFrameDocument->completeURL(url), emptyString(), mouseEvent.get(), LockHistory::No, LockBackForwardList::No, ShouldSendReferrer::MaybeSendReferrer, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
 }
 
 void WebPage::stopLoadingFrame(uint64_t frameID)