@@ -12,27 +12,31 @@ import {
12
12
StateService ,
13
13
} from '@uirouter/core' ;
14
14
15
+ import { DSRDataStore , StateObjectDataStore } from './DSRDataStore' ;
15
16
import { _DSRConfig , DSRConfigObj , DSRFunction , DSRProp , ParamPredicate , RecordedDSR } from './interface' ;
16
17
17
18
class DSRPlugin implements UIRouterPlugin {
18
19
name = 'deep-state-redirect' ;
19
20
21
+ dataStore : DSRDataStore ;
20
22
$transitions : TransitionService ;
21
23
$state : StateService ;
22
24
hookDeregFns = [ ] ;
23
25
24
- constructor ( $uiRouter : UIRouter ) {
26
+ constructor ( $uiRouter : UIRouter , options : { dataStore : DSRDataStore } ) {
25
27
this . $transitions = $uiRouter . transitionService ;
26
28
this . $state = $uiRouter . stateService ;
29
+ this . dataStore = ( options && options . dataStore ) || new StateObjectDataStore ( ) ;
30
+ this . dataStore . init ( $uiRouter ) ;
27
31
28
32
this . hookDeregFns . push (
29
- this . $transitions . onRetain ( { retained : state => ! ! this . getDsrProp ( state . self ) } , this . recordDeepState . bind ( this ) ) ,
33
+ this . $transitions . onRetain ( { retained : state => ! ! this . getDsrProp ( state . self ) } , this . recordDeepState . bind ( this ) )
30
34
) ;
31
35
this . hookDeregFns . push (
32
- this . $transitions . onEnter ( { entering : state => ! ! this . getDsrProp ( state . self ) } , this . recordDeepState . bind ( this ) ) ,
36
+ this . $transitions . onEnter ( { entering : state => ! ! this . getDsrProp ( state . self ) } , this . recordDeepState . bind ( this ) )
33
37
) ;
34
38
this . hookDeregFns . push (
35
- this . $transitions . onBefore ( { to : state => ! ! this . getDsrProp ( state . self ) } , this . deepStateRedirect . bind ( this ) ) ,
39
+ this . $transitions . onBefore ( { to : state => ! ! this . getDsrProp ( state . self ) } , this . deepStateRedirect . bind ( this ) )
36
40
) ;
37
41
}
38
42
@@ -58,12 +62,13 @@ class DSRPlugin implements UIRouterPlugin {
58
62
reset ( state ?: StateOrName , params ?: RawParams ) : void {
59
63
const { $state } = this ;
60
64
if ( ! state ) {
61
- $state . get ( ) . forEach ( _state => delete _state . $$state ( ) . $dsr ) ;
65
+ $state . get ( ) . forEach ( _state => this . dataStore . set ( _state , undefined ) ) ;
62
66
} else if ( ! params ) {
63
- delete $state . get ( state ) . $$state ( ) . $dsr ;
67
+ this . dataStore . set ( state , undefined ) ;
64
68
} else {
69
+ const currentDSRS = this . dataStore . get ( state ) ;
65
70
const $$state = $state . get ( state ) . $$state ( ) ;
66
- $$state . $dsr = ( $$ state. $dsr as RecordedDSR [ ] ) . filter ( this . paramsEqual ( $$state , params , undefined , true ) ) ;
71
+ this . dataStore . set ( state , currentDSRS . filter ( this . paramsEqual ( $$state , params , undefined , true ) ) ) ;
67
72
}
68
73
}
69
74
@@ -85,7 +90,7 @@ class DSRPlugin implements UIRouterPlugin {
85
90
return state . deepStateRedirect || state . dsr ;
86
91
}
87
92
88
- private getConfig ( state : StateDeclaration ) : _DSRConfig {
93
+ public getConfig ( state : StateDeclaration ) : _DSRConfig {
89
94
const { $state } = this ;
90
95
const dsrProp : DSRProp = this . getDsrProp ( state ) ;
91
96
if ( typeof dsrProp === 'undefined' ) return ;
@@ -116,11 +121,11 @@ class DSRPlugin implements UIRouterPlugin {
116
121
return { default : defaultTarget , params, fn } ;
117
122
}
118
123
119
- private paramsEqual (
124
+ public paramsEqual (
120
125
state : StateObject ,
121
126
transParams : RawParams ,
122
127
paramPredicate : ParamPredicate = ( ) => true ,
123
- negate = false ,
128
+ negate = false
124
129
) : ( redirect : RecordedDSR ) => boolean {
125
130
const schema = state . parameters ( { inherit : true } ) . filter ( paramPredicate ) ;
126
131
@@ -132,26 +137,29 @@ class DSRPlugin implements UIRouterPlugin {
132
137
133
138
private recordDeepState ( transition : Transition , state : StateDeclaration ) : void {
134
139
const { $state } = this ;
135
- const paramsConfig = this . getConfig ( state ) . params ;
136
- const _state = state . $$state ( ) ;
140
+ const hasParamsConfig : boolean = ! ! this . getConfig ( state ) . params ;
141
+ const _state : StateObject = state . $$state ( ) ;
137
142
138
143
transition . promise . then ( ( ) => {
139
144
const transTo = transition . to ( ) ;
140
- const transParams = transition . params ( ) ;
141
- const recordedDsrTarget = $state . target ( transTo , transParams ) ;
142
-
143
- if ( paramsConfig ) {
144
- const recordedDSR = ( _state . $dsr as RecordedDSR [ ] ) || [ ] ;
145
- const predicate = this . paramsEqual ( transTo . $$state ( ) , transParams , undefined , true ) ;
146
- _state . $dsr = recordedDSR . filter ( predicate ) ;
147
- _state . $dsr . push ( { triggerParams : transParams , target : recordedDsrTarget } ) ;
145
+ const triggerParams = transition . params ( ) ;
146
+ const target : TargetState = $state . target ( transTo , triggerParams ) ;
147
+ const targetStateName = target . name ( ) ;
148
+ const targetParams = target . params ( ) ;
149
+ const recordedDSR : RecordedDSR = { triggerParams, targetStateName, targetParams } ;
150
+
151
+ if ( hasParamsConfig ) {
152
+ const currentDSRS : RecordedDSR [ ] = this . dataStore . get ( _state ) ;
153
+ const predicate = this . paramsEqual ( transTo . $$state ( ) , triggerParams , undefined , true ) ;
154
+ const updatedDSRS = currentDSRS . filter ( predicate ) . concat ( recordedDSR ) ;
155
+ this . dataStore . set ( _state , updatedDSRS ) ;
148
156
} else {
149
- _state . $dsr = recordedDsrTarget ;
157
+ this . dataStore . set ( _state , [ recordedDSR ] ) ;
150
158
}
151
159
} ) ;
152
160
}
153
161
154
- private deepStateRedirect ( transition : Transition ) {
162
+ private deepStateRedirect ( transition : Transition ) : TargetState | undefined {
155
163
const opts = transition . options ( ) ;
156
164
if ( opts [ 'ignoreDsr' ] || ( opts . custom && opts . custom . ignoreDsr ) ) return ;
157
165
@@ -165,22 +173,27 @@ class DSRPlugin implements UIRouterPlugin {
165
173
return redirect ;
166
174
}
167
175
176
+ private getTargetState ( dsr : RecordedDSR ) : TargetState {
177
+ return this . $state . target ( dsr . targetStateName , dsr . targetParams ) ;
178
+ }
179
+
168
180
private getDeepStateRedirect ( stateOrName : StateOrName , params : RawParams ) : TargetState {
169
181
const { $state } = this ;
170
182
const _state = $state . get ( stateOrName ) ;
171
183
const state = _state && _state . $$state ( ) ;
172
184
const config : _DSRConfig = this . getConfig ( _state ) ;
173
- let dsrTarget : TargetState ;
185
+ const currentDSRS = this . dataStore . get ( stateOrName ) ;
186
+ let recordedDSR : RecordedDSR ;
174
187
175
188
if ( config . params ) {
176
189
const predicate = this . paramsEqual ( state , params , config . params , false ) ;
177
- const match = state . $dsr && ( state . $dsr as RecordedDSR [ ] ) . filter ( predicate ) [ 0 ] ;
178
- dsrTarget = match && match . target ;
190
+ const match = currentDSRS . find ( predicate ) ;
191
+ recordedDSR = match && match ;
179
192
} else {
180
- dsrTarget = state . $dsr as TargetState ;
193
+ recordedDSR = currentDSRS [ 0 ] && currentDSRS [ 0 ] ;
181
194
}
182
195
183
- dsrTarget = dsrTarget || config . default ;
196
+ let dsrTarget = recordedDSR ? this . getTargetState ( recordedDSR ) : config . default ;
184
197
185
198
if ( dsrTarget ) {
186
199
// merge original params with deep state redirect params
0 commit comments