diff options
| author | qsm-odoo <qsm@odoo.com> | 2019-04-05 12:32:49 +0000 |
|---|---|---|
| committer | qsm-odoo <qsm@odoo.com> | 2019-04-19 12:07:14 +0000 |
| commit | 75f16ee07f4fbf1f5dab13afde758c607577381e (patch) | |
| tree | 31cc3e92869a4d827f035eca63f11559aa427a31 /addons/web/static/src | |
| parent | a742bf3d5bd3d613cc792339b910ac0f5143e2d7 (diff) | |
[FIX] web, website: adapt menu loading to jQuery 3
Javascript is responsible of showing the menu, potentially with some
parts regrouped in an extra dropdown, on page load (this is what we
call the "autohide" feature). This was done on both the menu and the
affix menu. It worked on the affix menu because the affix menu widget
was initialized before (by luck: alphabetical order).
Since the jQuery 3 update https://github.com/odoo/odoo/commit/bb004e3d7f3df5a5af6b2e994ec0af79e2da890f
deferred are always delayed (even if their resolve condition is met on
creation). This made the animations to be initialized in the same order
as before but their 'start' method to be delayed (as the willStart was
delayed). So what happened before was:
1) Find menus to enable affix
2) Enable affix on found menus (duplicate the menus to do that)
3) Find menus to enable autohide
4) Enable autohide on found menus (both the menu and the duplicated one
were found)
And since jQuery 3:
1) Find menus to enable affix
2) Find menus to enable autohide
3) Enable affix on found menus (duplicate the menus to do that)
4) Enable autohide on found menus (the duplicated one was not found at
step 2 since it did not exist yet)
In fact, widget starting should never have relied on alphabetical order.
The fix only consists of starting widgets on the duplicated menu once it
is ready. This is what this commit does.
However, doing this revealed another bug: if the widgets are started
only for a DOM portion like a '.a' element, a widget with a multiple
parts selector like a '.a .b' selector will not be considered, as
searching inside a '.a' element will not allow to match elements with
a selector containing a '.a'. This is in fact not really a "bug" but a
limitation, so unless we get problems because of this in stable
versions, we can only "fix" this for the current saas. This is fixed
thanks to `dom.cssFind` which already existed. This commit however
improves it to try making it more efficient.
closes odoo/odoo#32465
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
Diffstat (limited to 'addons/web/static/src')
| -rw-r--r-- | addons/web/static/src/js/core/dom.js | 21 | ||||
| -rw-r--r-- | addons/web/static/src/js/public/public_root.js | 3 |
2 files changed, 21 insertions, 3 deletions
diff --git a/addons/web/static/src/js/core/dom.js b/addons/web/static/src/js/core/dom.js index 81211788246..7be17700f98 100644 --- a/addons/web/static/src/js/core/dom.js +++ b/addons/web/static/src/js/core/dom.js @@ -153,10 +153,27 @@ var dom = { * * @param {jQuery} $from - the jQuery element(s) from which to search * @param {string} selector - the CSS selector to match + * @param {boolean} [addBack=false] - whether or not the $from element + * should be considered in the results * @returns {jQuery} */ - cssFind: function ($from, selector) { - return $from.find('*').filter(selector); + cssFind: function ($from, selector, addBack) { + var $results; + + // No way to correctly parse a complex jQuery selector but having no + // spaces should be a good-enough condition to use a simple find + var multiParts = selector.indexOf(' ') >= 0; + if (multiParts) { + $results = $from.find('*').filter(selector); + } else { + $results = $from.find(selector); + } + + if (addBack && $from.is(selector)) { + $results = $results.add($from); + } + + return $results; }, /** * Detaches widgets from the DOM and performs their on_detach_callback() diff --git a/addons/web/static/src/js/public/public_root.js b/addons/web/static/src/js/public/public_root.js index 2c91c795df3..5d0483ad886 100644 --- a/addons/web/static/src/js/public/public_root.js +++ b/addons/web/static/src/js/public/public_root.js @@ -2,6 +2,7 @@ odoo.define('web.public.root', function (require) { 'use strict'; var ajax = require('web.ajax'); +var dom = require('web.dom'); var ServiceProviderMixin = require('web.ServiceProviderMixin'); var session = require('web.session'); var utils = require('web.utils'); @@ -199,7 +200,7 @@ var PublicRoot = publicWidget.RootWidget.extend(ServiceProviderMixin, { var defs = _.map(this._getPublicWidgetsRegistry(options), function (PublicWidget) { var selector = PublicWidget.prototype.selector || ''; - var $target = $from.find(selector).addBack(selector); + var $target = dom.cssFind($from, selector, true); var defs = _.map($target, function (el) { var widget = new PublicWidget(self, options); |
