diff --git a/addons/hr_holidays/static/tests/leave_stats_tests.js b/addons/hr_holidays/static/tests/leave_stats_tests.js index a49918be2e4..b1684184674 100644 --- a/addons/hr_holidays/static/tests/leave_stats_tests.js +++ b/addons/hr_holidays/static/tests/leave_stats_tests.js @@ -154,10 +154,10 @@ QUnit.test("leave stats reload when employee/department changes", async (assert) `, mockRPC(route, args) { if (args.model === "hr.leave" && args.method === "search_read") { - assert.ok(_.some(args.kwargs.domain, _.matcher(["department_id", "=", 11]))); + assert.ok(args.kwargs.domain.some(_.matcher(["department_id", "=", 11]))); } if (args.model === "hr.leave" && args.method === "read_group") { - assert.ok(_.some(args.kwargs.domain, _.matcher(["employee_id", "=", 200]))); + assert.ok(args.kwargs.domain.some(_.matcher(["employee_id", "=", 200]))); } }, }); diff --git a/addons/im_livechat/static/src/legacy/public_models/livechat_button_view.js b/addons/im_livechat/static/src/legacy/public_models/livechat_button_view.js index 18d844e0a44..7ea79b5a56e 100644 --- a/addons/im_livechat/static/src/legacy/public_models/livechat_button_view.js +++ b/addons/im_livechat/static/src/legacy/public_models/livechat_button_view.js @@ -22,11 +22,8 @@ Model({ * @param {Object} [options={}] */ addMessage(data, options) { - const hasAlreadyMessage = _.some( - this.messaging.publicLivechatGlobal.messages, - function (msg) { - return data.id === msg.id; - } + const hasAlreadyMessage = this.messaging.publicLivechatGlobal.messages.some( + (msg) => data.id === msg.id ); if (hasAlreadyMessage) { return; diff --git a/addons/mass_mailing/static/src/js/snippets.editor.js b/addons/mass_mailing/static/src/js/snippets.editor.js index 13ed75c22fe..6b0001bc143 100644 --- a/addons/mass_mailing/static/src/js/snippets.editor.js +++ b/addons/mass_mailing/static/src/js/snippets.editor.js @@ -4,16 +4,16 @@ import {_lt} from "web.core"; import snippetsEditor from "web_editor.snippet.editor"; const MassMailingSnippetsMenu = snippetsEditor.SnippetsMenu.extend({ - events: _.extend({}, snippetsEditor.SnippetsMenu.prototype.events, { + events: Object.assign({}, snippetsEditor.SnippetsMenu.prototype.events, { 'click .o_we_customize_design_btn': '_onDesignTabClick', }), - custom_events: _.extend({}, snippetsEditor.SnippetsMenu.prototype.custom_events, { + custom_events: Object.assign({}, snippetsEditor.SnippetsMenu.prototype.custom_events, { drop_zone_over: '_onDropZoneOver', drop_zone_out: '_onDropZoneOut', drop_zone_start: '_onDropZoneStart', drop_zone_stop: '_onDropZoneStop', }), - tabs: _.extend({}, snippetsEditor.SnippetsMenu.prototype.tabs, { + tabs: Object.assign({}, snippetsEditor.SnippetsMenu.prototype.tabs, { DESIGN: 'design', }), optionsTabStructure: [ diff --git a/addons/point_of_sale/static/src/js/db.js b/addons/point_of_sale/static/src/js/db.js index 849f2229755..43b069bf974 100644 --- a/addons/point_of_sale/static/src/js/db.js +++ b/addons/point_of_sale/static/src/js/db.js @@ -231,7 +231,7 @@ export const PosDB = core.Class.extend({ add_packagings: function (product_packagings) { var self = this; _.map(product_packagings, function (product_packaging) { - if (_.find(self.product_by_id, { id: product_packaging.product_id[0] })) { + if (self.product_by_id.find(({ id }) => id === product_packaging.product_id[0])) { self.product_packaging_by_barcode[product_packaging.barcode] = product_packaging; } }); diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index ad37eca3349..fafb60f846b 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -1679,7 +1679,7 @@ export class Product extends PosModel { let price_extra = 0.0; let draftPackLotLines, weight, description, packLotLinesToEdit; - if (_.some(this.attribute_line_ids, (id) => id in this.pos.attributes_by_ptal_id)) { + if (this.attribute_line_ids.some((id) => id in this.pos.attributes_by_ptal_id)) { const attributes = _.map( this.attribute_line_ids, (id) => this.pos.attributes_by_ptal_id[id] @@ -1769,8 +1769,9 @@ export class Product extends PosModel { return { draftPackLotLines, quantity: weight, description, price_extra }; } isPricelistItemUsable(item, date) { + const categories = this.parent_category_ids.concat(this.categ.id); return ( - (!item.categ_id || _.contains(this.parent_category_ids.concat(this.categ.id), item.categ_id[0])) && + (!item.categ_id || categories.includes(item.categ_id[0])) && (!item.date_start || moment.utc(item.date_start).isSameOrBefore(date)) && (!item.date_end || moment.utc(item.date_end).isSameOrAfter(date)) ); @@ -1824,13 +1825,13 @@ export class Product extends PosModel { if (price_extra) { price += price_extra; } - _.find(pricelist_items, function (rule) { + pricelist_items.find(function (rule) { if (rule.min_quantity && quantity < rule.min_quantity) { return false; } if (rule.base === "pricelist") { - const base_pricelist = _.find(self.pos.pricelists, function (pricelist) { + const base_pricelist = self.pos.pricelists.find(function (pricelist) { return pricelist.id === rule.base_pricelist_id[0]; }); if (base_pricelist) { @@ -1949,10 +1950,7 @@ export class Orderline extends PosModel { var pack_lot_lines = json.pack_lot_ids; for (var i = 0; i < pack_lot_lines.length; i++) { var packlotline = pack_lot_lines[i][2]; - var pack_lot_line = new Packlotline( - {}, - { json: _.extend({ ...packlotline }, { order_line: this }) } - ); + var pack_lot_line = new Packlotline({}, { json: { ...packlotline, order_line: this } }); this.pack_lot_lines.add(pack_lot_line); } this.tax_ids = json.tax_ids && json.tax_ids.length !== 0 ? json.tax_ids[0][2] : undefined; @@ -2335,8 +2333,8 @@ export class Orderline extends PosModel { tax: this.get_tax(), product_description: this.get_product().description, product_description_sale: this.get_product().description_sale, - pack_lot_lines: this.get_lot_lines(), - customer_note: this.get_customer_note(), + pack_lot_lines: this.get_lot_lines(), + customer_note: this.get_customer_note(), taxed_lst_unit_price: this.get_taxed_lst_unit_price(), }; } @@ -2425,26 +2423,27 @@ export class Orderline extends PosModel { return this.get_base_price(); } } - get_taxed_lst_unit_price(){ + get_taxed_lst_unit_price() { var lst_price = this.compute_fixed_price(this.get_lst_price()); - if (this.pos.config.iface_tax_included === 'total') { - var product = this.get_product(); + if (this.pos.config.iface_tax_included === "total") { + var product = this.get_product(); var taxes_ids = product.taxes_id; var product_taxes = this.pos.get_taxes_after_fp(taxes_ids); - return this.compute_all(product_taxes, lst_price, 1, this.pos.currency.rounding).total_included; + return this.compute_all(product_taxes, lst_price, 1, this.pos.currency.rounding) + .total_included; } return lst_price; } - get_price_without_tax(){ + get_price_without_tax() { return this.get_all_prices().priceWithoutTax; } - get_price_with_tax(){ + get_price_with_tax() { return this.get_all_prices().priceWithTax; } - get_price_with_tax_before_discount () { + get_price_with_tax_before_discount() { return this.get_all_prices().priceWithTaxBeforeDiscount; } - get_tax(){ + get_tax() { return this.get_all_prices().tax; } get_applicable_taxes() { @@ -2598,8 +2597,8 @@ export class Orderline extends PosModel { get_fixed_lst_price() { return this.compute_fixed_price(this.get_lst_price()); } - get_lst_price(){ - return this.product.get_price(this.pos.default_pricelist, 1, 0) + get_lst_price() { + return this.product.get_price(this.pos.default_pricelist, 1, 0); } set_lst_price(price) { this.order.assert_editable(); @@ -2842,7 +2841,7 @@ export class Order extends PosModel { this.uid = this.generate_unique_id(); this.name = _.str.sprintf(_t("Order %s"), this.uid); this.validation_date = undefined; - this.fiscal_position = _.find(this.pos.fiscal_positions, function (fp) { + this.fiscal_position = this.pos.fiscal_positions.find(function (fp) { return fp.id === self.pos.config.default_fiscal_position_id[0]; }); } @@ -2884,7 +2883,7 @@ export class Order extends PosModel { this.firstDraft = false; if (json.fiscal_position_id) { - var fiscal_position = _.find(this.pos.fiscal_positions, function (fp) { + var fiscal_position = this.pos.fiscal_positions.find(function (fp) { return fp.id === json.fiscal_position_id; }); @@ -2896,7 +2895,7 @@ export class Order extends PosModel { } if (json.pricelist_id) { - this.pricelist = _.find(this.pos.pricelists, function (pricelist) { + this.pricelist = this.pos.pricelists.find(function (pricelist) { return pricelist.id === json.pricelist_id; }); } else { @@ -3325,7 +3324,7 @@ export class Order extends PosModel { this.select_orderline(this.get_last_orderline()); } - isFirstDraft(){ + isFirstDraft() { return this.firstDraft; } diff --git a/addons/portal/static/src/js/portal_chatter.js b/addons/portal/static/src/js/portal_chatter.js index 9501afb1b20..26ae58bf524 100644 --- a/addons/portal/static/src/js/portal_chatter.js +++ b/addons/portal/static/src/js/portal_chatter.js @@ -181,7 +181,7 @@ var PortalChatter = publicWidget.Widget.extend({ params: this._messageFetchPrepareParams() }).then(function (result) { self.result = result; - self.options = _.extend(self.options, self.result['options'] || {}); + self.options = Object.assign(self.options, self.result['options'] || {}); return result; }); }, diff --git a/addons/portal/static/src/js/portal_composer.js b/addons/portal/static/src/js/portal_composer.js index 25536cd34ff..8908193cc4f 100644 --- a/addons/portal/static/src/js/portal_composer.js +++ b/addons/portal/static/src/js/portal_composer.js @@ -78,7 +78,7 @@ var PortalComposer = publicWidget.Widget.extend({ _onAttachmentDeleteClick: function (ev) { var self = this; var attachmentId = $(ev.currentTarget).closest('.o_portal_chatter_attachment').data('id'); - var accessToken = _.find(this.attachments, {'id': attachmentId}).access_token; + var accessToken = this.attachments.find(attachment => attachment.id === attachmentId).access_token; ev.preventDefault(); ev.stopPropagation(); diff --git a/addons/portal/static/src/js/portal_signature.js b/addons/portal/static/src/js/portal_signature.js index 533c2ac6784..695e98d72a7 100644 --- a/addons/portal/static/src/js/portal_signature.js +++ b/addons/portal/static/src/js/portal_signature.js @@ -111,7 +111,7 @@ var SignatureForm = publicWidget.Widget.extend({ return this._rpc({ route: this.callUrl, - params: _.extend(this.rpcParams, { + params: Object.assign(this.rpcParams, { 'name': name, 'signature': signature, }), diff --git a/addons/portal_rating/static/src/js/portal_chatter.js b/addons/portal_rating/static/src/js/portal_chatter.js index 984397f7b4d..56ba6dc8975 100644 --- a/addons/portal_rating/static/src/js/portal_chatter.js +++ b/addons/portal_rating/static/src/js/portal_chatter.js @@ -15,7 +15,7 @@ var qweb = core.qweb; * Extends Frontend Chatter to handle rating */ PortalChatter.include({ - events: _.extend({}, PortalChatter.prototype.events, { + events: Object.assign({}, PortalChatter.prototype.events, { // star based control 'click .o_website_rating_table_row': '_onClickStarDomain', 'click .o_website_rating_selection_reset': '_onClickStarDomainReset', @@ -199,7 +199,7 @@ PortalChatter.include({ ratingData.publisher_name = rawRating.publisher_id[1]; ratingData.publisher_avatar = _.str.sprintf('/web/image/res.partner/%s/avatar_128/50x50', ratingData.publisher_id); } - var commentData = _.extend(this._newPublisherCommentData(messageIndex), ratingData); + var commentData = Object.assign(this._newPublisherCommentData(messageIndex), ratingData); return commentData; }, diff --git a/addons/portal_rating/static/src/js/portal_composer.js b/addons/portal_rating/static/src/js/portal_composer.js index d36a5d814d5..49262cc5bf1 100644 --- a/addons/portal_rating/static/src/js/portal_composer.js +++ b/addons/portal_rating/static/src/js/portal_composer.js @@ -13,7 +13,7 @@ var PortalComposer = portalComposer.PortalComposer; * Extends Portal Composer to handle rating submission */ PortalComposer.include({ - events: _.extend({}, PortalComposer.prototype.events, { + events: Object.assign({}, PortalComposer.prototype.events, { 'click .stars i': '_onClickStar', 'mouseleave .stars': '_onMouseleaveStarBlock', 'mousemove .stars i': '_onMoveStar', diff --git a/addons/portal_rating/static/src/js/portal_rating_composer.js b/addons/portal_rating/static/src/js/portal_rating_composer.js index c3e01e30069..eb8f1b74ba0 100644 --- a/addons/portal_rating/static/src/js/portal_rating_composer.js +++ b/addons/portal_rating/static/src/js/portal_rating_composer.js @@ -114,7 +114,7 @@ const RatingPopupComposer = publicWidget.Widget.extend({ delete data.rating_count; delete data.rating_value; - this.options = _.extend(this.options, data); + this.options = Object.assign(this.options, data); this._reloadRatingPopupComposer(); } diff --git a/addons/pos_adyen/static/src/js/payment_adyen.js b/addons/pos_adyen/static/src/js/payment_adyen.js index e423c5d3681..8eb651511b7 100644 --- a/addons/pos_adyen/static/src/js/payment_adyen.js +++ b/addons/pos_adyen/static/src/js/payment_adyen.js @@ -102,7 +102,7 @@ export const PaymentAdyen = PaymentInterface.extend({ var line = order.selected_paymentline; var data = { SaleToPOIRequest: { - MessageHeader: _.extend(this._adyen_common_message_header(), { + MessageHeader: Object.assign(this._adyen_common_message_header(), { MessageCategory: "Payment", }), PaymentRequest: { @@ -156,7 +156,7 @@ export const PaymentAdyen = PaymentInterface.extend({ var self = this; var config = this.pos.config; var previous_service_id = this.most_recent_service_id; - var header = _.extend(this._adyen_common_message_header(), { + var header = Object.assign(this._adyen_common_message_header(), { MessageCategory: "Abort", }); diff --git a/addons/pos_mercury/static/src/js/PaymentScreen.js b/addons/pos_mercury/static/src/js/PaymentScreen.js index 2a88d82c7a3..32644c7166a 100644 --- a/addons/pos_mercury/static/src/js/PaymentScreen.js +++ b/addons/pos_mercury/static/src/js/PaymentScreen.js @@ -425,7 +425,7 @@ patch(PaymentScreen.prototype, "pos_mercury.PaymentScreen", { transaction: def, }); - var request_data = _.extend( + var request_data = Object.assign( { transaction_type: "Credit", transaction_code: "VoidSaleByRecordNo", diff --git a/addons/pos_mercury/static/src/js/pos_mercury.js b/addons/pos_mercury/static/src/js/pos_mercury.js index b76285d9166..563c7aff0aa 100644 --- a/addons/pos_mercury/static/src/js/pos_mercury.js +++ b/addons/pos_mercury/static/src/js/pos_mercury.js @@ -102,7 +102,7 @@ patch(Payment.prototype, "pos_mercury.Payment", { this.set_credit_card_name(); }, export_as_JSON() { - return _.extend(this._super(...arguments), { + return Object.assign(this._super(...arguments), { paid: this.paid, mercury_card_number: this.mercury_card_number, mercury_card_brand: this.mercury_card_brand, diff --git a/addons/pos_six/static/src/js/payment_six.js b/addons/pos_six/static/src/js/payment_six.js index 23d4cc3fb50..f9361f9a336 100644 --- a/addons/pos_six/static/src/js/payment_six.js +++ b/addons/pos_six/static/src/js/payment_six.js @@ -29,7 +29,7 @@ export const PaymentSix = PaymentInterface.extend({ this.enable_reversals(); var terminal_ip = this.payment_method.six_terminal_ip; - var instanced_payment_method = _.find(this.pos.payment_methods, function (payment_method) { + var instanced_payment_method = this.pos.payment_methods.find(function (payment_method) { return ( payment_method.use_payment_terminal === "six" && payment_method.six_terminal_ip === terminal_ip && diff --git a/addons/sale_product_configurator/static/src/js/product_configurator_modal.js b/addons/sale_product_configurator/static/src/js/product_configurator_modal.js index d98142a52f1..b5b9c83b7f8 100644 --- a/addons/sale_product_configurator/static/src/js/product_configurator_modal.js +++ b/addons/sale_product_configurator/static/src/js/product_configurator_modal.js @@ -7,7 +7,7 @@ import ServicesMixin from 'web.ServicesMixin'; import VariantMixin from 'sale.VariantMixin'; export const OptionalProductsModal = Dialog.extend(ServicesMixin, VariantMixin, { - events: _.extend({}, Dialog.prototype.events, VariantMixin.events, { + events: Object.assign({}, Dialog.prototype.events, VariantMixin.events, { 'click a.js_add, a.js_remove': '_onAddOrRemoveOption', 'click button.js_add_cart_json': 'onClickAddCartJSON', 'change .in_cart input.js_quantity': '_onChangeQuantity', @@ -37,7 +37,7 @@ export const OptionalProductsModal = Dialog.extend(ServicesMixin, VariantMixin, init: function (parent, params) { var self = this; - var options = _.extend({ + var options = Object.assign({ size: 'large', buttons: [{ text: params.okButtonText, @@ -85,7 +85,7 @@ export const OptionalProductsModal = Dialog.extend(ServicesMixin, VariantMixin, force_dialog: self.forceDialog, no_attribute: self.rootProduct.no_variant_attribute_values, custom_attribute: self.rootProduct.product_custom_attribute_values, - context: _.extend({'quantity': self.rootProduct.quantity}, this.context), + context: Object.assign({'quantity': self.rootProduct.quantity}, this.context), }) .then(function (modalContent) { if (modalContent) { diff --git a/addons/web/static/src/legacy/js/core/ajax.js b/addons/web/static/src/legacy/js/core/ajax.js index 6b1445d5382..99b77843859 100644 --- a/addons/web/static/src/legacy/js/core/ajax.js +++ b/addons/web/static/src/legacy/js/core/ajax.js @@ -125,7 +125,7 @@ function _genericJsonRpc (fct_name, params, settings, fct) { function jsonRpc(url, fct_name, params, settings) { settings = settings || {}; return _genericJsonRpc(fct_name, params, settings, function(data) { - return $.ajax(url, _.extend({}, settings, { + return $.ajax(url, Object.assign({}, settings, { url: url, dataType: 'json', type: 'POST', @@ -275,7 +275,7 @@ var loadAsset = (function () { if (cache[xmlId]) { return cache[xmlId]; } - context = _.extend({}, session.user_context, context); + context = Object.assign({}, session.user_context, context); const params = { args: [xmlId, { debug: config.isDebug() @@ -316,7 +316,7 @@ var loadAsset = (function () { return load; })(); -_.extend(ajax, { +Object.assign(ajax, { jsonRpc: jsonRpc, rpc: rpc, loadAsset: loadAsset, diff --git a/addons/web/static/src/legacy/js/core/dialog.js b/addons/web/static/src/legacy/js/core/dialog.js index 9dc8936b63c..9069211348d 100644 --- a/addons/web/static/src/legacy/js/core/dialog.js +++ b/addons/web/static/src/legacy/js/core/dialog.js @@ -18,11 +18,11 @@ var _t = core._t; **/ var Dialog = Widget.extend({ tagName: 'main', - custom_events: _.extend({}, Widget.prototype.custom_events, { + custom_events: Object.assign({}, Widget.prototype.custom_events, { focus_control_button: '_onFocusControlButton', close_dialog: '_onCloseDialog', }), - events: _.extend({}, Widget.prototype.events, { + events: Object.assign({}, Widget.prototype.events, { 'keydown .modal-footer button': '_onFooterButtonKeyDown', }), /** @@ -411,7 +411,7 @@ Dialog.alert = function (owner, message, options) { close: true, click: options && options.confirm_callback, }]; - return new Dialog(owner, _.extend({ + return new Dialog(owner, Object.assign({ size: 'medium', buttons: buttons, $content: $('
', { @@ -464,7 +464,7 @@ Dialog.confirm = function (owner, message, options) { click: makeCallback('cancel_callback'), } ]; - return new Dialog(owner, _.extend({ + return new Dialog(owner, Object.assign({ size: 'medium', buttons: buttons, $content: $('
', { @@ -518,7 +518,7 @@ Dialog.safeConfirm = function (owner, message, options) { click: options && options.cancel_callback } ]; - var dialog = new Dialog(owner, _.extend({ + var dialog = new Dialog(owner, Object.assign({ size: 'medium', buttons: buttons, $content: $content, diff --git a/addons/web/static/src/legacy/js/core/dom.js b/addons/web/static/src/legacy/js/core/dom.js index a4125b3f3b8..ca99b78a345 100644 --- a/addons/web/static/src/legacy/js/core/dom.js +++ b/addons/web/static/src/legacy/js/core/dom.js @@ -406,7 +406,7 @@ var dom = { * @returns {jQuery} */ renderButton: function (options) { - var jQueryParams = _.extend({ + var jQueryParams = Object.assign({ type: 'button', }, options.attrs || {}); diff --git a/addons/web/static/src/legacy/js/core/domain.js b/addons/web/static/src/legacy/js/core/domain.js index edc920450d1..52c6f3a2300 100644 --- a/addons/web/static/src/legacy/js/core/domain.js +++ b/addons/web/static/src/legacy/js/core/domain.js @@ -140,13 +140,9 @@ var Domain = collections.Tree.extend({ } else { // The domain is a set of [name, operator, value] entitie(s) switch (this._data) { case "&": - return _.every(this._children, function (child) { - return child.compute(values); - }); + return this._children.every(child => child.compute(values)); case "|": - return _.some(this._children, function (child) { - return child.compute(values); - }); + return this._children.some(child => child.compute(values)); case "!": return !this._children[0].compute(values); } diff --git a/addons/web/static/src/legacy/js/core/local_storage.js b/addons/web/static/src/legacy/js/core/local_storage.js index 544c8b7f75b..b8030940e9d 100644 --- a/addons/web/static/src/legacy/js/core/local_storage.js +++ b/addons/web/static/src/legacy/js/core/local_storage.js @@ -20,7 +20,7 @@ try { * it's not up to them to handle these cases. */ storage = (function () { - var storage = Object.create(_.extend({ + var storage = Object.create(Object.assign({ getItem: localStorage.getItem.bind(localStorage), setItem: localStorage.setItem.bind(localStorage), removeItem: localStorage.removeItem.bind(localStorage), diff --git a/addons/web/static/src/legacy/js/core/mixins.js b/addons/web/static/src/legacy/js/core/mixins.js index 14f861a2baa..df1f1e07af2 100644 --- a/addons/web/static/src/legacy/js/core/mixins.js +++ b/addons/web/static/src/legacy/js/core/mixins.js @@ -119,7 +119,7 @@ function OdooEvent(target, name, data) { this.target = target; this.name = name; this.data = Object.create(null); - _.extend(this.data, data); + Object.assign(this.data, data); this.stopped = false; } @@ -238,7 +238,7 @@ var Events = Class.extend({ * @name EventDispatcherMixin * @mixin */ -var EventDispatcherMixin = _.extend({}, ParentedMixin, { +var EventDispatcherMixin = Object.assign({}, ParentedMixin, { __eventDispatcherMixin: true, custom_events: {}, init: function () { @@ -358,7 +358,7 @@ var EventDispatcherMixin = _.extend({}, ParentedMixin, { * @name PropertiesMixin * @mixin */ -var PropertiesMixin = _.extend({}, EventDispatcherMixin, { +var PropertiesMixin = Object.assign({}, EventDispatcherMixin, { init: function () { EventDispatcherMixin.init.call(this); this.__getterSetterInternalMap = {}; diff --git a/addons/web/static/src/legacy/js/core/mvc.js b/addons/web/static/src/legacy/js/core/mvc.js index b1be3646016..074bae32baa 100644 --- a/addons/web/static/src/legacy/js/core/mvc.js +++ b/addons/web/static/src/legacy/js/core/mvc.js @@ -183,7 +183,7 @@ var Factory = Class.extend({ var renderer = self.getRenderer(parent, state); var Controller = self.Controller || self.config.Controller; const initialState = model.get(handle); - var controllerParams = _.extend({ + var controllerParams = Object.assign({ initialState, handle, }, self.controllerParams); diff --git a/addons/web/static/src/legacy/js/core/py_utils.js b/addons/web/static/src/legacy/js/core/py_utils.js index 1f4b065717a..5e0339dcc53 100644 --- a/addons/web/static/src/legacy/js/core/py_utils.js +++ b/addons/web/static/src/legacy/js/core/py_utils.js @@ -105,7 +105,7 @@ function wrap_context(context) { } function eval_contexts(contexts, evaluation_context) { - evaluation_context = _.extend(pycontext(), evaluation_context || {}); + evaluation_context = Object.assign(pycontext(), evaluation_context || {}); return _(contexts).reduce(function (result_context, ctx) { // __eval_context evaluations can lead to some of `contexts`'s // values being null, skip them as well as empty contexts @@ -123,18 +123,18 @@ function eval_contexts(contexts, evaluation_context) { case 'compound_context': var eval_context = eval_contexts([ctx.__eval_context]); evaluated = eval_contexts( - ctx.__contexts, _.extend({}, evaluation_context, eval_context)); + ctx.__contexts, Object.assign({}, evaluation_context, eval_context)); break; } // add newly evaluated context to evaluation context for following // siblings - _.extend(evaluation_context, evaluated); - return _.extend(result_context, evaluated); + Object.assign(evaluation_context, evaluated); + return Object.assign(result_context, evaluated); }, {}); } function eval_domains(domains, evaluation_context) { - evaluation_context = _.extend(pycontext(), evaluation_context || {}); + evaluation_context = Object.assign(pycontext(), evaluation_context || {}); var result_domain = []; // Normalize only if the first domain is the array ["|"] or ["!"] var need_normalization = ( @@ -187,7 +187,7 @@ function get_normalized_domain(domain_array) { } function eval_groupbys(contexts, evaluation_context) { - evaluation_context = _.extend(pycontext(), evaluation_context || {}); + evaluation_context = Object.assign(pycontext(), evaluation_context || {}); var result_group = []; _(contexts).each(function (ctx) { if (_.isString(ctx)) { @@ -204,7 +204,7 @@ function eval_groupbys(contexts, evaluation_context) { case 'compound_context': var eval_context = eval_contexts([ctx.__eval_context]); evaluated = eval_contexts( - ctx.__contexts, _.extend({}, evaluation_context, eval_context)); + ctx.__contexts, Object.assign({}, evaluation_context, eval_context)); break; } group = evaluated.group_by; @@ -217,7 +217,7 @@ function eval_groupbys(contexts, evaluation_context) { throw new Error('Got invalid groupby {{' + JSON.stringify(group) + '}}'); } - _.extend(evaluation_context, evaluated); + Object.assign(evaluation_context, evaluated); }); return result_group; } @@ -285,7 +285,7 @@ function pycontext() { * @param {Object} [context] evaluation context */ function pyeval(type, object, context) { - context = _.extend(pycontext(), context || {}); + context = Object.assign(pycontext(), context || {}); //noinspection FallthroughInSwitchStatementJS switch(type) { @@ -347,7 +347,7 @@ function eval_domains_and_contexts(source) { } function py_eval(expr, context) { - return py.eval(expr, _.extend({}, context || {}, {"true": true, "false": false, "null": null})); + return py.eval(expr, Object.assign({}, context || {}, {"true": true, "false": false, "null": null})); } /** diff --git a/addons/web/static/src/legacy/js/core/qweb.js b/addons/web/static/src/legacy/js/core/qweb.js index 79c5eae3575..8aa392abee3 100644 --- a/addons/web/static/src/legacy/js/core/qweb.js +++ b/addons/web/static/src/legacy/js/core/qweb.js @@ -17,7 +17,7 @@ function QWeb(debug, default_dict, enableTranslation) { enableTranslation = true; } var qweb = new QWeb2.Engine(); - qweb.default_dict = _.extend({}, default_dict || {}, { + qweb.default_dict = Object.assign({}, default_dict || {}, { '_' : _, 'JSON': JSON, '_t' : translation._t, diff --git a/addons/web/static/src/legacy/js/core/rpc.js b/addons/web/static/src/legacy/js/core/rpc.js index d9ceaf225a9..68fe98369ab 100644 --- a/addons/web/static/src/legacy/js/core/rpc.js +++ b/addons/web/static/src/legacy/js/core/rpc.js @@ -46,7 +46,7 @@ const rpc = { params.args = options.args || []; params.model = options.model; params.method = options.method; - params.kwargs = _.extend(params.kwargs || {}, options.kwargs); + params.kwargs = Object.assign(params.kwargs || {}, options.kwargs); params.kwargs.context = options.context || params.context || params.kwargs.context; } diff --git a/addons/web/static/src/legacy/js/core/session.js b/addons/web/static/src/legacy/js/core/session.js index abf9e697302..85f13a8de92 100644 --- a/addons/web/static/src/legacy/js/core/session.js +++ b/addons/web/static/src/legacy/js/core/session.js @@ -124,7 +124,7 @@ var Session = core.Class.extend(mixins.EventDispatcherMixin, { if (!result.uid) { return Promise.reject(); } - _.extend(self, result); + Object.assign(self, result); }); }, session_logout: function () { @@ -228,8 +228,8 @@ var Session = core.Class.extend(mixins.EventDispatcherMixin, { * @returns {Promise} promise indicating the session is done reloading */ session_reload: function () { - var result = _.extend({}, session); - _.extend(this, result); + var result = Object.assign({}, session); + Object.assign(this, result); return Promise.resolve(); }, /** @@ -247,17 +247,17 @@ var Session = core.Class.extend(mixins.EventDispatcherMixin, { rpc: function (url, params, options) { var self = this; options = _.clone(options || {}); - options.headers = _.extend({}, options.headers); + options.headers = Object.assign({}, options.headers); // we add here the user context for ALL queries, mainly to pass // the allowed_company_ids key if (params && params.kwargs) { - params.kwargs.context = _.extend(params.kwargs.context || {}, this.user_context); + params.kwargs.context = Object.assign(params.kwargs.context || {}, this.user_context); } // TODO: remove if (! _.isString(url)) { - _.extend(options, url); + Object.assign(options, url); url = url.url; } if (self.use_cors) { @@ -267,7 +267,7 @@ var Session = core.Class.extend(mixins.EventDispatcherMixin, { return ajax.jsonRpc(url, "call", params, options); }, url: function (path, params) { - params = _.extend(params || {}); + params = Object.assign(params || {}); var qs = $.param(params); if (qs.length > 0) qs = "?" + qs; diff --git a/addons/web/static/src/legacy/js/core/session_storage.js b/addons/web/static/src/legacy/js/core/session_storage.js index 24b04cc8201..4a3179d6863 100644 --- a/addons/web/static/src/legacy/js/core/session_storage.js +++ b/addons/web/static/src/legacy/js/core/session_storage.js @@ -20,7 +20,7 @@ try { * it's not up to them to handle these cases. */ storage = (function () { - var storage = Object.create(_.extend({ + var storage = Object.create(Object.assign({ getItem: sessionStorage.getItem.bind(sessionStorage), setItem: sessionStorage.setItem.bind(sessionStorage), removeItem: sessionStorage.removeItem.bind(sessionStorage), diff --git a/addons/web/static/src/legacy/js/core/widget.js b/addons/web/static/src/legacy/js/core/widget.js index ae10ff2e19e..d0249a34c54 100644 --- a/addons/web/static/src/legacy/js/core/widget.js +++ b/addons/web/static/src/legacy/js/core/widget.js @@ -364,7 +364,7 @@ var Widget = core.Class.extend(mixins.PropertiesMixin, ServicesMixin, { * @return {jQuery} */ _makeDescriptive: function () { - var attrs = _.extend({}, this.attributes || {}); + var attrs = Object.assign({}, this.attributes || {}); if (this.id) { attrs.id = this.id; } diff --git a/addons/web/static/src/legacy/js/fields/abstract_field.js b/addons/web/static/src/legacy/js/fields/abstract_field.js index 5e5f5a94202..1377e1cee4f 100644 --- a/addons/web/static/src/legacy/js/fields/abstract_field.js +++ b/addons/web/static/src/legacy/js/fields/abstract_field.js @@ -432,7 +432,7 @@ var AbstractField = Widget.extend({ if (!formatType) { throw new Error(`Missing format type for '${this.name}' value from the '${this.model}' model`); } - var options = _.extend({}, this.nodeOptions, { data: this.recordData }, this.formatOptions); + var options = Object.assign({}, this.nodeOptions, { data: this.recordData }, this.formatOptions); return field_utils.format[formatType](value, this.field, options); }, /** diff --git a/addons/web/static/src/legacy/js/fields/basic_fields.js b/addons/web/static/src/legacy/js/fields/basic_fields.js index 19047d52a1c..725323b5ed6 100644 --- a/addons/web/static/src/legacy/js/fields/basic_fields.js +++ b/addons/web/static/src/legacy/js/fields/basic_fields.js @@ -60,7 +60,7 @@ var TranslatableFieldMixin = { var FieldBoolean = AbstractField.extend({ className: 'o_field_boolean', description: _lt("Checkbox"), - events: _.extend({}, AbstractField.prototype.events, { + events: Object.assign({}, AbstractField.prototype.events, { change: '_onChange', }), supportedFieldTypes: ['boolean'], @@ -308,10 +308,10 @@ var DebouncedField = AbstractField.extend({ }); var InputField = DebouncedField.extend({ - custom_events: _.extend({}, DebouncedField.prototype.custom_events, { + custom_events: Object.assign({}, DebouncedField.prototype.custom_events, { field_changed: '_onFieldChanged', }), - events: _.extend({}, DebouncedField.prototype.events, { + events: Object.assign({}, DebouncedField.prototype.events, { 'input': '_onInput', 'change': '_onChange', 'blur' : '_onBlur', @@ -417,10 +417,10 @@ var InputField = DebouncedField.extend({ var inputAttrs = { placeholder: this.attrs.placeholder || "" }; var inputVal; if (this.nodeOptions.isPassword) { - inputAttrs = _.extend(inputAttrs, { type: 'password', autocomplete: this.attrs.autocomplete || 'new-password' }); + inputAttrs = Object.assign(inputAttrs, { type: 'password', autocomplete: this.attrs.autocomplete || 'new-password' }); inputVal = this.value || ''; } else { - inputAttrs = _.extend(inputAttrs, { type: 'text', autocomplete: this.attrs.autocomplete || 'off'}); + inputAttrs = Object.assign(inputAttrs, { type: 'text', autocomplete: this.attrs.autocomplete || 'off'}); inputVal = this._formatValue(this.value); } @@ -1427,7 +1427,7 @@ var FieldText = InputField.extend(TranslatableFieldMixin, { var UrlWidget = InputField.extend({ description: _lt("URL"), className: 'o_field_url', - events: _.extend({}, InputField.prototype.events, { + events: Object.assign({}, InputField.prototype.events, { 'click': '_onClick', }), supportedFieldTypes: ['char'], @@ -1503,7 +1503,7 @@ var UrlWidget = InputField.extend({ }); var AbstractFieldBinary = AbstractField.extend({ - events: _.extend({}, AbstractField.prototype.events, { + events: Object.assign({}, AbstractField.prototype.events, { 'change .o_input_file': 'on_file_change', 'click .o_select_file_button': function () { this.$('.o_input_file').click(); @@ -1627,7 +1627,7 @@ var AbstractFieldBinary = AbstractField.extend({ var FieldBinaryFile = AbstractFieldBinary.extend({ description: _lt("File"), template: 'FieldBinaryFile', - events: _.extend({}, AbstractFieldBinary.prototype.events, { + events: Object.assign({}, AbstractFieldBinary.prototype.events, { 'click': function (event) { if (this.mode === 'readonly' && this.value && this.recordData.id) { this.on_save_as(event); diff --git a/addons/web/static/src/legacy/js/fields/field_utils.js b/addons/web/static/src/legacy/js/fields/field_utils.js index c4ae46602fb..d7d5598d8f0 100644 --- a/addons/web/static/src/legacy/js/fields/field_utils.js +++ b/addons/web/static/src/legacy/js/fields/field_utils.js @@ -360,7 +360,7 @@ function formatMonetary(value, field, options) { digits = field.digits || digits; } var formatted_value = formatFloat(value, field, - _.extend({}, options , {digits: digits}) + Object.assign({}, options , {digits: digits}) ); if (!currency || options.noSymbol) { @@ -402,9 +402,7 @@ function formatPercentage(value, field, options) { * @param {boolean} [options.escape=false] if true, escapes the formatted value */ function formatSelection(value, field, options) { - var val = _.find(field.selection, function (option) { - return option[0] === value; - }); + var val = field.selection.find(option => option[0] === value); if (!val) { return ''; } diff --git a/addons/web/static/src/legacy/js/fields/relational_fields.js b/addons/web/static/src/legacy/js/fields/relational_fields.js index 3563b4d6b2c..bd42c66f7af 100644 --- a/addons/web/static/src/legacy/js/fields/relational_fields.js +++ b/addons/web/static/src/legacy/js/fields/relational_fields.js @@ -75,12 +75,12 @@ var FieldMany2One = AbstractField.extend({ description: _lt("Many2one"), supportedFieldTypes: ['many2one'], template: 'FieldMany2One', - custom_events: _.extend({}, AbstractField.prototype.custom_events, { + custom_events: Object.assign({}, AbstractField.prototype.custom_events, { 'closed_unset': '_onDialogClosedUnset', 'field_changed': '_onFieldChanged', 'quick_create': '_onQuickCreate', }), - events: _.extend({}, AbstractField.prototype.events, { + events: Object.assign({}, AbstractField.prototype.events, { 'click input': '_onInputClick', 'click': '_onLinkClick', 'focusout input': '_onInputFocusout', @@ -421,7 +421,7 @@ var FieldMany2One = AbstractField.extend({ return { resModel: this.field.relation, domain: this.record.getDomain({fieldName: this.name}), - context: _.extend({}, this.record.getContext(this.recordParams), context || {}), + context: Object.assign({}, this.record.getContext(this.recordParams), context || {}), dynamicFilters: dynamicFilters || [], title: _.str.sprintf((view === 'search' ? _t("Search: %s") : _t("Create: %s")), this.string), multiSelect: false, @@ -973,10 +973,10 @@ var FieldMany2ManyTags = AbstractField.extend({ tag_template: "FieldMany2ManyTag", className: "o_field_many2manytags", supportedFieldTypes: ['many2many'], - custom_events: _.extend({}, AbstractField.prototype.custom_events, { + custom_events: Object.assign({}, AbstractField.prototype.custom_events, { field_changed: '_onFieldChanged', }), - events: _.extend({}, AbstractField.prototype.events, { + events: Object.assign({}, AbstractField.prototype.events, { 'click .o_delete': '_onDeleteTag', }), relatedFields: { @@ -1125,7 +1125,7 @@ var FieldMany2ManyTags = AbstractField.extend({ var options = _getSearchCreatePopupOptions.apply(this, arguments); var domain = this.record.getDomain({fieldName: this.name}); var m2mRecords = []; - return _.extend({}, options, { + return Object.assign({}, options, { domain: domain.concat(["!", ["id", "in", self.value.res_ids]]), multiSelect: true, onSelected: function (recordIds) { @@ -1293,7 +1293,7 @@ const ListMany2ManyTagsAvatar = FieldMany2ManyTagsAvatar.extend(M2MAvatarMixin, }); var FormFieldMany2ManyTags = FieldMany2ManyTags.extend({ - events: _.extend({}, FieldMany2ManyTags.prototype.events, { + events: Object.assign({}, FieldMany2ManyTags.prototype.events, { 'click .dropdown-toggle': '_onOpenColorPicker', 'mousedown .o_colorpicker a': '_onUpdateColor', 'mousedown .o_colorpicker .o_hide_in_kanban': '_onUpdateColor', @@ -1413,7 +1413,7 @@ var FieldSelection = AbstractField.extend({ template: 'web.Legacy.FieldSelection', specialData: "_fetchSpecialRelation", supportedFieldTypes: ['selection'], - events: _.extend({}, AbstractField.prototype.events, { + events: Object.assign({}, AbstractField.prototype.events, { 'change': '_onChange', }), isQuickEditable: true, @@ -1532,9 +1532,7 @@ var FieldSelection = AbstractField.extend({ _onChange: function () { var res_id = JSON.parse(this.$el.val()); if (this.field.type === 'many2one') { - var value = _.find(this.values, function (val) { - return val[0] === res_id; - }); + var value = this.values.find(val => val[0] === res_id); this._setValue({id: res_id, display_name: value[1]}); } else { this._setValue(res_id); @@ -1549,7 +1547,7 @@ var FieldRadio = FieldSelection.extend({ tagName: 'div', specialData: "_fetchSpecialMany2ones", supportedFieldTypes: ['selection', 'many2one'], - events: _.extend({}, AbstractField.prototype.events, { + events: Object.assign({}, AbstractField.prototype.events, { 'click input': '_onInputClick', }), isQuickEditable: true, diff --git a/addons/web/static/src/legacy/js/public/public_root.js b/addons/web/static/src/legacy/js/public/public_root.js index b33f03f080f..c0da3596fc8 100644 --- a/addons/web/static/src/legacy/js/public/public_root.js +++ b/addons/web/static/src/legacy/js/public/public_root.js @@ -48,11 +48,11 @@ var localeDef = lang !== 'en_US' ? loadJS('/web/webclient/locale/' + lang.replac * children and handle them. */ export const PublicRoot = publicWidget.RootWidget.extend({ - events: _.extend({}, publicWidget.RootWidget.prototype.events || {}, { + events: Object.assign({}, publicWidget.RootWidget.prototype.events || {}, { 'submit .js_website_submit_form': '_onWebsiteFormSubmit', 'click .js_disable_on_click': '_onDisableOnClick', }), - custom_events: _.extend({}, publicWidget.RootWidget.prototype.custom_events || {}, { + custom_events: Object.assign({}, publicWidget.RootWidget.prototype.custom_events || {}, { call_service: '_onCallService', context_get: '_onContextGet', main_object_request: '_onMainObjectRequest', @@ -124,7 +124,7 @@ export const PublicRoot = publicWidget.RootWidget.extend({ * @returns {Object} */ _getContext: function (context) { - return _.extend({ + return Object.assign({ 'lang': getLang(), }, context || {}); }, @@ -237,7 +237,7 @@ export const PublicRoot = publicWidget.RootWidget.extend({ */ _onCallService: function (ev) { function _computeContext(context, noContextKeys) { - context = _.extend({}, this._getContext(), context); + context = Object.assign({}, this._getContext(), context); if (noContextKeys) { context = _.omit(context, noContextKeys); } diff --git a/addons/web/static/src/legacy/js/views/abstract_model.js b/addons/web/static/src/legacy/js/views/abstract_model.js index 217d2e3c330..439829eb85f 100644 --- a/addons/web/static/src/legacy/js/views/abstract_model.js +++ b/addons/web/static/src/legacy/js/views/abstract_model.js @@ -104,9 +104,7 @@ var AbstractModel = mvc.Model.extend({ value = fieldUtils.parse[field.type](value, field, {isUTC: true}); } else if (field.type === 'selection' && value === false) { // process selection: convert false to 0, if 0 is a valid key - var hasKey0 = _.find(field.selection, function (option) { - return option[0] === 0; - }); + var hasKey0 = field.selection.find(option => option[0] === 0); value = hasKey0 ? 0 : value; } return value; diff --git a/addons/web/static/src/legacy/js/views/basic/basic_model.js b/addons/web/static/src/legacy/js/views/basic/basic_model.js index b3e90f62bce..3057bae513a 100644 --- a/addons/web/static/src/legacy/js/views/basic/basic_model.js +++ b/addons/web/static/src/legacy/js/views/basic/basic_model.js @@ -187,7 +187,7 @@ var BasicModel = AbstractModel.extend({ addDefaultRecord: function (listID, options) { var self = this; var list = this.localData[listID]; - var context = _.extend({}, this._getDefaultContext(list), this._getContext(list)); + var context = Object.assign({}, this._getDefaultContext(list), this._getContext(list)); var position = (options && options.position) || 'top'; var params = { @@ -225,7 +225,7 @@ var BasicModel = AbstractModel.extend({ */ addFieldsInfo: async function (dataPointID, viewInfo) { var dataPoint = this.localData[dataPointID]; - dataPoint.fields = _.extend({}, dataPoint.fields, viewInfo.fields); + dataPoint.fields = Object.assign({}, dataPoint.fields, viewInfo.fields); // complete the given fieldInfo with the fields of the main view, so // that those field will be reloaded if a reload is triggered by the // secondary view @@ -254,7 +254,7 @@ var BasicModel = AbstractModel.extend({ }); } else { // case 'record': on datapoints of all x2many fields - const values = _.extend({}, dataPoint.data, dataPoint._changes); + const values = Object.assign({}, dataPoint.data, dataPoint._changes); Object.keys(fieldInfo).forEach(fieldName => { const fieldType = dataPoint.fields[fieldName].type; if (fieldType === 'one2many' || fieldType === 'many2many') { @@ -335,7 +335,7 @@ var BasicModel = AbstractModel.extend({ return false; } // 2.2. no drop on new addition on "UPDATE" - var lastEntry = _.last(parent._savePoint); + var lastEntry = parent._savePoint.at(-1); if (lastEntry.operation === 'UPDATE' && lastEntry.id === id) { return false; } @@ -360,7 +360,7 @@ var BasicModel = AbstractModel.extend({ deleteRecords: function (recordIds, modelName) { var self = this; var records = _.map(recordIds, function (id) { return self.localData[id]; }); - var context = _.extend(records[0].getContext(), session.user_context); + var context = Object.assign(records[0].getContext(), session.user_context); return this._rpc({ model: modelName, method: 'unlink', @@ -410,7 +410,7 @@ var BasicModel = AbstractModel.extend({ if (elem._savePoint instanceof Array) { elem._changes = elem._savePoint.slice(0); } else { - elem._changes = _.extend({}, elem._savePoint); + elem._changes = Object.assign({}, elem._savePoint); } elem._isDirty = !isNew; } else { @@ -621,8 +621,8 @@ var BasicModel = AbstractModel.extend({ } var list = { - aggregateValues: _.extend({}, element.aggregateValues), - context: _.extend({}, element.context), + aggregateValues: Object.assign({}, element.aggregateValues), + context: Object.assign({}, element.context), count: element.count, data: _.map(element.data, function (elemID) { return self.__get(elemID, options); @@ -1119,7 +1119,7 @@ var BasicModel = AbstractModel.extend({ if (newValue instanceof Array) { rec._savePoint = newValue.slice(0); } else { - rec._savePoint = _.extend({}, newValue); + rec._savePoint = Object.assign({}, newValue); } }); @@ -1190,7 +1190,7 @@ var BasicModel = AbstractModel.extend({ reject, ); } else { - _.extend(record.data, _changes); + Object.assign(record.data, _changes); resolve(changedFields); } }).guardedCatch(reject); @@ -1403,7 +1403,7 @@ var BasicModel = AbstractModel.extend({ unfreezeOrder: function (elementID) { var list = this.localData[elementID]; if (list.type === 'record') { - var data = _.extend({}, list.data, list._changes); + var data = Object.assign({}, list.data, list._changes); for (var fieldName in data) { var field = list.fields[fieldName]; if (!field || !data[fieldName]) { @@ -1561,7 +1561,7 @@ var BasicModel = AbstractModel.extend({ resolve(_.keys(changes).concat(Object.keys(result && result.value || {}))); }).guardedCatch(function () { self._visitChildren(record, function (elem) { - _.extend(elem, initialData[elem.id]); + Object.assign(elem, initialData[elem.id]); }); reject(); }); @@ -1806,7 +1806,7 @@ var BasicModel = AbstractModel.extend({ // CREATE or UPDATE if (command[0] === 0 && command[1]) { // updating an existing (virtual) record - var previousChange = _.find(oldChanges, function (operation) { + var previousChange = oldChanges.find(operation => { var child = self.localData[operation.id]; return child && (child.ref === command[1]); }); @@ -2014,7 +2014,7 @@ var BasicModel = AbstractModel.extend({ model: list.model, method: 'read', args: [_.pluck(data, 'id'), fieldNames], - context: _.extend({}, record.context, field.context, list.getContext()), + context: Object.assign({}, record.context, field.context, list.getContext()), }).then(function (records) { _.each(records, function (record) { list_records[record.id].data = record; @@ -2029,7 +2029,7 @@ var BasicModel = AbstractModel.extend({ } break; case 'CREATE': - var createOptions = _.extend({ + var createOptions = Object.assign({ context: command.context, position: command.position }, options || {}); @@ -2517,9 +2517,7 @@ var BasicModel = AbstractModel.extend({ }) .then(function (name_gets) { _.each(records, function (record) { - var nameGet = _.find(name_gets, function (nameGet) { - return nameGet[0] === record.data.id; - }); + var nameGet = name_gets.find(nameGet => nameGet[0] === record.data.id); record.data.display_name = nameGet[1]; }); }); @@ -2546,14 +2544,14 @@ var BasicModel = AbstractModel.extend({ model: record.model, method: 'read', args: [[record.res_id], fieldNames], - context: _.extend({bin_size: true}, record.getContext()), + context: Object.assign({bin_size: true}, record.getContext()), }) .then(function (result) { if (result.length === 0) { return Promise.reject(); } result = result[0]; - record.data = _.extend({}, record.data, result); + record.data = Object.assign({}, record.data, result); }) .then(function () { self._parseServerData(fieldNames, record, record.data); @@ -3174,9 +3172,9 @@ var BasicModel = AbstractModel.extend({ var changes; const changesOnly = 'changesOnly' in options ? !!options.changesOnly : true; if (!changesOnly) { - changes = _.extend({}, record.data, record._changes); + changes = Object.assign({}, record.data, record._changes); } else { - changes = _.extend({}, record._changes); + changes = Object.assign({}, record._changes); } var withReadonly = options.withReadonly || false; var commands = this._generateX2ManyCommands(record, { @@ -3231,11 +3229,11 @@ var BasicModel = AbstractModel.extend({ * @returns {Object} the data */ _generateOnChangeData: function (record, options) { - options = _.extend({}, options || {}, {withReadonly: true}); + options = Object.assign({}, options || {}, {withReadonly: true}); var data = {}; if (!options.firstOnChange) { var commands = this._generateX2ManyCommands(record, options); - data = _.extend(this.get(record.id, {raw: true}).data, commands); + data = Object.assign(this.get(record.id, {raw: true}).data, commands); // 'display_name' is automatically added to the list of fields to fetch, // when fetching a record, even if it doesn't appear in the view. However, // only the fields in the view must be passed to the onchange RPC, so we @@ -3286,7 +3284,7 @@ var BasicModel = AbstractModel.extend({ fields = _.pick(fields, options.fieldNames); } var commands = {}; - var data = _.extend({}, record.data, record._changes); + var data = Object.assign({}, record.data, record._changes); var type; for (var fieldName in fields) { type = fields[fieldName].type; @@ -3851,7 +3849,7 @@ var BasicModel = AbstractModel.extend({ _getRecordEvalContext: function (record, forDomain) { var self = this; var relDataPoint; - var context = _.extend({}, record.data, record._changes); + var context = Object.assign({}, record.data, record._changes); // calls _generateX2ManyCommands for a given field, and returns the array of commands function _generateX2ManyCommands(fieldName) { @@ -4146,7 +4144,7 @@ var BasicModel = AbstractModel.extend({ var res_ids = params.res_ids || []; var data = params.data || (type === 'record' ? {} : []); var context = params.context; - var fields = _.extend({ + var fields = Object.assign({ display_name: {type: 'char'}, id: {type: 'integer'}, }, params.fields); @@ -4424,7 +4422,7 @@ var BasicModel = AbstractModel.extend({ var self = this; // save the RPC request - var request = _.extend({}, params); + var request = Object.assign({}, params); var prom = new Promise(function (resolve, reject) { request.resolve = resolve; request.reject = reject; @@ -4449,7 +4447,7 @@ var BasicModel = AbstractModel.extend({ var request = batchedRPCsRequests[i]; key = request.model + ',' + JSON.stringify(request.context); if (!batches[key]) { - batches[key] = _.extend({}, request, {requests: [request]}); + batches[key] = Object.assign({}, request, {requests: [request]}); } else { batches[key].ids = _.uniq(batches[key].ids.concat(request.ids)); batches[key].fieldNames = _.uniq(batches[key].fieldNames.concat(request.fieldNames)); @@ -4702,7 +4700,7 @@ var BasicModel = AbstractModel.extend({ continue; } var record = self.localData[dataPointID]; - var data = _.extend({}, record.data, record._changes); + var data = Object.assign({}, record.data, record._changes); if (_.difference(fieldNames, _.keys(data)).length) { missingIDs.push(resId); } @@ -4730,7 +4728,7 @@ var BasicModel = AbstractModel.extend({ dataPoint = self.localData[list._cache[id]]; if (data) { self._parseServerData(fieldNames, dataPoint, data); - _.extend(dataPoint.data, data); + Object.assign(dataPoint.data, data); } } else { dataPoint = self._makeDataPoint({ @@ -4815,9 +4813,7 @@ var BasicModel = AbstractModel.extend({ // the 'title'. var value = group[groupByField]; if (list.fields[rawGroupBy].type === "selection") { - var choice = _.find(list.fields[rawGroupBy].selection, function (c) { - return c[0] === value; - }); + var choice = list.fields[rawGroupBy].selection.find(c => c[0] === value); value = choice ? choice[1] : false; } var newGroup = self._makeDataPoint({ @@ -4839,9 +4835,7 @@ var BasicModel = AbstractModel.extend({ type: 'list', viewType: list.viewType, }); - var oldGroup = _.find(previousGroups, function (g) { - return g.res_id === newGroup.res_id && g.value === newGroup.value; - }); + var oldGroup = previousGroups.find(g => g.res_id === newGroup.res_id && g.value === newGroup.value); if (oldGroup) { delete self.localData[newGroup.id]; // restore the internal state of the group @@ -5122,7 +5116,7 @@ var BasicModel = AbstractModel.extend({ route: '/web/dataset/search_read', model: list.model, fields: fieldNames, - context: _.extend({}, list.getContext(), {bin_size: true}), + context: Object.assign({}, list.getContext(), {bin_size: true}), domain: this._getUngroupedListDomain(list), limit: list.limit, offset: list.loadMoreOffset + list.offset, @@ -5264,8 +5258,8 @@ var BasicModel = AbstractModel.extend({ } var r1 = self.localData[record1ID]; var r2 = self.localData[record2ID]; - var data1 = _.extend({}, r1.data, r1._changes); - var data2 = _.extend({}, r2.data, r2._changes); + var data1 = Object.assign({}, r1.data, r1._changes); + var data2 = Object.assign({}, r2.data, r2._changes); // Default value to sort against: the value of the field var orderData1 = data1[order.name]; diff --git a/addons/web/static/src/legacy/js/views/standalone_field_manager_mixin.js b/addons/web/static/src/legacy/js/views/standalone_field_manager_mixin.js index 73a677841d7..5d0a1f08d65 100644 --- a/addons/web/static/src/legacy/js/views/standalone_field_manager_mixin.js +++ b/addons/web/static/src/legacy/js/views/standalone_field_manager_mixin.js @@ -12,7 +12,7 @@ import FieldManagerMixin from 'web.FieldManagerMixin'; * @property {Function} _confirmChange * @property {Function} _registerWidget */ -var StandaloneFieldManagerMixin = _.extend({}, FieldManagerMixin, { +var StandaloneFieldManagerMixin = Object.assign({}, FieldManagerMixin, { /** * @override diff --git a/addons/web/static/src/legacy/js/views/view_utils.js b/addons/web/static/src/legacy/js/views/view_utils.js index 50a3200afee..26db6e11047 100644 --- a/addons/web/static/src/legacy/js/views/view_utils.js +++ b/addons/web/static/src/legacy/js/views/view_utils.js @@ -31,9 +31,7 @@ var viewUtils = { case 'many2one': return group.res_id || false; case 'selection': - var descriptor = _.find(groupedByField.selection, function (option) { - return option[1] === group.value; - }); + var descriptor = groupedByField.selection.find(option => option[1] === group.value); return descriptor && descriptor[0]; case 'char': case 'boolean': diff --git a/addons/web/static/src/legacy/js/widgets/colorpicker.js b/addons/web/static/src/legacy/js/widgets/colorpicker.js index ca7e675692b..bb307e55827 100644 --- a/addons/web/static/src/legacy/js/widgets/colorpicker.js +++ b/addons/web/static/src/legacy/js/widgets/colorpicker.js @@ -177,7 +177,7 @@ var ColorpickerWidget = Widget.extend({ if (!rgb) { return; } - _.extend(this.colorComponents, + Object.assign(this.colorComponents, {hex: hex}, rgb, ColorpickerWidget.convertRgbToHsl(rgb.red, rgb.green, rgb.blue) @@ -207,7 +207,7 @@ var ColorpickerWidget = Widget.extend({ if (!hex) { return; } - _.extend(this.colorComponents, + Object.assign(this.colorComponents, {red: r, green: g, blue: b}, a === undefined ? {} : {opacity: a}, {hex: hex}, @@ -236,7 +236,7 @@ var ColorpickerWidget = Widget.extend({ } // We receive an hexa as we ignore the opacity const hex = ColorpickerWidget.convertRgbaToCSSColor(rgb.red, rgb.green, rgb.blue); - _.extend(this.colorComponents, + Object.assign(this.colorComponents, {hue: h, saturation: s, lightness: l}, rgb, {hex: hex}, @@ -254,7 +254,7 @@ var ColorpickerWidget = Widget.extend({ if (a < 0 || a > 100) { return; } - _.extend(this.colorComponents, + Object.assign(this.colorComponents, {opacity: a} ); this._updateCssColor(); @@ -277,7 +277,7 @@ var ColorpickerWidget = Widget.extend({ const g = this.colorComponents.green; const b = this.colorComponents.blue; const a = this.colorComponents.opacity; - _.extend(this.colorComponents, + Object.assign(this.colorComponents, {cssColor: ColorpickerWidget.convertRgbaToCSSColor(r, g, b, a)} ); if (this.previewActive) { @@ -702,7 +702,7 @@ const ColorpickerDialog = Dialog.extend({ */ init: function (parent, options) { this.options = options || {}; - this._super(parent, _.extend({ + this._super(parent, Object.assign({ size: 'small', title: _t('Pick a color'), buttons: [ @@ -716,7 +716,7 @@ const ColorpickerDialog = Dialog.extend({ */ start: function () { const proms = [this._super(...arguments)]; - this.colorPicker = new ColorpickerWidget(this, _.extend({ + this.colorPicker = new ColorpickerWidget(this, Object.assign({ colorPreview: true, }, this.options)); proms.push(this.colorPicker.appendTo(this.$el)); diff --git a/addons/web/static/src/legacy/js/widgets/date_picker.js b/addons/web/static/src/legacy/js/widgets/date_picker.js index b73dee9a6ba..2d0bcba07b9 100644 --- a/addons/web/static/src/legacy/js/widgets/date_picker.js +++ b/addons/web/static/src/legacy/js/widgets/date_picker.js @@ -26,7 +26,7 @@ var DateWidget = Widget.extend({ this._super.apply(this, arguments); this.name = parent.name; - this.options = _.extend({ + this.options = Object.assign({ locale: moment.locale(), format : this.type_of_date === 'datetime' ? time.getLangDatetimeFormat() : time.getLangDateFormat(), minDate: moment({ y: 1000 }), @@ -339,7 +339,7 @@ var DateWidget = Widget.extend({ var DateTimeWidget = DateWidget.extend({ type_of_date: "datetime", init: function (parent, options) { - this._super(parent, _.extend({ + this._super(parent, Object.assign({ buttons: { showToday: false, showClear: false, diff --git a/addons/web/static/src/legacy/js/widgets/domain_selector.js b/addons/web/static/src/legacy/js/widgets/domain_selector.js index ac9e33fc58b..8183fc5115d 100644 --- a/addons/web/static/src/legacy/js/widgets/domain_selector.js +++ b/addons/web/static/src/legacy/js/widgets/domain_selector.js @@ -71,7 +71,7 @@ var DomainNode = Widget.extend({ this._super.apply(this, arguments); this.model = model; - this.options = _.extend({ + this.options = Object.assign({ readonly: true, operators: null, debugMode: false, @@ -162,7 +162,7 @@ var DomainNode = Widget.extend({ */ var DomainTree = DomainNode.extend({ template: "DomainTree", - events: _.extend({}, DomainNode.prototype.events, { + events: Object.assign({}, DomainNode.prototype.events, { "click .o_domain_tree_operator_selector .dropdown-item": "_onOperatorChange", }), custom_events: { @@ -461,11 +461,11 @@ var DomainTree = DomainNode.extend({ */ var DomainSelector = DomainTree.extend({ template: "DomainSelector", - events: _.extend({}, DomainTree.prototype.events, { + events: Object.assign({}, DomainTree.prototype.events, { "click .o_domain_add_first_node_button": "_onAddFirstButtonClick", "change .o_domain_debug_input": "_onDebugInputChange", }), - custom_events: _.extend({}, DomainTree.prototype.custom_events, { + custom_events: Object.assign({}, DomainTree.prototype.custom_events, { domain_changed: "_onDomainChange", }), @@ -637,7 +637,7 @@ var DomainSelector = DomainTree.extend({ */ var DomainLeaf = DomainNode.extend({ template: "DomainLeaf", - events: _.extend({}, DomainNode.prototype.events, { + events: Object.assign({}, DomainNode.prototype.events, { "change .o_domain_leaf_operator_select": "_onOperatorSelectChange", "change .o_domain_leaf_value_input": "_onValueInputChange", @@ -922,7 +922,7 @@ var DomainLeaf = DomainNode.extend({ break; default: - operators = _.extend({}, operator_mapping); + operators = Object.assign({}, operator_mapping); break; } diff --git a/addons/web/static/src/legacy/js/widgets/domain_selector_dialog.js b/addons/web/static/src/legacy/js/widgets/domain_selector_dialog.js index a6d453351c1..ab3566b8a20 100644 --- a/addons/web/static/src/legacy/js/widgets/domain_selector_dialog.js +++ b/addons/web/static/src/legacy/js/widgets/domain_selector_dialog.js @@ -11,13 +11,13 @@ var _t = core._t; * @class DomainSelectorDialog */ export default Dialog.extend({ - custom_events: _.extend({}, Dialog.prototype.custom_events, { + custom_events: Object.assign({}, Dialog.prototype.custom_events, { domain_changed: "_onDomainChange", }), init: function (parent, model, domain, options) { this.model = model; this.newDomain = null; - this.options = _.extend({ + this.options = Object.assign({ readonly: true, debugMode: false, }, options || {}); @@ -38,7 +38,7 @@ export default Dialog.extend({ ]; } - this._super(parent, _.extend({}, { + this._super(parent, Object.assign({}, { title: _t("Domain"), buttons: buttons, }, options || {})); diff --git a/addons/web/static/src/legacy/js/widgets/model_field_selector.js b/addons/web/static/src/legacy/js/widgets/model_field_selector.js index 5719a8d167c..bfbe3049f16 100644 --- a/addons/web/static/src/legacy/js/widgets/model_field_selector.js +++ b/addons/web/static/src/legacy/js/widgets/model_field_selector.js @@ -56,7 +56,7 @@ var ModelFieldSelector = Widget.extend({ this.model = model; this.chain = chain; - this.options = _.extend({ + this.options = Object.assign({ order: 'string', readonly: true, fields: null, @@ -67,7 +67,7 @@ var ModelFieldSelector = Widget.extend({ this.popover = new ModelFieldSelectorPopover(this, model, chain, options); if (!this.options.readonly) { - _.extend(this.events, this.edition_events); + Object.assign(this.events, this.edition_events); } }, /** diff --git a/addons/web/static/src/legacy/js/widgets/model_field_selector_popover.js b/addons/web/static/src/legacy/js/widgets/model_field_selector_popover.js index 3b71d1890e2..81752970b23 100644 --- a/addons/web/static/src/legacy/js/widgets/model_field_selector_popover.js +++ b/addons/web/static/src/legacy/js/widgets/model_field_selector_popover.js @@ -86,7 +86,7 @@ var ModelFieldSelectorPopover = Widget.extend({ this.model = model; this.chain = chain; - this.options = _.extend({ + this.options = Object.assign({ order: 'string', filters: {}, fields: null, @@ -98,7 +98,7 @@ var ModelFieldSelectorPopover = Widget.extend({ cancelOnEscape: false, chainedTitle: false }, options || {}); - this.options.filters = _.extend({ + this.options.filters = Object.assign({ searchable: true, }, this.options.filters); @@ -149,7 +149,7 @@ var ModelFieldSelectorPopover = Widget.extend({ * @returns {Object} */ getSelectedField: function () { - return _.findWhere(this.pages[this.chain.length - 1], {name: _.last(this.chain)}); + return _.findWhere(this.pages[this.chain.length - 1], {name: this.chain.at(-1)}); }, /** * Saves a new field chain (array) and re-render. @@ -213,7 +213,7 @@ var ModelFieldSelectorPopover = Widget.extend({ * to its name /*/ _getLastPageField: function (name) { - return _.findWhere(_.last(this.pages), { + return _.findWhere(this.pages.at(-1) , { name: name, }); }, @@ -404,10 +404,10 @@ var ModelFieldSelectorPopover = Widget.extend({ var title = ""; if (this.pages.length > 1) { var prevField = _.findWhere(this.pages[this.pages.length - 2], { - name: (this.chain.length === this.pages.length) ? this.chain[this.chain.length - 2] : _.last(this.chain), + name: (this.chain.length === this.pages.length) ? this.chain[this.chain.length - 2] : this.chain.at(-1), }); if (prevField) { - this.titlesNames[_.last(this.chain)] = prevField.string; + this.titlesNames[this.chain.at(-1)] = prevField.string; title = prevField.string; } } @@ -426,7 +426,7 @@ var ModelFieldSelectorPopover = Widget.extend({ this._adaptInputVisibility(); // Adapt the popover content - var page = _.last(this.pages); + var page = this.pages.at(-1); this.$(".o_field_selector_popover_header .o_field_selector_title").text(this._getTitle()); var lines = _.filter(page, this.options.filter); @@ -722,7 +722,7 @@ function sortFields(fields, model, order) { array = array.sortBy(function (p) {return p[1][order]; }); } return array.map(function (p) { - return _.extend({ + return Object.assign({ name: p[0], model: model, }, p[1]); diff --git a/addons/web/static/src/legacy/js/widgets/name_and_signature.js b/addons/web/static/src/legacy/js/widgets/name_and_signature.js index d611aae55a3..a7a97ea6088 100644 --- a/addons/web/static/src/legacy/js/widgets/name_and_signature.js +++ b/addons/web/static/src/legacy/js/widgets/name_and_signature.js @@ -423,7 +423,7 @@ var NameAndSignature = Widget.extend({ } self.$signatureField.jSignature('reset'); var ignoredContext = _.pick(context, ['shadowOffsetX', 'shadowOffsetY']); - _.extend(context, {shadowOffsetX: 0, shadowOffsetY: 0}); + Object.assign(context, {shadowOffsetX: 0, shadowOffsetY: 0}); context.drawImage(image, 0, 0, @@ -434,7 +434,7 @@ var NameAndSignature = Widget.extend({ width, height ); - _.extend(context, ignoredContext); + Object.assign(context, ignoredContext); self.trigger_up('signature_changed'); }, 0); }; diff --git a/addons/web/static/tests/legacy/core/domain_tests.js b/addons/web/static/tests/legacy/core/domain_tests.js index 8f6ec255b5d..52df7d8c524 100644 --- a/addons/web/static/tests/legacy/core/domain_tests.js +++ b/addons/web/static/tests/legacy/core/domain_tests.js @@ -40,9 +40,9 @@ QUnit.module('core', {}, function () { ['user_id', '=', 3], ['member_ids', 'in', [3]] ]; - assert.ok(new Domain(currentDomain).compute(_.extend({}, web, {section_id: 42}))); - assert.ok(new Domain(currentDomain).compute(_.extend({}, web, {user_id: 3}))); - assert.ok(new Domain(currentDomain).compute(_.extend({}, web, {member_ids: 3}))); + assert.ok(new Domain(currentDomain).compute(Object.assign({}, web, {section_id: 42}))); + assert.ok(new Domain(currentDomain).compute(Object.assign({}, web, {user_id: 3}))); + assert.ok(new Domain(currentDomain).compute(Object.assign({}, web, {member_ids: 3}))); }); QUnit.test("not", function (assert) { diff --git a/addons/web/static/tests/legacy/core/py_utils_tests.js b/addons/web/static/tests/legacy/core/py_utils_tests.js index 4fe4a729ca3..a804d2d35a3 100644 --- a/addons/web/static/tests/legacy/core/py_utils_tests.js +++ b/addons/web/static/tests/legacy/core/py_utils_tests.js @@ -66,7 +66,7 @@ QUnit.module('core', function () { // Port from pypy/lib_pypy/test_datetime.py function makeEq(assert, c2) { var ctx = pyUtils.context(); - var c = _.extend({ td: ctx.datetime.timedelta }, c2 || {}); + var c = Object.assign({ td: ctx.datetime.timedelta }, c2 || {}); return function (a, b, message) { assert.ok(py.eval(a + ' == ' + b, c), message); }; diff --git a/addons/web/static/tests/legacy/helpers/mock_server.js b/addons/web/static/tests/legacy/helpers/mock_server.js index 0051c9f7655..b792c9d44ef 100644 --- a/addons/web/static/tests/legacy/helpers/mock_server.js +++ b/addons/web/static/tests/legacy/helpers/mock_server.js @@ -362,7 +362,7 @@ var MockServer = Class.extend({ var attrs = node.getAttribute('attrs'); if (attrs) { attrs = pyUtils.py_eval(attrs); - _.extend(modifiers, attrs); + Object.assign(modifiers, attrs); } var states = node.getAttribute('states'); @@ -422,7 +422,7 @@ var MockServer = Class.extend({ // this is hackhish, but _getView modifies the subview document in place, // especially to generate the "modifiers" attribute const { models } = self._getView(childNode, relModel, - relFields, _.extend({}, context, {base_model_name: model})); + relFields, Object.assign({}, context, {base_model_name: model})); [...models].forEach((modelName) => relatedModels.add(modelName)); } }); @@ -570,7 +570,7 @@ var MockServer = Class.extend({ var model = this.data[modelName]; var newID = this._getUnusedID(modelName); var originalRecord = _.findWhere(model.records, {id: id}); - var duplicateRecord = _.extend({}, originalRecord, {id: newID}); + var duplicateRecord = Object.assign({}, originalRecord, {id: newID}); duplicateRecord.display_name = originalRecord.display_name + ' (copy)'; model.records.push(duplicateRecord); return newID; diff --git a/addons/web/static/tests/legacy/helpers/test_utils_mock.js b/addons/web/static/tests/legacy/helpers/test_utils_mock.js index 23311be2de0..22aded6025c 100644 --- a/addons/web/static/tests/legacy/helpers/test_utils_mock.js +++ b/addons/web/static/tests/legacy/helpers/test_utils_mock.js @@ -218,13 +218,13 @@ function _mockGlobalObjects(params) { for (key in config) { delete config[key]; } - _.extend(config, initialConfig); + Object.assign(config, initialConfig); } if ('translateParameters' in params) { for (key in core._t.database.parameters) { delete core._t.database.parameters[key]; } - _.extend(core._t.database.parameters, initialParameters); + Object.assign(core._t.database.parameters, initialParameters); } } diff --git a/addons/web/static/tests/legacy/owl_compatibility_tests.js b/addons/web/static/tests/legacy/owl_compatibility_tests.js index 3d0b7ff85a1..9a398020ab3 100644 --- a/addons/web/static/tests/legacy/owl_compatibility_tests.js +++ b/addons/web/static/tests/legacy/owl_compatibility_tests.js @@ -1442,7 +1442,7 @@ WidgetComponent.template = xml`
Component
`; const MyWidget = WidgetAdapter.extend({ - custom_events: _.extend({}, Widget.custom_events, { + custom_events: Object.assign({}, Widget.custom_events, { some_event: function (ev) { assert.step(ev.data.value); } @@ -1474,7 +1474,7 @@ class WidgetComponent extends LegacyComponent {} WidgetComponent.template = xml`
Component
`; const MyWidget = WidgetAdapter.extend({ - custom_events: _.extend({}, Widget.custom_events, { + custom_events: Object.assign({}, Widget.custom_events, { some_event: function (ev) { assert.strictEqual(this, ev.data.widget); assert.step(ev.data.value); diff --git a/addons/web/static/tests/legacy/qweb_tests.js b/addons/web/static/tests/legacy/qweb_tests.js index 8e9f3cc80d3..044eb613b32 100644 --- a/addons/web/static/tests/legacy/qweb_tests.js +++ b/addons/web/static/tests/legacy/qweb_tests.js @@ -79,7 +79,7 @@ const table = [ fixture: { before() { this.WORD_REPLACEMENT = window.QWeb2.WORD_REPLACEMENT; - window.QWeb2.WORD_REPLACEMENT = _.extend( + window.QWeb2.WORD_REPLACEMENT = Object.assign( {not: '!', None: 'undefined'}, this.WORD_REPLACEMENT ) diff --git a/addons/web/static/tests/legacy/views/basic_model_tests.js b/addons/web/static/tests/legacy/views/basic_model_tests.js index 7c6250cefa7..41608d6be1b 100644 --- a/addons/web/static/tests/legacy/views/basic_model_tests.js +++ b/addons/web/static/tests/legacy/views/basic_model_tests.js @@ -98,7 +98,7 @@ return this._super.apply(this, arguments); }, }); - const params = _.extend(this.params, { + const params = Object.assign(this.params, { context: { active_field: 2 }, groupedBy: ['product_id'], fieldNames: ['foo'], @@ -825,7 +825,7 @@ var rpcCount = 0; var fields = this.data.partner.fields; - fields.other_product_id = _.extend({}, fields.product_id); + fields.other_product_id = Object.assign({}, fields.product_id); fields.product_id.default = 37; fields.other_product_id.default = 41; @@ -1995,7 +1995,7 @@ }); // load a new record (default_get) - var params = _.extend(this.params, { + var params = Object.assign(this.params, { res_id: undefined, type: 'record', fieldNames: ['foo'], @@ -2195,7 +2195,7 @@ string: 'foobool2', }, }; - _.extend(this.data.partner.fields, newFields); + Object.assign(this.data.partner.fields, newFields); this.data.partner.fields.foobool.onChange = true; this.data.partner.onchanges.foobool = function (obj) { diff --git a/addons/web/static/tests/views/fields/badge_selection_field_tests.js b/addons/web/static/tests/views/fields/badge_selection_field_tests.js index 97714fdca41..8f767a8d39f 100644 --- a/addons/web/static/tests/views/fields/badge_selection_field_tests.js +++ b/addons/web/static/tests/views/fields/badge_selection_field_tests.js @@ -91,7 +91,7 @@ QUnit.module("Fields", (hooks) => { await click(target, ".o_form_button_save"); - var newRecord = _.last(serverData.models.partner.records); + var newRecord = serverData.models.partner.records.at(-1); assert.strictEqual(newRecord.product_id, 37, "should have saved record with correct value"); }); @@ -122,7 +122,7 @@ QUnit.module("Fields", (hooks) => { await click(target.querySelector(".o_form_button_save")); - var newRecord = _.last(serverData.models.partner.records); + var newRecord = serverData.models.partner.records.at(-1); assert.strictEqual( newRecord.color, "black", diff --git a/addons/web/static/tests/views/fields/many2many_field_tests.js b/addons/web/static/tests/views/fields/many2many_field_tests.js index beafde32329..8b66bae6d63 100644 --- a/addons/web/static/tests/views/fields/many2many_field_tests.js +++ b/addons/web/static/tests/views/fields/many2many_field_tests.js @@ -817,7 +817,7 @@ QUnit.module("Fields", (hooks) => { `, mockRPC(route, args) { if (args.method !== "get_views") { - assert.step(_.last(route.split("/"))); + assert.step(route.split("/").at(-1)); } if (args.method === "write") { assert.deepEqual(args.args[1].timmy, [ @@ -1424,7 +1424,7 @@ QUnit.module("Fields", (hooks) => { resId: 1, mockRPC(route, args) { if (args.method !== "get_views") { - assert.step(_.last(route.split("/")) + " on " + args.model); + assert.step(route.split("/").at(-1) + " on " + args.model); } if (args.model === "turtle") { assert.step(JSON.stringify(args.args[0])); // the read ids diff --git a/addons/web/static/tests/views/kanban_view_tests.js b/addons/web/static/tests/views/kanban_view_tests.js index 4c8e950ed83..323aa2ac8bc 100644 --- a/addons/web/static/tests/views/kanban_view_tests.js +++ b/addons/web/static/tests/views/kanban_view_tests.js @@ -3467,7 +3467,7 @@ QUnit.module("Views", (hooks) => { "should have created a partner" ); assert.strictEqual( - _.last(serverData.models.partner.records).name, + serverData.models.partner.records.at(-1).name, "new partner", "should have correct name" ); diff --git a/addons/web/static/tests/views/list_view_tests.js b/addons/web/static/tests/views/list_view_tests.js index cf168dd2e28..745d3dfa269 100644 --- a/addons/web/static/tests/views/list_view_tests.js +++ b/addons/web/static/tests/views/list_view_tests.js @@ -9752,7 +9752,7 @@ QUnit.module("Views", (hooks) => { // create records to have the search more button const newRecs = []; for (let i = 0; i < 8; i++) { - const newRec = _.extend({}, rec); + const newRec = Object.assign({}, rec); newRec.id = 1 + i; newRec.cornichon = "extra fin"; newRecs.push(newRec); diff --git a/addons/web_editor/static/src/js/common/ace.js b/addons/web_editor/static/src/js/common/ace.js index 8326c4a55ff..8faac6b9e7d 100644 --- a/addons/web_editor/static/src/js/common/ace.js +++ b/addons/web_editor/static/src/js/common/ace.js @@ -518,7 +518,7 @@ var ViewEditor = Widget.extend({ function _processViews(views) { // Only keep the active views and index them by ID. - _.extend(this.views, _.indexBy(_.filter(views, function (view) { + Object.assign(this.views, _.indexBy(_.filter(views, function (view) { return view.active; }), 'id')); @@ -566,7 +566,7 @@ var ViewEditor = Widget.extend({ var resources = type === 'scss' ? this.scss : this.js; _.each(data, function (bundleInfos) { _.each(bundleInfos[1], function (info) { info.bundle = bundleInfos[0]; }); - _.extend(resources, _.indexBy(bundleInfos[1], 'url')); + Object.assign(resources, _.indexBy(bundleInfos[1], 'url')); }); } }, diff --git a/addons/web_editor/static/src/js/editor/snippets.editor.js b/addons/web_editor/static/src/js/editor/snippets.editor.js index bc321119fbd..cc7a170b2d0 100644 --- a/addons/web_editor/static/src/js/editor/snippets.editor.js +++ b/addons/web_editor/static/src/js/editor/snippets.editor.js @@ -807,7 +807,7 @@ var SnippetEditor = Widget.extend({ val.$el.children(), val.base_target ? this.$target.find(val.base_target).eq(0) : this.$target, this.$el, - _.extend({ + Object.assign({ optionName: optionName, snippetName: this.getName(), }, val.data), @@ -2804,7 +2804,7 @@ var SnippetsMenu = Widget.extend({ '$el': $style, 'drop-near': $style.data('drop-near') && self._computeSelectorFunctions($style.data('drop-near'), '', false, noCheck, true, excludeParent), 'drop-in': $style.data('drop-in') && self._computeSelectorFunctions($style.data('drop-in'), '', false, noCheck), - 'data': _.extend({string: $style.attr('string')}, $style.data()), + 'data': Object.assign({string: $style.attr('string')}, $style.data()), }; self.templateOptions.push(option); selectors.push(option.selector); diff --git a/addons/web_editor/static/src/js/editor/snippets.options.js b/addons/web_editor/static/src/js/editor/snippets.options.js index ee9604e7d09..885a324b4c3 100644 --- a/addons/web_editor/static/src/js/editor/snippets.options.js +++ b/addons/web_editor/static/src/js/editor/snippets.options.js @@ -402,7 +402,7 @@ const UserValueWidget = Widget.extend({ * @returns {Object} */ getMethodsParams: function (methodName) { - const params = _.extend({}, this._methodsParams); + const params = Object.assign({}, this._methodsParams); if (methodName) { params.possibleValues = params.optionsPossibleValues[methodName] || []; params.activeValue = this.getActiveValue(methodName); @@ -472,7 +472,7 @@ const UserValueWidget = Widget.extend({ */ loadMethodsData: function (validMethodNames, extraParams) { this._methodsNames = []; - this._methodsParams = _.extend({}, extraParams); + this._methodsParams = Object.assign({}, extraParams); this._methodsParams.optionsPossibleValues = {}; this._dependencies = []; this._triggerWidgetsNames = []; @@ -495,7 +495,7 @@ const UserValueWidget = Widget.extend({ } } this._userValueWidgets.forEach(widget => { - const inheritedParams = _.extend({}, this._methodsParams); + const inheritedParams = Object.assign({}, this._methodsParams); inheritedParams.optionsPossibleValues = null; widget.loadMethodsData(validMethodNames, inheritedParams); const subMethodsNames = widget.getMethodsNames(); @@ -1388,7 +1388,7 @@ const MultiUserValueWidget = UserValueWidget.extend({ const ColorpickerUserValueWidget = SelectUserValueWidget.extend({ className: (SelectUserValueWidget.prototype.className || '') + ' o_we_so_color_palette', - custom_events: _.extend({}, SelectUserValueWidget.prototype.custom_events, { + custom_events: Object.assign({}, SelectUserValueWidget.prototype.custom_events, { 'custom_color_picked': '_onCustomColorPicked', 'color_picked': '_onColorPicked', 'color_hover': '_onColorHovered', @@ -1458,7 +1458,7 @@ const ColorpickerUserValueWidget = SelectUserValueWidget.extend({ * @override */ getMethodsParams: function () { - return _.extend(this._super(...arguments), { + return Object.assign(this._super(...arguments), { colorNames: this.colorPalette.getColorNames(), }); }, @@ -1883,7 +1883,7 @@ const DatetimePickerUserValueWidget = InputUserValueWidget.extend({ * @override */ getMethodsParams: function () { - return _.extend(this._super(...arguments), { + return Object.assign(this._super(...arguments), { format: this.defaultFormat, }); }, @@ -2011,7 +2011,7 @@ const ListUserValueWidget = UserValueWidget.extend({ * @override */ getMethodsParams() { - return _.extend(this._super(...arguments), { + return Object.assign(this._super(...arguments), { records: this.records, }); }, diff --git a/addons/web_editor/static/src/js/wysiwyg/dialog.js b/addons/web_editor/static/src/js/wysiwyg/dialog.js index 4561ed70900..e1321f478a2 100644 --- a/addons/web_editor/static/src/js/wysiwyg/dialog.js +++ b/addons/web_editor/static/src/js/wysiwyg/dialog.js @@ -18,7 +18,7 @@ var WysiwygDialog = Dialog.extend({ if (config.device.isMobile) { options.fullscreen = true; } - this._super(parent, _.extend({}, { + this._super(parent, Object.assign({}, { buttons: [{ text: this.options.save_text || _t("Save"), classes: 'btn-primary', diff --git a/addons/web_editor/static/src/js/wysiwyg/widgets/alt_dialog.js b/addons/web_editor/static/src/js/wysiwyg/widgets/alt_dialog.js index 2b70f7d1260..5eb46a6c8fb 100644 --- a/addons/web_editor/static/src/js/wysiwyg/widgets/alt_dialog.js +++ b/addons/web_editor/static/src/js/wysiwyg/widgets/alt_dialog.js @@ -15,7 +15,7 @@ var AltDialog = Dialog.extend({ */ init: function (parent, options, media) { options = options || {}; - this._super(parent, _.extend({}, { + this._super(parent, Object.assign({}, { title: _t("Change media description and tooltip") }, options)); diff --git a/addons/web_editor/static/src/js/wysiwyg/widgets/color_palette.js b/addons/web_editor/static/src/js/wysiwyg/widgets/color_palette.js index c64a6466a54..1c17858fe9f 100644 --- a/addons/web_editor/static/src/js/wysiwyg/widgets/color_palette.js +++ b/addons/web_editor/static/src/js/wysiwyg/widgets/color_palette.js @@ -49,7 +49,7 @@ const ColorPaletteWidget = Widget.extend({ this._super.apply(this, arguments); const editableDocument = options.editable ? options.editable.ownerDocument : document; this.style = editableDocument.defaultView.getComputedStyle(editableDocument.documentElement); - this.options = _.extend({ + this.options = Object.assign({ selectedColor: false, resetButton: true, excluded: [], diff --git a/addons/web_editor/static/src/js/wysiwyg/widgets/link.js b/addons/web_editor/static/src/js/wysiwyg/widgets/link.js index e44ce25c1e9..4249964a0d9 100644 --- a/addons/web_editor/static/src/js/wysiwyg/widgets/link.js +++ b/addons/web_editor/static/src/js/wysiwyg/widgets/link.js @@ -26,7 +26,7 @@ const Link = Widget.extend({ */ init: function (parent, options, editable, data, $button, link) { this.options = options || {}; - this._super(parent, _.extend({ + this._super(parent, Object.assign({ title: _t("Link to"), }, this.options)); diff --git a/addons/web_editor/static/src/js/wysiwyg/widgets/link_dialog.js b/addons/web_editor/static/src/js/wysiwyg/widgets/link_dialog.js index 413797d5034..0ac334c69b2 100644 --- a/addons/web_editor/static/src/js/wysiwyg/widgets/link_dialog.js +++ b/addons/web_editor/static/src/js/wysiwyg/widgets/link_dialog.js @@ -7,7 +7,7 @@ import Link from "wysiwyg.widgets.Link"; // This widget is there only to extend Link and be instantiated by LinkDialog. const _DialogLinkWidget = Link.extend({ template: 'wysiwyg.widgets.link', - events: _.extend({}, Link.prototype.events || {}, { + events: Object.assign({}, Link.prototype.events || {}, { 'change [name="link_style_color"]': '_onTypeChange', }), diff --git a/addons/web_editor/static/src/js/wysiwyg/widgets/link_tools.js b/addons/web_editor/static/src/js/wysiwyg/widgets/link_tools.js index 32994be816d..5c35610fec0 100644 --- a/addons/web_editor/static/src/js/wysiwyg/widgets/link_tools.js +++ b/addons/web_editor/static/src/js/wysiwyg/widgets/link_tools.js @@ -16,7 +16,7 @@ import { */ const LinkTools = Link.extend({ template: 'wysiwyg.widgets.linkTools', - events: _.extend({}, Link.prototype.events, { + events: Object.assign({}, Link.prototype.events, { 'click we-select we-button': '_onPickSelectOption', 'click we-checkbox': '_onClickCheckbox', 'change .link-custom-color-border input': '_onChangeCustomBorderWidth', diff --git a/addons/web_editor/static/tests/test_utils.js b/addons/web_editor/static/tests/test_utils.js index 9413564565b..7827ca43ee6 100644 --- a/addons/web_editor/static/tests/test_utils.js +++ b/addons/web_editor/static/tests/test_utils.js @@ -295,7 +295,7 @@ async function createWysiwyg(params) { var parent = new Widget(); await testUtils.mock.addMockEnvironment(parent, params); - var wysiwygOptions = _.extend({}, params.wysiwygOptions, { + var wysiwygOptions = Object.assign({}, params.wysiwygOptions, { recordInfo: { context: {}, res_model: 'module.test', diff --git a/addons/website/static/src/js/content/snippets.animation.js b/addons/website/static/src/js/content/snippets.animation.js index c4f645365d4..9c1e0bd083b 100644 --- a/addons/website/static/src/js/content/snippets.animation.js +++ b/addons/website/static/src/js/content/snippets.animation.js @@ -79,7 +79,7 @@ publicWidget.Widget.include({ this.editableMode = this.options.editableMode || false; var extraEvents = this.editableMode ? this.edit_events : this.read_events; if (extraEvents) { - this.events = _.extend({}, this.events || {}, extraEvents); + this.events = Object.assign({}, this.events || {}, extraEvents); } }, }); diff --git a/addons/website/static/src/js/content/website_root.js b/addons/website/static/src/js/content/website_root.js index 2190d838e34..f51d5932200 100644 --- a/addons/website/static/src/js/content/website_root.js +++ b/addons/website/static/src/js/content/website_root.js @@ -10,12 +10,12 @@ import "web.zoomodoo"; export const WebsiteRoot = publicRootData.PublicRoot.extend(KeyboardNavigationMixin, { // TODO remove KeyboardNavigationMixin in master - events: _.extend({}, KeyboardNavigationMixin.events, publicRootData.PublicRoot.prototype.events || {}, { + events: Object.assign({}, KeyboardNavigationMixin.events, publicRootData.PublicRoot.prototype.events || {}, { 'click .js_change_lang': '_onLangChangeClick', 'click .js_publish_management .js_publish_btn': '_onPublishBtnClick', 'shown.bs.modal': '_onModalShown', }), - custom_events: _.extend({}, publicRootData.PublicRoot.prototype.custom_events || {}, { + custom_events: Object.assign({}, publicRootData.PublicRoot.prototype.custom_events || {}, { 'gmap_api_request': '_onGMapAPIRequest', 'gmap_api_key_request': '_onGMapAPIKeyRequest', 'ready_to_clean_for_save': '_onWidgetsStopRequest', @@ -62,7 +62,7 @@ export const WebsiteRoot = publicRootData.PublicRoot.extend(KeyboardNavigationMi */ _getContext: function (context) { var html = document.documentElement; - return _.extend({ + return Object.assign({ 'website_id': html.getAttribute('data-website-id') | 0, }, this._super.apply(this, arguments)); }, @@ -71,7 +71,7 @@ export const WebsiteRoot = publicRootData.PublicRoot.extend(KeyboardNavigationMi */ _getExtraContext: function (context) { var html = document.documentElement; - return _.extend({ + return Object.assign({ 'editable': !!(html.dataset.editable || $('[data-oe-model]').length), // temporary hack, this should be done in python 'translatable': !!html.dataset.translatable, 'edit_translations': !!html.dataset.edit_translations, diff --git a/addons/website/static/src/js/editor/snippets.editor.js b/addons/website/static/src/js/editor/snippets.editor.js index 862a2a6543b..2096557c49b 100644 --- a/addons/website/static/src/js/editor/snippets.editor.js +++ b/addons/website/static/src/js/editor/snippets.editor.js @@ -11,7 +11,7 @@ const getTraversedNodes = OdooEditorLib.getTraversedNodes; const FontFamilyPickerUserValueWidget = wSnippetOptions.FontFamilyPickerUserValueWidget; const wSnippetMenu = weSnippetEditor.SnippetsMenu.extend({ - events: _.extend({}, weSnippetEditor.SnippetsMenu.prototype.events, { + events: Object.assign({}, weSnippetEditor.SnippetsMenu.prototype.events, { 'click .o_we_customize_theme_btn': '_onThemeTabClick', 'click .o_we_animate_text': '_onAnimateTextClick', 'click .o_we_highlight_animated_text': '_onHighlightAnimatedTextClick', @@ -21,7 +21,7 @@ const wSnippetMenu = weSnippetEditor.SnippetsMenu.extend({ 'gmap_api_key_request': '_onGMapAPIKeyRequest', 'reload_bundles': '_onReloadBundles', }), - tabs: _.extend({}, weSnippetEditor.SnippetsMenu.prototype.tabs, { + tabs: Object.assign({}, weSnippetEditor.SnippetsMenu.prototype.tabs, { THEME: 'theme', }), optionsTabStructure: [ diff --git a/addons/website/static/src/js/editor/snippets.options.js b/addons/website/static/src/js/editor/snippets.options.js index 51d82d7697c..6ae2e5b0307 100644 --- a/addons/website/static/src/js/editor/snippets.options.js +++ b/addons/website/static/src/js/editor/snippets.options.js @@ -39,10 +39,10 @@ options.UserValueWidget.include({ }); const UrlPickerUserValueWidget = InputUserValueWidget.extend({ - custom_events: _.extend({}, InputUserValueWidget.prototype.custom_events || {}, { + custom_events: Object.assign({}, InputUserValueWidget.prototype.custom_events || {}, { 'website_url_chosen': '_onWebsiteURLChosen', }), - events: _.extend({}, InputUserValueWidget.prototype.events || {}, { + events: Object.assign({}, InputUserValueWidget.prototype.events || {}, { 'click .o_we_redirect_to': '_onRedirectTo', }), @@ -99,7 +99,7 @@ const UrlPickerUserValueWidget = InputUserValueWidget.extend({ }); const FontFamilyPickerUserValueWidget = SelectUserValueWidget.extend({ - events: _.extend({}, SelectUserValueWidget.prototype.events || {}, { + events: Object.assign({}, SelectUserValueWidget.prototype.events || {}, { 'click .o_we_add_google_font_btn': '_onAddGoogleFontClick', 'click .o_we_delete_google_font_btn': '_onDeleteGoogleFontClick', }), @@ -540,7 +540,7 @@ options.userValueWidgetsRegistry['we-gpspicker'] = GPSPicker; //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: options.Class.include({ - custom_events: _.extend({}, options.Class.prototype.custom_events || {}, { + custom_events: Object.assign({}, options.Class.prototype.custom_events || {}, { 'google_fonts_custo_request': '_onGoogleFontsCustoRequest', }), specialCheckAndReloadMethodsNames: ['customizeWebsiteViews', 'customizeWebsiteVariable', 'customizeWebsiteColor'], diff --git a/addons/website/static/src/js/editor/widget_link.js b/addons/website/static/src/js/editor/widget_link.js index 2478cd524f3..5ef1c818360 100644 --- a/addons/website/static/src/js/editor/widget_link.js +++ b/addons/website/static/src/js/editor/widget_link.js @@ -4,7 +4,7 @@ import weWidgets from "wysiwyg.widgets"; import wUtils from "website.utils"; weWidgets.LinkTools.include({ - custom_events: _.extend({}, weWidgets.LinkTools.prototype.custom_events || {}, { + custom_events: Object.assign({}, weWidgets.LinkTools.prototype.custom_events || {}, { website_url_chosen: '_onAutocompleteClose', }), LINK_DEBOUNCE: 1000, diff --git a/addons/website/static/src/js/utils.js b/addons/website/static/src/js/utils.js index 7238c6e8bfe..5e5189bd78b 100644 --- a/addons/website/static/src/js/utils.js +++ b/addons/website/static/src/js/utils.js @@ -177,7 +177,7 @@ function prompt(options, _qweb) { if (_.isUndefined(_qweb)) { _qweb = 'website.prompt'; } - options = _.extend({ + options = Object.assign({ window_title: '', field_name: '', 'default': '', // dict notation for IE<9 diff --git a/addons/website/static/src/js/widgets/link_popover_widget.js b/addons/website/static/src/js/widgets/link_popover_widget.js index 5866f6b6906..2d55c804b4f 100644 --- a/addons/website/static/src/js/widgets/link_popover_widget.js +++ b/addons/website/static/src/js/widgets/link_popover_widget.js @@ -22,7 +22,7 @@ weWidgets.LinkPopoverWidget.include({ }); const NavbarLinkPopoverWidget = weWidgets.LinkPopoverWidget.extend({ - events: _.extend({}, weWidgets.LinkPopoverWidget.prototype.events, { + events: Object.assign({}, weWidgets.LinkPopoverWidget.prototype.events, { 'click .js_edit_menu': '_onEditMenuClick', }), /** diff --git a/addons/website/static/src/snippets/s_chart/options.js b/addons/website/static/src/snippets/s_chart/options.js index eccae79ec60..72f1855e14e 100644 --- a/addons/website/static/src/snippets/s_chart/options.js +++ b/addons/website/static/src/snippets/s_chart/options.js @@ -8,10 +8,10 @@ import weUtils from "web_editor.utils"; var _t = core._t; options.registry.InnerChart = options.Class.extend({ - custom_events: _.extend({}, options.Class.prototype.custom_events, { + custom_events: Object.assign({}, options.Class.prototype.custom_events, { 'get_custom_colors': '_onGetCustomColors', }), - events: _.extend({}, options.Class.prototype.events, { + events: Object.assign({}, options.Class.prototype.events, { 'click we-button.add_column': '_onAddColumnClick', 'click we-button.add_row': '_onAddRowClick', 'click we-button.o_we_matrix_remove_col': '_onRemoveColumnClick', diff --git a/addons/website/static/src/snippets/s_countdown/options.js b/addons/website/static/src/snippets/s_countdown/options.js index 4938e0b381c..541f98b5279 100644 --- a/addons/website/static/src/snippets/s_countdown/options.js +++ b/addons/website/static/src/snippets/s_countdown/options.js @@ -6,7 +6,7 @@ import options from "web_editor.snippets.options"; const qweb = core.qweb; options.registry.countdown = options.Class.extend({ - events: _.extend({}, options.Class.prototype.events || {}, { + events: Object.assign({}, options.Class.prototype.events || {}, { 'click .toggle-edit-message': '_onToggleEndMessageClick', }), diff --git a/addons/website/static/src/snippets/s_image_gallery/options.js b/addons/website/static/src/snippets/s_image_gallery/options.js index 7a5c52cf5d3..3e3f1c90c70 100644 --- a/addons/website/static/src/snippets/s_image_gallery/options.js +++ b/addons/website/static/src/snippets/s_image_gallery/options.js @@ -92,7 +92,7 @@ options.registry.gallery = options.Class.extend({ addImages: function (previewMode) { const $images = this.$('img'); var $container = this.$('> .container, > .container-fluid, > .o_container_small'); - const lastImage = _.last(this._getImages()); + const lastImage = this._getImages().at(-1); let index = lastImage ? this._getIndex(lastImage) : -1; const dialog = new ComponentWrapper(this, MediaDialogWrapper, { multiImages: true, diff --git a/addons/website/static/src/snippets/s_website_form/options.js b/addons/website/static/src/snippets/s_website_form/options.js index 5f41e56ceba..9b99f2d9f36 100644 --- a/addons/website/static/src/snippets/s_website_form/options.js +++ b/addons/website/static/src/snippets/s_website_form/options.js @@ -284,7 +284,7 @@ const FieldEditor = FormEditor.extend({ }); options.registry.WebsiteFormEditor = FormEditor.extend({ - events: _.extend({}, options.Class.prototype.events || {}, { + events: Object.assign({}, options.Class.prototype.events || {}, { 'click .toggle-edit-message': '_onToggleEndMessageClick', }), diff --git a/addons/website_crm_partner_assign/static/src/js/crm_partner_assign.js b/addons/website_crm_partner_assign/static/src/js/crm_partner_assign.js index 6c700bda087..ac2b6660306 100644 --- a/addons/website_crm_partner_assign/static/src/js/crm_partner_assign.js +++ b/addons/website_crm_partner_assign/static/src/js/crm_partner_assign.js @@ -82,7 +82,7 @@ publicWidget.registry.crmPartnerAssign = publicWidget.Widget.extend({ args: [[leadID], { stage_id: stageID, }], - context: _.extend({website_partner_assign: 1}), + context: Object.assign({website_partner_assign: 1}), }).then(function () { window.location.reload(); }); diff --git a/addons/website_event_exhibitor/static/src/js/event_exhibitor_connect.js b/addons/website_event_exhibitor/static/src/js/event_exhibitor_connect.js index e651311654d..519981ae31d 100644 --- a/addons/website_event_exhibitor/static/src/js/event_exhibitor_connect.js +++ b/addons/website_event_exhibitor/static/src/js/event_exhibitor_connect.js @@ -5,7 +5,7 @@ import publicWidget from "web.public.widget"; import {Markup} from "web.utils"; var ExhibitorConnectClosedDialog = Dialog.extend({ - events: _.extend({}, Dialog.prototype.events, { + events: Object.assign({}, Dialog.prototype.events, { 'click .o_wesponsor_js_connect_modal_contry': '_onClickCountryFlag', }), template: 'exhibitor.connect.closed.modal', diff --git a/addons/website_event_track_live/static/src/js/website_event_track_live.js b/addons/website_event_track_live/static/src/js/website_event_track_live.js index 808b3d86cb1..d44eaa25395 100644 --- a/addons/website_event_track_live/static/src/js/website_event_track_live.js +++ b/addons/website_event_track_live/static/src/js/website_event_track_live.js @@ -7,7 +7,7 @@ import ReplaySuggestionWidget from "website_event_track_live.website_event_track publicWidget.registry.websiteEventTrackLive = publicWidget.Widget.extend({ selector: '.o_wevent_event_track_live', - custom_events: _.extend({}, publicWidget.Widget.prototype.custom_events, { + custom_events: Object.assign({}, publicWidget.Widget.prototype.custom_events, { 'video-ended': '_onVideoEnded' }), diff --git a/addons/website_event_track_live_quiz/static/src/js/website_event_track_suggestion.js b/addons/website_event_track_live_quiz/static/src/js/website_event_track_suggestion.js index 980cf3e7fc7..a5f32c4babf 100644 --- a/addons/website_event_track_live_quiz/static/src/js/website_event_track_suggestion.js +++ b/addons/website_event_track_live_quiz/static/src/js/website_event_track_suggestion.js @@ -3,7 +3,7 @@ import WebsiteEventTrackSuggestion from "website_event_track_live.website_event_track_suggestion"; var WebsiteEventTrackSuggestionLiveQuiz = WebsiteEventTrackSuggestion.include({ - events: _.extend({}, WebsiteEventTrackSuggestion.prototype.events, { + events: Object.assign({}, WebsiteEventTrackSuggestion.prototype.events, { 'click .owevent_track_suggestion_quiz': '_onQuizClick' }), diff --git a/addons/website_event_track_quiz/static/src/js/event_quiz.js b/addons/website_event_track_quiz/static/src/js/event_quiz.js index 9aba022c45b..53d9bc8c819 100644 --- a/addons/website_event_track_quiz/static/src/js/event_quiz.js +++ b/addons/website_event_track_quiz/static/src/js/event_quiz.js @@ -224,7 +224,7 @@ var Quiz = publicWidget.Widget.extend({ if (data.error) { self._alertShow(data.error); } else { - self.quiz = _.extend(self.quiz, data); + self.quiz = Object.assign(self.quiz, data); self.quiz.quizPointsGained = data.quiz_points; if (data.quiz_completed) { self._disableAnswers(); diff --git a/addons/website_links/static/src/js/website_links.js b/addons/website_links/static/src/js/website_links.js index 4ba6f592333..8b83635bf32 100644 --- a/addons/website_links/static/src/js/website_links.js +++ b/addons/website_links/static/src/js/website_links.js @@ -70,9 +70,7 @@ var SelectBox = publicWidget.Widget.extend({ * @param {String} query */ _objectExists: function (query) { - return _.find(this.objects, function (val) { - return val.text.toLowerCase() === query.toLowerCase(); - }) !== undefined; + return this.objects.find(val => val.text.toLowerCase() === query.toLowerCase()) !== undefined; }, /** * @private diff --git a/addons/website_payment/static/src/js/website_payment_form.js b/addons/website_payment/static/src/js/website_payment_form.js index 18f129aad78..599fe99e896 100644 --- a/addons/website_payment/static/src/js/website_payment_form.js +++ b/addons/website_payment/static/src/js/website_payment_form.js @@ -4,7 +4,7 @@ import core, { _t } from 'web.core'; import checkoutForm from 'payment.checkout_form'; checkoutForm.include({ - events: _.extend({}, checkoutForm.prototype.events || {}, { + events: Object.assign({}, checkoutForm.prototype.events || {}, { 'change .o_wpayment_fee_impact': '_onFeeParameterChange', }), diff --git a/addons/website_sale/static/src/js/website_sale.editor.js b/addons/website_sale/static/src/js/website_sale.editor.js index d4e0e77db08..d16ef7ada6c 100644 --- a/addons/website_sale/static/src/js/website_sale.editor.js +++ b/addons/website_sale/static/src/js/website_sale.editor.js @@ -304,7 +304,7 @@ options.registry.WebsiteSaleGridLayout = options.Class.extend({ }); options.registry.WebsiteSaleProductsItem = options.Class.extend({ - events: _.extend({}, options.Class.prototype.events || {}, { + events: Object.assign({}, options.Class.prototype.events || {}, { 'mouseenter .o_wsale_soptions_menu_sizes table': '_onTableMouseEnter', 'mouseleave .o_wsale_soptions_menu_sizes table': '_onTableMouseLeave', 'mouseover .o_wsale_soptions_menu_sizes td': '_onTableItemMouseEnter', diff --git a/addons/website_sale/static/src/js/website_sale.js b/addons/website_sale/static/src/js/website_sale.js index eb5eae1b5fa..9ca64ade91f 100644 --- a/addons/website_sale/static/src/js/website_sale.js +++ b/addons/website_sale/static/src/js/website_sale.js @@ -15,7 +15,7 @@ import { ProductImageViewerWrapper } from "@website_sale/js/components/website_s publicWidget.registry.WebsiteSale = publicWidget.Widget.extend(VariantMixin, cartHandlerMixin, { selector: '.oe_website_sale', - events: _.extend({}, VariantMixin.events || {}, { + events: Object.assign({}, VariantMixin.events || {}, { 'change form .js_product:first input[name="add_qty"]': '_onChangeAddQuantity', 'mouseup .js_publish': '_onMouseupPublish', 'touchend .js_publish': '_onMouseupPublish', diff --git a/addons/website_sale/static/src/snippets/s_add_to_cart/options.js b/addons/website_sale/static/src/snippets/s_add_to_cart/options.js index df241ebdd85..a65993dff89 100644 --- a/addons/website_sale/static/src/snippets/s_add_to_cart/options.js +++ b/addons/website_sale/static/src/snippets/s_add_to_cart/options.js @@ -25,7 +25,7 @@ const Many2oneDefaultMessageWidget = Many2oneUserValueWidget.extend({ options.userValueWidgetsRegistry['we-many2one-default-message'] = Many2oneDefaultMessageWidget; options.registry.AddToCart = options.Class.extend({ - events: _.extend({}, options.Class.prototype.events || {}, { + events: Object.assign({}, options.Class.prototype.events || {}, { 'click .reset-variant-picker': '_onClickResetVariantPicker', 'click .reset-product-picker': '_onClickResetProductPicker', }), diff --git a/addons/website_sale_comparison_wishlist/static/src/js/wishlist.js b/addons/website_sale_comparison_wishlist/static/src/js/wishlist.js index e9155c93473..1bedc2eafb6 100644 --- a/addons/website_sale_comparison_wishlist/static/src/js/wishlist.js +++ b/addons/website_sale_comparison_wishlist/static/src/js/wishlist.js @@ -4,7 +4,7 @@ import publicWidget from 'web.public.widget'; import 'website_sale_comparison.comparison'; publicWidget.registry.ProductComparison.include({ - events: _.extend({}, publicWidget.registry.ProductComparison.prototype.events, { + events: Object.assign({}, publicWidget.registry.ProductComparison.prototype.events, { 'click .wishlist-section .o_add_to_compare': '_onClickCompare', }), diff --git a/addons/website_sale_mondialrelay/static/src/js/website_sale_mondialrelay.js b/addons/website_sale_mondialrelay/static/src/js/website_sale_mondialrelay.js index ba33316a9d6..669898bb8cc 100644 --- a/addons/website_sale_mondialrelay/static/src/js/website_sale_mondialrelay.js +++ b/addons/website_sale_mondialrelay/static/src/js/website_sale_mondialrelay.js @@ -18,7 +18,7 @@ function corsIgnoredErrorHandler(env, error) { } WebsiteSaleDeliveryWidget.include({ - events: _.extend({ + events: Object.assign({ "click #btn_confirm_relay": "_onClickBtnConfirmRelay", }, WebsiteSaleDeliveryWidget.prototype.events), diff --git a/addons/website_sale_slides/static/src/js/slides_course_quiz.js b/addons/website_sale_slides/static/src/js/slides_course_quiz.js index 0ef9e58f000..0b0a4fd7e45 100644 --- a/addons/website_sale_slides/static/src/js/slides_course_quiz.js +++ b/addons/website_sale_slides/static/src/js/slides_course_quiz.js @@ -4,7 +4,7 @@ import {websiteSlidesQuizNoFullscreen} from "@website_slides/js/slides_course_qu websiteSlidesQuizNoFullscreen.include({ _extractChannelData: function (slideData) { - return _.extend({}, this._super.apply(this, arguments), { + return Object.assign({}, this._super.apply(this, arguments), { productId: slideData.productId, enroll: slideData.enroll, currencyName: slideData.currencyName, diff --git a/addons/website_slides/static/src/js/slides_course_fullscreen_player.js b/addons/website_slides/static/src/js/slides_course_fullscreen_player.js index 708b52e5613..ea6eb50ebdf 100644 --- a/addons/website_slides/static/src/js/slides_course_fullscreen_player.js +++ b/addons/website_slides/static/src/js/slides_course_fullscreen_player.js @@ -22,7 +22,7 @@ */ var findSlide = function (slideList, matcher) { var slideMatch = _.matcher(matcher); - return _.find(slideList, slideMatch); + return slideList.find(slide => slideMatch(slide)); }; /** @@ -494,10 +494,10 @@ * This widget is rendered sever side, and attached to the existing DOM. */ var Fullscreen = SlideCoursePage.extend({ - events: _.extend({}, SlideCoursePage.prototype.events, { + events: Object.assign({}, SlideCoursePage.prototype.events, { 'click .o_wslides_fs_toggle_sidebar': '_onClickToggleSidebar', }), - custom_events: _.extend({}, SlideCoursePage.prototype.custom_events, { + custom_events: Object.assign({}, SlideCoursePage.prototype.custom_events, { 'change_slide': '_onChangeSlideRequest', 'slide_go_next': '_onSlideGoToNext', }), diff --git a/addons/website_slides/static/src/js/slides_course_quiz.js b/addons/website_slides/static/src/js/slides_course_quiz.js index dc879bad900..8b7f8a1291a 100644 --- a/addons/website_slides/static/src/js/slides_course_quiz.js +++ b/addons/website_slides/static/src/js/slides_course_quiz.js @@ -690,7 +690,7 @@ publicWidget.registry.websiteSlidesQuizNoFullscreen = SlideCoursePage.extend({ selector: '.o_wslides_lesson_main', // selector of complete page, as we need slide content and aside content table - custom_events: _.extend({}, SlideCoursePage.prototype.custom_events, { + custom_events: Object.assign({}, SlideCoursePage.prototype.custom_events, { slide_go_next: '_onQuizNextSlide', }), diff --git a/addons/website_slides/static/src/js/slides_course_tag_add.js b/addons/website_slides/static/src/js/slides_course_tag_add.js index fa1df40f810..29d69576db8 100644 --- a/addons/website_slides/static/src/js/slides_course_tag_add.js +++ b/addons/website_slides/static/src/js/slides_course_tag_add.js @@ -6,7 +6,7 @@ import publicWidget from 'web.public.widget'; var TagCourseDialog = Dialog.extend({ template: 'website.slides.tag.add', - events: _.extend({}, Dialog.prototype.events, { + events: Object.assign({}, Dialog.prototype.events, { 'change input#tag_id' : '_onChangeTag', }), diff --git a/addons/website_slides/static/src/js/slides_upload.js b/addons/website_slides/static/src/js/slides_upload.js index 88c5cce28d9..7ff32dc4680 100644 --- a/addons/website_slides/static/src/js/slides_upload.js +++ b/addons/website_slides/static/src/js/slides_upload.js @@ -8,7 +8,7 @@ import wUtils from 'website.utils'; var SlideUploadDialog = Dialog.extend({ template: 'website.slide.upload.modal', - events: _.extend({}, Dialog.prototype.events, { + events: Object.assign({}, Dialog.prototype.events, { 'click .o_wslides_js_upload_install_button': '_onClickInstallModule', 'click .o_wslides_select_category': '_onClickSlideCategoryIcon', 'change input#upload': '_onChangeSlideUpload', @@ -156,7 +156,7 @@ var SlideUploadDialog = Dialog.extend({ } else { sourceType = this.$('input[name="source_type"]:checked').data('value'); } - var values = _.extend({ + var values = Object.assign({ 'channel_id': this.channelID, 'description': this._formGetFieldValue('description'), 'document_google_url': this._formGetFieldValue('document_google_url'), @@ -171,17 +171,17 @@ var SlideUploadDialog = Dialog.extend({ var canvas = this.$('#data_canvas')[0]; if (this.file.type === 'application/pdf') { - _.extend(values, { + Object.assign(values, { 'image_1920': canvas.toDataURL().split(',')[1], 'slide_category': 'document', 'binary_content': this.file.data }); } else if (values['slide_category'] === 'article') { - _.extend(values, { + Object.assign(values, { 'image_1920': this.file.type === 'image/svg+xml' ? await this._svgToPng() : this.file.data, }); } else if (/^image\/.*/.test(this.file.type)) { - _.extend(values, { + Object.assign(values, { 'slide_category': 'infographic', 'binary_content': this.file.type === 'image/svg+xml' ? await this._svgToPNG() : this.file.data, }); @@ -656,7 +656,7 @@ var SlideUploadDialog = Dialog.extend({ .text(_.str.sprintf(_t('Failed to install "%s".'), this.modulesToInstallStatus.name)); } } else { - this.modulesToInstallStatus = _.extend({}, _.find(this.modulesToInstall, function (item) { return item.id === moduleId; })); + this.modulesToInstallStatus = Object.assign({}, this.modulesToInstall.find( function (item) { return item.id === moduleId; })); this.set('state', '_import'); this.$('#o_wslides_install_module_text') .text(_.str.sprintf(_t('Do you want to install the "%s" app?'), this.modulesToInstallStatus.name)); diff --git a/addons/website_slides_survey/static/src/js/slides_upload.js b/addons/website_slides_survey/static/src/js/slides_upload.js index 797794f3765..5afc3363288 100644 --- a/addons/website_slides_survey/static/src/js/slides_upload.js +++ b/addons/website_slides_survey/static/src/js/slides_upload.js @@ -8,7 +8,7 @@ import SlidesUpload from "@website_slides/js/slides_upload"; * Management of the new 'certification' slide_category */ SlidesUpload.SlideUploadDialog.include({ - events: _.extend({}, SlidesUpload.SlideUploadDialog.prototype.events || {}, { + events: Object.assign({}, SlidesUpload.SlideUploadDialog.prototype.events || {}, { 'change input#certification_id': '_onChangeCertification' }),