| Index: content/renderer/history_controller.cc
|
| diff --git a/content/renderer/history_controller.cc b/content/renderer/history_controller.cc
|
| deleted file mode 100644
|
| index 6369f09354e7ad7c2191745b3c781ff8f074e9cb..0000000000000000000000000000000000000000
|
| --- a/content/renderer/history_controller.cc
|
| +++ /dev/null
|
| @@ -1,335 +0,0 @@
|
| -// Copyright 2014 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -/*
|
| - * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
|
| - * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
|
| - * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved.
|
| - * (http://www.torchmobile.com/)
|
| - *
|
| - * Redistribution and use in source and binary forms, with or without
|
| - * modification, are permitted provided that the following conditions
|
| - * are met:
|
| - *
|
| - * 1. Redistributions of source code must retain the above copyright
|
| - * notice, this list of conditions and the following disclaimer.
|
| - * 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 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.
|
| - *
|
| - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
|
| - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
| - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
| - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
|
| - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
| - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
| - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
| - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
| - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| - */
|
| -
|
| -#include "content/renderer/history_controller.h"
|
| -
|
| -#include <utility>
|
| -
|
| -#include "base/memory/ptr_util.h"
|
| -#include "content/common/navigation_params.h"
|
| -#include "content/common/site_isolation_policy.h"
|
| -#include "content/renderer/render_frame_impl.h"
|
| -#include "content/renderer/render_view_impl.h"
|
| -#include "third_party/WebKit/public/web/WebFrameLoadType.h"
|
| -#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
| -
|
| -using blink::WebCachePolicy;
|
| -using blink::WebFrame;
|
| -using blink::WebHistoryCommitType;
|
| -using blink::WebHistoryItem;
|
| -using blink::WebURLRequest;
|
| -
|
| -namespace content {
|
| -
|
| -HistoryController::HistoryController(RenderViewImpl* render_view)
|
| - : render_view_(render_view) {
|
| - // We don't use HistoryController in OOPIF enabled modes.
|
| - DCHECK(!SiteIsolationPolicy::UseSubframeNavigationEntries());
|
| -}
|
| -
|
| -HistoryController::~HistoryController() {
|
| -}
|
| -
|
| -bool HistoryController::GoToEntry(
|
| - blink::WebLocalFrame* main_frame,
|
| - std::unique_ptr<HistoryEntry> target_entry,
|
| - std::unique_ptr<NavigationParams> navigation_params,
|
| - WebCachePolicy cache_policy) {
|
| - DCHECK(!main_frame->parent());
|
| - HistoryFrameLoadVector same_document_loads;
|
| - HistoryFrameLoadVector different_document_loads;
|
| -
|
| - set_provisional_entry(std::move(target_entry));
|
| - navigation_params_ = std::move(navigation_params);
|
| -
|
| - if (current_entry_) {
|
| - RecursiveGoToEntry(
|
| - main_frame, same_document_loads, different_document_loads);
|
| - }
|
| -
|
| - if (same_document_loads.empty() && different_document_loads.empty()) {
|
| - // If we don't have any frames to navigate at this point, either
|
| - // (1) there is no previous history entry to compare against, or
|
| - // (2) we were unable to match any frames by name. In the first case,
|
| - // doing a different document navigation to the root item is the only valid
|
| - // thing to do. In the second case, we should have been able to find a
|
| - // frame to navigate based on names if this were a same document
|
| - // navigation, so we can safely assume this is the different document case.
|
| - different_document_loads.push_back(
|
| - std::make_pair(main_frame, provisional_entry_->root()));
|
| - }
|
| -
|
| - bool has_main_frame_request = false;
|
| - for (const auto& item : same_document_loads) {
|
| - WebFrame* frame = item.first;
|
| - RenderFrameImpl* render_frame = RenderFrameImpl::FromWebFrame(frame);
|
| - if (!render_frame)
|
| - continue;
|
| - render_frame->SetPendingNavigationParams(
|
| - base::MakeUnique<NavigationParams>(*navigation_params_.get()));
|
| - WebURLRequest request = frame->toWebLocalFrame()->requestFromHistoryItem(
|
| - item.second, cache_policy);
|
| - frame->toWebLocalFrame()->load(
|
| - request, blink::WebFrameLoadType::BackForward, item.second,
|
| - blink::WebHistorySameDocumentLoad);
|
| - if (frame == main_frame)
|
| - has_main_frame_request = true;
|
| - }
|
| - for (const auto& item : different_document_loads) {
|
| - WebFrame* frame = item.first;
|
| - RenderFrameImpl* render_frame = RenderFrameImpl::FromWebFrame(frame);
|
| - if (!render_frame)
|
| - continue;
|
| - render_frame->SetPendingNavigationParams(
|
| - base::MakeUnique<NavigationParams>(*navigation_params_.get()));
|
| - WebURLRequest request = frame->toWebLocalFrame()->requestFromHistoryItem(
|
| - item.second, cache_policy);
|
| - frame->toWebLocalFrame()->load(
|
| - request, blink::WebFrameLoadType::BackForward, item.second,
|
| - blink::WebHistoryDifferentDocumentLoad);
|
| - if (frame == main_frame)
|
| - has_main_frame_request = true;
|
| - }
|
| -
|
| - return has_main_frame_request;
|
| -}
|
| -
|
| -void HistoryController::RecursiveGoToEntry(
|
| - WebFrame* frame,
|
| - HistoryFrameLoadVector& same_document_loads,
|
| - HistoryFrameLoadVector& different_document_loads) {
|
| - DCHECK(provisional_entry_);
|
| - DCHECK(current_entry_);
|
| - RenderFrameImpl* render_frame = RenderFrameImpl::FromWebFrame(frame);
|
| - const WebHistoryItem& new_item =
|
| - provisional_entry_->GetItemForFrame(render_frame);
|
| -
|
| - // Use the last committed history item for the frame rather than
|
| - // current_entry_, since the latter may not accurately reflect which URL is
|
| - // currently committed in the frame. See https://crbug.com/612713#c12.
|
| - const WebHistoryItem& old_item = render_frame->current_history_item();
|
| -
|
| - if (new_item.isNull())
|
| - return;
|
| -
|
| - if (old_item.isNull() ||
|
| - new_item.itemSequenceNumber() != old_item.itemSequenceNumber()) {
|
| - if (!old_item.isNull() &&
|
| - new_item.documentSequenceNumber() ==
|
| - old_item.documentSequenceNumber()) {
|
| - same_document_loads.push_back(std::make_pair(frame, new_item));
|
| -
|
| - // Returning here (and omitting child frames which have also changed) is
|
| - // wrong, but not returning here is worse. See the discussion in
|
| - // NavigationControllerImpl::FindFramesToNavigate for more information.
|
| - return;
|
| - } else {
|
| - different_document_loads.push_back(std::make_pair(frame, new_item));
|
| - // For a different document, the subframes will be destroyed, so there's
|
| - // no need to consider them.
|
| - return;
|
| - }
|
| - }
|
| -
|
| - for (WebFrame* child = frame->firstChild(); child;
|
| - child = child->nextSibling()) {
|
| - RecursiveGoToEntry(child, same_document_loads, different_document_loads);
|
| - }
|
| -}
|
| -
|
| -void HistoryController::UpdateForInitialLoadInChildFrame(
|
| - RenderFrameImpl* frame,
|
| - const WebHistoryItem& item) {
|
| - DCHECK_NE(frame->GetWebFrame()->top(), frame->GetWebFrame());
|
| - if (!current_entry_)
|
| - return;
|
| - if (HistoryEntry::HistoryNode* existing_node =
|
| - current_entry_->GetHistoryNodeForFrame(frame)) {
|
| - // Clear the children and any NavigationParams if this commit isn't for
|
| - // the same item. Otherwise we might have stale data after a redirect.
|
| - if (existing_node->item().itemSequenceNumber() !=
|
| - item.itemSequenceNumber()) {
|
| - existing_node->RemoveChildren();
|
| - navigation_params_.reset();
|
| - }
|
| - existing_node->set_item(item);
|
| - return;
|
| - }
|
| - RenderFrameImpl* parent =
|
| - RenderFrameImpl::FromWebFrame(frame->GetWebFrame()->parent());
|
| - if (!parent)
|
| - return;
|
| - if (HistoryEntry::HistoryNode* parent_history_node =
|
| - current_entry_->GetHistoryNodeForFrame(parent)) {
|
| - parent_history_node->AddChild(item);
|
| - }
|
| -}
|
| -
|
| -void HistoryController::UpdateForCommit(RenderFrameImpl* frame,
|
| - const WebHistoryItem& item,
|
| - WebHistoryCommitType commit_type,
|
| - bool navigation_within_page) {
|
| - switch (commit_type) {
|
| - case blink::WebBackForwardCommit:
|
| - if (!provisional_entry_) {
|
| - // The provisional entry may have been discarded due to a navigation in
|
| - // a different frame. For main frames, it is not safe to leave the
|
| - // current_entry_ in place, which may have a cross-site page and will be
|
| - // included in the PageState for this commit. Replace it with a new
|
| - // HistoryEntry corresponding to the commit, and clear any stale
|
| - // NavigationParams which might point to the wrong entry.
|
| - //
|
| - // This will lack any subframe history items that were in the original
|
| - // provisional entry, but we don't know what those were after discarding
|
| - // it. We'll load the default URL in those subframes instead.
|
| - //
|
| - // TODO(creis): It's also possible to get here for subframe commits.
|
| - // We'll leave a stale current_entry_ in that case, but that only causes
|
| - // an earlier URL to load in the subframe when leaving and coming back,
|
| - // and only in rare cases. It does not risk a URL spoof, unlike the
|
| - // main frame case. Since this bug is not present in the new
|
| - // FrameNavigationEntry-based navigation path (https://crbug.com/236848)
|
| - // we'll wait for that to fix the subframe case.
|
| - if (frame->IsMainFrame()) {
|
| - current_entry_.reset(new HistoryEntry(item));
|
| - navigation_params_.reset();
|
| - }
|
| -
|
| - return;
|
| - }
|
| -
|
| - // If the current entry is null, this must be a main frame commit.
|
| - DCHECK(current_entry_ || frame->IsMainFrame());
|
| -
|
| - // Commit the provisional entry, but only if it is a plausible transition.
|
| - // Do not commit it if the navigation is in a subframe and the provisional
|
| - // entry's main frame item does not match the current entry's main frame,
|
| - // which can happen if multiple forward navigations occur. In that case,
|
| - // committing the provisional entry would corrupt it, leading to a URL
|
| - // spoof. See https://crbug.com/597322. (Note that the race in this bug
|
| - // does not affect main frame navigations, only navigations in subframes.)
|
| - //
|
| - // Note that we cannot compare the provisional entry against |item|, since
|
| - // |item| may have redirected to a different URL and ISN. We also cannot
|
| - // compare against the main frame's URL, since that may have changed due
|
| - // to a replaceState. (Even origin can change on replaceState in certain
|
| - // modes.)
|
| - //
|
| - // It would be safe to additionally check the ISNs of all parent frames
|
| - // (and not just the root), but that is less critical because it won't
|
| - // lead to a URL spoof.
|
| - if (frame->IsMainFrame() ||
|
| - current_entry_->root().itemSequenceNumber() ==
|
| - provisional_entry_->root().itemSequenceNumber()) {
|
| - current_entry_ = std::move(provisional_entry_);
|
| - }
|
| -
|
| - // We're guaranteed to have a current entry now.
|
| - DCHECK(current_entry_);
|
| -
|
| - if (HistoryEntry::HistoryNode* node =
|
| - current_entry_->GetHistoryNodeForFrame(frame)) {
|
| - // Clear the children and any NavigationParams if this commit isn't for
|
| - // the same item. Otherwise we might have stale data from a race.
|
| - if (node->item().itemSequenceNumber() != item.itemSequenceNumber()) {
|
| - node->RemoveChildren();
|
| - navigation_params_.reset();
|
| - }
|
| -
|
| - node->set_item(item);
|
| - }
|
| - break;
|
| - case blink::WebStandardCommit:
|
| - CreateNewBackForwardItem(frame, item, navigation_within_page);
|
| - break;
|
| - case blink::WebInitialCommitInChildFrame:
|
| - UpdateForInitialLoadInChildFrame(frame, item);
|
| - break;
|
| - case blink::WebHistoryInertCommit:
|
| - // Even for inert commits (e.g., location.replace, client redirects), make
|
| - // sure the current entry gets updated, if there is one.
|
| - if (current_entry_) {
|
| - if (HistoryEntry::HistoryNode* node =
|
| - current_entry_->GetHistoryNodeForFrame(frame)) {
|
| - // Inert commits that reset the page without changing the item (e.g.,
|
| - // reloads, location.replace) shouldn't keep the old subtree.
|
| - if (!navigation_within_page)
|
| - node->RemoveChildren();
|
| - node->set_item(item);
|
| - }
|
| - }
|
| - break;
|
| - default:
|
| - NOTREACHED() << "Invalid commit type: " << commit_type;
|
| - }
|
| -}
|
| -
|
| -HistoryEntry* HistoryController::GetCurrentEntry() {
|
| - return current_entry_.get();
|
| -}
|
| -
|
| -WebHistoryItem HistoryController::GetItemForNewChildFrame(
|
| - RenderFrameImpl* frame) const {
|
| - if (navigation_params_.get()) {
|
| - frame->SetPendingNavigationParams(
|
| - base::MakeUnique<NavigationParams>(*navigation_params_.get()));
|
| - }
|
| -
|
| - if (!current_entry_)
|
| - return WebHistoryItem();
|
| - return current_entry_->GetItemForFrame(frame);
|
| -}
|
| -
|
| -void HistoryController::RemoveChildrenForRedirect(RenderFrameImpl* frame) {
|
| - if (!provisional_entry_)
|
| - return;
|
| - if (HistoryEntry::HistoryNode* node =
|
| - provisional_entry_->GetHistoryNodeForFrame(frame))
|
| - node->RemoveChildren();
|
| -}
|
| -
|
| -void HistoryController::CreateNewBackForwardItem(
|
| - RenderFrameImpl* target_frame,
|
| - const WebHistoryItem& new_item,
|
| - bool clone_children_of_target) {
|
| - if (!current_entry_) {
|
| - current_entry_.reset(new HistoryEntry(new_item));
|
| - } else {
|
| - current_entry_.reset(current_entry_->CloneAndReplace(
|
| - new_item, clone_children_of_target, target_frame, render_view_));
|
| - }
|
| -}
|
| -
|
| -} // namespace content
|
|
|