refactor(router): add types
This commit is contained in:
parent
3644036693
commit
fc13cdab3a
|
@ -4,21 +4,22 @@ export class BrowserLocation {
|
||||||
_location;
|
_location;
|
||||||
_history;
|
_history;
|
||||||
_baseHref:string;
|
_baseHref:string;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this._location = DOM.getLocation();
|
this._location = DOM.getLocation();
|
||||||
this._history = DOM.getHistory();
|
this._history = DOM.getHistory();
|
||||||
this._baseHref = DOM.getBaseHref();
|
this._baseHref = DOM.getBaseHref();
|
||||||
}
|
}
|
||||||
|
|
||||||
onPopState(fn) {
|
onPopState(fn: Function): void {
|
||||||
DOM.getGlobalEventTarget('window').addEventListener('popstate', fn, false);
|
DOM.getGlobalEventTarget('window').addEventListener('popstate', fn, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
getBaseHref() {
|
getBaseHref(): string {
|
||||||
return this._baseHref;
|
return this._baseHref;
|
||||||
}
|
}
|
||||||
|
|
||||||
path() {
|
path(): string {
|
||||||
return this._location.pathname;
|
return this._location.pathname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,11 +27,11 @@ export class BrowserLocation {
|
||||||
this._history.pushState(state, title, url);
|
this._history.pushState(state, title, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
forward() {
|
forward(): void {
|
||||||
this._history.forward();
|
this._history.forward();
|
||||||
}
|
}
|
||||||
|
|
||||||
back() {
|
back(): void {
|
||||||
this._history.back();
|
this._history.back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,29 @@
|
||||||
import {Map, MapWrapper, StringMap, StringMapWrapper, List, ListWrapper} from 'angular2/src/facade/collection';
|
import {Map, MapWrapper, StringMap, StringMapWrapper, List, ListWrapper} from 'angular2/src/facade/collection';
|
||||||
import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
|
import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
|
||||||
import {isPresent} from 'angular2/src/facade/lang';
|
import {isPresent, normalizeBlank} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
export class RouteParams {
|
export class RouteParams {
|
||||||
params:Map<string, string>;
|
params:StringMap<string, string>;
|
||||||
|
|
||||||
constructor(params:StringMap) {
|
constructor(params:StringMap) {
|
||||||
this.params = params;
|
this.params = params;
|
||||||
}
|
}
|
||||||
|
|
||||||
get(param:string) {
|
get(param:string): string {
|
||||||
return StringMapWrapper.get(this.params, param);
|
return normalizeBlank(StringMapWrapper.get(this.params, param));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Instruction {
|
export class Instruction {
|
||||||
component:any;
|
component:any;
|
||||||
_children:Map<string, Instruction>;
|
_children:StringMap<string, Instruction>;
|
||||||
router:any;
|
router:any;
|
||||||
matchedUrl:string;
|
matchedUrl:string;
|
||||||
params:Map<string, string>;
|
params:StringMap<string, string>;
|
||||||
reuse:boolean;
|
reuse:boolean;
|
||||||
cost:number;
|
cost:number;
|
||||||
|
|
||||||
constructor({params, component, children, matchedUrl, parentCost}:{params:StringMap, component:any, children:Map, matchedUrl:string, cost:int} = {}) {
|
constructor({params, component, children, matchedUrl, parentCost}:{params:StringMap, component:any, children:StringMap, matchedUrl:string, cost:number} = {}) {
|
||||||
this.reuse = false;
|
this.reuse = false;
|
||||||
this.matchedUrl = matchedUrl;
|
this.matchedUrl = matchedUrl;
|
||||||
this.cost = parentCost;
|
this.cost = parentCost;
|
||||||
|
@ -43,11 +44,11 @@ export class Instruction {
|
||||||
this.params = params;
|
this.params = params;
|
||||||
}
|
}
|
||||||
|
|
||||||
getChildInstruction(outletName:string) {
|
getChildInstruction(outletName:string): Instruction {
|
||||||
return StringMapWrapper.get(this._children, outletName);
|
return StringMapWrapper.get(this._children, outletName);
|
||||||
}
|
}
|
||||||
|
|
||||||
forEachChild(fn:Function) {
|
forEachChild(fn:Function): void {
|
||||||
StringMapWrapper.forEach(this._children, fn);
|
StringMapWrapper.forEach(this._children, fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +61,7 @@ export class Instruction {
|
||||||
* Takes a function with signature:
|
* Takes a function with signature:
|
||||||
* (parent:Instruction, child:Instruction) => {}
|
* (parent:Instruction, child:Instruction) => {}
|
||||||
*/
|
*/
|
||||||
traverseSync(fn:Function) {
|
traverseSync(fn:Function): void {
|
||||||
this.forEachChild((childInstruction, _) => fn(this, childInstruction));
|
this.forEachChild((childInstruction, _) => fn(this, childInstruction));
|
||||||
this.forEachChild((childInstruction, _) => childInstruction.traverseSync(fn));
|
this.forEachChild((childInstruction, _) => childInstruction.traverseSync(fn));
|
||||||
}
|
}
|
||||||
|
@ -70,7 +71,7 @@ export class Instruction {
|
||||||
* Takes a function with signature:
|
* Takes a function with signature:
|
||||||
* (child:Instruction, parentOutletName:string) => {}
|
* (child:Instruction, parentOutletName:string) => {}
|
||||||
*/
|
*/
|
||||||
traverseAsync(fn:Function) {
|
traverseAsync(fn:Function):Promise {
|
||||||
return this.mapChildrenAsync(fn)
|
return this.mapChildrenAsync(fn)
|
||||||
.then((_) => this.mapChildrenAsync((childInstruction, _) => childInstruction.traverseAsync(fn)));
|
.then((_) => this.mapChildrenAsync((childInstruction, _) => childInstruction.traverseAsync(fn)));
|
||||||
}
|
}
|
||||||
|
@ -79,7 +80,7 @@ export class Instruction {
|
||||||
/**
|
/**
|
||||||
* Takes a currently active instruction and sets a reuse flag on this instruction
|
* Takes a currently active instruction and sets a reuse flag on this instruction
|
||||||
*/
|
*/
|
||||||
reuseComponentsFrom(oldInstruction:Instruction) {
|
reuseComponentsFrom(oldInstruction:Instruction): void {
|
||||||
this.forEachChild((childInstruction, outletName) => {
|
this.forEachChild((childInstruction, outletName) => {
|
||||||
var oldInstructionChild = oldInstruction.getChildInstruction(outletName);
|
var oldInstructionChild = oldInstruction.getChildInstruction(outletName);
|
||||||
if (shouldReuseComponent(childInstruction, oldInstructionChild)) {
|
if (shouldReuseComponent(childInstruction, oldInstructionChild)) {
|
||||||
|
@ -89,16 +90,16 @@ export class Instruction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function shouldReuseComponent(instr1:Instruction, instr2:Instruction) {
|
function shouldReuseComponent(instr1:Instruction, instr2:Instruction): boolean {
|
||||||
return instr1.component == instr2.component &&
|
return instr1.component == instr2.component &&
|
||||||
StringMapWrapper.equals(instr1.params, instr2.params);
|
StringMapWrapper.equals(instr1.params, instr2.params);
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapObjAsync(obj:StringMap, fn) {
|
function mapObjAsync(obj:StringMap, fn): Promise {
|
||||||
return PromiseWrapper.all(mapObj(obj, fn));
|
return PromiseWrapper.all(mapObj(obj, fn));
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapObj(obj:StringMap, fn):List {
|
function mapObj(obj:StringMap, fn: Function):List {
|
||||||
var result = ListWrapper.create();
|
var result = ListWrapper.create();
|
||||||
StringMapWrapper.forEach(obj, (value, key) => ListWrapper.push(result, fn(value, key)));
|
StringMapWrapper.forEach(obj, (value, key) => ListWrapper.push(result, fn(value, key)));
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -13,62 +13,62 @@ export class Location {
|
||||||
this._browserLocation.onPopState((_) => this._onPopState(_));
|
this._browserLocation.onPopState((_) => this._onPopState(_));
|
||||||
}
|
}
|
||||||
|
|
||||||
_onPopState(_) {
|
_onPopState(_): void {
|
||||||
ObservableWrapper.callNext(this._subject, {
|
ObservableWrapper.callNext(this._subject, {
|
||||||
'url': this.path()
|
'url': this.path()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
path() {
|
path(): string {
|
||||||
return this.normalize(this._browserLocation.path());
|
return this.normalize(this._browserLocation.path());
|
||||||
}
|
}
|
||||||
|
|
||||||
normalize(url) {
|
normalize(url: string): string {
|
||||||
return this._stripBaseHref(stripIndexHtml(url));
|
return this._stripBaseHref(stripIndexHtml(url));
|
||||||
}
|
}
|
||||||
|
|
||||||
normalizeAbsolutely(url) {
|
normalizeAbsolutely(url: string): string {
|
||||||
if (url[0] != '/') {
|
if (url[0] != '/') {
|
||||||
url = '/' + url;
|
url = '/' + url;
|
||||||
}
|
}
|
||||||
return this._addBaseHref(url);
|
return this._addBaseHref(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
_stripBaseHref(url) {
|
_stripBaseHref(url: string): string {
|
||||||
if (this._baseHref.length > 0 && StringWrapper.startsWith(url, this._baseHref)) {
|
if (this._baseHref.length > 0 && StringWrapper.startsWith(url, this._baseHref)) {
|
||||||
return StringWrapper.substring(url, this._baseHref.length);
|
return StringWrapper.substring(url, this._baseHref.length);
|
||||||
}
|
}
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
_addBaseHref(url) {
|
_addBaseHref(url: string): string {
|
||||||
if (!StringWrapper.startsWith(url, this._baseHref)) {
|
if (!StringWrapper.startsWith(url, this._baseHref)) {
|
||||||
return this._baseHref + url;
|
return this._baseHref + url;
|
||||||
}
|
}
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
go(url:string) {
|
go(url:string): void {
|
||||||
var finalUrl = this.normalizeAbsolutely(url);
|
var finalUrl = this.normalizeAbsolutely(url);
|
||||||
this._browserLocation.pushState(null, '', finalUrl);
|
this._browserLocation.pushState(null, '', finalUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
forward() {
|
forward(): void {
|
||||||
this._browserLocation.forward();
|
this._browserLocation.forward();
|
||||||
}
|
}
|
||||||
|
|
||||||
back() {
|
back(): void {
|
||||||
this._browserLocation.back();
|
this._browserLocation.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
subscribe(onNext, onThrow = null, onReturn = null) {
|
subscribe(onNext, onThrow = null, onReturn = null): void {
|
||||||
ObservableWrapper.subscribe(this._subject, onNext, onThrow, onReturn);
|
ObservableWrapper.subscribe(this._subject, onNext, onThrow, onReturn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function stripIndexHtml(url) {
|
function stripIndexHtml(url: string): string {
|
||||||
// '/index.html'.length == 11
|
// '/index.html'.length == 11
|
||||||
if (url.length > 10 && StringWrapper.substring(url, url.length - 11) == '/index.html') {
|
if (url.length > 10 && StringWrapper.substring(url, url.length - 11) == '/index.html') {
|
||||||
return StringWrapper.substring(url, 0, url.length - 11);
|
return StringWrapper.substring(url, 0, url.length - 11);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {RegExp, RegExpWrapper, RegExpMatcherWrapper, StringWrapper, isPresent, isBlank, BaseException} from 'angular2/src/facade/lang';
|
import {RegExp, RegExpWrapper, RegExpMatcherWrapper, StringWrapper, isPresent, isBlank, BaseException, normalizeBlank} from 'angular2/src/facade/lang';
|
||||||
import {Map, MapWrapper, StringMap, StringMapWrapper, List, ListWrapper} from 'angular2/src/facade/collection';
|
import {Map, MapWrapper, StringMap, StringMapWrapper, List, ListWrapper} from 'angular2/src/facade/collection';
|
||||||
|
|
||||||
import {escapeRegex} from './url';
|
import {escapeRegex} from './url';
|
||||||
|
@ -7,13 +7,14 @@ class StaticSegment {
|
||||||
string:string;
|
string:string;
|
||||||
regex:string;
|
regex:string;
|
||||||
name:string;
|
name:string;
|
||||||
|
|
||||||
constructor(string:string) {
|
constructor(string:string) {
|
||||||
this.string = string;
|
this.string = string;
|
||||||
this.name = '';
|
this.name = '';
|
||||||
this.regex = escapeRegex(string);
|
this.regex = escapeRegex(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
generate(params) {
|
generate(params): string {
|
||||||
return this.string;
|
return this.string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,11 +27,11 @@ class DynamicSegment {
|
||||||
this.regex = "([^/]+)";
|
this.regex = "([^/]+)";
|
||||||
}
|
}
|
||||||
|
|
||||||
generate(params:StringMap) {
|
generate(params:StringMap<string, string>): string {
|
||||||
if (!StringMapWrapper.contains(params, this.name)) {
|
if (!StringMapWrapper.contains(params, this.name)) {
|
||||||
throw new BaseException(`Route generator for '${this.name}' was not included in parameters passed.`)
|
throw new BaseException(`Route generator for '${this.name}' was not included in parameters passed.`)
|
||||||
}
|
}
|
||||||
return StringMapWrapper.get(params, this.name);
|
return normalizeBlank(StringMapWrapper.get(params, this.name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,8 +44,8 @@ class StarSegment {
|
||||||
this.regex = "(.+)";
|
this.regex = "(.+)";
|
||||||
}
|
}
|
||||||
|
|
||||||
generate(params:StringMap) {
|
generate(params:StringMap<string, string>): string {
|
||||||
return StringMapWrapper.get(params, this.name);
|
return normalizeBlank(StringMapWrapper.get(params, this.name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,9 +83,8 @@ function parsePathString(route:string) {
|
||||||
return {segments: results, cost};
|
return {segments: results, cost};
|
||||||
}
|
}
|
||||||
|
|
||||||
var SLASH_RE = RegExpWrapper.create('/');
|
|
||||||
function splitBySlash (url:string):List<string> {
|
function splitBySlash (url:string):List<string> {
|
||||||
return StringWrapper.split(url, SLASH_RE);
|
return url.split('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ export class PathRecognizer {
|
||||||
|
|
||||||
constructor(path:string, handler:any) {
|
constructor(path:string, handler:any) {
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
this.segments = ListWrapper.create();
|
this.segments = [];
|
||||||
|
|
||||||
// TODO: use destructuring assignment
|
// TODO: use destructuring assignment
|
||||||
// see https://github.com/angular/ts2dart/issues/158
|
// see https://github.com/angular/ts2dart/issues/158
|
||||||
|
@ -115,7 +115,7 @@ export class PathRecognizer {
|
||||||
this.cost = cost;
|
this.cost = cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
parseParams(url:string):StringMap {
|
parseParams(url:string):StringMap<string, string> {
|
||||||
var params = StringMapWrapper.create();
|
var params = StringMapWrapper.create();
|
||||||
var urlPart = url;
|
var urlPart = url;
|
||||||
for(var i=0; i<this.segments.length; i++) {
|
for(var i=0; i<this.segments.length; i++) {
|
||||||
|
@ -130,7 +130,7 @@ export class PathRecognizer {
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
generate(params:StringMap):string {
|
generate(params:StringMap<string, string>):string {
|
||||||
return ListWrapper.join(ListWrapper.map(this.segments, (segment) =>
|
return ListWrapper.join(ListWrapper.map(this.segments, (segment) =>
|
||||||
'/' + segment.generate(params)), '');
|
'/' + segment.generate(params)), '');
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,8 @@ import {Instruction} from './instruction';
|
||||||
* "Steps" are conceptually similar to "middleware"
|
* "Steps" are conceptually similar to "middleware"
|
||||||
*/
|
*/
|
||||||
export class Pipeline {
|
export class Pipeline {
|
||||||
steps:List;
|
steps:List<Function>;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.steps = [
|
this.steps = [
|
||||||
instruction => instruction.traverseSync((parentInstruction, childInstruction) => {
|
instruction => instruction.traverseSync((parentInstruction, childInstruction) => {
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {List, Map} from 'angular2/src/facade/collection';
|
||||||
*/
|
*/
|
||||||
export class RouteConfig {
|
export class RouteConfig {
|
||||||
configs:List<Map>;
|
configs:List<Map>;
|
||||||
|
|
||||||
@CONST()
|
@CONST()
|
||||||
constructor(configs:List<Map>) {
|
constructor(configs:List<Map>) {
|
||||||
this.configs = configs;
|
this.configs = configs;
|
||||||
|
|
|
@ -14,11 +14,11 @@ export class RouteRecognizer {
|
||||||
this.redirects = MapWrapper.create();
|
this.redirects = MapWrapper.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
addRedirect(path:string, target:string) {
|
addRedirect(path:string, target:string): void {
|
||||||
MapWrapper.set(this.redirects, path, target);
|
MapWrapper.set(this.redirects, path, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
addConfig(path:string, handler:any, alias:string = null) {
|
addConfig(path:string, handler:any, alias:string = null): void {
|
||||||
var recognizer = new PathRecognizer(path, handler);
|
var recognizer = new PathRecognizer(path, handler);
|
||||||
MapWrapper.set(this.matchers, recognizer.regex, recognizer);
|
MapWrapper.set(this.matchers, recognizer.regex, recognizer);
|
||||||
if (isPresent(alias)) {
|
if (isPresent(alias)) {
|
||||||
|
@ -59,12 +59,12 @@ export class RouteRecognizer {
|
||||||
return solutions;
|
return solutions;
|
||||||
}
|
}
|
||||||
|
|
||||||
hasRoute(name:string) {
|
hasRoute(name:string): boolean {
|
||||||
return MapWrapper.contains(this.names, name);
|
return MapWrapper.contains(this.names, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
generate(name:string, params:any) {
|
generate(name:string, params:any): string {
|
||||||
var pathRecognizer = MapWrapper.get(this.names, name);
|
var pathRecognizer = MapWrapper.get(this.names, name);
|
||||||
return pathRecognizer.generate(params);
|
return isPresent(pathRecognizer) ? pathRecognizer.generate(params) : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ export class RouteRegistry {
|
||||||
this._rules = MapWrapper.create();
|
this._rules = MapWrapper.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
config(parentComponent, config) {
|
config(parentComponent, config: StringMap<string, any>): void {
|
||||||
if (!StringMapWrapper.contains(config, 'path')) {
|
if (!StringMapWrapper.contains(config, 'path')) {
|
||||||
throw new BaseException('Route config does not contain "path"');
|
throw new BaseException('Route config does not contain "path"');
|
||||||
}
|
}
|
||||||
|
@ -23,10 +23,9 @@ export class RouteRegistry {
|
||||||
throw new BaseException('Route config does not contain "component," "components," or "redirectTo"');
|
throw new BaseException('Route config does not contain "component," "components," or "redirectTo"');
|
||||||
}
|
}
|
||||||
|
|
||||||
var recognizer:RouteRecognizer;
|
var recognizer:RouteRecognizer = MapWrapper.get(this._rules, parentComponent);
|
||||||
if (MapWrapper.contains(this._rules, parentComponent)) {
|
|
||||||
recognizer = MapWrapper.get(this._rules, parentComponent);
|
if (isBlank(recognizer)) {
|
||||||
} else {
|
|
||||||
recognizer = new RouteRecognizer();
|
recognizer = new RouteRecognizer();
|
||||||
MapWrapper.set(this._rules, parentComponent, recognizer);
|
MapWrapper.set(this._rules, parentComponent, recognizer);
|
||||||
}
|
}
|
||||||
|
@ -46,7 +45,7 @@ export class RouteRegistry {
|
||||||
recognizer.addConfig(config['path'], config, config['as']);
|
recognizer.addConfig(config['path'], config, config['as']);
|
||||||
}
|
}
|
||||||
|
|
||||||
configFromComponent(component) {
|
configFromComponent(component): void {
|
||||||
if (!isType(component)) {
|
if (!isType(component)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -71,14 +70,14 @@ export class RouteRegistry {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
recognize(url:string, parentComponent) {
|
recognize(url:string, parentComponent): Instruction {
|
||||||
var componentRecognizer = MapWrapper.get(this._rules, parentComponent);
|
var componentRecognizer = MapWrapper.get(this._rules, parentComponent);
|
||||||
if (isBlank(componentRecognizer)) {
|
if (isBlank(componentRecognizer)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var componentSolutions = componentRecognizer.recognize(url);
|
var componentSolutions = componentRecognizer.recognize(url);
|
||||||
var fullSolutions = ListWrapper.create();
|
var fullSolutions = [];
|
||||||
|
|
||||||
for(var i = 0; i < componentSolutions.length; i++) {
|
for(var i = 0; i < componentSolutions.length; i++) {
|
||||||
var candidate = componentSolutions[i];
|
var candidate = componentSolutions[i];
|
||||||
|
@ -120,16 +119,14 @@ export class RouteRegistry {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
generate(name:string, params:any, hostComponent) {
|
generate(name:string, params:StringMap<string, string>, hostComponent): string {
|
||||||
//TODO: implement for hierarchical routes
|
//TODO: implement for hierarchical routes
|
||||||
var componentRecognizer = MapWrapper.get(this._rules, hostComponent);
|
var componentRecognizer = MapWrapper.get(this._rules, hostComponent);
|
||||||
if (isPresent(componentRecognizer)) {
|
return isPresent(componentRecognizer) ? componentRecognizer.generate(name, params) : null;
|
||||||
return componentRecognizer.generate(name, params);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handlerToLeafInstructions(context, parentComponent) {
|
function handlerToLeafInstructions(context, parentComponent): Instruction {
|
||||||
var children = StringMapWrapper.create();
|
var children = StringMapWrapper.create();
|
||||||
StringMapWrapper.forEach(context['handler']['components'], (component, outletName) => {
|
StringMapWrapper.forEach(context['handler']['components'], (component, outletName) => {
|
||||||
children[outletName] = new Instruction({
|
children[outletName] = new Instruction({
|
||||||
|
@ -150,7 +147,7 @@ function handlerToLeafInstructions(context, parentComponent) {
|
||||||
// { component: Foo }
|
// { component: Foo }
|
||||||
// mutates the config to:
|
// mutates the config to:
|
||||||
// { components: { default: Foo } }
|
// { components: { default: Foo } }
|
||||||
function normalizeConfig(config:StringMap) {
|
function normalizeConfig(config:StringMap<string, any>): StringMap<string, any> {
|
||||||
if (StringMapWrapper.contains(config, 'component')) {
|
if (StringMapWrapper.contains(config, 'component')) {
|
||||||
var component = StringMapWrapper.get(config, 'component');
|
var component = StringMapWrapper.get(config, 'component');
|
||||||
var components = StringMapWrapper.create();
|
var components = StringMapWrapper.create();
|
||||||
|
|
|
@ -51,18 +51,22 @@ export class Router {
|
||||||
/**
|
/**
|
||||||
* Constructs a child router. You probably don't need to use this unless you're writing a reusable component.
|
* Constructs a child router. You probably don't need to use this unless you're writing a reusable component.
|
||||||
*/
|
*/
|
||||||
childRouter(outletName = 'default') {
|
childRouter(outletName = 'default'): Router {
|
||||||
if (!MapWrapper.contains(this._children, outletName)) {
|
var router = MapWrapper.get(this._children, outletName);
|
||||||
MapWrapper.set(this._children, outletName, new ChildRouter(this, outletName));
|
|
||||||
|
if (isBlank(router)) {
|
||||||
|
router = new ChildRouter(this, outletName);
|
||||||
|
MapWrapper.set(this._children, outletName, router);
|
||||||
}
|
}
|
||||||
return MapWrapper.get(this._children, outletName);
|
|
||||||
|
return router;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register an object to notify of route changes. You probably don't need to use this unless you're writing a reusable component.
|
* Register an object to notify of route changes. You probably don't need to use this unless you're writing a reusable component.
|
||||||
*/
|
*/
|
||||||
registerOutlet(outlet:RouterOutlet, name = 'default'):Promise {
|
registerOutlet(outlet:RouterOutlet, name: string = 'default'):Promise {
|
||||||
MapWrapper.set(this._outlets, name, outlet);
|
MapWrapper.set(this._outlets, name, outlet);
|
||||||
if (isPresent(this._currentInstruction)) {
|
if (isPresent(this._currentInstruction)) {
|
||||||
var childInstruction = this._currentInstruction.getChildInstruction(name);
|
var childInstruction = this._currentInstruction.getChildInstruction(name);
|
||||||
|
@ -91,12 +95,12 @@ export class Router {
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
config(config:any) {
|
config(config:any): Promise {
|
||||||
if (config instanceof List) {
|
if (config instanceof List) {
|
||||||
config.forEach((configObject) => {
|
config.forEach((configObject) => {
|
||||||
// TODO: this is a hack
|
// TODO: this is a hack
|
||||||
this._registry.config(this.hostComponent, configObject);
|
this._registry.config(this.hostComponent, configObject);
|
||||||
})
|
});
|
||||||
} else {
|
} else {
|
||||||
this._registry.config(this.hostComponent, config);
|
this._registry.config(this.hostComponent, config);
|
||||||
}
|
}
|
||||||
|
@ -140,18 +144,18 @@ export class Router {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
_startNavigating() {
|
_startNavigating(): void {
|
||||||
this.navigating = true;
|
this.navigating = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_finishNavigating() {
|
_finishNavigating(): void {
|
||||||
this.navigating = false;
|
this.navigating = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscribe to URL updates from the router
|
* Subscribe to URL updates from the router
|
||||||
*/
|
*/
|
||||||
subscribe(onNext) {
|
subscribe(onNext): void {
|
||||||
ObservableWrapper.subscribe(this._subject, onNext);
|
ObservableWrapper.subscribe(this._subject, onNext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +186,7 @@ export class Router {
|
||||||
/**
|
/**
|
||||||
* Given a URL, returns an instruction representing the component graph
|
* Given a URL, returns an instruction representing the component graph
|
||||||
*/
|
*/
|
||||||
recognize(url:string) {
|
recognize(url:string): Instruction {
|
||||||
return this._registry.recognize(url, this.hostComponent);
|
return this._registry.recognize(url, this.hostComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,7 +206,7 @@ export class Router {
|
||||||
/**
|
/**
|
||||||
* Generate a URL from a component name and optional map of parameters. The URL is relative to the app's base href.
|
* Generate a URL from a component name and optional map of parameters. The URL is relative to the app's base href.
|
||||||
*/
|
*/
|
||||||
generate(name:string, params:any) {
|
generate(name:string, params:StringMap<string, string>): string {
|
||||||
return this._registry.generate(name, params, this.hostComponent);
|
return this._registry.generate(name, params, this.hostComponent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -223,7 +227,7 @@ class ChildRouter extends Router {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapObjAsync(obj:Map, fn) {
|
function mapObjAsync(obj:Map, fn): Promise {
|
||||||
return PromiseWrapper.all(mapObj(obj, fn));
|
return PromiseWrapper.all(mapObj(obj, fn));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ import {Location} from './location';
|
||||||
export class RouterLink {
|
export class RouterLink {
|
||||||
_domEl;
|
_domEl;
|
||||||
_route:string;
|
_route:string;
|
||||||
_params:any;
|
_params:StringMap<string, string>;
|
||||||
_router:Router;
|
_router:Router;
|
||||||
_location:Location;
|
_location:Location;
|
||||||
_href:string;
|
_href:string;
|
||||||
|
@ -56,15 +56,15 @@ export class RouterLink {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
set route(changes) {
|
set route(changes: string) {
|
||||||
this._route = changes;
|
this._route = changes;
|
||||||
}
|
}
|
||||||
|
|
||||||
set params(changes) {
|
set params(changes: StringMap) {
|
||||||
this._params = changes;
|
this._params = changes;
|
||||||
}
|
}
|
||||||
|
|
||||||
onAllChangesDone() {
|
onAllChangesDone(): void {
|
||||||
if (isPresent(this._route) && isPresent(this._params)) {
|
if (isPresent(this._route) && isPresent(this._params)) {
|
||||||
var newHref = this._router.generate(this._route, this._params);
|
var newHref = this._router.generate(this._route, this._params);
|
||||||
this._href = this._location.normalizeAbsolutely(newHref);
|
this._href = this._location.normalizeAbsolutely(newHref);
|
||||||
|
|
|
@ -29,7 +29,7 @@ export class RouterOutlet {
|
||||||
this._router.registerOutlet(this, nameAttr);
|
this._router.registerOutlet(this, nameAttr);
|
||||||
}
|
}
|
||||||
|
|
||||||
activate(instruction:Instruction) {
|
activate(instruction:Instruction): Promise {
|
||||||
return this._compiler.compileInHost(instruction.component).then((pv) => {
|
return this._compiler.compileInHost(instruction.component).then((pv) => {
|
||||||
var outletInjector = this._injector.resolveAndCreateChild([
|
var outletInjector = this._injector.resolveAndCreateChild([
|
||||||
bind(RouteParams).toValue(new RouteParams(instruction.params)),
|
bind(RouteParams).toValue(new RouteParams(instruction.params)),
|
||||||
|
@ -41,11 +41,11 @@ export class RouterOutlet {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
canActivate(instruction:any) {
|
canActivate(instruction:Instruction): Promise<boolean> {
|
||||||
return PromiseWrapper.resolve(true);
|
return PromiseWrapper.resolve(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
canDeactivate(instruction:any) {
|
canDeactivate(instruction:Instruction): Promise<boolean> {
|
||||||
return PromiseWrapper.resolve(true);
|
return PromiseWrapper.resolve(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ var specialCharacters = [
|
||||||
|
|
||||||
var escapeRe = RegExpWrapper.create('(\\' + specialCharacters.join('|\\') + ')', 'g');
|
var escapeRe = RegExpWrapper.create('(\\' + specialCharacters.join('|\\') + ')', 'g');
|
||||||
|
|
||||||
export function escapeRegex(string:string) {
|
export function escapeRegex(string:string): string {
|
||||||
return StringWrapper.replaceAllMapped(string, escapeRe, (match) => {
|
return StringWrapper.replaceAllMapped(string, escapeRe, (match) => {
|
||||||
return "\\" + match;
|
return "\\" + match;
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue