UNPKG

ui-router

Version:

State-based routing for Javascript

52 lines (41 loc) 1.64 kB
/** @module state */ /** for typedoc */ import {isString} from "../common/predicates"; import {StateOrName} from "./interface"; import {State} from "./module"; export class StateMatcher { constructor (private _states: { [key: string]: State }) { } isRelative(stateName: string) { stateName = stateName || ""; return stateName.indexOf(".") === 0 || stateName.indexOf("^") === 0; } find(stateOrName: StateOrName, base?: StateOrName): State { if (!stateOrName && stateOrName !== "") return undefined; let isStr = isString(stateOrName); let name: string = isStr ? stateOrName : (<any>stateOrName).name; if (this.isRelative(name)) name = this.resolvePath(name, base); let state = this._states[name]; if (state && (isStr || (!isStr && (state === stateOrName || state.self === stateOrName)))) { return state; } return undefined; } resolvePath(name: string, base: StateOrName) { if (!base) throw new Error(`No reference point given for path '${name}'`); let baseState: State = this.find(base); let splitName = name.split("."), i = 0, pathLength = splitName.length, current = baseState; for (; i < pathLength; i++) { if (splitName[i] === "" && i === 0) { current = baseState; continue; } if (splitName[i] === "^") { if (!current.parent) throw new Error(`Path '${name}' not valid for state '${baseState.name}'`); current = current.parent; continue; } break; } let relName = splitName.slice(i).join("."); return current.name + (current.name && relName ? "." : "") + relName; } }