Add support for checkbox with dialog.showMessageBox
This adds the `checkboxLabel` and `checkboxChecked` options to display a checkbox in the message box. Fixes #6048.
This commit is contained in:
parent
9163b601a4
commit
c8c11e68c6
10 changed files with 155 additions and 61 deletions
|
@ -47,6 +47,8 @@ void ShowMessageBox(int type,
|
|||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const std::string& checkbox_label,
|
||||
bool checkbox_checked,
|
||||
const gfx::ImageSkia& icon,
|
||||
atom::NativeWindow* window,
|
||||
mate::Arguments* args) {
|
||||
|
@ -56,8 +58,8 @@ void ShowMessageBox(int type,
|
|||
peek,
|
||||
&callback)) {
|
||||
atom::ShowMessageBox(window, (atom::MessageBoxType)type, buttons,
|
||||
default_id, cancel_id, options, title,
|
||||
message, detail, icon, callback);
|
||||
default_id, cancel_id, options, title, message, detail,
|
||||
checkbox_label, checkbox_checked, icon, callback);
|
||||
} else {
|
||||
int chosen = atom::ShowMessageBox(window, (atom::MessageBoxType)type,
|
||||
buttons, default_id, cancel_id,
|
||||
|
|
|
@ -38,14 +38,9 @@ void AtomJavaScriptDialogManager::RunJavaScriptDialog(
|
|||
}
|
||||
|
||||
atom::ShowMessageBox(NativeWindow::FromWebContents(web_contents),
|
||||
atom::MessageBoxType::MESSAGE_BOX_TYPE_NONE,
|
||||
buttons,
|
||||
-1,
|
||||
0,
|
||||
atom::MessageBoxOptions::MESSAGE_BOX_NONE,
|
||||
"",
|
||||
base::UTF16ToUTF8(message_text),
|
||||
"",
|
||||
atom::MessageBoxType::MESSAGE_BOX_TYPE_NONE, buttons, -1,
|
||||
0, atom::MessageBoxOptions::MESSAGE_BOX_NONE, "",
|
||||
base::UTF16ToUTF8(message_text), "", "", false,
|
||||
gfx::ImageSkia(),
|
||||
base::Bind(&OnMessageBoxCallback, callback));
|
||||
}
|
||||
|
@ -66,7 +61,9 @@ void AtomJavaScriptDialogManager::CancelDialogs(
|
|||
|
||||
// static
|
||||
void AtomJavaScriptDialogManager::OnMessageBoxCallback(
|
||||
const DialogClosedCallback& callback, int code) {
|
||||
const DialogClosedCallback& callback,
|
||||
int code,
|
||||
bool checkbox_checked) {
|
||||
callback.Run(code == 0, base::string16());
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,8 @@ class AtomJavaScriptDialogManager : public content::JavaScriptDialogManager {
|
|||
|
||||
private:
|
||||
static void OnMessageBoxCallback(const DialogClosedCallback& callback,
|
||||
int code);
|
||||
int code,
|
||||
bool checkbox_checked);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
|
|
@ -32,7 +32,8 @@ enum MessageBoxOptions {
|
|||
MESSAGE_BOX_NO_LINK = 1 << 0,
|
||||
};
|
||||
|
||||
typedef base::Callback<void(int code)> MessageBoxCallback;
|
||||
typedef base::Callback<void(int code, bool checkbox_checked)>
|
||||
MessageBoxCallback;
|
||||
|
||||
int ShowMessageBox(NativeWindow* parent_window,
|
||||
MessageBoxType type,
|
||||
|
@ -54,6 +55,8 @@ void ShowMessageBox(NativeWindow* parent_window,
|
|||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const std::string& checkbox_label,
|
||||
bool checkbox_checked,
|
||||
const gfx::ImageSkia& icon,
|
||||
const MessageBoxCallback& callback);
|
||||
|
||||
|
|
|
@ -36,8 +36,11 @@ class GtkMessageBox : public NativeWindowObserver {
|
|||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const std::string& checkbox_label,
|
||||
bool checkbox_checked,
|
||||
const gfx::ImageSkia& icon)
|
||||
: cancel_id_(cancel_id),
|
||||
checkbox_checked_(false),
|
||||
parent_(static_cast<NativeWindowViews*>(parent_window)) {
|
||||
// Create dialog.
|
||||
dialog_ = gtk_message_dialog_new(
|
||||
|
@ -68,6 +71,18 @@ class GtkMessageBox : public NativeWindowObserver {
|
|||
g_object_unref(pixbuf);
|
||||
}
|
||||
|
||||
if (!checkbox_label.empty()) {
|
||||
GtkWidget* message_area =
|
||||
gtk_message_dialog_get_message_area(GTK_MESSAGE_DIALOG(dialog_));
|
||||
GtkWidget* check_button =
|
||||
gtk_check_button_new_with_label(checkbox_label.c_str());
|
||||
g_signal_connect(check_button, "toggled",
|
||||
G_CALLBACK(OnCheckboxToggledThunk), this);
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_button),
|
||||
checkbox_checked);
|
||||
gtk_container_add(GTK_CONTAINER(message_area), check_button);
|
||||
}
|
||||
|
||||
// Add buttons.
|
||||
for (size_t i = 0; i < buttons.size(); ++i) {
|
||||
GtkWidget* button = gtk_dialog_add_button(
|
||||
|
@ -154,6 +169,7 @@ class GtkMessageBox : public NativeWindowObserver {
|
|||
}
|
||||
|
||||
CHROMEGTK_CALLBACK_1(GtkMessageBox, void, OnResponseDialog, int);
|
||||
CHROMEGTK_CALLBACK_1(GtkMessageBox, void, OnCheckboxToggled, gpointer);
|
||||
|
||||
private:
|
||||
atom::UnresponsiveSuppressor unresponsive_suppressor_;
|
||||
|
@ -161,6 +177,8 @@ class GtkMessageBox : public NativeWindowObserver {
|
|||
// The id to return when the dialog is closed without pressing buttons.
|
||||
int cancel_id_;
|
||||
|
||||
bool checkbox_checked_;
|
||||
|
||||
NativeWindowViews* parent_;
|
||||
GtkWidget* dialog_;
|
||||
MessageBoxCallback callback_;
|
||||
|
@ -172,12 +190,16 @@ void GtkMessageBox::OnResponseDialog(GtkWidget* widget, int response) {
|
|||
gtk_widget_hide(dialog_);
|
||||
|
||||
if (response < 0)
|
||||
callback_.Run(cancel_id_);
|
||||
callback_.Run(cancel_id_, checkbox_checked_);
|
||||
else
|
||||
callback_.Run(response);
|
||||
callback_.Run(response, checkbox_checked_);
|
||||
delete this;
|
||||
}
|
||||
|
||||
void GtkMessageBox::OnCheckboxToggled(GtkWidget* widget, gpointer data) {
|
||||
checkbox_checked_ = GTK_TOGGLE_BUTTON(widget)->active;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int ShowMessageBox(NativeWindow* parent,
|
||||
|
@ -190,8 +212,9 @@ int ShowMessageBox(NativeWindow* parent,
|
|||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const gfx::ImageSkia& icon) {
|
||||
return GtkMessageBox(parent, type, buttons, default_id, cancel_id,
|
||||
title, message, detail, icon).RunSynchronous();
|
||||
return GtkMessageBox(parent, type, buttons, default_id, cancel_id, title,
|
||||
message, detail, "", false, icon)
|
||||
.RunSynchronous();
|
||||
}
|
||||
|
||||
void ShowMessageBox(NativeWindow* parent,
|
||||
|
@ -203,18 +226,22 @@ void ShowMessageBox(NativeWindow* parent,
|
|||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const std::string& checkbox_label,
|
||||
bool checkbox_checked,
|
||||
const gfx::ImageSkia& icon,
|
||||
const MessageBoxCallback& callback) {
|
||||
(new GtkMessageBox(parent, type, buttons, default_id, cancel_id,
|
||||
title, message, detail, icon))->RunAsynchronous(callback);
|
||||
(new GtkMessageBox(parent, type, buttons, default_id, cancel_id, title,
|
||||
message, detail, checkbox_label, checkbox_checked, icon))
|
||||
->RunAsynchronous(callback);
|
||||
}
|
||||
|
||||
void ShowErrorBox(const base::string16& title, const base::string16& content) {
|
||||
if (Browser::Get()->is_ready()) {
|
||||
GtkMessageBox(nullptr, MESSAGE_BOX_TYPE_ERROR, { "OK" }, -1, 0, "Error",
|
||||
GtkMessageBox(nullptr, MESSAGE_BOX_TYPE_ERROR, {"OK"}, -1, 0, "Error",
|
||||
base::UTF16ToUTF8(title).c_str(),
|
||||
base::UTF16ToUTF8(content).c_str(),
|
||||
gfx::ImageSkia()).RunSynchronous();
|
||||
base::UTF16ToUTF8(content).c_str(), "", false,
|
||||
gfx::ImageSkia())
|
||||
.RunSynchronous();
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
ANSI_TEXT_BOLD ANSI_BACKGROUND_GRAY
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
- (void)alertDidEnd:(NSAlert*)alert
|
||||
returnCode:(NSInteger)returnCode
|
||||
contextInfo:(void*)contextInfo {
|
||||
callback_.Run(returnCode);
|
||||
callback_.Run(returnCode, alert.suppressionButton.state == NSOnState);
|
||||
[alert_ release];
|
||||
[self release];
|
||||
|
||||
|
@ -60,6 +60,8 @@ NSAlert* CreateNSAlert(NativeWindow* parent_window,
|
|||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const std::string& checkbox_label,
|
||||
bool checkbox_checked,
|
||||
const gfx::ImageSkia& icon) {
|
||||
// Ignore the title; it's the window title on other platforms and ignorable.
|
||||
NSAlert* alert = [[NSAlert alloc] init];
|
||||
|
@ -95,6 +97,12 @@ NSAlert* CreateNSAlert(NativeWindow* parent_window,
|
|||
[[ns_buttons objectAtIndex:default_id] setKeyEquivalent:@"\r"];
|
||||
}
|
||||
|
||||
if (!checkbox_label.empty()) {
|
||||
alert.showsSuppressionButton = YES;
|
||||
alert.suppressionButton.title = base::SysUTF8ToNSString(checkbox_label);
|
||||
alert.suppressionButton.state = checkbox_checked ? NSOnState : NSOffState;
|
||||
}
|
||||
|
||||
if (!icon.isNull()) {
|
||||
NSImage* image = skia::SkBitmapToNSImageWithColorSpace(
|
||||
*icon.bitmap(), base::mac::GetGenericRGBColorSpace());
|
||||
|
@ -104,7 +112,7 @@ NSAlert* CreateNSAlert(NativeWindow* parent_window,
|
|||
return alert;
|
||||
}
|
||||
|
||||
void SetReturnCode(int* ret_code, int result) {
|
||||
void SetReturnCode(int* ret_code, int result, bool checkbox_checked) {
|
||||
*ret_code = result;
|
||||
}
|
||||
|
||||
|
@ -120,9 +128,8 @@ int ShowMessageBox(NativeWindow* parent_window,
|
|||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const gfx::ImageSkia& icon) {
|
||||
NSAlert* alert = CreateNSAlert(
|
||||
parent_window, type, buttons, default_id, title, message,
|
||||
detail, icon);
|
||||
NSAlert* alert = CreateNSAlert(parent_window, type, buttons, default_id,
|
||||
title, message, detail, "", false, icon);
|
||||
|
||||
// Use runModal for synchronous alert without parent, since we don't have a
|
||||
// window to wait for.
|
||||
|
@ -154,11 +161,13 @@ void ShowMessageBox(NativeWindow* parent_window,
|
|||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const std::string& checkbox_label,
|
||||
bool checkbox_checked,
|
||||
const gfx::ImageSkia& icon,
|
||||
const MessageBoxCallback& callback) {
|
||||
NSAlert* alert = CreateNSAlert(
|
||||
parent_window, type, buttons, default_id, title, message,
|
||||
detail, icon);
|
||||
NSAlert* alert =
|
||||
CreateNSAlert(parent_window, type, buttons, default_id, title, message,
|
||||
detail, checkbox_label, checkbox_checked, icon);
|
||||
ModalDelegate* delegate = [[ModalDelegate alloc] initWithCallback:callback
|
||||
andAlert:alert
|
||||
callEndModal:false];
|
||||
|
|
|
@ -72,7 +72,7 @@ void MapToCommonID(const std::vector<base::string16>& buttons,
|
|||
}
|
||||
}
|
||||
|
||||
int ShowMessageBoxUTF16(HWND parent,
|
||||
int ShowTaskDialogUTF16(NativeWindow* parent,
|
||||
MessageBoxType type,
|
||||
const std::vector<base::string16>& buttons,
|
||||
int default_id,
|
||||
|
@ -81,6 +81,8 @@ int ShowMessageBoxUTF16(HWND parent,
|
|||
const base::string16& title,
|
||||
const base::string16& message,
|
||||
const base::string16& detail,
|
||||
const base::string16& checkbox_label,
|
||||
bool* checkbox_checked,
|
||||
const gfx::ImageSkia& icon) {
|
||||
TASKDIALOG_FLAGS flags =
|
||||
TDF_SIZE_TO_CONTENT | // Show all content.
|
||||
|
@ -88,10 +90,14 @@ int ShowMessageBoxUTF16(HWND parent,
|
|||
|
||||
TASKDIALOGCONFIG config = { 0 };
|
||||
config.cbSize = sizeof(config);
|
||||
config.hwndParent = parent;
|
||||
config.hInstance = GetModuleHandle(NULL);
|
||||
config.dwFlags = flags;
|
||||
|
||||
if (parent) {
|
||||
config.hwndParent =
|
||||
static_cast<atom::NativeWindowViews*>(parent)->GetAcceleratedWidget();
|
||||
}
|
||||
|
||||
if (default_id > 0)
|
||||
config.nDefaultButton = kIDStart + default_id;
|
||||
|
||||
|
@ -132,6 +138,14 @@ int ShowMessageBoxUTF16(HWND parent,
|
|||
config.pszContent = detail.c_str();
|
||||
}
|
||||
|
||||
if (!checkbox_label.empty()) {
|
||||
config.pszVerificationText = checkbox_label.c_str();
|
||||
|
||||
if (checkbox_checked && *checkbox_checked) {
|
||||
config.dwFlags |= TDF_VERIFICATION_FLAG_CHECKED;
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate through the buttons, put common buttons in dwCommonButtons
|
||||
// and custom buttons in pButtons.
|
||||
std::map<int, int> id_map;
|
||||
|
@ -151,7 +165,12 @@ int ShowMessageBoxUTF16(HWND parent,
|
|||
}
|
||||
|
||||
int id = 0;
|
||||
TaskDialogIndirect(&config, &id, NULL, NULL);
|
||||
BOOL verificationFlagChecked = FALSE;
|
||||
TaskDialogIndirect(&config, &id, nullptr, &verificationFlagChecked);
|
||||
if (checkbox_checked) {
|
||||
*checkbox_checked = verificationFlagChecked;
|
||||
}
|
||||
|
||||
if (id_map.find(id) != id_map.end()) // common button.
|
||||
return id_map[id];
|
||||
else if (id >= kIDStart) // custom button.
|
||||
|
@ -160,6 +179,29 @@ int ShowMessageBoxUTF16(HWND parent,
|
|||
return cancel_id;
|
||||
}
|
||||
|
||||
int ShowTaskDialogUTF8(NativeWindow* parent,
|
||||
MessageBoxType type,
|
||||
const std::vector<std::string>& buttons,
|
||||
int default_id,
|
||||
int cancel_id,
|
||||
int options,
|
||||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const std::string& checkbox_label,
|
||||
bool* checkbox_checked,
|
||||
const gfx::ImageSkia& icon) {
|
||||
std::vector<base::string16> utf16_buttons;
|
||||
for (const auto& button : buttons)
|
||||
utf16_buttons.push_back(base::UTF8ToUTF16(button));
|
||||
|
||||
return ShowTaskDialogUTF16(
|
||||
parent, type, utf16_buttons, default_id, cancel_id, options,
|
||||
base::UTF8ToUTF16(title), base::UTF8ToUTF16(message),
|
||||
base::UTF8ToUTF16(detail), base::UTF8ToUTF16(checkbox_label),
|
||||
checkbox_checked, icon);
|
||||
}
|
||||
|
||||
void RunMessageBoxInNewThread(base::Thread* thread,
|
||||
NativeWindow* parent,
|
||||
MessageBoxType type,
|
||||
|
@ -170,12 +212,16 @@ void RunMessageBoxInNewThread(base::Thread* thread,
|
|||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const std::string& checkbox_label,
|
||||
bool checkbox_checked,
|
||||
const gfx::ImageSkia& icon,
|
||||
const MessageBoxCallback& callback) {
|
||||
int result = ShowMessageBox(parent, type, buttons, default_id,
|
||||
cancel_id, options, title, message, detail, icon);
|
||||
int result = ShowTaskDialogUTF8(parent, type, buttons, default_id, cancel_id,
|
||||
options, title, message, detail,
|
||||
checkbox_label, &checkbox_checked, icon);
|
||||
content::BrowserThread::PostTask(
|
||||
content::BrowserThread::UI, FROM_HERE, base::Bind(callback, result));
|
||||
content::BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(callback, result, checkbox_checked));
|
||||
content::BrowserThread::DeleteSoon(
|
||||
content::BrowserThread::UI, FROM_HERE, thread);
|
||||
}
|
||||
|
@ -192,25 +238,9 @@ int ShowMessageBox(NativeWindow* parent,
|
|||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const gfx::ImageSkia& icon) {
|
||||
std::vector<base::string16> utf16_buttons;
|
||||
for (const auto& button : buttons)
|
||||
utf16_buttons.push_back(base::UTF8ToUTF16(button));
|
||||
|
||||
HWND hwnd_parent = parent ?
|
||||
static_cast<atom::NativeWindowViews*>(parent)->GetAcceleratedWidget() :
|
||||
NULL;
|
||||
|
||||
atom::UnresponsiveSuppressor suppressor;
|
||||
return ShowMessageBoxUTF16(hwnd_parent,
|
||||
type,
|
||||
utf16_buttons,
|
||||
default_id,
|
||||
cancel_id,
|
||||
options,
|
||||
base::UTF8ToUTF16(title),
|
||||
base::UTF8ToUTF16(message),
|
||||
base::UTF8ToUTF16(detail),
|
||||
icon);
|
||||
return ShowTaskDialogUTF8(parent, type, buttons, default_id, cancel_id,
|
||||
options, title, message, detail, "", nullptr, icon);
|
||||
}
|
||||
|
||||
void ShowMessageBox(NativeWindow* parent,
|
||||
|
@ -222,13 +252,15 @@ void ShowMessageBox(NativeWindow* parent,
|
|||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const std::string& checkbox_label,
|
||||
bool checkbox_checked,
|
||||
const gfx::ImageSkia& icon,
|
||||
const MessageBoxCallback& callback) {
|
||||
std::unique_ptr<base::Thread> thread(
|
||||
new base::Thread(ATOM_PRODUCT_NAME "MessageBoxThread"));
|
||||
thread->init_com_with_mta(false);
|
||||
if (!thread->Start()) {
|
||||
callback.Run(cancel_id);
|
||||
callback.Run(cancel_id, checkbox_checked);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -237,13 +269,14 @@ void ShowMessageBox(NativeWindow* parent,
|
|||
FROM_HERE,
|
||||
base::Bind(&RunMessageBoxInNewThread, base::Unretained(unretained),
|
||||
parent, type, buttons, default_id, cancel_id, options, title,
|
||||
message, detail, icon, callback));
|
||||
message, detail, checkbox_label, checkbox_checked, icon,
|
||||
callback));
|
||||
}
|
||||
|
||||
void ShowErrorBox(const base::string16& title, const base::string16& content) {
|
||||
atom::UnresponsiveSuppressor suppressor;
|
||||
ShowMessageBoxUTF16(NULL, MESSAGE_BOX_TYPE_ERROR, {}, -1, 0, 0, L"Error",
|
||||
title, content, gfx::ImageSkia());
|
||||
ShowTaskDialogUTF16(nullptr, MESSAGE_BOX_TYPE_ERROR, {}, -1, 0, 0, L"Error",
|
||||
title, content, L"", nullptr, gfx::ImageSkia());
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
|
|
@ -122,6 +122,11 @@ will be passed via `callback(filename)`
|
|||
* `title` String (optional) - Title of the message box, some platforms will not show it.
|
||||
* `message` String - Content of the message box.
|
||||
* `detail` String (optional) - Extra information of the message.
|
||||
* `checkboxLabel` String (optional) - If provided, the message box will
|
||||
include a checkbox with the given label. The checkbox state can be
|
||||
inspected only when using `callback`.
|
||||
* `checkboxChecked` Boolean (optional) - Initial checked state of the
|
||||
checkbox. `false` by default.
|
||||
* `icon` [NativeImage](native-image.md) (optional)
|
||||
* `cancelId` Integer (optional) - The value will be returned when user cancels the dialog
|
||||
instead of clicking the buttons of the dialog. By default it is the index
|
||||
|
@ -135,6 +140,8 @@ will be passed via `callback(filename)`
|
|||
set `noLink` to `true`.
|
||||
* `callback` Function (optional)
|
||||
* `response` Number - The index of the button that was clicked
|
||||
* `checkboxChecked` Boolean - The checked state of the checkbox if
|
||||
`checkboxLabel` was set. Otherwise `false`.
|
||||
|
||||
Returns `Integer`, the index of the clicked button, if a callback is provided
|
||||
it returns undefined.
|
||||
|
|
|
@ -178,7 +178,10 @@ module.exports = {
|
|||
}
|
||||
}
|
||||
|
||||
let {buttons, cancelId, defaultId, detail, icon, message, title, type} = options
|
||||
let {
|
||||
buttons, cancelId, checkboxLabel, checkboxChecked, defaultId, detail,
|
||||
icon, message, title, type
|
||||
} = options
|
||||
|
||||
if (type == null) {
|
||||
type = 'none'
|
||||
|
@ -217,6 +220,14 @@ module.exports = {
|
|||
throw new TypeError('Detail must be a string')
|
||||
}
|
||||
|
||||
checkboxChecked = !!checkboxChecked
|
||||
|
||||
if (checkboxLabel == null) {
|
||||
checkboxLabel = ''
|
||||
} else if (typeof checkboxLabel !== 'string') {
|
||||
throw new TypeError('checkboxLabel must be a string')
|
||||
}
|
||||
|
||||
if (icon == null) {
|
||||
icon = null
|
||||
}
|
||||
|
@ -239,8 +250,8 @@ module.exports = {
|
|||
|
||||
const flags = options.noLink ? messageBoxOptions.noLink : 0
|
||||
return binding.showMessageBox(messageBoxType, buttons, defaultId, cancelId,
|
||||
flags, title, message, detail, icon, window,
|
||||
callback)
|
||||
flags, title, message, detail, checkboxLabel,
|
||||
checkboxChecked, icon, window, callback)
|
||||
},
|
||||
|
||||
showErrorBox: function (...args) {
|
||||
|
|
|
@ -59,6 +59,10 @@ describe('dialog module', () => {
|
|||
assert.throws(() => {
|
||||
dialog.showMessageBox({detail: 3.14})
|
||||
}, /Detail must be a string/)
|
||||
|
||||
assert.throws(() => {
|
||||
dialog.showMessageBox({checkboxLabel: false})
|
||||
}, /checkboxLabel must be a string/)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
Loading…
Reference in a new issue