blueimp-gallery-rails 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/blueimp-gallery-rails.rb +10 -0
- data/lib/blueimp-gallery-rails/version.rb +14 -0
- data/vendor/assets/images/error.png +0 -0
- data/vendor/assets/images/error.svg +5 -0
- data/vendor/assets/images/loading.gif +0 -0
- data/vendor/assets/images/play-pause.png +0 -0
- data/vendor/assets/images/play-pause.svg +6 -0
- data/vendor/assets/images/video-play.png +0 -0
- data/vendor/assets/images/video-play.svg +5 -0
- data/vendor/assets/javascripts/blueimp-gallery.js +1443 -0
- data/vendor/assets/stylesheets/blueimp-gallery.css.scss +282 -0
- metadata +98 -0
checksums.yaml
ADDED
@@ -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
|
Binary file
|
@@ -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>
|
Binary file
|
Binary file
|
@@ -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>
|
Binary file
|
@@ -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
|
+
}());
|