feat(router): serialize outlet names into the url

This commit is contained in:
vsavkin
2016-05-26 16:50:59 -07:00
parent 10d38cbb72
commit a9e773b47b
3 changed files with 74 additions and 48 deletions

View File

@ -1,4 +1,5 @@
import { UrlTree, UrlSegment } from './url_tree';
import { PRIMARY_OUTLET } from './shared';
import { rootNode, TreeNode } from './utils/tree';
/**
@ -54,7 +55,8 @@ function serializeChildren(node: TreeNode<UrlSegment>): string {
}
export function serializeSegment(segment: UrlSegment): string {
return `${segment.path}${serializeParams(segment.parameters)}`;
const outlet = segment.outlet === PRIMARY_OUTLET ? '' : `${segment.outlet}:`;
return `${outlet}${segment.path}${serializeParams(segment.parameters)}`;
}
function serializeParams(params: {[key: string]: string}): string {
@ -105,41 +107,58 @@ class UrlParser {
parseRootSegment(): TreeNode<UrlSegment> {
if (this.remaining == '' || this.remaining == '/') {
return new TreeNode<UrlSegment>(new UrlSegment('', {}), []);
return new TreeNode<UrlSegment>(new UrlSegment('', {}, PRIMARY_OUTLET), []);
} else {
let segments = this.parseSegments();
return new TreeNode<UrlSegment>(new UrlSegment('', {}), segments);
const segments = this.parseSegments(false);
return new TreeNode<UrlSegment>(new UrlSegment('', {}, PRIMARY_OUTLET), segments);
}
}
parseSegments(): TreeNode<UrlSegment>[] {
parseSegments(hasOutletName: boolean): TreeNode<UrlSegment>[] {
if (this.remaining.length == 0) {
return [];
}
if (this.peekStartsWith('/')) {
this.capture('/');
}
var path = matchUrlSegment(this.remaining);
let path = matchUrlSegment(this.remaining);
this.capture(path);
var matrixParams: {[key: string]: any} = {};
let outletName;
if (hasOutletName) {
if (path.indexOf(":") === -1) {
throw new Error("Not outlet name is provided");
}
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");
}
outletName = PRIMARY_OUTLET;
}
let matrixParams: {[key: string]: any} = {};
if (this.peekStartsWith(';')) {
matrixParams = this.parseMatrixParams();
}
var secondary = [];
let secondary = [];
if (this.peekStartsWith('(')) {
secondary = this.parseSecondarySegments();
}
var children: TreeNode<UrlSegment>[] = [];
let children: TreeNode<UrlSegment>[] = [];
if (this.peekStartsWith('/') && !this.peekStartsWith('//')) {
this.capture('/');
children = this.parseSegments();
children = this.parseSegments(false);
}
let segment = new UrlSegment(path, matrixParams);
let node = new TreeNode<UrlSegment>(segment, children);
const segment = new UrlSegment(path, matrixParams, outletName);
const node = new TreeNode<UrlSegment>(segment, children);
return [node].concat(secondary);
}
@ -215,7 +234,7 @@ class UrlParser {
this.capture('(');
while (!this.peekStartsWith(')') && this.remaining.length > 0) {
segments = segments.concat(this.parseSegments());
segments = segments.concat(this.parseSegments(true));
if (this.peekStartsWith('//')) {
this.capture('//');
}

View File

@ -1,5 +1,10 @@
import { Tree, TreeNode } from './utils/tree';
import { shallowEqual } from './utils/collection';
import { PRIMARY_OUTLET } from './shared';
export function createEmptyUrlTree() {
return new UrlTree(new TreeNode<UrlSegment>(new UrlSegment("", {}, PRIMARY_OUTLET), []), {}, null);
}
/**
* A URL in the tree form.
@ -11,17 +16,18 @@ export class UrlTree extends Tree<UrlSegment> {
}
export class UrlSegment {
constructor(public path: string, public parameters: {[key: string]: string}) {}
constructor(public path: string, public parameters: {[key: string]: string}, public outlet: string) {}
toString() {
let params = [];
const params = [];
for (let prop in this.parameters) {
if (this.parameters.hasOwnProperty(prop)) {
params.push(`${prop}=${this.parameters[prop]}`);
}
}
const paramsString = params.length > 0 ? `(${params.join(',')})` : '';
return `${this.path}${paramsString}`;
const outlet = this.outlet === PRIMARY_OUTLET ? '' : `${this.outlet}:`;
return `${outlet}${this.path}${paramsString}`;
}
}