2016-06-08 11:13:41 -07:00
|
|
|
import {PRIMARY_OUTLET} from './shared';
|
2016-06-14 14:55:59 -07:00
|
|
|
import {DefaultUrlSerializer, serializePath, serializePaths} from './url_serializer';
|
|
|
|
|
import {forEach, shallowEqual} from './utils/collection';
|
2016-05-26 16:50:59 -07:00
|
|
|
|
|
|
|
|
export function createEmptyUrlTree() {
|
2016-06-14 14:55:59 -07:00
|
|
|
return new UrlTree(new UrlSegment([], {}), {}, null);
|
2016-05-26 16:50:59 -07:00
|
|
|
}
|
2016-05-21 17:35:55 -07:00
|
|
|
|
2016-05-24 13:41:37 -07:00
|
|
|
/**
|
|
|
|
|
* A URL in the tree form.
|
|
|
|
|
*/
|
2016-06-14 14:55:59 -07:00
|
|
|
export class UrlTree {
|
2016-06-02 15:18:34 -07:00
|
|
|
/**
|
|
|
|
|
* @internal
|
|
|
|
|
*/
|
2016-06-08 11:13:41 -07:00
|
|
|
constructor(
|
2016-06-14 14:55:59 -07:00
|
|
|
public root: UrlSegment, public queryParams: {[key: string]: string},
|
|
|
|
|
public fragment: string|null) {}
|
2016-06-09 14:11:54 -07:00
|
|
|
|
2016-06-09 14:33:09 -07:00
|
|
|
toString(): string { return new DefaultUrlSerializer().serialize(this); }
|
2016-05-21 17:35:55 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class UrlSegment {
|
2016-06-14 14:55:59 -07:00
|
|
|
public parent: UrlSegment|null = null;
|
2016-06-08 11:13:41 -07:00
|
|
|
constructor(
|
2016-06-14 14:55:59 -07:00
|
|
|
public pathsWithParams: UrlPathWithParams[], public children: {[key: string]: UrlSegment}) {
|
|
|
|
|
forEach(children, (v, k) => v.parent = this);
|
|
|
|
|
}
|
2016-05-23 16:14:23 -07:00
|
|
|
|
2016-06-14 14:55:59 -07:00
|
|
|
toString(): string { return serializePaths(this); }
|
2016-05-23 16:14:23 -07:00
|
|
|
}
|
|
|
|
|
|
2016-06-14 14:55:59 -07:00
|
|
|
export class UrlPathWithParams {
|
|
|
|
|
constructor(public path: string, public parameters: {[key: string]: string}) {}
|
|
|
|
|
toString(): string { return serializePath(this); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function equalPathsWithParams(a: UrlPathWithParams[], b: UrlPathWithParams[]): boolean {
|
2016-05-23 16:14:23 -07:00
|
|
|
if (a.length !== b.length) return false;
|
|
|
|
|
for (let i = 0; i < a.length; ++i) {
|
|
|
|
|
if (a[i].path !== b[i].path) return false;
|
|
|
|
|
if (!shallowEqual(a[i].parameters, b[i].parameters)) return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2016-06-14 14:55:59 -07:00
|
|
|
|
|
|
|
|
export function mapChildren(segment: UrlSegment, fn: (v: UrlSegment, k: string) => UrlSegment):
|
|
|
|
|
{[name: string]: UrlSegment} {
|
|
|
|
|
const newChildren = {};
|
|
|
|
|
forEach(segment.children, (child, childOutlet) => {
|
|
|
|
|
if (childOutlet === PRIMARY_OUTLET) {
|
|
|
|
|
newChildren[childOutlet] = fn(child, childOutlet);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
forEach(segment.children, (child, childOutlet) => {
|
|
|
|
|
if (childOutlet !== PRIMARY_OUTLET) {
|
|
|
|
|
newChildren[childOutlet] = fn(child, childOutlet);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
return newChildren;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function mapChildrenIntoArray<T>(
|
|
|
|
|
segment: UrlSegment, fn: (v: UrlSegment, k: string) => T[]): T[] {
|
|
|
|
|
let res = [];
|
|
|
|
|
forEach(segment.children, (child, childOutlet) => {
|
|
|
|
|
if (childOutlet === PRIMARY_OUTLET) {
|
|
|
|
|
res = res.concat(fn(child, childOutlet));
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
forEach(segment.children, (child, childOutlet) => {
|
|
|
|
|
if (childOutlet !== PRIMARY_OUTLET) {
|
|
|
|
|
res = res.concat(fn(child, childOutlet));
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
return res;
|
|
|
|
|
}
|