summaryrefslogtreecommitdiffstats
path: root/chrome/browser/web_contents.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/web_contents.cc')
-rw-r--r--chrome/browser/web_contents.cc1117
1 files changed, 138 insertions, 979 deletions
diff --git a/chrome/browser/web_contents.cc b/chrome/browser/web_contents.cc
index 9ed7927..9108c7d 100644
--- a/chrome/browser/web_contents.cc
+++ b/chrome/browser/web_contents.cc
@@ -219,6 +219,9 @@ WebContents::WebContents(Profile* profile,
int routing_id,
HANDLE modal_dialog_event)
: TabContents(TAB_CONTENTS_WEB),
+#pragma warning(suppress: 4355) // Okay to pass "this" here.
+ render_manager_(render_view_factory, this, this),
+ render_view_factory_(render_view_factory),
is_profiling_(false),
has_page_title_(false),
info_bar_visible_(false),
@@ -226,31 +229,18 @@ WebContents::WebContents(Profile* profile,
printing_(*this),
notify_disconnection_(false),
message_box_active_(CreateEvent(NULL, TRUE, FALSE, NULL)),
- render_view_factory_(render_view_factory),
- original_render_view_host_(NULL),
- interstitial_render_view_host_(NULL),
- pending_render_view_host_(NULL),
- renderer_state_(NORMAL),
capturing_contents_(false),
#pragma warning(suppress: 4355) // Okay to pass "this" here.
fav_icon_helper_(this),
crashed_plugin_info_bar_(NULL),
suppress_javascript_messages_(false),
- load_state_(net::LOAD_STATE_IDLE),
- showing_repost_interstitial_(false),
- interstitial_delegate_(NULL) {
+ load_state_(net::LOAD_STATE_IDLE) {
InitWebContentsClass();
pending_install_.page_id = 0;
pending_install_.callback_functor = NULL;
- // Create a RenderViewHost, once we have an instance. It is important to
- // immediately give this SiteInstance to a RenderViewHost so that it is
- // ref counted.
- if (!site_instance)
- site_instance = SiteInstance::CreateSiteInstance(profile);
- render_view_host_ = CreateRenderViewHost(
- site_instance, this, routing_id, modal_dialog_event);
+ render_manager_.Init(profile, site_instance, routing_id, modal_dialog_event);
// Register for notifications about all interested prefs change.
PrefService* prefs = profile->GetPrefs();
@@ -290,8 +280,8 @@ void WebContents::GetContainerBounds(gfx::Rect *out) const {
}
void WebContents::ShowContents() {
- if (render_view_host_ && render_view_host_->view())
- render_view_host_->view()->DidBecomeSelected();
+ if (view())
+ view()->DidBecomeSelected();
// Loop through children and send DidBecomeSelected to them, too.
int count = static_cast<int>(child_windows_.size());
@@ -317,8 +307,8 @@ void WebContents::HideContents() {
}
void WebContents::SizeContents(const gfx::Size& size) {
- if (render_view_host_ && render_view_host_->view())
- render_view_host_->view()->SetSize(size);
+ if (view())
+ view()->SetSize(size);
if (find_in_page_controller_.get())
find_in_page_controller_->RespondToResize(size);
RepositionSupressedPopupsToFit(size);
@@ -336,21 +326,15 @@ void WebContents::Destroy() {
// 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)
+ if (prefs) {
for (int i = 0; i < kPrefsToObserveLength; ++i)
prefs->RemovePrefObserver(kPrefsToObserve[i], this);
+ }
cancelable_consumer_.CancelAllRequests();
- if (IsShowingInterstitialPage()) {
- // The tab is closed while the interstitial page is showing, hide and
- // destroy it.
- HideInterstitialPage(false, false);
- }
-
// Close the Find in page dialog.
if (find_in_page_controller_.get())
find_in_page_controller_->Close();
@@ -359,19 +343,9 @@ void WebContents::Destroy() {
// They will be cleaned up properly in plugin process.
DetachPluginWindows();
- if (pending_render_view_host_)
- pending_render_view_host_->Shutdown();
- if (original_render_view_host_)
- original_render_view_host_->Shutdown();
- if (interstitial_render_view_host_)
- interstitial_render_view_host_->Shutdown();
-
NotifyDisconnected();
HungRendererWarning::HideForWebContents(this);
-
- render_view_host_->Shutdown();
- render_view_host_ = NULL;
-
+ render_manager_.Shutdown();
TabContents::Destroy();
}
@@ -409,7 +383,7 @@ void WebContents::OnWindowPosChanged(WINDOWPOS* window_pos) {
}
void WebContents::OnPaint(HDC junk_dc) {
- if (render_view_host_ && !render_view_host_->IsRenderViewLive()) {
+ if (render_view_host() && !render_view_host()->IsRenderViewLive()) {
if (!sad_tab_.get())
sad_tab_.reset(new SadTabView);
CRect cr;
@@ -450,8 +424,7 @@ LRESULT WebContents::OnMouseRange(UINT msg, WPARAM w_param, LPARAM l_param) {
delegate()->ContentsMouseEvent(this, WM_MOUSEMOVE);
break;
case WM_MOUSEWHEEL:
- // This message is reflected from the render_view_host_->view()
- // to this window.
+ // This message is reflected from the view() to this window.
if (GET_KEYSTATE_WPARAM(w_param) & MK_CONTROL) {
WheelZoom(GET_WHEEL_DELTA_WPARAM(w_param));
return 1;
@@ -532,8 +505,8 @@ void WebContents::OnSetFocus(HWND window) {
// background from properly taking focus.
// We NULL-check the render_view_host_ here because Windows can send us
// messages during the destruction process after it has been destroyed.
- if (render_view_host_ && render_view_host_->view()) {
- HWND inner_hwnd = render_view_host_->view()->GetPluginHWND();
+ if (view()) {
+ HWND inner_hwnd = view()->GetPluginHWND();
if (::IsWindow(inner_hwnd))
::SetFocus(inner_hwnd);
}
@@ -554,7 +527,7 @@ void WebContents::SaveCurrentProfilingEntry() {
if (is_profiling()) {
NavigationProfiler* profiler = GetNavigationProfiler();
profiler->MoveActivePageToVisited(process()->host_id(),
- render_view_host_->routing_id());
+ render_view_host()->routing_id());
}
is_profiling_ = false;
}
@@ -568,7 +541,7 @@ void WebContents::CreateNewProfilingEntry(const GURL& url) {
TimeTicks current_time = TimeTicks::Now();
PageLoadTracker *page = new PageLoadTracker(
- url, process()->host_id(), render_view_host_->routing_id(),
+ url, process()->host_id(), render_view_host()->routing_id(),
current_time);
profiler->AddActivePage(page);
@@ -653,40 +626,7 @@ void WebContents::SavePage(const std::wstring& main_file,
// pending RVH and goes back to the NORMAL RendererState.
bool WebContents::Navigate(const NavigationEntry& entry, bool reload) {
- RenderViewHost* dest_render_view_host = UpdateRendererStateNavigate(entry);
- if (!dest_render_view_host) {
- // We weren't able to create a pending render view host.
- return false;
- }
-
- // 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)
- if (dest_render_view_host != render_view_host_ &&
- !render_view_host_->IsRenderViewLive()) {
- CreateRenderView(render_view_host_);
- }
-
- // If the renderer crashed, then try to create a new one to satisfy this
- // navigation request.
- if (!dest_render_view_host->IsRenderViewLive()) {
- if (!CreateRenderView(dest_render_view_host))
- return false;
-
- // Now that we've created a new renderer, be sure to hide it if it isn't
- // our primary one. Otherwise, we might crash if we try to call Show()
- // on it later.
- if (dest_render_view_host != render_view_host_ &&
- dest_render_view_host->view()) {
- 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).
- NotificationService::current()->Notify(
- NOTIFY_RENDER_VIEW_HOST_CHANGED,
- Source<WebContents>(this), NotificationService::NoDetails());
- }
- }
+ RenderViewHost* dest_render_view_host = render_manager_.Navigate(entry);
CreateNewProfilingEntry(entry.GetURL());
@@ -696,8 +636,6 @@ bool WebContents::Navigate(const NavigationEntry& entry, bool reload) {
// Navigate in the desired RenderViewHost
dest_render_view_host->NavigateToEntry(entry, reload);
- showing_repost_interstitial_ = false;
-
if (entry.GetPageID() == -1) {
// HACK!! This code suppresses javascript: URLs from being added to
// session history, which is what we want to do for javascript: URLs that
@@ -718,371 +656,29 @@ bool WebContents::Navigate(const NavigationEntry& entry, bool reload) {
return true;
}
-RenderViewHost* WebContents::UpdateRendererStateNavigate(
- const NavigationEntry& entry) {
- // If we are in PENDING or ENTERING_INTERSTITIAL, then we want to get back
- // to NORMAL and navigate as usual.
- if (renderer_state_ == PENDING || renderer_state_ == ENTERING_INTERSTITIAL) {
- if (pending_render_view_host_)
- CancelRenderView(&pending_render_view_host_);
- if (interstitial_render_view_host_)
- CancelRenderView(&interstitial_render_view_host_);
- renderer_state_ = NORMAL;
- }
-
- // render_view_host_ will not be deleted before the end of this method, so we
- // don't have to worry about this SiteInstance's ref count dropping to zero.
- SiteInstance* curr_instance = render_view_host_->site_instance();
-
- if (IsShowingInterstitialPage()) {
- // Must disable any ability to proceed from the interstitial, because we're
- // about to navigate somewhere else.
- DisableInterstitialProceed(true);
-
- if (pending_render_view_host_)
- CancelRenderView(&pending_render_view_host_);
-
- renderer_state_ = LEAVING_INTERSTITIAL;
-
- // We want to compare against where we were, because we just cancelled
- // where we were going. The original_render_view_host_ won't be deleted
- // before the end of this method, so we don't have to worry about this
- // SiteInstance's ref count dropping to zero.
- curr_instance = original_render_view_host_->site_instance();
- }
-
- // Determine if we need a new SiteInstance for this entry.
- // Again, new_instance won't be deleted before the end of this method, so it
- // is safe to use a normal pointer here.
- SiteInstance* new_instance = curr_instance;
- if (ShouldTransitionCrossSite()) {
- new_instance = GetSiteInstanceForEntry(entry, curr_instance);
- }
-
- if (new_instance != curr_instance) {
- // New SiteInstance.
- DCHECK(renderer_state_ == NORMAL ||
- renderer_state_ == LEAVING_INTERSTITIAL);
-
- // Create a pending RVH and navigate it.
- bool success = CreatePendingRenderView(new_instance);
- if (!success)
- return NULL;
-
- // Check if our current RVH is live before we set up a transition.
- if (!render_view_host_->IsRenderViewLive()) {
- if (renderer_state_ == NORMAL) {
- // The current RVH is not live. There's no reason to sit around with a
- // sad tab or a newly created RVH while we wait for the pending RVH to
- // navigate. Just switch to the pending RVH now and go back to NORMAL,
- // without requiring a cross-site transition. (Note that we don't care
- // about on{before}unload handlers if the current RVH isn't live.)
- SwapToRenderView(&pending_render_view_host_, true);
- return render_view_host_;
-
- } else if (renderer_state_ == LEAVING_INTERSTITIAL) {
- // Cancel the interstitial, since it has died and we're navigating away
- // anyway.
- DCHECK(original_render_view_host_);
- if (original_render_view_host_->IsRenderViewLive()) {
- // Swap back to the original and act like a pending request (using
- // the logic below).
- SwapToRenderView(&original_render_view_host_, true);
- renderer_state_ = NORMAL;
- InterstitialPageGone();
- // Continue with the pending cross-site transition logic below.
- } else {
- // Both the interstitial and original are dead. Just like the NORMAL
- // case, let's skip the cross-site transition entirely. We also have
- // to clean up the interstitial state.
- SwapToRenderView(&pending_render_view_host_, true);
- CancelRenderView(&original_render_view_host_);
- renderer_state_ = NORMAL;
- InterstitialPageGone();
- return render_view_host_;
- }
- } else {
- NOTREACHED();
- return render_view_host_;
- }
- }
- // Otherwise, it's safe to treat this as a pending cross-site transition.
-
- // Make sure the old render view stops, in case a load is in progress.
- render_view_host_->Stop();
-
- // Suspend the new render view (i.e., don't let it send the cross-site
- // Navigate message) until we hear back from the old renderer's
- // onbeforeunload handler. If it returns false, we'll have to cancel the
- // request.
- pending_render_view_host_->SetNavigationsSuspended(true);
-
- // Tell the CrossSiteRequestManager that this RVH has a pending cross-site
- // request, so that ResourceDispatcherHost will know to tell us to run the
- // old page's onunload handler before it sends the response.
- pending_render_view_host_->SetHasPendingCrossSiteRequest(true);
-
- // We now have a pending RVH. If we were in NORMAL, we should now be in
- // PENDING. If we were in LEAVING_INTERSTITIAL, we should stay there.
- if (renderer_state_ == NORMAL)
- renderer_state_ = PENDING;
- else
- DCHECK(renderer_state_ == LEAVING_INTERSTITIAL);
-
- // Tell the old render view to run its onbeforeunload handler, since it
- // doesn't otherwise know that the cross-site request is happening. This
- // will trigger a call to ShouldClosePage with the reply.
- render_view_host_->FirePageBeforeUnload();
-
- return pending_render_view_host_;
- }
-
- // Same SiteInstance can be used. Navigate render_view_host_ if we are in
- // the NORMAL state, and original_render_view_host_ if an interstitial is
- // showing.
- if (renderer_state_ == NORMAL)
- return render_view_host_;
-
- DCHECK(renderer_state_ == LEAVING_INTERSTITIAL);
- return original_render_view_host_;
-}
-
-bool WebContents::ShouldTransitionCrossSite() {
- // True if we are using process-per-site-instance (default) or
- // process-per-site (kProcessPerSite).
- return !CommandLine().HasSwitch(switches::kProcessPerTab);
-}
-
-SiteInstance* WebContents::GetSiteInstanceForEntry(
- const NavigationEntry& entry, SiteInstance* curr_instance) {
- // NOTE: This is only called when ShouldTransitionCrossSite is true.
-
- // If the entry has an instance already, we should use it.
- if (entry.site_instance())
- return entry.site_instance();
-
- // (UGLY) HEURISTIC, process-per-site only:
- //
- // If this navigation is generated, then it probably corresponds to a search
- // query. Given that search results typically lead to users navigating to
- // other sites, we don't really want to use the search engine hostname to
- // determine the site instance for this navigation.
- //
- // NOTE: This can be removed once we have a way to transition between
- // RenderViews in response to a link click.
- //
- if (CommandLine().HasSwitch(switches::kProcessPerSite) &&
- entry.GetTransitionType() == PageTransition::GENERATED)
- return curr_instance;
-
- const GURL& dest_url = entry.GetURL();
-
- // If we haven't used our SiteInstance (and thus RVH) yet, then we can use it
- // for this entry. We won't commit the SiteInstance to this site until the
- // navigation commits (in DidNavigate), unless the navigation entry was
- // restored. As session restore loads all the pages immediately we need to set
- // the site first, otherwise after a restore none of the pages would share
- // renderers.
- if (!curr_instance->has_site()) {
- // If we've already created a SiteInstance for our destination, we don't
- // want to use this unused SiteInstance; use the existing one. (We don't
- // do this check if the curr_instance has a site, because for now, we want
- // to compare against the current URL and not the SiteInstance's site. In
- // this case, there is no current URL, so comparing against the site is ok.
- // See additional comments below.)
- if (curr_instance->HasRelatedSiteInstance(dest_url)) {
- return curr_instance->GetRelatedSiteInstance(dest_url);
- } else {
- if (entry.restored())
- curr_instance->SetSite(dest_url);
- return curr_instance;
- }
- }
-
- // Otherwise, only create a new SiteInstance for cross-site navigation.
-
- // TODO(creis): Once we intercept links and script-based navigations, we
- // will be able to enforce that all entries in a SiteInstance actually have
- // the same site, and it will be safe to compare the URL against the
- // SiteInstance's site, as follows:
- // const GURL& current_url = curr_instance->site();
- // 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.
- NavigationEntry* curr_entry = controller()->GetLastCommittedEntry();
- if (IsShowingInterstitialPage()) {
- // The interstitial is currently the last committed entry, but we want to
- // compare against the last non-interstitial entry.
- 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
- // to compare against the URL of the page that opened us, but we can't
- // get to it directly. The best we can do is check against the site of
- // the SiteInstance. This will be correct when we intercept links and
- // script-based navigations, but for now, it could place some pages in a
- // new process unnecessarily. We should only hit this case if a page tries
- // to open a new tab to an interstitial-inducing URL, and then navigates
- // the page to a different same-site URL. (This seems very unlikely in
- // practice.)
- const GURL& current_url = (curr_entry) ? curr_entry->GetURL() :
- curr_instance->site();
-
- if (SiteInstance::IsSameWebSite(current_url, dest_url)) {
- return curr_instance;
- } else {
- // Start the new renderer in a new SiteInstance, but in the current
- // BrowsingInstance. It is important to immediately give this new
- // SiteInstance to a RenderViewHost (if it is different than our current
- // SiteInstance), so that it is ref counted. This will happen in
- // CreatePendingRenderView.
- return curr_instance->GetRelatedSiteInstance(dest_url);
- }
-}
-
-void WebContents::DisableInterstitialProceed(bool stop_request) {
- // TODO(creis): Make sure the interstitial page disables any ability to
- // proceed at this point, because we're about to abort the original request.
- // This can be done by adding a new event to the NotificationService.
- // We should also disable the button on the page itself, but it's ok if that
- // doesn't happen immediately.
-
- // Stopping the request is necessary if we are navigating away, because the
- // user could be requesting the same URL again, causing the HttpCache to
- // ignore it. (Fixes bug 1079784.)
- if (stop_request) {
- original_render_view_host_->Stop();
- if (pending_render_view_host_)
- pending_render_view_host_->Stop();
- }
-}
-
-bool WebContents::CreatePendingRenderView(SiteInstance* instance) {
- NavigationEntry* curr_entry = controller()->GetLastCommittedEntry();
- if (curr_entry && curr_entry->GetType() == TAB_CONTENTS_WEB) {
- DCHECK(!curr_entry->GetContentState().empty());
-
- // TODO(creis): Should send a message to the RenderView to let it know
- // we're about to switch away, so that it sends an UpdateState message.
- }
-
- pending_render_view_host_ =
- CreateRenderViewHost(instance, this, MSG_ROUTING_NONE, NULL);
-
- bool success = CreateRenderView(pending_render_view_host_);
- if (success) {
- // Don't show the view until we get a DidNavigate from it.
- pending_render_view_host_->view()->Hide();
- } else {
- CancelRenderView(&pending_render_view_host_);
- }
- return success;
-}
-
-void WebContents::CancelRenderView(RenderViewHost** render_view_host) {
- DCHECK(*render_view_host != NULL);
-
- // Destroy the render view host
- (*render_view_host)->Shutdown();
- (*render_view_host) = NULL;
-}
-
-void WebContents::ShouldClosePage(bool proceed) {
- // Should only see this while we have a pending renderer. Otherwise, we
- // should ignore.
- if (!pending_render_view_host_) {
- bool proceed_to_fire_unload;
- delegate()->BeforeUnloadFired(this, proceed, &proceed_to_fire_unload);
-
- if (proceed_to_fire_unload) {
- // This is not a cross-site navigation, the tab is being closed.
- render_view_host_->FirePageUnload();
- }
- return;
- }
-
- DCHECK(renderer_state_ != ENTERING_INTERSTITIAL);
- DCHECK(renderer_state_ != INTERSTITIAL);
- if (proceed) {
- // Ok to unload the current page, so proceed with the cross-site navigate.
- pending_render_view_host_->SetNavigationsSuspended(false);
- } else {
- // Current page says to cancel.
- CancelRenderView(&pending_render_view_host_);
- renderer_state_ = NORMAL;
- }
-}
-
-void WebContents::OnCrossSiteResponse(int new_render_process_host_id,
- int new_request_id) {
- // Should only see this while we have a pending renderer, possibly during an
- // interstitial. Otherwise, we should ignore.
- if (renderer_state_ != PENDING && renderer_state_ != LEAVING_INTERSTITIAL)
- return;
- DCHECK(pending_render_view_host_);
-
- // Tell the old renderer to run its onunload handler. When it finishes, it
- // will send a ClosePage_ACK to the ResourceDispatcherHost with the given
- // IDs (of the pending RVH's request), allowing the pending RVH's response to
- // resume.
- if (IsShowingInterstitialPage()) {
- DCHECK(original_render_view_host_);
- original_render_view_host_->ClosePage(new_render_process_host_id,
- new_request_id);
- } else {
- render_view_host_->ClosePage(new_render_process_host_id,
- new_request_id);
- }
-
- // ResourceDispatcherHost has told us to run the onunload handler, which
- // means it is not a download or unsafe page, and we are going to perform the
- // navigation. Thus, we no longer need to remember that the RenderViewHost
- // is part of a pending cross-site request.
- pending_render_view_host_->SetHasPendingCrossSiteRequest(false);
-}
-
void WebContents::Stop() {
- render_view_host_->Stop();
-
- // If we aren't in the NORMAL renderer state, we should stop the pending
- // renderers. This will lead to a DidFailProvisionalLoad, which will
- // properly destroy them.
- if (renderer_state_ == PENDING) {
- pending_render_view_host_->Stop();
-
- } else if (renderer_state_ == ENTERING_INTERSTITIAL) {
- interstitial_render_view_host_->Stop();
- if (pending_render_view_host_) {
- pending_render_view_host_->Stop();
- }
-
- } else if (renderer_state_ == LEAVING_INTERSTITIAL) {
- if (pending_render_view_host_) {
- pending_render_view_host_->Stop();
- }
- }
-
+ render_manager_.Stop();
printing_.Stop();
}
void WebContents::DidBecomeSelected() {
TabContents::DidBecomeSelected();
- if (render_view_host_ && render_view_host_->view())
- render_view_host_->view()->DidBecomeSelected();
+ if (render_view_host() && view())
+ view()->DidBecomeSelected();
CacheManagerHost::GetInstance()->ObserveActivity(process()->host_id());
}
void WebContents::WasHidden() {
if (!capturing_contents_) {
- // |render_view_host_| can be NULL if the user middle clicks a link to open
+ // |render_view_host()| can be NULL if the user middle clicks a link to open
// a tab in then background, then closes the tab before selecting it. This
// is because closing the tab calls WebContents::Destroy(), which removes
- // the |render_view_host_|; then when we actually destroy the window,
+ // the |render_view_host()|; then when we actually destroy the window,
// OnWindowPosChanged() notices and calls HideContents() (which calls us).
- if (render_view_host_ && render_view_host_->view())
- render_view_host_->view()->WasHidden();
+ if (render_view_host() && view())
+ view()->WasHidden();
// Loop through children and send WasHidden to them, too.
int count = static_cast<int>(child_windows_.size());
@@ -1104,16 +700,14 @@ void WebContents::StartFinding(int request_id,
bool forward,
bool match_case,
bool find_next) {
- if (search_string.empty()) {
+ if (search_string.empty())
return;
- }
-
- render_view_host_->StartFinding(request_id, search_string, forward,
- match_case, find_next);
+ render_view_host()->StartFinding(request_id, search_string, forward,
+ match_case, find_next);
}
void WebContents::StopFinding(bool clear_selection) {
- render_view_host_->StopFinding(clear_selection);
+ render_view_host()->StopFinding(clear_selection);
}
void WebContents::OpenFindInPageWindow(const Browser& browser) {
@@ -1156,29 +750,29 @@ bool WebContents::AdvanceFindSelection(bool forward_direction) {
}
void WebContents::AlterTextSize(text_zoom::TextSize size) {
- render_view_host_->AlterTextSize(size);
+ render_view_host()->AlterTextSize(size);
// TODO(creis): should this be propagated to other and future RVHs?
}
void WebContents::SetPageEncoding(const std::wstring& encoding_name) {
- render_view_host_->SetPageEncoding(encoding_name);
+ render_view_host()->SetPageEncoding(encoding_name);
// TODO(creis): should this be propagated to other and future RVHs?
}
void WebContents::CopyImageAt(int x, int y) {
- render_view_host_->CopyImageAt(x, y);
+ render_view_host()->CopyImageAt(x, y);
}
void WebContents::InspectElementAt(int x, int y) {
- render_view_host_->InspectElementAt(x, y);
+ render_view_host()->InspectElementAt(x, y);
}
void WebContents::ShowJavaScriptConsole() {
- render_view_host_->ShowJavaScriptConsole();
+ render_view_host()->ShowJavaScriptConsole();
}
void WebContents::AllowDomAutomationBindings() {
- render_view_host_->AllowDomAutomationBindings();
+ render_view_host()->AllowDomAutomationBindings();
// TODO(creis): should this be propagated to other and future RVHs?
}
@@ -1186,19 +780,7 @@ void WebContents::OnJavaScriptMessageBoxClosed(IPC::Message* reply_msg,
bool success,
const std::wstring& prompt) {
last_javascript_message_dismissal_ = TimeTicks::Now();
-
- RenderViewHost* rvh = render_view_host_;
- if (IsShowingInterstitialPage()) {
- // No JavaScript message boxes are ever shown by interstitial pages, but
- // they can be shown by the original RVH while an interstitial page is
- // showing (e.g., from an onunload event handler). We should send this to
- // the original RVH and not the interstitial's RVH.
- // TODO(creis): Perhaps the JavascriptMessageBoxHandler should store which
- // RVH created it, so that it can tell this method which RVH to reply to.
- DCHECK(original_render_view_host_);
- rvh = original_render_view_host_;
- }
- rvh->JavaScriptMessageBoxClosed(reply_msg, success, prompt);
+ render_manager_.OnJavaScriptMessageBoxClosed(reply_msg, success, prompt);
}
// Generic NotificationObserver callback.
@@ -1360,33 +942,33 @@ InfoBarView* WebContents::GetInfoBarView() {
void WebContents::ExecuteJavascriptInWebFrame(
const std::wstring& frame_xpath, const std::wstring& jscript) {
- render_view_host_->ExecuteJavascriptInWebFrame(frame_xpath, jscript);
+ render_view_host()->ExecuteJavascriptInWebFrame(frame_xpath, jscript);
}
void WebContents::AddMessageToConsole(
const std::wstring& frame_xpath, const std::wstring& msg,
ConsoleMessageLevel level) {
- render_view_host_->AddMessageToConsole(frame_xpath, msg, level);
+ render_view_host()->AddMessageToConsole(frame_xpath, msg, level);
}
void WebContents::Undo() {
- render_view_host_->Undo();
+ render_view_host()->Undo();
}
void WebContents::Redo() {
- render_view_host_->Redo();
+ render_view_host()->Redo();
}
void WebContents::Replace(const std::wstring& text) {
- render_view_host_->Replace(text);
+ render_view_host()->Replace(text);
}
void WebContents::Delete() {
- render_view_host_->Delete();
+ render_view_host()->Delete();
}
void WebContents::SelectAll() {
- render_view_host_->SelectAll();
+ render_view_host()->SelectAll();
}
void WebContents::StartFileUpload(const std::wstring& file_path,
@@ -1394,7 +976,7 @@ void WebContents::StartFileUpload(const std::wstring& file_path,
const std::wstring& file,
const std::wstring& submit,
const std::wstring& other_values) {
- render_view_host_->UploadFile(file_path, form, file, submit, other_values);
+ render_view_host()->UploadFile(file_path, form, file, submit, other_values);
}
void WebContents::SetWebApp(WebApp* web_app) {
@@ -1435,35 +1017,35 @@ void WebContents::CreateShortcut() {
// Request the application info. When done OnDidGetApplicationInfo is invoked
// and we'll create the shortcut.
- render_view_host_->GetApplicationInfo(pending_install_.page_id);
+ render_view_host()->GetApplicationInfo(pending_install_.page_id);
}
void WebContents::FillForm(const FormData& form) {
- render_view_host_->FillForm(form);
+ render_view_host()->FillForm(form);
}
void WebContents::FillPasswordForm(
const PasswordFormDomManager::FillData& form_data) {
- render_view_host_->FillPasswordForm(form_data);
+ render_view_host()->FillPasswordForm(form_data);
}
void WebContents::DragTargetDragEnter(const WebDropData& drop_data,
const gfx::Point& client_pt, const gfx::Point& screen_pt) {
- render_view_host_->DragTargetDragEnter(drop_data, client_pt, screen_pt);
+ render_view_host()->DragTargetDragEnter(drop_data, client_pt, screen_pt);
}
void WebContents::DragTargetDragOver(
const gfx::Point& client_pt, const gfx::Point& screen_pt) {
- render_view_host_->DragTargetDragOver(client_pt, screen_pt);
+ render_view_host()->DragTargetDragOver(client_pt, screen_pt);
}
void WebContents::DragTargetDragLeave() {
- render_view_host_->DragTargetDragLeave();
+ render_view_host()->DragTargetDragLeave();
}
void WebContents::DragTargetDrop(
const gfx::Point& client_pt, const gfx::Point& screen_pt) {
- render_view_host_->DragTargetDrop(client_pt, screen_pt);
+ render_view_host()->DragTargetDrop(client_pt, screen_pt);
}
PasswordManager* WebContents::GetPasswordManager() {
@@ -1478,16 +1060,6 @@ PluginInstaller* WebContents::GetPluginInstaller() {
return plugin_installer_.get();
}
-RenderProcessHost* WebContents::process() const {
- return render_view_host_->process();
-}
-RenderViewHost* WebContents::render_view_host() const {
- return render_view_host_;
-}
-SiteInstance* WebContents::site_instance() const {
- return render_view_host_->site_instance();
-}
-
bool WebContents::IsActiveEntry(int32 page_id) {
NavigationEntry* active_entry = controller()->GetActiveEntry();
return (active_entry != NULL &&
@@ -1516,7 +1088,9 @@ void WebContents::CreateView(int route_id, HANDLE modal_dialog_event) {
// other issues. We should fix this.
HWND new_view_parent_window = ::GetAncestor(GetHWND(), GA_ROOT);
new_view->CreateView(new_view_parent_window, gfx::Rect());
- new_view->CreatePageView(new_view->render_view_host_);
+ // TODO(brettw) it seems bogus that we have to call this function on the
+ // newly created object and give it one of its own member variables.
+ new_view->CreatePageView(new_view->render_view_host());
// Don't show the view until we get enough context in ShowView.
pending_views_[route_id] = new_view;
@@ -1529,7 +1103,7 @@ void WebContents::CreateWidget(int route_id) {
// We set the parent HWDN explicitly as pop-up HWNDs are parented and owned by
// the first non-child HWND of the HWND that was specified to the CreateWindow
// call.
- widget_view->set_parent_hwnd(render_view_host_->view()->GetPluginHWND());
+ widget_view->set_parent_hwnd(view()->GetPluginHWND());
widget_view->set_close_on_deactivate(true);
// Don't show the widget until we get its position in ShowWidget.
@@ -1549,13 +1123,14 @@ void WebContents::ShowView(int route_id,
WebContents* new_view = iter->second;
pending_views_.erase(route_id);
- if (!new_view->render_view_host_->view() ||
- !new_view->render_view_host_->process()->channel()) {
+ if (!new_view->view() ||
+ !new_view->process()->channel()) {
// The view has gone away or the renderer crashed. Nothing to do.
return;
}
- new_view->render_view_host_->Init();
+ // TODO(brettw) this seems bogus to reach into here and initialize the host.
+ new_view->render_view_host()->Init();
AddNewContents(new_view, disposition, initial_pos, user_gesture);
}
@@ -1586,11 +1161,12 @@ void WebContents::ShowWidget(int route_id, const gfx::Rect& initial_pos) {
widget_host->Init();
}
-void WebContents::RendererReady(RenderViewHost* render_view_host) {
- if (IsShowingInterstitialPage() && (render_view_host == render_view_host_)) {
+void WebContents::RendererReady(RenderViewHost* rvh) {
+ if (render_manager_.showing_interstitial_page() &&
+ rvh == render_view_host()) {
// We are showing an interstitial page, don't notify the world.
return;
- } else if (render_view_host != render_view_host_) {
+ } else if (rvh != render_view_host()) {
// Don't notify the world, since this came from a renderer in the
// background.
return;
@@ -1600,11 +1176,11 @@ void WebContents::RendererReady(RenderViewHost* render_view_host) {
SetIsCrashed(false);
}
-void WebContents::RendererGone(RenderViewHost* render_view_host) {
+void WebContents::RendererGone(RenderViewHost* rvh) {
// Ask the print preview if this renderer was valuable.
- if (!printing_.OnRendererGone(render_view_host))
+ if (!printing_.OnRendererGone(rvh))
return;
- if (render_view_host != render_view_host_) {
+ if (rvh != render_view_host()) {
// The pending or interstitial page's RenderViewHost is gone. If we are
// showing an interstitial, this may mean that the original RenderViewHost
// is gone. If so, we will call RendererGone again if we try to swap that
@@ -1634,16 +1210,14 @@ void WebContents::RendererGone(RenderViewHost* render_view_host) {
HungRendererWarning::HideForWebContents(this);
}
-void WebContents::DidNavigate(RenderViewHost* render_view_host,
+void WebContents::DidNavigate(RenderViewHost* rvh,
const ViewHostMsg_FrameNavigate_Params& params) {
if (PageTransition::IsMainFrame(params.transition))
- UpdateRendererStateDidNavigate(render_view_host);
+ render_manager_.DidNavigateMainFrame(rvh);
// In the case of interstitial, we don't mess with the navigation entries.
- if (IsShowingInterstitialPage()) {
- DCHECK(renderer_state_ != LEAVING_INTERSTITIAL);
+ if (render_manager_.showing_interstitial_page())
return;
- }
// Check for navigations we don't expect.
if (!controller() || !is_active_ || params.page_id == -1) {
@@ -1653,7 +1227,7 @@ void WebContents::DidNavigate(RenderViewHost* render_view_host,
"invalid |page_id| if, and only if, this is the initial blank "
"page for a main frame.";
}
- BroadcastProvisionalLoadCommit(render_view_host, params);
+ BroadcastProvisionalLoadCommit(rvh, params);
return;
}
@@ -1688,7 +1262,7 @@ void WebContents::DidNavigate(RenderViewHost* render_view_host,
// Run post-commit tasks.
if (PageTransition::IsMainFrame(params.transition))
DidNavigateMainFramePostCommit(params);
- DidNavigateAnyFramePostCommit(render_view_host, params);
+ DidNavigateAnyFramePostCommit(rvh, params);
}
NavigationEntry* WebContents::CreateNavigationEntryForCommit(
@@ -1710,7 +1284,12 @@ NavigationEntry* WebContents::CreateNavigationEntryForCommit(
// Update the site of the SiteInstance if it doesn't have one yet, unless we
// are showing an interstitial page. If we are, we should wait until the
// real page commits.
- if (!site_instance()->has_site() && renderer_state_ != INTERSTITIAL)
+ //
+ // TODO(brettw) the old code only checked for INTERSTIAL, this new code also
+ // checks for LEAVING_INTERSTITIAL mode in the manager. Is this difference
+ // important?
+ if (!site_instance()->has_site() &&
+ !render_manager_.showing_interstitial_page())
site_instance()->SetSite(params.url);
// When the navigation is just a change in ref or a sub-frame navigation, the
@@ -1973,117 +1552,8 @@ void WebContents::HandleProfilingForDidNavigate(
params.page_id);
profiler->AddFrameMetrics(process()->host_id(),
- render_view_host_->routing_id(), frame);
- }
-}
-
-void WebContents::UpdateRendererStateDidNavigate(
- RenderViewHost* render_view_host) {
- if (renderer_state_ == NORMAL) {
- // We should only hear this from our current renderer.
- DCHECK(render_view_host == render_view_host_);
- return;
- } else if (renderer_state_ == PENDING) {
- if (render_view_host == pending_render_view_host_) {
- // The pending cross-site navigation completed, so show the renderer.
- SwapToRenderView(&pending_render_view_host_, true);
- renderer_state_ = NORMAL;
- } else if (render_view_host == render_view_host_) {
- // A navigation in the original page has taken place. Cancel the pending
- // one.
- CancelRenderView(&pending_render_view_host_);
- renderer_state_ = NORMAL;
- } else {
- // No one else should be sending us DidNavigate in this state.
- DCHECK(false);
- return;
- }
-
- } else if (renderer_state_ == ENTERING_INTERSTITIAL) {
- if (render_view_host == interstitial_render_view_host_) {
- // The interstitial renderer is ready, so show it, and keep the old
- // RenderViewHost around.
- original_render_view_host_ = render_view_host_;
- SwapToRenderView(&interstitial_render_view_host_, false);
- renderer_state_ = INTERSTITIAL;
- } else if (render_view_host == render_view_host_) {
- // We shouldn't get here, because the original render view was the one
- // that caused the ShowInterstitial.
- // However, until we intercept navigation events from JavaScript, it is
- // possible to get here, if another tab tells render_view_host_ to
- // navigate. To be safe, we'll cancel the interstitial and show the
- // page that caused the DidNavigate.
- CancelRenderView(&interstitial_render_view_host_);
- if (pending_render_view_host_)
- CancelRenderView(&pending_render_view_host_);
- renderer_state_ = NORMAL;
- } else if (render_view_host == pending_render_view_host_) {
- // We shouldn't get here, because the original render view was the one
- // that caused the ShowInterstitial.
- // However, until we intercept navigation events from JavaScript, it is
- // possible to get here, if another tab tells pending_render_view_host_
- // to navigate. To be safe, we'll cancel the interstitial and show the
- // page that caused the DidNavigate.
- CancelRenderView(&interstitial_render_view_host_);
- SwapToRenderView(&pending_render_view_host_, true);
- renderer_state_ = NORMAL;
- } else {
- // No one else should be sending us DidNavigate in this state.
- DCHECK(false);
- return;
- }
-
- } else if (renderer_state_ == INTERSTITIAL) {
- if (render_view_host == original_render_view_host_) {
- // We shouldn't get here, because the original render view was the one
- // that caused the ShowInterstitial.
- // However, until we intercept navigation events from JavaScript, it is
- // possible to get here, if another tab tells render_view_host_ to
- // navigate. To be safe, we'll cancel the interstitial and show the
- // page that caused the DidNavigate.
- SwapToRenderView(&original_render_view_host_, true);
- if (pending_render_view_host_)
- CancelRenderView(&pending_render_view_host_);
- renderer_state_ = NORMAL;
- } else if (render_view_host == pending_render_view_host_) {
- // No one else should be sending us DidNavigate in this state.
- // However, until we intercept navigation events from JavaScript, it is
- // possible to get here, if another tab tells pending_render_view_host_
- // to navigate. To be safe, we'll cancel the interstitial and show the
- // page that caused the DidNavigate.
- SwapToRenderView(&pending_render_view_host_, true);
- CancelRenderView(&original_render_view_host_);
- renderer_state_ = NORMAL;
- } else {
- // No one else should be sending us DidNavigate in this state.
- DCHECK(false);
- return;
- }
- InterstitialPageGone();
-
- } else if (renderer_state_ == LEAVING_INTERSTITIAL) {
- if (render_view_host == original_render_view_host_) {
- // We navigated to something in the original renderer, so show it.
- if (pending_render_view_host_)
- CancelRenderView(&pending_render_view_host_);
- SwapToRenderView(&original_render_view_host_, true);
- renderer_state_ = NORMAL;
- } else if (render_view_host == pending_render_view_host_) {
- // We navigated to something in the pending renderer.
- CancelRenderView(&original_render_view_host_);
- SwapToRenderView(&pending_render_view_host_, true);
- renderer_state_ = NORMAL;
- } else {
- // No one else should be sending us DidNavigate in this state.
- DCHECK(false);
- return;
- }
- InterstitialPageGone();
-
- } else {
- // No such state.
- DCHECK(false);
- return;
+ render_view_host()->routing_id(),
+ frame);
}
}
@@ -2092,7 +1562,7 @@ void WebContents::BroadcastProvisionalLoadCommit(
const ViewHostMsg_FrameNavigate_Params& params) {
ProvisionalLoadDetails details(
PageTransition::IsMainFrame(params.transition),
- IsInterstitialRenderViewHost(render_view_host),
+ render_manager_.IsRenderViewInterstitial(render_view_host),
IsInPageNavigation(params.url),
params.url, params.security_info);
NotificationService::current()->
@@ -2119,51 +1589,6 @@ void WebContents::UpdateWebPreferences() {
render_view_host()->UpdateWebPreferences(GetWebkitPrefs());
}
-void WebContents::SwapToRenderView(RenderViewHost** new_render_view_host,
- bool destroy_after) {
- // Remember if the page was focused so we can focus the new renderer in
- // that case.
- bool focus_render_view = render_view_host_->view() &&
- render_view_host_->view()->HasFocus();
-
- // Hide the current view and prepare to destroy it.
- // TODO(creis): Get the old RenderViewHost to send us an UpdateState message
- // before we destroy it.
- if (render_view_host_->view())
- render_view_host_->view()->Hide();
- 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;
-
- // If the view is gone, then this RenderViewHost died while it was hidden.
- // We ignored the RendererGone call at the time, so we should send it now
- // to make sure the sad tab shows up, etc.
- if (render_view_host_->view())
- render_view_host_->view()->Show();
- else
- RendererGone(render_view_host_);
-
- // Make sure the size is up to date. (Fix for bug 1079768.)
- UpdateRenderViewSize();
-
- if (focus_render_view && render_view_host_->view())
- render_view_host_->view()->Focus();
-
- NotificationService::current()->Notify(
- NOTIFY_RENDER_VIEW_HOST_CHANGED,
- Source<WebContents>(this),
- Details<RenderViewHost>(old_render_view_host));
-
- if (destroy_after)
- old_render_view_host->Shutdown();
-
- // Let the task manager know that we've swapped RenderViewHosts, since it
- // might need to update its process groupings.
- NotifySwapped();
-}
-
void WebContents::UpdateRenderViewSize() {
// Using same technique as OnPaint, which sets size of SadTab.
CRect cr;
@@ -2172,12 +1597,13 @@ void WebContents::UpdateRenderViewSize() {
SizeContents(new_size);
}
-void WebContents::UpdateState(RenderViewHost* render_view_host,
+void WebContents::UpdateState(RenderViewHost* rvh,
int32 page_id,
const GURL& url,
const std::wstring& title,
const std::string& state) {
- if (render_view_host != render_view_host_ || IsShowingInterstitialPage()) {
+ if (rvh != render_view_host() ||
+ render_manager_.showing_interstitial_page()) {
// This UpdateState is either:
// - targeted not at the current RenderViewHost. This could be that we are
// showing the interstitial page and getting an update for the regular page,
@@ -2234,7 +1660,7 @@ void WebContents::UpdateState(RenderViewHost* render_view_host,
if (GetHWND()) {
// It's possible to get this after the hwnd has been destroyed.
::SetWindowText(GetHWND(), title.c_str());
- ::SetWindowText(render_view_host_->view()->GetPluginHWND(), title.c_str());
+ ::SetWindowText(view()->GetPluginHWND(), title.c_str());
}
// Update the state (forms, etc.).
@@ -2249,7 +1675,7 @@ void WebContents::UpdateState(RenderViewHost* render_view_host,
controller()->SyncSessionWithEntryByPageID(type(), site_instance(), page_id);
}
-void WebContents::UpdateTitle(RenderViewHost* render_view_host,
+void WebContents::UpdateTitle(RenderViewHost* rvh,
int32 page_id, const std::wstring& title) {
if (!controller())
return;
@@ -2259,7 +1685,8 @@ void WebContents::UpdateTitle(RenderViewHost* render_view_host,
response_started_ = false;
NavigationEntry* entry;
- if (IsShowingInterstitialPage() && (render_view_host == render_view_host_)) {
+ if (render_manager_.showing_interstitial_page() &&
+ (rvh == render_view_host())) {
// We are showing an interstitial page in a different RenderViewHost, so
// the page_id is not sufficient to find the entry from the controller.
// (both RenderViewHost page_ids overlap). We know it is the last entry,
@@ -2316,9 +1743,9 @@ void WebContents::UpdateThumbnail(const GURL& url,
}
}
-void WebContents::Close(RenderViewHost* render_view_host) {
+void WebContents::Close(RenderViewHost* rvh) {
// Ignore this if it comes from a RenderViewHost that we aren't showing.
- if (delegate() && render_view_host == render_view_host_)
+ if (delegate() && rvh == render_view_host())
delegate()->CloseContents(this);
}
@@ -2339,7 +1766,7 @@ void WebContents::DidStopLoading(RenderViewHost* rvh, int32 page_id) {
NavigationProfiler* profiler = GetNavigationProfiler();
profiler->SetLoadingEndTime(process()->host_id(),
- render_view_host_->routing_id(), page_id,
+ render_view_host()->routing_id(), page_id,
current_time);
SaveCurrentProfilingEntry();
}
@@ -2380,10 +1807,11 @@ void WebContents::DidStartProvisionalLoadForFrame(
RenderViewHost* render_view_host,
bool is_main_frame,
const GURL& url) {
- ProvisionalLoadDetails details(is_main_frame,
- IsInterstitialRenderViewHost(render_view_host),
- IsInPageNavigation(url),
- url, std::string());
+ ProvisionalLoadDetails details(
+ is_main_frame,
+ render_manager_.IsRenderViewInterstitial(render_view_host),
+ IsInPageNavigation(url),
+ url, std::string());
NotificationService::current()->
Notify(NOTIFY_FRAME_PROVISIONAL_LOAD_START,
Source<NavigationController>(controller()),
@@ -2431,78 +1859,27 @@ void WebContents::DidFailProvisionalLoadWithError(
if (!controller())
return;
- // This will discard our pending entry if we cancelled the load (e.g., if we
- // 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.
if (net::ERR_ABORTED == error_code) {
+ // This will discard our pending entry if we cancelled the load (e.g., if we
+ // 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()->GetPendingEntry();
if (pending_entry && pending_entry->GetURL() == url)
controller()->DiscardPendingEntry();
- // We used to cancel the pending renderer here for cross-site downloads.
- // However, it's not safe to do that because the download logic repeatedly
- // looks for this TabContents based on a render view ID. Instead, we just
- // leave the pending renderer around until the next navigation event
- // (Navigate, DidNavigate, etc), which will clean it up properly.
- // TODO(creis): All of this will go away when we move the cross-site logic
- // to ResourceDispatcherHost, so that we intercept responses rather than
- // navigation events. (That's necessary to support onunload anyway.) Once
- // we've made that change, we won't create a pending renderer until we know
- // the response is not a download.
-
- if (renderer_state_ == ENTERING_INTERSTITIAL) {
- if ((pending_render_view_host_ &&
- (pending_render_view_host_ == render_view_host)) ||
- (!pending_render_view_host_ &&
- (render_view_host_ == render_view_host))) {
- // The abort came from the RenderViewHost that triggered the
- // interstitial. (e.g., User clicked stop after ShowInterstitial but
- // before the interstitial was visible.) We should go back to NORMAL.
- // Note that this is an uncommon case, because we are only in the
- // ENTERING_INTERSTITIAL state in the small time window while the
- // interstitial's RenderViewHost is being created.
- if (pending_render_view_host_)
- CancelRenderView(&pending_render_view_host_);
- CancelRenderView(&interstitial_render_view_host_);
- renderer_state_ = NORMAL;
- }
- // We can get here, at least in the following case.
- // We show an interstitial, then navigate to a URL that leads to another
- // interstitial. Now there's a race. The new interstitial will be
- // created and we will go to ENTERING_INTERSTITIAL, but the old one will
- // meanwhile destroy itself and fire DidFailProvisionalLoad. That puts
- // us here. Should be safe to ignore the DidFailProvisionalLoad, from
- // the perspective of the renderer state.
- } else if (renderer_state_ == LEAVING_INTERSTITIAL) {
- // If we've left the interstitial by seeing a download (or otherwise
- // aborting a load), we should get back to the original page, because
- // interstitial page doesn't make sense anymore. (For example, we may
- // have clicked Proceed on a download URL.)
-
- // TODO(creis): This causes problems in the old process model when
- // visiting a new URL from an interstitial page.
- // This is because we receive a DidFailProvisionalLoad from cancelling
- // the first request, which is indistinguishable from a
- // DidFailProvisionalLoad from the second request (if it is a download).
- // We need to find a way to distinguish these cases, because it doesn't
- // make sense to keep showing the interstitial after a download.
- // if (pending_render_view_host_)
- // CancelRenderView(&pending_render_view_host_);
- // SwapToRenderView(&original_render_view_host_, true);
- // renderer_state_ = NORMAL;
- // InterstitialPageGone();
- }
+ render_manager_.RendererAbortedProvisionalLoad(render_view_host);
}
// Send out a notification that we failed a provisional load with an error.
- ProvisionalLoadDetails details(is_main_frame,
- IsInterstitialRenderViewHost(render_view_host),
- IsInPageNavigation(url),
- url, std::string());
+ ProvisionalLoadDetails details(
+ is_main_frame,
+ render_manager_.IsRenderViewInterstitial(render_view_host),
+ IsInPageNavigation(url),
+ url, std::string());
details.set_error_code(error_code);
- showing_repost_interstitial_ = showing_repost_interstitial;
+ render_manager_.set_showing_repost_interstitial(showing_repost_interstitial);
NotificationService::current()->
Notify(NOTIFY_FAIL_PROVISIONAL_LOAD_WITH_ERROR,
@@ -2590,7 +1967,7 @@ void WebContents::StartDragging(const WebDropData& drop_data) {
data->SetString(drop_data.plain_text);
scoped_refptr<WebDragSource> drag_source(
- new WebDragSource(GetHWND(), render_view_host_));
+ new WebDragSource(GetHWND(), render_view_host()));
DWORD effects;
@@ -2601,7 +1978,8 @@ void WebContents::StartDragging(const WebDropData& drop_data) {
DoDragDrop(data, drag_source, DROPEFFECT_COPY | DROPEFFECT_LINK, &effects);
MessageLoop::current()->SetNestableTasksAllowed(old_state);
- render_view_host_->DragSourceSystemDragEnded();
+ if (render_view_host())
+ render_view_host()->DragSourceSystemDragEnded();
}
void WebContents::UpdateDragCursor(bool is_drop_target) {
@@ -2969,11 +2347,17 @@ void WebContents::UpdateMaxPageIDIfNecessary(SiteInstance* site_instance,
}
}
+void WebContents::BeforeUnloadFiredFromRenderManager(
+ bool proceed,
+ bool* proceed_to_fire_unload) {
+ delegate()->BeforeUnloadFired(this, proceed, proceed_to_fire_unload);
+}
+
+
HWND WebContents::GetContentHWND() {
- if (!render_view_host_ || !render_view_host_->view())
+ if (!view())
return NULL;
-
- return render_view_host_->view()->GetPluginHWND();
+ return view()->GetPluginHWND();
}
bool WebContents::CanDisplayFile(const std::wstring& full_path) {
@@ -2989,7 +2373,7 @@ bool WebContents::CanDisplayFile(const std::wstring& full_path) {
void WebContents::PrintPreview() {
// We can't print interstitial page for now.
- if (IsShowingInterstitialPage())
+ if (render_manager_.showing_interstitial_page())
return;
// If we have a FindInPage dialog, notify it that its tab was hidden.
@@ -3002,7 +2386,7 @@ void WebContents::PrintPreview() {
bool WebContents::PrintNow() {
// We can't print interstitial page for now.
- if (IsShowingInterstitialPage())
+ if (render_manager_.showing_interstitial_page())
return false;
// If we have a FindInPage dialog, notify it that its tab was hidden.
@@ -3021,19 +2405,19 @@ void WebContents::DidCaptureContents() {
}
void WebContents::Cut() {
- render_view_host_->Cut();
+ render_view_host()->Cut();
}
void WebContents::Copy() {
- render_view_host_->Copy();
+ render_view_host()->Copy();
}
void WebContents::Paste() {
- render_view_host_->Paste();
+ render_view_host()->Paste();
}
void WebContents::SetInitialFocus(bool reverse) {
- render_view_host_->SetInitialFocus(reverse);
+ render_view_host()->SetInitialFocus(reverse);
}
void WebContents::GenerateKeywordIfNecessary(
@@ -3148,21 +2532,8 @@ void WebContents::HandleKeyboardEvent(const WebKeyboardEvent& event) {
event.actual_message.lParam);
}
-RenderViewHost* WebContents::CreateRenderViewHost(
- SiteInstance* instance,
- RenderViewHostDelegate* delegate,
- int routing_id,
- HANDLE modal_dialog_event) {
- if (render_view_factory_) {
- return render_view_factory_->CreateRenderViewHost(
- instance, delegate, routing_id, modal_dialog_event);
- } else {
- return new RenderViewHost(instance, delegate, routing_id,
- modal_dialog_event);
- }
-}
-
-bool WebContents::CreateRenderView(RenderViewHost* render_view_host) {
+bool WebContents::CreateRenderViewForRenderManager(
+ RenderViewHost* render_view_host) {
RenderWidgetHostHWND* view = CreatePageView(render_view_host);
bool ok = render_view_host->CreateRenderView();
@@ -3199,239 +2570,25 @@ void WebContents::SetIsLoading(bool is_loading,
LoadNotificationDetails* details) {
if (!is_loading) {
load_state_ = net::LOAD_STATE_IDLE;
- load_state_host_ = std::wstring();
+ load_state_host_.clear();
}
TabContents::SetIsLoading(is_loading, details);
- // We don't know which render_view_host this is for, so let's tell them all
- render_view_host_->SetIsLoading(is_loading);
- if (pending_render_view_host_)
- pending_render_view_host_->SetIsLoading(is_loading);
- if (original_render_view_host_)
- original_render_view_host_->SetIsLoading(is_loading);
+ render_manager_.SetIsLoading(is_loading);
}
void WebContents::FileSelected(const std::wstring& path, void* params) {
- render_view_host_->FileSelected(path);
+ render_view_host()->FileSelected(path);
}
void WebContents::FileSelectionCanceled(void* params) {
// If the user cancels choosing a file to upload we need to pass back the
// empty string.
- render_view_host_->FileSelected(L"");
+ render_view_host()->FileSelected(std::wstring());
}
///////////////////////////////////////////////////////////////////////////////
-bool WebContents::IsShowingInterstitialPage() const {
- return (renderer_state_ == INTERSTITIAL) ||
- (renderer_state_ == LEAVING_INTERSTITIAL);
-}
-
-void WebContents::ShowInterstitialPage(const std::string& html_text,
- InterstitialPageDelegate* delegate) {
- // Note that it is important that the interstitial page render view host is
- // in the same process as the normal render view host for the tab, so they
- // use page ids from the same pool. If they came from different processes,
- // page ids may collide causing confusion in the controller (existing
- // navigation entries in the controller history could get overridden with the
- // interstitial entry).
- SiteInstance* interstitial_instance = NULL;
-
- if (renderer_state_ == NORMAL) {
- // render_view_host_ will not be deleted before the end of this method, so
- // we don't have to worry about this SiteInstance's ref count dropping to
- // zero.
- interstitial_instance = render_view_host_->site_instance();
-
- } else if (renderer_state_ == PENDING) {
- // pending_render_view_host_ will not be deleted before the end of this
- // method (when we are in this state), so we don't have to worry about this
- // SiteInstance's ref count dropping to zero.
- interstitial_instance = pending_render_view_host_->site_instance();
-
- } else if (renderer_state_ == ENTERING_INTERSTITIAL) {
- // We should never get here if we're in the process of showing an
- // interstitial.
- // However, until we intercept navigation events from JavaScript, it is
- // possible to get here, if another tab tells render_view_host_ to
- // navigate to a URL that causes an interstitial. To be safe, we'll cancel
- // the first interstitial.
- CancelRenderView(&interstitial_render_view_host_);
- renderer_state_ = NORMAL;
-
- // We'd like to now show the new interstitial, but if there's a
- // pending_render_view_host_, we can't tell if this JavaScript navigation
- // occurred in the original or the pending renderer. That means we won't
- // know where to proceed, so we can't show the interstitial. This is
- // really just meant to avoid a crash until we can intercept JavaScript
- // navigation events, so for now we'll kill the interstitial and go back
- // to the last known good page.
- if (pending_render_view_host_) {
- CancelRenderView(&pending_render_view_host_);
- return;
- }
- // Should be safe to show the interstitial for the new page.
- // render_view_host_ will not be deleted before the end of this method, so
- // we don't have to worry about this SiteInstance's ref count dropping to
- // zero.
- interstitial_instance = render_view_host_->site_instance();
-
- } else if (renderer_state_ == INTERSTITIAL) {
- // We should never get here if we're already showing an interstitial.
- // However, until we intercept navigation events from JavaScript, it is
- // possible to get here, if another tab tells render_view_host_ to
- // navigate to a URL that causes an interstitial. To be safe, we'll go
- // back to normal first.
- if (pending_render_view_host_ != NULL) {
- // There was a pending RVH. We don't know which RVH caused this call
- // to ShowInterstitial, so we can't really proceed. We'll have to stay
- // in the NORMAL state, showing the last good page. This is only a
- // temporary fix anyway, to stave off a crash.
- HideInterstitialPage(false, false);
- return;
- }
- // Should be safe to show the interstitial for the new page.
- // render_view_host_ will not be deleted before the end of this method, so
- // we don't have to worry about this SiteInstance's ref count dropping to
- // zero.
- SwapToRenderView(&original_render_view_host_, true);
- interstitial_instance = render_view_host_->site_instance();
-
- } else if (renderer_state_ == LEAVING_INTERSTITIAL) {
- SwapToRenderView(&original_render_view_host_, true);
- interstitial_instance = NULL;
- if (pending_render_view_host_) {
- // We're now effectively in PENDING.
- // pending_render_view_host_ will not be deleted before the end of this
- // method, so we don't have to worry about this SiteInstance's ref count
- // dropping to zero.
- interstitial_instance = pending_render_view_host_->site_instance();
- } else {
- // We're now effectively in NORMAL.
- // render_view_host_ will not be deleted before the end of this method,
- // so we don't have to worry about this SiteInstance's ref count dropping
- // to zero.
- interstitial_instance = render_view_host_->site_instance();
- }
-
- } else {
- // No such state.
- DCHECK(false);
- return;
- }
-
- // Create a pending renderer and move to ENTERING_INTERSTITIAL.
- interstitial_render_view_host_ =
- CreateRenderViewHost(interstitial_instance, this, MSG_ROUTING_NONE, NULL);
- interstitial_delegate_ = delegate;
- bool success = CreateRenderView(interstitial_render_view_host_);
- if (!success) {
- // TODO(creis): If this fails, should we load the interstitial in
- // render_view_host_? We shouldn't just skip the interstitial...
- CancelRenderView(&interstitial_render_view_host_);
- return;
- }
-
- // Don't show the view yet.
- interstitial_render_view_host_->view()->Hide();
-
- renderer_state_ = ENTERING_INTERSTITIAL;
-
- // We allow the DOM bindings as a way to get the page to talk back to us.
- interstitial_render_view_host_->AllowDomAutomationBindings();
-
- interstitial_render_view_host_->LoadAlternateHTMLString(html_text, false,
- GURL::EmptyGURL(),
- std::string());
-}
-
-void WebContents::HideInterstitialPage(bool wait_for_navigation,
- bool proceed) {
- if (renderer_state_ == NORMAL || renderer_state_ == PENDING) {
- // Shouldn't get here, since there's no interstitial showing.
- DCHECK(false);
- return;
-
- } else if (renderer_state_ == ENTERING_INTERSTITIAL) {
- // Unclear if it is possible to get here. (Can you hide the interstitial
- // before it is shown?) If so, we should go back to NORMAL.
- CancelRenderView(&interstitial_render_view_host_);
- if (pending_render_view_host_)
- CancelRenderView(&pending_render_view_host_);
- renderer_state_ = NORMAL;
- return;
- }
-
- DCHECK(IsShowingInterstitialPage());
- DCHECK(render_view_host_ && original_render_view_host_ &&
- !interstitial_render_view_host_);
-
- if (renderer_state_ == INTERSTITIAL) {
- // Disable the Proceed button on the interstitial, because the destination
- // renderer might get replaced.
- DisableInterstitialProceed(false);
-
- } else if (renderer_state_ == LEAVING_INTERSTITIAL) {
- // We have already given up the ability to proceed by starting a new
- // navigation. If this is a request to proceed, we must ignore it.
- // (Hopefully we will have disabled the Proceed button by now, but it's
- // possible to get here before that happens.)
- if (proceed)
- return;
- }
-
- if (wait_for_navigation) {
- // We are resuming the loading. We need to set the state to loading again
- // as it was set to false when the interstitial stopped loading (so the
- // throbber runs).
- DidStartLoading(render_view_host_, NULL);
- }
-
- if (proceed) {
- // Now we will resume loading automatically, either in
- // original_render_view_host_ or in pending_render_view_host_. When it
- // completes, we will display the renderer in DidNavigate.
- renderer_state_ = LEAVING_INTERSTITIAL;
-
- } else {
- // Don't proceed. Go back to the previously showing page.
- if (renderer_state_ == LEAVING_INTERSTITIAL) {
- // We said DontProceed after starting to leave the interstitial.
- // Abandon whatever we were in the process of doing.
- original_render_view_host_->Stop();
- }
- SwapToRenderView(&original_render_view_host_, true);
- if (pending_render_view_host_)
- CancelRenderView(&pending_render_view_host_);
- renderer_state_ = NORMAL;
- InterstitialPageGone();
- }
-}
-
-void WebContents::InterstitialPageGone() {
- DCHECK(!IsShowingInterstitialPage());
-
- NotificationService::current()->Notify(
- NOTIFY_INTERSTITIAL_PAGE_CLOSED,
- Source<WebContents>(this), NotificationService::NoDetails());
- if (interstitial_delegate_) {
- interstitial_delegate_->InterstitialClosed();
- interstitial_delegate_ = NULL;
- }
-}
-
-bool WebContents::IsInterstitialRenderViewHost(
- RenderViewHost* render_view_host) const {
- if (IsShowingInterstitialPage()) {
- return render_view_host_ == render_view_host;
- }
- if (renderer_state_ == ENTERING_INTERSTITIAL) {
- return interstitial_render_view_host_ == render_view_host;
- }
- return false;
-}
-
bool WebContents::IsInPageNavigation(const GURL& url) const {
// We compare to the last committed entry and not the active entry as the
// active entry is the current pending entry (if any).
@@ -3484,7 +2641,8 @@ void WebContents::InstallMissingPlugin() {
void WebContents::GetAllSavableResourceLinksForCurrentPage(
const GURL& page_url) {
- render_view_host_->GetAllSavableResourceLinksForCurrentPage(page_url);
+ render_view_host()->GetAllSavableResourceLinksForCurrentPage(
+ page_url);
}
void WebContents::OnReceivedSavableResourceLinksForCurrentPage(
@@ -3492,10 +2650,11 @@ void WebContents::OnReceivedSavableResourceLinksForCurrentPage(
const std::vector<GURL>& referrers_list,
const std::vector<GURL>& frames_list) {
SavePackage* save_package = get_save_package();
- if (save_package)
+ if (save_package) {
save_package->ProcessCurrentPageAllSavableResourceLinks(resources_list,
referrers_list,
frames_list);
+ }
}
void WebContents::GetSerializedHtmlDataForCurrentPageWithLocalLinks(
@@ -3521,8 +2680,8 @@ bool WebContents::CanBlur() const {
return delegate() ? delegate()->CanBlur() : true;
}
-void WebContents::RendererUnresponsive(RenderViewHost* render_view_host) {
- if (render_view_host_ && render_view_host_->IsRenderViewLive())
+void WebContents::RendererUnresponsive(RenderViewHost* rvh) {
+ if (render_view_host() && render_view_host()->IsRenderViewLive())
HungRendererWarning::ShowForWebContents(this);
}
@@ -3533,7 +2692,7 @@ void WebContents::RendererResponsive(RenderViewHost* render_view_host) {
void WebContents::LoadStateChanged(const GURL& url,
net::LoadState load_state) {
load_state_ = load_state;
- load_state_host_ = UTF8ToWide(url.host().c_str());
+ load_state_host_ = UTF8ToWide(url.host());
if (load_state_ == net::LOAD_STATE_READING_RESPONSE)
response_started_ = false;
if (is_loading())