1212import {
1313 PUSH_ACTION ,
1414 POP_ACTION2 ,
15+ POP_TO ,
1516 JUMP_ACTION ,
1617 REPLACE_ACTION ,
1718 RESET_ACTION ,
@@ -56,18 +57,30 @@ function inject(state, action, props, scenes) {
5657 return state ;
5758 }
5859 let ind ;
60+
5961 switch ( action . type ) {
62+ case POP_TO : {
63+ const targetIndex = action . targetIndex ;
64+
65+ return {
66+ ...state ,
67+ index : targetIndex ,
68+ children : state . children . slice ( 0 , ( targetIndex + 1 ) ) ,
69+ } ;
70+ }
71+
6072 case POP_ACTION2 :
6173 case POP_ACTION :
6274 assert ( ! state . tabs , 'pop() operation cannot be run on tab bar (tabs=true)' ) ;
6375 if ( state . index === 0 ) {
6476 return state ;
6577 }
78+
6679 return {
6780 ...state ,
6881 index : state . index - 1 ,
6982 from : state . children [ state . children . length - 1 ] ,
70- children : state . children . slice ( 0 , - 1 ) ,
83+ children : state . children . slice ( 0 , - 1 ) ,
7184 } ;
7285 case REFRESH_ACTION :
7386 return props . base ?
@@ -203,11 +216,38 @@ function reducer({ initialState, scenes }) {
203216 } else {
204217 // set current route for pop action or refresh action
205218 if ( action . type === POP_ACTION || action . type === POP_ACTION2 ||
206- action . type === REFRESH_ACTION ) {
219+ action . type === REFRESH_ACTION || action . type === POP_TO ) {
207220 if ( ! action . key && ! action . parent ) {
208221 action = { ...getCurrent ( state ) , ...action } ;
209222 }
210223 }
224+
225+ // Find the parent and index of the future state
226+ if ( action . type === POP_TO ) {
227+ const target = action . data ;
228+ assert ( target , 'PopTo() must be called with scene name' ) ;
229+
230+ const targetEl = findElement ( state , target , action . type ) ;
231+ assert ( targetEl , `Cannot find element name named ${ target } within current state` ) ;
232+
233+ // target is a node
234+ let parent = targetEl . sceneKey ;
235+ let targetIndex = 0 ;
236+
237+ // target is child of a node
238+ if ( ! targetEl . children ) {
239+ const targetParent = findElement ( state , targetEl . parent , action . type ) ;
240+ assert ( targetParent , `Cannot find parent for target ${ target } ` ) ;
241+ parent = targetParent . sceneKey ;
242+
243+ targetIndex = targetParent . children . indexOf ( targetEl ) ;
244+ assert ( targetIndex > - 1 , `${ target } does not belong to ${ targetParent . sceneKey } ` ) ;
245+ }
246+
247+ action . parent = parent ;
248+ action . targetIndex = targetIndex ;
249+ }
250+
211251 // recursive pop parent
212252 if ( action . type === POP_ACTION || action . type === POP_ACTION2 ) {
213253 const parent = action . parent || state . scenes [ action . key ] . parent ;
@@ -219,9 +259,11 @@ function reducer({ initialState, scenes }) {
219259 action . parent = el . sceneKey ;
220260 }
221261 }
262+
222263 switch ( action . type ) {
223264 case POP_ACTION2 :
224265 case POP_ACTION :
266+ case POP_TO :
225267 case REFRESH_ACTION :
226268 case PUSH_ACTION :
227269 case JUMP_ACTION :
0 commit comments