Skip to content

Commit cc76df2

Browse files
committed
refactor(*): consolidate path handling
1 parent 33e38b1 commit cc76df2

34 files changed

+456
-681
lines changed

src/common/common.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -391,8 +391,9 @@ export function padString(length: number, str: string) {
391391
return str;
392392
}
393393

394-
export function tail(array: any[]) {
395-
return array.length && array[array.length - 1] || undefined;
394+
export function tail<T>(collection: T[]): T;
395+
export function tail(collection: any[]): any {
396+
return collection.length && collection[collection.length - 1] || undefined;
396397
}
397398

398399

src/params/interface.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import ParamValues from "./paramValues";
2-
31
export interface IRawParams {
42
[key: string]: any
53
}
6-
export type IParamsOrArray = (IRawParams|IRawParams[]|ParamValues);
4+
export type IParamsOrArray = (IRawParams|IRawParams[]);

src/params/module.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
import * as param from "./param";
22
export {param};
33

4-
import * as paramSet from "./paramSet";
5-
export {paramSet};
6-
74
import * as paramTypes from "./paramTypes";
85
export {paramTypes};
96

10-
import * as paramValues from "./paramValues";
11-
export {paramValues};
12-
137
import * as type from "./type";
148
export {type};

src/params/param.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import {isInjectable, extend, isDefined, isString, isArray, filter, map, pick, prop, propEq, curry} from "../common/common";
1+
import {isInjectable, extend, isDefined, isString, isArray, filter, map, pick, prop, propEq, curry, applyPairs} from "../common/common";
2+
import {IRawParams} from "../params/interface";
23
import {runtime} from "../common/angular1";
34
import matcherConfig from "../url/urlMatcherConfig";
45
import paramTypes from "./paramTypes";
@@ -143,4 +144,20 @@ export default class Param {
143144
static fromSearch(id: string, type: Type, config: any): Param {
144145
return new Param(id, type, config, DefType.SEARCH);
145146
}
147+
148+
static values(params: Param[], values): IRawParams {
149+
values = values || {};
150+
return <IRawParams> params.map(param => [param.id, param.value(values[param.id])]).reduce(applyPairs, {});
151+
}
152+
153+
static equals(params: Param[], values1, values2): boolean {
154+
values1 = values1 || {};
155+
values2 = values2 || {};
156+
return params.map(param => param.type.equals(values1[param.id], values2[param.id])).indexOf(false) === -1;
157+
}
158+
159+
static validates(params: Param[], values): boolean {
160+
values = values || {};
161+
return params.map(param => param.validates(values[param.id])).indexOf(false) === -1;
162+
}
146163
}

src/params/paramSet.ts

Lines changed: 0 additions & 75 deletions
This file was deleted.

src/params/paramValues.ts

Lines changed: 0 additions & 31 deletions
This file was deleted.

src/path/interface.ts

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,29 @@
1-
2-
import Path from "./../path/path";
3-
4-
import {IState} from "../state/interface";
1+
import {State} from "../state/state";
2+
import Node from "../path/node";
53

64
import {ViewConfig} from "../view/view";
75

86
import {IRawParams} from "../params/interface";
9-
import ParamValues from "../params/paramValues";
107

118
import {IResolvables} from "../resolve/interface";
129
import ResolveContext from "../resolve/resolveContext";
1310
import ResolveInjector from "../resolve/resolveInjector";
1411

15-
/** Base data (contains a state) for a node in a Path */
16-
export interface INode {
17-
state: IState;
18-
}
19-
/** A basic Path. Each node contains an IState */
20-
export interface IPath extends Path<INode> {}
2112

22-
23-
/** Contains INode base data plus raw params values for the node */
24-
export interface IParamsNode extends INode {
25-
ownParamValues: IRawParams;
13+
/** Contains Node base data plus raw params values for the node */
14+
export interface IParamsNode extends Node {
15+
values: IRawParams;
2616
}
27-
/** A Path of IParamsNode(s) */
28-
export interface IParamsPath extends Path<IParamsNode> {}
29-
3017

3118
/** Contains IParamsNode data, plus Resolvables for the node */
3219
export interface IResolveNode extends IParamsNode {
33-
ownResolvables: IResolvables;
20+
resolves: IResolvables;
3421
}
35-
/** A Path of IResolveNode(s) */
36-
export interface IResolvePath extends Path<IResolveNode> {}
3722

3823
/** Contains IResolveNode data, plus a ResolveContext and ParamsValues (bound to a full path) for the node, */
3924
export interface ITransNode extends IResolveNode {
4025
resolveContext: ResolveContext;
4126
resolveInjector: ResolveInjector;
4227
views: ViewConfig[];
43-
paramValues: ParamValues;
28+
// paramValues: ParamValues;
4429
}
45-
/**
46-
* A Path of ITransNode(s). Each node contains raw param values, Resolvables and also a ResolveContext
47-
* and ParamValues which are bound to the overall path, but isolated to the node.
48-
*/
49-
export interface ITransPath extends Path<ITransNode> {}

src/path/module.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import * as path from "./path";
2-
export {path};
1+
import * as Node from "./node";
2+
export {Node};
33

44
import * as pathFactory from "./pathFactory";
55
export {pathFactory};

src/path/node.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/// <reference path='../../typings/angularjs/angular.d.ts' />
2+
import {extend, pick, prop, propEq, pairs, map, find} from "../common/common";
3+
import {State} from "../state/state";
4+
import Param from "../params/param";
5+
import Type from "../params/type";
6+
import {IRawParams} from "../params/interface";
7+
import Resolvable from "../resolve/resolvable";
8+
import ResolveContext from "../resolve/resolveContext";
9+
import ResolveInjector from "../resolve/resolveInjector";
10+
import {ViewConfig} from "../view/view";
11+
12+
export default class Node {
13+
14+
public schema: Param[];
15+
public values: { [key: string]: any };
16+
public resolves: any;
17+
public views: ViewConfig[];
18+
public resolveContext: ResolveContext;
19+
public resolveInjector: ResolveInjector;
20+
21+
// Possibly extract this logic into an intermediary object that maps states to nodes
22+
constructor(public state: State, params: IRawParams, resolves: any = {}) {
23+
const schema: Param[] = state.parameters({ inherit: false });
24+
// schema = keys.map(key => [key, state.parameter(key)]).reduce(applyPairs, {});
25+
26+
// Object.freeze(extend(this, { ... }))
27+
extend(this, {
28+
state,
29+
schema,
30+
values: pick(params, schema.map(prop('id'))),
31+
resolves: map(
32+
extend(state.resolve || {}, resolves),
33+
(fn: Function, name: string) => new Resolvable(name, fn, state)
34+
),
35+
views: pairs(state.views || {}).map(([rawViewName, viewDeclarationObj]): ViewConfig => {
36+
return new ViewConfig({
37+
rawViewName, viewDeclarationObj, context: state, params
38+
});
39+
})
40+
});
41+
}
42+
43+
parameter(name: string): Param {
44+
return find(this.schema, prop('id'));
45+
}
46+
47+
equals(node: Node, keys?: string[]): boolean {
48+
return this.state === node.state && (keys || Object.keys(this.values)).map(key => {
49+
return this.parameter(key).type.equals(this.values[key], node.values[key]);
50+
}).reduce((previous, current) => previous && current, true);
51+
}
52+
53+
static clone(node: Node, update: any = {}) {
54+
return new Node(node.state, update.params || node.values, update.resolves || map(node.resolves, prop('resolveFn')));
55+
}
56+
57+
/**
58+
* Returns a new path which is a subpath of this path. The new path starts from root and contains any nodes
59+
* that match the nodes in the second path. Nodes are compared using their state properties.
60+
* @param first {Node[]}
61+
* @param second {Node[]}
62+
* @returns {Node[]}
63+
*/
64+
static matching(first: Node[], second: Node[]): Node[] {
65+
let matchedCount = first.reduce((prev, node, i) =>
66+
prev === i && i < second.length && node.state === second[i].state ? i + 1 : prev, 0);
67+
return first.slice(matchedCount);
68+
}
69+
}

0 commit comments

Comments
 (0)