Add 'did_proceed' and 'repeat_visit' to ClientMalwareReportRequest to track CTR.
[chromium-blink-merge.git] / components / web_view / navigation_controller.cc
blobb9ffdb9ed29664fdca077d64f6d85ff36317288a
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/web_view/navigation_controller.h"
7 #include "components/web_view/frame.h"
8 #include "components/web_view/navigation_controller_delegate.h"
9 #include "components/web_view/navigation_entry.h"
10 #include "components/web_view/reload_type.h"
12 namespace web_view {
14 NavigationController::NavigationController(
15 NavigationControllerDelegate* delegate)
16 : pending_entry_(nullptr),
17 last_committed_entry_index_(-1),
18 pending_entry_index_(-1),
19 delegate_(delegate) {}
21 NavigationController::~NavigationController() {
22 DiscardPendingEntry(false);
25 int NavigationController::GetCurrentEntryIndex() const {
26 if (pending_entry_index_ != -1)
27 return pending_entry_index_;
28 return last_committed_entry_index_;
31 int NavigationController::GetIndexForOffset(int offset) const {
32 return GetCurrentEntryIndex() + offset;
35 int NavigationController::GetEntryCount() const {
36 // TODO(erg): Have a max number of entries, and DCHECK that we are smaller
37 // than it here.
38 return static_cast<int>(entries_.size());
41 NavigationEntry* NavigationController::GetEntryAtIndex(int index) const {
42 if (index < 0 || index >= GetEntryCount())
43 return nullptr;
45 return entries_[index];
48 NavigationEntry* NavigationController::GetEntryAtOffset(int offset) const {
49 return GetEntryAtIndex(GetIndexForOffset(offset));
52 bool NavigationController::CanGoBack() const {
53 return CanGoToOffset(-1);
56 bool NavigationController::CanGoForward() const {
57 return CanGoToOffset(1);
60 bool NavigationController::CanGoToOffset(int offset) const {
61 int index = GetIndexForOffset(offset);
62 return index >= 0 && index < GetEntryCount();
65 void NavigationController::GoBack() {
66 if (!CanGoBack()) {
67 NOTREACHED();
68 return;
71 // Base the navigation on where we are now...
72 int current_index = GetCurrentEntryIndex();
74 DiscardPendingEntry(false);
76 pending_entry_index_ = current_index - 1;
77 // TODO(erg): Transition type handled here.
78 NavigateToPendingEntry(ReloadType::NO_RELOAD);
81 void NavigationController::GoForward() {
82 if (!CanGoForward()) {
83 NOTREACHED();
84 return;
87 // TODO(erg): The upstream version handles transience here.
89 // Base the navigation on where we are now...
90 int current_index = GetCurrentEntryIndex();
92 DiscardPendingEntry(false);
94 pending_entry_index_ = current_index + 1;
95 // TODO(erg): Transition type handled here.
96 NavigateToPendingEntry(ReloadType::NO_RELOAD);
99 void NavigationController::LoadURL(mojo::URLRequestPtr request) {
100 // TODO(erg): This mimics part of NavigationControllerImpl::LoadURL(), minus
101 // all the error checking.
102 SetPendingEntry(make_scoped_ptr(new NavigationEntry(request.Pass())));
103 NavigateToPendingEntry(ReloadType::NO_RELOAD);
106 void NavigationController::NavigateToPendingEntry(ReloadType reload_type) {
107 // TODO(erg): Deal with session history navigations while trying to navigate
108 // to a slow-to-commit page.
110 // TODO(erg): Deal with interstitials.
112 // For session history navigations only the pending_entry_index_ is set.
113 if (!pending_entry_) {
114 CHECK_NE(pending_entry_index_, -1);
115 pending_entry_ = entries_[pending_entry_index_];
118 // TODO(erg): Eventually, we need to deal with restoring the state of the
119 // full tree. For now, we'll just shell back to the WebView.
120 delegate_->OnNavigate(pending_entry_->BuildURLRequest());
123 void NavigationController::DiscardPendingEntry(bool was_failure) {
124 // TODO(erg): We might copy the CHECK regarding NavigateToEntry here.
126 // TODO(erg): We need to maintain the failed_pending_entry_ during
127 // |was_failure| here.
129 if (pending_entry_index_ == -1)
130 delete pending_entry_;
131 pending_entry_ = nullptr;
132 pending_entry_index_ = -1;
135 void NavigationController::SetPendingEntry(scoped_ptr<NavigationEntry> entry) {
136 // TODO(erg): Should be DiscardNonCommittedEntries() if we start porting
137 // transient states over.
138 DiscardPendingEntry(false);
139 pending_entry_ = entry.release();
140 DCHECK_EQ(-1, pending_entry_index_);
141 // TODO(erg): The content code sends NOTIFICATION_NAV_ENTRY_PENDING here.
144 void NavigationController::FrameDidCommitProvisionalLoad(Frame* frame) {
145 // Our renderer is committing a frame. If this was a real implementation,
146 // we'd do something!
147 if (frame->parent())
148 return;
150 // TODO(erg): Need some equivalent of InsertOrReplaceEntry(), as we need to
151 // prune the history list.
153 // TODO(erg): We should copy all the logic from the various
154 // RendererDidNavigate* methods here.
156 // TODO(erg): Medium term, we shouldn't be reusing the NavigationEntry, as it
157 // appears that blink can change some of the data during the navigation. Do
158 // it for now for bootstrapping purposes.
159 if (pending_entry_index_ == -1 && pending_entry_) {
160 int current_size = static_cast<int>(entries_.size());
161 if (current_size > 0) {
162 while (last_committed_entry_index_ < (current_size - 1)) {
163 entries_.pop_back();
164 current_size--;
168 entries_.push_back(pending_entry_);
169 last_committed_entry_index_ = static_cast<int>(entries_.size() - 1);
170 pending_entry_ = nullptr;
171 } else if (pending_entry_index_ != -1 && pending_entry_) {
172 last_committed_entry_index_ = pending_entry_index_;
173 pending_entry_ = nullptr;
175 // This was a historical navigation. In this limited prototype, we don't
176 // actually do anything with it.
177 } else {
178 LOG(ERROR)
179 << "Hit an unknown case in NavigationController::RendererDidNavigate";
182 DiscardPendingEntry(false);
184 delegate_->OnDidNavigate();
187 } // namespace web_view