Skip to content

Commit a8971f8

Browse files
committed
url: support non-special URLs
Fixes: #34899 Refs: whatwg/url#505 Refs: web-platform-tests/wpt#25113 PR-URL: #34925 Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 770ad3a commit a8971f8

File tree

8 files changed

+279
-20
lines changed

8 files changed

+279
-20
lines changed

lib/internal/url.js

+11-2
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ ObjectDefineProperties(URL.prototype, {
401401
...options
402402
};
403403
const ctx = this[context];
404+
// https://url.spec.whatwg.org/#url-serializing
404405
let ret = ctx.scheme;
405406
if (ctx.host !== null) {
406407
ret += '//';
@@ -420,8 +421,16 @@ ObjectDefineProperties(URL.prototype, {
420421
} else if (ctx.scheme === 'file:') {
421422
ret += '//';
422423
}
423-
if (this.pathname)
424-
ret += this.pathname;
424+
if (this[cannotBeBase]) {
425+
ret += ctx.path[0];
426+
} else {
427+
if (ctx.host === null && ctx.path.length > 1 && ctx.path[0] === '') {
428+
ret += '/.';
429+
}
430+
for (const segment of ctx.path) {
431+
ret += '/' + segment;
432+
}
433+
}
425434
if (options.search && ctx.query !== null)
426435
ret += `?${ctx.query}`;
427436
if (options.fragment && ctx.fragment !== null)

test/fixtures/wpt/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ Last update:
1313
- console: https://github.com/web-platform-tests/wpt/tree/3b1f72e99a/console
1414
- encoding: https://github.com/web-platform-tests/wpt/tree/11e6941923/encoding
1515
- url: https://github.com/web-platform-tests/wpt/tree/551c9d604f/url
16-
- resources: https://github.com/web-platform-tests/wpt/tree/55e9dc7f5e/resources
17-
- interfaces: https://github.com/web-platform-tests/wpt/tree/4471cda31b/interfaces
16+
- resources: https://github.com/web-platform-tests/wpt/tree/1d14e821b9/resources
17+
- interfaces: https://github.com/web-platform-tests/wpt/tree/15e47f779c/interfaces
1818
- html/webappapis/microtask-queuing: https://github.com/web-platform-tests/wpt/tree/2c5c3c4c27/html/webappapis/microtask-queuing
1919
- html/webappapis/timers: https://github.com/web-platform-tests/wpt/tree/264f12bc7b/html/webappapis/timers
2020
- hr-time: https://github.com/web-platform-tests/wpt/tree/a5d1774ecf/hr-time

test/fixtures/wpt/interfaces/encoding.idl

-5
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,6 @@ interface TextEncoder {
4444
};
4545
TextEncoder includes TextEncoderCommon;
4646

47-
interface mixin GenericTransformStream {
48-
readonly attribute ReadableStream readable;
49-
readonly attribute WritableStream writable;
50-
};
51-
5247
[Exposed=(Window,Worker)]
5348
interface TextDecoderStream {
5449
constructor(optional DOMString label = "utf-8", optional TextDecoderOptions options = {});

test/fixtures/wpt/interfaces/html.idl

+1-1
Original file line numberDiff line numberDiff line change
@@ -1552,7 +1552,7 @@ OffscreenCanvasRenderingContext2D includes CanvasPath;
15521552
interface CustomElementRegistry {
15531553
[CEReactions] undefined define(DOMString name, CustomElementConstructor constructor, optional ElementDefinitionOptions options = {});
15541554
(CustomElementConstructor or undefined) get(DOMString name);
1555-
Promise<undefined> whenDefined(DOMString name);
1555+
Promise<CustomElementConstructor> whenDefined(DOMString name);
15561556
[CEReactions] undefined upgrade(Node root);
15571557
};
15581558

test/fixtures/wpt/resources/test-only-api.js

+23-7
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,14 @@ function loadScript(path) {
4747
* Only call this function if isChromiumBased === true.
4848
*
4949
* @param {Array.<string>} resources - A list of scripts to load: Mojo JS
50-
* bindings should be of the form '/gen/../*.mojom.js', the ordering of which
51-
* does not matter. Do not include mojo_bindings.js in this list.
50+
* bindings should be of the form '/gen/../*.mojom.js' or
51+
* '/gen/../*.mojom-lite.js' (requires `lite` to be true); the order does not
52+
* matter. Do not include 'mojo_bindings.js' or 'mojo_bindings_lite.js'.
53+
* @param {boolean=} lite - Whether the lite bindings (*.mojom-lite.js) are used
54+
* (default is false).
5255
* @returns {Promise}
5356
*/
54-
async function loadMojoResources(resources) {
57+
async function loadMojoResources(resources, lite = false) {
5558
if (!isChromiumBased) {
5659
throw new Error('MojoJS not enabled; start Chrome with --enable-blink-features=MojoJS,MojoJSTest');
5760
}
@@ -70,13 +73,26 @@ async function loadMojoResources(resources) {
7073
if (path.endsWith('/mojo_bindings.js')) {
7174
throw new Error('Do not load mojo_bindings.js explicitly.');
7275
}
73-
if (! /^\/gen\/.*\.mojom\.js$/.test(path)) {
74-
throw new Error(`Unrecognized resource path: ${path}`);
76+
if (path.endsWith('/mojo_bindings_lite.js')) {
77+
throw new Error('Do not load mojo_bindings_lite.js explicitly.');
78+
}
79+
if (lite) {
80+
if (! /^\/gen\/.*\.mojom-lite\.js$/.test(path)) {
81+
throw new Error(`Unrecognized resource path: ${path}`);
82+
}
83+
} else {
84+
if (! /^\/gen\/.*\.mojom\.js$/.test(path)) {
85+
throw new Error(`Unrecognized resource path: ${path}`);
86+
}
7587
}
7688
}
7789

78-
await loadScript(genPrefix + '/gen/layout_test_data/mojo/public/js/mojo_bindings.js');
79-
mojo.config.autoLoadMojomDeps = false;
90+
if (lite) {
91+
await loadScript(genPrefix + '/gen/layout_test_data/mojo/public/js/mojo_bindings_lite.js');
92+
} else {
93+
await loadScript(genPrefix + '/gen/layout_test_data/mojo/public/js/mojo_bindings.js');
94+
mojo.config.autoLoadMojomDeps = false;
95+
}
8096

8197
for (const path of resources) {
8298
await loadScript(genPrefix + path);

test/fixtures/wpt/url/resources/setters_tests.json

+55
Original file line numberDiff line numberDiff line change
@@ -1324,6 +1324,27 @@
13241324
"hostname": "test",
13251325
"port": "12"
13261326
}
1327+
},
1328+
{
1329+
"comment": "Drop /. from path",
1330+
"href": "non-spec:/.//p",
1331+
"new_value": "h",
1332+
"expected": {
1333+
"href": "non-spec://h//p",
1334+
"host": "h",
1335+
"hostname": "h",
1336+
"pathname": "//p"
1337+
}
1338+
},
1339+
{
1340+
"href": "non-spec:/.//p",
1341+
"new_value": "",
1342+
"expected": {
1343+
"href": "non-spec:////p",
1344+
"host": "",
1345+
"hostname": "",
1346+
"pathname": "//p"
1347+
}
13271348
}
13281349
],
13291350
"port": [
@@ -1672,6 +1693,40 @@
16721693
"href": "file:///",
16731694
"pathname": "/"
16741695
}
1696+
},
1697+
{
1698+
"comment": "Serialize /. in path",
1699+
"href": "non-spec:/",
1700+
"new_value": "/.//p",
1701+
"expected": {
1702+
"href": "non-spec:/.//p",
1703+
"pathname": "//p"
1704+
}
1705+
},
1706+
{
1707+
"href": "non-spec:/",
1708+
"new_value": "/..//p",
1709+
"expected": {
1710+
"href": "non-spec:/.//p",
1711+
"pathname": "//p"
1712+
}
1713+
},
1714+
{
1715+
"href": "non-spec:/",
1716+
"new_value": "//p",
1717+
"expected": {
1718+
"href": "non-spec:/.//p",
1719+
"pathname": "//p"
1720+
}
1721+
},
1722+
{
1723+
"comment": "Drop /. from path",
1724+
"href": "non-spec:/.//",
1725+
"new_value": "p",
1726+
"expected": {
1727+
"href": "non-spec:/p",
1728+
"pathname": "/p"
1729+
}
16751730
}
16761731
],
16771732
"search": [

test/fixtures/wpt/url/resources/urltestdata.json

+184
Original file line numberDiff line numberDiff line change
@@ -6445,6 +6445,190 @@
64456445
"search": "",
64466446
"hash": ""
64476447
},
6448+
"Serialize /. in path",
6449+
{
6450+
"input": "non-spec:/.//",
6451+
"base": "about:blank",
6452+
"href": "non-spec:/.//",
6453+
"protocol": "non-spec:",
6454+
"username": "",
6455+
"password": "",
6456+
"host": "",
6457+
"hostname": "",
6458+
"port": "",
6459+
"pathname": "//",
6460+
"search": "",
6461+
"hash": ""
6462+
},
6463+
{
6464+
"input": "non-spec:/..//",
6465+
"base": "about:blank",
6466+
"href": "non-spec:/.//",
6467+
"protocol": "non-spec:",
6468+
"username": "",
6469+
"password": "",
6470+
"host": "",
6471+
"hostname": "",
6472+
"port": "",
6473+
"pathname": "//",
6474+
"search": "",
6475+
"hash": ""
6476+
},
6477+
{
6478+
"input": "non-spec:/a/..//",
6479+
"base": "about:blank",
6480+
"href": "non-spec:/.//",
6481+
"protocol": "non-spec:",
6482+
"username": "",
6483+
"password": "",
6484+
"host": "",
6485+
"hostname": "",
6486+
"port": "",
6487+
"pathname": "//",
6488+
"search": "",
6489+
"hash": ""
6490+
},
6491+
{
6492+
"input": "non-spec:/.//path",
6493+
"base": "about:blank",
6494+
"href": "non-spec:/.//path",
6495+
"protocol": "non-spec:",
6496+
"username": "",
6497+
"password": "",
6498+
"host": "",
6499+
"hostname": "",
6500+
"port": "",
6501+
"pathname": "//path",
6502+
"search": "",
6503+
"hash": ""
6504+
},
6505+
{
6506+
"input": "non-spec:/..//path",
6507+
"base": "about:blank",
6508+
"href": "non-spec:/.//path",
6509+
"protocol": "non-spec:",
6510+
"username": "",
6511+
"password": "",
6512+
"host": "",
6513+
"hostname": "",
6514+
"port": "",
6515+
"pathname": "//path",
6516+
"search": "",
6517+
"hash": ""
6518+
},
6519+
{
6520+
"input": "non-spec:/a/..//path",
6521+
"base": "about:blank",
6522+
"href": "non-spec:/.//path",
6523+
"protocol": "non-spec:",
6524+
"username": "",
6525+
"password": "",
6526+
"host": "",
6527+
"hostname": "",
6528+
"port": "",
6529+
"pathname": "//path",
6530+
"search": "",
6531+
"hash": ""
6532+
},
6533+
{
6534+
"input": "/.//path",
6535+
"base": "non-spec:/p",
6536+
"href": "non-spec:/.//path",
6537+
"protocol": "non-spec:",
6538+
"username": "",
6539+
"password": "",
6540+
"host": "",
6541+
"hostname": "",
6542+
"port": "",
6543+
"pathname": "//path",
6544+
"search": "",
6545+
"hash": ""
6546+
},
6547+
{
6548+
"input": "/..//path",
6549+
"base": "non-spec:/p",
6550+
"href": "non-spec:/.//path",
6551+
"protocol": "non-spec:",
6552+
"username": "",
6553+
"password": "",
6554+
"host": "",
6555+
"hostname": "",
6556+
"port": "",
6557+
"pathname": "//path",
6558+
"search": "",
6559+
"hash": ""
6560+
},
6561+
{
6562+
"input": "..//path",
6563+
"base": "non-spec:/p",
6564+
"href": "non-spec:/.//path",
6565+
"protocol": "non-spec:",
6566+
"username": "",
6567+
"password": "",
6568+
"host": "",
6569+
"hostname": "",
6570+
"port": "",
6571+
"pathname": "//path",
6572+
"search": "",
6573+
"hash": ""
6574+
},
6575+
{
6576+
"input": "a/..//path",
6577+
"base": "non-spec:/p",
6578+
"href": "non-spec:/.//path",
6579+
"protocol": "non-spec:",
6580+
"username": "",
6581+
"password": "",
6582+
"host": "",
6583+
"hostname": "",
6584+
"port": "",
6585+
"pathname": "//path",
6586+
"search": "",
6587+
"hash": ""
6588+
},
6589+
{
6590+
"input": "",
6591+
"base": "non-spec:/..//p",
6592+
"href": "non-spec:/.//p",
6593+
"protocol": "non-spec:",
6594+
"username": "",
6595+
"password": "",
6596+
"host": "",
6597+
"hostname": "",
6598+
"port": "",
6599+
"pathname": "//p",
6600+
"search": "",
6601+
"hash": ""
6602+
},
6603+
{
6604+
"input": "path",
6605+
"base": "non-spec:/..//p",
6606+
"href": "non-spec:/.//path",
6607+
"protocol": "non-spec:",
6608+
"username": "",
6609+
"password": "",
6610+
"host": "",
6611+
"hostname": "",
6612+
"port": "",
6613+
"pathname": "//path",
6614+
"search": "",
6615+
"hash": ""
6616+
},
6617+
"Do not serialize /. in path",
6618+
{
6619+
"input": "../path",
6620+
"base": "non-spec:/.//p",
6621+
"href": "non-spec:/path",
6622+
"protocol": "non-spec:",
6623+
"username": "",
6624+
"password": "",
6625+
"host": "",
6626+
"hostname": "",
6627+
"port": "",
6628+
"pathname": "/path",
6629+
"search": "",
6630+
"hash": ""
6631+
},
64486632
"# percent encoded hosts in non-special-URLs",
64496633
{
64506634
"input": "non-special://%E2%80%A0/",

test/fixtures/wpt/versions.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88
"path": "encoding"
99
},
1010
"url": {
11-
"commit": "6c74b7e43c9a1f6dc3dc529e427e2ef96152409e",
11+
"commit": "551c9d604fb8b97d3f8c65793bb047d15baddbc2",
1212
"path": "url"
1313
},
1414
"resources": {
15-
"commit": "55e9dc7f5e74bb5bd189920ef348169f795ab71c",
15+
"commit": "1d14e821b9586f250e6a31d550504e3d16a05ae7",
1616
"path": "resources"
1717
},
1818
"interfaces": {
19-
"commit": "4471cda31be9e299ba0546e115f84d5010ed8136",
19+
"commit": "15e47f779cf61555669b0f67e2c49b9c830b9019",
2020
"path": "interfaces"
2121
},
2222
"html/webappapis/microtask-queuing": {

0 commit comments

Comments
 (0)