summaryrefslogtreecommitdiff
path: root/cli/js/web/url_search_params.ts
diff options
context:
space:
mode:
Diffstat (limited to 'cli/js/web/url_search_params.ts')
-rw-r--r--cli/js/web/url_search_params.ts167
1 files changed, 80 insertions, 87 deletions
diff --git a/cli/js/web/url_search_params.ts b/cli/js/web/url_search_params.ts
index 8f60f2918..aad59bb8c 100644
--- a/cli/js/web/url_search_params.ts
+++ b/cli/js/web/url_search_params.ts
@@ -1,33 +1,61 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-import { URL } from "./url.ts";
-import { requiredArguments } from "./util.ts";
-
-// Returns whether o is iterable.
-// @internal
-export function isIterable<T, P extends keyof T, K extends T[P]>(
- o: T
-): o is T & Iterable<[P, K]> {
- // checks for null and undefined
- if (o == null) {
- return false;
- }
- return (
- typeof ((o as unknown) as Iterable<[P, K]>)[Symbol.iterator] === "function"
- );
+import * as domTypes from "./dom_types.ts";
+import { URL, parts } from "./url.ts";
+import { isIterable, requiredArguments } from "./util.ts";
+
+/** @internal */
+export const urls = new WeakMap<URLSearchParams, URL | null>();
+
+function handleStringInitialization(
+ searchParams: URLSearchParams,
+ init: string
+): void {
+ // Overload: USVString
+ // If init is a string and starts with U+003F (?),
+ // remove the first code point from init.
+ if (init.charCodeAt(0) === 0x003f) {
+ init = init.slice(1);
+ }
+
+ for (const pair of init.split("&")) {
+ // Empty params are ignored
+ if (pair.length === 0) {
+ continue;
+ }
+ const position = pair.indexOf("=");
+ const name = pair.slice(0, position === -1 ? pair.length : position);
+ const value = pair.slice(name.length + 1);
+ searchParams.append(decodeURIComponent(name), decodeURIComponent(value));
+ }
+}
+
+function handleArrayInitialization(
+ searchParams: URLSearchParams,
+ init: string[][] | Iterable<[string, string]>
+): void {
+ // Overload: sequence<sequence<USVString>>
+ for (const tuple of init) {
+ // If pair does not contain exactly two items, then throw a TypeError.
+ if (tuple.length !== 2) {
+ throw new TypeError(
+ "URLSearchParams.constructor tuple array argument must only contain pair elements"
+ );
+ }
+ searchParams.append(tuple[0], tuple[1]);
+ }
}
-export class URLSearchParams {
- private params: Array<[string, string]> = [];
- private url: URL | null = null;
+export class URLSearchParams implements domTypes.URLSearchParams {
+ #params: Array<[string, string]> = [];
constructor(init: string | string[][] | Record<string, string> = "") {
if (typeof init === "string") {
- this._handleStringInitialization(init);
+ handleStringInitialization(this, init);
return;
}
if (Array.isArray(init) || isIterable(init)) {
- this._handleArrayInitialization(init);
+ handleArrayInitialization(this, init);
return;
}
@@ -36,7 +64,7 @@ export class URLSearchParams {
}
if (init instanceof URLSearchParams) {
- this.params = init.params;
+ this.#params = [...init.#params];
return;
}
@@ -44,10 +72,13 @@ export class URLSearchParams {
for (const key of Object.keys(init)) {
this.append(key, init[key]);
}
+
+ urls.set(this, null);
}
- private updateSteps(): void {
- if (this.url === null) {
+ #updateSteps = (): void => {
+ const url = urls.get(this);
+ if (url == null) {
return;
}
@@ -56,35 +87,34 @@ export class URLSearchParams {
query = null;
}
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- (this.url as any)._parts.query = query;
- }
+ parts.get(url)!.query = query;
+ };
append(name: string, value: string): void {
requiredArguments("URLSearchParams.append", arguments.length, 2);
- this.params.push([String(name), String(value)]);
- this.updateSteps();
+ this.#params.push([String(name), String(value)]);
+ this.#updateSteps();
}
delete(name: string): void {
requiredArguments("URLSearchParams.delete", arguments.length, 1);
name = String(name);
let i = 0;
- while (i < this.params.length) {
- if (this.params[i][0] === name) {
- this.params.splice(i, 1);
+ while (i < this.#params.length) {
+ if (this.#params[i][0] === name) {
+ this.#params.splice(i, 1);
} else {
i++;
}
}
- this.updateSteps();
+ this.#updateSteps();
}
getAll(name: string): string[] {
requiredArguments("URLSearchParams.getAll", arguments.length, 1);
name = String(name);
const values = [];
- for (const entry of this.params) {
+ for (const entry of this.#params) {
if (entry[0] === name) {
values.push(entry[1]);
}
@@ -96,7 +126,7 @@ export class URLSearchParams {
get(name: string): string | null {
requiredArguments("URLSearchParams.get", arguments.length, 1);
name = String(name);
- for (const entry of this.params) {
+ for (const entry of this.#params) {
if (entry[0] === name) {
return entry[1];
}
@@ -108,7 +138,7 @@ export class URLSearchParams {
has(name: string): boolean {
requiredArguments("URLSearchParams.has", arguments.length, 1);
name = String(name);
- return this.params.some((entry): boolean => entry[0] === name);
+ return this.#params.some((entry) => entry[0] === name);
}
set(name: string, value: string): void {
@@ -121,14 +151,14 @@ export class URLSearchParams {
value = String(value);
let found = false;
let i = 0;
- while (i < this.params.length) {
- if (this.params[i][0] === name) {
+ while (i < this.#params.length) {
+ if (this.#params[i][0] === name) {
if (!found) {
- this.params[i][1] = value;
+ this.#params[i][1] = value;
found = true;
i++;
} else {
- this.params.splice(i, 1);
+ this.#params.splice(i, 1);
}
} else {
i++;
@@ -141,14 +171,12 @@ export class URLSearchParams {
this.append(name, value);
}
- this.updateSteps();
+ this.#updateSteps();
}
sort(): void {
- this.params = this.params.sort((a, b): number =>
- a[0] === b[0] ? 0 : a[0] > b[0] ? 1 : -1
- );
- this.updateSteps();
+ this.#params.sort((a, b) => (a[0] === b[0] ? 0 : a[0] > b[0] ? 1 : -1));
+ this.#updateSteps();
}
forEach(
@@ -168,66 +196,31 @@ export class URLSearchParams {
}
*keys(): IterableIterator<string> {
- for (const entry of this.params) {
- yield entry[0];
+ for (const [key] of this.#params) {
+ yield key;
}
}
*values(): IterableIterator<string> {
- for (const entry of this.params) {
- yield entry[1];
+ for (const [, value] of this.#params) {
+ yield value;
}
}
*entries(): IterableIterator<[string, string]> {
- yield* this.params;
+ yield* this.#params;
}
*[Symbol.iterator](): IterableIterator<[string, string]> {
- yield* this.params;
+ yield* this.#params;
}
toString(): string {
- return this.params
+ return this.#params
.map(
- (tuple): string =>
+ (tuple) =>
`${encodeURIComponent(tuple[0])}=${encodeURIComponent(tuple[1])}`
)
.join("&");
}
-
- private _handleStringInitialization(init: string): void {
- // Overload: USVString
- // If init is a string and starts with U+003F (?),
- // remove the first code point from init.
- if (init.charCodeAt(0) === 0x003f) {
- init = init.slice(1);
- }
-
- for (const pair of init.split("&")) {
- // Empty params are ignored
- if (pair.length === 0) {
- continue;
- }
- const position = pair.indexOf("=");
- const name = pair.slice(0, position === -1 ? pair.length : position);
- const value = pair.slice(name.length + 1);
- this.append(decodeURIComponent(name), decodeURIComponent(value));
- }
- }
-
- private _handleArrayInitialization(
- init: string[][] | Iterable<[string, string]>
- ): void {
- // Overload: sequence<sequence<USVString>>
- for (const tuple of init) {
- // If pair does not contain exactly two items, then throw a TypeError.
- if (tuple.length !== 2) {
- throw new TypeError(
- "URLSearchParams.constructor tuple array argument must only contain pair elements"
- );
- }
- this.append(tuple[0], tuple[1]);
- }
- }
}