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