magento2-docker/lib/web/fotorama/fotorama.js

3889 lines
128 KiB
JavaScript
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*!
* Fotorama 4.6.4 | http://fotorama.io/license/
*/
fotoramaVersion = '4.6.4';
(function (window, document, location, $, undefined) {
"use strict";
var _fotoramaClass = 'fotorama',
_fullscreenClass = 'fotorama__fullscreen',
wrapClass = _fotoramaClass + '__wrap',
wrapCss2Class = wrapClass + '--css2',
wrapCss3Class = wrapClass + '--css3',
wrapVideoClass = wrapClass + '--video',
wrapFadeClass = wrapClass + '--fade',
wrapSlideClass = wrapClass + '--slide',
wrapNoControlsClass = wrapClass + '--no-controls',
wrapNoShadowsClass = wrapClass + '--no-shadows',
wrapPanYClass = wrapClass + '--pan-y',
wrapRtlClass = wrapClass + '--rtl',
wrapOnlyActiveClass = wrapClass + '--only-active',
wrapNoCaptionsClass = wrapClass + '--no-captions',
wrapToggleArrowsClass = wrapClass + '--toggle-arrows',
stageClass = _fotoramaClass + '__stage',
stageFrameClass = stageClass + '__frame',
stageFrameVideoClass = stageFrameClass + '--video',
stageShaftClass = stageClass + '__shaft',
grabClass = _fotoramaClass + '__grab',
pointerClass = _fotoramaClass + '__pointer',
arrClass = _fotoramaClass + '__arr',
arrDisabledClass = arrClass + '--disabled',
arrPrevClass = arrClass + '--prev',
arrNextClass = arrClass + '--next',
navClass = _fotoramaClass + '__nav',
navWrapClass = navClass + '-wrap',
navShaftClass = navClass + '__shaft',
navShaftVerticalClass = navWrapClass + '--vertical',
navShaftListClass = navWrapClass + '--list',
navShafthorizontalClass = navWrapClass + '--horizontal',
navDotsClass = navClass + '--dots',
navThumbsClass = navClass + '--thumbs',
navFrameClass = navClass + '__frame',
fadeClass = _fotoramaClass + '__fade',
fadeFrontClass = fadeClass + '-front',
fadeRearClass = fadeClass + '-rear',
shadowClass = _fotoramaClass + '__shadow',
shadowsClass = shadowClass + 's',
shadowsLeftClass = shadowsClass + '--left',
shadowsRightClass = shadowsClass + '--right',
shadowsTopClass = shadowsClass + '--top',
shadowsBottomClass = shadowsClass + '--bottom',
activeClass = _fotoramaClass + '__active',
selectClass = _fotoramaClass + '__select',
hiddenClass = _fotoramaClass + '--hidden',
fullscreenClass = _fotoramaClass + '--fullscreen',
fullscreenIconClass = _fotoramaClass + '__fullscreen-icon',
errorClass = _fotoramaClass + '__error',
loadingClass = _fotoramaClass + '__loading',
loadedClass = _fotoramaClass + '__loaded',
loadedFullClass = loadedClass + '--full',
loadedImgClass = loadedClass + '--img',
grabbingClass = _fotoramaClass + '__grabbing',
imgClass = _fotoramaClass + '__img',
imgFullClass = imgClass + '--full',
thumbClass = _fotoramaClass + '__thumb',
thumbArrLeft = thumbClass + '__arr--left',
thumbArrRight = thumbClass + '__arr--right',
thumbBorderClass = thumbClass + '-border',
htmlClass = _fotoramaClass + '__html',
videoContainerClass = _fotoramaClass + '-video-container',
videoClass = _fotoramaClass + '__video',
videoPlayClass = videoClass + '-play',
videoCloseClass = videoClass + '-close',
horizontalImageClass = _fotoramaClass + '_horizontal_ratio',
verticalImageClass = _fotoramaClass + '_vertical_ratio',
fotoramaSpinnerClass = _fotoramaClass + '__spinner',
spinnerShowClass = fotoramaSpinnerClass + '--show';
var JQUERY_VERSION = $ && $.fn.jquery.split('.');
if (!JQUERY_VERSION
|| JQUERY_VERSION[0] < 1
|| (JQUERY_VERSION[0] == 1 && JQUERY_VERSION[1] < 8)) {
throw 'Fotorama requires jQuery 1.8 or later and will not run without it.';
}
var _ = {};
/* Modernizr 2.8.3 (Custom Build) | MIT & BSD
* Build: http://modernizr.com/download/#-csstransforms3d-csstransitions-touch-prefixed
*/
var Modernizr = (function (window, document, undefined) {
var version = '2.8.3',
Modernizr = {},
docElement = document.documentElement,
mod = 'modernizr',
modElem = document.createElement(mod),
mStyle = modElem.style,
inputElem,
toString = {}.toString,
prefixes = ' -webkit- -moz- -o- -ms- '.split(' '),
omPrefixes = 'Webkit Moz O ms',
cssomPrefixes = omPrefixes.split(' '),
domPrefixes = omPrefixes.toLowerCase().split(' '),
tests = {},
inputs = {},
attrs = {},
classes = [],
slice = classes.slice,
featureName,
injectElementWithStyles = function (rule, callback, nodes, testnames) {
var style, ret, node, docOverflow,
div = document.createElement('div'),
body = document.body,
fakeBody = body || document.createElement('body');
if (parseInt(nodes, 10)) {
while (nodes--) {
node = document.createElement('div');
node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
div.appendChild(node);
}
}
style = ['&#173;', '<style id="s', mod, '">', rule, '</style>'].join('');
div.id = mod;
(body ? div : fakeBody).innerHTML += style;
fakeBody.appendChild(div);
if (!body) {
fakeBody.style.background = '';
fakeBody.style.overflow = 'hidden';
docOverflow = docElement.style.overflow;
docElement.style.overflow = 'hidden';
docElement.appendChild(fakeBody);
}
ret = callback(div, rule);
if (!body) {
fakeBody.parentNode.removeChild(fakeBody);
docElement.style.overflow = docOverflow;
} else {
div.parentNode.removeChild(div);
}
return !!ret;
},
_hasOwnProperty = ({}).hasOwnProperty, hasOwnProp;
if (!is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined')) {
hasOwnProp = function (object, property) {
return _hasOwnProperty.call(object, property);
};
}
else {
hasOwnProp = function (object, property) {
return ((property in object) && is(object.constructor.prototype[property], 'undefined'));
};
}
if (!Function.prototype.bind) {
Function.prototype.bind = function bind(that) {
var target = this;
if (typeof target != "function") {
throw new TypeError();
}
var args = slice.call(arguments, 1),
bound = function () {
if (this instanceof bound) {
var F = function () {
};
F.prototype = target.prototype;
var self = new F();
var result = target.apply(
self,
args.concat(slice.call(arguments))
);
if (Object(result) === result) {
return result;
}
return self;
} else {
return target.apply(
that,
args.concat(slice.call(arguments))
);
}
};
return bound;
};
}
function setCss(str) {
mStyle.cssText = str;
}
function setCssAll(str1, str2) {
return setCss(prefixes.join(str1 + ';') + ( str2 || '' ));
}
function is(obj, type) {
return typeof obj === type;
}
function contains(str, substr) {
return !!~('' + str).indexOf(substr);
}
function testProps(props, prefixed) {
for (var i in props) {
var prop = props[i];
if (!contains(prop, "-") && mStyle[prop] !== undefined) {
return prefixed == 'pfx' ? prop : true;
}
}
return false;
}
function testDOMProps(props, obj, elem) {
for (var i in props) {
var item = obj[props[i]];
if (item !== undefined) {
if (elem === false) return props[i];
if (is(item, 'function')) {
return item.bind(elem || obj);
}
return item;
}
}
return false;
}
function testPropsAll(prop, prefixed, elem) {
var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');
if (is(prefixed, "string") || is(prefixed, "undefined")) {
return testProps(props, prefixed);
} else {
props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
return testDOMProps(props, prefixed, elem);
}
}
tests['touch'] = function () {
var bool;
if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
bool = true;
} else {
injectElementWithStyles(['@media (', prefixes.join('touch-enabled),('), mod, ')', '{#modernizr{top:9px;position:absolute}}'].join(''), function (node) {
bool = node.offsetTop === 9;
});
}
return bool;
};
tests['csstransforms3d'] = function () {
var ret = !!testPropsAll('perspective');
if (ret && 'webkitPerspective' in docElement.style) {
injectElementWithStyles('@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}', function (node, rule) {
ret = node.offsetLeft === 9 && node.offsetHeight === 3;
});
}
return ret;
};
tests['csstransitions'] = function () {
return testPropsAll('transition');
};
for (var feature in tests) {
if (hasOwnProp(tests, feature)) {
featureName = feature.toLowerCase();
Modernizr[featureName] = tests[feature]();
classes.push((Modernizr[featureName] ? '' : 'no-') + featureName);
}
}
Modernizr.addTest = function (feature, test) {
if (typeof feature == 'object') {
for (var key in feature) {
if (hasOwnProp(feature, key)) {
Modernizr.addTest(key, feature[key]);
}
}
} else {
feature = feature.toLowerCase();
if (Modernizr[feature] !== undefined) {
return Modernizr;
}
test = typeof test == 'function' ? test() : test;
if (typeof enableClasses !== "undefined" && enableClasses) {
docElement.className += ' ' + (test ? '' : 'no-') + feature;
}
Modernizr[feature] = test;
}
return Modernizr;
};
setCss('');
modElem = inputElem = null;
Modernizr._version = version;
Modernizr._prefixes = prefixes;
Modernizr._domPrefixes = domPrefixes;
Modernizr._cssomPrefixes = cssomPrefixes;
Modernizr.testProp = function (prop) {
return testProps([prop]);
};
Modernizr.testAllProps = testPropsAll;
Modernizr.testStyles = injectElementWithStyles;
Modernizr.prefixed = function (prop, obj, elem) {
if (!obj) {
return testPropsAll(prop, 'pfx');
} else {
return testPropsAll(prop, obj, elem);
}
};
return Modernizr;
})(window, document);
var fullScreenApi = {
ok: false,
is: function () {
return false;
},
request: function () {
},
cancel: function () {
},
event: '',
prefix: ''
},
browserPrefixes = 'webkit moz o ms khtml'.split(' ');
// check for native support
if (typeof document.cancelFullScreen != 'undefined') {
fullScreenApi.ok = true;
} else {
// check for fullscreen support by vendor prefix
for (var i = 0, il = browserPrefixes.length; i < il; i++) {
fullScreenApi.prefix = browserPrefixes[i];
if (typeof document[fullScreenApi.prefix + 'CancelFullScreen'] != 'undefined') {
fullScreenApi.ok = true;
break;
}
}
}
// update methods to do something useful
if (fullScreenApi.ok) {
fullScreenApi.event = fullScreenApi.prefix + 'fullscreenchange';
fullScreenApi.is = function () {
switch (this.prefix) {
case '':
return document.fullScreen;
case 'webkit':
return document.webkitIsFullScreen;
default:
return document[this.prefix + 'FullScreen'];
}
};
fullScreenApi.request = function (el) {
return (this.prefix === '') ? el.requestFullScreen() : el[this.prefix + 'RequestFullScreen']();
};
fullScreenApi.cancel = function (el) {
if (!this.is()) {
return false;
}
return (this.prefix === '') ? document.cancelFullScreen() : document[this.prefix + 'CancelFullScreen']();
};
}
/* Bez v1.0.10-g5ae0136
* http://github.com/rdallasgray/bez
*
* A plugin to convert CSS3 cubic-bezier co-ordinates to jQuery-compatible easing functions
*
* With thanks to Nikolay Nemshilov for clarification on the cubic-bezier maths
* See http://st-on-it.blogspot.com/2011/05/calculating-cubic-bezier-function.html
*
* Copyright 2011 Robert Dallas Gray. All rights reserved.
* Provided under the FreeBSD license: https://github.com/rdallasgray/bez/blob/master/LICENSE.txt
*/
function bez(coOrdArray) {
var encodedFuncName = "bez_" + $.makeArray(arguments).join("_").replace(".", "p");
if (typeof $['easing'][encodedFuncName] !== "function") {
var polyBez = function (p1, p2) {
var A = [null, null],
B = [null, null],
C = [null, null],
bezCoOrd = function (t, ax) {
C[ax] = 3 * p1[ax];
B[ax] = 3 * (p2[ax] - p1[ax]) - C[ax];
A[ax] = 1 - C[ax] - B[ax];
return t * (C[ax] + t * (B[ax] + t * A[ax]));
},
xDeriv = function (t) {
return C[0] + t * (2 * B[0] + 3 * A[0] * t);
},
xForT = function (t) {
var x = t, i = 0, z;
while (++i < 14) {
z = bezCoOrd(x, 0) - t;
if (Math.abs(z) < 1e-3) break;
x -= z / xDeriv(x);
}
return x;
};
return function (t) {
return bezCoOrd(xForT(t), 1);
}
};
$['easing'][encodedFuncName] = function (x, t, b, c, d) {
return c * polyBez([coOrdArray[0], coOrdArray[1]], [coOrdArray[2], coOrdArray[3]])(t / d) + b;
}
}
return encodedFuncName;
}
var $WINDOW = $(window),
$DOCUMENT = $(document),
$HTML,
$BODY,
QUIRKS_FORCE = location.hash.replace('#', '') === 'quirks',
TRANSFORMS3D = Modernizr.csstransforms3d,
CSS3 = TRANSFORMS3D && !QUIRKS_FORCE,
COMPAT = TRANSFORMS3D || document.compatMode === 'CSS1Compat',
FULLSCREEN = fullScreenApi.ok,
MOBILE = navigator.userAgent.match(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i),
SLOW = !CSS3 || MOBILE,
MS_POINTER = navigator.msPointerEnabled,
WHEEL = "onwheel" in document.createElement("div") ? "wheel" : document.onmousewheel !== undefined ? "mousewheel" : "DOMMouseScroll",
TOUCH_TIMEOUT = 250,
TRANSITION_DURATION = 300,
SCROLL_LOCK_TIMEOUT = 1400,
AUTOPLAY_INTERVAL = 5000,
MARGIN = 2,
THUMB_SIZE = 64,
WIDTH = 500,
HEIGHT = 333,
STAGE_FRAME_KEY = '$stageFrame',
NAV_DOT_FRAME_KEY = '$navDotFrame',
NAV_THUMB_FRAME_KEY = '$navThumbFrame',
AUTO = 'auto',
BEZIER = bez([.1, 0, .25, 1]),
MAX_WIDTH = 1200,
/**
* Number of thumbnails in slide. Calculated only on setOptions and resize.
* @type {number}
*/
thumbsPerSlide = 1,
OPTIONS = {
/**
* Set width for gallery.
* Default value - width of first image
* Number - set value in px
* String - set value in quotes
*
*/
width: null,
/**
* Set min-width for gallery
*
*/
minwidth: null,
/**
* Set max-width for gallery
*
*/
maxwidth: '100%',
/**
* Set height for gallery
* Default value - height of first image
* Number - set value in px
* String - set value in quotes
*
*/
height: null,
/**
* Set min-height for gallery
*
*/
minheight: null,
/**
* Set max-height for gallery
*
*/
maxheight: null,
/**
* Set proportion ratio for gallery depends of image
*
*/
ratio: null, // '16/9' || 500/333 || 1.5
margin: MARGIN,
nav: 'dots', // 'thumbs' || false
navposition: 'bottom', // 'top'
navwidth: null,
thumbwidth: THUMB_SIZE,
thumbheight: THUMB_SIZE,
thumbmargin: MARGIN,
thumbborderwidth: MARGIN,
allowfullscreen: false, // true || 'native'
transition: 'slide', // 'crossfade' || 'dissolve'
clicktransition: null,
transitionduration: TRANSITION_DURATION,
captions: true,
startindex: 0,
loop: false,
autoplay: false,
stopautoplayontouch: true,
keyboard: false,
arrows: true,
click: true,
swipe: false,
trackpad: false,
shuffle: false,
direction: 'ltr', // 'rtl'
shadows: true,
showcaption: true,
/**
* Set type of thumbnail navigation
*/
navdir: 'horizontal',
/**
* Set configuration to show or hide arrows in thumb navigation
*/
navarrows: true,
/**
* Set type of navigation. Can be thumbs or slides
*/
navtype: 'thumbs'
},
KEYBOARD_OPTIONS = {
left: true,
right: true,
down: true,
up: true,
space: false,
home: false,
end: false
};
function noop() {
}
function minMaxLimit(value, min, max) {
return Math.max(isNaN(min) ? -Infinity : min, Math.min(isNaN(max) ? Infinity : max, value));
}
function readTransform(css, dir) {
return css.match(/ma/) && css.match(/-?\d+(?!d)/g)[css.match(/3d/) ?
(dir === 'vertical' ? 13 : 12) : (dir === 'vertical' ? 5 : 4)
]
}
function readPosition($el, dir) {
if (CSS3) {
return +readTransform($el.css('transform'), dir);
} else {
return +$el.css(dir === 'vertical' ? 'top' : 'left').replace('px', '');
}
}
function getTranslate(pos, direction) {
var obj = {};
if (CSS3) {
switch (direction) {
case 'vertical':
obj.transform = 'translate3d(0, ' + (pos) + 'px,0)';
break;
case 'list':
break;
default :
obj.transform = 'translate3d(' + (pos) + 'px,0,0)';
break;
}
} else {
direction === 'vertical' ?
obj.top = pos :
obj.left = pos;
}
return obj;
}
function getDuration(time) {
return {'transition-duration': time + 'ms'};
}
function unlessNaN(value, alternative) {
return isNaN(value) ? alternative : value;
}
function numberFromMeasure(value, measure) {
return unlessNaN(+String(value).replace(measure || 'px', ''));
}
function numberFromPercent(value) {
return /%$/.test(value) ? numberFromMeasure(value, '%') : undefined;
}
function numberFromWhatever(value, whole) {
return unlessNaN(numberFromPercent(value) / 100 * whole, numberFromMeasure(value));
}
function measureIsValid(value) {
return (!isNaN(numberFromMeasure(value)) || !isNaN(numberFromMeasure(value, '%'))) && value;
}
function getPosByIndex(index, side, margin, baseIndex) {
return (index - (baseIndex || 0)) * (side + (margin || 0));
}
function getIndexByPos(pos, side, margin, baseIndex) {
return -Math.round(pos / (side + (margin || 0)) - (baseIndex || 0));
}
function bindTransitionEnd($el) {
var elData = $el.data();
if (elData.tEnd) return;
var el = $el[0],
transitionEndEvent = {
WebkitTransition: 'webkitTransitionEnd',
MozTransition: 'transitionend',
OTransition: 'oTransitionEnd otransitionend',
msTransition: 'MSTransitionEnd',
transition: 'transitionend'
};
addEvent(el, transitionEndEvent[Modernizr.prefixed('transition')], function (e) {
elData.tProp && e.propertyName.match(elData.tProp) && elData.onEndFn();
});
elData.tEnd = true;
}
function afterTransition($el, property, fn, time) {
var ok,
elData = $el.data();
if (elData) {
elData.onEndFn = function () {
if (ok) return;
ok = true;
clearTimeout(elData.tT);
fn();
};
elData.tProp = property;
// Passive call, just in case of fail of native transition-end event
clearTimeout(elData.tT);
elData.tT = setTimeout(function () {
elData.onEndFn();
}, time * 1.5);
bindTransitionEnd($el);
}
}
function stop($el, pos/*, _001*/) {
var dir = $el.navdir || 'horizontal';
if ($el.length) {
var elData = $el.data();
if (CSS3) {
$el.css(getDuration(0));
elData.onEndFn = noop;
clearTimeout(elData.tT);
} else {
$el.stop();
}
var lockedPos = getNumber(pos, function () {
return readPosition($el, dir);
});
$el.css(getTranslate(lockedPos, dir/*, _001*/));//.width(); // `.width()` for reflow
return lockedPos;
}
}
function getNumber() {
var number;
for (var _i = 0, _l = arguments.length; _i < _l; _i++) {
number = _i ? arguments[_i]() : arguments[_i];
if (typeof number === 'number') {
break;
}
}
return number;
}
function edgeResistance(pos, edge) {
return Math.round(pos + ((edge - pos) / 1.5));
}
function getProtocol() {
getProtocol.p = getProtocol.p || (location.protocol === 'https:' ? 'https://' : 'http://');
return getProtocol.p;
}
function parseHref(href) {
var a = document.createElement('a');
a.href = href;
return a;
}
function findVideoId(href, forceVideo) {
if (typeof href !== 'string') return href;
href = parseHref(href);
var id,
type;
if (href.host.match(/youtube\.com/) && href.search) {
//.log();
id = href.search.split('v=')[1];
if (id) {
var ampersandPosition = id.indexOf('&');
if (ampersandPosition !== -1) {
id = id.substring(0, ampersandPosition);
}
type = 'youtube';
}
} else if (href.host.match(/youtube\.com|youtu\.be|youtube-nocookie.com/)) {
id = href.pathname.replace(/^\/(embed\/|v\/)?/, '').replace(/\/.*/, '');
type = 'youtube';
} else if (href.host.match(/vimeo\.com/)) {
type = 'vimeo';
id = href.pathname.replace(/^\/(video\/)?/, '').replace(/\/.*/, '');
}
if ((!id || !type) && forceVideo) {
id = href.href;
type = 'custom';
}
return id ? {id: id, type: type, s: href.search.replace(/^\?/, ''), p: getProtocol()} : false;
}
function getVideoThumbs(dataFrame, data, fotorama) {
var img, thumb, video = dataFrame.video;
if (video.type === 'youtube') {
thumb = getProtocol() + 'img.youtube.com/vi/' + video.id + '/default.jpg';
img = thumb.replace(/\/default.jpg$/, '/hqdefault.jpg');
dataFrame.thumbsReady = true;
} else if (video.type === 'vimeo') {
$.ajax({
url: getProtocol() + 'vimeo.com/api/oembed.json',
data: {
url: 'https://vimeo.com/' + video.id
},
dataType: 'jsonp',
success: function (json) {
dataFrame.thumbsReady = true;
updateData(data, {
img: json[0].thumbnail_url,
thumb: json[0].thumbnail_url
}, dataFrame.i, fotorama);
}
});
} else {
dataFrame.thumbsReady = true;
}
return {
img: img,
thumb: thumb
}
}
function updateData(data, _dataFrame, i, fotorama) {
for (var _i = 0, _l = data.length; _i < _l; _i++) {
var dataFrame = data[_i];
if (dataFrame.i === i && dataFrame.thumbsReady) {
var clear = {videoReady: true};
clear[STAGE_FRAME_KEY] = clear[NAV_THUMB_FRAME_KEY] = clear[NAV_DOT_FRAME_KEY] = false;
fotorama.splice(_i, 1, $.extend(
{},
dataFrame,
clear,
_dataFrame
));
break;
}
}
}
function getDataFromHtml($el) {
var data = [];
function getDataFromImg($img, imgData, checkVideo) {
var $child = $img.children('img').eq(0),
_imgHref = $img.attr('href'),
_imgSrc = $img.attr('src'),
_thumbSrc = $child.attr('src'),
_video = imgData.video,
video = checkVideo ? findVideoId(_imgHref, _video === true) : false;
if (video) {
_imgHref = false;
} else {
video = _video;
}
getDimensions($img, $child, $.extend(imgData, {
video: video,
img: imgData.img || _imgHref || _imgSrc || _thumbSrc,
thumb: imgData.thumb || _thumbSrc || _imgSrc || _imgHref
}));
}
function getDimensions($img, $child, imgData) {
var separateThumbFLAG = imgData.thumb && imgData.img !== imgData.thumb,
width = numberFromMeasure(imgData.width || $img.attr('width')),
height = numberFromMeasure(imgData.height || $img.attr('height'));
$.extend(imgData, {
width: width,
height: height,
thumbratio: getRatio(imgData.thumbratio || (numberFromMeasure(imgData.thumbwidth || ($child && $child.attr('width')) || separateThumbFLAG || width) / numberFromMeasure(imgData.thumbheight || ($child && $child.attr('height')) || separateThumbFLAG || height)))
});
}
$el.children().each(function () {
var $this = $(this),
dataFrame = optionsToLowerCase($.extend($this.data(), {id: $this.attr('id')}));
if ($this.is('a, img')) {
getDataFromImg($this, dataFrame, true);
} else if (!$this.is(':empty')) {
getDimensions($this, null, $.extend(dataFrame, {
html: this,
_html: $this.html() // Because of IE
}));
} else return;
data.push(dataFrame);
});
return data;
}
function isHidden(el) {
return el.offsetWidth === 0 && el.offsetHeight === 0;
}
function isDetached(el) {
return !$.contains(document.documentElement, el);
}
function waitFor(test, fn, timeout, i) {
if (!waitFor.i) {
waitFor.i = 1;
waitFor.ii = [true];
}
i = i || waitFor.i;
if (typeof waitFor.ii[i] === 'undefined') {
waitFor.ii[i] = true;
}
if (test()) {
fn();
} else {
waitFor.ii[i] && setTimeout(function () {
waitFor.ii[i] && waitFor(test, fn, timeout, i);
}, timeout || 100);
}
return waitFor.i++;
}
waitFor.stop = function (i) {
waitFor.ii[i] = false;
};
function fit($el, measuresToFit) {
var elData = $el.data(),
measures = elData.measures;
if (measures && (!elData.l ||
elData.l.W !== measures.width ||
elData.l.H !== measures.height ||
elData.l.r !== measures.ratio ||
elData.l.w !== measuresToFit.w ||
elData.l.h !== measuresToFit.h)) {
var height = minMaxLimit(measuresToFit.h, 0, measures.height),
width = height * measures.ratio;
UTIL.setRatio($el, width, height);
elData.l = {
W: measures.width,
H: measures.height,
r: measures.ratio,
w: measuresToFit.w,
h: measuresToFit.h
};
}
return true;
}
function setStyle($el, style) {
var el = $el[0];
if (el.styleSheet) {
el.styleSheet.cssText = style;
} else {
$el.html(style);
}
}
function findShadowEdge(pos, min, max, dir) {
return min === max ? false :
dir === 'vertical' ?
(pos <= min ? 'top' : pos >= max ? 'bottom' : 'top bottom') :
(pos <= min ? 'left' : pos >= max ? 'right' : 'left right');
}
function smartClick($el, fn, _options) {
_options = _options || {};
$el.each(function () {
var $this = $(this),
thisData = $this.data(),
startEvent;
if (thisData.clickOn) return;
thisData.clickOn = true;
$.extend(touch($this, {
onStart: function (e) {
startEvent = e;
(_options.onStart || noop).call(this, e);
},
onMove: _options.onMove || noop,
onTouchEnd: _options.onTouchEnd || noop,
onEnd: function (result) {
if (result.moved) return;
fn.call(this, startEvent);
}
}), {noMove: true});
});
}
function div(classes, child) {
return '<div class="' + classes + '">' + (child || '') + '</div>';
}
/**
* Function transforming into valid classname
* @param className - name of the class
* @returns {string} - dom format of class name
*/
function cls(className) {
return "." + className;
}
/**
*
* @param {json-object} videoItem Parsed object from data.video item or href from link a in input dates
* @returns {string} DOM view of video iframe
*/
function createVideoFrame(videoItem) {
var frame = '<iframe src="' + videoItem.p + videoItem.type + '.com/embed/' + videoItem.id + '" frameborder="0" allowfullscreen></iframe>';
return frame;
}
// FisherYates Shuffle
// http://bost.ocks.org/mike/shuffle/
function shuffle(array) {
// While there remain elements to shuffle
var l = array.length;
while (l) {
// Pick a remaining element
var i = Math.floor(Math.random() * l--);
// And swap it with the current element
var t = array[l];
array[l] = array[i];
array[i] = t;
}
return array;
}
function clone(array) {
return Object.prototype.toString.call(array) == '[object Array]'
&& $.map(array, function (frame) {
return $.extend({}, frame);
});
}
function lockScroll($el, left, top) {
$el
.scrollLeft(left || 0)
.scrollTop(top || 0);
}
function optionsToLowerCase(options) {
if (options) {
var opts = {};
$.each(options, function (key, value) {
opts[key.toLowerCase()] = value;
});
return opts;
}
}
function getRatio(_ratio) {
if (!_ratio) return;
var ratio = +_ratio;
if (!isNaN(ratio)) {
return ratio;
} else {
ratio = _ratio.split('/');
return +ratio[0] / +ratio[1] || undefined;
}
}
function addEvent(el, e, fn, bool) {
if (!e) return;
el.addEventListener ? el.addEventListener(e, fn, !!bool) : el.attachEvent('on' + e, fn);
}
/**
*
* @param position guess position for navShaft
* @param restriction object contains min and max values for position
* @returns {*} filtered value of position
*/
function validateRestrictions(position, restriction) {
if (position > restriction.max) {
position = restriction.max;
} else {
if (position < restriction.min) {
position = restriction.min;
}
}
return position;
}
function validateSlidePos(opt, navShaftTouchTail, guessIndex, offsetNav, $guessNavFrame, $navWrap, dir) {
var position,
size,
wrapSize;
if (dir === 'horizontal') {
size = opt.thumbwidth;
wrapSize = $navWrap.width();
} else {
size = opt.thumbheight;
wrapSize = $navWrap.height();
}
if ( (size + opt.margin) * (guessIndex + 1) >= (wrapSize - offsetNav) ) {
if (dir === 'horizontal') {
position = -$guessNavFrame.position().left;
} else {
position = -$guessNavFrame.position().top;
}
} else {
if ((size + opt.margin) * (guessIndex) <= Math.abs(offsetNav)) {
if (dir === 'horizontal') {
position = -$guessNavFrame.position().left + wrapSize - (size + opt.margin);
} else {
position = -$guessNavFrame.position().top + wrapSize - (size + opt.margin);
}
} else {
position = offsetNav;
}
}
position = validateRestrictions(position, navShaftTouchTail);
return position || 0;
}
function elIsDisabled(el) {
return !!el.getAttribute('disabled');
}
function disableAttr(FLAG, disable) {
if (disable) {
return {disabled: FLAG};
} else {
return {tabindex: FLAG * -1 + '', disabled: FLAG};
}
}
function addEnterUp(el, fn) {
addEvent(el, 'keyup', function (e) {
elIsDisabled(el) || e.keyCode == 13 && fn.call(el, e);
});
}
function addFocus(el, fn) {
addEvent(el, 'focus', el.onfocusin = function (e) {
fn.call(el, e);
}, true);
}
function stopEvent(e, stopPropagation) {
e.preventDefault ? e.preventDefault() : (e.returnValue = false);
stopPropagation && e.stopPropagation && e.stopPropagation();
}
function getDirectionSign(forward) {
return forward ? '>' : '<';
}
var UTIL = (function () {
function setRatioClass($el, wh, ht) {
var rateImg = wh / ht;
if (rateImg <= 1) {
$el.parent().removeClass(horizontalImageClass);
$el.parent().addClass(verticalImageClass);
} else {
$el.parent().removeClass(verticalImageClass);
$el.parent().addClass(horizontalImageClass);
}
}
/**
* Set specific attribute in thumbnail template
* @param $frame DOM item of specific thumbnail
* @param value Value which must be setted into specific attribute
* @param searchAttr Name of attribute where value must be included
*/
function setThumbAttr($frame, value, searchAttr) {
var attr = searchAttr;
if (!$frame.attr(attr) && $frame.attr(attr) !== undefined) {
$frame.attr(attr, value);
}
if ($frame.find("[" + attr + "]").length) {
$frame.find("[" + attr + "]")
.each(function () {
$(this).attr(attr, value);
});
}
}
/**
* Method describe behavior need to render caption on preview or not
* @param frameItem specific item from data
* @param isExpected {bool} if items with caption need render them or not
* @returns {boolean} if true then caption should be rendered
*/
function isExpectedCaption(frameItem, isExpected, undefined) {
var expected = false,
frameExpected;
frameItem.showCaption === undefined || frameItem.showCaption === true ? frameExpected = true : frameExpected = false;
if (!isExpected) {
return false;
}
if (frameItem.caption && frameExpected) {
expected = true;
}
return expected;
}
return {
setRatio: setRatioClass,
setThumbAttr: setThumbAttr,
isExpectedCaption: isExpectedCaption
};
}(UTIL || {}, jQuery));
function slide($el, options) {
var elData = $el.data(),
elPos = Math.round(options.pos),
onEndFn = function () {
if (elData && elData.sliding) {
elData.sliding = false;
}
(options.onEnd || noop)();
};
if (typeof options.overPos !== 'undefined' && options.overPos !== options.pos) {
elPos = options.overPos;
}
var translate = $.extend(getTranslate(elPos, options.direction), options.width && {width: options.width}, options.height && {height: options.height});
if (elData && elData.sliding) {
elData.sliding = true;
}
if (CSS3) {
$el.css($.extend(getDuration(options.time), translate));
if (options.time > 10) {
afterTransition($el, 'transform', onEndFn, options.time);
} else {
onEndFn();
}
} else {
$el.stop().animate(translate, options.time, BEZIER, onEndFn);
}
}
function fade($el1, $el2, $frames, options, fadeStack, chain) {
var chainedFLAG = typeof chain !== 'undefined';
if (!chainedFLAG) {
fadeStack.push(arguments);
Array.prototype.push.call(arguments, fadeStack.length);
if (fadeStack.length > 1) return;
}
$el1 = $el1 || $($el1);
$el2 = $el2 || $($el2);
var _$el1 = $el1[0],
_$el2 = $el2[0],
crossfadeFLAG = options.method === 'crossfade',
onEndFn = function () {
if (!onEndFn.done) {
onEndFn.done = true;
var args = (chainedFLAG || fadeStack.shift()) && fadeStack.shift();
args && fade.apply(this, args);
(options.onEnd || noop)(!!args);
}
},
time = options.time / (chain || 1);
$frames.removeClass(fadeRearClass + ' ' + fadeFrontClass);
$el1
.stop()
.addClass(fadeRearClass);
$el2
.stop()
.addClass(fadeFrontClass);
crossfadeFLAG && _$el2 && $el1.fadeTo(0, 0);
$el1.fadeTo(crossfadeFLAG ? time : 0, 1, crossfadeFLAG && onEndFn);
$el2.fadeTo(time, 0, onEndFn);
(_$el1 && crossfadeFLAG) || _$el2 || onEndFn();
}
var lastEvent,
moveEventType,
preventEvent,
preventEventTimeout,
dragDomEl;
function extendEvent(e) {
var touch = (e.touches || [])[0] || e;
e._x = touch.pageX || touch.originalEvent.pageX;
e._y = touch.clientY || touch.originalEvent.clientY;
e._now = $.now();
}
function touch($el, options) {
var el = $el[0],
tail = {},
touchEnabledFLAG,
startEvent,
$target,
controlTouch,
touchFLAG,
targetIsSelectFLAG,
targetIsLinkFlag,
isDisabledSwipe,
tolerance,
moved;
function onStart(e) {
$target = $(e.target);
tail.checked = targetIsSelectFLAG = targetIsLinkFlag = isDisabledSwipe = moved = false;
if (touchEnabledFLAG
|| tail.flow
|| (e.touches && e.touches.length > 1)
|| e.which > 1
|| (lastEvent && lastEvent.type !== e.type && preventEvent)
|| (targetIsSelectFLAG = options.select && $target.is(options.select, el))) return targetIsSelectFLAG;
touchFLAG = e.type === 'touchstart';
targetIsLinkFlag = $target.is('a, a *', el);
isDisabledSwipe = $target.hasClass('disableSwipe');
controlTouch = tail.control;
tolerance = (tail.noMove || tail.noSwipe || controlTouch) ? 16 : !tail.snap ? 4 : 0;
extendEvent(e);
startEvent = lastEvent = e;
moveEventType = e.type.replace(/down|start/, 'move').replace(/Down/, 'Move');
(options.onStart || noop).call(el, e, {control: controlTouch, $target: $target});
touchEnabledFLAG = tail.flow = true;
if (!isDisabledSwipe && (!touchFLAG || tail.go)) stopEvent(e);
}
function onMove(e) {
if ((e.touches && e.touches.length > 1)
|| (MS_POINTER && !e.isPrimary)
|| moveEventType !== e.type
|| !touchEnabledFLAG) {
touchEnabledFLAG && onEnd();
(options.onTouchEnd || noop)();
return;
}
isDisabledSwipe = $(e.target).hasClass('disableSwipe');
if (isDisabledSwipe) {
return;
}
extendEvent(e);
var xDiff = Math.abs(e._x - startEvent._x), // opt _x → _pageX
yDiff = Math.abs(e._y - startEvent._y),
xyDiff = xDiff - yDiff,
xWin = (tail.go || tail.x || xyDiff >= 0) && !tail.noSwipe,
yWin = xyDiff < 0;
if (touchFLAG && !tail.checked) {
if (touchEnabledFLAG = xWin) {
stopEvent(e);
}
} else {
stopEvent(e);
if (movedEnough(xDiff,yDiff)) {
(options.onMove || noop).call(el, e, {touch: touchFLAG});
}
}
if (!moved && movedEnough(xDiff, yDiff) && Math.sqrt(Math.pow(xDiff, 2) + Math.pow(yDiff, 2)) > tolerance) {
moved = true;
}
tail.checked = tail.checked || xWin || yWin;
}
function movedEnough(xDiff, yDiff) {
return xDiff > yDiff && xDiff > 1.5;
}
function onEnd(e) {
(options.onTouchEnd || noop)();
var _touchEnabledFLAG = touchEnabledFLAG;
tail.control = touchEnabledFLAG = false;
if (_touchEnabledFLAG) {
tail.flow = false;
}
if (!_touchEnabledFLAG || (targetIsLinkFlag && !tail.checked)) return;
e && stopEvent(e);
preventEvent = true;
clearTimeout(preventEventTimeout);
preventEventTimeout = setTimeout(function () {
preventEvent = false;
}, 1000);
(options.onEnd || noop).call(el, {
moved: moved,
$target: $target,
control: controlTouch,
touch: touchFLAG,
startEvent: startEvent,
aborted: !e || e.type === 'MSPointerCancel'
});
}
function onOtherStart() {
if (tail.flow) return;
tail.flow = true;
}
function onOtherEnd() {
if (!tail.flow) return;
tail.flow = false;
}
if (MS_POINTER) {
addEvent(el, 'MSPointerDown', onStart);
addEvent(document, 'MSPointerMove', onMove);
addEvent(document, 'MSPointerCancel', onEnd);
addEvent(document, 'MSPointerUp', onEnd);
} else {
addEvent(el, 'touchstart', onStart);
addEvent(el, 'touchmove', onMove);
addEvent(el, 'touchend', onEnd);
addEvent(document, 'touchstart', onOtherStart, true);
addEvent(document, 'touchend', onOtherEnd);
addEvent(document, 'touchcancel', onOtherEnd);
$WINDOW.on('scroll', onOtherEnd);
$el.on('mousedown', onStart);
$DOCUMENT
.on('mousemove', onMove)
.on('mouseup', onEnd);
}
if (Modernizr.touch) {
dragDomEl = 'a';
} else {
dragDomEl = 'div';
}
$el.on('click', dragDomEl, function (e) {
tail.checked && stopEvent(e);
});
return tail;
}
function moveOnTouch($el, options) {
var el = $el[0],
elData = $el.data(),
tail = {},
startCoo,
coo,
startElPos,
moveElPos,
edge,
moveTrack,
startTime,
endTime,
min,
max,
snap,
dir,
slowFLAG,
controlFLAG,
moved,
tracked;
function startTracking(e, noStop) {
tracked = true;
startCoo = coo = (dir === 'vertical') ? e._y : e._x;
startTime = e._now;
moveTrack = [
[startTime, startCoo]
];
startElPos = moveElPos = tail.noMove || noStop ? 0 : stop($el, (options.getPos || noop)()/*, options._001*/);
(options.onStart || noop).call(el, e);
}
function onStart(e, result) {
min = tail.min;
max = tail.max;
snap = tail.snap,
dir = tail.direction || 'horizontal',
$el.navdir = dir;
slowFLAG = e.altKey;
tracked = moved = false;
controlFLAG = result.control;
if (!controlFLAG && !elData.sliding) {
startTracking(e);
}
}
function onMove(e, result) {
if (!tail.noSwipe) {
if (!tracked) {
startTracking(e);
}
coo = (dir === 'vertical') ? e._y : e._x;
moveTrack.push([e._now, coo]);
moveElPos = startElPos - (startCoo - coo);
edge = findShadowEdge(moveElPos, min, max, dir);
if (moveElPos <= min) {
moveElPos = edgeResistance(moveElPos, min);
} else if (moveElPos >= max) {
moveElPos = edgeResistance(moveElPos, max);
}
if (!tail.noMove) {
$el.css(getTranslate(moveElPos, dir));
if (!moved) {
moved = true;
// only for mouse
result.touch || MS_POINTER || $el.addClass(grabbingClass);
}
(options.onMove || noop).call(el, e, {pos: moveElPos, edge: edge});
}
}
}
function onEnd(result) {
if (tail.noSwipe && result.moved) return;
if (!tracked) {
startTracking(result.startEvent, true);
}
result.touch || MS_POINTER || $el.removeClass(grabbingClass);
endTime = $.now();
var _backTimeIdeal = endTime - TOUCH_TIMEOUT,
_backTime,
_timeDiff,
_timeDiffLast,
backTime = null,
backCoo,
virtualPos,
limitPos,
newPos,
overPos,
time = TRANSITION_DURATION,
speed,
friction = options.friction;
for (var _i = moveTrack.length - 1; _i >= 0; _i--) {
_backTime = moveTrack[_i][0];
_timeDiff = Math.abs(_backTime - _backTimeIdeal);
if (backTime === null || _timeDiff < _timeDiffLast) {
backTime = _backTime;
backCoo = moveTrack[_i][1];
} else if (backTime === _backTimeIdeal || _timeDiff > _timeDiffLast) {
break;
}
_timeDiffLast = _timeDiff;
}
newPos = minMaxLimit(moveElPos, min, max);
var cooDiff = backCoo - coo,
forwardFLAG = cooDiff >= 0,
timeDiff = endTime - backTime,
longTouchFLAG = timeDiff > TOUCH_TIMEOUT,
swipeFLAG = !longTouchFLAG && moveElPos !== startElPos && newPos === moveElPos;
if (snap) {
newPos = minMaxLimit(Math[swipeFLAG ? (forwardFLAG ? 'floor' : 'ceil') : 'round'](moveElPos / snap) * snap, min, max);
min = max = newPos;
}
if (swipeFLAG && (snap || newPos === moveElPos)) {
speed = -(cooDiff / timeDiff);
time *= minMaxLimit(Math.abs(speed), options.timeLow, options.timeHigh);
virtualPos = Math.round(moveElPos + speed * time / friction);
if (!snap) {
newPos = virtualPos;
}
if (!forwardFLAG && virtualPos > max || forwardFLAG && virtualPos < min) {
limitPos = forwardFLAG ? min : max;
overPos = virtualPos - limitPos;
if (!snap) {
newPos = limitPos;
}
overPos = minMaxLimit(newPos + overPos * .03, limitPos - 50, limitPos + 50);
time = Math.abs((moveElPos - overPos) / (speed / friction));
}
}
time *= slowFLAG ? 10 : 1;
(options.onEnd || noop).call(el, $.extend(result, {
moved: result.moved || longTouchFLAG && snap,
pos: moveElPos,
newPos: newPos,
overPos: overPos,
time: time,
dir: dir
}));
}
tail = $.extend(touch(options.$wrap, $.extend({}, options, {
onStart: onStart,
onMove: onMove,
onEnd: onEnd
})), tail);
return tail;
}
function wheel($el, options) {
var el = $el[0],
lockFLAG,
lastDirection,
lastNow,
tail = {
prevent: {}
};
addEvent(el, WHEEL, function (e) {
var yDelta = e.wheelDeltaY || -1 * e.deltaY || 0,
xDelta = e.wheelDeltaX || -1 * e.deltaX || 0,
xWin = Math.abs(xDelta) && !Math.abs(yDelta),
direction = getDirectionSign(xDelta < 0),
sameDirection = lastDirection === direction,
now = $.now(),
tooFast = now - lastNow < TOUCH_TIMEOUT;
lastDirection = direction;
lastNow = now;
if (!xWin || !tail.ok || tail.prevent[direction] && !lockFLAG) {
return;
} else {
stopEvent(e, true);
if (lockFLAG && sameDirection && tooFast) {
return;
}
}
if (options.shift) {
lockFLAG = true;
clearTimeout(tail.t);
tail.t = setTimeout(function () {
lockFLAG = false;
}, SCROLL_LOCK_TIMEOUT);
}
(options.onEnd || noop)(e, options.shift ? direction : xDelta);
});
return tail;
}
jQuery.Fotorama = function ($fotorama, opts) {
$HTML = $('html');
$BODY = $('body');
var that = this,
stamp = $.now(),
stampClass = _fotoramaClass + stamp,
fotorama = $fotorama[0],
data,
dataFrameCount = 1,
fotoramaData = $fotorama.data(),
size,
$style = $('<style></style>'),
$anchor = $(div(hiddenClass)),
$wrap = $fotorama.find(cls(wrapClass)),
$stage = $wrap.find(cls(stageClass)),
stage = $stage[0],
$stageShaft = $fotorama.find(cls(stageShaftClass)),
$stageFrame = $(),
$arrPrev = $fotorama.find(cls(arrPrevClass)),
$arrNext = $fotorama.find(cls(arrNextClass)),
$arrs = $fotorama.find(cls(arrClass)),
$navWrap = $fotorama.find(cls(navWrapClass)),
$nav = $navWrap.find(cls(navClass)),
$navShaft = $nav.find(cls(navShaftClass)),
$navFrame,
$navDotFrame = $(),
$navThumbFrame = $(),
stageShaftData = $stageShaft.data(),
navShaftData = $navShaft.data(),
$thumbBorder = $fotorama.find(cls(thumbBorderClass)),
$thumbArrLeft = $fotorama.find(cls(thumbArrLeft)),
$thumbArrRight = $fotorama.find(cls(thumbArrRight)),
$fullscreenIcon = $fotorama.find(cls(fullscreenIconClass)),
fullscreenIcon = $fullscreenIcon[0],
$videoPlay = $(div(videoPlayClass)),
$videoClose = $fotorama.find(cls(videoCloseClass)),
videoClose = $videoClose[0],
$spinner = $fotorama.find(cls(fotoramaSpinnerClass)),
$videoPlaying,
activeIndex = false,
activeFrame,
activeIndexes,
repositionIndex,
dirtyIndex,
lastActiveIndex,
prevIndex,
nextIndex,
nextAutoplayIndex,
startIndex,
o_loop,
o_nav,
o_navThumbs,
o_navTop,
o_allowFullScreen,
o_nativeFullScreen,
o_fade,
o_thumbSide,
o_thumbSide2,
o_transitionDuration,
o_transition,
o_shadows,
o_rtl,
o_keyboard,
lastOptions = {},
measures = {},
measuresSetFLAG,
stageShaftTouchTail = {},
stageWheelTail = {},
navShaftTouchTail = {},
navWheelTail = {},
scrollTop,
scrollLeft,
showedFLAG,
pausedAutoplayFLAG,
stoppedAutoplayFLAG,
toDeactivate = {},
toDetach = {},
measuresStash,
touchedFLAG,
hoverFLAG,
navFrameKey,
stageLeft = 0,
fadeStack = [];
$wrap[STAGE_FRAME_KEY] = $('<div class="' + stageFrameClass + '"></div>');
$wrap[NAV_THUMB_FRAME_KEY] = $($.Fotorama.jst.thumb());
$wrap[NAV_DOT_FRAME_KEY] = $($.Fotorama.jst.dots());
toDeactivate[STAGE_FRAME_KEY] = [];
toDeactivate[NAV_THUMB_FRAME_KEY] = [];
toDeactivate[NAV_DOT_FRAME_KEY] = [];
toDetach[STAGE_FRAME_KEY] = {};
$wrap.addClass(CSS3 ? wrapCss3Class : wrapCss2Class);
fotoramaData.fotorama = this;
/**
* Search video items in incoming data and transform object for video layout.
*
*/
function checkForVideo() {
$.each(data, function (i, dataFrame) {
if (!dataFrame.i) {
dataFrame.i = dataFrameCount++;
var video = findVideoId(dataFrame.video, true);
if (video) {
var thumbs = {};
dataFrame.video = video;
if (!dataFrame.img && !dataFrame.thumb) {
thumbs = getVideoThumbs(dataFrame, data, that);
} else {
dataFrame.thumbsReady = true;
}
updateData(data, {img: thumbs.img, thumb: thumbs.thumb}, dataFrame.i, that);
}
}
});
}
/**
* Checks if current media object is YouTube or Vimeo video stream
* @returns {boolean}
*/
function isVideo() {
return $((that.activeFrame || {}).$stageFrame || {}).hasClass('fotorama-video-container');
}
function allowKey(key) {
return o_keyboard[key];
}
function setStagePosition() {
if ($stage !== undefined) {
if (opts.navdir == 'vertical') {
var padding = opts.thumbwidth + opts.thumbmargin;
$stage.css('left', padding);
$arrNext.css('right', padding);
$fullscreenIcon.css('right', padding);
$wrap.css('width', $wrap.css('width') + padding);
$stageShaft.css('max-width', $wrap.width() - padding);
} else {
$stage.css('left', '');
$arrNext.css('right', '');
$fullscreenIcon.css('right', '');
$wrap.css('width', $wrap.css('width') + padding);
$stageShaft.css('max-width', '');
}
}
}
function bindGlobalEvents(FLAG) {
var keydownCommon = 'keydown.' + _fotoramaClass,
localStamp = _fotoramaClass + stamp,
keydownLocal = 'keydown.' + localStamp,
keyupLocal = 'keyup.' + localStamp,
resizeLocal = 'resize.' + localStamp + ' ' + 'orientationchange.' + localStamp,
showParams;
if (FLAG) {
$DOCUMENT
.on(keydownLocal, function (e) {
var catched,
index;
if ($videoPlaying && e.keyCode === 27) {
catched = true;
unloadVideo($videoPlaying, true, true);
} else if (that.fullScreen || (opts.keyboard && !that.index)) {
if (e.keyCode === 27) {
catched = true;
that.cancelFullScreen();
} else if ((e.shiftKey && e.keyCode === 32 && allowKey('space')) || (!e.altKey && !e.metaKey && e.keyCode === 37 && allowKey('left')) || (e.keyCode === 38 && allowKey('up') && $(':focus').attr('data-gallery-role'))) {
that.longPress.progress();
index = '<';
} else if ((e.keyCode === 32 && allowKey('space')) || (!e.altKey && !e.metaKey && e.keyCode === 39 && allowKey('right')) || (e.keyCode === 40 && allowKey('down') && $(':focus').attr('data-gallery-role'))) {
that.longPress.progress();
index = '>';
} else if (e.keyCode === 36 && allowKey('home')) {
that.longPress.progress();
index = '<<';
} else if (e.keyCode === 35 && allowKey('end')) {
that.longPress.progress();
index = '>>';
}
}
(catched || index) && stopEvent(e);
showParams = {index: index, slow: e.altKey, user: true};
index && (that.longPress.inProgress ?
that.showWhileLongPress(showParams) :
that.show(showParams));
});
if (FLAG) {
$DOCUMENT
.on(keyupLocal, function (e) {
if (that.longPress.inProgress) {
that.showEndLongPress({user: true});
}
that.longPress.reset();
});
}
if (!that.index) {
$DOCUMENT
.off(keydownCommon)
.on(keydownCommon, 'textarea, input, select', function (e) {
!$BODY.hasClass(_fullscreenClass) && e.stopPropagation();
});
}
$WINDOW.on(resizeLocal, that.resize);
} else {
$DOCUMENT.off(keydownLocal);
$WINDOW.off(resizeLocal);
}
}
function appendElements(FLAG) {
if (FLAG === appendElements.f) return;
if (FLAG) {
$fotorama
.addClass(_fotoramaClass + ' ' + stampClass)
.before($anchor)
.before($style);
addInstance(that);
} else {
$anchor.detach();
$style.detach();
$fotorama
.html(fotoramaData.urtext)
.removeClass(stampClass);
hideInstance(that);
}
bindGlobalEvents(FLAG);
appendElements.f = FLAG;
}
/**
* Set and install data from incoming @param {JSON} options or takes data attr from data-"name"=... values.
*/
function setData() {
data = that.data = data || clone(opts.data) || getDataFromHtml($fotorama);
size = that.size = data.length;
ready.ok && opts.shuffle && shuffle(data);
checkForVideo();
activeIndex = limitIndex(activeIndex);
size && appendElements(true);
}
function stageNoMove() {
var _noMove = size < 2 || $videoPlaying;
stageShaftTouchTail.noMove = _noMove || o_fade;
stageShaftTouchTail.noSwipe = _noMove || !opts.swipe;
!o_transition && $stageShaft.toggleClass(grabClass, !opts.click && !stageShaftTouchTail.noMove && !stageShaftTouchTail.noSwipe);
MS_POINTER && $wrap.toggleClass(wrapPanYClass, !stageShaftTouchTail.noSwipe);
}
function setAutoplayInterval(interval) {
if (interval === true) interval = '';
opts.autoplay = Math.max(+interval || AUTOPLAY_INTERVAL, o_transitionDuration * 1.5);
}
function updateThumbArrow(opt) {
if (opt.navarrows && opt.nav === 'thumbs') {
$thumbArrLeft.show();
$thumbArrRight.show();
} else {
$thumbArrLeft.hide();
$thumbArrRight.hide();
}
}
function getThumbsInSlide($el, opts) {
return Math.floor($wrap.width() / (opts.thumbwidth + opts.thumbmargin));
}
/**
* Options on the fly
* */
function setOptions() {
if (!opts.nav || opts.nav === 'dots') {
opts.navdir = 'horizontal'
}
that.options = opts = optionsToLowerCase(opts);
thumbsPerSlide = getThumbsInSlide($wrap, opts);
o_fade = (opts.transition === 'crossfade' || opts.transition === 'dissolve');
o_loop = opts.loop && (size > 2 || (o_fade && (!o_transition || o_transition !== 'slide')));
o_transitionDuration = +opts.transitionduration || TRANSITION_DURATION;
o_rtl = opts.direction === 'rtl';
o_keyboard = $.extend({}, opts.keyboard && KEYBOARD_OPTIONS, opts.keyboard);
updateThumbArrow(opts);
var classes = {add: [], remove: []};
function addOrRemoveClass(FLAG, value) {
classes[FLAG ? 'add' : 'remove'].push(value);
}
if (size > 1) {
o_nav = opts.nav;
o_navTop = opts.navposition === 'top';
classes.remove.push(selectClass);
$arrs.toggle(!!opts.arrows);
} else {
o_nav = false;
$arrs.hide();
}
arrsUpdate();
stageWheelUpdate();
thumbArrUpdate();
if (opts.autoplay) setAutoplayInterval(opts.autoplay);
o_thumbSide = numberFromMeasure(opts.thumbwidth) || THUMB_SIZE;
o_thumbSide2 = numberFromMeasure(opts.thumbheight) || THUMB_SIZE;
stageWheelTail.ok = navWheelTail.ok = opts.trackpad && !SLOW;
stageNoMove();
extendMeasures(opts, [measures]);
o_navThumbs = o_nav === 'thumbs';
if ($navWrap.filter(':hidden') && !!o_nav) {
$navWrap.show();
}
if (o_navThumbs) {
frameDraw(size, 'navThumb');
$navFrame = $navThumbFrame;
navFrameKey = NAV_THUMB_FRAME_KEY;
setStyle($style, $.Fotorama.jst.style({
w: o_thumbSide,
h: o_thumbSide2,
b: opts.thumbborderwidth,
m: opts.thumbmargin,
s: stamp,
q: !COMPAT
}));
$nav
.addClass(navThumbsClass)
.removeClass(navDotsClass);
} else if (o_nav === 'dots') {
frameDraw(size, 'navDot');
$navFrame = $navDotFrame;
navFrameKey = NAV_DOT_FRAME_KEY;
$nav
.addClass(navDotsClass)
.removeClass(navThumbsClass);
} else {
$navWrap.hide();
o_nav = false;
$nav.removeClass(navThumbsClass + ' ' + navDotsClass);
}
if (o_nav) {
if (o_navTop) {
$navWrap.insertBefore($stage);
} else {
$navWrap.insertAfter($stage);
}
frameAppend.nav = false;
frameAppend($navFrame, $navShaft, 'nav');
}
o_allowFullScreen = opts.allowfullscreen;
if (o_allowFullScreen) {
$fullscreenIcon.prependTo($stage);
o_nativeFullScreen = FULLSCREEN && o_allowFullScreen === 'native';
} else {
$fullscreenIcon.detach();
o_nativeFullScreen = false;
}
addOrRemoveClass(o_fade, wrapFadeClass);
addOrRemoveClass(!o_fade, wrapSlideClass);
addOrRemoveClass(!opts.captions, wrapNoCaptionsClass);
addOrRemoveClass(o_rtl, wrapRtlClass);
addOrRemoveClass(opts.arrows, wrapToggleArrowsClass);
o_shadows = opts.shadows && !SLOW;
addOrRemoveClass(!o_shadows, wrapNoShadowsClass);
$wrap
.addClass(classes.add.join(' '))
.removeClass(classes.remove.join(' '));
lastOptions = $.extend({}, opts);
setStagePosition();
}
function normalizeIndex(index) {
return index < 0 ? (size + (index % size)) % size : index >= size ? index % size : index;
}
function limitIndex(index) {
return minMaxLimit(index, 0, size - 1);
}
function edgeIndex(index) {
return o_loop ? normalizeIndex(index) : limitIndex(index);
}
function getPrevIndex(index) {
return index > 0 || o_loop ? index - 1 : false;
}
function getNextIndex(index) {
return index < size - 1 || o_loop ? index + 1 : false;
}
function setStageShaftMinmaxAndSnap() {
stageShaftTouchTail.min = o_loop ? -Infinity : -getPosByIndex(size - 1, measures.w, opts.margin, repositionIndex);
stageShaftTouchTail.max = o_loop ? Infinity : -getPosByIndex(0, measures.w, opts.margin, repositionIndex);
stageShaftTouchTail.snap = measures.w + opts.margin;
}
function setNavShaftMinMax() {
var isVerticalDir = (opts.navdir === 'vertical');
var param = isVerticalDir ? $navShaft.height() : $navShaft.width();
var mainParam = isVerticalDir ? measures.h : measures.nw;
navShaftTouchTail.min = Math.min(0, mainParam - param);
navShaftTouchTail.max = 0;
navShaftTouchTail.direction = opts.navdir;
$navShaft.toggleClass(grabClass, !(navShaftTouchTail.noMove = navShaftTouchTail.min === navShaftTouchTail.max));
}
function eachIndex(indexes, type, fn) {
if (typeof indexes === 'number') {
indexes = new Array(indexes);
var rangeFLAG = true;
}
return $.each(indexes, function (i, index) {
if (rangeFLAG) index = i;
if (typeof index === 'number') {
var dataFrame = data[normalizeIndex(index)];
if (dataFrame) {
var key = '$' + type + 'Frame',
$frame = dataFrame[key];
fn.call(this, i, index, dataFrame, $frame, key, $frame && $frame.data());
}
}
});
}
function setMeasures(width, height, ratio, index) {
if (!measuresSetFLAG || (measuresSetFLAG === '*' && index === startIndex)) {
width = measureIsValid(opts.width) || measureIsValid(width) || WIDTH;
height = measureIsValid(opts.height) || measureIsValid(height) || HEIGHT;
that.resize({
width: width,
ratio: opts.ratio || ratio || width / height
}, 0, index !== startIndex && '*');
}
}
function loadImg(indexes, type, specialMeasures, again) {
eachIndex(indexes, type, function (i, index, dataFrame, $frame, key, frameData) {
if (!$frame) return;
var fullFLAG = that.fullScreen && !frameData.$full && type === 'stage';
if (frameData.$img && !again && !fullFLAG) return;
var img = new Image(),
$img = $(img),
imgData = $img.data();
frameData[fullFLAG ? '$full' : '$img'] = $img;
var srcKey = type === 'stage' ? (fullFLAG ? 'full' : 'img') : 'thumb',
src = dataFrame[srcKey],
dummy = fullFLAG ? dataFrame['img'] : dataFrame[type === 'stage' ? 'thumb' : 'img'];
if (type === 'navThumb') $frame = frameData.$wrap;
function triggerTriggerEvent(event) {
var _index = normalizeIndex(index);
triggerEvent(event, {
index: _index,
src: src,
frame: data[_index]
});
}
function error() {
$img.remove();
$.Fotorama.cache[src] = 'error';
if ((!dataFrame.html || type !== 'stage') && dummy && dummy !== src) {
dataFrame[srcKey] = src = dummy;
frameData.$full = null;
loadImg([index], type, specialMeasures, true);
} else {
if (src && !dataFrame.html && !fullFLAG) {
$frame
.trigger('f:error')
.removeClass(loadingClass)
.addClass(errorClass);
triggerTriggerEvent('error');
} else if (type === 'stage') {
$frame
.trigger('f:load')
.removeClass(loadingClass + ' ' + errorClass)
.addClass(loadedClass);
triggerTriggerEvent('load');
setMeasures();
}
frameData.state = 'error';
if (size > 1 && data[index] === dataFrame && !dataFrame.html && !dataFrame.deleted && !dataFrame.video && !fullFLAG) {
dataFrame.deleted = true;
that.splice(index, 1);
}
}
}
function loaded() {
$.Fotorama.measures[src] = imgData.measures = $.Fotorama.measures[src] || {
width: img.width,
height: img.height,
ratio: img.width / img.height
};
setMeasures(imgData.measures.width, imgData.measures.height, imgData.measures.ratio, index);
$img
.off('load error')
.addClass('' + (fullFLAG ? imgFullClass: imgClass))
.attr('aria-hidden', 'false')
.prependTo($frame);
if ($frame.hasClass(stageFrameClass) && !$frame.hasClass(videoContainerClass)) {
$frame.attr("href", $img.attr("src"));
}
fit($img, (
$.isFunction(specialMeasures) ? specialMeasures() : specialMeasures) || measures);
$.Fotorama.cache[src] = frameData.state = 'loaded';
setTimeout(function () {
$frame
.trigger('f:load')
.removeClass(loadingClass + ' ' + errorClass)
.addClass(loadedClass + ' ' + (fullFLAG ? loadedFullClass : loadedImgClass));
if (type === 'stage') {
triggerTriggerEvent('load');
} else if (dataFrame.thumbratio === AUTO || !dataFrame.thumbratio && opts.thumbratio === AUTO) {
// danger! reflow for all thumbnails
dataFrame.thumbratio = imgData.measures.ratio;
reset();
}
}, 0);
}
if (!src) {
error();
return;
}
function waitAndLoad() {
var _i = 10;
waitFor(function () {
return !touchedFLAG || !_i-- && !SLOW;
}, function () {
loaded();
});
}
if (!$.Fotorama.cache[src]) {
$.Fotorama.cache[src] = '*';
$img
.on('load', waitAndLoad)
.on('error', error);
} else {
(function justWait() {
if ($.Fotorama.cache[src] === 'error') {
error();
} else if ($.Fotorama.cache[src] === 'loaded') {
setTimeout(waitAndLoad, 0);
} else {
setTimeout(justWait, 100);
}
})();
}
frameData.state = '';
img.src = src;
if (frameData.data.caption) {
img.alt = frameData.data.caption || "";
}
if (frameData.data.full) {
$(img).data('original', frameData.data.full);
}
if (UTIL.isExpectedCaption(dataFrame, opts.showcaption)) {
$(img).attr('aria-labelledby', dataFrame.labelledby);
}
});
}
function updateFotoramaState() {
var $frame = activeFrame[STAGE_FRAME_KEY];
if ($frame && !$frame.data().state) {
$spinner.addClass(spinnerShowClass);
$frame.on('f:load f:error', function () {
$frame.off('f:load f:error');
$spinner.removeClass(spinnerShowClass);
});
}
}
function addNavFrameEvents(frame) {
addEnterUp(frame, onNavFrameClick);
addFocus(frame, function () {
setTimeout(function () {
lockScroll($nav);
}, 0);
slideNavShaft({time: o_transitionDuration, guessIndex: $(this).data().eq, minMax: navShaftTouchTail});
});
}
function frameDraw(indexes, type) {
eachIndex(indexes, type, function (i, index, dataFrame, $frame, key, frameData) {
if ($frame) return;
$frame = dataFrame[key] = $wrap[key].clone();
frameData = $frame.data();
frameData.data = dataFrame;
var frame = $frame[0],
labelledbyValue = "labelledby" + $.now();
if (type === 'stage') {
if (dataFrame.html) {
$('<div class="' + htmlClass + '"></div>')
.append(
dataFrame._html ? $(dataFrame.html)
.removeAttr('id')
.html(dataFrame._html) // Because of IE
: dataFrame.html
)
.appendTo($frame);
}
if (dataFrame.id) {
labelledbyValue = dataFrame.id || labelledbyValue;
}
dataFrame.labelledby = labelledbyValue;
if (UTIL.isExpectedCaption(dataFrame, opts.showcaption)) {
$($.Fotorama.jst.frameCaption({
caption: dataFrame.caption,
labelledby: labelledbyValue
})).appendTo($frame);
}
dataFrame.video && $frame
.addClass(stageFrameVideoClass)
.append($videoPlay.clone());
// This solves tabbing problems
addFocus(frame, function (e) {
setTimeout(function () {
lockScroll($stage);
}, 0);
clickToShow({index: frameData.eq, user: true}, e);
});
$stageFrame = $stageFrame.add($frame);
} else if (type === 'navDot') {
addNavFrameEvents(frame);
$navDotFrame = $navDotFrame.add($frame);
} else if (type === 'navThumb') {
addNavFrameEvents(frame);
frameData.$wrap = $frame.children(':first');
$navThumbFrame = $navThumbFrame.add($frame);
if (dataFrame.video) {
frameData.$wrap.append($videoPlay.clone());
}
}
});
}
function callFit($img, measuresToFit) {
return $img && $img.length && fit($img, measuresToFit);
}
function stageFramePosition(indexes) {
eachIndex(indexes, 'stage', function (i, index, dataFrame, $frame, key, frameData) {
if (!$frame) return;
var normalizedIndex = normalizeIndex(index);
frameData.eq = normalizedIndex;
toDetach[STAGE_FRAME_KEY][normalizedIndex] = $frame.css($.extend({left: o_fade ? 0 : getPosByIndex(index, measures.w, opts.margin, repositionIndex)}, o_fade && getDuration(0)));
if (isDetached($frame[0])) {
$frame.appendTo($stageShaft);
unloadVideo(dataFrame.$video);
}
callFit(frameData.$img, measures);
callFit(frameData.$full, measures);
if ($frame.hasClass(stageFrameClass) && !($frame.attr('aria-hidden') === "false" && $frame.hasClass(activeClass))) {
$frame.attr('aria-hidden', 'true');
}
});
}
function thumbsDraw(pos, loadFLAG) {
var leftLimit,
rightLimit,
exceedLimit;
if (o_nav !== 'thumbs' || isNaN(pos)) return;
leftLimit = -pos;
rightLimit = -pos + measures.nw;
if (opts.navdir === 'vertical') {
pos = pos - opts.thumbheight;
rightLimit = -pos + measures.h;
}
$navThumbFrame.each(function () {
var $this = $(this),
thisData = $this.data(),
eq = thisData.eq,
getSpecialMeasures = function () {
return {
h: o_thumbSide2,
w: thisData.w
}
},
specialMeasures = getSpecialMeasures(),
exceedLimit = opts.navdir === 'vertical' ?
thisData.t > rightLimit : thisData.l > rightLimit;
specialMeasures.w = thisData.w;
if ((opts.navdir !== 'vertical' && thisData.l + thisData.w < leftLimit)
|| exceedLimit
|| callFit(thisData.$img, specialMeasures)) return;
loadFLAG && loadImg([eq], 'navThumb', getSpecialMeasures);
});
}
function frameAppend($frames, $shaft, type) {
if (!frameAppend[type]) {
var thumbsFLAG = type === 'nav' && o_navThumbs,
left = 0,
top = 0;
$shaft.append(
$frames
.filter(function () {
var actual,
$this = $(this),
frameData = $this.data();
for (var _i = 0, _l = data.length; _i < _l; _i++) {
if (frameData.data === data[_i]) {
actual = true;
frameData.eq = _i;
break;
}
}
return actual || $this.remove() && false;
})
.sort(function (a, b) {
return $(a).data().eq - $(b).data().eq;
})
.each(function () {
var $this = $(this),
frameData = $this.data();
UTIL.setThumbAttr($this, frameData.data.caption, "aria-label");
})
.each(function () {
if (!thumbsFLAG) return;
var $this = $(this),
frameData = $this.data(),
thumbwidth = Math.round(o_thumbSide2 * frameData.data.thumbratio) || o_thumbSide,
thumbheight = Math.round(o_thumbSide / frameData.data.thumbratio) || o_thumbSide2;
frameData.t = top;
frameData.h = thumbheight;
frameData.l = left;
frameData.w = thumbwidth;
$this.css({width: thumbwidth});
top += thumbheight + opts.thumbmargin;
left += thumbwidth + opts.thumbmargin;
})
);
frameAppend[type] = true;
}
}
function getDirection(x) {
return x - stageLeft > measures.w / 3;
}
function disableDirrection(i) {
return !o_loop && (!(activeIndex + i) || !(activeIndex - size + i)) && !$videoPlaying;
}
function arrsUpdate() {
var disablePrev = disableDirrection(0),
disableNext = disableDirrection(1);
$arrPrev
.toggleClass(arrDisabledClass, disablePrev)
.attr(disableAttr(disablePrev, false));
$arrNext
.toggleClass(arrDisabledClass, disableNext)
.attr(disableAttr(disableNext, false));
}
function thumbArrUpdate() {
var isLeftDisable = false,
isRightDisable = false;
if (opts.navtype === 'thumbs' && !opts.loop) {
(activeIndex == 0) ? isLeftDisable = true : isLeftDisable = false;
(activeIndex == opts.data.length - 1) ? isRightDisable = true : isRightDisable = false;
}
if (opts.navtype === 'slides') {
var pos = readPosition($navShaft, opts.navdir);
pos >= navShaftTouchTail.max ? isLeftDisable = true : isLeftDisable = false;
pos <= Math.round(navShaftTouchTail.min) ? isRightDisable = true : isRightDisable = false;
}
$thumbArrLeft
.toggleClass(arrDisabledClass, isLeftDisable)
.attr(disableAttr(isLeftDisable, true));
$thumbArrRight
.toggleClass(arrDisabledClass, isRightDisable)
.attr(disableAttr(isRightDisable, true));
}
function stageWheelUpdate() {
if (stageWheelTail.ok) {
stageWheelTail.prevent = {'<': disableDirrection(0), '>': disableDirrection(1)};
}
}
function getNavFrameBounds($navFrame) {
var navFrameData = $navFrame.data(),
left,
top,
width,
height;
if (o_navThumbs) {
left = navFrameData.l;
top = navFrameData.t;
width = navFrameData.w;
height = navFrameData.h;
} else {
left = $navFrame.position().left;
width = $navFrame.width();
}
var horizontalBounds = {
c: left + width / 2,
min: -left + opts.thumbmargin * 10,
max: -left + measures.w - width - opts.thumbmargin * 10
};
var verticalBounds = {
c: top + height / 2,
min: -top + opts.thumbmargin * 10,
max: -top + measures.h - height - opts.thumbmargin * 10
};
return opts.navdir === 'vertical' ? verticalBounds : horizontalBounds;
}
function slideThumbBorder(time) {
var navFrameData = activeFrame[navFrameKey].data();
slide($thumbBorder, {
time: time * 1.2,
pos: (opts.navdir === 'vertical' ? navFrameData.t : navFrameData.l),
width: navFrameData.w,
height: navFrameData.h,
direction: opts.navdir
});
}
function slideNavShaft(options) {
var $guessNavFrame = data[options.guessIndex][navFrameKey],
typeOfAnimation = opts.navtype;
var overflowFLAG,
time,
minMax,
boundTop,
boundLeft,
l,
pos,
x;
if ($guessNavFrame) {
if (typeOfAnimation === 'thumbs') {
overflowFLAG = navShaftTouchTail.min !== navShaftTouchTail.max;
minMax = options.minMax || overflowFLAG && getNavFrameBounds(activeFrame[navFrameKey]);
boundTop = overflowFLAG && (options.keep && slideNavShaft.t ? slideNavShaft.l : minMaxLimit((options.coo || measures.nw / 2) - getNavFrameBounds($guessNavFrame).c, minMax.min, minMax.max));
boundLeft = overflowFLAG && (options.keep && slideNavShaft.l ? slideNavShaft.l : minMaxLimit((options.coo || measures.nw / 2) - getNavFrameBounds($guessNavFrame).c, minMax.min, minMax.max));
l = (opts.navdir === 'vertical' ? boundTop : boundLeft);
pos = overflowFLAG && minMaxLimit(l, navShaftTouchTail.min, navShaftTouchTail.max) || 0;
time = options.time * 1.1;
slide($navShaft, {
time: time,
pos: pos,
direction: opts.navdir,
onEnd: function () {
thumbsDraw(pos, true);
thumbArrUpdate();
}
});
setShadow($nav, findShadowEdge(pos, navShaftTouchTail.min, navShaftTouchTail.max, opts.navdir));
slideNavShaft.l = l;
} else {
x = readPosition($navShaft, opts.navdir);
time = options.time * 1.11;
pos = validateSlidePos(opts, navShaftTouchTail, options.guessIndex, x, $guessNavFrame, $navWrap, opts.navdir);
slide($navShaft, {
time: time,
pos: pos,
direction: opts.navdir,
onEnd: function () {
thumbsDraw(pos, true);
thumbArrUpdate();
}
});
setShadow($nav, findShadowEdge(pos, navShaftTouchTail.min, navShaftTouchTail.max, opts.navdir));
}
}
}
function navUpdate() {
deactivateFrames(navFrameKey);
toDeactivate[navFrameKey].push(activeFrame[navFrameKey].addClass(activeClass).attr('data-active', true));
}
function deactivateFrames(key) {
var _toDeactivate = toDeactivate[key];
while (_toDeactivate.length) {
_toDeactivate.shift().removeClass(activeClass).attr('data-active', false);
}
}
function detachFrames(key) {
var _toDetach = toDetach[key];
$.each(activeIndexes, function (i, index) {
delete _toDetach[normalizeIndex(index)];
});
$.each(_toDetach, function (index, $frame) {
delete _toDetach[index];
$frame.detach();
});
}
function stageShaftReposition(skipOnEnd) {
repositionIndex = dirtyIndex = activeIndex;
var $frame = activeFrame[STAGE_FRAME_KEY];
if ($frame) {
deactivateFrames(STAGE_FRAME_KEY);
toDeactivate[STAGE_FRAME_KEY].push($frame.addClass(activeClass).attr('data-active', true));
if ($frame.hasClass(stageFrameClass)) {
$frame.attr('aria-hidden', 'false');
}
skipOnEnd || that.showStage.onEnd(true);
stop($stageShaft, 0, true);
detachFrames(STAGE_FRAME_KEY);
stageFramePosition(activeIndexes);
setStageShaftMinmaxAndSnap();
setNavShaftMinMax();
addEnterUp($stageShaft[0], function () {
if (!$fotorama.hasClass(fullscreenClass)) {
that.requestFullScreen();
$fullscreenIcon.focus();
}
});
}
}
function extendMeasures(options, measuresArray) {
if (!options) return;
$.each(measuresArray, function (i, measures) {
if (!measures) return;
$.extend(measures, {
width: options.width || measures.width,
height: options.height,
minwidth: options.minwidth,
maxwidth: options.maxwidth,
minheight: options.minheight,
maxheight: options.maxheight,
ratio: getRatio(options.ratio)
})
});
}
function triggerEvent(event, extra) {
$fotorama.trigger(_fotoramaClass + ':' + event, [that, extra]);
}
function onTouchStart() {
clearTimeout(onTouchEnd.t);
touchedFLAG = 1;
if (opts.stopautoplayontouch) {
that.stopAutoplay();
} else {
pausedAutoplayFLAG = true;
}
}
function onTouchEnd() {
if (!touchedFLAG) return;
if (!opts.stopautoplayontouch) {
releaseAutoplay();
changeAutoplay();
}
onTouchEnd.t = setTimeout(function () {
touchedFLAG = 0;
}, TRANSITION_DURATION + TOUCH_TIMEOUT);
}
function releaseAutoplay() {
pausedAutoplayFLAG = !!($videoPlaying || stoppedAutoplayFLAG);
}
function changeAutoplay() {
clearTimeout(changeAutoplay.t);
waitFor.stop(changeAutoplay.w);
if (!opts.autoplay || pausedAutoplayFLAG) {
if (that.autoplay) {
that.autoplay = false;
triggerEvent('stopautoplay');
}
return;
}
if (!that.autoplay) {
that.autoplay = true;
triggerEvent('startautoplay');
}
var _activeIndex = activeIndex;
var frameData = activeFrame[STAGE_FRAME_KEY].data();
changeAutoplay.w = waitFor(function () {
return frameData.state || _activeIndex !== activeIndex;
}, function () {
changeAutoplay.t = setTimeout(function () {
if (pausedAutoplayFLAG || _activeIndex !== activeIndex) return;
var _nextAutoplayIndex = nextAutoplayIndex,
nextFrameData = data[_nextAutoplayIndex][STAGE_FRAME_KEY].data();
changeAutoplay.w = waitFor(function () {
return nextFrameData.state || _nextAutoplayIndex !== nextAutoplayIndex;
}, function () {
if (pausedAutoplayFLAG || _nextAutoplayIndex !== nextAutoplayIndex) return;
that.show(o_loop ? getDirectionSign(!o_rtl) : nextAutoplayIndex);
});
}, opts.autoplay);
});
}
that.startAutoplay = function (interval) {
if (that.autoplay) return this;
pausedAutoplayFLAG = stoppedAutoplayFLAG = false;
setAutoplayInterval(interval || opts.autoplay);
changeAutoplay();
return this;
};
that.stopAutoplay = function () {
if (that.autoplay) {
pausedAutoplayFLAG = stoppedAutoplayFLAG = true;
changeAutoplay();
}
return this;
};
that.showSlide = function (slideDir) {
var currentPosition = readPosition($navShaft, opts.navdir),
pos,
time = 500 * 1.1,
size = opts.navdir === 'horizontal' ? opts.thumbwidth : opts.thumbheight,
onEnd = function () {
thumbArrUpdate();
};
if (slideDir === 'next') {
pos = currentPosition - (size + opts.margin) * thumbsPerSlide;
}
if (slideDir === 'prev') {
pos = currentPosition + (size + opts.margin) * thumbsPerSlide;
}
pos = validateRestrictions(pos, navShaftTouchTail);
thumbsDraw(pos, true);
slide($navShaft, {
time: time,
pos: pos,
direction: opts.navdir,
onEnd: onEnd
});
};
that.showWhileLongPress = function (options) {
if (that.longPress.singlePressInProgress) {
return;
}
var index = calcActiveIndex(options);
calcGlobalIndexes(index);
var time = calcTime(options) / 50;
var _activeFrame = activeFrame;
that.activeFrame = activeFrame = data[activeIndex];
var silent = _activeFrame === activeFrame && !options.user;
that.showNav(silent, options, time);
return this;
};
that.showEndLongPress = function (options) {
if (that.longPress.singlePressInProgress) {
return;
}
var index = calcActiveIndex(options);
calcGlobalIndexes(index);
var time = calcTime(options) / 50;
var _activeFrame = activeFrame;
that.activeFrame = activeFrame = data[activeIndex];
var silent = _activeFrame === activeFrame && !options.user;
that.showStage(silent, options, time);
showedFLAG = typeof lastActiveIndex !== 'undefined' && lastActiveIndex !== activeIndex;
lastActiveIndex = activeIndex;
return this;
};
function calcActiveIndex (options) {
var index;
if (typeof options !== 'object') {
index = options;
options = {};
} else {
index = options.index;
}
index = index === '>' ? dirtyIndex + 1 : index === '<' ? dirtyIndex - 1 : index === '<<' ? 0 : index === '>>' ? size - 1 : index;
index = isNaN(index) ? undefined : index;
index = typeof index === 'undefined' ? activeIndex || 0 : index;
return index;
}
function calcGlobalIndexes (index) {
that.activeIndex = activeIndex = edgeIndex(index);
prevIndex = getPrevIndex(activeIndex);
nextIndex = getNextIndex(activeIndex);
nextAutoplayIndex = normalizeIndex(activeIndex + (o_rtl ? -1 : 1));
activeIndexes = [activeIndex, prevIndex, nextIndex];
dirtyIndex = o_loop ? index : activeIndex;
}
function calcTime (options) {
var diffIndex = Math.abs(lastActiveIndex - dirtyIndex),
time = getNumber(options.time, function () {
return Math.min(o_transitionDuration * (1 + (diffIndex - 1) / 12), o_transitionDuration * 2);
});
if (options.slow) {
time *= 10;
}
return time;
}
that.showStage = function (silent, options, time, e) {
if (e !== undefined && e.target.tagName == 'IFRAME') {
return;
}
unloadVideo($videoPlaying, activeFrame.i !== data[normalizeIndex(repositionIndex)].i);
frameDraw(activeIndexes, 'stage');
stageFramePosition(SLOW ? [dirtyIndex] : [dirtyIndex, getPrevIndex(dirtyIndex), getNextIndex(dirtyIndex)]);
updateTouchTails('go', true);
silent || triggerEvent('show', {
user: options.user,
time: time
});
pausedAutoplayFLAG = true;
var overPos = options.overPos;
var onEnd = that.showStage.onEnd = function (skipReposition) {
if (onEnd.ok) return;
onEnd.ok = true;
skipReposition || stageShaftReposition(true);
if (!silent) {
triggerEvent('showend', {
user: options.user
});
}
if (!skipReposition && o_transition && o_transition !== opts.transition) {
that.setOptions({transition: o_transition});
o_transition = false;
return;
}
updateFotoramaState();
loadImg(activeIndexes, 'stage');
updateTouchTails('go', false);
stageWheelUpdate();
stageCursor();
releaseAutoplay();
changeAutoplay();
if (that.fullScreen) {
activeFrame[STAGE_FRAME_KEY].find('.' + imgFullClass).attr('aria-hidden', false);
activeFrame[STAGE_FRAME_KEY].find('.' + imgClass).attr('aria-hidden', true)
} else {
activeFrame[STAGE_FRAME_KEY].find('.' + imgFullClass).attr('aria-hidden', true);
activeFrame[STAGE_FRAME_KEY].find('.' + imgClass).attr('aria-hidden', false)
}
};
if (!o_fade) {
slide($stageShaft, {
pos: -getPosByIndex(dirtyIndex, measures.w, opts.margin, repositionIndex),
overPos: overPos,
time: time,
onEnd: onEnd
});
} else {
var $activeFrame = activeFrame[STAGE_FRAME_KEY],
$prevActiveFrame = data[lastActiveIndex] && activeIndex !== lastActiveIndex ? data[lastActiveIndex][STAGE_FRAME_KEY] : null;
fade($activeFrame, $prevActiveFrame, $stageFrame, {
time: time,
method: opts.transition,
onEnd: onEnd
}, fadeStack);
}
arrsUpdate();
};
that.showNav = function(silent, options, time){
thumbArrUpdate();
if (o_nav) {
navUpdate();
var guessIndex = limitIndex(activeIndex + minMaxLimit(dirtyIndex - lastActiveIndex, -1, 1));
slideNavShaft({
time: time,
coo: guessIndex !== activeIndex && options.coo,
guessIndex: typeof options.coo !== 'undefined' ? guessIndex : activeIndex,
keep: silent
});
if (o_navThumbs) slideThumbBorder(time);
}
};
that.show = function (options, e) {
that.longPress.singlePressInProgress = true;
var index = calcActiveIndex(options);
calcGlobalIndexes(index);
var time = calcTime(options);
var _activeFrame = activeFrame;
that.activeFrame = activeFrame = data[activeIndex];
var silent = _activeFrame === activeFrame && !options.user;
that.showStage(silent, options, time, e);
that.showNav(silent, options, time);
showedFLAG = typeof lastActiveIndex !== 'undefined' && lastActiveIndex !== activeIndex;
lastActiveIndex = activeIndex;
that.longPress.singlePressInProgress = false;
return this;
};
that.requestFullScreen = function () {
if (o_allowFullScreen && !that.fullScreen) {
//check that this is not video
if(isVideo()) {
return;
}
scrollTop = $WINDOW.scrollTop();
scrollLeft = $WINDOW.scrollLeft();
lockScroll($WINDOW);
updateTouchTails('x', true);
measuresStash = $.extend({}, measures);
$fotorama
.addClass(fullscreenClass)
.appendTo($BODY.addClass(_fullscreenClass));
$HTML.addClass(_fullscreenClass);
unloadVideo($videoPlaying, true, true);
that.fullScreen = true;
if (o_nativeFullScreen) {
fullScreenApi.request(fotorama);
}
loadImg(activeIndexes, 'stage');
updateFotoramaState();
triggerEvent('fullscreenenter');
that.resize();
if (!('ontouchstart' in window)) {
$fullscreenIcon.focus();
}
}
return this;
};
function cancelFullScreen() {
if (that.fullScreen) {
that.fullScreen = false;
if (FULLSCREEN) {
fullScreenApi.cancel(fotorama);
}
$BODY.removeClass(_fullscreenClass);
$HTML.removeClass(_fullscreenClass);
$fotorama
.removeClass(fullscreenClass)
.insertAfter($anchor);
measures = $.extend({}, measuresStash);
unloadVideo($videoPlaying, true, true);
updateTouchTails('x', false);
that.resize();
loadImg(activeIndexes, 'stage');
lockScroll($WINDOW, scrollLeft, scrollTop);
triggerEvent('fullscreenexit');
}
}
that.cancelFullScreen = function () {
if (o_nativeFullScreen && fullScreenApi.is()) {
fullScreenApi.cancel(document);
} else {
cancelFullScreen();
}
return this;
};
that.toggleFullScreen = function () {
return that[(that.fullScreen ? 'cancel' : 'request') + 'FullScreen']();
};
that.resize = function (options) {
if (!data) return this;
var time = arguments[1] || 0,
setFLAG = arguments[2];
thumbsPerSlide = getThumbsInSlide($wrap, opts);
extendMeasures(!that.fullScreen ? optionsToLowerCase(options) : {
width: $(window).width(),
maxwidth: null,
minwidth: null,
height: $(window).height(),
maxheight: null,
minheight: null
}, [measures, setFLAG || that.fullScreen || opts]);
var width = measures.width,
height = measures.height,
ratio = measures.ratio,
windowHeight = $WINDOW.height() - (o_nav ? $nav.height() : 0);
if (measureIsValid(width)) {
$wrap.css({width: ''});
$stage.css({width: ''});
$stageShaft.css({width: ''});
$nav.css({width: ''});
$wrap.css({minWidth: measures.minwidth || 0, maxWidth: measures.maxwidth || MAX_WIDTH});
if (o_nav === 'dots') {
$navWrap.hide();
}
width = measures.W = measures.w = $wrap.width();
measures.nw = o_nav && numberFromWhatever(opts.navwidth, width) || width;
$stageShaft.css({width: measures.w, marginLeft: (measures.W - measures.w) / 2});
height = numberFromWhatever(height, windowHeight);
height = height || (ratio && width / ratio);
if (height) {
width = Math.round(width);
height = measures.h = Math.round(minMaxLimit(height, numberFromWhatever(measures.minheight, windowHeight), numberFromWhatever(measures.maxheight, windowHeight)));
$stage.css({'width': width, 'height': height});
if (opts.navdir === 'vertical' && !that.fullscreen) {
$nav.width(opts.thumbwidth + opts.thumbmargin * 2);
}
if (opts.navdir === 'horizontal' && !that.fullscreen) {
$nav.height(opts.thumbheight + opts.thumbmargin * 2);
}
if (o_nav === 'dots') {
$nav.width(width)
.height('auto');
$navWrap.show();
}
if (opts.navdir === 'vertical' && that.fullScreen) {
$stage.css('height', $WINDOW.height());
}
if (opts.navdir === 'horizontal' && that.fullScreen) {
$stage.css('height', $WINDOW.height() - $nav.height());
}
if (o_nav) {
switch (opts.navdir) {
case 'vertical':
$navWrap.removeClass(navShafthorizontalClass);
$navWrap.removeClass(navShaftListClass);
$navWrap.addClass(navShaftVerticalClass);
$nav
.stop()
.animate({height: measures.h, width: opts.thumbwidth}, time);
break;
case 'list':
$navWrap.removeClass(navShaftVerticalClass);
$navWrap.removeClass(navShafthorizontalClass);
$navWrap.addClass(navShaftListClass);
break;
default:
$navWrap.removeClass(navShaftVerticalClass);
$navWrap.removeClass(navShaftListClass);
$navWrap.addClass(navShafthorizontalClass);
$nav
.stop()
.animate({width: measures.nw}, time);
break;
}
stageShaftReposition();
slideNavShaft({guessIndex: activeIndex, time: time, keep: true});
if (o_navThumbs && frameAppend.nav) slideThumbBorder(time);
}
measuresSetFLAG = setFLAG || true;
ready.ok = true;
ready();
}
}
stageLeft = $stage.offset().left;
setStagePosition();
return this;
};
that.setOptions = function (options) {
$.extend(opts, options);
reset();
return this;
};
that.shuffle = function () {
data && shuffle(data) && reset();
return this;
};
function setShadow($el, edge) {
if (o_shadows) {
$el.removeClass(shadowsLeftClass + ' ' + shadowsRightClass);
$el.removeClass(shadowsTopClass + ' ' + shadowsBottomClass);
edge && !$videoPlaying && $el.addClass(edge.replace(/^|\s/g, ' ' + shadowsClass + '--'));
}
}
that.longPress = {
threshold: 1,
count: 0,
thumbSlideTime: 20,
progress: function(){
if (!this.inProgress) {
this.count++;
this.inProgress = this.count > this.threshold;
}
},
end: function(){
if(this.inProgress) {
this.isEnded = true
}
},
reset: function(){
this.count = 0;
this.inProgress = false;
this.isEnded = false;
}
};
that.destroy = function () {
that.cancelFullScreen();
that.stopAutoplay();
data = that.data = null;
appendElements();
activeIndexes = [];
detachFrames(STAGE_FRAME_KEY);
reset.ok = false;
return this;
};
/**
*
* @returns {jQuery.Fotorama}
*/
that.playVideo = function () {
var dataFrame = activeFrame,
video = dataFrame.video,
_activeIndex = activeIndex;
if (typeof video === 'object' && dataFrame.videoReady) {
o_nativeFullScreen && that.fullScreen && that.cancelFullScreen();
waitFor(function () {
return !fullScreenApi.is() || _activeIndex !== activeIndex;
}, function () {
if (_activeIndex === activeIndex) {
dataFrame.$video = dataFrame.$video || $(div(videoClass)).append(createVideoFrame(video));
dataFrame.$video.appendTo(dataFrame[STAGE_FRAME_KEY]);
$wrap.addClass(wrapVideoClass);
$videoPlaying = dataFrame.$video;
stageNoMove();
$arrs.blur();
$fullscreenIcon.blur();
triggerEvent('loadvideo');
}
});
}
return this;
};
that.stopVideo = function () {
unloadVideo($videoPlaying, true, true);
return this;
};
that.spliceByIndex = function (index, newImgObj) {
newImgObj.i = index + 1;
newImgObj.img && $.ajax({
url: newImgObj.img,
type: 'HEAD',
success: function () {
data.splice(index, 1, newImgObj);
reset();
}
});
};
function unloadVideo($video, unloadActiveFLAG, releaseAutoplayFLAG) {
if (unloadActiveFLAG) {
$wrap.removeClass(wrapVideoClass);
$videoPlaying = false;
stageNoMove();
}
if ($video && $video !== $videoPlaying) {
$video.remove();
triggerEvent('unloadvideo');
}
if (releaseAutoplayFLAG) {
releaseAutoplay();
changeAutoplay();
}
}
function toggleControlsClass(FLAG) {
$wrap.toggleClass(wrapNoControlsClass, FLAG);
}
function stageCursor(e) {
if (stageShaftTouchTail.flow) return;
var x = e ? e.pageX : stageCursor.x,
pointerFLAG = x && !disableDirrection(getDirection(x)) && opts.click;
if (stageCursor.p !== pointerFLAG
&& $stage.toggleClass(pointerClass, pointerFLAG)) {
stageCursor.p = pointerFLAG;
stageCursor.x = x;
}
}
$stage.on('mousemove', stageCursor);
function clickToShow(showOptions, e) {
clearTimeout(clickToShow.t);
if (opts.clicktransition && opts.clicktransition !== opts.transition) {
setTimeout(function () {
var _o_transition = opts.transition;
that.setOptions({transition: opts.clicktransition});
// now safe to pass base transition to o_transition, so that.show will restor it
o_transition = _o_transition;
// this timeout is here to prevent jerking in some browsers
clickToShow.t = setTimeout(function () {
that.show(showOptions);
}, 10);
}, 0);
} else {
that.show(showOptions, e);
}
}
function onStageTap(e, toggleControlsFLAG) {
var target = e.target,
$target = $(target);
if ($target.hasClass(videoPlayClass)) {
that.playVideo();
} else if (target === fullscreenIcon) {
that.toggleFullScreen();
} else if ($videoPlaying) {
target === videoClose && unloadVideo($videoPlaying, true, true);
} else if (!$fotorama.hasClass(fullscreenClass)) {
that.requestFullScreen();
}
}
function updateTouchTails(key, value) {
stageShaftTouchTail[key] = navShaftTouchTail[key] = value;
}
stageShaftTouchTail = moveOnTouch($stageShaft, {
onStart: onTouchStart,
onMove: function (e, result) {
setShadow($stage, result.edge);
},
onTouchEnd: onTouchEnd,
onEnd: function (result) {
var toggleControlsFLAG;
setShadow($stage);
toggleControlsFLAG = (MS_POINTER && !hoverFLAG || result.touch) &&
opts.arrows;
if ((result.moved || (toggleControlsFLAG && result.pos !== result.newPos && !result.control)) && result.$target[0] !== $fullscreenIcon[0]) {
var index = getIndexByPos(result.newPos, measures.w, opts.margin, repositionIndex);
that.show({
index: index,
time: o_fade ? o_transitionDuration : result.time,
overPos: result.overPos,
user: true
});
} else if (!result.aborted && !result.control) {
onStageTap(result.startEvent, toggleControlsFLAG);
}
},
timeLow: 1,
timeHigh: 1,
friction: 2,
select: '.' + selectClass + ', .' + selectClass + ' *',
$wrap: $stage,
direction: 'horizontal'
});
navShaftTouchTail = moveOnTouch($navShaft, {
onStart: onTouchStart,
onMove: function (e, result) {
setShadow($nav, result.edge);
},
onTouchEnd: onTouchEnd,
onEnd: function (result) {
function onEnd() {
slideNavShaft.l = result.newPos;
releaseAutoplay();
changeAutoplay();
thumbsDraw(result.newPos, true);
thumbArrUpdate();
}
if (!result.moved) {
var target = result.$target.closest('.' + navFrameClass, $navShaft)[0];
target && onNavFrameClick.call(target, result.startEvent);
} else if (result.pos !== result.newPos) {
pausedAutoplayFLAG = true;
slide($navShaft, {
time: result.time,
pos: result.newPos,
overPos: result.overPos,
direction: opts.navdir,
onEnd: onEnd
});
thumbsDraw(result.newPos);
o_shadows && setShadow($nav, findShadowEdge(result.newPos, navShaftTouchTail.min, navShaftTouchTail.max, result.dir));
} else {
onEnd();
}
},
timeLow: .5,
timeHigh: 2,
friction: 5,
$wrap: $nav,
direction: opts.navdir
});
stageWheelTail = wheel($stage, {
shift: true,
onEnd: function (e, direction) {
onTouchStart();
onTouchEnd();
that.show({index: direction, slow: e.altKey})
}
});
navWheelTail = wheel($nav, {
onEnd: function (e, direction) {
onTouchStart();
onTouchEnd();
var newPos = stop($navShaft) + direction * .25;
$navShaft.css(getTranslate(minMaxLimit(newPos, navShaftTouchTail.min, navShaftTouchTail.max), opts.navdir));
o_shadows && setShadow($nav, findShadowEdge(newPos, navShaftTouchTail.min, navShaftTouchTail.max, opts.navdir));
navWheelTail.prevent = {'<': newPos >= navShaftTouchTail.max, '>': newPos <= navShaftTouchTail.min};
clearTimeout(navWheelTail.t);
navWheelTail.t = setTimeout(function () {
slideNavShaft.l = newPos;
thumbsDraw(newPos, true)
}, TOUCH_TIMEOUT);
thumbsDraw(newPos);
}
});
$wrap.hover(
function () {
setTimeout(function () {
if (touchedFLAG) return;
toggleControlsClass(!(hoverFLAG = true));
}, 0);
},
function () {
if (!hoverFLAG) return;
toggleControlsClass(!(hoverFLAG = false));
}
);
function onNavFrameClick(e) {
var index = $(this).data().eq;
if (opts.navtype === 'thumbs') {
clickToShow({index: index, slow: e.altKey, user: true, coo: e._x - $nav.offset().left});
} else {
clickToShow({index: index, slow: e.altKey, user: true});
}
}
function onArrClick(e) {
clickToShow({index: $arrs.index(this) ? '>' : '<', slow: e.altKey, user: true});
}
smartClick($arrs, function (e) {
stopEvent(e);
onArrClick.call(this, e);
}, {
onStart: function () {
onTouchStart();
stageShaftTouchTail.control = true;
},
onTouchEnd: onTouchEnd
});
smartClick($thumbArrLeft, function (e) {
stopEvent(e);
if (opts.navtype === 'thumbs') {
that.show('<');
} else {
that.showSlide('prev')
}
});
smartClick($thumbArrRight, function (e) {
stopEvent(e);
if (opts.navtype === 'thumbs') {
that.show('>');
} else {
that.showSlide('next')
}
});
function addFocusOnControls(el) {
addFocus(el, function () {
setTimeout(function () {
lockScroll($stage);
}, 0);
toggleControlsClass(false);
});
}
$arrs.each(function () {
addEnterUp(this, function (e) {
onArrClick.call(this, e);
});
addFocusOnControls(this);
});
addEnterUp(fullscreenIcon, function () {
if ($fotorama.hasClass(fullscreenClass)) {
that.cancelFullScreen();
$stageShaft.focus();
} else {
that.requestFullScreen();
$fullscreenIcon.focus();
}
});
addFocusOnControls(fullscreenIcon);
function reset() {
setData();
setOptions();
if (!reset.i) {
reset.i = true;
// Only once
var _startindex = opts.startindex;
activeIndex = repositionIndex = dirtyIndex = lastActiveIndex = startIndex = edgeIndex(_startindex) || 0;
/*(o_rtl ? size - 1 : 0)*///;
}
if (size) {
if (changeToRtl()) return;
if ($videoPlaying) {
unloadVideo($videoPlaying, true);
}
activeIndexes = [];
if (!isVideo()) {
detachFrames(STAGE_FRAME_KEY);
}
reset.ok = true;
that.show({index: activeIndex, time: 0});
that.resize();
} else {
that.destroy();
}
}
function changeToRtl() {
if (!changeToRtl.f === o_rtl) {
changeToRtl.f = o_rtl;
activeIndex = size - 1 - activeIndex;
that.reverse();
return true;
}
}
$.each('load push pop shift unshift reverse sort splice'.split(' '), function (i, method) {
that[method] = function () {
data = data || [];
if (method !== 'load') {
Array.prototype[method].apply(data, arguments);
} else if (arguments[0] && typeof arguments[0] === 'object' && arguments[0].length) {
data = clone(arguments[0]);
}
reset();
return that;
}
});
function ready() {
if (ready.ok) {
ready.ok = false;
triggerEvent('ready');
}
}
reset();
};
$.fn.fotorama = function (opts) {
return this.each(function () {
var that = this,
$fotorama = $(this),
fotoramaData = $fotorama.data(),
fotorama = fotoramaData.fotorama;
if (!fotorama) {
waitFor(function () {
return !isHidden(that);
}, function () {
fotoramaData.urtext = $fotorama.html();
new $.Fotorama($fotorama,
$.extend(
{},
OPTIONS,
window.fotoramaDefaults,
opts,
fotoramaData
)
);
});
} else {
fotorama.setOptions(opts, true);
}
});
};
$.Fotorama.instances = [];
function calculateIndexes() {
$.each($.Fotorama.instances, function (index, instance) {
instance.index = index;
});
}
function addInstance(instance) {
$.Fotorama.instances.push(instance);
calculateIndexes();
}
function hideInstance(instance) {
$.Fotorama.instances.splice(instance.index, 1);
calculateIndexes();
}
$.Fotorama.cache = {};
$.Fotorama.measures = {};
$ = $ || {};
$.Fotorama = $.Fotorama || {};
$.Fotorama.jst = $.Fotorama.jst || {};
$.Fotorama.jst.dots = function (v) {
var __t, __p = '', __e = _.escape;
__p += '<div class="fotorama__nav__frame fotorama__nav__frame--dot" tabindex="0" role="button" data-gallery-role="nav-frame" data-nav-type="thumb" aria-label>\r\n <div class="fotorama__dot"></div>\r\n</div>';
return __p
};
$.Fotorama.jst.frameCaption = function (v) {
var __t, __p = '', __e = _.escape;
__p += '<div class="fotorama__caption" aria-hidden="true">\r\n <div class="fotorama__caption__wrap" id="' +
((__t = ( v.labelledby )) == null ? '' : __t) +
'">' +
((__t = ( v.caption )) == null ? '' : __t) +
'</div>\r\n</div>\r\n';
return __p
};
$.Fotorama.jst.style = function (v) {
var __t, __p = '', __e = _.escape;
__p += '.fotorama' +
((__t = ( v.s )) == null ? '' : __t) +
' .fotorama__nav--thumbs .fotorama__nav__frame{\r\npadding:' +
((__t = ( v.m )) == null ? '' : __t) +
'px;\r\nheight:' +
((__t = ( v.h )) == null ? '' : __t) +
'px}\r\n.fotorama' +
((__t = ( v.s )) == null ? '' : __t) +
' .fotorama__thumb-border{\r\nheight:' +
((__t = ( v.h )) == null ? '' : __t) +
'px;\r\nborder-width:' +
((__t = ( v.b )) == null ? '' : __t) +
'px;\r\nmargin-top:' +
((__t = ( v.m )) == null ? '' : __t) +
'px}';
return __p
};
$.Fotorama.jst.thumb = function (v) {
var __t, __p = '', __e = _.escape;
__p += '<div class="fotorama__nav__frame fotorama__nav__frame--thumb" tabindex="0" role="button" data-gallery-role="nav-frame" data-nav-type="thumb" aria-label>\r\n <div class="fotorama__thumb">\r\n </div>\r\n</div>';
return __p
};
})(window, document, location, typeof jQuery !== 'undefined' && jQuery);