From 2c8cffc65556450665191fc90b01b57dd63d2837 Mon Sep 17 00:00:00 2001 From: Tom Jenkinson Date: Sat, 10 Jul 2021 11:26:23 +0100 Subject: [PATCH] document differences to `URL()` and 'special scheme' --- README.md | 8 ++++++++ test/__snapshots__/url-toolkit.js.snap | 22 ++++++++++++++++++++++ test/url-toolkit.js | 8 ++++++++ 3 files changed, 38 insertions(+) diff --git a/README.md b/README.md index 9ce6389..eeaadb6 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,14 @@ Lightweight library to build an absolute URL from a base URL and a relative URL, written from [the spec (RFC 1808)](https://tools.ietf.org/html/rfc1808). Initially part of [HLS.JS](https://github.com/dailymotion/hls.js). +## Differences to JS `URL()` + +The JS [URL()](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) function also lets you calculate a new URL from a base and relative one. + +That uses the [URL Living Standard](https://url.spec.whatwg.org/) which is slightly different to [RFC 1808](https://tools.ietf.org/html/rfc1808) that this library implements. + +One of the key differences is that the [URL Living Standard](https://url.spec.whatwg.org/) has the concept of a ['special url'](https://url.spec.whatwg.org/#is-special) and ['special scheme'](https://url.spec.whatwg.org/#special-scheme). For these special URL's, such as a URL with the `http` scheme, they normalise them in a way that results in `http:///example.com/something` becoming `http://example.com/something`. This library does not do that and [`parseURL()`](#parseurlurl) would give you `//` as the `netLoc` and `/example.com` as the path. + ## Methods ### `buildAbsoluteURL(baseURL, relativeURL, opts={})` diff --git a/test/__snapshots__/url-toolkit.js.snap b/test/__snapshots__/url-toolkit.js.snap index 54b568c..0b40631 100644 --- a/test/__snapshots__/url-toolkit.js.snap +++ b/test/__snapshots__/url-toolkit.js.snap @@ -462,6 +462,28 @@ Object { } `; +exports[`url toolkit works with a selection of valid urls "http:///example.com/a/" + "../../b" {} 1`] = ` +Object { + "fragment": "", + "netLoc": "//", + "params": "", + "path": "/example.com/a/", + "query": "", + "scheme": "http:", +} +`; + +exports[`url toolkit works with a selection of valid urls "http:///example.com/a/" + "../../b" {} 2`] = ` +Object { + "fragment": "", + "netLoc": "", + "params": "", + "path": "../../b", + "query": "", + "scheme": "", +} +`; + exports[`url toolkit works with a selection of valid urls "http://[0:0:0:0::0]/a/b.c" + "d" {} 1`] = ` Object { "fragment": "", diff --git a/test/url-toolkit.js b/test/url-toolkit.js index 020b377..5aa7883 100644 --- a/test/url-toolkit.js +++ b/test/url-toolkit.js @@ -294,6 +294,14 @@ describe('url toolkit', () => { test('http://[0:0:0:0::0]/a/b.c', 'd', 'http://[0:0:0:0::0]/a/d'); test('http://example.com/', 'a#\nb', 'http://example.com/a#\nb'); + + // in the URL living standard (https://url.spec.whatwg.org/) + // `http` is a 'special scheme', and that results in + // the `///` becoming `//`, meaning `netLoc` would essentially be + // `//example.com` instead of `//` + // This library is specifically RFC 1808, which does not have these + // special cases. + test('http:///example.com/a/', '../../b', 'http:///b'); }); });