217 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			217 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
export * from '@angular/router';
 | 
						|
 | 
						|
import { Directive, DynamicComponentLoader, ViewContainerRef,
 | 
						|
         Injectable, Optional, Input } from '@angular/core';
 | 
						|
 | 
						|
import { ComponentInstruction, Instruction,
 | 
						|
         Router, RouterOutlet} from '@angular/router';
 | 
						|
 | 
						|
let _resolveToTrue = Promise.resolve(true);
 | 
						|
 | 
						|
const NOT_IMPLEMENTED = (what: string) => {
 | 
						|
  throw new Error (`"${what}" is not implemented`);
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
@Directive({
 | 
						|
  selector: '[routerLink]',
 | 
						|
  host: {
 | 
						|
    '(click)': 'onClick()',
 | 
						|
    '[attr.href]': 'visibleHref',
 | 
						|
    '[class.router-link-active]': 'isRouteActive'
 | 
						|
  }
 | 
						|
})
 | 
						|
export class MockRouterLink  {
 | 
						|
 | 
						|
  isRouteActive = false;
 | 
						|
  visibleHref: string; // the url displayed on the anchor element.
 | 
						|
 | 
						|
  @Input('routerLink') routeParams: any[];
 | 
						|
  @Input() target: string;
 | 
						|
  navigatedTo: any[] = null;
 | 
						|
 | 
						|
  constructor(public router: Router) { }
 | 
						|
 | 
						|
  onClick() {
 | 
						|
    this.navigatedTo = null;
 | 
						|
 | 
						|
    // If no target, or if target is _self, prevent default browser behavior
 | 
						|
    if (!this.target || typeof this.target !== 'string' || this.target === '_self') {
 | 
						|
      this.navigatedTo = this.routeParams;
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
@Directive({selector: 'router-outlet'})
 | 
						|
export class MockRouterOutlet extends RouterOutlet {
 | 
						|
  name: string = null;
 | 
						|
 | 
						|
  constructor(
 | 
						|
    _viewContainerRef: ViewContainerRef,
 | 
						|
    @Optional() _loader: DynamicComponentLoader,
 | 
						|
    _parentRouter: Router,
 | 
						|
    nameAttr: string) {
 | 
						|
    super(_viewContainerRef, _loader, _parentRouter, nameAttr);
 | 
						|
      if (nameAttr) {
 | 
						|
        this.name = nameAttr;
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Called by the Router to instantiate a new component during the commit phase of a navigation.
 | 
						|
   * This method in turn is responsible for calling the `routerOnActivate` hook of its child.
 | 
						|
   */
 | 
						|
  activate(nextInstruction: ComponentInstruction): Promise<any> { NOT_IMPLEMENTED('activate'); return _resolveToTrue; }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Called by the {@link Router} during the commit phase of a navigation when an outlet
 | 
						|
   * reuses a component between different routes.
 | 
						|
   * This method in turn is responsible for calling the `routerOnReuse` hook of its child.
 | 
						|
   */
 | 
						|
  reuse(nextInstruction: ComponentInstruction): Promise<any> { NOT_IMPLEMENTED('reuse'); return _resolveToTrue; }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Called by the {@link Router} when an outlet disposes of a component's contents.
 | 
						|
   * This method in turn is responsible for calling the `routerOnDeactivate` hook of its child.
 | 
						|
   */
 | 
						|
  deactivate(nextInstruction: ComponentInstruction): Promise<any> { NOT_IMPLEMENTED('deactivate'); return _resolveToTrue; }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Called by the {@link Router} during recognition phase of a navigation.
 | 
						|
   *
 | 
						|
   * If this resolves to `false`, the given navigation is cancelled.
 | 
						|
   *
 | 
						|
   * This method delegates to the child component's `routerCanDeactivate` hook if it exists,
 | 
						|
   * and otherwise resolves to true.
 | 
						|
   */
 | 
						|
  routerCanDeactivate(nextInstruction: ComponentInstruction): Promise<any> {
 | 
						|
    NOT_IMPLEMENTED('routerCanDeactivate'); return _resolveToTrue;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Called by the {@link Router} during recognition phase of a navigation.
 | 
						|
   *
 | 
						|
   * If the new child component has a different Type than the existing child component,
 | 
						|
   * this will resolve to `false`. You can't reuse an old component when the new component
 | 
						|
   * is of a different Type.
 | 
						|
   *
 | 
						|
   * Otherwise, this method delegates to the child component's `routerCanReuse` hook if it exists,
 | 
						|
   * or resolves to true if the hook is not present.
 | 
						|
   */
 | 
						|
  routerCanReuse(nextInstruction: ComponentInstruction): Promise<any> { NOT_IMPLEMENTED('routerCanReuse'); return _resolveToTrue; }
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
@Injectable()
 | 
						|
export class MockRouter extends Router {
 | 
						|
 | 
						|
  mockIsRouteActive = false;
 | 
						|
  mockRecognizedInstruction: Instruction;
 | 
						|
  outlet: RouterOutlet = null;
 | 
						|
 | 
						|
  constructor() {
 | 
						|
    super(null, null, null, null);
 | 
						|
  }
 | 
						|
 | 
						|
  auxRouter(hostComponent: any): Router { return new MockChildRouter(this, hostComponent); }
 | 
						|
  childRouter(hostComponent: any): Router { return new MockChildRouter(this, hostComponent); }
 | 
						|
 | 
						|
  commit(instruction: Instruction, _skipLocationChange = false): Promise<any> {
 | 
						|
    NOT_IMPLEMENTED('commit'); return _resolveToTrue;
 | 
						|
  }
 | 
						|
 | 
						|
  deactivate(instruction: Instruction, _skipLocationChange = false): Promise<any> {
 | 
						|
    NOT_IMPLEMENTED('deactivate'); return _resolveToTrue;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Generate an `Instruction` based on the provided Route Link DSL.
 | 
						|
   */
 | 
						|
  generate(linkParams: any[]): Instruction {
 | 
						|
    NOT_IMPLEMENTED('generate');  return null;
 | 
						|
  }
 | 
						|
 | 
						|
  isRouteActive(instruction: Instruction): boolean { return this.mockIsRouteActive; }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Navigate based on the provided Route Link DSL. It's preferred to navigate with this method
 | 
						|
   * over `navigateByUrl`.
 | 
						|
   *
 | 
						|
   * ### Usage
 | 
						|
   *
 | 
						|
   * This method takes an array representing the Route Link DSL:
 | 
						|
   * ```
 | 
						|
   * ['./MyCmp', {param: 3}]
 | 
						|
   * ```
 | 
						|
   * See the {@link RouterLink} directive for more.
 | 
						|
   */
 | 
						|
  navigate(linkParams: any[]): Promise<any> {
 | 
						|
    return Promise.resolve(linkParams);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Navigate to a URL. Returns a promise that resolves when navigation is complete.
 | 
						|
   * It's preferred to navigate with `navigate` instead of this method, since URLs are more brittle.
 | 
						|
   *
 | 
						|
   * If the given URL begins with a `/`, router will navigate absolutely.
 | 
						|
   * If the given URL does not begin with `/`, the router will navigate relative to this component.
 | 
						|
   */
 | 
						|
  navigateByUrl(url: string, _skipLocationChange = false): Promise<any> {
 | 
						|
    return Promise.resolve(url);
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  /**
 | 
						|
   * Navigate via the provided instruction. Returns a promise that resolves when navigation is
 | 
						|
   * complete.
 | 
						|
   */
 | 
						|
  navigateByInstruction(instruction: Instruction, _skipLocationChange = false): Promise<any> {
 | 
						|
    return Promise.resolve(instruction);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Subscribe to URL updates from the router
 | 
						|
   */
 | 
						|
  subscribe(onNext: (v: any) => void, onError?: (v: any) => void) {
 | 
						|
    return {onNext, onError};
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Given a URL, returns an instruction representing the component graph
 | 
						|
   */
 | 
						|
  recognize(url: string): Promise<Instruction> {
 | 
						|
    return Promise.resolve(this.mockRecognizedInstruction);
 | 
						|
  }
 | 
						|
 | 
						|
  registerPrimaryOutlet(outlet: RouterOutlet): Promise<any> {
 | 
						|
    this.outlet = outlet;
 | 
						|
    return super.registerPrimaryOutlet(outlet);
 | 
						|
  }
 | 
						|
 | 
						|
  unregisterPrimaryOutlet(outlet: RouterOutlet) {
 | 
						|
    super.unregisterPrimaryOutlet(outlet);
 | 
						|
    this.outlet = null;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
class MockChildRouter extends MockRouter {
 | 
						|
  constructor(parent: MockRouter, hostComponent: any) {
 | 
						|
    super();
 | 
						|
    this.parent = parent;
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  navigateByUrl(url: string, _skipLocationChange = false): Promise<any> {
 | 
						|
    // Delegate navigation to the root router
 | 
						|
    return this.parent.navigateByUrl(url, _skipLocationChange);
 | 
						|
  }
 | 
						|
 | 
						|
  navigateByInstruction(instruction: Instruction, _skipLocationChange = false):
 | 
						|
      Promise<any> {
 | 
						|
    // Delegate navigation to the root router
 | 
						|
    return this.parent.navigateByInstruction(instruction, _skipLocationChange);
 | 
						|
  }
 | 
						|
}
 |