| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include "components/web_view/navigation_controller.h" | |
| 6 | |
| 7 #include <utility> | |
| 8 | |
| 9 #include "components/web_view/frame.h" | |
| 10 #include "components/web_view/navigation_controller_delegate.h" | |
| 11 #include "components/web_view/navigation_entry.h" | |
| 12 #include "components/web_view/reload_type.h" | |
| 13 | |
| 14 namespace web_view { | |
| 15 | |
| 16 NavigationController::NavigationController( | |
| 17 NavigationControllerDelegate* delegate) | |
| 18 : pending_entry_(nullptr), | |
| 19 last_committed_entry_index_(-1), | |
| 20 pending_entry_index_(-1), | |
| 21 delegate_(delegate) {} | |
| 22 | |
| 23 NavigationController::~NavigationController() { | |
| 24 DiscardPendingEntry(false); | |
| 25 } | |
| 26 | |
| 27 int NavigationController::GetCurrentEntryIndex() const { | |
| 28 if (pending_entry_index_ != -1) | |
| 29 return pending_entry_index_; | |
| 30 return last_committed_entry_index_; | |
| 31 } | |
| 32 | |
| 33 int NavigationController::GetIndexForOffset(int offset) const { | |
| 34 return GetCurrentEntryIndex() + offset; | |
| 35 } | |
| 36 | |
| 37 int NavigationController::GetEntryCount() const { | |
| 38 // TODO(erg): Have a max number of entries, and DCHECK that we are smaller | |
| 39 // than it here. | |
| 40 return static_cast<int>(entries_.size()); | |
| 41 } | |
| 42 | |
| 43 NavigationEntry* NavigationController::GetEntryAtIndex(int index) const { | |
| 44 if (index < 0 || index >= GetEntryCount()) | |
| 45 return nullptr; | |
| 46 | |
| 47 return entries_[index]; | |
| 48 } | |
| 49 | |
| 50 NavigationEntry* NavigationController::GetEntryAtOffset(int offset) const { | |
| 51 return GetEntryAtIndex(GetIndexForOffset(offset)); | |
| 52 } | |
| 53 | |
| 54 bool NavigationController::CanGoBack() const { | |
| 55 return CanGoToOffset(-1); | |
| 56 } | |
| 57 | |
| 58 bool NavigationController::CanGoForward() const { | |
| 59 return CanGoToOffset(1); | |
| 60 } | |
| 61 | |
| 62 bool NavigationController::CanGoToOffset(int offset) const { | |
| 63 int index = GetIndexForOffset(offset); | |
| 64 return index >= 0 && index < GetEntryCount(); | |
| 65 } | |
| 66 | |
| 67 void NavigationController::GoBack() { | |
| 68 if (!CanGoBack()) { | |
| 69 NOTREACHED(); | |
| 70 return; | |
| 71 } | |
| 72 | |
| 73 // Base the navigation on where we are now... | |
| 74 int current_index = GetCurrentEntryIndex(); | |
| 75 | |
| 76 DiscardPendingEntry(false); | |
| 77 | |
| 78 pending_entry_index_ = current_index - 1; | |
| 79 // TODO(erg): Transition type handled here. | |
| 80 NavigateToPendingEntry(ReloadType::NO_RELOAD, true); | |
| 81 } | |
| 82 | |
| 83 void NavigationController::GoForward() { | |
| 84 if (!CanGoForward()) { | |
| 85 NOTREACHED(); | |
| 86 return; | |
| 87 } | |
| 88 | |
| 89 // TODO(erg): The upstream version handles transience here. | |
| 90 | |
| 91 // Base the navigation on where we are now... | |
| 92 int current_index = GetCurrentEntryIndex(); | |
| 93 | |
| 94 DiscardPendingEntry(false); | |
| 95 | |
| 96 pending_entry_index_ = current_index + 1; | |
| 97 // TODO(erg): Transition type handled here. | |
| 98 NavigateToPendingEntry(ReloadType::NO_RELOAD, true); | |
| 99 } | |
| 100 | |
| 101 void NavigationController::LoadURL(mojo::URLRequestPtr request) { | |
| 102 // TODO(erg): This mimics part of NavigationControllerImpl::LoadURL(), minus | |
| 103 // all the error checking. | |
| 104 SetPendingEntry(make_scoped_ptr(new NavigationEntry(std::move(request)))); | |
| 105 NavigateToPendingEntry(ReloadType::NO_RELOAD, false); | |
| 106 } | |
| 107 | |
| 108 void NavigationController::NavigateToPendingEntry( | |
| 109 ReloadType reload_type, | |
| 110 bool update_navigation_start_time) { | |
| 111 // TODO(erg): Deal with session history navigations while trying to navigate | |
| 112 // to a slow-to-commit page. | |
| 113 | |
| 114 // TODO(erg): Deal with interstitials. | |
| 115 | |
| 116 // For session history navigations only the pending_entry_index_ is set. | |
| 117 if (!pending_entry_) { | |
| 118 CHECK_NE(pending_entry_index_, -1); | |
| 119 pending_entry_ = entries_[pending_entry_index_]; | |
| 120 } | |
| 121 | |
| 122 // TODO(erg): Eventually, we need to deal with restoring the state of the | |
| 123 // full tree. For now, we'll just shell back to the WebView. | |
| 124 delegate_->OnNavigate( | |
| 125 pending_entry_->BuildURLRequest(update_navigation_start_time)); | |
| 126 } | |
| 127 | |
| 128 void NavigationController::DiscardPendingEntry(bool was_failure) { | |
| 129 // TODO(erg): We might copy the CHECK regarding NavigateToEntry here. | |
| 130 | |
| 131 // TODO(erg): We need to maintain the failed_pending_entry_ during | |
| 132 // |was_failure| here. | |
| 133 | |
| 134 if (pending_entry_index_ == -1) | |
| 135 delete pending_entry_; | |
| 136 pending_entry_ = nullptr; | |
| 137 pending_entry_index_ = -1; | |
| 138 } | |
| 139 | |
| 140 void NavigationController::SetPendingEntry(scoped_ptr<NavigationEntry> entry) { | |
| 141 // TODO(erg): Should be DiscardNonCommittedEntries() if we start porting | |
| 142 // transient states over. | |
| 143 DiscardPendingEntry(false); | |
| 144 pending_entry_ = entry.release(); | |
| 145 DCHECK_EQ(-1, pending_entry_index_); | |
| 146 // TODO(erg): The content code sends NOTIFICATION_NAV_ENTRY_PENDING here. | |
| 147 } | |
| 148 | |
| 149 void NavigationController::FrameDidCommitProvisionalLoad(Frame* frame) { | |
| 150 // Our renderer is committing a frame. If this was a real implementation, | |
| 151 // we'd do something! | |
| 152 if (frame->parent()) | |
| 153 return; | |
| 154 | |
| 155 // TODO(erg): Need some equivalent of InsertOrReplaceEntry(), as we need to | |
| 156 // prune the history list. | |
| 157 | |
| 158 // TODO(erg): We should copy all the logic from the various | |
| 159 // RendererDidNavigate* methods here. | |
| 160 | |
| 161 // TODO(erg): Medium term, we shouldn't be reusing the NavigationEntry, as it | |
| 162 // appears that blink can change some of the data during the navigation. Do | |
| 163 // it for now for bootstrapping purposes. | |
| 164 if (pending_entry_index_ == -1 && pending_entry_) { | |
| 165 ClearForwardEntries(); | |
| 166 entries_.push_back(pending_entry_); | |
| 167 last_committed_entry_index_ = static_cast<int>(entries_.size() - 1); | |
| 168 pending_entry_ = nullptr; | |
| 169 } else if (pending_entry_index_ != -1 && pending_entry_) { | |
| 170 last_committed_entry_index_ = pending_entry_index_; | |
| 171 pending_entry_ = nullptr; | |
| 172 | |
| 173 // This was a historical navigation. In this limited prototype, we don't | |
| 174 // actually do anything with it. | |
| 175 } else { | |
| 176 LOG(ERROR) | |
| 177 << "Hit an unknown case in NavigationController::RendererDidNavigate"; | |
| 178 } | |
| 179 | |
| 180 DiscardPendingEntry(false); | |
| 181 | |
| 182 delegate_->OnDidNavigate(); | |
| 183 } | |
| 184 | |
| 185 void NavigationController::FrameDidNavigateLocally(Frame* frame, | |
| 186 const GURL& url) { | |
| 187 // If this is a local navigation of a non-top frame, don't try to commit | |
| 188 // it. | |
| 189 if (frame->parent()) | |
| 190 return; | |
| 191 | |
| 192 ClearForwardEntries(); | |
| 193 | |
| 194 // TODO(erg): This is overly cheap handling of local navigations in | |
| 195 // frames. We don't have all the information needed to construct a real | |
| 196 // URLRequest. | |
| 197 | |
| 198 entries_.push_back(new NavigationEntry(url)); | |
| 199 last_committed_entry_index_ = static_cast<int>(entries_.size() - 1); | |
| 200 | |
| 201 delegate_->OnDidNavigate(); | |
| 202 } | |
| 203 | |
| 204 void NavigationController::ClearForwardEntries() { | |
| 205 int current_size = static_cast<int>(entries_.size()); | |
| 206 if (current_size > 0) { | |
| 207 while (last_committed_entry_index_ < (current_size - 1)) { | |
| 208 entries_.pop_back(); | |
| 209 current_size--; | |
| 210 } | |
| 211 } | |
| 212 } | |
| 213 | |
| 214 } // namespace web_view | |
| OLD | NEW |