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