diff options
Diffstat (limited to 'chrome/browser/tab_contents')
-rw-r--r-- | chrome/browser/tab_contents/infobar_delegate.cc | 2 | ||||
-rw-r--r-- | chrome/browser/tab_contents/interstitial_page.cc | 14 | ||||
-rw-r--r-- | chrome/browser/tab_contents/navigation_controller.cc | 108 | ||||
-rw-r--r-- | chrome/browser/tab_contents/navigation_controller.h | 44 | ||||
-rw-r--r-- | chrome/browser/tab_contents/render_view_context_menu.cc | 16 | ||||
-rw-r--r-- | chrome/browser/tab_contents/render_view_host_delegate_helper.cc | 1 | ||||
-rw-r--r-- | chrome/browser/tab_contents/render_view_host_manager.cc | 34 | ||||
-rw-r--r-- | chrome/browser/tab_contents/render_view_host_manager.h | 8 | ||||
-rw-r--r-- | chrome/browser/tab_contents/render_view_host_manager_unittest.cc | 21 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents.cc | 85 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents.h | 76 | ||||
-rw-r--r-- | chrome/browser/tab_contents/web_contents.cc | 327 | ||||
-rw-r--r-- | chrome/browser/tab_contents/web_contents.h | 9 | ||||
-rw-r--r-- | chrome/browser/tab_contents/web_contents_unittest.cc | 160 |
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(¶ms, 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(¶ms1, 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(¶ms1, 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(¶ms1, 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(¶ms2a, 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(¶ms2b, 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(¶ms1, 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(¶ms2, 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(¶ms4, 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(¶ms1, 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(¶ms1, 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(¶ms2, 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()); |