| 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..9930ab793e7d2988d4c39cc49a81a83122b0b9ba
|
| --- /dev/null
|
| +++ b/components/web_modal/popup_manager.cc
|
| @@ -0,0 +1,144 @@
|
| +// 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(new PopupState(manager->popup(), manager.Pass()));
|
| +
|
| + if (child_popups_.size() == 1)
|
| + child_popups_.back()->manager->Show();
|
| +}
|
| +
|
| +bool PopupManager::IsPopupActiveInCurrentWebContents() const {
|
| + return !child_popups_.empty();
|
| +}
|
| +
|
| +void PopupManager::FocusTopmostPopup() {
|
| + DCHECK(!child_popups_.empty());
|
| + child_popups_.front()->manager->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<PopupState> deleter(*dlg);
|
| + child_popups_.erase(dlg);
|
| + if (!child_popups_.empty() && removed_topmost_dialog &&
|
| + !closing_all_popups_) {
|
| + child_popups_.front()->manager->Show();
|
| + }
|
| +}
|
| +
|
| +PopupManager::PopupState::PopupState(
|
| + NativePopup popup,
|
| + scoped_ptr<SinglePopupManager> mgr)
|
| + : popup(popup),
|
| + manager(mgr.release()),
|
| +#if defined(USE_AURA)
|
| + close_on_interstitial_webui(true)
|
| +#else
|
| + // TODO(wittman): Test that closing on interstitial webui works properly
|
| + // on Mac and use the true default for all platforms.
|
| + close_on_interstitial_webui(false)
|
| +#endif
|
| + {
|
| +}
|
| +
|
| +PopupManager::PopupState::~PopupState() {}
|
| +
|
| +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()->manager->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()->manager->Focus();
|
| + }
|
| +}
|
| +
|
| +void PopupManager::WasShown(content::WebContents* web_contents) {
|
| + if (!child_popups_.empty())
|
| + child_popups_.front()->manager->Show();
|
| +}
|
| +
|
| +void PopupManager::WasHidden(content::WebContents* web_contents) {
|
| + if (!child_popups_.empty())
|
| + child_popups_.front()->manager->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 dialogs(child_popups_);
|
| + for (PopupList::iterator it = dialogs.begin();
|
| + it != dialogs.end(); ++it) {
|
| + if ((*it)->close_on_interstitial_webui)
|
| + (*it)->manager->Close();
|
| + }
|
| +}
|
| +
|
| +} // namespace web_modal
|
|
|