https://rectorarosadeves.cl/wp-content/themes/salient/js/build/third-party/flickity.min.js?ver=2.2.2
1/*! 2 * Flickity PACKAGED v2.1.2 3 * Touch, responsive, flickable carousels 4 * 5 * Licensed GPLv3 for open source use 6 * or Flickity Commercial License for commercial use 7 * 8 * https://flickity.metafizzy.co 9 * Copyright 2015-2018 Metafizzy
vendor: 15,950 bytes, lines 9-660
9 10 */ 11 12/** 13 * Bridget makes jQuery widgets 14 * v2.0.1 15 * MIT license 16 */ 17 18/* jshint browser: true, strict: true, undef: true, unused: true */ 19 20( function( window, factory ) { 21 // universal module definition 22 /*jshint strict: false */ /* globals define, module, require */ 23 if ( typeof define == 'function' && define.amd ) { 24 // AMD 25 define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) { 26 return factory( window, jQuery ); 27 }); 28 } else if ( typeof module == 'object' && module.exports ) { 29 // CommonJS 30 module.exports = factory( 31 window, 32 require('jquery') 33 ); 34 } else { 35 // browser global 36 window.jQueryBridget = factory( 37 window, 38 window.jQuery 39 ); 40 } 41 42}( window, function factory( window, jQuery ) { 43'use strict'; 44 45// ----- utils ----- // 46 47var arraySlice = Array.prototype.slice; 48 49// helper function for logging errors 50// $.error breaks jQuery chaining 51var console = window.console; 52var logError = typeof console == 'undefined' ? function() {} : 53 function( message ) { 54 console.error( message ); 55 }; 56 57// ----- jQueryBridget ----- // 58 59function jQueryBridget( namespace, PluginClass, $ ) { 60 $ = $ || jQuery || window.jQuery; 61 if ( !$ ) { 62 return; 63 } 64 65 // add option method -> $().plugin('option', {...}) 66 if ( !PluginClass.prototype.option ) { 67 // option setter 68 PluginClass.prototype.option = function( opts ) { 69 // bail out if not an object 70 if ( !$.isPlainObject( opts ) ){ 71 return; 72 } 73 this.options = $.extend( true, this.options, opts ); 74 }; 75 } 76 77 // make jQuery plugin 78 $.fn[ namespace ] = function( arg0 /*, arg1 */ ) { 79 if ( typeof arg0 == 'string' ) { 80 // method call $().plugin( 'methodName', { options } ) 81 // shift arguments by 1 82 var args = arraySlice.call( arguments, 1 ); 83 return methodCall( this, arg0, args ); 84 } 85 // just $().plugin({ options }) 86 plainCall( this, arg0 ); 87 return this; 88 }; 89 90 // $().plugin('methodName') 91 function methodCall( $elems, methodName, args ) { 92 var returnValue; 93 var pluginMethodStr = '$().' + namespace + '("' + methodName + '")'; 94 95 $elems.each( function( i, elem ) { 96 // get instance 97 var instance = $.data( elem, namespace ); 98 if ( !instance ) { 99 logError( namespace + ' not initialized. Cannot call methods, i.e. ' + 100 pluginMethodStr ); 101 return; 102 } 103 104 var method = instance[ methodName ]; 105 if ( !method || methodName.charAt(0) == '_' ) { 106 logError( pluginMethodStr + ' is not a valid method' ); 107 return; 108 } 109 110 // apply method, get return value 111 var value = method.apply( instance, args ); 112 // set return value if value is returned, use only first value 113 returnValue = returnValue === undefined ? value : returnValue; 114 }); 115 116 return returnValue !== undefined ? returnValue : $elems; 117 } 118 119 function plainCall( $elems, options ) { 120 $elems.each( function( i, elem ) { 121 var instance = $.data( elem, namespace ); 122 if ( instance ) { 123 // set options & init 124 instance.option( options ); 125 instance._init(); 126 } else { 127 // initialize new instance 128 instance = new PluginClass( elem, options ); 129 $.data( elem, namespace, instance ); 130 } 131 }); 132 } 133 134 updateJQuery( $ ); 135 136} 137 138// ----- updateJQuery ----- // 139 140// set $.bridget for v1 backwards compatibility 141function updateJQuery( $ ) { 142 if ( !$ || ( $ && $.bridget ) ) { 143 return; 144 } 145 $.bridget = jQueryBridget; 146} 147 148updateJQuery( jQuery || window.jQuery ); 149 150// ----- ----- // 151 152return jQueryBridget; 153 154})); 155 156/** 157 * EvEmitter v1.1.0 158 * Lil' event emitter 159 * MIT License 160 */ 161 162/* jshint unused: true, undef: true, strict: true */ 163 164( function( global, factory ) { 165 // universal module definition 166 /* jshint strict: false */ /* globals define, module, window */ 167 if ( typeof define == 'function' && define.amd ) { 168 // AMD - RequireJS 169 define( 'ev-emitter/ev-emitter',factory ); 170 } else if ( typeof module == 'object' && module.exports ) { 171 // CommonJS - Browserify, Webpack 172 module.exports = factory(); 173 } else { 174 // Browser globals 175 global.EvEmitter = factory(); 176 } 177 178}( typeof window != 'undefined' ? window : this, function() { 179 180 181 182function EvEmitter() {} 183 184var proto = EvEmitter.prototype; 185 186proto.on = function( eventName, listener ) { 187 if ( !eventName || !listener ) { 188 return; 189 } 190 // set events hash 191 var events = this._events = this._events || {}; 192 // set listeners array 193 var listeners = events[ eventName ] = events[ eventName ] || []; 194 // only add once 195 if ( listeners.indexOf( listener ) == -1 ) { 196 listeners.push( listener ); 197 } 198 199 return this; 200}; 201 202proto.once = function( eventName, listener ) { 203 if ( !eventName || !listener ) { 204 return; 205 } 206 // add event 207 this.on( eventName, listener ); 208 // set once flag 209 // set onceEvents hash 210 var onceEvents = this._onceEvents = this._onceEvents || {}; 211 // set onceListeners object 212 var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {}; 213 // set flag 214 onceListeners[ listener ] = true; 215 216 return this; 217}; 218 219proto.off = function( eventName, listener ) { 220 var listeners = this._events && this._events[ eventName ]; 221 if ( !listeners || !listeners.length ) { 222 return; 223 } 224 var index = listeners.indexOf( listener ); 225 if ( index != -1 ) { 226 listeners.splice( index, 1 ); 227 } 228 229 return this; 230}; 231 232proto.emitEvent = function( eventName, args ) { 233 var listeners = this._events && this._events[ eventName ]; 234 if ( !listeners || !listeners.length ) { 235 return; 236 } 237 // copy over to avoid interference if .off() in listener 238 listeners = listeners.slice(0); 239 args = args || []; 240 // once stuff 241 var onceListeners = this._onceEvents && this._onceEvents[ eventName ]; 242 243 for ( var i=0; i < listeners.length; i++ ) { 244 var listener = listeners[i] 245 var isOnce = onceListeners && onceListeners[ listener ]; 246 if ( isOnce ) { 247 // remove listener 248 // remove before trigger to prevent recursion 249 this.off( eventName, listener ); 250 // unset once flag 251 delete onceListeners[ listener ]; 252 } 253 // trigger listener 254 listener.apply( this, args ); 255 } 256 257 return this; 258}; 259 260proto.allOff = function() { 261 delete this._events; 262 delete this._onceEvents; 263}; 264 265return EvEmitter; 266 267})); 268 269/*! 270 * getSize v2.0.3 271 * measure size of elements 272 * MIT license 273 */ 274 275/* jshint browser: true, strict: true, undef: true, unused: true */ 276/* globals console: false */ 277 278( function( window, factory ) { 279 /* jshint strict: false */ /* globals define, module */ 280 if ( typeof define == 'function' && define.amd ) { 281 // AMD 282 define( 'get-size/get-size',factory ); 283 } else if ( typeof module == 'object' && module.exports ) { 284 // CommonJS 285 module.exports = factory(); 286 } else { 287 // browser global 288 window.getSize = factory(); 289 } 290 291})( window, function factory() { 292'use strict'; 293 294// -------------------------- helpers -------------------------- // 295 296// get a number from a string, not a percentage 297function getStyleSize( value ) { 298 var num = parseFloat( value ); 299 // not a percent like '100%', and a number 300 var isValid = value.indexOf('%') == -1 && !isNaN( num ); 301 return isValid && num; 302} 303 304function noop() {} 305 306var logError = typeof console == 'undefined' ? noop : 307 function( message ) { 308 console.error( message ); 309 }; 310 311// -------------------------- measurements -------------------------- // 312 313var measurements = [ 314 'paddingLeft', 315 'paddingRight', 316 'paddingTop', 317 'paddingBottom', 318 'marginLeft', 319 'marginRight', 320 'marginTop', 321 'marginBottom', 322 'borderLeftWidth', 323 'borderRightWidth', 324 'borderTopWidth', 325 'borderBottomWidth' 326]; 327 328var measurementsLength = measurements.length; 329 330function getZeroSize() { 331 var size = { 332 width: 0, 333 height: 0, 334 innerWidth: 0, 335 innerHeight: 0, 336 outerWidth: 0, 337 outerHeight: 0 338 }; 339 for ( var i=0; i < measurementsLength; i++ ) { 340 var measurement = measurements[i]; 341 size[ measurement ] = 0; 342 } 343 return size; 344} 345 346// -------------------------- getStyle -------------------------- // 347 348/** 349 * getStyle, get style of element, check for Firefox bug 350 * https://bugzilla.mozilla.org/show_bug.cgi?id=548397 351 */ 352function getStyle( elem ) { 353 var style = getComputedStyle( elem ); 354 if ( !style ) { 355 logError( 'Style returned ' + style + 356 '. Are you running this code in a hidden iframe on Firefox? ' + 357 'See https://bit.ly/getsizebug1' ); 358 } 359 return style; 360} 361 362// -------------------------- setup -------------------------- // 363 364var isSetup = false; 365 366var isBoxSizeOuter; 367 368/** 369 * setup 370 * check isBoxSizerOuter 371 * do on first getSize() rather than on page load for Firefox bug 372 */ 373function setup() { 374 // setup once 375 if ( isSetup ) { 376 return; 377 } 378 isSetup = true; 379 380 // -------------------------- box sizing -------------------------- // 381 382 /** 383 * Chrome & Safari measure the outer-width on style.width on border-box elems 384 * IE11 & Firefox<29 measures the inner-width 385 */ 386 var div = document.createElement('div'); 387 div.style.width = '200px'; 388 div.style.padding = '1px 2px 3px 4px'; 389 div.style.borderStyle = 'solid'; 390 div.style.borderWidth = '1px 2px 3px 4px'; 391 div.style.boxSizing = 'border-box'; 392 393 var body = document.body || document.documentElement; 394 body.appendChild( div ); 395 var style = getStyle( div ); 396 // round value for browser zoom. desandro/masonry#928 397 isBoxSizeOuter = Math.round( getStyleSize( style.width ) ) == 200; 398 getSize.isBoxSizeOuter = isBoxSizeOuter; 399 400 body.removeChild( div ); 401} 402 403// -------------------------- getSize -------------------------- // 404 405function getSize( elem ) { 406 setup(); 407 408 // use querySeletor if elem is string 409 if ( typeof elem == 'string' ) { 410 elem = document.querySelector( elem ); 411 } 412 413 // do not proceed on non-objects 414 if ( !elem || typeof elem != 'object' || !elem.nodeType ) { 415 return; 416 } 417 418 var style = getStyle( elem ); 419 420 // if hidden, everything is 0 421 if ( style.display == 'none' ) { 422 return getZeroSize(); 423 } 424 425 var size = {}; 426 size.width = elem.offsetWidth; 427 size.height = elem.offsetHeight; 428 429 var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box'; 430 431 // get all measurements 432 for ( var i=0; i < measurementsLength; i++ ) { 433 var measurement = measurements[i]; 434 var value = style[ measurement ]; 435 var num = parseFloat( value ); 436 // any 'auto', 'medium' value will be 0 437 size[ measurement ] = !isNaN( num ) ? num : 0; 438 } 439 440 var paddingWidth = size.paddingLeft + size.paddingRight; 441 var paddingHeight = size.paddingTop + size.paddingBottom; 442 var marginWidth = size.marginLeft + size.marginRight; 443 var marginHeight = size.marginTop + size.marginBottom; 444 var borderWidth = size.borderLeftWidth + size.borderRightWidth; 445 var borderHeight = size.borderTopWidth + size.borderBottomWidth; 446 447 var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter; 448 449 // overwrite width and height if we can get it from style 450 var styleWidth = getStyleSize( style.width ); 451 if ( styleWidth !== false ) { 452 size.width = styleWidth + 453 // add padding and border unless it's already including it 454 ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth ); 455 } 456 457 var styleHeight = getStyleSize( style.height ); 458 if ( styleHeight !== false ) { 459 size.height = styleHeight + 460 // add padding and border unless it's already including it 461 ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight ); 462 } 463 464 size.innerWidth = size.width - ( paddingWidth + borderWidth ); 465 size.innerHeight = size.height - ( paddingHeight + borderHeight ); 466 467 size.outerWidth = size.width + marginWidth; 468 size.outerHeight = size.height + marginHeight; 469 470 return size; 471} 472 473return getSize; 474 475}); 476 477/** 478 * matchesSelector v2.0.2 479 * matchesSelector( element, '.selector' ) 480 * MIT license 481 */ 482 483/*jshint browser: true, strict: true, undef: true, unused: true */ 484 485( function( window, factory ) { 486 /*global define: false, module: false */ 487 'use strict'; 488 // universal module definition 489 if ( typeof define == 'function' && define.amd ) { 490 // AMD 491 define( 'desandro-matches-selector/matches-selector',factory ); 492 } else if ( typeof module == 'object' && module.exports ) { 493 // CommonJS 494 module.exports = factory(); 495 } else { 496 // browser global 497 window.matchesSelector = factory(); 498 } 499 500}( window, function factory() { 501 'use strict'; 502 503 var matchesMethod = ( function() { 504 var ElemProto = window.Element.prototype; 505 // check for the standard method name first 506 if ( ElemProto.matches ) { 507 return 'matches'; 508 } 509 // check un-prefixed 510 if ( ElemProto.matchesSelector ) { 511 return 'matchesSelector'; 512 } 513 // check vendor prefixes 514 var prefixes = [ 'webkit', 'moz', 'ms', 'o' ]; 515 516 for ( var i=0; i < prefixes.length; i++ ) { 517 var prefix = prefixes[i]; 518 var method = prefix + 'MatchesSelector'; 519 if ( ElemProto[ method ] ) { 520 return method; 521 } 522 } 523 })(); 524 525 return function matchesSelector( elem, selector ) { 526 return elem[ matchesMethod ]( selector ); 527 }; 528 529})); 530 531/** 532 * Fizzy UI utils v2.0.7 533 * MIT license 534 */ 535 536/*jshint browser: true, undef: true, unused: true, strict: true */ 537 538( function( window, factory ) { 539 // universal module definition 540 /*jshint strict: false */ /*globals define, module, require */ 541 542 if ( typeof define == 'function' && define.amd ) { 543 // AMD 544 define( 'fizzy-ui-utils/utils',[ 545 'desandro-matches-selector/matches-selector' 546 ], function( matchesSelector ) { 547 return factory( window, matchesSelector ); 548 }); 549 } else if ( typeof module == 'object' && module.exports ) { 550 // CommonJS 551 module.exports = factory( 552 window, 553 require('desandro-matches-selector') 554 ); 555 } else { 556 // browser global 557 window.fizzyUIUtils = factory( 558 window, 559 window.matchesSelector 560 ); 561 } 562 563}( window, function factory( window, matchesSelector ) { 564 565 566 567var utils = {}; 568 569// ----- extend ----- // 570 571// extends objects 572utils.extend = function( a, b ) { 573 for ( var prop in b ) { 574 a[ prop ] = b[ prop ]; 575 } 576 return a; 577}; 578 579// ----- modulo ----- // 580 581utils.modulo = function( num, div ) { 582 return ( ( num % div ) + div ) % div; 583}; 584 585// ----- makeArray ----- // 586 587var arraySlice = Array.prototype.slice; 588 589// turn element or nodeList into an array 590utils.makeArray = function( obj ) { 591 if ( Array.isArray( obj ) ) { 592 // use object if already an array 593 return obj; 594 } 595 // return empty array if undefined or null. #6 596 if ( obj === null || obj === undefined ) { 597 return []; 598 } 599 600 var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number'; 601 if ( isArrayLike ) { 602 // convert nodeList to array 603 return arraySlice.call( obj ); 604 } 605 606 // array of single index 607 return [ obj ]; 608}; 609 610// ----- removeFrom ----- // 611 612utils.removeFrom = function( ary, obj ) { 613 var index = ary.indexOf( obj ); 614 if ( index != -1 ) { 615 ary.splice( index, 1 ); 616 } 617}; 618 619// ----- getParent ----- // 620 621utils.getParent = function( elem, selector ) { 622 while ( elem.parentNode && elem != document.body ) { 623 elem = elem.parentNode; 624 if ( matchesSelector( elem, selector ) ) { 625 return elem; 626 } 627 } 628}; 629 630// ----- getQueryElement ----- // 631 632// use element as selector string 633utils.getQueryElement = function( elem ) { 634 if ( typeof elem == 'string' ) { 635 return document.querySelector( elem ); 636 } 637 return elem; 638}; 639 640// ----- handleEvent ----- // 641 642// enable .ontype to trigger from .addEventListener( elem, 'type' ) 643utils.handleEvent = function( event ) { 644 var method = 'on' + event.type; 645 if ( this[ method ] ) { 646 this[ method ]( event ); 647 } 648}; 649 650// ----- filterFindElements ----- // 651 652utils.filterFindElements = function( elems, selector ) { 653 // make array of elems 654 elems = utils.makeArray( elems ); 655 var ffElems = []; 656 657 elems.forEach( function( elem ) { 658 // check that elem is an actual element 659 if ( !( elem instanceof HTMLElement ) ) { 660
660/*nectar addition*/ 661 if(jQuery('body.compose-mode').length == 0) { 662 return; 663 } 664 /*nectar addition end*/ 665 } 666 // add elem if no selector 667 if ( !selector ) { 668 ffElems.push( elem ); 669 return; 670 } 671 // filter & find items if we have a selector 672 // filter 673 if ( matchesSelector( elem, selector ) ) { 674 ffElems.push( elem ); 675 } 676 // find children 677 var childElems = elem.querySelectorAll( selector ); 678 // concat childElems to filterFound array 679 for ( var i=0; i < childElems.length; i++ ) { 680 ffElems.push( childElems[i] ); 681 } 682 }); 683 684 return ffElems; 685}; 686 687// ----- debounceMethod ----- // 688 689utils.debounceMethod = function( _class, methodName, threshold ) { 690 threshold = threshold || 100; 691 // original method 692 var method = _class.prototype[ methodName ]; 693 var timeoutName = methodName + 'Timeout'; 694 695 _class.prototype[ methodName ] = function() { 696 var timeout = this[ timeoutName ]; 697 clearTimeout( timeout ); 698 699 var args = arguments; 700 var _this = this; 701 this[ timeoutName ] = setTimeout( function() { 702 method.apply( _this, args ); 703 delete _this[ timeoutName ]; 704 }, threshold ); 705 }; 706}; 707 708// ----- docReady ----- // 709 710utils.docReady = function( callback ) { 711 var readyState = document.readyState; 712 if ( readyState == 'complete' || readyState == 'interactive' ) { 713 // do async to allow for other scripts to run. metafizzy/flickity#441 714 setTimeout( callback ); 715 } else { 716 document.addEventListener( 'DOMContentLoaded', callback ); 717 } 718}; 719 720// ----- htmlInit ----- // 721 722// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/ 723utils.toDashed = function( str ) { 724 return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) { 725 return $1 + '-' + $2; 726 }).toLowerCase(); 727}; 728 729var console = window.console; 730/** 731 * allow user to initialize classes via [data-namespace] or .js-namespace class 732 * htmlInit( Widget, 'widgetName' ) 733 * options are parsed from data-namespace-options 734 */ 735utils.htmlInit = function( WidgetClass, namespace ) { 736 utils.docReady( function() { 737 var dashedNamespace = utils.toDashed( namespace ); 738 var dataAttr = 'data-' + dashedNamespace; 739 var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' ); 740 var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace ); 741 var elems = utils.makeArray( dataAttrElems ) 742 .concat( utils.makeArray( jsDashElems ) ); 743 var dataOptionsAttr = dataAttr + '-options'; 744 var jQuery = window.jQuery; 745 746 elems.forEach( function( elem ) { 747 var attr = elem.getAttribute( dataAttr ) || 748 elem.getAttribute( dataOptionsAttr ); 749 var options; 750 try { 751 options = attr && JSON.parse( attr ); 752 } catch ( error ) { 753 // log error, do not initialize 754 if ( console ) { 755 console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className + 756 ': ' + error ); 757 } 758 return; 759 } 760 // initialize 761 var instance = new WidgetClass( elem, options ); 762 // make available via $().data('namespace') 763 if ( jQuery ) { 764 jQuery.data( elem, namespace, instance ); 765 } 766 }); 767 768 }); 769}; 770 771// ----- ----- // 772 773return utils; 774 775})); 776 777// Flickity.Cell 778( function( window, factory ) { 779 // universal module definition 780 /* jshint strict: false */ 781 if ( typeof define == 'function' && define.amd ) { 782 // AMD 783 define( 'flickity/js/cell',[ 784 'get-size/get-size' 785 ], function( getSize ) { 786 return factory( window, getSize ); 787 }); 788 } else if ( typeof module == 'object' && module.exports ) { 789 // CommonJS 790 module.exports = factory( 791 window, 792 require('get-size') 793 ); 794 } else { 795 // browser global 796 window.Flickity = window.Flickity || {}; 797 window.Flickity.Cell = factory( 798 window, 799 window.getSize 800 ); 801 } 802 803}( window, function factory( window, getSize ) { 804 805 806 807function Cell( elem, parent ) { 808 this.element = elem; 809 this.parent = parent; 810 811 this.create(); 812} 813 814var proto = Cell.prototype; 815 816proto.create = function() { 817 this.element.style.position = 'absolute'; 818 this.element.setAttribute( 'aria-selected', 'false' ); 819 this.x = 0; 820 this.shift = 0; 821}; 822 823proto.destroy = function() { 824 // reset style 825 this.element.style.position = ''; 826 var side = this.parent.originSide; 827 this.element.removeAttribute('aria-selected'); 828 this.element.style[ side ] = ''; 829}; 830 831proto.getSize = function() { 832 this.size = getSize( this.element ); 833}; 834 835proto.setPosition = function( x ) { 836 this.x = x; 837 this.updateTarget(); 838 this.renderPosition( x ); 839}; 840 841// setDefaultTarget v1 method, backwards compatibility, remove in v3 842proto.updateTarget = proto.setDefaultTarget = function() { 843 var marginProperty = this.parent.originSide == 'left' ? 'marginLeft' : 'marginRight'; 844 this.target = this.x + this.size[ marginProperty ] + 845 this.size.width * this.parent.cellAlign; 846}; 847 848proto.renderPosition = function( x ) { 849 // render position of cell with in slider 850 var side = this.parent.originSide; 851 this.element.style[ side ] = this.parent.getPositionValue( x ); 852}; 853 854/** 855 * @param {Integer} factor - 0, 1, or -1 856**/ 857proto.wrapShift = function( shift ) { 858 this.shift = shift; 859 this.renderPosition( this.x + this.parent.slideableWidth * shift ); 860}; 861 862proto.remove = function() { 863 this.element.parentNode.removeChild( this.element ); 864}; 865 866return Cell; 867 868})); 869 870// slide 871( function( window, factory ) { 872 // universal module definition 873 /* jshint strict: false */ 874 if ( typeof define == 'function' && define.amd ) { 875 // AMD 876 define( 'flickity/js/slide',factory ); 877 } else if ( typeof module == 'object' && module.exports ) { 878 // CommonJS 879 module.exports = factory(); 880 } else { 881 // browser global 882 window.Flickity = window.Flickity || {}; 883 window.Flickity.Slide = factory(); 884 } 885 886}( window, function factory() { 887'use strict'; 888 889function Slide( parent ) { 890 this.parent = parent; 891 this.isOriginLeft = parent.originSide == 'left'; 892 this.cells = []; 893 this.outerWidth = 0; 894 this.height = 0; 895} 896 897var proto = Slide.prototype; 898 899proto.addCell = function( cell ) { 900 this.cells.push( cell ); 901 this.outerWidth += cell.size.outerWidth; 902 this.height = Math.max( cell.size.outerHeight, this.height ); 903 // first cell stuff 904 if ( this.cells.length == 1 ) { 905 this.x = cell.x; // x comes from first cell 906 var beginMargin = this.isOriginLeft ? 'marginLeft' : 'marginRight'; 907 this.firstMargin = cell.size[ beginMargin ]; 908 } 909}; 910 911proto.updateTarget = function() { 912 var endMargin = this.isOriginLeft ? 'marginRight' : 'marginLeft'; 913 var lastCell = this.getLastCell(); 914 var lastMargin = lastCell ? lastCell.size[ endMargin ] : 0; 915 var slideWidth = this.outerWidth - ( this.firstMargin + lastMargin ); 916 this.target = this.x + this.firstMargin + slideWidth * this.parent.cellAlign; 917}; 918 919proto.getLastCell = function() { 920 return this.cells[ this.cells.length - 1 ]; 921}; 922 923proto.select = function() { 924 this.changeSelected( true ); 925}; 926 927proto.unselect = function() { 928 this.changeSelected( false ); 929}; 930 931proto.changeSelected = function( isSelected ) { 932 var classMethod = isSelected ? 'add' : 'remove';
933 this.cells.forEach( function( cell ) { 934 cell.element.classList[ classMethod ]('is-selected'); 935 cell.element.setAttribute( 'aria-selected', isSelected.toString() ); 936 }); 937}; 938 939proto.getCellElements = function() { 940 return this.cells.map( function( cell ) { 941 return cell.element; 942 }); 943}; 944 945return Slide; 946 947})); 948 949// animate 950( function( window, factory ) { 951 // universal module definition 952 /* jshint strict: false */ 953 if ( typeof define == 'function' && define.amd ) { 954 // AMD 955 define( 'flickity/js/animate',[ 956 'fizzy-ui-utils/utils' 957 ], function( utils ) { 958 return factory( window, utils ); 959 }); 960 } else if ( typeof module == 'object' && module.exports ) { 961 // CommonJS 962 module.exports = factory( 963 window, 964 require('fizzy-ui-utils') 965 ); 966 } else { 967 // browser global 968 window.Flickity = window.Flickity || {}; 969 window.Flickity.animatePrototype = factory( 970 window, 971 window.fizzyUIUtils 972 ); 973 } 974 975}( window, function factory( window, utils ) { 976 977 978 979// -------------------------- animate -------------------------- // 980 981var proto = {}; 982 983proto.startAnimation = function() { 984 if ( this.isAnimating ) { 985 return; 986 } 987 988 this.isAnimating = true; 989 this.restingFrames = 0; 990 this.animate(); 991}; 992 993proto.animate = function() { 994 this.applyDragForce(); 995 this.applySelectedAttraction(); 996 997 var previousX = this.x; 998 999 this.integratePhysics(); 1000 this.positionSlider(); 1001 this.settle( previousX ); 1002 // animate next frame 1003 if ( this.isAnimating ) { 1004 var _this = this; 1005 requestAnimationFrame( function animateFrame() { 1006 _this.animate(); 1007 }); 1008 } 1009}; 1010 1011proto.positionSlider = function() { 1012 var x = this.x; 1013 // wrap position around 1014 if ( this.options.wrapAround && this.cells.length > 1 ) { 1015 x = utils.modulo( x, this.slideableWidth ); 1016 x = x - this.slideableWidth; 1017 this.shiftWrapCells( x ); 1018 } 1019 1020 x = x + this.cursorPosition; 1021 // reverse if right-to-left and using transform 1022 x = this.options.rightToLeft ? -x : x; 1023 var value = this.getPositionValue( x ); 1024 // use 3D tranforms for hardware acceleration on iOS 1025 // but use 2D when settled, for better font-rendering 1026 this.slider.style.transform = this.isAnimating ? 1027 'translate3d(' + value + ',0,0)' : 'translateX(' + value + ')'; 1028 1029 // scroll event 1030 var firstSlide = this.slides[0]; 1031 if ( firstSlide ) { 1032 var positionX = -this.x - firstSlide.target; 1033 var progress = positionX / this.slidesWidth; 1034 this.dispatchEvent( 'scroll', null, [ progress, positionX ] ); 1035 } 1036}; 1037 1038proto.setTranslateX = function( x, is3d ) { 1039 x += this.cursorPosition; 1040 // reverse if right-to-left and using transform 1041 x = this.options.rightToLeft ? -x : x; 1042 var translateX = this.getPositionValue( x ); 1043 // use 3D transforms for hardware acceleration on iOS 1044 // but use 2D when settled, for better font-rendering 1045 this.slider.style.transform = is3d ? 1046 'translate3d(' + translateX + ',0,0)' : 'translateX(' + translateX + ')'; 1047}; 1048 1049proto.dispatchScrollEvent = function() { 1050 var firstSlide = this.slides[0]; 1051 if ( !firstSlide ) { 1052 return; 1053 } 1054 var positionX = -this.x - firstSlide.target; 1055 var progress = positionX / this.slidesWidth; 1056 this.dispatchEvent( 'scroll', null, [ progress, positionX ] ); 1057}; 1058 1059 1060proto.positionSliderAtSelected = function() { 1061 if ( !this.cells.length ) { 1062 return; 1063 } 1064 this.x = -this.selectedSlide.target; 1065 this.velocity = 0; // stop wobble 1066 this.positionSlider(); 1067}; 1068 1069proto.getPositionValue = function( position ) { 1070 if ( this.options.percentPosition ) { 1071 // percent position, round to 2 digits, like 12.34% 1072 return ( Math.round( ( position / this.size.innerWidth ) * 10000 ) * 0.01 )+ '%'; 1073 } else { 1074 // pixel positioning 1075 return Math.round( position ) + 'px'; 1076 } 1077}; 1078 1079proto.settle = function( previousX ) { 1080 // keep track of frames where x hasn't moved 1081 if ( !this.isPointerDown && Math.round( this.x * 100 ) == Math.round( previousX * 100 ) ) { 1082 this.restingFrames++; 1083 } 1084 // stop animating if resting for 3 or more frames 1085 if ( this.restingFrames > 2 ) { 1086 this.isAnimating = false; 1087 delete this.isFreeScrolling; 1088 // render position with translateX when settled 1089 this.positionSlider(); 1090 this.dispatchEvent( 'settle', null, [ this.selectedIndex ] ); 1091 } 1092}; 1093 1094proto.shiftWrapCells = function( x ) { 1095 // shift before cells 1096 var beforeGap = this.cursorPosition + x; 1097 this._shiftCells( this.beforeShiftCells, beforeGap, -1 ); 1098 // shift after cells 1099 var afterGap = this.size.innerWidth - ( x + this.slideableWidth + this.cursorPosition ); 1100 this._shiftCells( this.afterShiftCells, afterGap, 1 ); 1101}; 1102 1103proto._shiftCells = function( cells, gap, shift ) { 1104 for ( var i=0; i < cells.length; i++ ) { 1105 var cell = cells[i]; 1106 var cellShift = gap > 0 ? shift : 0; 1107 cell.wrapShift( cellShift ); 1108 gap -= cell.size.outerWidth; 1109 } 1110}; 1111 1112proto._unshiftCells = function( cells ) { 1113 if ( !cells || !cells.length ) { 1114 return; 1115 } 1116 for ( var i=0; i < cells.length; i++ ) { 1117 cells[i].wrapShift( 0 ); 1118 } 1119}; 1120 1121// -------------------------- physics -------------------------- // 1122 1123proto.integratePhysics = function() { 1124 this.x += this.velocity; 1125 this.velocity *= this.getFrictionFactor(); 1126}; 1127 1128proto.applyForce = function( force ) { 1129 this.velocity += force; 1130}; 1131 1132proto.getFrictionFactor = function() { 1133 return 1 - this.options[ this.isFreeScrolling ? 'freeScrollFriction' : 'friction' ]; 1134}; 1135 1136proto.getRestingPosition = function() { 1137 // my thanks to Steven Wittens, who simplified this math greatly 1138 return this.x + this.velocity / ( 1 - this.getFrictionFactor() ); 1139}; 1140 1141proto.applyDragForce = function() { 1142 if ( !this.isDraggable || !this.isPointerDown ) { 1143 return; 1144 } 1145 // change the position to drag position by applying force 1146 var dragVelocity = this.dragX - this.x; 1147 var dragForce = dragVelocity - this.velocity; 1148 this.applyForce( dragForce ); 1149}; 1150 1151proto.applySelectedAttraction = function() { 1152 // do not attract if pointer down or no slides 1153 var dragDown = this.isDraggable && this.isPointerDown; 1154 if ( dragDown || this.isFreeScrolling || !this.slides.length ) { 1155 return; 1156 } 1157 var distance = this.selectedSlide.target * -1 - this.x; 1158 var force = distance * this.options.selectedAttraction; 1159 this.applyForce( force ); 1160}; 1161 1162return proto; 1163 1164})); 1165 1166// Flickity main 1167( function( window, factory ) { 1168 // universal module definition 1169 /* jshint strict: false */ 1170 if ( typeof define == 'function' && define.amd ) { 1171 // AMD 1172 define( 'flickity/js/flickity',[ 1173 'ev-emitter/ev-emitter', 1174 'get-size/get-size', 1175 'fizzy-ui-utils/utils', 1176 './cell', 1177 './slide', 1178 './animate' 1179 ], function( EvEmitter, getSize, utils, Cell, Slide, animatePrototype ) { 1180 return factory( window, EvEmitter, getSize, utils, Cell, Slide, animatePrototype ); 1181 }); 1182 } else if ( typeof module == 'object' && module.exports ) { 1183 // CommonJS 1184 module.exports = factory( 1185 window, 1186 require('ev-emitter'), 1187 require('get-size'), 1188 require('fizzy-ui-utils'), 1189 require('./cell'), 1190 require('./slide'), 1191 require('./animate') 1192 ); 1193 } else { 1194 // browser global 1195 var _Flickity = window.Flickity; 1196 1197 window.Flickity = factory( 1198 window, 1199 window.EvEmitter, 1200 window.getSize, 1201 window.fizzyUIUtils, 1202 _Flickity.Cell, 1203 _Flickity.Slide, 1204 _Flickity.animatePrototype 1205 ); 1206 } 1207 1208}( window, function factory( window, EvEmitter, getSize, 1209 utils, Cell, Slide, animatePrototype ) { 1210 1211 1212 1213// vars 1214var jQuery = window.jQuery; 1215var getComputedStyle = window.getComputedStyle; 1216var console = window.console; 1217 1218function moveElements( elems, toElem ) { 1219 elems = utils.makeArray( elems ); 1220 while ( elems.length ) { 1221 toElem.appendChild( elems.shift() ); 1222 } 1223} 1224 1225// -------------------------- Flickity -------------------------- // 1226 1227// globally unique identifiers 1228var GUID = 0; 1229// internal store of all Flickity intances 1230var instances = {}; 1231 1232function Flickity( element, options ) { 1233 var queryElement = utils.getQueryElement( element ); 1234 if ( !queryElement ) { 1235 if ( console ) { 1236 console.error( 'Bad element for Flickity: ' + ( queryElement || element ) ); 1237 } 1238 return; 1239 } 1240 this.element = queryElement; 1241 // do not initialize twice on same element 1242 if ( this.element.flickityGUID ) { 1243 var instance = instances[ this.element.flickityGUID ]; 1244 instance.option( options ); 1245 return instance; 1246 } 1247 1248 // add jQuery 1249 if ( jQuery ) { 1250 this.$element = jQuery( this.element ); 1251 } 1252 // options 1253 this.options = utils.extend( {}, this.constructor.defaults ); 1254 this.option( options ); 1255 1256 // kick things off 1257 this._create(); 1258} 1259 1260Flickity.defaults = { 1261 accessibility: true, 1262 // adaptiveHeight: false, 1263 cellAlign: 'center', 1264 // cellSelector: undefined,
1265 // contain: false, 1266 freeScrollFriction: 0.075, // friction when free-scrolling 1267 friction: 0.28, // friction when selecting 1268 namespaceJQueryEvents: true, 1269 // initialIndex: 0, 1270 percentPosition: true, 1271 resize: true, 1272 selectedAttraction: 0.025, 1273 setGallerySize: true 1274 // watchCSS: false, 1275 // wrapAround: false 1276}; 1277 1278// hash of methods triggered on _create() 1279Flickity.createMethods = []; 1280 1281var proto = Flickity.prototype; 1282// inherit EventEmitter 1283utils.extend( proto, EvEmitter.prototype ); 1284 1285proto._create = function() { 1286 // add id for Flickity.data 1287 var id = this.guid = ++GUID; 1288 this.element.flickityGUID = id; // expando 1289 instances[ id ] = this; // associate via id 1290 // initial properties 1291 this.selectedIndex = 0; 1292 // how many frames slider has been in same position 1293 this.restingFrames = 0; 1294 // initial physics properties 1295 this.x = 0; 1296 this.velocity = 0; 1297 this.originSide = this.options.rightToLeft ? 'right' : 'left'; 1298 // create viewport & slider 1299 /*nectar addition*/ 1300 1301 if(this.$element.hasClass('generate-markup')) { 1302 this.viewport = document.createElement('div'); 1303 this.viewport.className = 'flickity-viewport'; 1304 } else { 1305 this.viewport = this.$element.find('.flickity-viewport')[0]; 1306 this.slider = this.$element.find('.flickity-slider')[0]; 1307 this.viewport.className = 'flickity-viewport'; 1308 } 1309 1310 this._createSlider(); 1311 1312 1313 /*nectar addition end*/ 1314 1315 if ( this.options.resize || this.options.watchCSS ) { 1316 window.addEventListener( 'resize', this ); 1317 } 1318 1319 // add listeners from on option 1320 for ( var eventName in this.options.on ) { 1321 var listener = this.options.on[ eventName ]; 1322 this.on( eventName, listener ); 1323 } 1324 1325 Flickity.createMethods.forEach( function( method ) { 1326 this[ method ](); 1327 }, this ); 1328 1329 if ( this.options.watchCSS ) { 1330 this.watchCSS(); 1331 } else { 1332 this.activate(); 1333 } 1334 1335}; 1336 1337/** 1338 * set options 1339 * @param {Object} opts 1340 */ 1341proto.option = function( opts ) { 1342 utils.extend( this.options, opts ); 1343}; 1344 1345proto.activate = function() { 1346 if ( this.isActive ) { 1347 return; 1348 } 1349 this.isActive = true; 1350 this.element.classList.add('flickity-enabled'); 1351 if ( this.options.rightToLeft ) { 1352 this.element.classList.add('flickity-rtl'); 1353 } 1354 1355 this.getSize(); 1356 // move initial cell elements so they can be loaded as cells 1357 var cellElems = this._filterFindCellElements( this.element.children ); 1358 1359 /* nectar addition */ 1360 if(this.$element.hasClass('generate-markup')) { 1361 moveElements( cellElems, this.slider ); 1362 this.viewport.appendChild( this.slider ); 1363 this.element.appendChild( this.viewport ); 1364 } else { 1365 //do nothing 1366 } 1367 /* nectar addition end */ 1368 1369 // get cells from children 1370 this.reloadCells(); 1371 1372 if ( this.options.accessibility ) { 1373 // allow element to focusable 1374 this.element.tabIndex = 0; 1375 // listen for key presses 1376 this.element.addEventListener( 'keydown', this ); 1377 } 1378 1379 this.emitEvent('activate'); 1380 1381 var index; 1382 var initialIndex = this.options.initialIndex; 1383 if ( this.isInitActivated ) { 1384 index = this.selectedIndex; 1385 } else if ( initialIndex !== undefined ) { 1386 index = this.cells[ initialIndex ] ? initialIndex : 0; 1387 } else { 1388 index = 0; 1389 } 1390 // select instantly 1391 this.select( index, false, true ); 1392 // flag for initial activation, for using initialIndex 1393 this.isInitActivated = true; 1394 // ready event. #493 1395 this.dispatchEvent('ready'); 1396}; 1397 1398// slider positions the cells 1399/* nectar addition */ 1400proto._createSlider = function() { 1401 if(this.$element.hasClass('generate-markup')) { 1402 var slider = document.createElement('div'); 1403 slider.className = 'flickity-slider'; 1404 slider.style[ this.originSide ] = 0; 1405 this.slider = slider; 1406 } else { 1407 // slider element does all the positioning 1408 //var slider = document.createElement('div'); 1409 //slider.className = 'flickity-slider'; 1410 this.slider.style[ this.originSide ] = 0; 1411 //this.slider = slider; 1412 } 1413 1414}; 1415/* nectar addition end */ 1416 1417proto._filterFindCellElements = function( elems ) { 1418 return utils.filterFindElements( elems, this.options.cellSelector ); 1419}; 1420 1421// goes through all children 1422proto.reloadCells = function() { 1423 /* nectar addition */ 1424 1425 if(jQuery(this.slider).parent().parent().find('.flickity-page-dots').length > 0) { 1426 var $that = this; 1427 setTimeout(function(){ 1428 $that.pageDots.setDots(); 1429 },100); 1430 } 1431 var slidesArr = []; 1432 jQuery(this.slider).find('> *').each(function(i){ 1433 slidesArr[i] = jQuery(this)[0]; 1434 }); 1435 1436 1437 // collection of item elements 1438 this.cells = this._makeCells(slidesArr); 1439 /* nectar addition end */ 1440 this.positionCells(); 1441 this._getWrapShiftCells(); 1442 this.setGallerySize(); 1443}; 1444 1445/** 1446 * turn elements into Flickity.Cells 1447 * @param {Array or NodeList or HTMLElement} elems 1448 * @returns {Array} items - collection of new Flickity Cells 1449 */ 1450proto._makeCells = function( elems ) { 1451 var cellElems = this._filterFindCellElements( elems ); 1452 1453 // create new Flickity for collection 1454 var cells = cellElems.map( function( cellElem ) { 1455 return new Cell( cellElem, this ); 1456 }, this ); 1457 1458 return cells; 1459}; 1460 1461proto.getLastCell = function() { 1462 return this.cells[ this.cells.length - 1 ]; 1463}; 1464 1465proto.getLastSlide = function() { 1466 return this.slides[ this.slides.length - 1 ]; 1467}; 1468 1469// positions all cells 1470proto.positionCells = function() { 1471 // size all cells 1472 this._sizeCells( this.cells ); 1473 // position all cells 1474 this._positionCells( 0 ); 1475}; 1476 1477/** 1478 * position certain cells 1479 * @param {Integer} index - which cell to start with 1480 */ 1481proto._positionCells = function( index ) { 1482 index = index || 0; 1483 // also measure maxCellHeight 1484 // start 0 if positioning all cells 1485 this.maxCellHeight = index ? this.maxCellHeight || 0 : 0; 1486 var cellX = 0; 1487 // get cellX 1488 if ( index > 0 ) { 1489 var startCell = this.cells[ index - 1 ]; 1490 cellX = startCell.x + startCell.size.outerWidth; 1491 } 1492 var len = this.cells.length; 1493 for ( var i=index; i < len; i++ ) { 1494 var cell = this.cells[i]; 1495 cell.setPosition( cellX ); 1496 cellX += cell.size.outerWidth; 1497 this.maxCellHeight = Math.max( cell.size.outerHeight, this.maxCellHeight ); 1498 } 1499 // keep track of cellX for wrap-around 1500 this.slideableWidth = cellX; 1501 // slides 1502 this.updateSlides(); 1503 // contain slides target 1504 this._containSlides(); 1505 // update slidesWidth 1506 this.slidesWidth = len ? this.getLastSlide().target - this.slides[0].target : 0; 1507}; 1508 1509/** 1510 * cell.getSize() on multiple cells 1511 * @param {Array} cells 1512 */ 1513proto._sizeCells = function( cells ) {
1514 cells.forEach( function( cell ) { 1515 cell.getSize(); 1516 }); 1517}; 1518 1519// -------------------------- -------------------------- // 1520 1521proto.updateSlides = function() { 1522 this.slides = []; 1523 if ( !this.cells.length ) { 1524 return; 1525 } 1526 1527 var slide = new Slide( this ); 1528 this.slides.push( slide ); 1529 var isOriginLeft = this.originSide == 'left'; 1530 var nextMargin = isOriginLeft ? 'marginRight' : 'marginLeft'; 1531 1532 var canCellFit = this._getCanCellFit(); 1533 1534 this.cells.forEach( function( cell, i ) { 1535 // just add cell if first cell in slide 1536 if ( !slide.cells.length ) { 1537 slide.addCell( cell ); 1538 return; 1539 } 1540 1541 var slideWidth = ( slide.outerWidth - slide.firstMargin ) + 1542 ( cell.size.outerWidth - cell.size[ nextMargin ] ); 1543 1544 if ( canCellFit.call( this, i, slideWidth ) ) { 1545 slide.addCell( cell ); 1546 } else { 1547 // doesn't fit, new slide 1548 slide.updateTarget(); 1549 1550 slide = new Slide( this ); 1551 this.slides.push( slide ); 1552 slide.addCell( cell ); 1553 } 1554 }, this ); 1555 // last slide 1556 slide.updateTarget(); 1557 // update .selectedSlide 1558 this.updateSelectedSlide(); 1559}; 1560 1561proto._getCanCellFit = function() { 1562 var groupCells = this.options.groupCells; 1563 if ( !groupCells ) { 1564 return function() { 1565 return false; 1566 }; 1567 } else if ( typeof groupCells == 'number' ) { 1568 // group by number. 3 -> [0,1,2], [3,4,5], ... 1569 var number = parseInt( groupCells, 10 ); 1570 return function( i ) { 1571 return ( i % number ) !== 0; 1572 }; 1573 } 1574 // default, group by width of slide 1575 // parse '75% 1576 var percentMatch = typeof groupCells == 'string' && 1577 groupCells.match(/^(\d+)%$/); 1578 var percent = percentMatch ? parseInt( percentMatch[1], 10 ) / 100 : 1; 1579 return function( i, slideWidth ) { 1580 return slideWidth <= ( this.size.innerWidth + 1 ) * percent; 1581 }; 1582}; 1583 1584// alias _init for jQuery plugin .flickity() 1585proto._init = 1586proto.reposition = function() { 1587 this.positionCells(); 1588 this.positionSliderAtSelected(); 1589}; 1590 1591proto.getSize = function() { 1592 this.size = getSize( this.element ); 1593 this.setCellAlign(); 1594 this.cursorPosition = this.size.innerWidth * this.cellAlign; 1595}; 1596 1597var cellAlignShorthands = { 1598 // cell align, then based on origin side 1599 center: { 1600 left: 0.5, 1601 right: 0.5 1602 }, 1603 left: { 1604 left: 0, 1605 right: 1 1606 }, 1607 right: { 1608 right: 0, 1609 left: 1 1610 } 1611}; 1612 1613proto.setCellAlign = function() { 1614 var shorthand = cellAlignShorthands[ this.options.cellAlign ]; 1615 this.cellAlign = shorthand ? shorthand[ this.originSide ] : this.options.cellAlign; 1616}; 1617 1618proto.setGallerySize = function() { 1619 if ( this.options.setGallerySize ) { 1620 var height = this.options.adaptiveHeight && this.selectedSlide ? 1621 this.selectedSlide.height : this.maxCellHeight; 1622 this.viewport.style.height = height + 'px'; 1623 } 1624}; 1625 1626proto._getWrapShiftCells = function() { 1627 // only for wrap-around 1628 if ( !this.options.wrapAround ) { 1629 return; 1630 } 1631 // unshift previous cells 1632 this._unshiftCells( this.beforeShiftCells ); 1633 this._unshiftCells( this.afterShiftCells ); 1634 // get before cells 1635 // initial gap 1636 var gapX = this.cursorPosition; 1637 var cellIndex = this.cells.length - 1; 1638 this.beforeShiftCells = this._getGapCells( gapX, cellIndex, -1 ); 1639 // get after cells 1640 // ending gap between last cell and end of gallery viewport 1641 gapX = this.size.innerWidth - this.cursorPosition; 1642 // start cloning at first cell, working forwards 1643 this.afterShiftCells = this._getGapCells( gapX, 0, 1 ); 1644}; 1645 1646proto._getGapCells = function( gapX, cellIndex, increment ) { 1647 // keep adding cells until the cover the initial gap 1648 var cells = []; 1649 while ( gapX > 0 ) { 1650 var cell = this.cells[ cellIndex ]; 1651 if ( !cell ) { 1652 break; 1653 } 1654 cells.push( cell ); 1655 cellIndex += increment; 1656 gapX -= cell.size.outerWidth; 1657 } 1658 return cells; 1659}; 1660 1661// ----- contain ----- // 1662 1663// contain cell targets so no excess sliding 1664proto._containSlides = function() { 1665 if ( !this.options.contain || this.options.wrapAround || !this.cells.length ) { 1666 return; 1667 } 1668 var isRightToLeft = this.options.rightToLeft; 1669 var beginMargin = isRightToLeft ? 'marginRight' : 'marginLeft'; 1670 var endMargin = isRightToLeft ? 'marginLeft' : 'marginRight'; 1671 var contentWidth = this.slideableWidth - this.getLastCell().size[ endMargin ]; 1672 // content is less than gallery size 1673 var isContentSmaller = contentWidth < this.size.innerWidth; 1674 // bounds 1675 var beginBound = this.cursorPosition + this.cells[0].size[ beginMargin ]; 1676 var endBound = contentWidth - this.size.innerWidth * ( 1 - this.cellAlign ); 1677 // contain each cell target
1678 this.slides.forEach( function( slide ) { 1679 if ( isContentSmaller ) { 1680 // all cells fit inside gallery 1681 slide.target = contentWidth * this.cellAlign; 1682 } else { 1683 // contain to bounds 1684 slide.target = Math.max( slide.target, beginBound ); 1685 slide.target = Math.min( slide.target, endBound ); 1686 } 1687 }, this ); 1688}; 1689 1690// ----- ----- // 1691 1692/** 1693 * emits events via eventEmitter and jQuery events 1694 * @param {String} type - name of event 1695 * @param {Event} event - original event 1696 * @param {Array} args - extra arguments 1697 */ 1698proto.dispatchEvent = function( type, event, args ) { 1699 var emitArgs = event ? [ event ].concat( args ) : args; 1700 this.emitEvent( type, emitArgs ); 1701 1702 if ( jQuery && this.$element ) { 1703 // default trigger with type if no event 1704 type += this.options.namespaceJQueryEvents ? '.flickity' : ''; 1705 var $event = type; 1706 if ( event ) { 1707 // create jQuery event 1708 var jQEvent = new jQuery.Event( event ); 1709 jQEvent.type = type; 1710 $event = jQEvent; 1711 } 1712 this.$element.trigger( $event, args ); 1713 } 1714}; 1715 1716// -------------------------- select -------------------------- // 1717 1718/** 1719 * @param {Integer} index - index of the slide 1720 * @param {Boolean} isWrap - will wrap-around to last/first if at the end 1721 * @param {Boolean} isInstant - will immediately set position at selected cell 1722 */ 1723proto.select = function( index, isWrap, isInstant ) { 1724 if ( !this.isActive ) { 1725 return; 1726 } 1727 index = parseInt( index, 10 ); 1728 this._wrapSelect( index ); 1729 1730 if ( this.options.wrapAround || isWrap ) { 1731 index = utils.modulo( index, this.slides.length ); 1732 } 1733 // bail if invalid index 1734 if ( !this.slides[ index ] ) { 1735 return; 1736 } 1737 var prevIndex = this.selectedIndex; 1738 this.selectedIndex = index; 1739 this.updateSelectedSlide(); 1740 if ( isInstant ) { 1741 this.positionSliderAtSelected(); 1742 } else { 1743 this.startAnimation(); 1744 } 1745 if ( this.options.adaptiveHeight ) { 1746 this.setGallerySize(); 1747 } 1748 // events 1749 this.dispatchEvent( 'select', null, [ index ] ); 1750 // change event if new index 1751 if ( index != prevIndex ) { 1752 this.dispatchEvent( 'change', null, [ index ] ); 1753 } 1754 // old v1 event name, remove in v3 1755 this.dispatchEvent('cellSelect'); 1756}; 1757 1758// wraps position for wrapAround, to move to closest slide. #113 1759proto._wrapSelect = function( index ) { 1760 var len = this.slides.length; 1761 var isWrapping = this.options.wrapAround && len > 1; 1762 if ( !isWrapping ) { 1763 return index; 1764 } 1765 var wrapIndex = utils.modulo( index, len ); 1766 // go to shortest 1767 var delta = Math.abs( wrapIndex - this.selectedIndex ); 1768 var backWrapDelta = Math.abs( ( wrapIndex + len ) - this.selectedIndex ); 1769 var forewardWrapDelta = Math.abs( ( wrapIndex - len ) - this.selectedIndex ); 1770 if ( !this.isDragSelect && backWrapDelta < delta ) { 1771 index += len; 1772 } else if ( !this.isDragSelect && forewardWrapDelta < delta ) { 1773 index -= len; 1774 } 1775 // wrap position so slider is within normal area 1776 if ( index < 0 ) { 1777 this.x -= this.slideableWidth; 1778 } else if ( index >= len ) { 1779 this.x += this.slideableWidth; 1780 } 1781}; 1782 1783proto.previous = function( isWrap, isInstant ) { 1784 this.select( this.selectedIndex - 1, isWrap, isInstant ); 1785}; 1786 1787proto.next = function( isWrap, isInstant ) { 1788 this.select( this.selectedIndex + 1, isWrap, isInstant ); 1789}; 1790 1791proto.updateSelectedSlide = function() { 1792 var slide = this.slides[ this.selectedIndex ]; 1793 // selectedIndex could be outside of slides, if triggered before resize() 1794 if ( !slide ) { 1795 return; 1796 } 1797 // unselect previous selected slide 1798 this.unselectSelectedSlide(); 1799 // update new selected slide 1800 this.selectedSlide = slide; 1801 slide.select(); 1802 this.selectedCells = slide.cells; 1803 this.selectedElements = slide.getCellElements(); 1804 // HACK: selectedCell & selectedElement is first cell in slide, backwards compatibility 1805 // Remove in v3? 1806 this.selectedCell = slide.cells[0]; 1807 this.selectedElement = this.selectedElements[0]; 1808}; 1809 1810proto.unselectSelectedSlide = function() { 1811 if ( this.selectedSlide ) { 1812 this.selectedSlide.unselect(); 1813 } 1814}; 1815 1816/** 1817 * select slide from number or cell element 1818 * @param {Element or Number} elem 1819 */ 1820proto.selectCell = function( value, isWrap, isInstant ) { 1821 // get cell 1822 var cell = this.queryCell( value ); 1823 if ( !cell ) { 1824 return; 1825 } 1826 1827 var index = this.getCellSlideIndex( cell ); 1828 this.select( index, isWrap, isInstant ); 1829}; 1830 1831proto.getCellSlideIndex = function( cell ) { 1832 // get index of slides that has cell 1833 for ( var i=0; i < this.slides.length; i++ ) { 1834 var slide = this.slides[i]; 1835 var index = slide.cells.indexOf( cell ); 1836 if ( index != -1 ) { 1837 return i; 1838 } 1839 } 1840}; 1841 1842// -------------------------- get cells -------------------------- // 1843 1844/** 1845 * get Flickity.Cell, given an Element 1846 * @param {Element} elem 1847 * @returns {Flickity.Cell} item 1848 */ 1849proto.getCell = function( elem ) { 1850 // loop through cells to get the one that matches 1851 for ( var i=0; i < this.cells.length; i++ ) { 1852 var cell = this.cells[i]; 1853 if ( cell.element == elem ) { 1854 return cell; 1855 } 1856 } 1857}; 1858 1859/** 1860 * get collection of Flickity.Cells, given Elements 1861 * @param {Element, Array, NodeList} elems 1862 * @returns {Array} cells - Flickity.Cells 1863 */ 1864proto.getCells = function( elems ) { 1865 elems = utils.makeArray( elems ); 1866 var cells = [];
1867 elems.forEach( function( elem ) { 1868 var cell = this.getCell( elem ); 1869 if ( cell ) { 1870 cells.push( cell ); 1871 } 1872 }, this ); 1873 return cells; 1874}; 1875 1876/** 1877 * get cell elements 1878 * @returns {Array} cellElems 1879 */ 1880proto.getCellElements = function() { 1881 return this.cells.map( function( cell ) { 1882 return cell.element; 1883 }); 1884}; 1885 1886/** 1887 * get parent cell from an element 1888 * @param {Element} elem 1889 * @returns {Flickit.Cell} cell 1890 */ 1891proto.getParentCell = function( elem ) { 1892 // first check if elem is cell 1893 var cell = this.getCell( elem ); 1894 if ( cell ) { 1895 return cell; 1896 } 1897 // try to get parent cell elem 1898 elem = utils.getParent( elem, '.flickity-slider > *' ); 1899 return this.getCell( elem ); 1900}; 1901 1902/** 1903 * get cells adjacent to a slide 1904 * @param {Integer} adjCount - number of adjacent slides 1905 * @param {Integer} index - index of slide to start 1906 * @returns {Array} cells - array of Flickity.Cells 1907 */ 1908proto.getAdjacentCellElements = function( adjCount, index ) { 1909 if ( !adjCount ) { 1910 return this.selectedSlide.getCellElements(); 1911 } 1912 index = index === undefined ? this.selectedIndex : index; 1913 1914 var len = this.slides.length; 1915 if ( 1 + ( adjCount * 2 ) >= len ) { 1916 return this.getCellElements(); 1917 } 1918 1919 var cellElems = []; 1920 for ( var i = index - adjCount; i <= index + adjCount ; i++ ) { 1921 var slideIndex = this.options.wrapAround ? utils.modulo( i, len ) : i; 1922 var slide = this.slides[ slideIndex ]; 1923 if ( slide ) { 1924 cellElems = cellElems.concat( slide.getCellElements() ); 1925 } 1926 } 1927 return cellElems; 1928}; 1929 1930/** 1931 * select slide from number or cell element 1932 * @param {Element, Selector String, or Number} selector 1933 */ 1934proto.queryCell = function( selector ) { 1935 if ( typeof selector == 'number' ) { 1936 // use number as index 1937 return this.cells[ selector ]; 1938 } 1939 if ( typeof selector == 'string' ) { 1940 // use string as selector, get element 1941 selector = this.element.querySelector( selector ); 1942 } 1943 // get cell from element 1944 return this.getCell( selector ); 1945}; 1946 1947// -------------------------- events -------------------------- // 1948 1949proto.uiChange = function() { 1950 this.emitEvent('uiChange'); 1951}; 1952 1953proto.childUIPointerDown = function( event ) { 1954 this.emitEvent( 'childUIPointerDown', [ event ] ); 1955}; 1956 1957// ----- resize ----- // 1958 1959proto.onresize = function() { 1960 this.watchCSS(); 1961 this.resize(); 1962}; 1963 1964utils.debounceMethod( Flickity, 'onresize', 150 ); 1965 1966proto.resize = function() { 1967 /* nectar addition to check for this.isAnimating for iOS15 fix */ 1968 1969 if ( !this.isActive || this.isAnimating ) { 1970 return; 1971 } 1972 this.getSize(); 1973 // wrap values 1974 if ( this.options.wrapAround ) { 1975 this.x = utils.modulo( this.x, this.slideableWidth ); 1976 } 1977 this.positionCells(); 1978 this._getWrapShiftCells(); 1979 this.setGallerySize(); 1980 this.emitEvent('resize'); 1981 // update selected index for group slides, instant 1982 // TODO: position can be lost between groups of various numbers 1983 var selectedElement = this.selectedElements && this.selectedElements[0]; 1984 this.selectCell( selectedElement, false, true ); 1985}; 1986 1987// watches the :after property, activates/deactivates 1988proto.watchCSS = function() { 1989 var watchOption = this.options.watchCSS; 1990 if ( !watchOption ) { 1991 return; 1992 } 1993 1994 var afterContent = getComputedStyle( this.element, ':after' ).content; 1995 // activate if :after { content: 'flickity' } 1996 if ( afterContent.indexOf('flickity') != -1 ) { 1997 this.activate(); 1998 } else { 1999 this.deactivate(); 2000 } 2001}; 2002 2003// ----- keydown ----- // 2004 2005// go previous/next if left/right keys pressed 2006proto.onkeydown = function( event ) { 2007 // only work if element is in focus 2008 var isNotFocused = document.activeElement && document.activeElement != this.element; 2009 if ( !this.options.accessibility ||isNotFocused ) { 2010 return; 2011 } 2012 2013 var handler = Flickity.keyboardHandlers[ event.keyCode ]; 2014 if ( handler ) { 2015 handler.call( this ); 2016 } 2017}; 2018 2019Flickity.keyboardHandlers = { 2020 // left arrow 2021 37: function() { 2022 var leftMethod = this.options.rightToLeft ? 'next' : 'previous'; 2023 this.uiChange(); 2024 this[ leftMethod ](); 2025 }, 2026 // right arrow 2027 39: function() { 2028 var rightMethod = this.options.rightToLeft ? 'previous' : 'next'; 2029 this.uiChange(); 2030 this[ rightMethod ](); 2031 }, 2032}; 2033 2034// ----- focus ----- // 2035 2036proto.focus = function() { 2037 // TODO remove scrollTo once focus options gets more support 2038 // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#Browser_compatibility 2039 var prevScrollY = window.pageYOffset; 2040 this.element.focus({ preventScroll: true }); 2041 // hack to fix scroll jump after focus, #76 2042 if ( window.pageYOffset != prevScrollY && prevScrollY > 10 ) { // nectar addition - iframe fix 2043 window.scrollTo( window.pageXOffset, prevScrollY ); 2044 } 2045}; 2046 2047// -------------------------- destroy -------------------------- // 2048 2049// deactivate all Flickity functionality, but keep stuff available 2050proto.deactivate = function() { 2051 if ( !this.isActive ) { 2052 return; 2053 } 2054 this.element.classList.remove('flickity-enabled'); 2055 this.element.classList.remove('flickity-rtl'); 2056 this.unselectSelectedSlide(); 2057 // destroy cells
vendor: 10,270 bytes, lines 2058-2495
2058 this.cells.forEach( function( cell ) { 2059 cell.destroy(); 2060 }); 2061 this.element.removeChild( this.viewport ); 2062 // move child elements back into element 2063 moveElements( this.slider.children, this.element ); 2064 if ( this.options.accessibility ) { 2065 this.element.removeAttribute('tabIndex'); 2066 this.element.removeEventListener( 'keydown', this ); 2067 } 2068 // set flags 2069 this.isActive = false; 2070 this.emitEvent('deactivate'); 2071}; 2072 2073proto.destroy = function() { 2074 this.deactivate(); 2075 window.removeEventListener( 'resize', this ); 2076 this.emitEvent('destroy'); 2077 if ( jQuery && this.$element ) { 2078 jQuery.removeData( this.element, 'flickity' ); 2079 } 2080 delete this.element.flickityGUID; 2081 delete instances[ this.guid ]; 2082}; 2083 2084// -------------------------- prototype -------------------------- // 2085 2086utils.extend( proto, animatePrototype ); 2087 2088// -------------------------- extras -------------------------- // 2089 2090/** 2091 * get Flickity instance from element 2092 * @param {Element} elem 2093 * @returns {Flickity} 2094 */ 2095Flickity.data = function( elem ) { 2096 elem = utils.getQueryElement( elem ); 2097 var id = elem && elem.flickityGUID; 2098 return id && instances[ id ]; 2099}; 2100 2101utils.htmlInit( Flickity, 'flickity' ); 2102 2103if ( jQuery && jQuery.bridget ) { 2104 jQuery.bridget( 'flickity', Flickity ); 2105} 2106 2107// set internal jQuery, for Webpack + jQuery v3, #478 2108Flickity.setJQuery = function( jq ) { 2109 jQuery = jq; 2110}; 2111 2112Flickity.Cell = Cell; 2113Flickity.Slide = Slide; 2114 2115return Flickity; 2116 2117})); 2118 2119/*! 2120 * Unipointer v2.3.0 2121 * base class for doing one thing with pointer event 2122 * MIT license 2123 */ 2124 2125/*jshint browser: true, undef: true, unused: true, strict: true */ 2126 2127( function( window, factory ) { 2128 // universal module definition 2129 /* jshint strict: false */ /*global define, module, require */ 2130 if ( typeof define == 'function' && define.amd ) { 2131 // AMD 2132 define( 'unipointer/unipointer',[ 2133 'ev-emitter/ev-emitter' 2134 ], function( EvEmitter ) { 2135 return factory( window, EvEmitter ); 2136 }); 2137 } else if ( typeof module == 'object' && module.exports ) { 2138 // CommonJS 2139 module.exports = factory( 2140 window, 2141 require('ev-emitter') 2142 ); 2143 } else { 2144 // browser global 2145 window.Unipointer = factory( 2146 window, 2147 window.EvEmitter 2148 ); 2149 } 2150 2151}( window, function factory( window, EvEmitter ) { 2152 2153 2154 2155function noop() {} 2156 2157function Unipointer() {} 2158 2159// inherit EvEmitter 2160var proto = Unipointer.prototype = Object.create( EvEmitter.prototype ); 2161 2162proto.bindStartEvent = function( elem ) { 2163 this._bindStartEvent( elem, true ); 2164}; 2165 2166proto.unbindStartEvent = function( elem ) { 2167 this._bindStartEvent( elem, false ); 2168}; 2169 2170/** 2171 * Add or remove start event 2172 * @param {Boolean} isAdd - remove if falsey 2173 */ 2174proto._bindStartEvent = function( elem, isAdd ) { 2175 // munge isAdd, default to true 2176 isAdd = isAdd === undefined ? true : isAdd; 2177 var bindMethod = isAdd ? 'addEventListener' : 'removeEventListener'; 2178 2179 // default to mouse events 2180 var startEvent = 'mousedown'; 2181 if ( window.PointerEvent ) { 2182 // Pointer Events 2183 startEvent = 'pointerdown'; 2184 } else if ( 'ontouchstart' in window ) { 2185 // Touch Events. iOS Safari 2186 startEvent = 'touchstart'; 2187 } 2188 elem[ bindMethod ]( startEvent, this ); 2189}; 2190 2191// trigger handler methods for events 2192proto.handleEvent = function( event ) { 2193 var method = 'on' + event.type; 2194 if ( this[ method ] ) { 2195 this[ method ]( event ); 2196 } 2197}; 2198 2199// returns the touch that we're keeping track of 2200proto.getTouch = function( touches ) { 2201 for ( var i=0; i < touches.length; i++ ) { 2202 var touch = touches[i]; 2203 if ( touch.identifier == this.pointerIdentifier ) { 2204 return touch; 2205 } 2206 } 2207}; 2208 2209// ----- start event ----- // 2210 2211proto.onmousedown = function( event ) { 2212 // dismiss clicks from right or middle buttons 2213 var button = event.button; 2214 if ( button && ( button !== 0 && button !== 1 ) ) { 2215 return; 2216 } 2217 this._pointerDown( event, event ); 2218}; 2219 2220proto.ontouchstart = function( event ) { 2221 this._pointerDown( event, event.changedTouches[0] ); 2222}; 2223 2224proto.onpointerdown = function( event ) { 2225 this._pointerDown( event, event ); 2226}; 2227 2228/** 2229 * pointer start 2230 * @param {Event} event 2231 * @param {Event or Touch} pointer 2232 */ 2233proto._pointerDown = function( event, pointer ) { 2234 // dismiss right click and other pointers 2235 // button = 0 is okay, 1-4 not 2236 if ( event.button || this.isPointerDown ) { 2237 return; 2238 } 2239 2240 this.isPointerDown = true; 2241 // save pointer identifier to match up touch events 2242 this.pointerIdentifier = pointer.pointerId !== undefined ? 2243 // pointerId for pointer events, touch.indentifier for touch events 2244 pointer.pointerId : pointer.identifier; 2245 2246 this.pointerDown( event, pointer ); 2247}; 2248 2249proto.pointerDown = function( event, pointer ) { 2250 this._bindPostStartEvents( event ); 2251 this.emitEvent( 'pointerDown', [ event, pointer ] ); 2252}; 2253 2254// hash of events to be bound after start event 2255var postStartEvents = { 2256 mousedown: [ 'mousemove', 'mouseup' ], 2257 touchstart: [ 'touchmove', 'touchend', 'touchcancel' ], 2258 pointerdown: [ 'pointermove', 'pointerup', 'pointercancel' ], 2259}; 2260 2261proto._bindPostStartEvents = function( event ) { 2262 if ( !event ) { 2263 return; 2264 } 2265 // get proper events to match start event 2266 var events = postStartEvents[ event.type ]; 2267 // bind events to node 2268 events.forEach( function( eventName ) { 2269 window.addEventListener( eventName, this ); 2270 }, this ); 2271 // save these arguments 2272 this._boundPointerEvents = events; 2273}; 2274 2275proto._unbindPostStartEvents = function() { 2276 // check for _boundEvents, in case dragEnd triggered twice (old IE8 bug) 2277 if ( !this._boundPointerEvents ) { 2278 return; 2279 } 2280 this._boundPointerEvents.forEach( function( eventName ) { 2281 window.removeEventListener( eventName, this ); 2282 }, this ); 2283 2284 delete this._boundPointerEvents; 2285}; 2286 2287// ----- move event ----- // 2288 2289proto.onmousemove = function( event ) { 2290 this._pointerMove( event, event ); 2291}; 2292 2293proto.onpointermove = function( event ) { 2294 if ( event.pointerId == this.pointerIdentifier ) { 2295 this._pointerMove( event, event ); 2296 } 2297}; 2298 2299proto.ontouchmove = function( event ) { 2300 var touch = this.getTouch( event.changedTouches ); 2301 if ( touch ) { 2302 this._pointerMove( event, touch ); 2303 } 2304}; 2305 2306/** 2307 * pointer move 2308 * @param {Event} event 2309 * @param {Event or Touch} pointer 2310 * @private 2311 */ 2312proto._pointerMove = function( event, pointer ) { 2313 this.pointerMove( event, pointer ); 2314}; 2315 2316// public 2317proto.pointerMove = function( event, pointer ) { 2318 this.emitEvent( 'pointerMove', [ event, pointer ] ); 2319}; 2320 2321// ----- end event ----- // 2322 2323 2324proto.onmouseup = function( event ) { 2325 this._pointerUp( event, event ); 2326}; 2327 2328proto.onpointerup = function( event ) { 2329 if ( event.pointerId == this.pointerIdentifier ) { 2330 this._pointerUp( event, event ); 2331 } 2332}; 2333 2334proto.ontouchend = function( event ) { 2335 var touch = this.getTouch( event.changedTouches ); 2336 if ( touch ) { 2337 this._pointerUp( event, touch ); 2338 } 2339}; 2340 2341/** 2342 * pointer up 2343 * @param {Event} event 2344 * @param {Event or Touch} pointer 2345 * @private 2346 */ 2347proto._pointerUp = function( event, pointer ) { 2348 this._pointerDone(); 2349 this.pointerUp( event, pointer ); 2350}; 2351 2352// public 2353proto.pointerUp = function( event, pointer ) { 2354 this.emitEvent( 'pointerUp', [ event, pointer ] ); 2355}; 2356 2357// ----- pointer done ----- // 2358 2359// triggered on pointer up & pointer cancel 2360proto._pointerDone = function() { 2361 this._pointerReset(); 2362 this._unbindPostStartEvents(); 2363 this.pointerDone(); 2364}; 2365 2366proto._pointerReset = function() { 2367 // reset properties 2368 this.isPointerDown = false; 2369 delete this.pointerIdentifier; 2370}; 2371 2372proto.pointerDone = noop; 2373 2374// ----- pointer cancel ----- // 2375 2376proto.onpointercancel = function( event ) { 2377 if ( event.pointerId == this.pointerIdentifier ) { 2378 this._pointerCancel( event, event ); 2379 } 2380}; 2381 2382proto.ontouchcancel = function( event ) { 2383 var touch = this.getTouch( event.changedTouches ); 2384 if ( touch ) { 2385 this._pointerCancel( event, touch ); 2386 } 2387}; 2388 2389/** 2390 * pointer cancel 2391 * @param {Event} event 2392 * @param {Event or Touch} pointer 2393 * @private 2394 */ 2395proto._pointerCancel = function( event, pointer ) { 2396 this._pointerDone(); 2397 this.pointerCancel( event, pointer ); 2398}; 2399 2400// public 2401proto.pointerCancel = function( event, pointer ) { 2402 this.emitEvent( 'pointerCancel', [ event, pointer ] ); 2403}; 2404 2405// ----- ----- // 2406 2407// utility function for getting x/y coords from event 2408Unipointer.getPointerPoint = function( pointer ) { 2409 return { 2410 x: pointer.pageX, 2411 y: pointer.pageY 2412 }; 2413}; 2414 2415// ----- ----- // 2416 2417return Unipointer; 2418 2419})); 2420 2421/*! 2422 * Unidragger v2.3.0 2423 * Draggable base class 2424 * MIT license 2425 */ 2426 2427/*jshint browser: true, unused: true, undef: true, strict: true */ 2428 2429( function( window, factory ) { 2430 // universal module definition 2431 /*jshint strict: false */ /*globals define, module, require */ 2432 2433 if ( typeof define == 'function' && define.amd ) { 2434 // AMD 2435 define( 'unidragger/unidragger',[ 2436 'unipointer/unipointer' 2437 ], function( Unipointer ) { 2438 return factory( window, Unipointer ); 2439 }); 2440 } else if ( typeof module == 'object' && module.exports ) { 2441 // CommonJS 2442 module.exports = factory( 2443 window, 2444 require('unipointer') 2445 ); 2446 } else { 2447 // browser global 2448 window.Unidragger = factory( 2449 window, 2450 window.Unipointer 2451 ); 2452 } 2453 2454}( window, function factory( window, Unipointer ) { 2455 2456 2457 2458// -------------------------- Unidragger -------------------------- // 2459 2460function Unidragger() {} 2461 2462// inherit Unipointer & EvEmitter 2463var proto = Unidragger.prototype = Object.create( Unipointer.prototype ); 2464 2465// ----- bind start ----- // 2466 2467proto.bindHandles = function() { 2468 this._bindHandles( true ); 2469}; 2470 2471proto.unbindHandles = function() { 2472 this._bindHandles( false ); 2473}; 2474 2475/** 2476 * Add or remove start event 2477 * @param {Boolean} isAdd 2478 */ 2479proto._bindHandles = function( isAdd ) { 2480 // munge isAdd, default to true 2481 isAdd = isAdd === undefined ? true : isAdd; 2482 // bind each handle 2483 var bindMethod = isAdd ? 'addEventListener' : 'removeEventListener'; 2484 var touchAction = isAdd ? this._touchActionValue : ''; 2485 for ( var i=0; i < this.handles.length; i++ ) { 2486 var handle = this.handles[i]; 2487 this._bindStartEvent( handle, isAdd ); 2488 handle[ bindMethod ]( 'click', this ); 2489 // touch-action: none to override browser touch gestures. metafizzy/flickity#540 2490 if ( window.PointerEvent ) { 2491 handle.style.touchAction = touchAction; 2492 } 2493 } 2494}; 2495
vendor: 3,343 bytes, lines 2496-2627
2496// prototype so it can be overwriteable by Flickity 2497proto._touchActionValue = 'none'; 2498 2499// ----- start event ----- // 2500 2501/** 2502 * pointer start 2503 * @param {Event} event 2504 * @param {Event or Touch} pointer 2505 */ 2506proto.pointerDown = function( event, pointer ) { 2507 var isOkay = this.okayPointerDown( event ); 2508 if ( !isOkay ) { 2509 return; 2510 } 2511 // track start event position 2512 // Safari 9 overrides pageX and pageY. These values needs to be copied. flickity#842 2513 this.pointerDownPointer = { 2514 pageX: pointer.pageX, 2515 pageY: pointer.pageY, 2516 }; 2517 2518 event.preventDefault(); 2519 this.pointerDownBlur(); 2520 // bind move and end events 2521 this._bindPostStartEvents( event ); 2522 this.emitEvent( 'pointerDown', [ event, pointer ] ); 2523}; 2524 2525// nodes that have text fields 2526var cursorNodes = { 2527 TEXTAREA: true, 2528 INPUT: true, 2529 SELECT: true, 2530 OPTION: true, 2531}; 2532 2533// input types that do not have text fields 2534var clickTypes = { 2535 radio: true, 2536 checkbox: true, 2537 button: true, 2538 submit: true, 2539 image: true, 2540 file: true, 2541}; 2542 2543// dismiss inputs with text fields. flickity#403, flickity#404 2544proto.okayPointerDown = function( event ) { 2545 var isCursorNode = cursorNodes[ event.target.nodeName ]; 2546 var isClickType = clickTypes[ event.target.type ]; 2547 var isOkay = !isCursorNode || isClickType; 2548 if ( !isOkay ) { 2549 this._pointerReset(); 2550 } 2551 return isOkay; 2552}; 2553 2554// kludge to blur previously focused input 2555proto.pointerDownBlur = function() { 2556 var focused = document.activeElement; 2557 // do not blur body for IE10, metafizzy/flickity#117 2558 var canBlur = focused && focused.blur && focused != document.body; 2559 if ( canBlur ) { 2560 focused.blur(); 2561 } 2562}; 2563 2564// ----- move event ----- // 2565 2566/** 2567 * drag move 2568 * @param {Event} event 2569 * @param {Event or Touch} pointer 2570 */ 2571proto.pointerMove = function( event, pointer ) { 2572 var moveVector = this._dragPointerMove( event, pointer ); 2573 this.emitEvent( 'pointerMove', [ event, pointer, moveVector ] ); 2574 this._dragMove( event, pointer, moveVector ); 2575}; 2576 2577// base pointer move logic 2578proto._dragPointerMove = function( event, pointer ) { 2579 var moveVector = { 2580 x: pointer.pageX - this.pointerDownPointer.pageX, 2581 y: pointer.pageY - this.pointerDownPointer.pageY 2582 }; 2583 // start drag if pointer has moved far enough to start drag 2584 if ( !this.isDragging && this.hasDragStarted( moveVector ) ) { 2585 this._dragStart( event, pointer ); 2586 } 2587 return moveVector; 2588}; 2589 2590// condition if pointer has moved far enough to start drag 2591proto.hasDragStarted = function( moveVector ) { 2592 return Math.abs( moveVector.x ) > 3 || Math.abs( moveVector.y ) > 3; 2593}; 2594 2595// ----- end event ----- // 2596 2597/** 2598 * pointer up 2599 * @param {Event} event 2600 * @param {Event or Touch} pointer 2601 */ 2602proto.pointerUp = function( event, pointer ) { 2603 this.emitEvent( 'pointerUp', [ event, pointer ] ); 2604 this._dragPointerUp( event, pointer ); 2605}; 2606 2607proto._dragPointerUp = function( event, pointer ) { 2608 if ( this.isDragging ) { 2609 this._dragEnd( event, pointer ); 2610 } else { 2611 // pointer didn't move enough for drag to start 2612 this._staticClick( event, pointer ); 2613 } 2614}; 2615 2616// -------------------------- drag -------------------------- // 2617 2618// dragStart 2619proto._dragStart = function( event, pointer ) { 2620 this.isDragging = true; 2621 /* nectar addition iOS15 fix */ 2622 document.ontouchmove = function() { 2623 return false; 2624 }; 2625 /* nectar addition iOS15 fix end */ 2626 2627 // prevent clicks
2628 this.isPreventingClicks = true; 2629 this.dragStart( event, pointer ); 2630}; 2631 2632proto.dragStart = function( event, pointer ) { 2633 this.emitEvent( 'dragStart', [ event, pointer ] ); 2634}; 2635 2636// dragMove 2637proto._dragMove = function( event, pointer, moveVector ) { 2638 // do not drag if not dragging yet 2639 if ( !this.isDragging ) { 2640 return; 2641 } 2642 2643 this.dragMove( event, pointer, moveVector ); 2644}; 2645 2646proto.dragMove = function( event, pointer, moveVector ) { 2647 event.preventDefault(); 2648 this.emitEvent( 'dragMove', [ event, pointer, moveVector ] ); 2649}; 2650 2651// dragEnd 2652proto._dragEnd = function( event, pointer ) { 2653 // set flags 2654 this.isDragging = false; 2655 2656 /* nectar addition iOS15 fix */ 2657 document.ontouchmove = function() { 2658 return true; 2659 }; 2660 /* nectar addition iOS15 fix end */ 2661 2662 // re-enable clicking async 2663 setTimeout( function() { 2664 delete this.isPreventingClicks; 2665 }.bind( this ) ); 2666 2667 this.dragEnd( event, pointer ); 2668}; 2669 2670proto.dragEnd = function( event, pointer ) { 2671 this.emitEvent( 'dragEnd', [ event, pointer ] ); 2672}; 2673 2674// ----- onclick ----- // 2675 2676// handle all clicks and prevent clicks when dragging 2677proto.onclick = function( event ) {
vendor: 9,088 bytes, lines 2678-3006
2678 if ( this.isPreventingClicks ) { 2679 event.preventDefault(); 2680 } 2681}; 2682 2683// ----- staticClick ----- // 2684 2685// triggered after pointer down & up with no/tiny movement 2686proto._staticClick = function( event, pointer ) { 2687 // ignore emulated mouse up clicks 2688 if ( this.isIgnoringMouseUp && event.type == 'mouseup' ) { 2689 return; 2690 } 2691 2692 this.staticClick( event, pointer ); 2693 2694 // set flag for emulated clicks 300ms after touchend 2695 if ( event.type != 'mouseup' ) { 2696 this.isIgnoringMouseUp = true; 2697 // reset flag after 300ms 2698 setTimeout( function() { 2699 delete this.isIgnoringMouseUp; 2700 }.bind( this ), 400 ); 2701 } 2702}; 2703 2704proto.staticClick = function( event, pointer ) { 2705 this.emitEvent( 'staticClick', [ event, pointer ] ); 2706}; 2707 2708// ----- utils ----- // 2709 2710Unidragger.getPointerPoint = Unipointer.getPointerPoint; 2711 2712// ----- ----- // 2713 2714return Unidragger; 2715 2716})); 2717 2718// drag 2719( function( window, factory ) { 2720 // universal module definition 2721 /* jshint strict: false */ 2722 if ( typeof define == 'function' && define.amd ) { 2723 // AMD 2724 define( 'flickity/js/drag',[ 2725 './flickity', 2726 'unidragger/unidragger', 2727 'fizzy-ui-utils/utils' 2728 ], function( Flickity, Unidragger, utils ) { 2729 return factory( window, Flickity, Unidragger, utils ); 2730 }); 2731 } else if ( typeof module == 'object' && module.exports ) { 2732 // CommonJS 2733 module.exports = factory( 2734 window, 2735 require('./flickity'), 2736 require('unidragger'), 2737 require('fizzy-ui-utils') 2738 ); 2739 } else { 2740 // browser global 2741 window.Flickity = factory( 2742 window, 2743 window.Flickity, 2744 window.Unidragger, 2745 window.fizzyUIUtils 2746 ); 2747 } 2748 2749}( window, function factory( window, Flickity, Unidragger, utils ) { 2750 2751 2752 2753// ----- defaults ----- // 2754 2755utils.extend( Flickity.defaults, { 2756 draggable: '>1', 2757 dragThreshold: 3, 2758}); 2759 2760// ----- create ----- // 2761 2762Flickity.createMethods.push('_createDrag'); 2763 2764// -------------------------- drag prototype -------------------------- // 2765 2766var proto = Flickity.prototype; 2767utils.extend( proto, Unidragger.prototype ); 2768proto._touchActionValue = 'pan-y'; 2769 2770// -------------------------- -------------------------- // 2771 2772var isTouch = 'createTouch' in document; 2773var isTouchmoveScrollCanceled = false; 2774 2775proto._createDrag = function() { 2776 this.on( 'activate', this.onActivateDrag ); 2777 this.on( 'uiChange', this._uiChangeDrag ); 2778 this.on( 'childUIPointerDown', this._childUIPointerDownDrag ); 2779 this.on( 'deactivate', this.onDeactivateDrag ); 2780 this.on( 'cellChange', this.updateDraggable ); 2781 // TODO updateDraggable on resize? if groupCells & slides change 2782 // HACK - add seemingly innocuous handler to fix iOS 10 scroll behavior 2783 // #457, RubaXa/Sortable#973 2784 if ( isTouch && !isTouchmoveScrollCanceled ) { 2785 window.addEventListener( 'touchmove', function() {}); 2786 isTouchmoveScrollCanceled = true; 2787 } 2788}; 2789 2790proto.onActivateDrag = function() { 2791 this.handles = [ this.viewport ]; 2792 this.bindHandles(); 2793 this.updateDraggable(); 2794}; 2795 2796proto.onDeactivateDrag = function() { 2797 this.unbindHandles(); 2798 this.element.classList.remove('is-draggable'); 2799}; 2800 2801proto.updateDraggable = function() { 2802 // disable dragging if less than 2 slides. #278 2803 if ( this.options.draggable == '>1' ) { 2804 this.isDraggable = this.slides.length > 1; 2805 } else { 2806 this.isDraggable = this.options.draggable; 2807 } 2808 if ( this.isDraggable ) { 2809 this.element.classList.add('is-draggable'); 2810 } else { 2811 this.element.classList.remove('is-draggable'); 2812 } 2813}; 2814 2815// backwards compatibility 2816proto.bindDrag = function() { 2817 this.options.draggable = true; 2818 this.updateDraggable(); 2819}; 2820 2821proto.unbindDrag = function() { 2822 this.options.draggable = false; 2823 this.updateDraggable(); 2824}; 2825 2826proto._uiChangeDrag = function() { 2827 delete this.isFreeScrolling; 2828}; 2829 2830proto._childUIPointerDownDrag = function( event ) { 2831 // allow focus & preventDefault even when not draggable 2832 // so child UI elements keep focus on carousel. #721 2833 event.preventDefault(); 2834 this.pointerDownFocus( event ); 2835}; 2836 2837// -------------------------- pointer events -------------------------- // 2838 2839proto.pointerDown = function( event, pointer ) { 2840 if ( !this.isDraggable ) { 2841 this._pointerDownDefault( event, pointer ); 2842 return; 2843 } 2844 var isOkay = this.okayPointerDown( event ); 2845 if ( !isOkay ) { 2846 return; 2847 } 2848 2849 this._pointerDownPreventDefault( event ); 2850 this.pointerDownFocus( event ); 2851 // blur 2852 if ( document.activeElement != this.element ) { 2853 // do not blur if already focused 2854 this.pointerDownBlur(); 2855 } 2856 2857 // stop if it was moving 2858 this.dragX = this.x; 2859 this.viewport.classList.add('is-pointer-down'); 2860 // track scrolling 2861 this.pointerDownScroll = getScrollPosition(); 2862 window.addEventListener( 'scroll', this ); 2863 2864 this._pointerDownDefault( event, pointer ); 2865}; 2866 2867// default pointerDown logic, used for staticClick 2868proto._pointerDownDefault = function( event, pointer ) { 2869 // track start event position 2870 // Safari 9 overrides pageX and pageY. These values needs to be copied. #779 2871 this.pointerDownPointer = { 2872 pageX: pointer.pageX, 2873 pageY: pointer.pageY, 2874 }; 2875 // bind move and end events 2876 this._bindPostStartEvents( event ); 2877 this.dispatchEvent( 'pointerDown', event, [ pointer ] ); 2878}; 2879 2880var focusNodes = { 2881 INPUT: true, 2882 TEXTAREA: true, 2883 SELECT: true, 2884}; 2885 2886proto.pointerDownFocus = function( event ) { 2887 var isFocusNode = focusNodes[ event.target.nodeName ]; 2888 if ( !isFocusNode ) { 2889 this.focus(); 2890 } 2891}; 2892 2893proto._pointerDownPreventDefault = function( event ) { 2894 var isTouchStart = event.type == 'touchstart'; 2895 var isTouchPointer = event.pointerType == 'touch'; 2896 var isFocusNode = focusNodes[ event.target.nodeName ]; 2897 if ( !isTouchStart && !isTouchPointer && !isFocusNode ) { 2898 event.preventDefault(); 2899 } 2900}; 2901 2902// ----- move ----- // 2903 2904proto.hasDragStarted = function( moveVector ) { 2905 return Math.abs( moveVector.x ) > this.options.dragThreshold; 2906}; 2907 2908// ----- up ----- // 2909 2910proto.pointerUp = function( event, pointer ) { 2911 delete this.isTouchScrolling; 2912 this.viewport.classList.remove('is-pointer-down'); 2913 this.dispatchEvent( 'pointerUp', event, [ pointer ] ); 2914 this._dragPointerUp( event, pointer ); 2915}; 2916 2917proto.pointerDone = function() { 2918 window.removeEventListener( 'scroll', this ); 2919 delete this.pointerDownScroll; 2920}; 2921 2922// -------------------------- dragging -------------------------- // 2923 2924proto.dragStart = function( event, pointer ) { 2925 if ( !this.isDraggable ) { 2926 return; 2927 } 2928 this.dragStartPosition = this.x; 2929 this.startAnimation(); 2930 window.removeEventListener( 'scroll', this ); 2931 this.dispatchEvent( 'dragStart', event, [ pointer ] ); 2932}; 2933 2934proto.pointerMove = function( event, pointer ) { 2935 var moveVector = this._dragPointerMove( event, pointer ); 2936 this.dispatchEvent( 'pointerMove', event, [ pointer, moveVector ] ); 2937 this._dragMove( event, pointer, moveVector ); 2938}; 2939 2940proto.dragMove = function( event, pointer, moveVector ) { 2941 if ( !this.isDraggable ) { 2942 return; 2943 } 2944 event.preventDefault(); 2945 2946 // reverse if right-to-left 2947 var direction = this.options.rightToLeft ? -1 : 1; 2948 if ( this.options.wrapAround ) { 2949 // wrap around move. #589 2950 moveVector.x = moveVector.x % this.slideableWidth; 2951 } 2952 var dragX = this.dragStartPosition + moveVector.x * direction; 2953 2954 if ( !this.options.wrapAround && this.slides.length ) { 2955 // slow drag 2956 var originBound = Math.max( -this.slides[0].target, this.dragStartPosition ); 2957 dragX = dragX > originBound ? ( dragX + originBound ) * 0.5 : dragX; 2958 var endBound = Math.min( -this.getLastSlide().target, this.dragStartPosition ); 2959 dragX = dragX < endBound ? ( dragX + endBound ) * 0.5 : dragX; 2960 } 2961 2962 // nectar addition ios13 bugfix 2963 if ( this.dragX !== dragX ) { 2964 this.previousDragX = this.dragX; 2965 } 2966 2967 this.dragX = dragX; 2968 2969 this.dragMoveTime = new Date(); 2970 this.dispatchEvent( 'dragMove', event, [ pointer, moveVector ] ); 2971}; 2972 2973proto.dragEnd = function( event, pointer ) { 2974 if ( !this.isDraggable ) { 2975 return; 2976 } 2977 if ( this.options.freeScroll ) { 2978 this.isFreeScrolling = true; 2979 } 2980 // set selectedIndex based on where flick will end up 2981 var index = this.dragEndRestingSelect(); 2982 2983 if ( this.options.freeScroll && !this.options.wrapAround ) { 2984 // if free-scroll & not wrap around 2985 // do not free-scroll if going outside of bounding slides 2986 // so bounding slides can attract slider, and keep it in bounds 2987 var restingX = this.getRestingPosition(); 2988 this.isFreeScrolling = -restingX > this.slides[0].target && 2989 -restingX < this.getLastSlide().target; 2990 } else if ( !this.options.freeScroll && index == this.selectedIndex ) { 2991 // boost selection if selected index has not changed 2992 index += this.dragEndBoostSelect(); 2993 } 2994 delete this.previousDragX; 2995 // apply selection 2996 // TODO refactor this, selecting here feels weird 2997 // HACK, set flag so dragging stays in correct direction 2998 this.isDragSelect = this.options.wrapAround; 2999 this.select( index ); 3000 delete this.isDragSelect; 3001 this.dispatchEvent( 'dragEnd', event, [ pointer ] ); 3002}; 3003 3004proto.dragEndRestingSelect = function() { 3005 var restingX = this.getRestingPosition(); 3006 // how far away from selected slide
3007 var distance = Math.abs( this.getSlideDistance( -restingX, this.selectedIndex ) ); 3008 // get closet resting going up and going down 3009 var positiveResting = this._getClosestResting( restingX, distance, 1 ); 3010 var negativeResting = this._getClosestResting( restingX, distance, -1 ); 3011 // use closer resting for wrap-around 3012 var index = positiveResting.distance < negativeResting.distance ? 3013 positiveResting.index : negativeResting.index; 3014 return index; 3015}; 3016 3017/** 3018 * given resting X and distance to selected cell 3019 * get the distance and index of the closest cell 3020 * @param {Number} restingX - estimated post-flick resting position 3021 * @param {Number} distance - distance to selected cell 3022 * @param {Integer} increment - +1 or -1, going up or down 3023 * @returns {Object} - { distance: {Number}, index: {Integer} } 3024 */ 3025proto._getClosestResting = function( restingX, distance, increment ) { 3026 var index = this.selectedIndex; 3027 var minDistance = Infinity; 3028 var condition = this.options.contain && !this.options.wrapAround ? 3029 // if contain, keep going if distance is equal to minDistance 3030 function( d, md ) { return d <= md; } : function( d, md ) { return d < md; }; 3031 while ( condition( distance, minDistance ) ) { 3032 // measure distance to next cell 3033 index += increment; 3034 minDistance = distance; 3035 distance = this.getSlideDistance( -restingX, index ); 3036 if ( distance === null ) { 3037 break; 3038 } 3039 distance = Math.abs( distance ); 3040 } 3041 return { 3042 distance: minDistance, 3043 // selected was previous index 3044 index: index - increment 3045 }; 3046}; 3047 3048/** 3049 * measure distance between x and a slide target 3050 * @param {Number} x 3051 * @param {Integer} index - slide index 3052 */ 3053proto.getSlideDistance = function( x, index ) { 3054 var len = this.slides.length; 3055 // wrap around if at least 2 slides 3056 var isWrapAround = this.options.wrapAround && len > 1; 3057 var slideIndex = isWrapAround ? utils.modulo( index, len ) : index; 3058 var slide = this.slides[ slideIndex ]; 3059 if ( !slide ) { 3060 return null; 3061 } 3062 // add distance for wrap-around slides 3063 var wrap = isWrapAround ? this.slideableWidth * Math.floor( index / len ) : 0; 3064 return x - ( slide.target + wrap ); 3065}; 3066 3067proto.dragEndBoostSelect = function() { 3068 // do not boost if no previousDragX or dragMoveTime 3069 if ( this.previousDragX === undefined || !this.dragMoveTime || 3070 // or if drag was held for 100 ms 3071 new Date() - this.dragMoveTime > 100 ) { 3072 return 0; 3073 } 3074 3075 var distance = this.getSlideDistance( -this.dragX, this.selectedIndex ); 3076 var delta = this.previousDragX - this.dragX; 3077 if ( distance > 0 && delta > 0 ) { 3078 // boost to next if moving towards the right, and positive velocity 3079 return 1; 3080 } else if ( distance < 0 && delta < 0 ) { 3081 // boost to previous if moving towards the left, and negative velocity 3082 return -1; 3083 } 3084 return 0; 3085}; 3086 3087// ----- staticClick ----- // 3088 3089proto.staticClick = function( event, pointer ) { 3090 // get clickedCell, if cell was clicked 3091 var clickedCell = this.getParentCell( event.target ); 3092 var cellElem = clickedCell && clickedCell.element; 3093 var cellIndex = clickedCell && this.cells.indexOf( clickedCell ); 3094 this.dispatchEvent( 'staticClick', event, [ pointer, cellElem, cellIndex ] ); 3095}; 3096 3097// ----- scroll ----- // 3098 3099proto.onscroll = function() { 3100 var scroll = getScrollPosition(); 3101 var scrollMoveX = this.pointerDownScroll.x - scroll.x; 3102 var scrollMoveY = this.pointerDownScroll.y - scroll.y; 3103 // cancel click/tap if scroll is too much 3104 if ( Math.abs( scrollMoveX ) > 3 || Math.abs( scrollMoveY ) > 3 ) { 3105 this._pointerDone(); 3106 } 3107}; 3108 3109// ----- utils ----- // 3110 3111function getScrollPosition() { 3112 return { 3113 x: window.pageXOffset, 3114 y: window.pageYOffset 3115 }; 3116} 3117 3118// ----- ----- // 3119 3120return Flickity; 3121 3122})); 3123 3124/*! 3125 * Tap listener v2.0.0 3126 * listens to taps 3127 * MIT license 3128 */ 3129 3130/*jshint browser: true, unused: true, undef: true, strict: true */ 3131 3132( function( window, factory ) { 3133 // universal module definition 3134 /*jshint strict: false*/ /*globals define, module, require */ 3135 3136 if ( typeof define == 'function' && define.amd ) { 3137 // AMD 3138 define( 'tap-listener/tap-listener',[
3139 'unipointer/unipointer' 3140 ], function( Unipointer ) { 3141 return factory( window, Unipointer ); 3142 }); 3143 } else if ( typeof module == 'object' && module.exports ) { 3144 // CommonJS 3145 module.exports = factory( 3146 window, 3147 require('unipointer') 3148 ); 3149 } else { 3150 // browser global 3151 window.TapListener = factory( 3152 window, 3153 window.Unipointer 3154 ); 3155 } 3156 3157}( window, function factory( window, Unipointer ) { 3158 3159 3160 3161// -------------------------- TapListener -------------------------- // 3162 3163function TapListener( elem ) { 3164 this.bindTap( elem ); 3165} 3166 3167// inherit Unipointer & EventEmitter 3168var proto = TapListener.prototype = Object.create( Unipointer.prototype ); 3169 3170/** 3171 * bind tap event to element 3172 * @param {Element} elem 3173 */ 3174proto.bindTap = function( elem ) { 3175 if ( !elem ) { 3176 return; 3177 } 3178 this.unbindTap(); 3179 this.tapElement = elem; 3180 this._bindStartEvent( elem, true ); 3181}; 3182 3183proto.unbindTap = function() { 3184 if ( !this.tapElement ) { 3185 return; 3186 } 3187 this._bindStartEvent( this.tapElement, true ); 3188 delete this.tapElement; 3189}; 3190 3191/** 3192 * pointer up 3193 * @param {Event} event 3194 * @param {Event or Touch} pointer 3195 */ 3196proto.pointerUp = function( event, pointer ) { 3197 // ignore emulated mouse up clicks 3198 if ( this.isIgnoringMouseUp && event.type == 'mouseup' ) { 3199 return; 3200 } 3201 3202 var pointerPoint = Unipointer.getPointerPoint( pointer ); 3203 var boundingRect = this.tapElement.getBoundingClientRect(); 3204 var scrollX = window.pageXOffset; 3205 var scrollY = window.pageYOffset; 3206 // calculate if pointer is inside tapElement 3207 var isInside = pointerPoint.x >
3207= boundingRect.left + scrollX && 3208 pointerPoint.x <= boundingRect.right + scrollX && 3209 pointerPoint.y >= boundingRect.top + scrollY && 3210 pointerPoint.y <= boundingRect.bottom + scrollY; 3211 // trigger callback if pointer is inside element 3212 if ( isInside ) { 3213 this.emitEvent( 'tap', [ event, pointer ] ); 3214 } 3215 3216 // set flag for emulated clicks 300ms after touchend 3217 if ( event.type != 'mouseup' ) { 3218 this.isIgnoringMouseUp = true; 3219 // reset flag after 300ms 3220 var _this = this; 3221 setTimeout( function() { 3222 delete _this.isIgnoringMouseUp; 3223 }, 400 ); 3224 } 3225}; 3226 3227proto.destroy = function() { 3228 this.pointerDone(); 3229 this.unbindTap(); 3230}; 3231 3232// ----- ----- // 3233 3234return TapListener; 3235 3236})); 3237 3238// prev/next buttons 3239( function( window, factory ) { 3240 // universal module definition 3241 /* jshint strict: false */ 3242 if ( typeof define == 'function' && define.amd ) { 3243 // AMD 3244 define( 'flickity/js/prev-next-button',[ 3245 './flickity', 3246 'tap-listener/tap-listener', 3247 'fizzy-ui-utils/utils' 3248 ], function( Flickity, TapListener, utils ) { 3249 return factory( window, Flickity, TapListener, utils ); 3250 }); 3251 } else if ( typeof module == 'object' && module.exports ) { 3252 // CommonJS 3253 module.exports = factory( 3254 window, 3255 require('./flickity'), 3256 require('tap-listener'), 3257 require('fizzy-ui-utils') 3258 ); 3259 } else { 3260 // browser global 3261 factory( 3262 window, 3263 window.Flickity, 3264 window.TapListener, 3265 window.fizzyUIUtils 3266 ); 3267 } 3268 3269}( window, function factory( window, Flickity, TapListener, utils ) { 3270'use strict'; 3271 3272var svgURI = 'http://www.w3.org/2000/svg'; 3273 3274// -------------------------- PrevNextButton -------------------------- // 3275 3276function PrevNextButton( direction, parent ) { 3277 this.direction = direction; 3278 this.parent = parent; 3279 this._create(); 3280} 3281 3282PrevNextButton.prototype = Object.create( TapListener.prototype ); 3283 3284PrevNextButton.prototype._create = function() { 3285 // properties 3286 this.isEnabled = true; 3287 this.isPrevious = this.direction == -1; 3288 var leftDirection = this.parent.options.rightToLeft ? 1 : -1; 3289 this.isLeft = this.direction == leftDirection; 3290 3291 var element = this.element = document.createElement('button'); 3292 element.className = 'flickity-button flickity-prev-next-button'; 3293 element.className += this.isPrevious ? ' previous' : ' next'; 3294 // prevent button from submitting form http://stackoverflow.com/a/10836076/182183 3295 element.setAttribute( 'type', 'button' ); 3296 // init as disabled 3297 this.disable(); 3298 3299 element.setAttribute( 'aria-label', this.isPrevious ? 'Previous' : 'Next' ); 3300 3301 // create arrow 3302 var svg = this.createSVG(); 3303 element.appendChild( svg ); 3304 // events 3305 this.on( 'tap', this.onTap ); 3306 this.parent.on( 'select', this.update.bind( this ) ); 3307 this.on( 'pointerDown', this.parent.childUIPointerDown.bind( this.parent ) ); 3308}; 3309 3310PrevNextButton.prototype.activate = function() { 3311 this.bindTap( this.element ); 3312 // click events from keyboard 3313 this.element.addEventListener( 'click', this ); 3314 // add to DOM 3315 this.parent.element.appendChild( this.element ); 3316}; 3317 3318PrevNextButton.prototype.deactivate = function() { 3319 // remove from DOM 3320 this.parent.element.removeChild( this.element ); 3321 // do regular TapListener destroy 3322 TapListener.prototype.destroy.call( this ); 3323 // click events from keyboard 3324 this.element.removeEventListener( 'click', this ); 3325}; 3326 3327PrevNextButton.prototype.createSVG = function() { 3328 var svg = document.createElementNS( svgURI, 'svg'); 3329 svg.setAttribute( 'class', 'flickity-button-icon' ); 3330 svg.setAttribute( 'viewBox', '0 0 100 100' ); 3331 var path = document.createElementNS( svgURI, 'path'); 3332 var pathMovements = getArrowMovements( this.parent.options.arrowShape ); 3333 path.setAttribute( 'd', pathMovements ); 3334 path.setAttribute( 'class', 'arrow' ); 3335 // rotate arrow 3336 if ( !this.isLeft ) { 3337 path.setAttribute( 'transform', 'translate(100, 100) rotate(180) ' ); 3338 } 3339 svg.appendChild( path ); 3340 return svg; 3341}; 3342 3343// get SVG path movmement 3344function getArrowMovements( shape ) { 3345 // use shape as movement if string 3346 if ( typeof shape == 'string' ) { 3347 return shape; 3348 } 3349 // create movement string 3350 return 'M ' + shape.x0 + ',50' + 3351 ' L ' + shape.x1 + ',' + ( shape.y1 + 50 ) + 3352 ' L ' + shape.x2 + ',' + ( shape.y2 + 50 ) + 3353 ' L ' + shape.x3 + ',50 ' + 3354 ' L ' + shape.x2 + ',' + ( 50 - shape.y2 ) + 3355 ' L ' + shape.x1 + ',' + ( 50 - shape.y1 ) + 3356 ' Z'; 3357} 3358 3359PrevNextButton.prototype.onTap = function() { 3360 if ( !this.isEnabled ) { 3361 return; 3362 } 3363 this.parent.uiChange(); 3364 var method = this.isPrevious ? 'previous' : 'next'; 3365 this.parent[ method ](); 3366}; 3367 3368PrevNextButton.prototype.handleEvent = utils.handleEvent; 3369 3370PrevNextButton.prototype.onclick = function( event ) { 3371 // only allow clicks from keyboard 3372 var focused = document.activeElement;
3373 if ( focused && focused == this.element ) { 3374 this.onTap( event, event ); 3375 } 3376}; 3377 3378// ----- ----- // 3379 3380PrevNextButton.prototype.enable = function() { 3381 if ( this.isEnabled ) { 3382 return; 3383 } 3384 this.element.disabled = false; 3385 this.isEnabled = true; 3386}; 3387 3388PrevNextButton.prototype.disable = function() { 3389 if ( !this.isEnabled ) { 3390 return; 3391 } 3392 this.element.disabled = true; 3393 this.isEnabled = false; 3394}; 3395 3396PrevNextButton.prototype.update = function() { 3397 // index of first or last slide, if previous or next 3398 var slides = this.parent.slides; 3399 // enable is wrapAround and at least 2 slides 3400 if ( this.parent.options.wrapAround && slides.length > 1 ) { 3401 this.enable(); 3402 return; 3403 } 3404 var lastIndex = slides.length ? slides.length - 1 : 0; 3405 var boundIndex = this.isPrevious ? 0 : lastIndex; 3406 var method = this.parent.selectedIndex == boundIndex ? 'disable' : 'enable'; 3407 this[ method ](); 3408}; 3409 3410PrevNextButton.prototype.destroy = function() { 3411 this.deactivate(); 3412}; 3413 3414// -------------------------- Flickity prototype -------------------------- // 3415 3416utils.extend( Flickity.defaults, { 3417 prevNextButtons: true, 3418 arrowShape: { 3419 x0: 10, 3420 x1: 60, y1: 50, 3421 x2: 70, y2: 40, 3422 x3: 30 3423 } 3424}); 3425 3426Flickity.createMethods.push('_createPrevNextButtons'); 3427var proto = Flickity.prototype; 3428 3429proto._createPrevNextButtons = function() { 3430 if ( !this.options.prevNextButtons ) { 3431 return; 3432 } 3433 3434 this.prevButton = new PrevNextButton( -1, this ); 3435 this.nextButton = new PrevNextButton( 1, this ); 3436 3437 this.on( 'activate', this.activatePrevNextButtons ); 3438}; 3439 3440proto.activatePrevNextButtons = function() { 3441 this.prevButton.activate(); 3442 this.nextButton.activate(); 3443 this.on( 'deactivate', this.deactivatePrevNextButtons ); 3444}; 3445 3446proto.deactivatePrevNextButtons = function() { 3447 this.prevButton.deactivate(); 3448 this.nextButton.deactivate(); 3449 this.off( 'deactivate', this.deactivatePrevNextButtons ); 3450}; 3451 3452// -------------------------- -------------------------- // 3453 3454Flickity.PrevNextButton = PrevNextButton; 3455 3456return Flickity; 3457 3458})); 3459 3460// page dots 3461( function( window, factory ) { 3462 // universal module definition 3463 /* jshint strict: false */ 3464 if ( typeof define == 'function' && define.amd ) { 3465 // AMD 3466 define( 'flickity/js/page-dots',[ 3467 './flickity', 3468 'tap-listener/tap-listener', 3469 'fizzy-ui-utils/utils' 3470 ], function( Flickity, TapListener, utils ) { 3471 return factory( window, Flickity, TapListener, utils ); 3472 }); 3473 } else if ( typeof module == 'object' && module.exports ) { 3474 // CommonJS 3475 module.exports = factory( 3476 window, 3477 require('./flickity'), 3478 require('tap-listener'), 3479 require('fizzy-ui-utils') 3480 ); 3481 } else { 3482 // browser global 3483 factory( 3484 window, 3485 window.Flickity, 3486 window.TapListener, 3487 window.fizzyUIUtils 3488 ); 3489 } 3490 3491}( window, function factory( window, Flickity, TapListener, utils ) { 3492 3493// -------------------------- PageDots -------------------------- // 3494 3495 3496 3497function PageDots( parent ) { 3498 this.parent = parent; 3499 this._create(); 3500} 3501 3502PageDots.prototype = new TapListener(); 3503 3504PageDots.prototype._create = function() { 3505 // create holder element 3506 this.holder = document.createElement('ol'); 3507 this.holder.className = 'flickity-page-dots'; 3508 // create dots, array of elements 3509 this.dots = []; 3510 // events 3511 this.on( 'tap', this.onTap ); 3512 this.on( 'pointerDown', this.parent.childUIPointerDown.bind( this.parent ) ); 3513}; 3514 3515PageDots.prototype.activate = function() { 3516 this.setDots(); 3517 this.bindTap( this.holder ); 3518 // add to DOM 3519 this.parent.element.appendChild( this.holder ); 3520}; 3521 3522PageDots.prototype.deactivate = function() { 3523 // remove from DOM 3524 this.parent.element.removeChild( this.holder ); 3525 TapListener.prototype.destroy.call( this ); 3526}; 3527 3528PageDots.prototype.setDots = function() { 3529 // get difference between number of slides and number of dots 3530 var delta = this.parent.slides.length - this.dots.length; 3531 if ( delta > 0 ) { 3532 this.addDots( delta ); 3533 } else if ( delta < 0 ) { 3534 this.removeDots( -delta ); 3535 } 3536}; 3537 3538PageDots.prototype.addDots = function( count ) { 3539 var fragment = document.createDocumentFragment(); 3540 var newDots = []; 3541 var length = this.dots.length; 3542 var max = length + count; 3543 3544 for ( var i = length; i < max; i++ ) { 3545 var dot = document.createElement('li'); 3546 dot.className = 'dot'; 3547 dot.setAttribute( 'aria-label', 'Page dot ' + ( i + 1 ) ); 3548 fragment.appendChild( dot ); 3549 newDots.push( dot ); 3550 } 3551 3552 this.holder.appendChild( fragment ); 3553 this.dots = this.dots.concat( newDots ); 3554}; 3555 3556PageDots.prototype.removeDots = function( count ) { 3557 // remove from this.dots collection 3558 var removeDots = this.dots.splice( this.dots.length - count, count ); 3559 // remove from DOM
3560 removeDots.forEach( function( dot ) { 3561 this.holder.removeChild( dot ); 3562 }, this ); 3563}; 3564 3565PageDots.prototype.updateSelected = function() { 3566 // remove selected class on previous 3567 if ( this.selectedDot ) { 3568 this.selectedDot.className = 'dot'; 3569 this.selectedDot.removeAttribute('aria-current'); 3570 } 3571 // don't proceed if no dots 3572 if ( !this.dots.length ) { 3573 return; 3574 } 3575 this.selectedDot = this.dots[ this.parent.selectedIndex ]; 3576 this.selectedDot.className = 'dot is-selected'; 3577 this.selectedDot.setAttribute( 'aria-current', 'step' ); 3578}; 3579 3580PageDots.prototype.onTap = function( event ) { 3581 var target = event.target; 3582 // only care about dot clicks 3583 if ( target.nodeName != 'LI' ) { 3584 return; 3585 } 3586 3587 this.parent.uiChange(); 3588 var index = this.dots.indexOf( target ); 3589 this.parent.select( index ); 3590}; 3591 3592PageDots.prototype.destroy = function() { 3593 this.deactivate(); 3594}; 3595 3596Flickity.PageDots = PageDots; 3597 3598// -------------------------- Flickity -------------------------- // 3599 3600utils.extend( Flickity.defaults, { 3601 pageDots: true 3602}); 3603 3604Flickity.createMethods.push('_createPageDots'); 3605 3606var proto = Flickity.prototype; 3607 3608proto._createPageDots = function() { 3609 if ( !this.options.pageDots ) { 3610 return; 3611 } 3612 this.pageDots = new PageDots( this ); 3613 // events 3614 this.on( 'activate', this.activatePageDots ); 3615 this.on( 'select', this.updateSelectedPageDots ); 3616 this.on( 'cellChange', this.updatePageDots ); 3617 this.on( 'resize', this.updatePageDots ); 3618 this.on( 'deactivate', this.deactivatePageDots ); 3619}; 3620 3621proto.activatePageDots = function() { 3622 this.pageDots.activate(); 3623}; 3624 3625proto.updateSelectedPageDots = function() { 3626 this.pageDots.updateSelected(); 3627}; 3628 3629proto.updatePageDots = function() { 3630 this.pageDots.setDots(); 3631}; 3632 3633proto.deactivatePageDots = function() { 3634 this.pageDots.deactivate(); 3635}; 3636 3637// ----- ----- // 3638 3639Flickity.PageDots = PageDots; 3640 3641return Flickity; 3642 3643})); 3644 3645// player & autoPlay 3646( function( window, factory ) { 3647 // universal module definition 3648 /* jshint strict: false */ 3649 if ( typeof define == 'function' && define.amd ) { 3650 // AMD 3651 define( 'flickity/js/player',[ 3652 'ev-emitter/ev-emitter', 3653 'fizzy-ui-utils/utils', 3654 './flickity' 3655 ], function( EvEmitter, utils, Flickity ) { 3656 return factory( EvEmitter, utils, Flickity ); 3657 }); 3658 } else if ( typeof module == 'object' && module.exports ) { 3659 // CommonJS 3660 module.exports = factory( 3661 require('ev-emitter'), 3662 require('fizzy-ui-utils'), 3663 require('./flickity') 3664 ); 3665 } else { 3666 // browser global 3667 factory( 3668 window.EvEmitter, 3669 window.fizzyUIUtils, 3670 window.Flickity 3671 ); 3672 } 3673 3674}( window, function factory( EvEmitter, utils, Flickity ) { 3675 3676 3677 3678// -------------------------- Player -------------------------- // 3679 3680function Player( parent ) { 3681 this.parent = parent; 3682 this.state = 'stopped'; 3683 // visibility change event handler 3684 this.onVisibilityChange = this.visibilityChange.bind( this ); 3685 this.onVisibilityPlay = this.visibilityPlay.bind( this ); 3686} 3687 3688Player.prototype = Object.create( EvEmitter.prototype ); 3689 3690// start play 3691Player.prototype.play = function() { 3692 if ( this.state == 'playing' ) { 3693 return; 3694 } 3695 // do not play if page is hidden, start playing when page is visible 3696 var isPageHidden = document.hidden; 3697 if ( isPageHidden ) { 3698 document.addEventListener( 'visibilitychange', this.onVisibilityPlay ); 3699 return; 3700 } 3701 3702 this.state = 'playing'; 3703 // listen to visibility change 3704 document.addEventListener( 'visibilitychange', this.onVisibilityChange ); 3705 // start ticking 3706 this.tick(); 3707}; 3708 3709Player.prototype.tick = function() { 3710 // do not tick if not playing 3711 if ( this.state != 'playing' ) { 3712 return; 3713 } 3714 3715 var time = this.parent.options.autoPlay; 3716 // default to 3 seconds 3717 time = typeof time == 'number' ? time : 3000; 3718 var _this = this; 3719 // HACK: reset ticks if stopped and started within interval 3720 this.clear(); 3721 this.timeout = setTimeout( function() { 3722 _this.parent.next( true ); 3723 _this.tick(); 3724 }, time ); 3725}; 3726 3727Player.prototype.stop = function() { 3728 this.state = 'stopped'; 3729 this.clear(); 3730 // remove visibility change event 3731 document.removeEventListener( 'visibilitychange', this.onVisibilityChange ); 3732}; 3733 3734Player.prototype.clear = function() { 3735 clearTimeout( this.timeout ); 3736}; 3737 3738Player.prototype.pause = function() { 3739 if ( this.state == 'playing' ) { 3740 this.state = 'paused'; 3741 this.clear(); 3742 } 3743}; 3744 3745Player.prototype.unpause = function() { 3746 // re-start play if paused 3747 if ( this.state == 'paused' ) { 3748 this.play(); 3749 } 3750}; 3751 3752// pause if page visibility is hidden, unpause if visible 3753Player.prototype.visibilityChange = function() { 3754 var isPageHidden = document.hidden; 3755 this[ isPageHidden ? 'pause' : 'unpause' ](); 3756}; 3757 3758Player.prototype.visibilityPlay = function() { 3759 this.play(); 3760 document.removeEventListener( 'visibilitychange', this.onVisibilityPlay ); 3761}; 3762 3763// -------------------------- Flickity -------------------------- // 3764 3765utils.extend( Flickity.defaults, { 3766 pauseAutoPlayOnHover: true 3767}); 3768 3769Flickity.createMethods.push('_createPlayer'); 3770var proto = Flickity.prototype; 3771 3772proto._createPlayer = function() { 3773 this.player = new Player( this ); 3774 3775 this.on( 'activate', this.activatePlayer ); 3776 this.on( 'uiChange', this.stopPlayer ); 3777 this.on( 'pointerDown', this.stopPlayer ); 3778 this.on( 'deactivate', this.deactivatePlayer ); 3779}; 3780 3781proto.activatePlayer = function() { 3782 if ( !this.options.autoPlay ) { 3783 return; 3784 } 3785 this.player.play(); 3786 this.element.addEventListener( 'mouseenter', this ); 3787}; 3788 3789// Player API, don't hate the ... thanks I know where the door is 3790 3791proto.playPlayer = function() { 3792 this.player.play(); 3793}; 3794 3795proto.stopPlayer = function() { 3796 this.player.stop(); 3797}; 3798 3799proto.pausePlayer = function() { 3800 this.player.pause(); 3801}; 3802 3803proto.unpausePlayer = function() { 3804 this.player.unpause(); 3805}; 3806 3807proto.deactivatePlayer = function() { 3808 this.player.stop(); 3809 this.element.removeEventListener( 'mouseenter', this ); 3810}; 3811 3812// ----- mouseenter/leave ----- // 3813 3814// pause auto-play on hover 3815proto.onmouseenter = function() { 3816 if ( !this.options.pauseAutoPlayOnHover ) { 3817 return; 3818 } 3819 this.player.pause(); 3820 this.element.addEventListener( 'mouseleave', this ); 3821}; 3822 3823// resume auto-play on hover off 3824proto.onmouseleave = function() { 3825 this.player.unpause(); 3826 this.element.removeEventListener( 'mouseleave', this ); 3827}; 3828 3829// ----- ----- // 3830 3831Flickity.Player = Player; 3832 3833return Flickity; 3834 3835})); 3836 3837// add, remove cell 3838( function( window, factory ) { 3839 // universal module definition 3840 /* jshint strict: false */ 3841 if ( typeof define == 'function' && define.amd ) { 3842 // AMD 3843 define( 'flickity/js/add-remove-cell',[ 3844 './flickity', 3845 'fizzy-ui-utils/utils' 3846 ], function( Flickity, utils ) { 3847 return factory( window, Flickity, utils ); 3848 }); 3849 } else if ( typeof module == 'object' && module.exports ) { 3850 // CommonJS 3851 module.exports = factory( 3852 window, 3853 require('./flickity'), 3854 require('fizzy-ui-utils') 3855 ); 3856 } else { 3857 // browser global 3858 factory( 3859 window, 3860 window.Flickity, 3861 window.fizzyUIUtils 3862 ); 3863 } 3864 3865}( window, function factory( window, Flickity, utils ) { 3866 3867 3868 3869// append cells to a document fragment 3870function getCellsFragment( cells ) { 3871 var fragment = document.createDocumentFragment();
3872 cells.forEach( function( cell ) { 3873 fragment.appendChild( cell.element ); 3874 }); 3875 return fragment; 3876} 3877 3878// -------------------------- add/remove cell prototype -------------------------- // 3879 3880var proto = Flickity.prototype; 3881 3882/** 3883 * Insert, prepend, or append cells 3884 * @param {Element, Array, NodeList} elems 3885 * @param {Integer} index 3886 */ 3887proto.insert = function( elems, index ) { 3888 var cells = this._makeCells( elems ); 3889 if ( !cells || !cells.length ) { 3890 return; 3891 } 3892 var len = this.cells.length; 3893 // default to append 3894 index = index === undefined ? len : index; 3895 // add cells with document fragment 3896 var fragment = getCellsFragment( cells ); 3897 // append to slider 3898 var isAppend = index == len; 3899 if ( isAppend ) { 3900 this.slider.appendChild( fragment ); 3901 } else { 3902 var insertCellElement = this.cells[ index ].element; 3903 this.slider.insertBefore( fragment, insertCellElement ); 3904 } 3905 // add to this.cells 3906 if ( index === 0 ) { 3907 // prepend, add to start 3908 this.cells = cells.concat( this.cells ); 3909 } else if ( isAppend ) { 3910 // append, add to end 3911 this.cells = this.cells.concat( cells ); 3912 } else { 3913 // insert in this.cells 3914 var endCells = this.cells.splice( index, len - index ); 3915 this.cells = this.cells.concat( cells ).concat( endCells ); 3916 } 3917 3918 this._sizeCells( cells ); 3919 this.cellChange( index, true ); 3920}; 3921 3922proto.append = function( elems ) { 3923 this.insert( elems, this.cells.length ); 3924}; 3925 3926proto.prepend = function( elems ) { 3927 this.insert( elems, 0 ); 3928}; 3929 3930/** 3931 * Remove cells 3932 * @param {Element, Array, NodeList} elems 3933 */ 3934proto.remove = function( elems ) { 3935 var cells = this.getCells( elems ); 3936 if ( !cells || !cells.length ) { 3937 return; 3938 } 3939 3940 var minCellIndex = this.cells.length - 1; 3941 // remove cells from collection & DOM 3942 cells.forEach( function( cell ) { 3943 cell.remove(); 3944 var index = this.cells.indexOf( cell ); 3945 minCellIndex = Math.min( index, minCellIndex ); 3946 utils.removeFrom( this.cells, cell ); 3947 }, this ); 3948 3949 this.cellChange( minCellIndex, true ); 3950}; 3951 3952/** 3953 * logic to be run after a cell's size changes 3954 * @param {Element} elem - cell's element 3955 */ 3956proto.cellSizeChange = function( elem ) { 3957 var cell = this.getCell( elem ); 3958 if ( !cell ) { 3959 return; 3960 } 3961 cell.getSize(); 3962 3963 var index = this.cells.indexOf( cell ); 3964 this.cellChange( index ); 3965}; 3966 3967/** 3968 * logic any time a cell is changed: added, removed, or size changed 3969 * @param {Integer} changedCellIndex - index of the changed cell, optional 3970 */ 3971proto.cellChange = function( changedCellIndex, isPositioningSlider ) { 3972 var prevSelectedElem = this.selectedElement; 3973 this._positionCells( changedCellIndex ); 3974 this._getWrapShiftCells(); 3975 this.setGallerySize(); 3976 // update selectedIndex 3977 // try to maintain position & select previous selected element 3978 var cell = this.getCell( prevSelectedElem ); 3979 if ( cell ) { 3980 this.selectedIndex = this.getCellSlideIndex( cell ); 3981 } 3982 this.selectedIndex = Math.min( this.slides.length - 1, this.selectedIndex ); 3983 3984 this.emitEvent( 'cellChange', [ changedCellIndex ] ); 3985 // position slider 3986 this.select( this.selectedIndex ); 3987 // do not position slider after lazy load 3988 if ( isPositioningSlider ) { 3989 this.positionSliderAtSelected(); 3990 } 3991}; 3992 3993// ----- ----- // 3994 3995return Flickity; 3996 3997})); 3998 3999// lazyload 4000( function( window, factory ) { 4001 // universal module definition 4002 /* jshint strict: false */ 4003 if ( typeof define == 'function' && define.amd ) { 4004 // AMD 4005 define( 'flickity/js/lazyload',[ 4006 './flickity', 4007 'fizzy-ui-utils/utils' 4008 ], function( Flickity, utils ) { 4009 return factory( window, Flickity, utils ); 4010 }); 4011 } else if ( typeof module == 'object' && module.exports ) { 4012 // CommonJS 4013 module.exports = factory( 4014 window, 4015 require('./flickity'), 4016 require('fizzy-ui-utils') 4017 ); 4018 } else { 4019 // browser global 4020 factory( 4021 window, 4022 window.Flickity, 4023 window.fizzyUIUtils 4024 ); 4025 } 4026 4027}( window, function factory( window, Flickity, utils ) { 4028'use strict'; 4029 4030Flickity.createMethods.push('_createLazyload'); 4031var proto = Flickity.prototype; 4032 4033proto._createLazyload = function() { 4034 this.on( 'select', this.lazyLoad ); 4035}; 4036 4037proto.lazyLoad = function() { 4038 var lazyLoad = this.options.lazyLoad; 4039 if ( !lazyLoad ) { 4040 return; 4041 } 4042 // get adjacent cells, use lazyLoad option for adjacent count 4043 var adjCount = typeof lazyLoad == 'number' ? lazyLoad : 0; 4044 var cellElems = this.getAdjacentCellElements( adjCount ); 4045 // get lazy images in those cells 4046 var lazyImages = [];
4047 cellElems.forEach( function( cellElem ) { 4048 var lazyCellImages = getCellLazyImages( cellElem ); 4049 lazyImages = lazyImages.concat( lazyCellImages ); 4050 }); 4051 // load lazy images 4052 lazyImages.forEach( function( img ) { 4053 new LazyLoader( img, this ); 4054 }, this ); 4055}; 4056 4057function getCellLazyImages( cellElem ) { 4058 // check if cell element is lazy image 4059 if ( cellElem.nodeName == 'IMG' ) { 4060 var lazyloadAttr = cellElem.getAttribute('data-flickity-lazyload'); 4061 var srcAttr = cellElem.getAttribute('data-flickity-lazyload-src'); 4062 var srcsetAttr = cellElem.getAttribute('data-flickity-lazyload-srcset'); 4063 if ( lazyloadAttr || srcAttr || srcsetAttr ) { 4064 return [ cellElem ]; 4065 } 4066 } 4067 // select lazy images in cell 4068 var lazySelector = 'img[data-flickity-lazyload], ' + 4069 'img[data-flickity-lazyload-src], img[data-flickity-lazyload-srcset]'; 4070 var imgs = cellElem.querySelectorAll( lazySelector ); 4071 return utils.makeArray( imgs ); 4072} 4073 4074// -------------------------- LazyLoader -------------------------- // 4075 4076/** 4077 * class to handle loading images 4078 */ 4079function LazyLoader( img, flickity ) { 4080 this.img = img; 4081 this.flickity = flickity; 4082 this.load(); 4083} 4084 4085LazyLoader.prototype.handleEvent = utils.handleEvent; 4086 4087LazyLoader.prototype.load = function() { 4088 this.img.addEventListener( 'load', this ); 4089 this.img.addEventListener( 'error', this ); 4090 // get src & srcset 4091 var src = this.img.getAttribute('data-flickity-lazyload') || 4092 this.img.getAttribute('data-flickity-lazyload-src'); 4093 var srcset = this.img.getAttribute('data-flickity-lazyload-srcset'); 4094 // set src & serset 4095 this.img.src = src; 4096 if ( srcset ) { 4097 this.img.setAttribute( 'srcset', srcset ); 4098 } 4099 // remove attr 4100 this.img.removeAttribute('data-flickity-lazyload'); 4101 this.img.removeAttribute('data-flickity-lazyload-src'); 4102 this.img.removeAttribute('data-flickity-lazyload-srcset'); 4103}; 4104 4105LazyLoader.prototype.onload = function( event ) { 4106 this.complete( event, 'flickity-lazyloaded' ); 4107}; 4108 4109LazyLoader.prototype.onerror = function( event ) { 4110 this.complete( event, 'flickity-lazyerror' ); 4111}; 4112 4113LazyLoader.prototype.complete = function( event, className ) { 4114 // unbind events 4115 this.img.removeEventListener( 'load', this ); 4116 this.img.removeEventListener( 'error', this ); 4117 4118 var cell = this.flickity.getParentCell( this.img ); 4119 var cellElem = cell && cell.element; 4120 this.flickity.cellSizeChange( cellElem ); 4121 4122 this.img.classList.add( className ); 4123 this.flickity.dispatchEvent( 'lazyLoad', event, cellElem ); 4124}; 4125 4126// ----- ----- // 4127 4128Flickity.LazyLoader = LazyLoader; 4129 4130return Flickity; 4131 4132})); 4133 4134/*! 4135 * Flickity v2.1.2 4136 * Touch, responsive, flickable carousels 4137 * 4138 * Licensed GPLv3 for open source use 4139 * or Flickity Commercial License for commercial use 4140 * 4141 * https://flickity.metafizzy.co 4142 * Copyright 2015-2018 Metafizzy 4143 */ 4144 4145( function( window, factory ) { 4146 // universal module definition 4147 /* jshint strict: false */ 4148 if ( typeof define == 'function' && define.amd ) { 4149 // AMD 4150 define( 'flickity/js/index',[ 4151 './flickity', 4152 './drag', 4153 './prev-next-button', 4154 './page-dots', 4155 './player', 4156 './add-remove-cell', 4157 './lazyload' 4158 ], factory ); 4159 } else if ( typeof module == 'object' && module.exports ) { 4160 // CommonJS 4161 module.exports = factory( 4162 require('./flickity'), 4163 require('./drag'), 4164 require('./prev-next-button'), 4165 require('./page-dots'), 4166 require('./player'), 4167 require('./add-remove-cell'), 4168 require('./lazyload') 4169 ); 4170 } 4171 4172})( window, function factory( Flickity ) { 4173 /*jshint strict: false*/ 4174 return Flickity; 4175}); 4176 4177/*! 4178 * Flickity asNavFor v2.0.1 4179 * enable asNavFor for Flickity 4180 */ 4181 4182/*jshint browser: true, undef: true, unused: true, strict: true*/ 4183 4184( function( window, factory ) { 4185 // universal module definition 4186 /*jshint strict: false */ /*globals define, module, require */ 4187 if ( typeof define == 'function' && define.amd ) { 4188 // AMD 4189 define( 'flickity-as-nav-for/as-nav-for',[ 4190 'flickity/js/index', 4191 'fizzy-ui-utils/utils' 4192 ], factory ); 4193 } else if ( typeof module == 'object' && module.exports ) { 4194 // CommonJS 4195 module.exports = factory( 4196 require('flickity'), 4197 require('fizzy-ui-utils') 4198 ); 4199 } else { 4200 // browser global 4201 window.Flickity = factory( 4202 window.Flickity, 4203 window.fizzyUIUtils 4204 ); 4205 } 4206 4207}( window, function factory( Flickity, utils ) { 4208 4209 4210 4211// -------------------------- asNavFor prototype -------------------------- // 4212 4213// Flickity.defaults.asNavFor = null; 4214 4215Flickity.createMethods.push('_createAsNavFor'); 4216 4217var proto = Flickity.prototype; 4218 4219proto._createAsNavFor = function() { 4220 this.on( 'activate', this.activateAsNavFor ); 4221 this.on( 'deactivate', this.deactivateAsNavFor ); 4222 this.on( 'destroy', this.destroyAsNavFor ); 4223 4224 var asNavForOption = this.options.asNavFor; 4225 if ( !asNavForOption ) { 4226 return; 4227 } 4228 // HACK do async, give time for other flickity to be initalized 4229 var _this = this; 4230 setTimeout( function initNavCompanion() { 4231 _this.setNavCompanion( asNavForOption ); 4232 }); 4233}; 4234 4235proto.setNavCompanion = function( elem ) { 4236 elem = utils.getQueryElement( elem ); 4237 var companion = Flickity.data( elem ); 4238 // stop if no companion or companion is self 4239 if ( !companion || companion == this ) { 4240 return; 4241 } 4242 4243 this.navCompanion = companion; 4244 // companion select 4245 var _this = this; 4246 this.onNavCompanionSelect = function() { 4247 _this.navCompanionSelect(); 4248 }; 4249 companion.on( 'select', this.onNavCompanionSelect ); 4250 // click 4251 this.on( 'staticClick', this.onNavStaticClick ); 4252 4253 this.navCompanionSelect( true ); 4254}; 4255 4256proto.navCompanionSelect = function( isInstant ) { 4257 if ( !this.navCompanion ) { 4258 return; 4259 } 4260 // select slide that matches first cell of slide 4261 var selectedCell = this.navCompanion.selectedCells[0]; 4262 var firstIndex = this.navCompanion.cells.indexOf( selectedCell ); 4263 var lastIndex = firstIndex + this.navCompanion.selectedCells.length - 1; 4264 var selectIndex = Math.floor( lerp( firstIndex, lastIndex, 4265 this.navCompanion.cellAlign ) ); 4266 this.selectCell( selectIndex, false, isInstant ); 4267 // set nav selected class 4268 this.removeNavSelectedElements();
vendor: 4,404 bytes, lines 4269-4454
4269 // stop if companion has more cells than this one 4270 if ( selectIndex >= this.cells.length ) { 4271 return; 4272 } 4273 4274 var selectedCells = this.cells.slice( firstIndex, lastIndex + 1 ); 4275 this.navSelectedElements = selectedCells.map( function( cell ) { 4276 return cell.element; 4277 }); 4278 this.changeNavSelectedClass('add'); 4279}; 4280 4281function lerp( a, b, t ) { 4282 return ( b - a ) * t + a; 4283} 4284 4285proto.changeNavSelectedClass = function( method ) { 4286 this.navSelectedElements.forEach( function( navElem ) { 4287 navElem.classList[ method ]('is-nav-selected'); 4288 }); 4289}; 4290 4291proto.activateAsNavFor = function() { 4292 this.navCompanionSelect( true ); 4293}; 4294 4295proto.removeNavSelectedElements = function() { 4296 if ( !this.navSelectedElements ) { 4297 return; 4298 } 4299 this.changeNavSelectedClass('remove'); 4300 delete this.navSelectedElements; 4301}; 4302 4303proto.onNavStaticClick = function( event, pointer, cellElement, cellIndex ) { 4304 if ( typeof cellIndex == 'number' ) { 4305 this.navCompanion.selectCell( cellIndex ); 4306 } 4307}; 4308 4309proto.deactivateAsNavFor = function() { 4310 this.removeNavSelectedElements(); 4311}; 4312 4313proto.destroyAsNavFor = function() { 4314 if ( !this.navCompanion ) { 4315 return; 4316 } 4317 this.navCompanion.off( 'select', this.onNavCompanionSelect ); 4318 this.off( 'staticClick', this.onNavStaticClick ); 4319 delete this.navCompanion; 4320}; 4321 4322// ----- ----- // 4323 4324return Flickity; 4325 4326})); 4327 4328/*! 4329 * imagesLoaded v4.1.4 4330 * JavaScript is all like "You images are done yet or what?" 4331 * MIT License 4332 */ 4333 4334( function( window, factory ) { 'use strict'; 4335 // universal module definition 4336 4337 /*global define: false, module: false, require: false */ 4338 4339 if ( typeof define == 'function' && define.amd ) { 4340 // AMD 4341 define( 'imagesloaded/imagesloaded',[ 4342 'ev-emitter/ev-emitter' 4343 ], function( EvEmitter ) { 4344 return factory( window, EvEmitter ); 4345 }); 4346 } else if ( typeof module == 'object' && module.exports ) { 4347 // CommonJS 4348 module.exports = factory( 4349 window, 4350 require('ev-emitter') 4351 ); 4352 } else { 4353 // browser global 4354 window.imagesLoaded = factory( 4355 window, 4356 window.EvEmitter 4357 ); 4358 } 4359 4360})( typeof window !== 'undefined' ? window : this, 4361 4362// -------------------------- factory -------------------------- // 4363 4364function factory( window, EvEmitter ) { 4365 4366 4367 4368var $ = window.jQuery; 4369var console = window.console; 4370 4371// -------------------------- helpers -------------------------- // 4372 4373// extend objects 4374function extend( a, b ) { 4375 for ( var prop in b ) { 4376 a[ prop ] = b[ prop ]; 4377 } 4378 return a; 4379} 4380 4381var arraySlice = Array.prototype.slice; 4382 4383// turn element or nodeList into an array 4384function makeArray( obj ) { 4385 if ( Array.isArray( obj ) ) { 4386 // use object if already an array 4387 return obj; 4388 } 4389 4390 var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number'; 4391 if ( isArrayLike ) { 4392 // convert nodeList to array 4393 return arraySlice.call( obj ); 4394 } 4395 4396 // array of single index 4397 return [ obj ]; 4398} 4399 4400// -------------------------- imagesLoaded -------------------------- // 4401 4402/** 4403 * @param {Array, Element, NodeList, String} elem 4404 * @param {Object or Function} options - if function, use as callback 4405 * @param {Function} onAlways - callback function 4406 */ 4407function ImagesLoaded( elem, options, onAlways ) { 4408 // coerce ImagesLoaded() without new, to be new ImagesLoaded() 4409 if ( !( this instanceof ImagesLoaded ) ) { 4410 return new ImagesLoaded( elem, options, onAlways ); 4411 } 4412 // use elem as selector string 4413 var queryElem = elem; 4414 if ( typeof elem == 'string' ) { 4415 queryElem = document.querySelectorAll( elem ); 4416 } 4417 // bail if bad element 4418 if ( !queryElem ) { 4419 console.error( 'Bad element for imagesLoaded ' + ( queryElem || elem ) ); 4420 return; 4421 } 4422 4423 this.elements = makeArray( queryElem ); 4424 this.options = extend( {}, this.options ); 4425 // shift arguments if no options set 4426 if ( typeof options == 'function' ) { 4427 onAlways = options; 4428 } else { 4429 extend( this.options, options ); 4430 } 4431 4432 if ( onAlways ) { 4433 this.on( 'always', onAlways ); 4434 } 4435 4436 this.getImages(); 4437 4438 if ( $ ) { 4439 // add jQuery Deferred object 4440 this.jqDeferred = new $.Deferred(); 4441 } 4442 4443 // HACK check async to allow time to bind listeners 4444 setTimeout( this.check.bind( this ) ); 4445} 4446 4447ImagesLoaded.prototype = Object.create( EvEmitter.prototype ); 4448 4449ImagesLoaded.prototype.options = {}; 4450 4451ImagesLoaded.prototype.getImages = function() { 4452 this.images = []; 4453 4454 // filter & find items if we have an item selector
vendor: 4,347 bytes, lines 4455-4611
4455 this.elements.forEach( this.addElementImages, this ); 4456}; 4457 4458/** 4459 * @param {Node} element 4460 */ 4461ImagesLoaded.prototype.addElementImages = function( elem ) { 4462 // filter siblings 4463 if ( elem.nodeName == 'IMG' ) { 4464 this.addImage( elem ); 4465 } 4466 // get background image on element 4467 if ( this.options.background === true ) { 4468 this.addElementBackgroundImages( elem ); 4469 } 4470 4471 // find children 4472 // no non-element nodes, #143 4473 var nodeType = elem.nodeType; 4474 if ( !nodeType || !elementNodeTypes[ nodeType ] ) { 4475 return; 4476 } 4477 var childImgs = elem.querySelectorAll('img'); 4478 // concat childElems to filterFound array 4479 for ( var i=0; i < childImgs.length; i++ ) { 4480 var img = childImgs[i]; 4481 this.addImage( img ); 4482 } 4483 4484 // get child background images 4485 if ( typeof this.options.background == 'string' ) { 4486 var children = elem.querySelectorAll( this.options.background ); 4487 for ( i=0; i < children.length; i++ ) { 4488 var child = children[i]; 4489 this.addElementBackgroundImages( child ); 4490 } 4491 } 4492}; 4493 4494var elementNodeTypes = { 4495 1: true, 4496 9: true, 4497 11: true 4498}; 4499 4500ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) { 4501 var style = getComputedStyle( elem ); 4502 if ( !style ) { 4503 // Firefox returns null if in a hidden iframe https://bugzil.la/548397 4504 return; 4505 } 4506 // get url inside url("...") 4507 var reURL = /url\((['"])?(.*?)\1\)/gi; 4508 var matches = reURL.exec( style.backgroundImage ); 4509 while ( matches !== null ) { 4510 var url = matches && matches[2]; 4511 if ( url ) { 4512 this.addBackground( url, elem ); 4513 } 4514 matches = reURL.exec( style.backgroundImage ); 4515 } 4516}; 4517 4518/** 4519 * @param {Image} img 4520 */ 4521ImagesLoaded.prototype.addImage = function( img ) { 4522 var loadingImage = new LoadingImage( img ); 4523 this.images.push( loadingImage ); 4524}; 4525 4526ImagesLoaded.prototype.addBackground = function( url, elem ) { 4527 var background = new Background( url, elem ); 4528 this.images.push( background ); 4529}; 4530 4531ImagesLoaded.prototype.check = function() { 4532 var _this = this; 4533 this.progressedCount = 0; 4534 this.hasAnyBroken = false; 4535 // complete if no images 4536 if ( !this.images.length ) { 4537 this.complete(); 4538 return; 4539 } 4540 4541 function onProgress( image, elem, message ) { 4542 // HACK - Chrome triggers event before object properties have changed. #83 4543 setTimeout( function() { 4544 _this.progress( image, elem, message ); 4545 }); 4546 } 4547 4548 this.images.forEach( function( loadingImage ) { 4549 loadingImage.once( 'progress', onProgress ); 4550 loadingImage.check(); 4551 }); 4552}; 4553 4554ImagesLoaded.prototype.progress = function( image, elem, message ) { 4555 this.progressedCount++; 4556 this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded; 4557 // progress event 4558 this.emitEvent( 'progress', [ this, image, elem ] ); 4559 if ( this.jqDeferred && this.jqDeferred.notify ) { 4560 this.jqDeferred.notify( this, image ); 4561 } 4562 // check if completed 4563 if ( this.progressedCount == this.images.length ) { 4564 this.complete(); 4565 } 4566 4567 if ( this.options.debug && console ) { 4568 console.log( 'progress: ' + message, image, elem ); 4569 } 4570}; 4571 4572ImagesLoaded.prototype.complete = function() { 4573 var eventName = this.hasAnyBroken ? 'fail' : 'done'; 4574 this.isComplete = true; 4575 this.emitEvent( eventName, [ this ] ); 4576 this.emitEvent( 'always', [ this ] ); 4577 if ( this.jqDeferred ) { 4578 var jqMethod = this.hasAnyBroken ? 'reject' : 'resolve'; 4579 this.jqDeferred[ jqMethod ]( this ); 4580 } 4581}; 4582 4583// -------------------------- -------------------------- // 4584 4585function LoadingImage( img ) { 4586 this.img = img; 4587} 4588 4589LoadingImage.prototype = Object.create( EvEmitter.prototype ); 4590 4591LoadingImage.prototype.check = function() { 4592 // If complete is true and browser supports natural sizes, 4593 // try to check for image status manually. 4594 var isComplete = this.getIsImageComplete(); 4595 if ( isComplete ) { 4596 // report based on naturalWidth 4597 this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' ); 4598 return; 4599 } 4600 4601 // If none of the checks above matched, simulate loading on detached element. 4602 this.proxyImage = new Image(); 4603 this.proxyImage.addEventListener( 'load', this ); 4604 this.proxyImage.addEventListener( 'error', this ); 4605 // bind to image as well for Firefox. #191 4606 this.img.addEventListener( 'load', this ); 4607 this.img.addEventListener( 'error', this ); 4608 this.proxyImage.src = this.img.src; 4609}; 4610 4611LoadingImage.prototype.getIsImageComplete = function() {
vendor: 4,127 bytes, lines 4612-4769
4612 // check for non-zero, non-undefined naturalWidth 4613 // fixes Safari+InfiniteScroll+Masonry bug infinite-scroll#671 4614 return this.img.complete && this.img.naturalWidth; 4615}; 4616 4617LoadingImage.prototype.confirm = function( isLoaded, message ) { 4618 this.isLoaded = isLoaded; 4619 this.emitEvent( 'progress', [ this, this.img, message ] ); 4620}; 4621 4622// ----- events ----- // 4623 4624// trigger specified handler for event type 4625LoadingImage.prototype.handleEvent = function( event ) { 4626 var method = 'on' + event.type; 4627 if ( this[ method ] ) { 4628 this[ method ]( event ); 4629 } 4630}; 4631 4632LoadingImage.prototype.onload = function() { 4633 this.confirm( true, 'onload' ); 4634 this.unbindEvents(); 4635}; 4636 4637LoadingImage.prototype.onerror = function() { 4638 this.confirm( false, 'onerror' ); 4639 this.unbindEvents(); 4640}; 4641 4642LoadingImage.prototype.unbindEvents = function() { 4643 this.proxyImage.removeEventListener( 'load', this ); 4644 this.proxyImage.removeEventListener( 'error', this ); 4645 this.img.removeEventListener( 'load', this ); 4646 this.img.removeEventListener( 'error', this ); 4647}; 4648 4649// -------------------------- Background -------------------------- // 4650 4651function Background( url, element ) { 4652 this.url = url; 4653 this.element = element; 4654 this.img = new Image(); 4655} 4656 4657// inherit LoadingImage prototype 4658Background.prototype = Object.create( LoadingImage.prototype ); 4659 4660Background.prototype.check = function() { 4661 this.img.addEventListener( 'load', this ); 4662 this.img.addEventListener( 'error', this ); 4663 this.img.src = this.url; 4664 // check if image is already complete 4665 var isComplete = this.getIsImageComplete(); 4666 if ( isComplete ) { 4667 this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' ); 4668 this.unbindEvents(); 4669 } 4670}; 4671 4672Background.prototype.unbindEvents = function() { 4673 this.img.removeEventListener( 'load', this ); 4674 this.img.removeEventListener( 'error', this ); 4675}; 4676 4677Background.prototype.confirm = function( isLoaded, message ) { 4678 this.isLoaded = isLoaded; 4679 this.emitEvent( 'progress', [ this, this.element, message ] ); 4680}; 4681 4682// -------------------------- jQuery -------------------------- // 4683 4684ImagesLoaded.makeJQueryPlugin = function( jQuery ) { 4685 jQuery = jQuery || window.jQuery; 4686 if ( !jQuery ) { 4687 return; 4688 } 4689 // set local variable 4690 $ = jQuery; 4691 // $().imagesLoaded() 4692 $.fn.imagesLoaded = function( options, callback ) { 4693 var instance = new ImagesLoaded( this, options, callback ); 4694 return instance.jqDeferred.promise( $(this) ); 4695 }; 4696}; 4697// try making plugin 4698ImagesLoaded.makeJQueryPlugin(); 4699 4700// -------------------------- -------------------------- // 4701 4702return ImagesLoaded; 4703 4704}); 4705 4706/*! 4707 * Flickity imagesLoaded v2.0.0 4708 * enables imagesLoaded option for Flickity 4709 */ 4710 4711/*jshint browser: true, strict: true, undef: true, unused: true */ 4712 4713( function( window, factory ) { 4714 // universal module definition 4715 /*jshint strict: false */ /*globals define, module, require */ 4716 if ( typeof define == 'function' && define.amd ) { 4717 // AMD 4718 define( [ 4719 'flickity/js/index', 4720 'imagesloaded/imagesloaded' 4721 ], function( Flickity, imagesLoaded ) { 4722 return factory( window, Flickity, imagesLoaded ); 4723 }); 4724 } else if ( typeof module == 'object' && module.exports ) { 4725 // CommonJS 4726 module.exports = factory( 4727 window, 4728 require('flickity'), 4729 require('imagesloaded') 4730 ); 4731 } else { 4732 // browser global 4733 window.Flickity = factory( 4734 window, 4735 window.Flickity, 4736 window.imagesLoaded 4737 ); 4738 } 4739 4740}( window, function factory( window, Flickity, imagesLoaded ) { 4741'use strict'; 4742 4743Flickity.createMethods.push('_createImagesLoaded'); 4744 4745var proto = Flickity.prototype; 4746 4747proto._createImagesLoaded = function() { 4748 this.on( 'activate', this.imagesLoaded ); 4749}; 4750 4751proto.imagesLoaded = function() { 4752 if ( !this.options.imagesLoaded ) { 4753 return; 4754 } 4755 var _this = this; 4756 function onImagesLoadedProgress( instance, image ) { 4757 var cell = _this.getParentCell( image.img ); 4758 _this.cellSizeChange( cell && cell.element ); 4759 if ( !_this.options.freeScroll ) { 4760 _this.positionSliderAtSelected(); 4761 } 4762 } 4763 imagesLoaded( this.slider ).on( 'progress', onImagesLoadedProgress ); 4764}; 4765 4766return Flickity; 4767 4768 4769}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.