diff --git a/src/ng1/directives/viewDirective.ts b/src/ng1/directives/viewDirective.ts index ac47a25fc..d6e14bfc7 100644 --- a/src/ng1/directives/viewDirective.ts +++ b/src/ng1/directives/viewDirective.ts @@ -9,7 +9,7 @@ import {TransitionService} from "../../transition/transitionService"; import {parse} from "../../common/hof"; import {ResolveContext} from "../../resolve/resolveContext"; import {Transition} from "../../transition/transition"; -import {Node} from "../../path/node"; +import {PathNode} from "../../path/node"; import {Param} from "../../params/param"; import {kebobString} from "../../common/strings"; import {HookRegOptions} from "../../transition/interface"; @@ -401,8 +401,8 @@ function registerControllerCallbacks($transitions: TransitionService, controller let toParams = $transition$.params("to"); let fromParams = $transition$.params("from"); - let toSchema: Param[] = $transition$.treeChanges().to.map((node: Node) => node.paramSchema).reduce(unnestR, []); - let fromSchema: Param[] = $transition$.treeChanges().from.map((node: Node) => node.paramSchema).reduce(unnestR, []); + let toSchema: Param[] = $transition$.treeChanges().to.map((node: PathNode) => node.paramSchema).reduce(unnestR, []); + let fromSchema: Param[] = $transition$.treeChanges().from.map((node: PathNode) => node.paramSchema).reduce(unnestR, []); // Find the to params that have different values than the from params let changedToParams = toSchema.filter((param: Param) => { diff --git a/src/ng1/legacy/resolveService.ts b/src/ng1/legacy/resolveService.ts index 3ab644044..e0a3dbc36 100644 --- a/src/ng1/legacy/resolveService.ts +++ b/src/ng1/legacy/resolveService.ts @@ -1,5 +1,5 @@ import {State} from "../../state/stateObject"; -import {Node} from "../../path/node"; +import {PathNode} from "../../path/node"; import {ResolveContext} from "../../resolve/resolveContext"; import {Resolvable} from "../../resolve/resolvable"; import {map} from "../../common/common"; @@ -12,8 +12,8 @@ export const resolveFactory = () => ({ * @param parent a promise for a "parent resolve" */ resolve: (invocables, locals = {}, parent?) => { - let parentNode = new Node(new State( { params: {} })); - let node = new Node(new State( { params: {} })); + let parentNode = new PathNode(new State( { params: {} })); + let node = new PathNode(new State( { params: {} })); let context = new ResolveContext([parentNode, node]); context.addResolvables(Resolvable.makeResolvables(invocables), node.state); diff --git a/src/ng1/services.ts b/src/ng1/services.ts index 116bf4bda..679498068 100644 --- a/src/ng1/services.ts +++ b/src/ng1/services.ts @@ -15,7 +15,7 @@ import {services} from "../common/coreservices"; import {map, bindFunctions, removeFrom, find, noop} from "../common/common"; import {prop, propEq} from "../common/hof"; import {isObject} from "../common/predicates"; -import {Node} from "../path/node"; +import {PathNode} from "../path/node"; import {resolveFactory} from "./legacy/resolveService"; import {trace} from "../common/trace"; import {ng1ViewsBuilder, ng1ViewConfigFactory, Ng1ViewConfig} from "./statebuilders/views"; @@ -260,7 +260,7 @@ function getTransitionsProvider() { // TODO: check if we can remove loadAllControllerLocals. Shouldn't be necessary without JIT resolve policy function loadAllControllerLocals($transition$: Transition) { const loadLocals = (vc: Ng1ViewConfig) => { - let node = ( find($transition$.treeChanges().to, propEq('state', vc.viewDecl.$context))); + let node = ( find($transition$.treeChanges().to, propEq('state', vc.viewDecl.$context))); // Temporary fix; This whole callback should be nuked when fixing #2662 if (!node) return services.$q.when(); let resolveCtx = node.resolveContext; diff --git a/src/ng1/statebuilders/views.ts b/src/ng1/statebuilders/views.ts index 3ba432069..ca40d2730 100644 --- a/src/ng1/statebuilders/views.ts +++ b/src/ng1/statebuilders/views.ts @@ -8,7 +8,7 @@ import {ViewService} from "../../view/view"; import {isInjectable, isDefined, isString, isObject} from "../../common/predicates"; import {services} from "../../common/coreservices"; import {trace} from "../../common/trace"; -import {Node} from "../../path/node"; +import {PathNode} from "../../path/node"; import {TemplateFactory} from "../templateFactory"; import {ResolveContext} from "../../resolve/resolveContext"; @@ -104,7 +104,7 @@ export class Ng1ViewConfig implements ViewConfig { template: string; locals: any; // TODO: delete me - constructor(public node: Node, public viewDecl: Ng1ViewDeclaration) { } + constructor(public node: PathNode, public viewDecl: Ng1ViewDeclaration) { } load() { let $q = services.$q; diff --git a/src/ng2/directives/uiSrefStatus.ts b/src/ng2/directives/uiSrefStatus.ts index 570cf1689..cd0bf0bbf 100644 --- a/src/ng2/directives/uiSrefStatus.ts +++ b/src/ng2/directives/uiSrefStatus.ts @@ -2,7 +2,7 @@ import {Directive, Output, EventEmitter} from "@angular/core"; import {StateService} from "../../state/stateService"; import {UiSref} from "./uiSref"; -import {Node} from "../../path/node"; +import {PathNode} from "../../path/node"; import {TransitionService} from "../../transition/transitionService"; import {Transition} from "../../transition/transition"; import {TargetState} from "../../state/targetState"; @@ -95,18 +95,18 @@ export class UiSrefStatus { /** - * Returns a Predicate that returns true when the target state (and any param values) + * Returns a Predicate that returns true when the target state (and any param values) * match the (tail of) the path, and the path's param values */ const pathMatches = (target: TargetState) => { let state: State = target.$state(); let targetParamVals = target.params(); - let targetPath: Node[] = PathFactory.buildPath(target); + let targetPath: PathNode[] = PathFactory.buildPath(target); let paramSchema: Param[] = targetPath.map(node => node.paramSchema) .reduce(unnestR, []) .filter((param: Param) => targetParamVals.hasOwnProperty(param.id)); - return (path: Node[]) => { + return (path: PathNode[]) => { let tailNode = tail(path); if (!tailNode || tailNode.state !== state) return false; var paramValues = PathFactory.paramValues(path); @@ -121,7 +121,7 @@ export class UiSrefStatus { * Expands the path to [c], [c, d] * Then appends each to [a,b,] and returns: [a, b, c], [a, b, c, d] */ - function spreadToSubPaths (path: Node[], appendTo: Node[] = []): Node[][] { + function spreadToSubPaths (path: PathNode[], appendTo: PathNode[] = []): PathNode[][] { return path.map(node => appendTo.concat(PathFactory.subPath(path, node.state))); } @@ -135,7 +135,7 @@ export class UiSrefStatus { this._setStatus(status); } - let update = (currentPath: Node[]) => () => { + let update = (currentPath: PathNode[]) => () => { if (this._deregisterHook == null) return; // destroyed if (!$transition$.isActive()) return; // superseded status.active = spreadToSubPaths(currentPath).map(isTarget).reduce(anyTrueR, false); diff --git a/src/ng2/providers.ts b/src/ng2/providers.ts index 28b3c68be..1aef8a349 100644 --- a/src/ng2/providers.ts +++ b/src/ng2/providers.ts @@ -48,7 +48,7 @@ */ /** */ import {Provider, provide} from "@angular/core"; import {UIRouter} from "../router"; -import {Node} from "../path/node"; +import {PathNode} from "../path/node"; import {StateRegistry} from "../state/stateRegistry"; import {StateService} from "../state/stateService"; import {TransitionService} from "../transition/transitionService"; @@ -67,7 +67,7 @@ let uiRouterFactory = (routerConfig: UIRouterConfig, location: UIRouterLocation) location.init(); - router.viewService.viewConfigFactory("ng2", (node: Node, config: Ng2ViewDeclaration) => new Ng2ViewConfig(node, config)); + router.viewService.viewConfigFactory("ng2", (node: PathNode, config: Ng2ViewDeclaration) => new Ng2ViewConfig(node, config)); router.stateRegistry.decorator('views', ng2ViewsBuilder); router.stateRegistry.stateQueue.autoFlush(router.stateService); diff --git a/src/ng2/statebuilders/views.ts b/src/ng2/statebuilders/views.ts index 36aa49ba2..1e717104b 100644 --- a/src/ng2/statebuilders/views.ts +++ b/src/ng2/statebuilders/views.ts @@ -1,6 +1,6 @@ /** @module ng2 */ /** */ import {State} from "../../state/stateObject"; -import {Node} from "../../path/node"; +import {PathNode} from "../../path/node"; import {pick, forEach} from "../../common/common"; import {ViewConfig} from "../../view/interface"; import {Ng2ViewDeclaration} from "../interface"; @@ -39,7 +39,7 @@ export function ng2ViewsBuilder(state: State) { export class Ng2ViewConfig implements ViewConfig { loaded: boolean = true; - constructor(public node: Node, public viewDecl: Ng2ViewDeclaration) { } + constructor(public node: PathNode, public viewDecl: Ng2ViewDeclaration) { } load() { return services.$q.when(this); diff --git a/src/path/node.ts b/src/path/node.ts index 43f5369e4..c4af3a488 100644 --- a/src/path/node.ts +++ b/src/path/node.ts @@ -8,19 +8,34 @@ import {Resolvable} from "../resolve/resolvable"; import {ResolveContext} from "../resolve/resolveContext"; import {ViewConfig} from "../view/interface"; -export class Node { +/** + * A node in a [[TreeChanges]] path + * + * For a [[TreeChanges]] path, this class holds the stateful information for a single node in the path. + * Each PathNode corresponds to a state being entered, exited, or retained. + * The stateful information includes parameter values and resolve data. + */ +export class PathNode { + /** The state being entered, exited, or retained */ public state: State; + /** The parameters declared on the state */ public paramSchema: Param[]; + /** The parameter values that belong to the state */ public paramValues: { [key: string]: any }; + /** A context object used in conjunction with [[resolvables]] to manage resolves */ + public resolveContext: ResolveContext; + /** The individual (stateful) resolvable objects that belong to the state */ public resolvables: Resolvable[]; + /** The state's declared view configuration objects */ public views: ViewConfig[]; - public resolveContext: ResolveContext; - constructor(state: Node); + /** Creates a copy of a PathNode */ + constructor(state: PathNode); + /** Creates a new (empty) PathNode for a State */ constructor(state: State); constructor(state) { - if (state instanceof Node) { - let node: Node = state; + if (state instanceof PathNode) { + let node: PathNode = state; this.state = node.state; this.paramSchema = node.paramSchema.slice(); this.paramValues = extend({}, node.paramValues); @@ -35,23 +50,30 @@ export class Node { } } - applyRawParams(params: RawParams): Node { + /** Sets [[paramValues]] for the node, from the values of an object hash */ + applyRawParams(params: RawParams): PathNode { const getParamVal = (paramDef: Param) => [ paramDef.id, paramDef.value(params[paramDef.id]) ]; this.paramValues = this.paramSchema.reduce((memo, pDef) => applyPairs(memo, getParamVal(pDef)), {}); return this; } + /** Gets a specific [[Param]] metadata that belongs to the node */ parameter(name: string): Param { return find(this.paramSchema, propEq("id", name)); } - equals(node: Node, keys = this.paramSchema.map(prop('id'))): boolean { + /** + * @returns true if the state and parameter values for another PathNode are + * equal to the state and param values for this PathNode + */ + equals(node: PathNode, keys = this.paramSchema.map(prop('id'))): boolean { const paramValsEq = key => this.parameter(key).type.equals(this.paramValues[key], node.paramValues[key]); return this.state === node.state && keys.map(paramValsEq).reduce(allTrueR, true); } - static clone(node: Node) { - return new Node(node); + /** Returns a clone of the PathNode */ + static clone(node: PathNode) { + return new PathNode(node); } /** @@ -60,17 +82,17 @@ export class Node { * The new path starts from root and contains any nodes that match the nodes in the second path. * Nodes are compared using their state property and parameter values. */ - static matching(pathA: Node[], pathB: Node[]): Node[] { + static matching(pathA: PathNode[], pathB: PathNode[]): PathNode[] { let matching = []; - + for (let i = 0; i < pathA.length && i < pathB.length; i++) { let a = pathA[i], b = pathB[i]; - + if (a.state !== b.state) break; if (!Param.equals(a.paramSchema, a.paramValues, b.paramValues)) break; matching.push(a); } - + return matching } } \ No newline at end of file diff --git a/src/path/pathFactory.ts b/src/path/pathFactory.ts index 34357f119..138f07df7 100644 --- a/src/path/pathFactory.ts +++ b/src/path/pathFactory.ts @@ -10,7 +10,7 @@ import {_ViewDeclaration} from "../state/interface"; import {State} from "../state/stateObject"; import {TargetState} from "../state/targetState"; -import {Node} from "../path/node"; +import {PathNode} from "../path/node"; import {ResolveContext} from "../resolve/resolveContext"; import {ViewService} from "../view/view"; @@ -21,20 +21,20 @@ export class PathFactory { constructor() { } - /** Given a Node[], create an TargetState */ - static makeTargetState(path: Node[]): TargetState { + /** Given a PathNode[], create an TargetState */ + static makeTargetState(path: PathNode[]): TargetState { let state = tail(path).state; return new TargetState(state, state, path.map(prop("paramValues")).reduce(mergeR, {})); } static buildPath(targetState: TargetState) { let toParams = targetState.params(); - return targetState.$state().path.map(state => new Node(state).applyRawParams(toParams)); + return targetState.$state().path.map(state => new PathNode(state).applyRawParams(toParams)); } - /** Given a fromPath: Node[] and a TargetState, builds a toPath: Node[] */ - static buildToPath(fromPath: Node[], targetState: TargetState): Node[] { - let toPath: Node[] = PathFactory.buildPath(targetState); + /** Given a fromPath: PathNode[] and a TargetState, builds a toPath: PathNode[] */ + static buildToPath(fromPath: PathNode[], targetState: TargetState): PathNode[] { + let toPath: PathNode[] = PathFactory.buildPath(targetState); if (targetState.options().inherit) { return PathFactory.inheritParams(fromPath, toPath, Object.keys(targetState.params())); } @@ -44,9 +44,9 @@ export class PathFactory { /** * Creates ViewConfig objects and adds to nodes. * - * On each Node, creates ViewConfig objects from the views: property of the node's state + * On each [[PathNode]], creates ViewConfig objects from the views: property of the node's state */ - static applyViewConfigs($view: ViewService, path: Node[]) { + static applyViewConfigs($view: ViewService, path: PathNode[]) { return path.map(node => { let viewDecls: _ViewDeclaration[] = values(node.state.views || {}); let viewConfigs: ViewConfig[][] = viewDecls.map(view => $view.createViewConfig(node, view)); @@ -66,17 +66,17 @@ export class PathFactory { * caller, for instance, $state.transitionTo(..., toParams). If a key was found in toParams, * it is not inherited from the fromPath. */ - static inheritParams(fromPath: Node[], toPath: Node[], toKeys: string[] = []): Node[] { - function nodeParamVals(path: Node[], state: State): RawParams { - let node: Node = find(path, propEq('state', state)); + static inheritParams(fromPath: PathNode[], toPath: PathNode[], toKeys: string[] = []): PathNode[] { + function nodeParamVals(path: PathNode[], state: State): RawParams { + let node: PathNode = find(path, propEq('state', state)); return extend({}, node && node.paramValues); } /** - * Given an Node "toNode", return a new Node with param values inherited from the + * Given an [[PathNode]] "toNode", return a new [[PathNode]] with param values inherited from the * matching node in fromPath. Only inherit keys that aren't found in "toKeys" from the node in "fromPath"" */ - function makeInheritedParamsNode(toNode: Node): Node { + function makeInheritedParamsNode(toNode: PathNode): PathNode { // All param values for the node (may include default key/vals, when key was not found in toParams) let toParamVals = extend({}, toNode && toNode.paramValues); // limited to only those keys found in toParams @@ -85,20 +85,20 @@ export class PathFactory { let fromParamVals = nodeParamVals(fromPath, toNode.state) || {}; // extend toParamVals with any fromParamVals, then override any of those those with incomingParamVals let ownParamVals: RawParams = extend(toParamVals, fromParamVals, incomingParamVals); - return new Node(toNode.state).applyRawParams(ownParamVals); + return new PathNode(toNode.state).applyRawParams(ownParamVals); } // The param keys specified by the incoming toParams - return toPath.map(makeInheritedParamsNode); + return toPath.map(makeInheritedParamsNode); } /** * Given a path of nodes, creates and binds a ResolveContext to each node. * The ResolveContext is used to inject functions from the proper scoping in the resolve tree. */ - static bindResolveContexts(resolvePath: Node[]): Node[] { + static bindResolveContexts(resolvePath: PathNode[]): PathNode[] { let resolveContext = new ResolveContext(resolvePath); - return resolvePath.map((node: Node) => { + return resolvePath.map((node: PathNode) => { node.resolveContext = resolveContext.isolateRootTo(node.state); return node; }); @@ -107,23 +107,23 @@ export class PathFactory { /** * Computes the tree changes (entering, exiting) between a fromPath and toPath. */ - static treeChanges(fromPath: Node[], toPath: Node[], reloadState: State): TreeChanges { + static treeChanges(fromPath: PathNode[], toPath: PathNode[], reloadState: State): TreeChanges { let keep = 0, max = Math.min(fromPath.length, toPath.length); const staticParams = (state) => state.parameters({ inherit: false }).filter(not(prop('dynamic'))).map(prop('id')); - const nodesMatch = (node1: Node, node2: Node) => node1.equals(node2, staticParams(node1.state)); + const nodesMatch = (node1: PathNode, node2: PathNode) => node1.equals(node2, staticParams(node1.state)); while (keep < max && fromPath[keep].state !== reloadState && nodesMatch(fromPath[keep], toPath[keep])) { keep++; } /** Given a retained node, return a new node which uses the to node's param values */ - function applyToParams(retainedNode: Node, idx: number): Node { - let cloned = Node.clone(retainedNode); + function applyToParams(retainedNode: PathNode, idx: number): PathNode { + let cloned = PathNode.clone(retainedNode); cloned.paramValues = toPath[idx].paramValues; return cloned; } - let from: Node[], retained: Node[], exiting: Node[], entering: Node[], to: Node[]; + let from: PathNode[], retained: PathNode[], exiting: PathNode[], entering: PathNode[], to: PathNode[]; from = fromPath; retained = from.slice(0, keep); @@ -143,10 +143,10 @@ export class PathFactory { * Given an array of nodes, returns a subset of the array starting from the first node, up to the * node whose state matches `stateName` * - * @param path a path of [[Node]]s + * @param path a path of [[PathNode]]s * @param state the [[State]] to stop at */ - static subPath(path: Node[], state): Node[] { + static subPath(path: PathNode[], state): PathNode[] { let node = find(path, _node => _node.state === state); let elementIdx = path.indexOf(node); if (elementIdx === -1) throw new Error("The path does not contain the state: " + state); @@ -154,5 +154,5 @@ export class PathFactory { } /** Gets the raw parameter values from a path */ - static paramValues = (path: Node[]) => path.reduce((acc, node) => extend(acc, node.paramValues), {}); + static paramValues = (path: PathNode[]) => path.reduce((acc, node) => extend(acc, node.paramValues), {}); } diff --git a/src/resolve/resolveContext.ts b/src/resolve/resolveContext.ts index d4a0ea45b..1e7a18be1 100644 --- a/src/resolve/resolveContext.ts +++ b/src/resolve/resolveContext.ts @@ -6,7 +6,7 @@ import {trace} from "../common/trace"; import {services} from "../common/coreservices"; import {Resolvables, ResolvePolicy, IOptions1} from "./interface"; -import {Node} from "../path/node"; +import {PathNode} from "../path/node"; import {Resolvable} from "./resolvable"; import {State} from "../state/stateObject"; import {mergeR} from "../common/common"; @@ -20,15 +20,15 @@ interface Promises { [key: string]: Promise; } export class ResolveContext { - private _nodeFor: (s: State) => Node; - private _pathTo: (s: State) => Node[]; + private _nodeFor: (s: State) => PathNode; + private _pathTo: (s: State) => PathNode[]; - constructor(private _path: Node[]) { + constructor(private _path: PathNode[]) { extend(this, { - _nodeFor(state: State): Node { - return find(this._path, propEq('state', state)); + _nodeFor(state: State): PathNode { + return find(this._path, propEq('state', state)); }, - _pathTo(state: State): Node[] { + _pathTo(state: State): PathNode[] { return PathFactory.subPath(this._path, state); } }); @@ -62,7 +62,7 @@ export class ResolveContext { const path = (state ? this._pathTo(state) : this._path); const last = tail(path); - return path.reduce((memo, node: Node) => { + return path.reduce((memo, node: PathNode) => { let omitProps = (node === last) ? options.omitOwnLocals : []; let filteredResolvables = node.resolvables @@ -98,7 +98,7 @@ export class ResolveContext { // Returns a promise for an array of resolved path Element promises resolvePath(options: IOptions1 = {}): Promise { trace.traceResolvePath(this._path, options); - const promiseForNode = (node: Node) => this.resolvePathElement(node.state, options); + const promiseForNode = (node: PathNode) => this.resolvePathElement(node.state, options); return services.$q.all( map(this._path, promiseForNode)).then(all => all.reduce(mergeR, {})); } diff --git a/src/state/hooks/resolveHooks.ts b/src/state/hooks/resolveHooks.ts index 266d0922a..899f4d0cd 100644 --- a/src/state/hooks/resolveHooks.ts +++ b/src/state/hooks/resolveHooks.ts @@ -30,7 +30,7 @@ export class ResolveHooks { return tail( treeChanges.to).resolveContext.resolvePath(extend({ transition: $transition$ }, { resolvePolicy: EAGER })); } - /** Returns a function which pre-resolves any LAZY Resolvables for a Node in a Path */ + /** Returns a function which pre-resolves any LAZY Resolvables for a [[PathNode]] in a Path */ function $lazyResolveEnteringState(transition: Transition, injector, state: State) { let node = find( treeChanges.entering, propEq('state', state)); diff --git a/src/state/stateService.ts b/src/state/stateService.ts index f483c0a94..945e7c370 100644 --- a/src/state/stateService.ts +++ b/src/state/stateService.ts @@ -5,7 +5,7 @@ import {Queue} from "../common/queue"; import {services} from "../common/coreservices"; import {PathFactory} from "../path/pathFactory"; -import {Node} from "../path/node"; +import {PathNode} from "../path/node"; import {ViewService} from "../view/view"; @@ -59,7 +59,7 @@ export class StateService { * If a callback returns an TargetState, then it is used as arguments to $state.transitionTo() and * the result returned. */ - private _handleInvalidTargetState(fromPath: Node[], $to$: TargetState) { + private _handleInvalidTargetState(fromPath: PathNode[], $to$: TargetState) { const latestThing = () => this.globals.transitionHistory.peekTail(); let latest = latestThing(); let $from$ = PathFactory.makeTargetState(fromPath); @@ -275,8 +275,8 @@ export class StateService { let ref: TargetState = this.target(to, toParams, options); let latestSuccess: Transition = this.globals.successfulTransitions.peekTail(); - const rootPath = () => PathFactory.bindResolveContexts([new Node(this.stateRegistry.root())]); - let currentPath: Node[] = latestSuccess ? latestSuccess.treeChanges().to : rootPath(); + const rootPath = () => PathFactory.bindResolveContexts([new PathNode(this.stateRegistry.root())]); + let currentPath: PathNode[] = latestSuccess ? latestSuccess.treeChanges().to : rootPath(); if (!ref.exists()) return this._handleInvalidTargetState(currentPath, ref); diff --git a/src/transition/hookBuilder.ts b/src/transition/hookBuilder.ts index 97e61974e..730b83e06 100644 --- a/src/transition/hookBuilder.ts +++ b/src/transition/hookBuilder.ts @@ -8,7 +8,7 @@ import {TransitionOptions, TransitionHookOptions, IHookRegistry, TreeChanges, IE import {Transition} from "./transition"; import {TransitionHook} from "./transitionHook"; import {State} from "../state/stateObject"; -import {Node} from "../path/node"; +import {PathNode} from "../path/node"; import {TransitionService} from "./transitionService"; /** @@ -64,12 +64,12 @@ export class HookBuilder { * Returns an array of newly built TransitionHook objects. * * - Finds all IEventHooks registered for the given `hookType` which matched the transition's [[TreeChanges]]. - * - Finds [[Node]] (or `Node[]`) to use as the TransitionHook context(s) - * - For each of the [[Node]]s, creates a TransitionHook + * - Finds [[PathNode]] (or `PathNode[]`) to use as the TransitionHook context(s) + * - For each of the [[PathNode]]s, creates a TransitionHook * * @param hookType the name of the hook registration function, e.g., 'onEnter', 'onFinish'. - * @param matchingNodesProp selects which [[Node]]s from the [[IMatchingNodes]] object to create hooks for. - * @param getLocals a function which accepts a [[Node]] and returns additional locals to provide to the hook as injectables + * @param matchingNodesProp selects which [[PathNode]]s from the [[IMatchingNodes]] object to create hooks for. + * @param getLocals a function which accepts a [[PathNode]] and returns additional locals to provide to the hook as injectables * @param sortHooksFn a function which compares two HookTuple and returns <1, 0, or >1 * @param options any specific Transition Hook Options */ @@ -85,8 +85,8 @@ export class HookBuilder { const makeTransitionHooks = (hook: IEventHook) => { // Fetch the Nodes that caused this hook to match. let matches: IMatchingNodes = hook.matches(this.treeChanges); - // Select the Node[] that will be used as TransitionHook context objects - let nodes: Node[] = matches[matchingNodesProp]; + // Select the PathNode[] that will be used as TransitionHook context objects + let nodes: PathNode[] = matches[matchingNodesProp]; // Return an array of HookTuples return nodes.map(node => { @@ -123,12 +123,12 @@ export class HookBuilder { } } -interface HookTuple { hook: IEventHook, node: Node, transitionHook: TransitionHook } +interface HookTuple { hook: IEventHook, node: PathNode, transitionHook: TransitionHook } /** * A factory for a sort function for HookTuples. * - * The sort function first compares the Node depth (how deep in the state tree a node is), then compares + * The sort function first compares the PathNode depth (how deep in the state tree a node is), then compares * the EventHook priority. * * @param reverseDepthSort a boolean, when true, reverses the sort order for the node depth diff --git a/src/transition/hookRegistry.ts b/src/transition/hookRegistry.ts index 2fc76c9fe..33a574fdf 100644 --- a/src/transition/hookRegistry.ts +++ b/src/transition/hookRegistry.ts @@ -1,7 +1,7 @@ /** @module transition */ /** for typedoc */ import {extend, removeFrom, allTrueR, tail} from "../common/common"; import {isString, isFunction} from "../common/predicates"; -import {Node} from "../path/node"; +import {PathNode} from "../path/node"; import {TransitionStateHookFn, TransitionHookFn} from "./interface"; import { @@ -54,7 +54,7 @@ export class EventHook implements IEventHook { this.bind = options.bind || null; } - private static _matchingNodes(nodes: Node[], criterion: HookMatchCriterion): Node[] { + private static _matchingNodes(nodes: PathNode[], criterion: HookMatchCriterion): PathNode[] { if (criterion === true) return nodes; let matching = nodes.filter(node => matchState(node.state, criterion)); return matching.length ? matching : null; @@ -64,7 +64,7 @@ export class EventHook implements IEventHook { * Determines if this hook's [[matchCriteria]] match the given [[TreeChanges]] * * @returns an IMatchingNodes object, or null. If an IMatchingNodes object is returned, its values - * are the matching [[Node]]s for each [[HookMatchCriterion]] (to, from, exiting, retained, entering) + * are the matching [[PathNode]]s for each [[HookMatchCriterion]] (to, from, exiting, retained, entering) */ matches(treeChanges: TreeChanges): IMatchingNodes { let mc = this.matchCriteria, _matchingNodes = EventHook._matchingNodes; diff --git a/src/transition/interface.ts b/src/transition/interface.ts index 994364a2f..156990944 100644 --- a/src/transition/interface.ts +++ b/src/transition/interface.ts @@ -4,7 +4,7 @@ import {Predicate} from "../common/common"; import {Transition} from "./transition"; import {State} from "../state/stateObject"; -import {Node} from "../path/node"; +import {PathNode} from "../path/node"; import {TargetState} from "../state/targetState"; import {UIRInjector} from "../common/interface"; @@ -97,15 +97,17 @@ export interface TransitionHookOptions { /** * TreeChanges encapsulates the various Paths that are involved in a Transition. * + * Get a TreeChanges object using [[Transition.treeChanges]] + * * A UI-Router Transition is from one Path in a State Tree to another Path. For a given Transition, * this object stores the "to" and "from" paths, as well as subsets of those: the "retained", * "exiting" and "entering" paths. * - * Each path in TreeChanges is an array of [[Node]] objects. Each Node in the array corresponds to a portion + * Each path in TreeChanges is an array of [[PathNode]] objects. Each PathNode in the array corresponds to a portion * of a nested state. * * For example, if you had a nested state named `foo.bar.baz`, it would have three - * portions, `foo, bar, baz`. If you transitioned **to** `foo.bar.baz` and inspected the TreeChanges.to + * portions, `foo, bar, baz`. If you transitioned **to** `foo.bar.baz` and inspected the [[TreeChanges.to]] * Path, you would find a node in the array for each portion: `foo`, `bar`, and `baz`. * * --- @@ -114,13 +116,13 @@ export interface TransitionHookOptions { */ export interface TreeChanges { /** @nodoc */ - [key: string]: Node[]; + [key: string]: PathNode[]; /** The path of nodes in the state tree that the transition is coming *from* */ - from: Node[]; + from: PathNode[]; /** The path of nodes in the state tree that the transition is going *to* */ - to: Node[]; + to: PathNode[]; /** * The path of active nodes that the transition is retaining. @@ -128,7 +130,7 @@ export interface TreeChanges { * These nodes are neither exited, nor entered. * Before and after the transition is successful, these nodes are active. */ - retained: Node[]; + retained: PathNode[]; /** * The path of previously active nodes that the transition is exiting. @@ -138,7 +140,7 @@ export interface TreeChanges { * Note that a state that is being reloaded (due to parameter values changing, or `reload: true`) may be in both the * `exiting` and `entering` paths. */ - exiting: Node[]; + exiting: PathNode[]; /** * The path of nodes that the transition is entering. @@ -150,7 +152,7 @@ export interface TreeChanges { * Note that a state that is reloaded (due to parameter values changing, or `reload: true`) may be in both the * `exiting` and `entering` paths. */ - entering: Node[]; + entering: PathNode[]; } export type IErrorHandler = (error: Error) => void; @@ -730,11 +732,11 @@ export interface HookMatchCriteria { } export interface IMatchingNodes { - to: Node[]; - from: Node[]; - exiting: Node[]; - retained: Node[]; - entering: Node[]; + to: PathNode[]; + from: PathNode[]; + exiting: PathNode[]; + retained: PathNode[]; + entering: PathNode[]; } /** diff --git a/src/transition/transition.ts b/src/transition/transition.ts index eb4baf6fc..9106d89e7 100644 --- a/src/transition/transition.ts +++ b/src/transition/transition.ts @@ -14,7 +14,7 @@ import {TransitionOptions, TransitionHookOptions, TreeChanges, IHookRegistry, IH import {TransitionHook} from "./transitionHook"; import {HookRegistry, matchState} from "./hookRegistry"; import {HookBuilder} from "./hookBuilder"; -import {Node} from "../path/node"; +import {PathNode} from "../path/node"; import {PathFactory} from "../path/pathFactory"; import {State} from "../state/stateObject"; import {TargetState} from "../state/targetState"; @@ -131,12 +131,12 @@ export class Transition implements IHookRegistry { * * If the target state is not valid, an error is thrown. * - * @param fromPath The path of [[Node]]s from which the transition is leaving. The last node in the `fromPath` + * @param fromPath The path of [[PathNode]]s from which the transition is leaving. The last node in the `fromPath` * encapsulates the "from state". * @param targetState The target state and parameters being transitioned to (also, the transition options) * @param _transitionService The Transition Service instance */ - constructor(fromPath: Node[], targetState: TargetState, private _transitionService: TransitionService) { + constructor(fromPath: PathNode[], targetState: TargetState, private _transitionService: TransitionService) { if (!targetState.valid()) { throw new Error(targetState.error()); } @@ -157,7 +157,7 @@ export class Transition implements IHookRegistry { new Resolvable('$transition$', () => this, this), new Resolvable('$stateParams', () => this.params(), this.params()) ]; - let rootNode: Node = this._treeChanges.to[0]; + let rootNode: PathNode = this._treeChanges.to[0]; rootNode.resolveContext.addResolvables(rootResolvables, rootNode.state) } @@ -327,12 +327,12 @@ export class Transition implements IHookRegistry { // The redirected transition does not have to re-fetch the resolve. // --------------------------------------------------------- - const nodeIsReloading = (reloadState: State) => (node: Node) => { + const nodeIsReloading = (reloadState: State) => (node: PathNode) => { return reloadState && reloadState.includes[node.state.name]; }; // Find any "entering" nodes in the redirect path that match the original path and aren't being reloaded - let matchingEnteringNodes: Node[] = Node.matching(redirectEnteringNodes, originalEnteringNodes) + let matchingEnteringNodes: PathNode[] = PathNode.matching(redirectEnteringNodes, originalEnteringNodes) .filter(not(nodeIsReloading(targetState.options().reloadState))); // Use the existing (possibly pre-resolved) resolvables for the matching entering nodes. @@ -348,7 +348,7 @@ export class Transition implements IHookRegistry { let {to, from} = this._treeChanges; if (this._options.reload || tail(to).state !== tail(from).state) return undefined; - let nodeSchemas: Param[][] = to.map((node: Node) => node.paramSchema); + let nodeSchemas: Param[][] = to.map((node: PathNode) => node.paramSchema); let [toValues, fromValues] = [to, from].map(path => path.map(x => x.paramValues)); let tuples = arrayTuples(nodeSchemas, toValues, fromValues); diff --git a/src/transition/transitionService.ts b/src/transition/transitionService.ts index 50b2ab843..08f74d5bd 100644 --- a/src/transition/transitionService.ts +++ b/src/transition/transitionService.ts @@ -4,7 +4,7 @@ import { IHookRegistry, TransitionOptions, HookMatchCriteria, HookRegOptions } f import {Transition} from "./transition"; import {HookRegistry} from "./hookRegistry"; import {TargetState} from "../state/targetState"; -import {Node} from "../path/node"; +import {PathNode} from "../path/node"; import {IEventHook} from "./interface"; import {ViewService} from "../view/view"; import {IInjectable} from "../common/common"; @@ -96,7 +96,7 @@ export class TransitionService implements IHookRegistry { * @param targetState the target state (destination) * @returns a Transition */ - create(fromPath: Node[], targetState: TargetState) { + create(fromPath: PathNode[], targetState: TargetState) { return new Transition(fromPath, targetState, this); } } diff --git a/src/view/interface.ts b/src/view/interface.ts index 26249ff1c..bd6d115b7 100644 --- a/src/view/interface.ts +++ b/src/view/interface.ts @@ -1,6 +1,6 @@ /** @module view */ /** for typedoc */ import {_ViewDeclaration} from "../state/interface"; -import {Node} from "../path/node"; +import {PathNode} from "../path/node"; /** * The context ref can be anything that has a `name` and a `parent` reference to another IContextRef @@ -29,7 +29,7 @@ export interface ActiveUIView { } /** - * This interface represents a [[ViewDeclaration]] that is bound to a [[Node]]. + * This interface represents a [[ViewDeclaration]] that is bound to a [[PathNode]]. * * A `ViewConfig` is the runtime definition of a single view. * @@ -46,7 +46,7 @@ export interface ViewConfig { viewDecl: _ViewDeclaration; /** The node the ViewConfig is bound to */ - node: Node; + node: PathNode; /** Fetches templates, runs dynamic (controller|template)Provider code, lazy loads Components, etc */ load(): Promise; diff --git a/src/view/view.ts b/src/view/view.ts index a406e1fe2..9267a7b27 100644 --- a/src/view/view.ts +++ b/src/view/view.ts @@ -3,7 +3,7 @@ import {equals, applyPairs, removeFrom, TypedMap} from "../common/common"; import {curry, prop} from "../common/hof"; import {isString, isArray} from "../common/predicates"; import {trace} from "../common/trace"; -import {Node} from "../path/node"; +import {PathNode} from "../path/node"; import {ActiveUIView, ViewContext, ViewConfig} from "./interface"; import {_ViewDeclaration} from "../state/interface"; @@ -11,7 +11,7 @@ import {_ViewDeclaration} from "../state/interface"; const match = (obj1, ...keys) => (obj2) => keys.reduce((memo, key) => memo && obj1[key] === obj2[key], true); -export type ViewConfigFactory = (node: Node, decl: _ViewDeclaration) => ViewConfig|ViewConfig[]; +export type ViewConfigFactory = (node: PathNode, decl: _ViewDeclaration) => ViewConfig|ViewConfig[]; /** * The View service @@ -32,7 +32,7 @@ export class ViewService { this._viewConfigFactories[viewType] = factory; } - createViewConfig(node: Node, decl: _ViewDeclaration): ViewConfig[] { + createViewConfig(node: PathNode, decl: _ViewDeclaration): ViewConfig[] { let cfgFactory = this._viewConfigFactories[decl.$type]; if (!cfgFactory) throw new Error("ViewService: No view config factory registered for type " + decl.$type); let cfgs = cfgFactory(node, decl); diff --git a/test/core/hookBuilderSpec.ts b/test/core/hookBuilderSpec.ts index ae8795402..1f17e39eb 100644 --- a/test/core/hookBuilderSpec.ts +++ b/test/core/hookBuilderSpec.ts @@ -1,5 +1,5 @@ import { - UIRouter, TransitionService, StateService, State, Node, tail, PathFactory + UIRouter, TransitionService, StateService, State, PathNode, tail, PathFactory } from "../../src/core"; import {tree2Array} from "../stateHelper.ts"; @@ -45,7 +45,7 @@ describe('HookBuilder:', function() { // Transition from 'A' to 'A.B.C' let A = $state.target('A', null).$state(); - let path = [new Node(root), new Node(A)]; + let path = [new PathNode(root), new PathNode(A)]; path = PathFactory.bindResolveContexts(path); trans = $trans.create(path, $state.target("A.B.C", null)); hb = trans.hookBuilder(); @@ -55,7 +55,7 @@ describe('HookBuilder:', function() { let A = $state.target('A', null).$state(); let B = $state.target('A.B', null).$state(); let C = $state.target('A.B.C', null).$state(); - let fromPath = [new Node(root), new Node(A), new Node(B), new Node(C)]; + let fromPath = [new PathNode(root), new PathNode(A), new PathNode(B), new PathNode(C)]; fromPath = PathFactory.bindResolveContexts(fromPath); trans2 = $trans.create(fromPath, $state.target("A", null)); hb2 = trans2.hookBuilder(); diff --git a/test/core/resolveSpec.ts b/test/core/resolveSpec.ts index 42fde06dd..35fad5d3b 100644 --- a/test/core/resolveSpec.ts +++ b/test/core/resolveSpec.ts @@ -3,7 +3,7 @@ import "../matchers.ts" import { - ResolveContext, State, Node, PathFactory + ResolveContext, State, PathNode, PathFactory } from "../../src/core"; import { @@ -82,8 +82,8 @@ beforeEach(function () { } }); -function makePath(names: string[]): Node[] { - let nodes = map(names, name => new Node(statesMap[name])); +function makePath(names: string[]): PathNode[] { + let nodes = map(names, name => new PathNode(statesMap[name])); return PathFactory.bindResolveContexts(nodes); } diff --git a/test/ng1/resolveSpec.ts b/test/ng1/resolveSpec.ts index 8737ca020..0f4cb5235 100644 --- a/test/ng1/resolveSpec.ts +++ b/test/ng1/resolveSpec.ts @@ -2,13 +2,12 @@ import "../testUtilsNg1.js"; import "../matchers.ts"; import { - ResolveContext, State, StateDeclaration, Node, PathFactory, + ResolveContext, State, StateDeclaration, PathNode, PathFactory, omit, map, pick, extend, forEach, prop, copy } from "../../src/ng1"; import Spy = jasmine.Spy; import {tail} from "../../src/common/common"; -import {Node} from "../../src/path/node"; let module = angular.mock.module; /////////////////////////////////////////////// @@ -81,8 +80,8 @@ beforeEach(function () { } }); -function makePath(names: string[]): Node[] { - let nodes = map(names, name => new Node(statesMap[name])); +function makePath(names: string[]): PathNode[] { + let nodes = map(names, name => new PathNode(statesMap[name])); return PathFactory.bindResolveContexts(nodes); } diff --git a/test/ng1/transitionSpec.ts b/test/ng1/transitionSpec.ts index 20f9260df..7cc3b5bf8 100644 --- a/test/ng1/transitionSpec.ts +++ b/test/ng1/transitionSpec.ts @@ -1,4 +1,4 @@ -import {Node} from "../../src/path/node"; +import {PathNode} from "../../src/path/node"; var module = angular.mock.module; import { UIRouter } from "../../src/core"; import { RejectType, Rejection } from "../../src/transition/rejectFactory"; @@ -75,7 +75,7 @@ describe('transition', function () { queue.flush($state); makeTransition = function makeTransition(from, to, options) { let fromState = targetState(from).$state(); - let fromPath = PathFactory.bindResolveContexts(fromState.path.map(state => new Node(state))); + let fromPath = PathFactory.bindResolveContexts(fromState.path.map(state => new PathNode(state))); return $transitions.create(fromPath, targetState(to, null, options)); }; })); diff --git a/test/ng1/viewSpec.ts b/test/ng1/viewSpec.ts index c4a781616..63a4b54f6 100644 --- a/test/ng1/viewSpec.ts +++ b/test/ng1/viewSpec.ts @@ -6,7 +6,7 @@ var module = angular.mock.module; import {inherit, extend, tail} from "../../src/common/common"; import {curry} from "../../src/common/hof"; -import {Node} from "../../src/path/module"; +import {PathNode} from "../../src/path/module"; import {ResolveContext} from "../../src/resolve/module"; import {PathFactory} from "../../src/path/module"; import {ng1ViewsBuilder, ng1ViewConfigFactory} from "../../src/ng1/statebuilders/views"; @@ -66,7 +66,7 @@ describe('view', function() { let $view = new ViewService(); $view.viewConfigFactory("ng1", ng1ViewConfigFactory); - path = PathFactory.bindResolveContexts([root, state].map(_state => new Node(_state, {}))); + path = PathFactory.bindResolveContexts([root, state].map(_state => new PathNode(_state, {}))); path = PathFactory.applyViewConfigs($view, path); ctx = new ResolveContext(path);