whatwg-url 15.1.0 → 16.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.
- package/README.md +3 -5
- package/lib/URL-impl.js +2 -1
- package/lib/percent-encoding.js +6 -1
- package/lib/url-state-machine.js +17 -10
- package/lib/utils.js +14 -2
- package/package.json +10 -9
package/README.md
CHANGED
|
@@ -4,12 +4,10 @@ whatwg-url is a full implementation of the WHATWG [URL Standard](https://url.spe
|
|
|
4
4
|
|
|
5
5
|
## Specification conformance
|
|
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 [b6b3251](https://github.com/whatwg/url/commit/b6b3251fe911ab33d68fb051efe0e4d39ae4145e).
|
|
8
8
|
|
|
9
9
|
For `file:` URLs, whose [origin is left unspecified](https://url.spec.whatwg.org/#concept-url-origin), whatwg-url chooses to use a new opaque origin (which serializes to `"null"`).
|
|
10
10
|
|
|
11
|
-
whatwg-url does not yet implement any encoding handling beyond UTF-8. That is, the _encoding override_ parameter does not exist in our API.
|
|
12
|
-
|
|
13
11
|
## API
|
|
14
12
|
|
|
15
13
|
### The `URL` and `URLSearchParams` classes
|
|
@@ -20,8 +18,8 @@ The main API is provided by the [`URL`](https://url.spec.whatwg.org/#url-class)
|
|
|
20
18
|
|
|
21
19
|
The following methods are exported for use by places like jsdom that need to implement things like [`HTMLHyperlinkElementUtils`](https://html.spec.whatwg.org/#htmlhyperlinkelementutils). They mostly operate on or return an "internal URL" or ["URL record"](https://url.spec.whatwg.org/#concept-url) type.
|
|
22
20
|
|
|
23
|
-
- [URL parser](https://url.spec.whatwg.org/#concept-url-parser): `parseURL(input, { baseURL })`
|
|
24
|
-
- [Basic URL parser](https://url.spec.whatwg.org/#concept-basic-url-parser): `basicURLParse(input, { baseURL, url, stateOverride })`
|
|
21
|
+
- [URL parser](https://url.spec.whatwg.org/#concept-url-parser): `parseURL(input, { baseURL, encoding = "UTF-8" })`
|
|
22
|
+
- [Basic URL parser](https://url.spec.whatwg.org/#concept-basic-url-parser): `basicURLParse(input, { baseURL, url, stateOverride, encoding = "UTF-8" })`
|
|
25
23
|
- [URL serializer](https://url.spec.whatwg.org/#concept-url-serializer): `serializeURL(urlRecord, excludeFragment)`
|
|
26
24
|
- [Host serializer](https://url.spec.whatwg.org/#concept-host-serializer): `serializeHost(hostFromURLRecord)`
|
|
27
25
|
- [URL path serializer](https://url.spec.whatwg.org/#url-path-serializer): `serializePath(urlRecord)`
|
package/lib/URL-impl.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
const usm = require("./url-state-machine");
|
|
3
3
|
const urlencoded = require("./urlencoded");
|
|
4
4
|
const URLSearchParams = require("./URLSearchParams");
|
|
5
|
+
const URL = require("./URL");
|
|
5
6
|
|
|
6
7
|
exports.implementation = class URLImpl {
|
|
7
8
|
// Unlike the spec, we duplicate some code between the constructor and canParse, because we want to give useful error
|
|
@@ -32,7 +33,7 @@ exports.implementation = class URLImpl {
|
|
|
32
33
|
|
|
33
34
|
static parse(globalObject, input, base) {
|
|
34
35
|
try {
|
|
35
|
-
return
|
|
36
|
+
return URL.createImpl(globalObject, [input, base]);
|
|
36
37
|
} catch {
|
|
37
38
|
return null;
|
|
38
39
|
}
|
package/lib/percent-encoding.js
CHANGED
|
@@ -55,13 +55,16 @@ function isFragmentPercentEncode(c) {
|
|
|
55
55
|
|
|
56
56
|
// https://url.spec.whatwg.org/#query-percent-encode-set
|
|
57
57
|
const extraQueryPercentEncodeSet = new Set([p(" "), p("\""), p("#"), p("<"), p(">")]);
|
|
58
|
+
const extraQueryPercentEncodeChars = String.fromCodePoint(...[...extraQueryPercentEncodeSet].sort());
|
|
58
59
|
function isQueryPercentEncode(c) {
|
|
59
60
|
return isC0ControlPercentEncode(c) || extraQueryPercentEncodeSet.has(c);
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
// https://url.spec.whatwg.org/#special-query-percent-encode-set
|
|
64
|
+
const extraSpecialQueryPercentEncodeSet = new Set([...extraQueryPercentEncodeSet, p("'")]);
|
|
65
|
+
const extraSpecialQueryPercentEncodeChars = String.fromCodePoint(...[...extraSpecialQueryPercentEncodeSet].sort());
|
|
63
66
|
function isSpecialQueryPercentEncode(c) {
|
|
64
|
-
return
|
|
67
|
+
return isC0ControlPercentEncode(c) || extraSpecialQueryPercentEncodeSet.has(c);
|
|
65
68
|
}
|
|
66
69
|
|
|
67
70
|
// https://url.spec.whatwg.org/#path-percent-encode-set
|
|
@@ -135,6 +138,8 @@ module.exports = {
|
|
|
135
138
|
isPathPercentEncode,
|
|
136
139
|
isUserinfoPercentEncode,
|
|
137
140
|
isURLEncodedPercentEncode,
|
|
141
|
+
extraQueryPercentEncodeChars,
|
|
142
|
+
extraSpecialQueryPercentEncodeChars,
|
|
138
143
|
percentDecodeString,
|
|
139
144
|
percentDecodeBytes,
|
|
140
145
|
utf8PercentEncodeString,
|
package/lib/url-state-machine.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
require("@exodus/bytes/encoding.js"); // for legacy multi-byte encodings
|
|
3
|
+
const { percentEncodeAfterEncoding } = require("@exodus/bytes/whatwg.js");
|
|
2
4
|
const tr46 = require("tr46");
|
|
3
5
|
|
|
4
6
|
const infra = require("./infra");
|
|
5
7
|
const { utf8DecodeWithoutBOM } = require("./encoding");
|
|
6
|
-
const { percentDecodeString, utf8PercentEncodeCodePoint, utf8PercentEncodeString,
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
const { percentDecodeString, utf8PercentEncodeCodePoint, utf8PercentEncodeString,
|
|
9
|
+
isC0ControlPercentEncode, isFragmentPercentEncode,
|
|
10
|
+
extraQueryPercentEncodeChars, extraSpecialQueryPercentEncodeChars,
|
|
11
|
+
isPathPercentEncode, isUserinfoPercentEncode } = require("./percent-encoding");
|
|
9
12
|
|
|
10
13
|
function p(char) {
|
|
11
14
|
return char.codePointAt(0);
|
|
@@ -498,11 +501,11 @@ function isNormalizedWindowsDriveLetter(string) {
|
|
|
498
501
|
return /^[A-Za-z]:$/u.test(string);
|
|
499
502
|
}
|
|
500
503
|
|
|
501
|
-
function URLStateMachine(input, base,
|
|
504
|
+
function URLStateMachine(input, base, encoding, url, stateOverride) {
|
|
502
505
|
this.pointer = 0;
|
|
503
506
|
this.input = input;
|
|
504
507
|
this.base = base || null;
|
|
505
|
-
this.
|
|
508
|
+
this.encoding = encoding || "utf-8";
|
|
506
509
|
this.stateOverride = stateOverride;
|
|
507
510
|
this.url = url;
|
|
508
511
|
this.failure = false;
|
|
@@ -1092,12 +1095,16 @@ URLStateMachine.prototype["parse opaque path"] = function parseOpaquePath(c) {
|
|
|
1092
1095
|
|
|
1093
1096
|
URLStateMachine.prototype["parse query"] = function parseQuery(c, cStr) {
|
|
1094
1097
|
if (!isSpecial(this.url) || this.url.scheme === "ws" || this.url.scheme === "wss") {
|
|
1095
|
-
this.
|
|
1098
|
+
this.encoding = "utf-8";
|
|
1096
1099
|
}
|
|
1097
1100
|
|
|
1098
1101
|
if ((!this.stateOverride && c === p("#")) || isNaN(c)) {
|
|
1099
|
-
const
|
|
1100
|
-
this.url.query +=
|
|
1102
|
+
const percentEncodeSet = isSpecial(this.url) ? extraSpecialQueryPercentEncodeChars : extraQueryPercentEncodeChars;
|
|
1103
|
+
this.url.query += percentEncodeAfterEncoding(
|
|
1104
|
+
this.encoding,
|
|
1105
|
+
this.buffer,
|
|
1106
|
+
percentEncodeSet
|
|
1107
|
+
);
|
|
1101
1108
|
|
|
1102
1109
|
this.buffer = "";
|
|
1103
1110
|
|
|
@@ -1241,7 +1248,7 @@ module.exports.basicURLParse = function (input, options) {
|
|
|
1241
1248
|
options = {};
|
|
1242
1249
|
}
|
|
1243
1250
|
|
|
1244
|
-
const usm = new URLStateMachine(input, options.baseURL, options.
|
|
1251
|
+
const usm = new URLStateMachine(input, options.baseURL, options.encoding, options.url, options.stateOverride);
|
|
1245
1252
|
if (usm.failure) {
|
|
1246
1253
|
return null;
|
|
1247
1254
|
}
|
|
@@ -1273,5 +1280,5 @@ module.exports.parseURL = function (input, options) {
|
|
|
1273
1280
|
}
|
|
1274
1281
|
|
|
1275
1282
|
// We don't handle blobs, so this just delegates:
|
|
1276
|
-
return module.exports.basicURLParse(input, { baseURL: options.baseURL,
|
|
1283
|
+
return module.exports.basicURLParse(input, { baseURL: options.baseURL, encoding: options.encoding });
|
|
1277
1284
|
};
|
package/lib/utils.js
CHANGED
|
@@ -110,11 +110,22 @@ function isArrayIndexPropName(P) {
|
|
|
110
110
|
return true;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
const
|
|
113
|
+
const arrayBufferByteLengthGetter =
|
|
114
114
|
Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, "byteLength").get;
|
|
115
115
|
function isArrayBuffer(value) {
|
|
116
116
|
try {
|
|
117
|
-
|
|
117
|
+
arrayBufferByteLengthGetter.call(value);
|
|
118
|
+
return true;
|
|
119
|
+
} catch {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const sharedArrayBufferByteLengthGetter =
|
|
125
|
+
Object.getOwnPropertyDescriptor(SharedArrayBuffer.prototype, "byteLength").get;
|
|
126
|
+
function isSharedArrayBuffer(value) {
|
|
127
|
+
try {
|
|
128
|
+
sharedArrayBufferByteLengthGetter.call(value);
|
|
118
129
|
return true;
|
|
119
130
|
} catch {
|
|
120
131
|
return false;
|
|
@@ -219,6 +230,7 @@ module.exports = exports = {
|
|
|
219
230
|
tryImplForWrapper,
|
|
220
231
|
iterInternalSymbol,
|
|
221
232
|
isArrayBuffer,
|
|
233
|
+
isSharedArrayBuffer,
|
|
222
234
|
isArrayIndexPropName,
|
|
223
235
|
supportsPropertyIndex,
|
|
224
236
|
supportedPropertyIndices,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "whatwg-url",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "16.0.1",
|
|
4
4
|
"description": "An implementation of the WHATWG URL Standard's URL API and parsing machinery",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -15,20 +15,21 @@
|
|
|
15
15
|
"url": "git+https://github.com/jsdom/whatwg-url.git"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
+
"@exodus/bytes": "^1.11.0",
|
|
18
19
|
"tr46": "^6.0.0",
|
|
19
|
-
"webidl-conversions": "^8.0.
|
|
20
|
+
"webidl-conversions": "^8.0.1"
|
|
20
21
|
},
|
|
21
22
|
"devDependencies": {
|
|
22
|
-
"@domenic/eslint-config": "^4.0
|
|
23
|
-
"
|
|
23
|
+
"@domenic/eslint-config": "^4.1.0",
|
|
24
|
+
"tinybench": "^6.0.0",
|
|
24
25
|
"c8": "^10.1.3",
|
|
25
|
-
"esbuild": "^0.
|
|
26
|
-
"eslint": "^9.
|
|
27
|
-
"globals": "^
|
|
28
|
-
"webidl2js": "^19.
|
|
26
|
+
"esbuild": "^0.27.2",
|
|
27
|
+
"eslint": "^9.39.2",
|
|
28
|
+
"globals": "^17.3.0",
|
|
29
|
+
"webidl2js": "^19.1.0"
|
|
29
30
|
},
|
|
30
31
|
"engines": {
|
|
31
|
-
"node": ">=
|
|
32
|
+
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
|
|
32
33
|
},
|
|
33
34
|
"scripts": {
|
|
34
35
|
"coverage": "c8 node --test --experimental-test-coverage test/*.js",
|