PluginProbe ʕ •ᴥ•ʔ
Responsive Lightbox & Gallery / 2.5.3
Responsive Lightbox & Gallery v2.5.3
2.7.8 trunk 1.0.0 1.0.1 1.0.1.1 1.0.2 1.0.3 1.0.4 1.1.0 1.1.1 1.1.2 1.2.0 1.2.1 1.2.2 1.2.3 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.4.0 1.4.0.1 1.4.1 1.4.11 1.4.12 1.4.13 1.4.14 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.6.0 1.6.1 1.6.10 1.6.11 1.6.12 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 2.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.1 2.2.0 2.2.1 2.2.2 2.2.3 2.2.3.1 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.3.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.4.8 2.4.9 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 2.6.0 2.6.1 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7
responsive-lightbox / assets / swipebox / jquery.swipebox.js
responsive-lightbox / assets / swipebox Last commit date
img 11 years ago README.md 4 years ago jquery.swipebox.js 10 months ago jquery.swipebox.min.js 10 months ago swipebox.css 4 years ago swipebox.min.css 4 years ago
jquery.swipebox.js
967 lines
1 /*! Swipebox v1.5.2 | Constantin Saguin csag.co | MIT License | github.com/brutaldesign/swipebox */
2
3 ;( function ( window, document, $, undefined ) {
4
5 $.swipebox = function( elem, options ) {
6
7 $( elem ).addClass( 'swipebox' ); // fugly but yea, swipebox class all the things
8
9 // Default options
10 var ui,
11 defaults = {
12 useCSS : true,
13 useSVG : true,
14 initialIndexOnArray : 0,
15 removeBarsOnMobile : true,
16 hideCloseButtonOnMobile : false,
17 hideBarsDelay : 3000,
18 videoMaxWidth : 1140,
19 vimeoColor : 'cccccc',
20 beforeOpen: null,
21 afterOpen: null,
22 afterClose: null,
23 afterMedia: null,
24 nextSlide: null,
25 prevSlide: null,
26 loopAtEnd: false,
27 autoplayVideos: false,
28 queryStringData: {},
29 toggleClassOnLoad: ''
30 },
31
32 plugin = this,
33 elements = [], // slides array [ { href:'...', title:'...' }, ...],
34 $elem,
35 selector = '.swipebox',
36 isMobile = navigator.userAgent.match( /(iPad)|(iPhone)|(iPod)|(Android)|(PlayBook)|(BB10)|(BlackBerry)|(Opera Mini)|(IEMobile)|(webOS)|(MeeGo)/i ),
37 isTouch = isMobile !== null || document.createTouch !== undefined || ( 'ontouchstart' in window ) || ( 'onmsgesturechange' in window ) || navigator.msMaxTouchPoints,
38 supportSVG = !! document.createElementNS && !! document.createElementNS( 'http://www.w3.org/2000/svg', 'svg').createSVGRect,
39 winWidth = window.innerWidth ? window.innerWidth : $( window ).width(),
40 winHeight = window.innerHeight ? window.innerHeight : $( window ).height(),
41 currentX = 0,
42 /* jshint multistr: true */
43 html = '<div id="swipebox-overlay">\
44 <div id="swipebox-container">\
45 <div id="swipebox-slider"></div>\
46 <div id="swipebox-top-bar">\
47 <div id="swipebox-title"></div>\
48 </div>\
49 <div id="swipebox-bottom-bar">\
50 <div id="swipebox-arrows">\
51 <a id="swipebox-prev"></a>\
52 <a id="swipebox-next"></a>\
53 </div>\
54 </div>\
55 <a id="swipebox-close"></a>\
56 </div>\
57 </div>';
58
59 plugin.settings = {};
60
61 $.swipebox.close = function () {
62 ui.closeSlide();
63 };
64
65 $.swipebox.extend = function () {
66 return ui;
67 };
68
69 plugin.init = function() {
70
71 plugin.settings = $.extend( {}, defaults, options );
72
73 if ( Array.isArray( elem ) ) {
74
75 elements = elem;
76 ui.target = $( window );
77 ui.init( plugin.settings.initialIndexOnArray );
78
79 } else {
80
81 $( document ).on( 'click', selector, function( event ) {
82
83 // console.log( isTouch );
84
85 if ( event.target.parentNode.className === 'slide current' ) {
86
87 return false;
88 }
89
90 if ( ! Array.isArray( elem ) ) {
91 ui.destroy();
92 $elem = $( selector );
93 ui.actions();
94 }
95
96 elements = [];
97 var index, relType, relVal;
98
99 // Allow for HTML5 compliant attribute before legacy use of rel
100 if ( ! relVal ) {
101 relType = 'data-rel';
102 relVal = $( this ).attr( relType );
103 }
104
105 if ( ! relVal ) {
106 relType = 'rel';
107 relVal = $( this ).attr( relType );
108 }
109
110 if ( relVal && relVal !== '' && relVal !== 'nofollow' ) {
111 $elem = $( selector ).filter( '[' + relType + '="' + relVal + '"]' );
112 } else {
113 $elem = $( selector );
114 }
115
116 $elem.each( function() {
117
118 var title = null,
119 href = null;
120
121 if ( $( this ).attr( 'title' ) ) {
122 title = $( this ).attr( 'title' );
123 }
124
125 if ( $( this ).attr( 'href' ) ) {
126 href = $( this ).attr( 'href' );
127 }
128
129 elements.push( {
130 href: href,
131 title: title
132 } );
133 } );
134
135 index = $elem.index( $( this ) );
136 event.preventDefault();
137 event.stopPropagation();
138 ui.target = $( event.target );
139 ui.init( index );
140 } );
141 }
142 };
143
144 ui = {
145
146 /**
147 * Initiate Swipebox
148 */
149 init : function( index ) {
150 if ( plugin.settings.beforeOpen ) {
151 plugin.settings.beforeOpen();
152 }
153 this.target.trigger( 'swipebox-start' );
154 $.swipebox.isOpen = true;
155 this.build();
156 this.openSlide( index );
157 this.openMedia( index );
158 this.preloadMedia( index+1 );
159 this.preloadMedia( index-1 );
160 if ( plugin.settings.afterOpen ) {
161 plugin.settings.afterOpen(index);
162 }
163 },
164
165 /**
166 * Built HTML containers and fire main functions
167 */
168 build : function () {
169 var $this = this, bg;
170
171 $( 'body' ).append( html );
172
173 if ( supportSVG && plugin.settings.useSVG === true ) {
174 bg = $( '#swipebox-close' ).css( 'background-image' );
175 bg = bg.replace( 'png', 'svg' );
176 $( '#swipebox-prev, #swipebox-next, #swipebox-close' ).css( {
177 'background-image' : bg
178 } );
179 }
180
181 if ( isMobile && plugin.settings.removeBarsOnMobile ) {
182 $( '#swipebox-bottom-bar, #swipebox-top-bar' ).remove();
183 }
184
185 $.each( elements, function() {
186 $( '#swipebox-slider' ).append( '<div class="slide"></div>' );
187 } );
188
189 $this.setDim();
190 $this.actions();
191
192 if ( isTouch ) {
193 $this.gesture();
194 }
195
196 // Devices can have both touch and keyboard input so always allow key events
197 $this.keyboard();
198
199 $this.animBars();
200 $this.resize();
201
202 },
203
204 /**
205 * Set dimensions depending on windows width and height
206 */
207 setDim : function () {
208
209 var width, height, sliderCss = {};
210
211 // Reset dimensions on mobile orientation change
212 if ( 'onorientationchange' in window ) {
213
214 window.addEventListener( 'orientationchange', function() {
215 if ( window.orientation === 0 ) {
216 width = winWidth;
217 height = winHeight;
218 } else if ( window.orientation === 90 || window.orientation === -90 ) {
219 width = winHeight;
220 height = winWidth;
221 }
222 }, false );
223
224
225 } else {
226
227 width = window.innerWidth ? window.innerWidth : $( window ).width();
228 height = window.innerHeight ? window.innerHeight : $( window ).height();
229 }
230
231 sliderCss = {
232 width : width,
233 height : height
234 };
235
236 $( '#swipebox-overlay' ).css( sliderCss );
237
238 },
239
240 /**
241 * Reset dimensions on window resize envent
242 */
243 resize : function () {
244 var $this = this;
245
246 $( window ).on( 'resize', function() {
247 $this.setDim();
248 } ).trigger( 'resize' );
249 },
250
251 /**
252 * Check if device supports CSS transitions
253 */
254 supportTransition : function () {
255
256 var prefixes = 'transition WebkitTransition MozTransition OTransition msTransition KhtmlTransition'.split( ' ' ),
257 i;
258
259 for ( i = 0; i < prefixes.length; i++ ) {
260 if ( document.createElement( 'div' ).style[ prefixes[i] ] !== undefined ) {
261 return prefixes[i];
262 }
263 }
264 return false;
265 },
266
267 /**
268 * Check if CSS transitions are allowed (options + devicesupport)
269 */
270 doCssTrans : function () {
271 if ( plugin.settings.useCSS && this.supportTransition() ) {
272 return true;
273 }
274 },
275
276 /**
277 * Touch navigation
278 */
279 gesture : function () {
280
281 var $this = this,
282 index,
283 hDistance,
284 vDistance,
285 hDistanceLast,
286 vDistanceLast,
287 hDistancePercent,
288 vSwipe = false,
289 hSwipe = false,
290 hSwipMinDistance = 10,
291 vSwipMinDistance = 50,
292 startCoords = {},
293 endCoords = {},
294 bars = $( '#swipebox-top-bar, #swipebox-bottom-bar' ),
295 slider = $( '#swipebox-slider' );
296
297 bars.addClass( 'visible-bars' );
298 $this.setTimeout();
299
300 $( 'body' ).on( 'touchstart', function( event ) {
301
302 $( this ).addClass( 'touching' );
303 index = $( '#swipebox-slider .slide' ).index( $( '#swipebox-slider .slide.current' ) );
304 endCoords = event.originalEvent.targetTouches[0];
305 startCoords.pageX = event.originalEvent.targetTouches[0].pageX;
306 startCoords.pageY = event.originalEvent.targetTouches[0].pageY;
307
308 $( '#swipebox-slider' ).css( {
309 '-webkit-transform' : 'translate3d(' + currentX +'%, 0, 0)',
310 'transform' : 'translate3d(' + currentX + '%, 0, 0)'
311 } );
312
313 $( '.touching' ).on( 'touchmove',function( event ) {
314 event.preventDefault();
315 event.stopPropagation();
316 endCoords = event.originalEvent.targetTouches[0];
317
318 if ( ! hSwipe ) {
319 vDistanceLast = vDistance;
320 vDistance = endCoords.pageY - startCoords.pageY;
321 if ( Math.abs( vDistance ) >= vSwipMinDistance || vSwipe ) {
322 var opacity = 0.75 - Math.abs(vDistance) / slider.height();
323
324 slider.css( { 'top': vDistance + 'px' } );
325 slider.css( { 'opacity': opacity } );
326
327 vSwipe = true;
328 }
329 }
330
331 hDistanceLast = hDistance;
332 hDistance = endCoords.pageX - startCoords.pageX;
333 hDistancePercent = hDistance * 100 / winWidth;
334
335 if ( ! hSwipe && ! vSwipe && Math.abs( hDistance ) >= hSwipMinDistance ) {
336 $( '#swipebox-slider' ).css( {
337 '-webkit-transition' : '',
338 'transition' : ''
339 } );
340 hSwipe = true;
341 }
342
343 if ( hSwipe ) {
344
345 // swipe left
346 if ( 0 < hDistance ) {
347
348 // first slide
349 if ( 0 === index ) {
350 // console.log( 'first' );
351 $( '#swipebox-overlay' ).addClass( 'leftSpringTouch' );
352 } else {
353 // Follow gesture
354 $( '#swipebox-overlay' ).removeClass( 'leftSpringTouch' ).removeClass( 'rightSpringTouch' );
355 $( '#swipebox-slider' ).css( {
356 '-webkit-transform' : 'translate3d(' + ( currentX + hDistancePercent ) +'%, 0, 0)',
357 'transform' : 'translate3d(' + ( currentX + hDistancePercent ) + '%, 0, 0)'
358 } );
359 }
360
361 // swipe right
362 } else if ( 0 > hDistance ) {
363
364 // last Slide
365 if ( elements.length === index +1 ) {
366 // console.log( 'last' );
367 $( '#swipebox-overlay' ).addClass( 'rightSpringTouch' );
368 } else {
369 $( '#swipebox-overlay' ).removeClass( 'leftSpringTouch' ).removeClass( 'rightSpringTouch' );
370 $( '#swipebox-slider' ).css( {
371 '-webkit-transform' : 'translate3d(' + ( currentX + hDistancePercent ) +'%, 0, 0)',
372 'transform' : 'translate3d(' + ( currentX + hDistancePercent ) + '%, 0, 0)'
373 } );
374 }
375
376 }
377 }
378 } );
379
380 return false;
381
382 } ).on( 'touchend',function( event ) {
383 event.preventDefault();
384 event.stopPropagation();
385
386 $( '#swipebox-slider' ).css( {
387 '-webkit-transition' : '-webkit-transform 0.4s ease',
388 'transition' : 'transform 0.4s ease'
389 } );
390
391 vDistance = endCoords.pageY - startCoords.pageY;
392 hDistance = endCoords.pageX - startCoords.pageX;
393 hDistancePercent = hDistance*100/winWidth;
394
395 // Swipe to bottom to close
396 if ( vSwipe ) {
397 vSwipe = false;
398 if ( Math.abs( vDistance ) >= 2 * vSwipMinDistance && Math.abs( vDistance ) > Math.abs( vDistanceLast ) ) {
399 var vOffset = vDistance > 0 ? slider.height() : - slider.height();
400 slider.animate( { top: vOffset + 'px', 'opacity': 0 },
401 300,
402 function () {
403 $this.closeSlide();
404 } );
405 } else {
406 slider.animate( { top: 0, 'opacity': 1 }, 300 );
407 }
408
409 } else if ( hSwipe ) {
410
411 hSwipe = false;
412
413 // swipeLeft
414 if( hDistance >= hSwipMinDistance && hDistance >= hDistanceLast) {
415
416 $this.getPrev();
417
418 // swipeRight
419 } else if ( hDistance <= -hSwipMinDistance && hDistance <= hDistanceLast) {
420
421 $this.getNext();
422 }
423
424 } else { // Top and bottom bars have been removed on touchable devices
425 // tap
426 if ( ! bars.hasClass( 'visible-bars' ) ) {
427 $this.showBars();
428 $this.setTimeout();
429 } else {
430 $this.clearTimeout();
431 $this.hideBars();
432 }
433 }
434
435 $( '#swipebox-slider' ).css( {
436 '-webkit-transform' : 'translate3d(' + currentX + '%, 0, 0)',
437 'transform' : 'translate3d(' + currentX + '%, 0, 0)'
438 } );
439
440 $( '#swipebox-overlay' ).removeClass( 'leftSpringTouch' ).removeClass( 'rightSpringTouch' );
441 $( '.touching' ).off( 'touchmove' ).removeClass( 'touching' );
442
443 } );
444 },
445
446 /**
447 * Set timer to hide the action bars
448 */
449 setTimeout: function () {
450 if ( plugin.settings.hideBarsDelay > 0 ) {
451 var $this = this;
452 $this.clearTimeout();
453 $this.timeout = window.setTimeout( function() {
454 $this.hideBars();
455 },
456
457 plugin.settings.hideBarsDelay
458 );
459 }
460 },
461
462 /**
463 * Clear timer
464 */
465 clearTimeout: function () {
466 window.clearTimeout( this.timeout );
467 this.timeout = null;
468 },
469
470 /**
471 * Show navigation and title bars
472 */
473 showBars : function () {
474 var bars = $( '#swipebox-top-bar, #swipebox-bottom-bar' );
475 if ( this.doCssTrans() ) {
476 bars.addClass( 'visible-bars' );
477 } else {
478 $( '#swipebox-top-bar' ).animate( { top : 0 }, 500 );
479 $( '#swipebox-bottom-bar' ).animate( { bottom : 0 }, 500 );
480 setTimeout( function() {
481 bars.addClass( 'visible-bars' );
482 }, 1000 );
483 }
484 },
485
486 /**
487 * Hide navigation and title bars
488 */
489 hideBars : function () {
490 var bars = $( '#swipebox-top-bar, #swipebox-bottom-bar' );
491 if ( this.doCssTrans() ) {
492 bars.removeClass( 'visible-bars' );
493 } else {
494 $( '#swipebox-top-bar' ).animate( { top : '-50px' }, 500 );
495 $( '#swipebox-bottom-bar' ).animate( { bottom : '-50px' }, 500 );
496 setTimeout( function() {
497 bars.removeClass( 'visible-bars' );
498 }, 1000 );
499 }
500 },
501
502 /**
503 * Animate navigation and top bars
504 */
505 animBars : function () {
506 var $this = this,
507 bars = $( '#swipebox-top-bar, #swipebox-bottom-bar' );
508
509 bars.addClass( 'visible-bars' );
510 $this.setTimeout();
511
512 $( '#swipebox-slider' ).on( 'click', function() {
513 if ( ! bars.hasClass( 'visible-bars' ) ) {
514 $this.showBars();
515 $this.setTimeout();
516 }
517 } );
518
519 $( '#swipebox-bottom-bar' ).on( 'mouseenter', function() {
520 $this.showBars();
521 bars.addClass( 'visible-bars' );
522 $this.clearTimeout();
523
524 } ).on( 'mouseleave', function() {
525 if ( plugin.settings.hideBarsDelay > 0 ) {
526 bars.removeClass( 'visible-bars' );
527 $this.setTimeout();
528 }
529
530 } );
531 },
532
533 /**
534 * Keyboard navigation
535 */
536 keyboard : function () {
537 var $this = this;
538 $( window ).on( 'keyup', function( event ) {
539 event.preventDefault();
540 event.stopPropagation();
541
542 if ( event.keyCode === 37 ) {
543
544 $this.getPrev();
545
546 } else if ( event.keyCode === 39 ) {
547
548 $this.getNext();
549
550 } else if ( event.keyCode === 27 ) {
551
552 $this.closeSlide();
553 }
554 } );
555 },
556
557 /**
558 * Navigation events : go to next slide, go to prevous slide and close
559 */
560 actions : function () {
561 var $this = this,
562 action = 'touchend click'; // Just detect for both event types to allow for multi-input
563
564 if ( elements.length < 2 ) {
565
566 $( '#swipebox-bottom-bar' ).hide();
567
568 if ( undefined === elements[ 1 ] ) {
569 $( '#swipebox-top-bar' ).hide();
570 }
571
572 } else {
573 $( '#swipebox-prev' ).on( action, function( event ) {
574 event.preventDefault();
575 event.stopPropagation();
576 $this.getPrev();
577 $this.setTimeout();
578 } );
579
580 $( '#swipebox-next' ).on( action, function( event ) {
581 event.preventDefault();
582 event.stopPropagation();
583 $this.getNext();
584 $this.setTimeout();
585 } );
586 }
587
588 $( '#swipebox-close' ).on( action, function( event ) {
589 event.preventDefault();
590 event.stopPropagation();
591 $this.closeSlide();
592 } );
593 },
594
595 /**
596 * Set current slide
597 */
598 setSlide : function ( index, isFirst ) {
599
600 isFirst = isFirst || false;
601
602 var slider = $( '#swipebox-slider' );
603
604 currentX = -index*100;
605
606 if ( this.doCssTrans() ) {
607 slider.css( {
608 '-webkit-transform' : 'translate3d(' + (-index*100)+'%, 0, 0)',
609 'transform' : 'translate3d(' + (-index*100)+'%, 0, 0)'
610 } );
611 } else {
612 slider.animate( { left : ( -index*100 )+'%' } );
613 }
614
615 $( '#swipebox-slider .slide' ).removeClass( 'current' );
616 $( '#swipebox-slider .slide' ).eq( index ).addClass( 'current' );
617 this.setTitle( index );
618
619 if ( isFirst ) {
620 slider.fadeIn();
621 }
622
623 $( '#swipebox-prev, #swipebox-next' ).removeClass( 'disabled' );
624
625 if ( index === 0 ) {
626 $( '#swipebox-prev' ).addClass( 'disabled' );
627 } else if ( index === elements.length - 1 && plugin.settings.loopAtEnd !== true ) {
628 $( '#swipebox-next' ).addClass( 'disabled' );
629 }
630 },
631
632 /**
633 * Open slide
634 */
635 openSlide : function ( index ) {
636 $( 'html' ).addClass( 'swipebox-html' );
637 if ( isTouch ) {
638 $( 'html' ).addClass( 'swipebox-touch' );
639
640 if ( plugin.settings.hideCloseButtonOnMobile ) {
641 $( 'html' ).addClass( 'swipebox-no-close-button' );
642 }
643 } else {
644 $( 'html' ).addClass( 'swipebox-no-touch' );
645 }
646 $( window ).trigger( 'resize' ); // fix scroll bar visibility on desktop
647 this.setSlide( index, true );
648 },
649
650 /**
651 * Set a time out if the media is a video
652 */
653 preloadMedia : function ( index ) {
654 var $this = this,
655 src = null;
656
657 if ( elements[ index ] !== undefined ) {
658 src = elements[ index ].href;
659 }
660
661 if ( ! $this.isVideo( src ) ) {
662 setTimeout( function() {
663 $this.openMedia( index );
664 }, 1000);
665 } else {
666 $this.openMedia( index );
667 }
668 },
669
670 /**
671 * Open
672 */
673 openMedia : function ( index ) {
674 var $this = this,
675 src,
676 slide;
677
678 if ( elements[ index ] !== undefined ) {
679 src = elements[ index ].href;
680 }
681
682 if ( index < 0 || index >= elements.length ) {
683 return false;
684 }
685
686 slide = $( '#swipebox-slider .slide' ).eq( index );
687
688 if ( ! $this.isVideo( src ) ) {
689 slide.addClass( 'slide-loading' );
690 $this.loadMedia( src, function() {
691 slide.removeClass( 'slide-loading' );
692 slide.html( this );
693
694 if ( plugin.settings.afterMedia ) {
695 plugin.settings.afterMedia( index );
696 }
697 } );
698 } else {
699 slide.html( $this.getVideo( src ) );
700
701 if ( plugin.settings.afterMedia ) {
702 plugin.settings.afterMedia( index );
703 }
704 }
705
706 },
707
708 /**
709 * Set link title attribute as caption
710 */
711 setTitle : function ( index ) {
712 var title = null;
713
714 $( '#swipebox-title' ).empty();
715
716 if ( elements[ index ] !== undefined ) {
717 title = elements[ index ].title;
718 }
719
720 if ( title ) {
721 title = title.replace( /[^]/g, function( c ) {
722 return '&#' + c.charCodeAt( 0 ) + ';';
723 } );
724 $( '#swipebox-top-bar' ).show();
725 $( '#swipebox-title' ).append( title );
726 } else {
727 $( '#swipebox-top-bar' ).hide();
728 }
729 },
730
731 /**
732 * Check if the URL is a video
733 */
734 isVideo : function ( src ) {
735
736 if ( src ) {
737 if ( src.match( /(youtube\.com|youtube-nocookie\.com)\/watch\?v=([a-zA-Z0-9\-_]+)/) || src.match( /vimeo\.com\/([0-9]*)/ ) || src.match( /youtu\.be\/([a-zA-Z0-9\-_]+)/ ) ) {
738 return true;
739 }
740
741 if ( src.toLowerCase().indexOf( 'swipeboxvideo=1' ) >= 0 ) {
742
743 return true;
744 }
745 }
746
747 },
748
749 /**
750 * Parse URI querystring and:
751 * - overrides value provided via dictionary
752 * - rebuild it again returning a string
753 */
754 parseUri : function (uri, customData) {
755 var a = document.createElement('a'),
756 qs = {};
757
758 // Decode the URI
759 a.href = decodeURIComponent( uri );
760
761 // QueryString to Object
762 if ( a.search ) {
763 qs = JSON.parse( '{"' + a.search.toLowerCase().replace('?','').replace(/&/g,'","').replace(/=/g,'":"') + '"}' );
764 }
765
766 // Extend with custom data
767 if ( $.isPlainObject( customData ) ) {
768 qs = $.extend( qs, customData, plugin.settings.queryStringData ); // The dev has always the final word
769 }
770
771 // Return querystring as a string
772 return $
773 .map( qs, function (val, key) {
774 if ( val && val > '' ) {
775 return encodeURIComponent( key ) + '=' + encodeURIComponent( val );
776 }
777 })
778 .join('&');
779 },
780
781 /**
782 * Get video iframe code from URL
783 */
784 getVideo : function( url ) {
785 var iframe = '',
786 youtubeUrl = url.match( /((?:www\.)?youtube\.com|(?:www\.)?youtube-nocookie\.com)\/watch\?v=([a-zA-Z0-9\-_]+)/ ),
787 youtubeShortUrl = url.match(/(?:www\.)?youtu\.be\/([a-zA-Z0-9\-_]+)/),
788 vimeoUrl = url.match( /(?:www\.)?vimeo\.com\/([0-9]*)/ ),
789 qs = '';
790
791 if ( youtubeUrl || youtubeShortUrl) {
792 if ( youtubeShortUrl ) {
793 youtubeUrl = youtubeShortUrl;
794 }
795
796 qs = ui.parseUri( url, {
797 'autoplay' : ( plugin.settings.autoplayVideos ? '1' : '0' ),
798 'v' : ''
799 });
800 iframe = '<iframe width="560" height="315" src="https://' + youtubeUrl[1] + '/embed/' + youtubeUrl[2] + '?' + qs + '" frameborder="0" allowfullscreen></iframe>';
801
802 } else if ( vimeoUrl ) {
803 qs = ui.parseUri( url, {
804 'autoplay' : ( plugin.settings.autoplayVideos ? '1' : '0' ),
805 'byline' : '0',
806 'portrait' : '0',
807 'color': plugin.settings.vimeoColor
808 });
809 iframe = '<iframe width="560" height="315" src="//player.vimeo.com/video/' + vimeoUrl[1] + '?' + qs + '" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>';
810
811 } else {
812 iframe = '<iframe width="560" height="315" src="' + url + '" frameborder="0" allowfullscreen></iframe>';
813 }
814
815 return '<div class="swipebox-video-container" style="max-width:' + plugin.settings.videoMaxWidth + 'px"><div class="swipebox-video">' + iframe + '</div></div>';
816 },
817
818 /**
819 * Load image
820 */
821 loadMedia : function ( src, callback ) {
822 // Inline content
823 if ( src.trim().indexOf('#') === 0 ) {
824 callback.call(
825 $('<div>', {
826 'class' : 'swipebox-inline-container'
827 })
828 .append(
829 $(src)
830 .clone()
831 .toggleClass( plugin.settings.toggleClassOnLoad )
832 )
833 );
834 }
835 // Everything else
836 else {
837 if ( ! this.isVideo( src ) ) {
838 var img = $( '<img>' ).on( 'load', function() {
839 callback.call( img );
840 } );
841
842 img.attr( 'src', src );
843 }
844 }
845 },
846
847 /**
848 * Get next slide
849 */
850 getNext : function () {
851 var $this = this,
852 src,
853 index = $( '#swipebox-slider .slide' ).index( $( '#swipebox-slider .slide.current' ) );
854 if ( index + 1 < elements.length ) {
855
856 src = $( '#swipebox-slider .slide' ).eq( index ).contents().find( 'iframe' ).attr( 'src' );
857 $( '#swipebox-slider .slide' ).eq( index ).contents().find( 'iframe' ).attr( 'src', src );
858 index++;
859 $this.setSlide( index );
860 $this.preloadMedia( index+1 );
861 if ( plugin.settings.nextSlide ) {
862 plugin.settings.nextSlide(index);
863 }
864 } else {
865
866 if ( plugin.settings.loopAtEnd === true ) {
867 src = $( '#swipebox-slider .slide' ).eq( index ).contents().find( 'iframe' ).attr( 'src' );
868 $( '#swipebox-slider .slide' ).eq( index ).contents().find( 'iframe' ).attr( 'src', src );
869 index = 0;
870 $this.preloadMedia( index );
871 $this.setSlide( index );
872 $this.preloadMedia( index + 1 );
873 if ( plugin.settings.nextSlide ) {
874 plugin.settings.nextSlide(index);
875 }
876 } else {
877 $( '#swipebox-overlay' ).addClass( 'rightSpring' );
878 setTimeout( function() {
879 $( '#swipebox-overlay' ).removeClass( 'rightSpring' );
880 }, 500 );
881 }
882 }
883 },
884
885 /**
886 * Get previous slide
887 */
888 getPrev : function () {
889 var index = $( '#swipebox-slider .slide' ).index( $( '#swipebox-slider .slide.current' ) ),
890 src;
891 if ( index > 0 ) {
892 src = $( '#swipebox-slider .slide' ).eq( index ).contents().find( 'iframe').attr( 'src' );
893 $( '#swipebox-slider .slide' ).eq( index ).contents().find( 'iframe' ).attr( 'src', src );
894 index--;
895 this.setSlide( index );
896 this.preloadMedia( index-1 );
897 if ( plugin.settings.prevSlide ) {
898 plugin.settings.prevSlide(index);
899 }
900 } else {
901 $( '#swipebox-overlay' ).addClass( 'leftSpring' );
902 setTimeout( function() {
903 $( '#swipebox-overlay' ).removeClass( 'leftSpring' );
904 }, 500 );
905 }
906 },
907 /* jshint unused:false */
908 nextSlide : function ( index ) {
909 // Callback for next slide
910 },
911
912 prevSlide : function ( index ) {
913 // Callback for prev slide
914 },
915
916 /**
917 * Close
918 */
919 closeSlide : function () {
920 $( 'html' ).removeClass( 'swipebox-html' );
921 $( 'html' ).removeClass( 'swipebox-touch' );
922 $( window ).trigger( 'resize' );
923 this.destroy();
924 },
925
926 /**
927 * Destroy the whole thing
928 */
929 destroy : function () {
930 $( window ).off( 'keyup' );
931 $( 'body' ).off( 'touchstart' );
932 $( 'body' ).off( 'touchmove' );
933 $( 'body' ).off( 'touchend' );
934 $( '#swipebox-slider' ).off();
935 $( '#swipebox-overlay' ).remove();
936
937 if ( ! Array.isArray( elem ) ) {
938 elem.removeData( '_swipebox' );
939 }
940
941 if ( this.target ) {
942 this.target.trigger( 'swipebox-destroy' );
943 }
944
945 $.swipebox.isOpen = false;
946
947 if ( plugin.settings.afterClose ) {
948 plugin.settings.afterClose();
949 }
950 }
951 };
952
953 plugin.init();
954 };
955
956 $.fn.swipebox = function( options ) {
957
958 if ( ! $.data( this, '_swipebox' ) ) {
959 var swipebox = new $.swipebox( this, options );
960 this.data( '_swipebox', swipebox );
961 }
962 return this.data( '_swipebox' );
963
964 };
965
966 }( window, document, jQuery ) );
967