whatwg-url 6.2.1 → 6.5.0
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.
- package/README.md +2 -2
- package/lib/URL-impl.js +6 -0
- package/lib/url-state-machine.js +43 -20
- package/lib/urlencoded.js +3 -3
- package/package.json +17 -12
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ whatwg-url is a full implementation of the WHATWG [URL Standard](https://url.spe
|
|
|
4
4
|
|
|
5
5
|
## Current status
|
|
6
6
|
|
|
7
|
-
whatwg-url is currently up to date with the URL spec up to commit [
|
|
7
|
+
whatwg-url is currently up to date with the URL spec up to commit [6ef17eb](https://github.com/whatwg/url/commit/6ef17ebe1220a7e7c0cfff0785017502ee18808b).
|
|
8
8
|
|
|
9
9
|
## API
|
|
10
10
|
|
|
@@ -21,7 +21,7 @@ The following methods are exported for use by places like jsdom that need to imp
|
|
|
21
21
|
- [URL serializer](https://url.spec.whatwg.org/#concept-url-serializer): `serializeURL(urlRecord, excludeFragment)`
|
|
22
22
|
- [Host serializer](https://url.spec.whatwg.org/#concept-host-serializer): `serializeHost(hostFromURLRecord)`
|
|
23
23
|
- [Serialize an integer](https://url.spec.whatwg.org/#serialize-an-integer): `serializeInteger(number)`
|
|
24
|
-
- [Origin](https://url.spec.whatwg.org/#concept-url-origin) [serializer](https://html.spec.whatwg.org/multipage/
|
|
24
|
+
- [Origin](https://url.spec.whatwg.org/#concept-url-origin) [serializer](https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin): `serializeURLOrigin(urlRecord)`
|
|
25
25
|
- [Set the username](https://url.spec.whatwg.org/#set-the-username): `setTheUsername(urlRecord, usernameString)`
|
|
26
26
|
- [Set the password](https://url.spec.whatwg.org/#set-the-password): `setThePassword(urlRecord, passwordString)`
|
|
27
27
|
- [Cannot have a username/password/port](https://url.spec.whatwg.org/#cannot-have-a-username-password-port): `cannotHaveAUsernamePasswordPort(urlRecord)`
|
package/lib/URL-impl.js
CHANGED
|
@@ -42,6 +42,12 @@ exports.implementation = class URLImpl {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
this._url = parsedURL;
|
|
45
|
+
|
|
46
|
+
this._query._list.splice(0);
|
|
47
|
+
const { query } = parsedURL;
|
|
48
|
+
if (query !== null) {
|
|
49
|
+
this._query._list = urlencoded.parseUrlencoded(query);
|
|
50
|
+
}
|
|
45
51
|
}
|
|
46
52
|
|
|
47
53
|
get origin() {
|
package/lib/url-state-machine.js
CHANGED
|
@@ -63,6 +63,10 @@ function isSpecial(url) {
|
|
|
63
63
|
return isSpecialScheme(url.scheme);
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
function isNotSpecial(url) {
|
|
67
|
+
return !isSpecialScheme(url.scheme);
|
|
68
|
+
}
|
|
69
|
+
|
|
66
70
|
function defaultPort(scheme) {
|
|
67
71
|
return specialSchemes[scheme];
|
|
68
72
|
}
|
|
@@ -83,17 +87,22 @@ function isC0ControlPercentEncode(c) {
|
|
|
83
87
|
return c <= 0x1F || c > 0x7E;
|
|
84
88
|
}
|
|
85
89
|
|
|
86
|
-
const extraPathPercentEncodeSet = new Set([32, 34, 35, 60, 62, 63, 96, 123, 125]);
|
|
87
|
-
function isPathPercentEncode(c) {
|
|
88
|
-
return isC0ControlPercentEncode(c) || extraPathPercentEncodeSet.has(c);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
90
|
const extraUserinfoPercentEncodeSet =
|
|
92
91
|
new Set([47, 58, 59, 61, 64, 91, 92, 93, 94, 124]);
|
|
93
92
|
function isUserinfoPercentEncode(c) {
|
|
94
93
|
return isPathPercentEncode(c) || extraUserinfoPercentEncodeSet.has(c);
|
|
95
94
|
}
|
|
96
95
|
|
|
96
|
+
const extraFragmentPercentEncodeSet = new Set([32, 34, 60, 62, 96]);
|
|
97
|
+
function isFragmentPercentEncode(c) {
|
|
98
|
+
return isC0ControlPercentEncode(c) || extraFragmentPercentEncodeSet.has(c);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const extraPathPercentEncodeSet = new Set([35, 63, 123, 125]);
|
|
102
|
+
function isPathPercentEncode(c) {
|
|
103
|
+
return isFragmentPercentEncode(c) || extraPathPercentEncodeSet.has(c);
|
|
104
|
+
}
|
|
105
|
+
|
|
97
106
|
function percentEncodeChar(c, encodeSetPredicate) {
|
|
98
107
|
const cStr = String.fromCodePoint(c);
|
|
99
108
|
|
|
@@ -119,7 +128,14 @@ function parseIPv4Number(input) {
|
|
|
119
128
|
return 0;
|
|
120
129
|
}
|
|
121
130
|
|
|
122
|
-
|
|
131
|
+
let regex = /[^0-7]/;
|
|
132
|
+
if (R === 10) {
|
|
133
|
+
regex = /[^0-9]/;
|
|
134
|
+
}
|
|
135
|
+
if (R === 16) {
|
|
136
|
+
regex = /[^0-9A-Fa-f]/;
|
|
137
|
+
}
|
|
138
|
+
|
|
123
139
|
if (regex.test(input)) {
|
|
124
140
|
return failure;
|
|
125
141
|
}
|
|
@@ -346,7 +362,7 @@ function serializeIPv6(address) {
|
|
|
346
362
|
return output;
|
|
347
363
|
}
|
|
348
364
|
|
|
349
|
-
function parseHost(input,
|
|
365
|
+
function parseHost(input, isNotSpecialArg = false) {
|
|
350
366
|
if (input[0] === "[") {
|
|
351
367
|
if (input[input.length - 1] !== "]") {
|
|
352
368
|
return failure;
|
|
@@ -355,7 +371,7 @@ function parseHost(input, isSpecialArg) {
|
|
|
355
371
|
return parseIPv6(input.substring(1, input.length - 1));
|
|
356
372
|
}
|
|
357
373
|
|
|
358
|
-
if (
|
|
374
|
+
if (isNotSpecialArg) {
|
|
359
375
|
return parseOpaqueHost(input);
|
|
360
376
|
}
|
|
361
377
|
|
|
@@ -461,7 +477,7 @@ function trimTabAndNewline(url) {
|
|
|
461
477
|
}
|
|
462
478
|
|
|
463
479
|
function shortenPath(url) {
|
|
464
|
-
const path = url
|
|
480
|
+
const { path } = url;
|
|
465
481
|
if (path.length === 0) {
|
|
466
482
|
return;
|
|
467
483
|
}
|
|
@@ -804,7 +820,7 @@ URLStateMachine.prototype["parse host"] = function parseHostName(c, cStr) {
|
|
|
804
820
|
return failure;
|
|
805
821
|
}
|
|
806
822
|
|
|
807
|
-
const host = parseHost(this.buffer,
|
|
823
|
+
const host = parseHost(this.buffer, isNotSpecial(this.url));
|
|
808
824
|
if (host === failure) {
|
|
809
825
|
return failure;
|
|
810
826
|
}
|
|
@@ -827,7 +843,7 @@ URLStateMachine.prototype["parse host"] = function parseHostName(c, cStr) {
|
|
|
827
843
|
return false;
|
|
828
844
|
}
|
|
829
845
|
|
|
830
|
-
const host = parseHost(this.buffer,
|
|
846
|
+
const host = parseHost(this.buffer, isNotSpecial(this.url));
|
|
831
847
|
if (host === failure) {
|
|
832
848
|
return failure;
|
|
833
849
|
}
|
|
@@ -880,6 +896,13 @@ URLStateMachine.prototype["parse port"] = function parsePort(c, cStr) {
|
|
|
880
896
|
|
|
881
897
|
const fileOtherwiseCodePoints = new Set([47, 92, 63, 35]);
|
|
882
898
|
|
|
899
|
+
function startsWithWindowsDriveLetter(input, pointer) {
|
|
900
|
+
const length = input.length - pointer;
|
|
901
|
+
return length >= 2 &&
|
|
902
|
+
isWindowsDriveLetterCodePoints(input[pointer], input[pointer + 1]) &&
|
|
903
|
+
(length === 2 || fileOtherwiseCodePoints.has(input[pointer + 2]));
|
|
904
|
+
}
|
|
905
|
+
|
|
883
906
|
URLStateMachine.prototype["parse file"] = function parseFile(c) {
|
|
884
907
|
this.url.scheme = "file";
|
|
885
908
|
|
|
@@ -905,10 +928,7 @@ URLStateMachine.prototype["parse file"] = function parseFile(c) {
|
|
|
905
928
|
this.url.fragment = "";
|
|
906
929
|
this.state = "fragment";
|
|
907
930
|
} else {
|
|
908
|
-
if (this.input
|
|
909
|
-
!isWindowsDriveLetterCodePoints(c, this.input[this.pointer + 1]) ||
|
|
910
|
-
(this.input.length - this.pointer - 1 >= 2 && // remaining has at least 2 code points
|
|
911
|
-
!fileOtherwiseCodePoints.has(this.input[this.pointer + 2]))) {
|
|
931
|
+
if (!startsWithWindowsDriveLetter(this.input, this.pointer)) {
|
|
912
932
|
this.url.host = this.base.host;
|
|
913
933
|
this.url.path = this.base.path.slice();
|
|
914
934
|
shortenPath(this.url);
|
|
@@ -934,7 +954,8 @@ URLStateMachine.prototype["parse file slash"] = function parseFileSlash(c) {
|
|
|
934
954
|
}
|
|
935
955
|
this.state = "file host";
|
|
936
956
|
} else {
|
|
937
|
-
if (this.base !== null && this.base.scheme === "file"
|
|
957
|
+
if (this.base !== null && this.base.scheme === "file" &&
|
|
958
|
+
!startsWithWindowsDriveLetter(this.input, this.pointer)) {
|
|
938
959
|
if (isNormalizedWindowsDriveLetterString(this.base.path[0])) {
|
|
939
960
|
this.url.path.push(this.base.path[0]);
|
|
940
961
|
} else {
|
|
@@ -961,7 +982,7 @@ URLStateMachine.prototype["parse file host"] = function parseFileHost(c, cStr) {
|
|
|
961
982
|
}
|
|
962
983
|
this.state = "path start";
|
|
963
984
|
} else {
|
|
964
|
-
let host = parseHost(this.buffer,
|
|
985
|
+
let host = parseHost(this.buffer, isNotSpecial(this.url));
|
|
965
986
|
if (host === failure) {
|
|
966
987
|
return failure;
|
|
967
988
|
}
|
|
@@ -1100,8 +1121,10 @@ URLStateMachine.prototype["parse query"] = function parseQuery(c, cStr) {
|
|
|
1100
1121
|
|
|
1101
1122
|
const buffer = Buffer.from(this.buffer); // TODO: Use encoding override instead
|
|
1102
1123
|
for (let i = 0; i < buffer.length; ++i) {
|
|
1103
|
-
if (buffer[i] < 0x21 ||
|
|
1104
|
-
buffer[i]
|
|
1124
|
+
if (buffer[i] < 0x21 ||
|
|
1125
|
+
buffer[i] > 0x7E ||
|
|
1126
|
+
buffer[i] === 0x22 || buffer[i] === 0x23 || buffer[i] === 0x3C || buffer[i] === 0x3E ||
|
|
1127
|
+
(buffer[i] === 0x27 && isSpecial(this.url))) {
|
|
1105
1128
|
this.url.query += percentEncode(buffer[i]);
|
|
1106
1129
|
} else {
|
|
1107
1130
|
this.url.query += String.fromCodePoint(buffer[i]);
|
|
@@ -1139,7 +1162,7 @@ URLStateMachine.prototype["parse fragment"] = function parseFragment(c) {
|
|
|
1139
1162
|
this.parseError = true;
|
|
1140
1163
|
}
|
|
1141
1164
|
|
|
1142
|
-
this.url.fragment += percentEncodeChar(c,
|
|
1165
|
+
this.url.fragment += percentEncodeChar(c, isFragmentPercentEncode);
|
|
1143
1166
|
}
|
|
1144
1167
|
|
|
1145
1168
|
return true;
|
package/lib/urlencoded.js
CHANGED
|
@@ -84,10 +84,10 @@ function serializeUrlencodedByte(input) {
|
|
|
84
84
|
} else if (byte === 42 ||
|
|
85
85
|
byte === 45 ||
|
|
86
86
|
byte === 46 ||
|
|
87
|
-
byte >= 48 && byte <= 57 ||
|
|
88
|
-
byte >= 65 && byte <= 90 ||
|
|
87
|
+
(byte >= 48 && byte <= 57) ||
|
|
88
|
+
(byte >= 65 && byte <= 90) ||
|
|
89
89
|
byte === 95 ||
|
|
90
|
-
byte >= 97 && byte <= 122) {
|
|
90
|
+
(byte >= 97 && byte <= 122)) {
|
|
91
91
|
output += String.fromCodePoint(byte);
|
|
92
92
|
} else {
|
|
93
93
|
output += percentEncode(byte);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "whatwg-url",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.5.0",
|
|
4
4
|
"description": "An implementation of the WHATWG URL Standard's URL API and parsing machinery",
|
|
5
5
|
"main": "lib/public-api.js",
|
|
6
6
|
"files": [
|
|
@@ -11,18 +11,19 @@
|
|
|
11
11
|
"repository": "jsdom/whatwg-url",
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"lodash.sortby": "^4.7.0",
|
|
14
|
-
"tr46": "^1.0.
|
|
15
|
-
"webidl-conversions": "^4.0.
|
|
14
|
+
"tr46": "^1.0.1",
|
|
15
|
+
"webidl-conversions": "^4.0.2"
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
18
|
+
"browserify": "^16.2.2",
|
|
19
|
+
"domexception": "^1.0.1",
|
|
20
|
+
"eslint": "^4.19.1",
|
|
21
|
+
"istanbul": "~0.4.5",
|
|
22
|
+
"jest": "^22.4.3",
|
|
23
|
+
"jsdom": "^11.8.0",
|
|
24
|
+
"recast": "~0.14.7",
|
|
25
|
+
"request": "^2.85.0",
|
|
26
|
+
"webidl2js": "^7.4.0"
|
|
26
27
|
},
|
|
27
28
|
"scripts": {
|
|
28
29
|
"build": "node scripts/transform.js && node scripts/convert-idl.js",
|
|
@@ -30,6 +31,7 @@
|
|
|
30
31
|
"lint": "eslint .",
|
|
31
32
|
"prepublish": "node scripts/transform.js && node scripts/convert-idl.js",
|
|
32
33
|
"pretest": "node scripts/get-latest-platform-tests.js && node scripts/transform.js && node scripts/convert-idl.js",
|
|
34
|
+
"build-live-viewer": "browserify lib/public-api.js --standalone whatwgURL > live-viewer/whatwg-url.js",
|
|
33
35
|
"test": "jest"
|
|
34
36
|
},
|
|
35
37
|
"jest": {
|
|
@@ -38,7 +40,10 @@
|
|
|
38
40
|
"!lib/utils.js"
|
|
39
41
|
],
|
|
40
42
|
"coverageDirectory": "coverage",
|
|
41
|
-
"coverageReporters": [
|
|
43
|
+
"coverageReporters": [
|
|
44
|
+
"lcov",
|
|
45
|
+
"text-summary"
|
|
46
|
+
],
|
|
42
47
|
"testEnvironment": "node",
|
|
43
48
|
"testMatch": [
|
|
44
49
|
"<rootDir>/test/**/*.js"
|