1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

feat(ext/url): add URL.parse (#23318)

Closes #23069
This commit is contained in:
Kenta Moriuchi 2024-04-17 00:11:57 +09:00 committed by GitHub
parent 50223c5c53
commit 1e26508579
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 1857 additions and 8 deletions

View file

@ -351,17 +351,29 @@ function trim(s) {
// Represents a "no port" value. A port in URL cannot be greater than 2^16 - 1 // Represents a "no port" value. A port in URL cannot be greater than 2^16 - 1
const NO_PORT = 65536; const NO_PORT = 65536;
const skipInit = Symbol();
const componentsBuf = new Uint32Array(8); const componentsBuf = new Uint32Array(8);
class URL { class URL {
/** @type {URLSearchParams|null} */
#queryObject = null; #queryObject = null;
/** @type {string} */
#serialization; #serialization;
/** @type {number} */
#schemeEnd; #schemeEnd;
/** @type {number} */
#usernameEnd; #usernameEnd;
/** @type {number} */
#hostStart; #hostStart;
/** @type {number} */
#hostEnd; #hostEnd;
/** @type {number} */
#port; #port;
/** @type {number} */
#pathStart; #pathStart;
/** @type {number} */
#queryStart; #queryStart;
/** @type {number} */
#fragmentStart; #fragmentStart;
[_updateUrlSearch](value) { [_updateUrlSearch](value) {
@ -378,18 +390,46 @@ class URL {
* @param {string} [base] * @param {string} [base]
*/ */
constructor(url, base = undefined) { constructor(url, base = undefined) {
// skip initialization for URL.parse
if (url === skipInit) {
return;
}
const prefix = "Failed to construct 'URL'"; const prefix = "Failed to construct 'URL'";
webidl.requiredArguments(arguments.length, 1, prefix); webidl.requiredArguments(arguments.length, 1, prefix);
url = webidl.converters.DOMString(url, prefix, "Argument 1"); url = webidl.converters.DOMString(url, prefix, "Argument 1");
if (base !== undefined) { if (base !== undefined) {
base = webidl.converters.DOMString(base, prefix, "Argument 2"); base = webidl.converters.DOMString(base, prefix, "Argument 2");
} }
this[webidl.brand] = webidl.brand;
const status = opUrlParse(url, base); const status = opUrlParse(url, base);
this[webidl.brand] = webidl.brand;
this.#serialization = getSerialization(status, url, base); this.#serialization = getSerialization(status, url, base);
this.#updateComponents(); this.#updateComponents();
} }
/**
* @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} url
* @param {string} [base] * @param {string} [base]
@ -799,7 +839,7 @@ class URL {
} }
} }
/** @return {string} */ /** @return {URLSearchParams} */
get searchParams() { get searchParams() {
if (this.#queryObject == null) { if (this.#queryObject == null) {
this.#queryObject = new URLSearchParams(this.search); this.#queryObject = new URLSearchParams(this.search);

View file

@ -195,6 +195,7 @@ declare interface URL {
declare var URL: { declare var URL: {
readonly prototype: URL; readonly prototype: URL;
new (url: string | URL, base?: string | URL): 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; canParse(url: string | URL, base?: string | URL): boolean;
createObjectURL(blob: Blob): string; createObjectURL(blob: Blob): string;
revokeObjectURL(url: string): void; revokeObjectURL(url: string): void;

File diff suppressed because it is too large Load diff