diff options
author | Zeno Albisser <zeno.albisser@digia.com> | 2013-08-15 21:46:11 +0200 |
---|---|---|
committer | Zeno Albisser <zeno.albisser@digia.com> | 2013-08-15 21:46:11 +0200 |
commit | 679147eead574d186ebf3069647b4c23e8ccace6 (patch) | |
tree | fc247a0ac8ff119f7c8550879ebb6d3dd8d1ff69 /chromium/components/web_modal | |
download | qtwebengine-chromium-679147eead574d186ebf3069647b4c23e8ccace6.tar.gz |
Initial import.
Diffstat (limited to 'chromium/components/web_modal')
10 files changed, 585 insertions, 0 deletions
diff --git a/chromium/components/web_modal/DEPS b/chromium/components/web_modal/DEPS new file mode 100644 index 00000000000..3539cc43913 --- /dev/null +++ b/chromium/components/web_modal/DEPS @@ -0,0 +1,6 @@ +include_rules = [ + "+content/public/browser", + "+content/public/test", + "+net/base", + "+ui/gfx", +] diff --git a/chromium/components/web_modal/native_web_contents_modal_dialog.h b/chromium/components/web_modal/native_web_contents_modal_dialog.h new file mode 100644 index 00000000000..266e073ab9c --- /dev/null +++ b/chromium/components/web_modal/native_web_contents_modal_dialog.h @@ -0,0 +1,22 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_WEB_MODAL_NATIVE_WEB_CONTENTS_MODAL_DIALOG_H_ +#define COMPONENTS_WEB_MODAL_NATIVE_WEB_CONTENTS_MODAL_DIALOG_H_ + +#include "ui/gfx/native_widget_types.h" + +namespace web_modal { + +#if defined(OS_MACOSX) +// Use a void* since none of the gfx::Native* types are suitable for +// representing the web contents modal dialog under Cocoa. +typedef void* NativeWebContentsModalDialog; +#else +typedef gfx::NativeView NativeWebContentsModalDialog; +#endif + +} // namespace web_modal + +#endif // COMPONENTS_WEB_MODAL_NATIVE_WEB_CONTENTS_MODAL_DIALOG_H_ 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 new file mode 100644 index 00000000000..7145a08c088 --- /dev/null +++ b/chromium/components/web_modal/native_web_contents_modal_dialog_manager.h @@ -0,0 +1,66 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_WEB_MODAL_NATIVE_WEB_CONTENTS_MODAL_DIALOG_MANAGER_H_ +#define COMPONENTS_WEB_MODAL_NATIVE_WEB_CONTENTS_MODAL_DIALOG_MANAGER_H_ + +#include "components/web_modal/native_web_contents_modal_dialog.h" + +namespace content { +class WebContents; +} // namespace content + +namespace web_modal { + +// Interface from NativeWebContentsModalDialogManager to +// WebContentsModalDialogManager. +class NativeWebContentsModalDialogManagerDelegate { + public: + NativeWebContentsModalDialogManagerDelegate() {} + virtual ~NativeWebContentsModalDialogManagerDelegate() {} + + virtual content::WebContents* GetWebContents() const = 0; + virtual void WillClose(NativeWebContentsModalDialog dialog) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(NativeWebContentsModalDialogManagerDelegate); +}; + +// Provides an interface for platform-specific UI implementation for the web +// contents modal dialog. +class NativeWebContentsModalDialogManager { + public: + virtual ~NativeWebContentsModalDialogManager() {} + + // Starts management of the modal aspects of the dialog. This function should + // also register to be notified when the dialog is closing, so that it can + // notify the manager. + virtual void ManageDialog(NativeWebContentsModalDialog dialog) = 0; + + // Makes the web contents modal dialog visible. Only one web contents modal + // dialog is shown at a time per tab. + virtual void ShowDialog(NativeWebContentsModalDialog dialog) = 0; + + // Hides the web contents modal dialog without closing it. + virtual void HideDialog(NativeWebContentsModalDialog dialog) = 0; + + // Closes the web contents modal dialog. + virtual void CloseDialog(NativeWebContentsModalDialog dialog) = 0; + + // Sets focus on the web contents modal dialog. + virtual void FocusDialog(NativeWebContentsModalDialog dialog) = 0; + + // Runs a pulse animation for the web contents modal dialog. + virtual void PulseDialog(NativeWebContentsModalDialog dialog) = 0; + + protected: + NativeWebContentsModalDialogManager() {} + + private: + DISALLOW_COPY_AND_ASSIGN(NativeWebContentsModalDialogManager); +}; + +} // namespace web_modal + +#endif // COMPONENTS_WEB_MODAL_NATIVE_WEB_CONTENTS_MODAL_DIALOG_MANAGER_H_ diff --git a/chromium/components/web_modal/web_contents_modal_dialog_host.cc b/chromium/components/web_modal/web_contents_modal_dialog_host.cc new file mode 100644 index 00000000000..1dcaa00508e --- /dev/null +++ b/chromium/components/web_modal/web_contents_modal_dialog_host.cc @@ -0,0 +1,21 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/web_modal/web_contents_modal_dialog_host.h" + +namespace web_modal { + +WebContentsModalDialogHostObserver::~WebContentsModalDialogHostObserver() { +} + +WebContentsModalDialogHostObserver::WebContentsModalDialogHostObserver() { +} + +WebContentsModalDialogHost::~WebContentsModalDialogHost() { +} + +WebContentsModalDialogHost::WebContentsModalDialogHost() { +} + +} // namespace web_modal diff --git a/chromium/components/web_modal/web_contents_modal_dialog_host.h b/chromium/components/web_modal/web_contents_modal_dialog_host.h new file mode 100644 index 00000000000..499925cac21 --- /dev/null +++ b/chromium/components/web_modal/web_contents_modal_dialog_host.h @@ -0,0 +1,54 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_WEB_MODAL_WEB_CONTENTS_MODAL_DIALOG_HOST_H_ +#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 web_modal { + +// Observer to be implemented to update web contents modal dialogs when the host +// indicates their position needs to be changed. +class WebContentsModalDialogHostObserver { + public: + virtual ~WebContentsModalDialogHostObserver(); + + virtual void OnPositionRequiresUpdate() = 0; + + protected: + WebContentsModalDialogHostObserver(); + + private: + DISALLOW_COPY_AND_ASSIGN(WebContentsModalDialogHostObserver); +}; + +// Interface for supporting positioning of web contents modal dialogs over a +// window/widget. +class WebContentsModalDialogHost { + public: + virtual ~WebContentsModalDialogHost(); + + // Returns the view against which the dialog is positioned and parented. + virtual gfx::NativeView GetHostView() const = 0; + // Gets the position for the dialog in coordinates relative to the host + // view. + virtual gfx::Point GetDialogPosition(const gfx::Size& size) = 0; + + // Add/remove observer. + virtual void AddObserver(WebContentsModalDialogHostObserver* observer) = 0; + virtual void RemoveObserver(WebContentsModalDialogHostObserver* observer) = 0; + + protected: + WebContentsModalDialogHost(); + + private: + DISALLOW_COPY_AND_ASSIGN(WebContentsModalDialogHost); +}; + +} // namespace web_modal + +#endif // COMPONENTS_WEB_MODAL_WEB_CONTENTS_MODAL_DIALOG_HOST_H_ diff --git a/chromium/components/web_modal/web_contents_modal_dialog_manager.cc b/chromium/components/web_modal/web_contents_modal_dialog_manager.cc new file mode 100644 index 00000000000..0e07f8dd1d9 --- /dev/null +++ b/chromium/components/web_modal/web_contents_modal_dialog_manager.cc @@ -0,0 +1,149 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/web_modal/web_contents_modal_dialog_manager.h" + +#include "components/web_modal/web_contents_modal_dialog_manager_delegate.h" +#include "content/public/browser/navigation_details.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/browser/notification_details.h" +#include "content/public/browser/notification_source.h" +#include "content/public/browser/notification_types.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_view.h" +#include "net/base/registry_controlled_domains/registry_controlled_domain.h" + +using content::WebContents; + +DEFINE_WEB_CONTENTS_USER_DATA_KEY(web_modal::WebContentsModalDialogManager); + +namespace web_modal { + +WebContentsModalDialogManager::~WebContentsModalDialogManager() { + DCHECK(child_dialogs_.empty()); +} + +void WebContentsModalDialogManager::ShowDialog( + NativeWebContentsModalDialog dialog) { + child_dialogs_.push_back(dialog); + + native_manager_->ManageDialog(dialog); + + if (child_dialogs_.size() == 1) { + if (delegate_ && delegate_->IsWebContentsVisible(web_contents())) + native_manager_->ShowDialog(dialog); + BlockWebContentsInteraction(true); + } +} + +bool WebContentsModalDialogManager::IsShowingDialog() const { + return !child_dialogs_.empty(); +} + +void WebContentsModalDialogManager::FocusTopmostDialog() { + DCHECK(!child_dialogs_.empty()); + native_manager_->FocusDialog(child_dialogs_.front()); +} + +content::WebContents* WebContentsModalDialogManager::GetWebContents() const { + return web_contents(); +} + +void WebContentsModalDialogManager::WillClose( + NativeWebContentsModalDialog dialog) { + WebContentsModalDialogList::iterator i( + std::find(child_dialogs_.begin(), child_dialogs_.end(), dialog)); + + // The Views tab contents modal dialog calls WillClose twice. Ignore the + // second invocation. + if (i == child_dialogs_.end()) + return; + + bool removed_topmost_dialog = i == child_dialogs_.begin(); + child_dialogs_.erase(i); + if (!child_dialogs_.empty() && removed_topmost_dialog && + !closing_all_dialogs_) + native_manager_->ShowDialog(child_dialogs_.front()); + + BlockWebContentsInteraction(!child_dialogs_.empty()); +} + +void WebContentsModalDialogManager::Observe( + int type, + 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()); + else + native_manager_->HideDialog(child_dialogs_.front()); +} + +WebContentsModalDialogManager::WebContentsModalDialogManager( + content::WebContents* web_contents) + : content::WebContentsObserver(web_contents), + delegate_(NULL), + native_manager_(CreateNativeManager(this)), + closing_all_dialogs_(false) { + DCHECK(native_manager_); + registrar_.Add(this, + content::NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED, + content::Source<content::WebContents>(web_contents)); +} + +void WebContentsModalDialogManager::BlockWebContentsInteraction(bool blocked) { + WebContents* contents = web_contents(); + if (!contents) { + // The WebContents has already disconnected. + return; + } + + // RenderViewHost may be NULL during shutdown. + content::RenderViewHost* host = contents->GetRenderViewHost(); + if (host) + host->SetIgnoreInputEvents(blocked); + if (delegate_) + delegate_->SetWebContentsBlocked(contents, blocked); +} + +void WebContentsModalDialogManager::CloseAllDialogs() { + closing_all_dialogs_ = true; + + // Clear out any dialogs since we are leaving this page entirely. + while (!child_dialogs_.empty()) + native_manager_->CloseDialog(child_dialogs_.front()); + + closing_all_dialogs_ = false; +} + +void WebContentsModalDialogManager::DidNavigateMainFrame( + const content::LoadCommittedDetails& details, + const content::FrameNavigateParams& params) { + // Close constrained windows if necessary. + if (!net::registry_controlled_domains::SameDomainOrHost( + details.previous_url, details.entry->GetURL(), + net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES)) + CloseAllDialogs(); +} + +void WebContentsModalDialogManager::DidGetIgnoredUIEvent() { + if (!child_dialogs_.empty()) + native_manager_->FocusDialog(child_dialogs_.front()); +} + +void WebContentsModalDialogManager::WebContentsDestroyed(WebContents* tab) { + // First cleanly close all child dialogs. + // TODO(mpcomplete): handle case if MaybeCloseChildWindows() already asked + // some of these to close. CloseAllDialogs is async, so it might get called + // twice before it runs. + CloseAllDialogs(); +} + +} // 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 new file mode 100644 index 00000000000..e2548c04e5c --- /dev/null +++ b/chromium/components/web_modal/web_contents_modal_dialog_manager.h @@ -0,0 +1,116 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_WEB_MODAL_WEB_CONTENTS_MODAL_DIALOG_MANAGER_H_ +#define COMPONENTS_WEB_MODAL_WEB_CONTENTS_MODAL_DIALOG_MANAGER_H_ + +#include <deque> + +#include "base/memory/scoped_ptr.h" +#include "components/web_modal/native_web_contents_modal_dialog_manager.h" +#include "content/public/browser/notification_observer.h" +#include "content/public/browser/notification_registrar.h" +#include "content/public/browser/web_contents_observer.h" +#include "content/public/browser/web_contents_user_data.h" +#include "ui/gfx/native_widget_types.h" + +namespace web_modal { + +class WebContentsModalDialogManagerDelegate; + +// Per-WebContents class to manage WebContents-modal dialogs. +class WebContentsModalDialogManager + : public NativeWebContentsModalDialogManagerDelegate, + public content::WebContentsObserver, + public content::WebContentsUserData<WebContentsModalDialogManager>, + public content::NotificationObserver { + public: + virtual ~WebContentsModalDialogManager(); + + WebContentsModalDialogManagerDelegate* delegate() const { return delegate_; } + void set_delegate(WebContentsModalDialogManagerDelegate* d) { delegate_ = d; } + + static NativeWebContentsModalDialogManager* CreateNativeManager( + NativeWebContentsModalDialogManagerDelegate* native_delegate); + + // Shows the dialog as a web contents modal dialog. The dialog will notify via + // WillClose() when it is being destroyed. + void ShowDialog(NativeWebContentsModalDialog dialog); + + // Returns true if a dialog is currently being shown. + bool IsShowingDialog() const; + + // Focus the topmost modal dialog. IsShowingDialog() must be true when + // calling this function. + void FocusTopmostDialog(); + + // Overriden from NativeWebContentsModalDialogManagerDelegate: + virtual content::WebContents* GetWebContents() const OVERRIDE; + // Called when a WebContentsModalDialogs we own is about to be closed. + virtual void WillClose(NativeWebContentsModalDialog dialog) OVERRIDE; + + // content::NotificationObserver overrides + virtual void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) OVERRIDE; + + // For testing. + class TestApi { + public: + explicit TestApi(WebContentsModalDialogManager* manager) + : manager_(manager) {} + + void CloseAllDialogs() { manager_->CloseAllDialogs(); } + void ResetNativeManager(NativeWebContentsModalDialogManager* delegate) { + manager_->native_manager_.reset(delegate); + } + + private: + WebContentsModalDialogManager* manager_; + + DISALLOW_COPY_AND_ASSIGN(TestApi); + }; + + private: + explicit WebContentsModalDialogManager(content::WebContents* web_contents); + friend class content::WebContentsUserData<WebContentsModalDialogManager>; + + typedef std::deque<NativeWebContentsModalDialog> WebContentsModalDialogList; + + // Blocks/unblocks interaction with renderer process. + void BlockWebContentsInteraction(bool blocked); + + bool IsWebContentsVisible() const; + + // Closes all WebContentsModalDialogs. + void CloseAllDialogs(); + + // Overridden from content::WebContentsObserver: + virtual void DidNavigateMainFrame( + const content::LoadCommittedDetails& details, + const content::FrameNavigateParams& params) OVERRIDE; + virtual void DidGetIgnoredUIEvent() OVERRIDE; + virtual void WebContentsDestroyed(content::WebContents* tab) OVERRIDE; + + // Delegate for notifying our owner about stuff. Not owned by us. + WebContentsModalDialogManagerDelegate* delegate_; + + // Delegate for native UI-specific functions on the dialog. + scoped_ptr<NativeWebContentsModalDialogManager> native_manager_; + + // All active dialogs. + WebContentsModalDialogList child_dialogs_; + + // True while closing the dialogs on WebContents close. + bool closing_all_dialogs_; + + // A scoped container for notification registries. + content::NotificationRegistrar registrar_; + + DISALLOW_COPY_AND_ASSIGN(WebContentsModalDialogManager); +}; + +} // namespace web_modal + +#endif // COMPONENTS_WEB_MODAL_WEB_CONTENTS_MODAL_DIALOG_MANAGER_H_ diff --git a/chromium/components/web_modal/web_contents_modal_dialog_manager_delegate.cc b/chromium/components/web_modal/web_contents_modal_dialog_manager_delegate.cc new file mode 100644 index 00000000000..25a777cf4f5 --- /dev/null +++ b/chromium/components/web_modal/web_contents_modal_dialog_manager_delegate.cc @@ -0,0 +1,28 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/web_modal/web_contents_modal_dialog_manager_delegate.h" + +#include <string.h> + +namespace web_modal { + +void WebContentsModalDialogManagerDelegate::SetWebContentsBlocked( + content::WebContents* web_contents, bool blocked) { +} + +WebContentsModalDialogHost* + WebContentsModalDialogManagerDelegate::GetWebContentsModalDialogHost() { + return NULL; +} + +bool WebContentsModalDialogManagerDelegate::IsWebContentsVisible( + content::WebContents* web_contents) { + return true; +} + +WebContentsModalDialogManagerDelegate::~WebContentsModalDialogManagerDelegate( +) {} + +} // namespace web_modal diff --git a/chromium/components/web_modal/web_contents_modal_dialog_manager_delegate.h b/chromium/components/web_modal/web_contents_modal_dialog_manager_delegate.h new file mode 100644 index 00000000000..76f74354de5 --- /dev/null +++ b/chromium/components/web_modal/web_contents_modal_dialog_manager_delegate.h @@ -0,0 +1,42 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_WEB_MODAL_WEB_CONTENTS_MODAL_DIALOG_MANAGER_DELEGATE_H_ +#define COMPONENTS_WEB_MODAL_WEB_CONTENTS_MODAL_DIALOG_MANAGER_DELEGATE_H_ + +namespace content { +class WebContents; +} + +namespace gfx { +class Point; +} + +namespace web_modal { + +class WebContentsModalDialogHost; + +class WebContentsModalDialogManagerDelegate { + public: + // Changes the blocked state of |web_contents|. WebContentses are considered + // blocked while displaying a web contents modal dialog. During that time + // renderer host will ignore any UI interaction within WebContents outside of + // the currently displaying dialog. + virtual void SetWebContentsBlocked(content::WebContents* web_contents, + bool blocked); + + // Returns the WebContentsModalDialogHost for use in positioning web contents + // modal dialogs within the browser window. + virtual WebContentsModalDialogHost* GetWebContentsModalDialogHost(); + + // Returns whether the WebContents is currently visible or not. + virtual bool IsWebContentsVisible(content::WebContents* web_contents); + + protected: + virtual ~WebContentsModalDialogManagerDelegate(); +}; + +} // namespace web_modal + +#endif // COMPONENTS_WEB_MODAL_WEB_CONTENTS_MODAL_DIALOG_MANAGER_DELEGATE_H_ 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 new file mode 100644 index 00000000000..1268896d6af --- /dev/null +++ b/chromium/components/web_modal/web_contents_modal_dialog_manager_unittest.cc @@ -0,0 +1,81 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#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 "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 + : public NativeWebContentsModalDialogManager { + public: + NativeWebContentsModalDialogManagerCloseTest( + NativeWebContentsModalDialogManagerDelegate* delegate) + : delegate_(delegate) {} + virtual void ManageDialog(NativeWebContentsModalDialog dialog) OVERRIDE { + } + virtual void ShowDialog(NativeWebContentsModalDialog dialog) OVERRIDE { + } + virtual void HideDialog(NativeWebContentsModalDialog dialog) OVERRIDE { + } + virtual void CloseDialog(NativeWebContentsModalDialog dialog) OVERRIDE { + delegate_->WillClose(dialog); + close_count++; + } + virtual void FocusDialog(NativeWebContentsModalDialog dialog) OVERRIDE { + } + virtual void PulseDialog(NativeWebContentsModalDialog dialog) OVERRIDE { + } + + int close_count; + NativeWebContentsModalDialogManagerDelegate* delegate_; +}; + +NativeWebContentsModalDialogManager* WebContentsModalDialogManager:: +CreateNativeManager( + NativeWebContentsModalDialogManagerDelegate* native_delegate) { + return new NativeWebContentsModalDialogManagerCloseTest(native_delegate); +} + +TEST_F(WebContentsModalDialogManagerTest, WebContentsModalDialogs) { + WebContentsModalDialogManager* web_contents_modal_dialog_manager = + WebContentsModalDialogManager::FromWebContents(web_contents()); + WebContentsModalDialogManager::TestApi test_api( + web_contents_modal_dialog_manager); + + NativeWebContentsModalDialogManagerCloseTest* native_manager = + new NativeWebContentsModalDialogManagerCloseTest( + web_contents_modal_dialog_manager); + native_manager->close_count = 0; + + test_api.ResetNativeManager(native_manager); + + 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); + + test_api.CloseAllDialogs(); + EXPECT_EQ(native_manager->close_count, kWindowCount); +} + +} // namespace web_modal |