|
1 | 1 | import {extend, isString} from "../common/common"
|
2 | 2 | import StateReference from "./stateReference"
|
| 3 | +import {IState, IStateDeclaration} from "./interface" |
3 | 4 |
|
4 |
| -export default function StateMatcher(states) { |
5 |
| - extend(this, { |
6 |
| - isRelative: function(stateName) { |
7 |
| - stateName = stateName || ""; |
8 |
| - return stateName.indexOf(".") === 0 || stateName.indexOf("^") === 0; |
9 |
| - }, |
| 5 | +type PStateRef = (string|IStateDeclaration|IState); |
10 | 6 |
|
11 |
| - find: function(stateOrName, base) { |
12 |
| - if (!stateOrName && stateOrName !== "") return undefined; |
13 |
| - var isStr = isString(stateOrName), name = isStr ? stateOrName : stateOrName.name; |
14 | 7 |
|
15 |
| - if (this.isRelative(name)) name = this.resolvePath(name, base); |
16 |
| - var state = states[name]; |
| 8 | +export default class StateMatcher { |
| 9 | + constructor (private _states: {[key: string]: IState}) { } |
| 10 | + |
| 11 | + isRelative(stateName: string) { |
| 12 | + stateName = stateName || ""; |
| 13 | + return stateName.indexOf(".") === 0 || stateName.indexOf("^") === 0; |
| 14 | + } |
17 | 15 |
|
18 |
| - if (state && (isStr || (!isStr && (state === stateOrName || state.self === stateOrName)))) { |
19 |
| - return state; |
| 16 | + |
| 17 | + find(stateOrName: PStateRef, base?: PStateRef): IState { |
| 18 | + if (!stateOrName && stateOrName !== "") return undefined; |
| 19 | + let isStr = isString(stateOrName); |
| 20 | + let name: string = isStr ? stateOrName : (<any>stateOrName).name; |
| 21 | + |
| 22 | + if (this.isRelative(name)) name = this.resolvePath(name, base); |
| 23 | + var state = this._states[name]; |
| 24 | + |
| 25 | + if (state && (isStr || (!isStr && (state === stateOrName || state.self === stateOrName)))) { |
| 26 | + return state; |
| 27 | + } |
| 28 | + return undefined; |
| 29 | + } |
| 30 | + |
| 31 | + reference(identifier: PStateRef, base: PStateRef, params): StateReference { |
| 32 | + return new StateReference(identifier, this.find(identifier, base), params, base); |
| 33 | + } |
| 34 | + |
| 35 | + resolvePath(name: string, base: PStateRef) { |
| 36 | + if (!base) throw new Error(`No reference point given for path '${name}'`); |
| 37 | + |
| 38 | + let baseState: IState = this.find(base); |
| 39 | + |
| 40 | + var splitName = name.split("."), i = 0, pathLength = splitName.length, current = baseState; |
| 41 | + |
| 42 | + for (; i < pathLength; i++) { |
| 43 | + if (splitName[i] === "" && i === 0) { |
| 44 | + current = baseState; |
| 45 | + continue; |
20 | 46 | }
|
21 |
| - return undefined; |
22 |
| - }, |
23 |
| - |
24 |
| - reference: function(identifier, base, params) { |
25 |
| - return new StateReference(identifier, this.find(identifier, base), params, base); |
26 |
| - }, |
27 |
| - |
28 |
| - resolvePath: function(name, base) { |
29 |
| - if (!base) throw new Error(`No reference point given for path '${name}'`); |
30 |
| - base = this.find(base); |
31 |
| - |
32 |
| - var rel = name.split("."), i = 0, pathLength = rel.length, current = base; |
33 |
| - |
34 |
| - for (; i < pathLength; i++) { |
35 |
| - if (rel[i] === "" && i === 0) { |
36 |
| - current = base; |
37 |
| - continue; |
38 |
| - } |
39 |
| - if (rel[i] === "^") { |
40 |
| - if (!current.parent) throw new Error(`Path '${name}' not valid for state '${base.name}'`); |
41 |
| - current = current.parent; |
42 |
| - continue; |
43 |
| - } |
44 |
| - break; |
| 47 | + if (splitName[i] === "^") { |
| 48 | + if (!current.parent) throw new Error(`Path '${name}' not valid for state '${baseState.name}'`); |
| 49 | + current = current.parent; |
| 50 | + continue; |
45 | 51 | }
|
46 |
| - rel = rel.slice(i).join("."); |
47 |
| - return current.name + (current.name && rel ? "." : "") + rel; |
| 52 | + break; |
48 | 53 | }
|
49 |
| - }); |
| 54 | + let relName = splitName.slice(i).join("."); |
| 55 | + return current.name + (current.name && relName ? "." : "") + relName; |
| 56 | + } |
50 | 57 | }
|
0 commit comments