blueimp-gallery-rails 2.3.2 → 2.7.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d6581abb69082c1c8d44306d9b9f6a4d71e4befc
4
- data.tar.gz: f1277611d95ec513587bb7dea509230e0becf99c
3
+ metadata.gz: 21d70c7e753912e22cdeffab04b7b1c5499ee896
4
+ data.tar.gz: 5b89928f6bee057b13726ab35af0671512afa901
5
5
  SHA512:
6
- metadata.gz: b0a531ab96a5c88cc5b6d7763b57455cd1c30d2f15e82720e6c39b9c2cc6642e987e66783f1b6db1e6f23e709e6faf7a8599c55272b4d2e7e4df68991657c88c
7
- data.tar.gz: b8a2d1980087abbde6576a9b976f4c7a6e44136a9912a0ef4bdf6a2b7d144b3771322f4f2a4877c9e58ed106933894da5345e54349907a99aeaf282779adb71c
6
+ metadata.gz: d809cfdf07300c019190b2efdd48b819bb2f060f0c2254acec4e6553cb725f2778bc2dec8da20c0ef1d19c33aea2ae517d09113501cba5e5cf21ae6def11963b
7
+ data.tar.gz: a1ab550b0bbce607b62a6e1b7d5bca9aaa305955268dc38f1566eb8b9c76fcf066297a4913de5c3a7829fbf3ae126fc8b993450375177fb7fe99990a1ae903ca
File without changes
File without changes
@@ -0,0 +1,85 @@
1
+ /*
2
+ * blueimp Gallery Fullscreen JS 1.0.0
3
+ * https://github.com/blueimp/Gallery
4
+ *
5
+ * Copyright 2013, Sebastian Tschan
6
+ * https://blueimp.net
7
+ *
8
+ * Licensed under the MIT license:
9
+ * http://www.opensource.org/licenses/MIT
10
+ */
11
+
12
+ /*global define, window, document */
13
+
14
+ (function (factory) {
15
+ 'use strict';
16
+ if (typeof define === 'function' && define.amd) {
17
+ // Register as an anonymous AMD module:
18
+ define([
19
+ './blueimp-helper',
20
+ './blueimp-gallery'
21
+ ], factory);
22
+ } else {
23
+ // Browser globals:
24
+ factory(
25
+ window.blueimp.helper || window.jQuery,
26
+ window.blueimp.Gallery
27
+ );
28
+ }
29
+ }(function ($, Gallery) {
30
+ 'use strict';
31
+
32
+ $.extend(Gallery.prototype.options, {
33
+ // Defines if the gallery should open in fullscreen mode:
34
+ fullScreen: false
35
+ });
36
+
37
+ var initialize = Gallery.prototype.initialize,
38
+ close = Gallery.prototype.close;
39
+
40
+ $.extend(Gallery.prototype, {
41
+
42
+ getFullScreenElement: function () {
43
+ return document.fullscreenElement ||
44
+ document.webkitFullscreenElement ||
45
+ document.mozFullScreenElement;
46
+ },
47
+
48
+ requestFullScreen: function (element) {
49
+ if (element.requestFullscreen) {
50
+ element.requestFullscreen();
51
+ } else if (element.webkitRequestFullscreen) {
52
+ element.webkitRequestFullscreen();
53
+ } else if (element.mozRequestFullScreen) {
54
+ element.mozRequestFullScreen();
55
+ }
56
+ },
57
+
58
+ exitFullScreen: function () {
59
+ if (document.exitFullscreen) {
60
+ document.exitFullscreen();
61
+ } else if (document.webkitCancelFullScreen) {
62
+ document.webkitCancelFullScreen();
63
+ } else if (document.mozCancelFullScreen) {
64
+ document.mozCancelFullScreen();
65
+ }
66
+ },
67
+
68
+ initialize: function () {
69
+ initialize.call(this);
70
+ if (this.options.fullScreen && !this.getFullScreenElement()) {
71
+ this.requestFullScreen(this.container[0]);
72
+ }
73
+ },
74
+
75
+ close: function () {
76
+ if (this.getFullScreenElement() === this.container[0]) {
77
+ this.exitFullScreen();
78
+ }
79
+ close.call(this);
80
+ }
81
+
82
+ });
83
+
84
+ return Gallery;
85
+ }));
@@ -0,0 +1,153 @@
1
+ /*
2
+ * blueimp Gallery Indicator JS 1.0.0
3
+ * https://github.com/blueimp/Gallery
4
+ *
5
+ * Copyright 2013, Sebastian Tschan
6
+ * https://blueimp.net
7
+ *
8
+ * Licensed under the MIT license:
9
+ * http://www.opensource.org/licenses/MIT
10
+ */
11
+
12
+ /*global define, window, document */
13
+
14
+ (function (factory) {
15
+ 'use strict';
16
+ if (typeof define === 'function' && define.amd) {
17
+ // Register as an anonymous AMD module:
18
+ define([
19
+ './blueimp-helper',
20
+ './blueimp-gallery'
21
+ ], factory);
22
+ } else {
23
+ // Browser globals:
24
+ factory(
25
+ window.blueimp.helper || window.jQuery,
26
+ window.blueimp.Gallery
27
+ );
28
+ }
29
+ }(function ($, Gallery) {
30
+ 'use strict';
31
+
32
+ $.extend(Gallery.prototype.options, {
33
+ // The tag name, Id, element or querySelector of the indicator container:
34
+ indicatorContainer: 'ol',
35
+ // The class for the active indicator:
36
+ activeIndicatorClass: 'active',
37
+ // The list object property (or data attribute) with the thumbnail URL,
38
+ // used as alternative to a thumbnail child element:
39
+ thumbnailProperty: 'thumbnail',
40
+ // Defines if the gallery indicators should display a thumbnail:
41
+ thumbnailIndicators: true
42
+ });
43
+
44
+ var initSlides = Gallery.prototype.initSlides,
45
+ addSlide = Gallery.prototype.addSlide,
46
+ resetSlides = Gallery.prototype.resetSlides,
47
+ handleClick = Gallery.prototype.handleClick,
48
+ handleSlide = Gallery.prototype.handleSlide,
49
+ close = Gallery.prototype.close;
50
+
51
+ $.extend(Gallery.prototype, {
52
+
53
+ createIndicator: function (obj) {
54
+ var indicator = this.indicatorPrototype.cloneNode(false),
55
+ title = this.getItemProperty(obj, this.options.titleProperty),
56
+ thumbnailProperty = this.options.thumbnailProperty,
57
+ thumbnailUrl,
58
+ thumbnail;
59
+ if (this.options.thumbnailIndicators) {
60
+ thumbnail = obj.getElementsByTagName && $(obj).find('img')[0];
61
+ if (thumbnail) {
62
+ thumbnailUrl = thumbnail.src;
63
+ } else if (thumbnailProperty) {
64
+ thumbnailUrl = this.getItemProperty(obj, thumbnailProperty);
65
+ }
66
+ if (thumbnailUrl) {
67
+ indicator.style.backgroundImage = 'url("' + thumbnailUrl + '")';
68
+ }
69
+ }
70
+ if (title) {
71
+ indicator.title = title;
72
+ }
73
+ return indicator;
74
+ },
75
+
76
+ addIndicator: function (index) {
77
+ if (this.indicatorContainer.length) {
78
+ var indicator = this.createIndicator(this.list[index]);
79
+ indicator.setAttribute('data-index', index);
80
+ this.indicatorContainer[0].appendChild(indicator);
81
+ this.indicators.push(indicator);
82
+ }
83
+ },
84
+
85
+ setActiveIndicator: function (index) {
86
+ if (this.indicators) {
87
+ if (this.activeIndicator) {
88
+ this.activeIndicator
89
+ .removeClass(this.options.activeIndicatorClass);
90
+ }
91
+ this.activeIndicator = $(this.indicators[index]);
92
+ this.activeIndicator
93
+ .addClass(this.options.activeIndicatorClass);
94
+ }
95
+ },
96
+
97
+ initSlides: function (reload) {
98
+ if (!reload) {
99
+ this.indicatorContainer = this.container.find(
100
+ this.options.indicatorContainer
101
+ );
102
+ if (this.indicatorContainer.length) {
103
+ this.indicatorPrototype = document.createElement('li');
104
+ this.indicators = this.indicatorContainer[0].children;
105
+ }
106
+ }
107
+ initSlides.call(this, reload);
108
+ },
109
+
110
+ addSlide: function (index) {
111
+ addSlide.call(this, index);
112
+ this.addIndicator(index);
113
+ },
114
+
115
+ resetSlides: function () {
116
+ resetSlides.call(this);
117
+ this.indicatorContainer.empty();
118
+ this.indicators = [];
119
+ },
120
+
121
+ handleClick: function (event) {
122
+ var target = event.target || event.srcElement,
123
+ parent = target.parentNode;
124
+ if (parent === this.indicatorContainer[0]) {
125
+ // Click on indicator element
126
+ this.preventDefault(event);
127
+ this.slide(this.getNodeIndex(target));
128
+ } else if (parent.parentNode === this.indicatorContainer[0]) {
129
+ // Click on indicator child element
130
+ this.preventDefault(event);
131
+ this.slide(this.getNodeIndex(parent));
132
+ } else {
133
+ return handleClick.call(this, event);
134
+ }
135
+ },
136
+
137
+ handleSlide: function (index) {
138
+ handleSlide.call(this, index);
139
+ this.setActiveIndicator(index);
140
+ },
141
+
142
+ close: function () {
143
+ if (this.activeIndicator) {
144
+ this.activeIndicator
145
+ .removeClass(this.options.activeIndicatorClass);
146
+ }
147
+ close.call(this);
148
+ }
149
+
150
+ });
151
+
152
+ return Gallery;
153
+ }));
@@ -0,0 +1,5 @@
1
+ //= require blueimp-gallery
2
+ //= require blueimp-gallery-fullscreen
3
+ //= require blueimp-gallery-indicator
4
+ //= require blueimp-gallery-video
5
+ //= require jquery.blueimp-gallery
@@ -0,0 +1,5 @@
1
+ //= require blueimp-helper
2
+ //= require blueimp-gallery
3
+ //= require blueimp-gallery-fullscreen
4
+ //= require blueimp-gallery-indicator
5
+ //= require blueimp-gallery-video
@@ -0,0 +1,156 @@
1
+ /*
2
+ * blueimp Gallery Video Factory JS 1.0.0
3
+ * https://github.com/blueimp/Gallery
4
+ *
5
+ * Copyright 2013, Sebastian Tschan
6
+ * https://blueimp.net
7
+ *
8
+ * Licensed under the MIT license:
9
+ * http://www.opensource.org/licenses/MIT
10
+ */
11
+
12
+ /*global define, window, document */
13
+
14
+ (function (factory) {
15
+ 'use strict';
16
+ if (typeof define === 'function' && define.amd) {
17
+ // Register as an anonymous AMD module:
18
+ define([
19
+ './blueimp-helper',
20
+ './blueimp-gallery'
21
+ ], factory);
22
+ } else {
23
+ // Browser globals:
24
+ factory(
25
+ window.blueimp.helper || window.jQuery,
26
+ window.blueimp.Gallery
27
+ );
28
+ }
29
+ }(function ($, Gallery) {
30
+ 'use strict';
31
+
32
+ $.extend(Gallery.prototype.options, {
33
+ // The class for video content elements:
34
+ videoContentClass: 'video-content',
35
+ // The class for video when it is loading:
36
+ videoLoadingClass: 'video-loading',
37
+ // The class for video when it is playing:
38
+ videoPlayingClass: 'video-playing',
39
+ // The list object property (or data attribute) for the video poster URL:
40
+ videoPosterProperty: 'poster',
41
+ // The list object property (or data attribute) for the video sources array:
42
+ videoSourcesProperty: 'sources'
43
+ });
44
+
45
+ Gallery.prototype.videoFactory = function (obj, callback) {
46
+ var that = this,
47
+ options = this.options,
48
+ videoContainerNode = this.elementPrototype.cloneNode(false),
49
+ videoContainer = $(videoContainerNode),
50
+ errorArgs = [{
51
+ type: 'error',
52
+ target: videoContainerNode
53
+ }],
54
+ video = document.createElement('video'),
55
+ url = this.getItemProperty(obj, options.urlProperty),
56
+ type = this.getItemProperty(obj, options.typeProperty),
57
+ title = this.getItemProperty(obj, options.titleProperty),
58
+ posterUrl = this.getItemProperty(obj, options.videoPosterProperty),
59
+ posterImage,
60
+ sources = this.getItemProperty(
61
+ obj,
62
+ options.videoSourcesProperty
63
+ ),
64
+ source,
65
+ playMediaControl,
66
+ isLoading,
67
+ hasControls;
68
+ videoContainer.addClass(options.videoContentClass);
69
+ if (title) {
70
+ videoContainerNode.title = title;
71
+ }
72
+ if (video.canPlayType) {
73
+ if (url && type && video.canPlayType(type)) {
74
+ video.src = url;
75
+ } else if (sources) {
76
+ if (typeof sources === 'string') {
77
+ sources = $.parseJSON(sources);
78
+ }
79
+ while (sources && sources.length) {
80
+ source = sources.shift();
81
+ url = this.getItemProperty(source, options.urlProperty);
82
+ type = this.getItemProperty(source, options.typeProperty);
83
+ if (url && type && video.canPlayType(type)) {
84
+ video.src = url;
85
+ break;
86
+ }
87
+ }
88
+ }
89
+ }
90
+ if (posterUrl) {
91
+ video.setAttribute('poster', posterUrl);
92
+ posterImage = this.imagePrototype.cloneNode(false);
93
+ $(posterImage).addClass(options.toggleClass);
94
+ posterImage.src = posterUrl;
95
+ posterImage.draggable = false;
96
+ videoContainerNode.appendChild(posterImage);
97
+ }
98
+ playMediaControl = document.createElement('a');
99
+ playMediaControl.setAttribute('target', '_blank');
100
+ playMediaControl.setAttribute('download', title);
101
+ playMediaControl.href = url;
102
+ if (video.src) {
103
+ video.controls = true;
104
+ $(video)
105
+ .on('error', function () {
106
+ that.setTimeout(callback, errorArgs);
107
+ })
108
+ .on('pause', function () {
109
+ isLoading = false;
110
+ videoContainer
111
+ .removeClass(that.options.videoLoadingClass)
112
+ .removeClass(that.options.videoPlayingClass);
113
+ if (hasControls) {
114
+ that.container.addClass(that.options.controlsClass);
115
+ }
116
+ if (that.interval) {
117
+ that.play();
118
+ }
119
+ })
120
+ .on('playing', function () {
121
+ isLoading = false;
122
+ videoContainer
123
+ .removeClass(that.options.videoLoadingClass)
124
+ .addClass(that.options.videoPlayingClass);
125
+ if (that.container.hasClass(that.options.controlsClass)) {
126
+ hasControls = true;
127
+ that.container.removeClass(that.options.controlsClass);
128
+ } else {
129
+ hasControls = false;
130
+ }
131
+ })
132
+ .on('play', function () {
133
+ window.clearTimeout(that.timeout);
134
+ isLoading = true;
135
+ videoContainer.addClass(that.options.videoLoadingClass);
136
+ });
137
+ $(playMediaControl).on('click', function (event) {
138
+ event.preventDefault();
139
+ if (isLoading) {
140
+ video.pause();
141
+ } else {
142
+ video.play();
143
+ }
144
+ });
145
+ videoContainerNode.appendChild(video);
146
+ }
147
+ videoContainerNode.appendChild(playMediaControl);
148
+ this.setTimeout(callback, [{
149
+ type: 'load',
150
+ target: videoContainerNode
151
+ }]);
152
+ return videoContainerNode;
153
+ };
154
+
155
+ return Gallery;
156
+ }));
@@ -1,5 +1,5 @@
1
1
  /*
2
- * blueimp Gallery JS 2.3.1
2
+ * blueimp Gallery JS 2.7.0
3
3
  * https://github.com/blueimp/Gallery
4
4
  *
5
5
  * Copyright 2013, Sebastian Tschan
@@ -15,7 +15,19 @@
15
15
  /*jslint regexp: true */
16
16
  /*global define, window, document, DocumentTouch */
17
17
 
18
- (function () {
18
+ (function (factory) {
19
+ 'use strict';
20
+ if (typeof define === 'function' && define.amd) {
21
+ // Register as an anonymous AMD module:
22
+ define(['./blueimp-helper'], factory);
23
+ } else {
24
+ // Browser globals:
25
+ window.blueimp = window.blueimp || {};
26
+ window.blueimp.Gallery = factory(
27
+ window.blueimp.helper || window.jQuery
28
+ );
29
+ }
30
+ }(function ($) {
19
31
  'use strict';
20
32
 
21
33
  function Gallery(list, options) {
@@ -31,132 +43,10 @@
31
43
  this.list = list;
32
44
  this.num = list.length;
33
45
  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
- }
46
+ this.initialize();
48
47
  }
49
48
 
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,
49
+ $.extend(Gallery.prototype, {
160
50
 
161
51
  options: {
162
52
  // The Id, element or querySelector of the gallery widget:
@@ -165,8 +55,6 @@
165
55
  slidesContainer: 'div',
166
56
  // The tag name, Id, element or querySelector of the title element:
167
57
  titleElement: 'h3',
168
- // The tag name, Id, element or querySelector of the indicator container:
169
- indicatorContainer: 'ol',
170
58
  // The class to add when the gallery is visible:
171
59
  displayClass: 'blueimp-gallery-display',
172
60
  // The class to add when the gallery controls are visible:
@@ -187,12 +75,6 @@
187
75
  slideErrorClass: 'slide-error',
188
76
  // The class for the content element loaded into each slide:
189
77
  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
78
  // The class for the "toggle" control:
197
79
  toggleClass: 'toggle',
198
80
  // The class for the "prev" control:
@@ -203,28 +85,15 @@
203
85
  closeClass: 'close',
204
86
  // The class for the "play-pause" toggle control:
205
87
  playPauseClass: 'play-pause',
206
- // The class for the active indicator:
207
- activeClass: 'active',
208
88
  // The list object property (or data attribute) with the object type:
209
89
  typeProperty: 'type',
210
90
  // The list object property (or data attribute) with the object title:
211
91
  titleProperty: 'title',
212
92
  // The list object property (or data attribute) with the object URL:
213
93
  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
94
  // Defines if the gallery slides are cleared from the gallery modal,
224
95
  // or reused for the next gallery initialization:
225
96
  clearSlides: true,
226
- // Defines if the gallery should open in fullscreen mode:
227
- fullScreen: false,
228
97
  // Defines if images should be stretched to fill the available space,
229
98
  // while maintaining their aspect ratio (will only be enabled for browsers
230
99
  // supporting background-size="contain", which excludes IE < 9):
@@ -235,7 +104,7 @@
235
104
  toggleSlideshowOnSpace: true,
236
105
  // Navigate the gallery by pressing left and right on the keyboard:
237
106
  enableKeyboardNavigation: true,
238
- // Close the gallery on pressing the ESC key:
107
+ // Close the gallery on pressing the Esc key:
239
108
  closeOnEscape: true,
240
109
  // Close the gallery when clicking on an empty slide area:
241
110
  closeOnSlideClick: true,
@@ -252,6 +121,8 @@
252
121
  // Allow continuous navigation, moving from last to first
253
122
  // and from first to last slide:
254
123
  continuous: true,
124
+ // Remove elements outside of the preload range from the DOM:
125
+ unloadElements: true,
255
126
  // Start with the automatic slideshow:
256
127
  startSlideshow: false,
257
128
  // Delay in milliseconds between slides for the automatic slideshow:
@@ -267,18 +138,27 @@
267
138
  // The transition speed for automatic slide changes, set to an integer
268
139
  // greater 0 to override the default transition speed:
269
140
  slideshowTransitionSpeed: undefined,
141
+ // The event object for which the default action will be canceled
142
+ // on Gallery initialization (e.g. the click event to open the Gallery):
143
+ event: undefined,
144
+ // Callback function executed when the Gallery is initialized.
145
+ // Is called with the gallery instance as "this" object:
146
+ onopen: undefined,
270
147
  // Callback function executed on slide change.
271
- // Is called with the list object as "this" object and the
148
+ // Is called with the gallery instance as "this" object and the
272
149
  // current index and slide as arguments:
273
150
  onslide: undefined,
274
151
  // Callback function executed after the slide change transition.
275
- // Is called with the list object as "this" object and the
152
+ // Is called with the gallery instance as "this" object and the
276
153
  // current index and slide as arguments:
277
154
  onslideend: undefined,
278
155
  // Callback function executed on slide content load.
279
- // Is called with the list object as "this" object and the
156
+ // Is called with the gallery instance as "this" object and the
280
157
  // slide index and slide element as arguments:
281
- onslidecomplete: undefined
158
+ onslidecomplete: undefined,
159
+ // Callback function executed when the Gallery is closed.
160
+ // Is called with the gallery instance as "this" object:
161
+ onclose: undefined
282
162
  },
283
163
 
284
164
  carouselOptions: {
@@ -357,6 +237,25 @@
357
237
  // for the CSS3 transform translateZ test to be applicable:
358
238
  }(document.createElement('div'))),
359
239
 
240
+ initialize: function () {
241
+ this.initStartIndex();
242
+ if (this.initWidget() === false) {
243
+ return false;
244
+ }
245
+ this.initEventListeners();
246
+ if (this.options.onopen) {
247
+ this.options.onopen.call(this);
248
+ }
249
+ // Load the slide at the given index:
250
+ this.onslide(this.index);
251
+ // Manually trigger the slideend event for the initial slide:
252
+ this.ontransitionend();
253
+ // Start the automatic slideshow if applicable:
254
+ if (this.options.startSlideshow) {
255
+ this.play();
256
+ }
257
+ },
258
+
360
259
  slide: function (to, speed) {
361
260
  window.clearTimeout(this.timeout);
362
261
  var index = this.index,
@@ -409,7 +308,6 @@
409
308
  to = this.circle(to);
410
309
  this.animate(index * -this.slideWidth, to * -this.slideWidth, speed);
411
310
  }
412
- this.index = to;
413
311
  this.onslide(to);
414
312
  },
415
313
 
@@ -436,20 +334,20 @@
436
334
  play: function (time) {
437
335
  window.clearTimeout(this.timeout);
438
336
  this.interval = time || this.options.slideshowInterval;
439
- if (this.status[this.index] > 1) {
337
+ if (this.elements[this.index] > 1) {
440
338
  this.timeout = this.setTimeout(
441
339
  this.slide,
442
340
  [this.index + 1, this.options.slideshowTransitionSpeed],
443
341
  this.interval
444
342
  );
445
343
  }
446
- this.helper.addClass(this.container, this.options.playingClass);
344
+ this.container.addClass(this.options.playingClass);
447
345
  },
448
346
 
449
347
  pause: function () {
450
348
  window.clearTimeout(this.timeout);
451
349
  this.interval = null;
452
- this.helper.removeClass(this.container, this.options.playingClass);
350
+ this.container.removeClass(this.options.playingClass);
453
351
  },
454
352
 
455
353
  add: function (list) {
@@ -458,48 +356,43 @@
458
356
  this.num = this.list.length;
459
357
  if (this.num > 2 && this.options.continuous === null) {
460
358
  this.options.continuous = true;
461
- this.helper.removeClass(this.container, this.options.leftEdgeClass);
359
+ this.container.removeClass(this.options.leftEdgeClass);
462
360
  }
463
- this.helper.removeClass(this.container, this.options.rightEdgeClass);
464
- this.helper.removeClass(this.container, this.options.singleClass);
361
+ this.container
362
+ .removeClass(this.options.rightEdgeClass)
363
+ .removeClass(this.options.singleClass);
465
364
  for (i = this.num - list.length; i < this.num; i += 1) {
466
365
  this.addSlide(i);
467
366
  this.positionSlide(i);
468
- this.addIndicator(i);
469
367
  }
470
- this.elements.length =
471
- this.status.length =
472
- this.positions.length = this.num;
368
+ this.positions.length = this.num;
473
369
  this.initSlides(true);
474
370
  },
475
371
 
372
+ resetSlides: function () {
373
+ this.slidesContainer.empty();
374
+ this.slides = [];
375
+ },
376
+
476
377
  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
- }
378
+ var options = this.options;
490
379
  this.destroyEventListeners();
491
380
  // Cancel the slideshow:
492
381
  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
- }
382
+ this.container[0].style.display = 'none';
383
+ this.container
384
+ .removeClass(options.displayClass)
385
+ .removeClass(options.singleClass)
386
+ .removeClass(options.leftEdgeClass)
387
+ .removeClass(options.rightEdgeClass);
388
+ if (options.hidePageScrollbars) {
389
+ document.body.style.overflow = this.bodyOverflowStyle;
390
+ }
391
+ if (this.options.clearSlides) {
392
+ this.resetSlides();
393
+ }
394
+ if (this.options.onclose) {
395
+ this.options.onclose.call(this);
503
396
  }
504
397
  },
505
398
 
@@ -532,7 +425,7 @@
532
425
 
533
426
  animate: function (from, to, speed) {
534
427
  if (!speed) {
535
- this.slidesContainer.style.left = to + 'px';
428
+ this.slidesContainer[0].style.left = to + 'px';
536
429
  return;
537
430
  }
538
431
  var that = this,
@@ -540,16 +433,25 @@
540
433
  timer = window.setInterval(function () {
541
434
  var timeElap = new Date().getTime() - start;
542
435
  if (timeElap > speed) {
543
- that.slidesContainer.style.left = to + 'px';
436
+ that.slidesContainer[0].style.left = to + 'px';
544
437
  that.ontransitionend();
545
438
  window.clearInterval(timer);
546
439
  return;
547
440
  }
548
- that.slidesContainer.style.left = (((to - from) *
549
- (Math.floor((timeElap / speed) * 100) / 100)) + from) + 'px';
441
+ that.slidesContainer[0].style.left = (((to - from) *
442
+ (Math.floor((timeElap / speed) * 100) / 100)) +
443
+ from) + 'px';
550
444
  }, 4);
551
445
  },
552
446
 
447
+ preventDefault: function (event) {
448
+ if (event.preventDefault) {
449
+ event.preventDefault();
450
+ } else {
451
+ event.returnValue = false;
452
+ }
453
+ },
454
+
553
455
  onresize: function () {
554
456
  this.initSlides(true);
555
457
  },
@@ -587,7 +489,7 @@
587
489
  var target = event.target,
588
490
  related = event.relatedTarget;
589
491
  if (!related || (related !== target &&
590
- !this.helper.contains(target, related))) {
492
+ !$.contains(target, related))) {
591
493
  this.onmouseup(event);
592
494
  }
593
495
  }
@@ -736,7 +638,6 @@
736
638
  this.translateY(index, 0, speed);
737
639
  }
738
640
  }
739
- this.index = index;
740
641
  },
741
642
 
742
643
  ontransitionend: function (event) {
@@ -760,16 +661,16 @@
760
661
  return;
761
662
  }
762
663
  index = this.getNodeIndex(parent);
763
- this.helper.removeClass(parent, this.options.slideLoadingClass);
664
+ $(parent).removeClass(this.options.slideLoadingClass);
764
665
  if (event.type === 'error') {
765
- this.helper.addClass(parent, this.options.slideErrorClass);
766
- this.status[index] = 3; // Fail
666
+ $(parent).addClass(this.options.slideErrorClass);
667
+ this.elements[index] = 3; // Fail
767
668
  } else {
768
- this.status[index] = 2; // Done
669
+ this.elements[index] = 2; // Done
769
670
  }
770
671
  // 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;
672
+ if (target.clientHeight > this.container[0].clientHeight) {
673
+ target.style.maxHeight = this.container[0].clientHeight;
773
674
  }
774
675
  if (this.interval && this.slides[this.index] === parent) {
775
676
  this.play();
@@ -792,139 +693,131 @@
792
693
  switch (event.which || event.keyCode) {
793
694
  case 13: // Return
794
695
  if (this.options.toggleControlsOnReturn) {
795
- this.helper.preventDefault(event);
696
+ this.preventDefault(event);
796
697
  this.toggleControls();
797
698
  }
798
699
  break;
799
- case 27: // ESC
700
+ case 27: // Esc
800
701
  if (this.options.closeOnEscape) {
801
702
  this.close();
802
703
  }
803
704
  break;
804
705
  case 32: // Space
805
706
  if (this.options.toggleSlideshowOnSpace) {
806
- this.helper.preventDefault(event);
707
+ this.preventDefault(event);
807
708
  this.toggleSlideshow();
808
709
  }
809
710
  break;
810
- case 37: // left
711
+ case 37: // Left
811
712
  if (this.options.enableKeyboardNavigation) {
812
- this.helper.preventDefault(event);
713
+ this.preventDefault(event);
813
714
  this.prev();
814
715
  }
815
716
  break;
816
- case 39: // right
717
+ case 39: // Right
817
718
  if (this.options.enableKeyboardNavigation) {
818
- this.helper.preventDefault(event);
719
+ this.preventDefault(event);
819
720
  this.next();
820
721
  }
821
722
  break;
822
723
  }
823
724
  },
824
725
 
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
- }
726
+ handleClick: function (event) {
832
727
  var options = this.options,
833
728
  target = event.target || event.srcElement,
834
729
  parent = target.parentNode,
835
- helper = this.helper,
836
730
  isTarget = function (className) {
837
- return helper.hasClass(target, className) ||
838
- helper.hasClass(parent, className);
731
+ return $(target).hasClass(className) ||
732
+ $(parent).hasClass(className);
839
733
  };
840
- if (parent === this.slidesContainer) {
734
+ if (parent === this.slidesContainer[0]) {
841
735
  // Click on slide background
842
- helper.preventDefault(event);
736
+ this.preventDefault(event);
843
737
  if (options.closeOnSlideClick) {
844
738
  this.close();
845
739
  } else {
846
740
  this.toggleControls();
847
741
  }
848
742
  } else if (parent.parentNode &&
849
- parent.parentNode === this.slidesContainer) {
743
+ parent.parentNode === this.slidesContainer[0]) {
850
744
  // Click on displayed element
851
- helper.preventDefault(event);
745
+ this.preventDefault(event);
852
746
  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
747
  } else if (isTarget(options.toggleClass)) {
862
748
  // Click on "toggle" control
863
- helper.preventDefault(event);
749
+ this.preventDefault(event);
864
750
  this.toggleControls();
865
751
  } else if (isTarget(options.prevClass)) {
866
752
  // Click on "prev" control
867
- helper.preventDefault(event);
753
+ this.preventDefault(event);
868
754
  this.prev();
869
755
  } else if (isTarget(options.nextClass)) {
870
756
  // Click on "next" control
871
- helper.preventDefault(event);
757
+ this.preventDefault(event);
872
758
  this.next();
873
759
  } else if (isTarget(options.closeClass)) {
874
760
  // Click on "close" control
875
- helper.preventDefault(event);
761
+ this.preventDefault(event);
876
762
  this.close();
877
763
  } else if (isTarget(options.playPauseClass)) {
878
764
  // Click on "play-pause" control
879
- helper.preventDefault(event);
765
+ this.preventDefault(event);
880
766
  this.toggleSlideshow();
881
767
  }
882
768
  },
883
769
 
770
+ onclick: function (event) {
771
+ if (this.options.emulateTouchEvents &&
772
+ this.touchDelta && (Math.abs(this.touchDelta.x) > 20 ||
773
+ Math.abs(this.touchDelta.y) > 20)) {
774
+ delete this.touchDelta;
775
+ return;
776
+ }
777
+ return this.handleClick(event);
778
+ },
779
+
884
780
  updateEdgeClasses: function (index) {
885
781
  if (!index) {
886
- this.helper.addClass(this.container, this.options.leftEdgeClass);
782
+ this.container.addClass(this.options.leftEdgeClass);
887
783
  } else {
888
- this.helper.removeClass(this.container, this.options.leftEdgeClass);
784
+ this.container.removeClass(this.options.leftEdgeClass);
889
785
  }
890
786
  if (index === this.num - 1) {
891
- this.helper.addClass(this.container, this.options.rightEdgeClass);
787
+ this.container.addClass(this.options.rightEdgeClass);
892
788
  } else {
893
- this.helper.removeClass(this.container, this.options.rightEdgeClass);
789
+ this.container.removeClass(this.options.rightEdgeClass);
894
790
  }
895
791
  },
896
792
 
897
- onslide: function (index) {
793
+ handleSlide: function (index) {
898
794
  if (!this.options.continuous) {
899
795
  this.updateEdgeClasses(index);
900
796
  }
901
797
  this.loadElements(index);
798
+ if (this.options.unloadElements) {
799
+ this.unloadElements(index);
800
+ }
902
801
  this.setTitle(index);
903
- this.setActiveIndicator(index);
802
+ },
803
+
804
+ onslide: function (index) {
805
+ this.index = index;
806
+ this.handleSlide(index);
904
807
  this.setTimeout(this.options.onslide, [index, this.slides[index]]);
905
808
  },
906
809
 
907
810
  setTitle: function (index) {
908
- var text = this.elements[index].title,
811
+ var text = this.slides[index].firstChild.title,
909
812
  titleElement = this.titleElement;
910
- if (titleElement) {
911
- this.helper.empty(titleElement);
813
+ if (titleElement.length) {
814
+ this.titleElement.empty();
912
815
  if (text) {
913
- titleElement.appendChild(document.createTextNode(text));
816
+ titleElement[0].appendChild(document.createTextNode(text));
914
817
  }
915
818
  }
916
819
  },
917
820
 
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
821
  setTimeout: function (func, args, wait) {
929
822
  var that = this;
930
823
  return func && window.setTimeout(function () {
@@ -932,155 +825,55 @@
932
825
  }, wait || 0);
933
826
  },
934
827
 
935
- videoFactory: function (obj, callback) {
828
+ imageFactory: function (obj, callback) {
936
829
  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;
830
+ img = this.imagePrototype.cloneNode(false),
831
+ url = obj,
832
+ contain = this.options.stretchImages &&
833
+ this.support.backgroundSize &&
834
+ this.support.backgroundSize.contain,
835
+ called,
836
+ element,
837
+ callbackWrapper = function (event) {
838
+ if (!called) {
839
+ event = {
840
+ type: event.type,
841
+ target: element
842
+ };
843
+ if (!element.parentNode) {
844
+ // Fix for IE7 firing the load event for
845
+ // cached images before the element could
846
+ // be added to the DOM:
847
+ return that.setTimeout(callbackWrapper, [event]);
975
848
  }
849
+ called = true;
850
+ $(img).off('load error', callbackWrapper);
851
+ if (contain) {
852
+ if (event.type === 'load') {
853
+ element.style.background = 'url("' + url +
854
+ '") center no-repeat';
855
+ element.style.backgroundSize = 'contain';
856
+ }
857
+ }
858
+ callback(event);
976
859
  }
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,
860
+ },
1045
861
  title;
1046
862
  if (typeof url !== 'string') {
1047
863
  url = this.getItemProperty(obj, this.options.urlProperty);
1048
864
  title = this.getItemProperty(obj, this.options.titleProperty);
1049
865
  }
1050
- if (this.options.stretchImages && this.support.backgroundSize &&
1051
- this.support.backgroundSize.contain) {
866
+ if (contain) {
1052
867
  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
868
  } else {
1068
869
  element = img;
1069
870
  img.draggable = false;
1070
- this.helper.addListener(img, 'load', callback);
1071
- this.helper.addListener(img, 'error', callback);
1072
871
  }
1073
872
  if (title) {
1074
873
  element.title = title;
1075
874
  }
875
+ $(img).on('load error', callbackWrapper);
1076
876
  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
877
  return element;
1085
878
  },
1086
879
 
@@ -1096,57 +889,27 @@
1096
889
  target: element
1097
890
  }]);
1098
891
  }
1099
- this.helper.addClass(element, this.options.slideContentClass);
892
+ $(element).addClass(this.options.slideContentClass);
1100
893
  return element;
1101
894
  },
1102
895
 
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
896
  loadElement: function (index) {
1131
897
  if (!this.elements[index]) {
1132
898
  if (this.slides[index].firstChild) {
1133
- this.elements[index] = this.slides[index].firstChild;
899
+ this.elements[index] = $(this.slides[index])
900
+ .hasClass(this.options.slideErrorClass) ? 3 : 2;
1134
901
  } else {
1135
- this.helper.addClass(this.slides[index], this.options.slideLoadingClass);
1136
- this.elements[index] = this.createElement(
902
+ this.elements[index] = 1; // Loading
903
+ $(this.slides[index]).addClass(this.options.slideLoadingClass);
904
+ this.slides[index].appendChild(this.createElement(
1137
905
  this.list[index],
1138
906
  this.proxyListener
1139
- );
1140
- this.slides[index].appendChild(this.elements[index]);
907
+ ));
1141
908
  }
1142
909
  }
1143
910
  },
1144
911
 
1145
912
  loadElements: function (index) {
1146
- if (this.status[index]) {
1147
- return;
1148
- }
1149
- this.status[index] = 1; // Loading
1150
913
  var limit = Math.min(this.num, this.options.preloadRange * 2 + 1),
1151
914
  j = index,
1152
915
  i;
@@ -1163,19 +926,27 @@
1163
926
  }
1164
927
  },
1165
928
 
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);
929
+ unloadElements: function (index) {
930
+ var i,
931
+ slide,
932
+ diff;
933
+ for (i in this.elements) {
934
+ if (this.elements.hasOwnProperty(i)) {
935
+ diff = Math.abs(index - i);
936
+ if (diff > this.options.preloadRange &&
937
+ diff + this.options.preloadRange < this.num) {
938
+ slide = this.slides[i];
939
+ slide.removeChild(slide.firstChild);
940
+ delete this.elements[i];
941
+ }
942
+ }
1172
943
  }
1173
944
  },
1174
945
 
1175
946
  addSlide: function (index) {
1176
947
  var slide = this.slidePrototype.cloneNode(false);
1177
948
  slide.setAttribute('data-index', index);
1178
- this.slidesContainer.appendChild(slide);
949
+ this.slidesContainer[0].appendChild(slide);
1179
950
  this.slides.push(slide);
1180
951
  },
1181
952
 
@@ -1193,42 +964,26 @@
1193
964
  var clearSlides,
1194
965
  i;
1195
966
  if (!reload) {
1196
- this.elements = [];
1197
- this.status = [];
1198
967
  this.positions = [];
1199
- this.elements.length =
1200
- this.status.length =
1201
- this.positions.length = this.num;
968
+ this.positions.length = this.num;
969
+ this.elements = {};
1202
970
  this.imagePrototype = document.createElement('img');
1203
971
  this.elementPrototype = document.createElement('div');
1204
972
  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';
973
+ $(this.slidePrototype).addClass(this.options.slideClass);
974
+ this.slides = this.slidesContainer[0].children;
975
+ clearSlides = this.options.clearSlides ||
976
+ this.slides.length !== this.num;
977
+ }
978
+ this.slideWidth = this.container[0].offsetWidth;
979
+ this.slideHeight = this.container[0].offsetHeight;
980
+ this.slidesContainer[0].style.width =
981
+ (this.num * this.slideWidth) + 'px';
1219
982
  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
- }
983
+ this.resetSlides();
1228
984
  }
1229
985
  for (i = 0; i < this.num; i += 1) {
1230
986
  if (clearSlides) {
1231
- this.addIndicator(i);
1232
987
  this.addSlide(i);
1233
988
  }
1234
989
  this.positionSlide(i);
@@ -1239,42 +994,17 @@
1239
994
  this.move(this.circle(this.index + 1), this.slideWidth, 0);
1240
995
  }
1241
996
  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();
997
+ this.slidesContainer[0].style.left =
998
+ (this.index * -this.slideWidth) + 'px';
1269
999
  }
1270
1000
  },
1271
1001
 
1272
1002
  toggleControls: function () {
1273
1003
  var controlsClass = this.options.controlsClass;
1274
- if (this.helper.hasClass(this.container, controlsClass)) {
1275
- this.helper.removeClass(this.container, controlsClass);
1004
+ if (this.container.hasClass(controlsClass)) {
1005
+ this.container.removeClass(controlsClass);
1276
1006
  } else {
1277
- this.helper.addClass(this.container, controlsClass);
1007
+ this.container.addClass(controlsClass);
1278
1008
  }
1279
1009
  },
1280
1010
 
@@ -1290,10 +1020,26 @@
1290
1020
  return parseInt(element.getAttribute('data-index'), 10);
1291
1021
  },
1292
1022
 
1023
+ getNestedProperty: function (obj, property) {
1024
+ property.replace(
1025
+ // Matches native JavaScript notation in a String,
1026
+ // e.g. '["doubleQuoteProp"].dotProp[2]'
1027
+ /\[(?:'([^']+)'|"([^"]+)"|(\d+))\]|(?:(?:^|\.)([^\.\[]+))/g,
1028
+ function (str, singleQuoteProp, doubleQuoteProp, arrayIndex, dotProp) {
1029
+ var prop = dotProp || singleQuoteProp || doubleQuoteProp ||
1030
+ (arrayIndex && parseInt(arrayIndex, 10));
1031
+ if (str && obj) {
1032
+ obj = obj[prop];
1033
+ }
1034
+ }
1035
+ );
1036
+ return obj;
1037
+ },
1038
+
1293
1039
  getItemProperty: function (obj, property) {
1294
1040
  return obj[property] || (obj.getAttribute &&
1295
1041
  obj.getAttribute('data-' + property)) ||
1296
- this.helper.getNestedProperty(obj, property);
1042
+ this.getNestedProperty(obj, property);
1297
1043
  },
1298
1044
 
1299
1045
  initStartIndex: function () {
@@ -1317,7 +1063,6 @@
1317
1063
 
1318
1064
  initEventListeners: function () {
1319
1065
  var that = this,
1320
- helper = this.helper,
1321
1066
  slidesContainer = this.slidesContainer,
1322
1067
  proxyListener = function (event) {
1323
1068
  var type = that.support.transition &&
@@ -1325,101 +1070,85 @@
1325
1070
  'transitionend' : event.type;
1326
1071
  that['on' + type](event);
1327
1072
  };
1328
- helper.addListener(window, 'resize', proxyListener);
1329
- helper.addListener(document.body, 'keydown', proxyListener);
1330
- helper.addListener(this.container, 'click', proxyListener);
1073
+ $(window).on('resize', proxyListener);
1074
+ $(document.body).on('keydown', proxyListener);
1075
+ this.container.on('click', proxyListener);
1331
1076
  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);
1077
+ slidesContainer
1078
+ .on('touchstart touchmove touchend', proxyListener);
1079
+ } else if (this.options.emulateTouchEvents &&
1080
+ this.support.transition) {
1081
+ slidesContainer
1082
+ .on('mousedown mousemove mouseup mouseout', proxyListener);
1340
1083
  }
1341
1084
  if (this.support.transition) {
1342
- slidesContainer.addEventListener(
1085
+ slidesContainer.on(
1343
1086
  this.support.transition.end,
1344
- proxyListener,
1345
- false
1087
+ proxyListener
1346
1088
  );
1347
1089
  }
1348
1090
  this.proxyListener = proxyListener;
1349
1091
  },
1350
1092
 
1351
1093
  destroyEventListeners: function () {
1352
- var helper = this.helper,
1353
- slidesContainer = this.slidesContainer,
1094
+ var slidesContainer = this.slidesContainer,
1354
1095
  proxyListener = this.proxyListener;
1355
- helper.removeListener(window, 'resize', proxyListener);
1356
- helper.removeListener(document.body, 'keydown', proxyListener);
1357
- helper.removeListener(this.container, 'click', proxyListener);
1096
+ $(window).off('resize', proxyListener);
1097
+ $(document.body).off('keydown', proxyListener);
1098
+ this.container.off('click', proxyListener);
1358
1099
  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);
1100
+ slidesContainer
1101
+ .off('touchstart touchmove touchend', proxyListener);
1102
+ } else if (this.options.emulateTouchEvents &&
1103
+ this.support.transition) {
1104
+ slidesContainer
1105
+ .off('mousedown mousemove mouseup mouseout', proxyListener);
1367
1106
  }
1368
1107
  if (this.support.transition) {
1369
- slidesContainer.removeEventListener(
1108
+ slidesContainer.off(
1370
1109
  this.support.transition.end,
1371
- proxyListener,
1372
- false
1110
+ proxyListener
1373
1111
  );
1374
1112
  }
1375
1113
  },
1376
1114
 
1377
1115
  initWidget: function () {
1378
- this.container = this.helper.query(
1379
- document,
1380
- this.options.container
1381
- );
1382
- if (!this.container) {
1116
+ this.container = $(this.options.container);
1117
+ if (!this.container.length) {
1383
1118
  return false;
1384
1119
  }
1385
- this.slidesContainer = this.helper.query(
1386
- this.container,
1120
+ this.slidesContainer = this.container.find(
1387
1121
  this.options.slidesContainer
1388
1122
  );
1389
- if (!this.slidesContainer) {
1123
+ if (!this.slidesContainer.length) {
1390
1124
  return false;
1391
1125
  }
1392
- this.titleElement = this.helper.query(
1393
- this.container,
1126
+ this.titleElement = this.container.find(
1394
1127
  this.options.titleElement
1395
1128
  );
1396
- this.indicatorContainer = this.helper.query(
1397
- this.container,
1398
- this.options.indicatorContainer
1399
- );
1400
1129
  if (this.options.hidePageScrollbars) {
1401
1130
  // Hide the page scrollbars:
1402
1131
  this.bodyOverflowStyle = document.body.style.overflow;
1403
1132
  document.body.style.overflow = 'hidden';
1404
1133
  }
1405
1134
  if (this.num === 1) {
1406
- this.helper.addClass(this.container, this.options.singleClass);
1135
+ this.container.addClass(this.options.singleClass);
1407
1136
  }
1408
- this.container.style.display = 'block';
1137
+ this.container[0].style.display = 'block';
1409
1138
  this.initSlides();
1410
- this.helper.addClass(this.container, this.options.displayClass);
1139
+ this.container.addClass(this.options.displayClass);
1411
1140
  },
1412
1141
 
1413
1142
  initOptions: function (options) {
1414
1143
  // Create a copy of the prototype options:
1415
- this.options = this.helper.extend({}, this.options);
1144
+ this.options = $.extend({}, this.options);
1416
1145
  // Check if carousel mode is enabled:
1417
1146
  if ((options && options.carousel) ||
1418
1147
  (this.options.carousel && (!options || options.carousel !== false))) {
1419
- this.helper.extend(this.options, this.carouselOptions);
1148
+ $.extend(this.options, this.carouselOptions);
1420
1149
  }
1421
1150
  // Override any given options:
1422
- this.helper.extend(this.options, options);
1151
+ $.extend(this.options, options);
1423
1152
  if (this.num < 3) {
1424
1153
  // 1 or 2 slides cannot be displayed continuous,
1425
1154
  // remember the original option by setting to null instead of false:
@@ -1428,16 +1157,12 @@
1428
1157
  if (!this.support.transition) {
1429
1158
  this.options.emulateTouchEvents = false;
1430
1159
  }
1160
+ if (this.options.event) {
1161
+ this.preventDefault(this.options.event);
1162
+ }
1431
1163
  }
1432
1164
 
1433
1165
  });
1434
1166
 
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
- }());
1167
+ return Gallery;
1168
+ }));