Skip to content

Commit

Permalink
ExtendableMessageEvent.ports should return the same object
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=273542
rdar://127350353

Reviewed by Chris Dumez.

Reuse what was done for MessageEvent.ports in ExtendableMessageEvent.ports.
We use a JSValueInWrappedObject to store the JS ports object so that we always return the same JS object.

* LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/message-event-ports-worker.js: Added.
* LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/message-event-ports.https-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/message-event-ports.https.html: Added.
* Source/WebCore/bindings/js/JSExtendableMessageEventCustom.cpp:
(WebCore::JSExtendableMessageEvent::ports const):
(WebCore::JSExtendableMessageEvent::visitAdditionalChildren):
* Source/WebCore/workers/service/ExtendableMessageEvent.h:
* Source/WebCore/workers/service/ExtendableMessageEvent.idl:

Originally-landed-as: bb2720bcf112. https://bugs.webkit.org/show_bug.cgi?id=273542
Canonical link: https://commits.webkit.org/278690@main
  • Loading branch information
youennf committed May 13, 2024
1 parent 55a78ab commit ac508ff
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
self.onmessage = e => {
e.source.postMessage(e.ports === e.ports ? "same ports array" : "different ports array");
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

PASS Verify MessageEvent.ports getter returns the same object

Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<head>
<title>Service Worker GlobalScope onerror event</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<canvas id=canvas></canvas>
<script>
var registration;

async function registerServiceWorker()
{
const registration = await navigator.serviceWorker.register("message-event-ports-worker.js", { scope : "." });
let activeWorker = registration.active;
if (activeWorker)
return registration;
activeWorker = registration.installing;
return new Promise(resolve => {
activeWorker.addEventListener('statechange', () => {
if (activeWorker.state === "activated")
resolve(registration);
});
});
}

promise_test(async (test) => {
registration = await registerServiceWorker();

registration.active.postMessage("test");
let result = await new Promise(resolve => navigator.serviceWorker.onmessage = e => resolve(e.data));
assert_equals(result, "same ports array", "empty array");

const channel = new MessageChannel();;
const port = channel.port1;
registration.active.postMessage({ port }, [port]);
result = await new Promise(resolve => navigator.serviceWorker.onmessage = e => resolve(e.data));
assert_equals(result, "same ports array", "not empty array");
}, "Verify MessageEvent.ports getter returns the same object");
</script>
</body>
</html>
9 changes: 9 additions & 0 deletions Source/WebCore/bindings/js/JSExtendableMessageEventCustom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,19 @@ JSC::EncodedJSValue constructJSExtendableMessageEvent(JSC::JSGlobalObject* lexic
return JSValue::encode(object.strongWrapper.get());
}

JSC::JSValue JSExtendableMessageEvent::ports(JSC::JSGlobalObject& lexicalGlobalObject) const
{
auto throwScope = DECLARE_THROW_SCOPE(lexicalGlobalObject.vm());
return cachedPropertyValue(throwScope, lexicalGlobalObject, *this, wrapped().cachedPorts(), [&](JSC::ThrowScope& throwScope) {
return toJS<IDLFrozenArray<IDLInterface<MessagePort>>>(lexicalGlobalObject, *globalObject(), throwScope, wrapped().ports());
});
}

template<typename Visitor>
void JSExtendableMessageEvent::visitAdditionalChildren(Visitor& visitor)
{
wrapped().data().visit(visitor);
wrapped().cachedPorts().visit(visitor);
}

DEFINE_VISIT_ADDITIONAL_CHILDREN(JSExtendableMessageEvent);
Expand Down
2 changes: 2 additions & 0 deletions Source/WebCore/workers/service/ExtendableMessageEvent.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class ExtendableMessageEvent final : public ExtendableEvent {
~ExtendableMessageEvent();

JSValueInWrappedObject& data() { return m_data; }
JSValueInWrappedObject& cachedPorts() { return m_cachedPorts; }

const String& origin() const { return m_origin; }
const String& lastEventId() const { return m_lastEventId; }
Expand All @@ -83,6 +84,7 @@ class ExtendableMessageEvent final : public ExtendableEvent {
String m_lastEventId;
std::optional<ExtendableMessageEventSource> m_source;
Vector<Ref<MessagePort>> m_ports;
JSValueInWrappedObject m_cachedPorts;
};

} // namespace WebCore
2 changes: 1 addition & 1 deletion Source/WebCore/workers/service/ExtendableMessageEvent.idl
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
readonly attribute USVString origin;
readonly attribute DOMString lastEventId;
[SameObject] readonly attribute (ServiceWorkerClient or ServiceWorker or MessagePort)? source;
readonly attribute FrozenArray<MessagePort> ports;
[CustomGetter] readonly attribute FrozenArray<MessagePort> ports;
};

dictionary ExtendableMessageEventInit : ExtendableEventInit {
Expand Down

0 comments on commit ac508ff

Please sign in to comment.