Replace PruneAllButActive with PruneAllButVisible.

Before we would forget the entry for the visible page, so we now require there
to be a last committed entry, no transient entry, and optionally a new pending
entry (not an existing pending entry).

BUG=234809
TEST=Prerendering should not swap in without a last committed entry.

Review URL: https://chromiumcodereview.appspot.com/15041004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@203492 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/ui/browser_instant_controller.cc b/chrome/browser/ui/browser_instant_controller.cc
index 9b2ad3d..c2d3ab45 100644
--- a/chrome/browser/ui/browser_instant_controller.cc
+++ b/chrome/browser/ui/browser_instant_controller.cc
@@ -100,13 +100,32 @@
 
   *target_contents = instant_ntp.get();
   if (source_contents) {
-    instant_ntp->GetController().CopyStateFromAndPrune(
-        &source_contents->GetController());
-    ReplaceWebContentsAt(
-        browser_->tab_strip_model()->GetIndexOfWebContents(source_contents),
-        instant_ntp.Pass());
+    // If the Instant NTP hasn't yet committed an entry, we can't call
+    // CopyStateFromAndPrune.  Instead, load the Local NTP URL directly in the
+    // source contents.
+    // TODO(sreeram): Always using the local URL is wrong in the case of the
+    // first tab in a window where we might want to use the remote URL. Fix.
+    if (!instant_ntp->GetController().CanPruneAllButVisible()) {
+      source_contents->GetController().LoadURL(chrome::GetLocalInstantURL(
+          profile()), content::Referrer(), content::PAGE_TRANSITION_GENERATED,
+          std::string());
+      *target_contents = source_contents;
+    } else {
+      instant_ntp->GetController().CopyStateFromAndPrune(
+          &source_contents->GetController());
+      ReplaceWebContentsAt(
+          browser_->tab_strip_model()->GetIndexOfWebContents(source_contents),
+          instant_ntp.Pass());
+    }
   } else {
-    instant_ntp->GetController().PruneAllButActive();
+    // If the Instant NTP hasn't yet committed an entry, we can't call
+    // PruneAllButVisible.  In that case, there shouldn't be any entries to
+    // prune anyway.
+    if (instant_ntp->GetController().CanPruneAllButVisible())
+      instant_ntp->GetController().PruneAllButVisible();
+    else
+      CHECK(!instant_ntp->GetController().GetLastCommittedEntry());
+
     // If |source_contents| is NULL, then the caller is responsible for
     // inserting instant_ntp into the tabstrip and will take ownership.
     ignore_result(instant_ntp.release());