diff options
author | dominich@chromium.org <dominich@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-25 18:18:28 +0000 |
---|---|---|
committer | dominich@chromium.org <dominich@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-25 18:18:28 +0000 |
commit | 00d64211401b604b7af52168efe01af024324f10 (patch) | |
tree | 2a5ca63f95eb1cd622f7a14d080e222c8c40a339 /chrome/browser/instant | |
parent | fe2a2ba11a08e72d9c249b25b4cd5d6d2cb0375e (diff) | |
download | chromium_src-00d64211401b604b7af52168efe01af024324f10.zip chromium_src-00d64211401b604b7af52168efe01af024324f10.tar.gz chromium_src-00d64211401b604b7af52168efe01af024324f10.tar.bz2 |
Prerender/Instant interopability.
BUG=82590
TEST=Use instant to navigate to a page that is currently being prerendered. Observe it does not crash.
Review URL: http://codereview.chromium.org/7034043
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@86651 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/instant')
-rw-r--r-- | chrome/browser/instant/instant_controller.cc | 5 | ||||
-rw-r--r-- | chrome/browser/instant/instant_controller.h | 1 | ||||
-rw-r--r-- | chrome/browser/instant/instant_loader.cc | 84 | ||||
-rw-r--r-- | chrome/browser/instant/instant_loader.h | 9 | ||||
-rw-r--r-- | chrome/browser/instant/instant_loader_delegate.h | 3 | ||||
-rw-r--r-- | chrome/browser/instant/instant_loader_manager_unittest.cc | 3 |
6 files changed, 94 insertions, 11 deletions
diff --git a/chrome/browser/instant/instant_controller.cc b/chrome/browser/instant/instant_controller.cc index dc8ea60..65ba84f 100644 --- a/chrome/browser/instant/instant_controller.cc +++ b/chrome/browser/instant/instant_controller.cc @@ -500,6 +500,11 @@ void InstantController::AddToBlacklist(InstantLoader* loader, const GURL& url) { UpdateDisplayableLoader(); } +void InstantController::SwappedTabContents(InstantLoader* loader) { + if (displayable_loader_ == loader) + delegate_->ShowInstant(displayable_loader_->preview_contents()); +} + void InstantController::UpdateDisplayableLoader() { InstantLoader* loader = NULL; // As soon as the pending loader is displayable it becomes the current loader, diff --git a/chrome/browser/instant/instant_controller.h b/chrome/browser/instant/instant_controller.h index 3fdc14a7..acf4b42 100644 --- a/chrome/browser/instant/instant_controller.h +++ b/chrome/browser/instant/instant_controller.h @@ -184,6 +184,7 @@ class InstantController : public InstantLoaderDelegate { InstantLoader* loader) OVERRIDE; virtual void AddToBlacklist(InstantLoader* loader, const GURL& url) OVERRIDE; + virtual void SwappedTabContents(InstantLoader* loader) OVERRIDE; private: friend class InstantTest; diff --git a/chrome/browser/instant/instant_loader.cc b/chrome/browser/instant/instant_loader.cc index 7018ebc..1c7a874 100644 --- a/chrome/browser/instant/instant_loader.cc +++ b/chrome/browser/instant/instant_loader.cc @@ -25,6 +25,7 @@ #include "chrome/browser/ui/download/download_tab_helper.h" #include "chrome/browser/ui/download/download_tab_helper_delegate.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper_delegate.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/render_messages.h" #include "content/browser/renderer_host/render_view_host.h" @@ -144,6 +145,7 @@ void InstantLoader::FrameLoadObserver::Observe( class InstantLoader::TabContentsDelegateImpl : public TabContentsDelegate, + public TabContentsWrapperDelegate, public NotificationObserver, public TabContentsObserver, public DownloadTabHelperDelegate { @@ -220,6 +222,10 @@ class InstantLoader::TabContentsDelegateImpl NavigationType::Type navigation_type) OVERRIDE; virtual bool ShouldShowHungRendererDialog() OVERRIDE; + // TabContentsWrapperDelegate: + virtual void SwapTabContents(TabContentsWrapper* old_tc, + TabContentsWrapper* new_tc) OVERRIDE; + // TabContentsObserver: virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; @@ -554,6 +560,15 @@ bool InstantLoader::TabContentsDelegateImpl::ShouldShowHungRendererDialog() { return false; } +// If this is being called, something is swapping in to our preview_contents_ +// before we've added it to the tab strip. +void InstantLoader::TabContentsDelegateImpl::SwapTabContents( + TabContentsWrapper* old_tc, + TabContentsWrapper* new_tc) { + loader_->ReplacePreviewContents(old_tc, new_tc); +} + + bool InstantLoader::TabContentsDelegateImpl::OnMessageReceived( const IPC::Message& message) { bool handled = true; @@ -995,21 +1010,55 @@ void InstantLoader::SendBoundsToPage(bool force_if_waiting) { } } -void InstantLoader::CreatePreviewContents(TabContentsWrapper* tab_contents) { - TabContents* new_contents = - new TabContents( - tab_contents->profile(), NULL, MSG_ROUTING_NONE, NULL, NULL); - preview_contents_.reset(new TabContentsWrapper(new_contents)); +void InstantLoader::ReplacePreviewContents(TabContentsWrapper* old_tc, + TabContentsWrapper* new_tc) { + DCHECK(old_tc == preview_contents_); + // We release here without deleting so that the caller still has reponsibility + // for deleting the TabContentsWrapper. + ignore_result(preview_contents_.release()); + preview_contents_.reset(new_tc); + + // Make sure the new preview contents acts like the old one. + SetupPreviewContents(old_tc); + + // Cleanup the old preview contents. + old_tc->download_tab_helper()->set_delegate(NULL); + old_tc->tab_contents()->set_delegate(NULL); + old_tc->set_delegate(NULL); + +#if defined(OS_MACOSX) + registrar_.Remove(this, + NotificationType::RENDER_VIEW_HOST_CHANGED, + Source<NavigationController>(&old_tc->controller())); +#endif + registrar_.Remove(this, + NotificationType::NAV_ENTRY_COMMITTED, + Source<NavigationController>(&old_tc->controller())); + + // We prerendered so we should be ready to show. If we're ready, swap in + // immediately, otherwise show the preview as normal. + if (ready_) + delegate_->SwappedTabContents(this); + else + ShowPreview(); +} + +void InstantLoader::SetupPreviewContents(TabContentsWrapper* tab_contents) { + preview_contents_->set_delegate(preview_tab_contents_delegate_.get()); + preview_contents_->tab_contents()->set_delegate( + preview_tab_contents_delegate_.get()); preview_contents_->blocked_content_tab_helper()->SetAllContentsBlocked(true); - preview_tab_contents_delegate_.reset(new TabContentsDelegateImpl(this)); - new_contents->set_delegate(preview_tab_contents_delegate_.get()); + + // Propagate the max page id. That way if we end up merging the two + // NavigationControllers (which happens if we commit) none of the page ids + // will overlap. + int32 max_page_id = tab_contents->tab_contents()->GetMaxPageID(); + if (max_page_id != -1) + preview_contents_->controller().set_max_restored_page_id(max_page_id + 1); + preview_contents_->download_tab_helper()->set_delegate( preview_tab_contents_delegate_.get()); - gfx::Rect tab_bounds; - tab_contents->view()->GetContainerBounds(&tab_bounds); - preview_contents_->view()->SizeContents(tab_bounds.size()); - #if defined(OS_MACOSX) // If |preview_contents_| does not currently have a RWHV, we will call // SetTakesFocusOnlyOnMouseDown() as a result of the @@ -1029,5 +1078,18 @@ void InstantLoader::CreatePreviewContents(TabContentsWrapper* tab_contents) { NotificationType::NAV_ENTRY_COMMITTED, Source<NavigationController>(&preview_contents_->controller())); + gfx::Rect tab_bounds; + tab_contents->view()->GetContainerBounds(&tab_bounds); + preview_contents_->view()->SizeContents(tab_bounds.size()); +} + +void InstantLoader::CreatePreviewContents(TabContentsWrapper* tab_contents) { + TabContents* new_contents = + new TabContents( + tab_contents->profile(), NULL, MSG_ROUTING_NONE, NULL, NULL); + preview_contents_.reset(new TabContentsWrapper(new_contents)); + preview_tab_contents_delegate_.reset(new TabContentsDelegateImpl(this)); + SetupPreviewContents(tab_contents); + preview_contents_->tab_contents()->ShowContents(); } diff --git a/chrome/browser/instant/instant_loader.h b/chrome/browser/instant/instant_loader.h index 3aa5235..5182e2f 100644 --- a/chrome/browser/instant/instant_loader.h +++ b/chrome/browser/instant/instant_loader.h @@ -150,6 +150,15 @@ class InstantLoader : public NotificationObserver { // waiting on the load and |force_if_loading| is false this does nothing. void SendBoundsToPage(bool force_if_loading); + // Called when the TabContentsDelegate wants to swap a new TabContentsWrapper + // into our |preview_contents_|. + void ReplacePreviewContents(TabContentsWrapper* old_tc, + TabContentsWrapper* new_tc); + + // Called to set up the |preview_contents_| based on |tab_contents| when it is + // created or replaced. + void SetupPreviewContents(TabContentsWrapper* tab_contents); + // Creates and sets the preview TabContentsWrapper. void CreatePreviewContents(TabContentsWrapper* tab_contents); diff --git a/chrome/browser/instant/instant_loader_delegate.h b/chrome/browser/instant/instant_loader_delegate.h index 8c43657..5b98257 100644 --- a/chrome/browser/instant/instant_loader_delegate.h +++ b/chrome/browser/instant/instant_loader_delegate.h @@ -45,6 +45,9 @@ class InstantLoaderDelegate { // Adds the specified url to the set of urls instant won't prefetch for. virtual void AddToBlacklist(InstantLoader* loader, const GURL& url) = 0; + // Invoked if the loader swaps to a different TabContents. + virtual void SwappedTabContents(InstantLoader* loader) = 0; + protected: virtual ~InstantLoaderDelegate() {} }; diff --git a/chrome/browser/instant/instant_loader_manager_unittest.cc b/chrome/browser/instant/instant_loader_manager_unittest.cc index 480d72d..9854184 100644 --- a/chrome/browser/instant/instant_loader_manager_unittest.cc +++ b/chrome/browser/instant/instant_loader_manager_unittest.cc @@ -39,6 +39,9 @@ class InstantLoaderDelegateImpl : public InstantLoaderDelegate { const GURL& url) OVERRIDE { } + virtual void SwappedTabContents(InstantLoader* loader) OVERRIDE { + } + private: DISALLOW_COPY_AND_ASSIGN(InstantLoaderDelegateImpl); }; |