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