diff --git a/modules/angular2/src/alt_router/segments.ts b/modules/angular2/src/alt_router/segments.ts index 72ae311558..32b2db95c5 100644 --- a/modules/angular2/src/alt_router/segments.ts +++ b/modules/angular2/src/alt_router/segments.ts @@ -26,6 +26,10 @@ export class Tree { } pathFromRoot(t: T): T[] { return _findPath(t, this._root, []).map(s => s.value); } + + contains(tree: Tree): boolean { + return _contains(this._root, tree._root); + } } export class UrlTree extends Tree { @@ -55,9 +59,8 @@ function _findPath(expected: T, c: TreeNode, collected: TreeNode[]): Tr collected.push(c); // TODO: vsavkin remove it once recognize is fixed - if (expected instanceof RouteSegment && equalSegments(expected, c.value)) - return collected; - if (expected === c.value) return collected; + if(_equalValues(expected, c.value)) return collected; + for (let cc of c.children) { let r = _findPath(expected, cc, ListWrapper.clone(collected)); if (isPresent(r)) return r; @@ -66,6 +69,24 @@ function _findPath(expected: T, c: TreeNode, collected: TreeNode[]): Tr return null; } +function _contains(tree: TreeNode, subtree: TreeNode): boolean { + if (!_equalValues(tree.value, subtree.value)) return false; + + for (let subtreeNode of subtree.children) { + let s = tree.children.filter(child => _equalValues(child.value, subtreeNode.value)); + if (s.length === 0) return false; + if (!_contains(s[0], subtreeNode)) return false; + } + + return true; +} + +function _equalValues(a:any, b:any):boolean { + if (a instanceof RouteSegment) return equalSegments(a, b); + if (a instanceof UrlSegment) return equalUrlSegments(a, b) + return a === b; +} + export class TreeNode { constructor(public value: T, public children: TreeNode[]) {} } @@ -125,6 +146,17 @@ export function equalSegments(a: RouteSegment, b: RouteSegment): boolean { if (isBlank(a) && !isBlank(b)) return false; if (!isBlank(a) && isBlank(b)) return false; if (a._type !== b._type) return false; + if (a.outlet != b.outlet) return false; + if (isBlank(a.parameters) && !isBlank(b.parameters)) return false; + if (!isBlank(a.parameters) && isBlank(b.parameters)) return false; + if (isBlank(a.parameters) && isBlank(b.parameters)) return true; + return StringMapWrapper.equals(a.parameters, b.parameters); +} + +export function equalUrlSegments(a: UrlSegment, b: UrlSegment): boolean { + if (isBlank(a) && !isBlank(b)) return false; + if (!isBlank(a) && isBlank(b)) return false; + if (a.outlet != b.outlet) return false; if (isBlank(a.parameters) && !isBlank(b.parameters)) return false; if (!isBlank(a.parameters) && isBlank(b.parameters)) return false; if (isBlank(a.parameters) && isBlank(b.parameters)) return true; diff --git a/modules/angular2/test/alt_router/tree_spec.ts b/modules/angular2/test/alt_router/tree_spec.ts index d2d9d30fe7..4a95e39013 100644 --- a/modules/angular2/test/alt_router/tree_spec.ts +++ b/modules/angular2/test/alt_router/tree_spec.ts @@ -46,5 +46,22 @@ export function main() { let t = new Tree(new TreeNode(1, [new TreeNode(2, [])])); expect(t.pathFromRoot(2)).toEqual([1, 2]); }); + + describe("contains", () => { + it("should work", () => { + let tree = new Tree(new TreeNode(1, [new TreeNode(2, []), new TreeNode(3, [])])); + let subtree1 = new Tree(new TreeNode(1, [])); + let subtree2 = new Tree(new TreeNode(1, [new TreeNode(2, [])])); + let subtree3 = new Tree(new TreeNode(1, [new TreeNode(3, [])])); + let notSubtree1 = new Tree(new TreeNode(1, [new TreeNode(4, [])])); + let notSubtree2 = new Tree(new TreeNode(1, [new TreeNode(2, [new TreeNode(4, [])])])); + + expect(tree.contains(subtree1)).toEqual(true); + expect(tree.contains(subtree2)).toEqual(true); + expect(tree.contains(subtree3)).toEqual(true); + expect(tree.contains(notSubtree1)).toEqual(false); + expect(tree.contains(notSubtree2)).toEqual(false); + }); + }); }); } \ No newline at end of file