ServiceWorkerClient.cpp [plain text]
#include "config.h"
#if ENABLE(SERVICE_WORKER)
#include "ServiceWorkerClient.h"
#include "MessagePort.h"
#include "SWContextManager.h"
#include "ScriptExecutionContext.h"
#include "SerializedScriptValue.h"
#include "ServiceWorkerGlobalScope.h"
#include "ServiceWorkerThread.h"
#include "ServiceWorkerWindowClient.h"
namespace WebCore {
Ref<ServiceWorkerClient> ServiceWorkerClient::getOrCreate(ServiceWorkerGlobalScope& context, ServiceWorkerClientData&& data)
{
if (auto* client = context.serviceWorkerClient(data.identifier))
return *client;
if (data.type == ServiceWorkerClientType::Window)
return ServiceWorkerWindowClient::create(context, WTFMove(data));
return adoptRef(*new ServiceWorkerClient { context, WTFMove(data) });
}
ServiceWorkerClient::ServiceWorkerClient(ServiceWorkerGlobalScope& context, ServiceWorkerClientData&& data)
: ContextDestructionObserver(&context)
, m_data(WTFMove(data))
{
context.addServiceWorkerClient(*this);
}
ServiceWorkerClient::~ServiceWorkerClient()
{
if (auto* context = scriptExecutionContext())
downcast<ServiceWorkerGlobalScope>(*context).removeServiceWorkerClient(*this);
}
const URL& ServiceWorkerClient::url() const
{
return m_data.url;
}
auto ServiceWorkerClient::type() const -> Type
{
return m_data.type;
}
auto ServiceWorkerClient::frameType() const -> FrameType
{
return m_data.frameType;
}
String ServiceWorkerClient::id() const
{
return identifier().toString();
}
ExceptionOr<void> ServiceWorkerClient::postMessage(ScriptExecutionContext& context, JSC::JSValue messageValue, Vector<JSC::Strong<JSC::JSObject>>&& transfer)
{
auto* execState = context.execState();
ASSERT(execState);
Vector<RefPtr<MessagePort>> ports;
auto messageData = SerializedScriptValue::create(*execState, messageValue, WTFMove(transfer), ports, SerializationContext::WorkerPostMessage);
if (messageData.hasException())
return messageData.releaseException();
auto portsOrException = MessagePort::disentanglePorts(WTFMove(ports));
if (portsOrException.hasException())
return portsOrException.releaseException();
MessageWithMessagePorts message = { messageData.releaseReturnValue(), portsOrException.releaseReturnValue() };
auto sourceIdentifier = downcast<ServiceWorkerGlobalScope>(context).thread().identifier();
callOnMainThread([message = WTFMove(message), destinationIdentifier = identifier(), sourceIdentifier, sourceOrigin = context.origin().isolatedCopy()] () mutable {
if (auto* connection = SWContextManager::singleton().connection())
connection->postMessageToServiceWorkerClient(destinationIdentifier, WTFMove(message), sourceIdentifier, sourceOrigin);
});
return { };
}
}
#endif // ENABLE(SERVICE_WORKER)