From 82846a5556ff50d17dd799d5af34324b622a1b8f Mon Sep 17 00:00:00 2001 From: xO-Tx Date: Thu, 19 Aug 2021 14:22:20 +0000 Subject: [PATCH 1/5] [FIX] website_sale: fix cart popover position On vertical menu with "flex-direction: column", cart item will take full parent width, which makes the popover appear far from cart link (in the middle of screen). The goal of this commit is to fix this behaviour by adjusting cart item width on large vertical menu. task-2618929 X-original-commit: c72d29fff6d97f42c512d597a98fd392b547e931 Part-of: odoo/odoo#77843 --- addons/website_sale/views/templates.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/website_sale/views/templates.xml b/addons/website_sale/views/templates.xml index 0718e764bc3..9e786e682d9 100644 --- a/addons/website_sale/views/templates.xml +++ b/addons/website_sale/views/templates.xml @@ -4,7 +4,7 @@
  • -
  • +
  • My Cart @@ -124,7 +124,7 @@ - + From 0de634965a0dec4470b30154f3722a1e83b0e866 Mon Sep 17 00:00:00 2001 From: xO-Tx Date: Wed, 1 Sep 2021 16:15:18 +0000 Subject: [PATCH 2/5] [REF] web, website: rewrite initAutoMoreMenu method The goal of this commit is to make initAutoMoreMenu fully non-jquery and totally independant of other odoo utils. task-2618929 X-original-commit: 7be1bb9083c786064fa140c811952e7735ce5539 Part-of: odoo/odoo#77843 --- addons/web/static/src/legacy/js/core/dom.js | 169 +++++++++++-------- addons/website/static/src/js/content/menu.js | 5 +- addons/website/static/src/js/menu/navbar.js | 18 +- 3 files changed, 110 insertions(+), 82 deletions(-) diff --git a/addons/web/static/src/legacy/js/core/dom.js b/addons/web/static/src/legacy/js/core/dom.js index 9412fdc1cde..3e040ff7629 100644 --- a/addons/web/static/src/legacy/js/core/dom.js +++ b/addons/web/static/src/legacy/js/core/dom.js @@ -619,101 +619,103 @@ var dom = { /** * Creates an automatic 'more' dropdown-menu for a set of navbar items. * - * @param {jQuery} $el + * @param {HTMLElement} el * @param {Object} [options] - * @param {string} [options.unfoldable='none'] - * @param {function} [options.maxWidth] - * @param {string} [options.sizeClass='SM'] + * @param {string} [options.unfoldable='none'] selector for items that do not + * need to be added to dropdown-menu. + * @param {float} [options.maxWidth] The max width value that menu content + * can take => the overflowing (foldable) items are added in the dropdown-menu. + * @param {string} [options.minSize] the menu auto-hide option will be disabled + * if viewport is smaller than minSize. */ - initAutoMoreMenu: function ($el, options) { - options = _.extend({ + initAutoMoreMenu: function (el, options) { + if (!el) { + return; + } + options = Object.assign({ unfoldable: 'none', - maxWidth: false, - sizeClass: 'SM', + maxWidth: 0, + minSize: '767', }, options || {}); var autoMarginLeftRegex = /\bm[lx]?(?:-(?:sm|md|lg|xl))?-auto\b/; var autoMarginRightRegex = /\bm[rx]?(?:-(?:sm|md|lg|xl))?-auto\b/; + var extraItemsToggle = null; + let debounce; - var $extraItemsToggle = null; - - var debouncedAdapt = _.debounce(_adapt, 250); - core.bus.on('resize', null, debouncedAdapt); + const debouncedAdapt = () => { + clearTimeout(debounce); + debounce = setTimeout(_adapt, 250); + }; + window.addEventListener('resize', debouncedAdapt); _adapt(); - $el.data('dom:autoMoreMenu:adapt', _adapt); - $el.data('dom:autoMoreMenu:destroy', function () { - _restore(); - core.bus.off('resize', null, debouncedAdapt); - $el.removeData(['dom:autoMoreMenu:destroy', 'dom:autoMoreMenu:adapt']); - }); + el.addEventListener('dom:autoMoreMenu:adapt', _adapt); + el.addEventListener('dom:autoMoreMenu:destroy', destroy, {once: true}); function _restore() { - if ($extraItemsToggle === null) { + if (!extraItemsToggle) { return; } - var $items = $extraItemsToggle.children('.dropdown-menu').children(); - $items.addClass('nav-item'); - $items.children('.dropdown-item, a').removeClass('dropdown-item').addClass('nav-link'); - $items.insertBefore($extraItemsToggle); - $extraItemsToggle.remove(); - $extraItemsToggle = null; + // Move extra menu items from dropdown-menu to menu element in the same order. + [...extraItemsToggle.querySelector('.dropdown-menu').children].forEach((item) => { + item.classList.add('nav-item'); + const itemLink = item.querySelector('.dropdown-item'); + itemLink.classList.remove('dropdown-item'); + itemLink.classList.add('nav-link'); + el.insertBefore(item, extraItemsToggle); + }); + extraItemsToggle.remove(); + extraItemsToggle = null; } function _adapt() { _restore(); - if (!$el.is(':visible') || $el.closest('.show').length) { - // Never transform the menu when it is not visible yet or if - // it is a toggleable one. - return; - } - if (config.device.size_class <= config.device.SIZES[options.sizeClass]) { + // Ignore invisible/toggleable top menu element & small viewports. + if (!el.getClientRects().length || el.closest('.show') + || window.matchMedia(`(max-width: ${options.minSize}px)`).matches) { return; } - var $allItems = $el.children(); - var $unfoldableItems = $allItems.filter(options.unfoldable); - var $items = $allItems.not($unfoldableItems); + let unfoldableItems = []; + const items = [...el.children].filter((node) => { + if (node.matches && !node.matches(options.unfoldable)) { + return true; + } + unfoldableItems.push(node); + return false; + }); + var nbItems = items.length; + var menuItemsWidth = items.reduce((sum, el) => sum + computeFloatOuterWidthWithMargins(el, true, true, false), 0); - var maxWidth = 0; - if (options.maxWidth) { - maxWidth = options.maxWidth(); - } else { - maxWidth = computeFloatOuterWidthWithMargins($el[0], true, true, true); - var style = window.getComputedStyle($el[0]); + var maxWidth = options.maxWidth; + if (!maxWidth) { + maxWidth = computeFloatOuterWidthWithMargins(el, true, true, true); + var style = window.getComputedStyle(el); maxWidth -= (parseFloat(style.paddingLeft) + parseFloat(style.paddingRight) + parseFloat(style.borderLeftWidth) + parseFloat(style.borderRightWidth)); - maxWidth -= _.reduce($unfoldableItems, function (sum, el) { - return sum + computeFloatOuterWidthWithMargins(el, true, true, false); - }, 0); + maxWidth -= unfoldableItems.reduce((sum, el) => sum + computeFloatOuterWidthWithMargins(el, true, true, false), 0); } - - var nbItems = $items.length; - var menuItemsWidth = _.reduce($items, function (sum, el) { - return sum + computeFloatOuterWidthWithMargins(el, true, true, false); - }, 0); - + // Ignore if there is no overflow. if (maxWidth - menuItemsWidth >= -0.001) { return; } - var $dropdownMenu = $('