Skip to content

Commit 635161b

Browse files
authored
Merge pull request #114 from curbengh/whatwg-url
refactor: whatwg url api
2 parents c505094 + f60127b commit 635161b

File tree

8 files changed

+65
-37
lines changed

8 files changed

+65
-37
lines changed

lib/decode_url.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
'use strict';
22

3+
// To be refactored to WHATWG URL API
4+
// after support for Node 8 is dropped.
5+
// url.format(WHATWG URL object) in Node 8 doesn't support port number
6+
37
const { parse, format } = require('url');
48
const { toUnicode } = require('./punycode');
59

lib/encode_url.js

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,33 @@
11
'use strict';
22

3-
const { parse, format } = require('url');
4-
const regexNonUrl = /^(data|javascript|mailto|vbscript)/i;
3+
const { URL } = require('url');
54

6-
function encodeURL(str) {
7-
const parsed = parse(str);
8-
if (parsed.slashes) {
9-
const obj = Object.assign({}, {
10-
auth: parsed.auth,
11-
protocol: parsed.protocol,
12-
host: parsed.host,
13-
pathname: encodeURI(safeDecodeURI(parsed.pathname))
14-
});
15-
16-
if (parsed.hash) {
17-
Object.assign(obj, { hash: encodeURI(safeDecodeURI(parsed.hash)) });
18-
}
19-
20-
if (parsed.search) {
21-
Object.assign(obj, { search: encodeURI(safeDecodeURI(parsed.search)) });
22-
}
23-
24-
return format(obj);
5+
const urlObj = (str) => {
6+
try {
7+
return new URL(str);
8+
} catch (err) {
9+
return str;
2510
}
11+
};
2612

27-
if (str.match(regexNonUrl)) return str;
28-
29-
return encodeURI(safeDecodeURI(str));
30-
}
31-
32-
function safeDecodeURI(str) {
13+
const safeDecodeURI = (str) => {
3314
try {
3415
return decodeURI(str);
3516
} catch (err) {
3617
return str;
3718
}
38-
}
19+
};
20+
21+
const encodeURL = (str) => {
22+
const parsed = urlObj(str);
23+
if (typeof parsed === 'object') {
24+
if (parsed.origin === 'null') return str;
25+
26+
parsed.search = encodeURI(safeDecodeURI(parsed.search));
27+
return parsed.toString();
28+
}
29+
30+
return encodeURI(safeDecodeURI(str));
31+
};
3932

4033
module.exports = encodeURL;

lib/full_url_for.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,25 @@
11
'use strict';
22

3-
const { parse } = require('url');
3+
const { URL } = require('url');
44
const encodeURL = require('./encode_url');
55

6+
const urlObj = (str) => {
7+
try {
8+
return new URL(str);
9+
} catch (err) {
10+
return str;
11+
}
12+
};
13+
614
function fullUrlForHelper(path = '/') {
715
if (path.startsWith('//')) return path;
816
const { config } = this;
9-
const data = parse(path);
17+
const data = urlObj(path);
1018

1119
// Exit if this is an external path
12-
if (data.protocol) return path;
20+
if (typeof data === 'object') {
21+
if (data.origin !== 'null') return path;
22+
}
1323

1424
path = encodeURL(config.url + `/${path}`.replace(/\/{2,}/g, '/'));
1525
return path;

lib/url_for.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,33 @@
11
'use strict';
22

3-
const { parse } = require('url');
3+
const { URL } = require('url');
44
const encodeURL = require('./encode_url');
55
const relative_url = require('./relative_url');
66

7+
const urlObj = (str) => {
8+
try {
9+
return new URL(str);
10+
} catch (err) {
11+
return str;
12+
}
13+
};
14+
715
function urlForHelper(path = '/', options) {
816
if (path[0] === '#' || path.startsWith('//')) {
917
return path;
1018
}
1119

1220
const { config } = this;
1321
const { root } = config;
14-
const data = parse(path);
22+
const data = urlObj(path);
1523

1624
options = Object.assign({
1725
relative: config.relative_link
1826
}, options);
1927

2028
// Exit if this is an external path
21-
if (data.protocol) {
22-
return path;
29+
if (typeof data === 'object') {
30+
if (data.origin !== 'null') return path;
2331
}
2432

2533
// Resolve relative url

test/decode_url.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ describe('decodeURL', () => {
1616
});
1717

1818
it('port', () => {
19-
const content = 'http://foo.com:80/';
19+
const content = 'http://foo.com:8080/';
2020
decodeURL(content).should.eql(content);
2121
});
2222

test/encode_url.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ describe('encodeURL', () => {
1616
});
1717

1818
it('port', () => {
19-
const content = 'http://foo.com:80/';
19+
const content = 'http://foo.com:8080/';
2020
encodeURL(content).should.eql(content);
2121
});
2222

test/full_url_for.spec.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,9 @@ describe('full_url_for', () => {
3737
ctx.config.url = 'https://example.com/blog';
3838
fullUrlFor('#test').should.eql(ctx.config.url + '/#test');
3939
});
40+
41+
it('path with semicolon', () => {
42+
ctx.config.url = 'https://example.com/blog';
43+
fullUrlFor('foo:bar').should.eql(ctx.config.url + '/foo:bar');
44+
});
4045
});

test/url_for.spec.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,12 @@ describe('url_for', () => {
7272
it('only hash', () => {
7373
urlFor('#test').should.eql('#test');
7474
});
75+
76+
it('path with semicolon', () => {
77+
ctx.config.root = '/';
78+
urlFor('foo:bar').should.eql('/foo:bar');
79+
80+
ctx.config.root = '/foo/';
81+
urlFor('bar:baz').should.eql('/foo/bar:baz');
82+
});
7583
});

0 commit comments

Comments
 (0)