diff --git a/Cargo.lock b/Cargo.lock
index 928464fcf1..c199cf560f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -635,8 +635,10 @@ dependencies = [
"deno_core",
"deno_crypto",
"deno_fetch",
+ "deno_url",
"deno_web",
"deno_webgpu",
+ "deno_webidl",
"deno_websocket",
"dlopen",
"encoding_rs",
@@ -668,13 +670,21 @@ dependencies = [
"winres",
]
+[[package]]
+name = "deno_url"
+version = "0.1.0"
+dependencies = [
+ "deno_core",
+ "idna",
+ "serde",
+]
+
[[package]]
name = "deno_web"
version = "0.30.3"
dependencies = [
"deno_core",
"futures",
- "serde",
]
[[package]]
@@ -688,6 +698,13 @@ dependencies = [
"wgpu-types",
]
+[[package]]
+name = "deno_webidl"
+version = "0.1.0"
+dependencies = [
+ "deno_core",
+]
+
[[package]]
name = "deno_websocket"
version = "0.5.3"
diff --git a/Cargo.toml b/Cargo.toml
index 8a5f1021c4..e89ca19b7b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,9 +7,13 @@ members = [
"runtime",
"test_plugin",
"test_util",
+ "op_crates/crypto",
"op_crates/fetch",
+ "op_crates/url",
"op_crates/web",
- "op_crates/crypto"
+ "op_crates/webgpu",
+ "op_crates/webidl",
+ "op_crates/websocket",
]
exclude = [
"std/hash/_wasm"
diff --git a/cli/build.rs b/cli/build.rs
index 236097cbf8..3f97a71b74 100644
--- a/cli/build.rs
+++ b/cli/build.rs
@@ -10,6 +10,7 @@ use deno_core::JsRuntime;
use deno_core::RuntimeOptions;
use deno_runtime::deno_crypto;
use deno_runtime::deno_fetch;
+use deno_runtime::deno_url;
use deno_runtime::deno_web;
use deno_runtime::deno_webgpu;
use deno_runtime::deno_websocket;
@@ -61,6 +62,7 @@ fn create_compiler_snapshot(
) {
// libs that are being provided by op crates.
let mut op_crate_libs = HashMap::new();
+ op_crate_libs.insert("deno.url", deno_url::get_declaration());
op_crate_libs.insert("deno.web", deno_web::get_declaration());
op_crate_libs.insert("deno.fetch", deno_fetch::get_declaration());
op_crate_libs.insert("deno.webgpu", deno_webgpu::get_declaration());
@@ -254,6 +256,10 @@ fn main() {
println!("cargo:rustc-env=TS_VERSION={}", ts_version());
println!("cargo:rustc-env=GIT_COMMIT_HASH={}", git_commit_hash());
+ println!(
+ "cargo:rustc-env=DENO_URL_LIB_PATH={}",
+ deno_url::get_declaration().display()
+ );
println!(
"cargo:rustc-env=DENO_WEB_LIB_PATH={}",
deno_web::get_declaration().display()
diff --git a/cli/dts/lib.deno.shared_globals.d.ts b/cli/dts/lib.deno.shared_globals.d.ts
index 4332b757b1..206cafdc30 100644
--- a/cli/dts/lib.deno.shared_globals.d.ts
+++ b/cli/dts/lib.deno.shared_globals.d.ts
@@ -5,6 +5,7 @@
///
///
+///
///
///
///
diff --git a/cli/main.rs b/cli/main.rs
index 93639d34f7..8d685c6dbe 100644
--- a/cli/main.rs
+++ b/cli/main.rs
@@ -278,8 +278,9 @@ fn print_cache_info(
pub fn get_types(unstable: bool) -> String {
let mut types = format!(
- "{}\n{}\n{}\n{}\n{}\n{}\n{}",
+ "{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}",
crate::tsc::DENO_NS_LIB,
+ crate::tsc::DENO_URL_LIB,
crate::tsc::DENO_WEB_LIB,
crate::tsc::DENO_FETCH_LIB,
crate::tsc::DENO_WEBGPU_LIB,
diff --git a/cli/tsc.rs b/cli/tsc.rs
index 8d28b959d3..6bf8546509 100644
--- a/cli/tsc.rs
+++ b/cli/tsc.rs
@@ -29,6 +29,7 @@ use std::sync::Mutex;
// Declaration files
pub static DENO_NS_LIB: &str = include_str!("dts/lib.deno.ns.d.ts");
+pub static DENO_URL_LIB: &str = include_str!(env!("DENO_URL_LIB_PATH"));
pub static DENO_WEB_LIB: &str = include_str!(env!("DENO_WEB_LIB_PATH"));
pub static DENO_FETCH_LIB: &str = include_str!(env!("DENO_FETCH_LIB_PATH"));
pub static DENO_WEBGPU_LIB: &str = include_str!(env!("DENO_WEBGPU_LIB_PATH"));
diff --git a/op_crates/crypto/Cargo.toml b/op_crates/crypto/Cargo.toml
index 3d5af740e4..8b0d2d3fa4 100644
--- a/op_crates/crypto/Cargo.toml
+++ b/op_crates/crypto/Cargo.toml
@@ -4,7 +4,7 @@
name = "deno_crypto"
version = "0.14.1"
edition = "2018"
-description = "Collection of WebCrypto APIs"
+description = "Web Cryptography API implementation for Deno"
authors = ["the Deno authors"]
license = "MIT"
readme = "README.md"
diff --git a/op_crates/crypto/README.md b/op_crates/crypto/README.md
index 0e1c248e64..be07244584 100644
--- a/op_crates/crypto/README.md
+++ b/op_crates/crypto/README.md
@@ -1,3 +1,5 @@
-# deno crypto
+# deno_crypto
-Op crate that implements crypto functions.
+This crate implements the Web Cryptography API.
+
+Spec: https://www.w3.org/TR/WebCryptoAPI/
diff --git a/op_crates/fetch/Cargo.toml b/op_crates/fetch/Cargo.toml
index 9491b87a36..57a56d7409 100644
--- a/op_crates/fetch/Cargo.toml
+++ b/op_crates/fetch/Cargo.toml
@@ -4,7 +4,7 @@
name = "deno_fetch"
version = "0.22.3"
edition = "2018"
-description = "provides fetch Web API to deno_core"
+description = "Fetch API implementation for Deno"
authors = ["the Deno authors"]
license = "MIT"
readme = "README.md"
diff --git a/op_crates/fetch/README.md b/op_crates/fetch/README.md
index 1a6dcab174..2c946197e0 100644
--- a/op_crates/fetch/README.md
+++ b/op_crates/fetch/README.md
@@ -1 +1,5 @@
-This crate provides the web standard fetch API to `deno_core`.
+# deno_fetch
+
+This crate implements the Fetch API.
+
+Spec: https://fetch.spec.whatwg.org/
diff --git a/op_crates/web/11_url.js b/op_crates/url/00_url.js
similarity index 90%
rename from op_crates/web/11_url.js
rename to op_crates/url/00_url.js
index d8f5bd5f7a..9dd2b78007 100644
--- a/op_crates/web/11_url.js
+++ b/op_crates/url/00_url.js
@@ -28,7 +28,7 @@
init = init.slice(1);
}
- this.#params = core.jsonOpSync("op_parse_url_search_params", init);
+ this.#params = core.jsonOpSync("op_url_parse_search_params", init);
} else if (
Array.isArray(init) ||
typeof init?.[Symbol.iterator] == "function"
@@ -64,7 +64,7 @@
return;
}
const parseArgs = { href: url.href, setSearch: this.toString() };
- parts.set(url, core.jsonOpSync("op_parse_url", parseArgs));
+ parts.set(url, core.jsonOpSync("op_url_parse", parseArgs));
};
append(name, value) {
@@ -189,7 +189,7 @@
}
toString() {
- return core.jsonOpSync("op_stringify_url_search_params", this.#params);
+ return core.jsonOpSync("op_url_stringify_search_params", this.#params);
}
}
@@ -206,7 +206,7 @@
} else {
base = base !== undefined ? String(base) : base;
const parseArgs = { href: String(url), baseHref: base };
- parts.set(this, core.jsonOpSync("op_parse_url", parseArgs));
+ parts.set(this, core.jsonOpSync("op_url_parse", parseArgs));
}
}
@@ -231,7 +231,7 @@
if (this.#searchParams != null) {
const params = paramLists.get(this.#searchParams);
const newParams = core.jsonOpSync(
- "op_parse_url_search_params",
+ "op_url_parse_search_params",
this.search.slice(1),
);
params.splice(0, params.length, ...newParams);
@@ -245,7 +245,7 @@
set hash(value) {
try {
const parseArgs = { href: this.href, setHash: String(value) };
- parts.set(this, core.jsonOpSync("op_parse_url", parseArgs));
+ parts.set(this, core.jsonOpSync("op_url_parse", parseArgs));
} catch {
/* pass */
}
@@ -258,7 +258,7 @@
set host(value) {
try {
const parseArgs = { href: this.href, setHost: String(value) };
- parts.set(this, core.jsonOpSync("op_parse_url", parseArgs));
+ parts.set(this, core.jsonOpSync("op_url_parse", parseArgs));
} catch {
/* pass */
}
@@ -271,7 +271,7 @@
set hostname(value) {
try {
const parseArgs = { href: this.href, setHostname: String(value) };
- parts.set(this, core.jsonOpSync("op_parse_url", parseArgs));
+ parts.set(this, core.jsonOpSync("op_url_parse", parseArgs));
} catch {
/* pass */
}
@@ -284,7 +284,7 @@
set href(value) {
try {
const parseArgs = { href: String(value) };
- parts.set(this, core.jsonOpSync("op_parse_url", parseArgs));
+ parts.set(this, core.jsonOpSync("op_url_parse", parseArgs));
} catch {
throw new TypeError("Invalid URL");
}
@@ -302,7 +302,7 @@
set password(value) {
try {
const parseArgs = { href: this.href, setPassword: String(value) };
- parts.set(this, core.jsonOpSync("op_parse_url", parseArgs));
+ parts.set(this, core.jsonOpSync("op_url_parse", parseArgs));
} catch {
/* pass */
}
@@ -315,7 +315,7 @@
set pathname(value) {
try {
const parseArgs = { href: this.href, setPathname: String(value) };
- parts.set(this, core.jsonOpSync("op_parse_url", parseArgs));
+ parts.set(this, core.jsonOpSync("op_url_parse", parseArgs));
} catch {
/* pass */
}
@@ -328,7 +328,7 @@
set port(value) {
try {
const parseArgs = { href: this.href, setPort: String(value) };
- parts.set(this, core.jsonOpSync("op_parse_url", parseArgs));
+ parts.set(this, core.jsonOpSync("op_url_parse", parseArgs));
} catch {
/* pass */
}
@@ -341,7 +341,7 @@
set protocol(value) {
try {
const parseArgs = { href: this.href, setProtocol: String(value) };
- parts.set(this, core.jsonOpSync("op_parse_url", parseArgs));
+ parts.set(this, core.jsonOpSync("op_url_parse", parseArgs));
} catch {
/* pass */
}
@@ -354,7 +354,7 @@
set search(value) {
try {
const parseArgs = { href: this.href, setSearch: String(value) };
- parts.set(this, core.jsonOpSync("op_parse_url", parseArgs));
+ parts.set(this, core.jsonOpSync("op_url_parse", parseArgs));
this.#updateSearchParams();
} catch {
/* pass */
@@ -368,7 +368,7 @@
set username(value) {
try {
const parseArgs = { href: this.href, setUsername: String(value) };
- parts.set(this, core.jsonOpSync("op_parse_url", parseArgs));
+ parts.set(this, core.jsonOpSync("op_url_parse", parseArgs));
} catch {
/* pass */
}
diff --git a/op_crates/url/Cargo.toml b/op_crates/url/Cargo.toml
new file mode 100644
index 0000000000..a07bfc7d3a
--- /dev/null
+++ b/op_crates/url/Cargo.toml
@@ -0,0 +1,19 @@
+# Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+
+[package]
+name = "deno_url"
+version = "0.1.0"
+edition = "2018"
+description = "URL API implementation for Deno"
+authors = ["the Deno authors"]
+license = "MIT"
+readme = "README.md"
+repository = "https://github.com/denoland/deno"
+
+[lib]
+path = "lib.rs"
+
+[dependencies]
+deno_core = { version = "0.80.2", path = "../../core" }
+idna = "0.2.1"
+serde = { version = "1.0.123", features = ["derive"] }
diff --git a/op_crates/url/README.md b/op_crates/url/README.md
new file mode 100644
index 0000000000..991dd8b200
--- /dev/null
+++ b/op_crates/url/README.md
@@ -0,0 +1,5 @@
+# deno_url
+
+This crate implements the URL API for Deno.
+
+Spec: https://url.spec.whatwg.org/
diff --git a/op_crates/url/internal.d.ts b/op_crates/url/internal.d.ts
new file mode 100644
index 0000000000..f852928d35
--- /dev/null
+++ b/op_crates/url/internal.d.ts
@@ -0,0 +1,13 @@
+// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
+
+///
+///
+
+declare namespace globalThis {
+ declare namespace __bootstrap {
+ declare var url: {
+ URL: typeof URL;
+ URLSearchParams: typeof URLSearchParams;
+ };
+ }
+}
diff --git a/op_crates/url/lib.deno_url.d.ts b/op_crates/url/lib.deno_url.d.ts
new file mode 100644
index 0000000000..2a27fe6933
--- /dev/null
+++ b/op_crates/url/lib.deno_url.d.ts
@@ -0,0 +1,175 @@
+// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
+
+// deno-lint-ignore-file no-explicit-any
+
+///
+///
+
+declare class URLSearchParams {
+ constructor(
+ init?: string[][] | Record | string | URLSearchParams,
+ );
+ static toString(): string;
+
+ /** Appends a specified key/value pair as a new search parameter.
+ *
+ * ```ts
+ * let searchParams = new URLSearchParams();
+ * searchParams.append('name', 'first');
+ * searchParams.append('name', 'second');
+ * ```
+ */
+ append(name: string, value: string): void;
+
+ /** Deletes the given search parameter and its associated value,
+ * from the list of all search parameters.
+ *
+ * ```ts
+ * let searchParams = new URLSearchParams([['name', 'value']]);
+ * searchParams.delete('name');
+ * ```
+ */
+ delete(name: string): void;
+
+ /** Returns all the values associated with a given search parameter
+ * as an array.
+ *
+ * ```ts
+ * searchParams.getAll('name');
+ * ```
+ */
+ getAll(name: string): string[];
+
+ /** Returns the first value associated to the given search parameter.
+ *
+ * ```ts
+ * searchParams.get('name');
+ * ```
+ */
+ get(name: string): string | null;
+
+ /** Returns a Boolean that indicates whether a parameter with the
+ * specified name exists.
+ *
+ * ```ts
+ * searchParams.has('name');
+ * ```
+ */
+ has(name: string): boolean;
+
+ /** Sets the value associated with a given search parameter to the
+ * given value. If there were several matching values, this method
+ * deletes the others. If the search parameter doesn't exist, this
+ * method creates it.
+ *
+ * ```ts
+ * searchParams.set('name', 'value');
+ * ```
+ */
+ set(name: string, value: string): void;
+
+ /** Sort all key/value pairs contained in this object in place and
+ * return undefined. The sort order is according to Unicode code
+ * points of the keys.
+ *
+ * ```ts
+ * searchParams.sort();
+ * ```
+ */
+ sort(): void;
+
+ /** Calls a function for each element contained in this object in
+ * place and return undefined. Optionally accepts an object to use
+ * as this when executing callback as second argument.
+ *
+ * ```ts
+ * const params = new URLSearchParams([["a", "b"], ["c", "d"]]);
+ * params.forEach((value, key, parent) => {
+ * console.log(value, key, parent);
+ * });
+ * ```
+ *
+ */
+ forEach(
+ callbackfn: (value: string, key: string, parent: this) => void,
+ thisArg?: any,
+ ): void;
+
+ /** Returns an iterator allowing to go through all keys contained
+ * in this object.
+ *
+ * ```ts
+ * const params = new URLSearchParams([["a", "b"], ["c", "d"]]);
+ * for (const key of params.keys()) {
+ * console.log(key);
+ * }
+ * ```
+ */
+ keys(): IterableIterator;
+
+ /** Returns an iterator allowing to go through all values contained
+ * in this object.
+ *
+ * ```ts
+ * const params = new URLSearchParams([["a", "b"], ["c", "d"]]);
+ * for (const value of params.values()) {
+ * console.log(value);
+ * }
+ * ```
+ */
+ values(): IterableIterator;
+
+ /** Returns an iterator allowing to go through all key/value
+ * pairs contained in this object.
+ *
+ * ```ts
+ * const params = new URLSearchParams([["a", "b"], ["c", "d"]]);
+ * for (const [key, value] of params.entries()) {
+ * console.log(key, value);
+ * }
+ * ```
+ */
+ entries(): IterableIterator<[string, string]>;
+
+ /** Returns an iterator allowing to go through all key/value
+ * pairs contained in this object.
+ *
+ * ```ts
+ * const params = new URLSearchParams([["a", "b"], ["c", "d"]]);
+ * for (const [key, value] of params) {
+ * console.log(key, value);
+ * }
+ * ```
+ */
+ [Symbol.iterator](): IterableIterator<[string, string]>;
+
+ /** Returns a query string suitable for use in a URL.
+ *
+ * ```ts
+ * searchParams.toString();
+ * ```
+ */
+ toString(): string;
+}
+
+/** The URL interface represents an object providing static methods used for creating object URLs. */
+declare class URL {
+ constructor(url: string, base?: string | URL);
+ createObjectURL(object: any): string;
+ revokeObjectURL(url: string): void;
+
+ hash: string;
+ host: string;
+ hostname: string;
+ href: string;
+ toString(): string;
+ readonly origin: string;
+ password: string;
+ pathname: string;
+ port: string;
+ protocol: string;
+ search: string;
+ readonly searchParams: URLSearchParams;
+ username: string;
+ toJSON(): string;
+}
diff --git a/op_crates/url/lib.rs b/op_crates/url/lib.rs
new file mode 100644
index 0000000000..a655d8c34b
--- /dev/null
+++ b/op_crates/url/lib.rs
@@ -0,0 +1,155 @@
+// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
+
+use deno_core::error::generic_error;
+use deno_core::error::type_error;
+use deno_core::error::uri_error;
+use deno_core::error::AnyError;
+use deno_core::serde_json;
+use deno_core::serde_json::json;
+use deno_core::serde_json::Value;
+use deno_core::url::form_urlencoded;
+use deno_core::url::quirks;
+use deno_core::url::Url;
+use deno_core::JsRuntime;
+use deno_core::ZeroCopyBuf;
+use serde::Deserialize;
+use serde::Serialize;
+use std::panic::catch_unwind;
+use std::path::PathBuf;
+
+/// Parse `UrlParseArgs::href` with an optional `UrlParseArgs::base_href`, or an
+/// optional part to "set" after parsing. Return `UrlParts`.
+pub fn op_url_parse(
+ _state: &mut deno_core::OpState,
+ args: Value,
+ _zero_copy: &mut [ZeroCopyBuf],
+) -> Result {
+ #[derive(Deserialize)]
+ #[serde(rename_all = "camelCase")]
+ struct UrlParseArgs {
+ href: String,
+ base_href: Option,
+ // If one of the following are present, this is a setter call. Apply the
+ // proper `Url::set_*()` method after (re)parsing `href`.
+ set_hash: Option,
+ set_host: Option,
+ set_hostname: Option,
+ set_password: Option,
+ set_pathname: Option,
+ set_port: Option,
+ set_protocol: Option,
+ set_search: Option,
+ set_username: Option,
+ }
+ let args: UrlParseArgs = serde_json::from_value(args)?;
+ let base_url = args
+ .base_href
+ .as_ref()
+ .map(|b| Url::parse(b).map_err(|_| type_error("Invalid base URL")))
+ .transpose()?;
+ let mut url = Url::options()
+ .base_url(base_url.as_ref())
+ .parse(&args.href)
+ .map_err(|_| type_error("Invalid URL"))?;
+
+ if let Some(hash) = args.set_hash.as_ref() {
+ quirks::set_hash(&mut url, hash);
+ } else if let Some(host) = args.set_host.as_ref() {
+ quirks::set_host(&mut url, host).map_err(|_| uri_error("Invalid host"))?;
+ } else if let Some(hostname) = args.set_hostname.as_ref() {
+ quirks::set_hostname(&mut url, hostname)
+ .map_err(|_| uri_error("Invalid hostname"))?;
+ } else if let Some(password) = args.set_password.as_ref() {
+ quirks::set_password(&mut url, password)
+ .map_err(|_| uri_error("Invalid password"))?;
+ } else if let Some(pathname) = args.set_pathname.as_ref() {
+ quirks::set_pathname(&mut url, pathname);
+ } else if let Some(port) = args.set_port.as_ref() {
+ quirks::set_port(&mut url, port).map_err(|_| uri_error("Invalid port"))?;
+ } else if let Some(protocol) = args.set_protocol.as_ref() {
+ quirks::set_protocol(&mut url, protocol)
+ .map_err(|_| uri_error("Invalid protocol"))?;
+ } else if let Some(search) = args.set_search.as_ref() {
+ quirks::set_search(&mut url, search);
+ } else if let Some(username) = args.set_username.as_ref() {
+ quirks::set_username(&mut url, username)
+ .map_err(|_| uri_error("Invalid username"))?;
+ }
+
+ #[derive(Serialize)]
+ struct UrlParts<'a> {
+ href: &'a str,
+ hash: &'a str,
+ host: &'a str,
+ hostname: &'a str,
+ origin: &'a str,
+ password: &'a str,
+ pathname: &'a str,
+ port: &'a str,
+ protocol: &'a str,
+ search: &'a str,
+ username: &'a str,
+ }
+ // TODO(nayeemrmn): Panic that occurs in rust-url for the `non-spec:`
+ // url-constructor wpt tests: https://github.com/servo/rust-url/issues/670.
+ let username = catch_unwind(|| quirks::username(&url)).map_err(|_| {
+ generic_error(format!(
+ "Internal error while parsing \"{}\"{}, \
+ see https://github.com/servo/rust-url/issues/670",
+ args.href,
+ args
+ .base_href
+ .map(|b| format!(" against \"{}\"", b))
+ .unwrap_or_default()
+ ))
+ })?;
+ Ok(json!(UrlParts {
+ href: quirks::href(&url),
+ hash: quirks::hash(&url),
+ host: quirks::host(&url),
+ hostname: quirks::hostname(&url),
+ origin: &quirks::origin(&url),
+ password: quirks::password(&url),
+ pathname: quirks::pathname(&url),
+ port: quirks::port(&url),
+ protocol: quirks::protocol(&url),
+ search: quirks::search(&url),
+ username,
+ }))
+}
+
+pub fn op_url_parse_search_params(
+ _state: &mut deno_core::OpState,
+ args: Value,
+ _zero_copy: &mut [ZeroCopyBuf],
+) -> Result {
+ let search: String = serde_json::from_value(args)?;
+ let search_params: Vec<_> = form_urlencoded::parse(search.as_bytes())
+ .into_iter()
+ .collect();
+ Ok(json!(search_params))
+}
+
+pub fn op_url_stringify_search_params(
+ _state: &mut deno_core::OpState,
+ args: Value,
+ _zero_copy: &mut [ZeroCopyBuf],
+) -> Result {
+ let search_params: Vec<(String, String)> = serde_json::from_value(args)?;
+ let search = form_urlencoded::Serializer::new(String::new())
+ .extend_pairs(search_params)
+ .finish();
+ Ok(json!(search))
+}
+
+/// Load and execute the javascript code.
+pub fn init(isolate: &mut JsRuntime) {
+ let files = vec![("deno:op_crates/url/00_url.js", include_str!("00_url.js"))];
+ for (url, source_code) in files {
+ isolate.execute(url, source_code).unwrap();
+ }
+}
+
+pub fn get_declaration() -> PathBuf {
+ PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_url.d.ts")
+}
diff --git a/op_crates/web/01_dom_exception.js b/op_crates/web/01_dom_exception.js
index 14f4ca8e93..f5bd3289bf 100644
--- a/op_crates/web/01_dom_exception.js
+++ b/op_crates/web/01_dom_exception.js
@@ -2,6 +2,7 @@
// @ts-check
///
+///
///
///
diff --git a/op_crates/web/Cargo.toml b/op_crates/web/Cargo.toml
index d1d37c216d..e862078814 100644
--- a/op_crates/web/Cargo.toml
+++ b/op_crates/web/Cargo.toml
@@ -15,7 +15,6 @@ path = "lib.rs"
[dependencies]
deno_core = { version = "0.80.2", path = "../../core" }
-serde = { version = "1.0.123", features = ["derive"] }
[dev-dependencies]
futures = "0.3.12"
diff --git a/op_crates/web/abort_controller_test.js b/op_crates/web/abort_controller_test.js
deleted file mode 100644
index 26f58dccb8..0000000000
--- a/op_crates/web/abort_controller_test.js
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
-"use strict";
-function assert(cond) {
- if (!cond) {
- throw Error("assert");
- }
-}
-
-function assertEquals(left, right) {
- assert(left === right);
-}
-
-function assertThrows(fn) {
- let error = null;
- try {
- fn();
- } catch (error_) {
- error = error_;
- }
- if (error == null) {
- throw new Error("Didn't throw.");
- }
- return error;
-}
-
-function basicAbortController() {
- const controller = new AbortController();
- assert(controller);
- const { signal } = controller;
- assert(signal);
- assertEquals(signal.aborted, false);
- controller.abort();
- assertEquals(signal.aborted, true);
-}
-
-function signalCallsOnabort() {
- const controller = new AbortController();
- const { signal } = controller;
- let called = false;
- signal.onabort = (evt) => {
- assert(evt);
- assertEquals(evt.type, "abort");
- called = true;
- };
- controller.abort();
- assert(called);
-}
-
-function signalEventListener() {
- const controller = new AbortController();
- const { signal } = controller;
- let called = false;
- signal.addEventListener("abort", function (ev) {
- assert(this === signal);
- assertEquals(ev.type, "abort");
- called = true;
- });
- controller.abort();
- assert(called);
-}
-
-function onlyAbortsOnce() {
- const controller = new AbortController();
- const { signal } = controller;
- let called = 0;
- signal.addEventListener("abort", () => called++);
- signal.onabort = () => {
- called++;
- };
- controller.abort();
- assertEquals(called, 2);
- controller.abort();
- assertEquals(called, 2);
-}
-
-function controllerHasProperToString() {
- const actual = Object.prototype.toString.call(new AbortController());
- assertEquals(actual, "[object AbortController]");
-}
-
-function abortSignalIllegalConstructor() {
- const error = assertThrows(() => new AbortSignal());
- assert(error instanceof TypeError);
- assertEquals(error.message, "Illegal constructor.");
-}
-
-function abortSignalEventOrder() {
- const arr = [];
- const controller = new AbortController();
- const { signal } = controller;
- signal.addEventListener("abort", () => arr.push(1));
- signal.onabort = () => arr.push(2);
- signal.addEventListener("abort", () => arr.push(3));
- controller.abort();
- assertEquals(arr[0], 1);
- assertEquals(arr[1], 2);
- assertEquals(arr[2], 3);
-}
-
-function abortSignalEventOrderComplex() {
- const arr = [];
- const controller = new AbortController();
- const { signal } = controller;
- signal.addEventListener("abort", () => arr.push(1));
- signal.onabort = () => {
- throw new Error();
- };
- signal.addEventListener("abort", () => arr.push(3));
- signal.onabort = () => arr.push(2);
- controller.abort();
- assertEquals(arr[0], 1);
- assertEquals(arr[1], 2);
- assertEquals(arr[2], 3);
-}
-
-function abortSignalHandlerLocation() {
- const controller = new AbortController();
- const { signal } = controller;
- const abortHandler = Object.getOwnPropertyDescriptor(signal, "onabort");
- assertEquals(abortHandler, undefined);
-}
-function abortSignalLength() {
- const controller = new AbortController();
- const { signal } = controller;
- assertEquals(signal.constructor.length, 0);
-}
-function main() {
- basicAbortController();
- signalCallsOnabort();
- signalEventListener();
- onlyAbortsOnce();
- controllerHasProperToString();
- abortSignalIllegalConstructor();
- abortSignalEventOrder();
- abortSignalEventOrderComplex();
- abortSignalHandlerLocation();
- abortSignalLength();
-}
-
-main();
diff --git a/op_crates/web/event_target_test.js b/op_crates/web/event_target_test.js
deleted file mode 100644
index acb75cc190..0000000000
--- a/op_crates/web/event_target_test.js
+++ /dev/null
@@ -1,245 +0,0 @@
-// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
-"use strict";
-function assert(cond) {
- if (!cond) {
- throw Error("assert");
- }
-}
-
-function addEventListenerTest() {
- const document = new EventTarget();
-
- assert(document.addEventListener("x", null, false) === undefined);
- assert(document.addEventListener("x", null, true) === undefined);
- assert(document.addEventListener("x", null) === undefined);
-}
-
-function constructedEventTargetCanBeUsedAsExpected() {
- const target = new EventTarget();
- const event = new Event("foo", { bubbles: true, cancelable: false });
- let callCount = 0;
-
- const listener = (e) => {
- assert(e === event);
- ++callCount;
- };
-
- target.addEventListener("foo", listener);
-
- target.dispatchEvent(event);
- assert(callCount === 1);
-
- target.dispatchEvent(event);
- assert(callCount === 2);
-
- target.removeEventListener("foo", listener);
- target.dispatchEvent(event);
- assert(callCount === 2);
-}
-
-function anEventTargetCanBeSubclassed() {
- class NicerEventTarget extends EventTarget {
- on(
- type,
- callback,
- options,
- ) {
- this.addEventListener(type, callback, options);
- }
-
- off(
- type,
- callback,
- options,
- ) {
- this.removeEventListener(type, callback, options);
- }
- }
-
- const target = new NicerEventTarget();
- new Event("foo", { bubbles: true, cancelable: false });
- let callCount = 0;
-
- const listener = () => {
- ++callCount;
- };
-
- target.on("foo", listener);
- assert(callCount === 0);
-
- target.off("foo", listener);
- assert(callCount === 0);
-}
-
-function removingNullEventListenerShouldSucceed() {
- const document = new EventTarget();
- assert(document.removeEventListener("x", null, false) === undefined);
- assert(document.removeEventListener("x", null, true) === undefined);
- assert(document.removeEventListener("x", null) === undefined);
-}
-
-function constructedEventTargetUseObjectPrototype() {
- const target = new EventTarget();
- const event = new Event("toString", { bubbles: true, cancelable: false });
- let callCount = 0;
-
- const listener = (e) => {
- assert(e === event);
- ++callCount;
- };
-
- target.addEventListener("toString", listener);
-
- target.dispatchEvent(event);
- assert(callCount === 1);
-
- target.dispatchEvent(event);
- assert(callCount === 2);
-
- target.removeEventListener("toString", listener);
- target.dispatchEvent(event);
- assert(callCount === 2);
-}
-
-function toStringShouldBeWebCompatible() {
- const target = new EventTarget();
- assert(target.toString() === "[object EventTarget]");
-}
-
-function dispatchEventShouldNotThrowError() {
- let hasThrown = false;
-
- try {
- const target = new EventTarget();
- const event = new Event("hasOwnProperty", {
- bubbles: true,
- cancelable: false,
- });
- const listener = () => {};
- target.addEventListener("hasOwnProperty", listener);
- target.dispatchEvent(event);
- } catch {
- hasThrown = true;
- }
-
- assert(hasThrown === false);
-}
-
-function eventTargetThisShouldDefaultToWindow() {
- const {
- addEventListener,
- dispatchEvent,
- removeEventListener,
- } = EventTarget.prototype;
- let n = 1;
- const event = new Event("hello");
- const listener = () => {
- n = 2;
- };
-
- addEventListener("hello", listener);
- globalThis.dispatchEvent(event);
- assert(n === 2);
- n = 1;
- removeEventListener("hello", listener);
- globalThis.dispatchEvent(event);
- assert(n === 1);
-
- globalThis.addEventListener("hello", listener);
- dispatchEvent(event);
- assert(n === 2);
- n = 1;
- globalThis.removeEventListener("hello", listener);
- dispatchEvent(event);
- assert(n === 1);
-}
-
-function eventTargetShouldAcceptEventListenerObject() {
- const target = new EventTarget();
- const event = new Event("foo", { bubbles: true, cancelable: false });
- let callCount = 0;
-
- const listener = {
- handleEvent(e) {
- assert(e === event);
- ++callCount;
- },
- };
-
- target.addEventListener("foo", listener);
-
- target.dispatchEvent(event);
- assert(callCount === 1);
-
- target.dispatchEvent(event);
- assert(callCount === 2);
-
- target.removeEventListener("foo", listener);
- target.dispatchEvent(event);
- assert(callCount === 2);
-}
-
-function eventTargetShouldAcceptAsyncFunction() {
- const target = new EventTarget();
- const event = new Event("foo", { bubbles: true, cancelable: false });
- let callCount = 0;
-
- const listener = (e) => {
- assert(e === event);
- ++callCount;
- };
-
- target.addEventListener("foo", listener);
-
- target.dispatchEvent(event);
- assert(callCount === 1);
-
- target.dispatchEvent(event);
- assert(callCount === 2);
-
- target.removeEventListener("foo", listener);
- target.dispatchEvent(event);
- assert(callCount === 2);
-}
-
-function eventTargetShouldAcceptAsyncFunctionForEventListenerObject() {
- const target = new EventTarget();
- const event = new Event("foo", { bubbles: true, cancelable: false });
- let callCount = 0;
-
- const listener = {
- handleEvent(e) {
- assert(e === event);
- ++callCount;
- },
- };
-
- target.addEventListener("foo", listener);
-
- target.dispatchEvent(event);
- assert(callCount === 1);
-
- target.dispatchEvent(event);
- assert(callCount === 2);
-
- target.removeEventListener("foo", listener);
- target.dispatchEvent(event);
- assert(callCount === 2);
-}
-
-function main() {
- globalThis.__bootstrap.eventTarget.setEventTargetData(globalThis);
- addEventListenerTest();
- constructedEventTargetCanBeUsedAsExpected();
- anEventTargetCanBeSubclassed();
- removingNullEventListenerShouldSucceed();
- constructedEventTargetUseObjectPrototype();
- toStringShouldBeWebCompatible();
- dispatchEventShouldNotThrowError();
- eventTargetThisShouldDefaultToWindow();
- eventTargetShouldAcceptEventListenerObject();
- eventTargetShouldAcceptAsyncFunction();
- eventTargetShouldAcceptAsyncFunctionForEventListenerObject();
-}
-
-main();
diff --git a/op_crates/web/event_test.js b/op_crates/web/event_test.js
deleted file mode 100644
index fa92a3e078..0000000000
--- a/op_crates/web/event_test.js
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
-"use strict";
-function assert(cond) {
- if (!cond) {
- throw Error("assert");
- }
-}
-
-function eventInitializedWithType() {
- const type = "click";
- const event = new Event(type);
-
- assert(event.isTrusted === false);
- assert(event.target === null);
- assert(event.currentTarget === null);
- assert(event.type === "click");
- assert(event.bubbles === false);
- assert(event.cancelable === false);
-}
-
-function eventInitializedWithTypeAndDict() {
- const init = "submit";
- const eventInit = { bubbles: true, cancelable: true };
- const event = new Event(init, eventInit);
-
- assert(event.isTrusted === false);
- assert(event.target === null);
- assert(event.currentTarget === null);
- assert(event.type === "submit");
- assert(event.bubbles === true);
- assert(event.cancelable === true);
-}
-
-function eventComposedPathSuccess() {
- const type = "click";
- const event = new Event(type);
- const composedPath = event.composedPath();
-
- assert(composedPath.length === 0);
-}
-
-function eventStopPropagationSuccess() {
- const type = "click";
- const event = new Event(type);
-
- assert(event.cancelBubble === false);
- event.stopPropagation();
- assert(event.cancelBubble === true);
-}
-
-function eventStopImmediatePropagationSuccess() {
- const type = "click";
- const event = new Event(type);
-
- assert(event.cancelBubble === false);
- event.stopImmediatePropagation();
- assert(event.cancelBubble === true);
-}
-
-function eventPreventDefaultSuccess() {
- const type = "click";
- const event = new Event(type);
-
- assert(event.defaultPrevented === false);
- event.preventDefault();
- assert(event.defaultPrevented === false);
-
- const eventInit = { bubbles: true, cancelable: true };
- const cancelableEvent = new Event(type, eventInit);
- assert(cancelableEvent.defaultPrevented === false);
- cancelableEvent.preventDefault();
- assert(cancelableEvent.defaultPrevented === true);
-}
-
-function eventInitializedWithNonStringType() {
- const type = undefined;
- const event = new Event(type);
-
- assert(event.isTrusted === false);
- assert(event.target === null);
- assert(event.currentTarget === null);
- assert(event.type === "undefined");
- assert(event.bubbles === false);
- assert(event.cancelable === false);
-}
-
-// ref https://github.com/web-platform-tests/wpt/blob/master/dom/events/Event-isTrusted.any.js
-function eventIsTrusted() {
- const desc1 = Object.getOwnPropertyDescriptor(new Event("x"), "isTrusted");
- assert(desc1);
- assert(typeof desc1.get === "function");
-
- const desc2 = Object.getOwnPropertyDescriptor(new Event("x"), "isTrusted");
- assert(desc2);
- assert(typeof desc2.get === "function");
-
- assert(desc1.get === desc2.get);
-}
-
-function eventIsTrustedGetterName() {
- const { get } = Object.getOwnPropertyDescriptor(new Event("x"), "isTrusted");
- assert(get.name === "get isTrusted");
- try {
- Reflect.construct(get);
- throw new Error("Should not have reached here");
- } catch (e) {
- assert(e.message.includes("not a constructor"));
- }
-}
-function eventAbortSignal() {
- let count = 0;
- function handler() {
- count++;
- }
- const et = new EventTarget();
- const controller = new AbortController();
- et.addEventListener("test", handler, { signal: controller.signal });
- et.dispatchEvent(new Event("test"));
- assert(count === 1);
- et.dispatchEvent(new Event("test"));
- assert(count === 2);
- controller.abort();
- et.dispatchEvent(new Event("test"));
- assert(count === 2);
- et.addEventListener("test", handler, { signal: controller.signal });
- et.dispatchEvent(new Event("test"));
- assert(count === 2);
-}
-function main() {
- eventInitializedWithType();
- eventInitializedWithTypeAndDict();
- eventComposedPathSuccess();
- eventStopPropagationSuccess();
- eventStopImmediatePropagationSuccess();
- eventPreventDefaultSuccess();
- eventInitializedWithNonStringType();
- eventIsTrusted();
- eventIsTrustedGetterName();
- eventAbortSignal();
-}
-
-main();
diff --git a/op_crates/web/internal.d.ts b/op_crates/web/internal.d.ts
index efafee26cd..458f4a173c 100644
--- a/op_crates/web/internal.d.ts
+++ b/op_crates/web/internal.d.ts
@@ -1,301 +1,14 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
-// deno-lint-ignore-file no-explicit-any ban-types
///
///
declare namespace globalThis {
declare namespace __bootstrap {
- declare namespace webidl {
- declare interface ConverterOpts {
- /**
- * The prefix for error messages created by this converter.
- * Examples:
- * - `Failed to construct 'Event'`
- * - `Failed to execute 'removeEventListener' on 'EventTarget'`
- */
- prefix: string;
- }
- declare interface ValueConverterOpts extends ConverterOpts {
- /**
- * The context of this value error messages created by this converter.
- * Examples:
- * - `Argument 1`
- * - `Argument 3`
- */
- context: string;
- }
- declare function makeException(
- ErrorType: any,
- message: string,
- opts: ValueConverterOpts,
- ): any;
- declare interface IntConverterOpts extends ValueConverterOpts {
- /**
- * Wether to throw if the number is outside of the acceptable values for
- * this type.
- */
- enforceRange?: boolean;
- /**
- * Wether to clamp this number to the acceptable values for this type.
- */
- clamp?: boolean;
- }
- declare interface StringConverterOpts extends ValueConverterOpts {
- /**
- * Wether to treat `null` value as an empty string.
- */
- treatNullAsEmptyString?: boolean;
- }
- declare interface BufferConverterOpts extends ValueConverterOpts {
- /**
- * Wether to allow `SharedArrayBuffer` (not just `ArrayBuffer`).
- */
- allowShared?: boolean;
- }
- declare const converters: {
- any(v: any): any;
- /**
- * Convert a value into a `boolean` (bool).
- */
- boolean(v: any, opts?: IntConverterOpts): boolean;
- /**
- * Convert a value into a `byte` (int8).
- */
- byte(v: any, opts?: IntConverterOpts): number;
- /**
- * Convert a value into a `octet` (uint8).
- */
- octet(v: any, opts?: IntConverterOpts): number;
- /**
- * Convert a value into a `short` (int16).
- */
- short(v: any, opts?: IntConverterOpts): number;
- /**
- * Convert a value into a `unsigned short` (uint16).
- */
- ["unsigned short"](v: any, opts?: IntConverterOpts): number;
- /**
- * Convert a value into a `long` (int32).
- */
- long(v: any, opts?: IntConverterOpts): number;
- /**
- * Convert a value into a `unsigned long` (uint32).
- */
- ["unsigned long"](v: any, opts?: IntConverterOpts): number;
- /**
- * Convert a value into a `long long` (int64).
- * **Note this is truncated to a JS number (53 bit precision).**
- */
- ["long long"](v: any, opts?: IntConverterOpts): number;
- /**
- * Convert a value into a `unsigned long long` (uint64).
- * **Note this is truncated to a JS number (53 bit precision).**
- */
- ["unsigned long long"](v: any, opts?: IntConverterOpts): number;
- /**
- * Convert a value into a `float` (f32).
- */
- float(v: any, opts?: ValueConverterOpts): number;
- /**
- * Convert a value into a `unrestricted float` (f32, infinity, or NaN).
- */
- ["unrestricted float"](v: any, opts?: ValueConverterOpts): number;
- /**
- * Convert a value into a `double` (f64).
- */
- double(v: any, opts?: ValueConverterOpts): number;
- /**
- * Convert a value into a `unrestricted double` (f64, infinity, or NaN).
- */
- ["unrestricted double"](v: any, opts?: ValueConverterOpts): number;
- /**
- * Convert a value into a `DOMString` (string).
- */
- DOMString(v: any, opts?: StringConverterOpts): string;
- /**
- * Convert a value into a `ByteString` (string with only u8 codepoints).
- */
- ByteString(v: any, opts?: StringConverterOpts): string;
- /**
- * Convert a value into a `USVString` (string with only valid non
- * surrogate Unicode code points).
- */
- USVString(v: any, opts?: StringConverterOpts): string;
- /**
- * Convert a value into an `object` (object).
- */
- object(v: any, opts?: ValueConverterOpts): object;
- /**
- * Convert a value into an `ArrayBuffer` (ArrayBuffer).
- */
- ArrayBuffer(v: any, opts?: BufferConverterOpts): ArrayBuffer;
- /**
- * Convert a value into a `DataView` (ArrayBuffer).
- */
- DataView(v: any, opts?: BufferConverterOpts): DataView;
- /**
- * Convert a value into a `Int8Array` (Int8Array).
- */
- Int8Array(v: any, opts?: BufferConverterOpts): Int8Array;
- /**
- * Convert a value into a `Int16Array` (Int16Array).
- */
- Int16Array(v: any, opts?: BufferConverterOpts): Int16Array;
- /**
- * Convert a value into a `Int32Array` (Int32Array).
- */
- Int32Array(v: any, opts?: BufferConverterOpts): Int32Array;
- /**
- * Convert a value into a `Uint8Array` (Uint8Array).
- */
- Uint8Array(v: any, opts?: BufferConverterOpts): Uint8Array;
- /**
- * Convert a value into a `Uint16Array` (Uint16Array).
- */
- Uint16Array(v: any, opts?: BufferConverterOpts): Uint16Array;
- /**
- * Convert a value into a `Uint32Array` (Uint32Array).
- */
- Uint32Array(v: any, opts?: BufferConverterOpts): Uint32Array;
- /**
- * Convert a value into a `Uint8ClampedArray` (Uint8ClampedArray).
- */
- Uint8ClampedArray(
- v: any,
- opts?: BufferConverterOpts,
- ): Uint8ClampedArray;
- /**
- * Convert a value into a `Float32Array` (Float32Array).
- */
- Float32Array(v: any, opts?: BufferConverterOpts): Float32Array;
- /**
- * Convert a value into a `Float64Array` (Float64Array).
- */
- Float64Array(v: any, opts?: BufferConverterOpts): Float64Array;
- /**
- * Convert a value into an `ArrayBufferView` (ArrayBufferView).
- */
- ArrayBufferView(v: any, opts?: BufferConverterOpts): ArrayBufferView;
- /**
- * Convert a value into a `BufferSource` (ArrayBuffer or ArrayBufferView).
- */
- BufferSource(
- v: any,
- opts?: BufferConverterOpts,
- ): ArrayBuffer | ArrayBufferView;
- /**
- * Convert a value into a `DOMTimeStamp` (u64). Alias for unsigned long long
- */
- DOMTimeStamp(v: any, opts?: IntConverterOpts): number;
- /**
- * Convert a value into a `Function` ((...args: any[]) => any).
- */
- Function(v: any, opts?: ValueConverterOpts): (...args: any) => any;
- /**
- * Convert a value into a `VoidFunction` (() => void).
- */
- VoidFunction(v: any, opts?: ValueConverterOpts): () => void;
- ["UVString?"](v: any, opts?: ValueConverterOpts): string | null;
- ["sequence"](v: any, opts?: ValueConverterOpts): number[];
-
- [type: string]: (v: any, opts: ValueConverterOpts) => any;
- };
-
- /**
- * Assert that the a function has at least a required amount of arguments.
- */
- declare function requiredArguments(
- length: number,
- required: number,
- opts: ConverterOpts,
- ): void;
- declare type Dictionary = DictionaryMember[];
- declare interface DictionaryMember {
- key: string;
- converter: (v: any, opts: ValueConverterOpts) => any;
- defaultValue?: any;
- required?: boolean;
- }
-
- /**
- * Create a converter for dictionaries.
- */
- declare function createDictionaryConverter(
- name: string,
- ...dictionaries: Dictionary[]
- ): (v: any, opts: ValueConverterOpts) => T;
-
- /**
- * Create a converter for enums.
- */
- declare function createEnumConverter(
- name: string,
- values: string[],
- ): (v: any, opts: ValueConverterOpts) => string;
-
- /**
- * Create a converter that makes the contained type nullable.
- */
- declare function createNullableConverter(
- converter: (v: any, opts: ValueConverterOpts) => T,
- ): (v: any, opts: ValueConverterOpts) => T | null;
-
- /**
- * Create a converter that converts a sequence of the inner type.
- */
- declare function createSequenceConverter(
- converter: (v: any, opts: ValueConverterOpts) => T,
- ): (v: any, opts: ValueConverterOpts) => T[];
-
- /**
- * Throw an illegal constructor error.
- */
- declare function illegalConstructor(): never;
-
- /**
- * The branding symbol.
- */
- declare const brand: unique symbol;
-
- /**
- * Create a branded instance of an interface.
- */
- declare function createBranded(self: any): any;
-
- /**
- * Assert that self is branded.
- */
- declare function assertBranded(self: any, type: any): void;
-
- /**
- * Create a converter for interfaces.
- */
- declare function createInterfaceConverter(
- name: string,
- prototype: any,
- ): (v: any, opts: ValueConverterOpts) => any;
-
- declare function createRecordConverter<
- K extends string | number | symbol,
- V,
- >(
- keyConverter: (v: any, opts: ValueConverterOpts) => K,
- valueConverter: (v: any, opts: ValueConverterOpts) => V,
- ): (
- v: Record,
- opts: ValueConverterOpts,
- ) => any;
- }
-
declare var eventTarget: {
EventTarget: typeof EventTarget;
};
- declare var url: {
- URLSearchParams: typeof URLSearchParams;
- };
-
declare var location: {
getLocationHref(): string | undefined;
};
diff --git a/op_crates/web/lib.deno_web.d.ts b/op_crates/web/lib.deno_web.d.ts
index 24a8f929d2..79b56f68e2 100644
--- a/op_crates/web/lib.deno_web.d.ts
+++ b/op_crates/web/lib.deno_web.d.ts
@@ -313,172 +313,3 @@ declare var FileReader: {
readonly EMPTY: number;
readonly LOADING: number;
};
-
-declare class URLSearchParams {
- constructor(
- init?: string[][] | Record | string | URLSearchParams,
- );
- static toString(): string;
-
- /** Appends a specified key/value pair as a new search parameter.
- *
- * ```ts
- * let searchParams = new URLSearchParams();
- * searchParams.append('name', 'first');
- * searchParams.append('name', 'second');
- * ```
- */
- append(name: string, value: string): void;
-
- /** Deletes the given search parameter and its associated value,
- * from the list of all search parameters.
- *
- * ```ts
- * let searchParams = new URLSearchParams([['name', 'value']]);
- * searchParams.delete('name');
- * ```
- */
- delete(name: string): void;
-
- /** Returns all the values associated with a given search parameter
- * as an array.
- *
- * ```ts
- * searchParams.getAll('name');
- * ```
- */
- getAll(name: string): string[];
-
- /** Returns the first value associated to the given search parameter.
- *
- * ```ts
- * searchParams.get('name');
- * ```
- */
- get(name: string): string | null;
-
- /** Returns a Boolean that indicates whether a parameter with the
- * specified name exists.
- *
- * ```ts
- * searchParams.has('name');
- * ```
- */
- has(name: string): boolean;
-
- /** Sets the value associated with a given search parameter to the
- * given value. If there were several matching values, this method
- * deletes the others. If the search parameter doesn't exist, this
- * method creates it.
- *
- * ```ts
- * searchParams.set('name', 'value');
- * ```
- */
- set(name: string, value: string): void;
-
- /** Sort all key/value pairs contained in this object in place and
- * return undefined. The sort order is according to Unicode code
- * points of the keys.
- *
- * ```ts
- * searchParams.sort();
- * ```
- */
- sort(): void;
-
- /** Calls a function for each element contained in this object in
- * place and return undefined. Optionally accepts an object to use
- * as this when executing callback as second argument.
- *
- * ```ts
- * const params = new URLSearchParams([["a", "b"], ["c", "d"]]);
- * params.forEach((value, key, parent) => {
- * console.log(value, key, parent);
- * });
- * ```
- *
- */
- forEach(
- callbackfn: (value: string, key: string, parent: this) => void,
- thisArg?: any,
- ): void;
-
- /** Returns an iterator allowing to go through all keys contained
- * in this object.
- *
- * ```ts
- * const params = new URLSearchParams([["a", "b"], ["c", "d"]]);
- * for (const key of params.keys()) {
- * console.log(key);
- * }
- * ```
- */
- keys(): IterableIterator;
-
- /** Returns an iterator allowing to go through all values contained
- * in this object.
- *
- * ```ts
- * const params = new URLSearchParams([["a", "b"], ["c", "d"]]);
- * for (const value of params.values()) {
- * console.log(value);
- * }
- * ```
- */
- values(): IterableIterator;
-
- /** Returns an iterator allowing to go through all key/value
- * pairs contained in this object.
- *
- * ```ts
- * const params = new URLSearchParams([["a", "b"], ["c", "d"]]);
- * for (const [key, value] of params.entries()) {
- * console.log(key, value);
- * }
- * ```
- */
- entries(): IterableIterator<[string, string]>;
-
- /** Returns an iterator allowing to go through all key/value
- * pairs contained in this object.
- *
- * ```ts
- * const params = new URLSearchParams([["a", "b"], ["c", "d"]]);
- * for (const [key, value] of params) {
- * console.log(key, value);
- * }
- * ```
- */
- [Symbol.iterator](): IterableIterator<[string, string]>;
-
- /** Returns a query string suitable for use in a URL.
- *
- * ```ts
- * searchParams.toString();
- * ```
- */
- toString(): string;
-}
-
-/** The URL interface represents an object providing static methods used for creating object URLs. */
-declare class URL {
- constructor(url: string, base?: string | URL);
- createObjectURL(object: any): string;
- revokeObjectURL(url: string): void;
-
- hash: string;
- host: string;
- hostname: string;
- href: string;
- toString(): string;
- readonly origin: string;
- password: string;
- pathname: string;
- port: string;
- protocol: string;
- search: string;
- readonly searchParams: URLSearchParams;
- username: string;
- toJSON(): string;
-}
diff --git a/op_crates/web/lib.rs b/op_crates/web/lib.rs
index f67fd81a11..af7a7cebc4 100644
--- a/op_crates/web/lib.rs
+++ b/op_crates/web/lib.rs
@@ -1,29 +1,11 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
-use deno_core::error::generic_error;
-use deno_core::error::type_error;
-use deno_core::error::uri_error;
-use deno_core::error::AnyError;
-use deno_core::serde_json;
-use deno_core::serde_json::json;
-use deno_core::serde_json::Value;
-use deno_core::url::form_urlencoded;
-use deno_core::url::quirks;
-use deno_core::url::Url;
use deno_core::JsRuntime;
-use deno_core::ZeroCopyBuf;
-use serde::Deserialize;
-use serde::Serialize;
-use std::panic::catch_unwind;
use std::path::PathBuf;
/// Load and execute the javascript code.
pub fn init(isolate: &mut JsRuntime) {
let files = vec![
- (
- "deno:op_crates/web/00_webidl.js",
- include_str!("00_webidl.js"),
- ),
(
"deno:op_crates/web/01_dom_exception.js",
include_str!("01_dom_exception.js"),
@@ -44,7 +26,6 @@ pub fn init(isolate: &mut JsRuntime) {
"deno:op_crates/web/08_text_encoding.js",
include_str!("08_text_encoding.js"),
),
- ("deno:op_crates/web/11_url.js", include_str!("11_url.js")),
(
"deno:op_crates/web/12_location.js",
include_str!("12_location.js"),
@@ -59,213 +40,6 @@ pub fn init(isolate: &mut JsRuntime) {
}
}
-/// Parse `UrlParseArgs::href` with an optional `UrlParseArgs::base_href`, or an
-/// optional part to "set" after parsing. Return `UrlParts`.
-pub fn op_parse_url(
- _state: &mut deno_core::OpState,
- args: Value,
- _zero_copy: &mut [ZeroCopyBuf],
-) -> Result {
- #[derive(Deserialize)]
- #[serde(rename_all = "camelCase")]
- struct UrlParseArgs {
- href: String,
- base_href: Option,
- // If one of the following are present, this is a setter call. Apply the
- // proper `Url::set_*()` method after (re)parsing `href`.
- set_hash: Option,
- set_host: Option,
- set_hostname: Option,
- set_password: Option,
- set_pathname: Option,
- set_port: Option,
- set_protocol: Option,
- set_search: Option,
- set_username: Option,
- }
- let args: UrlParseArgs = serde_json::from_value(args)?;
- let base_url = args
- .base_href
- .as_ref()
- .map(|b| Url::parse(b).map_err(|_| type_error("Invalid base URL")))
- .transpose()?;
- let mut url = Url::options()
- .base_url(base_url.as_ref())
- .parse(&args.href)
- .map_err(|_| type_error("Invalid URL"))?;
-
- if let Some(hash) = args.set_hash.as_ref() {
- quirks::set_hash(&mut url, hash);
- } else if let Some(host) = args.set_host.as_ref() {
- quirks::set_host(&mut url, host).map_err(|_| uri_error("Invalid host"))?;
- } else if let Some(hostname) = args.set_hostname.as_ref() {
- quirks::set_hostname(&mut url, hostname)
- .map_err(|_| uri_error("Invalid hostname"))?;
- } else if let Some(password) = args.set_password.as_ref() {
- quirks::set_password(&mut url, password)
- .map_err(|_| uri_error("Invalid password"))?;
- } else if let Some(pathname) = args.set_pathname.as_ref() {
- quirks::set_pathname(&mut url, pathname);
- } else if let Some(port) = args.set_port.as_ref() {
- quirks::set_port(&mut url, port).map_err(|_| uri_error("Invalid port"))?;
- } else if let Some(protocol) = args.set_protocol.as_ref() {
- quirks::set_protocol(&mut url, protocol)
- .map_err(|_| uri_error("Invalid protocol"))?;
- } else if let Some(search) = args.set_search.as_ref() {
- quirks::set_search(&mut url, search);
- } else if let Some(username) = args.set_username.as_ref() {
- quirks::set_username(&mut url, username)
- .map_err(|_| uri_error("Invalid username"))?;
- }
-
- #[derive(Serialize)]
- struct UrlParts<'a> {
- href: &'a str,
- hash: &'a str,
- host: &'a str,
- hostname: &'a str,
- origin: &'a str,
- password: &'a str,
- pathname: &'a str,
- port: &'a str,
- protocol: &'a str,
- search: &'a str,
- username: &'a str,
- }
- // TODO(nayeemrmn): Panic that occurs in rust-url for the `non-spec:`
- // url-constructor wpt tests: https://github.com/servo/rust-url/issues/670.
- let username = catch_unwind(|| quirks::username(&url)).map_err(|_| {
- generic_error(format!(
- "Internal error while parsing \"{}\"{}, \
- see https://github.com/servo/rust-url/issues/670",
- args.href,
- args
- .base_href
- .map(|b| format!(" against \"{}\"", b))
- .unwrap_or_default()
- ))
- })?;
- Ok(json!(UrlParts {
- href: quirks::href(&url),
- hash: quirks::hash(&url),
- host: quirks::host(&url),
- hostname: quirks::hostname(&url),
- origin: &quirks::origin(&url),
- password: quirks::password(&url),
- pathname: quirks::pathname(&url),
- port: quirks::port(&url),
- protocol: quirks::protocol(&url),
- search: quirks::search(&url),
- username,
- }))
-}
-
-pub fn op_parse_url_search_params(
- _state: &mut deno_core::OpState,
- args: Value,
- _zero_copy: &mut [ZeroCopyBuf],
-) -> Result {
- let search: String = serde_json::from_value(args)?;
- let search_params: Vec<_> = form_urlencoded::parse(search.as_bytes())
- .into_iter()
- .collect();
- Ok(json!(search_params))
-}
-
-pub fn op_stringify_url_search_params(
- _state: &mut deno_core::OpState,
- args: Value,
- _zero_copy: &mut [ZeroCopyBuf],
-) -> Result {
- let search_params: Vec<(String, String)> = serde_json::from_value(args)?;
- let search = form_urlencoded::Serializer::new(String::new())
- .extend_pairs(search_params)
- .finish();
- Ok(json!(search))
-}
-
pub fn get_declaration() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_web.d.ts")
}
-
-#[cfg(test)]
-mod tests {
- use deno_core::JsRuntime;
- use futures::future::lazy;
- use futures::task::Context;
- use futures::task::Poll;
-
- fn run_in_task(f: F)
- where
- F: FnOnce(&mut Context) + Send + 'static,
- {
- futures::executor::block_on(lazy(move |cx| f(cx)));
- }
-
- fn setup() -> JsRuntime {
- let mut isolate = JsRuntime::new(Default::default());
- crate::init(&mut isolate);
- isolate
- }
-
- #[test]
- fn test_abort_controller() {
- run_in_task(|mut cx| {
- let mut isolate = setup();
- isolate
- .execute(
- "abort_controller_test.js",
- include_str!("abort_controller_test.js"),
- )
- .unwrap();
- if let Poll::Ready(Err(_)) = isolate.poll_event_loop(&mut cx) {
- unreachable!();
- }
- });
- }
-
- #[test]
- fn test_event() {
- run_in_task(|mut cx| {
- let mut isolate = setup();
- isolate
- .execute("event_test.js", include_str!("event_test.js"))
- .unwrap();
- if let Poll::Ready(Err(_)) = isolate.poll_event_loop(&mut cx) {
- unreachable!();
- }
- });
- }
-
- #[test]
- fn test_event_error() {
- run_in_task(|mut cx| {
- let mut isolate = setup();
- let result = isolate.execute("foo.js", "new Event()");
- if let Err(error) = result {
- let error_string = error.to_string();
- // Test that the script specifier is a URL: `deno:`.
- assert!(error_string.contains("deno:op_crates/web/02_event.js"));
- assert!(error_string.contains("TypeError"));
- } else {
- unreachable!();
- }
- if let Poll::Ready(Err(_)) = isolate.poll_event_loop(&mut cx) {
- unreachable!();
- }
- });
- }
-
- #[test]
- fn test_event_target() {
- run_in_task(|mut cx| {
- let mut isolate = setup();
- isolate
- .execute("event_target_test.js", include_str!("event_target_test.js"))
- .unwrap();
- if let Poll::Ready(Err(_)) = isolate.poll_event_loop(&mut cx) {
- unreachable!();
- }
- });
- }
-}
diff --git a/op_crates/webgpu/Cargo.toml b/op_crates/webgpu/Cargo.toml
index f420106d31..603d0ad1be 100644
--- a/op_crates/webgpu/Cargo.toml
+++ b/op_crates/webgpu/Cargo.toml
@@ -4,7 +4,7 @@
name = "deno_webgpu"
version = "0.1.1"
edition = "2018"
-description = "provides webgpu Web API to deno_core"
+description = "WebGPU implementation for Deno"
authors = ["the Deno authors"]
license = "MIT"
readme = "README.md"
diff --git a/op_crates/web/00_webidl.js b/op_crates/webidl/00_webidl.js
similarity index 100%
rename from op_crates/web/00_webidl.js
rename to op_crates/webidl/00_webidl.js
diff --git a/op_crates/webidl/Cargo.toml b/op_crates/webidl/Cargo.toml
new file mode 100644
index 0000000000..5d2b179990
--- /dev/null
+++ b/op_crates/webidl/Cargo.toml
@@ -0,0 +1,17 @@
+# Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+
+[package]
+name = "deno_webidl"
+version = "0.1.0"
+edition = "2018"
+description = "WebIDL implementation for Deno"
+authors = ["the Deno authors"]
+license = "MIT"
+readme = "README.md"
+repository = "https://github.com/denoland/deno"
+
+[lib]
+path = "lib.rs"
+
+[dependencies]
+deno_core = { version = "0.80.2", path = "../../core" }
diff --git a/op_crates/webidl/README.md b/op_crates/webidl/README.md
new file mode 100644
index 0000000000..ce2d661e36
--- /dev/null
+++ b/op_crates/webidl/README.md
@@ -0,0 +1,6 @@
+# deno_webidl
+
+This crate implements WebIDL for Deno. It consists of infrastructure to do ECMA
+-> WebIDL conversions.
+
+Spec: https://heycam.github.io/webidl/
diff --git a/op_crates/webidl/internal.d.ts b/op_crates/webidl/internal.d.ts
new file mode 100644
index 0000000000..425ee674e5
--- /dev/null
+++ b/op_crates/webidl/internal.d.ts
@@ -0,0 +1,291 @@
+// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
+// deno-lint-ignore-file no-explicit-any ban-types
+
+///
+///
+
+declare namespace globalThis {
+ declare namespace __bootstrap {
+ declare namespace webidl {
+ declare interface ConverterOpts {
+ /**
+ * The prefix for error messages created by this converter.
+ * Examples:
+ * - `Failed to construct 'Event'`
+ * - `Failed to execute 'removeEventListener' on 'EventTarget'`
+ */
+ prefix: string;
+ }
+ declare interface ValueConverterOpts extends ConverterOpts {
+ /**
+ * The context of this value error messages created by this converter.
+ * Examples:
+ * - `Argument 1`
+ * - `Argument 3`
+ */
+ context: string;
+ }
+ declare function makeException(
+ ErrorType: any,
+ message: string,
+ opts: ValueConverterOpts,
+ ): any;
+ declare interface IntConverterOpts extends ValueConverterOpts {
+ /**
+ * Wether to throw if the number is outside of the acceptable values for
+ * this type.
+ */
+ enforceRange?: boolean;
+ /**
+ * Wether to clamp this number to the acceptable values for this type.
+ */
+ clamp?: boolean;
+ }
+ declare interface StringConverterOpts extends ValueConverterOpts {
+ /**
+ * Wether to treat `null` value as an empty string.
+ */
+ treatNullAsEmptyString?: boolean;
+ }
+ declare interface BufferConverterOpts extends ValueConverterOpts {
+ /**
+ * Wether to allow `SharedArrayBuffer` (not just `ArrayBuffer`).
+ */
+ allowShared?: boolean;
+ }
+ declare const converters: {
+ any(v: any): any;
+ /**
+ * Convert a value into a `boolean` (bool).
+ */
+ boolean(v: any, opts?: IntConverterOpts): boolean;
+ /**
+ * Convert a value into a `byte` (int8).
+ */
+ byte(v: any, opts?: IntConverterOpts): number;
+ /**
+ * Convert a value into a `octet` (uint8).
+ */
+ octet(v: any, opts?: IntConverterOpts): number;
+ /**
+ * Convert a value into a `short` (int16).
+ */
+ short(v: any, opts?: IntConverterOpts): number;
+ /**
+ * Convert a value into a `unsigned short` (uint16).
+ */
+ ["unsigned short"](v: any, opts?: IntConverterOpts): number;
+ /**
+ * Convert a value into a `long` (int32).
+ */
+ long(v: any, opts?: IntConverterOpts): number;
+ /**
+ * Convert a value into a `unsigned long` (uint32).
+ */
+ ["unsigned long"](v: any, opts?: IntConverterOpts): number;
+ /**
+ * Convert a value into a `long long` (int64).
+ * **Note this is truncated to a JS number (53 bit precision).**
+ */
+ ["long long"](v: any, opts?: IntConverterOpts): number;
+ /**
+ * Convert a value into a `unsigned long long` (uint64).
+ * **Note this is truncated to a JS number (53 bit precision).**
+ */
+ ["unsigned long long"](v: any, opts?: IntConverterOpts): number;
+ /**
+ * Convert a value into a `float` (f32).
+ */
+ float(v: any, opts?: ValueConverterOpts): number;
+ /**
+ * Convert a value into a `unrestricted float` (f32, infinity, or NaN).
+ */
+ ["unrestricted float"](v: any, opts?: ValueConverterOpts): number;
+ /**
+ * Convert a value into a `double` (f64).
+ */
+ double(v: any, opts?: ValueConverterOpts): number;
+ /**
+ * Convert a value into a `unrestricted double` (f64, infinity, or NaN).
+ */
+ ["unrestricted double"](v: any, opts?: ValueConverterOpts): number;
+ /**
+ * Convert a value into a `DOMString` (string).
+ */
+ DOMString(v: any, opts?: StringConverterOpts): string;
+ /**
+ * Convert a value into a `ByteString` (string with only u8 codepoints).
+ */
+ ByteString(v: any, opts?: StringConverterOpts): string;
+ /**
+ * Convert a value into a `USVString` (string with only valid non
+ * surrogate Unicode code points).
+ */
+ USVString(v: any, opts?: StringConverterOpts): string;
+ /**
+ * Convert a value into an `object` (object).
+ */
+ object(v: any, opts?: ValueConverterOpts): object;
+ /**
+ * Convert a value into an `ArrayBuffer` (ArrayBuffer).
+ */
+ ArrayBuffer(v: any, opts?: BufferConverterOpts): ArrayBuffer;
+ /**
+ * Convert a value into a `DataView` (ArrayBuffer).
+ */
+ DataView(v: any, opts?: BufferConverterOpts): DataView;
+ /**
+ * Convert a value into a `Int8Array` (Int8Array).
+ */
+ Int8Array(v: any, opts?: BufferConverterOpts): Int8Array;
+ /**
+ * Convert a value into a `Int16Array` (Int16Array).
+ */
+ Int16Array(v: any, opts?: BufferConverterOpts): Int16Array;
+ /**
+ * Convert a value into a `Int32Array` (Int32Array).
+ */
+ Int32Array(v: any, opts?: BufferConverterOpts): Int32Array;
+ /**
+ * Convert a value into a `Uint8Array` (Uint8Array).
+ */
+ Uint8Array(v: any, opts?: BufferConverterOpts): Uint8Array;
+ /**
+ * Convert a value into a `Uint16Array` (Uint16Array).
+ */
+ Uint16Array(v: any, opts?: BufferConverterOpts): Uint16Array;
+ /**
+ * Convert a value into a `Uint32Array` (Uint32Array).
+ */
+ Uint32Array(v: any, opts?: BufferConverterOpts): Uint32Array;
+ /**
+ * Convert a value into a `Uint8ClampedArray` (Uint8ClampedArray).
+ */
+ Uint8ClampedArray(
+ v: any,
+ opts?: BufferConverterOpts,
+ ): Uint8ClampedArray;
+ /**
+ * Convert a value into a `Float32Array` (Float32Array).
+ */
+ Float32Array(v: any, opts?: BufferConverterOpts): Float32Array;
+ /**
+ * Convert a value into a `Float64Array` (Float64Array).
+ */
+ Float64Array(v: any, opts?: BufferConverterOpts): Float64Array;
+ /**
+ * Convert a value into an `ArrayBufferView` (ArrayBufferView).
+ */
+ ArrayBufferView(v: any, opts?: BufferConverterOpts): ArrayBufferView;
+ /**
+ * Convert a value into a `BufferSource` (ArrayBuffer or ArrayBufferView).
+ */
+ BufferSource(
+ v: any,
+ opts?: BufferConverterOpts,
+ ): ArrayBuffer | ArrayBufferView;
+ /**
+ * Convert a value into a `DOMTimeStamp` (u64). Alias for unsigned long long
+ */
+ DOMTimeStamp(v: any, opts?: IntConverterOpts): number;
+ /**
+ * Convert a value into a `Function` ((...args: any[]) => any).
+ */
+ Function(v: any, opts?: ValueConverterOpts): (...args: any) => any;
+ /**
+ * Convert a value into a `VoidFunction` (() => void).
+ */
+ VoidFunction(v: any, opts?: ValueConverterOpts): () => void;
+ ["UVString?"](v: any, opts?: ValueConverterOpts): string | null;
+ ["sequence"](v: any, opts?: ValueConverterOpts): number[];
+
+ [type: string]: (v: any, opts: ValueConverterOpts) => any;
+ };
+
+ /**
+ * Assert that the a function has at least a required amount of arguments.
+ */
+ declare function requiredArguments(
+ length: number,
+ required: number,
+ opts: ConverterOpts,
+ ): void;
+ declare type Dictionary = DictionaryMember[];
+ declare interface DictionaryMember {
+ key: string;
+ converter: (v: any, opts: ValueConverterOpts) => any;
+ defaultValue?: any;
+ required?: boolean;
+ }
+
+ /**
+ * Create a converter for dictionaries.
+ */
+ declare function createDictionaryConverter(
+ name: string,
+ ...dictionaries: Dictionary[]
+ ): (v: any, opts: ValueConverterOpts) => T;
+
+ /**
+ * Create a converter for enums.
+ */
+ declare function createEnumConverter(
+ name: string,
+ values: string[],
+ ): (v: any, opts: ValueConverterOpts) => string;
+
+ /**
+ * Create a converter that makes the contained type nullable.
+ */
+ declare function createNullableConverter(
+ converter: (v: any, opts: ValueConverterOpts) => T,
+ ): (v: any, opts: ValueConverterOpts) => T | null;
+
+ /**
+ * Create a converter that converts a sequence of the inner type.
+ */
+ declare function createSequenceConverter(
+ converter: (v: any, opts: ValueConverterOpts) => T,
+ ): (v: any, opts: ValueConverterOpts) => T[];
+
+ /**
+ * Throw an illegal constructor error.
+ */
+ declare function illegalConstructor(): never;
+
+ /**
+ * The branding symbol.
+ */
+ declare const brand: unique symbol;
+
+ /**
+ * Create a branded instance of an interface.
+ */
+ declare function createBranded(self: any): any;
+
+ /**
+ * Assert that self is branded.
+ */
+ declare function assertBranded(self: any, type: any): void;
+
+ /**
+ * Create a converter for interfaces.
+ */
+ declare function createInterfaceConverter(
+ name: string,
+ prototype: any,
+ ): (v: any, opts: ValueConverterOpts) => any;
+
+ declare function createRecordConverter<
+ K extends string | number | symbol,
+ V,
+ >(
+ keyConverter: (v: any, opts: ValueConverterOpts) => K,
+ valueConverter: (v: any, opts: ValueConverterOpts) => V,
+ ): (
+ v: Record,
+ opts: ValueConverterOpts,
+ ) => any;
+ }
+ }
+}
diff --git a/op_crates/webidl/lib.rs b/op_crates/webidl/lib.rs
new file mode 100644
index 0000000000..7e617c7a76
--- /dev/null
+++ b/op_crates/webidl/lib.rs
@@ -0,0 +1,14 @@
+// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
+
+use deno_core::JsRuntime;
+
+/// Load and execute the javascript code.
+pub fn init(isolate: &mut JsRuntime) {
+ let files = vec![(
+ "deno:op_crates/webidl/00_webidl.js",
+ include_str!("00_webidl.js"),
+ )];
+ for (url, source_code) in files {
+ isolate.execute(url, source_code).unwrap();
+ }
+}
diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml
index 0ece4228eb..f654e015c0 100644
--- a/runtime/Cargo.toml
+++ b/runtime/Cargo.toml
@@ -22,6 +22,8 @@ deno_core = { path = "../core", version = "0.80.2" }
deno_crypto = { path = "../op_crates/crypto", version = "0.14.1" }
deno_fetch = { path = "../op_crates/fetch", version = "0.22.3" }
deno_web = { path = "../op_crates/web", version = "0.30.3" }
+deno_url = { path = "../op_crates/url", version = "0.1.0" }
+deno_webidl = { path = "../op_crates/webidl", version = "0.1.0" }
deno_websocket = { path = "../op_crates/websocket", version = "0.5.3" }
deno_webgpu = { path = "../op_crates/webgpu", version = "0.1.1" }
@@ -34,6 +36,8 @@ deno_core = { path = "../core", version = "0.80.2" }
deno_crypto = { path = "../op_crates/crypto", version = "0.14.1" }
deno_fetch = { path = "../op_crates/fetch", version = "0.22.3" }
deno_web = { path = "../op_crates/web", version = "0.30.3" }
+deno_url = { path = "../op_crates/url", version = "0.1.0" }
+deno_webidl = { path = "../op_crates/webidl", version = "0.1.0" }
deno_websocket = { path = "../op_crates/websocket", version = "0.5.3" }
deno_webgpu = { path = "../op_crates/webgpu", version = "0.1.1" }
diff --git a/runtime/build.rs b/runtime/build.rs
index 2481485684..67f80c8672 100644
--- a/runtime/build.rs
+++ b/runtime/build.rs
@@ -13,6 +13,8 @@ fn create_snapshot(
snapshot_path: &Path,
files: Vec,
) {
+ deno_webidl::init(&mut js_runtime);
+ deno_url::init(&mut js_runtime);
deno_web::init(&mut js_runtime);
deno_fetch::init(&mut js_runtime);
deno_websocket::init(&mut js_runtime);
diff --git a/runtime/lib.rs b/runtime/lib.rs
index c523b24b7a..1406372616 100644
--- a/runtime/lib.rs
+++ b/runtime/lib.rs
@@ -9,8 +9,10 @@ extern crate log;
pub use deno_crypto;
pub use deno_fetch;
+pub use deno_url;
pub use deno_web;
pub use deno_webgpu;
+pub use deno_webidl;
pub use deno_websocket;
pub mod colors;
diff --git a/runtime/ops/mod.rs b/runtime/ops/mod.rs
index 0ef04ff3cf..6b64b8042f 100644
--- a/runtime/ops/mod.rs
+++ b/runtime/ops/mod.rs
@@ -20,6 +20,7 @@ pub mod signal;
pub mod timers;
pub mod tls;
pub mod tty;
+pub mod url;
pub mod web_worker;
pub mod webgpu;
pub mod websocket;
diff --git a/runtime/ops/url.rs b/runtime/ops/url.rs
new file mode 100644
index 0000000000..4add9132d6
--- /dev/null
+++ b/runtime/ops/url.rs
@@ -0,0 +1,18 @@
+// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
+use deno_url::op_url_parse;
+use deno_url::op_url_parse_search_params;
+use deno_url::op_url_stringify_search_params;
+
+pub fn init(rt: &mut deno_core::JsRuntime) {
+ super::reg_json_sync(rt, "op_url_parse", op_url_parse);
+ super::reg_json_sync(
+ rt,
+ "op_url_parse_search_params",
+ op_url_parse_search_params,
+ );
+ super::reg_json_sync(
+ rt,
+ "op_url_stringify_search_params",
+ op_url_stringify_search_params,
+ );
+}
diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs
index 73d351c9c6..f35b38d3ba 100644
--- a/runtime/web_worker.rs
+++ b/runtime/web_worker.rs
@@ -231,17 +231,7 @@ impl WebWorker {
);
ops::reg_json_sync(js_runtime, "op_close", deno_core::op_close);
ops::reg_json_sync(js_runtime, "op_resources", deno_core::op_resources);
- ops::reg_json_sync(js_runtime, "op_parse_url", deno_web::op_parse_url);
- ops::reg_json_sync(
- js_runtime,
- "op_parse_url_search_params",
- deno_web::op_parse_url_search_params,
- );
- ops::reg_json_sync(
- js_runtime,
- "op_stringify_url_search_params",
- deno_web::op_stringify_url_search_params,
- );
+ ops::url::init(js_runtime);
ops::io::init(js_runtime);
ops::webgpu::init(js_runtime);
ops::websocket::init(
diff --git a/runtime/worker.rs b/runtime/worker.rs
index e63fdbe18c..51fe1dc273 100644
--- a/runtime/worker.rs
+++ b/runtime/worker.rs
@@ -127,17 +127,7 @@ impl MainWorker {
ops::crypto::init(js_runtime, options.seed);
ops::reg_json_sync(js_runtime, "op_close", deno_core::op_close);
ops::reg_json_sync(js_runtime, "op_resources", deno_core::op_resources);
- ops::reg_json_sync(js_runtime, "op_parse_url", deno_web::op_parse_url);
- ops::reg_json_sync(
- js_runtime,
- "op_parse_url_search_params",
- deno_web::op_parse_url_search_params,
- );
- ops::reg_json_sync(
- js_runtime,
- "op_stringify_url_search_params",
- deno_web::op_stringify_url_search_params,
- );
+ ops::url::init(js_runtime);
ops::fs_events::init(js_runtime);
ops::fs::init(js_runtime);
ops::io::init(js_runtime);