API::FrameInfo should know the web page that contains the frame; add API property...
authordbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 30 Jun 2017 21:35:23 +0000 (21:35 +0000)
committerdbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 30 Jun 2017 21:35:23 +0000 (21:35 +0000)
https://bugs.webkit.org/show_bug.cgi?id=165160
<rdar://problem/29451999>

Reviewed by Brady Eidson.

Source/WebCore:

Pass the document that is requesting the load to the loader.

* inspector/InspectorFrontendClientLocal.cpp:
(WebCore::InspectorFrontendClientLocal::openInNewTab): Pass the document when instantiating the FrameLoadRequest.
Also use C++11 brace initialization to instantiate ResourceRequest.
* inspector/InspectorPageAgent.cpp:
(WebCore::InspectorPageAgent::navigate): Pass the document when instantiating the FrameLoadRequest.
* loader/FrameLoadRequest.cpp:
(WebCore::FrameLoadRequest::FrameLoadRequest): Moved from FrameLoadRequest.h.
(WebCore::FrameLoadRequest::requester): Added.
(WebCore::FrameLoadRequest::requesterSecurityOrigin): Added.
* loader/FrameLoadRequest.h:
(WebCore::FrameLoadRequest::FrameLoadRequest): Marked as WEBCORE_EXPORT and modified to take
the document that requested the load.
(WebCore::FrameLoadRequest::requester): Deleted; made out-of-line/moved to FrameLoadRequest.cpp.
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::urlSelected): Pass the document when instantiating the FrameLoadRequest. Also use C++11
brace initialization to instantiate ResourceRequest.
(WebCore::FrameLoader::loadURLIntoChildFrame): Pass the document when instantiating the FrameLoadRequest.
(WebCore::FrameLoader::loadFrameRequest): Substitute FrameLoadRequest::requesterSecurityOrigin() for
FrameLoadRequest::requester() as the former replaces the latter.
(WebCore::FrameLoader::loadURL): Pass the document when instantiating the NavigationAction.
(WebCore::FrameLoader::load): Ditto.
(WebCore::FrameLoader::loadWithDocumentLoader): Pass the document when instantiating the NavigationAction.
Also use C++11 brace initialization syntax to instantiate the NavigationAction.
(WebCore::FrameLoader::reload): Ditto.
(WebCore::FrameLoader::loadPostRequest): Ditto.
(WebCore::FrameLoader::continueLoadAfterNewWindowPolicy): Pass the document when instantiating the NavigationAction.
(WebCore::FrameLoader::loadDifferentDocumentItem): Pass the document when instantiating the NavigationAction.
Also use C++11 brace initialization syntax to instantiate the NavigationAction.
(WebCore::createWindow): Pass the document when instantiating the NavigationAction.
* loader/NavigationAction.cpp:
(WebCore::NavigationAction::NavigationAction): Modified to take the source document.
* loader/NavigationAction.h:
(WebCore::NavigationAction::isEmpty): Consider a NavigationAction empty if does not have a source document
or the associated ResourceRequest has an empty URL.
(WebCore::NavigationAction::sourceDocument): Added.
(WebCore::NavigationAction::NavigationAction): Deleted; made out-of-line/moved to NavigationAction.cpp to
avoid the need to include the header Document.h.
* loader/NavigationScheduler.cpp:
(WebCore::ScheduledURLNavigation::ScheduledURLNavigation): Store the document that scheduled the navigation.
Also use C++11 brace initialization to instantiate in the member initialization list.
(WebCore::ScheduledURLNavigation::initiatingDocument): Added. Retrieves the document that scheduled the navigation.
(WebCore::NavigationScheduler::scheduleLocationChange): Pass the document when instantiating the FrameLoadRequest.
* loader/PolicyChecker.cpp:
(WebCore::PolicyChecker::checkNavigationPolicy): Pass the document when instantiating the NavigationAction.
Also use C++11 brace initialization syntax to instantiate the NavigationAction.
* page/ContextMenuController.cpp:
(WebCore::openNewWindow):
(WebCore::ContextMenuController::contextMenuItemSelected): Pass the document when instantiating the FrameLoadRequest.
Also use C++11 brace initialization syntax to instantiate the FrameLoadRequest.
* page/DOMWindow.cpp:
(WebCore::DOMWindow::createWindow): Pass the document when instantiating the FrameLoadRequest.

Source/WebKit/ios:

Pass the document that is requesting the load to the loader.

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

Source/WebKit/mac:

Pass the document that is requesting the load to the loader.

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

Source/WebKit/win:

Pass the document that is requesting the load to the loader.

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

Source/WebKit2:

Expose a property on WKFrameInfo to retrieve the WKWebView of the web page that contains the
frame. This will allow an embedding client to know the web view that initiated the navigation
request as well as differentiate between a navigation initiated by web content from one
initiated via API.

The majority of this change is passing the document D that initiated the targeted navigation
or called window.open() through the loading machinery to the FrameLoaderClient. The changes
to pass this information to the FrameLoaderClient when creating a new window are straightforward.
For targeted navigation, the WebKit2 FrameLoaderClient implementation now computes the info
for the originating frame regardless of the navigation type (NavigationAction::type()).
(Currently we only compute the originating frame for hyperlink activated navigations,
form submissions, and form resubmissions). The WebProcess computes the page ID of the page
that contains the originating frame and sends that to the UIProcess so that it can create
an API::FrameInfo for the originating frame and associate the page that contains the frame,
if the navigation was triggered by web content. If the navigation was triggered by API
(e.g. -[WKWebView goBack]) then the created API::FrameInfo does not have an associated page
so that an embedding client can distinguish between a navigation initiated by web content
from a navigation that it initiated via API depending on whether API::FrameInfo::page() is
nullptr. We expose property webView on the Mac and iOS API class WKFrameInfo to return the
WKWebView corresponding to API::FrameInfo::page().

A small change that this patch makes is to have the WebProcess compute the originating frame
info (call WebFrame::info()) and send it over to the UIProcess as opposed to sending the frame
ID of the originating frame and having the UIProcess compute the frame info from it. We do this
because the UIProcess may not be able to compute the frame info for the originating frame if
the window that it was contained in was closed between the time the WebProcess sent the frame
ID to the UIProcess and the UIProcess received it.

* UIProcess/API/APIFrameInfo.cpp:
(API::FrameInfo::create):
(API::FrameInfo::FrameInfo):
(API::FrameInfo::clearPage):
* UIProcess/API/APIFrameInfo.h:
* UIProcess/API/APIUIClient.h:
(API::UIClient::createNewPage):
(API::UIClient::createNewPageAsync):
* UIProcess/API/C/WKPage.cpp:
(WKPageSetPageUIClient):
* UIProcess/API/Cocoa/WKFrameInfo.h:
* UIProcess/API/Cocoa/WKFrameInfo.mm:
(-[WKFrameInfo description]):
(-[WKFrameInfo webView]):
* UIProcess/API/Cocoa/WKUserContentController.mm:
* UIProcess/Cocoa/UIDelegate.h:
* UIProcess/Cocoa/UIDelegate.mm:
(WebKit::UIDelegate::UIClient::createNewPageCommon):
(WebKit::UIDelegate::UIClient::createNewPage):
(WebKit::UIDelegate::UIClient::createNewPageAsync):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::decidePolicyForNavigationAction):
(WebKit::WebPageProxy::createNewPage):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* WebProcess/Plugins/PluginView.cpp:
(WebKit::PluginView::loadURL):
* WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::createWindow):
* WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
(WebKit::WebFrameLoaderClient::dispatchCreatePage):
(WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction):
* WebProcess/WebPage/WebInspector.cpp:
(WebKit::WebInspector::openInNewTab):

Tools:

Add tests to ensure that -[WKFrameInfo webView] is computed correctly for the source and target frame
for navigations and window creation.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKit2Cocoa/DecidePolicyForNavigationAction.mm: Added. Derived from file ShouldOpenExternalURLsInNewWindowActions.mm.
(-[DecidePolicyForNavigationActionController webView:decidePolicyForNavigationAction:decisionHandler:]):
(-[DecidePolicyForNavigationActionController webView:didFinishNavigation:]):
(-[DecidePolicyForNavigationActionController webView:createWebViewWithConfiguration:forNavigationAction:windowFeatures:]):
(TEST):

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

38 files changed:
Source/WebCore/ChangeLog
Source/WebCore/inspector/InspectorFrontendClientLocal.cpp
Source/WebCore/inspector/InspectorPageAgent.cpp
Source/WebCore/loader/FrameLoadRequest.cpp
Source/WebCore/loader/FrameLoadRequest.h
Source/WebCore/loader/FrameLoader.cpp
Source/WebCore/loader/NavigationAction.cpp
Source/WebCore/loader/NavigationAction.h
Source/WebCore/loader/NavigationScheduler.cpp
Source/WebCore/loader/PolicyChecker.cpp
Source/WebCore/page/ContextMenuController.cpp
Source/WebCore/page/DOMWindow.cpp
Source/WebKit/ios/ChangeLog
Source/WebKit/ios/WebView/WebPDFViewPlaceholder.mm
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebView/WebPDFView.mm
Source/WebKit/win/ChangeLog
Source/WebKit/win/Plugins/PluginView.cpp
Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/API/APIFrameInfo.cpp
Source/WebKit2/UIProcess/API/APIFrameInfo.h
Source/WebKit2/UIProcess/API/APIUIClient.h
Source/WebKit2/UIProcess/API/C/WKPage.cpp
Source/WebKit2/UIProcess/API/Cocoa/WKFrameInfo.h
Source/WebKit2/UIProcess/API/Cocoa/WKFrameInfo.mm
Source/WebKit2/UIProcess/API/Cocoa/WKUserContentController.mm
Source/WebKit2/UIProcess/Cocoa/UIDelegate.h
Source/WebKit2/UIProcess/Cocoa/UIDelegate.mm
Source/WebKit2/UIProcess/WebPageProxy.cpp
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/UIProcess/WebPageProxy.messages.in
Source/WebKit2/WebProcess/Plugins/PluginView.cpp
Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp
Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
Source/WebKit2/WebProcess/WebPage/WebInspector.cpp
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKit2Cocoa/DecidePolicyForNavigationAction.mm [new file with mode: 0644]

index a833e6a..9c21482 100644 (file)
@@ -1,3 +1,65 @@
+2017-06-30  Daniel Bates  <dabates@apple.com>
+
+        API::FrameInfo should know the web page that contains the frame; add API property webView to WKFrameInfo
+        https://bugs.webkit.org/show_bug.cgi?id=165160
+        <rdar://problem/29451999>
+
+        Reviewed by Brady Eidson.
+
+        Pass the document that is requesting the load to the loader.
+
+        * inspector/InspectorFrontendClientLocal.cpp:
+        (WebCore::InspectorFrontendClientLocal::openInNewTab): Pass the document when instantiating the FrameLoadRequest.
+        Also use C++11 brace initialization to instantiate ResourceRequest.
+        * inspector/InspectorPageAgent.cpp:
+        (WebCore::InspectorPageAgent::navigate): Pass the document when instantiating the FrameLoadRequest.
+        * loader/FrameLoadRequest.cpp:
+        (WebCore::FrameLoadRequest::FrameLoadRequest): Moved from FrameLoadRequest.h.
+        (WebCore::FrameLoadRequest::requester): Added.
+        (WebCore::FrameLoadRequest::requesterSecurityOrigin): Added.
+        * loader/FrameLoadRequest.h:
+        (WebCore::FrameLoadRequest::FrameLoadRequest): Marked as WEBCORE_EXPORT and modified to take
+        the document that requested the load.
+        (WebCore::FrameLoadRequest::requester): Deleted; made out-of-line/moved to FrameLoadRequest.cpp.
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::urlSelected): Pass the document when instantiating the FrameLoadRequest. Also use C++11
+        brace initialization to instantiate ResourceRequest.
+        (WebCore::FrameLoader::loadURLIntoChildFrame): Pass the document when instantiating the FrameLoadRequest.
+        (WebCore::FrameLoader::loadFrameRequest): Substitute FrameLoadRequest::requesterSecurityOrigin() for
+        FrameLoadRequest::requester() as the former replaces the latter.
+        (WebCore::FrameLoader::loadURL): Pass the document when instantiating the NavigationAction.
+        (WebCore::FrameLoader::load): Ditto.
+        (WebCore::FrameLoader::loadWithDocumentLoader): Pass the document when instantiating the NavigationAction.
+        Also use C++11 brace initialization syntax to instantiate the NavigationAction.
+        (WebCore::FrameLoader::reload): Ditto.
+        (WebCore::FrameLoader::loadPostRequest): Ditto.
+        (WebCore::FrameLoader::continueLoadAfterNewWindowPolicy): Pass the document when instantiating the NavigationAction.
+        (WebCore::FrameLoader::loadDifferentDocumentItem): Pass the document when instantiating the NavigationAction.
+        Also use C++11 brace initialization syntax to instantiate the NavigationAction.
+        (WebCore::createWindow): Pass the document when instantiating the NavigationAction.
+        * loader/NavigationAction.cpp:
+        (WebCore::NavigationAction::NavigationAction): Modified to take the source document.
+        * loader/NavigationAction.h:
+        (WebCore::NavigationAction::isEmpty): Consider a NavigationAction empty if does not have a source document
+        or the associated ResourceRequest has an empty URL.
+        (WebCore::NavigationAction::sourceDocument): Added.
+        (WebCore::NavigationAction::NavigationAction): Deleted; made out-of-line/moved to NavigationAction.cpp to
+        avoid the need to include the header Document.h.
+        * loader/NavigationScheduler.cpp:
+        (WebCore::ScheduledURLNavigation::ScheduledURLNavigation): Store the document that scheduled the navigation.
+        Also use C++11 brace initialization to instantiate in the member initialization list.
+        (WebCore::ScheduledURLNavigation::initiatingDocument): Added. Retrieves the document that scheduled the navigation.
+        (WebCore::NavigationScheduler::scheduleLocationChange): Pass the document when instantiating the FrameLoadRequest.
+        * loader/PolicyChecker.cpp:
+        (WebCore::PolicyChecker::checkNavigationPolicy): Pass the document when instantiating the NavigationAction.
+        Also use C++11 brace initialization syntax to instantiate the NavigationAction.
+        * page/ContextMenuController.cpp:
+        (WebCore::openNewWindow):
+        (WebCore::ContextMenuController::contextMenuItemSelected): Pass the document when instantiating the FrameLoadRequest.
+        Also use C++11 brace initialization syntax to instantiate the FrameLoadRequest.
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::createWindow): Pass the document when instantiating the FrameLoadRequest.
+
 2017-06-29  Jer Noble  <jer.noble@apple.com>
 
         Make Legacy EME API controlled by RuntimeEnabled setting.
index 7063f7c..0499f9c 100644 (file)
@@ -227,7 +227,7 @@ void InspectorFrontendClientLocal::openInNewTab(const String& url)
 {
     UserGestureIndicator indicator { ProcessingUserGesture };
     Frame& mainFrame = m_inspectedPageController->inspectedPage().mainFrame();
-    FrameLoadRequest frameLoadRequest { mainFrame.document()->securityOrigin(), ResourceRequest(), ASCIILiteral("_blank"), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
+    FrameLoadRequest frameLoadRequest { *mainFrame.document(), mainFrame.document()->securityOrigin(), { }, ASCIILiteral("_blank"), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
 
     bool created;
     RefPtr<Frame> frame = WebCore::createWindow(mainFrame, mainFrame, WTFMove(frameLoadRequest), { }, created);
@@ -239,7 +239,7 @@ void InspectorFrontendClientLocal::openInNewTab(const String& url)
 
     // FIXME: Why do we compute the absolute URL with respect to |frame| instead of |mainFrame|?
     ResourceRequest resourceRequest { frame->document()->completeURL(url) };
-    FrameLoadRequest frameLoadRequest2 { mainFrame.document()->securityOrigin(), resourceRequest, ASCIILiteral("_self"), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
+    FrameLoadRequest frameLoadRequest2 { *mainFrame.document(), mainFrame.document()->securityOrigin(), resourceRequest, ASCIILiteral("_self"), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
     frame->loader().changeLocation(WTFMove(frameLoadRequest2));
 }
 
index 6d81fa1..f9b25ed 100644 (file)
@@ -423,7 +423,7 @@ void InspectorPageAgent::navigate(ErrorString&, const String& url)
     Frame& frame = m_page.mainFrame();
 
     ResourceRequest resourceRequest { frame.document()->completeURL(url) };
-    FrameLoadRequest frameLoadRequest { frame.document()->securityOrigin(), resourceRequest, ASCIILiteral("_self"), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
+    FrameLoadRequest frameLoadRequest { *frame.document(), frame.document()->securityOrigin(), resourceRequest, ASCIILiteral("_self"), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
     frame.loader().changeLocation(WTFMove(frameLoadRequest));
 }
 
index a2d20aa..e3acef0 100644 (file)
 
 #include "Document.h"
 #include "Frame.h"
+#include "SecurityOrigin.h"
 
 namespace WebCore {
 
+FrameLoadRequest::FrameLoadRequest(Document& requester, SecurityOrigin& requesterSecurityOrigin, const ResourceRequest& resourceRequest, const String& frameName, LockHistory lockHistory, LockBackForwardList lockBackForwardList, ShouldSendReferrer shouldSendReferrer, AllowNavigationToInvalidURL allowNavigationToInvalidURL, NewFrameOpenerPolicy newFrameOpenerPolicy, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, ShouldReplaceDocumentIfJavaScriptURL shouldReplaceDocumentIfJavaScriptURL, const AtomicString& downloadAttribute)
+    : m_requester { makeRef(requester) }
+    , m_requesterSecurityOrigin { makeRef(requesterSecurityOrigin) }
+    , m_resourceRequest { resourceRequest }
+    , m_frameName { frameName }
+    , m_lockHistory { lockHistory }
+    , m_lockBackForwardList { lockBackForwardList }
+    , m_shouldSendReferrer { shouldSendReferrer }
+    , m_allowNavigationToInvalidURL { allowNavigationToInvalidURL }
+    , m_newFrameOpenerPolicy { newFrameOpenerPolicy }
+    , m_shouldReplaceDocumentIfJavaScriptURL { shouldReplaceDocumentIfJavaScriptURL }
+    , m_shouldOpenExternalURLsPolicy { shouldOpenExternalURLsPolicy }
+    , m_downloadAttribute { downloadAttribute }
+{
+}
+
 FrameLoadRequest::FrameLoadRequest(Frame& frame, const ResourceRequest& resourceRequest, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, const SubstituteData& substituteData)
-    : m_requester { makeRef(frame.document()->securityOrigin()) }
+    : m_requester { makeRef(*frame.document()) }
+    , m_requesterSecurityOrigin { makeRef(frame.document()->securityOrigin()) }
     , m_resourceRequest { resourceRequest }
     , m_substituteData { substituteData }
     , m_lockHistory { LockHistory::No }
@@ -50,4 +68,16 @@ FrameLoadRequest::FrameLoadRequest(Frame& frame, const ResourceRequest& resource
 {
 }
 
+FrameLoadRequest::~FrameLoadRequest() = default;
+
+Document& FrameLoadRequest::requester()
+{
+    return m_requester.get();
+}
+
+const SecurityOrigin& FrameLoadRequest::requesterSecurityOrigin() const
+{
+    return m_requesterSecurityOrigin.get();
+}
+
 } // namespace WebCore
index a231334..1d0cdf9 100644 (file)
 
 #include "FrameLoaderTypes.h"
 #include "ResourceRequest.h"
-#include "SecurityOrigin.h"
 #include "SubstituteData.h"
+#include <wtf/Forward.h>
 
 namespace WebCore {
 
+class Document;
 class Frame;
+class SecurityOrigin;
 
 class FrameLoadRequest {
 public:
-    FrameLoadRequest(SecurityOrigin& requester, const ResourceRequest& resourceRequest, const String& frameName, LockHistory lockHistory, LockBackForwardList lockBackForwardList, ShouldSendReferrer shouldSendReferrer, AllowNavigationToInvalidURL allowNavigationToInvalidURL, NewFrameOpenerPolicy newFrameOpenerPolicy, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, ShouldReplaceDocumentIfJavaScriptURL shouldReplaceDocumentIfJavaScriptURL = ReplaceDocumentIfJavaScriptURL, const AtomicString& downloadAttribute = { })
-        : m_requester { makeRef(requester) }
-        , m_resourceRequest { resourceRequest }
-        , m_frameName { frameName }
-        , m_lockHistory { lockHistory }
-        , m_lockBackForwardList { lockBackForwardList }
-        , m_shouldSendReferrer { shouldSendReferrer }
-        , m_allowNavigationToInvalidURL { allowNavigationToInvalidURL }
-        , m_newFrameOpenerPolicy { newFrameOpenerPolicy }
-        , m_shouldReplaceDocumentIfJavaScriptURL { shouldReplaceDocumentIfJavaScriptURL }
-        , m_shouldOpenExternalURLsPolicy { shouldOpenExternalURLsPolicy }
-        , m_downloadAttribute { downloadAttribute }
-    {
-    }
+    WEBCORE_EXPORT FrameLoadRequest(Document&, SecurityOrigin&, const ResourceRequest&, const String& frameName, LockHistory, LockBackForwardList, ShouldSendReferrer, AllowNavigationToInvalidURL, NewFrameOpenerPolicy, ShouldOpenExternalURLsPolicy, ShouldReplaceDocumentIfJavaScriptURL = ReplaceDocumentIfJavaScriptURL, const AtomicString& downloadAttribute = { });
     WEBCORE_EXPORT FrameLoadRequest(Frame&, const ResourceRequest&, ShouldOpenExternalURLsPolicy, const SubstituteData& = SubstituteData());
 
+    WEBCORE_EXPORT ~FrameLoadRequest();
+
     FrameLoadRequest(FrameLoadRequest&&) = default;
     FrameLoadRequest& operator=(FrameLoadRequest&&) = default;
 
     bool isEmpty() const { return m_resourceRequest.isEmpty(); }
 
-    const SecurityOrigin& requester() const { return m_requester.get(); }
+    Document& requester();
+    const SecurityOrigin& requesterSecurityOrigin() const;
 
     ResourceRequest& resourceRequest() { return m_resourceRequest; }
     const ResourceRequest& resourceRequest() const { return m_resourceRequest; }
@@ -88,7 +80,8 @@ public:
     const AtomicString& downloadAttribute() const { return m_downloadAttribute; }
 
 private:
-    Ref<SecurityOrigin> m_requester;
+    Ref<Document> m_requester;
+    Ref<SecurityOrigin> m_requesterSecurityOrigin;
     ResourceRequest m_resourceRequest;
     String m_frameName;
     SubstituteData m_substituteData;
index 043cdeb..078084f 100644 (file)
@@ -363,7 +363,7 @@ void FrameLoader::changeLocation(FrameLoadRequest&& request)
 void FrameLoader::urlSelected(const URL& url, const String& passedTarget, Event* triggeringEvent, LockHistory lockHistory, LockBackForwardList lockBackForwardList, ShouldSendReferrer shouldSendReferrer, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, std::optional<NewFrameOpenerPolicy> openerPolicy, const AtomicString& downloadAttribute)
 {
     NewFrameOpenerPolicy newFrameOpenerPolicy = openerPolicy.value_or(shouldSendReferrer == NeverSendReferrer ? NewFrameOpenerPolicy::Suppress : NewFrameOpenerPolicy::Allow);
-    urlSelected(FrameLoadRequest(m_frame.document()->securityOrigin(), ResourceRequest(url), passedTarget, lockHistory, lockBackForwardList, shouldSendReferrer, AllowNavigationToInvalidURL::Yes, newFrameOpenerPolicy, shouldOpenExternalURLsPolicy, DoNotReplaceDocumentIfJavaScriptURL, downloadAttribute), triggeringEvent);
+    urlSelected(FrameLoadRequest(*m_frame.document(), m_frame.document()->securityOrigin(), { url }, passedTarget, lockHistory, lockBackForwardList, shouldSendReferrer, AllowNavigationToInvalidURL::Yes, newFrameOpenerPolicy, shouldOpenExternalURLsPolicy, DoNotReplaceDocumentIfJavaScriptURL, downloadAttribute), triggeringEvent);
 }
 
 void FrameLoader::urlSelected(FrameLoadRequest&& frameRequest, Event* triggeringEvent)
@@ -923,7 +923,7 @@ void FrameLoader::loadURLIntoChildFrame(const URL& url, const String& referer, F
         }
     }
 
-    FrameLoadRequest frameLoadRequest { m_frame.document()->securityOrigin(), { url }, ASCIILiteral("_self"), LockHistory::No, LockBackForwardList::Yes, ShouldSendReferrer::MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
+    FrameLoadRequest frameLoadRequest { *m_frame.document(), m_frame.document()->securityOrigin(), { url }, ASCIILiteral("_self"), LockHistory::No, LockBackForwardList::Yes, ShouldSendReferrer::MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
     childFrame->loader().loadURL(WTFMove(frameLoadRequest), referer, FrameLoadType::RedirectWithLockedBackForwardList, nullptr, nullptr);
 }
 
@@ -1165,7 +1165,7 @@ void FrameLoader::loadFrameRequest(FrameLoadRequest&& request, Event* event, For
     URL url = request.resourceRequest().url();
 
     ASSERT(m_frame.document());
-    if (!request.requester().canDisplay(url)) {
+    if (!request.requesterSecurityOrigin().canDisplay(url)) {
         reportLocalLoadFailed(&m_frame, url.stringCenterEllipsizedToLength());
         return;
     }
@@ -1258,7 +1258,7 @@ void FrameLoader::loadURL(FrameLoadRequest&& frameLoadRequest, const String& ref
     if (!isNavigationAllowed())
         return;
 
-    NavigationAction action(request, newLoadType, isFormSubmission, event, frameLoadRequest.shouldOpenExternalURLsPolicy(), frameLoadRequest.downloadAttribute());
+    NavigationAction action { frameLoadRequest.requester(), request, newLoadType, isFormSubmission, event, frameLoadRequest.shouldOpenExternalURLsPolicy(), frameLoadRequest.downloadAttribute() };
 
     if (!targetFrame && !frameName.isEmpty()) {
         action = action.copyWithShouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicyToApply(m_frame, frameLoadRequest.shouldOpenExternalURLsPolicy()));
@@ -1331,7 +1331,7 @@ void FrameLoader::load(FrameLoadRequest&& request)
     }
 
     if (request.shouldCheckNewWindowPolicy()) {
-        NavigationAction action(request.resourceRequest(), NavigationType::Other, request.shouldOpenExternalURLsPolicy());
+        NavigationAction action { request.requester(), request.resourceRequest(), NavigationType::Other, request.shouldOpenExternalURLsPolicy() };
         policyChecker().checkNewWindowPolicy(action, request.resourceRequest(), nullptr, request.frameName(), [this] (const ResourceRequest& request, FormState* formState, const String& frameName, const NavigationAction& action, bool shouldContinue) {
             continueLoadAfterNewWindowPolicy(request, formState, frameName, action, shouldContinue, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress);
         });
@@ -1436,7 +1436,7 @@ void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType t
 
     if (shouldPerformFragmentNavigation(isFormSubmission, httpMethod, policyChecker().loadType(), newURL)) {
         RefPtr<DocumentLoader> oldDocumentLoader = m_documentLoader;
-        NavigationAction action(loader->request(), policyChecker().loadType(), isFormSubmission);
+        NavigationAction action { *m_frame.document(), loader->request(), policyChecker().loadType(), isFormSubmission };
 
         oldDocumentLoader->setTriggeringAction(action);
         oldDocumentLoader->setLastCheckedRequest(ResourceRequest());
@@ -1453,7 +1453,7 @@ void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType t
     policyChecker().stopCheck();
     setPolicyDocumentLoader(loader);
     if (loader->triggeringAction().isEmpty())
-        loader->setTriggeringAction(NavigationAction(loader->request(), policyChecker().loadType(), isFormSubmission));
+        loader->setTriggeringAction({ *m_frame.document(), loader->request(), policyChecker().loadType(), isFormSubmission });
 
     if (Element* ownerElement = m_frame.ownerElement()) {
         // We skip dispatching the beforeload event if we've already
@@ -1592,7 +1592,7 @@ void FrameLoader::reload(OptionSet<ReloadOption> options)
 
     // If we're about to re-post, set up action so the application can warn the user.
     if (request.httpMethod() == "POST")
-        loader->setTriggeringAction(NavigationAction(request, NavigationType::FormResubmitted));
+        loader->setTriggeringAction({ *m_frame.document(), request, NavigationType::FormResubmitted });
 
     loader->setOverrideEncoding(m_documentLoader->overrideEncoding());
 
@@ -2716,7 +2716,7 @@ void FrameLoader::loadPostRequest(FrameLoadRequest&& request, const String& refe
     if (Document* document = m_frame.document())
         document->contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(workingResourceRequest, ContentSecurityPolicy::InsecureRequestType::Load);
 
-    NavigationAction action(workingResourceRequest, loadType, true, event, request.shouldOpenExternalURLsPolicy(), request.downloadAttribute());
+    NavigationAction action { request.requester(), workingResourceRequest, loadType, true, event, request.shouldOpenExternalURLsPolicy(), request.downloadAttribute() };
 
     if (!frameName.isEmpty()) {
         // The search for a target frame is done earlier in the case of form submission.
@@ -3172,7 +3172,7 @@ void FrameLoader::continueLoadAfterNewWindowPolicy(const ResourceRequest& reques
         mainFrame->document()->setReferrerPolicy(frame->document()->referrerPolicy());
     }
 
-    NavigationAction newAction { request, NavigationType::Other, action.shouldOpenExternalURLsPolicy() };
+    NavigationAction newAction { *frame->document(), request, NavigationType::Other, action.shouldOpenExternalURLsPolicy() };
     mainFrame->loader().loadWithNavigationAction(request, newAction, LockHistory::No, FrameLoadType::Standard, formState, allowNavigationToInvalidURL);
 }
 
@@ -3358,7 +3358,7 @@ void FrameLoader::loadDifferentDocumentItem(HistoryItem& item, FrameLoadType loa
     if (CachedPage* cachedPage = PageCache::singleton().get(item, m_frame.page())) {
         auto documentLoader = cachedPage->documentLoader();
         m_client.updateCachedDocumentLoader(*documentLoader);
-        documentLoader->setTriggeringAction(NavigationAction(documentLoader->request(), loadType, false));
+        documentLoader->setTriggeringAction({ *m_frame.document(), documentLoader->request(), loadType, false });
         documentLoader->setLastCheckedRequest(ResourceRequest());
         loadWithDocumentLoader(documentLoader, loadType, 0, AllowNavigationToInvalidURL::Yes);
         return;
@@ -3406,10 +3406,10 @@ void FrameLoader::loadDifferentDocumentItem(HistoryItem& item, FrameLoadType loa
         
         if (cacheLoadPolicy == MayAttemptCacheOnlyLoadForFormSubmissionItem) {
             request.setCachePolicy(ReturnCacheDataDontLoad);
-            action = NavigationAction(request, loadType, isFormSubmission, event, shouldOpenExternalURLsPolicy);
+            action = { *m_frame.document(), request, loadType, isFormSubmission, event, shouldOpenExternalURLsPolicy };
         } else {
             request.setCachePolicy(ReturnCacheDataElseLoad);
-            action = NavigationAction(request, NavigationType::FormResubmitted, shouldOpenExternalURLsPolicy, event);
+            action = { *m_frame.document(), request, NavigationType::FormResubmitted, shouldOpenExternalURLsPolicy, event };
         }
     } else {
         switch (loadType) {
@@ -3443,7 +3443,7 @@ void FrameLoader::loadDifferentDocumentItem(HistoryItem& item, FrameLoadType loa
 
         ResourceRequest requestForOriginalURL(request);
         requestForOriginalURL.setURL(itemOriginalURL);
-        action = NavigationAction(requestForOriginalURL, loadType, isFormSubmission, event, shouldOpenExternalURLsPolicy);
+        action = { *m_frame.document(), requestForOriginalURL, loadType, isFormSubmission, event, shouldOpenExternalURLsPolicy };
     }
 
     loadWithNavigationAction(request, action, LockHistory::No, loadType, 0, AllowNavigationToInvalidURL::Yes);
@@ -3697,7 +3697,7 @@ RefPtr<Frame> createWindow(Frame& openerFrame, Frame& lookupFrame, FrameLoadRequ
         return nullptr;
 
     ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy = shouldOpenExternalURLsPolicyToApply(openerFrame, request.shouldOpenExternalURLsPolicy());
-    NavigationAction action { request.resourceRequest(), NavigationType::Other, shouldOpenExternalURLsPolicy };
+    NavigationAction action { request.requester(), request.resourceRequest(), NavigationType::Other, shouldOpenExternalURLsPolicy };
     Page* page = oldPage->chrome().createWindow(openerFrame, request, features, action);
     if (!page)
         return nullptr;
index 895c085..8b029d4 100644 (file)
 #include "config.h"
 #include "NavigationAction.h"
 
+#include "Document.h"
 #include "Event.h"
 #include "FrameLoader.h"
 
 namespace WebCore {
 
+NavigationAction::NavigationAction() = default;
 NavigationAction::~NavigationAction() = default;
 
 NavigationAction::NavigationAction(const NavigationAction&) = default;
@@ -42,8 +44,9 @@ NavigationAction::NavigationAction(NavigationAction&&) = default;
 NavigationAction& NavigationAction::operator=(const NavigationAction&) = default;
 NavigationAction& NavigationAction::operator=(NavigationAction&&) = default;
 
-NavigationAction::NavigationAction(const ResourceRequest& resourceRequest, NavigationType type, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, Event* event, const AtomicString& downloadAttribute)
-    : m_resourceRequest { resourceRequest }
+NavigationAction::NavigationAction(Document& source, const ResourceRequest& resourceRequest, NavigationType type, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, Event* event, const AtomicString& downloadAttribute)
+    : m_sourceDocument { makeRefPtr(source) }
+    , m_resourceRequest { resourceRequest }
     , m_type { type }
     , m_shouldOpenExternalURLsPolicy { shouldOpenExternalURLsPolicy }
     , m_event { event }
@@ -64,8 +67,9 @@ static NavigationType navigationType(FrameLoadType frameLoadType, bool isFormSub
     return NavigationType::Other;
 }
 
-NavigationAction::NavigationAction(const ResourceRequest& resourceRequest, FrameLoadType frameLoadType, bool isFormSubmission, Event* event, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, const AtomicString& downloadAttribute)
-    : m_resourceRequest { resourceRequest }
+NavigationAction::NavigationAction(Document& source, const ResourceRequest& resourceRequest, FrameLoadType frameLoadType, bool isFormSubmission, Event* event, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, const AtomicString& downloadAttribute)
+    : m_sourceDocument { makeRefPtr(source) }
+    , m_resourceRequest { resourceRequest }
     , m_type { navigationType(frameLoadType, isFormSubmission, !!event) }
     , m_shouldOpenExternalURLsPolicy { shouldOpenExternalURLsPolicy }
     , m_event { event }
index 0abb442..99db44b 100644 (file)
 
 namespace WebCore {
 
+class Document;
 class Event;
 
 class NavigationAction {
 public:
-    WEBCORE_EXPORT explicit NavigationAction(const ResourceRequest& = { }, NavigationType = NavigationType::Other, ShouldOpenExternalURLsPolicy = ShouldOpenExternalURLsPolicy::ShouldNotAllow, Event* = nullptr, const AtomicString& downloadAttribute = nullAtom);
-    NavigationAction(const ResourceRequest&, FrameLoadType, bool isFormSubmission, Event* = nullptr, ShouldOpenExternalURLsPolicy = ShouldOpenExternalURLsPolicy::ShouldNotAllow, const AtomicString& downloadAttribute = nullAtom);
+    NavigationAction();
+    WEBCORE_EXPORT NavigationAction(Document&, const ResourceRequest&, NavigationType = NavigationType::Other, ShouldOpenExternalURLsPolicy = ShouldOpenExternalURLsPolicy::ShouldNotAllow, Event* = nullptr, const AtomicString& downloadAttribute = nullAtom);
+    NavigationAction(Document&, const ResourceRequest&, FrameLoadType, bool isFormSubmission, Event* = nullptr, ShouldOpenExternalURLsPolicy = ShouldOpenExternalURLsPolicy::ShouldNotAllow, const AtomicString& downloadAttribute = nullAtom);
 
     WEBCORE_EXPORT ~NavigationAction();
 
     WEBCORE_EXPORT NavigationAction(const NavigationAction&);
-    NavigationAction(NavigationAction&&);
-
     NavigationAction& operator=(const NavigationAction&);
+
+    NavigationAction(NavigationAction&&);
     NavigationAction& operator=(NavigationAction&&);
 
     NavigationAction copyWithShouldOpenExternalURLsPolicy(ShouldOpenExternalURLsPolicy) const;
 
-    bool isEmpty() const { return m_resourceRequest.url().isEmpty(); }
+    bool isEmpty() const { return !m_sourceDocument || m_resourceRequest.url().isEmpty(); }
 
     URL url() const { return m_resourceRequest.url(); }
     const ResourceRequest& resourceRequest() const { return m_resourceRequest; }
@@ -60,6 +62,8 @@ public:
     NavigationType type() const { return m_type; }
     const Event* event() const { return m_event.get(); }
 
+    const Document* sourceDocument() const { return m_sourceDocument.get(); }
+
     bool processingUserGesture() const { return m_userGestureToken ? m_userGestureToken->processingUserGesture() : false; }
     RefPtr<UserGestureToken> userGestureToken() const { return m_userGestureToken; }
 
@@ -68,6 +72,7 @@ public:
     const AtomicString& downloadAttribute() const { return m_downloadAttribute; }
 
 private:
+    RefPtr<Document> m_sourceDocument;
     ResourceRequest m_resourceRequest;
     NavigationType m_type;
     ShouldOpenExternalURLsPolicy m_shouldOpenExternalURLsPolicy;
index 3e84b08..b41a54f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2017 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
  * Copyright (C) 2009 Adam Barth. All rights reserved.
@@ -113,20 +113,21 @@ class ScheduledURLNavigation : public ScheduledNavigation {
 protected:
     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, initiatingDocument.shouldOpenExternalURLsPolicyToPropagate())
-        , m_securityOrigin(securityOrigin)
-        , m_url(url)
-        , m_referrer(referrer)
+        , m_initiatingDocument { makeRef(initiatingDocument) }
+        , m_securityOrigin{ makeRefPtr(securityOrigin) }
+        , m_url { url }
+        , m_referrer { referrer }
     {
     }
 
     void fire(Frame& frame) override
     {
-        UserGestureIndicator gestureIndicator(userGestureToForward());
+        UserGestureIndicator gestureIndicator { userGestureToForward() };
 
-        ResourceRequest resourceRequest(m_url, m_referrer, UseProtocolCachePolicy);
-        FrameLoadRequest frameRequest(*m_securityOrigin, resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs());
+        ResourceRequest resourceRequest { m_url, m_referrer, UseProtocolCachePolicy };
+        FrameLoadRequest frameLoadRequest { m_initiatingDocument.get(), *m_securityOrigin, resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs() };
 
-        frame.loader().changeLocation(WTFMove(frameRequest));
+        frame.loader().changeLocation(WTFMove(frameLoadRequest));
     }
 
     void didStartTimer(Frame& frame, Timer& timer) override
@@ -153,11 +154,13 @@ protected:
         frame.loader().clientRedirectCancelledOrFinished(newLoadInProgress);
     }
 
+    Document& initiatingDocument() { return m_initiatingDocument.get(); }
     SecurityOrigin* securityOrigin() const { return m_securityOrigin.get(); }
     const URL& url() const { return m_url; }
     String referrer() const { return m_referrer; }
 
 private:
+    Ref<Document> m_initiatingDocument;
     RefPtr<SecurityOrigin> m_securityOrigin;
     URL m_url;
     String m_referrer;
@@ -179,12 +182,13 @@ public:
 
     void fire(Frame& frame) override
     {
-        UserGestureIndicator gestureIndicator(userGestureToForward());
+        UserGestureIndicator gestureIndicator { userGestureToForward() };
+
         bool refresh = equalIgnoringFragmentIdentifier(frame.document()->url(), url());
-        ResourceRequest resourceRequest(url(), referrer(), refresh ? ReloadIgnoringCacheData : UseProtocolCachePolicy);
-        FrameLoadRequest frameRequest(*securityOrigin(), resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs());
+        ResourceRequest resourceRequest { url(), referrer(), refresh ? ReloadIgnoringCacheData : UseProtocolCachePolicy };
+        FrameLoadRequest frameLoadRequest { initiatingDocument(), *securityOrigin(), resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs() };
 
-        frame.loader().changeLocation(WTFMove(frameRequest));
+        frame.loader().changeLocation(WTFMove(frameLoadRequest));
     }
 };
 
@@ -195,11 +199,11 @@ public:
 
     void fire(Frame& frame) override
     {
-        UserGestureIndicator gestureIndicator(userGestureToForward());
+        UserGestureIndicator gestureIndicator { userGestureToForward() };
 
-        ResourceRequest resourceRequest(url(), referrer(), UseProtocolCachePolicy);
-        FrameLoadRequest frameRequest(*securityOrigin(), resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs());
-        frame.loader().changeLocation(WTFMove(frameRequest));
+        ResourceRequest resourceRequest { url(), referrer(), UseProtocolCachePolicy };
+        FrameLoadRequest frameLoadRequest { initiatingDocument(), *securityOrigin(), resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs() };
+        frame.loader().changeLocation(WTFMove(frameLoadRequest));
     }
 };
 
@@ -212,11 +216,11 @@ public:
 
     void fire(Frame& frame) override
     {
-        UserGestureIndicator gestureIndicator(userGestureToForward());
+        UserGestureIndicator gestureIndicator { userGestureToForward() };
 
-        ResourceRequest resourceRequest(url(), referrer(), ReloadIgnoringCacheData);
-        FrameLoadRequest frameRequest(*securityOrigin(), resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs());
-        frame.loader().changeLocation(WTFMove(frameRequest));
+        ResourceRequest resourceRequest { url(), referrer(), ReloadIgnoringCacheData };
+        FrameLoadRequest frameLoadRequest { initiatingDocument(), *securityOrigin(), resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs() };
+        frame.loader().changeLocation(WTFMove(frameLoadRequest));
     }
 };
 
@@ -267,7 +271,7 @@ public:
         auto& requestingDocument = m_submission->state().sourceDocument();
         if (!requestingDocument.canNavigate(&frame))
             return;
-        FrameLoadRequest frameLoadRequest { requestingDocument.securityOrigin(), { }, { }, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs() };
+        FrameLoadRequest frameLoadRequest { requestingDocument, requestingDocument.securityOrigin(), { }, { }, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs() };
         m_submission->populateFrameLoadRequest(frameLoadRequest);
         frame.loader().loadFrameRequest(WTFMove(frameLoadRequest), m_submission->event(), &m_submission->state());
     }
@@ -311,13 +315,13 @@ public:
 
     void fire(Frame& frame) override
     {
-        UserGestureIndicator gestureIndicator(userGestureToForward());
+        UserGestureIndicator gestureIndicator { userGestureToForward() };
 
-        ResourceResponse replacementResponse(m_originDocument.url(), ASCIILiteral("text/plain"), 0, ASCIILiteral("UTF-8"));
-        SubstituteData replacementData(SharedBuffer::create(), m_originDocument.url(), replacementResponse, SubstituteData::SessionHistoryVisibility::Hidden);
+        ResourceResponse replacementResponse { m_originDocument.url(), ASCIILiteral("text/plain"), 0, ASCIILiteral("UTF-8") };
+        SubstituteData replacementData { SharedBuffer::create(), m_originDocument.url(), replacementResponse, SubstituteData::SessionHistoryVisibility::Hidden };
 
-        ResourceRequest resourceRequest(m_originDocument.url(), emptyString(), ReloadIgnoringCacheData);
-        FrameLoadRequest frameLoadRequest { m_originDocument.securityOrigin(), resourceRequest, { }, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs() };
+        ResourceRequest resourceRequest { m_originDocument.url(), emptyString(), ReloadIgnoringCacheData };
+        FrameLoadRequest frameLoadRequest { m_originDocument, m_originDocument.securityOrigin(), resourceRequest, { }, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs() };
         frameLoadRequest.setSubstituteData(replacementData);
         frame.loader().load(WTFMove(frameLoadRequest));
     }
@@ -416,7 +420,7 @@ void NavigationScheduler::scheduleLocationChange(Document& initiatingDocument, S
     // 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 frameLoadRequest { securityOrigin, resourceRequest, ASCIILiteral("_self"), lockHistory, lockBackForwardList, MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, initiatingDocument.shouldOpenExternalURLsPolicyToPropagate() };
+        FrameLoadRequest frameLoadRequest { initiatingDocument, securityOrigin, resourceRequest, ASCIILiteral("_self"), lockHistory, lockBackForwardList, MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, initiatingDocument.shouldOpenExternalURLsPolicyToPropagate() };
         loader.changeLocation(WTFMove(frameLoadRequest));
         return;
     }
index 54af1f2..dbeda87 100644 (file)
@@ -84,7 +84,7 @@ void PolicyChecker::checkNavigationPolicy(const ResourceRequest& request, bool d
 {
     NavigationAction action = loader->triggeringAction();
     if (action.isEmpty()) {
-        action = NavigationAction(request, NavigationType::Other, loader->shouldOpenExternalURLsPolicyToPropagate());
+        action = NavigationAction { *m_frame.document(), request, NavigationType::Other, loader->shouldOpenExternalURLsPolicyToPropagate() };
         loader->setTriggeringAction(action);
     }
 
index f5e92ca..8141b51 100644 (file)
@@ -189,9 +189,9 @@ static void openNewWindow(const URL& urlToLoad, Frame& frame, ShouldOpenExternal
     if (!oldPage)
         return;
 
-    FrameLoadRequest frameLoadRequest { frame.document()->securityOrigin(), ResourceRequest(urlToLoad, frame.loader().outgoingReferrer()), { }, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress, shouldOpenExternalURLsPolicy };
+    FrameLoadRequest frameLoadRequest { *frame.document(), frame.document()->securityOrigin(), ResourceRequest(urlToLoad, frame.loader().outgoingReferrer()), { }, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress, shouldOpenExternalURLsPolicy };
 
-    Page* newPage = oldPage->chrome().createWindow(frame, frameLoadRequest, { }, NavigationAction(frameLoadRequest.resourceRequest()));
+    Page* newPage = oldPage->chrome().createWindow(frame, frameLoadRequest, { }, { *frame.document(), frameLoadRequest.resourceRequest() });
     if (!newPage)
         return;
     newPage->chrome().show();
@@ -395,7 +395,7 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuAction action, co
     case ContextMenuItemTagOpenLink:
         if (Frame* targetFrame = m_context.hitTestResult().targetFrame()) {
             ResourceRequest resourceRequest { m_context.hitTestResult().absoluteLinkURL(), frame->loader().outgoingReferrer() };
-            FrameLoadRequest frameLoadRequest { frame->document()->securityOrigin(), resourceRequest, { }, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress, targetFrame->isMainFrame() ? ShouldOpenExternalURLsPolicy::ShouldAllow : ShouldOpenExternalURLsPolicy::ShouldNotAllow };
+            FrameLoadRequest frameLoadRequest { *frame->document(), frame->document()->securityOrigin(), resourceRequest, { }, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress, targetFrame->isMainFrame() ? ShouldOpenExternalURLsPolicy::ShouldAllow : ShouldOpenExternalURLsPolicy::ShouldNotAllow };
             targetFrame->loader().loadFrameRequest(WTFMove(frameLoadRequest), nullptr, nullptr);
         } else
             openNewWindow(m_context.hitTestResult().absoluteLinkURL(), *frame, ShouldOpenExternalURLsPolicy::ShouldAllow);
index f91aed6..b893445 100644 (file)
@@ -2199,7 +2199,7 @@ RefPtr<Frame> DOMWindow::createWindow(const String& urlString, const AtomicStrin
 
     ResourceRequest resourceRequest { completedURL, referrer };
     FrameLoader::addHTTPOriginIfNeeded(resourceRequest, firstFrame.loader().outgoingOrigin());
-    FrameLoadRequest frameLoadRequest { activeDocument->securityOrigin(), resourceRequest, frameName, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, activeDocument->shouldOpenExternalURLsPolicyToPropagate() };
+    FrameLoadRequest frameLoadRequest { *activeDocument, activeDocument->securityOrigin(), resourceRequest, frameName, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, 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.
@@ -2220,11 +2220,11 @@ RefPtr<Frame> DOMWindow::createWindow(const String& urlString, const AtomicStrin
 
     if (created) {
         ResourceRequest resourceRequest { completedURL, referrer, UseProtocolCachePolicy };
-        FrameLoadRequest frameLoadRequest { activeWindow.document()->securityOrigin(), resourceRequest, ASCIILiteral("_self"), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, activeDocument->shouldOpenExternalURLsPolicyToPropagate() };
+        FrameLoadRequest frameLoadRequest { *activeWindow.document(), activeWindow.document()->securityOrigin(), resourceRequest, ASCIILiteral("_self"), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, activeDocument->shouldOpenExternalURLsPolicyToPropagate() };
         newFrame->loader().changeLocation(WTFMove(frameLoadRequest));
     } else if (!urlString.isEmpty()) {
         LockHistory lockHistory = ScriptController::processingUserGesture() ? LockHistory::No : LockHistory::Yes;
-        newFrame->navigationScheduler().scheduleLocationChange(*activeWindow.document(), activeWindow.document()->securityOrigin(), completedURL, referrer, lockHistory, LockBackForwardList::No);
+        newFrame->navigationScheduler().scheduleLocationChange(*activeDocument, activeDocument->securityOrigin(), completedURL, referrer, lockHistory, LockBackForwardList::No);
     }
 
     // Navigating the new frame could result in it being detached from its page by a navigation policy delegate.
index 107a728..6128f91 100644 (file)
@@ -1,3 +1,16 @@
+2017-06-30  Daniel Bates  <dabates@apple.com>
+
+        API::FrameInfo should know the web page that contains the frame; add API property webView to WKFrameInfo
+        https://bugs.webkit.org/show_bug.cgi?id=165160
+        <rdar://problem/29451999>
+
+        Reviewed by Brady Eidson.
+
+        Pass the document that is requesting the load to the loader.
+
+        * WebView/WebPDFViewPlaceholder.mm:
+        (-[WebPDFViewPlaceholder simulateClickOnLinkToURL:]):
+
 2017-06-22  Daniel Bates  <dabates@apple.com>
 
         Make FrameLoadRequest a move-only type
index 52b965e..da41884 100644 (file)
@@ -487,7 +487,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]);
-    FrameLoadRequest frameLoadRequest { frame->document()->securityOrigin(), { URL }, { }, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
+    FrameLoadRequest frameLoadRequest { *frame->document(), frame->document()->securityOrigin(), { URL }, { }, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
     frame->loader().loadFrameRequest(WTFMove(frameLoadRequest), event.get(), nullptr);
 }
 
index 3b7be1e..48716b0 100644 (file)
@@ -1,3 +1,16 @@
+2017-06-30  Daniel Bates  <dabates@apple.com>
+
+        API::FrameInfo should know the web page that contains the frame; add API property webView to WKFrameInfo
+        https://bugs.webkit.org/show_bug.cgi?id=165160
+        <rdar://problem/29451999>
+
+        Reviewed by Brady Eidson.
+
+        Pass the document that is requesting the load to the loader.
+
+        * WebView/WebPDFView.mm:
+        (-[WebPDFView PDFViewWillClickOnLink:withURL:]):
+
 2017-06-29  Jer Noble  <jer.noble@apple.com>
 
         Make Legacy EME API controlled by RuntimeEnabled setting.
index 7160720..47ce371 100644 (file)
@@ -1038,7 +1038,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]);
-    FrameLoadRequest frameLoadRequest { frame->document()->securityOrigin(), { URL }, { }, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
+    FrameLoadRequest frameLoadRequest { *frame->document(), frame->document()->securityOrigin(), { URL }, { }, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
     frame->loader().loadFrameRequest(WTFMove(frameLoadRequest), event.get(), nullptr);
 }
 
index b16b805..8032cf6 100644 (file)
@@ -1,3 +1,19 @@
+2017-06-30  Daniel Bates  <dabates@apple.com>
+
+        API::FrameInfo should know the web page that contains the frame; add API property webView to WKFrameInfo
+        https://bugs.webkit.org/show_bug.cgi?id=165160
+        <rdar://problem/29451999>
+
+        Reviewed by Brady Eidson.
+
+        Pass the document that is requesting the load to the loader.
+
+        * Plugins/PluginView.cpp:
+        (WebCore::PluginView::start):
+        (WebCore::PluginView::getURLNotify):
+        (WebCore::PluginView::getURL):
+        (WebCore::PluginView::handlePost):
+
 2017-06-27  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         Refactor drag start codepaths to plumb a DragItem to client layers
index bf52fb5..522a4ba 100644 (file)
@@ -255,7 +255,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, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
+        FrameLoadRequest frameLoadRequest { *m_parentFrame->document(), 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(WTFMove(frameLoadRequest), false, nullptr);
@@ -534,7 +534,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(), { }, target, LockHistory::No, LockBackForwardList::No, ShouldSendReferrer::MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
+    FrameLoadRequest frameLoadRequest { *m_parentFrame->document(), m_parentFrame->document()->securityOrigin(), { }, target, LockHistory::No, LockBackForwardList::No, ShouldSendReferrer::MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
 
     frameLoadRequest.resourceRequest().setHTTPMethod("GET");
     frameLoadRequest.resourceRequest().setURL(makeURL(m_parentFrame->document()->baseURL(), url));
@@ -544,7 +544,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(), { }, target, LockHistory::No, LockBackForwardList::No, ShouldSendReferrer::MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
+    FrameLoadRequest frameLoadRequest { *m_parentFrame->document(), m_parentFrame->document()->securityOrigin(), { }, target, LockHistory::No, LockBackForwardList::No, ShouldSendReferrer::MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
 
     frameLoadRequest.resourceRequest().setHTTPMethod("GET");
     frameLoadRequest.resourceRequest().setURL(makeURL(m_parentFrame->document()->baseURL(), url));
@@ -1087,7 +1087,7 @@ NPError PluginView::handlePost(const char* url, const char* target, uint32_t len
         }
     }
 
-    FrameLoadRequest frameLoadRequest { m_parentFrame->document()->securityOrigin(), { }, target, LockHistory::No, LockBackForwardList::No, ShouldSendReferrer::MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
+    FrameLoadRequest frameLoadRequest { *m_parentFrame->document(), m_parentFrame->document()->securityOrigin(), { }, target, LockHistory::No, LockBackForwardList::No, ShouldSendReferrer::MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
     frameLoadRequest.resourceRequest().setHTTPMethod("POST");
     frameLoadRequest.resourceRequest().setURL(makeURL(m_parentFrame->document()->baseURL(), url));
     frameLoadRequest.resourceRequest().setHTTPHeaderFields(WTFMove(headerFields));
index c21d5b8..8ed9c0f 100644 (file)
@@ -1,3 +1,74 @@
+2017-06-30  Daniel Bates  <dabates@apple.com>
+
+        API::FrameInfo should know the web page that contains the frame; add API property webView to WKFrameInfo
+        https://bugs.webkit.org/show_bug.cgi?id=165160
+        <rdar://problem/29451999>
+
+        Reviewed by Brady Eidson.
+
+        Expose a property on WKFrameInfo to retrieve the WKWebView of the web page that contains the
+        frame. This will allow an embedding client to know the web view that initiated the navigation
+        request as well as differentiate between a navigation initiated by web content from one
+        initiated via API.
+
+        The majority of this change is passing the document D that initiated the targeted navigation
+        or called window.open() through the loading machinery to the FrameLoaderClient. The changes
+        to pass this information to the FrameLoaderClient when creating a new window are straightforward.
+        For targeted navigation, the WebKit2 FrameLoaderClient implementation now computes the info
+        for the originating frame regardless of the navigation type (NavigationAction::type()).
+        (Currently we only compute the originating frame for hyperlink activated navigations,
+        form submissions, and form resubmissions). The WebProcess computes the page ID of the page
+        that contains the originating frame and sends that to the UIProcess so that it can create
+        an API::FrameInfo for the originating frame and associate the page that contains the frame,
+        if the navigation was triggered by web content. If the navigation was triggered by API
+        (e.g. -[WKWebView goBack]) then the created API::FrameInfo does not have an associated page
+        so that an embedding client can distinguish between a navigation initiated by web content
+        from a navigation that it initiated via API depending on whether API::FrameInfo::page() is
+        nullptr. We expose property webView on the Mac and iOS API class WKFrameInfo to return the
+        WKWebView corresponding to API::FrameInfo::page().
+
+        A small change that this patch makes is to have the WebProcess compute the originating frame
+        info (call WebFrame::info()) and send it over to the UIProcess as opposed to sending the frame
+        ID of the originating frame and having the UIProcess compute the frame info from it. We do this
+        because the UIProcess may not be able to compute the frame info for the originating frame if
+        the window that it was contained in was closed between the time the WebProcess sent the frame
+        ID to the UIProcess and the UIProcess received it.
+
+        * UIProcess/API/APIFrameInfo.cpp:
+        (API::FrameInfo::create):
+        (API::FrameInfo::FrameInfo):
+        (API::FrameInfo::clearPage):
+        * UIProcess/API/APIFrameInfo.h:
+        * UIProcess/API/APIUIClient.h:
+        (API::UIClient::createNewPage):
+        (API::UIClient::createNewPageAsync):
+        * UIProcess/API/C/WKPage.cpp:
+        (WKPageSetPageUIClient):
+        * UIProcess/API/Cocoa/WKFrameInfo.h:
+        * UIProcess/API/Cocoa/WKFrameInfo.mm:
+        (-[WKFrameInfo description]):
+        (-[WKFrameInfo webView]):
+        * UIProcess/API/Cocoa/WKUserContentController.mm:
+        * UIProcess/Cocoa/UIDelegate.h:
+        * UIProcess/Cocoa/UIDelegate.mm:
+        (WebKit::UIDelegate::UIClient::createNewPageCommon):
+        (WebKit::UIDelegate::UIClient::createNewPage):
+        (WebKit::UIDelegate::UIClient::createNewPageAsync):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::decidePolicyForNavigationAction):
+        (WebKit::WebPageProxy::createNewPage):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * WebProcess/Plugins/PluginView.cpp:
+        (WebKit::PluginView::loadURL):
+        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+        (WebKit::WebChromeClient::createWindow):
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+        (WebKit::WebFrameLoaderClient::dispatchCreatePage):
+        (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction):
+        * WebProcess/WebPage/WebInspector.cpp:
+        (WebKit::WebInspector::openInNewTab):
+
 2017-06-29  Jer Noble  <jer.noble@apple.com>
 
         Make Legacy EME API controlled by RuntimeEnabled setting.
index a24a3d6..0319e5a 100644 (file)
 #include "APIFrameHandle.h"
 #include "FrameInfoData.h"
 #include "WebFrameProxy.h"
+#include "WebPageProxy.h"
 
 namespace API {
 
-Ref<FrameInfo> FrameInfo::create(const WebKit::FrameInfoData& frameInfoData)
+Ref<FrameInfo> FrameInfo::create(const WebKit::FrameInfoData& frameInfoData, WebKit::WebPageProxy* page)
 {
-    return adoptRef(*new FrameInfo(frameInfoData));
+    return adoptRef(*new FrameInfo(frameInfoData, page));
 }
 
 Ref<FrameInfo> FrameInfo::create(const WebKit::WebFrameProxy& frame, const WebCore::SecurityOrigin& securityOrigin)
@@ -47,14 +48,15 @@ Ref<FrameInfo> FrameInfo::create(const WebKit::WebFrameProxy& frame, const WebCo
     frameInfoData.securityOrigin = WebCore::SecurityOriginData::fromSecurityOrigin(securityOrigin);
     frameInfoData.frameID = frame.frameID();
 
-    return create(frameInfoData);
+    return create(frameInfoData, frame.page());
 }
 
-FrameInfo::FrameInfo(const WebKit::FrameInfoData& frameInfoData)
-    : m_isMainFrame(frameInfoData.isMainFrame)
-    , m_request(frameInfoData.request)
-    , m_securityOrigin(SecurityOrigin::create(frameInfoData.securityOrigin.securityOrigin()))
-    , m_handle(API::FrameHandle::create(frameInfoData.frameID))
+FrameInfo::FrameInfo(const WebKit::FrameInfoData& frameInfoData, WebKit::WebPageProxy* page)
+    : m_isMainFrame { frameInfoData.isMainFrame }
+    , m_request { frameInfoData.request }
+    , m_securityOrigin { SecurityOrigin::create(frameInfoData.securityOrigin.securityOrigin()) }
+    , m_handle { API::FrameHandle::create(frameInfoData.frameID) }
+    , m_page { makeRefPtr(page) }
 {
 }
 
@@ -62,4 +64,9 @@ FrameInfo::~FrameInfo()
 {
 }
 
+void FrameInfo::clearPage()
+{
+    m_page = nullptr;
+}
+
 } // namespace API
index 29eef55..9793dec 100644 (file)
@@ -34,6 +34,7 @@ class SecurityOrigin;
 
 namespace WebKit {
 class WebFrameProxy;
+class WebPageProxy;
 struct FrameInfoData;
 }
 
@@ -44,7 +45,7 @@ class SecurityOrigin;
 
 class FrameInfo final : public ObjectImpl<Object::Type::FrameInfo> {
 public:
-    static Ref<FrameInfo> create(const WebKit::FrameInfoData&);
+    static Ref<FrameInfo> create(const WebKit::FrameInfoData&, WebKit::WebPageProxy*);
     static Ref<FrameInfo> create(const WebKit::WebFrameProxy&, const WebCore::SecurityOrigin&);
     virtual ~FrameInfo();
 
@@ -52,14 +53,18 @@ public:
     const WebCore::ResourceRequest& request() const { return m_request; }
     SecurityOrigin& securityOrigin() { return m_securityOrigin.get(); }
     API::FrameHandle& handle() { return m_handle.get(); }
+    WebKit::WebPageProxy* page() { return m_page.get(); }
+
+    void clearPage();
 
 private:
-    FrameInfo(const WebKit::FrameInfoData&);
+    FrameInfo(const WebKit::FrameInfoData&, WebKit::WebPageProxy*);
 
     bool m_isMainFrame;
     WebCore::ResourceRequest m_request;
     Ref<SecurityOrigin> m_securityOrigin;
     Ref<FrameHandle> m_handle;
+    RefPtr<WebKit::WebPageProxy> m_page;
 };
 
 } // namespace API
index 1253642..ccb95dc 100644 (file)
@@ -72,8 +72,8 @@ class UIClient {
 public:
     virtual ~UIClient() { }
 
-    virtual RefPtr<WebKit::WebPageProxy> createNewPage(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, const WebCore::SecurityOriginData&, const WebCore::ResourceRequest&, const WebCore::WindowFeatures&, const WebKit::NavigationActionData&) { return nullptr; }
-    virtual bool createNewPageAsync(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, const WebCore::SecurityOriginData&, const WebCore::ResourceRequest&, const WebCore::WindowFeatures&, const WebKit::NavigationActionData&, WTF::Function<void (RefPtr<WebKit::WebPageProxy>)>&& completionHandler) { return false; }
+    virtual RefPtr<WebKit::WebPageProxy> createNewPage(WebKit::WebPageProxy*, API::FrameInfo&, const WebCore::ResourceRequest&, const WebCore::WindowFeatures&, const WebKit::NavigationActionData&) { return nullptr; }
+    virtual bool createNewPageAsync(WebKit::WebPageProxy*, API::FrameInfo&, const WebCore::ResourceRequest&, const WebCore::WindowFeatures&, const WebKit::NavigationActionData&, WTF::Function<void (RefPtr<WebKit::WebPageProxy>)>&& completionHandler) { return false; }
     virtual void showPage(WebKit::WebPageProxy*) { }
     virtual void fullscreenMayReturnToInline(WebKit::WebPageProxy*) { }
     virtual void didEnterFullscreen(WebKit::WebPageProxy*) { }
index b28c0ea..d3c2fe5 100644 (file)
@@ -1704,17 +1704,15 @@ void WKPageSetPageUIClient(WKPageRef pageRef, const WKPageUIClientBase* wkClient
         }
 
     private:
-        RefPtr<WebPageProxy> createNewPage(WebPageProxy* page, WebFrameProxy* initiatingFrame, const SecurityOriginData& securityOriginData, const ResourceRequest& resourceRequest, const WindowFeatures& windowFeatures, const NavigationActionData& navigationActionData) override
+        RefPtr<WebPageProxy> createNewPage(WebPageProxy* page, API::FrameInfo& sourceFrameInfo, const ResourceRequest& resourceRequest, const WindowFeatures& windowFeatures, const NavigationActionData& navigationActionData) override
         {
             if (m_client.createNewPage) {
                 auto configuration = page->configuration().copy();
                 configuration->setRelatedPage(page);
 
-                auto sourceFrameInfo = API::FrameInfo::create(*initiatingFrame, securityOriginData.securityOrigin());
-
                 auto userInitiatedActivity = page->process().userInitiatedActivity(navigationActionData.userGestureTokenIdentifier);
-                bool shouldOpenAppLinks = !hostsAreEqual(WebCore::URL(WebCore::ParsedURLString, initiatingFrame->url()), resourceRequest.url());
-                auto apiNavigationAction = API::NavigationAction::create(navigationActionData, sourceFrameInfo.ptr(), nullptr, resourceRequest, WebCore::URL(), shouldOpenAppLinks, userInitiatedActivity);
+                bool shouldOpenAppLinks = !hostsAreEqual(sourceFrameInfo.request().url(), resourceRequest.url());
+                auto apiNavigationAction = API::NavigationAction::create(navigationActionData, &sourceFrameInfo, nullptr, resourceRequest, WebCore::URL(), shouldOpenAppLinks, userInitiatedActivity);
 
                 auto apiWindowFeatures = API::WindowFeatures::create(windowFeatures);
 
index be66845..62e015b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,6 +29,7 @@
 
 #import <Foundation/Foundation.h>
 #import <WebKit/WKSecurityOrigin.h>
+#import <WebKit/WKWebView.h>
 
 /*! A WKFrameInfo object contains information about a frame on a webpage.
  @discussion An instance of this class is a transient, data-only object;
@@ -53,6 +54,10 @@ WK_CLASS_AVAILABLE(macosx(10.10), ios(8.0))
  */
 @property (nonatomic, readonly) WKSecurityOrigin *securityOrigin WK_API_AVAILABLE(macosx(10.11), ios(9.0));
 
+/*! @abstract The web view of the webpage that contains this frame.
+ */
+@property (nonatomic, readonly, weak) WKWebView *webView WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
+
 @end
 
 NS_ASSUME_NONNULL_END
index 3430fee..226919c 100644 (file)
@@ -29,6 +29,7 @@
 #if WK_API_ENABLED
 
 #import "WKSecurityOriginInternal.h"
+#import "WKWebViewInternal.h"
 #import "_WKFrameHandleInternal.h"
 
 @implementation WKFrameInfo
@@ -42,7 +43,7 @@
 
 - (NSString *)description
 {
-    return [NSString stringWithFormat:@"<%@: %p; isMainFrame = %s; request = %@>", NSStringFromClass(self.class), self, self.mainFrame ? "YES" : "NO", self.request];
+    return [NSString stringWithFormat:@"<%@: %p; webView = %p; isMainFrame = %s; request = %@>", NSStringFromClass(self.class), self, self.webView, self.mainFrame ? "YES" : "NO", self.request];
 }
 
 - (BOOL)isMainFrame
     return wrapper(_frameInfo->securityOrigin());
 }
 
+- (WKWebView *)webView
+{
+    if (WebKit::WebPageProxy* page = _frameInfo->page())
+        return [[fromWebPageProxy(*page) retain] autorelease];
+    return nil;
+}
+
 - (id)copyWithZone:(NSZone *)zone
 {
     return [self retain];
index 38f8c12..3f3c561 100644 (file)
@@ -125,7 +125,7 @@ public:
     void didPostMessage(WebKit::WebPageProxy& page, const WebKit::FrameInfoData& frameInfoData, WebCore::SerializedScriptValue& serializedScriptValue) override
     {
         @autoreleasepool {
-            RetainPtr<WKFrameInfo> frameInfo = wrapper(API::FrameInfo::create(frameInfoData));
+            RetainPtr<WKFrameInfo> frameInfo = wrapper(API::FrameInfo::create(frameInfoData, &page));
             id body = API::SerializedScriptValue::deserialize(serializedScriptValue, 0);
             auto message = adoptNS([[WKScriptMessage alloc] _initWithBody:body webView:fromWebPageProxy(page) frameInfo:frameInfo.get() name:m_name.get()]);
         
index 7b02f34..a4cb7de 100644 (file)
 @class WKWebView;
 @protocol WKUIDelegate;
 
+namespace API {
+class FrameInfo;
+}
+
 namespace WebKit {
 
 class UIDelegate {
@@ -75,9 +79,9 @@ private:
 
     private:
         // API::UIClient
-        RefPtr<WebKit::WebPageProxy> createNewPage(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, const WebCore::SecurityOriginData&, const WebCore::ResourceRequest&, const WebCore::WindowFeatures&, const WebKit::NavigationActionData&) override;
-        bool createNewPageAsync(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, const WebCore::SecurityOriginData&, const WebCore::ResourceRequest&, const WebCore::WindowFeatures&, const WebKit::NavigationActionData&, WTF::Function<void (RefPtr<WebKit::WebPageProxy>)>&& completionHandler) override;
-        RefPtr<WebKit::WebPageProxy> createNewPageCommon(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, const WebCore::SecurityOriginData&, const WebCore::ResourceRequest&, const WebCore::WindowFeatures&, const WebKit::NavigationActionData&, WTF::Function<void (RefPtr<WebKit::WebPageProxy>)>&& completionHandler);
+        RefPtr<WebKit::WebPageProxy> createNewPage(WebKit::WebPageProxy*, API::FrameInfo&, const WebCore::ResourceRequest&, const WebCore::WindowFeatures&, const WebKit::NavigationActionData&) override;
+        bool createNewPageAsync(WebKit::WebPageProxy*, API::FrameInfo&, const WebCore::ResourceRequest&, const WebCore::WindowFeatures&, const WebKit::NavigationActionData&, WTF::Function<void (RefPtr<WebKit::WebPageProxy>)>&& completionHandler) override;
+        RefPtr<WebKit::WebPageProxy> createNewPageCommon(WebKit::WebPageProxy*, API::FrameInfo&, const WebCore::ResourceRequest&, const WebCore::WindowFeatures&, const WebKit::NavigationActionData&, WTF::Function<void (RefPtr<WebKit::WebPageProxy>)>&& completionHandler);
 
         void close(WebKit::WebPageProxy*) override;
         void fullscreenMayReturnToInline(WebKit::WebPageProxy*) override;
index 3003ea3..9f98a31 100644 (file)
@@ -28,6 +28,7 @@
 
 #if WK_API_ENABLED
 
+#import "APIFrameInfo.h"
 #import "CompletionHandlerCallChecker.h"
 #import "NavigationActionData.h"
 #import "UserMediaPermissionCheckProxy.h"
@@ -173,7 +174,7 @@ UIDelegate::UIClient::~UIClient()
 {
 }
 
-RefPtr<WebKit::WebPageProxy> UIDelegate::UIClient::createNewPageCommon(WebKit::WebPageProxy* page, WebKit::WebFrameProxy* initiatingFrame, const WebCore::SecurityOriginData& securityOriginData, const WebCore::ResourceRequest& request, const WebCore::WindowFeatures& windowFeatures, const WebKit::NavigationActionData& navigationActionData, WTF::Function<void (RefPtr<WebKit::WebPageProxy>)>&& completionHandler)
+RefPtr<WebKit::WebPageProxy> UIDelegate::UIClient::createNewPageCommon(WebKit::WebPageProxy* page, API::FrameInfo& sourceFrameInfo, const WebCore::ResourceRequest& request, const WebCore::WindowFeatures& windowFeatures, const WebKit::NavigationActionData& navigationActionData, WTF::Function<void (RefPtr<WebKit::WebPageProxy>)>&& completionHandler)
 {
     auto delegate = m_uiDelegate.m_delegate.get();
     ASSERT(delegate);
@@ -181,11 +182,9 @@ RefPtr<WebKit::WebPageProxy> UIDelegate::UIClient::createNewPageCommon(WebKit::W
     auto configuration = adoptNS([m_uiDelegate.m_webView->_configuration copy]);
     [configuration _setRelatedWebView:m_uiDelegate.m_webView];
 
-    auto sourceFrameInfo = API::FrameInfo::create(*initiatingFrame, securityOriginData.securityOrigin());
-
     auto userInitiatedActivity = page->process().userInitiatedActivity(navigationActionData.userGestureTokenIdentifier);
-    bool shouldOpenAppLinks = !hostsAreEqual(WebCore::URL(WebCore::ParsedURLString, initiatingFrame->url()), request.url());
-    auto apiNavigationAction = API::NavigationAction::create(navigationActionData, sourceFrameInfo.ptr(), nullptr, request, WebCore::URL(), shouldOpenAppLinks, userInitiatedActivity);
+    bool shouldOpenAppLinks = !hostsAreEqual(sourceFrameInfo.request().url(), request.url());
+    auto apiNavigationAction = API::NavigationAction::create(navigationActionData, &sourceFrameInfo, nullptr, request, WebCore::URL(), shouldOpenAppLinks, userInitiatedActivity);
 
     auto apiWindowFeatures = API::WindowFeatures::create(windowFeatures);
 
@@ -222,7 +221,7 @@ RefPtr<WebKit::WebPageProxy> UIDelegate::UIClient::createNewPageCommon(WebKit::W
     return webView->_page.get();
 }
 
-RefPtr<WebKit::WebPageProxy> UIDelegate::UIClient::createNewPage(WebKit::WebPageProxy* page, WebKit::WebFrameProxy* initiatingFrame, const WebCore::SecurityOriginData& securityOriginData, const WebCore::ResourceRequest& request, const WebCore::WindowFeatures& windowFeatures, const WebKit::NavigationActionData& navigationActionData)
+RefPtr<WebKit::WebPageProxy> UIDelegate::UIClient::createNewPage(WebKit::WebPageProxy* page, API::FrameInfo& originatingFrameInfo, const WebCore::ResourceRequest& request, const WebCore::WindowFeatures& windowFeatures, const WebKit::NavigationActionData& navigationActionData)
 {
     if (!m_uiDelegate.m_delegateMethods.webViewCreateWebViewWithConfigurationForNavigationActionWindowFeatures)
         return nullptr;
@@ -231,10 +230,10 @@ RefPtr<WebKit::WebPageProxy> UIDelegate::UIClient::createNewPage(WebKit::WebPage
     if (!delegate)
         return nullptr;
 
-    return createNewPageCommon(page, initiatingFrame, securityOriginData, request, windowFeatures, navigationActionData, nullptr);
+    return createNewPageCommon(page, originatingFrameInfo, request, windowFeatures, navigationActionData, nullptr);
 }
 
-bool UIDelegate::UIClient::createNewPageAsync(WebKit::WebPageProxy* page, WebKit::WebFrameProxy* initiatingFrame, const WebCore::SecurityOriginData& securityOriginData, const WebCore::ResourceRequest& request, const WebCore::WindowFeatures& windowFeatures, const WebKit::NavigationActionData& navigationActionData, WTF::Function<void (RefPtr<WebKit::WebPageProxy>)>&& completionHandler)
+bool UIDelegate::UIClient::createNewPageAsync(WebKit::WebPageProxy* page, API::FrameInfo& originatingFrameInfo, const WebCore::ResourceRequest& request, const WebCore::WindowFeatures& windowFeatures, const WebKit::NavigationActionData& navigationActionData, WTF::Function<void (RefPtr<WebKit::WebPageProxy>)>&& completionHandler)
 {
     if (!m_uiDelegate.m_delegateMethods.webViewCreateWebViewWithConfigurationForNavigationActionWindowFeaturesAsync)
         return false;
@@ -243,7 +242,7 @@ bool UIDelegate::UIClient::createNewPageAsync(WebKit::WebPageProxy* page, WebKit
     if (!delegate)
         return false;
 
-    createNewPageCommon(page, initiatingFrame, securityOriginData, request, windowFeatures, navigationActionData, WTFMove(completionHandler));
+    createNewPageCommon(page, originatingFrameInfo, request, windowFeatures, navigationActionData, WTFMove(completionHandler));
 
     return true;
 }
index b86df18..e0c12f9 100644 (file)
@@ -57,6 +57,7 @@
 #include "DrawingAreaProxy.h"
 #include "DrawingAreaProxyMessages.h"
 #include "EventDispatcherMessages.h"
+#include "FrameInfoData.h"
 #include "LoadParameters.h"
 #include "Logging.h"
 #include "NativeWebGestureEvent.h"
@@ -3598,21 +3599,20 @@ void WebPageProxy::frameDidBecomeFrameSet(uint64_t frameID, bool value)
         m_frameSetLargestFrame = value ? m_mainFrame : 0;
 }
 
-void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const NavigationActionData& navigationActionData, uint64_t originatingFrameID, const SecurityOriginData& originatingFrameSecurityOrigin, const WebCore::ResourceRequest& originalRequest, const ResourceRequest& request, uint64_t listenerID, const UserData& userData, Ref<Messages::WebPageProxy::DecidePolicyForNavigationAction::DelayedReply>&& reply)
+void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const NavigationActionData& navigationActionData, const FrameInfoData& originatingFrameInfoData, uint64_t originatingPageID, const WebCore::ResourceRequest& originalRequest, const ResourceRequest& request, uint64_t listenerID, const UserData& userData, Ref<Messages::WebPageProxy::DecidePolicyForNavigationAction::DelayedReply>&& reply)
 {
     PageClientProtector protector(m_pageClient);
 
     auto transaction = m_pageLoadState.transaction();
 
-    if (request.url() != m_pageLoadState.pendingAPIRequestURL())
+    bool fromAPI = request.url() == m_pageLoadState.pendingAPIRequestURL();
+    if (!fromAPI)
         m_pageLoadState.clearPendingAPIRequestURL(transaction);
 
     WebFrameProxy* frame = m_process->webFrame(frameID);
     MESSAGE_CHECK(frame);
     MESSAGE_CHECK_URL(request.url());
     MESSAGE_CHECK_URL(originalRequest.url());
-
-    WebFrameProxy* originatingFrame = m_process->webFrame(originatingFrameID);
     
     m_newNavigationID = 0;
     Ref<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
@@ -3635,17 +3635,19 @@ void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, const Secur
 #endif
     m_navigationActionPolicyReply = WTFMove(reply);
 
+    WebFrameProxy* originatingFrame = m_process->webFrame(originatingFrameInfoData.frameID);
+
     if (m_navigationClient) {
-        RefPtr<API::FrameInfo> destinationFrameInfo;
+        RefPtr<API::FrameInfo> destinationFrameInfo = API::FrameInfo::create(*frame, frameSecurityOrigin.securityOrigin());
         RefPtr<API::FrameInfo> sourceFrameInfo;
-
-        if (frame)
-            destinationFrameInfo = API::FrameInfo::create(*frame, frameSecurityOrigin.securityOrigin());
-
         if (originatingFrame == frame)
             sourceFrameInfo = destinationFrameInfo;
-        else if (originatingFrame)
-            sourceFrameInfo = API::FrameInfo::create(*originatingFrame, originatingFrameSecurityOrigin.securityOrigin());
+        else
+            sourceFrameInfo = API::FrameInfo::create(originatingFrameInfoData, m_process->webPage(originatingPageID));
+        if (fromAPI) {
+            sourceFrameInfo->clearPage();
+            destinationFrameInfo->clearPage();
+        }
 
         auto userInitiatedActivity = m_process->userInitiatedActivity(navigationActionData.userGestureTokenIdentifier);
         bool shouldOpenAppLinks = !m_shouldSuppressAppLinksInNextNavigationPolicyDecision && (!destinationFrameInfo || destinationFrameInfo->isMainFrame()) && !hostsAreEqual(URL(ParsedURLString, m_mainFrame->url()), request.url()) && navigationActionData.navigationType != WebCore::NavigationType::BackForward;
@@ -3816,10 +3818,10 @@ void WebPageProxy::didUpdateHistoryTitle(const String& title, const String& url,
 
 // UIClient
 
-void WebPageProxy::createNewPage(uint64_t frameID, const SecurityOriginData& securityOriginData, const ResourceRequest& request, const WindowFeatures& windowFeatures, const NavigationActionData& navigationActionData, RefPtr<Messages::WebPageProxy::CreateNewPage::DelayedReply> reply)
+void WebPageProxy::createNewPage(const FrameInfoData& originatingFrameInfoData, uint64_t originatingPageID, const ResourceRequest& request, const WindowFeatures& windowFeatures, const NavigationActionData& navigationActionData, RefPtr<Messages::WebPageProxy::CreateNewPage::DelayedReply> reply)
 {
-    WebFrameProxy* frame = m_process->webFrame(frameID);
-    MESSAGE_CHECK(frame);
+    MESSAGE_CHECK(m_process->webFrame(originatingFrameInfoData.frameID));
+    auto originatingFrameInfo = API::FrameInfo::create(originatingFrameInfoData, m_process->webPage(originatingPageID));
 
     auto mainFrameURL = m_mainFrame->url();
 
@@ -3836,10 +3838,10 @@ void WebPageProxy::createNewPage(uint64_t frameID, const SecurityOriginData& sec
 
     };
 
-    if (m_uiClient->createNewPageAsync(this, frame, securityOriginData, request, windowFeatures, navigationActionData, [completionHandler](RefPtr<WebPageProxy> newPage) { completionHandler(newPage); }))
+    if (m_uiClient->createNewPageAsync(this, originatingFrameInfo, request, windowFeatures, navigationActionData, [completionHandler](RefPtr<WebPageProxy> newPage) { completionHandler(newPage); }))
         return;
 
-    RefPtr<WebPageProxy> newPage = m_uiClient->createNewPage(this, frame, securityOriginData, request, windowFeatures, navigationActionData);
+    RefPtr<WebPageProxy> newPage = m_uiClient->createNewPage(this, originatingFrameInfo, request, windowFeatures, navigationActionData);
     completionHandler(WTFMove(newPage));
 }
     
index 3fb24c4..6bd794a 100644 (file)
@@ -218,6 +218,7 @@ struct AttributedString;
 struct ColorSpaceData;
 struct EditingRange;
 struct EditorState;
+struct FrameInfoData;
 struct InteractionInformationRequest;
 struct LoadParameters;
 struct PlatformPopupMenuData;
@@ -1273,7 +1274,7 @@ private:
 
     void didDestroyNavigation(uint64_t navigationID);
 
-    void decidePolicyForNavigationAction(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const NavigationActionData&, uint64_t originatingFrameID, const WebCore::SecurityOriginData& originatingFrameSecurityOrigin, const WebCore::ResourceRequest& originalRequest, const WebCore::ResourceRequest&, uint64_t listenerID, const UserData&, Ref<Messages::WebPageProxy::DecidePolicyForNavigationAction::DelayedReply>&&);
+    void decidePolicyForNavigationAction(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const NavigationActionData&, const FrameInfoData&, uint64_t originatingPageID, const WebCore::ResourceRequest& originalRequest, const WebCore::ResourceRequest&, uint64_t listenerID, const UserData&, Ref<Messages::WebPageProxy::DecidePolicyForNavigationAction::DelayedReply>&&);
     void decidePolicyForNewWindowAction(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, const NavigationActionData&, const WebCore::ResourceRequest&, const String& frameName, uint64_t listenerID, const UserData&);
     void decidePolicyForResponse(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, uint64_t listenerID, const UserData&);
     void decidePolicyForResponseSync(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, uint64_t listenerID, const UserData&, Ref<Messages::WebPageProxy::DecidePolicyForResponseSync::DelayedReply>&&);
@@ -1288,7 +1289,7 @@ private:
     void didUpdateHistoryTitle(const String& title, const String& url, uint64_t frameID);
 
     // UI client
-    void createNewPage(uint64_t frameID, const WebCore::SecurityOriginData&, const WebCore::ResourceRequest&, const WebCore::WindowFeatures&, const NavigationActionData&, RefPtr<Messages::WebPageProxy::CreateNewPage::DelayedReply>);
+    void createNewPage(const FrameInfoData&, uint64_t originatingPageID, const WebCore::ResourceRequest&, const WebCore::WindowFeatures&, const NavigationActionData&, RefPtr<Messages::WebPageProxy::CreateNewPage::DelayedReply>);
     void showPage();
     void runJavaScriptAlert(uint64_t frameID, const WebCore::SecurityOriginData&, const String&, Ref<Messages::WebPageProxy::RunJavaScriptAlert::DelayedReply>&&);
     void runJavaScriptConfirm(uint64_t frameID, const WebCore::SecurityOriginData&, const String&, Ref<Messages::WebPageProxy::RunJavaScriptConfirm::DelayedReply>&&);
index 4243897..bb0e444 100644 (file)
@@ -22,7 +22,7 @@
 
 messages -> WebPageProxy {
     # UI messages
-    CreateNewPage(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, WebCore::ResourceRequest request, struct WebCore::WindowFeatures windowFeatures, struct WebKit::NavigationActionData navigationActionData) -> (uint64_t newPageID, struct WebKit::WebPageCreationParameters newPageParameters) Delayed
+    CreateNewPage(struct WebKit::FrameInfoData originatingFrameInfoData, uint64_t originatingPageID, WebCore::ResourceRequest request, struct WebCore::WindowFeatures windowFeatures, struct WebKit::NavigationActionData navigationActionData) -> (uint64_t newPageID, struct WebKit::WebPageCreationParameters newPageParameters) Delayed
     ShowPage()
     ClosePage(bool stopResponsivenessTimer)
     RunJavaScriptAlert(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, String message) -> () Delayed
@@ -100,7 +100,7 @@ messages -> WebPageProxy {
 
     # Policy messages
     DecidePolicyForResponseSync(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, WebCore::ResourceResponse response, WebCore::ResourceRequest request, bool canShowMIMEType, uint64_t listenerID, WebKit::UserData userData) -> (uint64_t policyAction, WebKit::DownloadID downloadID) Delayed
-    DecidePolicyForNavigationAction(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, uint64_t navigationID, struct WebKit::NavigationActionData navigationActionData, uint64_t originatingFrameID, struct WebCore::SecurityOriginData originatingFrameSecurityOrigin, WebCore::ResourceRequest originalRequest, WebCore::ResourceRequest request, uint64_t listenerID, WebKit::UserData userData) -> (uint64_t newNavigationID, uint64_t policyAction, WebKit::DownloadID downloadID, struct WebKit::WebsitePolicies websitePolicies) Delayed
+    DecidePolicyForNavigationAction(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, uint64_t navigationID, struct WebKit::NavigationActionData navigationActionData, struct WebKit::FrameInfoData originatingFrameInfoData, uint64_t originatingPageID, WebCore::ResourceRequest originalRequest, WebCore::ResourceRequest request, uint64_t listenerID, WebKit::UserData userData) -> (uint64_t newNavigationID, uint64_t policyAction, WebKit::DownloadID downloadID, struct WebKit::WebsitePolicies websitePolicies) Delayed
     DecidePolicyForNewWindowAction(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, struct WebKit::NavigationActionData navigationActionData, WebCore::ResourceRequest request, String frameName, uint64_t listenerID, WebKit::UserData userData)
     UnableToImplementPolicy(uint64_t frameID, WebCore::ResourceError error, WebKit::UserData userData)
 
index 3b86687..c58c5cb 100644 (file)
@@ -1388,7 +1388,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(), { }, target, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
+    FrameLoadRequest frameLoadRequest { m_pluginElement->document(), m_pluginElement->document().securityOrigin(), { }, target, 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 88455d9..df7ed2f 100644 (file)
@@ -31,6 +31,7 @@
 #include "APISecurityOrigin.h"
 #include "DrawingArea.h"
 #include "FindController.h"
+#include "FrameInfoData.h"
 #include "HangDetectionDisabler.h"
 #include "InjectedBundleNavigationAction.h"
 #include "InjectedBundleNodeHandle.h"
@@ -234,8 +235,6 @@ Page* WebChromeClient::createWindow(Frame& frame, const FrameLoadRequest& reques
 
     auto& webProcess = WebProcess::singleton();
 
-    WebFrame* webFrame = WebFrame::fromCoreFrame(frame);
-
     NavigationActionData navigationActionData;
     navigationActionData.navigationType = navigationAction.type();
     navigationActionData.modifiers = InjectedBundleNavigationAction::modifiersForNavigationAction(navigationAction);
@@ -246,9 +245,11 @@ Page* WebChromeClient::createWindow(Frame& frame, const FrameLoadRequest& reques
     navigationActionData.shouldOpenExternalURLsPolicy = navigationAction.shouldOpenExternalURLsPolicy();
     navigationActionData.downloadAttribute = navigationAction.downloadAttribute();
 
+    WebFrame* webFrame = WebFrame::fromCoreFrame(frame);
+
     uint64_t newPageID = 0;
     WebPageCreationParameters parameters;
-    if (!webProcess.parentProcessConnection()->sendSync(Messages::WebPageProxy::CreateNewPage(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), request.resourceRequest(), windowFeatures, navigationActionData), Messages::WebPageProxy::CreateNewPage::Reply(newPageID, parameters), m_page.pageID()))
+    if (!webProcess.parentProcessConnection()->sendSync(Messages::WebPageProxy::CreateNewPage(webFrame->info(), webFrame->page()->pageID(), request.resourceRequest(), windowFeatures, navigationActionData), Messages::WebPageProxy::CreateNewPage::Reply(newPageID, parameters), m_page.pageID()))
         return nullptr;
 
     if (!newPageID)
index 85b84e7..ffdaf03 100644 (file)
@@ -30,6 +30,7 @@
 #include "DataReference.h"
 #include "DrawingArea.h"
 #include "FindController.h"
+#include "FrameInfoData.h"
 #include "InjectedBundle.h"
 #include "InjectedBundleBackForwardListItem.h"
 #include "InjectedBundleDOMWindowExtension.h"
@@ -657,7 +658,7 @@ Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction& navigati
         return nullptr;
 
     // Just call through to the chrome client.
-    FrameLoadRequest frameLoadRequest { m_frame->coreFrame()->document()->securityOrigin(), navigationAction.resourceRequest(), { }, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, navigationAction.shouldOpenExternalURLsPolicy() };
+    FrameLoadRequest frameLoadRequest { *m_frame->coreFrame()->document(), 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(), frameLoadRequest, { }, navigationAction);
     if (!newPage)
         return nullptr;
@@ -779,26 +780,8 @@ void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const Navigat
     uint64_t policyAction;
     DownloadID downloadID;
 
-    RefPtr<WebFrame> originatingFrame;
-    switch (action->navigationType()) {
-    case NavigationType::LinkClicked:
-        if (EventTarget* target = navigationAction.event()->target()) {
-            if (Node* node = target->toNode()) {
-                if (Frame* frame = node->document().frame())
-                    originatingFrame = WebFrame::fromCoreFrame(*frame);
-            }
-        }
-        break;
-    case NavigationType::FormSubmitted:
-    case NavigationType::FormResubmitted:
-        if (formState)
-            originatingFrame = WebFrame::fromCoreFrame(*formState->sourceDocument().frame());
-        break;
-    case NavigationType::BackForward:
-    case NavigationType::Reload:
-    case NavigationType::Other:
-        break;
-    }
+    ASSERT(navigationAction.sourceDocument());
+    RefPtr<WebFrame> originatingFrame = WebFrame::fromCoreFrame(*navigationAction.sourceDocument()->frame());
 
     NavigationActionData navigationActionData;
     navigationActionData.navigationType = action->navigationType();
@@ -822,9 +805,8 @@ void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const Navigat
 
     // Notify the UIProcess.
     Ref<WebFrame> protect(*m_frame);
-    WebCore::Frame* originatingCoreFrame = originatingFrame ? originatingFrame->coreFrame() : nullptr;
     WebsitePolicies websitePolicies;
-    if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForNavigationAction(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), documentLoader->navigationID(), navigationActionData, originatingFrame ? originatingFrame->frameID() : 0, SecurityOriginData::fromFrame(originatingCoreFrame), navigationAction.resourceRequest(), request, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())), Messages::WebPageProxy::DecidePolicyForNavigationAction::Reply(newNavigationID, policyAction, downloadID, websitePolicies))) {
+    if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForNavigationAction(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), documentLoader->navigationID(), navigationActionData, originatingFrame ? originatingFrame->info() : FrameInfoData(), originatingFrame && originatingFrame->page() ? originatingFrame->page()->pageID() : 0, navigationAction.resourceRequest(), request, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())), Messages::WebPageProxy::DecidePolicyForNavigationAction::Reply(newNavigationID, policyAction, downloadID, websitePolicies))) {
         m_frame->didReceivePolicyDecision(listenerID, PolicyIgnore, 0, { });
         return;
     }
index c014da6..226879c 100644 (file)
@@ -146,9 +146,10 @@ void WebInspector::openInNewTab(const String& urlString)
         return;
 
     Frame& inspectedMainFrame = inspectedPage->mainFrame();
-    FrameLoadRequest frameLoadRequest { inspectedMainFrame.document()->securityOrigin(), { urlString }, ASCIILiteral("_blank"), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
+    FrameLoadRequest frameLoadRequest { *inspectedMainFrame.document(), inspectedMainFrame.document()->securityOrigin(), { urlString }, ASCIILiteral("_blank"), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
 
-    Page* newPage = inspectedPage->chrome().createWindow(inspectedMainFrame, frameLoadRequest, { }, NavigationAction(frameLoadRequest.resourceRequest(), NavigationType::LinkClicked));
+    NavigationAction action { *inspectedMainFrame.document(), frameLoadRequest.resourceRequest(), NavigationType::LinkClicked };
+    Page* newPage = inspectedPage->chrome().createWindow(inspectedMainFrame, frameLoadRequest, { }, action);
     if (!newPage)
         return;
 
index 36507e1..74bb695 100644 (file)
@@ -1,3 +1,21 @@
+2017-06-30  Daniel Bates  <dabates@apple.com>
+
+        API::FrameInfo should know the web page that contains the frame; add API property webView to WKFrameInfo
+        https://bugs.webkit.org/show_bug.cgi?id=165160
+        <rdar://problem/29451999>
+
+        Reviewed by Brady Eidson.
+
+        Add tests to ensure that -[WKFrameInfo webView] is computed correctly for the source and target frame
+        for navigations and window creation.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKit2Cocoa/DecidePolicyForNavigationAction.mm: Added. Derived from file ShouldOpenExternalURLsInNewWindowActions.mm.
+        (-[DecidePolicyForNavigationActionController webView:decidePolicyForNavigationAction:decisionHandler:]):
+        (-[DecidePolicyForNavigationActionController webView:didFinishNavigation:]):
+        (-[DecidePolicyForNavigationActionController webView:createWebViewWithConfiguration:forNavigationAction:windowFeatures:]):
+        (TEST):
+
 2017-06-29  Jer Noble  <jer.noble@apple.com>
 
         Make Legacy EME API controlled by RuntimeEnabled setting.
index e1fb255..2ad086e 100644 (file)
                CEBCA1391E3A807A00C73293 /* page-with-csp-iframe.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CEBCA1341E3A803400C73293 /* page-with-csp-iframe.html */; };
                CEBCA13A1E3A807A00C73293 /* page-without-csp.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CEBCA1371E3A803400C73293 /* page-without-csp.html */; };
                CEBCA13B1E3A807A00C73293 /* page-without-csp-iframe.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CEBCA1361E3A803400C73293 /* page-without-csp-iframe.html */; };
+               CEC16EA51EE863C000DE479A /* DecidePolicyForNavigationAction.mm in Sources */ = {isa = PBXBuildFile; fileRef = CEC16EA41EE863BF00DE479A /* DecidePolicyForNavigationAction.mm */; };
                D34E08761E4E42E1005FF14A /* WKWebViewGetContents.mm in Sources */ = {isa = PBXBuildFile; fileRef = D3BE5E341E4CE85E00FD563A /* WKWebViewGetContents.mm */; };
                E1220DCA155B28AA0013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = E1220DC9155B287D0013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.html */; };
                E194E1BD177E53C7009C4D4E /* StopLoadingFromDidReceiveResponse.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = E194E1BC177E534A009C4D4E /* StopLoadingFromDidReceiveResponse.html */; };
                CEBCA1351E3A803400C73293 /* page-with-csp.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "page-with-csp.html"; sourceTree = "<group>"; };
                CEBCA1361E3A803400C73293 /* page-without-csp-iframe.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "page-without-csp-iframe.html"; sourceTree = "<group>"; };
                CEBCA1371E3A803400C73293 /* page-without-csp.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "page-without-csp.html"; sourceTree = "<group>"; };
+               CEC16EA41EE863BF00DE479A /* DecidePolicyForNavigationAction.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DecidePolicyForNavigationAction.mm; sourceTree = "<group>"; };
                D3BE5E341E4CE85E00FD563A /* WKWebViewGetContents.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKWebViewGetContents.mm; sourceTree = "<group>"; };
                DC69AA621CF77C6500C6272F /* ScopedLambda.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScopedLambda.cpp; sourceTree = "<group>"; };
                E1220D9F155B25480013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MemoryCacheDisableWithinResourceLoadDelegate.mm; sourceTree = "<group>"; };
                                A14FC5891B89927100D107EB /* ContentFilteringPlugIn.mm */,
                                5C2936911D5BF63E00DEAB1E /* CookieAcceptPolicy.mm */,
                                2DC4CF761D2D9DD800ECCC94 /* DataDetection.mm */,
+                               CEC16EA41EE863BF00DE479A /* DecidePolicyForNavigationAction.mm */,
                                2DC60E221E79F88C00FA6C7D /* DoAfterNextPresentationUpdateAfterCrash.mm */,
                                A1A4FE5D18DD3DB700B5EA8A /* Download.mm */,
                                A15502281E05020B00A24C57 /* DuplicateCompletionHandlerCalls.mm */,
                                7CCE7EBA1A411A7E00447C4C /* DeviceScaleFactorOnBack.mm in Sources */,
                                7C83E04D1D0A641800FEBCF3 /* DFACombiner.cpp in Sources */,
                                7C83E04E1D0A641800FEBCF3 /* DFAMinimizer.cpp in Sources */,
+                               CEC16EA51EE863C000DE479A /* DecidePolicyForNavigationAction.mm in Sources */,
                                7CCE7EE91A411AE600447C4C /* DidAssociateFormControls.cpp in Sources */,
                                7CCE7EEA1A411AE600447C4C /* DidNotHandleKeyDown.cpp in Sources */,
                                AD57AC211DA7465B00FF1BDE /* DidRemoveFrameFromHiearchyInPageCache.cpp in Sources */,
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/DecidePolicyForNavigationAction.mm b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/DecidePolicyForNavigationAction.mm
new file mode 100644 (file)
index 0000000..7b2b8ab
--- /dev/null
@@ -0,0 +1,381 @@
+/*
+ * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if PLATFORM(MAC)
+
+#import "PlatformUtilities.h"
+#import <wtf/RetainPtr.h>
+#import <wtf/mac/AppKitCompatibilityDeclarations.h>
+
+#if WK_API_ENABLED
+
+static bool createdWebView;
+static bool decidedPolicy;
+static bool finishedNavigation;
+static RetainPtr<WKNavigationAction> action;
+static RetainPtr<WKWebView> newWebView;
+
+static NSString *firstURL = @"data:text/html,First";
+static NSString *secondURL = @"data:text/html,Second";
+
+@interface DecidePolicyForNavigationActionController : NSObject <WKNavigationDelegate, WKUIDelegate>
+@end
+
+@implementation DecidePolicyForNavigationActionController
+
+- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
+{
+    decisionHandler(webView == newWebView.get() ? WKNavigationActionPolicyCancel : WKNavigationActionPolicyAllow);
+
+    action = navigationAction;
+    decidedPolicy = true;
+}
+
+- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
+{
+    finishedNavigation = true;
+}
+
+- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
+{
+    action = navigationAction;
+    newWebView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration]);
+
+    createdWebView = true;
+    return newWebView.get();
+}
+
+@end
+
+TEST(WebKit2, DecidePolicyForNavigationActionReload)
+{
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+
+    auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
+    [[window contentView] addSubview:webView.get()];
+
+    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
+    [webView setNavigationDelegate:controller.get()];
+    [webView setUIDelegate:controller.get()];
+
+    finishedNavigation = false;
+    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:firstURL]]];
+    TestWebKitAPI::Util::run(&finishedNavigation);
+
+    decidedPolicy = false;
+    [webView reload];
+    TestWebKitAPI::Util::run(&decidedPolicy);
+
+    EXPECT_EQ(WKNavigationTypeReload, [action navigationType]);
+    EXPECT_TRUE([action sourceFrame] == [action targetFrame]);
+    EXPECT_WK_STREQ(firstURL, [[[action request] URL] absoluteString]);
+    EXPECT_WK_STREQ(firstURL, [[[[action sourceFrame] request] URL] absoluteString]);
+    EXPECT_EQ(nil, [[action sourceFrame] webView]);
+
+    newWebView = nullptr;
+    action = nullptr;
+}
+
+TEST(WebKit2, DecidePolicyForNavigationActionReloadFromOrigin)
+{
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+
+    auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
+    [[window contentView] addSubview:webView.get()];
+
+    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
+    [webView setNavigationDelegate:controller.get()];
+    [webView setUIDelegate:controller.get()];
+
+    finishedNavigation = false;
+    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:firstURL]]];
+    TestWebKitAPI::Util::run(&finishedNavigation);
+
+    decidedPolicy = false;
+    [webView reloadFromOrigin];
+    TestWebKitAPI::Util::run(&decidedPolicy);
+
+    EXPECT_EQ(WKNavigationTypeReload, [action navigationType]);
+    EXPECT_TRUE([action sourceFrame] == [action targetFrame]);
+    EXPECT_WK_STREQ(firstURL, [[[action request] URL] absoluteString]);
+    EXPECT_WK_STREQ(firstURL, [[[[action sourceFrame] request] URL] absoluteString]);
+    EXPECT_EQ(nil, [[action sourceFrame] webView]);
+
+    newWebView = nullptr;
+    action = nullptr;
+}
+
+TEST(WebKit2, DecidePolicyForNavigationActionGoBack)
+{
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+
+    auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
+    [[window contentView] addSubview:webView.get()];
+
+    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
+    [webView setNavigationDelegate:controller.get()];
+    [webView setUIDelegate:controller.get()];
+
+    finishedNavigation = false;
+    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:firstURL]]];
+    TestWebKitAPI::Util::run(&finishedNavigation);
+
+    finishedNavigation = false;
+    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:secondURL]]];
+    TestWebKitAPI::Util::run(&finishedNavigation);
+
+    decidedPolicy = false;
+    [webView goBack];
+    TestWebKitAPI::Util::run(&decidedPolicy);
+
+    EXPECT_EQ(WKNavigationTypeBackForward, [action navigationType]);
+    EXPECT_TRUE([action sourceFrame] == [action targetFrame]);
+    EXPECT_WK_STREQ(firstURL, [[[action request] URL] absoluteString]);
+    EXPECT_WK_STREQ(secondURL, [[[[action sourceFrame] request] URL] absoluteString]);
+    EXPECT_EQ(nil, [[action sourceFrame] webView]);
+
+    newWebView = nullptr;
+    action = nullptr;
+}
+
+TEST(WebKit2, DecidePolicyForNavigationActionGoForward)
+{
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+
+    auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
+    [[window contentView] addSubview:webView.get()];
+
+    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
+    [webView setNavigationDelegate:controller.get()];
+    [webView setUIDelegate:controller.get()];
+
+    finishedNavigation = false;
+    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:firstURL]]];
+    TestWebKitAPI::Util::run(&finishedNavigation);
+
+    finishedNavigation = false;
+    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:secondURL]]];
+    TestWebKitAPI::Util::run(&finishedNavigation);
+
+    finishedNavigation = false;
+    [webView goBack];
+    TestWebKitAPI::Util::run(&finishedNavigation);
+
+    decidedPolicy = false;
+    [webView goForward];
+    TestWebKitAPI::Util::run(&decidedPolicy);
+
+    EXPECT_EQ(WKNavigationTypeBackForward, [action navigationType]);
+    EXPECT_TRUE([action sourceFrame] == [action targetFrame]);
+    EXPECT_WK_STREQ(secondURL, [[[action request] URL] absoluteString]);
+    EXPECT_WK_STREQ(firstURL, [[[[action sourceFrame] request] URL] absoluteString]);
+    EXPECT_EQ(nil, [[action sourceFrame] webView]);
+
+    newWebView = nullptr;
+    action = nullptr;
+}
+
+TEST(WebKit2, DecidePolicyForNavigationActionOpenNewWindowAndDeallocSourceWebView)
+{
+    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
+
+    @autoreleasepool {
+        auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+
+        auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
+        [[window contentView] addSubview:webView.get()];
+
+        [webView setNavigationDelegate:controller.get()];
+        [webView setUIDelegate:controller.get()];
+
+        createdWebView = false;
+        [webView loadHTMLString:@"<script>window.open('http://webkit.org/destination.html')</script>" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
+        TestWebKitAPI::Util::run(&createdWebView);
+    }
+
+    decidedPolicy = false;
+    [newWebView setNavigationDelegate:controller.get()];
+    TestWebKitAPI::Util::run(&decidedPolicy);
+
+    EXPECT_EQ(WKNavigationTypeOther, [action navigationType]);
+    EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
+    EXPECT_EQ(nil, [[action sourceFrame] webView]);
+    EXPECT_EQ(newWebView.get(), [[action targetFrame] webView]);
+
+    newWebView = nullptr;
+    action = nullptr;
+}
+
+TEST(WebKit2, DecidePolicyForNavigationActionForTargetedHyperlink)
+{
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+
+    auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
+    [[window contentView] addSubview:webView.get()];
+
+    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
+    [webView setNavigationDelegate:controller.get()];
+    [webView setUIDelegate:controller.get()];
+
+    finishedNavigation = false;
+    [webView loadHTMLString:@"<a style=\"display: block; height: 100%\" href=\"https://webkit.org/destination2.html\" target=\"B\">" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
+    TestWebKitAPI::Util::run(&finishedNavigation);
+
+    createdWebView = false;
+    [webView evaluateJavaScript:@"window.open(\"https://webkit.org/destination1.html\", \"B\")" completionHandler:nil];
+    TestWebKitAPI::Util::run(&createdWebView);
+
+    EXPECT_EQ(WKNavigationTypeOther, [action navigationType]);
+    EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
+    EXPECT_EQ(nil, [action targetFrame]);
+    EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
+    EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
+    EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
+
+    // Wait for newWebView to ask to load its initial document.
+    decidedPolicy = false;
+    [newWebView setNavigationDelegate:controller.get()];
+    TestWebKitAPI::Util::run(&decidedPolicy);
+
+    decidedPolicy = false;
+    [newWebView setNavigationDelegate:controller.get()];
+    NSPoint clickPoint = NSMakePoint(100, 100);
+    [[webView hitTest:clickPoint] mouseDown:[NSEvent mouseEventWithType:NSEventTypeLeftMouseDown location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
+    [[webView hitTest:clickPoint] mouseUp:[NSEvent mouseEventWithType:NSEventTypeLeftMouseUp location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
+    TestWebKitAPI::Util::run(&decidedPolicy);
+
+    EXPECT_EQ(WKNavigationTypeLinkActivated, [action navigationType]);
+    EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
+    EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
+    EXPECT_EQ(newWebView.get(), [[action targetFrame] webView]);
+    EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
+    EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
+
+    newWebView = nullptr;
+    action = nullptr;
+}
+
+TEST(WebKit2, DecidePolicyForNavigationActionForTargetedWindowOpen)
+{
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+
+    auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
+    [[window contentView] addSubview:webView.get()];
+
+    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
+    [webView setNavigationDelegate:controller.get()];
+    [webView setUIDelegate:controller.get()];
+
+    finishedNavigation = false;
+    [webView loadHTMLString:@"<a style=\"display: block; height: 100%\" href=\"javascript:window.open('https://webkit.org/destination2.html', 'B')\">" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
+    TestWebKitAPI::Util::run(&finishedNavigation);
+
+    createdWebView = false;
+    [webView evaluateJavaScript:@"window.open(\"https://webkit.org/destination1.html\", \"B\")" completionHandler:nil];
+    TestWebKitAPI::Util::run(&createdWebView);
+
+    EXPECT_EQ(WKNavigationTypeOther, [action navigationType]);
+    EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
+    EXPECT_EQ(nil, [action targetFrame]);
+    EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
+    EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
+    EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
+
+    // Wait for newWebView to ask to load its initial document.
+    decidedPolicy = false;
+    [newWebView setNavigationDelegate:controller.get()];
+    TestWebKitAPI::Util::run(&decidedPolicy);
+
+    decidedPolicy = false;
+    [newWebView setNavigationDelegate:controller.get()];
+    NSPoint clickPoint = NSMakePoint(100, 100);
+    [[webView hitTest:clickPoint] mouseDown:[NSEvent mouseEventWithType:NSEventTypeLeftMouseDown location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
+    [[webView hitTest:clickPoint] mouseUp:[NSEvent mouseEventWithType:NSEventTypeLeftMouseUp location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
+    TestWebKitAPI::Util::run(&decidedPolicy);
+
+    EXPECT_EQ(WKNavigationTypeOther, [action navigationType]);
+    EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
+    EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
+    EXPECT_EQ(newWebView.get(), [[action targetFrame] webView]);
+    EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
+    EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
+
+    newWebView = nullptr;
+    action = nullptr;
+}
+
+TEST(WebKit2, DecidePolicyForNavigationActionForTargetedFormSubmission)
+{
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+
+    auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
+    [[window contentView] addSubview:webView.get()];
+
+    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
+    [webView setNavigationDelegate:controller.get()];
+    [webView setUIDelegate:controller.get()];
+
+    finishedNavigation = false;
+    [webView loadHTMLString:@"<form action=\"https://webkit.org/destination1.html\" target=\"B\"><input type=\"submit\" name=\"submit\" value=\"Submit\" style=\"-webkit-appearance: none; height: 100%; width: 100%\"></form>" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
+    TestWebKitAPI::Util::run(&finishedNavigation);
+
+    createdWebView = false;
+    [webView evaluateJavaScript:@"window.open(\"https://webkit.org/destination2.html\", \"B\")" completionHandler:nil];
+    TestWebKitAPI::Util::run(&createdWebView);
+
+    EXPECT_EQ(WKNavigationTypeOther, [action navigationType]);
+    EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
+    EXPECT_EQ(nil, [action targetFrame]);
+    EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
+    EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
+    EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
+
+    // Wait for newWebView to ask to load its initial document.
+    decidedPolicy = false;
+    [newWebView setNavigationDelegate:controller.get()];
+    TestWebKitAPI::Util::run(&decidedPolicy);
+
+    decidedPolicy = false;
+    NSPoint clickPoint = NSMakePoint(100, 100);
+    [[webView hitTest:clickPoint] mouseDown:[NSEvent mouseEventWithType:NSEventTypeLeftMouseDown location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
+    [[webView hitTest:clickPoint] mouseUp:[NSEvent mouseEventWithType:NSEventTypeLeftMouseUp location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
+    TestWebKitAPI::Util::run(&decidedPolicy);
+
+    EXPECT_EQ(WKNavigationTypeFormSubmitted, [action navigationType]);
+    EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
+    EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
+    EXPECT_EQ(newWebView.get(), [[action targetFrame] webView]);
+    EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
+    EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
+
+    newWebView = nullptr;
+    action = nullptr;
+}
+
+#endif
+
+#endif