OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2007 Henry Mason (hmason@mac.com) | 2 * Copyright (C) 2007 Henry Mason (hmason@mac.com) |
3 * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. | 3 * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 22 matching lines...) Expand all Loading... |
33 #include "bindings/core/v8/V8ArrayBuffer.h" | 33 #include "bindings/core/v8/V8ArrayBuffer.h" |
34 #include "platform/bindings/V8PrivateProperty.h" | 34 #include "platform/bindings/V8PrivateProperty.h" |
35 | 35 |
36 namespace blink { | 36 namespace blink { |
37 | 37 |
38 static inline bool IsValidSource(EventTarget* source) { | 38 static inline bool IsValidSource(EventTarget* source) { |
39 return !source || source->ToLocalDOMWindow() || source->ToMessagePort() || | 39 return !source || source->ToLocalDOMWindow() || source->ToMessagePort() || |
40 source->ToServiceWorker(); | 40 source->ToServiceWorker(); |
41 } | 41 } |
42 | 42 |
43 MessageEvent::MessageEvent() : data_type_(kDataTypeScriptValue) {} | 43 MessageEvent::MessageEvent() |
| 44 : data_type_(kDataTypeV8Reference), data_as_v8_value_reference_(this) {} |
44 | 45 |
45 MessageEvent::MessageEvent(const AtomicString& type, | 46 MessageEvent::MessageEvent(ScriptState* script_state, |
| 47 const AtomicString& type, |
46 const MessageEventInit& initializer) | 48 const MessageEventInit& initializer) |
47 : Event(type, initializer), | 49 : Event(type, initializer), |
48 data_type_(kDataTypeScriptValue), | 50 data_type_(kDataTypeV8Reference), |
| 51 data_as_v8_value_reference_(this), |
49 source_(nullptr) { | 52 source_(nullptr) { |
50 if (initializer.hasData()) | 53 if (initializer.hasData()) { |
51 data_as_script_value_ = initializer.data(); | 54 world_ = RefPtr<DOMWrapperWorld>(script_state->World()); |
| 55 data_as_v8_value_reference_.Set(initializer.data().GetIsolate(), |
| 56 initializer.data().V8Value()); |
| 57 } |
52 if (initializer.hasOrigin()) | 58 if (initializer.hasOrigin()) |
53 origin_ = initializer.origin(); | 59 origin_ = initializer.origin(); |
54 if (initializer.hasLastEventId()) | 60 if (initializer.hasLastEventId()) |
55 last_event_id_ = initializer.lastEventId(); | 61 last_event_id_ = initializer.lastEventId(); |
56 if (initializer.hasSource() && IsValidSource(initializer.source())) | 62 if (initializer.hasSource() && IsValidSource(initializer.source())) |
57 source_ = initializer.source(); | 63 source_ = initializer.source(); |
58 if (initializer.hasPorts()) | 64 if (initializer.hasPorts()) |
59 ports_ = new MessagePortArray(initializer.ports()); | 65 ports_ = new MessagePortArray(initializer.ports()); |
60 DCHECK(IsValidSource(source_.Get())); | 66 DCHECK(IsValidSource(source_.Get())); |
61 } | 67 } |
62 | 68 |
63 MessageEvent::MessageEvent(const String& origin, | 69 MessageEvent::MessageEvent(const String& origin, |
64 const String& last_event_id, | 70 const String& last_event_id, |
65 EventTarget* source, | 71 EventTarget* source, |
66 MessagePortArray* ports, | 72 MessagePortArray* ports, |
67 const String& suborigin) | 73 const String& suborigin) |
68 : Event(EventTypeNames::message, false, false), | 74 : Event(EventTypeNames::message, false, false), |
69 data_type_(kDataTypeScriptValue), | 75 data_type_(kDataTypeV8Reference), |
| 76 data_as_v8_value_reference_(this), |
70 origin_(origin), | 77 origin_(origin), |
71 last_event_id_(last_event_id), | 78 last_event_id_(last_event_id), |
72 source_(source), | 79 source_(source), |
73 ports_(ports) { | 80 ports_(ports) { |
74 DCHECK(IsValidSource(source_.Get())); | 81 DCHECK(IsValidSource(source_.Get())); |
75 } | 82 } |
76 | 83 |
77 MessageEvent::MessageEvent(PassRefPtr<SerializedScriptValue> data, | 84 MessageEvent::MessageEvent(PassRefPtr<SerializedScriptValue> data, |
78 const String& origin, | 85 const String& origin, |
79 const String& last_event_id, | 86 const String& last_event_id, |
80 EventTarget* source, | 87 EventTarget* source, |
81 MessagePortArray* ports, | 88 MessagePortArray* ports, |
82 const String& suborigin) | 89 const String& suborigin) |
83 : Event(EventTypeNames::message, false, false), | 90 : Event(EventTypeNames::message, false, false), |
84 data_type_(kDataTypeSerializedScriptValue), | 91 data_type_(kDataTypeSerializedScriptValue), |
| 92 data_as_v8_value_reference_(this), |
85 data_as_serialized_script_value_(std::move(data)), | 93 data_as_serialized_script_value_(std::move(data)), |
86 origin_(origin), | 94 origin_(origin), |
87 last_event_id_(last_event_id), | 95 last_event_id_(last_event_id), |
88 source_(source), | 96 source_(source), |
89 ports_(ports) { | 97 ports_(ports) { |
90 if (data_as_serialized_script_value_) | 98 if (data_as_serialized_script_value_) |
91 data_as_serialized_script_value_ | 99 data_as_serialized_script_value_ |
92 ->RegisterMemoryAllocatedWithCurrentScriptContext(); | 100 ->RegisterMemoryAllocatedWithCurrentScriptContext(); |
93 DCHECK(IsValidSource(source_.Get())); | 101 DCHECK(IsValidSource(source_.Get())); |
94 } | 102 } |
95 | 103 |
96 MessageEvent::MessageEvent(PassRefPtr<SerializedScriptValue> data, | 104 MessageEvent::MessageEvent(PassRefPtr<SerializedScriptValue> data, |
97 const String& origin, | 105 const String& origin, |
98 const String& last_event_id, | 106 const String& last_event_id, |
99 EventTarget* source, | 107 EventTarget* source, |
100 MessagePortChannelArray channels, | 108 MessagePortChannelArray channels, |
101 const String& suborigin) | 109 const String& suborigin) |
102 : Event(EventTypeNames::message, false, false), | 110 : Event(EventTypeNames::message, false, false), |
103 data_type_(kDataTypeSerializedScriptValue), | 111 data_type_(kDataTypeSerializedScriptValue), |
| 112 data_as_v8_value_reference_(this), |
104 data_as_serialized_script_value_(std::move(data)), | 113 data_as_serialized_script_value_(std::move(data)), |
105 origin_(origin), | 114 origin_(origin), |
106 last_event_id_(last_event_id), | 115 last_event_id_(last_event_id), |
107 source_(source), | 116 source_(source), |
108 channels_(std::move(channels)), | 117 channels_(std::move(channels)), |
109 suborigin_(suborigin) { | 118 suborigin_(suborigin) { |
110 if (data_as_serialized_script_value_) | 119 if (data_as_serialized_script_value_) |
111 data_as_serialized_script_value_ | 120 data_as_serialized_script_value_ |
112 ->RegisterMemoryAllocatedWithCurrentScriptContext(); | 121 ->RegisterMemoryAllocatedWithCurrentScriptContext(); |
113 DCHECK(IsValidSource(source_.Get())); | 122 DCHECK(IsValidSource(source_.Get())); |
114 } | 123 } |
115 | 124 |
116 MessageEvent::MessageEvent(const String& data, | 125 MessageEvent::MessageEvent(const String& data, |
117 const String& origin, | 126 const String& origin, |
118 const String& suborigin) | 127 const String& suborigin) |
119 : Event(EventTypeNames::message, false, false), | 128 : Event(EventTypeNames::message, false, false), |
120 data_type_(kDataTypeString), | 129 data_type_(kDataTypeString), |
| 130 data_as_v8_value_reference_(this), |
121 data_as_string_(data), | 131 data_as_string_(data), |
122 origin_(origin) {} | 132 origin_(origin) {} |
123 | 133 |
124 MessageEvent::MessageEvent(Blob* data, | 134 MessageEvent::MessageEvent(Blob* data, |
125 const String& origin, | 135 const String& origin, |
126 const String& suborigin) | 136 const String& suborigin) |
127 : Event(EventTypeNames::message, false, false), | 137 : Event(EventTypeNames::message, false, false), |
128 data_type_(kDataTypeBlob), | 138 data_type_(kDataTypeBlob), |
| 139 data_as_v8_value_reference_(this), |
129 data_as_blob_(data), | 140 data_as_blob_(data), |
130 origin_(origin) {} | 141 origin_(origin) {} |
131 | 142 |
132 MessageEvent::MessageEvent(DOMArrayBuffer* data, | 143 MessageEvent::MessageEvent(DOMArrayBuffer* data, |
133 const String& origin, | 144 const String& origin, |
134 const String& suborigin) | 145 const String& suborigin) |
135 : Event(EventTypeNames::message, false, false), | 146 : Event(EventTypeNames::message, false, false), |
136 data_type_(kDataTypeArrayBuffer), | 147 data_type_(kDataTypeArrayBuffer), |
| 148 data_as_v8_value_reference_(this), |
137 data_as_array_buffer_(data), | 149 data_as_array_buffer_(data), |
138 origin_(origin) {} | 150 origin_(origin) {} |
139 | 151 |
140 MessageEvent::~MessageEvent() {} | 152 MessageEvent::~MessageEvent() {} |
141 | 153 |
142 MessageEvent* MessageEvent::Create(const AtomicString& type, | 154 MessageEvent* MessageEvent::Create(ScriptState* script_state, |
| 155 const AtomicString& type, |
143 const MessageEventInit& initializer, | 156 const MessageEventInit& initializer, |
144 ExceptionState& exception_state) { | 157 ExceptionState& exception_state) { |
145 if (initializer.source() && !IsValidSource(initializer.source())) { | 158 if (initializer.source() && !IsValidSource(initializer.source())) { |
146 exception_state.ThrowTypeError( | 159 exception_state.ThrowTypeError( |
147 "The optional 'source' property is neither a Window nor MessagePort."); | 160 "The optional 'source' property is neither a Window nor MessagePort."); |
148 return nullptr; | 161 return nullptr; |
149 } | 162 } |
150 return new MessageEvent(type, initializer); | 163 return new MessageEvent(script_state, type, initializer); |
151 } | 164 } |
152 | 165 |
153 void MessageEvent::initMessageEvent(const AtomicString& type, | 166 void MessageEvent::initMessageEvent(ScriptState* script_state, |
| 167 const AtomicString& type, |
154 bool can_bubble, | 168 bool can_bubble, |
155 bool cancelable, | 169 bool cancelable, |
156 ScriptValue data, | 170 ScriptValue data, |
157 const String& origin, | 171 const String& origin, |
158 const String& last_event_id, | 172 const String& last_event_id, |
159 EventTarget* source, | 173 EventTarget* source, |
160 MessagePortArray* ports) { | 174 MessagePortArray* ports) { |
161 if (IsBeingDispatched()) | 175 if (IsBeingDispatched()) |
162 return; | 176 return; |
163 | 177 |
164 initEvent(type, can_bubble, cancelable); | 178 initEvent(type, can_bubble, cancelable); |
165 | 179 |
166 data_type_ = kDataTypeScriptValue; | 180 data_type_ = kDataTypeV8Reference; |
167 data_as_script_value_ = data; | 181 if (!data.IsEmpty()) { |
| 182 world_ = RefPtr<DOMWrapperWorld>(script_state->World()); |
| 183 data_as_v8_value_reference_.Set(data.GetIsolate(), data.V8Value()); |
| 184 } |
168 origin_ = origin; | 185 origin_ = origin; |
169 last_event_id_ = last_event_id; | 186 last_event_id_ = last_event_id; |
170 source_ = source; | 187 source_ = source; |
171 ports_ = ports; | 188 ports_ = ports; |
172 suborigin_ = ""; | 189 suborigin_ = ""; |
173 } | 190 } |
174 | 191 |
175 void MessageEvent::initMessageEvent(const AtomicString& type, | 192 void MessageEvent::initMessageEvent(const AtomicString& type, |
176 bool can_bubble, | 193 bool can_bubble, |
177 bool cancelable, | 194 bool cancelable, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 last_event_id_ = last_event_id; | 234 last_event_id_ = last_event_id; |
218 source_ = source; | 235 source_ = source; |
219 ports_ = ports; | 236 ports_ = ports; |
220 suborigin_ = ""; | 237 suborigin_ = ""; |
221 } | 238 } |
222 | 239 |
223 const AtomicString& MessageEvent::InterfaceName() const { | 240 const AtomicString& MessageEvent::InterfaceName() const { |
224 return EventNames::MessageEvent; | 241 return EventNames::MessageEvent; |
225 } | 242 } |
226 | 243 |
| 244 ScriptValue MessageEvent::DataAsScriptValue(ScriptState* script_state) const { |
| 245 DCHECK_EQ(data_type_, kDataTypeV8Reference); |
| 246 DCHECK(script_state); |
| 247 v8::Isolate* isolate = script_state->GetIsolate(); |
| 248 if (data_as_v8_value_reference_.IsEmpty()) |
| 249 return ScriptValue(script_state, v8::Null(isolate)); |
| 250 // Returns a clone of the v8 value if the world is different. |
| 251 if (!world_ || world_->GetWorldId() != script_state->World().GetWorldId()) { |
| 252 v8::Local<v8::Value> value = data_as_v8_value_reference_.NewLocal(isolate); |
| 253 RefPtr<SerializedScriptValue> serialized = |
| 254 SerializedScriptValue::SerializeAndSwallowExceptions(isolate, value); |
| 255 return ScriptValue(script_state, serialized->Deserialize(isolate)); |
| 256 } |
| 257 return ScriptValue(script_state, |
| 258 data_as_v8_value_reference_.NewLocal(isolate)); |
| 259 } |
| 260 |
227 MessagePortArray MessageEvent::ports(bool& is_null) const { | 261 MessagePortArray MessageEvent::ports(bool& is_null) const { |
228 // TODO(bashi): Currently we return a copied array because the binding | 262 // TODO(bashi): Currently we return a copied array because the binding |
229 // layer could modify the content of the array while executing JS callbacks. | 263 // layer could modify the content of the array while executing JS callbacks. |
230 // Avoid copying once we can make sure that the binding layer won't | 264 // Avoid copying once we can make sure that the binding layer won't |
231 // modify the content. | 265 // modify the content. |
232 if (ports_) { | 266 if (ports_) { |
233 is_null = false; | 267 is_null = false; |
234 return *ports_; | 268 return *ports_; |
235 } | 269 } |
236 is_null = true; | 270 is_null = true; |
(...skipping 10 matching lines...) Expand all Loading... |
247 } | 281 } |
248 | 282 |
249 DEFINE_TRACE(MessageEvent) { | 283 DEFINE_TRACE(MessageEvent) { |
250 visitor->Trace(data_as_blob_); | 284 visitor->Trace(data_as_blob_); |
251 visitor->Trace(data_as_array_buffer_); | 285 visitor->Trace(data_as_array_buffer_); |
252 visitor->Trace(source_); | 286 visitor->Trace(source_); |
253 visitor->Trace(ports_); | 287 visitor->Trace(ports_); |
254 Event::Trace(visitor); | 288 Event::Trace(visitor); |
255 } | 289 } |
256 | 290 |
| 291 DEFINE_TRACE_WRAPPERS(MessageEvent) { |
| 292 visitor->TraceWrappers(data_as_v8_value_reference_); |
| 293 Event::TraceWrappers(visitor); |
| 294 } |
| 295 |
257 v8::Local<v8::Object> MessageEvent::AssociateWithWrapper( | 296 v8::Local<v8::Object> MessageEvent::AssociateWithWrapper( |
258 v8::Isolate* isolate, | 297 v8::Isolate* isolate, |
259 const WrapperTypeInfo* wrapper_type, | 298 const WrapperTypeInfo* wrapper_type, |
260 v8::Local<v8::Object> wrapper) { | 299 v8::Local<v8::Object> wrapper) { |
261 wrapper = Event::AssociateWithWrapper(isolate, wrapper_type, wrapper); | 300 wrapper = Event::AssociateWithWrapper(isolate, wrapper_type, wrapper); |
262 | 301 |
263 // Ensures a wrapper is created for the data to return now so that V8 knows | 302 // Ensures a wrapper is created for the data to return now so that V8 knows |
264 // how much memory is used via the wrapper. To keep the wrapper alive, it's | 303 // how much memory is used via the wrapper. To keep the wrapper alive, it's |
265 // set to the wrapper of the MessageEvent as a private value. | 304 // set to the wrapper of the MessageEvent as a private value. |
266 switch (GetDataType()) { | 305 switch (GetDataType()) { |
267 case MessageEvent::kDataTypeScriptValue: | 306 case MessageEvent::kDataTypeV8Reference: |
268 case MessageEvent::kDataTypeSerializedScriptValue: | 307 case MessageEvent::kDataTypeSerializedScriptValue: |
269 break; | 308 break; |
270 case MessageEvent::kDataTypeString: | 309 case MessageEvent::kDataTypeString: |
271 V8PrivateProperty::GetMessageEventCachedData(isolate).Set( | 310 V8PrivateProperty::GetMessageEventCachedData(isolate).Set( |
272 wrapper, V8String(isolate, DataAsString())); | 311 wrapper, V8String(isolate, DataAsString())); |
273 break; | 312 break; |
274 case MessageEvent::kDataTypeBlob: | 313 case MessageEvent::kDataTypeBlob: |
275 break; | 314 break; |
276 case MessageEvent::kDataTypeArrayBuffer: | 315 case MessageEvent::kDataTypeArrayBuffer: |
277 V8PrivateProperty::GetMessageEventCachedData(isolate).Set( | 316 V8PrivateProperty::GetMessageEventCachedData(isolate).Set( |
278 wrapper, ToV8(DataAsArrayBuffer(), wrapper, isolate)); | 317 wrapper, ToV8(DataAsArrayBuffer(), wrapper, isolate)); |
279 break; | 318 break; |
280 } | 319 } |
281 | 320 |
282 return wrapper; | 321 return wrapper; |
283 } | 322 } |
284 | 323 |
285 } // namespace blink | 324 } // namespace blink |
OLD | NEW |