summaryrefslogtreecommitdiff
path: root/Source/WebCore/loader/HistoryController.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
commit32761a6cee1d0dee366b885b7b9c777e67885688 (patch)
treed6bec92bebfb216f4126356e55518842c2f476a1 /Source/WebCore/loader/HistoryController.cpp
parenta4e969f4965059196ca948db781e52f7cfebf19e (diff)
downloadWebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/WebCore/loader/HistoryController.cpp')
-rw-r--r--Source/WebCore/loader/HistoryController.cpp369
1 files changed, 177 insertions, 192 deletions
diff --git a/Source/WebCore/loader/HistoryController.cpp b/Source/WebCore/loader/HistoryController.cpp
index a33287d41..ffd9d32c1 100644
--- a/Source/WebCore/loader/HistoryController.cpp
+++ b/Source/WebCore/loader/HistoryController.cpp
@@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -41,21 +41,22 @@
#include "FrameTree.h"
#include "FrameView.h"
#include "HistoryItem.h"
-#include "LinkHash.h"
#include "Logging.h"
#include "MainFrame.h"
#include "Page.h"
#include "PageCache.h"
#include "PageGroup.h"
+#include "PlatformStrategies.h"
#include "ScrollingCoordinator.h"
-#include "VisitedLinkStore.h"
+#include "Settings.h"
+#include "VisitedLinkStrategy.h"
#include <wtf/text/CString.h>
namespace WebCore {
-static inline void addVisitedLink(Page& page, const URL& url)
+static inline void addVisitedLink(Page* page, const URL& url)
{
- page.visitedLinkStore().addVisitedLink(page, visitedLinkHash(url.string()));
+ platformStrategies()->visitedLinkStrategy()->addVisitedLink(page, visitedLinkHash(url.string()));
}
HistoryController::HistoryController(Frame& frame)
@@ -71,28 +72,20 @@ HistoryController::~HistoryController()
void HistoryController::saveScrollPositionAndViewStateToItem(HistoryItem* item)
{
- FrameView* frameView = m_frame.view();
- if (!item || !frameView)
+ if (!item || !m_frame.view())
return;
if (m_frame.document()->inPageCache())
- item->setScrollPosition(frameView->cachedScrollPosition());
+ item->setScrollPoint(m_frame.view()->cachedScrollPosition());
else
- item->setScrollPosition(frameView->scrollPosition());
-#if PLATFORM(IOS)
- item->setExposedContentRect(frameView->exposedContentRect());
- item->setUnobscuredContentRect(frameView->unobscuredContentRect());
-#endif
+ item->setScrollPoint(m_frame.view()->scrollPosition());
Page* page = m_frame.page();
if (page && m_frame.isMainFrame())
- item->setPageScaleFactor(page->pageScaleFactor() / page->viewScaleFactor());
+ item->setPageScaleFactor(page->pageScaleFactor());
// FIXME: It would be great to work out a way to put this code in WebCore instead of calling through to the client.
m_frame.loader().client().saveViewStateToItem(item);
-
- // Notify clients that the HistoryItem has changed.
- item->notifyChanged();
}
void HistoryController::clearScrollPositionAndViewState()
@@ -100,7 +93,7 @@ void HistoryController::clearScrollPositionAndViewState()
if (!m_currentItem)
return;
- m_currentItem->clearScrollPosition();
+ m_currentItem->clearScrollPoint();
m_currentItem->setPageScaleFactor(0);
}
@@ -117,7 +110,7 @@ void HistoryController::clearScrollPositionAndViewState()
*/
void HistoryController::restoreScrollPositionAndViewState()
{
- if (!m_frame.loader().stateMachine().committedFirstRealDocumentLoad())
+ if (!m_frame.loader().stateMachine()->committedFirstRealDocumentLoad())
return;
ASSERT(m_currentItem);
@@ -129,44 +122,31 @@ void HistoryController::restoreScrollPositionAndViewState()
// so there *is* no scroll or view state to restore!
if (!m_currentItem)
return;
+
+ // FIXME: It would be great to work out a way to put this code in WebCore instead of calling
+ // through to the client. It's currently used only for the PDF view on Mac.
+ m_frame.loader().client().restoreViewState();
- FrameView* view = m_frame.view();
-
+ // Don't restore scroll point on iOS as FrameLoaderClient::restoreViewState() does that.
+#if !PLATFORM(IOS)
// FIXME: There is some scrolling related work that needs to happen whenever a page goes into the
// page cache and similar work that needs to occur when it comes out. This is where we do the work
// that needs to happen when we exit, and the work that needs to happen when we enter is in
// Document::setIsInPageCache(bool). It would be nice if there was more symmetry in these spots.
// https://bugs.webkit.org/show_bug.cgi?id=98698
- if (view) {
+ if (FrameView* view = m_frame.view()) {
Page* page = m_frame.page();
if (page && m_frame.isMainFrame()) {
if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
- scrollingCoordinator->frameViewRootLayerDidChange(*view);
+ scrollingCoordinator->frameViewRootLayerDidChange(view);
}
- }
-
- // FIXME: It would be great to work out a way to put this code in WebCore instead of calling
- // through to the client.
- m_frame.loader().client().restoreViewState();
-#if !PLATFORM(IOS) && !PLATFORM(EFL)
- // Don't restore scroll point on iOS as FrameLoaderClient::restoreViewState() does that.
- if (view && !view->wasScrolledByUser()) {
- Page* page = m_frame.page();
- auto desiredScrollPosition = m_currentItem->scrollPosition();
-
- if (page && m_frame.isMainFrame() && m_currentItem->pageScaleFactor())
- page->setPageScaleFactor(m_currentItem->pageScaleFactor() * page->viewScaleFactor(), desiredScrollPosition);
- else
- view->setScrollPosition(desiredScrollPosition);
-
- // If the scroll position doesn't have to be clamped, consider it successfully restored.
- if (m_frame.isMainFrame()) {
- auto adjustedDesiredScrollPosition = view->adjustScrollPositionWithinRange(desiredScrollPosition);
- if (desiredScrollPosition == adjustedDesiredScrollPosition)
- m_frame.loader().client().didRestoreScrollPosition();
+ if (!view->wasScrolledByUser()) {
+ if (page && m_frame.isMainFrame() && m_currentItem->pageScaleFactor())
+ page->setPageScaleFactor(m_currentItem->pageScaleFactor(), m_currentItem->scrollPoint());
+ else
+ view->setScrollPosition(m_currentItem->scrollPoint());
}
-
}
#endif
}
@@ -180,7 +160,7 @@ void HistoryController::saveDocumentState()
{
// FIXME: Reading this bit of FrameLoader state here is unfortunate. I need to study
// this more to see if we can remove this dependency.
- if (m_frame.loader().stateMachine().creatingInitialEmptyDocument())
+ if (m_frame.loader().stateMachine()->creatingInitialEmptyDocument())
return;
// For a standard page load, we will have a previous item set, which will be used to
@@ -198,14 +178,12 @@ void HistoryController::saveDocumentState()
if (!item)
return;
- ASSERT(m_frame.document());
- Document& document = *m_frame.document();
- if (item->isCurrentDocument(document) && document.hasLivingRenderTree()) {
- if (DocumentLoader* documentLoader = document.loader())
- item->setShouldOpenExternalURLsPolicy(documentLoader->shouldOpenExternalURLsPolicyToPropagate());
-
+ Document* document = m_frame.document();
+ ASSERT(document);
+
+ if (item->isCurrentDocument(document) && document->hasLivingRenderTree()) {
LOG(Loading, "WebCoreLoading %s: saving form state to %p", m_frame.tree().uniqueName().string().utf8().data(), item);
- item->setDocumentState(document.formElementsState());
+ item->setDocumentState(document->formElementsState());
}
}
@@ -222,18 +200,18 @@ void HistoryController::saveDocumentAndScrollState()
void HistoryController::restoreDocumentState()
{
switch (m_frame.loader().loadType()) {
- case FrameLoadType::Reload:
- case FrameLoadType::ReloadFromOrigin:
- case FrameLoadType::Same:
- case FrameLoadType::Replace:
- // Not restoring the document state.
- return;
- case FrameLoadType::Back:
- case FrameLoadType::Forward:
- case FrameLoadType::IndexedBackForward:
- case FrameLoadType::RedirectWithLockedBackForwardList:
- case FrameLoadType::Standard:
- break;
+ case FrameLoadTypeReload:
+ case FrameLoadTypeReloadFromOrigin:
+ case FrameLoadTypeSame:
+ case FrameLoadTypeReplace:
+ // Not restoring the document state.
+ return;
+ case FrameLoadTypeBack:
+ case FrameLoadTypeForward:
+ case FrameLoadTypeIndexedBackForward:
+ case FrameLoadTypeRedirectWithLockedBackForwardList:
+ case FrameLoadTypeStandard:
+ break;
}
if (!m_currentItem)
@@ -243,22 +221,18 @@ void HistoryController::restoreDocumentState()
if (m_frame.loader().documentLoader()->isClientRedirect())
return;
- m_frame.loader().documentLoader()->setShouldOpenExternalURLsPolicy(m_currentItem->shouldOpenExternalURLsPolicy());
-
LOG(Loading, "WebCoreLoading %s: restoring form state from %p", m_frame.tree().uniqueName().string().utf8().data(), m_currentItem.get());
m_frame.document()->setStateForNewFormElements(m_currentItem->documentState());
}
void HistoryController::invalidateCurrentItemCachedPage()
{
- if (!currentItem())
- return;
-
// When we are pre-commit, the currentItem is where any page cache data resides.
- std::unique_ptr<CachedPage> cachedPage = PageCache::singleton().take(*currentItem(), m_frame.page());
- if (!cachedPage)
+ if (!pageCache()->get(currentItem()))
return;
+ std::unique_ptr<CachedPage> cachedPage = pageCache()->take(currentItem());
+
// FIXME: This is a grotesque hack to fix <rdar://problem/4059059> Crash in RenderFlow::detach
// Somehow the PageState object is not properly updated, and is holding onto a stale document.
// Both Xcode and FileMaker see this crash, Safari does not.
@@ -270,7 +244,7 @@ void HistoryController::invalidateCurrentItemCachedPage()
}
}
-bool HistoryController::shouldStopLoadingForHistoryItem(HistoryItem& targetItem) const
+bool HistoryController::shouldStopLoadingForHistoryItem(HistoryItem* targetItem) const
{
if (!m_currentItem)
return false;
@@ -284,7 +258,7 @@ bool HistoryController::shouldStopLoadingForHistoryItem(HistoryItem& targetItem)
// Main funnel for navigating to a previous location (back/forward, non-search snap-back)
// This includes recursion to handle loading into framesets properly
-void HistoryController::goToItem(HistoryItem& targetItem, FrameLoadType type)
+void HistoryController::goToItem(HistoryItem* targetItem, FrameLoadType type)
{
ASSERT(!m_frame.tree().parent());
@@ -295,27 +269,26 @@ void HistoryController::goToItem(HistoryItem& targetItem, FrameLoadType type)
Page* page = m_frame.page();
if (!page)
return;
- if (!m_frame.loader().client().shouldGoToHistoryItem(&targetItem))
+ if (!m_frame.loader().client().shouldGoToHistoryItem(targetItem))
return;
if (m_defersLoading) {
- m_deferredItem = &targetItem;
+ m_deferredItem = targetItem;
m_deferredFrameLoadType = type;
return;
}
// Set the BF cursor before commit, which lets the user quickly click back/forward again.
- // - plus, it only makes sense for the top level of the operation through the frame tree,
+ // - plus, it only makes sense for the top level of the operation through the frametree,
// as opposed to happening for some/one of the page commits that might happen soon
RefPtr<HistoryItem> currentItem = page->backForward().currentItem();
- page->backForward().setCurrentItem(&targetItem);
+ page->backForward().setCurrentItem(targetItem);
m_frame.loader().client().updateGlobalHistoryItemForPage();
// First set the provisional item of any frames that are not actually navigating.
// This must be done before trying to navigate the desired frame, because some
// navigations can commit immediately (such as about:blank). We must be sure that
// all frames have provisional items set before the commit.
- recursiveSetProvisionalItem(targetItem, currentItem.get());
-
+ recursiveSetProvisionalItem(targetItem, currentItem.get(), type);
// Now that all other frames have provisional items, do the actual navigation.
recursiveGoToItem(targetItem, currentItem.get(), type);
}
@@ -324,14 +297,17 @@ void HistoryController::setDefersLoading(bool defer)
{
m_defersLoading = defer;
if (!defer && m_deferredItem) {
- goToItem(*m_deferredItem, m_deferredFrameLoadType);
- m_deferredItem = nullptr;
+ goToItem(m_deferredItem.get(), m_deferredFrameLoadType);
+ m_deferredItem = 0;
}
}
void HistoryController::updateForBackForwardNavigation()
{
- LOG(History, "HistoryController %p updateForBackForwardNavigation: Updating History for back/forward navigation in frame %p (main frame %d) %s", this, &m_frame, m_frame.isMainFrame(), m_frame.loader().documentLoader() ? m_frame.loader().documentLoader()->url().string().utf8().data() : "");
+#if !LOG_DISABLED
+ if (m_frame.loader().documentLoader())
+ LOG(History, "WebCoreHistory: Updating History for back/forward navigation in frame %s", m_frame.loader().documentLoader()->title().string().utf8().data());
+#endif
// Must grab the current scroll position before disturbing it
if (!m_frameLoadComplete)
@@ -344,16 +320,16 @@ void HistoryController::updateForBackForwardNavigation()
void HistoryController::updateForReload()
{
- LOG(History, "HistoryController %p updateForBackForwardNavigation: Updating History for reload in frame %p (main frame %d) %s", this, &m_frame, m_frame.isMainFrame(), m_frame.loader().documentLoader() ? m_frame.loader().documentLoader()->url().string().utf8().data() : "");
+#if !LOG_DISABLED
+ if (m_frame.loader().documentLoader())
+ LOG(History, "WebCoreHistory: Updating History for reload in frame %s", m_frame.loader().documentLoader()->title().string().utf8().data());
+#endif
if (m_currentItem) {
- PageCache::singleton().remove(*m_currentItem);
+ pageCache()->remove(m_currentItem.get());
- if (m_frame.loader().loadType() == FrameLoadType::Reload || m_frame.loader().loadType() == FrameLoadType::ReloadFromOrigin)
+ if (m_frame.loader().loadType() == FrameLoadTypeReload || m_frame.loader().loadType() == FrameLoadTypeReloadFromOrigin)
saveScrollPositionAndViewStateToItem(m_currentItem.get());
-
- // Rebuild the history item tree when reloading as trying to re-associate everything is too error-prone.
- m_currentItem->clearChildren();
}
// When reloading the page, we may end up redirecting to a different URL
@@ -369,11 +345,11 @@ void HistoryController::updateForReload()
void HistoryController::updateForStandardLoad(HistoryUpdateType updateType)
{
- LOG(History, "HistoryController %p updateForStandardLoad: Updating History for standard load in frame %p (main frame %d) %s", this, &m_frame, m_frame.isMainFrame(), m_frame.loader().documentLoader()->url().string().ascii().data());
+ LOG(History, "WebCoreHistory: Updating History for Standard Load in frame %s", m_frame.loader().documentLoader()->url().string().ascii().data());
FrameLoader& frameLoader = m_frame.loader();
- bool needPrivacy = m_frame.page()->usesEphemeralSession();
+ bool needPrivacy = m_frame.settings().privateBrowsingEnabled();
const URL& historyURL = frameLoader.documentLoader()->urlForHistory();
if (!frameLoader.documentLoader()->isClientRedirect()) {
@@ -396,7 +372,7 @@ void HistoryController::updateForStandardLoad(HistoryUpdateType updateType)
if (!historyURL.isEmpty() && !needPrivacy) {
if (Page* page = m_frame.page())
- addVisitedLink(*page, historyURL);
+ addVisitedLink(page, historyURL);
if (!frameLoader.documentLoader()->didCreateGlobalHistoryEntry() && frameLoader.documentLoader()->unreachableURL().isEmpty() && !m_frame.document()->url().isEmpty())
frameLoader.client().updateGlobalHistoryRedirectLinks();
@@ -405,9 +381,12 @@ void HistoryController::updateForStandardLoad(HistoryUpdateType updateType)
void HistoryController::updateForRedirectWithLockedBackForwardList()
{
- LOG(History, "HistoryController %p updateForRedirectWithLockedBackForwardList: Updating History for redirect load in frame %p (main frame %d) %s", this, &m_frame, m_frame.isMainFrame(), m_frame.loader().documentLoader() ? m_frame.loader().documentLoader()->url().string().utf8().data() : "");
+#if !LOG_DISABLED
+ if (m_frame.loader().documentLoader())
+ LOG(History, "WebCoreHistory: Updating History for redirect load in frame %s", m_frame.loader().documentLoader()->title().string().utf8().data());
+#endif
- bool needPrivacy = m_frame.page()->usesEphemeralSession();
+ bool needPrivacy = m_frame.settings().privateBrowsingEnabled();
const URL& historyURL = m_frame.loader().documentLoader()->urlForHistory();
if (m_frame.loader().documentLoader()->isClientRedirect()) {
@@ -434,7 +413,7 @@ void HistoryController::updateForRedirectWithLockedBackForwardList()
if (!historyURL.isEmpty() && !needPrivacy) {
if (Page* page = m_frame.page())
- addVisitedLink(*page, historyURL);
+ addVisitedLink(page, historyURL);
if (!m_frame.loader().documentLoader()->didCreateGlobalHistoryEntry() && m_frame.loader().documentLoader()->unreachableURL().isEmpty() && !m_frame.document()->url().isEmpty())
m_frame.loader().client().updateGlobalHistoryRedirectLinks();
@@ -443,29 +422,34 @@ void HistoryController::updateForRedirectWithLockedBackForwardList()
void HistoryController::updateForClientRedirect()
{
- LOG(History, "HistoryController %p updateForClientRedirect: Updating History for client redirect in frame %p (main frame %d) %s", this, &m_frame, m_frame.isMainFrame(), m_frame.loader().documentLoader() ? m_frame.loader().documentLoader()->url().string().utf8().data() : "");
+#if !LOG_DISABLED
+ if (m_frame.loader().documentLoader())
+ LOG(History, "WebCoreHistory: Updating History for client redirect in frame %s", m_frame.loader().documentLoader()->title().string().utf8().data());
+#endif
// Clear out form data so we don't try to restore it into the incoming page. Must happen after
// webcore has closed the URL and saved away the form state.
if (m_currentItem) {
m_currentItem->clearDocumentState();
- m_currentItem->clearScrollPosition();
+ m_currentItem->clearScrollPoint();
}
- bool needPrivacy = m_frame.page()->usesEphemeralSession();
+ bool needPrivacy = m_frame.settings().privateBrowsingEnabled();
const URL& historyURL = m_frame.loader().documentLoader()->urlForHistory();
if (!historyURL.isEmpty() && !needPrivacy) {
if (Page* page = m_frame.page())
- addVisitedLink(*page, historyURL);
+ addVisitedLink(page, historyURL);
}
}
void HistoryController::updateForCommit()
{
FrameLoader& frameLoader = m_frame.loader();
- LOG(History, "HistoryController %p updateForCommit: Updating History for commit in frame %p (main frame %d) %s", this, &m_frame, m_frame.isMainFrame(), m_frame.loader().documentLoader() ? m_frame.loader().documentLoader()->url().string().utf8().data() : "");
-
+#if !LOG_DISABLED
+ if (frameLoader.documentLoader())
+ LOG(History, "WebCoreHistory: Updating History for commit in frame %s", frameLoader.documentLoader()->title().string().utf8().data());
+#endif
FrameLoadType type = frameLoader.loadType();
if (isBackForwardLoadType(type)
|| isReplaceLoadTypeWithProvisionalItem(type)
@@ -474,14 +458,11 @@ void HistoryController::updateForCommit()
// the provisional item for restoring state.
// Note previousItem must be set before we close the URL, which will
// happen when the data source is made non-provisional below
-
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=146842
- // We should always have a provisional item when committing, but we sometimes don't.
- // Not having one leads to us not having a m_currentItem later, which is also a terrible known issue.
- // We should get to the bottom of this.
+ m_frameLoadComplete = false;
+ m_previousItem = m_currentItem;
ASSERT(m_provisionalItem);
- setCurrentItem(m_provisionalItem.get());
- m_provisionalItem = nullptr;
+ m_currentItem = m_provisionalItem;
+ m_provisionalItem = 0;
// Tell all other frames in the tree to commit their provisional items and
// restore their scroll position. We'll avoid this frame (which has already
@@ -492,14 +473,14 @@ void HistoryController::updateForCommit()
bool HistoryController::isReplaceLoadTypeWithProvisionalItem(FrameLoadType type)
{
- // Going back to an error page in a subframe can trigger a FrameLoadType::Replace
+ // Going back to an error page in a subframe can trigger a FrameLoadTypeReplace
// while m_provisionalItem is set, so we need to commit it.
- return type == FrameLoadType::Replace && m_provisionalItem;
+ return type == FrameLoadTypeReplace && m_provisionalItem;
}
bool HistoryController::isReloadTypeWithProvisionalItem(FrameLoadType type)
{
- return (type == FrameLoadType::Reload || type == FrameLoadType::ReloadFromOrigin) && m_provisionalItem;
+ return (type == FrameLoadTypeReload || type == FrameLoadTypeReloadFromOrigin) && m_provisionalItem;
}
void HistoryController::recursiveUpdateForCommit()
@@ -512,7 +493,7 @@ void HistoryController::recursiveUpdateForCommit()
// For each frame that already had the content the item requested (based on
// (a matching URL and frame tree snapshot), just restore the scroll position.
// Save form state (works from currentItem, since m_frameLoadComplete is true)
- if (m_currentItem && itemsAreClones(*m_currentItem, m_provisionalItem.get())) {
+ if (m_currentItem && itemsAreClones(m_currentItem.get(), m_provisionalItem.get())) {
ASSERT(m_frameLoadComplete);
saveDocumentState();
saveScrollPositionAndViewStateToItem(m_currentItem.get());
@@ -521,8 +502,10 @@ void HistoryController::recursiveUpdateForCommit()
view->setWasScrolledByUser(false);
// Now commit the provisional item
- setCurrentItem(m_provisionalItem.get());
- m_provisionalItem = nullptr;
+ m_frameLoadComplete = false;
+ m_previousItem = m_currentItem;
+ m_currentItem = m_provisionalItem;
+ m_provisionalItem = 0;
// Restore form state (works from currentItem)
restoreDocumentState();
@@ -541,14 +524,14 @@ void HistoryController::updateForSameDocumentNavigation()
if (m_frame.document()->url().isEmpty())
return;
- if (m_frame.page()->usesEphemeralSession())
+ if (m_frame.settings().privateBrowsingEnabled())
return;
Page* page = m_frame.page();
if (!page)
return;
- addVisitedLink(*page, m_frame.document()->url());
+ addVisitedLink(page, m_frame.document()->url());
m_frame.mainFrame().loader().history().recursiveUpdateForSameDocumentNavigation();
if (m_currentItem) {
@@ -566,12 +549,14 @@ void HistoryController::recursiveUpdateForSameDocumentNavigation()
// The provisional item may represent a different pending navigation.
// Don't commit it if it isn't a same document navigation.
- if (m_currentItem && !m_currentItem->shouldDoSameDocumentNavigationTo(*m_provisionalItem))
+ if (m_currentItem && !m_currentItem->shouldDoSameDocumentNavigationTo(m_provisionalItem.get()))
return;
// Commit the provisional item.
- setCurrentItem(m_provisionalItem.get());
- m_provisionalItem = nullptr;
+ m_frameLoadComplete = false;
+ m_previousItem = m_currentItem;
+ m_currentItem = m_provisionalItem;
+ m_provisionalItem = 0;
// Iterate over the rest of the tree.
for (Frame* child = m_frame.tree().firstChild(); child; child = child->tree().nextSibling())
@@ -606,14 +591,7 @@ bool HistoryController::currentItemShouldBeReplaced() const
// "If the browsing context's session history contains only one Document,
// and that was the about:blank Document created when the browsing context
// was created, then the navigation must be done with replacement enabled."
- return m_currentItem && !m_previousItem && equalIgnoringASCIICase(m_currentItem->urlString(), blankURL());
-}
-
-void HistoryController::clearPreviousItem()
-{
- m_previousItem = nullptr;
- for (Frame* child = m_frame.tree().firstChild(); child; child = child->tree().nextSibling())
- child->loader().history().clearPreviousItem();
+ return m_currentItem && !m_previousItem && equalIgnoringCase(m_currentItem->urlString(), blankURL());
}
void HistoryController::setProvisionalItem(HistoryItem* item)
@@ -621,7 +599,7 @@ void HistoryController::setProvisionalItem(HistoryItem* item)
m_provisionalItem = item;
}
-void HistoryController::initializeItem(HistoryItem& item)
+void HistoryController::initializeItem(HistoryItem* item)
{
DocumentLoader* documentLoader = m_frame.loader().documentLoader();
ASSERT(documentLoader);
@@ -649,37 +627,40 @@ void HistoryController::initializeItem(HistoryItem& item)
if (originalURL.isEmpty())
originalURL = blankURL();
+ Frame* parentFrame = m_frame.tree().parent();
+ String parent = parentFrame ? parentFrame->tree().uniqueName() : "";
StringWithDirection title = documentLoader->title();
- item.setURL(url);
- item.setTarget(m_frame.tree().uniqueName());
+ item->setURL(url);
+ item->setTarget(m_frame.tree().uniqueName());
+ item->setParent(parent);
// FIXME: should store title directionality in history as well.
- item.setTitle(title.string());
- item.setOriginalURLString(originalURL.string());
+ item->setTitle(title.string());
+ item->setOriginalURLString(originalURL.string());
if (!unreachableURL.isEmpty() || documentLoader->response().httpStatusCode() >= 400)
- item.setLastVisitWasFailure(true);
-
- item.setShouldOpenExternalURLsPolicy(documentLoader->shouldOpenExternalURLsPolicyToPropagate());
+ item->setLastVisitWasFailure(true);
// Save form state if this is a POST
- item.setFormInfoFromRequest(documentLoader->request());
+ item->setFormInfoFromRequest(documentLoader->request());
}
-Ref<HistoryItem> HistoryController::createItem()
+PassRefPtr<HistoryItem> HistoryController::createItem()
{
- Ref<HistoryItem> item = HistoryItem::create();
- initializeItem(item);
+ RefPtr<HistoryItem> item = HistoryItem::create();
+ initializeItem(item.get());
// Set the item for which we will save document state
- setCurrentItem(item.ptr());
+ m_frameLoadComplete = false;
+ m_previousItem = m_currentItem;
+ m_currentItem = item;
- return item;
+ return item.release();
}
-Ref<HistoryItem> HistoryController::createItemTree(Frame& targetFrame, bool clipAtTarget)
+PassRefPtr<HistoryItem> HistoryController::createItemTree(Frame& targetFrame, bool clipAtTarget)
{
- Ref<HistoryItem> bfItem = createItem();
+ RefPtr<HistoryItem> bfItem = createItem();
if (!m_frameLoadComplete)
saveScrollPositionAndViewStateToItem(m_previousItem.get());
@@ -719,47 +700,54 @@ Ref<HistoryItem> HistoryController::createItemTree(Frame& targetFrame, bool clip
// tracking whether each frame already has the content the item requests. If there is
// a match, we set the provisional item and recurse. Otherwise we will reload that
// frame and all its kids in recursiveGoToItem.
-void HistoryController::recursiveSetProvisionalItem(HistoryItem& item, HistoryItem* fromItem)
+void HistoryController::recursiveSetProvisionalItem(HistoryItem* item, HistoryItem* fromItem, FrameLoadType type)
{
- if (!itemsAreClones(item, fromItem))
- return;
+ ASSERT(item);
- // Set provisional item, which will be committed in recursiveUpdateForCommit.
- m_provisionalItem = &item;
+ if (itemsAreClones(item, fromItem)) {
+ // Set provisional item, which will be committed in recursiveUpdateForCommit.
+ m_provisionalItem = item;
- for (auto& childItem : item.children()) {
- const String& childFrameName = childItem->target();
+ const HistoryItemVector& childItems = item->children();
- HistoryItem* fromChildItem = fromItem->childItemWithTarget(childFrameName);
- ASSERT(fromChildItem);
- Frame* childFrame = m_frame.tree().child(childFrameName);
- ASSERT(childFrame);
+ int size = childItems.size();
- childFrame->loader().history().recursiveSetProvisionalItem(const_cast<HistoryItem&>(childItem.get()), fromChildItem);
+ for (int i = 0; i < size; ++i) {
+ String childFrameName = childItems[i]->target();
+ HistoryItem* fromChildItem = fromItem->childItemWithTarget(childFrameName);
+ ASSERT(fromChildItem);
+ Frame* childFrame = m_frame.tree().child(childFrameName);
+ ASSERT(childFrame);
+ childFrame->loader().history().recursiveSetProvisionalItem(childItems[i].get(), fromChildItem, type);
+ }
}
}
// We now traverse the frame tree and item tree a second time, loading frames that
// do have the content the item requests.
-void HistoryController::recursiveGoToItem(HistoryItem& item, HistoryItem* fromItem, FrameLoadType type)
-{
- if (!itemsAreClones(item, fromItem)) {
+void HistoryController::recursiveGoToItem(HistoryItem* item, HistoryItem* fromItem, FrameLoadType type)
+{
+ ASSERT(item);
+
+ if (itemsAreClones(item, fromItem)) {
+ // Just iterate over the rest, looking for frames to navigate.
+ const HistoryItemVector& childItems = item->children();
+
+ int size = childItems.size();
+ for (int i = 0; i < size; ++i) {
+ String childFrameName = childItems[i]->target();
+ HistoryItem* fromChildItem = fromItem->childItemWithTarget(childFrameName);
+ ASSERT(fromChildItem);
+ Frame* childFrame = m_frame.tree().child(childFrameName);
+ ASSERT(childFrame);
+ childFrame->loader().history().recursiveGoToItem(childItems[i].get(), fromChildItem, type);
+ }
+ } else {
m_frame.loader().loadItem(item, type);
- return;
- }
-
- // Just iterate over the rest, looking for frames to navigate.
- for (auto& childItem : item.children()) {
- const String& childFrameName = childItem->target();
-
- HistoryItem* fromChildItem = fromItem->childItemWithTarget(childFrameName);
- ASSERT(fromChildItem);
- if (Frame* childFrame = m_frame.tree().child(childFrameName))
- childFrame->loader().history().recursiveGoToItem(const_cast<HistoryItem&>(childItem.get()), fromChildItem, type);
}
}
-bool HistoryController::itemsAreClones(HistoryItem& item1, HistoryItem* item2) const
+bool HistoryController::itemsAreClones(HistoryItem* item1, HistoryItem* item2) const
{
// If the item we're going to is a clone of the item we're at, then we do
// not need to load it again. The current frame tree and the frame tree
@@ -768,10 +756,11 @@ bool HistoryController::itemsAreClones(HistoryItem& item1, HistoryItem* item2) c
// a reload. Thus, if item1 and item2 are the same, we need to create a
// new document and should not consider them clones.
// (See http://webkit.org/b/35532 for details.)
- return item2
- && &item1 != item2
- && item1.itemSequenceNumber() == item2->itemSequenceNumber()
- && currentFramesMatchItem(&item1)
+ return item1
+ && item2
+ && item1 != item2
+ && item1->itemSequenceNumber() == item2->itemSequenceNumber()
+ && currentFramesMatchItem(item1)
&& item2->hasSameFrames(item1);
}
@@ -785,8 +774,9 @@ bool HistoryController::currentFramesMatchItem(HistoryItem* item) const
if (childItems.size() != m_frame.tree().childCount())
return false;
- for (auto& item : childItems) {
- if (!m_frame.tree().child(item->target()))
+ unsigned size = childItems.size();
+ for (unsigned i = 0; i < size; ++i) {
+ if (!m_frame.tree().child(childItems[i]->target()))
return false;
}
@@ -809,10 +799,9 @@ void HistoryController::updateBackForwardListClippedAtTarget(bool doClip)
FrameLoader& frameLoader = m_frame.mainFrame().loader();
- Ref<HistoryItem> topItem = frameLoader.history().createItemTree(m_frame, doClip);
- LOG(History, "HistoryController %p updateBackForwardListClippedAtTarget: Adding backforward item %p in frame %p (main frame %d) %s", this, topItem.ptr(), &m_frame, m_frame.isMainFrame(), m_frame.loader().documentLoader()->url().string().utf8().data());
-
- page->backForward().addItem(WTFMove(topItem));
+ RefPtr<HistoryItem> topItem = frameLoader.history().createItemTree(m_frame, doClip);
+ LOG(BackForward, "WebCoreBackForward - Adding backforward item %p for frame %s", topItem.get(), m_frame.loader().documentLoader()->url().string().ascii().data());
+ page->backForward().addItem(topItem.release());
}
void HistoryController::updateCurrentItem()
@@ -832,7 +821,7 @@ void HistoryController::updateCurrentItem()
// dependent on the document.
bool isTargetItem = m_currentItem->isTargetItem();
m_currentItem->reset();
- initializeItem(*m_currentItem);
+ initializeItem(m_currentItem.get());
m_currentItem->setIsTargetItem(isTargetItem);
} else {
// Even if the final URL didn't change, the form data may have changed.
@@ -849,7 +838,7 @@ void HistoryController::pushState(PassRefPtr<SerializedScriptValue> stateObject,
ASSERT(page);
// Get a HistoryItem tree for the current frame tree.
- Ref<HistoryItem> topItem = m_frame.mainFrame().loader().history().createItemTree(m_frame, false);
+ RefPtr<HistoryItem> topItem = m_frame.mainFrame().loader().history().createItemTree(m_frame, false);
// Override data in the current item (created by createItemTree) to reflect
// the pushState() arguments.
@@ -857,14 +846,12 @@ void HistoryController::pushState(PassRefPtr<SerializedScriptValue> stateObject,
m_currentItem->setStateObject(stateObject);
m_currentItem->setURLString(urlString);
- LOG(History, "HistoryController %p pushState: Adding top item %p, setting url of current item %p to %s", this, topItem.ptr(), m_currentItem.get(), urlString.ascii().data());
-
- page->backForward().addItem(WTFMove(topItem));
+ page->backForward().addItem(topItem.release());
- if (m_frame.page()->usesEphemeralSession())
+ if (m_frame.settings().privateBrowsingEnabled())
return;
- addVisitedLink(*page, URL(ParsedURLString, urlString));
+ addVisitedLink(page, URL(ParsedURLString, urlString));
m_frame.loader().client().updateGlobalHistory();
}
@@ -873,20 +860,18 @@ void HistoryController::replaceState(PassRefPtr<SerializedScriptValue> stateObje
if (!m_currentItem)
return;
- LOG(History, "HistoryController %p replaceState: Setting url of current item %p to %s", this, m_currentItem.get(), urlString.ascii().data());
-
if (!urlString.isEmpty())
m_currentItem->setURLString(urlString);
m_currentItem->setTitle(title);
m_currentItem->setStateObject(stateObject);
- m_currentItem->setFormData(nullptr);
+ m_currentItem->setFormData(0);
m_currentItem->setFormContentType(String());
- if (m_frame.page()->usesEphemeralSession())
+ if (m_frame.settings().privateBrowsingEnabled())
return;
ASSERT(m_frame.page());
- addVisitedLink(*m_frame.page(), URL(ParsedURLString, urlString));
+ addVisitedLink(m_frame.page(), URL(ParsedURLString, urlString));
m_frame.loader().client().updateGlobalHistory();
}