123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- /**
- * ownCloud
- *
- * @author Vincent Petry
- * @copyright 2014 Vincent Petry <pvince81@owncloud.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
- *
- * You should have received a copy of the GNU Affero General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
- /* global OC */
- (function() {
- /**
- * Creates an breadcrumb element in the given container
- */
- var BreadCrumb = function(options){
- this.$el = $('<div class="breadcrumb"></div>');
- options = options || {};
- if (options.onClick) {
- this.onClick = options.onClick;
- }
- if (options.onDrop) {
- this.onDrop = options.onDrop;
- }
- if (options.getCrumbUrl) {
- this.getCrumbUrl = options.getCrumbUrl;
- }
- };
- BreadCrumb.prototype = {
- $el: null,
- dir: null,
-
- lastWidth: 0,
- hiddenBreadcrumbs: 0,
- totalWidth: 0,
- breadcrumbs: [],
- onClick: null,
- onDrop: null,
-
- /**
- * Sets the directory to be displayed as breadcrumb.
- * This will re-render the breadcrumb.
- * @param dir path to be displayed as breadcrumb
- */
- setDirectory: function(dir) {
- dir = dir || '/';
- if (dir !== this.dir) {
- this.dir = dir;
- this.render();
- }
- },
-
- /**
- * Returns the full URL to the given directory
- * @param part crumb data as map
- * @param index crumb index
- * @return full URL
- */
- getCrumbUrl: function(part, index) {
- return '#';
- },
-
- /**
- * Renders the breadcrumb elements
- */
- render: function() {
- var parts = this._makeCrumbs(this.dir || '/');
- var $crumb;
- this.$el.empty();
- this.breadcrumbs = [];
-
- for (var i = 0; i < parts.length; i++) {
- var part = parts[i];
- var $image;
- var $link = $('<a></a>').attr('href', this.getCrumbUrl(part, i));
- $link.text(part.name);
- $crumb = $('<div class="crumb svg"></div>');
- $crumb.append($link);
- $crumb.attr('data-dir', part.dir);
-
- if (part.img) {
- $image = $('<img class="svg"></img>');
- $image.attr('src', part.img);
- $link.append($image);
- }
- this.breadcrumbs.push($crumb);
- this.$el.append($crumb);
- if (this.onClick) {
- $crumb.on('click', this.onClick);
- }
- }
- $crumb.addClass('last');
-
- // in case svg is not supported by the browser we need to execute the fallback mechanism
- if (!OC.Util.hasSVGSupport()) {
- OC.Util.replaceSVG(this.$el);
- }
-
- // setup drag and drop
- if (this.onDrop) {
- this.$el.find('.crumb:not(.last)').droppable({
- drop: this.onDrop,
- tolerance: 'pointer'
- });
- }
-
- this._updateTotalWidth();
- this.resize($(window).width(), true);
- },
-
- /**
- * Makes a breadcrumb structure based on the given path
- * @param dir path to split into a breadcrumb structure
- * @return array of map {dir: path, name: displayName}
- */
- _makeCrumbs: function(dir) {
- var crumbs = [];
- var pathToHere = '';
- // trim leading and trailing slashes
- dir = dir.replace(/^\/+|\/+$/g, '');
- var parts = dir.split('/');
- if (dir === '') {
- parts = [];
- }
- // root part
- crumbs.push({
- dir: '/',
- name: '',
- img: OC.imagePath('core', 'places/home.svg')
- });
- for (var i = 0; i < parts.length; i++) {
- var part = parts[i];
- pathToHere = pathToHere + '/' + part;
- crumbs.push({
- dir: pathToHere,
- name: part
- });
- }
- return crumbs;
- },
-
- _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').get(0).offsetWidth;
- }
- this.hiddenBreadcrumbs = 0;
-
- for (var i = 0; i < this.breadcrumbs.length; i++ ) {
- this.totalWidth += $(this.breadcrumbs[i]).get(0).offsetWidth;
- }
-
- $.each($('#controls .actions>div'), function(index, action) {
- self.totalWidth += $(action).get(0).offsetWidth;
- });
-
- },
-
- /**
- * Show/hide breadcrumbs to fit the given width
- */
- resize: function (width, firstRun) {
- var i, $crumb;
-
- if (width === this.lastWidth) {
- 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;
- $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;
- }
- }
- i--;
- this.hiddenBreadcrumbs = i;
- }
- }
-
- this.lastWidth = width;
- }
- };
-
- window.BreadCrumb = BreadCrumb;
- })();
|