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

Side by Side Diff: chrome/browser/app_modal_dialog.cc

Issue 435014: Merge 32889 - Fix crash when an extension popup shows a JS alert. Showing the... (Closed) Base URL: svn://svn.chromium.org/chrome/branches/249/src/
Patch Set: Created 11 years 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
« no previous file with comments | « chrome/browser/app_modal_dialog.h ('k') | chrome/browser/extensions/extension_host.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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/app_modal_dialog.h" 5 #include "chrome/browser/app_modal_dialog.h"
6 6
7 #include "chrome/browser/app_modal_dialog_queue.h" 7 #include "chrome/browser/app_modal_dialog_queue.h"
8 #include "chrome/browser/extensions/extension_host.h"
8 #include "chrome/browser/tab_contents/tab_contents.h" 9 #include "chrome/browser/tab_contents/tab_contents.h"
9 #include "chrome/common/notification_service.h" 10 #include "chrome/common/notification_service.h"
10 #include "chrome/common/notification_type.h" 11 #include "chrome/common/notification_type.h"
11 #include "ipc/ipc_message.h" 12 #include "ipc/ipc_message.h"
12 13
13 AppModalDialog::AppModalDialog(JavaScriptMessageBoxClient* client, 14 AppModalDialog::AppModalDialog(JavaScriptMessageBoxClient* client,
14 const std::wstring& title, 15 const std::wstring& title,
15 int dialog_flags, 16 int dialog_flags,
16 const std::wstring& message_text, 17 const std::wstring& message_text,
17 const std::wstring& default_prompt_text, 18 const std::wstring& default_prompt_text,
18 bool display_suppress_checkbox, 19 bool display_suppress_checkbox,
19 bool is_before_unload_dialog, 20 bool is_before_unload_dialog,
20 IPC::Message* reply_msg) 21 IPC::Message* reply_msg)
21 : dialog_(NULL), 22 : dialog_(NULL),
22 client_(client), 23 client_(client),
24 tab_contents_(client_->AsTabContents()),
25 extension_host_(client_->AsExtensionHost()),
23 skip_this_dialog_(false), 26 skip_this_dialog_(false),
24 title_(title), 27 title_(title),
25 dialog_flags_(dialog_flags), 28 dialog_flags_(dialog_flags),
26 message_text_(message_text), 29 message_text_(message_text),
27 default_prompt_text_(default_prompt_text), 30 default_prompt_text_(default_prompt_text),
28 display_suppress_checkbox_(display_suppress_checkbox), 31 display_suppress_checkbox_(display_suppress_checkbox),
29 is_before_unload_dialog_(is_before_unload_dialog), 32 is_before_unload_dialog_(is_before_unload_dialog),
30 reply_msg_(reply_msg) { 33 reply_msg_(reply_msg) {
31 InitNotifications(); 34 InitNotifications();
35 DCHECK((tab_contents_ != NULL) != (extension_host_ != NULL));
32 } 36 }
33 37
34 void AppModalDialog::Observe(NotificationType type, 38 void AppModalDialog::Observe(NotificationType type,
35 const NotificationSource& source, 39 const NotificationSource& source,
36 const NotificationDetails& details) { 40 const NotificationDetails& details) {
37 if (skip_this_dialog_) 41 if (skip_this_dialog_)
38 return; 42 return;
39 43
40 // We only observe our NavigationController for NAV_ENTRY_COMMITTED and our 44 if (NotificationType::EXTENSION_HOST_DESTROYED == type &&
41 // TabContents for TAB_CONTENTS_DESTROYED, both of which indicate that we 45 Details<ExtensionHost>(extension_host_) != details)
42 // should ignore this dialog. Also clear the client for good measure, since 46 return;
43 // it's now invalid. 47
48 // If we reach here, we know the notification is relevant to us, either
49 // because we're only observing applicable sources or because we passed the
50 // check above. Both of those indicate that we should ignore this dialog.
51 // Also clear the client, since it's now invalid.
44 skip_this_dialog_ = true; 52 skip_this_dialog_ = true;
45 client_ = NULL; 53 client_ = NULL;
46 CloseModalDialog(); 54 CloseModalDialog();
47 } 55 }
48 56
49 void AppModalDialog::SendCloseNotification() {
50 NotificationService::current()->Notify(
51 NotificationType::APP_MODAL_DIALOG_CLOSED,
52 Source<AppModalDialog>(this),
53 NotificationService::NoDetails());
54 }
55
56 void AppModalDialog::InitNotifications() { 57 void AppModalDialog::InitNotifications() {
57 // Make sure we get relevant navigation notifications so we know when our 58 // Make sure we get relevant navigation notifications so we know when our
58 // parent contents will disappear or navigate to a different page. 59 // parent contents will disappear or navigate to a different page.
59 TabContents* tab_contents = client_->AsTabContents(); 60 if (tab_contents_) {
60 if (tab_contents) {
61 registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED, 61 registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED,
62 Source<NavigationController>(&tab_contents->controller())); 62 Source<NavigationController>(&tab_contents_->controller()));
63 registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED, 63 registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED,
64 Source<TabContents>(tab_contents)); 64 Source<TabContents>(tab_contents_));
65 } else if (extension_host_) {
66 // EXTENSION_HOST_DESTROYED uses the Profile as its source, but we care
67 // about the ExtensionHost (which is passed in the details).
68 registrar_.Add(this, NotificationType::EXTENSION_HOST_DESTROYED,
69 NotificationService::AllSources());
70 } else {
71 NOTREACHED();
65 } 72 }
66 } 73 }
67 74
68 void AppModalDialog::ShowModalDialog() { 75 void AppModalDialog::ShowModalDialog() {
69 // If the TabContents that created this dialog navigated away before this 76 // If the TabContents or ExtensionHost that created this dialog navigated
70 // dialog became visible, simply show the next dialog if any. 77 // away or was destroyed before this dialog became visible, simply show the
78 // next dialog if any.
71 if (skip_this_dialog_) { 79 if (skip_this_dialog_) {
72 Singleton<AppModalDialogQueue>()->ShowNextDialog(); 80 Singleton<AppModalDialogQueue>()->ShowNextDialog();
73 delete this; 81 delete this;
74 return; 82 return;
75 } 83 }
76 TabContents* tab_contents = client_->AsTabContents(); 84 if (tab_contents_)
77 if (tab_contents) 85 tab_contents_->Activate();
78 tab_contents->Activate();
79 86
80 CreateAndShowDialog(); 87 CreateAndShowDialog();
81 88
82 NotificationService::current()->Notify( 89 NotificationService::current()->Notify(
83 NotificationType::APP_MODAL_DIALOG_SHOWN, 90 NotificationType::APP_MODAL_DIALOG_SHOWN,
84 Source<AppModalDialog>(this), 91 Source<AppModalDialog>(this),
85 NotificationService::NoDetails()); 92 NotificationService::NoDetails());
86 } 93 }
87 94
88 void AppModalDialog::OnCancel() { 95 void AppModalDialog::OnCancel() {
89 // We need to do this before WM_DESTROY (WindowClosing()) as any parent frame 96 // We need to do this before WM_DESTROY (WindowClosing()) as any parent frame
90 // will receive its activation messages before this dialog receives 97 // will receive its activation messages before this dialog receives
91 // WM_DESTROY. The parent frame would then try to activate any modal dialogs 98 // WM_DESTROY. The parent frame would then try to activate any modal dialogs
92 // that were still open in the ModalDialogQueue, which would send activation 99 // that were still open in the ModalDialogQueue, which would send activation
93 // back to this one. The framework should be improved to handle this, so this 100 // back to this one. The framework should be improved to handle this, so this
94 // is a temporary workaround. 101 // is a temporary workaround.
95 Singleton<AppModalDialogQueue>()->ShowNextDialog(); 102 Singleton<AppModalDialogQueue>()->ShowNextDialog();
96 103
97 if (!skip_this_dialog_) { 104 if (!skip_this_dialog_) {
98 client_->OnMessageBoxClosed(reply_msg_, false, std::wstring()); 105 client_->OnMessageBoxClosed(reply_msg_, false, std::wstring());
99 } 106 }
100 107
101 SendCloseNotification(); 108 Cleanup();
102 } 109 }
103 110
104 void AppModalDialog::OnAccept(const std::wstring& prompt_text, 111 void AppModalDialog::OnAccept(const std::wstring& prompt_text,
105 bool suppress_js_messages) { 112 bool suppress_js_messages) {
106 Singleton<AppModalDialogQueue>()->ShowNextDialog(); 113 Singleton<AppModalDialogQueue>()->ShowNextDialog();
107 114
108 if (!skip_this_dialog_) { 115 if (!skip_this_dialog_) {
109 client_->OnMessageBoxClosed(reply_msg_, true, prompt_text); 116 client_->OnMessageBoxClosed(reply_msg_, true, prompt_text);
110 if (suppress_js_messages) 117 if (suppress_js_messages)
111 client_->SetSuppressMessageBoxes(true); 118 client_->SetSuppressMessageBoxes(true);
112 } 119 }
113 120
114 SendCloseNotification(); 121 Cleanup();
115 } 122 }
116 123
117 void AppModalDialog::OnClose() { 124 void AppModalDialog::OnClose() {
118 SendCloseNotification(); 125 Cleanup();
119 } 126 }
127
128 void AppModalDialog::Cleanup() {
129 if (skip_this_dialog_) {
130 // We can't use the client_, because we might be in the process of
131 // destroying it.
132 if (tab_contents_)
133 tab_contents_->OnMessageBoxClosed(reply_msg_, false, L"");
134 else if (extension_host_)
135 extension_host_->OnMessageBoxClosed(reply_msg_, false, L"");
136 else
137 NOTREACHED();
138 }
139 NotificationService::current()->Notify(
140 NotificationType::APP_MODAL_DIALOG_CLOSED,
141 Source<AppModalDialog>(this),
142 NotificationService::NoDetails());
143 }
OLDNEW
« no previous file with comments | « chrome/browser/app_modal_dialog.h ('k') | chrome/browser/extensions/extension_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698