diff options
author | Andras Becsi <andras.becsi@digia.com> | 2013-12-11 21:33:03 +0100 |
---|---|---|
committer | Andras Becsi <andras.becsi@digia.com> | 2013-12-13 12:34:07 +0100 |
commit | f2a33ff9cbc6d19943f1c7fbddd1f23d23975577 (patch) | |
tree | 0586a32aa390ade8557dfd6b4897f43a07449578 /chromium/components/web_modal | |
parent | 5362912cdb5eea702b68ebe23702468d17c3017a (diff) | |
download | qtwebengine-chromium-f2a33ff9cbc6d19943f1c7fbddd1f23d23975577.tar.gz |
Update Chromium to branch 1650 (31.0.1650.63)
Change-Id: I57d8c832eaec1eb2364e0a8e7352a6dd354db99f
Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
Diffstat (limited to 'chromium/components/web_modal')
6 files changed, 389 insertions, 56 deletions
diff --git a/chromium/components/web_modal/OWNERS b/chromium/components/web_modal/OWNERS new file mode 100644 index 00000000000..ddd924dfa6a --- /dev/null +++ b/chromium/components/web_modal/OWNERS @@ -0,0 +1,2 @@ +wittman@chromium.org +ben@chromium.org diff --git a/chromium/components/web_modal/native_web_contents_modal_dialog_manager.h b/chromium/components/web_modal/native_web_contents_modal_dialog_manager.h index 7145a08c088..4df36800c71 100644 --- a/chromium/components/web_modal/native_web_contents_modal_dialog_manager.h +++ b/chromium/components/web_modal/native_web_contents_modal_dialog_manager.h @@ -13,6 +13,8 @@ class WebContents; namespace web_modal { +class WebContentsModalDialogHost; + // Interface from NativeWebContentsModalDialogManager to // WebContentsModalDialogManager. class NativeWebContentsModalDialogManagerDelegate { @@ -54,6 +56,9 @@ class NativeWebContentsModalDialogManager { // Runs a pulse animation for the web contents modal dialog. virtual void PulseDialog(NativeWebContentsModalDialog dialog) = 0; + // Called when the host view for the dialog has changed. + virtual void HostChanged(WebContentsModalDialogHost* new_host) = 0; + protected: NativeWebContentsModalDialogManager() {} diff --git a/chromium/components/web_modal/web_contents_modal_dialog_host.h b/chromium/components/web_modal/web_contents_modal_dialog_host.h index 499925cac21..73a3a7a0da6 100644 --- a/chromium/components/web_modal/web_contents_modal_dialog_host.h +++ b/chromium/components/web_modal/web_contents_modal_dialog_host.h @@ -6,8 +6,11 @@ #define COMPONENTS_WEB_MODAL_WEB_CONTENTS_MODAL_DIALOG_HOST_H_ #include "ui/gfx/native_widget_types.h" -#include "ui/gfx/point.h" -#include "ui/gfx/size.h" + +namespace gfx { +class Point; +class Size; +} namespace web_modal { @@ -18,6 +21,7 @@ class WebContentsModalDialogHostObserver { virtual ~WebContentsModalDialogHostObserver(); virtual void OnPositionRequiresUpdate() = 0; + virtual void OnHostDestroying() = 0; protected: WebContentsModalDialogHostObserver(); @@ -38,6 +42,9 @@ class WebContentsModalDialogHost { // view. virtual gfx::Point GetDialogPosition(const gfx::Size& size) = 0; + // Returns the maximum dimensions a dialog can have. + virtual gfx::Size GetMaximumDialogSize() = 0; + // Add/remove observer. virtual void AddObserver(WebContentsModalDialogHostObserver* observer) = 0; virtual void RemoveObserver(WebContentsModalDialogHostObserver* observer) = 0; diff --git a/chromium/components/web_modal/web_contents_modal_dialog_manager.cc b/chromium/components/web_modal/web_contents_modal_dialog_manager.cc index 0e07f8dd1d9..4d8aca714c5 100644 --- a/chromium/components/web_modal/web_contents_modal_dialog_manager.cc +++ b/chromium/components/web_modal/web_contents_modal_dialog_manager.cc @@ -25,9 +25,16 @@ WebContentsModalDialogManager::~WebContentsModalDialogManager() { DCHECK(child_dialogs_.empty()); } +void WebContentsModalDialogManager::SetDelegate( + WebContentsModalDialogManagerDelegate* d) { + delegate_ = d; + // Delegate can be NULL on Views/Win32 during tab drag. + native_manager_->HostChanged(d ? d->GetWebContentsModalDialogHost() : NULL); +} + void WebContentsModalDialogManager::ShowDialog( NativeWebContentsModalDialog dialog) { - child_dialogs_.push_back(dialog); + child_dialogs_.push_back(DialogState(dialog)); native_manager_->ManageDialog(dialog); @@ -38,13 +45,21 @@ void WebContentsModalDialogManager::ShowDialog( } } -bool WebContentsModalDialogManager::IsShowingDialog() const { +bool WebContentsModalDialogManager::IsDialogActive() const { return !child_dialogs_.empty(); } 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 { @@ -53,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. @@ -65,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()); } @@ -75,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( @@ -98,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) { @@ -118,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; } @@ -135,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) { @@ -146,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/chromium/components/web_modal/web_contents_modal_dialog_manager.h b/chromium/components/web_modal/web_contents_modal_dialog_manager.h index e2548c04e5c..58d5520b9fc 100644 --- a/chromium/components/web_modal/web_contents_modal_dialog_manager.h +++ b/chromium/components/web_modal/web_contents_modal_dialog_manager.h @@ -29,7 +29,7 @@ class WebContentsModalDialogManager virtual ~WebContentsModalDialogManager(); WebContentsModalDialogManagerDelegate* delegate() const { return delegate_; } - void set_delegate(WebContentsModalDialogManagerDelegate* d) { delegate_ = d; } + void SetDelegate(WebContentsModalDialogManagerDelegate* d); static NativeWebContentsModalDialogManager* CreateNativeManager( NativeWebContentsModalDialogManagerDelegate* native_delegate); @@ -38,13 +38,17 @@ class WebContentsModalDialogManager // WillClose() when it is being destroyed. void ShowDialog(NativeWebContentsModalDialog dialog); - // Returns true if a dialog is currently being shown. - bool IsShowingDialog() const; + // Returns true if any dialogs are active and not closed. + bool IsDialogActive() const; - // Focus the topmost modal dialog. IsShowingDialog() must be true when - // calling this function. + // Focus the topmost modal dialog. IsDialogActive() must be true when 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. @@ -62,6 +66,7 @@ class WebContentsModalDialogManager : manager_(manager) {} void CloseAllDialogs() { manager_->CloseAllDialogs(); } + void DidAttachInterstitialPage() { manager_->DidAttachInterstitialPage(); } void ResetNativeManager(NativeWebContentsModalDialogManager* delegate) { manager_->native_manager_.reset(delegate); } @@ -76,7 +81,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); @@ -92,6 +108,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/chromium/components/web_modal/web_contents_modal_dialog_manager_unittest.cc b/chromium/components/web_modal/web_contents_modal_dialog_manager_unittest.cc index 1268896d6af..bb866916264 100644 --- a/chromium/components/web_modal/web_contents_modal_dialog_manager_unittest.cc +++ b/chromium/components/web_modal/web_contents_modal_dialog_manager_unittest.cc @@ -2,80 +2,340 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <map> + +#include "base/memory/scoped_ptr.h" #include "components/web_modal/native_web_contents_modal_dialog_manager.h" #include "components/web_modal/web_contents_modal_dialog_manager.h" -#include "content/public/browser/browser_thread.h" +#include "components/web_modal/web_contents_modal_dialog_manager_delegate.h" +#include "content/public/browser/notification_details.h" +#include "content/public/browser/notification_service.h" +#include "content/public/browser/notification_source.h" +#include "content/public/browser/notification_types.h" #include "content/public/test/test_renderer_host.h" #include "testing/gtest/include/gtest/gtest.h" -using content::BrowserThread; - namespace web_modal { -class WebContentsModalDialogManagerTest - : public content::RenderViewHostTestHarness { - public: - virtual void SetUp() { - content::RenderViewHostTestHarness::SetUp(); - WebContentsModalDialogManager::CreateForWebContents(web_contents()); - } -}; - -class NativeWebContentsModalDialogManagerCloseTest +class TestNativeWebContentsModalDialogManager : public NativeWebContentsModalDialogManager { public: - NativeWebContentsModalDialogManagerCloseTest( + enum DialogState { + UNKNOWN, + NOT_SHOWN, + SHOWN, + HIDDEN, + CLOSED + }; + + explicit TestNativeWebContentsModalDialogManager( NativeWebContentsModalDialogManagerDelegate* delegate) : delegate_(delegate) {} virtual void ManageDialog(NativeWebContentsModalDialog dialog) OVERRIDE { + dialog_state_[dialog] = NOT_SHOWN; } virtual void ShowDialog(NativeWebContentsModalDialog dialog) OVERRIDE { + dialog_state_[dialog] = SHOWN; } virtual void HideDialog(NativeWebContentsModalDialog dialog) OVERRIDE { + dialog_state_[dialog] = HIDDEN; } virtual void CloseDialog(NativeWebContentsModalDialog dialog) OVERRIDE { delegate_->WillClose(dialog); - close_count++; + dialog_state_[dialog] = CLOSED; } virtual void FocusDialog(NativeWebContentsModalDialog dialog) OVERRIDE { } virtual void PulseDialog(NativeWebContentsModalDialog dialog) OVERRIDE { } + virtual void HostChanged(WebContentsModalDialogHost* new_host) OVERRIDE { + } + + int GetCloseCount() const { + int count = 0; + for (DialogStateMap::const_iterator it = dialog_state_.begin(); + it != dialog_state_.end(); ++it) { + if (it->second == CLOSED) + count++; + } + return count; + } + + DialogState GetDialogState(NativeWebContentsModalDialog dialog) const { + DialogStateMap::const_iterator loc = dialog_state_.find(dialog); + return loc == dialog_state_.end() ? UNKNOWN : loc->second; + } + + private: + typedef std::map<NativeWebContentsModalDialog, DialogState> DialogStateMap; - int close_count; NativeWebContentsModalDialogManagerDelegate* delegate_; + DialogStateMap dialog_state_; + + DISALLOW_COPY_AND_ASSIGN(TestNativeWebContentsModalDialogManager); +}; + +class TestWebContentsModalDialogManagerDelegate + : public WebContentsModalDialogManagerDelegate { + public: + TestWebContentsModalDialogManagerDelegate() + : web_contents_visible_(true), + web_contents_blocked_(false) { + } + + // WebContentsModalDialogManagerDelegate overrides + virtual void SetWebContentsBlocked(content::WebContents* web_contents, + bool blocked) OVERRIDE { + web_contents_blocked_ = blocked; + } + + virtual WebContentsModalDialogHost* GetWebContentsModalDialogHost() OVERRIDE { + return NULL; + } + + virtual bool IsWebContentsVisible( + content::WebContents* web_contents) OVERRIDE { + return web_contents_visible_; + } + + void set_web_contents_visible(bool visible) { + web_contents_visible_ = visible; + } + + bool web_contents_blocked() const { return web_contents_blocked_; } + + private: + bool web_contents_visible_; + bool web_contents_blocked_; + + DISALLOW_COPY_AND_ASSIGN(TestWebContentsModalDialogManagerDelegate); }; -NativeWebContentsModalDialogManager* WebContentsModalDialogManager:: -CreateNativeManager( +class WebContentsModalDialogManagerTest + : public content::RenderViewHostTestHarness { + public: + WebContentsModalDialogManagerTest() + : next_dialog_id(1), + manager(NULL), + native_manager(NULL) { + } + + virtual void SetUp() { + content::RenderViewHostTestHarness::SetUp(); + + delegate.reset(new TestWebContentsModalDialogManagerDelegate); + WebContentsModalDialogManager::CreateForWebContents(web_contents()); + manager = WebContentsModalDialogManager::FromWebContents(web_contents()); + manager->SetDelegate(delegate.get()); + test_api.reset(new WebContentsModalDialogManager::TestApi(manager)); + native_manager = new TestNativeWebContentsModalDialogManager(manager); + + // |manager| owns |native_manager| as a result. + test_api->ResetNativeManager(native_manager); + } + + virtual void TearDown() { + test_api.reset(); + content::RenderViewHostTestHarness::TearDown(); + } + + protected: + NativeWebContentsModalDialog MakeFakeDialog() { + // WebContentsModalDialogManager treats the NativeWebContentsModalDialog as + // an opaque type, so creating fake NativeWebContentsModalDialogs using + // reinterpret_cast is valid. + return reinterpret_cast<NativeWebContentsModalDialog>(next_dialog_id++); + } + + int next_dialog_id; + scoped_ptr<TestWebContentsModalDialogManagerDelegate> delegate; + WebContentsModalDialogManager* manager; + scoped_ptr<WebContentsModalDialogManager::TestApi> test_api; + TestNativeWebContentsModalDialogManager* native_manager; + + DISALLOW_COPY_AND_ASSIGN(WebContentsModalDialogManagerTest); +}; + +NativeWebContentsModalDialogManager* +WebContentsModalDialogManager::CreateNativeManager( NativeWebContentsModalDialogManagerDelegate* native_delegate) { - return new NativeWebContentsModalDialogManagerCloseTest(native_delegate); + return new TestNativeWebContentsModalDialogManager(native_delegate); +} + +// Test that the dialog is shown immediately when the delegate indicates the web +// contents is visible. +TEST_F(WebContentsModalDialogManagerTest, WebContentsVisible) { + // Dialog should be shown while WebContents is visible. + const NativeWebContentsModalDialog dialog1 = MakeFakeDialog(); + + manager->ShowDialog(dialog1); + + EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN, + native_manager->GetDialogState(dialog1)); + EXPECT_TRUE(manager->IsDialogActive()); + EXPECT_TRUE(delegate->web_contents_blocked()); } -TEST_F(WebContentsModalDialogManagerTest, WebContentsModalDialogs) { - WebContentsModalDialogManager* web_contents_modal_dialog_manager = - WebContentsModalDialogManager::FromWebContents(web_contents()); - WebContentsModalDialogManager::TestApi test_api( - web_contents_modal_dialog_manager); +// Test that the dialog is not shown immediately when the delegate indicates the +// web contents is not visible. +TEST_F(WebContentsModalDialogManagerTest, WebContentsNotVisible) { + // Dialog should not be shown while WebContents is not visible. + delegate->set_web_contents_visible(false); + + const NativeWebContentsModalDialog dialog1 = MakeFakeDialog(); + + manager->ShowDialog(dialog1); + + EXPECT_EQ(TestNativeWebContentsModalDialogManager::NOT_SHOWN, + native_manager->GetDialogState(dialog1)); + EXPECT_TRUE(manager->IsDialogActive()); + EXPECT_TRUE(delegate->web_contents_blocked()); +} + +// Test that only the first of multiple dialogs is shown. +TEST_F(WebContentsModalDialogManagerTest, ShowDialogs) { + const NativeWebContentsModalDialog dialog1 = MakeFakeDialog(); + const NativeWebContentsModalDialog dialog2 = MakeFakeDialog(); + const NativeWebContentsModalDialog dialog3 = MakeFakeDialog(); + + manager->ShowDialog(dialog1); + manager->ShowDialog(dialog2); + manager->ShowDialog(dialog3); + + EXPECT_TRUE(delegate->web_contents_blocked()); + EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN, + native_manager->GetDialogState(dialog1)); + EXPECT_EQ(TestNativeWebContentsModalDialogManager::NOT_SHOWN, + native_manager->GetDialogState(dialog2)); + EXPECT_EQ(TestNativeWebContentsModalDialogManager::NOT_SHOWN, + native_manager->GetDialogState(dialog3)); +} + +// Test that the dialog is shown/hidden on +// NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED. +TEST_F(WebContentsModalDialogManagerTest, VisibilityObservation) { + const NativeWebContentsModalDialog dialog1 = MakeFakeDialog(); + bool web_contents_visible = true; + + manager->ShowDialog(dialog1); + + EXPECT_TRUE(manager->IsDialogActive()); + EXPECT_TRUE(delegate->web_contents_blocked()); + EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN, + native_manager->GetDialogState(dialog1)); + + web_contents_visible = false; + manager->Observe(content::NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED, + content::NotificationService::AllSources(), + content::Details<bool>(&web_contents_visible)); - NativeWebContentsModalDialogManagerCloseTest* native_manager = - new NativeWebContentsModalDialogManagerCloseTest( - web_contents_modal_dialog_manager); - native_manager->close_count = 0; + EXPECT_TRUE(manager->IsDialogActive()); + EXPECT_TRUE(delegate->web_contents_blocked()); + EXPECT_EQ(TestNativeWebContentsModalDialogManager::HIDDEN, + native_manager->GetDialogState(dialog1)); - test_api.ResetNativeManager(native_manager); + web_contents_visible = true; + manager->Observe(content::NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED, + content::NotificationService::AllSources(), + content::Details<bool>(&web_contents_visible)); + EXPECT_TRUE(manager->IsDialogActive()); + EXPECT_TRUE(delegate->web_contents_blocked()); + EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN, + 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) { + // The front dialog is always shown regardless of dialog close order. + const NativeWebContentsModalDialog dialog1 = MakeFakeDialog(); + const NativeWebContentsModalDialog dialog2 = MakeFakeDialog(); + const NativeWebContentsModalDialog dialog3 = MakeFakeDialog(); + const NativeWebContentsModalDialog dialog4 = MakeFakeDialog(); + + manager->ShowDialog(dialog1); + manager->ShowDialog(dialog2); + manager->ShowDialog(dialog3); + manager->ShowDialog(dialog4); + + native_manager->CloseDialog(dialog1); + + EXPECT_TRUE(manager->IsDialogActive()); + EXPECT_TRUE(delegate->web_contents_blocked()); + EXPECT_EQ(TestNativeWebContentsModalDialogManager::CLOSED, + native_manager->GetDialogState(dialog1)); + EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN, + native_manager->GetDialogState(dialog2)); + EXPECT_EQ(TestNativeWebContentsModalDialogManager::NOT_SHOWN, + native_manager->GetDialogState(dialog3)); + EXPECT_EQ(TestNativeWebContentsModalDialogManager::NOT_SHOWN, + native_manager->GetDialogState(dialog4)); + + native_manager->CloseDialog(dialog3); + + EXPECT_TRUE(manager->IsDialogActive()); + EXPECT_TRUE(delegate->web_contents_blocked()); + EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN, + native_manager->GetDialogState(dialog2)); + EXPECT_EQ(TestNativeWebContentsModalDialogManager::CLOSED, + native_manager->GetDialogState(dialog3)); + EXPECT_EQ(TestNativeWebContentsModalDialogManager::NOT_SHOWN, + native_manager->GetDialogState(dialog4)); + + native_manager->CloseDialog(dialog2); + + EXPECT_TRUE(manager->IsDialogActive()); + EXPECT_TRUE(delegate->web_contents_blocked()); + EXPECT_EQ(TestNativeWebContentsModalDialogManager::CLOSED, + native_manager->GetDialogState(dialog2)); + EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN, + native_manager->GetDialogState(dialog4)); + + native_manager->CloseDialog(dialog4); + + EXPECT_FALSE(manager->IsDialogActive()); + EXPECT_FALSE(delegate->web_contents_blocked()); + EXPECT_EQ(TestNativeWebContentsModalDialogManager::CLOSED, + native_manager->GetDialogState(dialog4)); +} + +// Test that CloseAllDialogs does what it says. +TEST_F(WebContentsModalDialogManagerTest, CloseAllDialogs) { const int kWindowCount = 4; for (int i = 0; i < kWindowCount; i++) - // WebContentsModalDialogManager treats the NativeWebContentsModalDialog as - // an opaque type, so creating fake NativeWebContentsModalDialogs using - // reinterpret_cast is valid. - web_contents_modal_dialog_manager->ShowDialog( - reinterpret_cast<NativeWebContentsModalDialog>(i)); - EXPECT_EQ(native_manager->close_count, 0); + manager->ShowDialog(MakeFakeDialog()); + + EXPECT_EQ(0, native_manager->GetCloseCount()); - test_api.CloseAllDialogs(); - EXPECT_EQ(native_manager->close_count, kWindowCount); + test_api->CloseAllDialogs(); + EXPECT_FALSE(delegate->web_contents_blocked()); + EXPECT_FALSE(manager->IsDialogActive()); + EXPECT_EQ(kWindowCount, native_manager->GetCloseCount()); } } // namespace web_modal |