diff options
Diffstat (limited to 'components')
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) { |