From dbffb2a614ce732b05471623ac3ddb19532bf6d8 Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Sat, 8 Feb 2020 19:15:38 -0800 Subject: [PATCH] js: Convert _.extend to spread syntax or Object.assign. This is not always a behavior-preserving translation: _.extend mutates its first argument. However, the code does not always appear to have been written to expect that. Signed-off-by: Anders Kaseorg --- frontend_tests/node_tests/stream_list.js | 5 +++-- frontend_tests/zjsunit/namespace.js | 2 +- static/js/admin.js | 2 +- static/js/blueslip.js | 2 +- static/js/bot_data.js | 4 ++-- static/js/channel.js | 10 +++++----- static/js/compose_actions.js | 13 ++++++------- static/js/emoji_picker.js | 7 ++++--- static/js/message_list.js | 14 ++++++-------- static/js/message_list_view.js | 5 +++-- static/js/server_events.js | 2 +- static/js/settings_org.js | 13 ++++++++----- static/js/stream_color.js | 8 +++++--- static/js/util.js | 2 +- 14 files changed, 47 insertions(+), 42 deletions(-) diff --git a/frontend_tests/node_tests/stream_list.js b/frontend_tests/node_tests/stream_list.js index bfb96c92cf..edb24f8092 100644 --- a/frontend_tests/node_tests/stream_list.js +++ b/frontend_tests/node_tests/stream_list.js @@ -714,9 +714,10 @@ run_test('refresh_pin', () => { stream_data.add_sub(sub); - const pinned_sub = _.extend(sub, { + const pinned_sub = { + ...sub, pin_to_top: true, - }); + }; const li_stub = $.create('li stub'); li_stub.length = 0; diff --git a/frontend_tests/zjsunit/namespace.js b/frontend_tests/zjsunit/namespace.js index 37dc59b0c2..d3915106a4 100644 --- a/frontend_tests/zjsunit/namespace.js +++ b/frontend_tests/zjsunit/namespace.js @@ -31,7 +31,7 @@ exports.restore = function () { requires.forEach(function (fn) { delete require.cache[require.resolve(fn)]; }); - _.extend(global, old_globals); + Object.assign(global, old_globals); old_globals = {}; for (const name of new_globals) { delete global[name]; diff --git a/static/js/admin.js b/static/js/admin.js index da6365cd28..3e1d0dfc95 100644 --- a/static/js/admin.js +++ b/static/js/admin.js @@ -84,7 +84,7 @@ exports.build_page = function () { options.msg_delete_limit_dropdown_values = settings_config.msg_delete_limit_dropdown_values; options.bot_creation_policy_values = settings_bots.bot_creation_policy_values; options.email_address_visibility_values = settings_config.email_address_visibility_values; - _.extend(options, settings_org.get_organization_settings_options()); + Object.assign(options, settings_org.get_organization_settings_options()); if (options.realm_logo_source !== 'D' && options.realm_night_logo_source === 'D') { // If no night mode logo is specified but a day mode one is, diff --git a/static/js/blueslip.js b/static/js/blueslip.js index 3d2fd513d4..03bfa2364d 100644 --- a/static/js/blueslip.js +++ b/static/js/blueslip.js @@ -80,7 +80,7 @@ const reported_errors = new Set(); const last_report_attempt = new Map(); function report_error(msg, stack, opts) { - opts = _.extend({show_ui_msg: false}, opts); + opts = { show_ui_msg: false, ...opts }; if (stack === undefined) { stack = 'No stacktrace available'; diff --git a/static/js/bot_data.js b/static/js/bot_data.js index 9a4a915cd7..fc3ac0ba59 100644 --- a/static/js/bot_data.js +++ b/static/js/bot_data.js @@ -45,13 +45,13 @@ exports.del = function bot_data__del(bot_id) { exports.update = function bot_data__update(bot_id, bot_update) { const bot = bots.get(bot_id); - _.extend(bot, _.pick(bot_update, bot_fields)); + Object.assign(bot, _.pick(bot_update, bot_fields)); set_can_admin(bot); // We currently only support one service per bot. const service = services.get(bot_id)[0]; if (typeof bot_update.services !== 'undefined' && bot_update.services.length > 0) { - _.extend(service, _.pick(bot_update.services[0], services_fields)); + Object.assign(service, _.pick(bot_update.services[0], services_fields)); } send_change_event(); }; diff --git a/static/js/channel.js b/static/js/channel.js index b66cfaefd1..cfb99e5a72 100644 --- a/static/js/channel.js +++ b/static/js/channel.js @@ -83,23 +83,23 @@ function call(args, idempotent) { } exports.get = function (options) { - const args = _.extend({type: "GET", dataType: "json"}, options); + const args = { type: "GET", dataType: "json", ...options }; return call(args, options.idempotent); }; exports.post = function (options) { - const args = _.extend({type: "POST", dataType: "json"}, options); + const args = { type: "POST", dataType: "json", ...options }; return call(args, options.idempotent); }; exports.put = function (options) { - const args = _.extend({type: "PUT", dataType: "json"}, options); + const args = { type: "PUT", dataType: "json", ...options }; return call(args, options.idempotent); }; // Not called exports.delete because delete is a reserved word in JS exports.del = function (options) { - const args = _.extend({type: "DELETE", dataType: "json"}, options); + const args = { type: "DELETE", dataType: "json", ...options }; return call(args, options.idempotent); }; @@ -111,7 +111,7 @@ exports.patch = function (options) { // method this way options.data.append("method", "PATCH"); } else { - options.data = _.extend({}, options.data, {method: 'PATCH'}); + options.data = { ...options.data, method: 'PATCH' }; } return exports.post(options, options.idempotent); }; diff --git a/static/js/compose_actions.js b/static/js/compose_actions.js index c7942cb82c..6144bea3bf 100644 --- a/static/js/compose_actions.js +++ b/static/js/compose_actions.js @@ -169,19 +169,18 @@ exports.maybe_scroll_up_selected_message = function () { }; function fill_in_opts_from_current_narrowed_view(msg_type, opts) { - let default_opts = { + return { message_type: msg_type, stream: '', topic: '', private_message_recipient: '', trigger: 'unknown', - }; - // Set default parameters based on the current narrowed view. - const compose_opts = narrow_state.set_compose_defaults(); - default_opts = _.extend(default_opts, compose_opts); - opts = _.extend(default_opts, opts); - return opts; + // Set default parameters based on the current narrowed view. + ...narrow_state.set_compose_defaults(), + + ...opts, + }; } function same_recipient_as_before(msg_type, opts) { diff --git a/static/js/emoji_picker.js b/static/js/emoji_picker.js index 42bea26392..71941f48c9 100644 --- a/static/js/emoji_picker.js +++ b/static/js/emoji_picker.js @@ -213,7 +213,7 @@ function filter_emojis() { for (const alias of emoji_dict.aliases) { const match = search_terms.every(search_term => alias.includes(search_term)); if (match) { - search_results.push(_.extend({}, emoji_dict, {name: alias})); + search_results.push({ ...emoji_dict, name: alias }); break; // We only need the first matching alias per emoji. } } @@ -313,9 +313,10 @@ function update_emoji_showcase($focused_emoji) { const canonical_name = emoji.get_canonical_name(focused_emoji_name); const focused_emoji_dict = emoji.emojis_by_name.get(canonical_name); - const emoji_dict = _.extend({}, focused_emoji_dict, { + const emoji_dict = { + ...focused_emoji_dict, name: focused_emoji_name.replace(/_/g, ' '), - }); + }; const rendered_showcase = render_emoji_showcase({ emoji_dict: emoji_dict, }); diff --git a/static/js/message_list.js b/static/js/message_list.js index a8b0aaf4da..a898d1ec73 100644 --- a/static/js/message_list.js +++ b/static/js/message_list.js @@ -19,9 +19,7 @@ exports.MessageList = function (opts) { }); } - _.extend(opts, { - collapse_messages: true, - }); + opts.collapse_messages = true; const collapse_messages = opts.collapse_messages; const table_name = opts.table_name; @@ -125,7 +123,7 @@ exports.MessageList.prototype = { }, clear: function MessageList_clear(opts) { - opts = _.extend({clear_selected_id: true}, opts); + opts = { clear_selected_id: true, ...opts }; this.data.clear(); this.view.clear_rendering_state(true); @@ -140,18 +138,18 @@ exports.MessageList.prototype = { }, select_id: function MessageList_select_id(id, opts) { - opts = _.extend({ + opts = { then_scroll: false, target_scroll_offset: undefined, use_closest: false, empty_ok: false, mark_read: true, force_rerender: false, - }, opts, { + ...opts, id: id, msg_list: this, previously_selected: this.data.selected_id(), - }); + }; function convert_id(str_id) { const id = parseFloat(str_id); @@ -293,7 +291,7 @@ exports.MessageList.prototype = { }, append_to_view: function (messages, opts) { - opts = _.extend({messages_are_new: false}, opts); + opts = { messages_are_new: false, ...opts }; this.num_appends += 1; const render_info = this.view.append(messages, opts.messages_are_new); diff --git a/static/js/message_list_view.js b/static/js/message_list_view.js index 336884d48b..fb50d18c01 100644 --- a/static/js/message_list_view.js +++ b/static/js/message_list_view.js @@ -640,9 +640,10 @@ MessageListView.prototype = { _get_message_template: function (message_container) { const msg_reactions = reactions.get_message_reactions(message_container.msg); message_container.msg.message_reactions = msg_reactions; - const msg_to_render = _.extend(message_container, { + const msg_to_render = { + ...message_container, table_name: this.table_name, - }); + }; return render_single_message(msg_to_render); }, diff --git a/static/js/server_events.js b/static/js/server_events.js index b141a8a821..47756a2d8f 100644 --- a/static/js/server_events.js +++ b/static/js/server_events.js @@ -166,7 +166,7 @@ function hide_ui_connection_error() { } function get_events(options) { - options = _.extend({dont_block: false}, options); + options = { dont_block: false, ...options }; if (reload_state.is_in_progress()) { return; diff --git a/static/js/settings_org.js b/static/js/settings_org.js index 28dcc48d23..0b660a9b9c 100644 --- a/static/js/settings_org.js +++ b/static/js/settings_org.js @@ -38,9 +38,10 @@ exports.maybe_disable_widgets = function () { }; exports.get_sorted_options_list = function (option_values_object) { - const options_list = Object.keys(option_values_object).map((key) => { - return _.extend(option_values_object[key], {key: key}); - }); + const options_list = Object.keys(option_values_object).map(key => ({ + ...option_values_object[key], + key: key, + })); let comparator = (x, y) => x.order - y.order; if (!options_list[0].order) { comparator = (x, y) => { @@ -810,8 +811,10 @@ exports.build_page = function () { const subsection = subsection_id.split('-').join('_'); const subsection_elem = save_button.closest('.org-subsection-parent'); - let data = populate_data_for_request(subsection_elem); - data = _.extend(data, get_complete_data_for_subsection(subsection)); + const data = { + ...populate_data_for_request(subsection_elem), + ...get_complete_data_for_subsection(subsection), + }; exports.save_organization_settings(data, save_button); }); diff --git a/static/js/stream_color.js b/static/js/stream_color.js index 33d272d021..89a0fb43b6 100644 --- a/static/js/stream_color.js +++ b/static/js/stream_color.js @@ -51,9 +51,11 @@ const subscriptions_table_colorpicker_options = { }; exports.set_colorpicker_color = function (colorpicker, color) { - colorpicker.spectrum(_.extend(subscriptions_table_colorpicker_options, - {color: color, - container: "#subscription_overlay .subscription_settings.show"})); + colorpicker.spectrum({ + ...subscriptions_table_colorpicker_options, + color: color, + container: "#subscription_overlay .subscription_settings.show", + }); }; exports.update_stream_color = function (sub, color, opts) { diff --git a/static/js/util.js b/static/js/util.js index 560abd8003..986a9833fd 100644 --- a/static/js/util.js +++ b/static/js/util.js @@ -175,7 +175,7 @@ exports.array_compare = function util_array_compare(a, b) { const unassigned_value_sentinel = {}; exports.CachedValue = function (opts) { this._value = unassigned_value_sentinel; - _.extend(this, opts); + Object.assign(this, opts); }; exports.CachedValue.prototype = {