Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "components/web_modal/popup_manager.h" | |
| 6 | |
| 7 #include "content/public/browser/navigation_details.h" | |
| 8 #include "content/public/browser/navigation_entry.h" | |
| 9 #include "content/public/browser/render_view_host.h" | |
| 10 #include "content/public/browser/web_contents.h" | |
| 11 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | |
| 12 | |
| 13 using content::WebContents; | |
| 14 | |
| 15 namespace web_modal { | |
| 16 | |
| 17 PopupManager::PopupManager() | |
| 18 : closing_all_popups_(false) { | |
| 19 } | |
| 20 | |
| 21 PopupManager::~PopupManager() { | |
| 22 DCHECK(child_popups_.empty()); | |
| 23 } | |
| 24 | |
| 25 void PopupManager::ShowPopup(scoped_ptr<SinglePopupManager> manager) { | |
| 26 child_popups_.push_back(manager.Pass())); | |
| 27 | |
| 28 if (child_popups_.size() == 1) | |
| 29 child_popups_.back()->Show(); | |
| 30 } | |
| 31 | |
| 32 | |
| 33 bool PopupManager::IsPopupActive( | |
| 34 const content::WebContents* web_contents) const { | |
| 35 // TODO(gbillock): needs help to figure out what's going on for the given | |
| 36 // web contents. | |
| 37 return !child_popups_.empty(); | |
| 38 } | |
| 39 | |
| 40 void PopupManager::FocusTopmostPopupForWebContentsIfActive( | |
| 41 const content::WebContents* web_contents) { | |
| 42 // TODO(gbillock): check if the top popups are already being shown, | |
| 43 // or need to be re-activated, or what. We may want to close some, too, | |
| 44 // 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
| |
| 45 DCHECK(!child_popups_.empty()); | |
| 46 child_popups_.front()->Focus(); | |
| 47 } | |
| 48 | |
| 49 void PopupManager::WillClose(NativePopup popup) { | |
| 50 PopupList::iterator dlg = FindPopupState(popup); | |
| 51 | |
| 52 // The Views tab contents modal dialog calls WillClose twice. Ignore the | |
| 53 // second invocation. | |
| 54 if (dlg == child_popups_.end()) | |
| 55 return; | |
| 56 | |
| 57 bool removed_topmost_dialog = dlg == child_popups_.begin(); | |
| 58 scoped_ptr<SinglePopupManager> deleter(*dlg); | |
| 59 child_popups_.erase(dlg); | |
| 60 if (!child_popups_.empty() && removed_topmost_dialog && | |
| 61 !closing_all_popups_) { | |
| 62 child_popups_.front()->Show(); | |
| 63 } | |
| 64 } | |
| 65 | |
| 66 PopupManager::PopupList::iterator PopupManager::FindPopupState( | |
| 67 NativePopup popup) { | |
| 68 PopupList::iterator i; | |
| 69 for (i = child_popups_.begin(); i != child_popups_.end(); ++i) { | |
| 70 if ((*i)->popup() == popup) | |
| 71 break; | |
| 72 } | |
| 73 | |
| 74 return i; | |
| 75 } | |
| 76 | |
| 77 void PopupManager::CloseAllPopups() { | |
| 78 closing_all_popups_ = true; | |
| 79 | |
| 80 // Clear out any dialogs since we are leaving this page entirely. | |
| 81 while (!child_popups_.empty()) { | |
| 82 child_popups_.front()->Close(); | |
| 83 } | |
| 84 | |
| 85 closing_all_popups_ = false; | |
| 86 } | |
| 87 | |
| 88 void PopupManager::DidNavigateMainFrame( | |
| 89 content::WebContents* web_contents, | |
| 90 const content::LoadCommittedDetails& details, | |
| 91 const content::FrameNavigateParams& params) { | |
| 92 // Close constrained windows if necessary. | |
| 93 if (!net::registry_controlled_domains::SameDomainOrHost( | |
| 94 details.previous_url, details.entry->GetURL(), | |
| 95 net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES)) | |
| 96 CloseAllPopups(); | |
| 97 } | |
| 98 | |
| 99 void PopupManager::DidGetIgnoredUIEvent(content::WebContents* web_contents) { | |
| 100 if (!child_popups_.empty()) { | |
| 101 child_popups_.front()->Focus(); | |
| 102 } | |
| 103 } | |
| 104 | |
| 105 void PopupManager::WasShown(content::WebContents* web_contents) { | |
| 106 if (!child_popups_.empty()) | |
| 107 child_popups_.front()->Show(); | |
| 108 } | |
| 109 | |
| 110 void PopupManager::WasHidden(content::WebContents* web_contents) { | |
| 111 if (!child_popups_.empty()) | |
| 112 child_popups_.front()->Hide(); | |
| 113 } | |
| 114 | |
| 115 void PopupManager::WebContentsDestroyed(content::WebContents* web_contents) { | |
| 116 // First cleanly close all child dialogs. | |
| 117 // TODO(mpcomplete): handle case if MaybeCloseChildWindows() already asked | |
| 118 // some of these to close. CloseAllDialogs is async, so it might get called | |
| 119 // twice before it runs. | |
| 120 CloseAllPopups(); | |
| 121 } | |
| 122 | |
| 123 void PopupManager::DidAttachInterstitialPage( | |
| 124 content::WebContents* web_contents) { | |
| 125 // Copy the dialogs so we can close and remove them while iterating over the | |
| 126 // list. | |
| 127 PopupList popups(child_popups_); | |
| 128 for (PopupList::iterator it = popups.begin(); it != popups.end(); ++it) { | |
| 129 if ((*it)->ShouldCloseOnNavigation()) | |
| 130 (*it)->Close(); | |
| 131 } | |
| 132 } | |
| 133 | |
| 134 // TODO(gbillock): Need other navigation hooks to close? | |
| 135 | |
| 136 } // namespace web_modal | |
| OLD | NEW |