12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586 |
- /*!
- * Flickity PACKAGED v2.2.1
- * Touch, responsive, flickable carousels
- *
- * Licensed GPLv3 for open source use
- * or Flickity Commercial License for commercial use
- *
- * https://flickity.metafizzy.co
- * Copyright 2015-2019 Metafizzy
- */
- /**
- * Bridget makes jQuery widgets
- * v2.0.1
- * MIT license
- */
- /* jshint browser: true, strict: true, undef: true, unused: true */
- ( function( window, factory ) {
- // universal module definition
- /*jshint strict: false */ /* globals define, module, require */
- if ( typeof define == 'function' && define.amd ) {
- // AMD
- define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) {
- return factory( window, jQuery );
- });
- } else if ( typeof module == 'object' && module.exports ) {
- // CommonJS
- module.exports = factory(
- window,
- require('jquery')
- );
- } else {
- // browser global
- window.jQueryBridget = factory(
- window,
- window.jQuery
- );
- }
- }( window, function factory( window, jQuery ) {
- 'use strict';
- // ----- utils ----- //
- var arraySlice = Array.prototype.slice;
- // helper function for logging errors
- // $.error breaks jQuery chaining
- var console = window.console;
- var logError = typeof console == 'undefined' ? function() {} :
- function( message ) {
- console.error( message );
- };
- // ----- jQueryBridget ----- //
- function jQueryBridget( namespace, PluginClass, $ ) {
- $ = $ || jQuery || window.jQuery;
- if ( !$ ) {
- return;
- }
- // add option method -> $().plugin('option', {...})
- if ( !PluginClass.prototype.option ) {
- // option setter
- PluginClass.prototype.option = function( opts ) {
- // bail out if not an object
- if ( !$.isPlainObject( opts ) ){
- return;
- }
- this.options = $.extend( true, this.options, opts );
- };
- }
- // make jQuery plugin
- $.fn[ namespace ] = function( arg0 /*, arg1 */ ) {
- if ( typeof arg0 == 'string' ) {
- // method call $().plugin( 'methodName', { options } )
- // shift arguments by 1
- var args = arraySlice.call( arguments, 1 );
- return methodCall( this, arg0, args );
- }
- // just $().plugin({ options })
- plainCall( this, arg0 );
- return this;
- };
- // $().plugin('methodName')
- function methodCall( $elems, methodName, args ) {
- var returnValue;
- var pluginMethodStr = '$().' + namespace + '("' + methodName + '")';
- $elems.each( function( i, elem ) {
- // get instance
- var instance = $.data( elem, namespace );
- if ( !instance ) {
- logError( namespace + ' not initialized. Cannot call methods, i.e. ' +
- pluginMethodStr );
- return;
- }
- var method = instance[ methodName ];
- if ( !method || methodName.charAt(0) == '_' ) {
- logError( pluginMethodStr + ' is not a valid method' );
- return;
- }
- // apply method, get return value
- var value = method.apply( instance, args );
- // set return value if value is returned, use only first value
- returnValue = returnValue === undefined ? value : returnValue;
- });
- return returnValue !== undefined ? returnValue : $elems;
- }
- function plainCall( $elems, options ) {
- $elems.each( function( i, elem ) {
- var instance = $.data( elem, namespace );
- if ( instance ) {
- // set options & init
- instance.option( options );
- instance._init();
- } else {
- // initialize new instance
- instance = new PluginClass( elem, options );
- $.data( elem, namespace, instance );
- }
- });
- }
- updateJQuery( $ );
- }
- // ----- updateJQuery ----- //
- // set $.bridget for v1 backwards compatibility
- function updateJQuery( $ ) {
- if ( !$ || ( $ && $.bridget ) ) {
- return;
- }
- $.bridget = jQueryBridget;
- }
- updateJQuery( jQuery || window.jQuery );
- // ----- ----- //
- return jQueryBridget;
- }));
- /**
- * EvEmitter v1.1.0
- * Lil' event emitter
- * MIT License
- */
- /* jshint unused: true, undef: true, strict: true */
- ( function( global, factory ) {
- // universal module definition
- /* jshint strict: false */ /* globals define, module, window */
- if ( typeof define == 'function' && define.amd ) {
- // AMD - RequireJS
- define( 'ev-emitter/ev-emitter',factory );
- } else if ( typeof module == 'object' && module.exports ) {
- // CommonJS - Browserify, Webpack
- module.exports = factory();
- } else {
- // Browser globals
- global.EvEmitter = factory();
- }
- }( typeof window != 'undefined' ? window : this, function() {
- function EvEmitter() {}
- var proto = EvEmitter.prototype;
- proto.on = function( eventName, listener ) {
- if ( !eventName || !listener ) {
- return;
- }
- // set events hash
- var events = this._events = this._events || {};
- // set listeners array
- var listeners = events[ eventName ] = events[ eventName ] || [];
- // only add once
- if ( listeners.indexOf( listener ) == -1 ) {
- listeners.push( listener );
- }
- return this;
- };
- proto.once = function( eventName, listener ) {
- if ( !eventName || !listener ) {
- return;
- }
- // add event
- this.on( eventName, listener );
- // set once flag
- // set onceEvents hash
- var onceEvents = this._onceEvents = this._onceEvents || {};
- // set onceListeners object
- var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
- // set flag
- onceListeners[ listener ] = true;
- return this;
- };
- proto.off = function( eventName, listener ) {
- var listeners = this._events && this._events[ eventName ];
- if ( !listeners || !listeners.length ) {
- return;
- }
- var index = listeners.indexOf( listener );
- if ( index != -1 ) {
- listeners.splice( index, 1 );
- }
- return this;
- };
- proto.emitEvent = function( eventName, args ) {
- var listeners = this._events && this._events[ eventName ];
- if ( !listeners || !listeners.length ) {
- return;
- }
- // copy over to avoid interference if .off() in listener
- listeners = listeners.slice(0);
- args = args || [];
- // once stuff
- var onceListeners = this._onceEvents && this._onceEvents[ eventName ];
- for ( var i=0; i < listeners.length; i++ ) {
- var listener = listeners[i]
- var isOnce = onceListeners && onceListeners[ listener ];
- if ( isOnce ) {
- // remove listener
- // remove before trigger to prevent recursion
- this.off( eventName, listener );
- // unset once flag
- delete onceListeners[ listener ];
- }
- // trigger listener
- listener.apply( this, args );
- }
- return this;
- };
- proto.allOff = function() {
- delete this._events;
- delete this._onceEvents;
- };
- return EvEmitter;
- }));
- /*!
- * getSize v2.0.3
- * measure size of elements
- * MIT license
- */
- /* jshint browser: true, strict: true, undef: true, unused: true */
- /* globals console: false */
- ( function( window, factory ) {
- /* jshint strict: false */ /* globals define, module */
- if ( typeof define == 'function' && define.amd ) {
- // AMD
- define( 'get-size/get-size',factory );
- } else if ( typeof module == 'object' && module.exports ) {
- // CommonJS
- module.exports = factory();
- } else {
- // browser global
- window.getSize = factory();
- }
- })( window, function factory() {
- 'use strict';
- // -------------------------- helpers -------------------------- //
- // get a number from a string, not a percentage
- function getStyleSize( value ) {
- var num = parseFloat( value );
- // not a percent like '100%', and a number
- var isValid = value.indexOf('%') == -1 && !isNaN( num );
- return isValid && num;
- }
- function noop() {}
- var logError = typeof console == 'undefined' ? noop :
- function( message ) {
- console.error( message );
- };
- // -------------------------- measurements -------------------------- //
- var measurements = [
- 'paddingLeft',
- 'paddingRight',
- 'paddingTop',
- 'paddingBottom',
- 'marginLeft',
- 'marginRight',
- 'marginTop',
- 'marginBottom',
- 'borderLeftWidth',
- 'borderRightWidth',
- 'borderTopWidth',
- 'borderBottomWidth'
- ];
- var measurementsLength = measurements.length;
- function getZeroSize() {
- var size = {
- width: 0,
- height: 0,
- innerWidth: 0,
- innerHeight: 0,
- outerWidth: 0,
- outerHeight: 0
- };
- for ( var i=0; i < measurementsLength; i++ ) {
- var measurement = measurements[i];
- size[ measurement ] = 0;
- }
- return size;
- }
- // -------------------------- getStyle -------------------------- //
- /**
- * getStyle, get style of element, check for Firefox bug
- * https://bugzilla.mozilla.org/show_bug.cgi?id=548397
- */
- function getStyle( elem ) {
- var style = getComputedStyle( elem );
- if ( !style ) {
- logError( 'Style returned ' + style +
- '. Are you running this code in a hidden iframe on Firefox? ' +
- 'See https://bit.ly/getsizebug1' );
- }
- return style;
- }
- // -------------------------- setup -------------------------- //
- var isSetup = false;
- var isBoxSizeOuter;
- /**
- * setup
- * check isBoxSizerOuter
- * do on first getSize() rather than on page load for Firefox bug
- */
- function setup() {
- // setup once
- if ( isSetup ) {
- return;
- }
- isSetup = true;
- // -------------------------- box sizing -------------------------- //
- /**
- * Chrome & Safari measure the outer-width on style.width on border-box elems
- * IE11 & Firefox<29 measures the inner-width
- */
- var div = document.createElement('div');
- div.style.width = '200px';
- div.style.padding = '1px 2px 3px 4px';
- div.style.borderStyle = 'solid';
- div.style.borderWidth = '1px 2px 3px 4px';
- div.style.boxSizing = 'border-box';
- var body = document.body || document.documentElement;
- body.appendChild( div );
- var style = getStyle( div );
- // round value for browser zoom. desandro/masonry#928
- isBoxSizeOuter = Math.round( getStyleSize( style.width ) ) == 200;
- getSize.isBoxSizeOuter = isBoxSizeOuter;
- body.removeChild( div );
- }
- // -------------------------- getSize -------------------------- //
- function getSize( elem ) {
- setup();
- // use querySeletor if elem is string
- if ( typeof elem == 'string' ) {
- elem = document.querySelector( elem );
- }
- // do not proceed on non-objects
- if ( !elem || typeof elem != 'object' || !elem.nodeType ) {
- return;
- }
- var style = getStyle( elem );
- // if hidden, everything is 0
- if ( style.display == 'none' ) {
- return getZeroSize();
- }
- var size = {};
- size.width = elem.offsetWidth;
- size.height = elem.offsetHeight;
- var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box';
- // get all measurements
- for ( var i=0; i < measurementsLength; i++ ) {
- var measurement = measurements[i];
- var value = style[ measurement ];
- var num = parseFloat( value );
- // any 'auto', 'medium' value will be 0
- size[ measurement ] = !isNaN( num ) ? num : 0;
- }
- var paddingWidth = size.paddingLeft + size.paddingRight;
- var paddingHeight = size.paddingTop + size.paddingBottom;
- var marginWidth = size.marginLeft + size.marginRight;
- var marginHeight = size.marginTop + size.marginBottom;
- var borderWidth = size.borderLeftWidth + size.borderRightWidth;
- var borderHeight = size.borderTopWidth + size.borderBottomWidth;
- var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;
- // overwrite width and height if we can get it from style
- var styleWidth = getStyleSize( style.width );
- if ( styleWidth !== false ) {
- size.width = styleWidth +
- // add padding and border unless it's already including it
- ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );
- }
- var styleHeight = getStyleSize( style.height );
- if ( styleHeight !== false ) {
- size.height = styleHeight +
- // add padding and border unless it's already including it
- ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );
- }
- size.innerWidth = size.width - ( paddingWidth + borderWidth );
- size.innerHeight = size.height - ( paddingHeight + borderHeight );
- size.outerWidth = size.width + marginWidth;
- size.outerHeight = size.height + marginHeight;
- return size;
- }
- return getSize;
- });
- /**
- * matchesSelector v2.0.2
- * matchesSelector( element, '.selector' )
- * MIT license
- */
- /*jshint browser: true, strict: true, undef: true, unused: true */
- ( function( window, factory ) {
- /*global define: false, module: false */
- 'use strict';
- // universal module definition
- if ( typeof define == 'function' && define.amd ) {
- // AMD
- define( 'desandro-matches-selector/matches-selector',factory );
- } else if ( typeof module == 'object' && module.exports ) {
- // CommonJS
- module.exports = factory();
- } else {
- // browser global
- window.matchesSelector = factory();
- }
- }( window, function factory() {
- 'use strict';
- var matchesMethod = ( function() {
- var ElemProto = window.Element.prototype;
- // check for the standard method name first
- if ( ElemProto.matches ) {
- return 'matches';
- }
- // check un-prefixed
- if ( ElemProto.matchesSelector ) {
- return 'matchesSelector';
- }
- // check vendor prefixes
- var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];
- for ( var i=0; i < prefixes.length; i++ ) {
- var prefix = prefixes[i];
- var method = prefix + 'MatchesSelector';
- if ( ElemProto[ method ] ) {
- return method;
- }
- }
- })();
- return function matchesSelector( elem, selector ) {
- return elem[ matchesMethod ]( selector );
- };
- }));
- /**
- * Fizzy UI utils v2.0.7
- * MIT license
- */
- /*jshint browser: true, undef: true, unused: true, strict: true */
- ( function( window, factory ) {
- // universal module definition
- /*jshint strict: false */ /*globals define, module, require */
- if ( typeof define == 'function' && define.amd ) {
- // AMD
- define( 'fizzy-ui-utils/utils',[
- 'desandro-matches-selector/matches-selector'
- ], function( matchesSelector ) {
- return factory( window, matchesSelector );
- });
- } else if ( typeof module == 'object' && module.exports ) {
- // CommonJS
- module.exports = factory(
- window,
- require('desandro-matches-selector')
- );
- } else {
- // browser global
- window.fizzyUIUtils = factory(
- window,
- window.matchesSelector
- );
- }
- }( window, function factory( window, matchesSelector ) {
- var utils = {};
- // ----- extend ----- //
- // extends objects
- utils.extend = function( a, b ) {
- for ( var prop in b ) {
- a[ prop ] = b[ prop ];
- }
- return a;
- };
- // ----- modulo ----- //
- utils.modulo = function( num, div ) {
- return ( ( num % div ) + div ) % div;
- };
- // ----- makeArray ----- //
- var arraySlice = Array.prototype.slice;
- // turn element or nodeList into an array
- utils.makeArray = function( obj ) {
- if ( Array.isArray( obj ) ) {
- // use object if already an array
- return obj;
- }
- // return empty array if undefined or null. #6
- if ( obj === null || obj === undefined ) {
- return [];
- }
- var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
- if ( isArrayLike ) {
- // convert nodeList to array
- return arraySlice.call( obj );
- }
- // array of single index
- return [ obj ];
- };
- // ----- removeFrom ----- //
- utils.removeFrom = function( ary, obj ) {
- var index = ary.indexOf( obj );
- if ( index != -1 ) {
- ary.splice( index, 1 );
- }
- };
- // ----- getParent ----- //
- utils.getParent = function( elem, selector ) {
- while ( elem.parentNode && elem != document.body ) {
- elem = elem.parentNode;
- if ( matchesSelector( elem, selector ) ) {
- return elem;
- }
- }
- };
- // ----- getQueryElement ----- //
- // use element as selector string
- utils.getQueryElement = function( elem ) {
- if ( typeof elem == 'string' ) {
- return document.querySelector( elem );
- }
- return elem;
- };
- // ----- handleEvent ----- //
- // enable .ontype to trigger from .addEventListener( elem, 'type' )
- utils.handleEvent = function( event ) {
- var method = 'on' + event.type;
- if ( this[ method ] ) {
- this[ method ]( event );
- }
- };
- // ----- filterFindElements ----- //
- utils.filterFindElements = function( elems, selector ) {
- // make array of elems
- elems = utils.makeArray( elems );
- var ffElems = [];
- elems.forEach( function( elem ) {
- // check that elem is an actual element
- if ( !( elem instanceof HTMLElement ) ) {
- return;
- }
- // add elem if no selector
- if ( !selector ) {
- ffElems.push( elem );
- return;
- }
- // filter & find items if we have a selector
- // filter
- if ( matchesSelector( elem, selector ) ) {
- ffElems.push( elem );
- }
- // find children
- var childElems = elem.querySelectorAll( selector );
- // concat childElems to filterFound array
- for ( var i=0; i < childElems.length; i++ ) {
- ffElems.push( childElems[i] );
- }
- });
- return ffElems;
- };
- // ----- debounceMethod ----- //
- utils.debounceMethod = function( _class, methodName, threshold ) {
- threshold = threshold || 100;
- // original method
- var method = _class.prototype[ methodName ];
- var timeoutName = methodName + 'Timeout';
- _class.prototype[ methodName ] = function() {
- var timeout = this[ timeoutName ];
- clearTimeout( timeout );
- var args = arguments;
- var _this = this;
- this[ timeoutName ] = setTimeout( function() {
- method.apply( _this, args );
- delete _this[ timeoutName ];
- }, threshold );
- };
- };
- // ----- docReady ----- //
- utils.docReady = function( callback ) {
- var readyState = document.readyState;
- if ( readyState == 'complete' || readyState == 'interactive' ) {
- // do async to allow for other scripts to run. metafizzy/flickity#441
- setTimeout( callback );
- } else {
- document.addEventListener( 'DOMContentLoaded', callback );
- }
- };
- // ----- htmlInit ----- //
- // http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
- utils.toDashed = function( str ) {
- return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {
- return $1 + '-' + $2;
- }).toLowerCase();
- };
- var console = window.console;
- /**
- * allow user to initialize classes via [data-namespace] or .js-namespace class
- * htmlInit( Widget, 'widgetName' )
- * options are parsed from data-namespace-options
- */
- utils.htmlInit = function( WidgetClass, namespace ) {
- utils.docReady( function() {
- var dashedNamespace = utils.toDashed( namespace );
- var dataAttr = 'data-' + dashedNamespace;
- var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' );
- var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace );
- var elems = utils.makeArray( dataAttrElems )
- .concat( utils.makeArray( jsDashElems ) );
- var dataOptionsAttr = dataAttr + '-options';
- var jQuery = window.jQuery;
- elems.forEach( function( elem ) {
- var attr = elem.getAttribute( dataAttr ) ||
- elem.getAttribute( dataOptionsAttr );
- var options;
- try {
- options = attr && JSON.parse( attr );
- } catch ( error ) {
- // log error, do not initialize
- if ( console ) {
- console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className +
- ': ' + error );
- }
- return;
- }
- // initialize
- var instance = new WidgetClass( elem, options );
- // make available via $().data('namespace')
- if ( jQuery ) {
- jQuery.data( elem, namespace, instance );
- }
- });
- });
- };
- // ----- ----- //
- return utils;
- }));
- // Flickity.Cell
- ( function( window, factory ) {
- // universal module definition
- /* jshint strict: false */
- if ( typeof define == 'function' && define.amd ) {
- // AMD
- define( 'flickity/js/cell',[
- 'get-size/get-size'
- ], function( getSize ) {
- return factory( window, getSize );
- });
- } else if ( typeof module == 'object' && module.exports ) {
- // CommonJS
- module.exports = factory(
- window,
- require('get-size')
- );
- } else {
- // browser global
- window.Flickity = window.Flickity || {};
- window.Flickity.Cell = factory(
- window,
- window.getSize
- );
- }
- }( window, function factory( window, getSize ) {
- function Cell( elem, parent ) {
- this.element = elem;
- this.parent = parent;
- this.create();
- }
- var proto = Cell.prototype;
- proto.create = function() {
- this.element.style.position = 'absolute';
- this.element.setAttribute( 'aria-hidden', 'true' );
- this.x = 0;
- this.shift = 0;
- };
- proto.destroy = function() {
- // reset style
- this.unselect();
- this.element.style.position = '';
- var side = this.parent.originSide;
- this.element.style[ side ] = '';
- };
- proto.getSize = function() {
- this.size = getSize( this.element );
- };
- proto.setPosition = function( x ) {
- this.x = x;
- this.updateTarget();
- this.renderPosition( x );
- };
- // setDefaultTarget v1 method, backwards compatibility, remove in v3
- proto.updateTarget = proto.setDefaultTarget = function() {
- var marginProperty = this.parent.originSide == 'left' ? 'marginLeft' : 'marginRight';
- this.target = this.x + this.size[ marginProperty ] +
- this.size.width * this.parent.cellAlign;
- };
- proto.renderPosition = function( x ) {
- // render position of cell with in slider
- var side = this.parent.originSide;
- this.element.style[ side ] = this.parent.getPositionValue( x );
- };
- proto.select = function() {
- this.element.classList.add('is-selected');
- this.element.removeAttribute('aria-hidden');
- };
- proto.unselect = function() {
- this.element.classList.remove('is-selected');
- this.element.setAttribute( 'aria-hidden', 'true' );
- };
- /**
- * @param {Integer} factor - 0, 1, or -1
- **/
- proto.wrapShift = function( shift ) {
- this.shift = shift;
- this.renderPosition( this.x + this.parent.slideableWidth * shift );
- };
- proto.remove = function() {
- this.element.parentNode.removeChild( this.element );
- };
- return Cell;
- }));
- // slide
- ( function( window, factory ) {
- // universal module definition
- /* jshint strict: false */
- if ( typeof define == 'function' && define.amd ) {
- // AMD
- define( 'flickity/js/slide',factory );
- } else if ( typeof module == 'object' && module.exports ) {
- // CommonJS
- module.exports = factory();
- } else {
- // browser global
- window.Flickity = window.Flickity || {};
- window.Flickity.Slide = factory();
- }
- }( window, function factory() {
- 'use strict';
- function Slide( parent ) {
- this.parent = parent;
- this.isOriginLeft = parent.originSide == 'left';
- this.cells = [];
- this.outerWidth = 0;
- this.height = 0;
- }
- var proto = Slide.prototype;
- proto.addCell = function( cell ) {
- this.cells.push( cell );
- this.outerWidth += cell.size.outerWidth;
- this.height = Math.max( cell.size.outerHeight, this.height );
- // first cell stuff
- if ( this.cells.length == 1 ) {
- this.x = cell.x; // x comes from first cell
- var beginMargin = this.isOriginLeft ? 'marginLeft' : 'marginRight';
- this.firstMargin = cell.size[ beginMargin ];
- }
- };
- proto.updateTarget = function() {
- var endMargin = this.isOriginLeft ? 'marginRight' : 'marginLeft';
- var lastCell = this.getLastCell();
- var lastMargin = lastCell ? lastCell.size[ endMargin ] : 0;
- var slideWidth = this.outerWidth - ( this.firstMargin + lastMargin );
- this.target = this.x + this.firstMargin + slideWidth * this.parent.cellAlign;
- };
- proto.getLastCell = function() {
- return this.cells[ this.cells.length - 1 ];
- };
- proto.select = function() {
- this.cells.forEach( function( cell ) {
- cell.select();
- });
- };
- proto.unselect = function() {
- this.cells.forEach( function( cell ) {
- cell.unselect();
- });
- };
- proto.getCellElements = function() {
- return this.cells.map( function( cell ) {
- return cell.element;
- });
- };
- return Slide;
- }));
- // animate
- ( function( window, factory ) {
- // universal module definition
- /* jshint strict: false */
- if ( typeof define == 'function' && define.amd ) {
- // AMD
- define( 'flickity/js/animate',[
- 'fizzy-ui-utils/utils'
- ], function( utils ) {
- return factory( window, utils );
- });
- } else if ( typeof module == 'object' && module.exports ) {
- // CommonJS
- module.exports = factory(
- window,
- require('fizzy-ui-utils')
- );
- } else {
- // browser global
- window.Flickity = window.Flickity || {};
- window.Flickity.animatePrototype = factory(
- window,
- window.fizzyUIUtils
- );
- }
- }( window, function factory( window, utils ) {
- // -------------------------- animate -------------------------- //
- var proto = {};
- proto.startAnimation = function() {
- if ( this.isAnimating ) {
- return;
- }
- this.isAnimating = true;
- this.restingFrames = 0;
- this.animate();
- };
- proto.animate = function() {
- this.applyDragForce();
- this.applySelectedAttraction();
- var previousX = this.x;
- this.integratePhysics();
- this.positionSlider();
- this.settle( previousX );
- // animate next frame
- if ( this.isAnimating ) {
- var _this = this;
- requestAnimationFrame( function animateFrame() {
- _this.animate();
- });
- }
- };
- proto.positionSlider = function() {
- var x = this.x;
- // wrap position around
- if ( this.options.wrapAround && this.cells.length > 1 ) {
- x = utils.modulo( x, this.slideableWidth );
- x = x - this.slideableWidth;
- this.shiftWrapCells( x );
- }
- this.setTranslateX( x, this.isAnimating );
- this.dispatchScrollEvent();
- };
- proto.setTranslateX = function( x, is3d ) {
- x += this.cursorPosition;
- // reverse if right-to-left and using transform
- x = this.options.rightToLeft ? -x : x;
- var translateX = this.getPositionValue( x );
- // use 3D tranforms for hardware acceleration on iOS
- // but use 2D when settled, for better font-rendering
- this.slider.style.transform = is3d ?
- 'translate3d(' + translateX + ',0,0)' : 'translateX(' + translateX + ')';
- };
- proto.dispatchScrollEvent = function() {
- var firstSlide = this.slides[0];
- if ( !firstSlide ) {
- return;
- }
- var positionX = -this.x - firstSlide.target;
- var progress = positionX / this.slidesWidth;
- this.dispatchEvent( 'scroll', null, [ progress, positionX ] );
- };
- proto.positionSliderAtSelected = function() {
- if ( !this.cells.length ) {
- return;
- }
- this.x = -this.selectedSlide.target;
- this.velocity = 0; // stop wobble
- this.positionSlider();
- };
- proto.getPositionValue = function( position ) {
- if ( this.options.percentPosition ) {
- // percent position, round to 2 digits, like 12.34%
- return ( Math.round( ( position / this.size.innerWidth ) * 10000 ) * 0.01 )+ '%';
- } else {
- // pixel positioning
- return Math.round( position ) + 'px';
- }
- };
- proto.settle = function( previousX ) {
- // keep track of frames where x hasn't moved
- if ( !this.isPointerDown && Math.round( this.x * 100 ) == Math.round( previousX * 100 ) ) {
- this.restingFrames++;
- }
- // stop animating if resting for 3 or more frames
- if ( this.restingFrames > 2 ) {
- this.isAnimating = false;
- delete this.isFreeScrolling;
- // render position with translateX when settled
- this.positionSlider();
- this.dispatchEvent( 'settle', null, [ this.selectedIndex ] );
- }
- };
- proto.shiftWrapCells = function( x ) {
- // shift before cells
- var beforeGap = this.cursorPosition + x;
- this._shiftCells( this.beforeShiftCells, beforeGap, -1 );
- // shift after cells
- var afterGap = this.size.innerWidth - ( x + this.slideableWidth + this.cursorPosition );
- this._shiftCells( this.afterShiftCells, afterGap, 1 );
- };
- proto._shiftCells = function( cells, gap, shift ) {
- for ( var i=0; i < cells.length; i++ ) {
- var cell = cells[i];
- var cellShift = gap > 0 ? shift : 0;
- cell.wrapShift( cellShift );
- gap -= cell.size.outerWidth;
- }
- };
- proto._unshiftCells = function( cells ) {
- if ( !cells || !cells.length ) {
- return;
- }
- for ( var i=0; i < cells.length; i++ ) {
- cells[i].wrapShift( 0 );
- }
- };
- // -------------------------- physics -------------------------- //
- proto.integratePhysics = function() {
- this.x += this.velocity;
- this.velocity *= this.getFrictionFactor();
- };
- proto.applyForce = function( force ) {
- this.velocity += force;
- };
- proto.getFrictionFactor = function() {
- return 1 - this.options[ this.isFreeScrolling ? 'freeScrollFriction' : 'friction' ];
- };
- proto.getRestingPosition = function() {
- // my thanks to Steven Wittens, who simplified this math greatly
- return this.x + this.velocity / ( 1 - this.getFrictionFactor() );
- };
- proto.applyDragForce = function() {
- if ( !this.isDraggable || !this.isPointerDown ) {
- return;
- }
- // change the position to drag position by applying force
- var dragVelocity = this.dragX - this.x;
- var dragForce = dragVelocity - this.velocity;
- this.applyForce( dragForce );
- };
- proto.applySelectedAttraction = function() {
- // do not attract if pointer down or no slides
- var dragDown = this.isDraggable && this.isPointerDown;
- if ( dragDown || this.isFreeScrolling || !this.slides.length ) {
- return;
- }
- var distance = this.selectedSlide.target * -1 - this.x;
- var force = distance * this.options.selectedAttraction;
- this.applyForce( force );
- };
- return proto;
- }));
- // Flickity main
- ( function( window, factory ) {
- // universal module definition
- /* jshint strict: false */
- if ( typeof define == 'function' && define.amd ) {
- // AMD
- define( 'flickity/js/flickity',[
- 'ev-emitter/ev-emitter',
- 'get-size/get-size',
- 'fizzy-ui-utils/utils',
- './cell',
- './slide',
- './animate'
- ], function( EvEmitter, getSize, utils, Cell, Slide, animatePrototype ) {
- return factory( window, EvEmitter, getSize, utils, Cell, Slide, animatePrototype );
- });
- } else if ( typeof module == 'object' && module.exports ) {
- // CommonJS
- module.exports = factory(
- window,
- require('ev-emitter'),
- require('get-size'),
- require('fizzy-ui-utils'),
- require('./cell'),
- require('./slide'),
- require('./animate')
- );
- } else {
- // browser global
- var _Flickity = window.Flickity;
- window.Flickity = factory(
- window,
- window.EvEmitter,
- window.getSize,
- window.fizzyUIUtils,
- _Flickity.Cell,
- _Flickity.Slide,
- _Flickity.animatePrototype
- );
- }
- }( window, function factory( window, EvEmitter, getSize,
- utils, Cell, Slide, animatePrototype ) {
- // vars
- var jQuery = window.jQuery;
- var getComputedStyle = window.getComputedStyle;
- var console = window.console;
- function moveElements( elems, toElem ) {
- elems = utils.makeArray( elems );
- while ( elems.length ) {
- toElem.appendChild( elems.shift() );
- }
- }
- // -------------------------- Flickity -------------------------- //
- // globally unique identifiers
- var GUID = 0;
- // internal store of all Flickity intances
- var instances = {};
- function Flickity( element, options ) {
- var queryElement = utils.getQueryElement( element );
- if ( !queryElement ) {
- if ( console ) {
- console.error( 'Bad element for Flickity: ' + ( queryElement || element ) );
- }
- return;
- }
- this.element = queryElement;
- // do not initialize twice on same element
- if ( this.element.flickityGUID ) {
- var instance = instances[ this.element.flickityGUID ];
- instance.option( options );
- return instance;
- }
- // add jQuery
- if ( jQuery ) {
- this.$element = jQuery( this.element );
- }
- // options
- this.options = utils.extend( {}, this.constructor.defaults );
- this.option( options );
- // kick things off
- this._create();
- }
- Flickity.defaults = {
- accessibility: true,
- // adaptiveHeight: false,
- cellAlign: 'center',
- // cellSelector: undefined,
- // contain: false,
- freeScrollFriction: 0.075, // friction when free-scrolling
- friction: 0.28, // friction when selecting
- namespaceJQueryEvents: true,
- // initialIndex: 0,
- percentPosition: true,
- resize: true,
- selectedAttraction: 0.025,
- setGallerySize: true
- // watchCSS: false,
- // wrapAround: false
- };
- // hash of methods triggered on _create()
- Flickity.createMethods = [];
- var proto = Flickity.prototype;
- // inherit EventEmitter
- utils.extend( proto, EvEmitter.prototype );
- proto._create = function() {
- // add id for Flickity.data
- var id = this.guid = ++GUID;
- this.element.flickityGUID = id; // expando
- instances[ id ] = this; // associate via id
- // initial properties
- this.selectedIndex = 0;
- // how many frames slider has been in same position
- this.restingFrames = 0;
- // initial physics properties
- this.x = 0;
- this.velocity = 0;
- this.originSide = this.options.rightToLeft ? 'right' : 'left';
- // create viewport & slider
- this.viewport = document.createElement('div');
- this.viewport.className = 'flickity-viewport';
- this._createSlider();
- if ( this.options.resize || this.options.watchCSS ) {
- window.addEventListener( 'resize', this );
- }
- // add listeners from on option
- for ( var eventName in this.options.on ) {
- var listener = this.options.on[ eventName ];
- this.on( eventName, listener );
- }
- Flickity.createMethods.forEach( function( method ) {
- this[ method ]();
- }, this );
- if ( this.options.watchCSS ) {
- this.watchCSS();
- } else {
- this.activate();
- }
- };
- /**
- * set options
- * @param {Object} opts
- */
- proto.option = function( opts ) {
- utils.extend( this.options, opts );
- };
- proto.activate = function() {
- if ( this.isActive ) {
- return;
- }
- this.isActive = true;
- this.element.classList.add('flickity-enabled');
- if ( this.options.rightToLeft ) {
- this.element.classList.add('flickity-rtl');
- }
- this.getSize();
- // move initial cell elements so they can be loaded as cells
- var cellElems = this._filterFindCellElements( this.element.children );
- moveElements( cellElems, this.slider );
- this.viewport.appendChild( this.slider );
- this.element.appendChild( this.viewport );
- // get cells from children
- this.reloadCells();
- if ( this.options.accessibility ) {
- // allow element to focusable
- this.element.tabIndex = 0;
- // listen for key presses
- this.element.addEventListener( 'keydown', this );
- }
- this.emitEvent('activate');
- this.selectInitialIndex();
- // flag for initial activation, for using initialIndex
- this.isInitActivated = true;
- // ready event. #493
- this.dispatchEvent('ready');
- };
- // slider positions the cells
- proto._createSlider = function() {
- // slider element does all the positioning
- var slider = document.createElement('div');
- slider.className = 'flickity-slider';
- slider.style[ this.originSide ] = 0;
- this.slider = slider;
- };
- proto._filterFindCellElements = function( elems ) {
- return utils.filterFindElements( elems, this.options.cellSelector );
- };
- // goes through all children
- proto.reloadCells = function() {
- // collection of item elements
- this.cells = this._makeCells( this.slider.children );
- this.positionCells();
- this._getWrapShiftCells();
- this.setGallerySize();
- };
- /**
- * turn elements into Flickity.Cells
- * @param {Array or NodeList or HTMLElement} elems
- * @returns {Array} items - collection of new Flickity Cells
- */
- proto._makeCells = function( elems ) {
- var cellElems = this._filterFindCellElements( elems );
- // create new Flickity for collection
- var cells = cellElems.map( function( cellElem ) {
- return new Cell( cellElem, this );
- }, this );
- return cells;
- };
- proto.getLastCell = function() {
- return this.cells[ this.cells.length - 1 ];
- };
- proto.getLastSlide = function() {
- return this.slides[ this.slides.length - 1 ];
- };
- // positions all cells
- proto.positionCells = function() {
- // size all cells
- this._sizeCells( this.cells );
- // position all cells
- this._positionCells( 0 );
- };
- /**
- * position certain cells
- * @param {Integer} index - which cell to start with
- */
- proto._positionCells = function( index ) {
- index = index || 0;
- // also measure maxCellHeight
- // start 0 if positioning all cells
- this.maxCellHeight = index ? this.maxCellHeight || 0 : 0;
- var cellX = 0;
- // get cellX
- if ( index > 0 ) {
- var startCell = this.cells[ index - 1 ];
- cellX = startCell.x + startCell.size.outerWidth;
- }
- var len = this.cells.length;
- for ( var i=index; i < len; i++ ) {
- var cell = this.cells[i];
- cell.setPosition( cellX );
- cellX += cell.size.outerWidth;
- this.maxCellHeight = Math.max( cell.size.outerHeight, this.maxCellHeight );
- }
- // keep track of cellX for wrap-around
- this.slideableWidth = cellX;
- // slides
- this.updateSlides();
- // contain slides target
- this._containSlides();
- // update slidesWidth
- this.slidesWidth = len ? this.getLastSlide().target - this.slides[0].target : 0;
- };
- /**
- * cell.getSize() on multiple cells
- * @param {Array} cells
- */
- proto._sizeCells = function( cells ) {
- cells.forEach( function( cell ) {
- cell.getSize();
- });
- };
- // -------------------------- -------------------------- //
- proto.updateSlides = function() {
- this.slides = [];
- if ( !this.cells.length ) {
- return;
- }
- var slide = new Slide( this );
- this.slides.push( slide );
- var isOriginLeft = this.originSide == 'left';
- var nextMargin = isOriginLeft ? 'marginRight' : 'marginLeft';
- var canCellFit = this._getCanCellFit();
- this.cells.forEach( function( cell, i ) {
- // just add cell if first cell in slide
- if ( !slide.cells.length ) {
- slide.addCell( cell );
- return;
- }
- var slideWidth = ( slide.outerWidth - slide.firstMargin ) +
- ( cell.size.outerWidth - cell.size[ nextMargin ] );
- if ( canCellFit.call( this, i, slideWidth ) ) {
- slide.addCell( cell );
- } else {
- // doesn't fit, new slide
- slide.updateTarget();
- slide = new Slide( this );
- this.slides.push( slide );
- slide.addCell( cell );
- }
- }, this );
- // last slide
- slide.updateTarget();
- // update .selectedSlide
- this.updateSelectedSlide();
- };
- proto._getCanCellFit = function() {
- var groupCells = this.options.groupCells;
- if ( !groupCells ) {
- return function() {
- return false;
- };
- } else if ( typeof groupCells == 'number' ) {
- // group by number. 3 -> [0,1,2], [3,4,5], ...
- var number = parseInt( groupCells, 10 );
- return function( i ) {
- return ( i % number ) !== 0;
- };
- }
- // default, group by width of slide
- // parse '75%
- var percentMatch = typeof groupCells == 'string' &&
- groupCells.match(/^(\d+)%$/);
- var percent = percentMatch ? parseInt( percentMatch[1], 10 ) / 100 : 1;
- return function( i, slideWidth ) {
- return slideWidth <= ( this.size.innerWidth + 1 ) * percent;
- };
- };
- // alias _init for jQuery plugin .flickity()
- proto._init =
- proto.reposition = function() {
- this.positionCells();
- this.positionSliderAtSelected();
- };
- proto.getSize = function() {
- this.size = getSize( this.element );
- this.setCellAlign();
- this.cursorPosition = this.size.innerWidth * this.cellAlign;
- };
- var cellAlignShorthands = {
- // cell align, then based on origin side
- center: {
- left: 0.5,
- right: 0.5
- },
- left: {
- left: 0,
- right: 1
- },
- right: {
- right: 0,
- left: 1
- }
- };
- proto.setCellAlign = function() {
- var shorthand = cellAlignShorthands[ this.options.cellAlign ];
- this.cellAlign = shorthand ? shorthand[ this.originSide ] : this.options.cellAlign;
- };
- proto.setGallerySize = function() {
- if ( this.options.setGallerySize ) {
- var height = this.options.adaptiveHeight && this.selectedSlide ?
- this.selectedSlide.height : this.maxCellHeight;
- this.viewport.style.height = height + 'px';
- }
- };
- proto._getWrapShiftCells = function() {
- // only for wrap-around
- if ( !this.options.wrapAround ) {
- return;
- }
- // unshift previous cells
- this._unshiftCells( this.beforeShiftCells );
- this._unshiftCells( this.afterShiftCells );
- // get before cells
- // initial gap
- var gapX = this.cursorPosition;
- var cellIndex = this.cells.length - 1;
- this.beforeShiftCells = this._getGapCells( gapX, cellIndex, -1 );
- // get after cells
- // ending gap between last cell and end of gallery viewport
- gapX = this.size.innerWidth - this.cursorPosition;
- // start cloning at first cell, working forwards
- this.afterShiftCells = this._getGapCells( gapX, 0, 1 );
- };
- proto._getGapCells = function( gapX, cellIndex, increment ) {
- // keep adding cells until the cover the initial gap
- var cells = [];
- while ( gapX > 0 ) {
- var cell = this.cells[ cellIndex ];
- if ( !cell ) {
- break;
- }
- cells.push( cell );
- cellIndex += increment;
- gapX -= cell.size.outerWidth;
- }
- return cells;
- };
- // ----- contain ----- //
- // contain cell targets so no excess sliding
- proto._containSlides = function() {
- if ( !this.options.contain || this.options.wrapAround || !this.cells.length ) {
- return;
- }
- var isRightToLeft = this.options.rightToLeft;
- var beginMargin = isRightToLeft ? 'marginRight' : 'marginLeft';
- var endMargin = isRightToLeft ? 'marginLeft' : 'marginRight';
- var contentWidth = this.slideableWidth - this.getLastCell().size[ endMargin ];
- // content is less than gallery size
- var isContentSmaller = contentWidth < this.size.innerWidth;
- // bounds
- var beginBound = this.cursorPosition + this.cells[0].size[ beginMargin ];
- var endBound = contentWidth - this.size.innerWidth * ( 1 - this.cellAlign );
- // contain each cell target
- this.slides.forEach( function( slide ) {
- if ( isContentSmaller ) {
- // all cells fit inside gallery
- slide.target = contentWidth * this.cellAlign;
- } else {
- // contain to bounds
- slide.target = Math.max( slide.target, beginBound );
- slide.target = Math.min( slide.target, endBound );
- }
- }, this );
- };
- // ----- ----- //
- /**
- * emits events via eventEmitter and jQuery events
- * @param {String} type - name of event
- * @param {Event} event - original event
- * @param {Array} args - extra arguments
- */
- proto.dispatchEvent = function( type, event, args ) {
- var emitArgs = event ? [ event ].concat( args ) : args;
- this.emitEvent( type, emitArgs );
- if ( jQuery && this.$element ) {
- // default trigger with type if no event
- type += this.options.namespaceJQueryEvents ? '.flickity' : '';
- var $event = type;
- if ( event ) {
- // create jQuery event
- var jQEvent = jQuery.Event( event );
- jQEvent.type = type;
- $event = jQEvent;
- }
- this.$element.trigger( $event, args );
- }
- };
- // -------------------------- select -------------------------- //
- /**
- * @param {Integer} index - index of the slide
- * @param {Boolean} isWrap - will wrap-around to last/first if at the end
- * @param {Boolean} isInstant - will immediately set position at selected cell
- */
- proto.select = function( index, isWrap, isInstant ) {
- if ( !this.isActive ) {
- return;
- }
- index = parseInt( index, 10 );
- this._wrapSelect( index );
- if ( this.options.wrapAround || isWrap ) {
- index = utils.modulo( index, this.slides.length );
- }
- // bail if invalid index
- if ( !this.slides[ index ] ) {
- return;
- }
- var prevIndex = this.selectedIndex;
- this.selectedIndex = index;
- this.updateSelectedSlide();
- if ( isInstant ) {
- this.positionSliderAtSelected();
- } else {
- this.startAnimation();
- }
- if ( this.options.adaptiveHeight ) {
- this.setGallerySize();
- }
- // events
- this.dispatchEvent( 'select', null, [ index ] );
- // change event if new index
- if ( index != prevIndex ) {
- this.dispatchEvent( 'change', null, [ index ] );
- }
- // old v1 event name, remove in v3
- this.dispatchEvent('cellSelect');
- };
- // wraps position for wrapAround, to move to closest slide. #113
- proto._wrapSelect = function( index ) {
- var len = this.slides.length;
- var isWrapping = this.options.wrapAround && len > 1;
- if ( !isWrapping ) {
- return index;
- }
- var wrapIndex = utils.modulo( index, len );
- // go to shortest
- var delta = Math.abs( wrapIndex - this.selectedIndex );
- var backWrapDelta = Math.abs( ( wrapIndex + len ) - this.selectedIndex );
- var forewardWrapDelta = Math.abs( ( wrapIndex - len ) - this.selectedIndex );
- if ( !this.isDragSelect && backWrapDelta < delta ) {
- index += len;
- } else if ( !this.isDragSelect && forewardWrapDelta < delta ) {
- index -= len;
- }
- // wrap position so slider is within normal area
- if ( index < 0 ) {
- this.x -= this.slideableWidth;
- } else if ( index >= len ) {
- this.x += this.slideableWidth;
- }
- };
- proto.previous = function( isWrap, isInstant ) {
- this.select( this.selectedIndex - 1, isWrap, isInstant );
- };
- proto.next = function( isWrap, isInstant ) {
- this.select( this.selectedIndex + 1, isWrap, isInstant );
- };
- proto.updateSelectedSlide = function() {
- var slide = this.slides[ this.selectedIndex ];
- // selectedIndex could be outside of slides, if triggered before resize()
- if ( !slide ) {
- return;
- }
- // unselect previous selected slide
- this.unselectSelectedSlide();
- // update new selected slide
- this.selectedSlide = slide;
- slide.select();
- this.selectedCells = slide.cells;
- this.selectedElements = slide.getCellElements();
- // HACK: selectedCell & selectedElement is first cell in slide, backwards compatibility
- // Remove in v3?
- this.selectedCell = slide.cells[0];
- this.selectedElement = this.selectedElements[0];
- };
- proto.unselectSelectedSlide = function() {
- if ( this.selectedSlide ) {
- this.selectedSlide.unselect();
- }
- };
- proto.selectInitialIndex = function() {
- var initialIndex = this.options.initialIndex;
- // already activated, select previous selectedIndex
- if ( this.isInitActivated ) {
- this.select( this.selectedIndex, false, true );
- return;
- }
- // select with selector string
- if ( initialIndex && typeof initialIndex == 'string' ) {
- var cell = this.queryCell( initialIndex );
- if ( cell ) {
- this.selectCell( initialIndex, false, true );
- return;
- }
- }
- var index = 0;
- // select with number
- if ( initialIndex && this.slides[ initialIndex ] ) {
- index = initialIndex;
- }
- // select instantly
- this.select( index, false, true );
- };
- /**
- * select slide from number or cell element
- * @param {Element or Number} elem
- */
- proto.selectCell = function( value, isWrap, isInstant ) {
- // get cell
- var cell = this.queryCell( value );
- if ( !cell ) {
- return;
- }
- var index = this.getCellSlideIndex( cell );
- this.select( index, isWrap, isInstant );
- };
- proto.getCellSlideIndex = function( cell ) {
- // get index of slides that has cell
- for ( var i=0; i < this.slides.length; i++ ) {
- var slide = this.slides[i];
- var index = slide.cells.indexOf( cell );
- if ( index != -1 ) {
- return i;
- }
- }
- };
- // -------------------------- get cells -------------------------- //
- /**
- * get Flickity.Cell, given an Element
- * @param {Element} elem
- * @returns {Flickity.Cell} item
- */
- proto.getCell = function( elem ) {
- // loop through cells to get the one that matches
- for ( var i=0; i < this.cells.length; i++ ) {
- var cell = this.cells[i];
- if ( cell.element == elem ) {
- return cell;
- }
- }
- };
- /**
- * get collection of Flickity.Cells, given Elements
- * @param {Element, Array, NodeList} elems
- * @returns {Array} cells - Flickity.Cells
- */
- proto.getCells = function( elems ) {
- elems = utils.makeArray( elems );
- var cells = [];
- elems.forEach( function( elem ) {
- var cell = this.getCell( elem );
- if ( cell ) {
- cells.push( cell );
- }
- }, this );
- return cells;
- };
- /**
- * get cell elements
- * @returns {Array} cellElems
- */
- proto.getCellElements = function() {
- return this.cells.map( function( cell ) {
- return cell.element;
- });
- };
- /**
- * get parent cell from an element
- * @param {Element} elem
- * @returns {Flickit.Cell} cell
- */
- proto.getParentCell = function( elem ) {
- // first check if elem is cell
- var cell = this.getCell( elem );
- if ( cell ) {
- return cell;
- }
- // try to get parent cell elem
- elem = utils.getParent( elem, '.flickity-slider > *' );
- return this.getCell( elem );
- };
- /**
- * get cells adjacent to a slide
- * @param {Integer} adjCount - number of adjacent slides
- * @param {Integer} index - index of slide to start
- * @returns {Array} cells - array of Flickity.Cells
- */
- proto.getAdjacentCellElements = function( adjCount, index ) {
- if ( !adjCount ) {
- return this.selectedSlide.getCellElements();
- }
- index = index === undefined ? this.selectedIndex : index;
- var len = this.slides.length;
- if ( 1 + ( adjCount * 2 ) >= len ) {
- return this.getCellElements();
- }
- var cellElems = [];
- for ( var i = index - adjCount; i <= index + adjCount ; i++ ) {
- var slideIndex = this.options.wrapAround ? utils.modulo( i, len ) : i;
- var slide = this.slides[ slideIndex ];
- if ( slide ) {
- cellElems = cellElems.concat( slide.getCellElements() );
- }
- }
- return cellElems;
- };
- /**
- * select slide from number or cell element
- * @param {Element, Selector String, or Number} selector
- */
- proto.queryCell = function( selector ) {
- if ( typeof selector == 'number' ) {
- // use number as index
- return this.cells[ selector ];
- }
- if ( typeof selector == 'string' ) {
- // do not select invalid selectors from hash: #123, #/. #791
- if ( selector.match(/^[#\.]?[\d\/]/) ) {
- return;
- }
- // use string as selector, get element
- selector = this.element.querySelector( selector );
- }
- // get cell from element
- return this.getCell( selector );
- };
- // -------------------------- events -------------------------- //
- proto.uiChange = function() {
- this.emitEvent('uiChange');
- };
- // keep focus on element when child UI elements are clicked
- proto.childUIPointerDown = function( event ) {
- // HACK iOS does not allow touch events to bubble up?!
- if ( event.type != 'touchstart' ) {
- event.preventDefault();
- }
- this.focus();
- };
- // ----- resize ----- //
- proto.onresize = function() {
- this.watchCSS();
- this.resize();
- };
- utils.debounceMethod( Flickity, 'onresize', 150 );
- proto.resize = function() {
- if ( !this.isActive ) {
- return;
- }
- this.getSize();
- // wrap values
- if ( this.options.wrapAround ) {
- this.x = utils.modulo( this.x, this.slideableWidth );
- }
- this.positionCells();
- this._getWrapShiftCells();
- this.setGallerySize();
- this.emitEvent('resize');
- // update selected index for group slides, instant
- // TODO: position can be lost between groups of various numbers
- var selectedElement = this.selectedElements && this.selectedElements[0];
- this.selectCell( selectedElement, false, true );
- };
- // watches the :after property, activates/deactivates
- proto.watchCSS = function() {
- var watchOption = this.options.watchCSS;
- if ( !watchOption ) {
- return;
- }
- var afterContent = getComputedStyle( this.element, ':after' ).content;
- // activate if :after { content: 'flickity' }
- if ( afterContent.indexOf('flickity') != -1 ) {
- this.activate();
- } else {
- this.deactivate();
- }
- };
- // ----- keydown ----- //
- // go previous/next if left/right keys pressed
- proto.onkeydown = function( event ) {
- // only work if element is in focus
- var isNotFocused = document.activeElement && document.activeElement != this.element;
- if ( !this.options.accessibility ||isNotFocused ) {
- return;
- }
- var handler = Flickity.keyboardHandlers[ event.keyCode ];
- if ( handler ) {
- handler.call( this );
- }
- };
- Flickity.keyboardHandlers = {
- // left arrow
- 37: function() {
- var leftMethod = this.options.rightToLeft ? 'next' : 'previous';
- this.uiChange();
- this[ leftMethod ]();
- },
- // right arrow
- 39: function() {
- var rightMethod = this.options.rightToLeft ? 'previous' : 'next';
- this.uiChange();
- this[ rightMethod ]();
- },
- };
- // ----- focus ----- //
- proto.focus = function() {
- // TODO remove scrollTo once focus options gets more support
- // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#Browser_compatibility
- var prevScrollY = window.pageYOffset;
- this.element.focus({ preventScroll: true });
- // hack to fix scroll jump after focus, #76
- if ( window.pageYOffset != prevScrollY ) {
- window.scrollTo( window.pageXOffset, prevScrollY );
- }
- };
- // -------------------------- destroy -------------------------- //
- // deactivate all Flickity functionality, but keep stuff available
- proto.deactivate = function() {
- if ( !this.isActive ) {
- return;
- }
- this.element.classList.remove('flickity-enabled');
- this.element.classList.remove('flickity-rtl');
- this.unselectSelectedSlide();
- // destroy cells
- this.cells.forEach( function( cell ) {
- cell.destroy();
- });
- this.element.removeChild( this.viewport );
- // move child elements back into element
- moveElements( this.slider.children, this.element );
- if ( this.options.accessibility ) {
- this.element.removeAttribute('tabIndex');
- this.element.removeEventListener( 'keydown', this );
- }
- // set flags
- this.isActive = false;
- this.emitEvent('deactivate');
- };
- proto.destroy = function() {
- this.deactivate();
- window.removeEventListener( 'resize', this );
- this.allOff();
- this.emitEvent('destroy');
- if ( jQuery && this.$element ) {
- jQuery.removeData( this.element, 'flickity' );
- }
- delete this.element.flickityGUID;
- delete instances[ this.guid ];
- };
- // -------------------------- prototype -------------------------- //
- utils.extend( proto, animatePrototype );
- // -------------------------- extras -------------------------- //
- /**
- * get Flickity instance from element
- * @param {Element} elem
- * @returns {Flickity}
- */
- Flickity.data = function( elem ) {
- elem = utils.getQueryElement( elem );
- var id = elem && elem.flickityGUID;
- return id && instances[ id ];
- };
- utils.htmlInit( Flickity, 'flickity' );
- if ( jQuery && jQuery.bridget ) {
- jQuery.bridget( 'flickity', Flickity );
- }
- // set internal jQuery, for Webpack + jQuery v3, #478
- Flickity.setJQuery = function( jq ) {
- jQuery = jq;
- };
- Flickity.Cell = Cell;
- Flickity.Slide = Slide;
- return Flickity;
- }));
- /*!
- * Unipointer v2.3.0
- * base class for doing one thing with pointer event
- * MIT license
- */
- /*jshint browser: true, undef: true, unused: true, strict: true */
- ( function( window, factory ) {
- // universal module definition
- /* jshint strict: false */ /*global define, module, require */
- if ( typeof define == 'function' && define.amd ) {
- // AMD
- define( 'unipointer/unipointer',[
- 'ev-emitter/ev-emitter'
- ], function( EvEmitter ) {
- return factory( window, EvEmitter );
- });
- } else if ( typeof module == 'object' && module.exports ) {
- // CommonJS
- module.exports = factory(
- window,
- require('ev-emitter')
- );
- } else {
- // browser global
- window.Unipointer = factory(
- window,
- window.EvEmitter
- );
- }
- }( window, function factory( window, EvEmitter ) {
- function noop() {}
- function Unipointer() {}
- // inherit EvEmitter
- var proto = Unipointer.prototype = Object.create( EvEmitter.prototype );
- proto.bindStartEvent = function( elem ) {
- this._bindStartEvent( elem, true );
- };
- proto.unbindStartEvent = function( elem ) {
- this._bindStartEvent( elem, false );
- };
- /**
- * Add or remove start event
- * @param {Boolean} isAdd - remove if falsey
- */
- proto._bindStartEvent = function( elem, isAdd ) {
- // munge isAdd, default to true
- isAdd = isAdd === undefined ? true : isAdd;
- var bindMethod = isAdd ? 'addEventListener' : 'removeEventListener';
- // default to mouse events
- var startEvent = 'mousedown';
- if ( window.PointerEvent ) {
- // Pointer Events
- startEvent = 'pointerdown';
- } else if ( 'ontouchstart' in window ) {
- // Touch Events. iOS Safari
- startEvent = 'touchstart';
- }
- elem[ bindMethod ]( startEvent, this );
- };
- // trigger handler methods for events
- proto.handleEvent = function( event ) {
- var method = 'on' + event.type;
- if ( this[ method ] ) {
- this[ method ]( event );
- }
- };
- // returns the touch that we're keeping track of
- proto.getTouch = function( touches ) {
- for ( var i=0; i < touches.length; i++ ) {
- var touch = touches[i];
- if ( touch.identifier == this.pointerIdentifier ) {
- return touch;
- }
- }
- };
- // ----- start event ----- //
- proto.onmousedown = function( event ) {
- // dismiss clicks from right or middle buttons
- var button = event.button;
- if ( button && ( button !== 0 && button !== 1 ) ) {
- return;
- }
- this._pointerDown( event, event );
- };
- proto.ontouchstart = function( event ) {
- this._pointerDown( event, event.changedTouches[0] );
- };
- proto.onpointerdown = function( event ) {
- this._pointerDown( event, event );
- };
- /**
- * pointer start
- * @param {Event} event
- * @param {Event or Touch} pointer
- */
- proto._pointerDown = function( event, pointer ) {
- // dismiss right click and other pointers
- // button = 0 is okay, 1-4 not
- if ( event.button || this.isPointerDown ) {
- return;
- }
- this.isPointerDown = true;
- // save pointer identifier to match up touch events
- this.pointerIdentifier = pointer.pointerId !== undefined ?
- // pointerId for pointer events, touch.indentifier for touch events
- pointer.pointerId : pointer.identifier;
- this.pointerDown( event, pointer );
- };
- proto.pointerDown = function( event, pointer ) {
- this._bindPostStartEvents( event );
- this.emitEvent( 'pointerDown', [ event, pointer ] );
- };
- // hash of events to be bound after start event
- var postStartEvents = {
- mousedown: [ 'mousemove', 'mouseup' ],
- touchstart: [ 'touchmove', 'touchend', 'touchcancel' ],
- pointerdown: [ 'pointermove', 'pointerup', 'pointercancel' ],
- };
- proto._bindPostStartEvents = function( event ) {
- if ( !event ) {
- return;
- }
- // get proper events to match start event
- var events = postStartEvents[ event.type ];
- // bind events to node
- events.forEach( function( eventName ) {
- window.addEventListener( eventName, this );
- }, this );
- // save these arguments
- this._boundPointerEvents = events;
- };
- proto._unbindPostStartEvents = function() {
- // check for _boundEvents, in case dragEnd triggered twice (old IE8 bug)
- if ( !this._boundPointerEvents ) {
- return;
- }
- this._boundPointerEvents.forEach( function( eventName ) {
- window.removeEventListener( eventName, this );
- }, this );
- delete this._boundPointerEvents;
- };
- // ----- move event ----- //
- proto.onmousemove = function( event ) {
- this._pointerMove( event, event );
- };
- proto.onpointermove = function( event ) {
- if ( event.pointerId == this.pointerIdentifier ) {
- this._pointerMove( event, event );
- }
- };
- proto.ontouchmove = function( event ) {
- var touch = this.getTouch( event.changedTouches );
- if ( touch ) {
- this._pointerMove( event, touch );
- }
- };
- /**
- * pointer move
- * @param {Event} event
- * @param {Event or Touch} pointer
- * @private
- */
- proto._pointerMove = function( event, pointer ) {
- this.pointerMove( event, pointer );
- };
- // public
- proto.pointerMove = function( event, pointer ) {
- this.emitEvent( 'pointerMove', [ event, pointer ] );
- };
- // ----- end event ----- //
- proto.onmouseup = function( event ) {
- this._pointerUp( event, event );
- };
- proto.onpointerup = function( event ) {
- if ( event.pointerId == this.pointerIdentifier ) {
- this._pointerUp( event, event );
- }
- };
- proto.ontouchend = function( event ) {
- var touch = this.getTouch( event.changedTouches );
- if ( touch ) {
- this._pointerUp( event, touch );
- }
- };
- /**
- * pointer up
- * @param {Event} event
- * @param {Event or Touch} pointer
- * @private
- */
- proto._pointerUp = function( event, pointer ) {
- this._pointerDone();
- this.pointerUp( event, pointer );
- };
- // public
- proto.pointerUp = function( event, pointer ) {
- this.emitEvent( 'pointerUp', [ event, pointer ] );
- };
- // ----- pointer done ----- //
- // triggered on pointer up & pointer cancel
- proto._pointerDone = function() {
- this._pointerReset();
- this._unbindPostStartEvents();
- this.pointerDone();
- };
- proto._pointerReset = function() {
- // reset properties
- this.isPointerDown = false;
- delete this.pointerIdentifier;
- };
- proto.pointerDone = noop;
- // ----- pointer cancel ----- //
- proto.onpointercancel = function( event ) {
- if ( event.pointerId == this.pointerIdentifier ) {
- this._pointerCancel( event, event );
- }
- };
- proto.ontouchcancel = function( event ) {
- var touch = this.getTouch( event.changedTouches );
- if ( touch ) {
- this._pointerCancel( event, touch );
- }
- };
- /**
- * pointer cancel
- * @param {Event} event
- * @param {Event or Touch} pointer
- * @private
- */
- proto._pointerCancel = function( event, pointer ) {
- this._pointerDone();
- this.pointerCancel( event, pointer );
- };
- // public
- proto.pointerCancel = function( event, pointer ) {
- this.emitEvent( 'pointerCancel', [ event, pointer ] );
- };
- // ----- ----- //
- // utility function for getting x/y coords from event
- Unipointer.getPointerPoint = function( pointer ) {
- return {
- x: pointer.pageX,
- y: pointer.pageY
- };
- };
- // ----- ----- //
- return Unipointer;
- }));
- /*!
- * Unidragger v2.3.0
- * Draggable base class
- * MIT license
- */
- /*jshint browser: true, unused: true, undef: true, strict: true */
- ( function( window, factory ) {
- // universal module definition
- /*jshint strict: false */ /*globals define, module, require */
- if ( typeof define == 'function' && define.amd ) {
- // AMD
- define( 'unidragger/unidragger',[
- 'unipointer/unipointer'
- ], function( Unipointer ) {
- return factory( window, Unipointer );
- });
- } else if ( typeof module == 'object' && module.exports ) {
- // CommonJS
- module.exports = factory(
- window,
- require('unipointer')
- );
- } else {
- // browser global
- window.Unidragger = factory(
- window,
- window.Unipointer
- );
- }
- }( window, function factory( window, Unipointer ) {
- // -------------------------- Unidragger -------------------------- //
- function Unidragger() {}
- // inherit Unipointer & EvEmitter
- var proto = Unidragger.prototype = Object.create( Unipointer.prototype );
- // ----- bind start ----- //
- proto.bindHandles = function() {
- this._bindHandles( true );
- };
- proto.unbindHandles = function() {
- this._bindHandles( false );
- };
- /**
- * Add or remove start event
- * @param {Boolean} isAdd
- */
- proto._bindHandles = function( isAdd ) {
- // munge isAdd, default to true
- isAdd = isAdd === undefined ? true : isAdd;
- // bind each handle
- var bindMethod = isAdd ? 'addEventListener' : 'removeEventListener';
- var touchAction = isAdd ? this._touchActionValue : '';
- for ( var i=0; i < this.handles.length; i++ ) {
- var handle = this.handles[i];
- this._bindStartEvent( handle, isAdd );
- handle[ bindMethod ]( 'click', this );
- // touch-action: none to override browser touch gestures. metafizzy/flickity#540
- if ( window.PointerEvent ) {
- handle.style.touchAction = touchAction;
- }
- }
- };
- // prototype so it can be overwriteable by Flickity
- proto._touchActionValue = 'none';
- // ----- start event ----- //
- /**
- * pointer start
- * @param {Event} event
- * @param {Event or Touch} pointer
- */
- proto.pointerDown = function( event, pointer ) {
- var isOkay = this.okayPointerDown( event );
- if ( !isOkay ) {
- return;
- }
- // track start event position
- this.pointerDownPointer = pointer;
- event.preventDefault();
- this.pointerDownBlur();
- // bind move and end events
- this._bindPostStartEvents( event );
- this.emitEvent( 'pointerDown', [ event, pointer ] );
- };
- // nodes that have text fields
- var cursorNodes = {
- TEXTAREA: true,
- INPUT: true,
- SELECT: true,
- OPTION: true,
- };
- // input types that do not have text fields
- var clickTypes = {
- radio: true,
- checkbox: true,
- button: true,
- submit: true,
- image: true,
- file: true,
- };
- // dismiss inputs with text fields. flickity#403, flickity#404
- proto.okayPointerDown = function( event ) {
- var isCursorNode = cursorNodes[ event.target.nodeName ];
- var isClickType = clickTypes[ event.target.type ];
- var isOkay = !isCursorNode || isClickType;
- if ( !isOkay ) {
- this._pointerReset();
- }
- return isOkay;
- };
- // kludge to blur previously focused input
- proto.pointerDownBlur = function() {
- var focused = document.activeElement;
- // do not blur body for IE10, metafizzy/flickity#117
- var canBlur = focused && focused.blur && focused != document.body;
- if ( canBlur ) {
- focused.blur();
- }
- };
- // ----- move event ----- //
- /**
- * drag move
- * @param {Event} event
- * @param {Event or Touch} pointer
- */
- proto.pointerMove = function( event, pointer ) {
- var moveVector = this._dragPointerMove( event, pointer );
- this.emitEvent( 'pointerMove', [ event, pointer, moveVector ] );
- this._dragMove( event, pointer, moveVector );
- };
- // base pointer move logic
- proto._dragPointerMove = function( event, pointer ) {
- var moveVector = {
- x: pointer.pageX - this.pointerDownPointer.pageX,
- y: pointer.pageY - this.pointerDownPointer.pageY
- };
- // start drag if pointer has moved far enough to start drag
- if ( !this.isDragging && this.hasDragStarted( moveVector ) ) {
- this._dragStart( event, pointer );
- }
- return moveVector;
- };
- // condition if pointer has moved far enough to start drag
- proto.hasDragStarted = function( moveVector ) {
- return Math.abs( moveVector.x ) > 3 || Math.abs( moveVector.y ) > 3;
- };
- // ----- end event ----- //
- /**
- * pointer up
- * @param {Event} event
- * @param {Event or Touch} pointer
- */
- proto.pointerUp = function( event, pointer ) {
- this.emitEvent( 'pointerUp', [ event, pointer ] );
- this._dragPointerUp( event, pointer );
- };
- proto._dragPointerUp = function( event, pointer ) {
- if ( this.isDragging ) {
- this._dragEnd( event, pointer );
- } else {
- // pointer didn't move enough for drag to start
- this._staticClick( event, pointer );
- }
- };
- // -------------------------- drag -------------------------- //
- // dragStart
- proto._dragStart = function( event, pointer ) {
- this.isDragging = true;
- // prevent clicks
- this.isPreventingClicks = true;
- this.dragStart( event, pointer );
- };
- proto.dragStart = function( event, pointer ) {
- this.emitEvent( 'dragStart', [ event, pointer ] );
- };
- // dragMove
- proto._dragMove = function( event, pointer, moveVector ) {
- // do not drag if not dragging yet
- if ( !this.isDragging ) {
- return;
- }
- this.dragMove( event, pointer, moveVector );
- };
- proto.dragMove = function( event, pointer, moveVector ) {
- event.preventDefault();
- this.emitEvent( 'dragMove', [ event, pointer, moveVector ] );
- };
- // dragEnd
- proto._dragEnd = function( event, pointer ) {
- // set flags
- this.isDragging = false;
- // re-enable clicking async
- setTimeout( function() {
- delete this.isPreventingClicks;
- }.bind( this ) );
- this.dragEnd( event, pointer );
- };
- proto.dragEnd = function( event, pointer ) {
- this.emitEvent( 'dragEnd', [ event, pointer ] );
- };
- // ----- onclick ----- //
- // handle all clicks and prevent clicks when dragging
- proto.onclick = function( event ) {
- if ( this.isPreventingClicks ) {
- event.preventDefault();
- }
- };
- // ----- staticClick ----- //
- // triggered after pointer down & up with no/tiny movement
- proto._staticClick = function( event, pointer ) {
- // ignore emulated mouse up clicks
- if ( this.isIgnoringMouseUp && event.type == 'mouseup' ) {
- return;
- }
- this.staticClick( event, pointer );
- // set flag for emulated clicks 300ms after touchend
- if ( event.type != 'mouseup' ) {
- this.isIgnoringMouseUp = true;
- // reset flag after 300ms
- setTimeout( function() {
- delete this.isIgnoringMouseUp;
- }.bind( this ), 400 );
- }
- };
- proto.staticClick = function( event, pointer ) {
- this.emitEvent( 'staticClick', [ event, pointer ] );
- };
- // ----- utils ----- //
- Unidragger.getPointerPoint = Unipointer.getPointerPoint;
- // ----- ----- //
- return Unidragger;
- }));
- // drag
- ( function( window, factory ) {
- // universal module definition
- /* jshint strict: false */
- if ( typeof define == 'function' && define.amd ) {
- // AMD
- define( 'flickity/js/drag',[
- './flickity',
- 'unidragger/unidragger',
- 'fizzy-ui-utils/utils'
- ], function( Flickity, Unidragger, utils ) {
- return factory( window, Flickity, Unidragger, utils );
- });
- } else if ( typeof module == 'object' && module.exports ) {
- // CommonJS
- module.exports = factory(
- window,
- require('./flickity'),
- require('unidragger'),
- require('fizzy-ui-utils')
- );
- } else {
- // browser global
- window.Flickity = factory(
- window,
- window.Flickity,
- window.Unidragger,
- window.fizzyUIUtils
- );
- }
- }( window, function factory( window, Flickity, Unidragger, utils ) {
- // ----- defaults ----- //
- utils.extend( Flickity.defaults, {
- draggable: '>1',
- dragThreshold: 3,
- });
- // ----- create ----- //
- Flickity.createMethods.push('_createDrag');
- // -------------------------- drag prototype -------------------------- //
- var proto = Flickity.prototype;
- utils.extend( proto, Unidragger.prototype );
- proto._touchActionValue = 'pan-y';
- // -------------------------- -------------------------- //
- var isTouch = 'createTouch' in document;
- var isTouchmoveScrollCanceled = false;
- proto._createDrag = function() {
- this.on( 'activate', this.onActivateDrag );
- this.on( 'uiChange', this._uiChangeDrag );
- this.on( 'deactivate', this.onDeactivateDrag );
- this.on( 'cellChange', this.updateDraggable );
- // TODO updateDraggable on resize? if groupCells & slides change
- // HACK - add seemingly innocuous handler to fix iOS 10 scroll behavior
- // #457, RubaXa/Sortable#973
- if ( isTouch && !isTouchmoveScrollCanceled ) {
- window.addEventListener( 'touchmove', function() {});
- isTouchmoveScrollCanceled = true;
- }
- };
- proto.onActivateDrag = function() {
- this.handles = [ this.viewport ];
- this.bindHandles();
- this.updateDraggable();
- };
- proto.onDeactivateDrag = function() {
- this.unbindHandles();
- this.element.classList.remove('is-draggable');
- };
- proto.updateDraggable = function() {
- // disable dragging if less than 2 slides. #278
- if ( this.options.draggable == '>1' ) {
- this.isDraggable = this.slides.length > 1;
- } else {
- this.isDraggable = this.options.draggable;
- }
- if ( this.isDraggable ) {
- this.element.classList.add('is-draggable');
- } else {
- this.element.classList.remove('is-draggable');
- }
- };
- // backwards compatibility
- proto.bindDrag = function() {
- this.options.draggable = true;
- this.updateDraggable();
- };
- proto.unbindDrag = function() {
- this.options.draggable = false;
- this.updateDraggable();
- };
- proto._uiChangeDrag = function() {
- delete this.isFreeScrolling;
- };
- // -------------------------- pointer events -------------------------- //
- proto.pointerDown = function( event, pointer ) {
- if ( !this.isDraggable ) {
- this._pointerDownDefault( event, pointer );
- return;
- }
- var isOkay = this.okayPointerDown( event );
- if ( !isOkay ) {
- return;
- }
- this._pointerDownPreventDefault( event );
- this.pointerDownFocus( event );
- // blur
- if ( document.activeElement != this.element ) {
- // do not blur if already focused
- this.pointerDownBlur();
- }
- // stop if it was moving
- this.dragX = this.x;
- this.viewport.classList.add('is-pointer-down');
- // track scrolling
- this.pointerDownScroll = getScrollPosition();
- window.addEventListener( 'scroll', this );
- this._pointerDownDefault( event, pointer );
- };
- // default pointerDown logic, used for staticClick
- proto._pointerDownDefault = function( event, pointer ) {
- // track start event position
- // Safari 9 overrides pageX and pageY. These values needs to be copied. #779
- this.pointerDownPointer = {
- pageX: pointer.pageX,
- pageY: pointer.pageY,
- };
- // bind move and end events
- this._bindPostStartEvents( event );
- this.dispatchEvent( 'pointerDown', event, [ pointer ] );
- };
- var focusNodes = {
- INPUT: true,
- TEXTAREA: true,
- SELECT: true,
- };
- proto.pointerDownFocus = function( event ) {
- var isFocusNode = focusNodes[ event.target.nodeName ];
- if ( !isFocusNode ) {
- this.focus();
- }
- };
- proto._pointerDownPreventDefault = function( event ) {
- var isTouchStart = event.type == 'touchstart';
- var isTouchPointer = event.pointerType == 'touch';
- var isFocusNode = focusNodes[ event.target.nodeName ];
- if ( !isTouchStart && !isTouchPointer && !isFocusNode ) {
- event.preventDefault();
- }
- };
- // ----- move ----- //
- proto.hasDragStarted = function( moveVector ) {
- return Math.abs( moveVector.x ) > this.options.dragThreshold;
- };
- // ----- up ----- //
- proto.pointerUp = function( event, pointer ) {
- delete this.isTouchScrolling;
- this.viewport.classList.remove('is-pointer-down');
- this.dispatchEvent( 'pointerUp', event, [ pointer ] );
- this._dragPointerUp( event, pointer );
- };
- proto.pointerDone = function() {
- window.removeEventListener( 'scroll', this );
- delete this.pointerDownScroll;
- };
- // -------------------------- dragging -------------------------- //
- proto.dragStart = function( event, pointer ) {
- if ( !this.isDraggable ) {
- return;
- }
- this.dragStartPosition = this.x;
- this.startAnimation();
- window.removeEventListener( 'scroll', this );
- this.dispatchEvent( 'dragStart', event, [ pointer ] );
- };
- proto.pointerMove = function( event, pointer ) {
- var moveVector = this._dragPointerMove( event, pointer );
- this.dispatchEvent( 'pointerMove', event, [ pointer, moveVector ] );
- this._dragMove( event, pointer, moveVector );
- };
- proto.dragMove = function( event, pointer, moveVector ) {
- if ( !this.isDraggable ) {
- return;
- }
- event.preventDefault();
- this.previousDragX = this.dragX;
- // reverse if right-to-left
- var direction = this.options.rightToLeft ? -1 : 1;
- if ( this.options.wrapAround ) {
- // wrap around move. #589
- moveVector.x = moveVector.x % this.slideableWidth;
- }
- var dragX = this.dragStartPosition + moveVector.x * direction;
- if ( !this.options.wrapAround && this.slides.length ) {
- // slow drag
- var originBound = Math.max( -this.slides[0].target, this.dragStartPosition );
- dragX = dragX > originBound ? ( dragX + originBound ) * 0.5 : dragX;
- var endBound = Math.min( -this.getLastSlide().target, this.dragStartPosition );
- dragX = dragX < endBound ? ( dragX + endBound ) * 0.5 : dragX;
- }
- this.dragX = dragX;
- this.dragMoveTime = new Date();
- this.dispatchEvent( 'dragMove', event, [ pointer, moveVector ] );
- };
- proto.dragEnd = function( event, pointer ) {
- if ( !this.isDraggable ) {
- return;
- }
- if ( this.options.freeScroll ) {
- this.isFreeScrolling = true;
- }
- // set selectedIndex based on where flick will end up
- var index = this.dragEndRestingSelect();
- if ( this.options.freeScroll && !this.options.wrapAround ) {
- // if free-scroll & not wrap around
- // do not free-scroll if going outside of bounding slides
- // so bounding slides can attract slider, and keep it in bounds
- var restingX = this.getRestingPosition();
- this.isFreeScrolling = -restingX > this.slides[0].target &&
- -restingX < this.getLastSlide().target;
- } else if ( !this.options.freeScroll && index == this.selectedIndex ) {
- // boost selection if selected index has not changed
- index += this.dragEndBoostSelect();
- }
- delete this.previousDragX;
- // apply selection
- // TODO refactor this, selecting here feels weird
- // HACK, set flag so dragging stays in correct direction
- this.isDragSelect = this.options.wrapAround;
- this.select( index );
- delete this.isDragSelect;
- this.dispatchEvent( 'dragEnd', event, [ pointer ] );
- };
- proto.dragEndRestingSelect = function() {
- var restingX = this.getRestingPosition();
- // how far away from selected slide
- var distance = Math.abs( this.getSlideDistance( -restingX, this.selectedIndex ) );
- // get closet resting going up and going down
- var positiveResting = this._getClosestResting( restingX, distance, 1 );
- var negativeResting = this._getClosestResting( restingX, distance, -1 );
- // use closer resting for wrap-around
- var index = positiveResting.distance < negativeResting.distance ?
- positiveResting.index : negativeResting.index;
- return index;
- };
- /**
- * given resting X and distance to selected cell
- * get the distance and index of the closest cell
- * @param {Number} restingX - estimated post-flick resting position
- * @param {Number} distance - distance to selected cell
- * @param {Integer} increment - +1 or -1, going up or down
- * @returns {Object} - { distance: {Number}, index: {Integer} }
- */
- proto._getClosestResting = function( restingX, distance, increment ) {
- var index = this.selectedIndex;
- var minDistance = Infinity;
- var condition = this.options.contain && !this.options.wrapAround ?
- // if contain, keep going if distance is equal to minDistance
- function( d, md ) { return d <= md; } : function( d, md ) { return d < md; };
- while ( condition( distance, minDistance ) ) {
- // measure distance to next cell
- index += increment;
- minDistance = distance;
- distance = this.getSlideDistance( -restingX, index );
- if ( distance === null ) {
- break;
- }
- distance = Math.abs( distance );
- }
- return {
- distance: minDistance,
- // selected was previous index
- index: index - increment
- };
- };
- /**
- * measure distance between x and a slide target
- * @param {Number} x
- * @param {Integer} index - slide index
- */
- proto.getSlideDistance = function( x, index ) {
- var len = this.slides.length;
- // wrap around if at least 2 slides
- var isWrapAround = this.options.wrapAround && len > 1;
- var slideIndex = isWrapAround ? utils.modulo( index, len ) : index;
- var slide = this.slides[ slideIndex ];
- if ( !slide ) {
- return null;
- }
- // add distance for wrap-around slides
- var wrap = isWrapAround ? this.slideableWidth * Math.floor( index / len ) : 0;
- return x - ( slide.target + wrap );
- };
- proto.dragEndBoostSelect = function() {
- // do not boost if no previousDragX or dragMoveTime
- if ( this.previousDragX === undefined || !this.dragMoveTime ||
- // or if drag was held for 100 ms
- new Date() - this.dragMoveTime > 100 ) {
- return 0;
- }
- var distance = this.getSlideDistance( -this.dragX, this.selectedIndex );
- var delta = this.previousDragX - this.dragX;
- if ( distance > 0 && delta > 0 ) {
- // boost to next if moving towards the right, and positive velocity
- return 1;
- } else if ( distance < 0 && delta < 0 ) {
- // boost to previous if moving towards the left, and negative velocity
- return -1;
- }
- return 0;
- };
- // ----- staticClick ----- //
- proto.staticClick = function( event, pointer ) {
- // get clickedCell, if cell was clicked
- var clickedCell = this.getParentCell( event.target );
- var cellElem = clickedCell && clickedCell.element;
- var cellIndex = clickedCell && this.cells.indexOf( clickedCell );
- this.dispatchEvent( 'staticClick', event, [ pointer, cellElem, cellIndex ] );
- };
- // ----- scroll ----- //
- proto.onscroll = function() {
- var scroll = getScrollPosition();
- var scrollMoveX = this.pointerDownScroll.x - scroll.x;
- var scrollMoveY = this.pointerDownScroll.y - scroll.y;
- // cancel click/tap if scroll is too much
- if ( Math.abs( scrollMoveX ) > 3 || Math.abs( scrollMoveY ) > 3 ) {
- this._pointerDone();
- }
- };
- // ----- utils ----- //
- function getScrollPosition() {
- return {
- x: window.pageXOffset,
- y: window.pageYOffset
- };
- }
- // ----- ----- //
- return Flickity;
- }));
- // prev/next buttons
- ( function( window, factory ) {
- // universal module definition
- /* jshint strict: false */
- if ( typeof define == 'function' && define.amd ) {
- // AMD
- define( 'flickity/js/prev-next-button',[
- './flickity',
- 'unipointer/unipointer',
- 'fizzy-ui-utils/utils'
- ], function( Flickity, Unipointer, utils ) {
- return factory( window, Flickity, Unipointer, utils );
- });
- } else if ( typeof module == 'object' && module.exports ) {
- // CommonJS
- module.exports = factory(
- window,
- require('./flickity'),
- require('unipointer'),
- require('fizzy-ui-utils')
- );
- } else {
- // browser global
- factory(
- window,
- window.Flickity,
- window.Unipointer,
- window.fizzyUIUtils
- );
- }
- }( window, function factory( window, Flickity, Unipointer, utils ) {
- 'use strict';
- var svgURI = 'http://www.w3.org/2000/svg';
- // -------------------------- PrevNextButton -------------------------- //
- function PrevNextButton( direction, parent ) {
- this.direction = direction;
- this.parent = parent;
- this._create();
- }
- PrevNextButton.prototype = Object.create( Unipointer.prototype );
- PrevNextButton.prototype._create = function() {
- // properties
- this.isEnabled = true;
- this.isPrevious = this.direction == -1;
- var leftDirection = this.parent.options.rightToLeft ? 1 : -1;
- this.isLeft = this.direction == leftDirection;
- var element = this.element = document.createElement('button');
- element.className = 'flickity-button flickity-prev-next-button';
- element.className += this.isPrevious ? ' previous' : ' next';
- // prevent button from submitting form http://stackoverflow.com/a/10836076/182183
- element.setAttribute( 'type', 'button' );
- // init as disabled
- this.disable();
- element.setAttribute( 'aria-label', this.isPrevious ? 'Previous' : 'Next' );
- // create arrow
- var svg = this.createSVG();
- element.appendChild( svg );
- // events
- this.parent.on( 'select', this.update.bind( this ) );
- this.on( 'pointerDown', this.parent.childUIPointerDown.bind( this.parent ) );
- };
- PrevNextButton.prototype.activate = function() {
- this.bindStartEvent( this.element );
- this.element.addEventListener( 'click', this );
- // add to DOM
- this.parent.element.appendChild( this.element );
- };
- PrevNextButton.prototype.deactivate = function() {
- // remove from DOM
- this.parent.element.removeChild( this.element );
- // click events
- this.unbindStartEvent( this.element );
- this.element.removeEventListener( 'click', this );
- };
- PrevNextButton.prototype.createSVG = function() {
- var svg = document.createElementNS( svgURI, 'svg');
- svg.setAttribute( 'class', 'flickity-button-icon' );
- svg.setAttribute( 'viewBox', '0 0 100 100' );
- var path = document.createElementNS( svgURI, 'path');
- var pathMovements = getArrowMovements( this.parent.options.arrowShape );
- path.setAttribute( 'd', pathMovements );
- path.setAttribute( 'class', 'arrow' );
- // rotate arrow
- if ( !this.isLeft ) {
- path.setAttribute( 'transform', 'translate(100, 100) rotate(180) ' );
- }
- svg.appendChild( path );
- return svg;
- };
- // get SVG path movmement
- function getArrowMovements( shape ) {
- // use shape as movement if string
- if ( typeof shape == 'string' ) {
- return shape;
- }
- // create movement string
- return 'M ' + shape.x0 + ',50' +
- ' L ' + shape.x1 + ',' + ( shape.y1 + 50 ) +
- ' L ' + shape.x2 + ',' + ( shape.y2 + 50 ) +
- ' L ' + shape.x3 + ',50 ' +
- ' L ' + shape.x2 + ',' + ( 50 - shape.y2 ) +
- ' L ' + shape.x1 + ',' + ( 50 - shape.y1 ) +
- ' Z';
- }
- PrevNextButton.prototype.handleEvent = utils.handleEvent;
- PrevNextButton.prototype.onclick = function() {
- if ( !this.isEnabled ) {
- return;
- }
- this.parent.uiChange();
- var method = this.isPrevious ? 'previous' : 'next';
- this.parent[ method ]();
- };
- // ----- ----- //
- PrevNextButton.prototype.enable = function() {
- if ( this.isEnabled ) {
- return;
- }
- this.element.disabled = false;
- this.isEnabled = true;
- };
- PrevNextButton.prototype.disable = function() {
- if ( !this.isEnabled ) {
- return;
- }
- this.element.disabled = true;
- this.isEnabled = false;
- };
- PrevNextButton.prototype.update = function() {
- // index of first or last slide, if previous or next
- var slides = this.parent.slides;
- // enable is wrapAround and at least 2 slides
- if ( this.parent.options.wrapAround && slides.length > 1 ) {
- this.enable();
- return;
- }
- var lastIndex = slides.length ? slides.length - 1 : 0;
- var boundIndex = this.isPrevious ? 0 : lastIndex;
- var method = this.parent.selectedIndex == boundIndex ? 'disable' : 'enable';
- this[ method ]();
- };
- PrevNextButton.prototype.destroy = function() {
- this.deactivate();
- this.allOff();
- };
- // -------------------------- Flickity prototype -------------------------- //
- utils.extend( Flickity.defaults, {
- prevNextButtons: true,
- arrowShape: {
- x0: 10,
- x1: 60, y1: 50,
- x2: 70, y2: 40,
- x3: 30
- }
- });
- Flickity.createMethods.push('_createPrevNextButtons');
- var proto = Flickity.prototype;
- proto._createPrevNextButtons = function() {
- if ( !this.options.prevNextButtons ) {
- return;
- }
- this.prevButton = new PrevNextButton( -1, this );
- this.nextButton = new PrevNextButton( 1, this );
- this.on( 'activate', this.activatePrevNextButtons );
- };
- proto.activatePrevNextButtons = function() {
- this.prevButton.activate();
- this.nextButton.activate();
- this.on( 'deactivate', this.deactivatePrevNextButtons );
- };
- proto.deactivatePrevNextButtons = function() {
- this.prevButton.deactivate();
- this.nextButton.deactivate();
- this.off( 'deactivate', this.deactivatePrevNextButtons );
- };
- // -------------------------- -------------------------- //
- Flickity.PrevNextButton = PrevNextButton;
- return Flickity;
- }));
- // page dots
- ( function( window, factory ) {
- // universal module definition
- /* jshint strict: false */
- if ( typeof define == 'function' && define.amd ) {
- // AMD
- define( 'flickity/js/page-dots',[
- './flickity',
- 'unipointer/unipointer',
- 'fizzy-ui-utils/utils'
- ], function( Flickity, Unipointer, utils ) {
- return factory( window, Flickity, Unipointer, utils );
- });
- } else if ( typeof module == 'object' && module.exports ) {
- // CommonJS
- module.exports = factory(
- window,
- require('./flickity'),
- require('unipointer'),
- require('fizzy-ui-utils')
- );
- } else {
- // browser global
- factory(
- window,
- window.Flickity,
- window.Unipointer,
- window.fizzyUIUtils
- );
- }
- }( window, function factory( window, Flickity, Unipointer, utils ) {
- // -------------------------- PageDots -------------------------- //
- function PageDots( parent ) {
- this.parent = parent;
- this._create();
- }
- PageDots.prototype = Object.create( Unipointer.prototype );
- PageDots.prototype._create = function() {
- // create holder element
- this.holder = document.createElement('ol');
- this.holder.className = 'flickity-page-dots';
- // create dots, array of elements
- this.dots = [];
- // events
- this.handleClick = this.onClick.bind( this );
- this.on( 'pointerDown', this.parent.childUIPointerDown.bind( this.parent ) );
- };
- PageDots.prototype.activate = function() {
- this.setDots();
- this.holder.addEventListener( 'click', this.handleClick );
- this.bindStartEvent( this.holder );
- // add to DOM
- this.parent.element.appendChild( this.holder );
- };
- PageDots.prototype.deactivate = function() {
- this.holder.removeEventListener( 'click', this.handleClick );
- this.unbindStartEvent( this.holder );
- // remove from DOM
- this.parent.element.removeChild( this.holder );
- };
- PageDots.prototype.setDots = function() {
- // get difference between number of slides and number of dots
- var delta = this.parent.slides.length - this.dots.length;
- if ( delta > 0 ) {
- this.addDots( delta );
- } else if ( delta < 0 ) {
- this.removeDots( -delta );
- }
- };
- PageDots.prototype.addDots = function( count ) {
- var fragment = document.createDocumentFragment();
- var newDots = [];
- var length = this.dots.length;
- var max = length + count;
- for ( var i = length; i < max; i++ ) {
- var dot = document.createElement('li');
- dot.className = 'dot';
- dot.setAttribute( 'aria-label', 'Page dot ' + ( i + 1 ) );
- fragment.appendChild( dot );
- newDots.push( dot );
- }
- this.holder.appendChild( fragment );
- this.dots = this.dots.concat( newDots );
- };
- PageDots.prototype.removeDots = function( count ) {
- // remove from this.dots collection
- var removeDots = this.dots.splice( this.dots.length - count, count );
- // remove from DOM
- removeDots.forEach( function( dot ) {
- this.holder.removeChild( dot );
- }, this );
- };
- PageDots.prototype.updateSelected = function() {
- // remove selected class on previous
- if ( this.selectedDot ) {
- this.selectedDot.className = 'dot';
- this.selectedDot.removeAttribute('aria-current');
- }
- // don't proceed if no dots
- if ( !this.dots.length ) {
- return;
- }
- this.selectedDot = this.dots[ this.parent.selectedIndex ];
- this.selectedDot.className = 'dot is-selected';
- this.selectedDot.setAttribute( 'aria-current', 'step' );
- };
- PageDots.prototype.onTap = // old method name, backwards-compatible
- PageDots.prototype.onClick = function( event ) {
- var target = event.target;
- // only care about dot clicks
- if ( target.nodeName != 'LI' ) {
- return;
- }
- this.parent.uiChange();
- var index = this.dots.indexOf( target );
- this.parent.select( index );
- };
- PageDots.prototype.destroy = function() {
- this.deactivate();
- this.allOff();
- };
- Flickity.PageDots = PageDots;
- // -------------------------- Flickity -------------------------- //
- utils.extend( Flickity.defaults, {
- pageDots: true
- });
- Flickity.createMethods.push('_createPageDots');
- var proto = Flickity.prototype;
- proto._createPageDots = function() {
- if ( !this.options.pageDots ) {
- return;
- }
- this.pageDots = new PageDots( this );
- // events
- this.on( 'activate', this.activatePageDots );
- this.on( 'select', this.updateSelectedPageDots );
- this.on( 'cellChange', this.updatePageDots );
- this.on( 'resize', this.updatePageDots );
- this.on( 'deactivate', this.deactivatePageDots );
- };
- proto.activatePageDots = function() {
- this.pageDots.activate();
- };
- proto.updateSelectedPageDots = function() {
- this.pageDots.updateSelected();
- };
- proto.updatePageDots = function() {
- this.pageDots.setDots();
- };
- proto.deactivatePageDots = function() {
- this.pageDots.deactivate();
- };
- // ----- ----- //
- Flickity.PageDots = PageDots;
- return Flickity;
- }));
- // player & autoPlay
- ( function( window, factory ) {
- // universal module definition
- /* jshint strict: false */
- if ( typeof define == 'function' && define.amd ) {
- // AMD
- define( 'flickity/js/player',[
- 'ev-emitter/ev-emitter',
- 'fizzy-ui-utils/utils',
- './flickity'
- ], function( EvEmitter, utils, Flickity ) {
- return factory( EvEmitter, utils, Flickity );
- });
- } else if ( typeof module == 'object' && module.exports ) {
- // CommonJS
- module.exports = factory(
- require('ev-emitter'),
- require('fizzy-ui-utils'),
- require('./flickity')
- );
- } else {
- // browser global
- factory(
- window.EvEmitter,
- window.fizzyUIUtils,
- window.Flickity
- );
- }
- }( window, function factory( EvEmitter, utils, Flickity ) {
- // -------------------------- Player -------------------------- //
- function Player( parent ) {
- this.parent = parent;
- this.state = 'stopped';
- // visibility change event handler
- this.onVisibilityChange = this.visibilityChange.bind( this );
- this.onVisibilityPlay = this.visibilityPlay.bind( this );
- }
- Player.prototype = Object.create( EvEmitter.prototype );
- // start play
- Player.prototype.play = function() {
- if ( this.state == 'playing' ) {
- return;
- }
- // do not play if page is hidden, start playing when page is visible
- var isPageHidden = document.hidden;
- if ( isPageHidden ) {
- document.addEventListener( 'visibilitychange', this.onVisibilityPlay );
- return;
- }
- this.state = 'playing';
- // listen to visibility change
- document.addEventListener( 'visibilitychange', this.onVisibilityChange );
- // start ticking
- this.tick();
- };
- Player.prototype.tick = function() {
- // do not tick if not playing
- if ( this.state != 'playing' ) {
- return;
- }
- var time = this.parent.options.autoPlay;
- // default to 3 seconds
- time = typeof time == 'number' ? time : 3000;
- var _this = this;
- // HACK: reset ticks if stopped and started within interval
- this.clear();
- this.timeout = setTimeout( function() {
- _this.parent.next( true );
- _this.tick();
- }, time );
- };
- Player.prototype.stop = function() {
- this.state = 'stopped';
- this.clear();
- // remove visibility change event
- document.removeEventListener( 'visibilitychange', this.onVisibilityChange );
- };
- Player.prototype.clear = function() {
- clearTimeout( this.timeout );
- };
- Player.prototype.pause = function() {
- if ( this.state == 'playing' ) {
- this.state = 'paused';
- this.clear();
- }
- };
- Player.prototype.unpause = function() {
- // re-start play if paused
- if ( this.state == 'paused' ) {
- this.play();
- }
- };
- // pause if page visibility is hidden, unpause if visible
- Player.prototype.visibilityChange = function() {
- var isPageHidden = document.hidden;
- this[ isPageHidden ? 'pause' : 'unpause' ]();
- };
- Player.prototype.visibilityPlay = function() {
- this.play();
- document.removeEventListener( 'visibilitychange', this.onVisibilityPlay );
- };
- // -------------------------- Flickity -------------------------- //
- utils.extend( Flickity.defaults, {
- pauseAutoPlayOnHover: true
- });
- Flickity.createMethods.push('_createPlayer');
- var proto = Flickity.prototype;
- proto._createPlayer = function() {
- this.player = new Player( this );
- this.on( 'activate', this.activatePlayer );
- this.on( 'uiChange', this.stopPlayer );
- this.on( 'pointerDown', this.stopPlayer );
- this.on( 'deactivate', this.deactivatePlayer );
- };
- proto.activatePlayer = function() {
- if ( !this.options.autoPlay ) {
- return;
- }
- this.player.play();
- this.element.addEventListener( 'mouseenter', this );
- };
- // Player API, don't hate the ... thanks I know where the door is
- proto.playPlayer = function() {
- this.player.play();
- };
- proto.stopPlayer = function() {
- this.player.stop();
- };
- proto.pausePlayer = function() {
- this.player.pause();
- };
- proto.unpausePlayer = function() {
- this.player.unpause();
- };
- proto.deactivatePlayer = function() {
- this.player.stop();
- this.element.removeEventListener( 'mouseenter', this );
- };
- // ----- mouseenter/leave ----- //
- // pause auto-play on hover
- proto.onmouseenter = function() {
- if ( !this.options.pauseAutoPlayOnHover ) {
- return;
- }
- this.player.pause();
- this.element.addEventListener( 'mouseleave', this );
- };
- // resume auto-play on hover off
- proto.onmouseleave = function() {
- this.player.unpause();
- this.element.removeEventListener( 'mouseleave', this );
- };
- // ----- ----- //
- Flickity.Player = Player;
- return Flickity;
- }));
- // add, remove cell
- ( function( window, factory ) {
- // universal module definition
- /* jshint strict: false */
- if ( typeof define == 'function' && define.amd ) {
- // AMD
- define( 'flickity/js/add-remove-cell',[
- './flickity',
- 'fizzy-ui-utils/utils'
- ], function( Flickity, utils ) {
- return factory( window, Flickity, utils );
- });
- } else if ( typeof module == 'object' && module.exports ) {
- // CommonJS
- module.exports = factory(
- window,
- require('./flickity'),
- require('fizzy-ui-utils')
- );
- } else {
- // browser global
- factory(
- window,
- window.Flickity,
- window.fizzyUIUtils
- );
- }
- }( window, function factory( window, Flickity, utils ) {
- // append cells to a document fragment
- function getCellsFragment( cells ) {
- var fragment = document.createDocumentFragment();
- cells.forEach( function( cell ) {
- fragment.appendChild( cell.element );
- });
- return fragment;
- }
- // -------------------------- add/remove cell prototype -------------------------- //
- var proto = Flickity.prototype;
- /**
- * Insert, prepend, or append cells
- * @param {Element, Array, NodeList} elems
- * @param {Integer} index
- */
- proto.insert = function( elems, index ) {
- var cells = this._makeCells( elems );
- if ( !cells || !cells.length ) {
- return;
- }
- var len = this.cells.length;
- // default to append
- index = index === undefined ? len : index;
- // add cells with document fragment
- var fragment = getCellsFragment( cells );
- // append to slider
- var isAppend = index == len;
- if ( isAppend ) {
- this.slider.appendChild( fragment );
- } else {
- var insertCellElement = this.cells[ index ].element;
- this.slider.insertBefore( fragment, insertCellElement );
- }
- // add to this.cells
- if ( index === 0 ) {
- // prepend, add to start
- this.cells = cells.concat( this.cells );
- } else if ( isAppend ) {
- // append, add to end
- this.cells = this.cells.concat( cells );
- } else {
- // insert in this.cells
- var endCells = this.cells.splice( index, len - index );
- this.cells = this.cells.concat( cells ).concat( endCells );
- }
- this._sizeCells( cells );
- this.cellChange( index, true );
- };
- proto.append = function( elems ) {
- this.insert( elems, this.cells.length );
- };
- proto.prepend = function( elems ) {
- this.insert( elems, 0 );
- };
- /**
- * Remove cells
- * @param {Element, Array, NodeList} elems
- */
- proto.remove = function( elems ) {
- var cells = this.getCells( elems );
- if ( !cells || !cells.length ) {
- return;
- }
- var minCellIndex = this.cells.length - 1;
- // remove cells from collection & DOM
- cells.forEach( function( cell ) {
- cell.remove();
- var index = this.cells.indexOf( cell );
- minCellIndex = Math.min( index, minCellIndex );
- utils.removeFrom( this.cells, cell );
- }, this );
- this.cellChange( minCellIndex, true );
- };
- /**
- * logic to be run after a cell's size changes
- * @param {Element} elem - cell's element
- */
- proto.cellSizeChange = function( elem ) {
- var cell = this.getCell( elem );
- if ( !cell ) {
- return;
- }
- cell.getSize();
- var index = this.cells.indexOf( cell );
- this.cellChange( index );
- };
- /**
- * logic any time a cell is changed: added, removed, or size changed
- * @param {Integer} changedCellIndex - index of the changed cell, optional
- */
- proto.cellChange = function( changedCellIndex, isPositioningSlider ) {
- var prevSelectedElem = this.selectedElement;
- this._positionCells( changedCellIndex );
- this._getWrapShiftCells();
- this.setGallerySize();
- // update selectedIndex
- // try to maintain position & select previous selected element
- var cell = this.getCell( prevSelectedElem );
- if ( cell ) {
- this.selectedIndex = this.getCellSlideIndex( cell );
- }
- this.selectedIndex = Math.min( this.slides.length - 1, this.selectedIndex );
- this.emitEvent( 'cellChange', [ changedCellIndex ] );
- // position slider
- this.select( this.selectedIndex );
- // do not position slider after lazy load
- if ( isPositioningSlider ) {
- this.positionSliderAtSelected();
- }
- };
- // ----- ----- //
- return Flickity;
- }));
- // lazyload
- ( function( window, factory ) {
- // universal module definition
- /* jshint strict: false */
- if ( typeof define == 'function' && define.amd ) {
- // AMD
- define( 'flickity/js/lazyload',[
- './flickity',
- 'fizzy-ui-utils/utils'
- ], function( Flickity, utils ) {
- return factory( window, Flickity, utils );
- });
- } else if ( typeof module == 'object' && module.exports ) {
- // CommonJS
- module.exports = factory(
- window,
- require('./flickity'),
- require('fizzy-ui-utils')
- );
- } else {
- // browser global
- factory(
- window,
- window.Flickity,
- window.fizzyUIUtils
- );
- }
- }( window, function factory( window, Flickity, utils ) {
- 'use strict';
- Flickity.createMethods.push('_createLazyload');
- var proto = Flickity.prototype;
- proto._createLazyload = function() {
- this.on( 'select', this.lazyLoad );
- };
- proto.lazyLoad = function() {
- var lazyLoad = this.options.lazyLoad;
- if ( !lazyLoad ) {
- return;
- }
- // get adjacent cells, use lazyLoad option for adjacent count
- var adjCount = typeof lazyLoad == 'number' ? lazyLoad : 0;
- var cellElems = this.getAdjacentCellElements( adjCount );
- // get lazy images in those cells
- var lazyImages = [];
- cellElems.forEach( function( cellElem ) {
- var lazyCellImages = getCellLazyImages( cellElem );
- lazyImages = lazyImages.concat( lazyCellImages );
- });
- // load lazy images
- lazyImages.forEach( function( img ) {
- new LazyLoader( img, this );
- }, this );
- };
- function getCellLazyImages( cellElem ) {
- // check if cell element is lazy image
- if ( cellElem.nodeName == 'IMG' ) {
- var lazyloadAttr = cellElem.getAttribute('data-flickity-lazyload');
- var srcAttr = cellElem.getAttribute('data-flickity-lazyload-src');
- var srcsetAttr = cellElem.getAttribute('data-flickity-lazyload-srcset');
- if ( lazyloadAttr || srcAttr || srcsetAttr ) {
- return [ cellElem ];
- }
- }
- // select lazy images in cell
- var lazySelector = 'img[data-flickity-lazyload], ' +
- 'img[data-flickity-lazyload-src], img[data-flickity-lazyload-srcset]';
- var imgs = cellElem.querySelectorAll( lazySelector );
- return utils.makeArray( imgs );
- }
- // -------------------------- LazyLoader -------------------------- //
- /**
- * class to handle loading images
- */
- function LazyLoader( img, flickity ) {
- this.img = img;
- this.flickity = flickity;
- this.load();
- }
- LazyLoader.prototype.handleEvent = utils.handleEvent;
- LazyLoader.prototype.load = function() {
- this.img.addEventListener( 'load', this );
- this.img.addEventListener( 'error', this );
- // get src & srcset
- var src = this.img.getAttribute('data-flickity-lazyload') ||
- this.img.getAttribute('data-flickity-lazyload-src');
- var srcset = this.img.getAttribute('data-flickity-lazyload-srcset');
- // set src & serset
- this.img.src = src;
- if ( srcset ) {
- this.img.setAttribute( 'srcset', srcset );
- }
- // remove attr
- this.img.removeAttribute('data-flickity-lazyload');
- this.img.removeAttribute('data-flickity-lazyload-src');
- this.img.removeAttribute('data-flickity-lazyload-srcset');
- };
- LazyLoader.prototype.onload = function( event ) {
- this.complete( event, 'flickity-lazyloaded' );
- };
- LazyLoader.prototype.onerror = function( event ) {
- this.complete( event, 'flickity-lazyerror' );
- };
- LazyLoader.prototype.complete = function( event, className ) {
- // unbind events
- this.img.removeEventListener( 'load', this );
- this.img.removeEventListener( 'error', this );
- var cell = this.flickity.getParentCell( this.img );
- var cellElem = cell && cell.element;
- this.flickity.cellSizeChange( cellElem );
- this.img.classList.add( className );
- this.flickity.dispatchEvent( 'lazyLoad', event, cellElem );
- };
- // ----- ----- //
- Flickity.LazyLoader = LazyLoader;
- return Flickity;
- }));
- /*!
- * Flickity v2.2.1
- * Touch, responsive, flickable carousels
- *
- * Licensed GPLv3 for open source use
- * or Flickity Commercial License for commercial use
- *
- * https://flickity.metafizzy.co
- * Copyright 2015-2019 Metafizzy
- */
- ( function( window, factory ) {
- // universal module definition
- /* jshint strict: false */
- if ( typeof define == 'function' && define.amd ) {
- // AMD
- define( 'flickity/js/index',[
- './flickity',
- './drag',
- './prev-next-button',
- './page-dots',
- './player',
- './add-remove-cell',
- './lazyload'
- ], factory );
- } else if ( typeof module == 'object' && module.exports ) {
- // CommonJS
- module.exports = factory(
- require('./flickity'),
- require('./drag'),
- require('./prev-next-button'),
- require('./page-dots'),
- require('./player'),
- require('./add-remove-cell'),
- require('./lazyload')
- );
- }
- })( window, function factory( Flickity ) {
- /*jshint strict: false*/
- return Flickity;
- });
- /*!
- * Flickity asNavFor v2.0.2
- * enable asNavFor for Flickity
- */
- /*jshint browser: true, undef: true, unused: true, strict: true*/
- ( function( window, factory ) {
- // universal module definition
- /*jshint strict: false */ /*globals define, module, require */
- if ( typeof define == 'function' && define.amd ) {
- // AMD
- define( 'flickity-as-nav-for/as-nav-for',[
- 'flickity/js/index',
- 'fizzy-ui-utils/utils'
- ], factory );
- } else if ( typeof module == 'object' && module.exports ) {
- // CommonJS
- module.exports = factory(
- require('flickity'),
- require('fizzy-ui-utils')
- );
- } else {
- // browser global
- window.Flickity = factory(
- window.Flickity,
- window.fizzyUIUtils
- );
- }
- }( window, function factory( Flickity, utils ) {
- // -------------------------- asNavFor prototype -------------------------- //
- // Flickity.defaults.asNavFor = null;
- Flickity.createMethods.push('_createAsNavFor');
- var proto = Flickity.prototype;
- proto._createAsNavFor = function() {
- this.on( 'activate', this.activateAsNavFor );
- this.on( 'deactivate', this.deactivateAsNavFor );
- this.on( 'destroy', this.destroyAsNavFor );
- var asNavForOption = this.options.asNavFor;
- if ( !asNavForOption ) {
- return;
- }
- // HACK do async, give time for other flickity to be initalized
- var _this = this;
- setTimeout( function initNavCompanion() {
- _this.setNavCompanion( asNavForOption );
- });
- };
- proto.setNavCompanion = function( elem ) {
- elem = utils.getQueryElement( elem );
- var companion = Flickity.data( elem );
- // stop if no companion or companion is self
- if ( !companion || companion == this ) {
- return;
- }
- this.navCompanion = companion;
- // companion select
- var _this = this;
- this.onNavCompanionSelect = function() {
- _this.navCompanionSelect();
- };
- companion.on( 'select', this.onNavCompanionSelect );
- // click
- this.on( 'staticClick', this.onNavStaticClick );
- this.navCompanionSelect( true );
- };
- proto.navCompanionSelect = function( isInstant ) {
- // wait for companion & selectedCells first. #8
- var companionCells = this.navCompanion && this.navCompanion.selectedCells;
- if ( !companionCells ) {
- return;
- }
- // select slide that matches first cell of slide
- var selectedCell = companionCells[0];
- var firstIndex = this.navCompanion.cells.indexOf( selectedCell );
- var lastIndex = firstIndex + companionCells.length - 1;
- var selectIndex = Math.floor( lerp( firstIndex, lastIndex,
- this.navCompanion.cellAlign ) );
- this.selectCell( selectIndex, false, isInstant );
- // set nav selected class
- this.removeNavSelectedElements();
- // stop if companion has more cells than this one
- if ( selectIndex >= this.cells.length ) {
- return;
- }
- var selectedCells = this.cells.slice( firstIndex, lastIndex + 1 );
- this.navSelectedElements = selectedCells.map( function( cell ) {
- return cell.element;
- });
- this.changeNavSelectedClass('add');
- };
- function lerp( a, b, t ) {
- return ( b - a ) * t + a;
- }
- proto.changeNavSelectedClass = function( method ) {
- this.navSelectedElements.forEach( function( navElem ) {
- navElem.classList[ method ]('is-nav-selected');
- });
- };
- proto.activateAsNavFor = function() {
- this.navCompanionSelect( true );
- };
- proto.removeNavSelectedElements = function() {
- if ( !this.navSelectedElements ) {
- return;
- }
- this.changeNavSelectedClass('remove');
- delete this.navSelectedElements;
- };
- proto.onNavStaticClick = function( event, pointer, cellElement, cellIndex ) {
- if ( typeof cellIndex == 'number' ) {
- this.navCompanion.selectCell( cellIndex );
- }
- };
- proto.deactivateAsNavFor = function() {
- this.removeNavSelectedElements();
- };
- proto.destroyAsNavFor = function() {
- if ( !this.navCompanion ) {
- return;
- }
- this.navCompanion.off( 'select', this.onNavCompanionSelect );
- this.off( 'staticClick', this.onNavStaticClick );
- delete this.navCompanion;
- };
- // ----- ----- //
- return Flickity;
- }));
- /*!
- * imagesLoaded v4.1.4
- * JavaScript is all like "You images are done yet or what?"
- * MIT License
- */
- ( function( window, factory ) { 'use strict';
- // universal module definition
- /*global define: false, module: false, require: false */
- if ( typeof define == 'function' && define.amd ) {
- // AMD
- define( 'imagesloaded/imagesloaded',[
- 'ev-emitter/ev-emitter'
- ], function( EvEmitter ) {
- return factory( window, EvEmitter );
- });
- } else if ( typeof module == 'object' && module.exports ) {
- // CommonJS
- module.exports = factory(
- window,
- require('ev-emitter')
- );
- } else {
- // browser global
- window.imagesLoaded = factory(
- window,
- window.EvEmitter
- );
- }
- })( typeof window !== 'undefined' ? window : this,
- // -------------------------- factory -------------------------- //
- function factory( window, EvEmitter ) {
- var $ = window.jQuery;
- var console = window.console;
- // -------------------------- helpers -------------------------- //
- // extend objects
- function extend( a, b ) {
- for ( var prop in b ) {
- a[ prop ] = b[ prop ];
- }
- return a;
- }
- var arraySlice = Array.prototype.slice;
- // turn element or nodeList into an array
- function makeArray( obj ) {
- if ( Array.isArray( obj ) ) {
- // use object if already an array
- return obj;
- }
- var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
- if ( isArrayLike ) {
- // convert nodeList to array
- return arraySlice.call( obj );
- }
- // array of single index
- return [ obj ];
- }
- // -------------------------- imagesLoaded -------------------------- //
- /**
- * @param {Array, Element, NodeList, String} elem
- * @param {Object or Function} options - if function, use as callback
- * @param {Function} onAlways - callback function
- */
- function ImagesLoaded( elem, options, onAlways ) {
- // coerce ImagesLoaded() without new, to be new ImagesLoaded()
- if ( !( this instanceof ImagesLoaded ) ) {
- return new ImagesLoaded( elem, options, onAlways );
- }
- // use elem as selector string
- var queryElem = elem;
- if ( typeof elem == 'string' ) {
- queryElem = document.querySelectorAll( elem );
- }
- // bail if bad element
- if ( !queryElem ) {
- console.error( 'Bad element for imagesLoaded ' + ( queryElem || elem ) );
- return;
- }
- this.elements = makeArray( queryElem );
- this.options = extend( {}, this.options );
- // shift arguments if no options set
- if ( typeof options == 'function' ) {
- onAlways = options;
- } else {
- extend( this.options, options );
- }
- if ( onAlways ) {
- this.on( 'always', onAlways );
- }
- this.getImages();
- if ( $ ) {
- // add jQuery Deferred object
- this.jqDeferred = new $.Deferred();
- }
- // HACK check async to allow time to bind listeners
- setTimeout( this.check.bind( this ) );
- }
- ImagesLoaded.prototype = Object.create( EvEmitter.prototype );
- ImagesLoaded.prototype.options = {};
- ImagesLoaded.prototype.getImages = function() {
- this.images = [];
- // filter & find items if we have an item selector
- this.elements.forEach( this.addElementImages, this );
- };
- /**
- * @param {Node} element
- */
- ImagesLoaded.prototype.addElementImages = function( elem ) {
- // filter siblings
- if ( elem.nodeName == 'IMG' ) {
- this.addImage( elem );
- }
- // get background image on element
- if ( this.options.background === true ) {
- this.addElementBackgroundImages( elem );
- }
- // find children
- // no non-element nodes, #143
- var nodeType = elem.nodeType;
- if ( !nodeType || !elementNodeTypes[ nodeType ] ) {
- return;
- }
- var childImgs = elem.querySelectorAll('img');
- // concat childElems to filterFound array
- for ( var i=0; i < childImgs.length; i++ ) {
- var img = childImgs[i];
- this.addImage( img );
- }
- // get child background images
- if ( typeof this.options.background == 'string' ) {
- var children = elem.querySelectorAll( this.options.background );
- for ( i=0; i < children.length; i++ ) {
- var child = children[i];
- this.addElementBackgroundImages( child );
- }
- }
- };
- var elementNodeTypes = {
- 1: true,
- 9: true,
- 11: true
- };
- ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) {
- var style = getComputedStyle( elem );
- if ( !style ) {
- // Firefox returns null if in a hidden iframe https://bugzil.la/548397
- return;
- }
- // get url inside url("...")
- var reURL = /url\((['"])?(.*?)\1\)/gi;
- var matches = reURL.exec( style.backgroundImage );
- while ( matches !== null ) {
- var url = matches && matches[2];
- if ( url ) {
- this.addBackground( url, elem );
- }
- matches = reURL.exec( style.backgroundImage );
- }
- };
- /**
- * @param {Image} img
- */
- ImagesLoaded.prototype.addImage = function( img ) {
- var loadingImage = new LoadingImage( img );
- this.images.push( loadingImage );
- };
- ImagesLoaded.prototype.addBackground = function( url, elem ) {
- var background = new Background( url, elem );
- this.images.push( background );
- };
- ImagesLoaded.prototype.check = function() {
- var _this = this;
- this.progressedCount = 0;
- this.hasAnyBroken = false;
- // complete if no images
- if ( !this.images.length ) {
- this.complete();
- return;
- }
- function onProgress( image, elem, message ) {
- // HACK - Chrome triggers event before object properties have changed. #83
- setTimeout( function() {
- _this.progress( image, elem, message );
- });
- }
- this.images.forEach( function( loadingImage ) {
- loadingImage.once( 'progress', onProgress );
- loadingImage.check();
- });
- };
- ImagesLoaded.prototype.progress = function( image, elem, message ) {
- this.progressedCount++;
- this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;
- // progress event
- this.emitEvent( 'progress', [ this, image, elem ] );
- if ( this.jqDeferred && this.jqDeferred.notify ) {
- this.jqDeferred.notify( this, image );
- }
- // check if completed
- if ( this.progressedCount == this.images.length ) {
- this.complete();
- }
- if ( this.options.debug && console ) {
- console.log( 'progress: ' + message, image, elem );
- }
- };
- ImagesLoaded.prototype.complete = function() {
- var eventName = this.hasAnyBroken ? 'fail' : 'done';
- this.isComplete = true;
- this.emitEvent( eventName, [ this ] );
- this.emitEvent( 'always', [ this ] );
- if ( this.jqDeferred ) {
- var jqMethod = this.hasAnyBroken ? 'reject' : 'resolve';
- this.jqDeferred[ jqMethod ]( this );
- }
- };
- // -------------------------- -------------------------- //
- function LoadingImage( img ) {
- this.img = img;
- }
- LoadingImage.prototype = Object.create( EvEmitter.prototype );
- LoadingImage.prototype.check = function() {
- // If complete is true and browser supports natural sizes,
- // try to check for image status manually.
- var isComplete = this.getIsImageComplete();
- if ( isComplete ) {
- // report based on naturalWidth
- this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
- return;
- }
- // If none of the checks above matched, simulate loading on detached element.
- this.proxyImage = new Image();
- this.proxyImage.addEventListener( 'load', this );
- this.proxyImage.addEventListener( 'error', this );
- // bind to image as well for Firefox. #191
- this.img.addEventListener( 'load', this );
- this.img.addEventListener( 'error', this );
- this.proxyImage.src = this.img.src;
- };
- LoadingImage.prototype.getIsImageComplete = function() {
- // check for non-zero, non-undefined naturalWidth
- // fixes Safari+InfiniteScroll+Masonry bug infinite-scroll#671
- return this.img.complete && this.img.naturalWidth;
- };
- LoadingImage.prototype.confirm = function( isLoaded, message ) {
- this.isLoaded = isLoaded;
- this.emitEvent( 'progress', [ this, this.img, message ] );
- };
- // ----- events ----- //
- // trigger specified handler for event type
- LoadingImage.prototype.handleEvent = function( event ) {
- var method = 'on' + event.type;
- if ( this[ method ] ) {
- this[ method ]( event );
- }
- };
- LoadingImage.prototype.onload = function() {
- this.confirm( true, 'onload' );
- this.unbindEvents();
- };
- LoadingImage.prototype.onerror = function() {
- this.confirm( false, 'onerror' );
- this.unbindEvents();
- };
- LoadingImage.prototype.unbindEvents = function() {
- this.proxyImage.removeEventListener( 'load', this );
- this.proxyImage.removeEventListener( 'error', this );
- this.img.removeEventListener( 'load', this );
- this.img.removeEventListener( 'error', this );
- };
- // -------------------------- Background -------------------------- //
- function Background( url, element ) {
- this.url = url;
- this.element = element;
- this.img = new Image();
- }
- // inherit LoadingImage prototype
- Background.prototype = Object.create( LoadingImage.prototype );
- Background.prototype.check = function() {
- this.img.addEventListener( 'load', this );
- this.img.addEventListener( 'error', this );
- this.img.src = this.url;
- // check if image is already complete
- var isComplete = this.getIsImageComplete();
- if ( isComplete ) {
- this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
- this.unbindEvents();
- }
- };
- Background.prototype.unbindEvents = function() {
- this.img.removeEventListener( 'load', this );
- this.img.removeEventListener( 'error', this );
- };
- Background.prototype.confirm = function( isLoaded, message ) {
- this.isLoaded = isLoaded;
- this.emitEvent( 'progress', [ this, this.element, message ] );
- };
- // -------------------------- jQuery -------------------------- //
- ImagesLoaded.makeJQueryPlugin = function( jQuery ) {
- jQuery = jQuery || window.jQuery;
- if ( !jQuery ) {
- return;
- }
- // set local variable
- $ = jQuery;
- // $().imagesLoaded()
- $.fn.imagesLoaded = function( options, callback ) {
- var instance = new ImagesLoaded( this, options, callback );
- return instance.jqDeferred.promise( $(this) );
- };
- };
- // try making plugin
- ImagesLoaded.makeJQueryPlugin();
- // -------------------------- -------------------------- //
- return ImagesLoaded;
- });
- /*!
- * Flickity imagesLoaded v2.0.0
- * enables imagesLoaded option for Flickity
- */
- /*jshint browser: true, strict: true, undef: true, unused: true */
- ( function( window, factory ) {
- // universal module definition
- /*jshint strict: false */ /*globals define, module, require */
- if ( typeof define == 'function' && define.amd ) {
- // AMD
- define( [
- 'flickity/js/index',
- 'imagesloaded/imagesloaded'
- ], function( Flickity, imagesLoaded ) {
- return factory( window, Flickity, imagesLoaded );
- });
- } else if ( typeof module == 'object' && module.exports ) {
- // CommonJS
- module.exports = factory(
- window,
- require('flickity'),
- require('imagesloaded')
- );
- } else {
- // browser global
- window.Flickity = factory(
- window,
- window.Flickity,
- window.imagesLoaded
- );
- }
- }( window, function factory( window, Flickity, imagesLoaded ) {
- 'use strict';
- Flickity.createMethods.push('_createImagesLoaded');
- var proto = Flickity.prototype;
- proto._createImagesLoaded = function() {
- this.on( 'activate', this.imagesLoaded );
- };
- proto.imagesLoaded = function() {
- if ( !this.options.imagesLoaded ) {
- return;
- }
- var _this = this;
- function onImagesLoadedProgress( instance, image ) {
- var cell = _this.getParentCell( image.img );
- _this.cellSizeChange( cell && cell.element );
- if ( !_this.options.freeScroll ) {
- _this.positionSliderAtSelected();
- }
- }
- imagesLoaded( this.slider ).on( 'progress', onImagesLoadedProgress );
- };
- return Flickity;
- }));
|