summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/web_modal/web_contents_modal_dialog_manager.cc55
-rw-r--r--components/web_modal/web_contents_modal_dialog_manager.h19
-rw-r--r--components/web_modal/web_contents_modal_dialog_manager_unittest.cc24
3 files changed, 87 insertions, 11 deletions
diff --git a/components/web_modal/web_contents_modal_dialog_manager.cc b/components/web_modal/web_contents_modal_dialog_manager.cc
index f30b6a0..949abbf 100644
--- a/components/web_modal/web_contents_modal_dialog_manager.cc
+++ b/components/web_modal/web_contents_modal_dialog_manager.cc
@@ -34,7 +34,7 @@ void WebContentsModalDialogManager::SetDelegate(
void WebContentsModalDialogManager::ShowDialog(
NativeWebContentsModalDialog dialog) {
- child_dialogs_.push_back(dialog);
+ child_dialogs_.push_back(DialogState(dialog));
native_manager_->ManageDialog(dialog);
@@ -51,7 +51,15 @@ bool WebContentsModalDialogManager::IsShowingDialog() const {
void WebContentsModalDialogManager::FocusTopmostDialog() {
DCHECK(!child_dialogs_.empty());
- native_manager_->FocusDialog(child_dialogs_.front());
+ native_manager_->FocusDialog(child_dialogs_.front().dialog);
+}
+
+void WebContentsModalDialogManager::SetCloseOnInterstitialWebUI(
+ NativeWebContentsModalDialog dialog,
+ bool close) {
+ WebContentsModalDialogList::iterator loc = FindDialogState(dialog);
+ DCHECK(loc != child_dialogs_.end());
+ loc->close_on_interstitial_webui = close;
}
content::WebContents* WebContentsModalDialogManager::GetWebContents() const {
@@ -60,8 +68,7 @@ content::WebContents* WebContentsModalDialogManager::GetWebContents() const {
void WebContentsModalDialogManager::WillClose(
NativeWebContentsModalDialog dialog) {
- WebContentsModalDialogList::iterator i(
- std::find(child_dialogs_.begin(), child_dialogs_.end(), dialog));
+ WebContentsModalDialogList::iterator i = FindDialogState(dialog);
// The Views tab contents modal dialog calls WillClose twice. Ignore the
// second invocation.
@@ -72,7 +79,7 @@ void WebContentsModalDialogManager::WillClose(
child_dialogs_.erase(i);
if (!child_dialogs_.empty() && removed_topmost_dialog &&
!closing_all_dialogs_)
- native_manager_->ShowDialog(child_dialogs_.front());
+ native_manager_->ShowDialog(child_dialogs_.front().dialog);
BlockWebContentsInteraction(!child_dialogs_.empty());
}
@@ -82,15 +89,14 @@ void WebContentsModalDialogManager::Observe(
const content::NotificationSource& source,
const content::NotificationDetails& details) {
DCHECK(type == content::NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED);
-
if (child_dialogs_.empty())
return;
bool visible = *content::Details<bool>(details).ptr();
if (visible)
- native_manager_->ShowDialog(child_dialogs_.front());
+ native_manager_->ShowDialog(child_dialogs_.front().dialog);
else
- native_manager_->HideDialog(child_dialogs_.front());
+ native_manager_->HideDialog(child_dialogs_.front().dialog);
}
WebContentsModalDialogManager::WebContentsModalDialogManager(
@@ -105,6 +111,24 @@ WebContentsModalDialogManager::WebContentsModalDialogManager(
content::Source<content::WebContents>(web_contents));
}
+WebContentsModalDialogManager::DialogState::DialogState(
+ NativeWebContentsModalDialog dialog)
+ : dialog(dialog),
+ close_on_interstitial_webui(false) {
+}
+
+WebContentsModalDialogManager::WebContentsModalDialogList::iterator
+ WebContentsModalDialogManager::FindDialogState(
+ NativeWebContentsModalDialog dialog) {
+ WebContentsModalDialogList::iterator i;
+ for (i = child_dialogs_.begin(); i != child_dialogs_.end(); ++i) {
+ if (i->dialog == dialog)
+ break;
+ }
+
+ return i;
+}
+
void WebContentsModalDialogManager::BlockWebContentsInteraction(bool blocked) {
WebContents* contents = web_contents();
if (!contents) {
@@ -125,7 +149,7 @@ void WebContentsModalDialogManager::CloseAllDialogs() {
// Clear out any dialogs since we are leaving this page entirely.
while (!child_dialogs_.empty())
- native_manager_->CloseDialog(child_dialogs_.front());
+ native_manager_->CloseDialog(child_dialogs_.front().dialog);
closing_all_dialogs_ = false;
}
@@ -142,7 +166,7 @@ void WebContentsModalDialogManager::DidNavigateMainFrame(
void WebContentsModalDialogManager::DidGetIgnoredUIEvent() {
if (!child_dialogs_.empty())
- native_manager_->FocusDialog(child_dialogs_.front());
+ native_manager_->FocusDialog(child_dialogs_.front().dialog);
}
void WebContentsModalDialogManager::WebContentsDestroyed(WebContents* tab) {
@@ -153,4 +177,15 @@ void WebContentsModalDialogManager::WebContentsDestroyed(WebContents* tab) {
CloseAllDialogs();
}
+void WebContentsModalDialogManager::DidAttachInterstitialPage() {
+ // Copy the dialogs so we can close and remove them while iterating over the
+ // list.
+ WebContentsModalDialogList dialogs(child_dialogs_);
+ for (WebContentsModalDialogList::iterator it = dialogs.begin();
+ it != dialogs.end(); ++it) {
+ if (it->close_on_interstitial_webui)
+ native_manager_->CloseDialog(it->dialog);
+ }
+}
+
} // namespace web_modal
diff --git a/components/web_modal/web_contents_modal_dialog_manager.h b/components/web_modal/web_contents_modal_dialog_manager.h
index 5502c09..eff0e2c 100644
--- a/components/web_modal/web_contents_modal_dialog_manager.h
+++ b/components/web_modal/web_contents_modal_dialog_manager.h
@@ -47,6 +47,10 @@ class WebContentsModalDialogManager
// calling this function.
void FocusTopmostDialog();
+ // Set to true to close the window when a page load starts on the WebContents.
+ void SetCloseOnInterstitialWebUI(NativeWebContentsModalDialog dialog,
+ bool close);
+
// Overriden from NativeWebContentsModalDialogManagerDelegate:
virtual content::WebContents* GetWebContents() const OVERRIDE;
// Called when a WebContentsModalDialogs we own is about to be closed.
@@ -64,6 +68,7 @@ class WebContentsModalDialogManager
: manager_(manager) {}
void CloseAllDialogs() { manager_->CloseAllDialogs(); }
+ void DidAttachInterstitialPage() { manager_->DidAttachInterstitialPage(); }
void ResetNativeManager(NativeWebContentsModalDialogManager* delegate) {
manager_->native_manager_.reset(delegate);
}
@@ -78,7 +83,18 @@ class WebContentsModalDialogManager
explicit WebContentsModalDialogManager(content::WebContents* web_contents);
friend class content::WebContentsUserData<WebContentsModalDialogManager>;
- typedef std::deque<NativeWebContentsModalDialog> WebContentsModalDialogList;
+ struct DialogState {
+ explicit DialogState(NativeWebContentsModalDialog dialog);
+
+ NativeWebContentsModalDialog dialog;
+ bool close_on_interstitial_webui;
+ };
+
+ typedef std::deque<DialogState> WebContentsModalDialogList;
+
+ // Utility function to get the dialog state for a dialog.
+ WebContentsModalDialogList::iterator FindDialogState(
+ NativeWebContentsModalDialog dialog);
// Blocks/unblocks interaction with renderer process.
void BlockWebContentsInteraction(bool blocked);
@@ -94,6 +110,7 @@ class WebContentsModalDialogManager
const content::FrameNavigateParams& params) OVERRIDE;
virtual void DidGetIgnoredUIEvent() OVERRIDE;
virtual void WebContentsDestroyed(content::WebContents* tab) OVERRIDE;
+ virtual void DidAttachInterstitialPage() OVERRIDE;
// Delegate for notifying our owner about stuff. Not owned by us.
WebContentsModalDialogManagerDelegate* delegate_;
diff --git a/components/web_modal/web_contents_modal_dialog_manager_unittest.cc b/components/web_modal/web_contents_modal_dialog_manager_unittest.cc
index 837824e..31af59c 100644
--- a/components/web_modal/web_contents_modal_dialog_manager_unittest.cc
+++ b/components/web_modal/web_contents_modal_dialog_manager_unittest.cc
@@ -245,6 +245,30 @@ TEST_F(WebContentsModalDialogManagerTest, VisibilityObservation) {
native_manager->GetDialogState(dialog1));
}
+// Test that attaching an interstitial WebUI page closes dialogs configured to
+// close on interstitial WebUI.
+TEST_F(WebContentsModalDialogManagerTest, InterstitialWebUI) {
+ const NativeWebContentsModalDialog dialog1 = MakeFakeDialog();
+ const NativeWebContentsModalDialog dialog2 = MakeFakeDialog();
+ const NativeWebContentsModalDialog dialog3 = MakeFakeDialog();
+
+ manager->ShowDialog(dialog1);
+ manager->ShowDialog(dialog2);
+ manager->ShowDialog(dialog3);
+
+ manager->SetCloseOnInterstitialWebUI(dialog1, true);
+ manager->SetCloseOnInterstitialWebUI(dialog3, true);
+
+ test_api->DidAttachInterstitialPage();
+ EXPECT_EQ(TestNativeWebContentsModalDialogManager::CLOSED,
+ native_manager->GetDialogState(dialog1));
+ EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN,
+ native_manager->GetDialogState(dialog2));
+ EXPECT_EQ(TestNativeWebContentsModalDialogManager::CLOSED,
+ native_manager->GetDialogState(dialog3));
+}
+
+
// Test that the first dialog is always shown, regardless of the order in which
// dialogs are closed.
TEST_F(WebContentsModalDialogManagerTest, CloseDialogs) {