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

Side by Side Diff: components/web_modal/web_contents_modal_dialog_manager.cc

Issue 23981002: Provide configurable closing of web contents modal dialogs on interstitial webui (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase + add test comment Created 7 years, 3 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698