@@ -5,6 +5,7 @@ import { warn } from '../util/warn'
55import { inBrowser } from '../util/dom'
66import { runQueue } from '../util/async'
77import { START , isSameRoute } from '../util/route'
8+ import { _Vue } from '../install'
89
910export class History {
1011 router : VueRouter ;
@@ -147,53 +148,82 @@ function resolveQueue (
147148 }
148149}
149150
150- function extractGuard ( def , key ) {
151- if ( typeof def === 'function' && def . options ) {
152- return def . options [ key ]
153- } else if ( def ) {
154- return def [ key ]
151+ function extractGuard (
152+ def : Object | Function ,
153+ key : string
154+ ) : NavigationGuard | Array < NavigationGuard > {
155+ if ( typeof def !== 'function' ) {
156+ // extend now so that global mixins are applied.
157+ def = _Vue . extend ( def )
155158 }
159+ return def . options [ key ]
156160}
157161
158162function extractLeaveGuards ( matched : Array < RouteRecord > ) : Array < ?Function > {
159- return flatMapComponents ( matched , ( def , instance ) => {
163+ return flatten ( flatMapComponents ( matched , ( def , instance ) => {
160164 const guard = extractGuard ( def , 'beforeRouteLeave' )
161165 if ( guard ) {
162- return function routeLeaveGuard ( ) {
163- return guard . apply ( instance , arguments )
164- }
166+ return Array . isArray ( guard )
167+ ? guard . map ( guard => wrapLeaveGuard ( guard , instance ) )
168+ : wrapLeaveGuard ( guard , instance )
165169 }
166- } ) . reverse ( )
170+ } ) . reverse ( ) )
171+ }
172+
173+ function wrapLeaveGuard (
174+ guard : NavigationGuard ,
175+ instance : _Vue
176+ ) : NavigationGuard {
177+ return function routeLeaveGuard ( ) {
178+ return guard . apply ( instance , arguments )
179+ }
167180}
168181
169182function extractEnterGuards (
170183 matched : Array < RouteRecord > ,
171184 cbs : Array < Function > ,
172185 isValid : ( ) = > boolean
173186) : Array < ?Function > {
174- return flatMapComponents ( matched , ( def , _ , match , key ) => {
187+ return flatten ( flatMapComponents ( matched , ( def , _ , match , key ) => {
175188 const guard = extractGuard ( def , 'beforeRouteEnter' )
176189 if ( guard ) {
177- return function routeEnterGuard ( to , from , next ) {
178- return guard ( to , from , cb => {
179- next ( cb )
180- if ( typeof cb === 'function' ) {
181- cbs . push ( ( ) => {
182- // #750
183- // if a router-view is wrapped with an out-in transition,
184- // the instance may not have been registered at this time.
185- // we will need to poll for registration until current route
186- // is no longer valid.
187- poll ( cb , match . instances , key , isValid )
188- } )
189- }
190+ return Array . isArray ( guard )
191+ ? guard . map ( guard => wrapEnterGuard ( guard , cbs , match , key , isValid ) )
192+ : wrapEnterGuard ( guard , cbs , match , key , isValid )
193+ }
194+ } ) )
195+ }
196+
197+ function wrapEnterGuard (
198+ guard : NavigationGuard ,
199+ cbs : Array < Function > ,
200+ match : RouteRecord ,
201+ key : string ,
202+ isValid : ( ) = > boolean
203+ ) : NavigationGuard {
204+ return function routeEnterGuard ( to , from , next ) {
205+ return guard ( to , from , cb => {
206+ next ( cb )
207+ if ( typeof cb === 'function' ) {
208+ cbs . push ( ( ) => {
209+ // #750
210+ // if a router-view is wrapped with an out-in transition,
211+ // the instance may not have been registered at this time.
212+ // we will need to poll for registration until current route
213+ // is no longer valid.
214+ poll ( cb , match . instances , key , isValid )
190215 } )
191216 }
192- }
193- } )
217+ } )
218+ }
194219}
195220
196- function poll ( cb , instances , key , isValid ) {
221+ function poll (
222+ cb : any , // somehow flow cannot infer this is a function
223+ instances : Object ,
224+ key : string ,
225+ isValid : ( ) = > boolean
226+ ) {
197227 if ( instances [ key ] ) {
198228 cb ( instances [ key ] )
199229 } else if ( isValid ( ) ) {
@@ -235,11 +265,15 @@ function flatMapComponents (
235265 matched : Array < RouteRecord > ,
236266 fn : Function
237267) : Array < ?Function > {
238- return Array . prototype . concat . apply ( [ ] , matched . map ( m => {
268+ return flatten ( matched . map ( m => {
239269 return Object . keys ( m . components ) . map ( key => fn (
240270 m . components [ key ] ,
241271 m . instances [ key ] ,
242272 m , key
243273 ) )
244274 } ) )
245275}
276+
277+ function flatten ( arr ) {
278+ return Array . prototype . concat . apply ( [ ] , arr )
279+ }
0 commit comments