1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
|
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/views/javascript_tab_modal_dialog_view_views.h"
#include "base/functional/callback.h"
#include "chrome/browser/ui/javascript_dialogs/javascript_tab_modal_dialog_manager_delegate_desktop.h"
#include "chrome/browser/ui/views/title_origin_label.h"
#include "components/constrained_window/constrained_window_views.h"
#include "content/public/browser/javascript_dialog_manager.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/base/mojom/dialog_button.mojom.h"
#include "ui/base/mojom/ui_base_types.mojom-shared.h"
#include "ui/strings/grit/ui_strings.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/bubble/bubble_frame_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/message_box_view.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/layout/fill_layout.h"
JavaScriptTabModalDialogViewViews::~JavaScriptTabModalDialogViewViews() =
default;
void JavaScriptTabModalDialogViewViews::CloseDialogWithoutCallback() {
scoped_tab_modal_ui_.reset();
dialog_callback_.Reset();
dialog_force_closed_callback_.Reset();
GetWidget()->Close();
}
std::u16string JavaScriptTabModalDialogViewViews::GetUserInput() {
return std::u16string(message_box_view_->GetInputText());
}
std::u16string JavaScriptTabModalDialogViewViews::GetWindowTitle() const {
return title_;
}
bool JavaScriptTabModalDialogViewViews::ShouldShowCloseButton() const {
return false;
}
views::View* JavaScriptTabModalDialogViewViews::GetInitiallyFocusedView() {
auto* text_box = message_box_view_->GetVisiblePromptField();
return text_box ? text_box : views::DialogDelegate::GetInitiallyFocusedView();
}
void JavaScriptTabModalDialogViewViews::AddedToWidget() {
auto* bubble_frame_view = static_cast<views::BubbleFrameView*>(
GetWidget()->non_client_view()->frame_view());
bubble_frame_view->SetTitleView(CreateTitleOriginLabel(GetWindowTitle()));
if (!message_text_.empty()) {
GetWidget()->GetRootView()->GetViewAccessibility().SetDescription(
message_text_);
}
// On some platforms, the platform accessibility API automatically
// calculates the name of the native window based on the child RootView.
// We override that calculation here so that we can present both the
// title (e.g. "url.com says") and the message text on platforms where
// the accessible description is ignored.
GetViewAccessibility().OverrideNativeWindowTitle(l10n_util::GetStringFUTF16(
IDS_CONCAT_TWO_STRINGS_WITH_COMMA, GetWindowTitle(), message_text_));
}
JavaScriptTabModalDialogViewViews::JavaScriptTabModalDialogViewViews(
content::WebContents* parent_web_contents,
content::WebContents* alerting_web_contents,
const std::u16string& title,
content::JavaScriptDialogType dialog_type,
const std::u16string& message_text,
const std::u16string& default_prompt_text,
content::JavaScriptDialogManager::DialogClosedCallback dialog_callback,
base::OnceClosure dialog_force_closed_callback)
: title_(title),
message_text_(message_text),
default_prompt_text_(default_prompt_text),
dialog_callback_(std::move(dialog_callback)),
dialog_force_closed_callback_(std::move(dialog_force_closed_callback)) {
tabs::TabInterface* tab =
tabs::TabInterface::GetFromContents(parent_web_contents);
CHECK(tab && tab->CanShowModalUI());
scoped_tab_modal_ui_ = tab->ShowModalUI();
SetModalType(ui::mojom::ModalType::kChild);
SetDefaultButton(static_cast<int>(ui::mojom::DialogButton::kOk));
const bool is_alert = dialog_type == content::JAVASCRIPT_DIALOG_TYPE_ALERT;
SetButtons(
// Alerts only have an OK button, no Cancel, because there is no choice
// being made.
is_alert ? static_cast<int>(ui::mojom::DialogButton::kOk)
: static_cast<int>(ui::mojom::DialogButton::kOk) |
static_cast<int>(ui::mojom::DialogButton::kCancel));
SetAcceptCallback(base::BindOnce(
[](JavaScriptTabModalDialogViewViews* dialog) {
// Remove the force-close callback to indicate that we were closed as a
// result of user action.
dialog->dialog_force_closed_callback_ = base::OnceClosure();
if (dialog->dialog_callback_) {
std::move(dialog->dialog_callback_)
.Run(true,
std::u16string(dialog->message_box_view_->GetInputText()));
}
},
base::Unretained(this)));
SetCancelCallback(base::BindOnce(
[](JavaScriptTabModalDialogViewViews* dialog) {
// Remove the force-close callback to indicate that we were closed as a
// result of user action.
dialog->dialog_force_closed_callback_ = base::OnceClosure();
if (dialog->dialog_callback_) {
std::move(dialog->dialog_callback_).Run(false, std::u16string());
}
},
base::Unretained(this)));
RegisterWindowWillCloseCallback(
RegisterWillCloseCallbackPassKey(),
base::BindOnce(
[](JavaScriptTabModalDialogViewViews* dialog) {
// Since the window is closing, reset the ScopedTabModalUI so it
// removes its reference to the TabModel prior to the TabModel being
// destroyed.
dialog->scoped_tab_modal_ui_.reset();
// If the force-close callback still exists at this point we're not
// closed due to a user action (would've been caught in
// Accept/Cancel).
if (dialog->dialog_force_closed_callback_) {
std::move(dialog->dialog_force_closed_callback_).Run();
}
},
base::Unretained(this)));
message_box_view_ = new views::MessageBoxView(
message_text, /* detect_directionality = */ true);
if (dialog_type == content::JAVASCRIPT_DIALOG_TYPE_PROMPT) {
message_box_view_->SetPromptField(default_prompt_text);
}
SetLayoutManager(std::make_unique<views::FillLayout>());
AddChildViewRaw(message_box_view_.get());
constrained_window::ShowWebModalDialogViews(this, parent_web_contents);
}
// static
JavaScriptTabModalDialogViewViews*
JavaScriptTabModalDialogViewViews::CreateAlertDialogForTesting(
Browser* browser,
std::u16string title,
std::u16string message) {
return new JavaScriptTabModalDialogViewViews(
browser->tab_strip_model()->GetActiveWebContents(),
browser->tab_strip_model()->GetActiveWebContents(), title,
content::JAVASCRIPT_DIALOG_TYPE_ALERT, message, std::u16string(),
base::NullCallback(), base::NullCallback());
}
BEGIN_METADATA(JavaScriptTabModalDialogViewViews)
END_METADATA
// Creates a new JS dialog. Note the two callbacks; |dialog_callback| is for
// user responses, while |dialog_force_closed_callback| is for when Views
// forces the dialog closed without a user reply.
base::WeakPtr<javascript_dialogs::TabModalDialogView>
JavaScriptTabModalDialogManagerDelegateDesktop::CreateNewDialog(
content::WebContents* alerting_web_contents,
const std::u16string& title,
content::JavaScriptDialogType dialog_type,
const std::u16string& message_text,
const std::u16string& default_prompt_text,
content::JavaScriptDialogManager::DialogClosedCallback dialog_callback,
base::OnceClosure dialog_force_closed_callback) {
return (new JavaScriptTabModalDialogViewViews(
web_contents_, alerting_web_contents, title, dialog_type,
message_text, default_prompt_text, std::move(dialog_callback),
std::move(dialog_force_closed_callback)))
->weak_factory_.GetWeakPtr();
}
|