| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2006-2008 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 "webkit/tools/test_shell/test_navigation_controller.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "webkit/tools/test_shell/test_shell.h" | |
| 9 | |
| 10 // ---------------------------------------------------------------------------- | |
| 11 // TestNavigationEntry | |
| 12 | |
| 13 TestNavigationEntry::TestNavigationEntry() | |
| 14 : page_id_(-1) { | |
| 15 } | |
| 16 | |
| 17 TestNavigationEntry::TestNavigationEntry(int page_id, | |
| 18 const GURL& url, | |
| 19 const base::string16& target_frame) | |
| 20 : page_id_(page_id), | |
| 21 url_(url), | |
| 22 target_frame_(target_frame) { | |
| 23 } | |
| 24 | |
| 25 TestNavigationEntry::~TestNavigationEntry() { | |
| 26 } | |
| 27 | |
| 28 void TestNavigationEntry::SetContentState(const std::string& state) { | |
| 29 state_ = state; | |
| 30 } | |
| 31 | |
| 32 // ---------------------------------------------------------------------------- | |
| 33 // TestNavigationController | |
| 34 | |
| 35 TestNavigationController::TestNavigationController(TestShell* shell) | |
| 36 : pending_entry_(NULL), | |
| 37 last_committed_entry_index_(-1), | |
| 38 pending_entry_index_(-1), | |
| 39 shell_(shell), | |
| 40 max_page_id_(-1) { | |
| 41 } | |
| 42 | |
| 43 TestNavigationController::~TestNavigationController() { | |
| 44 DiscardPendingEntry(); | |
| 45 } | |
| 46 | |
| 47 void TestNavigationController::Reset() { | |
| 48 entries_.clear(); | |
| 49 DiscardPendingEntry(); | |
| 50 | |
| 51 last_committed_entry_index_ = -1; | |
| 52 } | |
| 53 | |
| 54 void TestNavigationController::Reload() { | |
| 55 // Base the navigation on where we are now... | |
| 56 int current_index = GetCurrentEntryIndex(); | |
| 57 | |
| 58 // If we are no where, then we can't reload. TODO(darin): We should add a | |
| 59 // CanReload method. | |
| 60 if (current_index == -1) | |
| 61 return; | |
| 62 | |
| 63 DiscardPendingEntry(); | |
| 64 | |
| 65 pending_entry_index_ = current_index; | |
| 66 NavigateToPendingEntry(true); | |
| 67 } | |
| 68 | |
| 69 void TestNavigationController::GoToOffset(int offset) { | |
| 70 int index = last_committed_entry_index_ + offset; | |
| 71 if (index < 0 || index >= GetEntryCount()) | |
| 72 return; | |
| 73 | |
| 74 GoToIndex(index); | |
| 75 } | |
| 76 | |
| 77 void TestNavigationController::GoToIndex(int index) { | |
| 78 DCHECK(index >= 0); | |
| 79 DCHECK(index < static_cast<int>(entries_.size())); | |
| 80 | |
| 81 DiscardPendingEntry(); | |
| 82 | |
| 83 pending_entry_index_ = index; | |
| 84 NavigateToPendingEntry(false); | |
| 85 } | |
| 86 | |
| 87 void TestNavigationController::LoadEntry(TestNavigationEntry* entry) { | |
| 88 // When navigating to a new page, we don't know for sure if we will actually | |
| 89 // end up leaving the current page. The new page load could for example | |
| 90 // result in a download or a 'no content' response (e.g., a mailto: URL). | |
| 91 DiscardPendingEntry(); | |
| 92 pending_entry_ = entry; | |
| 93 NavigateToPendingEntry(false); | |
| 94 } | |
| 95 | |
| 96 | |
| 97 TestNavigationEntry* TestNavigationController::GetLastCommittedEntry() const { | |
| 98 if (last_committed_entry_index_ == -1) | |
| 99 return NULL; | |
| 100 return entries_[last_committed_entry_index_].get(); | |
| 101 } | |
| 102 | |
| 103 TestNavigationEntry* TestNavigationController::GetActiveEntry() const { | |
| 104 TestNavigationEntry* entry = pending_entry_; | |
| 105 if (!entry) | |
| 106 entry = GetLastCommittedEntry(); | |
| 107 return entry; | |
| 108 } | |
| 109 | |
| 110 int TestNavigationController::GetCurrentEntryIndex() const { | |
| 111 if (pending_entry_index_ != -1) | |
| 112 return pending_entry_index_; | |
| 113 return last_committed_entry_index_; | |
| 114 } | |
| 115 | |
| 116 | |
| 117 TestNavigationEntry* TestNavigationController::GetEntryAtIndex( | |
| 118 int index) const { | |
| 119 if (index < 0 || index >= GetEntryCount()) | |
| 120 return NULL; | |
| 121 | |
| 122 return entries_[index].get(); | |
| 123 } | |
| 124 | |
| 125 TestNavigationEntry* TestNavigationController::GetEntryWithPageID( | |
| 126 int32 page_id) const { | |
| 127 int index = GetEntryIndexWithPageID(page_id); | |
| 128 return (index != -1) ? entries_[index].get() : NULL; | |
| 129 } | |
| 130 | |
| 131 void TestNavigationController::DidNavigateToEntry(TestNavigationEntry* entry) { | |
| 132 // If the entry is that of a page with PageID larger than any this Tab has | |
| 133 // seen before, then consider it a new navigation. | |
| 134 if (entry->GetPageID() > GetMaxPageID()) { | |
| 135 InsertEntry(entry); | |
| 136 return; | |
| 137 } | |
| 138 | |
| 139 // Otherwise, we just need to update an existing entry with matching PageID. | |
| 140 // If the existing entry corresponds to the entry which is pending, then we | |
| 141 // must update the current entry index accordingly. When navigating to the | |
| 142 // same URL, a new PageID is not created. | |
| 143 | |
| 144 int existing_entry_index = GetEntryIndexWithPageID(entry->GetPageID()); | |
| 145 TestNavigationEntry* existing_entry = (existing_entry_index != -1) ? | |
| 146 entries_[existing_entry_index].get() : NULL; | |
| 147 if (!existing_entry) { | |
| 148 // No existing entry, then simply ignore this navigation! | |
| 149 DLOG(WARNING) << "ignoring navigation for page: " << entry->GetPageID(); | |
| 150 } else if (existing_entry == pending_entry_) { | |
| 151 // The given entry might provide a new URL... e.g., navigating back to a | |
| 152 // page in session history could have resulted in a new client redirect. | |
| 153 existing_entry->SetURL(entry->GetURL()); | |
| 154 existing_entry->SetContentState(entry->GetContentState()); | |
| 155 last_committed_entry_index_ = pending_entry_index_; | |
| 156 pending_entry_index_ = -1; | |
| 157 pending_entry_ = NULL; | |
| 158 } else if (pending_entry_ && pending_entry_->GetPageID() == -1 && | |
| 159 pending_entry_->GetURL() == existing_entry->GetURL()) { | |
| 160 // Not a new navigation | |
| 161 DiscardPendingEntry(); | |
| 162 } else { | |
| 163 // The given entry might provide a new URL... e.g., navigating to a page | |
| 164 // might result in a client redirect, which should override the URL of the | |
| 165 // existing entry. | |
| 166 existing_entry->SetURL(entry->GetURL()); | |
| 167 existing_entry->SetContentState(entry->GetContentState()); | |
| 168 | |
| 169 // The navigation could have been issued by the renderer, so be sure that | |
| 170 // we update our current index. | |
| 171 last_committed_entry_index_ = existing_entry_index; | |
| 172 } | |
| 173 | |
| 174 delete entry; | |
| 175 UpdateMaxPageID(); | |
| 176 } | |
| 177 | |
| 178 void TestNavigationController::DiscardPendingEntry() { | |
| 179 if (pending_entry_index_ == -1) | |
| 180 delete pending_entry_; | |
| 181 pending_entry_ = NULL; | |
| 182 pending_entry_index_ = -1; | |
| 183 } | |
| 184 | |
| 185 void TestNavigationController::InsertEntry(TestNavigationEntry* entry) { | |
| 186 DiscardPendingEntry(); | |
| 187 | |
| 188 // Prune any entry which are in front of the current entry | |
| 189 int current_size = static_cast<int>(entries_.size()); | |
| 190 if (current_size > 0) { | |
| 191 while (last_committed_entry_index_ < (current_size - 1)) { | |
| 192 entries_.pop_back(); | |
| 193 current_size--; | |
| 194 } | |
| 195 } | |
| 196 | |
| 197 entries_.push_back(linked_ptr<TestNavigationEntry>(entry)); | |
| 198 last_committed_entry_index_ = static_cast<int>(entries_.size()) - 1; | |
| 199 UpdateMaxPageID(); | |
| 200 } | |
| 201 | |
| 202 int TestNavigationController::GetEntryIndexWithPageID(int32 page_id) const { | |
| 203 for (int i = static_cast<int>(entries_.size())-1; i >= 0; --i) { | |
| 204 if (entries_[i]->GetPageID() == page_id) | |
| 205 return i; | |
| 206 } | |
| 207 return -1; | |
| 208 } | |
| 209 | |
| 210 void TestNavigationController::NavigateToPendingEntry(bool reload) { | |
| 211 // For session history navigations only the pending_entry_index_ is set. | |
| 212 if (!pending_entry_) { | |
| 213 DCHECK(pending_entry_index_ != -1); | |
| 214 pending_entry_ = entries_[pending_entry_index_].get(); | |
| 215 } | |
| 216 | |
| 217 if (shell_->Navigate(*pending_entry_, reload)) { | |
| 218 // Note: this is redundant if navigation completed synchronously because | |
| 219 // DidNavigateToEntry call this as well. | |
| 220 UpdateMaxPageID(); | |
| 221 } else { | |
| 222 DiscardPendingEntry(); | |
| 223 } | |
| 224 } | |
| 225 | |
| 226 void TestNavigationController::UpdateMaxPageID() { | |
| 227 TestNavigationEntry* entry = GetActiveEntry(); | |
| 228 if (entry) | |
| 229 max_page_id_ = std::max(max_page_id_, entry->GetPageID()); | |
| 230 } | |
| OLD | NEW |