feat(router): rename UrlPathWithParams into UrlSegment

BREAKING CHANGE:

UrlPathWithParams => UrlSegment
UrlSegment => UrlSegmentGroup
This commit is contained in:
vsavkin
2016-07-25 12:15:07 -07:00
parent 2b63330a36
commit 6f68330fa5
12 changed files with 407 additions and 379 deletions

View File

@ -8,7 +8,7 @@
import {ActivatedRoute} from './router_state';
import {PRIMARY_OUTLET, Params} from './shared';
import {UrlPathWithParams, UrlSegment, UrlTree} from './url_tree';
import {UrlSegment, UrlSegmentGroup, UrlTree} from './url_tree';
import {forEach, shallowEqual} from './utils/collection';
export function createUrlTree(
@ -22,15 +22,16 @@ export function createUrlTree(
validateCommands(normalizedCommands);
if (navigateToRoot(normalizedCommands)) {
return tree(urlTree.root, new UrlSegment([], {}), urlTree, queryParams, fragment);
return tree(urlTree.root, new UrlSegmentGroup([], {}), urlTree, queryParams, fragment);
}
const startingPosition = findStartingPosition(normalizedCommands, urlTree, route);
const segment = startingPosition.processChildren ?
updateSegmentChildren(
startingPosition.segment, startingPosition.index, normalizedCommands.commands) :
updateSegment(startingPosition.segment, startingPosition.index, normalizedCommands.commands);
return tree(startingPosition.segment, segment, urlTree, queryParams, fragment);
const segmentGroup = startingPosition.processChildren ?
updateSegmentGroupChildren(
startingPosition.segmentGroup, startingPosition.index, normalizedCommands.commands) :
updateSegmentGroup(
startingPosition.segmentGroup, startingPosition.index, normalizedCommands.commands);
return tree(startingPosition.segmentGroup, segmentGroup, urlTree, queryParams, fragment);
}
function validateCommands(n: NormalizedNavigationCommands): void {
@ -40,27 +41,29 @@ function validateCommands(n: NormalizedNavigationCommands): void {
}
function tree(
oldSegment: UrlSegment, newSegment: UrlSegment, urlTree: UrlTree, queryParams: Params,
fragment: string): UrlTree {
if (urlTree.root === oldSegment) {
return new UrlTree(newSegment, stringify(queryParams), fragment);
oldSegmentGroup: UrlSegmentGroup, newSegmentGroup: UrlSegmentGroup, urlTree: UrlTree,
queryParams: Params, fragment: string): UrlTree {
if (urlTree.root === oldSegmentGroup) {
return new UrlTree(newSegmentGroup, stringify(queryParams), fragment);
} else {
return new UrlTree(
replaceSegment(urlTree.root, oldSegment, newSegment), stringify(queryParams), fragment);
replaceSegment(urlTree.root, oldSegmentGroup, newSegmentGroup), stringify(queryParams),
fragment);
}
}
function replaceSegment(
current: UrlSegment, oldSegment: UrlSegment, newSegment: UrlSegment): UrlSegment {
const children: {[key: string]: UrlSegment} = {};
forEach(current.children, (c: UrlSegment, outletName: string) => {
current: UrlSegmentGroup, oldSegment: UrlSegmentGroup,
newSegment: UrlSegmentGroup): UrlSegmentGroup {
const children: {[key: string]: UrlSegmentGroup} = {};
forEach(current.children, (c: UrlSegmentGroup, outletName: string) => {
if (c === oldSegment) {
children[outletName] = newSegment;
} else {
children[outletName] = replaceSegment(c, oldSegment, newSegment);
}
});
return new UrlSegment(current.pathsWithParams, children);
return new UrlSegmentGroup(current.segments, children);
}
function navigateToRoot(normalizedChange: NormalizedNavigationCommands): boolean {
@ -131,7 +134,9 @@ function normalizeCommands(commands: any[]): NormalizedNavigationCommands {
}
class Position {
constructor(public segment: UrlSegment, public processChildren: boolean, public index: number) {}
constructor(
public segmentGroup: UrlSegmentGroup, public processChildren: boolean, public index: number) {
}
}
function findStartingPosition(
@ -160,58 +165,59 @@ function getOutlets(commands: any[]): {[k: string]: any[]} {
return commands[0].outlets;
}
function updateSegment(segment: UrlSegment, startIndex: number, commands: any[]): UrlSegment {
if (!segment) {
segment = new UrlSegment([], {});
function updateSegmentGroup(
segmentGroup: UrlSegmentGroup, startIndex: number, commands: any[]): UrlSegmentGroup {
if (!segmentGroup) {
segmentGroup = new UrlSegmentGroup([], {});
}
if (segment.pathsWithParams.length === 0 && segment.hasChildren()) {
return updateSegmentChildren(segment, startIndex, commands);
if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
return updateSegmentGroupChildren(segmentGroup, startIndex, commands);
}
const m = prefixedWith(segment, startIndex, commands);
const m = prefixedWith(segmentGroup, startIndex, commands);
const slicedCommands = commands.slice(m.lastIndex);
if (m.match && slicedCommands.length === 0) {
return new UrlSegment(segment.pathsWithParams, {});
} else if (m.match && !segment.hasChildren()) {
return createNewSegment(segment, startIndex, commands);
return new UrlSegmentGroup(segmentGroup.segments, {});
} else if (m.match && !segmentGroup.hasChildren()) {
return createNewSegmentGroup(segmentGroup, startIndex, commands);
} else if (m.match) {
return updateSegmentChildren(segment, 0, slicedCommands);
return updateSegmentGroupChildren(segmentGroup, 0, slicedCommands);
} else {
return createNewSegment(segment, startIndex, commands);
return createNewSegmentGroup(segmentGroup, startIndex, commands);
}
}
function updateSegmentChildren(
segment: UrlSegment, startIndex: number, commands: any[]): UrlSegment {
function updateSegmentGroupChildren(
segmentGroup: UrlSegmentGroup, startIndex: number, commands: any[]): UrlSegmentGroup {
if (commands.length === 0) {
return new UrlSegment(segment.pathsWithParams, {});
return new UrlSegmentGroup(segmentGroup.segments, {});
} else {
const outlets = getOutlets(commands);
const children: {[key: string]: UrlSegment} = {};
const children: {[key: string]: UrlSegmentGroup} = {};
forEach(outlets, (commands: any, outlet: string) => {
if (commands !== null) {
children[outlet] = updateSegment(segment.children[outlet], startIndex, commands);
children[outlet] = updateSegmentGroup(segmentGroup.children[outlet], startIndex, commands);
}
});
forEach(segment.children, (child: UrlSegment, childOutlet: string) => {
forEach(segmentGroup.children, (child: UrlSegmentGroup, childOutlet: string) => {
if (outlets[childOutlet] === undefined) {
children[childOutlet] = child;
}
});
return new UrlSegment(segment.pathsWithParams, children);
return new UrlSegmentGroup(segmentGroup.segments, children);
}
}
function prefixedWith(segment: UrlSegment, startIndex: number, commands: any[]) {
function prefixedWith(segmentGroup: UrlSegmentGroup, startIndex: number, commands: any[]) {
let currentCommandIndex = 0;
let currentPathIndex = startIndex;
const noMatch = {match: false, lastIndex: 0};
while (currentPathIndex < segment.pathsWithParams.length) {
while (currentPathIndex < segmentGroup.segments.length) {
if (currentCommandIndex >= commands.length) return noMatch;
const path = segment.pathsWithParams[currentPathIndex];
const path = segmentGroup.segments[currentPathIndex];
const curr = getPath(commands[currentCommandIndex]);
const next =
currentCommandIndex < commands.length - 1 ? commands[currentCommandIndex + 1] : null;
@ -229,14 +235,15 @@ function prefixedWith(segment: UrlSegment, startIndex: number, commands: any[])
return {match: true, lastIndex: currentCommandIndex};
}
function createNewSegment(segment: UrlSegment, startIndex: number, commands: any[]): UrlSegment {
const paths = segment.pathsWithParams.slice(0, startIndex);
function createNewSegmentGroup(
segmentGroup: UrlSegmentGroup, startIndex: number, commands: any[]): UrlSegmentGroup {
const paths = segmentGroup.segments.slice(0, startIndex);
let i = 0;
while (i < commands.length) {
// if we start with an object literal, we need to reuse the path part from the segment
if (i === 0 && (typeof commands[0] === 'object')) {
const p = segment.pathsWithParams[startIndex];
paths.push(new UrlPathWithParams(p.path, commands[0]));
const p = segmentGroup.segments[startIndex];
paths.push(new UrlSegment(p.path, commands[0]));
i++;
continue;
}
@ -244,14 +251,14 @@ function createNewSegment(segment: UrlSegment, startIndex: number, commands: any
const curr = getPath(commands[i]);
const next = (i < commands.length - 1) ? commands[i + 1] : null;
if (curr && next && (typeof next === 'object')) {
paths.push(new UrlPathWithParams(curr, stringify(next)));
paths.push(new UrlSegment(curr, stringify(next)));
i += 2;
} else {
paths.push(new UrlPathWithParams(curr, {}));
paths.push(new UrlSegment(curr, {}));
i++;
}
}
return new UrlSegment(paths, {});
return new UrlSegmentGroup(paths, {});
}
function stringify(params: {[key: string]: any}): {[key: string]: string} {
@ -260,7 +267,6 @@ function stringify(params: {[key: string]: any}): {[key: string]: string} {
return res;
}
function compare(
path: string, params: {[key: string]: any}, pathWithParams: UrlPathWithParams): boolean {
return path == pathWithParams.path && shallowEqual(params, pathWithParams.parameters);
function compare(path: string, params: {[key: string]: any}, segment: UrlSegment): boolean {
return path == segment.path && shallowEqual(params, segment.parameters);
}