diff options
| author | Vincent Schippefilt <vsc@odoo.com> | 2019-03-06 14:02:32 +0100 |
|---|---|---|
| committer | Aaron Bohy <aab@odoo.com> | 2019-03-06 20:07:17 +0100 |
| commit | ab56e637b7f97ddcdbcc9baea99ae097e342409c (patch) | |
| tree | 4cb47da9f7ef89b19d18429220a7507470ec12a9 /addons/web/static/src/js/chrome | |
| parent | eeed894fd50e477135e1ac9a82f6e98ce063ab90 (diff) | |
[REF] web: adapt code after jQuery update
Part of task 1896658
Co-authored-by: Aaron Bohy <aab@odoo.com>
Co-authored-by: Christophe Matthieu <chm@odoo.com>
Co-authored-by: Mathieu Duckerts-Antoine <dam@odoo.com>
Co-authored-by: David Monjoie <dmo@odoo.com>
Co-authored-by: Martin Geubelle <mge@odoo.com>
Co-authored-by: svs-odoo <svs@odoo.com>
Co-authored-by: Vincent Schippefilt <vsc@odoo.com>
Diffstat (limited to 'addons/web/static/src/js/chrome')
| -rw-r--r-- | addons/web/static/src/js/chrome/abstract_action.js | 4 | ||||
| -rw-r--r-- | addons/web/static/src/js/chrome/abstract_web_client.js | 11 | ||||
| -rw-r--r-- | addons/web/static/src/js/chrome/action_manager.js | 73 | ||||
| -rw-r--r-- | addons/web/static/src/js/chrome/action_manager_act_window.js | 105 | ||||
| -rw-r--r-- | addons/web/static/src/js/chrome/action_manager_report.js | 57 | ||||
| -rw-r--r-- | addons/web/static/src/js/chrome/action_mixin.js | 8 | ||||
| -rw-r--r-- | addons/web/static/src/js/chrome/loading.js | 2 | ||||
| -rw-r--r-- | addons/web/static/src/js/chrome/menu.js | 12 | ||||
| -rw-r--r-- | addons/web/static/src/js/chrome/pager.js | 7 | ||||
| -rw-r--r-- | addons/web/static/src/js/chrome/sidebar.js | 2 | ||||
| -rw-r--r-- | addons/web/static/src/js/chrome/systray_menu.js | 9 | ||||
| -rw-r--r-- | addons/web/static/src/js/chrome/user_menu.js | 8 | ||||
| -rw-r--r-- | addons/web/static/src/js/chrome/web_client.js | 65 |
13 files changed, 193 insertions, 170 deletions
diff --git a/addons/web/static/src/js/chrome/abstract_action.js b/addons/web/static/src/js/chrome/abstract_action.js index a5f98434ddb..1b258ccc6f6 100644 --- a/addons/web/static/src/js/chrome/abstract_action.js +++ b/addons/web/static/src/js/chrome/abstract_action.js @@ -104,7 +104,7 @@ var AbstractAction = Widget.extend(ActionMixin, { }; }); } - return $.when(def).then(function () { + return Promise.resolve(def).then(function () { var controlPanelView = new self.config.ControlPanelView(params); return controlPanelView.getController(self).then(function (controlPanel) { self._controlPanel = controlPanel; @@ -112,7 +112,7 @@ var AbstractAction = Widget.extend(ActionMixin, { }); }); } - return $.when(); + return Promise.resolve(); }, /** * @override diff --git a/addons/web/static/src/js/chrome/abstract_web_client.js b/addons/web/static/src/js/chrome/abstract_web_client.js index 7082f26e69d..68ac157868d 100644 --- a/addons/web/static/src/js/chrome/abstract_web_client.js +++ b/addons/web/static/src/js/chrome/abstract_web_client.js @@ -78,7 +78,7 @@ var AbstractWebClient = Widget.extend(ServiceProviderMixin, KeyboardNavigationMi if (event.data.on_success) { event.data.on_success(result); } - }).fail(function (result) { + }).guardedCatch(function (result) { if (event.data.on_fail) { event.data.on_fail(result); } @@ -116,17 +116,17 @@ var AbstractWebClient = Widget.extend(ServiceProviderMixin, KeyboardNavigationMi .then(function () { self.$el.toggleClass('o_rtl', _t.database.parameters.direction === "rtl"); self.bind_events(); - return $.when( + return Promise.all([ self.set_action_manager(), self.set_loading() - ); + ]); }).then(function () { if (session.session_is_valid()) { return self.show_application(); } else { // database manager needs the webclient to keep going even // though it has no valid session - return $.when(); + return Promise.resolve(); } }).then(function () { // Listen to 'scroll' event and propagate it on main bus @@ -145,12 +145,13 @@ var AbstractWebClient = Widget.extend(ServiceProviderMixin, KeyboardNavigationMi this.$el.on('mouseenter', '.oe_systray > div:not([data-toggle=tooltip])', function () { $(this).attr('data-toggle', 'tooltip').tooltip().trigger('mouseenter'); }); + // TODO: this handler seems useless since 11.0, should be removed this.$el.on('click', '.oe_dropdown_toggle', function (ev) { ev.preventDefault(); var $toggle = $(this); var doc_width = $(document).width(); var $menu = $toggle.siblings('.oe_dropdown_menu'); - $menu = $menu.size() >= 1 ? $menu : $toggle.find('.oe_dropdown_menu'); + $menu = $menu.length >= 1 ? $menu : $toggle.find('.oe_dropdown_menu'); var state = $menu.is('.oe_opened'); setTimeout(function () { // Do not alter propagation diff --git a/addons/web/static/src/js/chrome/action_manager.js b/addons/web/static/src/js/chrome/action_manager.js index 107c6e314eb..0537b45deb5 100644 --- a/addons/web/static/src/js/chrome/action_manager.js +++ b/addons/web/static/src/js/chrome/action_manager.js @@ -92,7 +92,7 @@ var ActionManager = Widget.extend({ * will be restored. It ensures that the current controller can be left (for * instance, that it has no unsaved changes). * - * @returns {Deferred} resolved if the current controller can be left, + * @returns {Promise} resolved if the current controller can be left, * rejected otherwise. */ clearUncommittedChanges: function () { @@ -100,7 +100,7 @@ var ActionManager = Widget.extend({ if (currentController) { return currentController.widget.canBeRemoved(); } - return $.when(); + return Promise.resolve(); }, /** * This is the entry point to execute Odoo actions, given as an ID in @@ -123,7 +123,7 @@ var ActionManager = Widget.extend({ * is useful when we come from a loadState()) * @param {boolean} [options.replace_last_action=false] set to true to * replace last part of the breadcrumbs with the action - * @return {$.Deferred<Object>} resolved with the action when the action is + * @return {Promise<Object>} resolved with the action when the action is * loaded and appended to the DOM ; rejected if the action can't be * executed (e.g. if doAction has been called to execute another action * before this one was complete). @@ -155,7 +155,7 @@ var ActionManager = Widget.extend({ }); } - return this.dp.add($.when(def)).then(function () { + return this.dp.add(Promise.resolve(def)).then(function () { // action.target 'main' is equivalent to 'current' except that it // also clears the breadcrumbs options.clear_breadcrumbs = action.target === 'main' || @@ -211,12 +211,12 @@ var ActionManager = Widget.extend({ * @param {Object} state * @param {integer|string} [state.action] the action to execute (given its * id or tag for client actions) - * @returns {Deferred} resolved when the UI has been updated + * @returns {Promise} resolved when the UI has been updated */ loadState: function (state) { var action; if (!state.action) { - return $.when(); + return Promise.resolve(); } if (_.isString(state.action) && core.action_registry.contains(state.action)) { action = { @@ -299,7 +299,7 @@ var ActionManager = Widget.extend({ * @param {string} [action.target="current"] set to "new" to render the * controller in a dialog * @param {Object} options @see doAction for details - * @returns {Deferred} resolved when the controller is started and appended + * @returns {Promise} resolved when the controller is started and appended */ _executeAction: function (action, options) { var self = this; @@ -338,7 +338,7 @@ var ActionManager = Widget.extend({ return action; }) - .fail(function () { + .guardedCatch(function () { self._removeAction(action.jsID); }); }, @@ -349,7 +349,7 @@ var ActionManager = Widget.extend({ * @private * @param {Object} action * @param {Object} options @see doAction for details - * @returns {Deferred} resolved when the controller is rendered inside a + * @returns {Promise} resolved when the controller is rendered inside a * dialog appended to the DOM */ _executeActionInDialog: function (action, options) { @@ -401,7 +401,7 @@ var ActionManager = Widget.extend({ return action; }); - }).fail(function () { + }).guardedCatch(function () { self._removeAction(action.jsID); }); }, @@ -412,14 +412,14 @@ var ActionManager = Widget.extend({ * @param {Object} action the description of the action to execute * @param {string} action.tag the key of the action in the action_registry * @param {Object} options @see doAction for details - * @returns {Deferred} resolved when the client action has been executed + * @returns {Promise} resolved when the client action has been executed */ _executeClientAction: function (action, options) { var self = this; var ClientAction = core.action_registry.get(action.tag); if (!ClientAction) { console.error("Could not find client action " + action.tag, action); - return $.Deferred().reject(); + return Promise.reject(); } if (!(ClientAction.prototype instanceof AbstractAction)) { console.warn('The client action ' + action.tag + ' should be an instance of AbstractAction!'); @@ -431,7 +431,7 @@ var ActionManager = Widget.extend({ if (next) { return this.doAction(next, options); } - return $.when(); + return Promise.resolve(); } var controllerID = _.uniqueId('controller_'); @@ -449,12 +449,14 @@ var ActionManager = Widget.extend({ }; this.controllers[controllerID] = controller; action.controllerID = controllerID; - return this._executeAction(action, options).done(function () { + var prom = this._executeAction(action, options); + prom.then(function () { // AAB: this should be done automatically in AbstractAction, so that // it can be overriden by actions that have specific stuff to push // (e.g. Discuss, Views) self._pushState(controllerID, {}); }); + return prom; }, /** * Executes actions of type 'ir.actions.act_window_close', i.e. closes the @@ -469,7 +471,7 @@ var ActionManager = Widget.extend({ * @param {Object} [action.effect] effect to show up, e.g. rainbow man. * @param {Object} [action.infos] infos on performing the close action. * Useful for providing some context for the `on_close` handler. - * @returns {Deferred} resolved immediately + * @returns {Promise} resolved immediately */ _executeCloseAction: function (action, options) { var result; @@ -484,7 +486,7 @@ var ActionManager = Widget.extend({ this.trigger_up('show_effect', action.effect); } - return $.when(result); + return Promise.resolve(result); }, /** * Executes actions of type 'ir.actions.server'. @@ -494,7 +496,7 @@ var ActionManager = Widget.extend({ * @param {integer} action.id the db ID of the action to execute * @param {Object} [action.context] * @param {Object} options @see doAction for details - * @returns {Deferred} resolved when the action has been executed + * @returns {Promise} resolved when the action has been executed */ _executeServerAction: function (action, options) { var self = this; @@ -520,7 +522,7 @@ var ActionManager = Widget.extend({ * @param {string} [action.target] set to 'self' to redirect in the current page, * redirects to a new page by default * @param {Object} options @see doAction for details - * @returns {Deferred} resolved when the redirection is done (immediately + * @returns {Promise} resolved when the redirection is done (immediately * when redirecting to a new page) */ _executeURLAction: function (action, options) { @@ -531,7 +533,7 @@ var ActionManager = Widget.extend({ if (action.target === 'self') { framework.redirect(url); - return $.Deferred(); + return Promise.resolve(); } else { var w = window.open(url, '_blank'); if (!w || w.closed || typeof w.closed === 'undefined') { @@ -544,7 +546,7 @@ var ActionManager = Widget.extend({ options.on_close(); - return $.when(); + return Promise.resolve(); }, /** * Returns a description of the controllers in the given controller stack. @@ -653,14 +655,14 @@ var ActionManager = Widget.extend({ * @param {Object} action * @param {string} action.type * @param {Object} options - * @returns {Deferred} resolved when the action has been executed ; rejected + * @returns {Promise} resolved when the action has been executed ; rejected * if the type of action isn't supported, or if the action can't be * executed */ _handleAction: function (action, options) { if (!action.type) { console.error("No type for action", action); - return $.Deferred().reject(); + return Promise.reject(); } switch (action.type) { case 'ir.actions.act_url': @@ -674,7 +676,7 @@ var ActionManager = Widget.extend({ default: console.error("The ActionManager can't handle actions of type " + action.type, action); - return $.Deferred().reject(); + return Promise.reject(); } }, /** @@ -749,16 +751,17 @@ var ActionManager = Widget.extend({ * @private * @param {integer|string} action's ID or xml ID * @param {Object} context - * @returns {Deferred<Object>} resolved with the description of the action + * @returns {Promise<Object>} resolved with the description of the action */ _loadAction: function (actionID, context) { - var def = $.Deferred(); - this.trigger_up('load_action', { - actionID: actionID, - context: context, - on_success: def.resolve.bind(def), + var self = this; + return new Promise(function (resolve, reject) { + self.trigger_up('load_action', { + actionID: actionID, + context: context, + on_success: resolve, + }); }); - return def; }, /** * Preprocesses the action before it is handled by the ActionManager @@ -815,20 +818,20 @@ var ActionManager = Widget.extend({ * * @private * @param {string} controllerID - * @returns {Deferred} resolved when the controller has been restored + * @returns {Promise} resolved when the controller has been restored */ _restoreController: function (controllerID) { var self = this; var controller = this.controllers[controllerID]; // AAB: AbstractAction should define a proper hook to execute code when - // it is restored (other than do_show), and it should return a deferred + // it is restored (other than do_show), and it should return a promise var action = this.actions[controller.actionID]; var def; if (action.on_reverse_breadcrumb) { def = action.on_reverse_breadcrumb(); } - return $.when(def).then(function () { - return $.when(controller.widget.do_show()).then(function () { + return Promise.resolve(def).then(function () { + return Promise.resolve(controller.widget.do_show()).then(function () { var index = _.indexOf(self.controllerStack, controllerID); self._pushController(controller, index); }); @@ -844,7 +847,7 @@ var ActionManager = Widget.extend({ * * @private * @param {Object} controller - * @returns {Deferred<Object>} resolved with the controller when it is ready + * @returns {Promise<Object>} resolved with the controller when it is ready */ _startController: function (controller) { var fragment = document.createDocumentFragment(); diff --git a/addons/web/static/src/js/chrome/action_manager_act_window.js b/addons/web/static/src/js/chrome/action_manager_act_window.js index 106f9f2aa47..d00b3a49eb2 100644 --- a/addons/web/static/src/js/chrome/action_manager_act_window.js +++ b/addons/web/static/src/js/chrome/action_manager_act_window.js @@ -144,7 +144,7 @@ ActionManager.include({ * @param {integer} [options.index=0] the controller's index in the stack * @param {boolean} [options.lazy=false] set to true to differ the * initialization of the controller's widget - * @returns {Deferred<Object>} resolved with the created controller + * @returns {Promise<Object>} resolved with the created controller */ _createViewController: function (action, viewType, viewOptions, options) { var self = this; @@ -153,7 +153,7 @@ ActionManager.include({ // the requested view type isn't specified in the action (e.g. // action with list view only, user clicks on a row in the list, it // tries to switch to form view) - return $.Deferred().reject(); + return Promise.reject(); } options = options || {}; @@ -186,26 +186,31 @@ ActionManager.include({ // communication with trigger_up controllerID: controllerID, }); + var rejection; var view = new viewDescr.Widget(viewDescr.fieldsView, viewOptions); - var def = $.Deferred(); - action.controllers[viewType] = def; - view.getController(this).then(function (widget) { - if (def.state() === 'rejected') { - // the deferred has been rejected meanwhile, meaning that - // the action has been removed, so simply destroy the widget - widget.destroy(); - } else { - controller.widget = widget; - def.resolve(controller); - } - }).fail(def.reject.bind(def)); - def.fail(function () { + var def = new Promise(function (resolve, reject) { + rejection = reject; + view.getController(self).then(function (widget) { + if (def.rejected) { + // the promise has been rejected meanwhile, meaning that + // the action has been removed, so simply destroy the widget + widget.destroy(); + } else { + controller.widget = widget; + resolve(controller); + } + }).guardedCatch(reject); + }); + // Need to define an reject property to call it into _destroyWindowAction + def.reject = rejection; + def.guardedCatch(function () { + def.rejected = true; delete self.controllers[controllerID]; }); + action.controllers[viewType] = def; } else { - action.controllers[viewType] = $.Deferred().resolve(controller); + action.controllers[viewType] = Promise.resolve(controller); } - return action.controllers[viewType]; }, /** @@ -217,18 +222,22 @@ ActionManager.include({ */ _destroyWindowAction: function (action) { var self = this; - _.each(action.controllers, function (controllerDef) { + for (var c in action.controllers) { + var controllerDef = action.controllers[c]; controllerDef.then(function (controller) { delete self.controllers[controller.jsID]; if (controller.widget) { controller.widget.destroy(); } }); - // reject the deferred if it is not yet resolved, so that the - // controller is correctly destroyed as soon as it is ready, and - // its reference is removed - controllerDef.reject(); - }); + // If controllerDef is not resolved yet, reject it so that the + // controller will be correctly destroyed as soon as it'll be ready, + // and its reference will be removed. Lazy-loaded controllers do + // not have a reject function on their promise + if (controllerDef.reject) { + controllerDef.reject(); + } + } }, /** * Executes actions of type 'ir.actions.act_window'. @@ -239,13 +248,13 @@ ActionManager.include({ * @param {Object} options @see doAction for details * @param {integer} [options.resID] the current res ID * @param {string} [options.viewType] the view to open - * @returns {Deferred} resolved when the action is appended to the DOM + * @returns {Promise} resolved when the action is appended to the DOM */ _executeWindowAction: function (action, options) { var self = this; return this.dp.add(this._loadViews(action)).then(function (fieldsViews) { var views = self._generateActionViews(action, fieldsViews); - action._views = action.views; // save the initial attribute + action._views = action.views; // save the initial attribute action.views = views; action.controlPanelFieldsView = fieldsViews.search; action.controllers = {}; @@ -285,7 +294,7 @@ ActionManager.include({ self.controllerStack.push(lazyLoadedController.jsID); }); } - return self.dp.add($.when(lazyViewDef)) + return self.dp.add(Promise.resolve(lazyViewDef)) .then(function () { var viewOptions = { controllerState: options.controllerState, @@ -300,7 +309,7 @@ ActionManager.include({ action.controllerID = controller.jsID; return self._executeAction(action, options); }) - .fail(self._destroyWindowAction.bind(self, action)); + .guardedCatch(self._destroyWindowAction.bind(self, action)); }); }, /** @@ -389,7 +398,7 @@ ActionManager.include({ * * @private * @param {Object} action - * @returns {Deferred} + * @returns {Promise} */ _loadViews: function (action) { var inDialog = action.target === 'new'; @@ -443,11 +452,11 @@ ActionManager.include({ return this.clearUncommittedChanges().then(function () { // AAB: this will be done directly in AbstractAction's restore // function - var def; + var def = Promise.resolve(); if (action.on_reverse_breadcrumb) { def = action.on_reverse_breadcrumb(); } - return $.when(def).then(function () { + return Promise.resolve(def).then(function () { return self._switchController(action, controller.viewType); }); }); @@ -461,14 +470,14 @@ ActionManager.include({ * @private * @param {Object} controller the controller to switch to * @param {Object} [viewOptions] - * @return {Deferred} resolved when the new controller is in the DOM + * @return {Promise} resolved when the new controller is in the DOM */ _switchController: function (action, viewType, viewOptions) { var self = this; var view = _.findWhere(action.views, {type: viewType}); if (!view) { // can't switch to an unknown view - return $.Deferred().reject(); + return Promise.reject(); } var currentController = this.getCurrentController(); var index; @@ -519,28 +528,30 @@ ActionManager.include({ }; var controllerDef = action.controllers[viewType]; - if (!controllerDef || controllerDef.state() === 'rejected') { - // if the controllerDef is rejected, it probably means that the js - // code or the requests made to the server crashed. In that case, - // if we reuse the same deferred, then the switch to the view is - // definitely blocked. We want to use a new controller, even though - // it is very likely that it will recrash again. At least, it will - // give more feedback to the user, and it could happen that one - // record crashes, but not another. - controllerDef = newController(); - } else { + if (controllerDef) { controllerDef = controllerDef.then(function (controller) { if (!controller.widget) { // lazy loaded -> load it now (with same jsID) return newController(controller.jsID); } else { - return $.when(controller.widget.willRestore()).then(function () { + return Promise.resolve(controller.widget.willRestore()).then(function () { return controller.widget.reload(viewOptions).then(function () { return controller; }); }); } + }, function () { + // if the controllerDef is rejected, it probably means that the js + // code or the requests made to the server crashed. In that case, + // if we reuse the same promise, then the switch to the view is + // definitely blocked. We want to use a new controller, even though + // it is very likely that it will recrash again. At least, it will + // give more feedback to the user, and it could happen that one + // record crashes, but not another. + return newController(); }); + } else { + controllerDef = newController(); } return this.dp.add(controllerDef).then(function (controller) { @@ -577,11 +588,11 @@ ActionManager.include({ var env = ev.data.env; var context = new Context(env.context, actionData.context || {}); var recordID = env.currentID || null; // pyUtils handles null value, not undefined - var def = $.Deferred(); + var def; // determine the action to execute according to the actionData if (actionData.special) { - def = $.when({type: 'ir.actions.act_window_close', infos: 'special'}); + def = Promise.resolve({type: 'ir.actions.act_window_close', infos: 'special'}); } else if (actionData.type === 'object') { // call a Python Object method, which may return an action to execute var args = recordID ? [[recordID]] : [env.resIDs]; @@ -611,13 +622,15 @@ ActionManager.include({ active_ids: env.resIDs, active_id: recordID, })); + } else { + def = new Promise(function () {}); } // use the DropPrevious to prevent from executing the handler if another // request (doAction, switchView...) has been done meanwhile ; execute // the fail handler if the 'call_button' or 'loadAction' failed but not // if the request failed due to the DropPrevious, - def.fail(ev.data.on_fail); + def.guardedCatch(ev.data.on_fail); this.dp.add(def).then(function (action) { // show effect if button have effect attribute // rainbowman can be displayed from two places: from attribute on a button or from python diff --git a/addons/web/static/src/js/chrome/action_manager_report.js b/addons/web/static/src/js/chrome/action_manager_report.js index 51922cd719f..30bac14006d 100644 --- a/addons/web/static/src/js/chrome/action_manager_report.js +++ b/addons/web/static/src/js/chrome/action_manager_report.js @@ -40,35 +40,36 @@ ActionManager.include({ * report generation and download. * * @param {string} url - * @returns {Deferred} resolved when the report has been downloaded ; + * @returns {Promise} resolved when the report has been downloaded ; * rejected if something went wrong during the report generation */ _downloadReport: function (url) { + var self = this; framework.blockUI(); - var def = $.Deferred(); - var type = 'qweb-' + url.split('/')[2]; - var blocked = !session.get_file({ - url: '/report/download', - data: { - data: JSON.stringify([url, type]), - }, - success: def.resolve.bind(def), - error: function () { - crash_manager.rpc_error.apply(crash_manager, arguments); - def.reject(); - }, - complete: framework.unblockUI, + return new Promise(function (resolve, reject) { + var type = 'qweb-' + url.split('/')[2]; + var blocked = !session.get_file({ + url: '/report/download', + data: { + data: JSON.stringify([url, type]), + }, + success: resolve, + error: function () { + crash_manager.rpc_error.apply(crash_manager, arguments); + reject(); + }, + complete: framework.unblockUI, + }); + if (blocked) { + // AAB: this check should be done in get_file service directly, + // should not be the concern of the caller (and that way, get_file + // could return a promise) + var message = _t('A popup window with your report was blocked. You ' + + 'may need to change your browser settings to allow ' + + 'popup windows for this page.'); + self.do_warn(_t('Warning'), message, true); + } }); - if (blocked) { - // AAB: this check should be done in get_file service directly, - // should not be the concern of the caller (and that way, get_file - // could return a deferred) - var message = _t('A popup window with your report was blocked. You ' + - 'may need to change your browser settings to allow ' + - 'popup windows for this page.'); - this.do_warn(_t('Warning'), message, true); - } - return def; }, /** @@ -77,7 +78,7 @@ ActionManager.include({ * @private * @param {Object} action the description of the action to execute * @param {Object} options @see doAction for details - * @returns {Deferred} resolved when the action has been executed + * @returns {Promise} resolved when the action has been executed */ _triggerDownload: function (action, options, type){ var self = this; @@ -97,7 +98,7 @@ ActionManager.include({ * @private * @param {Object} action the description of the action to execute * @param {Object} options @see doAction for details - * @returns {Deferred} resolved when the action has been executed + * @returns {Promise} resolved when the action has been executed */ _executeReportAction: function (action, options) { var self = this; @@ -125,7 +126,7 @@ ActionManager.include({ } else { console.error("The ActionManager can't handle reports of type " + action.report_type, action); - return $.Deferred().reject(); + return Promise.reject(); } }, /** @@ -135,7 +136,7 @@ ActionManager.include({ * * @param {Object} action * @param {Object} options - * @returns {Deferred} resolved when the client action has been executed + * @returns {Promise} resolved when the client action has been executed */ _executeReportClientAction: function (action, options) { var urls = this._makeReportUrls(action); diff --git a/addons/web/static/src/js/chrome/action_mixin.js b/addons/web/static/src/js/chrome/action_mixin.js index 92d6716a7c0..02345e7e969 100644 --- a/addons/web/static/src/js/chrome/action_mixin.js +++ b/addons/web/static/src/js/chrome/action_mixin.js @@ -75,7 +75,7 @@ var ActionMixin = { * Called by the action manager when action is restored (typically, when the * user clicks on the action in the breadcrumb) * - * @returns {Deferred|undefined} + * @returns {Promise|undefined} */ willRestore: function () {}, @@ -89,14 +89,14 @@ var ActionMixin = { * example, if the user has edited a form, maybe we should ask him if we * can discard all his changes when we switch to another action. In that * case, the action manager will call this method. If the returned - * deferred is succesfully resolved, then we can destroy the current action, + * promise is succesfully resolved, then we can destroy the current action, * otherwise, we need to stop. * - * @returns {Deferred} resolved if the action can be removed, rejected + * @returns {Promise} resolved if the action can be removed, rejected * otherwise */ canBeRemoved: function () { - return $.when(); + return Promise.resolve(); }, /** * This function is called when the current state of the action diff --git a/addons/web/static/src/js/chrome/loading.js b/addons/web/static/src/js/chrome/loading.js index 6c7f102231b..865aa081bf0 100644 --- a/addons/web/static/src/js/chrome/loading.js +++ b/addons/web/static/src/js/chrome/loading.js @@ -26,6 +26,8 @@ var Loading = Widget.extend({ this._super(parent); this.count = 0; this.blocked_ui = false; + }, + start: function() { core.bus.on('rpc_request', this, this.request_call); core.bus.on("rpc_response", this, this.response_call); core.bus.on("rpc_response_failed", this, this.response_call); diff --git a/addons/web/static/src/js/chrome/menu.js b/addons/web/static/src/js/chrome/menu.js index 8722724c9a6..552dfce811c 100644 --- a/addons/web/static/src/js/chrome/menu.js +++ b/addons/web/static/src/js/chrome/menu.js @@ -64,20 +64,22 @@ var Menu = Widget.extend({ // Apps Menu this._appsMenu = new AppsMenu(self, this.menu_data); - this._appsMenu.appendTo(this.$menu_apps); + var appsMenuProm = this._appsMenu.appendTo(this.$menu_apps); // Systray Menu this.systray_menu = new SystrayMenu(this); - this.systray_menu.attachTo(this.$('.o_menu_systray')); - - dom.initAutoMoreMenu(this.$section_placeholder, { + var systrayMenuProm = this.systray_menu.attachTo(this.$('.o_menu_systray')).then(function() { + dom.initAutoMoreMenu(self.$section_placeholder, { maxWidth: function () { return self.$el.width() - (self.$menu_apps.outerWidth(true) + self.$menu_brand_placeholder.outerWidth(true) + self.systray_menu.$el.outerWidth(true)); }, sizeClass: 'SM', + }); }); - return this._super.apply(this, arguments); + + + return Promise.all([this._super.apply(this, arguments), appsMenuProm, systrayMenuProm]); }, change_menu_section: function (primary_menu_id) { if (!this.$menu_sections[primary_menu_id]) { diff --git a/addons/web/static/src/js/chrome/pager.js b/addons/web/static/src/js/chrome/pager.js index c7f22a6f2c9..86700d93374 100644 --- a/addons/web/static/src/js/chrome/pager.js +++ b/addons/web/static/src/js/chrome/pager.js @@ -28,7 +28,7 @@ var Pager = Widget.extend({ * @param {boolean} [options.can_edit] editable feature of the pager * @param {boolean} [options.single_page_hidden] (not) to display the pager * if only one page - * @param {function} [options.validate] callback returning a Deferred to + * @param {function} [options.validate] callback returning a Promise to * validate changes */ init: function (parent, size, current_min, limit, options) { @@ -46,7 +46,7 @@ var Pager = Widget.extend({ can_edit: true, // editable single_page_hidden: false, // displayed even if there is a single page validate: function() { - return $.Deferred().resolve(); + return Promise.resolve(); }, withAccessKey: true, // can be disabled, for example, for x2m widgets }); @@ -55,7 +55,7 @@ var Pager = Widget.extend({ /** * Renders the pager * - * @returns {jQuery.Deferred} + * @returns {Promise} */ start: function () { this.$value = this.$('.o_pager_value'); @@ -216,7 +216,6 @@ var Pager = Widget.extend({ } self.trigger('pager_changed', _.clone(self.state)); } - }).always(function() { // Render the pager's new state (removes the input) self._render(); }); diff --git a/addons/web/static/src/js/chrome/sidebar.js b/addons/web/static/src/js/chrome/sidebar.js index 5cf6005a788..b7883cbb0f7 100644 --- a/addons/web/static/src/js/chrome/sidebar.js +++ b/addons/web/static/src/js/chrome/sidebar.js @@ -153,7 +153,7 @@ var Sidebar = Widget.extend({ action_id: item.action.id, context: context, }, - }).done(function (result) { + }).then(function (result) { result.context = new Context( result.context || {}, activeIdsContext) .set_eval_context(context); diff --git a/addons/web/static/src/js/chrome/systray_menu.js b/addons/web/static/src/js/chrome/systray_menu.js index 24fd02a3736..fd214c0b650 100644 --- a/addons/web/static/src/js/chrome/systray_menu.js +++ b/addons/web/static/src/js/chrome/systray_menu.js @@ -16,20 +16,19 @@ var SystrayMenu = Widget.extend({ this._super(parent); this.items = []; this.widgets = []; - this.load = $.Deferred(); }, /** * @override - * @returns {Deferred} + * @returns {Promise} */ start: function () { var self = this; self._super.apply(this, arguments); self._loadItems(); - $.when.apply($, self.items).always(function () { - self.load.resolve(); + + return new Promise(function (resolve, reject) { + Promise.all(self.items).then(resolve).guardedCatch(resolve); }); - return self.load; }, //-------------------------------------------------------------------------- diff --git a/addons/web/static/src/js/chrome/user_menu.js b/addons/web/static/src/js/chrome/user_menu.js index a066b661fb2..2cc39b4d6bd 100644 --- a/addons/web/static/src/js/chrome/user_menu.js +++ b/addons/web/static/src/js/chrome/user_menu.js @@ -22,7 +22,7 @@ var UserMenu = Widget.extend({ /** * @override - * @returns {Deferred} + * @returns {Promise} */ start: function () { var self = this; @@ -36,7 +36,7 @@ var UserMenu = Widget.extend({ var $avatar = self.$('.oe_topbar_avatar'); if (!session.uid) { $avatar.attr('src', $avatar.data('default-src')); - return $.when(); + return Promise.resolve(); } var topbar_name = session.name; if (session.debug) { @@ -67,7 +67,7 @@ var UserMenu = Widget.extend({ .then(function (url) { framework.redirect(url); }) - .fail(function (result, ev){ + .guardedCatch(function (result, ev){ ev.preventDefault(); framework.redirect('https://accounts.odoo.com/account'); }); @@ -100,7 +100,7 @@ var UserMenu = Widget.extend({ model: "res.users", method: "action_get" }) - .done(function (result) { + .then(function (result) { result.res_id = session.uid; self.do_action(result); }); diff --git a/addons/web/static/src/js/chrome/web_client.js b/addons/web/static/src/js/chrome/web_client.js index 0688adc362f..392d534f372 100644 --- a/addons/web/static/src/js/chrome/web_client.js +++ b/addons/web/static/src/js/chrome/web_client.js @@ -111,7 +111,7 @@ return AbstractWebClient.extend({ instanciate_menu_widgets: function () { var self = this; - var defs = []; + var proms = []; return this.load_menus().then(function (menuData) { self.menu_data = menuData; @@ -122,8 +122,8 @@ return AbstractWebClient.extend({ self.menu.destroy(); } self.menu = new Menu(self, menuData); - defs.push(self.menu.prependTo(self.$el)); - return $.when.apply($, defs); + proms.push(self.menu.prependTo(self.$el)); + return Promise.all(proms); }); }, @@ -133,7 +133,7 @@ return AbstractWebClient.extend({ on_hashchange: function (event) { if (this._ignore_hashchange) { this._ignore_hashchange = false; - return $.when(); + return Promise.resolve(); } var self = this; @@ -181,48 +181,51 @@ return AbstractWebClient.extend({ return this.menu_dm.add(data_manager.load_action(ev.data.action_id)) .then(function (result) { return self.action_mutex.exec(function () { - var completed = $.Deferred(); - var options = _.extend({}, ev.data.options, { - clear_breadcrumbs: true, - action_menu_id: ev.data.menu_id, - }); - $.when(self._openMenu(result, options)).fail(function () { - completed.resolve(); - }).done(function () { - self._on_app_clicked_done(ev) - .then(completed.resolve.bind(completed)) - .fail(completed.reject.bind(completed)); + var completed = new Promise(function (resolve, reject) { + var options = _.extend({}, ev.data.options, { + clear_breadcrumbs: true, + action_menu_id: ev.data.menu_id, + }); + + Promise.resolve(self._openMenu(result, options)) + .then(function() { + self._on_app_clicked_done(ev) + .then(resolve) + .guardedCatch(reject); + }).guardedCatch(function() { + resolve(); + }); + setTimeout(function () { + resolve(); + }, 2000); }); - setTimeout(function () { - completed.resolve(); - }, 2000); return completed; }); }); }, _on_app_clicked_done: function (ev) { core.bus.trigger('change_menu_section', ev.data.menu_id); - return $.Deferred().resolve(); + return Promise.resolve(); }, on_menu_clicked: function (ev) { var self = this; return this.menu_dm.add(data_manager.load_action(ev.data.action_id)) .then(function (result) { - return self.action_mutex.exec(function () { - var completed = $.Deferred(); - $.when(self._openMenu(result, { - clear_breadcrumbs: true, - })).always(function () { - completed.resolve(); - }); + self.$el.removeClass('o_mobile_menu_opened'); - setTimeout(function () { - completed.resolve(); - }, 2000); + return self.action_mutex.exec(function () { + var completed = new Promise(function (resolve, reject) { + Promise.resolve(self._openMenu(result, { + clear_breadcrumbs: true, + })).then(resolve).guardedCatch(reject); + setTimeout(function () { + resolve(); + }, 2000); + }); return completed; }); - }).always(function () { + }).guardedCatch(function () { self.$el.removeClass('o_mobile_menu_opened'); }); }, @@ -233,7 +236,7 @@ return AbstractWebClient.extend({ * @private * @param {Object} action * @param {Object} options - * @returns {Deferred} + * @returns {Promise} */ _openMenu: function (action, options) { return this.do_action(action, options); |
