vue-rails 2.0.1 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +3 -9
- data/Gemfile +1 -3
- data/{LICENSE → LICENSE.md} +1 -1
- data/Rakefile +0 -1
- data/Readme.md +56 -0
- data/lib/vue-rails.rb +2 -5
- data/lib/vue-rails/engine.rb +6 -0
- data/lib/vue-rails/version.rb +1 -1
- data/vendor/assets/javascripts/vue-resource.js +1534 -0
- data/vendor/assets/javascripts/vue-router.js +1196 -749
- data/vendor/assets/javascripts/vue.js +6031 -4258
- data/vendor/assets/javascripts/vuex.js +811 -0
- data/vue-rails.gemspec +5 -6
- metadata +17 -13
- data/README.md +0 -21
@@ -1,14 +1,28 @@
|
|
1
1
|
/**
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
* vue-router v2.2.1
|
3
|
+
* (c) 2017 Evan You
|
4
|
+
* @license MIT
|
5
|
+
*/
|
6
6
|
(function (global, factory) {
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
8
|
+
typeof define === 'function' && define.amd ? define(factory) :
|
9
|
+
(global.VueRouter = factory());
|
10
10
|
}(this, (function () { 'use strict';
|
11
11
|
|
12
|
+
/* */
|
13
|
+
|
14
|
+
function assert (condition, message) {
|
15
|
+
if (!condition) {
|
16
|
+
throw new Error(("[vue-router] " + message))
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
function warn (condition, message) {
|
21
|
+
if (!condition) {
|
22
|
+
typeof console !== 'undefined' && console.warn(("[vue-router] " + message));
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
12
26
|
var View = {
|
13
27
|
name: 'router-view',
|
14
28
|
functional: true,
|
@@ -24,133 +38,91 @@ var View = {
|
|
24
38
|
var parent = ref.parent;
|
25
39
|
var data = ref.data;
|
26
40
|
|
27
|
-
data.routerView = true
|
41
|
+
data.routerView = true;
|
28
42
|
|
29
|
-
var
|
30
|
-
var
|
31
|
-
var
|
32
|
-
var inactive = false
|
43
|
+
var name = props.name;
|
44
|
+
var route = parent.$route;
|
45
|
+
var cache = parent._routerViewCache || (parent._routerViewCache = {});
|
33
46
|
|
47
|
+
// determine current view depth, also check to see if the tree
|
48
|
+
// has been toggled inactive but kept-alive.
|
49
|
+
var depth = 0;
|
50
|
+
var inactive = false;
|
34
51
|
while (parent) {
|
35
52
|
if (parent.$vnode && parent.$vnode.data.routerView) {
|
36
|
-
depth
|
53
|
+
depth++;
|
37
54
|
}
|
38
55
|
if (parent._inactive) {
|
39
|
-
inactive = true
|
56
|
+
inactive = true;
|
40
57
|
}
|
41
|
-
parent = parent.$parent
|
58
|
+
parent = parent.$parent;
|
59
|
+
}
|
60
|
+
data.routerViewDepth = depth;
|
61
|
+
|
62
|
+
// render previous view if the tree is inactive and kept-alive
|
63
|
+
if (inactive) {
|
64
|
+
return h(cache[name], data, children)
|
42
65
|
}
|
43
66
|
|
44
|
-
|
45
|
-
|
67
|
+
var matched = route.matched[depth];
|
68
|
+
// render empty node if no matched route
|
46
69
|
if (!matched) {
|
70
|
+
cache[name] = null;
|
47
71
|
return h()
|
48
72
|
}
|
49
73
|
|
50
|
-
var component =
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
74
|
+
var component = cache[name] = matched.components[name];
|
75
|
+
|
76
|
+
// inject instance registration hooks
|
77
|
+
var hooks = data.hook || (data.hook = {});
|
78
|
+
hooks.init = function (vnode) {
|
79
|
+
matched.instances[name] = vnode.child;
|
80
|
+
};
|
81
|
+
hooks.prepatch = function (oldVnode, vnode) {
|
82
|
+
matched.instances[name] = vnode.child;
|
83
|
+
};
|
84
|
+
hooks.destroy = function (vnode) {
|
85
|
+
if (matched.instances[name] === vnode.child) {
|
86
|
+
matched.instances[name] = undefined;
|
57
87
|
}
|
58
|
-
}
|
59
|
-
|
60
|
-
return h(component, data, children)
|
61
|
-
}
|
62
|
-
}
|
63
|
-
|
64
|
-
/* */
|
65
|
-
|
66
|
-
function resolvePath (
|
67
|
-
relative,
|
68
|
-
base,
|
69
|
-
append
|
70
|
-
) {
|
71
|
-
if (relative.charAt(0) === '/') {
|
72
|
-
return relative
|
73
|
-
}
|
74
|
-
|
75
|
-
if (relative.charAt(0) === '?' || relative.charAt(0) === '#') {
|
76
|
-
return base + relative
|
77
|
-
}
|
78
|
-
|
79
|
-
var stack = base.split('/')
|
80
|
-
|
81
|
-
// remove trailing segment if:
|
82
|
-
// - not appending
|
83
|
-
// - appending to trailing slash (last segment is empty)
|
84
|
-
if (!append || !stack[stack.length - 1]) {
|
85
|
-
stack.pop()
|
86
|
-
}
|
87
|
-
|
88
|
-
// resolve relative path
|
89
|
-
var segments = relative.replace(/^\//, '').split('/')
|
90
|
-
for (var i = 0; i < segments.length; i++) {
|
91
|
-
var segment = segments[i]
|
92
|
-
if (segment === '.') {
|
93
|
-
continue
|
94
|
-
} else if (segment === '..') {
|
95
|
-
stack.pop()
|
96
|
-
} else {
|
97
|
-
stack.push(segment)
|
98
|
-
}
|
99
|
-
}
|
100
|
-
|
101
|
-
// ensure leading slash
|
102
|
-
if (stack[0] !== '') {
|
103
|
-
stack.unshift('')
|
104
|
-
}
|
105
|
-
|
106
|
-
return stack.join('/')
|
107
|
-
}
|
88
|
+
};
|
108
89
|
|
109
|
-
|
110
|
-
|
111
|
-
var query = ''
|
112
|
-
|
113
|
-
var hashIndex = path.indexOf('#')
|
114
|
-
if (hashIndex >= 0) {
|
115
|
-
hash = path.slice(hashIndex)
|
116
|
-
path = path.slice(0, hashIndex)
|
117
|
-
}
|
90
|
+
// resolve props
|
91
|
+
data.props = resolveProps(route, matched.props && matched.props[name]);
|
118
92
|
|
119
|
-
|
120
|
-
if (queryIndex >= 0) {
|
121
|
-
query = path.slice(queryIndex + 1)
|
122
|
-
path = path.slice(0, queryIndex)
|
93
|
+
return h(component, data, children)
|
123
94
|
}
|
95
|
+
};
|
124
96
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
97
|
+
function resolveProps (route, config) {
|
98
|
+
switch (typeof config) {
|
99
|
+
case 'undefined':
|
100
|
+
return
|
101
|
+
case 'object':
|
102
|
+
return config
|
103
|
+
case 'function':
|
104
|
+
return config(route)
|
105
|
+
case 'boolean':
|
106
|
+
return config ? route.params : undefined
|
107
|
+
default:
|
108
|
+
warn(false, ("props in \"" + (route.path) + "\" is a " + (typeof config) + ", expecting an object, function or boolean."));
|
129
109
|
}
|
130
110
|
}
|
131
111
|
|
132
|
-
function cleanPath (path) {
|
133
|
-
return path.replace(/\/\//g, '/')
|
134
|
-
}
|
135
|
-
|
136
112
|
/* */
|
137
113
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
}
|
142
|
-
}
|
143
|
-
|
144
|
-
function warn (condition, message) {
|
145
|
-
if (!condition) {
|
146
|
-
typeof console !== 'undefined' && console.warn(("[vue-router] " + message))
|
147
|
-
}
|
148
|
-
}
|
114
|
+
var encodeReserveRE = /[!'()*]/g;
|
115
|
+
var encodeReserveReplacer = function (c) { return '%' + c.charCodeAt(0).toString(16); };
|
116
|
+
var commaRE = /%2C/g;
|
149
117
|
|
150
|
-
|
118
|
+
// fixed encodeURIComponent which is more comformant to RFC3986:
|
119
|
+
// - escapes [!'()*]
|
120
|
+
// - preserve commas
|
121
|
+
var encode = function (str) { return encodeURIComponent(str)
|
122
|
+
.replace(encodeReserveRE, encodeReserveReplacer)
|
123
|
+
.replace(commaRE, ','); };
|
151
124
|
|
152
|
-
var
|
153
|
-
var decode = decodeURIComponent
|
125
|
+
var decode = decodeURIComponent;
|
154
126
|
|
155
127
|
function resolveQuery (
|
156
128
|
query,
|
@@ -159,15 +131,15 @@ function resolveQuery (
|
|
159
131
|
if ( extraQuery === void 0 ) extraQuery = {};
|
160
132
|
|
161
133
|
if (query) {
|
162
|
-
var parsedQuery
|
134
|
+
var parsedQuery;
|
163
135
|
try {
|
164
|
-
parsedQuery = parseQuery(query)
|
136
|
+
parsedQuery = parseQuery(query);
|
165
137
|
} catch (e) {
|
166
|
-
warn(false, e.message)
|
167
|
-
parsedQuery = {}
|
138
|
+
"development" !== 'production' && warn(false, e.message);
|
139
|
+
parsedQuery = {};
|
168
140
|
}
|
169
141
|
for (var key in extraQuery) {
|
170
|
-
parsedQuery[key] = extraQuery[key]
|
142
|
+
parsedQuery[key] = extraQuery[key];
|
171
143
|
}
|
172
144
|
return parsedQuery
|
173
145
|
} else {
|
@@ -176,36 +148,36 @@ function resolveQuery (
|
|
176
148
|
}
|
177
149
|
|
178
150
|
function parseQuery (query) {
|
179
|
-
var res =
|
151
|
+
var res = {};
|
180
152
|
|
181
|
-
query = query.trim().replace(/^(\?|#|&)/, '')
|
153
|
+
query = query.trim().replace(/^(\?|#|&)/, '');
|
182
154
|
|
183
155
|
if (!query) {
|
184
156
|
return res
|
185
157
|
}
|
186
158
|
|
187
159
|
query.split('&').forEach(function (param) {
|
188
|
-
var parts = param.replace(/\+/g, ' ').split('=')
|
189
|
-
var key = decode(parts.shift())
|
160
|
+
var parts = param.replace(/\+/g, ' ').split('=');
|
161
|
+
var key = decode(parts.shift());
|
190
162
|
var val = parts.length > 0
|
191
163
|
? decode(parts.join('='))
|
192
|
-
: null
|
164
|
+
: null;
|
193
165
|
|
194
166
|
if (res[key] === undefined) {
|
195
|
-
res[key] = val
|
167
|
+
res[key] = val;
|
196
168
|
} else if (Array.isArray(res[key])) {
|
197
|
-
res[key].push(val)
|
169
|
+
res[key].push(val);
|
198
170
|
} else {
|
199
|
-
res[key] = [res[key], val]
|
171
|
+
res[key] = [res[key], val];
|
200
172
|
}
|
201
|
-
})
|
173
|
+
});
|
202
174
|
|
203
175
|
return res
|
204
176
|
}
|
205
177
|
|
206
178
|
function stringifyQuery (obj) {
|
207
|
-
var res = obj ? Object.keys(obj).
|
208
|
-
var val = obj[key]
|
179
|
+
var res = obj ? Object.keys(obj).map(function (key) {
|
180
|
+
var val = obj[key];
|
209
181
|
|
210
182
|
if (val === undefined) {
|
211
183
|
return ''
|
@@ -216,27 +188,29 @@ function stringifyQuery (obj) {
|
|
216
188
|
}
|
217
189
|
|
218
190
|
if (Array.isArray(val)) {
|
219
|
-
var result = []
|
191
|
+
var result = [];
|
220
192
|
val.slice().forEach(function (val2) {
|
221
193
|
if (val2 === undefined) {
|
222
194
|
return
|
223
195
|
}
|
224
196
|
if (val2 === null) {
|
225
|
-
result.push(encode(key))
|
197
|
+
result.push(encode(key));
|
226
198
|
} else {
|
227
|
-
result.push(encode(key) + '=' + encode(val2))
|
199
|
+
result.push(encode(key) + '=' + encode(val2));
|
228
200
|
}
|
229
|
-
})
|
201
|
+
});
|
230
202
|
return result.join('&')
|
231
203
|
}
|
232
204
|
|
233
205
|
return encode(key) + '=' + encode(val)
|
234
|
-
}).filter(function (x) { return x.length > 0; }).join('&') : null
|
206
|
+
}).filter(function (x) { return x.length > 0; }).join('&') : null;
|
235
207
|
return res ? ("?" + res) : ''
|
236
208
|
}
|
237
209
|
|
238
210
|
/* */
|
239
211
|
|
212
|
+
var trailingSlashRE = /\/?$/;
|
213
|
+
|
240
214
|
function createRoute (
|
241
215
|
record,
|
242
216
|
location,
|
@@ -251,9 +225,9 @@ function createRoute (
|
|
251
225
|
params: location.params || {},
|
252
226
|
fullPath: getFullPath(location),
|
253
227
|
matched: record ? formatMatch(record) : []
|
254
|
-
}
|
228
|
+
};
|
255
229
|
if (redirectedFrom) {
|
256
|
-
route.redirectedFrom = getFullPath(redirectedFrom)
|
230
|
+
route.redirectedFrom = getFullPath(redirectedFrom);
|
257
231
|
}
|
258
232
|
return Object.freeze(route)
|
259
233
|
}
|
@@ -261,13 +235,13 @@ function createRoute (
|
|
261
235
|
// the starting route that represents the initial state
|
262
236
|
var START = createRoute(null, {
|
263
237
|
path: '/'
|
264
|
-
})
|
238
|
+
});
|
265
239
|
|
266
240
|
function formatMatch (record) {
|
267
|
-
var res = []
|
241
|
+
var res = [];
|
268
242
|
while (record) {
|
269
|
-
res.unshift(record)
|
270
|
-
record = record.parent
|
243
|
+
res.unshift(record);
|
244
|
+
record = record.parent;
|
271
245
|
}
|
272
246
|
return res
|
273
247
|
}
|
@@ -280,7 +254,6 @@ function getFullPath (ref) {
|
|
280
254
|
return (path || '/') + stringifyQuery(query) + hash
|
281
255
|
}
|
282
256
|
|
283
|
-
var trailingSlashRE = /\/$/
|
284
257
|
function isSameRoute (a, b) {
|
285
258
|
if (b === START) {
|
286
259
|
return a === b
|
@@ -308,8 +281,8 @@ function isObjectEqual (a, b) {
|
|
308
281
|
if ( a === void 0 ) a = {};
|
309
282
|
if ( b === void 0 ) b = {};
|
310
283
|
|
311
|
-
var aKeys = Object.keys(a)
|
312
|
-
var bKeys = Object.keys(b)
|
284
|
+
var aKeys = Object.keys(a);
|
285
|
+
var bKeys = Object.keys(b);
|
313
286
|
if (aKeys.length !== bKeys.length) {
|
314
287
|
return false
|
315
288
|
}
|
@@ -318,7 +291,9 @@ function isObjectEqual (a, b) {
|
|
318
291
|
|
319
292
|
function isIncludedRoute (current, target) {
|
320
293
|
return (
|
321
|
-
current.path.indexOf(
|
294
|
+
current.path.replace(trailingSlashRE, '/').indexOf(
|
295
|
+
target.path.replace(trailingSlashRE, '/')
|
296
|
+
) === 0 &&
|
322
297
|
(!target.hash || current.hash === target.hash) &&
|
323
298
|
queryIncludes(current.query, target.query)
|
324
299
|
)
|
@@ -335,39 +310,9 @@ function queryIncludes (current, target) {
|
|
335
310
|
|
336
311
|
/* */
|
337
312
|
|
338
|
-
function normalizeLocation (
|
339
|
-
raw,
|
340
|
-
current,
|
341
|
-
append
|
342
|
-
) {
|
343
|
-
var next = typeof raw === 'string' ? { path: raw } : raw
|
344
|
-
if (next.name || next._normalized) {
|
345
|
-
return next
|
346
|
-
}
|
347
|
-
|
348
|
-
var parsedPath = parsePath(next.path || '')
|
349
|
-
var basePath = (current && current.path) || '/'
|
350
|
-
var path = parsedPath.path
|
351
|
-
? resolvePath(parsedPath.path, basePath, append)
|
352
|
-
: (current && current.path) || '/'
|
353
|
-
var query = resolveQuery(parsedPath.query, next.query)
|
354
|
-
var hash = next.hash || parsedPath.hash
|
355
|
-
if (hash && hash.charAt(0) !== '#') {
|
356
|
-
hash = "#" + hash
|
357
|
-
}
|
358
|
-
|
359
|
-
return {
|
360
|
-
_normalized: true,
|
361
|
-
path: path,
|
362
|
-
query: query,
|
363
|
-
hash: hash
|
364
|
-
}
|
365
|
-
}
|
366
|
-
|
367
|
-
/* */
|
368
|
-
|
369
313
|
// work around weird flow bug
|
370
|
-
var toTypes = [String, Object]
|
314
|
+
var toTypes = [String, Object];
|
315
|
+
var eventTypes = [String, Array];
|
371
316
|
|
372
317
|
var Link = {
|
373
318
|
name: 'router-link',
|
@@ -383,63 +328,97 @@ var Link = {
|
|
383
328
|
exact: Boolean,
|
384
329
|
append: Boolean,
|
385
330
|
replace: Boolean,
|
386
|
-
activeClass: String
|
331
|
+
activeClass: String,
|
332
|
+
event: {
|
333
|
+
type: eventTypes,
|
334
|
+
default: 'click'
|
335
|
+
}
|
387
336
|
},
|
388
337
|
render: function render (h) {
|
389
338
|
var this$1 = this;
|
390
339
|
|
391
|
-
var router = this.$router
|
392
|
-
var current = this.$route
|
393
|
-
var
|
394
|
-
var
|
395
|
-
var
|
396
|
-
var
|
397
|
-
var
|
398
|
-
var
|
399
|
-
var
|
400
|
-
var compareTarget = to.path ? createRoute(null, to) : resolved
|
340
|
+
var router = this.$router;
|
341
|
+
var current = this.$route;
|
342
|
+
var ref = router.resolve(this.to, current, this.append);
|
343
|
+
var location = ref.location;
|
344
|
+
var route = ref.route;
|
345
|
+
var href = ref.href;
|
346
|
+
var classes = {};
|
347
|
+
var activeClass = this.activeClass || router.options.linkActiveClass || 'router-link-active';
|
348
|
+
var compareTarget = location.path ? createRoute(null, location) : route;
|
401
349
|
classes[activeClass] = this.exact
|
402
350
|
? isSameRoute(current, compareTarget)
|
403
|
-
: isIncludedRoute(current, compareTarget)
|
351
|
+
: isIncludedRoute(current, compareTarget);
|
404
352
|
|
405
|
-
var
|
406
|
-
|
407
|
-
e.preventDefault()
|
353
|
+
var handler = function (e) {
|
354
|
+
if (guardEvent(e)) {
|
408
355
|
if (this$1.replace) {
|
409
|
-
router.replace(
|
356
|
+
router.replace(location);
|
410
357
|
} else {
|
411
|
-
router.push(
|
358
|
+
router.push(location);
|
412
359
|
}
|
413
360
|
}
|
361
|
+
};
|
362
|
+
|
363
|
+
var on = { click: guardEvent };
|
364
|
+
if (Array.isArray(this.event)) {
|
365
|
+
this.event.forEach(function (e) { on[e] = handler; });
|
366
|
+
} else {
|
367
|
+
on[this.event] = handler;
|
414
368
|
}
|
415
369
|
|
416
370
|
var data = {
|
417
371
|
class: classes
|
418
|
-
}
|
372
|
+
};
|
419
373
|
|
420
374
|
if (this.tag === 'a') {
|
421
|
-
data.on = on
|
422
|
-
data.attrs = { href: href }
|
375
|
+
data.on = on;
|
376
|
+
data.attrs = { href: href };
|
423
377
|
} else {
|
424
378
|
// find the first <a> child and apply listener and href
|
425
|
-
var a = findAnchor(this.$slots.default)
|
379
|
+
var a = findAnchor(this.$slots.default);
|
426
380
|
if (a) {
|
427
|
-
|
428
|
-
|
429
|
-
var
|
430
|
-
|
381
|
+
// in case the <a> is a static node
|
382
|
+
a.isStatic = false;
|
383
|
+
var extend = _Vue.util.extend;
|
384
|
+
var aData = a.data = extend({}, a.data);
|
385
|
+
aData.on = on;
|
386
|
+
var aAttrs = a.data.attrs = extend({}, a.data.attrs);
|
387
|
+
aAttrs.href = href;
|
388
|
+
} else {
|
389
|
+
// doesn't have <a> child, apply listener to self
|
390
|
+
data.on = on;
|
431
391
|
}
|
432
392
|
}
|
433
393
|
|
434
394
|
return h(this.tag, data, this.$slots.default)
|
435
395
|
}
|
396
|
+
};
|
397
|
+
|
398
|
+
function guardEvent (e) {
|
399
|
+
// don't redirect with control keys
|
400
|
+
if (e.metaKey || e.ctrlKey || e.shiftKey) { return }
|
401
|
+
// don't redirect when preventDefault called
|
402
|
+
if (e.defaultPrevented) { return }
|
403
|
+
// don't redirect on right click
|
404
|
+
if (e.button !== undefined && e.button !== 0) { return }
|
405
|
+
// don't redirect if `target="_blank"`
|
406
|
+
if (e.target && e.target.getAttribute) {
|
407
|
+
var target = e.target.getAttribute('target');
|
408
|
+
if (/\b_blank\b/i.test(target)) { return }
|
409
|
+
}
|
410
|
+
// this may be a Weex event which doesn't have this method
|
411
|
+
if (e.preventDefault) {
|
412
|
+
e.preventDefault();
|
413
|
+
}
|
414
|
+
return true
|
436
415
|
}
|
437
416
|
|
438
417
|
function findAnchor (children) {
|
439
418
|
if (children) {
|
440
|
-
var child
|
419
|
+
var child;
|
441
420
|
for (var i = 0; i < children.length; i++) {
|
442
|
-
child = children[i]
|
421
|
+
child = children[i];
|
443
422
|
if (child.tag === 'a') {
|
444
423
|
return child
|
445
424
|
}
|
@@ -450,46 +429,251 @@ function findAnchor (children) {
|
|
450
429
|
}
|
451
430
|
}
|
452
431
|
|
432
|
+
var _Vue;
|
433
|
+
|
453
434
|
function install (Vue) {
|
454
435
|
if (install.installed) { return }
|
455
|
-
install.installed = true
|
436
|
+
install.installed = true;
|
437
|
+
|
438
|
+
_Vue = Vue;
|
456
439
|
|
457
440
|
Object.defineProperty(Vue.prototype, '$router', {
|
458
441
|
get: function get () { return this.$root._router }
|
459
|
-
})
|
442
|
+
});
|
460
443
|
|
461
444
|
Object.defineProperty(Vue.prototype, '$route', {
|
462
|
-
get: function get
|
463
|
-
})
|
445
|
+
get: function get () { return this.$root._route }
|
446
|
+
});
|
464
447
|
|
465
448
|
Vue.mixin({
|
466
449
|
beforeCreate: function beforeCreate () {
|
467
450
|
if (this.$options.router) {
|
468
|
-
this._router = this.$options.router
|
469
|
-
this._router.init(this)
|
470
|
-
Vue.util.defineReactive(this, '_route', this._router.history.current)
|
451
|
+
this._router = this.$options.router;
|
452
|
+
this._router.init(this);
|
453
|
+
Vue.util.defineReactive(this, '_route', this._router.history.current);
|
471
454
|
}
|
472
455
|
}
|
473
|
-
})
|
456
|
+
});
|
457
|
+
|
458
|
+
Vue.component('router-view', View);
|
459
|
+
Vue.component('router-link', Link);
|
460
|
+
|
461
|
+
var strats = Vue.config.optionMergeStrategies;
|
462
|
+
// use the same hook merging strategy for route hooks
|
463
|
+
strats.beforeRouteEnter = strats.beforeRouteLeave = strats.created;
|
464
|
+
}
|
465
|
+
|
466
|
+
/* */
|
467
|
+
|
468
|
+
var inBrowser = typeof window !== 'undefined';
|
469
|
+
|
470
|
+
/* */
|
471
|
+
|
472
|
+
function resolvePath (
|
473
|
+
relative,
|
474
|
+
base,
|
475
|
+
append
|
476
|
+
) {
|
477
|
+
if (relative.charAt(0) === '/') {
|
478
|
+
return relative
|
479
|
+
}
|
480
|
+
|
481
|
+
if (relative.charAt(0) === '?' || relative.charAt(0) === '#') {
|
482
|
+
return base + relative
|
483
|
+
}
|
484
|
+
|
485
|
+
var stack = base.split('/');
|
486
|
+
|
487
|
+
// remove trailing segment if:
|
488
|
+
// - not appending
|
489
|
+
// - appending to trailing slash (last segment is empty)
|
490
|
+
if (!append || !stack[stack.length - 1]) {
|
491
|
+
stack.pop();
|
492
|
+
}
|
493
|
+
|
494
|
+
// resolve relative path
|
495
|
+
var segments = relative.replace(/^\//, '').split('/');
|
496
|
+
for (var i = 0; i < segments.length; i++) {
|
497
|
+
var segment = segments[i];
|
498
|
+
if (segment === '.') {
|
499
|
+
continue
|
500
|
+
} else if (segment === '..') {
|
501
|
+
stack.pop();
|
502
|
+
} else {
|
503
|
+
stack.push(segment);
|
504
|
+
}
|
505
|
+
}
|
506
|
+
|
507
|
+
// ensure leading slash
|
508
|
+
if (stack[0] !== '') {
|
509
|
+
stack.unshift('');
|
510
|
+
}
|
511
|
+
|
512
|
+
return stack.join('/')
|
513
|
+
}
|
514
|
+
|
515
|
+
function parsePath (path) {
|
516
|
+
var hash = '';
|
517
|
+
var query = '';
|
518
|
+
|
519
|
+
var hashIndex = path.indexOf('#');
|
520
|
+
if (hashIndex >= 0) {
|
521
|
+
hash = path.slice(hashIndex);
|
522
|
+
path = path.slice(0, hashIndex);
|
523
|
+
}
|
524
|
+
|
525
|
+
var queryIndex = path.indexOf('?');
|
526
|
+
if (queryIndex >= 0) {
|
527
|
+
query = path.slice(queryIndex + 1);
|
528
|
+
path = path.slice(0, queryIndex);
|
529
|
+
}
|
530
|
+
|
531
|
+
return {
|
532
|
+
path: path,
|
533
|
+
query: query,
|
534
|
+
hash: hash
|
535
|
+
}
|
536
|
+
}
|
537
|
+
|
538
|
+
function cleanPath (path) {
|
539
|
+
return path.replace(/\/\//g, '/')
|
540
|
+
}
|
474
541
|
|
475
|
-
|
476
|
-
|
542
|
+
/* */
|
543
|
+
|
544
|
+
function createRouteMap (
|
545
|
+
routes,
|
546
|
+
oldPathMap,
|
547
|
+
oldNameMap
|
548
|
+
) {
|
549
|
+
var pathMap = oldPathMap || Object.create(null);
|
550
|
+
var nameMap = oldNameMap || Object.create(null);
|
551
|
+
|
552
|
+
routes.forEach(function (route) {
|
553
|
+
addRouteRecord(pathMap, nameMap, route);
|
554
|
+
});
|
555
|
+
|
556
|
+
return {
|
557
|
+
pathMap: pathMap,
|
558
|
+
nameMap: nameMap
|
559
|
+
}
|
560
|
+
}
|
561
|
+
|
562
|
+
function addRouteRecord (
|
563
|
+
pathMap,
|
564
|
+
nameMap,
|
565
|
+
route,
|
566
|
+
parent,
|
567
|
+
matchAs
|
568
|
+
) {
|
569
|
+
var path = route.path;
|
570
|
+
var name = route.name;
|
571
|
+
{
|
572
|
+
assert(path != null, "\"path\" is required in a route configuration.");
|
573
|
+
assert(
|
574
|
+
typeof route.component !== 'string',
|
575
|
+
"route config \"component\" for path: " + (String(path || name)) + " cannot be a " +
|
576
|
+
"string id. Use an actual component instead."
|
577
|
+
);
|
578
|
+
}
|
579
|
+
|
580
|
+
var record = {
|
581
|
+
path: normalizePath(path, parent),
|
582
|
+
components: route.components || { default: route.component },
|
583
|
+
instances: {},
|
584
|
+
name: name,
|
585
|
+
parent: parent,
|
586
|
+
matchAs: matchAs,
|
587
|
+
redirect: route.redirect,
|
588
|
+
beforeEnter: route.beforeEnter,
|
589
|
+
meta: route.meta || {},
|
590
|
+
props: route.props == null
|
591
|
+
? {}
|
592
|
+
: route.components
|
593
|
+
? route.props
|
594
|
+
: { default: route.props }
|
595
|
+
};
|
596
|
+
|
597
|
+
if (route.children) {
|
598
|
+
// Warn if route is named and has a default child route.
|
599
|
+
// If users navigate to this route by name, the default child will
|
600
|
+
// not be rendered (GH Issue #629)
|
601
|
+
{
|
602
|
+
if (route.name && route.children.some(function (child) { return /^\/?$/.test(child.path); })) {
|
603
|
+
warn(
|
604
|
+
false,
|
605
|
+
"Named Route '" + (route.name) + "' has a default child route. " +
|
606
|
+
"When navigating to this named route (:to=\"{name: '" + (route.name) + "'\"), " +
|
607
|
+
"the default child route will not be rendered. Remove the name from " +
|
608
|
+
"this route and use the name of the default child route for named " +
|
609
|
+
"links instead."
|
610
|
+
);
|
611
|
+
}
|
612
|
+
}
|
613
|
+
route.children.forEach(function (child) {
|
614
|
+
var childMatchAs = matchAs
|
615
|
+
? cleanPath((matchAs + "/" + (child.path)))
|
616
|
+
: undefined;
|
617
|
+
addRouteRecord(pathMap, nameMap, child, record, childMatchAs);
|
618
|
+
});
|
619
|
+
}
|
620
|
+
|
621
|
+
if (route.alias !== undefined) {
|
622
|
+
if (Array.isArray(route.alias)) {
|
623
|
+
route.alias.forEach(function (alias) {
|
624
|
+
var aliasRoute = {
|
625
|
+
path: alias,
|
626
|
+
children: route.children
|
627
|
+
};
|
628
|
+
addRouteRecord(pathMap, nameMap, aliasRoute, parent, record.path);
|
629
|
+
});
|
630
|
+
} else {
|
631
|
+
var aliasRoute = {
|
632
|
+
path: route.alias,
|
633
|
+
children: route.children
|
634
|
+
};
|
635
|
+
addRouteRecord(pathMap, nameMap, aliasRoute, parent, record.path);
|
636
|
+
}
|
637
|
+
}
|
638
|
+
|
639
|
+
if (!pathMap[record.path]) {
|
640
|
+
pathMap[record.path] = record;
|
641
|
+
}
|
642
|
+
|
643
|
+
if (name) {
|
644
|
+
if (!nameMap[name]) {
|
645
|
+
nameMap[name] = record;
|
646
|
+
} else if ("development" !== 'production' && !matchAs) {
|
647
|
+
warn(
|
648
|
+
false,
|
649
|
+
"Duplicate named routes definition: " +
|
650
|
+
"{ name: \"" + name + "\", path: \"" + (record.path) + "\" }"
|
651
|
+
);
|
652
|
+
}
|
653
|
+
}
|
654
|
+
}
|
655
|
+
|
656
|
+
function normalizePath (path, parent) {
|
657
|
+
path = path.replace(/\/$/, '');
|
658
|
+
if (path[0] === '/') { return path }
|
659
|
+
if (parent == null) { return path }
|
660
|
+
return cleanPath(((parent.path) + "/" + path))
|
477
661
|
}
|
478
662
|
|
479
|
-
var
|
663
|
+
var index$1 = Array.isArray || function (arr) {
|
480
664
|
return Object.prototype.toString.call(arr) == '[object Array]';
|
481
665
|
};
|
482
666
|
|
483
|
-
var isarray =
|
667
|
+
var isarray = index$1;
|
484
668
|
|
485
669
|
/**
|
486
670
|
* Expose `pathToRegexp`.
|
487
671
|
*/
|
488
|
-
var index = pathToRegexp
|
489
|
-
var parse_1 = parse
|
490
|
-
var compile_1 = compile
|
491
|
-
var tokensToFunction_1 = tokensToFunction
|
492
|
-
var tokensToRegExp_1 = tokensToRegExp
|
672
|
+
var index = pathToRegexp;
|
673
|
+
var parse_1 = parse;
|
674
|
+
var compile_1 = compile;
|
675
|
+
var tokensToFunction_1 = tokensToFunction;
|
676
|
+
var tokensToRegExp_1 = tokensToRegExp;
|
493
677
|
|
494
678
|
/**
|
495
679
|
* The main path matching regexp utility.
|
@@ -507,53 +691,55 @@ var PATH_REGEXP = new RegExp([
|
|
507
691
|
// "/route(\\d+)" => [undefined, undefined, undefined, "\d+", undefined, undefined]
|
508
692
|
// "/*" => ["/", undefined, undefined, undefined, undefined, "*"]
|
509
693
|
'([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))'
|
510
|
-
].join('|'), 'g')
|
694
|
+
].join('|'), 'g');
|
511
695
|
|
512
696
|
/**
|
513
697
|
* Parse a string for the raw tokens.
|
514
698
|
*
|
515
|
-
* @param {string}
|
699
|
+
* @param {string} str
|
700
|
+
* @param {Object=} options
|
516
701
|
* @return {!Array}
|
517
702
|
*/
|
518
|
-
function parse (str) {
|
519
|
-
var tokens = []
|
520
|
-
var key = 0
|
521
|
-
var index = 0
|
522
|
-
var path = ''
|
523
|
-
var
|
703
|
+
function parse (str, options) {
|
704
|
+
var tokens = [];
|
705
|
+
var key = 0;
|
706
|
+
var index = 0;
|
707
|
+
var path = '';
|
708
|
+
var defaultDelimiter = options && options.delimiter || '/';
|
709
|
+
var res;
|
524
710
|
|
525
711
|
while ((res = PATH_REGEXP.exec(str)) != null) {
|
526
|
-
var m = res[0]
|
527
|
-
var escaped = res[1]
|
528
|
-
var offset = res.index
|
529
|
-
path += str.slice(index, offset)
|
530
|
-
index = offset + m.length
|
712
|
+
var m = res[0];
|
713
|
+
var escaped = res[1];
|
714
|
+
var offset = res.index;
|
715
|
+
path += str.slice(index, offset);
|
716
|
+
index = offset + m.length;
|
531
717
|
|
532
718
|
// Ignore already escaped sequences.
|
533
719
|
if (escaped) {
|
534
|
-
path += escaped[1]
|
720
|
+
path += escaped[1];
|
535
721
|
continue
|
536
722
|
}
|
537
723
|
|
538
|
-
var next = str[index]
|
539
|
-
var prefix = res[2]
|
540
|
-
var name = res[3]
|
541
|
-
var capture = res[4]
|
542
|
-
var group = res[5]
|
543
|
-
var modifier = res[6]
|
544
|
-
var asterisk = res[7]
|
724
|
+
var next = str[index];
|
725
|
+
var prefix = res[2];
|
726
|
+
var name = res[3];
|
727
|
+
var capture = res[4];
|
728
|
+
var group = res[5];
|
729
|
+
var modifier = res[6];
|
730
|
+
var asterisk = res[7];
|
545
731
|
|
546
732
|
// Push the current path onto the tokens.
|
547
733
|
if (path) {
|
548
|
-
tokens.push(path)
|
549
|
-
path = ''
|
734
|
+
tokens.push(path);
|
735
|
+
path = '';
|
550
736
|
}
|
551
737
|
|
552
|
-
var partial = prefix != null && next != null && next !== prefix
|
553
|
-
var repeat = modifier === '+' || modifier === '*'
|
554
|
-
var optional = modifier === '?' || modifier === '*'
|
555
|
-
var delimiter = res[2] ||
|
556
|
-
var pattern = capture || group
|
738
|
+
var partial = prefix != null && next != null && next !== prefix;
|
739
|
+
var repeat = modifier === '+' || modifier === '*';
|
740
|
+
var optional = modifier === '?' || modifier === '*';
|
741
|
+
var delimiter = res[2] || defaultDelimiter;
|
742
|
+
var pattern = capture || group;
|
557
743
|
|
558
744
|
tokens.push({
|
559
745
|
name: name || key++,
|
@@ -563,18 +749,18 @@ function parse (str) {
|
|
563
749
|
repeat: repeat,
|
564
750
|
partial: partial,
|
565
751
|
asterisk: !!asterisk,
|
566
|
-
pattern: escapeGroup(pattern)
|
567
|
-
})
|
752
|
+
pattern: pattern ? escapeGroup(pattern) : (asterisk ? '.*' : '[^' + escapeString(delimiter) + ']+?')
|
753
|
+
});
|
568
754
|
}
|
569
755
|
|
570
756
|
// Match any characters still remaining.
|
571
757
|
if (index < str.length) {
|
572
|
-
path += str.substr(index)
|
758
|
+
path += str.substr(index);
|
573
759
|
}
|
574
760
|
|
575
761
|
// If the path exists, push it onto the end.
|
576
762
|
if (path) {
|
577
|
-
tokens.push(path)
|
763
|
+
tokens.push(path);
|
578
764
|
}
|
579
765
|
|
580
766
|
return tokens
|
@@ -584,10 +770,11 @@ function parse (str) {
|
|
584
770
|
* Compile a string to a template function for the path.
|
585
771
|
*
|
586
772
|
* @param {string} str
|
773
|
+
* @param {Object=} options
|
587
774
|
* @return {!function(Object=, Object=)}
|
588
775
|
*/
|
589
|
-
function compile (str) {
|
590
|
-
return tokensToFunction(parse(str))
|
776
|
+
function compile (str, options) {
|
777
|
+
return tokensToFunction(parse(str, options))
|
591
778
|
}
|
592
779
|
|
593
780
|
/**
|
@@ -619,38 +806,38 @@ function encodeAsterisk (str) {
|
|
619
806
|
*/
|
620
807
|
function tokensToFunction (tokens) {
|
621
808
|
// Compile all the tokens into regexps.
|
622
|
-
var matches = new Array(tokens.length)
|
809
|
+
var matches = new Array(tokens.length);
|
623
810
|
|
624
811
|
// Compile all the patterns before compilation.
|
625
812
|
for (var i = 0; i < tokens.length; i++) {
|
626
813
|
if (typeof tokens[i] === 'object') {
|
627
|
-
matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$')
|
814
|
+
matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$');
|
628
815
|
}
|
629
816
|
}
|
630
817
|
|
631
818
|
return function (obj, opts) {
|
632
|
-
var path = ''
|
633
|
-
var data = obj || {}
|
634
|
-
var options = opts || {}
|
635
|
-
var encode = options.pretty ? encodeURIComponentPretty : encodeURIComponent
|
819
|
+
var path = '';
|
820
|
+
var data = obj || {};
|
821
|
+
var options = opts || {};
|
822
|
+
var encode = options.pretty ? encodeURIComponentPretty : encodeURIComponent;
|
636
823
|
|
637
824
|
for (var i = 0; i < tokens.length; i++) {
|
638
|
-
var token = tokens[i]
|
825
|
+
var token = tokens[i];
|
639
826
|
|
640
827
|
if (typeof token === 'string') {
|
641
|
-
path += token
|
828
|
+
path += token;
|
642
829
|
|
643
830
|
continue
|
644
831
|
}
|
645
832
|
|
646
|
-
var value = data[token.name]
|
647
|
-
var segment
|
833
|
+
var value = data[token.name];
|
834
|
+
var segment;
|
648
835
|
|
649
836
|
if (value == null) {
|
650
837
|
if (token.optional) {
|
651
838
|
// Prepend partial segment prefixes.
|
652
839
|
if (token.partial) {
|
653
|
-
path += token.prefix
|
840
|
+
path += token.prefix;
|
654
841
|
}
|
655
842
|
|
656
843
|
continue
|
@@ -673,25 +860,25 @@ function tokensToFunction (tokens) {
|
|
673
860
|
}
|
674
861
|
|
675
862
|
for (var j = 0; j < value.length; j++) {
|
676
|
-
segment = encode(value[j])
|
863
|
+
segment = encode(value[j]);
|
677
864
|
|
678
865
|
if (!matches[i].test(segment)) {
|
679
866
|
throw new TypeError('Expected all "' + token.name + '" to match "' + token.pattern + '", but received `' + JSON.stringify(segment) + '`')
|
680
867
|
}
|
681
868
|
|
682
|
-
path += (j === 0 ? token.prefix : token.delimiter) + segment
|
869
|
+
path += (j === 0 ? token.prefix : token.delimiter) + segment;
|
683
870
|
}
|
684
871
|
|
685
872
|
continue
|
686
873
|
}
|
687
874
|
|
688
|
-
segment = token.asterisk ? encodeAsterisk(value) : encode(value)
|
875
|
+
segment = token.asterisk ? encodeAsterisk(value) : encode(value);
|
689
876
|
|
690
877
|
if (!matches[i].test(segment)) {
|
691
878
|
throw new TypeError('Expected "' + token.name + '" to match "' + token.pattern + '", but received "' + segment + '"')
|
692
879
|
}
|
693
880
|
|
694
|
-
path += token.prefix + segment
|
881
|
+
path += token.prefix + segment;
|
695
882
|
}
|
696
883
|
|
697
884
|
return path
|
@@ -726,7 +913,7 @@ function escapeGroup (group) {
|
|
726
913
|
* @return {!RegExp}
|
727
914
|
*/
|
728
915
|
function attachKeys (re, keys) {
|
729
|
-
re.keys = keys
|
916
|
+
re.keys = keys;
|
730
917
|
return re
|
731
918
|
}
|
732
919
|
|
@@ -749,7 +936,7 @@ function flags (options) {
|
|
749
936
|
*/
|
750
937
|
function regexpToRegexp (path, keys) {
|
751
938
|
// Use a negative lookahead to match only capturing groups.
|
752
|
-
var groups = path.source.match(/\((?!\?)/g)
|
939
|
+
var groups = path.source.match(/\((?!\?)/g);
|
753
940
|
|
754
941
|
if (groups) {
|
755
942
|
for (var i = 0; i < groups.length; i++) {
|
@@ -762,7 +949,7 @@ function regexpToRegexp (path, keys) {
|
|
762
949
|
partial: false,
|
763
950
|
asterisk: false,
|
764
951
|
pattern: null
|
765
|
-
})
|
952
|
+
});
|
766
953
|
}
|
767
954
|
}
|
768
955
|
|
@@ -778,13 +965,13 @@ function regexpToRegexp (path, keys) {
|
|
778
965
|
* @return {!RegExp}
|
779
966
|
*/
|
780
967
|
function arrayToRegexp (path, keys, options) {
|
781
|
-
var parts = []
|
968
|
+
var parts = [];
|
782
969
|
|
783
970
|
for (var i = 0; i < path.length; i++) {
|
784
|
-
parts.push(pathToRegexp(path[i], keys, options).source)
|
971
|
+
parts.push(pathToRegexp(path[i], keys, options).source);
|
785
972
|
}
|
786
973
|
|
787
|
-
var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options))
|
974
|
+
var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options));
|
788
975
|
|
789
976
|
return attachKeys(regexp, keys)
|
790
977
|
}
|
@@ -798,80 +985,79 @@ function arrayToRegexp (path, keys, options) {
|
|
798
985
|
* @return {!RegExp}
|
799
986
|
*/
|
800
987
|
function stringToRegexp (path, keys, options) {
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
// Attach keys back to the regexp.
|
805
|
-
for (var i = 0; i < tokens.length; i++) {
|
806
|
-
if (typeof tokens[i] !== 'string') {
|
807
|
-
keys.push(tokens[i])
|
808
|
-
}
|
809
|
-
}
|
810
|
-
|
811
|
-
return attachKeys(re, keys)
|
812
|
-
}
|
988
|
+
return tokensToRegExp(parse(path, options), keys, options)
|
989
|
+
}
|
813
990
|
|
814
991
|
/**
|
815
992
|
* Expose a function for taking tokens and returning a RegExp.
|
816
993
|
*
|
817
|
-
* @param {!Array}
|
818
|
-
* @param {Object=}
|
994
|
+
* @param {!Array} tokens
|
995
|
+
* @param {(Array|Object)=} keys
|
996
|
+
* @param {Object=} options
|
819
997
|
* @return {!RegExp}
|
820
998
|
*/
|
821
|
-
function tokensToRegExp (tokens, options) {
|
822
|
-
|
999
|
+
function tokensToRegExp (tokens, keys, options) {
|
1000
|
+
if (!isarray(keys)) {
|
1001
|
+
options = /** @type {!Object} */ (keys || options);
|
1002
|
+
keys = [];
|
1003
|
+
}
|
1004
|
+
|
1005
|
+
options = options || {};
|
823
1006
|
|
824
|
-
var strict = options.strict
|
825
|
-
var end = options.end !== false
|
826
|
-
var route = ''
|
827
|
-
var lastToken = tokens[tokens.length - 1]
|
828
|
-
var endsWithSlash = typeof lastToken === 'string' && /\/$/.test(lastToken)
|
1007
|
+
var strict = options.strict;
|
1008
|
+
var end = options.end !== false;
|
1009
|
+
var route = '';
|
829
1010
|
|
830
1011
|
// Iterate over the tokens and create our regexp string.
|
831
1012
|
for (var i = 0; i < tokens.length; i++) {
|
832
|
-
var token = tokens[i]
|
1013
|
+
var token = tokens[i];
|
833
1014
|
|
834
1015
|
if (typeof token === 'string') {
|
835
|
-
route += escapeString(token)
|
1016
|
+
route += escapeString(token);
|
836
1017
|
} else {
|
837
|
-
var prefix = escapeString(token.prefix)
|
838
|
-
var capture = '(?:' + token.pattern + ')'
|
1018
|
+
var prefix = escapeString(token.prefix);
|
1019
|
+
var capture = '(?:' + token.pattern + ')';
|
1020
|
+
|
1021
|
+
keys.push(token);
|
839
1022
|
|
840
1023
|
if (token.repeat) {
|
841
|
-
capture += '(?:' + prefix + capture + ')*'
|
1024
|
+
capture += '(?:' + prefix + capture + ')*';
|
842
1025
|
}
|
843
1026
|
|
844
1027
|
if (token.optional) {
|
845
1028
|
if (!token.partial) {
|
846
|
-
capture = '(?:' + prefix + '(' + capture + '))?'
|
1029
|
+
capture = '(?:' + prefix + '(' + capture + '))?';
|
847
1030
|
} else {
|
848
|
-
capture = prefix + '(' + capture + ')?'
|
1031
|
+
capture = prefix + '(' + capture + ')?';
|
849
1032
|
}
|
850
1033
|
} else {
|
851
|
-
capture = prefix + '(' + capture + ')'
|
1034
|
+
capture = prefix + '(' + capture + ')';
|
852
1035
|
}
|
853
1036
|
|
854
|
-
route += capture
|
1037
|
+
route += capture;
|
855
1038
|
}
|
856
1039
|
}
|
857
1040
|
|
1041
|
+
var delimiter = escapeString(options.delimiter || '/');
|
1042
|
+
var endsWithDelimiter = route.slice(-delimiter.length) === delimiter;
|
1043
|
+
|
858
1044
|
// In non-strict mode we allow a slash at the end of match. If the path to
|
859
1045
|
// match already ends with a slash, we remove it for consistency. The slash
|
860
1046
|
// is valid at the end of a path match, not in the middle. This is important
|
861
1047
|
// in non-ending mode, where "/test/" shouldn't match "/test//route".
|
862
1048
|
if (!strict) {
|
863
|
-
route = (
|
1049
|
+
route = (endsWithDelimiter ? route.slice(0, -delimiter.length) : route) + '(?:' + delimiter + '(?=$))?';
|
864
1050
|
}
|
865
1051
|
|
866
1052
|
if (end) {
|
867
|
-
route += '$'
|
1053
|
+
route += '$';
|
868
1054
|
} else {
|
869
1055
|
// In non-ending mode, we need the capturing groups to match as much as
|
870
1056
|
// possible by using a positive lookahead to the end or next path segment.
|
871
|
-
route += strict &&
|
1057
|
+
route += strict && endsWithDelimiter ? '' : '(?=' + delimiter + '|$)';
|
872
1058
|
}
|
873
1059
|
|
874
|
-
return new RegExp('^' + route, flags(options))
|
1060
|
+
return attachKeys(new RegExp('^' + route, flags(options)), keys)
|
875
1061
|
}
|
876
1062
|
|
877
1063
|
/**
|
@@ -887,15 +1073,13 @@ function tokensToRegExp (tokens, options) {
|
|
887
1073
|
* @return {!RegExp}
|
888
1074
|
*/
|
889
1075
|
function pathToRegexp (path, keys, options) {
|
890
|
-
keys = keys || []
|
891
|
-
|
892
1076
|
if (!isarray(keys)) {
|
893
|
-
options = /** @type {!Object} */ (keys)
|
894
|
-
keys = []
|
895
|
-
} else if (!options) {
|
896
|
-
options = {}
|
1077
|
+
options = /** @type {!Object} */ (keys || options);
|
1078
|
+
keys = [];
|
897
1079
|
}
|
898
1080
|
|
1081
|
+
options = options || {};
|
1082
|
+
|
899
1083
|
if (path instanceof RegExp) {
|
900
1084
|
return regexpToRegexp(path, /** @type {!Array} */ (keys))
|
901
1085
|
}
|
@@ -914,101 +1098,146 @@ index.tokensToRegExp = tokensToRegExp_1;
|
|
914
1098
|
|
915
1099
|
/* */
|
916
1100
|
|
917
|
-
|
918
|
-
var pathMap = Object.create(null)
|
919
|
-
var nameMap = Object.create(null)
|
1101
|
+
var regexpCache = Object.create(null);
|
920
1102
|
|
921
|
-
|
922
|
-
|
923
|
-
|
1103
|
+
function getRouteRegex (path) {
|
1104
|
+
var hit = regexpCache[path];
|
1105
|
+
var keys, regexp;
|
924
1106
|
|
925
|
-
|
926
|
-
|
927
|
-
|
1107
|
+
if (hit) {
|
1108
|
+
keys = hit.keys;
|
1109
|
+
regexp = hit.regexp;
|
1110
|
+
} else {
|
1111
|
+
keys = [];
|
1112
|
+
regexp = index(path, keys);
|
1113
|
+
regexpCache[path] = { keys: keys, regexp: regexp };
|
928
1114
|
}
|
1115
|
+
|
1116
|
+
return { keys: keys, regexp: regexp }
|
929
1117
|
}
|
930
1118
|
|
931
|
-
|
932
|
-
pathMap,
|
933
|
-
nameMap,
|
934
|
-
route,
|
935
|
-
parent,
|
936
|
-
matchAs
|
937
|
-
) {
|
938
|
-
var path = route.path;
|
939
|
-
var name = route.name;
|
940
|
-
assert(path != null, "\"path\" is required in a route configuration.")
|
1119
|
+
var regexpCompileCache = Object.create(null);
|
941
1120
|
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
1121
|
+
function fillParams (
|
1122
|
+
path,
|
1123
|
+
params,
|
1124
|
+
routeMsg
|
1125
|
+
) {
|
1126
|
+
try {
|
1127
|
+
var filler =
|
1128
|
+
regexpCompileCache[path] ||
|
1129
|
+
(regexpCompileCache[path] = index.compile(path));
|
1130
|
+
return filler(params || {}, { pretty: true })
|
1131
|
+
} catch (e) {
|
1132
|
+
{
|
1133
|
+
warn(false, ("missing param for " + routeMsg + ": " + (e.message)));
|
1134
|
+
}
|
1135
|
+
return ''
|
952
1136
|
}
|
1137
|
+
}
|
953
1138
|
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
1139
|
+
/* */
|
1140
|
+
|
1141
|
+
function normalizeLocation (
|
1142
|
+
raw,
|
1143
|
+
current,
|
1144
|
+
append
|
1145
|
+
) {
|
1146
|
+
var next = typeof raw === 'string' ? { path: raw } : raw;
|
1147
|
+
// named target
|
1148
|
+
if (next.name || next._normalized) {
|
1149
|
+
return next
|
962
1150
|
}
|
963
1151
|
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
1152
|
+
// relative params
|
1153
|
+
if (!next.path && next.params && current) {
|
1154
|
+
next = assign({}, next);
|
1155
|
+
next._normalized = true;
|
1156
|
+
var params = assign(assign({}, current.params), next.params);
|
1157
|
+
if (current.name) {
|
1158
|
+
next.name = current.name;
|
1159
|
+
next.params = params;
|
1160
|
+
} else if (current.matched) {
|
1161
|
+
var rawPath = current.matched[current.matched.length - 1].path;
|
1162
|
+
next.path = fillParams(rawPath, params, ("path " + (current.path)));
|
969
1163
|
} else {
|
970
|
-
|
1164
|
+
warn(false, "relative params navigation requires a current route.");
|
971
1165
|
}
|
1166
|
+
return next
|
1167
|
+
}
|
1168
|
+
|
1169
|
+
var parsedPath = parsePath(next.path || '');
|
1170
|
+
var basePath = (current && current.path) || '/';
|
1171
|
+
var path = parsedPath.path
|
1172
|
+
? resolvePath(parsedPath.path, basePath, append || next.append)
|
1173
|
+
: (current && current.path) || '/';
|
1174
|
+
var query = resolveQuery(parsedPath.query, next.query);
|
1175
|
+
var hash = next.hash || parsedPath.hash;
|
1176
|
+
if (hash && hash.charAt(0) !== '#') {
|
1177
|
+
hash = "#" + hash;
|
972
1178
|
}
|
973
1179
|
|
974
|
-
|
975
|
-
|
1180
|
+
return {
|
1181
|
+
_normalized: true,
|
1182
|
+
path: path,
|
1183
|
+
query: query,
|
1184
|
+
hash: hash
|
1185
|
+
}
|
976
1186
|
}
|
977
1187
|
|
978
|
-
function
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
return
|
1188
|
+
function assign (a, b) {
|
1189
|
+
for (var key in b) {
|
1190
|
+
a[key] = b[key];
|
1191
|
+
}
|
1192
|
+
return a
|
983
1193
|
}
|
984
1194
|
|
985
1195
|
/* */
|
986
1196
|
|
987
|
-
var regexpCache = Object.create(null)
|
988
|
-
|
989
|
-
var regexpCompileCache = Object.create(null)
|
990
|
-
|
991
1197
|
function createMatcher (routes) {
|
992
1198
|
var ref = createRouteMap(routes);
|
993
1199
|
var pathMap = ref.pathMap;
|
994
1200
|
var nameMap = ref.nameMap;
|
995
1201
|
|
1202
|
+
function addRoutes (routes) {
|
1203
|
+
createRouteMap(routes, pathMap, nameMap);
|
1204
|
+
}
|
1205
|
+
|
996
1206
|
function match (
|
997
1207
|
raw,
|
998
1208
|
currentRoute,
|
999
1209
|
redirectedFrom
|
1000
1210
|
) {
|
1001
|
-
var location = normalizeLocation(raw, currentRoute)
|
1211
|
+
var location = normalizeLocation(raw, currentRoute);
|
1002
1212
|
var name = location.name;
|
1003
1213
|
|
1004
1214
|
if (name) {
|
1005
|
-
var record = nameMap[name]
|
1215
|
+
var record = nameMap[name];
|
1216
|
+
{
|
1217
|
+
warn(record, ("Route with name '" + name + "' does not exist"));
|
1218
|
+
}
|
1219
|
+
var paramNames = getRouteRegex(record.path).keys
|
1220
|
+
.filter(function (key) { return !key.optional; })
|
1221
|
+
.map(function (key) { return key.name; });
|
1222
|
+
|
1223
|
+
if (typeof location.params !== 'object') {
|
1224
|
+
location.params = {};
|
1225
|
+
}
|
1226
|
+
|
1227
|
+
if (currentRoute && typeof currentRoute.params === 'object') {
|
1228
|
+
for (var key in currentRoute.params) {
|
1229
|
+
if (!(key in location.params) && paramNames.indexOf(key) > -1) {
|
1230
|
+
location.params[key] = currentRoute.params[key];
|
1231
|
+
}
|
1232
|
+
}
|
1233
|
+
}
|
1234
|
+
|
1006
1235
|
if (record) {
|
1007
|
-
location.path = fillParams(record.path, location.params, ("named route \"" + name + "\""))
|
1236
|
+
location.path = fillParams(record.path, location.params, ("named route \"" + name + "\""));
|
1008
1237
|
return _createRoute(record, location, redirectedFrom)
|
1009
1238
|
}
|
1010
1239
|
} else if (location.path) {
|
1011
|
-
location.params = {}
|
1240
|
+
location.params = {};
|
1012
1241
|
for (var path in pathMap) {
|
1013
1242
|
if (matchRoute(path, location.params, location.path)) {
|
1014
1243
|
return _createRoute(pathMap[path], location, redirectedFrom)
|
@@ -1023,34 +1252,38 @@ function createMatcher (routes) {
|
|
1023
1252
|
record,
|
1024
1253
|
location
|
1025
1254
|
) {
|
1026
|
-
var originalRedirect = record.redirect
|
1255
|
+
var originalRedirect = record.redirect;
|
1027
1256
|
var redirect = typeof originalRedirect === 'function'
|
1028
1257
|
? originalRedirect(createRoute(record, location))
|
1029
|
-
: originalRedirect
|
1258
|
+
: originalRedirect;
|
1030
1259
|
|
1031
1260
|
if (typeof redirect === 'string') {
|
1032
|
-
redirect = { path: redirect }
|
1261
|
+
redirect = { path: redirect };
|
1033
1262
|
}
|
1034
1263
|
|
1035
1264
|
if (!redirect || typeof redirect !== 'object') {
|
1036
|
-
|
1265
|
+
"development" !== 'production' && warn(
|
1266
|
+
false, ("invalid redirect option: " + (JSON.stringify(redirect)))
|
1267
|
+
);
|
1037
1268
|
return _createRoute(null, location)
|
1038
1269
|
}
|
1039
1270
|
|
1040
|
-
var re = redirect
|
1271
|
+
var re = redirect;
|
1041
1272
|
var name = re.name;
|
1042
1273
|
var path = re.path;
|
1043
1274
|
var query = location.query;
|
1044
1275
|
var hash = location.hash;
|
1045
1276
|
var params = location.params;
|
1046
|
-
query = re.hasOwnProperty('query') ? re.query : query
|
1047
|
-
hash = re.hasOwnProperty('hash') ? re.hash : hash
|
1048
|
-
params = re.hasOwnProperty('params') ? re.params : params
|
1277
|
+
query = re.hasOwnProperty('query') ? re.query : query;
|
1278
|
+
hash = re.hasOwnProperty('hash') ? re.hash : hash;
|
1279
|
+
params = re.hasOwnProperty('params') ? re.params : params;
|
1049
1280
|
|
1050
1281
|
if (name) {
|
1051
1282
|
// resolved named direct
|
1052
|
-
var targetRecord = nameMap[name]
|
1053
|
-
|
1283
|
+
var targetRecord = nameMap[name];
|
1284
|
+
{
|
1285
|
+
assert(targetRecord, ("redirect failed: named route \"" + name + "\" not found."));
|
1286
|
+
}
|
1054
1287
|
return match({
|
1055
1288
|
_normalized: true,
|
1056
1289
|
name: name,
|
@@ -1060,9 +1293,9 @@ function createMatcher (routes) {
|
|
1060
1293
|
}, undefined, location)
|
1061
1294
|
} else if (path) {
|
1062
1295
|
// 1. resolve relative redirect
|
1063
|
-
var rawPath = resolveRecordPath(path, record)
|
1296
|
+
var rawPath = resolveRecordPath(path, record);
|
1064
1297
|
// 2. resolve params
|
1065
|
-
var resolvedPath = fillParams(rawPath, params, ("redirect route with path \"" + rawPath + "\""))
|
1298
|
+
var resolvedPath = fillParams(rawPath, params, ("redirect route with path \"" + rawPath + "\""));
|
1066
1299
|
// 3. rematch with existing query and hash
|
1067
1300
|
return match({
|
1068
1301
|
_normalized: true,
|
@@ -1071,7 +1304,7 @@ function createMatcher (routes) {
|
|
1071
1304
|
hash: hash
|
1072
1305
|
}, undefined, location)
|
1073
1306
|
} else {
|
1074
|
-
warn(false, ("invalid redirect option: " + (JSON.stringify(redirect))))
|
1307
|
+
warn(false, ("invalid redirect option: " + (JSON.stringify(redirect))));
|
1075
1308
|
return _createRoute(null, location)
|
1076
1309
|
}
|
1077
1310
|
}
|
@@ -1081,15 +1314,15 @@ function createMatcher (routes) {
|
|
1081
1314
|
location,
|
1082
1315
|
matchAs
|
1083
1316
|
) {
|
1084
|
-
var aliasedPath = fillParams(matchAs, location.params, ("aliased route with path \"" + matchAs + "\""))
|
1317
|
+
var aliasedPath = fillParams(matchAs, location.params, ("aliased route with path \"" + matchAs + "\""));
|
1085
1318
|
var aliasedMatch = match({
|
1086
1319
|
_normalized: true,
|
1087
1320
|
path: aliasedPath
|
1088
|
-
})
|
1321
|
+
});
|
1089
1322
|
if (aliasedMatch) {
|
1090
|
-
var matched = aliasedMatch.matched
|
1091
|
-
var aliasedRecord = matched[matched.length - 1]
|
1092
|
-
location.params = aliasedMatch.params
|
1323
|
+
var matched = aliasedMatch.matched;
|
1324
|
+
var aliasedRecord = matched[matched.length - 1];
|
1325
|
+
location.params = aliasedMatch.params;
|
1093
1326
|
return _createRoute(aliasedRecord, location)
|
1094
1327
|
}
|
1095
1328
|
return _createRoute(null, location)
|
@@ -1109,7 +1342,10 @@ function createMatcher (routes) {
|
|
1109
1342
|
return createRoute(record, location, redirectedFrom)
|
1110
1343
|
}
|
1111
1344
|
|
1112
|
-
return
|
1345
|
+
return {
|
1346
|
+
match: match,
|
1347
|
+
addRoutes: addRoutes
|
1348
|
+
}
|
1113
1349
|
}
|
1114
1350
|
|
1115
1351
|
function matchRoute (
|
@@ -1117,17 +1353,10 @@ function matchRoute (
|
|
1117
1353
|
params,
|
1118
1354
|
pathname
|
1119
1355
|
) {
|
1120
|
-
var
|
1121
|
-
var
|
1122
|
-
|
1123
|
-
|
1124
|
-
regexp = hit.regexp
|
1125
|
-
} else {
|
1126
|
-
keys = []
|
1127
|
-
regexp = index(path, keys)
|
1128
|
-
regexpCache[path] = { keys: keys, regexp: regexp }
|
1129
|
-
}
|
1130
|
-
var m = pathname.match(regexp)
|
1356
|
+
var ref = getRouteRegex(path);
|
1357
|
+
var regexp = ref.regexp;
|
1358
|
+
var keys = ref.keys;
|
1359
|
+
var m = pathname.match(regexp);
|
1131
1360
|
|
1132
1361
|
if (!m) {
|
1133
1362
|
return false
|
@@ -1136,40 +1365,121 @@ function matchRoute (
|
|
1136
1365
|
}
|
1137
1366
|
|
1138
1367
|
for (var i = 1, len = m.length; i < len; ++i) {
|
1139
|
-
var key = keys[i - 1]
|
1140
|
-
var val = typeof m[i] === 'string' ? decodeURIComponent(m[i]) : m[i]
|
1141
|
-
if (key) { params[key.name] = val }
|
1368
|
+
var key = keys[i - 1];
|
1369
|
+
var val = typeof m[i] === 'string' ? decodeURIComponent(m[i]) : m[i];
|
1370
|
+
if (key) { params[key.name] = val; }
|
1142
1371
|
}
|
1143
1372
|
|
1144
1373
|
return true
|
1145
1374
|
}
|
1146
1375
|
|
1147
|
-
function
|
1148
|
-
path,
|
1149
|
-
|
1150
|
-
|
1376
|
+
function resolveRecordPath (path, record) {
|
1377
|
+
return resolvePath(path, record.parent ? record.parent.path : '/', true)
|
1378
|
+
}
|
1379
|
+
|
1380
|
+
/* */
|
1381
|
+
|
1382
|
+
|
1383
|
+
var positionStore = Object.create(null);
|
1384
|
+
|
1385
|
+
function setupScroll () {
|
1386
|
+
window.addEventListener('popstate', function (e) {
|
1387
|
+
saveScrollPosition();
|
1388
|
+
if (e.state && e.state.key) {
|
1389
|
+
setStateKey(e.state.key);
|
1390
|
+
}
|
1391
|
+
});
|
1392
|
+
}
|
1393
|
+
|
1394
|
+
function handleScroll (
|
1395
|
+
router,
|
1396
|
+
to,
|
1397
|
+
from,
|
1398
|
+
isPop
|
1151
1399
|
) {
|
1152
|
-
|
1153
|
-
|
1154
|
-
regexpCompileCache[path] ||
|
1155
|
-
(regexpCompileCache[path] = index.compile(path))
|
1156
|
-
return filler(params || {}, { pretty: true })
|
1157
|
-
} catch (e) {
|
1158
|
-
assert(false, ("missing param for " + routeMsg + ": " + (e.message)))
|
1159
|
-
return ''
|
1400
|
+
if (!router.app) {
|
1401
|
+
return
|
1160
1402
|
}
|
1403
|
+
|
1404
|
+
var behavior = router.options.scrollBehavior;
|
1405
|
+
if (!behavior) {
|
1406
|
+
return
|
1407
|
+
}
|
1408
|
+
|
1409
|
+
{
|
1410
|
+
assert(typeof behavior === 'function', "scrollBehavior must be a function");
|
1411
|
+
}
|
1412
|
+
|
1413
|
+
// wait until re-render finishes before scrolling
|
1414
|
+
router.app.$nextTick(function () {
|
1415
|
+
var position = getScrollPosition();
|
1416
|
+
var shouldScroll = behavior(to, from, isPop ? position : null);
|
1417
|
+
if (!shouldScroll) {
|
1418
|
+
return
|
1419
|
+
}
|
1420
|
+
var isObject = typeof shouldScroll === 'object';
|
1421
|
+
if (isObject && typeof shouldScroll.selector === 'string') {
|
1422
|
+
var el = document.querySelector(shouldScroll.selector);
|
1423
|
+
if (el) {
|
1424
|
+
position = getElementPosition(el);
|
1425
|
+
} else if (isValidPosition(shouldScroll)) {
|
1426
|
+
position = normalizePosition(shouldScroll);
|
1427
|
+
}
|
1428
|
+
} else if (isObject && isValidPosition(shouldScroll)) {
|
1429
|
+
position = normalizePosition(shouldScroll);
|
1430
|
+
}
|
1431
|
+
|
1432
|
+
if (position) {
|
1433
|
+
window.scrollTo(position.x, position.y);
|
1434
|
+
}
|
1435
|
+
});
|
1161
1436
|
}
|
1162
1437
|
|
1163
|
-
function
|
1164
|
-
|
1438
|
+
function saveScrollPosition () {
|
1439
|
+
var key = getStateKey();
|
1440
|
+
if (key) {
|
1441
|
+
positionStore[key] = {
|
1442
|
+
x: window.pageXOffset,
|
1443
|
+
y: window.pageYOffset
|
1444
|
+
};
|
1445
|
+
}
|
1165
1446
|
}
|
1166
1447
|
|
1167
|
-
|
1448
|
+
function getScrollPosition () {
|
1449
|
+
var key = getStateKey();
|
1450
|
+
if (key) {
|
1451
|
+
return positionStore[key]
|
1452
|
+
}
|
1453
|
+
}
|
1168
1454
|
|
1169
|
-
|
1455
|
+
function getElementPosition (el) {
|
1456
|
+
var docRect = document.documentElement.getBoundingClientRect();
|
1457
|
+
var elRect = el.getBoundingClientRect();
|
1458
|
+
return {
|
1459
|
+
x: elRect.left - docRect.left,
|
1460
|
+
y: elRect.top - docRect.top
|
1461
|
+
}
|
1462
|
+
}
|
1463
|
+
|
1464
|
+
function isValidPosition (obj) {
|
1465
|
+
return isNumber(obj.x) || isNumber(obj.y)
|
1466
|
+
}
|
1467
|
+
|
1468
|
+
function normalizePosition (obj) {
|
1469
|
+
return {
|
1470
|
+
x: isNumber(obj.x) ? obj.x : window.pageXOffset,
|
1471
|
+
y: isNumber(obj.y) ? obj.y : window.pageYOffset
|
1472
|
+
}
|
1473
|
+
}
|
1474
|
+
|
1475
|
+
function isNumber (v) {
|
1476
|
+
return typeof v === 'number'
|
1477
|
+
}
|
1170
1478
|
|
1171
|
-
|
1172
|
-
|
1479
|
+
/* */
|
1480
|
+
|
1481
|
+
var supportsPushState = inBrowser && (function () {
|
1482
|
+
var ua = window.navigator.userAgent;
|
1173
1483
|
|
1174
1484
|
if (
|
1175
1485
|
(ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) &&
|
@@ -1181,63 +1491,127 @@ var supportsHistory = inBrowser && (function () {
|
|
1181
1491
|
}
|
1182
1492
|
|
1183
1493
|
return window.history && 'pushState' in window.history
|
1184
|
-
})()
|
1494
|
+
})();
|
1495
|
+
|
1496
|
+
// use User Timing api (if present) for more accurate key precision
|
1497
|
+
var Time = inBrowser && window.performance && window.performance.now
|
1498
|
+
? window.performance
|
1499
|
+
: Date;
|
1500
|
+
|
1501
|
+
var _key = genKey();
|
1502
|
+
|
1503
|
+
function genKey () {
|
1504
|
+
return Time.now().toFixed(3)
|
1505
|
+
}
|
1506
|
+
|
1507
|
+
function getStateKey () {
|
1508
|
+
return _key
|
1509
|
+
}
|
1510
|
+
|
1511
|
+
function setStateKey (key) {
|
1512
|
+
_key = key;
|
1513
|
+
}
|
1514
|
+
|
1515
|
+
function pushState (url, replace) {
|
1516
|
+
saveScrollPosition();
|
1517
|
+
// try...catch the pushState call to get around Safari
|
1518
|
+
// DOM Exception 18 where it limits to 100 pushState calls
|
1519
|
+
var history = window.history;
|
1520
|
+
try {
|
1521
|
+
if (replace) {
|
1522
|
+
history.replaceState({ key: _key }, '', url);
|
1523
|
+
} else {
|
1524
|
+
_key = genKey();
|
1525
|
+
history.pushState({ key: _key }, '', url);
|
1526
|
+
}
|
1527
|
+
} catch (e) {
|
1528
|
+
window.location[replace ? 'replace' : 'assign'](url);
|
1529
|
+
}
|
1530
|
+
}
|
1531
|
+
|
1532
|
+
function replaceState (url) {
|
1533
|
+
pushState(url, true);
|
1534
|
+
}
|
1185
1535
|
|
1186
1536
|
/* */
|
1187
1537
|
|
1188
1538
|
function runQueue (queue, fn, cb) {
|
1189
1539
|
var step = function (index) {
|
1190
1540
|
if (index >= queue.length) {
|
1191
|
-
cb()
|
1541
|
+
cb();
|
1192
1542
|
} else {
|
1193
1543
|
if (queue[index]) {
|
1194
1544
|
fn(queue[index], function () {
|
1195
|
-
step(index + 1)
|
1196
|
-
})
|
1545
|
+
step(index + 1);
|
1546
|
+
});
|
1197
1547
|
} else {
|
1198
|
-
step(index + 1)
|
1548
|
+
step(index + 1);
|
1199
1549
|
}
|
1200
1550
|
}
|
1201
|
-
}
|
1202
|
-
step(0)
|
1551
|
+
};
|
1552
|
+
step(0);
|
1203
1553
|
}
|
1204
1554
|
|
1205
1555
|
/* */
|
1206
1556
|
|
1207
1557
|
|
1208
1558
|
var History = function History (router, base) {
|
1209
|
-
this.router = router
|
1210
|
-
this.base = normalizeBase(base)
|
1559
|
+
this.router = router;
|
1560
|
+
this.base = normalizeBase(base);
|
1211
1561
|
// start with a route object that stands for "nowhere"
|
1212
|
-
this.current = START
|
1213
|
-
this.pending = null
|
1562
|
+
this.current = START;
|
1563
|
+
this.pending = null;
|
1564
|
+
this.ready = false;
|
1565
|
+
this.readyCbs = [];
|
1214
1566
|
};
|
1215
1567
|
|
1216
1568
|
History.prototype.listen = function listen (cb) {
|
1217
|
-
this.cb = cb
|
1569
|
+
this.cb = cb;
|
1218
1570
|
};
|
1219
1571
|
|
1220
|
-
History.prototype.
|
1572
|
+
History.prototype.onReady = function onReady (cb) {
|
1573
|
+
if (this.ready) {
|
1574
|
+
cb();
|
1575
|
+
} else {
|
1576
|
+
this.readyCbs.push(cb);
|
1577
|
+
}
|
1578
|
+
};
|
1579
|
+
|
1580
|
+
History.prototype.transitionTo = function transitionTo (location, onComplete, onAbort) {
|
1221
1581
|
var this$1 = this;
|
1222
1582
|
|
1223
|
-
var route = this.router.match(location, this.current)
|
1583
|
+
var route = this.router.match(location, this.current);
|
1224
1584
|
this.confirmTransition(route, function () {
|
1225
|
-
this$1.updateRoute(route)
|
1226
|
-
|
1227
|
-
this$1.ensureURL()
|
1228
|
-
|
1585
|
+
this$1.updateRoute(route);
|
1586
|
+
onComplete && onComplete(route);
|
1587
|
+
this$1.ensureURL();
|
1588
|
+
|
1589
|
+
// fire ready cbs once
|
1590
|
+
if (!this$1.ready) {
|
1591
|
+
this$1.ready = true;
|
1592
|
+
this$1.readyCbs.forEach(function (cb) {
|
1593
|
+
cb(route);
|
1594
|
+
});
|
1595
|
+
}
|
1596
|
+
}, onAbort);
|
1229
1597
|
};
|
1230
1598
|
|
1231
|
-
History.prototype.confirmTransition = function confirmTransition (route,
|
1599
|
+
History.prototype.confirmTransition = function confirmTransition (route, onComplete, onAbort) {
|
1232
1600
|
var this$1 = this;
|
1233
1601
|
|
1234
|
-
var current = this.current
|
1235
|
-
|
1236
|
-
|
1237
|
-
|
1602
|
+
var current = this.current;
|
1603
|
+
var abort = function () { onAbort && onAbort(); };
|
1604
|
+
if (
|
1605
|
+
isSameRoute(route, current) &&
|
1606
|
+
// in the case the route map has been dynamically appended to
|
1607
|
+
route.matched.length === current.matched.length
|
1608
|
+
) {
|
1609
|
+
this.ensureURL();
|
1610
|
+
return abort()
|
1238
1611
|
}
|
1239
1612
|
|
1240
1613
|
var ref = resolveQueue(this.current.matched, route.matched);
|
1614
|
+
var updated = ref.updated;
|
1241
1615
|
var deactivated = ref.deactivated;
|
1242
1616
|
var activated = ref.activated;
|
1243
1617
|
|
@@ -1246,67 +1620,78 @@ History.prototype.confirmTransition = function confirmTransition (route, cb) {
|
|
1246
1620
|
extractLeaveGuards(deactivated),
|
1247
1621
|
// global before hooks
|
1248
1622
|
this.router.beforeHooks,
|
1249
|
-
//
|
1623
|
+
// in-component update hooks
|
1624
|
+
extractUpdateHooks(updated),
|
1625
|
+
// in-config enter guards
|
1250
1626
|
activated.map(function (m) { return m.beforeEnter; }),
|
1251
1627
|
// async components
|
1252
1628
|
resolveAsyncComponents(activated)
|
1253
|
-
)
|
1629
|
+
);
|
1254
1630
|
|
1255
|
-
this.pending = route
|
1631
|
+
this.pending = route;
|
1256
1632
|
var iterator = function (hook, next) {
|
1257
|
-
if (this$1.pending !== route) {
|
1633
|
+
if (this$1.pending !== route) {
|
1634
|
+
return abort()
|
1635
|
+
}
|
1258
1636
|
hook(route, current, function (to) {
|
1259
1637
|
if (to === false) {
|
1260
1638
|
// next(false) -> abort navigation, ensure current URL
|
1261
|
-
this$1.ensureURL()
|
1639
|
+
this$1.ensureURL(true);
|
1640
|
+
abort();
|
1262
1641
|
} else if (typeof to === 'string' || typeof to === 'object') {
|
1263
1642
|
// next('/') or next({ path: '/' }) -> redirect
|
1264
|
-
this$1.push(to)
|
1643
|
+
(typeof to === 'object' && to.replace) ? this$1.replace(to) : this$1.push(to);
|
1644
|
+
abort();
|
1265
1645
|
} else {
|
1266
1646
|
// confirm transition and pass on the value
|
1267
|
-
next(to)
|
1647
|
+
next(to);
|
1268
1648
|
}
|
1269
|
-
})
|
1270
|
-
}
|
1649
|
+
});
|
1650
|
+
};
|
1271
1651
|
|
1272
1652
|
runQueue(queue, iterator, function () {
|
1273
|
-
var postEnterCbs = []
|
1653
|
+
var postEnterCbs = [];
|
1654
|
+
var isValid = function () { return this$1.current === route; };
|
1655
|
+
var enterGuards = extractEnterGuards(activated, postEnterCbs, isValid);
|
1274
1656
|
// wait until async components are resolved before
|
1275
1657
|
// extracting in-component enter guards
|
1276
|
-
runQueue(
|
1277
|
-
if (this$1.pending
|
1278
|
-
|
1279
|
-
|
1658
|
+
runQueue(enterGuards, iterator, function () {
|
1659
|
+
if (this$1.pending !== route) {
|
1660
|
+
return abort()
|
1661
|
+
}
|
1662
|
+
this$1.pending = null;
|
1663
|
+
onComplete(route);
|
1664
|
+
if (this$1.router.app) {
|
1280
1665
|
this$1.router.app.$nextTick(function () {
|
1281
|
-
postEnterCbs.forEach(function (cb) { return cb(); })
|
1282
|
-
})
|
1666
|
+
postEnterCbs.forEach(function (cb) { return cb(); });
|
1667
|
+
});
|
1283
1668
|
}
|
1284
|
-
})
|
1285
|
-
})
|
1669
|
+
});
|
1670
|
+
});
|
1286
1671
|
};
|
1287
1672
|
|
1288
1673
|
History.prototype.updateRoute = function updateRoute (route) {
|
1289
|
-
var prev = this.current
|
1290
|
-
this.current = route
|
1291
|
-
this.cb && this.cb(route)
|
1674
|
+
var prev = this.current;
|
1675
|
+
this.current = route;
|
1676
|
+
this.cb && this.cb(route);
|
1292
1677
|
this.router.afterHooks.forEach(function (hook) {
|
1293
|
-
hook && hook(route, prev)
|
1294
|
-
})
|
1678
|
+
hook && hook(route, prev);
|
1679
|
+
});
|
1295
1680
|
};
|
1296
1681
|
|
1297
1682
|
function normalizeBase (base) {
|
1298
1683
|
if (!base) {
|
1299
1684
|
if (inBrowser) {
|
1300
1685
|
// respect <base> tag
|
1301
|
-
var baseEl = document.querySelector('base')
|
1302
|
-
base = baseEl ? baseEl.getAttribute('href') : '/'
|
1686
|
+
var baseEl = document.querySelector('base');
|
1687
|
+
base = baseEl ? baseEl.getAttribute('href') : '/';
|
1303
1688
|
} else {
|
1304
|
-
base = '/'
|
1689
|
+
base = '/';
|
1305
1690
|
}
|
1306
1691
|
}
|
1307
1692
|
// make sure there's the starting slash
|
1308
1693
|
if (base.charAt(0) !== '/') {
|
1309
|
-
base = '/' + base
|
1694
|
+
base = '/' + base;
|
1310
1695
|
}
|
1311
1696
|
// remove trailing slash
|
1312
1697
|
return base.replace(/\/$/, '')
|
@@ -1316,48 +1701,111 @@ function resolveQueue (
|
|
1316
1701
|
current,
|
1317
1702
|
next
|
1318
1703
|
) {
|
1319
|
-
var i
|
1320
|
-
var max = Math.max(current.length, next.length)
|
1704
|
+
var i;
|
1705
|
+
var max = Math.max(current.length, next.length);
|
1321
1706
|
for (i = 0; i < max; i++) {
|
1322
1707
|
if (current[i] !== next[i]) {
|
1323
1708
|
break
|
1324
1709
|
}
|
1325
1710
|
}
|
1326
1711
|
return {
|
1712
|
+
updated: next.slice(0, i),
|
1327
1713
|
activated: next.slice(i),
|
1328
1714
|
deactivated: current.slice(i)
|
1329
1715
|
}
|
1330
1716
|
}
|
1331
1717
|
|
1332
|
-
function
|
1333
|
-
|
1334
|
-
|
1718
|
+
function extractGuards (
|
1719
|
+
records,
|
1720
|
+
name,
|
1721
|
+
bind,
|
1722
|
+
reverse
|
1723
|
+
) {
|
1724
|
+
var guards = flatMapComponents(records, function (def, instance, match, key) {
|
1725
|
+
var guard = extractGuard(def, name);
|
1335
1726
|
if (guard) {
|
1336
|
-
return
|
1337
|
-
|
1338
|
-
|
1727
|
+
return Array.isArray(guard)
|
1728
|
+
? guard.map(function (guard) { return bind(guard, instance, match, key); })
|
1729
|
+
: bind(guard, instance, match, key)
|
1339
1730
|
}
|
1340
|
-
})
|
1731
|
+
});
|
1732
|
+
return flatten(reverse ? guards.reverse() : guards)
|
1341
1733
|
}
|
1342
1734
|
|
1343
|
-
function
|
1344
|
-
|
1345
|
-
|
1346
|
-
|
1347
|
-
|
1348
|
-
|
1349
|
-
|
1350
|
-
|
1351
|
-
|
1352
|
-
|
1353
|
-
|
1354
|
-
|
1355
|
-
|
1356
|
-
|
1357
|
-
|
1735
|
+
function extractGuard (
|
1736
|
+
def,
|
1737
|
+
key
|
1738
|
+
) {
|
1739
|
+
if (typeof def !== 'function') {
|
1740
|
+
// extend now so that global mixins are applied.
|
1741
|
+
def = _Vue.extend(def);
|
1742
|
+
}
|
1743
|
+
return def.options[key]
|
1744
|
+
}
|
1745
|
+
|
1746
|
+
function extractLeaveGuards (deactivated) {
|
1747
|
+
return extractGuards(deactivated, 'beforeRouteLeave', bindGuard, true)
|
1748
|
+
}
|
1749
|
+
|
1750
|
+
function extractUpdateHooks (updated) {
|
1751
|
+
return extractGuards(updated, 'beforeRouteUpdate', bindGuard)
|
1752
|
+
}
|
1753
|
+
|
1754
|
+
function bindGuard (guard, instance) {
|
1755
|
+
return function boundRouteGuard () {
|
1756
|
+
return guard.apply(instance, arguments)
|
1757
|
+
}
|
1758
|
+
}
|
1759
|
+
|
1760
|
+
function extractEnterGuards (
|
1761
|
+
activated,
|
1762
|
+
cbs,
|
1763
|
+
isValid
|
1764
|
+
) {
|
1765
|
+
return extractGuards(activated, 'beforeRouteEnter', function (guard, _, match, key) {
|
1766
|
+
return bindEnterGuard(guard, match, key, cbs, isValid)
|
1358
1767
|
})
|
1359
1768
|
}
|
1360
1769
|
|
1770
|
+
function bindEnterGuard (
|
1771
|
+
guard,
|
1772
|
+
match,
|
1773
|
+
key,
|
1774
|
+
cbs,
|
1775
|
+
isValid
|
1776
|
+
) {
|
1777
|
+
return function routeEnterGuard (to, from, next) {
|
1778
|
+
return guard(to, from, function (cb) {
|
1779
|
+
next(cb);
|
1780
|
+
if (typeof cb === 'function') {
|
1781
|
+
cbs.push(function () {
|
1782
|
+
// #750
|
1783
|
+
// if a router-view is wrapped with an out-in transition,
|
1784
|
+
// the instance may not have been registered at this time.
|
1785
|
+
// we will need to poll for registration until current route
|
1786
|
+
// is no longer valid.
|
1787
|
+
poll(cb, match.instances, key, isValid);
|
1788
|
+
});
|
1789
|
+
}
|
1790
|
+
})
|
1791
|
+
}
|
1792
|
+
}
|
1793
|
+
|
1794
|
+
function poll (
|
1795
|
+
cb, // somehow flow cannot infer this is a function
|
1796
|
+
instances,
|
1797
|
+
key,
|
1798
|
+
isValid
|
1799
|
+
) {
|
1800
|
+
if (instances[key]) {
|
1801
|
+
cb(instances[key]);
|
1802
|
+
} else if (isValid()) {
|
1803
|
+
setTimeout(function () {
|
1804
|
+
poll(cb, instances, key, isValid);
|
1805
|
+
}, 16);
|
1806
|
+
}
|
1807
|
+
}
|
1808
|
+
|
1361
1809
|
function resolveAsyncComponents (matched) {
|
1362
1810
|
return flatMapComponents(matched, function (def, _, match, key) {
|
1363
1811
|
// if it's a function and doesn't have Vue options attached,
|
@@ -1367,19 +1815,19 @@ function resolveAsyncComponents (matched) {
|
|
1367
1815
|
// resolved.
|
1368
1816
|
if (typeof def === 'function' && !def.options) {
|
1369
1817
|
return function (to, from, next) {
|
1370
|
-
var resolve = function (resolvedDef) {
|
1371
|
-
match.components[key] = resolvedDef
|
1372
|
-
next()
|
1373
|
-
}
|
1818
|
+
var resolve = once(function (resolvedDef) {
|
1819
|
+
match.components[key] = resolvedDef;
|
1820
|
+
next();
|
1821
|
+
});
|
1374
1822
|
|
1375
|
-
var reject = function (reason) {
|
1376
|
-
warn(false, ("Failed to resolve async component " + key + ": " + reason))
|
1377
|
-
next(false)
|
1378
|
-
}
|
1823
|
+
var reject = once(function (reason) {
|
1824
|
+
warn(false, ("Failed to resolve async component " + key + ": " + reason));
|
1825
|
+
next(false);
|
1826
|
+
});
|
1379
1827
|
|
1380
|
-
var res = def(resolve, reject)
|
1828
|
+
var res = def(resolve, reject);
|
1381
1829
|
if (res && typeof res.then === 'function') {
|
1382
|
-
res.then(resolve, reject)
|
1830
|
+
res.then(resolve, reject);
|
1383
1831
|
}
|
1384
1832
|
}
|
1385
1833
|
}
|
@@ -1390,7 +1838,7 @@ function flatMapComponents (
|
|
1390
1838
|
matched,
|
1391
1839
|
fn
|
1392
1840
|
) {
|
1393
|
-
return
|
1841
|
+
return flatten(matched.map(function (m) {
|
1394
1842
|
return Object.keys(m.components).map(function (key) { return fn(
|
1395
1843
|
m.components[key],
|
1396
1844
|
m.instances[key],
|
@@ -1399,321 +1847,249 @@ function flatMapComponents (
|
|
1399
1847
|
}))
|
1400
1848
|
}
|
1401
1849
|
|
1402
|
-
|
1403
|
-
|
1404
|
-
function saveScrollPosition (key) {
|
1405
|
-
if (!key) { return }
|
1406
|
-
window.sessionStorage.setItem(key, JSON.stringify({
|
1407
|
-
x: window.pageXOffset,
|
1408
|
-
y: window.pageYOffset
|
1409
|
-
}))
|
1410
|
-
}
|
1411
|
-
|
1412
|
-
function getScrollPosition (key) {
|
1413
|
-
if (!key) { return }
|
1414
|
-
return JSON.parse(window.sessionStorage.getItem(key))
|
1415
|
-
}
|
1416
|
-
|
1417
|
-
function getElementPosition (el) {
|
1418
|
-
var docRect = document.documentElement.getBoundingClientRect()
|
1419
|
-
var elRect = el.getBoundingClientRect()
|
1420
|
-
return {
|
1421
|
-
x: elRect.left - docRect.left,
|
1422
|
-
y: elRect.top - docRect.top
|
1423
|
-
}
|
1424
|
-
}
|
1425
|
-
|
1426
|
-
function isValidPosition (obj) {
|
1427
|
-
return isNumber(obj.x) || isNumber(obj.y)
|
1850
|
+
function flatten (arr) {
|
1851
|
+
return Array.prototype.concat.apply([], arr)
|
1428
1852
|
}
|
1429
1853
|
|
1430
|
-
|
1431
|
-
|
1432
|
-
|
1433
|
-
|
1854
|
+
// in Webpack 2, require.ensure now also returns a Promise
|
1855
|
+
// so the resolve/reject functions may get called an extra time
|
1856
|
+
// if the user uses an arrow function shorthand that happens to
|
1857
|
+
// return that Promise.
|
1858
|
+
function once (fn) {
|
1859
|
+
var called = false;
|
1860
|
+
return function () {
|
1861
|
+
if (called) { return }
|
1862
|
+
called = true;
|
1863
|
+
return fn.apply(this, arguments)
|
1434
1864
|
}
|
1435
1865
|
}
|
1436
1866
|
|
1437
|
-
function isNumber (v) {
|
1438
|
-
return typeof v === 'number'
|
1439
|
-
}
|
1440
|
-
|
1441
1867
|
/* */
|
1442
1868
|
|
1443
1869
|
|
1444
|
-
var
|
1445
|
-
var _key = genKey()
|
1446
|
-
|
1447
|
-
var HTML5History = (function (History) {
|
1870
|
+
var HTML5History = (function (History$$1) {
|
1448
1871
|
function HTML5History (router, base) {
|
1449
1872
|
var this$1 = this;
|
1450
1873
|
|
1451
|
-
History.call(this, router, base)
|
1874
|
+
History$$1.call(this, router, base);
|
1875
|
+
|
1876
|
+
var expectScroll = router.options.scrollBehavior;
|
1452
1877
|
|
1453
|
-
|
1878
|
+
if (expectScroll) {
|
1879
|
+
setupScroll();
|
1880
|
+
}
|
1454
1881
|
|
1455
|
-
var expectScroll = router.options.scrollBehavior
|
1456
1882
|
window.addEventListener('popstate', function (e) {
|
1457
|
-
|
1458
|
-
var current = this$1.current
|
1459
|
-
this$1.transitionTo(getLocation(this$1.base), function (next) {
|
1883
|
+
this$1.transitionTo(getLocation(this$1.base), function (route) {
|
1460
1884
|
if (expectScroll) {
|
1461
|
-
this$1.
|
1885
|
+
handleScroll(router, route, this$1.current, true);
|
1462
1886
|
}
|
1463
|
-
})
|
1464
|
-
})
|
1465
|
-
|
1466
|
-
if (expectScroll) {
|
1467
|
-
window.addEventListener('scroll', function () {
|
1468
|
-
saveScrollPosition(_key)
|
1469
|
-
})
|
1470
|
-
}
|
1887
|
+
});
|
1888
|
+
});
|
1471
1889
|
}
|
1472
1890
|
|
1473
|
-
if ( History ) HTML5History.__proto__ = History;
|
1474
|
-
HTML5History.prototype = Object.create( History && History.prototype );
|
1891
|
+
if ( History$$1 ) HTML5History.__proto__ = History$$1;
|
1892
|
+
HTML5History.prototype = Object.create( History$$1 && History$$1.prototype );
|
1475
1893
|
HTML5History.prototype.constructor = HTML5History;
|
1476
1894
|
|
1477
1895
|
HTML5History.prototype.go = function go (n) {
|
1478
|
-
window.history.go(n)
|
1896
|
+
window.history.go(n);
|
1479
1897
|
};
|
1480
1898
|
|
1481
|
-
HTML5History.prototype.push = function push (location) {
|
1899
|
+
HTML5History.prototype.push = function push (location, onComplete, onAbort) {
|
1482
1900
|
var this$1 = this;
|
1483
1901
|
|
1484
|
-
var current = this.current
|
1485
1902
|
this.transitionTo(location, function (route) {
|
1486
|
-
pushState(cleanPath(this$1.base + route.fullPath))
|
1487
|
-
this$1.
|
1488
|
-
|
1903
|
+
pushState(cleanPath(this$1.base + route.fullPath));
|
1904
|
+
handleScroll(this$1.router, route, this$1.current, false);
|
1905
|
+
onComplete && onComplete(route);
|
1906
|
+
}, onAbort);
|
1489
1907
|
};
|
1490
1908
|
|
1491
|
-
HTML5History.prototype.replace = function replace (location) {
|
1909
|
+
HTML5History.prototype.replace = function replace (location, onComplete, onAbort) {
|
1492
1910
|
var this$1 = this;
|
1493
1911
|
|
1494
|
-
var current = this.current
|
1495
1912
|
this.transitionTo(location, function (route) {
|
1496
|
-
replaceState(cleanPath(this$1.base + route.fullPath))
|
1497
|
-
this$1.
|
1498
|
-
|
1913
|
+
replaceState(cleanPath(this$1.base + route.fullPath));
|
1914
|
+
handleScroll(this$1.router, route, this$1.current, false);
|
1915
|
+
onComplete && onComplete(route);
|
1916
|
+
}, onAbort);
|
1499
1917
|
};
|
1500
1918
|
|
1501
|
-
HTML5History.prototype.ensureURL = function ensureURL () {
|
1919
|
+
HTML5History.prototype.ensureURL = function ensureURL (push) {
|
1502
1920
|
if (getLocation(this.base) !== this.current.fullPath) {
|
1503
|
-
|
1921
|
+
var current = cleanPath(this.base + this.current.fullPath);
|
1922
|
+
push ? pushState(current) : replaceState(current);
|
1504
1923
|
}
|
1505
1924
|
};
|
1506
1925
|
|
1507
|
-
HTML5History.prototype.
|
1508
|
-
|
1509
|
-
if (!router.app) {
|
1510
|
-
return
|
1511
|
-
}
|
1512
|
-
|
1513
|
-
var behavior = router.options.scrollBehavior
|
1514
|
-
if (!behavior) {
|
1515
|
-
return
|
1516
|
-
}
|
1517
|
-
assert(typeof behavior === 'function', "scrollBehavior must be a function")
|
1518
|
-
|
1519
|
-
// wait until re-render finishes before scrolling
|
1520
|
-
router.app.$nextTick(function () {
|
1521
|
-
var position = getScrollPosition(_key)
|
1522
|
-
var shouldScroll = behavior(to, from, isPop ? position : null)
|
1523
|
-
if (!shouldScroll) {
|
1524
|
-
return
|
1525
|
-
}
|
1526
|
-
var isObject = typeof shouldScroll === 'object'
|
1527
|
-
if (isObject && typeof shouldScroll.selector === 'string') {
|
1528
|
-
var el = document.querySelector(shouldScroll.selector)
|
1529
|
-
if (el) {
|
1530
|
-
position = getElementPosition(el)
|
1531
|
-
} else if (isValidPosition(shouldScroll)) {
|
1532
|
-
position = normalizePosition(shouldScroll)
|
1533
|
-
}
|
1534
|
-
} else if (isObject && isValidPosition(shouldScroll)) {
|
1535
|
-
position = normalizePosition(shouldScroll)
|
1536
|
-
}
|
1537
|
-
|
1538
|
-
if (position) {
|
1539
|
-
window.scrollTo(position.x, position.y)
|
1540
|
-
}
|
1541
|
-
})
|
1926
|
+
HTML5History.prototype.getCurrentLocation = function getCurrentLocation () {
|
1927
|
+
return getLocation(this.base)
|
1542
1928
|
};
|
1543
1929
|
|
1544
1930
|
return HTML5History;
|
1545
1931
|
}(History));
|
1546
1932
|
|
1547
1933
|
function getLocation (base) {
|
1548
|
-
var path = window.location.pathname
|
1934
|
+
var path = window.location.pathname;
|
1549
1935
|
if (base && path.indexOf(base) === 0) {
|
1550
|
-
path = path.slice(base.length)
|
1936
|
+
path = path.slice(base.length);
|
1551
1937
|
}
|
1552
1938
|
return (path || '/') + window.location.search + window.location.hash
|
1553
1939
|
}
|
1554
1940
|
|
1555
|
-
function pushState (url, replace) {
|
1556
|
-
// try...catch the pushState call to get around Safari
|
1557
|
-
// DOM Exception 18 where it limits to 100 pushState calls
|
1558
|
-
var history = window.history
|
1559
|
-
try {
|
1560
|
-
if (replace) {
|
1561
|
-
history.replaceState({ key: _key }, '', url)
|
1562
|
-
} else {
|
1563
|
-
_key = genKey()
|
1564
|
-
history.pushState({ key: _key }, '', url)
|
1565
|
-
}
|
1566
|
-
saveScrollPosition(_key)
|
1567
|
-
} catch (e) {
|
1568
|
-
window.location[replace ? 'assign' : 'replace'](url)
|
1569
|
-
}
|
1570
|
-
}
|
1571
|
-
|
1572
|
-
function replaceState (url) {
|
1573
|
-
pushState(url, true)
|
1574
|
-
}
|
1575
|
-
|
1576
1941
|
/* */
|
1577
1942
|
|
1578
1943
|
|
1579
|
-
var HashHistory = (function (History) {
|
1944
|
+
var HashHistory = (function (History$$1) {
|
1580
1945
|
function HashHistory (router, base, fallback) {
|
1581
|
-
|
1582
|
-
|
1583
|
-
History.call(this, router, base)
|
1584
|
-
|
1946
|
+
History$$1.call(this, router, base);
|
1585
1947
|
// check history fallback deeplinking
|
1586
|
-
if (fallback && this.
|
1948
|
+
if (fallback && checkFallback(this.base)) {
|
1587
1949
|
return
|
1588
1950
|
}
|
1589
|
-
|
1590
|
-
ensureSlash()
|
1591
|
-
this.transitionTo(getHash())
|
1592
|
-
|
1593
|
-
window.addEventListener('hashchange', function () {
|
1594
|
-
this$1.onHashChange()
|
1595
|
-
})
|
1951
|
+
ensureSlash();
|
1596
1952
|
}
|
1597
1953
|
|
1598
|
-
if ( History ) HashHistory.__proto__ = History;
|
1599
|
-
HashHistory.prototype = Object.create( History && History.prototype );
|
1954
|
+
if ( History$$1 ) HashHistory.__proto__ = History$$1;
|
1955
|
+
HashHistory.prototype = Object.create( History$$1 && History$$1.prototype );
|
1600
1956
|
HashHistory.prototype.constructor = HashHistory;
|
1601
1957
|
|
1602
|
-
|
1603
|
-
|
1604
|
-
|
1605
|
-
|
1606
|
-
cleanPath(this.base + '/#' + location)
|
1607
|
-
)
|
1608
|
-
return true
|
1609
|
-
}
|
1610
|
-
};
|
1958
|
+
// this is delayed until the app mounts
|
1959
|
+
// to avoid the hashchange listener being fired too early
|
1960
|
+
HashHistory.prototype.setupListeners = function setupListeners () {
|
1961
|
+
var this$1 = this;
|
1611
1962
|
|
1612
|
-
|
1613
|
-
|
1614
|
-
|
1615
|
-
|
1616
|
-
|
1617
|
-
|
1618
|
-
|
1963
|
+
window.addEventListener('hashchange', function () {
|
1964
|
+
if (!ensureSlash()) {
|
1965
|
+
return
|
1966
|
+
}
|
1967
|
+
this$1.transitionTo(getHash(), function (route) {
|
1968
|
+
replaceHash(route.fullPath);
|
1969
|
+
});
|
1970
|
+
});
|
1619
1971
|
};
|
1620
1972
|
|
1621
|
-
HashHistory.prototype.push = function push (location) {
|
1622
|
-
|
1623
|
-
pushHash(route.fullPath)
|
1624
|
-
|
1973
|
+
HashHistory.prototype.push = function push (location, onComplete, onAbort) {
|
1974
|
+
this.transitionTo(location, function (route) {
|
1975
|
+
pushHash(route.fullPath);
|
1976
|
+
onComplete && onComplete(route);
|
1977
|
+
}, onAbort);
|
1625
1978
|
};
|
1626
1979
|
|
1627
|
-
HashHistory.prototype.replace = function replace (location) {
|
1628
|
-
|
1629
|
-
replaceHash(route.fullPath)
|
1630
|
-
|
1980
|
+
HashHistory.prototype.replace = function replace (location, onComplete, onAbort) {
|
1981
|
+
this.transitionTo(location, function (route) {
|
1982
|
+
replaceHash(route.fullPath);
|
1983
|
+
onComplete && onComplete(route);
|
1984
|
+
}, onAbort);
|
1631
1985
|
};
|
1632
1986
|
|
1633
1987
|
HashHistory.prototype.go = function go (n) {
|
1634
|
-
window.history.go(n)
|
1988
|
+
window.history.go(n);
|
1635
1989
|
};
|
1636
1990
|
|
1637
|
-
HashHistory.prototype.ensureURL = function ensureURL () {
|
1638
|
-
|
1639
|
-
|
1991
|
+
HashHistory.prototype.ensureURL = function ensureURL (push) {
|
1992
|
+
var current = this.current.fullPath;
|
1993
|
+
if (getHash() !== current) {
|
1994
|
+
push ? pushHash(current) : replaceHash(current);
|
1640
1995
|
}
|
1641
1996
|
};
|
1642
1997
|
|
1998
|
+
HashHistory.prototype.getCurrentLocation = function getCurrentLocation () {
|
1999
|
+
return getHash()
|
2000
|
+
};
|
2001
|
+
|
1643
2002
|
return HashHistory;
|
1644
2003
|
}(History));
|
1645
2004
|
|
2005
|
+
function checkFallback (base) {
|
2006
|
+
var location = getLocation(base);
|
2007
|
+
if (!/^\/#/.test(location)) {
|
2008
|
+
window.location.replace(
|
2009
|
+
cleanPath(base + '/#' + location)
|
2010
|
+
);
|
2011
|
+
return true
|
2012
|
+
}
|
2013
|
+
}
|
2014
|
+
|
1646
2015
|
function ensureSlash () {
|
1647
|
-
var path = getHash()
|
2016
|
+
var path = getHash();
|
1648
2017
|
if (path.charAt(0) === '/') {
|
1649
2018
|
return true
|
1650
2019
|
}
|
1651
|
-
replaceHash('/' + path)
|
2020
|
+
replaceHash('/' + path);
|
1652
2021
|
return false
|
1653
2022
|
}
|
1654
2023
|
|
1655
2024
|
function getHash () {
|
1656
2025
|
// We can't use window.location.hash here because it's not
|
1657
2026
|
// consistent across browsers - Firefox will pre-decode it!
|
1658
|
-
var href = window.location.href
|
1659
|
-
var index = href.indexOf('#')
|
2027
|
+
var href = window.location.href;
|
2028
|
+
var index = href.indexOf('#');
|
1660
2029
|
return index === -1 ? '' : href.slice(index + 1)
|
1661
2030
|
}
|
1662
2031
|
|
1663
2032
|
function pushHash (path) {
|
1664
|
-
window.location.hash = path
|
2033
|
+
window.location.hash = path;
|
1665
2034
|
}
|
1666
2035
|
|
1667
2036
|
function replaceHash (path) {
|
1668
|
-
var i = window.location.href.indexOf('#')
|
2037
|
+
var i = window.location.href.indexOf('#');
|
1669
2038
|
window.location.replace(
|
1670
2039
|
window.location.href.slice(0, i >= 0 ? i : 0) + '#' + path
|
1671
|
-
)
|
2040
|
+
);
|
1672
2041
|
}
|
1673
2042
|
|
1674
2043
|
/* */
|
1675
2044
|
|
1676
2045
|
|
1677
|
-
var AbstractHistory = (function (History) {
|
1678
|
-
function AbstractHistory (router) {
|
1679
|
-
History.call(this, router)
|
1680
|
-
this.stack = []
|
1681
|
-
this.index =
|
2046
|
+
var AbstractHistory = (function (History$$1) {
|
2047
|
+
function AbstractHistory (router, base) {
|
2048
|
+
History$$1.call(this, router, base);
|
2049
|
+
this.stack = [];
|
2050
|
+
this.index = -1;
|
1682
2051
|
}
|
1683
2052
|
|
1684
|
-
if ( History ) AbstractHistory.__proto__ = History;
|
1685
|
-
AbstractHistory.prototype = Object.create( History && History.prototype );
|
2053
|
+
if ( History$$1 ) AbstractHistory.__proto__ = History$$1;
|
2054
|
+
AbstractHistory.prototype = Object.create( History$$1 && History$$1.prototype );
|
1686
2055
|
AbstractHistory.prototype.constructor = AbstractHistory;
|
1687
2056
|
|
1688
|
-
AbstractHistory.prototype.push = function push (location) {
|
2057
|
+
AbstractHistory.prototype.push = function push (location, onComplete, onAbort) {
|
1689
2058
|
var this$1 = this;
|
1690
2059
|
|
1691
|
-
|
1692
|
-
this$1.stack = this$1.stack.slice(0, this$1.index + 1).concat(route)
|
1693
|
-
this$1.index
|
1694
|
-
|
2060
|
+
this.transitionTo(location, function (route) {
|
2061
|
+
this$1.stack = this$1.stack.slice(0, this$1.index + 1).concat(route);
|
2062
|
+
this$1.index++;
|
2063
|
+
onComplete && onComplete(route);
|
2064
|
+
}, onAbort);
|
1695
2065
|
};
|
1696
2066
|
|
1697
|
-
AbstractHistory.prototype.replace = function replace (location) {
|
2067
|
+
AbstractHistory.prototype.replace = function replace (location, onComplete, onAbort) {
|
1698
2068
|
var this$1 = this;
|
1699
2069
|
|
1700
|
-
|
1701
|
-
this$1.stack = this$1.stack.slice(0, this$1.index).concat(route)
|
1702
|
-
|
2070
|
+
this.transitionTo(location, function (route) {
|
2071
|
+
this$1.stack = this$1.stack.slice(0, this$1.index).concat(route);
|
2072
|
+
onComplete && onComplete(route);
|
2073
|
+
}, onAbort);
|
1703
2074
|
};
|
1704
2075
|
|
1705
2076
|
AbstractHistory.prototype.go = function go (n) {
|
1706
2077
|
var this$1 = this;
|
1707
2078
|
|
1708
|
-
var targetIndex = this.index + n
|
2079
|
+
var targetIndex = this.index + n;
|
1709
2080
|
if (targetIndex < 0 || targetIndex >= this.stack.length) {
|
1710
2081
|
return
|
1711
2082
|
}
|
1712
|
-
var
|
1713
|
-
this.confirmTransition(
|
1714
|
-
this$1.index = targetIndex
|
1715
|
-
this$1.updateRoute(
|
1716
|
-
})
|
2083
|
+
var route = this.stack[targetIndex];
|
2084
|
+
this.confirmTransition(route, function () {
|
2085
|
+
this$1.index = targetIndex;
|
2086
|
+
this$1.updateRoute(route);
|
2087
|
+
});
|
2088
|
+
};
|
2089
|
+
|
2090
|
+
AbstractHistory.prototype.getCurrentLocation = function getCurrentLocation () {
|
2091
|
+
var current = this.stack[this.stack.length - 1];
|
2092
|
+
return current ? current.fullPath : '/'
|
1717
2093
|
};
|
1718
2094
|
|
1719
2095
|
AbstractHistory.prototype.ensureURL = function ensureURL () {
|
@@ -1728,25 +2104,50 @@ var AbstractHistory = (function (History) {
|
|
1728
2104
|
var VueRouter = function VueRouter (options) {
|
1729
2105
|
if ( options === void 0 ) options = {};
|
1730
2106
|
|
1731
|
-
this.app = null
|
1732
|
-
this.
|
1733
|
-
this.
|
1734
|
-
this.
|
1735
|
-
this.
|
2107
|
+
this.app = null;
|
2108
|
+
this.apps = [];
|
2109
|
+
this.options = options;
|
2110
|
+
this.beforeHooks = [];
|
2111
|
+
this.afterHooks = [];
|
2112
|
+
this.matcher = createMatcher(options.routes || []);
|
1736
2113
|
|
1737
|
-
var mode = options.mode || 'hash'
|
1738
|
-
this.fallback = mode === 'history' && !
|
2114
|
+
var mode = options.mode || 'hash';
|
2115
|
+
this.fallback = mode === 'history' && !supportsPushState;
|
1739
2116
|
if (this.fallback) {
|
1740
|
-
mode = 'hash'
|
2117
|
+
mode = 'hash';
|
1741
2118
|
}
|
1742
2119
|
if (!inBrowser) {
|
1743
|
-
mode = 'abstract'
|
2120
|
+
mode = 'abstract';
|
2121
|
+
}
|
2122
|
+
this.mode = mode;
|
2123
|
+
|
2124
|
+
switch (mode) {
|
2125
|
+
case 'history':
|
2126
|
+
this.history = new HTML5History(this, options.base);
|
2127
|
+
break
|
2128
|
+
case 'hash':
|
2129
|
+
this.history = new HashHistory(this, options.base, this.fallback);
|
2130
|
+
break
|
2131
|
+
case 'abstract':
|
2132
|
+
this.history = new AbstractHistory(this, options.base);
|
2133
|
+
break
|
2134
|
+
default:
|
2135
|
+
{
|
2136
|
+
assert(false, ("invalid mode: " + mode));
|
2137
|
+
}
|
1744
2138
|
}
|
1745
|
-
this.mode = mode
|
1746
2139
|
};
|
1747
2140
|
|
1748
2141
|
var prototypeAccessors = { currentRoute: {} };
|
1749
2142
|
|
2143
|
+
VueRouter.prototype.match = function match (
|
2144
|
+
raw,
|
2145
|
+
current,
|
2146
|
+
redirectedFrom
|
2147
|
+
) {
|
2148
|
+
return this.matcher.match(raw, current, redirectedFrom)
|
2149
|
+
};
|
2150
|
+
|
1750
2151
|
prototypeAccessors.currentRoute.get = function () {
|
1751
2152
|
return this.history && this.history.current
|
1752
2153
|
};
|
@@ -1754,82 +2155,128 @@ prototypeAccessors.currentRoute.get = function () {
|
|
1754
2155
|
VueRouter.prototype.init = function init (app /* Vue component instance */) {
|
1755
2156
|
var this$1 = this;
|
1756
2157
|
|
1757
|
-
assert(
|
2158
|
+
"development" !== 'production' && assert(
|
1758
2159
|
install.installed,
|
1759
2160
|
"not installed. Make sure to call `Vue.use(VueRouter)` " +
|
1760
2161
|
"before creating root instance."
|
1761
|
-
)
|
2162
|
+
);
|
1762
2163
|
|
1763
|
-
this.app
|
2164
|
+
this.apps.push(app);
|
1764
2165
|
|
1765
|
-
|
1766
|
-
|
1767
|
-
|
1768
|
-
var fallback = ref.fallback;
|
1769
|
-
switch (mode) {
|
1770
|
-
case 'history':
|
1771
|
-
this.history = new HTML5History(this, options.base)
|
1772
|
-
break
|
1773
|
-
case 'hash':
|
1774
|
-
this.history = new HashHistory(this, options.base, fallback)
|
1775
|
-
break
|
1776
|
-
case 'abstract':
|
1777
|
-
this.history = new AbstractHistory(this)
|
1778
|
-
break
|
1779
|
-
default:
|
1780
|
-
assert(false, ("invalid mode: " + mode))
|
2166
|
+
// main app already initialized.
|
2167
|
+
if (this.app) {
|
2168
|
+
return
|
1781
2169
|
}
|
1782
2170
|
|
1783
|
-
this.
|
1784
|
-
|
1785
|
-
|
2171
|
+
this.app = app;
|
2172
|
+
|
2173
|
+
var history = this.history;
|
2174
|
+
|
2175
|
+
if (history instanceof HTML5History) {
|
2176
|
+
history.transitionTo(history.getCurrentLocation());
|
2177
|
+
} else if (history instanceof HashHistory) {
|
2178
|
+
var setupHashListener = function () {
|
2179
|
+
history.setupListeners();
|
2180
|
+
};
|
2181
|
+
history.transitionTo(
|
2182
|
+
history.getCurrentLocation(),
|
2183
|
+
setupHashListener,
|
2184
|
+
setupHashListener
|
2185
|
+
);
|
2186
|
+
}
|
2187
|
+
|
2188
|
+
history.listen(function (route) {
|
2189
|
+
this$1.apps.forEach(function (app) {
|
2190
|
+
app._route = route;
|
2191
|
+
});
|
2192
|
+
});
|
1786
2193
|
};
|
1787
2194
|
|
1788
2195
|
VueRouter.prototype.beforeEach = function beforeEach (fn) {
|
1789
|
-
this.beforeHooks.push(fn)
|
2196
|
+
this.beforeHooks.push(fn);
|
1790
2197
|
};
|
1791
2198
|
|
1792
2199
|
VueRouter.prototype.afterEach = function afterEach (fn) {
|
1793
|
-
this.afterHooks.push(fn)
|
2200
|
+
this.afterHooks.push(fn);
|
1794
2201
|
};
|
1795
2202
|
|
1796
|
-
VueRouter.prototype.
|
1797
|
-
this.history.
|
2203
|
+
VueRouter.prototype.onReady = function onReady (cb) {
|
2204
|
+
this.history.onReady(cb);
|
1798
2205
|
};
|
1799
2206
|
|
1800
|
-
VueRouter.prototype.
|
1801
|
-
this.history.
|
2207
|
+
VueRouter.prototype.push = function push (location, onComplete, onAbort) {
|
2208
|
+
this.history.push(location, onComplete, onAbort);
|
2209
|
+
};
|
2210
|
+
|
2211
|
+
VueRouter.prototype.replace = function replace (location, onComplete, onAbort) {
|
2212
|
+
this.history.replace(location, onComplete, onAbort);
|
1802
2213
|
};
|
1803
2214
|
|
1804
2215
|
VueRouter.prototype.go = function go (n) {
|
1805
|
-
this.history.go(n)
|
2216
|
+
this.history.go(n);
|
1806
2217
|
};
|
1807
2218
|
|
1808
2219
|
VueRouter.prototype.back = function back () {
|
1809
|
-
this.go(-1)
|
2220
|
+
this.go(-1);
|
1810
2221
|
};
|
1811
2222
|
|
1812
2223
|
VueRouter.prototype.forward = function forward () {
|
1813
|
-
this.go(1)
|
2224
|
+
this.go(1);
|
1814
2225
|
};
|
1815
2226
|
|
1816
|
-
VueRouter.prototype.getMatchedComponents = function getMatchedComponents () {
|
1817
|
-
|
2227
|
+
VueRouter.prototype.getMatchedComponents = function getMatchedComponents (to) {
|
2228
|
+
var route = to
|
2229
|
+
? this.resolve(to).route
|
2230
|
+
: this.currentRoute;
|
2231
|
+
if (!route) {
|
1818
2232
|
return []
|
1819
2233
|
}
|
1820
|
-
return [].concat.apply([],
|
2234
|
+
return [].concat.apply([], route.matched.map(function (m) {
|
1821
2235
|
return Object.keys(m.components).map(function (key) {
|
1822
2236
|
return m.components[key]
|
1823
2237
|
})
|
1824
2238
|
}))
|
1825
2239
|
};
|
1826
2240
|
|
2241
|
+
VueRouter.prototype.resolve = function resolve (
|
2242
|
+
to,
|
2243
|
+
current,
|
2244
|
+
append
|
2245
|
+
) {
|
2246
|
+
var location = normalizeLocation(to, current || this.history.current, append);
|
2247
|
+
var route = this.match(location, current);
|
2248
|
+
var fullPath = route.redirectedFrom || route.fullPath;
|
2249
|
+
var base = this.history.base;
|
2250
|
+
var href = createHref(base, fullPath, this.mode);
|
2251
|
+
return {
|
2252
|
+
location: location,
|
2253
|
+
route: route,
|
2254
|
+
href: href,
|
2255
|
+
// for backwards compat
|
2256
|
+
normalizedTo: location,
|
2257
|
+
resolved: route
|
2258
|
+
}
|
2259
|
+
};
|
2260
|
+
|
2261
|
+
VueRouter.prototype.addRoutes = function addRoutes (routes) {
|
2262
|
+
this.matcher.addRoutes(routes);
|
2263
|
+
if (this.history.current !== START) {
|
2264
|
+
this.history.transitionTo(this.history.getCurrentLocation());
|
2265
|
+
}
|
2266
|
+
};
|
2267
|
+
|
1827
2268
|
Object.defineProperties( VueRouter.prototype, prototypeAccessors );
|
1828
2269
|
|
1829
|
-
|
2270
|
+
function createHref (base, fullPath, mode) {
|
2271
|
+
var path = mode === 'hash' ? '#' + fullPath : fullPath;
|
2272
|
+
return base ? cleanPath(base + '/' + path) : path
|
2273
|
+
}
|
2274
|
+
|
2275
|
+
VueRouter.install = install;
|
2276
|
+
VueRouter.version = '2.2.1';
|
1830
2277
|
|
1831
2278
|
if (inBrowser && window.Vue) {
|
1832
|
-
window.Vue.use(VueRouter)
|
2279
|
+
window.Vue.use(VueRouter);
|
1833
2280
|
}
|
1834
2281
|
|
1835
2282
|
return VueRouter;
|