OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/web_modal/web_contents_modal_dialog_manager.h" | 5 #include "components/web_modal/web_contents_modal_dialog_manager.h" |
6 | 6 |
7 #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h" | 7 #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h" |
8 #include "content/public/browser/navigation_details.h" | 8 #include "content/public/browser/navigation_details.h" |
9 #include "content/public/browser/navigation_entry.h" | 9 #include "content/public/browser/navigation_entry.h" |
10 #include "content/public/browser/notification_details.h" | 10 #include "content/public/browser/notification_details.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 | 27 |
28 void WebContentsModalDialogManager::SetDelegate( | 28 void WebContentsModalDialogManager::SetDelegate( |
29 WebContentsModalDialogManagerDelegate* d) { | 29 WebContentsModalDialogManagerDelegate* d) { |
30 delegate_ = d; | 30 delegate_ = d; |
31 // Delegate can be NULL on Views/Win32 during tab drag. | 31 // Delegate can be NULL on Views/Win32 during tab drag. |
32 native_manager_->HostChanged(d ? d->GetWebContentsModalDialogHost() : NULL); | 32 native_manager_->HostChanged(d ? d->GetWebContentsModalDialogHost() : NULL); |
33 } | 33 } |
34 | 34 |
35 void WebContentsModalDialogManager::ShowDialog( | 35 void WebContentsModalDialogManager::ShowDialog( |
36 NativeWebContentsModalDialog dialog) { | 36 NativeWebContentsModalDialog dialog) { |
37 child_dialogs_.push_back(dialog); | 37 child_dialogs_.push_back(DialogState(dialog)); |
38 | 38 |
39 native_manager_->ManageDialog(dialog); | 39 native_manager_->ManageDialog(dialog); |
40 | 40 |
41 if (child_dialogs_.size() == 1) { | 41 if (child_dialogs_.size() == 1) { |
42 if (delegate_ && delegate_->IsWebContentsVisible(web_contents())) | 42 if (delegate_ && delegate_->IsWebContentsVisible(web_contents())) |
43 native_manager_->ShowDialog(dialog); | 43 native_manager_->ShowDialog(dialog); |
44 BlockWebContentsInteraction(true); | 44 BlockWebContentsInteraction(true); |
45 } | 45 } |
46 } | 46 } |
47 | 47 |
48 bool WebContentsModalDialogManager::IsShowingDialog() const { | 48 bool WebContentsModalDialogManager::IsShowingDialog() const { |
49 return !child_dialogs_.empty(); | 49 return !child_dialogs_.empty(); |
50 } | 50 } |
51 | 51 |
52 void WebContentsModalDialogManager::FocusTopmostDialog() { | 52 void WebContentsModalDialogManager::FocusTopmostDialog() { |
53 DCHECK(!child_dialogs_.empty()); | 53 DCHECK(!child_dialogs_.empty()); |
54 native_manager_->FocusDialog(child_dialogs_.front()); | 54 native_manager_->FocusDialog(child_dialogs_.front().dialog); |
| 55 } |
| 56 |
| 57 void WebContentsModalDialogManager::SetCloseOnInterstitialWebUI( |
| 58 NativeWebContentsModalDialog dialog, |
| 59 bool close) { |
| 60 WebContentsModalDialogList::iterator loc = FindDialogState(dialog); |
| 61 DCHECK(loc != child_dialogs_.end()); |
| 62 loc->close_on_interstitial_webui = close; |
55 } | 63 } |
56 | 64 |
57 content::WebContents* WebContentsModalDialogManager::GetWebContents() const { | 65 content::WebContents* WebContentsModalDialogManager::GetWebContents() const { |
58 return web_contents(); | 66 return web_contents(); |
59 } | 67 } |
60 | 68 |
61 void WebContentsModalDialogManager::WillClose( | 69 void WebContentsModalDialogManager::WillClose( |
62 NativeWebContentsModalDialog dialog) { | 70 NativeWebContentsModalDialog dialog) { |
63 WebContentsModalDialogList::iterator i( | 71 WebContentsModalDialogList::iterator i = FindDialogState(dialog); |
64 std::find(child_dialogs_.begin(), child_dialogs_.end(), dialog)); | |
65 | 72 |
66 // The Views tab contents modal dialog calls WillClose twice. Ignore the | 73 // The Views tab contents modal dialog calls WillClose twice. Ignore the |
67 // second invocation. | 74 // second invocation. |
68 if (i == child_dialogs_.end()) | 75 if (i == child_dialogs_.end()) |
69 return; | 76 return; |
70 | 77 |
71 bool removed_topmost_dialog = i == child_dialogs_.begin(); | 78 bool removed_topmost_dialog = i == child_dialogs_.begin(); |
72 child_dialogs_.erase(i); | 79 child_dialogs_.erase(i); |
73 if (!child_dialogs_.empty() && removed_topmost_dialog && | 80 if (!child_dialogs_.empty() && removed_topmost_dialog && |
74 !closing_all_dialogs_) | 81 !closing_all_dialogs_) |
75 native_manager_->ShowDialog(child_dialogs_.front()); | 82 native_manager_->ShowDialog(child_dialogs_.front().dialog); |
76 | 83 |
77 BlockWebContentsInteraction(!child_dialogs_.empty()); | 84 BlockWebContentsInteraction(!child_dialogs_.empty()); |
78 } | 85 } |
79 | 86 |
80 void WebContentsModalDialogManager::Observe( | 87 void WebContentsModalDialogManager::Observe( |
81 int type, | 88 int type, |
82 const content::NotificationSource& source, | 89 const content::NotificationSource& source, |
83 const content::NotificationDetails& details) { | 90 const content::NotificationDetails& details) { |
84 DCHECK(type == content::NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED); | 91 DCHECK(type == content::NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED); |
85 | |
86 if (child_dialogs_.empty()) | 92 if (child_dialogs_.empty()) |
87 return; | 93 return; |
88 | 94 |
89 bool visible = *content::Details<bool>(details).ptr(); | 95 bool visible = *content::Details<bool>(details).ptr(); |
90 if (visible) | 96 if (visible) |
91 native_manager_->ShowDialog(child_dialogs_.front()); | 97 native_manager_->ShowDialog(child_dialogs_.front().dialog); |
92 else | 98 else |
93 native_manager_->HideDialog(child_dialogs_.front()); | 99 native_manager_->HideDialog(child_dialogs_.front().dialog); |
94 } | 100 } |
95 | 101 |
96 WebContentsModalDialogManager::WebContentsModalDialogManager( | 102 WebContentsModalDialogManager::WebContentsModalDialogManager( |
97 content::WebContents* web_contents) | 103 content::WebContents* web_contents) |
98 : content::WebContentsObserver(web_contents), | 104 : content::WebContentsObserver(web_contents), |
99 delegate_(NULL), | 105 delegate_(NULL), |
100 native_manager_(CreateNativeManager(this)), | 106 native_manager_(CreateNativeManager(this)), |
101 closing_all_dialogs_(false) { | 107 closing_all_dialogs_(false) { |
102 DCHECK(native_manager_); | 108 DCHECK(native_manager_); |
103 registrar_.Add(this, | 109 registrar_.Add(this, |
104 content::NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED, | 110 content::NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED, |
105 content::Source<content::WebContents>(web_contents)); | 111 content::Source<content::WebContents>(web_contents)); |
106 } | 112 } |
107 | 113 |
| 114 WebContentsModalDialogManager::DialogState::DialogState( |
| 115 NativeWebContentsModalDialog dialog) |
| 116 : dialog(dialog), |
| 117 close_on_interstitial_webui(false) { |
| 118 } |
| 119 |
| 120 WebContentsModalDialogManager::WebContentsModalDialogList::iterator |
| 121 WebContentsModalDialogManager::FindDialogState( |
| 122 NativeWebContentsModalDialog dialog) { |
| 123 WebContentsModalDialogList::iterator i; |
| 124 for (i = child_dialogs_.begin(); i != child_dialogs_.end(); ++i) { |
| 125 if (i->dialog == dialog) |
| 126 break; |
| 127 } |
| 128 |
| 129 return i; |
| 130 } |
| 131 |
108 void WebContentsModalDialogManager::BlockWebContentsInteraction(bool blocked) { | 132 void WebContentsModalDialogManager::BlockWebContentsInteraction(bool blocked) { |
109 WebContents* contents = web_contents(); | 133 WebContents* contents = web_contents(); |
110 if (!contents) { | 134 if (!contents) { |
111 // The WebContents has already disconnected. | 135 // The WebContents has already disconnected. |
112 return; | 136 return; |
113 } | 137 } |
114 | 138 |
115 // RenderViewHost may be NULL during shutdown. | 139 // RenderViewHost may be NULL during shutdown. |
116 content::RenderViewHost* host = contents->GetRenderViewHost(); | 140 content::RenderViewHost* host = contents->GetRenderViewHost(); |
117 if (host) | 141 if (host) |
118 host->SetIgnoreInputEvents(blocked); | 142 host->SetIgnoreInputEvents(blocked); |
119 if (delegate_) | 143 if (delegate_) |
120 delegate_->SetWebContentsBlocked(contents, blocked); | 144 delegate_->SetWebContentsBlocked(contents, blocked); |
121 } | 145 } |
122 | 146 |
123 void WebContentsModalDialogManager::CloseAllDialogs() { | 147 void WebContentsModalDialogManager::CloseAllDialogs() { |
124 closing_all_dialogs_ = true; | 148 closing_all_dialogs_ = true; |
125 | 149 |
126 // Clear out any dialogs since we are leaving this page entirely. | 150 // Clear out any dialogs since we are leaving this page entirely. |
127 while (!child_dialogs_.empty()) | 151 while (!child_dialogs_.empty()) |
128 native_manager_->CloseDialog(child_dialogs_.front()); | 152 native_manager_->CloseDialog(child_dialogs_.front().dialog); |
129 | 153 |
130 closing_all_dialogs_ = false; | 154 closing_all_dialogs_ = false; |
131 } | 155 } |
132 | 156 |
133 void WebContentsModalDialogManager::DidNavigateMainFrame( | 157 void WebContentsModalDialogManager::DidNavigateMainFrame( |
134 const content::LoadCommittedDetails& details, | 158 const content::LoadCommittedDetails& details, |
135 const content::FrameNavigateParams& params) { | 159 const content::FrameNavigateParams& params) { |
136 // Close constrained windows if necessary. | 160 // Close constrained windows if necessary. |
137 if (!net::registry_controlled_domains::SameDomainOrHost( | 161 if (!net::registry_controlled_domains::SameDomainOrHost( |
138 details.previous_url, details.entry->GetURL(), | 162 details.previous_url, details.entry->GetURL(), |
139 net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES)) | 163 net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES)) |
140 CloseAllDialogs(); | 164 CloseAllDialogs(); |
141 } | 165 } |
142 | 166 |
143 void WebContentsModalDialogManager::DidGetIgnoredUIEvent() { | 167 void WebContentsModalDialogManager::DidGetIgnoredUIEvent() { |
144 if (!child_dialogs_.empty()) | 168 if (!child_dialogs_.empty()) |
145 native_manager_->FocusDialog(child_dialogs_.front()); | 169 native_manager_->FocusDialog(child_dialogs_.front().dialog); |
146 } | 170 } |
147 | 171 |
148 void WebContentsModalDialogManager::WebContentsDestroyed(WebContents* tab) { | 172 void WebContentsModalDialogManager::WebContentsDestroyed(WebContents* tab) { |
149 // First cleanly close all child dialogs. | 173 // First cleanly close all child dialogs. |
150 // TODO(mpcomplete): handle case if MaybeCloseChildWindows() already asked | 174 // TODO(mpcomplete): handle case if MaybeCloseChildWindows() already asked |
151 // some of these to close. CloseAllDialogs is async, so it might get called | 175 // some of these to close. CloseAllDialogs is async, so it might get called |
152 // twice before it runs. | 176 // twice before it runs. |
153 CloseAllDialogs(); | 177 CloseAllDialogs(); |
154 } | 178 } |
155 | 179 |
| 180 void WebContentsModalDialogManager::DidAttachInterstitialPage() { |
| 181 // Copy the dialogs so we can close and remove them while iterating over the |
| 182 // list. |
| 183 WebContentsModalDialogList dialogs(child_dialogs_); |
| 184 for (WebContentsModalDialogList::iterator it = dialogs.begin(); |
| 185 it != dialogs.end(); ++it) { |
| 186 if (it->close_on_interstitial_webui) |
| 187 native_manager_->CloseDialog(it->dialog); |
| 188 } |
| 189 } |
| 190 |
156 } // namespace web_modal | 191 } // namespace web_modal |
OLD | NEW |