mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-01 13:44:21 +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
|
@ -32,6 +32,9 @@ Message 1 data: undefined
|
|||
Message 1 origin: file://
|
||||
Message 1 lastEventId:
|
||||
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 === iframe.contentWindow: false
|
||||
Message 1 source === blobIframe.contentWindow: false
|
||||
|
@ -39,6 +42,9 @@ Message 2 data: null
|
|||
Message 2 origin: file://
|
||||
Message 2 lastEventId:
|
||||
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 === iframe.contentWindow: false
|
||||
Message 2 source === blobIframe.contentWindow: false
|
||||
|
@ -46,6 +52,9 @@ Message 3 data: true
|
|||
Message 3 origin: file://
|
||||
Message 3 lastEventId:
|
||||
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 === iframe.contentWindow: false
|
||||
Message 3 source === blobIframe.contentWindow: false
|
||||
|
@ -53,6 +62,9 @@ Message 4 data: false
|
|||
Message 4 origin: file://
|
||||
Message 4 lastEventId:
|
||||
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 === iframe.contentWindow: false
|
||||
Message 4 source === blobIframe.contentWindow: false
|
||||
|
@ -60,6 +72,9 @@ Message 5 data: 123
|
|||
Message 5 origin: file://
|
||||
Message 5 lastEventId:
|
||||
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 === iframe.contentWindow: false
|
||||
Message 5 source === blobIframe.contentWindow: false
|
||||
|
@ -67,6 +82,9 @@ Message 6 data: 123.456
|
|||
Message 6 origin: file://
|
||||
Message 6 lastEventId:
|
||||
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 === iframe.contentWindow: false
|
||||
Message 6 source === blobIframe.contentWindow: false
|
||||
|
@ -74,6 +92,9 @@ Message 7 data: 9007199254740991
|
|||
Message 7 origin: file://
|
||||
Message 7 lastEventId:
|
||||
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 === iframe.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 lastEventId:
|
||||
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 === iframe.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 lastEventId:
|
||||
Message 9 source: [object Window]
|
||||
Message 9 source === window: false
|
||||
Message 9 source === iframe.contentWindow: true
|
||||
Message 9 ports: [object MessagePort]
|
||||
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 10 data: All done :^)
|
||||
Message 10 data: I am from another ~planet~ iframe
|
||||
Message 10 origin: file://
|
||||
Message 10 lastEventId:
|
||||
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 === iframe.contentWindow: false
|
||||
Message 10 source === blobIframe.contentWindow: true
|
||||
Message 10 source === iframe.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>
|
||||
<script>
|
||||
window.addEventListener('message', (event) => {
|
||||
window.parent.postMessage(event.data, '*');
|
||||
window.parent.postMessage(event.data, '*', event.ports);
|
||||
});
|
||||
</script>
|
||||
<body>
|
||||
|
@ -30,6 +30,9 @@
|
|||
println(`Message ${messageCount} origin: ${messageEvent.origin}`);
|
||||
println(`Message ${messageCount} lastEventId: ${messageEvent.lastEventId}`);
|
||||
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 === iframe.contentWindow: ${messageEvent.source === iframe.contentWindow}`);
|
||||
println(`Message ${messageCount} source === blobIframe.contentWindow: ${messageEvent.source === blobIframe.contentWindow}`);
|
||||
|
@ -55,6 +58,8 @@
|
|||
window.postMessage("This is a string", "/");
|
||||
window.postMessage("I shouldn't appear, I'm not same origin!", "https://serenityos.org");
|
||||
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);
|
||||
|
||||
try {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <AK/DeprecatedString.h>
|
||||
#include <AK/GenericLexer.h>
|
||||
#include <AK/Utf8View.h>
|
||||
#include <LibIPC/File.h>
|
||||
#include <LibJS/Runtime/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/Accessor.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"].
|
||||
// FIXME: This is currently unused.
|
||||
auto& transfer = options.transfer;
|
||||
|
||||
// 7. Let serializeWithTransferResult be StructuredSerializeWithTransfer(message, transfer). Rethrow any exceptions.
|
||||
// FIXME: Use StructuredSerializeWithTransfer instead of StructuredSerialize
|
||||
auto serialize_with_transfer_result = TRY(structured_serialize(target_realm.vm(), message));
|
||||
auto serialize_with_transfer_result = TRY(structured_serialize_with_transfer(target_realm.vm(), message, transfer));
|
||||
|
||||
// 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]() {
|
||||
|
@ -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());
|
||||
|
||||
// 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 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,
|
||||
// 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]].
|
||||
// FIXME: Get this from deserializeRecord.[[Deserialized]] once it uses StructuredDeserializeWithTransfer instead of StructuredDeserialize.
|
||||
auto message_clone = deserialize_record_or_error.release_value();
|
||||
auto deserialize_record = 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]],
|
||||
// if any, maintaining their relative order.
|
||||
// 6. Let newPorts be a new frozen array consisting of all MessagePort objects in deserializeRecord.[[TransferredValues]],
|
||||
// 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,
|
||||
// the source attribute initialized to source, the data attribute initialized to messageClone, and the ports attribute
|
||||
// initialized to newPorts.
|
||||
// FIXME: Set the ports attribute to newPorts.
|
||||
MessageEventInit message_event_init {};
|
||||
message_event_init.origin = MUST(String::from_deprecated_string(origin));
|
||||
message_event_init.source = JS::make_handle(source);
|
||||
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);
|
||||
dispatch_event(message_event);
|
||||
|
|
Loading…
Reference in a new issue