aboutsummaryrefslogtreecommitdiffstats
path: root/docs/assets/js/baguetteBox.js
diff options
context:
space:
mode:
authorgramanas <anastasis.gramm2@gmail.com>2018-05-03 03:06:50 +0300
committergramanas <anastasis.gramm2@gmail.com>2018-05-03 12:09:27 +0300
commit3a3424774944a421e1b93cbaf533a3500a4d613c (patch)
tree8780bec2bbacde34cf861b7cd4dc11f6f07e813f /docs/assets/js/baguetteBox.js
parentac8a32e855b078e137fe5de4c2bbf9628c004532 (diff)
downloadck-3a3424774944a421e1b93cbaf533a3500a4d613c.tar.gz
ck-3a3424774944a421e1b93cbaf533a3500a4d613c.tar.bz2
ck-3a3424774944a421e1b93cbaf533a3500a4d613c.zip
add site and .gitignore
Diffstat (limited to 'docs/assets/js/baguetteBox.js')
-rw-r--r--docs/assets/js/baguetteBox.js710
1 files changed, 710 insertions, 0 deletions
diff --git a/docs/assets/js/baguetteBox.js b/docs/assets/js/baguetteBox.js
new file mode 100644
index 0000000..5303fae
--- /dev/null
+++ b/docs/assets/js/baguetteBox.js
@@ -0,0 +1,710 @@
+/*!
+ * baguetteBox.js
+ * @author feimosi
+ * @version 1.8.2
+ * @url https://github.com/feimosi/baguetteBox.js
+ */
+
+/* global define, module */
+
+(function (root, factory) {
+ 'use strict';
+ if (typeof define === 'function' && define.amd) {
+ define(factory);
+ } else if (typeof exports === 'object') {
+ module.exports = factory();
+ } else {
+ root.baguetteBox = factory();
+ }
+}(this, function () {
+ 'use strict';
+
+ // SVG shapes used on the buttons
+ var leftArrow = '<svg width="44" height="60">' +
+ '<polyline points="30 10 10 30 30 50" stroke="rgba(255,255,255,0.5)" stroke-width="4"' +
+ 'stroke-linecap="butt" fill="none" stroke-linejoin="round"/>' +
+ '</svg>',
+ rightArrow = '<svg width="44" height="60">' +
+ '<polyline points="14 10 34 30 14 50" stroke="rgba(255,255,255,0.5)" stroke-width="4"' +
+ 'stroke-linecap="butt" fill="none" stroke-linejoin="round"/>' +
+ '</svg>',
+ closeX = '<svg width="30" height="30">' +
+ '<g stroke="rgb(160,160,160)" stroke-width="4">' +
+ '<line x1="5" y1="5" x2="25" y2="25"/>' +
+ '<line x1="5" y1="25" x2="25" y2="5"/>' +
+ '</g></svg>';
+ // Global options and their defaults
+ var options = {},
+ defaults = {
+ captions: true,
+ fullScreen: false,
+ noScrollbars: false,
+ titleTag: false,
+ buttons: 'auto',
+ async: false,
+ preload: 2,
+ animation: 'slideIn',
+ afterShow: null,
+ afterHide: null,
+ // callback when image changes with `currentIndex` and `imagesElements.length` as parameters
+ onChange: null,
+ overlayBackgroundColor: 'rgba(0,0,0,.8)'
+ };
+ // Object containing information about features compatibility
+ var supports = {};
+ // DOM Elements references
+ var overlay, slider, previousButton, nextButton, closeButton;
+ // An array with all images in the current gallery
+ var currentGallery = [];
+ // Current image index inside the slider
+ var currentIndex = 0;
+ // Touch event start position (for slide gesture)
+ var touch = {};
+ // If set to true ignore touch events because animation was already fired
+ var touchFlag = false;
+ // Regex pattern to match image files
+ var regex = /.+\.(gif|jpe?g|png|webp)/i;
+ // Object of all used galleries
+ var data = {};
+ // Array containing temporary images DOM elements
+ var imagesElements = [];
+ // The last focused element before opening the overlay
+ var documentLastFocus = null;
+ var overlayClickHandler = function(event) {
+ // Close the overlay when user clicks directly on the background
+ if (event.target.id.indexOf('baguette-img') !== -1) {
+ hideOverlay();
+ }
+ };
+ var previousButtonClickHandler = function(event) {
+ event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true; // jshint ignore:line
+ showPreviousImage();
+ };
+ var nextButtonClickHandler = function(event) {
+ event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true; // jshint ignore:line
+ showNextImage();
+ };
+ var closeButtonClickHandler = function(event) {
+ event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true; // jshint ignore:line
+ hideOverlay();
+ };
+ var touchstartHandler = function(event) {
+ touch.count++;
+ if (touch.count > 1) {
+ touch.multitouch = true;
+ }
+ // Save x and y axis position
+ touch.startX = event.changedTouches[0].pageX;
+ touch.startY = event.changedTouches[0].pageY;
+ };
+ var touchmoveHandler = function(event) {
+ // If action was already triggered or multitouch return
+ if (touchFlag || touch.multitouch) {
+ return;
+ }
+ event.preventDefault ? event.preventDefault() : event.returnValue = false; // jshint ignore:line
+ var touchEvent = event.touches[0] || event.changedTouches[0];
+ // Move at least 40 pixels to trigger the action
+ if (touchEvent.pageX - touch.startX > 40) {
+ touchFlag = true;
+ showPreviousImage();
+ } else if (touchEvent.pageX - touch.startX < -40) {
+ touchFlag = true;
+ showNextImage();
+ // Move 100 pixels up to close the overlay
+ } else if (touch.startY - touchEvent.pageY > 100) {
+ hideOverlay();
+ }
+ };
+ var touchendHandler = function() {
+ touch.count--;
+ if (touch.count <= 0) {
+ touch.multitouch = false;
+ }
+ touchFlag = false;
+ };
+
+ var trapFocusInsideOverlay = function(event) {
+ if (overlay.style.display === 'block' && (overlay.contains && !overlay.contains(event.target))) {
+ event.stopPropagation();
+ initFocus();
+ }
+ };
+
+ // forEach polyfill for IE8
+ // http://stackoverflow.com/a/14827443/1077846
+ /* jshint ignore:start */
+ if (![].forEach) {
+ Array.prototype.forEach = function(callback, thisArg) {
+ for (var i = 0; i < this.length; i++) {
+ callback.call(thisArg, this[i], i, this);
+ }
+ };
+ }
+
+ // filter polyfill for IE8
+ // https://gist.github.com/eliperelman/1031656
+ if (![].filter) {
+ Array.prototype.filter = function(a, b, c, d, e) {
+ c = this;
+ d = [];
+ for (e = 0; e < c.length; e++)
+ a.call(b, c[e], e, c) && d.push(c[e]);
+ return d;
+ };
+ }
+ /* jshint ignore:end */
+
+ // Script entry point
+ function run(selector, userOptions) {
+ // Fill supports object
+ supports.transforms = testTransformsSupport();
+ supports.svg = testSVGSupport();
+
+ buildOverlay();
+ removeFromCache(selector);
+ bindImageClickListeners(selector, userOptions);
+ }
+
+ function bindImageClickListeners(selector, userOptions) {
+ // For each gallery bind a click event to every image inside it
+ var galleryNodeList = document.querySelectorAll(selector);
+ var selectorData = {
+ galleries: [],
+ nodeList: galleryNodeList
+ };
+ data[selector] = selectorData;
+
+ [].forEach.call(galleryNodeList, function(galleryElement) {
+ if (userOptions && userOptions.filter) {
+ regex = userOptions.filter;
+ }
+
+ // Get nodes from gallery elements or single-element galleries
+ var tagsNodeList = [];
+ if (galleryElement.tagName === 'A') {
+ tagsNodeList = [galleryElement];
+ } else {
+ tagsNodeList = galleryElement.getElementsByTagName('a');
+ }
+
+ // Filter 'a' elements from those not linking to images
+ tagsNodeList = [].filter.call(tagsNodeList, function(element) {
+ return regex.test(element.href);
+ });
+ if (tagsNodeList.length === 0) {
+ return;
+ }
+
+ var gallery = [];
+ [].forEach.call(tagsNodeList, function(imageElement, imageIndex) {
+ var imageElementClickHandler = function(event) {
+ event.preventDefault ? event.preventDefault() : event.returnValue = false; // jshint ignore:line
+ prepareOverlay(gallery, userOptions);
+ showOverlay(imageIndex);
+ };
+ var imageItem = {
+ eventHandler: imageElementClickHandler,
+ imageElement: imageElement
+ };
+ bind(imageElement, 'click', imageElementClickHandler);
+ gallery.push(imageItem);
+ });
+ selectorData.galleries.push(gallery);
+ });
+ }
+
+ function clearCachedData() {
+ for (var selector in data) {
+ if (data.hasOwnProperty(selector)) {
+ removeFromCache(selector);
+ }
+ }
+ }
+
+ function removeFromCache(selector) {
+ if (!data.hasOwnProperty(selector)) {
+ return;
+ }
+ var galleries = data[selector].galleries;
+ [].forEach.call(galleries, function(gallery) {
+ [].forEach.call(gallery, function(imageItem) {
+ unbind(imageItem.imageElement, 'click', imageItem.eventHandler);
+ });
+
+ if (currentGallery === gallery) {
+ currentGallery = [];
+ }
+ });
+
+ delete data[selector];
+ }
+
+ function buildOverlay() {
+ overlay = getByID('baguetteBox-overlay');
+ // Check if the overlay already exists
+ if (overlay) {
+ slider = getByID('baguetteBox-slider');
+ previousButton = getByID('previous-button');
+ nextButton = getByID('next-button');
+ closeButton = getByID('close-button');
+ return;
+ }
+ // Create overlay element
+ overlay = create('div');
+ overlay.setAttribute('role', 'dialog');
+ overlay.id = 'baguetteBox-overlay';
+ document.getElementsByTagName('body')[0].appendChild(overlay);
+ // Create gallery slider element
+ slider = create('div');
+ slider.id = 'baguetteBox-slider';
+ overlay.appendChild(slider);
+ // Create all necessary buttons
+ previousButton = create('button');
+ previousButton.setAttribute('type', 'button');
+ previousButton.id = 'previous-button';
+ previousButton.setAttribute('aria-label', 'Previous');
+ previousButton.innerHTML = supports.svg ? leftArrow : '&lt;';
+ overlay.appendChild(previousButton);
+
+ nextButton = create('button');
+ nextButton.setAttribute('type', 'button');
+ nextButton.id = 'next-button';
+ nextButton.setAttribute('aria-label', 'Next');
+ nextButton.innerHTML = supports.svg ? rightArrow : '&gt;';
+ overlay.appendChild(nextButton);
+
+ closeButton = create('button');
+ closeButton.setAttribute('type', 'button');
+ closeButton.id = 'close-button';
+ closeButton.setAttribute('aria-label', 'Close');
+ closeButton.innerHTML = supports.svg ? closeX : '&times;';
+ overlay.appendChild(closeButton);
+
+ previousButton.className = nextButton.className = closeButton.className = 'baguetteBox-button';
+
+ bindEvents();
+ }
+
+ function keyDownHandler(event) {
+ switch (event.keyCode) {
+ case 37: // Left arrow
+ showPreviousImage();
+ break;
+ case 39: // Right arrow
+ showNextImage();
+ break;
+ case 27: // Esc
+ hideOverlay();
+ break;
+ }
+ }
+
+ function bindEvents() {
+ bind(overlay, 'click', overlayClickHandler);
+ bind(previousButton, 'click', previousButtonClickHandler);
+ bind(nextButton, 'click', nextButtonClickHandler);
+ bind(closeButton, 'click', closeButtonClickHandler);
+ bind(overlay, 'touchstart', touchstartHandler);
+ bind(overlay, 'touchmove', touchmoveHandler);
+ bind(overlay, 'touchend', touchendHandler);
+ bind(document, 'focus', trapFocusInsideOverlay, true);
+ }
+
+ function unbindEvents() {
+ unbind(overlay, 'click', overlayClickHandler);
+ unbind(previousButton, 'click', previousButtonClickHandler);
+ unbind(nextButton, 'click', nextButtonClickHandler);
+ unbind(closeButton, 'click', closeButtonClickHandler);
+ unbind(overlay, 'touchstart', touchstartHandler);
+ unbind(overlay, 'touchmove', touchmoveHandler);
+ unbind(overlay, 'touchend', touchendHandler);
+ unbind(document, 'focus', trapFocusInsideOverlay, true);
+ }
+
+ function prepareOverlay(gallery, userOptions) {
+ // If the same gallery is being opened prevent from loading it once again
+ if (currentGallery === gallery) {
+ return;
+ }
+ currentGallery = gallery;
+ // Update gallery specific options
+ setOptions(userOptions);
+ // Empty slider of previous contents (more effective than .innerHTML = "")
+ while (slider.firstChild) {
+ slider.removeChild(slider.firstChild);
+ }
+ imagesElements.length = 0;
+
+ var imagesFiguresIds = [];
+ var imagesCaptionsIds = [];
+ // Prepare and append images containers and populate figure and captions IDs arrays
+ for (var i = 0, fullImage; i < gallery.length; i++) {
+ fullImage = create('div');
+ fullImage.className = 'full-image';
+ fullImage.id = 'baguette-img-' + i;
+ imagesElements.push(fullImage);
+
+ imagesFiguresIds.push('baguetteBox-figure-' + i);
+ imagesCaptionsIds.push('baguetteBox-figcaption-' + i);
+ slider.appendChild(imagesElements[i]);
+ }
+ overlay.setAttribute('aria-labelledby', imagesFiguresIds.join(' '));
+ overlay.setAttribute('aria-describedby', imagesCaptionsIds.join(' '));
+ }
+
+ function setOptions(newOptions) {
+ if (!newOptions) {
+ newOptions = {};
+ }
+ // Fill options object
+ for (var item in defaults) {
+ options[item] = defaults[item];
+ if (typeof newOptions[item] !== 'undefined') {
+ options[item] = newOptions[item];
+ }
+ }
+ /* Apply new options */
+ // Change transition for proper animation
+ slider.style.transition = slider.style.webkitTransition = (options.animation === 'fadeIn' ? 'opacity .4s ease' :
+ options.animation === 'slideIn' ? '' : 'none');
+ // Hide buttons if necessary
+ if (options.buttons === 'auto' && ('ontouchstart' in window || currentGallery.length === 1)) {
+ options.buttons = false;
+ }
+ // Set buttons style to hide or display them
+ previousButton.style.display = nextButton.style.display = (options.buttons ? '' : 'none');
+ // Set overlay color
+ try {
+ overlay.style.backgroundColor = options.overlayBackgroundColor;
+ } catch (e) {
+ // Silence the error and continue
+ }
+ }
+
+ function showOverlay(chosenImageIndex) {
+ if (options.noScrollbars) {
+ document.documentElement.style.overflowY = 'hidden';
+ document.body.style.overflowY = 'scroll';
+ }
+ if (overlay.style.display === 'block') {
+ return;
+ }
+
+ bind(document, 'keydown', keyDownHandler);
+ currentIndex = chosenImageIndex;
+ touch = {
+ count: 0,
+ startX: null,
+ startY: null
+ };
+ loadImage(currentIndex, function() {
+ preloadNext(currentIndex);
+ preloadPrev(currentIndex);
+ });
+
+ updateOffset();
+ overlay.style.display = 'block';
+ if (options.fullScreen) {
+ enterFullScreen();
+ }
+ // Fade in overlay
+ setTimeout(function() {
+ overlay.className = 'visible';
+ if (options.afterShow) {
+ options.afterShow();
+ }
+ }, 50);
+ if (options.onChange) {
+ options.onChange(currentIndex, imagesElements.length);
+ }
+ documentLastFocus = document.activeElement;
+ initFocus();
+ }
+
+ function initFocus() {
+ if (options.buttons) {
+ previousButton.focus();
+ } else {
+ closeButton.focus();
+ }
+ }
+
+ function enterFullScreen() {
+ if (overlay.requestFullscreen) {
+ overlay.requestFullscreen();
+ } else if (overlay.webkitRequestFullscreen) {
+ overlay.webkitRequestFullscreen();
+ } else if (overlay.mozRequestFullScreen) {
+ overlay.mozRequestFullScreen();
+ }
+ }
+
+ function exitFullscreen() {
+ if (document.exitFullscreen) {
+ document.exitFullscreen();
+ } else if (document.mozCancelFullScreen) {
+ document.mozCancelFullScreen();
+ } else if (document.webkitExitFullscreen) {
+ document.webkitExitFullscreen();
+ }
+ }
+
+ function hideOverlay() {
+ if (options.noScrollbars) {
+ document.documentElement.style.overflowY = 'auto';
+ document.body.style.overflowY = 'auto';
+ }
+ if (overlay.style.display === 'none') {
+ return;
+ }
+
+ unbind(document, 'keydown', keyDownHandler);
+ // Fade out and hide the overlay
+ overlay.className = '';
+ setTimeout(function() {
+ overlay.style.display = 'none';
+ exitFullscreen();
+ if (options.afterHide) {
+ options.afterHide();
+ }
+ }, 500);
+ documentLastFocus.focus();
+ }
+
+ function loadImage(index, callback) {
+ var imageContainer = imagesElements[index];
+ var galleryItem = currentGallery[index];
+
+ // Return if the index exceeds prepared images in the overlay
+ // or if the current gallery has been changed / closed
+ if (imageContainer === undefined || galleryItem === undefined) {
+ return;
+ }
+
+ // If image is already loaded run callback and return
+ if (imageContainer.getElementsByTagName('img')[0]) {
+ if (callback) {
+ callback();
+ }
+ return;
+ }
+
+ // Get element reference, optional caption and source path
+ var imageElement = galleryItem.imageElement;
+ var thumbnailElement = imageElement.getElementsByTagName('img')[0];
+ var imageCaption = typeof options.captions === 'function' ?
+ options.captions.call(currentGallery, imageElement) :
+ imageElement.getAttribute('data-caption') || imageElement.title;
+ var imageSrc = getImageSrc(imageElement);
+
+ // Prepare figure element
+ var figure = create('figure');
+ figure.id = 'baguetteBox-figure-' + index;
+ figure.innerHTML = '<div class="baguetteBox-spinner">' +
+ '<div class="baguetteBox-double-bounce1"></div>' +
+ '<div class="baguetteBox-double-bounce2"></div>' +
+ '</div>';
+ // Insert caption if available
+ if (options.captions && imageCaption) {
+ var figcaption = create('figcaption');
+ figcaption.id = 'baguetteBox-figcaption-' + index;
+ figcaption.innerHTML = imageCaption;
+ figure.appendChild(figcaption);
+ }
+ imageContainer.appendChild(figure);
+
+ // Prepare gallery img element
+ var image = create('img');
+ image.onload = function() {
+ // Remove loader element
+ var spinner = document.querySelector('#baguette-img-' + index + ' .baguetteBox-spinner');
+ figure.removeChild(spinner);
+ if (!options.async && callback) {
+ callback();
+ }
+ };
+ image.setAttribute('src', imageSrc);
+ image.alt = thumbnailElement ? thumbnailElement.alt || '' : '';
+ if (options.titleTag && imageCaption) {
+ image.title = imageCaption;
+ }
+ figure.appendChild(image);
+
+ // Run callback
+ if (options.async && callback) {
+ callback();
+ }
+ }
+
+ // Get image source location, mostly used for responsive images
+ function getImageSrc(image) {
+ // Set default image path from href
+ var result = image.href;
+ // If dataset is supported find the most suitable image
+ if (image.dataset) {
+ var srcs = [];
+ // Get all possible image versions depending on the resolution
+ for (var item in image.dataset) {
+ if (item.substring(0, 3) === 'at-' && !isNaN(item.substring(3))) {
+ srcs[item.replace('at-', '')] = image.dataset[item];
+ }
+ }
+ // Sort resolutions ascending
+ var keys = Object.keys(srcs).sort(function(a, b) {
+ return parseInt(a, 10) < parseInt(b, 10) ? -1 : 1;
+ });
+ // Get real screen resolution
+ var width = window.innerWidth * window.devicePixelRatio;
+ // Find the first image bigger than or equal to the current width
+ var i = 0;
+ while (i < keys.length - 1 && keys[i] < width) {
+ i++;
+ }
+ result = srcs[keys[i]] || result;
+ }
+ return result;
+ }
+
+ // Return false at the right end of the gallery
+ function showNextImage() {
+ var returnValue;
+ // Check if next image exists
+ if (currentIndex <= imagesElements.length - 2) {
+ currentIndex++;
+ updateOffset();
+ preloadNext(currentIndex);
+ returnValue = true;
+ } else if (options.animation) {
+ slider.className = 'bounce-from-right';
+ setTimeout(function() {
+ slider.className = '';
+ }, 400);
+ returnValue = false;
+ }
+ if (options.onChange) {
+ options.onChange(currentIndex, imagesElements.length);
+ }
+ return returnValue;
+ }
+
+ // Return false at the left end of the gallery
+ function showPreviousImage() {
+ var returnValue;
+ // Check if previous image exists
+ if (currentIndex >= 1) {
+ currentIndex--;
+ updateOffset();
+ preloadPrev(currentIndex);
+ returnValue = true;
+ } else if (options.animation) {
+ slider.className = 'bounce-from-left';
+ setTimeout(function() {
+ slider.className = '';
+ }, 400);
+ returnValue = false;
+ }
+ if (options.onChange) {
+ options.onChange(currentIndex, imagesElements.length);
+ }
+ return returnValue;
+ }
+
+ function updateOffset() {
+ var offset = -currentIndex * 100 + '%';
+ if (options.animation === 'fadeIn') {
+ slider.style.opacity = 0;
+ setTimeout(function() {
+ /* jshint -W030 */
+ supports.transforms ?
+ slider.style.transform = slider.style.webkitTransform = 'translate3d(' + offset + ',0,0)'
+ : slider.style.left = offset;
+ slider.style.opacity = 1;
+ }, 400);
+ } else {
+ /* jshint -W030 */
+ supports.transforms ?
+ slider.style.transform = slider.style.webkitTransform = 'translate3d(' + offset + ',0,0)'
+ : slider.style.left = offset;
+ }
+ }
+
+ // CSS 3D Transforms test
+ function testTransformsSupport() {
+ var div = create('div');
+ return typeof div.style.perspective !== 'undefined' || typeof div.style.webkitPerspective !== 'undefined';
+ }
+
+ // Inline SVG test
+ function testSVGSupport() {
+ var div = create('div');
+ div.innerHTML = '<svg/>';
+ return (div.firstChild && div.firstChild.namespaceURI) === 'http://www.w3.org/2000/svg';
+ }
+
+ function preloadNext(index) {
+ if (index - currentIndex >= options.preload) {
+ return;
+ }
+ loadImage(index + 1, function() {
+ preloadNext(index + 1);
+ });
+ }
+
+ function preloadPrev(index) {
+ if (currentIndex - index >= options.preload) {
+ return;
+ }
+ loadImage(index - 1, function() {
+ preloadPrev(index - 1);
+ });
+ }
+
+ function bind(element, event, callback, useCapture) {
+ if (element.addEventListener) {
+ element.addEventListener(event, callback, useCapture);
+ } else {
+ // IE8 fallback
+ element.attachEvent('on' + event, function(event) {
+ // `event` and `event.target` are not provided in IE8
+ event = event || window.event;
+ event.target = event.target || event.srcElement;
+ callback(event);
+ });
+ }
+ }
+
+ function unbind(element, event, callback, useCapture) {
+ if (element.removeEventListener) {
+ element.removeEventListener(event, callback, useCapture);
+ } else {
+ // IE8 fallback
+ element.detachEvent('on' + event, callback);
+ }
+ }
+
+ function getByID(id) {
+ return document.getElementById(id);
+ }
+
+ function create(element) {
+ return document.createElement(element);
+ }
+
+ function destroyPlugin() {
+ unbindEvents();
+ clearCachedData();
+ unbind(document, 'keydown', keyDownHandler);
+ document.getElementsByTagName('body')[0].removeChild(document.getElementById('baguetteBox-overlay'));
+ data = {};
+ currentGallery = [];
+ currentIndex = 0;
+ }
+
+ return {
+ run: run,
+ destroy: destroyPlugin,
+ showNext: showNextImage,
+ showPrevious: showPreviousImage
+ };
+}));