Allow navigations in subframes to get a ShouldOpenExternalURLsPolicy of "ShouldAllow".
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 Jul 2017 00:01:53 +0000 (00:01 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 Jul 2017 00:01:53 +0000 (00:01 +0000)
<rdar://problem/22485589> and https://bugs.webkit.org/show_bug.cgi?id=174178

Reviewed by Alex Christensen.

Source/WebCore:

Test: loader/navigation-policy/should-open-external-urls/subframe-navigated-programatically-by-main-frame.html

This patch introduces a new flag to FrameLoadRequest to track when it is known with certainty that a
FrameLoadRequest originates from the main frame.

Later, when calculating the final ShouldOpenExternalURLsPolicy, main frames navigating iframes get to propagate
their permissions to the iframe.

* bindings/js/CommonVM.cpp:
(WebCore::lexicalFrameFromCommonVM): Helper to grab the current frame associated with the current JS callstack.
* bindings/js/CommonVM.h:

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

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

Add the new flag to FrameLoadRequest (and force almost everybody to explicitly include the flag):
* loader/FrameLoadRequest.cpp:
(WebCore::FrameLoadRequest::FrameLoadRequest):
* loader/FrameLoadRequest.h:
(WebCore::FrameLoadRequest::FrameLoadRequest):
(WebCore::FrameLoadRequest::navigationInitiatedByMainFrame):

* loader/FrameLoader.cpp:
(WebCore::FrameLoader::urlSelected):
(WebCore::FrameLoader::loadURLIntoChildFrame):
(WebCore::shouldOpenExternalURLsPolicyToApply): Helper that takes the new flag into account when deciding
  what the final ShouldOpenExternalURLsPolicy will be.
(WebCore::applyShouldOpenExternalURLsPolicyToNewDocumentLoader):
(WebCore::FrameLoader::loadURL):
(WebCore::FrameLoader::load):
(WebCore::FrameLoader::loadWithNavigationAction):
(WebCore::FrameLoader::reloadWithOverrideEncoding):
(WebCore::FrameLoader::reload):
(WebCore::FrameLoader::loadPostRequest):
(WebCore::FrameLoader::continueLoadAfterNewWindowPolicy):
(WebCore::FrameLoader::loadDifferentDocumentItem):
(WebCore::createWindow):
(WebCore::FrameLoader::applyShouldOpenExternalURLsPolicyToNewDocumentLoader): Deleted.
* loader/FrameLoader.h:

* loader/FrameLoaderTypes.h:

* loader/NavigationAction.h:
(WebCore::NavigationAction::navigationInitiatedByMainFrame):
* loader/NavigationScheduler.cpp:
(WebCore::ScheduledNavigation::ScheduledNavigation): Grab the "initiating frame" at the time the
  ScheduledNavigation is created, as it dictates the policy we decide later.
(WebCore::ScheduledNavigation::navigationInitiatedByMainFrame):
(WebCore::NavigationScheduler::scheduleLocationChange):

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

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

Source/WebKit/ios:

Adopt to the new constructor for FrameLoadRequest.

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

Source/WebKit/mac:

Adopt to the new constructor for FrameLoadRequest.

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

Source/WebKit/win:

Adopt to the new constructor for FrameLoadRequest.

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

Source/WebKit2:

Adopt to the new constructor for FrameLoadRequest.

* WebProcess/Plugins/PluginView.cpp:
(WebKit::PluginView::loadURL):
* WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
(WebKit::WebFrameLoaderClient::dispatchCreatePage):
* WebProcess/WebPage/WebInspector.cpp:
(WebKit::WebInspector::openInNewTab):

LayoutTests:

Added a new explicit test and updated expectations for an old one.

* loader/navigation-policy/should-open-external-urls/resources/main-frame-with-subframe-main-programatically-navigates-subframe.html: Added.
* loader/navigation-policy/should-open-external-urls/subframe-click-target-self-expected.txt:
* loader/navigation-policy/should-open-external-urls/subframe-navigated-programatically-by-main-frame-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/subframe-navigated-programatically-by-main-frame.html: Added.

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

29 files changed:
LayoutTests/ChangeLog
LayoutTests/loader/navigation-policy/should-open-external-urls/resources/main-frame-with-subframe-main-programatically-navigates-subframe.html [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/subframe-click-target-self-expected.txt
LayoutTests/loader/navigation-policy/should-open-external-urls/subframe-navigated-programatically-by-main-frame-expected.txt [new file with mode: 0644]
LayoutTests/loader/navigation-policy/should-open-external-urls/subframe-navigated-programatically-by-main-frame.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/CommonVM.cpp
Source/WebCore/bindings/js/CommonVM.h
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/FrameLoader.h
Source/WebCore/loader/FrameLoaderTypes.h
Source/WebCore/loader/NavigationAction.h
Source/WebCore/loader/NavigationScheduler.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/WebProcess/Plugins/PluginView.cpp
Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
Source/WebKit2/WebProcess/WebPage/WebInspector.cpp

index b9280ad..627f3fe 100644 (file)
@@ -1,3 +1,17 @@
+2017-07-05  Brady Eidson  <beidson@apple.com>
+
+        Allow navigations in subframes to get a ShouldOpenExternalURLsPolicy of "ShouldAllow".
+        <rdar://problem/22485589> and https://bugs.webkit.org/show_bug.cgi?id=174178
+
+        Reviewed by Alex Christensen.
+
+        Added a new explicit test and updated expectations for an old one.
+        
+        * loader/navigation-policy/should-open-external-urls/resources/main-frame-with-subframe-main-programatically-navigates-subframe.html: Added.
+        * loader/navigation-policy/should-open-external-urls/subframe-click-target-self-expected.txt:
+        * loader/navigation-policy/should-open-external-urls/subframe-navigated-programatically-by-main-frame-expected.txt: Added.
+        * loader/navigation-policy/should-open-external-urls/subframe-navigated-programatically-by-main-frame.html: Added.
+
 2017-07-05  Matt Lewis  <jlewis3@apple.com>
 
         Marked animations/needs-layout.html as flaky.
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/main-frame-with-subframe-main-programatically-navigates-subframe.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/resources/main-frame-with-subframe-main-programatically-navigates-subframe.html
new file mode 100644 (file)
index 0000000..63de0cc
--- /dev/null
@@ -0,0 +1,10 @@
+<script>
+if (window.testRunner)
+    testRunner.waitUntilDone();
+
+function iframeLoaded() {
+    window.frames[0].location = "notify-done.html";
+}
+</script>
+
+<iframe onload="iframeLoaded();" src="do-nothing.html"></iframe>
index 3055533..c30fe8b 100644 (file)
@@ -3,7 +3,7 @@
  - decidePolicyForNavigationAction 
 <NSURLRequest URL resources/iframe-click-notify-done-target-self.html, main document URL subframe-click-target-self.html, http method GET> is main frame - no should open URLs externally - no
  - decidePolicyForNavigationAction 
-<NSURLRequest URL resources/notify-done.html, main document URL subframe-click-target-self.html, http method GET> is main frame - no should open URLs externally - no
+<NSURLRequest URL resources/notify-done.html, main document URL subframe-click-target-self.html, http method GET> is main frame - no should open URLs externally - yes
 This page has a subframe with a link.
 Then a link is clicked in that subframe that navigates inside that subframe, and that navigation should have the "should open external urls" flag set to false even though it was from a user gesture.
 
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/subframe-navigated-programatically-by-main-frame-expected.txt b/LayoutTests/loader/navigation-policy/should-open-external-urls/subframe-navigated-programatically-by-main-frame-expected.txt
new file mode 100644 (file)
index 0000000..dda95c1
--- /dev/null
@@ -0,0 +1,7 @@
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL resources/main-frame-with-subframe-main-programatically-navigates-subframe.html, main document URL resources/main-frame-with-subframe-main-programatically-navigates-subframe.html, http method GET> is main frame - yes should open URLs externally - yes
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL do-nothing.html, main document URL main-frame-with-subframe-main-programatically-navigates-subframe.html, http method GET> is main frame - no should open URLs externally - no
+ - decidePolicyForNavigationAction 
+<NSURLRequest URL notify-done.html, main document URL main-frame-with-subframe-main-programatically-navigates-subframe.html, http method GET> is main frame - no should open URLs externally - yes
+
diff --git a/LayoutTests/loader/navigation-policy/should-open-external-urls/subframe-navigated-programatically-by-main-frame.html b/LayoutTests/loader/navigation-policy/should-open-external-urls/subframe-navigated-programatically-by-main-frame.html
new file mode 100644 (file)
index 0000000..d8cd829
--- /dev/null
@@ -0,0 +1,13 @@
+<script>
+
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpPolicyDelegateCallbacks();
+    testRunner.queueLoad("resources/main-frame-with-subframe-main-programatically-navigates-subframe.html", "", true);
+}
+
+</script>
+This page has does not have the "should open external URLs" flag set.<br>
+It navigates to a 2nd page that does have the flag set.<br>
+That 2nd page contains an iframe, and the main frame programatically navigates the iframe to a 3rd document.<br>
+The "should open external URLs" flag should be set because the programatic navigation initiated from the main frame and the flag should propagate.<br>
index 03055c4..dd15605 100644 (file)
@@ -1,3 +1,70 @@
+2017-07-05  Brady Eidson  <beidson@apple.com>
+
+        Allow navigations in subframes to get a ShouldOpenExternalURLsPolicy of "ShouldAllow".
+        <rdar://problem/22485589> and https://bugs.webkit.org/show_bug.cgi?id=174178
+
+        Reviewed by Alex Christensen.
+
+        Test: loader/navigation-policy/should-open-external-urls/subframe-navigated-programatically-by-main-frame.html
+
+        This patch introduces a new flag to FrameLoadRequest to track when it is known with certainty that a 
+        FrameLoadRequest originates from the main frame.
+        
+        Later, when calculating the final ShouldOpenExternalURLsPolicy, main frames navigating iframes get to propagate
+        their permissions to the iframe.
+        
+        * bindings/js/CommonVM.cpp:
+        (WebCore::lexicalFrameFromCommonVM): Helper to grab the current frame associated with the current JS callstack.
+        * bindings/js/CommonVM.h:
+
+        * inspector/InspectorFrontendClientLocal.cpp:
+        (WebCore::InspectorFrontendClientLocal::openInNewTab):
+
+        * inspector/InspectorPageAgent.cpp:
+        (WebCore::InspectorPageAgent::navigate):
+
+        Add the new flag to FrameLoadRequest (and force almost everybody to explicitly include the flag):
+        * loader/FrameLoadRequest.cpp:
+        (WebCore::FrameLoadRequest::FrameLoadRequest):
+        * loader/FrameLoadRequest.h:
+        (WebCore::FrameLoadRequest::FrameLoadRequest):
+        (WebCore::FrameLoadRequest::navigationInitiatedByMainFrame):
+
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::urlSelected):
+        (WebCore::FrameLoader::loadURLIntoChildFrame):
+        (WebCore::shouldOpenExternalURLsPolicyToApply): Helper that takes the new flag into account when deciding
+          what the final ShouldOpenExternalURLsPolicy will be.
+        (WebCore::applyShouldOpenExternalURLsPolicyToNewDocumentLoader):
+        (WebCore::FrameLoader::loadURL):
+        (WebCore::FrameLoader::load):
+        (WebCore::FrameLoader::loadWithNavigationAction):
+        (WebCore::FrameLoader::reloadWithOverrideEncoding):
+        (WebCore::FrameLoader::reload):
+        (WebCore::FrameLoader::loadPostRequest):
+        (WebCore::FrameLoader::continueLoadAfterNewWindowPolicy):
+        (WebCore::FrameLoader::loadDifferentDocumentItem):
+        (WebCore::createWindow):
+        (WebCore::FrameLoader::applyShouldOpenExternalURLsPolicyToNewDocumentLoader): Deleted.
+        * loader/FrameLoader.h:
+
+        * loader/FrameLoaderTypes.h:
+
+        * loader/NavigationAction.h:
+        (WebCore::NavigationAction::navigationInitiatedByMainFrame):
+        * loader/NavigationScheduler.cpp:
+        (WebCore::ScheduledNavigation::ScheduledNavigation): Grab the "initiating frame" at the time the 
+          ScheduledNavigation is created, as it dictates the policy we decide later.
+        (WebCore::ScheduledNavigation::navigationInitiatedByMainFrame):
+        (WebCore::NavigationScheduler::scheduleLocationChange):
+
+        * page/ContextMenuController.cpp:
+        (WebCore::openNewWindow):
+        (WebCore::ContextMenuController::contextMenuItemSelected):
+
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::createWindow):
+
 2017-07-05  Simon Fraser  <simon.fraser@apple.com>
 
         Another build fix, for Mac.
index aa79eee..76d0909 100644 (file)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "CommonVM.h"
 
+#include "Frame.h"
 #include "ScriptController.h"
 #include "Settings.h"
 #include "WebCoreJSClientData.h"
@@ -65,6 +66,20 @@ VM& commonVMSlow()
     return *g_commonVMOrNull;
 }
 
+Frame* lexicalFrameFromCommonVM()
+{
+    if (auto* topCallFrame = commonVM().topCallFrame) {
+        if (auto* globalObject = JSC::jsCast<JSDOMGlobalObject*>(topCallFrame->lexicalGlobalObject())) {
+            if (auto* window = jsDynamicDowncast<JSDOMWindow*>(commonVM(), globalObject)) {
+                if (auto* frame = window->wrapped().frame())
+                    return frame;
+            }
+        }
+    }
+
+    return nullptr;
+}
+
 void addImpureProperty(const AtomicString& propertyName)
 {
     commonVM().addImpureProperty(propertyName);
index 2c67f99..2821eb2 100644 (file)
@@ -33,6 +33,9 @@ class VM;
 
 namespace WebCore {
 
+class Frame;
+Frame* lexicalFrameFromCommonVM();
+
 WEBCORE_EXPORT extern JSC::VM* g_commonVMOrNull;
 
 WEBCORE_EXPORT JSC::VM& commonVMSlow();
index 0499f9c..c877706 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(), mainFrame.document()->securityOrigin(), { }, 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, NavigationInitiatedByMainFrame::Unknown };
 
     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(), 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, NavigationInitiatedByMainFrame::Unknown };
     frame->loader().changeLocation(WTFMove(frameLoadRequest2));
 }
 
index f9b25ed..cf251f5 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(), 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, NavigationInitiatedByMainFrame::Unknown };
     frame.loader().changeLocation(WTFMove(frameLoadRequest));
 }
 
index 52e30c2..a553f5b 100644 (file)
@@ -37,7 +37,7 @@
 
 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)
+FrameLoadRequest::FrameLoadRequest(Document& requester, SecurityOrigin& requesterSecurityOrigin, const ResourceRequest& resourceRequest, const String& frameName, LockHistory lockHistory, LockBackForwardList lockBackForwardList, ShouldSendReferrer shouldSendReferrer, AllowNavigationToInvalidURL allowNavigationToInvalidURL, NewFrameOpenerPolicy newFrameOpenerPolicy, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, NavigationInitiatedByMainFrame navigationInitiatedByMainFrame, ShouldReplaceDocumentIfJavaScriptURL shouldReplaceDocumentIfJavaScriptURL, const AtomicString& downloadAttribute)
     : m_requester { makeRef(requester) }
     , m_requesterSecurityOrigin { makeRef(requesterSecurityOrigin) }
     , m_resourceRequest { resourceRequest }
@@ -50,6 +50,7 @@ FrameLoadRequest::FrameLoadRequest(Document& requester, SecurityOrigin& requeste
     , m_shouldReplaceDocumentIfJavaScriptURL { shouldReplaceDocumentIfJavaScriptURL }
     , m_shouldOpenExternalURLsPolicy { shouldOpenExternalURLsPolicy }
     , m_downloadAttribute { downloadAttribute }
+    , m_navigationInitiatedByMainFrame { navigationInitiatedByMainFrame }
 {
 }
 
index 482a629..9a05303 100644 (file)
@@ -38,7 +38,7 @@ class SecurityOrigin;
 
 class FrameLoadRequest {
 public:
-    WEBCORE_EXPORT FrameLoadRequest(Document&, SecurityOrigin&, const ResourceRequest&, const String& frameName, LockHistory, LockBackForwardList, ShouldSendReferrer, AllowNavigationToInvalidURL, NewFrameOpenerPolicy, ShouldOpenExternalURLsPolicy, ShouldReplaceDocumentIfJavaScriptURL = ReplaceDocumentIfJavaScriptURL, const AtomicString& downloadAttribute = { });
+    WEBCORE_EXPORT FrameLoadRequest(Document&, SecurityOrigin&, const ResourceRequest&, const String& frameName, LockHistory, LockBackForwardList, ShouldSendReferrer, AllowNavigationToInvalidURL, NewFrameOpenerPolicy, ShouldOpenExternalURLsPolicy, NavigationInitiatedByMainFrame, ShouldReplaceDocumentIfJavaScriptURL = ReplaceDocumentIfJavaScriptURL, const AtomicString& downloadAttribute = { });
     WEBCORE_EXPORT FrameLoadRequest(Frame&, const ResourceRequest&, ShouldOpenExternalURLsPolicy, const SubstituteData& = SubstituteData());
 
     WEBCORE_EXPORT ~FrameLoadRequest();
@@ -79,6 +79,8 @@ public:
 
     const AtomicString& downloadAttribute() const { return m_downloadAttribute; }
 
+    NavigationInitiatedByMainFrame navigationInitiatedByMainFrame() const { return m_navigationInitiatedByMainFrame; }
+
 private:
     Ref<Document> m_requester;
     Ref<SecurityOrigin> m_requesterSecurityOrigin;
@@ -95,6 +97,7 @@ private:
     ShouldReplaceDocumentIfJavaScriptURL m_shouldReplaceDocumentIfJavaScriptURL;
     ShouldOpenExternalURLsPolicy m_shouldOpenExternalURLsPolicy { ShouldOpenExternalURLsPolicy::ShouldNotAllow };
     AtomicString m_downloadAttribute;
+    NavigationInitiatedByMainFrame m_navigationInitiatedByMainFrame { NavigationInitiatedByMainFrame::Unknown };
 };
 
 } // namespace WebCore
index 3d4f303..48d7da8 100644 (file)
@@ -43,6 +43,7 @@
 #include "CachedResourceLoader.h"
 #include "Chrome.h"
 #include "ChromeClient.h"
+#include "CommonVM.h"
 #include "ContentFilter.h"
 #include "ContentSecurityPolicy.h"
 #include "DOMWindow.h"
@@ -363,8 +364,11 @@ 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)
 {
+    auto* frame = lexicalFrameFromCommonVM();
+    auto navigationInitiatedByMainFrame = frame && frame->isMainFrame() ? NavigationInitiatedByMainFrame::Yes : NavigationInitiatedByMainFrame::Unknown;
+
     NewFrameOpenerPolicy newFrameOpenerPolicy = openerPolicy.value_or(shouldSendReferrer == NeverSendReferrer ? NewFrameOpenerPolicy::Suppress : NewFrameOpenerPolicy::Allow);
-    urlSelected(FrameLoadRequest(*m_frame.document(), m_frame.document()->securityOrigin(), { 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, navigationInitiatedByMainFrame, DoNotReplaceDocumentIfJavaScriptURL, downloadAttribute), triggeringEvent);
 }
 
 void FrameLoader::urlSelected(FrameLoadRequest&& frameRequest, Event* triggeringEvent)
@@ -924,7 +928,10 @@ void FrameLoader::loadURLIntoChildFrame(const URL& url, const String& referer, F
         }
     }
 
-    FrameLoadRequest frameLoadRequest { *m_frame.document(), m_frame.document()->securityOrigin(), { url }, ASCIILiteral("_self"), LockHistory::No, LockBackForwardList::Yes, ShouldSendReferrer::MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
+    auto* lexicalFrame = lexicalFrameFromCommonVM();
+    auto navigationInitiatedByMainFrame = lexicalFrame && lexicalFrame->isMainFrame() ? NavigationInitiatedByMainFrame::Yes : NavigationInitiatedByMainFrame::Unknown;
+
+    FrameLoadRequest frameLoadRequest { *m_frame.document(), m_frame.document()->securityOrigin(), { url }, ASCIILiteral("_self"), LockHistory::No, LockBackForwardList::Yes, ShouldSendReferrer::MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress, ShouldOpenExternalURLsPolicy::ShouldNotAllow, navigationInitiatedByMainFrame };
     childFrame->loader().loadURL(WTFMove(frameLoadRequest), referer, FrameLoadType::RedirectWithLockedBackForwardList, nullptr, nullptr);
 }
 
@@ -1208,15 +1215,35 @@ void FrameLoader::loadFrameRequest(FrameLoadRequest&& request, Event* event, For
     }
 }
 
-static ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicyToApply(Frame& sourceFrame, ShouldOpenExternalURLsPolicy propagatedPolicy)
+static ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicyToApply(Frame& currentFrame, NavigationInitiatedByMainFrame navigationInitiatedByMainFrame, ShouldOpenExternalURLsPolicy propagatedPolicy)
 {
-    if (!sourceFrame.isMainFrame())
-        return ShouldOpenExternalURLsPolicy::ShouldNotAllow;
     if (ScriptController::processingUserGesture())
         return ShouldOpenExternalURLsPolicy::ShouldAllow;
+
+    if (navigationInitiatedByMainFrame == NavigationInitiatedByMainFrame::Yes)
+        return propagatedPolicy;
+
+    if (!currentFrame.isMainFrame())
+        return ShouldOpenExternalURLsPolicy::ShouldNotAllow;
+
     return propagatedPolicy;
 }
 
+static ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicyToApply(Frame& currentFrame, const FrameLoadRequest& frameLoadRequest)
+{
+    return shouldOpenExternalURLsPolicyToApply(currentFrame, frameLoadRequest.navigationInitiatedByMainFrame(), frameLoadRequest.shouldOpenExternalURLsPolicy());
+}
+
+static void applyShouldOpenExternalURLsPolicyToNewDocumentLoader(Frame& frame, DocumentLoader& documentLoader, NavigationInitiatedByMainFrame navigationInitiatedByMainFrame, ShouldOpenExternalURLsPolicy propagatedPolicy)
+{
+    documentLoader.setShouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicyToApply(frame, navigationInitiatedByMainFrame, propagatedPolicy));
+}
+
+static void applyShouldOpenExternalURLsPolicyToNewDocumentLoader(Frame& frame, DocumentLoader& documentLoader, const FrameLoadRequest& frameLoadRequest)
+{
+    documentLoader.setShouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicyToApply(frame, frameLoadRequest));
+}
+
 bool FrameLoader::isNavigationAllowed() const
 {
     return m_pageDismissalEventBeingDispatched == PageDismissalType::None && NavigationDisabler::isNavigationAllowed(m_frame);
@@ -1265,7 +1292,7 @@ void FrameLoader::loadURL(FrameLoadRequest&& frameLoadRequest, const String& ref
     NavigationAction action { frameLoadRequest.requester(), request, newLoadType, isFormSubmission, event, frameLoadRequest.shouldOpenExternalURLsPolicy(), frameLoadRequest.downloadAttribute() };
 
     if (!targetFrame && !frameName.isEmpty()) {
-        action = action.copyWithShouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicyToApply(m_frame, frameLoadRequest.shouldOpenExternalURLsPolicy()));
+        action = action.copyWithShouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicyToApply(m_frame, frameLoadRequest));
         policyChecker().checkNewWindowPolicy(action, request, formState, frameName, [this, allowNavigationToInvalidURL, openerPolicy] (const ResourceRequest& request, FormState* formState, const String& frameName, const NavigationAction& action, bool shouldContinue) {
             continueLoadAfterNewWindowPolicy(request, formState, frameName, action, shouldContinue, allowNavigationToInvalidURL, openerPolicy);
         });
@@ -1293,7 +1320,7 @@ void FrameLoader::loadURL(FrameLoadRequest&& frameLoadRequest, const String& ref
 
     // must grab this now, since this load may stop the previous load and clear this flag
     bool isRedirect = m_quickRedirectComing;
-    loadWithNavigationAction(request, action, lockHistory, newLoadType, formState, allowNavigationToInvalidURL);
+    loadWithNavigationAction(request, action, lockHistory, newLoadType, formState, allowNavigationToInvalidURL, frameLoadRequest.navigationInitiatedByMainFrame());
     if (isRedirect) {
         m_quickRedirectComing = false;
         if (m_provisionalDocumentLoader)
@@ -1347,15 +1374,15 @@ void FrameLoader::load(FrameLoadRequest&& request)
         request.setSubstituteData(defaultSubstituteDataForURL(request.resourceRequest().url()));
 
     Ref<DocumentLoader> loader = m_client.createDocumentLoader(request.resourceRequest(), request.substituteData());
-    applyShouldOpenExternalURLsPolicyToNewDocumentLoader(loader, request.shouldOpenExternalURLsPolicy());
+    applyShouldOpenExternalURLsPolicyToNewDocumentLoader(m_frame, loader, request);
 
     load(loader.ptr());
 }
 
-void FrameLoader::loadWithNavigationAction(const ResourceRequest& request, const NavigationAction& action, LockHistory lockHistory, FrameLoadType type, FormState* formState, AllowNavigationToInvalidURL allowNavigationToInvalidURL)
+void FrameLoader::loadWithNavigationAction(const ResourceRequest& request, const NavigationAction& action, LockHistory lockHistory, FrameLoadType type, FormState* formState, AllowNavigationToInvalidURL allowNavigationToInvalidURL, NavigationInitiatedByMainFrame navigationInitiatedByMainFrame)
 {
     Ref<DocumentLoader> loader = m_client.createDocumentLoader(request, defaultSubstituteDataForURL(request.url()));
-    applyShouldOpenExternalURLsPolicyToNewDocumentLoader(loader, action.shouldOpenExternalURLsPolicy());
+    applyShouldOpenExternalURLsPolicyToNewDocumentLoader(m_frame, loader, navigationInitiatedByMainFrame, action.shouldOpenExternalURLsPolicy());
 
     if (lockHistory == LockHistory::Yes && m_documentLoader)
         loader->setClientRedirectSourceForHistory(m_documentLoader->didCreateGlobalHistoryEntry() ? m_documentLoader->urlForHistory().string() : m_documentLoader->clientRedirectSourceForHistory());
@@ -1557,7 +1584,7 @@ void FrameLoader::reloadWithOverrideEncoding(const String& encoding)
     request.setCachePolicy(ReturnCacheDataElseLoad);
 
     Ref<DocumentLoader> loader = m_client.createDocumentLoader(request, defaultSubstituteDataForURL(request.url()));
-    applyShouldOpenExternalURLsPolicyToNewDocumentLoader(loader, m_documentLoader->shouldOpenExternalURLsPolicyToPropagate());
+    applyShouldOpenExternalURLsPolicyToNewDocumentLoader(m_frame, loader, NavigationInitiatedByMainFrame::Unknown, m_documentLoader->shouldOpenExternalURLsPolicyToPropagate());
 
     setPolicyDocumentLoader(loader.ptr());
 
@@ -1585,7 +1612,7 @@ void FrameLoader::reload(OptionSet<ReloadOption> options)
     // Create a new document loader for the reload, this will become m_documentLoader eventually,
     // but first it has to be the "policy" document loader, and then the "provisional" document loader.
     Ref<DocumentLoader> loader = m_client.createDocumentLoader(initialRequest, defaultSubstituteDataForURL(initialRequest.url()));
-    applyShouldOpenExternalURLsPolicyToNewDocumentLoader(loader, m_documentLoader->shouldOpenExternalURLsPolicyToPropagate());
+    applyShouldOpenExternalURLsPolicyToNewDocumentLoader(m_frame, loader, NavigationInitiatedByMainFrame::Unknown, m_documentLoader->shouldOpenExternalURLsPolicyToPropagate());
 
     loader->setUserContentExtensionsEnabled(!options.contains(ReloadOption::DisableContentBlockers));
     
@@ -2725,7 +2752,7 @@ void FrameLoader::loadPostRequest(FrameLoadRequest&& request, const String& refe
     if (!frameName.isEmpty()) {
         // The search for a target frame is done earlier in the case of form submission.
         if (Frame* targetFrame = formState ? 0 : findFrameForNavigation(frameName)) {
-            targetFrame->loader().loadWithNavigationAction(workingResourceRequest, action, lockHistory, loadType, WTFMove(formState), allowNavigationToInvalidURL);
+            targetFrame->loader().loadWithNavigationAction(workingResourceRequest, action, lockHistory, loadType, WTFMove(formState), allowNavigationToInvalidURL, request.navigationInitiatedByMainFrame());
             return;
         }
 
@@ -2737,7 +2764,7 @@ void FrameLoader::loadPostRequest(FrameLoadRequest&& request, const String& refe
 
     // must grab this now, since this load may stop the previous load and clear this flag
     bool isRedirect = m_quickRedirectComing;
-    loadWithNavigationAction(workingResourceRequest, action, lockHistory, loadType, WTFMove(formState), allowNavigationToInvalidURL);
+    loadWithNavigationAction(workingResourceRequest, action, lockHistory, loadType, WTFMove(formState), allowNavigationToInvalidURL, request.navigationInitiatedByMainFrame());
     if (isRedirect) {
         m_quickRedirectComing = false;
         if (m_provisionalDocumentLoader)
@@ -3177,7 +3204,7 @@ void FrameLoader::continueLoadAfterNewWindowPolicy(const ResourceRequest& reques
     }
 
     NavigationAction newAction { *frame->document(), request, NavigationType::Other, action.shouldOpenExternalURLsPolicy() };
-    mainFrame->loader().loadWithNavigationAction(request, newAction, LockHistory::No, FrameLoadType::Standard, formState, allowNavigationToInvalidURL);
+    mainFrame->loader().loadWithNavigationAction(request, newAction, LockHistory::No, FrameLoadType::Standard, formState, allowNavigationToInvalidURL, NavigationInitiatedByMainFrame::Unknown);
 }
 
 void FrameLoader::requestFromDelegate(ResourceRequest& request, unsigned long& identifier, ResourceError& error)
@@ -3380,7 +3407,7 @@ void FrameLoader::loadDifferentDocumentItem(HistoryItem& item, FrameLoadType loa
     if (!item.referrer().isNull())
         request.setHTTPReferrer(item.referrer());
 
-    ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy = shouldOpenExternalURLsPolicyToApply(m_frame, item.shouldOpenExternalURLsPolicy());
+    ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy = shouldOpenExternalURLsPolicyToApply(m_frame, NavigationInitiatedByMainFrame::Unknown, item.shouldOpenExternalURLsPolicy());
     bool isFormSubmission = false;
     Event* event = nullptr;
 
@@ -3450,7 +3477,7 @@ void FrameLoader::loadDifferentDocumentItem(HistoryItem& item, FrameLoadType loa
         action = { *m_frame.document(), requestForOriginalURL, loadType, isFormSubmission, event, shouldOpenExternalURLsPolicy };
     }
 
-    loadWithNavigationAction(request, action, LockHistory::No, loadType, 0, AllowNavigationToInvalidURL::Yes);
+    loadWithNavigationAction(request, action, LockHistory::No, loadType, 0, AllowNavigationToInvalidURL::Yes, NavigationInitiatedByMainFrame::Unknown);
 }
 
 // Loads content into this frame, as specified by history item
@@ -3651,11 +3678,6 @@ void FrameLoader::clearTestingOverrides()
     m_isStrictRawResourceValidationPolicyDisabledForTesting = false;
 }
 
-void FrameLoader::applyShouldOpenExternalURLsPolicyToNewDocumentLoader(DocumentLoader& documentLoader, ShouldOpenExternalURLsPolicy propagatedPolicy)
-{
-    documentLoader.setShouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicyToApply(m_frame, propagatedPolicy));
-}
-
 bool FrameLoader::isAlwaysOnLoggingAllowed() const
 {
     return frame().isAlwaysOnLoggingAllowed();
@@ -3700,7 +3722,7 @@ RefPtr<Frame> createWindow(Frame& openerFrame, Frame& lookupFrame, FrameLoadRequ
     if (!oldPage)
         return nullptr;
 
-    ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy = shouldOpenExternalURLsPolicyToApply(openerFrame, request.shouldOpenExternalURLsPolicy());
+    ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy = shouldOpenExternalURLsPolicyToApply(openerFrame, request);
     NavigationAction action { request.requester(), request.resourceRequest(), NavigationType::Other, shouldOpenExternalURLsPolicy };
     Page* page = oldPage->chrome().createWindow(openerFrame, request, features, action);
     if (!page)
index 6cacdda..349652b 100644 (file)
@@ -358,7 +358,7 @@ private:
     void loadWithDocumentLoader(DocumentLoader*, FrameLoadType, FormState*, AllowNavigationToInvalidURL); // Calls continueLoadAfterNavigationPolicy
     void load(DocumentLoader*); // Calls loadWithDocumentLoader
 
-    void loadWithNavigationAction(const ResourceRequest&, const NavigationAction&, LockHistory, FrameLoadType, FormState*, AllowNavigationToInvalidURL); // Calls loadWithDocumentLoader
+    void loadWithNavigationAction(const ResourceRequest&, const NavigationAction&, LockHistory, FrameLoadType, FormState*, AllowNavigationToInvalidURL, NavigationInitiatedByMainFrame); // Calls loadWithDocumentLoader
 
     void loadPostRequest(FrameLoadRequest&&, const String& referrer, FrameLoadType, Event*, FormState*);
     void loadURL(FrameLoadRequest&&, const String& referrer, FrameLoadType, Event*, FormState*);
@@ -386,8 +386,6 @@ private:
 
     void dispatchGlobalObjectAvailableInAllWorlds();
 
-    void applyShouldOpenExternalURLsPolicyToNewDocumentLoader(DocumentLoader&, ShouldOpenExternalURLsPolicy propagatedPolicy);
-
     bool isNavigationAllowed() const;
 
     Frame& m_frame;
index 84ea25b..79d46d5 100644 (file)
@@ -83,6 +83,11 @@ enum class ShouldOpenExternalURLsPolicy {
     ShouldAllow,
 };
 
+enum class NavigationInitiatedByMainFrame {
+    Yes,
+    Unknown,
+};
+
 enum ClearProvisionalItemPolicy {
     ShouldClearProvisionalItem,
     ShouldNotClearProvisionalItem
index 99db44b..b457d19 100644 (file)
@@ -68,6 +68,7 @@ public:
     RefPtr<UserGestureToken> userGestureToken() const { return m_userGestureToken; }
 
     ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy() const { return m_shouldOpenExternalURLsPolicy; }
+    NavigationInitiatedByMainFrame navigationInitiatedByMainFrame() const { return m_navigationInitiatedByMainFrame; }
 
     const AtomicString& downloadAttribute() const { return m_downloadAttribute; }
 
@@ -76,6 +77,7 @@ private:
     ResourceRequest m_resourceRequest;
     NavigationType m_type;
     ShouldOpenExternalURLsPolicy m_shouldOpenExternalURLsPolicy;
+    NavigationInitiatedByMainFrame m_navigationInitiatedByMainFrame;
     RefPtr<Event> m_event;
     RefPtr<UserGestureToken> m_userGestureToken { UserGestureIndicator::currentUserGesture() };
     AtomicString m_downloadAttribute;
index b41a54f..3bcb1a5 100644 (file)
@@ -33,6 +33,7 @@
 #include "NavigationScheduler.h"
 
 #include "BackForwardController.h"
+#include "CommonVM.h"
 #include "DOMWindow.h"
 #include "DocumentLoader.h"
 #include "Event.h"
@@ -79,6 +80,10 @@ public:
         , m_userGestureToForward(UserGestureIndicator::currentUserGesture())
         , m_shouldOpenExternalURLsPolicy(externalURLPolicy)
     {
+        if (auto* frame = lexicalFrameFromCommonVM()) {
+            if (frame->isMainFrame())
+                m_navigationInitiatedByMainFrame = NavigationInitiatedByMainFrame::Yes;
+        }
     }
     virtual ~ScheduledNavigation() { }
 
@@ -98,6 +103,7 @@ public:
 protected:
     void clearUserGesture() { m_userGestureToForward = nullptr; }
     ShouldOpenExternalURLsPolicy shouldOpenExternalURLs() const { return m_shouldOpenExternalURLsPolicy; }
+    NavigationInitiatedByMainFrame navigationInitiatedByMainFrame() const { return m_navigationInitiatedByMainFrame; };
 
 private:
     double m_delay;
@@ -107,6 +113,7 @@ private:
     bool m_isLocationChange;
     RefPtr<UserGestureToken> m_userGestureToForward;
     ShouldOpenExternalURLsPolicy m_shouldOpenExternalURLsPolicy { ShouldOpenExternalURLsPolicy::ShouldNotAllow };
+    NavigationInitiatedByMainFrame m_navigationInitiatedByMainFrame { NavigationInitiatedByMainFrame::Unknown };
 };
 
 class ScheduledURLNavigation : public ScheduledNavigation {
@@ -125,7 +132,7 @@ protected:
         UserGestureIndicator gestureIndicator { userGestureToForward() };
 
         ResourceRequest resourceRequest { m_url, m_referrer, UseProtocolCachePolicy };
-        FrameLoadRequest frameLoadRequest { m_initiatingDocument.get(), *m_securityOrigin, resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs() };
+        FrameLoadRequest frameLoadRequest { m_initiatingDocument.get(), *m_securityOrigin, resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs(), navigationInitiatedByMainFrame() };
 
         frame.loader().changeLocation(WTFMove(frameLoadRequest));
     }
@@ -186,7 +193,7 @@ public:
 
         bool refresh = equalIgnoringFragmentIdentifier(frame.document()->url(), url());
         ResourceRequest resourceRequest { url(), referrer(), refresh ? ReloadIgnoringCacheData : UseProtocolCachePolicy };
-        FrameLoadRequest frameLoadRequest { initiatingDocument(), *securityOrigin(), resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs() };
+        FrameLoadRequest frameLoadRequest { initiatingDocument(), *securityOrigin(), resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs(), navigationInitiatedByMainFrame() };
 
         frame.loader().changeLocation(WTFMove(frameLoadRequest));
     }
@@ -202,7 +209,8 @@ public:
         UserGestureIndicator gestureIndicator { userGestureToForward() };
 
         ResourceRequest resourceRequest { url(), referrer(), UseProtocolCachePolicy };
-        FrameLoadRequest frameLoadRequest { initiatingDocument(), *securityOrigin(), resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs() };
+        FrameLoadRequest frameLoadRequest { initiatingDocument(), *securityOrigin(), resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs(), navigationInitiatedByMainFrame() };
+
         frame.loader().changeLocation(WTFMove(frameLoadRequest));
     }
 };
@@ -219,7 +227,8 @@ public:
         UserGestureIndicator gestureIndicator { userGestureToForward() };
 
         ResourceRequest resourceRequest { url(), referrer(), ReloadIgnoringCacheData };
-        FrameLoadRequest frameLoadRequest { initiatingDocument(), *securityOrigin(), resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs() };
+        FrameLoadRequest frameLoadRequest { initiatingDocument(), *securityOrigin(), resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs(), navigationInitiatedByMainFrame() };
+
         frame.loader().changeLocation(WTFMove(frameLoadRequest));
     }
 };
@@ -271,7 +280,7 @@ public:
         auto& requestingDocument = m_submission->state().sourceDocument();
         if (!requestingDocument.canNavigate(&frame))
             return;
-        FrameLoadRequest frameLoadRequest { requestingDocument, requestingDocument.securityOrigin(), { }, { }, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs() };
+        FrameLoadRequest frameLoadRequest { requestingDocument, requestingDocument.securityOrigin(), { }, { }, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs(), navigationInitiatedByMainFrame() };
         m_submission->populateFrameLoadRequest(frameLoadRequest);
         frame.loader().loadFrameRequest(WTFMove(frameLoadRequest), m_submission->event(), &m_submission->state());
     }
@@ -321,7 +330,7 @@ public:
         SubstituteData replacementData { SharedBuffer::create(), m_originDocument.url(), replacementResponse, SubstituteData::SessionHistoryVisibility::Hidden };
 
         ResourceRequest resourceRequest { m_originDocument.url(), emptyString(), ReloadIgnoringCacheData };
-        FrameLoadRequest frameLoadRequest { m_originDocument, m_originDocument.securityOrigin(), resourceRequest, { }, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs() };
+        FrameLoadRequest frameLoadRequest { m_originDocument, m_originDocument.securityOrigin(), resourceRequest, { }, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs(), navigationInitiatedByMainFrame() };
         frameLoadRequest.setSubstituteData(replacementData);
         frame.loader().load(WTFMove(frameLoadRequest));
     }
@@ -420,7 +429,10 @@ 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 { initiatingDocument, securityOrigin, resourceRequest, ASCIILiteral("_self"), lockHistory, lockBackForwardList, MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, initiatingDocument.shouldOpenExternalURLsPolicyToPropagate() };
+        auto* frame = lexicalFrameFromCommonVM();
+        auto navigationInitiatedByMainFrame = frame && frame->isMainFrame() ? NavigationInitiatedByMainFrame::Yes : NavigationInitiatedByMainFrame::Unknown;
+        
+        FrameLoadRequest frameLoadRequest { initiatingDocument, securityOrigin, resourceRequest, ASCIILiteral("_self"), lockHistory, lockBackForwardList, MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, initiatingDocument.shouldOpenExternalURLsPolicyToPropagate(), navigationInitiatedByMainFrame };
         loader.changeLocation(WTFMove(frameLoadRequest));
         return;
     }
index 8141b51..ac88753 100644 (file)
@@ -189,7 +189,7 @@ static void openNewWindow(const URL& urlToLoad, Frame& frame, ShouldOpenExternal
     if (!oldPage)
         return;
 
-    FrameLoadRequest frameLoadRequest { *frame.document(), 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, NavigationInitiatedByMainFrame::Unknown };
 
     Page* newPage = oldPage->chrome().createWindow(frame, frameLoadRequest, { }, { *frame.document(), frameLoadRequest.resourceRequest() });
     if (!newPage)
@@ -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(), 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, NavigationInitiatedByMainFrame::Unknown };
             targetFrame->loader().loadFrameRequest(WTFMove(frameLoadRequest), nullptr, nullptr);
         } else
             openNewWindow(m_context.hitTestResult().absoluteLinkURL(), *frame, ShouldOpenExternalURLsPolicy::ShouldAllow);
index fc708f7..803af6f 100644 (file)
@@ -2197,10 +2197,11 @@ RefPtr<Frame> DOMWindow::createWindow(const String& urlString, const AtomicStrin
 
     // For whatever reason, Firefox uses the first frame to determine the outgoingReferrer. We replicate that behavior here.
     String referrer = SecurityPolicy::generateReferrerHeader(firstFrame.document()->referrerPolicy(), completedURL, firstFrame.loader().outgoingReferrer());
+    auto initiatedByMainFrame = activeFrame->isMainFrame() ? NavigationInitiatedByMainFrame::Yes : NavigationInitiatedByMainFrame::Unknown;
 
     ResourceRequest resourceRequest { completedURL, referrer };
     FrameLoader::addHTTPOriginIfNeeded(resourceRequest, firstFrame.loader().outgoingOrigin());
-    FrameLoadRequest frameLoadRequest { *activeDocument, 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(), initiatedByMainFrame };
 
     // 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.
@@ -2221,7 +2222,7 @@ RefPtr<Frame> DOMWindow::createWindow(const String& urlString, const AtomicStrin
 
     if (created) {
         ResourceRequest resourceRequest { completedURL, referrer, UseProtocolCachePolicy };
-        FrameLoadRequest frameLoadRequest { *activeWindow.document(), 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(), initiatedByMainFrame };
         newFrame->loader().changeLocation(WTFMove(frameLoadRequest));
     } else if (!urlString.isEmpty()) {
         LockHistory lockHistory = ScriptController::processingUserGesture() ? LockHistory::No : LockHistory::Yes;
index 05903d8..9fa5444 100644 (file)
@@ -1,3 +1,15 @@
+2017-07-05  Brady Eidson  <beidson@apple.com>
+
+        Allow navigations in subframes to get a ShouldOpenExternalURLsPolicy of "ShouldAllow".
+        <rdar://problem/22485589> and https://bugs.webkit.org/show_bug.cgi?id=174178
+
+        Reviewed by Alex Christensen.
+
+        Adopt to the new constructor for FrameLoadRequest.
+
+        * WebView/WebPDFViewPlaceholder.mm:
+        (-[WebPDFViewPlaceholder simulateClickOnLinkToURL:]):
+
 2017-07-01  Tim Horton  <timothy_horton@apple.com>
 
         Expose viewport-fit value to UIKit via viewport arguments dictionary
index da41884..0745ab7 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(), 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,  NavigationInitiatedByMainFrame::Unknown };
     frame->loader().loadFrameRequest(WTFMove(frameLoadRequest), event.get(), nullptr);
 }
 
index 0ce2d8f..d42420a 100644 (file)
@@ -1,3 +1,15 @@
+2017-07-05  Brady Eidson  <beidson@apple.com>
+
+        Allow navigations in subframes to get a ShouldOpenExternalURLsPolicy of "ShouldAllow".
+        <rdar://problem/22485589> and https://bugs.webkit.org/show_bug.cgi?id=174178
+
+        Reviewed by Alex Christensen.
+
+        Adopt to the new constructor for FrameLoadRequest.
+
+        * WebView/WebPDFView.mm:
+        (-[WebPDFView PDFViewWillClickOnLink:withURL:]):
+
 2017-07-05  Ryosuke Niwa  <rniwa@webkit.org>
 
         Make WebKit's public headers on Mac and iOS C++ module safe
index 47ce371..979c3b5 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(), 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, NavigationInitiatedByMainFrame::Unknown };
     frame->loader().loadFrameRequest(WTFMove(frameLoadRequest), event.get(), nullptr);
 }
 
index 777a2cd..3ce7646 100644 (file)
@@ -1,3 +1,18 @@
+2017-07-05  Brady Eidson  <beidson@apple.com>
+
+        Allow navigations in subframes to get a ShouldOpenExternalURLsPolicy of "ShouldAllow".
+        <rdar://problem/22485589> and https://bugs.webkit.org/show_bug.cgi?id=174178
+
+        Reviewed by Alex Christensen.
+
+        Adopt to the new constructor for FrameLoadRequest.
+
+        * Plugins/PluginView.cpp:
+        (WebCore::PluginView::start):
+        (WebCore::PluginView::getURLNotify):
+        (WebCore::PluginView::getURL):
+        (WebCore::PluginView::handlePost):
+
 2017-07-03  Brady Eidson  <beidson@apple.com>
 
         Switch all WebKit API related to favicons from WebIconDatabase over to new WebCore::IconLoader mechanism.
index 522a4ba..77cfcfd 100644 (file)
@@ -255,7 +255,7 @@ bool PluginView::start()
     m_isStarted = true;
 
     if (!m_url.isEmpty() && !m_loadManually) {
-        FrameLoadRequest frameLoadRequest { *m_parentFrame->document(), 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, NavigationInitiatedByMainFrame::Unknown };
         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(), 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, NavigationInitiatedByMainFrame::Unknown };
 
     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(), 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, NavigationInitiatedByMainFrame::Unknown };
 
     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(), 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, NavigationInitiatedByMainFrame::Unknown };
     frameLoadRequest.resourceRequest().setHTTPMethod("POST");
     frameLoadRequest.resourceRequest().setURL(makeURL(m_parentFrame->document()->baseURL(), url));
     frameLoadRequest.resourceRequest().setHTTPHeaderFields(WTFMove(headerFields));
index f9d6edf..2dfc664 100644 (file)
@@ -1,3 +1,19 @@
+2017-07-05  Brady Eidson  <beidson@apple.com>
+
+        Allow navigations in subframes to get a ShouldOpenExternalURLsPolicy of "ShouldAllow".
+        <rdar://problem/22485589> and https://bugs.webkit.org/show_bug.cgi?id=174178
+
+        Reviewed by Alex Christensen.
+
+        Adopt to the new constructor for FrameLoadRequest.
+
+        * WebProcess/Plugins/PluginView.cpp:
+        (WebKit::PluginView::loadURL):
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+        (WebKit::WebFrameLoaderClient::dispatchCreatePage):
+        * WebProcess/WebPage/WebInspector.cpp:
+        (WebKit::WebInspector::openInNewTab):
+
 2017-07-05  Ryosuke Niwa  <rniwa@webkit.org>
 
         Remove unnecessary forward declartions now that we include Foundation.h
index c58c5cb..f91efbc 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(), 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, NavigationInitiatedByMainFrame::Unknown };
     frameLoadRequest.resourceRequest().setHTTPMethod(method);
     frameLoadRequest.resourceRequest().setURL(m_pluginElement->document().completeURL(urlString));
     frameLoadRequest.resourceRequest().setHTTPHeaderFields(headerFields);
index b29169a..3993f88 100644 (file)
@@ -653,7 +653,7 @@ Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction& navigati
         return nullptr;
 
     // Just call through to the chrome client.
-    FrameLoadRequest frameLoadRequest { *m_frame->coreFrame()->document(), 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(), NavigationInitiatedByMainFrame::Unknown };
     Page* newPage = webPage->corePage()->chrome().createWindow(*m_frame->coreFrame(), frameLoadRequest, { }, navigationAction);
     if (!newPage)
         return nullptr;
index 1ae60af..3a60f6d 100644 (file)
@@ -147,7 +147,7 @@ void WebInspector::openInNewTab(const String& urlString)
         return;
 
     Frame& inspectedMainFrame = inspectedPage->mainFrame();
-    FrameLoadRequest frameLoadRequest { *inspectedMainFrame.document(), 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, NavigationInitiatedByMainFrame::Unknown };
 
     NavigationAction action { *inspectedMainFrame.document(), frameLoadRequest.resourceRequest(), NavigationType::LinkClicked };
     Page* newPage = inspectedPage->chrome().createWindow(inspectedMainFrame, frameLoadRequest, { }, action);