From a7455eaee0d02009cbb4b6ae77371d3968bccf5f Mon Sep 17 00:00:00 2001 From: qsm-odoo Date: Fri, 17 Apr 2020 14:52:57 +0000 Subject: [PATCH] [FIX] website: fix website menu lazy loading on hover Small bug introduced by [1]: now the website menu is loaded on demand to avoid useless page loading. This was done when hovering the toggle which induced two problems: not loaded if the user was already over the button when the JS is fully loaded and not loaded if the dropdown was opened via the keyboard. Also, the 'mouseover' event was used instead of the 'mouseenter' and the RPC was not checked for already pending ones. Both issues could lead to have the RPC performed multiple times for no reason. [1]: https://github.com/odoo/odoo/commit/4206c1f225f5b1c54a0cdd4913e1d8224a2e7889 closes odoo/odoo#49986 X-original-commit: 7aebd7d88d1d0a0f81351b8a0e12a03964c8431a Signed-off-by: Quentin Smetz (qsm) --- addons/website/static/src/js/menu/navbar.js | 49 ++++++++++++++------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/addons/website/static/src/js/menu/navbar.js b/addons/website/static/src/js/menu/navbar.js index 1f6cf824790..da86853f4e1 100644 --- a/addons/website/static/src/js/menu/navbar.js +++ b/addons/website/static/src/js/menu/navbar.js @@ -8,8 +8,6 @@ var concurrency = require('web.concurrency'); var Widget = require('web.Widget'); var websiteRootData = require('website.root'); -var qweb = core.qweb; - var websiteNavbarRegistry = new publicWidget.RootWidgetRegistry(); var WebsiteNavbar = publicWidget.RootWidget.extend({ @@ -18,7 +16,8 @@ var WebsiteNavbar = publicWidget.RootWidget.extend({ 'click [data-action]': '_onActionMenuClick', 'mouseover > ul > li.dropdown:not(.show)': '_onMenuHovered', 'click .o_mobile_menu_toggle': '_onMobileMenuToggleClick', - 'mouseover #oe_applications:not(:has(.dropdown-item))': '_onOeApplicationsHovered', + 'mouseenter #oe_applications:not(:has(.dropdown-item))': '_onOeApplicationsHovered', + 'show.bs.dropdown #oe_applications:not(:has(.dropdown-item))': '_onOeApplicationsShow', }), custom_events: _.extend({}, publicWidget.RootWidget.prototype.custom_events || {}, { 'action_demand': '_onActionDemand', @@ -123,6 +122,25 @@ var WebsiteNavbar = publicWidget.RootWidget.extend({ }); }); }, + /** + * @private + * @returns {Promise} + */ + async _loadAppMenus() { + if (!this._loadAppMenusProm) { + this._loadAppMenusProm = this._rpc({ + model: 'ir.ui.menu', + method: 'load_menus_root', + args: [], + }); + const result = await this._loadAppMenusProm; + const menus = core.qweb.render('website.oe_applications_menu', { + 'menu_data': result, + }); + this.$('#oe_applications .dropdown-menu').html(menus); + } + return this._loadAppMenusProm; + }, /** * @private */ @@ -139,19 +157,20 @@ var WebsiteNavbar = publicWidget.RootWidget.extend({ * available menus and insert it in DOM. * * @private - * @param {Event} ev */ - _onOeApplicationsHovered: function (ev) { - var self = this; - this._rpc({ - model: 'ir.ui.menu', - method: 'load_menus_root', - args: [], - }).then(function (result) { - self.$('#oe_applications .dropdown-menu').html( - $(qweb.render('website.oe_applications_menu', {menu_data: result})) - ); - }); + _onOeApplicationsHovered: function () { + this._loadAppMenus(); + }, + /** + * Called when the backend applications menu is opening -> fetch the + * available menus and insert it in DOM. Needed on top of hovering as the + * dropdown could be opened via keyboard (or the user could just already + * be over the dropdown when the JS is fully loaded). + * + * @private + */ + _onOeApplicationsShow: function () { + this._loadAppMenus(); }, /** * Called when an action menu is clicked -> searches for the automatic