1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961 |
- /**
- * @license Angular v7.0.3
- * (c) 2010-2018 Google, Inc. https://angular.io/
- * License: MIT
- */
- import { Component, ɵisObservable, ɵisPromise, NgModuleRef, InjectionToken, NgModuleFactory, NgZone, isDevMode, ɵConsole, 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';
- import { from, of, BehaviorSubject, EmptyError, Observable, EMPTY, Subject } from 'rxjs';
- import { concatAll, every, last, map, mergeAll, catchError, first, mergeMap, switchMap, concatMap, reduce, filter, finalize, tap } from 'rxjs/operators';
- import { LocationStrategy, APP_BASE_HREF, HashLocationStrategy, LOCATION_INITIALIZED, Location, PathLocationStrategy, PlatformLocation, ViewportScroller } from '@angular/common';
- import { ɵgetDOM } from '@angular/platform-browser';
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /**
- * \@description
- *
- * Base for events the Router goes through, as opposed to events tied to a specific
- * Route. `RouterEvent`s will only be fired one time for any given navigation.
- *
- * Example:
- *
- * ```
- * class MyService {
- * constructor(public router: Router, logger: Logger) {
- * router.events.filter(e => e instanceof RouterEvent).subscribe(e => {
- * logger.log(e.id, e.url);
- * });
- * }
- * }
- * ```
- *
- * \@publicApi
- */
- class RouterEvent {
- /**
- * @param {?} id
- * @param {?} url
- */
- constructor(id, url) {
- this.id = id;
- this.url = url;
- }
- }
- /**
- * \@description
- *
- * Represents an event triggered when a navigation starts.
- *
- * \@publicApi
- */
- class NavigationStart extends RouterEvent {
- /**
- * @param {?} id
- * @param {?} url
- * @param {?=} navigationTrigger
- * @param {?=} restoredState
- */
- constructor(/** @docsNotRequired */
- id, /** @docsNotRequired */
- url, /** @docsNotRequired */
- navigationTrigger = 'imperative', /** @docsNotRequired */
- restoredState = null) {
- super(id, url);
- this.navigationTrigger = navigationTrigger;
- this.restoredState = restoredState;
- }
- /**
- * \@docsNotRequired
- * @return {?}
- */
- toString() { return `NavigationStart(id: ${this.id}, url: '${this.url}')`; }
- }
- /**
- * \@description
- *
- * Represents an event triggered when a navigation ends successfully.
- *
- * \@publicApi
- */
- class NavigationEnd extends RouterEvent {
- /**
- * @param {?} id
- * @param {?} url
- * @param {?} urlAfterRedirects
- */
- constructor(/** @docsNotRequired */
- id, /** @docsNotRequired */
- url, urlAfterRedirects) {
- super(id, url);
- this.urlAfterRedirects = urlAfterRedirects;
- }
- /**
- * \@docsNotRequired
- * @return {?}
- */
- toString() {
- return `NavigationEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}')`;
- }
- }
- /**
- * \@description
- *
- * Represents an event triggered when a navigation is canceled.
- *
- * \@publicApi
- */
- class NavigationCancel extends RouterEvent {
- /**
- * @param {?} id
- * @param {?} url
- * @param {?} reason
- */
- constructor(/** @docsNotRequired */
- id, /** @docsNotRequired */
- url, reason) {
- super(id, url);
- this.reason = reason;
- }
- /**
- * \@docsNotRequired
- * @return {?}
- */
- toString() { return `NavigationCancel(id: ${this.id}, url: '${this.url}')`; }
- }
- /**
- * \@description
- *
- * Represents an event triggered when a navigation fails due to an unexpected error.
- *
- * \@publicApi
- */
- class NavigationError extends RouterEvent {
- /**
- * @param {?} id
- * @param {?} url
- * @param {?} error
- */
- constructor(/** @docsNotRequired */
- id, /** @docsNotRequired */
- url, error) {
- super(id, url);
- this.error = error;
- }
- /**
- * \@docsNotRequired
- * @return {?}
- */
- toString() {
- return `NavigationError(id: ${this.id}, url: '${this.url}', error: ${this.error})`;
- }
- }
- /**
- * \@description
- *
- * Represents an event triggered when routes are recognized.
- *
- * \@publicApi
- */
- class RoutesRecognized extends RouterEvent {
- /**
- * @param {?} id
- * @param {?} url
- * @param {?} urlAfterRedirects
- * @param {?} state
- */
- constructor(/** @docsNotRequired */
- id, /** @docsNotRequired */
- url, urlAfterRedirects, state) {
- super(id, url);
- this.urlAfterRedirects = urlAfterRedirects;
- this.state = state;
- }
- /**
- * \@docsNotRequired
- * @return {?}
- */
- toString() {
- return `RoutesRecognized(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
- }
- }
- /**
- * \@description
- *
- * Represents the start of the Guard phase of routing.
- *
- * \@publicApi
- */
- class GuardsCheckStart extends RouterEvent {
- /**
- * @param {?} id
- * @param {?} url
- * @param {?} urlAfterRedirects
- * @param {?} state
- */
- constructor(/** @docsNotRequired */
- id, /** @docsNotRequired */
- url, urlAfterRedirects, state) {
- super(id, url);
- this.urlAfterRedirects = urlAfterRedirects;
- this.state = state;
- }
- /**
- * @return {?}
- */
- toString() {
- return `GuardsCheckStart(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
- }
- }
- /**
- * \@description
- *
- * Represents the end of the Guard phase of routing.
- *
- * \@publicApi
- */
- class GuardsCheckEnd extends RouterEvent {
- /**
- * @param {?} id
- * @param {?} url
- * @param {?} urlAfterRedirects
- * @param {?} state
- * @param {?} shouldActivate
- */
- constructor(/** @docsNotRequired */
- id, /** @docsNotRequired */
- url, urlAfterRedirects, state, shouldActivate) {
- super(id, url);
- this.urlAfterRedirects = urlAfterRedirects;
- this.state = state;
- this.shouldActivate = shouldActivate;
- }
- /**
- * @return {?}
- */
- toString() {
- return `GuardsCheckEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state}, shouldActivate: ${this.shouldActivate})`;
- }
- }
- /**
- * \@description
- *
- * Represents the start of the Resolve phase of routing. The timing of this
- * event may change, thus it's experimental. In the current iteration it will run
- * in the "resolve" phase whether there's things to resolve or not. In the future this
- * behavior may change to only run when there are things to be resolved.
- *
- * \@publicApi
- */
- class ResolveStart extends RouterEvent {
- /**
- * @param {?} id
- * @param {?} url
- * @param {?} urlAfterRedirects
- * @param {?} state
- */
- constructor(/** @docsNotRequired */
- id, /** @docsNotRequired */
- url, urlAfterRedirects, state) {
- super(id, url);
- this.urlAfterRedirects = urlAfterRedirects;
- this.state = state;
- }
- /**
- * @return {?}
- */
- toString() {
- return `ResolveStart(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
- }
- }
- /**
- * \@description
- *
- * Represents the end of the Resolve phase of routing. See note on
- * `ResolveStart` for use of this experimental API.
- *
- * \@publicApi
- */
- class ResolveEnd extends RouterEvent {
- /**
- * @param {?} id
- * @param {?} url
- * @param {?} urlAfterRedirects
- * @param {?} state
- */
- constructor(/** @docsNotRequired */
- id, /** @docsNotRequired */
- url, urlAfterRedirects, state) {
- super(id, url);
- this.urlAfterRedirects = urlAfterRedirects;
- this.state = state;
- }
- /**
- * @return {?}
- */
- toString() {
- return `ResolveEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
- }
- }
- /**
- * \@description
- *
- * Represents an event triggered before lazy loading a route config.
- *
- * \@publicApi
- */
- class RouteConfigLoadStart {
- /**
- * @param {?} route
- */
- constructor(route) {
- this.route = route;
- }
- /**
- * @return {?}
- */
- toString() { return `RouteConfigLoadStart(path: ${this.route.path})`; }
- }
- /**
- * \@description
- *
- * Represents an event triggered when a route has been lazy loaded.
- *
- * \@publicApi
- */
- class RouteConfigLoadEnd {
- /**
- * @param {?} route
- */
- constructor(route) {
- this.route = route;
- }
- /**
- * @return {?}
- */
- toString() { return `RouteConfigLoadEnd(path: ${this.route.path})`; }
- }
- /**
- * \@description
- *
- * Represents the start of end of the Resolve phase of routing. See note on
- * `ChildActivationEnd` for use of this experimental API.
- *
- * \@publicApi
- */
- class ChildActivationStart {
- /**
- * @param {?} snapshot
- */
- constructor(snapshot) {
- this.snapshot = snapshot;
- }
- /**
- * @return {?}
- */
- toString() {
- /** @type {?} */
- const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
- return `ChildActivationStart(path: '${path}')`;
- }
- }
- /**
- * \@description
- *
- * Represents the start of end of the Resolve phase of routing. See note on
- * `ChildActivationStart` for use of this experimental API.
- *
- * \@publicApi
- */
- class ChildActivationEnd {
- /**
- * @param {?} snapshot
- */
- constructor(snapshot) {
- this.snapshot = snapshot;
- }
- /**
- * @return {?}
- */
- toString() {
- /** @type {?} */
- const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
- return `ChildActivationEnd(path: '${path}')`;
- }
- }
- /**
- * \@description
- *
- * Represents the start of end of the Resolve phase of routing. See note on
- * `ActivationEnd` for use of this experimental API.
- *
- * \@publicApi
- */
- class ActivationStart {
- /**
- * @param {?} snapshot
- */
- constructor(snapshot) {
- this.snapshot = snapshot;
- }
- /**
- * @return {?}
- */
- toString() {
- /** @type {?} */
- const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
- return `ActivationStart(path: '${path}')`;
- }
- }
- /**
- * \@description
- *
- * Represents the start of end of the Resolve phase of routing. See note on
- * `ActivationStart` for use of this experimental API.
- *
- * \@publicApi
- */
- class ActivationEnd {
- /**
- * @param {?} snapshot
- */
- constructor(snapshot) {
- this.snapshot = snapshot;
- }
- /**
- * @return {?}
- */
- toString() {
- /** @type {?} */
- const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
- return `ActivationEnd(path: '${path}')`;
- }
- }
- /**
- * \@description
- *
- * Represents a scrolling event.
- *
- * \@publicApi
- */
- class Scroll {
- /**
- * @param {?} routerEvent
- * @param {?} position
- * @param {?} anchor
- */
- constructor(/** @docsNotRequired */
- routerEvent, /** @docsNotRequired */
- position, /** @docsNotRequired */
- anchor) {
- this.routerEvent = routerEvent;
- this.position = position;
- this.anchor = anchor;
- }
- /**
- * @return {?}
- */
- toString() {
- /** @type {?} */
- const pos = this.position ? `${this.position[0]}, ${this.position[1]}` : null;
- return `Scroll(anchor: '${this.anchor}', position: '${pos}')`;
- }
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /**
- * This component is used internally within the router to be a placeholder when an empty
- * router-outlet is needed. For example, with a config such as:
- *
- * `{path: 'parent', outlet: 'nav', children: [...]}`
- *
- * In order to render, there needs to be a component on this config, which will default
- * to this `EmptyOutletComponent`.
- */
- class EmptyOutletComponent {
- }
- EmptyOutletComponent.decorators = [
- { type: Component, args: [{ template: `<router-outlet></router-outlet>` }] }
- ];
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /**
- * @license
- * Copyright Google Inc. All Rights Reserved.
- *
- * Use of this source code is governed by an MIT-style license that can be
- * found in the LICENSE file at https://angular.io/license
- */
- /** *
- * \@description
- *
- * Name of the primary outlet.
- *
- * \@publicApi
- @type {?} */
- const PRIMARY_OUTLET = 'primary';
- class ParamsAsMap {
- /**
- * @param {?} params
- */
- constructor(params) { this.params = params || {}; }
- /**
- * @param {?} name
- * @return {?}
- */
- has(name) { return this.params.hasOwnProperty(name); }
- /**
- * @param {?} name
- * @return {?}
- */
- get(name) {
- if (this.has(name)) {
- /** @type {?} */
- const v = this.params[name];
- return Array.isArray(v) ? v[0] : v;
- }
- return null;
- }
- /**
- * @param {?} name
- * @return {?}
- */
- getAll(name) {
- if (this.has(name)) {
- /** @type {?} */
- const v = this.params[name];
- return Array.isArray(v) ? v : [v];
- }
- return [];
- }
- /**
- * @return {?}
- */
- get keys() { return Object.keys(this.params); }
- }
- /**
- * Convert a `Params` instance to a `ParamMap`.
- *
- * \@publicApi
- * @param {?} params
- * @return {?}
- */
- function convertToParamMap(params) {
- return new ParamsAsMap(params);
- }
- /** @type {?} */
- const NAVIGATION_CANCELING_ERROR = 'ngNavigationCancelingError';
- /**
- * @param {?} message
- * @return {?}
- */
- function navigationCancelingError(message) {
- /** @type {?} */
- const error = Error('NavigationCancelingError: ' + message);
- (/** @type {?} */ (error))[NAVIGATION_CANCELING_ERROR] = true;
- return error;
- }
- /**
- * @param {?} error
- * @return {?}
- */
- function isNavigationCancelingError(error) {
- return error && (/** @type {?} */ (error))[NAVIGATION_CANCELING_ERROR];
- }
- /**
- * @param {?} segments
- * @param {?} segmentGroup
- * @param {?} route
- * @return {?}
- */
- function defaultUrlMatcher(segments, segmentGroup, route) {
- /** @type {?} */
- const parts = /** @type {?} */ ((route.path)).split('/');
- if (parts.length > segments.length) {
- // The actual URL is shorter than the config, no match
- return null;
- }
- if (route.pathMatch === 'full' &&
- (segmentGroup.hasChildren() || parts.length < segments.length)) {
- // The config is longer than the actual URL but we are looking for a full match, return null
- return null;
- }
- /** @type {?} */
- const posParams = {};
- // Check each config part against the actual URL
- for (let index = 0; index < parts.length; index++) {
- /** @type {?} */
- const part = parts[index];
- /** @type {?} */
- const segment = segments[index];
- /** @type {?} */
- const isParameter = part.startsWith(':');
- if (isParameter) {
- posParams[part.substring(1)] = segment;
- }
- else if (part !== segment.path) {
- // The actual URL part does not match the config, no match
- return null;
- }
- }
- return { consumed: segments.slice(0, parts.length), posParams };
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- class LoadedRouterConfig {
- /**
- * @param {?} routes
- * @param {?} module
- */
- constructor(routes, module) {
- this.routes = routes;
- this.module = module;
- }
- }
- /**
- * @param {?} config
- * @param {?=} parentPath
- * @return {?}
- */
- function validateConfig(config, parentPath = '') {
- // forEach doesn't iterate undefined values
- for (let i = 0; i < config.length; i++) {
- /** @type {?} */
- const route = config[i];
- /** @type {?} */
- const fullPath = getFullPath(parentPath, route);
- validateNode(route, fullPath);
- }
- }
- /**
- * @param {?} route
- * @param {?} fullPath
- * @return {?}
- */
- function validateNode(route, fullPath) {
- if (!route) {
- throw new Error(`
- Invalid configuration of route '${fullPath}': Encountered undefined route.
- The reason might be an extra comma.
- Example:
- const routes: Routes = [
- { path: '', redirectTo: '/dashboard', pathMatch: 'full' },
- { path: 'dashboard', component: DashboardComponent },, << two commas
- { path: 'detail/:id', component: HeroDetailComponent }
- ];
- `);
- }
- if (Array.isArray(route)) {
- throw new Error(`Invalid configuration of route '${fullPath}': Array cannot be specified`);
- }
- if (!route.component && !route.children && !route.loadChildren &&
- (route.outlet && route.outlet !== PRIMARY_OUTLET)) {
- throw new Error(`Invalid configuration of route '${fullPath}': a componentless route without children or loadChildren cannot have a named outlet set`);
- }
- if (route.redirectTo && route.children) {
- throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and children cannot be used together`);
- }
- if (route.redirectTo && route.loadChildren) {
- throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and loadChildren cannot be used together`);
- }
- if (route.children && route.loadChildren) {
- throw new Error(`Invalid configuration of route '${fullPath}': children and loadChildren cannot be used together`);
- }
- if (route.redirectTo && route.component) {
- throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and component cannot be used together`);
- }
- if (route.path && route.matcher) {
- throw new Error(`Invalid configuration of route '${fullPath}': path and matcher cannot be used together`);
- }
- if (route.redirectTo === void 0 && !route.component && !route.children && !route.loadChildren) {
- throw new Error(`Invalid configuration of route '${fullPath}'. One of the following must be provided: component, redirectTo, children or loadChildren`);
- }
- if (route.path === void 0 && route.matcher === void 0) {
- throw new Error(`Invalid configuration of route '${fullPath}': routes must have either a path or a matcher specified`);
- }
- if (typeof route.path === 'string' && route.path.charAt(0) === '/') {
- throw new Error(`Invalid configuration of route '${fullPath}': path cannot start with a slash`);
- }
- if (route.path === '' && route.redirectTo !== void 0 && route.pathMatch === void 0) {
- /** @type {?} */
- const exp = `The default value of 'pathMatch' is 'prefix', but often the intent is to use 'full'.`;
- throw new Error(`Invalid configuration of route '{path: "${fullPath}", redirectTo: "${route.redirectTo}"}': please provide 'pathMatch'. ${exp}`);
- }
- if (route.pathMatch !== void 0 && route.pathMatch !== 'full' && route.pathMatch !== 'prefix') {
- throw new Error(`Invalid configuration of route '${fullPath}': pathMatch can only be set to 'prefix' or 'full'`);
- }
- if (route.children) {
- validateConfig(route.children, fullPath);
- }
- }
- /**
- * @param {?} parentPath
- * @param {?} currentRoute
- * @return {?}
- */
- function getFullPath(parentPath, currentRoute) {
- if (!currentRoute) {
- return parentPath;
- }
- if (!parentPath && !currentRoute.path) {
- return '';
- }
- else if (parentPath && !currentRoute.path) {
- return `${parentPath}/`;
- }
- else if (!parentPath && currentRoute.path) {
- return currentRoute.path;
- }
- else {
- return `${parentPath}/${currentRoute.path}`;
- }
- }
- /**
- * Makes a copy of the config and adds any default required properties.
- * @param {?} r
- * @return {?}
- */
- function standardizeConfig(r) {
- /** @type {?} */
- const children = r.children && r.children.map(standardizeConfig);
- /** @type {?} */
- const c = children ? Object.assign({}, r, { children }) : Object.assign({}, r);
- if (!c.component && (children || c.loadChildren) && (c.outlet && c.outlet !== PRIMARY_OUTLET)) {
- c.component = EmptyOutletComponent;
- }
- return c;
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /**
- * @param {?} a
- * @param {?} b
- * @return {?}
- */
- function shallowEqualArrays(a, b) {
- if (a.length !== b.length)
- return false;
- for (let i = 0; i < a.length; ++i) {
- if (!shallowEqual(a[i], b[i]))
- return false;
- }
- return true;
- }
- /**
- * @param {?} a
- * @param {?} b
- * @return {?}
- */
- function shallowEqual(a, b) {
- /** @type {?} */
- const k1 = Object.keys(a);
- /** @type {?} */
- const k2 = Object.keys(b);
- if (k1.length != k2.length) {
- return false;
- }
- /** @type {?} */
- let key;
- for (let i = 0; i < k1.length; i++) {
- key = k1[i];
- if (a[key] !== b[key]) {
- return false;
- }
- }
- return true;
- }
- /**
- * Flattens single-level nested arrays.
- * @template T
- * @param {?} arr
- * @return {?}
- */
- function flatten(arr) {
- return Array.prototype.concat.apply([], arr);
- }
- /**
- * Return the last element of an array.
- * @template T
- * @param {?} a
- * @return {?}
- */
- function last$1(a) {
- return a.length > 0 ? a[a.length - 1] : null;
- }
- /**
- * @template K, V
- * @param {?} map
- * @param {?} callback
- * @return {?}
- */
- function forEach(map$$1, callback) {
- for (const prop in map$$1) {
- if (map$$1.hasOwnProperty(prop)) {
- callback(map$$1[prop], prop);
- }
- }
- }
- /**
- * @template A, B
- * @param {?} obj
- * @param {?} fn
- * @return {?}
- */
- function waitForMap(obj, fn) {
- if (Object.keys(obj).length === 0) {
- return of({});
- }
- /** @type {?} */
- const waitHead = [];
- /** @type {?} */
- const waitTail = [];
- /** @type {?} */
- const res = {};
- forEach(obj, (a, k) => {
- /** @type {?} */
- const mapped = fn(k, a).pipe(map((r) => res[k] = r));
- if (k === PRIMARY_OUTLET) {
- waitHead.push(mapped);
- }
- else {
- waitTail.push(mapped);
- }
- });
- // Closure compiler has problem with using spread operator here. So just using Array.concat.
- return of.apply(null, waitHead.concat(waitTail)).pipe(concatAll(), last(), map(() => res));
- }
- /**
- * ANDs Observables by merging all input observables, reducing to an Observable verifying all
- * input Observables return `true`.
- * @param {?} observables
- * @return {?}
- */
- function andObservables(observables) {
- return observables.pipe(mergeAll(), every((result) => result === true));
- }
- /**
- * @template T
- * @param {?} value
- * @return {?}
- */
- function wrapIntoObservable(value) {
- if (ɵisObservable(value)) {
- return value;
- }
- if (ɵisPromise(value)) {
- // Use `Promise.resolve()` to wrap promise-like instances.
- // Required ie when a Resolver returns a AngularJS `$q` promise to correctly trigger the
- // change detection.
- return from(Promise.resolve(value));
- }
- return of(/** @type {?} */ (value));
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /**
- * @return {?}
- */
- function createEmptyUrlTree() {
- return new UrlTree(new UrlSegmentGroup([], {}), {}, null);
- }
- /**
- * @param {?} container
- * @param {?} containee
- * @param {?} exact
- * @return {?}
- */
- function containsTree(container, containee, exact) {
- if (exact) {
- return equalQueryParams(container.queryParams, containee.queryParams) &&
- equalSegmentGroups(container.root, containee.root);
- }
- return containsQueryParams(container.queryParams, containee.queryParams) &&
- containsSegmentGroup(container.root, containee.root);
- }
- /**
- * @param {?} container
- * @param {?} containee
- * @return {?}
- */
- function equalQueryParams(container, containee) {
- // TODO: This does not handle array params correctly.
- return shallowEqual(container, containee);
- }
- /**
- * @param {?} container
- * @param {?} containee
- * @return {?}
- */
- function equalSegmentGroups(container, containee) {
- if (!equalPath(container.segments, containee.segments))
- return false;
- if (container.numberOfChildren !== containee.numberOfChildren)
- return false;
- for (const c in containee.children) {
- if (!container.children[c])
- return false;
- if (!equalSegmentGroups(container.children[c], containee.children[c]))
- return false;
- }
- return true;
- }
- /**
- * @param {?} container
- * @param {?} containee
- * @return {?}
- */
- function containsQueryParams(container, containee) {
- // TODO: This does not handle array params correctly.
- return Object.keys(containee).length <= Object.keys(container).length &&
- Object.keys(containee).every(key => containee[key] === container[key]);
- }
- /**
- * @param {?} container
- * @param {?} containee
- * @return {?}
- */
- function containsSegmentGroup(container, containee) {
- return containsSegmentGroupHelper(container, containee, containee.segments);
- }
- /**
- * @param {?} container
- * @param {?} containee
- * @param {?} containeePaths
- * @return {?}
- */
- function containsSegmentGroupHelper(container, containee, containeePaths) {
- if (container.segments.length > containeePaths.length) {
- /** @type {?} */
- const current = container.segments.slice(0, containeePaths.length);
- if (!equalPath(current, containeePaths))
- return false;
- if (containee.hasChildren())
- return false;
- return true;
- }
- else if (container.segments.length === containeePaths.length) {
- if (!equalPath(container.segments, containeePaths))
- return false;
- for (const c in containee.children) {
- if (!container.children[c])
- return false;
- if (!containsSegmentGroup(container.children[c], containee.children[c]))
- return false;
- }
- return true;
- }
- else {
- /** @type {?} */
- const current = containeePaths.slice(0, container.segments.length);
- /** @type {?} */
- const next = containeePaths.slice(container.segments.length);
- if (!equalPath(container.segments, current))
- return false;
- if (!container.children[PRIMARY_OUTLET])
- return false;
- return containsSegmentGroupHelper(container.children[PRIMARY_OUTLET], containee, next);
- }
- }
- /**
- * \@description
- *
- * Represents the parsed URL.
- *
- * Since a router state is a tree, and the URL is nothing but a serialized state, the URL is a
- * serialized tree.
- * UrlTree is a data structure that provides a lot of affordances in dealing with URLs
- *
- * \@usageNotes
- * ### Example
- *
- * ```
- * \@Component({templateUrl:'template.html'})
- * class MyComponent {
- * constructor(router: Router) {
- * const tree: UrlTree =
- * router.parseUrl('/team/33/(user/victor//support:help)?debug=true#fragment');
- * const f = tree.fragment; // return 'fragment'
- * const q = tree.queryParams; // returns {debug: 'true'}
- * const g: UrlSegmentGroup = tree.root.children[PRIMARY_OUTLET];
- * const s: UrlSegment[] = g.segments; // returns 2 segments 'team' and '33'
- * g.children[PRIMARY_OUTLET].segments; // returns 2 segments 'user' and 'victor'
- * g.children['support'].segments; // return 1 segment 'help'
- * }
- * }
- * ```
- *
- * \@publicApi
- */
- class UrlTree {
- /**
- * \@internal
- * @param {?} root
- * @param {?} queryParams
- * @param {?} fragment
- */
- constructor(root, queryParams, fragment) {
- this.root = root;
- this.queryParams = queryParams;
- this.fragment = fragment;
- }
- /**
- * @return {?}
- */
- get queryParamMap() {
- if (!this._queryParamMap) {
- this._queryParamMap = convertToParamMap(this.queryParams);
- }
- return this._queryParamMap;
- }
- /**
- * \@docsNotRequired
- * @return {?}
- */
- toString() { return DEFAULT_SERIALIZER.serialize(this); }
- }
- /**
- * \@description
- *
- * Represents the parsed URL segment group.
- *
- * See `UrlTree` for more information.
- *
- * \@publicApi
- */
- class UrlSegmentGroup {
- /**
- * @param {?} segments
- * @param {?} children
- */
- constructor(segments, children) {
- this.segments = segments;
- this.children = children;
- /**
- * The parent node in the url tree
- */
- this.parent = null;
- forEach(children, (v, k) => v.parent = this);
- }
- /**
- * Whether the segment has child segments
- * @return {?}
- */
- hasChildren() { return this.numberOfChildren > 0; }
- /**
- * Number of child segments
- * @return {?}
- */
- get numberOfChildren() { return Object.keys(this.children).length; }
- /**
- * \@docsNotRequired
- * @return {?}
- */
- toString() { return serializePaths(this); }
- }
- /**
- * \@description
- *
- * Represents a single URL segment.
- *
- * A UrlSegment is a part of a URL between the two slashes. It contains a path and the matrix
- * parameters associated with the segment.
- *
- * \@usageNotes
- * ### Example
- *
- * ```
- * \@Component({templateUrl:'template.html'})
- * class MyComponent {
- * constructor(router: Router) {
- * const tree: UrlTree = router.parseUrl('/team;id=33');
- * const g: UrlSegmentGroup = tree.root.children[PRIMARY_OUTLET];
- * const s: UrlSegment[] = g.segments;
- * s[0].path; // returns 'team'
- * s[0].parameters; // returns {id: 33}
- * }
- * }
- * ```
- *
- * \@publicApi
- */
- class UrlSegment {
- /**
- * @param {?} path
- * @param {?} parameters
- */
- constructor(path, parameters) {
- this.path = path;
- this.parameters = parameters;
- }
- /**
- * @return {?}
- */
- get parameterMap() {
- if (!this._parameterMap) {
- this._parameterMap = convertToParamMap(this.parameters);
- }
- return this._parameterMap;
- }
- /**
- * \@docsNotRequired
- * @return {?}
- */
- toString() { return serializePath(this); }
- }
- /**
- * @param {?} as
- * @param {?} bs
- * @return {?}
- */
- function equalSegments(as, bs) {
- return equalPath(as, bs) && as.every((a, i) => shallowEqual(a.parameters, bs[i].parameters));
- }
- /**
- * @param {?} as
- * @param {?} bs
- * @return {?}
- */
- function equalPath(as, bs) {
- if (as.length !== bs.length)
- return false;
- return as.every((a, i) => a.path === bs[i].path);
- }
- /**
- * @template T
- * @param {?} segment
- * @param {?} fn
- * @return {?}
- */
- function mapChildrenIntoArray(segment, fn) {
- /** @type {?} */
- let res = [];
- forEach(segment.children, (child, childOutlet) => {
- if (childOutlet === PRIMARY_OUTLET) {
- res = res.concat(fn(child, childOutlet));
- }
- });
- forEach(segment.children, (child, childOutlet) => {
- if (childOutlet !== PRIMARY_OUTLET) {
- res = res.concat(fn(child, childOutlet));
- }
- });
- return res;
- }
- /**
- * \@description
- *
- * Serializes and deserializes a URL string into a URL tree.
- *
- * The url serialization strategy is customizable. You can
- * make all URLs case insensitive by providing a custom UrlSerializer.
- *
- * See `DefaultUrlSerializer` for an example of a URL serializer.
- *
- * \@publicApi
- * @abstract
- */
- class UrlSerializer {
- }
- /**
- * \@description
- *
- * A default implementation of the `UrlSerializer`.
- *
- * Example URLs:
- *
- * ```
- * /inbox/33(popup:compose)
- * /inbox/33;open=true/messages/44
- * ```
- *
- * DefaultUrlSerializer uses parentheses to serialize secondary segments (e.g., popup:compose), the
- * colon syntax to specify the outlet, and the ';parameter=value' syntax (e.g., open=true) to
- * specify route specific parameters.
- *
- * \@publicApi
- */
- class DefaultUrlSerializer {
- /**
- * Parses a url into a `UrlTree`
- * @param {?} url
- * @return {?}
- */
- parse(url) {
- /** @type {?} */
- const p = new UrlParser(url);
- return new UrlTree(p.parseRootSegment(), p.parseQueryParams(), p.parseFragment());
- }
- /**
- * Converts a `UrlTree` into a url
- * @param {?} tree
- * @return {?}
- */
- serialize(tree) {
- /** @type {?} */
- const segment = `/${serializeSegment(tree.root, true)}`;
- /** @type {?} */
- const query = serializeQueryParams(tree.queryParams);
- /** @type {?} */
- const fragment = typeof tree.fragment === `string` ? `#${encodeUriFragment((/** @type {?} */ ((tree.fragment))))}` : '';
- return `${segment}${query}${fragment}`;
- }
- }
- /** @type {?} */
- const DEFAULT_SERIALIZER = new DefaultUrlSerializer();
- /**
- * @param {?} segment
- * @return {?}
- */
- function serializePaths(segment) {
- return segment.segments.map(p => serializePath(p)).join('/');
- }
- /**
- * @param {?} segment
- * @param {?} root
- * @return {?}
- */
- function serializeSegment(segment, root) {
- if (!segment.hasChildren()) {
- return serializePaths(segment);
- }
- if (root) {
- /** @type {?} */
- const primary = segment.children[PRIMARY_OUTLET] ?
- serializeSegment(segment.children[PRIMARY_OUTLET], false) :
- '';
- /** @type {?} */
- const children = [];
- forEach(segment.children, (v, k) => {
- if (k !== PRIMARY_OUTLET) {
- children.push(`${k}:${serializeSegment(v, false)}`);
- }
- });
- return children.length > 0 ? `${primary}(${children.join('//')})` : primary;
- }
- else {
- /** @type {?} */
- const children = mapChildrenIntoArray(segment, (v, k) => {
- if (k === PRIMARY_OUTLET) {
- return [serializeSegment(segment.children[PRIMARY_OUTLET], false)];
- }
- return [`${k}:${serializeSegment(v, false)}`];
- });
- return `${serializePaths(segment)}/(${children.join('//')})`;
- }
- }
- /**
- * Encodes a URI string with the default encoding. This function will only ever be called from
- * `encodeUriQuery` or `encodeUriSegment` as it's the base set of encodings to be used. We need
- * a custom encoding because encodeURIComponent is too aggressive and encodes stuff that doesn't
- * have to be encoded per https://url.spec.whatwg.org.
- * @param {?} s
- * @return {?}
- */
- function encodeUriString(s) {
- return encodeURIComponent(s)
- .replace(/%40/g, '@')
- .replace(/%3A/gi, ':')
- .replace(/%24/g, '$')
- .replace(/%2C/gi, ',');
- }
- /**
- * This function should be used to encode both keys and values in a query string key/value. In
- * the following URL, you need to call encodeUriQuery on "k" and "v":
- *
- * http://www.site.org/html;mk=mv?k=v#f
- * @param {?} s
- * @return {?}
- */
- function encodeUriQuery(s) {
- return encodeUriString(s).replace(/%3B/gi, ';');
- }
- /**
- * This function should be used to encode a URL fragment. In the following URL, you need to call
- * encodeUriFragment on "f":
- *
- * http://www.site.org/html;mk=mv?k=v#f
- * @param {?} s
- * @return {?}
- */
- function encodeUriFragment(s) {
- return encodeURI(s);
- }
- /**
- * This function should be run on any URI segment as well as the key and value in a key/value
- * pair for matrix params. In the following URL, you need to call encodeUriSegment on "html",
- * "mk", and "mv":
- *
- * http://www.site.org/html;mk=mv?k=v#f
- * @param {?} s
- * @return {?}
- */
- function encodeUriSegment(s) {
- return encodeUriString(s).replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/%26/gi, '&');
- }
- /**
- * @param {?} s
- * @return {?}
- */
- function decode(s) {
- return decodeURIComponent(s);
- }
- /**
- * @param {?} s
- * @return {?}
- */
- function decodeQuery(s) {
- return decode(s.replace(/\+/g, '%20'));
- }
- /**
- * @param {?} path
- * @return {?}
- */
- function serializePath(path) {
- return `${encodeUriSegment(path.path)}${serializeMatrixParams(path.parameters)}`;
- }
- /**
- * @param {?} params
- * @return {?}
- */
- function serializeMatrixParams(params) {
- return Object.keys(params)
- .map(key => `;${encodeUriSegment(key)}=${encodeUriSegment(params[key])}`)
- .join('');
- }
- /**
- * @param {?} params
- * @return {?}
- */
- function serializeQueryParams(params) {
- /** @type {?} */
- const strParams = Object.keys(params).map((name) => {
- /** @type {?} */
- const value = params[name];
- return Array.isArray(value) ?
- value.map(v => `${encodeUriQuery(name)}=${encodeUriQuery(v)}`).join('&') :
- `${encodeUriQuery(name)}=${encodeUriQuery(value)}`;
- });
- return strParams.length ? `?${strParams.join("&")}` : '';
- }
- /** @type {?} */
- const SEGMENT_RE = /^[^\/()?;=#]+/;
- /**
- * @param {?} str
- * @return {?}
- */
- function matchSegments(str) {
- /** @type {?} */
- const match = str.match(SEGMENT_RE);
- return match ? match[0] : '';
- }
- /** @type {?} */
- const QUERY_PARAM_RE = /^[^=?&#]+/;
- /**
- * @param {?} str
- * @return {?}
- */
- function matchQueryParams(str) {
- /** @type {?} */
- const match = str.match(QUERY_PARAM_RE);
- return match ? match[0] : '';
- }
- /** @type {?} */
- const QUERY_PARAM_VALUE_RE = /^[^?&#]+/;
- /**
- * @param {?} str
- * @return {?}
- */
- function matchUrlQueryParamValue(str) {
- /** @type {?} */
- const match = str.match(QUERY_PARAM_VALUE_RE);
- return match ? match[0] : '';
- }
- class UrlParser {
- /**
- * @param {?} url
- */
- constructor(url) {
- this.url = url;
- this.remaining = url;
- }
- /**
- * @return {?}
- */
- parseRootSegment() {
- this.consumeOptional('/');
- if (this.remaining === '' || this.peekStartsWith('?') || this.peekStartsWith('#')) {
- return new UrlSegmentGroup([], {});
- }
- // The root segment group never has segments
- return new UrlSegmentGroup([], this.parseChildren());
- }
- /**
- * @return {?}
- */
- parseQueryParams() {
- /** @type {?} */
- const params = {};
- if (this.consumeOptional('?')) {
- do {
- this.parseQueryParam(params);
- } while (this.consumeOptional('&'));
- }
- return params;
- }
- /**
- * @return {?}
- */
- parseFragment() {
- return this.consumeOptional('#') ? decodeURIComponent(this.remaining) : null;
- }
- /**
- * @return {?}
- */
- parseChildren() {
- if (this.remaining === '') {
- return {};
- }
- this.consumeOptional('/');
- /** @type {?} */
- const segments = [];
- if (!this.peekStartsWith('(')) {
- segments.push(this.parseSegment());
- }
- while (this.peekStartsWith('/') && !this.peekStartsWith('//') && !this.peekStartsWith('/(')) {
- this.capture('/');
- segments.push(this.parseSegment());
- }
- /** @type {?} */
- let children = {};
- if (this.peekStartsWith('/(')) {
- this.capture('/');
- children = this.parseParens(true);
- }
- /** @type {?} */
- let res = {};
- if (this.peekStartsWith('(')) {
- res = this.parseParens(false);
- }
- if (segments.length > 0 || Object.keys(children).length > 0) {
- res[PRIMARY_OUTLET] = new UrlSegmentGroup(segments, children);
- }
- return res;
- }
- /**
- * @return {?}
- */
- parseSegment() {
- /** @type {?} */
- const path = matchSegments(this.remaining);
- if (path === '' && this.peekStartsWith(';')) {
- throw new Error(`Empty path url segment cannot have parameters: '${this.remaining}'.`);
- }
- this.capture(path);
- return new UrlSegment(decode(path), this.parseMatrixParams());
- }
- /**
- * @return {?}
- */
- parseMatrixParams() {
- /** @type {?} */
- const params = {};
- while (this.consumeOptional(';')) {
- this.parseParam(params);
- }
- return params;
- }
- /**
- * @param {?} params
- * @return {?}
- */
- parseParam(params) {
- /** @type {?} */
- const key = matchSegments(this.remaining);
- if (!key) {
- return;
- }
- this.capture(key);
- /** @type {?} */
- let value = '';
- if (this.consumeOptional('=')) {
- /** @type {?} */
- const valueMatch = matchSegments(this.remaining);
- if (valueMatch) {
- value = valueMatch;
- this.capture(value);
- }
- }
- params[decode(key)] = decode(value);
- }
- /**
- * @param {?} params
- * @return {?}
- */
- parseQueryParam(params) {
- /** @type {?} */
- const key = matchQueryParams(this.remaining);
- if (!key) {
- return;
- }
- this.capture(key);
- /** @type {?} */
- let value = '';
- if (this.consumeOptional('=')) {
- /** @type {?} */
- const valueMatch = matchUrlQueryParamValue(this.remaining);
- if (valueMatch) {
- value = valueMatch;
- this.capture(value);
- }
- }
- /** @type {?} */
- const decodedKey = decodeQuery(key);
- /** @type {?} */
- const decodedVal = decodeQuery(value);
- if (params.hasOwnProperty(decodedKey)) {
- /** @type {?} */
- let currentVal = params[decodedKey];
- if (!Array.isArray(currentVal)) {
- currentVal = [currentVal];
- params[decodedKey] = currentVal;
- }
- currentVal.push(decodedVal);
- }
- else {
- // Create a new value
- params[decodedKey] = decodedVal;
- }
- }
- /**
- * @param {?} allowPrimary
- * @return {?}
- */
- parseParens(allowPrimary) {
- /** @type {?} */
- const segments = {};
- this.capture('(');
- while (!this.consumeOptional(')') && this.remaining.length > 0) {
- /** @type {?} */
- const path = matchSegments(this.remaining);
- /** @type {?} */
- const next = this.remaining[path.length];
- // if is is not one of these characters, then the segment was unescaped
- // or the group was not closed
- if (next !== '/' && next !== ')' && next !== ';') {
- throw new Error(`Cannot parse url '${this.url}'`);
- }
- /** @type {?} */
- let outletName = /** @type {?} */ ((undefined));
- if (path.indexOf(':') > -1) {
- outletName = path.substr(0, path.indexOf(':'));
- this.capture(outletName);
- this.capture(':');
- }
- else if (allowPrimary) {
- outletName = PRIMARY_OUTLET;
- }
- /** @type {?} */
- const children = this.parseChildren();
- segments[outletName] = Object.keys(children).length === 1 ? children[PRIMARY_OUTLET] :
- new UrlSegmentGroup([], children);
- this.consumeOptional('//');
- }
- return segments;
- }
- /**
- * @param {?} str
- * @return {?}
- */
- peekStartsWith(str) { return this.remaining.startsWith(str); }
- /**
- * @param {?} str
- * @return {?}
- */
- consumeOptional(str) {
- if (this.peekStartsWith(str)) {
- this.remaining = this.remaining.substring(str.length);
- return true;
- }
- return false;
- }
- /**
- * @param {?} str
- * @return {?}
- */
- capture(str) {
- if (!this.consumeOptional(str)) {
- throw new Error(`Expected "${str}".`);
- }
- }
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /**
- * @license
- * Copyright Google Inc. All Rights Reserved.
- *
- * Use of this source code is governed by an MIT-style license that can be
- * found in the LICENSE file at https://angular.io/license
- */
- /**
- * @template T
- */
- class Tree {
- /**
- * @param {?} root
- */
- constructor(root) { this._root = root; }
- /**
- * @return {?}
- */
- get root() { return this._root.value; }
- /**
- * \@internal
- * @param {?} t
- * @return {?}
- */
- parent(t) {
- /** @type {?} */
- const p = this.pathFromRoot(t);
- return p.length > 1 ? p[p.length - 2] : null;
- }
- /**
- * \@internal
- * @param {?} t
- * @return {?}
- */
- children(t) {
- /** @type {?} */
- const n = findNode(t, this._root);
- return n ? n.children.map(t => t.value) : [];
- }
- /**
- * \@internal
- * @param {?} t
- * @return {?}
- */
- firstChild(t) {
- /** @type {?} */
- const n = findNode(t, this._root);
- return n && n.children.length > 0 ? n.children[0].value : null;
- }
- /**
- * \@internal
- * @param {?} t
- * @return {?}
- */
- siblings(t) {
- /** @type {?} */
- const p = findPath(t, this._root);
- if (p.length < 2)
- return [];
- /** @type {?} */
- const c = p[p.length - 2].children.map(c => c.value);
- return c.filter(cc => cc !== t);
- }
- /**
- * \@internal
- * @param {?} t
- * @return {?}
- */
- pathFromRoot(t) { return findPath(t, this._root).map(s => s.value); }
- }
- /**
- * @template T
- * @param {?} value
- * @param {?} node
- * @return {?}
- */
- function findNode(value, node) {
- if (value === node.value)
- return node;
- for (const child of node.children) {
- /** @type {?} */
- const node = findNode(value, child);
- if (node)
- return node;
- }
- return null;
- }
- /**
- * @template T
- * @param {?} value
- * @param {?} node
- * @return {?}
- */
- function findPath(value, node) {
- if (value === node.value)
- return [node];
- for (const child of node.children) {
- /** @type {?} */
- const path = findPath(value, child);
- if (path.length) {
- path.unshift(node);
- return path;
- }
- }
- return [];
- }
- /**
- * @template T
- */
- class TreeNode {
- /**
- * @param {?} value
- * @param {?} children
- */
- constructor(value, children) {
- this.value = value;
- this.children = children;
- }
- /**
- * @return {?}
- */
- toString() { return `TreeNode(${this.value})`; }
- }
- /**
- * @template T
- * @param {?} node
- * @return {?}
- */
- function nodeChildrenAsMap(node) {
- /** @type {?} */
- const map$$1 = {};
- if (node) {
- node.children.forEach(child => map$$1[child.value.outlet] = child);
- }
- return map$$1;
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /**
- * \@description
- *
- * Represents the state of the router.
- *
- * RouterState is a tree of activated routes. Every node in this tree knows about the "consumed" URL
- * segments, the extracted parameters, and the resolved data.
- *
- * \@usageNotes
- * ### Example
- *
- * ```
- * \@Component({templateUrl:'template.html'})
- * class MyComponent {
- * constructor(router: Router) {
- * const state: RouterState = router.routerState;
- * const root: ActivatedRoute = state.root;
- * const child = root.firstChild;
- * const id: Observable<string> = child.params.map(p => p.id);
- * //...
- * }
- * }
- * ```
- *
- * See `ActivatedRoute` for more information.
- *
- * \@publicApi
- */
- class RouterState extends Tree {
- /**
- * \@internal
- * @param {?} root
- * @param {?} snapshot
- */
- constructor(root, snapshot) {
- super(root);
- this.snapshot = snapshot;
- setRouterState(/** @type {?} */ (this), root);
- }
- /**
- * @return {?}
- */
- toString() { return this.snapshot.toString(); }
- }
- /**
- * @param {?} urlTree
- * @param {?} rootComponent
- * @return {?}
- */
- function createEmptyState(urlTree, rootComponent) {
- /** @type {?} */
- const snapshot = createEmptyStateSnapshot(urlTree, rootComponent);
- /** @type {?} */
- const emptyUrl = new BehaviorSubject([new UrlSegment('', {})]);
- /** @type {?} */
- const emptyParams = new BehaviorSubject({});
- /** @type {?} */
- const emptyData = new BehaviorSubject({});
- /** @type {?} */
- const emptyQueryParams = new BehaviorSubject({});
- /** @type {?} */
- const fragment = new BehaviorSubject('');
- /** @type {?} */
- const activated = new ActivatedRoute(emptyUrl, emptyParams, emptyQueryParams, fragment, emptyData, PRIMARY_OUTLET, rootComponent, snapshot.root);
- activated.snapshot = snapshot.root;
- return new RouterState(new TreeNode(activated, []), snapshot);
- }
- /**
- * @param {?} urlTree
- * @param {?} rootComponent
- * @return {?}
- */
- function createEmptyStateSnapshot(urlTree, rootComponent) {
- /** @type {?} */
- const emptyParams = {};
- /** @type {?} */
- const emptyData = {};
- /** @type {?} */
- const emptyQueryParams = {};
- /** @type {?} */
- const fragment = '';
- /** @type {?} */
- const activated = new ActivatedRouteSnapshot([], emptyParams, emptyQueryParams, fragment, emptyData, PRIMARY_OUTLET, rootComponent, null, urlTree.root, -1, {});
- return new RouterStateSnapshot('', new TreeNode(activated, []));
- }
- /**
- * \@description
- *
- * Contains the information about a route associated with a component loaded in an
- * outlet. An `ActivatedRoute` can also be used to traverse the router state tree.
- *
- * ```
- * \@Component({...})
- * class MyComponent {
- * constructor(route: ActivatedRoute) {
- * const id: Observable<string> = route.params.map(p => p.id);
- * const url: Observable<string> = route.url.map(segments => segments.join(''));
- * // route.data includes both `data` and `resolve`
- * const user = route.data.map(d => d.user);
- * }
- * }
- * ```
- *
- * \@publicApi
- */
- class ActivatedRoute {
- /**
- * \@internal
- * @param {?} url
- * @param {?} params
- * @param {?} queryParams
- * @param {?} fragment
- * @param {?} data
- * @param {?} outlet
- * @param {?} component
- * @param {?} futureSnapshot
- */
- constructor(url, params, queryParams, fragment, data, outlet, component, futureSnapshot) {
- this.url = url;
- this.params = params;
- this.queryParams = queryParams;
- this.fragment = fragment;
- this.data = data;
- this.outlet = outlet;
- this.component = component;
- this._futureSnapshot = futureSnapshot;
- }
- /**
- * The configuration used to match this route
- * @return {?}
- */
- get routeConfig() { return this._futureSnapshot.routeConfig; }
- /**
- * The root of the router state
- * @return {?}
- */
- get root() { return this._routerState.root; }
- /**
- * The parent of this route in the router state tree
- * @return {?}
- */
- get parent() { return this._routerState.parent(this); }
- /**
- * The first child of this route in the router state tree
- * @return {?}
- */
- get firstChild() { return this._routerState.firstChild(this); }
- /**
- * The children of this route in the router state tree
- * @return {?}
- */
- get children() { return this._routerState.children(this); }
- /**
- * The path from the root of the router state tree to this route
- * @return {?}
- */
- get pathFromRoot() { return this._routerState.pathFromRoot(this); }
- /**
- * @return {?}
- */
- get paramMap() {
- if (!this._paramMap) {
- this._paramMap = this.params.pipe(map((p) => convertToParamMap(p)));
- }
- return this._paramMap;
- }
- /**
- * @return {?}
- */
- get queryParamMap() {
- if (!this._queryParamMap) {
- this._queryParamMap =
- this.queryParams.pipe(map((p) => convertToParamMap(p)));
- }
- return this._queryParamMap;
- }
- /**
- * @return {?}
- */
- toString() {
- return this.snapshot ? this.snapshot.toString() : `Future(${this._futureSnapshot})`;
- }
- }
- /**
- * Returns the inherited params, data, and resolve for a given route.
- * By default, this only inherits values up to the nearest path-less or component-less route.
- * \@internal
- * @param {?} route
- * @param {?=} paramsInheritanceStrategy
- * @return {?}
- */
- function inheritedParamsDataResolve(route, paramsInheritanceStrategy = 'emptyOnly') {
- /** @type {?} */
- const pathFromRoot = route.pathFromRoot;
- /** @type {?} */
- let inheritingStartingFrom = 0;
- if (paramsInheritanceStrategy !== 'always') {
- inheritingStartingFrom = pathFromRoot.length - 1;
- while (inheritingStartingFrom >= 1) {
- /** @type {?} */
- const current = pathFromRoot[inheritingStartingFrom];
- /** @type {?} */
- const parent = pathFromRoot[inheritingStartingFrom - 1];
- // current route is an empty path => inherits its parent's params and data
- if (current.routeConfig && current.routeConfig.path === '') {
- inheritingStartingFrom--;
- // parent is componentless => current route should inherit its params and data
- }
- else if (!parent.component) {
- inheritingStartingFrom--;
- }
- else {
- break;
- }
- }
- }
- return flattenInherited(pathFromRoot.slice(inheritingStartingFrom));
- }
- /**
- * \@internal
- * @param {?} pathFromRoot
- * @return {?}
- */
- function flattenInherited(pathFromRoot) {
- return pathFromRoot.reduce((res, curr) => {
- /** @type {?} */
- const params = Object.assign({}, res.params, curr.params);
- /** @type {?} */
- const data = Object.assign({}, res.data, curr.data);
- /** @type {?} */
- const resolve = Object.assign({}, res.resolve, curr._resolvedData);
- return { params, data, resolve };
- }, /** @type {?} */ ({ params: {}, data: {}, resolve: {} }));
- }
- /**
- * \@description
- *
- * Contains the information about a route associated with a component loaded in an
- * outlet at a particular moment in time. ActivatedRouteSnapshot can also be used to
- * traverse the router state tree.
- *
- * ```
- * \@Component({templateUrl:'./my-component.html'})
- * class MyComponent {
- * constructor(route: ActivatedRoute) {
- * const id: string = route.snapshot.params.id;
- * const url: string = route.snapshot.url.join('');
- * const user = route.snapshot.data.user;
- * }
- * }
- * ```
- *
- * \@publicApi
- */
- class ActivatedRouteSnapshot {
- /**
- * \@internal
- * @param {?} url
- * @param {?} params
- * @param {?} queryParams
- * @param {?} fragment
- * @param {?} data
- * @param {?} outlet
- * @param {?} component
- * @param {?} routeConfig
- * @param {?} urlSegment
- * @param {?} lastPathIndex
- * @param {?} resolve
- */
- constructor(url, params, queryParams, fragment, data, outlet, component, routeConfig, urlSegment, lastPathIndex, resolve) {
- this.url = url;
- this.params = params;
- this.queryParams = queryParams;
- this.fragment = fragment;
- this.data = data;
- this.outlet = outlet;
- this.component = component;
- this.routeConfig = routeConfig;
- this._urlSegment = urlSegment;
- this._lastPathIndex = lastPathIndex;
- this._resolve = resolve;
- }
- /**
- * The root of the router state
- * @return {?}
- */
- get root() { return this._routerState.root; }
- /**
- * The parent of this route in the router state tree
- * @return {?}
- */
- get parent() { return this._routerState.parent(this); }
- /**
- * The first child of this route in the router state tree
- * @return {?}
- */
- get firstChild() { return this._routerState.firstChild(this); }
- /**
- * The children of this route in the router state tree
- * @return {?}
- */
- get children() { return this._routerState.children(this); }
- /**
- * The path from the root of the router state tree to this route
- * @return {?}
- */
- get pathFromRoot() { return this._routerState.pathFromRoot(this); }
- /**
- * @return {?}
- */
- get paramMap() {
- if (!this._paramMap) {
- this._paramMap = convertToParamMap(this.params);
- }
- return this._paramMap;
- }
- /**
- * @return {?}
- */
- get queryParamMap() {
- if (!this._queryParamMap) {
- this._queryParamMap = convertToParamMap(this.queryParams);
- }
- return this._queryParamMap;
- }
- /**
- * @return {?}
- */
- toString() {
- /** @type {?} */
- const url = this.url.map(segment => segment.toString()).join('/');
- /** @type {?} */
- const matched = this.routeConfig ? this.routeConfig.path : '';
- return `Route(url:'${url}', path:'${matched}')`;
- }
- }
- /**
- * \@description
- *
- * Represents the state of the router at a moment in time.
- *
- * This is a tree of activated route snapshots. Every node in this tree knows about
- * the "consumed" URL segments, the extracted parameters, and the resolved data.
- *
- * \@usageNotes
- * ### Example
- *
- * ```
- * \@Component({templateUrl:'template.html'})
- * class MyComponent {
- * constructor(router: Router) {
- * const state: RouterState = router.routerState;
- * const snapshot: RouterStateSnapshot = state.snapshot;
- * const root: ActivatedRouteSnapshot = snapshot.root;
- * const child = root.firstChild;
- * const id: Observable<string> = child.params.map(p => p.id);
- * //...
- * }
- * }
- * ```
- *
- * \@publicApi
- */
- class RouterStateSnapshot extends Tree {
- /**
- * \@internal
- * @param {?} url
- * @param {?} root
- */
- constructor(url, root) {
- super(root);
- this.url = url;
- setRouterState(/** @type {?} */ (this), root);
- }
- /**
- * @return {?}
- */
- toString() { return serializeNode(this._root); }
- }
- /**
- * @template U, T
- * @param {?} state
- * @param {?} node
- * @return {?}
- */
- function setRouterState(state, node) {
- node.value._routerState = state;
- node.children.forEach(c => setRouterState(state, c));
- }
- /**
- * @param {?} node
- * @return {?}
- */
- function serializeNode(node) {
- /** @type {?} */
- const c = node.children.length > 0 ? ` { ${node.children.map(serializeNode).join(', ')} } ` : '';
- return `${node.value}${c}`;
- }
- /**
- * The expectation is that the activate route is created with the right set of parameters.
- * So we push new values into the observables only when they are not the initial values.
- * And we detect that by checking if the snapshot field is set.
- * @param {?} route
- * @return {?}
- */
- function advanceActivatedRoute(route) {
- if (route.snapshot) {
- /** @type {?} */
- const currentSnapshot = route.snapshot;
- /** @type {?} */
- const nextSnapshot = route._futureSnapshot;
- route.snapshot = nextSnapshot;
- if (!shallowEqual(currentSnapshot.queryParams, nextSnapshot.queryParams)) {
- (/** @type {?} */ (route.queryParams)).next(nextSnapshot.queryParams);
- }
- if (currentSnapshot.fragment !== nextSnapshot.fragment) {
- (/** @type {?} */ (route.fragment)).next(nextSnapshot.fragment);
- }
- if (!shallowEqual(currentSnapshot.params, nextSnapshot.params)) {
- (/** @type {?} */ (route.params)).next(nextSnapshot.params);
- }
- if (!shallowEqualArrays(currentSnapshot.url, nextSnapshot.url)) {
- (/** @type {?} */ (route.url)).next(nextSnapshot.url);
- }
- if (!shallowEqual(currentSnapshot.data, nextSnapshot.data)) {
- (/** @type {?} */ (route.data)).next(nextSnapshot.data);
- }
- }
- else {
- route.snapshot = route._futureSnapshot;
- // this is for resolved data
- (/** @type {?} */ (route.data)).next(route._futureSnapshot.data);
- }
- }
- /**
- * @param {?} a
- * @param {?} b
- * @return {?}
- */
- function equalParamsAndUrlSegments(a, b) {
- /** @type {?} */
- const equalUrlParams = shallowEqual(a.params, b.params) && equalSegments(a.url, b.url);
- /** @type {?} */
- const parentsMismatch = !a.parent !== !b.parent;
- return equalUrlParams && !parentsMismatch &&
- (!a.parent || equalParamsAndUrlSegments(a.parent, /** @type {?} */ ((b.parent))));
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /**
- * @param {?} routeReuseStrategy
- * @param {?} curr
- * @param {?} prevState
- * @return {?}
- */
- function createRouterState(routeReuseStrategy, curr, prevState) {
- /** @type {?} */
- const root = createNode(routeReuseStrategy, curr._root, prevState ? prevState._root : undefined);
- return new RouterState(root, curr);
- }
- /**
- * @param {?} routeReuseStrategy
- * @param {?} curr
- * @param {?=} prevState
- * @return {?}
- */
- function createNode(routeReuseStrategy, curr, prevState) {
- // reuse an activated route that is currently displayed on the screen
- if (prevState && routeReuseStrategy.shouldReuseRoute(curr.value, prevState.value.snapshot)) {
- /** @type {?} */
- const value = prevState.value;
- value._futureSnapshot = curr.value;
- /** @type {?} */
- const children = createOrReuseChildren(routeReuseStrategy, curr, prevState);
- return new TreeNode(value, children);
- // retrieve an activated route that is used to be displayed, but is not currently displayed
- }
- else {
- /** @type {?} */
- const detachedRouteHandle = /** @type {?} */ (routeReuseStrategy.retrieve(curr.value));
- if (detachedRouteHandle) {
- /** @type {?} */
- const tree = detachedRouteHandle.route;
- setFutureSnapshotsOfActivatedRoutes(curr, tree);
- return tree;
- }
- else {
- /** @type {?} */
- const value = createActivatedRoute(curr.value);
- /** @type {?} */
- const children = curr.children.map(c => createNode(routeReuseStrategy, c));
- return new TreeNode(value, children);
- }
- }
- }
- /**
- * @param {?} curr
- * @param {?} result
- * @return {?}
- */
- function setFutureSnapshotsOfActivatedRoutes(curr, result) {
- if (curr.value.routeConfig !== result.value.routeConfig) {
- throw new Error('Cannot reattach ActivatedRouteSnapshot created from a different route');
- }
- if (curr.children.length !== result.children.length) {
- throw new Error('Cannot reattach ActivatedRouteSnapshot with a different number of children');
- }
- result.value._futureSnapshot = curr.value;
- for (let i = 0; i < curr.children.length; ++i) {
- setFutureSnapshotsOfActivatedRoutes(curr.children[i], result.children[i]);
- }
- }
- /**
- * @param {?} routeReuseStrategy
- * @param {?} curr
- * @param {?} prevState
- * @return {?}
- */
- function createOrReuseChildren(routeReuseStrategy, curr, prevState) {
- return curr.children.map(child => {
- for (const p of prevState.children) {
- if (routeReuseStrategy.shouldReuseRoute(p.value.snapshot, child.value)) {
- return createNode(routeReuseStrategy, child, p);
- }
- }
- return createNode(routeReuseStrategy, child);
- });
- }
- /**
- * @param {?} c
- * @return {?}
- */
- function createActivatedRoute(c) {
- 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);
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /**
- * @param {?} route
- * @param {?} urlTree
- * @param {?} commands
- * @param {?} queryParams
- * @param {?} fragment
- * @return {?}
- */
- function createUrlTree(route, urlTree, commands, queryParams, fragment) {
- if (commands.length === 0) {
- return tree(urlTree.root, urlTree.root, urlTree, queryParams, fragment);
- }
- /** @type {?} */
- const nav = computeNavigation(commands);
- if (nav.toRoot()) {
- return tree(urlTree.root, new UrlSegmentGroup([], {}), urlTree, queryParams, fragment);
- }
- /** @type {?} */
- const startingPosition = findStartingPosition(nav, urlTree, route);
- /** @type {?} */
- const segmentGroup = startingPosition.processChildren ?
- updateSegmentGroupChildren(startingPosition.segmentGroup, startingPosition.index, nav.commands) :
- updateSegmentGroup(startingPosition.segmentGroup, startingPosition.index, nav.commands);
- return tree(startingPosition.segmentGroup, segmentGroup, urlTree, queryParams, fragment);
- }
- /**
- * @param {?} command
- * @return {?}
- */
- function isMatrixParams(command) {
- return typeof command === 'object' && command != null && !command.outlets && !command.segmentPath;
- }
- /**
- * @param {?} oldSegmentGroup
- * @param {?} newSegmentGroup
- * @param {?} urlTree
- * @param {?} queryParams
- * @param {?} fragment
- * @return {?}
- */
- function tree(oldSegmentGroup, newSegmentGroup, urlTree, queryParams, fragment) {
- /** @type {?} */
- let qp = {};
- if (queryParams) {
- forEach(queryParams, (value, name) => {
- qp[name] = Array.isArray(value) ? value.map((v) => `${v}`) : `${value}`;
- });
- }
- if (urlTree.root === oldSegmentGroup) {
- return new UrlTree(newSegmentGroup, qp, fragment);
- }
- return new UrlTree(replaceSegment(urlTree.root, oldSegmentGroup, newSegmentGroup), qp, fragment);
- }
- /**
- * @param {?} current
- * @param {?} oldSegment
- * @param {?} newSegment
- * @return {?}
- */
- function replaceSegment(current, oldSegment, newSegment) {
- /** @type {?} */
- const children = {};
- forEach(current.children, (c, outletName) => {
- if (c === oldSegment) {
- children[outletName] = newSegment;
- }
- else {
- children[outletName] = replaceSegment(c, oldSegment, newSegment);
- }
- });
- return new UrlSegmentGroup(current.segments, children);
- }
- class Navigation {
- /**
- * @param {?} isAbsolute
- * @param {?} numberOfDoubleDots
- * @param {?} commands
- */
- constructor(isAbsolute, numberOfDoubleDots, commands) {
- this.isAbsolute = isAbsolute;
- this.numberOfDoubleDots = numberOfDoubleDots;
- this.commands = commands;
- if (isAbsolute && commands.length > 0 && isMatrixParams(commands[0])) {
- throw new Error('Root segment cannot have matrix parameters');
- }
- /** @type {?} */
- const cmdWithOutlet = commands.find(c => typeof c === 'object' && c != null && c.outlets);
- if (cmdWithOutlet && cmdWithOutlet !== last$1(commands)) {
- throw new Error('{outlets:{}} has to be the last command');
- }
- }
- /**
- * @return {?}
- */
- toRoot() {
- return this.isAbsolute && this.commands.length === 1 && this.commands[0] == '/';
- }
- }
- /**
- * Transforms commands to a normalized `Navigation`
- * @param {?} commands
- * @return {?}
- */
- function computeNavigation(commands) {
- if ((typeof commands[0] === 'string') && commands.length === 1 && commands[0] === '/') {
- return new Navigation(true, 0, commands);
- }
- /** @type {?} */
- let numberOfDoubleDots = 0;
- /** @type {?} */
- let isAbsolute = false;
- /** @type {?} */
- const res = commands.reduce((res, cmd, cmdIdx) => {
- if (typeof cmd === 'object' && cmd != null) {
- if (cmd.outlets) {
- /** @type {?} */
- const outlets = {};
- forEach(cmd.outlets, (commands, name) => {
- outlets[name] = typeof commands === 'string' ? commands.split('/') : commands;
- });
- return [...res, { outlets }];
- }
- if (cmd.segmentPath) {
- return [...res, cmd.segmentPath];
- }
- }
- if (!(typeof cmd === 'string')) {
- return [...res, cmd];
- }
- if (cmdIdx === 0) {
- cmd.split('/').forEach((urlPart, partIndex) => {
- if (partIndex == 0 && urlPart === '.') ;
- else if (partIndex == 0 && urlPart === '') { // '/a'
- // '/a'
- isAbsolute = true;
- }
- else if (urlPart === '..') { // '../a'
- // '../a'
- numberOfDoubleDots++;
- }
- else if (urlPart != '') {
- res.push(urlPart);
- }
- });
- return res;
- }
- return [...res, cmd];
- }, []);
- return new Navigation(isAbsolute, numberOfDoubleDots, res);
- }
- class Position {
- /**
- * @param {?} segmentGroup
- * @param {?} processChildren
- * @param {?} index
- */
- constructor(segmentGroup, processChildren, index) {
- this.segmentGroup = segmentGroup;
- this.processChildren = processChildren;
- this.index = index;
- }
- }
- /**
- * @param {?} nav
- * @param {?} tree
- * @param {?} route
- * @return {?}
- */
- function findStartingPosition(nav, tree, route) {
- if (nav.isAbsolute) {
- return new Position(tree.root, true, 0);
- }
- if (route.snapshot._lastPathIndex === -1) {
- return new Position(route.snapshot._urlSegment, true, 0);
- }
- /** @type {?} */
- const modifier = isMatrixParams(nav.commands[0]) ? 0 : 1;
- /** @type {?} */
- const index = route.snapshot._lastPathIndex + modifier;
- return createPositionApplyingDoubleDots(route.snapshot._urlSegment, index, nav.numberOfDoubleDots);
- }
- /**
- * @param {?} group
- * @param {?} index
- * @param {?} numberOfDoubleDots
- * @return {?}
- */
- function createPositionApplyingDoubleDots(group, index, numberOfDoubleDots) {
- /** @type {?} */
- let g = group;
- /** @type {?} */
- let ci = index;
- /** @type {?} */
- let dd = numberOfDoubleDots;
- while (dd > ci) {
- dd -= ci;
- g = /** @type {?} */ ((g.parent));
- if (!g) {
- throw new Error('Invalid number of \'../\'');
- }
- ci = g.segments.length;
- }
- return new Position(g, false, ci - dd);
- }
- /**
- * @param {?} command
- * @return {?}
- */
- function getPath(command) {
- if (typeof command === 'object' && command != null && command.outlets) {
- return command.outlets[PRIMARY_OUTLET];
- }
- return `${command}`;
- }
- /**
- * @param {?} commands
- * @return {?}
- */
- function getOutlets(commands) {
- if (!(typeof commands[0] === 'object'))
- return { [PRIMARY_OUTLET]: commands };
- if (commands[0].outlets === undefined)
- return { [PRIMARY_OUTLET]: commands };
- return commands[0].outlets;
- }
- /**
- * @param {?} segmentGroup
- * @param {?} startIndex
- * @param {?} commands
- * @return {?}
- */
- function updateSegmentGroup(segmentGroup, startIndex, commands) {
- if (!segmentGroup) {
- segmentGroup = new UrlSegmentGroup([], {});
- }
- if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
- return updateSegmentGroupChildren(segmentGroup, startIndex, commands);
- }
- /** @type {?} */
- const m = prefixedWith(segmentGroup, startIndex, commands);
- /** @type {?} */
- const slicedCommands = commands.slice(m.commandIndex);
- if (m.match && m.pathIndex < segmentGroup.segments.length) {
- /** @type {?} */
- const g = new UrlSegmentGroup(segmentGroup.segments.slice(0, m.pathIndex), {});
- g.children[PRIMARY_OUTLET] =
- new UrlSegmentGroup(segmentGroup.segments.slice(m.pathIndex), segmentGroup.children);
- return updateSegmentGroupChildren(g, 0, slicedCommands);
- }
- else if (m.match && slicedCommands.length === 0) {
- return new UrlSegmentGroup(segmentGroup.segments, {});
- }
- else if (m.match && !segmentGroup.hasChildren()) {
- return createNewSegmentGroup(segmentGroup, startIndex, commands);
- }
- else if (m.match) {
- return updateSegmentGroupChildren(segmentGroup, 0, slicedCommands);
- }
- else {
- return createNewSegmentGroup(segmentGroup, startIndex, commands);
- }
- }
- /**
- * @param {?} segmentGroup
- * @param {?} startIndex
- * @param {?} commands
- * @return {?}
- */
- function updateSegmentGroupChildren(segmentGroup, startIndex, commands) {
- if (commands.length === 0) {
- return new UrlSegmentGroup(segmentGroup.segments, {});
- }
- else {
- /** @type {?} */
- const outlets = getOutlets(commands);
- /** @type {?} */
- const children = {};
- forEach(outlets, (commands, outlet) => {
- if (commands !== null) {
- children[outlet] = updateSegmentGroup(segmentGroup.children[outlet], startIndex, commands);
- }
- });
- forEach(segmentGroup.children, (child, childOutlet) => {
- if (outlets[childOutlet] === undefined) {
- children[childOutlet] = child;
- }
- });
- return new UrlSegmentGroup(segmentGroup.segments, children);
- }
- }
- /**
- * @param {?} segmentGroup
- * @param {?} startIndex
- * @param {?} commands
- * @return {?}
- */
- function prefixedWith(segmentGroup, startIndex, commands) {
- /** @type {?} */
- let currentCommandIndex = 0;
- /** @type {?} */
- let currentPathIndex = startIndex;
- /** @type {?} */
- const noMatch = { match: false, pathIndex: 0, commandIndex: 0 };
- while (currentPathIndex < segmentGroup.segments.length) {
- if (currentCommandIndex >= commands.length)
- return noMatch;
- /** @type {?} */
- const path = segmentGroup.segments[currentPathIndex];
- /** @type {?} */
- const curr = getPath(commands[currentCommandIndex]);
- /** @type {?} */
- const next = currentCommandIndex < commands.length - 1 ? commands[currentCommandIndex + 1] : null;
- if (currentPathIndex > 0 && curr === undefined)
- break;
- if (curr && next && (typeof next === 'object') && next.outlets === undefined) {
- if (!compare(curr, next, path))
- return noMatch;
- currentCommandIndex += 2;
- }
- else {
- if (!compare(curr, {}, path))
- return noMatch;
- currentCommandIndex++;
- }
- currentPathIndex++;
- }
- return { match: true, pathIndex: currentPathIndex, commandIndex: currentCommandIndex };
- }
- /**
- * @param {?} segmentGroup
- * @param {?} startIndex
- * @param {?} commands
- * @return {?}
- */
- function createNewSegmentGroup(segmentGroup, startIndex, commands) {
- /** @type {?} */
- const paths = segmentGroup.segments.slice(0, startIndex);
- /** @type {?} */
- let i = 0;
- while (i < commands.length) {
- if (typeof commands[i] === 'object' && commands[i].outlets !== undefined) {
- /** @type {?} */
- const children = createNewSegmentChildren(commands[i].outlets);
- return new UrlSegmentGroup(paths, children);
- }
- // if we start with an object literal, we need to reuse the path part from the segment
- if (i === 0 && isMatrixParams(commands[0])) {
- /** @type {?} */
- const p = segmentGroup.segments[startIndex];
- paths.push(new UrlSegment(p.path, commands[0]));
- i++;
- continue;
- }
- /** @type {?} */
- const curr = getPath(commands[i]);
- /** @type {?} */
- const next = (i < commands.length - 1) ? commands[i + 1] : null;
- if (curr && next && isMatrixParams(next)) {
- paths.push(new UrlSegment(curr, stringify(next)));
- i += 2;
- }
- else {
- paths.push(new UrlSegment(curr, {}));
- i++;
- }
- }
- return new UrlSegmentGroup(paths, {});
- }
- /**
- * @param {?} outlets
- * @return {?}
- */
- function createNewSegmentChildren(outlets) {
- /** @type {?} */
- const children = {};
- forEach(outlets, (commands, outlet) => {
- if (commands !== null) {
- children[outlet] = createNewSegmentGroup(new UrlSegmentGroup([], {}), 0, commands);
- }
- });
- return children;
- }
- /**
- * @param {?} params
- * @return {?}
- */
- function stringify(params) {
- /** @type {?} */
- const res = {};
- forEach(params, (v, k) => res[k] = `${v}`);
- return res;
- }
- /**
- * @param {?} path
- * @param {?} params
- * @param {?} segment
- * @return {?}
- */
- function compare(path, params, segment) {
- return path == segment.path && shallowEqual(params, segment.parameters);
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /** @type {?} */
- const activateRoutes = (rootContexts, routeReuseStrategy, forwardEvent) => map(t => {
- new ActivateRoutes(routeReuseStrategy, /** @type {?} */ ((t.targetRouterState)), t.currentRouterState, forwardEvent)
- .activate(rootContexts);
- return t;
- });
- class ActivateRoutes {
- /**
- * @param {?} routeReuseStrategy
- * @param {?} futureState
- * @param {?} currState
- * @param {?} forwardEvent
- */
- constructor(routeReuseStrategy, futureState, currState, forwardEvent) {
- this.routeReuseStrategy = routeReuseStrategy;
- this.futureState = futureState;
- this.currState = currState;
- this.forwardEvent = forwardEvent;
- }
- /**
- * @param {?} parentContexts
- * @return {?}
- */
- activate(parentContexts) {
- /** @type {?} */
- const futureRoot = this.futureState._root;
- /** @type {?} */
- const currRoot = this.currState ? this.currState._root : null;
- this.deactivateChildRoutes(futureRoot, currRoot, parentContexts);
- advanceActivatedRoute(this.futureState.root);
- this.activateChildRoutes(futureRoot, currRoot, parentContexts);
- }
- /**
- * @param {?} futureNode
- * @param {?} currNode
- * @param {?} contexts
- * @return {?}
- */
- deactivateChildRoutes(futureNode, currNode, contexts) {
- /** @type {?} */
- const children = nodeChildrenAsMap(currNode);
- // Recurse on the routes active in the future state to de-activate deeper children
- futureNode.children.forEach(futureChild => {
- /** @type {?} */
- const childOutletName = futureChild.value.outlet;
- this.deactivateRoutes(futureChild, children[childOutletName], contexts);
- delete children[childOutletName];
- });
- // De-activate the routes that will not be re-used
- forEach(children, (v, childName) => {
- this.deactivateRouteAndItsChildren(v, contexts);
- });
- }
- /**
- * @param {?} futureNode
- * @param {?} currNode
- * @param {?} parentContext
- * @return {?}
- */
- deactivateRoutes(futureNode, currNode, parentContext) {
- /** @type {?} */
- const future = futureNode.value;
- /** @type {?} */
- const curr = currNode ? currNode.value : null;
- if (future === curr) {
- // Reusing the node, check to see if the children need to be de-activated
- if (future.component) {
- /** @type {?} */
- const context = parentContext.getContext(future.outlet);
- if (context) {
- this.deactivateChildRoutes(futureNode, currNode, context.children);
- }
- }
- else {
- // if we have a componentless route, we recurse but keep the same outlet map.
- this.deactivateChildRoutes(futureNode, currNode, parentContext);
- }
- }
- else {
- if (curr) {
- // Deactivate the current route which will not be re-used
- this.deactivateRouteAndItsChildren(currNode, parentContext);
- }
- }
- }
- /**
- * @param {?} route
- * @param {?} parentContexts
- * @return {?}
- */
- deactivateRouteAndItsChildren(route, parentContexts) {
- if (this.routeReuseStrategy.shouldDetach(route.value.snapshot)) {
- this.detachAndStoreRouteSubtree(route, parentContexts);
- }
- else {
- this.deactivateRouteAndOutlet(route, parentContexts);
- }
- }
- /**
- * @param {?} route
- * @param {?} parentContexts
- * @return {?}
- */
- detachAndStoreRouteSubtree(route, parentContexts) {
- /** @type {?} */
- const context = parentContexts.getContext(route.value.outlet);
- if (context && context.outlet) {
- /** @type {?} */
- const componentRef = context.outlet.detach();
- /** @type {?} */
- const contexts = context.children.onOutletDeactivated();
- this.routeReuseStrategy.store(route.value.snapshot, { componentRef, route, contexts });
- }
- }
- /**
- * @param {?} route
- * @param {?} parentContexts
- * @return {?}
- */
- deactivateRouteAndOutlet(route, parentContexts) {
- /** @type {?} */
- const context = parentContexts.getContext(route.value.outlet);
- if (context) {
- /** @type {?} */
- const children = nodeChildrenAsMap(route);
- /** @type {?} */
- const contexts = route.value.component ? context.children : parentContexts;
- forEach(children, (v, k) => this.deactivateRouteAndItsChildren(v, contexts));
- if (context.outlet) {
- // Destroy the component
- context.outlet.deactivate();
- // Destroy the contexts for all the outlets that were in the component
- context.children.onOutletDeactivated();
- }
- }
- }
- /**
- * @param {?} futureNode
- * @param {?} currNode
- * @param {?} contexts
- * @return {?}
- */
- activateChildRoutes(futureNode, currNode, contexts) {
- /** @type {?} */
- const children = nodeChildrenAsMap(currNode);
- futureNode.children.forEach(c => {
- this.activateRoutes(c, children[c.value.outlet], contexts);
- this.forwardEvent(new ActivationEnd(c.value.snapshot));
- });
- if (futureNode.children.length) {
- this.forwardEvent(new ChildActivationEnd(futureNode.value.snapshot));
- }
- }
- /**
- * @param {?} futureNode
- * @param {?} currNode
- * @param {?} parentContexts
- * @return {?}
- */
- activateRoutes(futureNode, currNode, parentContexts) {
- /** @type {?} */
- const future = futureNode.value;
- /** @type {?} */
- const curr = currNode ? currNode.value : null;
- advanceActivatedRoute(future);
- // reusing the node
- if (future === curr) {
- if (future.component) {
- /** @type {?} */
- const context = parentContexts.getOrCreateContext(future.outlet);
- this.activateChildRoutes(futureNode, currNode, context.children);
- }
- else {
- // if we have a componentless route, we recurse but keep the same outlet map.
- this.activateChildRoutes(futureNode, currNode, parentContexts);
- }
- }
- else {
- if (future.component) {
- /** @type {?} */
- const context = parentContexts.getOrCreateContext(future.outlet);
- if (this.routeReuseStrategy.shouldAttach(future.snapshot)) {
- /** @type {?} */
- const stored = (/** @type {?} */ (this.routeReuseStrategy.retrieve(future.snapshot)));
- this.routeReuseStrategy.store(future.snapshot, null);
- context.children.onOutletReAttached(stored.contexts);
- context.attachRef = stored.componentRef;
- context.route = stored.route.value;
- if (context.outlet) {
- // Attach right away when the outlet has already been instantiated
- // Otherwise attach from `RouterOutlet.ngOnInit` when it is instantiated
- context.outlet.attach(stored.componentRef, stored.route.value);
- }
- if(context.children.contexts != null && context.children.contexts.size > 0){
- this.activateChildRoutes(futureNode, null, context.children);
- advanceActivatedRoute(stored.route.value);
- }else{
- advanceActivatedRouteNodeAndItsChildren(stored.route);
- }
- }
- else {
- /** @type {?} */
- const config = parentLoadedConfig(future.snapshot);
- /** @type {?} */
- const cmpFactoryResolver = config ? config.module.componentFactoryResolver : null;
- context.attachRef = null;
- context.route = future;
- context.resolver = cmpFactoryResolver;
- if (context.outlet) {
- // Activate the outlet when it has already been instantiated
- // Otherwise it will get activated from its `ngOnInit` when instantiated
- context.outlet.activateWith(future, cmpFactoryResolver);
- }
- this.activateChildRoutes(futureNode, null, context.children);
- }
- }
- else {
- // if we have a componentless route, we recurse but keep the same outlet map.
- this.activateChildRoutes(futureNode, null, parentContexts);
- }
- }
- }
- }
- /**
- * @param {?} node
- * @return {?}
- */
- function advanceActivatedRouteNodeAndItsChildren(node) {
- advanceActivatedRoute(node.value);
- node.children.forEach(advanceActivatedRouteNodeAndItsChildren);
- }
- /**
- * @param {?} snapshot
- * @return {?}
- */
- function parentLoadedConfig(snapshot) {
- for (let s = snapshot.parent; s; s = s.parent) {
- /** @type {?} */
- const route = s.routeConfig;
- if (route && route._loadedConfig)
- return route._loadedConfig;
- if (route && route.component)
- return null;
- }
- return null;
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- class NoMatch {
- /**
- * @param {?=} segmentGroup
- */
- constructor(segmentGroup) { this.segmentGroup = segmentGroup || null; }
- }
- class AbsoluteRedirect {
- /**
- * @param {?} urlTree
- */
- constructor(urlTree) {
- this.urlTree = urlTree;
- }
- }
- /**
- * @param {?} segmentGroup
- * @return {?}
- */
- function noMatch(segmentGroup) {
- return new Observable((obs) => obs.error(new NoMatch(segmentGroup)));
- }
- /**
- * @param {?} newTree
- * @return {?}
- */
- function absoluteRedirect(newTree) {
- return new Observable((obs) => obs.error(new AbsoluteRedirect(newTree)));
- }
- /**
- * @param {?} redirectTo
- * @return {?}
- */
- function namedOutletsRedirect(redirectTo) {
- return new Observable((obs) => obs.error(new Error(`Only absolute redirects can have named outlets. redirectTo: '${redirectTo}'`)));
- }
- /**
- * @param {?} route
- * @return {?}
- */
- function canLoadFails(route) {
- return new Observable((obs) => obs.error(navigationCancelingError(`Cannot load children because the guard of the route "path: '${route.path}'" returned false`)));
- }
- /**
- * Returns the `UrlTree` with the redirection applied.
- *
- * Lazy modules are loaded along the way.
- * @param {?} moduleInjector
- * @param {?} configLoader
- * @param {?} urlSerializer
- * @param {?} urlTree
- * @param {?} config
- * @return {?}
- */
- function applyRedirects(moduleInjector, configLoader, urlSerializer, urlTree, config) {
- return new ApplyRedirects(moduleInjector, configLoader, urlSerializer, urlTree, config).apply();
- }
- class ApplyRedirects {
- /**
- * @param {?} moduleInjector
- * @param {?} configLoader
- * @param {?} urlSerializer
- * @param {?} urlTree
- * @param {?} config
- */
- constructor(moduleInjector, configLoader, urlSerializer, urlTree, config) {
- this.configLoader = configLoader;
- this.urlSerializer = urlSerializer;
- this.urlTree = urlTree;
- this.config = config;
- this.allowRedirects = true;
- this.ngModule = moduleInjector.get(NgModuleRef);
- }
- /**
- * @return {?}
- */
- apply() {
- /** @type {?} */
- const expanded$ = this.expandSegmentGroup(this.ngModule, this.config, this.urlTree.root, PRIMARY_OUTLET);
- /** @type {?} */
- const urlTrees$ = expanded$.pipe(map((rootSegmentGroup) => this.createUrlTree(rootSegmentGroup, this.urlTree.queryParams, /** @type {?} */ ((this.urlTree.fragment)))));
- return urlTrees$.pipe(catchError((e) => {
- if (e instanceof AbsoluteRedirect) {
- // after an absolute redirect we do not apply any more redirects!
- this.allowRedirects = false;
- // we need to run matching, so we can fetch all lazy-loaded modules
- return this.match(e.urlTree);
- }
- if (e instanceof NoMatch) {
- throw this.noMatchError(e);
- }
- throw e;
- }));
- }
- /**
- * @param {?} tree
- * @return {?}
- */
- match(tree) {
- /** @type {?} */
- const expanded$ = this.expandSegmentGroup(this.ngModule, this.config, tree.root, PRIMARY_OUTLET);
- /** @type {?} */
- const mapped$ = expanded$.pipe(map((rootSegmentGroup) => this.createUrlTree(rootSegmentGroup, tree.queryParams, /** @type {?} */ ((tree.fragment)))));
- return mapped$.pipe(catchError((e) => {
- if (e instanceof NoMatch) {
- throw this.noMatchError(e);
- }
- throw e;
- }));
- }
- /**
- * @param {?} e
- * @return {?}
- */
- noMatchError(e) {
- return new Error(`Cannot match any routes. URL Segment: '${e.segmentGroup}'`);
- }
- /**
- * @param {?} rootCandidate
- * @param {?} queryParams
- * @param {?} fragment
- * @return {?}
- */
- createUrlTree(rootCandidate, queryParams, fragment) {
- /** @type {?} */
- const root = rootCandidate.segments.length > 0 ?
- new UrlSegmentGroup([], { [PRIMARY_OUTLET]: rootCandidate }) :
- rootCandidate;
- return new UrlTree(root, queryParams, fragment);
- }
- /**
- * @param {?} ngModule
- * @param {?} routes
- * @param {?} segmentGroup
- * @param {?} outlet
- * @return {?}
- */
- expandSegmentGroup(ngModule, routes, segmentGroup, outlet) {
- if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
- return this.expandChildren(ngModule, routes, segmentGroup)
- .pipe(map((children) => new UrlSegmentGroup([], children)));
- }
- return this.expandSegment(ngModule, segmentGroup, routes, segmentGroup.segments, outlet, true);
- }
- /**
- * @param {?} ngModule
- * @param {?} routes
- * @param {?} segmentGroup
- * @return {?}
- */
- expandChildren(ngModule, routes, segmentGroup) {
- return waitForMap(segmentGroup.children, (childOutlet, child) => this.expandSegmentGroup(ngModule, routes, child, childOutlet));
- }
- /**
- * @param {?} ngModule
- * @param {?} segmentGroup
- * @param {?} routes
- * @param {?} segments
- * @param {?} outlet
- * @param {?} allowRedirects
- * @return {?}
- */
- expandSegment(ngModule, segmentGroup, routes, segments, outlet, allowRedirects) {
- return of(...routes).pipe(map((r) => {
- /** @type {?} */
- const expanded$ = this.expandSegmentAgainstRoute(ngModule, segmentGroup, routes, r, segments, outlet, allowRedirects);
- return expanded$.pipe(catchError((e) => {
- if (e instanceof NoMatch) {
- // TODO(i): this return type doesn't match the declared Observable<UrlSegmentGroup> -
- // talk to Jason
- return /** @type {?} */ (of(null));
- }
- throw e;
- }));
- }), concatAll(), first((s) => !!s), catchError((e, _) => {
- if (e instanceof EmptyError || e.name === 'EmptyError') {
- if (this.noLeftoversInUrl(segmentGroup, segments, outlet)) {
- return of(new UrlSegmentGroup([], {}));
- }
- throw new NoMatch(segmentGroup);
- }
- throw e;
- }));
- }
- /**
- * @param {?} segmentGroup
- * @param {?} segments
- * @param {?} outlet
- * @return {?}
- */
- noLeftoversInUrl(segmentGroup, segments, outlet) {
- return segments.length === 0 && !segmentGroup.children[outlet];
- }
- /**
- * @param {?} ngModule
- * @param {?} segmentGroup
- * @param {?} routes
- * @param {?} route
- * @param {?} paths
- * @param {?} outlet
- * @param {?} allowRedirects
- * @return {?}
- */
- expandSegmentAgainstRoute(ngModule, segmentGroup, routes, route, paths, outlet, allowRedirects) {
- if (getOutlet(route) !== outlet) {
- return noMatch(segmentGroup);
- }
- if (route.redirectTo === undefined) {
- return this.matchSegmentAgainstRoute(ngModule, segmentGroup, route, paths);
- }
- if (allowRedirects && this.allowRedirects) {
- return this.expandSegmentAgainstRouteUsingRedirect(ngModule, segmentGroup, routes, route, paths, outlet);
- }
- return noMatch(segmentGroup);
- }
- /**
- * @param {?} ngModule
- * @param {?} segmentGroup
- * @param {?} routes
- * @param {?} route
- * @param {?} segments
- * @param {?} outlet
- * @return {?}
- */
- expandSegmentAgainstRouteUsingRedirect(ngModule, segmentGroup, routes, route, segments, outlet) {
- if (route.path === '**') {
- return this.expandWildCardWithParamsAgainstRouteUsingRedirect(ngModule, routes, route, outlet);
- }
- return this.expandRegularSegmentAgainstRouteUsingRedirect(ngModule, segmentGroup, routes, route, segments, outlet);
- }
- /**
- * @param {?} ngModule
- * @param {?} routes
- * @param {?} route
- * @param {?} outlet
- * @return {?}
- */
- expandWildCardWithParamsAgainstRouteUsingRedirect(ngModule, routes, route, outlet) {
- /** @type {?} */
- const newTree = this.applyRedirectCommands([], /** @type {?} */ ((route.redirectTo)), {});
- if (/** @type {?} */ ((route.redirectTo)).startsWith('/')) {
- return absoluteRedirect(newTree);
- }
- return this.lineralizeSegments(route, newTree).pipe(mergeMap((newSegments) => {
- /** @type {?} */
- const group = new UrlSegmentGroup(newSegments, {});
- return this.expandSegment(ngModule, group, routes, newSegments, outlet, false);
- }));
- }
- /**
- * @param {?} ngModule
- * @param {?} segmentGroup
- * @param {?} routes
- * @param {?} route
- * @param {?} segments
- * @param {?} outlet
- * @return {?}
- */
- expandRegularSegmentAgainstRouteUsingRedirect(ngModule, segmentGroup, routes, route, segments, outlet) {
- const { matched, consumedSegments, lastChild, positionalParamSegments } = match(segmentGroup, route, segments);
- if (!matched)
- return noMatch(segmentGroup);
- /** @type {?} */
- const newTree = this.applyRedirectCommands(consumedSegments, /** @type {?} */ ((route.redirectTo)), /** @type {?} */ (positionalParamSegments));
- if (/** @type {?} */ ((route.redirectTo)).startsWith('/')) {
- return absoluteRedirect(newTree);
- }
- return this.lineralizeSegments(route, newTree).pipe(mergeMap((newSegments) => {
- return this.expandSegment(ngModule, segmentGroup, routes, newSegments.concat(segments.slice(lastChild)), outlet, false);
- }));
- }
- /**
- * @param {?} ngModule
- * @param {?} rawSegmentGroup
- * @param {?} route
- * @param {?} segments
- * @return {?}
- */
- matchSegmentAgainstRoute(ngModule, rawSegmentGroup, route, segments) {
- if (route.path === '**') {
- if (route.loadChildren) {
- return this.configLoader.load(ngModule.injector, route)
- .pipe(map((cfg) => {
- route._loadedConfig = cfg;
- return new UrlSegmentGroup(segments, {});
- }));
- }
- return of(new UrlSegmentGroup(segments, {}));
- }
- const { matched, consumedSegments, lastChild } = match(rawSegmentGroup, route, segments);
- if (!matched)
- return noMatch(rawSegmentGroup);
- /** @type {?} */
- const rawSlicedSegments = segments.slice(lastChild);
- /** @type {?} */
- const childConfig$ = this.getChildConfig(ngModule, route, segments);
- return childConfig$.pipe(mergeMap((routerConfig) => {
- /** @type {?} */
- const childModule = routerConfig.module;
- /** @type {?} */
- const childConfig = routerConfig.routes;
- const { segmentGroup, slicedSegments } = split(rawSegmentGroup, consumedSegments, rawSlicedSegments, childConfig);
- if (slicedSegments.length === 0 && segmentGroup.hasChildren()) {
- /** @type {?} */
- const expanded$ = this.expandChildren(childModule, childConfig, segmentGroup);
- return expanded$.pipe(map((children) => new UrlSegmentGroup(consumedSegments, children)));
- }
- if (childConfig.length === 0 && slicedSegments.length === 0) {
- return of(new UrlSegmentGroup(consumedSegments, {}));
- }
- /** @type {?} */
- const expanded$ = this.expandSegment(childModule, segmentGroup, childConfig, slicedSegments, PRIMARY_OUTLET, true);
- return expanded$.pipe(map((cs) => new UrlSegmentGroup(consumedSegments.concat(cs.segments), cs.children)));
- }));
- }
- /**
- * @param {?} ngModule
- * @param {?} route
- * @param {?} segments
- * @return {?}
- */
- getChildConfig(ngModule, route, segments) {
- if (route.children) {
- // The children belong to the same module
- return of(new LoadedRouterConfig(route.children, ngModule));
- }
- if (route.loadChildren) {
- // lazy children belong to the loaded module
- if (route._loadedConfig !== undefined) {
- return of(route._loadedConfig);
- }
- return runCanLoadGuard(ngModule.injector, route, segments)
- .pipe(mergeMap((shouldLoad) => {
- if (shouldLoad) {
- return this.configLoader.load(ngModule.injector, route)
- .pipe(map((cfg) => {
- route._loadedConfig = cfg;
- return cfg;
- }));
- }
- return canLoadFails(route);
- }));
- }
- return of(new LoadedRouterConfig([], ngModule));
- }
- /**
- * @param {?} route
- * @param {?} urlTree
- * @return {?}
- */
- lineralizeSegments(route, urlTree) {
- /** @type {?} */
- let res = [];
- /** @type {?} */
- let c = urlTree.root;
- while (true) {
- res = res.concat(c.segments);
- if (c.numberOfChildren === 0) {
- return of(res);
- }
- if (c.numberOfChildren > 1 || !c.children[PRIMARY_OUTLET]) {
- return namedOutletsRedirect(/** @type {?} */ ((route.redirectTo)));
- }
- c = c.children[PRIMARY_OUTLET];
- }
- }
- /**
- * @param {?} segments
- * @param {?} redirectTo
- * @param {?} posParams
- * @return {?}
- */
- applyRedirectCommands(segments, redirectTo, posParams) {
- return this.applyRedirectCreatreUrlTree(redirectTo, this.urlSerializer.parse(redirectTo), segments, posParams);
- }
- /**
- * @param {?} redirectTo
- * @param {?} urlTree
- * @param {?} segments
- * @param {?} posParams
- * @return {?}
- */
- applyRedirectCreatreUrlTree(redirectTo, urlTree, segments, posParams) {
- /** @type {?} */
- const newRoot = this.createSegmentGroup(redirectTo, urlTree.root, segments, posParams);
- return new UrlTree(newRoot, this.createQueryParams(urlTree.queryParams, this.urlTree.queryParams), urlTree.fragment);
- }
- /**
- * @param {?} redirectToParams
- * @param {?} actualParams
- * @return {?}
- */
- createQueryParams(redirectToParams, actualParams) {
- /** @type {?} */
- const res = {};
- forEach(redirectToParams, (v, k) => {
- /** @type {?} */
- const copySourceValue = typeof v === 'string' && v.startsWith(':');
- if (copySourceValue) {
- /** @type {?} */
- const sourceName = v.substring(1);
- res[k] = actualParams[sourceName];
- }
- else {
- res[k] = v;
- }
- });
- return res;
- }
- /**
- * @param {?} redirectTo
- * @param {?} group
- * @param {?} segments
- * @param {?} posParams
- * @return {?}
- */
- createSegmentGroup(redirectTo, group, segments, posParams) {
- /** @type {?} */
- const updatedSegments = this.createSegments(redirectTo, group.segments, segments, posParams);
- /** @type {?} */
- let children = {};
- forEach(group.children, (child, name) => {
- children[name] = this.createSegmentGroup(redirectTo, child, segments, posParams);
- });
- return new UrlSegmentGroup(updatedSegments, children);
- }
- /**
- * @param {?} redirectTo
- * @param {?} redirectToSegments
- * @param {?} actualSegments
- * @param {?} posParams
- * @return {?}
- */
- createSegments(redirectTo, redirectToSegments, actualSegments, posParams) {
- return redirectToSegments.map(s => s.path.startsWith(':') ? this.findPosParam(redirectTo, s, posParams) :
- this.findOrReturn(s, actualSegments));
- }
- /**
- * @param {?} redirectTo
- * @param {?} redirectToUrlSegment
- * @param {?} posParams
- * @return {?}
- */
- findPosParam(redirectTo, redirectToUrlSegment, posParams) {
- /** @type {?} */
- const pos = posParams[redirectToUrlSegment.path.substring(1)];
- if (!pos)
- throw new Error(`Cannot redirect to '${redirectTo}'. Cannot find '${redirectToUrlSegment.path}'.`);
- return pos;
- }
- /**
- * @param {?} redirectToUrlSegment
- * @param {?} actualSegments
- * @return {?}
- */
- findOrReturn(redirectToUrlSegment, actualSegments) {
- /** @type {?} */
- let idx = 0;
- for (const s of actualSegments) {
- if (s.path === redirectToUrlSegment.path) {
- actualSegments.splice(idx);
- return s;
- }
- idx++;
- }
- return redirectToUrlSegment;
- }
- }
- /**
- * @param {?} moduleInjector
- * @param {?} route
- * @param {?} segments
- * @return {?}
- */
- function runCanLoadGuard(moduleInjector, route, segments) {
- /** @type {?} */
- const canLoad = route.canLoad;
- if (!canLoad || canLoad.length === 0)
- return of(true);
- /** @type {?} */
- const obs = from(canLoad).pipe(map((injectionToken) => {
- /** @type {?} */
- const guard = moduleInjector.get(injectionToken);
- return wrapIntoObservable(guard.canLoad ? guard.canLoad(route, segments) : guard(route, segments));
- }));
- return andObservables(obs);
- }
- /**
- * @param {?} segmentGroup
- * @param {?} route
- * @param {?} segments
- * @return {?}
- */
- function match(segmentGroup, route, segments) {
- if (route.path === '') {
- if ((route.pathMatch === 'full') && (segmentGroup.hasChildren() || segments.length > 0)) {
- return { matched: false, consumedSegments: [], lastChild: 0, positionalParamSegments: {} };
- }
- return { matched: true, consumedSegments: [], lastChild: 0, positionalParamSegments: {} };
- }
- /** @type {?} */
- const matcher = route.matcher || defaultUrlMatcher;
- /** @type {?} */
- const res = matcher(segments, segmentGroup, route);
- if (!res) {
- return {
- matched: false,
- consumedSegments: /** @type {?} */ ([]),
- lastChild: 0,
- positionalParamSegments: {},
- };
- }
- return {
- matched: true,
- consumedSegments: /** @type {?} */ ((res.consumed)),
- lastChild: /** @type {?} */ ((res.consumed.length)),
- positionalParamSegments: /** @type {?} */ ((res.posParams)),
- };
- }
- /**
- * @param {?} segmentGroup
- * @param {?} consumedSegments
- * @param {?} slicedSegments
- * @param {?} config
- * @return {?}
- */
- function split(segmentGroup, consumedSegments, slicedSegments, config) {
- if (slicedSegments.length > 0 &&
- containsEmptyPathRedirectsWithNamedOutlets(segmentGroup, slicedSegments, config)) {
- /** @type {?} */
- const s = new UrlSegmentGroup(consumedSegments, createChildrenForEmptySegments(config, new UrlSegmentGroup(slicedSegments, segmentGroup.children)));
- return { segmentGroup: mergeTrivialChildren(s), slicedSegments: [] };
- }
- if (slicedSegments.length === 0 &&
- containsEmptyPathRedirects(segmentGroup, slicedSegments, config)) {
- /** @type {?} */
- const s = new UrlSegmentGroup(segmentGroup.segments, addEmptySegmentsToChildrenIfNeeded(segmentGroup, slicedSegments, config, segmentGroup.children));
- return { segmentGroup: mergeTrivialChildren(s), slicedSegments };
- }
- return { segmentGroup, slicedSegments };
- }
- /**
- * @param {?} s
- * @return {?}
- */
- function mergeTrivialChildren(s) {
- if (s.numberOfChildren === 1 && s.children[PRIMARY_OUTLET]) {
- /** @type {?} */
- const c = s.children[PRIMARY_OUTLET];
- return new UrlSegmentGroup(s.segments.concat(c.segments), c.children);
- }
- return s;
- }
- /**
- * @param {?} segmentGroup
- * @param {?} slicedSegments
- * @param {?} routes
- * @param {?} children
- * @return {?}
- */
- function addEmptySegmentsToChildrenIfNeeded(segmentGroup, slicedSegments, routes, children) {
- /** @type {?} */
- const res = {};
- for (const r of routes) {
- if (isEmptyPathRedirect(segmentGroup, slicedSegments, r) && !children[getOutlet(r)]) {
- res[getOutlet(r)] = new UrlSegmentGroup([], {});
- }
- }
- return Object.assign({}, children, res);
- }
- /**
- * @param {?} routes
- * @param {?} primarySegmentGroup
- * @return {?}
- */
- function createChildrenForEmptySegments(routes, primarySegmentGroup) {
- /** @type {?} */
- const res = {};
- res[PRIMARY_OUTLET] = primarySegmentGroup;
- for (const r of routes) {
- if (r.path === '' && getOutlet(r) !== PRIMARY_OUTLET) {
- res[getOutlet(r)] = new UrlSegmentGroup([], {});
- }
- }
- return res;
- }
- /**
- * @param {?} segmentGroup
- * @param {?} segments
- * @param {?} routes
- * @return {?}
- */
- function containsEmptyPathRedirectsWithNamedOutlets(segmentGroup, segments, routes) {
- return routes.some(r => isEmptyPathRedirect(segmentGroup, segments, r) && getOutlet(r) !== PRIMARY_OUTLET);
- }
- /**
- * @param {?} segmentGroup
- * @param {?} segments
- * @param {?} routes
- * @return {?}
- */
- function containsEmptyPathRedirects(segmentGroup, segments, routes) {
- return routes.some(r => isEmptyPathRedirect(segmentGroup, segments, r));
- }
- /**
- * @param {?} segmentGroup
- * @param {?} segments
- * @param {?} r
- * @return {?}
- */
- function isEmptyPathRedirect(segmentGroup, segments, r) {
- if ((segmentGroup.hasChildren() || segments.length > 0) && r.pathMatch === 'full') {
- return false;
- }
- return r.path === '' && r.redirectTo !== undefined;
- }
- /**
- * @param {?} route
- * @return {?}
- */
- function getOutlet(route) {
- return route.outlet || PRIMARY_OUTLET;
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /**
- * @param {?} moduleInjector
- * @param {?} configLoader
- * @param {?} urlSerializer
- * @param {?} config
- * @return {?}
- */
- function applyRedirects$1(moduleInjector, configLoader, urlSerializer, config) {
- return function (source) {
- return source.pipe(switchMap(t => applyRedirects(moduleInjector, configLoader, urlSerializer, t.extractedUrl, config)
- .pipe(map(urlAfterRedirects => (Object.assign({}, t, { urlAfterRedirects }))))));
- };
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- class CanActivate {
- /**
- * @param {?} path
- */
- constructor(path) {
- this.path = path;
- this.route = this.path[this.path.length - 1];
- }
- }
- class CanDeactivate {
- /**
- * @param {?} component
- * @param {?} route
- */
- constructor(component, route) {
- this.component = component;
- this.route = route;
- }
- }
- /**
- * @param {?} future
- * @param {?} curr
- * @param {?} parentContexts
- * @return {?}
- */
- function getAllRouteGuards(future, curr, parentContexts) {
- /** @type {?} */
- const futureRoot = future._root;
- /** @type {?} */
- const currRoot = curr ? curr._root : null;
- return getChildRouteGuards(futureRoot, currRoot, parentContexts, [futureRoot.value]);
- }
- /**
- * @param {?} p
- * @return {?}
- */
- function getCanActivateChild(p) {
- /** @type {?} */
- const canActivateChild = p.routeConfig ? p.routeConfig.canActivateChild : null;
- if (!canActivateChild || canActivateChild.length === 0)
- return null;
- return { node: p, guards: canActivateChild };
- }
- /**
- * @param {?} token
- * @param {?} snapshot
- * @param {?} moduleInjector
- * @return {?}
- */
- function getToken(token, snapshot, moduleInjector) {
- /** @type {?} */
- const config = getClosestLoadedConfig(snapshot);
- /** @type {?} */
- const injector = config ? config.module.injector : moduleInjector;
- return injector.get(token);
- }
- /**
- * @param {?} snapshot
- * @return {?}
- */
- function getClosestLoadedConfig(snapshot) {
- if (!snapshot)
- return null;
- for (let s = snapshot.parent; s; s = s.parent) {
- /** @type {?} */
- const route = s.routeConfig;
- if (route && route._loadedConfig)
- return route._loadedConfig;
- }
- return null;
- }
- /**
- * @param {?} futureNode
- * @param {?} currNode
- * @param {?} contexts
- * @param {?} futurePath
- * @param {?=} checks
- * @return {?}
- */
- function getChildRouteGuards(futureNode, currNode, contexts, futurePath, checks = {
- canDeactivateChecks: [],
- canActivateChecks: []
- }) {
- /** @type {?} */
- const prevChildren = nodeChildrenAsMap(currNode);
- // Process the children of the future route
- futureNode.children.forEach(c => {
- getRouteGuards(c, prevChildren[c.value.outlet], contexts, futurePath.concat([c.value]), checks);
- delete prevChildren[c.value.outlet];
- });
- // Process any children left from the current route (not active for the future route)
- forEach(prevChildren, (v, k) => deactivateRouteAndItsChildren(v, /** @type {?} */ ((contexts)).getContext(k), checks));
- return checks;
- }
- /**
- * @param {?} futureNode
- * @param {?} currNode
- * @param {?} parentContexts
- * @param {?} futurePath
- * @param {?=} checks
- * @return {?}
- */
- function getRouteGuards(futureNode, currNode, parentContexts, futurePath, checks = {
- canDeactivateChecks: [],
- canActivateChecks: []
- }) {
- /** @type {?} */
- const future = futureNode.value;
- /** @type {?} */
- const curr = currNode ? currNode.value : null;
- /** @type {?} */
- const context = parentContexts ? parentContexts.getContext(futureNode.value.outlet) : null;
- // reusing the node
- if (curr && future.routeConfig === curr.routeConfig) {
- /** @type {?} */
- const shouldRun = shouldRunGuardsAndResolvers(curr, future, /** @type {?} */ ((future.routeConfig)).runGuardsAndResolvers);
- if (shouldRun) {
- checks.canActivateChecks.push(new CanActivate(futurePath));
- }
- else {
- // we need to set the data
- future.data = curr.data;
- future._resolvedData = curr._resolvedData;
- }
- // If we have a component, we need to go through an outlet.
- if (future.component) {
- getChildRouteGuards(futureNode, currNode, context ? context.children : null, futurePath, checks);
- // if we have a componentless route, we recurse but keep the same outlet map.
- }
- else {
- getChildRouteGuards(futureNode, currNode, parentContexts, futurePath, checks);
- }
- if (shouldRun) {
- /** @type {?} */
- const component = context && context.outlet && context.outlet.component || null;
- checks.canDeactivateChecks.push(new CanDeactivate(component, curr));
- }
- }
- else {
- if (curr) {
- deactivateRouteAndItsChildren(currNode, context, checks);
- }
- checks.canActivateChecks.push(new CanActivate(futurePath));
- // If we have a component, we need to go through an outlet.
- if (future.component) {
- getChildRouteGuards(futureNode, null, context ? context.children : null, futurePath, checks);
- // if we have a componentless route, we recurse but keep the same outlet map.
- }
- else {
- getChildRouteGuards(futureNode, null, parentContexts, futurePath, checks);
- }
- }
- return checks;
- }
- /**
- * @param {?} curr
- * @param {?} future
- * @param {?} mode
- * @return {?}
- */
- function shouldRunGuardsAndResolvers(curr, future, mode) {
- switch (mode) {
- case 'always':
- return true;
- case 'paramsOrQueryParamsChange':
- return !equalParamsAndUrlSegments(curr, future) ||
- !shallowEqual(curr.queryParams, future.queryParams);
- case 'paramsChange':
- default:
- return !equalParamsAndUrlSegments(curr, future);
- }
- }
- /**
- * @param {?} route
- * @param {?} context
- * @param {?} checks
- * @return {?}
- */
- function deactivateRouteAndItsChildren(route, context, checks) {
- /** @type {?} */
- const children = nodeChildrenAsMap(route);
- /** @type {?} */
- const r = route.value;
- forEach(children, (node, childName) => {
- if (!r.component) {
- deactivateRouteAndItsChildren(node, context, checks);
- }
- else if (context) {
- deactivateRouteAndItsChildren(node, context.children.getContext(childName), checks);
- }
- else {
- deactivateRouteAndItsChildren(node, null, checks);
- }
- });
- if (!r.component) {
- checks.canDeactivateChecks.push(new CanDeactivate(null, r));
- }
- else if (context && context.outlet && context.outlet.isActivated) {
- checks.canDeactivateChecks.push(new CanDeactivate(context.outlet.component, r));
- }
- else {
- checks.canDeactivateChecks.push(new CanDeactivate(null, r));
- }
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /**
- * @param {?} moduleInjector
- * @param {?=} forwardEvent
- * @return {?}
- */
- function checkGuards(moduleInjector, forwardEvent) {
- return function (source) {
- return source.pipe(mergeMap(t => {
- const { targetSnapshot, currentSnapshot, guards: { canActivateChecks, canDeactivateChecks } } = t;
- if (canDeactivateChecks.length === 0 && canActivateChecks.length === 0) {
- return of(Object.assign({}, t, { guardsResult: true }));
- }
- return runCanDeactivateChecks(canDeactivateChecks, /** @type {?} */ ((targetSnapshot)), currentSnapshot, moduleInjector)
- .pipe(mergeMap((canDeactivate) => {
- return canDeactivate ?
- runCanActivateChecks(/** @type {?} */ ((targetSnapshot)), canActivateChecks, moduleInjector, forwardEvent) :
- of(false);
- }), map(guardsResult => (Object.assign({}, t, { guardsResult }))));
- }));
- };
- }
- /**
- * @param {?} checks
- * @param {?} futureRSS
- * @param {?} currRSS
- * @param {?} moduleInjector
- * @return {?}
- */
- function runCanDeactivateChecks(checks, futureRSS, currRSS, moduleInjector) {
- return from(checks).pipe(mergeMap((check) => runCanDeactivate(check.component, check.route, currRSS, futureRSS, moduleInjector)), every((result) => result === true));
- }
- /**
- * @param {?} futureSnapshot
- * @param {?} checks
- * @param {?} moduleInjector
- * @param {?=} forwardEvent
- * @return {?}
- */
- function runCanActivateChecks(futureSnapshot, checks, moduleInjector, forwardEvent) {
- return from(checks).pipe(concatMap((check) => andObservables(from([
- fireChildActivationStart(check.route.parent, forwardEvent),
- fireActivationStart(check.route, forwardEvent),
- runCanActivateChild(futureSnapshot, check.path, moduleInjector),
- runCanActivate(futureSnapshot, check.route, moduleInjector)
- ]))), every((result) => result === true));
- }
- /**
- * This should fire off `ActivationStart` events for each route being activated at this
- * level.
- * In other words, if you're activating `a` and `b` below, `path` will contain the
- * `ActivatedRouteSnapshot`s for both and we will fire `ActivationStart` for both. Always
- * return
- * `true` so checks continue to run.
- * @param {?} snapshot
- * @param {?=} forwardEvent
- * @return {?}
- */
- function fireActivationStart(snapshot, forwardEvent) {
- if (snapshot !== null && forwardEvent) {
- forwardEvent(new ActivationStart(snapshot));
- }
- return of(true);
- }
- /**
- * This should fire off `ChildActivationStart` events for each route being activated at this
- * level.
- * In other words, if you're activating `a` and `b` below, `path` will contain the
- * `ActivatedRouteSnapshot`s for both and we will fire `ChildActivationStart` for both. Always
- * return
- * `true` so checks continue to run.
- * @param {?} snapshot
- * @param {?=} forwardEvent
- * @return {?}
- */
- function fireChildActivationStart(snapshot, forwardEvent) {
- if (snapshot !== null && forwardEvent) {
- forwardEvent(new ChildActivationStart(snapshot));
- }
- return of(true);
- }
- /**
- * @param {?} futureRSS
- * @param {?} futureARS
- * @param {?} moduleInjector
- * @return {?}
- */
- function runCanActivate(futureRSS, futureARS, moduleInjector) {
- /** @type {?} */
- const canActivate = futureARS.routeConfig ? futureARS.routeConfig.canActivate : null;
- if (!canActivate || canActivate.length === 0)
- return of(true);
- /** @type {?} */
- const obs = from(canActivate).pipe(map((c) => {
- /** @type {?} */
- const guard = getToken(c, futureARS, moduleInjector);
- /** @type {?} */
- let observable;
- if (guard.canActivate) {
- observable = wrapIntoObservable(guard.canActivate(futureARS, futureRSS));
- }
- else {
- observable = wrapIntoObservable(guard(futureARS, futureRSS));
- }
- return observable.pipe(first());
- }));
- return andObservables(obs);
- }
- /**
- * @param {?} futureRSS
- * @param {?} path
- * @param {?} moduleInjector
- * @return {?}
- */
- function runCanActivateChild(futureRSS, path, moduleInjector) {
- /** @type {?} */
- const futureARS = path[path.length - 1];
- /** @type {?} */
- const canActivateChildGuards = path.slice(0, path.length - 1)
- .reverse()
- .map(p => getCanActivateChild(p))
- .filter(_ => _ !== null);
- return andObservables(from(canActivateChildGuards).pipe(map((d) => {
- /** @type {?} */
- const obs = from(d.guards).pipe(map((c) => {
- /** @type {?} */
- const guard = getToken(c, d.node, moduleInjector);
- /** @type {?} */
- let observable;
- if (guard.canActivateChild) {
- observable = wrapIntoObservable(guard.canActivateChild(futureARS, futureRSS));
- }
- else {
- observable = wrapIntoObservable(guard(futureARS, futureRSS));
- }
- return observable.pipe(first());
- }));
- return andObservables(obs);
- })));
- }
- /**
- * @param {?} component
- * @param {?} currARS
- * @param {?} currRSS
- * @param {?} futureRSS
- * @param {?} moduleInjector
- * @return {?}
- */
- function runCanDeactivate(component, currARS, currRSS, futureRSS, moduleInjector) {
- /** @type {?} */
- const canDeactivate = currARS && currARS.routeConfig ? currARS.routeConfig.canDeactivate : null;
- if (!canDeactivate || canDeactivate.length === 0)
- return of(true);
- /** @type {?} */
- const canDeactivate$ = from(canDeactivate).pipe(mergeMap((c) => {
- /** @type {?} */
- const guard = getToken(c, currARS, moduleInjector);
- /** @type {?} */
- let observable;
- if (guard.canDeactivate) {
- observable = wrapIntoObservable(guard.canDeactivate(component, currARS, currRSS, futureRSS));
- }
- else {
- observable = wrapIntoObservable(guard(component, currARS, currRSS, futureRSS));
- }
- return observable.pipe(first());
- }));
- return canDeactivate$.pipe(every((result) => result === true));
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- class NoMatch$1 {
- }
- /**
- * @param {?} rootComponentType
- * @param {?} config
- * @param {?} urlTree
- * @param {?} url
- * @param {?=} paramsInheritanceStrategy
- * @param {?=} relativeLinkResolution
- * @return {?}
- */
- function recognize(rootComponentType, config, urlTree, url, paramsInheritanceStrategy = 'emptyOnly', relativeLinkResolution = 'legacy') {
- return new Recognizer(rootComponentType, config, urlTree, url, paramsInheritanceStrategy, relativeLinkResolution)
- .recognize();
- }
- class Recognizer {
- /**
- * @param {?} rootComponentType
- * @param {?} config
- * @param {?} urlTree
- * @param {?} url
- * @param {?} paramsInheritanceStrategy
- * @param {?} relativeLinkResolution
- */
- constructor(rootComponentType, config, urlTree, url, paramsInheritanceStrategy, relativeLinkResolution) {
- this.rootComponentType = rootComponentType;
- this.config = config;
- this.urlTree = urlTree;
- this.url = url;
- this.paramsInheritanceStrategy = paramsInheritanceStrategy;
- this.relativeLinkResolution = relativeLinkResolution;
- }
- /**
- * @return {?}
- */
- recognize() {
- try {
- /** @type {?} */
- const rootSegmentGroup = split$1(this.urlTree.root, [], [], this.config, this.relativeLinkResolution).segmentGroup;
- /** @type {?} */
- const children = this.processSegmentGroup(this.config, rootSegmentGroup, PRIMARY_OUTLET);
- /** @type {?} */
- const 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, {});
- /** @type {?} */
- const rootNode = new TreeNode(root, children);
- /** @type {?} */
- const routeState = new RouterStateSnapshot(this.url, rootNode);
- this.inheritParamsAndData(routeState._root);
- return of(routeState);
- }
- catch (e) {
- return new Observable((obs) => obs.error(e));
- }
- }
- /**
- * @param {?} routeNode
- * @return {?}
- */
- inheritParamsAndData(routeNode) {
- /** @type {?} */
- const route = routeNode.value;
- /** @type {?} */
- const i = inheritedParamsDataResolve(route, this.paramsInheritanceStrategy);
- route.params = Object.freeze(i.params);
- route.data = Object.freeze(i.data);
- routeNode.children.forEach(n => this.inheritParamsAndData(n));
- }
- /**
- * @param {?} config
- * @param {?} segmentGroup
- * @param {?} outlet
- * @return {?}
- */
- processSegmentGroup(config, segmentGroup, outlet) {
- if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
- return this.processChildren(config, segmentGroup);
- }
- return this.processSegment(config, segmentGroup, segmentGroup.segments, outlet);
- }
- /**
- * @param {?} config
- * @param {?} segmentGroup
- * @return {?}
- */
- processChildren(config, segmentGroup) {
- /** @type {?} */
- const children = mapChildrenIntoArray(segmentGroup, (child, childOutlet) => this.processSegmentGroup(config, child, childOutlet));
- checkOutletNameUniqueness(children);
- sortActivatedRouteSnapshots(children);
- return children;
- }
- /**
- * @param {?} config
- * @param {?} segmentGroup
- * @param {?} segments
- * @param {?} outlet
- * @return {?}
- */
- processSegment(config, segmentGroup, segments, outlet) {
- for (const r of config) {
- try {
- return this.processSegmentAgainstRoute(r, segmentGroup, segments, outlet);
- }
- catch (e) {
- if (!(e instanceof NoMatch$1))
- throw e;
- }
- }
- if (this.noLeftoversInUrl(segmentGroup, segments, outlet)) {
- return [];
- }
- throw new NoMatch$1();
- }
- /**
- * @param {?} segmentGroup
- * @param {?} segments
- * @param {?} outlet
- * @return {?}
- */
- noLeftoversInUrl(segmentGroup, segments, outlet) {
- return segments.length === 0 && !segmentGroup.children[outlet];
- }
- /**
- * @param {?} route
- * @param {?} rawSegment
- * @param {?} segments
- * @param {?} outlet
- * @return {?}
- */
- processSegmentAgainstRoute(route, rawSegment, segments, outlet) {
- if (route.redirectTo)
- throw new NoMatch$1();
- if ((route.outlet || PRIMARY_OUTLET) !== outlet)
- throw new NoMatch$1();
- /** @type {?} */
- let snapshot;
- /** @type {?} */
- let consumedSegments = [];
- /** @type {?} */
- let rawSlicedSegments = [];
- if (route.path === '**') {
- /** @type {?} */
- const params = segments.length > 0 ? /** @type {?} */ ((last$1(segments))).parameters : {};
- 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));
- }
- else {
- /** @type {?} */
- const result = match$1(rawSegment, route, segments);
- consumedSegments = result.consumedSegments;
- rawSlicedSegments = segments.slice(result.lastChild);
- 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));
- }
- /** @type {?} */
- const childConfig = getChildConfig(route);
- const { segmentGroup, slicedSegments } = split$1(rawSegment, consumedSegments, rawSlicedSegments, childConfig, this.relativeLinkResolution);
- if (slicedSegments.length === 0 && segmentGroup.hasChildren()) {
- /** @type {?} */
- const children = this.processChildren(childConfig, segmentGroup);
- return [new TreeNode(snapshot, children)];
- }
- if (childConfig.length === 0 && slicedSegments.length === 0) {
- return [new TreeNode(snapshot, [])];
- }
- /** @type {?} */
- const children = this.processSegment(childConfig, segmentGroup, slicedSegments, PRIMARY_OUTLET);
- return [new TreeNode(snapshot, children)];
- }
- }
- /**
- * @param {?} nodes
- * @return {?}
- */
- function sortActivatedRouteSnapshots(nodes) {
- nodes.sort((a, b) => {
- if (a.value.outlet === PRIMARY_OUTLET)
- return -1;
- if (b.value.outlet === PRIMARY_OUTLET)
- return 1;
- return a.value.outlet.localeCompare(b.value.outlet);
- });
- }
- /**
- * @param {?} route
- * @return {?}
- */
- function getChildConfig(route) {
- if (route.children) {
- return route.children;
- }
- if (route.loadChildren) {
- return /** @type {?} */ ((route._loadedConfig)).routes;
- }
- return [];
- }
- /**
- * @param {?} segmentGroup
- * @param {?} route
- * @param {?} segments
- * @return {?}
- */
- function match$1(segmentGroup, route, segments) {
- if (route.path === '') {
- if (route.pathMatch === 'full' && (segmentGroup.hasChildren() || segments.length > 0)) {
- throw new NoMatch$1();
- }
- return { consumedSegments: [], lastChild: 0, parameters: {} };
- }
- /** @type {?} */
- const matcher = route.matcher || defaultUrlMatcher;
- /** @type {?} */
- const res = matcher(segments, segmentGroup, route);
- if (!res)
- throw new NoMatch$1();
- /** @type {?} */
- const posParams = {};
- forEach(/** @type {?} */ ((res.posParams)), (v, k) => { posParams[k] = v.path; });
- /** @type {?} */
- const parameters = res.consumed.length > 0 ? Object.assign({}, posParams, res.consumed[res.consumed.length - 1].parameters) :
- posParams;
- return { consumedSegments: res.consumed, lastChild: res.consumed.length, parameters };
- }
- /**
- * @param {?} nodes
- * @return {?}
- */
- function checkOutletNameUniqueness(nodes) {
- /** @type {?} */
- const names = {};
- nodes.forEach(n => {
- /** @type {?} */
- const routeWithSameOutletName = names[n.value.outlet];
- if (routeWithSameOutletName) {
- /** @type {?} */
- const p = routeWithSameOutletName.url.map(s => s.toString()).join('/');
- /** @type {?} */
- const c = n.value.url.map(s => s.toString()).join('/');
- throw new Error(`Two segments cannot have the same outlet name: '${p}' and '${c}'.`);
- }
- names[n.value.outlet] = n.value;
- });
- }
- /**
- * @param {?} segmentGroup
- * @return {?}
- */
- function getSourceSegmentGroup(segmentGroup) {
- /** @type {?} */
- let s = segmentGroup;
- while (s._sourceSegment) {
- s = s._sourceSegment;
- }
- return s;
- }
- /**
- * @param {?} segmentGroup
- * @return {?}
- */
- function getPathIndexShift(segmentGroup) {
- /** @type {?} */
- let s = segmentGroup;
- /** @type {?} */
- let res = (s._segmentIndexShift ? s._segmentIndexShift : 0);
- while (s._sourceSegment) {
- s = s._sourceSegment;
- res += (s._segmentIndexShift ? s._segmentIndexShift : 0);
- }
- return res - 1;
- }
- /**
- * @param {?} segmentGroup
- * @param {?} consumedSegments
- * @param {?} slicedSegments
- * @param {?} config
- * @param {?} relativeLinkResolution
- * @return {?}
- */
- function split$1(segmentGroup, consumedSegments, slicedSegments, config, relativeLinkResolution) {
- if (slicedSegments.length > 0 &&
- containsEmptyPathMatchesWithNamedOutlets(segmentGroup, slicedSegments, config)) {
- /** @type {?} */
- const s = new UrlSegmentGroup(consumedSegments, createChildrenForEmptyPaths(segmentGroup, consumedSegments, config, new UrlSegmentGroup(slicedSegments, segmentGroup.children)));
- s._sourceSegment = segmentGroup;
- s._segmentIndexShift = consumedSegments.length;
- return { segmentGroup: s, slicedSegments: [] };
- }
- if (slicedSegments.length === 0 &&
- containsEmptyPathMatches(segmentGroup, slicedSegments, config)) {
- /** @type {?} */
- const s = new UrlSegmentGroup(segmentGroup.segments, addEmptyPathsToChildrenIfNeeded(segmentGroup, consumedSegments, slicedSegments, config, segmentGroup.children, relativeLinkResolution));
- s._sourceSegment = segmentGroup;
- s._segmentIndexShift = consumedSegments.length;
- return { segmentGroup: s, slicedSegments };
- }
- /** @type {?} */
- const s = new UrlSegmentGroup(segmentGroup.segments, segmentGroup.children);
- s._sourceSegment = segmentGroup;
- s._segmentIndexShift = consumedSegments.length;
- return { segmentGroup: s, slicedSegments };
- }
- /**
- * @param {?} segmentGroup
- * @param {?} consumedSegments
- * @param {?} slicedSegments
- * @param {?} routes
- * @param {?} children
- * @param {?} relativeLinkResolution
- * @return {?}
- */
- function addEmptyPathsToChildrenIfNeeded(segmentGroup, consumedSegments, slicedSegments, routes, children, relativeLinkResolution) {
- /** @type {?} */
- const res = {};
- for (const r of routes) {
- if (emptyPathMatch(segmentGroup, slicedSegments, r) && !children[getOutlet$1(r)]) {
- /** @type {?} */
- const s = new UrlSegmentGroup([], {});
- s._sourceSegment = segmentGroup;
- if (relativeLinkResolution === 'legacy') {
- s._segmentIndexShift = segmentGroup.segments.length;
- }
- else {
- s._segmentIndexShift = consumedSegments.length;
- }
- res[getOutlet$1(r)] = s;
- }
- }
- return Object.assign({}, children, res);
- }
- /**
- * @param {?} segmentGroup
- * @param {?} consumedSegments
- * @param {?} routes
- * @param {?} primarySegment
- * @return {?}
- */
- function createChildrenForEmptyPaths(segmentGroup, consumedSegments, routes, primarySegment) {
- /** @type {?} */
- const res = {};
- res[PRIMARY_OUTLET] = primarySegment;
- primarySegment._sourceSegment = segmentGroup;
- primarySegment._segmentIndexShift = consumedSegments.length;
- for (const r of routes) {
- if (r.path === '' && getOutlet$1(r) !== PRIMARY_OUTLET) {
- /** @type {?} */
- const s = new UrlSegmentGroup([], {});
- s._sourceSegment = segmentGroup;
- s._segmentIndexShift = consumedSegments.length;
- res[getOutlet$1(r)] = s;
- }
- }
- return res;
- }
- /**
- * @param {?} segmentGroup
- * @param {?} slicedSegments
- * @param {?} routes
- * @return {?}
- */
- function containsEmptyPathMatchesWithNamedOutlets(segmentGroup, slicedSegments, routes) {
- return routes.some(r => emptyPathMatch(segmentGroup, slicedSegments, r) && getOutlet$1(r) !== PRIMARY_OUTLET);
- }
- /**
- * @param {?} segmentGroup
- * @param {?} slicedSegments
- * @param {?} routes
- * @return {?}
- */
- function containsEmptyPathMatches(segmentGroup, slicedSegments, routes) {
- return routes.some(r => emptyPathMatch(segmentGroup, slicedSegments, r));
- }
- /**
- * @param {?} segmentGroup
- * @param {?} slicedSegments
- * @param {?} r
- * @return {?}
- */
- function emptyPathMatch(segmentGroup, slicedSegments, r) {
- if ((segmentGroup.hasChildren() || slicedSegments.length > 0) && r.pathMatch === 'full') {
- return false;
- }
- return r.path === '' && r.redirectTo === undefined;
- }
- /**
- * @param {?} route
- * @return {?}
- */
- function getOutlet$1(route) {
- return route.outlet || PRIMARY_OUTLET;
- }
- /**
- * @param {?} route
- * @return {?}
- */
- function getData(route) {
- return route.data || {};
- }
- /**
- * @param {?} route
- * @return {?}
- */
- function getResolve(route) {
- return route.resolve || {};
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /**
- * @param {?} rootComponentType
- * @param {?} config
- * @param {?} serializer
- * @param {?} paramsInheritanceStrategy
- * @return {?}
- */
- function recognize$1(rootComponentType, config, serializer, paramsInheritanceStrategy) {
- return function (source) {
- return source.pipe(mergeMap(t => recognize(rootComponentType, config, t.urlAfterRedirects, serializer(t.urlAfterRedirects), paramsInheritanceStrategy)
- .pipe(map(targetSnapshot => (Object.assign({}, t, { targetSnapshot }))))));
- };
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /**
- * @param {?} paramsInheritanceStrategy
- * @param {?} moduleInjector
- * @return {?}
- */
- function resolveData(paramsInheritanceStrategy, moduleInjector) {
- return function (source) {
- return source.pipe(mergeMap(t => {
- const { targetSnapshot, guards: { canActivateChecks } } = t;
- if (!canActivateChecks.length) {
- return of(t);
- }
- return from(canActivateChecks)
- .pipe(concatMap(check => runResolve(check.route, /** @type {?} */ ((targetSnapshot)), paramsInheritanceStrategy, moduleInjector)), reduce((_, __) => _), map(_ => t));
- }));
- };
- }
- /**
- * @param {?} futureARS
- * @param {?} futureRSS
- * @param {?} paramsInheritanceStrategy
- * @param {?} moduleInjector
- * @return {?}
- */
- function runResolve(futureARS, futureRSS, paramsInheritanceStrategy, moduleInjector) {
- /** @type {?} */
- const resolve = futureARS._resolve;
- return resolveNode(resolve, futureARS, futureRSS, moduleInjector)
- .pipe(map((resolvedData) => {
- futureARS._resolvedData = resolvedData;
- futureARS.data = Object.assign({}, futureARS.data, inheritedParamsDataResolve(futureARS, paramsInheritanceStrategy).resolve);
- return null;
- }));
- }
- /**
- * @param {?} resolve
- * @param {?} futureARS
- * @param {?} futureRSS
- * @param {?} moduleInjector
- * @return {?}
- */
- function resolveNode(resolve, futureARS, futureRSS, moduleInjector) {
- /** @type {?} */
- const keys = Object.keys(resolve);
- if (keys.length === 0) {
- return of({});
- }
- if (keys.length === 1) {
- /** @type {?} */
- const key = keys[0];
- return getResolver(resolve[key], futureARS, futureRSS, moduleInjector)
- .pipe(map((value) => { return { [key]: value }; }));
- }
- /** @type {?} */
- const data = {};
- /** @type {?} */
- const runningResolvers$ = from(keys).pipe(mergeMap((key) => {
- return getResolver(resolve[key], futureARS, futureRSS, moduleInjector)
- .pipe(map((value) => {
- data[key] = value;
- return value;
- }));
- }));
- return runningResolvers$.pipe(last(), map(() => data));
- }
- /**
- * @param {?} injectionToken
- * @param {?} futureARS
- * @param {?} futureRSS
- * @param {?} moduleInjector
- * @return {?}
- */
- function getResolver(injectionToken, futureARS, futureRSS, moduleInjector) {
- /** @type {?} */
- const resolver = getToken(injectionToken, futureARS, moduleInjector);
- return resolver.resolve ? wrapIntoObservable(resolver.resolve(futureARS, futureRSS)) :
- wrapIntoObservable(resolver(futureARS, futureRSS));
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /**
- * Perform a side effect through a switchMap for every emission on the source Observable,
- * but return an Observable that is identical to the source. It's essentially the same as
- * the `tap` operator, but if the side effectful `next` function returns an ObservableInput,
- * it will wait before continuing with the original value.
- * @template T
- * @param {?} next
- * @return {?}
- */
- function switchTap(next) {
- return function (source) {
- return source.pipe(switchMap(v => {
- /** @type {?} */
- const nextResult = next(v);
- if (nextResult) {
- return from(nextResult).pipe(map(() => v));
- }
- return from([v]);
- }));
- };
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /**
- * \@description
- *
- * Provides a way to customize when activated routes get reused.
- *
- * \@publicApi
- * @abstract
- */
- class RouteReuseStrategy {
- }
- /**
- * Does not detach any subtrees. Reuses routes as long as their route config is the same.
- */
- class DefaultRouteReuseStrategy {
- /**
- * @param {?} route
- * @return {?}
- */
- shouldDetach(route) { return false; }
- /**
- * @param {?} route
- * @param {?} detachedTree
- * @return {?}
- */
- store(route, detachedTree) { }
- /**
- * @param {?} route
- * @return {?}
- */
- shouldAttach(route) { return false; }
- /**
- * @param {?} route
- * @return {?}
- */
- retrieve(route) { return null; }
- /**
- * @param {?} future
- * @param {?} curr
- * @return {?}
- */
- shouldReuseRoute(future, curr) {
- return future.routeConfig === curr.routeConfig;
- }
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /** *
- * \@docsNotRequired
- * \@publicApi
- @type {?} */
- const ROUTES = new InjectionToken('ROUTES');
- class RouterConfigLoader {
- /**
- * @param {?} loader
- * @param {?} compiler
- * @param {?=} onLoadStartListener
- * @param {?=} onLoadEndListener
- */
- constructor(loader, compiler, onLoadStartListener, onLoadEndListener) {
- this.loader = loader;
- this.compiler = compiler;
- this.onLoadStartListener = onLoadStartListener;
- this.onLoadEndListener = onLoadEndListener;
- }
- /**
- * @param {?} parentInjector
- * @param {?} route
- * @return {?}
- */
- load(parentInjector, route) {
- if (this.onLoadStartListener) {
- this.onLoadStartListener(route);
- }
- /** @type {?} */
- const moduleFactory$ = this.loadModuleFactory(/** @type {?} */ ((route.loadChildren)));
- return moduleFactory$.pipe(map((factory) => {
- if (this.onLoadEndListener) {
- this.onLoadEndListener(route);
- }
- /** @type {?} */
- const module = factory.create(parentInjector);
- return new LoadedRouterConfig(flatten(module.injector.get(ROUTES)).map(standardizeConfig), module);
- }));
- }
- /**
- * @param {?} loadChildren
- * @return {?}
- */
- loadModuleFactory(loadChildren) {
- if (typeof loadChildren === 'string') {
- return from(this.loader.load(loadChildren));
- }
- else {
- return wrapIntoObservable(loadChildren()).pipe(mergeMap((t) => {
- if (t instanceof NgModuleFactory) {
- return of(t);
- }
- else {
- return from(this.compiler.compileModuleAsync(t));
- }
- }));
- }
- }
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /**
- * @license
- * Copyright Google Inc. All Rights Reserved.
- *
- * Use of this source code is governed by an MIT-style license that can be
- * found in the LICENSE file at https://angular.io/license
- */
- /**
- * \@description
- *
- * Provides a way to migrate AngularJS applications to Angular.
- *
- * \@publicApi
- * @abstract
- */
- class UrlHandlingStrategy {
- }
- /**
- * \@publicApi
- */
- class DefaultUrlHandlingStrategy {
- /**
- * @param {?} url
- * @return {?}
- */
- shouldProcessUrl(url) { return true; }
- /**
- * @param {?} url
- * @return {?}
- */
- extract(url) { return url; }
- /**
- * @param {?} newUrlPart
- * @param {?} wholeUrl
- * @return {?}
- */
- merge(newUrlPart, wholeUrl) { return newUrlPart; }
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /**
- * @param {?} error
- * @return {?}
- */
- function defaultErrorHandler(error) {
- throw error;
- }
- /**
- * @param {?} error
- * @param {?} urlSerializer
- * @param {?} url
- * @return {?}
- */
- function defaultMalformedUriErrorHandler(error, urlSerializer, url) {
- return urlSerializer.parse('/');
- }
- /**
- * \@internal
- * @param {?} snapshot
- * @param {?} runExtras
- * @return {?}
- */
- function defaultRouterHook(snapshot, runExtras) {
- return /** @type {?} */ (of(null));
- }
- /**
- * \@description
- *
- * Provides the navigation and url manipulation capabilities.
- *
- * See `Routes` for more details and examples.
- *
- * \@ngModule RouterModule
- *
- * \@publicApi
- */
- class Router {
- /**
- * Creates the router service.
- * @param {?} rootComponentType
- * @param {?} urlSerializer
- * @param {?} rootContexts
- * @param {?} location
- * @param {?} injector
- * @param {?} loader
- * @param {?} compiler
- * @param {?} config
- */
- constructor(rootComponentType, urlSerializer, rootContexts, location, injector, loader, compiler, config) {
- this.rootComponentType = rootComponentType;
- this.urlSerializer = urlSerializer;
- this.rootContexts = rootContexts;
- this.location = location;
- this.config = config;
- this.navigationId = 0;
- this.isNgZoneEnabled = false;
- this.events = new Subject();
- /**
- * Error handler that is invoked when a navigation errors.
- *
- * See `ErrorHandler` for more information.
- */
- this.errorHandler = defaultErrorHandler;
- /**
- * Malformed uri error handler is invoked when `Router.parseUrl(url)` throws an
- * error due to containing an invalid character. The most common case would be a `%` sign
- * that's not encoded and is not part of a percent encoded sequence.
- */
- this.malformedUriErrorHandler = defaultMalformedUriErrorHandler;
- /**
- * Indicates if at least one navigation happened.
- */
- this.navigated = false;
- this.lastSuccessfulId = -1;
- /**
- * Used by RouterModule. This allows us to
- * pause the navigation either before preactivation or after it.
- * \@internal
- */
- this.hooks = {
- beforePreactivation: defaultRouterHook,
- afterPreactivation: defaultRouterHook
- };
- /**
- * Extracts and merges URLs. Used for AngularJS to Angular migrations.
- */
- this.urlHandlingStrategy = new DefaultUrlHandlingStrategy();
- this.routeReuseStrategy = new DefaultRouteReuseStrategy();
- /**
- * Define what the router should do if it receives a navigation request to the current URL.
- * By default, the router will ignore this navigation. However, this prevents features such
- * as a "refresh" button. Use this option to configure the behavior when navigating to the
- * current URL. Default is 'ignore'.
- */
- this.onSameUrlNavigation = 'ignore';
- /**
- * Defines how the router merges params, data and resolved data from parent to child
- * routes. Available options are:
- *
- * - `'emptyOnly'`, the default, only inherits parent params for path-less or component-less
- * routes.
- * - `'always'`, enables unconditional inheritance of parent params.
- */
- this.paramsInheritanceStrategy = 'emptyOnly';
- /**
- * Defines when the router updates the browser URL. The default behavior is to update after
- * successful navigation. However, some applications may prefer a mode where the URL gets
- * updated at the beginning of navigation. The most common use case would be updating the
- * URL early so if navigation fails, you can show an error message with the URL that failed.
- * Available options are:
- *
- * - `'deferred'`, the default, updates the browser URL after navigation has finished.
- * - `'eager'`, updates browser URL at the beginning of navigation.
- */
- this.urlUpdateStrategy = 'deferred';
- /**
- * See {\@link RouterModule} for more information.
- */
- this.relativeLinkResolution = 'legacy';
- /** @type {?} */
- const onLoadStart = (r) => this.triggerEvent(new RouteConfigLoadStart(r));
- /** @type {?} */
- const onLoadEnd = (r) => this.triggerEvent(new RouteConfigLoadEnd(r));
- this.ngModule = injector.get(NgModuleRef);
- this.console = injector.get(ɵConsole);
- /** @type {?} */
- const ngZone = injector.get(NgZone);
- this.isNgZoneEnabled = ngZone instanceof NgZone;
- this.resetConfig(config);
- this.currentUrlTree = createEmptyUrlTree();
- this.rawUrlTree = this.currentUrlTree;
- this.configLoader = new RouterConfigLoader(loader, compiler, onLoadStart, onLoadEnd);
- this.routerState = createEmptyState(this.currentUrlTree, this.rootComponentType);
- this.transitions = new BehaviorSubject({
- id: 0,
- currentUrlTree: this.currentUrlTree,
- currentRawUrl: this.currentUrlTree,
- extractedUrl: this.urlHandlingStrategy.extract(this.currentUrlTree),
- urlAfterRedirects: this.urlHandlingStrategy.extract(this.currentUrlTree),
- rawUrl: this.currentUrlTree,
- extras: {},
- resolve: null,
- reject: null,
- promise: Promise.resolve(true),
- source: 'imperative',
- state: null,
- currentSnapshot: this.routerState.snapshot,
- targetSnapshot: null,
- currentRouterState: this.routerState,
- targetRouterState: null,
- guards: { canActivateChecks: [], canDeactivateChecks: [] },
- guardsResult: null,
- });
- this.navigations = this.setupNavigations(this.transitions);
- this.processNavigations();
- }
- /**
- * @param {?} transitions
- * @return {?}
- */
- setupNavigations(transitions) {
- /** @type {?} */
- const eventsSubject = (/** @type {?} */ (this.events));
- return /** @type {?} */ ((transitions.pipe(filter(t => t.id !== 0),
- // Extract URL
- map(t => (/** @type {?} */ (Object.assign({}, t, { extractedUrl: this.urlHandlingStrategy.extract(t.rawUrl) })))),
- // Using switchMap so we cancel executing navigations when a new one comes in
- switchMap(t => {
- /** @type {?} */
- let completed = false;
- /** @type {?} */
- let errored = false;
- return of(t).pipe(switchMap(t => {
- /** @type {?} */
- const urlTransition = !this.navigated || t.extractedUrl.toString() !== this.currentUrlTree.toString();
- /** @type {?} */
- const processCurrentUrl = (this.onSameUrlNavigation === 'reload' ? true : urlTransition) &&
- this.urlHandlingStrategy.shouldProcessUrl(t.rawUrl);
- if (processCurrentUrl) {
- return of(t).pipe(
- // Update URL if in `eager` update mode
- tap(t => this.urlUpdateStrategy === 'eager' && !t.extras.skipLocationChange &&
- this.setBrowserUrl(t.rawUrl, !!t.extras.replaceUrl, t.id)),
- // Fire NavigationStart event
- switchMap(t => {
- /** @type {?} */
- const transition = this.transitions.getValue();
- eventsSubject.next(new NavigationStart(t.id, this.serializeUrl(t.extractedUrl), t.source, t.state));
- if (transition !== this.transitions.getValue()) {
- return EMPTY;
- }
- return [t];
- }),
- // This delay is required to match old behavior that forced navigation to
- // always be async
- switchMap(t => Promise.resolve(t)),
- // ApplyRedirects
- applyRedirects$1(this.ngModule.injector, this.configLoader, this.urlSerializer, this.config),
- // Recognize
- recognize$1(this.rootComponentType, this.config, (url) => this.serializeUrl(url), this.paramsInheritanceStrategy),
- // Fire RoutesRecognized
- tap(t => {
- /** @type {?} */
- const routesRecognized = new RoutesRecognized(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), /** @type {?} */ ((t.targetSnapshot)));
- eventsSubject.next(routesRecognized);
- }));
- }
- else {
- /** @type {?} */
- const processPreviousUrl = urlTransition && this.rawUrlTree &&
- this.urlHandlingStrategy.shouldProcessUrl(this.rawUrlTree);
- /* When the current URL shouldn't be processed, but the previous one was, we
- * handle this "error condition" by navigating to the previously successful URL,
- * but leaving the URL intact.*/
- if (processPreviousUrl) {
- const { id, extractedUrl, source, state, extras } = t;
- /** @type {?} */
- const navStart = new NavigationStart(id, this.serializeUrl(extractedUrl), source, state);
- eventsSubject.next(navStart);
- /** @type {?} */
- const targetSnapshot = createEmptyState(extractedUrl, this.rootComponentType).snapshot;
- return of(Object.assign({}, t, { targetSnapshot, urlAfterRedirects: extractedUrl, extras: Object.assign({}, extras, { skipLocationChange: false, replaceUrl: false }) }));
- }
- else {
- /* When neither the current or previous URL can be processed, do nothing other
- * than update router's internal reference to the current "settled" URL. This
- * way the next navigation will be coming from the current URL in the browser.
- */
- this.rawUrlTree = t.rawUrl;
- t.resolve(null);
- return EMPTY;
- }
- }
- }),
- // Before Preactivation
- switchTap(t => {
- const { targetSnapshot, id: navigationId, extractedUrl: appliedUrlTree, rawUrl: rawUrlTree, extras: { skipLocationChange, replaceUrl } } = t;
- return this.hooks.beforePreactivation(/** @type {?} */ ((targetSnapshot)), {
- navigationId,
- appliedUrlTree,
- rawUrlTree,
- skipLocationChange: !!skipLocationChange,
- replaceUrl: !!replaceUrl,
- });
- }),
- // --- GUARDS ---
- tap(t => {
- /** @type {?} */
- const guardsStart = new GuardsCheckStart(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), /** @type {?} */ ((t.targetSnapshot)));
- this.triggerEvent(guardsStart);
- }), map(t => (Object.assign({}, t, { guards: getAllRouteGuards(/** @type {?} */ ((t.targetSnapshot)), t.currentSnapshot, this.rootContexts) }))), checkGuards(this.ngModule.injector, (evt) => this.triggerEvent(evt)), tap(t => {
- /** @type {?} */
- const guardsEnd = new GuardsCheckEnd(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), /** @type {?} */ ((t.targetSnapshot)), !!t.guardsResult);
- this.triggerEvent(guardsEnd);
- }), filter(t => {
- if (!t.guardsResult) {
- this.resetUrlToCurrentUrlTree();
- /** @type {?} */
- const navCancel = new NavigationCancel(t.id, this.serializeUrl(t.extractedUrl), '');
- eventsSubject.next(navCancel);
- t.resolve(false);
- return false;
- }
- return true;
- }),
- // --- RESOLVE ---
- switchTap(t => {
- if (t.guards.canActivateChecks.length) {
- return of(t).pipe(tap(t => {
- /** @type {?} */
- const resolveStart = new ResolveStart(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), /** @type {?} */ ((t.targetSnapshot)));
- this.triggerEvent(resolveStart);
- }), resolveData(this.paramsInheritanceStrategy, this.ngModule.injector), //
- //
- tap(t => {
- /** @type {?} */
- const resolveEnd = new ResolveEnd(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), /** @type {?} */ ((t.targetSnapshot)));
- this.triggerEvent(resolveEnd);
- }));
- }
- return undefined;
- }),
- // --- AFTER PREACTIVATION ---
- switchTap(t => {
- const { targetSnapshot, id: navigationId, extractedUrl: appliedUrlTree, rawUrl: rawUrlTree, extras: { skipLocationChange, replaceUrl } } = t;
- return this.hooks.afterPreactivation(/** @type {?} */ ((targetSnapshot)), {
- navigationId,
- appliedUrlTree,
- rawUrlTree,
- skipLocationChange: !!skipLocationChange,
- replaceUrl: !!replaceUrl,
- });
- }), map(t => {
- /** @type {?} */
- const targetRouterState = createRouterState(this.routeReuseStrategy, /** @type {?} */ ((t.targetSnapshot)), t.currentRouterState);
- return (Object.assign({}, t, { targetRouterState }));
- }), /* Once here, we are about to activate syncronously. The assumption is this will
- succeed, and user code may read from the Router service. Therefore before
- activation, we need to update router properties storing the current URL and the
- RouterState, as well as updated the browser URL. All this should happen *before*
- activating. */
- tap(t => {
- this.currentUrlTree = t.urlAfterRedirects;
- this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, t.rawUrl);
- (/** @type {?} */ (this)).routerState = /** @type {?} */ ((t.targetRouterState));
- if (this.urlUpdateStrategy === 'deferred' && !t.extras.skipLocationChange) {
- this.setBrowserUrl(this.rawUrlTree, !!t.extras.replaceUrl, t.id);
- }
- }), activateRoutes(this.rootContexts, this.routeReuseStrategy, (evt) => this.triggerEvent(evt)), tap({
- /**
- * @return {?}
- */
- next() { completed = true; }, /**
- * @return {?}
- */
- complete() { completed = true; }
- }), finalize(() => {
- /* When the navigation stream finishes either through error or success, we set the
- * `completed` or `errored` flag. However, there are some situations where we could
- * get here without either of those being set. For instance, a redirect during
- * NavigationStart. Therefore, this is a catch-all to make sure the NavigationCancel
- * event is fired when a navigation gets cancelled but not caught by other means. */
- if (!completed && !errored) {
- // Must reset to current URL tree here to ensure history.state is set. On a fresh
- // page load, if a new navigation comes in before a successful navigation
- // completes, there will be nothing in history.state.navigationId. This can cause
- // sync problems with AngularJS sync code which looks for a value here in order
- // to determine whether or not to handle a given popstate event or to leave it
- // to the Angualr router.
- this.resetUrlToCurrentUrlTree();
- /** @type {?} */
- const navCancel = new NavigationCancel(t.id, this.serializeUrl(t.extractedUrl), `Navigation ID ${t.id} is not equal to the current navigation id ${this.navigationId}`);
- eventsSubject.next(navCancel);
- t.resolve(false);
- }
- }), catchError((e) => {
- errored = true;
- /* This error type is issued during Redirect, and is handled as a cancellation
- * rather than an error. */
- if (isNavigationCancelingError(e)) {
- this.navigated = true;
- this.resetStateAndUrl(t.currentRouterState, t.currentUrlTree, t.rawUrl);
- /** @type {?} */
- const navCancel = new NavigationCancel(t.id, this.serializeUrl(t.extractedUrl), e.message);
- eventsSubject.next(navCancel);
- t.resolve(false);
- /* All other errors should reset to the router's internal URL reference to the
- * pre-error state. */
- }
- else {
- this.resetStateAndUrl(t.currentRouterState, t.currentUrlTree, t.rawUrl);
- /** @type {?} */
- const navError = new NavigationError(t.id, this.serializeUrl(t.extractedUrl), e);
- eventsSubject.next(navError);
- try {
- t.resolve(this.errorHandler(e));
- }
- catch (ee) {
- t.reject(ee);
- }
- }
- return EMPTY;
- }));
- // TODO(jasonaden): remove cast once g3 is on updated TypeScript
- }))));
- }
- /**
- * \@internal
- * TODO: this should be removed once the constructor of the router made internal
- * @param {?} rootComponentType
- * @return {?}
- */
- resetRootComponentType(rootComponentType) {
- this.rootComponentType = rootComponentType;
- // TODO: vsavkin router 4.0 should make the root component set to null
- // this will simplify the lifecycle of the router.
- this.routerState.root.component = this.rootComponentType;
- }
- /**
- * @return {?}
- */
- getTransition() { return this.transitions.value; }
- /**
- * @param {?} t
- * @return {?}
- */
- setTransition(t) {
- this.transitions.next(Object.assign({}, this.getTransition(), t));
- }
- /**
- * Sets up the location change listener and performs the initial navigation.
- * @return {?}
- */
- initialNavigation() {
- this.setUpLocationChangeListener();
- if (this.navigationId === 0) {
- this.navigateByUrl(this.location.path(true), { replaceUrl: true });
- }
- }
- /**
- * Sets up the location change listener.
- * @return {?}
- */
- setUpLocationChangeListener() {
- // Don't need to use Zone.wrap any more, because zone.js
- // already patch onPopState, so location change callback will
- // run into ngZone
- if (!this.locationSubscription) {
- this.locationSubscription = /** @type {?} */ (this.location.subscribe((change) => {
- /** @type {?} */
- let rawUrlTree = this.parseUrl(change['url']);
- /** @type {?} */
- const source = change['type'] === 'popstate' ? 'popstate' : 'hashchange';
- /** @type {?} */
- const state = change.state && change.state.navigationId ?
- { navigationId: change.state.navigationId } :
- null;
- setTimeout(() => { this.scheduleNavigation(rawUrlTree, source, state, { replaceUrl: true }); }, 0);
- }));
- }
- }
- /**
- * The current url
- * @return {?}
- */
- get url() { return this.serializeUrl(this.currentUrlTree); }
- /**
- * \@internal
- * @param {?} event
- * @return {?}
- */
- triggerEvent(event) { (/** @type {?} */ (this.events)).next(event); }
- /**
- * Resets the configuration used for navigation and generating links.
- *
- * \@usageNotes
- *
- * ### Example
- *
- * ```
- * router.resetConfig([
- * { path: 'team/:id', component: TeamCmp, children: [
- * { path: 'simple', component: SimpleCmp },
- * { path: 'user/:name', component: UserCmp }
- * ]}
- * ]);
- * ```
- * @param {?} config
- * @return {?}
- */
- resetConfig(config) {
- validateConfig(config);
- this.config = config.map(standardizeConfig);
- this.navigated = false;
- this.lastSuccessfulId = -1;
- }
- /**
- * \@docsNotRequired
- * @return {?}
- */
- ngOnDestroy() { this.dispose(); }
- /**
- * Disposes of the router
- * @return {?}
- */
- dispose() {
- if (this.locationSubscription) {
- this.locationSubscription.unsubscribe();
- this.locationSubscription = /** @type {?} */ ((null));
- }
- }
- /**
- * Applies an array of commands to the current url tree and creates a new url tree.
- *
- * When given an activate route, applies the given commands starting from the route.
- * When not given a route, applies the given command starting from the root.
- *
- * \@usageNotes
- *
- * ### Example
- *
- * ```
- * // create /team/33/user/11
- * router.createUrlTree(['/team', 33, 'user', 11]);
- *
- * // create /team/33;expand=true/user/11
- * router.createUrlTree(['/team', 33, {expand: true}, 'user', 11]);
- *
- * // you can collapse static segments like this (this works only with the first passed-in value):
- * router.createUrlTree(['/team/33/user', userId]);
- *
- * // If the first segment can contain slashes, and you do not want the router to split it, you
- * // can do the following:
- *
- * router.createUrlTree([{segmentPath: '/one/two'}]);
- *
- * // create /team/33/(user/11//right:chat)
- * router.createUrlTree(['/team', 33, {outlets: {primary: 'user/11', right: 'chat'}}]);
- *
- * // remove the right secondary node
- * router.createUrlTree(['/team', 33, {outlets: {primary: 'user/11', right: null}}]);
- *
- * // assuming the current url is `/team/33/user/11` and the route points to `user/11`
- *
- * // navigate to /team/33/user/11/details
- * router.createUrlTree(['details'], {relativeTo: route});
- *
- * // navigate to /team/33/user/22
- * router.createUrlTree(['../22'], {relativeTo: route});
- *
- * // navigate to /team/44/user/22
- * router.createUrlTree(['../../team/44/user/22'], {relativeTo: route});
- * ```
- * @param {?} commands
- * @param {?=} navigationExtras
- * @return {?}
- */
- createUrlTree(commands, navigationExtras = {}) {
- const { relativeTo, queryParams, fragment, preserveQueryParams, queryParamsHandling, preserveFragment } = navigationExtras;
- if (isDevMode() && preserveQueryParams && /** @type {?} */ (console) && /** @type {?} */ (console.warn)) {
- console.warn('preserveQueryParams is deprecated, use queryParamsHandling instead.');
- }
- /** @type {?} */
- const a = relativeTo || this.routerState.root;
- /** @type {?} */
- const f = preserveFragment ? this.currentUrlTree.fragment : fragment;
- /** @type {?} */
- let q = null;
- if (queryParamsHandling) {
- switch (queryParamsHandling) {
- case 'merge':
- q = Object.assign({}, this.currentUrlTree.queryParams, queryParams);
- break;
- case 'preserve':
- q = this.currentUrlTree.queryParams;
- break;
- default:
- q = queryParams || null;
- }
- }
- else {
- q = preserveQueryParams ? this.currentUrlTree.queryParams : queryParams || null;
- }
- if (q !== null) {
- q = this.removeEmptyProps(q);
- }
- return createUrlTree(a, this.currentUrlTree, commands, /** @type {?} */ ((q)), /** @type {?} */ ((f)));
- }
- /**
- * Navigate based on the provided url. This navigation is always absolute.
- *
- * Returns a promise that:
- * - resolves to 'true' when navigation succeeds,
- * - resolves to 'false' when navigation fails,
- * - is rejected when an error happens.
- *
- * \@usageNotes
- *
- * ### Example
- *
- * ```
- * router.navigateByUrl("/team/33/user/11");
- *
- * // Navigate without updating the URL
- * router.navigateByUrl("/team/33/user/11", { skipLocationChange: true });
- * ```
- *
- * Since `navigateByUrl()` takes an absolute URL as the first parameter,
- * it will not apply any delta to the current URL and ignores any properties
- * in the second parameter (the `NavigationExtras`) that would change the
- * provided URL.
- * @param {?} url
- * @param {?=} extras
- * @return {?}
- */
- navigateByUrl(url, extras = { skipLocationChange: false }) {
- if (isDevMode() && this.isNgZoneEnabled && !NgZone.isInAngularZone()) {
- this.console.warn(`Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?`);
- }
- /** @type {?} */
- const urlTree = url instanceof UrlTree ? url : this.parseUrl(url);
- /** @type {?} */
- const mergedTree = this.urlHandlingStrategy.merge(urlTree, this.rawUrlTree);
- return this.scheduleNavigation(mergedTree, 'imperative', null, extras);
- }
- /**
- * Navigate based on the provided array of commands and a starting point.
- * If no starting route is provided, the navigation is absolute.
- *
- * Returns a promise that:
- * - resolves to 'true' when navigation succeeds,
- * - resolves to 'false' when navigation fails,
- * - is rejected when an error happens.
- *
- * \@usageNotes
- *
- * ### Example
- *
- * ```
- * router.navigate(['team', 33, 'user', 11], {relativeTo: route});
- *
- * // Navigate without updating the URL
- * router.navigate(['team', 33, 'user', 11], {relativeTo: route, skipLocationChange: true});
- * ```
- *
- * The first parameter of `navigate()` is a delta to be applied to the current URL
- * or the one provided in the `relativeTo` property of the second parameter (the
- * `NavigationExtras`).
- * @param {?} commands
- * @param {?=} extras
- * @return {?}
- */
- navigate(commands, extras = { skipLocationChange: false }) {
- validateCommands(commands);
- return this.navigateByUrl(this.createUrlTree(commands, extras), extras);
- }
- /**
- * Serializes a `UrlTree` into a string
- * @param {?} url
- * @return {?}
- */
- serializeUrl(url) { return this.urlSerializer.serialize(url); }
- /**
- * Parses a string into a `UrlTree`
- * @param {?} url
- * @return {?}
- */
- parseUrl(url) {
- /** @type {?} */
- let urlTree;
- try {
- urlTree = this.urlSerializer.parse(url);
- }
- catch (e) {
- urlTree = this.malformedUriErrorHandler(e, this.urlSerializer, url);
- }
- return urlTree;
- }
- /**
- * Returns whether the url is activated
- * @param {?} url
- * @param {?} exact
- * @return {?}
- */
- isActive(url, exact) {
- if (url instanceof UrlTree) {
- return containsTree(this.currentUrlTree, url, exact);
- }
- /** @type {?} */
- const urlTree = this.parseUrl(url);
- return containsTree(this.currentUrlTree, urlTree, exact);
- }
- /**
- * @param {?} params
- * @return {?}
- */
- removeEmptyProps(params) {
- return Object.keys(params).reduce((result, key) => {
- /** @type {?} */
- const value = params[key];
- if (value !== null && value !== undefined) {
- result[key] = value;
- }
- return result;
- }, {});
- }
- /**
- * @return {?}
- */
- processNavigations() {
- this.navigations.subscribe(t => {
- this.navigated = true;
- this.lastSuccessfulId = t.id;
- (/** @type {?} */ (this.events))
- .next(new NavigationEnd(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(this.currentUrlTree)));
- t.resolve(true);
- }, e => { this.console.warn(`Unhandled Navigation Error: `); });
- }
- /**
- * @param {?} rawUrl
- * @param {?} source
- * @param {?} state
- * @param {?} extras
- * @return {?}
- */
- scheduleNavigation(rawUrl, source, state, extras) {
- /** @type {?} */
- const lastNavigation = this.getTransition();
- // If the user triggers a navigation imperatively (e.g., by using navigateByUrl),
- // and that navigation results in 'replaceState' that leads to the same URL,
- // we should skip those.
- if (lastNavigation && source !== 'imperative' && lastNavigation.source === 'imperative' &&
- lastNavigation.rawUrl.toString() === rawUrl.toString()) {
- return Promise.resolve(true); // return value is not used
- }
- // Because of a bug in IE and Edge, the location class fires two events (popstate and
- // hashchange) every single time. The second one should be ignored. Otherwise, the URL will
- // flicker. Handles the case when a popstate was emitted first.
- if (lastNavigation && source == 'hashchange' && lastNavigation.source === 'popstate' &&
- lastNavigation.rawUrl.toString() === rawUrl.toString()) {
- return Promise.resolve(true); // return value is not used
- }
- // Because of a bug in IE and Edge, the location class fires two events (popstate and
- // hashchange) every single time. The second one should be ignored. Otherwise, the URL will
- // flicker. Handles the case when a hashchange was emitted first.
- if (lastNavigation && source == 'popstate' && lastNavigation.source === 'hashchange' &&
- lastNavigation.rawUrl.toString() === rawUrl.toString()) {
- return Promise.resolve(true); // return value is not used
- }
- /** @type {?} */
- let resolve = null;
- /** @type {?} */
- let reject = null;
- /** @type {?} */
- const promise = new Promise((res, rej) => {
- resolve = res;
- reject = rej;
- });
- /** @type {?} */
- const id = ++this.navigationId;
- this.setTransition({
- id,
- source,
- state,
- currentUrlTree: this.currentUrlTree,
- currentRawUrl: this.rawUrlTree, rawUrl, extras, resolve, reject, promise,
- currentSnapshot: this.routerState.snapshot,
- currentRouterState: this.routerState
- });
- // Make sure that the error is propagated even though `processNavigations` catch
- // handler does not rethrow
- return promise.catch((e) => { return Promise.reject(e); });
- }
- /**
- * @param {?} url
- * @param {?} replaceUrl
- * @param {?} id
- * @return {?}
- */
- setBrowserUrl(url, replaceUrl, id) {
- /** @type {?} */
- const path = this.urlSerializer.serialize(url);
- if (this.location.isCurrentPathEqualTo(path) || replaceUrl) {
- this.location.replaceState(path, '', { navigationId: id });
- }
- else {
- this.location.go(path, '', { navigationId: id });
- }
- }
- /**
- * @param {?} storedState
- * @param {?} storedUrl
- * @param {?} rawUrl
- * @return {?}
- */
- resetStateAndUrl(storedState, storedUrl, rawUrl) {
- (/** @type {?} */ (this)).routerState = storedState;
- this.currentUrlTree = storedUrl;
- this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, rawUrl);
- this.resetUrlToCurrentUrlTree();
- }
- /**
- * @return {?}
- */
- resetUrlToCurrentUrlTree() {
- this.location.replaceState(this.urlSerializer.serialize(this.rawUrlTree), '', { navigationId: this.lastSuccessfulId });
- }
- }
- /**
- * @param {?} commands
- * @return {?}
- */
- function validateCommands(commands) {
- for (let i = 0; i < commands.length; i++) {
- /** @type {?} */
- const cmd = commands[i];
- if (cmd == null) {
- throw new Error(`The requested path contains ${cmd} segment at index ${i}`);
- }
- }
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /**
- * \@description
- *
- * Lets you link to specific routes in your app.
- *
- * Consider the following route configuration:
- * `[{ path: 'user/:name', component: UserCmp }]`.
- * When linking to this `user/:name` route, you use the `RouterLink` directive.
- *
- * If the link is static, you can use the directive as follows:
- * `<a routerLink="/user/bob">link to user component</a>`
- *
- * If you use dynamic values to generate the link, you can pass an array of path
- * segments, followed by the params for each segment.
- *
- * For instance `['/team', teamId, 'user', userName, {details: true}]`
- * means that we want to generate a link to `/team/11/user/bob;details=true`.
- *
- * Multiple static segments can be merged into one
- * (e.g., `['/team/11/user', userName, {details: true}]`).
- *
- * The first segment name can be prepended with `/`, `./`, or `../`:
- * * If the first segment begins with `/`, the router will look up the route from the root of the
- * app.
- * * If the first segment begins with `./`, or doesn't begin with a slash, the router will
- * instead look in the children of the current activated route.
- * * And if the first segment begins with `../`, the router will go up one level.
- *
- * You can set query params and fragment as follows:
- *
- * ```
- * <a [routerLink]="['/user/bob']" [queryParams]="{debug: true}" fragment="education">
- * link to user component
- * </a>
- * ```
- * RouterLink will use these to generate this link: `/user/bob#education?debug=true`.
- *
- * (Deprecated in v4.0.0 use `queryParamsHandling` instead) You can also tell the
- * directive to preserve the current query params and fragment:
- *
- * ```
- * <a [routerLink]="['/user/bob']" preserveQueryParams preserveFragment>
- * link to user component
- * </a>
- * ```
- *
- * You can tell the directive to how to handle queryParams, available options are:
- * - `'merge'`: merge the queryParams into the current queryParams
- * - `'preserve'`: preserve the current queryParams
- * - default/`''`: use the queryParams only
- *
- * Same options for {\@link NavigationExtras#queryParamsHandling
- * NavigationExtras#queryParamsHandling}.
- *
- * ```
- * <a [routerLink]="['/user/bob']" [queryParams]="{debug: true}" queryParamsHandling="merge">
- * link to user component
- * </a>
- * ```
- *
- * The router link directive always treats the provided input as a delta to the current url.
- *
- * For instance, if the current url is `/user/(box//aux:team)`.
- *
- * Then the following link `<a [routerLink]="['/user/jim']">Jim</a>` will generate the link
- * `/user/(jim//aux:team)`.
- *
- * See {\@link Router#createUrlTree createUrlTree} for more information.
- *
- * \@ngModule RouterModule
- *
- * \@publicApi
- */
- class RouterLink {
- /**
- * @param {?} router
- * @param {?} route
- * @param {?} tabIndex
- * @param {?} renderer
- * @param {?} el
- */
- constructor(router, route, tabIndex, renderer, el) {
- this.router = router;
- this.route = route;
- this.commands = [];
- if (tabIndex == null) {
- renderer.setAttribute(el.nativeElement, 'tabindex', '0');
- }
- }
- /**
- * @param {?} commands
- * @return {?}
- */
- set routerLink(commands) {
- if (commands != null) {
- this.commands = Array.isArray(commands) ? commands : [commands];
- }
- else {
- this.commands = [];
- }
- }
- /**
- * @deprecated 4.0.0 use `queryParamsHandling` instead.
- * @param {?} value
- * @return {?}
- */
- set preserveQueryParams(value) {
- if (isDevMode() && /** @type {?} */ (console) && /** @type {?} */ (console.warn)) {
- console.warn('preserveQueryParams is deprecated!, use queryParamsHandling instead.');
- }
- this.preserve = value;
- }
- /**
- * @return {?}
- */
- onClick() {
- /** @type {?} */
- const extras = {
- skipLocationChange: attrBoolValue(this.skipLocationChange),
- replaceUrl: attrBoolValue(this.replaceUrl),
- };
- this.router.navigateByUrl(this.urlTree, extras);
- return true;
- }
- /**
- * @return {?}
- */
- get urlTree() {
- return this.router.createUrlTree(this.commands, {
- relativeTo: this.route,
- queryParams: this.queryParams,
- fragment: this.fragment,
- preserveQueryParams: attrBoolValue(this.preserve),
- queryParamsHandling: this.queryParamsHandling,
- preserveFragment: attrBoolValue(this.preserveFragment),
- });
- }
- }
- RouterLink.decorators = [
- { type: Directive, args: [{ selector: ':not(a)[routerLink]' },] }
- ];
- /** @nocollapse */
- RouterLink.ctorParameters = () => [
- { type: Router },
- { type: ActivatedRoute },
- { type: String, decorators: [{ type: Attribute, args: ['tabindex',] }] },
- { type: Renderer2 },
- { type: ElementRef }
- ];
- RouterLink.propDecorators = {
- queryParams: [{ type: Input }],
- fragment: [{ type: Input }],
- queryParamsHandling: [{ type: Input }],
- preserveFragment: [{ type: Input }],
- skipLocationChange: [{ type: Input }],
- replaceUrl: [{ type: Input }],
- routerLink: [{ type: Input }],
- preserveQueryParams: [{ type: Input }],
- onClick: [{ type: HostListener, args: ['click',] }]
- };
- /**
- * \@description
- *
- * Lets you link to specific routes in your app.
- *
- * See `RouterLink` for more information.
- *
- * \@ngModule RouterModule
- *
- * \@publicApi
- */
- class RouterLinkWithHref {
- /**
- * @param {?} router
- * @param {?} route
- * @param {?} locationStrategy
- */
- constructor(router, route, locationStrategy) {
- this.router = router;
- this.route = route;
- this.locationStrategy = locationStrategy;
- this.commands = [];
- this.subscription = router.events.subscribe((s) => {
- if (s instanceof NavigationEnd) {
- this.updateTargetUrlAndHref();
- }
- });
- }
- /**
- * @param {?} commands
- * @return {?}
- */
- set routerLink(commands) {
- if (commands != null) {
- this.commands = Array.isArray(commands) ? commands : [commands];
- }
- else {
- this.commands = [];
- }
- }
- /**
- * @param {?} value
- * @return {?}
- */
- set preserveQueryParams(value) {
- if (isDevMode() && /** @type {?} */ (console) && /** @type {?} */ (console.warn)) {
- console.warn('preserveQueryParams is deprecated, use queryParamsHandling instead.');
- }
- this.preserve = value;
- }
- /**
- * @param {?} changes
- * @return {?}
- */
- ngOnChanges(changes) { this.updateTargetUrlAndHref(); }
- /**
- * @return {?}
- */
- ngOnDestroy() { this.subscription.unsubscribe(); }
- /**
- * @param {?} button
- * @param {?} ctrlKey
- * @param {?} metaKey
- * @param {?} shiftKey
- * @return {?}
- */
- onClick(button, ctrlKey, metaKey, shiftKey) {
- if (button !== 0 || ctrlKey || metaKey || shiftKey) {
- return true;
- }
- if (typeof this.target === 'string' && this.target != '_self') {
- return true;
- }
- /** @type {?} */
- const extras = {
- skipLocationChange: attrBoolValue(this.skipLocationChange),
- replaceUrl: attrBoolValue(this.replaceUrl),
- };
- this.router.navigateByUrl(this.urlTree, extras);
- return false;
- }
- /**
- * @return {?}
- */
- updateTargetUrlAndHref() {
- this.href = this.locationStrategy.prepareExternalUrl(this.router.serializeUrl(this.urlTree));
- }
- /**
- * @return {?}
- */
- get urlTree() {
- return this.router.createUrlTree(this.commands, {
- relativeTo: this.route,
- queryParams: this.queryParams,
- fragment: this.fragment,
- preserveQueryParams: attrBoolValue(this.preserve),
- queryParamsHandling: this.queryParamsHandling,
- preserveFragment: attrBoolValue(this.preserveFragment),
- });
- }
- }
- RouterLinkWithHref.decorators = [
- { type: Directive, args: [{ selector: 'a[routerLink]' },] }
- ];
- /** @nocollapse */
- RouterLinkWithHref.ctorParameters = () => [
- { type: Router },
- { type: ActivatedRoute },
- { type: LocationStrategy }
- ];
- RouterLinkWithHref.propDecorators = {
- target: [{ type: HostBinding, args: ['attr.target',] }, { type: Input }],
- queryParams: [{ type: Input }],
- fragment: [{ type: Input }],
- queryParamsHandling: [{ type: Input }],
- preserveFragment: [{ type: Input }],
- skipLocationChange: [{ type: Input }],
- replaceUrl: [{ type: Input }],
- href: [{ type: HostBinding }],
- routerLink: [{ type: Input }],
- preserveQueryParams: [{ type: Input }],
- onClick: [{ type: HostListener, args: ['click', ['$event.button', '$event.ctrlKey', '$event.metaKey', '$event.shiftKey'],] }]
- };
- /**
- * @param {?} s
- * @return {?}
- */
- function attrBoolValue(s) {
- return s === '' || !!s;
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /**
- *
- * \@description
- *
- * Lets you add a CSS class to an element when the link's route becomes active.
- *
- * This directive lets you add a CSS class to an element when the link's route
- * becomes active.
- *
- * Consider the following example:
- *
- * ```
- * <a routerLink="/user/bob" routerLinkActive="active-link">Bob</a>
- * ```
- *
- * When the url is either '/user' or '/user/bob', the active-link class will
- * be added to the `a` tag. If the url changes, the class will be removed.
- *
- * You can set more than one class, as follows:
- *
- * ```
- * <a routerLink="/user/bob" routerLinkActive="class1 class2">Bob</a>
- * <a routerLink="/user/bob" [routerLinkActive]="['class1', 'class2']">Bob</a>
- * ```
- *
- * You can configure RouterLinkActive by passing `exact: true`. This will add the classes
- * only when the url matches the link exactly.
- *
- * ```
- * <a routerLink="/user/bob" routerLinkActive="active-link" [routerLinkActiveOptions]="{exact:
- * true}">Bob</a>
- * ```
- *
- * You can assign the RouterLinkActive instance to a template variable and directly check
- * the `isActive` status.
- * ```
- * <a routerLink="/user/bob" routerLinkActive #rla="routerLinkActive">
- * Bob {{ rla.isActive ? '(already open)' : ''}}
- * </a>
- * ```
- *
- * Finally, you can apply the RouterLinkActive directive to an ancestor of a RouterLink.
- *
- * ```
- * <div routerLinkActive="active-link" [routerLinkActiveOptions]="{exact: true}">
- * <a routerLink="/user/jim">Jim</a>
- * <a routerLink="/user/bob">Bob</a>
- * </div>
- * ```
- *
- * This will set the active-link class on the div tag if the url is either '/user/jim' or
- * '/user/bob'.
- *
- * \@ngModule RouterModule
- *
- * \@publicApi
- */
- class RouterLinkActive {
- /**
- * @param {?} router
- * @param {?} element
- * @param {?} renderer
- * @param {?} cdr
- */
- constructor(router, element, renderer, cdr) {
- this.router = router;
- this.element = element;
- this.renderer = renderer;
- this.cdr = cdr;
- this.classes = [];
- this.isActive = false;
- this.routerLinkActiveOptions = { exact: false };
- this.subscription = router.events.subscribe((s) => {
- if (s instanceof NavigationEnd) {
- this.update();
- }
- });
- }
- /**
- * @return {?}
- */
- ngAfterContentInit() {
- this.links.changes.subscribe(_ => this.update());
- this.linksWithHrefs.changes.subscribe(_ => this.update());
- this.update();
- }
- /**
- * @param {?} data
- * @return {?}
- */
- set routerLinkActive(data) {
- /** @type {?} */
- const classes = Array.isArray(data) ? data : data.split(' ');
- this.classes = classes.filter(c => !!c);
- }
- /**
- * @param {?} changes
- * @return {?}
- */
- ngOnChanges(changes) { this.update(); }
- /**
- * @return {?}
- */
- ngOnDestroy() { this.subscription.unsubscribe(); }
- /**
- * @return {?}
- */
- update() {
- if (!this.links || !this.linksWithHrefs || !this.router.navigated)
- return;
- Promise.resolve().then(() => {
- /** @type {?} */
- const hasActiveLinks = this.hasActiveLinks();
- if (this.isActive !== hasActiveLinks) {
- (/** @type {?} */ (this)).isActive = hasActiveLinks;
- this.classes.forEach((c) => {
- if (hasActiveLinks) {
- this.renderer.addClass(this.element.nativeElement, c);
- }
- else {
- this.renderer.removeClass(this.element.nativeElement, c);
- }
- });
- }
- });
- }
- /**
- * @param {?} router
- * @return {?}
- */
- isLinkActive(router) {
- return (link) => router.isActive(link.urlTree, this.routerLinkActiveOptions.exact);
- }
- /**
- * @return {?}
- */
- hasActiveLinks() {
- return this.links.some(this.isLinkActive(this.router)) ||
- this.linksWithHrefs.some(this.isLinkActive(this.router));
- }
- }
- RouterLinkActive.decorators = [
- { type: Directive, args: [{
- selector: '[routerLinkActive]',
- exportAs: 'routerLinkActive',
- },] }
- ];
- /** @nocollapse */
- RouterLinkActive.ctorParameters = () => [
- { type: Router },
- { type: ElementRef },
- { type: Renderer2 },
- { type: ChangeDetectorRef }
- ];
- RouterLinkActive.propDecorators = {
- links: [{ type: ContentChildren, args: [RouterLink, { descendants: true },] }],
- linksWithHrefs: [{ type: ContentChildren, args: [RouterLinkWithHref, { descendants: true },] }],
- routerLinkActiveOptions: [{ type: Input }],
- routerLinkActive: [{ type: Input }]
- };
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /**
- * @license
- * Copyright Google Inc. All Rights Reserved.
- *
- * Use of this source code is governed by an MIT-style license that can be
- * found in the LICENSE file at https://angular.io/license
- */
- /**
- * Store contextual information about a `RouterOutlet`
- *
- * \@publicApi
- */
- class OutletContext {
- constructor() {
- this.outlet = null;
- this.route = null;
- this.resolver = null;
- this.children = new ChildrenOutletContexts();
- this.attachRef = null;
- }
- }
- /**
- * Store contextual information about the children (= nested) `RouterOutlet`
- *
- * \@publicApi
- */
- class ChildrenOutletContexts {
- constructor() {
- this.contexts = new Map();
- }
- /**
- * Called when a `RouterOutlet` directive is instantiated
- * @param {?} childName
- * @param {?} outlet
- * @return {?}
- */
- onChildOutletCreated(childName, outlet) {
- /** @type {?} */
- const context = this.getOrCreateContext(childName);
- context.outlet = outlet;
- this.contexts.set(childName, context);
- }
- /**
- * Called when a `RouterOutlet` directive is destroyed.
- * We need to keep the context as the outlet could be destroyed inside a NgIf and might be
- * re-created later.
- * @param {?} childName
- * @return {?}
- */
- onChildOutletDestroyed(childName) {
- /** @type {?} */
- const context = this.getContext(childName);
- if (context) {
- context.outlet = null;
- }
- }
- /**
- * Called when the corresponding route is deactivated during navigation.
- * Because the component get destroyed, all children outlet are destroyed.
- * @return {?}
- */
- onOutletDeactivated() {
- /** @type {?} */
- const contexts = this.contexts;
- this.contexts = new Map();
- return contexts;
- }
- /**
- * @param {?} contexts
- * @return {?}
- */
- onOutletReAttached(contexts) { this.contexts = contexts; }
- /**
- * @param {?} childName
- * @return {?}
- */
- getOrCreateContext(childName) {
- /** @type {?} */
- let context = this.getContext(childName);
- if (!context) {
- context = new OutletContext();
- this.contexts.set(childName, context);
- }
- return context;
- }
- /**
- * @param {?} childName
- * @return {?}
- */
- getContext(childName) { return this.contexts.get(childName) || null; }
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /**
- * \@description
- *
- * Acts as a placeholder that Angular dynamically fills based on the current router state.
- *
- * ```
- * <router-outlet></router-outlet>
- * <router-outlet name='left'></router-outlet>
- * <router-outlet name='right'></router-outlet>
- * ```
- *
- * A router outlet will emit an activate event any time a new component is being instantiated,
- * and a deactivate event when it is being destroyed.
- *
- * ```
- * <router-outlet
- * (activate)='onActivate($event)'
- * (deactivate)='onDeactivate($event)'></router-outlet>
- * ```
- * \@ngModule RouterModule
- *
- * \@publicApi
- */
- class RouterOutlet {
- /**
- * @param {?} parentContexts
- * @param {?} location
- * @param {?} resolver
- * @param {?} name
- * @param {?} changeDetector
- */
- constructor(parentContexts, location, resolver, name, changeDetector) {
- this.parentContexts = parentContexts;
- this.location = location;
- this.resolver = resolver;
- this.changeDetector = changeDetector;
- this.activated = null;
- this._activatedRoute = null;
- this.activateEvents = new EventEmitter();
- this.deactivateEvents = new EventEmitter();
- this.name = name || PRIMARY_OUTLET;
- parentContexts.onChildOutletCreated(this.name, this);
- }
- /**
- * @return {?}
- */
- ngOnDestroy() { this.parentContexts.onChildOutletDestroyed(this.name); }
- /**
- * @return {?}
- */
- ngOnInit() {
- if (!this.activated) {
- /** @type {?} */
- const context = this.parentContexts.getContext(this.name);
- if (context && context.route) {
- if (context.attachRef) {
- // `attachRef` is populated when there is an existing component to mount
- this.attach(context.attachRef, context.route);
- }
- else {
- // otherwise the component defined in the configuration is created
- this.activateWith(context.route, context.resolver || null);
- }
- }
- }
- }
- /**
- * @return {?}
- */
- get isActivated() { return !!this.activated; }
- /**
- * @return {?}
- */
- get component() {
- if (!this.activated)
- throw new Error('Outlet is not activated');
- return this.activated.instance;
- }
- /**
- * @return {?}
- */
- get activatedRoute() {
- if (!this.activated)
- throw new Error('Outlet is not activated');
- return /** @type {?} */ (this._activatedRoute);
- }
- /**
- * @return {?}
- */
- get activatedRouteData() {
- if (this._activatedRoute) {
- return this._activatedRoute.snapshot.data;
- }
- return {};
- }
- /**
- * Called when the `RouteReuseStrategy` instructs to detach the subtree
- * @return {?}
- */
- detach() {
- if (!this.activated)
- throw new Error('Outlet is not activated');
- this.location.detach();
- /** @type {?} */
- const cmp = this.activated;
- this.activated = null;
- this._activatedRoute = null;
- return cmp;
- }
- /**
- * Called when the `RouteReuseStrategy` instructs to re-attach a previously detached subtree
- * @param {?} ref
- * @param {?} activatedRoute
- * @return {?}
- */
- attach(ref, activatedRoute) {
- this.activated = ref;
- this._activatedRoute = activatedRoute;
- this.location.insert(ref.hostView);
- }
- /**
- * @return {?}
- */
- deactivate() {
- if (this.activated) {
- /** @type {?} */
- const c = this.component;
- this.activated.destroy();
- this.activated = null;
- this._activatedRoute = null;
- this.deactivateEvents.emit(c);
- }
- }
- /**
- * @param {?} activatedRoute
- * @param {?} resolver
- * @return {?}
- */
- activateWith(activatedRoute, resolver) {
- if (this.isActivated) {
- throw new Error('Cannot activate an already activated outlet');
- }
- this._activatedRoute = activatedRoute;
- /** @type {?} */
- const snapshot = activatedRoute._futureSnapshot;
- /** @type {?} */
- const component = /** @type {?} */ (/** @type {?} */ ((snapshot.routeConfig)).component);
- resolver = resolver || this.resolver;
- /** @type {?} */
- const factory = resolver.resolveComponentFactory(component);
- /** @type {?} */
- const childContexts = this.parentContexts.getOrCreateContext(this.name).children;
- /** @type {?} */
- const injector = new OutletInjector(activatedRoute, childContexts, this.location.injector);
- this.activated = this.location.createComponent(factory, this.location.length, injector);
- // Calling `markForCheck` to make sure we will run the change detection when the
- // `RouterOutlet` is inside a `ChangeDetectionStrategy.OnPush` component.
- this.changeDetector.markForCheck();
- this.activateEvents.emit(this.activated.instance);
- }
- }
- RouterOutlet.decorators = [
- { type: Directive, args: [{ selector: 'router-outlet', exportAs: 'outlet' },] }
- ];
- /** @nocollapse */
- RouterOutlet.ctorParameters = () => [
- { type: ChildrenOutletContexts },
- { type: ViewContainerRef },
- { type: ComponentFactoryResolver },
- { type: String, decorators: [{ type: Attribute, args: ['name',] }] },
- { type: ChangeDetectorRef }
- ];
- RouterOutlet.propDecorators = {
- activateEvents: [{ type: Output, args: ['activate',] }],
- deactivateEvents: [{ type: Output, args: ['deactivate',] }]
- };
- class OutletInjector {
- /**
- * @param {?} route
- * @param {?} childContexts
- * @param {?} parent
- */
- constructor(route, childContexts, parent) {
- this.route = route;
- this.childContexts = childContexts;
- this.parent = parent;
- }
- /**
- * @param {?} token
- * @param {?=} notFoundValue
- * @return {?}
- */
- get(token, notFoundValue) {
- if (token === ActivatedRoute) {
- return this.route;
- }
- if (token === ChildrenOutletContexts) {
- return this.childContexts;
- }
- return this.parent.get(token, notFoundValue);
- }
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /**
- * \@description
- *
- * Provides a preloading strategy.
- *
- * \@publicApi
- * @abstract
- */
- class PreloadingStrategy {
- }
- /**
- * \@description
- *
- * Provides a preloading strategy that preloads all modules as quickly as possible.
- *
- * ```
- * RouteModule.forRoot(ROUTES, {preloadingStrategy: PreloadAllModules})
- * ```
- *
- * \@publicApi
- */
- class PreloadAllModules {
- /**
- * @param {?} route
- * @param {?} fn
- * @return {?}
- */
- preload(route, fn) {
- return fn().pipe(catchError(() => of(null)));
- }
- }
- /**
- * \@description
- *
- * Provides a preloading strategy that does not preload any modules.
- *
- * This strategy is enabled by default.
- *
- * \@publicApi
- */
- class NoPreloading {
- /**
- * @param {?} route
- * @param {?} fn
- * @return {?}
- */
- preload(route, fn) { return of(null); }
- }
- /**
- * The preloader optimistically loads all router configurations to
- * make navigations into lazily-loaded sections of the application faster.
- *
- * The preloader runs in the background. When the router bootstraps, the preloader
- * starts listening to all navigation events. After every such event, the preloader
- * will check if any configurations can be loaded lazily.
- *
- * If a route is protected by `canLoad` guards, the preloaded will not load it.
- *
- * \@publicApi
- */
- class RouterPreloader {
- /**
- * @param {?} router
- * @param {?} moduleLoader
- * @param {?} compiler
- * @param {?} injector
- * @param {?} preloadingStrategy
- */
- constructor(router, moduleLoader, compiler, injector, preloadingStrategy) {
- this.router = router;
- this.injector = injector;
- this.preloadingStrategy = preloadingStrategy;
- /** @type {?} */
- const onStartLoad = (r) => router.triggerEvent(new RouteConfigLoadStart(r));
- /** @type {?} */
- const onEndLoad = (r) => router.triggerEvent(new RouteConfigLoadEnd(r));
- this.loader = new RouterConfigLoader(moduleLoader, compiler, onStartLoad, onEndLoad);
- }
- /**
- * @return {?}
- */
- setUpPreloading() {
- this.subscription =
- this.router.events
- .pipe(filter((e) => e instanceof NavigationEnd), concatMap(() => this.preload()))
- .subscribe(() => { });
- }
- /**
- * @return {?}
- */
- preload() {
- /** @type {?} */
- const ngModule = this.injector.get(NgModuleRef);
- return this.processRoutes(ngModule, this.router.config);
- }
- /**
- * @return {?}
- */
- ngOnDestroy() { this.subscription.unsubscribe(); }
- /**
- * @param {?} ngModule
- * @param {?} routes
- * @return {?}
- */
- processRoutes(ngModule, routes) {
- /** @type {?} */
- const res = [];
- for (const route of routes) {
- // we already have the config loaded, just recurse
- if (route.loadChildren && !route.canLoad && route._loadedConfig) {
- /** @type {?} */
- const childConfig = route._loadedConfig;
- res.push(this.processRoutes(childConfig.module, childConfig.routes));
- // no config loaded, fetch the config
- }
- else if (route.loadChildren && !route.canLoad) {
- res.push(this.preloadConfig(ngModule, route));
- // recurse into children
- }
- else if (route.children) {
- res.push(this.processRoutes(ngModule, route.children));
- }
- }
- return from(res).pipe(mergeAll(), map((_) => void 0));
- }
- /**
- * @param {?} ngModule
- * @param {?} route
- * @return {?}
- */
- preloadConfig(ngModule, route) {
- return this.preloadingStrategy.preload(route, () => {
- /** @type {?} */
- const loaded$ = this.loader.load(ngModule.injector, route);
- return loaded$.pipe(mergeMap((config) => {
- route._loadedConfig = config;
- return this.processRoutes(config.module, config.routes);
- }));
- });
- }
- }
- RouterPreloader.decorators = [
- { type: Injectable }
- ];
- /** @nocollapse */
- RouterPreloader.ctorParameters = () => [
- { type: Router },
- { type: NgModuleFactoryLoader },
- { type: Compiler },
- { type: Injector },
- { type: PreloadingStrategy }
- ];
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- class RouterScroller {
- /**
- * @param {?} router
- * @param {?} viewportScroller
- * @param {?=} options
- */
- constructor(router, viewportScroller, options = {}) {
- this.router = router;
- this.viewportScroller = viewportScroller;
- this.options = options;
- this.lastId = 0;
- this.lastSource = 'imperative';
- this.restoredId = 0;
- this.store = {};
- // Default both options to 'disabled'
- options.scrollPositionRestoration = options.scrollPositionRestoration || 'disabled';
- options.anchorScrolling = options.anchorScrolling || 'disabled';
- }
- /**
- * @return {?}
- */
- init() {
- // we want to disable the automatic scrolling because having two places
- // responsible for scrolling results race conditions, especially given
- // that browser don't implement this behavior consistently
- if (this.options.scrollPositionRestoration !== 'disabled') {
- this.viewportScroller.setHistoryScrollRestoration('manual');
- }
- this.routerEventsSubscription = this.createScrollEvents();
- this.scrollEventsSubscription = this.consumeScrollEvents();
- }
- /**
- * @return {?}
- */
- createScrollEvents() {
- return this.router.events.subscribe(e => {
- if (e instanceof NavigationStart) {
- // store the scroll position of the current stable navigations.
- this.store[this.lastId] = this.viewportScroller.getScrollPosition();
- this.lastSource = e.navigationTrigger;
- this.restoredId = e.restoredState ? e.restoredState.navigationId : 0;
- }
- else if (e instanceof NavigationEnd) {
- this.lastId = e.id;
- this.scheduleScrollEvent(e, this.router.parseUrl(e.urlAfterRedirects).fragment);
- }
- });
- }
- /**
- * @return {?}
- */
- consumeScrollEvents() {
- return this.router.events.subscribe(e => {
- if (!(e instanceof Scroll))
- return;
- // a popstate event. The pop state event will always ignore anchor scrolling.
- if (e.position) {
- if (this.options.scrollPositionRestoration === 'top') {
- this.viewportScroller.scrollToPosition([0, 0]);
- }
- else if (this.options.scrollPositionRestoration === 'enabled') {
- this.viewportScroller.scrollToPosition(e.position);
- }
- // imperative navigation "forward"
- }
- else {
- if (e.anchor && this.options.anchorScrolling === 'enabled') {
- this.viewportScroller.scrollToAnchor(e.anchor);
- }
- else if (this.options.scrollPositionRestoration !== 'disabled') {
- this.viewportScroller.scrollToPosition([0, 0]);
- }
- }
- });
- }
- /**
- * @param {?} routerEvent
- * @param {?} anchor
- * @return {?}
- */
- scheduleScrollEvent(routerEvent, anchor) {
- this.router.triggerEvent(new Scroll(routerEvent, this.lastSource === 'popstate' ? this.store[this.restoredId] : null, anchor));
- }
- /**
- * @return {?}
- */
- ngOnDestroy() {
- if (this.routerEventsSubscription) {
- this.routerEventsSubscription.unsubscribe();
- }
- if (this.scrollEventsSubscription) {
- this.scrollEventsSubscription.unsubscribe();
- }
- }
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /** *
- * \@description
- *
- * Contains a list of directives
- *
- *
- @type {?} */
- const ROUTER_DIRECTIVES = [RouterOutlet, RouterLink, RouterLinkWithHref, RouterLinkActive, EmptyOutletComponent];
- /** *
- * \@description
- *
- * Is used in DI to configure the router.
- *
- * \@publicApi
- @type {?} */
- const ROUTER_CONFIGURATION = new InjectionToken('ROUTER_CONFIGURATION');
- /** *
- * \@docsNotRequired
- @type {?} */
- const ROUTER_FORROOT_GUARD = new InjectionToken('ROUTER_FORROOT_GUARD');
- /** @type {?} */
- const ROUTER_PROVIDERS = [
- Location,
- { provide: UrlSerializer, useClass: DefaultUrlSerializer },
- {
- provide: Router,
- useFactory: setupRouter,
- deps: [
- ApplicationRef, UrlSerializer, ChildrenOutletContexts, Location, Injector,
- NgModuleFactoryLoader, Compiler, ROUTES, ROUTER_CONFIGURATION,
- [UrlHandlingStrategy, new Optional()], [RouteReuseStrategy, new Optional()]
- ]
- },
- ChildrenOutletContexts,
- { provide: ActivatedRoute, useFactory: rootRoute, deps: [Router] },
- { provide: NgModuleFactoryLoader, useClass: SystemJsNgModuleLoader },
- RouterPreloader,
- NoPreloading,
- PreloadAllModules,
- { provide: ROUTER_CONFIGURATION, useValue: { enableTracing: false } },
- ];
- /**
- * @return {?}
- */
- function routerNgProbeToken() {
- return new NgProbeToken('Router', Router);
- }
- /**
- * \@usageNotes
- *
- * RouterModule can be imported multiple times: once per lazily-loaded bundle.
- * Since the router deals with a global shared resource--location, we cannot have
- * more than one router service active.
- *
- * That is why there are two ways to create the module: `RouterModule.forRoot` and
- * `RouterModule.forChild`.
- *
- * * `forRoot` creates a module that contains all the directives, the given routes, and the router
- * service itself.
- * * `forChild` creates a module that contains all the directives and the given routes, but does not
- * include the router service.
- *
- * When registered at the root, the module should be used as follows
- *
- * ```
- * \@NgModule({
- * imports: [RouterModule.forRoot(ROUTES)]
- * })
- * class MyNgModule {}
- * ```
- *
- * For submodules and lazy loaded submodules the module should be used as follows:
- *
- * ```
- * \@NgModule({
- * imports: [RouterModule.forChild(ROUTES)]
- * })
- * class MyNgModule {}
- * ```
- *
- * \@description
- *
- * Adds router directives and providers.
- *
- * Managing state transitions is one of the hardest parts of building applications. This is
- * especially true on the web, where you also need to ensure that the state is reflected in the URL.
- * In addition, we often want to split applications into multiple bundles and load them on demand.
- * Doing this transparently is not trivial.
- *
- * The Angular router solves these problems. Using the router, you can declaratively specify
- * application states, manage state transitions while taking care of the URL, and load bundles on
- * demand.
- *
- * [Read this developer guide](https://angular.io/docs/ts/latest/guide/router.html) to get an
- * overview of how the router should be used.
- *
- * \@publicApi
- */
- class RouterModule {
- /**
- * @param {?} guard
- * @param {?} router
- */
- constructor(guard, router) { }
- /**
- * Creates a module with all the router providers and directives. It also optionally sets up an
- * application listener to perform an initial navigation.
- *
- * Options (see `ExtraOptions`):
- * * `enableTracing` makes the router log all its internal events to the console.
- * * `useHash` enables the location strategy that uses the URL fragment instead of the history
- * API.
- * * `initialNavigation` disables the initial navigation.
- * * `errorHandler` provides a custom error handler.
- * * `preloadingStrategy` configures a preloading strategy (see `PreloadAllModules`).
- * * `onSameUrlNavigation` configures how the router handles navigation to the current URL. See
- * `ExtraOptions` for more details.
- * * `paramsInheritanceStrategy` defines how the router merges params, data and resolved data
- * from parent to child routes.
- * @param {?} routes
- * @param {?=} config
- * @return {?}
- */
- static forRoot(routes, config) {
- return {
- ngModule: RouterModule,
- providers: [
- ROUTER_PROVIDERS,
- provideRoutes(routes),
- {
- provide: ROUTER_FORROOT_GUARD,
- useFactory: provideForRootGuard,
- deps: [[Router, new Optional(), new SkipSelf()]]
- },
- { provide: ROUTER_CONFIGURATION, useValue: config ? config : {} },
- {
- provide: LocationStrategy,
- useFactory: provideLocationStrategy,
- deps: [
- PlatformLocation, [new Inject(APP_BASE_HREF), new Optional()], ROUTER_CONFIGURATION
- ]
- },
- {
- provide: RouterScroller,
- useFactory: createRouterScroller,
- deps: [Router, ViewportScroller, ROUTER_CONFIGURATION]
- },
- {
- provide: PreloadingStrategy,
- useExisting: config && config.preloadingStrategy ? config.preloadingStrategy :
- NoPreloading
- },
- { provide: NgProbeToken, multi: true, useFactory: routerNgProbeToken },
- provideRouterInitializer(),
- ],
- };
- }
- /**
- * Creates a module with all the router directives and a provider registering routes.
- * @param {?} routes
- * @return {?}
- */
- static forChild(routes) {
- return { ngModule: RouterModule, providers: [provideRoutes(routes)] };
- }
- }
- RouterModule.decorators = [
- { type: NgModule, args: [{
- declarations: ROUTER_DIRECTIVES,
- exports: ROUTER_DIRECTIVES,
- entryComponents: [EmptyOutletComponent]
- },] }
- ];
- /** @nocollapse */
- RouterModule.ctorParameters = () => [
- { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [ROUTER_FORROOT_GUARD,] }] },
- { type: Router, decorators: [{ type: Optional }] }
- ];
- /**
- * @param {?} router
- * @param {?} viewportScroller
- * @param {?} config
- * @return {?}
- */
- function createRouterScroller(router, viewportScroller, config) {
- if (config.scrollOffset) {
- viewportScroller.setOffset(config.scrollOffset);
- }
- return new RouterScroller(router, viewportScroller, config);
- }
- /**
- * @param {?} platformLocationStrategy
- * @param {?} baseHref
- * @param {?=} options
- * @return {?}
- */
- function provideLocationStrategy(platformLocationStrategy, baseHref, options = {}) {
- return options.useHash ? new HashLocationStrategy(platformLocationStrategy, baseHref) :
- new PathLocationStrategy(platformLocationStrategy, baseHref);
- }
- /**
- * @param {?} router
- * @return {?}
- */
- function provideForRootGuard(router) {
- if (router) {
- throw new Error(`RouterModule.forRoot() called twice. Lazy loaded modules should use RouterModule.forChild() instead.`);
- }
- return 'guarded';
- }
- /**
- * \@description
- *
- * Registers routes.
- *
- * \@usageNotes
- * ### Example
- *
- * ```
- * \@NgModule({
- * imports: [RouterModule.forChild(ROUTES)],
- * providers: [provideRoutes(EXTRA_ROUTES)]
- * })
- * class MyNgModule {}
- * ```
- *
- * \@publicApi
- * @param {?} routes
- * @return {?}
- */
- function provideRoutes(routes) {
- return [
- { provide: ANALYZE_FOR_ENTRY_COMPONENTS, multi: true, useValue: routes },
- { provide: ROUTES, multi: true, useValue: routes },
- ];
- }
- /**
- * @param {?} ref
- * @param {?} urlSerializer
- * @param {?} contexts
- * @param {?} location
- * @param {?} injector
- * @param {?} loader
- * @param {?} compiler
- * @param {?} config
- * @param {?=} opts
- * @param {?=} urlHandlingStrategy
- * @param {?=} routeReuseStrategy
- * @return {?}
- */
- function setupRouter(ref, urlSerializer, contexts, location, injector, loader, compiler, config, opts = {}, urlHandlingStrategy, routeReuseStrategy) {
- /** @type {?} */
- const router = new Router(null, urlSerializer, contexts, location, injector, loader, compiler, flatten(config));
- if (urlHandlingStrategy) {
- router.urlHandlingStrategy = urlHandlingStrategy;
- }
- if (routeReuseStrategy) {
- router.routeReuseStrategy = routeReuseStrategy;
- }
- if (opts.errorHandler) {
- router.errorHandler = opts.errorHandler;
- }
- if (opts.malformedUriErrorHandler) {
- router.malformedUriErrorHandler = opts.malformedUriErrorHandler;
- }
- if (opts.enableTracing) {
- /** @type {?} */
- const dom = ɵgetDOM();
- router.events.subscribe((e) => {
- dom.logGroup(`Router Event: ${((/** @type {?} */ (e.constructor))).name}`);
- dom.log(e.toString());
- dom.log(e);
- dom.logGroupEnd();
- });
- }
- if (opts.onSameUrlNavigation) {
- router.onSameUrlNavigation = opts.onSameUrlNavigation;
- }
- if (opts.paramsInheritanceStrategy) {
- router.paramsInheritanceStrategy = opts.paramsInheritanceStrategy;
- }
- if (opts.urlUpdateStrategy) {
- router.urlUpdateStrategy = opts.urlUpdateStrategy;
- }
- if (opts.relativeLinkResolution) {
- router.relativeLinkResolution = opts.relativeLinkResolution;
- }
- return router;
- }
- /**
- * @param {?} router
- * @return {?}
- */
- function rootRoute(router) {
- return router.routerState.root;
- }
- /**
- * To initialize the router properly we need to do in two steps:
- *
- * We need to start the navigation in a APP_INITIALIZER to block the bootstrap if
- * a resolver or a guards executes asynchronously. Second, we need to actually run
- * activation in a BOOTSTRAP_LISTENER. We utilize the afterPreactivation
- * hook provided by the router to do that.
- *
- * The router navigation starts, reaches the point when preactivation is done, and then
- * pauses. It waits for the hook to be resolved. We then resolve it only in a bootstrap listener.
- */
- class RouterInitializer {
- /**
- * @param {?} injector
- */
- constructor(injector) {
- this.injector = injector;
- this.initNavigation = false;
- this.resultOfPreactivationDone = new Subject();
- }
- /**
- * @return {?}
- */
- appInitializer() {
- /** @type {?} */
- const p = this.injector.get(LOCATION_INITIALIZED, Promise.resolve(null));
- return p.then(() => {
- /** @type {?} */
- let resolve = /** @type {?} */ ((null));
- /** @type {?} */
- const res = new Promise(r => resolve = r);
- /** @type {?} */
- const router = this.injector.get(Router);
- /** @type {?} */
- const opts = this.injector.get(ROUTER_CONFIGURATION);
- if (this.isLegacyDisabled(opts) || this.isLegacyEnabled(opts)) {
- resolve(true);
- }
- else if (opts.initialNavigation === 'disabled') {
- router.setUpLocationChangeListener();
- resolve(true);
- }
- else if (opts.initialNavigation === 'enabled') {
- router.hooks.afterPreactivation = () => {
- // only the initial navigation should be delayed
- if (!this.initNavigation) {
- this.initNavigation = true;
- resolve(true);
- return this.resultOfPreactivationDone;
- // subsequent navigations should not be delayed
- }
- else {
- return /** @type {?} */ (of(null));
- }
- };
- router.initialNavigation();
- }
- else {
- throw new Error(`Invalid initialNavigation options: '${opts.initialNavigation}'`);
- }
- return res;
- });
- }
- /**
- * @param {?} bootstrappedComponentRef
- * @return {?}
- */
- bootstrapListener(bootstrappedComponentRef) {
- /** @type {?} */
- const opts = this.injector.get(ROUTER_CONFIGURATION);
- /** @type {?} */
- const preloader = this.injector.get(RouterPreloader);
- /** @type {?} */
- const routerScroller = this.injector.get(RouterScroller);
- /** @type {?} */
- const router = this.injector.get(Router);
- /** @type {?} */
- const ref = this.injector.get(ApplicationRef);
- if (bootstrappedComponentRef !== ref.components[0]) {
- return;
- }
- if (this.isLegacyEnabled(opts)) {
- router.initialNavigation();
- }
- else if (this.isLegacyDisabled(opts)) {
- router.setUpLocationChangeListener();
- }
- preloader.setUpPreloading();
- routerScroller.init();
- router.resetRootComponentType(ref.componentTypes[0]);
- this.resultOfPreactivationDone.next(/** @type {?} */ ((null)));
- this.resultOfPreactivationDone.complete();
- }
- /**
- * @param {?} opts
- * @return {?}
- */
- isLegacyEnabled(opts) {
- return opts.initialNavigation === 'legacy_enabled' || opts.initialNavigation === true ||
- opts.initialNavigation === undefined;
- }
- /**
- * @param {?} opts
- * @return {?}
- */
- isLegacyDisabled(opts) {
- return opts.initialNavigation === 'legacy_disabled' || opts.initialNavigation === false;
- }
- }
- RouterInitializer.decorators = [
- { type: Injectable }
- ];
- /** @nocollapse */
- RouterInitializer.ctorParameters = () => [
- { type: Injector }
- ];
- /**
- * @param {?} r
- * @return {?}
- */
- function getAppInitializer(r) {
- return r.appInitializer.bind(r);
- }
- /**
- * @param {?} r
- * @return {?}
- */
- function getBootstrapListener(r) {
- return r.bootstrapListener.bind(r);
- }
- /** *
- * A token for the router initializer that will be called after the app is bootstrapped.
- *
- * \@publicApi
- @type {?} */
- const ROUTER_INITIALIZER = new InjectionToken('Router Initializer');
- /**
- * @return {?}
- */
- function provideRouterInitializer() {
- return [
- RouterInitializer,
- {
- provide: APP_INITIALIZER,
- multi: true,
- useFactory: getAppInitializer,
- deps: [RouterInitializer]
- },
- { provide: ROUTER_INITIALIZER, useFactory: getBootstrapListener, deps: [RouterInitializer] },
- { provide: APP_BOOTSTRAP_LISTENER, multi: true, useExisting: ROUTER_INITIALIZER },
- ];
- }
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /** *
- * \@publicApi
- @type {?} */
- const VERSION = new Version('7.0.3');
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- // This file only reexports content of the `src` folder. Keep it that way.
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
- */
- /**
- * Generated bundle index. Do not edit.
- */
- export { ROUTER_FORROOT_GUARD as ɵangular_packages_router_router_a, RouterInitializer as ɵangular_packages_router_router_h, createRouterScroller as ɵangular_packages_router_router_c, getAppInitializer as ɵangular_packages_router_router_i, getBootstrapListener as ɵangular_packages_router_router_j, provideForRootGuard as ɵangular_packages_router_router_e, provideLocationStrategy as ɵangular_packages_router_router_d, provideRouterInitializer as ɵangular_packages_router_router_k, rootRoute as ɵangular_packages_router_router_g, routerNgProbeToken as ɵangular_packages_router_router_b, setupRouter as ɵangular_packages_router_router_f, RouterScroller as ɵangular_packages_router_router_n, Tree as ɵangular_packages_router_router_l, TreeNode as ɵangular_packages_router_router_m, RouterLink, RouterLinkWithHref, RouterLinkActive, RouterOutlet, ActivationEnd, ActivationStart, ChildActivationEnd, ChildActivationStart, GuardsCheckEnd, GuardsCheckStart, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RouterEvent, RoutesRecognized, Scroll, 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 };
- //# sourceMappingURL=router.js.map
|