112 lines
3.3 KiB
JavaScript
Raw Normal View History

2015-05-14 15:24:35 +02:00
import {Map, MapWrapper, StringMap, StringMapWrapper, List, ListWrapper} from 'angular2/src/facade/collection';
import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
2015-05-14 15:24:35 +02:00
import {isPresent, normalizeBlank} from 'angular2/src/facade/lang';
export class RouteParams {
2015-05-14 15:24:35 +02:00
params:StringMap<string, string>;
constructor(params:StringMap) {
this.params = params;
}
2015-05-14 15:24:35 +02:00
get(param:string): string {
return normalizeBlank(StringMapWrapper.get(this.params, param));
}
}
/**
* An `Instruction` represents the component hierarchy of the application based on a given route
*/
export class Instruction {
component:any;
_children:Map<string, Instruction>;
// the part of the URL captured by this instruction
capturedUrl:string;
// the part of the URL captured by this instruction and all children
accumulatedUrl:string;
params:StringMap<string, string>;
reuse:boolean;
specificity:number;
constructor({params, component, children, matchedUrl, parentSpecificity}:{params:StringMap, component:any, children:Map, matchedUrl:string, parentSpecificity:number} = {}) {
this.reuse = false;
this.capturedUrl = matchedUrl;
this.accumulatedUrl = matchedUrl;
this.specificity = parentSpecificity;
if (isPresent(children)) {
this._children = children;
var childUrl;
StringMapWrapper.forEach(this._children, (child, _) => {
childUrl = child.accumulatedUrl;
this.specificity += child.specificity;
});
if (isPresent(childUrl)) {
this.accumulatedUrl += childUrl;
}
} else {
this._children = StringMapWrapper.create();
}
this.component = component;
this.params = params;
}
hasChild(outletName:string):boolean {
return StringMapWrapper.contains(this._children, outletName);
}
/**
* Returns the child instruction with the given outlet name
*/
getChild(outletName:string):Instruction {
return StringMapWrapper.get(this._children, outletName);
}
/**
* (child:Instruction, outletName:string) => {}
*/
2015-05-14 15:24:35 +02:00
forEachChild(fn:Function): void {
StringMapWrapper.forEach(this._children, fn);
}
/**
* Does a synchronous, breadth-first traversal of the graph of instructions.
* Takes a function with signature:
* (child:Instruction, outletName:string) => {}
*/
2015-05-14 15:24:35 +02:00
traverseSync(fn:Function): void {
this.forEachChild(fn);
this.forEachChild((childInstruction, _) => childInstruction.traverseSync(fn));
}
/**
* Takes a currently active instruction and sets a reuse flag on each of this instruction's children
*/
2015-05-14 15:24:35 +02:00
reuseComponentsFrom(oldInstruction:Instruction): void {
this.traverseSync((childInstruction, outletName) => {
var oldInstructionChild = oldInstruction.getChild(outletName);
if (shouldReuseComponent(childInstruction, oldInstructionChild)) {
childInstruction.reuse = true;
}
});
}
}
2015-05-14 15:24:35 +02:00
function shouldReuseComponent(instr1:Instruction, instr2:Instruction): boolean {
return instr1.component == instr2.component &&
StringMapWrapper.equals(instr1.params, instr2.params);
}
2015-05-14 15:24:35 +02:00
function mapObjAsync(obj:StringMap, fn): Promise {
return PromiseWrapper.all(mapObj(obj, fn));
}
2015-05-14 15:24:35 +02:00
function mapObj(obj:StringMap, fn: Function):List {
var result = ListWrapper.create();
StringMapWrapper.forEach(obj, (value, key) => ListWrapper.push(result, fn(value, key)));
return result;
}