| Index: chrome/browser/tab_contents/render_view_host_manager.cc
|
| ===================================================================
|
| --- chrome/browser/tab_contents/render_view_host_manager.cc (revision 12396)
|
| +++ chrome/browser/tab_contents/render_view_host_manager.cc (working copy)
|
| @@ -6,6 +6,7 @@
|
|
|
| #include "base/command_line.h"
|
| #include "base/logging.h"
|
| +#include "chrome/browser/dom_ui/dom_ui.h"
|
| #include "chrome/browser/dom_ui/dom_ui_factory.h"
|
| #include "chrome/browser/renderer_host/render_view_host.h"
|
| #include "chrome/browser/renderer_host/render_view_host_delegate.h"
|
| @@ -57,7 +58,7 @@
|
|
|
| void RenderViewHostManager::Shutdown() {
|
| if (pending_render_view_host_)
|
| - CancelPendingRenderView();
|
| + CancelPending();
|
|
|
| // We should always have a main RenderViewHost.
|
| RenderViewHost* render_view_host = render_view_host_;
|
| @@ -66,10 +67,15 @@
|
| }
|
|
|
| RenderViewHost* RenderViewHostManager::Navigate(const NavigationEntry& entry) {
|
| - RenderViewHost* dest_render_view_host = UpdateRendererStateNavigate(entry);
|
| + // Create a pending RenderViewHost. It will give us the one we should use
|
| + RenderViewHost* dest_render_view_host = UpdateRendererStateForNavigate(entry);
|
| if (!dest_render_view_host)
|
| return NULL; // We weren't able to create a pending render view host.
|
|
|
| + // 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.
|
| + pending_dom_ui_.reset(delegate_->CreateDOMUIForRenderManager(entry.url()));
|
| +
|
| // If the current render_view_host_ isn't live, we should create it so
|
| // that we don't show a sad tab while the dest_render_view_host fetches
|
| // its first page. (Bug 1145340)
|
| @@ -92,7 +98,7 @@
|
| dest_render_view_host->view()->Hide();
|
| } else {
|
| // This is our primary renderer, notify here as we won't be calling
|
| - // SwapToRenderView (which does the notify).
|
| + // CommitPending (which does the notify).
|
| RenderViewHostSwitchedDetails details;
|
| details.new_host = render_view_host_;
|
| details.old_host = NULL;
|
| @@ -112,10 +118,8 @@
|
|
|
| // If we are cross-navigating, we should stop the pending renderers. This
|
| // will lead to a DidFailProvisionalLoad, which will properly destroy them.
|
| - if (cross_navigation_pending_) {
|
| + if (cross_navigation_pending_)
|
| pending_render_view_host_->Stop();
|
| -
|
| - }
|
| }
|
|
|
| void RenderViewHostManager::SetIsLoading(bool is_loading) {
|
| @@ -157,19 +161,25 @@
|
| void RenderViewHostManager::DidNavigateMainFrame(
|
| RenderViewHost* render_view_host) {
|
| if (!cross_navigation_pending_) {
|
| + DCHECK(!pending_render_view_host_);
|
| +
|
| // We should only hear this from our current renderer.
|
| DCHECK(render_view_host == render_view_host_);
|
| +
|
| + // Even when there is no pending RVH, there may be a pending DOM UI.
|
| + if (pending_dom_ui_.get())
|
| + CommitPending();
|
| return;
|
| }
|
|
|
| if (render_view_host == pending_render_view_host_) {
|
| // The pending cross-site navigation completed, so show the renderer.
|
| - SwapToRenderView(&pending_render_view_host_, true);
|
| + CommitPending();
|
| cross_navigation_pending_ = false;
|
| } else if (render_view_host == render_view_host_) {
|
| // A navigation in the original page has taken place. Cancel the pending
|
| // one.
|
| - CancelPendingRenderView();
|
| + CancelPending();
|
| cross_navigation_pending_ = false;
|
| } else {
|
| // No one else should be sending us DidNavigate in this state.
|
| @@ -237,7 +247,7 @@
|
| pending_render_view_host_->SetNavigationsSuspended(false);
|
| } else {
|
| // Current page says to cancel.
|
| - CancelPendingRenderView();
|
| + CancelPending();
|
| cross_navigation_pending_ = false;
|
| }
|
| }
|
| @@ -397,7 +407,7 @@
|
| // Don't show the view until we get a DidNavigate from it.
|
| pending_render_view_host_->view()->Hide();
|
| } else {
|
| - CancelPendingRenderView();
|
| + CancelPending();
|
| }
|
| return success;
|
| }
|
| @@ -415,9 +425,17 @@
|
| }
|
| }
|
|
|
| -void RenderViewHostManager::SwapToRenderView(
|
| - RenderViewHost** new_render_view_host,
|
| - bool destroy_after) {
|
| +void RenderViewHostManager::CommitPending() {
|
| + // First commit the DOM UI, if any.
|
| + dom_ui_.swap(pending_dom_ui_);
|
| + pending_dom_ui_.reset();
|
| +
|
| + // It's possible for the pending_render_view_host_ to be NULL when we aren't
|
| + // crossing process boundaries. If so, we just needed to handle the DOM UI
|
| + // committing above and we're done.
|
| + if (!pending_render_view_host_)
|
| + return;
|
| +
|
| // Remember if the page was focused so we can focus the new renderer in
|
| // that case.
|
| bool focus_render_view = render_view_host_->view() &&
|
| @@ -431,8 +449,8 @@
|
| RenderViewHost* old_render_view_host = render_view_host_;
|
|
|
| // Swap in the pending view and make it active.
|
| - render_view_host_ = (*new_render_view_host);
|
| - (*new_render_view_host) = NULL;
|
| + render_view_host_ = pending_render_view_host_;
|
| + pending_render_view_host_ = NULL;
|
|
|
| // If the view is gone, then this RenderViewHost died while it was hidden.
|
| // We ignored the RenderViewGone call at the time, so we should send it now
|
| @@ -456,21 +474,20 @@
|
| Source<NavigationController>(delegate_->GetControllerForRenderManager()),
|
| Details<RenderViewHostSwitchedDetails>(&details));
|
|
|
| - if (destroy_after)
|
| - old_render_view_host->Shutdown();
|
| + old_render_view_host->Shutdown();
|
|
|
| // Let the task manager know that we've swapped RenderViewHosts, since it
|
| // might need to update its process groupings.
|
| delegate_->NotifySwappedFromRenderManager();
|
| }
|
|
|
| -RenderViewHost* RenderViewHostManager::UpdateRendererStateNavigate(
|
| +RenderViewHost* RenderViewHostManager::UpdateRendererStateForNavigate(
|
| const NavigationEntry& entry) {
|
| // If we are cross-navigating, then we want to get back to normal and navigate
|
| // as usual.
|
| if (cross_navigation_pending_) {
|
| if (pending_render_view_host_)
|
| - CancelPendingRenderView();
|
| + CancelPending();
|
| cross_navigation_pending_ = false;
|
| }
|
|
|
| @@ -485,7 +502,8 @@
|
| if (ShouldTransitionCrossSite())
|
| new_instance = GetSiteInstanceForEntry(entry, curr_instance);
|
|
|
| - if (new_instance != curr_instance || ShouldSwapRenderViewsForNavigation(
|
| + if (new_instance != curr_instance ||
|
| + ShouldSwapRenderViewsForNavigation(
|
| delegate_->GetLastCommittedNavigationEntryForRenderManager(),
|
| &entry)) {
|
| // New SiteInstance.
|
| @@ -504,7 +522,7 @@
|
| // navigate. Just switch to the pending RVH now and go back to non
|
| // cross-navigating (Note that we don't care about on{before}unload
|
| // handlers if the current RVH isn't live.)
|
| - SwapToRenderView(&pending_render_view_host_, true);
|
| + CommitPending();
|
| return render_view_host_;
|
| } else {
|
| NOTREACHED();
|
| @@ -546,15 +564,17 @@
|
| return render_view_host_;
|
| }
|
|
|
| -void RenderViewHostManager::CancelPendingRenderView() {
|
| +void RenderViewHostManager::CancelPending() {
|
| RenderViewHost* pending_render_view_host = pending_render_view_host_;
|
| pending_render_view_host_ = NULL;
|
| pending_render_view_host->Shutdown();
|
| +
|
| + pending_dom_ui_.reset();
|
| }
|
|
|
| void RenderViewHostManager::CrossSiteNavigationCanceled() {
|
| DCHECK(cross_navigation_pending_);
|
| cross_navigation_pending_ = false;
|
| if (pending_render_view_host_)
|
| - CancelPendingRenderView();
|
| + CancelPending();
|
| }
|
|
|