diff --git a/extensions/broadcast_channel/01_broadcast_channel.js b/extensions/broadcast_channel/01_broadcast_channel.js index cab4fa41cd0729..c921132fab288c 100644 --- a/extensions/broadcast_channel/01_broadcast_channel.js +++ b/extensions/broadcast_channel/01_broadcast_channel.js @@ -4,6 +4,7 @@ ((window) => { const core = window.Deno.core; const webidl = window.__bootstrap.webidl; + const { setTarget } = window.__bootstrap.event; const handlerSymbol = Symbol("eventHandlers"); function makeWrappedHandler(handler) { @@ -21,7 +22,10 @@ // HTML specification section 8.1.5.1 Object.defineProperty(emitter, `on${name}`, { get() { - return this[handlerSymbol]?.get(name)?.handler; + // 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]) { @@ -81,14 +85,23 @@ throw new DOMException("Already closed", "InvalidStateError"); } + const prefix = "Failed to execute 'postMessage' on 'BroadcastChannel'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + + if (typeof message === "function" || typeof message === "symbol") { + throw new DOMException("Uncloneable value", "DataCloneError"); + } + core.opAsync("op_broadcast_send", this[_rid], core.serialize(message)); } close() { webidl.assertBranded(this, BroadcastChannel); + const closed = this[_closed]; this[_closed] = true; - core.close(this[_rid]); + + if (!closed) core.close(this[_rid]); } async #eventLoop() { @@ -102,11 +115,13 @@ return; } + const location = window.location; + const event = new MessageEvent("message", { data: core.deserialize(new Uint8Array(message)), - origin: window.location, + origin: location.protocol + "//" + location.host, }); - event.target = this; + setTarget(event, this); this.dispatchEvent(event); } diff --git a/extensions/broadcast_channel/lib.rs b/extensions/broadcast_channel/lib.rs index 62a31aed9d3456..614474495f6924 100644 --- a/extensions/broadcast_channel/lib.rs +++ b/extensions/broadcast_channel/lib.rs @@ -132,13 +132,12 @@ pub async fn op_broadcast_next_event( rid: ResourceId, _bufs: Option, ) -> Result>, AnyError> { - let resource = state - .borrow() - .resource_table - .get::(rid) - .ok_or_else(bad_resource_id)?; + let resource = state.borrow().resource_table.get::(rid); - B::next_event(&resource).await + match resource { + Some(resource) => B::next_event(&resource).await, + None => Ok(None), + } } pub fn init() -> Extension { diff --git a/extensions/web/02_event.js b/extensions/web/02_event.js index 35112132e05a21..2b6d3a0e491452 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/tools/wpt.ts b/tools/wpt.ts index 12e9047a488693..327899e80165dc 100755 --- a/tools/wpt.ts +++ b/tools/wpt.ts @@ -506,21 +506,32 @@ function discoverTestsToRun( continue; } - for ( - const [path, options] of entry.slice( - 1, - ) as ManifestTestVariation[] - ) { - if (!path) continue; - const url = new URL(path, "http://web-platform.test:8000"); - if (!url.pathname.endsWith(".any.html")) continue; + if (key.endsWith(".html")) { + const url = new URL(sourcePath, "http://web-platform.test:8000"); testsToRun.push({ sourcePath, path: url.pathname + url.search, url, - options, + options: {}, expectation, }); + } else { + for ( + const [path, options] of entry.slice( + 1, + ) as ManifestTestVariation[] + ) { + if (!path) continue; + const url = new URL(path, "http://web-platform.test:8000"); + if (!url.pathname.endsWith(".any.html")) continue; + testsToRun.push({ + sourcePath, + path: url.pathname + url.search, + url, + options, + expectation, + }); + } } } else { walk(entry, expectation, sourcePath); diff --git a/tools/wpt/expectation.json b/tools/wpt/expectation.json index 6eec573cb89d61..84d46814045f48 100644 --- a/tools/wpt/expectation.json +++ b/tools/wpt/expectation.json @@ -1064,6 +1064,12 @@ } } }, + "webmessaging": { + "broadcastchannel": { + "basics.html": true, + "interface.html": true + } + }, "xhr": { "formdata": { "append.any.js": true,