blob: 50281f8747e753facb687e82667c9c4021f7054f [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/html/portal/portal_post_message_helper.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/transferables.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_post_message_options.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/core/events/message_event.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/user_activation.h"
#include "third_party/blink/renderer/core/html/portal/html_portal_element.h"
#include "third_party/blink/renderer/core/inspector/main_thread_debugger.h"
#include "third_party/blink/renderer/core/inspector/thread_debugger.h"
#include "third_party/blink/renderer/core/messaging/blink_transferable_message.h"
#include "third_party/blink/renderer/core/messaging/message_port.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
namespace blink {
// static
BlinkTransferableMessage PortalPostMessageHelper::CreateMessage(
ScriptState* script_state,
const ScriptValue& message,
const PostMessageOptions* options,
ExceptionState& exception_state) {
BlinkTransferableMessage transferable_message;
Transferables transferables;
scoped_refptr<SerializedScriptValue> serialized_message =
PostMessageHelper::SerializeMessageByMove(script_state->GetIsolate(),
message, options, transferables,
exception_state);
if (exception_state.HadException())
return {};
DCHECK(serialized_message);
transferable_message.message = serialized_message;
// Disentangle the port in preparation for sending it to the remote context.
auto* execution_context = ExecutionContext::From(script_state);
transferable_message.ports = MessagePort::DisentanglePorts(
execution_context, transferables.message_ports, exception_state);
if (exception_state.HadException())
return {};
transferable_message.sender_origin =
execution_context->GetSecurityOrigin()->IsolatedCopy();
if (ThreadDebugger* debugger =
ThreadDebugger::From(script_state->GetIsolate())) {
transferable_message.sender_stack_trace_id =
debugger->StoreCurrentStackTrace("postMessage");
}
transferable_message.user_activation =
PostMessageHelper::CreateUserActivationSnapshot(execution_context,
options);
return transferable_message;
}
// static
void PortalPostMessageHelper::CreateAndDispatchMessageEvent(
EventTarget* event_target,
BlinkTransferableMessage message,
scoped_refptr<const SecurityOrigin> source_origin) {
DCHECK(event_target->ToPortalHost() ||
IsA<HTMLPortalElement>(event_target->ToNode()));
DCHECK(source_origin->IsSameOriginWith(
event_target->GetExecutionContext()->GetSecurityOrigin()));
UserActivation* user_activation = nullptr;
if (message.user_activation) {
user_activation = MakeGarbageCollected<UserActivation>(
message.user_activation->has_been_active,
message.user_activation->was_active);
}
MessageEvent* event = MessageEvent::Create(
message.ports, message.message, source_origin->ToString(), String(),
event_target, user_activation);
event->EntangleMessagePorts(event_target->GetExecutionContext());
ThreadDebugger* debugger = MainThreadDebugger::Instance();
if (debugger)
debugger->ExternalAsyncTaskStarted(message.sender_stack_trace_id);
event_target->DispatchEvent(*event);
if (debugger)
debugger->ExternalAsyncTaskFinished(message.sender_stack_trace_id);
}
} // namespace blink