js: Simplify code using default parameters and destructuring.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg
2021-03-24 13:44:43 -07:00
committed by Tim Abbott
parent 4703256c91
commit 7656d44abc
25 changed files with 116 additions and 261 deletions

View File

@@ -1150,10 +1150,7 @@ test("begins_typeahead", (override) => {
assert.deepEqual(values, reference);
}
function assert_stream_list(input, rest) {
if (rest === undefined) {
rest = "";
}
function assert_stream_list(input, rest = "") {
const values = get_values(input, rest);
assert.deepEqual(sorted_names_from(values), ["Denmark", "Sweden", "The Netherlands"]);
}

View File

@@ -38,19 +38,9 @@ people.add_active_user(steve);
people.initialize_current_user(me.user_id);
function assert_same_operators(result, terms) {
terms = terms.map((term) => {
// If negated flag is undefined, we explicitly
// set it to false.
let negated = term.negated;
if (!negated) {
negated = false;
}
return {
negated,
operator: term.operator,
operand: term.operand,
};
});
terms = terms.map(({negated = false, operator, operand}) => ({negated, operator, operand}));
assert.deepEqual(result, terms);
}

View File

@@ -57,13 +57,7 @@ run_test("msg_edited_vars", () => {
// * message that includes sender
// * message without sender
function build_message_context(message, message_context) {
if (message_context === undefined) {
message_context = {};
}
if (message === undefined) {
message = {};
}
function build_message_context(message = {}, message_context = {}) {
message_context = {
include_sender: true,
...message_context,
@@ -130,13 +124,7 @@ run_test("merge_message_groups", () => {
// MessageListView has lots of DOM code, so we are going to test the message
// group mearging logic on its own.
function build_message_context(message, message_context) {
if (message_context === undefined) {
message_context = {};
}
if (message === undefined) {
message = {};
}
function build_message_context(message = {}, message_context = {}) {
message_context = {
include_sender: true,
...message_context,

View File

@@ -413,10 +413,7 @@ test_ui("with_external_user", (override) => {
// Test the 'off' handlers on the pill-container
const turned_off = {};
pill_container_stub.off = (event_name, sel) => {
if (sel === undefined) {
sel = "whole";
}
pill_container_stub.off = (event_name, sel = "whole") => {
turned_off[event_name + "/" + sel] = true;
};

View File

@@ -672,7 +672,7 @@ run_test("uppy_events", (override) => {
override(upload, "show_error_message", (config, message) => {
show_error_message_called = true;
assert.equal(config.mode, "compose");
assert.equal(message, null);
assert.equal(message, undefined);
});
uppy_cancel_all_called = false;
on_upload_error_callback(file, null, null);

View File

@@ -13,10 +13,7 @@ import * as ui_report from "./ui_report";
let attachments;
let upload_space_used;
export function bytes_to_size(bytes, kb_with_1024_bytes) {
if (kb_with_1024_bytes === undefined) {
kb_with_1024_bytes = false;
}
export function bytes_to_size(bytes, kb_with_1024_bytes = false) {
const kb_size = kb_with_1024_bytes ? 1024 : 1000;
const sizes = ["B", "KB", "MB", "GB", "TB"];
if (bytes === 0) {

View File

@@ -75,13 +75,11 @@ export function get_log() {
const reported_errors = new Set();
const last_report_attempt = new Map();
function report_error(msg, stack, opts) {
opts = {show_ui_msg: false, ...opts};
if (stack === undefined) {
stack = "No stacktrace available";
}
function report_error(
msg,
stack = "No stacktrace available",
{show_ui_msg = false, more_info} = {},
) {
if (page_params.debug_mode) {
// In development, we display blueslip errors in the web UI,
// to make them hard to miss.
@@ -114,8 +112,8 @@ function report_error(msg, stack, opts) {
data: {
message: msg,
stacktrace: stack,
ui_message: opts.show_ui_msg,
more_info: JSON.stringify(opts.more_info),
ui_message: show_ui_msg,
more_info: JSON.stringify(more_info),
href: window.location.href,
user_agent: window.navigator.userAgent,
log: logger.get_log().join("\n"),
@@ -123,7 +121,7 @@ function report_error(msg, stack, opts) {
timeout: 3 * 1000,
success() {
reported_errors.add(key);
if (opts.show_ui_msg && ui_report !== undefined) {
if (show_ui_msg && ui_report !== undefined) {
// There are a few races here (and below in the error
// callback):
// 1) The ui_report module or something it requires might
@@ -153,7 +151,7 @@ function report_error(msg, stack, opts) {
}
},
error() {
if (opts.show_ui_msg && ui_report !== undefined) {
if (show_ui_msg && ui_report !== undefined) {
ui_report.client_error(
"Oops. It seems something has gone wrong. Please try reloading the page.",
$("#home-error"),
@@ -234,10 +232,7 @@ export function warn(msg, more_info) {
}
}
export function error(msg, more_info, stack) {
if (stack === undefined) {
stack = new Error("dummy").stack;
}
export function error(msg, more_info, stack = new Error("dummy").stack) {
const args = build_arg_list(msg, more_info);
logger.error(...args);
report_error(msg, stack, {more_info});

View File

@@ -334,11 +334,7 @@ export function send_message_success(local_id, message_id, locally_echoed) {
echo.reify_message_id(local_id, message_id);
}
export function send_message(request) {
if (request === undefined) {
request = create_message_object();
}
export function send_message(request = create_message_object()) {
if (request.type === "private") {
request.to = JSON.stringify(request.to);
} else {

View File

@@ -55,26 +55,18 @@ export function smart_insert(textarea, syntax) {
autosize.update(textarea);
}
export function insert_syntax_and_focus(syntax, textarea) {
export function insert_syntax_and_focus(syntax, textarea = $("#compose-textarea")) {
// Generic helper for inserting syntax into the main compose box
// where the cursor was and focusing the area. Mostly a thin
// wrapper around smart_insert.
if (textarea === undefined) {
textarea = $("#compose-textarea");
}
smart_insert(textarea, syntax);
}
export function replace_syntax(old_syntax, new_syntax, textarea) {
export function replace_syntax(old_syntax, new_syntax, textarea = $("#compose-textarea")) {
// Replaces `old_syntax` with `new_syntax` text in the compose box. Due to
// the way that JavaScript handles string replacements, if `old_syntax` is
// a string it will only replace the first instance. If `old_syntax` is
// a RegExp with a global flag, it will replace all instances.
if (textarea === undefined) {
textarea = $("#compose-textarea");
}
textarea.val(
textarea.val().replace(
old_syntax,

View File

@@ -5,49 +5,47 @@ import render_dropdown_list from "../templates/settings/dropdown_list.hbs";
import * as blueslip from "./blueslip";
import * as ListWidget from "./list_widget";
export const DropdownListWidget = function (opts) {
const init = () => {
// Run basic sanity checks on opts, and set up sane defaults.
opts = {
null_value: null,
render_text: (item_name) => item_name,
on_update: () => {},
...opts,
};
opts.container_id = `${opts.widget_name}_widget`;
opts.value_id = `id_${opts.widget_name}`;
if (opts.value === undefined) {
opts.value = opts.null_value;
export const DropdownListWidget = function ({
widget_name,
data,
default_text,
render_text = (item_name) => item_name,
null_value = null,
value,
on_update = () => {},
}) {
const container_id = `${widget_name}_widget`;
const value_id = `id_${widget_name}`;
if (value === undefined) {
value = null_value;
blueslip.warn("dropdown-list-widget: Called without a default value; using null value");
}
};
init();
const render_default_text = (elem) => {
elem.text(opts.default_text);
elem.text(default_text);
elem.addClass("text-warning");
elem.closest(".input-group").find(".dropdown_list_reset_button:enabled").hide();
};
const render = (value) => {
$(`#${CSS.escape(opts.container_id)} #${CSS.escape(opts.value_id)}`).data("value", value);
$(`#${CSS.escape(container_id)} #${CSS.escape(value_id)}`).data("value", value);
const elem = $(`#${CSS.escape(opts.container_id)} #${CSS.escape(opts.widget_name)}_name`);
const elem = $(`#${CSS.escape(container_id)} #${CSS.escape(widget_name)}_name`);
if (!value || value === opts.null_value) {
if (!value || value === null_value) {
render_default_text(elem);
return;
}
// Happy path
const item = opts.data.find((x) => x.value === value.toString());
const item = data.find((x) => x.value === value.toString());
if (item === undefined) {
render_default_text(elem);
return;
}
const text = opts.render_text(item.name);
const text = render_text(item.name);
elem.text(text);
elem.removeClass("text-warning");
elem.closest(".input-group").find(".dropdown_list_reset_button:enabled").show();
@@ -55,15 +53,15 @@ export const DropdownListWidget = function (opts) {
const update = (value) => {
render(value);
opts.on_update(value);
on_update(value);
};
const register_event_handlers = () => {
$(`#${CSS.escape(opts.container_id)} .dropdown-list-body`).on(
$(`#${CSS.escape(container_id)} .dropdown-list-body`).on(
"click keypress",
".list_item",
function (e) {
const setting_elem = $(this).closest(`.${CSS.escape(opts.widget_name)}_setting`);
const setting_elem = $(this).closest(`.${CSS.escape(widget_name)}_setting`);
if (e.type === "keypress") {
if (e.which === 13) {
setting_elem.find(".dropdown-menu").dropdown("toggle");
@@ -75,8 +73,8 @@ export const DropdownListWidget = function (opts) {
update(value);
},
);
$(`#${CSS.escape(opts.container_id)} .dropdown_list_reset_button`).on("click", (e) => {
update(opts.null_value);
$(`#${CSS.escape(container_id)} .dropdown_list_reset_button`).on("click", (e) => {
update(null_value);
e.preventDefault();
});
};
@@ -84,15 +82,13 @@ export const DropdownListWidget = function (opts) {
const setup = () => {
// populate the dropdown
const dropdown_list_body = $(
`#${CSS.escape(opts.container_id)} .dropdown-list-body`,
`#${CSS.escape(container_id)} .dropdown-list-body`,
).expectOne();
const search_input = $(
`#${CSS.escape(opts.container_id)} .dropdown-search > input[type=text]`,
);
const dropdown_toggle = $(`#${CSS.escape(opts.container_id)} .dropdown-toggle`);
const search_input = $(`#${CSS.escape(container_id)} .dropdown-search > input[type=text]`);
const dropdown_toggle = $(`#${CSS.escape(container_id)} .dropdown-toggle`);
ListWidget.create(dropdown_list_body, opts.data, {
name: `${CSS.escape(opts.widget_name)}_list`,
ListWidget.create(dropdown_list_body, data, {
name: `${CSS.escape(widget_name)}_list`,
modifier(item) {
return render_dropdown_list({item});
},
@@ -102,9 +98,9 @@ export const DropdownListWidget = function (opts) {
return item.name.toLowerCase().includes(value);
},
},
simplebar_container: $(`#${CSS.escape(opts.container_id)} .dropdown-list-wrapper`),
simplebar_container: $(`#${CSS.escape(container_id)} .dropdown-list-wrapper`),
});
$(`#${CSS.escape(opts.container_id)} .dropdown-search`).on("click", (e) => {
$(`#${CSS.escape(container_id)} .dropdown-search`).on("click", (e) => {
e.stopPropagation();
});
@@ -131,14 +127,12 @@ export const DropdownListWidget = function (opts) {
dropdown_toggle.trigger(custom_event);
});
render(opts.value);
render(value);
register_event_handlers();
};
const value = () => {
let val = $(`#${CSS.escape(opts.container_id)} #${CSS.escape(opts.value_id)}`).data(
"value",
);
const get_value = () => {
let val = $(`#${CSS.escape(container_id)} #${CSS.escape(value_id)}`).data("value");
if (val === null) {
val = "";
}
@@ -150,7 +144,7 @@ export const DropdownListWidget = function (opts) {
return {
render,
value,
value: get_value,
update,
};
};

View File

@@ -202,17 +202,9 @@ export class Filter {
return operator;
}
static canonicalize_term(opts) {
let negated = opts.negated;
let operator = opts.operator;
let operand = opts.operand;
// Make negated be explicitly false for both clarity and
static canonicalize_term({negated = false, operator, operand}) {
// Make negated explicitly default to false for both clarity and
// simplifying deepEqual checks in the tests.
if (!negated) {
negated = false;
}
operator = Filter.canonicalize_operator(operator);
switch (operator) {

View File

@@ -127,13 +127,11 @@ export class MessageList {
return this.data.can_mark_messages_read();
}
clear(opts) {
opts = {clear_selected_id: true, ...opts};
clear({clear_selected_id = true} = {}) {
this.data.clear();
this.view.clear_rendering_state(true);
if (opts.clear_selected_id) {
if (clear_selected_id) {
this.data.clear_selected_id();
}
}
@@ -294,11 +292,9 @@ export class MessageList {
this.append_to_view(viewable_messages, opts);
}
append_to_view(messages, opts) {
opts = {messages_are_new: false, ...opts};
append_to_view(messages, {messages_are_new = false} = {}) {
this.num_appends += 1;
const render_info = this.view.append(messages, opts.messages_are_new);
const render_info = this.view.append(messages, messages_are_new);
return render_info;
}

View File

@@ -8,8 +8,8 @@ import * as unread from "./unread";
import * as util from "./util";
export class MessageListData {
constructor(opts) {
this.excludes_muted_topics = opts.excludes_muted_topics;
constructor({excludes_muted_topics, filter = new Filter()}) {
this.excludes_muted_topics = excludes_muted_topics;
if (this.excludes_muted_topics) {
this._all_items = [];
}
@@ -18,11 +18,6 @@ export class MessageListData {
this._local_only = new Set();
this._selected_id = -1;
let filter = opts.filter;
if (filter === undefined) {
filter = new Filter();
}
this.filter = filter;
this.fetch_status = new FetchStatus();
}

View File

@@ -179,18 +179,13 @@ export class PollData {
}
}
export function activate(opts) {
const elem = opts.elem;
const callback = opts.callback;
let question = "";
let options = [];
if (opts.extra_data) {
question = opts.extra_data.question || "";
options = opts.extra_data.options || [];
}
const is_my_poll = people.is_my_user_id(opts.message.sender_id);
export function activate({
elem,
callback,
extra_data: {question = "", options = []} = {},
message,
}) {
const is_my_poll = people.is_my_user_id(message.sender_id);
const poll_data = new PollData(is_my_poll, question, options);
function update_edit_controls() {

View File

@@ -29,9 +29,6 @@ function preserve_state(send_after_reload, save_pointer, save_narrow, save_compo
return;
}
if (send_after_reload === undefined) {
send_after_reload = 0;
}
let url = "#reload:send_after_reload=" + Number(send_after_reload);
url += "+csrf_token=" + encodeURIComponent(csrf_token);
@@ -199,10 +196,6 @@ function do_reload_app(send_after_reload, save_pointer, save_narrow, save_compos
}
}
if (message === undefined) {
message = "Reloading ...";
}
// TODO: We need a better API for showing messages.
ui_report.message(message, $("#reloading-application"));
blueslip.log("Starting server requested page reload");
@@ -232,32 +225,16 @@ function do_reload_app(send_after_reload, save_pointer, save_narrow, save_compos
window.location.reload(true);
}
export function initiate(options) {
options = {
immediate: false,
save_pointer: true,
save_narrow: true,
save_compose: true,
send_after_reload: false,
...options,
};
if (
options.save_pointer === undefined ||
options.save_narrow === undefined ||
options.save_compose === undefined
) {
blueslip.error("reload.initiate() called without explicit save options.");
}
if (options.immediate) {
do_reload_app(
options.send_after_reload,
options.save_pointer,
options.save_narrow,
options.save_compose,
options.message,
);
export function initiate({
immediate = false,
save_pointer = true,
save_narrow = true,
save_compose = true,
send_after_reload = false,
message = "Reloading ...",
}) {
if (immediate) {
do_reload_app(send_after_reload, save_pointer, save_narrow, save_compose, message);
}
if (reload_state.is_pending()) {
@@ -294,13 +271,7 @@ export function initiate(options) {
let compose_started_handler;
function reload_from_idle() {
do_reload_app(
false,
options.save_pointer,
options.save_narrow,
options.save_compose,
options.message,
);
do_reload_app(false, save_pointer, save_narrow, save_compose, message);
}
// Make sure we always do a reload eventually after

View File

@@ -42,11 +42,7 @@ function patch_request_for_scheduling(request, message_content, deliver_at, deli
return new_request;
}
export function schedule_message(request) {
if (request === undefined) {
request = compose.create_message_object();
}
export function schedule_message(request = compose.create_message_object()) {
const raw_message = request.content.split("\n");
const command_line = raw_message[0];
const message = raw_message.slice(1).join("\n");

View File

@@ -168,9 +168,7 @@ function hide_ui_connection_error() {
$("#connection-error").removeClass("get-events-error");
}
function get_events(options) {
options = {dont_block: false, ...options};
function get_events({dont_block = false} = {}) {
if (reload_state.is_in_progress()) {
return;
}
@@ -182,7 +180,7 @@ function get_events(options) {
return;
}
get_events_params.dont_block = options.dont_block || get_events_failures > 0;
get_events_params.dont_block = dont_block || get_events_failures > 0;
if (get_events_params.dont_block) {
// If we're requesting an immediate re-connect to the server,

View File

@@ -19,28 +19,25 @@ export const strings = {
// Generic function for informing users about changes to the settings
// UI. Intended to replace the old system that was built around
// direct calls to `ui_report`.
export function do_settings_change(request_method, url, data, status_element, opts) {
export function do_settings_change(
request_method,
url,
data,
status_element,
{
success_msg = strings.success,
success_continuation,
error_continuation,
sticky = false,
error_msg_element,
} = {},
) {
const spinner = $(status_element).expectOne();
spinner.fadeTo(0, 1);
loading.make_indicator(spinner, {text: strings.saving});
let success_msg;
let success_continuation;
let error_continuation;
let remove_after = 1000;
const remove_after = sticky ? null : 1000;
const appear_after = 500;
if (opts !== undefined) {
success_msg = opts.success_msg;
success_continuation = opts.success_continuation;
error_continuation = opts.error_continuation;
if (opts.sticky) {
remove_after = null;
}
}
if (success_msg === undefined) {
success_msg = strings.success;
}
request_method({
url,
data,
@@ -50,17 +47,13 @@ export function do_settings_change(request_method, url, data, status_element, op
display_checkmark(spinner);
}, appear_after);
if (success_continuation !== undefined) {
if (opts !== undefined && opts.success_continuation_arg) {
success_continuation(opts.success_continuation_arg);
} else {
success_continuation(reponse_data);
}
}
},
error(xhr) {
if (opts !== undefined && opts.error_msg_element) {
if (error_msg_element) {
loading.destroy_indicator(spinner);
ui_report.error(strings.failure, xhr, opts.error_msg_element);
ui_report.error(strings.failure, xhr, error_msg_element);
} else {
ui_report.error(strings.failure, xhr, spinner);
}

View File

@@ -70,8 +70,7 @@ export function set_colorpicker_color(colorpicker, color) {
});
}
export function update_stream_color(sub, color, opts) {
opts = {update_historical: false, ...opts};
export function update_stream_color(sub, color, {update_historical = false} = {}) {
sub.color = color;
const stream_id = sub.stream_id;
// The swatch in the subscription row header.
@@ -94,7 +93,7 @@ export function update_stream_color(sub, color, opts) {
)}'] .large-icon`,
).css("color", color);
if (opts.update_historical) {
if (update_historical) {
update_historical_message_color(sub.name, color);
}
update_stream_sidebar_swatch_color(stream_id, color);

View File

@@ -94,17 +94,14 @@ export class PerStreamHistory {
}
}
add_or_update(opts) {
const topic_name = opts.topic_name;
let message_id = opts.message_id || 0;
add_or_update({topic_name, message_id = 0}) {
message_id = Number.parseInt(message_id, 10);
this.update_stream_max_message_id(message_id);
const existing = this.topics.get(topic_name);
if (!existing) {
this.topics.set(opts.topic_name, {
this.topics.set(topic_name, {
message_id,
pretty_name: topic_name,
historical: false,

View File

@@ -441,13 +441,9 @@ export function render_left_panel_superset() {
}
// LeftPanelParams { input: String, subscribed_only: Boolean, sort_order: String }
export function redraw_left_panel(left_panel_params) {
export function redraw_left_panel(left_panel_params = get_left_panel_params()) {
// We only get left_panel_params passed in from tests. Real
// code calls get_left_panel_params().
if (left_panel_params === undefined) {
left_panel_params = get_left_panel_params();
}
show_active_stream_in_left_panel();
function stream_id_for_row(row) {

View File

@@ -273,17 +273,9 @@ export function sort_recipients(
query,
current_stream,
current_topic,
groups,
max_num_items,
groups = [],
max_num_items = 20,
) {
if (!groups) {
groups = [];
}
if (max_num_items === undefined) {
max_num_items = 20;
}
function sort_relevance(items) {
return sort_people_for_relevance(items, current_stream, current_topic);
}

View File

@@ -9,11 +9,7 @@ import * as common from "./common";
cls- class that we want to add/remove to/from the status_box
*/
export function message(response, status_box, cls, remove_after) {
if (cls === undefined) {
cls = "alert";
}
export function message(response, status_box, cls = "alert", remove_after = false) {
// Note we use html() below, since we can rely on our callers escaping HTML
// via i18n.t when interpolating data.
status_box

View File

@@ -99,10 +99,7 @@ export function hide_upload_status(config) {
get_item("send_status", config).removeClass("alert-info").hide();
}
export function show_error_message(config, message) {
if (!message) {
message = i18n.t("An unknown error occurred.");
}
export function show_error_message(config, message = i18n.t("An unknown error occurred.")) {
get_item("send_button", config).prop("disabled", false);
get_item("send_status", config).addClass("alert-error").removeClass("alert-info").show();
get_item("send_status_message", config).text(message);
@@ -304,7 +301,7 @@ export function setup_upload(config) {
});
uppy.on("upload-error", (file, error, response) => {
const message = response ? response.body.msg : null;
const message = response ? response.body.msg : undefined;
uppy.cancelAll();
show_error_message(config, message);
compose_ui.replace_syntax(get_translated_status(file), "", get_item("textarea", config));

View File

@@ -108,7 +108,7 @@ export function get_emoji_matcher(query) {
};
}
export function triage(query, objs, get_item) {
export function triage(query, objs, get_item = (x) => x) {
/*
We split objs into four groups:
@@ -121,10 +121,6 @@ export function triage(query, objs, get_item) {
`matches` and then call the rest `rest`.
*/
if (!get_item) {
get_item = (x) => x;
}
const exactMatch = [];
const beginswithCaseSensitive = [];
const beginswithCaseInsensitive = [];