/* jshint browser: true, jquery: true, devel: true */ /* global window, jQuery */ (function($, window, undefined) { 'use strict'; function throttle(func, delay) { var timer = null; return function() { var context = this, args = arguments; if ( timer === null ) { timer = setTimeout(function() { func.apply(context, args); timer = null; }, delay); } }; } // Check for browser CSS support and cache the result for subsequent calls. var checkStyleSupport = (function() { var support = {}; return function(prop) { if ( support[prop] !== undefined ) { return support[prop]; } var div = document.createElement('div'), style = div.style, ucProp = prop.charAt(0).toUpperCase() + prop.slice(1), prefixes = ["webkit", "moz", "ms", "o"], props = (prop + ' ' + (prefixes).join(ucProp + ' ') + ucProp).split(' '); for (var i in props) { if ( props[i] in style ) { return support[prop] = props[i]; } } return support[prop] = false; }; }()); var svgNS = 'http://www.w3.org/2000/svg', svgSupport = (function() { var support; return function() { if ( support !== undefined ) { return support; } var div = document.createElement('div'); div.innerHTML = ''; support = ( div.firstChild && div.firstChild.namespaceURI === svgNS ); return support; }; }()); var $window = $(window), transformSupport = checkStyleSupport('transform'), defaults = { itemContainer: 'ul', // [string|object] // Selector for the container of the flippin' items. itemSelector: 'li', // [string|object] // Selector for children of `itemContainer` to flip start: 'center', // ['center'|number] // Zero based index of the starting item, or use 'center' to start in the middle fadeIn: 400, // [milliseconds] // Speed of the fade in animation after items have been setup loop: false, // [true|false|number] // Loop around when the start or end is reached // If number, this is the number of items that will be shown when the beginning or end is reached autoplay: false, // [false|milliseconds] // If a positive number, Flipster will automatically advance to next item after that number of milliseconds pauseOnHover: true, // [true|false] // If true, autoplay advancement will pause when Flipster is hovered style: 'coverflow', // [coverflow|carousel|flat|...] // Adds a class (e.g. flipster--coverflow) to the flipster element to switch between display styles // Create your own theme in CSS and use this setting to have Flipster add the custom class spacing: -0.6, // [number] // Space between items relative to each item's width. 0 for no spacing, negative values to overlap click: true, // [true|false] // Clicking an item switches to that item keyboard: true, // [true|false] // Enable left/right arrow navigation scrollwheel: true, // [true|false] // Enable mousewheel/trackpad navigation; up/left = previous, down/right = next touch: true, // [true|false] // Enable swipe navigation for touch devices nav: false, // [true|false|'before'|'after'] // If not false, Flipster will build an unordered list of the items // Values true or 'before' will insert the navigation before the items, 'after' will append the navigation after the items buttons: false, // [true|false|'custom'] // If true, Flipster will insert Previous / Next buttons with SVG arrows // If 'custom', Flipster will not insert the arrows and will instead use the values of `buttonPrev` and `buttonNext` buttonPrev: 'Previous', // [text|html] // Changes the text for the Previous button buttonNext: 'Next', // [text|html] // Changes the text for the Next button onItemSwitch: false // [function] // Callback function when items are switched // Arguments received: [currentItem, previousItem] }, classes = { main: 'flipster', active: 'flipster--active', container: 'flipster__container', nav: 'flipster__nav', navChild: 'flipster__nav__child', navItem: 'flipster__nav__item', navLink: 'flipster__nav__link', navCurrent: 'flipster__nav__item--current', navCategory: 'flipster__nav__item--category', navCategoryLink: 'flipster__nav__link--category', button: 'flipster__button', buttonPrev: 'flipster__button--prev', buttonNext: 'flipster__button--next', item: 'flipster__item', itemCurrent: 'flipster__item--current', itemPast: 'flipster__item--past', itemFuture: 'flipster__item--future', itemContent: 'flipster__item__content' }, classRemover = new RegExp('\\b(' + classes.itemCurrent + '|' + classes.itemPast + '|' + classes.itemFuture + ')(.*?)(\\s|$)', 'g'), whiteSpaceRemover = new RegExp('\\s\\s+', 'g'); $.fn.flipster = function(options) { var isMethodCall = (typeof options === 'string' ? true : false); if ( isMethodCall ) { var args = Array.prototype.slice.call(arguments, 1); return this.each(function() { var methods = $(this).data('methods'); if ( methods[options] ) { return methods[options].apply(this, args); } else { return this; } }); } var settings = $.extend({}, defaults, options); return this.each(function() { var self = $(this), methods, _container, _containerWidth, _items, _itemOffsets = [], _currentItem, _currentIndex = 0, _nav, _navItems, _navLinks, _playing = false, _startDrag = false, _isItemClicked = false; function buildButtonContent(dir) { var text = ( dir === 'next' ? settings.buttonNext : settings.buttonPrev ); if ( settings.buttons === 'custom' || !svgSupport ) { return text; } return '' + text + ''; } function buildButton(dir) { dir = dir || 'next'; return $('