Index: WebCore/loader/HistoryController.cpp |
=================================================================== |
--- WebCore/loader/HistoryController.cpp (revision 78375) |
+++ WebCore/loader/HistoryController.cpp (working copy) |
@@ -248,6 +248,10 @@ |
// Must grab the current scroll position before disturbing it |
if (!m_frameLoadComplete) |
saveScrollPositionAndViewStateToItem(m_previousItem.get()); |
+ |
+ // When traversing history, we may end up redirecting to a different URL |
+ // this time (e.g., due to cookies). See http://webkit.org/b/49654. |
+ updateCurrentItem(); |
} |
void HistoryController::updateForReload() |
@@ -262,11 +266,11 @@ |
if (m_frame->loader()->loadType() == FrameLoadTypeReload || m_frame->loader()->loadType() == FrameLoadTypeReloadFromOrigin) |
saveScrollPositionAndViewStateToItem(m_currentItem.get()); |
- |
- // Sometimes loading a page again leads to a different result because of cookies. Bugzilla 4072 |
- if (m_frame->loader()->documentLoader()->unreachableURL().isEmpty()) |
- m_currentItem->setURL(m_frame->loader()->documentLoader()->requestURL()); |
} |
+ |
+ // When reloading the page, we may end up redirecting to a different URL |
+ // this time (e.g., due to cookies). See http://webkit.org/b/4072. |
+ updateCurrentItem(); |
} |
// There are 3 things you might think of as "history", all of which are handled by these functions. |
@@ -298,9 +302,9 @@ |
if (Page* page = m_frame->page()) |
page->setGlobalHistoryItem(needPrivacy ? 0 : page->backForward()->currentItem()); |
} |
- } else if (frameLoader->documentLoader()->unreachableURL().isEmpty() && m_currentItem) { |
- m_currentItem->setURL(frameLoader->documentLoader()->url()); |
- m_currentItem->setFormInfoFromRequest(frameLoader->documentLoader()->request()); |
+ } else { |
+ // The client redirect replaces the current history item. |
+ updateCurrentItem(); |
} |
if (!historyURL.isEmpty() && !needPrivacy) { |
@@ -337,14 +341,12 @@ |
page->setGlobalHistoryItem(needPrivacy ? 0 : page->backForward()->currentItem()); |
} |
} |
- if (m_currentItem) { |
- m_currentItem->setURL(m_frame->loader()->documentLoader()->url()); |
- m_currentItem->setFormInfoFromRequest(m_frame->loader()->documentLoader()->request()); |
- } |
+ // The client redirect replaces the current history item. |
+ updateCurrentItem(); |
} else { |
Frame* parentFrame = m_frame->tree()->parent(); |
if (parentFrame && parentFrame->loader()->history()->m_currentItem) |
- parentFrame->loader()->history()->m_currentItem->setChildItem(createItem(true)); |
+ parentFrame->loader()->history()->m_currentItem->setChildItem(createItem()); |
} |
if (!historyURL.isEmpty() && !needPrivacy) { |
@@ -453,12 +455,13 @@ |
m_provisionalItem = item; |
} |
-PassRefPtr<HistoryItem> HistoryController::createItem(bool useOriginal) |
+void HistoryController::initializeItem(HistoryItem* item) |
{ |
DocumentLoader* documentLoader = m_frame->loader()->documentLoader(); |
- |
- KURL unreachableURL = documentLoader ? documentLoader->unreachableURL() : KURL(); |
- |
+ ASSERT(documentLoader); |
+ |
+ KURL unreachableURL = documentLoader->unreachableURL(); |
+ |
KURL url; |
KURL originalURL; |
@@ -466,15 +469,10 @@ |
url = unreachableURL; |
originalURL = unreachableURL; |
} else { |
- originalURL = documentLoader ? documentLoader->originalURL() : KURL(); |
- if (useOriginal) |
- url = originalURL; |
- else if (documentLoader) |
- url = documentLoader->requestURL(); |
+ url = documentLoader->url(); |
+ originalURL = documentLoader->originalURL(); |
} |
- LOG(History, "WebCoreHistory: Creating item for %s", url.string().ascii().data()); |
- |
// Frames that have never successfully loaded any content |
// may have no URL at all. Currently our history code can't |
// deal with such things, so we nip that in the bud here. |
@@ -487,21 +485,25 @@ |
Frame* parentFrame = m_frame->tree()->parent(); |
String parent = parentFrame ? parentFrame->tree()->uniqueName() : ""; |
- String title = documentLoader ? documentLoader->title() : ""; |
+ String title = documentLoader->title(); |
- RefPtr<HistoryItem> item = HistoryItem::create(url, m_frame->tree()->uniqueName(), parent, title); |
+ item->setURL(url); |
+ item->setTarget(m_frame->tree()->uniqueName()); |
+ item->setParent(parent); |
+ item->setTitle(title); |
item->setOriginalURLString(originalURL.string()); |
- if (!unreachableURL.isEmpty() || !documentLoader || documentLoader->response().httpStatusCode() >= 400) |
+ if (!unreachableURL.isEmpty() || documentLoader->response().httpStatusCode() >= 400) |
item->setLastVisitWasFailure(true); |
// Save form state if this is a POST |
- if (documentLoader) { |
- if (useOriginal) |
- item->setFormInfoFromRequest(documentLoader->originalRequest()); |
- else |
- item->setFormInfoFromRequest(documentLoader->request()); |
- } |
+ item->setFormInfoFromRequest(documentLoader->request()); |
+} |
+ |
+PassRefPtr<HistoryItem> HistoryController::createItem() |
+{ |
+ RefPtr<HistoryItem> item = HistoryItem::create(); |
+ initializeItem(item.get()); |
// Set the item for which we will save document state |
m_frameLoadComplete = false; |
@@ -513,7 +515,7 @@ |
PassRefPtr<HistoryItem> HistoryController::createItemTree(Frame* targetFrame, bool clipAtTarget) |
{ |
- RefPtr<HistoryItem> bfItem = createItem(m_frame->tree()->parent() ? true : false); |
+ RefPtr<HistoryItem> bfItem = createItem(); |
if (!m_frameLoadComplete) |
saveScrollPositionAndViewStateToItem(m_previousItem.get()); |
@@ -647,6 +649,31 @@ |
page->backForward()->addItem(topItem.release()); |
} |
+void HistoryController::updateCurrentItem() |
+{ |
+ if (!m_currentItem) |
+ return; |
+ |
+ DocumentLoader* documentLoader = m_frame->loader()->documentLoader(); |
+ |
+ if (!documentLoader->unreachableURL().isEmpty()) |
+ return; |
+ |
+ if (m_currentItem->url() != documentLoader->url()) { |
+ // We ended up on a completely different URL this time, so the HistoryItem |
+ // needs to be re-initialized. Preserve the isTargetItem flag as it is a |
+ // property of how this HistoryItem was originally created and is not |
+ // dependent on the document. |
+ bool isTargetItem = m_currentItem->isTargetItem(); |
+ m_currentItem->reset(); |
+ initializeItem(m_currentItem.get()); |
+ m_currentItem->setIsTargetItem(isTargetItem); |
+ } else { |
+ // Even if the final URL didn't change, the form data may have changed. |
+ m_currentItem->setFormInfoFromRequest(documentLoader->request()); |
+ } |
+} |
+ |
void HistoryController::pushState(PassRefPtr<SerializedScriptValue> stateObject, const String& title, const String& urlString) |
{ |
if (!m_currentItem) |