mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 15:07:45 +00:00
LibWeb: Use StructuredSerializeWithTransfer in window.postMessage()
And update tests to transfer message a message port between iframes.
This commit is contained in:
parent
84ac6a454f
commit
ec11743fae
3 changed files with 68 additions and 18 deletions
|
@ -32,6 +32,9 @@ Message 1 data: undefined
|
||||||
Message 1 origin: file://
|
Message 1 origin: file://
|
||||||
Message 1 lastEventId:
|
Message 1 lastEventId:
|
||||||
Message 1 source: [object Window]
|
Message 1 source: [object Window]
|
||||||
|
Message 1 ports:
|
||||||
|
Message 1 ports === ports: true
|
||||||
|
Message 1 Object.isFrozen(ports): true
|
||||||
Message 1 source === window: true
|
Message 1 source === window: true
|
||||||
Message 1 source === iframe.contentWindow: false
|
Message 1 source === iframe.contentWindow: false
|
||||||
Message 1 source === blobIframe.contentWindow: false
|
Message 1 source === blobIframe.contentWindow: false
|
||||||
|
@ -39,6 +42,9 @@ Message 2 data: null
|
||||||
Message 2 origin: file://
|
Message 2 origin: file://
|
||||||
Message 2 lastEventId:
|
Message 2 lastEventId:
|
||||||
Message 2 source: [object Window]
|
Message 2 source: [object Window]
|
||||||
|
Message 2 ports:
|
||||||
|
Message 2 ports === ports: true
|
||||||
|
Message 2 Object.isFrozen(ports): true
|
||||||
Message 2 source === window: true
|
Message 2 source === window: true
|
||||||
Message 2 source === iframe.contentWindow: false
|
Message 2 source === iframe.contentWindow: false
|
||||||
Message 2 source === blobIframe.contentWindow: false
|
Message 2 source === blobIframe.contentWindow: false
|
||||||
|
@ -46,6 +52,9 @@ Message 3 data: true
|
||||||
Message 3 origin: file://
|
Message 3 origin: file://
|
||||||
Message 3 lastEventId:
|
Message 3 lastEventId:
|
||||||
Message 3 source: [object Window]
|
Message 3 source: [object Window]
|
||||||
|
Message 3 ports:
|
||||||
|
Message 3 ports === ports: true
|
||||||
|
Message 3 Object.isFrozen(ports): true
|
||||||
Message 3 source === window: true
|
Message 3 source === window: true
|
||||||
Message 3 source === iframe.contentWindow: false
|
Message 3 source === iframe.contentWindow: false
|
||||||
Message 3 source === blobIframe.contentWindow: false
|
Message 3 source === blobIframe.contentWindow: false
|
||||||
|
@ -53,6 +62,9 @@ Message 4 data: false
|
||||||
Message 4 origin: file://
|
Message 4 origin: file://
|
||||||
Message 4 lastEventId:
|
Message 4 lastEventId:
|
||||||
Message 4 source: [object Window]
|
Message 4 source: [object Window]
|
||||||
|
Message 4 ports:
|
||||||
|
Message 4 ports === ports: true
|
||||||
|
Message 4 Object.isFrozen(ports): true
|
||||||
Message 4 source === window: true
|
Message 4 source === window: true
|
||||||
Message 4 source === iframe.contentWindow: false
|
Message 4 source === iframe.contentWindow: false
|
||||||
Message 4 source === blobIframe.contentWindow: false
|
Message 4 source === blobIframe.contentWindow: false
|
||||||
|
@ -60,6 +72,9 @@ Message 5 data: 123
|
||||||
Message 5 origin: file://
|
Message 5 origin: file://
|
||||||
Message 5 lastEventId:
|
Message 5 lastEventId:
|
||||||
Message 5 source: [object Window]
|
Message 5 source: [object Window]
|
||||||
|
Message 5 ports:
|
||||||
|
Message 5 ports === ports: true
|
||||||
|
Message 5 Object.isFrozen(ports): true
|
||||||
Message 5 source === window: true
|
Message 5 source === window: true
|
||||||
Message 5 source === iframe.contentWindow: false
|
Message 5 source === iframe.contentWindow: false
|
||||||
Message 5 source === blobIframe.contentWindow: false
|
Message 5 source === blobIframe.contentWindow: false
|
||||||
|
@ -67,6 +82,9 @@ Message 6 data: 123.456
|
||||||
Message 6 origin: file://
|
Message 6 origin: file://
|
||||||
Message 6 lastEventId:
|
Message 6 lastEventId:
|
||||||
Message 6 source: [object Window]
|
Message 6 source: [object Window]
|
||||||
|
Message 6 ports:
|
||||||
|
Message 6 ports === ports: true
|
||||||
|
Message 6 Object.isFrozen(ports): true
|
||||||
Message 6 source === window: true
|
Message 6 source === window: true
|
||||||
Message 6 source === iframe.contentWindow: false
|
Message 6 source === iframe.contentWindow: false
|
||||||
Message 6 source === blobIframe.contentWindow: false
|
Message 6 source === blobIframe.contentWindow: false
|
||||||
|
@ -74,6 +92,9 @@ Message 7 data: 9007199254740991
|
||||||
Message 7 origin: file://
|
Message 7 origin: file://
|
||||||
Message 7 lastEventId:
|
Message 7 lastEventId:
|
||||||
Message 7 source: [object Window]
|
Message 7 source: [object Window]
|
||||||
|
Message 7 ports:
|
||||||
|
Message 7 ports === ports: true
|
||||||
|
Message 7 Object.isFrozen(ports): true
|
||||||
Message 7 source === window: true
|
Message 7 source === window: true
|
||||||
Message 7 source === iframe.contentWindow: false
|
Message 7 source === iframe.contentWindow: false
|
||||||
Message 7 source === blobIframe.contentWindow: false
|
Message 7 source === blobIframe.contentWindow: false
|
||||||
|
@ -81,20 +102,39 @@ Message 8 data: This is a string
|
||||||
Message 8 origin: file://
|
Message 8 origin: file://
|
||||||
Message 8 lastEventId:
|
Message 8 lastEventId:
|
||||||
Message 8 source: [object Window]
|
Message 8 source: [object Window]
|
||||||
|
Message 8 ports:
|
||||||
|
Message 8 ports === ports: true
|
||||||
|
Message 8 Object.isFrozen(ports): true
|
||||||
Message 8 source === window: true
|
Message 8 source === window: true
|
||||||
Message 8 source === iframe.contentWindow: false
|
Message 8 source === iframe.contentWindow: false
|
||||||
Message 8 source === blobIframe.contentWindow: false
|
Message 8 source === blobIframe.contentWindow: false
|
||||||
Message 9 data: I am from another ~planet~ iframe
|
Message 9 data: [object Object]
|
||||||
Message 9 origin: file://
|
Message 9 origin: file://
|
||||||
Message 9 lastEventId:
|
Message 9 lastEventId:
|
||||||
Message 9 source: [object Window]
|
Message 9 source: [object Window]
|
||||||
Message 9 source === window: false
|
Message 9 ports: [object MessagePort]
|
||||||
Message 9 source === iframe.contentWindow: true
|
Message 9 ports === ports: true
|
||||||
|
Message 9 Object.isFrozen(ports): true
|
||||||
|
Message 9 source === window: true
|
||||||
|
Message 9 source === iframe.contentWindow: false
|
||||||
Message 9 source === blobIframe.contentWindow: false
|
Message 9 source === blobIframe.contentWindow: false
|
||||||
Message 10 data: All done :^)
|
Message 10 data: I am from another ~planet~ iframe
|
||||||
Message 10 origin: file://
|
Message 10 origin: file://
|
||||||
Message 10 lastEventId:
|
Message 10 lastEventId:
|
||||||
Message 10 source: [object Window]
|
Message 10 source: [object Window]
|
||||||
|
Message 10 ports:
|
||||||
|
Message 10 ports === ports: true
|
||||||
|
Message 10 Object.isFrozen(ports): true
|
||||||
Message 10 source === window: false
|
Message 10 source === window: false
|
||||||
Message 10 source === iframe.contentWindow: false
|
Message 10 source === iframe.contentWindow: true
|
||||||
Message 10 source === blobIframe.contentWindow: true
|
Message 10 source === blobIframe.contentWindow: false
|
||||||
|
Message 11 data: All done :^)
|
||||||
|
Message 11 origin: file://
|
||||||
|
Message 11 lastEventId:
|
||||||
|
Message 11 source: [object Window]
|
||||||
|
Message 11 ports:
|
||||||
|
Message 11 ports === ports: true
|
||||||
|
Message 11 Object.isFrozen(ports): true
|
||||||
|
Message 11 source === window: false
|
||||||
|
Message 11 source === iframe.contentWindow: false
|
||||||
|
Message 11 source === blobIframe.contentWindow: true
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<body>
|
<body>
|
||||||
<script>
|
<script>
|
||||||
window.addEventListener('message', (event) => {
|
window.addEventListener('message', (event) => {
|
||||||
window.parent.postMessage(event.data, '*');
|
window.parent.postMessage(event.data, '*', event.ports);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<body>
|
<body>
|
||||||
|
@ -30,6 +30,9 @@
|
||||||
println(`Message ${messageCount} origin: ${messageEvent.origin}`);
|
println(`Message ${messageCount} origin: ${messageEvent.origin}`);
|
||||||
println(`Message ${messageCount} lastEventId: ${messageEvent.lastEventId}`);
|
println(`Message ${messageCount} lastEventId: ${messageEvent.lastEventId}`);
|
||||||
println(`Message ${messageCount} source: ${messageEvent.source}`);
|
println(`Message ${messageCount} source: ${messageEvent.source}`);
|
||||||
|
println(`Message ${messageCount} ports: ${messageEvent.ports}`);
|
||||||
|
println(`Message ${messageCount} ports === ports: ${messageEvent.ports === messageEvent.ports}`);
|
||||||
|
println(`Message ${messageCount} Object.isFrozen(ports): ${Object.isFrozen(messageEvent.ports)}`);
|
||||||
println(`Message ${messageCount} source === window: ${messageEvent.source === window}`);
|
println(`Message ${messageCount} source === window: ${messageEvent.source === window}`);
|
||||||
println(`Message ${messageCount} source === iframe.contentWindow: ${messageEvent.source === iframe.contentWindow}`);
|
println(`Message ${messageCount} source === iframe.contentWindow: ${messageEvent.source === iframe.contentWindow}`);
|
||||||
println(`Message ${messageCount} source === blobIframe.contentWindow: ${messageEvent.source === blobIframe.contentWindow}`);
|
println(`Message ${messageCount} source === blobIframe.contentWindow: ${messageEvent.source === blobIframe.contentWindow}`);
|
||||||
|
@ -55,6 +58,8 @@
|
||||||
window.postMessage("This is a string", "/");
|
window.postMessage("This is a string", "/");
|
||||||
window.postMessage("I shouldn't appear, I'm not same origin!", "https://serenityos.org");
|
window.postMessage("I shouldn't appear, I'm not same origin!", "https://serenityos.org");
|
||||||
iframe.contentWindow.postMessage("I am from another ~planet~ iframe", "*");
|
iframe.contentWindow.postMessage("I am from another ~planet~ iframe", "*");
|
||||||
|
let channel = new MessageChannel();
|
||||||
|
window.postMessage({foo: [channel.port1]}, "*", [channel.port1]);
|
||||||
blobIframe.contentWindow.postMessage("All done :^)", iframeSrcdocBlobUrl);
|
blobIframe.contentWindow.postMessage("All done :^)", iframeSrcdocBlobUrl);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <AK/DeprecatedString.h>
|
#include <AK/DeprecatedString.h>
|
||||||
#include <AK/GenericLexer.h>
|
#include <AK/GenericLexer.h>
|
||||||
#include <AK/Utf8View.h>
|
#include <AK/Utf8View.h>
|
||||||
|
#include <LibIPC/File.h>
|
||||||
#include <LibJS/Runtime/AbstractOperations.h>
|
#include <LibJS/Runtime/AbstractOperations.h>
|
||||||
#include <LibJS/Runtime/Accessor.h>
|
#include <LibJS/Runtime/Accessor.h>
|
||||||
#include <LibJS/Runtime/Completion.h>
|
#include <LibJS/Runtime/Completion.h>
|
||||||
|
@ -1062,11 +1063,10 @@ WebIDL::ExceptionOr<void> Window::window_post_message_steps(JS::Value message, W
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. Let transfer be options["transfer"].
|
// 6. Let transfer be options["transfer"].
|
||||||
// FIXME: This is currently unused.
|
auto& transfer = options.transfer;
|
||||||
|
|
||||||
// 7. Let serializeWithTransferResult be StructuredSerializeWithTransfer(message, transfer). Rethrow any exceptions.
|
// 7. Let serializeWithTransferResult be StructuredSerializeWithTransfer(message, transfer). Rethrow any exceptions.
|
||||||
// FIXME: Use StructuredSerializeWithTransfer instead of StructuredSerialize
|
auto serialize_with_transfer_result = TRY(structured_serialize_with_transfer(target_realm.vm(), message, transfer));
|
||||||
auto serialize_with_transfer_result = TRY(structured_serialize(target_realm.vm(), message));
|
|
||||||
|
|
||||||
// 8. Queue a global task on the posted message task source given targetWindow to run the following steps:
|
// 8. Queue a global task on the posted message task source given targetWindow to run the following steps:
|
||||||
queue_global_task(Task::Source::PostedMessage, *this, [this, serialize_with_transfer_result = move(serialize_with_transfer_result), target_origin = move(target_origin), &incumbent_settings, &target_realm]() {
|
queue_global_task(Task::Source::PostedMessage, *this, [this, serialize_with_transfer_result = move(serialize_with_transfer_result), target_origin = move(target_origin), &incumbent_settings, &target_realm]() {
|
||||||
|
@ -1086,11 +1086,9 @@ WebIDL::ExceptionOr<void> Window::window_post_message_steps(JS::Value message, W
|
||||||
auto& source = verify_cast<WindowProxy>(incumbent_settings.realm().global_environment().global_this_value());
|
auto& source = verify_cast<WindowProxy>(incumbent_settings.realm().global_environment().global_this_value());
|
||||||
|
|
||||||
// 4. Let deserializeRecord be StructuredDeserializeWithTransfer(serializeWithTransferResult, targetRealm).
|
// 4. Let deserializeRecord be StructuredDeserializeWithTransfer(serializeWithTransferResult, targetRealm).
|
||||||
// FIXME: Use StructuredDeserializeWithTransfer instead of StructuredDeserialize
|
|
||||||
// FIXME: Don't use a temporary execution context here.
|
|
||||||
auto& settings_object = Bindings::host_defined_environment_settings_object(target_realm);
|
auto& settings_object = Bindings::host_defined_environment_settings_object(target_realm);
|
||||||
auto temporary_execution_context = TemporaryExecutionContext { settings_object };
|
auto temporary_execution_context = TemporaryExecutionContext { settings_object };
|
||||||
auto deserialize_record_or_error = structured_deserialize(vm(), serialize_with_transfer_result, target_realm, Optional<HTML::DeserializationMemory> {});
|
auto deserialize_record_or_error = structured_deserialize_with_transfer(vm(), serialize_with_transfer_result);
|
||||||
|
|
||||||
// If this throws an exception, catch it, fire an event named messageerror at targetWindow, using MessageEvent,
|
// If this throws an exception, catch it, fire an event named messageerror at targetWindow, using MessageEvent,
|
||||||
// with the origin attribute initialized to origin and the source attribute initialized to source, and then return.
|
// with the origin attribute initialized to origin and the source attribute initialized to source, and then return.
|
||||||
|
@ -1105,20 +1103,27 @@ WebIDL::ExceptionOr<void> Window::window_post_message_steps(JS::Value message, W
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. Let messageClone be deserializeRecord.[[Deserialized]].
|
// 5. Let messageClone be deserializeRecord.[[Deserialized]].
|
||||||
// FIXME: Get this from deserializeRecord.[[Deserialized]] once it uses StructuredDeserializeWithTransfer instead of StructuredDeserialize.
|
auto deserialize_record = deserialize_record_or_error.release_value();
|
||||||
auto message_clone = deserialize_record_or_error.release_value();
|
auto message_clone = deserialize_record.deserialized;
|
||||||
|
|
||||||
// FIXME: 6. Let newPorts be a new frozen array consisting of all MessagePort objects in deserializeRecord.[[TransferredValues]],
|
// 6. Let newPorts be a new frozen array consisting of all MessagePort objects in deserializeRecord.[[TransferredValues]],
|
||||||
// if any, maintaining their relative order.
|
// if any, maintaining their relative order.
|
||||||
|
// FIXME: Use a FrozenArray
|
||||||
|
Vector<JS::Handle<JS::Object>> new_ports;
|
||||||
|
for (auto const& object : deserialize_record.transferred_values) {
|
||||||
|
if (is<HTML::MessagePort>(*object)) {
|
||||||
|
new_ports.append(object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 7. Fire an event named message at targetWindow, using MessageEvent, with the origin attribute initialized to origin,
|
// 7. Fire an event named message at targetWindow, using MessageEvent, with the origin attribute initialized to origin,
|
||||||
// the source attribute initialized to source, the data attribute initialized to messageClone, and the ports attribute
|
// the source attribute initialized to source, the data attribute initialized to messageClone, and the ports attribute
|
||||||
// initialized to newPorts.
|
// initialized to newPorts.
|
||||||
// FIXME: Set the ports attribute to newPorts.
|
|
||||||
MessageEventInit message_event_init {};
|
MessageEventInit message_event_init {};
|
||||||
message_event_init.origin = MUST(String::from_deprecated_string(origin));
|
message_event_init.origin = MUST(String::from_deprecated_string(origin));
|
||||||
message_event_init.source = JS::make_handle(source);
|
message_event_init.source = JS::make_handle(source);
|
||||||
message_event_init.data = message_clone;
|
message_event_init.data = message_clone;
|
||||||
|
message_event_init.ports = move(new_ports);
|
||||||
|
|
||||||
auto message_event = MessageEvent::create(target_realm, EventNames::message, message_event_init);
|
auto message_event = MessageEvent::create(target_realm, EventNames::message, message_event_init);
|
||||||
dispatch_event(message_event);
|
dispatch_event(message_event);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue