vendor: 16,710 bytes, lines 1-656
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 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
vendor: 4,947 bytes, lines 657-839
657 elems.forEach( function( elem ) { 658 // check that elem is an actual element 659 if ( !( elem instanceof HTMLElement ) ) { 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.positionSliderAtSelected = function() { 1039 if ( !this.cells.length ) { 1040 return; 1041 } 1042 this.x = -this.selectedSlide.target; 1043 this.velocity = 0; // stop wobble 1044 this.positionSlider(); 1045}; 1046 1047proto.getPositionValue = function( position ) { 1048 if ( this.options.percentPosition ) { 1049 // percent position, round to 2 digits, like 12.34% 1050 return ( Math.round( ( position / this.size.innerWidth ) * 10000 ) * 0.01 )+ '%'; 1051 } else { 1052 // pixel positioning 1053 return Math.round( position ) + 'px'; 1054 } 1055}; 1056 1057proto.settle = function( previousX ) { 1058 // keep track of frames where x hasn't moved 1059 if ( !this.isPointerDown && Math.round( this.x * 100 ) == Math.round( previousX * 100 ) ) { 1060 this.restingFrames++; 1061 } 1062 // stop animating if resting for 3 or more frames 1063 if ( this.restingFrames > 2 ) { 1064 this.isAnimating = false; 1065 delete this.isFreeScrolling; 1066 // render position with translateX when settled 1067 this.positionSlider(); 1068 this.dispatchEvent( 'settle', null, [ this.selectedIndex ] ); 1069 } 1070}; 1071 1072proto.shiftWrapCells = function( x ) { 1073 // shift before cells 1074 var beforeGap = this.cursorPosition + x; 1075 this._shiftCells( this.beforeShiftCells, beforeGap, -1 ); 1076 // shift after cells 1077 var afterGap = this.size.innerWidth - ( x + this.slideableWidth + this.cursorPosition ); 1078 this._shiftCells( this.afterShiftCells, afterGap, 1 ); 1079}; 1080 1081proto._shiftCells = function( cells, gap, shift ) { 1082 for ( var i=0; i < cells.length; i++ ) { 1083 var cell = cells[i]; 1084 var cellShift = gap > 0 ? shift : 0; 1085 cell.wrapShift( cellShift ); 1086 gap -= cell.size.outerWidth; 1087 } 1088}; 1089 1090proto._unshiftCells = function( cells ) { 1091 if ( !cells || !cells.length ) { 1092 return; 1093 } 1094 for ( var i=0; i < cells.length; i++ ) { 1095 cells[i].wrapShift( 0 ); 1096 } 1097}; 1098 1099// -------------------------- physics -------------------------- // 1100 1101proto.integratePhysics = function() { 1102 this.x += this.velocity; 1103 this.velocity *= this.getFrictionFactor(); 1104}; 1105 1106proto.applyForce = function( force ) { 1107 this.velocity += force; 1108}; 1109 1110proto.getFrictionFactor = function() { 1111 return 1 - this.options[ this.isFreeScrolling ? 'freeScrollFriction' : 'friction' ]; 1112}; 1113 1114proto.getRestingPosition = function() { 1115 // my thanks to Steven Wittens, who simplified this math greatly 1116 return this.x + this.velocity / ( 1 - this.getFrictionFactor() ); 1117}; 1118 1119proto.applyDragForce = function() { 1120 if ( !this.isDraggable || !this.isPointerDown ) { 1121 return; 1122 } 1123 // change the position to drag position by applying force 1124 var dragVelocity = this.dragX - this.x; 1125 var dragForce = dragVelocity - this.velocity; 1126 this.applyForce( dragForce ); 1127}; 1128 1129proto.applySelectedAttraction = function() { 1130 // do not attract if pointer down or no slides 1131 var dragDown = this.isDraggable && this.isPointerDown; 1132 if ( dragDown || this.isFreeScrolling || !this.slides.length ) { 1133 return; 1134 } 1135 var distance = this.selectedSlide.target * -1 - this.x; 1136 var force = distance * this.options.selectedAttraction; 1137 this.applyForce( force ); 1138}; 1139 1140return proto; 1141 1142})); 1143 1144// Flickity main 1145( function( window, factory ) { 1146 // universal module definition 1147 /* jshint strict: false */ 1148 if ( typeof define == 'function' && define.amd ) { 1149 // AMD 1150 define( 'flickity/js/flickity',[ 1151 'ev-emitter/ev-emitter', 1152 'get-size/get-size', 1153 'fizzy-ui-utils/utils', 1154 './cell', 1155 './slide', 1156 './animate' 1157 ], function( EvEmitter, getSize, utils, Cell, Slide, animatePrototype ) { 1158 return factory( window, EvEmitter, getSize, utils, Cell, Slide, animatePrototype ); 1159 });
1160 } else if ( typeof module == 'object' && module.exports ) { 1161 // CommonJS 1162 module.exports = factory( 1163 window, 1164 require('ev-emitter'), 1165 require('get-size'), 1166 require('fizzy-ui-utils'), 1167 require('./cell'), 1168 require('./slide'), 1169 require('./animate') 1170 ); 1171 } else { 1172 // browser global 1173 var _Flickity = window.Flickity; 1174 1175 window.Flickity = factory( 1176 window, 1177 window.EvEmitter, 1178 window.getSize, 1179 window.fizzyUIUtils, 1180 _Flickity.Cell, 1181 _Flickity.Slide, 1182 _Flickity.animatePrototype 1183 ); 1184 } 1185 1186}( window, function factory( window, EvEmitter, getSize, 1187 utils, Cell, Slide, animatePrototype ) { 1188 1189 1190 1191// vars 1192var jQuery = window.jQuery; 1193var getComputedStyle = window.getComputedStyle; 1194var console = window.console; 1195 1196function moveElements( elems, toElem ) { 1197 elems = utils.makeArray( elems ); 1198 while ( elems.length ) { 1199 toElem.appendChild( elems.shift() ); 1200 } 1201} 1202 1203// -------------------------- Flickity -------------------------- // 1204 1205// globally unique identifiers 1206var GUID = 0; 1207// internal store of all Flickity intances 1208var instances = {}; 1209 1210function Flickity( element, options ) { 1211 var queryElement = utils.getQueryElement( element ); 1212 if ( !queryElement ) { 1213 if ( console ) { 1214 console.error( 'Bad element for Flickity: ' + ( queryElement || element ) ); 1215 } 1216 return; 1217 } 1218 this.element = queryElement; 1219 // do not initialize twice on same element 1220 if ( this.element.flickityGUID ) { 1221 var instance = instances[ this.element.flickityGUID ]; 1222 instance.option( options ); 1223 return instance; 1224 } 1225 1226 // add jQuery 1227 if ( jQuery ) { 1228 this.$element = jQuery( this.element ); 1229 } 1230 // options 1231 this.options = utils.extend( {}, this.constructor.defaults ); 1232 this.option( options ); 1233 1234 // kick things off 1235 this._create(); 1236} 1237 1238Flickity.defaults = { 1239 accessibility: true, 1240 // adaptiveHeight: false, 1241 cellAlign: 'center', 1242 // cellSelector: undefined, 1243 // contain: false, 1244 freeScrollFriction: 0.075, // friction when free-scrolling 1245 friction: 0.28, // friction when selecting 1246 namespaceJQueryEvents: true, 1247 // initialIndex: 0, 1248 percentPosition: true, 1249 resize: true, 1250 selectedAttraction: 0.025, 1251 setGallerySize: true 1252 // watchCSS: false, 1253 // wrapAround: false 1254}; 1255 1256// hash of methods triggered on _create() 1257Flickity.createMethods = []; 1258 1259var proto = Flickity.prototype; 1260// inherit EventEmitter 1261utils.extend( proto, EvEmitter.prototype ); 1262 1263proto._create = function() { 1264 // add id for Flickity.data 1265 var id = this.guid = ++GUID; 1266 this.element.flickityGUID = id; // expando 1267 instances[ id ] = this; // associate via id 1268 // initial properties 1269 this.selectedIndex = 0; 1270 // how many frames slider has been in same position 1271 this.restingFrames = 0; 1272 // initial physics properties 1273 this.x = 0; 1274 this.velocity = 0; 1275 this.originSide = this.options.rightToLeft ? 'right' : 'left'; 1276 // create viewport & slider 1277 /*nectar addition*/ 1278 1279 if(this.$element.hasClass('generate-markup')) { 1280 this.viewport = document.createElement('div'); 1281 this.viewport.className = 'flickity-viewport'; 1282 } else { 1283 this.viewport = this.$element.find('.flickity-viewport')[0]; 1284 this.slider = this.$element.find('.flickity-slider')[0]; 1285 this.viewport.className = 'flickity-viewport'; 1286 } 1287 1288 this._createSlider(); 1289 1290 1291 /*nectar addition end*/ 1292 1293 if ( this.options.resize || this.options.watchCSS ) { 1294 window.addEventListener( 'resize', this ); 1295 } 1296 1297 // add listeners from on option 1298 for ( var eventName in this.options.on ) { 1299 var listener = this.options.on[ eventName ]; 1300 this.on( eventName, listener ); 1301 } 1302 1303 Flickity.createMethods.forEach( function( method ) { 1304 this[ method ](); 1305 }, this ); 1306 1307 if ( this.options.watchCSS ) { 1308 this.watchCSS(); 1309 } else { 1310 this.activate(); 1311 } 1312 1313}; 1314 1315/** 1316 * set options 1317 * @param {Object} opts 1318 */ 1319proto.option = function( opts ) { 1320 utils.extend( this.options, opts ); 1321}; 1322 1323proto.activate = function() { 1324 if ( this.isActive ) { 1325 return; 1326 } 1327 this.isActive = true; 1328 this.element.classList.add('flickity-enabled'); 1329 if ( this.options.rightToLeft ) { 1330 this.element.classList.add('flickity-rtl'); 1331 } 1332
1333 this.getSize(); 1334 // move initial cell elements so they can be loaded as cells 1335 var cellElems = this._filterFindCellElements( this.element.children ); 1336 1337 /* nectar addition */ 1338 if(this.$element.hasClass('generate-markup')) { 1339 moveElements( cellElems, this.slider ); 1340 this.viewport.appendChild( this.slider ); 1341 this.element.appendChild( this.viewport ); 1342 } else { 1343 //do nothing 1344 } 1345 /* nectar addition end */ 1346 1347 // get cells from children 1348 this.reloadCells(); 1349 1350 if ( this.options.accessibility ) { 1351 // allow element to focusable 1352 this.element.tabIndex = 0; 1353 // listen for key presses 1354 this.element.addEventListener( 'keydown', this ); 1355 } 1356 1357 this.emitEvent('activate'); 1358 1359 var index; 1360 var initialIndex = this.options.initialIndex; 1361 if ( this.isInitActivated ) { 1362 index = this.selectedIndex; 1363 } else if ( initialIndex !== undefined ) { 1364 index = this.cells[ initialIndex ] ? initialIndex : 0; 1365 } else { 1366 index = 0; 1367 } 1368 // select instantly 1369 this.select( index, false, true ); 1370 // flag for initial activation, for using initialIndex 1371 this.isInitActivated = true; 1372 // ready event. #493 1373 this.dispatchEvent('ready'); 1374}; 1375 1376// slider positions the cells 1377/* nectar addition */ 1378proto._createSlider = function() { 1379 if(this.$element.hasClass('generate-markup')) { 1380 var slider = document.createElement('div'); 1381 slider.className = 'flickity-slider'; 1382 slider.style[ this.originSide ] = 0; 1383 this.slider = slider; 1384 } else { 1385 // slider element does all the positioning 1386 //var slider = document.createElement('div'); 1387 //slider.className = 'flickity-slider'; 1388 this.slider.style[ this.originSide ] = 0; 1389 // this.slider = slider; 1390 } 1391 1392}; 1393/* nectar addition end */ 1394 1395proto._filterFindCellElements = function( elems ) { 1396 return utils.filterFindElements( elems, this.options.cellSelector ); 1397}; 1398 1399// goes through all children 1400proto.reloadCells = function() { 1401 /* nectar addition */ 1402 1403 if(jQuery(this.slider).parent().parent().find('.flickity-page-dots').length > 0) { 1404 var $that = this; 1405 setTimeout(function(){ 1406 $that.pageDots.setDots(); 1407 },100); 1408 } 1409 var slidesArr = []; 1410 jQuery(this.slider).find('> *').each(function(i){ 1411 slidesArr[i] = jQuery(this)[0]; 1412 }); 1413 1414 1415 // collection of item elements 1416 this.cells = this._makeCells(slidesArr); 1417 /* nectar addition end */ 1418 this.positionCells(); 1419 this._getWrapShiftCells(); 1420 this.setGallerySize(); 1421}; 1422 1423/** 1424 * turn elements into Flickity.Cells 1425 * @param {Array or NodeList or HTMLElement} elems 1426 * @returns {Array} items - collection of new Flickity Cells 1427 */ 1428proto._makeCells = function( elems ) { 1429 var cellElems = this._filterFindCellElements( elems ); 1430 1431 // create new Flickity for collection 1432 var cells = cellElems.map( function( cellElem ) { 1433 return new Cell( cellElem, this ); 1434 }, this ); 1435 1436 return cells; 1437}; 1438 1439proto.getLastCell = function() { 1440 return this.cells[ this.cells.length - 1 ]; 1441}; 1442 1443proto.getLastSlide = function() { 1444 return this.slides[ this.slides.length - 1 ]; 1445}; 1446 1447// positions all cells 1448proto.positionCells = function() { 1449 // size all cells 1450 this._sizeCells( this.cells ); 1451 // position all cells 1452 this._positionCells( 0 ); 1453}; 1454 1455/** 1456 * position certain cells 1457 * @param {Integer} index - which cell to start with 1458 */ 1459proto._positionCells = function( index ) { 1460 index = index || 0; 1461 // also measure maxCellHeight 1462 // start 0 if positioning all cells 1463 this.maxCellHeight = index ? this.maxCellHeight || 0 : 0; 1464 var cellX = 0; 1465 // get cellX 1466 if ( index > 0 ) { 1467 var startCell = this.cells[ index - 1 ]; 1468 cellX = startCell.x + startCell.size.outerWidth; 1469 } 1470 var len = this.cells.length; 1471 for ( var i=index; i < len; i++ ) { 1472 var cell = this.cells[i]; 1473 cell.setPosition( cellX ); 1474 cellX += cell.size.outerWidth; 1475 this.maxCellHeight = Math.max( cell.size.outerHeight, this.maxCellHeight ); 1476 } 1477 // keep track of cellX for wrap-around 1478 this.slideableWidth = cellX; 1479 // slides 1480 this.updateSlides(); 1481 // contain slides target 1482 this._containSlides(); 1483 // update slidesWidth 1484 this.slidesWidth = len ? this.getLastSlide().target - this.slides[0].target : 0; 1485}; 1486 1487/** 1488 * cell.getSize() on multiple cells 1489 * @param {Array} cells 1490 */ 1491proto._sizeCells = function( cells ) {
1492 cells.forEach( function( cell ) { 1493 cell.getSize(); 1494 }); 1495}; 1496 1497// -------------------------- -------------------------- // 1498 1499proto.updateSlides = function() { 1500 this.slides = []; 1501 if ( !this.cells.length ) { 1502 return; 1503 } 1504 1505 var slide = new Slide( this ); 1506 this.slides.push( slide ); 1507 var isOriginLeft = this.originSide == 'left'; 1508 var nextMargin = isOriginLeft ? 'marginRight' : 'marginLeft'; 1509 1510 var canCellFit = this._getCanCellFit(); 1511 1512 this.cells.forEach( function( cell, i ) { 1513 // just add cell if first cell in slide 1514 if ( !slide.cells.length ) { 1515 slide.addCell( cell ); 1516 return; 1517 } 1518 1519 var slideWidth = ( slide.outerWidth - slide.firstMargin ) + 1520 ( cell.size.outerWidth - cell.size[ nextMargin ] ); 1521 1522 if ( canCellFit.call( this, i, slideWidth ) ) { 1523 slide.addCell( cell ); 1524 } else { 1525 // doesn't fit, new slide 1526 slide.updateTarget(); 1527 1528 slide = new Slide( this ); 1529 this.slides.push( slide ); 1530 slide.addCell( cell ); 1531 } 1532 }, this ); 1533 // last slide 1534 slide.updateTarget(); 1535 // update .selectedSlide 1536 this.updateSelectedSlide(); 1537}; 1538 1539proto._getCanCellFit = function() { 1540 var groupCells = this.options.groupCells; 1541 if ( !groupCells ) { 1542 return function() { 1543 return false; 1544 }; 1545 } else if ( typeof groupCells == 'number' ) { 1546 // group by number. 3 -> [0,1,2], [3,4,5], ... 1547 var number = parseInt( groupCells, 10 ); 1548 return function( i ) { 1549 return ( i % number ) !== 0; 1550 }; 1551 } 1552 // default, group by width of slide 1553 // parse '75% 1554 var percentMatch = typeof groupCells == 'string' && 1555 groupCells.match(/^(\d+)%$/); 1556 var percent = percentMatch ? parseInt( percentMatch[1], 10 ) / 100 : 1; 1557 return function( i, slideWidth ) { 1558 return slideWidth <= ( this.size.innerWidth + 1 ) * percent; 1559 }; 1560}; 1561 1562// alias _init for jQuery plugin .flickity() 1563proto._init = 1564proto.reposition = function() { 1565 this.positionCells(); 1566 this.positionSliderAtSelected(); 1567}; 1568 1569proto.getSize = function() { 1570 this.size = getSize( this.element ); 1571 this.setCellAlign(); 1572 this.cursorPosition = this.size.innerWidth * this.cellAlign; 1573}; 1574 1575var cellAlignShorthands = { 1576 // cell align, then based on origin side 1577 center: { 1578 left: 0.5, 1579 right: 0.5 1580 }, 1581 left: { 1582 left: 0, 1583 right: 1 1584 }, 1585 right: { 1586 right: 0, 1587 left: 1 1588 } 1589}; 1590 1591proto.setCellAlign = function() { 1592 var shorthand = cellAlignShorthands[ this.options.cellAlign ]; 1593 this.cellAlign = shorthand ? shorthand[ this.originSide ] : this.options.cellAlign; 1594}; 1595 1596proto.setGallerySize = function() { 1597 if ( this.options.setGallerySize ) { 1598 var height = this.options.adaptiveHeight && this.selectedSlide ? 1599 this.selectedSlide.height : this.maxCellHeight; 1600 this.viewport.style.height = height + 'px'; 1601 } 1602}; 1603 1604proto._getWrapShiftCells = function() { 1605 // only for wrap-around 1606 if ( !this.options.wrapAround ) { 1607 return; 1608 } 1609 // unshift previous cells 1610 this._unshiftCells( this.beforeShiftCells ); 1611 this._unshiftCells( this.afterShiftCells ); 1612 // get before cells 1613 // initial gap 1614 var gapX = this.cursorPosition; 1615 var cellIndex = this.cells.length - 1; 1616 this.beforeShiftCells = this._getGapCells( gapX, cellIndex, -1 ); 1617 // get after cells 1618 // ending gap between last cell and end of gallery viewport 1619 gapX = this.size.innerWidth - this.cursorPosition; 1620 // start cloning at first cell, working forwards 1621 this.afterShiftCells = this._getGapCells( gapX, 0, 1 ); 1622}; 1623 1624proto._getGapCells = function( gapX, cellIndex, increment ) { 1625 // keep adding cells until the cover the initial gap 1626 var cells = []; 1627 while ( gapX > 0 ) { 1628 var cell = this.cells[ cellIndex ]; 1629 if ( !cell ) { 1630 break; 1631 } 1632 cells.push( cell ); 1633 cellIndex += increment; 1634 gapX -= cell.size.outerWidth; 1635 } 1636 return cells; 1637}; 1638 1639// ----- contain ----- // 1640 1641// contain cell targets so no excess sliding 1642proto._containSlides = function() { 1643 if ( !this.options.contain || this.options.wrapAround || !this.cells.length ) { 1644 return; 1645 } 1646 var isRightToLeft = this.options.rightToLeft; 1647 var beginMargin = isRightToLeft ? 'marginRight' : 'marginLeft'; 1648 var endMargin = isRightToLeft ? 'marginLeft' : 'marginRight'; 1649 var contentWidth = this.slideableWidth - this.getLastCell().size[ endMargin ]; 1650 // content is less than gallery size 1651 var isContentSmaller = contentWidth < this.size.innerWidth; 1652 // bounds 1653 var beginBound = this.cursorPosition + this.cells[0].size[ beginMargin ]; 1654 var endBound = contentWidth - this.size.innerWidth * ( 1 - this.cellAlign ); 1655 // contain each cell target
1656 this.slides.forEach( function( slide ) { 1657 if ( isContentSmaller ) { 1658 // all cells fit inside gallery 1659 slide.target = contentWidth * this.cellAlign; 1660 } else { 1661 // contain to bounds 1662 slide.target = Math.max( slide.target, beginBound ); 1663 slide.target = Math.min( slide.target, endBound ); 1664 } 1665 }, this ); 1666}; 1667 1668// ----- ----- // 1669 1670/** 1671 * emits events via eventEmitter and jQuery events 1672 * @param {String} type - name of event 1673 * @param {Event} event - original event 1674 * @param {Array} args - extra arguments 1675 */ 1676proto.dispatchEvent = function( type, event, args ) { 1677 var emitArgs = event ? [ event ].concat( args ) : args; 1678 this.emitEvent( type, emitArgs ); 1679 1680 if ( jQuery && this.$element ) { 1681 // default trigger with type if no event 1682 type += this.options.namespaceJQueryEvents ? '.flickity' : ''; 1683 var $event = type; 1684 if ( event ) { 1685 // create jQuery event 1686 var jQEvent = jQuery.Event( event ); 1687 jQEvent.type = type; 1688 $event = jQEvent; 1689 } 1690 this.$element.trigger( $event, args ); 1691 } 1692}; 1693 1694// -------------------------- select -------------------------- // 1695 1696/** 1697 * @param {Integer} index - index of the slide 1698 * @param {Boolean} isWrap - will wrap-around to last/first if at the end 1699 * @param {Boolean} isInstant - will immediately set position at selected cell 1700 */ 1701proto.select = function( index, isWrap, isInstant ) { 1702 if ( !this.isActive ) { 1703 return; 1704 } 1705 index = parseInt( index, 10 ); 1706 this._wrapSelect( index ); 1707 1708 if ( this.options.wrapAround || isWrap ) { 1709 index = utils.modulo( index, this.slides.length ); 1710 } 1711 // bail if invalid index 1712 if ( !this.slides[ index ] ) { 1713 return; 1714 } 1715 var prevIndex = this.selectedIndex; 1716 this.selectedIndex = index; 1717 this.updateSelectedSlide(); 1718 if ( isInstant ) { 1719 this.positionSliderAtSelected(); 1720 } else { 1721 this.startAnimation(); 1722 } 1723 if ( this.options.adaptiveHeight ) { 1724 this.setGallerySize(); 1725 } 1726 // events 1727 this.dispatchEvent( 'select', null, [ index ] ); 1728 // change event if new index 1729 if ( index != prevIndex ) { 1730 this.dispatchEvent( 'change', null, [ index ] ); 1731 } 1732 // old v1 event name, remove in v3 1733 this.dispatchEvent('cellSelect'); 1734}; 1735 1736// wraps position for wrapAround, to move to closest slide. #113 1737proto._wrapSelect = function( index ) { 1738 var len = this.slides.length; 1739 var isWrapping = this.options.wrapAround && len > 1; 1740 if ( !isWrapping ) { 1741 return index; 1742 } 1743 var wrapIndex = utils.modulo( index, len ); 1744 // go to shortest 1745 var delta = Math.abs( wrapIndex - this.selectedIndex ); 1746 var backWrapDelta = Math.abs( ( wrapIndex + len ) - this.selectedIndex ); 1747 var forewardWrapDelta = Math.abs( ( wrapIndex - len ) - this.selectedIndex ); 1748 if ( !this.isDragSelect && backWrapDelta < delta ) { 1749 index += len; 1750 } else if ( !this.isDragSelect && forewardWrapDelta < delta ) { 1751 index -= len; 1752 } 1753 // wrap position so slider is within normal area 1754 if ( index < 0 ) { 1755 this.x -= this.slideableWidth; 1756 } else if ( index >= len ) { 1757 this.x += this.slideableWidth; 1758 } 1759}; 1760 1761proto.previous = function( isWrap, isInstant ) { 1762 this.select( this.selectedIndex - 1, isWrap, isInstant ); 1763}; 1764 1765proto.next = function( isWrap, isInstant ) { 1766 this.select( this.selectedIndex + 1, isWrap, isInstant ); 1767}; 1768 1769proto.updateSelectedSlide = function() { 1770 var slide = this.slides[ this.selectedIndex ]; 1771 // selectedIndex could be outside of slides, if triggered before resize() 1772 if ( !slide ) { 1773 return; 1774 } 1775 // unselect previous selected slide 1776 this.unselectSelectedSlide(); 1777 // update new selected slide 1778 this.selectedSlide = slide; 1779 slide.select(); 1780 this.selectedCells = slide.cells; 1781 this.selectedElements = slide.getCellElements(); 1782 // HACK: selectedCell & selectedElement is first cell in slide, backwards compatibility 1783 // Remove in v3? 1784 this.selectedCell = slide.cells[0]; 1785 this.selectedElement = this.selectedElements[0]; 1786}; 1787 1788proto.unselectSelectedSlide = function() { 1789 if ( this.selectedSlide ) { 1790 this.selectedSlide.unselect(); 1791 } 1792}; 1793 1794/** 1795 * select slide from number or cell element 1796 * @param {Element or Number} elem 1797 */ 1798proto.selectCell = function( value, isWrap, isInstant ) { 1799 // get cell 1800 var cell = this.queryCell( value ); 1801 if ( !cell ) { 1802 return; 1803 } 1804 1805 var index = this.getCellSlideIndex( cell ); 1806 this.select( index, isWrap, isInstant ); 1807}; 1808 1809proto.getCellSlideIndex = function( cell ) { 1810 // get index of slides that has cell 1811 for ( var i=0; i < this.slides.length; i++ ) { 1812 var slide = this.slides[i];
1813 var index = slide.cells.indexOf( cell ); 1814 if ( index != -1 ) { 1815 return i; 1816 } 1817 } 1818}; 1819 1820// -------------------------- get cells -------------------------- // 1821 1822/** 1823 * get Flickity.Cell, given an Element 1824 * @param {Element} elem 1825 * @returns {Flickity.Cell} item 1826 */ 1827proto.getCell = function( elem ) { 1828 // loop through cells to get the one that matches 1829 for ( var i=0; i < this.cells.length; i++ ) { 1830 var cell = this.cells[i]; 1831 if ( cell.element == elem ) { 1832 return cell; 1833 } 1834 } 1835}; 1836 1837/** 1838 * get collection of Flickity.Cells, given Elements 1839 * @param {Element, Array, NodeList} elems 1840 * @returns {Array} cells - Flickity.Cells 1841 */ 1842proto.getCells = function( elems ) { 1843 elems = utils.makeArray( elems ); 1844 var cells = []; 1845 elems.forEach( function( elem ) { 1846 var cell = this.getCell( elem ); 1847 if ( cell ) { 1848 cells.push( cell ); 1849 } 1850 }, this ); 1851 return cells; 1852}; 1853 1854/** 1855 * get cell elements 1856 * @returns {Array} cellElems 1857 */ 1858proto.getCellElements = function() { 1859 return this.cells.map( function( cell ) { 1860 return cell.element; 1861 }); 1862}; 1863 1864/** 1865 * get parent cell from an element 1866 * @param {Element} elem 1867 * @returns {Flickit.Cell} cell 1868 */ 1869proto.getParentCell = function( elem ) { 1870 // first check if elem is cell 1871 var cell = this.getCell( elem ); 1872 if ( cell ) { 1873 return cell; 1874 } 1875 // try to get parent cell elem 1876 elem = utils.getParent( elem, '.flickity-slider > *' ); 1877 return this.getCell( elem ); 1878}; 1879 1880/** 1881 * get cells adjacent to a slide 1882 * @param {Integer} adjCount - number of adjacent slides 1883 * @param {Integer} index - index of slide to start 1884 * @returns {Array} cells - array of Flickity.Cells 1885 */ 1886proto.getAdjacentCellElements = function( adjCount, index ) { 1887 if ( !adjCount ) { 1888 return this.selectedSlide.getCellElements(); 1889 } 1890 index = index === undefined ? this.selectedIndex : index; 1891 1892 var len = this.slides.length; 1893 if ( 1 + ( adjCount * 2 ) >= len ) { 1894 return this.getCellElements(); 1895 } 1896 1897 var cellElems = []; 1898 for ( var i = index - adjCount; i <= index + adjCount ; i++ ) { 1899 var slideIndex = this.options.wrapAround ? utils.modulo( i, len ) : i; 1900 var slide = this.slides[ slideIndex ]; 1901 if ( slide ) { 1902 cellElems = cellElems.concat( slide.getCellElements() ); 1903 } 1904 } 1905 return cellElems; 1906}; 1907 1908/** 1909 * select slide from number or cell element 1910 * @param {Element, Selector String, or Number} selector 1911 */ 1912proto.queryCell = function( selector ) { 1913 if ( typeof selector == 'number' ) { 1914 // use number as index 1915 return this.cells[ selector ]; 1916 } 1917 if ( typeof selector == 'string' ) { 1918 // use string as selector, get element 1919 selector = this.element.querySelector( selector ); 1920 } 1921 // get cell from element 1922 return this.getCell( selector ); 1923}; 1924 1925// -------------------------- events -------------------------- // 1926 1927proto.uiChange = function() { 1928 this.emitEvent('uiChange'); 1929}; 1930 1931proto.childUIPointerDown = function( event ) { 1932 this.emitEvent( 'childUIPointerDown', [ event ] ); 1933}; 1934 1935// ----- resize ----- // 1936 1937proto.onresize = function() { 1938 this.watchCSS(); 1939 this.resize(); 1940}; 1941 1942utils.debounceMethod( Flickity, 'onresize', 150 ); 1943 1944proto.resize = function() { 1945 if ( !this.isActive ) { 1946 return; 1947 } 1948 this.getSize(); 1949 // wrap values 1950 if ( this.options.wrapAround ) { 1951 this.x = utils.modulo( this.x, this.slideableWidth ); 1952 } 1953 this.positionCells(); 1954 this._getWrapShiftCells(); 1955 this.setGallerySize(); 1956 this.emitEvent('resize'); 1957 // update selected index for group slides, instant 1958 // TODO: position can be lost between groups of various numbers 1959 var selectedElement = this.selectedElements && this.selectedElements[0]; 1960 this.selectCell( selectedElement, false, true ); 1961}; 1962 1963// watches the :after property, activates/deactivates 1964proto.watchCSS = function() { 1965 var watchOption = this.options.watchCSS; 1966 if ( !watchOption ) { 1967 return; 1968 } 1969 1970 var afterContent = getComputedStyle( this.element, ':after' ).content; 1971 // activate if :after { content: 'flickity' } 1972 if ( afterContent.indexOf('flickity') != -1 ) { 1973 this.activate(); 1974 } else { 1975 this.deactivate(); 1976 } 1977}; 1978 1979// ----- keydown ----- // 1980 1981// go previous/next if left/right keys pressed 1982proto.onkeydown = function( event ) {
1983 // only work if element is in focus 1984 var isNotFocused = document.activeElement && document.activeElement != this.element; 1985 if ( !this.options.accessibility ||isNotFocused ) { 1986 return; 1987 } 1988 1989 var handler = Flickity.keyboardHandlers[ event.keyCode ]; 1990 if ( handler ) { 1991 handler.call( this ); 1992 } 1993}; 1994 1995Flickity.keyboardHandlers = { 1996 // left arrow 1997 37: function() { 1998 var leftMethod = this.options.rightToLeft ? 'next' : 'previous'; 1999 this.uiChange(); 2000 this[ leftMethod ](); 2001 }, 2002 // right arrow 2003 39: function() { 2004 var rightMethod = this.options.rightToLeft ? 'previous' : 'next'; 2005 this.uiChange(); 2006 this[ rightMethod ](); 2007 }, 2008}; 2009 2010// ----- focus ----- // 2011 2012proto.focus = function() { 2013 // TODO remove scrollTo once focus options gets more support 2014 // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#Browser_compatibility 2015 var prevScrollY = window.pageYOffset; 2016 this.element.focus({ preventScroll: true }); 2017 // hack to fix scroll jump after focus, #76 2018 if ( window.pageYOffset != prevScrollY && prevScrollY > 10 ) { // nectar addition - iframe fix 2019 window.scrollTo( window.pageXOffset, prevScrollY ); 2020 } 2021}; 2022 2023// -------------------------- destroy -------------------------- // 2024 2025// deactivate all Flickity functionality, but keep stuff available 2026proto.deactivate = function() { 2027 if ( !this.isActive ) { 2028 return; 2029 } 2030 this.element.classList.remove('flickity-enabled'); 2031 this.element.classList.remove('flickity-rtl'); 2032 this.unselectSelectedSlide(); 2033 // destroy cells 2034 this.cells.forEach( function( cell ) { 2035 cell.destroy(); 2036 }); 2037 this.element.removeChild( this.viewport ); 2038 // move child elements back into element 2039 moveElements( this.slider.children, this.element ); 2040 if ( this.options.accessibility ) { 2041 this.element.removeAttribute('tabIndex'); 2042 this.element.removeEventListener( 'keydown', this ); 2043 } 2044 // set flags 2045 this.isActive = false; 2046 this.emitEvent('deactivate'); 2047}; 2048 2049proto.destroy = function() { 2050 this.deactivate(); 2051 window.removeEventListener( 'resize', this ); 2052 this.emitEvent('destroy'); 2053 if ( jQuery && this.$element ) { 2054 jQuery.removeData( this.element, 'flickity' ); 2055 } 2056 delete this.element.flickityGUID; 2057 delete instances[ this.guid ]; 2058}; 2059 2060// -------------------------- prototype -------------------------- // 2061 2062utils.extend( proto, animatePrototype ); 2063 2064// -------------------------- extras -------------------------- // 2065 2066/** 2067 * get Flickity instance from element 2068 * @param {Element} elem 2069 * @returns {Flickity} 2070 */ 2071Flickity.data = function( elem ) { 2072 elem = utils.getQueryElement( elem ); 2073 var id = elem && elem.flickityGUID; 2074 return id && instances[ id ]; 2075}; 2076 2077utils.htmlInit( Flickity, 'flickity' ); 2078 2079if ( jQuery && jQuery.bridget ) { 2080 jQuery.bridget( 'flickity', Flickity ); 2081} 2082 2083// set internal jQuery, for Webpack + jQuery v3, #478 2084Flickity.setJQuery = function( jq ) { 2085 jQuery = jq; 2086}; 2087 2088Flickity.Cell = Cell; 2089 2090return Flickity; 2091 2092})); 2093 2094/*! 2095 * Unipointer v2.3.0 2096 * base class for doing one thing with pointer event 2097 * MIT license 2098 */ 2099 2100/*jshint browser: true, undef: true, unused: true, strict: true */ 2101 2102( function( window, factory ) { 2103 // universal module definition 2104 /* jshint strict: false */ /*global define, module, require */ 2105 if ( typeof define == 'function' && define.amd ) { 2106 // AMD 2107 define( 'unipointer/unipointer',[ 2108 'ev-emitter/ev-emitter' 2109 ], function( EvEmitter ) { 2110 return factory( window, EvEmitter ); 2111 }); 2112 } else if ( typeof module == 'object' && module.exports ) { 2113 // CommonJS 2114 module.exports = factory( 2115 window, 2116 require('ev-emitter') 2117 ); 2118 } else { 2119 // browser global 2120 window.Unipointer = factory( 2121 window, 2122 window.EvEmitter 2123 ); 2124 } 2125 2126}( window, function factory( window, EvEmitter ) { 2127 2128 2129 2130function noop() {} 2131 2132function Unipointer() {} 2133 2134// inherit EvEmitter 2135var proto = Unipointer.prototype = Object.create( EvEmitter.prototype ); 2136 2137proto.bindStartEvent = function( elem ) { 2138 this._bindStartEvent( elem, true ); 2139}; 2140 2141proto.unbindStartEvent = function( elem ) { 2142 this._bindStartEvent( elem, false ); 2143}; 2144 2145/** 2146 * Add or remove start event 2147 * @param {Boolean} isAdd - remove if falsey 2148 */ 2149proto._bindStartEvent = function( elem, isAdd ) { 2150 // munge isAdd, default to true 2151 isAdd = isAdd === undefined ? true : isAdd;
vendor: 7,271 bytes, lines 2152-2456
2152 var bindMethod = isAdd ? 'addEventListener' : 'removeEventListener'; 2153 2154 // default to mouse events 2155 var startEvent = 'mousedown'; 2156 if ( window.PointerEvent ) { 2157 // Pointer Events 2158 startEvent = 'pointerdown'; 2159 } else if ( 'ontouchstart' in window ) { 2160 // Touch Events. iOS Safari 2161 startEvent = 'touchstart'; 2162 } 2163 elem[ bindMethod ]( startEvent, this ); 2164}; 2165 2166// trigger handler methods for events 2167proto.handleEvent = function( event ) { 2168 var method = 'on' + event.type; 2169 if ( this[ method ] ) { 2170 this[ method ]( event ); 2171 } 2172}; 2173 2174// returns the touch that we're keeping track of 2175proto.getTouch = function( touches ) { 2176 for ( var i=0; i < touches.length; i++ ) { 2177 var touch = touches[i]; 2178 if ( touch.identifier == this.pointerIdentifier ) { 2179 return touch; 2180 } 2181 } 2182}; 2183 2184// ----- start event ----- // 2185 2186proto.onmousedown = function( event ) { 2187 // dismiss clicks from right or middle buttons 2188 var button = event.button; 2189 if ( button && ( button !== 0 && button !== 1 ) ) { 2190 return; 2191 } 2192 this._pointerDown( event, event ); 2193}; 2194 2195proto.ontouchstart = function( event ) { 2196 this._pointerDown( event, event.changedTouches[0] ); 2197}; 2198 2199proto.onpointerdown = function( event ) { 2200 this._pointerDown( event, event ); 2201}; 2202 2203/** 2204 * pointer start 2205 * @param {Event} event 2206 * @param {Event or Touch} pointer 2207 */ 2208proto._pointerDown = function( event, pointer ) { 2209 // dismiss right click and other pointers 2210 // button = 0 is okay, 1-4 not 2211 if ( event.button || this.isPointerDown ) { 2212 return; 2213 } 2214 2215 this.isPointerDown = true; 2216 // save pointer identifier to match up touch events 2217 this.pointerIdentifier = pointer.pointerId !== undefined ? 2218 // pointerId for pointer events, touch.indentifier for touch events 2219 pointer.pointerId : pointer.identifier; 2220 2221 this.pointerDown( event, pointer ); 2222}; 2223 2224proto.pointerDown = function( event, pointer ) { 2225 this._bindPostStartEvents( event ); 2226 this.emitEvent( 'pointerDown', [ event, pointer ] ); 2227}; 2228 2229// hash of events to be bound after start event 2230var postStartEvents = { 2231 mousedown: [ 'mousemove', 'mouseup' ], 2232 touchstart: [ 'touchmove', 'touchend', 'touchcancel' ], 2233 pointerdown: [ 'pointermove', 'pointerup', 'pointercancel' ], 2234}; 2235 2236proto._bindPostStartEvents = function( event ) { 2237 if ( !event ) { 2238 return; 2239 } 2240 // get proper events to match start event 2241 var events = postStartEvents[ event.type ]; 2242 // bind events to node 2243 events.forEach( function( eventName ) { 2244 window.addEventListener( eventName, this ); 2245 }, this ); 2246 // save these arguments 2247 this._boundPointerEvents = events; 2248}; 2249 2250proto._unbindPostStartEvents = function() { 2251 // check for _boundEvents, in case dragEnd triggered twice (old IE8 bug) 2252 if ( !this._boundPointerEvents ) { 2253 return; 2254 } 2255 this._boundPointerEvents.forEach( function( eventName ) { 2256 window.removeEventListener( eventName, this ); 2257 }, this ); 2258 2259 delete this._boundPointerEvents; 2260}; 2261 2262// ----- move event ----- // 2263 2264proto.onmousemove = function( event ) { 2265 this._pointerMove( event, event ); 2266}; 2267 2268proto.onpointermove = function( event ) { 2269 if ( event.pointerId == this.pointerIdentifier ) { 2270 this._pointerMove( event, event ); 2271 } 2272}; 2273 2274proto.ontouchmove = function( event ) { 2275 var touch = this.getTouch( event.changedTouches ); 2276 if ( touch ) { 2277 this._pointerMove( event, touch ); 2278 } 2279}; 2280 2281/** 2282 * pointer move 2283 * @param {Event} event 2284 * @param {Event or Touch} pointer 2285 * @private 2286 */ 2287proto._pointerMove = function( event, pointer ) { 2288 this.pointerMove( event, pointer ); 2289}; 2290 2291// public 2292proto.pointerMove = function( event, pointer ) { 2293 this.emitEvent( 'pointerMove', [ event, pointer ] ); 2294}; 2295 2296// ----- end event ----- // 2297 2298 2299proto.onmouseup = function( event ) { 2300 this._pointerUp( event, event ); 2301}; 2302 2303proto.onpointerup = function( event ) { 2304 if ( event.pointerId == this.pointerIdentifier ) { 2305 this._pointerUp( event, event ); 2306 } 2307}; 2308 2309proto.ontouchend = function( event ) { 2310 var touch = this.getTouch( event.changedTouches ); 2311 if ( touch ) { 2312 this._pointerUp( event, touch ); 2313 } 2314}; 2315 2316/** 2317 * pointer up 2318 * @param {Event} event 2319 * @param {Event or Touch} pointer 2320 * @private 2321 */ 2322proto._pointerUp = function( event, pointer ) { 2323 this._pointerDone(); 2324 this.pointerUp( event, pointer ); 2325}; 2326 2327// public 2328proto.pointerUp = function( event, pointer ) { 2329 this.emitEvent( 'pointerUp', [ event, pointer ] ); 2330}; 2331 2332// ----- pointer done ----- // 2333 2334// triggered on pointer up & pointer cancel 2335proto._pointerDone = function() { 2336 this._pointerReset(); 2337 this._unbindPostStartEvents(); 2338 this.pointerDone(); 2339}; 2340 2341proto._pointerReset = function() { 2342 // reset properties 2343 this.isPointerDown = false; 2344 delete this.pointerIdentifier; 2345}; 2346 2347proto.pointerDone = noop; 2348 2349// ----- pointer cancel ----- // 2350 2351proto.onpointercancel = function( event ) { 2352 if ( event.pointerId == this.pointerIdentifier ) { 2353 this._pointerCancel( event, event ); 2354 } 2355}; 2356 2357proto.ontouchcancel = function( event ) { 2358 var touch = this.getTouch( event.changedTouches ); 2359 if ( touch ) { 2360 this._pointerCancel( event, touch ); 2361 } 2362}; 2363 2364/** 2365 * pointer cancel 2366 * @param {Event} event 2367 * @param {Event or Touch} pointer 2368 * @private 2369 */ 2370proto._pointerCancel = function( event, pointer ) { 2371 this._pointerDone(); 2372 this.pointerCancel( event, pointer ); 2373}; 2374 2375// public 2376proto.pointerCancel = function( event, pointer ) { 2377 this.emitEvent( 'pointerCancel', [ event, pointer ] ); 2378}; 2379 2380// ----- ----- // 2381 2382// utility function for getting x/y coords from event 2383Unipointer.getPointerPoint = function( pointer ) { 2384 return { 2385 x: pointer.pageX, 2386 y: pointer.pageY 2387 }; 2388}; 2389 2390// ----- ----- // 2391 2392return Unipointer; 2393 2394})); 2395 2396/*! 2397 * Unidragger v2.3.0 2398 * Draggable base class 2399 * MIT license 2400 */ 2401 2402/*jshint browser: true, unused: true, undef: true, strict: true */ 2403 2404( function( window, factory ) { 2405 // universal module definition 2406 /*jshint strict: false */ /*globals define, module, require */ 2407 2408 if ( typeof define == 'function' && define.amd ) { 2409 // AMD 2410 define( 'unidragger/unidragger',[ 2411 'unipointer/unipointer' 2412 ], function( Unipointer ) { 2413 return factory( window, Unipointer ); 2414 }); 2415 } else if ( typeof module == 'object' && module.exports ) { 2416 // CommonJS 2417 module.exports = factory( 2418 window, 2419 require('unipointer') 2420 ); 2421 } else { 2422 // browser global 2423 window.Unidragger = factory( 2424 window, 2425 window.Unipointer 2426 ); 2427 } 2428 2429}( window, function factory( window, Unipointer ) { 2430 2431 2432 2433// -------------------------- Unidragger -------------------------- // 2434 2435function Unidragger() {} 2436 2437// inherit Unipointer & EvEmitter 2438var proto = Unidragger.prototype = Object.create( Unipointer.prototype ); 2439 2440// ----- bind start ----- // 2441 2442proto.bindHandles = function() { 2443 this._bindHandles( true ); 2444}; 2445 2446proto.unbindHandles = function() { 2447 this._bindHandles( false ); 2448}; 2449 2450/** 2451 * Add or remove start event 2452 * @param {Boolean} isAdd 2453 */ 2454proto._bindHandles = function( isAdd ) { 2455 // munge isAdd, default to true 2456 isAdd = isAdd === undefined ? true : isAdd;
vendor: 3,706 bytes, lines 2457-2592
2457 // bind each handle 2458 var bindMethod = isAdd ? 'addEventListener' : 'removeEventListener'; 2459 var touchAction = isAdd ? this._touchActionValue : ''; 2460 for ( var i=0; i < this.handles.length; i++ ) { 2461 var handle = this.handles[i]; 2462 this._bindStartEvent( handle, isAdd ); 2463 handle[ bindMethod ]( 'click', this ); 2464 // touch-action: none to override browser touch gestures. metafizzy/flickity#540 2465 if ( window.PointerEvent ) { 2466 handle.style.touchAction = touchAction; 2467 } 2468 } 2469}; 2470 2471// prototype so it can be overwriteable by Flickity 2472proto._touchActionValue = 'none'; 2473 2474// ----- start event ----- // 2475 2476/** 2477 * pointer start 2478 * @param {Event} event 2479 * @param {Event or Touch} pointer 2480 */ 2481proto.pointerDown = function( event, pointer ) { 2482 var isOkay = this.okayPointerDown( event ); 2483 if ( !isOkay ) { 2484 return; 2485 } 2486 // track start event position 2487 this.pointerDownPointer = pointer; 2488 2489 event.preventDefault(); 2490 this.pointerDownBlur(); 2491 // bind move and end events 2492 this._bindPostStartEvents( event ); 2493 this.emitEvent( 'pointerDown', [ event, pointer ] ); 2494}; 2495 2496// nodes that have text fields 2497var cursorNodes = { 2498 TEXTAREA: true, 2499 INPUT: true, 2500 SELECT: true, 2501 OPTION: true, 2502}; 2503 2504// input types that do not have text fields 2505var clickTypes = { 2506 radio: true, 2507 checkbox: true, 2508 button: true, 2509 submit: true, 2510 image: true, 2511 file: true, 2512}; 2513 2514// dismiss inputs with text fields. flickity#403, flickity#404 2515proto.okayPointerDown = function( event ) { 2516 var isCursorNode = cursorNodes[ event.target.nodeName ]; 2517 var isClickType = clickTypes[ event.target.type ]; 2518 var isOkay = !isCursorNode || isClickType; 2519 if ( !isOkay ) { 2520 this._pointerReset(); 2521 } 2522 return isOkay; 2523}; 2524 2525// kludge to blur previously focused input 2526proto.pointerDownBlur = function() { 2527 var focused = document.activeElement; 2528 // do not blur body for IE10, metafizzy/flickity#117 2529 var canBlur = focused && focused.blur && focused != document.body; 2530 if ( canBlur ) { 2531 focused.blur(); 2532 } 2533}; 2534 2535// ----- move event ----- // 2536 2537/** 2538 * drag move 2539 * @param {Event} event 2540 * @param {Event or Touch} pointer 2541 */ 2542proto.pointerMove = function( event, pointer ) { 2543 var moveVector = this._dragPointerMove( event, pointer ); 2544 this.emitEvent( 'pointerMove', [ event, pointer, moveVector ] ); 2545 this._dragMove( event, pointer, moveVector ); 2546}; 2547 2548// base pointer move logic 2549proto._dragPointerMove = function( event, pointer ) { 2550 var moveVector = { 2551 x: pointer.pageX - this.pointerDownPointer.pageX, 2552 y: pointer.pageY - this.pointerDownPointer.pageY 2553 }; 2554 // start drag if pointer has moved far enough to start drag 2555 if ( !this.isDragging && this.hasDragStarted( moveVector ) ) { 2556 this._dragStart( event, pointer ); 2557 } 2558 return moveVector; 2559}; 2560 2561// condition if pointer has moved far enough to start drag 2562proto.hasDragStarted = function( moveVector ) { 2563 return Math.abs( moveVector.x ) > 3 || Math.abs( moveVector.y ) > 3; 2564}; 2565 2566// ----- end event ----- // 2567 2568/** 2569 * pointer up 2570 * @param {Event} event 2571 * @param {Event or Touch} pointer 2572 */ 2573proto.pointerUp = function( event, pointer ) { 2574 this.emitEvent( 'pointerUp', [ event, pointer ] ); 2575 this._dragPointerUp( event, pointer ); 2576}; 2577 2578proto._dragPointerUp = function( event, pointer ) { 2579 if ( this.isDragging ) { 2580 this._dragEnd( event, pointer ); 2581 } else { 2582 // pointer didn't move enough for drag to start 2583 this._staticClick( event, pointer ); 2584 } 2585}; 2586 2587// -------------------------- drag -------------------------- // 2588 2589// dragStart 2590proto._dragStart = function( event, pointer ) { 2591 this.isDragging = true; 2592 // prevent clicks
2593 this.isPreventingClicks = true; 2594 this.dragStart( event, pointer ); 2595}; 2596 2597proto.dragStart = function( event, pointer ) { 2598 this.emitEvent( 'dragStart', [ event, pointer ] ); 2599}; 2600 2601// dragMove 2602proto._dragMove = function( event, pointer, moveVector ) { 2603 // do not drag if not dragging yet 2604 if ( !this.isDragging ) { 2605 return; 2606 } 2607 2608 this.dragMove( event, pointer, moveVector ); 2609}; 2610 2611proto.dragMove = function( event, pointer, moveVector ) { 2612 event.preventDefault(); 2613 this.emitEvent( 'dragMove', [ event, pointer, moveVector ] ); 2614}; 2615 2616// dragEnd 2617proto._dragEnd = function( event, pointer ) { 2618 // set flags 2619 this.isDragging = false; 2620 // re-enable clicking async 2621 setTimeout( function() { 2622 delete this.isPreventingClicks; 2623 }.bind( this ) ); 2624 2625 this.dragEnd( event, pointer ); 2626}; 2627 2628proto.dragEnd = function( event, pointer ) { 2629 this.emitEvent( 'dragEnd', [ event, pointer ] ); 2630}; 2631 2632// ----- onclick ----- // 2633 2634// handle all clicks and prevent clicks when dragging 2635proto.onclick = function( event ) {
2636 if ( this.isPreventingClicks ) { 2637 event.preventDefault(); 2638 } 2639}; 2640 2641// ----- staticClick ----- // 2642 2643// triggered after pointer down & up with no/tiny movement 2644proto._staticClick = function( event, pointer ) { 2645 // ignore emulated mouse up clicks 2646 if ( this.isIgnoringMouseUp && event.type == 'mouseup' ) { 2647 return; 2648 } 2649 2650 this.staticClick( event, pointer ); 2651 2652 // set flag for emulated clicks 300ms after touchend 2653 if ( event.type != 'mouseup' ) { 2654 this.isIgnoringMouseUp = true; 2655 // reset flag after 300ms 2656 setTimeout( function() { 2657 delete this.isIgnoringMouseUp; 2658 }.bind( this ), 400 ); 2659 } 2660}; 2661 2662proto.staticClick = function( event, pointer ) { 2663 this.emitEvent( 'staticClick', [ event, pointer ] ); 2664}; 2665 2666// ----- utils ----- // 2667 2668Unidragger.getPointerPoint = Unipointer.getPointerPoint; 2669 2670// ----- ----- // 2671 2672return Unidragger; 2673 2674})); 2675 2676// drag 2677( function( window, factory ) { 2678 // universal module definition 2679 /* jshint strict: false */ 2680 if ( typeof define == 'function' && define.amd ) { 2681 // AMD 2682 define( 'flickity/js/drag',[ 2683 './flickity', 2684 'unidragger/unidragger', 2685 'fizzy-ui-utils/utils' 2686 ], function( Flickity, Unidragger, utils ) { 2687 return factory( window, Flickity, Unidragger, utils ); 2688 }); 2689 } else if ( typeof module == 'object' && module.exports ) { 2690 // CommonJS 2691 module.exports = factory( 2692 window, 2693 require('./flickity'), 2694 require('unidragger'), 2695 require('fizzy-ui-utils') 2696 ); 2697 } else { 2698 // browser global 2699 window.Flickity = factory( 2700 window, 2701 window.Flickity, 2702 window.Unidragger, 2703 window.fizzyUIUtils 2704 ); 2705 } 2706 2707}( window, function factory( window, Flickity, Unidragger, utils ) { 2708 2709 2710 2711// ----- defaults ----- // 2712 2713utils.extend( Flickity.defaults, { 2714 draggable: '>1', 2715 dragThreshold: 3, 2716}); 2717 2718// ----- create ----- // 2719 2720Flickity.createMethods.push('_createDrag'); 2721 2722// -------------------------- drag prototype -------------------------- // 2723 2724var proto = Flickity.prototype; 2725utils.extend( proto, Unidragger.prototype ); 2726proto._touchActionValue = 'pan-y'; 2727 2728// -------------------------- -------------------------- // 2729 2730var isTouch = 'createTouch' in document; 2731var isTouchmoveScrollCanceled = false; 2732 2733proto._createDrag = function() { 2734 this.on( 'activate', this.onActivateDrag ); 2735 this.on( 'uiChange', this._uiChangeDrag ); 2736 this.on( 'childUIPointerDown', this._childUIPointerDownDrag ); 2737 this.on( 'deactivate', this.onDeactivateDrag ); 2738 this.on( 'cellChange', this.updateDraggable ); 2739 // TODO updateDraggable on resize? if groupCells & slides change 2740 // HACK - add seemingly innocuous handler to fix iOS 10 scroll behavior 2741 // #457, RubaXa/Sortable#973 2742 if ( isTouch && !isTouchmoveScrollCanceled ) { 2743 window.addEventListener( 'touchmove', function() {}); 2744 isTouchmoveScrollCanceled = true; 2745 } 2746}; 2747 2748proto.onActivateDrag = function() { 2749 this.handles = [ this.viewport ]; 2750 this.bindHandles(); 2751 this.updateDraggable(); 2752}; 2753 2754proto.onDeactivateDrag = function() { 2755 this.unbindHandles(); 2756 this.element.classList.remove('is-draggable'); 2757};
vendor: 4,786 bytes, lines 2758-2925
2758 2759proto.updateDraggable = function() { 2760 // disable dragging if less than 2 slides. #278 2761 if ( this.options.draggable == '>1' ) { 2762 this.isDraggable = this.slides.length > 1; 2763 } else { 2764 this.isDraggable = this.options.draggable; 2765 } 2766 if ( this.isDraggable ) { 2767 this.element.classList.add('is-draggable'); 2768 } else { 2769 this.element.classList.remove('is-draggable'); 2770 } 2771}; 2772 2773// backwards compatibility 2774proto.bindDrag = function() { 2775 this.options.draggable = true; 2776 this.updateDraggable(); 2777}; 2778 2779proto.unbindDrag = function() { 2780 this.options.draggable = false; 2781 this.updateDraggable(); 2782}; 2783 2784proto._uiChangeDrag = function() { 2785 delete this.isFreeScrolling; 2786}; 2787 2788proto._childUIPointerDownDrag = function( event ) { 2789 // allow focus & preventDefault even when not draggable 2790 // so child UI elements keep focus on carousel. #721 2791 event.preventDefault(); 2792 this.pointerDownFocus( event ); 2793}; 2794 2795// -------------------------- pointer events -------------------------- // 2796 2797proto.pointerDown = function( event, pointer ) { 2798 if ( !this.isDraggable ) { 2799 this._pointerDownDefault( event, pointer ); 2800 return; 2801 } 2802 var isOkay = this.okayPointerDown( event ); 2803 if ( !isOkay ) { 2804 return; 2805 } 2806 2807 this._pointerDownPreventDefault( event ); 2808 this.pointerDownFocus( event ); 2809 // blur 2810 if ( document.activeElement != this.element ) { 2811 // do not blur if already focused 2812 this.pointerDownBlur(); 2813 } 2814 2815 // stop if it was moving 2816 this.dragX = this.x; 2817 this.viewport.classList.add('is-pointer-down'); 2818 // track scrolling 2819 this.pointerDownScroll = getScrollPosition(); 2820 window.addEventListener( 'scroll', this ); 2821 2822 this._pointerDownDefault( event, pointer ); 2823}; 2824 2825// default pointerDown logic, used for staticClick 2826proto._pointerDownDefault = function( event, pointer ) { 2827 // track start event position 2828 this.pointerDownPointer = pointer; 2829 // bind move and end events 2830 this._bindPostStartEvents( event ); 2831 this.dispatchEvent( 'pointerDown', event, [ pointer ] ); 2832}; 2833 2834var focusNodes = { 2835 INPUT: true, 2836 TEXTAREA: true, 2837 SELECT: true, 2838}; 2839 2840proto.pointerDownFocus = function( event ) { 2841 var isFocusNode = focusNodes[ event.target.nodeName ]; 2842 if ( !isFocusNode ) { 2843 this.focus(); 2844 } 2845}; 2846 2847proto._pointerDownPreventDefault = function( event ) { 2848 var isTouchStart = event.type == 'touchstart'; 2849 var isTouchPointer = event.pointerType == 'touch'; 2850 var isFocusNode = focusNodes[ event.target.nodeName ]; 2851 if ( !isTouchStart && !isTouchPointer && !isFocusNode ) { 2852 event.preventDefault(); 2853 } 2854}; 2855 2856// ----- move ----- // 2857 2858proto.hasDragStarted = function( moveVector ) { 2859 return Math.abs( moveVector.x ) > this.options.dragThreshold; 2860}; 2861 2862// ----- up ----- // 2863 2864proto.pointerUp = function( event, pointer ) { 2865 delete this.isTouchScrolling; 2866 this.viewport.classList.remove('is-pointer-down'); 2867 this.dispatchEvent( 'pointerUp', event, [ pointer ] ); 2868 this._dragPointerUp( event, pointer ); 2869}; 2870 2871proto.pointerDone = function() { 2872 window.removeEventListener( 'scroll', this ); 2873 delete this.pointerDownScroll; 2874}; 2875 2876// -------------------------- dragging -------------------------- // 2877 2878proto.dragStart = function( event, pointer ) { 2879 if ( !this.isDraggable ) { 2880 return; 2881 } 2882 this.dragStartPosition = this.x; 2883 this.startAnimation(); 2884 window.removeEventListener( 'scroll', this ); 2885 this.dispatchEvent( 'dragStart', event, [ pointer ] ); 2886}; 2887 2888proto.pointerMove = function( event, pointer ) { 2889 var moveVector = this._dragPointerMove( event, pointer ); 2890 this.dispatchEvent( 'pointerMove', event, [ pointer, moveVector ] ); 2891 this._dragMove( event, pointer, moveVector ); 2892}; 2893 2894proto.dragMove = function( event, pointer, moveVector ) { 2895 if ( !this.isDraggable ) { 2896 return; 2897 } 2898 event.preventDefault(); 2899 2900 // reverse if right-to-left 2901 var direction = this.options.rightToLeft ? -1 : 1; 2902 if ( this.options.wrapAround ) { 2903 // wrap around move. #589 2904 moveVector.x = moveVector.x % this.slideableWidth; 2905 } 2906 var dragX = this.dragStartPosition + moveVector.x * direction; 2907 2908 if ( !this.options.wrapAround && this.slides.length ) { 2909 // slow drag 2910 var originBound = Math.max( -this.slides[0].target, this.dragStartPosition ); 2911 dragX = dragX > originBound ? ( dragX + originBound ) * 0.5 : dragX; 2912 var endBound = Math.min( -this.getLastSlide().target, this.dragStartPosition ); 2913 dragX = dragX < endBound ? ( dragX + endBound ) * 0.5 : dragX; 2914 } 2915 2916 // nectar addition ios13 bugfix 2917 if ( this.dragX !== dragX ) { 2918 this.previousDragX = this.dragX; 2919 } 2920 2921 this.dragX = dragX; 2922 2923 this.dragMoveTime = new Date(); 2924 this.dispatchEvent( 'dragMove', event, [ pointer, moveVector ] ); 2925};
2926 2927proto.dragEnd = function( event, pointer ) { 2928 if ( !this.isDraggable ) { 2929 return; 2930 } 2931 if ( this.options.freeScroll ) { 2932 this.isFreeScrolling = true; 2933 } 2934 // set selectedIndex based on where flick will end up 2935 var index = this.dragEndRestingSelect(); 2936 2937 if ( this.options.freeScroll && !this.options.wrapAround ) { 2938 // if free-scroll & not wrap around 2939 // do not free-scroll if going outside of bounding slides 2940 // so bounding slides can attract slider, and keep it in bounds 2941 var restingX = this.getRestingPosition(); 2942 this.isFreeScrolling = -restingX > this.slides[0].target && 2943 -restingX < this.getLastSlide().target; 2944 } else if ( !this.options.freeScroll && index == this.selectedIndex ) { 2945 // boost selection if selected index has not changed 2946 index += this.dragEndBoostSelect(); 2947 } 2948 delete this.previousDragX; 2949 // apply selection 2950 // TODO refactor this, selecting here feels weird 2951 // HACK, set flag so dragging stays in correct direction 2952 this.isDragSelect = this.options.wrapAround; 2953 this.select( index ); 2954 delete this.isDragSelect; 2955 this.dispatchEvent( 'dragEnd', event, [ pointer ] ); 2956}; 2957 2958proto.dragEndRestingSelect = function() { 2959 var restingX = this.getRestingPosition(); 2960 // how far away from selected slide 2961 var distance = Math.abs( this.getSlideDistance( -restingX, this.selectedIndex ) ); 2962 // get closet resting going up and going down 2963 var positiveResting = this._getClosestResting( restingX, distance, 1 ); 2964 var negativeResting = this._getClosestResting( restingX, distance, -1 ); 2965 // use closer resting for wrap-around 2966 var index = positiveResting.distance < negativeResting.distance ? 2967 positiveResting.index : negativeResting.index; 2968 return index; 2969}; 2970 2971/** 2972 * given resting X and distance to selected cell 2973 * get the distance and index of the closest cell 2974 * @param {Number} restingX - estimated post-flick resting position 2975 * @param {Number} distance - distance to selected cell 2976 * @param {Integer} increment - +1 or -1, going up or down 2977 * @returns {Object} - { distance: {Number}, index: {Integer} } 2978 */ 2979proto._getClosestResting = function( restingX, distance, increment ) { 2980 var index = this.selectedIndex; 2981 var minDistance = Infinity; 2982 var condition = this.options.contain && !this.options.wrapAround ? 2983 // if contain, keep going if distance is equal to minDistance 2984 function( d, md ) { return d <= md; } : function( d, md ) { return d < md; }; 2985 while ( condition( distance, minDistance ) ) { 2986 // measure distance to next cell 2987 index += increment; 2988 minDistance = distance; 2989 distance = this.getSlideDistance( -restingX, index ); 2990 if ( distance === null ) { 2991 break; 2992 } 2993 distance = Math.abs( distance ); 2994 } 2995 return { 2996 distance: minDistance, 2997 // selected was previous index 2998 index: index - increment 2999 }; 3000}; 3001 3002/** 3003 * measure distance between x and a slide target 3004 * @param {Number} x 3005 * @param {Integer} index - slide index 3006 */ 3007proto.getSlideDistance = function( x, index ) { 3008 var len = this.slides.length; 3009 // wrap around if at least 2 slides 3010 var isWrapAround = this.options.wrapAround && len > 1; 3011 var slideIndex = isWrapAround ? utils.modulo( index, len ) : index; 3012 var slide = this.slides[ slideIndex ]; 3013 if ( !slide ) { 3014 return null; 3015 } 3016 // add distance for wrap-around slides 3017 var wrap = isWrapAround ? this.slideableWidth * Math.floor( index / len ) : 0; 3018 return x - ( slide.target + wrap ); 3019};
3020 3021proto.dragEndBoostSelect = function() { 3022 // do not boost if no previousDragX or dragMoveTime 3023 if ( this.previousDragX === undefined || !this.dragMoveTime || 3024 // or if drag was held for 100 ms 3025 new Date() - this.dragMoveTime > 100 ) { 3026 return 0; 3027 } 3028 3029 var distance = this.getSlideDistance( -this.dragX, this.selectedIndex ); 3030 var delta = this.previousDragX - this.dragX; 3031 if ( distance > 0 && delta > 0 ) { 3032 // boost to next if moving towards the right, and positive velocity 3033 return 1; 3034 } else if ( distance < 0 && delta < 0 ) { 3035 // boost to previous if moving towards the left, and negative velocity 3036 return -1; 3037 } 3038 return 0; 3039}; 3040 3041// ----- staticClick ----- // 3042 3043proto.staticClick = function( event, pointer ) { 3044 // get clickedCell, if cell was clicked 3045 var clickedCell = this.getParentCell( event.target ); 3046 var cellElem = clickedCell && clickedCell.element; 3047 var cellIndex = clickedCell && this.cells.indexOf( clickedCell ); 3048 this.dispatchEvent( 'staticClick', event, [ pointer, cellElem, cellIndex ] ); 3049}; 3050 3051// ----- scroll ----- // 3052 3053proto.onscroll = function() { 3054 var scroll = getScrollPosition(); 3055 var scrollMoveX = this.pointerDownScroll.x - scroll.x; 3056 var scrollMoveY = this.pointerDownScroll.y - scroll.y; 3057 // cancel click/tap if scroll is too much 3058 if ( Math.abs( scrollMoveX ) > 3 || Math.abs( scrollMoveY ) > 3 ) { 3059 this._pointerDone(); 3060 } 3061}; 3062 3063// ----- utils ----- // 3064 3065function getScrollPosition() { 3066 return { 3067 x: window.pageXOffset, 3068 y: window.pageYOffset 3069 }; 3070} 3071 3072// ----- ----- // 3073 3074return Flickity; 3075 3076})); 3077 3078/*! 3079 * Tap listener v2.0.0 3080 * listens to taps 3081 * MIT license 3082 */ 3083 3084/*jshint browser: true, unused: true, undef: true, strict: true */ 3085 3086( function( window, factory ) { 3087 // universal module definition 3088 /*jshint strict: false*/ /*globals define, module, require */ 3089 3090 if ( typeof define == 'function' && define.amd ) { 3091 // AMD 3092 define( 'tap-listener/tap-listener',[ 3093 'unipointer/unipointer' 3094 ], function( Unipointer ) { 3095 return factory( window, Unipointer ); 3096 }); 3097 } else if ( typeof module == 'object' && module.exports ) { 3098 // CommonJS 3099 module.exports = factory( 3100 window, 3101 require('unipointer') 3102 ); 3103 } else { 3104 // browser global 3105 window.TapListener = factory( 3106 window, 3107 window.Unipointer 3108 ); 3109 } 3110 3111}( window, function factory( window, Unipointer ) { 3112 3113 3114 3115// -------------------------- TapListener -------------------------- // 3116 3117function TapListener( elem ) { 3118 this.bindTap( elem ); 3119} 3120 3121// inherit Unipointer & EventEmitter 3122var proto = TapListener.prototype = Object.create( Unipointer.prototype ); 3123 3124/** 3125 * bind tap event to element 3126 * @param {Element} elem 3127 */ 3128proto.bindTap = function( elem ) { 3129 if ( !elem ) { 3130 return; 3131 } 3132 this.unbindTap(); 3133 this.tapElement = elem; 3134 this._bindStartEvent( elem, true ); 3135}; 3136 3137proto.unbindTap = function() { 3138 if ( !this.tapElement ) { 3139 return; 3140 } 3141 this._bindStartEvent( this.tapElement, true ); 3142 delete this.tapElement; 3143}; 3144 3145/** 3146 * pointer up 3147 * @param {Event} event 3148 * @param {Event or Touch} pointer 3149 */ 3150proto.pointerUp = function( event, pointer ) { 3151 // ignore emulated mouse up clicks 3152 if ( this.isIgnoringMouseUp && event.type == 'mouseup' ) { 3153 return; 3154 } 3155 3156 var pointerPoint = Unipointer.getPointerPoint( pointer ); 3157 var boundingRect = this.tapElement.getBoundingClientRect(); 3158 var scrollX = window.pageXOffset; 3159 var scrollY = window.pageYOffset; 3160 // calculate if pointer is inside tapElement 3161 var isInside = pointerPoint.x >
3161= boundingRect.left + scrollX && 3162 pointerPoint.x <= boundingRect.right + scrollX && 3163 pointerPoint.y >= boundingRect.top + scrollY && 3164 pointerPoint.y <= boundingRect.bottom + scrollY; 3165 // trigger callback if pointer is inside element 3166 if ( isInside ) { 3167 this.emitEvent( 'tap', [ event, pointer ] ); 3168 } 3169 3170 // set flag for emulated clicks 300ms after touchend 3171 if ( event.type != 'mouseup' ) { 3172 this.isIgnoringMouseUp = true; 3173 // reset flag after 300ms 3174 var _this = this; 3175 setTimeout( function() { 3176 delete _this.isIgnoringMouseUp; 3177 }, 400 ); 3178 } 3179}; 3180 3181proto.destroy = function() { 3182 this.pointerDone(); 3183 this.unbindTap(); 3184}; 3185 3186// ----- ----- // 3187 3188return TapListener; 3189 3190})); 3191 3192// prev/next buttons 3193( function( window, factory ) { 3194 // universal module definition 3195 /* jshint strict: false */ 3196 if ( typeof define == 'function' && define.amd ) { 3197 // AMD 3198 define( 'flickity/js/prev-next-button',[ 3199 './flickity', 3200 'tap-listener/tap-listener', 3201 'fizzy-ui-utils/utils' 3202 ], function( Flickity, TapListener, utils ) { 3203 return factory( window, Flickity, TapListener, utils ); 3204 }); 3205 } else if ( typeof module == 'object' && module.exports ) { 3206 // CommonJS 3207 module.exports = factory( 3208 window, 3209 require('./flickity'), 3210 require('tap-listener'), 3211 require('fizzy-ui-utils') 3212 ); 3213 } else { 3214 // browser global 3215 factory( 3216 window, 3217 window.Flickity, 3218 window.TapListener, 3219 window.fizzyUIUtils 3220 ); 3221 } 3222 3223}( window, function factory( window, Flickity, TapListener, utils ) { 3224'use strict'; 3225 3226var svgURI = 'http://www.w3.org/2000/svg'; 3227 3228// -------------------------- PrevNextButton -------------------------- // 3229 3230function PrevNextButton( direction, parent ) { 3231 this.direction = direction; 3232 this.parent = parent; 3233 this._create(); 3234} 3235 3236PrevNextButton.prototype = Object.create( TapListener.prototype ); 3237 3238PrevNextButton.prototype._create = function() { 3239 // properties 3240 this.isEnabled = true; 3241 this.isPrevious = this.direction == -1; 3242 var leftDirection = this.parent.options.rightToLeft ? 1 : -1; 3243 this.isLeft = this.direction == leftDirection; 3244 3245 var element = this.element = document.createElement('button'); 3246 element.className = 'flickity-button flickity-prev-next-button'; 3247 element.className += this.isPrevious ? ' previous' : ' next'; 3248 // prevent button from submitting form http://stackoverflow.com/a/10836076/182183 3249 element.setAttribute( 'type', 'button' ); 3250 // init as disabled 3251 this.disable(); 3252 3253 element.setAttribute( 'aria-label', this.isPrevious ? 'Previous' : 'Next' ); 3254 3255 // create arrow 3256 var svg = this.createSVG(); 3257 element.appendChild( svg ); 3258 // events 3259 this.on( 'tap', this.onTap ); 3260 this.parent.on( 'select', this.update.bind( this ) ); 3261 this.on( 'pointerDown', this.parent.childUIPointerDown.bind( this.parent ) ); 3262}; 3263 3264PrevNextButton.prototype.activate = function() { 3265 this.bindTap( this.element ); 3266 // click events from keyboard 3267 this.element.addEventListener( 'click', this ); 3268 // add to DOM 3269 this.parent.element.appendChild( this.element ); 3270}; 3271 3272PrevNextButton.prototype.deactivate = function() { 3273 // remove from DOM 3274 this.parent.element.removeChild( this.element ); 3275 // do regular TapListener destroy 3276 TapListener.prototype.destroy.call( this ); 3277 // click events from keyboard 3278 this.element.removeEventListener( 'click', this ); 3279}; 3280 3281PrevNextButton.prototype.createSVG = function() { 3282 var svg = document.createElementNS( svgURI, 'svg'); 3283 svg.setAttribute( 'class', 'flickity-button-icon' ); 3284 svg.setAttribute( 'viewBox', '0 0 100 100' ); 3285 var path = document.createElementNS( svgURI, 'path'); 3286 var pathMovements = getArrowMovements( this.parent.options.arrowShape ); 3287 path.setAttribute( 'd', pathMovements ); 3288 path.setAttribute( 'class', 'arrow' ); 3289 // rotate arrow 3290 if ( !this.isLeft ) { 3291 path.setAttribute( 'transform', 'translate(100, 100) rotate(180) ' ); 3292 } 3293 svg.appendChild( path ); 3294 return svg; 3295}; 3296 3297// get SVG path movmement 3298function getArrowMovements( shape ) { 3299 // use shape as movement if string 3300 if ( typeof shape == 'string' ) { 3301 return shape; 3302 } 3303 // create movement string 3304 return 'M ' + shape.x0 + ',50' + 3305 ' L ' + shape.x1 + ',' + ( shape.y1 + 50 ) + 3306 ' L ' + shape.x2 + ',' + ( shape.y2 + 50 ) + 3307 ' L ' + shape.x3 + ',50 ' + 3308 ' L ' + shape.x2 + ',' + ( 50 - shape.y2 ) + 3309 ' L ' + shape.x1 + ',' + ( 50 - shape.y1 ) + 3310 ' Z'; 3311} 3312 3313PrevNextButton.prototype.onTap = function() { 3314 if ( !this.isEnabled ) { 3315 return; 3316 } 3317 this.parent.uiChange(); 3318 var method = this.isPrevious ? 'previous' : 'next'; 3319 this.parent[ method ](); 3320}; 3321 3322PrevNextButton.prototype.handleEvent = utils.handleEvent; 3323 3324PrevNextButton.prototype.onclick = function( event ) { 3325 // only allow clicks from keyboard 3326 var focused = document.activeElement;
3327 if ( focused && focused == this.element ) { 3328 this.onTap( event, event ); 3329 } 3330}; 3331 3332// ----- ----- // 3333 3334PrevNextButton.prototype.enable = function() { 3335 if ( this.isEnabled ) { 3336 return; 3337 } 3338 this.element.disabled = false; 3339 this.isEnabled = true; 3340}; 3341 3342PrevNextButton.prototype.disable = function() { 3343 if ( !this.isEnabled ) { 3344 return; 3345 } 3346 this.element.disabled = true; 3347 this.isEnabled = false; 3348}; 3349 3350PrevNextButton.prototype.update = function() { 3351 // index of first or last slide, if previous or next 3352 var slides = this.parent.slides; 3353 // enable is wrapAround and at least 2 slides 3354 if ( this.parent.options.wrapAround && slides.length > 1 ) { 3355 this.enable(); 3356 return; 3357 } 3358 var lastIndex = slides.length ? slides.length - 1 : 0; 3359 var boundIndex = this.isPrevious ? 0 : lastIndex; 3360 var method = this.parent.selectedIndex == boundIndex ? 'disable' : 'enable'; 3361 this[ method ](); 3362}; 3363 3364PrevNextButton.prototype.destroy = function() { 3365 this.deactivate(); 3366}; 3367 3368// -------------------------- Flickity prototype -------------------------- // 3369 3370utils.extend( Flickity.defaults, { 3371 prevNextButtons: true, 3372 arrowShape: { 3373 x0: 10, 3374 x1: 60, y1: 50, 3375 x2: 70, y2: 40, 3376 x3: 30 3377 } 3378}); 3379 3380Flickity.createMethods.push('_createPrevNextButtons'); 3381var proto = Flickity.prototype; 3382 3383proto._createPrevNextButtons = function() { 3384 if ( !this.options.prevNextButtons ) { 3385 return; 3386 } 3387 3388 this.prevButton = new PrevNextButton( -1, this ); 3389 this.nextButton = new PrevNextButton( 1, this ); 3390 3391 this.on( 'activate', this.activatePrevNextButtons ); 3392}; 3393 3394proto.activatePrevNextButtons = function() { 3395 this.prevButton.activate(); 3396 this.nextButton.activate(); 3397 this.on( 'deactivate', this.deactivatePrevNextButtons ); 3398}; 3399 3400proto.deactivatePrevNextButtons = function() { 3401 this.prevButton.deactivate(); 3402 this.nextButton.deactivate(); 3403 this.off( 'deactivate', this.deactivatePrevNextButtons ); 3404}; 3405 3406// -------------------------- -------------------------- // 3407 3408Flickity.PrevNextButton = PrevNextButton; 3409 3410return Flickity; 3411 3412})); 3413 3414// page dots 3415( function( window, factory ) { 3416 // universal module definition 3417 /* jshint strict: false */ 3418 if ( typeof define == 'function' && define.amd ) { 3419 // AMD 3420 define( 'flickity/js/page-dots',[ 3421 './flickity', 3422 'tap-listener/tap-listener', 3423 'fizzy-ui-utils/utils' 3424 ], function( Flickity, TapListener, utils ) { 3425 return factory( window, Flickity, TapListener, utils ); 3426 }); 3427 } else if ( typeof module == 'object' && module.exports ) { 3428 // CommonJS 3429 module.exports = factory( 3430 window, 3431 require('./flickity'), 3432 require('tap-listener'), 3433 require('fizzy-ui-utils') 3434 ); 3435 } else { 3436 // browser global 3437 factory( 3438 window, 3439 window.Flickity, 3440 window.TapListener, 3441 window.fizzyUIUtils 3442 ); 3443 } 3444 3445}( window, function factory( window, Flickity, TapListener, utils ) { 3446 3447// -------------------------- PageDots -------------------------- // 3448 3449 3450 3451function PageDots( parent ) { 3452 this.parent = parent; 3453 this._create(); 3454} 3455 3456PageDots.prototype = new TapListener(); 3457 3458PageDots.prototype._create = function() { 3459 // create holder element 3460 this.holder = document.createElement('ol'); 3461 this.holder.className = 'flickity-page-dots'; 3462 // create dots, array of elements 3463 this.dots = []; 3464 // events 3465 this.on( 'tap', this.onTap ); 3466 this.on( 'pointerDown', this.parent.childUIPointerDown.bind( this.parent ) ); 3467}; 3468 3469PageDots.prototype.activate = function() { 3470 this.setDots(); 3471 this.bindTap( this.holder ); 3472 // add to DOM 3473 this.parent.element.appendChild( this.holder ); 3474}; 3475 3476PageDots.prototype.deactivate = function() { 3477 // remove from DOM 3478 this.parent.element.removeChild( this.holder ); 3479 TapListener.prototype.destroy.call( this ); 3480}; 3481 3482PageDots.prototype.setDots = function() { 3483 // get difference between number of slides and number of dots 3484 var delta = this.parent.slides.length - this.dots.length; 3485 if ( delta > 0 ) { 3486 this.addDots( delta ); 3487 } else if ( delta < 0 ) { 3488 this.removeDots( -delta ); 3489 } 3490}; 3491 3492PageDots.prototype.addDots = function( count ) { 3493 var fragment = document.createDocumentFragment(); 3494 var newDots = []; 3495 var length = this.dots.length; 3496 var max = length + count; 3497 3498 for ( var i = length; i < max; i++ ) { 3499 var dot = document.createElement('li'); 3500 dot.className = 'dot'; 3501 dot.setAttribute( 'aria-label', 'Page dot ' + ( i + 1 ) ); 3502 fragment.appendChild( dot ); 3503 newDots.push( dot ); 3504 } 3505 3506 this.holder.appendChild( fragment ); 3507 this.dots = this.dots.concat( newDots ); 3508};
3509 3510PageDots.prototype.removeDots = function( count ) { 3511 // remove from this.dots collection 3512 var removeDots = this.dots.splice( this.dots.length - count, count ); 3513 // remove from DOM 3514 removeDots.forEach( function( dot ) { 3515 this.holder.removeChild( dot ); 3516 }, this ); 3517}; 3518 3519PageDots.prototype.updateSelected = function() { 3520 // remove selected class on previous 3521 if ( this.selectedDot ) { 3522 this.selectedDot.className = 'dot'; 3523 this.selectedDot.removeAttribute('aria-current'); 3524 } 3525 // don't proceed if no dots 3526 if ( !this.dots.length ) { 3527 return; 3528 } 3529 this.selectedDot = this.dots[ this.parent.selectedIndex ]; 3530 this.selectedDot.className = 'dot is-selected'; 3531 this.selectedDot.setAttribute( 'aria-current', 'step' ); 3532}; 3533 3534PageDots.prototype.onTap = function( event ) { 3535 var target = event.target; 3536 // only care about dot clicks 3537 if ( target.nodeName != 'LI' ) { 3538 return; 3539 } 3540 3541 this.parent.uiChange(); 3542 var index = this.dots.indexOf( target ); 3543 this.parent.select( index ); 3544}; 3545 3546PageDots.prototype.destroy = function() { 3547 this.deactivate(); 3548}; 3549 3550Flickity.PageDots = PageDots; 3551 3552// -------------------------- Flickity -------------------------- // 3553 3554utils.extend( Flickity.defaults, { 3555 pageDots: true 3556}); 3557 3558Flickity.createMethods.push('_createPageDots'); 3559 3560var proto = Flickity.prototype; 3561 3562proto._createPageDots = function() { 3563 if ( !this.options.pageDots ) { 3564 return; 3565 } 3566 this.pageDots = new PageDots( this ); 3567 // events 3568 this.on( 'activate', this.activatePageDots ); 3569 this.on( 'select', this.updateSelectedPageDots ); 3570 this.on( 'cellChange', this.updatePageDots ); 3571 this.on( 'resize', this.updatePageDots ); 3572 this.on( 'deactivate', this.deactivatePageDots ); 3573}; 3574 3575proto.activatePageDots = function() { 3576 this.pageDots.activate(); 3577}; 3578 3579proto.updateSelectedPageDots = function() { 3580 this.pageDots.updateSelected(); 3581}; 3582 3583proto.updatePageDots = function() { 3584 this.pageDots.setDots(); 3585}; 3586 3587proto.deactivatePageDots = function() { 3588 this.pageDots.deactivate(); 3589}; 3590 3591// ----- ----- // 3592 3593Flickity.PageDots = PageDots; 3594 3595return Flickity; 3596 3597})); 3598 3599// player & autoPlay 3600( function( window, factory ) { 3601 // universal module definition 3602 /* jshint strict: false */ 3603 if ( typeof define == 'function' && define.amd ) { 3604 // AMD 3605 define( 'flickity/js/player',[ 3606 'ev-emitter/ev-emitter', 3607 'fizzy-ui-utils/utils', 3608 './flickity' 3609 ], function( EvEmitter, utils, Flickity ) { 3610 return factory( EvEmitter, utils, Flickity ); 3611 }); 3612 } else if ( typeof module == 'object' && module.exports ) { 3613 // CommonJS 3614 module.exports = factory( 3615 require('ev-emitter'), 3616 require('fizzy-ui-utils'), 3617 require('./flickity') 3618 ); 3619 } else { 3620 // browser global 3621 factory( 3622 window.EvEmitter, 3623 window.fizzyUIUtils, 3624 window.Flickity 3625 ); 3626 } 3627 3628}( window, function factory( EvEmitter, utils, Flickity ) { 3629 3630 3631 3632// -------------------------- Player -------------------------- // 3633 3634function Player( parent ) { 3635 this.parent = parent; 3636 this.state = 'stopped'; 3637 // visibility change event handler 3638 this.onVisibilityChange = this.visibilityChange.bind( this ); 3639 this.onVisibilityPlay = this.visibilityPlay.bind( this ); 3640} 3641 3642Player.prototype = Object.create( EvEmitter.prototype ); 3643 3644// start play 3645Player.prototype.play = function() { 3646 if ( this.state == 'playing' ) { 3647 return; 3648 } 3649 // do not play if page is hidden, start playing when page is visible 3650 var isPageHidden = document.hidden; 3651 if ( isPageHidden ) { 3652 document.addEventListener( 'visibilitychange', this.onVisibilityPlay ); 3653 return; 3654 } 3655 3656 this.state = 'playing'; 3657 // listen to visibility change 3658 document.addEventListener( 'visibilitychange', this.onVisibilityChange ); 3659 // start ticking 3660 this.tick(); 3661}; 3662 3663Player.prototype.tick = function() { 3664 // do not tick if not playing 3665 if ( this.state != 'playing' ) { 3666 return; 3667 } 3668 3669 var time = this.parent.options.autoPlay; 3670 // default to 3 seconds 3671 time = typeof time == 'number' ? time : 3000; 3672 var _this = this; 3673 // HACK: reset ticks if stopped and started within interval 3674 this.clear(); 3675 this.timeout = setTimeout( function() { 3676 _this.parent.next( true ); 3677 _this.tick(); 3678 }, time ); 3679}; 3680 3681Player.prototype.stop = function() { 3682 this.state = 'stopped'; 3683 this.clear(); 3684 // remove visibility change event 3685 document.removeEventListener( 'visibilitychange', this.onVisibilityChange ); 3686}; 3687 3688Player.prototype.clear = function() { 3689 clearTimeout( this.timeout ); 3690}; 3691 3692Player.prototype.pause = function() { 3693 if ( this.state == 'playing' ) { 3694 this.state = 'paused'; 3695 this.clear(); 3696 } 3697}; 3698 3699Player.prototype.unpause = function() { 3700 // re-start play if paused 3701 if ( this.state == 'paused' ) { 3702 this.play(); 3703 } 3704}; 3705 3706// pause if page visibility is hidden, unpause if visible 3707Player.prototype.visibilityChange = function() { 3708 var isPageHidden = document.hidden; 3709 this[ isPageHidden ? 'pause' : 'unpause' ](); 3710}; 3711 3712Player.prototype.visibilityPlay = function() { 3713 this.play(); 3714 document.removeEventListener( 'visibilitychange', this.onVisibilityPlay ); 3715};
3716 3717// -------------------------- Flickity -------------------------- // 3718 3719utils.extend( Flickity.defaults, { 3720 pauseAutoPlayOnHover: true 3721}); 3722 3723Flickity.createMethods.push('_createPlayer'); 3724var proto = Flickity.prototype; 3725 3726proto._createPlayer = function() { 3727 this.player = new Player( this ); 3728 3729 this.on( 'activate', this.activatePlayer ); 3730 this.on( 'uiChange', this.stopPlayer ); 3731 this.on( 'pointerDown', this.stopPlayer ); 3732 this.on( 'deactivate', this.deactivatePlayer ); 3733}; 3734 3735proto.activatePlayer = function() { 3736 if ( !this.options.autoPlay ) { 3737 return; 3738 } 3739 this.player.play(); 3740 this.element.addEventListener( 'mouseenter', this ); 3741}; 3742 3743// Player API, don't hate the ... thanks I know where the door is 3744 3745proto.playPlayer = function() { 3746 this.player.play(); 3747}; 3748 3749proto.stopPlayer = function() { 3750 this.player.stop(); 3751}; 3752 3753proto.pausePlayer = function() { 3754 this.player.pause(); 3755}; 3756 3757proto.unpausePlayer = function() { 3758 this.player.unpause(); 3759}; 3760 3761proto.deactivatePlayer = function() { 3762 this.player.stop(); 3763 this.element.removeEventListener( 'mouseenter', this ); 3764}; 3765 3766// ----- mouseenter/leave ----- // 3767 3768// pause auto-play on hover 3769proto.onmouseenter = function() { 3770 if ( !this.options.pauseAutoPlayOnHover ) { 3771 return; 3772 } 3773 this.player.pause(); 3774 this.element.addEventListener( 'mouseleave', this ); 3775}; 3776 3777// resume auto-play on hover off 3778proto.onmouseleave = function() { 3779 this.player.unpause(); 3780 this.element.removeEventListener( 'mouseleave', this ); 3781}; 3782 3783// ----- ----- // 3784 3785Flickity.Player = Player; 3786 3787return Flickity; 3788 3789})); 3790 3791// add, remove cell 3792( function( window, factory ) { 3793 // universal module definition 3794 /* jshint strict: false */ 3795 if ( typeof define == 'function' && define.amd ) { 3796 // AMD 3797 define( 'flickity/js/add-remove-cell',[ 3798 './flickity', 3799 'fizzy-ui-utils/utils' 3800 ], function( Flickity, utils ) { 3801 return factory( window, Flickity, utils ); 3802 }); 3803 } else if ( typeof module == 'object' && module.exports ) { 3804 // CommonJS 3805 module.exports = factory( 3806 window, 3807 require('./flickity'), 3808 require('fizzy-ui-utils') 3809 ); 3810 } else { 3811 // browser global 3812 factory( 3813 window, 3814 window.Flickity, 3815 window.fizzyUIUtils 3816 ); 3817 } 3818 3819}( window, function factory( window, Flickity, utils ) { 3820 3821 3822 3823// append cells to a document fragment 3824function getCellsFragment( cells ) { 3825 var fragment = document.createDocumentFragment(); 3826 cells.forEach( function( cell ) { 3827 fragment.appendChild( cell.element ); 3828 }); 3829 return fragment; 3830} 3831 3832// -------------------------- add/remove cell prototype -------------------------- // 3833 3834var proto = Flickity.prototype; 3835 3836/** 3837 * Insert, prepend, or append cells 3838 * @param {Element, Array, NodeList} elems 3839 * @param {Integer} index 3840 */ 3841proto.insert = function( elems, index ) { 3842 var cells = this._makeCells( elems ); 3843 if ( !cells || !cells.length ) { 3844 return; 3845 } 3846 var len = this.cells.length; 3847 // default to append 3848 index = index === undefined ? len : index; 3849 // add cells with document fragment 3850 var fragment = getCellsFragment( cells ); 3851 // append to slider 3852 var isAppend = index == len; 3853 if ( isAppend ) { 3854 this.slider.appendChild( fragment ); 3855 } else { 3856 var insertCellElement = this.cells[ index ].element; 3857 this.slider.insertBefore( fragment, insertCellElement ); 3858 } 3859 // add to this.cells 3860 if ( index === 0 ) { 3861 // prepend, add to start 3862 this.cells = cells.concat( this.cells ); 3863 } else if ( isAppend ) { 3864 // append, add to end 3865 this.cells = this.cells.concat( cells ); 3866 } else { 3867 // insert in this.cells 3868 var endCells = this.cells.splice( index, len - index ); 3869 this.cells = this.cells.concat( cells ).concat( endCells ); 3870 } 3871 3872 this._sizeCells( cells ); 3873 this.cellChange( index, true ); 3874}; 3875 3876proto.append = function( elems ) { 3877 this.insert( elems, this.cells.length ); 3878}; 3879 3880proto.prepend = function( elems ) { 3881 this.insert( elems, 0 ); 3882}; 3883 3884/** 3885 * Remove cells 3886 * @param {Element, Array, NodeList} elems 3887 */ 3888proto.remove = function( elems ) { 3889 var cells = this.getCells( elems ); 3890 if ( !cells || !cells.length ) { 3891 return; 3892 } 3893 3894 var minCellIndex = this.cells.length - 1; 3895 // remove cells from collection & DOM
3896 cells.forEach( function( cell ) { 3897 cell.remove(); 3898 var index = this.cells.indexOf( cell ); 3899 minCellIndex = Math.min( index, minCellIndex ); 3900 utils.removeFrom( this.cells, cell ); 3901 }, this ); 3902 3903 this.cellChange( minCellIndex, true ); 3904}; 3905 3906/** 3907 * logic to be run after a cell's size changes 3908 * @param {Element} elem - cell's element 3909 */ 3910proto.cellSizeChange = function( elem ) { 3911 var cell = this.getCell( elem ); 3912 if ( !cell ) { 3913 return; 3914 } 3915 cell.getSize(); 3916 3917 var index = this.cells.indexOf( cell ); 3918 this.cellChange( index ); 3919}; 3920 3921/** 3922 * logic any time a cell is changed: added, removed, or size changed 3923 * @param {Integer} changedCellIndex - index of the changed cell, optional 3924 */ 3925proto.cellChange = function( changedCellIndex, isPositioningSlider ) { 3926 var prevSelectedElem = this.selectedElement; 3927 this._positionCells( changedCellIndex ); 3928 this._getWrapShiftCells(); 3929 this.setGallerySize(); 3930 // update selectedIndex 3931 // try to maintain position & select previous selected element 3932 var cell = this.getCell( prevSelectedElem ); 3933 if ( cell ) { 3934 this.selectedIndex = this.getCellSlideIndex( cell ); 3935 } 3936 this.selectedIndex = Math.min( this.slides.length - 1, this.selectedIndex ); 3937 3938 this.emitEvent( 'cellChange', [ changedCellIndex ] ); 3939 // position slider 3940 this.select( this.selectedIndex ); 3941 // do not position slider after lazy load 3942 if ( isPositioningSlider ) { 3943 this.positionSliderAtSelected(); 3944 } 3945}; 3946 3947// ----- ----- // 3948 3949return Flickity; 3950 3951})); 3952 3953// lazyload 3954( function( window, factory ) { 3955 // universal module definition 3956 /* jshint strict: false */ 3957 if ( typeof define == 'function' && define.amd ) { 3958 // AMD 3959 define( 'flickity/js/lazyload',[ 3960 './flickity', 3961 'fizzy-ui-utils/utils' 3962 ], function( Flickity, utils ) { 3963 return factory( window, Flickity, utils ); 3964 }); 3965 } else if ( typeof module == 'object' && module.exports ) { 3966 // CommonJS 3967 module.exports = factory( 3968 window, 3969 require('./flickity'), 3970 require('fizzy-ui-utils') 3971 ); 3972 } else { 3973 // browser global 3974 factory( 3975 window, 3976 window.Flickity, 3977 window.fizzyUIUtils 3978 ); 3979 } 3980 3981}( window, function factory( window, Flickity, utils ) { 3982'use strict'; 3983 3984Flickity.createMethods.push('_createLazyload'); 3985var proto = Flickity.prototype; 3986 3987proto._createLazyload = function() { 3988 this.on( 'select', this.lazyLoad ); 3989}; 3990 3991proto.lazyLoad = function() { 3992 var lazyLoad = this.options.lazyLoad; 3993 if ( !lazyLoad ) { 3994 return; 3995 } 3996 // get adjacent cells, use lazyLoad option for adjacent count 3997 var adjCount = typeof lazyLoad == 'number' ? lazyLoad : 0; 3998 var cellElems = this.getAdjacentCellElements( adjCount ); 3999 // get lazy images in those cells 4000 var lazyImages = [];
4001 cellElems.forEach( function( cellElem ) { 4002 var lazyCellImages = getCellLazyImages( cellElem ); 4003 lazyImages = lazyImages.concat( lazyCellImages ); 4004 }); 4005 // load lazy images 4006 lazyImages.forEach( function( img ) { 4007 new LazyLoader( img, this ); 4008 }, this ); 4009}; 4010 4011function getCellLazyImages( cellElem ) { 4012 // check if cell element is lazy image 4013 if ( cellElem.nodeName == 'IMG' ) { 4014 var lazyloadAttr = cellElem.getAttribute('data-flickity-lazyload'); 4015 var srcAttr = cellElem.getAttribute('data-flickity-lazyload-src'); 4016 var srcsetAttr = cellElem.getAttribute('data-flickity-lazyload-srcset'); 4017 if ( lazyloadAttr || srcAttr || srcsetAttr ) { 4018 return [ cellElem ]; 4019 } 4020 } 4021 // select lazy images in cell 4022 var lazySelector = 'img[data-flickity-lazyload], ' + 4023 'img[data-flickity-lazyload-src], img[data-flickity-lazyload-srcset]'; 4024 var imgs = cellElem.querySelectorAll( lazySelector ); 4025 return utils.makeArray( imgs ); 4026} 4027 4028// -------------------------- LazyLoader -------------------------- // 4029 4030/** 4031 * class to handle loading images 4032 */ 4033function LazyLoader( img, flickity ) { 4034 this.img = img; 4035 this.flickity = flickity; 4036 this.load(); 4037} 4038 4039LazyLoader.prototype.handleEvent = utils.handleEvent; 4040 4041LazyLoader.prototype.load = function() { 4042 this.img.addEventListener( 'load', this ); 4043 this.img.addEventListener( 'error', this ); 4044 // get src & srcset 4045 var src = this.img.getAttribute('data-flickity-lazyload') || 4046 this.img.getAttribute('data-flickity-lazyload-src'); 4047 var srcset = this.img.getAttribute('data-flickity-lazyload-srcset'); 4048 // set src & serset 4049 this.img.src = src; 4050 if ( srcset ) { 4051 this.img.setAttribute( 'srcset', srcset ); 4052 } 4053 // remove attr 4054 this.img.removeAttribute('data-flickity-lazyload'); 4055 this.img.removeAttribute('data-flickity-lazyload-src'); 4056 this.img.removeAttribute('data-flickity-lazyload-srcset'); 4057}; 4058 4059LazyLoader.prototype.onload = function( event ) { 4060 this.complete( event, 'flickity-lazyloaded' ); 4061}; 4062 4063LazyLoader.prototype.onerror = function( event ) { 4064 this.complete( event, 'flickity-lazyerror' ); 4065}; 4066 4067LazyLoader.prototype.complete = function( event, className ) { 4068 // unbind events 4069 this.img.removeEventListener( 'load', this ); 4070 this.img.removeEventListener( 'error', this ); 4071 4072 var cell = this.flickity.getParentCell( this.img ); 4073 var cellElem = cell && cell.element; 4074 this.flickity.cellSizeChange( cellElem ); 4075 4076 this.img.classList.add( className ); 4077 this.flickity.dispatchEvent( 'lazyLoad', event, cellElem ); 4078}; 4079 4080// ----- ----- // 4081 4082Flickity.LazyLoader = LazyLoader; 4083 4084return Flickity; 4085 4086})); 4087 4088/*! 4089 * Flickity v2.1.2 4090 * Touch, responsive, flickable carousels 4091 * 4092 * Licensed GPLv3 for open source use 4093 * or Flickity Commercial License for commercial use 4094 * 4095 * https://flickity.metafizzy.co 4096 * Copyright 2015-2018 Metafizzy 4097 */ 4098 4099( function( window, factory ) { 4100 // universal module definition 4101 /* jshint strict: false */ 4102 if ( typeof define == 'function' && define.amd ) { 4103 // AMD 4104 define( 'flickity/js/index',[ 4105 './flickity', 4106 './drag', 4107 './prev-next-button', 4108 './page-dots', 4109 './player', 4110 './add-remove-cell', 4111 './lazyload' 4112 ], factory ); 4113 } else if ( typeof module == 'object' && module.exports ) { 4114 // CommonJS 4115 module.exports = factory( 4116 require('./flickity'), 4117 require('./drag'), 4118 require('./prev-next-button'), 4119 require('./page-dots'), 4120 require('./player'), 4121 require('./add-remove-cell'), 4122 require('./lazyload') 4123 ); 4124 } 4125 4126})( window, function factory( Flickity ) { 4127 /*jshint strict: false*/ 4128 return Flickity; 4129}); 4130 4131/*! 4132 * Flickity asNavFor v2.0.1 4133 * enable asNavFor for Flickity 4134 */ 4135 4136/*jshint browser: true, undef: true, unused: true, strict: true*/ 4137 4138( function( window, factory ) { 4139 // universal module definition 4140 /*jshint strict: false */ /*globals define, module, require */ 4141 if ( typeof define == 'function' && define.amd ) { 4142 // AMD 4143 define( 'flickity-as-nav-for/as-nav-for',[ 4144 'flickity/js/index', 4145 'fizzy-ui-utils/utils' 4146 ], factory ); 4147 } else if ( typeof module == 'object' && module.exports ) { 4148 // CommonJS 4149 module.exports = factory( 4150 require('flickity'), 4151 require('fizzy-ui-utils') 4152 ); 4153 } else { 4154 // browser global 4155 window.Flickity = factory( 4156 window.Flickity, 4157 window.fizzyUIUtils 4158 ); 4159 } 4160 4161}( window, function factory( Flickity, utils ) { 4162 4163 4164 4165// -------------------------- asNavFor prototype -------------------------- // 4166 4167// Flickity.defaults.asNavFor = null; 4168 4169Flickity.createMethods.push('_createAsNavFor'); 4170 4171var proto = Flickity.prototype; 4172 4173proto._createAsNavFor = function() { 4174 this.on( 'activate', this.activateAsNavFor ); 4175 this.on( 'deactivate', this.deactivateAsNavFor ); 4176 this.on( 'destroy', this.destroyAsNavFor ); 4177 4178 var asNavForOption = this.options.asNavFor; 4179 if ( !asNavForOption ) { 4180 return; 4181 } 4182 // HACK do async, give time for other flickity to be initalized 4183 var _this = this; 4184 setTimeout( function initNavCompanion() { 4185 _this.setNavCompanion( asNavForOption ); 4186 }); 4187}; 4188 4189proto.setNavCompanion = function( elem ) { 4190 elem = utils.getQueryElement( elem ); 4191 var companion = Flickity.data( elem ); 4192 // stop if no companion or companion is self 4193 if ( !companion || companion == this ) { 4194 return; 4195 } 4196 4197 this.navCompanion = companion; 4198 // companion select 4199 var _this = this; 4200 this.onNavCompanionSelect = function() { 4201 _this.navCompanionSelect(); 4202 }; 4203 companion.on( 'select', this.onNavCompanionSelect ); 4204 // click 4205 this.on( 'staticClick', this.onNavStaticClick ); 4206 4207 this.navCompanionSelect( true ); 4208}; 4209 4210proto.navCompanionSelect = function( isInstant ) { 4211 if ( !this.navCompanion ) { 4212 return; 4213 } 4214 // select slide that matches first cell of slide 4215 var selectedCell = this.navCompanion.selectedCells[0]; 4216 var firstIndex = this.navCompanion.cells.indexOf( selectedCell ); 4217 var lastIndex = firstIndex + this.navCompanion.selectedCells.length - 1; 4218 var selectIndex = Math.floor( lerp( firstIndex, lastIndex, 4219 this.navCompanion.cellAlign ) ); 4220 this.selectCell( selectIndex, false, isInstant ); 4221 // set nav selected class 4222 this.removeNavSelectedElements();
vendor: 4,590 bytes, lines 4223-4408
4223 // stop if companion has more cells than this one 4224 if ( selectIndex >= this.cells.length ) { 4225 return; 4226 } 4227 4228 var selectedCells = this.cells.slice( firstIndex, lastIndex + 1 ); 4229 this.navSelectedElements = selectedCells.map( function( cell ) { 4230 return cell.element; 4231 }); 4232 this.changeNavSelectedClass('add'); 4233}; 4234 4235function lerp( a, b, t ) { 4236 return ( b - a ) * t + a; 4237} 4238 4239proto.changeNavSelectedClass = function( method ) { 4240 this.navSelectedElements.forEach( function( navElem ) { 4241 navElem.classList[ method ]('is-nav-selected'); 4242 }); 4243}; 4244 4245proto.activateAsNavFor = function() { 4246 this.navCompanionSelect( true ); 4247}; 4248 4249proto.removeNavSelectedElements = function() { 4250 if ( !this.navSelectedElements ) { 4251 return; 4252 } 4253 this.changeNavSelectedClass('remove'); 4254 delete this.navSelectedElements; 4255}; 4256 4257proto.onNavStaticClick = function( event, pointer, cellElement, cellIndex ) { 4258 if ( typeof cellIndex == 'number' ) { 4259 this.navCompanion.selectCell( cellIndex ); 4260 } 4261}; 4262 4263proto.deactivateAsNavFor = function() { 4264 this.removeNavSelectedElements(); 4265}; 4266 4267proto.destroyAsNavFor = function() { 4268 if ( !this.navCompanion ) { 4269 return; 4270 } 4271 this.navCompanion.off( 'select', this.onNavCompanionSelect ); 4272 this.off( 'staticClick', this.onNavStaticClick ); 4273 delete this.navCompanion; 4274}; 4275 4276// ----- ----- // 4277 4278return Flickity; 4279 4280})); 4281 4282/*! 4283 * imagesLoaded v4.1.4 4284 * JavaScript is all like "You images are done yet or what?" 4285 * MIT License 4286 */ 4287 4288( function( window, factory ) { 'use strict'; 4289 // universal module definition 4290 4291 /*global define: false, module: false, require: false */ 4292 4293 if ( typeof define == 'function' && define.amd ) { 4294 // AMD 4295 define( 'imagesloaded/imagesloaded',[ 4296 'ev-emitter/ev-emitter' 4297 ], function( EvEmitter ) { 4298 return factory( window, EvEmitter ); 4299 }); 4300 } else if ( typeof module == 'object' && module.exports ) { 4301 // CommonJS 4302 module.exports = factory( 4303 window, 4304 require('ev-emitter') 4305 ); 4306 } else { 4307 // browser global 4308 window.imagesLoaded = factory( 4309 window, 4310 window.EvEmitter 4311 ); 4312 } 4313 4314})( typeof window !== 'undefined' ? window : this, 4315 4316// -------------------------- factory -------------------------- // 4317 4318function factory( window, EvEmitter ) { 4319 4320 4321 4322var $ = window.jQuery; 4323var console = window.console; 4324 4325// -------------------------- helpers -------------------------- // 4326 4327// extend objects 4328function extend( a, b ) { 4329 for ( var prop in b ) { 4330 a[ prop ] = b[ prop ]; 4331 } 4332 return a; 4333} 4334 4335var arraySlice = Array.prototype.slice; 4336 4337// turn element or nodeList into an array 4338function makeArray( obj ) { 4339 if ( Array.isArray( obj ) ) { 4340 // use object if already an array 4341 return obj; 4342 } 4343 4344 var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number'; 4345 if ( isArrayLike ) { 4346 // convert nodeList to array 4347 return arraySlice.call( obj ); 4348 } 4349 4350 // array of single index 4351 return [ obj ]; 4352} 4353 4354// -------------------------- imagesLoaded -------------------------- // 4355 4356/** 4357 * @param {Array, Element, NodeList, String} elem 4358 * @param {Object or Function} options - if function, use as callback 4359 * @param {Function} onAlways - callback function 4360 */ 4361function ImagesLoaded( elem, options, onAlways ) { 4362 // coerce ImagesLoaded() without new, to be new ImagesLoaded() 4363 if ( !( this instanceof ImagesLoaded ) ) { 4364 return new ImagesLoaded( elem, options, onAlways ); 4365 } 4366 // use elem as selector string 4367 var queryElem = elem; 4368 if ( typeof elem == 'string' ) { 4369 queryElem = document.querySelectorAll( elem ); 4370 } 4371 // bail if bad element 4372 if ( !queryElem ) { 4373 console.error( 'Bad element for imagesLoaded ' + ( queryElem || elem ) ); 4374 return; 4375 } 4376 4377 this.elements = makeArray( queryElem ); 4378 this.options = extend( {}, this.options ); 4379 // shift arguments if no options set 4380 if ( typeof options == 'function' ) { 4381 onAlways = options; 4382 } else { 4383 extend( this.options, options ); 4384 } 4385 4386 if ( onAlways ) { 4387 this.on( 'always', onAlways ); 4388 } 4389 4390 this.getImages(); 4391 4392 if ( $ ) { 4393 // add jQuery Deferred object 4394 this.jqDeferred = new $.Deferred(); 4395 } 4396 4397 // HACK check async to allow time to bind listeners 4398 setTimeout( this.check.bind( this ) ); 4399} 4400 4401ImagesLoaded.prototype = Object.create( EvEmitter.prototype ); 4402 4403ImagesLoaded.prototype.options = {}; 4404 4405ImagesLoaded.prototype.getImages = function() { 4406 this.images = []; 4407 4408 // filter & find items if we have an item selector
vendor: 4,504 bytes, lines 4409-4565
4409 this.elements.forEach( this.addElementImages, this ); 4410}; 4411 4412/** 4413 * @param {Node} element 4414 */ 4415ImagesLoaded.prototype.addElementImages = function( elem ) { 4416 // filter siblings 4417 if ( elem.nodeName == 'IMG' ) { 4418 this.addImage( elem ); 4419 } 4420 // get background image on element 4421 if ( this.options.background === true ) { 4422 this.addElementBackgroundImages( elem ); 4423 } 4424 4425 // find children 4426 // no non-element nodes, #143 4427 var nodeType = elem.nodeType; 4428 if ( !nodeType || !elementNodeTypes[ nodeType ] ) { 4429 return; 4430 } 4431 var childImgs = elem.querySelectorAll('img'); 4432 // concat childElems to filterFound array 4433 for ( var i=0; i < childImgs.length; i++ ) { 4434 var img = childImgs[i]; 4435 this.addImage( img ); 4436 } 4437 4438 // get child background images 4439 if ( typeof this.options.background == 'string' ) { 4440 var children = elem.querySelectorAll( this.options.background ); 4441 for ( i=0; i < children.length; i++ ) { 4442 var child = children[i]; 4443 this.addElementBackgroundImages( child ); 4444 } 4445 } 4446}; 4447 4448var elementNodeTypes = { 4449 1: true, 4450 9: true, 4451 11: true 4452}; 4453 4454ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) { 4455 var style = getComputedStyle( elem ); 4456 if ( !style ) { 4457 // Firefox returns null if in a hidden iframe https://bugzil.la/548397 4458 return; 4459 } 4460 // get url inside url("...") 4461 var reURL = /url\((['"])?(.*?)\1\)/gi; 4462 var matches = reURL.exec( style.backgroundImage ); 4463 while ( matches !== null ) { 4464 var url = matches && matches[2]; 4465 if ( url ) { 4466 this.addBackground( url, elem ); 4467 } 4468 matches = reURL.exec( style.backgroundImage ); 4469 } 4470}; 4471 4472/** 4473 * @param {Image} img 4474 */ 4475ImagesLoaded.prototype.addImage = function( img ) { 4476 var loadingImage = new LoadingImage( img ); 4477 this.images.push( loadingImage ); 4478}; 4479 4480ImagesLoaded.prototype.addBackground = function( url, elem ) { 4481 var background = new Background( url, elem ); 4482 this.images.push( background ); 4483}; 4484 4485ImagesLoaded.prototype.check = function() { 4486 var _this = this; 4487 this.progressedCount = 0; 4488 this.hasAnyBroken = false; 4489 // complete if no images 4490 if ( !this.images.length ) { 4491 this.complete(); 4492 return; 4493 } 4494 4495 function onProgress( image, elem, message ) { 4496 // HACK - Chrome triggers event before object properties have changed. #83 4497 setTimeout( function() { 4498 _this.progress( image, elem, message ); 4499 }); 4500 } 4501 4502 this.images.forEach( function( loadingImage ) { 4503 loadingImage.once( 'progress', onProgress ); 4504 loadingImage.check(); 4505 }); 4506}; 4507 4508ImagesLoaded.prototype.progress = function( image, elem, message ) { 4509 this.progressedCount++; 4510 this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded; 4511 // progress event 4512 this.emitEvent( 'progress', [ this, image, elem ] ); 4513 if ( this.jqDeferred && this.jqDeferred.notify ) { 4514 this.jqDeferred.notify( this, image ); 4515 } 4516 // check if completed 4517 if ( this.progressedCount == this.images.length ) { 4518 this.complete(); 4519 } 4520 4521 if ( this.options.debug && console ) { 4522 console.log( 'progress: ' + message, image, elem ); 4523 } 4524}; 4525 4526ImagesLoaded.prototype.complete = function() { 4527 var eventName = this.hasAnyBroken ? 'fail' : 'done'; 4528 this.isComplete = true; 4529 this.emitEvent( eventName, [ this ] ); 4530 this.emitEvent( 'always', [ this ] ); 4531 if ( this.jqDeferred ) { 4532 var jqMethod = this.hasAnyBroken ? 'reject' : 'resolve'; 4533 this.jqDeferred[ jqMethod ]( this ); 4534 } 4535}; 4536 4537// -------------------------- -------------------------- // 4538 4539function LoadingImage( img ) { 4540 this.img = img; 4541} 4542 4543LoadingImage.prototype = Object.create( EvEmitter.prototype ); 4544 4545LoadingImage.prototype.check = function() { 4546 // If complete is true and browser supports natural sizes, 4547 // try to check for image status manually. 4548 var isComplete = this.getIsImageComplete(); 4549 if ( isComplete ) { 4550 // report based on naturalWidth 4551 this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' ); 4552 return; 4553 } 4554 4555 // If none of the checks above matched, simulate loading on detached element. 4556 this.proxyImage = new Image(); 4557 this.proxyImage.addEventListener( 'load', this ); 4558 this.proxyImage.addEventListener( 'error', this ); 4559 // bind to image as well for Firefox. #191 4560 this.img.addEventListener( 'load', this ); 4561 this.img.addEventListener( 'error', this ); 4562 this.proxyImage.src = this.img.src; 4563}; 4564 4565LoadingImage.prototype.getIsImageComplete = function() {
vendor: 4,255 bytes, lines 4566-4718
4566 // check for non-zero, non-undefined naturalWidth 4567 // fixes Safari+InfiniteScroll+Masonry bug infinite-scroll#671 4568 return this.img.complete && this.img.naturalWidth; 4569}; 4570 4571LoadingImage.prototype.confirm = function( isLoaded, message ) { 4572 this.isLoaded = isLoaded; 4573 this.emitEvent( 'progress', [ this, this.img, message ] ); 4574}; 4575 4576// ----- events ----- // 4577 4578// trigger specified handler for event type 4579LoadingImage.prototype.handleEvent = function( event ) { 4580 var method = 'on' + event.type; 4581 if ( this[ method ] ) { 4582 this[ method ]( event ); 4583 } 4584}; 4585 4586LoadingImage.prototype.onload = function() { 4587 this.confirm( true, 'onload' ); 4588 this.unbindEvents(); 4589}; 4590 4591LoadingImage.prototype.onerror = function() { 4592 this.confirm( false, 'onerror' ); 4593 this.unbindEvents(); 4594}; 4595 4596LoadingImage.prototype.unbindEvents = function() { 4597 this.proxyImage.removeEventListener( 'load', this ); 4598 this.proxyImage.removeEventListener( 'error', this ); 4599 this.img.removeEventListener( 'load', this ); 4600 this.img.removeEventListener( 'error', this ); 4601}; 4602 4603// -------------------------- Background -------------------------- // 4604 4605function Background( url, element ) { 4606 this.url = url; 4607 this.element = element; 4608 this.img = new Image(); 4609} 4610 4611// inherit LoadingImage prototype 4612Background.prototype = Object.create( LoadingImage.prototype ); 4613 4614Background.prototype.check = function() { 4615 this.img.addEventListener( 'load', this ); 4616 this.img.addEventListener( 'error', this ); 4617 this.img.src = this.url; 4618 // check if image is already complete 4619 var isComplete = this.getIsImageComplete(); 4620 if ( isComplete ) { 4621 this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' ); 4622 this.unbindEvents(); 4623 } 4624}; 4625 4626Background.prototype.unbindEvents = function() { 4627 this.img.removeEventListener( 'load', this ); 4628 this.img.removeEventListener( 'error', this ); 4629}; 4630 4631Background.prototype.confirm = function( isLoaded, message ) { 4632 this.isLoaded = isLoaded; 4633 this.emitEvent( 'progress', [ this, this.element, message ] ); 4634}; 4635 4636// -------------------------- jQuery -------------------------- // 4637 4638ImagesLoaded.makeJQueryPlugin = function( jQuery ) { 4639 jQuery = jQuery || window.jQuery; 4640 if ( !jQuery ) { 4641 return; 4642 } 4643 // set local variable 4644 $ = jQuery; 4645 // $().imagesLoaded() 4646 $.fn.imagesLoaded = function( options, callback ) { 4647 var instance = new ImagesLoaded( this, options, callback ); 4648 return instance.jqDeferred.promise( $(this) ); 4649 }; 4650}; 4651// try making plugin 4652ImagesLoaded.makeJQueryPlugin(); 4653 4654// -------------------------- -------------------------- // 4655 4656return ImagesLoaded; 4657 4658}); 4659 4660/*! 4661 * Flickity imagesLoaded v2.0.0 4662 * enables imagesLoaded option for Flickity 4663 */ 4664 4665/*jshint browser: true, strict: true, undef: true, unused: true */ 4666 4667( function( window, factory ) { 4668 // universal module definition 4669 /*jshint strict: false */ /*globals define, module, require */ 4670 if ( typeof define == 'function' && define.amd ) { 4671 // AMD 4672 define( [ 4673 'flickity/js/index', 4674 'imagesloaded/imagesloaded' 4675 ], function( Flickity, imagesLoaded ) { 4676 return factory( window, Flickity, imagesLoaded ); 4677 }); 4678 } else if ( typeof module == 'object' && module.exports ) { 4679 // CommonJS 4680 module.exports = factory( 4681 window, 4682 require('flickity'), 4683 require('imagesloaded') 4684 ); 4685 } else { 4686 // browser global 4687 window.Flickity = factory( 4688 window, 4689 window.Flickity, 4690 window.imagesLoaded 4691 ); 4692 } 4693 4694}( window, function factory( window, Flickity, imagesLoaded ) { 4695'use strict'; 4696 4697Flickity.createMethods.push('_createImagesLoaded'); 4698 4699var proto = Flickity.prototype; 4700 4701proto._createImagesLoaded = function() { 4702 this.on( 'activate', this.imagesLoaded ); 4703}; 4704 4705proto.imagesLoaded = function() { 4706 if ( !this.options.imagesLoaded ) { 4707 return; 4708 } 4709 var _this = this; 4710 function onImagesLoadedProgress( instance, image ) { 4711 var cell = _this.getParentCell( image.img ); 4712 _this.cellSizeChange( cell && cell.element ); 4713 if ( !_this.options.freeScroll ) { 4714 _this.positionSliderAtSelected(); 4715 } 4716 } 4717 imagesLoaded( this.slider ).on( 'progress', onImagesLoadedProgress ); 4718};
4719 4720return Flickity; 4721 4722}));
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.