WebKit policy delegate should suggest if a navigation should be allowed to open URLs externally.
rdar://problem/21025301 and https://bugs.webkit.org/show_bug.cgi?id=145280
Source/WebCore:
Reviewed by Alex Christensen.
Tests: loader/navigation-policy/should-open-external-urls/main-frame-click.html
loader/navigation-policy/should-open-external-urls/main-frame-navigated-programatically-by-subframe.html
loader/navigation-policy/should-open-external-urls/main-frame-with-flag-progamatic.html
loader/navigation-policy/should-open-external-urls/main-frame-without-flag-programatic.html
loader/navigation-policy/should-open-external-urls/subframe-click-target-self.html
loader/navigation-policy/should-open-external-urls/subframe-click-target-top.html
loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag-from-subframe.html
loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag.html
loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag-from-subframe.html
loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag.html
loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag-from-subframe.html
loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag.html
loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag-from-subframe.html
loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag.html
loader/navigation-policy/should-open-external-urls/window-open-with-flag-from-subframe.html
loader/navigation-policy/should-open-external-urls/window-open-with-flag.html
loader/navigation-policy/should-open-external-urls/window-open-without-flag-from-subframe.html
loader/navigation-policy/should-open-external-urls/window-open-without-flag.html
The "should open external URLs" flag is only for main frames.
It doesn't enforce any sort of policy internal to WebKit, but rather is for notifications to the policy delegate.
It is set from one of two places:
1 - A main frame is navigated by any frame as the result of a user gesture.
2 - WebKit2 API explicitly states the flag is true.
The flag value propagates when:
1 - When a main frame document is navigated to a new main frame document.
2 - When a new window is opened from a page whose main frame had the flag set.
3 - When a new window is opened as the result of a user gesture.
The flag resets to false when:
1 - A subframe navigates a main frame without a user gesture.
This patch is large, but does little more than the following:
1 - Adds a ShouldOpenExternalURLs flag to both FrameLoadRequest and NavigationAction.
2 - Makes sure anybody who creates either of those objects sets a sensible for that flag.
3 - When FrameLoader creates a new DocumentLoader, it sets its flag based on whether or not the load is in a main frame,
whether or not the load is from a user gesture, and based on the initiator's value of the flag.
* dom/Document.cpp:
(WebCore::Document::processHttpEquiv):
(WebCore::Document::shouldOpenExternalURLsPolicyToPropagate):
* dom/Document.h:
* html/HTMLAnchorElement.cpp:
(WebCore::HTMLAnchorElement::handleClick):
* html/HTMLLinkElement.cpp:
(WebCore::HTMLLinkElement::handleClick):
* html/parser/XSSAuditorDelegate.cpp:
(WebCore::XSSAuditorDelegate::didBlockScript):
* inspector/InspectorFrontendClientLocal.cpp:
(WebCore::InspectorFrontendClientLocal::openInNewTab):
* inspector/InspectorPageAgent.cpp:
(WebCore::InspectorPageAgent::navigate):
* loader/DocumentLoader.cpp:
(WebCore::DocumentLoader::setTriggeringAction):
(WebCore::DocumentLoader::shouldOpenExternalURLsPolicyToPropagate):
* loader/DocumentLoader.h:
(WebCore::DocumentLoader::shouldOpenExternalURLsPolicy): Deleted.
* loader/FrameLoadRequest.cpp:
(WebCore::FrameLoadRequest::FrameLoadRequest):
* loader/FrameLoadRequest.h:
(WebCore::FrameLoadRequest::FrameLoadRequest):
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::urlSelected):
(WebCore::FrameLoader::receivedFirstData):
(WebCore::FrameLoader::loadURLIntoChildFrame):
(WebCore::FrameLoader::loadURL):
(WebCore::FrameLoader::load):
(WebCore::FrameLoader::loadWithNavigationAction):
(WebCore::FrameLoader::reloadWithOverrideEncoding):
(WebCore::FrameLoader::reload):
(WebCore::FrameLoader::loadPostRequest):
(WebCore::FrameLoader::continueLoadAfterNewWindowPolicy):
(WebCore::FrameLoader::applyShouldOpenExternalURLsPolicyToNewDocumentLoader):
* loader/FrameLoader.h:
* loader/NavigationAction.cpp:
(WebCore::NavigationAction::NavigationAction):
(WebCore::NavigationAction::copyWithShouldOpenExternalURLsPolicy):
* loader/NavigationAction.h:
(WebCore::NavigationAction::setShouldOpenExternalURLsPolicy): Deleted.
* loader/NavigationScheduler.cpp:
(WebCore::ScheduledURLNavigation::ScheduledURLNavigation):
(WebCore::ScheduledRedirect::ScheduledRedirect):
(WebCore::ScheduledLocationChange::ScheduledLocationChange):
(WebCore::ScheduledRefresh::ScheduledRefresh):
(WebCore::ScheduledFormSubmission::ScheduledFormSubmission):
(WebCore::NavigationScheduler::scheduleRedirect):
(WebCore::NavigationScheduler::scheduleLocationChange):
(WebCore::NavigationScheduler::scheduleRefresh):
* loader/NavigationScheduler.h:
* loader/PolicyChecker.cpp:
(WebCore::PolicyChecker::checkNavigationPolicy):
* loader/SubframeLoader.cpp:
(WebCore::SubframeLoader::loadOrRedirectSubframe):
* loader/appcache/ApplicationCacheGroup.cpp:
(WebCore::ApplicationCacheGroup::selectCache):
* page/ContextMenuController.cpp:
(WebCore::openNewWindow):
(WebCore::ContextMenuController::contextMenuItemSelected):
* page/DOMWindow.cpp:
(WebCore::DOMWindow::setLocation):
(WebCore::DOMWindow::createWindow):
(WebCore::DOMWindow::open):
* page/DragController.cpp:
(WebCore::DragController::performDragOperation):
* page/Location.cpp:
(WebCore::Location::reload):
* replay/ReplayInputDispatchMethods.cpp:
(WebCore::InitialNavigation::dispatch):
* svg/SVGAElement.cpp:
(WebCore::SVGAElement::defaultEventHandler):
Source/WebKit/ios:
Reviewed by Alex Christensen.
* WebView/WebPDFViewPlaceholder.mm:
(-[WebPDFViewPlaceholder simulateClickOnLinkToURL:]):
Source/WebKit/mac:
Reviewed by Alex Christensen.
* Plugins/WebPluginController.mm:
(-[WebPluginController webPlugInContainerLoadRequest:inFrame:]):
* WebView/WebFrame.mm:
(-[WebFrame loadRequest:]):
(-[WebFrame _loadData:MIMEType:textEncodingName:baseURL:unreachableURL:]):
* WebView/WebPDFView.mm:
(-[WebPDFView PDFViewWillClickOnLink:withURL:]):
Source/WebKit/win:
Reviewed by Alex Christensen.
* Plugins/PluginView.cpp:
(WebCore::PluginView::start):
(WebCore::PluginView::performRequest):
(WebCore::PluginView::getURLNotify):
(WebCore::PluginView::getURL):
(WebCore::PluginView::handlePost):
* WebCoreSupport/WebContextMenuClient.cpp:
(WebContextMenuClient::searchWithGoogle):
* WebFrame.cpp:
(WebFrame::loadRequest):
(WebFrame::loadData):
Source/WebKit2:
Reviewed by Alex Christensen.
* WebProcess/Plugins/PDF/PDFPlugin.mm:
(WebKit::PDFPlugin::clickedLink):
* WebProcess/Plugins/PluginView.cpp:
(WebKit::PluginView::performFrameLoadURLRequest):
(WebKit::PluginView::loadURL):
* WebProcess/WebCoreSupport/WebContextMenuClient.cpp:
(WebKit::WebContextMenuClient::searchWithGoogle):
* WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
(WebKit::WebFrameLoaderClient::dispatchCreatePage):
* WebProcess/WebPage/WebInspector.cpp:
(WebKit::WebInspector::openInNewTab):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::loadURLInFrame):
(WebKit::WebPage::loadRequest):
(WebKit::WebPage::loadDataImpl):
(WebKit::WebPage::navigateToPDFLinkWithSimulatedClick):
LayoutTests:
Reviewed by Alex Christensen.
* loader/navigation-policy/should-open-external-urls/main-frame-click-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/main-frame-click.html: Added.
* loader/navigation-policy/should-open-external-urls/main-frame-navigated-programatically-by-subframe-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/main-frame-navigated-programatically-by-subframe.html: Added.
* loader/navigation-policy/should-open-external-urls/main-frame-with-flag-progamatic-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/main-frame-with-flag-progamatic.html: Added.
* loader/navigation-policy/should-open-external-urls/main-frame-without-flag-programatic-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/main-frame-without-flag-programatic.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/click-notify-done-in-main.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/iframe-click-notify-done-target-self.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/iframe-click-notify-done-target-top.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/main-frame-with-subframe-click-targets-subframe.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/main-frame-with-subframe-programatically-navigates-main.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/programatically-navigate-to-notify-done-target-top.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/programatically-navigate-to-notify-done.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/user-gesture-target-blank-to-notify-done-from-subframe.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/user-gesture-target-blank-to-notify-done.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/user-gesture-window-open-to-notify-done-from-subframe.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/user-gesture-window-open-to-notify-done.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/window-open-to-notify-done-from-subframe.html: Added.
* loader/navigation-policy/should-open-external-urls/resources/window-open-to-notify-done.html: Added.
* loader/navigation-policy/should-open-external-urls/subframe-click-target-self-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/subframe-click-target-self.html: Added.
* loader/navigation-policy/should-open-external-urls/subframe-click-target-top-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/subframe-click-target-top.html: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag-from-subframe-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag-from-subframe.html: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-with-flag.html: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag-from-subframe-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag-from-subframe.html: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-target-blank-without-flag.html: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag-from-subframe-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag-from-subframe.html: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-window-open-with-flag.html: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag-from-subframe-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag-from-subframe.html: Added.
* loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag.html: Added.
* loader/navigation-policy/should-open-external-urls/window-open-with-flag-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/window-open-with-flag-from-subframe-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/window-open-with-flag-from-subframe.html: Added.
* loader/navigation-policy/should-open-external-urls/window-open-with-flag.html: Added.
* loader/navigation-policy/should-open-external-urls/window-open-without-flag-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/window-open-without-flag-from-subframe-expected.txt: Added.
* loader/navigation-policy/should-open-external-urls/window-open-without-flag-from-subframe.html: Added.
* loader/navigation-policy/should-open-external-urls/window-open-without-flag.html: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@185111 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/loader/NavigationScheduler.cpp b/Source/WebCore/loader/NavigationScheduler.cpp
index cf7bdab..d95cedb 100644
--- a/Source/WebCore/loader/NavigationScheduler.cpp
+++ b/Source/WebCore/loader/NavigationScheduler.cpp
@@ -87,6 +87,8 @@
protected:
void clearUserGesture() { m_wasUserGesture = false; }
+ ShouldOpenExternalURLsPolicy m_shouldOpenExternalURLsPolicy { ShouldOpenExternalURLsPolicy::ShouldNotAllow };
+
private:
double m_delay;
LockHistory m_lockHistory;
@@ -98,13 +100,15 @@
class ScheduledURLNavigation : public ScheduledNavigation {
protected:
- ScheduledURLNavigation(double delay, SecurityOrigin* securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList, bool duringLoad, bool isLocationChange)
+ ScheduledURLNavigation(Document* initiatingDocument, double delay, SecurityOrigin* securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList, bool duringLoad, bool isLocationChange)
: ScheduledNavigation(delay, lockHistory, lockBackForwardList, duringLoad, isLocationChange)
, m_securityOrigin(securityOrigin)
, m_url(url)
, m_referrer(referrer)
, m_haveToldClient(false)
{
+ if (initiatingDocument)
+ m_shouldOpenExternalURLsPolicy = initiatingDocument->shouldOpenExternalURLsPolicyToPropagate();
}
virtual void fire(Frame& frame) override
@@ -112,7 +116,7 @@
UserGestureIndicator gestureIndicator(wasUserGesture() ? DefinitelyProcessingUserGesture : DefinitelyNotProcessingUserGesture);
ResourceRequest resourceRequest(m_url, m_referrer, UseProtocolCachePolicy);
- FrameLoadRequest frameRequest(m_securityOrigin.get(), resourceRequest, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow);
+ FrameLoadRequest frameRequest(m_securityOrigin.get(), resourceRequest, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, m_shouldOpenExternalURLsPolicy);
frame.loader().changeLocation(frameRequest);
}
@@ -154,8 +158,8 @@
class ScheduledRedirect : public ScheduledURLNavigation {
public:
- ScheduledRedirect(double delay, SecurityOrigin* securityOrigin, const URL& url, LockHistory lockHistory, LockBackForwardList lockBackForwardList)
- : ScheduledURLNavigation(delay, securityOrigin, url, String(), lockHistory, lockBackForwardList, false, false)
+ ScheduledRedirect(Document* initiatingDocument, double delay, SecurityOrigin* securityOrigin, const URL& url, LockHistory lockHistory, LockBackForwardList lockBackForwardList)
+ : ScheduledURLNavigation(initiatingDocument, delay, securityOrigin, url, String(), lockHistory, lockBackForwardList, false, false)
{
clearUserGesture();
}
@@ -170,7 +174,7 @@
UserGestureIndicator gestureIndicator(wasUserGesture() ? DefinitelyProcessingUserGesture : DefinitelyNotProcessingUserGesture);
bool refresh = equalIgnoringFragmentIdentifier(frame.document()->url(), url());
ResourceRequest resourceRequest(url(), referrer(), refresh ? ReloadIgnoringCacheData : UseProtocolCachePolicy);
- FrameLoadRequest frameRequest(securityOrigin(), resourceRequest, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow);
+ FrameLoadRequest frameRequest(securityOrigin(), resourceRequest, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, m_shouldOpenExternalURLsPolicy);
frame.loader().changeLocation(frameRequest);
}
@@ -178,23 +182,23 @@
class ScheduledLocationChange : public ScheduledURLNavigation {
public:
- ScheduledLocationChange(SecurityOrigin* securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList, bool duringLoad)
- : ScheduledURLNavigation(0.0, securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad, true) { }
+ ScheduledLocationChange(Document* initiatingDocument, SecurityOrigin* securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList, bool duringLoad)
+ : ScheduledURLNavigation(initiatingDocument, 0.0, securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad, true) { }
virtual void fire(Frame& frame) override
{
UserGestureIndicator gestureIndicator(wasUserGesture() ? DefinitelyProcessingUserGesture : DefinitelyNotProcessingUserGesture);
ResourceRequest resourceRequest(url(), referrer(), UseProtocolCachePolicy);
- FrameLoadRequest frameRequest(securityOrigin(), resourceRequest, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow);
+ FrameLoadRequest frameRequest(securityOrigin(), resourceRequest, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, m_shouldOpenExternalURLsPolicy);
frame.loader().changeLocation(frameRequest);
}
};
class ScheduledRefresh : public ScheduledURLNavigation {
public:
- ScheduledRefresh(SecurityOrigin* securityOrigin, const URL& url, const String& referrer)
- : ScheduledURLNavigation(0.0, securityOrigin, url, referrer, LockHistory::Yes, LockBackForwardList::Yes, false, true)
+ ScheduledRefresh(Document* initiatingDocument, SecurityOrigin* securityOrigin, const URL& url, const String& referrer)
+ : ScheduledURLNavigation(initiatingDocument, 0.0, securityOrigin, url, referrer, LockHistory::Yes, LockBackForwardList::Yes, false, true)
{
}
@@ -203,7 +207,7 @@
UserGestureIndicator gestureIndicator(wasUserGesture() ? DefinitelyProcessingUserGesture : DefinitelyNotProcessingUserGesture);
ResourceRequest resourceRequest(url(), referrer(), ReloadIgnoringCacheData);
- FrameLoadRequest frameRequest(securityOrigin(), resourceRequest, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow);
+ FrameLoadRequest frameRequest(securityOrigin(), resourceRequest, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, m_shouldOpenExternalURLsPolicy);
frame.loader().changeLocation(frameRequest);
}
};
@@ -223,7 +227,7 @@
if (!m_historySteps) {
// Special case for go(0) from a frame -> reload only the frame
// To follow Firefox and IE's behavior, history reload can only navigate the self frame.
- frame.loader().urlSelected(frame.document()->url(), "_self", 0, lockHistory(), lockBackForwardList(), MaybeSendReferrer);
+ frame.loader().urlSelected(frame.document()->url(), "_self", 0, lockHistory(), lockBackForwardList(), MaybeSendReferrer, m_shouldOpenExternalURLsPolicy);
return;
}
@@ -244,6 +248,9 @@
, m_haveToldClient(false)
{
ASSERT(m_submission->state());
+
+ if (Document* document = m_submission->state()->sourceDocument())
+ m_shouldOpenExternalURLsPolicy = document->shouldOpenExternalURLsPolicyToPropagate();
}
virtual void fire(Frame& frame) override
@@ -257,7 +264,7 @@
Document* requestingDocument = m_submission->state()->sourceDocument();
if (!requestingDocument->canNavigate(&frame))
return;
- FrameLoadRequest frameRequest(requestingDocument->securityOrigin(), lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow);
+ FrameLoadRequest frameRequest(requestingDocument->securityOrigin(), lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, m_shouldOpenExternalURLsPolicy);
m_submission->populateFrameLoadRequest(frameRequest);
frame.loader().loadFrameRequest(frameRequest, m_submission->event(), m_submission->state());
}
@@ -303,7 +310,7 @@
void fire(Frame& frame) override
{
UserGestureIndicator gestureIndicator { wasUserGesture() ? DefinitelyProcessingUserGesture : DefinitelyNotProcessingUserGesture };
- frame.loader().load(FrameLoadRequest { &frame, m_baseURL, m_substituteData });
+ frame.loader().load(FrameLoadRequest { &frame, m_baseURL, m_shouldOpenExternalURLsPolicy, m_substituteData });
}
private:
@@ -353,7 +360,7 @@
return NavigationDisablerForBeforeUnload::isNavigationAllowed();
}
-void NavigationScheduler::scheduleRedirect(double delay, const URL& url)
+void NavigationScheduler::scheduleRedirect(Document* initiatingDocument, double delay, const URL& url)
{
if (!shouldScheduleNavigation(url))
return;
@@ -365,7 +372,7 @@
// We want a new back/forward list item if the refresh timeout is > 1 second.
if (!m_redirect || delay <= m_redirect->delay()) {
LockBackForwardList lockBackForwardList = delay <= 1 ? LockBackForwardList::Yes : LockBackForwardList::No;
- schedule(std::make_unique<ScheduledRedirect>(delay, m_frame.document()->securityOrigin(), url, LockHistory::Yes, lockBackForwardList));
+ schedule(std::make_unique<ScheduledRedirect>(initiatingDocument, delay, m_frame.document()->securityOrigin(), url, LockHistory::Yes, lockBackForwardList));
}
}
@@ -387,7 +394,7 @@
return LockBackForwardList::No;
}
-void NavigationScheduler::scheduleLocationChange(SecurityOrigin* securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList)
+void NavigationScheduler::scheduleLocationChange(Document* initiatingDocument, SecurityOrigin* securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList)
{
if (!shouldScheduleNavigation(url))
return;
@@ -401,7 +408,10 @@
// fragment part, we don't need to schedule the location change.
if (url.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(m_frame.document()->url(), url)) {
ResourceRequest resourceRequest(m_frame.document()->completeURL(url), referrer, UseProtocolCachePolicy);
- FrameLoadRequest frameRequest(securityOrigin, resourceRequest, emptyString(), lockHistory, lockBackForwardList, MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, ReplaceDocumentIfJavaScriptURL);
+ ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy = ShouldOpenExternalURLsPolicy::ShouldNotAllow;
+ if (initiatingDocument)
+ shouldOpenExternalURLsPolicy = initiatingDocument->shouldOpenExternalURLsPolicyToPropagate();
+ FrameLoadRequest frameRequest(securityOrigin, resourceRequest, emptyString(), lockHistory, lockBackForwardList, MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, ReplaceDocumentIfJavaScriptURL, shouldOpenExternalURLsPolicy);
loader.changeLocation(frameRequest);
return;
}
@@ -410,7 +420,7 @@
// This may happen when a frame changes the location of another frame.
bool duringLoad = !loader.stateMachine().committedFirstRealDocumentLoad();
- schedule(std::make_unique<ScheduledLocationChange>(securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad));
+ schedule(std::make_unique<ScheduledLocationChange>(initiatingDocument, securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad));
}
void NavigationScheduler::scheduleFormSubmission(PassRefPtr<FormSubmission> submission)
@@ -436,7 +446,7 @@
schedule(std::make_unique<ScheduledFormSubmission>(submission, lockBackForwardList, duringLoad));
}
-void NavigationScheduler::scheduleRefresh()
+void NavigationScheduler::scheduleRefresh(Document* initiatingDocument)
{
if (!shouldScheduleNavigation())
return;
@@ -444,7 +454,7 @@
if (url.isEmpty())
return;
- schedule(std::make_unique<ScheduledRefresh>(m_frame.document()->securityOrigin(), url, m_frame.loader().outgoingReferrer()));
+ schedule(std::make_unique<ScheduledRefresh>(initiatingDocument, m_frame.document()->securityOrigin(), url, m_frame.loader().outgoingReferrer()));
}
void NavigationScheduler::scheduleHistoryNavigation(int steps)