summaryrefslogtreecommitdiff
path: root/extensions
diff options
context:
space:
mode:
Diffstat (limited to 'extensions')
-rw-r--r--extensions/broadcast_channel/01_broadcast_channel.js167
-rw-r--r--extensions/broadcast_channel/Cargo.toml20
-rw-r--r--extensions/broadcast_channel/README.md5
-rw-r--r--extensions/broadcast_channel/in_memory_broadcast_channel.rs97
-rw-r--r--extensions/broadcast_channel/lib.deno_broadcast_channel.d.ts55
-rw-r--r--extensions/broadcast_channel/lib.rs139
-rw-r--r--extensions/fetch/21_formdata.js30
-rw-r--r--extensions/file/02_filereader.js4
-rw-r--r--extensions/timers/Cargo.toml7
-rw-r--r--extensions/timers/benches/timers_ops.rs36
-rw-r--r--extensions/url/00_url.js8
-rw-r--r--extensions/url/Cargo.toml2
-rw-r--r--extensions/url/benches/url_ops.rs45
-rw-r--r--extensions/web/02_event.js5
-rw-r--r--extensions/webstorage/lib.rs10
15 files changed, 576 insertions, 54 deletions
diff --git a/extensions/broadcast_channel/01_broadcast_channel.js b/extensions/broadcast_channel/01_broadcast_channel.js
new file mode 100644
index 000000000..7670b0cfd
--- /dev/null
+++ b/extensions/broadcast_channel/01_broadcast_channel.js
@@ -0,0 +1,167 @@
+// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
+"use strict";
+
+((window) => {
+ const core = window.Deno.core;
+ const webidl = window.__bootstrap.webidl;
+ const { setTarget } = window.__bootstrap.event;
+
+ const handlerSymbol = Symbol("eventHandlers");
+ function makeWrappedHandler(handler) {
+ function wrappedHandler(...args) {
+ if (typeof wrappedHandler.handler !== "function") {
+ return;
+ }
+ return wrappedHandler.handler.call(this, ...args);
+ }
+ wrappedHandler.handler = handler;
+ return wrappedHandler;
+ }
+ // TODO(lucacasonato) reuse when we can reuse code between web crates
+ function defineEventHandler(emitter, name) {
+ // HTML specification section 8.1.5.1
+ Object.defineProperty(emitter, `on${name}`, {
+ get() {
+ // TODO(bnoordhuis) The "BroadcastChannel should have an onmessage
+ // event" WPT test expects that .onmessage !== undefined. Returning
+ // null makes it pass but is perhaps not exactly in the spirit.
+ return this[handlerSymbol]?.get(name)?.handler ?? null;
+ },
+ set(value) {
+ if (!this[handlerSymbol]) {
+ this[handlerSymbol] = new Map();
+ }
+ let handlerWrapper = this[handlerSymbol]?.get(name);
+ if (handlerWrapper) {
+ handlerWrapper.handler = value;
+ } else {
+ handlerWrapper = makeWrappedHandler(value);
+ this.addEventListener(name, handlerWrapper);
+ }
+ this[handlerSymbol].set(name, handlerWrapper);
+ },
+ configurable: true,
+ enumerable: true,
+ });
+ }
+
+ const _name = Symbol("[[name]]");
+ const _closed = Symbol("[[closed]]");
+
+ const channels = [];
+ let rid = null;
+
+ async function recv() {
+ while (channels.length > 0) {
+ const message = await core.opAsync("op_broadcast_recv", rid);
+
+ if (message === null) {
+ break;
+ }
+
+ const [name, data] = message;
+ dispatch(null, name, new Uint8Array(data));
+ }
+
+ core.close(rid);
+ rid = null;
+ }
+
+ function dispatch(source, name, data) {
+ for (const channel of channels) {
+ if (channel === source) continue; // Don't self-send.
+ if (channel[_name] !== name) continue;
+ if (channel[_closed]) continue;
+
+ const go = () => {
+ if (channel[_closed]) return;
+ const event = new MessageEvent("message", {
+ data: core.deserialize(data), // TODO(bnoordhuis) Cache immutables.
+ origin: "http://127.0.0.1",
+ });
+ setTarget(event, channel);
+ channel.dispatchEvent(event);
+ };
+
+ defer(go);
+ }
+ }
+
+ // Defer to avoid starving the event loop. Not using queueMicrotask()
+ // for that reason: it lets promises make forward progress but can
+ // still starve other parts of the event loop.
+ function defer(go) {
+ setTimeout(go, 1);
+ }
+
+ class BroadcastChannel extends EventTarget {
+ [_name];
+ [_closed] = false;
+
+ get name() {
+ return this[_name];
+ }
+
+ constructor(name) {
+ super();
+
+ const prefix = "Failed to construct 'broadcastChannel'";
+ webidl.requiredArguments(arguments.length, 1, { prefix });
+
+ this[_name] = webidl.converters["DOMString"](name, {
+ prefix,
+ context: "Argument 1",
+ });
+
+ this[webidl.brand] = webidl.brand;
+
+ channels.push(this);
+
+ if (rid === null) {
+ // Create the rid immediately, otherwise there is a time window (and a
+ // race condition) where messages can get lost, because recv() is async.
+ rid = core.opSync("op_broadcast_subscribe");
+ recv();
+ }
+ }
+
+ postMessage(message) {
+ webidl.assertBranded(this, BroadcastChannel);
+
+ const prefix = "Failed to execute 'postMessage' on 'BroadcastChannel'";
+ webidl.requiredArguments(arguments.length, 1, { prefix });
+
+ if (this[_closed]) {
+ throw new DOMException("Already closed", "InvalidStateError");
+ }
+
+ if (typeof message === "function" || typeof message === "symbol") {
+ throw new DOMException("Uncloneable value", "DataCloneError");
+ }
+
+ const data = core.serialize(message);
+
+ // Send to other listeners in this VM.
+ dispatch(this, this[_name], new Uint8Array(data));
+
+ // Send to listeners in other VMs.
+ defer(() => core.opAsync("op_broadcast_send", [rid, this[_name]], data));
+ }
+
+ close() {
+ webidl.assertBranded(this, BroadcastChannel);
+ this[_closed] = true;
+
+ const index = channels.indexOf(this);
+ if (index === -1) return;
+
+ channels.splice(index, 1);
+ if (channels.length === 0) core.opSync("op_broadcast_unsubscribe", rid);
+ }
+ }
+
+ defineEventHandler(BroadcastChannel.prototype, "message");
+ defineEventHandler(BroadcastChannel.prototype, "messageerror");
+
+ window.__bootstrap.broadcastChannel = { BroadcastChannel };
+})(this);
diff --git a/extensions/broadcast_channel/Cargo.toml b/extensions/broadcast_channel/Cargo.toml
new file mode 100644
index 000000000..7bc65f3a0
--- /dev/null
+++ b/extensions/broadcast_channel/Cargo.toml
@@ -0,0 +1,20 @@
+# Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
+
+[package]
+name = "deno_broadcast_channel"
+version = "0.1.0"
+edition = "2018"
+description = "Implementation of BroadcastChannel API for Deno"
+authors = ["the Deno authors"]
+license = "MIT"
+readme = "README.md"
+repository = "https://github.com/denoland/deno"
+
+[lib]
+path = "lib.rs"
+
+[dependencies]
+async-trait = "0.1"
+deno_core = { version = "0.88.0", path = "../../core" }
+tokio = { version = "1.4.0", features = ["full"] }
+uuid = { version = "0.8.2", features = ["v4"] }
diff --git a/extensions/broadcast_channel/README.md b/extensions/broadcast_channel/README.md
new file mode 100644
index 000000000..5b5034ef7
--- /dev/null
+++ b/extensions/broadcast_channel/README.md
@@ -0,0 +1,5 @@
+# deno_broadcast_channel
+
+This crate implements the BroadcastChannel functions of Deno.
+
+Spec: https://html.spec.whatwg.org/multipage/web-messaging.html
diff --git a/extensions/broadcast_channel/in_memory_broadcast_channel.rs b/extensions/broadcast_channel/in_memory_broadcast_channel.rs
new file mode 100644
index 000000000..34498c830
--- /dev/null
+++ b/extensions/broadcast_channel/in_memory_broadcast_channel.rs
@@ -0,0 +1,97 @@
+// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
+
+use crate::BroadcastChannel;
+use async_trait::async_trait;
+use deno_core::error::AnyError;
+use std::sync::Arc;
+use std::sync::Mutex;
+use tokio::sync::broadcast;
+use tokio::sync::mpsc;
+use uuid::Uuid;
+
+#[derive(Clone)]
+pub struct InMemoryBroadcastChannel(Arc<Mutex<broadcast::Sender<Message>>>);
+
+pub struct InMemoryBroadcastChannelResource {
+ rx: tokio::sync::Mutex<(
+ broadcast::Receiver<Message>,
+ mpsc::UnboundedReceiver<()>,
+ )>,
+ cancel_tx: mpsc::UnboundedSender<()>,
+ uuid: Uuid,
+}
+
+#[derive(Clone, Debug)]
+struct Message {
+ name: Arc<String>,
+ data: Arc<Vec<u8>>,
+ uuid: Uuid,
+}
+
+impl Default for InMemoryBroadcastChannel {
+ fn default() -> Self {
+ let (tx, _) = broadcast::channel(256);
+ Self(Arc::new(Mutex::new(tx)))
+ }
+}
+
+#[async_trait]
+impl BroadcastChannel for InMemoryBroadcastChannel {
+ type Resource = InMemoryBroadcastChannelResource;
+
+ fn subscribe(&self) -> Result<Self::Resource, AnyError> {
+ let (cancel_tx, cancel_rx) = mpsc::unbounded_channel();
+ let broadcast_rx = self.0.lock().unwrap().subscribe();
+ let rx = tokio::sync::Mutex::new((broadcast_rx, cancel_rx));
+ let uuid = Uuid::new_v4();
+ Ok(Self::Resource {
+ rx,
+ cancel_tx,
+ uuid,
+ })
+ }
+
+ fn unsubscribe(&self, resource: &Self::Resource) -> Result<(), AnyError> {
+ Ok(resource.cancel_tx.send(())?)
+ }
+
+ async fn send(
+ &self,
+ resource: &Self::Resource,
+ name: String,
+ data: Vec<u8>,
+ ) -> Result<(), AnyError> {
+ let name = Arc::new(name);
+ let data = Arc::new(data);
+ let uuid = resource.uuid;
+ self.0.lock().unwrap().send(Message { name, data, uuid })?;
+ Ok(())
+ }
+
+ async fn recv(
+ &self,
+ resource: &Self::Resource,
+ ) -> Result<Option<crate::Message>, AnyError> {
+ let mut g = resource.rx.lock().await;
+ let (broadcast_rx, cancel_rx) = &mut *g;
+ loop {
+ let result = tokio::select! {
+ r = broadcast_rx.recv() => r,
+ _ = cancel_rx.recv() => return Ok(None),
+ };
+ use tokio::sync::broadcast::error::RecvError::*;
+ match result {
+ Err(Closed) => return Ok(None),
+ Err(Lagged(_)) => (), // Backlogged, messages dropped.
+ Ok(message) if message.uuid == resource.uuid => (), // Self-send.
+ Ok(message) => {
+ let name = String::clone(&message.name);
+ let data = Vec::clone(&message.data);
+ return Ok(Some((name, data)));
+ }
+ }
+ }
+ }
+}
+
+impl deno_core::Resource for InMemoryBroadcastChannelResource {}
diff --git a/extensions/broadcast_channel/lib.deno_broadcast_channel.d.ts b/extensions/broadcast_channel/lib.deno_broadcast_channel.d.ts
new file mode 100644
index 000000000..c8efef778
--- /dev/null
+++ b/extensions/broadcast_channel/lib.deno_broadcast_channel.d.ts
@@ -0,0 +1,55 @@
+// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
+
+// deno-lint-ignore-file no-explicit-any
+
+/// <reference no-default-lib="true" />
+/// <reference lib="esnext" />
+
+interface BroadcastChannelEventMap {
+ "message": MessageEvent;
+ "messageerror": MessageEvent;
+}
+
+interface BroadcastChannel extends EventTarget {
+ /**
+ * Returns the channel name (as passed to the constructor).
+ */
+ readonly name: string;
+ onmessage: ((this: BroadcastChannel, ev: MessageEvent) => any) | null;
+ onmessageerror: ((this: BroadcastChannel, ev: MessageEvent) => any) | null;
+ /**
+ * Closes the BroadcastChannel object, opening it up to garbage collection.
+ */
+ close(): void;
+ /**
+ * Sends the given message to other BroadcastChannel objects set up for
+ * this channel. Messages can be structured objects, e.g. nested objects
+ * and arrays.
+ */
+ postMessage(message: any): void;
+ addEventListener<K extends keyof BroadcastChannelEventMap>(
+ type: K,
+ listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any,
+ options?: boolean | AddEventListenerOptions,
+ ): void;
+ addEventListener(
+ type: string,
+ listener: EventListenerOrEventListenerObject,
+ options?: boolean | AddEventListenerOptions,
+ ): void;
+ removeEventListener<K extends keyof BroadcastChannelEventMap>(
+ type: K,
+ listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any,
+ options?: boolean | EventListenerOptions,
+ ): void;
+ removeEventListener(
+ type: string,
+ listener: EventListenerOrEventListenerObject,
+ options?: boolean | EventListenerOptions,
+ ): void;
+}
+
+declare var BroadcastChannel: {
+ prototype: BroadcastChannel;
+ new (name: string): BroadcastChannel;
+};
diff --git a/extensions/broadcast_channel/lib.rs b/extensions/broadcast_channel/lib.rs
new file mode 100644
index 000000000..b2a79916c
--- /dev/null
+++ b/extensions/broadcast_channel/lib.rs
@@ -0,0 +1,139 @@
+// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
+
+mod in_memory_broadcast_channel;
+
+pub use in_memory_broadcast_channel::InMemoryBroadcastChannel;
+
+use async_trait::async_trait;
+use deno_core::error::bad_resource_id;
+use deno_core::error::AnyError;
+use deno_core::include_js_files;
+use deno_core::op_async;
+use deno_core::op_sync;
+use deno_core::Extension;
+use deno_core::OpState;
+use deno_core::Resource;
+use deno_core::ResourceId;
+use deno_core::ZeroCopyBuf;
+use std::cell::RefCell;
+use std::path::PathBuf;
+use std::rc::Rc;
+
+#[async_trait]
+pub trait BroadcastChannel: Clone {
+ type Resource: Resource;
+
+ fn subscribe(&self) -> Result<Self::Resource, AnyError>;
+
+ fn unsubscribe(&self, resource: &Self::Resource) -> Result<(), AnyError>;
+
+ async fn send(
+ &self,
+ resource: &Self::Resource,
+ name: String,
+ data: Vec<u8>,
+ ) -> Result<(), AnyError>;
+
+ async fn recv(
+ &self,
+ resource: &Self::Resource,
+ ) -> Result<Option<Message>, AnyError>;
+}
+
+pub type Message = (String, Vec<u8>);
+
+struct Unstable(bool); // --unstable
+
+pub fn op_broadcast_subscribe<BC: BroadcastChannel + 'static>(
+ state: &mut OpState,
+ _args: (),
+ _buf: (),
+) -> Result<ResourceId, AnyError> {
+ let unstable = state.borrow::<Unstable>().0;
+
+ if !unstable {
+ eprintln!(
+ "Unstable API 'BroadcastChannel'. The --unstable flag must be provided.",
+ );
+ std::process::exit(70);
+ }
+
+ let bc = state.borrow::<BC>();
+ let resource = bc.subscribe()?;
+ Ok(state.resource_table.add(resource))
+}
+
+pub fn op_broadcast_unsubscribe<BC: BroadcastChannel + 'static>(
+ state: &mut OpState,
+ rid: ResourceId,
+ _buf: (),
+) -> Result<(), AnyError> {
+ let resource = state
+ .resource_table
+ .get::<BC::Resource>(rid)
+ .ok_or_else(bad_resource_id)?;
+ let bc = state.borrow::<BC>();
+ bc.unsubscribe(&resource)
+}
+
+pub async fn op_broadcast_send<BC: BroadcastChannel + 'static>(
+ state: Rc<RefCell<OpState>>,
+ (rid, name): (ResourceId, String),
+ buf: ZeroCopyBuf,
+) -> Result<(), AnyError> {
+ let resource = state
+ .borrow()
+ .resource_table
+ .get::<BC::Resource>(rid)
+ .ok_or_else(bad_resource_id)?;
+ let bc = state.borrow().borrow::<BC>().clone();
+ bc.send(&resource, name, buf.to_vec()).await
+}
+
+pub async fn op_broadcast_recv<BC: BroadcastChannel + 'static>(
+ state: Rc<RefCell<OpState>>,
+ rid: ResourceId,
+ _buf: (),
+) -> Result<Option<Message>, AnyError> {
+ let resource = state
+ .borrow()
+ .resource_table
+ .get::<BC::Resource>(rid)
+ .ok_or_else(bad_resource_id)?;
+ let bc = state.borrow().borrow::<BC>().clone();
+ bc.recv(&resource).await
+}
+
+pub fn init<BC: BroadcastChannel + 'static>(
+ bc: BC,
+ unstable: bool,
+) -> Extension {
+ Extension::builder()
+ .js(include_js_files!(
+ prefix "deno:extensions/broadcast_channel",
+ "01_broadcast_channel.js",
+ ))
+ .ops(vec![
+ (
+ "op_broadcast_subscribe",
+ op_sync(op_broadcast_subscribe::<BC>),
+ ),
+ (
+ "op_broadcast_unsubscribe",
+ op_sync(op_broadcast_unsubscribe::<BC>),
+ ),
+ ("op_broadcast_send", op_async(op_broadcast_send::<BC>)),
+ ("op_broadcast_recv", op_async(op_broadcast_recv::<BC>)),
+ ])
+ .state(move |state| {
+ state.put(bc.clone());
+ state.put(Unstable(unstable));
+ Ok(())
+ })
+ .build()
+}
+
+pub fn get_declaration() -> PathBuf {
+ PathBuf::from(env!("CARGO_MANIFEST_DIR"))
+ .join("lib.deno_broadcast_channel.d.ts")
+}
diff --git a/extensions/fetch/21_formdata.js b/extensions/fetch/21_formdata.js
index 379d5eca1..db4cfafa3 100644
--- a/extensions/fetch/21_formdata.js
+++ b/extensions/fetch/21_formdata.js
@@ -287,20 +287,20 @@
return finalBuffer;
}
- #createBoundary = () => {
+ #createBoundary() {
return (
"----------" +
Array.from(Array(32))
.map(() => Math.random().toString(36)[2] || 0)
.join("")
);
- };
+ }
/**
* @param {[string, string][]} headers
* @returns {void}
*/
- #writeHeaders = (headers) => {
+ #writeHeaders(headers) {
let buf = (this.chunks.length === 0) ? "" : "\r\n";
buf += `--${this.boundary}\r\n`;
@@ -310,7 +310,7 @@
buf += `\r\n`;
this.chunks.push(encoder.encode(buf));
- };
+ }
/**
* @param {string} field
@@ -318,11 +318,11 @@
* @param {string} [type]
* @returns {void}
*/
- #writeFileHeaders = (
+ #writeFileHeaders(
field,
filename,
type,
- ) => {
+ ) {
/** @type {[string, string][]} */
const headers = [
[
@@ -332,37 +332,37 @@
["Content-Type", type || "application/octet-stream"],
];
return this.#writeHeaders(headers);
- };
+ }
/**
* @param {string} field
* @returns {void}
*/
- #writeFieldHeaders = (field) => {
+ #writeFieldHeaders(field) {
/** @type {[string, string][]} */
const headers = [["Content-Disposition", `form-data; name="${field}"`]];
return this.#writeHeaders(headers);
- };
+ }
/**
* @param {string} field
* @param {string} value
* @returns {void}
*/
- #writeField = (field, value) => {
+ #writeField(field, value) {
this.#writeFieldHeaders(field);
this.chunks.push(encoder.encode(value));
- };
+ }
/**
* @param {string} field
* @param {File} value
* @returns {void}
*/
- #writeFile = (field, value) => {
+ #writeFile(field, value) {
this.#writeFileHeaders(field, value.name, value.type);
this.chunks.push(value[_byteSequence]);
- };
+ }
}
/**
@@ -418,7 +418,7 @@
* @param {string} headersText
* @returns {{ headers: Headers, disposition: Map<string, string> }}
*/
- #parseHeaders = (headersText) => {
+ #parseHeaders(headersText) {
const headers = new Headers();
const rawHeaders = headersText.split("\r\n");
for (const rawHeader of rawHeaders) {
@@ -436,7 +436,7 @@
);
return { headers, disposition };
- };
+ }
/**
* @returns {FormData}
diff --git a/extensions/file/02_filereader.js b/extensions/file/02_filereader.js
index 9575ab85a..428d8fd54 100644
--- a/extensions/file/02_filereader.js
+++ b/extensions/file/02_filereader.js
@@ -41,7 +41,7 @@
* @param {Blob} blob
* @param {{kind: "ArrayBuffer" | "Text" | "DataUrl" | "BinaryString", encoding?: string}} readtype
*/
- #readOperation = (blob, readtype) => {
+ #readOperation(blob, readtype) {
// 1. If fr’s state is "loading", throw an InvalidStateError DOMException.
if (this[state] === "loading") {
throw new DOMException(
@@ -221,7 +221,7 @@
}
}
})();
- };
+ }
constructor() {
super();
diff --git a/extensions/timers/Cargo.toml b/extensions/timers/Cargo.toml
index afdbf2e4c..6b68a02e9 100644
--- a/extensions/timers/Cargo.toml
+++ b/extensions/timers/Cargo.toml
@@ -16,3 +16,10 @@ path = "lib.rs"
[dependencies]
deno_core = { version = "0.88.1", path = "../../core" }
tokio = { version = "1.6.1", features = ["full"] }
+
+[dev-dependencies]
+deno_bench_util = { version = "0.1.0", path = "../../bench_util" }
+
+[[bench]]
+name = "timers_ops"
+harness = false
diff --git a/extensions/timers/benches/timers_ops.rs b/extensions/timers/benches/timers_ops.rs
new file mode 100644
index 000000000..e31fe31ac
--- /dev/null
+++ b/extensions/timers/benches/timers_ops.rs
@@ -0,0 +1,36 @@
+use deno_core::Extension;
+
+use deno_bench_util::bench_or_profile;
+use deno_bench_util::bencher::{benchmark_group, Bencher};
+use deno_bench_util::{bench_js_async, bench_js_sync};
+
+fn setup() -> Vec<Extension> {
+ vec![
+ deno_timers::init::<deno_timers::NoTimersPermission>(),
+ Extension::builder()
+ .js(vec![
+ ("setup",
+ Box::new(|| Ok(r#"
+ const { opNow, setTimeout, handleTimerMacrotask } = globalThis.__bootstrap.timers;
+ Deno.core.setMacrotaskCallback(handleTimerMacrotask);
+ "#.to_owned())),
+ ),
+ ])
+ .state(|state| {
+ state.put(deno_timers::NoTimersPermission{});
+ Ok(())
+ })
+ .build()
+ ]
+}
+
+fn bench_op_now(b: &mut Bencher) {
+ bench_js_sync(b, r#"opNow();"#, setup);
+}
+
+fn bench_set_timeout(b: &mut Bencher) {
+ bench_js_async(b, r#"setTimeout(() => {}, 0);"#, setup);
+}
+
+benchmark_group!(benches, bench_op_now, bench_set_timeout,);
+bench_or_profile!(benches);
diff --git a/extensions/url/00_url.js b/extensions/url/00_url.js
index 340937748..f6f3335dd 100644
--- a/extensions/url/00_url.js
+++ b/extensions/url/00_url.js
@@ -58,14 +58,14 @@
urls.set(this, null);
}
- #updateUrlSearch = () => {
+ #updateUrlSearch() {
const url = urls.get(this);
if (url == null) {
return;
}
const parseArgs = { href: url.href, setSearch: this.toString() };
parts.set(url, core.opSync("op_url_parse", parseArgs));
- };
+ }
append(name, value) {
requiredArguments("URLSearchParams.append", arguments.length, 2);
@@ -227,7 +227,7 @@
return `${this.constructor.name} ${inspect(object)}`;
}
- #updateSearchParams = () => {
+ #updateSearchParams() {
if (this.#searchParams != null) {
const params = paramLists.get(this.#searchParams);
const newParams = core.opSync(
@@ -236,7 +236,7 @@
);
params.splice(0, params.length, ...newParams);
}
- };
+ }
get hash() {
return parts.get(this).hash;
diff --git a/extensions/url/Cargo.toml b/extensions/url/Cargo.toml
index 57f82bba8..f87931ece 100644
--- a/extensions/url/Cargo.toml
+++ b/extensions/url/Cargo.toml
@@ -20,7 +20,7 @@ percent-encoding = "2.1.0"
serde = { version = "1.0.125", features = ["derive"] }
[dev-dependencies]
-bencher = "0.1"
+deno_bench_util = { version = "0.1.0", path = "../../bench_util" }
[[bench]]
name = "url_ops"
diff --git a/extensions/url/benches/url_ops.rs b/extensions/url/benches/url_ops.rs
index 8b3cf2705..c390af0d8 100644
--- a/extensions/url/benches/url_ops.rs
+++ b/extensions/url/benches/url_ops.rs
@@ -1,35 +1,26 @@
-use bencher::{benchmark_group, benchmark_main, Bencher};
+use deno_bench_util::bench_js_sync;
+use deno_bench_util::bench_or_profile;
+use deno_bench_util::bencher::{benchmark_group, Bencher};
-use deno_core::v8;
-use deno_core::JsRuntime;
-use deno_core::RuntimeOptions;
+use deno_core::Extension;
-fn create_js_runtime() -> JsRuntime {
- let mut runtime = JsRuntime::new(RuntimeOptions {
- extensions: vec![deno_url::init()],
- ..Default::default()
- });
-
- runtime
- .execute("setup", "const { URL } = globalThis.__bootstrap.url;")
- .unwrap();
-
- runtime
-}
-
-pub fn bench_runtime_js(b: &mut Bencher, src: &str) {
- let mut runtime = create_js_runtime();
- let scope = &mut runtime.handle_scope();
- let code = v8::String::new(scope, src).unwrap();
- let script = v8::Script::compile(scope, code, None).unwrap();
- b.iter(|| {
- script.run(scope).unwrap();
- });
+fn setup() -> Vec<Extension> {
+ vec![
+ deno_url::init(),
+ Extension::builder()
+ .js(vec![(
+ "setup",
+ Box::new(|| {
+ Ok(r#"const { URL } = globalThis.__bootstrap.url;"#.to_owned())
+ }),
+ )])
+ .build(),
+ ]
}
fn bench_url_parse(b: &mut Bencher) {
- bench_runtime_js(b, r#"new URL(`http://www.google.com/`);"#);
+ bench_js_sync(b, r#"new URL(`http://www.google.com/`);"#, setup);
}
benchmark_group!(benches, bench_url_parse,);
-benchmark_main!(benches);
+bench_or_profile!(benches);
diff --git a/extensions/web/02_event.js b/extensions/web/02_event.js
index b6b5609bc..8ee6acc61 100644
--- a/extensions/web/02_event.js
+++ b/extensions/web/02_event.js
@@ -1117,6 +1117,10 @@
}
class MessageEvent extends Event {
+ get source() {
+ return null;
+ }
+
constructor(type, eventInitDict) {
super(type, {
bubbles: eventInitDict?.bubbles ?? false,
@@ -1208,5 +1212,6 @@
};
window.__bootstrap.event = {
setIsTrusted,
+ setTarget,
};
})(this);
diff --git a/extensions/webstorage/lib.rs b/extensions/webstorage/lib.rs
index 8b3e206fb..d2170890e 100644
--- a/extensions/webstorage/lib.rs
+++ b/extensions/webstorage/lib.rs
@@ -13,9 +13,9 @@ use std::fmt;
use std::path::PathBuf;
#[derive(Clone)]
-struct LocationDataDir(PathBuf);
+struct OriginStorageDir(PathBuf);
-pub fn init(location_data_dir: Option<PathBuf>) -> Extension {
+pub fn init(origin_storage_dir: Option<PathBuf>) -> Extension {
Extension::builder()
.js(include_js_files!(
prefix "deno:extensions/webstorage",
@@ -34,8 +34,8 @@ pub fn init(location_data_dir: Option<PathBuf>) -> Extension {
),
])
.state(move |state| {
- if let Some(location_data_dir) = location_data_dir.clone() {
- state.put(LocationDataDir(location_data_dir));
+ if let Some(origin_storage_dir) = origin_storage_dir.clone() {
+ state.put(OriginStorageDir(origin_storage_dir));
}
Ok(())
})
@@ -55,7 +55,7 @@ fn get_webstorage(
) -> Result<&Connection, AnyError> {
let conn = if persistent {
if state.try_borrow::<LocalStorage>().is_none() {
- let path = state.try_borrow::<LocationDataDir>().ok_or_else(|| {
+ let path = state.try_borrow::<OriginStorageDir>().ok_or_else(|| {
DomExceptionNotSupportedError::new(
"LocalStorage is not supported in this context.",
)