5 <title>Test URL API
</title>
6 <script src=
"/tests/SimpleTest/SimpleTest.js"></script>
7 <link rel=
"stylesheet" type=
"text/css" href=
"/tests/SimpleTest/test.css"/>
10 <a target=
"_blank" href=
"https://bugzilla.mozilla.org/show_bug.cgi?id=887364">Mozilla Bug
887364</a>
11 <a target=
"_blank" href=
"https://bugzilla.mozilla.org/show_bug.cgi?id=991471">Mozilla Bug
991471</a>
12 <a target=
"_blank" href=
"https://bugzilla.mozilla.org/show_bug.cgi?id=996055">Mozilla Bug
996055</a>
14 <div id=
"content" style=
"display: none">
15 <iframe name=
"x" id=
"x"></iframe>
16 <iframe name=
"y" id=
"y"></iframe>
22 /** Test for Bug 887364 **/
23 ok("URL" in window
, "window.URL exists");
26 { url
: "http://www.abc.com",
29 href
: "http://www.abc.com/",
30 origin
: "http://www.abc.com",
35 hostname
: "www.abc.com",
41 { url
: "ftp://auser:apw@www.abc.com",
44 href
: "ftp://auser:apw@www.abc.com/",
45 origin
: "ftp://www.abc.com",
50 hostname
: "www.abc.com",
56 { url
: "http://www.abc.com:90/apath/",
59 href
: "http://www.abc.com:90/apath/",
60 origin
: "http://www.abc.com:90",
64 host
: "www.abc.com:90",
65 hostname
: "www.abc.com",
71 { url
: "http://www.abc.com/apath/afile.txt#ahash",
74 href
: "http://www.abc.com/apath/afile.txt#ahash",
75 origin
: "http://www.abc.com",
80 hostname
: "www.abc.com",
82 pathname
: "/apath/afile.txt",
86 { url
: "http://example.com/?test#hash",
89 href
: "http://example.com/?test#hash",
90 origin
: "http://example.com",
95 hostname
: "example.com",
101 { url
: "http://example.com/?test",
104 href
: "http://example.com/?test",
105 origin
: "http://example.com",
110 hostname
: "example.com",
116 { url
: "http://example.com/carrot#question%3f",
119 hash
: "#question%3f",
121 { url
: "https://example.com:4443?",
130 { url
: "http://www.abc.com/apath/afile.txt#ahash?asearch",
133 href
: "http://www.abc.com/apath/afile.txt#ahash?asearch",
135 pathname
: "/apath/afile.txt",
136 hash
: "#ahash?asearch",
139 { url
: "http://www.abc.com/apath/afile.txt?asearch#ahash",
142 href
: "http://www.abc.com/apath/afile.txt?asearch#ahash",
144 pathname
: "/apath/afile.txt",
148 { url
: "http://abc.com/apath/afile.txt?#ahash",
151 pathname
: "/apath/afile.txt",
155 { url
: "http://auser:apassword@www.abc.com:90/apath/afile.txt?asearch#ahash",
160 password
: "apassword",
161 host
: "www.abc.com:90",
162 hostname
: "www.abc.com",
164 pathname
: "/apath/afile.txt",
167 origin
: "http://www.abc.com:90",
171 base
: "www.test.org",
182 { url
: "ftp://ftp.something.net",
187 { url
: "file:///tmp/file",
192 { url
: "gopher://gopher.something.net",
196 expectedChangedProtocol
: "https:",
198 { url
: "ws://ws.something.net",
203 { url
: "wss://ws.something.net",
208 { url
: "foo://foo.something.net",
212 expectedChangedProtocol
: "https:",
215 { url
: "about:blank",
223 { url
: "foo:bar?what#yeah",
233 { url
: "http://sub2.xn--lt-uia.mochi.test:8888/foo",
236 href
: "http://sub2.xn--lt-uia.mochi.test:8888/foo",
237 origin
: "http://sub2.xn--lt-uia.mochi.test:8888",
241 host
: "sub2.xn--lt-uia.mochi.test:8888",
242 hostname
: "sub2.xn--lt-uia.mochi.test",
248 { url
: "http://sub2.ält.mochi.test:8888/foo",
251 href
: "http://sub2.xn--lt-uia.mochi.test:8888/foo",
252 origin
: "http://sub2.xn--lt-uia.mochi.test:8888",
256 host
: "sub2.xn--lt-uia.mochi.test:8888",
257 hostname
: "sub2.xn--lt-uia.mochi.test",
265 while (tests
.length
) {
266 var test
= tests
.shift();
272 url
= new URL(test
.url
, test
.base
);
274 url
= new URL(test
.url
);
280 is(test
.error
, error
, "Error creating URL");
285 if ("href" in test
) is(url
.href
, test
.href
, "href");
286 if ("origin" in test
) is(url
.origin
, test
.origin
, "origin");
287 if ("protocol" in test
) is(url
.protocol
, test
.protocol
, "protocol");
288 if ("username" in test
) is(url
.username
, test
.username
, "username");
289 if ("password" in test
) is(url
.password
, test
.password
, "password");
290 if ("host" in test
) is(url
.host
, test
.host
, "host");
291 if ("hostname" in test
) is(url
.hostname
, test
.hostname
, "hostname");
292 if ("port" in test
) is(url
.port
, test
.port
, "port");
293 if ("pathname" in test
) is(url
.pathname
, test
.pathname
, "pathname");
294 if ("search" in test
) is(url
.search
, test
.search
, "search");
295 if ("hash" in test
) is(url
.hash
, test
.hash
, "hash");
298 let uri
= SpecialPowers
.wrap(url
).URI
;
299 is(url
.href
, uri
.spec
, "Conversion to nsIURI");
300 is(SpecialPowers
.wrap(URL
).fromURI(uri
).href
, uri
.spec
, "Conversion from nsIURI");
303 if ("skip_setters" in test
&& test
.skip_setters
=== false) {
304 info("Skip setter methods for URL: " + test
);
308 url
= new URL("https://www.example.net/what#foo?bar");
309 ok(url
, "Url exists!");
311 if ("href" in test
) url
.href
= test
.href
;
312 if ("protocol" in test
) url
.protocol
= test
.protocol
;
313 if ("username" in test
&& test
.username
) url
.username
= test
.username
;
314 if ("password" in test
&& test
.password
) url
.password
= test
.password
;
315 if ("host" in test
) url
.host
= test
.host
;
316 if ("hostname" in test
) url
.hostname
= test
.hostname
;
317 if ("port" in test
) url
.port
= test
.port
;
318 if ("pathname" in test
) url
.pathname
= test
.pathname
;
319 if ("search" in test
) url
.search
= test
.search
;
320 if ("hash" in test
) url
.hash
= test
.hash
;
322 if ("href" in test
) is(url
.href
, test
.href
, "href");
323 if ("origin" in test
) is(url
.origin
, test
.origin
, "origin");
324 if ("expectedChangedProtocol" in test
) is(url
.protocol
, test
.expectedChangedProtocol
, "protocol");
325 else if ("protocol" in test
) is(url
.protocol
, test
.protocol
, "protocol");
326 if ("username" in test
) is(url
.username
, test
.username
, "username");
327 if ("password" in test
) is(url
.password
, test
.password
, "password");
328 if ("host" in test
) is(url
.host
, test
.host
, "host");
329 if ("hostname" in test
) is(test
.hostname
, url
.hostname
, "hostname");
330 if ("port" in test
) is(test
.port
, url
.port
, "port");
331 if ("pathname" in test
) is(test
.pathname
, url
.pathname
, "pathname");
332 if ("search" in test
) is(test
.search
, url
.search
, "search");
333 if ("hash" in test
) is(test
.hash
, url
.hash
, "hash");
335 if ("href" in test
) is(test
.href
, url
+ "", "stringify works");
341 /** Test for Bug 991471 **/
342 var url
= new URL("http://localhost/");
344 url
.username
= "tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt";
345 url
.hostname
= "www.mozilla.org";
347 url
.hostname
= "www.mozilla.org";
348 is(url
.href
, "http://www.mozilla.org/", "No parsing error with empty host");
352 /** Test for Bug 996055 **/
353 var url
= new URL("http://localhost/");
355 is(url
.href
, "http://localhost/", "Empty hostname is ignored");
359 /** Test for Bug 960014 **/
360 var url
= new URL("http://localhost/");
361 url
.hostname
= "[2001::1]";
362 is(url
.hostname
, "[2001::1]", "IPv6 hostname");
363 is(url
.href
, "http://[2001::1]/");
365 url
.hostname
= "[::192.9.5.5]";
366 is(url
.hostname
, "[::c009:505]", "IPv6 hostname");
367 is(url
.href
, "http://[::c009:505]/");
369 url
= new URL("http://localhost/");
370 url
.hostname
= "[::]";
371 is(url
.hostname
, "[::]", "IPv6 hostname");
373 url
= new URL("http://localhost/");
374 url
.host
= "[2001::1]:30";
375 is(url
.hostname
, "[2001::1]", "IPv6 hostname");
376 is(url
.port
, "30", "Port");
377 is(url
.host
, "[2001::1]:30", "IPv6 host");
379 url
= new URL("http://localhost/");
380 // This should silently fail since it's missing the brackets
381 url
.hostname
= "2001::1";
382 is(url
.hostname
, "localhost", "Setting bad hostname fails");
386 var blob
= new Blob(["a"]);
387 var url
= URL
.createObjectURL(blob
);
389 var u
= new URL(url
);
390 is(u
.origin
, location
.origin
, "The URL generated from a blob URI has an origin");
394 var blob
= new Blob(["a"]);
395 var url
= URL
.createObjectURL(blob
);
397 var a
= document
.createElement("A");
399 is(a
.origin
, location
.origin
, "The 'a' element has the correct origin");
403 var blob
= new Blob(["a"]);
404 var url
= URL
.createObjectURL(blob
);
405 URL
.revokeObjectURL(url
);
406 URL
.revokeObjectURL(url
);
407 ok(true, "Calling revokeObjectURL twice should be ok");
411 URL
.revokeObjectURL("blob:something");
412 ok(true, "This should not throw.");
416 var base
= new URL("http:\\\\test.com\\path/to\\file?query\\backslash#hash\\");
417 is(base
.href
, "http://test.com/path/to/file?query\\backslash#hash\\");
419 var url
= new URL("..\\", base
);
420 is(url
.href
, "http://test.com/path/");
422 url
= new URL("\\test", base
);
423 is(url
.href
, "http://test.com/test");
425 url
= new URL("\\test\\", base
);
426 is(url
.href
, "http://test.com/test/");
428 url
= new URL("http://example.org/test", base
);
429 is(url
.href
, "http://example.org/test");
431 url
= new URL("ftp://tmp/test", base
);
432 is(url
.href
, "ftp://tmp/test");
434 url
= new URL("ftp:\\\\tmp\\test", base
);
435 is(url
.href
, "ftp://tmp/test");
439 /** Test for Bug 1275746 **/
440 SimpleTest
.doesThrow(() => { new URL("http:"); }, "http: is not a valid URL");
441 SimpleTest
.doesThrow(() => { new URL("http:///"); }, "http: is not a valid URL");
443 var url
= new URL("file:");
444 is(url
.href
, "file:///", "Parsing file: should work.");
446 url
= new URL("file:///");
447 is(url
.href
, "file:///", "Parsing file:/// should work.");
451 async
function testStrippingAndEncoding() {
452 await SpecialPowers
.pushPrefEnv({ set: [
453 ["network.url.useDefaultURI", true],
456 var url
= new URL("scheme:path/to/file?query#hash");
457 is(url
.href
, "scheme:path/to/file?query#hash");
458 is(url
.pathname
, "path/to/file");
459 is(url
.search
, "?query");
460 is(url
.hash
, "#hash");
462 // pathname cannot be overwritten.
463 url
.pathname
= "new/path?newquery#newhash";
464 is(url
.href
, "scheme:path/to/file?query#hash");
466 // don't escape '#' until we implement a spec-compliant parser.
467 url
.search
= "?newquery#newhash";
468 is(url
.href
, "scheme:path/to/file?newquery%23newhash#hash");
470 // nulls get encoded, whitespace gets stripped
471 url
= new URL("scheme:pa\0\nth/to/fi\0\nle?qu\0\nery#ha\0\nsh");
472 is(url
.href
, "scheme:pa%00th/to/fi%00le?qu%00ery#ha%00sh");
474 url
.search
= "new\0\nquery";
475 is(url
.href
, "scheme:pa%00th/to/fi%00le?new%00query#ha%00sh");
476 url
.hash
= "new\0\nhash";
477 is(url
.href
, "scheme:pa%00th/to/fi%00le?new%00query#new%00hash");
479 url
= new URL("scheme:path#hash");
480 is(url
.href
, "scheme:path#hash");
481 url
.search
= "query";
482 is(url
.href
, "scheme:path?query#hash");
484 is(url
.href
, "scheme:path?query");
485 url
.hash
= "newhash";
486 is(url
.href
, "scheme:path?query#newhash");
488 is(url
.href
, "scheme:path#newhash");
490 // we don't implement a spec-compliant parser yet.
491 // make sure we are bug compatible with existing implementations.
492 url
= new URL("data:text/html,<a href=\"http://example.org/?q\">Link</a>");
493 is(url
.href
, "data:text/html,<a href=\"http://example.org/?q\">Link</a>");
497 SimpleTest
.waitForExplicitFinish();
498 testStrippingAndEncoding();
502 var u
= new URL("http://www.example.org");
503 is(u
.toJSON(), "http://www.example.org/", "URL.toJSON()");
504 is(JSON
.stringify(u
), "\"http://www.example.org/\"", "JSON.stringify(u) works");
509 var url
= new URL("http://example.com/");
510 url
.protocol
= 'file'
511 url
.protocol
= 'resource'