diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-28 15:40:20 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-28 15:40:20 +0000 |
commit | 160ad3d101988b9d842fef8b18cc49c54c9a1de5 (patch) | |
tree | 567875d2f363d0b110ad25da9a9aa07cffcaa201 | |
parent | 341078d4b72bd3de280b960be6cd4ac5e5ab0265 (diff) | |
download | chromium_src-160ad3d101988b9d842fef8b18cc49c54c9a1de5.zip chromium_src-160ad3d101988b9d842fef8b18cc49c54c9a1de5.tar.gz chromium_src-160ad3d101988b9d842fef8b18cc49c54c9a1de5.tar.bz2 |
Refactor AppModalDialog to more clearly isolate platform specific UI pieces and eliminate the dependency on individual frontends from cross platform code.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/3398015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@60785 0039d316-1c4b-4281-b951-d872f2087c98
22 files changed, 521 insertions, 470 deletions
diff --git a/chrome/browser/app_modal_dialog.cc b/chrome/browser/app_modal_dialog.cc index 09d1f33..506d76f 100644 --- a/chrome/browser/app_modal_dialog.cc +++ b/chrome/browser/app_modal_dialog.cc @@ -5,20 +5,20 @@ #include "chrome/browser/app_modal_dialog.h" #include "chrome/browser/app_modal_dialog_queue.h" +#include "chrome/browser/native_app_modal_dialog.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/notification_service.h" #include "chrome/common/notification_type.h" AppModalDialog::AppModalDialog(TabContents* tab_contents, const std::wstring& title) -#if defined(OS_WIN) || defined(OS_LINUX) - : dialog_(NULL), -#elif defined(OS_MACOSX) - : -#endif + : skip_this_dialog_(false), tab_contents_(tab_contents), - title_(title), - skip_this_dialog_(false) { + native_dialog_(NULL), + title_(title) { +} + +AppModalDialog::~AppModalDialog() { } void AppModalDialog::ShowModalDialog() { @@ -33,11 +33,19 @@ void AppModalDialog::ShowModalDialog() { NotificationService::NoDetails()); } -void AppModalDialog::Cleanup() { - NotificationService::current()->Notify( - NotificationType::APP_MODAL_DIALOG_CLOSED, - Source<AppModalDialog>(this), - NotificationService::NoDetails()); +void AppModalDialog::CreateAndShowDialog() { + native_dialog_ = CreateNativeDialog(); + native_dialog_->ShowAppModalDialog(); +} + +void AppModalDialog::ActivateModalDialog() { + DCHECK(native_dialog_); + native_dialog_->ActivateAppModalDialog(); +} + +void AppModalDialog::CloseModalDialog() { + DCHECK(native_dialog_); + native_dialog_->CloseAppModalDialog(); } void AppModalDialog::CompleteDialog() { diff --git a/chrome/browser/app_modal_dialog.h b/chrome/browser/app_modal_dialog.h index a3bf31a..708e86e 100644 --- a/chrome/browser/app_modal_dialog.h +++ b/chrome/browser/app_modal_dialog.h @@ -13,19 +13,7 @@ #include "chrome/common/notification_observer.h" #include "chrome/common/notification_registrar.h" -// Define NativeDialog type as platform specific dialog view. -#if defined(OS_WIN) -class ModalDialogDelegate; -typedef ModalDialogDelegate* NativeDialog; -#elif defined(OS_MACOSX) -typedef void* NativeDialog; -#elif defined(TOOLKIT_USES_GTK) -typedef struct _GtkDialog GtkDialog; -typedef struct _GtkWidget GtkWidget; -typedef int gint; -typedef GtkWidget* NativeDialog; -#endif - +class NativeAppModalDialog; class TabContents; // A controller+model base class for modal dialogs. @@ -37,74 +25,57 @@ class AppModalDialog { AppModalDialog(TabContents* tab_contents, const std::wstring& title); virtual ~AppModalDialog(); - // Called by the app modal window queue when it is time to show this window. + // Called by the AppModalDialogQueue to show this dialog. void ShowModalDialog(); - // Returns true if the dialog is still valid. As dialogs are created they are - // added to the AppModalDialogQueue. When the current modal dialog finishes - // and it's time to show the next dialog in the queue IsValid is invoked. - // If IsValid returns false the dialog is deleted and not shown. - virtual bool IsValid() { return !skip_this_dialog_; } - - ///////////////////////////////////////////////////////////////////////////// - // The following methods are platform specific and should be implemented in - // the platform specific .cc files. - // Create the platform specific NativeDialog and display it. When the - // NativeDialog is closed, it should call OnAccept or OnCancel to notify the - // renderer of the user's action. The NativeDialog is also expected to - // delete the AppModalDialog associated with it. - virtual void CreateAndShowDialog(); - -#if defined(TOOLKIT_USES_GTK) - virtual void HandleDialogResponse(GtkDialog* dialog, gint response_id) = 0; - // Callback for dialog response calls, passes results to specialized - // HandleDialogResponse() implementation. - static void OnDialogResponse(GtkDialog* dialog, gint response_id, - AppModalDialog* app_modal_dialog); -#endif - - // Close the dialog if it is showing. - virtual void CloseModalDialog(); - - // Called by the app modal window queue to activate the window. + // Called by the AppModalDialogQueue to activate the dialog. void ActivateModalDialog(); + // Closes the dialog if it is showing. + void CloseModalDialog(); + // Completes dialog handling, shows next modal dialog from the queue. + // TODO(beng): Get rid of this method. void CompleteDialog(); // Dialog window title. - std::wstring title() { - return title_; - } + std::wstring title() const { return title_; } - // Helper methods used to query or control the dialog. This is used by - // automation. - virtual int GetDialogButtons() = 0; - virtual void AcceptWindow() = 0; - virtual void CancelWindow() = 0; + NativeAppModalDialog* native_dialog() const { return native_dialog_; } - protected: - // Cleans up the dialog class. - virtual void Cleanup(); - // Creates the actual platform specific dialog view class. - virtual NativeDialog CreateNativeDialog() = 0; + // Methods overridable by AppModalDialog subclasses: - // A reference to the platform native dialog box. -#if defined(OS_LINUX) || defined(OS_WIN) - NativeDialog dialog_; -#endif + // Creates an implementation of NativeAppModalDialog and shows it. + // When the native dialog is closed, the implementation of + // NativeAppModalDialog should call OnAccept or OnCancel to notify the + // renderer of the user's action. The NativeAppModalDialog is also + // expected to delete the AppModalDialog associated with it. + virtual void CreateAndShowDialog(); - // Parent tab contents. - TabContents* tab_contents_; + // Returns true if the dialog is still valid. As dialogs are created they are + // added to the AppModalDialogQueue. When the current modal dialog finishes + // and it's time to show the next dialog in the queue IsValid is invoked. + // If IsValid returns false the dialog is deleted and not shown. + virtual bool IsValid() { return !skip_this_dialog_; } - // Information about the message box is held in the following variables. - std::wstring title_; + protected: + // Overridden by subclasses to create the feature-specific native dialog box. + virtual NativeAppModalDialog* CreateNativeDialog() = 0; // True if the dialog should no longer be shown, e.g. because the underlying // tab navigated away while the dialog was queued. bool skip_this_dialog_; + // Parent tab contents. + TabContents* tab_contents_; + private: + // The toolkit-specific implementation of the app modal dialog box. + NativeAppModalDialog* native_dialog_; + + // Information about the message box is held in the following variables. + std::wstring title_; + DISALLOW_COPY_AND_ASSIGN(AppModalDialog); }; diff --git a/chrome/browser/app_modal_dialog_gtk.cc b/chrome/browser/app_modal_dialog_gtk.cc deleted file mode 100644 index 63bcc87..0000000 --- a/chrome/browser/app_modal_dialog_gtk.cc +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/app_modal_dialog.h" - -#include <gtk/gtk.h> - -#include "base/logging.h" -#include "base/string_util.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/browser_window.h" -#include "chrome/browser/gtk/gtk_util.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/tab_contents/tab_contents_view.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" - -AppModalDialog::~AppModalDialog() { -} - -void AppModalDialog::CreateAndShowDialog() { -} - -// static -void AppModalDialog::OnDialogResponse(GtkDialog* dialog, gint response_id, - AppModalDialog* app_modal_dialog) { - app_modal_dialog->HandleDialogResponse(dialog, response_id); -} - -void AppModalDialog::ActivateModalDialog() { - DCHECK(dialog_); - gtk_window_present(GTK_WINDOW(dialog_)); -} - -void AppModalDialog::CloseModalDialog() { - DCHECK(dialog_); - HandleDialogResponse(GTK_DIALOG(dialog_), GTK_RESPONSE_DELETE_EVENT); -} - -void AppModalDialog::AcceptWindow() { - DCHECK(dialog_); - HandleDialogResponse(GTK_DIALOG(dialog_), GTK_RESPONSE_OK); -} - -void AppModalDialog::CancelWindow() { - DCHECK(dialog_); - HandleDialogResponse(GTK_DIALOG(dialog_), GTK_RESPONSE_CANCEL); -} diff --git a/chrome/browser/app_modal_dialog_mac.mm b/chrome/browser/app_modal_dialog_mac.mm deleted file mode 100644 index 8d23387..0000000 --- a/chrome/browser/app_modal_dialog_mac.mm +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/app_modal_dialog.h" - -#import <Cocoa/Cocoa.h> - -#include "base/logging.h" - -AppModalDialog::~AppModalDialog() { -} - -void AppModalDialog::CreateAndShowDialog() { - NOTIMPLEMENTED(); -} - -void AppModalDialog::ActivateModalDialog() { - NOTIMPLEMENTED(); -} - -void AppModalDialog::CloseModalDialog() { - NOTIMPLEMENTED(); -} diff --git a/chrome/browser/app_modal_dialog_win.cc b/chrome/browser/app_modal_dialog_win.cc deleted file mode 100644 index e48d986..0000000 --- a/chrome/browser/app_modal_dialog_win.cc +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/app_modal_dialog.h" - -#include "base/logging.h" -#include "chrome/browser/views/jsmessage_box_dialog.h" -#include "views/window/dialog_delegate.h" -#include "views/window/window.h" - -AppModalDialog::~AppModalDialog() { -} - -void AppModalDialog::CreateAndShowDialog() { - dialog_ = CreateNativeDialog(); - DCHECK(dialog_->IsModal()); - dialog_->ShowModalDialog(); -} - -void AppModalDialog::ActivateModalDialog() { - DCHECK(dialog_); - dialog_->ActivateModalDialog(); -} - -void AppModalDialog::CloseModalDialog() { - DCHECK(dialog_); - dialog_->CloseModalDialog(); -} diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc index 07865e6..29146ec 100644 --- a/chrome/browser/automation/testing_automation_provider.cc +++ b/chrome/browser/automation/testing_automation_provider.cc @@ -39,6 +39,7 @@ #include "chrome/browser/find_bar.h" #include "chrome/browser/location_bar.h" #include "chrome/browser/login_prompt.h" +#include "chrome/browser/native_app_modal_dialog.h" #include "chrome/browser/profile.h" #include "chrome/browser/platform_util.h" #include "chrome/browser/prefs/pref_service.h" @@ -1865,11 +1866,11 @@ void TestingAutomationProvider::SetBooleanPreference(int handle, void TestingAutomationProvider::GetShowingAppModalDialog(bool* showing_dialog, int* dialog_button) { - AppModalDialog* dialog_delegate = - Singleton<AppModalDialogQueue>()->active_dialog(); - *showing_dialog = (dialog_delegate != NULL); + NativeAppModalDialog* native_dialog = + Singleton<AppModalDialogQueue>()->active_dialog()->native_dialog(); + *showing_dialog = (native_dialog != NULL); if (*showing_dialog) - *dialog_button = dialog_delegate->GetDialogButtons(); + *dialog_button = native_dialog->GetAppModalDialogButtons(); else *dialog_button = MessageBoxFlags::DIALOGBUTTON_NONE; } @@ -1878,19 +1879,19 @@ void TestingAutomationProvider::ClickAppModalDialogButton(int button, bool* success) { *success = false; - AppModalDialog* dialog_delegate = - Singleton<AppModalDialogQueue>()->active_dialog(); - if (dialog_delegate && - (dialog_delegate->GetDialogButtons() & button) == button) { + NativeAppModalDialog* native_dialog = + Singleton<AppModalDialogQueue>()->active_dialog()->native_dialog(); + if (native_dialog && + (native_dialog->GetAppModalDialogButtons() & button) == button) { if ((button & MessageBoxFlags::DIALOGBUTTON_OK) == MessageBoxFlags::DIALOGBUTTON_OK) { - dialog_delegate->AcceptWindow(); + native_dialog->AcceptAppModalDialog(); *success = true; } if ((button & MessageBoxFlags::DIALOGBUTTON_CANCEL) == MessageBoxFlags::DIALOGBUTTON_CANCEL) { DCHECK(!*success) << "invalid param, OK and CANCEL specified"; - dialog_delegate->CancelWindow(); + native_dialog->CancelAppModalDialog(); *success = true; } } diff --git a/chrome/browser/browser_browsertest.cc b/chrome/browser/browser_browsertest.cc index fa60fef..1bd9a14 100644 --- a/chrome/browser/browser_browsertest.cc +++ b/chrome/browser/browser_browsertest.cc @@ -20,6 +20,7 @@ #include "chrome/browser/extensions/extension_browsertest.h" #include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/js_modal_dialog.h" +#include "chrome/browser/native_app_modal_dialog.h" #include "chrome/browser/profile.h" #include "chrome/browser/renderer_host/render_process_host.h" #include "chrome/browser/renderer_host/render_view_host.h" @@ -290,12 +291,12 @@ IN_PROC_BROWSER_TEST_F(BrowserTest, MAYBE_SingleBeforeUnloadAfterWindowClose) { browser()->GetTabContentsAt(0)->render_view_host()-> ExecuteJavascriptInWebFrame(L"", L"w.close(); alert('bar');"); AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); - alert->AcceptWindow(); + alert->native_dialog()->AcceptAppModalDialog(); alert = ui_test_utils::WaitForAppModalDialog(); EXPECT_FALSE(static_cast<JavaScriptAppModalDialog*>(alert)-> is_before_unload_dialog()); - alert->AcceptWindow(); + alert->native_dialog()->AcceptAppModalDialog(); } // Test that get_process_idle_time() returns reasonable values when compared diff --git a/chrome/browser/chromeos/tab_closeable_state_watcher_browsertest.cc b/chrome/browser/chromeos/tab_closeable_state_watcher_browsertest.cc index 9b0f997..ea49119 100644 --- a/chrome/browser/chromeos/tab_closeable_state_watcher_browsertest.cc +++ b/chrome/browser/chromeos/tab_closeable_state_watcher_browsertest.cc @@ -9,6 +9,7 @@ #include "chrome/browser/browser.h" #include "chrome/browser/browser_list.h" #include "chrome/browser/browser_window.h" +#include "chrome/browser/native_app_modal_dialog.h" #include "chrome/browser/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tabs/tab_strip_model.h" @@ -282,7 +283,7 @@ IN_PROC_BROWSER_TEST_F(TabCloseableStateWatcherTest, TabContents* tab_contents = browser()->GetSelectedTabContents(); browser()->CloseWindow(); AppModalDialog* confirm = ui_test_utils::WaitForAppModalDialog(); - confirm->CancelWindow(); + confirm->native_dialog()->CancelAppModalDialog(); ui_test_utils::RunAllPendingInMessageLoop(); EXPECT_EQ(1u, BrowserList::size()); EXPECT_EQ(browser(), *(BrowserList::begin())); @@ -292,7 +293,7 @@ IN_PROC_BROWSER_TEST_F(TabCloseableStateWatcherTest, // Close the browser. browser()->CloseWindow(); confirm = ui_test_utils::WaitForAppModalDialog(); - confirm->AcceptWindow(); + confirm->native_dialog()->AcceptAppModalDialog(); ui_test_utils::RunAllPendingInMessageLoop(); } @@ -308,7 +309,7 @@ IN_PROC_BROWSER_TEST_F(TabCloseableStateWatcherTest, // Close browser, click OK in BeforeUnload confirm dialog. browser()->CloseWindow(); AppModalDialog* confirm = ui_test_utils::WaitForAppModalDialog(); - confirm->AcceptWindow(); + confirm->native_dialog()->AcceptAppModalDialog(); NewTabObserver new_tab_observer(browser()); EXPECT_EQ(1u, BrowserList::size()); EXPECT_EQ(browser(), *(BrowserList::begin())); diff --git a/chrome/browser/cocoa/js_modal_dialog_cocoa.h b/chrome/browser/cocoa/js_modal_dialog_cocoa.h new file mode 100644 index 0000000..b31b1c2 --- /dev/null +++ b/chrome/browser/cocoa/js_modal_dialog_cocoa.h @@ -0,0 +1,48 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_COCOA_JS_MODAL_DIALOG_COCOA_H_ +#define CHROME_BROWSER_COCOA_JS_MODAL_DIALOG_COCOA_H_ +#pragma once + +#include "chrome/browser/native_app_modal_dialog.h" + +#include "base/logging.h" +#include "base/scoped_nsobject.h" +#include "base/scoped_ptr.h" + +#if __OBJC__ +@class NSAlert; +@class JavaScriptAppModalDialogHelper; +#else +class NSAlert; +class JavaScriptAppModalDialogHelper; +#endif + +class JSModalDialogCocoa : public NativeAppModalDialog { + public: + explicit JSModalDialogCocoa(JavaScriptAppModalDialog* dialog); + virtual ~JSModalDialogCocoa(); + + // Overridden from NativeAppModalDialog: + virtual int GetAppModalDialogButtons() const; + virtual void ShowAppModalDialog(); + virtual void ActivateAppModalDialog(); + virtual void CloseAppModalDialog(); + virtual void AcceptAppModalDialog(); + virtual void CancelAppModalDialog(); + + JavaScriptAppModalDialog* dialog() const { return dialog_.get(); } + + private: + scoped_ptr<JavaScriptAppModalDialog> dialog_; + + scoped_nsobject<JavaScriptAppModalDialogHelper> helper_; + NSAlert* alert_; // weak, owned by |helper_|. + + DISALLOW_COPY_AND_ASSIGN(JSModalDialogCocoa); +}; + +#endif // CHROME_BROWSER_COCOA_JS_MODAL_DIALOG_COCOA_H_ + diff --git a/chrome/browser/js_modal_dialog_mac.mm b/chrome/browser/cocoa/js_modal_dialog_cocoa.mm index ca21e55..ced3af1 100644 --- a/chrome/browser/js_modal_dialog_mac.mm +++ b/chrome/browser/cocoa/js_modal_dialog_cocoa.mm @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/js_modal_dialog.h" +#include "chrome/browser/cocoa/js_modal_dialog_cocoa.h" #import <Cocoa/Cocoa.h> @@ -12,6 +12,7 @@ #include "base/logging.h" #include "base/sys_string_conversions.h" #import "chrome/browser/chrome_browser_application_mac.h" +#include "chrome/browser/js_modal_dialog.h" #include "grit/app_strings.h" #include "grit/generated_resources.h" @@ -51,13 +52,12 @@ [super dealloc]; } -// |contextInfo| is the bridge back to the C++ JavaScriptAppModalDialog. When -// complete, autorelease to clean ourselves up. +// |contextInfo| is the JSModalDialogCocoa that owns us. - (void)alertDidEnd:(NSAlert*)alert returnCode:(int)returnCode contextInfo:(void*)contextInfo { - JavaScriptAppModalDialog* bridge = - reinterpret_cast<JavaScriptAppModalDialog*>(contextInfo); + scoped_ptr<JSModalDialogCocoa> native_dialog( + reinterpret_cast<JSModalDialogCocoa*>(contextInfo)); std::wstring input; if (textField_) input = base::SysNSStringToWide([textField_ stringValue]); @@ -66,35 +66,38 @@ bool shouldSuppress = false; if ([alert showsSuppressionButton]) shouldSuppress = [[alert suppressionButton] state] == NSOnState; - bridge->OnAccept(input, shouldSuppress); + native_dialog->dialog()->OnAccept(input, shouldSuppress); break; } case NSAlertSecondButtonReturn: { // Cancel // If the user wants to stay on this page, stop quitting (if a quit is in // progress). - if (bridge->is_before_unload_dialog()) + if (native_dialog->dialog()->is_before_unload_dialog()) chrome_browser_application_mac::CancelTerminate(); - bridge->OnCancel(); + native_dialog->dialog()->OnCancel(); break; } case NSRunStoppedResponse: { // Window was closed underneath us // Need to call OnCancel() because there is some cleanup that needs // to be done. It won't call back to the javascript since the // JavaScriptAppModalDialog knows that the TabContents was destroyed. - bridge->OnCancel(); + native_dialog->dialog()->OnCancel(); break; } default: { NOTREACHED(); } } - [self autorelease]; - delete bridge; // Done with the dialog, it needs be destroyed. } @end -void JavaScriptAppModalDialog::CreateAndShowDialog() { +//////////////////////////////////////////////////////////////////////////////// +// JSModalDialogCocoa, public: + +JSModalDialogCocoa::JSModalDialogCocoa(JavaScriptAppModalDialog* dialog) + : dialog_(dialog), + helper_(NULL) { // Determine the names of the dialog buttons based on the flags. "Default" // is the OK button. "Other" is the cancel button. We don't use the // "Alternate" button in NSRunAlertPanel. @@ -102,12 +105,12 @@ void JavaScriptAppModalDialog::CreateAndShowDialog() { NSString* other_button = l10n_util::GetNSStringWithFixup(IDS_APP_CANCEL); bool text_field = false; bool one_button = false; - switch (dialog_flags_) { + switch (dialog_->dialog_flags()) { case MessageBoxFlags::kIsJavascriptAlert: one_button = true; break; case MessageBoxFlags::kIsJavascriptConfirm: - if (is_before_unload_dialog_) { + if (dialog_->is_before_unload_dialog()) { default_button = l10n_util::GetNSStringWithFixup( IDS_BEFOREUNLOAD_MESSAGEBOX_OK_BUTTON_LABEL); other_button = l10n_util::GetNSStringWithFixup( @@ -125,46 +128,42 @@ void JavaScriptAppModalDialog::CreateAndShowDialog() { // Create a helper which will receive the sheet ended selector. It will // delete itself when done. It doesn't need anything passed to its init // as it will get a contextInfo parameter. - JavaScriptAppModalDialogHelper* helper = - [[JavaScriptAppModalDialogHelper alloc] init]; + helper_.reset([[JavaScriptAppModalDialogHelper alloc] init]); // Show the modal dialog. - NSAlert* alert = [helper alert]; - dialog_ = alert; + alert_ = [helper_ alert]; NSTextField* field = nil; if (text_field) { - field = [helper textField]; - [field setStringValue:base::SysWideToNSString(default_prompt_text_)]; + field = [helper_ textField]; + [field setStringValue:base::SysWideToNSString( + dialog_->default_prompt_text())]; } - [alert setDelegate:helper]; - [alert setInformativeText:base::SysWideToNSString(message_text_)]; - [alert setMessageText:base::SysWideToNSString(title_)]; - [alert addButtonWithTitle:default_button]; + [alert_ setDelegate:helper_]; + [alert_ setInformativeText:base::SysWideToNSString(dialog_->message_text())]; + [alert_ setMessageText:base::SysWideToNSString(dialog_->title())]; + [alert_ addButtonWithTitle:default_button]; if (!one_button) { - NSButton* other = [alert addButtonWithTitle:other_button]; + NSButton* other = [alert_ addButtonWithTitle:other_button]; [other setKeyEquivalent:@"\e"]; } - if (display_suppress_checkbox_) { - [alert setShowsSuppressionButton:YES]; + if (dialog_->display_suppress_checkbox()) { + [alert_ setShowsSuppressionButton:YES]; NSString* suppression_title = l10n_util::GetNSStringWithFixup( IDS_JAVASCRIPT_MESSAGEBOX_SUPPRESS_OPTION); - [[alert suppressionButton] setTitle:suppression_title]; + [[alert_ suppressionButton] setTitle:suppression_title]; } +} - [alert beginSheetModalForWindow:nil // nil here makes it app-modal - modalDelegate:helper - didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) - contextInfo:this]; - - if (field) - [[alert window] makeFirstResponder:field]; +JSModalDialogCocoa::~JSModalDialogCocoa() { } -// The functions below are used by the automation framework. -int JavaScriptAppModalDialog::GetDialogButtons() { +//////////////////////////////////////////////////////////////////////////////// +// JSModalDialogCocoa, NativeAppModalDialog implementation: + +int JSModalDialogCocoa::GetAppModalDialogButtons() const { // From the above, it is the case that if there is 1 button, it is always the // OK button. The second button, if it exists, is always the Cancel button. - int num_buttons = [[dialog_ buttons] count]; + int num_buttons = [[alert_ buttons] count]; switch (num_buttons) { case 1: return MessageBoxFlags::DIALOGBUTTON_OK; @@ -177,27 +176,43 @@ int JavaScriptAppModalDialog::GetDialogButtons() { } } -// On Mac, this is only used in testing. -void JavaScriptAppModalDialog::AcceptWindow() { - NSButton* first = [[dialog_ buttons] objectAtIndex:0]; +void JSModalDialogCocoa::ShowAppModalDialog() { + [alert_ + beginSheetModalForWindow:nil // nil here makes it app-modal + modalDelegate:helper_.get() + didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) + contextInfo:this]; + + if ([helper_ textField]) + [[alert_ window] makeFirstResponder:[helper_ textField]]; +} + +void JSModalDialogCocoa::ActivateAppModalDialog() { +} + +void JSModalDialogCocoa::CloseAppModalDialog() { + DCHECK([alert_ isKindOfClass:[NSAlert class]]); + [NSApp endSheet:[alert_ window]]; + alert_ = NULL; +} + +void JSModalDialogCocoa::AcceptAppModalDialog() { + NSButton* first = [[alert_ buttons] objectAtIndex:0]; [first performClick:nil]; } -void JavaScriptAppModalDialog::CancelWindow() { - DCHECK([[dialog_ buttons] count] >= 2); - NSButton* second = [[dialog_ buttons] objectAtIndex:1]; +void JSModalDialogCocoa::CancelAppModalDialog() { + DCHECK([[alert_ buttons] count] >= 2); + NSButton* second = [[alert_ buttons] objectAtIndex:1]; [second performClick:nil]; } -// This is only used by the app-modal dialog machinery on windows. -NativeDialog JavaScriptAppModalDialog::CreateNativeDialog() { - NOTIMPLEMENTED(); - return nil; -} +//////////////////////////////////////////////////////////////////////////////// +// NativeAppModalDialog, public: -void JavaScriptAppModalDialog::CloseModalDialog() { - NSAlert* alert = dialog_; - DCHECK([alert isKindOfClass:[NSAlert class]]); - [NSApp endSheet:[alert window]]; - dialog_ = nil; +// static +NativeAppModalDialog* NativeAppModalDialog::CreateNativeJavaScriptPrompt( + JavaScriptAppModalDialog* dialog, + gfx::NativeWindow parent_window) { + return new JSModalDialogCocoa(dialog); } diff --git a/chrome/browser/js_modal_dialog_gtk.cc b/chrome/browser/gtk/js_modal_dialog_gtk.cc index 0c07a3f..9a12cc9 100644 --- a/chrome/browser/js_modal_dialog_gtk.cc +++ b/chrome/browser/gtk/js_modal_dialog_gtk.cc @@ -1,8 +1,8 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/js_modal_dialog.h" +#include "chrome/browser/gtk/js_modal_dialog_gtk.h" #include <gtk/gtk.h> @@ -12,8 +12,7 @@ #include "base/logging.h" #include "base/utf_string_conversions.h" #include "chrome/browser/gtk/gtk_util.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/tab_contents/tab_contents_view.h" +#include "chrome/browser/js_modal_dialog.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" @@ -46,76 +45,25 @@ bool ShouldSuppressJSDialogs(GtkDialog* dialog) { } // namespace -void JavaScriptAppModalDialog::CreateAndShowDialog() { - dialog_ = CreateNativeDialog(); - gtk_util::ShowModalDialogWithMinLocalizedWidth(GTK_WIDGET(dialog_), - IDS_ALERT_DIALOG_WIDTH_CHARS); -} - -void JavaScriptAppModalDialog::HandleDialogResponse(GtkDialog* dialog, - gint response_id) { - switch (response_id) { - case GTK_RESPONSE_OK: - // The first arg is the prompt text and the second is true if we want to - // suppress additional popups from the page. - OnAccept(GetPromptText(dialog), ShouldSuppressJSDialogs(dialog)); - break; - - case GTK_RESPONSE_CANCEL: - case GTK_RESPONSE_DELETE_EVENT: // User hit the X on the dialog. - OnCancel(); - break; - - default: - NOTREACHED(); - } - gtk_widget_destroy(GTK_WIDGET(dialog)); +//////////////////////////////////////////////////////////////////////////////// +// JSModalDialogGtk, public: - // Now that the dialog is gone, we can put all the windows into separate - // window groups so other dialogs are no longer app modal. - gtk_util::AppModalDismissedUngroupWindows(); - delete this; -} - -int JavaScriptAppModalDialog::GetDialogButtons() { - switch (dialog_flags_) { - case MessageBoxFlags::kIsJavascriptAlert: - return MessageBoxFlags::DIALOGBUTTON_OK; - - case MessageBoxFlags::kIsJavascriptConfirm: - return MessageBoxFlags::DIALOGBUTTON_OK | - MessageBoxFlags::DIALOGBUTTON_CANCEL; - - case MessageBoxFlags::kIsJavascriptPrompt: - return MessageBoxFlags::DIALOGBUTTON_OK; - - default: - NOTREACHED(); - return 0; - } -} - -void JavaScriptAppModalDialog::AcceptWindow() { - HandleDialogResponse(GTK_DIALOG(dialog_), GTK_RESPONSE_OK); -} - -void JavaScriptAppModalDialog::CancelWindow() { - HandleDialogResponse(GTK_DIALOG(dialog_), GTK_RESPONSE_CANCEL); -} - -NativeDialog JavaScriptAppModalDialog::CreateNativeDialog() { +JSModalDialogGtk::JSModalDialogGtk(JavaScriptAppModalDialog* dialog, + gfx::NativeWindow parent_window) + : dialog_(dialog) { GtkButtonsType buttons = GTK_BUTTONS_NONE; GtkMessageType message_type = GTK_MESSAGE_OTHER; + // We add in the OK button manually later because we want to focus it // explicitly. - switch (dialog_flags_) { + switch (dialog_->dialog_flags()) { case MessageBoxFlags::kIsJavascriptAlert: buttons = GTK_BUTTONS_NONE; message_type = GTK_MESSAGE_WARNING; break; case MessageBoxFlags::kIsJavascriptConfirm: - if (is_before_unload_dialog_) { + if (dialog_->is_before_unload_dialog()) { // onbeforeunload also uses a confirm prompt, it just has custom // buttons. We add the buttons using gtk_dialog_add_button below. buttons = GTK_BUTTONS_NONE; @@ -138,56 +86,149 @@ NativeDialog JavaScriptAppModalDialog::CreateNativeDialog() { // same window group. gtk_util::MakeAppModalWindowGroup(); - gfx::NativeWindow window = client_->GetMessageBoxRootWindow(); - NativeDialog dialog = gtk_message_dialog_new(window, GTK_DIALOG_MODAL, - message_type, buttons, "%s", WideToUTF8(message_text_).c_str()); - gtk_util::ApplyMessageDialogQuirks(dialog); - gtk_window_set_title(GTK_WINDOW(dialog), WideToUTF8(title_).c_str()); + gtk_dialog_ = gtk_message_dialog_new(parent_window, + GTK_DIALOG_MODAL, message_type, buttons, "%s", + WideToUTF8(dialog_->message_text()).c_str()); + gtk_util::ApplyMessageDialogQuirks(gtk_dialog_); + gtk_window_set_title(GTK_WINDOW(gtk_dialog_), + WideToUTF8(dialog_->title()).c_str()); // Adjust content area as needed. Set up the prompt text entry or // suppression check box. - if (MessageBoxFlags::kIsJavascriptPrompt == dialog_flags_) { + if (MessageBoxFlags::kIsJavascriptPrompt == dialog_->dialog_flags()) { // TODO(tc): Replace with gtk_dialog_get_content_area() when using GTK 2.14+ - GtkWidget* contents_vbox = GTK_DIALOG(dialog)->vbox; + GtkWidget* contents_vbox = GTK_DIALOG(gtk_dialog_)->vbox; GtkWidget* text_box = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(text_box), - WideToUTF8(default_prompt_text_).c_str()); + WideToUTF8(dialog_->default_prompt_text()).c_str()); gtk_box_pack_start(GTK_BOX(contents_vbox), text_box, TRUE, TRUE, 0); - g_object_set_data(G_OBJECT(dialog), kPromptTextId, text_box); + g_object_set_data(G_OBJECT(gtk_dialog_), kPromptTextId, text_box); gtk_entry_set_activates_default(GTK_ENTRY(text_box), TRUE); } - if (display_suppress_checkbox_) { - GtkWidget* contents_vbox = GTK_DIALOG(dialog)->vbox; + if (dialog_->display_suppress_checkbox()) { + GtkWidget* contents_vbox = GTK_DIALOG(gtk_dialog_)->vbox; GtkWidget* check_box = gtk_check_button_new_with_label( l10n_util::GetStringUTF8( - IDS_JAVASCRIPT_MESSAGEBOX_SUPPRESS_OPTION).c_str()); + IDS_JAVASCRIPT_MESSAGEBOX_SUPPRESS_OPTION).c_str()); gtk_box_pack_start(GTK_BOX(contents_vbox), check_box, TRUE, TRUE, 0); - g_object_set_data(G_OBJECT(dialog), kSuppressCheckboxId, check_box); + g_object_set_data(G_OBJECT(gtk_dialog_), kSuppressCheckboxId, check_box); } // Adjust buttons/action area as needed. - if (is_before_unload_dialog_) { + if (dialog_->is_before_unload_dialog()) { std::string button_text = l10n_util::GetStringUTF8( - IDS_BEFOREUNLOAD_MESSAGEBOX_OK_BUTTON_LABEL); - gtk_dialog_add_button(GTK_DIALOG(dialog), button_text.c_str(), - GTK_RESPONSE_OK); + IDS_BEFOREUNLOAD_MESSAGEBOX_OK_BUTTON_LABEL); + gtk_dialog_add_button(GTK_DIALOG(gtk_dialog_), button_text.c_str(), + GTK_RESPONSE_OK); button_text = l10n_util::GetStringUTF8( IDS_BEFOREUNLOAD_MESSAGEBOX_CANCEL_BUTTON_LABEL); - gtk_dialog_add_button(GTK_DIALOG(dialog), button_text.c_str(), - GTK_RESPONSE_CANCEL); + gtk_dialog_add_button(GTK_DIALOG(gtk_dialog_), button_text.c_str(), + GTK_RESPONSE_CANCEL); } else { // Add the OK button and focus it. - GtkWidget* ok_button = gtk_dialog_add_button(GTK_DIALOG(dialog), + GtkWidget* ok_button = gtk_dialog_add_button(GTK_DIALOG(gtk_dialog_), GTK_STOCK_OK, GTK_RESPONSE_OK); - if (MessageBoxFlags::kIsJavascriptPrompt != dialog_flags_) + if (MessageBoxFlags::kIsJavascriptPrompt != dialog_->dialog_flags()) gtk_widget_grab_focus(ok_button); } - gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); - g_signal_connect(dialog, "response", - G_CALLBACK(AppModalDialog::OnDialogResponse), - reinterpret_cast<AppModalDialog*>(this)); - return dialog; + gtk_dialog_set_default_response(GTK_DIALOG(gtk_dialog_), GTK_RESPONSE_OK); + g_signal_connect(gtk_dialog_, "response", + G_CALLBACK(JSModalDialogGtk::OnDialogResponse), + reinterpret_cast<JSModalDialogGtk*>(this)); +} + +JSModalDialogGtk::~JSModalDialogGtk() { +} + +//////////////////////////////////////////////////////////////////////////////// +// JSModalDialogGtk, NativeAppModalDialog implementation: + +int JSModalDialogGtk::GetAppModalDialogButtons() const { + switch (dialog_->dialog_flags()) { + case MessageBoxFlags::kIsJavascriptAlert: + return MessageBoxFlags::DIALOGBUTTON_OK; + + case MessageBoxFlags::kIsJavascriptConfirm: + return MessageBoxFlags::DIALOGBUTTON_OK | + MessageBoxFlags::DIALOGBUTTON_CANCEL; + + case MessageBoxFlags::kIsJavascriptPrompt: + return MessageBoxFlags::DIALOGBUTTON_OK; + + default: + NOTREACHED(); + return 0; + } +} + +void JSModalDialogGtk::ShowAppModalDialog() { + gtk_util::ShowModalDialogWithMinLocalizedWidth(GTK_WIDGET(gtk_dialog_), + IDS_ALERT_DIALOG_WIDTH_CHARS); +} + +void JSModalDialogGtk::ActivateAppModalDialog() { + DCHECK(gtk_dialog_); + gtk_window_present(GTK_WINDOW(gtk_dialog_));} + +void JSModalDialogGtk::CloseAppModalDialog() { + DCHECK(gtk_dialog_); + HandleDialogResponse(GTK_DIALOG(gtk_dialog_), GTK_RESPONSE_DELETE_EVENT); +} + +void JSModalDialogGtk::AcceptAppModalDialog() { + HandleDialogResponse(GTK_DIALOG(gtk_dialog_), GTK_RESPONSE_OK); } + +void JSModalDialogGtk::CancelAppModalDialog() { + HandleDialogResponse(GTK_DIALOG(gtk_dialog_), GTK_RESPONSE_CANCEL); +} + +//////////////////////////////////////////////////////////////////////////////// +// JSModalDialogGtk, private: + +void JSModalDialogGtk::HandleDialogResponse(GtkDialog* dialog, + gint response_id) { + switch (response_id) { + case GTK_RESPONSE_OK: + // The first arg is the prompt text and the second is true if we want to + // suppress additional popups from the page. + dialog_->OnAccept(GetPromptText(dialog), ShouldSuppressJSDialogs(dialog)); + break; + + case GTK_RESPONSE_CANCEL: + case GTK_RESPONSE_DELETE_EVENT: // User hit the X on the dialog. + dialog_->OnCancel(); + break; + + default: + NOTREACHED(); + } + gtk_widget_destroy(GTK_WIDGET(dialog)); + + // Now that the dialog is gone, we can put all the windows into separate + // window groups so other dialogs are no longer app modal. + gtk_util::AppModalDismissedUngroupWindows(); + delete this; +} + +// static +void JSModalDialogGtk::OnDialogResponse(GtkDialog* gtk_dialog, + gint response_id, + JSModalDialogGtk* dialog) { + dialog->HandleDialogResponse(gtk_dialog, response_id); +} + +//////////////////////////////////////////////////////////////////////////////// +// NativeAppModalDialog, public: + +// static +NativeAppModalDialog* NativeAppModalDialog::CreateNativeJavaScriptPrompt( + JavaScriptAppModalDialog* dialog, + gfx::NativeWindow parent_window) { + return new JSModalDialogGtk(dialog, parent_window); +} + + diff --git a/chrome/browser/gtk/js_modal_dialog_gtk.h b/chrome/browser/gtk/js_modal_dialog_gtk.h new file mode 100644 index 0000000..18d573c --- /dev/null +++ b/chrome/browser/gtk/js_modal_dialog_gtk.h @@ -0,0 +1,45 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_GTK_JS_MODAL_DIALOG_GTK_H_ +#define CHROME_BROWSER_GTK_JS_MODAL_DIALOG_GTK_H_ +#pragma once + +#include <gtk/gtk.h> + +#include "app/gtk_signal.h" +#include "base/logging.h" +#include "base/scoped_ptr.h" +#include "chrome/browser/native_app_modal_dialog.h" +#include "gfx/native_widget_types.h" + +class JavaScriptAppModalDialog; + +class JSModalDialogGtk : public NativeAppModalDialog { + public: + JSModalDialogGtk(JavaScriptAppModalDialog* dialog, + gfx::NativeWindow parent_window); + virtual ~JSModalDialogGtk(); + + // Overridden from NativeAppModalDialog: + virtual int GetAppModalDialogButtons() const; + virtual void ShowAppModalDialog(); + virtual void ActivateAppModalDialog(); + virtual void CloseAppModalDialog(); + virtual void AcceptAppModalDialog(); + virtual void CancelAppModalDialog(); + + private: + void HandleDialogResponse(GtkDialog* dialog, gint response_id); + static void OnDialogResponse(GtkDialog* gtk_dialog, gint response_id, + JSModalDialogGtk* dialog); + + scoped_ptr<JavaScriptAppModalDialog> dialog_; + GtkWidget* gtk_dialog_; + + DISALLOW_COPY_AND_ASSIGN(JSModalDialogGtk); +}; + +#endif // CHROME_BROWSER_GTK_JS_MODAL_DIALOG_GTK_H_ + diff --git a/chrome/browser/js_modal_dialog.cc b/chrome/browser/js_modal_dialog.cc index 7c42c71..8f79da2 100644 --- a/chrome/browser/js_modal_dialog.cc +++ b/chrome/browser/js_modal_dialog.cc @@ -7,6 +7,7 @@ #include "base/string_util.h" #include "chrome/browser/browser_shutdown.h" #include "chrome/browser/extensions/extension_host.h" +#include "chrome/browser/native_app_modal_dialog.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/notification_service.h" #include "chrome/common/notification_type.h" @@ -30,9 +31,6 @@ JavaScriptAppModalDialog::JavaScriptAppModalDialog( bool is_before_unload_dialog, IPC::Message* reply_msg) : AppModalDialog(client->AsTabContents(), title), -#if defined(OS_MACOSX) - dialog_(NULL), -#endif client_(client), extension_host_(client->AsExtensionHost()), dialog_flags_(dialog_flags), @@ -52,6 +50,14 @@ JavaScriptAppModalDialog::JavaScriptAppModalDialog( JavaScriptAppModalDialog::~JavaScriptAppModalDialog() { } +NativeAppModalDialog* JavaScriptAppModalDialog::CreateNativeDialog() { + gfx::NativeWindow parent_window = tab_contents_ ? + tab_contents_->GetMessageBoxRootWindow() : + extension_host_->GetMessageBoxRootWindow(); + return NativeAppModalDialog::CreateNativeJavaScriptPrompt(this, + parent_window); +} + void JavaScriptAppModalDialog::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { @@ -68,7 +74,7 @@ void JavaScriptAppModalDialog::Observe(NotificationType type, // Also clear the client, since it's now invalid. skip_this_dialog_ = true; client_ = NULL; - if (dialog_) + if (native_dialog_) CloseModalDialog(); } @@ -144,5 +150,4 @@ void JavaScriptAppModalDialog::Cleanup() { NOTREACHED(); #endif } - AppModalDialog::Cleanup(); } diff --git a/chrome/browser/js_modal_dialog.h b/chrome/browser/js_modal_dialog.h index 7cfe34f..b2cccff 100644 --- a/chrome/browser/js_modal_dialog.h +++ b/chrome/browser/js_modal_dialog.h @@ -13,16 +13,9 @@ #include "chrome/common/notification_observer.h" #include "chrome/common/notification_registrar.h" -#if defined(OS_MACOSX) -#if __OBJC__ -@class NSAlert; -#else -class NSAlert; -#endif -#endif - class ExtensionHost; class JavaScriptMessageBoxClient; +class NativeAppModalDialog; namespace IPC { class Message; @@ -46,41 +39,27 @@ class JavaScriptAppModalDialog : public AppModalDialog, virtual ~JavaScriptAppModalDialog(); // AppModalDialog overrides. -#if defined(OS_POSIX) - virtual void CreateAndShowDialog(); -#endif -#if defined(TOOLKIT_USES_GTK) - virtual void HandleDialogResponse(GtkDialog* dialog, gint response_id); -#endif - virtual int GetDialogButtons(); - virtual void AcceptWindow(); - virtual void CancelWindow(); + virtual NativeAppModalDialog* CreateNativeDialog(); ///////////////////////////////////////////////////////////////////////////// // Getters so NativeDialog can get information about the message box. - JavaScriptMessageBoxClient* client() { - return client_; - } - int dialog_flags() { - return dialog_flags_; - } - bool is_before_unload_dialog() { - return is_before_unload_dialog_; - } - -#if defined(OS_MACOSX) - virtual void CloseModalDialog(); -#endif + JavaScriptMessageBoxClient* client() const { return client_; } // Callbacks from NativeDialog when the user accepts or cancels the dialog. void OnCancel(); void OnAccept(const std::wstring& prompt_text, bool suppress_js_messages); void OnClose(); + // Accessors + int dialog_flags() const { return dialog_flags_; } + std::wstring message_text() const { return message_text_; } + std::wstring default_prompt_text() const { return default_prompt_text_; } + bool display_suppress_checkbox() const { return display_suppress_checkbox_; } + bool is_before_unload_dialog() const { return is_before_unload_dialog_; } + protected: // AppModalDialog overrides. virtual void Cleanup(); - virtual NativeDialog CreateNativeDialog(); private: // NotificationObserver implementation. @@ -91,9 +70,7 @@ class JavaScriptAppModalDialog : public AppModalDialog, // Initializes for notifications to listen. void InitNotifications(); -#if defined(OS_MACOSX) - NSAlert* dialog_; -#endif + NativeAppModalDialog* native_dialog_; NotificationRegistrar registrar_; diff --git a/chrome/browser/js_modal_dialog_win.cc b/chrome/browser/js_modal_dialog_win.cc deleted file mode 100644 index 26cebc4..0000000 --- a/chrome/browser/js_modal_dialog_win.cc +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/js_modal_dialog.h" - -#include "chrome/browser/views/jsmessage_box_dialog.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "views/window/window.h" - -int JavaScriptAppModalDialog::GetDialogButtons() { - return dialog_->GetDialogButtons(); -} - -void JavaScriptAppModalDialog::AcceptWindow() { - views::DialogClientView* client_view = - dialog_->window()->GetClientView()->AsDialogClientView(); - client_view->AcceptWindow(); -} - -void JavaScriptAppModalDialog::CancelWindow() { - views::DialogClientView* client_view = - dialog_->window()->GetClientView()->AsDialogClientView(); - client_view->CancelWindow(); -} - -NativeDialog JavaScriptAppModalDialog::CreateNativeDialog() { - return new JavaScriptMessageBoxDialog(this, message_text_, - default_prompt_text_, display_suppress_checkbox_); -} diff --git a/chrome/browser/message_box_handler.cc b/chrome/browser/message_box_handler.cc index a6006dc..7389cc7 100644 --- a/chrome/browser/message_box_handler.cc +++ b/chrome/browser/message_box_handler.cc @@ -24,39 +24,41 @@ #include "grit/chromium_strings.h" static std::wstring GetTitle(Profile* profile, - ExtensionsService* extensions_service, bool is_alert, const GURL& frame_url) { - Extension* extension = extensions_service->GetExtensionByURL(frame_url); - if (!extension) - extension = extensions_service->GetExtensionByWebExtent(frame_url); + ExtensionsService* extensions_service = profile->GetExtensionsService(); + if (extensions_service) { + Extension* extension = extensions_service->GetExtensionByURL(frame_url); + if (!extension) + extension = extensions_service->GetExtensionByWebExtent(frame_url); - if (extension && (extension->location() == Extension::COMPONENT)) { - return l10n_util::GetString(IDS_PRODUCT_NAME); - } else if (extension && !extension->name().empty()) { - return UTF8ToWide(extension->name()); - } else { - if (!frame_url.has_host()) - return l10n_util::GetString( - is_alert ? IDS_JAVASCRIPT_ALERT_DEFAULT_TITLE - : IDS_JAVASCRIPT_MESSAGEBOX_DEFAULT_TITLE); + if (extension && (extension->location() == Extension::COMPONENT)) { + return l10n_util::GetString(IDS_PRODUCT_NAME); + } else if (extension && !extension->name().empty()) { + return UTF8ToWide(extension->name()); + } + } + if (!frame_url.has_host()) { + return l10n_util::GetString( + is_alert ? IDS_JAVASCRIPT_ALERT_DEFAULT_TITLE + : IDS_JAVASCRIPT_MESSAGEBOX_DEFAULT_TITLE); + } - // TODO(brettw) it should be easier than this to do the correct language - // handling without getting the accept language from the profile. - string16 base_address = WideToUTF16(gfx::ElideUrl(frame_url.GetOrigin(), - gfx::Font(), 0, - UTF8ToWide( - profile->GetPrefs()->GetString(prefs::kAcceptLanguages)))); + // TODO(brettw) it should be easier than this to do the correct language + // handling without getting the accept language from the profile. + string16 base_address = WideToUTF16(gfx::ElideUrl(frame_url.GetOrigin(), + gfx::Font(), 0, + UTF8ToWide( + profile->GetPrefs()->GetString(prefs::kAcceptLanguages)))); - // Force URL to have LTR directionality. - base_address = base::i18n::GetDisplayStringInLTRDirectionality( - base_address); + // Force URL to have LTR directionality. + base_address = base::i18n::GetDisplayStringInLTRDirectionality( + base_address); - return UTF16ToWide(l10n_util::GetStringFUTF16( - is_alert ? IDS_JAVASCRIPT_ALERT_TITLE : - IDS_JAVASCRIPT_MESSAGEBOX_TITLE, - base_address)); - } + return UTF16ToWide(l10n_util::GetStringFUTF16( + is_alert ? IDS_JAVASCRIPT_ALERT_TITLE : + IDS_JAVASCRIPT_MESSAGEBOX_TITLE, + base_address)); } void RunJavascriptMessageBox(Profile* profile, @@ -67,13 +69,8 @@ void RunJavascriptMessageBox(Profile* profile, const std::wstring& default_prompt_text, bool display_suppress_checkbox, IPC::Message* reply_msg) { - ExtensionsService* extensions_service = profile->GetExtensionsService(); - if (!extensions_service) - return; - bool is_alert = dialog_flags == MessageBoxFlags::kIsJavascriptAlert; - std::wstring title = GetTitle(profile, extensions_service, - is_alert, frame_url); + std::wstring title = GetTitle(profile, is_alert, frame_url); Singleton<AppModalDialogQueue>()->AddDialog(new JavaScriptAppModalDialog( client, title, dialog_flags, message_text, default_prompt_text, display_suppress_checkbox, false, reply_msg)); diff --git a/chrome/browser/native_app_modal_dialog.h b/chrome/browser/native_app_modal_dialog.h new file mode 100644 index 0000000..7b4c5b2 --- /dev/null +++ b/chrome/browser/native_app_modal_dialog.h @@ -0,0 +1,39 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_NATIVE_APP_MODAL_DIALOG_H_ +#define CHROME_BROWSER_NATIVE_APP_MODAL_DIALOG_H_ +#pragma once + +#include "gfx/native_widget_types.h" + +class JavaScriptAppModalDialog; + +class NativeAppModalDialog { + public: + // Returns the buttons to be shown. See MessageBoxFlags for a description of + // the values. + virtual int GetAppModalDialogButtons() const = 0; + + // Shows the dialog. + virtual void ShowAppModalDialog() = 0; + + // Activates the dialog. + virtual void ActivateAppModalDialog() = 0; + + // Closes the dialog. + virtual void CloseAppModalDialog() = 0; + + // Accepts or cancels the dialog. + virtual void AcceptAppModalDialog() = 0; + virtual void CancelAppModalDialog() = 0; + + // Creates an app modal dialog for a JavaScript prompt. + static NativeAppModalDialog* CreateNativeJavaScriptPrompt( + JavaScriptAppModalDialog* dialog, + gfx::NativeWindow parent_window); +}; + +#endif // CHROME_BROWSER_NATIVE_APP_MODAL_DIALOG_H_ + diff --git a/chrome/browser/views/jsmessage_box_dialog.cc b/chrome/browser/views/jsmessage_box_dialog.cc index f51116b..c0a6b3a 100644 --- a/chrome/browser/views/jsmessage_box_dialog.cc +++ b/chrome/browser/views/jsmessage_box_dialog.cc @@ -8,25 +8,24 @@ #include "app/l10n_util.h" #include "app/message_box_flags.h" #include "chrome/browser/app_modal_dialog.h" -#include "chrome/browser/tab_contents/tab_contents.h" #include "grit/generated_resources.h" #include "views/controls/message_box_view.h" #include "views/window/window.h" +//////////////////////////////////////////////////////////////////////////////// +// JavaScriptMessageBoxDialog, public: + JavaScriptMessageBoxDialog::JavaScriptMessageBoxDialog( - JavaScriptAppModalDialog* parent, - const std::wstring& message_text, - const std::wstring& default_prompt_text, - bool display_suppress_checkbox) + JavaScriptAppModalDialog* parent) : parent_(parent), message_box_view_(new MessageBoxView( parent->dialog_flags() | MessageBoxFlags::kAutoDetectAlignment, - message_text, default_prompt_text)) { + parent->message_text(), parent->default_prompt_text())) { DCHECK(message_box_view_); message_box_view_->AddAccelerator( views::Accelerator(app::VKEY_C, false, true, false)); - if (display_suppress_checkbox) { + if (parent->display_suppress_checkbox()) { message_box_view_->SetCheckBoxLabel( l10n_util::GetString(IDS_JAVASCRIPT_MESSAGEBOX_SUPPRESS_OPTION)); } @@ -35,8 +34,32 @@ JavaScriptMessageBoxDialog::JavaScriptMessageBoxDialog( JavaScriptMessageBoxDialog::~JavaScriptMessageBoxDialog() { } -gfx::NativeWindow JavaScriptMessageBoxDialog::GetDialogRootWindow() { - return client()->GetMessageBoxRootWindow(); +//////////////////////////////////////////////////////////////////////////////// +// JavaScriptMessageBoxDialog, NativeAppModalDialog implementation: + +int JavaScriptMessageBoxDialog::GetAppModalDialogButtons() const { + return GetDialogButtons(); +} + +void JavaScriptMessageBoxDialog::ShowAppModalDialog() { + window()->Show(); +} + +void JavaScriptMessageBoxDialog::ActivateAppModalDialog() { + window()->Show(); + window()->Activate(); +} + +void JavaScriptMessageBoxDialog::CloseAppModalDialog() { + window()->Close(); +} + +void JavaScriptMessageBoxDialog::AcceptAppModalDialog() { + GetDialogClientView()->AcceptWindow(); +} + +void JavaScriptMessageBoxDialog::CancelAppModalDialog() { + GetDialogClientView()->CancelWindow(); } ////////////////////////////////////////////////////////////////////////////// @@ -116,3 +139,15 @@ views::View* JavaScriptMessageBoxDialog::GetInitiallyFocusedView() { return message_box_view_->text_box(); return views::DialogDelegate::GetInitiallyFocusedView(); } + +//////////////////////////////////////////////////////////////////////////////// +// NativeAppModalDialog, public: + +// static +NativeAppModalDialog* NativeAppModalDialog::CreateNativeJavaScriptPrompt( + JavaScriptAppModalDialog* dialog, + gfx::NativeWindow parent_window) { + JavaScriptMessageBoxDialog* d = new JavaScriptMessageBoxDialog(dialog); + views::Window::CreateChromeWindow(parent_window, gfx::Rect(), d); + return d; +} diff --git a/chrome/browser/views/jsmessage_box_dialog.h b/chrome/browser/views/jsmessage_box_dialog.h index 512f2cf..08f3dab 100644 --- a/chrome/browser/views/jsmessage_box_dialog.h +++ b/chrome/browser/views/jsmessage_box_dialog.h @@ -12,24 +12,26 @@ #include "app/message_box_flags.h" #include "chrome/browser/jsmessage_box_client.h" -#include "chrome/browser/views/modal_dialog_delegate.h" +#include "chrome/browser/native_app_modal_dialog.h" +#include "views/window/dialog_delegate.h" class MessageBoxView; -class JavaScriptMessageBoxClient; -class JavaScriptMessageBoxDialog : public ModalDialogDelegate { +class JavaScriptMessageBoxDialog : public NativeAppModalDialog, + public views::DialogDelegate { public: - JavaScriptMessageBoxDialog(JavaScriptAppModalDialog* parent, - const std::wstring& message_text, - const std::wstring& default_prompt_text, - bool display_suppress_checkbox); - + explicit JavaScriptMessageBoxDialog(JavaScriptAppModalDialog* parent); virtual ~JavaScriptMessageBoxDialog(); - // Overriden from ModalDialogDelegate: - virtual gfx::NativeWindow GetDialogRootWindow(); + // Overridden from NativeAppModalDialog: + virtual int GetAppModalDialogButtons() const; + virtual void ShowAppModalDialog(); + virtual void ActivateAppModalDialog(); + virtual void CloseAppModalDialog(); + virtual void AcceptAppModalDialog(); + virtual void CancelAppModalDialog(); - // Overriden from views::DialogDelegate: + // Overridden from views::DialogDelegate: virtual int GetDefaultDialogButton() const; virtual int GetDialogButtons() const; virtual std::wstring GetWindowTitle() const; @@ -40,16 +42,14 @@ class JavaScriptMessageBoxDialog : public ModalDialogDelegate { virtual std::wstring GetDialogButtonLabel( MessageBoxFlags::DialogButton button) const; - // Overriden from views::WindowDelegate: + // Overridden from views::WindowDelegate: virtual bool IsModal() const { return true; } virtual views::View* GetContentsView(); virtual views::View* GetInitiallyFocusedView(); virtual void OnClose(); private: - JavaScriptMessageBoxClient* client() { - return parent_->client(); - } + JavaScriptMessageBoxClient* client() const { return parent_->client(); } // A pointer to the AppModalDialog that owns us. JavaScriptAppModalDialog* parent_; diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 27f8180..7575488 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -73,9 +73,6 @@ 'browser/app_launched_animation.h', 'browser/app_modal_dialog.cc', 'browser/app_modal_dialog.h', - 'browser/app_modal_dialog_gtk.cc', - 'browser/app_modal_dialog_mac.mm', - 'browser/app_modal_dialog_win.cc', 'browser/app_modal_dialog_queue.cc', 'browser/app_modal_dialog_queue.h', 'browser/appcache/appcache_dispatcher_host.cc', @@ -985,6 +982,8 @@ 'browser/cocoa/infobar_test_helper.h', 'browser/cocoa/install_from_dmg.h', 'browser/cocoa/install_from_dmg.mm', + 'browser/cocoa/js_modal_dialog_cocoa.h', + 'browser/cocoa/js_modal_dialog_cocoa.mm', 'browser/cocoa/keystone_glue.h', 'browser/cocoa/keystone_glue.mm', 'browser/cocoa/keystone_infobar.h', @@ -1765,6 +1764,8 @@ 'browser/gtk/infobar_container_gtk.h', 'browser/gtk/infobar_gtk.cc', 'browser/gtk/infobar_gtk.h', + 'browser/gtk/js_modal_dialog_gtk.cc', + 'browser/gtk/js_modal_dialog_gtk.h', 'browser/gtk/keyword_editor_view.cc', 'browser/gtk/keyword_editor_view.h', 'browser/gtk/location_bar_view_gtk.cc', @@ -2033,9 +2034,6 @@ 'browser/jumplist_win.h', 'browser/js_modal_dialog.cc', 'browser/js_modal_dialog.h', - 'browser/js_modal_dialog_gtk.cc', - 'browser/js_modal_dialog_mac.mm', - 'browser/js_modal_dialog_win.cc', 'browser/jsmessage_box_client.h', 'browser/keychain_mac.cc', 'browser/keychain_mac.h', @@ -2087,6 +2085,7 @@ 'browser/nacl_host/nacl_broker_service_win.h', 'browser/nacl_host/nacl_process_host.cc', 'browser/nacl_host/nacl_process_host.h', + 'browser/native_app_modal_dialog.h', 'browser/net/blob_url_request_job_factory.cc', 'browser/net/blob_url_request_job_factory.h', 'browser/net/browser_url_util.cc', @@ -3641,6 +3640,8 @@ ['include', '^browser/views/info_bubble.h'], ['include', '^browser/views/html_dialog_view.cc'], ['include', '^browser/views/html_dialog_view.h'], + ['include', '^browser/views/jsmessage_box_dialog.cc'], + ['include', '^browser/views/jsmessage_box_dialog.h'], ['include', '^browser/views/location_bar/click_handler.cc'], ['include', '^browser/views/location_bar/click_handler.h'], ['include', '^browser/views/location_bar/content_setting_image_view.cc'], diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h index c90d54a..541aaa9 100644 --- a/chrome/common/notification_type.h +++ b/chrome/common/notification_type.h @@ -294,10 +294,6 @@ class NotificationType { // is the dialog. APP_MODAL_DIALOG_SHOWN, - // Sent after an application-modal dialog has been closed. The source - // is the dialog. - APP_MODAL_DIALOG_CLOSED, - // Tabs -------------------------------------------------------------------- // Sent when a tab is added to a TabContentsDelegate. The source is the diff --git a/views/window/window_gtk.cc b/views/window/window_gtk.cc index 16444b3d9..785b1bc 100644 --- a/views/window/window_gtk.cc +++ b/views/window/window_gtk.cc @@ -491,6 +491,8 @@ void WindowGtk::SizeWindowToDefault(GtkWindow* parent) { void WindowGtk::OnDestroy(GtkWidget* widget) { non_client_view_->WindowClosing(); WidgetGtk::OnDestroy(widget); + window_delegate_->DeleteDelegate(); + window_delegate_ = NULL; } } // namespace views |