summaryrefslogtreecommitdiffstats
path: root/chrome/browser/interstitial_page.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/interstitial_page.cc')
-rw-r--r--chrome/browser/interstitial_page.cc229
1 files changed, 45 insertions, 184 deletions
diff --git a/chrome/browser/interstitial_page.cc b/chrome/browser/interstitial_page.cc
index 6fee67f..5cbc37e 100644
--- a/chrome/browser/interstitial_page.cc
+++ b/chrome/browser/interstitial_page.cc
@@ -5,237 +5,98 @@
#include "chrome/browser/interstitial_page.h"
#include "chrome/browser/browser.h"
-#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_resources.h"
#include "chrome/browser/dom_operation_notification_details.h"
#include "chrome/browser/navigation_controller.h"
#include "chrome/browser/navigation_entry.h"
-#include "chrome/browser/render_widget_host_view_win.h"
+#include "chrome/browser/tab_contents.h"
#include "chrome/browser/web_contents.h"
-#include "chrome/browser/web_contents_view_win.h"
-#include "chrome/views/window.h"
-#include "chrome/views/window_delegate.h"
-#include "net/base/escape.h"
// static
InterstitialPage::InterstitialPageMap*
InterstitialPage::tab_to_interstitial_page_ = NULL;
-InterstitialPage::InterstitialPage(WebContents* tab,
- bool new_navigation,
+InterstitialPage::InterstitialPage(TabContents* tab,
+ bool create_navigation_entry,
const GURL& url)
: tab_(tab),
url_(url),
- action_taken_(false),
- enabled_(true),
- new_navigation_(new_navigation),
- render_view_host_(NULL),
- should_revert_tab_title_(false) {
+ delegate_has_been_notified_(false),
+ create_navigation_entry_(create_navigation_entry) {
InitInterstitialPageMap();
- // It would be inconsistent to create an interstitial with no new navigation
- // (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()->GetPendingEntry());
+
+ // If there's already an interstitial in this tab, then we're about to
+ // replace it. We should be ok with just deleting the previous
+ // InterstitialPage (not hiding it first), since we're about to be shown.
+ InterstitialPageMap::const_iterator iter =
+ tab_to_interstitial_page_->find(tab_);
+ if (iter != tab_to_interstitial_page_->end()) {
+ // Deleting the InterstitialPage will also remove it from the map.
+ delete iter->second;
+ }
+ (*tab_to_interstitial_page_)[tab_] = this;
+
+ // Register for DOM operations, this is how the page notifies us of the user
+ // selection.
+ notification_registrar_.Add(this, NOTIFY_DOM_OPERATION_RESPONSE,
+ Source<TabContents>(tab_));
}
InterstitialPage::~InterstitialPage() {
InterstitialPageMap::iterator iter = tab_to_interstitial_page_->find(tab_);
DCHECK(iter != tab_to_interstitial_page_->end());
tab_to_interstitial_page_->erase(iter);
- DCHECK(!render_view_host_);
}
void InterstitialPage::Show() {
- // If an interstitial is already showing, close it before showing the new one.
- if (tab_->interstitial_page())
- tab_->interstitial_page()->DontProceed();
+ DCHECK(tab_->type() == TAB_CONTENTS_WEB);
+ WebContents* tab = tab_->AsWebContents();
- // Update the tab_to_interstitial_page_ map.
- InterstitialPageMap::const_iterator iter =
- tab_to_interstitial_page_->find(tab_);
- DCHECK(iter == tab_to_interstitial_page_->end());
- (*tab_to_interstitial_page_)[tab_] = this;
+ if (create_navigation_entry_) {
+ NavigationEntry* entry = new NavigationEntry(TAB_CONTENTS_WEB);
+ entry->set_url(url_);
+ entry->set_display_url(url_);
+ entry->set_page_type(NavigationEntry::INTERSTITIAL_PAGE);
- if (new_navigation_) {
- NavigationEntry* entry = new NavigationEntry(TAB_CONTENTS_WEB);
- entry->set_url(url_);
- entry->set_display_url(url_);
- entry->set_page_type(NavigationEntry::INTERSTITIAL_PAGE);
-
- // Give sub-classes a chance to set some states on the navigation entry.
- UpdateEntry(entry);
-
- tab_->controller()->AddTransientEntry(entry);
- }
-
- DCHECK(!render_view_host_);
- render_view_host_ = CreateRenderViewHost();
-
- std::string data_url = "data:text/html;charset=utf-8," +
- EscapePath(GetHTMLContents());
- render_view_host_->NavigateToURL(GURL(data_url));
-
- notification_registrar_.Add(this, NOTIFY_TAB_CONTENTS_DESTROYED,
- Source<TabContents>(tab_));
- notification_registrar_.Add(this, NOTIFY_NAV_ENTRY_COMMITTED,
- Source<NavigationController>(tab_->controller()));
- notification_registrar_.Add(this, NOTIFY_NAV_ENTRY_PENDING,
- Source<NavigationController>(tab_->controller()));
-}
+ // Give sub-classes a chance to set some states on the navigation entry.
+ UpdateEntry(entry);
-void InterstitialPage::Hide() {
- render_view_host_->Shutdown();
- render_view_host_ = NULL;
- if (tab_->interstitial_page())
- tab_->remove_interstitial_page();
- // Let's revert to the original title if necessary.
- NavigationEntry* entry = tab_->controller()->GetActiveEntry();
- if (!new_navigation_ && should_revert_tab_title_) {
- entry->set_title(original_tab_title_);
- tab_->NotifyNavigationStateChanged(TabContents::INVALIDATE_TITLE);
+ tab_->controller()->AddTransientEntry(entry);
}
- delete this;
+
+ tab->ShowInterstitialPage(this);
}
void InterstitialPage::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
- if (type == NOTIFY_NAV_ENTRY_PENDING) {
- // We are navigating away from the interstitial. Make sure clicking on the
- // interstitial will have no effect.
- Disable();
- return;
- }
- DCHECK(type == NOTIFY_TAB_CONTENTS_DESTROYED ||
- type == NOTIFY_NAV_ENTRY_COMMITTED);
- if (!action_taken_) {
- // We are navigating away from the interstitial or closing a tab with an
- // interstitial. Default to DontProceed(). We don't just call Hide as
- // subclasses will almost certainly override DontProceed to do some work
- // (ex: close pending connections).
- DontProceed();
- } else {
- // User decided to proceed and either the navigation was committed or the
- // tab was closed before that.
- Hide();
- // WARNING: we are now deleted!
- }
+ DCHECK(type == NOTIFY_DOM_OPERATION_RESPONSE);
+ std::string json = Details<DomOperationNotificationDetails>(details)->json();
+ CommandReceived(json);
}
-RenderViewHost* InterstitialPage::CreateRenderViewHost() {
- RenderViewHost* render_view_host = new RenderViewHost(
- SiteInstance::CreateSiteInstance(tab()->profile()),
- this, MSG_ROUTING_NONE, NULL);
- RenderWidgetHostViewWin* view =
- new RenderWidgetHostViewWin(render_view_host);
- render_view_host->set_view(view);
- view->Create(tab_->GetContentHWND());
- view->set_parent_hwnd(tab_->GetContentHWND());
- WebContentsViewWin* web_contents_view =
- static_cast<WebContentsViewWin*>(tab_->view());
- render_view_host->CreateRenderView();
- // SetSize must be called after CreateRenderView or the HWND won't show.
- view->SetSize(web_contents_view->GetContainerSize());
-
- render_view_host->AllowDomAutomationBindings();
- return render_view_host;
-}
+void InterstitialPage::InterstitialClosed() {
+ delete this;
+}
void InterstitialPage::Proceed() {
- DCHECK(!action_taken_);
- Disable();
- action_taken_ = true;
-
- // Resumes the throbber.
- tab_->SetIsLoading(true, NULL);
-
- // No need to hide if we are a new navigation, we'll get hidden when the
- // navigation is committed.
- if (!new_navigation_) {
- Hide();
- // WARNING: we are now deleted!
- }
+ DCHECK(tab_->type() == TAB_CONTENTS_WEB);
+ tab_->AsWebContents()->HideInterstitialPage(true, true);
}
void InterstitialPage::DontProceed() {
- DCHECK(!action_taken_);
- Disable();
- action_taken_ = true;
-
- if (new_navigation_) {
+ if (create_navigation_entry_) {
// Since no navigation happens we have to discard the transient entry
// 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_->AsWebContents()->HideInterstitialPage(false, false);
- Hide();
// WARNING: we are now deleted!
}
-void InterstitialPage::SetSize(const gfx::Size& size) {
- render_view_host_->view()->SetSize(size);
-}
-
-Profile* InterstitialPage::GetProfile() const {
- return tab_->profile();
-}
-
-void InterstitialPage::DidNavigate(
- RenderViewHost* render_view_host,
- const ViewHostMsg_FrameNavigate_Params& params) {
- // A fast user could have navigated away from the page that triggered the
- // interstitial while the interstitial was loading, that would have disabled
- // us. In that case we can dismiss ourselves.
- if (!enabled_){
- DontProceed();
- return;
- }
-
- // The RenderViewHost has loaded its contents, we can show it now.
- render_view_host_->view()->Show();
- tab_->set_interstitial_page(this);
-
- // Notify the tab we are not loading so the throbber is stopped. It also
- // causes a NOTIFY_LOAD_STOP notification, that the AutomationProvider (used
- // by the UI tests) expects to consider a navigation as complete. Without this,
- // navigating in a UI test to a URL that triggers an interstitial would hang.
- tab_->SetIsLoading(false, NULL);
-}
-
-void InterstitialPage::RendererGone(RenderViewHost* render_view_host) {
- // Our renderer died. This should not happen in normal cases.
- // Just dismiss the interstitial.
- DontProceed();
-}
-
-void InterstitialPage::DomOperationResponse(const std::string& json_string,
- int automation_id) {
- if (enabled_)
- CommandReceived(json_string);
-}
-
-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();
- // 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_) {
- original_tab_title_ = entry->title();
- should_revert_tab_title_ = true;
- }
- entry->set_title(title);
- tab_->NotifyNavigationStateChanged(TabContents::INVALIDATE_TITLE);
-}
-
-void InterstitialPage::Disable() {
- enabled_ = false;
-}
-
// static
void InterstitialPage::InitInterstitialPageMap() {
if (!tab_to_interstitial_page_)
@@ -244,10 +105,10 @@ void InterstitialPage::InitInterstitialPageMap() {
// static
InterstitialPage* InterstitialPage::GetInterstitialPage(
- WebContents* web_contents) {
+ TabContents* tab_contents) {
InitInterstitialPageMap();
InterstitialPageMap::const_iterator iter =
- tab_to_interstitial_page_->find(web_contents);
+ tab_to_interstitial_page_->find(tab_contents);
if (iter == tab_to_interstitial_page_->end())
return NULL;