-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathuri.js
120 lines (98 loc) · 2.87 KB
/
uri.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
define(function (require) {
var _ = require('underscore')
, serialize = require('./serialize')
, serializeEncoder = _.compose(String, encode)
uri.decode = decode
uri.encode = encode
return uri
function uri(url) {
var api = {
query: setQuery
, search: setSearch
, path: setPath
, pathname: setPathname
, hash: setHash
, toString: build
}
, pathname = ''
, query = {}
, hash = ''
return url ? parse(url) : api
function setQuery(value) {
if (!arguments.length) return query
if (!_.isObject(value)) return query[value]
query = _.extend(query, value)
return api
}
function setPathname(value) {
if (!arguments.length) return pathname
pathname = value
return api
}
function setHash(value) {
if (!arguments.length) return hash
hash = value
return api
}
function setSearch(queryString) {
if (!arguments.length) return serialize(query, serializeEncoder)
query = parseQueryString(queryString.charAt(0) === '?'
? queryString.slice(1)
: queryString
)
return api
}
function setPath(url) {
return !arguments.length ? build() : parse(url)
}
function build() {
var currentPathname = pathname.replace(/[?#]/g, encode)
, currentHash = hash && hash.charAt(0) !== '#' ? '#' + hash : hash
, search = setSearch().replace(/#/g, encode)
return currentPathname + search + currentHash
}
function parse(url) {
var parts = url.match(/^(.*?)(\?.*?)?(#.*?)?$/)
, search = parts[2] ? parts[2].slice(1) : ''
pathname = parts[1] || ''
hash = parts[3] ? parts[3].slice(1) : ''
return setSearch(search)
}
}
function parseQueryString(queryString, decoder) {
var sep = '&'
, eq = '='
, query = {}
, regexp = /\+/g
, decodedKey, decodedValue, fragment, parts
if (!queryString) return query
var queryFragments = queryString.split(sep)
, len = queryFragments.length
for (var i = 0; i < len; ++i) {
fragment = queryFragments[i].replace(regexp, '%20')
parts = fragment.split(eq)
decodedKey = decode(parts.shift())
decodedValue = decode(parts.join(eq))
if (!Object.prototype.hasOwnProperty.call(query, decodedKey)) {
query[decodedKey] = decodedValue
} else if (_.isArray(query[decodedKey])) {
query[decodedKey].push(decodedValue)
} else {
query[decodedKey] = [query[decodedKey], decodedValue]
}
}
return query
}
function encode(value) {
return value ? encodeURIComponent(value) : ''
}
function decode(value) {
if (value) {
return String(value).replace(/(?:%[0-9a-fA-F]{2})+/g, function(match) {
return decodeURIComponent(match)
})
} else {
return ''
}
}
})