Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Side by Side Diff: content/browser/web_contents/navigation_controller_impl.cc

Issue 15041004: Replace PruneAllButActive with PruneAllButVisible. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Update tests, mark TODOs Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/web_contents/navigation_controller_impl.h" 5 #include "content/browser/web_contents/navigation_controller_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/string_number_conversions.h" // Temporary 9 #include "base/string_number_conversions.h" // Temporary
10 #include "base/string_util.h" 10 #include "base/string_util.h"
(...skipping 1187 matching lines...) Expand 10 before | Expand all | Expand 10 after
1198 } 1198 }
1199 1199
1200 FinishRestore(source.last_committed_entry_index_, RESTORE_CURRENT_SESSION); 1200 FinishRestore(source.last_committed_entry_index_, RESTORE_CURRENT_SESSION);
1201 1201
1202 // Copy the max page id map from the old tab to the new tab. This ensures 1202 // Copy the max page id map from the old tab to the new tab. This ensures
1203 // that new and existing navigations in the tab's current SiteInstances 1203 // that new and existing navigations in the tab's current SiteInstances
1204 // are identified properly. 1204 // are identified properly.
1205 web_contents_->CopyMaxPageIDsFrom(source.web_contents()); 1205 web_contents_->CopyMaxPageIDsFrom(source.web_contents());
1206 } 1206 }
1207 1207
1208 void NavigationControllerImpl::CopyStateFromAndPrune( 1208 bool NavigationControllerImpl::CopyStateFromAndPrune(
1209 NavigationController* temp) { 1209 NavigationController* temp) {
1210 if (!CanPruneAllButVisible()) {
1211 // It is up to callers to check the invariants before calling this.
1212 NOTREACHED();
1213 return false;
1214 }
1215
1210 NavigationControllerImpl* source = 1216 NavigationControllerImpl* source =
1211 static_cast<NavigationControllerImpl*>(temp); 1217 static_cast<NavigationControllerImpl*>(temp);
1212 // The SiteInstance and page_id of the last committed entry needs to be 1218 // The SiteInstance and page_id of the last committed entry needs to be
1213 // remembered at this point, in case there is only one committed entry 1219 // remembered at this point, in case there is only one committed entry
1214 // and it is pruned. We use a scoped_refptr to ensure the SiteInstance 1220 // and it is pruned. We use a scoped_refptr to ensure the SiteInstance
1215 // can't be freed during this time period. 1221 // can't be freed during this time period.
1216 NavigationEntryImpl* last_committed = 1222 NavigationEntryImpl* last_committed =
1217 NavigationEntryImpl::FromNavigationEntry(GetLastCommittedEntry()); 1223 NavigationEntryImpl::FromNavigationEntry(GetLastCommittedEntry());
1218 scoped_refptr<SiteInstance> site_instance( 1224 scoped_refptr<SiteInstance> site_instance(
1219 last_committed ? last_committed->site_instance() : NULL); 1225 last_committed->site_instance());
1220 int32 minimum_page_id = last_committed ? last_committed->GetPageID() : -1; 1226 int32 minimum_page_id = last_committed->GetPageID();
1221 int32 max_page_id = last_committed ? 1227 int32 max_page_id =
1222 web_contents_->GetMaxPageIDForSiteInstance(site_instance.get()) : -1; 1228 web_contents_->GetMaxPageIDForSiteInstance(site_instance.get());
1223 1229
1224 // This code is intended for use when the last entry is the active entry. 1230 // This code is intended for use when the last entry is the active entry.
1225 DCHECK( 1231 DCHECK_EQ(GetEntryCount() - 1, last_committed_entry_index_);
cbentzel 2013/05/17 00:32:15 I understand this was in here before. I think the
Charlie Reis 2013/05/17 23:50:21 We can't put it in CanPruneAllButVisible, because
1226 (transient_entry_index_ != -1 &&
1227 transient_entry_index_ == GetEntryCount() - 1) ||
1228 (pending_entry_ && (pending_entry_index_ == -1 ||
1229 pending_entry_index_ == GetEntryCount() - 1)) ||
1230 (!pending_entry_ && last_committed_entry_index_ == GetEntryCount() - 1));
1231 1232
1232 // Remove all the entries leaving the active entry. 1233 // Remove all the entries leaving the active entry.
1233 PruneAllButActiveInternal(); 1234 if (!PruneAllButVisibleInternal())
1235 return false;
1234 1236
1235 // We now have zero or one entries. Ensure that adding the entries from 1237 // We now have one entry, possibly with a new pending entry. Ensure that
1236 // source won't put us over the limit. 1238 // adding the entries from source won't put us over the limit.
1237 DCHECK(GetEntryCount() == 0 || GetEntryCount() == 1); 1239 DCHECK_EQ(1, GetEntryCount());
1238 if (GetEntryCount() > 0) 1240 source->PruneOldestEntryIfFull();
1239 source->PruneOldestEntryIfFull();
1240 1241
1241 // Insert the entries from source. Don't use source->GetCurrentEntryIndex as 1242 // Insert the entries from source. Don't use source->GetCurrentEntryIndex as
1242 // we don't want to copy over the transient entry. 1243 // we don't want to copy over the transient entry. Ignore any pending entry,
1243 int max_source_index = source->pending_entry_index_ != -1 ? 1244 // since it has not committed in source.
1244 source->pending_entry_index_ : source->last_committed_entry_index_; 1245 int max_source_index = source->last_committed_entry_index_;
1245 if (max_source_index == -1) 1246 if (max_source_index == -1)
1246 max_source_index = source->GetEntryCount(); 1247 max_source_index = source->GetEntryCount();
1247 else 1248 else
1248 max_source_index++; 1249 max_source_index++;
1249 InsertEntriesFrom(*source, max_source_index); 1250 InsertEntriesFrom(*source, max_source_index);
1250 1251
1251 // Adjust indices such that the last entry and pending are at the end now. 1252 // Adjust indices such that the last entry and pending are at the end now.
1252 last_committed_entry_index_ = GetEntryCount() - 1; 1253 last_committed_entry_index_ = GetEntryCount() - 1;
1253 if (pending_entry_index_ != -1)
1254 pending_entry_index_ = GetEntryCount() - 1;
1255 if (transient_entry_index_ != -1) {
1256 // There's a transient entry. In this case we want the last committed to
1257 // point to the previous entry.
1258 transient_entry_index_ = GetEntryCount() - 1;
1259 if (last_committed_entry_index_ != -1)
1260 last_committed_entry_index_--;
1261 }
1262 1254
1263 web_contents_->SetHistoryLengthAndPrune(site_instance.get(), 1255 web_contents_->SetHistoryLengthAndPrune(site_instance.get(),
1264 max_source_index, 1256 max_source_index,
1265 minimum_page_id); 1257 minimum_page_id);
1266 1258
1267 // Copy the max page id map from the old tab to the new tab. This ensures 1259 // Copy the max page id map from the old tab to the new tab. This ensures
1268 // that new and existing navigations in the tab's current SiteInstances 1260 // that new and existing navigations in the tab's current SiteInstances
1269 // are identified properly. 1261 // are identified properly.
1270 web_contents_->CopyMaxPageIDsFrom(source->web_contents()); 1262 web_contents_->CopyMaxPageIDsFrom(source->web_contents());
1271 1263
1272 // If there is a last committed entry, be sure to include it in the new 1264 // If there is a last committed entry, be sure to include it in the new
1273 // max page ID map. 1265 // max page ID map.
1274 if (max_page_id > -1) { 1266 if (max_page_id > -1) {
1275 web_contents_->UpdateMaxPageIDForSiteInstance(site_instance.get(), 1267 web_contents_->UpdateMaxPageIDForSiteInstance(site_instance.get(),
1276 max_page_id); 1268 max_page_id);
1277 } 1269 }
1270
1271 return true;
1278 } 1272 }
1279 1273
1280 void NavigationControllerImpl::PruneAllButActive() { 1274 bool NavigationControllerImpl::CanPruneAllButVisible() {
1281 PruneAllButActiveInternal(); 1275 // If there is no last committed entry, we cannot prune. Even if there is a
1276 // pending entry, it may not commit, leaving this WebContents blank, despite
1277 // possibly giving it new entries via CopyStateFromAndPrune.
1278 if (last_committed_entry_index_ == -1)
1279 return false;
1282 1280
1283 // If there is an entry left, we need to update the session history length of 1281 // We cannot prune if there is a pending entry at an existing entry index.
1284 // the RenderView. 1282 // It may not commit, so we have to keep the last committed entry, and thus
1285 if (!GetActiveEntry()) 1283 // there is no sensible place to keep the pending entry. It is ok to have
1286 return; 1284 // a new pending entry, which can optionally commit as a new navigation.
1285 if (pending_entry_index_ != -1)
1286 return false;
1287
1288 // We should not prune if we are currently showing a transient entry.
1289 if (transient_entry_index_ != -1)
1290 return false;
1291
1292 return true;
1293 }
1294
1295 bool NavigationControllerImpl::PruneAllButVisible() {
1296 if (!PruneAllButVisibleInternal())
1297 return false;
1298
1299 // We should still have a last committed entry.
1300 DCHECK_NE(-1, last_committed_entry_index_);
1287 1301
1288 NavigationEntryImpl* entry = 1302 NavigationEntryImpl* entry =
1289 NavigationEntryImpl::FromNavigationEntry(GetActiveEntry()); 1303 NavigationEntryImpl::FromNavigationEntry(GetActiveEntry());
1290 // We pass 0 instead of GetEntryCount() for the history_length parameter of 1304 // We pass 0 instead of GetEntryCount() for the history_length parameter of
1291 // SetHistoryLengthAndPrune, because it will create history_length additional 1305 // SetHistoryLengthAndPrune, because it will create history_length additional
1292 // history entries. 1306 // history entries.
1293 // TODO(jochen): This API is confusing and we should clean it up. 1307 // TODO(jochen): This API is confusing and we should clean it up.
1294 // http://crbug.com/178491 1308 // http://crbug.com/178491
1295 web_contents_->SetHistoryLengthAndPrune( 1309 web_contents_->SetHistoryLengthAndPrune(
1296 entry->site_instance(), 0, entry->GetPageID()); 1310 entry->site_instance(), 0, entry->GetPageID());
1311
1312 return true;
1297 } 1313 }
1298 1314
1299 void NavigationControllerImpl::PruneAllButActiveInternal() { 1315 bool NavigationControllerImpl::PruneAllButVisibleInternal() {
1300 if (transient_entry_index_ != -1) { 1316 if (!CanPruneAllButVisible()) {
cbentzel 2013/05/17 00:32:15 Should this just be a DCHECK? The only callers are
Charlie Reis 2013/05/17 23:50:21 The public PruneAllButVisible doesn't call CanPrun
1301 // There is a transient entry. Prune up to it. 1317 // It is up to callers to check the invariants before calling this.
1302 DCHECK_EQ(GetEntryCount() - 1, transient_entry_index_); 1318 NOTREACHED();
1303 entries_.erase(entries_.begin(), entries_.begin() + transient_entry_index_); 1319 return false;
1304 transient_entry_index_ = 0;
1305 last_committed_entry_index_ = -1;
1306 pending_entry_index_ = -1;
1307 } else if (!pending_entry_) {
1308 // There's no pending entry. Leave the last entry (if there is one).
1309 if (!GetEntryCount())
1310 return;
1311
1312 DCHECK_GE(last_committed_entry_index_, 0);
1313 entries_.erase(entries_.begin(),
1314 entries_.begin() + last_committed_entry_index_);
1315 entries_.erase(entries_.begin() + 1, entries_.end());
1316 last_committed_entry_index_ = 0;
1317 } else if (pending_entry_index_ != -1) {
1318 entries_.erase(entries_.begin(), entries_.begin() + pending_entry_index_);
1319 entries_.erase(entries_.begin() + 1, entries_.end());
1320 pending_entry_index_ = 0;
1321 last_committed_entry_index_ = 0;
1322 } else {
1323 // There is a pending_entry, but it's not in entries_.
1324 pending_entry_index_ = -1;
1325 last_committed_entry_index_ = -1;
1326 entries_.clear();
1327 } 1320 }
1328 1321
1329 if (web_contents_->GetInterstitialPage()) { 1322 // Erase all entries but the last committed entry. There may still be a
1330 // Normally the interstitial page hides itself if the user doesn't proceeed. 1323 // new pending entry after this.
1331 // This would result in showing a NavigationEntry we just removed. Set this 1324 entries_.erase(entries_.begin(),
1332 // so the interstitial triggers a reload if the user doesn't proceed. 1325 entries_.begin() + last_committed_entry_index_);
1333 static_cast<InterstitialPageImpl*>(web_contents_->GetInterstitialPage())-> 1326 entries_.erase(entries_.begin() + 1, entries_.end());
1334 set_reload_on_dont_proceed(true); 1327 last_committed_entry_index_ = 0;
1335 } 1328
1329 return true;
1336 } 1330 }
1337 1331
1338 void NavigationControllerImpl::ClearAllScreenshots() { 1332 void NavigationControllerImpl::ClearAllScreenshots() {
1339 screenshot_manager_->ClearAllScreenshots(); 1333 screenshot_manager_->ClearAllScreenshots();
1340 } 1334 }
1341 1335
1342 void NavigationControllerImpl::SetSessionStorageNamespace( 1336 void NavigationControllerImpl::SetSessionStorageNamespace(
1343 const std::string& partition_id, 1337 const std::string& partition_id,
1344 SessionStorageNamespace* session_storage_namespace) { 1338 SessionStorageNamespace* session_storage_namespace) {
1345 if (!session_storage_namespace) 1339 if (!session_storage_namespace)
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
1677 } 1671 }
1678 } 1672 }
1679 } 1673 }
1680 1674
1681 void NavigationControllerImpl::SetGetTimestampCallbackForTest( 1675 void NavigationControllerImpl::SetGetTimestampCallbackForTest(
1682 const base::Callback<base::Time()>& get_timestamp_callback) { 1676 const base::Callback<base::Time()>& get_timestamp_callback) {
1683 get_timestamp_callback_ = get_timestamp_callback; 1677 get_timestamp_callback_ = get_timestamp_callback;
1684 } 1678 }
1685 1679
1686 } // namespace content 1680 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698