diff options
author | Vincent Petry <pvince81@owncloud.com> | 2014-05-23 19:02:50 +0200 |
---|---|---|
committer | Vincent Petry <pvince81@owncloud.com> | 2014-06-27 11:11:34 +0200 |
commit | ec4cf96f0d4f170b21d77378e4f11b88b01aaebc (patch) | |
tree | dde1e495ee09e86f3ab7b213084c8766ba5533cf /apps/files/js | |
parent | 8aa51a69fae60b7b4cb415d923a9978f5698fe0d (diff) | |
download | nextcloud-server-ec4cf96f0d4f170b21d77378e4f11b88b01aaebc.tar.gz nextcloud-server-ec4cf96f0d4f170b21d77378e4f11b88b01aaebc.zip |
Breadcrumb width calculation fix
Rewrote the breadcrumb calculation to be more readable.
Breadcrumb now has a setMaxWidth() method to set the maximum allowed
width which is used to fit the breadcrumbs.
The breadcrumb width is now based on the container width, passed through
setMaxWidth() by the FileList class.
Now using fixed widths for the test crumbs to simulate consistent
widths across browsers which rendering engines might usually yield
different results.
Diffstat (limited to 'apps/files/js')
-rw-r--r-- | apps/files/js/breadcrumb.js | 144 | ||||
-rw-r--r-- | apps/files/js/file-upload.js | 27 | ||||
-rw-r--r-- | apps/files/js/filelist.js | 28 |
3 files changed, 113 insertions, 86 deletions
diff --git a/apps/files/js/breadcrumb.js b/apps/files/js/breadcrumb.js index c017d710d6d..7381fa8e432 100644 --- a/apps/files/js/breadcrumb.js +++ b/apps/files/js/breadcrumb.js @@ -41,8 +41,9 @@ $el: null, dir: null, - lastWidth: 0, - hiddenBreadcrumbs: 0, + /** + * Total width of all breadcrumbs + */ totalWidth: 0, breadcrumbs: [], onClick: null, @@ -116,7 +117,6 @@ } this._updateTotalWidth(); - this.resize($(window).width(), true); }, /** @@ -150,93 +150,93 @@ return crumbs; }, + /** + * Calculate the total breadcrumb width when + * all crumbs are expanded + */ _updateTotalWidth: function () { - var self = this; - - this.lastWidth = 0; - - // initialize with some extra space - this.totalWidth = 64; - // FIXME: this class should not know about global elements - if ( $('#navigation').length ) { - this.totalWidth += $('#navigation').outerWidth(); + 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(); + }, - if ( $('#app-navigation').length && !$('#app-navigation').hasClass('hidden')) { - this.totalWidth += $('#app-navigation').outerWidth(); + /** + * Show/hide breadcrumbs to fit the given width + */ + setMaxWidth: function (availableWidth) { + if (this.availableWidth !== availableWidth) { + this.availableWidth = availableWidth; + this._resize(); } - this.hiddenBreadcrumbs = 0; + }, - for (var i = 0; i < this.breadcrumbs.length; i++ ) { - this.totalWidth += $(this.breadcrumbs[i]).get(0).offsetWidth; + _resize: function() { + var i, $crumb, $ellipsisCrumb; + + if (!this.availableWidth) { + this.availableWidth = this.$el.width(); } - $.each($('#controls .actions'), function(index, action) { - self.totalWidth += $(action).outerWidth(); - }); + if (this.breadcrumbs.length <= 1) { + return; + } - }, + // reset crumbs + this.$el.find('.crumb.ellipsized').remove(); - /** - * Show/hide breadcrumbs to fit the given width - */ - resize: function (width, firstRun) { - var i, $crumb; + // unhide all + this.$el.find('.crumb.hidden').removeClass('hidden'); - if (width === this.lastWidth) { + if (this.totalWidth <= this.availableWidth) { + // no need to compute breadcrumbs, there is enough space return; } - // window was shrinked since last time or first run ? - if ((width < this.lastWidth || firstRun) && width < this.totalWidth) { - if (this.hiddenBreadcrumbs === 0 && this.breadcrumbs.length > 1) { - // start by hiding the first breadcrumb after home, - // that one will have extra three dots displayed - $crumb = this.breadcrumbs[1]; - this.totalWidth -= $crumb.get(0).offsetWidth; - $crumb.find('a').addClass('hidden'); - $crumb.append('<span class="ellipsis">...</span>'); - this.totalWidth += $crumb.get(0).offsetWidth; - this.hiddenBreadcrumbs = 2; - } - i = this.hiddenBreadcrumbs; - // hide subsequent breadcrumbs if the space is still not enough - while (width < this.totalWidth && i > 1 && i < this.breadcrumbs.length - 1) { - $crumb = this.breadcrumbs[i]; - this.totalWidth -= $crumb.get(0).offsetWidth; + // 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 = $('<div class="crumb ellipsized svg"><span class="ellipsis">...</span></div>'); + $(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'); - this.hiddenBreadcrumbs = i; - i++; - } - // window is bigger than last time - } else if (width > this.lastWidth && this.hiddenBreadcrumbs > 0) { - i = this.hiddenBreadcrumbs; - while (width > this.totalWidth && i > 0) { - if (this.hiddenBreadcrumbs === 1) { - // special handling for last one as it has the three dots - $crumb = this.breadcrumbs[1]; - if ($crumb) { - this.totalWidth -= $crumb.get(0).offsetWidth; - $crumb.find('.ellipsis').remove(); - $crumb.find('a').removeClass('hidden'); - this.totalWidth += $crumb.get(0).offsetWidth; - } - } else { - $crumb = this.breadcrumbs[i]; - $crumb.removeClass('hidden'); - this.totalWidth += $crumb.get(0).offsetWidth; - if (this.totalWidth > width) { - this.totalWidth -= $crumb.get(0).offsetWidth; - $crumb.addClass('hidden'); - break; - } + if (firstHidden) { + // set the path of this one as title for the ellipsis + this.$el.find('.crumb.ellipsized') + .attr('title', $crumb.attr('data-dir')) + .tipsy(); } - i--; - this.hiddenBreadcrumbs = i; + // and all the previous ones (going backwards) + firstHidden = false; + } else { + // add to total width + currentTotalWidth += $crumb.data('real-width'); } + i--; } - this.lastWidth = width; + if (!OC.Util.hasSVGSupport()) { + OC.Util.replaceSVG(this.$el); + } } }; diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js index da58e1c31b8..2637d13f9ba 100644 --- a/apps/files/js/file-upload.js +++ b/apps/files/js/file-upload.js @@ -179,9 +179,20 @@ OC.Upload = { callbacks.onNoConflicts(selection); }, + _hideProgressBar: function() { + $('#uploadprogresswrapper input.stop').fadeOut(); + $('#uploadprogressbar').fadeOut(function() { + $('#file_upload_start').trigger(new $.Event('resized')); + }); + }, + + _showProgressBar: function() { + $('#uploadprogressbar').fadeIn(); + $('#file_upload_start').trigger(new $.Event('resized')); + }, + init: function() { if ( $('#file_upload_start').exists() ) { - var file_upload_param = { dropZone: $('#content'), // restrict dropZone to content div autoUpload: false, @@ -444,7 +455,7 @@ OC.Upload = { OC.Upload.log('progress handle fileuploadstart', e, data); $('#uploadprogresswrapper input.stop').show(); $('#uploadprogressbar').progressbar({value: 0}); - $('#uploadprogressbar').fadeIn(); + OC.Upload._showProgressBar(); }); fileupload.on('fileuploadprogress', function(e, data) { OC.Upload.log('progress handle fileuploadprogress', e, data); @@ -458,15 +469,13 @@ OC.Upload = { fileupload.on('fileuploadstop', function(e, data) { OC.Upload.log('progress handle fileuploadstop', e, data); - $('#uploadprogresswrapper input.stop').fadeOut(); - $('#uploadprogressbar').fadeOut(); + OC.Upload._hideProgressBar(); }); fileupload.on('fileuploadfail', function(e, data) { OC.Upload.log('progress handle fileuploadfail', e, data); //if user pressed cancel hide upload progress bar and cancel button if (data.errorThrown === 'abort') { - $('#uploadprogresswrapper input.stop').fadeOut(); - $('#uploadprogressbar').fadeOut(); + OC.Upload._hideProgressBar(); } }); @@ -649,7 +658,7 @@ OC.Upload = { //IE < 10 does not fire the necessary events for the progress bar. if ($('html.lte9').length === 0) { $('#uploadprogressbar').progressbar({value: 0}); - $('#uploadprogressbar').fadeIn(); + OC.Upload._showProgressBar(); } var eventSource = new OC.EventSource( @@ -668,12 +677,12 @@ OC.Upload = { }); eventSource.listen('success', function(data) { var file = data; - $('#uploadprogressbar').fadeOut(); + OC.Upload._hideProgressBar(); FileList.add(file, {hidden: hidden, animate: true}); }); eventSource.listen('error', function(error) { - $('#uploadprogressbar').fadeOut(); + OC.Upload._hideProgressBar(); var message = (error && error.message) || t('core', 'Error fetching URL'); OC.Notification.show(message); //hide notification after 10 sec diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index fb97b2f4595..36f8e063d15 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -150,11 +150,10 @@ this.$el.find('thead th .columntitle').click(_.bind(this._onClickHeader, this)); - $(window).resize(function() { - // TODO: debounce this ? - var width = $(this).width(); - self.breadcrumb.resize(width, false); - }); + this._onResize = _.debounce(_.bind(this._onResize, this), 100); + $(window).resize(this._onResize); + + this.$el.on('show', this._onResize); this.$fileList.on('click','td.filename>a.name', _.bind(this._onClickFile, this)); this.$fileList.on('change', 'td.filename>input:checkbox', _.bind(this._onClickFileCheckbox, this)); @@ -177,6 +176,22 @@ }, /** + * Event handler for when the window size changed + */ + _onResize: function() { + var containerWidth = this.$el.width(); + var actionsWidth = 0; + $.each(this.$el.find('#controls .actions'), function(index, action) { + actionsWidth += $(action).outerWidth(); + }); + + // substract app navigation toggle when visible + containerWidth -= $('#app-navigation-toggle').width(); + + this.breadcrumb.setMaxWidth(containerWidth - actionsWidth - 10); + }, + + /** * Event handler for when the URL changed */ _onUrlChanged: function(e) { @@ -1530,6 +1545,9 @@ // handle upload events var fileUploadStart = this.$el.find('#file_upload_start'); + // detect the progress bar resize + fileUploadStart.on('resized', this._onResize); + fileUploadStart.on('fileuploaddrop', function(e, data) { OC.Upload.log('filelist handle fileuploaddrop', e, data); |