From 9422e98151d24e69be06ea3835d96bd409bced6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6?= Date: Fri, 3 Nov 2017 12:23:57 +0100 Subject: [PATCH 01/33] Breadcrumbs hiding calculation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ --- apps/files/js/breadcrumb.js | 80 ++++++++++++------------------------- 1 file changed, 25 insertions(+), 55 deletions(-) diff --git a/apps/files/js/breadcrumb.js b/apps/files/js/breadcrumb.js index 2a4c2bc8a5..544ad70352 100644 --- a/apps/files/js/breadcrumb.js +++ b/apps/files/js/breadcrumb.js @@ -205,7 +205,6 @@ this.totalWidth = 0; for (var i = 0; i < this.breadcrumbs.length; i++ ) { var $crumb = $(this.breadcrumbs[i]); - $crumb.data('real-width', $crumb.width()); this.totalWidth += $crumb.width(); } this._resize(); @@ -213,7 +212,7 @@ /** * Show/hide breadcrumbs to fit the given width - * + * * @param {int} availableWidth available width */ setMaxWidth: function (availableWidth) { @@ -223,6 +222,29 @@ } }, + /** + * Return the number of items to hide + */ + _toShrink: function() { + var maxWidth = this.$el.width(); + var smallestWidth = 50; + // 50px by default for the ellipsis crumb + return Math.ceil((this.totalWidth + 50 - maxWidth) / smallestWidth); + }, + + /** + * Hide the desired number of items + * + * @param {int} number to hide + */ + _hideCrumbs: function(toHide) { + var min = Math.round(this.breadcrumbs.length/2 - toHide/2); + var max = Math.round(this.breadcrumbs.length/2 + toHide/2 - 1); + console.log(this.$el.find('.crumb').slice(min, max)); + this.$el.find('.crumb').removeClass('hidden') + .slice(min, max).addClass('hidden'); + }, + _resize: function() { var i, $crumb, $ellipsisCrumb; @@ -233,64 +255,12 @@ if (this.breadcrumbs.length <= 1) { return; } + this._hideCrumbs(this._toShrink()); - // reset crumbs - this.$el.find('.crumb.ellipsized').remove(); - // unhide all - this.$el.find('.crumb.hidden').removeClass('hidden'); - if (this.totalWidth <= this.availableWidth) { - // no need to compute breadcrumbs, there is enough space - return; - } - - // running width, considering the hidden crumbs - var currentTotalWidth = $(this.breadcrumbs[0]).data('real-width'); - var firstHidden = true; - - // insert ellipsis after root part (root part is always visible) - $ellipsisCrumb = $('
...
'); - $(this.breadcrumbs[0]).after($ellipsisCrumb); - currentTotalWidth += $ellipsisCrumb.width(); - - i = this.breadcrumbs.length - 1; - - // find the first section that would cause the overflow - // then hide everything in front of that - // - // this ensures that the last crumb section stays visible - // for most of the cases and is always the last one to be - // hidden when the screen becomes very narrow - while (i > 0) { - $crumb = $(this.breadcrumbs[i]); - // if the current breadcrumb would cause overflow - if (!firstHidden || currentTotalWidth + $crumb.data('real-width') > this.availableWidth) { - // hide it - $crumb.addClass('hidden'); - if (firstHidden) { - // set the path of this one as title for the ellipsis - this.$el.find('.crumb.ellipsized') - .attr('title', $crumb.attr('data-dir')) - .tooltip(); - this.$el.find('.ellipsis') - .wrap(''); - } - // and all the previous ones (going backwards) - firstHidden = false; - } else { - // add to total width - currentTotalWidth += $crumb.data('real-width'); - } - i--; - } - - if (!OC.Util.hasSVGSupport()) { - OC.Util.replaceSVG(this.$el); - } } }; OCA.Files.BreadCrumb = BreadCrumb; })(); - From 9bb28bab300192b38d29d4fa2809c719af7d0429 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6?= Date: Fri, 3 Nov 2017 12:53:21 +0100 Subject: [PATCH 02/33] Flex to controls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ --- apps/files/js/breadcrumb.js | 5 +++-- core/css/styles.scss | 20 +++++++++++--------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/apps/files/js/breadcrumb.js b/apps/files/js/breadcrumb.js index 544ad70352..c5cb97d5b4 100644 --- a/apps/files/js/breadcrumb.js +++ b/apps/files/js/breadcrumb.js @@ -226,7 +226,8 @@ * Return the number of items to hide */ _toShrink: function() { - var maxWidth = this.$el.width(); + var maxWidth = this.$el.parent().width(); + console.log('Available width:' +maxWidth); var smallestWidth = 50; // 50px by default for the ellipsis crumb return Math.ceil((this.totalWidth + 50 - maxWidth) / smallestWidth); @@ -240,7 +241,7 @@ _hideCrumbs: function(toHide) { var min = Math.round(this.breadcrumbs.length/2 - toHide/2); var max = Math.round(this.breadcrumbs.length/2 + toHide/2 - 1); - console.log(this.$el.find('.crumb').slice(min, max)); + console.log('toShrink: '+toHide); this.$el.find('.crumb').removeClass('hidden') .slice(min, max).addClass('hidden'); }, diff --git a/core/css/styles.scss b/core/css/styles.scss index e5e0145cdd..ba3437a4e4 100644 --- a/core/css/styles.scss +++ b/core/css/styles.scss @@ -237,6 +237,7 @@ body { -moz-user-select: none; -ms-user-select: none; user-select: none; + display: inline-flex; } /* position controls for apps with app-navigation */ @@ -1388,32 +1389,33 @@ span.ui-icon { } /* ---- BREADCRUMB ---- */ - +div.breadcrumb { + display: inline-flex; + overflow: hidden; +} div.crumb { - float: left; - display: block; + display: inline-flex; background-image: url('../img/breadcrumb.svg?v=1'); background-repeat: no-repeat; background-position: right center; height: 44px; background-size: auto 24px; + flex: 1 2 50px; + max-width: 200px; &.hidden { display: none; } a, > span { position: relative; - top: 12px; padding: 14px 24px 14px 17px; color: nc-lighten($color-main-text, 33%); + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; } &.last a { padding-right: 0; } - &:first-child a { - position: relative; - top: 13px; - padding-right: 14px; - } &.last { font-weight: 600; margin-right: 10px; From c80b824a464cb3fb64386be7406f1498ef64766c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Sat, 4 Nov 2017 09:37:21 +0100 Subject: [PATCH 03/33] Fix style and flex width MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- core/css/mobile.scss | 9 ++------- core/css/styles.scss | 27 ++++++++++----------------- 2 files changed, 12 insertions(+), 24 deletions(-) diff --git a/core/css/mobile.scss b/core/css/mobile.scss index aad3070e79..1951847998 100644 --- a/core/css/mobile.scss +++ b/core/css/mobile.scss @@ -81,16 +81,11 @@ opacity: 1; } - -/* controls bar for mobile */ -#controls { - min-width: initial !important; - left: 0 !important; - padding-left: 0; -} /* position controls for apps with app-navigation */ #app-navigation+#app-content #controls { + left: 0 !important; padding-left: 44px; + width: 100%; } /* .viewer-mode is when text editor, PDF viewer, etc is open */ diff --git a/core/css/styles.scss b/core/css/styles.scss index ba3437a4e4..e35f496f8f 100644 --- a/core/css/styles.scss +++ b/core/css/styles.scss @@ -228,7 +228,7 @@ body { right: 0; left: 0; height: 44px; - width: 100%; + width: calc(100% - 250px); padding: 0; margin: 0; background-color: rgba($color-main-background, 0.95); @@ -1391,7 +1391,6 @@ span.ui-icon { /* ---- BREADCRUMB ---- */ div.breadcrumb { display: inline-flex; - overflow: hidden; } div.crumb { display: inline-flex; @@ -1400,33 +1399,27 @@ div.crumb { background-position: right center; height: 44px; background-size: auto 24px; - flex: 1 2 50px; - max-width: 200px; + flex: 0 0 auto; &.hidden { display: none; } - a, > span { + a, + > span { position: relative; - padding: 14px 24px 14px 17px; + padding: 12px 24px 12px 17px; color: nc-lighten($color-main-text, 33%); text-overflow: ellipsis; white-space: nowrap; overflow: hidden; } - &.last a { - padding-right: 0; + &:not(:first-child) a { } - &.last { + &:last-child { font-weight: 600; margin-right: 10px; - } - &.ellipsized { - padding: 0 10px 0 5px; - } - a.ellipsislink { - padding: 0 !important; - position: relative; - top: 8px !important; + a { + padding-right: 0; + } } &:hover, &:focus, a:focus, &:active { opacity: .7; From 9616074f58b2d94f0e1722152720d982a1c2fc0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Sat, 4 Nov 2017 09:37:59 +0100 Subject: [PATCH 04/33] Fix controls width MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- apps/files/css/files.scss | 8 -------- 1 file changed, 8 deletions(-) diff --git a/apps/files/css/files.scss b/apps/files/css/files.scss index d1405517f1..1ef8ac0ef9 100644 --- a/apps/files/css/files.scss +++ b/apps/files/css/files.scss @@ -47,14 +47,6 @@ top: 44px; } -/* make sure there's enough room for the file actions */ -#body-user #filestable { - min-width: 688px; /* 768 (mobile break) - 80 (nav width) */ -} -#body-user #controls { - min-width: 688px; /* 768 (mobile break) - 80 (nav width) */ -} - #filestable tbody tr { height: 51px; } From 6ee75e16af35473caa5e7ee4dbfbf4c63e1d2b4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Sat, 4 Nov 2017 09:45:29 +0100 Subject: [PATCH 05/33] Fixed computation and removed unwanted scripts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- apps/files/js/breadcrumb.js | 89 ++++++++++++++++--------------------- apps/files/js/filelist.js | 34 +++++++------- core/js/js.js | 33 -------------- 3 files changed, 55 insertions(+), 101 deletions(-) diff --git a/apps/files/js/breadcrumb.js b/apps/files/js/breadcrumb.js index c5cb97d5b4..d895572f9b 100644 --- a/apps/files/js/breadcrumb.js +++ b/apps/files/js/breadcrumb.js @@ -136,7 +136,6 @@ $crumb.on('click', this.onClick); } } - $crumb.addClass('last'); _.each(this._detailViews, function(view) { view.render({ @@ -160,8 +159,7 @@ hoverClass: 'canDrop' }); } - - this._updateTotalWidth(); + this._resize(); }, /** @@ -197,55 +195,36 @@ return crumbs; }, - /** - * Calculate the total breadcrumb width when - * all crumbs are expanded - */ - _updateTotalWidth: function () { - this.totalWidth = 0; - for (var i = 0; i < this.breadcrumbs.length; i++ ) { - var $crumb = $(this.breadcrumbs[i]); - this.totalWidth += $crumb.width(); - } - this._resize(); - }, + /** + * Hide the middle crumb + */ + _hideCrumb: function() { + var length = this.$el.find('.crumb:not(.hidden)').length; + // Get the middle one floored down + var elmt = Math.floor(length / 2 - 0.5); + this.$el.find('.crumb:not(.hidden):eq('+elmt+')').addClass('hidden'); + }, - /** - * Show/hide breadcrumbs to fit the given width - * - * @param {int} availableWidth available width - */ - setMaxWidth: function (availableWidth) { - if (this.availableWidth !== availableWidth) { - this.availableWidth = availableWidth; - this._resize(); - } - }, - - /** - * Return the number of items to hide - */ - _toShrink: function() { - var maxWidth = this.$el.parent().width(); - console.log('Available width:' +maxWidth); - var smallestWidth = 50; - // 50px by default for the ellipsis crumb - return Math.ceil((this.totalWidth + 50 - maxWidth) / smallestWidth); - }, - - /** - * Hide the desired number of items - * - * @param {int} number to hide - */ - _hideCrumbs: function(toHide) { - var min = Math.round(this.breadcrumbs.length/2 - toHide/2); - var max = Math.round(this.breadcrumbs.length/2 + toHide/2 - 1); - console.log('toShrink: '+toHide); - this.$el.find('.crumb').removeClass('hidden') - .slice(min, max).addClass('hidden'); + /** + * Get the crumb to show + */ + _getCrumbElement: function() { + var length = this.$el.find('.crumb.hidden').length; + // Get the outer one with priority to the highest + var elmt = (length % 2) * (length - 1); + return this.$el.find('.crumb.hidden:eq('+elmt+')'); }, + /** + * Show the middle crumb + */ + _showCrumb: function() { + if(this.$el.find('.crumb.hidden').length === 1) { + this.$el.find('.crumb.hidden').removeClass('hidden'); + } + this._getCrumbElement().removeClass('hidden'); + }, + _resize: function() { var i, $crumb, $ellipsisCrumb; @@ -256,9 +235,17 @@ if (this.breadcrumbs.length <= 1) { return; } - this._hideCrumbs(this._toShrink()); - + // If container is smaller than content + while (this.$el.width() > this.$el.parent().width()) { + 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.$el.width() + this._getCrumbElement().width() < this.$el.parent().width()) { + this._showCrumb(); + } } }; diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 4790afcf4d..0fdec811a3 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -322,7 +322,7 @@ this.$el.find('thead th .columntitle').click(_.bind(this._onClickHeader, this)); - this._onResize = _.debounce(_.bind(this._onResize, this), 100); + this._onResize = _.debounce(_.bind(this._onResize, this), 250); $('#app-content').on('appresized', this._onResize); $(window).resize(this._onResize); @@ -555,7 +555,7 @@ // subtract app navigation toggle when visible containerWidth -= $('#app-navigation-toggle').width(); - this.breadcrumb.setMaxWidth(containerWidth - actionsWidth - 10); + this.breadcrumb._resize(); this.$table.find('>thead').width($('#app-content').width() - OC.Util.getScrollBarWidth()); }, @@ -1709,7 +1709,7 @@ if (status === 500) { // Go home this.changeDirectory('/'); - OC.Notification.show(t('files', 'This directory is unavailable, please check the logs or contact the administrator'), + OC.Notification.show(t('files', 'This directory is unavailable, please check the logs or contact the administrator'), {type: 'error'} ); return false; @@ -1720,7 +1720,7 @@ if (this.getCurrentDirectory() !== '/') { this.changeDirectory('/'); // TODO: read error message from exception - OC.Notification.show(t('files', 'Storage is temporarily not available'), + OC.Notification.show(t('files', 'Storage is temporarily not available'), {type: 'error'} ); } @@ -2036,11 +2036,11 @@ .fail(function(status) { if (status === 412) { // TODO: some day here we should invoke the conflict dialog - OC.Notification.show(t('files', 'Could not move "{file}", target exists', + OC.Notification.show(t('files', 'Could not move "{file}", target exists', {file: fileName}), {type: 'error'} ); } else { - OC.Notification.show(t('files', 'Could not move "{file}"', + OC.Notification.show(t('files', 'Could not move "{file}"', {file: fileName}), {type: 'error'} ); } @@ -2267,7 +2267,7 @@ // TODO: 409 means current folder does not exist, redirect ? if (status === 404) { // source not found, so remove it from the list - OC.Notification.show(t('files', 'Could not rename "{fileName}", it does not exist any more', + OC.Notification.show(t('files', 'Could not rename "{fileName}", it does not exist any more', {fileName: oldName}), {timeout: 7, type: 'error'} ); @@ -2287,7 +2287,7 @@ ); } else { // restore the item to its previous state - OC.Notification.show(t('files', 'Could not rename "{fileName}"', + OC.Notification.show(t('files', 'Could not rename "{fileName}"', {fileName: oldName}), {type: 'error'} ); } @@ -2372,18 +2372,18 @@ self.addAndFetchFileInfo(targetPath, '', {scrollTo: true}).then(function(status, data) { deferred.resolve(status, data); }, function() { - OC.Notification.show(t('files', 'Could not create file "{file}"', + OC.Notification.show(t('files', 'Could not create file "{file}"', {file: name}), {type: 'error'} ); }); }) .fail(function(status) { if (status === 412) { - OC.Notification.show(t('files', 'Could not create file "{file}" because it already exists', + OC.Notification.show(t('files', 'Could not create file "{file}" because it already exists', {file: name}), {type: 'error'} ); } else { - OC.Notification.show(t('files', 'Could not create file "{file}"', + OC.Notification.show(t('files', 'Could not create file "{file}"', {file: name}), {type: 'error'} ); } @@ -2422,7 +2422,7 @@ self.addAndFetchFileInfo(targetPath, '', {scrollTo:true}).then(function(status, data) { deferred.resolve(status, data); }, function() { - OC.Notification.show(t('files', 'Could not create folder "{dir}"', + OC.Notification.show(t('files', 'Could not create folder "{dir}"', {dir: name}), {type: 'error'} ); }); @@ -2433,20 +2433,20 @@ // add it to the list, for completeness self.addAndFetchFileInfo(targetPath, '', {scrollTo:true}) .done(function(status, data) { - OC.Notification.show(t('files', 'Could not create folder "{dir}" because it already exists', + OC.Notification.show(t('files', 'Could not create folder "{dir}" because it already exists', {dir: name}), {type: 'error'} ); // still consider a failure deferred.reject(createStatus, data); }) .fail(function() { - OC.Notification.show(t('files', 'Could not create folder "{dir}"', + OC.Notification.show(t('files', 'Could not create folder "{dir}"', {dir: name}), {type: 'error'} ); deferred.reject(status); }); } else { - OC.Notification.show(t('files', 'Could not create folder "{dir}"', + OC.Notification.show(t('files', 'Could not create folder "{dir}"', {dir: name}), {type: 'error'} ); deferred.reject(createStatus); @@ -2503,7 +2503,7 @@ deferred.resolve(status, data); }) .fail(function(status) { - OC.Notification.show(t('files', 'Could not create file "{file}"', + OC.Notification.show(t('files', 'Could not create file "{file}"', {file: name}), {type: 'error'} ); deferred.reject(status); @@ -2612,7 +2612,7 @@ removeFromList(file); } else { // only reset the spinner for that one file - OC.Notification.show(t('files', 'Error deleting file "{fileName}".', + OC.Notification.show(t('files', 'Error deleting file "{fileName}".', {fileName: file}), {type: 'error'} ); var deleteAction = self.findFileEl(file).find('.action.delete'); diff --git a/core/js/js.js b/core/js/js.js index 1f84b40a35..730586713a 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -1625,39 +1625,6 @@ function initCore() { // initial call toggleSnapperOnSize(); - // adjust controls bar width - var adjustControlsWidth = function() { - if($('#controls').length) { - var controlsWidth; - // if there is a scrollbar … - if($('#app-content').get(0).scrollHeight > $('#app-content').height()) { - if($(window).width() > 768) { - controlsWidth = $('#content').width() - $('#app-navigation').width() - getScrollBarWidth(); - if (!$('#app-sidebar').hasClass('hidden') && !$('#app-sidebar').hasClass('disappear')) { - controlsWidth -= $('#app-sidebar').width(); - } - } else { - controlsWidth = $('#content').width() - getScrollBarWidth(); - } - } else { // if there is none - if($(window).width() > 768) { - controlsWidth = $('#content').width() - $('#app-navigation').width(); - if (!$('#app-sidebar').hasClass('hidden') && !$('#app-sidebar').hasClass('disappear')) { - controlsWidth -= $('#app-sidebar').width(); - } - } else { - controlsWidth = $('#content').width(); - } - } - $('#controls').css('width', controlsWidth); - $('#controls').css('min-width', controlsWidth); - } - }; - - $(window).resize(_.debounce(adjustControlsWidth, 250)); - - $('body').delegate('#app-content', 'apprendered appresized', _.debounce(adjustControlsWidth, 150)); - } // Update live timestamps every 30 seconds From 1786784d12a66552786138efc22a116d7f0d9154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Sat, 4 Nov 2017 13:02:15 +0100 Subject: [PATCH 06/33] Popover init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- apps/files/js/breadcrumb.js | 55 ++++++++++++++++++++++++++++++++----- core/css/styles.scss | 30 ++++++++++++++++++-- core/img/places/home.svg | 2 +- 3 files changed, 76 insertions(+), 11 deletions(-) diff --git a/apps/files/js/breadcrumb.js b/apps/files/js/breadcrumb.js index d895572f9b..efd236af4a 100644 --- a/apps/files/js/breadcrumb.js +++ b/apps/files/js/breadcrumb.js @@ -33,6 +33,7 @@ */ var BreadCrumb = function(options){ this.$el = $(''); + this.$menu = $(''); options = options || {}; if (options.onClick) { this.onClick = options.onClick; @@ -73,6 +74,8 @@ * @param dir path to be displayed as breadcrumb */ setDirectory: function(dir) { + var err = new Error(); + console.log(err.stack); dir = dir.replace(/\\/g, '/'); dir = dir || '/'; if (dir !== this.dir) { @@ -118,11 +121,18 @@ for (var i = 0; i < parts.length; i++) { var part = parts[i]; var $image; - var $link = $('').attr('href', this.getCrumbUrl(part, i)); - $link.text(part.name); + var $link = $(''); + if(part.dir) { + $link.attr('href', this.getCrumbUrl(part, i)); + } + if(part.name) { + $link.text(part.name); + } + $link.addClass(part.linkclass); $crumb = $('
'); $crumb.append($link); $crumb.attr('data-dir', part.dir); + $crumb.addClass(part.class); if (part.img) { $image = $(''); @@ -159,6 +169,8 @@ hoverClass: 'canDrop' }); } + + this._createMenu(); this._resize(); }, @@ -180,9 +192,12 @@ // root part crumbs.push({ dir: '/', - name: '', - alt: t('files', 'Home'), - img: OC.imagePath('core', 'places/home.svg') + linkclass: 'icon-home' + }); + // menu part + crumbs.push({ + class: 'crumbmenu', + linkclass: 'icon-more' }); for (var i = 0; i < parts.length; i++) { var part = parts[i]; @@ -199,10 +214,11 @@ * Hide the middle crumb */ _hideCrumb: function() { - var length = this.$el.find('.crumb:not(.hidden)').length; + var selector = '.crumb:not(.hidden):not(.crumbmenu)'; + var length = this.$el.find(selector).length; // Get the middle one floored down var elmt = Math.floor(length / 2 - 0.5); - this.$el.find('.crumb:not(.hidden):eq('+elmt+')').addClass('hidden'); + this.$el.find(selector+':eq('+elmt+')').addClass('hidden'); }, /** @@ -225,6 +241,30 @@ this._getCrumbElement().removeClass('hidden'); }, + /** + * Create and append the popovermenu + */ + _createMenu: function() { + this.$el.find('.crumbmenu').append(this.$menu); + }, + + /** + * Update the popovermenu + */ + _updateMenu: function() { + var menuItems = this.$el.children('.crumb.hidden').clone(); + // Hide the crumb menu if no elements + this.$el.find('.crumbmenu').toggleClass('hidden', menuItems.length===0) + + this.$menu.children('ul').html(menuItems); + this.$menu.find('div').replaceWith(function(){ + return $('
  • ', { + html: this.innerHTML + }) + }); + this.$menu.find('a').addClass('icon-triangle-e').wrapInner(''); + }, + _resize: function() { var i, $crumb, $ellipsisCrumb; @@ -247,6 +287,7 @@ this._showCrumb(); } + this._updateMenu(); } }; diff --git a/core/css/styles.scss b/core/css/styles.scss index e35f496f8f..dda502df4d 100644 --- a/core/css/styles.scss +++ b/core/css/styles.scss @@ -1400,18 +1400,39 @@ div.crumb { height: 44px; background-size: auto 24px; flex: 0 0 auto; + order: 1; + &.crumbmenu { + order: 2; + position: relative; + a { + opacity: 0.5 + } + // Fix because of the display flex + .popovermenu { + top: 100%; + margin-right: 3px; + } + } &.hidden { display: none; + ~ .crumb { + order: 3; + } } - a, + > a, > span { position: relative; padding: 12px 24px 12px 17px; - color: nc-lighten($color-main-text, 33%); + opacity: 0.5; text-overflow: ellipsis; white-space: nowrap; overflow: hidden; } + > a[class^='icon-'] { + padding: 0; + width: 44px; + margin-right: 7px; + } &:not(:first-child) a { } &:last-child { @@ -1422,7 +1443,10 @@ div.crumb { } } &:hover, &:focus, a:focus, &:active { - opacity: .7; + > a, + > span { + opacity: .7; + } } } diff --git a/core/img/places/home.svg b/core/img/places/home.svg index 30ef3e31ad..7ef6db0fde 100644 --- a/core/img/places/home.svg +++ b/core/img/places/home.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file From 03d074ebe8517f4bfe7ec7b484c742cb13c5a462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Sat, 4 Nov 2017 17:47:38 +0100 Subject: [PATCH 07/33] Popover filling system updated MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- apps/files/js/breadcrumb.js | 112 +++++++++++++++++++++--------------- core/css/styles.scss | 7 +++ 2 files changed, 72 insertions(+), 47 deletions(-) diff --git a/apps/files/js/breadcrumb.js b/apps/files/js/breadcrumb.js index efd236af4a..2a864a24c5 100644 --- a/apps/files/js/breadcrumb.js +++ b/apps/files/js/breadcrumb.js @@ -33,7 +33,7 @@ */ var BreadCrumb = function(options){ this.$el = $(''); - this.$menu = $(''); + this.$menu = $(''); options = options || {}; if (options.onClick) { this.onClick = options.onClick; @@ -48,6 +48,7 @@ } this._detailViews = []; }; + /** * @memberof OCA.Files */ @@ -74,8 +75,6 @@ * @param dir path to be displayed as breadcrumb */ setDirectory: function(dir) { - var err = new Error(); - console.log(err.stack); dir = dir.replace(/\\/g, '/'); dir = dir || '/'; if (dir !== this.dir) { @@ -115,6 +114,7 @@ render: function() { var parts = this._makeCrumbs(this.dir || '/'); var $crumb; + var $menuItem; this.$el.empty(); this.breadcrumbs = []; @@ -122,6 +122,7 @@ var part = parts[i]; var $image; var $link = $(''); + $crumb = $('
    '); if(part.dir) { $link.attr('href', this.getCrumbUrl(part, i)); } @@ -129,9 +130,10 @@ $link.text(part.name); } $link.addClass(part.linkclass); - $crumb = $('
    '); $crumb.append($link); - $crumb.attr('data-dir', part.dir); + $crumb.data('dir', part.dir); + // Ignore menu button + $crumb.data('crumb-id', i - 1); $crumb.addClass(part.class); if (part.img) { @@ -147,6 +149,23 @@ } } + var err = new Error(); + console.log(err.stack); + // Menu creation + this._createMenu(); + for (var i = 0; i < parts.length; i++) { + var part = parts[i]; + if(part.dir) { + $menuItem = $('
  • '); + $menuItem.find('a').attr('href', this.getCrumbUrl(part, i)); + $menuItem.find('span').text(part.name); + this.$menu.children('ul').append($menuItem); + if (this.onClick) { + $menuItem.on('click', this.onClick); + } + } + } + _.each(this._detailViews, function(view) { view.render({ dirInfo: this.dirInfo @@ -170,7 +189,6 @@ }); } - this._createMenu(); this._resize(); }, @@ -189,16 +207,17 @@ if (dir === '') { parts = []; } - // root part - crumbs.push({ - dir: '/', - linkclass: 'icon-home' - }); // menu part crumbs.push({ class: 'crumbmenu', linkclass: 'icon-more' }); + // root part + crumbs.push({ + name: t('core', 'Home'), + dir: '/', + linkclass: 'icon-home' + }); for (var i = 0; i < parts.length; i++) { var part = parts[i]; pathToHere = pathToHere + '/' + part; @@ -213,57 +232,56 @@ /** * Hide the middle crumb */ - _hideCrumb: function() { - var selector = '.crumb:not(.hidden):not(.crumbmenu)'; - var length = this.$el.find(selector).length; - // Get the middle one floored down - var elmt = Math.floor(length / 2 - 0.5); - this.$el.find(selector+':eq('+elmt+')').addClass('hidden'); - }, + _hideCrumb: function() { + var selector = '.crumb:not(.hidden):not(.crumbmenu)'; + var length = this.$el.find(selector).length; + // Get the middle one floored down + var elmt = Math.floor(length / 2 - 0.5); + this.$el.find(selector+':eq('+elmt+')').addClass('hidden'); + }, /** * Get the crumb to show */ - _getCrumbElement: function() { - var length = this.$el.find('.crumb.hidden').length; - // Get the outer one with priority to the highest - var elmt = (length % 2) * (length - 1); - return this.$el.find('.crumb.hidden:eq('+elmt+')'); - }, + _getCrumbElement: function() { + var length = this.$el.find('.crumb.hidden').length; + // Get the outer one with priority to the highest + var elmt = (length % 2) * (length - 1); + return this.$el.find('.crumb.hidden:eq('+elmt+')'); + }, /** * Show the middle crumb */ - _showCrumb: function() { - if(this.$el.find('.crumb.hidden').length === 1) { - this.$el.find('.crumb.hidden').removeClass('hidden'); - } - this._getCrumbElement().removeClass('hidden'); - }, + _showCrumb: function() { + if(this.$el.find('.crumb.hidden').length === 1) { + this.$el.find('.crumb.hidden').removeClass('hidden'); + } + this._getCrumbElement().removeClass('hidden'); + }, - /** + /** * Create and append the popovermenu */ - _createMenu: function() { - this.$el.find('.crumbmenu').append(this.$menu); - }, + _createMenu: function() { + this.$el.find('.crumbmenu').append(this.$menu); + this.$menu.children('ul').empty(); + }, - /** + /** * Update the popovermenu */ - _updateMenu: function() { - var menuItems = this.$el.children('.crumb.hidden').clone(); - // Hide the crumb menu if no elements - this.$el.find('.crumbmenu').toggleClass('hidden', menuItems.length===0) + _updateMenu: function() { + var menuItems = this.$el.children('.crumb.hidden'); + // Hide the crumb menu if no elements + this.$el.find('.crumbmenu').toggleClass('hidden', menuItems.length===0) - this.$menu.children('ul').html(menuItems); - this.$menu.find('div').replaceWith(function(){ - return $('
  • ', { - html: this.innerHTML - }) - }); - this.$menu.find('a').addClass('icon-triangle-e').wrapInner(''); - }, + this.$menu.find('li').addClass('in-breadcrumb'); + for (var i = 0; i < menuItems.length; i++) { + var crumbId = $(menuItems[i]).data('crumb-id'); + this.$menu.find('li:eq('+crumbId+')').removeClass('in-breadcrumb'); + } + }, _resize: function() { var i, $crumb, $ellipsisCrumb; diff --git a/core/css/styles.scss b/core/css/styles.scss index dda502df4d..8ca1a6beea 100644 --- a/core/css/styles.scss +++ b/core/css/styles.scss @@ -1411,6 +1411,9 @@ div.crumb { .popovermenu { top: 100%; margin-right: 3px; + .in-breadcrumb { + display: none; + } } } &.hidden { @@ -1427,6 +1430,10 @@ div.crumb { text-overflow: ellipsis; white-space: nowrap; overflow: hidden; + &.icon-home { + // Hide home text + text-indent: -9999px; + } } > a[class^='icon-'] { padding: 0; From 33bac270db6977dd65ef02e8bb8b1d75bbefcbbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Mon, 6 Nov 2017 05:27:10 +0100 Subject: [PATCH 08/33] Do not hide root MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- apps/files/js/breadcrumb.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/files/js/breadcrumb.js b/apps/files/js/breadcrumb.js index 2a864a24c5..e44da02fe5 100644 --- a/apps/files/js/breadcrumb.js +++ b/apps/files/js/breadcrumb.js @@ -216,6 +216,7 @@ crumbs.push({ name: t('core', 'Home'), dir: '/', + class: 'crumbhome', linkclass: 'icon-home' }); for (var i = 0; i < parts.length; i++) { @@ -233,7 +234,7 @@ * Hide the middle crumb */ _hideCrumb: function() { - var selector = '.crumb:not(.hidden):not(.crumbmenu)'; + var selector = '.crumb:not(.hidden):not(.crumbhome):not(.crumbmenu)'; var length = this.$el.find(selector).length; // Get the middle one floored down var elmt = Math.floor(length / 2 - 0.5); From 9d3af829f2cdee369aee93250f330b50e57f2505 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Tue, 7 Nov 2017 05:40:26 +0100 Subject: [PATCH 09/33] Fixed breadcrumb action feedback and optimisation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- apps/files/js/breadcrumb.js | 14 +++++++------- apps/files/js/filelist.js | 2 ++ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/apps/files/js/breadcrumb.js b/apps/files/js/breadcrumb.js index e44da02fe5..f087a76a04 100644 --- a/apps/files/js/breadcrumb.js +++ b/apps/files/js/breadcrumb.js @@ -33,7 +33,7 @@ */ var BreadCrumb = function(options){ this.$el = $(''); - this.$menu = $(''); + this.$menu = $(''); options = options || {}; if (options.onClick) { this.onClick = options.onClick; @@ -84,6 +84,7 @@ }, setDirectoryInfo: function(dirInfo) { + console.log(dirInfo); if (dirInfo !== this.dirInfo) { this.dirInfo = dirInfo; this.render(); @@ -144,13 +145,12 @@ } this.breadcrumbs.push($crumb); this.$el.append($crumb); - if (this.onClick) { - $crumb.on('click', this.onClick); + // Only add feedback if not menu + if (this.onClick && i !== 0) { + $link.on('click', this.onClick); } } - var err = new Error(); - console.log(err.stack); // Menu creation this._createMenu(); for (var i = 0; i < parts.length; i++) { @@ -165,7 +165,6 @@ } } } - _.each(this._detailViews, function(view) { view.render({ dirInfo: this.dirInfo @@ -188,7 +187,8 @@ hoverClass: 'canDrop' }); } - + // Menu is destroyed on every change, we need to init it + OC.registerMenu($('.crumbmenu'), $('.crumbmenu > .popovermenu')); this._resize(); }, diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 0fdec811a3..e69fec9b0c 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -836,11 +836,13 @@ * Event handler when clicking on a bread crumb */ _onClickBreadCrumb: function(e) { + console.log('Clicked breadcrumb ', e); var $el = $(e.target).closest('.crumb'), $targetDir = $el.data('dir'); if ($targetDir !== undefined && e.which === 1) { e.preventDefault(); + console.log('Triggered dir change'); this.changeDirectory($targetDir, true, true); this.updateSearch(); } From 396154d7e420d17f103962dff45c4f8cebd59f45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Tue, 7 Nov 2017 05:53:17 +0100 Subject: [PATCH 10/33] Fixed click in menu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- apps/files/js/breadcrumb.js | 6 +++++- apps/files/js/filelist.js | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/apps/files/js/breadcrumb.js b/apps/files/js/breadcrumb.js index f087a76a04..6fbb5c0728 100644 --- a/apps/files/js/breadcrumb.js +++ b/apps/files/js/breadcrumb.js @@ -113,6 +113,9 @@ * Renders the breadcrumb elements */ render: function() { + // Hide menu on render + OC.hideMenus(); + var parts = this._makeCrumbs(this.dir || '/'); var $crumb; var $menuItem; @@ -156,7 +159,8 @@ for (var i = 0; i < parts.length; i++) { var part = parts[i]; if(part.dir) { - $menuItem = $('
  • '); + $menuItem = $('
  • '); + $menuItem.data('dir', part.dir); $menuItem.find('a').attr('href', this.getCrumbUrl(part, i)); $menuItem.find('span').text(part.name); this.$menu.children('ul').append($menuItem); diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index e69fec9b0c..6c71260f17 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -836,8 +836,8 @@ * Event handler when clicking on a bread crumb */ _onClickBreadCrumb: function(e) { - console.log('Clicked breadcrumb ', e); - var $el = $(e.target).closest('.crumb'), + // Select a crumb or a crumb in the menu + var $el = $(e.target).closest('.crumb, .crumblist'), $targetDir = $el.data('dir'); if ($targetDir !== undefined && e.which === 1) { From e4b190d80d35960b587c4228838ed64d7740d6c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Tue, 7 Nov 2017 15:12:11 +0100 Subject: [PATCH 11/33] small bg colour fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- core/css/styles.scss | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/core/css/styles.scss b/core/css/styles.scss index 8ca1a6beea..fe170f3fe3 100644 --- a/core/css/styles.scss +++ b/core/css/styles.scss @@ -1145,9 +1145,6 @@ code { #oc-dialog-filepicker-content { .dirtree { width: 92%; - float: left; - margin-left: 15px; - overflow: hidden; div:first-child a { background-image: url('../img/places/home.svg?v=1'); background-repeat: no-repeat; @@ -1182,7 +1179,7 @@ code { display: none; } .filelist { - background-color: white; + background-color: $color-main-background; width: 100%; } #filestable.filelist { @@ -1389,7 +1386,7 @@ span.ui-icon { } /* ---- BREADCRUMB ---- */ -div.breadcrumb { +.breadcrumb { display: inline-flex; } div.crumb { @@ -1401,6 +1398,7 @@ div.crumb { background-size: auto 24px; flex: 0 0 auto; order: 1; + padding-right: 7px; &.crumbmenu { order: 2; position: relative; @@ -1425,7 +1423,7 @@ div.crumb { > a, > span { position: relative; - padding: 12px 24px 12px 17px; + padding: 12px; opacity: 0.5; text-overflow: ellipsis; white-space: nowrap; From 4fe7ec387076c0c366965a74814c5b58d5b7d178 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Tue, 7 Nov 2017 15:22:35 +0100 Subject: [PATCH 12/33] fix multiple span next to last crumb link MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- core/css/styles.scss | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/css/styles.scss b/core/css/styles.scss index fe170f3fe3..6c9121b031 100644 --- a/core/css/styles.scss +++ b/core/css/styles.scss @@ -1443,8 +1443,9 @@ div.crumb { &:last-child { font-weight: 600; margin-right: 10px; - a { - padding-right: 0; + // Allow multiple span next to the main 'a' + a ~ span { + padding-left: 0; } } &:hover, &:focus, a:focus, &:active { From 397e6af890e92a02cddd531201c95f86425c5c2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Tue, 7 Nov 2017 15:34:11 +0100 Subject: [PATCH 13/33] Fix filepicker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- core/css/styles.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/core/css/styles.scss b/core/css/styles.scss index 6c9121b031..a27029ac96 100644 --- a/core/css/styles.scss +++ b/core/css/styles.scss @@ -1145,6 +1145,7 @@ code { #oc-dialog-filepicker-content { .dirtree { width: 92%; + flex-wrap: wrap; div:first-child a { background-image: url('../img/places/home.svg?v=1'); background-repeat: no-repeat; From 77f6456dc75ec31bd4038e8c95e9914f3e0eb8ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Tue, 7 Nov 2017 15:52:41 +0100 Subject: [PATCH 14/33] Fix click error on oc-dialog breadcrumb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- core/js/oc-dialogs.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/js/oc-dialogs.js b/core/js/oc-dialogs.js index 1bc1399466..9cd806720b 100644 --- a/core/js/oc-dialogs.js +++ b/core/js/oc-dialogs.js @@ -929,7 +929,7 @@ var OCdialogs = { */ _handleTreeListSelect:function(event, type) { var self = event.data; - var dir = $(event.target).parent().data('dir'); + var dir = $(event.target).closest('.crumb').data('dir'); self._fillFilePicker(dir); var getOcDialog = (event.target).closest('.oc-dialog'); var buttonEnableDisable = $('.primary', getOcDialog); From b9fbb6743816c11d48c24bb44a0b2f99b613e9ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Tue, 7 Nov 2017 15:56:41 +0100 Subject: [PATCH 15/33] Design fix for icons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- core/css/styles.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/core/css/styles.scss b/core/css/styles.scss index a27029ac96..c3d3dce67b 100644 --- a/core/css/styles.scss +++ b/core/css/styles.scss @@ -1437,7 +1437,6 @@ div.crumb { > a[class^='icon-'] { padding: 0; width: 44px; - margin-right: 7px; } &:not(:first-child) a { } From 2348d14e48d2482343bcc111347efcdd53c0faf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Tue, 7 Nov 2017 16:25:41 +0100 Subject: [PATCH 16/33] Moved too wide header menu selector to #header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- core/css/header.scss | 49 ++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/core/css/header.scss b/core/css/header.scss index 952389882c..a45e14cda0 100644 --- a/core/css/header.scss +++ b/core/css/header.scss @@ -22,30 +22,6 @@ -ms-user-select: none; } -/* Header menu */ -.menu { - position: absolute; - top: 45px; - background-color: $color-main-background; - box-shadow: 0 1px 10px $color-box-shadow; - border-radius: 0 0 3px 3px; - display: none; - box-sizing: border-box; - z-index: 2000; - - /* Dropdown arrow */ - &:after { - border: 10px solid transparent; - border-bottom-color: $color-main-background; - bottom: 100%; - content: ' '; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - } -} - /* removed until content-focusing issue is fixed */ #skip-to-content a { position: absolute; @@ -96,6 +72,29 @@ } #header { + /* Header menu */ + .menu { + position: relative; + top: 45px; + background-color: $color-main-background; + filter: drop-shadow(0 1px 3px $color-box-shadow); + border-radius: 0 0 3px 3px; + display: none; + box-sizing: border-box; + z-index: 2000; + + /* Dropdown arrow */ + &:after { + border: 10px solid transparent; + border-bottom-color: $color-main-background; + bottom: 100%; + content: ' '; + height: 0; + width: 0; + position: absolute; + pointer-events: none; + } + } .logo { display: inline-flex; background-image: url($image-logo); @@ -211,7 +210,7 @@ nav { left: -100%; width: 160px; background-color: $color-main-background; - box-shadow: 0 1px 10px $color-box-shadow; + filter: drop-shadow(0 1px 3px $color-box-shadow); &:after { /* position of dropdown arrow */ left: 47%; From c6103dc9b725b16df017ba2f0cfd937494012d5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Wed, 8 Nov 2017 13:10:30 +0100 Subject: [PATCH 17/33] Popover icon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- apps/files/js/breadcrumb.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/files/js/breadcrumb.js b/apps/files/js/breadcrumb.js index 6fbb5c0728..b32cbf89b4 100644 --- a/apps/files/js/breadcrumb.js +++ b/apps/files/js/breadcrumb.js @@ -159,10 +159,10 @@ for (var i = 0; i < parts.length; i++) { var part = parts[i]; if(part.dir) { - $menuItem = $('
  • '); + $menuItem = $('
  • '); $menuItem.data('dir', part.dir); $menuItem.find('a').attr('href', this.getCrumbUrl(part, i)); - $menuItem.find('span').text(part.name); + $menuItem.find('span:eq(1)').text(part.name); this.$menu.children('ul').append($menuItem); if (this.onClick) { $menuItem.on('click', this.onClick); From ce391eeccbd11ad163eae9ee5b044d61441a321c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Wed, 8 Nov 2017 13:39:39 +0100 Subject: [PATCH 18/33] Scroll in popover: max 10 items shown and no flex shrink MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- core/css/apps.scss | 1 + core/css/styles.scss | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/core/css/apps.scss b/core/css/apps.scss index 5493375b5a..8f49df7fda 100644 --- a/core/css/apps.scss +++ b/core/css/apps.scss @@ -822,6 +822,7 @@ kbd { } li { display: flex; + flex: 0 0 auto; > button, > a, > .menuitem { diff --git a/core/css/styles.scss b/core/css/styles.scss index c3d3dce67b..381e016213 100644 --- a/core/css/styles.scss +++ b/core/css/styles.scss @@ -1410,6 +1410,10 @@ div.crumb { .popovermenu { top: 100%; margin-right: 3px; + ul { + max-height: 345px; + overflow-y: scroll; + } .in-breadcrumb { display: none; } From 176ad7670f70c0d0717bea2ea82e41ca37a5cc9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Wed, 8 Nov 2017 14:01:57 +0100 Subject: [PATCH 19/33] Fix to-be-shown algorithm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- apps/files/js/breadcrumb.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/files/js/breadcrumb.js b/apps/files/js/breadcrumb.js index b32cbf89b4..4d67d1600f 100644 --- a/apps/files/js/breadcrumb.js +++ b/apps/files/js/breadcrumb.js @@ -249,9 +249,10 @@ * Get the crumb to show */ _getCrumbElement: function() { - var length = this.$el.find('.crumb.hidden').length; + var hidden = this.$el.find('.crumb.hidden').length; + var shown = this.$el.find('.crumb:not(.hidden):not(.crumbhome):not(.crumbmenu)').length; // Get the outer one with priority to the highest - var elmt = (length % 2) * (length - 1); + var elmt = (1 - shown % 2) * (hidden - 1); return this.$el.find('.crumb.hidden:eq('+elmt+')'); }, From 267b673ccb1e2d9da457310bb5fdf31edb2e9d67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Wed, 8 Nov 2017 16:00:40 +0100 Subject: [PATCH 20/33] Updated tests according to new system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- apps/files/js/breadcrumb.js | 41 +++++- apps/files/tests/js/breadcrumbSpec.js | 176 +++++++++++--------------- core/css/styles.scss | 1 + 3 files changed, 113 insertions(+), 105 deletions(-) diff --git a/apps/files/js/breadcrumb.js b/apps/files/js/breadcrumb.js index 4d67d1600f..4b6fc1c6ce 100644 --- a/apps/files/js/breadcrumb.js +++ b/apps/files/js/breadcrumb.js @@ -234,6 +234,36 @@ return crumbs; }, + /** + * 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) { + var totalWidth = 0; + for (var i = 0; i < this.breadcrumbs.length; i++ ) { + var $crumb = $(this.breadcrumbs[i]); + if(!$crumb.hasClass('hidden') || ignoreHidden) { + totalWidth += $crumb.width(); + } + } + return totalWidth; + }, + /** * Hide the middle crumb */ @@ -290,10 +320,11 @@ }, _resize: function() { - var i, $crumb, $ellipsisCrumb; - + // Used for testing since this.$el.parent fails if (!this.availableWidth) { - this.availableWidth = this.$el.width(); + this.usedWidth = this.$el.parent().width(); + } else { + this.usedWidth = this.availableWidth; } if (this.breadcrumbs.length <= 1) { @@ -301,13 +332,13 @@ } // If container is smaller than content - while (this.$el.width() > this.$el.parent().width()) { + while (this.getTotalWidth() > this.usedWidth) { 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.$el.width() + this._getCrumbElement().width() < this.$el.parent().width()) { + && this.getTotalWidth() + this._getCrumbElement().width() < this.usedWidth) { this._showCrumb(); } diff --git a/apps/files/tests/js/breadcrumbSpec.js b/apps/files/tests/js/breadcrumbSpec.js index a26f0176f1..c04b0f1803 100644 --- a/apps/files/tests/js/breadcrumbSpec.js +++ b/apps/files/tests/js/breadcrumbSpec.js @@ -43,80 +43,93 @@ describe('OCA.Files.BreadCrumb tests', function() { var $crumbs; bc.render(); $crumbs = bc.$el.find('.crumb'); - expect($crumbs.length).toEqual(1); - expect($crumbs.eq(0).find('a').attr('href')).toEqual('/#0'); - expect($crumbs.eq(0).find('img').length).toEqual(1); - expect($crumbs.eq(0).attr('data-dir')).toEqual('/'); + // menu and home + expect($crumbs.length).toEqual(2); + expect($crumbs.eq(0).find('a').hasClass('icon-more')).toEqual(true); + expect($crumbs.eq(0).find('div.popovermenu').length).toEqual(1); + expect($crumbs.eq(0).data('dir')).not.toBeDefined(); + expect($crumbs.eq(1).find('a').attr('href')).toEqual('/#1'); + expect($crumbs.eq(1).find('a').hasClass('icon-home')).toEqual(true); + expect($crumbs.eq(1).data('dir')).toEqual('/'); }); it('Renders root when switching to root', function() { var $crumbs; bc.setDirectory('/somedir'); bc.setDirectory('/'); $crumbs = bc.$el.find('.crumb'); - expect($crumbs.length).toEqual(1); - expect($crumbs.eq(0).attr('data-dir')).toEqual('/'); - }); - it('Renders last crumb with "last" class', function() { - bc.setDirectory('/abc/def'); - expect(bc.$el.find('.crumb:last').hasClass('last')).toEqual(true); + expect($crumbs.length).toEqual(2); + expect($crumbs.eq(1).data('dir')).toEqual('/'); }); it('Renders single path section', function() { var $crumbs; bc.setDirectory('/somedir'); $crumbs = bc.$el.find('.crumb'); - expect($crumbs.length).toEqual(2); - expect($crumbs.eq(0).find('a').attr('href')).toEqual('/#0'); - expect($crumbs.eq(0).find('img').length).toEqual(1); - expect($crumbs.eq(0).attr('data-dir')).toEqual('/'); - expect($crumbs.eq(1).find('a').attr('href')).toEqual('/somedir#1'); - expect($crumbs.eq(1).find('img').length).toEqual(0); - expect($crumbs.eq(1).attr('data-dir')).toEqual('/somedir'); + expect($crumbs.length).toEqual(3); + expect($crumbs.eq(0).find('a').hasClass('icon-more')).toEqual(true); + expect($crumbs.eq(0).find('div.popovermenu').length).toEqual(1); + expect($crumbs.eq(0).data('dir')).not.toBeDefined(); + + expect($crumbs.eq(1).find('a').attr('href')).toEqual('/#1'); + expect($crumbs.eq(1).find('a').hasClass('icon-home')).toEqual(true); + expect($crumbs.eq(1).data('dir')).toEqual('/'); + + expect($crumbs.eq(2).find('a').attr('href')).toEqual('/somedir#2'); + expect($crumbs.eq(2).find('img').length).toEqual(0); + expect($crumbs.eq(2).data('dir')).toEqual('/somedir'); }); it('Renders multiple path sections and special chars', function() { var $crumbs; bc.setDirectory('/somedir/with space/abc'); $crumbs = bc.$el.find('.crumb'); - expect($crumbs.length).toEqual(4); - expect($crumbs.eq(0).find('a').attr('href')).toEqual('/#0'); - expect($crumbs.eq(0).find('img').length).toEqual(1); - expect($crumbs.eq(0).attr('data-dir')).toEqual('/'); + expect($crumbs.length).toEqual(5); + expect($crumbs.eq(0).find('a').hasClass('icon-more')).toEqual(true); + expect($crumbs.eq(0).find('div.popovermenu').length).toEqual(1); + expect($crumbs.eq(0).data('dir')).not.toBeDefined(); - expect($crumbs.eq(1).find('a').attr('href')).toEqual('/somedir#1'); - expect($crumbs.eq(1).find('img').length).toEqual(0); - expect($crumbs.eq(1).attr('data-dir')).toEqual('/somedir'); + expect($crumbs.eq(1).find('a').attr('href')).toEqual('/#1'); + expect($crumbs.eq(1).find('a').hasClass('icon-home')).toEqual(true); + expect($crumbs.eq(1).data('dir')).toEqual('/'); - expect($crumbs.eq(2).find('a').attr('href')).toEqual('/somedir/with space#2'); + expect($crumbs.eq(2).find('a').attr('href')).toEqual('/somedir#2'); expect($crumbs.eq(2).find('img').length).toEqual(0); - expect($crumbs.eq(2).attr('data-dir')).toEqual('/somedir/with space'); + expect($crumbs.eq(2).data('dir')).toEqual('/somedir'); - expect($crumbs.eq(3).find('a').attr('href')).toEqual('/somedir/with space/abc#3'); + expect($crumbs.eq(3).find('a').attr('href')).toEqual('/somedir/with space#3'); expect($crumbs.eq(3).find('img').length).toEqual(0); - expect($crumbs.eq(3).attr('data-dir')).toEqual('/somedir/with space/abc'); + expect($crumbs.eq(3).data('dir')).toEqual('/somedir/with space'); + + expect($crumbs.eq(4).find('a').attr('href')).toEqual('/somedir/with space/abc#4'); + expect($crumbs.eq(4).find('img').length).toEqual(0); + expect($crumbs.eq(4).data('dir')).toEqual('/somedir/with space/abc'); }); it('Renders backslashes as regular directory separator', function() { var $crumbs; bc.setDirectory('/somedir\\with/mixed\\separators'); $crumbs = bc.$el.find('.crumb'); - expect($crumbs.length).toEqual(5); - expect($crumbs.eq(0).find('a').attr('href')).toEqual('/#0'); - expect($crumbs.eq(0).find('img').length).toEqual(1); - expect($crumbs.eq(0).attr('data-dir')).toEqual('/'); + expect($crumbs.length).toEqual(6); + expect($crumbs.eq(0).find('a').hasClass('icon-more')).toEqual(true); + expect($crumbs.eq(0).find('div.popovermenu').length).toEqual(1); + expect($crumbs.eq(0).data('dir')).not.toBeDefined(); - expect($crumbs.eq(1).find('a').attr('href')).toEqual('/somedir#1'); - expect($crumbs.eq(1).find('img').length).toEqual(0); - expect($crumbs.eq(1).attr('data-dir')).toEqual('/somedir'); + expect($crumbs.eq(1).find('a').attr('href')).toEqual('/#1'); + expect($crumbs.eq(1).find('a').hasClass('icon-home')).toEqual(true); + expect($crumbs.eq(1).data('dir')).toEqual('/'); - expect($crumbs.eq(2).find('a').attr('href')).toEqual('/somedir/with#2'); + expect($crumbs.eq(2).find('a').attr('href')).toEqual('/somedir#2'); expect($crumbs.eq(2).find('img').length).toEqual(0); - expect($crumbs.eq(2).attr('data-dir')).toEqual('/somedir/with'); + expect($crumbs.eq(2).data('dir')).toEqual('/somedir'); - expect($crumbs.eq(3).find('a').attr('href')).toEqual('/somedir/with/mixed#3'); + expect($crumbs.eq(3).find('a').attr('href')).toEqual('/somedir/with#3'); expect($crumbs.eq(3).find('img').length).toEqual(0); - expect($crumbs.eq(3).attr('data-dir')).toEqual('/somedir/with/mixed'); + expect($crumbs.eq(3).data('dir')).toEqual('/somedir/with'); - expect($crumbs.eq(4).find('a').attr('href')).toEqual('/somedir/with/mixed/separators#4'); + expect($crumbs.eq(4).find('a').attr('href')).toEqual('/somedir/with/mixed#4'); expect($crumbs.eq(4).find('img').length).toEqual(0); - expect($crumbs.eq(4).attr('data-dir')).toEqual('/somedir/with/mixed/separators'); + expect($crumbs.eq(4).data('dir')).toEqual('/somedir/with/mixed'); + + expect($crumbs.eq(5).find('a').attr('href')).toEqual('/somedir/with/mixed/separators#5'); + expect($crumbs.eq(5).find('img').length).toEqual(0); + expect($crumbs.eq(5).data('dir')).toEqual('/somedir/with/mixed/separators'); }); }); describe('Events', function() { @@ -126,14 +139,15 @@ describe('OCA.Files.BreadCrumb tests', function() { onClick: handler }); bc.setDirectory('/one/two/three/four'); - bc.$el.find('.crumb:eq(3)').click(); - expect(handler.calledOnce).toEqual(true); - expect(handler.getCall(0).thisValue).toEqual(bc.$el.find('.crumb').get(3)); + // Click on crumb does not work, only link + bc.$el.find('.crumb:eq(4)').click(); + expect(handler.calledOnce).toEqual(false); handler.reset(); - bc.$el.find('.crumb:eq(0) a').click(); + // Click on crumb link works + bc.$el.find('.crumb:eq(1) a').click(); expect(handler.calledOnce).toEqual(true); - expect(handler.getCall(0).thisValue).toEqual(bc.$el.find('.crumb').get(0)); + expect(handler.getCall(0).thisValue).toEqual(bc.$el.find('.crumb > a').get(1)); }); it('Calls onDrop handler when dropping on a crumb', function() { var droppableStub = sinon.stub($.fn, 'droppable'); @@ -163,17 +177,12 @@ describe('OCA.Files.BreadCrumb tests', function() { // using hard-coded widths (pre-measured) to avoid getting different // results on different browsers due to font engine differences - widths = [41, 106, 112, 160, 257, 251, 91]; + // 51px is default size for menu and home + widths = [51, 51, 106, 112, 160, 257, 251, 91]; - oldUpdateTotalWidth = BreadCrumb.prototype._updateTotalWidth; - BreadCrumb.prototype._updateTotalWidth = function() { - // pre-set a width to simulate consistent measurement - $('div.crumb').each(function(index){ - $(this).css('width', widths[index]); - }); - - return oldUpdateTotalWidth.apply(this, arguments); - }; + $('div.crumb').each(function(index){ + $(this).css('width', widths[index]); + }); bc = new BreadCrumb(); // append dummy navigation and controls @@ -184,30 +193,26 @@ describe('OCA.Files.BreadCrumb tests', function() { $('#controls').append(bc.$el); }); afterEach(function() { - BreadCrumb.prototype._updateTotalWidth = oldUpdateTotalWidth; bc = null; }); it('Hides breadcrumbs to fit max allowed width', function() { var $crumbs; bc.setMaxWidth(500); + // triggers resize implicitly bc.setDirectory(dummyDir); $crumbs = bc.$el.find('.crumb'); - // first one is always visible + // Menu and home are always visible expect($crumbs.eq(0).hasClass('hidden')).toEqual(false); - // second one has ellipsis expect($crumbs.eq(1).hasClass('hidden')).toEqual(false); - expect($crumbs.eq(1).find('.ellipsis').length).toEqual(1); - // there is only one ellipsis in total - expect($crumbs.find('.ellipsis').length).toEqual(1); - // subsequent elements are hidden + expect($crumbs.eq(2).hasClass('hidden')).toEqual(true); expect($crumbs.eq(3).hasClass('hidden')).toEqual(true); expect($crumbs.eq(4).hasClass('hidden')).toEqual(true); expect($crumbs.eq(5).hasClass('hidden')).toEqual(true); - expect($crumbs.eq(6).hasClass('hidden')).toEqual(false); + expect($crumbs.eq(6).hasClass('hidden')).toEqual(true); expect($crumbs.eq(7).hasClass('hidden')).toEqual(false); }); it('Updates the breadcrumbs when reducing max allowed width', function() { @@ -215,56 +220,27 @@ describe('OCA.Files.BreadCrumb tests', function() { // enough space bc.setMaxWidth(1800); + $crumbs = bc.$el.find('.crumb'); - expect(bc.$el.find('.ellipsis').length).toEqual(0); + // Menu is hidden + expect($crumbs.eq(0).hasClass('hidden')).toEqual(false); // triggers resize implicitly bc.setDirectory(dummyDir); - // simulate increase + // simulate decrease bc.setMaxWidth(950); - $crumbs = bc.$el.find('.crumb'); - // first one is always visible - expect($crumbs.eq(0).hasClass('hidden')).toEqual(false); - // second one has ellipsis - expect($crumbs.eq(1).hasClass('hidden')).toEqual(false); - expect($crumbs.eq(1).find('.ellipsis').length).toEqual(1); - // there is only one ellipsis in total - expect($crumbs.find('.ellipsis').length).toEqual(1); - // subsequent elements are hidden - expect($crumbs.eq(2).hasClass('hidden')).toEqual(true); - expect($crumbs.eq(3).hasClass('hidden')).toEqual(true); - // the rest is visible - expect($crumbs.eq(4).hasClass('hidden')).toEqual(false); - expect($crumbs.eq(5).hasClass('hidden')).toEqual(false); - expect($crumbs.eq(6).hasClass('hidden')).toEqual(false); - }); - it('Removes the ellipsis when there is enough space', function() { - var $crumbs; - - bc.setMaxWidth(500); - // triggers resize implicitly - bc.setDirectory(dummyDir); - $crumbs = bc.$el.find('.crumb'); - - // ellipsis - expect(bc.$el.find('.ellipsis').length).toEqual(1); - - // simulate increase - bc.setMaxWidth(1800); - - // no ellipsis - expect(bc.$el.find('.ellipsis').length).toEqual(0); - - // all are visible + // Menu and home are always visible expect($crumbs.eq(0).hasClass('hidden')).toEqual(false); expect($crumbs.eq(1).hasClass('hidden')).toEqual(false); + expect($crumbs.eq(2).hasClass('hidden')).toEqual(false); expect($crumbs.eq(3).hasClass('hidden')).toEqual(false); expect($crumbs.eq(4).hasClass('hidden')).toEqual(false); expect($crumbs.eq(5).hasClass('hidden')).toEqual(false); expect($crumbs.eq(6).hasClass('hidden')).toEqual(false); + expect($crumbs.eq(7).hasClass('hidden')).toEqual(false); }); }); }); diff --git a/core/css/styles.scss b/core/css/styles.scss index 381e016213..666f428eda 100644 --- a/core/css/styles.scss +++ b/core/css/styles.scss @@ -1433,6 +1433,7 @@ div.crumb { text-overflow: ellipsis; white-space: nowrap; overflow: hidden; + flex: 0 0 auto; &.icon-home { // Hide home text text-indent: -9999px; From 41210c8cf17a07add79e25149c37b23c0c30e35a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Wed, 8 Nov 2017 16:56:58 +0100 Subject: [PATCH 21/33] Add droppable ability to menu and icon switch. Fix colour MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- apps/files/css/files.scss | 4 ++-- apps/files/js/breadcrumb.js | 9 ++++++++- core/css/styles.scss | 6 ++++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/apps/files/css/files.scss b/apps/files/css/files.scss index 1ef8ac0ef9..c7d7ba45d9 100644 --- a/apps/files/css/files.scss +++ b/apps/files/css/files.scss @@ -732,9 +732,9 @@ table.dragshadow td.size { margin-bottom: 2px; } -.canDrop, +.breadcrumb .canDrop > a, #filestable tbody tr.canDrop { - background-color: rgba(255, 255, 140, 1); + background-color: rgb(179, 230, 255); } diff --git a/apps/files/js/breadcrumb.js b/apps/files/js/breadcrumb.js index 4b6fc1c6ce..526cada113 100644 --- a/apps/files/js/breadcrumb.js +++ b/apps/files/js/breadcrumb.js @@ -183,13 +183,20 @@ // setup drag and drop if (this.onDrop) { - this.$el.find('.crumb:not(.last)').droppable({ + this.$el.find('.crumb:not(:last-child):not(.crumbmenu), .crumblist:not(:last-child)').droppable({ drop: this.onDrop, over: this.onOver, out: this.onOut, tolerance: 'pointer', hoverClass: 'canDrop' }); + // Only toggle class to open the menu + this.$el.find('.crumb.crumbmenu').droppable({ + over: this.onOver, + out: this.onOut, + tolerance: 'pointer', + hoverClass: 'canDrop' + }); } // Menu is destroyed on every change, we need to init it OC.registerMenu($('.crumbmenu'), $('.crumbmenu > .popovermenu')); diff --git a/core/css/styles.scss b/core/css/styles.scss index 666f428eda..890773f396 100644 --- a/core/css/styles.scss +++ b/core/css/styles.scss @@ -1406,6 +1406,9 @@ div.crumb { a { opacity: 0.5 } + &.canDrop .popovermenu { + display: block; + } // Fix because of the display flex .popovermenu { top: 100%; @@ -1413,6 +1416,9 @@ div.crumb { ul { max-height: 345px; overflow-y: scroll; + li.canDrop span:first-child { + background-image: url('../img/filetypes/folder-drag-accept.svg?v=1') !important; + } } .in-breadcrumb { display: none; From 694a96d93816f93e487f0d5ce69e3e27e29702e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Wed, 8 Nov 2017 17:54:38 +0100 Subject: [PATCH 22/33] Fixed some more test and loop fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- apps/files/js/breadcrumb.js | 26 +++++++++++++++----------- apps/files/tests/js/breadcrumbSpec.js | 4 ++-- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/apps/files/js/breadcrumb.js b/apps/files/js/breadcrumb.js index 526cada113..da536f9de9 100644 --- a/apps/files/js/breadcrumb.js +++ b/apps/files/js/breadcrumb.js @@ -34,6 +34,8 @@ var BreadCrumb = function(options){ this.$el = $(''); this.$menu = $(''); + + this.crumbSelector = '.crumb:not(.hidden):not(.crumbhome):not(.crumbmenu)'; options = options || {}; if (options.onClick) { this.onClick = options.onClick; @@ -84,7 +86,6 @@ }, setDirectoryInfo: function(dirInfo) { - console.log(dirInfo); if (dirInfo !== this.dirInfo) { this.dirInfo = dirInfo; this.render(); @@ -264,7 +265,7 @@ var totalWidth = 0; for (var i = 0; i < this.breadcrumbs.length; i++ ) { var $crumb = $(this.breadcrumbs[i]); - if(!$crumb.hasClass('hidden') || ignoreHidden) { + if(!$crumb.hasClass('hidden') || ignoreHidden === true) { totalWidth += $crumb.width(); } } @@ -275,11 +276,10 @@ * Hide the middle crumb */ _hideCrumb: function() { - var selector = '.crumb:not(.hidden):not(.crumbhome):not(.crumbmenu)'; - var length = this.$el.find(selector).length; + var length = this.$el.find(this.crumbSelector).length; // Get the middle one floored down var elmt = Math.floor(length / 2 - 0.5); - this.$el.find(selector+':eq('+elmt+')').addClass('hidden'); + this.$el.find(this.crumbSelector+':eq('+elmt+')').addClass('hidden'); }, /** @@ -287,7 +287,7 @@ */ _getCrumbElement: function() { var hidden = this.$el.find('.crumb.hidden').length; - var shown = this.$el.find('.crumb:not(.hidden):not(.crumbhome):not(.crumbmenu)').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+')'); @@ -327,6 +327,12 @@ }, _resize: function() { + + if (this.breadcrumbs.length <= 2) { + // home & menu + return; + } + // Used for testing since this.$el.parent fails if (!this.availableWidth) { this.usedWidth = this.$el.parent().width(); @@ -334,12 +340,10 @@ this.usedWidth = this.availableWidth; } - if (this.breadcrumbs.length <= 1) { - return; - } - // If container is smaller than content - while (this.getTotalWidth() > this.usedWidth) { + // AND if there are crumbs left to hide + while (this.getTotalWidth() > this.usedWidth + && this.$el.find(this.crumbSelector).length > 0) { this._hideCrumb(); } // If container is bigger than content + element to be shown diff --git a/apps/files/tests/js/breadcrumbSpec.js b/apps/files/tests/js/breadcrumbSpec.js index c04b0f1803..b9075265ca 100644 --- a/apps/files/tests/js/breadcrumbSpec.js +++ b/apps/files/tests/js/breadcrumbSpec.js @@ -156,7 +156,7 @@ describe('OCA.Files.BreadCrumb tests', function() { onDrop: handler }); bc.setDirectory('/one/two/three/four'); - expect(droppableStub.calledOnce).toEqual(true); + expect(droppableStub.calledOnce).toEqual(false); expect(droppableStub.getCall(0).args[0].drop).toBeDefined(); // simulate drop @@ -169,7 +169,7 @@ describe('OCA.Files.BreadCrumb tests', function() { }); }); describe('Resizing', function() { - var bc, dummyDir, widths, oldUpdateTotalWidth; + var bc, dummyDir, widths; beforeEach(function() { dummyDir = '/short name/longer name/looooooooooooonger/' + From f25cb7d1566722a0a61b7639140ee676e2548d4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Wed, 8 Nov 2017 18:05:01 +0100 Subject: [PATCH 23/33] Menu hidden by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- apps/files/js/breadcrumb.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/files/js/breadcrumb.js b/apps/files/js/breadcrumb.js index da536f9de9..d57c46a3ee 100644 --- a/apps/files/js/breadcrumb.js +++ b/apps/files/js/breadcrumb.js @@ -221,7 +221,7 @@ } // menu part crumbs.push({ - class: 'crumbmenu', + class: 'crumbmenu hidden', linkclass: 'icon-more' }); // root part @@ -315,9 +315,9 @@ * Update the popovermenu */ _updateMenu: function() { - var menuItems = this.$el.children('.crumb.hidden'); + var menuItems = this.$el.find('.crumb.hidden'); // Hide the crumb menu if no elements - this.$el.find('.crumbmenu').toggleClass('hidden', menuItems.length===0) + this.$el.find('.crumbmenu').toggleClass('hidden', menuItems.length === 0) this.$menu.find('li').addClass('in-breadcrumb'); for (var i = 0; i < menuItems.length; i++) { From b001060556e93ba4c1e1f7aff48390a7612e0b56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Wed, 8 Nov 2017 18:11:33 +0100 Subject: [PATCH 24/33] Fixed remaining tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- apps/files/tests/js/breadcrumbSpec.js | 2 +- apps/files/tests/js/filelistSpec.js | 8 ++++---- apps/files_trashbin/tests/js/filelistSpec.js | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/files/tests/js/breadcrumbSpec.js b/apps/files/tests/js/breadcrumbSpec.js index b9075265ca..5765233c0a 100644 --- a/apps/files/tests/js/breadcrumbSpec.js +++ b/apps/files/tests/js/breadcrumbSpec.js @@ -208,7 +208,7 @@ describe('OCA.Files.BreadCrumb tests', function() { expect($crumbs.eq(0).hasClass('hidden')).toEqual(false); expect($crumbs.eq(1).hasClass('hidden')).toEqual(false); - expect($crumbs.eq(2).hasClass('hidden')).toEqual(true); + expect($crumbs.eq(2).hasClass('hidden')).toEqual(false); expect($crumbs.eq(3).hasClass('hidden')).toEqual(true); expect($crumbs.eq(4).hasClass('hidden')).toEqual(true); expect($crumbs.eq(5).hasClass('hidden')).toEqual(true); diff --git a/apps/files/tests/js/filelistSpec.js b/apps/files/tests/js/filelistSpec.js index 8bb188e360..5d37023f17 100644 --- a/apps/files/tests/js/filelistSpec.js +++ b/apps/files/tests/js/filelistSpec.js @@ -1656,7 +1656,7 @@ describe('OCA.Files.FileList tests', function() { fileList.changeDirectory('/subdir/two/three with space/four/five'); deferredList.resolve(200, [testRoot].concat(testFiles)); var changeDirStub = sinon.stub(fileList, 'changeDirectory'); - fileList.breadcrumb.$el.find('.crumb:eq(0)').trigger({type: 'click', which: 1}); + fileList.breadcrumb.$el.find('.crumb:eq(1) > a').trigger({type: 'click', which: 1}); expect(changeDirStub.calledOnce).toEqual(true); expect(changeDirStub.getCall(0).args[0]).toEqual('/'); @@ -1666,7 +1666,7 @@ describe('OCA.Files.FileList tests', function() { fileList.changeDirectory('/subdir/two/three with space/four/five'); deferredList.resolve(200, [testRoot].concat(testFiles)); var changeDirStub = sinon.stub(fileList, 'changeDirectory'); - fileList.breadcrumb.$el.find('.crumb:eq(3)').trigger({type: 'click', which: 1}); + fileList.breadcrumb.$el.find('.crumb:eq(4) > a').trigger({type: 'click', which: 1}); expect(changeDirStub.calledOnce).toEqual(true); expect(changeDirStub.getCall(0).args[0]).toEqual('/subdir/two/three with space'); @@ -1677,7 +1677,7 @@ describe('OCA.Files.FileList tests', function() { var moveStub = sinon.stub(filesClient, 'move').returns($.Deferred().promise()); fileList.changeDirectory(testDir); deferredList.resolve(200, [testRoot].concat(testFiles)); - var $crumb = fileList.breadcrumb.$el.find('.crumb:eq(3)'); + var $crumb = fileList.breadcrumb.$el.find('.crumb:eq(4)'); // no idea what this is but is required by the handler var ui = { helper: { @@ -2990,7 +2990,7 @@ describe('OCA.Files.FileList tests', function() { it('drop on a breadcrumb inside the table triggers upload to target folder', function() { var ev; fileList.changeDirectory('a/b/c/d'); - ev = dropOn(fileList.$el.find('.crumb:eq(2)'), uploadData); + ev = dropOn(fileList.$el.find('.crumb:eq(3)'), uploadData); expect(ev).not.toEqual(false); expect(uploadData.targetDir).toEqual('/a/b'); diff --git a/apps/files_trashbin/tests/js/filelistSpec.js b/apps/files_trashbin/tests/js/filelistSpec.js index 5e9a4cf27d..04ff243d07 100644 --- a/apps/files_trashbin/tests/js/filelistSpec.js +++ b/apps/files_trashbin/tests/js/filelistSpec.js @@ -132,12 +132,12 @@ describe('OCA.Trashbin.FileList tests', function() { fileList.changeDirectory('/subdir', false, true); fakeServer.respond(); var $crumbs = fileList.$el.find('#controls .crumb'); - expect($crumbs.length).toEqual(2); - expect($crumbs.eq(0).find('a').text()).toEqual(''); - expect($crumbs.eq(0).find('a').attr('href')) - .toEqual(OC.webroot + '/index.php/apps/files?view=trashbin&dir=/'); - expect($crumbs.eq(1).find('a').text()).toEqual('subdir'); + expect($crumbs.length).toEqual(3); + expect($crumbs.eq(1).find('a').text()).toEqual('Home'); expect($crumbs.eq(1).find('a').attr('href')) + .toEqual(OC.webroot + '/index.php/apps/files?view=trashbin&dir=/'); + expect($crumbs.eq(2).find('a').text()).toEqual('subdir'); + expect($crumbs.eq(2).find('a').attr('href')) .toEqual(OC.webroot + '/index.php/apps/files?view=trashbin&dir=/subdir'); }); }); From 584272962a0971d1025c1577f578985d0de7ec83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Wed, 8 Nov 2017 19:03:32 +0100 Subject: [PATCH 25/33] Improve drag & drop and fix some background issue if d&d on narrow windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- apps/files/css/files.scss | 10 +++++++--- apps/files/js/breadcrumb.js | 10 ++-------- apps/files/js/filelist.js | 5 ++--- apps/files/js/files.js | 18 +++++++++++------- core/css/styles.scss | 7 +++++-- 5 files changed, 27 insertions(+), 23 deletions(-) diff --git a/apps/files/css/files.scss b/apps/files/css/files.scss index c7d7ba45d9..1be3c9216f 100644 --- a/apps/files/css/files.scss +++ b/apps/files/css/files.scss @@ -66,12 +66,16 @@ background-color: rgb(179, 230, 255)!important; } -.app-files #app-content.dir-drop, .file-drag #filestable tbody tr, .file-drag #filestable tbody tr:hover{ - background-color: rgba(0, 0, 0, 0)!important; +.app-files #app-content.dir-drop { + background-color: $color-main-background !important; +} + +.file-drag #filestable tbody tr, .file-drag #filestable tbody tr:hover{ + background-color: transparent !important; } .app-files #app-content.dir-drop #filestable tbody tr.dropping-to-dir{ - background-color: rgb(179, 230, 255)!important; + background-color: rgb(179, 230, 255) !important; } /* icons for sidebar */ diff --git a/apps/files/js/breadcrumb.js b/apps/files/js/breadcrumb.js index d57c46a3ee..fc907d5ccc 100644 --- a/apps/files/js/breadcrumb.js +++ b/apps/files/js/breadcrumb.js @@ -189,14 +189,8 @@ over: this.onOver, out: this.onOut, tolerance: 'pointer', - hoverClass: 'canDrop' - }); - // Only toggle class to open the menu - this.$el.find('.crumb.crumbmenu').droppable({ - over: this.onOver, - out: this.onOut, - tolerance: 'pointer', - hoverClass: 'canDrop' + hoverClass: 'canDrop', + greedy: true }); } // Menu is destroyed on every change, we need to init it diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 6c71260f17..23a2fb8bb4 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -842,7 +842,6 @@ if ($targetDir !== undefined && e.which === 1) { e.preventDefault(); - console.log('Triggered dir change'); this.changeDirectory($targetDir, true, true); this.updateSearch(); } @@ -864,8 +863,8 @@ _onDropOnBreadCrumb: function( event, ui ) { var self = this; var $target = $(event.target); - if (!$target.is('.crumb')) { - $target = $target.closest('.crumb'); + if (!$target.is('.crumb, .crumblist')) { + $target = $target.closest('.crumb, .crumblist'); } var targetPath = $(event.target).data('dir'); var dir = this.getCurrentDirectory(); diff --git a/apps/files/js/files.js b/apps/files/js/files.js index e34d7fe255..017bf7ecf4 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -117,32 +117,32 @@ ownerDisplayName = $('#ownerDisplayName').val(); if (usedSpacePercent > 98) { if (owner !== oc_current_user) { - OC.Notification.show(t('files', 'Storage of {owner} is full, files can not be updated or synced anymore!', + OC.Notification.show(t('files', 'Storage of {owner} is full, files can not be updated or synced anymore!', {owner: ownerDisplayName}), {type: 'error'} ); return; } - OC.Notification.show(t('files', - 'Your storage is full, files can not be updated or synced anymore!'), + OC.Notification.show(t('files', + 'Your storage is full, files can not be updated or synced anymore!'), {type : 'error'} ); return; } if (usedSpacePercent > 90) { if (owner !== oc_current_user) { - OC.Notification.show(t('files', 'Storage of {owner} is almost full ({usedSpacePercent}%)', + OC.Notification.show(t('files', 'Storage of {owner} is almost full ({usedSpacePercent}%)', { - usedSpacePercent: usedSpacePercent, + usedSpacePercent: usedSpacePercent, owner: ownerDisplayName }), - { + { type: 'error' } ); return; } OC.Notification.show(t('files', 'Your storage is almost full ({usedSpacePercent}%)', - {usedSpacePercent: usedSpacePercent}), + {usedSpacePercent: usedSpacePercent}), {type : 'error'} ); } @@ -396,6 +396,8 @@ var dragOptions={ } $selectedFiles.closest('tr').addClass('animate-opacity dragging'); $selectedFiles.closest('tr').filter('.ui-droppable').droppable( 'disable' ); + // Show breadcrumbs menu + $('.crumbmenu').addClass('canDropChildren'); }, stop: function(event, ui) { @@ -411,6 +413,8 @@ var dragOptions={ setTimeout(function() { $tr.removeClass('animate-opacity'); }, 300); + // Hide breadcrumbs menu + $('.crumbmenu').removeClass('canDropChildren'); }, drag: function(event, ui) { var scrollingArea = FileList.$container; diff --git a/core/css/styles.scss b/core/css/styles.scss index 890773f396..568830c899 100644 --- a/core/css/styles.scss +++ b/core/css/styles.scss @@ -1406,8 +1406,11 @@ div.crumb { a { opacity: 0.5 } - &.canDrop .popovermenu { - display: block; + &.canDropChildren, + &.canDrop { + .popovermenu { + display: block; + } } // Fix because of the display flex .popovermenu { From aea30e0004bed8f2a36f0c1e79aa16abe884a7d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Wed, 8 Nov 2017 19:12:56 +0100 Subject: [PATCH 26/33] Scrutinizer fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- apps/files/js/breadcrumb.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/files/js/breadcrumb.js b/apps/files/js/breadcrumb.js index fc907d5ccc..e548084f33 100644 --- a/apps/files/js/breadcrumb.js +++ b/apps/files/js/breadcrumb.js @@ -157,13 +157,13 @@ // Menu creation this._createMenu(); - for (var i = 0; i < parts.length; i++) { - var part = parts[i]; - if(part.dir) { + for (var j = 0; j < parts.length; j++) { + var menuPart = parts[j]; + if(menuPart.dir) { $menuItem = $('
  • '); - $menuItem.data('dir', part.dir); - $menuItem.find('a').attr('href', this.getCrumbUrl(part, i)); - $menuItem.find('span:eq(1)').text(part.name); + $menuItem.data('dir', menuPart.dir); + $menuItem.find('a').attr('href', this.getCrumbUrl(part, j)); + $menuItem.find('span:eq(1)').text(menuPart.name); this.$menu.children('ul').append($menuItem); if (this.onClick) { $menuItem.on('click', this.onClick); @@ -311,7 +311,7 @@ _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) + this.$el.find('.crumbmenu').toggleClass('hidden', menuItems.length === 0); this.$menu.find('li').addClass('in-breadcrumb'); for (var i = 0; i < menuItems.length; i++) { From 85355e98e645698b9433674be7ad01b49fc8f20c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Wed, 8 Nov 2017 20:12:38 +0100 Subject: [PATCH 27/33] Fixed tests and width calculation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- apps/files/js/breadcrumb.js | 5 +++-- apps/files/tests/js/breadcrumbSpec.js | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/files/js/breadcrumb.js b/apps/files/js/breadcrumb.js index e548084f33..ccdecbe820 100644 --- a/apps/files/js/breadcrumb.js +++ b/apps/files/js/breadcrumb.js @@ -260,7 +260,7 @@ for (var i = 0; i < this.breadcrumbs.length; i++ ) { var $crumb = $(this.breadcrumbs[i]); if(!$crumb.hasClass('hidden') || ignoreHidden === true) { - totalWidth += $crumb.width(); + totalWidth += $crumb.outerWidth(); } } return totalWidth; @@ -329,10 +329,11 @@ // Used for testing since this.$el.parent fails if (!this.availableWidth) { - this.usedWidth = this.$el.parent().width(); + this.usedWidth = this.$el.parent().width() - this.$el.next('.actions').width(); } else { this.usedWidth = this.availableWidth; } + console.log(this.usedWidth, this.getTotalWidth()); // If container is smaller than content // AND if there are crumbs left to hide diff --git a/apps/files/tests/js/breadcrumbSpec.js b/apps/files/tests/js/breadcrumbSpec.js index 5765233c0a..f0489e927e 100644 --- a/apps/files/tests/js/breadcrumbSpec.js +++ b/apps/files/tests/js/breadcrumbSpec.js @@ -156,7 +156,7 @@ describe('OCA.Files.BreadCrumb tests', function() { onDrop: handler }); bc.setDirectory('/one/two/three/four'); - expect(droppableStub.calledOnce).toEqual(false); + expect(droppableStub.calledOnce).toEqual(true); expect(droppableStub.getCall(0).args[0].drop).toBeDefined(); // simulate drop From 521b8e813d3431928476e7e2e662054898d28d6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Thu, 9 Nov 2017 10:58:51 +0100 Subject: [PATCH 28/33] Fixed header menus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- core/css/header.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/css/header.scss b/core/css/header.scss index a45e14cda0..1844022e8a 100644 --- a/core/css/header.scss +++ b/core/css/header.scss @@ -74,7 +74,6 @@ #header { /* Header menu */ .menu { - position: relative; top: 45px; background-color: $color-main-background; filter: drop-shadow(0 1px 3px $color-box-shadow); @@ -82,6 +81,7 @@ display: none; box-sizing: border-box; z-index: 2000; + position: absolute; /* Dropdown arrow */ &:after { @@ -203,7 +203,7 @@ nav { margin-left: -54px; } -#navigation, +.header-left #navigation, .ui-datepicker, .ui-timepicker.ui-widget { position: relative; From 2a1e9ad046f4e9ae57065a9775e6c99e324c795d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Thu, 9 Nov 2017 11:04:30 +0100 Subject: [PATCH 29/33] Removed console log MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- apps/files/js/breadcrumb.js | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/files/js/breadcrumb.js b/apps/files/js/breadcrumb.js index ccdecbe820..44dccf95b7 100644 --- a/apps/files/js/breadcrumb.js +++ b/apps/files/js/breadcrumb.js @@ -333,7 +333,6 @@ } else { this.usedWidth = this.availableWidth; } - console.log(this.usedWidth, this.getTotalWidth()); // If container is smaller than content // AND if there are crumbs left to hide From ebf131be84cfbab2ce024e7beabcd2820bd7b4bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Thu, 9 Nov 2017 18:46:08 +0100 Subject: [PATCH 30/33] Fixed firefox scrollbar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- core/css/styles.scss | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/css/styles.scss b/core/css/styles.scss index 568830c899..ed72b32113 100644 --- a/core/css/styles.scss +++ b/core/css/styles.scss @@ -1418,7 +1418,9 @@ div.crumb { margin-right: 3px; ul { max-height: 345px; - overflow-y: scroll; + overflow-y: auto; + overflow-x: hidden; + padding-right: 5px; li.canDrop span:first-child { background-image: url('../img/filetypes/folder-drag-accept.svg?v=1') !important; } From f40e56f0e645cfb36ed39decdba7d4a215ed986c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Fri, 10 Nov 2017 08:23:24 +0100 Subject: [PATCH 31/33] Fix menu declaration and width calculation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- apps/files/js/breadcrumb.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/files/js/breadcrumb.js b/apps/files/js/breadcrumb.js index 44dccf95b7..35aeb8d357 100644 --- a/apps/files/js/breadcrumb.js +++ b/apps/files/js/breadcrumb.js @@ -114,8 +114,8 @@ * Renders the breadcrumb elements */ render: function() { - // Hide menu on render - OC.hideMenus(); + // Menu is destroyed on every change, we need to init it + OC.unregisterMenu($('.crumbmenu'), $('.crumbmenu > .popovermenu')); var parts = this._makeCrumbs(this.dir || '/'); var $crumb; @@ -193,8 +193,10 @@ greedy: true }); } + // Menu is destroyed on every change, we need to init it OC.registerMenu($('.crumbmenu'), $('.crumbmenu > .popovermenu')); + this._resize(); }, @@ -329,7 +331,7 @@ // Used for testing since this.$el.parent fails if (!this.availableWidth) { - this.usedWidth = this.$el.parent().width() - this.$el.next('.actions').width(); + this.usedWidth = this.$el.parent().width() - (this.$el.parent().find('.button').length + 1) * 44; } else { this.usedWidth = this.availableWidth; } @@ -337,7 +339,7 @@ // If container is smaller than content // AND if there are crumbs left to hide while (this.getTotalWidth() > this.usedWidth - && this.$el.find(this.crumbSelector).length > 0) { + && this.$el.find(this.crumbSelector).length > 0) { this._hideCrumb(); } // If container is bigger than content + element to be shown From b4f5b38713b140cac2318eaefb945e6126ee81ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Sat, 11 Nov 2017 17:27:56 +0100 Subject: [PATCH 32/33] Add menu tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- apps/files/tests/js/breadcrumbSpec.js | 54 +++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/apps/files/tests/js/breadcrumbSpec.js b/apps/files/tests/js/breadcrumbSpec.js index f0489e927e..fe565f4c3c 100644 --- a/apps/files/tests/js/breadcrumbSpec.js +++ b/apps/files/tests/js/breadcrumbSpec.js @@ -168,6 +168,60 @@ describe('OCA.Files.BreadCrumb tests', function() { droppableStub.restore(); }); }); + + describe('Menu tests', function() { + var bc, dummyDir, $crumbmenuLink, $popovermenu; + + beforeEach(function() { + dummyDir = '/one/two/three/four/five' + + $('div.crumb').each(function(index){ + $(this).css('width', 50); + }); + + bc = new BreadCrumb(); + // append dummy navigation and controls + // as they are currently used for measurements + $('#testArea').append( + '
    ' + ); + $('#controls').append(bc.$el); + + // Shrink to show popovermenu + bc.setMaxWidth(300); + + // triggers resize implicitly + bc.setDirectory(dummyDir); + + $crumbmenuLink = bc.$el.find('.crumbmenu > a'); + $popovermenu = $crumbmenuLink.next('.popovermenu'); + }); + afterEach(function() { + bc = null; + }); + + it('Opens and closes the menu on click', function() { + // Menu exists + expect($popovermenu.length).toEqual(1); + + // Disable jQuery delay + jQuery.fx.off = true + + // Click on menu + $crumbmenuLink.click(); + expect($popovermenu.is(':visible')).toEqual(true); + + // Click on home + $(document).mouseup(); + expect($popovermenu.is(':visible')).toEqual(false); + + }); + it('Shows only items not in the breadcrumb', function() { + var hiddenCrumbs = bc.$el.find('.crumb:not(.crumbmenu).hidden'); + expect($popovermenu.find('li:not(.in-breadcrumb)').length).toEqual(hiddenCrumbs.length); + }); + }); + describe('Resizing', function() { var bc, dummyDir, widths; From 8c2dbeb13a71ca320f6953302f75ce491c4f1aff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Sun, 12 Nov 2017 05:37:01 +0100 Subject: [PATCH 33/33] Added more tests and only test jsunit on drone (for testing only) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- apps/files/tests/js/breadcrumbSpec.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/apps/files/tests/js/breadcrumbSpec.js b/apps/files/tests/js/breadcrumbSpec.js index fe565f4c3c..dd3eac017e 100644 --- a/apps/files/tests/js/breadcrumbSpec.js +++ b/apps/files/tests/js/breadcrumbSpec.js @@ -215,6 +215,19 @@ describe('OCA.Files.BreadCrumb tests', function() { $(document).mouseup(); expect($popovermenu.is(':visible')).toEqual(false); + // Change directory and reset elements + bc.setDirectory('/one/two/three/four/five/six/seven/eight/nine/ten'); + $crumbmenuLink = bc.$el.find('.crumbmenu > a'); + $popovermenu = $crumbmenuLink.next('.popovermenu'); + + // Click on menu again + $crumbmenuLink.click(); + expect($popovermenu.is(':visible')).toEqual(true); + + // Click on home again + $(document).mouseup(); + expect($popovermenu.is(':visible')).toEqual(false); + }); it('Shows only items not in the breadcrumb', function() { var hiddenCrumbs = bc.$el.find('.crumb:not(.crumbmenu).hidden');