diff options
author | Kenta Moriuchi <moriken@kimamass.com> | 2024-04-17 00:11:57 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-16 17:11:57 +0200 |
commit | 1e26508579e1d102f462e58168398795270e7e61 (patch) | |
tree | 83990d3a158fa18dd5c6856716a95acf7f0bc3fd /ext/url | |
parent | 50223c5c532332f4a296b12b027f85429f529690 (diff) |
feat(ext/url): add `URL.parse` (#23318)
Closes #23069
Diffstat (limited to 'ext/url')
-rw-r--r-- | ext/url/00_url.js | 44 | ||||
-rw-r--r-- | ext/url/lib.deno_url.d.ts | 1 |
2 files changed, 43 insertions, 2 deletions
diff --git a/ext/url/00_url.js b/ext/url/00_url.js index 3b081218b..577caba90 100644 --- a/ext/url/00_url.js +++ b/ext/url/00_url.js @@ -351,17 +351,29 @@ function trim(s) { // Represents a "no port" value. A port in URL cannot be greater than 2^16 - 1 const NO_PORT = 65536; +const skipInit = Symbol(); const componentsBuf = new Uint32Array(8); + class URL { + /** @type {URLSearchParams|null} */ #queryObject = null; + /** @type {string} */ #serialization; + /** @type {number} */ #schemeEnd; + /** @type {number} */ #usernameEnd; + /** @type {number} */ #hostStart; + /** @type {number} */ #hostEnd; + /** @type {number} */ #port; + /** @type {number} */ #pathStart; + /** @type {number} */ #queryStart; + /** @type {number} */ #fragmentStart; [_updateUrlSearch](value) { @@ -378,14 +390,18 @@ class URL { * @param {string} [base] */ constructor(url, base = undefined) { + // skip initialization for URL.parse + if (url === skipInit) { + return; + } const prefix = "Failed to construct 'URL'"; webidl.requiredArguments(arguments.length, 1, prefix); url = webidl.converters.DOMString(url, prefix, "Argument 1"); if (base !== undefined) { base = webidl.converters.DOMString(base, prefix, "Argument 2"); } - this[webidl.brand] = webidl.brand; const status = opUrlParse(url, base); + this[webidl.brand] = webidl.brand; this.#serialization = getSerialization(status, url, base); this.#updateComponents(); } @@ -394,6 +410,30 @@ class URL { * @param {string} url * @param {string} [base] */ + static parse(url, base = undefined) { + const prefix = "Failed to execute 'URL.parse'"; + webidl.requiredArguments(arguments.length, 1, prefix); + url = webidl.converters.DOMString(url, prefix, "Argument 1"); + if (base !== undefined) { + base = webidl.converters.DOMString(base, prefix, "Argument 2"); + } + const status = opUrlParse(url, base); + if (status !== 0 && status !== 1) { + return null; + } + // If initialized with webidl.createBranded, private properties are not be accessible, + // so it is passed through the constructor + const self = new this(skipInit); + self[webidl.brand] = webidl.brand; + self.#serialization = getSerialization(status, url, base); + self.#updateComponents(); + return self; + } + + /** + * @param {string} url + * @param {string} [base] + */ static canParse(url, base = undefined) { const prefix = "Failed to execute 'URL.canParse'"; webidl.requiredArguments(arguments.length, 1, prefix); @@ -799,7 +839,7 @@ class URL { } } - /** @return {string} */ + /** @return {URLSearchParams} */ get searchParams() { if (this.#queryObject == null) { this.#queryObject = new URLSearchParams(this.search); diff --git a/ext/url/lib.deno_url.d.ts b/ext/url/lib.deno_url.d.ts index a184ee4a2..0ade8c85a 100644 --- a/ext/url/lib.deno_url.d.ts +++ b/ext/url/lib.deno_url.d.ts @@ -195,6 +195,7 @@ declare interface URL { declare var URL: { readonly prototype: URL; new (url: string | URL, base?: string | URL): URL; + parse(url: string | URL, base?: string | URL): URL | null; canParse(url: string | URL, base?: string | URL): boolean; createObjectURL(blob: Blob): string; revokeObjectURL(url: string): void; |