diff options
Diffstat (limited to 'chrome/browser/jsmessage_box_handler_win.cc')
-rw-r--r-- | chrome/browser/jsmessage_box_handler_win.cc | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/chrome/browser/jsmessage_box_handler_win.cc b/chrome/browser/jsmessage_box_handler_win.cc new file mode 100644 index 0000000..39d19cd --- /dev/null +++ b/chrome/browser/jsmessage_box_handler_win.cc @@ -0,0 +1,209 @@ +// Copyright (c) 2006-2008 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/jsmessage_box_handler_win.h" + +#include "chrome/browser/app_modal_dialog_queue.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/tab_contents/web_contents.h" +#include "chrome/common/gfx/text_elider.h" +#include "chrome/common/l10n_util.h" +#include "chrome/common/notification_service.h" +#include "chrome/common/notification_types.h" +#include "chrome/common/pref_names.h" +#include "chrome/common/pref_service.h" +#include "chrome/views/message_box_view.h" +#include "chrome/views/window.h" + +#include "generated_resources.h" + +void RunJavascriptMessageBox(WebContents* web_contents, + int dialog_flags, + const std::wstring& message_text, + const std::wstring& default_prompt_text, + bool display_suppress_checkbox, + IPC::Message* reply_msg) { + JavascriptMessageBoxHandler* handler = + new JavascriptMessageBoxHandler(web_contents, dialog_flags, + message_text, default_prompt_text, + display_suppress_checkbox, reply_msg); + AppModalDialogQueue::AddDialog(handler); +} + +JavascriptMessageBoxHandler::JavascriptMessageBoxHandler( + WebContents* web_contents, + int dialog_flags, + const std::wstring& message_text, + const std::wstring& default_prompt_text, + bool display_suppress_checkbox, + IPC::Message* reply_msg) + : web_contents_(web_contents), + reply_msg_(reply_msg), + dialog_flags_(dialog_flags), + dialog_(NULL), + message_box_view_(new MessageBoxView(dialog_flags, message_text, + default_prompt_text)) { + DCHECK(message_box_view_); + DCHECK(reply_msg_); + + if (display_suppress_checkbox) { + message_box_view_->SetCheckBoxLabel( + l10n_util::GetString(IDS_JAVASCRIPT_MESSAGEBOX_SUPPRESS_OPTION)); + } + + // Make sure we get navigation notifications so we know when our parent + // contents will disappear or navigate to a different page. + registrar_.Add(this, NOTIFY_NAV_ENTRY_COMMITTED, + NotificationService::AllSources()); + registrar_.Add(this, NOTIFY_TAB_CONTENTS_DESTROYED, + NotificationService::AllSources()); +} + +JavascriptMessageBoxHandler::~JavascriptMessageBoxHandler() { +} + +////////////////////////////////////////////////////////////////////////////// +// JavascriptMessageBoxHandler, views::DialogDelegate implementation: + +int JavascriptMessageBoxHandler::GetDialogButtons() const { + int dialog_buttons = 0; + if (dialog_flags_ & MessageBoxView::kFlagHasOKButton) + dialog_buttons = DIALOGBUTTON_OK; + + if (dialog_flags_ & MessageBoxView::kFlagHasCancelButton) + dialog_buttons |= DIALOGBUTTON_CANCEL; + + return dialog_buttons; +} + +std::wstring JavascriptMessageBoxHandler::GetWindowTitle() const { + if (!web_contents_) + return std::wstring(); + + GURL url = web_contents_->GetURL(); + if (!url.has_host()) + return l10n_util::GetString(IDS_JAVASCRIPT_MESSAGEBOX_DEFAULT_TITLE); + + // We really only want the scheme, hostname, and port. + GURL::Replacements replacements; + replacements.ClearUsername(); + replacements.ClearPassword(); + replacements.ClearPath(); + replacements.ClearQuery(); + replacements.ClearRef(); + GURL clean_url = url.ReplaceComponents(replacements); + + // TODO(brettw) it should be easier than this to do the correct language + // handling without getting the accept language from the profile. + std::wstring base_address = gfx::ElideUrl(clean_url, ChromeFont(), 0, + web_contents_->profile()->GetPrefs()->GetString(prefs::kAcceptLanguages)); + // Force URL to have LTR directionality. + if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) + l10n_util::WrapStringWithLTRFormatting(&base_address); + return l10n_util::GetStringF(IDS_JAVASCRIPT_MESSAGEBOX_TITLE, base_address); +} + +void JavascriptMessageBoxHandler::WindowClosing() { + dialog_ = NULL; + + if (message_box_view_->IsCheckBoxSelected() && web_contents_) + web_contents_->set_suppress_javascript_messages(true); + + delete this; +} + +bool JavascriptMessageBoxHandler::Cancel() { + // We need to do this before WM_DESTROY (WindowClosing()) as any parent frame + // will receive it's activation messages before this dialog receives + // WM_DESTROY. The parent frame would then try to activate any modal dialogs + // that were still open in the ModalDialogQueue, which would send activation + // back to this one. The framework should be improved to handle this, so this + // is a temporary workaround. + AppModalDialogQueue::ShowNextDialog(); + + if (web_contents_) { + web_contents_->OnJavaScriptMessageBoxClosed(reply_msg_, false, + EmptyWString()); + } + return true; +} + +bool JavascriptMessageBoxHandler::Accept() { + AppModalDialogQueue::ShowNextDialog(); + + if (web_contents_) { + web_contents_->OnJavaScriptMessageBoxClosed( + reply_msg_, true, message_box_view_->GetInputText()); + } + return true; +} + +////////////////////////////////////////////////////////////////////////////// +// JavascriptMessageBoxHandler, views::AppModalDialogDelegate +// implementation: + +void JavascriptMessageBoxHandler::ShowModalDialog() { + // If the WebContents that created this dialog navigated away before this + // dialog became visible, simply show the next dialog if any. + if (!web_contents_) { + AppModalDialogQueue::ShowNextDialog(); + delete this; + return; + } + + web_contents_->Activate(); + HWND root_hwnd = GetAncestor(web_contents_->GetContainerHWND(), GA_ROOT); + dialog_ = views::Window::CreateChromeWindow(root_hwnd, gfx::Rect(), this); + dialog_->Show(); +} + +void JavascriptMessageBoxHandler::ActivateModalDialog() { + // Ensure that the dialog is visible and at the top of the z-order. These + // conditions may not be true if the dialog was opened on a different virtual + // desktop to the one the browser window is on. + dialog_->Show(); + dialog_->Activate(); +} + +/////////////////////////////////////////////////////////////////////////////// +// JavascriptMessageBoxHandler, views::WindowDelegate implementation: + +views::View* JavascriptMessageBoxHandler::GetContentsView() { + return message_box_view_; +} + +views::View* JavascriptMessageBoxHandler::GetInitiallyFocusedView() const { + if (message_box_view_->text_box()) + return message_box_view_->text_box(); + return views::AppModalDialogDelegate::GetInitiallyFocusedView(); +} + +/////////////////////////////////////////////////////////////////////////////// +// JavascriptMessageBoxHandler, private: + +void JavascriptMessageBoxHandler::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + bool web_contents_gone = false; + if (!web_contents_) + return; + + if (type == NOTIFY_NAV_ENTRY_COMMITTED && + Source<NavigationController>(source).ptr() == web_contents_->controller()) + web_contents_gone = true; + + if (type == NOTIFY_TAB_CONTENTS_DESTROYED && + Source<TabContents>(source).ptr() == + static_cast<TabContents*>(web_contents_)) + web_contents_gone = true; + + if (web_contents_gone) { + web_contents_ = NULL; + + // If the dialog is visible close it. + if (dialog_) + dialog_->Close(); + } +} + |