@@ -28,6 +28,9 @@ class History {
28
28
29
29
this . parseQueryString = options . parseQueryString || parseQueryString ;
30
30
this . changeListeners = [ ] ;
31
+
32
+ this . location = null ;
33
+ this . _pendingLocation = null ;
31
34
}
32
35
33
36
_notifyChange ( ) {
@@ -45,6 +48,10 @@ class History {
45
48
} ) ;
46
49
}
47
50
51
+ onBeforeChange ( listener ) {
52
+ this . beforeChangeListener = listener ;
53
+ }
54
+
48
55
setup ( path , entry = { } ) {
49
56
if ( this . location )
50
57
return ;
@@ -56,15 +63,30 @@ class History {
56
63
if ( typeof this . readState === 'function' )
57
64
state = this . readState ( entry . key ) ;
58
65
59
- this . _update ( path , state , entry , NavigationTypes . POP , false ) ;
66
+ var location = this . _createLocation ( path , state , entry , NavigationTypes . POP ) ;
67
+ this . _update ( path , location , false ) ;
60
68
}
61
69
62
- handlePop ( path , entry = { } ) {
70
+ handlePop ( path , entry = { } , applyEntry = null ) {
63
71
var state = null ;
64
72
if ( entry . key && typeof this . readState === 'function' )
65
73
state = this . readState ( entry . key ) ;
66
74
67
- this . _update ( path , state , entry , NavigationTypes . POP ) ;
75
+ var location = this . _createLocation ( path , state , entry , NavigationTypes . POP ) ;
76
+
77
+ if ( ! this . beforeChangeListener ) {
78
+ applyEntry && applyEntry ( ) ;
79
+ this . _update ( path , location ) ;
80
+ } else {
81
+ this . _pendingLocation = location ;
82
+ this . beforeChangeListener . call ( this , location , ( ) => {
83
+ if ( this . _pendingLocation === location ) {
84
+ this . _pendingLocation = null ;
85
+ applyEntry && applyEntry ( ) ;
86
+ this . _update ( path , location ) ;
87
+ }
88
+ } ) ;
89
+ }
68
90
}
69
91
70
92
createRandomKey ( ) {
@@ -88,9 +110,27 @@ class History {
88
110
}
89
111
90
112
pushState ( state , path ) {
91
- var key = this . _saveNewState ( state ) ;
113
+ if ( ! this . beforeChangeListener ) {
114
+ this . _doPushState ( state , path ) ;
115
+ } else {
116
+ var pendingLocation = this . _createLocation ( path , state , null , NavigationTypes . PUSH ) ;
117
+ this . _pendingLocation = pendingLocation ;
118
+
119
+ this . beforeChangeListener . call ( this , pendingLocation , ( ) => {
120
+ if ( this . _pendingLocation === pendingLocation ) {
121
+ this . _pendingLocation = null ;
122
+ this . _doPushState ( state , path ) ;
123
+ return true ;
124
+ }
125
+ return false ;
126
+ } ) ;
127
+ }
128
+ }
92
129
130
+ _doPushState ( state , path ) {
131
+ var key = this . _saveNewState ( state ) ;
93
132
var entry = null ;
133
+
94
134
if ( this . path === path ) {
95
135
entry = this . replace ( path , key ) || { } ;
96
136
} else {
@@ -103,12 +143,30 @@ class History {
103
143
this . constructor . name
104
144
) ;
105
145
106
- this . _update ( path , state , entry , NavigationTypes . PUSH ) ;
146
+ var location = this . _createLocation ( path , state , entry , NavigationTypes . PUSH ) ;
147
+ this . _update ( path , location ) ;
107
148
}
108
149
109
150
replaceState ( state , path ) {
110
- var key = this . _saveNewState ( state ) ;
151
+ if ( ! this . beforeChangeListener ) {
152
+ this . _doReplaceState ( state , path ) ;
153
+ } else {
154
+ var pendingLocation = this . _createLocation ( path , state , null , NavigationTypes . REPLACE ) ;
155
+ this . _pendingLocation = pendingLocation ;
156
+
157
+ this . beforeChangeListener . call ( this , pendingLocation , ( ) => {
158
+ if ( this . _pendingLocation === pendingLocation ) {
159
+ this . _pendingLocation = null ;
160
+ this . _doReplaceState ( state , path ) ;
161
+ return true ;
162
+ }
163
+ return false ;
164
+ } ) ;
165
+ }
166
+ }
111
167
168
+ _doReplaceState ( state , path ) {
169
+ var key = this . _saveNewState ( state ) ;
112
170
var entry = this . replace ( path , key ) || { } ;
113
171
114
172
warning (
@@ -117,7 +175,8 @@ class History {
117
175
this . constructor . name
118
176
) ;
119
177
120
- this . _update ( path , state , entry , NavigationTypes . REPLACE ) ;
178
+ var location = this . _createLocation ( path , state , entry , NavigationTypes . REPLACE ) ;
179
+ this . _update ( path , location ) ;
121
180
}
122
181
123
182
back ( ) {
@@ -128,9 +187,10 @@ class History {
128
187
this . go ( 1 ) ;
129
188
}
130
189
131
- _update ( path , state , entry , navigationType , notify = true ) {
190
+ _update ( path , location , notify = true ) {
132
191
this . path = path ;
133
- this . location = this . _createLocation ( path , state , entry , navigationType ) ;
192
+ this . location = location ;
193
+ this . _pendingLocation = null ;
134
194
135
195
if ( notify )
136
196
this . _notifyChange ( ) ;
0 commit comments