Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1527)

Unified Diff: components/web_modal/popup_manager.cc

Issue 287123002: [WebModals] New API for browser-scoped popup management. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/web_modal/popup_manager.cc
diff --git a/components/web_modal/popup_manager.cc b/components/web_modal/popup_manager.cc
new file mode 100644
index 0000000000000000000000000000000000000000..5440aff372b01259e0c6f87cc5c60a1b08c49f38
--- /dev/null
+++ b/components/web_modal/popup_manager.cc
@@ -0,0 +1,136 @@
+// 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/popup_manager.h"
+
+#include "content/public/browser/navigation_details.h"
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/web_contents.h"
+#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
+
+using content::WebContents;
+
+namespace web_modal {
+
+PopupManager::PopupManager()
+ : closing_all_popups_(false) {
+}
+
+PopupManager::~PopupManager() {
+ DCHECK(child_popups_.empty());
+}
+
+void PopupManager::ShowPopup(scoped_ptr<SinglePopupManager> manager) {
+ child_popups_.push_back(manager.Pass()));
+
+ if (child_popups_.size() == 1)
+ child_popups_.back()->Show();
+}
+
+
+bool PopupManager::IsPopupActive(
+ const content::WebContents* web_contents) const {
+ // TODO(gbillock): needs help to figure out what's going on for the given
+ // web contents.
+ return !child_popups_.empty();
+}
+
+void PopupManager::FocusTopmostPopupForWebContentsIfActive(
+ const content::WebContents* web_contents) {
+ // TODO(gbillock): check if the top popups are already being shown,
+ // or need to be re-activated, or what. We may want to close some, too,
+ // depending on the policy.
Mike Wittman 2014/05/23 19:02:35 I think we should be making decisions about showin
Greg Billock 2014/05/27 22:42:03 I'm thinking the same thing. I added a note to tha
Mike Wittman 2014/05/28 21:47:09 On the focus issue, it's also entirely possible th
+ DCHECK(!child_popups_.empty());
+ child_popups_.front()->Focus();
+}
+
+void PopupManager::WillClose(NativePopup popup) {
+ PopupList::iterator dlg = FindPopupState(popup);
+
+ // The Views tab contents modal dialog calls WillClose twice. Ignore the
+ // second invocation.
+ if (dlg == child_popups_.end())
+ return;
+
+ bool removed_topmost_dialog = dlg == child_popups_.begin();
+ scoped_ptr<SinglePopupManager> deleter(*dlg);
+ child_popups_.erase(dlg);
+ if (!child_popups_.empty() && removed_topmost_dialog &&
+ !closing_all_popups_) {
+ child_popups_.front()->Show();
+ }
+}
+
+PopupManager::PopupList::iterator PopupManager::FindPopupState(
+ NativePopup popup) {
+ PopupList::iterator i;
+ for (i = child_popups_.begin(); i != child_popups_.end(); ++i) {
+ if ((*i)->popup() == popup)
+ break;
+ }
+
+ return i;
+}
+
+void PopupManager::CloseAllPopups() {
+ closing_all_popups_ = true;
+
+ // Clear out any dialogs since we are leaving this page entirely.
+ while (!child_popups_.empty()) {
+ child_popups_.front()->Close();
+ }
+
+ closing_all_popups_ = false;
+}
+
+void PopupManager::DidNavigateMainFrame(
+ content::WebContents* web_contents,
+ 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::INCLUDE_PRIVATE_REGISTRIES))
+ CloseAllPopups();
+}
+
+void PopupManager::DidGetIgnoredUIEvent(content::WebContents* web_contents) {
+ if (!child_popups_.empty()) {
+ child_popups_.front()->Focus();
+ }
+}
+
+void PopupManager::WasShown(content::WebContents* web_contents) {
+ if (!child_popups_.empty())
+ child_popups_.front()->Show();
+}
+
+void PopupManager::WasHidden(content::WebContents* web_contents) {
+ if (!child_popups_.empty())
+ child_popups_.front()->Hide();
+}
+
+void PopupManager::WebContentsDestroyed(content::WebContents* web_contents) {
+ // 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.
+ CloseAllPopups();
+}
+
+void PopupManager::DidAttachInterstitialPage(
+ content::WebContents* web_contents) {
+ // Copy the dialogs so we can close and remove them while iterating over the
+ // list.
+ PopupList popups(child_popups_);
+ for (PopupList::iterator it = popups.begin(); it != popups.end(); ++it) {
+ if ((*it)->ShouldCloseOnNavigation())
+ (*it)->Close();
+ }
+}
+
+// TODO(gbillock): Need other navigation hooks to close?
+
+} // namespace web_modal

Powered by Google App Engine
This is Rietveld 408576698