diff --git a/modules/@angular/router/src/common_router_providers.ts b/modules/@angular/router/src/common_router_providers.ts index 7c25921611..70abba7915 100644 --- a/modules/@angular/router/src/common_router_providers.ts +++ b/modules/@angular/router/src/common_router_providers.ts @@ -1,10 +1,12 @@ -import { RouterOutletMap } from './router_outlet_map'; -import { UrlSerializer, DefaultUrlSerializer } from './url_serializer'; -import { ActivatedRoute } from './router_state'; -import { Router } from './router'; -import { RouterConfig } from './config'; -import { ComponentResolver, ApplicationRef, Injector, APP_INITIALIZER } from '@angular/core'; -import { LocationStrategy, PathLocationStrategy, Location } from '@angular/common'; +import {Location, LocationStrategy, PathLocationStrategy} from '@angular/common'; +import {APP_INITIALIZER, ApplicationRef, ComponentResolver, Injector} from '@angular/core'; + +import {RouterConfig} from './config'; +import {Router} from './router'; +import {RouterOutletMap} from './router_outlet_map'; +import {ActivatedRoute} from './router_state'; +import {DefaultUrlSerializer, UrlSerializer} from './url_serializer'; + /** * A list of {@link Provider}s. To use the router, you must add this to your application. @@ -24,7 +26,7 @@ import { LocationStrategy, PathLocationStrategy, Location } from '@angular/commo * bootstrap(AppCmp, [provideRouter(router)]); * ``` */ -export function provideRouter(config: RouterConfig):any[] { +export function provideRouter(config: RouterConfig): any[] { return [ Location, {provide: LocationStrategy, useClass: PathLocationStrategy}, @@ -34,20 +36,27 @@ export function provideRouter(config: RouterConfig):any[] { provide: Router, useFactory: (ref, resolver, urlSerializer, outletMap, location, injector) => { if (ref.componentTypes.length == 0) { - throw new Error("Bootstrap at least one component before injecting Router."); + throw new Error('Bootstrap at least one component before injecting Router.'); } const componentType = ref.componentTypes[0]; - const r = new Router(componentType, resolver, urlSerializer, outletMap, location, injector, config); + const r = new Router( + componentType, resolver, urlSerializer, outletMap, location, injector, config); ref.registerDisposeListener(() => r.dispose()); return r; }, - deps: [ApplicationRef, ComponentResolver, UrlSerializer, RouterOutletMap, Location, Injector] + deps: + [ApplicationRef, ComponentResolver, UrlSerializer, RouterOutletMap, Location, Injector] }, RouterOutletMap, {provide: ActivatedRoute, useFactory: (r) => r.routerState.root, deps: [Router]}, - + // Trigger initial navigation - {provide: APP_INITIALIZER, multi: true, useFactory: (router: Router) => router.initialNavigation(), deps: [Router]}, + { + provide: APP_INITIALIZER, + multi: true, + useFactory: (router: Router) => router.initialNavigation(), + deps: [Router] + }, ]; } diff --git a/modules/@angular/router/src/config.ts b/modules/@angular/router/src/config.ts index a7c60d3c00..d8b959e065 100644 --- a/modules/@angular/router/src/config.ts +++ b/modules/@angular/router/src/config.ts @@ -1,11 +1,11 @@ -import { Type } from '@angular/core'; +import {Type} from '@angular/core'; export type RouterConfig = Route[]; export interface Route { index?: boolean; path?: string; - component: Type | string; + component: Type|string; outlet?: string; canActivate?: any[]; canDeactivate?: any[]; diff --git a/modules/@angular/router/src/create_router_state.ts b/modules/@angular/router/src/create_router_state.ts index 178fc13f7a..3037ab2b7c 100644 --- a/modules/@angular/router/src/create_router_state.ts +++ b/modules/@angular/router/src/create_router_state.ts @@ -1,6 +1,7 @@ -import { RouterStateSnapshot, ActivatedRouteSnapshot, RouterState, ActivatedRoute } from './router_state'; -import { TreeNode } from './utils/tree'; -import { BehaviorSubject } from 'rxjs/BehaviorSubject'; +import {BehaviorSubject} from 'rxjs/BehaviorSubject'; + +import {ActivatedRoute, ActivatedRouteSnapshot, RouterState, RouterStateSnapshot} from './router_state'; +import {TreeNode} from './utils/tree'; export function createRouterState(curr: RouterStateSnapshot, prevState: RouterState): RouterState { const root = createNode(curr._root, prevState ? prevState._root : undefined); @@ -9,11 +10,12 @@ export function createRouterState(curr: RouterStateSnapshot, prevState: RouterSt return new RouterState(root, queryParams, fragment, curr); } -function createNode(curr:TreeNode, prevState?:TreeNode):TreeNode { +function createNode(curr: TreeNode, prevState?: TreeNode): + TreeNode { if (prevState && equalRouteSnapshots(prevState.value.snapshot, curr.value)) { const value = prevState.value; value._futureSnapshot = curr.value; - + const children = createOrReuseChildren(curr, prevState); return new TreeNode(value, children); @@ -24,9 +26,11 @@ function createNode(curr:TreeNode, prevState?:TreeNode, prevState:TreeNode) { +function createOrReuseChildren( + curr: TreeNode, prevState: TreeNode) { return curr.children.map(child => { - const index = prevState.children.findIndex(p => equalRouteSnapshots(p.value.snapshot, child.value)); + const index = + prevState.children.findIndex(p => equalRouteSnapshots(p.value.snapshot, child.value)); if (index >= 0) { return createNode(child, prevState.children[index]); } else { @@ -35,8 +39,9 @@ function createOrReuseChildren(curr:TreeNode, prevState: }); } -function createActivatedRoute(c:ActivatedRouteSnapshot) { - return new ActivatedRoute(new BehaviorSubject(c.urlSegments), new BehaviorSubject(c.params), c.outlet, c.component, c); +function createActivatedRoute(c: ActivatedRouteSnapshot) { + return new ActivatedRoute( + new BehaviorSubject(c.urlSegments), new BehaviorSubject(c.params), c.outlet, c.component, c); } function equalRouteSnapshots(a: ActivatedRouteSnapshot, b: ActivatedRouteSnapshot): boolean { diff --git a/modules/@angular/router/src/create_url_tree.ts b/modules/@angular/router/src/create_url_tree.ts index 31d226a3d4..e037a2e708 100644 --- a/modules/@angular/router/src/create_url_tree.ts +++ b/modules/@angular/router/src/create_url_tree.ts @@ -1,11 +1,12 @@ -import { UrlTree, UrlSegment, equalUrlSegments } from './url_tree'; -import { TreeNode } from './utils/tree'; -import { forEach, shallowEqual } from './utils/collection'; -import { RouterState, ActivatedRoute } from './router_state'; -import { Params, PRIMARY_OUTLET } from './shared'; +import {ActivatedRoute} from './router_state'; +import {PRIMARY_OUTLET, Params} from './shared'; +import {UrlSegment, UrlTree} from './url_tree'; +import {forEach, shallowEqual} from './utils/collection'; +import {TreeNode} from './utils/tree'; -export function createUrlTree(route: ActivatedRoute, urlTree: UrlTree, commands: any[], - queryParams: Params | undefined, fragment: string | undefined): UrlTree { +export function createUrlTree( + route: ActivatedRoute, urlTree: UrlTree, commands: any[], queryParams: Params | undefined, + fragment: string | undefined): UrlTree { if (commands.length === 0) { return tree(urlTree._root, urlTree, queryParams, fragment); } @@ -24,7 +25,9 @@ export function createUrlTree(route: ActivatedRoute, urlTree: UrlTree, commands: return tree(newRoot, urlTree, queryParams, fragment); } -function tree(root: TreeNode, urlTree: UrlTree, queryParams: Params | undefined, fragment: string | undefined): UrlTree { +function tree( + root: TreeNode, urlTree: UrlTree, queryParams: Params | undefined, + fragment: string | undefined): UrlTree { const q = queryParams ? stringify(queryParams) : urlTree.queryParams; const f = fragment ? fragment : urlTree.fragment; return new UrlTree(root, q, f); @@ -32,16 +35,16 @@ function tree(root: TreeNode, urlTree: UrlTree, queryParams: Params function navigateToRoot(normalizedChange: NormalizedNavigationCommands): boolean { return normalizedChange.isAbsolute && normalizedChange.commands.length === 1 && - normalizedChange.commands[0] == "/"; + normalizedChange.commands[0] == '/'; } class NormalizedNavigationCommands { - constructor(public isAbsolute: boolean, public numberOfDoubleDots: number, - public commands: any[]) {} + constructor( + public isAbsolute: boolean, public numberOfDoubleDots: number, public commands: any[]) {} } function normalizeCommands(commands: any[]): NormalizedNavigationCommands { - if ((typeof commands[0] === "string") && commands.length === 1 && commands[0] == "/") { + if ((typeof commands[0] === 'string') && commands.length === 1 && commands[0] == '/') { return new NormalizedNavigationCommands(true, 0, commands); } @@ -52,7 +55,7 @@ function normalizeCommands(commands: any[]): NormalizedNavigationCommands { for (let i = 0; i < commands.length; ++i) { const c = commands[i]; - if (!(typeof c === "string")) { + if (!(typeof c === 'string')) { res.push(c); continue; } @@ -63,11 +66,11 @@ function normalizeCommands(commands: any[]): NormalizedNavigationCommands { // first exp is treated in a special way if (i == 0) { - if (j == 0 && cc == ".") { // './a' + if (j == 0 && cc == '.') { // './a' // skip it - } else if (j == 0 && cc == "") { // '/a' + } else if (j == 0 && cc == '') { // '/a' isAbsolute = true; - } else if (cc == "..") { // '../a' + } else if (cc == '..') { // '../a' numberOfDoubleDots++; } else if (cc != '') { res.push(cc); @@ -84,22 +87,23 @@ function normalizeCommands(commands: any[]): NormalizedNavigationCommands { return new NormalizedNavigationCommands(isAbsolute, numberOfDoubleDots, res); } -function findStartingNode(normalizedChange: NormalizedNavigationCommands, urlTree: UrlTree, - route: ActivatedRoute): TreeNode { +function findStartingNode( + normalizedChange: NormalizedNavigationCommands, urlTree: UrlTree, + route: ActivatedRoute): TreeNode { if (normalizedChange.isAbsolute) { return urlTree._root; } else { - const urlSegment = - findUrlSegment(route, urlTree, normalizedChange.numberOfDoubleDots); + const urlSegment = findUrlSegment(route, urlTree, normalizedChange.numberOfDoubleDots); return findMatchingNode(urlSegment, urlTree._root); } } -function findUrlSegment(route: ActivatedRoute, urlTree: UrlTree, numberOfDoubleDots: number): UrlSegment { +function findUrlSegment( + route: ActivatedRoute, urlTree: UrlTree, numberOfDoubleDots: number): UrlSegment { const urlSegment = route.snapshot._lastUrlSegment; const path = urlTree.pathFromRoot(urlSegment); if (path.length <= numberOfDoubleDots) { - throw new Error("Invalid number of '../'"); + throw new Error('Invalid number of \'../\''); } return path[path.length - 1 - numberOfDoubleDots]; } @@ -113,13 +117,14 @@ function findMatchingNode(segment: UrlSegment, node: TreeNode): Tree throw new Error(`Cannot find url segment '${segment}'`); } -function constructNewTree(node: TreeNode, original: TreeNode, - updated: TreeNode[]): TreeNode { +function constructNewTree( + node: TreeNode, original: TreeNode, + updated: TreeNode[]): TreeNode { if (node === original) { return new TreeNode(node.value, updated); } else { return new TreeNode( - node.value, node.children.map(c => constructNewTree(c, original, updated))); + node.value, node.children.map(c => constructNewTree(c, original, updated))); } } @@ -136,18 +141,18 @@ function updateMany(nodes: TreeNode[], commands: any[]): TreeNode 1 ? parts[1] : commands[0]; } function getOutlet(commands: any[]): string { - if (!(typeof commands[0] === "string")) return PRIMARY_OUTLET; - const parts = commands[0].toString().split(":"); + if (!(typeof commands[0] === 'string')) return PRIMARY_OUTLET; + const parts = commands[0].toString().split(':'); return parts.length > 1 ? parts[0] : PRIMARY_OUTLET; } -function update(node: TreeNode|null, commands: any[]): TreeNode { +function update(node: TreeNode| null, commands: any[]): TreeNode { const rest = commands.slice(1); const next = rest.length === 0 ? null : rest[0]; const outlet = getOutlet(commands); @@ -202,8 +207,8 @@ function compare(path: string, params: {[key: string]: any}, segment: UrlSegment return path == segment.path && shallowEqual(params, segment.parameters); } -function recurse(urlSegment: UrlSegment, node: TreeNode | null, - rest: any[]): TreeNode { +function recurse( + urlSegment: UrlSegment, node: TreeNode| null, rest: any[]): TreeNode { if (rest.length === 0) { return new TreeNode(urlSegment, []); } diff --git a/modules/@angular/router/src/directives/router_link.ts b/modules/@angular/router/src/directives/router_link.ts index c117784f99..5c86187314 100644 --- a/modules/@angular/router/src/directives/router_link.ts +++ b/modules/@angular/router/src/directives/router_link.ts @@ -1,13 +1,9 @@ -import { - Directive, - HostListener, - HostBinding, - Input, - OnChanges -} from '@angular/core'; +import {Directive, HostBinding, HostListener, Input, OnChanges} from '@angular/core'; + import {Router} from '../router'; import {ActivatedRoute} from '../router_state'; + /** * The RouterLink directive lets you link to specific parts of your app. * @@ -37,7 +33,7 @@ import {ActivatedRoute} from '../router_state'; export class RouterLink implements OnChanges { @Input() target: string; private commands: any[] = []; - @Input() queryParams: {[k:string]:any}; + @Input() queryParams: {[k: string]: any}; @Input() fragment: string; // the url displayed on the anchor element. @@ -49,7 +45,7 @@ export class RouterLink implements OnChanges { constructor(private router: Router, private route: ActivatedRoute) {} @Input() - set routerLink(data: any[] | string) { + set routerLink(data: any[]|string) { if (Array.isArray(data)) { this.commands = data; } else { @@ -57,30 +53,24 @@ export class RouterLink implements OnChanges { } } - ngOnChanges(changes:{}):any { - this.updateTargetUrlAndHref(); - } + ngOnChanges(changes: {}): any { this.updateTargetUrlAndHref(); } - @HostListener("click") + @HostListener('click') onClick(): boolean { // If no target, or if target is _self, prevent default browser behavior - if (!(typeof this.target === "string") || this.target == '_self') { - this.router.navigate(this.commands, { - relativeTo: this.route, - queryParams: this.queryParams, - fragment: this.fragment - }); + if (!(typeof this.target === 'string') || this.target == '_self') { + this.router.navigate( + this.commands, + {relativeTo: this.route, queryParams: this.queryParams, fragment: this.fragment}); return false; } return true; } private updateTargetUrlAndHref(): void { - const tree = this.router.createUrlTree(this.commands, { - relativeTo: this.route, - queryParams: this.queryParams, - fragment: this.fragment - }); + const tree = this.router.createUrlTree( + this.commands, + {relativeTo: this.route, queryParams: this.queryParams, fragment: this.fragment}); if (tree) { this.href = this.router.serializeUrl(tree); } diff --git a/modules/@angular/router/src/directives/router_outlet.ts b/modules/@angular/router/src/directives/router_outlet.ts index dfa2e670d6..99eb1daea6 100644 --- a/modules/@angular/router/src/directives/router_outlet.ts +++ b/modules/@angular/router/src/directives/router_outlet.ts @@ -1,23 +1,24 @@ -import {Injector, Directive, ViewContainerRef, Attribute, ComponentRef, ComponentFactory, ResolvedReflectiveProvider, ReflectiveInjector} from '@angular/core'; -import {RouterOutletMap} from '../router_outlet_map'; -import {PRIMARY_OUTLET} from '../shared'; +import {Attribute, ComponentFactory, ComponentRef, Directive, ReflectiveInjector, ResolvedReflectiveProvider, ViewContainerRef} from "@angular/core"; +import {RouterOutletMap} from "../router_outlet_map"; +import {PRIMARY_OUTLET} from "../shared"; @Directive({selector: 'router-outlet'}) export class RouterOutlet { - private activated:ComponentRef|null; - public outletMap:RouterOutletMap; + private activated: ComponentRef|null; + public outletMap: RouterOutletMap; /** * @internal */ - constructor(parentOutletMap:RouterOutletMap, private location:ViewContainerRef, - @Attribute('name') name:string) { + constructor( + parentOutletMap: RouterOutletMap, private location: ViewContainerRef, + @Attribute('name') name: string) { parentOutletMap.registerOutlet(name ? name : PRIMARY_OUTLET, this); } get isActivated(): boolean { return !!this.activated; } get component(): Object { - if (!this.activated) throw new Error("Outlet is not activated"); + if (!this.activated) throw new Error('Outlet is not activated'); return this.activated.instance; } @@ -28,8 +29,9 @@ export class RouterOutlet { } } - activate(factory: ComponentFactory, providers: ResolvedReflectiveProvider[], - outletMap: RouterOutletMap): void { + activate( + factory: ComponentFactory, providers: ResolvedReflectiveProvider[], + outletMap: RouterOutletMap): void { this.outletMap = outletMap; const inj = ReflectiveInjector.fromResolvedProviders(providers, this.location.parentInjector); this.activated = this.location.createComponent(factory, this.location.length, inj, []); diff --git a/modules/@angular/router/src/index.ts b/modules/@angular/router/src/index.ts index f19b56456b..95c089547b 100644 --- a/modules/@angular/router/src/index.ts +++ b/modules/@angular/router/src/index.ts @@ -1,14 +1,14 @@ -export { Router, Event, NavigationStart, NavigationEnd, NavigationCancel, NavigationError } from './router'; -export { UrlSerializer, DefaultUrlSerializer } from './url_serializer'; -export { RouterState, ActivatedRoute, RouterStateSnapshot, ActivatedRouteSnapshot } from './router_state'; -export { UrlTree, UrlSegment} from './url_tree'; -export { RouterOutletMap } from './router_outlet_map'; -export { RouterConfig, Route } from './config'; -export { Params, PRIMARY_OUTLET } from './shared'; -export { provideRouter } from './router_providers'; -export { CanActivate, CanDeactivate } from './interfaces'; +import {RouterLink} from './directives/router_link'; +import {RouterOutlet} from './directives/router_outlet'; -import { RouterOutlet } from './directives/router_outlet'; -import { RouterLink } from './directives/router_link'; +export {Route, RouterConfig} from './config'; +export {CanActivate, CanDeactivate} from './interfaces'; +export {Event, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, Router} from './router'; +export {RouterOutletMap} from './router_outlet_map'; +export {provideRouter} from './router_providers'; +export {ActivatedRoute, ActivatedRouteSnapshot, RouterState, RouterStateSnapshot} from './router_state'; +export {PRIMARY_OUTLET, Params} from './shared'; +export {DefaultUrlSerializer, UrlSerializer} from './url_serializer'; +export {UrlSegment, UrlTree} from './url_tree'; export const ROUTER_DIRECTIVES = [RouterOutlet, RouterLink]; \ No newline at end of file diff --git a/modules/@angular/router/src/interfaces.ts b/modules/@angular/router/src/interfaces.ts index e271070155..355969ad30 100644 --- a/modules/@angular/router/src/interfaces.ts +++ b/modules/@angular/router/src/interfaces.ts @@ -5,12 +5,14 @@ import {ActivatedRouteSnapshot, RouterStateSnapshot} from './router_state'; * An interface a class can implement to be a guard deciding if a route can be activated. */ export interface CanActivate { - canActivate(route:ActivatedRouteSnapshot, state:RouterStateSnapshot):Observable | boolean; + canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): + Observable|boolean; } /** * An interface a class can implement to be a guard deciding if a route can be deactivated. */ export interface CanDeactivate { - canDeactivate(component:T, route:ActivatedRouteSnapshot, state:RouterStateSnapshot):Observable | boolean; + canDeactivate(component: T, route: ActivatedRouteSnapshot, state: RouterStateSnapshot): + Observable|boolean; } \ No newline at end of file diff --git a/modules/@angular/router/src/recognize.ts b/modules/@angular/router/src/recognize.ts index 745de2bfeb..e78a51f3ce 100644 --- a/modules/@angular/router/src/recognize.ts +++ b/modules/@angular/router/src/recognize.ts @@ -1,26 +1,31 @@ -import { UrlTree, UrlSegment } from './url_tree'; -import { flatten, first, merge } from './utils/collection'; -import { TreeNode } from './utils/tree'; -import { RouterStateSnapshot, ActivatedRouteSnapshot } from './router_state'; -import { PRIMARY_OUTLET } from './shared'; -import { RouterConfig, Route } from './config'; -import { Type } from '@angular/core'; -import { Observable } from 'rxjs/Observable'; +import {Type} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; + +import {Route, RouterConfig} from './config'; +import {ActivatedRouteSnapshot, RouterStateSnapshot} from './router_state'; +import {PRIMARY_OUTLET} from './shared'; +import {UrlSegment, UrlTree} from './url_tree'; +import {first, flatten, merge} from './utils/collection'; +import {TreeNode} from './utils/tree'; class CannotRecognize {} -export function recognize(rootComponentType: Type, config: RouterConfig, url: UrlTree): Observable { +export function recognize( + rootComponentType: Type, config: RouterConfig, url: UrlTree): Observable { try { - const match = new MatchResult(rootComponentType, config, [url.root], {}, url._root.children, [], PRIMARY_OUTLET, null, url.root); + const match = new MatchResult( + rootComponentType, config, [url.root], {}, url._root.children, [], PRIMARY_OUTLET, null, + url.root); const roots = constructActivatedRoute(match); const res = new RouterStateSnapshot(roots[0], url.queryParams, url.fragment); return new Observable(obs => { obs.next(res); obs.complete(); }); - } catch(e) { + } catch (e) { if (e instanceof CannotRecognize) { - return new Observable(obs => obs.error(new Error("Cannot match any routes"))); + return new Observable( + obs => obs.error(new Error('Cannot match any routes'))); } else { return new Observable(obs => obs.error(e)); } @@ -30,7 +35,8 @@ export function recognize(rootComponentType: Type, config: RouterConfig, url: Ur function constructActivatedRoute(match: MatchResult): TreeNode[] { const activatedRoute = createActivatedRouteSnapshot(match); const children = match.leftOverUrl.length > 0 ? - recognizeMany(match.children, match.leftOverUrl) : recognizeLeftOvers(match.children, match.lastUrlSegment); + recognizeMany(match.children, match.leftOverUrl) : + recognizeLeftOvers(match.children, match.lastUrlSegment); checkOutletNameUniqueness(children); children.sort((a, b) => { if (a.value.outlet === PRIMARY_OUTLET) return -1; @@ -40,23 +46,28 @@ function constructActivatedRoute(match: MatchResult): TreeNode(activatedRoute, children)]; } -function recognizeLeftOvers(config: Route[], lastUrlSegment: UrlSegment): TreeNode[] { +function recognizeLeftOvers( + config: Route[], lastUrlSegment: UrlSegment): TreeNode[] { if (!config) return []; const mIndex = matchIndex(config, [], lastUrlSegment); return mIndex ? constructActivatedRoute(mIndex) : []; } -function recognizeMany(config: Route[], urls: TreeNode[]): TreeNode[] { +function recognizeMany( + config: Route[], urls: TreeNode[]): TreeNode[] { return flatten(urls.map(url => recognizeOne(config, url))); } function createActivatedRouteSnapshot(match: MatchResult): ActivatedRouteSnapshot { - return new ActivatedRouteSnapshot(match.consumedUrlSegments, match.parameters, match.outlet, match.component, match.route, match.lastUrlSegment); + return new ActivatedRouteSnapshot( + match.consumedUrlSegments, match.parameters, match.outlet, match.component, match.route, + match.lastUrlSegment); } -function recognizeOne(config: Route[], url: TreeNode): TreeNode[] { +function recognizeOne( + config: Route[], url: TreeNode): TreeNode[] { const matches = match(config, url); - for(let match of matches) { + for (let match of matches) { try { const primary = constructActivatedRoute(match); const secondary = recognizeMany(config, match.secondary); @@ -64,7 +75,7 @@ function recognizeOne(config: Route[], url: TreeNode): TreeNode): TreeNode[]): TreeNode[] { +function checkOutletNameUniqueness(nodes: TreeNode[]): + TreeNode[] { let names = {}; nodes.forEach(n => { let routeWithSameOutletName = names[n.value.outlet]; if (routeWithSameOutletName) { - const p = routeWithSameOutletName.urlSegments.map(s => s.toString()).join("/"); - const c = n.value.urlSegments.map(s => s.toString()).join("/"); + const p = routeWithSameOutletName.urlSegments.map(s => s.toString()).join('/'); + const c = n.value.urlSegments.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; @@ -99,13 +111,18 @@ function match(config: Route[], url: TreeNode): MatchResult[] { return res; } -function createIndexMatch(r: Route, leftOverUrls:TreeNode[], lastUrlSegment:UrlSegment): MatchResult { +function createIndexMatch( + r: Route, leftOverUrls: TreeNode[], lastUrlSegment: UrlSegment): MatchResult { const outlet = r.outlet ? r.outlet : PRIMARY_OUTLET; const children = r.children ? r.children : []; - return new MatchResult(r.component, children, [], lastUrlSegment.parameters, leftOverUrls, [], outlet, r, lastUrlSegment); + return new MatchResult( + r.component, children, [], lastUrlSegment.parameters, leftOverUrls, [], outlet, r, + lastUrlSegment); } -function matchIndex(config: Route[], leftOverUrls: TreeNode[], lastUrlSegment: UrlSegment): MatchResult | null { +function matchIndex( + config: Route[], leftOverUrls: TreeNode[], lastUrlSegment: UrlSegment): MatchResult| + null { for (let r of config) { if (r.index) { return createIndexMatch(r, leftOverUrls, lastUrlSegment); @@ -114,23 +131,24 @@ function matchIndex(config: Route[], leftOverUrls: TreeNode[], lastU return null; } -function matchWithParts(route: Route, url: TreeNode): MatchResult | null { +function matchWithParts(route: Route, url: TreeNode): MatchResult|null { if (!route.path) return null; if ((route.outlet ? route.outlet : PRIMARY_OUTLET) !== url.value.outlet) return null; - const path = route.path.startsWith("/") ? route.path.substring(1) : route.path; - if (path === "**") { + const path = route.path.startsWith('/') ? route.path.substring(1) : route.path; + if (path === '**') { const consumedUrl = []; - let u:TreeNode|null = url; + let u: TreeNode|null = url; while (u) { consumedUrl.push(u.value); u = first(u.children); } const last = consumedUrl[consumedUrl.length - 1]; - return new MatchResult(route.component, [], consumedUrl, last.parameters, [], [], PRIMARY_OUTLET, route, last); + return new MatchResult( + route.component, [], consumedUrl, last.parameters, [], [], PRIMARY_OUTLET, route, last); } - const parts = path.split("/"); + const parts = path.split('/'); const positionalParams = {}; const consumedUrlSegments = []; @@ -144,7 +162,7 @@ function matchWithParts(route: Route, url: TreeNode): MatchResult | const p = parts[i]; const isLastSegment = i === parts.length - 1; const isLastParent = i === parts.length - 2; - const isPosParam = p.startsWith(":"); + const isPosParam = p.startsWith(':'); if (!isPosParam && p != current.value.path) return null; if (isLastSegment) { @@ -163,7 +181,7 @@ function matchWithParts(route: Route, url: TreeNode): MatchResult | current = first(current.children); } - if (!lastSegment) throw "Cannot be reached"; + if (!lastSegment) throw 'Cannot be reached'; const p = lastSegment.value.parameters; const parameters = <{[key: string]: string}>merge(p, positionalParams); @@ -171,19 +189,15 @@ function matchWithParts(route: Route, url: TreeNode): MatchResult | const children = route.children ? route.children : []; const outlet = route.outlet ? route.outlet : PRIMARY_OUTLET; - return new MatchResult(route.component, children, consumedUrlSegments, parameters, lastSegment.children, - secondarySubtrees, outlet, route, lastSegment.value); + return new MatchResult( + route.component, children, consumedUrlSegments, parameters, lastSegment.children, + secondarySubtrees, outlet, route, lastSegment.value); } class MatchResult { - constructor(public component: Type | string, - public children: Route[], - public consumedUrlSegments: UrlSegment[], - public parameters: {[key: string]: string}, - public leftOverUrl: TreeNode[], - public secondary: TreeNode[], - public outlet: string, - public route: Route | null, - public lastUrlSegment: UrlSegment - ) {} + constructor( + public component: Type|string, public children: Route[], + public consumedUrlSegments: UrlSegment[], public parameters: {[key: string]: string}, + public leftOverUrl: TreeNode[], public secondary: TreeNode[], + public outlet: string, public route: Route|null, public lastUrlSegment: UrlSegment) {} } \ No newline at end of file diff --git a/modules/@angular/router/src/resolve.ts b/modules/@angular/router/src/resolve.ts index cdadbc5919..955bec6009 100644 --- a/modules/@angular/router/src/resolve.ts +++ b/modules/@angular/router/src/resolve.ts @@ -1,28 +1,33 @@ -import { RouterStateSnapshot, ActivatedRouteSnapshot } from './router_state'; -import { TreeNode } from './utils/tree'; -import { ComponentResolver } from '@angular/core'; -import { Observable } from 'rxjs/Observable'; import 'rxjs/add/operator/map'; -import {forkJoin} from 'rxjs/observable/forkJoin'; -import {fromPromise} from 'rxjs/observable/fromPromise'; import 'rxjs/add/operator/toPromise'; -export function resolve(resolver: ComponentResolver, state: RouterStateSnapshot): Observable { +import {ComponentResolver} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {forkJoin} from 'rxjs/observable/forkJoin'; +import {fromPromise} from 'rxjs/observable/fromPromise'; + +import {ActivatedRouteSnapshot, RouterStateSnapshot} from './router_state'; +import {TreeNode} from './utils/tree'; + +export function resolve( + resolver: ComponentResolver, state: RouterStateSnapshot): Observable { return resolveNode(resolver, state._root).map(_ => state); } -function resolveNode(resolver: ComponentResolver, node: TreeNode): Observable { +function resolveNode( + resolver: ComponentResolver, node: TreeNode): Observable { if (node.children.length === 0) { return fromPromise(resolver.resolveComponent(node.value.component).then(factory => { node.value._resolvedComponentFactory = factory; return node.value; })); - + } else { const c = node.children.map(c => resolveNode(resolver, c).toPromise()); - return forkJoin(c).map(_ => resolver.resolveComponent(node.value.component).then(factory => { - node.value._resolvedComponentFactory = factory; - return node.value; - })); + return forkJoin(c).map( + _ => resolver.resolveComponent(node.value.component).then(factory => { + node.value._resolvedComponentFactory = factory; + return node.value; + })); } } \ No newline at end of file diff --git a/modules/@angular/router/src/router.ts b/modules/@angular/router/src/router.ts index 57a2fbf050..c629188574 100644 --- a/modules/@angular/router/src/router.ts +++ b/modules/@angular/router/src/router.ts @@ -1,50 +1,64 @@ -import { ComponentResolver, ReflectiveInjector, Type, Injector } from '@angular/core'; -import { Location } from '@angular/common'; -import { UrlSerializer } from './url_serializer'; -import { RouterOutletMap } from './router_outlet_map'; -import { recognize } from './recognize'; -import { resolve } from './resolve'; -import { createRouterState } from './create_router_state'; -import { TreeNode } from './utils/tree'; -import { UrlTree, createEmptyUrlTree } from './url_tree'; -import { PRIMARY_OUTLET, Params } from './shared'; -import { createEmptyState, RouterState, RouterStateSnapshot, ActivatedRoute, ActivatedRouteSnapshot, advanceActivatedRoute} from './router_state'; -import { RouterConfig } from './config'; -import { RouterOutlet } from './directives/router_outlet'; -import { createUrlTree } from './create_url_tree'; -import { forEach, and, shallowEqual } from './utils/collection'; -import { Observable } from 'rxjs/Observable'; -import { Subscription } from 'rxjs/Subscription'; -import { Subject } from 'rxjs/Subject'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/scan'; import 'rxjs/add/operator/mergeMap'; import 'rxjs/add/operator/concat'; import 'rxjs/add/operator/concatMap'; -import {of} from 'rxjs/observable/of'; -import {forkJoin} from 'rxjs/observable/forkJoin'; -export interface NavigationExtras { relativeTo?: ActivatedRoute; queryParams?: Params; fragment?: string; } +import {Location} from '@angular/common'; +import {ComponentResolver, Injector, ReflectiveInjector, Type} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {Subject} from 'rxjs/Subject'; +import {Subscription} from 'rxjs/Subscription'; +import {forkJoin} from 'rxjs/observable/forkJoin'; +import {of } from 'rxjs/observable/of'; + +import {RouterConfig} from './config'; +import {createRouterState} from './create_router_state'; +import {createUrlTree} from './create_url_tree'; +import {RouterOutlet} from './directives/router_outlet'; +import {recognize} from './recognize'; +import {resolve} from './resolve'; +import {RouterOutletMap} from './router_outlet_map'; +import {ActivatedRoute, ActivatedRouteSnapshot, RouterState, RouterStateSnapshot, advanceActivatedRoute, createEmptyState} from './router_state'; +import {PRIMARY_OUTLET, Params} from './shared'; +import {UrlSerializer} from './url_serializer'; +import {UrlTree, createEmptyUrlTree} from './url_tree'; +import {and, forEach, shallowEqual} from './utils/collection'; +import {TreeNode} from './utils/tree'; + +export interface NavigationExtras { + relativeTo?: ActivatedRoute; + queryParams?: Params; + fragment?: string; +} /** * An event triggered when a navigation starts */ -export class NavigationStart { constructor(public id:number, public url:UrlTree) {} } +export class NavigationStart { + constructor(public id: number, public url: UrlTree) {} +} /** * An event triggered when a navigation ends successfully */ -export class NavigationEnd { constructor(public id:number, public url:UrlTree) {} } +export class NavigationEnd { + constructor(public id: number, public url: UrlTree) {} +} /** * An event triggered when a navigation is canceled */ -export class NavigationCancel { constructor(public id:number, public url:UrlTree) {} } +export class NavigationCancel { + constructor(public id: number, public url: UrlTree) {} +} /** * An event triggered when a navigation fails due to unexpected error */ -export class NavigationError { constructor(public id:number, public url:UrlTree, public error:any) {} } +export class NavigationError { + constructor(public id: number, public url: UrlTree, public error: any) {} +} export type Event = NavigationStart | NavigationEnd | NavigationCancel | NavigationError; @@ -61,7 +75,10 @@ export class Router { /** * @internal */ - constructor(private rootComponentType:Type, private resolver: ComponentResolver, private urlSerializer: UrlSerializer, private outletMap: RouterOutletMap, private location: Location, private injector: Injector, private config: RouterConfig) { + constructor( + private rootComponentType: Type, private resolver: ComponentResolver, + private urlSerializer: UrlSerializer, private outletMap: RouterOutletMap, + private location: Location, private injector: Injector, private config: RouterConfig) { this.routerEvents = new Subject(); this.currentUrlTree = createEmptyUrlTree(); this.currentRouterState = createEmptyState(this.rootComponentType); @@ -70,7 +87,7 @@ export class Router { /** * @internal */ - initialNavigation():void { + initialNavigation(): void { this.setUpLocationChangeListener(); this.navigateByUrl(this.location.path()); } @@ -78,23 +95,17 @@ export class Router { /** * Returns the current route state. */ - get routerState(): RouterState { - return this.currentRouterState; - } + get routerState(): RouterState { return this.currentRouterState; } /** * Returns the current url tree. */ - get urlTree(): UrlTree { - return this.currentUrlTree; - } + get urlTree(): UrlTree { return this.currentUrlTree; } /** * Returns an observable of route events */ - get events(): Observable { - return this.routerEvents; - } + get events(): Observable { return this.routerEvents; } /** * Navigate based on the provided url. This navigation is always absolute. @@ -129,9 +140,7 @@ export class Router { * ]); * ``` */ - resetConfig(config: RouterConfig): void { - this.config = config; - } + resetConfig(config: RouterConfig): void { this.config = config; } /** * @internal @@ -169,7 +178,8 @@ export class Router { * router.createUrlTree(['../../team/44/user/22'], {relativeTo: route}); * ``` */ - createUrlTree(commands: any[], {relativeTo, queryParams, fragment}: NavigationExtras = {}): UrlTree { + createUrlTree(commands: any[], {relativeTo, queryParams, fragment}: NavigationExtras = {}): + UrlTree { const a = relativeTo ? relativeTo : this.routerState.root; return createUrlTree(a, this.currentUrlTree, commands, queryParams, fragment); } @@ -204,8 +214,8 @@ export class Router { */ parseUrl(url: string): UrlTree { return this.urlSerializer.parse(url); } - private scheduleNavigation(url: UrlTree, pop: boolean):Promise { - const id = ++ this.navigationId; + private scheduleNavigation(url: UrlTree, pop: boolean): Promise { + const id = ++this.navigationId; this.routerEvents.next(new NavigationStart(id, url)); return Promise.resolve().then((_) => this.runNavigate(url, false, id)); } @@ -216,7 +226,7 @@ export class Router { }); } - private runNavigate(url: UrlTree, pop: boolean, id: number):Promise { + private runNavigate(url: UrlTree, pop: boolean, id: number): Promise { if (id !== this.navigationId) { this.routerEvents.next(new NavigationCancel(id, url)); return Promise.resolve(false); @@ -224,69 +234,85 @@ export class Router { return new Promise((resolvePromise, rejectPromise) => { let state; - recognize(this.rootComponentType, this.config, url).mergeMap((newRouterStateSnapshot) => { - return resolve(this.resolver, newRouterStateSnapshot); + recognize(this.rootComponentType, this.config, url) + .mergeMap((newRouterStateSnapshot) => { + return resolve(this.resolver, newRouterStateSnapshot); - }).map((routerStateSnapshot) => { - return createRouterState(routerStateSnapshot, this.currentRouterState); + }) + .map((routerStateSnapshot) => { + return createRouterState(routerStateSnapshot, this.currentRouterState); - }).map((newState:RouterState) => { - state = newState; + }) + .map((newState: RouterState) => { + state = newState; - }).mergeMap(_ => { - return new GuardChecks(state.snapshot, this.currentRouterState.snapshot, this.injector).check(this.outletMap); + }) + .mergeMap(_ => { + return new GuardChecks(state.snapshot, this.currentRouterState.snapshot, this.injector) + .check(this.outletMap); - }).forEach((shouldActivate) => { - if (!shouldActivate || id !== this.navigationId) { - this.routerEvents.next(new NavigationCancel(id, url)); - return Promise.resolve(false); - } + }) + .forEach((shouldActivate) => { + if (!shouldActivate || id !== this.navigationId) { + this.routerEvents.next(new NavigationCancel(id, url)); + return Promise.resolve(false); + } - new ActivateRoutes(state, this.currentRouterState).activate(this.outletMap); + new ActivateRoutes(state, this.currentRouterState).activate(this.outletMap); - this.currentUrlTree = url; - this.currentRouterState = state; - if (!pop) { - this.location.go(this.urlSerializer.serialize(url)); - } - }).then(() => { - this.routerEvents.next(new NavigationEnd(id, url)); - resolvePromise(true); + this.currentUrlTree = url; + this.currentRouterState = state; + if (!pop) { + this.location.go(this.urlSerializer.serialize(url)); + } + }) + .then( + () => { + this.routerEvents.next(new NavigationEnd(id, url)); + resolvePromise(true); - }, e => { - this.routerEvents.next(new NavigationError(id, url, e)); - rejectPromise(e); - }); + }, + e => { + this.routerEvents.next(new NavigationError(id, url, e)); + rejectPromise(e); + }); }); } } -class CanActivate { constructor(public route: ActivatedRouteSnapshot) {}} -class CanDeactivate { constructor(public component: Object, public route: ActivatedRouteSnapshot) {}} +class CanActivate { + constructor(public route: ActivatedRouteSnapshot) {} +} +class CanDeactivate { + constructor(public component: Object, public route: ActivatedRouteSnapshot) {} +} class GuardChecks { private checks = []; - constructor(private future: RouterStateSnapshot, private curr: RouterStateSnapshot, private injector: Injector) {} + constructor( + private future: RouterStateSnapshot, private curr: RouterStateSnapshot, + private injector: Injector) {} check(parentOutletMap: RouterOutletMap): Observable { const futureRoot = this.future._root; const currRoot = this.curr ? this.curr._root : null; this.traverseChildRoutes(futureRoot, currRoot, parentOutletMap); - if (this.checks.length === 0) return of(true); + if (this.checks.length === 0) return of (true); return forkJoin(this.checks.map(s => { - if (s instanceof CanActivate) { - return this.runCanActivate(s.route); - } else if (s instanceof CanDeactivate) { - return this.runCanDeactivate(s.component, s.route); - } else { - throw new Error("Cannot be reached"); - } - })).map(and); + if (s instanceof CanActivate) { + return this.runCanActivate(s.route); + } else if (s instanceof CanDeactivate) { + return this.runCanDeactivate(s.component, s.route); + } else { + throw new Error('Cannot be reached'); + } + })) + .map(and); } - private traverseChildRoutes(futureNode: TreeNode, - currNode: TreeNode | null, - outletMap: RouterOutletMap | null): void { + private traverseChildRoutes( + futureNode: TreeNode, currNode: TreeNode|null, + outletMap: RouterOutletMap|null): void { const prevChildren = nodeChildrenAsMap(currNode); futureNode.children.forEach(c => { this.traverseRoutes(c, prevChildren[c.value.outlet], outletMap); @@ -295,8 +321,9 @@ class GuardChecks { forEach(prevChildren, (v, k) => this.deactivateOutletAndItChildren(v, outletMap._outlets[k])); } - traverseRoutes(futureNode: TreeNode, currNode: TreeNode | null, - parentOutletMap: RouterOutletMap | null): void { + traverseRoutes( + futureNode: TreeNode, currNode: TreeNode|null, + parentOutletMap: RouterOutletMap|null): void { const future = futureNode.value; const curr = currNode ? currNode.value : null; const outlet = parentOutletMap ? parentOutletMap._outlets[futureNode.value.outlet] : null; @@ -315,35 +342,39 @@ class GuardChecks { private deactivateOutletAndItChildren(route: ActivatedRouteSnapshot, outlet: RouterOutlet): void { if (outlet && outlet.isActivated) { - forEach(outlet.outletMap._outlets, (v, k) => this.deactivateOutletAndItChildren(v, outlet.outletMap._outlets[k])); + forEach( + outlet.outletMap._outlets, + (v, k) => this.deactivateOutletAndItChildren(v, outlet.outletMap._outlets[k])); this.checks.push(new CanDeactivate(outlet.component, route)); } } private runCanActivate(future: ActivatedRouteSnapshot): Observable { const canActivate = future._routeConfig ? future._routeConfig.canActivate : null; - if (!canActivate || canActivate.length === 0) return of(true); + if (!canActivate || canActivate.length === 0) return of (true); return forkJoin(canActivate.map(c => { - const guard = this.injector.get(c); - if (guard.canActivate) { - return wrapIntoObservable(guard.canActivate(future, this.future)); - } else { - return wrapIntoObservable(guard(future, this.future)); - } - })).map(and); + const guard = this.injector.get(c); + if (guard.canActivate) { + return wrapIntoObservable(guard.canActivate(future, this.future)); + } else { + return wrapIntoObservable(guard(future, this.future)); + } + })) + .map(and); } private runCanDeactivate(component: Object, curr: ActivatedRouteSnapshot): Observable { const canDeactivate = curr._routeConfig ? curr._routeConfig.canDeactivate : null; - if (!canDeactivate || canDeactivate.length === 0) return of(true); + if (!canDeactivate || canDeactivate.length === 0) return of (true); return forkJoin(canDeactivate.map(c => { - const guard = this.injector.get(c); - if (guard.canDeactivate) { - return wrapIntoObservable(guard.canDeactivate(component, curr, this.curr)); - } else { - return wrapIntoObservable(guard(component, curr, this.curr)); - } - })).map(and); + const guard = this.injector.get(c); + if (guard.canDeactivate) { + return wrapIntoObservable(guard.canDeactivate(component, curr, this.curr)); + } else { + return wrapIntoObservable(guard(component, curr, this.curr)); + } + })) + .map(and); } } @@ -351,14 +382,14 @@ function wrapIntoObservable(value: T | Observable): Observable { if (value instanceof Observable) { return value; } else { - return of(value); + return of (value); } } class ActivateRoutes { constructor(private futureState: RouterState, private currState: RouterState) {} - activate(parentOutletMap: RouterOutletMap):void { + activate(parentOutletMap: RouterOutletMap): void { const futureRoot = this.futureState._root; const currRoot = this.currState ? this.currState._root : null; @@ -366,9 +397,9 @@ class ActivateRoutes { this.activateChildRoutes(futureRoot, currRoot, parentOutletMap); } - private activateChildRoutes(futureNode: TreeNode, - currNode: TreeNode | null, - outletMap: RouterOutletMap): void { + private activateChildRoutes( + futureNode: TreeNode, currNode: TreeNode|null, + outletMap: RouterOutletMap): void { const prevChildren = nodeChildrenAsMap(currNode); futureNode.children.forEach(c => { this.activateRoutes(c, prevChildren[c.value.outlet], outletMap); @@ -377,8 +408,9 @@ class ActivateRoutes { forEach(prevChildren, (v, k) => this.deactivateOutletAndItChildren(outletMap._outlets[k])); } - activateRoutes(futureNode: TreeNode, currNode: TreeNode | null, - parentOutletMap: RouterOutletMap): void { + activateRoutes( + futureNode: TreeNode, currNode: TreeNode|null, + parentOutletMap: RouterOutletMap): void { const future = futureNode.value; const curr = currNode ? currNode.value : null; const outlet = getOutlet(parentOutletMap, futureNode.value); @@ -394,7 +426,8 @@ class ActivateRoutes { } } - private activateNewRoutes(outletMap: RouterOutletMap, future: ActivatedRoute, outlet: RouterOutlet): void { + private activateNewRoutes( + outletMap: RouterOutletMap, future: ActivatedRoute, outlet: RouterOutlet): void { const resolved = ReflectiveInjector.resolve([ {provide: ActivatedRoute, useValue: future}, {provide: RouterOutletMap, useValue: outletMap} @@ -421,15 +454,11 @@ function pushQueryParamsAndFragment(state: RouterState): void { } } -function nodeChildrenAsMap(node: TreeNode|null) { - return node ? - node.children.reduce( - (m, c) => { - m[c.value.outlet] = c; - return m; - }, - {}) : - {}; +function nodeChildrenAsMap(node: TreeNode| null) { + return node ? node.children.reduce((m, c) => { + m[c.value.outlet] = c; + return m; + }, {}) : {}; } function getOutlet(outletMap: RouterOutletMap, route: ActivatedRoute): RouterOutlet { diff --git a/modules/@angular/router/src/router_outlet_map.ts b/modules/@angular/router/src/router_outlet_map.ts index 8443cb6655..d466543496 100644 --- a/modules/@angular/router/src/router_outlet_map.ts +++ b/modules/@angular/router/src/router_outlet_map.ts @@ -1,4 +1,4 @@ -import { RouterOutlet } from './directives/router_outlet'; +import {RouterOutlet} from './directives/router_outlet'; /** * @internal diff --git a/modules/@angular/router/src/router_providers.ts b/modules/@angular/router/src/router_providers.ts index ca6fecd657..3be515db05 100644 --- a/modules/@angular/router/src/router_providers.ts +++ b/modules/@angular/router/src/router_providers.ts @@ -1,7 +1,9 @@ -import { RouterConfig } from './config'; -import * as common from './common_router_providers'; -import {BrowserPlatformLocation} from '@angular/platform-browser'; import {PlatformLocation} from '@angular/common'; +import {BrowserPlatformLocation} from '@angular/platform-browser'; + +import * as common from './common_router_providers'; +import {RouterConfig} from './config'; + /** * A list of {@link Provider}s. To use the router, you must add this to your application. @@ -13,7 +15,7 @@ import {PlatformLocation} from '@angular/common'; * class AppCmp { * // ... * } - * + * * const router = [ * {path: '/home', component: Home} * ]; @@ -21,9 +23,8 @@ import {PlatformLocation} from '@angular/common'; * bootstrap(AppCmp, [provideRouter(router)]); * ``` */ -export function provideRouter(config: RouterConfig):any[] { +export function provideRouter(config: RouterConfig): any[] { return [ - {provide: PlatformLocation, useClass: BrowserPlatformLocation}, - ...common.provideRouter(config) + {provide: PlatformLocation, useClass: BrowserPlatformLocation}, ...common.provideRouter(config) ]; } diff --git a/modules/@angular/router/src/router_state.ts b/modules/@angular/router/src/router_state.ts index 2de22a310a..aca51ab09b 100644 --- a/modules/@angular/router/src/router_state.ts +++ b/modules/@angular/router/src/router_state.ts @@ -1,11 +1,13 @@ -import { Tree, TreeNode } from './utils/tree'; -import { shallowEqual } from './utils/collection'; -import { UrlSegment } from './url_tree'; -import { Route } from './config'; -import { Params, PRIMARY_OUTLET } from './shared'; -import { Observable } from 'rxjs/Observable'; -import { BehaviorSubject } from 'rxjs/BehaviorSubject'; -import { Type, ComponentFactory } from '@angular/core'; +import {ComponentFactory, Type} from '@angular/core'; +import {BehaviorSubject} from 'rxjs/BehaviorSubject'; +import {Observable} from 'rxjs/Observable'; + +import {Route} from './config'; +import {PRIMARY_OUTLET, Params} from './shared'; +import {UrlSegment} from './url_tree'; +import {shallowEqual} from './utils/collection'; +import {Tree, TreeNode} from './utils/tree'; + /** * The state of the router. @@ -26,34 +28,41 @@ export class RouterState extends Tree { /** * @internal */ - constructor(root: TreeNode, public queryParams: Observable, public fragment: Observable, public snapshot: RouterStateSnapshot) { + constructor( + root: TreeNode, public queryParams: Observable, + public fragment: Observable, public snapshot: RouterStateSnapshot) { super(root); } } export function createEmptyState(rootComponent: Type): RouterState { const snapshot = createEmptyStateSnapshot(rootComponent); - const emptyUrl = new BehaviorSubject([new UrlSegment("", {}, PRIMARY_OUTLET)]); + const emptyUrl = new BehaviorSubject([new UrlSegment('', {}, PRIMARY_OUTLET)]); const emptyParams = new BehaviorSubject({}); const emptyQueryParams = new BehaviorSubject({}); - const fragment = new BehaviorSubject(""); - const activated = new ActivatedRoute(emptyUrl, emptyParams, PRIMARY_OUTLET, rootComponent, snapshot.root); + const fragment = new BehaviorSubject(''); + const activated = + new ActivatedRoute(emptyUrl, emptyParams, PRIMARY_OUTLET, rootComponent, snapshot.root); activated.snapshot = snapshot.root; - return new RouterState(new TreeNode(activated, []), emptyQueryParams, fragment, snapshot); + return new RouterState( + new TreeNode(activated, []), emptyQueryParams, fragment, snapshot); } function createEmptyStateSnapshot(rootComponent: Type): RouterStateSnapshot { - const rootUrlSegment = new UrlSegment("", {}, PRIMARY_OUTLET); + const rootUrlSegment = new UrlSegment('', {}, PRIMARY_OUTLET); const emptyUrl = [rootUrlSegment]; const emptyParams = {}; const emptyQueryParams = {}; - const fragment = ""; - const activated = new ActivatedRouteSnapshot(emptyUrl, emptyParams, PRIMARY_OUTLET, rootComponent, null, rootUrlSegment); - return new RouterStateSnapshot(new TreeNode(activated, []), emptyQueryParams, fragment); + const fragment = ''; + const activated = new ActivatedRouteSnapshot( + emptyUrl, emptyParams, PRIMARY_OUTLET, rootComponent, null, rootUrlSegment); + return new RouterStateSnapshot( + new TreeNode(activated, []), emptyQueryParams, fragment); } /** - * Contains the information about a component loaded in an outlet. The information is provided through + * Contains the information about a component loaded in an outlet. The information is provided + * through * the params and urlSegments observables. * * ### Usage @@ -74,12 +83,10 @@ export class ActivatedRoute { /** * @internal */ - constructor(public urlSegments: Observable, - public params: Observable, - public outlet: string, - public component: Type | string, - futureSnapshot: ActivatedRouteSnapshot - ) { + constructor( + public urlSegments: Observable, public params: Observable, + public outlet: string, public component: Type|string, + futureSnapshot: ActivatedRouteSnapshot) { this._futureSnapshot = futureSnapshot; } } @@ -102,9 +109,9 @@ export class ActivatedRouteSnapshot { * @internal */ _resolvedComponentFactory: ComponentFactory; - + /** @internal **/ - _routeConfig: Route | null; + _routeConfig: Route|null; /** @internal **/ _lastUrlSegment: UrlSegment; @@ -112,12 +119,9 @@ export class ActivatedRouteSnapshot { /** * @internal */ - constructor(public urlSegments: UrlSegment[], - public params: Params, - public outlet: string, - public component: Type | string, - routeConfig: Route | null, - lastUrlSegment: UrlSegment) { + constructor( + public urlSegments: UrlSegment[], public params: Params, public outlet: string, + public component: Type|string, routeConfig: Route|null, lastUrlSegment: UrlSegment) { this._routeConfig = routeConfig; this._lastUrlSegment = lastUrlSegment; } @@ -140,7 +144,9 @@ export class RouterStateSnapshot extends Tree { /** * @internal */ - constructor(root: TreeNode, public queryParams: Params, public fragment: string | null) { + constructor( + root: TreeNode, public queryParams: Params, + public fragment: string|null) { super(root); } } diff --git a/modules/@angular/router/src/shared.ts b/modules/@angular/router/src/shared.ts index c97632bcd6..8824d9e78d 100644 --- a/modules/@angular/router/src/shared.ts +++ b/modules/@angular/router/src/shared.ts @@ -2,9 +2,11 @@ * Name of the primary outlet. * @type {string} */ -export const PRIMARY_OUTLET: string = "PRIMARY_OUTLET"; +export const PRIMARY_OUTLET = 'PRIMARY_OUTLET'; /** * A collection of parameters. */ -export type Params = { [key: string]: string }; +export type Params = { + [key: string]: string +}; diff --git a/modules/@angular/router/src/url_serializer.ts b/modules/@angular/router/src/url_serializer.ts index 758ffea416..b5b36faa67 100644 --- a/modules/@angular/router/src/url_serializer.ts +++ b/modules/@angular/router/src/url_serializer.ts @@ -1,6 +1,7 @@ -import { UrlTree, UrlSegment } from './url_tree'; -import { PRIMARY_OUTLET } from './shared'; -import { TreeNode } from './utils/tree'; +import {PRIMARY_OUTLET} from './shared'; +import {UrlSegment, UrlTree} from './url_tree'; +import {TreeNode} from './utils/tree'; + /** * Defines a way to serialize/deserialize a url tree. @@ -26,7 +27,7 @@ export class DefaultUrlSerializer implements UrlSerializer { return new UrlTree(p.parseRootSegment(), p.parseQueryParams(), p.parseFragment()); } - serialize(tree: UrlTree): string { + serialize(tree: UrlTree): string { const node = serializeUrlTreeNode(tree._root); const query = serializeQueryParams(tree.queryParams); const fragment = tree.fragment !== null ? `#${tree.fragment}` : ''; @@ -41,7 +42,8 @@ function serializeUrlTreeNode(node: TreeNode): string { function serializeUrlTreeNodes(nodes: TreeNode[]): string { const primary = serializeSegment(nodes[0].value); const secondaryNodes = nodes.slice(1); - const secondary = secondaryNodes.length > 0 ? `(${secondaryNodes.map(serializeUrlTreeNode).join("//")})` : ""; + const secondary = + secondaryNodes.length > 0 ? `(${secondaryNodes.map(serializeUrlTreeNode).join("//")})` : ''; const children = serializeChildren(nodes[0]); return `${primary}${secondary}${children}`; } @@ -50,7 +52,7 @@ function serializeChildren(node: TreeNode): string { if (node.children.length > 0) { return `/${serializeUrlTreeNodes(node.children)}`; } else { - return ""; + return ''; } } @@ -60,16 +62,18 @@ export function serializeSegment(segment: UrlSegment): string { } function serializeParams(params: {[key: string]: string}): string { - return pairs(params).map(p => `;${p.first}=${p.second}`).join(""); + return pairs(params).map(p => `;${p.first}=${p.second}`).join(''); } function serializeQueryParams(params: {[key: string]: string}): string { const strs = pairs(params).map(p => `${p.first}=${p.second}`); - return strs.length > 0 ? `?${strs.join("&")}` : ""; + return strs.length > 0 ? `?${strs.join("&")}` : ''; } -class Pair { constructor(public first:A, public second:B) {} } -function pairs(obj: {[key: string]: T}):Pair[] { +class Pair { + constructor(public first: A, public second: B) {} +} +function pairs(obj: {[key: string]: T}): Pair[] { const res = []; for (let prop in obj) { if (obj.hasOwnProperty(prop)) { @@ -106,7 +110,7 @@ class UrlParser { } parseRootSegment(): TreeNode { - if (this.remaining == '' || this.remaining == '/') { + if (this.remaining == '' || this.remaining == '/') { return new TreeNode(new UrlSegment('', {}, PRIMARY_OUTLET), []); } else { const segments = this.parseSegments(false); @@ -126,17 +130,17 @@ class UrlParser { let outletName; if (hasOutletName) { - if (path.indexOf(":") === -1) { - throw new Error("Not outlet name is provided"); + if (path.indexOf(':') === -1) { + throw new Error('Not outlet name is provided'); } - if (path.indexOf(":") > -1 && hasOutletName) { - let parts = path.split(":"); + if (path.indexOf(':') > -1 && hasOutletName) { + let parts = path.split(':'); outletName = parts[0]; path = parts[1]; } } else { - if (path.indexOf(":") > -1) { - throw new Error("Not outlet name is allowed"); + if (path.indexOf(':') > -1) { + throw new Error('Not outlet name is allowed'); } outletName = PRIMARY_OUTLET; } @@ -175,7 +179,7 @@ class UrlParser { return params; } - parseFragment(): string | null { + parseFragment(): string|null { if (this.peekStartsWith('#')) { return this.remaining.substring(1); } else { @@ -198,7 +202,7 @@ class UrlParser { return; } this.capture(key); - var value: any = "true"; + var value: any = 'true'; if (this.peekStartsWith('=')) { this.capture('='); var valueMatch = matchUrlSegment(this.remaining); @@ -217,7 +221,7 @@ class UrlParser { return; } this.capture(key); - var value: any = "true"; + var value: any = 'true'; if (this.peekStartsWith('=')) { this.capture('='); var valueMatch = matchUrlQueryParamValue(this.remaining); diff --git a/modules/@angular/router/src/url_tree.ts b/modules/@angular/router/src/url_tree.ts index 462173bded..f0653cd8c6 100644 --- a/modules/@angular/router/src/url_tree.ts +++ b/modules/@angular/router/src/url_tree.ts @@ -1,9 +1,10 @@ -import { Tree, TreeNode } from './utils/tree'; -import { shallowEqual } from './utils/collection'; -import { PRIMARY_OUTLET } from './shared'; +import {PRIMARY_OUTLET} from './shared'; +import {shallowEqual} from './utils/collection'; +import {Tree, TreeNode} from './utils/tree'; export function createEmptyUrlTree() { - return new UrlTree(new TreeNode(new UrlSegment("", {}, PRIMARY_OUTLET), []), {}, null); + return new UrlTree( + new TreeNode(new UrlSegment('', {}, PRIMARY_OUTLET), []), {}, null); } /** @@ -13,7 +14,9 @@ export class UrlTree extends Tree { /** * @internal */ - constructor(root: TreeNode, public queryParams: {[key: string]: string}, public fragment: string | null) { + constructor( + root: TreeNode, public queryParams: {[key: string]: string}, + public fragment: string|null) { super(root); } } @@ -22,7 +25,8 @@ export class UrlSegment { /** * @internal */ - constructor(public path: string, public parameters: {[key: string]: string}, public outlet: string) {} + constructor( + public path: string, public parameters: {[key: string]: string}, public outlet: string) {} toString() { const params = []; diff --git a/modules/@angular/router/src/utils/collection.ts b/modules/@angular/router/src/utils/collection.ts index 9a96714a79..7926aa085e 100644 --- a/modules/@angular/router/src/utils/collection.ts +++ b/modules/@angular/router/src/utils/collection.ts @@ -1,4 +1,4 @@ -export function shallowEqual(a: {[x:string]:any}, b: {[x:string]:any}): boolean { +export function shallowEqual(a: {[x: string]: any}, b: {[x: string]: any}): boolean { var k1 = Object.keys(a); var k2 = Object.keys(b); if (k1.length != k2.length) { @@ -24,12 +24,12 @@ export function flatten(a: T[][]): T[] { return target; } -export function first(a: T[]): T | null { +export function first(a: T[]): T|null { return a.length > 0 ? a[0] : null; } export function and(bools: boolean[]): boolean { - return bools.reduce((a,b) => a && b, true); + return bools.reduce((a, b) => a && b, true); } export function merge(m1: {[key: string]: V}, m2: {[key: string]: V}): {[key: string]: V} { @@ -50,7 +50,8 @@ export function merge(m1: {[key: string]: V}, m2: {[key: string]: V}): {[key: return m; } -export function forEach(map: {[key: string]: V}, callback: /*(V, K) => void*/ Function): void { +export function forEach( + map: {[key: string]: V}, callback: /*(V, K) => void*/ Function): void { for (var prop in map) { if (map.hasOwnProperty(prop)) { callback(map[prop], prop); diff --git a/modules/@angular/router/src/utils/tree.ts b/modules/@angular/router/src/utils/tree.ts index 8650902967..6d9e4a3934 100644 --- a/modules/@angular/router/src/utils/tree.ts +++ b/modules/@angular/router/src/utils/tree.ts @@ -6,7 +6,7 @@ export class Tree { get root(): T { return this._root.value; } - parent(t: T): T | null { + parent(t: T): T|null { const p = this.pathFromRoot(t); return p.length > 1 ? p[p.length - 2] : null; } @@ -16,7 +16,7 @@ export class Tree { return n ? n.children.map(t => t.value) : []; } - firstChild(t: T): T | null { + firstChild(t: T): T|null { const n = findNode(t, this._root); return n && n.children.length > 0 ? n.children[0].value : null; } @@ -34,7 +34,7 @@ export class Tree { contains(tree: Tree): boolean { return contains(this._root, tree._root); } } -function findNode(expected: T, c: TreeNode): TreeNode | null { +function findNode(expected: T, c: TreeNode): TreeNode|null { if (expected === c.value) return c; for (let cc of c.children) { const r = findNode(expected, cc); diff --git a/modules/@angular/router/tslint.json b/modules/@angular/router/tslint.json index 055dc404ce..192a338dcd 100644 --- a/modules/@angular/router/tslint.json +++ b/modules/@angular/router/tslint.json @@ -1,7 +1,6 @@ { "rulesDirectory": ["node_modules/codelyzer"], "rules": { - "max-line-length": [true, 100], "no-inferrable-types": true, "class-name": true, "comment-format": [ @@ -12,14 +11,13 @@ true, "spaces" ], - "eofline": true, "no-duplicate-variable": true, "no-eval": true, "no-arg": true, "no-internal-module": true, "no-trailing-whitespace": true, "no-bitwise": true, - "no-shadowed-variable": true, + "no-shadowed-variable": false, "no-unused-expression": true, "no-unused-variable": true, "one-line": [ @@ -29,11 +27,6 @@ "check-open-brace", "check-whitespace" ], - "quotemark": [ - true, - "single", - "avoid-escape" - ], "semicolon": [true, "always"], "typedef-whitespace": [ true, @@ -45,12 +38,12 @@ "variable-declaration": "nospace" } ], - "curly": true, + "curly": false, "variable-name": [ true, "ban-keywords", "check-format", - "allow-trailing-underscore" + "allow-leading-underscore" ], "whitespace": [ true, @@ -62,10 +55,6 @@ ], "component-selector-name": [true, "kebab-case"], "component-selector-type": [true, "element"], - "host-parameter-decorator": true, - "input-parameter-decorator": true, - "output-parameter-decorator": true, - "attribute-parameter-decorator": true, "input-property-directive": true, "output-property-directive": true }