1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301
  1. /**
  2. * @license Angular v6.0.9
  3. * (c) 2010-2018 Google, Inc. https://angular.io/
  4. * License: MIT
  5. */
  6. import { Component, ɵisObservable, ɵisPromise, NgModuleRef, InjectionToken, NgModuleFactory, isDevMode, Attribute, Directive, ElementRef, HostBinding, HostListener, Input, Renderer2, ChangeDetectorRef, ContentChildren, ComponentFactoryResolver, EventEmitter, Output, ViewContainerRef, Compiler, Injectable, Injector, NgModuleFactoryLoader, ANALYZE_FOR_ENTRY_COMPONENTS, APP_BOOTSTRAP_LISTENER, APP_INITIALIZER, ApplicationRef, Inject, NgModule, NgProbeToken, Optional, SkipSelf, SystemJsNgModuleLoader, Version } from '@angular/core';
  7. import { from, of, EmptyError, Observable, BehaviorSubject, Subject } from 'rxjs';
  8. import { concatAll, every, last, map, mergeAll, catchError, first, mergeMap, concatMap, reduce, filter } from 'rxjs/operators';
  9. import { LocationStrategy, APP_BASE_HREF, HashLocationStrategy, LOCATION_INITIALIZED, Location, PathLocationStrategy, PlatformLocation } from '@angular/common';
  10. import { ɵgetDOM } from '@angular/platform-browser';
  11. /**
  12. * @fileoverview added by tsickle
  13. * @suppress {checkTypes} checked by tsc
  14. */
  15. /**
  16. * @license
  17. * Copyright Google Inc. All Rights Reserved.
  18. *
  19. * Use of this source code is governed by an MIT-style license that can be
  20. * found in the LICENSE file at https://angular.io/license
  21. */
  22. /**
  23. * \@description
  24. *
  25. * Base for events the Router goes through, as opposed to events tied to a specific
  26. * Route. `RouterEvent`s will only be fired one time for any given navigation.
  27. *
  28. * Example:
  29. *
  30. * ```
  31. * class MyService {
  32. * constructor(public router: Router, logger: Logger) {
  33. * router.events.filter(e => e instanceof RouterEvent).subscribe(e => {
  34. * logger.log(e.id, e.url);
  35. * });
  36. * }
  37. * }
  38. * ```
  39. *
  40. * \@experimental
  41. */
  42. class RouterEvent {
  43. /**
  44. * @param {?} id
  45. * @param {?} url
  46. */
  47. constructor(id, url) {
  48. this.id = id;
  49. this.url = url;
  50. }
  51. }
  52. /**
  53. * \@description
  54. *
  55. * Represents an event triggered when a navigation starts.
  56. *
  57. *
  58. */
  59. class NavigationStart extends RouterEvent {
  60. /**
  61. * @param {?} id
  62. * @param {?} url
  63. * @param {?=} navigationTrigger
  64. * @param {?=} restoredState
  65. */
  66. constructor(/** @docsNotRequired */
  67. /** @docsNotRequired */
  68. id, /** @docsNotRequired */
  69. /** @docsNotRequired */
  70. url, /** @docsNotRequired */
  71. /** @docsNotRequired */
  72. navigationTrigger = 'imperative', /** @docsNotRequired */
  73. /** @docsNotRequired */
  74. restoredState = null) {
  75. super(id, url);
  76. this.navigationTrigger = navigationTrigger;
  77. this.restoredState = restoredState;
  78. }
  79. /**
  80. * \@docsNotRequired
  81. * @return {?}
  82. */
  83. toString() { return `NavigationStart(id: ${this.id}, url: '${this.url}')`; }
  84. }
  85. /**
  86. * \@description
  87. *
  88. * Represents an event triggered when a navigation ends successfully.
  89. *
  90. *
  91. */
  92. class NavigationEnd extends RouterEvent {
  93. /**
  94. * @param {?} id
  95. * @param {?} url
  96. * @param {?} urlAfterRedirects
  97. */
  98. constructor(/** @docsNotRequired */
  99. /** @docsNotRequired */
  100. id, /** @docsNotRequired */
  101. /** @docsNotRequired */
  102. url, urlAfterRedirects) {
  103. super(id, url);
  104. this.urlAfterRedirects = urlAfterRedirects;
  105. }
  106. /**
  107. * \@docsNotRequired
  108. * @return {?}
  109. */
  110. toString() {
  111. return `NavigationEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}')`;
  112. }
  113. }
  114. /**
  115. * \@description
  116. *
  117. * Represents an event triggered when a navigation is canceled.
  118. *
  119. *
  120. */
  121. class NavigationCancel extends RouterEvent {
  122. /**
  123. * @param {?} id
  124. * @param {?} url
  125. * @param {?} reason
  126. */
  127. constructor(/** @docsNotRequired */
  128. /** @docsNotRequired */
  129. id, /** @docsNotRequired */
  130. /** @docsNotRequired */
  131. url, reason) {
  132. super(id, url);
  133. this.reason = reason;
  134. }
  135. /**
  136. * \@docsNotRequired
  137. * @return {?}
  138. */
  139. toString() { return `NavigationCancel(id: ${this.id}, url: '${this.url}')`; }
  140. }
  141. /**
  142. * \@description
  143. *
  144. * Represents an event triggered when a navigation fails due to an unexpected error.
  145. *
  146. *
  147. */
  148. class NavigationError extends RouterEvent {
  149. /**
  150. * @param {?} id
  151. * @param {?} url
  152. * @param {?} error
  153. */
  154. constructor(/** @docsNotRequired */
  155. /** @docsNotRequired */
  156. id, /** @docsNotRequired */
  157. /** @docsNotRequired */
  158. url, error) {
  159. super(id, url);
  160. this.error = error;
  161. }
  162. /**
  163. * \@docsNotRequired
  164. * @return {?}
  165. */
  166. toString() {
  167. return `NavigationError(id: ${this.id}, url: '${this.url}', error: ${this.error})`;
  168. }
  169. }
  170. /**
  171. * \@description
  172. *
  173. * Represents an event triggered when routes are recognized.
  174. *
  175. *
  176. */
  177. class RoutesRecognized extends RouterEvent {
  178. /**
  179. * @param {?} id
  180. * @param {?} url
  181. * @param {?} urlAfterRedirects
  182. * @param {?} state
  183. */
  184. constructor(/** @docsNotRequired */
  185. /** @docsNotRequired */
  186. id, /** @docsNotRequired */
  187. /** @docsNotRequired */
  188. url, urlAfterRedirects, state) {
  189. super(id, url);
  190. this.urlAfterRedirects = urlAfterRedirects;
  191. this.state = state;
  192. }
  193. /**
  194. * \@docsNotRequired
  195. * @return {?}
  196. */
  197. toString() {
  198. return `RoutesRecognized(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
  199. }
  200. }
  201. /**
  202. * \@description
  203. *
  204. * Represents the start of the Guard phase of routing.
  205. *
  206. * \@experimental
  207. */
  208. class GuardsCheckStart extends RouterEvent {
  209. /**
  210. * @param {?} id
  211. * @param {?} url
  212. * @param {?} urlAfterRedirects
  213. * @param {?} state
  214. */
  215. constructor(/** @docsNotRequired */
  216. /** @docsNotRequired */
  217. id, /** @docsNotRequired */
  218. /** @docsNotRequired */
  219. url, urlAfterRedirects, state) {
  220. super(id, url);
  221. this.urlAfterRedirects = urlAfterRedirects;
  222. this.state = state;
  223. }
  224. /**
  225. * @return {?}
  226. */
  227. toString() {
  228. return `GuardsCheckStart(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
  229. }
  230. }
  231. /**
  232. * \@description
  233. *
  234. * Represents the end of the Guard phase of routing.
  235. *
  236. * \@experimental
  237. */
  238. class GuardsCheckEnd extends RouterEvent {
  239. /**
  240. * @param {?} id
  241. * @param {?} url
  242. * @param {?} urlAfterRedirects
  243. * @param {?} state
  244. * @param {?} shouldActivate
  245. */
  246. constructor(/** @docsNotRequired */
  247. /** @docsNotRequired */
  248. id, /** @docsNotRequired */
  249. /** @docsNotRequired */
  250. url, urlAfterRedirects, state, shouldActivate) {
  251. super(id, url);
  252. this.urlAfterRedirects = urlAfterRedirects;
  253. this.state = state;
  254. this.shouldActivate = shouldActivate;
  255. }
  256. /**
  257. * @return {?}
  258. */
  259. toString() {
  260. return `GuardsCheckEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state}, shouldActivate: ${this.shouldActivate})`;
  261. }
  262. }
  263. /**
  264. * \@description
  265. *
  266. * Represents the start of the Resolve phase of routing. The timing of this
  267. * event may change, thus it's experimental. In the current iteration it will run
  268. * in the "resolve" phase whether there's things to resolve or not. In the future this
  269. * behavior may change to only run when there are things to be resolved.
  270. *
  271. * \@experimental
  272. */
  273. class ResolveStart extends RouterEvent {
  274. /**
  275. * @param {?} id
  276. * @param {?} url
  277. * @param {?} urlAfterRedirects
  278. * @param {?} state
  279. */
  280. constructor(/** @docsNotRequired */
  281. /** @docsNotRequired */
  282. id, /** @docsNotRequired */
  283. /** @docsNotRequired */
  284. url, urlAfterRedirects, state) {
  285. super(id, url);
  286. this.urlAfterRedirects = urlAfterRedirects;
  287. this.state = state;
  288. }
  289. /**
  290. * @return {?}
  291. */
  292. toString() {
  293. return `ResolveStart(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
  294. }
  295. }
  296. /**
  297. * \@description
  298. *
  299. * Represents the end of the Resolve phase of routing. See note on
  300. * `ResolveStart` for use of this experimental API.
  301. *
  302. * \@experimental
  303. */
  304. class ResolveEnd extends RouterEvent {
  305. /**
  306. * @param {?} id
  307. * @param {?} url
  308. * @param {?} urlAfterRedirects
  309. * @param {?} state
  310. */
  311. constructor(/** @docsNotRequired */
  312. /** @docsNotRequired */
  313. id, /** @docsNotRequired */
  314. /** @docsNotRequired */
  315. url, urlAfterRedirects, state) {
  316. super(id, url);
  317. this.urlAfterRedirects = urlAfterRedirects;
  318. this.state = state;
  319. }
  320. /**
  321. * @return {?}
  322. */
  323. toString() {
  324. return `ResolveEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
  325. }
  326. }
  327. /**
  328. * \@description
  329. *
  330. * Represents an event triggered before lazy loading a route config.
  331. *
  332. * \@experimental
  333. */
  334. class RouteConfigLoadStart {
  335. /**
  336. * @param {?} route
  337. */
  338. constructor(route) {
  339. this.route = route;
  340. }
  341. /**
  342. * @return {?}
  343. */
  344. toString() { return `RouteConfigLoadStart(path: ${this.route.path})`; }
  345. }
  346. /**
  347. * \@description
  348. *
  349. * Represents an event triggered when a route has been lazy loaded.
  350. *
  351. * \@experimental
  352. */
  353. class RouteConfigLoadEnd {
  354. /**
  355. * @param {?} route
  356. */
  357. constructor(route) {
  358. this.route = route;
  359. }
  360. /**
  361. * @return {?}
  362. */
  363. toString() { return `RouteConfigLoadEnd(path: ${this.route.path})`; }
  364. }
  365. /**
  366. * \@description
  367. *
  368. * Represents the start of end of the Resolve phase of routing. See note on
  369. * `ChildActivationEnd` for use of this experimental API.
  370. *
  371. * \@experimental
  372. */
  373. class ChildActivationStart {
  374. /**
  375. * @param {?} snapshot
  376. */
  377. constructor(snapshot) {
  378. this.snapshot = snapshot;
  379. }
  380. /**
  381. * @return {?}
  382. */
  383. toString() {
  384. const /** @type {?} */ path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
  385. return `ChildActivationStart(path: '${path}')`;
  386. }
  387. }
  388. /**
  389. * \@description
  390. *
  391. * Represents the start of end of the Resolve phase of routing. See note on
  392. * `ChildActivationStart` for use of this experimental API.
  393. *
  394. * \@experimental
  395. */
  396. class ChildActivationEnd {
  397. /**
  398. * @param {?} snapshot
  399. */
  400. constructor(snapshot) {
  401. this.snapshot = snapshot;
  402. }
  403. /**
  404. * @return {?}
  405. */
  406. toString() {
  407. const /** @type {?} */ path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
  408. return `ChildActivationEnd(path: '${path}')`;
  409. }
  410. }
  411. /**
  412. * \@description
  413. *
  414. * Represents the start of end of the Resolve phase of routing. See note on
  415. * `ActivationEnd` for use of this experimental API.
  416. *
  417. * \@experimental
  418. */
  419. class ActivationStart {
  420. /**
  421. * @param {?} snapshot
  422. */
  423. constructor(snapshot) {
  424. this.snapshot = snapshot;
  425. }
  426. /**
  427. * @return {?}
  428. */
  429. toString() {
  430. const /** @type {?} */ path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
  431. return `ActivationStart(path: '${path}')`;
  432. }
  433. }
  434. /**
  435. * \@description
  436. *
  437. * Represents the start of end of the Resolve phase of routing. See note on
  438. * `ActivationStart` for use of this experimental API.
  439. *
  440. * \@experimental
  441. */
  442. class ActivationEnd {
  443. /**
  444. * @param {?} snapshot
  445. */
  446. constructor(snapshot) {
  447. this.snapshot = snapshot;
  448. }
  449. /**
  450. * @return {?}
  451. */
  452. toString() {
  453. const /** @type {?} */ path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
  454. return `ActivationEnd(path: '${path}')`;
  455. }
  456. }
  457. /**
  458. * @fileoverview added by tsickle
  459. * @suppress {checkTypes} checked by tsc
  460. */
  461. /**
  462. * This component is used internally within the router to be a placeholder when an empty
  463. * router-outlet is needed. For example, with a config such as:
  464. *
  465. * `{path: 'parent', outlet: 'nav', children: [...]}`
  466. *
  467. * In order to render, there needs to be a component on this config, which will default
  468. * to this `EmptyOutletComponent`.
  469. */
  470. class EmptyOutletComponent {
  471. }
  472. EmptyOutletComponent.decorators = [
  473. { type: Component, args: [{ template: `<router-outlet></router-outlet>` }] }
  474. ];
  475. /**
  476. * @fileoverview added by tsickle
  477. * @suppress {checkTypes} checked by tsc
  478. */
  479. /**
  480. * @license
  481. * Copyright Google Inc. All Rights Reserved.
  482. *
  483. * Use of this source code is governed by an MIT-style license that can be
  484. * found in the LICENSE file at https://angular.io/license
  485. */
  486. /**
  487. * \@description
  488. *
  489. * Name of the primary outlet.
  490. *
  491. *
  492. */
  493. const /** @type {?} */ PRIMARY_OUTLET = 'primary';
  494. class ParamsAsMap {
  495. /**
  496. * @param {?} params
  497. */
  498. constructor(params) { this.params = params || {}; }
  499. /**
  500. * @param {?} name
  501. * @return {?}
  502. */
  503. has(name) { return this.params.hasOwnProperty(name); }
  504. /**
  505. * @param {?} name
  506. * @return {?}
  507. */
  508. get(name) {
  509. if (this.has(name)) {
  510. const /** @type {?} */ v = this.params[name];
  511. return Array.isArray(v) ? v[0] : v;
  512. }
  513. return null;
  514. }
  515. /**
  516. * @param {?} name
  517. * @return {?}
  518. */
  519. getAll(name) {
  520. if (this.has(name)) {
  521. const /** @type {?} */ v = this.params[name];
  522. return Array.isArray(v) ? v : [v];
  523. }
  524. return [];
  525. }
  526. /**
  527. * @return {?}
  528. */
  529. get keys() { return Object.keys(this.params); }
  530. }
  531. /**
  532. * Convert a `Params` instance to a `ParamMap`.
  533. *
  534. *
  535. * @param {?} params
  536. * @return {?}
  537. */
  538. function convertToParamMap(params) {
  539. return new ParamsAsMap(params);
  540. }
  541. const /** @type {?} */ NAVIGATION_CANCELING_ERROR = 'ngNavigationCancelingError';
  542. /**
  543. * @param {?} message
  544. * @return {?}
  545. */
  546. function navigationCancelingError(message) {
  547. const /** @type {?} */ error = Error('NavigationCancelingError: ' + message);
  548. (/** @type {?} */ (error))[NAVIGATION_CANCELING_ERROR] = true;
  549. return error;
  550. }
  551. /**
  552. * @param {?} error
  553. * @return {?}
  554. */
  555. function isNavigationCancelingError(error) {
  556. return error && (/** @type {?} */ (error))[NAVIGATION_CANCELING_ERROR];
  557. }
  558. /**
  559. * @param {?} segments
  560. * @param {?} segmentGroup
  561. * @param {?} route
  562. * @return {?}
  563. */
  564. function defaultUrlMatcher(segments, segmentGroup, route) {
  565. const /** @type {?} */ parts = /** @type {?} */ ((route.path)).split('/');
  566. if (parts.length > segments.length) {
  567. // The actual URL is shorter than the config, no match
  568. return null;
  569. }
  570. if (route.pathMatch === 'full' &&
  571. (segmentGroup.hasChildren() || parts.length < segments.length)) {
  572. // The config is longer than the actual URL but we are looking for a full match, return null
  573. return null;
  574. }
  575. const /** @type {?} */ posParams = {};
  576. // Check each config part against the actual URL
  577. for (let /** @type {?} */ index = 0; index < parts.length; index++) {
  578. const /** @type {?} */ part = parts[index];
  579. const /** @type {?} */ segment = segments[index];
  580. const /** @type {?} */ isParameter = part.startsWith(':');
  581. if (isParameter) {
  582. posParams[part.substring(1)] = segment;
  583. }
  584. else if (part !== segment.path) {
  585. // The actual URL part does not match the config, no match
  586. return null;
  587. }
  588. }
  589. return { consumed: segments.slice(0, parts.length), posParams };
  590. }
  591. /**
  592. * @fileoverview added by tsickle
  593. * @suppress {checkTypes} checked by tsc
  594. */
  595. class LoadedRouterConfig {
  596. /**
  597. * @param {?} routes
  598. * @param {?} module
  599. */
  600. constructor(routes, module) {
  601. this.routes = routes;
  602. this.module = module;
  603. }
  604. }
  605. /**
  606. * @param {?} config
  607. * @param {?=} parentPath
  608. * @return {?}
  609. */
  610. function validateConfig(config, parentPath = '') {
  611. // forEach doesn't iterate undefined values
  612. for (let /** @type {?} */ i = 0; i < config.length; i++) {
  613. const /** @type {?} */ route = config[i];
  614. const /** @type {?} */ fullPath = getFullPath(parentPath, route);
  615. validateNode(route, fullPath);
  616. }
  617. }
  618. /**
  619. * @param {?} route
  620. * @param {?} fullPath
  621. * @return {?}
  622. */
  623. function validateNode(route, fullPath) {
  624. if (!route) {
  625. throw new Error(`
  626. Invalid configuration of route '${fullPath}': Encountered undefined route.
  627. The reason might be an extra comma.
  628. Example:
  629. const routes: Routes = [
  630. { path: '', redirectTo: '/dashboard', pathMatch: 'full' },
  631. { path: 'dashboard', component: DashboardComponent },, << two commas
  632. { path: 'detail/:id', component: HeroDetailComponent }
  633. ];
  634. `);
  635. }
  636. if (Array.isArray(route)) {
  637. throw new Error(`Invalid configuration of route '${fullPath}': Array cannot be specified`);
  638. }
  639. if (!route.component && !route.children && !route.loadChildren &&
  640. (route.outlet && route.outlet !== PRIMARY_OUTLET)) {
  641. throw new Error(`Invalid configuration of route '${fullPath}': a componentless route without children or loadChildren cannot have a named outlet set`);
  642. }
  643. if (route.redirectTo && route.children) {
  644. throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and children cannot be used together`);
  645. }
  646. if (route.redirectTo && route.loadChildren) {
  647. throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and loadChildren cannot be used together`);
  648. }
  649. if (route.children && route.loadChildren) {
  650. throw new Error(`Invalid configuration of route '${fullPath}': children and loadChildren cannot be used together`);
  651. }
  652. if (route.redirectTo && route.component) {
  653. throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and component cannot be used together`);
  654. }
  655. if (route.path && route.matcher) {
  656. throw new Error(`Invalid configuration of route '${fullPath}': path and matcher cannot be used together`);
  657. }
  658. if (route.redirectTo === void 0 && !route.component && !route.children && !route.loadChildren) {
  659. throw new Error(`Invalid configuration of route '${fullPath}'. One of the following must be provided: component, redirectTo, children or loadChildren`);
  660. }
  661. if (route.path === void 0 && route.matcher === void 0) {
  662. throw new Error(`Invalid configuration of route '${fullPath}': routes must have either a path or a matcher specified`);
  663. }
  664. if (typeof route.path === 'string' && route.path.charAt(0) === '/') {
  665. throw new Error(`Invalid configuration of route '${fullPath}': path cannot start with a slash`);
  666. }
  667. if (route.path === '' && route.redirectTo !== void 0 && route.pathMatch === void 0) {
  668. const /** @type {?} */ exp = `The default value of 'pathMatch' is 'prefix', but often the intent is to use 'full'.`;
  669. throw new Error(`Invalid configuration of route '{path: "${fullPath}", redirectTo: "${route.redirectTo}"}': please provide 'pathMatch'. ${exp}`);
  670. }
  671. if (route.pathMatch !== void 0 && route.pathMatch !== 'full' && route.pathMatch !== 'prefix') {
  672. throw new Error(`Invalid configuration of route '${fullPath}': pathMatch can only be set to 'prefix' or 'full'`);
  673. }
  674. if (route.children) {
  675. validateConfig(route.children, fullPath);
  676. }
  677. }
  678. /**
  679. * @param {?} parentPath
  680. * @param {?} currentRoute
  681. * @return {?}
  682. */
  683. function getFullPath(parentPath, currentRoute) {
  684. if (!currentRoute) {
  685. return parentPath;
  686. }
  687. if (!parentPath && !currentRoute.path) {
  688. return '';
  689. }
  690. else if (parentPath && !currentRoute.path) {
  691. return `${parentPath}/`;
  692. }
  693. else if (!parentPath && currentRoute.path) {
  694. return currentRoute.path;
  695. }
  696. else {
  697. return `${parentPath}/${currentRoute.path}`;
  698. }
  699. }
  700. /**
  701. * Makes a copy of the config and adds any default required properties.
  702. * @param {?} r
  703. * @return {?}
  704. */
  705. function standardizeConfig(r) {
  706. const /** @type {?} */ children = r.children && r.children.map(standardizeConfig);
  707. const /** @type {?} */ c = children ? Object.assign({}, r, { children }) : Object.assign({}, r);
  708. if (!c.component && (children || c.loadChildren) && (c.outlet && c.outlet !== PRIMARY_OUTLET)) {
  709. c.component = EmptyOutletComponent;
  710. }
  711. return c;
  712. }
  713. /**
  714. * @fileoverview added by tsickle
  715. * @suppress {checkTypes} checked by tsc
  716. */
  717. /**
  718. * @param {?} a
  719. * @param {?} b
  720. * @return {?}
  721. */
  722. function shallowEqualArrays(a, b) {
  723. if (a.length !== b.length)
  724. return false;
  725. for (let /** @type {?} */ i = 0; i < a.length; ++i) {
  726. if (!shallowEqual(a[i], b[i]))
  727. return false;
  728. }
  729. return true;
  730. }
  731. /**
  732. * @param {?} a
  733. * @param {?} b
  734. * @return {?}
  735. */
  736. function shallowEqual(a, b) {
  737. const /** @type {?} */ k1 = Object.keys(a);
  738. const /** @type {?} */ k2 = Object.keys(b);
  739. if (k1.length != k2.length) {
  740. return false;
  741. }
  742. let /** @type {?} */ key;
  743. for (let /** @type {?} */ i = 0; i < k1.length; i++) {
  744. key = k1[i];
  745. if (a[key] !== b[key]) {
  746. return false;
  747. }
  748. }
  749. return true;
  750. }
  751. /**
  752. * Flattens single-level nested arrays.
  753. * @template T
  754. * @param {?} arr
  755. * @return {?}
  756. */
  757. function flatten(arr) {
  758. return Array.prototype.concat.apply([], arr);
  759. }
  760. /**
  761. * Return the last element of an array.
  762. * @template T
  763. * @param {?} a
  764. * @return {?}
  765. */
  766. function last$1(a) {
  767. return a.length > 0 ? a[a.length - 1] : null;
  768. }
  769. /**
  770. * @template K, V
  771. * @param {?} map
  772. * @param {?} callback
  773. * @return {?}
  774. */
  775. function forEach(map$$1, callback) {
  776. for (const /** @type {?} */ prop in map$$1) {
  777. if (map$$1.hasOwnProperty(prop)) {
  778. callback(map$$1[prop], prop);
  779. }
  780. }
  781. }
  782. /**
  783. * @template A, B
  784. * @param {?} obj
  785. * @param {?} fn
  786. * @return {?}
  787. */
  788. function waitForMap(obj, fn) {
  789. if (Object.keys(obj).length === 0) {
  790. return of({});
  791. }
  792. const /** @type {?} */ waitHead = [];
  793. const /** @type {?} */ waitTail = [];
  794. const /** @type {?} */ res = {};
  795. forEach(obj, (a, k) => {
  796. const /** @type {?} */ mapped = fn(k, a).pipe(map((r) => res[k] = r));
  797. if (k === PRIMARY_OUTLET) {
  798. waitHead.push(mapped);
  799. }
  800. else {
  801. waitTail.push(mapped);
  802. }
  803. });
  804. // Closure compiler has problem with using spread operator here. So just using Array.concat.
  805. return of.apply(null, waitHead.concat(waitTail)).pipe(concatAll(), last(), map(() => res));
  806. }
  807. /**
  808. * ANDs Observables by merging all input observables, reducing to an Observable verifying all
  809. * input Observables return `true`.
  810. * @param {?} observables
  811. * @return {?}
  812. */
  813. function andObservables(observables) {
  814. return observables.pipe(mergeAll(), every((result) => result === true));
  815. }
  816. /**
  817. * @template T
  818. * @param {?} value
  819. * @return {?}
  820. */
  821. function wrapIntoObservable(value) {
  822. if (ɵisObservable(value)) {
  823. return value;
  824. }
  825. if (ɵisPromise(value)) {
  826. // Use `Promise.resolve()` to wrap promise-like instances.
  827. // Required ie when a Resolver returns a AngularJS `$q` promise to correctly trigger the
  828. // change detection.
  829. return from(Promise.resolve(value));
  830. }
  831. return of(/** @type {?} */ (value));
  832. }
  833. /**
  834. * @fileoverview added by tsickle
  835. * @suppress {checkTypes} checked by tsc
  836. */
  837. /**
  838. * @return {?}
  839. */
  840. function createEmptyUrlTree() {
  841. return new UrlTree(new UrlSegmentGroup([], {}), {}, null);
  842. }
  843. /**
  844. * @param {?} container
  845. * @param {?} containee
  846. * @param {?} exact
  847. * @return {?}
  848. */
  849. function containsTree(container, containee, exact) {
  850. if (exact) {
  851. return equalQueryParams(container.queryParams, containee.queryParams) &&
  852. equalSegmentGroups(container.root, containee.root);
  853. }
  854. return containsQueryParams(container.queryParams, containee.queryParams) &&
  855. containsSegmentGroup(container.root, containee.root);
  856. }
  857. /**
  858. * @param {?} container
  859. * @param {?} containee
  860. * @return {?}
  861. */
  862. function equalQueryParams(container, containee) {
  863. return shallowEqual(container, containee);
  864. }
  865. /**
  866. * @param {?} container
  867. * @param {?} containee
  868. * @return {?}
  869. */
  870. function equalSegmentGroups(container, containee) {
  871. if (!equalPath(container.segments, containee.segments))
  872. return false;
  873. if (container.numberOfChildren !== containee.numberOfChildren)
  874. return false;
  875. for (const /** @type {?} */ c in containee.children) {
  876. if (!container.children[c])
  877. return false;
  878. if (!equalSegmentGroups(container.children[c], containee.children[c]))
  879. return false;
  880. }
  881. return true;
  882. }
  883. /**
  884. * @param {?} container
  885. * @param {?} containee
  886. * @return {?}
  887. */
  888. function containsQueryParams(container, containee) {
  889. return Object.keys(containee).length <= Object.keys(container).length &&
  890. Object.keys(containee).every(key => containee[key] === container[key]);
  891. }
  892. /**
  893. * @param {?} container
  894. * @param {?} containee
  895. * @return {?}
  896. */
  897. function containsSegmentGroup(container, containee) {
  898. return containsSegmentGroupHelper(container, containee, containee.segments);
  899. }
  900. /**
  901. * @param {?} container
  902. * @param {?} containee
  903. * @param {?} containeePaths
  904. * @return {?}
  905. */
  906. function containsSegmentGroupHelper(container, containee, containeePaths) {
  907. if (container.segments.length > containeePaths.length) {
  908. const /** @type {?} */ current = container.segments.slice(0, containeePaths.length);
  909. if (!equalPath(current, containeePaths))
  910. return false;
  911. if (containee.hasChildren())
  912. return false;
  913. return true;
  914. }
  915. else if (container.segments.length === containeePaths.length) {
  916. if (!equalPath(container.segments, containeePaths))
  917. return false;
  918. for (const /** @type {?} */ c in containee.children) {
  919. if (!container.children[c])
  920. return false;
  921. if (!containsSegmentGroup(container.children[c], containee.children[c]))
  922. return false;
  923. }
  924. return true;
  925. }
  926. else {
  927. const /** @type {?} */ current = containeePaths.slice(0, container.segments.length);
  928. const /** @type {?} */ next = containeePaths.slice(container.segments.length);
  929. if (!equalPath(container.segments, current))
  930. return false;
  931. if (!container.children[PRIMARY_OUTLET])
  932. return false;
  933. return containsSegmentGroupHelper(container.children[PRIMARY_OUTLET], containee, next);
  934. }
  935. }
  936. /**
  937. * \@description
  938. *
  939. * Represents the parsed URL.
  940. *
  941. * Since a router state is a tree, and the URL is nothing but a serialized state, the URL is a
  942. * serialized tree.
  943. * UrlTree is a data structure that provides a lot of affordances in dealing with URLs
  944. *
  945. * ### Example
  946. *
  947. * ```
  948. * \@Component({templateUrl:'template.html'})
  949. * class MyComponent {
  950. * constructor(router: Router) {
  951. * const tree: UrlTree =
  952. * router.parseUrl('/team/33/(user/victor//support:help)?debug=true#fragment');
  953. * const f = tree.fragment; // return 'fragment'
  954. * const q = tree.queryParams; // returns {debug: 'true'}
  955. * const g: UrlSegmentGroup = tree.root.children[PRIMARY_OUTLET];
  956. * const s: UrlSegment[] = g.segments; // returns 2 segments 'team' and '33'
  957. * g.children[PRIMARY_OUTLET].segments; // returns 2 segments 'user' and 'victor'
  958. * g.children['support'].segments; // return 1 segment 'help'
  959. * }
  960. * }
  961. * ```
  962. *
  963. *
  964. */
  965. class UrlTree {
  966. /**
  967. * \@internal
  968. * @param {?} root
  969. * @param {?} queryParams
  970. * @param {?} fragment
  971. */
  972. constructor(root, queryParams, fragment) {
  973. this.root = root;
  974. this.queryParams = queryParams;
  975. this.fragment = fragment;
  976. }
  977. /**
  978. * @return {?}
  979. */
  980. get queryParamMap() {
  981. if (!this._queryParamMap) {
  982. this._queryParamMap = convertToParamMap(this.queryParams);
  983. }
  984. return this._queryParamMap;
  985. }
  986. /**
  987. * \@docsNotRequired
  988. * @return {?}
  989. */
  990. toString() { return DEFAULT_SERIALIZER.serialize(this); }
  991. }
  992. /**
  993. * \@description
  994. *
  995. * Represents the parsed URL segment group.
  996. *
  997. * See `UrlTree` for more information.
  998. *
  999. *
  1000. */
  1001. class UrlSegmentGroup {
  1002. /**
  1003. * @param {?} segments
  1004. * @param {?} children
  1005. */
  1006. constructor(segments, children) {
  1007. this.segments = segments;
  1008. this.children = children;
  1009. /**
  1010. * The parent node in the url tree
  1011. */
  1012. this.parent = null;
  1013. forEach(children, (v, k) => v.parent = this);
  1014. }
  1015. /**
  1016. * Whether the segment has child segments
  1017. * @return {?}
  1018. */
  1019. hasChildren() { return this.numberOfChildren > 0; }
  1020. /**
  1021. * Number of child segments
  1022. * @return {?}
  1023. */
  1024. get numberOfChildren() { return Object.keys(this.children).length; }
  1025. /**
  1026. * \@docsNotRequired
  1027. * @return {?}
  1028. */
  1029. toString() { return serializePaths(this); }
  1030. }
  1031. /**
  1032. * \@description
  1033. *
  1034. * Represents a single URL segment.
  1035. *
  1036. * A UrlSegment is a part of a URL between the two slashes. It contains a path and the matrix
  1037. * parameters associated with the segment.
  1038. *
  1039. *  ## Example
  1040. *
  1041. * ```
  1042. * \@Component({templateUrl:'template.html'})
  1043. * class MyComponent {
  1044. * constructor(router: Router) {
  1045. * const tree: UrlTree = router.parseUrl('/team;id=33');
  1046. * const g: UrlSegmentGroup = tree.root.children[PRIMARY_OUTLET];
  1047. * const s: UrlSegment[] = g.segments;
  1048. * s[0].path; // returns 'team'
  1049. * s[0].parameters; // returns {id: 33}
  1050. * }
  1051. * }
  1052. * ```
  1053. *
  1054. *
  1055. */
  1056. class UrlSegment {
  1057. /**
  1058. * @param {?} path
  1059. * @param {?} parameters
  1060. */
  1061. constructor(path, parameters) {
  1062. this.path = path;
  1063. this.parameters = parameters;
  1064. }
  1065. /**
  1066. * @return {?}
  1067. */
  1068. get parameterMap() {
  1069. if (!this._parameterMap) {
  1070. this._parameterMap = convertToParamMap(this.parameters);
  1071. }
  1072. return this._parameterMap;
  1073. }
  1074. /**
  1075. * \@docsNotRequired
  1076. * @return {?}
  1077. */
  1078. toString() { return serializePath(this); }
  1079. }
  1080. /**
  1081. * @param {?} as
  1082. * @param {?} bs
  1083. * @return {?}
  1084. */
  1085. function equalSegments(as, bs) {
  1086. return equalPath(as, bs) && as.every((a, i) => shallowEqual(a.parameters, bs[i].parameters));
  1087. }
  1088. /**
  1089. * @param {?} as
  1090. * @param {?} bs
  1091. * @return {?}
  1092. */
  1093. function equalPath(as, bs) {
  1094. if (as.length !== bs.length)
  1095. return false;
  1096. return as.every((a, i) => a.path === bs[i].path);
  1097. }
  1098. /**
  1099. * @template T
  1100. * @param {?} segment
  1101. * @param {?} fn
  1102. * @return {?}
  1103. */
  1104. function mapChildrenIntoArray(segment, fn) {
  1105. let /** @type {?} */ res = [];
  1106. forEach(segment.children, (child, childOutlet) => {
  1107. if (childOutlet === PRIMARY_OUTLET) {
  1108. res = res.concat(fn(child, childOutlet));
  1109. }
  1110. });
  1111. forEach(segment.children, (child, childOutlet) => {
  1112. if (childOutlet !== PRIMARY_OUTLET) {
  1113. res = res.concat(fn(child, childOutlet));
  1114. }
  1115. });
  1116. return res;
  1117. }
  1118. /**
  1119. * \@description
  1120. *
  1121. * Serializes and deserializes a URL string into a URL tree.
  1122. *
  1123. * The url serialization strategy is customizable. You can
  1124. * make all URLs case insensitive by providing a custom UrlSerializer.
  1125. *
  1126. * See `DefaultUrlSerializer` for an example of a URL serializer.
  1127. *
  1128. *
  1129. * @abstract
  1130. */
  1131. class UrlSerializer {
  1132. }
  1133. /**
  1134. * \@description
  1135. *
  1136. * A default implementation of the `UrlSerializer`.
  1137. *
  1138. * Example URLs:
  1139. *
  1140. * ```
  1141. * /inbox/33(popup:compose)
  1142. * /inbox/33;open=true/messages/44
  1143. * ```
  1144. *
  1145. * DefaultUrlSerializer uses parentheses to serialize secondary segments (e.g., popup:compose), the
  1146. * colon syntax to specify the outlet, and the ';parameter=value' syntax (e.g., open=true) to
  1147. * specify route specific parameters.
  1148. *
  1149. *
  1150. */
  1151. class DefaultUrlSerializer {
  1152. /**
  1153. * Parses a url into a `UrlTree`
  1154. * @param {?} url
  1155. * @return {?}
  1156. */
  1157. parse(url) {
  1158. const /** @type {?} */ p = new UrlParser(url);
  1159. return new UrlTree(p.parseRootSegment(), p.parseQueryParams(), p.parseFragment());
  1160. }
  1161. /**
  1162. * Converts a `UrlTree` into a url
  1163. * @param {?} tree
  1164. * @return {?}
  1165. */
  1166. serialize(tree) {
  1167. const /** @type {?} */ segment = `/${serializeSegment(tree.root, true)}`;
  1168. const /** @type {?} */ query = serializeQueryParams(tree.queryParams);
  1169. const /** @type {?} */ fragment = typeof tree.fragment === `string` ? `#${encodeUriFragment((/** @type {?} */ ((tree.fragment))))}` : '';
  1170. return `${segment}${query}${fragment}`;
  1171. }
  1172. }
  1173. const /** @type {?} */ DEFAULT_SERIALIZER = new DefaultUrlSerializer();
  1174. /**
  1175. * @param {?} segment
  1176. * @return {?}
  1177. */
  1178. function serializePaths(segment) {
  1179. return segment.segments.map(p => serializePath(p)).join('/');
  1180. }
  1181. /**
  1182. * @param {?} segment
  1183. * @param {?} root
  1184. * @return {?}
  1185. */
  1186. function serializeSegment(segment, root) {
  1187. if (!segment.hasChildren()) {
  1188. return serializePaths(segment);
  1189. }
  1190. if (root) {
  1191. const /** @type {?} */ primary = segment.children[PRIMARY_OUTLET] ?
  1192. serializeSegment(segment.children[PRIMARY_OUTLET], false) :
  1193. '';
  1194. const /** @type {?} */ children = [];
  1195. forEach(segment.children, (v, k) => {
  1196. if (k !== PRIMARY_OUTLET) {
  1197. children.push(`${k}:${serializeSegment(v, false)}`);
  1198. }
  1199. });
  1200. return children.length > 0 ? `${primary}(${children.join('//')})` : primary;
  1201. }
  1202. else {
  1203. const /** @type {?} */ children = mapChildrenIntoArray(segment, (v, k) => {
  1204. if (k === PRIMARY_OUTLET) {
  1205. return [serializeSegment(segment.children[PRIMARY_OUTLET], false)];
  1206. }
  1207. return [`${k}:${serializeSegment(v, false)}`];
  1208. });
  1209. return `${serializePaths(segment)}/(${children.join('//')})`;
  1210. }
  1211. }
  1212. /**
  1213. * Encodes a URI string with the default encoding. This function will only ever be called from
  1214. * `encodeUriQuery` or `encodeUriSegment` as it's the base set of encodings to be used. We need
  1215. * a custom encoding because encodeURIComponent is too aggressive and encodes stuff that doesn't
  1216. * have to be encoded per https://url.spec.whatwg.org.
  1217. * @param {?} s
  1218. * @return {?}
  1219. */
  1220. function encodeUriString(s) {
  1221. return encodeURIComponent(s)
  1222. .replace(/%40/g, '@')
  1223. .replace(/%3A/gi, ':')
  1224. .replace(/%24/g, '$')
  1225. .replace(/%2C/gi, ',');
  1226. }
  1227. /**
  1228. * This function should be used to encode both keys and values in a query string key/value. In
  1229. * the following URL, you need to call encodeUriQuery on "k" and "v":
  1230. *
  1231. * http://www.site.org/html;mk=mv?k=v#f
  1232. * @param {?} s
  1233. * @return {?}
  1234. */
  1235. function encodeUriQuery(s) {
  1236. return encodeUriString(s).replace(/%3B/gi, ';');
  1237. }
  1238. /**
  1239. * This function should be used to encode a URL fragment. In the following URL, you need to call
  1240. * encodeUriFragment on "f":
  1241. *
  1242. * http://www.site.org/html;mk=mv?k=v#f
  1243. * @param {?} s
  1244. * @return {?}
  1245. */
  1246. function encodeUriFragment(s) {
  1247. return encodeURI(s);
  1248. }
  1249. /**
  1250. * This function should be run on any URI segment as well as the key and value in a key/value
  1251. * pair for matrix params. In the following URL, you need to call encodeUriSegment on "html",
  1252. * "mk", and "mv":
  1253. *
  1254. * http://www.site.org/html;mk=mv?k=v#f
  1255. * @param {?} s
  1256. * @return {?}
  1257. */
  1258. function encodeUriSegment(s) {
  1259. return encodeUriString(s).replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/%26/gi, '&');
  1260. }
  1261. /**
  1262. * @param {?} s
  1263. * @return {?}
  1264. */
  1265. function decode(s) {
  1266. return decodeURIComponent(s);
  1267. }
  1268. /**
  1269. * @param {?} s
  1270. * @return {?}
  1271. */
  1272. function decodeQuery(s) {
  1273. return decode(s.replace(/\+/g, '%20'));
  1274. }
  1275. /**
  1276. * @param {?} path
  1277. * @return {?}
  1278. */
  1279. function serializePath(path) {
  1280. return `${encodeUriSegment(path.path)}${serializeMatrixParams(path.parameters)}`;
  1281. }
  1282. /**
  1283. * @param {?} params
  1284. * @return {?}
  1285. */
  1286. function serializeMatrixParams(params) {
  1287. return Object.keys(params)
  1288. .map(key => `;${encodeUriSegment(key)}=${encodeUriSegment(params[key])}`)
  1289. .join('');
  1290. }
  1291. /**
  1292. * @param {?} params
  1293. * @return {?}
  1294. */
  1295. function serializeQueryParams(params) {
  1296. const /** @type {?} */ strParams = Object.keys(params).map((name) => {
  1297. const /** @type {?} */ value = params[name];
  1298. return Array.isArray(value) ?
  1299. value.map(v => `${encodeUriQuery(name)}=${encodeUriQuery(v)}`).join('&') :
  1300. `${encodeUriQuery(name)}=${encodeUriQuery(value)}`;
  1301. });
  1302. return strParams.length ? `?${strParams.join("&")}` : '';
  1303. }
  1304. const /** @type {?} */ SEGMENT_RE = /^[^\/()?;=#]+/;
  1305. /**
  1306. * @param {?} str
  1307. * @return {?}
  1308. */
  1309. function matchSegments(str) {
  1310. const /** @type {?} */ match = str.match(SEGMENT_RE);
  1311. return match ? match[0] : '';
  1312. }
  1313. const /** @type {?} */ QUERY_PARAM_RE = /^[^=?&#]+/;
  1314. /**
  1315. * @param {?} str
  1316. * @return {?}
  1317. */
  1318. function matchQueryParams(str) {
  1319. const /** @type {?} */ match = str.match(QUERY_PARAM_RE);
  1320. return match ? match[0] : '';
  1321. }
  1322. const /** @type {?} */ QUERY_PARAM_VALUE_RE = /^[^?&#]+/;
  1323. /**
  1324. * @param {?} str
  1325. * @return {?}
  1326. */
  1327. function matchUrlQueryParamValue(str) {
  1328. const /** @type {?} */ match = str.match(QUERY_PARAM_VALUE_RE);
  1329. return match ? match[0] : '';
  1330. }
  1331. class UrlParser {
  1332. /**
  1333. * @param {?} url
  1334. */
  1335. constructor(url) {
  1336. this.url = url;
  1337. this.remaining = url;
  1338. }
  1339. /**
  1340. * @return {?}
  1341. */
  1342. parseRootSegment() {
  1343. this.consumeOptional('/');
  1344. if (this.remaining === '' || this.peekStartsWith('?') || this.peekStartsWith('#')) {
  1345. return new UrlSegmentGroup([], {});
  1346. }
  1347. // The root segment group never has segments
  1348. return new UrlSegmentGroup([], this.parseChildren());
  1349. }
  1350. /**
  1351. * @return {?}
  1352. */
  1353. parseQueryParams() {
  1354. const /** @type {?} */ params = {};
  1355. if (this.consumeOptional('?')) {
  1356. do {
  1357. this.parseQueryParam(params);
  1358. } while (this.consumeOptional('&'));
  1359. }
  1360. return params;
  1361. }
  1362. /**
  1363. * @return {?}
  1364. */
  1365. parseFragment() {
  1366. return this.consumeOptional('#') ? decodeURIComponent(this.remaining) : null;
  1367. }
  1368. /**
  1369. * @return {?}
  1370. */
  1371. parseChildren() {
  1372. if (this.remaining === '') {
  1373. return {};
  1374. }
  1375. this.consumeOptional('/');
  1376. const /** @type {?} */ segments = [];
  1377. if (!this.peekStartsWith('(')) {
  1378. segments.push(this.parseSegment());
  1379. }
  1380. while (this.peekStartsWith('/') && !this.peekStartsWith('//') && !this.peekStartsWith('/(')) {
  1381. this.capture('/');
  1382. segments.push(this.parseSegment());
  1383. }
  1384. let /** @type {?} */ children = {};
  1385. if (this.peekStartsWith('/(')) {
  1386. this.capture('/');
  1387. children = this.parseParens(true);
  1388. }
  1389. let /** @type {?} */ res = {};
  1390. if (this.peekStartsWith('(')) {
  1391. res = this.parseParens(false);
  1392. }
  1393. if (segments.length > 0 || Object.keys(children).length > 0) {
  1394. res[PRIMARY_OUTLET] = new UrlSegmentGroup(segments, children);
  1395. }
  1396. return res;
  1397. }
  1398. /**
  1399. * @return {?}
  1400. */
  1401. parseSegment() {
  1402. const /** @type {?} */ path = matchSegments(this.remaining);
  1403. if (path === '' && this.peekStartsWith(';')) {
  1404. throw new Error(`Empty path url segment cannot have parameters: '${this.remaining}'.`);
  1405. }
  1406. this.capture(path);
  1407. return new UrlSegment(decode(path), this.parseMatrixParams());
  1408. }
  1409. /**
  1410. * @return {?}
  1411. */
  1412. parseMatrixParams() {
  1413. const /** @type {?} */ params = {};
  1414. while (this.consumeOptional(';')) {
  1415. this.parseParam(params);
  1416. }
  1417. return params;
  1418. }
  1419. /**
  1420. * @param {?} params
  1421. * @return {?}
  1422. */
  1423. parseParam(params) {
  1424. const /** @type {?} */ key = matchSegments(this.remaining);
  1425. if (!key) {
  1426. return;
  1427. }
  1428. this.capture(key);
  1429. let /** @type {?} */ value = '';
  1430. if (this.consumeOptional('=')) {
  1431. const /** @type {?} */ valueMatch = matchSegments(this.remaining);
  1432. if (valueMatch) {
  1433. value = valueMatch;
  1434. this.capture(value);
  1435. }
  1436. }
  1437. params[decode(key)] = decode(value);
  1438. }
  1439. /**
  1440. * @param {?} params
  1441. * @return {?}
  1442. */
  1443. parseQueryParam(params) {
  1444. const /** @type {?} */ key = matchQueryParams(this.remaining);
  1445. if (!key) {
  1446. return;
  1447. }
  1448. this.capture(key);
  1449. let /** @type {?} */ value = '';
  1450. if (this.consumeOptional('=')) {
  1451. const /** @type {?} */ valueMatch = matchUrlQueryParamValue(this.remaining);
  1452. if (valueMatch) {
  1453. value = valueMatch;
  1454. this.capture(value);
  1455. }
  1456. }
  1457. const /** @type {?} */ decodedKey = decodeQuery(key);
  1458. const /** @type {?} */ decodedVal = decodeQuery(value);
  1459. if (params.hasOwnProperty(decodedKey)) {
  1460. // Append to existing values
  1461. let /** @type {?} */ currentVal = params[decodedKey];
  1462. if (!Array.isArray(currentVal)) {
  1463. currentVal = [currentVal];
  1464. params[decodedKey] = currentVal;
  1465. }
  1466. currentVal.push(decodedVal);
  1467. }
  1468. else {
  1469. // Create a new value
  1470. params[decodedKey] = decodedVal;
  1471. }
  1472. }
  1473. /**
  1474. * @param {?} allowPrimary
  1475. * @return {?}
  1476. */
  1477. parseParens(allowPrimary) {
  1478. const /** @type {?} */ segments = {};
  1479. this.capture('(');
  1480. while (!this.consumeOptional(')') && this.remaining.length > 0) {
  1481. const /** @type {?} */ path = matchSegments(this.remaining);
  1482. const /** @type {?} */ next = this.remaining[path.length];
  1483. // if is is not one of these characters, then the segment was unescaped
  1484. // or the group was not closed
  1485. if (next !== '/' && next !== ')' && next !== ';') {
  1486. throw new Error(`Cannot parse url '${this.url}'`);
  1487. }
  1488. let /** @type {?} */ outletName = /** @type {?} */ ((undefined));
  1489. if (path.indexOf(':') > -1) {
  1490. outletName = path.substr(0, path.indexOf(':'));
  1491. this.capture(outletName);
  1492. this.capture(':');
  1493. }
  1494. else if (allowPrimary) {
  1495. outletName = PRIMARY_OUTLET;
  1496. }
  1497. const /** @type {?} */ children = this.parseChildren();
  1498. segments[outletName] = Object.keys(children).length === 1 ? children[PRIMARY_OUTLET] :
  1499. new UrlSegmentGroup([], children);
  1500. this.consumeOptional('//');
  1501. }
  1502. return segments;
  1503. }
  1504. /**
  1505. * @param {?} str
  1506. * @return {?}
  1507. */
  1508. peekStartsWith(str) { return this.remaining.startsWith(str); }
  1509. /**
  1510. * @param {?} str
  1511. * @return {?}
  1512. */
  1513. consumeOptional(str) {
  1514. if (this.peekStartsWith(str)) {
  1515. this.remaining = this.remaining.substring(str.length);
  1516. return true;
  1517. }
  1518. return false;
  1519. }
  1520. /**
  1521. * @param {?} str
  1522. * @return {?}
  1523. */
  1524. capture(str) {
  1525. if (!this.consumeOptional(str)) {
  1526. throw new Error(`Expected "${str}".`);
  1527. }
  1528. }
  1529. }
  1530. /**
  1531. * @fileoverview added by tsickle
  1532. * @suppress {checkTypes} checked by tsc
  1533. */
  1534. class NoMatch {
  1535. /**
  1536. * @param {?=} segmentGroup
  1537. */
  1538. constructor(segmentGroup) { this.segmentGroup = segmentGroup || null; }
  1539. }
  1540. class AbsoluteRedirect {
  1541. /**
  1542. * @param {?} urlTree
  1543. */
  1544. constructor(urlTree) {
  1545. this.urlTree = urlTree;
  1546. }
  1547. }
  1548. /**
  1549. * @param {?} segmentGroup
  1550. * @return {?}
  1551. */
  1552. function noMatch(segmentGroup) {
  1553. return new Observable((obs) => obs.error(new NoMatch(segmentGroup)));
  1554. }
  1555. /**
  1556. * @param {?} newTree
  1557. * @return {?}
  1558. */
  1559. function absoluteRedirect(newTree) {
  1560. return new Observable((obs) => obs.error(new AbsoluteRedirect(newTree)));
  1561. }
  1562. /**
  1563. * @param {?} redirectTo
  1564. * @return {?}
  1565. */
  1566. function namedOutletsRedirect(redirectTo) {
  1567. return new Observable((obs) => obs.error(new Error(`Only absolute redirects can have named outlets. redirectTo: '${redirectTo}'`)));
  1568. }
  1569. /**
  1570. * @param {?} route
  1571. * @return {?}
  1572. */
  1573. function canLoadFails(route) {
  1574. return new Observable((obs) => obs.error(navigationCancelingError(`Cannot load children because the guard of the route "path: '${route.path}'" returned false`)));
  1575. }
  1576. /**
  1577. * Returns the `UrlTree` with the redirection applied.
  1578. *
  1579. * Lazy modules are loaded along the way.
  1580. * @param {?} moduleInjector
  1581. * @param {?} configLoader
  1582. * @param {?} urlSerializer
  1583. * @param {?} urlTree
  1584. * @param {?} config
  1585. * @return {?}
  1586. */
  1587. function applyRedirects(moduleInjector, configLoader, urlSerializer, urlTree, config) {
  1588. return new ApplyRedirects(moduleInjector, configLoader, urlSerializer, urlTree, config).apply();
  1589. }
  1590. class ApplyRedirects {
  1591. /**
  1592. * @param {?} moduleInjector
  1593. * @param {?} configLoader
  1594. * @param {?} urlSerializer
  1595. * @param {?} urlTree
  1596. * @param {?} config
  1597. */
  1598. constructor(moduleInjector, configLoader, urlSerializer, urlTree, config) {
  1599. this.configLoader = configLoader;
  1600. this.urlSerializer = urlSerializer;
  1601. this.urlTree = urlTree;
  1602. this.config = config;
  1603. this.allowRedirects = true;
  1604. this.ngModule = moduleInjector.get(NgModuleRef);
  1605. }
  1606. /**
  1607. * @return {?}
  1608. */
  1609. apply() {
  1610. const /** @type {?} */ expanded$ = this.expandSegmentGroup(this.ngModule, this.config, this.urlTree.root, PRIMARY_OUTLET);
  1611. const /** @type {?} */ urlTrees$ = expanded$.pipe(map((rootSegmentGroup) => this.createUrlTree(rootSegmentGroup, this.urlTree.queryParams, /** @type {?} */ ((this.urlTree.fragment)))));
  1612. return urlTrees$.pipe(catchError((e) => {
  1613. if (e instanceof AbsoluteRedirect) {
  1614. // after an absolute redirect we do not apply any more redirects!
  1615. this.allowRedirects = false;
  1616. // we need to run matching, so we can fetch all lazy-loaded modules
  1617. return this.match(e.urlTree);
  1618. }
  1619. if (e instanceof NoMatch) {
  1620. throw this.noMatchError(e);
  1621. }
  1622. throw e;
  1623. }));
  1624. }
  1625. /**
  1626. * @param {?} tree
  1627. * @return {?}
  1628. */
  1629. match(tree) {
  1630. const /** @type {?} */ expanded$ = this.expandSegmentGroup(this.ngModule, this.config, tree.root, PRIMARY_OUTLET);
  1631. const /** @type {?} */ mapped$ = expanded$.pipe(map((rootSegmentGroup) => this.createUrlTree(rootSegmentGroup, tree.queryParams, /** @type {?} */ ((tree.fragment)))));
  1632. return mapped$.pipe(catchError((e) => {
  1633. if (e instanceof NoMatch) {
  1634. throw this.noMatchError(e);
  1635. }
  1636. throw e;
  1637. }));
  1638. }
  1639. /**
  1640. * @param {?} e
  1641. * @return {?}
  1642. */
  1643. noMatchError(e) {
  1644. return new Error(`Cannot match any routes. URL Segment: '${e.segmentGroup}'`);
  1645. }
  1646. /**
  1647. * @param {?} rootCandidate
  1648. * @param {?} queryParams
  1649. * @param {?} fragment
  1650. * @return {?}
  1651. */
  1652. createUrlTree(rootCandidate, queryParams, fragment) {
  1653. const /** @type {?} */ root = rootCandidate.segments.length > 0 ?
  1654. new UrlSegmentGroup([], { [PRIMARY_OUTLET]: rootCandidate }) :
  1655. rootCandidate;
  1656. return new UrlTree(root, queryParams, fragment);
  1657. }
  1658. /**
  1659. * @param {?} ngModule
  1660. * @param {?} routes
  1661. * @param {?} segmentGroup
  1662. * @param {?} outlet
  1663. * @return {?}
  1664. */
  1665. expandSegmentGroup(ngModule, routes, segmentGroup, outlet) {
  1666. if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
  1667. return this.expandChildren(ngModule, routes, segmentGroup)
  1668. .pipe(map((children) => new UrlSegmentGroup([], children)));
  1669. }
  1670. return this.expandSegment(ngModule, segmentGroup, routes, segmentGroup.segments, outlet, true);
  1671. }
  1672. /**
  1673. * @param {?} ngModule
  1674. * @param {?} routes
  1675. * @param {?} segmentGroup
  1676. * @return {?}
  1677. */
  1678. expandChildren(ngModule, routes, segmentGroup) {
  1679. return waitForMap(segmentGroup.children, (childOutlet, child) => this.expandSegmentGroup(ngModule, routes, child, childOutlet));
  1680. }
  1681. /**
  1682. * @param {?} ngModule
  1683. * @param {?} segmentGroup
  1684. * @param {?} routes
  1685. * @param {?} segments
  1686. * @param {?} outlet
  1687. * @param {?} allowRedirects
  1688. * @return {?}
  1689. */
  1690. expandSegment(ngModule, segmentGroup, routes, segments, outlet, allowRedirects) {
  1691. return of(...routes).pipe(map((r) => {
  1692. const /** @type {?} */ expanded$ = this.expandSegmentAgainstRoute(ngModule, segmentGroup, routes, r, segments, outlet, allowRedirects);
  1693. return expanded$.pipe(catchError((e) => {
  1694. if (e instanceof NoMatch) {
  1695. // TODO(i): this return type doesn't match the declared Observable<UrlSegmentGroup> -
  1696. // talk to Jason
  1697. return /** @type {?} */ (of(null));
  1698. }
  1699. throw e;
  1700. }));
  1701. }), concatAll(), first((s) => !!s), catchError((e, _) => {
  1702. if (e instanceof EmptyError || e.name === 'EmptyError') {
  1703. if (this.noLeftoversInUrl(segmentGroup, segments, outlet)) {
  1704. return of(new UrlSegmentGroup([], {}));
  1705. }
  1706. throw new NoMatch(segmentGroup);
  1707. }
  1708. throw e;
  1709. }));
  1710. }
  1711. /**
  1712. * @param {?} segmentGroup
  1713. * @param {?} segments
  1714. * @param {?} outlet
  1715. * @return {?}
  1716. */
  1717. noLeftoversInUrl(segmentGroup, segments, outlet) {
  1718. return segments.length === 0 && !segmentGroup.children[outlet];
  1719. }
  1720. /**
  1721. * @param {?} ngModule
  1722. * @param {?} segmentGroup
  1723. * @param {?} routes
  1724. * @param {?} route
  1725. * @param {?} paths
  1726. * @param {?} outlet
  1727. * @param {?} allowRedirects
  1728. * @return {?}
  1729. */
  1730. expandSegmentAgainstRoute(ngModule, segmentGroup, routes, route, paths, outlet, allowRedirects) {
  1731. if (getOutlet(route) !== outlet) {
  1732. return noMatch(segmentGroup);
  1733. }
  1734. if (route.redirectTo === undefined) {
  1735. return this.matchSegmentAgainstRoute(ngModule, segmentGroup, route, paths);
  1736. }
  1737. if (allowRedirects && this.allowRedirects) {
  1738. return this.expandSegmentAgainstRouteUsingRedirect(ngModule, segmentGroup, routes, route, paths, outlet);
  1739. }
  1740. return noMatch(segmentGroup);
  1741. }
  1742. /**
  1743. * @param {?} ngModule
  1744. * @param {?} segmentGroup
  1745. * @param {?} routes
  1746. * @param {?} route
  1747. * @param {?} segments
  1748. * @param {?} outlet
  1749. * @return {?}
  1750. */
  1751. expandSegmentAgainstRouteUsingRedirect(ngModule, segmentGroup, routes, route, segments, outlet) {
  1752. if (route.path === '**') {
  1753. return this.expandWildCardWithParamsAgainstRouteUsingRedirect(ngModule, routes, route, outlet);
  1754. }
  1755. return this.expandRegularSegmentAgainstRouteUsingRedirect(ngModule, segmentGroup, routes, route, segments, outlet);
  1756. }
  1757. /**
  1758. * @param {?} ngModule
  1759. * @param {?} routes
  1760. * @param {?} route
  1761. * @param {?} outlet
  1762. * @return {?}
  1763. */
  1764. expandWildCardWithParamsAgainstRouteUsingRedirect(ngModule, routes, route, outlet) {
  1765. const /** @type {?} */ newTree = this.applyRedirectCommands([], /** @type {?} */ ((route.redirectTo)), {});
  1766. if (/** @type {?} */ ((route.redirectTo)).startsWith('/')) {
  1767. return absoluteRedirect(newTree);
  1768. }
  1769. return this.lineralizeSegments(route, newTree).pipe(mergeMap((newSegments) => {
  1770. const /** @type {?} */ group = new UrlSegmentGroup(newSegments, {});
  1771. return this.expandSegment(ngModule, group, routes, newSegments, outlet, false);
  1772. }));
  1773. }
  1774. /**
  1775. * @param {?} ngModule
  1776. * @param {?} segmentGroup
  1777. * @param {?} routes
  1778. * @param {?} route
  1779. * @param {?} segments
  1780. * @param {?} outlet
  1781. * @return {?}
  1782. */
  1783. expandRegularSegmentAgainstRouteUsingRedirect(ngModule, segmentGroup, routes, route, segments, outlet) {
  1784. const { matched, consumedSegments, lastChild, positionalParamSegments } = match(segmentGroup, route, segments);
  1785. if (!matched)
  1786. return noMatch(segmentGroup);
  1787. const /** @type {?} */ newTree = this.applyRedirectCommands(consumedSegments, /** @type {?} */ ((route.redirectTo)), /** @type {?} */ (positionalParamSegments));
  1788. if (/** @type {?} */ ((route.redirectTo)).startsWith('/')) {
  1789. return absoluteRedirect(newTree);
  1790. }
  1791. return this.lineralizeSegments(route, newTree).pipe(mergeMap((newSegments) => {
  1792. return this.expandSegment(ngModule, segmentGroup, routes, newSegments.concat(segments.slice(lastChild)), outlet, false);
  1793. }));
  1794. }
  1795. /**
  1796. * @param {?} ngModule
  1797. * @param {?} rawSegmentGroup
  1798. * @param {?} route
  1799. * @param {?} segments
  1800. * @return {?}
  1801. */
  1802. matchSegmentAgainstRoute(ngModule, rawSegmentGroup, route, segments) {
  1803. if (route.path === '**') {
  1804. if (route.loadChildren) {
  1805. return this.configLoader.load(ngModule.injector, route)
  1806. .pipe(map((cfg) => {
  1807. route._loadedConfig = cfg;
  1808. return new UrlSegmentGroup(segments, {});
  1809. }));
  1810. }
  1811. return of(new UrlSegmentGroup(segments, {}));
  1812. }
  1813. const { matched, consumedSegments, lastChild } = match(rawSegmentGroup, route, segments);
  1814. if (!matched)
  1815. return noMatch(rawSegmentGroup);
  1816. const /** @type {?} */ rawSlicedSegments = segments.slice(lastChild);
  1817. const /** @type {?} */ childConfig$ = this.getChildConfig(ngModule, route);
  1818. return childConfig$.pipe(mergeMap((routerConfig) => {
  1819. const /** @type {?} */ childModule = routerConfig.module;
  1820. const /** @type {?} */ childConfig = routerConfig.routes;
  1821. const { segmentGroup, slicedSegments } = split(rawSegmentGroup, consumedSegments, rawSlicedSegments, childConfig);
  1822. if (slicedSegments.length === 0 && segmentGroup.hasChildren()) {
  1823. const /** @type {?} */ expanded$ = this.expandChildren(childModule, childConfig, segmentGroup);
  1824. return expanded$.pipe(map((children) => new UrlSegmentGroup(consumedSegments, children)));
  1825. }
  1826. if (childConfig.length === 0 && slicedSegments.length === 0) {
  1827. return of(new UrlSegmentGroup(consumedSegments, {}));
  1828. }
  1829. const /** @type {?} */ expanded$ = this.expandSegment(childModule, segmentGroup, childConfig, slicedSegments, PRIMARY_OUTLET, true);
  1830. return expanded$.pipe(map((cs) => new UrlSegmentGroup(consumedSegments.concat(cs.segments), cs.children)));
  1831. }));
  1832. }
  1833. /**
  1834. * @param {?} ngModule
  1835. * @param {?} route
  1836. * @return {?}
  1837. */
  1838. getChildConfig(ngModule, route) {
  1839. if (route.children) {
  1840. // The children belong to the same module
  1841. return of(new LoadedRouterConfig(route.children, ngModule));
  1842. }
  1843. if (route.loadChildren) {
  1844. // lazy children belong to the loaded module
  1845. if (route._loadedConfig !== undefined) {
  1846. return of(route._loadedConfig);
  1847. }
  1848. return runCanLoadGuard(ngModule.injector, route).pipe(mergeMap((shouldLoad) => {
  1849. if (shouldLoad) {
  1850. return this.configLoader.load(ngModule.injector, route)
  1851. .pipe(map((cfg) => {
  1852. route._loadedConfig = cfg;
  1853. return cfg;
  1854. }));
  1855. }
  1856. return canLoadFails(route);
  1857. }));
  1858. }
  1859. return of(new LoadedRouterConfig([], ngModule));
  1860. }
  1861. /**
  1862. * @param {?} route
  1863. * @param {?} urlTree
  1864. * @return {?}
  1865. */
  1866. lineralizeSegments(route, urlTree) {
  1867. let /** @type {?} */ res = [];
  1868. let /** @type {?} */ c = urlTree.root;
  1869. while (true) {
  1870. res = res.concat(c.segments);
  1871. if (c.numberOfChildren === 0) {
  1872. return of(res);
  1873. }
  1874. if (c.numberOfChildren > 1 || !c.children[PRIMARY_OUTLET]) {
  1875. return namedOutletsRedirect(/** @type {?} */ ((route.redirectTo)));
  1876. }
  1877. c = c.children[PRIMARY_OUTLET];
  1878. }
  1879. }
  1880. /**
  1881. * @param {?} segments
  1882. * @param {?} redirectTo
  1883. * @param {?} posParams
  1884. * @return {?}
  1885. */
  1886. applyRedirectCommands(segments, redirectTo, posParams) {
  1887. return this.applyRedirectCreatreUrlTree(redirectTo, this.urlSerializer.parse(redirectTo), segments, posParams);
  1888. }
  1889. /**
  1890. * @param {?} redirectTo
  1891. * @param {?} urlTree
  1892. * @param {?} segments
  1893. * @param {?} posParams
  1894. * @return {?}
  1895. */
  1896. applyRedirectCreatreUrlTree(redirectTo, urlTree, segments, posParams) {
  1897. const /** @type {?} */ newRoot = this.createSegmentGroup(redirectTo, urlTree.root, segments, posParams);
  1898. return new UrlTree(newRoot, this.createQueryParams(urlTree.queryParams, this.urlTree.queryParams), urlTree.fragment);
  1899. }
  1900. /**
  1901. * @param {?} redirectToParams
  1902. * @param {?} actualParams
  1903. * @return {?}
  1904. */
  1905. createQueryParams(redirectToParams, actualParams) {
  1906. const /** @type {?} */ res = {};
  1907. forEach(redirectToParams, (v, k) => {
  1908. const /** @type {?} */ copySourceValue = typeof v === 'string' && v.startsWith(':');
  1909. if (copySourceValue) {
  1910. const /** @type {?} */ sourceName = v.substring(1);
  1911. res[k] = actualParams[sourceName];
  1912. }
  1913. else {
  1914. res[k] = v;
  1915. }
  1916. });
  1917. return res;
  1918. }
  1919. /**
  1920. * @param {?} redirectTo
  1921. * @param {?} group
  1922. * @param {?} segments
  1923. * @param {?} posParams
  1924. * @return {?}
  1925. */
  1926. createSegmentGroup(redirectTo, group, segments, posParams) {
  1927. const /** @type {?} */ updatedSegments = this.createSegments(redirectTo, group.segments, segments, posParams);
  1928. let /** @type {?} */ children = {};
  1929. forEach(group.children, (child, name) => {
  1930. children[name] = this.createSegmentGroup(redirectTo, child, segments, posParams);
  1931. });
  1932. return new UrlSegmentGroup(updatedSegments, children);
  1933. }
  1934. /**
  1935. * @param {?} redirectTo
  1936. * @param {?} redirectToSegments
  1937. * @param {?} actualSegments
  1938. * @param {?} posParams
  1939. * @return {?}
  1940. */
  1941. createSegments(redirectTo, redirectToSegments, actualSegments, posParams) {
  1942. return redirectToSegments.map(s => s.path.startsWith(':') ? this.findPosParam(redirectTo, s, posParams) :
  1943. this.findOrReturn(s, actualSegments));
  1944. }
  1945. /**
  1946. * @param {?} redirectTo
  1947. * @param {?} redirectToUrlSegment
  1948. * @param {?} posParams
  1949. * @return {?}
  1950. */
  1951. findPosParam(redirectTo, redirectToUrlSegment, posParams) {
  1952. const /** @type {?} */ pos = posParams[redirectToUrlSegment.path.substring(1)];
  1953. if (!pos)
  1954. throw new Error(`Cannot redirect to '${redirectTo}'. Cannot find '${redirectToUrlSegment.path}'.`);
  1955. return pos;
  1956. }
  1957. /**
  1958. * @param {?} redirectToUrlSegment
  1959. * @param {?} actualSegments
  1960. * @return {?}
  1961. */
  1962. findOrReturn(redirectToUrlSegment, actualSegments) {
  1963. let /** @type {?} */ idx = 0;
  1964. for (const /** @type {?} */ s of actualSegments) {
  1965. if (s.path === redirectToUrlSegment.path) {
  1966. actualSegments.splice(idx);
  1967. return s;
  1968. }
  1969. idx++;
  1970. }
  1971. return redirectToUrlSegment;
  1972. }
  1973. }
  1974. /**
  1975. * @param {?} moduleInjector
  1976. * @param {?} route
  1977. * @return {?}
  1978. */
  1979. function runCanLoadGuard(moduleInjector, route) {
  1980. const /** @type {?} */ canLoad = route.canLoad;
  1981. if (!canLoad || canLoad.length === 0)
  1982. return of(true);
  1983. const /** @type {?} */ obs = from(canLoad).pipe(map((injectionToken) => {
  1984. const /** @type {?} */ guard = moduleInjector.get(injectionToken);
  1985. return wrapIntoObservable(guard.canLoad ? guard.canLoad(route) : guard(route));
  1986. }));
  1987. return andObservables(obs);
  1988. }
  1989. /**
  1990. * @param {?} segmentGroup
  1991. * @param {?} route
  1992. * @param {?} segments
  1993. * @return {?}
  1994. */
  1995. function match(segmentGroup, route, segments) {
  1996. if (route.path === '') {
  1997. if ((route.pathMatch === 'full') && (segmentGroup.hasChildren() || segments.length > 0)) {
  1998. return { matched: false, consumedSegments: [], lastChild: 0, positionalParamSegments: {} };
  1999. }
  2000. return { matched: true, consumedSegments: [], lastChild: 0, positionalParamSegments: {} };
  2001. }
  2002. const /** @type {?} */ matcher = route.matcher || defaultUrlMatcher;
  2003. const /** @type {?} */ res = matcher(segments, segmentGroup, route);
  2004. if (!res) {
  2005. return {
  2006. matched: false,
  2007. consumedSegments: /** @type {?} */ ([]),
  2008. lastChild: 0,
  2009. positionalParamSegments: {},
  2010. };
  2011. }
  2012. return {
  2013. matched: true,
  2014. consumedSegments: /** @type {?} */ ((res.consumed)),
  2015. lastChild: /** @type {?} */ ((res.consumed.length)),
  2016. positionalParamSegments: /** @type {?} */ ((res.posParams)),
  2017. };
  2018. }
  2019. /**
  2020. * @param {?} segmentGroup
  2021. * @param {?} consumedSegments
  2022. * @param {?} slicedSegments
  2023. * @param {?} config
  2024. * @return {?}
  2025. */
  2026. function split(segmentGroup, consumedSegments, slicedSegments, config) {
  2027. if (slicedSegments.length > 0 &&
  2028. containsEmptyPathRedirectsWithNamedOutlets(segmentGroup, slicedSegments, config)) {
  2029. const /** @type {?} */ s = new UrlSegmentGroup(consumedSegments, createChildrenForEmptySegments(config, new UrlSegmentGroup(slicedSegments, segmentGroup.children)));
  2030. return { segmentGroup: mergeTrivialChildren(s), slicedSegments: [] };
  2031. }
  2032. if (slicedSegments.length === 0 &&
  2033. containsEmptyPathRedirects(segmentGroup, slicedSegments, config)) {
  2034. const /** @type {?} */ s = new UrlSegmentGroup(segmentGroup.segments, addEmptySegmentsToChildrenIfNeeded(segmentGroup, slicedSegments, config, segmentGroup.children));
  2035. return { segmentGroup: mergeTrivialChildren(s), slicedSegments };
  2036. }
  2037. return { segmentGroup, slicedSegments };
  2038. }
  2039. /**
  2040. * @param {?} s
  2041. * @return {?}
  2042. */
  2043. function mergeTrivialChildren(s) {
  2044. if (s.numberOfChildren === 1 && s.children[PRIMARY_OUTLET]) {
  2045. const /** @type {?} */ c = s.children[PRIMARY_OUTLET];
  2046. return new UrlSegmentGroup(s.segments.concat(c.segments), c.children);
  2047. }
  2048. return s;
  2049. }
  2050. /**
  2051. * @param {?} segmentGroup
  2052. * @param {?} slicedSegments
  2053. * @param {?} routes
  2054. * @param {?} children
  2055. * @return {?}
  2056. */
  2057. function addEmptySegmentsToChildrenIfNeeded(segmentGroup, slicedSegments, routes, children) {
  2058. const /** @type {?} */ res = {};
  2059. for (const /** @type {?} */ r of routes) {
  2060. if (isEmptyPathRedirect(segmentGroup, slicedSegments, r) && !children[getOutlet(r)]) {
  2061. res[getOutlet(r)] = new UrlSegmentGroup([], {});
  2062. }
  2063. }
  2064. return Object.assign({}, children, res);
  2065. }
  2066. /**
  2067. * @param {?} routes
  2068. * @param {?} primarySegmentGroup
  2069. * @return {?}
  2070. */
  2071. function createChildrenForEmptySegments(routes, primarySegmentGroup) {
  2072. const /** @type {?} */ res = {};
  2073. res[PRIMARY_OUTLET] = primarySegmentGroup;
  2074. for (const /** @type {?} */ r of routes) {
  2075. if (r.path === '' && getOutlet(r) !== PRIMARY_OUTLET) {
  2076. res[getOutlet(r)] = new UrlSegmentGroup([], {});
  2077. }
  2078. }
  2079. return res;
  2080. }
  2081. /**
  2082. * @param {?} segmentGroup
  2083. * @param {?} segments
  2084. * @param {?} routes
  2085. * @return {?}
  2086. */
  2087. function containsEmptyPathRedirectsWithNamedOutlets(segmentGroup, segments, routes) {
  2088. return routes.some(r => isEmptyPathRedirect(segmentGroup, segments, r) && getOutlet(r) !== PRIMARY_OUTLET);
  2089. }
  2090. /**
  2091. * @param {?} segmentGroup
  2092. * @param {?} segments
  2093. * @param {?} routes
  2094. * @return {?}
  2095. */
  2096. function containsEmptyPathRedirects(segmentGroup, segments, routes) {
  2097. return routes.some(r => isEmptyPathRedirect(segmentGroup, segments, r));
  2098. }
  2099. /**
  2100. * @param {?} segmentGroup
  2101. * @param {?} segments
  2102. * @param {?} r
  2103. * @return {?}
  2104. */
  2105. function isEmptyPathRedirect(segmentGroup, segments, r) {
  2106. if ((segmentGroup.hasChildren() || segments.length > 0) && r.pathMatch === 'full') {
  2107. return false;
  2108. }
  2109. return r.path === '' && r.redirectTo !== undefined;
  2110. }
  2111. /**
  2112. * @param {?} route
  2113. * @return {?}
  2114. */
  2115. function getOutlet(route) {
  2116. return route.outlet || PRIMARY_OUTLET;
  2117. }
  2118. /**
  2119. * @fileoverview added by tsickle
  2120. * @suppress {checkTypes} checked by tsc
  2121. */
  2122. /**
  2123. * @license
  2124. * Copyright Google Inc. All Rights Reserved.
  2125. *
  2126. * Use of this source code is governed by an MIT-style license that can be
  2127. * found in the LICENSE file at https://angular.io/license
  2128. */
  2129. /**
  2130. * @template T
  2131. */
  2132. class Tree {
  2133. /**
  2134. * @param {?} root
  2135. */
  2136. constructor(root) { this._root = root; }
  2137. /**
  2138. * @return {?}
  2139. */
  2140. get root() { return this._root.value; }
  2141. /**
  2142. * \@internal
  2143. * @param {?} t
  2144. * @return {?}
  2145. */
  2146. parent(t) {
  2147. const /** @type {?} */ p = this.pathFromRoot(t);
  2148. return p.length > 1 ? p[p.length - 2] : null;
  2149. }
  2150. /**
  2151. * \@internal
  2152. * @param {?} t
  2153. * @return {?}
  2154. */
  2155. children(t) {
  2156. const /** @type {?} */ n = findNode(t, this._root);
  2157. return n ? n.children.map(t => t.value) : [];
  2158. }
  2159. /**
  2160. * \@internal
  2161. * @param {?} t
  2162. * @return {?}
  2163. */
  2164. firstChild(t) {
  2165. const /** @type {?} */ n = findNode(t, this._root);
  2166. return n && n.children.length > 0 ? n.children[0].value : null;
  2167. }
  2168. /**
  2169. * \@internal
  2170. * @param {?} t
  2171. * @return {?}
  2172. */
  2173. siblings(t) {
  2174. const /** @type {?} */ p = findPath(t, this._root);
  2175. if (p.length < 2)
  2176. return [];
  2177. const /** @type {?} */ c = p[p.length - 2].children.map(c => c.value);
  2178. return c.filter(cc => cc !== t);
  2179. }
  2180. /**
  2181. * \@internal
  2182. * @param {?} t
  2183. * @return {?}
  2184. */
  2185. pathFromRoot(t) { return findPath(t, this._root).map(s => s.value); }
  2186. }
  2187. /**
  2188. * @template T
  2189. * @param {?} value
  2190. * @param {?} node
  2191. * @return {?}
  2192. */
  2193. function findNode(value, node) {
  2194. if (value === node.value)
  2195. return node;
  2196. for (const /** @type {?} */ child of node.children) {
  2197. const /** @type {?} */ node = findNode(value, child);
  2198. if (node)
  2199. return node;
  2200. }
  2201. return null;
  2202. }
  2203. /**
  2204. * @template T
  2205. * @param {?} value
  2206. * @param {?} node
  2207. * @return {?}
  2208. */
  2209. function findPath(value, node) {
  2210. if (value === node.value)
  2211. return [node];
  2212. for (const /** @type {?} */ child of node.children) {
  2213. const /** @type {?} */ path = findPath(value, child);
  2214. if (path.length) {
  2215. path.unshift(node);
  2216. return path;
  2217. }
  2218. }
  2219. return [];
  2220. }
  2221. /**
  2222. * @template T
  2223. */
  2224. class TreeNode {
  2225. /**
  2226. * @param {?} value
  2227. * @param {?} children
  2228. */
  2229. constructor(value, children) {
  2230. this.value = value;
  2231. this.children = children;
  2232. }
  2233. /**
  2234. * @return {?}
  2235. */
  2236. toString() { return `TreeNode(${this.value})`; }
  2237. }
  2238. /**
  2239. * @template T
  2240. * @param {?} node
  2241. * @return {?}
  2242. */
  2243. function nodeChildrenAsMap(node) {
  2244. const /** @type {?} */ map$$1 = {};
  2245. if (node) {
  2246. node.children.forEach(child => map$$1[child.value.outlet] = child);
  2247. }
  2248. return map$$1;
  2249. }
  2250. /**
  2251. * @fileoverview added by tsickle
  2252. * @suppress {checkTypes} checked by tsc
  2253. */
  2254. /**
  2255. * \@description
  2256. *
  2257. * Represents the state of the router.
  2258. *
  2259. * RouterState is a tree of activated routes. Every node in this tree knows about the "consumed" URL
  2260. * segments, the extracted parameters, and the resolved data.
  2261. *
  2262. * ### Example
  2263. *
  2264. * ```
  2265. * \@Component({templateUrl:'template.html'})
  2266. * class MyComponent {
  2267. * constructor(router: Router) {
  2268. * const state: RouterState = router.routerState;
  2269. * const root: ActivatedRoute = state.root;
  2270. * const child = root.firstChild;
  2271. * const id: Observable<string> = child.params.map(p => p.id);
  2272. * //...
  2273. * }
  2274. * }
  2275. * ```
  2276. *
  2277. * See `ActivatedRoute` for more information.
  2278. *
  2279. *
  2280. */
  2281. class RouterState extends Tree {
  2282. /**
  2283. * \@internal
  2284. * @param {?} root
  2285. * @param {?} snapshot
  2286. */
  2287. constructor(root, snapshot) {
  2288. super(root);
  2289. this.snapshot = snapshot;
  2290. setRouterState(/** @type {?} */ (this), root);
  2291. }
  2292. /**
  2293. * @return {?}
  2294. */
  2295. toString() { return this.snapshot.toString(); }
  2296. }
  2297. /**
  2298. * @param {?} urlTree
  2299. * @param {?} rootComponent
  2300. * @return {?}
  2301. */
  2302. function createEmptyState(urlTree, rootComponent) {
  2303. const /** @type {?} */ snapshot = createEmptyStateSnapshot(urlTree, rootComponent);
  2304. const /** @type {?} */ emptyUrl = new BehaviorSubject([new UrlSegment('', {})]);
  2305. const /** @type {?} */ emptyParams = new BehaviorSubject({});
  2306. const /** @type {?} */ emptyData = new BehaviorSubject({});
  2307. const /** @type {?} */ emptyQueryParams = new BehaviorSubject({});
  2308. const /** @type {?} */ fragment = new BehaviorSubject('');
  2309. const /** @type {?} */ activated = new ActivatedRoute(emptyUrl, emptyParams, emptyQueryParams, fragment, emptyData, PRIMARY_OUTLET, rootComponent, snapshot.root);
  2310. activated.snapshot = snapshot.root;
  2311. return new RouterState(new TreeNode(activated, []), snapshot);
  2312. }
  2313. /**
  2314. * @param {?} urlTree
  2315. * @param {?} rootComponent
  2316. * @return {?}
  2317. */
  2318. function createEmptyStateSnapshot(urlTree, rootComponent) {
  2319. const /** @type {?} */ emptyParams = {};
  2320. const /** @type {?} */ emptyData = {};
  2321. const /** @type {?} */ emptyQueryParams = {};
  2322. const /** @type {?} */ fragment = '';
  2323. const /** @type {?} */ activated = new ActivatedRouteSnapshot([], emptyParams, emptyQueryParams, fragment, emptyData, PRIMARY_OUTLET, rootComponent, null, urlTree.root, -1, {});
  2324. return new RouterStateSnapshot('', new TreeNode(activated, []));
  2325. }
  2326. /**
  2327. * \@description
  2328. *
  2329. * Contains the information about a route associated with a component loaded in an
  2330. * outlet. An `ActivatedRoute` can also be used to traverse the router state tree.
  2331. *
  2332. * ```
  2333. * \@Component({...})
  2334. * class MyComponent {
  2335. * constructor(route: ActivatedRoute) {
  2336. * const id: Observable<string> = route.params.map(p => p.id);
  2337. * const url: Observable<string> = route.url.map(segments => segments.join(''));
  2338. * // route.data includes both `data` and `resolve`
  2339. * const user = route.data.map(d => d.user);
  2340. * }
  2341. * }
  2342. * ```
  2343. *
  2344. *
  2345. */
  2346. class ActivatedRoute {
  2347. /**
  2348. * \@internal
  2349. * @param {?} url
  2350. * @param {?} params
  2351. * @param {?} queryParams
  2352. * @param {?} fragment
  2353. * @param {?} data
  2354. * @param {?} outlet
  2355. * @param {?} component
  2356. * @param {?} futureSnapshot
  2357. */
  2358. constructor(url, params, queryParams, fragment, data, outlet, component, futureSnapshot) {
  2359. this.url = url;
  2360. this.params = params;
  2361. this.queryParams = queryParams;
  2362. this.fragment = fragment;
  2363. this.data = data;
  2364. this.outlet = outlet;
  2365. this.component = component;
  2366. this._futureSnapshot = futureSnapshot;
  2367. }
  2368. /**
  2369. * The configuration used to match this route
  2370. * @return {?}
  2371. */
  2372. get routeConfig() { return this._futureSnapshot.routeConfig; }
  2373. /**
  2374. * The root of the router state
  2375. * @return {?}
  2376. */
  2377. get root() { return this._routerState.root; }
  2378. /**
  2379. * The parent of this route in the router state tree
  2380. * @return {?}
  2381. */
  2382. get parent() { return this._routerState.parent(this); }
  2383. /**
  2384. * The first child of this route in the router state tree
  2385. * @return {?}
  2386. */
  2387. get firstChild() { return this._routerState.firstChild(this); }
  2388. /**
  2389. * The children of this route in the router state tree
  2390. * @return {?}
  2391. */
  2392. get children() { return this._routerState.children(this); }
  2393. /**
  2394. * The path from the root of the router state tree to this route
  2395. * @return {?}
  2396. */
  2397. get pathFromRoot() { return this._routerState.pathFromRoot(this); }
  2398. /**
  2399. * @return {?}
  2400. */
  2401. get paramMap() {
  2402. if (!this._paramMap) {
  2403. this._paramMap = this.params.pipe(map((p) => convertToParamMap(p)));
  2404. }
  2405. return this._paramMap;
  2406. }
  2407. /**
  2408. * @return {?}
  2409. */
  2410. get queryParamMap() {
  2411. if (!this._queryParamMap) {
  2412. this._queryParamMap =
  2413. this.queryParams.pipe(map((p) => convertToParamMap(p)));
  2414. }
  2415. return this._queryParamMap;
  2416. }
  2417. /**
  2418. * @return {?}
  2419. */
  2420. toString() {
  2421. return this.snapshot ? this.snapshot.toString() : `Future(${this._futureSnapshot})`;
  2422. }
  2423. }
  2424. /**
  2425. * Returns the inherited params, data, and resolve for a given route.
  2426. * By default, this only inherits values up to the nearest path-less or component-less route.
  2427. * \@internal
  2428. * @param {?} route
  2429. * @param {?=} paramsInheritanceStrategy
  2430. * @return {?}
  2431. */
  2432. function inheritedParamsDataResolve(route, paramsInheritanceStrategy = 'emptyOnly') {
  2433. const /** @type {?} */ pathFromRoot = route.pathFromRoot;
  2434. let /** @type {?} */ inheritingStartingFrom = 0;
  2435. if (paramsInheritanceStrategy !== 'always') {
  2436. inheritingStartingFrom = pathFromRoot.length - 1;
  2437. while (inheritingStartingFrom >= 1) {
  2438. const /** @type {?} */ current = pathFromRoot[inheritingStartingFrom];
  2439. const /** @type {?} */ parent = pathFromRoot[inheritingStartingFrom - 1];
  2440. // current route is an empty path => inherits its parent's params and data
  2441. if (current.routeConfig && current.routeConfig.path === '') {
  2442. inheritingStartingFrom--;
  2443. // parent is componentless => current route should inherit its params and data
  2444. }
  2445. else if (!parent.component) {
  2446. inheritingStartingFrom--;
  2447. }
  2448. else {
  2449. break;
  2450. }
  2451. }
  2452. }
  2453. return flattenInherited(pathFromRoot.slice(inheritingStartingFrom));
  2454. }
  2455. /**
  2456. * \@internal
  2457. * @param {?} pathFromRoot
  2458. * @return {?}
  2459. */
  2460. function flattenInherited(pathFromRoot) {
  2461. return pathFromRoot.reduce((res, curr) => {
  2462. const /** @type {?} */ params = Object.assign({}, res.params, curr.params);
  2463. const /** @type {?} */ data = Object.assign({}, res.data, curr.data);
  2464. const /** @type {?} */ resolve = Object.assign({}, res.resolve, curr._resolvedData);
  2465. return { params, data, resolve };
  2466. }, /** @type {?} */ ({ params: {}, data: {}, resolve: {} }));
  2467. }
  2468. /**
  2469. * \@description
  2470. *
  2471. * Contains the information about a route associated with a component loaded in an
  2472. * outlet at a particular moment in time. ActivatedRouteSnapshot can also be used to
  2473. * traverse the router state tree.
  2474. *
  2475. * ```
  2476. * \@Component({templateUrl:'./my-component.html'})
  2477. * class MyComponent {
  2478. * constructor(route: ActivatedRoute) {
  2479. * const id: string = route.snapshot.params.id;
  2480. * const url: string = route.snapshot.url.join('');
  2481. * const user = route.snapshot.data.user;
  2482. * }
  2483. * }
  2484. * ```
  2485. *
  2486. *
  2487. */
  2488. class ActivatedRouteSnapshot {
  2489. /**
  2490. * \@internal
  2491. * @param {?} url
  2492. * @param {?} params
  2493. * @param {?} queryParams
  2494. * @param {?} fragment
  2495. * @param {?} data
  2496. * @param {?} outlet
  2497. * @param {?} component
  2498. * @param {?} routeConfig
  2499. * @param {?} urlSegment
  2500. * @param {?} lastPathIndex
  2501. * @param {?} resolve
  2502. */
  2503. constructor(url, params, queryParams, fragment, data, outlet, component, routeConfig, urlSegment, lastPathIndex, resolve) {
  2504. this.url = url;
  2505. this.params = params;
  2506. this.queryParams = queryParams;
  2507. this.fragment = fragment;
  2508. this.data = data;
  2509. this.outlet = outlet;
  2510. this.component = component;
  2511. this.routeConfig = routeConfig;
  2512. this._urlSegment = urlSegment;
  2513. this._lastPathIndex = lastPathIndex;
  2514. this._resolve = resolve;
  2515. }
  2516. /**
  2517. * The root of the router state
  2518. * @return {?}
  2519. */
  2520. get root() { return this._routerState.root; }
  2521. /**
  2522. * The parent of this route in the router state tree
  2523. * @return {?}
  2524. */
  2525. get parent() { return this._routerState.parent(this); }
  2526. /**
  2527. * The first child of this route in the router state tree
  2528. * @return {?}
  2529. */
  2530. get firstChild() { return this._routerState.firstChild(this); }
  2531. /**
  2532. * The children of this route in the router state tree
  2533. * @return {?}
  2534. */
  2535. get children() { return this._routerState.children(this); }
  2536. /**
  2537. * The path from the root of the router state tree to this route
  2538. * @return {?}
  2539. */
  2540. get pathFromRoot() { return this._routerState.pathFromRoot(this); }
  2541. /**
  2542. * @return {?}
  2543. */
  2544. get paramMap() {
  2545. if (!this._paramMap) {
  2546. this._paramMap = convertToParamMap(this.params);
  2547. }
  2548. return this._paramMap;
  2549. }
  2550. /**
  2551. * @return {?}
  2552. */
  2553. get queryParamMap() {
  2554. if (!this._queryParamMap) {
  2555. this._queryParamMap = convertToParamMap(this.queryParams);
  2556. }
  2557. return this._queryParamMap;
  2558. }
  2559. /**
  2560. * @return {?}
  2561. */
  2562. toString() {
  2563. const /** @type {?} */ url = this.url.map(segment => segment.toString()).join('/');
  2564. const /** @type {?} */ matched = this.routeConfig ? this.routeConfig.path : '';
  2565. return `Route(url:'${url}', path:'${matched}')`;
  2566. }
  2567. }
  2568. /**
  2569. * \@description
  2570. *
  2571. * Represents the state of the router at a moment in time.
  2572. *
  2573. * This is a tree of activated route snapshots. Every node in this tree knows about
  2574. * the "consumed" URL segments, the extracted parameters, and the resolved data.
  2575. *
  2576. * ### Example
  2577. *
  2578. * ```
  2579. * \@Component({templateUrl:'template.html'})
  2580. * class MyComponent {
  2581. * constructor(router: Router) {
  2582. * const state: RouterState = router.routerState;
  2583. * const snapshot: RouterStateSnapshot = state.snapshot;
  2584. * const root: ActivatedRouteSnapshot = snapshot.root;
  2585. * const child = root.firstChild;
  2586. * const id: Observable<string> = child.params.map(p => p.id);
  2587. * //...
  2588. * }
  2589. * }
  2590. * ```
  2591. *
  2592. *
  2593. */
  2594. class RouterStateSnapshot extends Tree {
  2595. /**
  2596. * \@internal
  2597. * @param {?} url
  2598. * @param {?} root
  2599. */
  2600. constructor(url, root) {
  2601. super(root);
  2602. this.url = url;
  2603. setRouterState(/** @type {?} */ (this), root);
  2604. }
  2605. /**
  2606. * @return {?}
  2607. */
  2608. toString() { return serializeNode(this._root); }
  2609. }
  2610. /**
  2611. * @template U, T
  2612. * @param {?} state
  2613. * @param {?} node
  2614. * @return {?}
  2615. */
  2616. function setRouterState(state, node) {
  2617. node.value._routerState = state;
  2618. node.children.forEach(c => setRouterState(state, c));
  2619. }
  2620. /**
  2621. * @param {?} node
  2622. * @return {?}
  2623. */
  2624. function serializeNode(node) {
  2625. const /** @type {?} */ c = node.children.length > 0 ? ` { ${node.children.map(serializeNode).join(', ')} } ` : '';
  2626. return `${node.value}${c}`;
  2627. }
  2628. /**
  2629. * The expectation is that the activate route is created with the right set of parameters.
  2630. * So we push new values into the observables only when they are not the initial values.
  2631. * And we detect that by checking if the snapshot field is set.
  2632. * @param {?} route
  2633. * @return {?}
  2634. */
  2635. function advanceActivatedRoute(route) {
  2636. if (route.snapshot) {
  2637. const /** @type {?} */ currentSnapshot = route.snapshot;
  2638. const /** @type {?} */ nextSnapshot = route._futureSnapshot;
  2639. route.snapshot = nextSnapshot;
  2640. if (!shallowEqual(currentSnapshot.queryParams, nextSnapshot.queryParams)) {
  2641. (/** @type {?} */ (route.queryParams)).next(nextSnapshot.queryParams);
  2642. }
  2643. if (currentSnapshot.fragment !== nextSnapshot.fragment) {
  2644. (/** @type {?} */ (route.fragment)).next(nextSnapshot.fragment);
  2645. }
  2646. if (!shallowEqual(currentSnapshot.params, nextSnapshot.params)) {
  2647. (/** @type {?} */ (route.params)).next(nextSnapshot.params);
  2648. }
  2649. if (!shallowEqualArrays(currentSnapshot.url, nextSnapshot.url)) {
  2650. (/** @type {?} */ (route.url)).next(nextSnapshot.url);
  2651. }
  2652. if (!shallowEqual(currentSnapshot.data, nextSnapshot.data)) {
  2653. (/** @type {?} */ (route.data)).next(nextSnapshot.data);
  2654. }
  2655. }
  2656. else {
  2657. route.snapshot = route._futureSnapshot;
  2658. // this is for resolved data
  2659. (/** @type {?} */ (route.data)).next(route._futureSnapshot.data);
  2660. }
  2661. }
  2662. /**
  2663. * @param {?} a
  2664. * @param {?} b
  2665. * @return {?}
  2666. */
  2667. function equalParamsAndUrlSegments(a, b) {
  2668. const /** @type {?} */ equalUrlParams = shallowEqual(a.params, b.params) && equalSegments(a.url, b.url);
  2669. const /** @type {?} */ parentsMismatch = !a.parent !== !b.parent;
  2670. return equalUrlParams && !parentsMismatch &&
  2671. (!a.parent || equalParamsAndUrlSegments(a.parent, /** @type {?} */ ((b.parent))));
  2672. }
  2673. /**
  2674. * @fileoverview added by tsickle
  2675. * @suppress {checkTypes} checked by tsc
  2676. */
  2677. /**
  2678. * @param {?} routeReuseStrategy
  2679. * @param {?} curr
  2680. * @param {?} prevState
  2681. * @return {?}
  2682. */
  2683. function createRouterState(routeReuseStrategy, curr, prevState) {
  2684. const /** @type {?} */ root = createNode(routeReuseStrategy, curr._root, prevState ? prevState._root : undefined);
  2685. return new RouterState(root, curr);
  2686. }
  2687. /**
  2688. * @param {?} routeReuseStrategy
  2689. * @param {?} curr
  2690. * @param {?=} prevState
  2691. * @return {?}
  2692. */
  2693. function createNode(routeReuseStrategy, curr, prevState) {
  2694. // reuse an activated route that is currently displayed on the screen
  2695. if (prevState && routeReuseStrategy.shouldReuseRoute(curr.value, prevState.value.snapshot)) {
  2696. const /** @type {?} */ value = prevState.value;
  2697. value._futureSnapshot = curr.value;
  2698. const /** @type {?} */ children = createOrReuseChildren(routeReuseStrategy, curr, prevState);
  2699. return new TreeNode(value, children);
  2700. // retrieve an activated route that is used to be displayed, but is not currently displayed
  2701. }
  2702. else {
  2703. const /** @type {?} */ detachedRouteHandle = /** @type {?} */ (routeReuseStrategy.retrieve(curr.value));
  2704. if (detachedRouteHandle) {
  2705. const /** @type {?} */ tree = detachedRouteHandle.route;
  2706. setFutureSnapshotsOfActivatedRoutes(curr, tree);
  2707. return tree;
  2708. }
  2709. else {
  2710. const /** @type {?} */ value = createActivatedRoute(curr.value);
  2711. const /** @type {?} */ children = curr.children.map(c => createNode(routeReuseStrategy, c));
  2712. return new TreeNode(value, children);
  2713. }
  2714. }
  2715. }
  2716. /**
  2717. * @param {?} curr
  2718. * @param {?} result
  2719. * @return {?}
  2720. */
  2721. function setFutureSnapshotsOfActivatedRoutes(curr, result) {
  2722. if (curr.value.routeConfig !== result.value.routeConfig) {
  2723. throw new Error('Cannot reattach ActivatedRouteSnapshot created from a different route');
  2724. }
  2725. if (curr.children.length !== result.children.length) {
  2726. throw new Error('Cannot reattach ActivatedRouteSnapshot with a different number of children');
  2727. }
  2728. result.value._futureSnapshot = curr.value;
  2729. for (let /** @type {?} */ i = 0; i < curr.children.length; ++i) {
  2730. setFutureSnapshotsOfActivatedRoutes(curr.children[i], result.children[i]);
  2731. }
  2732. }
  2733. /**
  2734. * @param {?} routeReuseStrategy
  2735. * @param {?} curr
  2736. * @param {?} prevState
  2737. * @return {?}
  2738. */
  2739. function createOrReuseChildren(routeReuseStrategy, curr, prevState) {
  2740. return curr.children.map(child => {
  2741. for (const /** @type {?} */ p of prevState.children) {
  2742. if (routeReuseStrategy.shouldReuseRoute(p.value.snapshot, child.value)) {
  2743. return createNode(routeReuseStrategy, child, p);
  2744. }
  2745. }
  2746. return createNode(routeReuseStrategy, child);
  2747. });
  2748. }
  2749. /**
  2750. * @param {?} c
  2751. * @return {?}
  2752. */
  2753. function createActivatedRoute(c) {
  2754. return new ActivatedRoute(new BehaviorSubject(c.url), new BehaviorSubject(c.params), new BehaviorSubject(c.queryParams), new BehaviorSubject(c.fragment), new BehaviorSubject(c.data), c.outlet, c.component, c);
  2755. }
  2756. /**
  2757. * @fileoverview added by tsickle
  2758. * @suppress {checkTypes} checked by tsc
  2759. */
  2760. /**
  2761. * @param {?} route
  2762. * @param {?} urlTree
  2763. * @param {?} commands
  2764. * @param {?} queryParams
  2765. * @param {?} fragment
  2766. * @return {?}
  2767. */
  2768. function createUrlTree(route, urlTree, commands, queryParams, fragment) {
  2769. if (commands.length === 0) {
  2770. return tree(urlTree.root, urlTree.root, urlTree, queryParams, fragment);
  2771. }
  2772. const /** @type {?} */ nav = computeNavigation(commands);
  2773. if (nav.toRoot()) {
  2774. return tree(urlTree.root, new UrlSegmentGroup([], {}), urlTree, queryParams, fragment);
  2775. }
  2776. const /** @type {?} */ startingPosition = findStartingPosition(nav, urlTree, route);
  2777. const /** @type {?} */ segmentGroup = startingPosition.processChildren ?
  2778. updateSegmentGroupChildren(startingPosition.segmentGroup, startingPosition.index, nav.commands) :
  2779. updateSegmentGroup(startingPosition.segmentGroup, startingPosition.index, nav.commands);
  2780. return tree(startingPosition.segmentGroup, segmentGroup, urlTree, queryParams, fragment);
  2781. }
  2782. /**
  2783. * @param {?} command
  2784. * @return {?}
  2785. */
  2786. function isMatrixParams(command) {
  2787. return typeof command === 'object' && command != null && !command.outlets && !command.segmentPath;
  2788. }
  2789. /**
  2790. * @param {?} oldSegmentGroup
  2791. * @param {?} newSegmentGroup
  2792. * @param {?} urlTree
  2793. * @param {?} queryParams
  2794. * @param {?} fragment
  2795. * @return {?}
  2796. */
  2797. function tree(oldSegmentGroup, newSegmentGroup, urlTree, queryParams, fragment) {
  2798. let /** @type {?} */ qp = {};
  2799. if (queryParams) {
  2800. forEach(queryParams, (value, name) => {
  2801. qp[name] = Array.isArray(value) ? value.map((v) => `${v}`) : `${value}`;
  2802. });
  2803. }
  2804. if (urlTree.root === oldSegmentGroup) {
  2805. return new UrlTree(newSegmentGroup, qp, fragment);
  2806. }
  2807. return new UrlTree(replaceSegment(urlTree.root, oldSegmentGroup, newSegmentGroup), qp, fragment);
  2808. }
  2809. /**
  2810. * @param {?} current
  2811. * @param {?} oldSegment
  2812. * @param {?} newSegment
  2813. * @return {?}
  2814. */
  2815. function replaceSegment(current, oldSegment, newSegment) {
  2816. const /** @type {?} */ children = {};
  2817. forEach(current.children, (c, outletName) => {
  2818. if (c === oldSegment) {
  2819. children[outletName] = newSegment;
  2820. }
  2821. else {
  2822. children[outletName] = replaceSegment(c, oldSegment, newSegment);
  2823. }
  2824. });
  2825. return new UrlSegmentGroup(current.segments, children);
  2826. }
  2827. class Navigation {
  2828. /**
  2829. * @param {?} isAbsolute
  2830. * @param {?} numberOfDoubleDots
  2831. * @param {?} commands
  2832. */
  2833. constructor(isAbsolute, numberOfDoubleDots, commands) {
  2834. this.isAbsolute = isAbsolute;
  2835. this.numberOfDoubleDots = numberOfDoubleDots;
  2836. this.commands = commands;
  2837. if (isAbsolute && commands.length > 0 && isMatrixParams(commands[0])) {
  2838. throw new Error('Root segment cannot have matrix parameters');
  2839. }
  2840. const /** @type {?} */ cmdWithOutlet = commands.find(c => typeof c === 'object' && c != null && c.outlets);
  2841. if (cmdWithOutlet && cmdWithOutlet !== last$1(commands)) {
  2842. throw new Error('{outlets:{}} has to be the last command');
  2843. }
  2844. }
  2845. /**
  2846. * @return {?}
  2847. */
  2848. toRoot() {
  2849. return this.isAbsolute && this.commands.length === 1 && this.commands[0] == '/';
  2850. }
  2851. }
  2852. /**
  2853. * Transforms commands to a normalized `Navigation`
  2854. * @param {?} commands
  2855. * @return {?}
  2856. */
  2857. function computeNavigation(commands) {
  2858. if ((typeof commands[0] === 'string') && commands.length === 1 && commands[0] === '/') {
  2859. return new Navigation(true, 0, commands);
  2860. }
  2861. let /** @type {?} */ numberOfDoubleDots = 0;
  2862. let /** @type {?} */ isAbsolute = false;
  2863. const /** @type {?} */ res = commands.reduce((res, cmd, cmdIdx) => {
  2864. if (typeof cmd === 'object' && cmd != null) {
  2865. if (cmd.outlets) {
  2866. const /** @type {?} */ outlets = {};
  2867. forEach(cmd.outlets, (commands, name) => {
  2868. outlets[name] = typeof commands === 'string' ? commands.split('/') : commands;
  2869. });
  2870. return [...res, { outlets }];
  2871. }
  2872. if (cmd.segmentPath) {
  2873. return [...res, cmd.segmentPath];
  2874. }
  2875. }
  2876. if (!(typeof cmd === 'string')) {
  2877. return [...res, cmd];
  2878. }
  2879. if (cmdIdx === 0) {
  2880. cmd.split('/').forEach((urlPart, partIndex) => {
  2881. if (partIndex == 0 && urlPart === '.') ;
  2882. else if (partIndex == 0 && urlPart === '') {
  2883. // '/a'
  2884. isAbsolute = true;
  2885. }
  2886. else if (urlPart === '..') {
  2887. // '../a'
  2888. numberOfDoubleDots++;
  2889. }
  2890. else if (urlPart != '') {
  2891. res.push(urlPart);
  2892. }
  2893. });
  2894. return res;
  2895. }
  2896. return [...res, cmd];
  2897. }, []);
  2898. return new Navigation(isAbsolute, numberOfDoubleDots, res);
  2899. }
  2900. class Position {
  2901. /**
  2902. * @param {?} segmentGroup
  2903. * @param {?} processChildren
  2904. * @param {?} index
  2905. */
  2906. constructor(segmentGroup, processChildren, index) {
  2907. this.segmentGroup = segmentGroup;
  2908. this.processChildren = processChildren;
  2909. this.index = index;
  2910. }
  2911. }
  2912. /**
  2913. * @param {?} nav
  2914. * @param {?} tree
  2915. * @param {?} route
  2916. * @return {?}
  2917. */
  2918. function findStartingPosition(nav, tree, route) {
  2919. if (nav.isAbsolute) {
  2920. return new Position(tree.root, true, 0);
  2921. }
  2922. if (route.snapshot._lastPathIndex === -1) {
  2923. return new Position(route.snapshot._urlSegment, true, 0);
  2924. }
  2925. const /** @type {?} */ modifier = isMatrixParams(nav.commands[0]) ? 0 : 1;
  2926. const /** @type {?} */ index = route.snapshot._lastPathIndex + modifier;
  2927. return createPositionApplyingDoubleDots(route.snapshot._urlSegment, index, nav.numberOfDoubleDots);
  2928. }
  2929. /**
  2930. * @param {?} group
  2931. * @param {?} index
  2932. * @param {?} numberOfDoubleDots
  2933. * @return {?}
  2934. */
  2935. function createPositionApplyingDoubleDots(group, index, numberOfDoubleDots) {
  2936. let /** @type {?} */ g = group;
  2937. let /** @type {?} */ ci = index;
  2938. let /** @type {?} */ dd = numberOfDoubleDots;
  2939. while (dd > ci) {
  2940. dd -= ci;
  2941. g = /** @type {?} */ ((g.parent));
  2942. if (!g) {
  2943. throw new Error('Invalid number of \'../\'');
  2944. }
  2945. ci = g.segments.length;
  2946. }
  2947. return new Position(g, false, ci - dd);
  2948. }
  2949. /**
  2950. * @param {?} command
  2951. * @return {?}
  2952. */
  2953. function getPath(command) {
  2954. if (typeof command === 'object' && command != null && command.outlets) {
  2955. return command.outlets[PRIMARY_OUTLET];
  2956. }
  2957. return `${command}`;
  2958. }
  2959. /**
  2960. * @param {?} commands
  2961. * @return {?}
  2962. */
  2963. function getOutlets(commands) {
  2964. if (!(typeof commands[0] === 'object'))
  2965. return { [PRIMARY_OUTLET]: commands };
  2966. if (commands[0].outlets === undefined)
  2967. return { [PRIMARY_OUTLET]: commands };
  2968. return commands[0].outlets;
  2969. }
  2970. /**
  2971. * @param {?} segmentGroup
  2972. * @param {?} startIndex
  2973. * @param {?} commands
  2974. * @return {?}
  2975. */
  2976. function updateSegmentGroup(segmentGroup, startIndex, commands) {
  2977. if (!segmentGroup) {
  2978. segmentGroup = new UrlSegmentGroup([], {});
  2979. }
  2980. if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
  2981. return updateSegmentGroupChildren(segmentGroup, startIndex, commands);
  2982. }
  2983. const /** @type {?} */ m = prefixedWith(segmentGroup, startIndex, commands);
  2984. const /** @type {?} */ slicedCommands = commands.slice(m.commandIndex);
  2985. if (m.match && m.pathIndex < segmentGroup.segments.length) {
  2986. const /** @type {?} */ g = new UrlSegmentGroup(segmentGroup.segments.slice(0, m.pathIndex), {});
  2987. g.children[PRIMARY_OUTLET] =
  2988. new UrlSegmentGroup(segmentGroup.segments.slice(m.pathIndex), segmentGroup.children);
  2989. return updateSegmentGroupChildren(g, 0, slicedCommands);
  2990. }
  2991. else if (m.match && slicedCommands.length === 0) {
  2992. return new UrlSegmentGroup(segmentGroup.segments, {});
  2993. }
  2994. else if (m.match && !segmentGroup.hasChildren()) {
  2995. return createNewSegmentGroup(segmentGroup, startIndex, commands);
  2996. }
  2997. else if (m.match) {
  2998. return updateSegmentGroupChildren(segmentGroup, 0, slicedCommands);
  2999. }
  3000. else {
  3001. return createNewSegmentGroup(segmentGroup, startIndex, commands);
  3002. }
  3003. }
  3004. /**
  3005. * @param {?} segmentGroup
  3006. * @param {?} startIndex
  3007. * @param {?} commands
  3008. * @return {?}
  3009. */
  3010. function updateSegmentGroupChildren(segmentGroup, startIndex, commands) {
  3011. if (commands.length === 0) {
  3012. return new UrlSegmentGroup(segmentGroup.segments, {});
  3013. }
  3014. else {
  3015. const /** @type {?} */ outlets = getOutlets(commands);
  3016. const /** @type {?} */ children = {};
  3017. forEach(outlets, (commands, outlet) => {
  3018. if (commands !== null) {
  3019. children[outlet] = updateSegmentGroup(segmentGroup.children[outlet], startIndex, commands);
  3020. }
  3021. });
  3022. forEach(segmentGroup.children, (child, childOutlet) => {
  3023. if (outlets[childOutlet] === undefined) {
  3024. children[childOutlet] = child;
  3025. }
  3026. });
  3027. return new UrlSegmentGroup(segmentGroup.segments, children);
  3028. }
  3029. }
  3030. /**
  3031. * @param {?} segmentGroup
  3032. * @param {?} startIndex
  3033. * @param {?} commands
  3034. * @return {?}
  3035. */
  3036. function prefixedWith(segmentGroup, startIndex, commands) {
  3037. let /** @type {?} */ currentCommandIndex = 0;
  3038. let /** @type {?} */ currentPathIndex = startIndex;
  3039. const /** @type {?} */ noMatch = { match: false, pathIndex: 0, commandIndex: 0 };
  3040. while (currentPathIndex < segmentGroup.segments.length) {
  3041. if (currentCommandIndex >= commands.length)
  3042. return noMatch;
  3043. const /** @type {?} */ path = segmentGroup.segments[currentPathIndex];
  3044. const /** @type {?} */ curr = getPath(commands[currentCommandIndex]);
  3045. const /** @type {?} */ next = currentCommandIndex < commands.length - 1 ? commands[currentCommandIndex + 1] : null;
  3046. if (currentPathIndex > 0 && curr === undefined)
  3047. break;
  3048. if (curr && next && (typeof next === 'object') && next.outlets === undefined) {
  3049. if (!compare(curr, next, path))
  3050. return noMatch;
  3051. currentCommandIndex += 2;
  3052. }
  3053. else {
  3054. if (!compare(curr, {}, path))
  3055. return noMatch;
  3056. currentCommandIndex++;
  3057. }
  3058. currentPathIndex++;
  3059. }
  3060. return { match: true, pathIndex: currentPathIndex, commandIndex: currentCommandIndex };
  3061. }
  3062. /**
  3063. * @param {?} segmentGroup
  3064. * @param {?} startIndex
  3065. * @param {?} commands
  3066. * @return {?}
  3067. */
  3068. function createNewSegmentGroup(segmentGroup, startIndex, commands) {
  3069. const /** @type {?} */ paths = segmentGroup.segments.slice(0, startIndex);
  3070. let /** @type {?} */ i = 0;
  3071. while (i < commands.length) {
  3072. if (typeof commands[i] === 'object' && commands[i].outlets !== undefined) {
  3073. const /** @type {?} */ children = createNewSegmentChildren(commands[i].outlets);
  3074. return new UrlSegmentGroup(paths, children);
  3075. }
  3076. // if we start with an object literal, we need to reuse the path part from the segment
  3077. if (i === 0 && isMatrixParams(commands[0])) {
  3078. const /** @type {?} */ p = segmentGroup.segments[startIndex];
  3079. paths.push(new UrlSegment(p.path, commands[0]));
  3080. i++;
  3081. continue;
  3082. }
  3083. const /** @type {?} */ curr = getPath(commands[i]);
  3084. const /** @type {?} */ next = (i < commands.length - 1) ? commands[i + 1] : null;
  3085. if (curr && next && isMatrixParams(next)) {
  3086. paths.push(new UrlSegment(curr, stringify(next)));
  3087. i += 2;
  3088. }
  3089. else {
  3090. paths.push(new UrlSegment(curr, {}));
  3091. i++;
  3092. }
  3093. }
  3094. return new UrlSegmentGroup(paths, {});
  3095. }
  3096. /**
  3097. * @param {?} outlets
  3098. * @return {?}
  3099. */
  3100. function createNewSegmentChildren(outlets) {
  3101. const /** @type {?} */ children = {};
  3102. forEach(outlets, (commands, outlet) => {
  3103. if (commands !== null) {
  3104. children[outlet] = createNewSegmentGroup(new UrlSegmentGroup([], {}), 0, commands);
  3105. }
  3106. });
  3107. return children;
  3108. }
  3109. /**
  3110. * @param {?} params
  3111. * @return {?}
  3112. */
  3113. function stringify(params) {
  3114. const /** @type {?} */ res = {};
  3115. forEach(params, (v, k) => res[k] = `${v}`);
  3116. return res;
  3117. }
  3118. /**
  3119. * @param {?} path
  3120. * @param {?} params
  3121. * @param {?} segment
  3122. * @return {?}
  3123. */
  3124. function compare(path, params, segment) {
  3125. return path == segment.path && shallowEqual(params, segment.parameters);
  3126. }
  3127. /**
  3128. * @fileoverview added by tsickle
  3129. * @suppress {checkTypes} checked by tsc
  3130. */
  3131. class CanActivate {
  3132. /**
  3133. * @param {?} path
  3134. */
  3135. constructor(path) {
  3136. this.path = path;
  3137. this.route = this.path[this.path.length - 1];
  3138. }
  3139. }
  3140. class CanDeactivate {
  3141. /**
  3142. * @param {?} component
  3143. * @param {?} route
  3144. */
  3145. constructor(component, route) {
  3146. this.component = component;
  3147. this.route = route;
  3148. }
  3149. }
  3150. /**
  3151. * This class bundles the actions involved in preactivation of a route.
  3152. */
  3153. class PreActivation {
  3154. /**
  3155. * @param {?} future
  3156. * @param {?} curr
  3157. * @param {?} moduleInjector
  3158. * @param {?=} forwardEvent
  3159. */
  3160. constructor(future, curr, moduleInjector, forwardEvent) {
  3161. this.future = future;
  3162. this.curr = curr;
  3163. this.moduleInjector = moduleInjector;
  3164. this.forwardEvent = forwardEvent;
  3165. this.canActivateChecks = [];
  3166. this.canDeactivateChecks = [];
  3167. }
  3168. /**
  3169. * @param {?} parentContexts
  3170. * @return {?}
  3171. */
  3172. initialize(parentContexts) {
  3173. const /** @type {?} */ futureRoot = this.future._root;
  3174. const /** @type {?} */ currRoot = this.curr ? this.curr._root : null;
  3175. this.setupChildRouteGuards(futureRoot, currRoot, parentContexts, [futureRoot.value]);
  3176. }
  3177. /**
  3178. * @return {?}
  3179. */
  3180. checkGuards() {
  3181. if (!this.isDeactivating() && !this.isActivating()) {
  3182. return of(true);
  3183. }
  3184. const /** @type {?} */ canDeactivate$ = this.runCanDeactivateChecks();
  3185. return canDeactivate$.pipe(mergeMap((canDeactivate) => canDeactivate ? this.runCanActivateChecks() : of(false)));
  3186. }
  3187. /**
  3188. * @param {?} paramsInheritanceStrategy
  3189. * @return {?}
  3190. */
  3191. resolveData(paramsInheritanceStrategy) {
  3192. if (!this.isActivating())
  3193. return of(null);
  3194. return from(this.canActivateChecks)
  3195. .pipe(concatMap((check) => this.runResolve(check.route, paramsInheritanceStrategy)), reduce((_, __) => _));
  3196. }
  3197. /**
  3198. * @return {?}
  3199. */
  3200. isDeactivating() { return this.canDeactivateChecks.length !== 0; }
  3201. /**
  3202. * @return {?}
  3203. */
  3204. isActivating() { return this.canActivateChecks.length !== 0; }
  3205. /**
  3206. * Iterates over child routes and calls recursive `setupRouteGuards` to get `this` instance in
  3207. * proper state to run `checkGuards()` method.
  3208. * @param {?} futureNode
  3209. * @param {?} currNode
  3210. * @param {?} contexts
  3211. * @param {?} futurePath
  3212. * @return {?}
  3213. */
  3214. setupChildRouteGuards(futureNode, currNode, contexts, futurePath) {
  3215. const /** @type {?} */ prevChildren = nodeChildrenAsMap(currNode);
  3216. // Process the children of the future route
  3217. futureNode.children.forEach(c => {
  3218. this.setupRouteGuards(c, prevChildren[c.value.outlet], contexts, futurePath.concat([c.value]));
  3219. delete prevChildren[c.value.outlet];
  3220. });
  3221. // Process any children left from the current route (not active for the future route)
  3222. forEach(prevChildren, (v, k) => this.deactivateRouteAndItsChildren(v, /** @type {?} */ ((contexts)).getContext(k)));
  3223. }
  3224. /**
  3225. * Iterates over child routes and calls recursive `setupRouteGuards` to get `this` instance in
  3226. * proper state to run `checkGuards()` method.
  3227. * @param {?} futureNode
  3228. * @param {?} currNode
  3229. * @param {?} parentContexts
  3230. * @param {?} futurePath
  3231. * @return {?}
  3232. */
  3233. setupRouteGuards(futureNode, currNode, parentContexts, futurePath) {
  3234. const /** @type {?} */ future = futureNode.value;
  3235. const /** @type {?} */ curr = currNode ? currNode.value : null;
  3236. const /** @type {?} */ context = parentContexts ? parentContexts.getContext(futureNode.value.outlet) : null;
  3237. // reusing the node
  3238. if (curr && future.routeConfig === curr.routeConfig) {
  3239. const /** @type {?} */ shouldRunGuardsAndResolvers = this.shouldRunGuardsAndResolvers(curr, future, /** @type {?} */ ((future.routeConfig)).runGuardsAndResolvers);
  3240. if (shouldRunGuardsAndResolvers) {
  3241. this.canActivateChecks.push(new CanActivate(futurePath));
  3242. }
  3243. else {
  3244. // we need to set the data
  3245. future.data = curr.data;
  3246. future._resolvedData = curr._resolvedData;
  3247. }
  3248. // If we have a component, we need to go through an outlet.
  3249. if (future.component) {
  3250. this.setupChildRouteGuards(futureNode, currNode, context ? context.children : null, futurePath);
  3251. // if we have a componentless route, we recurse but keep the same outlet map.
  3252. }
  3253. else {
  3254. this.setupChildRouteGuards(futureNode, currNode, parentContexts, futurePath);
  3255. }
  3256. if (shouldRunGuardsAndResolvers) {
  3257. const /** @type {?} */ outlet = /** @type {?} */ ((/** @type {?} */ ((context)).outlet));
  3258. this.canDeactivateChecks.push(new CanDeactivate(outlet.component, curr));
  3259. }
  3260. }
  3261. else {
  3262. if (curr) {
  3263. this.deactivateRouteAndItsChildren(currNode, context);
  3264. }
  3265. this.canActivateChecks.push(new CanActivate(futurePath));
  3266. // If we have a component, we need to go through an outlet.
  3267. if (future.component) {
  3268. this.setupChildRouteGuards(futureNode, null, context ? context.children : null, futurePath);
  3269. // if we have a componentless route, we recurse but keep the same outlet map.
  3270. }
  3271. else {
  3272. this.setupChildRouteGuards(futureNode, null, parentContexts, futurePath);
  3273. }
  3274. }
  3275. }
  3276. /**
  3277. * @param {?} curr
  3278. * @param {?} future
  3279. * @param {?} mode
  3280. * @return {?}
  3281. */
  3282. shouldRunGuardsAndResolvers(curr, future, mode) {
  3283. switch (mode) {
  3284. case 'always':
  3285. return true;
  3286. case 'paramsOrQueryParamsChange':
  3287. return !equalParamsAndUrlSegments(curr, future) ||
  3288. !shallowEqual(curr.queryParams, future.queryParams);
  3289. case 'paramsChange':
  3290. default:
  3291. return !equalParamsAndUrlSegments(curr, future);
  3292. }
  3293. }
  3294. /**
  3295. * @param {?} route
  3296. * @param {?} context
  3297. * @return {?}
  3298. */
  3299. deactivateRouteAndItsChildren(route, context) {
  3300. const /** @type {?} */ children = nodeChildrenAsMap(route);
  3301. const /** @type {?} */ r = route.value;
  3302. forEach(children, (node, childName) => {
  3303. if (!r.component) {
  3304. this.deactivateRouteAndItsChildren(node, context);
  3305. }
  3306. else if (context) {
  3307. this.deactivateRouteAndItsChildren(node, context.children.getContext(childName));
  3308. }
  3309. else {
  3310. this.deactivateRouteAndItsChildren(node, null);
  3311. }
  3312. });
  3313. if (!r.component) {
  3314. this.canDeactivateChecks.push(new CanDeactivate(null, r));
  3315. }
  3316. else if (context && context.outlet && context.outlet.isActivated) {
  3317. this.canDeactivateChecks.push(new CanDeactivate(context.outlet.component, r));
  3318. }
  3319. else {
  3320. this.canDeactivateChecks.push(new CanDeactivate(null, r));
  3321. }
  3322. }
  3323. /**
  3324. * @return {?}
  3325. */
  3326. runCanDeactivateChecks() {
  3327. return from(this.canDeactivateChecks)
  3328. .pipe(mergeMap((check) => this.runCanDeactivate(check.component, check.route)), every((result) => result === true));
  3329. }
  3330. /**
  3331. * @return {?}
  3332. */
  3333. runCanActivateChecks() {
  3334. return from(this.canActivateChecks)
  3335. .pipe(concatMap((check) => andObservables(from([
  3336. this.fireChildActivationStart(check.route.parent),
  3337. this.fireActivationStart(check.route), this.runCanActivateChild(check.path),
  3338. this.runCanActivate(check.route)
  3339. ]))), every((result) => result === true));
  3340. // this.fireChildActivationStart(check.path),
  3341. }
  3342. /**
  3343. * This should fire off `ActivationStart` events for each route being activated at this
  3344. * level.
  3345. * In other words, if you're activating `a` and `b` below, `path` will contain the
  3346. * `ActivatedRouteSnapshot`s for both and we will fire `ActivationStart` for both. Always
  3347. * return
  3348. * `true` so checks continue to run.
  3349. * @param {?} snapshot
  3350. * @return {?}
  3351. */
  3352. fireActivationStart(snapshot) {
  3353. if (snapshot !== null && this.forwardEvent) {
  3354. this.forwardEvent(new ActivationStart(snapshot));
  3355. }
  3356. return of(true);
  3357. }
  3358. /**
  3359. * This should fire off `ChildActivationStart` events for each route being activated at this
  3360. * level.
  3361. * In other words, if you're activating `a` and `b` below, `path` will contain the
  3362. * `ActivatedRouteSnapshot`s for both and we will fire `ChildActivationStart` for both. Always
  3363. * return
  3364. * `true` so checks continue to run.
  3365. * @param {?} snapshot
  3366. * @return {?}
  3367. */
  3368. fireChildActivationStart(snapshot) {
  3369. if (snapshot !== null && this.forwardEvent) {
  3370. this.forwardEvent(new ChildActivationStart(snapshot));
  3371. }
  3372. return of(true);
  3373. }
  3374. /**
  3375. * @param {?} future
  3376. * @return {?}
  3377. */
  3378. runCanActivate(future) {
  3379. const /** @type {?} */ canActivate = future.routeConfig ? future.routeConfig.canActivate : null;
  3380. if (!canActivate || canActivate.length === 0)
  3381. return of(true);
  3382. const /** @type {?} */ obs = from(canActivate).pipe(map((c) => {
  3383. const /** @type {?} */ guard = this.getToken(c, future);
  3384. let /** @type {?} */ observable;
  3385. if (guard.canActivate) {
  3386. observable = wrapIntoObservable(guard.canActivate(future, this.future));
  3387. }
  3388. else {
  3389. observable = wrapIntoObservable(guard(future, this.future));
  3390. }
  3391. return observable.pipe(first());
  3392. }));
  3393. return andObservables(obs);
  3394. }
  3395. /**
  3396. * @param {?} path
  3397. * @return {?}
  3398. */
  3399. runCanActivateChild(path) {
  3400. const /** @type {?} */ future = path[path.length - 1];
  3401. const /** @type {?} */ canActivateChildGuards = path.slice(0, path.length - 1)
  3402. .reverse()
  3403. .map(p => this.extractCanActivateChild(p))
  3404. .filter(_ => _ !== null);
  3405. return andObservables(from(canActivateChildGuards).pipe(map((d) => {
  3406. const /** @type {?} */ obs = from(d.guards).pipe(map((c) => {
  3407. const /** @type {?} */ guard = this.getToken(c, d.node);
  3408. let /** @type {?} */ observable;
  3409. if (guard.canActivateChild) {
  3410. observable = wrapIntoObservable(guard.canActivateChild(future, this.future));
  3411. }
  3412. else {
  3413. observable = wrapIntoObservable(guard(future, this.future));
  3414. }
  3415. return observable.pipe(first());
  3416. }));
  3417. return andObservables(obs);
  3418. })));
  3419. }
  3420. /**
  3421. * @param {?} p
  3422. * @return {?}
  3423. */
  3424. extractCanActivateChild(p) {
  3425. const /** @type {?} */ canActivateChild = p.routeConfig ? p.routeConfig.canActivateChild : null;
  3426. if (!canActivateChild || canActivateChild.length === 0)
  3427. return null;
  3428. return { node: p, guards: canActivateChild };
  3429. }
  3430. /**
  3431. * @param {?} component
  3432. * @param {?} curr
  3433. * @return {?}
  3434. */
  3435. runCanDeactivate(component, curr) {
  3436. const /** @type {?} */ canDeactivate = curr && curr.routeConfig ? curr.routeConfig.canDeactivate : null;
  3437. if (!canDeactivate || canDeactivate.length === 0)
  3438. return of(true);
  3439. const /** @type {?} */ canDeactivate$ = from(canDeactivate).pipe(mergeMap((c) => {
  3440. const /** @type {?} */ guard = this.getToken(c, curr);
  3441. let /** @type {?} */ observable;
  3442. if (guard.canDeactivate) {
  3443. observable =
  3444. wrapIntoObservable(guard.canDeactivate(component, curr, this.curr, this.future));
  3445. }
  3446. else {
  3447. observable = wrapIntoObservable(guard(component, curr, this.curr, this.future));
  3448. }
  3449. return observable.pipe(first());
  3450. }));
  3451. return canDeactivate$.pipe(every((result) => result === true));
  3452. }
  3453. /**
  3454. * @param {?} future
  3455. * @param {?} paramsInheritanceStrategy
  3456. * @return {?}
  3457. */
  3458. runResolve(future, paramsInheritanceStrategy) {
  3459. const /** @type {?} */ resolve = future._resolve;
  3460. return this.resolveNode(resolve, future).pipe(map((resolvedData) => {
  3461. future._resolvedData = resolvedData;
  3462. future.data = Object.assign({}, future.data, inheritedParamsDataResolve(future, paramsInheritanceStrategy).resolve);
  3463. return null;
  3464. }));
  3465. }
  3466. /**
  3467. * @param {?} resolve
  3468. * @param {?} future
  3469. * @return {?}
  3470. */
  3471. resolveNode(resolve, future) {
  3472. const /** @type {?} */ keys = Object.keys(resolve);
  3473. if (keys.length === 0) {
  3474. return of({});
  3475. }
  3476. if (keys.length === 1) {
  3477. const /** @type {?} */ key = keys[0];
  3478. return this.getResolver(resolve[key], future).pipe(map((value) => {
  3479. return { [key]: value };
  3480. }));
  3481. }
  3482. const /** @type {?} */ data = {};
  3483. const /** @type {?} */ runningResolvers$ = from(keys).pipe(mergeMap((key) => {
  3484. return this.getResolver(resolve[key], future).pipe(map((value) => {
  3485. data[key] = value;
  3486. return value;
  3487. }));
  3488. }));
  3489. return runningResolvers$.pipe(last(), map(() => data));
  3490. }
  3491. /**
  3492. * @param {?} injectionToken
  3493. * @param {?} future
  3494. * @return {?}
  3495. */
  3496. getResolver(injectionToken, future) {
  3497. const /** @type {?} */ resolver = this.getToken(injectionToken, future);
  3498. return resolver.resolve ? wrapIntoObservable(resolver.resolve(future, this.future)) :
  3499. wrapIntoObservable(resolver(future, this.future));
  3500. }
  3501. /**
  3502. * @param {?} token
  3503. * @param {?} snapshot
  3504. * @return {?}
  3505. */
  3506. getToken(token, snapshot) {
  3507. const /** @type {?} */ config = closestLoadedConfig(snapshot);
  3508. const /** @type {?} */ injector = config ? config.module.injector : this.moduleInjector;
  3509. return injector.get(token);
  3510. }
  3511. }
  3512. /**
  3513. * @param {?} snapshot
  3514. * @return {?}
  3515. */
  3516. function closestLoadedConfig(snapshot) {
  3517. if (!snapshot)
  3518. return null;
  3519. for (let /** @type {?} */ s = snapshot.parent; s; s = s.parent) {
  3520. const /** @type {?} */ route = s.routeConfig;
  3521. if (route && route._loadedConfig)
  3522. return route._loadedConfig;
  3523. }
  3524. return null;
  3525. }
  3526. /**
  3527. * @fileoverview added by tsickle
  3528. * @suppress {checkTypes} checked by tsc
  3529. */
  3530. class NoMatch$1 {
  3531. }
  3532. /**
  3533. * @param {?} rootComponentType
  3534. * @param {?} config
  3535. * @param {?} urlTree
  3536. * @param {?} url
  3537. * @param {?=} paramsInheritanceStrategy
  3538. * @return {?}
  3539. */
  3540. function recognize(rootComponentType, config, urlTree, url, paramsInheritanceStrategy = 'emptyOnly') {
  3541. return new Recognizer(rootComponentType, config, urlTree, url, paramsInheritanceStrategy)
  3542. .recognize();
  3543. }
  3544. class Recognizer {
  3545. /**
  3546. * @param {?} rootComponentType
  3547. * @param {?} config
  3548. * @param {?} urlTree
  3549. * @param {?} url
  3550. * @param {?} paramsInheritanceStrategy
  3551. */
  3552. constructor(rootComponentType, config, urlTree, url, paramsInheritanceStrategy) {
  3553. this.rootComponentType = rootComponentType;
  3554. this.config = config;
  3555. this.urlTree = urlTree;
  3556. this.url = url;
  3557. this.paramsInheritanceStrategy = paramsInheritanceStrategy;
  3558. }
  3559. /**
  3560. * @return {?}
  3561. */
  3562. recognize() {
  3563. try {
  3564. const /** @type {?} */ rootSegmentGroup = split$1(this.urlTree.root, [], [], this.config).segmentGroup;
  3565. const /** @type {?} */ children = this.processSegmentGroup(this.config, rootSegmentGroup, PRIMARY_OUTLET);
  3566. const /** @type {?} */ root = new ActivatedRouteSnapshot([], Object.freeze({}), Object.freeze(Object.assign({}, this.urlTree.queryParams)), /** @type {?} */ ((this.urlTree.fragment)), {}, PRIMARY_OUTLET, this.rootComponentType, null, this.urlTree.root, -1, {});
  3567. const /** @type {?} */ rootNode = new TreeNode(root, children);
  3568. const /** @type {?} */ routeState = new RouterStateSnapshot(this.url, rootNode);
  3569. this.inheritParamsAndData(routeState._root);
  3570. return of(routeState);
  3571. }
  3572. catch (/** @type {?} */ e) {
  3573. return new Observable((obs) => obs.error(e));
  3574. }
  3575. }
  3576. /**
  3577. * @param {?} routeNode
  3578. * @return {?}
  3579. */
  3580. inheritParamsAndData(routeNode) {
  3581. const /** @type {?} */ route = routeNode.value;
  3582. const /** @type {?} */ i = inheritedParamsDataResolve(route, this.paramsInheritanceStrategy);
  3583. route.params = Object.freeze(i.params);
  3584. route.data = Object.freeze(i.data);
  3585. routeNode.children.forEach(n => this.inheritParamsAndData(n));
  3586. }
  3587. /**
  3588. * @param {?} config
  3589. * @param {?} segmentGroup
  3590. * @param {?} outlet
  3591. * @return {?}
  3592. */
  3593. processSegmentGroup(config, segmentGroup, outlet) {
  3594. if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
  3595. return this.processChildren(config, segmentGroup);
  3596. }
  3597. return this.processSegment(config, segmentGroup, segmentGroup.segments, outlet);
  3598. }
  3599. /**
  3600. * @param {?} config
  3601. * @param {?} segmentGroup
  3602. * @return {?}
  3603. */
  3604. processChildren(config, segmentGroup) {
  3605. const /** @type {?} */ children = mapChildrenIntoArray(segmentGroup, (child, childOutlet) => this.processSegmentGroup(config, child, childOutlet));
  3606. checkOutletNameUniqueness(children);
  3607. sortActivatedRouteSnapshots(children);
  3608. return children;
  3609. }
  3610. /**
  3611. * @param {?} config
  3612. * @param {?} segmentGroup
  3613. * @param {?} segments
  3614. * @param {?} outlet
  3615. * @return {?}
  3616. */
  3617. processSegment(config, segmentGroup, segments, outlet) {
  3618. for (const /** @type {?} */ r of config) {
  3619. try {
  3620. return this.processSegmentAgainstRoute(r, segmentGroup, segments, outlet);
  3621. }
  3622. catch (/** @type {?} */ e) {
  3623. if (!(e instanceof NoMatch$1))
  3624. throw e;
  3625. }
  3626. }
  3627. if (this.noLeftoversInUrl(segmentGroup, segments, outlet)) {
  3628. return [];
  3629. }
  3630. throw new NoMatch$1();
  3631. }
  3632. /**
  3633. * @param {?} segmentGroup
  3634. * @param {?} segments
  3635. * @param {?} outlet
  3636. * @return {?}
  3637. */
  3638. noLeftoversInUrl(segmentGroup, segments, outlet) {
  3639. return segments.length === 0 && !segmentGroup.children[outlet];
  3640. }
  3641. /**
  3642. * @param {?} route
  3643. * @param {?} rawSegment
  3644. * @param {?} segments
  3645. * @param {?} outlet
  3646. * @return {?}
  3647. */
  3648. processSegmentAgainstRoute(route, rawSegment, segments, outlet) {
  3649. if (route.redirectTo)
  3650. throw new NoMatch$1();
  3651. if ((route.outlet || PRIMARY_OUTLET) !== outlet)
  3652. throw new NoMatch$1();
  3653. let /** @type {?} */ snapshot;
  3654. let /** @type {?} */ consumedSegments = [];
  3655. let /** @type {?} */ rawSlicedSegments = [];
  3656. if (route.path === '**') {
  3657. const /** @type {?} */ params = segments.length > 0 ? /** @type {?} */ ((last$1(segments))).parameters : {};
  3658. snapshot = new ActivatedRouteSnapshot(segments, params, Object.freeze(Object.assign({}, this.urlTree.queryParams)), /** @type {?} */ ((this.urlTree.fragment)), getData(route), outlet, /** @type {?} */ ((route.component)), route, getSourceSegmentGroup(rawSegment), getPathIndexShift(rawSegment) + segments.length, getResolve(route));
  3659. }
  3660. else {
  3661. const /** @type {?} */ result = match$1(rawSegment, route, segments);
  3662. consumedSegments = result.consumedSegments;
  3663. rawSlicedSegments = segments.slice(result.lastChild);
  3664. snapshot = new ActivatedRouteSnapshot(consumedSegments, result.parameters, Object.freeze(Object.assign({}, this.urlTree.queryParams)), /** @type {?} */ ((this.urlTree.fragment)), getData(route), outlet, /** @type {?} */ ((route.component)), route, getSourceSegmentGroup(rawSegment), getPathIndexShift(rawSegment) + consumedSegments.length, getResolve(route));
  3665. }
  3666. const /** @type {?} */ childConfig = getChildConfig(route);
  3667. const { segmentGroup, slicedSegments } = split$1(rawSegment, consumedSegments, rawSlicedSegments, childConfig);
  3668. if (slicedSegments.length === 0 && segmentGroup.hasChildren()) {
  3669. const /** @type {?} */ children = this.processChildren(childConfig, segmentGroup);
  3670. return [new TreeNode(snapshot, children)];
  3671. }
  3672. if (childConfig.length === 0 && slicedSegments.length === 0) {
  3673. return [new TreeNode(snapshot, [])];
  3674. }
  3675. const /** @type {?} */ children = this.processSegment(childConfig, segmentGroup, slicedSegments, PRIMARY_OUTLET);
  3676. return [new TreeNode(snapshot, children)];
  3677. }
  3678. }
  3679. /**
  3680. * @param {?} nodes
  3681. * @return {?}
  3682. */
  3683. function sortActivatedRouteSnapshots(nodes) {
  3684. nodes.sort((a, b) => {
  3685. if (a.value.outlet === PRIMARY_OUTLET)
  3686. return -1;
  3687. if (b.value.outlet === PRIMARY_OUTLET)
  3688. return 1;
  3689. return a.value.outlet.localeCompare(b.value.outlet);
  3690. });
  3691. }
  3692. /**
  3693. * @param {?} route
  3694. * @return {?}
  3695. */
  3696. function getChildConfig(route) {
  3697. if (route.children) {
  3698. return route.children;
  3699. }
  3700. if (route.loadChildren) {
  3701. return /** @type {?} */ ((route._loadedConfig)).routes;
  3702. }
  3703. return [];
  3704. }
  3705. /**
  3706. * @param {?} segmentGroup
  3707. * @param {?} route
  3708. * @param {?} segments
  3709. * @return {?}
  3710. */
  3711. function match$1(segmentGroup, route, segments) {
  3712. if (route.path === '') {
  3713. if (route.pathMatch === 'full' && (segmentGroup.hasChildren() || segments.length > 0)) {
  3714. throw new NoMatch$1();
  3715. }
  3716. return { consumedSegments: [], lastChild: 0, parameters: {} };
  3717. }
  3718. const /** @type {?} */ matcher = route.matcher || defaultUrlMatcher;
  3719. const /** @type {?} */ res = matcher(segments, segmentGroup, route);
  3720. if (!res)
  3721. throw new NoMatch$1();
  3722. const /** @type {?} */ posParams = {};
  3723. forEach(/** @type {?} */ ((res.posParams)), (v, k) => { posParams[k] = v.path; });
  3724. const /** @type {?} */ parameters = res.consumed.length > 0 ? Object.assign({}, posParams, res.consumed[res.consumed.length - 1].parameters) :
  3725. posParams;
  3726. return { consumedSegments: res.consumed, lastChild: res.consumed.length, parameters };
  3727. }
  3728. /**
  3729. * @param {?} nodes
  3730. * @return {?}
  3731. */
  3732. function checkOutletNameUniqueness(nodes) {
  3733. const /** @type {?} */ names = {};
  3734. nodes.forEach(n => {
  3735. const /** @type {?} */ routeWithSameOutletName = names[n.value.outlet];
  3736. if (routeWithSameOutletName) {
  3737. const /** @type {?} */ p = routeWithSameOutletName.url.map(s => s.toString()).join('/');
  3738. const /** @type {?} */ c = n.value.url.map(s => s.toString()).join('/');
  3739. throw new Error(`Two segments cannot have the same outlet name: '${p}' and '${c}'.`);
  3740. }
  3741. names[n.value.outlet] = n.value;
  3742. });
  3743. }
  3744. /**
  3745. * @param {?} segmentGroup
  3746. * @return {?}
  3747. */
  3748. function getSourceSegmentGroup(segmentGroup) {
  3749. let /** @type {?} */ s = segmentGroup;
  3750. while (s._sourceSegment) {
  3751. s = s._sourceSegment;
  3752. }
  3753. return s;
  3754. }
  3755. /**
  3756. * @param {?} segmentGroup
  3757. * @return {?}
  3758. */
  3759. function getPathIndexShift(segmentGroup) {
  3760. let /** @type {?} */ s = segmentGroup;
  3761. let /** @type {?} */ res = (s._segmentIndexShift ? s._segmentIndexShift : 0);
  3762. while (s._sourceSegment) {
  3763. s = s._sourceSegment;
  3764. res += (s._segmentIndexShift ? s._segmentIndexShift : 0);
  3765. }
  3766. return res - 1;
  3767. }
  3768. /**
  3769. * @param {?} segmentGroup
  3770. * @param {?} consumedSegments
  3771. * @param {?} slicedSegments
  3772. * @param {?} config
  3773. * @return {?}
  3774. */
  3775. function split$1(segmentGroup, consumedSegments, slicedSegments, config) {
  3776. if (slicedSegments.length > 0 &&
  3777. containsEmptyPathMatchesWithNamedOutlets(segmentGroup, slicedSegments, config)) {
  3778. const /** @type {?} */ s = new UrlSegmentGroup(consumedSegments, createChildrenForEmptyPaths(segmentGroup, consumedSegments, config, new UrlSegmentGroup(slicedSegments, segmentGroup.children)));
  3779. s._sourceSegment = segmentGroup;
  3780. s._segmentIndexShift = consumedSegments.length;
  3781. return { segmentGroup: s, slicedSegments: [] };
  3782. }
  3783. if (slicedSegments.length === 0 &&
  3784. containsEmptyPathMatches(segmentGroup, slicedSegments, config)) {
  3785. const /** @type {?} */ s = new UrlSegmentGroup(segmentGroup.segments, addEmptyPathsToChildrenIfNeeded(segmentGroup, slicedSegments, config, segmentGroup.children));
  3786. s._sourceSegment = segmentGroup;
  3787. s._segmentIndexShift = consumedSegments.length;
  3788. return { segmentGroup: s, slicedSegments };
  3789. }
  3790. const /** @type {?} */ s = new UrlSegmentGroup(segmentGroup.segments, segmentGroup.children);
  3791. s._sourceSegment = segmentGroup;
  3792. s._segmentIndexShift = consumedSegments.length;
  3793. return { segmentGroup: s, slicedSegments };
  3794. }
  3795. /**
  3796. * @param {?} segmentGroup
  3797. * @param {?} slicedSegments
  3798. * @param {?} routes
  3799. * @param {?} children
  3800. * @return {?}
  3801. */
  3802. function addEmptyPathsToChildrenIfNeeded(segmentGroup, slicedSegments, routes, children) {
  3803. const /** @type {?} */ res = {};
  3804. for (const /** @type {?} */ r of routes) {
  3805. if (emptyPathMatch(segmentGroup, slicedSegments, r) && !children[getOutlet$1(r)]) {
  3806. const /** @type {?} */ s = new UrlSegmentGroup([], {});
  3807. s._sourceSegment = segmentGroup;
  3808. s._segmentIndexShift = segmentGroup.segments.length;
  3809. res[getOutlet$1(r)] = s;
  3810. }
  3811. }
  3812. return Object.assign({}, children, res);
  3813. }
  3814. /**
  3815. * @param {?} segmentGroup
  3816. * @param {?} consumedSegments
  3817. * @param {?} routes
  3818. * @param {?} primarySegment
  3819. * @return {?}
  3820. */
  3821. function createChildrenForEmptyPaths(segmentGroup, consumedSegments, routes, primarySegment) {
  3822. const /** @type {?} */ res = {};
  3823. res[PRIMARY_OUTLET] = primarySegment;
  3824. primarySegment._sourceSegment = segmentGroup;
  3825. primarySegment._segmentIndexShift = consumedSegments.length;
  3826. for (const /** @type {?} */ r of routes) {
  3827. if (r.path === '' && getOutlet$1(r) !== PRIMARY_OUTLET) {
  3828. const /** @type {?} */ s = new UrlSegmentGroup([], {});
  3829. s._sourceSegment = segmentGroup;
  3830. s._segmentIndexShift = consumedSegments.length;
  3831. res[getOutlet$1(r)] = s;
  3832. }
  3833. }
  3834. return res;
  3835. }
  3836. /**
  3837. * @param {?} segmentGroup
  3838. * @param {?} slicedSegments
  3839. * @param {?} routes
  3840. * @return {?}
  3841. */
  3842. function containsEmptyPathMatchesWithNamedOutlets(segmentGroup, slicedSegments, routes) {
  3843. return routes.some(r => emptyPathMatch(segmentGroup, slicedSegments, r) && getOutlet$1(r) !== PRIMARY_OUTLET);
  3844. }
  3845. /**
  3846. * @param {?} segmentGroup
  3847. * @param {?} slicedSegments
  3848. * @param {?} routes
  3849. * @return {?}
  3850. */
  3851. function containsEmptyPathMatches(segmentGroup, slicedSegments, routes) {
  3852. return routes.some(r => emptyPathMatch(segmentGroup, slicedSegments, r));
  3853. }
  3854. /**
  3855. * @param {?} segmentGroup
  3856. * @param {?} slicedSegments
  3857. * @param {?} r
  3858. * @return {?}
  3859. */
  3860. function emptyPathMatch(segmentGroup, slicedSegments, r) {
  3861. if ((segmentGroup.hasChildren() || slicedSegments.length > 0) && r.pathMatch === 'full') {
  3862. return false;
  3863. }
  3864. return r.path === '' && r.redirectTo === undefined;
  3865. }
  3866. /**
  3867. * @param {?} route
  3868. * @return {?}
  3869. */
  3870. function getOutlet$1(route) {
  3871. return route.outlet || PRIMARY_OUTLET;
  3872. }
  3873. /**
  3874. * @param {?} route
  3875. * @return {?}
  3876. */
  3877. function getData(route) {
  3878. return route.data || {};
  3879. }
  3880. /**
  3881. * @param {?} route
  3882. * @return {?}
  3883. */
  3884. function getResolve(route) {
  3885. return route.resolve || {};
  3886. }
  3887. /**
  3888. * @fileoverview added by tsickle
  3889. * @suppress {checkTypes} checked by tsc
  3890. */
  3891. /**
  3892. * @license
  3893. * Copyright Google Inc. All Rights Reserved.
  3894. *
  3895. * Use of this source code is governed by an MIT-style license that can be
  3896. * found in the LICENSE file at https://angular.io/license
  3897. */
  3898. /**
  3899. * \@description
  3900. *
  3901. * Provides a way to customize when activated routes get reused.
  3902. *
  3903. * \@experimental
  3904. * @abstract
  3905. */
  3906. class RouteReuseStrategy {
  3907. }
  3908. /**
  3909. * Does not detach any subtrees. Reuses routes as long as their route config is the same.
  3910. */
  3911. class DefaultRouteReuseStrategy {
  3912. /**
  3913. * @param {?} route
  3914. * @return {?}
  3915. */
  3916. shouldDetach(route) { return false; }
  3917. /**
  3918. * @param {?} route
  3919. * @param {?} detachedTree
  3920. * @return {?}
  3921. */
  3922. store(route, detachedTree) { }
  3923. /**
  3924. * @param {?} route
  3925. * @return {?}
  3926. */
  3927. shouldAttach(route) { return false; }
  3928. /**
  3929. * @param {?} route
  3930. * @return {?}
  3931. */
  3932. retrieve(route) { return null; }
  3933. /**
  3934. * @param {?} future
  3935. * @param {?} curr
  3936. * @return {?}
  3937. */
  3938. shouldReuseRoute(future, curr) {
  3939. return future.routeConfig === curr.routeConfig;
  3940. }
  3941. }
  3942. /**
  3943. * @fileoverview added by tsickle
  3944. * @suppress {checkTypes} checked by tsc
  3945. */
  3946. /**
  3947. * \@docsNotRequired
  3948. * \@experimental
  3949. */
  3950. const /** @type {?} */ ROUTES = new InjectionToken('ROUTES');
  3951. class RouterConfigLoader {
  3952. /**
  3953. * @param {?} loader
  3954. * @param {?} compiler
  3955. * @param {?=} onLoadStartListener
  3956. * @param {?=} onLoadEndListener
  3957. */
  3958. constructor(loader, compiler, onLoadStartListener, onLoadEndListener) {
  3959. this.loader = loader;
  3960. this.compiler = compiler;
  3961. this.onLoadStartListener = onLoadStartListener;
  3962. this.onLoadEndListener = onLoadEndListener;
  3963. }
  3964. /**
  3965. * @param {?} parentInjector
  3966. * @param {?} route
  3967. * @return {?}
  3968. */
  3969. load(parentInjector, route) {
  3970. if (this.onLoadStartListener) {
  3971. this.onLoadStartListener(route);
  3972. }
  3973. const /** @type {?} */ moduleFactory$ = this.loadModuleFactory(/** @type {?} */ ((route.loadChildren)));
  3974. return moduleFactory$.pipe(map((factory) => {
  3975. if (this.onLoadEndListener) {
  3976. this.onLoadEndListener(route);
  3977. }
  3978. const /** @type {?} */ module = factory.create(parentInjector);
  3979. return new LoadedRouterConfig(flatten(module.injector.get(ROUTES)).map(standardizeConfig), module);
  3980. }));
  3981. }
  3982. /**
  3983. * @param {?} loadChildren
  3984. * @return {?}
  3985. */
  3986. loadModuleFactory(loadChildren) {
  3987. if (typeof loadChildren === 'string') {
  3988. return from(this.loader.load(loadChildren));
  3989. }
  3990. else {
  3991. return wrapIntoObservable(loadChildren()).pipe(mergeMap((t) => {
  3992. if (t instanceof NgModuleFactory) {
  3993. return of(t);
  3994. }
  3995. else {
  3996. return from(this.compiler.compileModuleAsync(t));
  3997. }
  3998. }));
  3999. }
  4000. }
  4001. }
  4002. /**
  4003. * @fileoverview added by tsickle
  4004. * @suppress {checkTypes} checked by tsc
  4005. */
  4006. /**
  4007. * @license
  4008. * Copyright Google Inc. All Rights Reserved.
  4009. *
  4010. * Use of this source code is governed by an MIT-style license that can be
  4011. * found in the LICENSE file at https://angular.io/license
  4012. */
  4013. /**
  4014. * \@description
  4015. *
  4016. * Provides a way to migrate AngularJS applications to Angular.
  4017. *
  4018. * \@experimental
  4019. * @abstract
  4020. */
  4021. class UrlHandlingStrategy {
  4022. }
  4023. /**
  4024. * \@experimental
  4025. */
  4026. class DefaultUrlHandlingStrategy {
  4027. /**
  4028. * @param {?} url
  4029. * @return {?}
  4030. */
  4031. shouldProcessUrl(url) { return true; }
  4032. /**
  4033. * @param {?} url
  4034. * @return {?}
  4035. */
  4036. extract(url) { return url; }
  4037. /**
  4038. * @param {?} newUrlPart
  4039. * @param {?} wholeUrl
  4040. * @return {?}
  4041. */
  4042. merge(newUrlPart, wholeUrl) { return newUrlPart; }
  4043. }
  4044. /**
  4045. * @fileoverview added by tsickle
  4046. * @suppress {checkTypes} checked by tsc
  4047. */
  4048. /**
  4049. * @param {?} error
  4050. * @return {?}
  4051. */
  4052. function defaultErrorHandler(error) {
  4053. throw error;
  4054. }
  4055. /**
  4056. * @param {?} error
  4057. * @param {?} urlSerializer
  4058. * @param {?} url
  4059. * @return {?}
  4060. */
  4061. function defaultMalformedUriErrorHandler(error, urlSerializer, url) {
  4062. return urlSerializer.parse('/');
  4063. }
  4064. /**
  4065. * \@internal
  4066. * @param {?} snapshot
  4067. * @return {?}
  4068. */
  4069. function defaultRouterHook(snapshot) {
  4070. return /** @type {?} */ (of(null));
  4071. }
  4072. /**
  4073. * \@description
  4074. *
  4075. * Provides the navigation and url manipulation capabilities.
  4076. *
  4077. * See `Routes` for more details and examples.
  4078. *
  4079. * \@ngModule RouterModule
  4080. *
  4081. *
  4082. */
  4083. class Router {
  4084. /**
  4085. * Creates the router service.
  4086. * @param {?} rootComponentType
  4087. * @param {?} urlSerializer
  4088. * @param {?} rootContexts
  4089. * @param {?} location
  4090. * @param {?} injector
  4091. * @param {?} loader
  4092. * @param {?} compiler
  4093. * @param {?} config
  4094. */
  4095. constructor(rootComponentType, urlSerializer, rootContexts, location, injector, loader, compiler, config) {
  4096. this.rootComponentType = rootComponentType;
  4097. this.urlSerializer = urlSerializer;
  4098. this.rootContexts = rootContexts;
  4099. this.location = location;
  4100. this.config = config;
  4101. this.navigations = new BehaviorSubject(/** @type {?} */ ((null)));
  4102. this.navigationId = 0;
  4103. this.events = new Subject();
  4104. /**
  4105. * Error handler that is invoked when a navigation errors.
  4106. *
  4107. * See `ErrorHandler` for more information.
  4108. */
  4109. this.errorHandler = defaultErrorHandler;
  4110. /**
  4111. * Malformed uri error handler is invoked when `Router.parseUrl(url)` throws an
  4112. * error due to containing an invalid character. The most common case would be a `%` sign
  4113. * that's not encoded and is not part of a percent encoded sequence.
  4114. */
  4115. this.malformedUriErrorHandler = defaultMalformedUriErrorHandler;
  4116. /**
  4117. * Indicates if at least one navigation happened.
  4118. */
  4119. this.navigated = false;
  4120. this.lastSuccessfulId = -1;
  4121. /**
  4122. * Used by RouterModule. This allows us to
  4123. * pause the navigation either before preactivation or after it.
  4124. * \@internal
  4125. */
  4126. this.hooks = {
  4127. beforePreactivation: defaultRouterHook,
  4128. afterPreactivation: defaultRouterHook
  4129. };
  4130. /**
  4131. * Extracts and merges URLs. Used for AngularJS to Angular migrations.
  4132. */
  4133. this.urlHandlingStrategy = new DefaultUrlHandlingStrategy();
  4134. this.routeReuseStrategy = new DefaultRouteReuseStrategy();
  4135. /**
  4136. * Define what the router should do if it receives a navigation request to the current URL.
  4137. * By default, the router will ignore this navigation. However, this prevents features such
  4138. * as a "refresh" button. Use this option to configure the behavior when navigating to the
  4139. * current URL. Default is 'ignore'.
  4140. */
  4141. this.onSameUrlNavigation = 'ignore';
  4142. /**
  4143. * Defines how the router merges params, data and resolved data from parent to child
  4144. * routes. Available options are:
  4145. *
  4146. * - `'emptyOnly'`, the default, only inherits parent params for path-less or component-less
  4147. * routes.
  4148. * - `'always'`, enables unconditional inheritance of parent params.
  4149. */
  4150. this.paramsInheritanceStrategy = 'emptyOnly';
  4151. const /** @type {?} */ onLoadStart = (r) => this.triggerEvent(new RouteConfigLoadStart(r));
  4152. const /** @type {?} */ onLoadEnd = (r) => this.triggerEvent(new RouteConfigLoadEnd(r));
  4153. this.ngModule = injector.get(NgModuleRef);
  4154. this.resetConfig(config);
  4155. this.currentUrlTree = createEmptyUrlTree();
  4156. this.rawUrlTree = this.currentUrlTree;
  4157. this.configLoader = new RouterConfigLoader(loader, compiler, onLoadStart, onLoadEnd);
  4158. this.routerState = createEmptyState(this.currentUrlTree, this.rootComponentType);
  4159. this.processNavigations();
  4160. }
  4161. /**
  4162. * \@internal
  4163. * TODO: this should be removed once the constructor of the router made internal
  4164. * @param {?} rootComponentType
  4165. * @return {?}
  4166. */
  4167. resetRootComponentType(rootComponentType) {
  4168. this.rootComponentType = rootComponentType;
  4169. // TODO: vsavkin router 4.0 should make the root component set to null
  4170. // this will simplify the lifecycle of the router.
  4171. this.routerState.root.component = this.rootComponentType;
  4172. }
  4173. /**
  4174. * Sets up the location change listener and performs the initial navigation.
  4175. * @return {?}
  4176. */
  4177. initialNavigation() {
  4178. this.setUpLocationChangeListener();
  4179. if (this.navigationId === 0) {
  4180. this.navigateByUrl(this.location.path(true), { replaceUrl: true });
  4181. }
  4182. }
  4183. /**
  4184. * Sets up the location change listener.
  4185. * @return {?}
  4186. */
  4187. setUpLocationChangeListener() {
  4188. // Don't need to use Zone.wrap any more, because zone.js
  4189. // already patch onPopState, so location change callback will
  4190. // run into ngZone
  4191. if (!this.locationSubscription) {
  4192. this.locationSubscription = /** @type {?} */ (this.location.subscribe((change) => {
  4193. let /** @type {?} */ rawUrlTree = this.parseUrl(change['url']);
  4194. const /** @type {?} */ source = change['type'] === 'popstate' ? 'popstate' : 'hashchange';
  4195. const /** @type {?} */ state = change.state && change.state.navigationId ?
  4196. { navigationId: change.state.navigationId } :
  4197. null;
  4198. setTimeout(() => { this.scheduleNavigation(rawUrlTree, source, state, { replaceUrl: true }); }, 0);
  4199. }));
  4200. }
  4201. }
  4202. /**
  4203. * The current url
  4204. * @return {?}
  4205. */
  4206. get url() { return this.serializeUrl(this.currentUrlTree); }
  4207. /**
  4208. * \@internal
  4209. * @param {?} e
  4210. * @return {?}
  4211. */
  4212. triggerEvent(e) { (/** @type {?} */ (this.events)).next(e); }
  4213. /**
  4214. * Resets the configuration used for navigation and generating links.
  4215. *
  4216. * ### Usage
  4217. *
  4218. * ```
  4219. * router.resetConfig([
  4220. * { path: 'team/:id', component: TeamCmp, children: [
  4221. * { path: 'simple', component: SimpleCmp },
  4222. * { path: 'user/:name', component: UserCmp }
  4223. * ]}
  4224. * ]);
  4225. * ```
  4226. * @param {?} config
  4227. * @return {?}
  4228. */
  4229. resetConfig(config) {
  4230. validateConfig(config);
  4231. this.config = config.map(standardizeConfig);
  4232. this.navigated = false;
  4233. this.lastSuccessfulId = -1;
  4234. }
  4235. /**
  4236. * \@docsNotRequired
  4237. * @return {?}
  4238. */
  4239. ngOnDestroy() { this.dispose(); }
  4240. /**
  4241. * Disposes of the router
  4242. * @return {?}
  4243. */
  4244. dispose() {
  4245. if (this.locationSubscription) {
  4246. this.locationSubscription.unsubscribe();
  4247. this.locationSubscription = /** @type {?} */ ((null));
  4248. }
  4249. }
  4250. /**
  4251. * Applies an array of commands to the current url tree and creates a new url tree.
  4252. *
  4253. * When given an activate route, applies the given commands starting from the route.
  4254. * When not given a route, applies the given command starting from the root.
  4255. *
  4256. * ### Usage
  4257. *
  4258. * ```
  4259. * // create /team/33/user/11
  4260. * router.createUrlTree(['/team', 33, 'user', 11]);
  4261. *
  4262. * // create /team/33;expand=true/user/11
  4263. * router.createUrlTree(['/team', 33, {expand: true}, 'user', 11]);
  4264. *
  4265. * // you can collapse static segments like this (this works only with the first passed-in value):
  4266. * router.createUrlTree(['/team/33/user', userId]);
  4267. *
  4268. * // If the first segment can contain slashes, and you do not want the router to split it, you
  4269. * // can do the following:
  4270. *
  4271. * router.createUrlTree([{segmentPath: '/one/two'}]);
  4272. *
  4273. * // create /team/33/(user/11//right:chat)
  4274. * router.createUrlTree(['/team', 33, {outlets: {primary: 'user/11', right: 'chat'}}]);
  4275. *
  4276. * // remove the right secondary node
  4277. * router.createUrlTree(['/team', 33, {outlets: {primary: 'user/11', right: null}}]);
  4278. *
  4279. * // assuming the current url is `/team/33/user/11` and the route points to `user/11`
  4280. *
  4281. * // navigate to /team/33/user/11/details
  4282. * router.createUrlTree(['details'], {relativeTo: route});
  4283. *
  4284. * // navigate to /team/33/user/22
  4285. * router.createUrlTree(['../22'], {relativeTo: route});
  4286. *
  4287. * // navigate to /team/44/user/22
  4288. * router.createUrlTree(['../../team/44/user/22'], {relativeTo: route});
  4289. * ```
  4290. * @param {?} commands
  4291. * @param {?=} navigationExtras
  4292. * @return {?}
  4293. */
  4294. createUrlTree(commands, navigationExtras = {}) {
  4295. const { relativeTo, queryParams, fragment, preserveQueryParams, queryParamsHandling, preserveFragment } = navigationExtras;
  4296. if (isDevMode() && preserveQueryParams && /** @type {?} */ (console) && /** @type {?} */ (console.warn)) {
  4297. console.warn('preserveQueryParams is deprecated, use queryParamsHandling instead.');
  4298. }
  4299. const /** @type {?} */ a = relativeTo || this.routerState.root;
  4300. const /** @type {?} */ f = preserveFragment ? this.currentUrlTree.fragment : fragment;
  4301. let /** @type {?} */ q = null;
  4302. if (queryParamsHandling) {
  4303. switch (queryParamsHandling) {
  4304. case 'merge':
  4305. q = Object.assign({}, this.currentUrlTree.queryParams, queryParams);
  4306. break;
  4307. case 'preserve':
  4308. q = this.currentUrlTree.queryParams;
  4309. break;
  4310. default:
  4311. q = queryParams || null;
  4312. }
  4313. }
  4314. else {
  4315. q = preserveQueryParams ? this.currentUrlTree.queryParams : queryParams || null;
  4316. }
  4317. if (q !== null) {
  4318. q = this.removeEmptyProps(q);
  4319. }
  4320. return createUrlTree(a, this.currentUrlTree, commands, /** @type {?} */ ((q)), /** @type {?} */ ((f)));
  4321. }
  4322. /**
  4323. * Navigate based on the provided url. This navigation is always absolute.
  4324. *
  4325. * Returns a promise that:
  4326. * - resolves to 'true' when navigation succeeds,
  4327. * - resolves to 'false' when navigation fails,
  4328. * - is rejected when an error happens.
  4329. *
  4330. * ### Usage
  4331. *
  4332. * ```
  4333. * router.navigateByUrl("/team/33/user/11");
  4334. *
  4335. * // Navigate without updating the URL
  4336. * router.navigateByUrl("/team/33/user/11", { skipLocationChange: true });
  4337. * ```
  4338. *
  4339. * In opposite to `navigate`, `navigateByUrl` takes a whole URL
  4340. * and does not apply any delta to the current one.
  4341. * @param {?} url
  4342. * @param {?=} extras
  4343. * @return {?}
  4344. */
  4345. navigateByUrl(url, extras = { skipLocationChange: false }) {
  4346. const /** @type {?} */ urlTree = url instanceof UrlTree ? url : this.parseUrl(url);
  4347. const /** @type {?} */ mergedTree = this.urlHandlingStrategy.merge(urlTree, this.rawUrlTree);
  4348. return this.scheduleNavigation(mergedTree, 'imperative', null, extras);
  4349. }
  4350. /**
  4351. * Navigate based on the provided array of commands and a starting point.
  4352. * If no starting route is provided, the navigation is absolute.
  4353. *
  4354. * Returns a promise that:
  4355. * - resolves to 'true' when navigation succeeds,
  4356. * - resolves to 'false' when navigation fails,
  4357. * - is rejected when an error happens.
  4358. *
  4359. * ### Usage
  4360. *
  4361. * ```
  4362. * router.navigate(['team', 33, 'user', 11], {relativeTo: route});
  4363. *
  4364. * // Navigate without updating the URL
  4365. * router.navigate(['team', 33, 'user', 11], {relativeTo: route, skipLocationChange: true});
  4366. * ```
  4367. *
  4368. * In opposite to `navigateByUrl`, `navigate` always takes a delta that is applied to the current
  4369. * URL.
  4370. * @param {?} commands
  4371. * @param {?=} extras
  4372. * @return {?}
  4373. */
  4374. navigate(commands, extras = { skipLocationChange: false }) {
  4375. validateCommands(commands);
  4376. return this.navigateByUrl(this.createUrlTree(commands, extras), extras);
  4377. }
  4378. /**
  4379. * Serializes a `UrlTree` into a string
  4380. * @param {?} url
  4381. * @return {?}
  4382. */
  4383. serializeUrl(url) { return this.urlSerializer.serialize(url); }
  4384. /**
  4385. * Parses a string into a `UrlTree`
  4386. * @param {?} url
  4387. * @return {?}
  4388. */
  4389. parseUrl(url) {
  4390. let /** @type {?} */ urlTree;
  4391. try {
  4392. urlTree = this.urlSerializer.parse(url);
  4393. }
  4394. catch (/** @type {?} */ e) {
  4395. urlTree = this.malformedUriErrorHandler(e, this.urlSerializer, url);
  4396. }
  4397. return urlTree;
  4398. }
  4399. /**
  4400. * Returns whether the url is activated
  4401. * @param {?} url
  4402. * @param {?} exact
  4403. * @return {?}
  4404. */
  4405. isActive(url, exact) {
  4406. if (url instanceof UrlTree) {
  4407. return containsTree(this.currentUrlTree, url, exact);
  4408. }
  4409. const /** @type {?} */ urlTree = this.parseUrl(url);
  4410. return containsTree(this.currentUrlTree, urlTree, exact);
  4411. }
  4412. /**
  4413. * @param {?} params
  4414. * @return {?}
  4415. */
  4416. removeEmptyProps(params) {
  4417. return Object.keys(params).reduce((result, key) => {
  4418. const /** @type {?} */ value = params[key];
  4419. if (value !== null && value !== undefined) {
  4420. result[key] = value;
  4421. }
  4422. return result;
  4423. }, {});
  4424. }
  4425. /**
  4426. * @return {?}
  4427. */
  4428. processNavigations() {
  4429. this.navigations
  4430. .pipe(concatMap((nav) => {
  4431. if (nav) {
  4432. this.executeScheduledNavigation(nav);
  4433. // a failed navigation should not stop the router from processing
  4434. // further navigations => the catch
  4435. return nav.promise.catch(() => { });
  4436. }
  4437. else {
  4438. return /** @type {?} */ (of(null));
  4439. }
  4440. }))
  4441. .subscribe(() => { });
  4442. }
  4443. /**
  4444. * @param {?} rawUrl
  4445. * @param {?} source
  4446. * @param {?} state
  4447. * @param {?} extras
  4448. * @return {?}
  4449. */
  4450. scheduleNavigation(rawUrl, source, state, extras) {
  4451. const /** @type {?} */ lastNavigation = this.navigations.value;
  4452. // If the user triggers a navigation imperatively (e.g., by using navigateByUrl),
  4453. // and that navigation results in 'replaceState' that leads to the same URL,
  4454. // we should skip those.
  4455. if (lastNavigation && source !== 'imperative' && lastNavigation.source === 'imperative' &&
  4456. lastNavigation.rawUrl.toString() === rawUrl.toString()) {
  4457. return Promise.resolve(true); // return value is not used
  4458. }
  4459. // Because of a bug in IE and Edge, the location class fires two events (popstate and
  4460. // hashchange) every single time. The second one should be ignored. Otherwise, the URL will
  4461. // flicker. Handles the case when a popstate was emitted first.
  4462. if (lastNavigation && source == 'hashchange' && lastNavigation.source === 'popstate' &&
  4463. lastNavigation.rawUrl.toString() === rawUrl.toString()) {
  4464. return Promise.resolve(true); // return value is not used
  4465. }
  4466. // Because of a bug in IE and Edge, the location class fires two events (popstate and
  4467. // hashchange) every single time. The second one should be ignored. Otherwise, the URL will
  4468. // flicker. Handles the case when a hashchange was emitted first.
  4469. if (lastNavigation && source == 'popstate' && lastNavigation.source === 'hashchange' &&
  4470. lastNavigation.rawUrl.toString() === rawUrl.toString()) {
  4471. return Promise.resolve(true); // return value is not used
  4472. }
  4473. let /** @type {?} */ resolve = null;
  4474. let /** @type {?} */ reject = null;
  4475. const /** @type {?} */ promise = new Promise((res, rej) => {
  4476. resolve = res;
  4477. reject = rej;
  4478. });
  4479. const /** @type {?} */ id = ++this.navigationId;
  4480. this.navigations.next({ id, source, state, rawUrl, extras, resolve, reject, promise });
  4481. // Make sure that the error is propagated even though `processNavigations` catch
  4482. // handler does not rethrow
  4483. return promise.catch((e) => Promise.reject(e));
  4484. }
  4485. /**
  4486. * @param {?} __0
  4487. * @return {?}
  4488. */
  4489. executeScheduledNavigation({ id, rawUrl, extras, resolve, reject, source, state }) {
  4490. const /** @type {?} */ url = this.urlHandlingStrategy.extract(rawUrl);
  4491. const /** @type {?} */ urlTransition = !this.navigated || url.toString() !== this.currentUrlTree.toString();
  4492. if ((this.onSameUrlNavigation === 'reload' ? true : urlTransition) &&
  4493. this.urlHandlingStrategy.shouldProcessUrl(rawUrl)) {
  4494. (/** @type {?} */ (this.events))
  4495. .next(new NavigationStart(id, this.serializeUrl(url), source, state));
  4496. Promise.resolve()
  4497. .then((_) => this.runNavigate(url, rawUrl, !!extras.skipLocationChange, !!extras.replaceUrl, id, null))
  4498. .then(resolve, reject);
  4499. // we cannot process the current URL, but we could process the previous one =>
  4500. // we need to do some cleanup
  4501. }
  4502. else if (urlTransition && this.rawUrlTree &&
  4503. this.urlHandlingStrategy.shouldProcessUrl(this.rawUrlTree)) {
  4504. (/** @type {?} */ (this.events))
  4505. .next(new NavigationStart(id, this.serializeUrl(url), source, state));
  4506. Promise.resolve()
  4507. .then((_) => this.runNavigate(url, rawUrl, false, false, id, createEmptyState(url, this.rootComponentType).snapshot))
  4508. .then(resolve, reject);
  4509. }
  4510. else {
  4511. this.rawUrlTree = rawUrl;
  4512. resolve(null);
  4513. }
  4514. }
  4515. /**
  4516. * @param {?} url
  4517. * @param {?} rawUrl
  4518. * @param {?} skipLocationChange
  4519. * @param {?} replaceUrl
  4520. * @param {?} id
  4521. * @param {?} precreatedState
  4522. * @return {?}
  4523. */
  4524. runNavigate(url, rawUrl, skipLocationChange, replaceUrl, id, precreatedState) {
  4525. if (id !== this.navigationId) {
  4526. (/** @type {?} */ (this.events))
  4527. .next(new NavigationCancel(id, this.serializeUrl(url), `Navigation ID ${id} is not equal to the current navigation id ${this.navigationId}`));
  4528. return Promise.resolve(false);
  4529. }
  4530. return new Promise((resolvePromise, rejectPromise) => {
  4531. // create an observable of the url and route state snapshot
  4532. // this operation do not result in any side effects
  4533. let /** @type {?} */ urlAndSnapshot$;
  4534. if (!precreatedState) {
  4535. const /** @type {?} */ moduleInjector = this.ngModule.injector;
  4536. const /** @type {?} */ redirectsApplied$ = applyRedirects(moduleInjector, this.configLoader, this.urlSerializer, url, this.config);
  4537. urlAndSnapshot$ = redirectsApplied$.pipe(mergeMap((appliedUrl) => {
  4538. return recognize(this.rootComponentType, this.config, appliedUrl, this.serializeUrl(appliedUrl), this.paramsInheritanceStrategy)
  4539. .pipe(map((snapshot) => {
  4540. (/** @type {?} */ (this.events))
  4541. .next(new RoutesRecognized(id, this.serializeUrl(url), this.serializeUrl(appliedUrl), snapshot));
  4542. return { appliedUrl, snapshot };
  4543. }));
  4544. }));
  4545. }
  4546. else {
  4547. urlAndSnapshot$ = of({ appliedUrl: url, snapshot: precreatedState });
  4548. }
  4549. const /** @type {?} */ beforePreactivationDone$ = urlAndSnapshot$.pipe(mergeMap((p) => {
  4550. if (typeof p === 'boolean')
  4551. return of(p);
  4552. return this.hooks.beforePreactivation(p.snapshot).pipe(map(() => p));
  4553. }));
  4554. // run preactivation: guards and data resolvers
  4555. let /** @type {?} */ preActivation;
  4556. const /** @type {?} */ preactivationSetup$ = beforePreactivationDone$.pipe(map((p) => {
  4557. if (typeof p === 'boolean')
  4558. return p;
  4559. const { appliedUrl, snapshot } = p;
  4560. const /** @type {?} */ moduleInjector = this.ngModule.injector;
  4561. preActivation = new PreActivation(snapshot, this.routerState.snapshot, moduleInjector, (evt) => this.triggerEvent(evt));
  4562. preActivation.initialize(this.rootContexts);
  4563. return { appliedUrl, snapshot };
  4564. }));
  4565. const /** @type {?} */ preactivationCheckGuards$ = preactivationSetup$.pipe(mergeMap((p) => {
  4566. if (typeof p === 'boolean' || this.navigationId !== id)
  4567. return of(false);
  4568. const { appliedUrl, snapshot } = p;
  4569. this.triggerEvent(new GuardsCheckStart(id, this.serializeUrl(url), this.serializeUrl(appliedUrl), snapshot));
  4570. return preActivation.checkGuards().pipe(map((shouldActivate) => {
  4571. this.triggerEvent(new GuardsCheckEnd(id, this.serializeUrl(url), this.serializeUrl(appliedUrl), snapshot, shouldActivate));
  4572. return { appliedUrl: appliedUrl, snapshot: snapshot, shouldActivate: shouldActivate };
  4573. }));
  4574. }));
  4575. const /** @type {?} */ preactivationResolveData$ = preactivationCheckGuards$.pipe(mergeMap((p) => {
  4576. if (typeof p === 'boolean' || this.navigationId !== id)
  4577. return of(false);
  4578. if (p.shouldActivate && preActivation.isActivating()) {
  4579. this.triggerEvent(new ResolveStart(id, this.serializeUrl(url), this.serializeUrl(p.appliedUrl), p.snapshot));
  4580. return preActivation.resolveData(this.paramsInheritanceStrategy).pipe(map(() => {
  4581. this.triggerEvent(new ResolveEnd(id, this.serializeUrl(url), this.serializeUrl(p.appliedUrl), p.snapshot));
  4582. return p;
  4583. }));
  4584. }
  4585. else {
  4586. return of(p);
  4587. }
  4588. }));
  4589. const /** @type {?} */ preactivationDone$ = preactivationResolveData$.pipe(mergeMap((p) => {
  4590. if (typeof p === 'boolean' || this.navigationId !== id)
  4591. return of(false);
  4592. return this.hooks.afterPreactivation(p.snapshot).pipe(map(() => p));
  4593. }));
  4594. // create router state
  4595. // this operation has side effects => route state is being affected
  4596. const /** @type {?} */ routerState$ = preactivationDone$.pipe(map((p) => {
  4597. if (typeof p === 'boolean' || this.navigationId !== id)
  4598. return false;
  4599. const { appliedUrl, snapshot, shouldActivate } = p;
  4600. if (shouldActivate) {
  4601. const /** @type {?} */ state = createRouterState(this.routeReuseStrategy, snapshot, this.routerState);
  4602. return { appliedUrl, state, shouldActivate };
  4603. }
  4604. else {
  4605. return { appliedUrl, state: null, shouldActivate };
  4606. }
  4607. }));
  4608. this.activateRoutes(routerState$, this.routerState, this.currentUrlTree, id, url, rawUrl, skipLocationChange, replaceUrl, resolvePromise, rejectPromise);
  4609. });
  4610. }
  4611. /**
  4612. * Performs the logic of activating routes. This is a synchronous process by default. While this
  4613. * is a private method, it could be overridden to make activation asynchronous.
  4614. * @param {?} state
  4615. * @param {?} storedState
  4616. * @param {?} storedUrl
  4617. * @param {?} id
  4618. * @param {?} url
  4619. * @param {?} rawUrl
  4620. * @param {?} skipLocationChange
  4621. * @param {?} replaceUrl
  4622. * @param {?} resolvePromise
  4623. * @param {?} rejectPromise
  4624. * @return {?}
  4625. */
  4626. activateRoutes(state, storedState, storedUrl, id, url, rawUrl, skipLocationChange, replaceUrl, resolvePromise, rejectPromise) {
  4627. // applied the new router state
  4628. // this operation has side effects
  4629. let /** @type {?} */ navigationIsSuccessful;
  4630. state
  4631. .forEach((p) => {
  4632. if (typeof p === 'boolean' || !p.shouldActivate || id !== this.navigationId || !p.state) {
  4633. navigationIsSuccessful = false;
  4634. return;
  4635. }
  4636. const { appliedUrl, state } = p;
  4637. this.currentUrlTree = appliedUrl;
  4638. this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, rawUrl);
  4639. (/** @type {?} */ (this)).routerState = state;
  4640. if (!skipLocationChange) {
  4641. const /** @type {?} */ path = this.urlSerializer.serialize(this.rawUrlTree);
  4642. if (this.location.isCurrentPathEqualTo(path) || replaceUrl) {
  4643. this.location.replaceState(path, '', { navigationId: id });
  4644. }
  4645. else {
  4646. this.location.go(path, '', { navigationId: id });
  4647. }
  4648. }
  4649. new ActivateRoutes(this.routeReuseStrategy, state, storedState, (evt) => this.triggerEvent(evt))
  4650. .activate(this.rootContexts);
  4651. navigationIsSuccessful = true;
  4652. })
  4653. .then(() => {
  4654. if (navigationIsSuccessful) {
  4655. this.navigated = true;
  4656. this.lastSuccessfulId = id;
  4657. (/** @type {?} */ (this.events))
  4658. .next(new NavigationEnd(id, this.serializeUrl(url), this.serializeUrl(this.currentUrlTree)));
  4659. resolvePromise(true);
  4660. }
  4661. else {
  4662. this.resetUrlToCurrentUrlTree();
  4663. (/** @type {?} */ (this.events))
  4664. .next(new NavigationCancel(id, this.serializeUrl(url), ''));
  4665. resolvePromise(false);
  4666. }
  4667. }, (e) => {
  4668. if (isNavigationCancelingError(e)) {
  4669. this.navigated = true;
  4670. this.resetStateAndUrl(storedState, storedUrl, rawUrl);
  4671. (/** @type {?} */ (this.events))
  4672. .next(new NavigationCancel(id, this.serializeUrl(url), e.message));
  4673. resolvePromise(false);
  4674. }
  4675. else {
  4676. this.resetStateAndUrl(storedState, storedUrl, rawUrl);
  4677. (/** @type {?} */ (this.events))
  4678. .next(new NavigationError(id, this.serializeUrl(url), e));
  4679. try {
  4680. resolvePromise(this.errorHandler(e));
  4681. }
  4682. catch (/** @type {?} */ ee) {
  4683. rejectPromise(ee);
  4684. }
  4685. }
  4686. });
  4687. }
  4688. /**
  4689. * @param {?} storedState
  4690. * @param {?} storedUrl
  4691. * @param {?} rawUrl
  4692. * @return {?}
  4693. */
  4694. resetStateAndUrl(storedState, storedUrl, rawUrl) {
  4695. (/** @type {?} */ (this)).routerState = storedState;
  4696. this.currentUrlTree = storedUrl;
  4697. this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, rawUrl);
  4698. this.resetUrlToCurrentUrlTree();
  4699. }
  4700. /**
  4701. * @return {?}
  4702. */
  4703. resetUrlToCurrentUrlTree() {
  4704. this.location.replaceState(this.urlSerializer.serialize(this.rawUrlTree), '', { navigationId: this.lastSuccessfulId });
  4705. }
  4706. }
  4707. class ActivateRoutes {
  4708. /**
  4709. * @param {?} routeReuseStrategy
  4710. * @param {?} futureState
  4711. * @param {?} currState
  4712. * @param {?} forwardEvent
  4713. */
  4714. constructor(routeReuseStrategy, futureState, currState, forwardEvent) {
  4715. this.routeReuseStrategy = routeReuseStrategy;
  4716. this.futureState = futureState;
  4717. this.currState = currState;
  4718. this.forwardEvent = forwardEvent;
  4719. }
  4720. /**
  4721. * @param {?} parentContexts
  4722. * @return {?}
  4723. */
  4724. activate(parentContexts) {
  4725. const /** @type {?} */ futureRoot = this.futureState._root;
  4726. const /** @type {?} */ currRoot = this.currState ? this.currState._root : null;
  4727. this.deactivateChildRoutes(futureRoot, currRoot, parentContexts);
  4728. advanceActivatedRoute(this.futureState.root);
  4729. this.activateChildRoutes(futureRoot, currRoot, parentContexts);
  4730. }
  4731. /**
  4732. * @param {?} futureNode
  4733. * @param {?} currNode
  4734. * @param {?} contexts
  4735. * @return {?}
  4736. */
  4737. deactivateChildRoutes(futureNode, currNode, contexts) {
  4738. const /** @type {?} */ children = nodeChildrenAsMap(currNode);
  4739. // Recurse on the routes active in the future state to de-activate deeper children
  4740. futureNode.children.forEach(futureChild => {
  4741. const /** @type {?} */ childOutletName = futureChild.value.outlet;
  4742. this.deactivateRoutes(futureChild, children[childOutletName], contexts);
  4743. delete children[childOutletName];
  4744. });
  4745. // De-activate the routes that will not be re-used
  4746. forEach(children, (v, childName) => {
  4747. this.deactivateRouteAndItsChildren(v, contexts);
  4748. });
  4749. }
  4750. /**
  4751. * @param {?} futureNode
  4752. * @param {?} currNode
  4753. * @param {?} parentContext
  4754. * @return {?}
  4755. */
  4756. deactivateRoutes(futureNode, currNode, parentContext) {
  4757. const /** @type {?} */ future = futureNode.value;
  4758. const /** @type {?} */ curr = currNode ? currNode.value : null;
  4759. if (future === curr) {
  4760. // Reusing the node, check to see if the children need to be de-activated
  4761. if (future.component) {
  4762. // If we have a normal route, we need to go through an outlet.
  4763. const /** @type {?} */ context = parentContext.getContext(future.outlet);
  4764. if (context) {
  4765. this.deactivateChildRoutes(futureNode, currNode, context.children);
  4766. }
  4767. }
  4768. else {
  4769. // if we have a componentless route, we recurse but keep the same outlet map.
  4770. this.deactivateChildRoutes(futureNode, currNode, parentContext);
  4771. }
  4772. }
  4773. else {
  4774. if (curr) {
  4775. // Deactivate the current route which will not be re-used
  4776. this.deactivateRouteAndItsChildren(currNode, parentContext);
  4777. }
  4778. }
  4779. }
  4780. /**
  4781. * @param {?} route
  4782. * @param {?} parentContexts
  4783. * @return {?}
  4784. */
  4785. deactivateRouteAndItsChildren(route, parentContexts) {
  4786. if (this.routeReuseStrategy.shouldDetach(route.value.snapshot)) {
  4787. this.detachAndStoreRouteSubtree(route, parentContexts);
  4788. }
  4789. else {
  4790. this.deactivateRouteAndOutlet(route, parentContexts);
  4791. }
  4792. }
  4793. /**
  4794. * @param {?} route
  4795. * @param {?} parentContexts
  4796. * @return {?}
  4797. */
  4798. detachAndStoreRouteSubtree(route, parentContexts) {
  4799. const /** @type {?} */ context = parentContexts.getContext(route.value.outlet);
  4800. if (context && context.outlet) {
  4801. const /** @type {?} */ componentRef = context.outlet.detach();
  4802. const /** @type {?} */ contexts = context.children.onOutletDeactivated();
  4803. this.routeReuseStrategy.store(route.value.snapshot, { componentRef, route, contexts });
  4804. }
  4805. }
  4806. /**
  4807. * @param {?} route
  4808. * @param {?} parentContexts
  4809. * @return {?}
  4810. */
  4811. deactivateRouteAndOutlet(route, parentContexts) {
  4812. const /** @type {?} */ context = parentContexts.getContext(route.value.outlet);
  4813. if (context) {
  4814. const /** @type {?} */ children = nodeChildrenAsMap(route);
  4815. const /** @type {?} */ contexts = route.value.component ? context.children : parentContexts;
  4816. forEach(children, (v, k) => this.deactivateRouteAndItsChildren(v, contexts));
  4817. if (context.outlet) {
  4818. // Destroy the component
  4819. context.outlet.deactivate();
  4820. // Destroy the contexts for all the outlets that were in the component
  4821. context.children.onOutletDeactivated();
  4822. }
  4823. }
  4824. }
  4825. /**
  4826. * @param {?} futureNode
  4827. * @param {?} currNode
  4828. * @param {?} contexts
  4829. * @return {?}
  4830. */
  4831. activateChildRoutes(futureNode, currNode, contexts) {
  4832. const /** @type {?} */ children = nodeChildrenAsMap(currNode);
  4833. futureNode.children.forEach(c => {
  4834. this.activateRoutes(c, children[c.value.outlet], contexts);
  4835. this.forwardEvent(new ActivationEnd(c.value.snapshot));
  4836. });
  4837. if (futureNode.children.length) {
  4838. this.forwardEvent(new ChildActivationEnd(futureNode.value.snapshot));
  4839. }
  4840. }
  4841. /**
  4842. * @param {?} futureNode
  4843. * @param {?} currNode
  4844. * @param {?} parentContexts
  4845. * @return {?}
  4846. */
  4847. activateRoutes(futureNode, currNode, parentContexts) {
  4848. const /** @type {?} */ future = futureNode.value;
  4849. const /** @type {?} */ curr = currNode ? currNode.value : null;
  4850. advanceActivatedRoute(future);
  4851. // reusing the node
  4852. if (future === curr) {
  4853. if (future.component) {
  4854. // If we have a normal route, we need to go through an outlet.
  4855. const /** @type {?} */ context = parentContexts.getOrCreateContext(future.outlet);
  4856. this.activateChildRoutes(futureNode, currNode, context.children);
  4857. }
  4858. else {
  4859. // if we have a componentless route, we recurse but keep the same outlet map.
  4860. this.activateChildRoutes(futureNode, currNode, parentContexts);
  4861. }
  4862. }
  4863. else {
  4864. if (future.component) {
  4865. // if we have a normal route, we need to place the component into the outlet and recurse.
  4866. const /** @type {?} */ context = parentContexts.getOrCreateContext(future.outlet);
  4867. if (this.routeReuseStrategy.shouldAttach(future.snapshot)) {
  4868. const /** @type {?} */ stored = (/** @type {?} */ (this.routeReuseStrategy.retrieve(future.snapshot)));
  4869. this.routeReuseStrategy.store(future.snapshot, null);
  4870. context.children.onOutletReAttached(stored.contexts);
  4871. context.attachRef = stored.componentRef;
  4872. context.route = stored.route.value;
  4873. if (context.outlet) {
  4874. // Attach right away when the outlet has already been instantiated
  4875. // Otherwise attach from `RouterOutlet.ngOnInit` when it is instantiated
  4876. context.outlet.attach(stored.componentRef, stored.route.value);
  4877. }
  4878. advanceActivatedRouteNodeAndItsChildren(stored.route);
  4879. }
  4880. else {
  4881. const /** @type {?} */ config = parentLoadedConfig(future.snapshot);
  4882. const /** @type {?} */ cmpFactoryResolver = config ? config.module.componentFactoryResolver : null;
  4883. context.route = future;
  4884. context.resolver = cmpFactoryResolver;
  4885. if (context.outlet) {
  4886. // Activate the outlet when it has already been instantiated
  4887. // Otherwise it will get activated from its `ngOnInit` when instantiated
  4888. context.outlet.activateWith(future, cmpFactoryResolver);
  4889. }
  4890. this.activateChildRoutes(futureNode, null, context.children);
  4891. }
  4892. }
  4893. else {
  4894. // if we have a componentless route, we recurse but keep the same outlet map.
  4895. this.activateChildRoutes(futureNode, null, parentContexts);
  4896. }
  4897. }
  4898. }
  4899. }
  4900. /**
  4901. * @param {?} node
  4902. * @return {?}
  4903. */
  4904. function advanceActivatedRouteNodeAndItsChildren(node) {
  4905. advanceActivatedRoute(node.value);
  4906. node.children.forEach(advanceActivatedRouteNodeAndItsChildren);
  4907. }
  4908. /**
  4909. * @param {?} snapshot
  4910. * @return {?}
  4911. */
  4912. function parentLoadedConfig(snapshot) {
  4913. for (let /** @type {?} */ s = snapshot.parent; s; s = s.parent) {
  4914. const /** @type {?} */ route = s.routeConfig;
  4915. if (route && route._loadedConfig)
  4916. return route._loadedConfig;
  4917. if (route && route.component)
  4918. return null;
  4919. }
  4920. return null;
  4921. }
  4922. /**
  4923. * @param {?} commands
  4924. * @return {?}
  4925. */
  4926. function validateCommands(commands) {
  4927. for (let /** @type {?} */ i = 0; i < commands.length; i++) {
  4928. const /** @type {?} */ cmd = commands[i];
  4929. if (cmd == null) {
  4930. throw new Error(`The requested path contains ${cmd} segment at index ${i}`);
  4931. }
  4932. }
  4933. }
  4934. /**
  4935. * @fileoverview added by tsickle
  4936. * @suppress {checkTypes} checked by tsc
  4937. */
  4938. /**
  4939. * \@description
  4940. *
  4941. * Lets you link to specific routes in your app.
  4942. *
  4943. * Consider the following route configuration:
  4944. * `[{ path: 'user/:name', component: UserCmp }]`.
  4945. * When linking to this `user/:name` route, you use the `RouterLink` directive.
  4946. *
  4947. * If the link is static, you can use the directive as follows:
  4948. * `<a routerLink="/user/bob">link to user component</a>`
  4949. *
  4950. * If you use dynamic values to generate the link, you can pass an array of path
  4951. * segments, followed by the params for each segment.
  4952. *
  4953. * For instance `['/team', teamId, 'user', userName, {details: true}]`
  4954. * means that we want to generate a link to `/team/11/user/bob;details=true`.
  4955. *
  4956. * Multiple static segments can be merged into one
  4957. * (e.g., `['/team/11/user', userName, {details: true}]`).
  4958. *
  4959. * The first segment name can be prepended with `/`, `./`, or `../`:
  4960. * * If the first segment begins with `/`, the router will look up the route from the root of the
  4961. * app.
  4962. * * If the first segment begins with `./`, or doesn't begin with a slash, the router will
  4963. * instead look in the children of the current activated route.
  4964. * * And if the first segment begins with `../`, the router will go up one level.
  4965. *
  4966. * You can set query params and fragment as follows:
  4967. *
  4968. * ```
  4969. * <a [routerLink]="['/user/bob']" [queryParams]="{debug: true}" fragment="education">
  4970. * link to user component
  4971. * </a>
  4972. * ```
  4973. * RouterLink will use these to generate this link: `/user/bob#education?debug=true`.
  4974. *
  4975. * (Deprecated in v4.0.0 use `queryParamsHandling` instead) You can also tell the
  4976. * directive to preserve the current query params and fragment:
  4977. *
  4978. * ```
  4979. * <a [routerLink]="['/user/bob']" preserveQueryParams preserveFragment>
  4980. * link to user component
  4981. * </a>
  4982. * ```
  4983. *
  4984. * You can tell the directive to how to handle queryParams, available options are:
  4985. * - `'merge'`: merge the queryParams into the current queryParams
  4986. * - `'preserve'`: preserve the current queryParams
  4987. * - default/`''`: use the queryParams only
  4988. *
  4989. * Same options for {\@link NavigationExtras#queryParamsHandling
  4990. * NavigationExtras#queryParamsHandling}.
  4991. *
  4992. * ```
  4993. * <a [routerLink]="['/user/bob']" [queryParams]="{debug: true}" queryParamsHandling="merge">
  4994. * link to user component
  4995. * </a>
  4996. * ```
  4997. *
  4998. * The router link directive always treats the provided input as a delta to the current url.
  4999. *
  5000. * For instance, if the current url is `/user/(box//aux:team)`.
  5001. *
  5002. * Then the following link `<a [routerLink]="['/user/jim']">Jim</a>` will generate the link
  5003. * `/user/(jim//aux:team)`.
  5004. *
  5005. * See {\@link Router#createUrlTree createUrlTree} for more information.
  5006. *
  5007. * \@ngModule RouterModule
  5008. *
  5009. *
  5010. */
  5011. class RouterLink {
  5012. /**
  5013. * @param {?} router
  5014. * @param {?} route
  5015. * @param {?} tabIndex
  5016. * @param {?} renderer
  5017. * @param {?} el
  5018. */
  5019. constructor(router, route, tabIndex, renderer, el) {
  5020. this.router = router;
  5021. this.route = route;
  5022. this.commands = [];
  5023. if (tabIndex == null) {
  5024. renderer.setAttribute(el.nativeElement, 'tabindex', '0');
  5025. }
  5026. }
  5027. /**
  5028. * @param {?} commands
  5029. * @return {?}
  5030. */
  5031. set routerLink(commands) {
  5032. if (commands != null) {
  5033. this.commands = Array.isArray(commands) ? commands : [commands];
  5034. }
  5035. else {
  5036. this.commands = [];
  5037. }
  5038. }
  5039. /**
  5040. * @deprecated 4.0.0 use `queryParamsHandling` instead.
  5041. * @param {?} value
  5042. * @return {?}
  5043. */
  5044. set preserveQueryParams(value) {
  5045. if (isDevMode() && /** @type {?} */ (console) && /** @type {?} */ (console.warn)) {
  5046. console.warn('preserveQueryParams is deprecated!, use queryParamsHandling instead.');
  5047. }
  5048. this.preserve = value;
  5049. }
  5050. /**
  5051. * @return {?}
  5052. */
  5053. onClick() {
  5054. const /** @type {?} */ extras = {
  5055. skipLocationChange: attrBoolValue(this.skipLocationChange),
  5056. replaceUrl: attrBoolValue(this.replaceUrl),
  5057. };
  5058. this.router.navigateByUrl(this.urlTree, extras);
  5059. return true;
  5060. }
  5061. /**
  5062. * @return {?}
  5063. */
  5064. get urlTree() {
  5065. return this.router.createUrlTree(this.commands, {
  5066. relativeTo: this.route,
  5067. queryParams: this.queryParams,
  5068. fragment: this.fragment,
  5069. preserveQueryParams: attrBoolValue(this.preserve),
  5070. queryParamsHandling: this.queryParamsHandling,
  5071. preserveFragment: attrBoolValue(this.preserveFragment),
  5072. });
  5073. }
  5074. }
  5075. RouterLink.decorators = [
  5076. { type: Directive, args: [{ selector: ':not(a)[routerLink]' },] }
  5077. ];
  5078. /** @nocollapse */
  5079. RouterLink.ctorParameters = () => [
  5080. { type: Router },
  5081. { type: ActivatedRoute },
  5082. { type: String, decorators: [{ type: Attribute, args: ['tabindex',] }] },
  5083. { type: Renderer2 },
  5084. { type: ElementRef }
  5085. ];
  5086. RouterLink.propDecorators = {
  5087. queryParams: [{ type: Input }],
  5088. fragment: [{ type: Input }],
  5089. queryParamsHandling: [{ type: Input }],
  5090. preserveFragment: [{ type: Input }],
  5091. skipLocationChange: [{ type: Input }],
  5092. replaceUrl: [{ type: Input }],
  5093. routerLink: [{ type: Input }],
  5094. preserveQueryParams: [{ type: Input }],
  5095. onClick: [{ type: HostListener, args: ['click',] }]
  5096. };
  5097. /**
  5098. * \@description
  5099. *
  5100. * Lets you link to specific routes in your app.
  5101. *
  5102. * See `RouterLink` for more information.
  5103. *
  5104. * \@ngModule RouterModule
  5105. *
  5106. *
  5107. */
  5108. class RouterLinkWithHref {
  5109. /**
  5110. * @param {?} router
  5111. * @param {?} route
  5112. * @param {?} locationStrategy
  5113. */
  5114. constructor(router, route, locationStrategy) {
  5115. this.router = router;
  5116. this.route = route;
  5117. this.locationStrategy = locationStrategy;
  5118. this.commands = [];
  5119. this.subscription = router.events.subscribe((s) => {
  5120. if (s instanceof NavigationEnd) {
  5121. this.updateTargetUrlAndHref();
  5122. }
  5123. });
  5124. }
  5125. /**
  5126. * @param {?} commands
  5127. * @return {?}
  5128. */
  5129. set routerLink(commands) {
  5130. if (commands != null) {
  5131. this.commands = Array.isArray(commands) ? commands : [commands];
  5132. }
  5133. else {
  5134. this.commands = [];
  5135. }
  5136. }
  5137. /**
  5138. * @param {?} value
  5139. * @return {?}
  5140. */
  5141. set preserveQueryParams(value) {
  5142. if (isDevMode() && /** @type {?} */ (console) && /** @type {?} */ (console.warn)) {
  5143. console.warn('preserveQueryParams is deprecated, use queryParamsHandling instead.');
  5144. }
  5145. this.preserve = value;
  5146. }
  5147. /**
  5148. * @param {?} changes
  5149. * @return {?}
  5150. */
  5151. ngOnChanges(changes) { this.updateTargetUrlAndHref(); }
  5152. /**
  5153. * @return {?}
  5154. */
  5155. ngOnDestroy() { this.subscription.unsubscribe(); }
  5156. /**
  5157. * @param {?} button
  5158. * @param {?} ctrlKey
  5159. * @param {?} metaKey
  5160. * @param {?} shiftKey
  5161. * @return {?}
  5162. */
  5163. onClick(button, ctrlKey, metaKey, shiftKey) {
  5164. if (button !== 0 || ctrlKey || metaKey || shiftKey) {
  5165. return true;
  5166. }
  5167. if (typeof this.target === 'string' && this.target != '_self') {
  5168. return true;
  5169. }
  5170. const /** @type {?} */ extras = {
  5171. skipLocationChange: attrBoolValue(this.skipLocationChange),
  5172. replaceUrl: attrBoolValue(this.replaceUrl),
  5173. };
  5174. this.router.navigateByUrl(this.urlTree, extras);
  5175. return false;
  5176. }
  5177. /**
  5178. * @return {?}
  5179. */
  5180. updateTargetUrlAndHref() {
  5181. this.href = this.locationStrategy.prepareExternalUrl(this.router.serializeUrl(this.urlTree));
  5182. }
  5183. /**
  5184. * @return {?}
  5185. */
  5186. get urlTree() {
  5187. return this.router.createUrlTree(this.commands, {
  5188. relativeTo: this.route,
  5189. queryParams: this.queryParams,
  5190. fragment: this.fragment,
  5191. preserveQueryParams: attrBoolValue(this.preserve),
  5192. queryParamsHandling: this.queryParamsHandling,
  5193. preserveFragment: attrBoolValue(this.preserveFragment),
  5194. });
  5195. }
  5196. }
  5197. RouterLinkWithHref.decorators = [
  5198. { type: Directive, args: [{ selector: 'a[routerLink]' },] }
  5199. ];
  5200. /** @nocollapse */
  5201. RouterLinkWithHref.ctorParameters = () => [
  5202. { type: Router },
  5203. { type: ActivatedRoute },
  5204. { type: LocationStrategy }
  5205. ];
  5206. RouterLinkWithHref.propDecorators = {
  5207. target: [{ type: HostBinding, args: ['attr.target',] }, { type: Input }],
  5208. queryParams: [{ type: Input }],
  5209. fragment: [{ type: Input }],
  5210. queryParamsHandling: [{ type: Input }],
  5211. preserveFragment: [{ type: Input }],
  5212. skipLocationChange: [{ type: Input }],
  5213. replaceUrl: [{ type: Input }],
  5214. href: [{ type: HostBinding }],
  5215. routerLink: [{ type: Input }],
  5216. preserveQueryParams: [{ type: Input }],
  5217. onClick: [{ type: HostListener, args: ['click', ['$event.button', '$event.ctrlKey', '$event.metaKey', '$event.shiftKey'],] }]
  5218. };
  5219. /**
  5220. * @param {?} s
  5221. * @return {?}
  5222. */
  5223. function attrBoolValue(s) {
  5224. return s === '' || !!s;
  5225. }
  5226. /**
  5227. * @fileoverview added by tsickle
  5228. * @suppress {checkTypes} checked by tsc
  5229. */
  5230. /**
  5231. *
  5232. * \@description
  5233. *
  5234. * Lets you add a CSS class to an element when the link's route becomes active.
  5235. *
  5236. * This directive lets you add a CSS class to an element when the link's route
  5237. * becomes active.
  5238. *
  5239. * Consider the following example:
  5240. *
  5241. * ```
  5242. * <a routerLink="/user/bob" routerLinkActive="active-link">Bob</a>
  5243. * ```
  5244. *
  5245. * When the url is either '/user' or '/user/bob', the active-link class will
  5246. * be added to the `a` tag. If the url changes, the class will be removed.
  5247. *
  5248. * You can set more than one class, as follows:
  5249. *
  5250. * ```
  5251. * <a routerLink="/user/bob" routerLinkActive="class1 class2">Bob</a>
  5252. * <a routerLink="/user/bob" [routerLinkActive]="['class1', 'class2']">Bob</a>
  5253. * ```
  5254. *
  5255. * You can configure RouterLinkActive by passing `exact: true`. This will add the classes
  5256. * only when the url matches the link exactly.
  5257. *
  5258. * ```
  5259. * <a routerLink="/user/bob" routerLinkActive="active-link" [routerLinkActiveOptions]="{exact:
  5260. * true}">Bob</a>
  5261. * ```
  5262. *
  5263. * You can assign the RouterLinkActive instance to a template variable and directly check
  5264. * the `isActive` status.
  5265. * ```
  5266. * <a routerLink="/user/bob" routerLinkActive #rla="routerLinkActive">
  5267. * Bob {{ rla.isActive ? '(already open)' : ''}}
  5268. * </a>
  5269. * ```
  5270. *
  5271. * Finally, you can apply the RouterLinkActive directive to an ancestor of a RouterLink.
  5272. *
  5273. * ```
  5274. * <div routerLinkActive="active-link" [routerLinkActiveOptions]="{exact: true}">
  5275. * <a routerLink="/user/jim">Jim</a>
  5276. * <a routerLink="/user/bob">Bob</a>
  5277. * </div>
  5278. * ```
  5279. *
  5280. * This will set the active-link class on the div tag if the url is either '/user/jim' or
  5281. * '/user/bob'.
  5282. *
  5283. * \@ngModule RouterModule
  5284. *
  5285. *
  5286. */
  5287. class RouterLinkActive {
  5288. /**
  5289. * @param {?} router
  5290. * @param {?} element
  5291. * @param {?} renderer
  5292. * @param {?} cdr
  5293. */
  5294. constructor(router, element, renderer, cdr) {
  5295. this.router = router;
  5296. this.element = element;
  5297. this.renderer = renderer;
  5298. this.cdr = cdr;
  5299. this.classes = [];
  5300. this.isActive = false;
  5301. this.routerLinkActiveOptions = { exact: false };
  5302. this.subscription = router.events.subscribe((s) => {
  5303. if (s instanceof NavigationEnd) {
  5304. this.update();
  5305. }
  5306. });
  5307. }
  5308. /**
  5309. * @return {?}
  5310. */
  5311. ngAfterContentInit() {
  5312. this.links.changes.subscribe(_ => this.update());
  5313. this.linksWithHrefs.changes.subscribe(_ => this.update());
  5314. this.update();
  5315. }
  5316. /**
  5317. * @param {?} data
  5318. * @return {?}
  5319. */
  5320. set routerLinkActive(data) {
  5321. const /** @type {?} */ classes = Array.isArray(data) ? data : data.split(' ');
  5322. this.classes = classes.filter(c => !!c);
  5323. }
  5324. /**
  5325. * @param {?} changes
  5326. * @return {?}
  5327. */
  5328. ngOnChanges(changes) { this.update(); }
  5329. /**
  5330. * @return {?}
  5331. */
  5332. ngOnDestroy() { this.subscription.unsubscribe(); }
  5333. /**
  5334. * @return {?}
  5335. */
  5336. update() {
  5337. if (!this.links || !this.linksWithHrefs || !this.router.navigated)
  5338. return;
  5339. Promise.resolve().then(() => {
  5340. const /** @type {?} */ hasActiveLinks = this.hasActiveLinks();
  5341. if (this.isActive !== hasActiveLinks) {
  5342. (/** @type {?} */ (this)).isActive = hasActiveLinks;
  5343. this.classes.forEach((c) => {
  5344. if (hasActiveLinks) {
  5345. this.renderer.addClass(this.element.nativeElement, c);
  5346. }
  5347. else {
  5348. this.renderer.removeClass(this.element.nativeElement, c);
  5349. }
  5350. });
  5351. }
  5352. });
  5353. }
  5354. /**
  5355. * @param {?} router
  5356. * @return {?}
  5357. */
  5358. isLinkActive(router) {
  5359. return (link) => router.isActive(link.urlTree, this.routerLinkActiveOptions.exact);
  5360. }
  5361. /**
  5362. * @return {?}
  5363. */
  5364. hasActiveLinks() {
  5365. return this.links.some(this.isLinkActive(this.router)) ||
  5366. this.linksWithHrefs.some(this.isLinkActive(this.router));
  5367. }
  5368. }
  5369. RouterLinkActive.decorators = [
  5370. { type: Directive, args: [{
  5371. selector: '[routerLinkActive]',
  5372. exportAs: 'routerLinkActive',
  5373. },] }
  5374. ];
  5375. /** @nocollapse */
  5376. RouterLinkActive.ctorParameters = () => [
  5377. { type: Router },
  5378. { type: ElementRef },
  5379. { type: Renderer2 },
  5380. { type: ChangeDetectorRef }
  5381. ];
  5382. RouterLinkActive.propDecorators = {
  5383. links: [{ type: ContentChildren, args: [RouterLink, { descendants: true },] }],
  5384. linksWithHrefs: [{ type: ContentChildren, args: [RouterLinkWithHref, { descendants: true },] }],
  5385. routerLinkActiveOptions: [{ type: Input }],
  5386. routerLinkActive: [{ type: Input }]
  5387. };
  5388. /**
  5389. * @fileoverview added by tsickle
  5390. * @suppress {checkTypes} checked by tsc
  5391. */
  5392. /**
  5393. * @license
  5394. * Copyright Google Inc. All Rights Reserved.
  5395. *
  5396. * Use of this source code is governed by an MIT-style license that can be
  5397. * found in the LICENSE file at https://angular.io/license
  5398. */
  5399. /**
  5400. * Store contextual information about a `RouterOutlet`
  5401. *
  5402. *
  5403. */
  5404. class OutletContext {
  5405. constructor() {
  5406. this.outlet = null;
  5407. this.route = null;
  5408. this.resolver = null;
  5409. this.children = new ChildrenOutletContexts();
  5410. this.attachRef = null;
  5411. }
  5412. }
  5413. /**
  5414. * Store contextual information about the children (= nested) `RouterOutlet`
  5415. *
  5416. *
  5417. */
  5418. class ChildrenOutletContexts {
  5419. constructor() {
  5420. this.contexts = new Map();
  5421. }
  5422. /**
  5423. * Called when a `RouterOutlet` directive is instantiated
  5424. * @param {?} childName
  5425. * @param {?} outlet
  5426. * @return {?}
  5427. */
  5428. onChildOutletCreated(childName, outlet) {
  5429. const /** @type {?} */ context = this.getOrCreateContext(childName);
  5430. context.outlet = outlet;
  5431. this.contexts.set(childName, context);
  5432. }
  5433. /**
  5434. * Called when a `RouterOutlet` directive is destroyed.
  5435. * We need to keep the context as the outlet could be destroyed inside a NgIf and might be
  5436. * re-created later.
  5437. * @param {?} childName
  5438. * @return {?}
  5439. */
  5440. onChildOutletDestroyed(childName) {
  5441. const /** @type {?} */ context = this.getContext(childName);
  5442. if (context) {
  5443. context.outlet = null;
  5444. }
  5445. }
  5446. /**
  5447. * Called when the corresponding route is deactivated during navigation.
  5448. * Because the component get destroyed, all children outlet are destroyed.
  5449. * @return {?}
  5450. */
  5451. onOutletDeactivated() {
  5452. const /** @type {?} */ contexts = this.contexts;
  5453. this.contexts = new Map();
  5454. return contexts;
  5455. }
  5456. /**
  5457. * @param {?} contexts
  5458. * @return {?}
  5459. */
  5460. onOutletReAttached(contexts) { this.contexts = contexts; }
  5461. /**
  5462. * @param {?} childName
  5463. * @return {?}
  5464. */
  5465. getOrCreateContext(childName) {
  5466. let /** @type {?} */ context = this.getContext(childName);
  5467. if (!context) {
  5468. context = new OutletContext();
  5469. this.contexts.set(childName, context);
  5470. }
  5471. return context;
  5472. }
  5473. /**
  5474. * @param {?} childName
  5475. * @return {?}
  5476. */
  5477. getContext(childName) { return this.contexts.get(childName) || null; }
  5478. }
  5479. /**
  5480. * @fileoverview added by tsickle
  5481. * @suppress {checkTypes} checked by tsc
  5482. */
  5483. /**
  5484. * \@description
  5485. *
  5486. * Acts as a placeholder that Angular dynamically fills based on the current router state.
  5487. *
  5488. * ```
  5489. * <router-outlet></router-outlet>
  5490. * <router-outlet name='left'></router-outlet>
  5491. * <router-outlet name='right'></router-outlet>
  5492. * ```
  5493. *
  5494. * A router outlet will emit an activate event any time a new component is being instantiated,
  5495. * and a deactivate event when it is being destroyed.
  5496. *
  5497. * ```
  5498. * <router-outlet
  5499. * (activate)='onActivate($event)'
  5500. * (deactivate)='onDeactivate($event)'></router-outlet>
  5501. * ```
  5502. * \@ngModule RouterModule
  5503. *
  5504. *
  5505. */
  5506. class RouterOutlet {
  5507. /**
  5508. * @param {?} parentContexts
  5509. * @param {?} location
  5510. * @param {?} resolver
  5511. * @param {?} name
  5512. * @param {?} changeDetector
  5513. */
  5514. constructor(parentContexts, location, resolver, name, changeDetector) {
  5515. this.parentContexts = parentContexts;
  5516. this.location = location;
  5517. this.resolver = resolver;
  5518. this.changeDetector = changeDetector;
  5519. this.activated = null;
  5520. this._activatedRoute = null;
  5521. this.activateEvents = new EventEmitter();
  5522. this.deactivateEvents = new EventEmitter();
  5523. this.name = name || PRIMARY_OUTLET;
  5524. parentContexts.onChildOutletCreated(this.name, this);
  5525. }
  5526. /**
  5527. * @return {?}
  5528. */
  5529. ngOnDestroy() { this.parentContexts.onChildOutletDestroyed(this.name); }
  5530. /**
  5531. * @return {?}
  5532. */
  5533. ngOnInit() {
  5534. if (!this.activated) {
  5535. // If the outlet was not instantiated at the time the route got activated we need to populate
  5536. // the outlet when it is initialized (ie inside a NgIf)
  5537. const /** @type {?} */ context = this.parentContexts.getContext(this.name);
  5538. if (context && context.route) {
  5539. if (context.attachRef) {
  5540. // `attachRef` is populated when there is an existing component to mount
  5541. this.attach(context.attachRef, context.route);
  5542. }
  5543. else {
  5544. // otherwise the component defined in the configuration is created
  5545. this.activateWith(context.route, context.resolver || null);
  5546. }
  5547. }
  5548. }
  5549. }
  5550. /**
  5551. * @return {?}
  5552. */
  5553. get isActivated() { return !!this.activated; }
  5554. /**
  5555. * @return {?}
  5556. */
  5557. get component() {
  5558. if (!this.activated)
  5559. throw new Error('Outlet is not activated');
  5560. return this.activated.instance;
  5561. }
  5562. /**
  5563. * @return {?}
  5564. */
  5565. get activatedRoute() {
  5566. if (!this.activated)
  5567. throw new Error('Outlet is not activated');
  5568. return /** @type {?} */ (this._activatedRoute);
  5569. }
  5570. /**
  5571. * @return {?}
  5572. */
  5573. get activatedRouteData() {
  5574. if (this._activatedRoute) {
  5575. return this._activatedRoute.snapshot.data;
  5576. }
  5577. return {};
  5578. }
  5579. /**
  5580. * Called when the `RouteReuseStrategy` instructs to detach the subtree
  5581. * @return {?}
  5582. */
  5583. detach() {
  5584. if (!this.activated)
  5585. throw new Error('Outlet is not activated');
  5586. this.location.detach();
  5587. const /** @type {?} */ cmp = this.activated;
  5588. this.activated = null;
  5589. this._activatedRoute = null;
  5590. return cmp;
  5591. }
  5592. /**
  5593. * Called when the `RouteReuseStrategy` instructs to re-attach a previously detached subtree
  5594. * @param {?} ref
  5595. * @param {?} activatedRoute
  5596. * @return {?}
  5597. */
  5598. attach(ref, activatedRoute) {
  5599. this.activated = ref;
  5600. this._activatedRoute = activatedRoute;
  5601. this.location.insert(ref.hostView);
  5602. }
  5603. /**
  5604. * @return {?}
  5605. */
  5606. deactivate() {
  5607. if (this.activated) {
  5608. const /** @type {?} */ c = this.component;
  5609. this.activated.destroy();
  5610. this.activated = null;
  5611. this._activatedRoute = null;
  5612. this.deactivateEvents.emit(c);
  5613. }
  5614. }
  5615. /**
  5616. * @param {?} activatedRoute
  5617. * @param {?} resolver
  5618. * @return {?}
  5619. */
  5620. activateWith(activatedRoute, resolver) {
  5621. if (this.isActivated) {
  5622. throw new Error('Cannot activate an already activated outlet');
  5623. }
  5624. this._activatedRoute = activatedRoute;
  5625. const /** @type {?} */ snapshot = activatedRoute._futureSnapshot;
  5626. const /** @type {?} */ component = /** @type {?} */ (/** @type {?} */ ((snapshot.routeConfig)).component);
  5627. resolver = resolver || this.resolver;
  5628. const /** @type {?} */ factory = resolver.resolveComponentFactory(component);
  5629. const /** @type {?} */ childContexts = this.parentContexts.getOrCreateContext(this.name).children;
  5630. const /** @type {?} */ injector = new OutletInjector(activatedRoute, childContexts, this.location.injector);
  5631. this.activated = this.location.createComponent(factory, this.location.length, injector);
  5632. // Calling `markForCheck` to make sure we will run the change detection when the
  5633. // `RouterOutlet` is inside a `ChangeDetectionStrategy.OnPush` component.
  5634. this.changeDetector.markForCheck();
  5635. this.activateEvents.emit(this.activated.instance);
  5636. }
  5637. }
  5638. RouterOutlet.decorators = [
  5639. { type: Directive, args: [{ selector: 'router-outlet', exportAs: 'outlet' },] }
  5640. ];
  5641. /** @nocollapse */
  5642. RouterOutlet.ctorParameters = () => [
  5643. { type: ChildrenOutletContexts },
  5644. { type: ViewContainerRef },
  5645. { type: ComponentFactoryResolver },
  5646. { type: String, decorators: [{ type: Attribute, args: ['name',] }] },
  5647. { type: ChangeDetectorRef }
  5648. ];
  5649. RouterOutlet.propDecorators = {
  5650. activateEvents: [{ type: Output, args: ['activate',] }],
  5651. deactivateEvents: [{ type: Output, args: ['deactivate',] }]
  5652. };
  5653. class OutletInjector {
  5654. /**
  5655. * @param {?} route
  5656. * @param {?} childContexts
  5657. * @param {?} parent
  5658. */
  5659. constructor(route, childContexts, parent) {
  5660. this.route = route;
  5661. this.childContexts = childContexts;
  5662. this.parent = parent;
  5663. }
  5664. /**
  5665. * @param {?} token
  5666. * @param {?=} notFoundValue
  5667. * @return {?}
  5668. */
  5669. get(token, notFoundValue) {
  5670. if (token === ActivatedRoute) {
  5671. return this.route;
  5672. }
  5673. if (token === ChildrenOutletContexts) {
  5674. return this.childContexts;
  5675. }
  5676. return this.parent.get(token, notFoundValue);
  5677. }
  5678. }
  5679. /**
  5680. * @fileoverview added by tsickle
  5681. * @suppress {checkTypes} checked by tsc
  5682. */
  5683. /**
  5684. * \@description
  5685. *
  5686. * Provides a preloading strategy.
  5687. *
  5688. * \@experimental
  5689. * @abstract
  5690. */
  5691. class PreloadingStrategy {
  5692. }
  5693. /**
  5694. * \@description
  5695. *
  5696. * Provides a preloading strategy that preloads all modules as quickly as possible.
  5697. *
  5698. * ```
  5699. * RouteModule.forRoot(ROUTES, {preloadingStrategy: PreloadAllModules})
  5700. * ```
  5701. *
  5702. * \@experimental
  5703. */
  5704. class PreloadAllModules {
  5705. /**
  5706. * @param {?} route
  5707. * @param {?} fn
  5708. * @return {?}
  5709. */
  5710. preload(route, fn) {
  5711. return fn().pipe(catchError(() => of(null)));
  5712. }
  5713. }
  5714. /**
  5715. * \@description
  5716. *
  5717. * Provides a preloading strategy that does not preload any modules.
  5718. *
  5719. * This strategy is enabled by default.
  5720. *
  5721. * \@experimental
  5722. */
  5723. class NoPreloading {
  5724. /**
  5725. * @param {?} route
  5726. * @param {?} fn
  5727. * @return {?}
  5728. */
  5729. preload(route, fn) { return of(null); }
  5730. }
  5731. /**
  5732. * The preloader optimistically loads all router configurations to
  5733. * make navigations into lazily-loaded sections of the application faster.
  5734. *
  5735. * The preloader runs in the background. When the router bootstraps, the preloader
  5736. * starts listening to all navigation events. After every such event, the preloader
  5737. * will check if any configurations can be loaded lazily.
  5738. *
  5739. * If a route is protected by `canLoad` guards, the preloaded will not load it.
  5740. *
  5741. *
  5742. */
  5743. class RouterPreloader {
  5744. /**
  5745. * @param {?} router
  5746. * @param {?} moduleLoader
  5747. * @param {?} compiler
  5748. * @param {?} injector
  5749. * @param {?} preloadingStrategy
  5750. */
  5751. constructor(router, moduleLoader, compiler, injector, preloadingStrategy) {
  5752. this.router = router;
  5753. this.injector = injector;
  5754. this.preloadingStrategy = preloadingStrategy;
  5755. const /** @type {?} */ onStartLoad = (r) => router.triggerEvent(new RouteConfigLoadStart(r));
  5756. const /** @type {?} */ onEndLoad = (r) => router.triggerEvent(new RouteConfigLoadEnd(r));
  5757. this.loader = new RouterConfigLoader(moduleLoader, compiler, onStartLoad, onEndLoad);
  5758. }
  5759. /**
  5760. * @return {?}
  5761. */
  5762. setUpPreloading() {
  5763. this.subscription =
  5764. this.router.events
  5765. .pipe(filter((e) => e instanceof NavigationEnd), concatMap(() => this.preload()))
  5766. .subscribe(() => { });
  5767. }
  5768. /**
  5769. * @return {?}
  5770. */
  5771. preload() {
  5772. const /** @type {?} */ ngModule = this.injector.get(NgModuleRef);
  5773. return this.processRoutes(ngModule, this.router.config);
  5774. }
  5775. /**
  5776. * @return {?}
  5777. */
  5778. ngOnDestroy() { this.subscription.unsubscribe(); }
  5779. /**
  5780. * @param {?} ngModule
  5781. * @param {?} routes
  5782. * @return {?}
  5783. */
  5784. processRoutes(ngModule, routes) {
  5785. const /** @type {?} */ res = [];
  5786. for (const /** @type {?} */ route of routes) {
  5787. // we already have the config loaded, just recurse
  5788. if (route.loadChildren && !route.canLoad && route._loadedConfig) {
  5789. const /** @type {?} */ childConfig = route._loadedConfig;
  5790. res.push(this.processRoutes(childConfig.module, childConfig.routes));
  5791. // no config loaded, fetch the config
  5792. }
  5793. else if (route.loadChildren && !route.canLoad) {
  5794. res.push(this.preloadConfig(ngModule, route));
  5795. // recurse into children
  5796. }
  5797. else if (route.children) {
  5798. res.push(this.processRoutes(ngModule, route.children));
  5799. }
  5800. }
  5801. return from(res).pipe(mergeAll(), map((_) => void 0));
  5802. }
  5803. /**
  5804. * @param {?} ngModule
  5805. * @param {?} route
  5806. * @return {?}
  5807. */
  5808. preloadConfig(ngModule, route) {
  5809. return this.preloadingStrategy.preload(route, () => {
  5810. const /** @type {?} */ loaded$ = this.loader.load(ngModule.injector, route);
  5811. return loaded$.pipe(mergeMap((config) => {
  5812. route._loadedConfig = config;
  5813. return this.processRoutes(config.module, config.routes);
  5814. }));
  5815. });
  5816. }
  5817. }
  5818. RouterPreloader.decorators = [
  5819. { type: Injectable }
  5820. ];
  5821. /** @nocollapse */
  5822. RouterPreloader.ctorParameters = () => [
  5823. { type: Router },
  5824. { type: NgModuleFactoryLoader },
  5825. { type: Compiler },
  5826. { type: Injector },
  5827. { type: PreloadingStrategy }
  5828. ];
  5829. /**
  5830. * @fileoverview added by tsickle
  5831. * @suppress {checkTypes} checked by tsc
  5832. */
  5833. /**
  5834. * \@description
  5835. *
  5836. * Contains a list of directives
  5837. *
  5838. *
  5839. */
  5840. const /** @type {?} */ ROUTER_DIRECTIVES = [RouterOutlet, RouterLink, RouterLinkWithHref, RouterLinkActive, EmptyOutletComponent];
  5841. /**
  5842. * \@description
  5843. *
  5844. * Is used in DI to configure the router.
  5845. *
  5846. *
  5847. */
  5848. const /** @type {?} */ ROUTER_CONFIGURATION = new InjectionToken('ROUTER_CONFIGURATION');
  5849. /**
  5850. * \@docsNotRequired
  5851. */
  5852. const /** @type {?} */ ROUTER_FORROOT_GUARD = new InjectionToken('ROUTER_FORROOT_GUARD');
  5853. const /** @type {?} */ ROUTER_PROVIDERS = [
  5854. Location,
  5855. { provide: UrlSerializer, useClass: DefaultUrlSerializer },
  5856. {
  5857. provide: Router,
  5858. useFactory: setupRouter,
  5859. deps: [
  5860. ApplicationRef, UrlSerializer, ChildrenOutletContexts, Location, Injector,
  5861. NgModuleFactoryLoader, Compiler, ROUTES, ROUTER_CONFIGURATION,
  5862. [UrlHandlingStrategy, new Optional()], [RouteReuseStrategy, new Optional()]
  5863. ]
  5864. },
  5865. ChildrenOutletContexts,
  5866. { provide: ActivatedRoute, useFactory: rootRoute, deps: [Router] },
  5867. { provide: NgModuleFactoryLoader, useClass: SystemJsNgModuleLoader },
  5868. RouterPreloader,
  5869. NoPreloading,
  5870. PreloadAllModules,
  5871. { provide: ROUTER_CONFIGURATION, useValue: { enableTracing: false } },
  5872. ];
  5873. /**
  5874. * @return {?}
  5875. */
  5876. function routerNgProbeToken() {
  5877. return new NgProbeToken('Router', Router);
  5878. }
  5879. /**
  5880. * \@usageNotes
  5881. *
  5882. * RouterModule can be imported multiple times: once per lazily-loaded bundle.
  5883. * Since the router deals with a global shared resource--location, we cannot have
  5884. * more than one router service active.
  5885. *
  5886. * That is why there are two ways to create the module: `RouterModule.forRoot` and
  5887. * `RouterModule.forChild`.
  5888. *
  5889. * * `forRoot` creates a module that contains all the directives, the given routes, and the router
  5890. * service itself.
  5891. * * `forChild` creates a module that contains all the directives and the given routes, but does not
  5892. * include the router service.
  5893. *
  5894. * When registered at the root, the module should be used as follows
  5895. *
  5896. * ```
  5897. * \@NgModule({
  5898. * imports: [RouterModule.forRoot(ROUTES)]
  5899. * })
  5900. * class MyNgModule {}
  5901. * ```
  5902. *
  5903. * For submodules and lazy loaded submodules the module should be used as follows:
  5904. *
  5905. * ```
  5906. * \@NgModule({
  5907. * imports: [RouterModule.forChild(ROUTES)]
  5908. * })
  5909. * class MyNgModule {}
  5910. * ```
  5911. *
  5912. * \@description
  5913. *
  5914. * Adds router directives and providers.
  5915. *
  5916. * Managing state transitions is one of the hardest parts of building applications. This is
  5917. * especially true on the web, where you also need to ensure that the state is reflected in the URL.
  5918. * In addition, we often want to split applications into multiple bundles and load them on demand.
  5919. * Doing this transparently is not trivial.
  5920. *
  5921. * The Angular router solves these problems. Using the router, you can declaratively specify
  5922. * application states, manage state transitions while taking care of the URL, and load bundles on
  5923. * demand.
  5924. *
  5925. * [Read this developer guide](https://angular.io/docs/ts/latest/guide/router.html) to get an
  5926. * overview of how the router should be used.
  5927. *
  5928. *
  5929. */
  5930. class RouterModule {
  5931. /**
  5932. * @param {?} guard
  5933. * @param {?} router
  5934. */
  5935. constructor(guard, router) { }
  5936. /**
  5937. * Creates a module with all the router providers and directives. It also optionally sets up an
  5938. * application listener to perform an initial navigation.
  5939. *
  5940. * Options (see `ExtraOptions`):
  5941. * * `enableTracing` makes the router log all its internal events to the console.
  5942. * * `useHash` enables the location strategy that uses the URL fragment instead of the history
  5943. * API.
  5944. * * `initialNavigation` disables the initial navigation.
  5945. * * `errorHandler` provides a custom error handler.
  5946. * * `preloadingStrategy` configures a preloading strategy (see `PreloadAllModules`).
  5947. * * `onSameUrlNavigation` configures how the router handles navigation to the current URL. See
  5948. * `ExtraOptions` for more details.
  5949. * * `paramsInheritanceStrategy` defines how the router merges params, data and resolved data
  5950. * from parent to child routes.
  5951. * @param {?} routes
  5952. * @param {?=} config
  5953. * @return {?}
  5954. */
  5955. static forRoot(routes, config) {
  5956. return {
  5957. ngModule: RouterModule,
  5958. providers: [
  5959. ROUTER_PROVIDERS,
  5960. provideRoutes(routes),
  5961. {
  5962. provide: ROUTER_FORROOT_GUARD,
  5963. useFactory: provideForRootGuard,
  5964. deps: [[Router, new Optional(), new SkipSelf()]]
  5965. },
  5966. { provide: ROUTER_CONFIGURATION, useValue: config ? config : {} },
  5967. {
  5968. provide: LocationStrategy,
  5969. useFactory: provideLocationStrategy,
  5970. deps: [
  5971. PlatformLocation, [new Inject(APP_BASE_HREF), new Optional()], ROUTER_CONFIGURATION
  5972. ]
  5973. },
  5974. {
  5975. provide: PreloadingStrategy,
  5976. useExisting: config && config.preloadingStrategy ? config.preloadingStrategy :
  5977. NoPreloading
  5978. },
  5979. { provide: NgProbeToken, multi: true, useFactory: routerNgProbeToken },
  5980. provideRouterInitializer(),
  5981. ],
  5982. };
  5983. }
  5984. /**
  5985. * Creates a module with all the router directives and a provider registering routes.
  5986. * @param {?} routes
  5987. * @return {?}
  5988. */
  5989. static forChild(routes) {
  5990. return { ngModule: RouterModule, providers: [provideRoutes(routes)] };
  5991. }
  5992. }
  5993. RouterModule.decorators = [
  5994. { type: NgModule, args: [{
  5995. declarations: ROUTER_DIRECTIVES,
  5996. exports: ROUTER_DIRECTIVES,
  5997. entryComponents: [EmptyOutletComponent]
  5998. },] }
  5999. ];
  6000. /** @nocollapse */
  6001. RouterModule.ctorParameters = () => [
  6002. { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [ROUTER_FORROOT_GUARD,] }] },
  6003. { type: Router, decorators: [{ type: Optional }] }
  6004. ];
  6005. /**
  6006. * @param {?} platformLocationStrategy
  6007. * @param {?} baseHref
  6008. * @param {?=} options
  6009. * @return {?}
  6010. */
  6011. function provideLocationStrategy(platformLocationStrategy, baseHref, options = {}) {
  6012. return options.useHash ? new HashLocationStrategy(platformLocationStrategy, baseHref) :
  6013. new PathLocationStrategy(platformLocationStrategy, baseHref);
  6014. }
  6015. /**
  6016. * @param {?} router
  6017. * @return {?}
  6018. */
  6019. function provideForRootGuard(router) {
  6020. if (router) {
  6021. throw new Error(`RouterModule.forRoot() called twice. Lazy loaded modules should use RouterModule.forChild() instead.`);
  6022. }
  6023. return 'guarded';
  6024. }
  6025. /**
  6026. * \@description
  6027. *
  6028. * Registers routes.
  6029. *
  6030. * ### Example
  6031. *
  6032. * ```
  6033. * \@NgModule({
  6034. * imports: [RouterModule.forChild(ROUTES)],
  6035. * providers: [provideRoutes(EXTRA_ROUTES)]
  6036. * })
  6037. * class MyNgModule {}
  6038. * ```
  6039. *
  6040. *
  6041. * @param {?} routes
  6042. * @return {?}
  6043. */
  6044. function provideRoutes(routes) {
  6045. return [
  6046. { provide: ANALYZE_FOR_ENTRY_COMPONENTS, multi: true, useValue: routes },
  6047. { provide: ROUTES, multi: true, useValue: routes },
  6048. ];
  6049. }
  6050. /**
  6051. * @param {?} ref
  6052. * @param {?} urlSerializer
  6053. * @param {?} contexts
  6054. * @param {?} location
  6055. * @param {?} injector
  6056. * @param {?} loader
  6057. * @param {?} compiler
  6058. * @param {?} config
  6059. * @param {?=} opts
  6060. * @param {?=} urlHandlingStrategy
  6061. * @param {?=} routeReuseStrategy
  6062. * @return {?}
  6063. */
  6064. function setupRouter(ref, urlSerializer, contexts, location, injector, loader, compiler, config, opts = {}, urlHandlingStrategy, routeReuseStrategy) {
  6065. const /** @type {?} */ router = new Router(null, urlSerializer, contexts, location, injector, loader, compiler, flatten(config));
  6066. if (urlHandlingStrategy) {
  6067. router.urlHandlingStrategy = urlHandlingStrategy;
  6068. }
  6069. if (routeReuseStrategy) {
  6070. router.routeReuseStrategy = routeReuseStrategy;
  6071. }
  6072. if (opts.errorHandler) {
  6073. router.errorHandler = opts.errorHandler;
  6074. }
  6075. if (opts.malformedUriErrorHandler) {
  6076. router.malformedUriErrorHandler = opts.malformedUriErrorHandler;
  6077. }
  6078. if (opts.enableTracing) {
  6079. const /** @type {?} */ dom = ɵgetDOM();
  6080. router.events.subscribe((e) => {
  6081. dom.logGroup(`Router Event: ${((/** @type {?} */ (e.constructor))).name}`);
  6082. dom.log(e.toString());
  6083. dom.log(e);
  6084. dom.logGroupEnd();
  6085. });
  6086. }
  6087. if (opts.onSameUrlNavigation) {
  6088. router.onSameUrlNavigation = opts.onSameUrlNavigation;
  6089. }
  6090. if (opts.paramsInheritanceStrategy) {
  6091. router.paramsInheritanceStrategy = opts.paramsInheritanceStrategy;
  6092. }
  6093. return router;
  6094. }
  6095. /**
  6096. * @param {?} router
  6097. * @return {?}
  6098. */
  6099. function rootRoute(router) {
  6100. return router.routerState.root;
  6101. }
  6102. /**
  6103. * To initialize the router properly we need to do in two steps:
  6104. *
  6105. * We need to start the navigation in a APP_INITIALIZER to block the bootstrap if
  6106. * a resolver or a guards executes asynchronously. Second, we need to actually run
  6107. * activation in a BOOTSTRAP_LISTENER. We utilize the afterPreactivation
  6108. * hook provided by the router to do that.
  6109. *
  6110. * The router navigation starts, reaches the point when preactivation is done, and then
  6111. * pauses. It waits for the hook to be resolved. We then resolve it only in a bootstrap listener.
  6112. */
  6113. class RouterInitializer {
  6114. /**
  6115. * @param {?} injector
  6116. */
  6117. constructor(injector) {
  6118. this.injector = injector;
  6119. this.initNavigation = false;
  6120. this.resultOfPreactivationDone = new Subject();
  6121. }
  6122. /**
  6123. * @return {?}
  6124. */
  6125. appInitializer() {
  6126. const /** @type {?} */ p = this.injector.get(LOCATION_INITIALIZED, Promise.resolve(null));
  6127. return p.then(() => {
  6128. let /** @type {?} */ resolve = /** @type {?} */ ((null));
  6129. const /** @type {?} */ res = new Promise(r => resolve = r);
  6130. const /** @type {?} */ router = this.injector.get(Router);
  6131. const /** @type {?} */ opts = this.injector.get(ROUTER_CONFIGURATION);
  6132. if (this.isLegacyDisabled(opts) || this.isLegacyEnabled(opts)) {
  6133. resolve(true);
  6134. }
  6135. else if (opts.initialNavigation === 'disabled') {
  6136. router.setUpLocationChangeListener();
  6137. resolve(true);
  6138. }
  6139. else if (opts.initialNavigation === 'enabled') {
  6140. router.hooks.afterPreactivation = () => {
  6141. // only the initial navigation should be delayed
  6142. if (!this.initNavigation) {
  6143. this.initNavigation = true;
  6144. resolve(true);
  6145. return this.resultOfPreactivationDone;
  6146. // subsequent navigations should not be delayed
  6147. }
  6148. else {
  6149. return /** @type {?} */ (of(null));
  6150. }
  6151. };
  6152. router.initialNavigation();
  6153. }
  6154. else {
  6155. throw new Error(`Invalid initialNavigation options: '${opts.initialNavigation}'`);
  6156. }
  6157. return res;
  6158. });
  6159. }
  6160. /**
  6161. * @param {?} bootstrappedComponentRef
  6162. * @return {?}
  6163. */
  6164. bootstrapListener(bootstrappedComponentRef) {
  6165. const /** @type {?} */ opts = this.injector.get(ROUTER_CONFIGURATION);
  6166. const /** @type {?} */ preloader = this.injector.get(RouterPreloader);
  6167. const /** @type {?} */ router = this.injector.get(Router);
  6168. const /** @type {?} */ ref = this.injector.get(ApplicationRef);
  6169. if (bootstrappedComponentRef !== ref.components[0]) {
  6170. return;
  6171. }
  6172. if (this.isLegacyEnabled(opts)) {
  6173. router.initialNavigation();
  6174. }
  6175. else if (this.isLegacyDisabled(opts)) {
  6176. router.setUpLocationChangeListener();
  6177. }
  6178. preloader.setUpPreloading();
  6179. router.resetRootComponentType(ref.componentTypes[0]);
  6180. this.resultOfPreactivationDone.next(/** @type {?} */ ((null)));
  6181. this.resultOfPreactivationDone.complete();
  6182. }
  6183. /**
  6184. * @param {?} opts
  6185. * @return {?}
  6186. */
  6187. isLegacyEnabled(opts) {
  6188. return opts.initialNavigation === 'legacy_enabled' || opts.initialNavigation === true ||
  6189. opts.initialNavigation === undefined;
  6190. }
  6191. /**
  6192. * @param {?} opts
  6193. * @return {?}
  6194. */
  6195. isLegacyDisabled(opts) {
  6196. return opts.initialNavigation === 'legacy_disabled' || opts.initialNavigation === false;
  6197. }
  6198. }
  6199. RouterInitializer.decorators = [
  6200. { type: Injectable }
  6201. ];
  6202. /** @nocollapse */
  6203. RouterInitializer.ctorParameters = () => [
  6204. { type: Injector }
  6205. ];
  6206. /**
  6207. * @param {?} r
  6208. * @return {?}
  6209. */
  6210. function getAppInitializer(r) {
  6211. return r.appInitializer.bind(r);
  6212. }
  6213. /**
  6214. * @param {?} r
  6215. * @return {?}
  6216. */
  6217. function getBootstrapListener(r) {
  6218. return r.bootstrapListener.bind(r);
  6219. }
  6220. /**
  6221. * A token for the router initializer that will be called after the app is bootstrapped.
  6222. *
  6223. * \@experimental
  6224. */
  6225. const /** @type {?} */ ROUTER_INITIALIZER = new InjectionToken('Router Initializer');
  6226. /**
  6227. * @return {?}
  6228. */
  6229. function provideRouterInitializer() {
  6230. return [
  6231. RouterInitializer,
  6232. {
  6233. provide: APP_INITIALIZER,
  6234. multi: true,
  6235. useFactory: getAppInitializer,
  6236. deps: [RouterInitializer]
  6237. },
  6238. { provide: ROUTER_INITIALIZER, useFactory: getBootstrapListener, deps: [RouterInitializer] },
  6239. { provide: APP_BOOTSTRAP_LISTENER, multi: true, useExisting: ROUTER_INITIALIZER },
  6240. ];
  6241. }
  6242. /**
  6243. * @fileoverview added by tsickle
  6244. * @suppress {checkTypes} checked by tsc
  6245. */
  6246. const /** @type {?} */ VERSION = new Version('6.0.9');
  6247. /**
  6248. * @fileoverview added by tsickle
  6249. * @suppress {checkTypes} checked by tsc
  6250. */
  6251. /**
  6252. * @fileoverview added by tsickle
  6253. * @suppress {checkTypes} checked by tsc
  6254. */
  6255. /**
  6256. * @fileoverview added by tsickle
  6257. * @suppress {checkTypes} checked by tsc
  6258. */
  6259. // This file only reexports content of the `src` folder. Keep it that way.
  6260. /**
  6261. * @fileoverview added by tsickle
  6262. * @suppress {checkTypes} checked by tsc
  6263. */
  6264. /**
  6265. * Generated bundle index. Do not edit.
  6266. */
  6267. export { ROUTER_FORROOT_GUARD as ɵangular_packages_router_router_a, RouterInitializer as ɵangular_packages_router_router_g, getAppInitializer as ɵangular_packages_router_router_h, getBootstrapListener as ɵangular_packages_router_router_i, provideForRootGuard as ɵangular_packages_router_router_d, provideLocationStrategy as ɵangular_packages_router_router_c, provideRouterInitializer as ɵangular_packages_router_router_j, rootRoute as ɵangular_packages_router_router_f, routerNgProbeToken as ɵangular_packages_router_router_b, setupRouter as ɵangular_packages_router_router_e, Tree as ɵangular_packages_router_router_k, TreeNode as ɵangular_packages_router_router_l, RouterLink, RouterLinkWithHref, RouterLinkActive, RouterOutlet, ActivationEnd, ActivationStart, ChildActivationEnd, ChildActivationStart, GuardsCheckEnd, GuardsCheckStart, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RouterEvent, RoutesRecognized, RouteReuseStrategy, Router, ROUTES, ROUTER_CONFIGURATION, ROUTER_INITIALIZER, RouterModule, provideRoutes, ChildrenOutletContexts, OutletContext, NoPreloading, PreloadAllModules, PreloadingStrategy, RouterPreloader, ActivatedRoute, ActivatedRouteSnapshot, RouterState, RouterStateSnapshot, PRIMARY_OUTLET, convertToParamMap, UrlHandlingStrategy, DefaultUrlSerializer, UrlSegment, UrlSegmentGroup, UrlSerializer, UrlTree, VERSION, EmptyOutletComponent as ɵEmptyOutletComponent, ROUTER_PROVIDERS as ɵROUTER_PROVIDERS, flatten as ɵflatten };
  6268. //# sourceMappingURL=router.js.map