diff --git a/Tests/LibWeb/Text/expected/HTML/Window-postMessage.txt b/Tests/LibWeb/Text/expected/HTML/Window-postMessage.txt index d1b09cd76c..7db9d9d37a 100644 --- a/Tests/LibWeb/Text/expected/HTML/Window-postMessage.txt +++ b/Tests/LibWeb/Text/expected/HTML/Window-postMessage.txt @@ -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 \ No newline at end of file +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 diff --git a/Tests/LibWeb/Text/input/HTML/Window-postMessage.html b/Tests/LibWeb/Text/input/HTML/Window-postMessage.html index fa2ee130f7..ec8f9608d6 100644 --- a/Tests/LibWeb/Text/input/HTML/Window-postMessage.html +++ b/Tests/LibWeb/Text/input/HTML/Window-postMessage.html @@ -3,7 +3,7 @@ @@ -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 { diff --git a/Userland/Libraries/LibWeb/HTML/Window.cpp b/Userland/Libraries/LibWeb/HTML/Window.cpp index e2327d3f6d..66310e4800 100644 --- a/Userland/Libraries/LibWeb/HTML/Window.cpp +++ b/Userland/Libraries/LibWeb/HTML/Window.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -1062,11 +1063,10 @@ WebIDL::ExceptionOr 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 Window::window_post_message_steps(JS::Value message, W auto& source = verify_cast(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 {}); + 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 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> new_ports; + for (auto const& object : deserialize_record.transferred_values) { + if (is(*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);