summaryrefslogtreecommitdiffstats
path: root/components/web_modal
diff options
context:
space:
mode:
authorwittman@chromium.org <wittman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-06 05:17:59 +0000
committerwittman@chromium.org <wittman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-06 05:17:59 +0000
commita02358d357f618507170daf192a9485e51bbc3c0 (patch)
treec0059de683878844a86e6a4ede76d7baea8c0174 /components/web_modal
parent5e3484fcaf2acc8f3cf44db4fbb9a75596440d04 (diff)
downloadchromium_src-a02358d357f618507170daf192a9485e51bbc3c0.zip
chromium_src-a02358d357f618507170daf192a9485e51bbc3c0.tar.gz
chromium_src-a02358d357f618507170daf192a9485e51bbc3c0.tar.bz2
Provide configurable closing of web contents modal dialogs on interstitial webui
Allow individual web contents modal dialog users to specify that dialogs should be closed when encountering interstitial webui (e.g. due to SSL warnings). Future CLs will enable use of this functionality for most dialogs. BUG=240575 Review URL: https://chromiumcodereview.appspot.com/23981002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@221575 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'components/web_modal')
-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) {