| Index: chrome/browser/ui/javascript_dialogs/javascript_dialog_tab_helper.cc
|
| diff --git a/chrome/browser/ui/javascript_dialogs/javascript_dialog_tab_helper.cc b/chrome/browser/ui/javascript_dialogs/javascript_dialog_tab_helper.cc
|
| index 66c838bae1974c657d427b25ff52ac01b2d19394..6f2c3cdc7320017ebd353ca973b3f0ba1c11ff87 100644
|
| --- a/chrome/browser/ui/javascript_dialogs/javascript_dialog_tab_helper.cc
|
| +++ b/chrome/browser/ui/javascript_dialogs/javascript_dialog_tab_helper.cc
|
| @@ -38,12 +38,32 @@ bool IsWebContentsForemost(content::WebContents* web_contents) {
|
|
|
| } // namespace
|
|
|
| +// A note on the interaction between the JavaScriptDialogTabHelper and the
|
| +// JavaScriptDialog classes.
|
| +//
|
| +// Either side can start the process of closing a dialog, and we need to ensure
|
| +// that everything is properly torn down no matter which side initiates.
|
| +//
|
| +// If closing is initiated by the JavaScriptDialogTabHelper, then it will call
|
| +// CloseDialog(), which calls JavaScriptDialog::CloseDialogWithoutCallback().
|
| +// That will clear the callback inside of JavaScriptDialog, and start the
|
| +// JavaScriptDialog on its own path of destruction. CloseDialog() then calls
|
| +// ClearDialogInfo() which removes observers.
|
| +//
|
| +// If closing is initiated by the JavaScriptDialog, which is a self-deleting
|
| +// object, then it will make its callback. The callback will have been wrapped
|
| +// within JavaScriptDialogTabHelper::RunJavaScriptDialog() to be a call to
|
| +// JavaScriptDialogTabHelper::OnDialogClosed(), which, after doing the callback,
|
| +// again calls ClearDialogInfo() to remove observers.
|
| +
|
| JavaScriptDialogTabHelper::JavaScriptDialogTabHelper(
|
| content::WebContents* web_contents)
|
| : content::WebContentsObserver(web_contents) {
|
| }
|
|
|
| JavaScriptDialogTabHelper::~JavaScriptDialogTabHelper() {
|
| + if (dialog_)
|
| + CloseDialog(true /*suppress_callback*/, false, base::string16());
|
| }
|
|
|
| void JavaScriptDialogTabHelper::SetDialogShownCallbackForTesting(
|
| @@ -119,7 +139,9 @@ void JavaScriptDialogTabHelper::RunJavaScriptDialog(
|
| dialog_callback_ = callback;
|
| dialog_ = JavaScriptDialog::Create(
|
| parent_web_contents, alerting_web_contents, title, message_type,
|
| - message_text, default_prompt_text, callback);
|
| + message_text, default_prompt_text,
|
| + base::Bind(&JavaScriptDialogTabHelper::OnDialogClosed,
|
| + base::Unretained(this), callback));
|
|
|
| BrowserList::AddObserver(this);
|
|
|
| @@ -222,6 +244,15 @@ void JavaScriptDialogTabHelper::OnBrowserSetLastActive(Browser* browser) {
|
| CloseDialog(false, false, base::string16());
|
| }
|
|
|
| +void JavaScriptDialogTabHelper::OnDialogClosed(
|
| + DialogClosedCallback callback,
|
| + bool success,
|
| + const base::string16& user_input) {
|
| + callback.Run(success, user_input);
|
| +
|
| + ClearDialogInfo();
|
| +}
|
| +
|
| void JavaScriptDialogTabHelper::CloseDialog(bool suppress_callback,
|
| bool success,
|
| const base::string16& user_input) {
|
| @@ -231,6 +262,10 @@ void JavaScriptDialogTabHelper::CloseDialog(bool suppress_callback,
|
| if (!suppress_callback)
|
| dialog_callback_.Run(success, user_input);
|
|
|
| + ClearDialogInfo();
|
| +}
|
| +
|
| +void JavaScriptDialogTabHelper::ClearDialogInfo() {
|
| dialog_.reset();
|
| dialog_callback_.Reset();
|
| BrowserList::RemoveObserver(this);
|
|
|