[FIX] web, website: prevent the submenus from overflowing the page
Since [this first commit], the elements that make up the submenu of the navbar of a website can no longer overflow the page. Depending on whether the content is too long, the elements are aligned to the left or to the right. This was done with the public `menuDirection` widget which looked at the available space on the left and right and depending on the size of the submenu elements, aligned the submenu in an optimal way. It has now been decided to get rid of all this widget because Bootstrap (with Popper) knows how to position dropdowns dynamically. Unfortunately Bootstrap has limited this dynamic positioning by disabling it on dropdowns that are in a navbar. So this commit removes the public widget and replaces it with a bootstrap patch so that dropdowns are dynamically aligned in navbars too. Note that if we had not made this patch in master, we would have had to adapt the public widget to the migration to Bootstrap 5 (see original commit). [this first commit]: https://github.com/odoo/odoo/commit/392c91cda3133b921e9aca9a7b1c511231027438 task-2904507 X-original-commit: b6963dc21bad4b012aace16b9ea9264c33a0d618 Part-of: odoo/odoo#115607
This commit is contained in:
@@ -148,3 +148,13 @@ ScrollSpy.prototype._activate = function (target) {
|
||||
}
|
||||
bootstrapSpyActivateFunction.apply(this, arguments);
|
||||
};
|
||||
|
||||
/**
|
||||
* Bootstrap disables dynamic dropdown positioning when it is in a navbar. Here
|
||||
* we make this patch to activate this dynamic navbar's dropdown positioning
|
||||
* which is useful to avoid that the elements of the website sub-menus overflow
|
||||
* the page.
|
||||
*/
|
||||
Dropdown.prototype._detectNavbar = function () {
|
||||
return false;
|
||||
};
|
||||
|
||||
@@ -501,86 +501,6 @@ publicWidget.registry.FadeOutHeader = BaseDisappearingHeader.extend({
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Note: this works well with the affixMenu... by chance (menuDirection is
|
||||
* called after alphabetically).
|
||||
*
|
||||
* @todo check bootstrap v4: maybe handled automatically now ?
|
||||
*/
|
||||
publicWidget.registry.menuDirection = publicWidget.Widget.extend({
|
||||
selector: 'header .navbar .nav',
|
||||
disabledInEditableMode: false,
|
||||
events: {
|
||||
'show.bs.dropdown': '_onDropdownShow',
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
start: function () {
|
||||
this.defaultAlignment = this.$el.is('.ms-auto, .ms-auto ~ *') ? 'right' : 'left';
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {string} alignment - either 'left' or 'right'
|
||||
* @param {integer} liOffset
|
||||
* @param {integer} liWidth
|
||||
* @param {integer} menuWidth
|
||||
* @param {integer} pageWidth
|
||||
* @returns {boolean}
|
||||
*/
|
||||
_checkOpening: function (alignment, liOffset, liWidth, menuWidth, pageWidth) {
|
||||
if (alignment === 'left') {
|
||||
// Check if ok to open the dropdown to the right (no window overflow)
|
||||
return (liOffset + menuWidth <= pageWidth);
|
||||
} else {
|
||||
// Check if ok to open the dropdown to the left (no window overflow)
|
||||
return (liOffset + liWidth - menuWidth >= 0);
|
||||
}
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_onDropdownShow: function (ev) {
|
||||
var $li = $(ev.target);
|
||||
var $menu = $li.children('.dropdown-menu');
|
||||
var liOffset = $li.offset().left;
|
||||
var liWidth = $li.outerWidth();
|
||||
var menuWidth = $menu.outerWidth();
|
||||
var pageWidth = $('#wrapwrap').outerWidth();
|
||||
|
||||
$menu.removeClass('dropdown-menu-start dropdown-menu-end');
|
||||
|
||||
var alignment = this.defaultAlignment;
|
||||
if ($li.nextAll(':visible').length === 0) {
|
||||
// The dropdown is the last menu item, open to the left
|
||||
alignment = 'right';
|
||||
}
|
||||
|
||||
// If can't open in the current direction because it would overflow the
|
||||
// page, change the direction. But if the other direction would do the
|
||||
// same, change back the direction.
|
||||
for (var i = 0; i < 2; i++) {
|
||||
if (!this._checkOpening(alignment, liOffset, liWidth, menuWidth, pageWidth)) {
|
||||
alignment = (alignment === 'left' ? 'right' : 'left');
|
||||
}
|
||||
}
|
||||
|
||||
$menu.addClass('dropdown-menu-' + alignment);
|
||||
},
|
||||
});
|
||||
|
||||
publicWidget.registry.hoverableDropdown = animations.Animation.extend({
|
||||
selector: 'header.o_hoverable_dropdown',
|
||||
disabledInEditableMode: false,
|
||||
|
||||
Reference in New Issue
Block a user