From a742af91930b23e65603f7fcfd9efa5e9ae51b00 Mon Sep 17 00:00:00 2001 From: Espen Hovlandsdal Date: Thu, 13 Aug 2026 13:19:10 -0700 Subject: [PATCH 1/2] Honor all MessageEventInit members in MessageEvent constructor --- src/workerd/api/events.c++ | 59 ++++++++++++----- src/workerd/api/events.h | 40 +++++++---- src/workerd/api/eventsource.c++ | 3 +- src/workerd/api/tests/events-test.js | 66 +++++++++++++++++++ .../experimental/index.d.ts | 10 ++- .../generated-snapshot/experimental/index.ts | 10 ++- types/generated-snapshot/index.d.ts | 10 ++- types/generated-snapshot/index.ts | 10 ++- 8 files changed, 172 insertions(+), 36 deletions(-) diff --git a/src/workerd/api/events.c++ b/src/workerd/api/events.c++ index ad8a46c453c..e9e43afcf1c 100644 --- a/src/workerd/api/events.c++ +++ b/src/workerd/api/events.c++ @@ -19,48 +19,73 @@ MessageEvent::MessageEvent(jsg::Lock& js, const jsg::JsValue& data, kj::String lastEventId, kj::Maybe> source, - kj::Maybe urlForOrigin) - : Event(kMessageEventName), + kj::Maybe origin, + Event::Init init) + : Event(kMessageEventName, kj::mv(init)), data(jsg::JsRef(js, data)), lastEventId(kj::mv(lastEventId)), maybeSource(kj::mv(source)), - maybeOrigin(urlForOrigin.map([](auto& url) { return url.getOrigin(); })) {} + maybeOrigin(kj::mv(origin)) {} MessageEvent::MessageEvent(jsg::Lock& js, jsg::JsRef data, kj::String lastEventId, kj::Maybe> source, - kj::Maybe urlForOrigin) - : Event(kMessageEventName), + kj::Maybe origin, + Event::Init init) + : Event(kMessageEventName, kj::mv(init)), data(kj::mv(data)), lastEventId(kj::mv(lastEventId)), maybeSource(kj::mv(source)), - maybeOrigin(urlForOrigin.map([](auto& url) { return url.getOrigin(); })) {} + maybeOrigin(kj::mv(origin)) {} MessageEvent::MessageEvent(jsg::Lock& js, kj::String type, const jsg::JsValue& data, kj::String lastEventId, kj::Maybe> source, - kj::Maybe urlForOrigin) - : Event(kj::mv(type)), + kj::Maybe origin, + Event::Init init) + : Event(kj::mv(type), kj::mv(init)), data(jsg::JsRef(js, kj::mv(data))), lastEventId(kj::mv(lastEventId)), maybeSource(kj::mv(source)), - maybeOrigin(urlForOrigin.map([](auto& url) { return url.getOrigin(); })) {} + maybeOrigin(kj::mv(origin)) {} MessageEvent::MessageEvent(jsg::Lock& js, kj::String type, kj::OneOf, jsg::Ref> data, kj::String lastEventId, kj::Maybe> source, - kj::Maybe urlForOrigin) - : Event(kj::mv(type)), + kj::Maybe origin, + Event::Init init) + : Event(kj::mv(type), kj::mv(init)), data(kj::mv(data)), lastEventId(kj::mv(lastEventId)), maybeSource(kj::mv(source)), - maybeOrigin(urlForOrigin.map([](auto& url) { return url.getOrigin(); })) {} + maybeOrigin(kj::mv(origin)) {} jsg::Ref MessageEvent::constructor( - jsg::Lock& js, kj::String type, Initializer initializer) { - return js.alloc(js, kj::mv(type), kj::mv(initializer.data)); + jsg::Lock& js, kj::String type, jsg::Optional maybeInitializer) { + Initializer initializer = kj::mv(maybeInitializer).orDefault({}); + + // Per the spec, MessageEventInit's data member defaults to null. + kj::OneOf, jsg::Ref> data = + jsg::JsRef(js, js.null()); + KJ_IF_SOME(d, initializer.data) { + data = kj::mv(d); + } + + kj::Maybe origin; + KJ_IF_SOME(o, initializer.origin) { + origin = kj::String(kj::mv(o)); + } + + return js.alloc(js, kj::mv(type), kj::mv(data), + kj::mv(initializer.lastEventId).orDefault(kj::String()), kj::mv(initializer.source), + kj::mv(origin), + Event::Init{ + .bubbles = initializer.bubbles, + .cancelable = initializer.cancelable, + .composed = initializer.composed, + }); } kj::OneOf> MessageEvent::getData(jsg::Lock& js) { @@ -75,8 +100,8 @@ kj::OneOf> MessageEvent::getData(jsg::Lock& js) { KJ_UNREACHABLE; } -kj::Maybe> MessageEvent::getOrigin() { - return maybeOrigin.map([](auto& a) -> kj::ArrayPtr { return a.asPtr(); }); +kj::Maybe MessageEvent::getOrigin() { + return maybeOrigin.map([](kj::String& origin) -> kj::StringPtr { return origin; }); } kj::StringPtr MessageEvent::getLastEventId() { @@ -106,6 +131,8 @@ void MessageEvent::visitForMemoryInfo(jsg::MemoryTracker& tracker) const { } } tracker.trackField("source", maybeSource); + tracker.trackField("lastEventId", lastEventId); + tracker.trackField("origin", maybeOrigin); } void MessageEvent::visitForGc(jsg::GcVisitor& visitor) { diff --git a/src/workerd/api/events.h b/src/workerd/api/events.h index 2cac81f2aea..430906504d1 100644 --- a/src/workerd/api/events.h +++ b/src/workerd/api/events.h @@ -16,42 +16,60 @@ class MessageEvent final: public Event { const jsg::JsValue& data, kj::String lastEventId = kj::String(), kj::Maybe> source = kj::none, - kj::Maybe urlForOrigin = kj::none); + kj::Maybe origin = kj::none, + Event::Init init = {}); MessageEvent(jsg::Lock& js, jsg::JsRef data, kj::String lastEventId = kj::String(), kj::Maybe> source = kj::none, - kj::Maybe urlForOrigin = kj::none); + kj::Maybe origin = kj::none, + Event::Init init = {}); MessageEvent(jsg::Lock& js, kj::String type, const jsg::JsValue& data, kj::String lastEventId = kj::String(), kj::Maybe> source = kj::none, - kj::Maybe urlForOrigin = kj::none); + kj::Maybe origin = kj::none, + Event::Init init = {}); MessageEvent(jsg::Lock& js, kj::String type, kj::OneOf, jsg::Ref> data, kj::String lastEventId = kj::String(), kj::Maybe> source = kj::none, - kj::Maybe urlForOrigin = kj::none); + kj::Maybe origin = kj::none, + Event::Init init = {}); struct Initializer { - jsg::JsRef data; - - JSG_STRUCT(data); + jsg::Optional> data; + jsg::Optional origin; + jsg::Optional lastEventId; + jsg::Optional> source; + + // Per the spec, MessageEventInit inherits from EventInit. JSG_STRUCT has no + // notion of dictionary inheritance, so EventInit's members are repeated here + // and forwarded on to the Event base class. + jsg::Optional bubbles; + jsg::Optional cancelable; + jsg::Optional composed; + + // Note that the spec also defines a `ports` member. We do not support + // transferring MessagePorts in a MessageEvent (see getPorts() below), so it + // is intentionally omitted here rather than being silently ignored. + + JSG_STRUCT(data, origin, lastEventId, source, bubbles, cancelable, composed); JSG_STRUCT_TS_OVERRIDE(MessageEventInit { - data: ArrayBuffer | string; + data?: any; }); }; static jsg::Ref constructor( - jsg::Lock& js, kj::String type, Initializer initializer); + jsg::Lock& js, kj::String type, jsg::Optional initializer); kj::OneOf> getData(jsg::Lock& js); - kj::Maybe> getOrigin(); + kj::Maybe getOrigin(); kj::StringPtr getLastEventId(); @@ -82,7 +100,7 @@ class MessageEvent final: public Event { kj::OneOf, jsg::Ref> data; kj::String lastEventId; kj::Maybe> maybeSource; - kj::Maybe> maybeOrigin; + kj::Maybe maybeOrigin; void visitForGc(jsg::GcVisitor& visitor); }; diff --git a/src/workerd/api/eventsource.c++ b/src/workerd/api/eventsource.c++ index 21e3e35687c..bbc769c39c3 100644 --- a/src/workerd/api/eventsource.c++ +++ b/src/workerd/api/eventsource.c++ @@ -310,7 +310,8 @@ void EventSource::notifyMessages(jsg::Lock& js, kj::Array messag kj::String type = kj::mv(message.event).orDefault([]() { return kj::str("message"); }); dispatchEventImpl(js, js.alloc(js, kj::mv(type), js.str(data), kj::mv(message.id), - kj::none /** source **/, impl.map([](FetchImpl& i) -> jsg::Url& { return i.url; }))); + kj::none /** source **/, + impl.map([](FetchImpl& i) { return kj::str(i.url.getOrigin()); }))); } }, [&](jsg::Value exception) { // If we end up with an exception being thrown in one of the event handlers, we will diff --git a/src/workerd/api/tests/events-test.js b/src/workerd/api/tests/events-test.js index 58f0a4eb705..35eb5854205 100644 --- a/src/workerd/api/tests/events-test.js +++ b/src/workerd/api/tests/events-test.js @@ -434,6 +434,72 @@ export const customEvent = { }, }; +export const messageEvent = { + test() { + // The MessageEvent constructor second argument is optional, and every member + // of MessageEventInit defaults per the spec. + const empty = new MessageEvent('foo'); + strictEqual(empty.type, 'foo'); + strictEqual(empty.data, null); + strictEqual(empty.lastEventId, ''); + strictEqual(empty.source, null); + deepStrictEqual(empty.ports, []); + + // MessageEventInit's own members are all honored. + const event = new MessageEvent('foo', { + data: { a: 123 }, + lastEventId: '123', + origin: 'https://example.org', + }); + ok(event instanceof Event); + strictEqual(event.type, 'foo'); + deepStrictEqual(event.data, { a: 123 }); + strictEqual(event.lastEventId, '123'); + strictEqual(event.origin, 'https://example.org'); + + // MessageEventInit inherits from EventInit, so those members are honored too. + const bubbling = new MessageEvent('foo', { + data: 'x', + bubbles: true, + cancelable: true, + composed: true, + }); + strictEqual(bubbling.bubbles, true); + strictEqual(bubbling.cancelable, true); + strictEqual(bubbling.composed, true); + + // lastEventId is stringified rather than requiring a string. + strictEqual( + new MessageEvent('foo', { lastEventId: 123 }).lastEventId, + '123' + ); + + // The members survive dispatch, and remain read only. + const target = new EventTarget(); + let dispatchCount = 0; + target.addEventListener('foo', (dispatched) => { + strictEqual(dispatched.lastEventId, '123'); + strictEqual(dispatched.origin, 'https://example.org'); + dispatchCount++; + }); + target.dispatchEvent(event); + strictEqual(dispatchCount, 1); + + throws(() => (event.data = 'nope')); + throws(() => (event.lastEventId = 'nope')); + throws(() => (event.origin = 'nope')); + + // A MessagePort may be used as the source. Anything else is rejected. + // MessageChannel is only exposed globally with a recent enough compatibility + // date, and this test runs under the oldest one too, so guard on it. + if (typeof MessageChannel === 'function') { + const { port1 } = new MessageChannel(); + strictEqual(new MessageEvent('foo', { source: port1 }).source, port1); + } + throws(() => new MessageEvent('foo', { source: 'not a port' })); + }, +}; + export const closeEvent = { test() { // The CloseEvent constructor second argument is optional. Our implementation diff --git a/types/generated-snapshot/experimental/index.d.ts b/types/generated-snapshot/experimental/index.d.ts index 557f4a99a97..cec96284bce 100755 --- a/types/generated-snapshot/experimental/index.d.ts +++ b/types/generated-snapshot/experimental/index.d.ts @@ -1700,7 +1700,7 @@ interface ErrorEventErrorEventInit { * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent) */ declare class MessageEvent extends Event { - constructor(type: string, initializer: MessageEventInit); + constructor(type: string, initializer?: MessageEventInit); /** * The **`data`** read-only property of the MessageEvent interface represents the data sent by the message emitter. * @@ -1733,7 +1733,13 @@ declare class MessageEvent extends Event { readonly ports: MessagePort[]; } interface MessageEventInit { - data: ArrayBuffer | string; + data?: any; + origin?: string; + lastEventId?: string; + source?: MessagePort; + bubbles?: boolean; + cancelable?: boolean; + composed?: boolean; } /** * The **`PromiseRejectionEvent`** interface represents events which are sent to the global script context when JavaScript Promises are rejected. These events are particularly useful for telemetry and debugging purposes. diff --git a/types/generated-snapshot/experimental/index.ts b/types/generated-snapshot/experimental/index.ts index 3f152773310..b5834b872b1 100755 --- a/types/generated-snapshot/experimental/index.ts +++ b/types/generated-snapshot/experimental/index.ts @@ -1704,7 +1704,7 @@ export interface ErrorEventErrorEventInit { * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent) */ export declare class MessageEvent extends Event { - constructor(type: string, initializer: MessageEventInit); + constructor(type: string, initializer?: MessageEventInit); /** * The **`data`** read-only property of the MessageEvent interface represents the data sent by the message emitter. * @@ -1737,7 +1737,13 @@ export declare class MessageEvent extends Event { readonly ports: MessagePort[]; } export interface MessageEventInit { - data: ArrayBuffer | string; + data?: any; + origin?: string; + lastEventId?: string; + source?: MessagePort; + bubbles?: boolean; + cancelable?: boolean; + composed?: boolean; } /** * The **`PromiseRejectionEvent`** interface represents events which are sent to the global script context when JavaScript Promises are rejected. These events are particularly useful for telemetry and debugging purposes. diff --git a/types/generated-snapshot/index.d.ts b/types/generated-snapshot/index.d.ts index 18bf68a6767..1578c64637f 100755 --- a/types/generated-snapshot/index.d.ts +++ b/types/generated-snapshot/index.d.ts @@ -1675,7 +1675,7 @@ interface ErrorEventErrorEventInit { * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent) */ declare class MessageEvent extends Event { - constructor(type: string, initializer: MessageEventInit); + constructor(type: string, initializer?: MessageEventInit); /** * The **`data`** read-only property of the MessageEvent interface represents the data sent by the message emitter. * @@ -1708,7 +1708,13 @@ declare class MessageEvent extends Event { readonly ports: MessagePort[]; } interface MessageEventInit { - data: ArrayBuffer | string; + data?: any; + origin?: string; + lastEventId?: string; + source?: MessagePort; + bubbles?: boolean; + cancelable?: boolean; + composed?: boolean; } /** * The **`PromiseRejectionEvent`** interface represents events which are sent to the global script context when JavaScript Promises are rejected. These events are particularly useful for telemetry and debugging purposes. diff --git a/types/generated-snapshot/index.ts b/types/generated-snapshot/index.ts index beed08a500f..2cddbc1ba93 100755 --- a/types/generated-snapshot/index.ts +++ b/types/generated-snapshot/index.ts @@ -1679,7 +1679,7 @@ export interface ErrorEventErrorEventInit { * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent) */ export declare class MessageEvent extends Event { - constructor(type: string, initializer: MessageEventInit); + constructor(type: string, initializer?: MessageEventInit); /** * The **`data`** read-only property of the MessageEvent interface represents the data sent by the message emitter. * @@ -1712,7 +1712,13 @@ export declare class MessageEvent extends Event { readonly ports: MessagePort[]; } export interface MessageEventInit { - data: ArrayBuffer | string; + data?: any; + origin?: string; + lastEventId?: string; + source?: MessagePort; + bubbles?: boolean; + cancelable?: boolean; + composed?: boolean; } /** * The **`PromiseRejectionEvent`** interface represents events which are sent to the global script context when JavaScript Promises are rejected. These events are particularly useful for telemetry and debugging purposes. From b4b570aaafea45b0be4eb08c69382f89cd192eab Mon Sep 17 00:00:00 2001 From: Espen Hovlandsdal Date: Sat, 15 Aug 2026 11:16:33 -0700 Subject: [PATCH 2/2] Store MessageEventInit origin verbatim and default it to the empty string --- src/workerd/api/events.c++ | 22 +++++++++++------- src/workerd/api/events.h | 19 +++++++-------- src/workerd/api/eventsource.c++ | 3 +-- src/workerd/api/tests/events-test.js | 23 +++++++++++++++++++ .../experimental/index.d.ts | 2 +- .../generated-snapshot/experimental/index.ts | 2 +- types/generated-snapshot/index.d.ts | 2 +- types/generated-snapshot/index.ts | 2 +- 8 files changed, 52 insertions(+), 23 deletions(-) diff --git a/src/workerd/api/events.c++ b/src/workerd/api/events.c++ index e9e43afcf1c..d97ecdb8e8a 100644 --- a/src/workerd/api/events.c++ +++ b/src/workerd/api/events.c++ @@ -19,7 +19,7 @@ MessageEvent::MessageEvent(jsg::Lock& js, const jsg::JsValue& data, kj::String lastEventId, kj::Maybe> source, - kj::Maybe origin, + kj::Maybe> origin, Event::Init init) : Event(kMessageEventName, kj::mv(init)), data(jsg::JsRef(js, data)), @@ -30,7 +30,7 @@ MessageEvent::MessageEvent(jsg::Lock& js, jsg::JsRef data, kj::String lastEventId, kj::Maybe> source, - kj::Maybe origin, + kj::Maybe> origin, Event::Init init) : Event(kMessageEventName, kj::mv(init)), data(kj::mv(data)), @@ -42,7 +42,7 @@ MessageEvent::MessageEvent(jsg::Lock& js, const jsg::JsValue& data, kj::String lastEventId, kj::Maybe> source, - kj::Maybe origin, + kj::Maybe> origin, Event::Init init) : Event(kj::mv(type), kj::mv(init)), data(jsg::JsRef(js, kj::mv(data))), @@ -54,7 +54,7 @@ MessageEvent::MessageEvent(jsg::Lock& js, kj::OneOf, jsg::Ref> data, kj::String lastEventId, kj::Maybe> source, - kj::Maybe origin, + kj::Maybe> origin, Event::Init init) : Event(kj::mv(type), kj::mv(init)), data(kj::mv(data)), @@ -73,9 +73,12 @@ jsg::Ref MessageEvent::constructor( data = kj::mv(d); } - kj::Maybe origin; + // A MessageEvent's origin is "an origin, a string, or null". The origin getter only + // serializes when it holds an actual origin; a string is returned as given. The + // initializer's origin is a USVString, so it is stored verbatim and never parsed. + kj::Maybe> origin; KJ_IF_SOME(o, initializer.origin) { - origin = kj::String(kj::mv(o)); + origin = kj::Array(kj::heapArray(o.asPtr())); } return js.alloc(js, kj::mv(type), kj::mv(data), @@ -100,8 +103,11 @@ kj::OneOf> MessageEvent::getData(jsg::Lock& js) { KJ_UNREACHABLE; } -kj::Maybe MessageEvent::getOrigin() { - return maybeOrigin.map([](kj::String& origin) -> kj::StringPtr { return origin; }); +kj::ArrayPtr MessageEvent::getOrigin() { + // Per the spec, an origin that was never set is reported as the empty string, not null. + return maybeOrigin.map([](auto& a) -> kj::ArrayPtr { + return a.asPtr(); + }).orDefault(nullptr); } kj::StringPtr MessageEvent::getLastEventId() { diff --git a/src/workerd/api/events.h b/src/workerd/api/events.h index 430906504d1..c93c51180d8 100644 --- a/src/workerd/api/events.h +++ b/src/workerd/api/events.h @@ -16,14 +16,14 @@ class MessageEvent final: public Event { const jsg::JsValue& data, kj::String lastEventId = kj::String(), kj::Maybe> source = kj::none, - kj::Maybe origin = kj::none, + kj::Maybe> origin = kj::none, Event::Init init = {}); MessageEvent(jsg::Lock& js, jsg::JsRef data, kj::String lastEventId = kj::String(), kj::Maybe> source = kj::none, - kj::Maybe origin = kj::none, + kj::Maybe> origin = kj::none, Event::Init init = {}); MessageEvent(jsg::Lock& js, @@ -31,7 +31,7 @@ class MessageEvent final: public Event { const jsg::JsValue& data, kj::String lastEventId = kj::String(), kj::Maybe> source = kj::none, - kj::Maybe origin = kj::none, + kj::Maybe> origin = kj::none, Event::Init init = {}); MessageEvent(jsg::Lock& js, @@ -39,7 +39,7 @@ class MessageEvent final: public Event { kj::OneOf, jsg::Ref> data, kj::String lastEventId = kj::String(), kj::Maybe> source = kj::none, - kj::Maybe origin = kj::none, + kj::Maybe> origin = kj::none, Event::Init init = {}); struct Initializer { @@ -55,9 +55,10 @@ class MessageEvent final: public Event { jsg::Optional cancelable; jsg::Optional composed; - // Note that the spec also defines a `ports` member. We do not support - // transferring MessagePorts in a MessageEvent (see getPorts() below), so it - // is intentionally omitted here rather than being silently ignored. + // Note that the spec also defines a `ports` member. We do not support transferring + // MessagePorts in a MessageEvent (see getPorts() below), so it is omitted here and, + // like any other unrecognized member, is dropped. `ports` therefore always reads + // back as an empty array even when one was supplied. JSG_STRUCT(data, origin, lastEventId, source, bubbles, cancelable, composed); JSG_STRUCT_TS_OVERRIDE(MessageEventInit { @@ -69,7 +70,7 @@ class MessageEvent final: public Event { kj::OneOf> getData(jsg::Lock& js); - kj::Maybe getOrigin(); + kj::ArrayPtr getOrigin(); kj::StringPtr getLastEventId(); @@ -100,7 +101,7 @@ class MessageEvent final: public Event { kj::OneOf, jsg::Ref> data; kj::String lastEventId; kj::Maybe> maybeSource; - kj::Maybe maybeOrigin; + kj::Maybe> maybeOrigin; void visitForGc(jsg::GcVisitor& visitor); }; diff --git a/src/workerd/api/eventsource.c++ b/src/workerd/api/eventsource.c++ index bbc769c39c3..d8097691839 100644 --- a/src/workerd/api/eventsource.c++ +++ b/src/workerd/api/eventsource.c++ @@ -310,8 +310,7 @@ void EventSource::notifyMessages(jsg::Lock& js, kj::Array messag kj::String type = kj::mv(message.event).orDefault([]() { return kj::str("message"); }); dispatchEventImpl(js, js.alloc(js, kj::mv(type), js.str(data), kj::mv(message.id), - kj::none /** source **/, - impl.map([](FetchImpl& i) { return kj::str(i.url.getOrigin()); }))); + kj::none /** source **/, impl.map([](FetchImpl& i) { return i.url.getOrigin(); }))); } }, [&](jsg::Value exception) { // If we end up with an exception being thrown in one of the event handlers, we will diff --git a/src/workerd/api/tests/events-test.js b/src/workerd/api/tests/events-test.js index 35eb5854205..2bbb6418b56 100644 --- a/src/workerd/api/tests/events-test.js +++ b/src/workerd/api/tests/events-test.js @@ -442,6 +442,7 @@ export const messageEvent = { strictEqual(empty.type, 'foo'); strictEqual(empty.data, null); strictEqual(empty.lastEventId, ''); + strictEqual(empty.origin, ''); strictEqual(empty.source, null); deepStrictEqual(empty.ports, []); @@ -457,6 +458,28 @@ export const messageEvent = { strictEqual(event.lastEventId, '123'); strictEqual(event.origin, 'https://example.org'); + // A MessageEvent's origin is "an origin, a string, or null", and the getter only + // serializes when it holds an actual origin. MessageEventInit's origin is a + // USVString, so it is returned exactly as given rather than parsed or normalized. + for (const origin of [ + 'https://example.org/some/path?a=b', + 'HTTPS://EXAMPLE.ORG', + 'https://example.org:443', + 'not a url', + // "null" is the serialization of an opaque origin, so an event carrying one has + // to survive a round trip back through the constructor. + 'null', + '', + ]) { + strictEqual(new MessageEvent('foo', { origin }).origin, origin); + } + + // origin is a non-nullable USVString, so it is never null and a non-string is + // coerced rather than rejected. Only undefined counts as "not provided". + strictEqual(new MessageEvent('foo', { origin: undefined }).origin, ''); + strictEqual(new MessageEvent('foo', { origin: null }).origin, 'null'); + strictEqual(new MessageEvent('foo', { origin: 123 }).origin, '123'); + // MessageEventInit inherits from EventInit, so those members are honored too. const bubbling = new MessageEvent('foo', { data: 'x', diff --git a/types/generated-snapshot/experimental/index.d.ts b/types/generated-snapshot/experimental/index.d.ts index cec96284bce..9967632403e 100755 --- a/types/generated-snapshot/experimental/index.d.ts +++ b/types/generated-snapshot/experimental/index.d.ts @@ -1712,7 +1712,7 @@ declare class MessageEvent extends Event { * * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent/origin) */ - readonly origin: string | null; + readonly origin: string; /** * The **`lastEventId`** read-only property of the MessageEvent interface is a string representing a unique ID for the event. * diff --git a/types/generated-snapshot/experimental/index.ts b/types/generated-snapshot/experimental/index.ts index b5834b872b1..9ef70628704 100755 --- a/types/generated-snapshot/experimental/index.ts +++ b/types/generated-snapshot/experimental/index.ts @@ -1716,7 +1716,7 @@ export declare class MessageEvent extends Event { * * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent/origin) */ - readonly origin: string | null; + readonly origin: string; /** * The **`lastEventId`** read-only property of the MessageEvent interface is a string representing a unique ID for the event. * diff --git a/types/generated-snapshot/index.d.ts b/types/generated-snapshot/index.d.ts index 1578c64637f..30eed1d79c5 100755 --- a/types/generated-snapshot/index.d.ts +++ b/types/generated-snapshot/index.d.ts @@ -1687,7 +1687,7 @@ declare class MessageEvent extends Event { * * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent/origin) */ - readonly origin: string | null; + readonly origin: string; /** * The **`lastEventId`** read-only property of the MessageEvent interface is a string representing a unique ID for the event. * diff --git a/types/generated-snapshot/index.ts b/types/generated-snapshot/index.ts index 2cddbc1ba93..7545d844e79 100755 --- a/types/generated-snapshot/index.ts +++ b/types/generated-snapshot/index.ts @@ -1691,7 +1691,7 @@ export declare class MessageEvent extends Event { * * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent/origin) */ - readonly origin: string | null; + readonly origin: string; /** * The **`lastEventId`** read-only property of the MessageEvent interface is a string representing a unique ID for the event. *