123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148 |
- /**
- * @license Angular v5.2.11
- * (c) 2010-2018 Google, Inc. https://angular.io/
- * License: MIT
- */
- import { AUTO_STYLE, NoopAnimationPlayer, sequence, style, ɵAnimationGroupPlayer, ɵPRE_STYLE } from '@angular/animations';
-
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes} checked by tsc
- */
- /**
- * @param {?} players
- * @return {?}
- */
- function optimizeGroupPlayer(players) {
- switch (players.length) {
- case 0:
- return new NoopAnimationPlayer();
- case 1:
- return players[0];
- default:
- return new ɵAnimationGroupPlayer(players);
- }
- }
- /**
- * @param {?} driver
- * @param {?} normalizer
- * @param {?} element
- * @param {?} keyframes
- * @param {?=} preStyles
- * @param {?=} postStyles
- * @return {?}
- */
- function normalizeKeyframes(driver, normalizer, element, keyframes, preStyles = {}, postStyles = {}) {
- const /** @type {?} */ errors = [];
- const /** @type {?} */ normalizedKeyframes = [];
- let /** @type {?} */ previousOffset = -1;
- let /** @type {?} */ previousKeyframe = null;
- keyframes.forEach(kf => {
- const /** @type {?} */ offset = /** @type {?} */ (kf['offset']);
- const /** @type {?} */ isSameOffset = offset == previousOffset;
- const /** @type {?} */ normalizedKeyframe = (isSameOffset && previousKeyframe) || {};
- Object.keys(kf).forEach(prop => {
- let /** @type {?} */ normalizedProp = prop;
- let /** @type {?} */ normalizedValue = kf[prop];
- if (prop !== 'offset') {
- normalizedProp = normalizer.normalizePropertyName(normalizedProp, errors);
- switch (normalizedValue) {
- case ɵPRE_STYLE:
- normalizedValue = preStyles[prop];
- break;
- case AUTO_STYLE:
- normalizedValue = postStyles[prop];
- break;
- default:
- normalizedValue =
- normalizer.normalizeStyleValue(prop, normalizedProp, normalizedValue, errors);
- break;
- }
- }
- normalizedKeyframe[normalizedProp] = normalizedValue;
- });
- if (!isSameOffset) {
- normalizedKeyframes.push(normalizedKeyframe);
- }
- previousKeyframe = normalizedKeyframe;
- previousOffset = offset;
- });
- if (errors.length) {
- const /** @type {?} */ LINE_START = '\n - ';
- throw new Error(`Unable to animate due to the following errors:${LINE_START}${errors.join(LINE_START)}`);
- }
- return normalizedKeyframes;
- }
- /**
- * @param {?} player
- * @param {?} eventName
- * @param {?} event
- * @param {?} callback
- * @return {?}
- */
- function listenOnPlayer(player, eventName, event, callback) {
- switch (eventName) {
- case 'start':
- player.onStart(() => callback(event && copyAnimationEvent(event, 'start', player.totalTime)));
- break;
- case 'done':
- player.onDone(() => callback(event && copyAnimationEvent(event, 'done', player.totalTime)));
- break;
- case 'destroy':
- player.onDestroy(() => callback(event && copyAnimationEvent(event, 'destroy', player.totalTime)));
- break;
- }
- }
- /**
- * @param {?} e
- * @param {?=} phaseName
- * @param {?=} totalTime
- * @return {?}
- */
- function copyAnimationEvent(e, phaseName, totalTime) {
- const /** @type {?} */ event = makeAnimationEvent(e.element, e.triggerName, e.fromState, e.toState, phaseName || e.phaseName, totalTime == undefined ? e.totalTime : totalTime);
- const /** @type {?} */ data = (/** @type {?} */ (e))['_data'];
- if (data != null) {
- (/** @type {?} */ (event))['_data'] = data;
- }
- return event;
- }
- /**
- * @param {?} element
- * @param {?} triggerName
- * @param {?} fromState
- * @param {?} toState
- * @param {?=} phaseName
- * @param {?=} totalTime
- * @return {?}
- */
- function makeAnimationEvent(element, triggerName, fromState, toState, phaseName = '', totalTime = 0) {
- return { element, triggerName, fromState, toState, phaseName, totalTime };
- }
- /**
- * @param {?} map
- * @param {?} key
- * @param {?} defaultValue
- * @return {?}
- */
- function getOrSetAsInMap(map, key, defaultValue) {
- let /** @type {?} */ value;
- if (map instanceof Map) {
- value = map.get(key);
- if (!value) {
- map.set(key, value = defaultValue);
- }
- }
- else {
- value = map[key];
- if (!value) {
- value = map[key] = defaultValue;
- }
- }
- return value;
- }
- /**
- * @param {?} command
- * @return {?}
- */
- function parseTimelineCommand(command) {
- const /** @type {?} */ separatorPos = command.indexOf(':');
- const /** @type {?} */ id = command.substring(1, separatorPos);
- const /** @type {?} */ action = command.substr(separatorPos + 1);
- return [id, action];
- }
- let _contains = (elm1, elm2) => false;
- let _matches = (element, selector) => false;
- let _query = (element, selector, multi) => {
- return [];
- };
- if (typeof Element != 'undefined') {
- // this is well supported in all browsers
- _contains = (elm1, elm2) => { return /** @type {?} */ (elm1.contains(elm2)); };
- if (Element.prototype.matches) {
- _matches = (element, selector) => element.matches(selector);
- }
- else {
- const /** @type {?} */ proto = /** @type {?} */ (Element.prototype);
- const /** @type {?} */ fn = proto.matchesSelector || proto.mozMatchesSelector || proto.msMatchesSelector ||
- proto.oMatchesSelector || proto.webkitMatchesSelector;
- if (fn) {
- _matches = (element, selector) => fn.apply(element, [selector]);
- }
- }
- _query = (element, selector, multi) => {
- let /** @type {?} */ results = [];
- if (multi) {
- results.push(...element.querySelectorAll(selector));
- }
- else {
- const /** @type {?} */ elm = element.querySelector(selector);
- if (elm) {
- results.push(elm);
- }
- }
- return results;
- };
- }
- /**
- * @param {?} prop
- * @return {?}
- */
- function containsVendorPrefix(prop) {
- // Webkit is the only real popular vendor prefix nowadays
- // cc: http://shouldiprefix.com/
- return prop.substring(1, 6) == 'ebkit'; // webkit or Webkit
- }
- let _CACHED_BODY = null;
- let _IS_WEBKIT = false;
- /**
- * @param {?} prop
- * @return {?}
- */
- function validateStyleProperty(prop) {
- if (!_CACHED_BODY) {
- _CACHED_BODY = getBodyNode() || {};
- _IS_WEBKIT = /** @type {?} */ ((_CACHED_BODY)).style ? ('WebkitAppearance' in /** @type {?} */ ((_CACHED_BODY)).style) : false;
- }
- let /** @type {?} */ result = true;
- if (/** @type {?} */ ((_CACHED_BODY)).style && !containsVendorPrefix(prop)) {
- result = prop in /** @type {?} */ ((_CACHED_BODY)).style;
- if (!result && _IS_WEBKIT) {
- const /** @type {?} */ camelProp = 'Webkit' + prop.charAt(0).toUpperCase() + prop.substr(1);
- result = camelProp in /** @type {?} */ ((_CACHED_BODY)).style;
- }
- }
- return result;
- }
- /**
- * @return {?}
- */
- function getBodyNode() {
- if (typeof document != 'undefined') {
- return document.body;
- }
- return null;
- }
- const matchesElement = _matches;
- const containsElement = _contains;
- const invokeQuery = _query;
-
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes} checked by tsc
- */
- /**
- * \@experimental
- */
- class NoopAnimationDriver {
- /**
- * @param {?} prop
- * @return {?}
- */
- validateStyleProperty(prop) { return validateStyleProperty(prop); }
- /**
- * @param {?} element
- * @param {?} selector
- * @return {?}
- */
- matchesElement(element, selector) {
- return matchesElement(element, selector);
- }
- /**
- * @param {?} elm1
- * @param {?} elm2
- * @return {?}
- */
- containsElement(elm1, elm2) { return containsElement(elm1, elm2); }
- /**
- * @param {?} element
- * @param {?} selector
- * @param {?} multi
- * @return {?}
- */
- query(element, selector, multi) {
- return invokeQuery(element, selector, multi);
- }
- /**
- * @param {?} element
- * @param {?} prop
- * @param {?=} defaultValue
- * @return {?}
- */
- computeStyle(element, prop, defaultValue) {
- return defaultValue || '';
- }
- /**
- * @param {?} element
- * @param {?} keyframes
- * @param {?} duration
- * @param {?} delay
- * @param {?} easing
- * @param {?=} previousPlayers
- * @return {?}
- */
- animate(element, keyframes, duration, delay, easing, previousPlayers = []) {
- return new NoopAnimationPlayer();
- }
- }
- /**
- * \@experimental
- * @abstract
- */
- class AnimationDriver {
- }
- AnimationDriver.NOOP = new NoopAnimationDriver();
-
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes} checked by tsc
- */
- const ONE_SECOND = 1000;
- const SUBSTITUTION_EXPR_START = '{{';
- const SUBSTITUTION_EXPR_END = '}}';
- const ENTER_CLASSNAME = 'ng-enter';
- const LEAVE_CLASSNAME = 'ng-leave';
-
-
- const NG_TRIGGER_CLASSNAME = 'ng-trigger';
- const NG_TRIGGER_SELECTOR = '.ng-trigger';
- const NG_ANIMATING_CLASSNAME = 'ng-animating';
- const NG_ANIMATING_SELECTOR = '.ng-animating';
- /**
- * @param {?} value
- * @return {?}
- */
- function resolveTimingValue(value) {
- if (typeof value == 'number')
- return value;
- const /** @type {?} */ matches = (/** @type {?} */ (value)).match(/^(-?[\.\d]+)(m?s)/);
- if (!matches || matches.length < 2)
- return 0;
- return _convertTimeValueToMS(parseFloat(matches[1]), matches[2]);
- }
- /**
- * @param {?} value
- * @param {?} unit
- * @return {?}
- */
- function _convertTimeValueToMS(value, unit) {
- switch (unit) {
- case 's':
- return value * ONE_SECOND;
- default:
- // ms or something else
- return value;
- }
- }
- /**
- * @param {?} timings
- * @param {?} errors
- * @param {?=} allowNegativeValues
- * @return {?}
- */
- function resolveTiming(timings, errors, allowNegativeValues) {
- return timings.hasOwnProperty('duration') ? /** @type {?} */ (timings) :
- parseTimeExpression(/** @type {?} */ (timings), errors, allowNegativeValues);
- }
- /**
- * @param {?} exp
- * @param {?} errors
- * @param {?=} allowNegativeValues
- * @return {?}
- */
- function parseTimeExpression(exp, errors, allowNegativeValues) {
- const /** @type {?} */ regex = /^(-?[\.\d]+)(m?s)(?:\s+(-?[\.\d]+)(m?s))?(?:\s+([-a-z]+(?:\(.+?\))?))?$/i;
- let /** @type {?} */ duration;
- let /** @type {?} */ delay = 0;
- let /** @type {?} */ easing = '';
- if (typeof exp === 'string') {
- const /** @type {?} */ matches = exp.match(regex);
- if (matches === null) {
- errors.push(`The provided timing value "${exp}" is invalid.`);
- return { duration: 0, delay: 0, easing: '' };
- }
- duration = _convertTimeValueToMS(parseFloat(matches[1]), matches[2]);
- const /** @type {?} */ delayMatch = matches[3];
- if (delayMatch != null) {
- delay = _convertTimeValueToMS(Math.floor(parseFloat(delayMatch)), matches[4]);
- }
- const /** @type {?} */ easingVal = matches[5];
- if (easingVal) {
- easing = easingVal;
- }
- }
- else {
- duration = /** @type {?} */ (exp);
- }
- if (!allowNegativeValues) {
- let /** @type {?} */ containsErrors = false;
- let /** @type {?} */ startIndex = errors.length;
- if (duration < 0) {
- errors.push(`Duration values below 0 are not allowed for this animation step.`);
- containsErrors = true;
- }
- if (delay < 0) {
- errors.push(`Delay values below 0 are not allowed for this animation step.`);
- containsErrors = true;
- }
- if (containsErrors) {
- errors.splice(startIndex, 0, `The provided timing value "${exp}" is invalid.`);
- }
- }
- return { duration, delay, easing };
- }
- /**
- * @param {?} obj
- * @param {?=} destination
- * @return {?}
- */
- function copyObj(obj, destination = {}) {
- Object.keys(obj).forEach(prop => { destination[prop] = obj[prop]; });
- return destination;
- }
- /**
- * @param {?} styles
- * @return {?}
- */
- function normalizeStyles(styles) {
- const /** @type {?} */ normalizedStyles = {};
- if (Array.isArray(styles)) {
- styles.forEach(data => copyStyles(data, false, normalizedStyles));
- }
- else {
- copyStyles(styles, false, normalizedStyles);
- }
- return normalizedStyles;
- }
- /**
- * @param {?} styles
- * @param {?} readPrototype
- * @param {?=} destination
- * @return {?}
- */
- function copyStyles(styles, readPrototype, destination = {}) {
- if (readPrototype) {
- // we make use of a for-in loop so that the
- // prototypically inherited properties are
- // revealed from the backFill map
- for (let /** @type {?} */ prop in styles) {
- destination[prop] = styles[prop];
- }
- }
- else {
- copyObj(styles, destination);
- }
- return destination;
- }
- /**
- * @param {?} element
- * @param {?} styles
- * @return {?}
- */
- function setStyles(element, styles) {
- if (element['style']) {
- Object.keys(styles).forEach(prop => {
- const /** @type {?} */ camelProp = dashCaseToCamelCase(prop);
- element.style[camelProp] = styles[prop];
- });
- }
- }
- /**
- * @param {?} element
- * @param {?} styles
- * @return {?}
- */
- function eraseStyles(element, styles) {
- if (element['style']) {
- Object.keys(styles).forEach(prop => {
- const /** @type {?} */ camelProp = dashCaseToCamelCase(prop);
- element.style[camelProp] = '';
- });
- }
- }
- /**
- * @param {?} steps
- * @return {?}
- */
- function normalizeAnimationEntry(steps) {
- if (Array.isArray(steps)) {
- if (steps.length == 1)
- return steps[0];
- return sequence(steps);
- }
- return /** @type {?} */ (steps);
- }
- /**
- * @param {?} value
- * @param {?} options
- * @param {?} errors
- * @return {?}
- */
- function validateStyleParams(value, options, errors) {
- const /** @type {?} */ params = options.params || {};
- const /** @type {?} */ matches = extractStyleParams(value);
- if (matches.length) {
- matches.forEach(varName => {
- if (!params.hasOwnProperty(varName)) {
- errors.push(`Unable to resolve the local animation param ${varName} in the given list of values`);
- }
- });
- }
- }
- const PARAM_REGEX = new RegExp(`${SUBSTITUTION_EXPR_START}\\s*(.+?)\\s*${SUBSTITUTION_EXPR_END}`, 'g');
- /**
- * @param {?} value
- * @return {?}
- */
- function extractStyleParams(value) {
- let /** @type {?} */ params = [];
- if (typeof value === 'string') {
- const /** @type {?} */ val = value.toString();
- let /** @type {?} */ match;
- while (match = PARAM_REGEX.exec(val)) {
- params.push(/** @type {?} */ (match[1]));
- }
- PARAM_REGEX.lastIndex = 0;
- }
- return params;
- }
- /**
- * @param {?} value
- * @param {?} params
- * @param {?} errors
- * @return {?}
- */
- function interpolateParams(value, params, errors) {
- const /** @type {?} */ original = value.toString();
- const /** @type {?} */ str = original.replace(PARAM_REGEX, (_, varName) => {
- let /** @type {?} */ localVal = params[varName];
- // this means that the value was never overidden by the data passed in by the user
- if (!params.hasOwnProperty(varName)) {
- errors.push(`Please provide a value for the animation param ${varName}`);
- localVal = '';
- }
- return localVal.toString();
- });
- // we do this to assert that numeric values stay as they are
- return str == original ? value : str;
- }
- /**
- * @param {?} iterator
- * @return {?}
- */
- function iteratorToArray(iterator) {
- const /** @type {?} */ arr = [];
- let /** @type {?} */ item = iterator.next();
- while (!item.done) {
- arr.push(item.value);
- item = iterator.next();
- }
- return arr;
- }
- /**
- * @param {?} source
- * @param {?} destination
- * @return {?}
- */
-
- const DASH_CASE_REGEXP = /-+([a-z0-9])/g;
- /**
- * @param {?} input
- * @return {?}
- */
- function dashCaseToCamelCase(input) {
- return input.replace(DASH_CASE_REGEXP, (...m) => m[1].toUpperCase());
- }
- /**
- * @param {?} duration
- * @param {?} delay
- * @return {?}
- */
- function allowPreviousPlayerStylesMerge(duration, delay) {
- return duration === 0 || delay === 0;
- }
- /**
- * @param {?} visitor
- * @param {?} node
- * @param {?} context
- * @return {?}
- */
- function visitDslNode(visitor, node, context) {
- switch (node.type) {
- case 7 /* Trigger */:
- return visitor.visitTrigger(node, context);
- case 0 /* State */:
- return visitor.visitState(node, context);
- case 1 /* Transition */:
- return visitor.visitTransition(node, context);
- case 2 /* Sequence */:
- return visitor.visitSequence(node, context);
- case 3 /* Group */:
- return visitor.visitGroup(node, context);
- case 4 /* Animate */:
- return visitor.visitAnimate(node, context);
- case 5 /* Keyframes */:
- return visitor.visitKeyframes(node, context);
- case 6 /* Style */:
- return visitor.visitStyle(node, context);
- case 8 /* Reference */:
- return visitor.visitReference(node, context);
- case 9 /* AnimateChild */:
- return visitor.visitAnimateChild(node, context);
- case 10 /* AnimateRef */:
- return visitor.visitAnimateRef(node, context);
- case 11 /* Query */:
- return visitor.visitQuery(node, context);
- case 12 /* Stagger */:
- return visitor.visitStagger(node, context);
- default:
- throw new Error(`Unable to resolve animation metadata node #${node.type}`);
- }
- }
-
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes} checked by tsc
- */
- /**
- * @license
- * Copyright Google Inc. All Rights Reserved.
- *
- * Use of this source code is governed by an MIT-style license that can be
- * found in the LICENSE file at https://angular.io/license
- */
- const ANY_STATE = '*';
- /**
- * @param {?} transitionValue
- * @param {?} errors
- * @return {?}
- */
- function parseTransitionExpr(transitionValue, errors) {
- const /** @type {?} */ expressions = [];
- if (typeof transitionValue == 'string') {
- (/** @type {?} */ (transitionValue))
- .split(/\s*,\s*/)
- .forEach(str => parseInnerTransitionStr(str, expressions, errors));
- }
- else {
- expressions.push(/** @type {?} */ (transitionValue));
- }
- return expressions;
- }
- /**
- * @param {?} eventStr
- * @param {?} expressions
- * @param {?} errors
- * @return {?}
- */
- function parseInnerTransitionStr(eventStr, expressions, errors) {
- if (eventStr[0] == ':') {
- const /** @type {?} */ result = parseAnimationAlias(eventStr, errors);
- if (typeof result == 'function') {
- expressions.push(result);
- return;
- }
- eventStr = /** @type {?} */ (result);
- }
- const /** @type {?} */ match = eventStr.match(/^(\*|[-\w]+)\s*(<?[=-]>)\s*(\*|[-\w]+)$/);
- if (match == null || match.length < 4) {
- errors.push(`The provided transition expression "${eventStr}" is not supported`);
- return expressions;
- }
- const /** @type {?} */ fromState = match[1];
- const /** @type {?} */ separator = match[2];
- const /** @type {?} */ toState = match[3];
- expressions.push(makeLambdaFromStates(fromState, toState));
- const /** @type {?} */ isFullAnyStateExpr = fromState == ANY_STATE && toState == ANY_STATE;
- if (separator[0] == '<' && !isFullAnyStateExpr) {
- expressions.push(makeLambdaFromStates(toState, fromState));
- }
- }
- /**
- * @param {?} alias
- * @param {?} errors
- * @return {?}
- */
- function parseAnimationAlias(alias, errors) {
- switch (alias) {
- case ':enter':
- return 'void => *';
- case ':leave':
- return '* => void';
- case ':increment':
- return (fromState, toState) => parseFloat(toState) > parseFloat(fromState);
- case ':decrement':
- return (fromState, toState) => parseFloat(toState) < parseFloat(fromState);
- default:
- errors.push(`The transition alias value "${alias}" is not supported`);
- return '* => *';
- }
- }
- // DO NOT REFACTOR ... keep the follow set instantiations
- // with the values intact (closure compiler for some reason
- // removes follow-up lines that add the values outside of
- // the constructor...
- const TRUE_BOOLEAN_VALUES = new Set(['true', '1']);
- const FALSE_BOOLEAN_VALUES = new Set(['false', '0']);
- /**
- * @param {?} lhs
- * @param {?} rhs
- * @return {?}
- */
- function makeLambdaFromStates(lhs, rhs) {
- const /** @type {?} */ LHS_MATCH_BOOLEAN = TRUE_BOOLEAN_VALUES.has(lhs) || FALSE_BOOLEAN_VALUES.has(lhs);
- const /** @type {?} */ RHS_MATCH_BOOLEAN = TRUE_BOOLEAN_VALUES.has(rhs) || FALSE_BOOLEAN_VALUES.has(rhs);
- return (fromState, toState) => {
- let /** @type {?} */ lhsMatch = lhs == ANY_STATE || lhs == fromState;
- let /** @type {?} */ rhsMatch = rhs == ANY_STATE || rhs == toState;
- if (!lhsMatch && LHS_MATCH_BOOLEAN && typeof fromState === 'boolean') {
- lhsMatch = fromState ? TRUE_BOOLEAN_VALUES.has(lhs) : FALSE_BOOLEAN_VALUES.has(lhs);
- }
- if (!rhsMatch && RHS_MATCH_BOOLEAN && typeof toState === 'boolean') {
- rhsMatch = toState ? TRUE_BOOLEAN_VALUES.has(rhs) : FALSE_BOOLEAN_VALUES.has(rhs);
- }
- return lhsMatch && rhsMatch;
- };
- }
-
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes} checked by tsc
- */
- const SELF_TOKEN = ':self';
- const SELF_TOKEN_REGEX = new RegExp(`\s*${SELF_TOKEN}\s*,?`, 'g');
- /**
- * @param {?} driver
- * @param {?} metadata
- * @param {?} errors
- * @return {?}
- */
- function buildAnimationAst(driver, metadata, errors) {
- return new AnimationAstBuilderVisitor(driver).build(metadata, errors);
- }
- const ROOT_SELECTOR = '';
- class AnimationAstBuilderVisitor {
- /**
- * @param {?} _driver
- */
- constructor(_driver) {
- this._driver = _driver;
- }
- /**
- * @param {?} metadata
- * @param {?} errors
- * @return {?}
- */
- build(metadata, errors) {
- const /** @type {?} */ context = new AnimationAstBuilderContext(errors);
- this._resetContextStyleTimingState(context);
- return /** @type {?} */ (visitDslNode(this, normalizeAnimationEntry(metadata), context));
- }
- /**
- * @param {?} context
- * @return {?}
- */
- _resetContextStyleTimingState(context) {
- context.currentQuerySelector = ROOT_SELECTOR;
- context.collectedStyles = {};
- context.collectedStyles[ROOT_SELECTOR] = {};
- context.currentTime = 0;
- }
- /**
- * @param {?} metadata
- * @param {?} context
- * @return {?}
- */
- visitTrigger(metadata, context) {
- let /** @type {?} */ queryCount = context.queryCount = 0;
- let /** @type {?} */ depCount = context.depCount = 0;
- const /** @type {?} */ states = [];
- const /** @type {?} */ transitions = [];
- if (metadata.name.charAt(0) == '@') {
- context.errors.push('animation triggers cannot be prefixed with an `@` sign (e.g. trigger(\'@foo\', [...]))');
- }
- metadata.definitions.forEach(def => {
- this._resetContextStyleTimingState(context);
- if (def.type == 0 /* State */) {
- const /** @type {?} */ stateDef = /** @type {?} */ (def);
- const /** @type {?} */ name = stateDef.name;
- name.split(/\s*,\s*/).forEach(n => {
- stateDef.name = n;
- states.push(this.visitState(stateDef, context));
- });
- stateDef.name = name;
- }
- else if (def.type == 1 /* Transition */) {
- const /** @type {?} */ transition = this.visitTransition(/** @type {?} */ (def), context);
- queryCount += transition.queryCount;
- depCount += transition.depCount;
- transitions.push(transition);
- }
- else {
- context.errors.push('only state() and transition() definitions can sit inside of a trigger()');
- }
- });
- return {
- type: 7 /* Trigger */,
- name: metadata.name, states, transitions, queryCount, depCount,
- options: null
- };
- }
- /**
- * @param {?} metadata
- * @param {?} context
- * @return {?}
- */
- visitState(metadata, context) {
- const /** @type {?} */ styleAst = this.visitStyle(metadata.styles, context);
- const /** @type {?} */ astParams = (metadata.options && metadata.options.params) || null;
- if (styleAst.containsDynamicStyles) {
- const /** @type {?} */ missingSubs = new Set();
- const /** @type {?} */ params = astParams || {};
- styleAst.styles.forEach(value => {
- if (isObject(value)) {
- const /** @type {?} */ stylesObj = /** @type {?} */ (value);
- Object.keys(stylesObj).forEach(prop => {
- extractStyleParams(stylesObj[prop]).forEach(sub => {
- if (!params.hasOwnProperty(sub)) {
- missingSubs.add(sub);
- }
- });
- });
- }
- });
- if (missingSubs.size) {
- const /** @type {?} */ missingSubsArr = iteratorToArray(missingSubs.values());
- context.errors.push(`state("${metadata.name}", ...) must define default values for all the following style substitutions: ${missingSubsArr.join(', ')}`);
- }
- }
- return {
- type: 0 /* State */,
- name: metadata.name,
- style: styleAst,
- options: astParams ? { params: astParams } : null
- };
- }
- /**
- * @param {?} metadata
- * @param {?} context
- * @return {?}
- */
- visitTransition(metadata, context) {
- context.queryCount = 0;
- context.depCount = 0;
- const /** @type {?} */ animation = visitDslNode(this, normalizeAnimationEntry(metadata.animation), context);
- const /** @type {?} */ matchers = parseTransitionExpr(metadata.expr, context.errors);
- return {
- type: 1 /* Transition */,
- matchers,
- animation,
- queryCount: context.queryCount,
- depCount: context.depCount,
- options: normalizeAnimationOptions(metadata.options)
- };
- }
- /**
- * @param {?} metadata
- * @param {?} context
- * @return {?}
- */
- visitSequence(metadata, context) {
- return {
- type: 2 /* Sequence */,
- steps: metadata.steps.map(s => visitDslNode(this, s, context)),
- options: normalizeAnimationOptions(metadata.options)
- };
- }
- /**
- * @param {?} metadata
- * @param {?} context
- * @return {?}
- */
- visitGroup(metadata, context) {
- const /** @type {?} */ currentTime = context.currentTime;
- let /** @type {?} */ furthestTime = 0;
- const /** @type {?} */ steps = metadata.steps.map(step => {
- context.currentTime = currentTime;
- const /** @type {?} */ innerAst = visitDslNode(this, step, context);
- furthestTime = Math.max(furthestTime, context.currentTime);
- return innerAst;
- });
- context.currentTime = furthestTime;
- return {
- type: 3 /* Group */,
- steps,
- options: normalizeAnimationOptions(metadata.options)
- };
- }
- /**
- * @param {?} metadata
- * @param {?} context
- * @return {?}
- */
- visitAnimate(metadata, context) {
- const /** @type {?} */ timingAst = constructTimingAst(metadata.timings, context.errors);
- context.currentAnimateTimings = timingAst;
- let /** @type {?} */ styleAst;
- let /** @type {?} */ styleMetadata = metadata.styles ? metadata.styles : style({});
- if (styleMetadata.type == 5 /* Keyframes */) {
- styleAst = this.visitKeyframes(/** @type {?} */ (styleMetadata), context);
- }
- else {
- let /** @type {?} */ styleMetadata = /** @type {?} */ (metadata.styles);
- let /** @type {?} */ isEmpty = false;
- if (!styleMetadata) {
- isEmpty = true;
- const /** @type {?} */ newStyleData = {};
- if (timingAst.easing) {
- newStyleData['easing'] = timingAst.easing;
- }
- styleMetadata = style(newStyleData);
- }
- context.currentTime += timingAst.duration + timingAst.delay;
- const /** @type {?} */ _styleAst = this.visitStyle(styleMetadata, context);
- _styleAst.isEmptyStep = isEmpty;
- styleAst = _styleAst;
- }
- context.currentAnimateTimings = null;
- return {
- type: 4 /* Animate */,
- timings: timingAst,
- style: styleAst,
- options: null
- };
- }
- /**
- * @param {?} metadata
- * @param {?} context
- * @return {?}
- */
- visitStyle(metadata, context) {
- const /** @type {?} */ ast = this._makeStyleAst(metadata, context);
- this._validateStyleAst(ast, context);
- return ast;
- }
- /**
- * @param {?} metadata
- * @param {?} context
- * @return {?}
- */
- _makeStyleAst(metadata, context) {
- const /** @type {?} */ styles = [];
- if (Array.isArray(metadata.styles)) {
- (/** @type {?} */ (metadata.styles)).forEach(styleTuple => {
- if (typeof styleTuple == 'string') {
- if (styleTuple == AUTO_STYLE) {
- styles.push(/** @type {?} */ (styleTuple));
- }
- else {
- context.errors.push(`The provided style string value ${styleTuple} is not allowed.`);
- }
- }
- else {
- styles.push(/** @type {?} */ (styleTuple));
- }
- });
- }
- else {
- styles.push(metadata.styles);
- }
- let /** @type {?} */ containsDynamicStyles = false;
- let /** @type {?} */ collectedEasing = null;
- styles.forEach(styleData => {
- if (isObject(styleData)) {
- const /** @type {?} */ styleMap = /** @type {?} */ (styleData);
- const /** @type {?} */ easing = styleMap['easing'];
- if (easing) {
- collectedEasing = /** @type {?} */ (easing);
- delete styleMap['easing'];
- }
- if (!containsDynamicStyles) {
- for (let /** @type {?} */ prop in styleMap) {
- const /** @type {?} */ value = styleMap[prop];
- if (value.toString().indexOf(SUBSTITUTION_EXPR_START) >= 0) {
- containsDynamicStyles = true;
- break;
- }
- }
- }
- }
- });
- return {
- type: 6 /* Style */,
- styles,
- easing: collectedEasing,
- offset: metadata.offset, containsDynamicStyles,
- options: null
- };
- }
- /**
- * @param {?} ast
- * @param {?} context
- * @return {?}
- */
- _validateStyleAst(ast, context) {
- const /** @type {?} */ timings = context.currentAnimateTimings;
- let /** @type {?} */ endTime = context.currentTime;
- let /** @type {?} */ startTime = context.currentTime;
- if (timings && startTime > 0) {
- startTime -= timings.duration + timings.delay;
- }
- ast.styles.forEach(tuple => {
- if (typeof tuple == 'string')
- return;
- Object.keys(tuple).forEach(prop => {
- if (!this._driver.validateStyleProperty(prop)) {
- context.errors.push(`The provided animation property "${prop}" is not a supported CSS property for animations`);
- return;
- }
- const /** @type {?} */ collectedStyles = context.collectedStyles[/** @type {?} */ ((context.currentQuerySelector))];
- const /** @type {?} */ collectedEntry = collectedStyles[prop];
- let /** @type {?} */ updateCollectedStyle = true;
- if (collectedEntry) {
- if (startTime != endTime && startTime >= collectedEntry.startTime &&
- endTime <= collectedEntry.endTime) {
- context.errors.push(`The CSS property "${prop}" that exists between the times of "${collectedEntry.startTime}ms" and "${collectedEntry.endTime}ms" is also being animated in a parallel animation between the times of "${startTime}ms" and "${endTime}ms"`);
- updateCollectedStyle = false;
- }
- // we always choose the smaller start time value since we
- // want to have a record of the entire animation window where
- // the style property is being animated in between
- startTime = collectedEntry.startTime;
- }
- if (updateCollectedStyle) {
- collectedStyles[prop] = { startTime, endTime };
- }
- if (context.options) {
- validateStyleParams(tuple[prop], context.options, context.errors);
- }
- });
- });
- }
- /**
- * @param {?} metadata
- * @param {?} context
- * @return {?}
- */
- visitKeyframes(metadata, context) {
- const /** @type {?} */ ast = { type: 5 /* Keyframes */, styles: [], options: null };
- if (!context.currentAnimateTimings) {
- context.errors.push(`keyframes() must be placed inside of a call to animate()`);
- return ast;
- }
- const /** @type {?} */ MAX_KEYFRAME_OFFSET = 1;
- let /** @type {?} */ totalKeyframesWithOffsets = 0;
- const /** @type {?} */ offsets = [];
- let /** @type {?} */ offsetsOutOfOrder = false;
- let /** @type {?} */ keyframesOutOfRange = false;
- let /** @type {?} */ previousOffset = 0;
- const /** @type {?} */ keyframes = metadata.steps.map(styles => {
- const /** @type {?} */ style$$1 = this._makeStyleAst(styles, context);
- let /** @type {?} */ offsetVal = style$$1.offset != null ? style$$1.offset : consumeOffset(style$$1.styles);
- let /** @type {?} */ offset = 0;
- if (offsetVal != null) {
- totalKeyframesWithOffsets++;
- offset = style$$1.offset = offsetVal;
- }
- keyframesOutOfRange = keyframesOutOfRange || offset < 0 || offset > 1;
- offsetsOutOfOrder = offsetsOutOfOrder || offset < previousOffset;
- previousOffset = offset;
- offsets.push(offset);
- return style$$1;
- });
- if (keyframesOutOfRange) {
- context.errors.push(`Please ensure that all keyframe offsets are between 0 and 1`);
- }
- if (offsetsOutOfOrder) {
- context.errors.push(`Please ensure that all keyframe offsets are in order`);
- }
- const /** @type {?} */ length = metadata.steps.length;
- let /** @type {?} */ generatedOffset = 0;
- if (totalKeyframesWithOffsets > 0 && totalKeyframesWithOffsets < length) {
- context.errors.push(`Not all style() steps within the declared keyframes() contain offsets`);
- }
- else if (totalKeyframesWithOffsets == 0) {
- generatedOffset = MAX_KEYFRAME_OFFSET / (length - 1);
- }
- const /** @type {?} */ limit = length - 1;
- const /** @type {?} */ currentTime = context.currentTime;
- const /** @type {?} */ currentAnimateTimings = /** @type {?} */ ((context.currentAnimateTimings));
- const /** @type {?} */ animateDuration = currentAnimateTimings.duration;
- keyframes.forEach((kf, i) => {
- const /** @type {?} */ offset = generatedOffset > 0 ? (i == limit ? 1 : (generatedOffset * i)) : offsets[i];
- const /** @type {?} */ durationUpToThisFrame = offset * animateDuration;
- context.currentTime = currentTime + currentAnimateTimings.delay + durationUpToThisFrame;
- currentAnimateTimings.duration = durationUpToThisFrame;
- this._validateStyleAst(kf, context);
- kf.offset = offset;
- ast.styles.push(kf);
- });
- return ast;
- }
- /**
- * @param {?} metadata
- * @param {?} context
- * @return {?}
- */
- visitReference(metadata, context) {
- return {
- type: 8 /* Reference */,
- animation: visitDslNode(this, normalizeAnimationEntry(metadata.animation), context),
- options: normalizeAnimationOptions(metadata.options)
- };
- }
- /**
- * @param {?} metadata
- * @param {?} context
- * @return {?}
- */
- visitAnimateChild(metadata, context) {
- context.depCount++;
- return {
- type: 9 /* AnimateChild */,
- options: normalizeAnimationOptions(metadata.options)
- };
- }
- /**
- * @param {?} metadata
- * @param {?} context
- * @return {?}
- */
- visitAnimateRef(metadata, context) {
- return {
- type: 10 /* AnimateRef */,
- animation: this.visitReference(metadata.animation, context),
- options: normalizeAnimationOptions(metadata.options)
- };
- }
- /**
- * @param {?} metadata
- * @param {?} context
- * @return {?}
- */
- visitQuery(metadata, context) {
- const /** @type {?} */ parentSelector = /** @type {?} */ ((context.currentQuerySelector));
- const /** @type {?} */ options = /** @type {?} */ ((metadata.options || {}));
- context.queryCount++;
- context.currentQuery = metadata;
- const [selector, includeSelf] = normalizeSelector(metadata.selector);
- context.currentQuerySelector =
- parentSelector.length ? (parentSelector + ' ' + selector) : selector;
- getOrSetAsInMap(context.collectedStyles, context.currentQuerySelector, {});
- const /** @type {?} */ animation = visitDslNode(this, normalizeAnimationEntry(metadata.animation), context);
- context.currentQuery = null;
- context.currentQuerySelector = parentSelector;
- return {
- type: 11 /* Query */,
- selector,
- limit: options.limit || 0,
- optional: !!options.optional, includeSelf, animation,
- originalSelector: metadata.selector,
- options: normalizeAnimationOptions(metadata.options)
- };
- }
- /**
- * @param {?} metadata
- * @param {?} context
- * @return {?}
- */
- visitStagger(metadata, context) {
- if (!context.currentQuery) {
- context.errors.push(`stagger() can only be used inside of query()`);
- }
- const /** @type {?} */ timings = metadata.timings === 'full' ?
- { duration: 0, delay: 0, easing: 'full' } :
- resolveTiming(metadata.timings, context.errors, true);
- return {
- type: 12 /* Stagger */,
- animation: visitDslNode(this, normalizeAnimationEntry(metadata.animation), context), timings,
- options: null
- };
- }
- }
- /**
- * @param {?} selector
- * @return {?}
- */
- function normalizeSelector(selector) {
- const /** @type {?} */ hasAmpersand = selector.split(/\s*,\s*/).find(token => token == SELF_TOKEN) ? true : false;
- if (hasAmpersand) {
- selector = selector.replace(SELF_TOKEN_REGEX, '');
- }
- // the :enter and :leave selectors are filled in at runtime during timeline building
- selector = selector.replace(/@\*/g, NG_TRIGGER_SELECTOR)
- .replace(/@\w+/g, match => NG_TRIGGER_SELECTOR + '-' + match.substr(1))
- .replace(/:animating/g, NG_ANIMATING_SELECTOR);
- return [selector, hasAmpersand];
- }
- /**
- * @param {?} obj
- * @return {?}
- */
- function normalizeParams(obj) {
- return obj ? copyObj(obj) : null;
- }
- class AnimationAstBuilderContext {
- /**
- * @param {?} errors
- */
- constructor(errors) {
- this.errors = errors;
- this.queryCount = 0;
- this.depCount = 0;
- this.currentTransition = null;
- this.currentQuery = null;
- this.currentQuerySelector = null;
- this.currentAnimateTimings = null;
- this.currentTime = 0;
- this.collectedStyles = {};
- this.options = null;
- }
- }
- /**
- * @param {?} styles
- * @return {?}
- */
- function consumeOffset(styles) {
- if (typeof styles == 'string')
- return null;
- let /** @type {?} */ offset = null;
- if (Array.isArray(styles)) {
- styles.forEach(styleTuple => {
- if (isObject(styleTuple) && styleTuple.hasOwnProperty('offset')) {
- const /** @type {?} */ obj = /** @type {?} */ (styleTuple);
- offset = parseFloat(/** @type {?} */ (obj['offset']));
- delete obj['offset'];
- }
- });
- }
- else if (isObject(styles) && styles.hasOwnProperty('offset')) {
- const /** @type {?} */ obj = /** @type {?} */ (styles);
- offset = parseFloat(/** @type {?} */ (obj['offset']));
- delete obj['offset'];
- }
- return offset;
- }
- /**
- * @param {?} value
- * @return {?}
- */
- function isObject(value) {
- return !Array.isArray(value) && typeof value == 'object';
- }
- /**
- * @param {?} value
- * @param {?} errors
- * @return {?}
- */
- function constructTimingAst(value, errors) {
- let /** @type {?} */ timings = null;
- if (value.hasOwnProperty('duration')) {
- timings = /** @type {?} */ (value);
- }
- else if (typeof value == 'number') {
- const /** @type {?} */ duration = resolveTiming(/** @type {?} */ (value), errors).duration;
- return makeTimingAst(/** @type {?} */ (duration), 0, '');
- }
- const /** @type {?} */ strValue = /** @type {?} */ (value);
- const /** @type {?} */ isDynamic = strValue.split(/\s+/).some(v => v.charAt(0) == '{' && v.charAt(1) == '{');
- if (isDynamic) {
- const /** @type {?} */ ast = /** @type {?} */ (makeTimingAst(0, 0, ''));
- ast.dynamic = true;
- ast.strValue = strValue;
- return /** @type {?} */ (ast);
- }
- timings = timings || resolveTiming(strValue, errors);
- return makeTimingAst(timings.duration, timings.delay, timings.easing);
- }
- /**
- * @param {?} options
- * @return {?}
- */
- function normalizeAnimationOptions(options) {
- if (options) {
- options = copyObj(options);
- if (options['params']) {
- options['params'] = /** @type {?} */ ((normalizeParams(options['params'])));
- }
- }
- else {
- options = {};
- }
- return options;
- }
- /**
- * @param {?} duration
- * @param {?} delay
- * @param {?} easing
- * @return {?}
- */
- function makeTimingAst(duration, delay, easing) {
- return { duration, delay, easing };
- }
-
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes} checked by tsc
- */
- /**
- * @record
- */
-
- /**
- * @param {?} element
- * @param {?} keyframes
- * @param {?} preStyleProps
- * @param {?} postStyleProps
- * @param {?} duration
- * @param {?} delay
- * @param {?=} easing
- * @param {?=} subTimeline
- * @return {?}
- */
- function createTimelineInstruction(element, keyframes, preStyleProps, postStyleProps, duration, delay, easing = null, subTimeline = false) {
- return {
- type: 1 /* TimelineAnimation */,
- element,
- keyframes,
- preStyleProps,
- postStyleProps,
- duration,
- delay,
- totalTime: duration + delay, easing, subTimeline
- };
- }
-
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes} checked by tsc
- */
- class ElementInstructionMap {
- constructor() {
- this._map = new Map();
- }
- /**
- * @param {?} element
- * @return {?}
- */
- consume(element) {
- let /** @type {?} */ instructions = this._map.get(element);
- if (instructions) {
- this._map.delete(element);
- }
- else {
- instructions = [];
- }
- return instructions;
- }
- /**
- * @param {?} element
- * @param {?} instructions
- * @return {?}
- */
- append(element, instructions) {
- let /** @type {?} */ existingInstructions = this._map.get(element);
- if (!existingInstructions) {
- this._map.set(element, existingInstructions = []);
- }
- existingInstructions.push(...instructions);
- }
- /**
- * @param {?} element
- * @return {?}
- */
- has(element) { return this._map.has(element); }
- /**
- * @return {?}
- */
- clear() { this._map.clear(); }
- }
-
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes} checked by tsc
- */
- const ONE_FRAME_IN_MILLISECONDS = 1;
- const ENTER_TOKEN = ':enter';
- const ENTER_TOKEN_REGEX = new RegExp(ENTER_TOKEN, 'g');
- const LEAVE_TOKEN = ':leave';
- const LEAVE_TOKEN_REGEX = new RegExp(LEAVE_TOKEN, 'g');
- /**
- * @param {?} driver
- * @param {?} rootElement
- * @param {?} ast
- * @param {?} enterClassName
- * @param {?} leaveClassName
- * @param {?=} startingStyles
- * @param {?=} finalStyles
- * @param {?=} options
- * @param {?=} subInstructions
- * @param {?=} errors
- * @return {?}
- */
- function buildAnimationTimelines(driver, rootElement, ast, enterClassName, leaveClassName, startingStyles = {}, finalStyles = {}, options, subInstructions, errors = []) {
- return new AnimationTimelineBuilderVisitor().buildKeyframes(driver, rootElement, ast, enterClassName, leaveClassName, startingStyles, finalStyles, options, subInstructions, errors);
- }
- class AnimationTimelineBuilderVisitor {
- /**
- * @param {?} driver
- * @param {?} rootElement
- * @param {?} ast
- * @param {?} enterClassName
- * @param {?} leaveClassName
- * @param {?} startingStyles
- * @param {?} finalStyles
- * @param {?} options
- * @param {?=} subInstructions
- * @param {?=} errors
- * @return {?}
- */
- buildKeyframes(driver, rootElement, ast, enterClassName, leaveClassName, startingStyles, finalStyles, options, subInstructions, errors = []) {
- subInstructions = subInstructions || new ElementInstructionMap();
- const /** @type {?} */ context = new AnimationTimelineContext(driver, rootElement, subInstructions, enterClassName, leaveClassName, errors, []);
- context.options = options;
- context.currentTimeline.setStyles([startingStyles], null, context.errors, options);
- visitDslNode(this, ast, context);
- // this checks to see if an actual animation happened
- const /** @type {?} */ timelines = context.timelines.filter(timeline => timeline.containsAnimation());
- if (timelines.length && Object.keys(finalStyles).length) {
- const /** @type {?} */ tl = timelines[timelines.length - 1];
- if (!tl.allowOnlyTimelineStyles()) {
- tl.setStyles([finalStyles], null, context.errors, options);
- }
- }
- return timelines.length ? timelines.map(timeline => timeline.buildKeyframes()) :
- [createTimelineInstruction(rootElement, [], [], [], 0, 0, '', false)];
- }
- /**
- * @param {?} ast
- * @param {?} context
- * @return {?}
- */
- visitTrigger(ast, context) {
- // these values are not visited in this AST
- }
- /**
- * @param {?} ast
- * @param {?} context
- * @return {?}
- */
- visitState(ast, context) {
- // these values are not visited in this AST
- }
- /**
- * @param {?} ast
- * @param {?} context
- * @return {?}
- */
- visitTransition(ast, context) {
- // these values are not visited in this AST
- }
- /**
- * @param {?} ast
- * @param {?} context
- * @return {?}
- */
- visitAnimateChild(ast, context) {
- const /** @type {?} */ elementInstructions = context.subInstructions.consume(context.element);
- if (elementInstructions) {
- const /** @type {?} */ innerContext = context.createSubContext(ast.options);
- const /** @type {?} */ startTime = context.currentTimeline.currentTime;
- const /** @type {?} */ endTime = this._visitSubInstructions(elementInstructions, innerContext, /** @type {?} */ (innerContext.options));
- if (startTime != endTime) {
- // we do this on the upper context because we created a sub context for
- // the sub child animations
- context.transformIntoNewTimeline(endTime);
- }
- }
- context.previousNode = ast;
- }
- /**
- * @param {?} ast
- * @param {?} context
- * @return {?}
- */
- visitAnimateRef(ast, context) {
- const /** @type {?} */ innerContext = context.createSubContext(ast.options);
- innerContext.transformIntoNewTimeline();
- this.visitReference(ast.animation, innerContext);
- context.transformIntoNewTimeline(innerContext.currentTimeline.currentTime);
- context.previousNode = ast;
- }
- /**
- * @param {?} instructions
- * @param {?} context
- * @param {?} options
- * @return {?}
- */
- _visitSubInstructions(instructions, context, options) {
- const /** @type {?} */ startTime = context.currentTimeline.currentTime;
- let /** @type {?} */ furthestTime = startTime;
- // this is a special-case for when a user wants to skip a sub
- // animation from being fired entirely.
- const /** @type {?} */ duration = options.duration != null ? resolveTimingValue(options.duration) : null;
- const /** @type {?} */ delay = options.delay != null ? resolveTimingValue(options.delay) : null;
- if (duration !== 0) {
- instructions.forEach(instruction => {
- const /** @type {?} */ instructionTimings = context.appendInstructionToTimeline(instruction, duration, delay);
- furthestTime =
- Math.max(furthestTime, instructionTimings.duration + instructionTimings.delay);
- });
- }
- return furthestTime;
- }
- /**
- * @param {?} ast
- * @param {?} context
- * @return {?}
- */
- visitReference(ast, context) {
- context.updateOptions(ast.options, true);
- visitDslNode(this, ast.animation, context);
- context.previousNode = ast;
- }
- /**
- * @param {?} ast
- * @param {?} context
- * @return {?}
- */
- visitSequence(ast, context) {
- const /** @type {?} */ subContextCount = context.subContextCount;
- let /** @type {?} */ ctx = context;
- const /** @type {?} */ options = ast.options;
- if (options && (options.params || options.delay)) {
- ctx = context.createSubContext(options);
- ctx.transformIntoNewTimeline();
- if (options.delay != null) {
- if (ctx.previousNode.type == 6 /* Style */) {
- ctx.currentTimeline.snapshotCurrentStyles();
- ctx.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
- }
- const /** @type {?} */ delay = resolveTimingValue(options.delay);
- ctx.delayNextStep(delay);
- }
- }
- if (ast.steps.length) {
- ast.steps.forEach(s => visitDslNode(this, s, ctx));
- // this is here just incase the inner steps only contain or end with a style() call
- ctx.currentTimeline.applyStylesToKeyframe();
- // this means that some animation function within the sequence
- // ended up creating a sub timeline (which means the current
- // timeline cannot overlap with the contents of the sequence)
- if (ctx.subContextCount > subContextCount) {
- ctx.transformIntoNewTimeline();
- }
- }
- context.previousNode = ast;
- }
- /**
- * @param {?} ast
- * @param {?} context
- * @return {?}
- */
- visitGroup(ast, context) {
- const /** @type {?} */ innerTimelines = [];
- let /** @type {?} */ furthestTime = context.currentTimeline.currentTime;
- const /** @type {?} */ delay = ast.options && ast.options.delay ? resolveTimingValue(ast.options.delay) : 0;
- ast.steps.forEach(s => {
- const /** @type {?} */ innerContext = context.createSubContext(ast.options);
- if (delay) {
- innerContext.delayNextStep(delay);
- }
- visitDslNode(this, s, innerContext);
- furthestTime = Math.max(furthestTime, innerContext.currentTimeline.currentTime);
- innerTimelines.push(innerContext.currentTimeline);
- });
- // this operation is run after the AST loop because otherwise
- // if the parent timeline's collected styles were updated then
- // it would pass in invalid data into the new-to-be forked items
- innerTimelines.forEach(timeline => context.currentTimeline.mergeTimelineCollectedStyles(timeline));
- context.transformIntoNewTimeline(furthestTime);
- context.previousNode = ast;
- }
- /**
- * @param {?} ast
- * @param {?} context
- * @return {?}
- */
- _visitTiming(ast, context) {
- if ((/** @type {?} */ (ast)).dynamic) {
- const /** @type {?} */ strValue = (/** @type {?} */ (ast)).strValue;
- const /** @type {?} */ timingValue = context.params ? interpolateParams(strValue, context.params, context.errors) : strValue;
- return resolveTiming(timingValue, context.errors);
- }
- else {
- return { duration: ast.duration, delay: ast.delay, easing: ast.easing };
- }
- }
- /**
- * @param {?} ast
- * @param {?} context
- * @return {?}
- */
- visitAnimate(ast, context) {
- const /** @type {?} */ timings = context.currentAnimateTimings = this._visitTiming(ast.timings, context);
- const /** @type {?} */ timeline = context.currentTimeline;
- if (timings.delay) {
- context.incrementTime(timings.delay);
- timeline.snapshotCurrentStyles();
- }
- const /** @type {?} */ style$$1 = ast.style;
- if (style$$1.type == 5 /* Keyframes */) {
- this.visitKeyframes(style$$1, context);
- }
- else {
- context.incrementTime(timings.duration);
- this.visitStyle(/** @type {?} */ (style$$1), context);
- timeline.applyStylesToKeyframe();
- }
- context.currentAnimateTimings = null;
- context.previousNode = ast;
- }
- /**
- * @param {?} ast
- * @param {?} context
- * @return {?}
- */
- visitStyle(ast, context) {
- const /** @type {?} */ timeline = context.currentTimeline;
- const /** @type {?} */ timings = /** @type {?} */ ((context.currentAnimateTimings));
- // this is a special case for when a style() call
- // directly follows an animate() call (but not inside of an animate() call)
- if (!timings && timeline.getCurrentStyleProperties().length) {
- timeline.forwardFrame();
- }
- const /** @type {?} */ easing = (timings && timings.easing) || ast.easing;
- if (ast.isEmptyStep) {
- timeline.applyEmptyStep(easing);
- }
- else {
- timeline.setStyles(ast.styles, easing, context.errors, context.options);
- }
- context.previousNode = ast;
- }
- /**
- * @param {?} ast
- * @param {?} context
- * @return {?}
- */
- visitKeyframes(ast, context) {
- const /** @type {?} */ currentAnimateTimings = /** @type {?} */ ((context.currentAnimateTimings));
- const /** @type {?} */ startTime = (/** @type {?} */ ((context.currentTimeline))).duration;
- const /** @type {?} */ duration = currentAnimateTimings.duration;
- const /** @type {?} */ innerContext = context.createSubContext();
- const /** @type {?} */ innerTimeline = innerContext.currentTimeline;
- innerTimeline.easing = currentAnimateTimings.easing;
- ast.styles.forEach(step => {
- const /** @type {?} */ offset = step.offset || 0;
- innerTimeline.forwardTime(offset * duration);
- innerTimeline.setStyles(step.styles, step.easing, context.errors, context.options);
- innerTimeline.applyStylesToKeyframe();
- });
- // this will ensure that the parent timeline gets all the styles from
- // the child even if the new timeline below is not used
- context.currentTimeline.mergeTimelineCollectedStyles(innerTimeline);
- // we do this because the window between this timeline and the sub timeline
- // should ensure that the styles within are exactly the same as they were before
- context.transformIntoNewTimeline(startTime + duration);
- context.previousNode = ast;
- }
- /**
- * @param {?} ast
- * @param {?} context
- * @return {?}
- */
- visitQuery(ast, context) {
- // in the event that the first step before this is a style step we need
- // to ensure the styles are applied before the children are animated
- const /** @type {?} */ startTime = context.currentTimeline.currentTime;
- const /** @type {?} */ options = /** @type {?} */ ((ast.options || {}));
- const /** @type {?} */ delay = options.delay ? resolveTimingValue(options.delay) : 0;
- if (delay && (context.previousNode.type === 6 /* Style */ ||
- (startTime == 0 && context.currentTimeline.getCurrentStyleProperties().length))) {
- context.currentTimeline.snapshotCurrentStyles();
- context.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
- }
- let /** @type {?} */ furthestTime = startTime;
- const /** @type {?} */ elms = context.invokeQuery(ast.selector, ast.originalSelector, ast.limit, ast.includeSelf, options.optional ? true : false, context.errors);
- context.currentQueryTotal = elms.length;
- let /** @type {?} */ sameElementTimeline = null;
- elms.forEach((element, i) => {
- context.currentQueryIndex = i;
- const /** @type {?} */ innerContext = context.createSubContext(ast.options, element);
- if (delay) {
- innerContext.delayNextStep(delay);
- }
- if (element === context.element) {
- sameElementTimeline = innerContext.currentTimeline;
- }
- visitDslNode(this, ast.animation, innerContext);
- // this is here just incase the inner steps only contain or end
- // with a style() call (which is here to signal that this is a preparatory
- // call to style an element before it is animated again)
- innerContext.currentTimeline.applyStylesToKeyframe();
- const /** @type {?} */ endTime = innerContext.currentTimeline.currentTime;
- furthestTime = Math.max(furthestTime, endTime);
- });
- context.currentQueryIndex = 0;
- context.currentQueryTotal = 0;
- context.transformIntoNewTimeline(furthestTime);
- if (sameElementTimeline) {
- context.currentTimeline.mergeTimelineCollectedStyles(sameElementTimeline);
- context.currentTimeline.snapshotCurrentStyles();
- }
- context.previousNode = ast;
- }
- /**
- * @param {?} ast
- * @param {?} context
- * @return {?}
- */
- visitStagger(ast, context) {
- const /** @type {?} */ parentContext = /** @type {?} */ ((context.parentContext));
- const /** @type {?} */ tl = context.currentTimeline;
- const /** @type {?} */ timings = ast.timings;
- const /** @type {?} */ duration = Math.abs(timings.duration);
- const /** @type {?} */ maxTime = duration * (context.currentQueryTotal - 1);
- let /** @type {?} */ delay = duration * context.currentQueryIndex;
- let /** @type {?} */ staggerTransformer = timings.duration < 0 ? 'reverse' : timings.easing;
- switch (staggerTransformer) {
- case 'reverse':
- delay = maxTime - delay;
- break;
- case 'full':
- delay = parentContext.currentStaggerTime;
- break;
- }
- const /** @type {?} */ timeline = context.currentTimeline;
- if (delay) {
- timeline.delayNextStep(delay);
- }
- const /** @type {?} */ startingTime = timeline.currentTime;
- visitDslNode(this, ast.animation, context);
- context.previousNode = ast;
- // time = duration + delay
- // the reason why this computation is so complex is because
- // the inner timeline may either have a delay value or a stretched
- // keyframe depending on if a subtimeline is not used or is used.
- parentContext.currentStaggerTime =
- (tl.currentTime - startingTime) + (tl.startTime - parentContext.currentTimeline.startTime);
- }
- }
- const DEFAULT_NOOP_PREVIOUS_NODE = /** @type {?} */ ({});
- class AnimationTimelineContext {
- /**
- * @param {?} _driver
- * @param {?} element
- * @param {?} subInstructions
- * @param {?} _enterClassName
- * @param {?} _leaveClassName
- * @param {?} errors
- * @param {?} timelines
- * @param {?=} initialTimeline
- */
- constructor(_driver, element, subInstructions, _enterClassName, _leaveClassName, errors, timelines, initialTimeline) {
- this._driver = _driver;
- this.element = element;
- this.subInstructions = subInstructions;
- this._enterClassName = _enterClassName;
- this._leaveClassName = _leaveClassName;
- this.errors = errors;
- this.timelines = timelines;
- this.parentContext = null;
- this.currentAnimateTimings = null;
- this.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
- this.subContextCount = 0;
- this.options = {};
- this.currentQueryIndex = 0;
- this.currentQueryTotal = 0;
- this.currentStaggerTime = 0;
- this.currentTimeline = initialTimeline || new TimelineBuilder(this._driver, element, 0);
- timelines.push(this.currentTimeline);
- }
- /**
- * @return {?}
- */
- get params() { return this.options.params; }
- /**
- * @param {?} options
- * @param {?=} skipIfExists
- * @return {?}
- */
- updateOptions(options, skipIfExists) {
- if (!options)
- return;
- const /** @type {?} */ newOptions = /** @type {?} */ (options);
- let /** @type {?} */ optionsToUpdate = this.options;
- // NOTE: this will get patched up when other animation methods support duration overrides
- if (newOptions.duration != null) {
- (/** @type {?} */ (optionsToUpdate)).duration = resolveTimingValue(newOptions.duration);
- }
- if (newOptions.delay != null) {
- optionsToUpdate.delay = resolveTimingValue(newOptions.delay);
- }
- const /** @type {?} */ newParams = newOptions.params;
- if (newParams) {
- let /** @type {?} */ paramsToUpdate = /** @type {?} */ ((optionsToUpdate.params));
- if (!paramsToUpdate) {
- paramsToUpdate = this.options.params = {};
- }
- Object.keys(newParams).forEach(name => {
- if (!skipIfExists || !paramsToUpdate.hasOwnProperty(name)) {
- paramsToUpdate[name] = interpolateParams(newParams[name], paramsToUpdate, this.errors);
- }
- });
- }
- }
- /**
- * @return {?}
- */
- _copyOptions() {
- const /** @type {?} */ options = {};
- if (this.options) {
- const /** @type {?} */ oldParams = this.options.params;
- if (oldParams) {
- const /** @type {?} */ params = options['params'] = {};
- Object.keys(oldParams).forEach(name => { params[name] = oldParams[name]; });
- }
- }
- return options;
- }
- /**
- * @param {?=} options
- * @param {?=} element
- * @param {?=} newTime
- * @return {?}
- */
- createSubContext(options = null, element, newTime) {
- const /** @type {?} */ target = element || this.element;
- const /** @type {?} */ context = new AnimationTimelineContext(this._driver, target, this.subInstructions, this._enterClassName, this._leaveClassName, this.errors, this.timelines, this.currentTimeline.fork(target, newTime || 0));
- context.previousNode = this.previousNode;
- context.currentAnimateTimings = this.currentAnimateTimings;
- context.options = this._copyOptions();
- context.updateOptions(options);
- context.currentQueryIndex = this.currentQueryIndex;
- context.currentQueryTotal = this.currentQueryTotal;
- context.parentContext = this;
- this.subContextCount++;
- return context;
- }
- /**
- * @param {?=} newTime
- * @return {?}
- */
- transformIntoNewTimeline(newTime) {
- this.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
- this.currentTimeline = this.currentTimeline.fork(this.element, newTime);
- this.timelines.push(this.currentTimeline);
- return this.currentTimeline;
- }
- /**
- * @param {?} instruction
- * @param {?} duration
- * @param {?} delay
- * @return {?}
- */
- appendInstructionToTimeline(instruction, duration, delay) {
- const /** @type {?} */ updatedTimings = {
- duration: duration != null ? duration : instruction.duration,
- delay: this.currentTimeline.currentTime + (delay != null ? delay : 0) + instruction.delay,
- easing: ''
- };
- const /** @type {?} */ builder = new SubTimelineBuilder(this._driver, instruction.element, instruction.keyframes, instruction.preStyleProps, instruction.postStyleProps, updatedTimings, instruction.stretchStartingKeyframe);
- this.timelines.push(builder);
- return updatedTimings;
- }
- /**
- * @param {?} time
- * @return {?}
- */
- incrementTime(time) {
- this.currentTimeline.forwardTime(this.currentTimeline.duration + time);
- }
- /**
- * @param {?} delay
- * @return {?}
- */
- delayNextStep(delay) {
- // negative delays are not yet supported
- if (delay > 0) {
- this.currentTimeline.delayNextStep(delay);
- }
- }
- /**
- * @param {?} selector
- * @param {?} originalSelector
- * @param {?} limit
- * @param {?} includeSelf
- * @param {?} optional
- * @param {?} errors
- * @return {?}
- */
- invokeQuery(selector, originalSelector, limit, includeSelf, optional, errors) {
- let /** @type {?} */ results = [];
- if (includeSelf) {
- results.push(this.element);
- }
- if (selector.length > 0) {
- // if :self is only used then the selector is empty
- selector = selector.replace(ENTER_TOKEN_REGEX, '.' + this._enterClassName);
- selector = selector.replace(LEAVE_TOKEN_REGEX, '.' + this._leaveClassName);
- const /** @type {?} */ multi = limit != 1;
- let /** @type {?} */ elements = this._driver.query(this.element, selector, multi);
- if (limit !== 0) {
- elements = limit < 0 ? elements.slice(elements.length + limit, elements.length) :
- elements.slice(0, limit);
- }
- results.push(...elements);
- }
- if (!optional && results.length == 0) {
- errors.push(`\`query("${originalSelector}")\` returned zero elements. (Use \`query("${originalSelector}", { optional: true })\` if you wish to allow this.)`);
- }
- return results;
- }
- }
- class TimelineBuilder {
- /**
- * @param {?} _driver
- * @param {?} element
- * @param {?} startTime
- * @param {?=} _elementTimelineStylesLookup
- */
- constructor(_driver, element, startTime, _elementTimelineStylesLookup) {
- this._driver = _driver;
- this.element = element;
- this.startTime = startTime;
- this._elementTimelineStylesLookup = _elementTimelineStylesLookup;
- this.duration = 0;
- this._previousKeyframe = {};
- this._currentKeyframe = {};
- this._keyframes = new Map();
- this._styleSummary = {};
- this._pendingStyles = {};
- this._backFill = {};
- this._currentEmptyStepKeyframe = null;
- if (!this._elementTimelineStylesLookup) {
- this._elementTimelineStylesLookup = new Map();
- }
- this._localTimelineStyles = Object.create(this._backFill, {});
- this._globalTimelineStyles = /** @type {?} */ ((this._elementTimelineStylesLookup.get(element)));
- if (!this._globalTimelineStyles) {
- this._globalTimelineStyles = this._localTimelineStyles;
- this._elementTimelineStylesLookup.set(element, this._localTimelineStyles);
- }
- this._loadKeyframe();
- }
- /**
- * @return {?}
- */
- containsAnimation() {
- switch (this._keyframes.size) {
- case 0:
- return false;
- case 1:
- return this.getCurrentStyleProperties().length > 0;
- default:
- return true;
- }
- }
- /**
- * @return {?}
- */
- getCurrentStyleProperties() { return Object.keys(this._currentKeyframe); }
- /**
- * @return {?}
- */
- get currentTime() { return this.startTime + this.duration; }
- /**
- * @param {?} delay
- * @return {?}
- */
- delayNextStep(delay) {
- // in the event that a style() step is placed right before a stagger()
- // and that style() step is the very first style() value in the animation
- // then we need to make a copy of the keyframe [0, copy, 1] so that the delay
- // properly applies the style() values to work with the stagger...
- const /** @type {?} */ hasPreStyleStep = this._keyframes.size == 1 && Object.keys(this._pendingStyles).length;
- if (this.duration || hasPreStyleStep) {
- this.forwardTime(this.currentTime + delay);
- if (hasPreStyleStep) {
- this.snapshotCurrentStyles();
- }
- }
- else {
- this.startTime += delay;
- }
- }
- /**
- * @param {?} element
- * @param {?=} currentTime
- * @return {?}
- */
- fork(element, currentTime) {
- this.applyStylesToKeyframe();
- return new TimelineBuilder(this._driver, element, currentTime || this.currentTime, this._elementTimelineStylesLookup);
- }
- /**
- * @return {?}
- */
- _loadKeyframe() {
- if (this._currentKeyframe) {
- this._previousKeyframe = this._currentKeyframe;
- }
- this._currentKeyframe = /** @type {?} */ ((this._keyframes.get(this.duration)));
- if (!this._currentKeyframe) {
- this._currentKeyframe = Object.create(this._backFill, {});
- this._keyframes.set(this.duration, this._currentKeyframe);
- }
- }
- /**
- * @return {?}
- */
- forwardFrame() {
- this.duration += ONE_FRAME_IN_MILLISECONDS;
- this._loadKeyframe();
- }
- /**
- * @param {?} time
- * @return {?}
- */
- forwardTime(time) {
- this.applyStylesToKeyframe();
- this.duration = time;
- this._loadKeyframe();
- }
- /**
- * @param {?} prop
- * @param {?} value
- * @return {?}
- */
- _updateStyle(prop, value) {
- this._localTimelineStyles[prop] = value;
- this._globalTimelineStyles[prop] = value;
- this._styleSummary[prop] = { time: this.currentTime, value };
- }
- /**
- * @return {?}
- */
- allowOnlyTimelineStyles() { return this._currentEmptyStepKeyframe !== this._currentKeyframe; }
- /**
- * @param {?} easing
- * @return {?}
- */
- applyEmptyStep(easing) {
- if (easing) {
- this._previousKeyframe['easing'] = easing;
- }
- // special case for animate(duration):
- // all missing styles are filled with a `*` value then
- // if any destination styles are filled in later on the same
- // keyframe then they will override the overridden styles
- // We use `_globalTimelineStyles` here because there may be
- // styles in previous keyframes that are not present in this timeline
- Object.keys(this._globalTimelineStyles).forEach(prop => {
- this._backFill[prop] = this._globalTimelineStyles[prop] || AUTO_STYLE;
- this._currentKeyframe[prop] = AUTO_STYLE;
- });
- this._currentEmptyStepKeyframe = this._currentKeyframe;
- }
- /**
- * @param {?} input
- * @param {?} easing
- * @param {?} errors
- * @param {?=} options
- * @return {?}
- */
- setStyles(input, easing, errors, options) {
- if (easing) {
- this._previousKeyframe['easing'] = easing;
- }
- const /** @type {?} */ params = (options && options.params) || {};
- const /** @type {?} */ styles = flattenStyles(input, this._globalTimelineStyles);
- Object.keys(styles).forEach(prop => {
- const /** @type {?} */ val = interpolateParams(styles[prop], params, errors);
- this._pendingStyles[prop] = val;
- if (!this._localTimelineStyles.hasOwnProperty(prop)) {
- this._backFill[prop] = this._globalTimelineStyles.hasOwnProperty(prop) ?
- this._globalTimelineStyles[prop] :
- AUTO_STYLE;
- }
- this._updateStyle(prop, val);
- });
- }
- /**
- * @return {?}
- */
- applyStylesToKeyframe() {
- const /** @type {?} */ styles = this._pendingStyles;
- const /** @type {?} */ props = Object.keys(styles);
- if (props.length == 0)
- return;
- this._pendingStyles = {};
- props.forEach(prop => {
- const /** @type {?} */ val = styles[prop];
- this._currentKeyframe[prop] = val;
- });
- Object.keys(this._localTimelineStyles).forEach(prop => {
- if (!this._currentKeyframe.hasOwnProperty(prop)) {
- this._currentKeyframe[prop] = this._localTimelineStyles[prop];
- }
- });
- }
- /**
- * @return {?}
- */
- snapshotCurrentStyles() {
- Object.keys(this._localTimelineStyles).forEach(prop => {
- const /** @type {?} */ val = this._localTimelineStyles[prop];
- this._pendingStyles[prop] = val;
- this._updateStyle(prop, val);
- });
- }
- /**
- * @return {?}
- */
- getFinalKeyframe() { return this._keyframes.get(this.duration); }
- /**
- * @return {?}
- */
- get properties() {
- const /** @type {?} */ properties = [];
- for (let /** @type {?} */ prop in this._currentKeyframe) {
- properties.push(prop);
- }
- return properties;
- }
- /**
- * @param {?} timeline
- * @return {?}
- */
- mergeTimelineCollectedStyles(timeline) {
- Object.keys(timeline._styleSummary).forEach(prop => {
- const /** @type {?} */ details0 = this._styleSummary[prop];
- const /** @type {?} */ details1 = timeline._styleSummary[prop];
- if (!details0 || details1.time > details0.time) {
- this._updateStyle(prop, details1.value);
- }
- });
- }
- /**
- * @return {?}
- */
- buildKeyframes() {
- this.applyStylesToKeyframe();
- const /** @type {?} */ preStyleProps = new Set();
- const /** @type {?} */ postStyleProps = new Set();
- const /** @type {?} */ isEmpty = this._keyframes.size === 1 && this.duration === 0;
- let /** @type {?} */ finalKeyframes = [];
- this._keyframes.forEach((keyframe, time) => {
- const /** @type {?} */ finalKeyframe = copyStyles(keyframe, true);
- Object.keys(finalKeyframe).forEach(prop => {
- const /** @type {?} */ value = finalKeyframe[prop];
- if (value == ɵPRE_STYLE) {
- preStyleProps.add(prop);
- }
- else if (value == AUTO_STYLE) {
- postStyleProps.add(prop);
- }
- });
- if (!isEmpty) {
- finalKeyframe['offset'] = time / this.duration;
- }
- finalKeyframes.push(finalKeyframe);
- });
- const /** @type {?} */ preProps = preStyleProps.size ? iteratorToArray(preStyleProps.values()) : [];
- const /** @type {?} */ postProps = postStyleProps.size ? iteratorToArray(postStyleProps.values()) : [];
- // special case for a 0-second animation (which is designed just to place styles onscreen)
- if (isEmpty) {
- const /** @type {?} */ kf0 = finalKeyframes[0];
- const /** @type {?} */ kf1 = copyObj(kf0);
- kf0['offset'] = 0;
- kf1['offset'] = 1;
- finalKeyframes = [kf0, kf1];
- }
- return createTimelineInstruction(this.element, finalKeyframes, preProps, postProps, this.duration, this.startTime, this.easing, false);
- }
- }
- class SubTimelineBuilder extends TimelineBuilder {
- /**
- * @param {?} driver
- * @param {?} element
- * @param {?} keyframes
- * @param {?} preStyleProps
- * @param {?} postStyleProps
- * @param {?} timings
- * @param {?=} _stretchStartingKeyframe
- */
- constructor(driver, element, keyframes, preStyleProps, postStyleProps, timings, _stretchStartingKeyframe = false) {
- super(driver, element, timings.delay);
- this.element = element;
- this.keyframes = keyframes;
- this.preStyleProps = preStyleProps;
- this.postStyleProps = postStyleProps;
- this._stretchStartingKeyframe = _stretchStartingKeyframe;
- this.timings = { duration: timings.duration, delay: timings.delay, easing: timings.easing };
- }
- /**
- * @return {?}
- */
- containsAnimation() { return this.keyframes.length > 1; }
- /**
- * @return {?}
- */
- buildKeyframes() {
- let /** @type {?} */ keyframes = this.keyframes;
- let { delay, duration, easing } = this.timings;
- if (this._stretchStartingKeyframe && delay) {
- const /** @type {?} */ newKeyframes = [];
- const /** @type {?} */ totalTime = duration + delay;
- const /** @type {?} */ startingGap = delay / totalTime;
- // the original starting keyframe now starts once the delay is done
- const /** @type {?} */ newFirstKeyframe = copyStyles(keyframes[0], false);
- newFirstKeyframe['offset'] = 0;
- newKeyframes.push(newFirstKeyframe);
- const /** @type {?} */ oldFirstKeyframe = copyStyles(keyframes[0], false);
- oldFirstKeyframe['offset'] = roundOffset(startingGap);
- newKeyframes.push(oldFirstKeyframe);
- /*
- When the keyframe is stretched then it means that the delay before the animation
- starts is gone. Instead the first keyframe is placed at the start of the animation
- and it is then copied to where it starts when the original delay is over. This basically
- means nothing animates during that delay, but the styles are still renderered. For this
- to work the original offset values that exist in the original keyframes must be "warped"
- so that they can take the new keyframe + delay into account.
-
- delay=1000, duration=1000, keyframes = 0 .5 1
-
- turns into
-
- delay=0, duration=2000, keyframes = 0 .33 .66 1
- */
- // offsets between 1 ... n -1 are all warped by the keyframe stretch
- const /** @type {?} */ limit = keyframes.length - 1;
- for (let /** @type {?} */ i = 1; i <= limit; i++) {
- let /** @type {?} */ kf = copyStyles(keyframes[i], false);
- const /** @type {?} */ oldOffset = /** @type {?} */ (kf['offset']);
- const /** @type {?} */ timeAtKeyframe = delay + oldOffset * duration;
- kf['offset'] = roundOffset(timeAtKeyframe / totalTime);
- newKeyframes.push(kf);
- }
- // the new starting keyframe should be added at the start
- duration = totalTime;
- delay = 0;
- easing = '';
- keyframes = newKeyframes;
- }
- return createTimelineInstruction(this.element, keyframes, this.preStyleProps, this.postStyleProps, duration, delay, easing, true);
- }
- }
- /**
- * @param {?} offset
- * @param {?=} decimalPoints
- * @return {?}
- */
- function roundOffset(offset, decimalPoints = 3) {
- const /** @type {?} */ mult = Math.pow(10, decimalPoints - 1);
- return Math.round(offset * mult) / mult;
- }
- /**
- * @param {?} input
- * @param {?} allStyles
- * @return {?}
- */
- function flattenStyles(input, allStyles) {
- const /** @type {?} */ styles = {};
- let /** @type {?} */ allProperties;
- input.forEach(token => {
- if (token === '*') {
- allProperties = allProperties || Object.keys(allStyles);
- allProperties.forEach(prop => { styles[prop] = AUTO_STYLE; });
- }
- else {
- copyStyles(/** @type {?} */ (token), false, styles);
- }
- });
- return styles;
- }
-
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes} checked by tsc
- */
- class Animation {
- /**
- * @param {?} _driver
- * @param {?} input
- */
- constructor(_driver, input) {
- this._driver = _driver;
- const /** @type {?} */ errors = [];
- const /** @type {?} */ ast = buildAnimationAst(_driver, input, errors);
- if (errors.length) {
- const /** @type {?} */ errorMessage = `animation validation failed:\n${errors.join("\n")}`;
- throw new Error(errorMessage);
- }
- this._animationAst = ast;
- }
- /**
- * @param {?} element
- * @param {?} startingStyles
- * @param {?} destinationStyles
- * @param {?} options
- * @param {?=} subInstructions
- * @return {?}
- */
- buildTimelines(element, startingStyles, destinationStyles, options, subInstructions) {
- const /** @type {?} */ start = Array.isArray(startingStyles) ? normalizeStyles(startingStyles) : /** @type {?} */ (startingStyles);
- const /** @type {?} */ dest = Array.isArray(destinationStyles) ? normalizeStyles(destinationStyles) : /** @type {?} */ (destinationStyles);
- const /** @type {?} */ errors = [];
- subInstructions = subInstructions || new ElementInstructionMap();
- const /** @type {?} */ result = buildAnimationTimelines(this._driver, element, this._animationAst, ENTER_CLASSNAME, LEAVE_CLASSNAME, start, dest, options, subInstructions, errors);
- if (errors.length) {
- const /** @type {?} */ errorMessage = `animation building failed:\n${errors.join("\n")}`;
- throw new Error(errorMessage);
- }
- return result;
- }
- }
-
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes} checked by tsc
- */
- /**
- * @license
- * Copyright Google Inc. All Rights Reserved.
- *
- * Use of this source code is governed by an MIT-style license that can be
- * found in the LICENSE file at https://angular.io/license
- */
- /**
- * \@experimental Animation support is experimental.
- * @abstract
- */
- class AnimationStyleNormalizer {
- }
- /**
- * \@experimental Animation support is experimental.
- */
- class NoopAnimationStyleNormalizer {
- /**
- * @param {?} propertyName
- * @param {?} errors
- * @return {?}
- */
- normalizePropertyName(propertyName, errors) { return propertyName; }
- /**
- * @param {?} userProvidedProperty
- * @param {?} normalizedProperty
- * @param {?} value
- * @param {?} errors
- * @return {?}
- */
- normalizeStyleValue(userProvidedProperty, normalizedProperty, value, errors) {
- return /** @type {?} */ (value);
- }
- }
-
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes} checked by tsc
- */
- class WebAnimationsStyleNormalizer extends AnimationStyleNormalizer {
- /**
- * @param {?} propertyName
- * @param {?} errors
- * @return {?}
- */
- normalizePropertyName(propertyName, errors) {
- return dashCaseToCamelCase(propertyName);
- }
- /**
- * @param {?} userProvidedProperty
- * @param {?} normalizedProperty
- * @param {?} value
- * @param {?} errors
- * @return {?}
- */
- normalizeStyleValue(userProvidedProperty, normalizedProperty, value, errors) {
- let /** @type {?} */ unit = '';
- const /** @type {?} */ strVal = value.toString().trim();
- if (DIMENSIONAL_PROP_MAP[normalizedProperty] && value !== 0 && value !== '0') {
- if (typeof value === 'number') {
- unit = 'px';
- }
- else {
- const /** @type {?} */ valAndSuffixMatch = value.match(/^[+-]?[\d\.]+([a-z]*)$/);
- if (valAndSuffixMatch && valAndSuffixMatch[1].length == 0) {
- errors.push(`Please provide a CSS unit value for ${userProvidedProperty}:${value}`);
- }
- }
- }
- return strVal + unit;
- }
- }
- const DIMENSIONAL_PROP_MAP = makeBooleanMap('width,height,minWidth,minHeight,maxWidth,maxHeight,left,top,bottom,right,fontSize,outlineWidth,outlineOffset,paddingTop,paddingLeft,paddingBottom,paddingRight,marginTop,marginLeft,marginBottom,marginRight,borderRadius,borderWidth,borderTopWidth,borderLeftWidth,borderRightWidth,borderBottomWidth,textIndent,perspective'
- .split(','));
- /**
- * @param {?} keys
- * @return {?}
- */
- function makeBooleanMap(keys) {
- const /** @type {?} */ map = {};
- keys.forEach(key => map[key] = true);
- return map;
- }
-
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes} checked by tsc
- */
- /**
- * @record
- */
-
- /**
- * @param {?} element
- * @param {?} triggerName
- * @param {?} fromState
- * @param {?} toState
- * @param {?} isRemovalTransition
- * @param {?} fromStyles
- * @param {?} toStyles
- * @param {?} timelines
- * @param {?} queriedElements
- * @param {?} preStyleProps
- * @param {?} postStyleProps
- * @param {?=} errors
- * @return {?}
- */
- function createTransitionInstruction(element, triggerName, fromState, toState, isRemovalTransition, fromStyles, toStyles, timelines, queriedElements, preStyleProps, postStyleProps, errors) {
- return {
- type: 0 /* TransitionAnimation */,
- element,
- triggerName,
- isRemovalTransition,
- fromState,
- fromStyles,
- toState,
- toStyles,
- timelines,
- queriedElements,
- preStyleProps,
- postStyleProps,
- errors
- };
- }
-
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes} checked by tsc
- */
- const EMPTY_OBJECT = {};
- class AnimationTransitionFactory {
- /**
- * @param {?} _triggerName
- * @param {?} ast
- * @param {?} _stateStyles
- */
- constructor(_triggerName, ast, _stateStyles) {
- this._triggerName = _triggerName;
- this.ast = ast;
- this._stateStyles = _stateStyles;
- }
- /**
- * @param {?} currentState
- * @param {?} nextState
- * @return {?}
- */
- match(currentState, nextState) {
- return oneOrMoreTransitionsMatch(this.ast.matchers, currentState, nextState);
- }
- /**
- * @param {?} stateName
- * @param {?} params
- * @param {?} errors
- * @return {?}
- */
- buildStyles(stateName, params, errors) {
- const /** @type {?} */ backupStateStyler = this._stateStyles['*'];
- const /** @type {?} */ stateStyler = this._stateStyles[stateName];
- const /** @type {?} */ backupStyles = backupStateStyler ? backupStateStyler.buildStyles(params, errors) : {};
- return stateStyler ? stateStyler.buildStyles(params, errors) : backupStyles;
- }
- /**
- * @param {?} driver
- * @param {?} element
- * @param {?} currentState
- * @param {?} nextState
- * @param {?} enterClassName
- * @param {?} leaveClassName
- * @param {?=} currentOptions
- * @param {?=} nextOptions
- * @param {?=} subInstructions
- * @return {?}
- */
- build(driver, element, currentState, nextState, enterClassName, leaveClassName, currentOptions, nextOptions, subInstructions) {
- const /** @type {?} */ errors = [];
- const /** @type {?} */ transitionAnimationParams = this.ast.options && this.ast.options.params || EMPTY_OBJECT;
- const /** @type {?} */ currentAnimationParams = currentOptions && currentOptions.params || EMPTY_OBJECT;
- const /** @type {?} */ currentStateStyles = this.buildStyles(currentState, currentAnimationParams, errors);
- const /** @type {?} */ nextAnimationParams = nextOptions && nextOptions.params || EMPTY_OBJECT;
- const /** @type {?} */ nextStateStyles = this.buildStyles(nextState, nextAnimationParams, errors);
- const /** @type {?} */ queriedElements = new Set();
- const /** @type {?} */ preStyleMap = new Map();
- const /** @type {?} */ postStyleMap = new Map();
- const /** @type {?} */ isRemoval = nextState === 'void';
- const /** @type {?} */ animationOptions = { params: Object.assign({}, transitionAnimationParams, nextAnimationParams) };
- const /** @type {?} */ timelines = buildAnimationTimelines(driver, element, this.ast.animation, enterClassName, leaveClassName, currentStateStyles, nextStateStyles, animationOptions, subInstructions, errors);
- if (errors.length) {
- return createTransitionInstruction(element, this._triggerName, currentState, nextState, isRemoval, currentStateStyles, nextStateStyles, [], [], preStyleMap, postStyleMap, errors);
- }
- timelines.forEach(tl => {
- const /** @type {?} */ elm = tl.element;
- const /** @type {?} */ preProps = getOrSetAsInMap(preStyleMap, elm, {});
- tl.preStyleProps.forEach(prop => preProps[prop] = true);
- const /** @type {?} */ postProps = getOrSetAsInMap(postStyleMap, elm, {});
- tl.postStyleProps.forEach(prop => postProps[prop] = true);
- if (elm !== element) {
- queriedElements.add(elm);
- }
- });
- const /** @type {?} */ queriedElementsList = iteratorToArray(queriedElements.values());
- return createTransitionInstruction(element, this._triggerName, currentState, nextState, isRemoval, currentStateStyles, nextStateStyles, timelines, queriedElementsList, preStyleMap, postStyleMap);
- }
- }
- /**
- * @param {?} matchFns
- * @param {?} currentState
- * @param {?} nextState
- * @return {?}
- */
- function oneOrMoreTransitionsMatch(matchFns, currentState, nextState) {
- return matchFns.some(fn => fn(currentState, nextState));
- }
- class AnimationStateStyles {
- /**
- * @param {?} styles
- * @param {?} defaultParams
- */
- constructor(styles, defaultParams) {
- this.styles = styles;
- this.defaultParams = defaultParams;
- }
- /**
- * @param {?} params
- * @param {?} errors
- * @return {?}
- */
- buildStyles(params, errors) {
- const /** @type {?} */ finalStyles = {};
- const /** @type {?} */ combinedParams = copyObj(this.defaultParams);
- Object.keys(params).forEach(key => {
- const /** @type {?} */ value = params[key];
- if (value != null) {
- combinedParams[key] = value;
- }
- });
- this.styles.styles.forEach(value => {
- if (typeof value !== 'string') {
- const /** @type {?} */ styleObj = /** @type {?} */ (value);
- Object.keys(styleObj).forEach(prop => {
- let /** @type {?} */ val = styleObj[prop];
- if (val.length > 1) {
- val = interpolateParams(val, combinedParams, errors);
- }
- finalStyles[prop] = val;
- });
- }
- });
- return finalStyles;
- }
- }
-
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes} checked by tsc
- */
- /**
- * \@experimental Animation support is experimental.
- * @param {?} name
- * @param {?} ast
- * @return {?}
- */
- function buildTrigger(name, ast) {
- return new AnimationTrigger(name, ast);
- }
- /**
- * \@experimental Animation support is experimental.
- */
- class AnimationTrigger {
- /**
- * @param {?} name
- * @param {?} ast
- */
- constructor(name, ast) {
- this.name = name;
- this.ast = ast;
- this.transitionFactories = [];
- this.states = {};
- ast.states.forEach(ast => {
- const /** @type {?} */ defaultParams = (ast.options && ast.options.params) || {};
- this.states[ast.name] = new AnimationStateStyles(ast.style, defaultParams);
- });
- balanceProperties(this.states, 'true', '1');
- balanceProperties(this.states, 'false', '0');
- ast.transitions.forEach(ast => {
- this.transitionFactories.push(new AnimationTransitionFactory(name, ast, this.states));
- });
- this.fallbackTransition = createFallbackTransition(name, this.states);
- }
- /**
- * @return {?}
- */
- get containsQueries() { return this.ast.queryCount > 0; }
- /**
- * @param {?} currentState
- * @param {?} nextState
- * @return {?}
- */
- matchTransition(currentState, nextState) {
- const /** @type {?} */ entry = this.transitionFactories.find(f => f.match(currentState, nextState));
- return entry || null;
- }
- /**
- * @param {?} currentState
- * @param {?} params
- * @param {?} errors
- * @return {?}
- */
- matchStyles(currentState, params, errors) {
- return this.fallbackTransition.buildStyles(currentState, params, errors);
- }
- }
- /**
- * @param {?} triggerName
- * @param {?} states
- * @return {?}
- */
- function createFallbackTransition(triggerName, states) {
- const /** @type {?} */ matchers = [(fromState, toState) => true];
- const /** @type {?} */ animation = { type: 2 /* Sequence */, steps: [], options: null };
- const /** @type {?} */ transition = {
- type: 1 /* Transition */,
- animation,
- matchers,
- options: null,
- queryCount: 0,
- depCount: 0
- };
- return new AnimationTransitionFactory(triggerName, transition, states);
- }
- /**
- * @param {?} obj
- * @param {?} key1
- * @param {?} key2
- * @return {?}
- */
- function balanceProperties(obj, key1, key2) {
- if (obj.hasOwnProperty(key1)) {
- if (!obj.hasOwnProperty(key2)) {
- obj[key2] = obj[key1];
- }
- }
- else if (obj.hasOwnProperty(key2)) {
- obj[key1] = obj[key2];
- }
- }
-
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes} checked by tsc
- */
- const EMPTY_INSTRUCTION_MAP = new ElementInstructionMap();
- class TimelineAnimationEngine {
- /**
- * @param {?} _driver
- * @param {?} _normalizer
- */
- constructor(_driver, _normalizer) {
- this._driver = _driver;
- this._normalizer = _normalizer;
- this._animations = {};
- this._playersById = {};
- this.players = [];
- }
- /**
- * @param {?} id
- * @param {?} metadata
- * @return {?}
- */
- register(id, metadata) {
- const /** @type {?} */ errors = [];
- const /** @type {?} */ ast = buildAnimationAst(this._driver, metadata, errors);
- if (errors.length) {
- throw new Error(`Unable to build the animation due to the following errors: ${errors.join("\n")}`);
- }
- else {
- this._animations[id] = ast;
- }
- }
- /**
- * @param {?} i
- * @param {?} preStyles
- * @param {?=} postStyles
- * @return {?}
- */
- _buildPlayer(i, preStyles, postStyles) {
- const /** @type {?} */ element = i.element;
- const /** @type {?} */ keyframes = normalizeKeyframes(this._driver, this._normalizer, element, i.keyframes, preStyles, postStyles);
- return this._driver.animate(element, keyframes, i.duration, i.delay, i.easing, []);
- }
- /**
- * @param {?} id
- * @param {?} element
- * @param {?=} options
- * @return {?}
- */
- create(id, element, options = {}) {
- const /** @type {?} */ errors = [];
- const /** @type {?} */ ast = this._animations[id];
- let /** @type {?} */ instructions;
- const /** @type {?} */ autoStylesMap = new Map();
- if (ast) {
- instructions = buildAnimationTimelines(this._driver, element, ast, ENTER_CLASSNAME, LEAVE_CLASSNAME, {}, {}, options, EMPTY_INSTRUCTION_MAP, errors);
- instructions.forEach(inst => {
- const /** @type {?} */ styles = getOrSetAsInMap(autoStylesMap, inst.element, {});
- inst.postStyleProps.forEach(prop => styles[prop] = null);
- });
- }
- else {
- errors.push('The requested animation doesn\'t exist or has already been destroyed');
- instructions = [];
- }
- if (errors.length) {
- throw new Error(`Unable to create the animation due to the following errors: ${errors.join("\n")}`);
- }
- autoStylesMap.forEach((styles, element) => {
- Object.keys(styles).forEach(prop => { styles[prop] = this._driver.computeStyle(element, prop, AUTO_STYLE); });
- });
- const /** @type {?} */ players = instructions.map(i => {
- const /** @type {?} */ styles = autoStylesMap.get(i.element);
- return this._buildPlayer(i, {}, styles);
- });
- const /** @type {?} */ player = optimizeGroupPlayer(players);
- this._playersById[id] = player;
- player.onDestroy(() => this.destroy(id));
- this.players.push(player);
- return player;
- }
- /**
- * @param {?} id
- * @return {?}
- */
- destroy(id) {
- const /** @type {?} */ player = this._getPlayer(id);
- player.destroy();
- delete this._playersById[id];
- const /** @type {?} */ index = this.players.indexOf(player);
- if (index >= 0) {
- this.players.splice(index, 1);
- }
- }
- /**
- * @param {?} id
- * @return {?}
- */
- _getPlayer(id) {
- const /** @type {?} */ player = this._playersById[id];
- if (!player) {
- throw new Error(`Unable to find the timeline player referenced by ${id}`);
- }
- return player;
- }
- /**
- * @param {?} id
- * @param {?} element
- * @param {?} eventName
- * @param {?} callback
- * @return {?}
- */
- listen(id, element, eventName, callback) {
- // triggerName, fromState, toState are all ignored for timeline animations
- const /** @type {?} */ baseEvent = makeAnimationEvent(element, '', '', '');
- listenOnPlayer(this._getPlayer(id), eventName, baseEvent, callback);
- return () => { };
- }
- /**
- * @param {?} id
- * @param {?} element
- * @param {?} command
- * @param {?} args
- * @return {?}
- */
- command(id, element, command, args) {
- if (command == 'register') {
- this.register(id, /** @type {?} */ (args[0]));
- return;
- }
- if (command == 'create') {
- const /** @type {?} */ options = /** @type {?} */ ((args[0] || {}));
- this.create(id, element, options);
- return;
- }
- const /** @type {?} */ player = this._getPlayer(id);
- switch (command) {
- case 'play':
- player.play();
- break;
- case 'pause':
- player.pause();
- break;
- case 'reset':
- player.reset();
- break;
- case 'restart':
- player.restart();
- break;
- case 'finish':
- player.finish();
- break;
- case 'init':
- player.init();
- break;
- case 'setPosition':
- player.setPosition(parseFloat(/** @type {?} */ (args[0])));
- break;
- case 'destroy':
- this.destroy(id);
- break;
- }
- }
- }
-
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes} checked by tsc
- */
- const QUEUED_CLASSNAME = 'ng-animate-queued';
- const QUEUED_SELECTOR = '.ng-animate-queued';
- const DISABLED_CLASSNAME = 'ng-animate-disabled';
- const DISABLED_SELECTOR = '.ng-animate-disabled';
- const STAR_CLASSNAME = 'ng-star-inserted';
- const STAR_SELECTOR = '.ng-star-inserted';
- const EMPTY_PLAYER_ARRAY = [];
- const NULL_REMOVAL_STATE = {
- namespaceId: '',
- setForRemoval: null,
- hasAnimation: false,
- removedBeforeQueried: false
- };
- const NULL_REMOVED_QUERIED_STATE = {
- namespaceId: '',
- setForRemoval: null,
- hasAnimation: false,
- removedBeforeQueried: true
- };
- /**
- * @record
- */
-
- const REMOVAL_FLAG = '__ng_removed';
- /**
- * @record
- */
-
- class StateValue {
- /**
- * @param {?} input
- * @param {?=} namespaceId
- */
- constructor(input, namespaceId = '') {
- this.namespaceId = namespaceId;
- const /** @type {?} */ isObj = input && input.hasOwnProperty('value');
- const /** @type {?} */ value = isObj ? input['value'] : input;
- this.value = normalizeTriggerValue(value);
- if (isObj) {
- const /** @type {?} */ options = copyObj(/** @type {?} */ (input));
- delete options['value'];
- this.options = /** @type {?} */ (options);
- }
- else {
- this.options = {};
- }
- if (!this.options.params) {
- this.options.params = {};
- }
- }
- /**
- * @return {?}
- */
- get params() { return /** @type {?} */ (this.options.params); }
- /**
- * @param {?} options
- * @return {?}
- */
- absorbOptions(options) {
- const /** @type {?} */ newParams = options.params;
- if (newParams) {
- const /** @type {?} */ oldParams = /** @type {?} */ ((this.options.params));
- Object.keys(newParams).forEach(prop => {
- if (oldParams[prop] == null) {
- oldParams[prop] = newParams[prop];
- }
- });
- }
- }
- }
- const VOID_VALUE = 'void';
- const DEFAULT_STATE_VALUE = new StateValue(VOID_VALUE);
- const DELETED_STATE_VALUE = new StateValue('DELETED');
- class AnimationTransitionNamespace {
- /**
- * @param {?} id
- * @param {?} hostElement
- * @param {?} _engine
- */
- constructor(id, hostElement, _engine) {
- this.id = id;
- this.hostElement = hostElement;
- this._engine = _engine;
- this.players = [];
- this._triggers = {};
- this._queue = [];
- this._elementListeners = new Map();
- this._hostClassName = 'ng-tns-' + id;
- addClass(hostElement, this._hostClassName);
- }
- /**
- * @param {?} element
- * @param {?} name
- * @param {?} phase
- * @param {?} callback
- * @return {?}
- */
- listen(element, name, phase, callback) {
- if (!this._triggers.hasOwnProperty(name)) {
- throw new Error(`Unable to listen on the animation trigger event "${phase}" because the animation trigger "${name}" doesn\'t exist!`);
- }
- if (phase == null || phase.length == 0) {
- throw new Error(`Unable to listen on the animation trigger "${name}" because the provided event is undefined!`);
- }
- if (!isTriggerEventValid(phase)) {
- throw new Error(`The provided animation trigger event "${phase}" for the animation trigger "${name}" is not supported!`);
- }
- const /** @type {?} */ listeners = getOrSetAsInMap(this._elementListeners, element, []);
- const /** @type {?} */ data = { name, phase, callback };
- listeners.push(data);
- const /** @type {?} */ triggersWithStates = getOrSetAsInMap(this._engine.statesByElement, element, {});
- if (!triggersWithStates.hasOwnProperty(name)) {
- addClass(element, NG_TRIGGER_CLASSNAME);
- addClass(element, NG_TRIGGER_CLASSNAME + '-' + name);
- triggersWithStates[name] = DEFAULT_STATE_VALUE;
- }
- return () => {
- // the event listener is removed AFTER the flush has occurred such
- // that leave animations callbacks can fire (otherwise if the node
- // is removed in between then the listeners would be deregistered)
- this._engine.afterFlush(() => {
- const /** @type {?} */ index = listeners.indexOf(data);
- if (index >= 0) {
- listeners.splice(index, 1);
- }
- if (!this._triggers[name]) {
- delete triggersWithStates[name];
- }
- });
- };
- }
- /**
- * @param {?} name
- * @param {?} ast
- * @return {?}
- */
- register(name, ast) {
- if (this._triggers[name]) {
- // throw
- return false;
- }
- else {
- this._triggers[name] = ast;
- return true;
- }
- }
- /**
- * @param {?} name
- * @return {?}
- */
- _getTrigger(name) {
- const /** @type {?} */ trigger = this._triggers[name];
- if (!trigger) {
- throw new Error(`The provided animation trigger "${name}" has not been registered!`);
- }
- return trigger;
- }
- /**
- * @param {?} element
- * @param {?} triggerName
- * @param {?} value
- * @param {?=} defaultToFallback
- * @return {?}
- */
- trigger(element, triggerName, value, defaultToFallback = true) {
- const /** @type {?} */ trigger = this._getTrigger(triggerName);
- const /** @type {?} */ player = new TransitionAnimationPlayer(this.id, triggerName, element);
- let /** @type {?} */ triggersWithStates = this._engine.statesByElement.get(element);
- if (!triggersWithStates) {
- addClass(element, NG_TRIGGER_CLASSNAME);
- addClass(element, NG_TRIGGER_CLASSNAME + '-' + triggerName);
- this._engine.statesByElement.set(element, triggersWithStates = {});
- }
- let /** @type {?} */ fromState = triggersWithStates[triggerName];
- const /** @type {?} */ toState = new StateValue(value, this.id);
- const /** @type {?} */ isObj = value && value.hasOwnProperty('value');
- if (!isObj && fromState) {
- toState.absorbOptions(fromState.options);
- }
- triggersWithStates[triggerName] = toState;
- if (!fromState) {
- fromState = DEFAULT_STATE_VALUE;
- }
- else if (fromState === DELETED_STATE_VALUE) {
- return player;
- }
- const /** @type {?} */ isRemoval = toState.value === VOID_VALUE;
- // normally this isn't reached by here, however, if an object expression
- // is passed in then it may be a new object each time. Comparing the value
- // is important since that will stay the same despite there being a new object.
- // The removal arc here is special cased because the same element is triggered
- // twice in the event that it contains animations on the outer/inner portions
- // of the host container
- if (!isRemoval && fromState.value === toState.value) {
- // this means that despite the value not changing, some inner params
- // have changed which means that the animation final styles need to be applied
- if (!objEquals(fromState.params, toState.params)) {
- const /** @type {?} */ errors = [];
- const /** @type {?} */ fromStyles = trigger.matchStyles(fromState.value, fromState.params, errors);
- const /** @type {?} */ toStyles = trigger.matchStyles(toState.value, toState.params, errors);
- if (errors.length) {
- this._engine.reportError(errors);
- }
- else {
- this._engine.afterFlush(() => {
- eraseStyles(element, fromStyles);
- setStyles(element, toStyles);
- });
- }
- }
- return;
- }
- const /** @type {?} */ playersOnElement = getOrSetAsInMap(this._engine.playersByElement, element, []);
- playersOnElement.forEach(player => {
- // only remove the player if it is queued on the EXACT same trigger/namespace
- // we only also deal with queued players here because if the animation has
- // started then we want to keep the player alive until the flush happens
- // (which is where the previousPlayers are passed into the new palyer)
- if (player.namespaceId == this.id && player.triggerName == triggerName && player.queued) {
- player.destroy();
- }
- });
- let /** @type {?} */ transition = trigger.matchTransition(fromState.value, toState.value);
- let /** @type {?} */ isFallbackTransition = false;
- if (!transition) {
- if (!defaultToFallback)
- return;
- transition = trigger.fallbackTransition;
- isFallbackTransition = true;
- }
- this._engine.totalQueuedPlayers++;
- this._queue.push({ element, triggerName, transition, fromState, toState, player, isFallbackTransition });
- if (!isFallbackTransition) {
- addClass(element, QUEUED_CLASSNAME);
- player.onStart(() => { removeClass(element, QUEUED_CLASSNAME); });
- }
- player.onDone(() => {
- let /** @type {?} */ index = this.players.indexOf(player);
- if (index >= 0) {
- this.players.splice(index, 1);
- }
- const /** @type {?} */ players = this._engine.playersByElement.get(element);
- if (players) {
- let /** @type {?} */ index = players.indexOf(player);
- if (index >= 0) {
- players.splice(index, 1);
- }
- }
- });
- this.players.push(player);
- playersOnElement.push(player);
- return player;
- }
- /**
- * @param {?} name
- * @return {?}
- */
- deregister(name) {
- delete this._triggers[name];
- this._engine.statesByElement.forEach((stateMap, element) => { delete stateMap[name]; });
- this._elementListeners.forEach((listeners, element) => {
- this._elementListeners.set(element, listeners.filter(entry => { return entry.name != name; }));
- });
- }
- /**
- * @param {?} element
- * @return {?}
- */
- clearElementCache(element) {
- this._engine.statesByElement.delete(element);
- this._elementListeners.delete(element);
- const /** @type {?} */ elementPlayers = this._engine.playersByElement.get(element);
- if (elementPlayers) {
- elementPlayers.forEach(player => player.destroy());
- this._engine.playersByElement.delete(element);
- }
- }
- /**
- * @param {?} rootElement
- * @param {?} context
- * @param {?=} animate
- * @return {?}
- */
- _signalRemovalForInnerTriggers(rootElement, context, animate = false) {
- // emulate a leave animation for all inner nodes within this node.
- // If there are no animations found for any of the nodes then clear the cache
- // for the element.
- this._engine.driver.query(rootElement, NG_TRIGGER_SELECTOR, true).forEach(elm => {
- // this means that an inner remove() operation has already kicked off
- // the animation on this element...
- if (elm[REMOVAL_FLAG])
- return;
- const /** @type {?} */ namespaces = this._engine.fetchNamespacesByElement(elm);
- if (namespaces.size) {
- namespaces.forEach(ns => ns.triggerLeaveAnimation(elm, context, false, true));
- }
- else {
- this.clearElementCache(elm);
- }
- });
- }
- /**
- * @param {?} element
- * @param {?} context
- * @param {?=} destroyAfterComplete
- * @param {?=} defaultToFallback
- * @return {?}
- */
- triggerLeaveAnimation(element, context, destroyAfterComplete, defaultToFallback) {
- const /** @type {?} */ triggerStates = this._engine.statesByElement.get(element);
- if (triggerStates) {
- const /** @type {?} */ players = [];
- Object.keys(triggerStates).forEach(triggerName => {
- // this check is here in the event that an element is removed
- // twice (both on the host level and the component level)
- if (this._triggers[triggerName]) {
- const /** @type {?} */ player = this.trigger(element, triggerName, VOID_VALUE, defaultToFallback);
- if (player) {
- players.push(player);
- }
- }
- });
- if (players.length) {
- this._engine.markElementAsRemoved(this.id, element, true, context);
- if (destroyAfterComplete) {
- optimizeGroupPlayer(players).onDone(() => this._engine.processLeaveNode(element));
- }
- return true;
- }
- }
- return false;
- }
- /**
- * @param {?} element
- * @return {?}
- */
- prepareLeaveAnimationListeners(element) {
- const /** @type {?} */ listeners = this._elementListeners.get(element);
- if (listeners) {
- const /** @type {?} */ visitedTriggers = new Set();
- listeners.forEach(listener => {
- const /** @type {?} */ triggerName = listener.name;
- if (visitedTriggers.has(triggerName))
- return;
- visitedTriggers.add(triggerName);
- const /** @type {?} */ trigger = this._triggers[triggerName];
- const /** @type {?} */ transition = trigger.fallbackTransition;
- const /** @type {?} */ elementStates = /** @type {?} */ ((this._engine.statesByElement.get(element)));
- const /** @type {?} */ fromState = elementStates[triggerName] || DEFAULT_STATE_VALUE;
- const /** @type {?} */ toState = new StateValue(VOID_VALUE);
- const /** @type {?} */ player = new TransitionAnimationPlayer(this.id, triggerName, element);
- this._engine.totalQueuedPlayers++;
- this._queue.push({
- element,
- triggerName,
- transition,
- fromState,
- toState,
- player,
- isFallbackTransition: true
- });
- });
- }
- }
- /**
- * @param {?} element
- * @param {?} context
- * @return {?}
- */
- removeNode(element, context) {
- const /** @type {?} */ engine = this._engine;
- if (element.childElementCount) {
- this._signalRemovalForInnerTriggers(element, context, true);
- }
- // this means that a * => VOID animation was detected and kicked off
- if (this.triggerLeaveAnimation(element, context, true))
- return;
- // find the player that is animating and make sure that the
- // removal is delayed until that player has completed
- let /** @type {?} */ containsPotentialParentTransition = false;
- if (engine.totalAnimations) {
- const /** @type {?} */ currentPlayers = engine.players.length ? engine.playersByQueriedElement.get(element) : [];
- // when this `if statement` does not continue forward it means that
- // a previous animation query has selected the current element and
- // is animating it. In this situation want to continue fowards and
- // allow the element to be queued up for animation later.
- if (currentPlayers && currentPlayers.length) {
- containsPotentialParentTransition = true;
- }
- else {
- let /** @type {?} */ parent = element;
- while (parent = parent.parentNode) {
- const /** @type {?} */ triggers = engine.statesByElement.get(parent);
- if (triggers) {
- containsPotentialParentTransition = true;
- break;
- }
- }
- }
- }
- // at this stage we know that the element will either get removed
- // during flush or will be picked up by a parent query. Either way
- // we need to fire the listeners for this element when it DOES get
- // removed (once the query parent animation is done or after flush)
- this.prepareLeaveAnimationListeners(element);
- // whether or not a parent has an animation we need to delay the deferral of the leave
- // operation until we have more information (which we do after flush() has been called)
- if (containsPotentialParentTransition) {
- engine.markElementAsRemoved(this.id, element, false, context);
- }
- else {
- // we do this after the flush has occurred such
- // that the callbacks can be fired
- engine.afterFlush(() => this.clearElementCache(element));
- engine.destroyInnerAnimations(element);
- engine._onRemovalComplete(element, context);
- }
- }
- /**
- * @param {?} element
- * @param {?} parent
- * @return {?}
- */
- insertNode(element, parent) { addClass(element, this._hostClassName); }
- /**
- * @param {?} microtaskId
- * @return {?}
- */
- drainQueuedTransitions(microtaskId) {
- const /** @type {?} */ instructions = [];
- this._queue.forEach(entry => {
- const /** @type {?} */ player = entry.player;
- if (player.destroyed)
- return;
- const /** @type {?} */ element = entry.element;
- const /** @type {?} */ listeners = this._elementListeners.get(element);
- if (listeners) {
- listeners.forEach((listener) => {
- if (listener.name == entry.triggerName) {
- const /** @type {?} */ baseEvent = makeAnimationEvent(element, entry.triggerName, entry.fromState.value, entry.toState.value);
- (/** @type {?} */ (baseEvent))['_data'] = microtaskId;
- listenOnPlayer(entry.player, listener.phase, baseEvent, listener.callback);
- }
- });
- }
- if (player.markedForDestroy) {
- this._engine.afterFlush(() => {
- // now we can destroy the element properly since the event listeners have
- // been bound to the player
- player.destroy();
- });
- }
- else {
- instructions.push(entry);
- }
- });
- this._queue = [];
- return instructions.sort((a, b) => {
- // if depCount == 0 them move to front
- // otherwise if a contains b then move back
- const /** @type {?} */ d0 = a.transition.ast.depCount;
- const /** @type {?} */ d1 = b.transition.ast.depCount;
- if (d0 == 0 || d1 == 0) {
- return d0 - d1;
- }
- return this._engine.driver.containsElement(a.element, b.element) ? 1 : -1;
- });
- }
- /**
- * @param {?} context
- * @return {?}
- */
- destroy(context) {
- this.players.forEach(p => p.destroy());
- this._signalRemovalForInnerTriggers(this.hostElement, context);
- }
- /**
- * @param {?} element
- * @return {?}
- */
- elementContainsData(element) {
- let /** @type {?} */ containsData = false;
- if (this._elementListeners.has(element))
- containsData = true;
- containsData =
- (this._queue.find(entry => entry.element === element) ? true : false) || containsData;
- return containsData;
- }
- }
- /**
- * @record
- */
-
- class TransitionAnimationEngine {
- /**
- * @param {?} driver
- * @param {?} _normalizer
- */
- constructor(driver, _normalizer) {
- this.driver = driver;
- this._normalizer = _normalizer;
- this.players = [];
- this.newHostElements = new Map();
- this.playersByElement = new Map();
- this.playersByQueriedElement = new Map();
- this.statesByElement = new Map();
- this.disabledNodes = new Set();
- this.totalAnimations = 0;
- this.totalQueuedPlayers = 0;
- this._namespaceLookup = {};
- this._namespaceList = [];
- this._flushFns = [];
- this._whenQuietFns = [];
- this.namespacesByHostElement = new Map();
- this.collectedEnterElements = [];
- this.collectedLeaveElements = [];
- this.onRemovalComplete = (element, context) => { };
- }
- /**
- * \@internal
- * @param {?} element
- * @param {?} context
- * @return {?}
- */
- _onRemovalComplete(element, context) { this.onRemovalComplete(element, context); }
- /**
- * @return {?}
- */
- get queuedPlayers() {
- const /** @type {?} */ players = [];
- this._namespaceList.forEach(ns => {
- ns.players.forEach(player => {
- if (player.queued) {
- players.push(player);
- }
- });
- });
- return players;
- }
- /**
- * @param {?} namespaceId
- * @param {?} hostElement
- * @return {?}
- */
- createNamespace(namespaceId, hostElement) {
- const /** @type {?} */ ns = new AnimationTransitionNamespace(namespaceId, hostElement, this);
- if (hostElement.parentNode) {
- this._balanceNamespaceList(ns, hostElement);
- }
- else {
- // defer this later until flush during when the host element has
- // been inserted so that we know exactly where to place it in
- // the namespace list
- this.newHostElements.set(hostElement, ns);
- // given that this host element is apart of the animation code, it
- // may or may not be inserted by a parent node that is an of an
- // animation renderer type. If this happens then we can still have
- // access to this item when we query for :enter nodes. If the parent
- // is a renderer then the set data-structure will normalize the entry
- this.collectEnterElement(hostElement);
- }
- return this._namespaceLookup[namespaceId] = ns;
- }
- /**
- * @param {?} ns
- * @param {?} hostElement
- * @return {?}
- */
- _balanceNamespaceList(ns, hostElement) {
- const /** @type {?} */ limit = this._namespaceList.length - 1;
- if (limit >= 0) {
- let /** @type {?} */ found = false;
- for (let /** @type {?} */ i = limit; i >= 0; i--) {
- const /** @type {?} */ nextNamespace = this._namespaceList[i];
- if (this.driver.containsElement(nextNamespace.hostElement, hostElement)) {
- this._namespaceList.splice(i + 1, 0, ns);
- found = true;
- break;
- }
- }
- if (!found) {
- this._namespaceList.splice(0, 0, ns);
- }
- }
- else {
- this._namespaceList.push(ns);
- }
- this.namespacesByHostElement.set(hostElement, ns);
- return ns;
- }
- /**
- * @param {?} namespaceId
- * @param {?} hostElement
- * @return {?}
- */
- register(namespaceId, hostElement) {
- let /** @type {?} */ ns = this._namespaceLookup[namespaceId];
- if (!ns) {
- ns = this.createNamespace(namespaceId, hostElement);
- }
- return ns;
- }
- /**
- * @param {?} namespaceId
- * @param {?} name
- * @param {?} trigger
- * @return {?}
- */
- registerTrigger(namespaceId, name, trigger) {
- let /** @type {?} */ ns = this._namespaceLookup[namespaceId];
- if (ns && ns.register(name, trigger)) {
- this.totalAnimations++;
- }
- }
- /**
- * @param {?} namespaceId
- * @param {?} context
- * @return {?}
- */
- destroy(namespaceId, context) {
- if (!namespaceId)
- return;
- const /** @type {?} */ ns = this._fetchNamespace(namespaceId);
- this.afterFlush(() => {
- this.namespacesByHostElement.delete(ns.hostElement);
- delete this._namespaceLookup[namespaceId];
- const /** @type {?} */ index = this._namespaceList.indexOf(ns);
- if (index >= 0) {
- this._namespaceList.splice(index, 1);
- }
- });
- this.afterFlushAnimationsDone(() => ns.destroy(context));
- }
- /**
- * @param {?} id
- * @return {?}
- */
- _fetchNamespace(id) { return this._namespaceLookup[id]; }
- /**
- * @param {?} element
- * @return {?}
- */
- fetchNamespacesByElement(element) {
- // normally there should only be one namespace per element, however
- // if @triggers are placed on both the component element and then
- // its host element (within the component code) then there will be
- // two namespaces returned. We use a set here to simply the dedupe
- // of namespaces incase there are multiple triggers both the elm and host
- const /** @type {?} */ namespaces = new Set();
- const /** @type {?} */ elementStates = this.statesByElement.get(element);
- if (elementStates) {
- const /** @type {?} */ keys = Object.keys(elementStates);
- for (let /** @type {?} */ i = 0; i < keys.length; i++) {
- const /** @type {?} */ nsId = elementStates[keys[i]].namespaceId;
- if (nsId) {
- const /** @type {?} */ ns = this._fetchNamespace(nsId);
- if (ns) {
- namespaces.add(ns);
- }
- }
- }
- }
- return namespaces;
- }
- /**
- * @param {?} namespaceId
- * @param {?} element
- * @param {?} name
- * @param {?} value
- * @return {?}
- */
- trigger(namespaceId, element, name, value) {
- if (isElementNode(element)) {
- this._fetchNamespace(namespaceId).trigger(element, name, value);
- return true;
- }
- return false;
- }
- /**
- * @param {?} namespaceId
- * @param {?} element
- * @param {?} parent
- * @param {?} insertBefore
- * @return {?}
- */
- insertNode(namespaceId, element, parent, insertBefore) {
- if (!isElementNode(element))
- return;
- // special case for when an element is removed and reinserted (move operation)
- // when this occurs we do not want to use the element for deletion later
- const /** @type {?} */ details = /** @type {?} */ (element[REMOVAL_FLAG]);
- if (details && details.setForRemoval) {
- details.setForRemoval = false;
- }
- // in the event that the namespaceId is blank then the caller
- // code does not contain any animation code in it, but it is
- // just being called so that the node is marked as being inserted
- if (namespaceId) {
- const /** @type {?} */ ns = this._fetchNamespace(namespaceId);
- // This if-statement is a workaround for router issue #21947.
- // The router sometimes hits a race condition where while a route
- // is being instantiated a new navigation arrives, triggering leave
- // animation of DOM that has not been fully initialized, until this
- // is resolved, we need to handle the scenario when DOM is not in a
- // consistent state during the animation.
- if (ns) {
- ns.insertNode(element, parent);
- }
- }
- // only *directives and host elements are inserted before
- if (insertBefore) {
- this.collectEnterElement(element);
- }
- }
- /**
- * @param {?} element
- * @return {?}
- */
- collectEnterElement(element) { this.collectedEnterElements.push(element); }
- /**
- * @param {?} element
- * @param {?} value
- * @return {?}
- */
- markElementAsDisabled(element, value) {
- if (value) {
- if (!this.disabledNodes.has(element)) {
- this.disabledNodes.add(element);
- addClass(element, DISABLED_CLASSNAME);
- }
- }
- else if (this.disabledNodes.has(element)) {
- this.disabledNodes.delete(element);
- removeClass(element, DISABLED_CLASSNAME);
- }
- }
- /**
- * @param {?} namespaceId
- * @param {?} element
- * @param {?} context
- * @return {?}
- */
- removeNode(namespaceId, element, context) {
- if (!isElementNode(element)) {
- this._onRemovalComplete(element, context);
- return;
- }
- const /** @type {?} */ ns = namespaceId ? this._fetchNamespace(namespaceId) : null;
- if (ns) {
- ns.removeNode(element, context);
- }
- else {
- this.markElementAsRemoved(namespaceId, element, false, context);
- }
- }
- /**
- * @param {?} namespaceId
- * @param {?} element
- * @param {?=} hasAnimation
- * @param {?=} context
- * @return {?}
- */
- markElementAsRemoved(namespaceId, element, hasAnimation, context) {
- this.collectedLeaveElements.push(element);
- element[REMOVAL_FLAG] = {
- namespaceId,
- setForRemoval: context, hasAnimation,
- removedBeforeQueried: false
- };
- }
- /**
- * @param {?} namespaceId
- * @param {?} element
- * @param {?} name
- * @param {?} phase
- * @param {?} callback
- * @return {?}
- */
- listen(namespaceId, element, name, phase, callback) {
- if (isElementNode(element)) {
- return this._fetchNamespace(namespaceId).listen(element, name, phase, callback);
- }
- return () => { };
- }
- /**
- * @param {?} entry
- * @param {?} subTimelines
- * @param {?} enterClassName
- * @param {?} leaveClassName
- * @return {?}
- */
- _buildInstruction(entry, subTimelines, enterClassName, leaveClassName) {
- return entry.transition.build(this.driver, entry.element, entry.fromState.value, entry.toState.value, enterClassName, leaveClassName, entry.fromState.options, entry.toState.options, subTimelines);
- }
- /**
- * @param {?} containerElement
- * @return {?}
- */
- destroyInnerAnimations(containerElement) {
- let /** @type {?} */ elements = this.driver.query(containerElement, NG_TRIGGER_SELECTOR, true);
- elements.forEach(element => this.destroyActiveAnimationsForElement(element));
- if (this.playersByQueriedElement.size == 0)
- return;
- elements = this.driver.query(containerElement, NG_ANIMATING_SELECTOR, true);
- elements.forEach(element => this.finishActiveQueriedAnimationOnElement(element));
- }
- /**
- * @param {?} element
- * @return {?}
- */
- destroyActiveAnimationsForElement(element) {
- const /** @type {?} */ players = this.playersByElement.get(element);
- if (players) {
- players.forEach(player => {
- // special case for when an element is set for destruction, but hasn't started.
- // in this situation we want to delay the destruction until the flush occurs
- // so that any event listeners attached to the player are triggered.
- if (player.queued) {
- player.markedForDestroy = true;
- }
- else {
- player.destroy();
- }
- });
- }
- const /** @type {?} */ stateMap = this.statesByElement.get(element);
- if (stateMap) {
- Object.keys(stateMap).forEach(triggerName => stateMap[triggerName] = DELETED_STATE_VALUE);
- }
- }
- /**
- * @param {?} element
- * @return {?}
- */
- finishActiveQueriedAnimationOnElement(element) {
- const /** @type {?} */ players = this.playersByQueriedElement.get(element);
- if (players) {
- players.forEach(player => player.finish());
- }
- }
- /**
- * @return {?}
- */
- whenRenderingDone() {
- return new Promise(resolve => {
- if (this.players.length) {
- return optimizeGroupPlayer(this.players).onDone(() => resolve());
- }
- else {
- resolve();
- }
- });
- }
- /**
- * @param {?} element
- * @return {?}
- */
- processLeaveNode(element) {
- const /** @type {?} */ details = /** @type {?} */ (element[REMOVAL_FLAG]);
- if (details && details.setForRemoval) {
- // this will prevent it from removing it twice
- element[REMOVAL_FLAG] = NULL_REMOVAL_STATE;
- if (details.namespaceId) {
- this.destroyInnerAnimations(element);
- const /** @type {?} */ ns = this._fetchNamespace(details.namespaceId);
- if (ns) {
- ns.clearElementCache(element);
- }
- }
- this._onRemovalComplete(element, details.setForRemoval);
- }
- if (this.driver.matchesElement(element, DISABLED_SELECTOR)) {
- this.markElementAsDisabled(element, false);
- }
- this.driver.query(element, DISABLED_SELECTOR, true).forEach(node => {
- this.markElementAsDisabled(element, false);
- });
- }
- /**
- * @param {?=} microtaskId
- * @return {?}
- */
- flush(microtaskId = -1) {
- let /** @type {?} */ players = [];
- if (this.newHostElements.size) {
- this.newHostElements.forEach((ns, element) => this._balanceNamespaceList(ns, element));
- this.newHostElements.clear();
- }
- if (this.totalAnimations && this.collectedEnterElements.length) {
- for (let /** @type {?} */ i = 0; i < this.collectedEnterElements.length; i++) {
- const /** @type {?} */ elm = this.collectedEnterElements[i];
- addClass(elm, STAR_CLASSNAME);
- }
- }
- if (this._namespaceList.length &&
- (this.totalQueuedPlayers || this.collectedLeaveElements.length)) {
- const /** @type {?} */ cleanupFns = [];
- try {
- players = this._flushAnimations(cleanupFns, microtaskId);
- }
- finally {
- for (let /** @type {?} */ i = 0; i < cleanupFns.length; i++) {
- cleanupFns[i]();
- }
- }
- }
- else {
- for (let /** @type {?} */ i = 0; i < this.collectedLeaveElements.length; i++) {
- const /** @type {?} */ element = this.collectedLeaveElements[i];
- this.processLeaveNode(element);
- }
- }
- this.totalQueuedPlayers = 0;
- this.collectedEnterElements.length = 0;
- this.collectedLeaveElements.length = 0;
- this._flushFns.forEach(fn => fn());
- this._flushFns = [];
- if (this._whenQuietFns.length) {
- // we move these over to a variable so that
- // if any new callbacks are registered in another
- // flush they do not populate the existing set
- const /** @type {?} */ quietFns = this._whenQuietFns;
- this._whenQuietFns = [];
- if (players.length) {
- optimizeGroupPlayer(players).onDone(() => { quietFns.forEach(fn => fn()); });
- }
- else {
- quietFns.forEach(fn => fn());
- }
- }
- }
- /**
- * @param {?} errors
- * @return {?}
- */
- reportError(errors) {
- throw new Error(`Unable to process animations due to the following failed trigger transitions\n ${errors.join('\n')}`);
- }
- /**
- * @param {?} cleanupFns
- * @param {?} microtaskId
- * @return {?}
- */
- _flushAnimations(cleanupFns, microtaskId) {
- const /** @type {?} */ subTimelines = new ElementInstructionMap();
- const /** @type {?} */ skippedPlayers = [];
- const /** @type {?} */ skippedPlayersMap = new Map();
- const /** @type {?} */ queuedInstructions = [];
- const /** @type {?} */ queriedElements = new Map();
- const /** @type {?} */ allPreStyleElements = new Map();
- const /** @type {?} */ allPostStyleElements = new Map();
- const /** @type {?} */ disabledElementsSet = new Set();
- this.disabledNodes.forEach(node => {
- disabledElementsSet.add(node);
- const /** @type {?} */ nodesThatAreDisabled = this.driver.query(node, QUEUED_SELECTOR, true);
- for (let /** @type {?} */ i = 0; i < nodesThatAreDisabled.length; i++) {
- disabledElementsSet.add(nodesThatAreDisabled[i]);
- }
- });
- const /** @type {?} */ bodyNode = getBodyNode();
- const /** @type {?} */ allTriggerElements = Array.from(this.statesByElement.keys());
- const /** @type {?} */ enterNodeMap = buildRootMap(allTriggerElements, this.collectedEnterElements);
- // this must occur before the instructions are built below such that
- // the :enter queries match the elements (since the timeline queries
- // are fired during instruction building).
- const /** @type {?} */ enterNodeMapIds = new Map();
- let /** @type {?} */ i = 0;
- enterNodeMap.forEach((nodes, root) => {
- const /** @type {?} */ className = ENTER_CLASSNAME + i++;
- enterNodeMapIds.set(root, className);
- nodes.forEach(node => addClass(node, className));
- });
- const /** @type {?} */ allLeaveNodes = [];
- const /** @type {?} */ mergedLeaveNodes = new Set();
- const /** @type {?} */ leaveNodesWithoutAnimations = new Set();
- for (let /** @type {?} */ i = 0; i < this.collectedLeaveElements.length; i++) {
- const /** @type {?} */ element = this.collectedLeaveElements[i];
- const /** @type {?} */ details = /** @type {?} */ (element[REMOVAL_FLAG]);
- if (details && details.setForRemoval) {
- allLeaveNodes.push(element);
- mergedLeaveNodes.add(element);
- if (details.hasAnimation) {
- this.driver.query(element, STAR_SELECTOR, true).forEach(elm => mergedLeaveNodes.add(elm));
- }
- else {
- leaveNodesWithoutAnimations.add(element);
- }
- }
- }
- const /** @type {?} */ leaveNodeMapIds = new Map();
- const /** @type {?} */ leaveNodeMap = buildRootMap(allTriggerElements, Array.from(mergedLeaveNodes));
- leaveNodeMap.forEach((nodes, root) => {
- const /** @type {?} */ className = LEAVE_CLASSNAME + i++;
- leaveNodeMapIds.set(root, className);
- nodes.forEach(node => addClass(node, className));
- });
- cleanupFns.push(() => {
- enterNodeMap.forEach((nodes, root) => {
- const /** @type {?} */ className = /** @type {?} */ ((enterNodeMapIds.get(root)));
- nodes.forEach(node => removeClass(node, className));
- });
- leaveNodeMap.forEach((nodes, root) => {
- const /** @type {?} */ className = /** @type {?} */ ((leaveNodeMapIds.get(root)));
- nodes.forEach(node => removeClass(node, className));
- });
- allLeaveNodes.forEach(element => { this.processLeaveNode(element); });
- });
- const /** @type {?} */ allPlayers = [];
- const /** @type {?} */ erroneousTransitions = [];
- for (let /** @type {?} */ i = this._namespaceList.length - 1; i >= 0; i--) {
- const /** @type {?} */ ns = this._namespaceList[i];
- ns.drainQueuedTransitions(microtaskId).forEach(entry => {
- const /** @type {?} */ player = entry.player;
- allPlayers.push(player);
- const /** @type {?} */ element = entry.element;
- if (!bodyNode || !this.driver.containsElement(bodyNode, element)) {
- player.destroy();
- return;
- }
- const /** @type {?} */ leaveClassName = /** @type {?} */ ((leaveNodeMapIds.get(element)));
- const /** @type {?} */ enterClassName = /** @type {?} */ ((enterNodeMapIds.get(element)));
- const /** @type {?} */ instruction = /** @type {?} */ ((this._buildInstruction(entry, subTimelines, enterClassName, leaveClassName)));
- if (instruction.errors && instruction.errors.length) {
- erroneousTransitions.push(instruction);
- return;
- }
- // if a unmatched transition is queued to go then it SHOULD NOT render
- // an animation and cancel the previously running animations.
- if (entry.isFallbackTransition) {
- player.onStart(() => eraseStyles(element, instruction.fromStyles));
- player.onDestroy(() => setStyles(element, instruction.toStyles));
- skippedPlayers.push(player);
- return;
- }
- // this means that if a parent animation uses this animation as a sub trigger
- // then it will instruct the timeline builder to not add a player delay, but
- // instead stretch the first keyframe gap up until the animation starts. The
- // reason this is important is to prevent extra initialization styles from being
- // required by the user in the animation.
- instruction.timelines.forEach(tl => tl.stretchStartingKeyframe = true);
- subTimelines.append(element, instruction.timelines);
- const /** @type {?} */ tuple = { instruction, player, element };
- queuedInstructions.push(tuple);
- instruction.queriedElements.forEach(element => getOrSetAsInMap(queriedElements, element, []).push(player));
- instruction.preStyleProps.forEach((stringMap, element) => {
- const /** @type {?} */ props = Object.keys(stringMap);
- if (props.length) {
- let /** @type {?} */ setVal = /** @type {?} */ ((allPreStyleElements.get(element)));
- if (!setVal) {
- allPreStyleElements.set(element, setVal = new Set());
- }
- props.forEach(prop => setVal.add(prop));
- }
- });
- instruction.postStyleProps.forEach((stringMap, element) => {
- const /** @type {?} */ props = Object.keys(stringMap);
- let /** @type {?} */ setVal = /** @type {?} */ ((allPostStyleElements.get(element)));
- if (!setVal) {
- allPostStyleElements.set(element, setVal = new Set());
- }
- props.forEach(prop => setVal.add(prop));
- });
- });
- }
- if (erroneousTransitions.length) {
- const /** @type {?} */ errors = [];
- erroneousTransitions.forEach(instruction => {
- errors.push(`@${instruction.triggerName} has failed due to:\n`); /** @type {?} */
- ((instruction.errors)).forEach(error => errors.push(`- ${error}\n`));
- });
- allPlayers.forEach(player => player.destroy());
- this.reportError(errors);
- }
- const /** @type {?} */ allPreviousPlayersMap = new Map();
- // this map works to tell which element in the DOM tree is contained by
- // which animation. Further down below this map will get populated once
- // the players are built and in doing so it can efficiently figure out
- // if a sub player is skipped due to a parent player having priority.
- const /** @type {?} */ animationElementMap = new Map();
- queuedInstructions.forEach(entry => {
- const /** @type {?} */ element = entry.element;
- if (subTimelines.has(element)) {
- animationElementMap.set(element, element);
- this._beforeAnimationBuild(entry.player.namespaceId, entry.instruction, allPreviousPlayersMap);
- }
- });
- skippedPlayers.forEach(player => {
- const /** @type {?} */ element = player.element;
- const /** @type {?} */ previousPlayers = this._getPreviousPlayers(element, false, player.namespaceId, player.triggerName, null);
- previousPlayers.forEach(prevPlayer => {
- getOrSetAsInMap(allPreviousPlayersMap, element, []).push(prevPlayer);
- prevPlayer.destroy();
- });
- });
- // this is a special case for nodes that will be removed (either by)
- // having their own leave animations or by being queried in a container
- // that will be removed once a parent animation is complete. The idea
- // here is that * styles must be identical to ! styles because of
- // backwards compatibility (* is also filled in by default in many places).
- // Otherwise * styles will return an empty value or auto since the element
- // that is being getComputedStyle'd will not be visible (since * = destination)
- const /** @type {?} */ replaceNodes = allLeaveNodes.filter(node => {
- return replacePostStylesAsPre(node, allPreStyleElements, allPostStyleElements);
- });
- // POST STAGE: fill the * styles
- const /** @type {?} */ postStylesMap = new Map();
- const /** @type {?} */ allLeaveQueriedNodes = cloakAndComputeStyles(postStylesMap, this.driver, leaveNodesWithoutAnimations, allPostStyleElements, AUTO_STYLE);
- allLeaveQueriedNodes.forEach(node => {
- if (replacePostStylesAsPre(node, allPreStyleElements, allPostStyleElements)) {
- replaceNodes.push(node);
- }
- });
- // PRE STAGE: fill the ! styles
- const /** @type {?} */ preStylesMap = new Map();
- enterNodeMap.forEach((nodes, root) => {
- cloakAndComputeStyles(preStylesMap, this.driver, new Set(nodes), allPreStyleElements, ɵPRE_STYLE);
- });
- replaceNodes.forEach(node => {
- const /** @type {?} */ post = postStylesMap.get(node);
- const /** @type {?} */ pre = preStylesMap.get(node);
- postStylesMap.set(node, /** @type {?} */ (Object.assign({}, post, pre)));
- });
- const /** @type {?} */ rootPlayers = [];
- const /** @type {?} */ subPlayers = [];
- const /** @type {?} */ NO_PARENT_ANIMATION_ELEMENT_DETECTED = {};
- queuedInstructions.forEach(entry => {
- const { element, player, instruction } = entry;
- // this means that it was never consumed by a parent animation which
- // means that it is independent and therefore should be set for animation
- if (subTimelines.has(element)) {
- if (disabledElementsSet.has(element)) {
- player.onDestroy(() => setStyles(element, instruction.toStyles));
- skippedPlayers.push(player);
- return;
- }
- // this will flow up the DOM and query the map to figure out
- // if a parent animation has priority over it. In the situation
- // that a parent is detected then it will cancel the loop. If
- // nothing is detected, or it takes a few hops to find a parent,
- // then it will fill in the missing nodes and signal them as having
- // a detected parent (or a NO_PARENT value via a special constant).
- let /** @type {?} */ parentWithAnimation = NO_PARENT_ANIMATION_ELEMENT_DETECTED;
- if (animationElementMap.size > 1) {
- let /** @type {?} */ elm = element;
- const /** @type {?} */ parentsToAdd = [];
- while (elm = elm.parentNode) {
- const /** @type {?} */ detectedParent = animationElementMap.get(elm);
- if (detectedParent) {
- parentWithAnimation = detectedParent;
- break;
- }
- parentsToAdd.push(elm);
- }
- parentsToAdd.forEach(parent => animationElementMap.set(parent, parentWithAnimation));
- }
- const /** @type {?} */ innerPlayer = this._buildAnimation(player.namespaceId, instruction, allPreviousPlayersMap, skippedPlayersMap, preStylesMap, postStylesMap);
- player.setRealPlayer(innerPlayer);
- if (parentWithAnimation === NO_PARENT_ANIMATION_ELEMENT_DETECTED) {
- rootPlayers.push(player);
- }
- else {
- const /** @type {?} */ parentPlayers = this.playersByElement.get(parentWithAnimation);
- if (parentPlayers && parentPlayers.length) {
- player.parentPlayer = optimizeGroupPlayer(parentPlayers);
- }
- skippedPlayers.push(player);
- }
- }
- else {
- eraseStyles(element, instruction.fromStyles);
- player.onDestroy(() => setStyles(element, instruction.toStyles));
- // there still might be a ancestor player animating this
- // element therefore we will still add it as a sub player
- // even if its animation may be disabled
- subPlayers.push(player);
- if (disabledElementsSet.has(element)) {
- skippedPlayers.push(player);
- }
- }
- });
- // find all of the sub players' corresponding inner animation player
- subPlayers.forEach(player => {
- // even if any players are not found for a sub animation then it
- // will still complete itself after the next tick since it's Noop
- const /** @type {?} */ playersForElement = skippedPlayersMap.get(player.element);
- if (playersForElement && playersForElement.length) {
- const /** @type {?} */ innerPlayer = optimizeGroupPlayer(playersForElement);
- player.setRealPlayer(innerPlayer);
- }
- });
- // the reason why we don't actually play the animation is
- // because all that a skipped player is designed to do is to
- // fire the start/done transition callback events
- skippedPlayers.forEach(player => {
- if (player.parentPlayer) {
- player.syncPlayerEvents(player.parentPlayer);
- }
- else {
- player.destroy();
- }
- });
- // run through all of the queued removals and see if they
- // were picked up by a query. If not then perform the removal
- // operation right away unless a parent animation is ongoing.
- for (let /** @type {?} */ i = 0; i < allLeaveNodes.length; i++) {
- const /** @type {?} */ element = allLeaveNodes[i];
- const /** @type {?} */ details = /** @type {?} */ (element[REMOVAL_FLAG]);
- removeClass(element, LEAVE_CLASSNAME);
- // this means the element has a removal animation that is being
- // taken care of and therefore the inner elements will hang around
- // until that animation is over (or the parent queried animation)
- if (details && details.hasAnimation)
- continue;
- let /** @type {?} */ players = [];
- // if this element is queried or if it contains queried children
- // then we want for the element not to be removed from the page
- // until the queried animations have finished
- if (queriedElements.size) {
- let /** @type {?} */ queriedPlayerResults = queriedElements.get(element);
- if (queriedPlayerResults && queriedPlayerResults.length) {
- players.push(...queriedPlayerResults);
- }
- let /** @type {?} */ queriedInnerElements = this.driver.query(element, NG_ANIMATING_SELECTOR, true);
- for (let /** @type {?} */ j = 0; j < queriedInnerElements.length; j++) {
- let /** @type {?} */ queriedPlayers = queriedElements.get(queriedInnerElements[j]);
- if (queriedPlayers && queriedPlayers.length) {
- players.push(...queriedPlayers);
- }
- }
- }
- const /** @type {?} */ activePlayers = players.filter(p => !p.destroyed);
- if (activePlayers.length) {
- removeNodesAfterAnimationDone(this, element, activePlayers);
- }
- else {
- this.processLeaveNode(element);
- }
- }
- // this is required so the cleanup method doesn't remove them
- allLeaveNodes.length = 0;
- rootPlayers.forEach(player => {
- this.players.push(player);
- player.onDone(() => {
- player.destroy();
- const /** @type {?} */ index = this.players.indexOf(player);
- this.players.splice(index, 1);
- });
- player.play();
- });
- return rootPlayers;
- }
- /**
- * @param {?} namespaceId
- * @param {?} element
- * @return {?}
- */
- elementContainsData(namespaceId, element) {
- let /** @type {?} */ containsData = false;
- const /** @type {?} */ details = /** @type {?} */ (element[REMOVAL_FLAG]);
- if (details && details.setForRemoval)
- containsData = true;
- if (this.playersByElement.has(element))
- containsData = true;
- if (this.playersByQueriedElement.has(element))
- containsData = true;
- if (this.statesByElement.has(element))
- containsData = true;
- return this._fetchNamespace(namespaceId).elementContainsData(element) || containsData;
- }
- /**
- * @param {?} callback
- * @return {?}
- */
- afterFlush(callback) { this._flushFns.push(callback); }
- /**
- * @param {?} callback
- * @return {?}
- */
- afterFlushAnimationsDone(callback) { this._whenQuietFns.push(callback); }
- /**
- * @param {?} element
- * @param {?} isQueriedElement
- * @param {?=} namespaceId
- * @param {?=} triggerName
- * @param {?=} toStateValue
- * @return {?}
- */
- _getPreviousPlayers(element, isQueriedElement, namespaceId, triggerName, toStateValue) {
- let /** @type {?} */ players = [];
- if (isQueriedElement) {
- const /** @type {?} */ queriedElementPlayers = this.playersByQueriedElement.get(element);
- if (queriedElementPlayers) {
- players = queriedElementPlayers;
- }
- }
- else {
- const /** @type {?} */ elementPlayers = this.playersByElement.get(element);
- if (elementPlayers) {
- const /** @type {?} */ isRemovalAnimation = !toStateValue || toStateValue == VOID_VALUE;
- elementPlayers.forEach(player => {
- if (player.queued)
- return;
- if (!isRemovalAnimation && player.triggerName != triggerName)
- return;
- players.push(player);
- });
- }
- }
- if (namespaceId || triggerName) {
- players = players.filter(player => {
- if (namespaceId && namespaceId != player.namespaceId)
- return false;
- if (triggerName && triggerName != player.triggerName)
- return false;
- return true;
- });
- }
- return players;
- }
- /**
- * @param {?} namespaceId
- * @param {?} instruction
- * @param {?} allPreviousPlayersMap
- * @return {?}
- */
- _beforeAnimationBuild(namespaceId, instruction, allPreviousPlayersMap) {
- const /** @type {?} */ triggerName = instruction.triggerName;
- const /** @type {?} */ rootElement = instruction.element;
- // when a removal animation occurs, ALL previous players are collected
- // and destroyed (even if they are outside of the current namespace)
- const /** @type {?} */ targetNameSpaceId = instruction.isRemovalTransition ? undefined : namespaceId;
- const /** @type {?} */ targetTriggerName = instruction.isRemovalTransition ? undefined : triggerName;
- for (const /** @type {?} */ timelineInstruction of instruction.timelines) {
- const /** @type {?} */ element = timelineInstruction.element;
- const /** @type {?} */ isQueriedElement = element !== rootElement;
- const /** @type {?} */ players = getOrSetAsInMap(allPreviousPlayersMap, element, []);
- const /** @type {?} */ previousPlayers = this._getPreviousPlayers(element, isQueriedElement, targetNameSpaceId, targetTriggerName, instruction.toState);
- previousPlayers.forEach(player => {
- const /** @type {?} */ realPlayer = /** @type {?} */ (player.getRealPlayer());
- if (realPlayer.beforeDestroy) {
- realPlayer.beforeDestroy();
- }
- player.destroy();
- players.push(player);
- });
- }
- // this needs to be done so that the PRE/POST styles can be
- // computed properly without interfering with the previous animation
- eraseStyles(rootElement, instruction.fromStyles);
- }
- /**
- * @param {?} namespaceId
- * @param {?} instruction
- * @param {?} allPreviousPlayersMap
- * @param {?} skippedPlayersMap
- * @param {?} preStylesMap
- * @param {?} postStylesMap
- * @return {?}
- */
- _buildAnimation(namespaceId, instruction, allPreviousPlayersMap, skippedPlayersMap, preStylesMap, postStylesMap) {
- const /** @type {?} */ triggerName = instruction.triggerName;
- const /** @type {?} */ rootElement = instruction.element;
- // we first run this so that the previous animation player
- // data can be passed into the successive animation players
- const /** @type {?} */ allQueriedPlayers = [];
- const /** @type {?} */ allConsumedElements = new Set();
- const /** @type {?} */ allSubElements = new Set();
- const /** @type {?} */ allNewPlayers = instruction.timelines.map(timelineInstruction => {
- const /** @type {?} */ element = timelineInstruction.element;
- allConsumedElements.add(element);
- // FIXME (matsko): make sure to-be-removed animations are removed properly
- const /** @type {?} */ details = element[REMOVAL_FLAG];
- if (details && details.removedBeforeQueried)
- return new NoopAnimationPlayer();
- const /** @type {?} */ isQueriedElement = element !== rootElement;
- const /** @type {?} */ previousPlayers = flattenGroupPlayers((allPreviousPlayersMap.get(element) || EMPTY_PLAYER_ARRAY)
- .map(p => p.getRealPlayer()))
- .filter(p => {
- // the `element` is not apart of the AnimationPlayer definition, but
- // Mock/WebAnimations
- // use the element within their implementation. This will be added in Angular5 to
- // AnimationPlayer
- const /** @type {?} */ pp = /** @type {?} */ (p);
- return pp.element ? pp.element === element : false;
- });
- const /** @type {?} */ preStyles = preStylesMap.get(element);
- const /** @type {?} */ postStyles = postStylesMap.get(element);
- const /** @type {?} */ keyframes = normalizeKeyframes(this.driver, this._normalizer, element, timelineInstruction.keyframes, preStyles, postStyles);
- const /** @type {?} */ player = this._buildPlayer(timelineInstruction, keyframes, previousPlayers);
- // this means that this particular player belongs to a sub trigger. It is
- // important that we match this player up with the corresponding (@trigger.listener)
- if (timelineInstruction.subTimeline && skippedPlayersMap) {
- allSubElements.add(element);
- }
- if (isQueriedElement) {
- const /** @type {?} */ wrappedPlayer = new TransitionAnimationPlayer(namespaceId, triggerName, element);
- wrappedPlayer.setRealPlayer(player);
- allQueriedPlayers.push(wrappedPlayer);
- }
- return player;
- });
- allQueriedPlayers.forEach(player => {
- getOrSetAsInMap(this.playersByQueriedElement, player.element, []).push(player);
- player.onDone(() => deleteOrUnsetInMap(this.playersByQueriedElement, player.element, player));
- });
- allConsumedElements.forEach(element => addClass(element, NG_ANIMATING_CLASSNAME));
- const /** @type {?} */ player = optimizeGroupPlayer(allNewPlayers);
- player.onDestroy(() => {
- allConsumedElements.forEach(element => removeClass(element, NG_ANIMATING_CLASSNAME));
- setStyles(rootElement, instruction.toStyles);
- });
- // this basically makes all of the callbacks for sub element animations
- // be dependent on the upper players for when they finish
- allSubElements.forEach(element => { getOrSetAsInMap(skippedPlayersMap, element, []).push(player); });
- return player;
- }
- /**
- * @param {?} instruction
- * @param {?} keyframes
- * @param {?} previousPlayers
- * @return {?}
- */
- _buildPlayer(instruction, keyframes, previousPlayers) {
- if (keyframes.length > 0) {
- return this.driver.animate(instruction.element, keyframes, instruction.duration, instruction.delay, instruction.easing, previousPlayers);
- }
- // special case for when an empty transition|definition is provided
- // ... there is no point in rendering an empty animation
- return new NoopAnimationPlayer();
- }
- }
- class TransitionAnimationPlayer {
- /**
- * @param {?} namespaceId
- * @param {?} triggerName
- * @param {?} element
- */
- constructor(namespaceId, triggerName, element) {
- this.namespaceId = namespaceId;
- this.triggerName = triggerName;
- this.element = element;
- this._player = new NoopAnimationPlayer();
- this._containsRealPlayer = false;
- this._queuedCallbacks = {};
- this.destroyed = false;
- this.markedForDestroy = false;
- this.queued = true;
- }
- /**
- * @param {?} player
- * @return {?}
- */
- setRealPlayer(player) {
- if (this._containsRealPlayer)
- return;
- this._player = player;
- Object.keys(this._queuedCallbacks).forEach(phase => {
- this._queuedCallbacks[phase].forEach(callback => listenOnPlayer(player, phase, undefined, callback));
- });
- this._queuedCallbacks = {};
- this._containsRealPlayer = true;
- (/** @type {?} */ (this)).queued = false;
- }
- /**
- * @return {?}
- */
- getRealPlayer() { return this._player; }
- /**
- * @param {?} player
- * @return {?}
- */
- syncPlayerEvents(player) {
- const /** @type {?} */ p = /** @type {?} */ (this._player);
- if (p.triggerCallback) {
- player.onStart(() => p.triggerCallback('start'));
- }
- player.onDone(() => this.finish());
- player.onDestroy(() => this.destroy());
- }
- /**
- * @param {?} name
- * @param {?} callback
- * @return {?}
- */
- _queueEvent(name, callback) {
- getOrSetAsInMap(this._queuedCallbacks, name, []).push(callback);
- }
- /**
- * @param {?} fn
- * @return {?}
- */
- onDone(fn) {
- if (this.queued) {
- this._queueEvent('done', fn);
- }
- this._player.onDone(fn);
- }
- /**
- * @param {?} fn
- * @return {?}
- */
- onStart(fn) {
- if (this.queued) {
- this._queueEvent('start', fn);
- }
- this._player.onStart(fn);
- }
- /**
- * @param {?} fn
- * @return {?}
- */
- onDestroy(fn) {
- if (this.queued) {
- this._queueEvent('destroy', fn);
- }
- this._player.onDestroy(fn);
- }
- /**
- * @return {?}
- */
- init() { this._player.init(); }
- /**
- * @return {?}
- */
- hasStarted() { return this.queued ? false : this._player.hasStarted(); }
- /**
- * @return {?}
- */
- play() { !this.queued && this._player.play(); }
- /**
- * @return {?}
- */
- pause() { !this.queued && this._player.pause(); }
- /**
- * @return {?}
- */
- restart() { !this.queued && this._player.restart(); }
- /**
- * @return {?}
- */
- finish() { this._player.finish(); }
- /**
- * @return {?}
- */
- destroy() {
- (/** @type {?} */ (this)).destroyed = true;
- this._player.destroy();
- }
- /**
- * @return {?}
- */
- reset() { !this.queued && this._player.reset(); }
- /**
- * @param {?} p
- * @return {?}
- */
- setPosition(p) {
- if (!this.queued) {
- this._player.setPosition(p);
- }
- }
- /**
- * @return {?}
- */
- getPosition() { return this.queued ? 0 : this._player.getPosition(); }
- /**
- * @return {?}
- */
- get totalTime() { return this._player.totalTime; }
- /**
- * @param {?} phaseName
- * @return {?}
- */
- triggerCallback(phaseName) {
- const /** @type {?} */ p = /** @type {?} */ (this._player);
- if (p.triggerCallback) {
- p.triggerCallback(phaseName);
- }
- }
- }
- /**
- * @param {?} map
- * @param {?} key
- * @param {?} value
- * @return {?}
- */
- function deleteOrUnsetInMap(map, key, value) {
- let /** @type {?} */ currentValues;
- if (map instanceof Map) {
- currentValues = map.get(key);
- if (currentValues) {
- if (currentValues.length) {
- const /** @type {?} */ index = currentValues.indexOf(value);
- currentValues.splice(index, 1);
- }
- if (currentValues.length == 0) {
- map.delete(key);
- }
- }
- }
- else {
- currentValues = map[key];
- if (currentValues) {
- if (currentValues.length) {
- const /** @type {?} */ index = currentValues.indexOf(value);
- currentValues.splice(index, 1);
- }
- if (currentValues.length == 0) {
- delete map[key];
- }
- }
- }
- return currentValues;
- }
- /**
- * @param {?} value
- * @return {?}
- */
- function normalizeTriggerValue(value) {
- // we use `!= null` here because it's the most simple
- // way to test against a "falsy" value without mixing
- // in empty strings or a zero value. DO NOT OPTIMIZE.
- return value != null ? value : null;
- }
- /**
- * @param {?} node
- * @return {?}
- */
- function isElementNode(node) {
- return node && node['nodeType'] === 1;
- }
- /**
- * @param {?} eventName
- * @return {?}
- */
- function isTriggerEventValid(eventName) {
- return eventName == 'start' || eventName == 'done';
- }
- /**
- * @param {?} element
- * @param {?=} value
- * @return {?}
- */
- function cloakElement(element, value) {
- const /** @type {?} */ oldValue = element.style.display;
- element.style.display = value != null ? value : 'none';
- return oldValue;
- }
- /**
- * @param {?} valuesMap
- * @param {?} driver
- * @param {?} elements
- * @param {?} elementPropsMap
- * @param {?} defaultStyle
- * @return {?}
- */
- function cloakAndComputeStyles(valuesMap, driver, elements, elementPropsMap, defaultStyle) {
- const /** @type {?} */ cloakVals = [];
- elements.forEach(element => cloakVals.push(cloakElement(element)));
- const /** @type {?} */ failedElements = [];
- elementPropsMap.forEach((props, element) => {
- const /** @type {?} */ styles = {};
- props.forEach(prop => {
- const /** @type {?} */ value = styles[prop] = driver.computeStyle(element, prop, defaultStyle);
- // there is no easy way to detect this because a sub element could be removed
- // by a parent animation element being detached.
- if (!value || value.length == 0) {
- element[REMOVAL_FLAG] = NULL_REMOVED_QUERIED_STATE;
- failedElements.push(element);
- }
- });
- valuesMap.set(element, styles);
- });
- // we use a index variable here since Set.forEach(a, i) does not return
- // an index value for the closure (but instead just the value)
- let /** @type {?} */ i = 0;
- elements.forEach(element => cloakElement(element, cloakVals[i++]));
- return failedElements;
- }
- /**
- * @param {?} roots
- * @param {?} nodes
- * @return {?}
- */
- function buildRootMap(roots, nodes) {
- const /** @type {?} */ rootMap = new Map();
- roots.forEach(root => rootMap.set(root, []));
- if (nodes.length == 0)
- return rootMap;
- const /** @type {?} */ NULL_NODE = 1;
- const /** @type {?} */ nodeSet = new Set(nodes);
- const /** @type {?} */ localRootMap = new Map();
- /**
- * @param {?} node
- * @return {?}
- */
- function getRoot(node) {
- if (!node)
- return NULL_NODE;
- let /** @type {?} */ root = localRootMap.get(node);
- if (root)
- return root;
- const /** @type {?} */ parent = node.parentNode;
- if (rootMap.has(parent)) {
- // ngIf inside @trigger
- root = parent;
- }
- else if (nodeSet.has(parent)) {
- // ngIf inside ngIf
- root = NULL_NODE;
- }
- else {
- // recurse upwards
- root = getRoot(parent);
- }
- localRootMap.set(node, root);
- return root;
- }
- nodes.forEach(node => {
- const /** @type {?} */ root = getRoot(node);
- if (root !== NULL_NODE) {
- /** @type {?} */ ((rootMap.get(root))).push(node);
- }
- });
- return rootMap;
- }
- const CLASSES_CACHE_KEY = '$$classes';
- /**
- * @param {?} element
- * @param {?} className
- * @return {?}
- */
- function addClass(element, className) {
- if (element.classList) {
- element.classList.add(className);
- }
- else {
- let /** @type {?} */ classes = element[CLASSES_CACHE_KEY];
- if (!classes) {
- classes = element[CLASSES_CACHE_KEY] = {};
- }
- classes[className] = true;
- }
- }
- /**
- * @param {?} element
- * @param {?} className
- * @return {?}
- */
- function removeClass(element, className) {
- if (element.classList) {
- element.classList.remove(className);
- }
- else {
- let /** @type {?} */ classes = element[CLASSES_CACHE_KEY];
- if (classes) {
- delete classes[className];
- }
- }
- }
- /**
- * @param {?} engine
- * @param {?} element
- * @param {?} players
- * @return {?}
- */
- function removeNodesAfterAnimationDone(engine, element, players) {
- optimizeGroupPlayer(players).onDone(() => engine.processLeaveNode(element));
- }
- /**
- * @param {?} players
- * @return {?}
- */
- function flattenGroupPlayers(players) {
- const /** @type {?} */ finalPlayers = [];
- _flattenGroupPlayersRecur(players, finalPlayers);
- return finalPlayers;
- }
- /**
- * @param {?} players
- * @param {?} finalPlayers
- * @return {?}
- */
- function _flattenGroupPlayersRecur(players, finalPlayers) {
- for (let /** @type {?} */ i = 0; i < players.length; i++) {
- const /** @type {?} */ player = players[i];
- if (player instanceof ɵAnimationGroupPlayer) {
- _flattenGroupPlayersRecur(player.players, finalPlayers);
- }
- else {
- finalPlayers.push(/** @type {?} */ (player));
- }
- }
- }
- /**
- * @param {?} a
- * @param {?} b
- * @return {?}
- */
- function objEquals(a, b) {
- const /** @type {?} */ k1 = Object.keys(a);
- const /** @type {?} */ k2 = Object.keys(b);
- if (k1.length != k2.length)
- return false;
- for (let /** @type {?} */ i = 0; i < k1.length; i++) {
- const /** @type {?} */ prop = k1[i];
- if (!b.hasOwnProperty(prop) || a[prop] !== b[prop])
- return false;
- }
- return true;
- }
- /**
- * @param {?} element
- * @param {?} allPreStyleElements
- * @param {?} allPostStyleElements
- * @return {?}
- */
- function replacePostStylesAsPre(element, allPreStyleElements, allPostStyleElements) {
- const /** @type {?} */ postEntry = allPostStyleElements.get(element);
- if (!postEntry)
- return false;
- let /** @type {?} */ preEntry = allPreStyleElements.get(element);
- if (preEntry) {
- postEntry.forEach(data => /** @type {?} */ ((preEntry)).add(data));
- }
- else {
- allPreStyleElements.set(element, postEntry);
- }
- allPostStyleElements.delete(element);
- return true;
- }
-
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes} checked by tsc
- */
- class AnimationEngine {
- /**
- * @param {?} _driver
- * @param {?} normalizer
- */
- constructor(_driver, normalizer) {
- this._driver = _driver;
- this._triggerCache = {};
- this.onRemovalComplete = (element, context) => { };
- this._transitionEngine = new TransitionAnimationEngine(_driver, normalizer);
- this._timelineEngine = new TimelineAnimationEngine(_driver, normalizer);
- this._transitionEngine.onRemovalComplete = (element, context) => this.onRemovalComplete(element, context);
- }
- /**
- * @param {?} componentId
- * @param {?} namespaceId
- * @param {?} hostElement
- * @param {?} name
- * @param {?} metadata
- * @return {?}
- */
- registerTrigger(componentId, namespaceId, hostElement, name, metadata) {
- const /** @type {?} */ cacheKey = componentId + '-' + name;
- let /** @type {?} */ trigger = this._triggerCache[cacheKey];
- if (!trigger) {
- const /** @type {?} */ errors = [];
- const /** @type {?} */ ast = /** @type {?} */ (buildAnimationAst(this._driver, /** @type {?} */ (metadata), errors));
- if (errors.length) {
- throw new Error(`The animation trigger "${name}" has failed to build due to the following errors:\n - ${errors.join("\n - ")}`);
- }
- trigger = buildTrigger(name, ast);
- this._triggerCache[cacheKey] = trigger;
- }
- this._transitionEngine.registerTrigger(namespaceId, name, trigger);
- }
- /**
- * @param {?} namespaceId
- * @param {?} hostElement
- * @return {?}
- */
- register(namespaceId, hostElement) {
- this._transitionEngine.register(namespaceId, hostElement);
- }
- /**
- * @param {?} namespaceId
- * @param {?} context
- * @return {?}
- */
- destroy(namespaceId, context) {
- this._transitionEngine.destroy(namespaceId, context);
- }
- /**
- * @param {?} namespaceId
- * @param {?} element
- * @param {?} parent
- * @param {?} insertBefore
- * @return {?}
- */
- onInsert(namespaceId, element, parent, insertBefore) {
- this._transitionEngine.insertNode(namespaceId, element, parent, insertBefore);
- }
- /**
- * @param {?} namespaceId
- * @param {?} element
- * @param {?} context
- * @return {?}
- */
- onRemove(namespaceId, element, context) {
- this._transitionEngine.removeNode(namespaceId, element, context);
- }
- /**
- * @param {?} element
- * @param {?} disable
- * @return {?}
- */
- disableAnimations(element, disable) {
- this._transitionEngine.markElementAsDisabled(element, disable);
- }
- /**
- * @param {?} namespaceId
- * @param {?} element
- * @param {?} property
- * @param {?} value
- * @return {?}
- */
- process(namespaceId, element, property, value) {
- if (property.charAt(0) == '@') {
- const [id, action] = parseTimelineCommand(property);
- const /** @type {?} */ args = /** @type {?} */ (value);
- this._timelineEngine.command(id, element, action, args);
- }
- else {
- this._transitionEngine.trigger(namespaceId, element, property, value);
- }
- }
- /**
- * @param {?} namespaceId
- * @param {?} element
- * @param {?} eventName
- * @param {?} eventPhase
- * @param {?} callback
- * @return {?}
- */
- listen(namespaceId, element, eventName, eventPhase, callback) {
- // @@listen
- if (eventName.charAt(0) == '@') {
- const [id, action] = parseTimelineCommand(eventName);
- return this._timelineEngine.listen(id, element, action, callback);
- }
- return this._transitionEngine.listen(namespaceId, element, eventName, eventPhase, callback);
- }
- /**
- * @param {?=} microtaskId
- * @return {?}
- */
- flush(microtaskId = -1) { this._transitionEngine.flush(microtaskId); }
- /**
- * @return {?}
- */
- get players() {
- return (/** @type {?} */ (this._transitionEngine.players))
- .concat(/** @type {?} */ (this._timelineEngine.players));
- }
- /**
- * @return {?}
- */
- whenRenderingDone() { return this._transitionEngine.whenRenderingDone(); }
- }
-
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes} checked by tsc
- */
- class WebAnimationsPlayer {
- /**
- * @param {?} element
- * @param {?} keyframes
- * @param {?} options
- * @param {?=} previousPlayers
- */
- constructor(element, keyframes, options, previousPlayers = []) {
- this.element = element;
- this.keyframes = keyframes;
- this.options = options;
- this.previousPlayers = previousPlayers;
- this._onDoneFns = [];
- this._onStartFns = [];
- this._onDestroyFns = [];
- this._initialized = false;
- this._finished = false;
- this._started = false;
- this._destroyed = false;
- this.time = 0;
- this.parentPlayer = null;
- this.previousStyles = {};
- this.currentSnapshot = {};
- this._duration = /** @type {?} */ (options['duration']);
- this._delay = /** @type {?} */ (options['delay']) || 0;
- this.time = this._duration + this._delay;
- if (allowPreviousPlayerStylesMerge(this._duration, this._delay)) {
- previousPlayers.forEach(player => {
- let /** @type {?} */ styles = player.currentSnapshot;
- Object.keys(styles).forEach(prop => this.previousStyles[prop] = styles[prop]);
- });
- }
- }
- /**
- * @return {?}
- */
- _onFinish() {
- if (!this._finished) {
- this._finished = true;
- this._onDoneFns.forEach(fn => fn());
- this._onDoneFns = [];
- }
- }
- /**
- * @return {?}
- */
- init() {
- this._buildPlayer();
- this._preparePlayerBeforeStart();
- }
- /**
- * @return {?}
- */
- _buildPlayer() {
- if (this._initialized)
- return;
- this._initialized = true;
- const /** @type {?} */ keyframes = this.keyframes.map(styles => copyStyles(styles, false));
- const /** @type {?} */ previousStyleProps = Object.keys(this.previousStyles);
- if (previousStyleProps.length && keyframes.length) {
- let /** @type {?} */ startingKeyframe = keyframes[0];
- let /** @type {?} */ missingStyleProps = [];
- previousStyleProps.forEach(prop => {
- if (!startingKeyframe.hasOwnProperty(prop)) {
- missingStyleProps.push(prop);
- }
- startingKeyframe[prop] = this.previousStyles[prop];
- });
- if (missingStyleProps.length) {
- const /** @type {?} */ self = this;
- // tslint:disable-next-line
- for (var /** @type {?} */ i = 1; i < keyframes.length; i++) {
- let /** @type {?} */ kf = keyframes[i];
- missingStyleProps.forEach(function (prop) {
- kf[prop] = _computeStyle(self.element, prop);
- });
- }
- }
- }
- (/** @type {?} */ (this)).domPlayer =
- this._triggerWebAnimation(this.element, keyframes, this.options);
- this._finalKeyframe = keyframes.length ? keyframes[keyframes.length - 1] : {};
- this.domPlayer.addEventListener('finish', () => this._onFinish());
- }
- /**
- * @return {?}
- */
- _preparePlayerBeforeStart() {
- // this is required so that the player doesn't start to animate right away
- if (this._delay) {
- this._resetDomPlayerState();
- }
- else {
- this.domPlayer.pause();
- }
- }
- /**
- * \@internal
- * @param {?} element
- * @param {?} keyframes
- * @param {?} options
- * @return {?}
- */
- _triggerWebAnimation(element, keyframes, options) {
- // jscompiler doesn't seem to know animate is a native property because it's not fully
- // supported yet across common browsers (we polyfill it for Edge/Safari) [CL #143630929]
- return /** @type {?} */ (element['animate'](keyframes, options));
- }
- /**
- * @param {?} fn
- * @return {?}
- */
- onStart(fn) { this._onStartFns.push(fn); }
- /**
- * @param {?} fn
- * @return {?}
- */
- onDone(fn) { this._onDoneFns.push(fn); }
- /**
- * @param {?} fn
- * @return {?}
- */
- onDestroy(fn) { this._onDestroyFns.push(fn); }
- /**
- * @return {?}
- */
- play() {
- this._buildPlayer();
- if (!this.hasStarted()) {
- this._onStartFns.forEach(fn => fn());
- this._onStartFns = [];
- this._started = true;
- }
- this.domPlayer.play();
- }
- /**
- * @return {?}
- */
- pause() {
- this.init();
- this.domPlayer.pause();
- }
- /**
- * @return {?}
- */
- finish() {
- this.init();
- this._onFinish();
- this.domPlayer.finish();
- }
- /**
- * @return {?}
- */
- reset() {
- this._resetDomPlayerState();
- this._destroyed = false;
- this._finished = false;
- this._started = false;
- }
- /**
- * @return {?}
- */
- _resetDomPlayerState() {
- if (this.domPlayer) {
- this.domPlayer.cancel();
- }
- }
- /**
- * @return {?}
- */
- restart() {
- this.reset();
- this.play();
- }
- /**
- * @return {?}
- */
- hasStarted() { return this._started; }
- /**
- * @return {?}
- */
- destroy() {
- if (!this._destroyed) {
- this._destroyed = true;
- this._resetDomPlayerState();
- this._onFinish();
- this._onDestroyFns.forEach(fn => fn());
- this._onDestroyFns = [];
- }
- }
- /**
- * @param {?} p
- * @return {?}
- */
- setPosition(p) { this.domPlayer.currentTime = p * this.time; }
- /**
- * @return {?}
- */
- getPosition() { return this.domPlayer.currentTime / this.time; }
- /**
- * @return {?}
- */
- get totalTime() { return this._delay + this._duration; }
- /**
- * @return {?}
- */
- beforeDestroy() {
- const /** @type {?} */ styles = {};
- if (this.hasStarted()) {
- Object.keys(this._finalKeyframe).forEach(prop => {
- if (prop != 'offset') {
- styles[prop] =
- this._finished ? this._finalKeyframe[prop] : _computeStyle(this.element, prop);
- }
- });
- }
- this.currentSnapshot = styles;
- }
- /**
- * @param {?} phaseName
- * @return {?}
- */
- triggerCallback(phaseName) {
- const /** @type {?} */ methods = phaseName == 'start' ? this._onStartFns : this._onDoneFns;
- methods.forEach(fn => fn());
- methods.length = 0;
- }
- }
- /**
- * @param {?} element
- * @param {?} prop
- * @return {?}
- */
- function _computeStyle(element, prop) {
- return (/** @type {?} */ (window.getComputedStyle(element)))[prop];
- }
-
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes} checked by tsc
- */
- class WebAnimationsDriver {
- /**
- * @param {?} prop
- * @return {?}
- */
- validateStyleProperty(prop) { return validateStyleProperty(prop); }
- /**
- * @param {?} element
- * @param {?} selector
- * @return {?}
- */
- matchesElement(element, selector) {
- return matchesElement(element, selector);
- }
- /**
- * @param {?} elm1
- * @param {?} elm2
- * @return {?}
- */
- containsElement(elm1, elm2) { return containsElement(elm1, elm2); }
- /**
- * @param {?} element
- * @param {?} selector
- * @param {?} multi
- * @return {?}
- */
- query(element, selector, multi) {
- return invokeQuery(element, selector, multi);
- }
- /**
- * @param {?} element
- * @param {?} prop
- * @param {?=} defaultValue
- * @return {?}
- */
- computeStyle(element, prop, defaultValue) {
- return /** @type {?} */ ((/** @type {?} */ (window.getComputedStyle(element)))[prop]);
- }
- /**
- * @param {?} element
- * @param {?} keyframes
- * @param {?} duration
- * @param {?} delay
- * @param {?} easing
- * @param {?=} previousPlayers
- * @return {?}
- */
- animate(element, keyframes, duration, delay, easing, previousPlayers = []) {
- const /** @type {?} */ fill = delay == 0 ? 'both' : 'forwards';
- const /** @type {?} */ playerOptions = { duration, delay, fill };
- // we check for this to avoid having a null|undefined value be present
- // for the easing (which results in an error for certain browsers #9752)
- if (easing) {
- playerOptions['easing'] = easing;
- }
- const /** @type {?} */ previousWebAnimationPlayers = /** @type {?} */ (previousPlayers.filter(player => { return player instanceof WebAnimationsPlayer; }));
- return new WebAnimationsPlayer(element, keyframes, playerOptions, previousWebAnimationPlayers);
- }
- }
- /**
- * @return {?}
- */
- function supportsWebAnimations() {
- return typeof Element !== 'undefined' && typeof (/** @type {?} */ (Element)).prototype['animate'] === 'function';
- }
-
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes} checked by tsc
- */
-
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes} checked by tsc
- */
- /**
- * @license
- * Copyright Google Inc. All Rights Reserved.
- *
- * Use of this source code is governed by an MIT-style license that can be
- * found in the LICENSE file at https://angular.io/license
- */
-
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes} checked by tsc
- */
- /**
- * @license
- * Copyright Google Inc. All Rights Reserved.
- *
- * Use of this source code is governed by an MIT-style license that can be
- * found in the LICENSE file at https://angular.io/license
- */
- /**
- * @module
- * @description
- * Entry point for all public APIs of this package.
- */
-
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes} checked by tsc
- */
- /**
- * Generated bundle index. Do not edit.
- */
-
- export { AnimationDriver, Animation as ɵAnimation, AnimationStyleNormalizer as ɵAnimationStyleNormalizer, NoopAnimationStyleNormalizer as ɵNoopAnimationStyleNormalizer, WebAnimationsStyleNormalizer as ɵWebAnimationsStyleNormalizer, NoopAnimationDriver as ɵNoopAnimationDriver, AnimationEngine as ɵAnimationEngine, WebAnimationsDriver as ɵWebAnimationsDriver, supportsWebAnimations as ɵsupportsWebAnimations, WebAnimationsPlayer as ɵWebAnimationsPlayer };
- //# sourceMappingURL=browser.js.map
|