assets/js/TosRUs/src/js/jquery.tosrus.js
/*
* jQuery Touch Optimized Sliders "R"Us 1.4.0
*
* Copyright (c) 2013 Fred Heusschen
* www.frebsite.nl
*
* Plugin website:
* tosrus.frebsite.nl
*
* Dual licensed under the MIT and GPL licenses.
* http://en.wikipedia.org/wiki/MIT_License
* http://en.wikipedia.org/wiki/GNU_General_Public_License
*/
// Whishlist
// - drag image around if zoomed
(function( $ )
{
if ( $.fn.TosRUs )
{
return;
}
var $window, $html, $body;
var _viewScale = false,
_isTouch = ( 'ontouchstart' in window ),
_duration = 400;
$.fn.TosRUs = $.fn.tosrus = function( oDefault, oDesktop, oTouch )
{
if ( this.length == 0 )
{
return this;
}
/*
GLOBAL VARS
*/
var $tos = this,
_tos = this[ 0 ];
oDefault = complObject( oDefault, {} );
oDefault = ( _isTouch )
? $.extend( true, {}, oDefault, oTouch )
: $.extend( true, {}, oDefault, oDesktop );
var opts = complementOptions( oDefault, $tos, _tos ),
_fixed = ( opts.wrapper.target == 'window' ),
_index = 0,
_total = 0,
_scrollPosition = 0;
$window = $(window);
$html = $('html');
$body = $('body');
if ( !_viewScale && _isTouch && typeof FlameViewportScale != 'undefined' )
{
_viewScale = new FlameViewportScale();
}
/*
MARKUP
*/
var $wrpr = $('<div class="' + cls( 'wrapper' ) + '" />'),
$sldr = $('<div class="' + cls( 'slider' ) + '" />').appendTo( $wrpr ),
$clse = null,
$capt = null,
$prev = null,
$next = null;
$wrpr
.css( opts.wrapper.css )
.addClass( cls( _fixed ? 'fixed' : 'inline' ) )
.addClass( cls( _isTouch ? 'touch' : 'desktop' ) )
.addClass( cls( opts.slides.scale ) );
if ( opts.caption )
{
$capt = $('<div class="' + cls( 'caption' ) + '" />').appendTo( $wrpr );
}
if ( opts.prev.button )
{
$prev = ( opts.prev.button instanceof $ )
? opts.prev.button
: $('<a class="' + cls( 'prev' ) + '" href="#" />').appendTo( $wrpr );
}
if ( opts.next.button )
{
$next = ( opts.next.button instanceof $ )
? opts.next.button
: $('<a class="' + cls( 'next' ) + '" href="#" />').appendTo( $wrpr );
}
if ( opts.close.button )
{
$clse = ( opts.close.button instanceof $ )
? opts.close.button
: $('<a class="' + cls( 'close' ) + '" href="#" />').appendTo( $wrpr );
}
/*
ADD SLIDES
*/
var $anchors = getValidAnchors( $tos, opts ),
$slides = _initSlides( $tos, $anchors, $wrpr, $sldr, opts );
_total = $slides.length;
_index = setIndex( _index, $wrpr );
/*
EVENTS
*/
$wrpr
.bind(
evt( '' ),
function( e )
{
e.stopPropagation();
}
)
// Open event, opens the gallery and slides to the designated slide
.bind(
evt( 'open' ),
function( e, index, direct )
{
if ( !_opened )
{
if ( _fixed )
{
_scrollPosition = $window.scrollTop();
}
$wrpr
.show()
.css( 'opacity', 0 )
.addClass( cls( 'hover' ) );
animate(
$wrpr,
{ 'opacity': 1 },
direct
);
// scale buttons
scaleButtons( [ $prev, $next, $clse ], $capt );
// callback event
$wrpr.trigger( evt( 'opening' ), [ index, direct ] );
}
loadContents( $sldr, _index, opts );
direct = ( direct || !_opened );
_opened = setOpened( true, $wrpr );
if ( $.isNumeric( index ) )
{
$wrpr.trigger( evt( 'slideTo' ), [ index, direct ] );
}
}
)
// Close event, closes the gallery
.bind(
evt( 'close' ),
function( e, direct )
{
if ( _opened )
{
$wrpr.removeClass( cls( 'hover' ) );
stopVideo( $wrpr.find( '.' + cls( 'video' ) ), 'stop' );
if ( typeof direct == 'undefined' )
{
direct = _duration / 2;
}
animate(
$('div.' + cls ( 'wrapper' ) ), //$wrpr, // PATCH
{ 'opacity': 0 },
direct,
function()
{
$('div.' + cls ( 'wrapper' ) ).hide(); //$wrpr.hide(); // PATCH
}
);
// callback event
$wrpr.trigger( evt( 'closing' ), [ direct ] );
}
_opened = setOpened( false, $wrpr );
}
)
// Prev + Prev events, slides to the previous / next set of slides
.bind(
evt( 'prev' ) + ' ' + evt( 'next' ),
function( e, slides, duration, easing )
{
if ( !$.isNumeric( slides ) )
{
slides = opts[ e.type ].slides;
}
$wrpr.trigger( evt( 'slideTo' ), [ ( e.type == 'prev' ) ? _index - slides : _index + slides, duration, easing ] );
}
)
// SlideTo event, slides to the designated slide
.bind(
evt( 'slideTo' ),
function( e, slide, duration, easing )
{
if ( !_opened )
{
return false;
}
if ( !$.isNumeric( slide ) )
{
return false;
}
var doSlide = true;
// Less then first
if ( slide < 0 )
{
slide = 0;
if ( _index == 0 )
{
doSlide = false;
}
}
// More then last
else if ( slide + opts.slides.visible > _total )
{
slide = _total - opts.slides.visible;
if ( _index + opts.slides.visible >= _total )
{
doSlide = false;
}
}
var $curSlide = $sldr.children().eq( _index );
_index = setIndex( slide, $wrpr );
loadContents( $sldr, _index, opts );
setButtons( $prev, $next, _index, _total, opts );
if ( doSlide )
{
// Slide
var left = 0 - ( _index * opts.slides.width ) + opts.slides.offset;
if ( opts.slidesWidthPercentage )
{
left += '%';
}
animate(
$sldr,
{ 'left': left },
duration,
null,
easing
);
// Get caption
if ( opts.caption )
{
var caption = $sldr.children().eq( _index ).data( dta( 'caption' ) );
$capt
.text( caption )
[ ( caption.length > 0 ) ? 'show' : 'hide' ]();
}
stopVideo( $curSlide.filter( '.' + cls( 'video' ) ), 'pause' );
// callback event
$wrpr.trigger( evt( 'sliding' ), [ _index, duration ] );
}
}
)
// Toggle UI
.bind(
evt( 'click' ),
function( e )
{
$wrpr.toggleClass( cls( 'hover' ) );
}
);
/*
BUTTONS
*/
setButtons( $prev, $next, _index, _total, opts );
_initButtons(
$wrpr,
{
'prev' : $prev,
'next' : $next,
'close' : $clse
}
);
$window.bind(
evt( 'orientationchange' ),
function()
{
if ( _opened )
{
scaleButtons( [ $prev, $next, $clse ], $capt, 250 );
}
}
);
/*
KEYPRESSES
*/
_initKeys( $wrpr, opts );
/*
DRAGGING
*/
if ( opts.touch.drag )
{
$.fn.TosRUs.dragSlide( $wrpr, opts.slides.visible, _total );
}
/*
PREVENT SCROLLING
*/
if ( _fixed )
{
$window.bind(
evt( 'scroll' ),
function( e )
{
if ( _opened )
{
window.scrollTo( 0, _scrollPosition );
e.preventDefault();
e.stopImmediatePropagation();
}
}
);
}
/*
START
*/
var _opened = setOpened( true, $wrpr );
if ( _fixed )
{
$wrpr
.appendTo( $body )
.trigger( evt( 'close' ), [ true ] );
}
else
{
$wrpr.appendTo( opts.wrapper.target );
if ( opts.show )
{
_opened = setOpened( false, $wrpr );
$wrpr.trigger( evt( 'open' ), [ 0, true ] );
}
else
{
$wrpr.trigger( evt( 'close' ), [ true ] );
}
}
return $wrpr;
};
/*
Public variables
*/
$.fn.TosRUs.isTouch = _isTouch;
/*
Public methods
*/
$.fn.TosRUs.dragSlide = function( $wrpr, _visible, _total )
{
var $sldr = $wrpr.find( '> .' + cls( 'slider' ) );
var _distance = 0,
_direction = false,
_swiping = false;
$wrpr
.hammer()
.on(
evt( 'dragleft' ) + ' ' + evt( 'dragright' ),
function( e )
{
e.gesture.preventDefault();
e.stopPropagation();
_distance = e.gesture.deltaX;
_direction = e.gesture.direction;
_swiping = false;
if ( ( _direction == 'left' && $wrpr.data( dta( 'index' ) ) + _visible >= _total ) ||
( _direction == 'right' && $wrpr.data( dta( 'index' ) ) == 0 ) )
{
_distance /= 2.5;
}
$sldr.css( 'marginLeft', Math.round( _distance ) );
}
)
.on(
evt( 'swipeleft' ) + ' ' + evt( 'swiperight' ),
function( e )
{
e.gesture.preventDefault();
e.stopPropagation();
_swiping = true;
}
)
.on(
evt( 'dragend' ),
function( e )
{
e.gesture.preventDefault();
e.stopPropagation();
var duration = _duration / 2;
if ( _direction == 'left' || _direction == 'right' )
{
var easing = null;
if ( _swiping )
{
var slides = _visible;
easing = 'swipeOutTos';
}
else
{
var slideWidth = $sldr.children().first().width(),
slides = Math.floor( ( Math.abs( _distance ) + ( slideWidth / 2 ) ) / slideWidth );
}
if ( slides > 0 )
{
$wrpr.trigger( evt( _direction == 'left' ? 'next' : 'prev' ), [ slides, duration, easing ] );
}
}
animate(
$sldr,
{ 'marginLeft': 0 },
duration,
null,
easing
);
_direction = false;
}
)
.on(
evt( 'pinch' ),
function( e )
{
e.gesture.preventDefault();
e.stopPropagation();
}
);
}
$.fn.TosRUs.pinchZoom = function( $img )
{
var _endScale = 1,
_curScale = 1,
_oldScale = 1,
_newScale = 1;
$img
.hammer()
.on(
evt( 'pinch' ),
function(e)
{
e.gesture.preventDefault();
e.stopPropagation();
_endScale = ( e.gesture.scale - _curScale ) * _oldScale;
_curScale = e.gesture.scale;
_newScale = restrictMinMax( _newScale + _endScale, 0.5, 4 );
$img.css({
'transform': 'scale( ' + _newScale + ' )'
});
}
)
.on(
evt( 'doubletap' ),
function( e )
{
e.gesture.preventDefault();
e.stopPropagation();
_endScale = 0;
_curScale = 1;
_newScale = ( _oldScale > 1 ) ? 1 : 3;
_oldScale = animateScale(
$img,
_oldScale,
_newScale
);
}
)
.on(
evt( 'release' ),
function( e )
{
e.gesture.preventDefault();
e.stopPropagation();
_endScale = 0;
_curScale = 1;
_oldScale = _newScale;
// After scaled < 1, animate to 1
if ( _oldScale < 1 )
{
_newScale = 1;
_oldScale = animateScale(
$img,
_oldScale,
_newScale
);
}
}
);
}
/*
SWIPE EASING
*/
jQuery.extend( jQuery.easing,
{
swipeOutTos: function (x, t, b, c, d) {
return c * Math.sin( t / d * ( Math.PI / 2 ) ) + b;
}
});
/*
INIT FUNCTIONS
*/
function _initSlides( $tos, $anchors, $wrpr, $sldr, opts )
{
if ( opts.slides.collect )
{
_initSlidesFromAnchors( $tos, $anchors, $wrpr, $sldr, opts );
}
else
{
_initSlidesFromContent( $tos, $anchors, $wrpr, $sldr, opts );
}
var $slides = $sldr.children();
// CSS
if ( opts.slides.css )
{
$slides.css( opts.slides.css );
}
var width = opts.slides.width;
if ( opts.slidesWidthPercentage )
{
width += '%';
}
$slides.css( 'width', width );
return $slides;
}
function _initSlidesFromAnchors( $tos, $anchors, $wrpr, $sldr, opts )
{
getZoomAnchors( $anchors, opts ).addClass( cls( 'zoom' ) );
$anchors
.css( opts.anchors.css )
.each(
function( index )
{
var $anchor = $(this);
// Create the slide
var $slide = $('<div class="' + cls( 'slide' ) + ' ' + cls( 'loading' ) + '" />')
.data( dta( 'anchor' ), $anchor )
.data( dta( 'content' ), $anchor.attr( 'href' ) )
.appendTo( $sldr );
// Clicking an achor opens the slide
$anchor
.data( dta( 'slide' ), $slide )
.bind(
evt( opts.anchors.event ),
function( e )
{
e.preventDefault();
$wrpr.trigger( evt( 'open' ), [ index ] );
}
);
// Get caption
if ( opts.caption )
{
$slide.data( dta( 'caption' ), '' );
for ( var c = 0, l = opts.caption.length; c < l; c++ )
{
var caption = $anchor.attr( opts.caption[ c ] );
if ( caption && caption.length )
{
$slide.data( dta( 'caption' ), caption );
break;
}
}
}
}
);
}
function _initSlidesFromContent( $tos, $anchors, $wrpr, $sldr, opts )
{
$tos.children().each(
function( index )
{
var $slide = $(this);
$('<div class="' + cls( 'slide' ) + '" />')
.append( $slide )
.appendTo( $sldr );
$slide = $slide.parent();
$slide.data( dta( 'caption' ), '' );
var $content = $slide.children(),
contenttype = 'html',
videotype = 'youtube';
// IMAGE
if ( $content.is( 'img' ) )
{
contenttype = 'image';
}
// (video)
else if ( $content.is( 'iframe' ) && $content.attr( 'src' ) )
{
var src = $content.attr( 'src' ).toLowerCase();
// YOUTUBE
if ( src.indexOf( 'youtube.com/embed/' ) > -1 )
{
contenttype = 'video';
}
// VIMEO
else if ( src.indexOf( 'vimeo.com/video/' ) > -1 )
{
contenttype = 'video';
videotype = 'vimeo';
}
}
$slide.data( dta( 'contenttype' ), contenttype );
switch ( contenttype )
{
// IMAGE
case 'image':
if ( opts.touch.zoom )
{
$.fn.TosRUs.pinchZoom( $content );
}
break;
// HTML NODE
case 'html':
$content.wrap( '<div class="' + cls( 'content' ) + '" />' );
break;
// VIDEO
case 'video':
$slide.data( dta( 'videotype' ), videotype );
_initResizeVideo(
$slide,
opts.video.ratio,
opts.video.maxWidth,
opts.video.maxHeight
);
break;
}
}
);
}
function _initResizeVideo( $slide, ratio, maxWidth, maxHeight )
{
var $video = $slide.children();
$slide
.addClass( cls( 'video' ) )
.bind(
evt( 'resizeVideo' ),
function()
{
$video.removeAttr( 'style' );
var _w = $slide.width(),
_h = $slide.height();
if ( maxWidth && _w > maxWidth )
{
_w = maxWidth;
}
if ( maxHeight && _h > maxHeight )
{
_h = maxHeight;
}
if ( _w / _h < ratio )
{
_h = _w / ratio;
}
else
{
_w = _h * ratio;
}
$video.width( _w );
$video.height( _h );
}
);
$window.bind(
evt( 'resize' ),
function( e )
{
$slide.trigger( evt( 'resizeVideo' ) );
}
);
}
function _initButtons( $wrpr, btns )
{
$.each(
btns,
function( index, value )
{
if ( value )
{
value.bind(
evt( 'click' ),
function( e )
{
e.stopPropagation();
e.preventDefault();
$wrpr.trigger( evt( index ) );
}
);
}
}
);
}
function _initKeys( $wrpr, opts )
{
if ( opts.prev.key || opts.next.key || opts.close.key )
{
$(document).bind(
evt( 'keyup' ),
function( e )
{
var k = e.keyCode;
if ( k == 27 || k == 37 || k == 39 )
{
if ( $wrpr.data( dta( 'opened' ) ) )
{
if ( k == 27 && opts.close.key )
{
e.preventDefault();
$wrpr.trigger( evt( 'close' ) );
}
else if (
( k == 37 && opts.prev.key ) ||
( k == 39 && opts.next.key )
) {
e.preventDefault();
$wrpr.trigger( evt( k == 37 ? 'prev' : 'next' ) );
}
}
}
}
);
}
}
/*
GENERAL FUNCTIONS
*/
function animate( $element, properties, direct, callback, easing )
{
var duration = _duration;
if ( $.isNumeric( direct ) )
{
duration = direct;
direct = false;
}
if ( direct )
{
$element.css( properties );
}
else
{
setTimeout(
function()
{
$element.animate(
properties,
{
duration: duration,
complete: callback,
easing: easing,
queue: false
}
);
}, 1
);
}
}
function animateScale( $element, startScale, endScale )
{
$('<div />').css('width', startScale).animate({
'width': endScale
}, {
duration: _duration / 2,
step: function( now )
{
$element.css({
'transform': 'scale(' + now + ')'
});
}
});
return endScale;
}
function restrictMinMax( val, min, max )
{
if ( typeof min == 'number' && val < min )
{
val = min;
}
if ( typeof max == 'number' && val > max )
{
val = max;
}
return val;
}
function setIndex( _index, $wrpr )
{
$wrpr.data( dta( 'index' ), _index );
return _index;
}
function setOpened( _opened, $wrpr )
{
$wrpr.data( dta( 'opened' ), _opened );
return _opened;
}
function setButtons( $prev, $next, _index, _total, opts )
{
if ( $prev )
{
$prev[ ( ( _index < 1 ) ? 'add' : 'remove' ) + 'Class' ]( cls( 'disabled' ) );
}
if ( $next )
{
$next[ ( ( _index >= _total - opts.slides.visible ) ? 'add' : 'remove' ) + 'Class' ]( cls( 'disabled' ) );
}
}
function scaleButtons( $btns, $capt, timeout )
{
if ( _viewScale )
{
var scale = _viewScale.getScale();
if ( typeof scale != 'undefined' )
{
scale = 1 / scale;
var $buttons = $();
for ( var a = 0, l = $btns.length; a < l; a++ )
{
if ( $btns[ a ] )
{
$buttons = $buttons.add( $btns[ a ] );
}
}
setTimeout(
function()
{
if ( $capt )
{
$capt.css({
'text-size-adjust': Math.ceil( 100 * restrictMinMax( scale, 1, 3 ) ) + '%'
});
}
$buttons.css({
'transform': 'scale(' + restrictMinMax( scale, 1, 2 ) + ')'
});
}, timeout || 1
);
}
}
}
function loadContents( $sldr, _index, opts )
{
// Preload current
loadContent( $sldr, _index, _index + opts.slides.visible, opts );
// Preload prev + next
setTimeout(
function()
{
loadContent( $sldr, _index - opts.slides.visible, _index, opts ); // prev
loadContent( $sldr, _index + opts.slides.visible, _index + ( opts.slides.visible * 2 ), opts ); // next
}, 500
);
}
function loadContent( $sldr, start, end, opts )
{
$sldr.children().slice( start, end ).each(
function()
{
var $slide = $(this);
if ( $slide.children().length == 0 )
{
var content = $slide.data( dta( 'content' ) ),
orgContent = content,
contenttype = false,
videotype = 'youtube';
// IMAGES
if ( $.inArray( content.toLowerCase().split( '.' ).pop().split( '?' )[ 0 ], [ 'jpg', 'jpe', 'jpeg', 'gif', 'png' ] ) > -1 )
{
contenttype = 'image';
}
// HTML NODE
else if ( content.indexOf( '#' ) == 0 )
{
content = $(content);
contenttype = 'html';
}
// YOUTUBE (video)
else if ( content.toLowerCase().indexOf( 'youtube.com/watch' ) > -1 )
{
content = content.split( '?v=' )[ 1 ].split( '&' )[ 0 ];
if ( opts.video.imageLink )
{
content = 'http://img.youtube.com/vi/' + content + '/0.jpg';
contenttype = 'videolink';
}
else
{
content = 'http://www.youtube.com/embed/' + content;
contenttype = 'video';
}
}
// VIMEO (video)
else if ( content.toLowerCase().indexOf( 'vimeo.com/' ) > -1 )
{
content = 'http://player.vimeo.com/video/' + content.split( 'vimeo.com/' )[ 1 ].split( '?' )[ 0 ] + '?api=1';
contenttype = 'video';
videotype = 'vimeo';
}
$slide.data( dta( 'contenttype' ), contenttype );
switch ( contenttype )
{
// IMAGE
case 'image':
case 'videolink':
$('<img border="0" />')
.bind(
evt( 'load' ),
function( e )
{
e.stopPropagation();
$slide.removeClass( cls( 'loading' ) );
if ( contenttype == 'videolink' )
{
$('<a href="' + orgContent + '" class="' + cls( 'play' ) + '" />')
.appendTo( $slide );
}
else
{
if ( opts.touch.zoom )
{
$.fn.TosRUs.pinchZoom( $(this) );
}
}
}
)
.appendTo( $slide )
.attr( 'src', content );
break;
// HTML NODE
case 'html':
$slide.removeClass( cls( 'loading' ) );
$('<div class="' + cls( 'content' ) + '" />')
.append( content )
.appendTo( $slide );
break;
// VIDEO
case 'video':
$slide.data( dta( 'videotype' ), videotype );
var $anchor = $slide.data( dta( 'anchor' ) );
$('<iframe src="' + content + '" frameborder="0" allowfullscreen />')
.appendTo( $slide );
_initResizeVideo(
$slide,
$anchor.data( dta( 'ratio' ) ) || opts.video.ratio,
$anchor.data( dta( 'maxWidth' ) ) || opts.video.maxWidth,
$anchor.data( dta( 'maxHeight' ) ) || opts.video.maxHeight
);
setTimeout(
function()
{
$slide.removeClass( cls( 'loading' ) );
}, 2500
);
break;
}
$sldr.parent().trigger( 'loading', [ $slide.data( dta( 'anchor' ) ), $slide ] );
}
if ( $slide.data( dta( 'contenttype' ) ) == 'video' )
{
$slide.trigger( evt( 'resizeVideo' ) );
}
}
);
}
function stopVideo( $slides, fn )
{
$slides.each(
function()
{
var $slide = $(this),
iframe = $slide.find( 'iframe' )[ 0 ];
switch ( $slide.data( dta( 'videotype' ) ) )
{
case 'youtube':
iframe.contentWindow.postMessage( '{ "event": "command", "func": "' + fn + 'Video" }', '*' );
break;
case 'vimeo':
if ( fn == 'stop' )
{
fn = 'unload';
}
iframe.contentWindow.postMessage( '{ "method": "' + fn + '" }', '*' );
break;
}
}
);
}
function getValidAnchors( $org, opts )
{
var $anchors = $();
if ( opts.slides.collect )
{
$anchors = $anchors.add( $org.filter( 'a[href*=".gif"]' ) ); // gif
$anchors = $anchors.add( $org.filter( 'a[href*=".png"]' ) ); // png
$anchors = $anchors.add( $org.filter( 'a[href*=".jpg"]' ) ); // jpg
$anchors = $anchors.add( $org.filter( 'a[href*=".jpe"]' ) );
$anchors = $anchors.add( $org.filter( 'a[href*=".jpeg"]' ) );
$anchors = $anchors.add( $org.filter( 'a[href^="#"][href!="#"]' ) ); // hidden content
$anchors = $anchors.add( $org.filter( 'a[href*="youtube.com/watch?v="]' ) ); // youtube
$anchors = $anchors.add( $org.filter( 'a[href*="vimeo.com/"]' ) ); // vimeo
}
return $anchors;
}
function getZoomAnchors( $org, opts )
{
var $anchors = $();
if ( opts.anchors.zoomIcon )
{
$org.each(
function()
{
var $t = $(this),
$i = $t.children();
if ( $i.length == 1 && $i.is( 'img' ) && $i.width() > 99 && $i.height() > 99 )
{
$anchors = $anchors.add( $t );
}
}
);
}
return $anchors;
}
/*
$.fn.TosRUs.defaults = {
show: false,
draggable: {
drag: false,
zoom: false
},
buttons: true,
keys: false,
caption: ["rel", "title"],
wrapper: {
target: 'window',
css: {
}
},
slides: {
visible: 1,
collect: true,
css: {
}
},
anchors: {
event: "click",
zoomIcon: true,
css: {
}
},
prev: {
slides: 1,
button: true,
key: false
},
next: {
slides: 1,
button: true,
key: false
},
close: {
button: true,
key: false
},
video: {
ratio: 16 / 9,
maxWidth: false,
maxHeight: false
}
};
*/
function complementOptions( o, $tos, _tos )
{
// Complement objects
// wrapper
if ( $.isFunction( o.wrapper ) )
{
o.wrapper = {
target: o.wrapper.call( _tos )
};
}
else if ( typeof o.wrapper == 'string' )
{
o.wrapper = {
target: $(o.wrapper)
}
}
o.wrapper = complObject( o.wrapper, {} );
if ( typeof o.touch == 'boolean' )
{
o.touch = {
drag: o.touch,
zoom: o.touch
};
}
o.touch = complObject( o.touch, {} );
// slides
if ( $.isNumeric( o.slides ) )
{
o.slides = {
visible: o.slides
};
}
else if ( typeof o.slides == 'string' )
{
o.slides = {
scale: o.slides
};
}
o.slides = complObject( o.slides, {} );
// anchors
if ( typeof o.anchors == 'boolean' )
{
o.anchors = {
zoomIcon: o.anchors
};
}
else if ( typeof o.anchors == 'string' )
{
o.anchors = {
event: o.anchors
}
}
o.anchors = complObject( o.anchors, {} );
// video
if ( $.isNumeric( o.video ) )
{
o.video = {
ratio: o.video
};
}
o.video = complObject( o.video, {} );
// Fill options
// wrapper
o.wrapper.css = complObject( o.wrapper.css, {} );
if ( $.isFunction( o.wrapper.target ) )
{
o.wrapper.target = o.wrapper.target.call( _tos );
}
if ( typeof o.wrapper.target == 'string' )
{
o.wrapper.target = $(o.wrapper.target);
}
if ( !(o.wrapper.target instanceof $) || o.wrapper.target.length == 0 )
{
o.wrapper.target = ( o.slides.collect === false ) ? $tos : 'window';
}
// show, touch, buttons, keys
o.show = complBoolean( o.show, !( o.wrapper.target == 'window' ) );
o.touch = ( $.fn.hammer )
? {
drag: complBoolean( o.touch.drag, _isTouch ),
zoom: complBoolean( o.touch.zoom, _isTouch && o.wrapper.target == 'window' )
} : {
drag: false,
zoom: false
};
o.buttons = complBoolean( o.buttons, !o.touch.drag );
o.keys = complBoolean( o.keys, ( !o.touch.drag && !o.buttons ) );
// caption
if ( typeof o.caption == 'string' )
{
o.caption = [ o.caption ];
}
if ( o.caption !== false && !$.isArray( o.caption ) )
{
o.caption = ( o.wrapper.target == 'window' || o.caption === true ) ? [ 'rel', 'title' ] : false;
}
// slides
if ( $.isNumeric( o.slides.width ) )
{
o.slidesWidthPercentage = false;
o.slides.visible = complNumber( o.slides.visible, 1 );
}
else
{
var percWidth = ( isPercentage( o.slides.width ) ) ? getPercentage( o.slides.width ) : false;
o.slidesWidthPercentage = true;
o.slides.visible = complNumber( o.slides.visible, ( percWidth ) ? Math.floor( 100 / percWidth ) : 1 );
o.slides.width = ( percWidth ) ? percWidth : Math.ceil( 100 * 100 / o.slides.visible ) / 100;
}
o.slides.offset = ( isPercentage( o.slides.offset ) ) ? getPercentage( o.slides.offset ) : complNumber( o.slides.offset, 0 );
o.slides.collect = complBoolean( o.slides.collect, o.wrapper.target == 'window' );
o.slides.scale = complString( o.slides.scale, 'fit' );
o.slides.css = complObject( o.slides.css, {} );
// anchors
o.anchors.zoomIcon = complBoolean( o.anchors.zoomIcon, ( !_isTouch && o.wrapper.target == 'window' ) );
o.anchors.event = complString( o.anchors.event, 'click' );
o.anchors.css = complObject( o.anchors.css, {} );
// prev, next, close
o = complButton( 'prev', o );
o = complButton( 'next', o );
o = complButton( 'close', o );
// video
o.video.ratio = complNumber( o.video.ratio, 16 / 9 );
o.video.maxWidth = complNumber( o.video.maxWidth, false );
o.video.maxHeight = complNumber( o.video.maxHeight, false );
o.video.imageLink = complBoolean( o.video.imageLink, _isTouch );
return o;
}
function complButton( btn, o )
{
var navi = ( btn != 'close' );
if ( navi && $.isNumeric( o[ btn ] ) )
{
o[ btn ] = {
slides: o[ btn ]
};
}
switch( typeof o[ btn ] )
{
case 'boolean':
case 'string':
o[ btn ] = {
button: o[ btn ]
};
break;
}
if ( !$.isPlainObject( o[ btn ] ) )
{
o[ btn ] = {};
}
if ( navi && ( !$.isNumeric( o[ btn ].slides ) || o[ btn ].slides < 1 ) )
{
o[ btn ].slides = o.slides.visible;
}
if ( typeof o[ btn ].button == 'string' )
{
o[ btn ].button = $(o[ btn ].button);
}
if ( !( o[ btn ].button instanceof $ ) )
{
var defaultBtn = ( navi )
? o.buttons
: ( o.wrapper.target == 'window' );
o[ btn ].button = complBoolean( o[ btn ].button, defaultBtn );
}
var defaultKey = ( navi )
? o.keys
: ( o.wrapper.target == 'window' && ( o.keys || !o[ btn ].button ) )
o[ btn ].key = complBoolean( o[ btn ].key, defaultKey );
return o;
}
function complObject( option, defaultVal )
{
if ( !$.isPlainObject( option ) )
{
option = defaultVal;
}
return option;
}
function complBoolean( option, defaultVal )
{
if ( typeof option != 'boolean' )
{
option = defaultVal;
}
return option;
}
function complNumber( option, defaultVal )
{
if ( !$.isNumeric( option ) )
{
option = defaultVal;
}
return option;
}
function complString( option, defaultVal )
{
if ( typeof option != 'string' )
{
option = defaultVal;
}
return option;
}
function isPercentage( value )
{
return ( typeof value == 'string' && value.slice( -1 ) == '%' );
{
value = parseInt( value.slice( 0, -1 ) );
}
return !isNaN( value );
}
function getPercentage( value )
{
return parseInt( value.slice( 0, -1 ) );
}
var cls = function( cls )
{
return 'tos-' + cls;
};
var dta = function( dta )
{
return 'tos-' + dta;
};
var evt = function( evt )
{
return evt + '.tos';
};
})( jQuery );