import { getOwner } from '@ember/application' ; import { action } from '@ember/object' ; import { addListener , removeListener } from '@ember/object/events' ; import RouteInfo from '@ember/routing/-private/route-info' ; import Transition from '@ember/routing/-private/transition' ; import RouterService from '@ember/routing/router-service' ; import Service , { inject as service } from '@ember/service' ; import { tracked } from '@glimmer/tracking' ; import Link , { LinkParams , UILinkParams , UILink } from '../link' ; interface RouterServiceWithRecognize extends RouterService { recognize ( url ) : RouteInfo ; } export default class LinkManagerService extends Service { @ tracked private _currentTransitionStack ? : Transition [ ] ; /**
     * The `RouterService` instance to be used by the generated `Link` instances.
     */ @ service ( 'router' ) readonly router ! : RouterServiceWithRecognize ; see https get isRouterInitialized ( ) { return Boolean ( getOwner ( this ) . lookup ( 'router:main' ) . currentURL ) ; } /**
     * The currently active `Transition` objects.
     */ get currentTransitionStack ( ) { return this . _currentTransitionStack ; } /**
     * Creates a `Link` instance.
     */ createLink ( linkParams ) { return new Link ( this , linkParams ) ; } /**
     * Creates a `UILink` instance.
     */ createUILink ( linkParams , uiParams ? ) { return new UILink ( this , { ... linkParams , ... uiParams } ) ; } /**
     * Deserializes the `LinkParams` to be passed to `createLink` / `createUILink`
     * from a URL.
     *
     * If the URL cannot be recognized by the router, an error is thrown.
     */ getLinkParamsFromURL ( url ) { const routeInfo = this . router . recognize ( url ) ; return LinkManagerService . getLinkParamsFromRouteInfo ( routeInfo ) ; } /**
     * Converts a `RouteInfo` object into `LinkParams`.
     */ static getLinkParamsFromRouteInfo ( routeInfo ) { const models = routeInfo . paramNames . map ( name => routeInfo . params [ name ] ! ) ; return { route : routeInfo . name , query : routeInfo . queryParams , models } ; } constructor ( properties ? ) { super ( properties ) ; addListener ( this . router , 'routeWillChange' , this . handleRouteWillChange ) ; addListener ( this . router , 'routeDidChange' , this . handleRouteDidChange ) ; } willDestroy ( ) { super . willDestroy ( ) ; removeListener ( this . router , 'routeWillChange' , this . handleRouteWillChange ) ; removeListener ( this . router , 'routeDidChange' , this . handleRouteDidChange ) ; } @ action handleRouteWillChange ( transition ) { this . _currentTransitionStack = [ ... ( this . _currentTransitionStack || [ ] ) , transition ] ; } @ action handleRouteDidChange ( ) { this . _currentTransitionStack = undefined ; } } declare module '@ember/service' { interface Registry { 'link-manager' : LinkManagerService ; } }