feat(router): add RouteTree and UrlTree as aliases to Tree<RouteSegment> and Tree<UrlSegment>

This commit is contained in:
vsavkin 2016-05-01 13:45:14 -07:00 committed by Victor Savkin
parent 8836219b16
commit 277b1fc473
10 changed files with 56 additions and 42 deletions

View File

@ -5,7 +5,7 @@
*/ */
export {Router, RouterOutletMap} from './src/alt_router/router'; export {Router, RouterOutletMap} from './src/alt_router/router';
export {RouteSegment, UrlSegment, Tree} from './src/alt_router/segments'; export {RouteSegment, UrlSegment, Tree, UrlTree, RouteTree} from './src/alt_router/segments';
export {Routes} from './src/alt_router/metadata/decorators'; export {Routes} from './src/alt_router/metadata/decorators';
export {Route} from './src/alt_router/metadata/metadata'; export {Route} from './src/alt_router/metadata/metadata';
export { export {

View File

@ -1,11 +1,10 @@
import {RouteSegment, Tree} from './segments'; import {RouteSegment, Tree, RouteTree} from './segments';
export interface OnActivate { export interface OnActivate {
routerOnActivate(curr: RouteSegment, prev?: RouteSegment, currTree?: Tree<RouteSegment>, routerOnActivate(curr: RouteSegment, prev?: RouteSegment, currTree?: RouteTree,
prevTree?: Tree<RouteSegment>): void; prevTree?: RouteTree): void;
} }
export interface CanDeactivate { export interface CanDeactivate {
routerCanDeactivate(currTree?: Tree<RouteSegment>, routerCanDeactivate(currTree?: RouteTree, futureTree?: RouteTree): Promise<boolean>;
futureTree?: Tree<RouteSegment>): Promise<boolean>;
} }

View File

@ -1,9 +1,9 @@
import {Tree, TreeNode, UrlSegment, RouteSegment, rootNode} from './segments'; import {Tree, TreeNode, UrlSegment, RouteSegment, rootNode, UrlTree, RouteTree} from './segments';
import {isBlank, isPresent, isString, isStringMap} from 'angular2/src/facade/lang'; import {isBlank, isPresent, isString, isStringMap} from 'angular2/src/facade/lang';
import {ListWrapper} from 'angular2/src/facade/collection'; import {ListWrapper} from 'angular2/src/facade/collection';
export function link(segment: RouteSegment, routeTree: Tree<RouteSegment>, export function link(segment: RouteSegment, routeTree: RouteTree, urlTree: UrlTree,
urlTree: Tree<UrlSegment>, change: any[]): Tree<UrlSegment> { change: any[]): UrlTree {
if (change.length === 0) return urlTree; if (change.length === 0) return urlTree;
let startingNode; let startingNode;
@ -29,10 +29,10 @@ export function link(segment: RouteSegment, routeTree: Tree<RouteSegment>,
let updated = _update(startingNode, normalizedChange); let updated = _update(startingNode, normalizedChange);
let newRoot = _constructNewTree(rootNode(urlTree), startingNode, updated); let newRoot = _constructNewTree(rootNode(urlTree), startingNode, updated);
return new Tree<UrlSegment>(newRoot); return new UrlTree(newRoot);
} }
function _findUrlSegment(segment: RouteSegment, routeTree: Tree<RouteSegment>): UrlSegment { function _findUrlSegment(segment: RouteSegment, routeTree: RouteTree): UrlSegment {
let s = segment; let s = segment;
let res = null; let res = null;
while (isBlank(res)) { while (isBlank(res)) {

View File

@ -1,4 +1,4 @@
import {RouteSegment, UrlSegment, Tree, TreeNode, rootNode} from './segments'; import {RouteSegment, UrlSegment, Tree, TreeNode, rootNode, UrlTree, RouteTree} from './segments';
import {RoutesMetadata, RouteMetadata} from './metadata/metadata'; import {RoutesMetadata, RouteMetadata} from './metadata/metadata';
import {Type, isBlank, isPresent, stringify} from 'angular2/src/facade/lang'; import {Type, isBlank, isPresent, stringify} from 'angular2/src/facade/lang';
import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection'; import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
@ -10,10 +10,9 @@ import {reflector} from 'angular2/src/core/reflection/reflection';
// TODO: vsavkin: recognize should take the old tree and merge it // TODO: vsavkin: recognize should take the old tree and merge it
export function recognize(componentResolver: ComponentResolver, type: Type, export function recognize(componentResolver: ComponentResolver, type: Type,
url: Tree<UrlSegment>): Promise<Tree<RouteSegment>> { url: UrlTree): Promise<RouteTree> {
let matched = new _MatchResult(type, [url.root], null, rootNode(url).children, []); let matched = new _MatchResult(type, [url.root], null, rootNode(url).children, []);
return _constructSegment(componentResolver, matched) return _constructSegment(componentResolver, matched).then(roots => new RouteTree(roots[0]));
.then(roots => new Tree<RouteSegment>(roots[0]));
} }
function _recognize(componentResolver: ComponentResolver, parentType: Type, function _recognize(componentResolver: ComponentResolver, parentType: Type,

View File

@ -20,7 +20,8 @@ import {
equalSegments, equalSegments,
routeSegmentComponentFactory, routeSegmentComponentFactory,
RouteSegment, RouteSegment,
Tree, UrlTree,
RouteTree,
rootNode, rootNode,
TreeNode, TreeNode,
UrlSegment, UrlSegment,
@ -36,8 +37,8 @@ export class RouterOutletMap {
} }
export class Router { export class Router {
private _prevTree: Tree<RouteSegment>; private _prevTree: RouteTree;
private _urlTree: Tree<UrlSegment>; private _urlTree: UrlTree;
private _locationSubscription: any; private _locationSubscription: any;
private _changes: EventEmitter<void> = new EventEmitter<void>(); private _changes: EventEmitter<void> = new EventEmitter<void>();
@ -49,7 +50,7 @@ export class Router {
this.navigateByUrl(this._location.path()); this.navigateByUrl(this._location.path());
} }
get urlTree(): Tree<UrlSegment> { return this._urlTree; } get urlTree(): UrlTree { return this._urlTree; }
navigateByUrl(url: string): Promise<void> { navigateByUrl(url: string): Promise<void> {
return this._navigate(this._urlSerializer.parse(url)); return this._navigate(this._urlSerializer.parse(url));
@ -66,7 +67,7 @@ export class Router {
(change) => { this._navigate(this._urlSerializer.parse(change['url'])); }); (change) => { this._navigate(this._urlSerializer.parse(change['url'])); });
} }
private _navigate(url: Tree<UrlSegment>): Promise<void> { private _navigate(url: UrlTree): Promise<void> {
this._urlTree = url; this._urlTree = url;
return recognize(this._componentResolver, this._rootComponentType, url) return recognize(this._componentResolver, this._rootComponentType, url)
.then(currTree => { .then(currTree => {
@ -82,7 +83,7 @@ export class Router {
}); });
} }
createUrlTree(changes: any[], segment?: RouteSegment): Tree<UrlSegment> { createUrlTree(changes: any[], segment?: RouteSegment): UrlTree {
if (isPresent(this._prevTree)) { if (isPresent(this._prevTree)) {
let s = isPresent(segment) ? segment : this._prevTree.root; let s = isPresent(segment) ? segment : this._prevTree.root;
return link(s, this._prevTree, this.urlTree, changes); return link(s, this._prevTree, this.urlTree, changes);
@ -91,11 +92,11 @@ export class Router {
} }
} }
serializeUrl(url: Tree<UrlSegment>): string { return this._urlSerializer.serialize(url); } serializeUrl(url: UrlTree): string { return this._urlSerializer.serialize(url); }
get changes(): Observable<void> { return this._changes; } get changes(): Observable<void> { return this._changes; }
get routeTree(): Tree<RouteSegment> { return this._prevTree; } get routeTree(): RouteTree { return this._prevTree; }
} }
@ -103,7 +104,7 @@ class _LoadSegments {
private deactivations: Object[][] = []; private deactivations: Object[][] = [];
private performMutation: boolean = true; private performMutation: boolean = true;
constructor(private currTree: Tree<RouteSegment>, private prevTree: Tree<RouteSegment>) {} constructor(private currTree: RouteTree, private prevTree: RouteTree) {}
load(parentOutletMap: RouterOutletMap, rootComponent: Object): Promise<boolean> { load(parentOutletMap: RouterOutletMap, rootComponent: Object): Promise<boolean> {
let prevRoot = isPresent(this.prevTree) ? rootNode(this.prevTree) : null; let prevRoot = isPresent(this.prevTree) ? rootNode(this.prevTree) : null;

View File

@ -1,20 +1,20 @@
import {UrlSegment, Tree, TreeNode, rootNode} from './segments'; import {UrlSegment, Tree, TreeNode, rootNode, UrlTree} from './segments';
import {BaseException} from 'angular2/src/facade/exceptions'; import {BaseException} from 'angular2/src/facade/exceptions';
import {isBlank, isPresent, RegExpWrapper} from 'angular2/src/facade/lang'; import {isBlank, isPresent, RegExpWrapper} from 'angular2/src/facade/lang';
import {ListWrapper} from 'angular2/src/facade/collection'; import {ListWrapper} from 'angular2/src/facade/collection';
export abstract class RouterUrlSerializer { export abstract class RouterUrlSerializer {
abstract parse(url: string): Tree<UrlSegment>; abstract parse(url: string): UrlTree;
abstract serialize(tree: Tree<UrlSegment>): string; abstract serialize(tree: UrlTree): string;
} }
export class DefaultRouterUrlSerializer extends RouterUrlSerializer { export class DefaultRouterUrlSerializer extends RouterUrlSerializer {
parse(url: string): Tree<UrlSegment> { parse(url: string): UrlTree {
let root = new _UrlParser().parse(url); let root = new _UrlParser().parse(url);
return new Tree<UrlSegment>(root); return new UrlTree(root);
} }
serialize(tree: Tree<UrlSegment>): string { return _serializeUrlTreeNode(rootNode(tree)); } serialize(tree: UrlTree): string { return _serializeUrlTreeNode(rootNode(tree)); }
} }
function _serializeUrlTreeNode(node: TreeNode<UrlSegment>): string { function _serializeUrlTreeNode(node: TreeNode<UrlSegment>): string {

View File

@ -28,6 +28,14 @@ export class Tree<T> {
pathFromRoot(t: T): T[] { return _findPath(t, this._root, []).map(s => s.value); } pathFromRoot(t: T): T[] { return _findPath(t, this._root, []).map(s => s.value); }
} }
export class UrlTree extends Tree<UrlSegment> {
constructor(root: TreeNode<UrlSegment>) { super(root); }
}
export class RouteTree extends Tree<RouteSegment> {
constructor(root: TreeNode<RouteSegment>) { super(root); }
}
export function rootNode<T>(tree: Tree<T>): TreeNode<T> { export function rootNode<T>(tree: Tree<T>): TreeNode<T> {
return tree._root; return tree._root;
} }
@ -103,7 +111,7 @@ export class RouteSegment {
get stringifiedUrlSegments(): string { return this.urlSegments.map(s => s.toString()).join("/"); } get stringifiedUrlSegments(): string { return this.urlSegments.map(s => s.toString()).join("/"); }
} }
export function serializeRouteSegmentTree(tree: Tree<RouteSegment>): string { export function serializeRouteSegmentTree(tree: RouteTree): string {
return _serializeRouteSegmentTree(tree._root); return _serializeRouteSegmentTree(tree._root);
} }

View File

@ -15,7 +15,13 @@ import {
xit xit
} from 'angular2/testing_internal'; } from 'angular2/testing_internal';
import {RouteSegment, UrlSegment, Tree, TreeNode} from 'angular2/src/alt_router/segments'; import {
RouteSegment,
UrlSegment,
UrlTree,
TreeNode,
RouteTree
} from 'angular2/src/alt_router/segments';
import {link} from 'angular2/src/alt_router/link'; import {link} from 'angular2/src/alt_router/link';
import {DefaultRouterUrlSerializer} from 'angular2/src/alt_router/router_url_serializer'; import {DefaultRouterUrlSerializer} from 'angular2/src/alt_router/router_url_serializer';
@ -88,7 +94,7 @@ export function main() {
let child = new RouteSegment([], null, null, null, null); let child = new RouteSegment([], null, null, null, null);
let root = new TreeNode<RouteSegment>(new RouteSegment([c], {}, null, null, null), let root = new TreeNode<RouteSegment>(new RouteSegment([c], {}, null, null, null),
[new TreeNode<RouteSegment>(child, [])]); [new TreeNode<RouteSegment>(child, [])]);
let tree = new Tree<RouteSegment>(root); let tree = new RouteTree(root);
let t = link(child, tree, p, ["./c2"]); let t = link(child, tree, p, ["./c2"]);
expect(parser.serialize(t)).toEqual("/a(aux:ap)/c2(aux:cp)"); expect(parser.serialize(t)).toEqual("/a(aux:ap)/c2(aux:cp)");
@ -96,7 +102,7 @@ export function main() {
}); });
} }
function s(u: UrlSegment): Tree<RouteSegment> { function s(u: UrlSegment): RouteTree {
let root = new TreeNode<RouteSegment>(new RouteSegment([u], {}, null, null, null), []); let root = new TreeNode<RouteSegment>(new RouteSegment([u], {}, null, null, null), []);
return new Tree<RouteSegment>(root); return new RouteTree(root);
} }

View File

@ -18,7 +18,7 @@ import {
import {recognize} from 'angular2/src/alt_router/recognize'; import {recognize} from 'angular2/src/alt_router/recognize';
import {Routes, Route} from 'angular2/alt_router'; import {Routes, Route} from 'angular2/alt_router';
import {provide, Component, ComponentResolver} from 'angular2/core'; import {provide, Component, ComponentResolver} from 'angular2/core';
import {UrlSegment, Tree} from 'angular2/src/alt_router/segments'; import {UrlSegment, RouteTree, UrlTree} from 'angular2/src/alt_router/segments';
import {DefaultRouterUrlSerializer} from 'angular2/src/alt_router/router_url_serializer'; import {DefaultRouterUrlSerializer} from 'angular2/src/alt_router/router_url_serializer';
import {DEFAULT_OUTLET_NAME} from 'angular2/src/alt_router/constants'; import {DEFAULT_OUTLET_NAME} from 'angular2/src/alt_router/constants';
@ -192,7 +192,7 @@ export function main() {
}); });
} }
function tree(url: string): Tree<UrlSegment> { function tree(url: string): UrlTree {
return new DefaultRouterUrlSerializer().parse(url); return new DefaultRouterUrlSerializer().parse(url);
} }

View File

@ -7,7 +7,8 @@ import {
ROUTER_PROVIDERS, ROUTER_PROVIDERS,
OnActivate, OnActivate,
RouteSegment, RouteSegment,
Tree, RouteTree,
UrlTree
} from 'angular2/alt_router'; } from 'angular2/alt_router';
import * as db from './data'; import * as db from './data';
import {Location} from 'angular2/platform/common'; import {Location} from 'angular2/platform/common';
@ -99,8 +100,8 @@ class InboxDetailCmp implements OnActivate {
constructor(private _db: DbService) {} constructor(private _db: DbService) {}
routerOnActivate(curr: RouteSegment, prev?: RouteSegment, currTree?: Tree<RouteSegment>, routerOnActivate(curr: RouteSegment, prev?: RouteSegment, currTree?: RouteTree,
prevTree?: Tree<RouteSegment>): void { prevTree?: RouteTree): void {
let id = curr.getParam("id"); let id = curr.getParam("id");
this._db.email(id).then(data => this.record.setData(data)); this._db.email(id).then(data => this.record.setData(data));
} }
@ -113,8 +114,8 @@ class InboxCmp implements OnActivate {
constructor(private _db: DbService) {} constructor(private _db: DbService) {}
routerOnActivate(curr: RouteSegment, prev?: RouteSegment, currTree?: Tree<RouteSegment>, routerOnActivate(curr: RouteSegment, prev?: RouteSegment, currTree?: RouteTree,
prevTree?: Tree<RouteSegment>): void { prevTree?: RouteTree): void {
var sortType = curr.getParam('sort'); var sortType = curr.getParam('sort');
var sortEmailsByDate = isPresent(sortType) && sortType == "date"; var sortEmailsByDate = isPresent(sortType) && sortType == "date";