summaryrefslogtreecommitdiff
path: root/chromium/components/web_modal
diff options
context:
space:
mode:
authorZeno Albisser <zeno.albisser@digia.com>2013-08-15 21:46:11 +0200
committerZeno Albisser <zeno.albisser@digia.com>2013-08-15 21:46:11 +0200
commit679147eead574d186ebf3069647b4c23e8ccace6 (patch)
treefc247a0ac8ff119f7c8550879ebb6d3dd8d1ff69 /chromium/components/web_modal
downloadqtwebengine-chromium-679147eead574d186ebf3069647b4c23e8ccace6.tar.gz
Initial import.
Diffstat (limited to 'chromium/components/web_modal')
-rw-r--r--chromium/components/web_modal/DEPS6
-rw-r--r--chromium/components/web_modal/native_web_contents_modal_dialog.h22
-rw-r--r--chromium/components/web_modal/native_web_contents_modal_dialog_manager.h66
-rw-r--r--chromium/components/web_modal/web_contents_modal_dialog_host.cc21
-rw-r--r--chromium/components/web_modal/web_contents_modal_dialog_host.h54
-rw-r--r--chromium/components/web_modal/web_contents_modal_dialog_manager.cc149
-rw-r--r--chromium/components/web_modal/web_contents_modal_dialog_manager.h116
-rw-r--r--chromium/components/web_modal/web_contents_modal_dialog_manager_delegate.cc28
-rw-r--r--chromium/components/web_modal/web_contents_modal_dialog_manager_delegate.h42
-rw-r--r--chromium/components/web_modal/web_contents_modal_dialog_manager_unittest.cc81
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