OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "chrome/browser/ui/javascript_dialogs/javascript_dialog_tab_helper.h" | 5 #include "chrome/browser/ui/javascript_dialogs/javascript_dialog_tab_helper.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
9 #include "base/feature_list.h" | 9 #include "base/feature_list.h" |
10 #include "base/metrics/histogram_macros.h" | 10 #include "base/metrics/histogram_macros.h" |
(...skipping 20 matching lines...) Expand all Loading... |
31 } | 31 } |
32 | 32 |
33 bool IsWebContentsForemost(content::WebContents* web_contents) { | 33 bool IsWebContentsForemost(content::WebContents* web_contents) { |
34 Browser* browser = BrowserList::GetInstance()->GetLastActive(); | 34 Browser* browser = BrowserList::GetInstance()->GetLastActive(); |
35 DCHECK(browser); | 35 DCHECK(browser); |
36 return browser->tab_strip_model()->GetActiveWebContents() == web_contents; | 36 return browser->tab_strip_model()->GetActiveWebContents() == web_contents; |
37 } | 37 } |
38 | 38 |
39 } // namespace | 39 } // namespace |
40 | 40 |
| 41 // A note on the interaction between the JavaScriptDialogTabHelper and the |
| 42 // JavaScriptDialog classes. |
| 43 // |
| 44 // Either side can start the process of closing a dialog, and we need to ensure |
| 45 // that everything is properly torn down no matter which side initiates. |
| 46 // |
| 47 // If closing is initiated by the JavaScriptDialogTabHelper, then it will call |
| 48 // CloseDialog(), which calls JavaScriptDialog::CloseDialogWithoutCallback(). |
| 49 // That will clear the callback inside of JavaScriptDialog, and start the |
| 50 // JavaScriptDialog on its own path of destruction. CloseDialog() then calls |
| 51 // ClearDialogInfo() which removes observers. |
| 52 // |
| 53 // If closing is initiated by the JavaScriptDialog, which is a self-deleting |
| 54 // object, then it will make its callback. The callback will have been wrapped |
| 55 // within JavaScriptDialogTabHelper::RunJavaScriptDialog() to be a call to |
| 56 // JavaScriptDialogTabHelper::OnDialogClosed(), which, after doing the callback, |
| 57 // again calls ClearDialogInfo() to remove observers. |
| 58 |
41 JavaScriptDialogTabHelper::JavaScriptDialogTabHelper( | 59 JavaScriptDialogTabHelper::JavaScriptDialogTabHelper( |
42 content::WebContents* web_contents) | 60 content::WebContents* web_contents) |
43 : content::WebContentsObserver(web_contents) { | 61 : content::WebContentsObserver(web_contents) { |
44 } | 62 } |
45 | 63 |
46 JavaScriptDialogTabHelper::~JavaScriptDialogTabHelper() { | 64 JavaScriptDialogTabHelper::~JavaScriptDialogTabHelper() { |
| 65 if (dialog_) |
| 66 CloseDialog(true /*suppress_callback*/, false, base::string16()); |
47 } | 67 } |
48 | 68 |
49 void JavaScriptDialogTabHelper::SetDialogShownCallbackForTesting( | 69 void JavaScriptDialogTabHelper::SetDialogShownCallbackForTesting( |
50 base::Closure callback) { | 70 base::Closure callback) { |
51 dialog_shown_ = callback; | 71 dialog_shown_ = callback; |
52 } | 72 } |
53 | 73 |
54 void JavaScriptDialogTabHelper::RunJavaScriptDialog( | 74 void JavaScriptDialogTabHelper::RunJavaScriptDialog( |
55 content::WebContents* alerting_web_contents, | 75 content::WebContents* alerting_web_contents, |
56 const GURL& origin_url, | 76 const GURL& origin_url, |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 if (dialog_) { | 132 if (dialog_) { |
113 // There's already a dialog up; clear it out. | 133 // There's already a dialog up; clear it out. |
114 CloseDialog(false, false, base::string16()); | 134 CloseDialog(false, false, base::string16()); |
115 } | 135 } |
116 | 136 |
117 base::string16 title = | 137 base::string16 title = |
118 AppModalDialogManager()->GetTitle(alerting_web_contents, origin_url); | 138 AppModalDialogManager()->GetTitle(alerting_web_contents, origin_url); |
119 dialog_callback_ = callback; | 139 dialog_callback_ = callback; |
120 dialog_ = JavaScriptDialog::Create( | 140 dialog_ = JavaScriptDialog::Create( |
121 parent_web_contents, alerting_web_contents, title, message_type, | 141 parent_web_contents, alerting_web_contents, title, message_type, |
122 message_text, default_prompt_text, callback); | 142 message_text, default_prompt_text, |
| 143 base::Bind(&JavaScriptDialogTabHelper::OnDialogClosed, |
| 144 base::Unretained(this), callback)); |
123 | 145 |
124 BrowserList::AddObserver(this); | 146 BrowserList::AddObserver(this); |
125 | 147 |
126 // Message suppression is something that we don't give the user a checkbox | 148 // Message suppression is something that we don't give the user a checkbox |
127 // for any more. It was useful back in the day when dialogs were app-modal | 149 // for any more. It was useful back in the day when dialogs were app-modal |
128 // and clicking the checkbox was the only way to escape a loop that the page | 150 // and clicking the checkbox was the only way to escape a loop that the page |
129 // was doing, but now the user can just close the page. | 151 // was doing, but now the user can just close the page. |
130 *did_suppress_message = false; | 152 *did_suppress_message = false; |
131 | 153 |
132 if (!dialog_shown_.is_null()) { | 154 if (!dialog_shown_.is_null()) { |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 void JavaScriptDialogTabHelper::WasHidden() { | 237 void JavaScriptDialogTabHelper::WasHidden() { |
216 if (dialog_) | 238 if (dialog_) |
217 CloseDialog(false, false, base::string16()); | 239 CloseDialog(false, false, base::string16()); |
218 } | 240 } |
219 | 241 |
220 void JavaScriptDialogTabHelper::OnBrowserSetLastActive(Browser* browser) { | 242 void JavaScriptDialogTabHelper::OnBrowserSetLastActive(Browser* browser) { |
221 if (dialog_ && !IsWebContentsForemost(web_contents())) | 243 if (dialog_ && !IsWebContentsForemost(web_contents())) |
222 CloseDialog(false, false, base::string16()); | 244 CloseDialog(false, false, base::string16()); |
223 } | 245 } |
224 | 246 |
| 247 void JavaScriptDialogTabHelper::OnDialogClosed( |
| 248 DialogClosedCallback callback, |
| 249 bool success, |
| 250 const base::string16& user_input) { |
| 251 callback.Run(success, user_input); |
| 252 |
| 253 ClearDialogInfo(); |
| 254 } |
| 255 |
225 void JavaScriptDialogTabHelper::CloseDialog(bool suppress_callback, | 256 void JavaScriptDialogTabHelper::CloseDialog(bool suppress_callback, |
226 bool success, | 257 bool success, |
227 const base::string16& user_input) { | 258 const base::string16& user_input) { |
228 DCHECK(dialog_); | 259 DCHECK(dialog_); |
229 | 260 |
230 dialog_->CloseDialogWithoutCallback(); | 261 dialog_->CloseDialogWithoutCallback(); |
231 if (!suppress_callback) | 262 if (!suppress_callback) |
232 dialog_callback_.Run(success, user_input); | 263 dialog_callback_.Run(success, user_input); |
233 | 264 |
| 265 ClearDialogInfo(); |
| 266 } |
| 267 |
| 268 void JavaScriptDialogTabHelper::ClearDialogInfo() { |
234 dialog_.reset(); | 269 dialog_.reset(); |
235 dialog_callback_.Reset(); | 270 dialog_callback_.Reset(); |
236 BrowserList::RemoveObserver(this); | 271 BrowserList::RemoveObserver(this); |
237 } | 272 } |
OLD | NEW |