interview 0.0.6 → 0.0.7

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