url.js
3.19 KB
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
var Class = require('./Class')
var map = require('./map')
var isArray = require('std/isArray')
var URL = Class(function() {
this._extractionRegex = new RegExp([
'^', // start at the beginning of the string
'((\\w+:)?//)?', // match a possible protocol, like http://, ftp://, or // for a relative url
'(\\w[\\w\\.\\-]+)?', // match a possible domain
'(:\\d+)?', // match a possible port
'(\\/[^\\?#]+)?', // match a possible path
'(\\?[^#]+)?', // match possible GET parameters
'(#.*)?' // match the rest of the URL as the hash
].join(''), 'i')
this.init = function(url) {
var match = (url || '').toString().match(this._extractionRegex) || []
this.protocol = match[2] || ''
this.hostname = match[3] || ''
this.port = (match[4] || '').substr(1)
this.host = (this.hostname ? this.hostname : '') + (this.port ? ':' + this.port : '')
this.pathname = match[5] || ''
this.search = (match[6]||'').substr(1)
this.hash = (match[7]||'').substr(1)
}
this.setProtocol = function(protocol) {
this.protocol = protocol
return this
}
this.toString = function() {
return [
this.protocol || '//',
this.host,
this.pathname,
this.getSearch(),
this.getHash()
].join('')
}
this.toJSON = this.toString
this.getTopLevelDomain = function() {
if (!this.host) { return '' }
var parts = this.host.split('.')
return parts.slice(parts.length - 2).join('.')
}
this.getSearchParams = function() {
if (this._searchParams) { return this._searchParams }
return this._searchParams = url.query.parse(this.search) || {}
}
this.getHashParams = function() {
if (this._hashParams) { return this._hashParams }
return this._hashParams = url.query.parse(this.hash) || {}
}
this.addToSearch = function(key, val) { this.getSearchParams()[key] = val; return this }
this.addToHash = function(key, val) { this.getHashParams()[key] = val; return this }
this.removeFromSearch = function(key) { delete this.getSearchParams()[key]; return this }
this.removeFromHash = function(key) { delete this.getHashParams()[key]; return this }
this.getSearch = function() {
return (
this._searchParams ? '?' + url.query.string(this._searchParams)
: this.search ? '?' + this.search
: '')
}
this.getHash = function() {
return (
this._hashParams ? '#' + url.query.string(this._hashParams)
: this.hash ? '?' + this.hash
: '')
}
this.getSearchParam = function(key) { return this.getSearchParams()[key] }
this.getHashParam = function(key) { return this.getHashParams()[key] }
})
var url = module.exports = function url(url) { return new URL(url) }
url.parse = url
url.query = {
parse:function(paramString) {
var parts = paramString.split('&'),
params = {}
for (var i=0; i<parts.length; i++) {
var kvp = parts[i].split('=')
if (kvp.length != 2) { continue }
params[decodeURIComponent(kvp[0])] = decodeURIComponent(kvp[1])
}
return params
},
string:function(params) {
return map(params, function(val, key) {
return encodeURIComponent(key) + '=' + url.query.encodeValue(val)
}).join('&')
},
encodeValue:function(val) {
if (isArray(val)) {
return map(val, function(v) {
return encodeURIComponent(v)
}).join(',')
} else {
return encodeURIComponent(val)
}
}
}