fotoramajs 4.6.2 → 4.6.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3707 +1,2 @@
1
- /*!
2
- * Fotorama 4.6.2 | http://fotorama.io/license/
3
- */
4
- fotoramaVersion = '4.6.2';
5
- (function (window, document, location, $, undefined) {
6
- "use strict";
7
- var _fotoramaClass = 'fotorama',
8
- _fullscreenClass = 'fullscreen',
9
-
10
- wrapClass = _fotoramaClass + '__wrap',
11
- wrapCss2Class = wrapClass + '--css2',
12
- wrapCss3Class = wrapClass + '--css3',
13
- wrapVideoClass = wrapClass + '--video',
14
- wrapFadeClass = wrapClass + '--fade',
15
- wrapSlideClass = wrapClass + '--slide',
16
- wrapNoControlsClass = wrapClass + '--no-controls',
17
- wrapNoShadowsClass = wrapClass + '--no-shadows',
18
- wrapPanYClass = wrapClass + '--pan-y',
19
- wrapRtlClass = wrapClass + '--rtl',
20
- wrapOnlyActiveClass = wrapClass + '--only-active',
21
- wrapNoCaptionsClass = wrapClass + '--no-captions',
22
- wrapToggleArrowsClass = wrapClass + '--toggle-arrows',
23
-
24
- stageClass = _fotoramaClass + '__stage',
25
- stageFrameClass = stageClass + '__frame',
26
- stageFrameVideoClass = stageFrameClass + '--video',
27
- stageShaftClass = stageClass + '__shaft',
28
-
29
- grabClass = _fotoramaClass + '__grab',
30
- pointerClass = _fotoramaClass + '__pointer',
31
-
32
- arrClass = _fotoramaClass + '__arr',
33
- arrDisabledClass = arrClass + '--disabled',
34
- arrPrevClass = arrClass + '--prev',
35
- arrNextClass = arrClass + '--next',
36
- arrArrClass = arrClass + '__arr',
37
-
38
- navClass = _fotoramaClass + '__nav',
39
- navWrapClass = navClass + '-wrap',
40
- navShaftClass = navClass + '__shaft',
41
- navDotsClass = navClass + '--dots',
42
- navThumbsClass = navClass + '--thumbs',
43
- navFrameClass = navClass + '__frame',
44
- navFrameDotClass = navFrameClass + '--dot',
45
- navFrameThumbClass = navFrameClass + '--thumb',
46
-
47
- fadeClass = _fotoramaClass + '__fade',
48
- fadeFrontClass = fadeClass + '-front',
49
- fadeRearClass = fadeClass + '-rear',
50
-
51
- shadowClass = _fotoramaClass + '__shadow',
52
- shadowsClass = shadowClass + 's',
53
- shadowsLeftClass = shadowsClass + '--left',
54
- shadowsRightClass = shadowsClass + '--right',
55
-
56
- activeClass = _fotoramaClass + '__active',
57
- selectClass = _fotoramaClass + '__select',
58
-
59
- hiddenClass = _fotoramaClass + '--hidden',
60
-
61
- fullscreenClass = _fotoramaClass + '--fullscreen',
62
- fullscreenIconClass = _fotoramaClass + '__fullscreen-icon',
63
-
64
- errorClass = _fotoramaClass + '__error',
65
- loadingClass = _fotoramaClass + '__loading',
66
- loadedClass = _fotoramaClass + '__loaded',
67
- loadedFullClass = loadedClass + '--full',
68
- loadedImgClass = loadedClass + '--img',
69
-
70
- grabbingClass = _fotoramaClass + '__grabbing',
71
-
72
- imgClass = _fotoramaClass + '__img',
73
- imgFullClass = imgClass + '--full',
74
-
75
- dotClass = _fotoramaClass + '__dot',
76
- thumbClass = _fotoramaClass + '__thumb',
77
- thumbBorderClass = thumbClass + '-border',
78
-
79
- htmlClass = _fotoramaClass + '__html',
80
-
81
- videoClass = _fotoramaClass + '__video',
82
- videoPlayClass = videoClass + '-play',
83
- videoCloseClass = videoClass + '-close',
84
-
85
- captionClass = _fotoramaClass + '__caption',
86
- captionWrapClass = _fotoramaClass + '__caption__wrap',
87
-
88
- spinnerClass = _fotoramaClass + '__spinner',
89
-
90
- buttonAttributes = '" tabindex="0" role="button';
91
- var JQUERY_VERSION = $ && $.fn.jquery.split('.');
92
-
93
- if (!JQUERY_VERSION
94
- || JQUERY_VERSION[0] < 1
95
- || (JQUERY_VERSION[0] == 1 && JQUERY_VERSION[1] < 8)) {
96
- throw 'Fotorama requires jQuery 1.8 or later and will not run without it.';
97
- }
98
- // My Underscore :-)
99
- var _ = {};
100
- /* Modernizr 2.6.2 (Custom Build) | MIT & BSD
101
- * Build: http://modernizr.com/download/#-csstransforms3d-prefixed-teststyles-testprop-testallprops-prefixes-domprefixes
102
- */
103
-
104
- var Modernizr = (function (window, document, undefined) {
105
-
106
- var version = '2.6.2',
107
-
108
- Modernizr = {},
109
-
110
- docElement = document.documentElement,
111
-
112
- mod = 'modernizr',
113
- modElem = document.createElement(mod),
114
- mStyle = modElem.style,
115
-
116
- inputElem,
117
-
118
- toString = {}.toString,
119
-
120
- prefixes = ' -webkit- -moz- -o- -ms- '.split(' '),
121
-
122
- omPrefixes = 'Webkit Moz O ms',
123
-
124
- cssomPrefixes = omPrefixes.split(' '),
125
-
126
- domPrefixes = omPrefixes.toLowerCase().split(' '),
127
-
128
- tests = {},
129
- inputs = {},
130
- attrs = {},
131
-
132
- classes = [],
133
-
134
- slice = classes.slice,
135
-
136
- featureName,
137
-
138
- injectElementWithStyles = function (rule, callback, nodes, testnames) {
139
-
140
- var style, ret, node, docOverflow,
141
- div = document.createElement('div'),
142
- body = document.body,
143
- fakeBody = body || document.createElement('body');
144
-
145
- if (parseInt(nodes, 10)) {
146
- while (nodes--) {
147
- node = document.createElement('div');
148
- node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
149
- div.appendChild(node);
150
- }
151
- }
152
-
153
- style = ['&#173;', '<style id="s', mod, '">', rule, '</style>'].join('');
154
- div.id = mod;
155
- (body ? div : fakeBody).innerHTML += style;
156
- fakeBody.appendChild(div);
157
- if (!body) {
158
- fakeBody.style.background = '';
159
- fakeBody.style.overflow = 'hidden';
160
- docOverflow = docElement.style.overflow;
161
- docElement.style.overflow = 'hidden';
162
- docElement.appendChild(fakeBody);
163
- }
164
-
165
- ret = callback(div, rule);
166
- if (!body) {
167
- fakeBody.parentNode.removeChild(fakeBody);
168
- docElement.style.overflow = docOverflow;
169
- } else {
170
- div.parentNode.removeChild(div);
171
- }
172
-
173
- return !!ret;
174
-
175
- },
176
- _hasOwnProperty = ({}).hasOwnProperty, hasOwnProp;
177
-
178
- if (!is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined')) {
179
- hasOwnProp = function (object, property) {
180
- return _hasOwnProperty.call(object, property);
181
- };
182
- }
183
- else {
184
- hasOwnProp = function (object, property) {
185
- return ((property in object) && is(object.constructor.prototype[property], 'undefined'));
186
- };
187
- }
188
-
189
-
190
- if (!Function.prototype.bind) {
191
- Function.prototype.bind = function bind (that) {
192
-
193
- var target = this;
194
-
195
- if (typeof target != "function") {
196
- throw new TypeError();
197
- }
198
-
199
- var args = slice.call(arguments, 1),
200
- bound = function () {
201
-
202
- if (this instanceof bound) {
203
-
204
- var F = function () {
205
- };
206
- F.prototype = target.prototype;
207
- var self = new F();
208
-
209
- var result = target.apply(
210
- self,
211
- args.concat(slice.call(arguments))
212
- );
213
- if (Object(result) === result) {
214
- return result;
215
- }
216
- return self;
217
-
218
- } else {
219
-
220
- return target.apply(
221
- that,
222
- args.concat(slice.call(arguments))
223
- );
224
-
225
- }
226
-
227
- };
228
-
229
- return bound;
230
- };
231
- }
232
-
233
- function setCss (str) {
234
- mStyle.cssText = str;
235
- }
236
-
237
- function setCssAll (str1, str2) {
238
- return setCss(prefixes.join(str1 + ';') + ( str2 || '' ));
239
- }
240
-
241
- function is (obj, type) {
242
- return typeof obj === type;
243
- }
244
-
245
- function contains (str, substr) {
246
- return !!~('' + str).indexOf(substr);
247
- }
248
-
249
- function testProps (props, prefixed) {
250
- for (var i in props) {
251
- var prop = props[i];
252
- if (!contains(prop, "-") && mStyle[prop] !== undefined) {
253
- return prefixed == 'pfx' ? prop : true;
254
- }
255
- }
256
- return false;
257
- }
258
-
259
- function testDOMProps (props, obj, elem) {
260
- for (var i in props) {
261
- var item = obj[props[i]];
262
- if (item !== undefined) {
263
-
264
- if (elem === false) return props[i];
265
-
266
- if (is(item, 'function')) {
267
- return item.bind(elem || obj);
268
- }
269
-
270
- return item;
271
- }
272
- }
273
- return false;
274
- }
275
-
276
- function testPropsAll (prop, prefixed, elem) {
277
-
278
- var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
279
- props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');
280
-
281
- if (is(prefixed, "string") || is(prefixed, "undefined")) {
282
- return testProps(props, prefixed);
283
-
284
- } else {
285
- props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
286
- return testDOMProps(props, prefixed, elem);
287
- }
288
- }
289
-
290
- tests['csstransforms3d'] = function () {
291
-
292
- var ret = !!testPropsAll('perspective');
293
-
294
- // Chrome fails that test, ignore
295
- // if (ret && 'webkitPerspective' in docElement.style) {
296
- //
297
- // injectElementWithStyles('@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}', function (node, rule) {
298
- // ret = node.offsetLeft === 9 && node.offsetHeight === 3;
299
- // });
300
- // }
301
- return ret;
302
- };
303
-
304
- for (var feature in tests) {
305
- if (hasOwnProp(tests, feature)) {
306
- featureName = feature.toLowerCase();
307
- Modernizr[featureName] = tests[feature]();
308
-
309
- classes.push((Modernizr[featureName] ? '' : 'no-') + featureName);
310
- }
311
- }
312
-
313
- Modernizr.addTest = function (feature, test) {
314
- if (typeof feature == 'object') {
315
- for (var key in feature) {
316
- if (hasOwnProp(feature, key)) {
317
- Modernizr.addTest(key, feature[ key ]);
318
- }
319
- }
320
- } else {
321
-
322
- feature = feature.toLowerCase();
323
-
324
- if (Modernizr[feature] !== undefined) {
325
- return Modernizr;
326
- }
327
-
328
- test = typeof test == 'function' ? test() : test;
329
-
330
- if (typeof enableClasses !== "undefined" && enableClasses) {
331
- docElement.className += ' ' + (test ? '' : 'no-') + feature;
332
- }
333
- Modernizr[feature] = test;
334
-
335
- }
336
-
337
- return Modernizr;
338
- };
339
-
340
-
341
- setCss('');
342
- modElem = inputElem = null;
343
-
344
-
345
- Modernizr._version = version;
346
-
347
- Modernizr._prefixes = prefixes;
348
- Modernizr._domPrefixes = domPrefixes;
349
- Modernizr._cssomPrefixes = cssomPrefixes;
350
-
351
- Modernizr.testProp = function (prop) {
352
- return testProps([prop]);
353
- };
354
-
355
- Modernizr.testAllProps = testPropsAll;
356
-
357
- Modernizr.testStyles = injectElementWithStyles;
358
- Modernizr.prefixed = function (prop, obj, elem) {
359
- if (!obj) {
360
- return testPropsAll(prop, 'pfx');
361
- } else {
362
- return testPropsAll(prop, obj, elem);
363
- }
364
- };
365
-
366
- return Modernizr;
367
- })(window, document);
368
- var fullScreenApi = {
369
- ok: false,
370
- is: function () {
371
- return false;
372
- },
373
- request: function () {
374
- },
375
- cancel: function () {
376
- },
377
- event: '',
378
- prefix: ''
379
- },
380
- browserPrefixes = 'webkit moz o ms khtml'.split(' ');
381
-
382
- // check for native support
383
- if (typeof document.cancelFullScreen != 'undefined') {
384
- fullScreenApi.ok = true;
385
- } else {
386
- // check for fullscreen support by vendor prefix
387
- for (var i = 0, il = browserPrefixes.length; i < il; i++) {
388
- fullScreenApi.prefix = browserPrefixes[i];
389
- if (typeof document[fullScreenApi.prefix + 'CancelFullScreen' ] != 'undefined') {
390
- fullScreenApi.ok = true;
391
- break;
392
- }
393
- }
394
- }
395
-
396
- // update methods to do something useful
397
- if (fullScreenApi.ok) {
398
- fullScreenApi.event = fullScreenApi.prefix + 'fullscreenchange';
399
- fullScreenApi.is = function () {
400
- switch (this.prefix) {
401
- case '':
402
- return document.fullScreen;
403
- case 'webkit':
404
- return document.webkitIsFullScreen;
405
- default:
406
- return document[this.prefix + 'FullScreen'];
407
- }
408
- };
409
- fullScreenApi.request = function (el) {
410
- return (this.prefix === '') ? el.requestFullScreen() : el[this.prefix + 'RequestFullScreen']();
411
- };
412
- fullScreenApi.cancel = function (el) {
413
- return (this.prefix === '') ? document.cancelFullScreen() : document[this.prefix + 'CancelFullScreen']();
414
- };
415
- }
416
- //fgnass.github.com/spin.js#v1.3.2
417
-
418
- /**
419
- * Copyright (c) 2011-2013 Felix Gnass
420
- * Licensed under the MIT license
421
- */
422
-
423
- var Spinner,
424
- spinnerDefaults = {
425
- lines: 12, // The number of lines to draw
426
- length: 5, // The length of each line
427
- width: 2, // The line thickness
428
- radius: 7, // The radius of the inner circle
429
- corners: 1, // Corner roundness (0..1)
430
- rotate: 15, // The rotation offset
431
- color: 'rgba(128, 128, 128, .75)',
432
- hwaccel: true
433
- },
434
- spinnerOverride = {
435
- top: 'auto',
436
- left: 'auto',
437
- className: ''
438
- };
439
-
440
- (function(root, factory) {
441
-
442
- /* CommonJS */
443
- //if (typeof exports == 'object') module.exports = factory()
444
-
445
- /* AMD module */
446
- //else if (typeof define == 'function' && define.amd) define(factory)
447
-
448
- /* Browser global */
449
- //else root.Spinner = factory()
450
-
451
- Spinner = factory();
452
- }
453
- (this, function() {
454
- "use strict";
455
-
456
- var prefixes = ['webkit', 'Moz', 'ms', 'O'] /* Vendor prefixes */
457
- , animations = {} /* Animation rules keyed by their name */
458
- , useCssAnimations /* Whether to use CSS animations or setTimeout */
459
-
460
- /**
461
- * Utility function to create elements. If no tag name is given,
462
- * a DIV is created. Optionally properties can be passed.
463
- */
464
- function createEl(tag, prop) {
465
- var el = document.createElement(tag || 'div')
466
- , n
467
-
468
- for(n in prop) el[n] = prop[n]
469
- return el
470
- }
471
-
472
- /**
473
- * Appends children and returns the parent.
474
- */
475
- function ins(parent /* child1, child2, ...*/) {
476
- for (var i=1, n=arguments.length; i<n; i++)
477
- parent.appendChild(arguments[i])
478
-
479
- return parent
480
- }
481
-
482
- /**
483
- * Insert a new stylesheet to hold the @keyframe or VML rules.
484
- */
485
- var sheet = (function() {
486
- var el = createEl('style', {type : 'text/css'})
487
- ins(document.getElementsByTagName('head')[0], el)
488
- return el.sheet || el.styleSheet
489
- }())
490
-
491
- /**
492
- * Creates an opacity keyframe animation rule and returns its name.
493
- * Since most mobile Webkits have timing issues with animation-delay,
494
- * we create separate rules for each line/segment.
495
- */
496
- function addAnimation(alpha, trail, i, lines) {
497
- var name = ['opacity', trail, ~~(alpha*100), i, lines].join('-')
498
- , start = 0.01 + i/lines * 100
499
- , z = Math.max(1 - (1-alpha) / trail * (100-start), alpha)
500
- , prefix = useCssAnimations.substring(0, useCssAnimations.indexOf('Animation')).toLowerCase()
501
- , pre = prefix && '-' + prefix + '-' || ''
502
-
503
- if (!animations[name]) {
504
- sheet.insertRule(
505
- '@' + pre + 'keyframes ' + name + '{' +
506
- '0%{opacity:' + z + '}' +
507
- start + '%{opacity:' + alpha + '}' +
508
- (start+0.01) + '%{opacity:1}' +
509
- (start+trail) % 100 + '%{opacity:' + alpha + '}' +
510
- '100%{opacity:' + z + '}' +
511
- '}', sheet.cssRules.length)
512
-
513
- animations[name] = 1
514
- }
515
-
516
- return name
517
- }
518
-
519
- /**
520
- * Tries various vendor prefixes and returns the first supported property.
521
- */
522
- function vendor(el, prop) {
523
- var s = el.style
524
- , pp
525
- , i
526
-
527
- prop = prop.charAt(0).toUpperCase() + prop.slice(1)
528
- for(i=0; i<prefixes.length; i++) {
529
- pp = prefixes[i]+prop
530
- if(s[pp] !== undefined) return pp
531
- }
532
- if(s[prop] !== undefined) return prop
533
- }
534
-
535
- /**
536
- * Sets multiple style properties at once.
537
- */
538
- function css(el, prop) {
539
- for (var n in prop)
540
- el.style[vendor(el, n)||n] = prop[n]
541
-
542
- return el
543
- }
544
-
545
- /**
546
- * Fills in default values.
547
- */
548
- function merge(obj) {
549
- for (var i=1; i < arguments.length; i++) {
550
- var def = arguments[i]
551
- for (var n in def)
552
- if (obj[n] === undefined) obj[n] = def[n]
553
- }
554
- return obj
555
- }
556
-
557
- /**
558
- * Returns the absolute page-offset of the given element.
559
- */
560
- function pos(el) {
561
- var o = { x:el.offsetLeft, y:el.offsetTop }
562
- while((el = el.offsetParent))
563
- o.x+=el.offsetLeft, o.y+=el.offsetTop
564
-
565
- return o
566
- }
567
-
568
- /**
569
- * Returns the line color from the given string or array.
570
- */
571
- function getColor(color, idx) {
572
- return typeof color == 'string' ? color : color[idx % color.length]
573
- }
574
-
575
- // Built-in defaults
576
-
577
- var defaults = {
578
- lines: 12, // The number of lines to draw
579
- length: 7, // The length of each line
580
- width: 5, // The line thickness
581
- radius: 10, // The radius of the inner circle
582
- rotate: 0, // Rotation offset
583
- corners: 1, // Roundness (0..1)
584
- color: '#000', // #rgb or #rrggbb
585
- direction: 1, // 1: clockwise, -1: counterclockwise
586
- speed: 1, // Rounds per second
587
- trail: 100, // Afterglow percentage
588
- opacity: 1/4, // Opacity of the lines
589
- fps: 20, // Frames per second when using setTimeout()
590
- zIndex: 2e9, // Use a high z-index by default
591
- className: 'spinner', // CSS class to assign to the element
592
- top: 'auto', // center vertically
593
- left: 'auto', // center horizontally
594
- position: 'relative' // element position
595
- }
596
-
597
- /** The constructor */
598
- function Spinner(o) {
599
- if (typeof this == 'undefined') return new Spinner(o)
600
- this.opts = merge(o || {}, Spinner.defaults, defaults)
601
- }
602
-
603
- // Global defaults that override the built-ins:
604
- Spinner.defaults = {}
605
-
606
- merge(Spinner.prototype, {
607
-
608
- /**
609
- * Adds the spinner to the given target element. If this instance is already
610
- * spinning, it is automatically removed from its previous target b calling
611
- * stop() internally.
612
- */
613
- spin: function(target) {
614
- this.stop()
615
-
616
- var self = this
617
- , o = self.opts
618
- , el = self.el = css(createEl(0, {className: o.className}), {position: o.position, width: 0, zIndex: o.zIndex})
619
- , mid = o.radius+o.length+o.width
620
- , ep // element position
621
- , tp // target position
622
-
623
- if (target) {
624
- target.insertBefore(el, target.firstChild||null)
625
- tp = pos(target)
626
- ep = pos(el)
627
- css(el, {
628
- left: (o.left == 'auto' ? tp.x-ep.x + (target.offsetWidth >> 1) : parseInt(o.left, 10) + mid) + 'px',
629
- top: (o.top == 'auto' ? tp.y-ep.y + (target.offsetHeight >> 1) : parseInt(o.top, 10) + mid) + 'px'
630
- })
631
- }
632
-
633
- el.setAttribute('role', 'progressbar')
634
- self.lines(el, self.opts)
635
-
636
- if (!useCssAnimations) {
637
- // No CSS animation support, use setTimeout() instead
638
- var i = 0
639
- , start = (o.lines - 1) * (1 - o.direction) / 2
640
- , alpha
641
- , fps = o.fps
642
- , f = fps/o.speed
643
- , ostep = (1-o.opacity) / (f*o.trail / 100)
644
- , astep = f/o.lines
645
-
646
- ;(function anim() {
647
- i++;
648
- for (var j = 0; j < o.lines; j++) {
649
- alpha = Math.max(1 - (i + (o.lines - j) * astep) % f * ostep, o.opacity)
650
-
651
- self.opacity(el, j * o.direction + start, alpha, o)
652
- }
653
- self.timeout = self.el && setTimeout(anim, ~~(1000/fps))
654
- })()
655
- }
656
- return self
657
- },
658
-
659
- /**
660
- * Stops and removes the Spinner.
661
- */
662
- stop: function() {
663
- var el = this.el
664
- if (el) {
665
- clearTimeout(this.timeout)
666
- if (el.parentNode) el.parentNode.removeChild(el)
667
- this.el = undefined
668
- }
669
- return this
670
- },
671
-
672
- /**
673
- * Internal method that draws the individual lines. Will be overwritten
674
- * in VML fallback mode below.
675
- */
676
- lines: function(el, o) {
677
- var i = 0
678
- , start = (o.lines - 1) * (1 - o.direction) / 2
679
- , seg
680
-
681
- function fill(color, shadow) {
682
- return css(createEl(), {
683
- position: 'absolute',
684
- width: (o.length+o.width) + 'px',
685
- height: o.width + 'px',
686
- background: color,
687
- boxShadow: shadow,
688
- transformOrigin: 'left',
689
- transform: 'rotate(' + ~~(360/o.lines*i+o.rotate) + 'deg) translate(' + o.radius+'px' +',0)',
690
- borderRadius: (o.corners * o.width>>1) + 'px'
691
- })
692
- }
693
-
694
- for (; i < o.lines; i++) {
695
- seg = css(createEl(), {
696
- position: 'absolute',
697
- top: 1+~(o.width/2) + 'px',
698
- transform: o.hwaccel ? 'translate3d(0,0,0)' : '',
699
- opacity: o.opacity,
700
- animation: useCssAnimations && addAnimation(o.opacity, o.trail, start + i * o.direction, o.lines) + ' ' + 1/o.speed + 's linear infinite'
701
- })
702
-
703
- if (o.shadow) ins(seg, css(fill('#000', '0 0 4px ' + '#000'), {top: 2+'px'}))
704
- ins(el, ins(seg, fill(getColor(o.color, i), '0 0 1px rgba(0,0,0,.1)')))
705
- }
706
- return el
707
- },
708
-
709
- /**
710
- * Internal method that adjusts the opacity of a single line.
711
- * Will be overwritten in VML fallback mode below.
712
- */
713
- opacity: function(el, i, val) {
714
- if (i < el.childNodes.length) el.childNodes[i].style.opacity = val
715
- }
716
-
717
- })
718
-
719
-
720
- function initVML() {
721
-
722
- /* Utility function to create a VML tag */
723
- function vml(tag, attr) {
724
- return createEl('<' + tag + ' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">', attr)
725
- }
726
-
727
- // No CSS transforms but VML support, add a CSS rule for VML elements:
728
- sheet.addRule('.spin-vml', 'behavior:url(#default#VML)')
729
-
730
- Spinner.prototype.lines = function(el, o) {
731
- var r = o.length+o.width
732
- , s = 2*r
733
-
734
- function grp() {
735
- return css(
736
- vml('group', {
737
- coordsize: s + ' ' + s,
738
- coordorigin: -r + ' ' + -r
739
- }),
740
- { width: s, height: s }
741
- )
742
- }
743
-
744
- var margin = -(o.width+o.length)*2 + 'px'
745
- , g = css(grp(), {position: 'absolute', top: margin, left: margin})
746
- , i
747
-
748
- function seg(i, dx, filter) {
749
- ins(g,
750
- ins(css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}),
751
- ins(css(vml('roundrect', {arcsize: o.corners}), {
752
- width: r,
753
- height: o.width,
754
- left: o.radius,
755
- top: -o.width>>1,
756
- filter: filter
757
- }),
758
- vml('fill', {color: getColor(o.color, i), opacity: o.opacity}),
759
- vml('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change
760
- )
761
- )
762
- )
763
- }
764
-
765
- if (o.shadow)
766
- for (i = 1; i <= o.lines; i++)
767
- seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)')
768
-
769
- for (i = 1; i <= o.lines; i++) seg(i)
770
- return ins(el, g)
771
- }
772
-
773
- Spinner.prototype.opacity = function(el, i, val, o) {
774
- var c = el.firstChild
775
- o = o.shadow && o.lines || 0
776
- if (c && i+o < c.childNodes.length) {
777
- c = c.childNodes[i+o]; c = c && c.firstChild; c = c && c.firstChild
778
- if (c) c.opacity = val
779
- }
780
- }
781
- }
782
-
783
- var probe = css(createEl('group'), {behavior: 'url(#default#VML)'})
784
-
785
- if (!vendor(probe, 'transform') && probe.adj) initVML()
786
- else useCssAnimations = vendor(probe, 'animation')
787
-
788
- return Spinner
789
-
790
- }));
791
-
792
- /* Bez v1.0.10-g5ae0136
793
- * http://github.com/rdallasgray/bez
794
- *
795
- * A plugin to convert CSS3 cubic-bezier co-ordinates to jQuery-compatible easing functions
796
- *
797
- * With thanks to Nikolay Nemshilov for clarification on the cubic-bezier maths
798
- * See http://st-on-it.blogspot.com/2011/05/calculating-cubic-bezier-function.html
799
- *
800
- * Copyright 2011 Robert Dallas Gray. All rights reserved.
801
- * Provided under the FreeBSD license: https://github.com/rdallasgray/bez/blob/master/LICENSE.txt
802
- */
803
- function bez (coOrdArray) {
804
- var encodedFuncName = "bez_" + $.makeArray(arguments).join("_").replace(".", "p");
805
- if (typeof $['easing'][encodedFuncName] !== "function") {
806
- var polyBez = function (p1, p2) {
807
- var A = [null, null],
808
- B = [null, null],
809
- C = [null, null],
810
- bezCoOrd = function (t, ax) {
811
- C[ax] = 3 * p1[ax];
812
- B[ax] = 3 * (p2[ax] - p1[ax]) - C[ax];
813
- A[ax] = 1 - C[ax] - B[ax];
814
- return t * (C[ax] + t * (B[ax] + t * A[ax]));
815
- },
816
- xDeriv = function (t) {
817
- return C[0] + t * (2 * B[0] + 3 * A[0] * t);
818
- },
819
- xForT = function (t) {
820
- var x = t, i = 0, z;
821
- while (++i < 14) {
822
- z = bezCoOrd(x, 0) - t;
823
- if (Math.abs(z) < 1e-3) break;
824
- x -= z / xDeriv(x);
825
- }
826
- return x;
827
- };
828
- return function (t) {
829
- return bezCoOrd(xForT(t), 1);
830
- }
831
- };
832
- $['easing'][encodedFuncName] = function (x, t, b, c, d) {
833
- return c * polyBez([coOrdArray[0], coOrdArray[1]], [coOrdArray[2], coOrdArray[3]])(t / d) + b;
834
- }
835
- }
836
- return encodedFuncName;
837
- }
838
- var $WINDOW = $(window),
839
- $DOCUMENT = $(document),
840
- $HTML,
841
- $BODY,
842
-
843
- QUIRKS_FORCE = location.hash.replace('#', '') === 'quirks',
844
- TRANSFORMS3D = Modernizr.csstransforms3d,
845
- CSS3 = TRANSFORMS3D && !QUIRKS_FORCE,
846
- COMPAT = TRANSFORMS3D || document.compatMode === 'CSS1Compat',
847
- FULLSCREEN = fullScreenApi.ok,
848
-
849
- MOBILE = navigator.userAgent.match(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i),
850
- SLOW = !CSS3 || MOBILE,
851
-
852
- MS_POINTER = navigator.msPointerEnabled,
853
-
854
- WHEEL = "onwheel" in document.createElement("div") ? "wheel" : document.onmousewheel !== undefined ? "mousewheel" : "DOMMouseScroll",
855
-
856
- TOUCH_TIMEOUT = 250,
857
- TRANSITION_DURATION = 300,
858
-
859
- SCROLL_LOCK_TIMEOUT = 1400,
860
-
861
- AUTOPLAY_INTERVAL = 5000,
862
- MARGIN = 2,
863
- THUMB_SIZE = 64,
864
-
865
- WIDTH = 500,
866
- HEIGHT = 333,
867
-
868
- STAGE_FRAME_KEY = '$stageFrame',
869
- NAV_DOT_FRAME_KEY = '$navDotFrame',
870
- NAV_THUMB_FRAME_KEY = '$navThumbFrame',
871
-
872
- AUTO = 'auto',
873
-
874
- BEZIER = bez([.1, 0, .25, 1]),
875
-
876
- MAX_WIDTH = 99999,
877
-
878
- FIFTYFIFTY = '50%',
879
-
880
- OPTIONS = {
881
- // dimensions
882
- width: null, // 500 || '100%'
883
- minwidth: null,
884
- maxwidth: '100%', // '100%'
885
- height: null,
886
- minheight: null,
887
- maxheight: null,
888
-
889
- ratio: null, // '16/9' || 500/333 || 1.5
890
-
891
- margin: MARGIN,
892
- glimpse: 0,
893
-
894
- fit: 'contain', // 'cover' || 'scaledown' || 'none'
895
-
896
- position: FIFTYFIFTY,
897
- thumbposition: FIFTYFIFTY,
898
-
899
- // navigation, thumbs
900
- nav: 'dots', // 'thumbs' || false
901
- navposition: 'bottom', // 'top'
902
- navwidth: null,
903
- thumbwidth: THUMB_SIZE,
904
- thumbheight: THUMB_SIZE,
905
- thumbmargin: MARGIN,
906
- thumbborderwidth: MARGIN,
907
- thumbfit: 'cover', // 'contain' || 'scaledown' || 'none'
908
-
909
- allowfullscreen: false, // true || 'native'
910
-
911
- transition: 'slide', // 'crossfade' || 'dissolve'
912
- clicktransition: null,
913
- transitionduration: TRANSITION_DURATION,
914
-
915
- captions: true,
916
-
917
- hash: false,
918
- startindex: 0,
919
-
920
- loop: false,
921
-
922
- autoplay: false,
923
- stopautoplayontouch: true,
924
-
925
- keyboard: false,
926
-
927
- arrows: true,
928
- click: true,
929
- swipe: true,
930
- trackpad: false,
931
-
932
- enableifsingleframe: false,
933
-
934
- controlsonstart: true,
935
-
936
- shuffle: false,
937
-
938
- direction: 'ltr', // 'rtl'
939
-
940
- shadows: true,
941
- spinner: null
942
- },
943
-
944
- KEYBOARD_OPTIONS = {
945
- left: true,
946
- right: true,
947
- down: false,
948
- up: false,
949
- space: false,
950
- home: false,
951
- end: false
952
- };
953
- function noop () {}
954
-
955
- function minMaxLimit (value, min, max) {
956
- return Math.max(isNaN(min) ? -Infinity : min, Math.min(isNaN(max) ? Infinity : max, value));
957
- }
958
-
959
- function readTransform (css) {
960
- return css.match(/ma/) && css.match(/-?\d+(?!d)/g)[css.match(/3d/) ? 12 : 4];
961
- }
962
-
963
- function readPosition ($el) {
964
- if (CSS3) {
965
- return +readTransform($el.css('transform'));
966
- } else {
967
- return +$el.css('left').replace('px', '');
968
- }
969
- }
970
-
971
- function getTranslate (pos/*, _001*/) {
972
- var obj = {};
973
- if (CSS3) {
974
- obj.transform = 'translate3d(' + (pos/* + (_001 ? 0.001 : 0)*/) + 'px,0,0)'; // 0.001 to remove Retina artifacts
975
- } else {
976
- obj.left = pos;
977
- }
978
- return obj;
979
- }
980
-
981
- function getDuration (time) {
982
- return {'transition-duration': time + 'ms'};
983
- }
984
-
985
- function unlessNaN (value, alternative) {
986
- return isNaN(value) ? alternative : value;
987
- }
988
-
989
- function numberFromMeasure (value, measure) {
990
- return unlessNaN(+String(value).replace(measure || 'px', ''));
991
- }
992
-
993
- function numberFromPercent (value) {
994
- return /%$/.test(value) ? numberFromMeasure(value, '%') : undefined;
995
- }
996
-
997
- function numberFromWhatever (value, whole) {
998
- return unlessNaN(numberFromPercent(value) / 100 * whole, numberFromMeasure(value));
999
- }
1000
-
1001
- function measureIsValid (value) {
1002
- return (!isNaN(numberFromMeasure(value)) || !isNaN(numberFromMeasure(value, '%'))) && value;
1003
- }
1004
-
1005
- function getPosByIndex (index, side, margin, baseIndex) {
1006
- ////console.log('getPosByIndex', index, side, margin, baseIndex);
1007
- ////console.log((index - (baseIndex || 0)) * (side + (margin || 0)));
1008
-
1009
- return (index - (baseIndex || 0)) * (side + (margin || 0));
1010
- }
1011
-
1012
- function getIndexByPos (pos, side, margin, baseIndex) {
1013
- return -Math.round(pos / (side + (margin || 0)) - (baseIndex || 0));
1014
- }
1015
-
1016
- function bindTransitionEnd ($el) {
1017
- var elData = $el.data();
1018
-
1019
- if (elData.tEnd) return;
1020
-
1021
- var el = $el[0],
1022
- transitionEndEvent = {
1023
- WebkitTransition: 'webkitTransitionEnd',
1024
- MozTransition: 'transitionend',
1025
- OTransition: 'oTransitionEnd otransitionend',
1026
- msTransition: 'MSTransitionEnd',
1027
- transition: 'transitionend'
1028
- };
1029
- addEvent(el, transitionEndEvent[Modernizr.prefixed('transition')], function (e) {
1030
- elData.tProp && e.propertyName.match(elData.tProp) && elData.onEndFn();
1031
- });
1032
- elData.tEnd = true;
1033
- }
1034
-
1035
- function afterTransition ($el, property, fn, time) {
1036
- var ok,
1037
- elData = $el.data();
1038
-
1039
- if (elData) {
1040
- elData.onEndFn = function () {
1041
- if (ok) return;
1042
- ok = true;
1043
- clearTimeout(elData.tT);
1044
- fn();
1045
- };
1046
- elData.tProp = property;
1047
-
1048
- // Passive call, just in case of fail of native transition-end event
1049
- clearTimeout(elData.tT);
1050
- elData.tT = setTimeout(function () {
1051
- elData.onEndFn();
1052
- }, time * 1.5);
1053
-
1054
- bindTransitionEnd($el);
1055
- }
1056
- }
1057
-
1058
-
1059
- function stop ($el, left/*, _001*/) {
1060
- if ($el.length) {
1061
- var elData = $el.data();
1062
- if (CSS3) {
1063
- $el.css(getDuration(0));
1064
- elData.onEndFn = noop;
1065
- clearTimeout(elData.tT);
1066
- } else {
1067
- $el.stop();
1068
- }
1069
- var lockedLeft = getNumber(left, function () {
1070
- return readPosition($el);
1071
- });
1072
-
1073
- $el.css(getTranslate(lockedLeft/*, _001*/));//.width(); // `.width()` for reflow
1074
- return lockedLeft;
1075
- }
1076
- }
1077
-
1078
- function getNumber () {
1079
- var number;
1080
- for (var _i = 0, _l = arguments.length; _i < _l; _i++) {
1081
- number = _i ? arguments[_i]() : arguments[_i];
1082
- if (typeof number === 'number') {
1083
- break;
1084
- }
1085
- }
1086
-
1087
- return number;
1088
- }
1089
-
1090
- function edgeResistance (pos, edge) {
1091
- return Math.round(pos + ((edge - pos) / 1.5));
1092
- }
1093
-
1094
- function getProtocol () {
1095
- getProtocol.p = getProtocol.p || (location.protocol === 'https:' ? 'https://' : 'http://');
1096
- return getProtocol.p;
1097
- }
1098
-
1099
- function parseHref (href) {
1100
- var a = document.createElement('a');
1101
- a.href = href;
1102
- return a;
1103
- }
1104
-
1105
- function findVideoId (href, forceVideo) {
1106
- if (typeof href !== 'string') return href;
1107
- href = parseHref(href);
1108
-
1109
- var id,
1110
- type;
1111
-
1112
- if (href.host.match(/youtube\.com/) && href.search) {
1113
- //.log();
1114
- id = href.search.split('v=')[1];
1115
- if (id) {
1116
- var ampersandPosition = id.indexOf('&');
1117
- if (ampersandPosition !== -1) {
1118
- id = id.substring(0, ampersandPosition);
1119
- }
1120
- type = 'youtube';
1121
- }
1122
- } else if (href.host.match(/youtube\.com|youtu\.be/)) {
1123
- id = href.pathname.replace(/^\/(embed\/|v\/)?/, '').replace(/\/.*/, '');
1124
- type = 'youtube';
1125
- } else if (href.host.match(/vimeo\.com/)) {
1126
- type = 'vimeo';
1127
- id = href.pathname.replace(/^\/(video\/)?/, '').replace(/\/.*/, '');
1128
- }
1129
-
1130
- if ((!id || !type) && forceVideo) {
1131
- id = href.href;
1132
- type = 'custom';
1133
- }
1134
-
1135
- return id ? {id: id, type: type, s: href.search.replace(/^\?/, ''), p: getProtocol()} : false;
1136
- }
1137
-
1138
- function getVideoThumbs (dataFrame, data, fotorama) {
1139
- var img, thumb, video = dataFrame.video;
1140
- if (video.type === 'youtube') {
1141
- thumb = getProtocol() + 'img.youtube.com/vi/' + video.id + '/default.jpg';
1142
- img = thumb.replace(/\/default.jpg$/, '/hqdefault.jpg');
1143
- dataFrame.thumbsReady = true;
1144
- } else if (video.type === 'vimeo') {
1145
- $.ajax({
1146
- url: getProtocol() + 'vimeo.com/api/v2/video/' + video.id + '.json',
1147
- dataType: 'jsonp',
1148
- success: function (json) {
1149
- dataFrame.thumbsReady = true;
1150
- updateData(data, {img: json[0].thumbnail_large, thumb: json[0].thumbnail_small}, dataFrame.i, fotorama);
1151
- }
1152
- });
1153
- } else {
1154
- dataFrame.thumbsReady = true;
1155
- }
1156
-
1157
- return {
1158
- img: img,
1159
- thumb: thumb
1160
- }
1161
- }
1162
-
1163
- function updateData (data, _dataFrame, i, fotorama) {
1164
- for (var _i = 0, _l = data.length; _i < _l; _i++) {
1165
- var dataFrame = data[_i];
1166
-
1167
- if (dataFrame.i === i && dataFrame.thumbsReady) {
1168
- var clear = {videoReady: true};
1169
- clear[STAGE_FRAME_KEY] = clear[NAV_THUMB_FRAME_KEY] = clear[NAV_DOT_FRAME_KEY] = false;
1170
-
1171
- fotorama.splice(_i, 1, $.extend(
1172
- {},
1173
- dataFrame,
1174
- clear,
1175
- _dataFrame
1176
- ));
1177
-
1178
- break;
1179
- }
1180
- }
1181
- }
1182
-
1183
- function getDataFromHtml ($el) {
1184
- var data = [];
1185
-
1186
- function getDataFromImg ($img, imgData, checkVideo) {
1187
- var $child = $img.children('img').eq(0),
1188
- _imgHref = $img.attr('href'),
1189
- _imgSrc = $img.attr('src'),
1190
- _thumbSrc = $child.attr('src'),
1191
- _video = imgData.video,
1192
- video = checkVideo ? findVideoId(_imgHref, _video === true) : false;
1193
-
1194
- if (video) {
1195
- _imgHref = false;
1196
- } else {
1197
- video = _video;
1198
- }
1199
-
1200
- getDimensions($img, $child, $.extend(imgData, {
1201
- video: video,
1202
- img: imgData.img || _imgHref || _imgSrc || _thumbSrc,
1203
- thumb: imgData.thumb || _thumbSrc || _imgSrc || _imgHref
1204
- }));
1205
- }
1206
-
1207
- function getDimensions ($img, $child, imgData) {
1208
- var separateThumbFLAG = imgData.thumb && imgData.img !== imgData.thumb,
1209
- width = numberFromMeasure(imgData.width || $img.attr('width')),
1210
- height = numberFromMeasure(imgData.height || $img.attr('height'));
1211
-
1212
- $.extend(imgData, {
1213
- width: width,
1214
- height: height,
1215
- thumbratio: getRatio(imgData.thumbratio || (numberFromMeasure(imgData.thumbwidth || ($child && $child.attr('width')) || separateThumbFLAG || width) / numberFromMeasure(imgData.thumbheight || ($child && $child.attr('height')) || separateThumbFLAG || height)))
1216
- });
1217
- }
1218
-
1219
- $el.children().each(function () {
1220
- var $this = $(this),
1221
- dataFrame = optionsToLowerCase($.extend($this.data(), {id: $this.attr('id')}));
1222
- if ($this.is('a, img')) {
1223
- getDataFromImg($this, dataFrame, true);
1224
- } else if (!$this.is(':empty')) {
1225
- getDimensions($this, null, $.extend(dataFrame, {
1226
- html: this,
1227
- _html: $this.html() // Because of IE
1228
- }));
1229
- } else return;
1230
-
1231
- data.push(dataFrame);
1232
- });
1233
-
1234
- return data;
1235
- }
1236
-
1237
- function isHidden (el) {
1238
- return el.offsetWidth === 0 && el.offsetHeight === 0;
1239
- }
1240
-
1241
- function isDetached (el) {
1242
- return !$.contains(document.documentElement, el);
1243
- }
1244
-
1245
- function waitFor (test, fn, timeout, i) {
1246
- if (!waitFor.i) {
1247
- waitFor.i = 1;
1248
- waitFor.ii = [true];
1249
- }
1250
-
1251
- i = i || waitFor.i;
1252
-
1253
- if (typeof waitFor.ii[i] === 'undefined') {
1254
- waitFor.ii[i] = true;
1255
- }
1256
-
1257
- if (test()) {
1258
- fn();
1259
- } else {
1260
- waitFor.ii[i] && setTimeout(function () {
1261
- waitFor.ii[i] && waitFor(test, fn, timeout, i);
1262
- }, timeout || 100);
1263
- }
1264
-
1265
- return waitFor.i++;
1266
- }
1267
-
1268
- waitFor.stop = function (i) {
1269
- waitFor.ii[i] = false;
1270
- };
1271
-
1272
- function setHash (hash) {
1273
- //////console.time('setHash ' + hash);
1274
- location.replace(location.protocol
1275
- + '//'
1276
- + location.host
1277
- + location.pathname.replace(/^\/?/, '/')
1278
- + location.search
1279
- + '#' + hash);
1280
- //////console.timeEnd('setHash ' + hash);
1281
- }
1282
-
1283
- function fit ($el, measuresToFit, method, position) {
1284
- var elData = $el.data(),
1285
- measures = elData.measures;
1286
-
1287
- if (measures && (!elData.l ||
1288
- elData.l.W !== measures.width ||
1289
- elData.l.H !== measures.height ||
1290
- elData.l.r !== measures.ratio ||
1291
- elData.l.w !== measuresToFit.w ||
1292
- elData.l.h !== measuresToFit.h ||
1293
- elData.l.m !== method ||
1294
- elData.l.p !== position)) {
1295
-
1296
- //console.log('fit');
1297
-
1298
- var width = measures.width,
1299
- height = measures.height,
1300
- ratio = measuresToFit.w / measuresToFit.h,
1301
- biggerRatioFLAG = measures.ratio >= ratio,
1302
- fitFLAG = method === 'scaledown',
1303
- containFLAG = method === 'contain',
1304
- coverFLAG = method === 'cover',
1305
- pos = parsePosition(position);
1306
-
1307
- if (biggerRatioFLAG && (fitFLAG || containFLAG) || !biggerRatioFLAG && coverFLAG) {
1308
- width = minMaxLimit(measuresToFit.w, 0, fitFLAG ? width : Infinity);
1309
- height = width / measures.ratio;
1310
- } else if (biggerRatioFLAG && coverFLAG || !biggerRatioFLAG && (fitFLAG || containFLAG)) {
1311
- height = minMaxLimit(measuresToFit.h, 0, fitFLAG ? height : Infinity);
1312
- width = height * measures.ratio;
1313
- }
1314
-
1315
- $el.css({
1316
- width: Math.ceil(width),
1317
- height: Math.ceil(height),
1318
- left: Math.floor(numberFromWhatever(pos.x, measuresToFit.w - width)),
1319
- top: Math.floor(numberFromWhatever(pos.y, measuresToFit.h- height))
1320
- });
1321
-
1322
- elData.l = {
1323
- W: measures.width,
1324
- H: measures.height,
1325
- r: measures.ratio,
1326
- w: measuresToFit.w,
1327
- h: measuresToFit.h,
1328
- m: method,
1329
- p: position
1330
- };
1331
- }
1332
-
1333
- return true;
1334
- }
1335
-
1336
- function setStyle ($el, style) {
1337
- var el = $el[0];
1338
- if (el.styleSheet) {
1339
- el.styleSheet.cssText = style;
1340
- } else {
1341
- $el.html(style);
1342
- }
1343
- }
1344
-
1345
- function findShadowEdge (pos, min, max) {
1346
- return min === max ? false : pos <= min ? 'left' : pos >= max ? 'right' : 'left right';
1347
- }
1348
-
1349
- function getIndexFromHash (hash, data, ok, startindex) {
1350
- if (!ok) return false;
1351
- if (!isNaN(hash)) return hash - (startindex ? 0 : 1);
1352
-
1353
- var index;
1354
-
1355
- for (var _i = 0, _l = data.length; _i < _l; _i++) {
1356
- var dataFrame = data[_i];
1357
-
1358
- if (dataFrame.id === hash) {
1359
- index = _i;
1360
- break;
1361
- }
1362
- }
1363
-
1364
- return index;
1365
- }
1366
-
1367
- function smartClick ($el, fn, _options) {
1368
- _options = _options || {};
1369
-
1370
- $el.each(function () {
1371
- var $this = $(this),
1372
- thisData = $this.data(),
1373
- startEvent;
1374
-
1375
- if (thisData.clickOn) return;
1376
-
1377
- thisData.clickOn = true;
1378
-
1379
- $.extend(touch($this, {
1380
- onStart: function (e) {
1381
- startEvent = e;
1382
- (_options.onStart || noop).call(this, e);
1383
- },
1384
- onMove: _options.onMove || noop,
1385
- onTouchEnd: _options.onTouchEnd || noop,
1386
- onEnd: function (result) {
1387
- ////console.log('smartClick → result.moved', result.moved);
1388
- if (result.moved) return;
1389
- fn.call(this, startEvent);
1390
- }
1391
- }), {noMove: true});
1392
- });
1393
- }
1394
-
1395
- function div (classes, child) {
1396
- return '<div class="' + classes + '">' + (child || '') + '</div>';
1397
- }
1398
-
1399
- // Fisher–Yates Shuffle
1400
- // http://bost.ocks.org/mike/shuffle/
1401
- function shuffle (array) {
1402
- // While there remain elements to shuffle
1403
- var l = array.length;
1404
- while (l) {
1405
- // Pick a remaining element
1406
- var i = Math.floor(Math.random() * l--);
1407
-
1408
- // And swap it with the current element
1409
- var t = array[l];
1410
- array[l] = array[i];
1411
- array[i] = t;
1412
- }
1413
-
1414
- return array;
1415
- }
1416
-
1417
- function clone (array) {
1418
- return Object.prototype.toString.call(array) == '[object Array]'
1419
- && $.map(array, function (frame) {
1420
- return $.extend({}, frame);
1421
- });
1422
- }
1423
-
1424
- function lockScroll ($el, left, top) {
1425
- $el
1426
- .scrollLeft(left || 0)
1427
- .scrollTop(top || 0);
1428
- }
1429
-
1430
- function optionsToLowerCase (options) {
1431
- if (options) {
1432
- var opts = {};
1433
- $.each(options, function (key, value) {
1434
- opts[key.toLowerCase()] = value;
1435
- });
1436
-
1437
- return opts;
1438
- }
1439
- }
1440
-
1441
- function getRatio (_ratio) {
1442
- if (!_ratio) return;
1443
- var ratio = +_ratio;
1444
- if (!isNaN(ratio)) {
1445
- return ratio;
1446
- } else {
1447
- ratio = _ratio.split('/');
1448
- return +ratio[0] / +ratio[1] || undefined;
1449
- }
1450
- }
1451
-
1452
- function addEvent (el, e, fn, bool) {
1453
- if (!e) return;
1454
- el.addEventListener ? el.addEventListener(e, fn, !!bool) : el.attachEvent('on'+e, fn);
1455
- }
1456
-
1457
- function elIsDisabled (el) {
1458
- return !!el.getAttribute('disabled');
1459
- }
1460
-
1461
- function disableAttr (FLAG) {
1462
- return {tabindex: FLAG * -1 + '', disabled: FLAG};
1463
- }
1464
-
1465
- function addEnterUp (el, fn) {
1466
- addEvent(el, 'keyup', function (e) {
1467
- elIsDisabled(el) || e.keyCode == 13 && fn.call(el, e);
1468
- });
1469
- }
1470
-
1471
- function addFocus (el, fn) {
1472
- addEvent(el, 'focus', el.onfocusin = function (e) {
1473
- fn.call(el, e);
1474
- }, true);
1475
- }
1476
-
1477
- function stopEvent (e, stopPropagation) {
1478
- e.preventDefault ? e.preventDefault() : (e.returnValue = false);
1479
- stopPropagation && e.stopPropagation && e.stopPropagation();
1480
- }
1481
-
1482
- function getDirectionSign (forward) {
1483
- return forward ? '>' : '<';
1484
- }
1485
-
1486
- function parsePosition (rule) {
1487
- rule = (rule + '').split(/\s+/);
1488
- return {
1489
- x: measureIsValid(rule[0]) || FIFTYFIFTY,
1490
- y: measureIsValid(rule[1]) || FIFTYFIFTY
1491
- }
1492
- }
1493
- function slide ($el, options) {
1494
- var elData = $el.data(),
1495
- elPos = Math.round(options.pos),
1496
- onEndFn = function () {
1497
- elData.sliding = false;
1498
- (options.onEnd || noop)();
1499
- };
1500
-
1501
- if (typeof options.overPos !== 'undefined' && options.overPos !== options.pos) {
1502
- elPos = options.overPos;
1503
- onEndFn = function () {
1504
- slide($el, $.extend({}, options, {overPos: options.pos, time: Math.max(TRANSITION_DURATION, options.time / 2)}))
1505
- };
1506
- }
1507
-
1508
- ////////console.time('var translate = $.extend');
1509
- var translate = $.extend(getTranslate(elPos/*, options._001*/), options.width && {width: options.width});
1510
- ////////console.timeEnd('var translate = $.extend');
1511
-
1512
- elData.sliding = true;
1513
-
1514
- if (CSS3) {
1515
- $el.css($.extend(getDuration(options.time), translate));
1516
- if (options.time > 10) {
1517
- ////////console.time('afterTransition');
1518
- afterTransition($el, 'transform', onEndFn, options.time);
1519
- ////////console.timeEnd('afterTransition');
1520
- } else {
1521
- onEndFn();
1522
- }
1523
- } else {
1524
- $el.stop().animate(translate, options.time, BEZIER, onEndFn);
1525
- }
1526
- }
1527
-
1528
- function fade ($el1, $el2, $frames, options, fadeStack, chain) {
1529
- var chainedFLAG = typeof chain !== 'undefined';
1530
- if (!chainedFLAG) {
1531
- fadeStack.push(arguments);
1532
- Array.prototype.push.call(arguments, fadeStack.length);
1533
- if (fadeStack.length > 1) return;
1534
- }
1535
-
1536
- $el1 = $el1 || $($el1);
1537
- $el2 = $el2 || $($el2);
1538
-
1539
- var _$el1 = $el1[0],
1540
- _$el2 = $el2[0],
1541
- crossfadeFLAG = options.method === 'crossfade',
1542
- onEndFn = function () {
1543
- if (!onEndFn.done) {
1544
- onEndFn.done = true;
1545
- var args = (chainedFLAG || fadeStack.shift()) && fadeStack.shift();
1546
- args && fade.apply(this, args);
1547
- (options.onEnd || noop)(!!args);
1548
- }
1549
- },
1550
- time = options.time / (chain || 1);
1551
-
1552
- $frames.removeClass(fadeRearClass + ' ' + fadeFrontClass);
1553
-
1554
- $el1
1555
- .stop()
1556
- .addClass(fadeRearClass);
1557
- $el2
1558
- .stop()
1559
- .addClass(fadeFrontClass);
1560
-
1561
- crossfadeFLAG && _$el2 && $el1.fadeTo(0, 0);
1562
-
1563
- $el1.fadeTo(crossfadeFLAG ? time : 0, 1, crossfadeFLAG && onEndFn);
1564
- $el2.fadeTo(time, 0, onEndFn);
1565
-
1566
- (_$el1 && crossfadeFLAG) || _$el2 || onEndFn();
1567
- }
1568
- var lastEvent,
1569
- moveEventType,
1570
- preventEvent,
1571
- preventEventTimeout;
1572
-
1573
- function extendEvent (e) {
1574
- var touch = (e.touches || [])[0] || e;
1575
- e._x = touch.pageX;
1576
- e._y = touch.clientY;
1577
- e._now = $.now();
1578
- }
1579
-
1580
- function touch ($el, options) {
1581
- var el = $el[0],
1582
- tail = {},
1583
- touchEnabledFLAG,
1584
- startEvent,
1585
- $target,
1586
- controlTouch,
1587
- touchFLAG,
1588
- targetIsSelectFLAG,
1589
- targetIsLinkFlag,
1590
- tolerance,
1591
- moved;
1592
-
1593
- function onStart (e) {
1594
- $target = $(e.target);
1595
- tail.checked = targetIsSelectFLAG = targetIsLinkFlag = moved = false;
1596
-
1597
- if (touchEnabledFLAG
1598
- || tail.flow
1599
- || (e.touches && e.touches.length > 1)
1600
- || e.which > 1
1601
- || (lastEvent && lastEvent.type !== e.type && preventEvent)
1602
- || (targetIsSelectFLAG = options.select && $target.is(options.select, el))) return targetIsSelectFLAG;
1603
-
1604
- touchFLAG = e.type === 'touchstart';
1605
- targetIsLinkFlag = $target.is('a, a *', el);
1606
- controlTouch = tail.control;
1607
-
1608
- tolerance = (tail.noMove || tail.noSwipe || controlTouch) ? 16 : !tail.snap ? 4 : 0;
1609
-
1610
- extendEvent(e);
1611
-
1612
- startEvent = lastEvent = e;
1613
- moveEventType = e.type.replace(/down|start/, 'move').replace(/Down/, 'Move');
1614
-
1615
- (options.onStart || noop).call(el, e, {control: controlTouch, $target: $target});
1616
-
1617
- touchEnabledFLAG = tail.flow = true;
1618
-
1619
- if (!touchFLAG || tail.go) stopEvent(e);
1620
- }
1621
-
1622
- function onMove (e) {
1623
- if ((e.touches && e.touches.length > 1)
1624
- || (MS_POINTER && !e.isPrimary)
1625
- || moveEventType !== e.type
1626
- || !touchEnabledFLAG) {
1627
- touchEnabledFLAG && onEnd();
1628
- (options.onTouchEnd || noop)();
1629
- return;
1630
- }
1631
-
1632
- extendEvent(e);
1633
-
1634
- var xDiff = Math.abs(e._x - startEvent._x), // opt _x → _pageX
1635
- yDiff = Math.abs(e._y - startEvent._y),
1636
- xyDiff = xDiff - yDiff,
1637
- xWin = (tail.go || tail.x || xyDiff >= 0) && !tail.noSwipe,
1638
- yWin = xyDiff < 0;
1639
-
1640
- if (touchFLAG && !tail.checked) {
1641
- if (touchEnabledFLAG = xWin) {
1642
- stopEvent(e);
1643
- }
1644
- } else {
1645
- ////console.log('onMove e.preventDefault');
1646
- stopEvent(e);
1647
- (options.onMove || noop).call(el, e, {touch: touchFLAG});
1648
- }
1649
-
1650
- if (!moved && Math.sqrt(Math.pow(xDiff, 2) + Math.pow(yDiff, 2)) > tolerance) {
1651
- moved = true;
1652
- }
1653
-
1654
- tail.checked = tail.checked || xWin || yWin;
1655
- }
1656
-
1657
- function onEnd (e) {
1658
- //////console.time('touch.js onEnd');
1659
-
1660
- (options.onTouchEnd || noop)();
1661
-
1662
- var _touchEnabledFLAG = touchEnabledFLAG;
1663
- tail.control = touchEnabledFLAG = false;
1664
-
1665
- if (_touchEnabledFLAG) {
1666
- tail.flow = false;
1667
- }
1668
-
1669
- if (!_touchEnabledFLAG || (targetIsLinkFlag && !tail.checked)) return;
1670
-
1671
- e && stopEvent(e);
1672
-
1673
- preventEvent = true;
1674
- clearTimeout(preventEventTimeout);
1675
- preventEventTimeout = setTimeout(function () {
1676
- preventEvent = false;
1677
- }, 1000);
1678
-
1679
- (options.onEnd || noop).call(el, {moved: moved, $target: $target, control: controlTouch, touch: touchFLAG, startEvent: startEvent, aborted: !e || e.type === 'MSPointerCancel'});
1680
- //////console.timeEnd('touch.js onEnd');
1681
- }
1682
-
1683
- function onOtherStart () {
1684
- if (tail.flow) return;
1685
- setTimeout(function () {
1686
- tail.flow = true;
1687
- }, 10);
1688
- }
1689
-
1690
- function onOtherEnd () {
1691
- if (!tail.flow) return;
1692
- setTimeout(function () {
1693
- tail.flow = false;
1694
- }, TOUCH_TIMEOUT);
1695
- }
1696
-
1697
- if (MS_POINTER) {
1698
- addEvent(el, 'MSPointerDown', onStart);
1699
- addEvent(document, 'MSPointerMove', onMove);
1700
- addEvent(document,'MSPointerCancel', onEnd);
1701
- addEvent(document, 'MSPointerUp', onEnd);
1702
- } else {
1703
- addEvent(el, 'touchstart', onStart);
1704
- addEvent(el, 'touchmove', onMove);
1705
- addEvent(el, 'touchend', onEnd);
1706
-
1707
- addEvent(document, 'touchstart', onOtherStart);
1708
- addEvent(document, 'touchend', onOtherEnd);
1709
- addEvent(document, 'touchcancel', onOtherEnd);
1710
-
1711
- $WINDOW.on('scroll', onOtherEnd);
1712
-
1713
- $el.on('mousedown', onStart);
1714
- $DOCUMENT
1715
- .on('mousemove', onMove)
1716
- .on('mouseup', onEnd);
1717
- }
1718
-
1719
- $el.on('click', 'a', function (e) {
1720
- tail.checked && stopEvent(e);
1721
- });
1722
-
1723
- return tail;
1724
- }
1725
-
1726
- function moveOnTouch ($el, options) {
1727
- var el = $el[0],
1728
- elData = $el.data(),
1729
- tail = {},
1730
- startCoo,
1731
- coo,
1732
- startElPos,
1733
- moveElPos,
1734
- edge,
1735
- moveTrack,
1736
- startTime,
1737
- endTime,
1738
- min,
1739
- max,
1740
- snap,
1741
- slowFLAG,
1742
- controlFLAG,
1743
- moved,
1744
- tracked;
1745
-
1746
- function startTracking (e, noStop) {
1747
- tracked = true;
1748
- startCoo = coo = e._x;
1749
- startTime = e._now;
1750
-
1751
- moveTrack = [
1752
- [startTime, startCoo]
1753
- ];
1754
-
1755
- startElPos = moveElPos = tail.noMove || noStop ? 0 : stop($el, (options.getPos || noop)()/*, options._001*/);
1756
-
1757
- (options.onStart || noop).call(el, e);
1758
- }
1759
-
1760
- function onStart (e, result) {
1761
- min = tail.min;
1762
- max = tail.max;
1763
- snap = tail.snap;
1764
-
1765
- slowFLAG = e.altKey;
1766
- tracked = moved = false;
1767
-
1768
- controlFLAG = result.control;
1769
-
1770
- if (!controlFLAG && !elData.sliding) {
1771
- startTracking(e);
1772
- }
1773
- }
1774
-
1775
- function onMove (e, result) {
1776
- if (!tail.noSwipe) {
1777
- if (!tracked) {
1778
- startTracking(e);
1779
- }
1780
-
1781
- coo = e._x;
1782
-
1783
- moveTrack.push([e._now, coo]);
1784
-
1785
- moveElPos = startElPos - (startCoo - coo);
1786
-
1787
- edge = findShadowEdge(moveElPos, min, max);
1788
-
1789
- if (moveElPos <= min) {
1790
- moveElPos = edgeResistance(moveElPos, min);
1791
- } else if (moveElPos >= max) {
1792
- moveElPos = edgeResistance(moveElPos, max);
1793
- }
1794
-
1795
- if (!tail.noMove) {
1796
- $el.css(getTranslate(moveElPos/*, options._001*/));
1797
- if (!moved) {
1798
- moved = true;
1799
- // only for mouse
1800
- result.touch || MS_POINTER || $el.addClass(grabbingClass);
1801
- }
1802
-
1803
- (options.onMove || noop).call(el, e, {pos: moveElPos, edge: edge});
1804
- }
1805
- }
1806
- }
1807
-
1808
- function onEnd (result) {
1809
- //////console.time('moveontouch.js onEnd');
1810
- if (tail.noSwipe && result.moved) return;
1811
-
1812
- if (!tracked) {
1813
- startTracking(result.startEvent, true);
1814
- }
1815
-
1816
- ////console.log('onEnd');
1817
-
1818
- result.touch || MS_POINTER || $el.removeClass(grabbingClass);
1819
-
1820
- endTime = $.now();
1821
-
1822
- var _backTimeIdeal = endTime - TOUCH_TIMEOUT,
1823
- _backTime,
1824
- _timeDiff,
1825
- _timeDiffLast,
1826
- backTime = null,
1827
- backCoo,
1828
- virtualPos,
1829
- limitPos,
1830
- newPos,
1831
- overPos,
1832
- time = TRANSITION_DURATION,
1833
- speed,
1834
- friction = options.friction;
1835
-
1836
- for (var _i = moveTrack.length - 1; _i >= 0; _i--) {
1837
- _backTime = moveTrack[_i][0];
1838
- _timeDiff = Math.abs(_backTime - _backTimeIdeal);
1839
- if (backTime === null || _timeDiff < _timeDiffLast) {
1840
- backTime = _backTime;
1841
- backCoo = moveTrack[_i][1];
1842
- } else if (backTime === _backTimeIdeal || _timeDiff > _timeDiffLast) {
1843
- break;
1844
- }
1845
- _timeDiffLast = _timeDiff;
1846
- }
1847
-
1848
- newPos = minMaxLimit(moveElPos, min, max);
1849
-
1850
- var cooDiff = backCoo - coo,
1851
- forwardFLAG = cooDiff >= 0,
1852
- timeDiff = endTime - backTime,
1853
- longTouchFLAG = timeDiff > TOUCH_TIMEOUT,
1854
- swipeFLAG = !longTouchFLAG && moveElPos !== startElPos && newPos === moveElPos;
1855
-
1856
- if (snap) {
1857
- newPos = minMaxLimit(Math[swipeFLAG ? (forwardFLAG ? 'floor' : 'ceil') : 'round'](moveElPos / snap) * snap, min, max);
1858
- min = max = newPos;
1859
- }
1860
-
1861
- if (swipeFLAG && (snap || newPos === moveElPos)) {
1862
- speed = -(cooDiff / timeDiff);
1863
- time *= minMaxLimit(Math.abs(speed), options.timeLow, options.timeHigh);
1864
- virtualPos = Math.round(moveElPos + speed * time / friction);
1865
-
1866
- if (!snap) {
1867
- newPos = virtualPos;
1868
- }
1869
-
1870
- if (!forwardFLAG && virtualPos > max || forwardFLAG && virtualPos < min) {
1871
- limitPos = forwardFLAG ? min : max;
1872
- overPos = virtualPos - limitPos;
1873
- if (!snap) {
1874
- newPos = limitPos;
1875
- }
1876
- overPos = minMaxLimit(newPos + overPos * .03, limitPos - 50, limitPos + 50);
1877
- time = Math.abs((moveElPos - overPos) / (speed / friction));
1878
- }
1879
- }
1880
-
1881
- time *= slowFLAG ? 10 : 1;
1882
-
1883
- (options.onEnd || noop).call(el, $.extend(result, {moved: result.moved || longTouchFLAG && snap, pos: moveElPos, newPos: newPos, overPos: overPos, time: time}));
1884
- }
1885
-
1886
- tail = $.extend(touch(options.$wrap, $.extend({}, options, {
1887
- onStart: onStart,
1888
- onMove: onMove,
1889
- onEnd: onEnd
1890
- })), tail);
1891
-
1892
- return tail;
1893
- }
1894
- function wheel ($el, options) {
1895
- var el = $el[0],
1896
- lockFLAG,
1897
- lastDirection,
1898
- lastNow,
1899
- tail = {
1900
- prevent: {}
1901
- };
1902
-
1903
- addEvent(el, WHEEL, function (e) {
1904
- var yDelta = e.wheelDeltaY || -1 * e.deltaY || 0,
1905
- xDelta = e.wheelDeltaX || -1 * e.deltaX || 0,
1906
- xWin = Math.abs(xDelta) && !Math.abs(yDelta),
1907
- direction = getDirectionSign(xDelta < 0),
1908
- sameDirection = lastDirection === direction,
1909
- now = $.now(),
1910
- tooFast = now - lastNow < TOUCH_TIMEOUT;
1911
-
1912
- lastDirection = direction;
1913
- lastNow = now;
1914
-
1915
- if (!xWin || !tail.ok || tail.prevent[direction] && !lockFLAG) {
1916
- return;
1917
- } else {
1918
- stopEvent(e, true);
1919
- if (lockFLAG && sameDirection && tooFast) {
1920
- return;
1921
- }
1922
- }
1923
-
1924
- if (options.shift) {
1925
- lockFLAG = true;
1926
- clearTimeout(tail.t);
1927
- tail.t = setTimeout(function () {
1928
- lockFLAG = false;
1929
- }, SCROLL_LOCK_TIMEOUT);
1930
- }
1931
-
1932
- (options.onEnd || noop)(e, options.shift ? direction : xDelta);
1933
-
1934
- });
1935
-
1936
- return tail;
1937
- }
1938
- jQuery.Fotorama = function ($fotorama, opts) {
1939
- $HTML = $('html');
1940
- $BODY = $('body');
1941
-
1942
- var that = this,
1943
- stamp = $.now(),
1944
- stampClass = _fotoramaClass + stamp,
1945
- fotorama = $fotorama[0],
1946
- data,
1947
- dataFrameCount = 1,
1948
- fotoramaData = $fotorama.data(),
1949
- size,
1950
-
1951
- $style = $('<style></style>'),
1952
-
1953
- $anchor = $(div(hiddenClass)),
1954
- $wrap = $(div(wrapClass)),
1955
- $stage = $(div(stageClass)).appendTo($wrap),
1956
- stage = $stage[0],
1957
-
1958
- $stageShaft = $(div(stageShaftClass)).appendTo($stage),
1959
- $stageFrame = $(),
1960
- $arrPrev = $(div(arrClass + ' ' + arrPrevClass + buttonAttributes)),
1961
- $arrNext = $(div(arrClass + ' ' + arrNextClass + buttonAttributes)),
1962
- $arrs = $arrPrev.add($arrNext).appendTo($stage),
1963
- $navWrap = $(div(navWrapClass)),
1964
- $nav = $(div(navClass)).appendTo($navWrap),
1965
- $navShaft = $(div(navShaftClass)).appendTo($nav),
1966
- $navFrame,
1967
- $navDotFrame = $(),
1968
- $navThumbFrame = $(),
1969
-
1970
- stageShaftData = $stageShaft.data(),
1971
- navShaftData = $navShaft.data(),
1972
-
1973
- $thumbBorder = $(div(thumbBorderClass)).appendTo($navShaft),
1974
-
1975
- $fullscreenIcon = $(div(fullscreenIconClass + buttonAttributes)),
1976
- fullscreenIcon = $fullscreenIcon[0],
1977
- $videoPlay = $(div(videoPlayClass)),
1978
- $videoClose = $(div(videoCloseClass)).appendTo($stage),
1979
- videoClose = $videoClose[0],
1980
-
1981
- spinner,
1982
- $spinner = $(div(spinnerClass)),
1983
-
1984
- $videoPlaying,
1985
-
1986
- activeIndex = false,
1987
- activeFrame,
1988
- activeIndexes,
1989
- repositionIndex,
1990
- dirtyIndex,
1991
- lastActiveIndex,
1992
- prevIndex,
1993
- nextIndex,
1994
- nextAutoplayIndex,
1995
- startIndex,
1996
-
1997
- o_loop,
1998
- o_nav,
1999
- o_navThumbs,
2000
- o_navTop,
2001
- o_allowFullScreen,
2002
- o_nativeFullScreen,
2003
- o_fade,
2004
- o_thumbSide,
2005
- o_thumbSide2,
2006
- o_transitionDuration,
2007
- o_transition,
2008
- o_shadows,
2009
- o_rtl,
2010
- o_keyboard,
2011
- lastOptions = {},
2012
-
2013
- measures = {},
2014
- measuresSetFLAG,
2015
-
2016
- stageShaftTouchTail = {},
2017
- stageWheelTail = {},
2018
- navShaftTouchTail = {},
2019
- navWheelTail = {},
2020
-
2021
- scrollTop,
2022
- scrollLeft,
2023
-
2024
- showedFLAG,
2025
- pausedAutoplayFLAG,
2026
- stoppedAutoplayFLAG,
2027
-
2028
- toDeactivate = {},
2029
- toDetach = {},
2030
-
2031
- measuresStash,
2032
-
2033
- touchedFLAG,
2034
-
2035
- hoverFLAG,
2036
-
2037
- navFrameKey,
2038
- stageLeft = 0,
2039
-
2040
- fadeStack = [];
2041
-
2042
- $wrap[STAGE_FRAME_KEY] = $(div(stageFrameClass));
2043
- $wrap[NAV_THUMB_FRAME_KEY] = $(div(navFrameClass + ' ' + navFrameThumbClass + buttonAttributes, div(thumbClass)));
2044
- $wrap[NAV_DOT_FRAME_KEY] = $(div(navFrameClass + ' ' + navFrameDotClass + buttonAttributes, div(dotClass)));
2045
-
2046
- toDeactivate[STAGE_FRAME_KEY] = [];
2047
- toDeactivate[NAV_THUMB_FRAME_KEY] = [];
2048
- toDeactivate[NAV_DOT_FRAME_KEY] = [];
2049
- toDetach[STAGE_FRAME_KEY] = {};
2050
-
2051
- $wrap
2052
- .addClass(CSS3 ? wrapCss3Class : wrapCss2Class)
2053
- .toggleClass(wrapNoControlsClass, !opts.controlsonstart);
2054
-
2055
- fotoramaData.fotorama = this;
2056
-
2057
- function checkForVideo () {
2058
- $.each(data, function (i, dataFrame) {
2059
- if (!dataFrame.i) {
2060
- dataFrame.i = dataFrameCount++;
2061
- var video = findVideoId(dataFrame.video, true);
2062
- if (video) {
2063
- var thumbs = {};
2064
- dataFrame.video = video;
2065
- if (!dataFrame.img && !dataFrame.thumb) {
2066
- thumbs = getVideoThumbs(dataFrame, data, that);
2067
- } else {
2068
- dataFrame.thumbsReady = true;
2069
- }
2070
- updateData(data, {img: thumbs.img, thumb: thumbs.thumb}, dataFrame.i, that);
2071
- }
2072
- }
2073
- });
2074
- }
2075
-
2076
- function allowKey (key) {
2077
- return o_keyboard[key] || that.fullScreen;
2078
- }
2079
-
2080
- function bindGlobalEvents (FLAG) {
2081
- var keydownCommon = 'keydown.' + _fotoramaClass,
2082
- localStamp = _fotoramaClass + stamp,
2083
- keydownLocal = 'keydown.' + localStamp,
2084
- resizeLocal = 'resize.' + localStamp + ' ' + 'orientationchange.' + localStamp;
2085
-
2086
- if (FLAG) {
2087
- $DOCUMENT
2088
- .on(keydownLocal, function (e) {
2089
- var catched,
2090
- index;
2091
-
2092
- if ($videoPlaying && e.keyCode === 27) {
2093
- catched = true;
2094
- unloadVideo($videoPlaying, true, true);
2095
- } else if (that.fullScreen || (opts.keyboard && !that.index)) {
2096
- if (e.keyCode === 27) {
2097
- catched = true;
2098
- that.cancelFullScreen();
2099
- } else if ((e.shiftKey && e.keyCode === 32 && allowKey('space')) || (e.keyCode === 37 && allowKey('left')) || (e.keyCode === 38 && allowKey('up'))) {
2100
- index = '<';
2101
- } else if ((e.keyCode === 32 && allowKey('space')) || (e.keyCode === 39 && allowKey('right')) || (e.keyCode === 40 && allowKey('down'))) {
2102
- index = '>';
2103
- } else if (e.keyCode === 36 && allowKey('home')) {
2104
- index = '<<';
2105
- } else if (e.keyCode === 35 && allowKey('end')) {
2106
- index = '>>';
2107
- }
2108
- }
2109
-
2110
- (catched || index) && stopEvent(e);
2111
- index && that.show({index: index, slow: e.altKey, user: true});
2112
- });
2113
-
2114
- if (!that.index) {
2115
- $DOCUMENT
2116
- .off(keydownCommon)
2117
- .on(keydownCommon, 'textarea, input, select', function (e) {
2118
- !$BODY.hasClass(_fullscreenClass) && e.stopPropagation();
2119
- });
2120
- }
2121
-
2122
- $WINDOW.on(resizeLocal, that.resize);
2123
- } else {
2124
- $DOCUMENT.off(keydownLocal);
2125
- $WINDOW.off(resizeLocal);
2126
- }
2127
- }
2128
-
2129
- function appendElements (FLAG) {
2130
- if (FLAG === appendElements.f) return;
2131
-
2132
- if (FLAG) {
2133
- $fotorama
2134
- .html('')
2135
- .addClass(_fotoramaClass + ' ' + stampClass)
2136
- .append($wrap)
2137
- .before($style)
2138
- .before($anchor);
2139
-
2140
- addInstance(that);
2141
- } else {
2142
- $wrap.detach();
2143
- $style.detach();
2144
- $anchor.detach();
2145
- $fotorama
2146
- .html(fotoramaData.urtext)
2147
- .removeClass(stampClass);
2148
-
2149
- hideInstance(that);
2150
- }
2151
-
2152
- bindGlobalEvents(FLAG);
2153
- appendElements.f = FLAG;
2154
- }
2155
-
2156
- function setData () {
2157
- data = that.data = data || clone(opts.data) || getDataFromHtml($fotorama);
2158
- size = that.size = data.length;
2159
-
2160
- !ready.ok && opts.shuffle && shuffle(data);
2161
-
2162
- checkForVideo();
2163
-
2164
- activeIndex = limitIndex(activeIndex);
2165
-
2166
- size && appendElements(true);
2167
- }
2168
-
2169
- function stageNoMove () {
2170
- var _noMove = (size < 2 && !opts.enableifsingleframe) || $videoPlaying;
2171
- stageShaftTouchTail.noMove = _noMove || o_fade;
2172
- stageShaftTouchTail.noSwipe = _noMove || !opts.swipe;
2173
-
2174
- !o_transition && $stageShaft.toggleClass(grabClass, !opts.click && !stageShaftTouchTail.noMove && !stageShaftTouchTail.noSwipe);
2175
- MS_POINTER && $wrap.toggleClass(wrapPanYClass, !stageShaftTouchTail.noSwipe);
2176
- }
2177
-
2178
- function setAutoplayInterval (interval) {
2179
- if (interval === true) interval = '';
2180
- opts.autoplay = Math.max(+interval || AUTOPLAY_INTERVAL, o_transitionDuration * 1.5);
2181
- }
2182
-
2183
- /**
2184
- * Options on the fly
2185
- * */
2186
- function setOptions () {
2187
- that.options = opts = optionsToLowerCase(opts);
2188
-
2189
- o_fade = (opts.transition === 'crossfade' || opts.transition === 'dissolve');
2190
-
2191
- o_loop = opts.loop && (size > 2 || (o_fade && (!o_transition || o_transition !== 'slide')));
2192
-
2193
- o_transitionDuration = +opts.transitionduration || TRANSITION_DURATION;
2194
-
2195
- o_rtl = opts.direction === 'rtl';
2196
-
2197
- o_keyboard = $.extend({}, opts.keyboard && KEYBOARD_OPTIONS, opts.keyboard);
2198
-
2199
- var classes = {add: [], remove: []};
2200
-
2201
- function addOrRemoveClass (FLAG, value) {
2202
- classes[FLAG ? 'add' : 'remove'].push(value);
2203
- }
2204
-
2205
- if (size > 1 || opts.enableifsingleframe) {
2206
- o_nav = opts.nav;
2207
- o_navTop = opts.navposition === 'top';
2208
- classes.remove.push(selectClass);
2209
-
2210
- $arrs.toggle(!!opts.arrows);
2211
- } else {
2212
- o_nav = false;
2213
- $arrs.hide();
2214
- }
2215
-
2216
- spinnerStop();
2217
- spinner = new Spinner($.extend(spinnerDefaults, opts.spinner, spinnerOverride, {direction: o_rtl ? -1 : 1}));
2218
-
2219
- arrsUpdate();
2220
- stageWheelUpdate();
2221
-
2222
- if (opts.autoplay) setAutoplayInterval(opts.autoplay);
2223
-
2224
- o_thumbSide = numberFromMeasure(opts.thumbwidth) || THUMB_SIZE;
2225
- o_thumbSide2 = numberFromMeasure(opts.thumbheight) || THUMB_SIZE;
2226
-
2227
- stageWheelTail.ok = navWheelTail.ok = opts.trackpad && !SLOW;
2228
-
2229
- stageNoMove();
2230
-
2231
- extendMeasures(opts, [measures]);
2232
-
2233
- o_navThumbs = o_nav === 'thumbs';
2234
-
2235
- if (o_navThumbs) {
2236
- frameDraw(size, 'navThumb');
2237
-
2238
- $navFrame = $navThumbFrame;
2239
- navFrameKey = NAV_THUMB_FRAME_KEY;
2240
-
2241
- setStyle($style, $.Fotorama.jst.style({w: o_thumbSide, h: o_thumbSide2, b: opts.thumbborderwidth, m: opts.thumbmargin, s: stamp, q: !COMPAT}));
2242
-
2243
- $nav
2244
- .addClass(navThumbsClass)
2245
- .removeClass(navDotsClass);
2246
- } else if (o_nav === 'dots') {
2247
- frameDraw(size, 'navDot');
2248
-
2249
- $navFrame = $navDotFrame;
2250
- navFrameKey = NAV_DOT_FRAME_KEY;
2251
-
2252
- $nav
2253
- .addClass(navDotsClass)
2254
- .removeClass(navThumbsClass);
2255
- } else {
2256
- o_nav = false;
2257
- $nav.removeClass(navThumbsClass + ' ' + navDotsClass);
2258
- }
2259
-
2260
- if (o_nav) {
2261
- if (o_navTop) {
2262
- $navWrap.insertBefore($stage);
2263
- } else {
2264
- $navWrap.insertAfter($stage);
2265
- }
2266
- frameAppend.nav = false;
2267
- frameAppend($navFrame, $navShaft, 'nav');
2268
- }
2269
-
2270
- o_allowFullScreen = opts.allowfullscreen;
2271
-
2272
- if (o_allowFullScreen) {
2273
- $fullscreenIcon.prependTo($stage);
2274
- o_nativeFullScreen = FULLSCREEN && o_allowFullScreen === 'native';
2275
- } else {
2276
- $fullscreenIcon.detach();
2277
- o_nativeFullScreen = false;
2278
- }
2279
-
2280
- addOrRemoveClass(o_fade, wrapFadeClass);
2281
- addOrRemoveClass(!o_fade, wrapSlideClass);
2282
- addOrRemoveClass(!opts.captions, wrapNoCaptionsClass);
2283
- addOrRemoveClass(o_rtl, wrapRtlClass);
2284
- addOrRemoveClass(opts.arrows !== 'always', wrapToggleArrowsClass);
2285
-
2286
- o_shadows = opts.shadows && !SLOW;
2287
- addOrRemoveClass(!o_shadows, wrapNoShadowsClass);
2288
-
2289
- $wrap
2290
- .addClass(classes.add.join(' '))
2291
- .removeClass(classes.remove.join(' '));
2292
-
2293
- lastOptions = $.extend({}, opts);
2294
- }
2295
-
2296
- function normalizeIndex (index) {
2297
- return index < 0 ? (size + (index % size)) % size : index >= size ? index % size : index;
2298
- }
2299
-
2300
- function limitIndex (index) {
2301
- return minMaxLimit(index, 0, size - 1);
2302
- }
2303
-
2304
- function edgeIndex (index) {
2305
- return o_loop ? normalizeIndex(index) : limitIndex(index);
2306
- }
2307
-
2308
- function getPrevIndex (index) {
2309
- return index > 0 || o_loop ? index - 1 : false;
2310
- }
2311
-
2312
- function getNextIndex (index) {
2313
- return index < size - 1 || o_loop ? index + 1 : false;
2314
- }
2315
-
2316
- function setStageShaftMinmaxAndSnap () {
2317
- stageShaftTouchTail.min = o_loop ? -Infinity : -getPosByIndex(size - 1, measures.w, opts.margin, repositionIndex);
2318
- stageShaftTouchTail.max = o_loop ? Infinity : -getPosByIndex(0, measures.w, opts.margin, repositionIndex);
2319
- stageShaftTouchTail.snap = measures.w + opts.margin;
2320
- }
2321
-
2322
- function setNavShaftMinMax () {
2323
- ////////console.log('setNavShaftMinMax', measures.nw);
2324
- navShaftTouchTail.min = Math.min(0, measures.nw - $navShaft.width());
2325
- navShaftTouchTail.max = 0;
2326
- $navShaft.toggleClass(grabClass, !(navShaftTouchTail.noMove = navShaftTouchTail.min === navShaftTouchTail.max));
2327
- }
2328
-
2329
- function eachIndex (indexes, type, fn) {
2330
- if (typeof indexes === 'number') {
2331
- indexes = new Array(indexes);
2332
- var rangeFLAG = true;
2333
- }
2334
- return $.each(indexes, function (i, index) {
2335
- if (rangeFLAG) index = i;
2336
- if (typeof index === 'number') {
2337
- var dataFrame = data[normalizeIndex(index)];
2338
-
2339
- if (dataFrame) {
2340
- var key = '$' + type + 'Frame',
2341
- $frame = dataFrame[key];
2342
-
2343
- fn.call(this, i, index, dataFrame, $frame, key, $frame && $frame.data());
2344
- }
2345
- }
2346
- });
2347
- }
2348
-
2349
- function setMeasures (width, height, ratio, index) {
2350
- if (!measuresSetFLAG || (measuresSetFLAG === '*' && index === startIndex)) {
2351
-
2352
- //////console.log('setMeasures', index, opts.width, opts.height);
2353
-
2354
- width = measureIsValid(opts.width) || measureIsValid(width) || WIDTH;
2355
- height = measureIsValid(opts.height) || measureIsValid(height) || HEIGHT;
2356
- that.resize({
2357
- width: width,
2358
- ratio: opts.ratio || ratio || width / height
2359
- }, 0, index !== startIndex && '*');
2360
- }
2361
- }
2362
-
2363
- function loadImg (indexes, type, specialMeasures, method, position, again) {
2364
- eachIndex(indexes, type, function (i, index, dataFrame, $frame, key, frameData) {
2365
-
2366
- if (!$frame) return;
2367
-
2368
- var fullFLAG = that.fullScreen && dataFrame.full && dataFrame.full !== dataFrame.img && !frameData.$full && type === 'stage';
2369
-
2370
- if (frameData.$img && !again && !fullFLAG) return;
2371
-
2372
- var img = new Image(),
2373
- $img = $(img),
2374
- imgData = $img.data();
2375
-
2376
- frameData[fullFLAG ? '$full' : '$img'] = $img;
2377
-
2378
- var srcKey = type === 'stage' ? (fullFLAG ? 'full' : 'img') : 'thumb',
2379
- src = dataFrame[srcKey],
2380
- dummy = fullFLAG ? null : dataFrame[type === 'stage' ? 'thumb' : 'img'];
2381
-
2382
- if (type === 'navThumb') $frame = frameData.$wrap;
2383
-
2384
- function triggerTriggerEvent (event) {
2385
- var _index = normalizeIndex(index);
2386
- triggerEvent(event, {
2387
- index: _index,
2388
- src: src,
2389
- frame: data[_index]
2390
- });
2391
- }
2392
-
2393
- function error () {
2394
- $img.remove();
2395
-
2396
- $.Fotorama.cache[src] = 'error';
2397
-
2398
- if ((!dataFrame.html || type !== 'stage') && dummy && dummy !== src) {
2399
- dataFrame[srcKey] = src = dummy;
2400
- loadImg([index], type, specialMeasures, method, position, true);
2401
- } else {
2402
- if (src && !dataFrame.html && !fullFLAG) {
2403
- $frame
2404
- .trigger('f:error')
2405
- .removeClass(loadingClass)
2406
- .addClass(errorClass);
2407
-
2408
- triggerTriggerEvent('error');
2409
- } else if (type === 'stage') {
2410
- $frame
2411
- .trigger('f:load')
2412
- .removeClass(loadingClass + ' ' + errorClass)
2413
- .addClass(loadedClass);
2414
-
2415
- triggerTriggerEvent('load');
2416
- setMeasures();
2417
- }
2418
-
2419
- frameData.state = 'error';
2420
-
2421
- if (size > 1 && data[index] === dataFrame && !dataFrame.html && !dataFrame.deleted && !dataFrame.video && !fullFLAG) {
2422
- dataFrame.deleted = true;
2423
- that.splice(index, 1);
2424
- }
2425
- }
2426
- }
2427
-
2428
- function loaded () {
2429
- //////console.log('loaded: ' + src);
2430
-
2431
- ////console.log('$.Fotorama.measures[src]', $.Fotorama.measures[src]);
2432
-
2433
- $.Fotorama.measures[src] = imgData.measures = $.Fotorama.measures[src] || {
2434
- width: img.width,
2435
- height: img.height,
2436
- ratio: img.width / img.height
2437
- };
2438
-
2439
- setMeasures(imgData.measures.width, imgData.measures.height, imgData.measures.ratio, index);
2440
-
2441
- $img
2442
- .off('load error')
2443
- .addClass(imgClass + (fullFLAG ? ' ' + imgFullClass : ''))
2444
- .prependTo($frame);
2445
-
2446
- fit($img, ($.isFunction(specialMeasures) ? specialMeasures() : specialMeasures) || measures, method || dataFrame.fit || opts.fit, position || dataFrame.position || opts.position);
2447
-
2448
- $.Fotorama.cache[src] = frameData.state = 'loaded';
2449
-
2450
- setTimeout(function () {
2451
- $frame
2452
- .trigger('f:load')
2453
- .removeClass(loadingClass + ' ' + errorClass)
2454
- .addClass(loadedClass + ' ' + (fullFLAG ? loadedFullClass : loadedImgClass));
2455
-
2456
- if (type === 'stage') {
2457
- triggerTriggerEvent('load');
2458
- } else if (dataFrame.thumbratio === AUTO || !dataFrame.thumbratio && opts.thumbratio === AUTO) {
2459
- // danger! reflow for all thumbnails
2460
- dataFrame.thumbratio = imgData.measures.ratio;
2461
- reset();
2462
- }
2463
- }, 0);
2464
- }
2465
-
2466
- if (!src) {
2467
- error();
2468
- return;
2469
- }
2470
-
2471
- function waitAndLoad () {
2472
- var _i = 10;
2473
- waitFor(function () {
2474
- return !touchedFLAG || !_i-- && !SLOW;
2475
- }, function () {
2476
- loaded();
2477
- });
2478
- }
2479
-
2480
- if (!$.Fotorama.cache[src]) {
2481
- $.Fotorama.cache[src] = '*';
2482
-
2483
- $img
2484
- .on('load', waitAndLoad)
2485
- .on('error', error);
2486
- } else {
2487
- (function justWait () {
2488
- if ($.Fotorama.cache[src] === 'error') {
2489
- error();
2490
- } else if ($.Fotorama.cache[src] === 'loaded') {
2491
- ////console.log('take from cache: ' + src);
2492
- setTimeout(waitAndLoad, 0);
2493
- } else {
2494
- setTimeout(justWait, 100);
2495
- }
2496
- })();
2497
- }
2498
-
2499
- frameData.state = '';
2500
- img.src = src;
2501
- });
2502
- }
2503
-
2504
- function spinnerSpin ($el) {
2505
- $spinner.append(spinner.spin().el).appendTo($el);
2506
- }
2507
-
2508
- function spinnerStop () {
2509
- $spinner.detach();
2510
- spinner && spinner.stop();
2511
- }
2512
-
2513
- function updateFotoramaState () {
2514
- var $frame = activeFrame[STAGE_FRAME_KEY];
2515
-
2516
- if ($frame && !$frame.data().state) {
2517
- spinnerSpin($frame);
2518
- $frame.on('f:load f:error', function () {
2519
- $frame.off('f:load f:error');
2520
- spinnerStop();
2521
- });
2522
- }
2523
- }
2524
-
2525
- function addNavFrameEvents (frame) {
2526
- addEnterUp(frame, onNavFrameClick);
2527
- addFocus(frame, function () {
2528
-
2529
- setTimeout(function () {
2530
- lockScroll($nav);
2531
- }, 0);
2532
- slideNavShaft({time: o_transitionDuration, guessIndex: $(this).data().eq, minMax: navShaftTouchTail});
2533
- });
2534
- }
2535
-
2536
- function frameDraw (indexes, type) {
2537
- eachIndex(indexes, type, function (i, index, dataFrame, $frame, key, frameData) {
2538
- if ($frame) return;
2539
-
2540
- $frame = dataFrame[key] = $wrap[key].clone();
2541
- frameData = $frame.data();
2542
- frameData.data = dataFrame;
2543
- var frame = $frame[0];
2544
-
2545
- if (type === 'stage') {
2546
-
2547
- if (dataFrame.html) {
2548
- $('<div class="' + htmlClass + '"></div>')
2549
- .append(
2550
- dataFrame._html ? $(dataFrame.html)
2551
- .removeAttr('id')
2552
- .html(dataFrame._html) // Because of IE
2553
- : dataFrame.html
2554
- )
2555
- .appendTo($frame);
2556
- }
2557
-
2558
- dataFrame.caption && $(div(captionClass, div(captionWrapClass, dataFrame.caption))).appendTo($frame);
2559
-
2560
- dataFrame.video && $frame
2561
- .addClass(stageFrameVideoClass)
2562
- .append($videoPlay.clone());
2563
-
2564
- // This solves tabbing problems
2565
- addFocus(frame, function () {
2566
- setTimeout(function () {
2567
- lockScroll($stage);
2568
- }, 0);
2569
- clickToShow({index: frameData.eq, user: true});
2570
- });
2571
-
2572
- $stageFrame = $stageFrame.add($frame);
2573
- } else if (type === 'navDot') {
2574
- addNavFrameEvents(frame);
2575
- $navDotFrame = $navDotFrame.add($frame);
2576
- } else if (type === 'navThumb') {
2577
- addNavFrameEvents(frame);
2578
- frameData.$wrap = $frame.children(':first');
2579
- $navThumbFrame = $navThumbFrame.add($frame);
2580
- if (dataFrame.video) {
2581
- frameData.$wrap.append($videoPlay.clone());
2582
- }
2583
- }
2584
- });
2585
- }
2586
-
2587
- function callFit ($img, measuresToFit, method, position) {
2588
- return $img && $img.length && fit($img, measuresToFit, method, position);
2589
- }
2590
-
2591
- function stageFramePosition (indexes) {
2592
- eachIndex(indexes, 'stage', function (i, index, dataFrame, $frame, key, frameData) {
2593
- if (!$frame) return;
2594
-
2595
- var normalizedIndex = normalizeIndex(index),
2596
- method = dataFrame.fit || opts.fit,
2597
- position = dataFrame.position || opts.position;
2598
- frameData.eq = normalizedIndex;
2599
-
2600
- toDetach[STAGE_FRAME_KEY][normalizedIndex] = $frame.css($.extend({left: o_fade ? 0 : getPosByIndex(index, measures.w, opts.margin, repositionIndex)}, o_fade && getDuration(0)));
2601
-
2602
- if (isDetached($frame[0])) {
2603
- $frame.appendTo($stageShaft);
2604
- unloadVideo(dataFrame.$video);
2605
- }
2606
-
2607
- callFit(frameData.$img, measures, method, position);
2608
- callFit(frameData.$full, measures, method, position);
2609
- });
2610
- }
2611
-
2612
- function thumbsDraw (pos, loadFLAG) {
2613
- if (o_nav !== 'thumbs' || isNaN(pos)) return;
2614
-
2615
- var leftLimit = -pos,
2616
- rightLimit = -pos + measures.nw;
2617
-
2618
- $navThumbFrame.each(function () {
2619
- var $this = $(this),
2620
- thisData = $this.data(),
2621
- eq = thisData.eq,
2622
- getSpecialMeasures = function () {
2623
- return {
2624
- h: o_thumbSide2,
2625
- w: thisData.w
2626
- }
2627
- },
2628
- specialMeasures = getSpecialMeasures(),
2629
- dataFrame = data[eq] || {},
2630
- method = dataFrame.thumbfit || opts.thumbfit,
2631
- position = dataFrame.thumbposition || opts.thumbposition;
2632
-
2633
- specialMeasures.w = thisData.w;
2634
-
2635
- if (thisData.l + thisData.w < leftLimit
2636
- || thisData.l > rightLimit
2637
- || callFit(thisData.$img, specialMeasures, method, position)) return;
2638
-
2639
- loadFLAG && loadImg([eq], 'navThumb', getSpecialMeasures, method, position);
2640
- });
2641
- }
2642
-
2643
- function frameAppend ($frames, $shaft, type) {
2644
- if (!frameAppend[type]) {
2645
-
2646
- var thumbsFLAG = type === 'nav' && o_navThumbs,
2647
- left = 0;
2648
-
2649
- $shaft.append(
2650
- $frames
2651
- .filter(function () {
2652
- var actual,
2653
- $this = $(this),
2654
- frameData = $this.data();
2655
- for (var _i = 0, _l = data.length; _i < _l; _i++) {
2656
- if (frameData.data === data[_i]) {
2657
- actual = true;
2658
- frameData.eq = _i;
2659
- break;
2660
- }
2661
- }
2662
- return actual || $this.remove() && false;
2663
- })
2664
- .sort(function (a, b) {
2665
- return $(a).data().eq - $(b).data().eq;
2666
- })
2667
- .each(function () {
2668
-
2669
- if (!thumbsFLAG) return;
2670
-
2671
- var $this = $(this),
2672
- frameData = $this.data(),
2673
- thumbwidth = Math.round(o_thumbSide2 * frameData.data.thumbratio) || o_thumbSide;
2674
-
2675
- frameData.l = left;
2676
- frameData.w = thumbwidth;
2677
-
2678
- $this.css({width: thumbwidth});
2679
-
2680
- left += thumbwidth + opts.thumbmargin;
2681
- })
2682
- );
2683
-
2684
- frameAppend[type] = true;
2685
- }
2686
- }
2687
-
2688
- function getDirection (x) {
2689
- return x - stageLeft > measures.w / 3;
2690
- }
2691
-
2692
- function disableDirrection (i) {
2693
- return !o_loop && (!(activeIndex + i) || !(activeIndex - size + i)) && !$videoPlaying;
2694
- }
2695
-
2696
- function arrsUpdate () {
2697
- var disablePrev = disableDirrection(0),
2698
- disableNext = disableDirrection(1);
2699
- $arrPrev
2700
- .toggleClass(arrDisabledClass, disablePrev)
2701
- .attr(disableAttr(disablePrev));
2702
- $arrNext
2703
- .toggleClass(arrDisabledClass, disableNext)
2704
- .attr(disableAttr(disableNext));
2705
- }
2706
-
2707
- function stageWheelUpdate () {
2708
- if (stageWheelTail.ok) {
2709
- stageWheelTail.prevent = {'<': disableDirrection(0), '>': disableDirrection(1)};
2710
- }
2711
- }
2712
-
2713
- function getNavFrameBounds ($navFrame) {
2714
- var navFrameData = $navFrame.data(),
2715
- left,
2716
- width;
2717
-
2718
- if (o_navThumbs) {
2719
- left = navFrameData.l;
2720
- width = navFrameData.w;
2721
- } else {
2722
- left = $navFrame.position().left;
2723
- width = $navFrame.width();
2724
- }
2725
-
2726
- return {
2727
- c: left + width / 2,
2728
- min: -left + opts.thumbmargin * 10,
2729
- max: -left + measures.w - width - opts.thumbmargin * 10
2730
- };
2731
- }
2732
-
2733
- function slideThumbBorder (time) {
2734
- var navFrameData = activeFrame[navFrameKey].data();
2735
- slide($thumbBorder, {
2736
- time: time * 1.2,
2737
- pos: navFrameData.l,
2738
- width: navFrameData.w - opts.thumbborderwidth * 2
2739
- });
2740
- }
2741
-
2742
- function slideNavShaft (options) {
2743
- ////console.log('slideNavShaft', options.guessIndex, options.keep, slideNavShaft.l);
2744
- var $guessNavFrame = data[options.guessIndex][navFrameKey];
2745
- if ($guessNavFrame) {
2746
- var overflowFLAG = navShaftTouchTail.min !== navShaftTouchTail.max,
2747
- minMax = options.minMax || overflowFLAG && getNavFrameBounds(activeFrame[navFrameKey]),
2748
- l = overflowFLAG && (options.keep && slideNavShaft.l ? slideNavShaft.l : minMaxLimit((options.coo || measures.nw / 2) - getNavFrameBounds($guessNavFrame).c, minMax.min, minMax.max)),
2749
- pos = overflowFLAG && minMaxLimit(l, navShaftTouchTail.min, navShaftTouchTail.max),
2750
- time = options.time * 1.1;
2751
-
2752
- slide($navShaft, {
2753
- time: time,
2754
- pos: pos || 0,
2755
- onEnd: function () {
2756
- thumbsDraw(pos, true);
2757
- }
2758
- });
2759
-
2760
- //if (time) thumbsDraw(pos);
2761
-
2762
- setShadow($nav, findShadowEdge(pos, navShaftTouchTail.min, navShaftTouchTail.max));
2763
- slideNavShaft.l = l;
2764
- }
2765
- }
2766
-
2767
- function navUpdate () {
2768
- deactivateFrames(navFrameKey);
2769
- toDeactivate[navFrameKey].push(activeFrame[navFrameKey].addClass(activeClass));
2770
- }
2771
-
2772
- function deactivateFrames (key) {
2773
- var _toDeactivate = toDeactivate[key];
2774
-
2775
- while (_toDeactivate.length) {
2776
- _toDeactivate.shift().removeClass(activeClass);
2777
- }
2778
- }
2779
-
2780
- function detachFrames (key) {
2781
- var _toDetach = toDetach[key];
2782
-
2783
- //////console.log('_toDetach', _toDetach);
2784
- //////console.log('activeIndexes', activeIndexes);
2785
-
2786
- $.each(activeIndexes, function (i, index) {
2787
- delete _toDetach[normalizeIndex(index)];
2788
- });
2789
-
2790
- $.each(_toDetach, function (index, $frame) {
2791
- delete _toDetach[index];
2792
- //////console.log('Detach', index);
2793
- $frame.detach();
2794
- });
2795
- }
2796
-
2797
- function stageShaftReposition (skipOnEnd) {
2798
-
2799
- repositionIndex = dirtyIndex = activeIndex;
2800
-
2801
- var $frame = activeFrame[STAGE_FRAME_KEY];
2802
-
2803
- if ($frame) {
2804
- deactivateFrames(STAGE_FRAME_KEY);
2805
- toDeactivate[STAGE_FRAME_KEY].push($frame.addClass(activeClass));
2806
-
2807
- skipOnEnd || that.show.onEnd(true);
2808
- stop($stageShaft, 0, true);
2809
-
2810
- detachFrames(STAGE_FRAME_KEY);
2811
- stageFramePosition(activeIndexes);
2812
- setStageShaftMinmaxAndSnap();
2813
- setNavShaftMinMax();
2814
- }
2815
- }
2816
-
2817
- function extendMeasures (options, measuresArray) {
2818
- if (!options) return;
2819
-
2820
- $.each(measuresArray, function (i, measures) {
2821
- if (!measures) return;
2822
-
2823
- $.extend(measures, {
2824
- width: options.width || measures.width,
2825
- height: options.height,
2826
- minwidth: options.minwidth,
2827
- maxwidth: options.maxwidth,
2828
- minheight: options.minheight,
2829
- maxheight: options.maxheight,
2830
- ratio: getRatio(options.ratio)
2831
- })
2832
- });
2833
- }
2834
-
2835
- function triggerEvent (event, extra) {
2836
- $fotorama.trigger(_fotoramaClass + ':' + event, [that, extra]);
2837
- }
2838
-
2839
- function onTouchStart () {
2840
- clearTimeout(onTouchEnd.t);
2841
- touchedFLAG = 1;
2842
-
2843
- if (opts.stopautoplayontouch) {
2844
- that.stopAutoplay();
2845
- } else {
2846
- pausedAutoplayFLAG = true;
2847
- }
2848
- }
2849
-
2850
- function onTouchEnd () {
2851
- if (!opts.stopautoplayontouch) {
2852
- releaseAutoplay();
2853
- changeAutoplay();
2854
- }
2855
-
2856
- onTouchEnd.t = setTimeout(function () {
2857
- touchedFLAG = 0;
2858
- }, TRANSITION_DURATION + TOUCH_TIMEOUT);
2859
- //////console.timeEnd('onTouchEnd');
2860
- }
2861
-
2862
- function releaseAutoplay () {
2863
- pausedAutoplayFLAG = !!($videoPlaying || stoppedAutoplayFLAG);
2864
- }
2865
-
2866
- function changeAutoplay () {
2867
- ////console.log('changeAutoplay');
2868
-
2869
- clearTimeout(changeAutoplay.t);
2870
- waitFor.stop(changeAutoplay.w);
2871
-
2872
- if (!opts.autoplay || pausedAutoplayFLAG) {
2873
- if (that.autoplay) {
2874
- that.autoplay = false;
2875
- triggerEvent('stopautoplay');
2876
- }
2877
-
2878
- return;
2879
- }
2880
-
2881
- ////console.log('changeAutoplay continue');
2882
-
2883
- if (!that.autoplay) {
2884
- that.autoplay = true;
2885
- triggerEvent('startautoplay');
2886
- }
2887
-
2888
- var _activeIndex = activeIndex;
2889
-
2890
-
2891
- var frameData = activeFrame[STAGE_FRAME_KEY].data();
2892
- changeAutoplay.w = waitFor(function () {
2893
- ////console.log('wait for the state of the current frame');
2894
- return frameData.state || _activeIndex !== activeIndex;
2895
- }, function () {
2896
- ////console.log('the current frame is ready');
2897
- changeAutoplay.t = setTimeout(function () {
2898
- ////console.log('changeAutoplay.t setTimeout', pausedAutoplayFLAG, _activeIndex !== activeIndex);
2899
- if (pausedAutoplayFLAG || _activeIndex !== activeIndex) return;
2900
-
2901
- var _nextAutoplayIndex = nextAutoplayIndex,
2902
- nextFrameData = data[_nextAutoplayIndex][STAGE_FRAME_KEY].data();
2903
-
2904
- changeAutoplay.w = waitFor(function () {
2905
- ////console.log('wait for the state of the next frame');
2906
- return nextFrameData.state || _nextAutoplayIndex !== nextAutoplayIndex;
2907
- }, function () {
2908
- if (pausedAutoplayFLAG || _nextAutoplayIndex !== nextAutoplayIndex) return;
2909
- that.show(o_loop ? getDirectionSign(!o_rtl) : nextAutoplayIndex);
2910
- });
2911
- }, opts.autoplay);
2912
- });
2913
-
2914
- }
2915
-
2916
- that.startAutoplay = function (interval) {
2917
- if (that.autoplay) return this;
2918
- pausedAutoplayFLAG = stoppedAutoplayFLAG = false;
2919
- setAutoplayInterval(interval || opts.autoplay);
2920
- changeAutoplay();
2921
-
2922
- return this;
2923
- };
2924
-
2925
- that.stopAutoplay = function () {
2926
- if (that.autoplay) {
2927
- pausedAutoplayFLAG = stoppedAutoplayFLAG = true;
2928
- changeAutoplay();
2929
- }
2930
- return this;
2931
- };
2932
-
2933
- that.show = function (options) {
2934
- ////console.log('that.show');
2935
- //////console.time('that.show prepare');
2936
- var index;
2937
-
2938
- if (typeof options !== 'object') {
2939
- index = options;
2940
- options = {};
2941
- } else {
2942
- index = options.index;
2943
- }
2944
-
2945
- index = index === '>' ? dirtyIndex + 1 : index === '<' ? dirtyIndex - 1 : index === '<<' ? 0 : index === '>>' ? size - 1 : index;
2946
- index = isNaN(index) ? getIndexFromHash(index, data, true) : index;
2947
- index = typeof index === 'undefined' ? activeIndex || 0 : index;
2948
-
2949
- that.activeIndex = activeIndex = edgeIndex(index);
2950
- prevIndex = getPrevIndex(activeIndex);
2951
- nextIndex = getNextIndex(activeIndex);
2952
- nextAutoplayIndex = normalizeIndex(activeIndex + (o_rtl ? -1 : 1));
2953
- activeIndexes = [activeIndex, prevIndex, nextIndex];
2954
-
2955
- dirtyIndex = o_loop ? index : activeIndex;
2956
-
2957
- var diffIndex = Math.abs(lastActiveIndex - dirtyIndex),
2958
- time = getNumber(options.time, function () {
2959
- return Math.min(o_transitionDuration * (1 + (diffIndex - 1) / 12), o_transitionDuration * 2);
2960
- }),
2961
- overPos = options.overPos;
2962
-
2963
- if (options.slow) time *= 10;
2964
-
2965
- var _activeFrame = activeFrame;
2966
- that.activeFrame = activeFrame = data[activeIndex];
2967
- //////console.timeEnd('that.show prepare');
2968
-
2969
- var silent = _activeFrame === activeFrame && !options.user;
2970
-
2971
- //setTimeout(function () {
2972
- //////console.time('unloadVideo');
2973
- unloadVideo($videoPlaying, activeFrame.i !== data[normalizeIndex(repositionIndex)].i);
2974
- //////console.timeEnd('unloadVideo');
2975
- //////console.time('frameDraw');
2976
- frameDraw(activeIndexes, 'stage');
2977
- //////console.timeEnd('frameDraw');
2978
- //////console.time('stageFramePosition');
2979
- stageFramePosition(SLOW ? [dirtyIndex] : [dirtyIndex, getPrevIndex(dirtyIndex), getNextIndex(dirtyIndex)]);
2980
- //////console.timeEnd('stageFramePosition');
2981
- //////console.time('updateTouchTails');
2982
- updateTouchTails('go', true);
2983
- //////console.timeEnd('updateTouchTails');
2984
- //////console.time('triggerEvent');
2985
-
2986
- silent || triggerEvent('show', {
2987
- user: options.user,
2988
- time: time
2989
- });
2990
- //////console.timeEnd('triggerEvent');
2991
- //}, 0);
2992
-
2993
- //////console.time('bind onEnd');
2994
-
2995
- pausedAutoplayFLAG = true;
2996
-
2997
- var onEnd = that.show.onEnd = function (skipReposition) {
2998
- if (onEnd.ok) return;
2999
- onEnd.ok = true;
3000
-
3001
- skipReposition || stageShaftReposition(true);
3002
-
3003
- if (!silent) {
3004
- triggerEvent('showend', {
3005
- user: options.user
3006
- });
3007
- }
3008
-
3009
- ////console.log('o_transition', o_transition);
3010
-
3011
- if (!skipReposition && o_transition && o_transition !== opts.transition) {
3012
- ////console.log('set transition back to: ' + o_transition);
3013
- that.setOptions({transition: o_transition});
3014
- o_transition = false;
3015
- return;
3016
- }
3017
-
3018
- updateFotoramaState();
3019
- loadImg(activeIndexes, 'stage');
3020
-
3021
- updateTouchTails('go', false);
3022
- stageWheelUpdate();
3023
-
3024
- stageCursor();
3025
- releaseAutoplay();
3026
- changeAutoplay();
3027
- };
3028
- //////console.timeEnd('bind onEnd');
3029
-
3030
- if (!o_fade) {
3031
- //////console.time('slide');
3032
- slide($stageShaft, {
3033
- pos: -getPosByIndex(dirtyIndex, measures.w, opts.margin, repositionIndex),
3034
- overPos: overPos,
3035
- time: time,
3036
- onEnd: onEnd/*,
3037
- _001: true*/
3038
- });
3039
- //////console.timeEnd('slide');
3040
- } else {
3041
- var $activeFrame = activeFrame[STAGE_FRAME_KEY],
3042
- $prevActiveFrame = activeIndex !== lastActiveIndex ? data[lastActiveIndex][STAGE_FRAME_KEY] : null;
3043
-
3044
- fade($activeFrame, $prevActiveFrame, $stageFrame, {
3045
- time: time,
3046
- method: opts.transition,
3047
- onEnd: onEnd
3048
- }, fadeStack);
3049
- }
3050
-
3051
- //////console.time('arrsUpdate');
3052
- arrsUpdate();
3053
- //////console.timeEnd('arrsUpdate');
3054
-
3055
- if (o_nav) {
3056
- //////console.time('navUpdate');
3057
- navUpdate();
3058
- //////console.timeEnd('navUpdate');
3059
-
3060
- //////console.time('slideNavShaft');
3061
- var guessIndex = limitIndex(activeIndex + minMaxLimit(dirtyIndex - lastActiveIndex, -1, 1));
3062
- slideNavShaft({time: time, coo: guessIndex !== activeIndex && options.coo, guessIndex: typeof options.coo !== 'undefined' ? guessIndex : activeIndex, keep: silent});
3063
- //////console.timeEnd('slideNavShaft');
3064
-
3065
- //////console.time('slideThumbBorder');
3066
- if (o_navThumbs) slideThumbBorder(time);
3067
- //////console.timeEnd('slideThumbBorder');
3068
- }
3069
-
3070
- //////console.time('that.show end');
3071
- showedFLAG = typeof lastActiveIndex !== 'undefined' && lastActiveIndex !== activeIndex;
3072
- lastActiveIndex = activeIndex;
3073
- opts.hash && showedFLAG && !that.eq && setHash(activeFrame.id || activeIndex + 1);
3074
- //////console.timeEnd('that.show end');
3075
-
3076
- //////console.timeEnd('that.show');
3077
-
3078
- return this;
3079
- };
3080
-
3081
- that.requestFullScreen = function () {
3082
- if (o_allowFullScreen && !that.fullScreen) {
3083
- scrollTop = $WINDOW.scrollTop();
3084
- scrollLeft = $WINDOW.scrollLeft();
3085
-
3086
- lockScroll($WINDOW);
3087
-
3088
- updateTouchTails('x', true);
3089
-
3090
- measuresStash = $.extend({}, measures);
3091
-
3092
- $fotorama
3093
- .addClass(fullscreenClass)
3094
- .appendTo($BODY.addClass(_fullscreenClass));
3095
-
3096
- $HTML.addClass(_fullscreenClass);
3097
-
3098
- unloadVideo($videoPlaying, true, true);
3099
-
3100
- that.fullScreen = true;
3101
-
3102
- if (o_nativeFullScreen) {
3103
- fullScreenApi.request(fotorama);
3104
- }
3105
-
3106
- that.resize();
3107
- loadImg(activeIndexes, 'stage');
3108
- updateFotoramaState();
3109
-
3110
- triggerEvent('fullscreenenter');
3111
- }
3112
-
3113
- return this;
3114
- };
3115
-
3116
- function cancelFullScreen () {
3117
- if (that.fullScreen) {
3118
- that.fullScreen = false;
3119
-
3120
- if (FULLSCREEN) {
3121
- fullScreenApi.cancel(fotorama);
3122
- }
3123
-
3124
- $BODY.removeClass(_fullscreenClass);
3125
- $HTML.removeClass(_fullscreenClass);
3126
-
3127
- $fotorama
3128
- .removeClass(fullscreenClass)
3129
- .insertAfter($anchor);
3130
-
3131
- measures = $.extend({}, measuresStash);
3132
-
3133
- unloadVideo($videoPlaying, true, true);
3134
-
3135
- updateTouchTails('x', false);
3136
-
3137
- that.resize();
3138
- loadImg(activeIndexes, 'stage');
3139
-
3140
- lockScroll($WINDOW, scrollLeft, scrollTop);
3141
-
3142
- triggerEvent('fullscreenexit');
3143
- }
3144
- }
3145
-
3146
- that.cancelFullScreen = function () {
3147
- if (o_nativeFullScreen && fullScreenApi.is()) {
3148
- fullScreenApi.cancel(document);
3149
- } else {
3150
- cancelFullScreen();
3151
- }
3152
-
3153
- return this;
3154
- };
3155
-
3156
- that.toggleFullScreen = function () {
3157
- return that[(that.fullScreen ? 'cancel' : 'request') + 'FullScreen']();
3158
- };
3159
-
3160
- addEvent(document, fullScreenApi.event, function () {
3161
- if (data && !fullScreenApi.is() && !$videoPlaying) {
3162
- cancelFullScreen();
3163
- }
3164
- });
3165
-
3166
- that.resize = function (options) {
3167
- if (!data) return this;
3168
-
3169
- var time = arguments[1] || 0,
3170
- setFLAG = arguments[2];
3171
-
3172
- extendMeasures(!that.fullScreen ? optionsToLowerCase(options) : {width: '100%', maxwidth: null, minwidth: null, height: '100%', maxheight: null, minheight: null}, [measures, setFLAG || that.fullScreen || opts]);
3173
-
3174
- var width = measures.width,
3175
- height = measures.height,
3176
- ratio = measures.ratio,
3177
- windowHeight = $WINDOW.height() - (o_nav ? $nav.height() : 0);
3178
-
3179
- if (measureIsValid(width)) {
3180
- $wrap
3181
- .addClass(wrapOnlyActiveClass)
3182
- .css({width: width, minWidth: measures.minwidth || 0, maxWidth: measures.maxwidth || MAX_WIDTH});
3183
-
3184
- width = measures.W = measures.w = $wrap.width();
3185
- measures.nw = o_nav && numberFromWhatever(opts.navwidth, width) || width;
3186
-
3187
- if (opts.glimpse) {
3188
- // Glimpse
3189
- measures.w -= Math.round((numberFromWhatever(opts.glimpse, width) || 0) * 2);
3190
- }
3191
-
3192
- $stageShaft.css({width: measures.w, marginLeft: (measures.W - measures.w) / 2});
3193
-
3194
- //////console.log('measures.W', measures.W);
3195
- //////console.log('measures.w', measures.w);
3196
-
3197
- height = numberFromWhatever(height, windowHeight);
3198
-
3199
- height = height || (ratio && width / ratio);
3200
-
3201
- if (height) {
3202
- width = Math.round(width);
3203
- height = measures.h = Math.round(minMaxLimit(height, numberFromWhatever(measures.minheight, windowHeight), numberFromWhatever(measures.maxheight, windowHeight)));
3204
-
3205
- $stage
3206
- .stop()
3207
- .animate({width: width, height: height}, time, function () {
3208
- $wrap.removeClass(wrapOnlyActiveClass);
3209
- });
3210
-
3211
- stageShaftReposition();
3212
-
3213
- if (o_nav) {
3214
- $nav
3215
- .stop()
3216
- .animate({width: measures.nw}, time);
3217
-
3218
- slideNavShaft({guessIndex: activeIndex, time: time, keep: true});
3219
- if (o_navThumbs && frameAppend.nav) slideThumbBorder(time);
3220
- }
3221
-
3222
- measuresSetFLAG = setFLAG || true;
3223
-
3224
- ready();
3225
- }
3226
- }
3227
-
3228
- stageLeft = $stage.offset().left;
3229
-
3230
- return this;
3231
- };
3232
-
3233
- that.setOptions = function (options) {
3234
- $.extend(opts, options);
3235
- reset();
3236
- return this;
3237
- };
3238
-
3239
- that.shuffle = function () {
3240
- data && shuffle(data) && reset();
3241
- return this;
3242
- };
3243
-
3244
- function setShadow ($el, edge) {
3245
- //////console.time('setShadow');
3246
- if (o_shadows) {
3247
- $el.removeClass(shadowsLeftClass + ' ' + shadowsRightClass);
3248
- edge && !$videoPlaying && $el.addClass(edge.replace(/^|\s/g, ' ' + shadowsClass + '--'));
3249
- }
3250
- //////console.timeEnd('setShadow');
3251
- }
3252
-
3253
- that.destroy = function () {
3254
- that.cancelFullScreen();
3255
- that.stopAutoplay();
3256
-
3257
- data = that.data = null;
3258
-
3259
- appendElements();
3260
-
3261
- activeIndexes = [];
3262
- detachFrames(STAGE_FRAME_KEY);
3263
-
3264
- reset.ok = false;
3265
-
3266
- return this;
3267
- };
3268
-
3269
- that.playVideo = function () {
3270
- var dataFrame = activeFrame,
3271
- video = dataFrame.video,
3272
- _activeIndex = activeIndex;
3273
-
3274
- if (typeof video === 'object' && dataFrame.videoReady) {
3275
- o_nativeFullScreen && that.fullScreen && that.cancelFullScreen();
3276
-
3277
- waitFor(function () {
3278
- return !fullScreenApi.is() || _activeIndex !== activeIndex;
3279
- }, function () {
3280
- if (_activeIndex === activeIndex) {
3281
- dataFrame.$video = dataFrame.$video || $($.Fotorama.jst.video(video));
3282
- dataFrame.$video.appendTo(dataFrame[STAGE_FRAME_KEY]);
3283
-
3284
- $wrap.addClass(wrapVideoClass);
3285
- $videoPlaying = dataFrame.$video;
3286
-
3287
- stageNoMove();
3288
-
3289
- $arrs.blur();
3290
- $fullscreenIcon.blur();
3291
-
3292
- triggerEvent('loadvideo');
3293
- }
3294
- });
3295
- }
3296
-
3297
- return this;
3298
- };
3299
-
3300
- that.stopVideo = function () {
3301
- unloadVideo($videoPlaying, true, true);
3302
- return this;
3303
- };
3304
-
3305
- function unloadVideo ($video, unloadActiveFLAG, releaseAutoplayFLAG) {
3306
- if (unloadActiveFLAG) {
3307
- $wrap.removeClass(wrapVideoClass);
3308
- $videoPlaying = false;
3309
-
3310
- stageNoMove();
3311
- }
3312
-
3313
- if ($video && $video !== $videoPlaying) {
3314
- $video.remove();
3315
- triggerEvent('unloadvideo');
3316
- }
3317
-
3318
- if (releaseAutoplayFLAG) {
3319
- releaseAutoplay();
3320
- changeAutoplay();
3321
- }
3322
- }
3323
-
3324
- function toggleControlsClass (FLAG) {
3325
- $wrap.toggleClass(wrapNoControlsClass, FLAG);
3326
- }
3327
-
3328
- function stageCursor (e) {
3329
- if (stageShaftTouchTail.flow) return;
3330
-
3331
- var x = e ? e.pageX : stageCursor.x,
3332
- pointerFLAG = x && !disableDirrection(getDirection(x)) && opts.click;
3333
-
3334
- if (stageCursor.p !== pointerFLAG
3335
- && $stage.toggleClass(pointerClass, pointerFLAG)) {
3336
- stageCursor.p = pointerFLAG;
3337
- stageCursor.x = x;
3338
- }
3339
- }
3340
-
3341
- $stage.on('mousemove', stageCursor);
3342
-
3343
- function clickToShow (showOptions) {
3344
- clearTimeout(clickToShow.t);
3345
-
3346
- if (opts.clicktransition && opts.clicktransition !== opts.transition) {
3347
- ////console.log('change transition to: ' + opts.clicktransition);
3348
-
3349
- // this timeout is for yield events flow
3350
- setTimeout(function () {
3351
- // save original transition for later
3352
- var _o_transition = opts.transition;
3353
-
3354
- that.setOptions({transition: opts.clicktransition});
3355
-
3356
- // now safe to pass base transition to o_transition, so that.show will restor it
3357
- o_transition = _o_transition;
3358
- // this timeout is here to prevent jerking in some browsers
3359
- clickToShow.t = setTimeout(function () {
3360
- that.show(showOptions);
3361
- }, 10);
3362
- }, 0);
3363
- } else {
3364
- that.show(showOptions);
3365
- }
3366
- }
3367
-
3368
- function onStageTap (e, toggleControlsFLAG) {
3369
- //////console.time('onStageTap');
3370
- var target = e.target,
3371
- $target = $(target);
3372
-
3373
- if ($target.hasClass(videoPlayClass)) {
3374
- that.playVideo();
3375
- } else if (target === fullscreenIcon) {
3376
- that.toggleFullScreen();
3377
- } else if ($videoPlaying) {
3378
- target === videoClose && unloadVideo($videoPlaying, true, true);
3379
- } else {
3380
- if (toggleControlsFLAG) {
3381
- toggleControlsClass();
3382
- } else if (opts.click) {
3383
-
3384
- clickToShow({index: e.shiftKey || getDirectionSign(getDirection(e._x)), slow: e.altKey, user: true});
3385
- }
3386
- }
3387
- //////console.timeEnd('onStageTap');
3388
- }
3389
-
3390
- function updateTouchTails (key, value) {
3391
- stageShaftTouchTail[key] = navShaftTouchTail[key] = value;
3392
- }
3393
-
3394
- stageShaftTouchTail = moveOnTouch($stageShaft, {
3395
- onStart: onTouchStart,
3396
- onMove: function (e, result) {
3397
- setShadow($stage, result.edge);
3398
- },
3399
- onTouchEnd: onTouchEnd,
3400
- onEnd: function (result) {
3401
- //////console.time('stageShaftTouchTail.onEnd');
3402
- setShadow($stage);
3403
-
3404
- //////console.log('result', result);
3405
-
3406
- var toggleControlsFLAG = (MS_POINTER && !hoverFLAG || result.touch) && opts.arrows && opts.arrows !== 'always';
3407
-
3408
- if (result.moved || (toggleControlsFLAG && result.pos !== result.newPos && !result.control)) {
3409
- var index = getIndexByPos(result.newPos, measures.w, opts.margin, repositionIndex);
3410
- that.show({
3411
- index: index,
3412
- time: o_fade ? o_transitionDuration : result.time,
3413
- overPos: result.overPos,
3414
- user: true
3415
- });
3416
- } else if (!result.aborted && !result.control) {
3417
- onStageTap(result.startEvent, toggleControlsFLAG);
3418
- }
3419
- //////console.timeEnd('stageShaftTouchTail.onEnd');
3420
- },
3421
- // getPos: function () {
3422
- // return -getPosByIndex(dirtyIndex, measures.w, opts.margin, repositionIndex);
3423
- // },
3424
- //_001: true,
3425
- timeLow: 1,
3426
- timeHigh: 1,
3427
- friction: 2,
3428
- select: '.' + selectClass + ', .' + selectClass + ' *',
3429
- $wrap: $stage
3430
- });
3431
-
3432
- navShaftTouchTail = moveOnTouch($navShaft, {
3433
- onStart: onTouchStart,
3434
- onMove: function (e, result) {
3435
- setShadow($nav, result.edge);
3436
- },
3437
- onTouchEnd: onTouchEnd,
3438
- onEnd: function (result) {
3439
-
3440
- function onEnd () {
3441
- slideNavShaft.l = result.newPos;
3442
- releaseAutoplay();
3443
- changeAutoplay();
3444
- thumbsDraw(result.newPos, true);
3445
- }
3446
-
3447
- if (!result.moved) {
3448
- var target = result.$target.closest('.' + navFrameClass, $navShaft)[0];
3449
- target && onNavFrameClick.call(target, result.startEvent);
3450
- } else if (result.pos !== result.newPos) {
3451
- pausedAutoplayFLAG = true;
3452
- slide($navShaft, {
3453
- time: result.time,
3454
- pos: result.newPos,
3455
- overPos: result.overPos,
3456
- onEnd: onEnd
3457
- });
3458
- thumbsDraw(result.newPos);
3459
- o_shadows && setShadow($nav, findShadowEdge(result.newPos, navShaftTouchTail.min, navShaftTouchTail.max));
3460
- } else {
3461
- onEnd();
3462
- }
3463
- },
3464
- timeLow: .5,
3465
- timeHigh: 2,
3466
- friction: 5,
3467
- $wrap: $nav
3468
- });
3469
-
3470
- stageWheelTail = wheel($stage, {
3471
- shift: true,
3472
- onEnd: function (e, direction) {
3473
- //////console.log('wheel $stage onEnd', direction);
3474
- onTouchStart();
3475
- onTouchEnd();
3476
- that.show({index: direction, slow: e.altKey})
3477
- }
3478
- });
3479
-
3480
- navWheelTail = wheel($nav, {
3481
- onEnd: function (e, direction) {
3482
- //////console.log('wheel $nav onEnd', direction);
3483
- onTouchStart();
3484
- onTouchEnd();
3485
- var newPos = stop($navShaft) + direction * .25;
3486
- $navShaft.css(getTranslate(minMaxLimit(newPos, navShaftTouchTail.min, navShaftTouchTail.max)));
3487
- o_shadows && setShadow($nav, findShadowEdge(newPos, navShaftTouchTail.min, navShaftTouchTail.max));
3488
- navWheelTail.prevent = {'<': newPos >= navShaftTouchTail.max, '>': newPos <= navShaftTouchTail.min};
3489
- clearTimeout(navWheelTail.t);
3490
- navWheelTail.t = setTimeout(function () {
3491
- slideNavShaft.l = newPos;
3492
- thumbsDraw(newPos, true)
3493
- }, TOUCH_TIMEOUT);
3494
- thumbsDraw(newPos);
3495
- }
3496
- });
3497
-
3498
- $wrap.hover(
3499
- function () {
3500
- setTimeout(function () {
3501
- if (touchedFLAG) return;
3502
- toggleControlsClass(!(hoverFLAG = true));
3503
- }, 0);
3504
- }, function () {
3505
- if (!hoverFLAG) return;
3506
- toggleControlsClass(!(hoverFLAG = false));
3507
- }
3508
- );
3509
-
3510
- function onNavFrameClick (e) {
3511
- var index = $(this).data().eq;
3512
- clickToShow({index: index, slow: e.altKey, user: true, coo: e._x - $nav.offset().left});
3513
- }
3514
-
3515
- function onArrClick (e) {
3516
- clickToShow({index: $arrs.index(this) ? '>' : '<', slow: e.altKey, user: true});
3517
- }
3518
-
3519
- smartClick($arrs, function (e) {
3520
- stopEvent(e);
3521
- onArrClick.call(this, e);
3522
- }, {
3523
- onStart: function () {
3524
- onTouchStart();
3525
- stageShaftTouchTail.control = true;
3526
- },
3527
- onTouchEnd: onTouchEnd
3528
- });
3529
-
3530
- function addFocusOnControls (el) {
3531
- addFocus(el, function () {
3532
- setTimeout(function () {
3533
- lockScroll($stage);
3534
- }, 0);
3535
- toggleControlsClass(false);
3536
- });
3537
- }
3538
-
3539
- $arrs.each(function () {
3540
- addEnterUp(this, function (e) {
3541
- onArrClick.call(this, e);
3542
- });
3543
- addFocusOnControls(this);
3544
- });
3545
-
3546
- addEnterUp(fullscreenIcon, that.toggleFullScreen);
3547
- addFocusOnControls(fullscreenIcon);
3548
-
3549
- function reset () {
3550
- setData();
3551
- setOptions();
3552
-
3553
- if (!reset.i) {
3554
- reset.i = true;
3555
- // Only once
3556
- var _startindex = opts.startindex;
3557
- if (_startindex || opts.hash && location.hash) {
3558
- startIndex = getIndexFromHash(_startindex || location.hash.replace(/^#/, ''), data, that.index === 0 || _startindex, _startindex);
3559
- }
3560
- activeIndex = repositionIndex = dirtyIndex = lastActiveIndex = startIndex = edgeIndex(startIndex) || 0;/*(o_rtl ? size - 1 : 0)*///;
3561
- }
3562
-
3563
- if (size) {
3564
- if (changeToRtl()) return;
3565
-
3566
- if ($videoPlaying) {
3567
- unloadVideo($videoPlaying, true);
3568
- }
3569
-
3570
- activeIndexes = [];
3571
- detachFrames(STAGE_FRAME_KEY);
3572
-
3573
- reset.ok = true;
3574
-
3575
- that.show({index: activeIndex, time: 0});
3576
- that.resize();
3577
- } else {
3578
- that.destroy();
3579
- }
3580
- }
3581
-
3582
- function changeToRtl () {
3583
- //////console.log('changeToRtl');
3584
- if (!changeToRtl.f === o_rtl) {
3585
- changeToRtl.f = o_rtl;
3586
- activeIndex = size - 1 - activeIndex;
3587
- //////console.log('changeToRtl execute, activeIndex is', activeIndex);
3588
- that.reverse();
3589
-
3590
- return true;
3591
- }
3592
- }
3593
-
3594
- $.each('load push pop shift unshift reverse sort splice'.split(' '), function (i, method) {
3595
- that[method] = function () {
3596
- data = data || [];
3597
- if (method !== 'load') {
3598
- Array.prototype[method].apply(data, arguments);
3599
- } else if (arguments[0] && typeof arguments[0] === 'object' && arguments[0].length) {
3600
- data = clone(arguments[0]);
3601
- }
3602
- reset();
3603
- return that;
3604
- }
3605
- });
3606
-
3607
- function ready () {
3608
- if (!ready.ok) {
3609
- ready.ok = true;
3610
- triggerEvent('ready');
3611
- }
3612
- }
3613
-
3614
- reset();
3615
- };
3616
-
3617
-
3618
- $.fn.fotorama = function (opts) {
3619
- return this.each(function () {
3620
- var that = this,
3621
- $fotorama = $(this),
3622
- fotoramaData = $fotorama.data(),
3623
- fotorama = fotoramaData.fotorama;
3624
-
3625
- if (!fotorama) {
3626
- waitFor(function () {
3627
- return !isHidden(that);
3628
- }, function () {
3629
- fotoramaData.urtext = $fotorama.html();
3630
- new $.Fotorama($fotorama,
3631
- /* Priority for options:
3632
- * 1. <div data-loop="true"></div>
3633
- * 2. $('div').fotorama({loop: false})
3634
- * 3. Defaults */
3635
- $.extend(
3636
- {},
3637
- OPTIONS,
3638
- window.fotoramaDefaults,
3639
- opts,
3640
- fotoramaData
3641
- )
3642
- );
3643
- });
3644
- } else {
3645
- fotorama.setOptions(opts, true);
3646
- }
3647
- });
3648
- };
3649
- $.Fotorama.instances = [];
3650
-
3651
- function calculateIndexes () {
3652
- $.each($.Fotorama.instances, function (index, instance) {
3653
- instance.index = index;
3654
- });
3655
- }
3656
-
3657
- function addInstance (instance) {
3658
- $.Fotorama.instances.push(instance);
3659
- calculateIndexes();
3660
- }
3661
-
3662
- function hideInstance (instance) {
3663
- $.Fotorama.instances.splice(instance.index, 1);
3664
- calculateIndexes();
3665
- }
3666
- $.Fotorama.cache = {};
3667
- $.Fotorama.measures = {};
3668
- $ = $ || {};
3669
- $.Fotorama = $.Fotorama || {};
3670
- $.Fotorama.jst = $.Fotorama.jst || {};
3671
-
3672
- $.Fotorama.jst.style = function(v) {
3673
- var __t, __p = '', __e = _.escape;
3674
- __p += '.fotorama' +
3675
- ((__t = ( v.s )) == null ? '' : __t) +
3676
- ' .fotorama__nav--thumbs .fotorama__nav__frame{\npadding:' +
3677
- ((__t = ( v.m )) == null ? '' : __t) +
3678
- 'px;\nheight:' +
3679
- ((__t = ( v.h )) == null ? '' : __t) +
3680
- 'px}\n.fotorama' +
3681
- ((__t = ( v.s )) == null ? '' : __t) +
3682
- ' .fotorama__thumb-border{\nheight:' +
3683
- ((__t = ( v.h - v.b * (v.q ? 0 : 2) )) == null ? '' : __t) +
3684
- 'px;\nborder-width:' +
3685
- ((__t = ( v.b )) == null ? '' : __t) +
3686
- 'px;\nmargin-top:' +
3687
- ((__t = ( v.m )) == null ? '' : __t) +
3688
- 'px}';
3689
- return __p
3690
- };
3691
-
3692
- $.Fotorama.jst.video = function(v) {
3693
- var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
3694
- function print() { __p += __j.call(arguments, '') }
3695
- __p += '<div class="fotorama__video"><iframe src="';
3696
- print((v.type == 'youtube' ? v.p + 'youtube.com/embed/' + v.id +'?autoplay=1' : v.type == 'vimeo' ? v.p + 'player.vimeo.com/video/' + v.id + '?autoplay=1&badge=0' : v.id) + (v.s && v.type != 'custom' ? '&' + v.s : '')) ;
3697
- __p += '" frameborder="0" allowfullscreen></iframe></div>\n';
3698
- return __p
3699
- };
3700
- $(function () {
3701
- $('.' + _fotoramaClass + ':not([data-auto="false"])').fotorama();
3702
-
3703
- // Get usage statistics
3704
- if (getProtocol() !== 'http://' || !location.host.match(/\./) || window.blockFotoramaData) return;
3705
- $('body').append('<iframe src="http://data.fotorama.io/?version=' + fotoramaVersion + '" style="display: none;"></iframe>');
3706
- });
3707
- })(window, document, location, typeof jQuery !== 'undefined' && jQuery);
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>D3318AE085B3BFAC</RequestId><HostId>h1ELuAQia3cs/P/e5NF+jhW6sDfJnNGhLs9MUZCDNMuxh41QuFtz9HebbmXVnJc4</HostId></Error>