diff options
author | Roeland Jago Douma <rullzer@users.noreply.github.com> | 2018-03-01 20:13:26 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-01 20:13:26 +0100 |
commit | 6b931eb64b71a276f4aeb9e24208d6a656d3d657 (patch) | |
tree | 2f691c00bdfacee6e42d431dab746e0ac54476ef /apps/files/js | |
parent | e1e16510a87226d2118631c50509ded0c041d51f (diff) | |
parent | ad71abca6ff6d959dd5979a7f6b73c0a1cbc37fd (diff) | |
download | nextcloud-server-6b931eb64b71a276f4aeb9e24208d6a656d3d657.tar.gz nextcloud-server-6b931eb64b71a276f4aeb9e24208d6a656d3d657.zip |
Merge pull request #8588 from nextcloud/fix-breadcrumbs-width-calculation
Fix breadcrumbs width calculation
Diffstat (limited to 'apps/files/js')
-rw-r--r-- | apps/files/js/breadcrumb.js | 79 |
1 files changed, 45 insertions, 34 deletions
diff --git a/apps/files/js/breadcrumb.js b/apps/files/js/breadcrumb.js index df68865f866..319425b67bd 100644 --- a/apps/files/js/breadcrumb.js +++ b/apps/files/js/breadcrumb.js @@ -36,6 +36,7 @@ this.$menu = $('<div class="popovermenu menu-center"><ul></ul></div>'); this.crumbSelector = '.crumb:not(.hidden):not(.crumbhome):not(.crumbmenu)'; + this.hiddenCrumbSelector = '.crumb.hidden:not(.crumbhome):not(.crumbmenu)'; options = options || {}; if (options.onClick) { this.onClick = options.onClick; @@ -239,30 +240,20 @@ }, /** - * Show/hide breadcrumbs to fit the given width - * Mostly used by tests - * - * @param {int} availableWidth available width - */ - setMaxWidth: function (availableWidth) { - if (this.availableWidth !== availableWidth) { - this.availableWidth = availableWidth; - this._resize(); - } - }, - - /** * Calculate real width based on individual crumbs - * More accurate and works with tests * * @param {boolean} ignoreHidden ignore hidden crumbs */ getTotalWidth: function(ignoreHidden) { + // The width has to be calculated by adding up the width of all the + // crumbs; getting the width of the breadcrumb element is not a + // valid approach, as the returned value could be clamped to its + // parent width. var totalWidth = 0; for (var i = 0; i < this.breadcrumbs.length; i++ ) { var $crumb = $(this.breadcrumbs[i]); if(!$crumb.hasClass('hidden') || ignoreHidden === true) { - totalWidth += $crumb.outerWidth(); + totalWidth += $crumb.outerWidth(true); } } return totalWidth; @@ -282,19 +273,19 @@ * Get the crumb to show */ _getCrumbElement: function() { - var hidden = this.$el.find('.crumb.hidden').length; + var hidden = this.$el.find(this.hiddenCrumbSelector).length; var shown = this.$el.find(this.crumbSelector).length; // Get the outer one with priority to the highest var elmt = (1 - shown % 2) * (hidden - 1); - return this.$el.find('.crumb.hidden:eq('+elmt+')'); + return this.$el.find(this.hiddenCrumbSelector + ':eq('+elmt+')'); }, /** * Show the middle crumb */ _showCrumb: function() { - if(this.$el.find('.crumb.hidden').length === 1) { - this.$el.find('.crumb.hidden').removeClass('hidden'); + if(this.$el.find(this.hiddenCrumbSelector).length === 1) { + this.$el.find(this.hiddenCrumbSelector).removeClass('hidden'); } this._getCrumbElement().removeClass('hidden'); }, @@ -311,9 +302,7 @@ * Update the popovermenu */ _updateMenu: function() { - var menuItems = this.$el.find('.crumb.hidden'); - // Hide the crumb menu if no elements - this.$el.find('.crumbmenu').toggleClass('hidden', menuItems.length === 0); + var menuItems = this.$el.find(this.hiddenCrumbSelector); this.$menu.find('li').addClass('in-breadcrumb'); for (var i = 0; i < menuItems.length; i++) { @@ -329,25 +318,47 @@ return; } - // Used for testing since this.$el.parent fails - if (!this.availableWidth) { - this.usedWidth = this.$el.parent().width() - this.$el.parent().find('.actions.creatable').width(); - } else { - this.usedWidth = this.availableWidth; + // Always hide the menu to ensure that it does not interfere with + // the width calculations; otherwise, the result could be different + // depending on whether the menu was previously being shown or not. + this.$el.find('.crumbmenu').addClass('hidden'); + + // Show the crumbs to compress the siblings before hidding again the + // crumbs. This is needed when the siblings expand to fill all the + // available width, as in that case their old width would limit the + // available width for the crumbs. + // Note that the crumbs shown always overflow the parent width + // (except, of course, when they all fit in). + while (this.$el.find(this.hiddenCrumbSelector).length > 0 + && this.getTotalWidth() <= this.$el.parent().width()) { + this._showCrumb(); } + var siblingsWidth = 0; + this.$el.prevAll(':visible').each(function () { + siblingsWidth += $(this).outerWidth(true); + }); + this.$el.nextAll(':visible').each(function () { + siblingsWidth += $(this).outerWidth(true); + }); + + var availableWidth = this.$el.parent().width() - siblingsWidth; + // If container is smaller than content // AND if there are crumbs left to hide - while (this.getTotalWidth() > this.usedWidth + while (this.getTotalWidth() > availableWidth && this.$el.find(this.crumbSelector).length > 0) { + // As soon as one of the crumbs is hidden the menu will be + // shown. This is needed for proper results in further width + // checks. + // Note that the menu is not shown only when all the crumbs were + // being shown and they all fit the available space; if any of + // the crumbs was not being shown then those shown would + // overflow the available width, so at least one will be hidden + // and thus the menu will be shown. + this.$el.find('.crumbmenu').removeClass('hidden'); this._hideCrumb(); } - // If container is bigger than content + element to be shown - // AND if there is at least one hidden crumb - while (this.$el.find('.crumb.hidden').length > 0 - && this.getTotalWidth() + this._getCrumbElement().width() < this.usedWidth) { - this._showCrumb(); - } this._updateMenu(); } |