mirror of
https://github.com/YunoHost-Apps/limesurvey_ynh.git
synced 2024-09-03 19:36:32 +02:00
395 lines
15 KiB
JavaScript
395 lines
15 KiB
JavaScript
/*
|
|
* Bootstrap Image Gallery 2.8.1
|
|
* https://github.com/blueimp/Bootstrap-Image-Gallery
|
|
*
|
|
* Copyright 2011, Sebastian Tschan
|
|
* https://blueimp.net
|
|
*
|
|
* Licensed under the MIT license:
|
|
* http://www.opensource.org/licenses/MIT
|
|
*/
|
|
|
|
/*jslint nomen: true, regexp: true */
|
|
/*global define, window, document, jQuery */
|
|
|
|
(function (factory) {
|
|
'use strict';
|
|
if (typeof define === 'function' && define.amd) {
|
|
// Register as an anonymous AMD module:
|
|
define([
|
|
'jquery',
|
|
'load-image',
|
|
'bootstrap'
|
|
], factory);
|
|
} else {
|
|
// Browser globals:
|
|
factory(
|
|
window.jQuery,
|
|
window.loadImage
|
|
);
|
|
}
|
|
}(function ($, loadImage) {
|
|
'use strict';
|
|
// Bootstrap Image Gallery is an extension to the Modal dialog of Twitter's
|
|
// Bootstrap toolkit, to ease navigation between a set of gallery images.
|
|
// It features transition effects, fullscreen mode and slideshow functionality.
|
|
$.extend($.fn.modal.defaults, {
|
|
// Delegate to search gallery links from, can be anything that
|
|
// is accepted as parameter for $():
|
|
delegate: document,
|
|
// Selector for gallery links:
|
|
selector: null,
|
|
// The filter for the selected gallery links (e.g. set to ":odd" to
|
|
// filter out label and thumbnail linking twice to the same image):
|
|
filter: '*',
|
|
// The index of the first gallery image to show:
|
|
index: 0,
|
|
// The href of the first gallery image to show (overrides index):
|
|
href: null,
|
|
// The range of images around the current one to preload:
|
|
preloadRange: 2,
|
|
// Offset of image width to viewport width:
|
|
offsetWidth: 100,
|
|
// Offset of image height to viewport height:
|
|
offsetHeight: 200,
|
|
// Set to true to display images as canvas elements:
|
|
canvas: false,
|
|
// Shows the next image after the given time in ms (0 = disabled):
|
|
slideshow: 0,
|
|
// Defines the image division for previous/next clicks:
|
|
imageClickDivision: 0.5
|
|
});
|
|
var originalShow = $.fn.modal.Constructor.prototype.show,
|
|
originalHide = $.fn.modal.Constructor.prototype.hide;
|
|
$.extend($.fn.modal.Constructor.prototype, {
|
|
initLinks: function () {
|
|
var $this = this,
|
|
options = this.options,
|
|
selector = options.selector ||
|
|
'a[data-target=' + options.target + ']';
|
|
this.$links = $(options.delegate).find(selector)
|
|
.filter(options.filter).each(function (index) {
|
|
if ($this.getUrl(this) === options.href) {
|
|
options.index = index;
|
|
}
|
|
});
|
|
if (!this.$links[options.index]) {
|
|
options.index = 0;
|
|
}
|
|
},
|
|
getUrl: function (element) {
|
|
return element.href || $(element).data('href');
|
|
},
|
|
startSlideShow: function () {
|
|
var $this = this;
|
|
if (this.options.slideshow) {
|
|
this._slideShow = window.setTimeout(
|
|
function () {
|
|
$this.next();
|
|
},
|
|
this.options.slideshow
|
|
);
|
|
}
|
|
},
|
|
stopSlideShow: function () {
|
|
window.clearTimeout(this._slideShow);
|
|
},
|
|
toggleSlideShow: function () {
|
|
var node = this.$element.find('.modal-slideshow');
|
|
if (this.options.slideshow) {
|
|
this.options.slideshow = 0;
|
|
this.stopSlideShow();
|
|
} else {
|
|
this.options.slideshow = node.data('slideshow') || 5000;
|
|
this.startSlideShow();
|
|
}
|
|
node.find('i').toggleClass('icon-play icon-pause');
|
|
},
|
|
preloadImages: function () {
|
|
var options = this.options,
|
|
range = options.index + options.preloadRange + 1,
|
|
link,
|
|
i;
|
|
for (i = options.index - options.preloadRange; i < range; i += 1) {
|
|
link = this.$links[i];
|
|
if (link && i !== options.index) {
|
|
$('<img>').prop('src', this.getUrl(link));
|
|
}
|
|
}
|
|
},
|
|
loadImage: function () {
|
|
var $this = this,
|
|
modal = this.$element,
|
|
index = this.options.index,
|
|
url = this.getUrl(this.$links[index]),
|
|
oldImg;
|
|
this.abortLoad();
|
|
this.stopSlideShow();
|
|
modal.trigger('beforeLoad');
|
|
// The timeout prevents displaying a loading status,
|
|
// if the image has already been loaded:
|
|
this._loadingTimeout = window.setTimeout(function () {
|
|
modal.addClass('modal-loading');
|
|
}, 100);
|
|
oldImg = modal.find('.modal-image').children().removeClass('in');
|
|
// The timeout allows transition effects to finish:
|
|
window.setTimeout(function () {
|
|
oldImg.remove();
|
|
}, 3000);
|
|
modal.find('.modal-title').text(this.$links[index].title);
|
|
modal.find('.modal-download').prop(
|
|
'href',
|
|
url
|
|
);
|
|
this._loadingImage = loadImage(
|
|
url,
|
|
function (img) {
|
|
$this.img = img;
|
|
window.clearTimeout($this._loadingTimeout);
|
|
modal.removeClass('modal-loading');
|
|
modal.trigger('load');
|
|
$this.showImage(img);
|
|
$this.startSlideShow();
|
|
},
|
|
this._loadImageOptions
|
|
);
|
|
this.preloadImages();
|
|
},
|
|
showImage: function (img) {
|
|
var modal = this.$element,
|
|
transition = $.support.transition && modal.hasClass('fade'),
|
|
method = transition ? modal.animate : modal.css,
|
|
modalImage = modal.find('.modal-image'),
|
|
clone,
|
|
forceReflow;
|
|
modalImage.css({
|
|
width: img.width,
|
|
height: img.height
|
|
});
|
|
modal.find('.modal-title').css({ width: Math.max(img.width, 380) });
|
|
if (transition) {
|
|
clone = modal.clone().hide().appendTo(document.body);
|
|
}
|
|
if ($(window).width() > 767) {
|
|
method.call(modal.stop(), {
|
|
'margin-top': -((clone || modal).outerHeight() / 2),
|
|
'margin-left': -((clone || modal).outerWidth() / 2)
|
|
});
|
|
} else {
|
|
modal.css({
|
|
top: ($(window).height() - (clone || modal).outerHeight()) / 2
|
|
});
|
|
}
|
|
if (clone) {
|
|
clone.remove();
|
|
}
|
|
modalImage.append(img);
|
|
forceReflow = img.offsetWidth;
|
|
modal.trigger('display');
|
|
if (transition) {
|
|
if (modal.is(':visible')) {
|
|
$(img).on(
|
|
$.support.transition.end,
|
|
function (e) {
|
|
// Make sure we don't respond to other transitions events
|
|
// in the container element, e.g. from button elements:
|
|
if (e.target === img) {
|
|
$(img).off($.support.transition.end);
|
|
modal.trigger('displayed');
|
|
}
|
|
}
|
|
).addClass('in');
|
|
} else {
|
|
$(img).addClass('in');
|
|
modal.one('shown', function () {
|
|
modal.trigger('displayed');
|
|
});
|
|
}
|
|
} else {
|
|
$(img).addClass('in');
|
|
modal.trigger('displayed');
|
|
}
|
|
},
|
|
abortLoad: function () {
|
|
if (this._loadingImage) {
|
|
this._loadingImage.onload = this._loadingImage.onerror = null;
|
|
}
|
|
window.clearTimeout(this._loadingTimeout);
|
|
},
|
|
prev: function () {
|
|
var options = this.options;
|
|
options.index -= 1;
|
|
if (options.index < 0) {
|
|
options.index = this.$links.length - 1;
|
|
}
|
|
this.loadImage();
|
|
},
|
|
next: function () {
|
|
var options = this.options;
|
|
options.index += 1;
|
|
if (options.index > this.$links.length - 1) {
|
|
options.index = 0;
|
|
}
|
|
this.loadImage();
|
|
},
|
|
keyHandler: function (e) {
|
|
switch (e.which) {
|
|
case 37: // left
|
|
case 38: // up
|
|
e.preventDefault();
|
|
this.prev();
|
|
break;
|
|
case 39: // right
|
|
case 40: // down
|
|
e.preventDefault();
|
|
this.next();
|
|
break;
|
|
}
|
|
},
|
|
wheelHandler: function (e) {
|
|
e.preventDefault();
|
|
e = e.originalEvent;
|
|
this._wheelCounter = this._wheelCounter || 0;
|
|
this._wheelCounter += (e.wheelDelta || e.detail || 0);
|
|
if ((e.wheelDelta && this._wheelCounter >= 120) ||
|
|
(!e.wheelDelta && this._wheelCounter < 0)) {
|
|
this.prev();
|
|
this._wheelCounter = 0;
|
|
} else if ((e.wheelDelta && this._wheelCounter <= -120) ||
|
|
(!e.wheelDelta && this._wheelCounter > 0)) {
|
|
this.next();
|
|
this._wheelCounter = 0;
|
|
}
|
|
},
|
|
initGalleryEvents: function () {
|
|
var $this = this,
|
|
modal = this.$element;
|
|
modal.find('.modal-image').on('click.modal-gallery', function (e) {
|
|
var modalImage = $(this);
|
|
if ($this.$links.length === 1) {
|
|
$this.hide();
|
|
} else {
|
|
if ((e.pageX - modalImage.offset().left) / modalImage.width() <
|
|
$this.options.imageClickDivision) {
|
|
$this.prev(e);
|
|
} else {
|
|
$this.next(e);
|
|
}
|
|
}
|
|
});
|
|
modal.find('.modal-prev').on('click.modal-gallery', function (e) {
|
|
$this.prev(e);
|
|
});
|
|
modal.find('.modal-next').on('click.modal-gallery', function (e) {
|
|
$this.next(e);
|
|
});
|
|
modal.find('.modal-slideshow').on('click.modal-gallery', function (e) {
|
|
$this.toggleSlideShow(e);
|
|
});
|
|
$(document)
|
|
.on('keydown.modal-gallery', function (e) {
|
|
$this.keyHandler(e);
|
|
})
|
|
.on(
|
|
'mousewheel.modal-gallery, DOMMouseScroll.modal-gallery',
|
|
function (e) {
|
|
$this.wheelHandler(e);
|
|
}
|
|
);
|
|
},
|
|
destroyGalleryEvents: function () {
|
|
var modal = this.$element;
|
|
this.abortLoad();
|
|
this.stopSlideShow();
|
|
modal.find('.modal-image, .modal-prev, .modal-next, .modal-slideshow')
|
|
.off('click.modal-gallery');
|
|
$(document)
|
|
.off('keydown.modal-gallery')
|
|
.off('mousewheel.modal-gallery, DOMMouseScroll.modal-gallery');
|
|
},
|
|
show: function () {
|
|
if (!this.isShown && this.$element.hasClass('modal-gallery')) {
|
|
var modal = this.$element,
|
|
options = this.options,
|
|
windowWidth = $(window).width(),
|
|
windowHeight = $(window).height();
|
|
if (modal.hasClass('modal-fullscreen')) {
|
|
this._loadImageOptions = {
|
|
maxWidth: windowWidth,
|
|
maxHeight: windowHeight,
|
|
canvas: options.canvas
|
|
};
|
|
if (modal.hasClass('modal-fullscreen-stretch')) {
|
|
this._loadImageOptions.minWidth = windowWidth;
|
|
this._loadImageOptions.minHeight = windowHeight;
|
|
}
|
|
} else {
|
|
this._loadImageOptions = {
|
|
maxWidth: windowWidth - options.offsetWidth,
|
|
maxHeight: windowHeight - options.offsetHeight,
|
|
canvas: options.canvas
|
|
};
|
|
}
|
|
if (windowWidth > 767) {
|
|
modal.css({
|
|
'margin-top': -(modal.outerHeight() / 2),
|
|
'margin-left': -(modal.outerWidth() / 2)
|
|
});
|
|
} else {
|
|
modal.css({
|
|
top: ($(window).height() - modal.outerHeight()) / 2
|
|
});
|
|
}
|
|
this.initGalleryEvents();
|
|
this.initLinks();
|
|
if (this.$links.length) {
|
|
modal.find('.modal-slideshow, .modal-prev, .modal-next')
|
|
.toggle(this.$links.length !== 1);
|
|
modal.toggleClass(
|
|
'modal-single',
|
|
this.$links.length === 1
|
|
);
|
|
this.loadImage();
|
|
}
|
|
}
|
|
originalShow.apply(this, arguments);
|
|
},
|
|
hide: function () {
|
|
if (this.isShown && this.$element.hasClass('modal-gallery')) {
|
|
this.options.delegate = document;
|
|
this.options.href = null;
|
|
this.destroyGalleryEvents();
|
|
}
|
|
originalHide.apply(this, arguments);
|
|
}
|
|
});
|
|
$(function () {
|
|
$(document.body).on(
|
|
'click.modal-gallery.data-api',
|
|
'[data-toggle="modal-gallery"]',
|
|
function (e) {
|
|
var $this = $(this),
|
|
options = $this.data(),
|
|
modal = $(options.target),
|
|
data = modal.data('modal'),
|
|
link;
|
|
if (!data) {
|
|
options = $.extend(modal.data(), options);
|
|
}
|
|
if (!options.selector) {
|
|
options.selector = 'a[rel=gallery]';
|
|
}
|
|
link = $(e.target).closest(options.selector);
|
|
if (link.length && modal.length) {
|
|
e.preventDefault();
|
|
options.href = link.prop('href') || link.data('href');
|
|
options.delegate = link[0] !== this ? this : document;
|
|
if (data) {
|
|
$.extend(data.options, options);
|
|
}
|
|
modal.modal(options);
|
|
}
|
|
}
|
|
);
|
|
});
|
|
}));
|