summaryrefslogtreecommitdiffstats
path: root/chrome/browser/tab_contents
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/tab_contents')
-rw-r--r--chrome/browser/tab_contents/infobar_delegate.cc2
-rw-r--r--chrome/browser/tab_contents/interstitial_page.cc14
-rw-r--r--chrome/browser/tab_contents/navigation_controller.cc108
-rw-r--r--chrome/browser/tab_contents/navigation_controller.h44
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu.cc16
-rw-r--r--chrome/browser/tab_contents/render_view_host_delegate_helper.cc1
-rw-r--r--chrome/browser/tab_contents/render_view_host_manager.cc34
-rw-r--r--chrome/browser/tab_contents/render_view_host_manager.h8
-rw-r--r--chrome/browser/tab_contents/render_view_host_manager_unittest.cc21
-rw-r--r--chrome/browser/tab_contents/tab_contents.cc85
-rw-r--r--chrome/browser/tab_contents/tab_contents.h76
-rw-r--r--chrome/browser/tab_contents/web_contents.cc327
-rw-r--r--chrome/browser/tab_contents/web_contents.h9
-rw-r--r--chrome/browser/tab_contents/web_contents_unittest.cc160
14 files changed, 332 insertions, 573 deletions
diff --git a/chrome/browser/tab_contents/infobar_delegate.cc b/chrome/browser/tab_contents/infobar_delegate.cc
index 6925dda..9a466fb 100644
--- a/chrome/browser/tab_contents/infobar_delegate.cc
+++ b/chrome/browser/tab_contents/infobar_delegate.cc
@@ -29,7 +29,7 @@ InfoBarDelegate::InfoBarDelegate(TabContents* contents)
}
void InfoBarDelegate::StoreActiveEntryUniqueID(TabContents* contents) {
- NavigationEntry* active_entry = contents->controller()->GetActiveEntry();
+ NavigationEntry* active_entry = contents->controller().GetActiveEntry();
contents_unique_id_ = active_entry ? active_entry->unique_id() : 0;
}
diff --git a/chrome/browser/tab_contents/interstitial_page.cc b/chrome/browser/tab_contents/interstitial_page.cc
index 206bc34..1ffff17 100644
--- a/chrome/browser/tab_contents/interstitial_page.cc
+++ b/chrome/browser/tab_contents/interstitial_page.cc
@@ -121,7 +121,7 @@ InterstitialPage::InterstitialPage(WebContents* tab,
// (which is the case when the interstitial was triggered by a sub-resource on
// a page) when we have a pending entry (in the process of loading a new top
// frame).
- DCHECK(new_navigation || !tab->controller()->pending_entry());
+ DCHECK(new_navigation || !tab->controller().pending_entry());
}
InterstitialPage::~InterstitialPage() {
@@ -169,7 +169,7 @@ void InterstitialPage::Show() {
// Give sub-classes a chance to set some states on the navigation entry.
UpdateEntry(entry);
- tab_->controller()->AddTransientEntry(entry);
+ tab_->controller().AddTransientEntry(entry);
}
DCHECK(!render_view_host_);
@@ -183,9 +183,9 @@ void InterstitialPage::Show() {
notification_registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED,
Source<TabContents>(tab_));
notification_registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED,
- Source<NavigationController>(tab_->controller()));
+ Source<NavigationController>(&tab_->controller()));
notification_registrar_.Add(this, NotificationType::NAV_ENTRY_PENDING,
- Source<NavigationController>(tab_->controller()));
+ Source<NavigationController>(&tab_->controller()));
}
void InterstitialPage::Hide() {
@@ -194,7 +194,7 @@ void InterstitialPage::Hide() {
if (tab_->interstitial_page())
tab_->remove_interstitial_page();
// Let's revert to the original title if necessary.
- NavigationEntry* entry = tab_->controller()->GetActiveEntry();
+ NavigationEntry* entry = tab_->controller().GetActiveEntry();
if (!new_navigation_ && should_revert_tab_title_) {
entry->set_title(WideToUTF16Hack(original_tab_title_));
tab_->NotifyNavigationStateChanged(TabContents::INVALIDATE_TITLE);
@@ -321,7 +321,7 @@ void InterstitialPage::DontProceed() {
// explicitely. Note that by calling DiscardNonCommittedEntries() we also
// discard the pending entry, which is what we want, since the navigation is
// cancelled.
- tab_->controller()->DiscardNonCommittedEntries();
+ tab_->controller().DiscardNonCommittedEntries();
}
Hide();
@@ -383,7 +383,7 @@ void InterstitialPage::UpdateTitle(RenderViewHost* render_view_host,
int32 page_id,
const std::wstring& title) {
DCHECK(render_view_host == render_view_host_);
- NavigationEntry* entry = tab_->controller()->GetActiveEntry();
+ NavigationEntry* entry = tab_->controller().GetActiveEntry();
// If this interstitial is shown on an existing navigation entry, we'll need
// to remember its title so we can revert to it when hidden.
if (!new_navigation_ && !should_revert_tab_title_) {
diff --git a/chrome/browser/tab_contents/navigation_controller.cc b/chrome/browser/tab_contents/navigation_controller.cc
index 77cf714..268eadb 100644
--- a/chrome/browser/tab_contents/navigation_controller.cc
+++ b/chrome/browser/tab_contents/navigation_controller.cc
@@ -15,7 +15,6 @@
#include "chrome/browser/tab_contents/navigation_entry.h"
#include "chrome/browser/tab_contents/repost_form_warning.h"
#include "chrome/browser/tab_contents/site_instance.h"
-#include "chrome/browser/tab_contents/web_contents.h"
#include "chrome/common/navigation_types.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/render_messages.h"
@@ -121,45 +120,34 @@ NavigationController::NavigationController(TabContents* contents,
ALLOW_THIS_IN_INITIALIZER_LIST(ssl_manager_(this, NULL)),
needs_reload_(false),
load_pending_entry_when_active_(false) {
- if (contents)
- contents->set_controller(this);
DCHECK(profile_);
}
-NavigationController::NavigationController(
- Profile* profile,
+NavigationController::~NavigationController() {
+ DiscardNonCommittedEntriesInternal();
+
+ NotificationService::current()->Notify(
+ NotificationType::TAB_CLOSED,
+ Source<NavigationController>(this),
+ NotificationService::NoDetails());
+}
+
+void NavigationController::RestoreFromState(
const std::vector<TabNavigation>& navigations,
- int selected_navigation)
- : profile_(profile),
- pending_entry_(NULL),
- last_committed_entry_index_(-1),
- pending_entry_index_(-1),
- transient_entry_index_(-1),
- tab_contents_(NULL),
- max_restored_page_id_(-1),
- ALLOW_THIS_IN_INITIALIZER_LIST(ssl_manager_(this, NULL)),
- needs_reload_(true),
- load_pending_entry_when_active_(false) {
- DCHECK(profile_);
+ int selected_navigation) {
+ // Verify that this controller is unused and that the input is valid.
+ DCHECK(entry_count() == 0 && !pending_entry());
DCHECK(selected_navigation >= 0 &&
selected_navigation < static_cast<int>(navigations.size()));
// Populate entries_ from the supplied TabNavigations.
+ needs_reload_ = true;
CreateNavigationEntriesFromTabNavigations(navigations, &entries_);
// And finish the restore.
FinishRestore(selected_navigation);
}
-NavigationController::~NavigationController() {
- DiscardNonCommittedEntriesInternal();
-
- NotificationService::current()->Notify(
- NotificationType::TAB_CLOSED,
- Source<NavigationController>(this),
- NotificationService::NoDetails());
-}
-
void NavigationController::Reload(bool check_for_repost) {
// Reloading a transient entry does nothing.
if (transient_entry_index_ != -1)
@@ -351,19 +339,6 @@ void NavigationController::RemoveEntryAtIndex(int index,
}
}
-void NavigationController::Destroy() {
- // TODO(brettw) the destruction of TabContents/NavigationController makes no
- // sense (see TabContentsWasDestroyed)
- tab_contents_->Destroy();
- // We are now deleted.
-}
-
-void NavigationController::TabContentsWasDestroyed() {
- // TODO(brettw) the destruction of TabContents/NavigationController makes no
- // sense (see Destroy).
- delete this;
-}
-
NavigationEntry* NavigationController::CreateNavigationEntry(
const GURL& url, const GURL& referrer, PageTransition::Type transition) {
// Allow the browser URL handler to rewrite the URL. This will, for example,
@@ -421,7 +396,7 @@ void NavigationController::LoadURLLazily(const GURL& url,
load_pending_entry_when_active_ = true;
}
-bool NavigationController::LoadingURLLazily() {
+bool NavigationController::LoadingURLLazily() const {
return load_pending_entry_when_active_;
}
@@ -741,6 +716,7 @@ bool NavigationController::RendererDidNavigateAutoSubframe(
return false;
}
+// TODO(brettw) I think this function is unnecessary.
void NavigationController::CommitPendingEntry() {
DiscardTransientEntry();
@@ -803,6 +779,22 @@ bool NavigationController::IsURLInPageNavigation(const GURL& url) const {
return AreURLsInPageNavigation(last_committed->url(), url);
}
+void NavigationController::CopyStateFrom(const NavigationController& source) {
+ // Verify that we look new.
+ DCHECK(entry_count() == 0 && !pending_entry());
+
+ if (source.entry_count() == 0)
+ return; // Nothing new to do.
+
+ needs_reload_ = true;
+ for (int i = 0; i < source.entry_count(); i++) {
+ entries_.push_back(linked_ptr<NavigationEntry>(
+ new NavigationEntry(*source.entries_[i])));
+ }
+
+ FinishRestore(source.last_committed_entry_index_);
+}
+
void NavigationController::DiscardNonCommittedEntries() {
bool transient = transient_entry_index_ != -1;
DiscardNonCommittedEntriesInternal();
@@ -867,9 +859,6 @@ void NavigationController::NavigateToPendingEntry(bool reload) {
pending_entry_ = entries_[pending_entry_index_].get();
}
- tab_contents_ = GetTabContentsCreateIfNecessary(*pending_entry_);
-
- NavigationEntry temp_entry(*pending_entry_);
if (!tab_contents_->NavigateToPendingEntry(reload))
DiscardNonCommittedEntries();
}
@@ -889,17 +878,6 @@ void NavigationController::NotifyNavigationEntryCommitted(
Details<LoadCommittedDetails>(details));
}
-TabContents* NavigationController::GetTabContentsCreateIfNecessary(
- const NavigationEntry& entry) {
- if (tab_contents_)
- return tab_contents_;
-
- tab_contents_ = new WebContents(profile_, entry.site_instance(),
- MSG_ROUTING_NONE, NULL);
- tab_contents_->set_controller(this);
- return tab_contents_; // TODO(brettw) it's stupid to both set and return it.
-}
-
// static
void NavigationController::DisablePromptOnRepost() {
check_for_repost_ = false;
@@ -938,25 +916,6 @@ void NavigationController::NotifyEntryChanged(const NavigationEntry* entry,
Details<EntryChangedDetails>(&det));
}
-NavigationController* NavigationController::Clone() {
- NavigationController* nc = new NavigationController(NULL, profile_);
-
- if (entry_count() == 0)
- return nc;
-
- nc->needs_reload_ = true;
-
- nc->entries_.reserve(entries_.size());
- for (int i = 0, c = entry_count(); i < c; ++i) {
- nc->entries_.push_back(linked_ptr<NavigationEntry>(
- new NavigationEntry(*GetEntryAtIndex(i))));
- }
-
- nc->FinishRestore(last_committed_entry_index_);
-
- return nc;
-}
-
void NavigationController::FinishRestore(int selected_index) {
DCHECK(selected_index >= 0 && selected_index < entry_count());
ConfigureEntriesForRestore(&entries_);
@@ -964,9 +923,6 @@ void NavigationController::FinishRestore(int selected_index) {
set_max_restored_page_id(entry_count());
last_committed_entry_index_ = selected_index;
-
- // Callers assume we have an active_contents after restoring, so set it now.
- tab_contents_ = GetTabContentsCreateIfNecessary(*entries_[selected_index]);
}
void NavigationController::DiscardNonCommittedEntriesInternal() {
diff --git a/chrome/browser/tab_contents/navigation_controller.h b/chrome/browser/tab_contents/navigation_controller.h
index af7cf60..e42f4ad 100644
--- a/chrome/browser/tab_contents/navigation_controller.h
+++ b/chrome/browser/tab_contents/navigation_controller.h
@@ -123,34 +123,21 @@ class NavigationController {
// ---------------------------------------------------------------------------
- NavigationController(TabContents* initial_contents, Profile* profile);
-
- // Creates a NavigationController from the specified history. Processing
- // for this is asynchronous and handled via the RestoreHelper (in
- // navigation_controller.cc).
- NavigationController(
- Profile* profile,
- const std::vector<TabNavigation>& navigations,
- int selected_navigation);
+ NavigationController(TabContents* tab_contents, Profile* profile);
~NavigationController();
- // Begin the destruction sequence for this NavigationController and all its
- // registered tabs. The sequence is as follows:
- // 1. All tabs are asked to Destroy themselves.
- // 2. When each tab is finished Destroying, it will notify the controller.
- // 3. Once all tabs are Destroyed, the NavigationController deletes itself.
- // This ensures that all the TabContents outlive the NavigationController.
- void Destroy();
-
- // Clone the receiving navigation controller. Only the active tab contents is
- // duplicated.
- NavigationController* Clone();
-
// Returns the profile for this controller. It can never be NULL.
Profile* profile() const {
return profile_;
}
+ // Initializes this NavigationController with the given saved navigations,
+ // using selected_navigation as the currently loaded entry. Before this call
+ // the controller should be unused (there should be no current entry). This is
+ // used for session restore.
+ void RestoreFromState(const std::vector<TabNavigation>& navigations,
+ int selected_navigation);
+
// Active entry --------------------------------------------------------------
// Returns the active entry, which is the transient entry if any, the pending
@@ -295,10 +282,6 @@ class NavigationController {
// TabContents ---------------------------------------------------------------
- // Notifies the controller that a TabContents that it owns has been destroyed.
- // This is part of the NavigationController's Destroy sequence.
- void TabContentsWasDestroyed();
-
// Returns the tab contents associated with this controller. Non-NULL except
// during set-up of the tab.
TabContents* tab_contents() const {
@@ -346,13 +329,17 @@ class NavigationController {
// refs without reload, only change to "#" which we don't count as empty).
bool IsURLInPageNavigation(const GURL& url) const;
+ // Copies the navigation state from the given controller to this one. This
+ // one should be empty (just created).
+ void CopyStateFrom(const NavigationController& source);
+
// Random data ---------------------------------------------------------------
// Returns true if this NavigationController is is configured to load a URL
// lazily. If true, use GetLazyTitle() and GetLazyFavIcon() to discover the
// titles and favicons. Since no request was made, this is the only info
// we have about this page. This feature is used by web application clusters.
- bool LoadingURLLazily();
+ bool LoadingURLLazily() const;
const string16& GetLazyTitle() const;
const SkBitmap& GetLazyFavIcon() const;
@@ -425,11 +412,6 @@ class NavigationController {
// committed. This will fill in the active entry to the details structure.
void NotifyNavigationEntryCommitted(LoadCommittedDetails* details);
- // Returns the TabContents for the |entry|'s type. If the TabContents
- // doesn't yet exist, it is created. If a new TabContents is created, its
- // parent is |parent|. Becomes part of |entry|'s SiteInstance.
- TabContents* GetTabContentsCreateIfNecessary(const NavigationEntry& entry);
-
// Sets the max restored page ID this NavigationController has seen, if it
// was restored from a previous session.
void set_max_restored_page_id(int max_id) { max_restored_page_id_ = max_id; }
diff --git a/chrome/browser/tab_contents/render_view_context_menu.cc b/chrome/browser/tab_contents/render_view_context_menu.cc
index fd94e13..698a65a 100644
--- a/chrome/browser/tab_contents/render_view_context_menu.cc
+++ b/chrome/browser/tab_contents/render_view_context_menu.cc
@@ -208,10 +208,10 @@ bool RenderViewContextMenu::IsItemCommandEnabled(int id) const {
switch (id) {
case IDS_CONTENT_CONTEXT_BACK:
- return source_web_contents_->controller()->CanGoBack();
+ return source_web_contents_->controller().CanGoBack();
case IDS_CONTENT_CONTEXT_FORWARD:
- return source_web_contents_->controller()->CanGoForward();
+ return source_web_contents_->controller().CanGoForward();
case IDS_CONTENT_CONTEXT_VIEWPAGESOURCE:
case IDS_CONTENT_CONTEXT_VIEWFRAMESOURCE:
@@ -283,7 +283,7 @@ bool RenderViewContextMenu::IsItemCommandEnabled(int id) const {
return !params_.misspelled_word.empty();
case IDS_CONTENT_CONTEXT_VIEWPAGEINFO:
- return (source_web_contents_->controller()->GetActiveEntry() != NULL);
+ return (source_web_contents_->controller().GetActiveEntry() != NULL);
case IDS_CONTENT_CONTEXT_RELOAD:
case IDS_CONTENT_CONTEXT_COPYIMAGE:
@@ -393,11 +393,11 @@ void RenderViewContextMenu::ExecuteItemCommand(int id) {
break;
case IDS_CONTENT_CONTEXT_BACK:
- source_web_contents_->controller()->GoBack();
+ source_web_contents_->controller().GoBack();
break;
case IDS_CONTENT_CONTEXT_FORWARD:
- source_web_contents_->controller()->GoForward();
+ source_web_contents_->controller().GoForward();
break;
case IDS_CONTENT_CONTEXT_SAVEPAGEAS:
@@ -405,7 +405,7 @@ void RenderViewContextMenu::ExecuteItemCommand(int id) {
break;
case IDS_CONTENT_CONTEXT_RELOAD:
- source_web_contents_->controller()->Reload(true);
+ source_web_contents_->controller().Reload(true);
break;
case IDS_CONTENT_CONTEXT_PRINT:
@@ -424,7 +424,7 @@ void RenderViewContextMenu::ExecuteItemCommand(int id) {
case IDS_CONTENT_CONTEXT_VIEWPAGEINFO: {
#if defined(OS_WIN)
NavigationEntry* nav_entry =
- source_web_contents_->controller()->GetActiveEntry();
+ source_web_contents_->controller().GetActiveEntry();
PageInfoWindow::CreatePageInfo(
source_web_contents_->profile(),
nav_entry,
@@ -581,7 +581,7 @@ bool RenderViewContextMenu::IsDevCommandEnabled(int id) const {
return true;
NavigationEntry *active_entry =
- source_web_contents_->controller()->GetActiveEntry();
+ source_web_contents_->controller().GetActiveEntry();
if (!active_entry)
return false;
diff --git a/chrome/browser/tab_contents/render_view_host_delegate_helper.cc b/chrome/browser/tab_contents/render_view_host_delegate_helper.cc
index 9846a77..9268850 100644
--- a/chrome/browser/tab_contents/render_view_host_delegate_helper.cc
+++ b/chrome/browser/tab_contents/render_view_host_delegate_helper.cc
@@ -29,7 +29,6 @@ void RenderViewHostDelegateViewHelper::CreateNewWindow(int route_id,
site,
route_id,
modal_dialog_event);
- new_contents->SetupController(profile);
WebContentsView* new_view = new_contents->view();
// TODO(brettw) it seems bogus that we have to call this function on the
diff --git a/chrome/browser/tab_contents/render_view_host_manager.cc b/chrome/browser/tab_contents/render_view_host_manager.cc
index a178356..8b2c276 100644
--- a/chrome/browser/tab_contents/render_view_host_manager.cc
+++ b/chrome/browser/tab_contents/render_view_host_manager.cc
@@ -37,9 +37,13 @@ RenderViewHostManager::RenderViewHostManager(
}
RenderViewHostManager::~RenderViewHostManager() {
- // Shutdown should have been called which should have cleaned these up.
- DCHECK(!render_view_host_);
- DCHECK(!pending_render_view_host_);
+ if (pending_render_view_host_)
+ CancelPending();
+
+ // We should always have a main RenderViewHost.
+ RenderViewHost* render_view_host = render_view_host_;
+ render_view_host_ = NULL;
+ render_view_host->Shutdown();
}
void RenderViewHostManager::Init(Profile* profile,
@@ -55,16 +59,6 @@ void RenderViewHostManager::Init(Profile* profile,
site_instance, render_view_delegate_, routing_id, modal_dialog_event);
}
-void RenderViewHostManager::Shutdown() {
- if (pending_render_view_host_)
- CancelPending();
-
- // We should always have a main RenderViewHost.
- RenderViewHost* render_view_host = render_view_host_;
- render_view_host_ = NULL;
- render_view_host->Shutdown();
-}
-
RenderViewHost* RenderViewHostManager::Navigate(const NavigationEntry& entry) {
// This will possibly create (set to NULL) a DOM UI object for the pending
// page. We'll use this later to give the page special access. This must
@@ -105,7 +99,7 @@ RenderViewHost* RenderViewHostManager::Navigate(const NavigationEntry& entry) {
NotificationService::current()->Notify(
NotificationType::RENDER_VIEW_HOST_CHANGED,
Source<NavigationController>(
- delegate_->GetControllerForRenderManager()),
+ &delegate_->GetControllerForRenderManager()),
Details<RenderViewHostSwitchedDetails>(&details));
}
}
@@ -356,12 +350,12 @@ SiteInstance* RenderViewHostManager::GetSiteInstanceForEntry(
// For now, though, we're in a hybrid model where you only switch
// SiteInstances if you type in a cross-site URL. This means we have to
// compare the entry's URL to the last committed entry's URL.
- NavigationController* controller = delegate_->GetControllerForRenderManager();
- NavigationEntry* curr_entry = controller->GetLastCommittedEntry();
+ NavigationController& controller = delegate_->GetControllerForRenderManager();
+ NavigationEntry* curr_entry = controller.GetLastCommittedEntry();
if (interstitial_page_) {
// The interstitial is currently the last committed entry, but we want to
// compare against the last non-interstitial entry.
- curr_entry = controller->GetEntryAtOffset(-1);
+ curr_entry = controller.GetEntryAtOffset(-1);
}
// If there is no last non-interstitial entry (and curr_instance already
// has a site), then we must have been opened from another tab. We want
@@ -386,7 +380,7 @@ SiteInstance* RenderViewHostManager::GetSiteInstanceForEntry(
// that page, we want to explicity ignore that BrowsingInstance and make a
// new process.
return SiteInstance::CreateSiteInstance(
- delegate_->GetControllerForRenderManager()->profile());
+ delegate_->GetControllerForRenderManager().profile());
} else {
// Start the new renderer in a new SiteInstance, but in the current
// BrowsingInstance. It is important to immediately give this new
@@ -399,7 +393,7 @@ SiteInstance* RenderViewHostManager::GetSiteInstanceForEntry(
bool RenderViewHostManager::CreatePendingRenderView(SiteInstance* instance) {
NavigationEntry* curr_entry =
- delegate_->GetControllerForRenderManager()->GetLastCommittedEntry();
+ delegate_->GetControllerForRenderManager().GetLastCommittedEntry();
if (curr_entry) {
DCHECK(!curr_entry->content_state().empty());
// TODO(creis): Should send a message to the RenderView to let it know
@@ -466,7 +460,7 @@ void RenderViewHostManager::CommitPending() {
details.old_host = old_render_view_host;
NotificationService::current()->Notify(
NotificationType::RENDER_VIEW_HOST_CHANGED,
- Source<NavigationController>(delegate_->GetControllerForRenderManager()),
+ Source<NavigationController>(&delegate_->GetControllerForRenderManager()),
Details<RenderViewHostSwitchedDetails>(&details));
old_render_view_host->Shutdown();
diff --git a/chrome/browser/tab_contents/render_view_host_manager.h b/chrome/browser/tab_contents/render_view_host_manager.h
index b3a5b25..15ee081 100644
--- a/chrome/browser/tab_contents/render_view_host_manager.h
+++ b/chrome/browser/tab_contents/render_view_host_manager.h
@@ -47,7 +47,7 @@ class RenderViewHostManager : public NotificationObserver {
RenderViewHost* render_view_host) = 0;
virtual void UpdateRenderViewSizeForRenderManager() = 0;
virtual void NotifySwappedFromRenderManager() = 0;
- virtual NavigationController* GetControllerForRenderManager() = 0;
+ virtual NavigationController& GetControllerForRenderManager() = 0;
// Creates a DOMUI object for the given URL if one applies. Ownership of the
// returned pointer will be passed to the caller. If no DOMUI applies,
@@ -64,8 +64,7 @@ class RenderViewHostManager : public NotificationObserver {
// They must outlive this class. The RenderViewHostDelegate is what will be
// installed into all RenderViewHosts that are created.
//
- // You must call Init() before using this class and Shutdown() before
- // deleting it.
+ // You must call Init() before using this class.
RenderViewHostManager(RenderViewHostDelegate* render_view_delegate,
Delegate* delegate);
~RenderViewHostManager();
@@ -76,9 +75,6 @@ class RenderViewHostManager : public NotificationObserver {
int routing_id,
base::WaitableEvent* modal_dialog_event);
- // Schedules all RenderViewHosts for destruction.
- void Shutdown();
-
// Returns the currently actuive RenderViewHost.
//
// This will be non-NULL between Init() and Shutdown(). You may want to NULL
diff --git a/chrome/browser/tab_contents/render_view_host_manager_unittest.cc b/chrome/browser/tab_contents/render_view_host_manager_unittest.cc
index 02f5473..f0caccd 100644
--- a/chrome/browser/tab_contents/render_view_host_manager_unittest.cc
+++ b/chrome/browser/tab_contents/render_view_host_manager_unittest.cc
@@ -23,27 +23,22 @@ TEST_F(RenderViewHostManagerTest, NewTabPageProcesses) {
NavigateAndCommit(dest);
// Make a second tab.
- WebContents* contents2 = new TestWebContents(profile_.get(), NULL);
- NavigationController* controller2 =
- new NavigationController(contents2, profile_.get());
- contents2->set_controller(controller2);
+ TestWebContents contents2(profile_.get(), NULL);
// Load the two URLs in the second tab. Note that the first navigation creates
// a RVH that's not pending (since there is no cross-site transition), so
// we use the committed one, but the second one is the opposite.
- contents2->controller()->LoadURL(ntp, GURL(), PageTransition::LINK);
- static_cast<TestRenderViewHost*>(contents2->render_manager()->
+ contents2.controller().LoadURL(ntp, GURL(), PageTransition::LINK);
+ static_cast<TestRenderViewHost*>(contents2.render_manager()->
current_host())->SendNavigate(100, ntp);
- contents2->controller()->LoadURL(dest, GURL(), PageTransition::LINK);
- static_cast<TestRenderViewHost*>(contents2->render_manager()->
+ contents2.controller().LoadURL(dest, GURL(), PageTransition::LINK);
+ static_cast<TestRenderViewHost*>(contents2.render_manager()->
pending_render_view_host())->SendNavigate(101, dest);
// The two RVH's should be different in every way.
- EXPECT_NE(rvh()->process(), contents2->render_view_host()->process());
+ EXPECT_NE(rvh()->process(), contents2.render_view_host()->process());
EXPECT_NE(rvh()->site_instance(),
- contents2->render_view_host()->site_instance());
+ contents2.render_view_host()->site_instance());
EXPECT_NE(rvh()->site_instance()->browsing_instance(),
- contents2->render_view_host()->site_instance()->browsing_instance());
-
- contents2->CloseContents();
+ contents2.render_view_host()->site_instance()->browsing_instance());
}
diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc
index ea5a9b5..226ce5b 100644
--- a/chrome/browser/tab_contents/tab_contents.cc
+++ b/chrome/browser/tab_contents/tab_contents.cc
@@ -24,9 +24,9 @@
#include "chrome/views/controls/scrollbar/native_scroll_bar.h"
#endif
-TabContents::TabContents()
+TabContents::TabContents(Profile* profile)
: delegate_(NULL),
- controller_(NULL),
+ controller_(this, profile),
is_loading_(false),
is_crashed_(false),
waiting_for_response_(false),
@@ -45,71 +45,13 @@ void TabContents::RegisterUserPrefs(PrefService* prefs) {
prefs->RegisterBooleanPref(prefs::kBlockPopups, false);
}
-void TabContents::CloseContents() {
- // Destroy our NavigationController, which will Destroy all tabs it owns.
- controller_->Destroy();
- // Note that the controller may have deleted us at this point,
- // so don't touch any member variables here.
-}
-
-void TabContents::Destroy() {
- DCHECK(!is_being_destroyed_);
- is_being_destroyed_ = true;
-
- // First cleanly close all child windows.
- // TODO(mpcomplete): handle case if MaybeCloseChildWindows() already asked
- // some of these to close. CloseWindows is async, so it might get called
- // twice before it runs.
- int size = static_cast<int>(child_windows_.size());
- for (int i = size - 1; i >= 0; --i) {
- ConstrainedWindow* window = child_windows_[i];
- if (window)
- window->CloseConstrainedWindow();
- }
-
- // Notify any lasting InfobarDelegates that have not yet been removed that
- // whatever infobar they were handling in this TabContents has closed,
- // because the TabContents is going away entirely.
- for (int i = 0; i < infobar_delegate_count(); ++i) {
- InfoBarDelegate* delegate = GetInfoBarDelegateAt(i);
- delegate->InfoBarClosed();
- }
- infobar_delegates_.clear();
-
- // Notify any observer that have a reference on this tab contents.
- NotificationService::current()->Notify(
- NotificationType::TAB_CONTENTS_DESTROYED,
- Source<TabContents>(this),
- NotificationService::NoDetails());
-
-#if defined(OS_WIN)
- // If we still have a window handle, destroy it. GetNativeView can return
- // NULL if this contents was part of a window that closed.
- if (GetNativeView())
- ::DestroyWindow(GetNativeView());
-#endif
-
- // Notify our NavigationController. Make sure we are deleted first, so
- // that the controller is the last to die.
- NavigationController* controller = controller_;
-
- delete this;
-
- controller->TabContentsWasDestroyed();
-}
-
-void TabContents::SetupController(Profile* profile) {
- DCHECK(!controller_);
- controller_ = new NavigationController(this, profile);
-}
-
bool TabContents::SupportsURL(GURL* url) {
return true;
}
const GURL& TabContents::GetURL() const {
// We may not have a navigation entry yet
- NavigationEntry* entry = controller_->GetActiveEntry();
+ NavigationEntry* entry = controller_.GetActiveEntry();
return entry ? entry->display_url() : GURL::EmptyGURL();
}
@@ -140,22 +82,22 @@ const std::wstring TabContents::GetDefaultTitle() const {
SkBitmap TabContents::GetFavIcon() const {
// Like GetTitle(), we also want to use the favicon for the last committed
// entry rather than a pending navigation entry.
- NavigationEntry* entry = controller_->GetTransientEntry();
+ NavigationEntry* entry = controller_.GetTransientEntry();
if (entry)
return entry->favicon().bitmap();
- entry = controller_->GetLastCommittedEntry();
+ entry = controller_.GetLastCommittedEntry();
if (entry)
return entry->favicon().bitmap();
- else if (controller_->LoadingURLLazily())
- return controller_->GetLazyFavIcon();
+ else if (controller_.LoadingURLLazily())
+ return controller_.GetLazyFavIcon();
return SkBitmap();
}
#if defined(OS_WIN)
SecurityStyle TabContents::GetSecurityStyle() const {
// We may not have a navigation entry yet.
- NavigationEntry* entry = controller_->GetActiveEntry();
+ NavigationEntry* entry = controller_.GetActiveEntry();
return entry ? entry->ssl().security_style() : SECURITY_STYLE_UNKNOWN;
}
@@ -165,7 +107,7 @@ bool TabContents::GetSSLEVText(std::wstring* ev_text,
ev_text->clear();
ev_tooltip_text->clear();
- NavigationEntry* entry = controller_->GetActiveEntry();
+ NavigationEntry* entry = controller_.GetActiveEntry();
if (!entry ||
net::IsCertStatusError(entry->ssl().cert_status()) ||
((entry->ssl().cert_status() & net::CERT_STATUS_IS_EV) == 0))
@@ -211,8 +153,8 @@ void TabContents::OpenURL(const GURL& url, const GURL& referrer,
bool TabContents::NavigateToPendingEntry(bool reload) {
// Our benavior is just to report that the entry was committed.
string16 default_title = WideToUTF16Hack(GetDefaultTitle());
- controller()->pending_entry()->set_title(default_title);
- controller()->CommitPendingEntry();
+ controller_.pending_entry()->set_title(default_title);
+ controller_.CommitPendingEntry();
return true;
}
@@ -302,9 +244,8 @@ void TabContents::AddInfoBar(InfoBarDelegate* delegate) {
// added. We use this notification to expire InfoBars that need to expire on
// page transitions.
if (infobar_delegates_.size() == 1) {
- DCHECK(controller());
registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED,
- Source<NavigationController>(controller()));
+ Source<NavigationController>(&controller_));
}
}
@@ -322,7 +263,7 @@ void TabContents::RemoveInfoBar(InfoBarDelegate* delegate) {
// Remove ourselves as an observer if we are tracking no more InfoBars.
if (infobar_delegates_.empty()) {
registrar_.Remove(this, NotificationType::NAV_ENTRY_COMMITTED,
- Source<NavigationController>(controller()));
+ Source<NavigationController>(&controller_));
}
}
}
diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h
index 26dda95..aa636f3 100644
--- a/chrome/browser/tab_contents/tab_contents.h
+++ b/chrome/browser/tab_contents/tab_contents.h
@@ -44,23 +44,8 @@ class SkBitmap;
class SiteInstance;
class WebContents;
-// Describes what goes in the main content area of a tab. For example,
-// the WebContents is one such thing.
-//
-// When instantiating a new TabContents explicitly, the TabContents will not
-// have an associated NavigationController. To setup a NavigationController
-// for the TabContents, its SetupController method should be called.
-//
-// Once they reside within a NavigationController, TabContents objects are
-// owned by that NavigationController. When the active TabContents within that
-// NavigationController is closed, that TabContents destroys the
-// NavigationController, which then destroys all of the TabContentses in it.
-//
-// NOTE: When the NavigationController is navigated to an URL corresponding to
-// a different type of TabContents (see the TabContents::TypeForURL method),
-// the NavigationController makes the active TabContents inactive, notifies the
-// TabContentsDelegate that the TabContents is being replaced, and then
-// activates the new TabContents.
+// Describes what goes in the main content area of a tab. WebContents is
+// the only type of TabContents, and these should be merged together.
class TabContents : public PageNavigator,
public NotificationObserver {
public:
@@ -77,22 +62,9 @@ class TabContents : public PageNavigator,
INVALIDATE_EVERYTHING = 0xFFFFFFFF
};
- static void RegisterUserPrefs(PrefService* prefs);
-
- // Creation & destruction ----------------------------------------------------
-
- // Request this tab to shut down. This kills the tab's NavigationController,
- // which then Destroy()s all tabs it controls.
- void CloseContents();
+ virtual ~TabContents();
- // Unregister/shut down any pending tasks involving this tab.
- // This is called as the tab is shutting down, before the
- // NavigationController (and consequently profile) are gone.
- //
- // If you override this, be sure to call this implementation at the end
- // of yours.
- // See also Close().
- virtual void Destroy() = 0;
+ static void RegisterUserPrefs(PrefService* prefs);
// Intrinsic tab state -------------------------------------------------------
@@ -116,27 +88,13 @@ class TabContents : public PageNavigator,
TabContentsDelegate* delegate() const { return delegate_; }
void set_delegate(TabContentsDelegate* d) { delegate_ = d; }
- // This can only be null if the TabContents has been created but
- // SetupController has not been called. The controller should always outlive
- // its TabContents.
- NavigationController* controller() const { return controller_; }
- void set_controller(NavigationController* c) { controller_ = c; }
-
- // Sets up a new NavigationController for this TabContents.
- // |profile| is the user profile that should be associated with
- // the new controller.
- //
- // TODO(brettw) this seems bogus and I couldn't find any legitimate need for
- // it. I think it should be passed in the constructor.
- void SetupController(Profile* profile);
+ // Gets the controller for this tab contents.
+ NavigationController& controller() { return controller_; }
+ const NavigationController& controller() const { return controller_; }
// Returns the user profile associated with this TabContents (via the
- // NavigationController). This will return NULL if there isn't yet a
- // NavigationController on this TabContents.
- // TODO(darin): make it so that controller_ can never be null
- Profile* profile() const {
- return controller_ ? controller_->profile() : NULL;
- }
+ // NavigationController).
+ Profile* profile() const { return controller_.profile(); }
// Returns whether this tab contents supports the provided URL.This method
// matches the tab contents type with the result of TypeForURL(). |url| points
@@ -273,6 +231,10 @@ class TabContents : public PageNavigator,
// Called on a TabContents when it isn't a popup, but a new window.
virtual void DisassociateFromPopupCount() = 0;
+ // Creates a new TabContents with the same state as this one. The returned
+ // heap-allocated pointer is owned by the caller.
+ virtual TabContents* Clone() = 0;
+
// Window management ---------------------------------------------------------
#if defined(OS_WIN)
@@ -386,15 +348,7 @@ class TabContents : public PageNavigator,
// automation purposes.
friend class AutomationProvider;
- TabContents();
-
- // NOTE: the TabContents destructor can run after the NavigationController
- // has gone away, so any complicated unregistering that expects the profile
- // or other shared objects to still be around does not belong in a
- // destructor.
- // For those purposes, instead see Destroy().
- // Protected so that others don't try to delete this directly.
- virtual ~TabContents();
+ TabContents(Profile* profile);
// Changes the IsLoading state and notifies delegate as needed
// |details| is used to provide details on the load that just finished
@@ -432,7 +386,7 @@ class TabContents : public PageNavigator,
// Data ----------------------------------------------------------------------
TabContentsDelegate* delegate_;
- NavigationController* controller_;
+ NavigationController controller_;
PropertyBag property_bag_;
diff --git a/chrome/browser/tab_contents/web_contents.cc b/chrome/browser/tab_contents/web_contents.cc
index bf70542..8592522 100644
--- a/chrome/browser/tab_contents/web_contents.cc
+++ b/chrome/browser/tab_contents/web_contents.cc
@@ -203,7 +203,8 @@ WebContents::WebContents(Profile* profile,
SiteInstance* site_instance,
int routing_id,
base::WaitableEvent* modal_dialog_event)
- : view_(WebContentsView::Create(this)),
+ : TabContents(profile),
+ view_(WebContentsView::Create(this)),
ALLOW_THIS_IN_INITIALIZER_LIST(render_manager_(this, this)),
printing_(*this),
notify_disconnection_(false),
@@ -234,14 +235,12 @@ WebContents::WebContents(Profile* profile,
}
// Register for notifications about URL starredness changing on any profile.
- NotificationService::current()->AddObserver(
- this, NotificationType::URLS_STARRED, NotificationService::AllSources());
- NotificationService::current()->AddObserver(
- this, NotificationType::BOOKMARK_MODEL_LOADED,
- NotificationService::AllSources());
- NotificationService::current()->AddObserver(
- this, NotificationType::RENDER_WIDGET_HOST_DESTROYED,
- NotificationService::AllSources());
+ registrar_.Add(this, NotificationType::URLS_STARRED,
+ NotificationService::AllSources());
+ registrar_.Add(this, NotificationType::BOOKMARK_MODEL_LOADED,
+ NotificationService::AllSources());
+ registrar_.Add(this, NotificationType::RENDER_WIDGET_HOST_DESTROYED,
+ NotificationService::AllSources());
// Keep a global copy of the previous search string (if any).
static string16 global_last_search = string16();
@@ -249,11 +248,60 @@ WebContents::WebContents(Profile* profile,
}
WebContents::~WebContents() {
+ is_being_destroyed_ = true;
+
+ // We don't want any notifications while we're runnign our destructor.
+ registrar_.RemoveAll();
+
+ // Unregister the notifications of all observed prefs change.
+ PrefService* prefs = profile()->GetPrefs();
+ if (prefs) {
+ for (int i = 0; i < kPrefsToObserveLength; ++i)
+ prefs->RemovePrefObserver(kPrefsToObserve[i], this);
+ }
+
+ // Clean up subwindows like plugins and the find in page bar.
+ view_->OnContentsDestroy();
+
+ NotifyDisconnected();
+ HungRendererWarning::HideForWebContents(this);
+
if (pending_install_.callback_functor)
pending_install_.callback_functor->Cancel();
- NotificationService::current()->RemoveObserver(
- this, NotificationType::RENDER_WIDGET_HOST_DESTROYED,
- NotificationService::AllSources());
+
+ // First cleanly close all child windows.
+ // TODO(mpcomplete): handle case if MaybeCloseChildWindows() already asked
+ // some of these to close. CloseWindows is async, so it might get called
+ // twice before it runs.
+ int size = static_cast<int>(child_windows_.size());
+ for (int i = size - 1; i >= 0; --i) {
+ ConstrainedWindow* window = child_windows_[i];
+ if (window)
+ window->CloseConstrainedWindow();
+ }
+
+ // Notify any lasting InfobarDelegates that have not yet been removed that
+ // whatever infobar they were handling in this TabContents has closed,
+ // because the TabContents is going away entirely.
+ for (int i = 0; i < infobar_delegate_count(); ++i) {
+ InfoBarDelegate* delegate = GetInfoBarDelegateAt(i);
+ delegate->InfoBarClosed();
+ }
+ infobar_delegates_.clear();
+
+ // Notify any observer that have a reference on this tab contents.
+ NotificationService::current()->Notify(
+ NotificationType::TAB_CONTENTS_DESTROYED,
+ Source<TabContents>(this),
+ NotificationService::NoDetails());
+
+ // TODO(brettw) this should be moved to the view.
+#if defined(OS_WIN)
+ // If we still have a window handle, destroy it. GetNativeView can return
+ // NULL if this contents was part of a window that closed.
+ if (GetNativeView())
+ ::DestroyWindow(GetNativeView());
+#endif
}
// static
@@ -330,78 +378,6 @@ PluginInstaller* WebContents::GetPluginInstaller() {
return plugin_installer_.get();
}
-void WebContents::Destroy() {
- DCHECK(!is_being_destroyed_);
- is_being_destroyed_ = true;
-
- // Tell the notification service we no longer want notifications.
- NotificationService::current()->RemoveObserver(
- this, NotificationType::URLS_STARRED, NotificationService::AllSources());
- NotificationService::current()->RemoveObserver(
- this, NotificationType::BOOKMARK_MODEL_LOADED,
- NotificationService::AllSources());
-
- // Destroy the print manager right now since a Print command may be pending.
- printing_.Destroy();
-
- // Unregister the notifications of all observed prefs change.
- PrefService* prefs = profile()->GetPrefs();
- if (prefs) {
- for (int i = 0; i < kPrefsToObserveLength; ++i)
- prefs->RemovePrefObserver(kPrefsToObserve[i], this);
- }
-
- cancelable_consumer_.CancelAllRequests();
-
- // Clean up subwindows like plugins and the find in page bar.
- view_->OnContentsDestroy();
-
- NotifyDisconnected();
- HungRendererWarning::HideForWebContents(this);
- render_manager_.Shutdown();
-
- // First cleanly close all child windows.
- // TODO(mpcomplete): handle case if MaybeCloseChildWindows() already asked
- // some of these to close. CloseWindows is async, so it might get called
- // twice before it runs.
- int size = static_cast<int>(child_windows_.size());
- for (int i = size - 1; i >= 0; --i) {
- ConstrainedWindow* window = child_windows_[i];
- if (window)
- window->CloseConstrainedWindow();
- }
-
- // Notify any lasting InfobarDelegates that have not yet been removed that
- // whatever infobar they were handling in this TabContents has closed,
- // because the TabContents is going away entirely.
- for (int i = 0; i < infobar_delegate_count(); ++i) {
- InfoBarDelegate* delegate = GetInfoBarDelegateAt(i);
- delegate->InfoBarClosed();
- }
- infobar_delegates_.clear();
-
- // Notify any observer that have a reference on this tab contents.
- NotificationService::current()->Notify(
- NotificationType::TAB_CONTENTS_DESTROYED,
- Source<TabContents>(this),
- NotificationService::NoDetails());
-
-#if defined(OS_WIN)
- // If we still have a window handle, destroy it. GetNativeView can return
- // NULL if this contents was part of a window that closed.
- if (GetNativeView())
- ::DestroyWindow(GetNativeView());
-#endif
-
- // Notify our NavigationController. Make sure we are deleted first, so
- // that the controller is the last to die.
- NavigationController* controller = controller_;
-
- delete this;
-
- controller->TabContentsWasDestroyed();
-}
-
const string16& WebContents::GetTitle() const {
DOMUI* our_dom_ui = render_manager_.pending_dom_ui() ?
render_manager_.pending_dom_ui() : render_manager_.dom_ui();
@@ -418,15 +394,15 @@ const string16& WebContents::GetTitle() const {
// title.
// The exception is with transient pages, for which we really want to use
// their title, as they are not committed.
- NavigationEntry* entry = controller_->GetTransientEntry();
+ NavigationEntry* entry = controller_.GetTransientEntry();
if (entry)
- return entry->GetTitleForDisplay(controller_);
+ return entry->GetTitleForDisplay(&controller_);
- entry = controller_->GetLastCommittedEntry();
+ entry = controller_.GetLastCommittedEntry();
if (entry)
- return entry->GetTitleForDisplay(controller_);
- else if (controller_->LoadingURLLazily())
- return controller_->GetLazyTitle();
+ return entry->GetTitleForDisplay(&controller_);
+ else if (controller_.LoadingURLLazily())
+ return controller_.GetLazyTitle();
return EmptyString16();
}
@@ -443,7 +419,7 @@ bool WebContents::ShouldDisplayURL() {
bool WebContents::ShouldDisplayFavIcon() {
// Always display a throbber during pending loads.
- if (controller()->GetLastCommittedEntry() && controller()->pending_entry())
+ if (controller_.GetLastCommittedEntry() && controller_.pending_entry())
return true;
DOMUI* dom_ui = GetDOMUIForCurrentState();
@@ -480,7 +456,7 @@ std::wstring WebContents::GetStatusText() const {
}
bool WebContents::NavigateToPendingEntry(bool reload) {
- const NavigationEntry& entry = *controller()->pending_entry();
+ const NavigationEntry& entry = *controller_.pending_entry();
RenderViewHost* dest_render_view_host = render_manager_.Navigate(entry);
if (!dest_render_view_host)
@@ -543,15 +519,19 @@ void WebContents::DisassociateFromPopupCount() {
render_view_host()->DisassociateFromPopupCount();
}
-void WebContents::DidBecomeSelected() {
- if (controller_)
- controller_->SetActive(true);
+TabContents* WebContents::Clone() {
+ // We create a new SiteInstance so that the new tab won't share processes
+ // with the old one. This can be changed in the future if we need it to share
+ // processes for some reason.
+ TabContents* tc = new WebContents(profile(),
+ SiteInstance::CreateSiteInstance(profile()),
+ MSG_ROUTING_NONE, NULL);
+ tc->controller().CopyStateFrom(controller_);
+ return tc;
+}
-#if defined(OS_WIN)
- // Invalidate all descendants. (take care to exclude invalidating ourselves!)
- // TODO(brettw) this should be moved to the view!
-// EnumChildWindows(GetNativeView(), InvalidateWindow, 0);
-#endif
+void WebContents::DidBecomeSelected() {
+ controller_.SetActive(true);
if (render_widget_host_view())
render_widget_host_view()->DidBecomeSelected();
@@ -612,7 +592,7 @@ bool WebContents::IsBookmarkBarAlwaysVisible() {
// See GetDOMUIForCurrentState() comment for more info. This case is very
// similar, but for non-first loads, we want to use the committed entry. This
// is so the bookmarks bar disappears at the same time the page does.
- if (controller()->GetLastCommittedEntry()) {
+ if (controller_.GetLastCommittedEntry()) {
// Not the first load, always use the committed DOM UI.
if (render_manager_.dom_ui())
return render_manager_.dom_ui()->force_bookmark_bar_visible();
@@ -677,7 +657,7 @@ void WebContents::GetContainerBounds(gfx::Rect *out) const {
}
void WebContents::CreateShortcut() {
- NavigationEntry* entry = controller()->GetLastCommittedEntry();
+ NavigationEntry* entry = controller_.GetLastCommittedEntry();
if (!entry)
return;
@@ -795,7 +775,7 @@ bool WebContents::PrintNow() {
}
bool WebContents::IsActiveEntry(int32 page_id) {
- NavigationEntry* active_entry = controller()->GetActiveEntry();
+ NavigationEntry* active_entry = controller_.GetActiveEntry();
return (active_entry != NULL &&
active_entry->site_instance() == GetSiteInstance() &&
active_entry->page_id() == page_id);
@@ -835,7 +815,7 @@ void WebContents::SetIsLoading(bool is_loading,
if (details)
det = Details<LoadNotificationDetails>(details);
NotificationService::current()->Notify(type,
- Source<NavigationController>(this->controller()),
+ Source<NavigationController>(&controller_),
det);
}
@@ -852,9 +832,7 @@ Profile* WebContents::GetProfile() const {
}
void WebContents::RenderViewCreated(RenderViewHost* render_view_host) {
- if (!controller())
- return;
- NavigationEntry* entry = controller()->GetActiveEntry();
+ NavigationEntry* entry = controller_.GetActiveEntry();
if (!entry)
return;
@@ -906,10 +884,6 @@ void WebContents::DidNavigate(RenderViewHost* rvh,
if (PageTransition::IsMainFrame(params.transition))
render_manager_.DidNavigateMainFrame(rvh);
- // We can't do anything about navigations when we're inactive.
- if (!controller())
- return;
-
// Update the site of the SiteInstance if it doesn't have one yet.
if (!GetSiteInstance()->has_site())
GetSiteInstance()->SetSite(params.url);
@@ -926,7 +900,7 @@ void WebContents::DidNavigate(RenderViewHost* rvh,
contents_mime_type_ = params.contents_mime_type;
NavigationController::LoadCommittedDetails details;
- if (!controller()->RendererDidNavigate(params, &details))
+ if (!controller_.RendererDidNavigate(params, &details))
return; // No navigation happened.
// DO NOT ADD MORE STUFF TO THIS FUNCTION! Your component should either listen
@@ -944,8 +918,6 @@ void WebContents::UpdateState(RenderViewHost* rvh,
int32 page_id,
const std::string& state) {
DCHECK(rvh == render_view_host());
- if (!controller())
- return;
// We must be prepared to handle state updates for any page, these occur
// when the user is scrolling and entering form data, as well as when we're
@@ -953,49 +925,43 @@ void WebContents::UpdateState(RenderViewHost* rvh,
// the next page. The navigation controller will look up the appropriate
// NavigationEntry and update it when it is notified via the delegate.
- int entry_index = controller()->GetEntryIndexWithPageID(
+ int entry_index = controller_.GetEntryIndexWithPageID(
GetSiteInstance(), page_id);
if (entry_index < 0)
return;
- NavigationEntry* entry = controller()->GetEntryAtIndex(entry_index);
+ NavigationEntry* entry = controller_.GetEntryAtIndex(entry_index);
if (state == entry->content_state())
return; // Nothing to update.
entry->set_content_state(state);
- controller()->NotifyEntryChanged(entry, entry_index);
+ controller_.NotifyEntryChanged(entry, entry_index);
}
void WebContents::UpdateTitle(RenderViewHost* rvh,
int32 page_id, const std::wstring& title) {
- if (!controller())
- return;
-
// If we have a title, that's a pretty good indication that we've started
// getting useful data.
SetNotWaitingForResponse();
DCHECK(rvh == render_view_host());
- NavigationEntry* entry = controller()->GetEntryWithPageID(GetSiteInstance(),
+ NavigationEntry* entry = controller_.GetEntryWithPageID(GetSiteInstance(),
page_id);
if (!entry || !UpdateTitleForEntry(entry, title))
return;
// Broadcast notifications when the UI should be updated.
- if (entry == controller()->GetEntryAtOffset(0))
+ if (entry == controller_.GetEntryAtOffset(0))
NotifyNavigationStateChanged(INVALIDATE_TITLE);
}
void WebContents::UpdateFeedList(
RenderViewHost* rvh, const ViewHostMsg_UpdateFeedList_Params& params) {
- if (!controller())
- return;
-
// We might have an old RenderViewHost sending messages, and we should ignore
// those messages.
if (rvh != render_view_host())
return;
- NavigationEntry* entry = controller()->GetEntryWithPageID(GetSiteInstance(),
+ NavigationEntry* entry = controller_.GetEntryWithPageID(GetSiteInstance(),
params.page_id);
if (!entry)
return;
@@ -1003,7 +969,7 @@ void WebContents::UpdateFeedList(
entry->set_feedlist(params.feedlist);
// Broadcast notifications when the UI should be updated.
- if (entry == controller()->GetEntryAtOffset(0))
+ if (entry == controller_.GetEntryAtOffset(0))
NotifyNavigationStateChanged(INVALIDATE_FEEDLIST);
}
@@ -1045,24 +1011,23 @@ void WebContents::DidStartLoading(RenderViewHost* rvh, int32 page_id) {
void WebContents::DidStopLoading(RenderViewHost* rvh, int32 page_id) {
scoped_ptr<LoadNotificationDetails> details;
- if (controller()) {
- NavigationEntry* entry = controller()->GetActiveEntry();
- // An entry may not exist for a stop when loading an initial blank page or
- // if an iframe injected by script into a blank page finishes loading.
- if (entry) {
- scoped_ptr<base::ProcessMetrics> metrics(
- base::ProcessMetrics::CreateProcessMetrics(
- process()->process().handle()));
-
- TimeDelta elapsed = TimeTicks::Now() - current_load_start_;
-
- details.reset(new LoadNotificationDetails(
- entry->display_url(),
- entry->transition_type(),
- elapsed,
- controller(),
- controller()->GetCurrentEntryIndex()));
- }
+
+ NavigationEntry* entry = controller_.GetActiveEntry();
+ // An entry may not exist for a stop when loading an initial blank page or
+ // if an iframe injected by script into a blank page finishes loading.
+ if (entry) {
+ scoped_ptr<base::ProcessMetrics> metrics(
+ base::ProcessMetrics::CreateProcessMetrics(
+ process()->process().handle()));
+
+ TimeDelta elapsed = TimeTicks::Now() - current_load_start_;
+
+ details.reset(new LoadNotificationDetails(
+ entry->display_url(),
+ entry->transition_type(),
+ elapsed,
+ &controller_,
+ controller_.GetCurrentEntryIndex()));
}
// Tell PasswordManager we've finished a page load, which serves as a
@@ -1077,11 +1042,11 @@ void WebContents::DidStartProvisionalLoadForFrame(
bool is_main_frame,
const GURL& url) {
ProvisionalLoadDetails details(is_main_frame,
- controller()->IsURLInPageNavigation(url),
+ controller_.IsURLInPageNavigation(url),
url, std::string(), false);
NotificationService::current()->Notify(
NotificationType::FRAME_PROVISIONAL_LOAD_START,
- Source<NavigationController>(controller()),
+ Source<NavigationController>(&controller_),
Details<ProvisionalLoadDetails>(&details));
}
@@ -1090,9 +1055,9 @@ void WebContents::DidRedirectProvisionalLoad(int32 page_id,
const GURL& target_url) {
NavigationEntry* entry;
if (page_id == -1)
- entry = controller()->pending_entry();
+ entry = controller_.pending_entry();
else
- entry = controller()->GetEntryWithPageID(GetSiteInstance(), page_id);
+ entry = controller_.GetEntryWithPageID(GetSiteInstance(), page_id);
if (!entry || entry->url() != source_url)
return;
entry->set_url(target_url);
@@ -1103,9 +1068,6 @@ void WebContents::DidLoadResourceFromMemoryCache(
const std::string& frame_origin,
const std::string& main_frame_origin,
const std::string& security_info) {
- if (!controller())
- return;
-
// Send out a notification that we loaded a resource from our memory cache.
int cert_id = 0, cert_status = 0, security_bits = 0;
SSLManager::DeserializeSecurityInfo(security_info,
@@ -1116,7 +1078,7 @@ void WebContents::DidLoadResourceFromMemoryCache(
NotificationService::current()->Notify(
NotificationType::LOAD_FROM_MEMORY_CACHE,
- Source<NavigationController>(controller()),
+ Source<NavigationController>(&controller_),
Details<LoadFromMemoryCacheDetails>(&details));
}
@@ -1126,9 +1088,6 @@ void WebContents::DidFailProvisionalLoadWithError(
int error_code,
const GURL& url,
bool showing_repost_interstitial) {
- if (!controller())
- return;
-
if (net::ERR_ABORTED == error_code) {
// EVIL HACK ALERT! Ignore failed loads when we're showing interstitials.
// This means that the interstitial won't be torn down properly, which is
@@ -1157,22 +1116,22 @@ void WebContents::DidFailProvisionalLoadWithError(
// decided to download the file instead of load it). Only discard the
// pending entry if the URLs match, otherwise the user initiated a navigate
// before the page loaded so that the discard would discard the wrong entry.
- NavigationEntry* pending_entry = controller()->pending_entry();
+ NavigationEntry* pending_entry = controller_.pending_entry();
if (pending_entry && pending_entry->url() == url)
- controller()->DiscardNonCommittedEntries();
+ controller_.DiscardNonCommittedEntries();
render_manager_.RendererAbortedProvisionalLoad(render_view_host);
}
// Send out a notification that we failed a provisional load with an error.
ProvisionalLoadDetails details(is_main_frame,
- controller()->IsURLInPageNavigation(url),
+ controller_.IsURLInPageNavigation(url),
url, std::string(), false);
details.set_error_code(error_code);
NotificationService::current()->Notify(
NotificationType::FAIL_PROVISIONAL_LOAD_WITH_ERROR,
- Source<NavigationController>(controller()),
+ Source<NavigationController>(&controller_),
Details<ProvisionalLoadDetails>(&details));
}
@@ -1244,21 +1203,14 @@ void WebContents::ProcessExternalHostMessage(const std::string& message,
}
void WebContents::GoToEntryAtOffset(int offset) {
- if (!controller())
- return;
- controller()->GoToOffset(offset);
+ controller_.GoToOffset(offset);
}
void WebContents::GetHistoryListCount(int* back_list_count,
int* forward_list_count) {
- *back_list_count = 0;
- *forward_list_count = 0;
-
- if (controller()) {
- int current_index = controller()->last_committed_entry_index();
- *back_list_count = current_index;
- *forward_list_count = controller()->entry_count() - current_index - 1;
- }
+ int current_index = controller_.last_committed_entry_index();
+ *back_list_count = current_index;
+ *forward_list_count = controller_.entry_count() - current_index - 1;
}
void WebContents::RunFileChooser(bool multiple_files,
@@ -1354,7 +1306,7 @@ void WebContents::PageHasOSDD(RenderViewHost* render_view_host,
bool autodetected) {
// Make sure page_id is the current page, and the TemplateURLModel is loaded.
DCHECK(url.is_valid());
- if (!controller() || !IsActiveEntry(page_id))
+ if (!IsActiveEntry(page_id))
return;
TemplateURLModel* url_model = profile()->GetTemplateURLModel();
if (!url_model)
@@ -1369,18 +1321,18 @@ void WebContents::PageHasOSDD(RenderViewHost* render_view_host,
if (profile()->IsOffTheRecord())
return;
- const NavigationEntry* entry = controller()->GetLastCommittedEntry();
+ const NavigationEntry* entry = controller_.GetLastCommittedEntry();
DCHECK(entry);
const NavigationEntry* base_entry = entry;
if (IsFormSubmit(base_entry)) {
// If the current page is a form submit, find the last page that was not
// a form submit and use its url to generate the keyword from.
- int index = controller()->last_committed_entry_index() - 1;
- while (index >= 0 && IsFormSubmit(controller()->GetEntryAtIndex(index)))
+ int index = controller_.last_committed_entry_index() - 1;
+ while (index >= 0 && IsFormSubmit(controller_.GetEntryAtIndex(index)))
index--;
if (index >= 0)
- base_entry = controller()->GetEntryAtIndex(index);
+ base_entry = controller_.GetEntryAtIndex(index);
else
base_entry = NULL;
}
@@ -1633,9 +1585,7 @@ DOMUI* WebContents::CreateDOMUIForRenderManager(const GURL& url) {
NavigationEntry*
WebContents::GetLastCommittedNavigationEntryForRenderManager() {
- if (!controller())
- return NULL;
- return controller()->GetLastCommittedEntry();
+ return controller_.GetLastCommittedEntry();
}
bool WebContents::CreateRenderViewForRenderManager(
@@ -1694,7 +1644,7 @@ void WebContents::Observe(NotificationType type,
break;
case NotificationType::NAV_ENTRY_COMMITTED: {
- DCHECK(controller() == Source<NavigationController>(source).ptr());
+ DCHECK(&controller_ == Source<NavigationController>(source).ptr());
NavigationController::LoadCommittedDetails& committed_details =
*(Details<NavigationController::LoadCommittedDetails>(details).ptr());
@@ -1828,7 +1778,7 @@ void WebContents::UpdateWebPreferences() {
void WebContents::OnGearsCreateShortcutDone(
const GearsShortcutData2& shortcut_data, bool success) {
- NavigationEntry* current_entry = controller()->GetLastCommittedEntry();
+ NavigationEntry* current_entry = controller_.GetLastCommittedEntry();
bool same_page =
current_entry && pending_install_.page_id == current_entry->page_id();
@@ -1852,7 +1802,7 @@ void WebContents::UpdateMaxPageIDIfNecessary(SiteInstance* site_instance,
// Note that it is ok for conflicting page IDs to exist in another tab
// (i.e., NavigationController), but if any page ID is larger than the max,
// the back/forward list will get confused.
- int max_restored_page_id = controller()->max_restored_page_id();
+ int max_restored_page_id = controller_.max_restored_page_id();
if (max_restored_page_id > 0) {
int curr_max_page_id = site_instance->max_page_id();
if (max_restored_page_id > curr_max_page_id) {
@@ -1967,14 +1917,13 @@ void WebContents::NotifyDisconnected() {
void WebContents::GenerateKeywordIfNecessary(
const ViewHostMsg_FrameNavigate_Params& params) {
- DCHECK(controller());
if (!params.searchable_form_url.is_valid())
return;
if (profile()->IsOffTheRecord())
return;
- int last_index = controller()->last_committed_entry_index();
+ int last_index = controller_.last_committed_entry_index();
// When there was no previous page, the last index will be 0. This is
// normally due to a form submit that opened in a new tab.
// TODO(brettw) bug 916126: we should support keywords when form submits
@@ -1982,7 +1931,7 @@ void WebContents::GenerateKeywordIfNecessary(
if (last_index <= 0)
return;
const NavigationEntry* previous_entry =
- controller()->GetEntryAtIndex(last_index - 1);
+ controller_.GetEntryAtIndex(last_index - 1);
if (IsFormSubmit(previous_entry)) {
// Only generate a keyword if the previous page wasn't itself a form
// submit.
@@ -2023,9 +1972,9 @@ void WebContents::GenerateKeywordIfNecessary(
new_url->set_short_name(keyword);
new_url->SetURL(url, 0, 0);
new_url->add_input_encoding(params.searchable_form_encoding);
- DCHECK(controller()->GetLastCommittedEntry());
+ DCHECK(controller_.GetLastCommittedEntry());
const GURL& favicon_url =
- controller()->GetLastCommittedEntry()->favicon().url();
+ controller_.GetLastCommittedEntry()->favicon().url();
if (favicon_url.is_valid()) {
new_url->SetFavIconURL(favicon_url);
} else {
@@ -2073,8 +2022,8 @@ DOMUI* WebContents::GetDOMUIForCurrentState() {
//
// - Normal state with no load: committed nav entry + no pending nav entry:
// -> Use committed DOM UI.
- if (controller()->pending_entry() &&
- (controller()->GetLastCommittedEntry() ||
+ if (controller_.pending_entry() &&
+ (controller_.GetLastCommittedEntry() ||
render_manager_.pending_dom_ui()))
return render_manager_.pending_dom_ui();
return render_manager_.dom_ui();
diff --git a/chrome/browser/tab_contents/web_contents.h b/chrome/browser/tab_contents/web_contents.h
index b89efd3..9128868 100644
--- a/chrome/browser/tab_contents/web_contents.h
+++ b/chrome/browser/tab_contents/web_contents.h
@@ -73,6 +73,8 @@ class WebContents : public TabContents,
int routing_id,
base::WaitableEvent* modal_dialog_event);
+ virtual ~WebContents();
+
static void RegisterUserPrefs(PrefService* prefs);
// Getters -------------------------------------------------------------------
@@ -126,7 +128,6 @@ class WebContents : public TabContents,
// TabContents (public overrides) --------------------------------------------
- virtual void Destroy();
virtual WebContents* AsWebContents() { return this; }
const string16& GetTitle() const;
virtual SiteInstance* GetSiteInstance() const;
@@ -139,6 +140,7 @@ class WebContents : public TabContents,
virtual void Copy();
virtual void Paste();
virtual void DisassociateFromPopupCount();
+ virtual TabContents* Clone();
virtual void DidBecomeSelected();
virtual void WasHidden();
virtual void ShowContents();
@@ -292,9 +294,6 @@ class WebContents : public TabContents,
}
protected:
- // Should be deleted via CloseContents.
- virtual ~WebContents();
-
RenderWidgetHostView* render_widget_host_view() const {
return render_manager_.current_view();
}
@@ -453,7 +452,7 @@ class WebContents : public TabContents,
virtual void NotifySwappedFromRenderManager() {
NotifySwapped();
}
- virtual NavigationController* GetControllerForRenderManager() {
+ virtual NavigationController& GetControllerForRenderManager() {
return controller();
}
virtual DOMUI* CreateDOMUIForRenderManager(const GURL& url);
diff --git a/chrome/browser/tab_contents/web_contents_unittest.cc b/chrome/browser/tab_contents/web_contents_unittest.cc
index c5e58e1..207a724 100644
--- a/chrome/browser/tab_contents/web_contents_unittest.cc
+++ b/chrome/browser/tab_contents/web_contents_unittest.cc
@@ -206,7 +206,7 @@ TEST_F(WebContentsTest, UpdateTitle) {
InitNavigateParams(&params, 0, GURL("about:blank"));
NavigationController::LoadCommittedDetails details;
- controller()->RendererDidNavigate(params, &details);
+ controller().RendererDidNavigate(params, &details);
contents()->UpdateTitle(rvh(), 0, L" Lots O' Whitespace\n");
EXPECT_EQ(std::wstring(L"Lots O' Whitespace"),
@@ -221,12 +221,12 @@ TEST_F(WebContentsTest, SimpleNavigation) {
// Navigate to URL
const GURL url("http://www.google.com");
- controller()->LoadURL(url, GURL(), PageTransition::TYPED);
+ controller().LoadURL(url, GURL(), PageTransition::TYPED);
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(instance1, orig_rvh->site_instance());
// Controller's pending entry will have a NULL site instance until we assign
// it in DidNavigate.
- EXPECT_TRUE(controller()->GetActiveEntry()->site_instance() == NULL);
+ EXPECT_TRUE(controller().GetActiveEntry()->site_instance() == NULL);
// DidNavigate from the page
ViewHostMsg_FrameNavigate_Params params;
@@ -237,7 +237,7 @@ TEST_F(WebContentsTest, SimpleNavigation) {
EXPECT_EQ(instance1, orig_rvh->site_instance());
// Controller's entry should now have the SiteInstance, or else we won't be
// able to find it later.
- EXPECT_EQ(instance1, controller()->GetActiveEntry()->site_instance());
+ EXPECT_EQ(instance1, controller().GetActiveEntry()->site_instance());
}
// Test that navigating across a site boundary creates a new RenderViewHost
@@ -251,7 +251,7 @@ TEST_F(WebContentsTest, CrossSiteBoundaries) {
// Navigate to URL. First URL should use first RenderViewHost.
const GURL url("http://www.google.com");
- controller()->LoadURL(url, GURL(), PageTransition::TYPED);
+ controller().LoadURL(url, GURL(), PageTransition::TYPED);
ViewHostMsg_FrameNavigate_Params params1;
InitNavigateParams(&params1, 1, url);
contents()->TestDidNavigate(orig_rvh, params1);
@@ -261,7 +261,7 @@ TEST_F(WebContentsTest, CrossSiteBoundaries) {
// Navigate to new site
const GURL url2("http://www.yahoo.com");
- controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
+ controller().LoadURL(url2, GURL(), PageTransition::TYPED);
EXPECT_TRUE(contents()->cross_navigation_pending());
TestRenderViewHost* pending_rvh = contents()->pending_rvh();
int pending_rvh_delete_count = 0;
@@ -281,7 +281,7 @@ TEST_F(WebContentsTest, CrossSiteBoundaries) {
// Going back should switch SiteInstances again. The first SiteInstance is
// stored in the NavigationEntry, so it should be the same as at the start.
- controller()->GoBack();
+ controller().GoBack();
TestRenderViewHost* goback_rvh = contents()->pending_rvh();
EXPECT_TRUE(contents()->cross_navigation_pending());
@@ -304,7 +304,7 @@ TEST_F(WebContentsTest, CrossSiteBoundariesAfterCrash) {
// Navigate to URL. First URL should use first RenderViewHost.
const GURL url("http://www.google.com");
- controller()->LoadURL(url, GURL(), PageTransition::TYPED);
+ controller().LoadURL(url, GURL(), PageTransition::TYPED);
ViewHostMsg_FrameNavigate_Params params1;
InitNavigateParams(&params1, 1, url);
contents()->TestDidNavigate(orig_rvh, params1);
@@ -317,7 +317,7 @@ TEST_F(WebContentsTest, CrossSiteBoundariesAfterCrash) {
// Navigate to new site. We should not go into PENDING.
const GURL url2("http://www.yahoo.com");
- controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
+ controller().LoadURL(url2, GURL(), PageTransition::TYPED);
TestRenderViewHost* new_rvh = rvh();
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_TRUE(contents()->pending_rvh() == NULL);
@@ -345,24 +345,23 @@ TEST_F(WebContentsTest, NavigateTwoTabsCrossSite) {
// Navigate to URL. First URL should use first RenderViewHost.
const GURL url("http://www.google.com");
- controller()->LoadURL(url, GURL(), PageTransition::TYPED);
+ controller().LoadURL(url, GURL(), PageTransition::TYPED);
ViewHostMsg_FrameNavigate_Params params1;
InitNavigateParams(&params1, 1, url);
contents()->TestDidNavigate(orig_rvh, params1);
// Open a new tab with the same SiteInstance, navigated to the same site.
- TestWebContents* contents2 = new TestWebContents(profile(), instance1);
+ TestWebContents contents2(profile(), instance1);
params1.page_id = 2; // Need this since the site instance is the same (which
// is the scope of page IDs) and we want to consider
// this a new page.
- contents2->transition_cross_site = true;
- contents2->SetupController(profile());
- contents2->controller()->LoadURL(url, GURL(), PageTransition::TYPED);
- contents2->TestDidNavigate(contents2->render_view_host(), params1);
+ contents2.transition_cross_site = true;
+ contents2.controller().LoadURL(url, GURL(), PageTransition::TYPED);
+ contents2.TestDidNavigate(contents2.render_view_host(), params1);
// Navigate first tab to a new site
const GURL url2a("http://www.yahoo.com");
- controller()->LoadURL(url2a, GURL(), PageTransition::TYPED);
+ controller().LoadURL(url2a, GURL(), PageTransition::TYPED);
TestRenderViewHost* pending_rvh_a = contents()->pending_rvh();
ViewHostMsg_FrameNavigate_Params params2a;
InitNavigateParams(&params2a, 1, url2a);
@@ -372,10 +371,10 @@ TEST_F(WebContentsTest, NavigateTwoTabsCrossSite) {
// Navigate second tab to the same site as the first tab
const GURL url2b("http://mail.yahoo.com");
- contents2->controller()->LoadURL(url2b, GURL(), PageTransition::TYPED);
- TestRenderViewHost* pending_rvh_b = contents2->pending_rvh();
+ contents2.controller().LoadURL(url2b, GURL(), PageTransition::TYPED);
+ TestRenderViewHost* pending_rvh_b = contents2.pending_rvh();
EXPECT_TRUE(pending_rvh_b != NULL);
- EXPECT_TRUE(contents2->cross_navigation_pending());
+ EXPECT_TRUE(contents2.cross_navigation_pending());
// NOTE(creis): We used to be in danger of showing a sad tab page here if the
// second tab hadn't navigated somewhere first (bug 1145430). That case is
@@ -383,14 +382,12 @@ TEST_F(WebContentsTest, NavigateTwoTabsCrossSite) {
ViewHostMsg_FrameNavigate_Params params2b;
InitNavigateParams(&params2b, 2, url2b);
- contents2->TestDidNavigate(pending_rvh_b, params2b);
- SiteInstance* instance2b = contents2->GetSiteInstance();
+ contents2.TestDidNavigate(pending_rvh_b, params2b);
+ SiteInstance* instance2b = contents2.GetSiteInstance();
EXPECT_NE(instance1, instance2b);
// Both tabs should now be in the same SiteInstance.
EXPECT_EQ(instance2a, instance2b);
-
- contents2->CloseContents();
}
// Tests that WebContents uses the current URL, not the SiteInstance's site, to
@@ -402,28 +399,27 @@ TEST_F(WebContentsTest, CrossSiteComparesAgainstCurrentPage) {
// Navigate to URL.
const GURL url("http://www.google.com");
- controller()->LoadURL(url, GURL(), PageTransition::TYPED);
+ controller().LoadURL(url, GURL(), PageTransition::TYPED);
ViewHostMsg_FrameNavigate_Params params1;
InitNavigateParams(&params1, 1, url);
contents()->TestDidNavigate(orig_rvh, params1);
// Open a related tab to a second site.
- TestWebContents* contents2 = new TestWebContents(profile(), instance1);
- contents2->transition_cross_site = true;
- contents2->SetupController(profile());
+ TestWebContents contents2(profile(), instance1);
+ contents2.transition_cross_site = true;
const GURL url2("http://www.yahoo.com");
- contents2->controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
+ contents2.controller().LoadURL(url2, GURL(), PageTransition::TYPED);
// The first RVH in contents2 isn't live yet, so we shortcut the cross site
// pending.
TestRenderViewHost* rvh2 = static_cast<TestRenderViewHost*>(
- contents2->render_view_host());
- EXPECT_FALSE(contents2->cross_navigation_pending());
+ contents2.render_view_host());
+ EXPECT_FALSE(contents2.cross_navigation_pending());
ViewHostMsg_FrameNavigate_Params params2;
InitNavigateParams(&params2, 2, url2);
- contents2->TestDidNavigate(rvh2, params2);
- SiteInstance* instance2 = contents2->GetSiteInstance();
+ contents2.TestDidNavigate(rvh2, params2);
+ SiteInstance* instance2 = contents2.GetSiteInstance();
EXPECT_NE(instance1, instance2);
- EXPECT_FALSE(contents2->cross_navigation_pending());
+ EXPECT_FALSE(contents2.cross_navigation_pending());
// Simulate a link click in first tab to second site. Doesn't switch
// SiteInstances, because we don't intercept WebKit navigations.
@@ -437,15 +433,13 @@ TEST_F(WebContentsTest, CrossSiteComparesAgainstCurrentPage) {
// Navigate to the new site. Doesn't switch SiteInstancees, because we
// compare against the current URL, not the SiteInstance's site.
const GURL url3("http://mail.yahoo.com");
- controller()->LoadURL(url3, GURL(), PageTransition::TYPED);
+ controller().LoadURL(url3, GURL(), PageTransition::TYPED);
EXPECT_FALSE(contents()->cross_navigation_pending());
ViewHostMsg_FrameNavigate_Params params4;
InitNavigateParams(&params4, 3, url3);
contents()->TestDidNavigate(orig_rvh, params4);
SiteInstance* instance4 = contents()->GetSiteInstance();
EXPECT_EQ(instance1, instance4);
-
- contents2->CloseContents();
}
// Test that the onbeforeunload and onunload handlers run when navigating
@@ -457,7 +451,7 @@ TEST_F(WebContentsTest, CrossSiteUnloadHandlers) {
// Navigate to URL. First URL should use first RenderViewHost.
const GURL url("http://www.google.com");
- controller()->LoadURL(url, GURL(), PageTransition::TYPED);
+ controller().LoadURL(url, GURL(), PageTransition::TYPED);
ViewHostMsg_FrameNavigate_Params params1;
InitNavigateParams(&params1, 1, url);
contents()->TestDidNavigate(orig_rvh, params1);
@@ -466,13 +460,13 @@ TEST_F(WebContentsTest, CrossSiteUnloadHandlers) {
// Navigate to new site, but simulate an onbeforeunload denial.
const GURL url2("http://www.yahoo.com");
- controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
+ controller().LoadURL(url2, GURL(), PageTransition::TYPED);
orig_rvh->TestOnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, false));
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(orig_rvh, contents()->render_view_host());
// Navigate again, but simulate an onbeforeunload approval.
- controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
+ controller().LoadURL(url2, GURL(), PageTransition::TYPED);
orig_rvh->TestOnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true));
EXPECT_TRUE(contents()->cross_navigation_pending());
TestRenderViewHost* pending_rvh = static_cast<TestRenderViewHost*>(
@@ -500,34 +494,34 @@ TEST_F(WebContentsTest, NavigationEntryContentState) {
// Navigate to URL. There should be no committed entry yet.
const GURL url("http://www.google.com");
- controller()->LoadURL(url, GURL(), PageTransition::TYPED);
- NavigationEntry* entry = controller()->GetLastCommittedEntry();
+ controller().LoadURL(url, GURL(), PageTransition::TYPED);
+ NavigationEntry* entry = controller().GetLastCommittedEntry();
EXPECT_TRUE(entry == NULL);
// Committed entry should have content state after DidNavigate.
ViewHostMsg_FrameNavigate_Params params1;
InitNavigateParams(&params1, 1, url);
contents()->TestDidNavigate(orig_rvh, params1);
- entry = controller()->GetLastCommittedEntry();
+ entry = controller().GetLastCommittedEntry();
EXPECT_FALSE(entry->content_state().empty());
// Navigate to same site.
const GURL url2("http://images.google.com");
- controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
- entry = controller()->GetLastCommittedEntry();
+ controller().LoadURL(url2, GURL(), PageTransition::TYPED);
+ entry = controller().GetLastCommittedEntry();
EXPECT_FALSE(entry->content_state().empty());
// Committed entry should have content state after DidNavigate.
ViewHostMsg_FrameNavigate_Params params2;
InitNavigateParams(&params2, 2, url2);
contents()->TestDidNavigate(orig_rvh, params2);
- entry = controller()->GetLastCommittedEntry();
+ entry = controller().GetLastCommittedEntry();
EXPECT_FALSE(entry->content_state().empty());
// Now go back. Committed entry should still have content state.
- controller()->GoBack();
+ controller().GoBack();
contents()->TestDidNavigate(orig_rvh, params1);
- entry = controller()->GetLastCommittedEntry();
+ entry = controller().GetLastCommittedEntry();
EXPECT_FALSE(entry->content_state().empty());
}
@@ -545,7 +539,7 @@ TEST_F(WebContentsTest, NavigationEntryContentStateNewWindow) {
contents()->TestDidNavigate(orig_rvh, params1);
// Should have a content state here.
- NavigationEntry* entry = controller()->GetLastCommittedEntry();
+ NavigationEntry* entry = controller().GetLastCommittedEntry();
EXPECT_FALSE(entry->content_state().empty());
}
@@ -577,10 +571,10 @@ TEST_F(WebContentsTest,
// Navigate to a page.
GURL url1("http://www.google.com");
rvh()->SendNavigate(1, url1);
- EXPECT_EQ(1, controller()->entry_count());
+ EXPECT_EQ(1, controller().entry_count());
// Initiate a browser navigation that will trigger the interstitial
- controller()->LoadURL(GURL("http://www.evil.com"), GURL(),
+ controller().LoadURL(GURL("http://www.evil.com"), GURL(),
PageTransition::TYPED);
// Show an interstitial.
@@ -601,7 +595,7 @@ TEST_F(WebContentsTest,
EXPECT_TRUE(interstitial->is_showing());
EXPECT_TRUE(contents()->showing_interstitial_page());
EXPECT_TRUE(contents()->interstitial_page() == interstitial);
- NavigationEntry* entry = controller()->GetActiveEntry();
+ NavigationEntry* entry = controller().GetActiveEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->url() == url2);
@@ -611,10 +605,10 @@ TEST_F(WebContentsTest,
EXPECT_EQ(TestInterstitialPage::CANCELED, state);
EXPECT_FALSE(contents()->showing_interstitial_page());
EXPECT_TRUE(contents()->interstitial_page() == NULL);
- entry = controller()->GetActiveEntry();
+ entry = controller().GetActiveEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->url() == url1);
- EXPECT_EQ(1, controller()->entry_count());
+ EXPECT_EQ(1, controller().entry_count());
}
// Test navigating to a page (with the navigation initiated from the renderer,
@@ -625,7 +619,7 @@ TEST_F(WebContentsTest,
// Navigate to a page.
GURL url1("http://www.google.com");
rvh()->SendNavigate(1, url1);
- EXPECT_EQ(1, controller()->entry_count());
+ EXPECT_EQ(1, controller().entry_count());
// Show an interstitial (no pending entry, the interstitial would have been
// triggered by clicking on a link).
@@ -646,7 +640,7 @@ TEST_F(WebContentsTest,
EXPECT_TRUE(interstitial->is_showing());
EXPECT_TRUE(contents()->showing_interstitial_page());
EXPECT_TRUE(contents()->interstitial_page() == interstitial);
- NavigationEntry* entry = controller()->GetActiveEntry();
+ NavigationEntry* entry = controller().GetActiveEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->url() == url2);
@@ -656,10 +650,10 @@ TEST_F(WebContentsTest,
EXPECT_EQ(TestInterstitialPage::CANCELED, state);
EXPECT_FALSE(contents()->showing_interstitial_page());
EXPECT_TRUE(contents()->interstitial_page() == NULL);
- entry = controller()->GetActiveEntry();
+ entry = controller().GetActiveEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->url() == url1);
- EXPECT_EQ(1, controller()->entry_count());
+ EXPECT_EQ(1, controller().entry_count());
}
// Test navigating to a page that shows an interstitial without creating a new
@@ -669,7 +663,7 @@ TEST_F(WebContentsTest, ShowInterstitialNoNewNavigationDontProceed) {
// Navigate to a page.
GURL url1("http://www.google.com");
rvh()->SendNavigate(1, url1);
- EXPECT_EQ(1, controller()->entry_count());
+ EXPECT_EQ(1, controller().entry_count());
// Show an interstitial.
TestInterstitialPage::InterstitialState state =
@@ -689,7 +683,7 @@ TEST_F(WebContentsTest, ShowInterstitialNoNewNavigationDontProceed) {
EXPECT_TRUE(interstitial->is_showing());
EXPECT_TRUE(contents()->showing_interstitial_page());
EXPECT_TRUE(contents()->interstitial_page() == interstitial);
- NavigationEntry* entry = controller()->GetActiveEntry();
+ NavigationEntry* entry = controller().GetActiveEntry();
ASSERT_TRUE(entry != NULL);
// The URL specified to the interstitial should have been ignored.
EXPECT_TRUE(entry->url() == url1);
@@ -700,10 +694,10 @@ TEST_F(WebContentsTest, ShowInterstitialNoNewNavigationDontProceed) {
EXPECT_EQ(TestInterstitialPage::CANCELED, state);
EXPECT_FALSE(contents()->showing_interstitial_page());
EXPECT_TRUE(contents()->interstitial_page() == NULL);
- entry = controller()->GetActiveEntry();
+ entry = controller().GetActiveEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->url() == url1);
- EXPECT_EQ(1, controller()->entry_count());
+ EXPECT_EQ(1, controller().entry_count());
}
// Test navigating to a page (with the navigation initiated from the browser,
@@ -714,10 +708,10 @@ TEST_F(WebContentsTest,
// Navigate to a page.
GURL url1("http://www.google.com");
rvh()->SendNavigate(1, url1);
- EXPECT_EQ(1, controller()->entry_count());
+ EXPECT_EQ(1, controller().entry_count());
// Initiate a browser navigation that will trigger the interstitial
- controller()->LoadURL(GURL("http://www.evil.com"), GURL(),
+ controller().LoadURL(GURL("http://www.evil.com"), GURL(),
PageTransition::TYPED);
// Show an interstitial.
@@ -738,7 +732,7 @@ TEST_F(WebContentsTest,
EXPECT_TRUE(interstitial->is_showing());
EXPECT_TRUE(contents()->showing_interstitial_page());
EXPECT_TRUE(contents()->interstitial_page() == interstitial);
- NavigationEntry* entry = controller()->GetActiveEntry();
+ NavigationEntry* entry = controller().GetActiveEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->url() == url2);
@@ -758,11 +752,11 @@ TEST_F(WebContentsTest,
EXPECT_TRUE(deleted);
EXPECT_FALSE(contents()->showing_interstitial_page());
EXPECT_TRUE(contents()->interstitial_page() == NULL);
- entry = controller()->GetActiveEntry();
+ entry = controller().GetActiveEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->url() == url3);
- EXPECT_EQ(2, controller()->entry_count());
+ EXPECT_EQ(2, controller().entry_count());
}
// Test navigating to a page (with the navigation initiated from the renderer,
@@ -773,7 +767,7 @@ TEST_F(WebContentsTest,
// Navigate to a page.
GURL url1("http://www.google.com");
rvh()->SendNavigate(1, url1);
- EXPECT_EQ(1, controller()->entry_count());
+ EXPECT_EQ(1, controller().entry_count());
// Show an interstitial.
TestInterstitialPage::InterstitialState state =
@@ -793,7 +787,7 @@ TEST_F(WebContentsTest,
EXPECT_TRUE(interstitial->is_showing());
EXPECT_TRUE(contents()->showing_interstitial_page());
EXPECT_TRUE(contents()->interstitial_page() == interstitial);
- NavigationEntry* entry = controller()->GetActiveEntry();
+ NavigationEntry* entry = controller().GetActiveEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->url() == url2);
@@ -813,11 +807,11 @@ TEST_F(WebContentsTest,
EXPECT_TRUE(deleted);
EXPECT_FALSE(contents()->showing_interstitial_page());
EXPECT_TRUE(contents()->interstitial_page() == NULL);
- entry = controller()->GetActiveEntry();
+ entry = controller().GetActiveEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->url() == url3);
- EXPECT_EQ(2, controller()->entry_count());
+ EXPECT_EQ(2, controller().entry_count());
}
// Test navigating to a page that shows an interstitial without creating a new
@@ -827,7 +821,7 @@ TEST_F(WebContentsTest, ShowInterstitialNoNewNavigationProceed) {
// Navigate to a page so we have a navigation entry in the controller.
GURL url1("http://www.google.com");
rvh()->SendNavigate(1, url1);
- EXPECT_EQ(1, controller()->entry_count());
+ EXPECT_EQ(1, controller().entry_count());
// Show an interstitial.
TestInterstitialPage::InterstitialState state =
@@ -847,7 +841,7 @@ TEST_F(WebContentsTest, ShowInterstitialNoNewNavigationProceed) {
EXPECT_TRUE(interstitial->is_showing());
EXPECT_TRUE(contents()->showing_interstitial_page());
EXPECT_TRUE(contents()->interstitial_page() == interstitial);
- NavigationEntry* entry = controller()->GetActiveEntry();
+ NavigationEntry* entry = controller().GetActiveEntry();
ASSERT_TRUE(entry != NULL);
// The URL specified to the interstitial should have been ignored.
EXPECT_TRUE(entry->url() == url1);
@@ -860,11 +854,11 @@ TEST_F(WebContentsTest, ShowInterstitialNoNewNavigationProceed) {
EXPECT_EQ(TestInterstitialPage::OKED, state);
EXPECT_FALSE(contents()->showing_interstitial_page());
EXPECT_TRUE(contents()->interstitial_page() == NULL);
- entry = controller()->GetActiveEntry();
+ entry = controller().GetActiveEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->url() == url1);
- EXPECT_EQ(1, controller()->entry_count());
+ EXPECT_EQ(1, controller().entry_count());
}
// Test navigating to a page that shows an interstitial, then navigating away.
@@ -902,7 +896,7 @@ TEST_F(WebContentsTest, ShowInterstitialThenCloseTab) {
interstitial->TestDidNavigate(1, url);
// Now close the tab.
- contents()->CloseContents();
+ delete contents();
ContentsCleanedUp();
EXPECT_TRUE(deleted);
EXPECT_EQ(TestInterstitialPage::CANCELED, state);
@@ -914,7 +908,7 @@ TEST_F(WebContentsTest, ShowInterstitialProceedMultipleCommands) {
// Navigate to a page so we have a navigation entry in the controller.
GURL url1("http://www.google.com");
rvh()->SendNavigate(1, url1);
- EXPECT_EQ(1, controller()->entry_count());
+ EXPECT_EQ(1, controller().entry_count());
// Show an interstitial.
TestInterstitialPage::InterstitialState state =
@@ -948,7 +942,7 @@ TEST_F(WebContentsTest, ShowInterstitialOnInterstitial) {
// Navigate to a page so we have a navigation entry in the controller.
GURL start_url("http://www.google.com");
rvh()->SendNavigate(1, start_url);
- EXPECT_EQ(1, controller()->entry_count());
+ EXPECT_EQ(1, controller().entry_count());
// Show an interstitial.
TestInterstitialPage::InterstitialState state1 =
@@ -986,10 +980,10 @@ TEST_F(WebContentsTest, ShowInterstitialOnInterstitial) {
EXPECT_TRUE(deleted2);
EXPECT_FALSE(contents()->showing_interstitial_page());
EXPECT_TRUE(contents()->interstitial_page() == NULL);
- NavigationEntry* entry = controller()->GetActiveEntry();
+ NavigationEntry* entry = controller().GetActiveEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->url() == landing_url);
- EXPECT_EQ(2, controller()->entry_count());
+ EXPECT_EQ(2, controller().entry_count());
}
// Test showing an interstitial, proceeding and then navigating to another
@@ -998,7 +992,7 @@ TEST_F(WebContentsTest, ShowInterstitialProceedShowInterstitial) {
// Navigate to a page so we have a navigation entry in the controller.
GURL start_url("http://www.google.com");
rvh()->SendNavigate(1, start_url);
- EXPECT_EQ(1, controller()->entry_count());
+ EXPECT_EQ(1, controller().entry_count());
// Show an interstitial.
TestInterstitialPage::InterstitialState state1 =
@@ -1041,10 +1035,10 @@ TEST_F(WebContentsTest, ShowInterstitialProceedShowInterstitial) {
EXPECT_TRUE(deleted2);
EXPECT_FALSE(contents()->showing_interstitial_page());
EXPECT_TRUE(contents()->interstitial_page() == NULL);
- NavigationEntry* entry = controller()->GetActiveEntry();
+ NavigationEntry* entry = controller().GetActiveEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->url() == landing_url);
- EXPECT_EQ(2, controller()->entry_count());
+ EXPECT_EQ(2, controller().entry_count());
}
// Test that navigating away from an interstitial while it's loading cause it
@@ -1064,7 +1058,7 @@ TEST_F(WebContentsTest, NavigateBeforeInterstitialShows) {
// Let's simulate a navigation initiated from the browser before the
// interstitial finishes loading.
const GURL url("http://www.google.com");
- controller()->LoadURL(url, GURL(), PageTransition::TYPED);
+ controller().LoadURL(url, GURL(), PageTransition::TYPED);
ASSERT_FALSE(deleted);
EXPECT_FALSE(interstitial->is_showing());