lightbox-bootstrap-rails 4.alpha5.0 → 5.0.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: 3a15924f622ddf6d740e1b12315878ca5ad4316a
4
- data.tar.gz: 672171730c444d1327c3a69909f19ad9f9f02b0e
3
+ metadata.gz: 2b486085e5a08b5e755c05d4a1f2f80da6e8534b
4
+ data.tar.gz: 2ffcd305f0a8b36069fd00177aa86714f7b49247
5
5
  SHA512:
6
- metadata.gz: 8c129717657d806a8aece7aa6e9cc5856b609f829006b4c40645fd6980ff41e83b20e0ba456912622556dfca8525de9a2a2d53eddee2b5c65d7960973db5b4ef
7
- data.tar.gz: 26006da48ecf12d9f916d4a51d70914a292e4bb15d229467095e1f73e76c76a41784506cc223f65fee9a885d7e1f8a42e04927c1aaed1ee78163722d4a26cd28
6
+ metadata.gz: 45dca40428ef2458e609ce791010e2e39ca378faf452b40a4fad921885de5a10b23a6d07b64b05ed6c868bceed85b031573eec97b049ce4e2be077ddcb1bdf5a
7
+ data.tar.gz: 2f1597ca8cdb6f63a85e36f76c9a0d2f9afba2f80f6005f6b711640794dc0975b0f6f5878247501e71e413637f5e1721f27d7ea732b22684138b7d72babdef36
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # Lightbox for Bootstrap 3 and 4
1
+ # Lightbox for Bootstrap 4
2
2
 
3
- This gem was built for the use of 'Lightbox for Bootstrap 3 and 4' as Rails assets pipeline and you can look for the detailed documents at http://ashleydw.github.io/lightbox/
3
+ This gem was built for the use of 'Lightbox for Bootstrap 4' as Rails assets pipeline and you can look for the detailed documents at http://ashleydw.github.io/lightbox/
4
4
 
5
5
  [![Gem Version](https://badge.fury.io/rb/lightbox-bootstrap-rails.svg)](http://badge.fury.io/rb/lightbox-bootstrap-rails)
6
6
 
@@ -9,7 +9,7 @@ This gem was built for the use of 'Lightbox for Bootstrap 3 and 4' as Rails asse
9
9
  Add this line to your application's Gemfile:
10
10
 
11
11
  ```ruby
12
- gem 'lightbox-bootstrap-rails'
12
+ gem 'lightbox-bootstrap-rails', '5.0.0'
13
13
  ```
14
14
 
15
15
  And then execute:
@@ -70,7 +70,8 @@ Among the gem sources, a test application is provided and there you can find how
70
70
  - v 3.3.0.0 : initially created.
71
71
  - v 3.3.0.1 : deployed to Rubygems.org
72
72
  - v 3.3.0.2 : modified @import stylesheet syntax
73
- - v 3.3.0.3 : fixed typos in ekko-lightbox.min.js and ekko-lightbox.js
73
+ - v 3.3.0.3 : fixed typos in ekko-lightbox.min.js and ekko-lightbox.js ([lightbox v4.0.2](https://github.com/ashleydw/lightbox/tree/v4.0.2) for Boostrap 3).
74
+ - v 5.0.0.0 : updated with [lightbox v5.0.0](https://github.com/ashleydw/lightbox/tree/v5.0.0) for Boostrap 4.
74
75
 
75
76
  ## Contributing
76
77
 
@@ -1,7 +1,7 @@
1
1
  module Lightbox
2
2
  module Bootstrap
3
3
  module Rails
4
- VERSION = "4.alpha5.0"
4
+ VERSION = "5.0.0"
5
5
  end
6
6
  end
7
7
  end
@@ -1,398 +1,602 @@
1
- /*
2
- Lightbox for Bootstrap 3 by @ashleydw
3
- https://github.com/ashleydw/lightbox
4
-
5
- License: https://github.com/ashleydw/lightbox/blob/master/LICENSE
6
- */
7
-
8
-
9
- (function() {
10
- "use strict";
11
- var $, EkkoLightbox;
12
-
13
- $ = jQuery;
14
-
15
- EkkoLightbox = function(element, options) {
16
- var content, footer, header,
17
- _this = this;
18
- this.options = $.extend({
19
- title: null,
20
- footer: null,
21
- remote: null
22
- }, $.fn.ekkoLightbox.defaults, options || {});
23
- this.$element = $(element);
24
- content = '';
25
- this.modal_id = this.options.modal_id ? this.options.modal_id : 'ekkoLightbox-' + Math.floor((Math.random() * 1000) + 1);
26
- header = '<div class="modal-header"' + (this.options.title || this.options.always_show_close ? '' : ' style="display:none"') + '><button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button><h4 class="modal-title">' + (this.options.title || "&nbsp;") + '</h4></div>';
27
- footer = '<div class="modal-footer"' + (this.options.footer ? '' : ' style="display:none"') + '>' + this.options.footer + '</div>';
28
- $(document.body).append('<div id="' + this.modal_id + '" class="ekko-lightbox modal fade" tabindex="-1"><div class="modal-dialog"><div class="modal-content">' + header + '<div class="modal-body"><div class="ekko-lightbox-container"><div></div></div></div>' + footer + '</div></div></div>');
29
- this.modal = $('#' + this.modal_id);
30
- this.modal_dialog = this.modal.find('.modal-dialog').first();
31
- this.modal_content = this.modal.find('.modal-content').first();
32
- this.modal_body = this.modal.find('.modal-body').first();
33
- this.lightbox_container = this.modal_body.find('.ekko-lightbox-container').first();
34
- this.lightbox_body = this.lightbox_container.find('> div:first-child').first();
35
- this.showLoading();
36
- this.modal_arrows = null;
37
- this.border = {
38
- top: parseFloat(this.modal_dialog.css('border-top-width')) + parseFloat(this.modal_content.css('border-top-width')) + parseFloat(this.modal_body.css('border-top-width')),
39
- right: parseFloat(this.modal_dialog.css('border-right-width')) + parseFloat(this.modal_content.css('border-right-width')) + parseFloat(this.modal_body.css('border-right-width')),
40
- bottom: parseFloat(this.modal_dialog.css('border-bottom-width')) + parseFloat(this.modal_content.css('border-bottom-width')) + parseFloat(this.modal_body.css('border-bottom-width')),
41
- left: parseFloat(this.modal_dialog.css('border-left-width')) + parseFloat(this.modal_content.css('border-left-width')) + parseFloat(this.modal_body.css('border-left-width'))
42
- };
43
- this.padding = {
44
- top: parseFloat(this.modal_dialog.css('padding-top')) + parseFloat(this.modal_content.css('padding-top')) + parseFloat(this.modal_body.css('padding-top')),
45
- right: parseFloat(this.modal_dialog.css('padding-right')) + parseFloat(this.modal_content.css('padding-right')) + parseFloat(this.modal_body.css('padding-right')),
46
- bottom: parseFloat(this.modal_dialog.css('padding-bottom')) + parseFloat(this.modal_content.css('padding-bottom')) + parseFloat(this.modal_body.css('padding-bottom')),
47
- left: parseFloat(this.modal_dialog.css('padding-left')) + parseFloat(this.modal_content.css('padding-left')) + parseFloat(this.modal_body.css('padding-left'))
48
- };
49
- this.modal.on('show.bs.modal', this.options.onShow.bind(this)).on('shown.bs.modal', function() {
50
- _this.modal_shown();
51
- return _this.options.onShown.call(_this);
52
- }).on('hide.bs.modal', this.options.onHide.bind(this)).on('hidden.bs.modal', function() {
53
- if (_this.gallery) {
54
- $(document).off('keydown.ekkoLightbox');
55
- }
56
- _this.modal.remove();
57
- return _this.options.onHidden.call(_this);
58
- }).modal('show', options);
59
- return this.modal;
60
- };
61
-
62
- EkkoLightbox.prototype = {
63
- modal_shown: function() {
64
- var video_id,
65
- _this = this;
66
- if (!this.options.remote) {
67
- return this.error('No remote target given');
68
- } else {
69
- this.gallery = this.$element.data('gallery');
70
- if (this.gallery) {
71
- if (this.options.gallery_parent_selector === 'document.body' || this.options.gallery_parent_selector === '') {
72
- this.gallery_items = $(document.body).find('*[data-toggle="lightbox"][data-gallery="' + this.gallery + '"]');
73
- } else {
74
- this.gallery_items = this.$element.parents(this.options.gallery_parent_selector).first().find('*[data-toggle="lightbox"][data-gallery="' + this.gallery + '"]');
75
- }
76
- this.gallery_index = this.gallery_items.index(this.$element);
77
- $(document).on('keydown.ekkoLightbox', this.navigate.bind(this));
78
- if (this.options.directional_arrows && this.gallery_items.length > 1) {
79
- this.lightbox_container.append('<div class="ekko-lightbox-nav-overlay"><a href="#" class="' + this.strip_stops(this.options.left_arrow_class) + '"></a><a href="#" class="' + this.strip_stops(this.options.right_arrow_class) + '"></a></div>');
80
- this.modal_arrows = this.lightbox_container.find('div.ekko-lightbox-nav-overlay').first();
81
- this.lightbox_container.find('a' + this.strip_spaces(this.options.left_arrow_class)).on('click', function(event) {
82
- event.preventDefault();
83
- return _this.navigate_left();
84
- });
85
- this.lightbox_container.find('a' + this.strip_spaces(this.options.right_arrow_class)).on('click', function(event) {
86
- event.preventDefault();
87
- return _this.navigate_right();
88
- });
89
- }
90
- }
91
- if (this.options.type) {
92
- if (this.options.type === 'image') {
93
- return this.preloadImage(this.options.remote, true);
94
- } else if (this.options.type === 'youtube' && (video_id = this.getYoutubeId(this.options.remote))) {
95
- return this.showYoutubeVideo(video_id);
96
- } else if (this.options.type === 'vimeo') {
97
- return this.showVimeoVideo(this.options.remote);
98
- } else if (this.options.type === 'instagram') {
99
- return this.showInstagramVideo(this.options.remote);
100
- } else if (this.options.type === 'url') {
101
- return this.loadRemoteContent(this.options.remote);
102
- } else if (this.options.type === 'video') {
103
- return this.showVideoIframe(this.options.remote);
104
- } else {
105
- return this.error("Could not detect remote target type. Force the type using data-type=\"image|youtube|vimeo|instagram|url|video\"");
106
- }
107
- } else {
108
- return this.detectRemoteType(this.options.remote);
109
- }
110
- }
111
- },
112
- strip_stops: function(str) {
113
- return str.replace(/\./g, '');
114
- },
115
- strip_spaces: function(str) {
116
- return str.replace(/\s/g, '');
117
- },
118
- isImage: function(str) {
119
- return str.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i);
120
- },
121
- isSwf: function(str) {
122
- return str.match(/\.(swf)((\?|#).*)?$/i);
123
- },
124
- getYoutubeId: function(str) {
125
- var match;
126
- match = str.match(/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/);
127
- if (match && match[2].length === 11) {
128
- return match[2];
129
- } else {
130
- return false;
131
- }
132
- },
133
- getVimeoId: function(str) {
134
- if (str.indexOf('vimeo') > 0) {
135
- return str;
136
- } else {
137
- return false;
138
- }
139
- },
140
- getInstagramId: function(str) {
141
- if (str.indexOf('instagram') > 0) {
142
- return str;
143
- } else {
144
- return false;
145
- }
146
- },
147
- navigate: function(event) {
148
- event = event || window.event;
149
- if (event.keyCode === 39 || event.keyCode === 37) {
150
- if (event.keyCode === 39) {
151
- return this.navigate_right();
152
- } else if (event.keyCode === 37) {
153
- return this.navigate_left();
154
- }
155
- }
156
- },
157
- navigateTo: function(index) {
158
- var next, src;
159
- if (index < 0 || index > this.gallery_items.length - 1) {
160
- return this;
161
- }
162
- this.showLoading();
163
- this.gallery_index = index;
164
- this.$element = $(this.gallery_items.get(this.gallery_index));
165
- this.updateTitleAndFooter();
166
- src = this.$element.attr('data-remote') || this.$element.attr('href');
167
- this.detectRemoteType(src, this.$element.attr('data-type') || false);
168
- if (this.gallery_index + 1 < this.gallery_items.length) {
169
- next = $(this.gallery_items.get(this.gallery_index + 1), false);
170
- src = next.attr('data-remote') || next.attr('href');
171
- if (next.attr('data-type') === 'image' || this.isImage(src)) {
172
- return this.preloadImage(src, false);
173
- }
174
- }
175
- },
176
- navigate_left: function() {
177
- if (this.gallery_items.length === 1) {
178
- return;
179
- }
180
- if (this.gallery_index === 0) {
181
- this.gallery_index = this.gallery_items.length - 1;
182
- } else {
183
- this.gallery_index--;
184
- }
185
- this.options.onNavigate.call(this, 'left', this.gallery_index);
186
- return this.navigateTo(this.gallery_index);
187
- },
188
- navigate_right: function() {
189
- if (this.gallery_items.length === 1) {
190
- return;
191
- }
192
- if (this.gallery_index === this.gallery_items.length - 1) {
193
- this.gallery_index = 0;
194
- } else {
195
- this.gallery_index++;
196
- }
197
- this.options.onNavigate.call(this, 'right', this.gallery_index);
198
- return this.navigateTo(this.gallery_index);
199
- },
200
- detectRemoteType: function(src, type) {
201
- var video_id;
202
- type = type || false;
203
- if (type === 'image' || this.isImage(src)) {
204
- this.options.type = 'image';
205
- return this.preloadImage(src, true);
206
- } else if (type === 'youtube' || (video_id = this.getYoutubeId(src))) {
207
- this.options.type = 'youtube';
208
- return this.showYoutubeVideo(video_id);
209
- } else if (type === 'vimeo' || (video_id = this.getVimeoId(src))) {
210
- this.options.type = 'vimeo';
211
- return this.showVimeoVideo(video_id);
212
- } else if (type === 'instagram' || (video_id = this.getInstagramId(src))) {
213
- this.options.type = 'instagram';
214
- return this.showInstagramVideo(video_id);
215
- } else if (type === 'video') {
216
- this.options.type = 'video';
217
- return this.showVideoIframe(video_id);
218
- } else {
219
- this.options.type = 'url';
220
- return this.loadRemoteContent(src);
221
- }
222
- },
223
- updateTitleAndFooter: function() {
224
- var caption, footer, header, title;
225
- header = this.modal_content.find('.modal-header');
226
- footer = this.modal_content.find('.modal-footer');
227
- title = this.$element.data('title') || "";
228
- caption = this.$element.data('footer') || "";
229
- if (title || this.options.always_show_close) {
230
- header.css('display', '').find('.modal-title').html(title || "&nbsp;");
231
- } else {
232
- header.css('display', 'none');
233
- }
234
- if (caption) {
235
- footer.css('display', '').html(caption);
236
- } else {
237
- footer.css('display', 'none');
238
- }
239
- return this;
240
- },
241
- showLoading: function() {
242
- this.lightbox_body.html('<div class="modal-loading">' + this.options.loadingMessage + '</div>');
243
- return this;
244
- },
245
- showYoutubeVideo: function(id) {
246
- var height, width;
247
- width = this.checkDimensions(this.$element.data('width') || 560);
248
- height = width / (560 / 315);
249
- return this.showVideoIframe('//www.youtube.com/embed/' + id + '?badge=0&autoplay=1&html5=1', width, height);
250
- },
251
- showVimeoVideo: function(id) {
252
- var height, width;
253
- width = this.checkDimensions(this.$element.data('width') || 560);
254
- height = width / (500 / 281);
255
- return this.showVideoIframe(id + '?autoplay=1', width, height);
256
- },
257
- showInstagramVideo: function(id) {
258
- var height, width;
259
- width = this.checkDimensions(this.$element.data('width') || 612);
260
- this.resize(width);
261
- height = width + 80;
262
- this.lightbox_body.html('<iframe width="' + width + '" height="' + height + '" src="' + this.addTrailingSlash(id) + 'embed/" frameborder="0" allowfullscreen></iframe>');
263
- this.options.onContentLoaded.call(this);
264
- if (this.modal_arrows) {
265
- return this.modal_arrows.css('display', 'none');
266
- }
267
- },
268
- showVideoIframe: function(url, width, height) {
269
- height = height || width;
270
- this.resize(width);
271
- this.lightbox_body.html('<div class="embed-responsive embed-responsive-16by9"><iframe width="' + width + '" height="' + height + '" src="' + url + '" frameborder="0" allowfullscreen class="embed-responsive-item"></iframe></div>');
272
- this.options.onContentLoaded.call(this);
273
- if (this.modal_arrows) {
274
- this.modal_arrows.css('display', 'none');
275
- }
276
- return this;
277
- },
278
- loadRemoteContent: function(url) {
279
- var disableExternalCheck, width,
280
- _this = this;
281
- width = this.$element.data('width') || 560;
282
- this.resize(width);
283
- disableExternalCheck = this.$element.data('disableExternalCheck') || false;
284
- if (!disableExternalCheck && !this.isExternal(url)) {
285
- this.lightbox_body.load(url, $.proxy(function() {
286
- return _this.$element.trigger('loaded.bs.modal');
287
- }));
288
- } else {
289
- this.lightbox_body.html('<iframe width="' + width + '" height="' + width + '" src="' + url + '" frameborder="0" allowfullscreen></iframe>');
290
- this.options.onContentLoaded.call(this);
291
- }
292
- if (this.modal_arrows) {
293
- this.modal_arrows.css('display', 'none');
294
- }
295
- return this;
296
- },
297
- isExternal: function(url) {
298
- var match;
299
- match = url.match(/^([^:\/?#]+:)?(?:\/\/([^\/?#]*))?([^?#]+)?(\?[^#]*)?(#.*)?/);
300
- if (typeof match[1] === "string" && match[1].length > 0 && match[1].toLowerCase() !== location.protocol) {
301
- return true;
302
- }
303
- if (typeof match[2] === "string" && match[2].length > 0 && match[2].replace(new RegExp(":(" + {
304
- "http:": 80,
305
- "https:": 443
306
- }[location.protocol] + ")?$"), "") !== location.host) {
307
- return true;
308
- }
309
- return false;
310
- },
311
- error: function(message) {
312
- this.lightbox_body.html(message);
313
- return this;
314
- },
315
- preloadImage: function(src, onLoadShowImage) {
316
- var img,
317
- _this = this;
318
- img = new Image();
319
- if ((onLoadShowImage == null) || onLoadShowImage === true) {
320
- img.onload = function() {
321
- var image;
322
- image = $('<img />');
323
- image.attr('src', img.src);
324
- image.addClass('img-responsive img-fluid');
325
- _this.lightbox_body.html(image);
326
- if (_this.modal_arrows) {
327
- _this.modal_arrows.css('display', 'block');
328
- }
329
- _this.resize(img.width);
330
- return _this.options.onContentLoaded.call(_this);
331
- };
332
- img.onerror = function() {
333
- return _this.error('Failed to load image: ' + src);
334
- };
335
- }
336
- img.src = src;
337
- return img;
338
- },
339
- resize: function(width) {
340
- var width_total;
341
- width_total = width + this.border.left + this.padding.left + this.padding.right + this.border.right;
342
- this.modal_dialog.css('width', 'auto').css('max-width', width_total);
343
- this.lightbox_container.find('a').css('line-height', function() {
344
- return $(this).parent().height() + 'px';
345
- });
346
- return this;
347
- },
348
- checkDimensions: function(width) {
349
- var body_width, width_total;
350
- width_total = width + this.border.left + this.padding.left + this.padding.right + this.border.right;
351
- body_width = document.body.clientWidth;
352
- if (width_total > body_width) {
353
- width = this.modal_body.width();
354
- }
355
- return width;
356
- },
357
- close: function() {
358
- return this.modal.modal('hide');
359
- },
360
- addTrailingSlash: function(url) {
361
- if (url.substr(-1) !== '/') {
362
- url += '/';
363
- }
364
- return url;
365
- }
366
- };
367
-
368
- $.fn.ekkoLightbox = function(options) {
369
- return this.each(function() {
370
- var $this;
371
- $this = $(this);
372
- options = $.extend({
373
- remote: $this.attr('data-remote') || $this.attr('href'),
374
- gallery_parent_selector: $this.attr('data-parent'),
375
- type: $this.attr('data-type')
376
- }, options, $this.data());
377
- new EkkoLightbox(this, options);
378
- return this;
379
- });
380
- };
381
-
382
- $.fn.ekkoLightbox.defaults = {
383
- gallery_parent_selector: 'document.body',
384
- left_arrow_class: '.glyphicon .glyphicon-chevron-left',
385
- right_arrow_class: '.glyphicon .glyphicon-chevron-right',
386
- directional_arrows: true,
387
- type: null,
388
- always_show_close: true,
389
- loadingMessage: 'Loading...',
390
- onShow: function() {},
391
- onShown: function() {},
392
- onHide: function() {},
393
- onHidden: function() {},
394
- onNavigate: function() {},
395
- onContentLoaded: function() {}
396
- };
397
-
398
- }).call(this);
1
+ /*!
2
+ * Lightbox for Bootstrap by @ashleydw
3
+ * https://github.com/ashleydw/lightbox
4
+ *
5
+ * License: https://github.com/ashleydw/lightbox/blob/master/LICENSE
6
+ */
7
+ +function ($) {
8
+
9
+ 'use strict';
10
+
11
+ var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
12
+
13
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
14
+
15
+ var Lightbox = (function ($) {
16
+
17
+ var NAME = 'ekkoLightbox';
18
+ var JQUERY_NO_CONFLICT = $.fn[NAME];
19
+
20
+ var Default = {
21
+ title: '',
22
+ footer: '',
23
+ showArrows: true, //display the left / right arrows or not
24
+ type: null, //force the lightbox into image / youtube mode. if null, or not image|youtube|vimeo; detect it
25
+ alwaysShowClose: false, //always show the close button, even if there is no title
26
+ loadingMessage: '<div class="ekko-lightbox-loader"><div><div></div><div></div></div></div>', // http://tobiasahlin.com/spinkit/
27
+ leftArrow: '<span>&#10094;</span>',
28
+ rightArrow: '<span>&#10095;</span>',
29
+ strings: {
30
+ close: 'Close',
31
+ fail: 'Failed to load image:',
32
+ type: 'Could not detect remote target type. Force the type using data-type'
33
+ },
34
+ doc: document, // if in an iframe can specify top.document
35
+ onShow: function onShow() {},
36
+ onShown: function onShown() {},
37
+ onHide: function onHide() {},
38
+ onHidden: function onHidden() {},
39
+ onNavigate: function onNavigate() {},
40
+ onContentLoaded: function onContentLoaded() {}
41
+ };
42
+
43
+ var Lightbox = (function () {
44
+ _createClass(Lightbox, null, [{
45
+ key: 'Default',
46
+
47
+ /**
48
+
49
+ Class properties:
50
+
51
+ _$element: null -> the <a> element currently being displayed
52
+ _$modal: The bootstrap modal generated
53
+ _$modalDialog: The .modal-dialog
54
+ _$modalContent: The .modal-content
55
+ _$modalBody: The .modal-body
56
+ _$modalHeader: The .modal-header
57
+ _$modalFooter: The .modal-footer
58
+ _$lightboxContainerOne: Container of the first lightbox element
59
+ _$lightboxContainerTwo: Container of the second lightbox element
60
+ _$lightboxBody: First element in the container
61
+ _$modalArrows: The overlayed arrows container
62
+ _$galleryItems: Other <a>'s available for this gallery
63
+ _galleryName: Name of the current data('gallery') showing
64
+ _galleryIndex: The current index of the _$galleryItems being shown
65
+ _config: {} the options for the modal
66
+ _modalId: unique id for the current lightbox
67
+ _padding / _border: CSS properties for the modal container; these are used to calculate the available space for the content
68
+ */
69
+
70
+ get: function get() {
71
+ return Default;
72
+ }
73
+ }]);
74
+
75
+ function Lightbox($element, config) {
76
+ var _this = this;
77
+
78
+ _classCallCheck(this, Lightbox);
79
+
80
+ this._config = $.extend({}, Default, config);
81
+ this._$modalArrows = null;
82
+ this._galleryIndex = 0;
83
+ this._galleryName = null;
84
+ this._padding = null;
85
+ this._border = null;
86
+ this._titleIsShown = false;
87
+ this._footerIsShown = false;
88
+ this._wantedWidth = 0;
89
+ this._wantedHeight = 0;
90
+ this._modalId = 'ekkoLightbox-' + Math.floor(Math.random() * 1000 + 1);
91
+ this._$element = $element instanceof jQuery ? $element : $($element);
92
+
93
+ var header = '<div class="modal-header"' + (this._config.title || this._config.alwaysShowClose ? '' : ' style="display:none"') + '><button type="button" class="close" data-dismiss="modal" aria-label="' + this._config.strings.close + '"><span aria-hidden="true">&times;</span></button><h4 class="modal-title">' + (this._config.title || "&nbsp;") + '</h4></div>';
94
+ var footer = '<div class="modal-footer"' + (this._config.footer ? '' : ' style="display:none"') + '>' + (this._config.footer || "&nbsp;") + '</div>';
95
+ var body = '<div class="modal-body"><div class="ekko-lightbox-container"><div class="ekko-lightbox-item fade in"></div><div class="ekko-lightbox-item fade"></div></div></div>';
96
+ var dialog = '<div class="modal-dialog" role="document"><div class="modal-content">' + header + body + footer + '</div></div>';
97
+ $(this._config.doc.body).append('<div id="' + this._modalId + '" class="ekko-lightbox modal fade" tabindex="-1" tabindex="-1" role="dialog" aria-hidden="true">' + dialog + '</div>');
98
+
99
+ this._$modal = $('#' + this._modalId, this._config.doc);
100
+ this._$modalDialog = this._$modal.find('.modal-dialog').first();
101
+ this._$modalContent = this._$modal.find('.modal-content').first();
102
+ this._$modalBody = this._$modal.find('.modal-body').first();
103
+ this._$modalHeader = this._$modal.find('.modal-header').first();
104
+ this._$modalFooter = this._$modal.find('.modal-footer').first();
105
+
106
+ this._$lightboxContainer = this._$modalBody.find('.ekko-lightbox-container').first();
107
+ this._$lightboxBodyOne = this._$lightboxContainer.find('> div:first-child').first();
108
+ this._$lightboxBodyTwo = this._$lightboxContainer.find('> div:last-child').first();
109
+
110
+ this._border = this._calculateBorders();
111
+ this._padding = this._calculatePadding();
112
+
113
+ this._galleryName = this._$element.data('gallery');
114
+ if (this._galleryName) {
115
+ this._$galleryItems = $(document.body).find('*[data-gallery="' + this._galleryName + '"]');
116
+ this._galleryIndex = this._$galleryItems.index(this._$element);
117
+ $(document).on('keydown.ekkoLightbox', this._navigationalBinder.bind(this));
118
+
119
+ // add the directional arrows to the modal
120
+ if (this._config.showArrows && this._$galleryItems.length > 1) {
121
+ this._$lightboxContainer.append('<div class="ekko-lightbox-nav-overlay"><a href="#">' + this._config.leftArrow + '</a><a href="#">' + this._config.rightArrow + '</a></div>');
122
+ this._$modalArrows = this._$lightboxContainer.find('div.ekko-lightbox-nav-overlay').first();
123
+ this._$lightboxContainer.on('click', 'a:first-child', function (event) {
124
+ event.preventDefault();
125
+ return _this.navigateLeft();
126
+ });
127
+ this._$lightboxContainer.on('click', 'a:last-child', function (event) {
128
+ event.preventDefault();
129
+ return _this.navigateRight();
130
+ });
131
+ }
132
+ }
133
+
134
+ this._$modal.on('show.bs.modal', this._config.onShow.bind(this)).on('shown.bs.modal', function () {
135
+ _this._toggleLoading(true);
136
+ _this._handle();
137
+ return _this._config.onShown.call(_this);
138
+ }).on('hide.bs.modal', this._config.onHide.bind(this)).on('hidden.bs.modal', function () {
139
+ if (_this._galleryName) {
140
+ $(document).off('keydown.ekkoLightbox');
141
+ $(window).off('resize.ekkoLightbox');
142
+ }
143
+ _this._$modal.remove();
144
+ return _this._config.onHidden.call(_this);
145
+ }).modal(this._config);
146
+
147
+ $(window).on('resize.ekkoLightbox', function () {
148
+ _this._resize(_this._wantedWidth, _this._wantedHeight);
149
+ });
150
+ }
151
+
152
+ _createClass(Lightbox, [{
153
+ key: 'element',
154
+ value: function element() {
155
+ return this._$element;
156
+ }
157
+ }, {
158
+ key: 'modal',
159
+ value: function modal() {
160
+ return this._$modal;
161
+ }
162
+ }, {
163
+ key: 'navigateTo',
164
+ value: function navigateTo(index) {
165
+
166
+ if (index < 0 || index > this._$galleryItems.length - 1) return this;
167
+
168
+ this._galleryIndex = index;
169
+
170
+ this._$element = $(this._$galleryItems.get(this._galleryIndex));
171
+ this._handle();
172
+ }
173
+ }, {
174
+ key: 'navigateLeft',
175
+ value: function navigateLeft() {
176
+
177
+ if (this._$galleryItems.length === 1) return;
178
+
179
+ if (this._galleryIndex === 0) this._galleryIndex = this._$galleryItems.length - 1;else //circular
180
+ this._galleryIndex--;
181
+
182
+ this._config.onNavigate.call(this, 'left', this._galleryIndex);
183
+ return this.navigateTo(this._galleryIndex);
184
+ }
185
+ }, {
186
+ key: 'navigateRight',
187
+ value: function navigateRight() {
188
+
189
+ if (this._$galleryItems.length === 1) return;
190
+
191
+ if (this._galleryIndex === this._$galleryItems.length - 1) this._galleryIndex = 0;else //circular
192
+ this._galleryIndex++;
193
+
194
+ this._config.onNavigate.call(this, 'right', this._galleryIndex);
195
+ return this.navigateTo(this._galleryIndex);
196
+ }
197
+ }, {
198
+ key: 'close',
199
+ value: function close() {
200
+ return this._$modal.modal('hide');
201
+ }
202
+
203
+ // helper private methods
204
+ }, {
205
+ key: '_navigationalBinder',
206
+ value: function _navigationalBinder(event) {
207
+ event = event || window.event;
208
+ if (event.keyCode === 39) return this.navigateRight();
209
+ if (event.keyCode === 37) return this.navigateLeft();
210
+ }
211
+
212
+ // type detection private methods
213
+ }, {
214
+ key: '_detectRemoteType',
215
+ value: function _detectRemoteType(src, type) {
216
+
217
+ type = type || false;
218
+
219
+ if (!type && this._isImage(src)) type = 'image';
220
+ if (!type && this._getYoutubeId(src)) type = 'youtube';
221
+ if (!type && this._getVimeoId(src)) type = 'vimeo';
222
+ if (!type && this._getInstagramId(src)) type = 'instagram';
223
+
224
+ if (!type || ['image', 'youtube', 'vimeo', 'instagram', 'video', 'url'].indexOf(type) < 0) type = 'url';
225
+
226
+ return type;
227
+ }
228
+ }, {
229
+ key: '_isImage',
230
+ value: function _isImage(string) {
231
+ return string && string.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i);
232
+ }
233
+ }, {
234
+ key: '_containerToUse',
235
+ value: function _containerToUse() {
236
+ var _this2 = this;
237
+
238
+ // if currently showing an image, fade it out and remove
239
+ var $toUse = this._$lightboxBodyTwo;
240
+ var $current = this._$lightboxBodyOne;
241
+
242
+ if (this._$lightboxBodyTwo.hasClass('in')) {
243
+ $toUse = this._$lightboxBodyOne;
244
+ $current = this._$lightboxBodyTwo;
245
+ }
246
+
247
+ $current.removeClass('in');
248
+ setTimeout(function () {
249
+ if (!_this2._$lightboxBodyTwo.hasClass('in')) _this2._$lightboxBodyTwo.empty();
250
+ if (!_this2._$lightboxBodyOne.hasClass('in')) _this2._$lightboxBodyOne.empty();
251
+ }, 500);
252
+
253
+ $toUse.addClass('in');
254
+ return $toUse;
255
+ }
256
+ }, {
257
+ key: '_handle',
258
+ value: function _handle() {
259
+
260
+ var $toUse = this._containerToUse();
261
+ this._updateTitleAndFooter();
262
+
263
+ var currentRemote = this._$element.attr('data-remote') || this._$element.attr('href');
264
+ var currentType = this._detectRemoteType(currentRemote, this._$element.attr('data-type') || false);
265
+
266
+ if (['image', 'youtube', 'vimeo', 'instagram', 'video', 'url'].indexOf(currentType) < 0) return this._error(this._config.strings.type);
267
+
268
+ switch (currentType) {
269
+ case 'image':
270
+ this._preloadImage(currentRemote, $toUse);
271
+ this._preloadImageByIndex(this._galleryIndex, 3);
272
+ break;
273
+ case 'youtube':
274
+ this._showYoutubeVideo(currentRemote, $toUse);
275
+ break;
276
+ case 'vimeo':
277
+ this._showVimeoVideo(this._getVimeoId(currentRemote), $toUse);
278
+ break;
279
+ case 'instagram':
280
+ this._showInstagramVideo(this._getInstagramId(currentRemote), $toUse);
281
+ break;
282
+ case 'video':
283
+ this._showHtml5Video(currentRemote, $toUse);
284
+ break;
285
+ default:
286
+ // url
287
+ this._loadRemoteContent(currentRemote, $toUse);
288
+ break;
289
+ }
290
+
291
+ return this;
292
+ }
293
+ }, {
294
+ key: '_getYoutubeId',
295
+ value: function _getYoutubeId(string) {
296
+ if (!string) return false;
297
+ var matches = string.match(/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/);
298
+ return matches && matches[2].length === 11 ? matches[2] : false;
299
+ }
300
+ }, {
301
+ key: '_getVimeoId',
302
+ value: function _getVimeoId(string) {
303
+ return string && string.indexOf('vimeo') > 0 ? string : false;
304
+ }
305
+ }, {
306
+ key: '_getInstagramId',
307
+ value: function _getInstagramId(string) {
308
+ return string && string.indexOf('instagram') > 0 ? string : false;
309
+ }
310
+
311
+ // layout private methods
312
+ }, {
313
+ key: '_toggleLoading',
314
+ value: function _toggleLoading(show) {
315
+ show = show || false;
316
+ if (show) {
317
+ this._$modalDialog.css('display', 'none');
318
+ this._$modal.removeClass('in');
319
+ $('.modal-backdrop').append(this._config.loadingMessage);
320
+ } else {
321
+ this._$modalDialog.css('display', 'block');
322
+ this._$modal.addClass('in');
323
+ $('.modal-backdrop').find('.ekko-lightbox-loader').remove();
324
+ }
325
+ return this;
326
+ }
327
+ }, {
328
+ key: '_calculateBorders',
329
+ value: function _calculateBorders() {
330
+ return {
331
+ top: this._totalCssByAttribute('border-top-width'),
332
+ right: this._totalCssByAttribute('border-right-width'),
333
+ bottom: this._totalCssByAttribute('border-bottom-width'),
334
+ left: this._totalCssByAttribute('border-left-width')
335
+ };
336
+ }
337
+ }, {
338
+ key: '_calculatePadding',
339
+ value: function _calculatePadding() {
340
+ return {
341
+ top: this._totalCssByAttribute('padding-top'),
342
+ right: this._totalCssByAttribute('padding-right'),
343
+ bottom: this._totalCssByAttribute('padding-bottom'),
344
+ left: this._totalCssByAttribute('padding-left')
345
+ };
346
+ }
347
+ }, {
348
+ key: '_totalCssByAttribute',
349
+ value: function _totalCssByAttribute(attribute) {
350
+ return parseInt(this._$modalDialog.css(attribute), 10) + parseInt(this._$modalContent.css(attribute), 10) + parseInt(this._$modalBody.css(attribute), 10);
351
+ }
352
+ }, {
353
+ key: '_updateTitleAndFooter',
354
+ value: function _updateTitleAndFooter() {
355
+ var title = this._$element.data('title') || "";
356
+ var caption = this._$element.data('footer') || "";
357
+
358
+ this._titleIsShown = false;
359
+ if (title || this._config.alwaysShowClose) {
360
+ this._titleIsShown = true;
361
+ this._$modalHeader.css('display', '').find('.modal-title').html(title || "&nbsp;");
362
+ } else this._$modalHeader.css('display', 'none');
363
+
364
+ this._footerIsShown = false;
365
+ if (caption) {
366
+ this._footerIsShown = true;
367
+ this._$modalFooter.css('display', '').html(caption);
368
+ } else this._$modalFooter.css('display', 'none');
369
+
370
+ return this;
371
+ }
372
+ }, {
373
+ key: '_showYoutubeVideo',
374
+ value: function _showYoutubeVideo(remote, $containerForElement) {
375
+ var id = this._getYoutubeId(remote);
376
+ var query = remote.indexOf('&') > 0 ? remote.substr(remote.indexOf('&')) : '';
377
+ var width = this._$element.data('width') || 560;
378
+ var height = this._$element.data('height') || width / (560 / 315);
379
+ return this._showVideoIframe('//www.youtube.com/embed/' + id + '?badge=0&autoplay=1&html5=1' + query, width, height, $containerForElement);
380
+ }
381
+ }, {
382
+ key: '_showVimeoVideo',
383
+ value: function _showVimeoVideo(id, $containerForElement) {
384
+ var width = 500;
385
+ var height = this._$element.data('height') || width / (560 / 315);
386
+ return this._showVideoIframe(id + '?autoplay=1', width, height, $containerForElement);
387
+ }
388
+ }, {
389
+ key: '_showInstagramVideo',
390
+ value: function _showInstagramVideo(id, $containerForElement) {
391
+ // instagram load their content into iframe's so this can be put straight into the element
392
+ var width = this._$element.data('width') || 612;
393
+ var height = width + 80;
394
+ id = id.substr(-1) !== '/' ? id + '/' : id; // ensure id has trailing slash
395
+ $containerForElement.html('<iframe width="' + width + '" height="' + height + '" src="' + id + 'embed/" frameborder="0" allowfullscreen></iframe>');
396
+ this._resize(width, height);
397
+ this._config.onContentLoaded.call(this);
398
+ if (this._$modalArrows) //hide the arrows when showing video
399
+ this._$modalArrows.css('display', 'none');
400
+ this._toggleLoading(false);
401
+ return this;
402
+ }
403
+ }, {
404
+ key: '_showVideoIframe',
405
+ value: function _showVideoIframe(url, width, height, $containerForElement) {
406
+ // should be used for videos only. for remote content use loadRemoteContent (data-type=url)
407
+ height = height || width; // default to square
408
+ $containerForElement.html('<div class="embed-responsive embed-responsive-16by9"><iframe width="' + width + '" height="' + height + '" src="' + url + '" frameborder="0" allowfullscreen class="embed-responsive-item"></iframe></div>');
409
+ this._resize(width, height);
410
+ this._config.onContentLoaded.call(this);
411
+ if (this._$modalArrows) this._$modalArrows.css('display', 'none'); //hide the arrows when showing video
412
+ this._toggleLoading(false);
413
+ return this;
414
+ }
415
+ }, {
416
+ key: '_showHtml5Video',
417
+ value: function _showHtml5Video(url, $containerForElement) {
418
+ // should be used for videos only. for remote content use loadRemoteContent (data-type=url)
419
+ var width = this._$element.data('width') || 560;
420
+ var height = this._$element.data('height') || width / (560 / 315);
421
+ $containerForElement.html('<div class="embed-responsive embed-responsive-16by9"><video width="' + width + '" height="' + height + '" src="' + url + '" preload="auto" autoplay controls class="embed-responsive-item"></video></div>');
422
+ this._resize(width, height);
423
+ this._config.onContentLoaded.call(this);
424
+ if (this._$modalArrows) this._$modalArrows.css('display', 'none'); //hide the arrows when showing video
425
+ this._toggleLoading(false);
426
+ return this;
427
+ }
428
+ }, {
429
+ key: '_loadRemoteContent',
430
+ value: function _loadRemoteContent(url, $containerForElement) {
431
+ var _this3 = this;
432
+
433
+ var width = this._$element.data('width') || 560;
434
+ var height = this._$element.data('height') || 560;
435
+
436
+ var disableExternalCheck = this._$element.data('disableExternalCheck') || false;
437
+ this._toggleLoading(false);
438
+
439
+ // external urls are loading into an iframe
440
+ // local ajax can be loaded into the container itself
441
+ if (!disableExternalCheck && !this._isExternal(url)) {
442
+ $containerForElement.load(url, $.proxy(function () {
443
+ return _this3._$element.trigger('loaded.bs.modal');l;
444
+ }));
445
+ } else {
446
+ $containerForElement.html('<iframe src="' + url + '" frameborder="0" allowfullscreen></iframe>');
447
+ this._config.onContentLoaded.call(this);
448
+ }
449
+
450
+ if (this._$modalArrows) //hide the arrows when remote content
451
+ this._$modalArrows.css('display', 'none');
452
+
453
+ this._resize(width, height);
454
+ return this;
455
+ }
456
+ }, {
457
+ key: '_isExternal',
458
+ value: function _isExternal(url) {
459
+ var match = url.match(/^([^:\/?#]+:)?(?:\/\/([^\/?#]*))?([^?#]+)?(\?[^#]*)?(#.*)?/);
460
+ if (typeof match[1] === "string" && match[1].length > 0 && match[1].toLowerCase() !== location.protocol) return true;
461
+
462
+ if (typeof match[2] === "string" && match[2].length > 0 && match[2].replace(new RegExp(':(' + ({
463
+ "http:": 80,
464
+ "https:": 443
465
+ })[location.protocol] + ')?$'), "") !== location.host) return true;
466
+
467
+ return false;
468
+ }
469
+ }, {
470
+ key: '_error',
471
+ value: function _error(message) {
472
+ console.error(message);
473
+ this._containerToUse().html(message);
474
+ this._resize(300, 300);
475
+ return this;
476
+ }
477
+ }, {
478
+ key: '_preloadImageByIndex',
479
+ value: function _preloadImageByIndex(startIndex, numberOfTimes) {
480
+
481
+ if (!this._$galleryItems) return;
482
+
483
+ var next = $(this._$galleryItems.get(startIndex), false);
484
+ if (typeof next == 'undefined') return;
485
+
486
+ var src = next.attr('data-remote') || next.attr('href');
487
+ if (next.attr('data-type') === 'image' || this._isImage(src)) this._preloadImage(src, false);
488
+
489
+ if (numberOfTimes > 0) return this._preloadImageByIndex(startIndex + 1, numberOfTimes - 1);
490
+ }
491
+ }, {
492
+ key: '_preloadImage',
493
+ value: function _preloadImage(src, $containerForImage) {
494
+ var _this4 = this;
495
+
496
+ $containerForImage = $containerForImage || false;
497
+
498
+ var img = new Image();
499
+ if ($containerForImage) {
500
+ (function () {
501
+
502
+ // if loading takes > 200ms show a loader
503
+ var loadingTimeout = setTimeout(function () {
504
+ $containerForImage.append(_this4._config.loadingMessage);
505
+ }, 200);
506
+
507
+ img.onload = function () {
508
+ if (loadingTimeout) clearTimeout(loadingTimeout);
509
+ loadingTimeout = null;
510
+ var image = $('<img />');
511
+ image.attr('src', img.src);
512
+ image.addClass('img-fluid');
513
+ $containerForImage.html(image);
514
+ if (_this4._$modalArrows) _this4._$modalArrows.css('display', ''); // remove display to default to css property
515
+
516
+ _this4._resize(img.width, img.height);
517
+ _this4._toggleLoading(false);
518
+ return _this4._config.onContentLoaded.call(_this4);
519
+ };
520
+ img.onerror = function () {
521
+ _this4._toggleLoading(false);
522
+ return _this4._error(_this4._config.strings.fail + (' ' + src));
523
+ };
524
+ })();
525
+ }
526
+
527
+ img.src = src;
528
+ return img;
529
+ }
530
+ }, {
531
+ key: '_resize',
532
+ value: function _resize(width, height) {
533
+
534
+ height = height || width;
535
+ this._wantedWidth = width;
536
+ this._wantedHeight = height;
537
+
538
+ // if width > the available space, scale down the expected width and height
539
+ var widthBorderAndPadding = this._padding.left + this._padding.right + this._border.left + this._border.right;
540
+ var maxWidth = Math.min(width + widthBorderAndPadding, this._config.doc.body.clientWidth);
541
+ if (width + widthBorderAndPadding > maxWidth) {
542
+ height = (maxWidth - widthBorderAndPadding) / width * height;
543
+ width = maxWidth;
544
+ } else width = width + widthBorderAndPadding;
545
+
546
+ var headerHeight = 0,
547
+ footerHeight = 0;
548
+
549
+ // as the resize is performed the modal is show, the calculate might fail
550
+ // if so, default to the default sizes
551
+ if (this._footerIsShown) footerHeight = this._$modalFooter.outerHeight(true) || 55;
552
+
553
+ if (this._titleIsShown) headerHeight = this._$modalHeader.outerHeight(true) || 67;
554
+
555
+ var borderPadding = this._padding.top + this._padding.bottom + this._border.bottom + this._border.top;
556
+
557
+ //calculated each time as resizing the window can cause them to change due to Bootstraps fluid margins
558
+ var margins = parseFloat(this._$modalDialog.css('margin-top')) + parseFloat(this._$modalDialog.css('margin-bottom'));
559
+
560
+ var maxHeight = Math.min(height, $(window).height() - borderPadding - margins - headerHeight - footerHeight);
561
+ if (height > maxHeight) {
562
+ // if height > the available height, scale down the width
563
+ var factor = Math.min(maxHeight / height, 1);
564
+ width = Math.ceil(factor * width);
565
+ }
566
+
567
+ this._$lightboxContainer.css('height', maxHeight);
568
+ this._$modalDialog.css('width', 'auto').css('maxWidth', width);
569
+
570
+ this._$modal.modal('_handleUpdate');
571
+ return this;
572
+ }
573
+ }], [{
574
+ key: '_jQueryInterface',
575
+ value: function _jQueryInterface(config) {
576
+ var _this5 = this;
577
+
578
+ config = config || {};
579
+ return this.each(function () {
580
+ var $this = $(_this5);
581
+ var _config = $.extend({}, Lightbox.Default, $this.data(), typeof config === 'object' && config);
582
+
583
+ new Lightbox(_this5, _config);
584
+ });
585
+ }
586
+ }]);
587
+
588
+ return Lightbox;
589
+ })();
590
+
591
+ $.fn[NAME] = Lightbox._jQueryInterface;
592
+ $.fn[NAME].Constructor = Lightbox;
593
+ $.fn[NAME].noConflict = function () {
594
+ $.fn[NAME] = JQUERY_NO_CONFLICT;
595
+ return Lightbox._jQueryInterface;
596
+ };
597
+
598
+ return Lightbox;
599
+ })(jQuery);
600
+ //# sourceMappingURL=ekko-lightbox.js.map
601
+
602
+ }(jQuery);