1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "third_party/blink/renderer/modules/service_worker/extendable_message_event.h"
6 
7 namespace blink {
8 
Create(const AtomicString & type,const ExtendableMessageEventInit * initializer)9 ExtendableMessageEvent* ExtendableMessageEvent::Create(
10     const AtomicString& type,
11     const ExtendableMessageEventInit* initializer) {
12   return MakeGarbageCollected<ExtendableMessageEvent>(type, initializer);
13 }
14 
Create(scoped_refptr<SerializedScriptValue> data,const String & origin,MessagePortArray * ports,ServiceWorkerClient * source,WaitUntilObserver * observer)15 ExtendableMessageEvent* ExtendableMessageEvent::Create(
16     scoped_refptr<SerializedScriptValue> data,
17     const String& origin,
18     MessagePortArray* ports,
19     ServiceWorkerClient* source,
20     WaitUntilObserver* observer) {
21   ExtendableMessageEvent* event = MakeGarbageCollected<ExtendableMessageEvent>(
22       std::move(data), origin, ports, observer);
23   event->source_as_client_ = source;
24   return event;
25 }
26 
Create(scoped_refptr<SerializedScriptValue> data,const String & origin,MessagePortArray * ports,ServiceWorker * source,WaitUntilObserver * observer)27 ExtendableMessageEvent* ExtendableMessageEvent::Create(
28     scoped_refptr<SerializedScriptValue> data,
29     const String& origin,
30     MessagePortArray* ports,
31     ServiceWorker* source,
32     WaitUntilObserver* observer) {
33   ExtendableMessageEvent* event = MakeGarbageCollected<ExtendableMessageEvent>(
34       std::move(data), origin, ports, observer);
35   event->source_as_service_worker_ = source;
36   return event;
37 }
38 
CreateError(const String & origin,MessagePortArray * ports,ServiceWorkerClient * source,WaitUntilObserver * observer)39 ExtendableMessageEvent* ExtendableMessageEvent::CreateError(
40     const String& origin,
41     MessagePortArray* ports,
42     ServiceWorkerClient* source,
43     WaitUntilObserver* observer) {
44   ExtendableMessageEvent* event =
45       MakeGarbageCollected<ExtendableMessageEvent>(origin, ports, observer);
46   event->source_as_client_ = source;
47   return event;
48 }
49 
CreateError(const String & origin,MessagePortArray * ports,ServiceWorker * source,WaitUntilObserver * observer)50 ExtendableMessageEvent* ExtendableMessageEvent::CreateError(
51     const String& origin,
52     MessagePortArray* ports,
53     ServiceWorker* source,
54     WaitUntilObserver* observer) {
55   ExtendableMessageEvent* event =
56       MakeGarbageCollected<ExtendableMessageEvent>(origin, ports, observer);
57   event->source_as_service_worker_ = source;
58   return event;
59 }
60 
data(ScriptState * script_state) const61 ScriptValue ExtendableMessageEvent::data(ScriptState* script_state) const {
62   v8::Local<v8::Value> value;
63   if (!data_.IsEmpty()) {
64     value = data_.GetAcrossWorld(script_state);
65   } else if (serialized_data_) {
66     SerializedScriptValue::DeserializeOptions options;
67     MessagePortArray message_ports = ports();
68     options.message_ports = &message_ports;
69     value = serialized_data_->Deserialize(script_state->GetIsolate(), options);
70   } else {
71     value = v8::Null(script_state->GetIsolate());
72   }
73   return ScriptValue(script_state->GetIsolate(), value);
74 }
75 
source(ClientOrServiceWorkerOrMessagePort & result) const76 void ExtendableMessageEvent::source(
77     ClientOrServiceWorkerOrMessagePort& result) const {
78   if (source_as_client_)
79     result = ClientOrServiceWorkerOrMessagePort::FromClient(source_as_client_);
80   else if (source_as_service_worker_)
81     result = ClientOrServiceWorkerOrMessagePort::FromServiceWorker(
82         source_as_service_worker_);
83   else if (source_as_message_port_)
84     result = ClientOrServiceWorkerOrMessagePort::FromMessagePort(
85         source_as_message_port_);
86   else
87     result = ClientOrServiceWorkerOrMessagePort();
88 }
89 
ports() const90 MessagePortArray ExtendableMessageEvent::ports() const {
91   // TODO(bashi): Currently we return a copied array because the binding
92   // layer could modify the content of the array while executing JS callbacks.
93   // Avoid copying once we can make sure that the binding layer won't
94   // modify the content.
95   if (ports_) {
96     return *ports_;
97   }
98   return MessagePortArray();
99 }
100 
InterfaceName() const101 const AtomicString& ExtendableMessageEvent::InterfaceName() const {
102   return event_interface_names::kExtendableMessageEvent;
103 }
104 
Trace(Visitor * visitor) const105 void ExtendableMessageEvent::Trace(Visitor* visitor) const {
106   visitor->Trace(data_);
107   visitor->Trace(source_as_client_);
108   visitor->Trace(source_as_service_worker_);
109   visitor->Trace(source_as_message_port_);
110   visitor->Trace(ports_);
111   ExtendableEvent::Trace(visitor);
112 }
113 
ExtendableMessageEvent(const AtomicString & type,const ExtendableMessageEventInit * initializer)114 ExtendableMessageEvent::ExtendableMessageEvent(
115     const AtomicString& type,
116     const ExtendableMessageEventInit* initializer)
117     : ExtendableMessageEvent(type, initializer, nullptr) {}
118 
ExtendableMessageEvent(const AtomicString & type,const ExtendableMessageEventInit * initializer,WaitUntilObserver * observer)119 ExtendableMessageEvent::ExtendableMessageEvent(
120     const AtomicString& type,
121     const ExtendableMessageEventInit* initializer,
122     WaitUntilObserver* observer)
123     : ExtendableEvent(type, initializer, observer) {
124   if (initializer->hasData()) {
125     const ScriptValue& data = initializer->data();
126     data_.Set(data.GetIsolate(), data.V8Value());
127   }
128   if (initializer->hasOrigin())
129     origin_ = initializer->origin();
130   if (initializer->hasLastEventId())
131     last_event_id_ = initializer->lastEventId();
132   if (initializer->hasSource()) {
133     if (initializer->source().IsClient())
134       source_as_client_ = initializer->source().GetAsClient();
135     else if (initializer->source().IsServiceWorker())
136       source_as_service_worker_ = initializer->source().GetAsServiceWorker();
137     else if (initializer->source().IsMessagePort())
138       source_as_message_port_ = initializer->source().GetAsMessagePort();
139   }
140   if (initializer->hasPorts())
141     ports_ = MakeGarbageCollected<MessagePortArray>(initializer->ports());
142 }
143 
ExtendableMessageEvent(scoped_refptr<SerializedScriptValue> data,const String & origin,MessagePortArray * ports,WaitUntilObserver * observer)144 ExtendableMessageEvent::ExtendableMessageEvent(
145     scoped_refptr<SerializedScriptValue> data,
146     const String& origin,
147     MessagePortArray* ports,
148     WaitUntilObserver* observer)
149     : ExtendableEvent(event_type_names::kMessage,
150                       ExtendableMessageEventInit::Create(),
151                       observer),
152       serialized_data_(std::move(data)),
153       origin_(origin),
154       last_event_id_(String()),
155       ports_(ports) {
156   if (serialized_data_)
157     serialized_data_->RegisterMemoryAllocatedWithCurrentScriptContext();
158 }
159 
ExtendableMessageEvent(const String & origin,MessagePortArray * ports,WaitUntilObserver * observer)160 ExtendableMessageEvent::ExtendableMessageEvent(const String& origin,
161                                                MessagePortArray* ports,
162                                                WaitUntilObserver* observer)
163     : ExtendableEvent(event_type_names::kMessageerror,
164                       ExtendableMessageEventInit::Create(),
165                       observer),
166       origin_(origin),
167       last_event_id_(String()),
168       ports_(ports) {}
169 
170 }  // namespace blink
171