vue-rails 2.0.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 +7 -0
- data/.gitignore +9 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +21 -0
- data/Rakefile +2 -0
- data/lib/vue-rails.rb +10 -0
- data/lib/vue-rails/version.rb +5 -0
- data/vendor/assets/javascripts/vue-router.js +1837 -0
- data/vendor/assets/javascripts/vue.js +7402 -0
- data/vue-rails.gemspec +22 -0
- metadata +54 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 61f65e26d38612013d7699898c3971a32c35a274
|
4
|
+
data.tar.gz: 078a81995f3701e0c0da23a56f4c8b5d61d6e97d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 37adf5af8a236db647fa6b2b5e02d1e91b42d9aa7ca454fdfd45027d9812ae748a2ecd073e7d88026e6032b8c31745b869fc5d3d675d4eb5511cd41d0769215c
|
7
|
+
data.tar.gz: 7cbedbb142186debffad0bcd7c36b336e1b811a1e451474916d6f7a95894872848a40b9d2f53c302ad68024ca30798a80de2304f8c225ab10ddb3bb78a8ee64d
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Marshall Shen
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# vue-rails
|
2
|
+
|
3
|
+
## About
|
4
|
+
|
5
|
+
Rails 4+ asset-pipeline gem to provide vue.js
|
6
|
+
|
7
|
+
## Versions
|
8
|
+
|
9
|
+
- vue v2.0.1
|
10
|
+
- vue-router v2.0.0
|
11
|
+
|
12
|
+
## Setup
|
13
|
+
|
14
|
+
Have in your Gemfile:
|
15
|
+
|
16
|
+
gem 'vue-rails'
|
17
|
+
|
18
|
+
And in your application.js manifest:
|
19
|
+
|
20
|
+
//= require vue
|
21
|
+
//= require vue-router (optional)
|
data/Rakefile
ADDED
data/lib/vue-rails.rb
ADDED
@@ -0,0 +1,1837 @@
|
|
1
|
+
/**
|
2
|
+
* vue-router v2.0.0
|
3
|
+
* (c) 2016 Evan You
|
4
|
+
* @license MIT
|
5
|
+
*/
|
6
|
+
(function (global, factory) {
|
7
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
8
|
+
typeof define === 'function' && define.amd ? define(factory) :
|
9
|
+
(global.VueRouter = factory());
|
10
|
+
}(this, (function () { 'use strict';
|
11
|
+
|
12
|
+
var View = {
|
13
|
+
name: 'router-view',
|
14
|
+
functional: true,
|
15
|
+
props: {
|
16
|
+
name: {
|
17
|
+
type: String,
|
18
|
+
default: 'default'
|
19
|
+
}
|
20
|
+
},
|
21
|
+
render: function render (h, ref) {
|
22
|
+
var props = ref.props;
|
23
|
+
var children = ref.children;
|
24
|
+
var parent = ref.parent;
|
25
|
+
var data = ref.data;
|
26
|
+
|
27
|
+
data.routerView = true
|
28
|
+
|
29
|
+
var route = parent.$route
|
30
|
+
var cache = parent._routerViewCache || (parent._routerViewCache = {})
|
31
|
+
var depth = 0
|
32
|
+
var inactive = false
|
33
|
+
|
34
|
+
while (parent) {
|
35
|
+
if (parent.$vnode && parent.$vnode.data.routerView) {
|
36
|
+
depth++
|
37
|
+
}
|
38
|
+
if (parent._inactive) {
|
39
|
+
inactive = true
|
40
|
+
}
|
41
|
+
parent = parent.$parent
|
42
|
+
}
|
43
|
+
|
44
|
+
data.routerViewDepth = depth
|
45
|
+
var matched = route.matched[depth]
|
46
|
+
if (!matched) {
|
47
|
+
return h()
|
48
|
+
}
|
49
|
+
|
50
|
+
var component = inactive
|
51
|
+
? cache[props.name]
|
52
|
+
: (cache[props.name] = matched.components[props.name])
|
53
|
+
|
54
|
+
if (!inactive) {
|
55
|
+
(data.hook || (data.hook = {})).init = function (vnode) {
|
56
|
+
matched.instances[props.name] = vnode.child
|
57
|
+
}
|
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
|
+
}
|
108
|
+
|
109
|
+
function parsePath (path) {
|
110
|
+
var hash = ''
|
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
|
+
}
|
118
|
+
|
119
|
+
var queryIndex = path.indexOf('?')
|
120
|
+
if (queryIndex >= 0) {
|
121
|
+
query = path.slice(queryIndex + 1)
|
122
|
+
path = path.slice(0, queryIndex)
|
123
|
+
}
|
124
|
+
|
125
|
+
return {
|
126
|
+
path: path,
|
127
|
+
query: query,
|
128
|
+
hash: hash
|
129
|
+
}
|
130
|
+
}
|
131
|
+
|
132
|
+
function cleanPath (path) {
|
133
|
+
return path.replace(/\/\//g, '/')
|
134
|
+
}
|
135
|
+
|
136
|
+
/* */
|
137
|
+
|
138
|
+
function assert (condition, message) {
|
139
|
+
if (!condition) {
|
140
|
+
throw new Error(("[vue-router] " + message))
|
141
|
+
}
|
142
|
+
}
|
143
|
+
|
144
|
+
function warn (condition, message) {
|
145
|
+
if (!condition) {
|
146
|
+
typeof console !== 'undefined' && console.warn(("[vue-router] " + message))
|
147
|
+
}
|
148
|
+
}
|
149
|
+
|
150
|
+
/* */
|
151
|
+
|
152
|
+
var encode = encodeURIComponent
|
153
|
+
var decode = decodeURIComponent
|
154
|
+
|
155
|
+
function resolveQuery (
|
156
|
+
query,
|
157
|
+
extraQuery
|
158
|
+
) {
|
159
|
+
if ( extraQuery === void 0 ) extraQuery = {};
|
160
|
+
|
161
|
+
if (query) {
|
162
|
+
var parsedQuery
|
163
|
+
try {
|
164
|
+
parsedQuery = parseQuery(query)
|
165
|
+
} catch (e) {
|
166
|
+
warn(false, e.message)
|
167
|
+
parsedQuery = {}
|
168
|
+
}
|
169
|
+
for (var key in extraQuery) {
|
170
|
+
parsedQuery[key] = extraQuery[key]
|
171
|
+
}
|
172
|
+
return parsedQuery
|
173
|
+
} else {
|
174
|
+
return extraQuery
|
175
|
+
}
|
176
|
+
}
|
177
|
+
|
178
|
+
function parseQuery (query) {
|
179
|
+
var res = Object.create(null)
|
180
|
+
|
181
|
+
query = query.trim().replace(/^(\?|#|&)/, '')
|
182
|
+
|
183
|
+
if (!query) {
|
184
|
+
return res
|
185
|
+
}
|
186
|
+
|
187
|
+
query.split('&').forEach(function (param) {
|
188
|
+
var parts = param.replace(/\+/g, ' ').split('=')
|
189
|
+
var key = decode(parts.shift())
|
190
|
+
var val = parts.length > 0
|
191
|
+
? decode(parts.join('='))
|
192
|
+
: null
|
193
|
+
|
194
|
+
if (res[key] === undefined) {
|
195
|
+
res[key] = val
|
196
|
+
} else if (Array.isArray(res[key])) {
|
197
|
+
res[key].push(val)
|
198
|
+
} else {
|
199
|
+
res[key] = [res[key], val]
|
200
|
+
}
|
201
|
+
})
|
202
|
+
|
203
|
+
return res
|
204
|
+
}
|
205
|
+
|
206
|
+
function stringifyQuery (obj) {
|
207
|
+
var res = obj ? Object.keys(obj).sort().map(function (key) {
|
208
|
+
var val = obj[key]
|
209
|
+
|
210
|
+
if (val === undefined) {
|
211
|
+
return ''
|
212
|
+
}
|
213
|
+
|
214
|
+
if (val === null) {
|
215
|
+
return encode(key)
|
216
|
+
}
|
217
|
+
|
218
|
+
if (Array.isArray(val)) {
|
219
|
+
var result = []
|
220
|
+
val.slice().forEach(function (val2) {
|
221
|
+
if (val2 === undefined) {
|
222
|
+
return
|
223
|
+
}
|
224
|
+
if (val2 === null) {
|
225
|
+
result.push(encode(key))
|
226
|
+
} else {
|
227
|
+
result.push(encode(key) + '=' + encode(val2))
|
228
|
+
}
|
229
|
+
})
|
230
|
+
return result.join('&')
|
231
|
+
}
|
232
|
+
|
233
|
+
return encode(key) + '=' + encode(val)
|
234
|
+
}).filter(function (x) { return x.length > 0; }).join('&') : null
|
235
|
+
return res ? ("?" + res) : ''
|
236
|
+
}
|
237
|
+
|
238
|
+
/* */
|
239
|
+
|
240
|
+
function createRoute (
|
241
|
+
record,
|
242
|
+
location,
|
243
|
+
redirectedFrom
|
244
|
+
) {
|
245
|
+
var route = {
|
246
|
+
name: location.name || (record && record.name),
|
247
|
+
meta: (record && record.meta) || {},
|
248
|
+
path: location.path || '/',
|
249
|
+
hash: location.hash || '',
|
250
|
+
query: location.query || {},
|
251
|
+
params: location.params || {},
|
252
|
+
fullPath: getFullPath(location),
|
253
|
+
matched: record ? formatMatch(record) : []
|
254
|
+
}
|
255
|
+
if (redirectedFrom) {
|
256
|
+
route.redirectedFrom = getFullPath(redirectedFrom)
|
257
|
+
}
|
258
|
+
return Object.freeze(route)
|
259
|
+
}
|
260
|
+
|
261
|
+
// the starting route that represents the initial state
|
262
|
+
var START = createRoute(null, {
|
263
|
+
path: '/'
|
264
|
+
})
|
265
|
+
|
266
|
+
function formatMatch (record) {
|
267
|
+
var res = []
|
268
|
+
while (record) {
|
269
|
+
res.unshift(record)
|
270
|
+
record = record.parent
|
271
|
+
}
|
272
|
+
return res
|
273
|
+
}
|
274
|
+
|
275
|
+
function getFullPath (ref) {
|
276
|
+
var path = ref.path;
|
277
|
+
var query = ref.query; if ( query === void 0 ) query = {};
|
278
|
+
var hash = ref.hash; if ( hash === void 0 ) hash = '';
|
279
|
+
|
280
|
+
return (path || '/') + stringifyQuery(query) + hash
|
281
|
+
}
|
282
|
+
|
283
|
+
var trailingSlashRE = /\/$/
|
284
|
+
function isSameRoute (a, b) {
|
285
|
+
if (b === START) {
|
286
|
+
return a === b
|
287
|
+
} else if (!b) {
|
288
|
+
return false
|
289
|
+
} else if (a.path && b.path) {
|
290
|
+
return (
|
291
|
+
a.path.replace(trailingSlashRE, '') === b.path.replace(trailingSlashRE, '') &&
|
292
|
+
a.hash === b.hash &&
|
293
|
+
isObjectEqual(a.query, b.query)
|
294
|
+
)
|
295
|
+
} else if (a.name && b.name) {
|
296
|
+
return (
|
297
|
+
a.name === b.name &&
|
298
|
+
a.hash === b.hash &&
|
299
|
+
isObjectEqual(a.query, b.query) &&
|
300
|
+
isObjectEqual(a.params, b.params)
|
301
|
+
)
|
302
|
+
} else {
|
303
|
+
return false
|
304
|
+
}
|
305
|
+
}
|
306
|
+
|
307
|
+
function isObjectEqual (a, b) {
|
308
|
+
if ( a === void 0 ) a = {};
|
309
|
+
if ( b === void 0 ) b = {};
|
310
|
+
|
311
|
+
var aKeys = Object.keys(a)
|
312
|
+
var bKeys = Object.keys(b)
|
313
|
+
if (aKeys.length !== bKeys.length) {
|
314
|
+
return false
|
315
|
+
}
|
316
|
+
return aKeys.every(function (key) { return String(a[key]) === String(b[key]); })
|
317
|
+
}
|
318
|
+
|
319
|
+
function isIncludedRoute (current, target) {
|
320
|
+
return (
|
321
|
+
current.path.indexOf(target.path) === 0 &&
|
322
|
+
(!target.hash || current.hash === target.hash) &&
|
323
|
+
queryIncludes(current.query, target.query)
|
324
|
+
)
|
325
|
+
}
|
326
|
+
|
327
|
+
function queryIncludes (current, target) {
|
328
|
+
for (var key in target) {
|
329
|
+
if (!(key in current)) {
|
330
|
+
return false
|
331
|
+
}
|
332
|
+
}
|
333
|
+
return true
|
334
|
+
}
|
335
|
+
|
336
|
+
/* */
|
337
|
+
|
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
|
+
// work around weird flow bug
|
370
|
+
var toTypes = [String, Object]
|
371
|
+
|
372
|
+
var Link = {
|
373
|
+
name: 'router-link',
|
374
|
+
props: {
|
375
|
+
to: {
|
376
|
+
type: toTypes,
|
377
|
+
required: true
|
378
|
+
},
|
379
|
+
tag: {
|
380
|
+
type: String,
|
381
|
+
default: 'a'
|
382
|
+
},
|
383
|
+
exact: Boolean,
|
384
|
+
append: Boolean,
|
385
|
+
replace: Boolean,
|
386
|
+
activeClass: String
|
387
|
+
},
|
388
|
+
render: function render (h) {
|
389
|
+
var this$1 = this;
|
390
|
+
|
391
|
+
var router = this.$router
|
392
|
+
var current = this.$route
|
393
|
+
var to = normalizeLocation(this.to, current, this.append)
|
394
|
+
var resolved = router.match(to)
|
395
|
+
var fullPath = resolved.redirectedFrom || resolved.fullPath
|
396
|
+
var base = router.history.base
|
397
|
+
var href = base ? cleanPath(base + fullPath) : fullPath
|
398
|
+
var classes = {}
|
399
|
+
var activeClass = this.activeClass || router.options.linkActiveClass || 'router-link-active'
|
400
|
+
var compareTarget = to.path ? createRoute(null, to) : resolved
|
401
|
+
classes[activeClass] = this.exact
|
402
|
+
? isSameRoute(current, compareTarget)
|
403
|
+
: isIncludedRoute(current, compareTarget)
|
404
|
+
|
405
|
+
var on = {
|
406
|
+
click: function (e) {
|
407
|
+
e.preventDefault()
|
408
|
+
if (this$1.replace) {
|
409
|
+
router.replace(to)
|
410
|
+
} else {
|
411
|
+
router.push(to)
|
412
|
+
}
|
413
|
+
}
|
414
|
+
}
|
415
|
+
|
416
|
+
var data = {
|
417
|
+
class: classes
|
418
|
+
}
|
419
|
+
|
420
|
+
if (this.tag === 'a') {
|
421
|
+
data.on = on
|
422
|
+
data.attrs = { href: href }
|
423
|
+
} else {
|
424
|
+
// find the first <a> child and apply listener and href
|
425
|
+
var a = findAnchor(this.$slots.default)
|
426
|
+
if (a) {
|
427
|
+
var aData = a.data || (a.data = {})
|
428
|
+
aData.on = on
|
429
|
+
var aAttrs = aData.attrs || (aData.attrs = {})
|
430
|
+
aAttrs.href = href
|
431
|
+
}
|
432
|
+
}
|
433
|
+
|
434
|
+
return h(this.tag, data, this.$slots.default)
|
435
|
+
}
|
436
|
+
}
|
437
|
+
|
438
|
+
function findAnchor (children) {
|
439
|
+
if (children) {
|
440
|
+
var child
|
441
|
+
for (var i = 0; i < children.length; i++) {
|
442
|
+
child = children[i]
|
443
|
+
if (child.tag === 'a') {
|
444
|
+
return child
|
445
|
+
}
|
446
|
+
if (child.children && (child = findAnchor(child.children))) {
|
447
|
+
return child
|
448
|
+
}
|
449
|
+
}
|
450
|
+
}
|
451
|
+
}
|
452
|
+
|
453
|
+
function install (Vue) {
|
454
|
+
if (install.installed) { return }
|
455
|
+
install.installed = true
|
456
|
+
|
457
|
+
Object.defineProperty(Vue.prototype, '$router', {
|
458
|
+
get: function get () { return this.$root._router }
|
459
|
+
})
|
460
|
+
|
461
|
+
Object.defineProperty(Vue.prototype, '$route', {
|
462
|
+
get: function get$1 () { return this.$root._route }
|
463
|
+
})
|
464
|
+
|
465
|
+
Vue.mixin({
|
466
|
+
beforeCreate: function beforeCreate () {
|
467
|
+
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)
|
471
|
+
}
|
472
|
+
}
|
473
|
+
})
|
474
|
+
|
475
|
+
Vue.component('router-view', View)
|
476
|
+
Vue.component('router-link', Link)
|
477
|
+
}
|
478
|
+
|
479
|
+
var __moduleExports = Array.isArray || function (arr) {
|
480
|
+
return Object.prototype.toString.call(arr) == '[object Array]';
|
481
|
+
};
|
482
|
+
|
483
|
+
var isarray = __moduleExports
|
484
|
+
|
485
|
+
/**
|
486
|
+
* Expose `pathToRegexp`.
|
487
|
+
*/
|
488
|
+
var index = pathToRegexp
|
489
|
+
var parse_1 = parse
|
490
|
+
var compile_1 = compile
|
491
|
+
var tokensToFunction_1 = tokensToFunction
|
492
|
+
var tokensToRegExp_1 = tokensToRegExp
|
493
|
+
|
494
|
+
/**
|
495
|
+
* The main path matching regexp utility.
|
496
|
+
*
|
497
|
+
* @type {RegExp}
|
498
|
+
*/
|
499
|
+
var PATH_REGEXP = new RegExp([
|
500
|
+
// Match escaped characters that would otherwise appear in future matches.
|
501
|
+
// This allows the user to escape special characters that won't transform.
|
502
|
+
'(\\\\.)',
|
503
|
+
// Match Express-style parameters and un-named parameters with a prefix
|
504
|
+
// and optional suffixes. Matches appear as:
|
505
|
+
//
|
506
|
+
// "/:test(\\d+)?" => ["/", "test", "\d+", undefined, "?", undefined]
|
507
|
+
// "/route(\\d+)" => [undefined, undefined, undefined, "\d+", undefined, undefined]
|
508
|
+
// "/*" => ["/", undefined, undefined, undefined, undefined, "*"]
|
509
|
+
'([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))'
|
510
|
+
].join('|'), 'g')
|
511
|
+
|
512
|
+
/**
|
513
|
+
* Parse a string for the raw tokens.
|
514
|
+
*
|
515
|
+
* @param {string} str
|
516
|
+
* @return {!Array}
|
517
|
+
*/
|
518
|
+
function parse (str) {
|
519
|
+
var tokens = []
|
520
|
+
var key = 0
|
521
|
+
var index = 0
|
522
|
+
var path = ''
|
523
|
+
var res
|
524
|
+
|
525
|
+
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
|
531
|
+
|
532
|
+
// Ignore already escaped sequences.
|
533
|
+
if (escaped) {
|
534
|
+
path += escaped[1]
|
535
|
+
continue
|
536
|
+
}
|
537
|
+
|
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]
|
545
|
+
|
546
|
+
// Push the current path onto the tokens.
|
547
|
+
if (path) {
|
548
|
+
tokens.push(path)
|
549
|
+
path = ''
|
550
|
+
}
|
551
|
+
|
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 || (asterisk ? '.*' : '[^' + delimiter + ']+?')
|
557
|
+
|
558
|
+
tokens.push({
|
559
|
+
name: name || key++,
|
560
|
+
prefix: prefix || '',
|
561
|
+
delimiter: delimiter,
|
562
|
+
optional: optional,
|
563
|
+
repeat: repeat,
|
564
|
+
partial: partial,
|
565
|
+
asterisk: !!asterisk,
|
566
|
+
pattern: escapeGroup(pattern)
|
567
|
+
})
|
568
|
+
}
|
569
|
+
|
570
|
+
// Match any characters still remaining.
|
571
|
+
if (index < str.length) {
|
572
|
+
path += str.substr(index)
|
573
|
+
}
|
574
|
+
|
575
|
+
// If the path exists, push it onto the end.
|
576
|
+
if (path) {
|
577
|
+
tokens.push(path)
|
578
|
+
}
|
579
|
+
|
580
|
+
return tokens
|
581
|
+
}
|
582
|
+
|
583
|
+
/**
|
584
|
+
* Compile a string to a template function for the path.
|
585
|
+
*
|
586
|
+
* @param {string} str
|
587
|
+
* @return {!function(Object=, Object=)}
|
588
|
+
*/
|
589
|
+
function compile (str) {
|
590
|
+
return tokensToFunction(parse(str))
|
591
|
+
}
|
592
|
+
|
593
|
+
/**
|
594
|
+
* Prettier encoding of URI path segments.
|
595
|
+
*
|
596
|
+
* @param {string}
|
597
|
+
* @return {string}
|
598
|
+
*/
|
599
|
+
function encodeURIComponentPretty (str) {
|
600
|
+
return encodeURI(str).replace(/[\/?#]/g, function (c) {
|
601
|
+
return '%' + c.charCodeAt(0).toString(16).toUpperCase()
|
602
|
+
})
|
603
|
+
}
|
604
|
+
|
605
|
+
/**
|
606
|
+
* Encode the asterisk parameter. Similar to `pretty`, but allows slashes.
|
607
|
+
*
|
608
|
+
* @param {string}
|
609
|
+
* @return {string}
|
610
|
+
*/
|
611
|
+
function encodeAsterisk (str) {
|
612
|
+
return encodeURI(str).replace(/[?#]/g, function (c) {
|
613
|
+
return '%' + c.charCodeAt(0).toString(16).toUpperCase()
|
614
|
+
})
|
615
|
+
}
|
616
|
+
|
617
|
+
/**
|
618
|
+
* Expose a method for transforming tokens into the path function.
|
619
|
+
*/
|
620
|
+
function tokensToFunction (tokens) {
|
621
|
+
// Compile all the tokens into regexps.
|
622
|
+
var matches = new Array(tokens.length)
|
623
|
+
|
624
|
+
// Compile all the patterns before compilation.
|
625
|
+
for (var i = 0; i < tokens.length; i++) {
|
626
|
+
if (typeof tokens[i] === 'object') {
|
627
|
+
matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$')
|
628
|
+
}
|
629
|
+
}
|
630
|
+
|
631
|
+
return function (obj, opts) {
|
632
|
+
var path = ''
|
633
|
+
var data = obj || {}
|
634
|
+
var options = opts || {}
|
635
|
+
var encode = options.pretty ? encodeURIComponentPretty : encodeURIComponent
|
636
|
+
|
637
|
+
for (var i = 0; i < tokens.length; i++) {
|
638
|
+
var token = tokens[i]
|
639
|
+
|
640
|
+
if (typeof token === 'string') {
|
641
|
+
path += token
|
642
|
+
|
643
|
+
continue
|
644
|
+
}
|
645
|
+
|
646
|
+
var value = data[token.name]
|
647
|
+
var segment
|
648
|
+
|
649
|
+
if (value == null) {
|
650
|
+
if (token.optional) {
|
651
|
+
// Prepend partial segment prefixes.
|
652
|
+
if (token.partial) {
|
653
|
+
path += token.prefix
|
654
|
+
}
|
655
|
+
|
656
|
+
continue
|
657
|
+
} else {
|
658
|
+
throw new TypeError('Expected "' + token.name + '" to be defined')
|
659
|
+
}
|
660
|
+
}
|
661
|
+
|
662
|
+
if (isarray(value)) {
|
663
|
+
if (!token.repeat) {
|
664
|
+
throw new TypeError('Expected "' + token.name + '" to not repeat, but received `' + JSON.stringify(value) + '`')
|
665
|
+
}
|
666
|
+
|
667
|
+
if (value.length === 0) {
|
668
|
+
if (token.optional) {
|
669
|
+
continue
|
670
|
+
} else {
|
671
|
+
throw new TypeError('Expected "' + token.name + '" to not be empty')
|
672
|
+
}
|
673
|
+
}
|
674
|
+
|
675
|
+
for (var j = 0; j < value.length; j++) {
|
676
|
+
segment = encode(value[j])
|
677
|
+
|
678
|
+
if (!matches[i].test(segment)) {
|
679
|
+
throw new TypeError('Expected all "' + token.name + '" to match "' + token.pattern + '", but received `' + JSON.stringify(segment) + '`')
|
680
|
+
}
|
681
|
+
|
682
|
+
path += (j === 0 ? token.prefix : token.delimiter) + segment
|
683
|
+
}
|
684
|
+
|
685
|
+
continue
|
686
|
+
}
|
687
|
+
|
688
|
+
segment = token.asterisk ? encodeAsterisk(value) : encode(value)
|
689
|
+
|
690
|
+
if (!matches[i].test(segment)) {
|
691
|
+
throw new TypeError('Expected "' + token.name + '" to match "' + token.pattern + '", but received "' + segment + '"')
|
692
|
+
}
|
693
|
+
|
694
|
+
path += token.prefix + segment
|
695
|
+
}
|
696
|
+
|
697
|
+
return path
|
698
|
+
}
|
699
|
+
}
|
700
|
+
|
701
|
+
/**
|
702
|
+
* Escape a regular expression string.
|
703
|
+
*
|
704
|
+
* @param {string} str
|
705
|
+
* @return {string}
|
706
|
+
*/
|
707
|
+
function escapeString (str) {
|
708
|
+
return str.replace(/([.+*?=^!:${}()[\]|\/\\])/g, '\\$1')
|
709
|
+
}
|
710
|
+
|
711
|
+
/**
|
712
|
+
* Escape the capturing group by escaping special characters and meaning.
|
713
|
+
*
|
714
|
+
* @param {string} group
|
715
|
+
* @return {string}
|
716
|
+
*/
|
717
|
+
function escapeGroup (group) {
|
718
|
+
return group.replace(/([=!:$\/()])/g, '\\$1')
|
719
|
+
}
|
720
|
+
|
721
|
+
/**
|
722
|
+
* Attach the keys as a property of the regexp.
|
723
|
+
*
|
724
|
+
* @param {!RegExp} re
|
725
|
+
* @param {Array} keys
|
726
|
+
* @return {!RegExp}
|
727
|
+
*/
|
728
|
+
function attachKeys (re, keys) {
|
729
|
+
re.keys = keys
|
730
|
+
return re
|
731
|
+
}
|
732
|
+
|
733
|
+
/**
|
734
|
+
* Get the flags for a regexp from the options.
|
735
|
+
*
|
736
|
+
* @param {Object} options
|
737
|
+
* @return {string}
|
738
|
+
*/
|
739
|
+
function flags (options) {
|
740
|
+
return options.sensitive ? '' : 'i'
|
741
|
+
}
|
742
|
+
|
743
|
+
/**
|
744
|
+
* Pull out keys from a regexp.
|
745
|
+
*
|
746
|
+
* @param {!RegExp} path
|
747
|
+
* @param {!Array} keys
|
748
|
+
* @return {!RegExp}
|
749
|
+
*/
|
750
|
+
function regexpToRegexp (path, keys) {
|
751
|
+
// Use a negative lookahead to match only capturing groups.
|
752
|
+
var groups = path.source.match(/\((?!\?)/g)
|
753
|
+
|
754
|
+
if (groups) {
|
755
|
+
for (var i = 0; i < groups.length; i++) {
|
756
|
+
keys.push({
|
757
|
+
name: i,
|
758
|
+
prefix: null,
|
759
|
+
delimiter: null,
|
760
|
+
optional: false,
|
761
|
+
repeat: false,
|
762
|
+
partial: false,
|
763
|
+
asterisk: false,
|
764
|
+
pattern: null
|
765
|
+
})
|
766
|
+
}
|
767
|
+
}
|
768
|
+
|
769
|
+
return attachKeys(path, keys)
|
770
|
+
}
|
771
|
+
|
772
|
+
/**
|
773
|
+
* Transform an array into a regexp.
|
774
|
+
*
|
775
|
+
* @param {!Array} path
|
776
|
+
* @param {Array} keys
|
777
|
+
* @param {!Object} options
|
778
|
+
* @return {!RegExp}
|
779
|
+
*/
|
780
|
+
function arrayToRegexp (path, keys, options) {
|
781
|
+
var parts = []
|
782
|
+
|
783
|
+
for (var i = 0; i < path.length; i++) {
|
784
|
+
parts.push(pathToRegexp(path[i], keys, options).source)
|
785
|
+
}
|
786
|
+
|
787
|
+
var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options))
|
788
|
+
|
789
|
+
return attachKeys(regexp, keys)
|
790
|
+
}
|
791
|
+
|
792
|
+
/**
|
793
|
+
* Create a path regexp from string input.
|
794
|
+
*
|
795
|
+
* @param {string} path
|
796
|
+
* @param {!Array} keys
|
797
|
+
* @param {!Object} options
|
798
|
+
* @return {!RegExp}
|
799
|
+
*/
|
800
|
+
function stringToRegexp (path, keys, options) {
|
801
|
+
var tokens = parse(path)
|
802
|
+
var re = tokensToRegExp(tokens, options)
|
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
|
+
}
|
813
|
+
|
814
|
+
/**
|
815
|
+
* Expose a function for taking tokens and returning a RegExp.
|
816
|
+
*
|
817
|
+
* @param {!Array} tokens
|
818
|
+
* @param {Object=} options
|
819
|
+
* @return {!RegExp}
|
820
|
+
*/
|
821
|
+
function tokensToRegExp (tokens, options) {
|
822
|
+
options = options || {}
|
823
|
+
|
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)
|
829
|
+
|
830
|
+
// Iterate over the tokens and create our regexp string.
|
831
|
+
for (var i = 0; i < tokens.length; i++) {
|
832
|
+
var token = tokens[i]
|
833
|
+
|
834
|
+
if (typeof token === 'string') {
|
835
|
+
route += escapeString(token)
|
836
|
+
} else {
|
837
|
+
var prefix = escapeString(token.prefix)
|
838
|
+
var capture = '(?:' + token.pattern + ')'
|
839
|
+
|
840
|
+
if (token.repeat) {
|
841
|
+
capture += '(?:' + prefix + capture + ')*'
|
842
|
+
}
|
843
|
+
|
844
|
+
if (token.optional) {
|
845
|
+
if (!token.partial) {
|
846
|
+
capture = '(?:' + prefix + '(' + capture + '))?'
|
847
|
+
} else {
|
848
|
+
capture = prefix + '(' + capture + ')?'
|
849
|
+
}
|
850
|
+
} else {
|
851
|
+
capture = prefix + '(' + capture + ')'
|
852
|
+
}
|
853
|
+
|
854
|
+
route += capture
|
855
|
+
}
|
856
|
+
}
|
857
|
+
|
858
|
+
// In non-strict mode we allow a slash at the end of match. If the path to
|
859
|
+
// match already ends with a slash, we remove it for consistency. The slash
|
860
|
+
// is valid at the end of a path match, not in the middle. This is important
|
861
|
+
// in non-ending mode, where "/test/" shouldn't match "/test//route".
|
862
|
+
if (!strict) {
|
863
|
+
route = (endsWithSlash ? route.slice(0, -2) : route) + '(?:\\/(?=$))?'
|
864
|
+
}
|
865
|
+
|
866
|
+
if (end) {
|
867
|
+
route += '$'
|
868
|
+
} else {
|
869
|
+
// In non-ending mode, we need the capturing groups to match as much as
|
870
|
+
// possible by using a positive lookahead to the end or next path segment.
|
871
|
+
route += strict && endsWithSlash ? '' : '(?=\\/|$)'
|
872
|
+
}
|
873
|
+
|
874
|
+
return new RegExp('^' + route, flags(options))
|
875
|
+
}
|
876
|
+
|
877
|
+
/**
|
878
|
+
* Normalize the given path string, returning a regular expression.
|
879
|
+
*
|
880
|
+
* An empty array can be passed in for the keys, which will hold the
|
881
|
+
* placeholder key descriptions. For example, using `/user/:id`, `keys` will
|
882
|
+
* contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
|
883
|
+
*
|
884
|
+
* @param {(string|RegExp|Array)} path
|
885
|
+
* @param {(Array|Object)=} keys
|
886
|
+
* @param {Object=} options
|
887
|
+
* @return {!RegExp}
|
888
|
+
*/
|
889
|
+
function pathToRegexp (path, keys, options) {
|
890
|
+
keys = keys || []
|
891
|
+
|
892
|
+
if (!isarray(keys)) {
|
893
|
+
options = /** @type {!Object} */ (keys)
|
894
|
+
keys = []
|
895
|
+
} else if (!options) {
|
896
|
+
options = {}
|
897
|
+
}
|
898
|
+
|
899
|
+
if (path instanceof RegExp) {
|
900
|
+
return regexpToRegexp(path, /** @type {!Array} */ (keys))
|
901
|
+
}
|
902
|
+
|
903
|
+
if (isarray(path)) {
|
904
|
+
return arrayToRegexp(/** @type {!Array} */ (path), /** @type {!Array} */ (keys), options)
|
905
|
+
}
|
906
|
+
|
907
|
+
return stringToRegexp(/** @type {string} */ (path), /** @type {!Array} */ (keys), options)
|
908
|
+
}
|
909
|
+
|
910
|
+
index.parse = parse_1;
|
911
|
+
index.compile = compile_1;
|
912
|
+
index.tokensToFunction = tokensToFunction_1;
|
913
|
+
index.tokensToRegExp = tokensToRegExp_1;
|
914
|
+
|
915
|
+
/* */
|
916
|
+
|
917
|
+
function createRouteMap (routes) {
|
918
|
+
var pathMap = Object.create(null)
|
919
|
+
var nameMap = Object.create(null)
|
920
|
+
|
921
|
+
routes.forEach(function (route) {
|
922
|
+
addRouteRecord(pathMap, nameMap, route)
|
923
|
+
})
|
924
|
+
|
925
|
+
return {
|
926
|
+
pathMap: pathMap,
|
927
|
+
nameMap: nameMap
|
928
|
+
}
|
929
|
+
}
|
930
|
+
|
931
|
+
function addRouteRecord (
|
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.")
|
941
|
+
|
942
|
+
var record = {
|
943
|
+
path: normalizePath(path, parent),
|
944
|
+
components: route.components || { default: route.component },
|
945
|
+
instances: {},
|
946
|
+
name: name,
|
947
|
+
parent: parent,
|
948
|
+
matchAs: matchAs,
|
949
|
+
redirect: route.redirect,
|
950
|
+
beforeEnter: route.beforeEnter,
|
951
|
+
meta: route.meta || {}
|
952
|
+
}
|
953
|
+
|
954
|
+
if (route.children) {
|
955
|
+
// Warn if route is named and has a default child route.
|
956
|
+
// If users navigate to this route by name, the default child will
|
957
|
+
// not be rendered (GH Issue #629)
|
958
|
+
if ("production" !== 'production') {}
|
959
|
+
route.children.forEach(function (child) {
|
960
|
+
addRouteRecord(pathMap, nameMap, child, record)
|
961
|
+
})
|
962
|
+
}
|
963
|
+
|
964
|
+
if (route.alias) {
|
965
|
+
if (Array.isArray(route.alias)) {
|
966
|
+
route.alias.forEach(function (alias) {
|
967
|
+
addRouteRecord(pathMap, nameMap, { path: alias }, parent, record.path)
|
968
|
+
})
|
969
|
+
} else {
|
970
|
+
addRouteRecord(pathMap, nameMap, { path: route.alias }, parent, record.path)
|
971
|
+
}
|
972
|
+
}
|
973
|
+
|
974
|
+
pathMap[record.path] = record
|
975
|
+
if (name) { nameMap[name] = record }
|
976
|
+
}
|
977
|
+
|
978
|
+
function normalizePath (path, parent) {
|
979
|
+
path = path.replace(/\/$/, '')
|
980
|
+
if (path[0] === '/') { return path }
|
981
|
+
if (parent == null) { return path }
|
982
|
+
return cleanPath(((parent.path) + "/" + path))
|
983
|
+
}
|
984
|
+
|
985
|
+
/* */
|
986
|
+
|
987
|
+
var regexpCache = Object.create(null)
|
988
|
+
|
989
|
+
var regexpCompileCache = Object.create(null)
|
990
|
+
|
991
|
+
function createMatcher (routes) {
|
992
|
+
var ref = createRouteMap(routes);
|
993
|
+
var pathMap = ref.pathMap;
|
994
|
+
var nameMap = ref.nameMap;
|
995
|
+
|
996
|
+
function match (
|
997
|
+
raw,
|
998
|
+
currentRoute,
|
999
|
+
redirectedFrom
|
1000
|
+
) {
|
1001
|
+
var location = normalizeLocation(raw, currentRoute)
|
1002
|
+
var name = location.name;
|
1003
|
+
|
1004
|
+
if (name) {
|
1005
|
+
var record = nameMap[name]
|
1006
|
+
if (record) {
|
1007
|
+
location.path = fillParams(record.path, location.params, ("named route \"" + name + "\""))
|
1008
|
+
return _createRoute(record, location, redirectedFrom)
|
1009
|
+
}
|
1010
|
+
} else if (location.path) {
|
1011
|
+
location.params = {}
|
1012
|
+
for (var path in pathMap) {
|
1013
|
+
if (matchRoute(path, location.params, location.path)) {
|
1014
|
+
return _createRoute(pathMap[path], location, redirectedFrom)
|
1015
|
+
}
|
1016
|
+
}
|
1017
|
+
}
|
1018
|
+
// no match
|
1019
|
+
return _createRoute(null, location)
|
1020
|
+
}
|
1021
|
+
|
1022
|
+
function redirect (
|
1023
|
+
record,
|
1024
|
+
location
|
1025
|
+
) {
|
1026
|
+
var originalRedirect = record.redirect
|
1027
|
+
var redirect = typeof originalRedirect === 'function'
|
1028
|
+
? originalRedirect(createRoute(record, location))
|
1029
|
+
: originalRedirect
|
1030
|
+
|
1031
|
+
if (typeof redirect === 'string') {
|
1032
|
+
redirect = { path: redirect }
|
1033
|
+
}
|
1034
|
+
|
1035
|
+
if (!redirect || typeof redirect !== 'object') {
|
1036
|
+
warn(false, ("invalid redirect option: " + (JSON.stringify(redirect))))
|
1037
|
+
return _createRoute(null, location)
|
1038
|
+
}
|
1039
|
+
|
1040
|
+
var re = redirect
|
1041
|
+
var name = re.name;
|
1042
|
+
var path = re.path;
|
1043
|
+
var query = location.query;
|
1044
|
+
var hash = location.hash;
|
1045
|
+
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
|
1049
|
+
|
1050
|
+
if (name) {
|
1051
|
+
// resolved named direct
|
1052
|
+
var targetRecord = nameMap[name]
|
1053
|
+
assert(targetRecord, ("redirect failed: named route \"" + name + "\" not found."))
|
1054
|
+
return match({
|
1055
|
+
_normalized: true,
|
1056
|
+
name: name,
|
1057
|
+
query: query,
|
1058
|
+
hash: hash,
|
1059
|
+
params: params
|
1060
|
+
}, undefined, location)
|
1061
|
+
} else if (path) {
|
1062
|
+
// 1. resolve relative redirect
|
1063
|
+
var rawPath = resolveRecordPath(path, record)
|
1064
|
+
// 2. resolve params
|
1065
|
+
var resolvedPath = fillParams(rawPath, params, ("redirect route with path \"" + rawPath + "\""))
|
1066
|
+
// 3. rematch with existing query and hash
|
1067
|
+
return match({
|
1068
|
+
_normalized: true,
|
1069
|
+
path: resolvedPath,
|
1070
|
+
query: query,
|
1071
|
+
hash: hash
|
1072
|
+
}, undefined, location)
|
1073
|
+
} else {
|
1074
|
+
warn(false, ("invalid redirect option: " + (JSON.stringify(redirect))))
|
1075
|
+
return _createRoute(null, location)
|
1076
|
+
}
|
1077
|
+
}
|
1078
|
+
|
1079
|
+
function alias (
|
1080
|
+
record,
|
1081
|
+
location,
|
1082
|
+
matchAs
|
1083
|
+
) {
|
1084
|
+
var aliasedPath = fillParams(matchAs, location.params, ("aliased route with path \"" + matchAs + "\""))
|
1085
|
+
var aliasedMatch = match({
|
1086
|
+
_normalized: true,
|
1087
|
+
path: aliasedPath
|
1088
|
+
})
|
1089
|
+
if (aliasedMatch) {
|
1090
|
+
var matched = aliasedMatch.matched
|
1091
|
+
var aliasedRecord = matched[matched.length - 1]
|
1092
|
+
location.params = aliasedMatch.params
|
1093
|
+
return _createRoute(aliasedRecord, location)
|
1094
|
+
}
|
1095
|
+
return _createRoute(null, location)
|
1096
|
+
}
|
1097
|
+
|
1098
|
+
function _createRoute (
|
1099
|
+
record,
|
1100
|
+
location,
|
1101
|
+
redirectedFrom
|
1102
|
+
) {
|
1103
|
+
if (record && record.redirect) {
|
1104
|
+
return redirect(record, redirectedFrom || location)
|
1105
|
+
}
|
1106
|
+
if (record && record.matchAs) {
|
1107
|
+
return alias(record, location, record.matchAs)
|
1108
|
+
}
|
1109
|
+
return createRoute(record, location, redirectedFrom)
|
1110
|
+
}
|
1111
|
+
|
1112
|
+
return match
|
1113
|
+
}
|
1114
|
+
|
1115
|
+
function matchRoute (
|
1116
|
+
path,
|
1117
|
+
params,
|
1118
|
+
pathname
|
1119
|
+
) {
|
1120
|
+
var keys, regexp
|
1121
|
+
var hit = regexpCache[path]
|
1122
|
+
if (hit) {
|
1123
|
+
keys = hit.keys
|
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)
|
1131
|
+
|
1132
|
+
if (!m) {
|
1133
|
+
return false
|
1134
|
+
} else if (!params) {
|
1135
|
+
return true
|
1136
|
+
}
|
1137
|
+
|
1138
|
+
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 }
|
1142
|
+
}
|
1143
|
+
|
1144
|
+
return true
|
1145
|
+
}
|
1146
|
+
|
1147
|
+
function fillParams (
|
1148
|
+
path,
|
1149
|
+
params,
|
1150
|
+
routeMsg
|
1151
|
+
) {
|
1152
|
+
try {
|
1153
|
+
var filler =
|
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 ''
|
1160
|
+
}
|
1161
|
+
}
|
1162
|
+
|
1163
|
+
function resolveRecordPath (path, record) {
|
1164
|
+
return resolvePath(path, record.parent ? record.parent.path : '/', true)
|
1165
|
+
}
|
1166
|
+
|
1167
|
+
/* */
|
1168
|
+
|
1169
|
+
var inBrowser = typeof window !== 'undefined'
|
1170
|
+
|
1171
|
+
var supportsHistory = inBrowser && (function () {
|
1172
|
+
var ua = window.navigator.userAgent
|
1173
|
+
|
1174
|
+
if (
|
1175
|
+
(ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) &&
|
1176
|
+
ua.indexOf('Mobile Safari') !== -1 &&
|
1177
|
+
ua.indexOf('Chrome') === -1 &&
|
1178
|
+
ua.indexOf('Windows Phone') === -1
|
1179
|
+
) {
|
1180
|
+
return false
|
1181
|
+
}
|
1182
|
+
|
1183
|
+
return window.history && 'pushState' in window.history
|
1184
|
+
})()
|
1185
|
+
|
1186
|
+
/* */
|
1187
|
+
|
1188
|
+
function runQueue (queue, fn, cb) {
|
1189
|
+
var step = function (index) {
|
1190
|
+
if (index >= queue.length) {
|
1191
|
+
cb()
|
1192
|
+
} else {
|
1193
|
+
if (queue[index]) {
|
1194
|
+
fn(queue[index], function () {
|
1195
|
+
step(index + 1)
|
1196
|
+
})
|
1197
|
+
} else {
|
1198
|
+
step(index + 1)
|
1199
|
+
}
|
1200
|
+
}
|
1201
|
+
}
|
1202
|
+
step(0)
|
1203
|
+
}
|
1204
|
+
|
1205
|
+
/* */
|
1206
|
+
|
1207
|
+
|
1208
|
+
var History = function History (router, base) {
|
1209
|
+
this.router = router
|
1210
|
+
this.base = normalizeBase(base)
|
1211
|
+
// start with a route object that stands for "nowhere"
|
1212
|
+
this.current = START
|
1213
|
+
this.pending = null
|
1214
|
+
};
|
1215
|
+
|
1216
|
+
History.prototype.listen = function listen (cb) {
|
1217
|
+
this.cb = cb
|
1218
|
+
};
|
1219
|
+
|
1220
|
+
History.prototype.transitionTo = function transitionTo (location, cb) {
|
1221
|
+
var this$1 = this;
|
1222
|
+
|
1223
|
+
var route = this.router.match(location, this.current)
|
1224
|
+
this.confirmTransition(route, function () {
|
1225
|
+
this$1.updateRoute(route)
|
1226
|
+
cb && cb(route)
|
1227
|
+
this$1.ensureURL()
|
1228
|
+
})
|
1229
|
+
};
|
1230
|
+
|
1231
|
+
History.prototype.confirmTransition = function confirmTransition (route, cb) {
|
1232
|
+
var this$1 = this;
|
1233
|
+
|
1234
|
+
var current = this.current
|
1235
|
+
if (isSameRoute(route, current)) {
|
1236
|
+
this.ensureURL()
|
1237
|
+
return
|
1238
|
+
}
|
1239
|
+
|
1240
|
+
var ref = resolveQueue(this.current.matched, route.matched);
|
1241
|
+
var deactivated = ref.deactivated;
|
1242
|
+
var activated = ref.activated;
|
1243
|
+
|
1244
|
+
var queue = [].concat(
|
1245
|
+
// in-component leave guards
|
1246
|
+
extractLeaveGuards(deactivated),
|
1247
|
+
// global before hooks
|
1248
|
+
this.router.beforeHooks,
|
1249
|
+
// enter guards
|
1250
|
+
activated.map(function (m) { return m.beforeEnter; }),
|
1251
|
+
// async components
|
1252
|
+
resolveAsyncComponents(activated)
|
1253
|
+
)
|
1254
|
+
|
1255
|
+
this.pending = route
|
1256
|
+
var iterator = function (hook, next) {
|
1257
|
+
if (this$1.pending !== route) { return }
|
1258
|
+
hook(route, current, function (to) {
|
1259
|
+
if (to === false) {
|
1260
|
+
// next(false) -> abort navigation, ensure current URL
|
1261
|
+
this$1.ensureURL()
|
1262
|
+
} else if (typeof to === 'string' || typeof to === 'object') {
|
1263
|
+
// next('/') or next({ path: '/' }) -> redirect
|
1264
|
+
this$1.push(to)
|
1265
|
+
} else {
|
1266
|
+
// confirm transition and pass on the value
|
1267
|
+
next(to)
|
1268
|
+
}
|
1269
|
+
})
|
1270
|
+
}
|
1271
|
+
|
1272
|
+
runQueue(queue, iterator, function () {
|
1273
|
+
var postEnterCbs = []
|
1274
|
+
// wait until async components are resolved before
|
1275
|
+
// extracting in-component enter guards
|
1276
|
+
runQueue(extractEnterGuards(activated, postEnterCbs), iterator, function () {
|
1277
|
+
if (this$1.pending === route) {
|
1278
|
+
this$1.pending = null
|
1279
|
+
cb(route)
|
1280
|
+
this$1.router.app.$nextTick(function () {
|
1281
|
+
postEnterCbs.forEach(function (cb) { return cb(); })
|
1282
|
+
})
|
1283
|
+
}
|
1284
|
+
})
|
1285
|
+
})
|
1286
|
+
};
|
1287
|
+
|
1288
|
+
History.prototype.updateRoute = function updateRoute (route) {
|
1289
|
+
var prev = this.current
|
1290
|
+
this.current = route
|
1291
|
+
this.cb && this.cb(route)
|
1292
|
+
this.router.afterHooks.forEach(function (hook) {
|
1293
|
+
hook && hook(route, prev)
|
1294
|
+
})
|
1295
|
+
};
|
1296
|
+
|
1297
|
+
function normalizeBase (base) {
|
1298
|
+
if (!base) {
|
1299
|
+
if (inBrowser) {
|
1300
|
+
// respect <base> tag
|
1301
|
+
var baseEl = document.querySelector('base')
|
1302
|
+
base = baseEl ? baseEl.getAttribute('href') : '/'
|
1303
|
+
} else {
|
1304
|
+
base = '/'
|
1305
|
+
}
|
1306
|
+
}
|
1307
|
+
// make sure there's the starting slash
|
1308
|
+
if (base.charAt(0) !== '/') {
|
1309
|
+
base = '/' + base
|
1310
|
+
}
|
1311
|
+
// remove trailing slash
|
1312
|
+
return base.replace(/\/$/, '')
|
1313
|
+
}
|
1314
|
+
|
1315
|
+
function resolveQueue (
|
1316
|
+
current,
|
1317
|
+
next
|
1318
|
+
) {
|
1319
|
+
var i
|
1320
|
+
var max = Math.max(current.length, next.length)
|
1321
|
+
for (i = 0; i < max; i++) {
|
1322
|
+
if (current[i] !== next[i]) {
|
1323
|
+
break
|
1324
|
+
}
|
1325
|
+
}
|
1326
|
+
return {
|
1327
|
+
activated: next.slice(i),
|
1328
|
+
deactivated: current.slice(i)
|
1329
|
+
}
|
1330
|
+
}
|
1331
|
+
|
1332
|
+
function extractLeaveGuards (matched) {
|
1333
|
+
return flatMapComponents(matched, function (def, instance) {
|
1334
|
+
var guard = def && def.beforeRouteLeave
|
1335
|
+
if (guard) {
|
1336
|
+
return function routeLeaveGuard () {
|
1337
|
+
return guard.apply(instance, arguments)
|
1338
|
+
}
|
1339
|
+
}
|
1340
|
+
}).reverse()
|
1341
|
+
}
|
1342
|
+
|
1343
|
+
function extractEnterGuards (matched, cbs) {
|
1344
|
+
return flatMapComponents(matched, function (def, _, match, key) {
|
1345
|
+
var guard = def && def.beforeRouteEnter
|
1346
|
+
if (guard) {
|
1347
|
+
return function routeEnterGuard (to, from, next) {
|
1348
|
+
return guard(to, from, function (cb) {
|
1349
|
+
next(cb)
|
1350
|
+
if (typeof cb === 'function') {
|
1351
|
+
cbs.push(function () {
|
1352
|
+
cb(match.instances[key])
|
1353
|
+
})
|
1354
|
+
}
|
1355
|
+
})
|
1356
|
+
}
|
1357
|
+
}
|
1358
|
+
})
|
1359
|
+
}
|
1360
|
+
|
1361
|
+
function resolveAsyncComponents (matched) {
|
1362
|
+
return flatMapComponents(matched, function (def, _, match, key) {
|
1363
|
+
// if it's a function and doesn't have Vue options attached,
|
1364
|
+
// assume it's an async component resolve function.
|
1365
|
+
// we are not using Vue's default async resolving mechanism because
|
1366
|
+
// we want to halt the navigation until the incoming component has been
|
1367
|
+
// resolved.
|
1368
|
+
if (typeof def === 'function' && !def.options) {
|
1369
|
+
return function (to, from, next) {
|
1370
|
+
var resolve = function (resolvedDef) {
|
1371
|
+
match.components[key] = resolvedDef
|
1372
|
+
next()
|
1373
|
+
}
|
1374
|
+
|
1375
|
+
var reject = function (reason) {
|
1376
|
+
warn(false, ("Failed to resolve async component " + key + ": " + reason))
|
1377
|
+
next(false)
|
1378
|
+
}
|
1379
|
+
|
1380
|
+
var res = def(resolve, reject)
|
1381
|
+
if (res && typeof res.then === 'function') {
|
1382
|
+
res.then(resolve, reject)
|
1383
|
+
}
|
1384
|
+
}
|
1385
|
+
}
|
1386
|
+
})
|
1387
|
+
}
|
1388
|
+
|
1389
|
+
function flatMapComponents (
|
1390
|
+
matched,
|
1391
|
+
fn
|
1392
|
+
) {
|
1393
|
+
return Array.prototype.concat.apply([], matched.map(function (m) {
|
1394
|
+
return Object.keys(m.components).map(function (key) { return fn(
|
1395
|
+
m.components[key],
|
1396
|
+
m.instances[key],
|
1397
|
+
m, key
|
1398
|
+
); })
|
1399
|
+
}))
|
1400
|
+
}
|
1401
|
+
|
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)
|
1428
|
+
}
|
1429
|
+
|
1430
|
+
function normalizePosition (obj) {
|
1431
|
+
return {
|
1432
|
+
x: isNumber(obj.x) ? obj.x : window.pageXOffset,
|
1433
|
+
y: isNumber(obj.y) ? obj.y : window.pageYOffset
|
1434
|
+
}
|
1435
|
+
}
|
1436
|
+
|
1437
|
+
function isNumber (v) {
|
1438
|
+
return typeof v === 'number'
|
1439
|
+
}
|
1440
|
+
|
1441
|
+
/* */
|
1442
|
+
|
1443
|
+
|
1444
|
+
var genKey = function () { return String(Date.now()); }
|
1445
|
+
var _key = genKey()
|
1446
|
+
|
1447
|
+
var HTML5History = (function (History) {
|
1448
|
+
function HTML5History (router, base) {
|
1449
|
+
var this$1 = this;
|
1450
|
+
|
1451
|
+
History.call(this, router, base)
|
1452
|
+
|
1453
|
+
this.transitionTo(getLocation(this.base))
|
1454
|
+
|
1455
|
+
var expectScroll = router.options.scrollBehavior
|
1456
|
+
window.addEventListener('popstate', function (e) {
|
1457
|
+
_key = e.state && e.state.key
|
1458
|
+
var current = this$1.current
|
1459
|
+
this$1.transitionTo(getLocation(this$1.base), function (next) {
|
1460
|
+
if (expectScroll) {
|
1461
|
+
this$1.handleScroll(next, current, true)
|
1462
|
+
}
|
1463
|
+
})
|
1464
|
+
})
|
1465
|
+
|
1466
|
+
if (expectScroll) {
|
1467
|
+
window.addEventListener('scroll', function () {
|
1468
|
+
saveScrollPosition(_key)
|
1469
|
+
})
|
1470
|
+
}
|
1471
|
+
}
|
1472
|
+
|
1473
|
+
if ( History ) HTML5History.__proto__ = History;
|
1474
|
+
HTML5History.prototype = Object.create( History && History.prototype );
|
1475
|
+
HTML5History.prototype.constructor = HTML5History;
|
1476
|
+
|
1477
|
+
HTML5History.prototype.go = function go (n) {
|
1478
|
+
window.history.go(n)
|
1479
|
+
};
|
1480
|
+
|
1481
|
+
HTML5History.prototype.push = function push (location) {
|
1482
|
+
var this$1 = this;
|
1483
|
+
|
1484
|
+
var current = this.current
|
1485
|
+
this.transitionTo(location, function (route) {
|
1486
|
+
pushState(cleanPath(this$1.base + route.fullPath))
|
1487
|
+
this$1.handleScroll(route, current, false)
|
1488
|
+
})
|
1489
|
+
};
|
1490
|
+
|
1491
|
+
HTML5History.prototype.replace = function replace (location) {
|
1492
|
+
var this$1 = this;
|
1493
|
+
|
1494
|
+
var current = this.current
|
1495
|
+
this.transitionTo(location, function (route) {
|
1496
|
+
replaceState(cleanPath(this$1.base + route.fullPath))
|
1497
|
+
this$1.handleScroll(route, current, false)
|
1498
|
+
})
|
1499
|
+
};
|
1500
|
+
|
1501
|
+
HTML5History.prototype.ensureURL = function ensureURL () {
|
1502
|
+
if (getLocation(this.base) !== this.current.fullPath) {
|
1503
|
+
replaceState(cleanPath(this.base + this.current.fullPath))
|
1504
|
+
}
|
1505
|
+
};
|
1506
|
+
|
1507
|
+
HTML5History.prototype.handleScroll = function handleScroll (to, from, isPop) {
|
1508
|
+
var router = this.router
|
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
|
+
})
|
1542
|
+
};
|
1543
|
+
|
1544
|
+
return HTML5History;
|
1545
|
+
}(History));
|
1546
|
+
|
1547
|
+
function getLocation (base) {
|
1548
|
+
var path = window.location.pathname
|
1549
|
+
if (base && path.indexOf(base) === 0) {
|
1550
|
+
path = path.slice(base.length)
|
1551
|
+
}
|
1552
|
+
return (path || '/') + window.location.search + window.location.hash
|
1553
|
+
}
|
1554
|
+
|
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
|
+
/* */
|
1577
|
+
|
1578
|
+
|
1579
|
+
var HashHistory = (function (History) {
|
1580
|
+
function HashHistory (router, base, fallback) {
|
1581
|
+
var this$1 = this;
|
1582
|
+
|
1583
|
+
History.call(this, router, base)
|
1584
|
+
|
1585
|
+
// check history fallback deeplinking
|
1586
|
+
if (fallback && this.checkFallback()) {
|
1587
|
+
return
|
1588
|
+
}
|
1589
|
+
|
1590
|
+
ensureSlash()
|
1591
|
+
this.transitionTo(getHash())
|
1592
|
+
|
1593
|
+
window.addEventListener('hashchange', function () {
|
1594
|
+
this$1.onHashChange()
|
1595
|
+
})
|
1596
|
+
}
|
1597
|
+
|
1598
|
+
if ( History ) HashHistory.__proto__ = History;
|
1599
|
+
HashHistory.prototype = Object.create( History && History.prototype );
|
1600
|
+
HashHistory.prototype.constructor = HashHistory;
|
1601
|
+
|
1602
|
+
HashHistory.prototype.checkFallback = function checkFallback () {
|
1603
|
+
var location = getLocation(this.base)
|
1604
|
+
if (!/^\/#/.test(location)) {
|
1605
|
+
window.location.replace(
|
1606
|
+
cleanPath(this.base + '/#' + location)
|
1607
|
+
)
|
1608
|
+
return true
|
1609
|
+
}
|
1610
|
+
};
|
1611
|
+
|
1612
|
+
HashHistory.prototype.onHashChange = function onHashChange () {
|
1613
|
+
if (!ensureSlash()) {
|
1614
|
+
return
|
1615
|
+
}
|
1616
|
+
this.transitionTo(getHash(), function (route) {
|
1617
|
+
replaceHash(route.fullPath)
|
1618
|
+
})
|
1619
|
+
};
|
1620
|
+
|
1621
|
+
HashHistory.prototype.push = function push (location) {
|
1622
|
+
History.prototype.transitionTo.call(this, location, function (route) {
|
1623
|
+
pushHash(route.fullPath)
|
1624
|
+
})
|
1625
|
+
};
|
1626
|
+
|
1627
|
+
HashHistory.prototype.replace = function replace (location) {
|
1628
|
+
History.prototype.transitionTo.call(this, location, function (route) {
|
1629
|
+
replaceHash(route.fullPath)
|
1630
|
+
})
|
1631
|
+
};
|
1632
|
+
|
1633
|
+
HashHistory.prototype.go = function go (n) {
|
1634
|
+
window.history.go(n)
|
1635
|
+
};
|
1636
|
+
|
1637
|
+
HashHistory.prototype.ensureURL = function ensureURL () {
|
1638
|
+
if (getHash() !== this.current.fullPath) {
|
1639
|
+
replaceHash(this.current.fullPath)
|
1640
|
+
}
|
1641
|
+
};
|
1642
|
+
|
1643
|
+
return HashHistory;
|
1644
|
+
}(History));
|
1645
|
+
|
1646
|
+
function ensureSlash () {
|
1647
|
+
var path = getHash()
|
1648
|
+
if (path.charAt(0) === '/') {
|
1649
|
+
return true
|
1650
|
+
}
|
1651
|
+
replaceHash('/' + path)
|
1652
|
+
return false
|
1653
|
+
}
|
1654
|
+
|
1655
|
+
function getHash () {
|
1656
|
+
// We can't use window.location.hash here because it's not
|
1657
|
+
// consistent across browsers - Firefox will pre-decode it!
|
1658
|
+
var href = window.location.href
|
1659
|
+
var index = href.indexOf('#')
|
1660
|
+
return index === -1 ? '' : href.slice(index + 1)
|
1661
|
+
}
|
1662
|
+
|
1663
|
+
function pushHash (path) {
|
1664
|
+
window.location.hash = path
|
1665
|
+
}
|
1666
|
+
|
1667
|
+
function replaceHash (path) {
|
1668
|
+
var i = window.location.href.indexOf('#')
|
1669
|
+
window.location.replace(
|
1670
|
+
window.location.href.slice(0, i >= 0 ? i : 0) + '#' + path
|
1671
|
+
)
|
1672
|
+
}
|
1673
|
+
|
1674
|
+
/* */
|
1675
|
+
|
1676
|
+
|
1677
|
+
var AbstractHistory = (function (History) {
|
1678
|
+
function AbstractHistory (router) {
|
1679
|
+
History.call(this, router)
|
1680
|
+
this.stack = []
|
1681
|
+
this.index = 0
|
1682
|
+
}
|
1683
|
+
|
1684
|
+
if ( History ) AbstractHistory.__proto__ = History;
|
1685
|
+
AbstractHistory.prototype = Object.create( History && History.prototype );
|
1686
|
+
AbstractHistory.prototype.constructor = AbstractHistory;
|
1687
|
+
|
1688
|
+
AbstractHistory.prototype.push = function push (location) {
|
1689
|
+
var this$1 = this;
|
1690
|
+
|
1691
|
+
History.prototype.transitionTo.call(this, location, function (route) {
|
1692
|
+
this$1.stack = this$1.stack.slice(0, this$1.index + 1).concat(route)
|
1693
|
+
this$1.index++
|
1694
|
+
})
|
1695
|
+
};
|
1696
|
+
|
1697
|
+
AbstractHistory.prototype.replace = function replace (location) {
|
1698
|
+
var this$1 = this;
|
1699
|
+
|
1700
|
+
History.prototype.transitionTo.call(this, location, function (route) {
|
1701
|
+
this$1.stack = this$1.stack.slice(0, this$1.index).concat(route)
|
1702
|
+
})
|
1703
|
+
};
|
1704
|
+
|
1705
|
+
AbstractHistory.prototype.go = function go (n) {
|
1706
|
+
var this$1 = this;
|
1707
|
+
|
1708
|
+
var targetIndex = this.index + n
|
1709
|
+
if (targetIndex < 0 || targetIndex >= this.stack.length) {
|
1710
|
+
return
|
1711
|
+
}
|
1712
|
+
var location = this.stack[targetIndex]
|
1713
|
+
this.confirmTransition(location, function () {
|
1714
|
+
this$1.index = targetIndex
|
1715
|
+
this$1.updateRoute(location)
|
1716
|
+
})
|
1717
|
+
};
|
1718
|
+
|
1719
|
+
AbstractHistory.prototype.ensureURL = function ensureURL () {
|
1720
|
+
// noop
|
1721
|
+
};
|
1722
|
+
|
1723
|
+
return AbstractHistory;
|
1724
|
+
}(History));
|
1725
|
+
|
1726
|
+
/* */
|
1727
|
+
|
1728
|
+
var VueRouter = function VueRouter (options) {
|
1729
|
+
if ( options === void 0 ) options = {};
|
1730
|
+
|
1731
|
+
this.app = null
|
1732
|
+
this.options = options
|
1733
|
+
this.beforeHooks = []
|
1734
|
+
this.afterHooks = []
|
1735
|
+
this.match = createMatcher(options.routes || [])
|
1736
|
+
|
1737
|
+
var mode = options.mode || 'hash'
|
1738
|
+
this.fallback = mode === 'history' && !supportsHistory
|
1739
|
+
if (this.fallback) {
|
1740
|
+
mode = 'hash'
|
1741
|
+
}
|
1742
|
+
if (!inBrowser) {
|
1743
|
+
mode = 'abstract'
|
1744
|
+
}
|
1745
|
+
this.mode = mode
|
1746
|
+
};
|
1747
|
+
|
1748
|
+
var prototypeAccessors = { currentRoute: {} };
|
1749
|
+
|
1750
|
+
prototypeAccessors.currentRoute.get = function () {
|
1751
|
+
return this.history && this.history.current
|
1752
|
+
};
|
1753
|
+
|
1754
|
+
VueRouter.prototype.init = function init (app /* Vue component instance */) {
|
1755
|
+
var this$1 = this;
|
1756
|
+
|
1757
|
+
assert(
|
1758
|
+
install.installed,
|
1759
|
+
"not installed. Make sure to call `Vue.use(VueRouter)` " +
|
1760
|
+
"before creating root instance."
|
1761
|
+
)
|
1762
|
+
|
1763
|
+
this.app = app
|
1764
|
+
|
1765
|
+
var ref = this;
|
1766
|
+
var mode = ref.mode;
|
1767
|
+
var options = ref.options;
|
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))
|
1781
|
+
}
|
1782
|
+
|
1783
|
+
this.history.listen(function (route) {
|
1784
|
+
this$1.app._route = route
|
1785
|
+
})
|
1786
|
+
};
|
1787
|
+
|
1788
|
+
VueRouter.prototype.beforeEach = function beforeEach (fn) {
|
1789
|
+
this.beforeHooks.push(fn)
|
1790
|
+
};
|
1791
|
+
|
1792
|
+
VueRouter.prototype.afterEach = function afterEach (fn) {
|
1793
|
+
this.afterHooks.push(fn)
|
1794
|
+
};
|
1795
|
+
|
1796
|
+
VueRouter.prototype.push = function push (location) {
|
1797
|
+
this.history.push(location)
|
1798
|
+
};
|
1799
|
+
|
1800
|
+
VueRouter.prototype.replace = function replace (location) {
|
1801
|
+
this.history.replace(location)
|
1802
|
+
};
|
1803
|
+
|
1804
|
+
VueRouter.prototype.go = function go (n) {
|
1805
|
+
this.history.go(n)
|
1806
|
+
};
|
1807
|
+
|
1808
|
+
VueRouter.prototype.back = function back () {
|
1809
|
+
this.go(-1)
|
1810
|
+
};
|
1811
|
+
|
1812
|
+
VueRouter.prototype.forward = function forward () {
|
1813
|
+
this.go(1)
|
1814
|
+
};
|
1815
|
+
|
1816
|
+
VueRouter.prototype.getMatchedComponents = function getMatchedComponents () {
|
1817
|
+
if (!this.currentRoute) {
|
1818
|
+
return []
|
1819
|
+
}
|
1820
|
+
return [].concat.apply([], this.currentRoute.matched.map(function (m) {
|
1821
|
+
return Object.keys(m.components).map(function (key) {
|
1822
|
+
return m.components[key]
|
1823
|
+
})
|
1824
|
+
}))
|
1825
|
+
};
|
1826
|
+
|
1827
|
+
Object.defineProperties( VueRouter.prototype, prototypeAccessors );
|
1828
|
+
|
1829
|
+
VueRouter.install = install
|
1830
|
+
|
1831
|
+
if (inBrowser && window.Vue) {
|
1832
|
+
window.Vue.use(VueRouter)
|
1833
|
+
}
|
1834
|
+
|
1835
|
+
return VueRouter;
|
1836
|
+
|
1837
|
+
})));
|