/** * Handles the resizing of a menu according to the available screen width * * Uses themes/original/css/resizable-menu.css.php * * To initialize: * $('#myMenu').menuResizer(function () { * // This function will be called to find out how much * // available horizontal space there is for the menu * return $('body').width() - 5; // Some extra margin for good measure * }); * * To trigger a resize operation: * $('#myMenu').menuResizer('resize'); // Bind this to $(window).resize() * * To restore the menu to a state like before it was initialized: * $('#myMenu').menuResizer('destroy'); * * @package PhpMyAdmin */ (function ($) { function MenuResizer ($container, widthCalculator) { var self = this; self.$container = $container; self.widthCalculator = widthCalculator; var windowWidth = $(window).width(); if (windowWidth < 768) { $('#pma_navigation_resizer').css({ 'width': '0px' }); } // create submenu container var link = $('', { 'href': '#', 'class': 'nav-link dropdown-toggle', 'id': 'navbarDropdown', 'role': 'button', 'data-bs-toggle': 'dropdown', 'aria-haspopup': 'true', 'aria-expanded': 'false' }).text(Messages.strMore); var img = $container.find('li img'); if (img.length) { $(Functions.getImage('b_more').toString()).prependTo(link); } var $submenu = $('
  • ', { 'class': 'nav-item dropdown d-none' }) .append(link) .append($('', { 'class': 'dropdown-menu dropdown-menu-end', 'aria-labelledby': 'navbarDropdown' })); $container.append($submenu); setTimeout(function () { self.resize(); }, 4); } MenuResizer.prototype.resize = function () { var wmax = this.widthCalculator.call(this.$container); var windowWidth = $(window).width(); var $submenu = this.$container.find('.nav-item.dropdown').last(); var submenuW = $submenu.outerWidth(true); var $submenuUl = $submenu.find('.dropdown-menu'); var $li = this.$container.find('> li'); var $li2 = $submenuUl.find('.dropdown-item'); var moreShown = $li2.length > 0; // Calculate the total width used by all the shown tabs var totalLen = moreShown ? submenuW : 0; var l = $li.length - 1; var i; for (i = 0; i < l; i++) { totalLen += $($li[i]).outerWidth(true); } // eslint-disable-next-line compat/compat var hasVScroll = document.body.scrollHeight > document.body.clientHeight; if (hasVScroll) { windowWidth += 15; } if (windowWidth < 768) { wmax = 2000; } // Now hide menu elements that don't fit into the menubar var hidden = false; // Whether we have hidden any tabs while (totalLen >= wmax && --l >= 0) { // Process the tabs backwards hidden = true; var el = $($li[l]); el.removeClass('nav-item').addClass('dropdown-item'); var elWidth = el.outerWidth(true); el.data('width', elWidth); if (! moreShown) { totalLen -= elWidth; el.prependTo($submenuUl); totalLen += submenuW; moreShown = true; } else { totalLen -= elWidth; el.prependTo($submenuUl); } } // If we didn't hide any tabs, then there might be some space to show some if (! hidden) { // Show menu elements that do fit into the menubar for (i = 0, l = $li2.length; i < l; i++) { totalLen += $($li2[i]).data('width'); // item fits or (it is the last item // and it would fit if More got removed) if (totalLen < wmax || (i === $li2.length - 1 && totalLen - submenuW < wmax) ) { $($li2[i]).removeClass('dropdown-item').addClass('nav-item'); $($li2[i]).insertBefore($submenu); } else { break; } } } // Show/hide the "More" tab as needed if (windowWidth < 768) { $('.navbar-collapse').css({ 'width': windowWidth - 80 - $('#pma_navigation').width() }); $submenu.addClass('d-none'); $('.navbar-collapse').css({ 'overflow': 'hidden' }); } else { $('.navbar-collapse').css({ 'width': 'auto' }); $('.navbar-collapse').css({ 'overflow': 'visible' }); if ($submenuUl.find('li').length > 0) { $submenu.removeClass('d-none'); } else { $submenu.addClass('d-none'); } } }; MenuResizer.prototype.destroy = function () { var $submenu = this.$container.find('.nav-item.dropdown').removeData(); $submenu.find('li').appendTo(this.$container); $submenu.remove(); }; /** Public API */ var methods = { init: function (widthCalculator) { return this.each(function () { var $this = $(this); if (! $this.data('menuResizer')) { $this.data( 'menuResizer', new MenuResizer($this, widthCalculator) ); } }); }, resize: function () { return this.each(function () { var self = $(this).data('menuResizer'); if (self) { self.resize(); } }); }, destroy: function () { return this.each(function () { var self = $(this).data('menuResizer'); if (self) { self.destroy(); } }); } }; /** * Extend jQuery * * @param {string} method * * @return {any} */ $.fn.menuResizer = function (method) { if (methods[method]) { return methods[method].call(this); } else if (typeof method === 'function') { return methods.init.apply(this, [method]); } else { $.error('Method ' + method + ' does not exist on jQuery.menuResizer'); } }; }(jQuery));