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