Index: Source/core/loader/FrameLoader.cpp |
diff --git a/Source/core/loader/FrameLoader.cpp b/Source/core/loader/FrameLoader.cpp |
index ffefbc45fbe89fa0b16e1b2ba3559ed6f2b6e2a5..44d909b7bdb6d3ea05e7bc5a6f4c50e42657cb2f 100644 |
--- a/Source/core/loader/FrameLoader.cpp |
+++ b/Source/core/loader/FrameLoader.cpp |
@@ -44,6 +44,7 @@ |
#include "core/dom/ViewportDescription.h" |
#include "core/editing/Editor.h" |
#include "core/editing/UndoStack.h" |
+#include "core/events/MouseEvent.h" |
#include "core/events/PageTransitionEvent.h" |
#include "core/fetch/FetchContext.h" |
#include "core/fetch/ResourceFetcher.h" |
@@ -683,8 +684,6 @@ FrameLoadType FrameLoader::determineFrameLoadType(const FrameLoadRequest& reques |
bool FrameLoader::prepareRequestForThisFrame(FrameLoadRequest& request) |
{ |
- request.resourceRequest().setFrameType(m_frame->isMainFrame() ? WebURLRequest::FrameTypeTopLevel : WebURLRequest::FrameTypeNested); |
- |
// If no origin Document* was specified, skip remaining security checks and assume the caller has fully initialized the FrameLoadRequest. |
if (!request.originDocument()) |
return true; |
@@ -703,13 +702,28 @@ bool FrameLoader::prepareRequestForThisFrame(FrameLoadRequest& request) |
return true; |
} |
-static bool shouldOpenInNewWindow(LocalFrame* targetFrame, const FrameLoadRequest& request, const NavigationAction& action) |
+static bool shouldOpenInNewWindow(LocalFrame* targetFrame, const FrameLoadRequest& request, NavigationPolicy policy) |
{ |
if (!targetFrame && !request.frameName().isEmpty()) |
return true; |
// FIXME: This case is a workaround for the fact that ctrl+clicking a form submission incorrectly |
// sends as a GET rather than a POST if it creates a new window in a different process. |
- return request.formState() && action.shouldOpenInNewWindow(); |
+ return request.formState() && policy != NavigationPolicyCurrentTab; |
+} |
+ |
+static NavigationType determineNavigationType(FrameLoadType frameLoadType, bool isFormSubmission, bool haveEvent) |
+{ |
+ bool isReload = frameLoadType == FrameLoadTypeReload || frameLoadType == FrameLoadTypeReloadFromOrigin; |
+ bool isBackForward = isBackForwardLoadType(frameLoadType); |
+ if (isFormSubmission) |
+ return (isReload || isBackForward) ? NavigationTypeFormResubmitted : NavigationTypeFormSubmitted; |
+ if (haveEvent) |
+ return NavigationTypeLinkClicked; |
+ if (isReload) |
+ return NavigationTypeReload; |
+ if (isBackForward) |
+ return NavigationTypeBackForward; |
+ return NavigationTypeOther; |
} |
static WebURLRequest::RequestContext determineRequestContextFromNavigationType(const NavigationType navigationType) |
@@ -733,6 +747,23 @@ static WebURLRequest::RequestContext determineRequestContextFromNavigationType(c |
return WebURLRequest::RequestContextHyperlink; |
} |
+static NavigationPolicy navigationPolicyForRequest(const FrameLoadRequest& request) |
+{ |
+ NavigationPolicy policy = NavigationPolicyCurrentTab; |
+ Event* event = request.triggeringEvent(); |
+ if (!event) |
+ return policy; |
+ |
+ if (request.formState() && event->underlyingEvent()) |
+ event = event->underlyingEvent(); |
+ if (!event->isMouseEvent()) |
+ return policy; |
+ |
+ const MouseEvent* mouseEvent = toMouseEvent(event); |
+ navigationPolicyFromMouseEvent(mouseEvent->button(), mouseEvent->ctrlKey(), mouseEvent->shiftKey(), mouseEvent->altKey(), mouseEvent->metaKey(), &policy); |
dcheng
2014/12/16 18:57:04
It seems kind of odd that we ignore the bool retur
|
+ return policy; |
+} |
+ |
void FrameLoader::load(const FrameLoadRequest& passedRequest) |
{ |
ASSERT(m_frame->document()); |
@@ -758,27 +789,25 @@ void FrameLoader::load(const FrameLoadRequest& passedRequest) |
setReferrerForFrameRequest(request.resourceRequest(), request.shouldSendReferrer(), request.originDocument()); |
FrameLoadType newLoadType = determineFrameLoadType(request); |
- NavigationAction action(request.resourceRequest(), newLoadType, request.formState(), request.triggeringEvent()); |
- if (action.resourceRequest().requestContext() == WebURLRequest::RequestContextUnspecified) |
- action.mutableResourceRequest().setRequestContext(determineRequestContextFromNavigationType(action.type())); |
- if (shouldOpenInNewWindow(targetFrame.get(), request, action)) { |
- if (action.policy() == NavigationPolicyDownload) |
- client()->loadURLExternally(action.resourceRequest(), NavigationPolicyDownload); |
+ NavigationPolicy policy = navigationPolicyForRequest(request); |
+ if (shouldOpenInNewWindow(targetFrame.get(), request, policy)) { |
+ if (policy == NavigationPolicyDownload) |
+ client()->loadURLExternally(request.resourceRequest(), NavigationPolicyDownload); |
else |
- createWindowForRequest(request, *m_frame, action.policy(), request.shouldSendReferrer()); |
+ createWindowForRequest(request, *m_frame, policy, request.shouldSendReferrer()); |
return; |
} |
const KURL& url = request.resourceRequest().url(); |
- if (!action.shouldOpenInNewWindow() && shouldPerformFragmentNavigation(request.formState(), request.resourceRequest().httpMethod(), newLoadType, url)) { |
- m_documentLoader->setTriggeringAction(action); |
+ if (policy == NavigationPolicyCurrentTab && shouldPerformFragmentNavigation(request.formState(), request.resourceRequest().httpMethod(), newLoadType, url)) { |
+ m_documentLoader->setNavigationType(determineNavigationType(newLoadType, false, request.triggeringEvent())); |
if (shouldTreatURLAsSameAsCurrent(url)) |
newLoadType = FrameLoadTypeRedirectWithLockedBackForwardList; |
loadInSameDocument(url, nullptr, newLoadType, request.clientRedirect()); |
return; |
} |
bool sameURL = url == m_documentLoader->urlForHistory(); |
- loadWithNavigationAction(action, newLoadType, request.formState(), request.substituteData(), request.shouldCheckMainWorldContentSecurityPolicy(), request.clientRedirect(), request.triggeringEvent()); |
+ startLoad(request, newLoadType, policy); |
// Example of this case are sites that reload the same URL with a different cookie |
// driving the generated content, or a master frame with links that drive a target |
// frame, where the user has clicked on the same link repeatedly. |
@@ -829,8 +858,6 @@ void FrameLoader::reload(ReloadPolicy reloadPolicy, const KURL& overrideURL, Cli |
ResourceRequestCachePolicy cachePolicy = reloadPolicy == EndToEndReload ? ReloadBypassingCache : ReloadIgnoringCacheData; |
ResourceRequest request = requestFromHistoryItem(m_currentItem.get(), cachePolicy); |
- request.setFrameType(m_frame->isMainFrame() ? WebURLRequest::FrameTypeTopLevel : WebURLRequest::FrameTypeNested); |
- request.setRequestContext(WebURLRequest::RequestContextInternal); |
// ClientRedirectPolicy is an indication that this load was triggered by |
// some direct interaction with the page. If this reload is not a client |
@@ -846,9 +873,9 @@ void FrameLoader::reload(ReloadPolicy reloadPolicy, const KURL& overrideURL, Cli |
request.clearHTTPReferrer(); |
} |
request.setSkipServiceWorker(reloadPolicy == EndToEndReload); |
- |
- FrameLoadType type = reloadPolicy == EndToEndReload ? FrameLoadTypeReloadFromOrigin : FrameLoadTypeReload; |
- loadWithNavigationAction(NavigationAction(request, type), type, nullptr, SubstituteData(), CheckContentSecurityPolicy, clientRedirectPolicy); |
+ FrameLoadRequest frameLoadRequest(nullptr, request); |
+ frameLoadRequest.setClientRedirect(clientRedirectPolicy); |
+ startLoad(frameLoadRequest, reloadPolicy == EndToEndReload ? FrameLoadTypeReloadFromOrigin : FrameLoadTypeReload, NavigationPolicyCurrentTab); |
} |
void FrameLoader::stopAllLoaders() |
@@ -1262,13 +1289,16 @@ bool FrameLoader::dispatchNavigationTransitionData() |
return true; |
} |
-void FrameLoader::loadWithNavigationAction(const NavigationAction& action, FrameLoadType type, PassRefPtrWillBeRawPtr<FormState> formState, const SubstituteData& substituteData, ContentSecurityPolicyDisposition shouldCheckMainWorldContentSecurityPolicy, ClientRedirectPolicy clientRedirect, Event* triggeringEvent) |
+void FrameLoader::startLoad(FrameLoadRequest& frameLoadRequest, FrameLoadType type, NavigationPolicy navigationPolicy) |
{ |
ASSERT(client()->hasWebView()); |
if (m_frame->document()->pageDismissalEventBeingDispatched() != Document::NoDismissal) |
return; |
- const ResourceRequest& request = action.resourceRequest(); |
+ NavigationType navigationType = determineNavigationType(type, frameLoadRequest.resourceRequest().httpBody() || frameLoadRequest.formState(), frameLoadRequest.triggeringEvent()); |
+ frameLoadRequest.resourceRequest().setRequestContext(determineRequestContextFromNavigationType(navigationType)); |
+ frameLoadRequest.resourceRequest().setFrameType(m_frame->isMainFrame() ? WebURLRequest::FrameTypeTopLevel : WebURLRequest::FrameTypeNested); |
+ ResourceRequest& request = frameLoadRequest.resourceRequest(); |
// The current load should replace the history item if it is the first real |
// load of the frame. |
@@ -1278,10 +1308,10 @@ void FrameLoader::loadWithNavigationAction(const NavigationAction& action, Frame |
replacesCurrentHistoryItem = true; |
} |
- m_policyDocumentLoader = client()->createDocumentLoader(m_frame, request, substituteData.isValid() ? substituteData : defaultSubstituteDataForURL(request.url())); |
- m_policyDocumentLoader->setTriggeringAction(action); |
+ m_policyDocumentLoader = client()->createDocumentLoader(m_frame, request, frameLoadRequest.substituteData().isValid() ? frameLoadRequest.substituteData() : defaultSubstituteDataForURL(request.url())); |
+ m_policyDocumentLoader->setNavigationType(navigationType); |
m_policyDocumentLoader->setReplacesCurrentHistoryItem(replacesCurrentHistoryItem); |
- m_policyDocumentLoader->setIsClientRedirect(clientRedirect == ClientRedirect); |
+ m_policyDocumentLoader->setIsClientRedirect(frameLoadRequest.clientRedirect() == ClientRedirect); |
bool isTransitionNavigation = false; |
if (RuntimeEnabledFeatures::navigationTransitionsEnabled() && type != FrameLoadTypeReload && type != FrameLoadTypeReloadFromOrigin && type != FrameLoadTypeSame) |
@@ -1289,7 +1319,7 @@ void FrameLoader::loadWithNavigationAction(const NavigationAction& action, Frame |
// stopAllLoaders can detach the LocalFrame, so protect it. |
RefPtrWillBeRawPtr<LocalFrame> protect(m_frame.get()); |
- if ((!m_policyDocumentLoader->shouldContinueForNavigationPolicy(request, shouldCheckMainWorldContentSecurityPolicy, isTransitionNavigation) || !shouldClose()) && m_policyDocumentLoader) { |
+ if ((!m_policyDocumentLoader->shouldContinueForNavigationPolicy(request, frameLoadRequest.shouldCheckMainWorldContentSecurityPolicy(), navigationPolicy, isTransitionNavigation) || !shouldClose()) && m_policyDocumentLoader) { |
m_policyDocumentLoader->detachFromFrame(); |
m_policyDocumentLoader = nullptr; |
if (!m_stateMachine.committedFirstRealDocumentLoad()) |
@@ -1319,14 +1349,14 @@ void FrameLoader::loadWithNavigationAction(const NavigationAction& action, Frame |
m_loadType = type; |
m_state = FrameStateProvisional; |
- if (formState) |
+ if (FormState* formState = frameLoadRequest.formState()) |
client()->dispatchWillSubmitForm(formState->form()); |
m_progressTracker->progressStarted(); |
if (m_provisionalDocumentLoader->isClientRedirect()) |
m_provisionalDocumentLoader->appendRedirect(m_frame->document()->url()); |
m_provisionalDocumentLoader->appendRedirect(m_provisionalDocumentLoader->request().url()); |
- double triggeringEventTime = triggeringEvent ? convertDOMTimeStampToSeconds(triggeringEvent->timeStamp()) : 0; |
+ double triggeringEventTime = frameLoadRequest.triggeringEvent() ? convertDOMTimeStampToSeconds(frameLoadRequest.triggeringEvent()->timeStamp()) : 0; |
client()->dispatchDidStartProvisionalLoad(isTransitionNavigation, triggeringEventTime); |
ASSERT(m_provisionalDocumentLoader); |
m_provisionalDocumentLoader->startLoadingMainResource(); |
@@ -1424,11 +1454,8 @@ void FrameLoader::loadHistoryItem(HistoryItem* item, FrameLoadType frameLoadType |
restoreScrollPositionAndViewState(); |
return; |
} |
- |
- ResourceRequest request = requestFromHistoryItem(item, cachePolicy); |
- request.setFrameType(m_frame->isMainFrame() ? WebURLRequest::FrameTypeTopLevel : WebURLRequest::FrameTypeNested); |
- request.setRequestContext(WebURLRequest::RequestContextInternal); |
- loadWithNavigationAction(NavigationAction(request, frameLoadType), frameLoadType, nullptr, SubstituteData(), CheckContentSecurityPolicy); |
+ FrameLoadRequest request(nullptr, requestFromHistoryItem(item, cachePolicy)); |
+ startLoad(request, frameLoadType, NavigationPolicyCurrentTab); |
} |
void FrameLoader::dispatchDocumentElementAvailable() |