Index: Source/core/loader/FrameLoader.cpp |
diff --git a/Source/core/loader/FrameLoader.cpp b/Source/core/loader/FrameLoader.cpp |
index df7b71458088ae0c1e25bcdf259046383eddf752..030276868168184bfe76b566d46a5c3be08518d6 100644 |
--- a/Source/core/loader/FrameLoader.cpp |
+++ b/Source/core/loader/FrameLoader.cpp |
@@ -100,12 +100,69 @@ using namespace HTMLNames; |
bool isBackForwardLoadType(FrameLoadType type) |
{ |
- return type == FrameLoadTypeBackForward || type == FrameLoadTypeInitialHistoryLoad; |
+ return type == FrameLoadTypeBackForward || type == FrameLoadTypeInitialHistoryLoad |
+ || type == FrameLoadTypeHistorySameDocument; |
} |
static bool needsHistoryItemRestore(FrameLoadType type) |
{ |
- return type == FrameLoadTypeBackForward || type == FrameLoadTypeReload || type == FrameLoadTypeReloadFromOrigin; |
+ return type == FrameLoadTypeBackForward || type == FrameLoadTypeReload |
+ || type == FrameLoadTypeReloadFromOrigin || type == FrameLoadTypeHistorySameDocument; |
+} |
+ |
+// static |
+ResourceRequest FrameLoader::resourceRequestFromHistoryItem(HistoryItem* item, |
+ ResourceRequestCachePolicy cachePolicy) |
+{ |
+ RefPtr<FormData> formData = item->formData(); |
+ ResourceRequest request(item->url()); |
+ request.setHTTPReferrer(item->referrer()); |
+ request.setCachePolicy(cachePolicy); |
+ if (formData) { |
+ request.setHTTPMethod("POST"); |
+ request.setHTTPBody(formData); |
+ request.setHTTPContentType(item->formContentType()); |
+ RefPtr<SecurityOrigin> securityOrigin = SecurityOrigin::createFromString(item->referrer().referrer); |
+ request.addHTTPOriginIfNeeded(securityOrigin->toAtomicString()); |
+ } |
+ return request; |
+} |
+ |
+// static |
+ResourceRequest FrameLoader::resourceRequestForReload(HistoryItem* item, const LocalFrame& frame, |
+ FrameLoadType frameLoadType, const KURL& overrideURL, ClientRedirectPolicy clientRedirectPolicy) |
+{ |
+ ASSERT(frameLoadType == FrameLoadTypeReload || frameLoadType == FrameLoadTypeReloadFromOrigin); |
+ ResourceRequestCachePolicy cachePolicy = frameLoadType == FrameLoadTypeReloadFromOrigin ? |
+ ReloadBypassingCache : ReloadIgnoringCacheData; |
+ ResourceRequest request = resourceRequestFromHistoryItem(item, cachePolicy); |
+ |
+ // ClientRedirectPolicy is an indication that this load was triggered by |
+ // some direct interaction with the page. If this reload is not a client |
+ // redirect, we should reuse the referrer from the original load of the |
+ // current document. If this reload is a client redirect (e.g., location.reload()), |
+ // it was initiated by something in the current document and should |
+ // therefore show the current document's url as the referrer. |
+ if (clientRedirectPolicy == ClientRedirect) { |
+ request.setHTTPReferrer(Referrer(frame.document()->outgoingReferrer(), |
+ frame.document()->referrerPolicy())); |
+ } |
+ |
+ if (!overrideURL.isEmpty()) { |
+ request.setURL(overrideURL); |
+ request.clearHTTPReferrer(); |
+ } |
+ request.setSkipServiceWorker(frameLoadType == FrameLoadTypeReloadFromOrigin); |
+ return request; |
+} |
+ |
+// static |
+FrameLoadRequest FrameLoader::frameRequestForReload(const ResourceRequest& resourceRequest, |
+ ClientRedirectPolicy clientRedirectPolicy) |
+{ |
+ FrameLoadRequest request = FrameLoadRequest(nullptr, resourceRequest); |
+ request.setClientRedirect(clientRedirectPolicy); |
+ return request; |
} |
FrameLoader::FrameLoader(LocalFrame* frame) |
@@ -169,8 +226,8 @@ void FrameLoader::setDefersLoading(bool defers) |
if (!defers) { |
if (m_deferredHistoryLoad.isValid()) { |
- loadHistoryItem(m_deferredHistoryLoad.m_item.get(), FrameLoadTypeBackForward, |
- m_deferredHistoryLoad.m_type, m_deferredHistoryLoad.m_cachePolicy); |
+ load(FrameLoadRequest(nullptr, m_deferredHistoryLoad.m_request), |
+ m_deferredHistoryLoad.m_loadType, m_deferredHistoryLoad.m_item.get()); |
m_deferredHistoryLoad = DeferredHistoryLoad(); |
} |
m_frame->navigationScheduler().startTimer(); |
@@ -329,6 +386,7 @@ static HistoryCommitType loadTypeToCommitType(FrameLoadType type) |
case FrameLoadTypeInitialHistoryLoad: |
return InitialCommitInChildFrame; |
case FrameLoadTypeBackForward: |
+ case FrameLoadTypeHistorySameDocument: |
return BackForwardCommit; |
default: |
break; |
@@ -394,8 +452,11 @@ void FrameLoader::didBeginDocument(bool dispatch) |
} |
} |
- if (m_provisionalItem && (m_loadType == FrameLoadTypeBackForward || m_loadType == FrameLoadTypeInitialHistoryLoad)) |
+ if (m_provisionalItem && (m_loadType == FrameLoadTypeBackForward |
+ || m_loadType == FrameLoadTypeInitialHistoryLoad |
+ || m_loadType == FrameLoadTypeHistorySameDocument)) { |
m_frame->document()->setStateForNewFormElements(m_provisionalItem->documentState()); |
+ } |
client()->didCreateNewDocument(); |
} |
@@ -591,7 +652,8 @@ void FrameLoader::updateForSameDocumentNavigation(const KURL& newURL, SameDocume |
void FrameLoader::loadInSameDocument(const KURL& url, PassRefPtr<SerializedScriptValue> stateObject, FrameLoadType type, ClientRedirectPolicy clientRedirect) |
{ |
// If we have a state object, we cannot also be a new navigation. |
- ASSERT(!stateObject || type == FrameLoadTypeBackForward); |
+ ASSERT(!stateObject || type == FrameLoadTypeBackForward |
+ || type == FrameLoadTypeHistorySameDocument); |
// If we have a provisional request for a different document, a fragment scroll should cancel it. |
if (m_provisionalDocumentLoader) { |
@@ -756,7 +818,8 @@ static NavigationPolicy navigationPolicyForRequest(const FrameLoadRequest& reque |
return policy; |
} |
-void FrameLoader::load(const FrameLoadRequest& passedRequest) |
+void FrameLoader::load(const FrameLoadRequest& passedRequest, FrameLoadType frameLoadType, |
+ HistoryItem* historyItem) |
{ |
ASSERT(m_frame->document()); |
@@ -765,13 +828,23 @@ void FrameLoader::load(const FrameLoadRequest& passedRequest) |
if (m_inStopAllLoaders) |
return; |
- FrameLoadRequest request(passedRequest); |
- request.resourceRequest().setHasUserGesture(UserGestureIndicator::processingUserGesture()); |
+ if (m_frame->page()->defersLoading() && isBackForwardLoadType(frameLoadType)) { |
+ m_deferredHistoryLoad = DeferredHistoryLoad( |
+ passedRequest.resourceRequest(), historyItem, frameLoadType); |
+ return; |
+ } |
+ FrameLoadRequest request(passedRequest); |
if (!prepareRequestForThisFrame(request)) |
return; |
+ if (isBackForwardLoadType(frameLoadType)) { |
+ ASSERT(historyItem); |
+ m_provisionalItem = historyItem; |
+ } |
+ |
RefPtrWillBeRawPtr<LocalFrame> targetFrame = toLocalFrame(request.form() ? nullptr : m_frame->findFrameForNavigation(AtomicString(request.frameName()), *m_frame)); |
+ request.resourceRequest().setHasUserGesture(UserGestureIndicator::processingUserGesture()); |
Nate Chapin
2015/05/27 16:54:34
Why move this?
clamy
2015/05/29 14:41:50
Done.
|
if (targetFrame && targetFrame.get() != m_frame) { |
bool wasInSamePage = targetFrame->page() == m_frame->page(); |
@@ -785,7 +858,9 @@ void FrameLoader::load(const FrameLoadRequest& passedRequest) |
setReferrerForFrameRequest(request.resourceRequest(), request.shouldSendReferrer(), request.originDocument()); |
- FrameLoadType newLoadType = determineFrameLoadType(request); |
+ FrameLoadType newLoadType = frameLoadType; |
Nate Chapin
2015/05/27 16:54:34
FrameLoadType newLoadType = (frameLoadType == Fram
clamy
2015/05/29 14:41:50
Done.
|
+ if (newLoadType == FrameLoadTypeStandard) |
+ newLoadType = determineFrameLoadType(request); |
NavigationPolicy policy = navigationPolicyForRequest(request); |
if (shouldOpenInNewWindow(targetFrame.get(), request, policy)) { |
if (policy == NavigationPolicyDownload) { |
@@ -798,20 +873,39 @@ void FrameLoader::load(const FrameLoadRequest& passedRequest) |
} |
const KURL& url = request.resourceRequest().url(); |
- if (policy == NavigationPolicyCurrentTab && shouldPerformFragmentNavigation(request.form(), request.resourceRequest().httpMethod(), newLoadType, url)) { |
+ |
+ // Perform history same document navigation. |
+ if (newLoadType == FrameLoadTypeHistorySameDocument) { |
+ ASSERT(historyItem); |
+ loadInSameDocument(url, historyItem->stateObject(), newLoadType, NotClientRedirect); |
+ restoreScrollPositionAndViewState(); |
+ return; |
+ } |
+ |
+ // Perform non-history same document navigation. |
+ if ((policy == NavigationPolicyCurrentTab && newLoadType != FrameLoadTypeReloadFromOrigin |
Nate Chapin
2015/05/27 16:54:34
Add the FrameLoadTypeReloadFromOrigin case to shou
clamy
2015/05/29 14:41:50
Done.
|
+ && shouldPerformFragmentNavigation(request.form(), 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; |
} |
+ |
+ // Perform navigation to a different document. |
bool sameURL = url == m_documentLoader->urlForHistory(); |
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. |
- if (sameURL && newLoadType != FrameLoadTypeReload && newLoadType != FrameLoadTypeReloadFromOrigin && request.resourceRequest().httpMethod() != "POST") |
+ if (sameURL |
+ && isBackForwardLoadType(frameLoadType) |
Nate Chapin
2015/05/27 16:54:34
Why this change?
clamy
2015/05/29 14:41:50
Actually I meant to write !isBackForwardLoadType(f
|
+ && newLoadType != FrameLoadTypeReload |
+ && newLoadType != FrameLoadTypeReloadFromOrigin |
+ && request.resourceRequest().httpMethod() != "POST") { |
m_loadType = FrameLoadTypeSame; |
+ } |
} |
SubstituteData FrameLoader::defaultSubstituteDataForURL(const KURL& url) |
@@ -833,50 +927,6 @@ void FrameLoader::reportLocalLoadFailed(LocalFrame* frame, const String& url) |
frame->document()->addConsoleMessage(ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel, "Not allowed to load local resource: " + url)); |
} |
-// static |
-ResourceRequest FrameLoader::requestFromHistoryItem(HistoryItem* item, ResourceRequestCachePolicy cachePolicy) |
-{ |
- RefPtr<FormData> formData = item->formData(); |
- ResourceRequest request(item->url()); |
- request.setHTTPReferrer(item->referrer()); |
- request.setCachePolicy(cachePolicy); |
- if (formData) { |
- request.setHTTPMethod("POST"); |
- request.setHTTPBody(formData); |
- request.setHTTPContentType(item->formContentType()); |
- RefPtr<SecurityOrigin> securityOrigin = SecurityOrigin::createFromString(item->referrer().referrer); |
- request.addHTTPOriginIfNeeded(securityOrigin->toAtomicString()); |
- } |
- return request; |
-} |
- |
-void FrameLoader::reload(ReloadPolicy reloadPolicy, const KURL& overrideURL, ClientRedirectPolicy clientRedirectPolicy) |
-{ |
- if (!m_currentItem) |
- return; |
- |
- ResourceRequestCachePolicy cachePolicy = reloadPolicy == EndToEndReload ? ReloadBypassingCache : ReloadIgnoringCacheData; |
- ResourceRequest request = requestFromHistoryItem(m_currentItem.get(), cachePolicy); |
- |
- // ClientRedirectPolicy is an indication that this load was triggered by |
- // some direct interaction with the page. If this reload is not a client |
- // redirect, we should reuse the referrer from the original load of the |
- // current document. If this reload is a client redirect (e.g., location.reload()), |
- // it was initiated by something in the current document and should |
- // therefore show the current document's url as the referrer. |
- if (clientRedirectPolicy == ClientRedirect) |
- request.setHTTPReferrer(Referrer(m_frame->document()->outgoingReferrer(), m_frame->document()->referrerPolicy())); |
- |
- if (!overrideURL.isEmpty()) { |
- request.setURL(overrideURL); |
- request.clearHTTPReferrer(); |
- } |
- request.setSkipServiceWorker(reloadPolicy == EndToEndReload); |
- FrameLoadRequest frameLoadRequest(nullptr, request); |
- frameLoadRequest.setClientRedirect(clientRedirectPolicy); |
- startLoad(frameLoadRequest, reloadPolicy == EndToEndReload ? FrameLoadTypeReloadFromOrigin : FrameLoadTypeReload, NavigationPolicyCurrentTab); |
-} |
- |
void FrameLoader::stopAllLoaders() |
{ |
if (m_frame->document()->pageDismissalEventBeingDispatched() != Document::NoDismissal) |
@@ -1132,6 +1182,7 @@ bool FrameLoader::shouldPerformFragmentNavigation(bool isFormSubmission, const S |
&& loadType != FrameLoadTypeReload |
&& loadType != FrameLoadTypeSame |
&& loadType != FrameLoadTypeBackForward |
+ && loadType != FrameLoadTypeHistorySameDocument |
&& url.hasFragmentIdentifier() |
&& equalIgnoringFragmentIdentifier(m_frame->document()->url(), url) |
// We don't want to just scroll if a link from within a |
@@ -1335,24 +1386,6 @@ bool FrameLoader::shouldTreatURLAsSrcdocDocument(const KURL& url) const |
return ownerElement->fastHasAttribute(srcdocAttr); |
} |
-void FrameLoader::loadHistoryItem(HistoryItem* item, FrameLoadType frameLoadType, HistoryLoadType historyLoadType, ResourceRequestCachePolicy cachePolicy) |
-{ |
- RefPtrWillBeRawPtr<LocalFrame> protect(m_frame.get()); |
- if (m_frame->page()->defersLoading()) { |
- m_deferredHistoryLoad = DeferredHistoryLoad(item, historyLoadType, cachePolicy); |
- return; |
- } |
- |
- m_provisionalItem = item; |
- if (historyLoadType == HistorySameDocumentLoad) { |
- loadInSameDocument(item->url(), item->stateObject(), frameLoadType, NotClientRedirect); |
- restoreScrollPositionAndViewState(); |
- return; |
- } |
- FrameLoadRequest request(nullptr, requestFromHistoryItem(item, cachePolicy)); |
- startLoad(request, frameLoadType, NavigationPolicyCurrentTab); |
-} |
- |
void FrameLoader::dispatchDocumentElementAvailable() |
{ |
client()->documentElementAvailable(); |