blueimp-gallery-rails 2.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0a0b2d9905de095b1dd3f613eaf41cd1fd8f6cfa
4
+ data.tar.gz: 38c9106f69c45d07010015e2ad9c297ddb2736ff
5
+ SHA512:
6
+ metadata.gz: 8a0244db2d7fd28a69bde5e21ca33ee0ae40b8857cb4f690be62b88dfbb655fa2c80470826e1ec0148138cc1571bb05fdc09952916234c80bdbe0eb1bd3ff547
7
+ data.tar.gz: aada469dd3e94eac653903b66d0ce7b506741268582549824350530cd36dbcc1ed89508ea0515d45d7b9d5ae2dd06f5ebd294a30995773da9fd0dfa1b3ad14f9
@@ -0,0 +1,10 @@
1
+ require "blueimp-gallery-rails/version"
2
+
3
+ module Blueimp
4
+ module Gallery
5
+ module Rails
6
+ class Engine < ::Rails::Engine
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ # This is a generated file.
2
+ module Blueimp
3
+ module Gallery
4
+ module Rails
5
+ class Version
6
+ class << self
7
+ def to_s
8
+ "2.3.1"
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="64" height="64">
3
+ <circle cx="32" cy="32" r="25" stroke="red" stroke-width="7" fill="black" fill-opacity="0.2"/>
4
+ <rect x="28" y="7" width="8" height="50" fill="red" transform="rotate(45, 32, 32)"/>
5
+ </svg>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="30" height="15">
3
+ <polygon points="2,1 2,14 13,7" stroke="black" stroke-width="1" fill="white"/>
4
+ <rect x="17" y="2" width="4" height="11" stroke="black" stroke-width="1" fill="white"/>
5
+ <rect x="24" y="2" width="4" height="11" stroke="black" stroke-width="1" fill="white"/>
6
+ </svg>
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="64" height="64">
3
+ <circle cx="32" cy="32" r="25" stroke="white" stroke-width="7" fill="black" fill-opacity="0.2"/>
4
+ <polygon points="26,22 26,42 43,32" fill="white"/>
5
+ </svg>
@@ -0,0 +1,1443 @@
1
+ /*
2
+ * blueimp Gallery JS 2.3.1
3
+ * https://github.com/blueimp/Gallery
4
+ *
5
+ * Copyright 2013, Sebastian Tschan
6
+ * https://blueimp.net
7
+ *
8
+ * Swipe implementation based on
9
+ * https://github.com/bradbirdsall/Swipe
10
+ *
11
+ * Licensed under the MIT license:
12
+ * http://www.opensource.org/licenses/MIT
13
+ */
14
+
15
+ /*jslint regexp: true */
16
+ /*global define, window, document, DocumentTouch */
17
+
18
+ (function () {
19
+ 'use strict';
20
+
21
+ function Gallery(list, options) {
22
+ if (!list || !list.length || document.body.style.maxHeight === undefined) {
23
+ // document.body.style.maxHeight is undefined on IE6 and lower
24
+ return false;
25
+ }
26
+ if (!this || this.options !== Gallery.prototype.options) {
27
+ // Called as function instead of as constructor,
28
+ // so we simply return a new instance:
29
+ return new Gallery(list, options);
30
+ }
31
+ this.list = list;
32
+ this.num = list.length;
33
+ this.initOptions(options);
34
+ this.initStartIndex();
35
+ if (this.initWidget() === false) {
36
+ return false;
37
+ }
38
+ this.initEventListeners();
39
+ // Load the slide at the given index:
40
+ this.onslide(this.index);
41
+ // Start the automatic slideshow if applicable:
42
+ if (this.options.startSlideshow) {
43
+ this.play();
44
+ }
45
+ if (this.options.fullScreen && !this.getFullScreenElement()) {
46
+ this.requestFullScreen(this.container);
47
+ }
48
+ }
49
+
50
+ var helper = {
51
+
52
+ extend: function (obj1, obj2) {
53
+ var prop;
54
+ for (prop in obj2) {
55
+ if (obj2.hasOwnProperty(prop)) {
56
+ obj1[prop] = obj2[prop];
57
+ }
58
+ }
59
+ return obj1;
60
+ },
61
+
62
+ hasClass: function (element, className) {
63
+ return new RegExp('(^|\\s+)' + className + '(\\s+|$)').test(element.className);
64
+ },
65
+
66
+ addClass: function (element, className) {
67
+ if (!element.className) {
68
+ element.className = className;
69
+ return;
70
+ }
71
+ if (this.hasClass(element, className)) {
72
+ return;
73
+ }
74
+ element.className += ' ' + className;
75
+ },
76
+
77
+ removeClass: function (element, className) {
78
+ var regexp = new RegExp('(^|\\s+)' + className + '(\\s+|$)');
79
+ element.className = element.className.replace(regexp, ' ');
80
+ },
81
+
82
+ addListener: function (element, eventName, handler) {
83
+ if (element.addEventListener) {
84
+ element.addEventListener(eventName, handler, false);
85
+ } else if (element.attachEvent) {
86
+ element.attachEvent('on' + eventName, handler);
87
+ }
88
+ },
89
+
90
+ removeListener: function (element, eventName, handler) {
91
+ if (element.removeEventListener) {
92
+ element.removeEventListener(eventName, handler, false);
93
+ } else if (element.detachEvent) {
94
+ element.detachEvent('on' + eventName, handler);
95
+ }
96
+ },
97
+
98
+ preventDefault: function (event) {
99
+ if (event.preventDefault) {
100
+ event.preventDefault();
101
+ } else {
102
+ event.returnValue = false;
103
+ }
104
+ },
105
+
106
+ empty: function (element) {
107
+ while (element.hasChildNodes()) {
108
+ element.removeChild(element.lastChild);
109
+ }
110
+ },
111
+
112
+ query: function (container, element) {
113
+ if (typeof element === 'string') {
114
+ if (container.querySelector) {
115
+ return container.querySelector(element);
116
+ }
117
+ if (element.charAt(0) === '#') {
118
+ return container.getElementById(element.slice(1));
119
+ }
120
+ return container.getElementsByTagName(element)[0];
121
+ }
122
+ return element;
123
+ },
124
+
125
+ contains: function (container, element) {
126
+ do {
127
+ element = element.parentNode;
128
+ if (element === container) {
129
+ return true;
130
+ }
131
+ } while (element);
132
+ return false;
133
+ },
134
+
135
+ parseJSON: function (string) {
136
+ return window.JSON && JSON.parse(string);
137
+ },
138
+
139
+ getNestedProperty: function (obj, property) {
140
+ property.replace(
141
+ // Matches native JavaScript notation in a String,
142
+ // e.g. '["doubleQuoteProp"].dotProp[2]'
143
+ /\[(?:'([^']+)'|"([^"]+)"|(\d+))\]|(?:(?:^|\.)([^\.\[]+))/g,
144
+ function (str, singleQuoteProp, doubleQuoteProp, arrayIndex, dotProp) {
145
+ var prop = dotProp || singleQuoteProp || doubleQuoteProp ||
146
+ (arrayIndex && parseInt(arrayIndex, 10));
147
+ if (str && obj) {
148
+ obj = obj[prop];
149
+ }
150
+ }
151
+ );
152
+ return obj;
153
+ }
154
+
155
+ };
156
+
157
+ helper.extend(Gallery.prototype, {
158
+
159
+ helper: helper,
160
+
161
+ options: {
162
+ // The Id, element or querySelector of the gallery widget:
163
+ container: '#blueimp-gallery',
164
+ // The tag name, Id, element or querySelector of the slides container:
165
+ slidesContainer: 'div',
166
+ // The tag name, Id, element or querySelector of the title element:
167
+ titleElement: 'h3',
168
+ // The tag name, Id, element or querySelector of the indicator container:
169
+ indicatorContainer: 'ol',
170
+ // The class to add when the gallery is visible:
171
+ displayClass: 'blueimp-gallery-display',
172
+ // The class to add when the gallery controls are visible:
173
+ controlsClass: 'blueimp-gallery-controls',
174
+ // The class to add when the gallery only displays one element:
175
+ singleClass: 'blueimp-gallery-single',
176
+ // The class to add when the left edge has been reached:
177
+ leftEdgeClass: 'blueimp-gallery-left',
178
+ // The class to add when the right edge has been reached:
179
+ rightEdgeClass: 'blueimp-gallery-right',
180
+ // The class to add when the automatic slideshow is active:
181
+ playingClass: 'blueimp-gallery-playing',
182
+ // The class for all slides:
183
+ slideClass: 'slide',
184
+ // The slide class for loading elements:
185
+ slideLoadingClass: 'slide-loading',
186
+ // The slide class for elements that failed to load:
187
+ slideErrorClass: 'slide-error',
188
+ // The class for the content element loaded into each slide:
189
+ slideContentClass: 'slide-content',
190
+ // The class for video content elements:
191
+ videoContentClass: 'video-content',
192
+ // The class for video when it is loading:
193
+ videoLoadingClass: 'video-loading',
194
+ // The class for video when it is playing:
195
+ videoPlayingClass: 'video-playing',
196
+ // The class for the "toggle" control:
197
+ toggleClass: 'toggle',
198
+ // The class for the "prev" control:
199
+ prevClass: 'prev',
200
+ // The class for the "next" control:
201
+ nextClass: 'next',
202
+ // The class for the "close" control:
203
+ closeClass: 'close',
204
+ // The class for the "play-pause" toggle control:
205
+ playPauseClass: 'play-pause',
206
+ // The class for the active indicator:
207
+ activeClass: 'active',
208
+ // The list object property (or data attribute) with the object type:
209
+ typeProperty: 'type',
210
+ // The list object property (or data attribute) with the object title:
211
+ titleProperty: 'title',
212
+ // The list object property (or data attribute) with the object URL:
213
+ urlProperty: 'href',
214
+ // The list object property (or data attribute) with the thumbnail URL,
215
+ // used as alternative to a thumbnail child element:
216
+ thumbnailProperty: 'thumbnail',
217
+ // The list object property (or data attribute) for the video poster URL:
218
+ videoPosterProperty: 'poster',
219
+ // The list object property (or data attribute) for the video sources array:
220
+ videoSourcesProperty: 'sources',
221
+ // Defines if the gallery indicators should display a thumbnail:
222
+ thumbnailIndicators: true,
223
+ // Defines if the gallery slides are cleared from the gallery modal,
224
+ // or reused for the next gallery initialization:
225
+ clearSlides: true,
226
+ // Defines if the gallery should open in fullscreen mode:
227
+ fullScreen: false,
228
+ // Defines if images should be stretched to fill the available space,
229
+ // while maintaining their aspect ratio (will only be enabled for browsers
230
+ // supporting background-size="contain", which excludes IE < 9):
231
+ stretchImages: false,
232
+ // Toggle the controls on pressing the Return key:
233
+ toggleControlsOnReturn: true,
234
+ // Toggle the automatic slideshow interval on pressing the Space key:
235
+ toggleSlideshowOnSpace: true,
236
+ // Navigate the gallery by pressing left and right on the keyboard:
237
+ enableKeyboardNavigation: true,
238
+ // Close the gallery on pressing the ESC key:
239
+ closeOnEscape: true,
240
+ // Close the gallery when clicking on an empty slide area:
241
+ closeOnSlideClick: true,
242
+ // Close the gallery by swiping up or down:
243
+ closeOnSwipeUpOrDown: true,
244
+ // Emulate touch events on mouse-pointer devices such as desktop browsers:
245
+ emulateTouchEvents: true,
246
+ // Hide the page scrollbars:
247
+ hidePageScrollbars: true,
248
+ // Stops any touches on the container from scrolling the page:
249
+ disableScroll: true,
250
+ // Carousel mode (shortcut for carousel specific options):
251
+ carousel: false,
252
+ // Allow continuous navigation, moving from last to first
253
+ // and from first to last slide:
254
+ continuous: true,
255
+ // Start with the automatic slideshow:
256
+ startSlideshow: false,
257
+ // Delay in milliseconds between slides for the automatic slideshow:
258
+ slideshowInterval: 5000,
259
+ // The starting index as integer.
260
+ // Can also be an object of the given list,
261
+ // or an equal object with the same url property:
262
+ index: 0,
263
+ // The number of elements to load around the current index:
264
+ preloadRange: 2,
265
+ // The transition speed between slide changes in milliseconds:
266
+ transitionSpeed: 400,
267
+ // The transition speed for automatic slide changes, set to an integer
268
+ // greater 0 to override the default transition speed:
269
+ slideshowTransitionSpeed: undefined,
270
+ // Callback function executed on slide change.
271
+ // Is called with the list object as "this" object and the
272
+ // current index and slide as arguments:
273
+ onslide: undefined,
274
+ // Callback function executed after the slide change transition.
275
+ // Is called with the list object as "this" object and the
276
+ // current index and slide as arguments:
277
+ onslideend: undefined,
278
+ // Callback function executed on slide content load.
279
+ // Is called with the list object as "this" object and the
280
+ // slide index and slide element as arguments:
281
+ onslidecomplete: undefined
282
+ },
283
+
284
+ carouselOptions: {
285
+ hidePageScrollbars: false,
286
+ toggleControlsOnReturn: false,
287
+ toggleSlideshowOnSpace: false,
288
+ enableKeyboardNavigation: false,
289
+ closeOnEscape: false,
290
+ closeOnSlideClick: false,
291
+ closeOnSwipeUpOrDown: false,
292
+ disableScroll: false,
293
+ startSlideshow: true
294
+ },
295
+
296
+ // Detect touch, transition, transform and background-size support:
297
+ support: (function (element) {
298
+ var support = {
299
+ touch: window.ontouchstart !== undefined ||
300
+ (window.DocumentTouch && document instanceof DocumentTouch)
301
+ },
302
+ transitions = {
303
+ webkitTransition: {
304
+ end: 'webkitTransitionEnd',
305
+ prefix: '-webkit-'
306
+ },
307
+ MozTransition: {
308
+ end: 'transitionend',
309
+ prefix: '-moz-'
310
+ },
311
+ OTransition: {
312
+ end: 'otransitionend',
313
+ prefix: '-o-'
314
+ },
315
+ transition: {
316
+ end: 'transitionend',
317
+ prefix: ''
318
+ }
319
+ },
320
+ prop,
321
+ transition,
322
+ translateZ;
323
+ for (prop in transitions) {
324
+ if (transitions.hasOwnProperty(prop) &&
325
+ element.style[prop] !== undefined) {
326
+ transition = transitions[prop];
327
+ transition.name = prop;
328
+ support.transition = transition;
329
+ break;
330
+ }
331
+ }
332
+ document.body.appendChild(element);
333
+ if (transition) {
334
+ prop = transition.name.slice(0, -9) + 'ransform';
335
+ if (element.style[prop] !== undefined) {
336
+ element.style[prop] = 'translateZ(0)';
337
+ translateZ = window.getComputedStyle(element)
338
+ .getPropertyValue(transition.prefix + 'transform');
339
+ support.transform = {
340
+ prefix: transition.prefix,
341
+ name: prop,
342
+ translate: true,
343
+ translateZ: translateZ && translateZ !== 'none'
344
+ };
345
+ }
346
+ }
347
+ if (element.style.backgroundSize !== undefined) {
348
+ element.style.backgroundSize = 'contain';
349
+ support.backgroundSize = {
350
+ contain: window.getComputedStyle(element)
351
+ .getPropertyValue('background-size') === 'contain'
352
+ };
353
+ }
354
+ document.body.removeChild(element);
355
+ return support;
356
+ // Test element, has to be standard HTML and must not be hidden
357
+ // for the CSS3 transform translateZ test to be applicable:
358
+ }(document.createElement('div'))),
359
+
360
+ slide: function (to, speed) {
361
+ window.clearTimeout(this.timeout);
362
+ var index = this.index,
363
+ direction,
364
+ natural_direction,
365
+ diff;
366
+ if (index === to || this.num === 1) {
367
+ return;
368
+ }
369
+ if (!speed) {
370
+ speed = this.options.transitionSpeed;
371
+ }
372
+ if (this.support.transition) {
373
+ if (!this.options.continuous) {
374
+ to = this.circle(to);
375
+ }
376
+ // 1: backward, -1: forward:
377
+ direction = Math.abs(index - to) / (index - to);
378
+ // Get the actual position of the slide:
379
+ if (this.options.continuous) {
380
+ natural_direction = direction;
381
+ direction = -this.positions[this.circle(to)] / this.slideWidth;
382
+ // If going forward but to < index, use to = slides.length + to
383
+ // If going backward but to > index, use to = -slides.length + to
384
+ if (direction !== natural_direction) {
385
+ to = -direction * this.num + to;
386
+ }
387
+ }
388
+ diff = Math.abs(index - to) - 1;
389
+ // Move all the slides between index and to in the right direction:
390
+ while (diff) {
391
+ diff -= 1;
392
+ this.move(
393
+ this.circle((to > index ? to : index) - diff - 1),
394
+ this.slideWidth * direction,
395
+ 0
396
+ );
397
+ }
398
+ to = this.circle(to);
399
+ this.move(index, this.slideWidth * direction, speed);
400
+ this.move(to, 0, speed);
401
+ if (this.options.continuous) {
402
+ this.move(
403
+ this.circle(to - direction),
404
+ -(this.slideWidth * direction),
405
+ 0
406
+ );
407
+ }
408
+ } else {
409
+ to = this.circle(to);
410
+ this.animate(index * -this.slideWidth, to * -this.slideWidth, speed);
411
+ }
412
+ this.index = to;
413
+ this.onslide(to);
414
+ },
415
+
416
+ getIndex: function () {
417
+ return this.index;
418
+ },
419
+
420
+ getNumber: function () {
421
+ return this.num;
422
+ },
423
+
424
+ prev: function () {
425
+ if (this.options.continuous || this.index) {
426
+ this.slide(this.index - 1);
427
+ }
428
+ },
429
+
430
+ next: function () {
431
+ if (this.options.continuous || this.index < this.num - 1) {
432
+ this.slide(this.index + 1);
433
+ }
434
+ },
435
+
436
+ play: function (time) {
437
+ window.clearTimeout(this.timeout);
438
+ this.interval = time || this.options.slideshowInterval;
439
+ if (this.status[this.index] > 1) {
440
+ this.timeout = this.setTimeout(
441
+ this.slide,
442
+ [this.index + 1, this.options.slideshowTransitionSpeed],
443
+ this.interval
444
+ );
445
+ }
446
+ this.helper.addClass(this.container, this.options.playingClass);
447
+ },
448
+
449
+ pause: function () {
450
+ window.clearTimeout(this.timeout);
451
+ this.interval = null;
452
+ this.helper.removeClass(this.container, this.options.playingClass);
453
+ },
454
+
455
+ add: function (list) {
456
+ var i;
457
+ this.list = this.list.concat(list);
458
+ this.num = this.list.length;
459
+ if (this.num > 2 && this.options.continuous === null) {
460
+ this.options.continuous = true;
461
+ this.helper.removeClass(this.container, this.options.leftEdgeClass);
462
+ }
463
+ this.helper.removeClass(this.container, this.options.rightEdgeClass);
464
+ this.helper.removeClass(this.container, this.options.singleClass);
465
+ for (i = this.num - list.length; i < this.num; i += 1) {
466
+ this.addSlide(i);
467
+ this.positionSlide(i);
468
+ this.addIndicator(i);
469
+ }
470
+ this.elements.length =
471
+ this.status.length =
472
+ this.positions.length = this.num;
473
+ this.initSlides(true);
474
+ },
475
+
476
+ close: function () {
477
+ var helper = this.helper,
478
+ options = this.options;
479
+ if (this.getFullScreenElement() === this.container) {
480
+ this.exitFullScreen();
481
+ }
482
+ this.container.style.display = 'none';
483
+ helper.removeClass(this.container, options.displayClass);
484
+ helper.removeClass(this.container, options.singleClass);
485
+ helper.removeClass(this.container, options.leftEdgeClass);
486
+ helper.removeClass(this.container, options.rightEdgeClass);
487
+ if (options.hidePageScrollbars) {
488
+ document.body.style.overflow = this.bodyOverflowStyle;
489
+ }
490
+ this.destroyEventListeners();
491
+ // Cancel the slideshow:
492
+ this.pause();
493
+ // Reset the slides:
494
+ if (options.clearSlides) {
495
+ helper.empty(this.slidesContainer);
496
+ if (this.indicatorContainer) {
497
+ helper.empty(this.indicatorContainer);
498
+ }
499
+ } else {
500
+ if (this.activeIndicator) {
501
+ helper.removeClass(this.activeIndicator, options.activeClass);
502
+ }
503
+ }
504
+ },
505
+
506
+ circle: function (index) {
507
+ // Always return a number inside of the slides index range:
508
+ return (this.num + (index % this.num)) % this.num;
509
+ },
510
+
511
+ move: function (index, dist, speed) {
512
+ this.translateX(index, dist, speed);
513
+ this.positions[index] = dist;
514
+ },
515
+
516
+ translate: function (index, x, y, speed) {
517
+ var style = this.slides[index].style,
518
+ transition = this.support.transition,
519
+ transform = this.support.transform;
520
+ style[transition.name + 'Duration'] = speed + 'ms';
521
+ style[transform.name] = 'translate(' + x + 'px, ' + y + 'px)' +
522
+ (transform.translateZ ? ' translateZ(0)' : '');
523
+ },
524
+
525
+ translateX: function (index, x, speed) {
526
+ this.translate(index, x, 0, speed);
527
+ },
528
+
529
+ translateY: function (index, y, speed) {
530
+ this.translate(index, 0, y, speed);
531
+ },
532
+
533
+ animate: function (from, to, speed) {
534
+ if (!speed) {
535
+ this.slidesContainer.style.left = to + 'px';
536
+ return;
537
+ }
538
+ var that = this,
539
+ start = new Date().getTime(),
540
+ timer = window.setInterval(function () {
541
+ var timeElap = new Date().getTime() - start;
542
+ if (timeElap > speed) {
543
+ that.slidesContainer.style.left = to + 'px';
544
+ that.ontransitionend();
545
+ window.clearInterval(timer);
546
+ return;
547
+ }
548
+ that.slidesContainer.style.left = (((to - from) *
549
+ (Math.floor((timeElap / speed) * 100) / 100)) + from) + 'px';
550
+ }, 4);
551
+ },
552
+
553
+ onresize: function () {
554
+ this.initSlides(true);
555
+ },
556
+
557
+ onmousedown: function (event) {
558
+ // Trigger on clicks of the left mouse button only:
559
+ if (event.which && event.which === 1) {
560
+ event.touches = [{
561
+ pageX: event.pageX,
562
+ pageY: event.pageY
563
+ }];
564
+ this.ontouchstart(event);
565
+ }
566
+ },
567
+
568
+ onmousemove: function (event) {
569
+ if (this.touchStart) {
570
+ event.touches = [{
571
+ pageX: event.pageX,
572
+ pageY: event.pageY
573
+ }];
574
+ this.ontouchmove(event);
575
+ }
576
+ },
577
+
578
+ onmouseup: function (event) {
579
+ if (this.touchStart) {
580
+ this.ontouchend(event);
581
+ delete this.touchStart;
582
+ }
583
+ },
584
+
585
+ onmouseout: function (event) {
586
+ if (this.touchStart) {
587
+ var target = event.target,
588
+ related = event.relatedTarget;
589
+ if (!related || (related !== target &&
590
+ !this.helper.contains(target, related))) {
591
+ this.onmouseup(event);
592
+ }
593
+ }
594
+ },
595
+
596
+ ontouchstart: function (event) {
597
+ var touches = event.touches[0];
598
+ this.touchStart = {
599
+ // Remember the initial touch coordinates:
600
+ x: touches.pageX,
601
+ y: touches.pageY,
602
+ // Store the time to determine touch duration:
603
+ time: Date.now()
604
+ };
605
+ // Helper variable to detect scroll movement:
606
+ this.isScrolling = undefined;
607
+ // Reset delta values:
608
+ this.touchDelta = {};
609
+ },
610
+
611
+ ontouchmove: function (event) {
612
+ // Ensure this is a one touch swipe and not, e.g. a pinch:
613
+ if (event.touches.length > 1 || (event.scale && event.scale !== 1)) {
614
+ return;
615
+ }
616
+ if (this.options.disableScroll) {
617
+ event.preventDefault();
618
+ }
619
+ var touches = event.touches[0],
620
+ index = this.index,
621
+ touchDeltaX,
622
+ indices;
623
+ // Measure change in x and y coordinates:
624
+ this.touchDelta = {
625
+ x: touches.pageX - this.touchStart.x,
626
+ y: touches.pageY - this.touchStart.y
627
+ };
628
+ touchDeltaX = this.touchDelta.x;
629
+ // Detect if this is a vertical scroll movement (run only once per touch):
630
+ if (this.isScrolling === undefined) {
631
+ this.isScrolling = this.isScrolling ||
632
+ Math.abs(touchDeltaX) < Math.abs(this.touchDelta.y);
633
+ }
634
+ if (!this.isScrolling) {
635
+ // Always prevent horizontal scroll:
636
+ event.preventDefault();
637
+ // Stop the slideshow:
638
+ window.clearTimeout(this.timeout);
639
+ if (this.options.continuous) {
640
+ indices = [
641
+ this.circle(index + 1),
642
+ index,
643
+ this.circle(index - 1)
644
+ ];
645
+ } else {
646
+ // Increase resistance if first slide and sliding left
647
+ // or last slide and sliding right:
648
+ this.touchDelta.x = touchDeltaX =
649
+ touchDeltaX /
650
+ (((!index && touchDeltaX > 0) ||
651
+ (index === this.num - 1 && touchDeltaX < 0)) ?
652
+ (Math.abs(touchDeltaX) / this.slideWidth + 1) : 1);
653
+ indices = [index];
654
+ if (index) {
655
+ indices.push(index - 1);
656
+ }
657
+ if (index < this.num - 1) {
658
+ indices.unshift(index + 1);
659
+ }
660
+ }
661
+ while (indices.length) {
662
+ index = indices.pop();
663
+ this.translateX(index, touchDeltaX + this.positions[index], 0);
664
+ }
665
+ } else if (this.options.closeOnSwipeUpOrDown) {
666
+ this.translateY(index, this.touchDelta.y + this.positions[index], 0);
667
+ }
668
+ },
669
+
670
+ ontouchend: function () {
671
+ var index = this.index,
672
+ speed = this.options.transitionSpeed,
673
+ slideWidth = this.slideWidth,
674
+ isShortDuration = Number(Date.now() - this.touchStart.time) < 250,
675
+ // Determine if slide attempt triggers next/prev slide:
676
+ isValidSlide = (isShortDuration && Math.abs(this.touchDelta.x) > 20) ||
677
+ Math.abs(this.touchDelta.x) > slideWidth / 2,
678
+ // Determine if slide attempt is past start or end:
679
+ isPastBounds = (!index && this.touchDelta.x > 0)
680
+ || (index === this.num - 1 && this.touchDelta.x < 0),
681
+ isValidClose = !isValidSlide && this.options.closeOnSwipeUpOrDown &&
682
+ ((isShortDuration && Math.abs(this.touchDelta.y) > 20) ||
683
+ Math.abs(this.touchDelta.y) > this.slideHeight / 2),
684
+ direction,
685
+ indexForward,
686
+ indexBackward,
687
+ distanceForward,
688
+ distanceBackward;
689
+ if (this.options.continuous) {
690
+ isPastBounds = false;
691
+ }
692
+ // Determine direction of swipe (true: right, false: left):
693
+ direction = this.touchDelta.x < 0 ? -1 : 1;
694
+ if (!this.isScrolling) {
695
+ if (isValidSlide && !isPastBounds) {
696
+ indexForward = index + direction;
697
+ indexBackward = index - direction;
698
+ distanceForward = slideWidth * direction;
699
+ distanceBackward = -slideWidth * direction;
700
+ if (this.options.continuous) {
701
+ this.move(this.circle(indexForward), distanceForward, 0);
702
+ this.move(this.circle(index - 2 * direction), distanceBackward, 0);
703
+ } else if (indexForward >= 0 &&
704
+ indexForward < this.num) {
705
+ this.move(indexForward, distanceForward, 0);
706
+ }
707
+ this.move(index, this.positions[index] + distanceForward, speed);
708
+ this.move(
709
+ this.circle(indexBackward),
710
+ this.positions[this.circle(indexBackward)] + distanceForward,
711
+ speed
712
+ );
713
+ index = this.circle(indexBackward);
714
+ this.onslide(index);
715
+ } else {
716
+ // Move back into position
717
+ if (this.options.continuous) {
718
+ this.move(this.circle(index - 1), -slideWidth, speed);
719
+ this.move(index, 0, speed);
720
+ this.move(this.circle(index + 1), slideWidth, speed);
721
+ } else {
722
+ if (index) {
723
+ this.move(index - 1, -slideWidth, speed);
724
+ }
725
+ this.move(index, 0, speed);
726
+ if (index < this.num - 1) {
727
+ this.move(index + 1, slideWidth, speed);
728
+ }
729
+ }
730
+ }
731
+ } else {
732
+ if (isValidClose) {
733
+ this.close();
734
+ } else {
735
+ // Move back into position
736
+ this.translateY(index, 0, speed);
737
+ }
738
+ }
739
+ this.index = index;
740
+ },
741
+
742
+ ontransitionend: function (event) {
743
+ var slide = this.slides[this.index];
744
+ if (!event || slide === event.target) {
745
+ if (this.interval) {
746
+ this.play();
747
+ }
748
+ this.setTimeout(
749
+ this.options.onslideend,
750
+ [this.index, slide]
751
+ );
752
+ }
753
+ },
754
+
755
+ oncomplete: function (event) {
756
+ var target = event.target || event.srcElement,
757
+ parent = target && target.parentNode,
758
+ index;
759
+ if (!target || !parent) {
760
+ return;
761
+ }
762
+ index = this.getNodeIndex(parent);
763
+ this.helper.removeClass(parent, this.options.slideLoadingClass);
764
+ if (event.type === 'error') {
765
+ this.helper.addClass(parent, this.options.slideErrorClass);
766
+ this.status[index] = 3; // Fail
767
+ } else {
768
+ this.status[index] = 2; // Done
769
+ }
770
+ // Fix for IE7's lack of support for percentage max-height:
771
+ if (target.clientHeight > this.container.clientHeight) {
772
+ target.style.maxHeight = this.container.clientHeight;
773
+ }
774
+ if (this.interval && this.slides[this.index] === parent) {
775
+ this.play();
776
+ }
777
+ this.setTimeout(
778
+ this.options.onslidecomplete,
779
+ [index, parent]
780
+ );
781
+ },
782
+
783
+ onload: function (event) {
784
+ this.oncomplete(event);
785
+ },
786
+
787
+ onerror: function (event) {
788
+ this.oncomplete(event);
789
+ },
790
+
791
+ onkeydown: function (event) {
792
+ switch (event.which || event.keyCode) {
793
+ case 13: // Return
794
+ if (this.options.toggleControlsOnReturn) {
795
+ this.helper.preventDefault(event);
796
+ this.toggleControls();
797
+ }
798
+ break;
799
+ case 27: // ESC
800
+ if (this.options.closeOnEscape) {
801
+ this.close();
802
+ }
803
+ break;
804
+ case 32: // Space
805
+ if (this.options.toggleSlideshowOnSpace) {
806
+ this.helper.preventDefault(event);
807
+ this.toggleSlideshow();
808
+ }
809
+ break;
810
+ case 37: // left
811
+ if (this.options.enableKeyboardNavigation) {
812
+ this.helper.preventDefault(event);
813
+ this.prev();
814
+ }
815
+ break;
816
+ case 39: // right
817
+ if (this.options.enableKeyboardNavigation) {
818
+ this.helper.preventDefault(event);
819
+ this.next();
820
+ }
821
+ break;
822
+ }
823
+ },
824
+
825
+ onclick: function (event) {
826
+ if (this.options.emulateTouchEvents &&
827
+ this.touchDelta && (Math.abs(this.touchDelta.x) > 20 ||
828
+ Math.abs(this.touchDelta.y) > 20)) {
829
+ delete this.touchDelta;
830
+ return;
831
+ }
832
+ var options = this.options,
833
+ target = event.target || event.srcElement,
834
+ parent = target.parentNode,
835
+ helper = this.helper,
836
+ isTarget = function (className) {
837
+ return helper.hasClass(target, className) ||
838
+ helper.hasClass(parent, className);
839
+ };
840
+ if (parent === this.slidesContainer) {
841
+ // Click on slide background
842
+ helper.preventDefault(event);
843
+ if (options.closeOnSlideClick) {
844
+ this.close();
845
+ } else {
846
+ this.toggleControls();
847
+ }
848
+ } else if (parent.parentNode &&
849
+ parent.parentNode === this.slidesContainer) {
850
+ // Click on displayed element
851
+ helper.preventDefault(event);
852
+ this.toggleControls();
853
+ } else if (parent === this.indicatorContainer) {
854
+ // Click on indicator element
855
+ helper.preventDefault(event);
856
+ this.slide(this.getNodeIndex(target));
857
+ } else if (parent.parentNode === this.indicatorContainer) {
858
+ // Click on indicator child element
859
+ helper.preventDefault(event);
860
+ this.slide(this.getNodeIndex(parent));
861
+ } else if (isTarget(options.toggleClass)) {
862
+ // Click on "toggle" control
863
+ helper.preventDefault(event);
864
+ this.toggleControls();
865
+ } else if (isTarget(options.prevClass)) {
866
+ // Click on "prev" control
867
+ helper.preventDefault(event);
868
+ this.prev();
869
+ } else if (isTarget(options.nextClass)) {
870
+ // Click on "next" control
871
+ helper.preventDefault(event);
872
+ this.next();
873
+ } else if (isTarget(options.closeClass)) {
874
+ // Click on "close" control
875
+ helper.preventDefault(event);
876
+ this.close();
877
+ } else if (isTarget(options.playPauseClass)) {
878
+ // Click on "play-pause" control
879
+ helper.preventDefault(event);
880
+ this.toggleSlideshow();
881
+ }
882
+ },
883
+
884
+ updateEdgeClasses: function (index) {
885
+ if (!index) {
886
+ this.helper.addClass(this.container, this.options.leftEdgeClass);
887
+ } else {
888
+ this.helper.removeClass(this.container, this.options.leftEdgeClass);
889
+ }
890
+ if (index === this.num - 1) {
891
+ this.helper.addClass(this.container, this.options.rightEdgeClass);
892
+ } else {
893
+ this.helper.removeClass(this.container, this.options.rightEdgeClass);
894
+ }
895
+ },
896
+
897
+ onslide: function (index) {
898
+ if (!this.options.continuous) {
899
+ this.updateEdgeClasses(index);
900
+ }
901
+ this.loadElements(index);
902
+ this.setTitle(index);
903
+ this.setActiveIndicator(index);
904
+ this.setTimeout(this.options.onslide, [index, this.slides[index]]);
905
+ },
906
+
907
+ setTitle: function (index) {
908
+ var text = this.elements[index].title,
909
+ titleElement = this.titleElement;
910
+ if (titleElement) {
911
+ this.helper.empty(titleElement);
912
+ if (text) {
913
+ titleElement.appendChild(document.createTextNode(text));
914
+ }
915
+ }
916
+ },
917
+
918
+ setActiveIndicator: function (index) {
919
+ if (this.indicators) {
920
+ if (this.activeIndicator) {
921
+ this.helper.removeClass(this.activeIndicator, this.options.activeClass);
922
+ }
923
+ this.activeIndicator = this.indicators[index];
924
+ this.helper.addClass(this.activeIndicator, this.options.activeClass);
925
+ }
926
+ },
927
+
928
+ setTimeout: function (func, args, wait) {
929
+ var that = this;
930
+ return func && window.setTimeout(function () {
931
+ func.apply(that, args || []);
932
+ }, wait || 0);
933
+ },
934
+
935
+ videoFactory: function (obj, callback) {
936
+ var that = this,
937
+ options = this.options,
938
+ videoContainer = this.elementPrototype.cloneNode(false),
939
+ errorArgs = [{
940
+ type: 'error',
941
+ target: videoContainer
942
+ }],
943
+ video = document.createElement('video'),
944
+ url = this.getItemProperty(obj, options.urlProperty),
945
+ type = this.getItemProperty(obj, options.typeProperty),
946
+ title = this.getItemProperty(obj, options.titleProperty),
947
+ posterUrl = this.getItemProperty(obj, options.videoPosterProperty),
948
+ posterImage,
949
+ sources = this.getItemProperty(
950
+ obj,
951
+ options.videoSourcesProperty
952
+ ),
953
+ source,
954
+ playMediaControl,
955
+ isLoading,
956
+ hasControls;
957
+ this.helper.addClass(videoContainer, options.videoContentClass);
958
+ if (title) {
959
+ videoContainer.title = title;
960
+ }
961
+ if (video.canPlayType) {
962
+ if (url && type && video.canPlayType(type)) {
963
+ video.src = url;
964
+ } else if (sources) {
965
+ if (typeof sources === 'string') {
966
+ sources = this.helper.parseJSON(sources);
967
+ }
968
+ while (sources && sources.length) {
969
+ source = sources.shift();
970
+ url = this.getItemProperty(source, options.urlProperty);
971
+ type = this.getItemProperty(source, options.typeProperty);
972
+ if (url && type && video.canPlayType(type)) {
973
+ video.src = url;
974
+ break;
975
+ }
976
+ }
977
+ }
978
+ }
979
+ if (posterUrl) {
980
+ video.setAttribute('poster', posterUrl);
981
+ posterImage = this.imagePrototype.cloneNode(false);
982
+ this.helper.addClass(posterImage, options.toggleClass);
983
+ posterImage.src = posterUrl;
984
+ posterImage.draggable = false;
985
+ videoContainer.appendChild(posterImage);
986
+ }
987
+ playMediaControl = document.createElement('a');
988
+ playMediaControl.setAttribute('target', '_blank');
989
+ playMediaControl.setAttribute('download', title);
990
+ playMediaControl.href = url;
991
+ if (video.src) {
992
+ video.controls = true;
993
+ this.helper.addListener(video, 'error', function () {
994
+ that.setTimeout(callback, errorArgs);
995
+ });
996
+ this.helper.addListener(video, 'pause', function () {
997
+ isLoading = false;
998
+ that.helper.removeClass(videoContainer, that.options.videoLoadingClass);
999
+ that.helper.removeClass(videoContainer, that.options.videoPlayingClass);
1000
+ if (hasControls) {
1001
+ that.helper.addClass(that.container, that.options.controlsClass);
1002
+ }
1003
+ if (that.interval) {
1004
+ that.play();
1005
+ }
1006
+ });
1007
+ this.helper.addListener(video, 'playing', function () {
1008
+ isLoading = false;
1009
+ that.helper.removeClass(videoContainer, that.options.videoLoadingClass);
1010
+ that.helper.addClass(videoContainer, that.options.videoPlayingClass);
1011
+ if (that.helper.hasClass(that.container, that.options.controlsClass)) {
1012
+ hasControls = true;
1013
+ that.helper.removeClass(that.container, that.options.controlsClass);
1014
+ } else {
1015
+ hasControls = false;
1016
+ }
1017
+ });
1018
+ this.helper.addListener(video, 'play', function () {
1019
+ window.clearTimeout(that.timeout);
1020
+ isLoading = true;
1021
+ that.helper.addClass(videoContainer, that.options.videoLoadingClass);
1022
+ });
1023
+ this.helper.addListener(playMediaControl, 'click', function (event) {
1024
+ event.preventDefault();
1025
+ if (isLoading) {
1026
+ video.pause();
1027
+ } else {
1028
+ video.play();
1029
+ }
1030
+ });
1031
+ videoContainer.appendChild(video);
1032
+ }
1033
+ videoContainer.appendChild(playMediaControl);
1034
+ this.setTimeout(callback, [{
1035
+ type: 'load',
1036
+ target: videoContainer
1037
+ }]);
1038
+ return videoContainer;
1039
+ },
1040
+
1041
+ imageFactory: function (obj, callback) {
1042
+ var img = this.imagePrototype.cloneNode(false),
1043
+ element,
1044
+ url = obj,
1045
+ title;
1046
+ if (typeof url !== 'string') {
1047
+ url = this.getItemProperty(obj, this.options.urlProperty);
1048
+ title = this.getItemProperty(obj, this.options.titleProperty);
1049
+ }
1050
+ if (this.options.stretchImages && this.support.backgroundSize &&
1051
+ this.support.backgroundSize.contain) {
1052
+ element = this.elementPrototype.cloneNode(false);
1053
+ this.helper.addListener(img, 'load', function () {
1054
+ element.style.background = 'url("' + url + '") center no-repeat';
1055
+ element.style.backgroundSize = 'contain';
1056
+ callback({
1057
+ type: 'load',
1058
+ target: element
1059
+ });
1060
+ });
1061
+ this.helper.addListener(img, 'error', function () {
1062
+ callback({
1063
+ type: 'error',
1064
+ target: element
1065
+ });
1066
+ });
1067
+ } else {
1068
+ element = img;
1069
+ img.draggable = false;
1070
+ this.helper.addListener(img, 'load', callback);
1071
+ this.helper.addListener(img, 'error', callback);
1072
+ }
1073
+ if (title) {
1074
+ element.title = title;
1075
+ }
1076
+ img.src = url;
1077
+ // Fix for IE7 not firing load events for cached images:
1078
+ if (img.complete) {
1079
+ this.setTimeout(callback, [{
1080
+ type: 'load',
1081
+ target: element
1082
+ }]);
1083
+ }
1084
+ return element;
1085
+ },
1086
+
1087
+ createElement: function (obj, callback) {
1088
+ var type = obj && this.getItemProperty(obj, this.options.typeProperty),
1089
+ factory = (type && this[type.split('/')[0] + 'Factory']) ||
1090
+ this.imageFactory,
1091
+ element = obj && factory.call(this, obj, callback);
1092
+ if (!element) {
1093
+ element = this.elementPrototype.cloneNode(false);
1094
+ this.setTimeout(callback, [{
1095
+ type: 'error',
1096
+ target: element
1097
+ }]);
1098
+ }
1099
+ this.helper.addClass(element, this.options.slideContentClass);
1100
+ return element;
1101
+ },
1102
+
1103
+ createIndicator: function (obj) {
1104
+ var indicator = this.indicatorPrototype.cloneNode(false),
1105
+ thumbnailProperty = this.options.thumbnailProperty,
1106
+ thumbnailUrl,
1107
+ thumbnail,
1108
+ title = this.getItemProperty(obj, this.options.titleProperty);
1109
+ if (this.options.thumbnailIndicators) {
1110
+ thumbnail = obj.getElementsByTagName && this.helper.query(obj, 'img');
1111
+ if (thumbnail) {
1112
+ thumbnail = thumbnail.cloneNode(false);
1113
+ } else if (thumbnailProperty) {
1114
+ thumbnailUrl = this.getItemProperty(obj, thumbnailProperty);
1115
+ if (thumbnailUrl) {
1116
+ thumbnail = this.thumbnailPrototype.cloneNode(false);
1117
+ thumbnail.src = thumbnailUrl;
1118
+ }
1119
+ }
1120
+ if (thumbnail) {
1121
+ indicator.appendChild(thumbnail);
1122
+ }
1123
+ }
1124
+ if (title && !(thumbnail && thumbnail.title)) {
1125
+ indicator.title = title;
1126
+ }
1127
+ return indicator;
1128
+ },
1129
+
1130
+ loadElement: function (index) {
1131
+ if (!this.elements[index]) {
1132
+ if (this.slides[index].firstChild) {
1133
+ this.elements[index] = this.slides[index].firstChild;
1134
+ } else {
1135
+ this.helper.addClass(this.slides[index], this.options.slideLoadingClass);
1136
+ this.elements[index] = this.createElement(
1137
+ this.list[index],
1138
+ this.proxyListener
1139
+ );
1140
+ this.slides[index].appendChild(this.elements[index]);
1141
+ }
1142
+ }
1143
+ },
1144
+
1145
+ loadElements: function (index) {
1146
+ if (this.status[index]) {
1147
+ return;
1148
+ }
1149
+ this.status[index] = 1; // Loading
1150
+ var limit = Math.min(this.num, this.options.preloadRange * 2 + 1),
1151
+ j = index,
1152
+ i;
1153
+ for (i = 0; i < limit; i += 1) {
1154
+ // First load the current slide element (0),
1155
+ // then the next one (+1),
1156
+ // then the previous one (-2),
1157
+ // then the next after next (+2), etc.:
1158
+ j += i * (i % 2 === 0 ? -1 : 1);
1159
+ // Connect the ends of the list to load slide elements for
1160
+ // continuous navigation:
1161
+ j = this.circle(j);
1162
+ this.loadElement(j);
1163
+ }
1164
+ },
1165
+
1166
+ addIndicator: function (index) {
1167
+ if (this.indicators) {
1168
+ var indicator = this.createIndicator(this.list[index]);
1169
+ indicator.setAttribute('data-index', index);
1170
+ this.indicatorContainer.appendChild(indicator);
1171
+ this.indicators.push(indicator);
1172
+ }
1173
+ },
1174
+
1175
+ addSlide: function (index) {
1176
+ var slide = this.slidePrototype.cloneNode(false);
1177
+ slide.setAttribute('data-index', index);
1178
+ this.slidesContainer.appendChild(slide);
1179
+ this.slides.push(slide);
1180
+ },
1181
+
1182
+ positionSlide: function (index) {
1183
+ var slide = this.slides[index];
1184
+ slide.style.width = this.slideWidth + 'px';
1185
+ if (this.support.transition) {
1186
+ slide.style.left = (index * -this.slideWidth) + 'px';
1187
+ this.move(index, this.index > index ? -this.slideWidth :
1188
+ (this.index < index ? this.slideWidth : 0), 0);
1189
+ }
1190
+ },
1191
+
1192
+ initSlides: function (reload) {
1193
+ var clearSlides,
1194
+ i;
1195
+ if (!reload) {
1196
+ this.elements = [];
1197
+ this.status = [];
1198
+ this.positions = [];
1199
+ this.elements.length =
1200
+ this.status.length =
1201
+ this.positions.length = this.num;
1202
+ this.imagePrototype = document.createElement('img');
1203
+ this.elementPrototype = document.createElement('div');
1204
+ this.slidePrototype = document.createElement('div');
1205
+ this.helper.addClass(this.slidePrototype, this.options.slideClass);
1206
+ if (this.indicatorContainer) {
1207
+ this.indicatorPrototype = document.createElement('li');
1208
+ if (this.options.thumbnailIndicators) {
1209
+ this.thumbnailPrototype = this.imagePrototype.cloneNode(false);
1210
+ }
1211
+ this.indicators = this.indicatorContainer.children;
1212
+ }
1213
+ this.slides = this.slidesContainer.children;
1214
+ clearSlides = this.options.clearSlides || this.slides.length !== this.num;
1215
+ }
1216
+ this.slideWidth = this.container.offsetWidth;
1217
+ this.slideHeight = this.container.offsetHeight;
1218
+ this.slidesContainer.style.width = (this.num * this.slideWidth) + 'px';
1219
+ if (clearSlides) {
1220
+ this.helper.empty(this.slidesContainer);
1221
+ if (this.indicatorContainer) {
1222
+ this.helper.empty(this.indicatorContainer);
1223
+ }
1224
+ this.slides = [];
1225
+ if (this.indicatorContainer) {
1226
+ this.indicators = [];
1227
+ }
1228
+ }
1229
+ for (i = 0; i < this.num; i += 1) {
1230
+ if (clearSlides) {
1231
+ this.addIndicator(i);
1232
+ this.addSlide(i);
1233
+ }
1234
+ this.positionSlide(i);
1235
+ }
1236
+ // Reposition the slides before and after the given index:
1237
+ if (this.options.continuous && this.support.transition) {
1238
+ this.move(this.circle(this.index - 1), -this.slideWidth, 0);
1239
+ this.move(this.circle(this.index + 1), this.slideWidth, 0);
1240
+ }
1241
+ if (!this.support.transition) {
1242
+ this.slidesContainer.style.left = (this.index * -this.slideWidth) + 'px';
1243
+ }
1244
+ },
1245
+
1246
+ getFullScreenElement: function () {
1247
+ return document.fullscreenElement ||
1248
+ document.webkitFullscreenElement ||
1249
+ document.mozFullScreenElement;
1250
+ },
1251
+
1252
+ requestFullScreen: function (element) {
1253
+ if (element.requestFullscreen) {
1254
+ element.requestFullscreen();
1255
+ } else if (element.webkitRequestFullscreen) {
1256
+ element.webkitRequestFullscreen();
1257
+ } else if (element.mozRequestFullScreen) {
1258
+ element.mozRequestFullScreen();
1259
+ }
1260
+ },
1261
+
1262
+ exitFullScreen: function () {
1263
+ if (document.exitFullscreen) {
1264
+ document.exitFullscreen();
1265
+ } else if (document.webkitCancelFullScreen) {
1266
+ document.webkitCancelFullScreen();
1267
+ } else if (document.mozCancelFullScreen) {
1268
+ document.mozCancelFullScreen();
1269
+ }
1270
+ },
1271
+
1272
+ toggleControls: function () {
1273
+ var controlsClass = this.options.controlsClass;
1274
+ if (this.helper.hasClass(this.container, controlsClass)) {
1275
+ this.helper.removeClass(this.container, controlsClass);
1276
+ } else {
1277
+ this.helper.addClass(this.container, controlsClass);
1278
+ }
1279
+ },
1280
+
1281
+ toggleSlideshow: function () {
1282
+ if (!this.interval) {
1283
+ this.play();
1284
+ } else {
1285
+ this.pause();
1286
+ }
1287
+ },
1288
+
1289
+ getNodeIndex: function (element) {
1290
+ return parseInt(element.getAttribute('data-index'), 10);
1291
+ },
1292
+
1293
+ getItemProperty: function (obj, property) {
1294
+ return obj[property] || (obj.getAttribute &&
1295
+ obj.getAttribute('data-' + property)) ||
1296
+ this.helper.getNestedProperty(obj, property);
1297
+ },
1298
+
1299
+ initStartIndex: function () {
1300
+ var index = this.options.index,
1301
+ urlProperty = this.options.urlProperty,
1302
+ i;
1303
+ // Check if the index is given as a list object:
1304
+ if (index && typeof index !== 'number') {
1305
+ for (i = 0; i < this.num; i += 1) {
1306
+ if (this.list[i] === index ||
1307
+ this.getItemProperty(this.list[i], urlProperty) ===
1308
+ this.getItemProperty(index, urlProperty)) {
1309
+ index = i;
1310
+ break;
1311
+ }
1312
+ }
1313
+ }
1314
+ // Make sure the index is in the list range:
1315
+ this.index = this.circle(parseInt(index, 10) || 0);
1316
+ },
1317
+
1318
+ initEventListeners: function () {
1319
+ var that = this,
1320
+ helper = this.helper,
1321
+ slidesContainer = this.slidesContainer,
1322
+ proxyListener = function (event) {
1323
+ var type = that.support.transition &&
1324
+ that.support.transition.end === event.type ?
1325
+ 'transitionend' : event.type;
1326
+ that['on' + type](event);
1327
+ };
1328
+ helper.addListener(window, 'resize', proxyListener);
1329
+ helper.addListener(document.body, 'keydown', proxyListener);
1330
+ helper.addListener(this.container, 'click', proxyListener);
1331
+ if (this.support.touch) {
1332
+ slidesContainer.addEventListener('touchstart', proxyListener, false);
1333
+ slidesContainer.addEventListener('touchmove', proxyListener, false);
1334
+ slidesContainer.addEventListener('touchend', proxyListener, false);
1335
+ } else if (this.options.emulateTouchEvents && slidesContainer.addEventListener) {
1336
+ slidesContainer.addEventListener('mousedown', proxyListener, false);
1337
+ slidesContainer.addEventListener('mousemove', proxyListener, false);
1338
+ slidesContainer.addEventListener('mouseup', proxyListener, false);
1339
+ slidesContainer.addEventListener('mouseout', proxyListener, false);
1340
+ }
1341
+ if (this.support.transition) {
1342
+ slidesContainer.addEventListener(
1343
+ this.support.transition.end,
1344
+ proxyListener,
1345
+ false
1346
+ );
1347
+ }
1348
+ this.proxyListener = proxyListener;
1349
+ },
1350
+
1351
+ destroyEventListeners: function () {
1352
+ var helper = this.helper,
1353
+ slidesContainer = this.slidesContainer,
1354
+ proxyListener = this.proxyListener;
1355
+ helper.removeListener(window, 'resize', proxyListener);
1356
+ helper.removeListener(document.body, 'keydown', proxyListener);
1357
+ helper.removeListener(this.container, 'click', proxyListener);
1358
+ if (this.support.touch) {
1359
+ slidesContainer.removeEventListener('touchstart', proxyListener, false);
1360
+ slidesContainer.removeEventListener('touchmove', proxyListener, false);
1361
+ slidesContainer.removeEventListener('touchend', proxyListener, false);
1362
+ } else if (this.options.emulateTouchEvents && slidesContainer.removeEventListener) {
1363
+ slidesContainer.removeEventListener('mousedown', proxyListener, false);
1364
+ slidesContainer.removeEventListener('mousemove', proxyListener, false);
1365
+ slidesContainer.removeEventListener('mouseup', proxyListener, false);
1366
+ slidesContainer.removeEventListener('mouseout', proxyListener, false);
1367
+ }
1368
+ if (this.support.transition) {
1369
+ slidesContainer.removeEventListener(
1370
+ this.support.transition.end,
1371
+ proxyListener,
1372
+ false
1373
+ );
1374
+ }
1375
+ },
1376
+
1377
+ initWidget: function () {
1378
+ this.container = this.helper.query(
1379
+ document,
1380
+ this.options.container
1381
+ );
1382
+ if (!this.container) {
1383
+ return false;
1384
+ }
1385
+ this.slidesContainer = this.helper.query(
1386
+ this.container,
1387
+ this.options.slidesContainer
1388
+ );
1389
+ if (!this.slidesContainer) {
1390
+ return false;
1391
+ }
1392
+ this.titleElement = this.helper.query(
1393
+ this.container,
1394
+ this.options.titleElement
1395
+ );
1396
+ this.indicatorContainer = this.helper.query(
1397
+ this.container,
1398
+ this.options.indicatorContainer
1399
+ );
1400
+ if (this.options.hidePageScrollbars) {
1401
+ // Hide the page scrollbars:
1402
+ this.bodyOverflowStyle = document.body.style.overflow;
1403
+ document.body.style.overflow = 'hidden';
1404
+ }
1405
+ if (this.num === 1) {
1406
+ this.helper.addClass(this.container, this.options.singleClass);
1407
+ }
1408
+ this.container.style.display = 'block';
1409
+ this.initSlides();
1410
+ this.helper.addClass(this.container, this.options.displayClass);
1411
+ },
1412
+
1413
+ initOptions: function (options) {
1414
+ // Create a copy of the prototype options:
1415
+ this.options = this.helper.extend({}, this.options);
1416
+ // Check if carousel mode is enabled:
1417
+ if ((options && options.carousel) ||
1418
+ (this.options.carousel && (!options || options.carousel !== false))) {
1419
+ this.helper.extend(this.options, this.carouselOptions);
1420
+ }
1421
+ // Override any given options:
1422
+ this.helper.extend(this.options, options);
1423
+ if (this.num < 3) {
1424
+ // 1 or 2 slides cannot be displayed continuous,
1425
+ // remember the original option by setting to null instead of false:
1426
+ this.options.continuous = this.options.continuous ? null : false;
1427
+ }
1428
+ if (!this.support.transition) {
1429
+ this.options.emulateTouchEvents = false;
1430
+ }
1431
+ }
1432
+
1433
+ });
1434
+
1435
+ if (typeof define === 'function' && define.amd) {
1436
+ define(function () {
1437
+ return Gallery;
1438
+ });
1439
+ } else {
1440
+ window.blueimp = window.blueimp || {};
1441
+ window.blueimp.Gallery = Gallery;
1442
+ }
1443
+ }());