3
3
import { extend , tail , assertPredicate , unnestR , identity } from "../common/common" ;
4
4
import { isArray } from "../common/predicates" ;
5
5
6
- import { TransitionOptions , TransitionHookOptions , IHookRegistry , TreeChanges , IEventHook , IMatchingNodes } from "./interface" ;
6
+ import {
7
+ TransitionOptions , TransitionHookOptions , IHookRegistry , TreeChanges , IEventHook , IMatchingNodes ,
8
+ TransitionHookPhase , TransitionHookScope
9
+ } from "./interface" ;
7
10
8
11
import { Transition } from "./transition" ;
9
12
import { TransitionHook } from "./transitionHook" ;
10
13
import { State } from "../state/stateObject" ;
11
14
import { PathNode } from "../path/node" ;
12
15
import { TransitionService } from "./transitionService" ;
13
- import { ResolveContext } from "../resolve/resolveContext " ;
16
+ import { TransitionHookType } from "./transitionHookType " ;
14
17
15
18
/**
16
19
* This class returns applicable TransitionHooks for a specific Transition instance.
@@ -28,37 +31,32 @@ import {ResolveContext} from "../resolve/resolveContext";
28
31
*/
29
32
export class HookBuilder {
30
33
34
+ private $transitions : TransitionService ;
35
+ private baseHookOptions : TransitionHookOptions ;
36
+
31
37
treeChanges : TreeChanges ;
32
38
transitionOptions : TransitionOptions ;
33
39
34
40
toState : State ;
35
41
fromState : State ;
36
42
37
- constructor ( private $transitions : TransitionService , private transition : Transition , private baseHookOptions : TransitionHookOptions ) {
43
+ constructor ( private transition : Transition ) {
38
44
this . treeChanges = transition . treeChanges ( ) ;
45
+ this . transitionOptions = transition . options ( ) ;
39
46
this . toState = tail ( this . treeChanges . to ) . state ;
40
47
this . fromState = tail ( this . treeChanges . from ) . state ;
41
- this . transitionOptions = transition . options ( ) ;
48
+ this . $transitions = transition . router . transitionService ;
49
+ this . baseHookOptions = < TransitionHookOptions > {
50
+ transition : transition ,
51
+ current : transition . options ( ) . current
52
+ } ;
42
53
}
43
54
44
- getOnBeforeHooks = ( ) => this . _buildNodeHooks ( "onBefore" , "to" , tupleSort ( ) ) ;
45
- getOnStartHooks = ( ) => this . _buildNodeHooks ( "onStart" , "to" , tupleSort ( ) ) ;
46
- getOnExitHooks = ( ) => this . _buildNodeHooks ( "onExit" , "exiting" , tupleSort ( true ) , { stateHook : true } ) ;
47
- getOnRetainHooks = ( ) => this . _buildNodeHooks ( "onRetain" , "retained" , tupleSort ( false ) , { stateHook : true } ) ;
48
- getOnEnterHooks = ( ) => this . _buildNodeHooks ( "onEnter" , "entering" , tupleSort ( false ) , { stateHook : true } ) ;
49
- getOnFinishHooks = ( ) => this . _buildNodeHooks ( "onFinish" , "to" , tupleSort ( ) ) ;
50
- getOnSuccessHooks = ( ) => this . _buildNodeHooks ( "onSuccess" , "to" , tupleSort ( ) , { rejectIfSuperseded : false } ) ;
51
- getOnErrorHooks = ( ) => this . _buildNodeHooks ( "onError" , "to" , tupleSort ( ) , { rejectIfSuperseded : false } ) ;
52
-
53
- asyncHooks ( ) {
54
- let onStartHooks = this . getOnStartHooks ( ) ;
55
- let onExitHooks = this . getOnExitHooks ( ) ;
56
- let onRetainHooks = this . getOnRetainHooks ( ) ;
57
- let onEnterHooks = this . getOnEnterHooks ( ) ;
58
- let onFinishHooks = this . getOnFinishHooks ( ) ;
59
-
60
- let asyncHooks = [ onStartHooks , onExitHooks , onRetainHooks , onEnterHooks , onFinishHooks ] ;
61
- return asyncHooks . reduce ( unnestR , [ ] ) . filter ( identity ) ;
55
+ buildHooksForPhase ( phase : TransitionHookPhase ) : TransitionHook [ ] {
56
+ return this . $transitions . getTransitionHookTypes ( phase )
57
+ . map ( type => this . buildHooks ( type ) )
58
+ . reduce ( unnestR , [ ] )
59
+ . filter ( identity ) ;
62
60
}
63
61
64
62
/**
@@ -68,44 +66,35 @@ export class HookBuilder {
68
66
* - Finds [[PathNode]] (or `PathNode[]`) to use as the TransitionHook context(s)
69
67
* - For each of the [[PathNode]]s, creates a TransitionHook
70
68
*
71
- * @param hookType the name of the hook registration function, e.g., 'onEnter', 'onFinish'.
72
- * @param matchingNodesProp selects which [[PathNode]]s from the [[IMatchingNodes]] object to create hooks for.
73
- * @param getLocals a function which accepts a [[PathNode]] and returns additional locals to provide to the hook as injectables
74
- * @param sortHooksFn a function which compares two HookTuple and returns <1, 0, or >1
75
- * @param options any specific Transition Hook Options
69
+ * @param hookType the type of the hook registration function, e.g., 'onEnter', 'onFinish'.
76
70
*/
77
- private _buildNodeHooks ( hookType : string ,
78
- matchingNodesProp : string ,
79
- sortHooksFn : ( l : HookTuple , r : HookTuple ) => number ,
80
- options ?: TransitionHookOptions ) : TransitionHook [ ] {
81
-
71
+ buildHooks ( hookType : TransitionHookType ) : TransitionHook [ ] {
82
72
// Find all the matching registered hooks for a given hook type
83
- let matchingHooks = this . _matchingHooks ( hookType , this . treeChanges ) ;
73
+ let matchingHooks = this . _matchingHooks ( hookType . name , this . treeChanges ) ;
84
74
if ( ! matchingHooks ) return [ ] ;
85
75
86
76
const makeTransitionHooks = ( hook : IEventHook ) => {
87
77
// Fetch the Nodes that caused this hook to match.
88
78
let matches : IMatchingNodes = hook . matches ( this . treeChanges ) ;
89
79
// Select the PathNode[] that will be used as TransitionHook context objects
90
- let matchingNodes : PathNode [ ] = matches [ matchingNodesProp ] ;
91
-
92
- // When invoking 'exiting' hooks, give them the "from path" for resolve data.
93
- // Everything else gets the "to path"
94
- let resolvePath = matchingNodesProp === 'exiting' ? this . treeChanges . from : this . treeChanges . to ;
95
- let resolveContext = new ResolveContext ( resolvePath ) ;
80
+ let matchingNodes : PathNode [ ] = matches [ hookType . criteriaMatchPath ] ;
96
81
97
82
// Return an array of HookTuples
98
83
return matchingNodes . map ( node => {
99
- let _options = extend ( { bind : hook . bind , traceData : { hookType, context : node } } , this . baseHookOptions , options ) ;
100
- let state = _options . stateHook ? node . state : null ;
84
+ let _options = extend ( {
85
+ bind : hook . bind ,
86
+ traceData : { hookType : hookType . name , context : node }
87
+ } , this . baseHookOptions ) ;
88
+
89
+ let state = hookType . hookScope === TransitionHookScope . STATE ? node . state : null ;
101
90
let transitionHook = new TransitionHook ( this . transition , state , hook , _options ) ;
102
91
return < HookTuple > { hook, node, transitionHook } ;
103
92
} ) ;
104
93
} ;
105
94
106
95
return matchingHooks . map ( makeTransitionHooks )
107
96
. reduce ( unnestR , [ ] )
108
- . sort ( sortHooksFn )
97
+ . sort ( tupleSort ( hookType . reverseSort ) )
109
98
. map ( tuple => tuple . transitionHook ) ;
110
99
}
111
100
0 commit comments