From ab56e637b7f97ddcdbcc9baea99ae097e342409c Mon Sep 17 00:00:00 2001 From: Vincent Schippefilt Date: Wed, 6 Mar 2019 14:02:32 +0100 Subject: [PATCH] [REF] web: adapt code after jQuery update Part of task 1896658 Co-authored-by: Aaron Bohy Co-authored-by: Christophe Matthieu Co-authored-by: Mathieu Duckerts-Antoine Co-authored-by: David Monjoie Co-authored-by: Martin Geubelle Co-authored-by: svs-odoo Co-authored-by: Vincent Schippefilt --- addons/web/doc/client_action.rst | 7 +- addons/web/static/src/js/_deprecated/data.js | 75 +- addons/web/static/src/js/apps.js | 103 +- addons/web/static/src/js/boot.js | 108 +- .../static/src/js/chrome/abstract_action.js | 4 +- .../src/js/chrome/abstract_web_client.js | 11 +- .../static/src/js/chrome/action_manager.js | 73 +- .../js/chrome/action_manager_act_window.js | 105 +- .../src/js/chrome/action_manager_report.js | 57 +- .../web/static/src/js/chrome/action_mixin.js | 8 +- addons/web/static/src/js/chrome/loading.js | 2 + addons/web/static/src/js/chrome/menu.js | 12 +- addons/web/static/src/js/chrome/pager.js | 7 +- addons/web/static/src/js/chrome/sidebar.js | 2 +- .../web/static/src/js/chrome/systray_menu.js | 9 +- addons/web/static/src/js/chrome/user_menu.js | 8 +- addons/web/static/src/js/chrome/web_client.js | 65 +- addons/web/static/src/js/core/ajax.js | 345 +- addons/web/static/src/js/core/concurrency.js | 239 +- addons/web/static/src/js/core/dialog.js | 10 +- addons/web/static/src/js/core/dom.js | 21 +- addons/web/static/src/js/core/misc.js | 4 +- addons/web/static/src/js/core/mixins.js | 31 +- addons/web/static/src/js/core/mvc.js | 11 +- addons/web/static/src/js/core/rpc.js | 2 +- .../web/static/src/js/core/service_mixins.js | 92 +- addons/web/static/src/js/core/session.js | 68 +- addons/web/static/src/js/core/translation.js | 4 +- addons/web/static/src/js/core/widget.js | 34 +- .../static/src/js/fields/abstract_field.js | 49 +- .../web/static/src/js/fields/basic_fields.js | 23 +- .../static/src/js/fields/field_registry.js | 2 +- .../static/src/js/fields/relational_fields.js | 257 +- .../static/src/js/fields/upgrade_fields.js | 2 +- .../web/static/src/js/public/public_root.js | 14 +- .../web/static/src/js/public/public_widget.js | 6 +- .../web/static/src/js/report/client_action.js | 4 +- .../static/src/js/services/ajax_service.js | 25 +- addons/web/static/src/js/services/core.js | 12 +- .../static/src/js/services/crash_manager.js | 2 +- .../static/src/js/services/data_manager.js | 16 +- .../static/src/js/services/report_service.js | 2 +- .../web/static/src/js/tools/debug_manager.js | 13 +- addons/web/static/src/js/tools/test_menus.js | 109 +- .../src/js/views/abstract_controller.js | 75 +- .../web/static/src/js/views/abstract_model.js | 2 +- .../static/src/js/views/abstract_renderer.js | 14 +- .../web/static/src/js/views/abstract_view.js | 7 +- .../src/js/views/basic/basic_controller.js | 112 +- .../static/src/js/views/basic/basic_model.js | 423 +-- .../src/js/views/basic/basic_renderer.js | 63 +- .../static/src/js/views/basic/basic_view.js | 4 +- .../js/views/calendar/calendar_controller.js | 12 +- .../src/js/views/calendar/calendar_model.js | 49 +- .../js/views/calendar/calendar_renderer.js | 46 +- .../control_panel/control_panel_controller.js | 6 +- .../control_panel/control_panel_model.js | 14 +- .../control_panel/control_panel_renderer.js | 14 +- .../views/control_panel/search/filter_menu.js | 4 +- .../views/control_panel/search/search_bar.js | 19 +- .../search/search_bar_autocomplete_sources.js | 24 +- .../control_panel/search/search_filters.js | 8 +- .../src/js/views/field_manager_mixin.js | 16 +- .../src/js/views/form/form_controller.js | 51 +- .../static/src/js/views/form/form_renderer.js | 129 +- .../web/static/src/js/views/form/form_view.js | 4 +- .../static/src/js/views/graph/graph_model.js | 10 +- .../src/js/views/graph/graph_renderer.js | 2 +- .../src/js/views/kanban/kanban_column.js | 13 +- .../src/js/views/kanban/kanban_controller.js | 39 +- .../src/js/views/kanban/kanban_model.js | 33 +- .../src/js/views/kanban/kanban_record.js | 49 +- .../kanban/kanban_record_quick_create.js | 21 +- .../src/js/views/kanban/kanban_renderer.js | 64 +- .../js/views/kanban/kanban_renderer_mobile.js | 53 +- .../static/src/js/views/kanban/kanban_view.js | 2 +- .../js/views/kanban/quick_create_form_view.js | 2 +- .../src/js/views/kanban/search_panel.js | 30 +- .../src/js/views/list/list_controller.js | 49 +- .../js/views/list/list_editable_renderer.js | 122 +- .../static/src/js/views/list/list_renderer.js | 92 +- .../static/src/js/views/pivot/pivot_model.js | 23 +- .../src/js/views/pivot/pivot_renderer.js | 2 +- .../views/standalone_field_manager_mixin.js | 2 +- .../web/static/src/js/views/view_dialogs.js | 19 +- addons/web/static/src/js/views/view_utils.js | 2 +- .../static/src/js/widgets/attach_document.js | 41 +- .../static/src/js/widgets/change_password.js | 4 +- .../web/static/src/js/widgets/data_export.js | 38 +- .../static/src/js/widgets/domain_selector.js | 25 +- .../src/js/widgets/domain_selector_dialog.js | 4 +- .../static/src/js/widgets/iframe_widget.js | 2 +- .../src/js/widgets/model_field_selector.js | 24 +- .../src/js/widgets/name_and_signature.js | 10 +- addons/web/static/src/js/widgets/pie_chart.js | 2 +- .../src/js/widgets/switch_company_menu.js | 12 +- .../chrome/action_manager_mobile_tests.js | 22 +- .../tests/chrome/action_manager_tests.js | 1072 +++--- .../chrome/keyboard_navigation_mixin_tests.js | 16 +- addons/web/static/tests/chrome/pager_tests.js | 36 +- .../static/tests/chrome/user_menu_tests.js | 4 +- .../static/tests/core/concurrency_tests.js | 661 ++-- addons/web/static/tests/core/dom_tests.js | 6 +- addons/web/static/tests/core/mixins_tests.js | 6 +- addons/web/static/tests/core/widget_tests.js | 99 +- .../tests/fields/basic_fields_mobile_tests.js | 28 +- .../static/tests/fields/basic_fields_tests.js | 1187 +++--- .../field_many2many_tests.js | 233 +- .../relational_fields/field_many2one_tests.js | 1078 +++--- .../relational_fields/field_one2many_tests.js | 2021 +++++----- .../fields/relational_fields_mobile_tests.js | 12 +- .../tests/fields/relational_fields_tests.js | 747 ++-- .../web/static/tests/fields/special_fields.js | 29 +- .../tests/fields/upgrade_fields_tests.js | 10 +- .../web/static/tests/helpers/mock_server.js | 71 +- .../web/static/tests/helpers/qunit_asserts.js | 17 +- .../web/static/tests/helpers/qunit_config.js | 58 + addons/web/static/tests/helpers/test_utils.js | 85 +- .../static/tests/helpers/test_utils_create.js | 94 +- .../static/tests/helpers/test_utils_dom.js | 78 +- .../static/tests/helpers/test_utils_fields.js | 104 +- .../static/tests/helpers/test_utils_file.js | 35 +- .../static/tests/helpers/test_utils_form.js | 10 +- .../static/tests/helpers/test_utils_graph.js | 2 +- .../static/tests/helpers/test_utils_kanban.js | 15 +- .../static/tests/helpers/test_utils_mock.js | 31 +- .../static/tests/helpers/test_utils_modal.js | 2 + .../static/tests/helpers/test_utils_pivot.js | 6 +- addons/web/static/tests/qweb_tests.js | 26 +- .../services/notification_service_tests.js | 126 +- .../static/tests/tools/debug_manager_tests.js | 32 +- .../tests/views/abstract_controller_tests.js | 155 +- .../tests/views/abstract_view_banner_tests.js | 6 +- .../static/tests/views/abstract_view_tests.js | 60 +- .../static/tests/views/basic_model_tests.js | 3265 ++++++++--------- .../tests/views/calendar_mobile_tests.js | 6 +- .../web/static/tests/views/calendar_tests.js | 658 ++-- .../static/tests/views/control_panel_tests.js | 12 +- addons/web/static/tests/views/form_tests.js | 1893 +++++----- addons/web/static/tests/views/graph_tests.js | 171 +- .../static/tests/views/kanban_mobile_tests.js | 30 +- .../static/tests/views/kanban_model_tests.js | 33 +- addons/web/static/tests/views/kanban_tests.js | 1220 +++--- addons/web/static/tests/views/list_tests.js | 1099 +++--- .../tests/views/mobile_control_panel_tests.js | 12 +- addons/web/static/tests/views/pivot_tests.js | 439 ++- addons/web/static/tests/views/qweb_tests.js | 21 +- .../tests/views/search_filter_menu_tests.js | 109 +- .../tests/views/search_groupby_menu_tests.js | 54 +- .../static/tests/views/search_panel_tests.js | 258 +- .../static/tests/views/search_view_tests.js | 431 ++- .../static/tests/views/view_dialogs_tests.js | 116 +- .../static/tests/widgets/data_export_tests.js | 50 +- .../tests/widgets/domain_selector_tests.js | 43 +- .../tests/widgets/dropdown_menu_tests.js | 60 +- .../widgets/model_field_selector_tests.js | 40 +- 156 files changed, 11415 insertions(+), 10825 deletions(-) diff --git a/addons/web/doc/client_action.rst b/addons/web/doc/client_action.rst index 9b729e228a6..4852400df10 100644 --- a/addons/web/doc/client_action.rst +++ b/addons/web/doc/client_action.rst @@ -83,18 +83,19 @@ method. As required by :js:class:`~openerp.web.Widget`'s contract, if :js:func:`~openerp.web.Widget.start()` executes any asynchronous - code it should return a ``$.Deferred`` so callers know when it's + code it should return a ``Promise`` so callers know when it's ready for interaction. .. code-block:: javascript start: function () { - return $.when( + return Promise.all([ this._super(), // Simply read the res.widget object this action should display new instance.web.Model('res.widget').call( 'read', [[this.widget_id], ['title']]) - .then(this.proxy('on_widget_loaded')); + .then(this.proxy('on_widget_loaded') + ]); } The client action can then behave exactly as it wishes to within its diff --git a/addons/web/static/src/js/_deprecated/data.js b/addons/web/static/src/js/_deprecated/data.js index 984f0bbaddb..acac959fcc8 100644 --- a/addons/web/static/src/js/_deprecated/data.js +++ b/addons/web/static/src/js/_deprecated/data.js @@ -101,7 +101,7 @@ var Query = Class.extend({ * Fetches the first record matching the query, or null * * @param {Object} [options] additional options for the rpc() method - * @returns {jQuery.Deferred} + * @returns {Promise} */ first: function (options) { var self = this; @@ -115,7 +115,7 @@ var Query = Class.extend({ * Fetches all records matching the query * * @param {Object} [options] additional options for the rpc() method - * @returns {jQuery.Deferred>} + * @returns {Promise>} */ all: function (options) { return this._execute(options); @@ -123,10 +123,10 @@ var Query = Class.extend({ /** * Fetches the number of records matching the query in the database * - * @returns {jQuery.Deferred} + * @returns {Promise} */ count: function () { - if (this._count !== undefined) { return $.when(this._count); } + if (this._count !== undefined) { return Promise.resolve(this._count); } return this._model.call( 'search_count', [this._filter], { context: this._model.context(this._context)}); @@ -367,11 +367,12 @@ var DataSet = Class.extend(mixins.PropertiesMixin, { * @param {Array} ids identifiers of the records to read * @param {Array} [fields] fields to read and return, by default all fields are returned * @param {Object} [options] - * @returns {$.Deferred} + * @returns {Promise} */ read_ids: function (ids, fields, options) { - if (_.isEmpty(ids)) - return $.Deferred().resolve([]); + if (_.isEmpty(ids)) { + return Promise.resolve([]); + } options = options || {}; var method = 'read'; @@ -405,7 +406,7 @@ var DataSet = Class.extend(mixins.PropertiesMixin, { * @params {Object} [options] * @param {Number} [options.offset=0] The index from which selected records should be returned * @param {Number} [options.limit=null] The maximum number of records to return - * @returns {$.Deferred} + * @returns {Promise} */ read_slice: function (fields, options) { var self = this; @@ -414,21 +415,23 @@ var DataSet = Class.extend(mixins.PropertiesMixin, { .limit(options.limit || false) .offset(options.offset || 0) .all(); - return this.orderer.add(query).done(function (records) { + var prom = this.orderer.add(query); + prom.then(function (records) { self.ids = _(records).pluck('id'); }); + return prom; }, /** * Reads the current dataset record (from its index) * * @params {Array} [fields] fields to read and return, by default all fields are returned * @param {Object} [options.context] context data to add to the request payload, on top of the DataSet's own context - * @returns {$.Deferred} + * @returns {Promise} */ read_index: function (fields, options) { options = options || {}; return this.read_ids([this.ids[this.index]], fields, options).then(function (records) { - if (_.isEmpty(records)) { return $.Deferred().reject().promise(); } + if (_.isEmpty(records)) { return Promise.reject(); } return records[0]; }); }, @@ -437,7 +440,7 @@ var DataSet = Class.extend(mixins.PropertiesMixin, { * * @param {Array} [fields] fields to get default values for, by default all defaults are read * @param {Object} [options.context] context data to add to the request payload, on top of the DataSet's own context - * @returns {$.Deferred} + * @returns {Promise} */ default_get: function (fields, options) { options = options || {}; @@ -451,15 +454,17 @@ var DataSet = Class.extend(mixins.PropertiesMixin, { * @param {Object} options Dictionary that can contain the following keys: * - readonly_fields: Values from readonly fields that were updated by * on_changes. Only used by the BufferedDataSet to make the o2m work correctly. - * @returns {$.Deferred} + * @returns {Promise} */ create: function (data, options) { var self = this; - return this._model.call('create', [data], { + var prom = this._model.call('create', [data], { context: this.get_context() - }).done(function () { + }); + prom.then(function () { self.trigger('dataset_changed', data, options); }); + return prom; }, /** * Saves the provided data in an existing db record @@ -470,16 +475,18 @@ var DataSet = Class.extend(mixins.PropertiesMixin, { * - context: The context to use in the server-side call. * - readonly_fields: Values from readonly fields that were updated by * on_changes. Only used by the BufferedDataSet to make the o2m work correctly. - * @returns {$.Deferred} + * @returns {Promise} */ write: function (id, data, options) { options = options || {}; var self = this; - return this._model.call('write', [[id], data], { + var prom = this._model.call('write', [[id], data], { context: this.get_context(options.context) - }).done(function () { + }); + prom.then(function () { self.trigger('dataset_changed', id, data, options); }); + return prom; }, /** * Deletes an existing record from the database @@ -488,11 +495,13 @@ var DataSet = Class.extend(mixins.PropertiesMixin, { */ unlink: function (ids) { var self = this; - return this._model.call('unlink', [ids], { + var prom = this._model.call('unlink', [ids], { context: this.get_context() - }).done(function () { + }); + prom.then(function () { self.trigger('dataset_changed', ids); }); + return prom; }, /** * Calls an arbitrary RPC method @@ -501,7 +510,7 @@ var DataSet = Class.extend(mixins.PropertiesMixin, { * @param {Array} [args] arguments to pass to the method * @param {Function} callback * @param {Function} error_callback - * @returns {$.Deferred} + * @returns {Promise} */ call: function (method, args) { return this._model.call(method, args); @@ -511,7 +520,7 @@ var DataSet = Class.extend(mixins.PropertiesMixin, { * * @param {String} method * @param {Array} [args] - * @returns {$.Deferred} + * @returns {Promise} */ call_button: function (method, args) { return this._model.call_button(method, args); @@ -520,7 +529,7 @@ var DataSet = Class.extend(mixins.PropertiesMixin, { * Fetches the "readable name" for records, based on intrinsic rules * * @param {Array} ids - * @returns {$.Deferred} + * @returns {Promise} */ name_get: function (ids) { return this._model.call('name_get', [ids], {context: this.get_context()}); @@ -532,7 +541,7 @@ var DataSet = Class.extend(mixins.PropertiesMixin, { * @param {String} [operator='ilike'] matching operator to use with the provided name value * @param {Number} [limit=0] maximum number of matches to return * @param {Function} callback function to call with name_search result - * @returns {$.Deferred} + * @returns {Promise} */ name_search: function (name, domain, operator, limit) { return this._model.call('name_search', { @@ -603,7 +612,7 @@ var DataSet = Class.extend(mixins.PropertiesMixin, { * Resequence records. * * @param {Array} ids identifiers of the records to resequence - * @returns {$.Deferred} + * @returns {Promise} */ resequence: function (ids, options) { options = options || {}; @@ -643,7 +652,7 @@ var DataSetStatic = DataSet.extend({ unlink: function (ids) { this.set_ids(_.without.apply(null, [this.ids].concat(ids))); this.trigger('unlink', ids); - return $.Deferred().resolve({result: true}); + return Promise.resolve({result: true}); }, }); @@ -674,7 +683,7 @@ var DataSetSearch = DataSet.extend({ * @param {Array} [options.domain] domain data to add to the request payload, ANDed with the dataset's domain * @param {Number} [options.offset=0] The index from which selected records should be returned * @param {Number} [options.limit=null] The maximum number of records to return - * @returns {$.Deferred} + * @returns {Promise} */ read_slice: function (fields, options) { options = options || {}; @@ -686,11 +695,13 @@ var DataSetSearch = DataSet.extend({ .limit(options.limit || false); q = q.order_by.apply(q, this._sort); - return this.orderer.add(q.all()).done(function (records) { + var prom = this.orderer.add(q.all()); + prom.then(function (records) { // FIXME: not sure about that one, *could* have discarded count - q.count().done(function (count) { self._length = count; }); + q.count().then(function (count) { self._length = count; }); self.ids = _(records).pluck('id'); }); + return prom; }, get_domain: function (other_domain) { return this._model.domain(other_domain); @@ -717,10 +728,12 @@ var DataSetSearch = DataSet.extend({ }, unlink: function (ids, callback, error_callback) { var self = this; - return this._super(ids).done(function () { + var prom = this._super(ids); + prom.then(function () { self.remove_ids( ids); self.trigger("dataset_changed", ids, callback, error_callback); }); + return prom; }, size: function () { if (this._length !== null) { @@ -801,7 +814,7 @@ var Model = Class.extend({ * @param {Array} [args] positipyEvalonal arguments * @param {Object} [kwargs] keyword arguments * @param {Object} [options] additional options for the rpc() method - * @returns {jQuery.Deferred<>} call result + * @returns {Promise<>} call result */ call: function (method, args, kwargs, options) { args = args || []; diff --git a/addons/web/static/src/js/apps.js b/addons/web/static/src/js/apps.js index aadcc700984..739317337ba 100644 --- a/addons/web/static/src/js/apps.js +++ b/addons/web/static/src/js/apps.js @@ -22,20 +22,21 @@ var Apps = AbstractAction.extend({ }, get_client: function() { - // return the client via a deferred, resolved or rejected depending if + // return the client via a promise, resolved or rejected depending if // the remote host is available or not. var check_client_available = function(client) { - var d = $.Deferred(); var i = new Image(); - i.onerror = function() { - d.reject(client); - }; - i.onload = function() { - d.resolve(client); - }; + var def = new Promise(function (resolve, reject) { + i.onerror = function() { + reject(client); + }; + i.onload = function() { + resolve(client); + }; + }); var ts = new Date().getTime(); i.src = _.str.sprintf('%s/web/static/src/img/sep-a.gif?%s', client.origin, ts); - return d.promise(); + return def; }; if (apps_client) { return check_client_available(apps_client); @@ -105,58 +106,56 @@ var Apps = AbstractAction.extend({ start: function() { var self = this; - var def = $.Deferred(); - self.get_client().then(function(client) { - self.client = client; + return new Promise(function (resolve, reject) { + self.get_client().then(function (client) { + self.client = client; - var qs = {db: client.dbname}; - if (session.debug) { - qs.debug = session.debug; - } - var u = $.param.querystring(client.origin + "/apps/embed/client", qs); - var css = {width: '100%', height: '750px'}; - self.$ifr = $('