Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / core / events / MessageEvent.cpp
blobb969056a73b8d408758118ec9b08c1703d418964
1 /*
2 * Copyright (C) 2007 Henry Mason (hmason@mac.com)
3 * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include "config.h"
29 #include "core/events/MessageEvent.h"
31 #include "bindings/core/v8/ExceptionMessages.h"
32 #include "bindings/core/v8/ExceptionState.h"
33 #include "bindings/core/v8/V8ArrayBuffer.h"
35 namespace blink {
37 static inline bool isValidSource(EventTarget* source)
39 return !source || source->toDOMWindow() || source->toMessagePort();
42 MessageEvent::MessageEvent()
43 : m_dataType(DataTypeScriptValue)
47 MessageEvent::MessageEvent(const AtomicString& type, const MessageEventInit& initializer)
48 : Event(type, initializer)
49 , m_dataType(DataTypeScriptValue)
50 , m_source(nullptr)
52 if (initializer.hasData())
53 m_dataAsScriptValue = initializer.data();
54 if (initializer.hasOrigin())
55 m_origin = initializer.origin();
56 if (initializer.hasLastEventId())
57 m_lastEventId = initializer.lastEventId();
58 if (initializer.hasSource() && isValidSource(initializer.source().get()))
59 m_source = initializer.source();
60 if (initializer.hasPorts())
61 m_ports = new MessagePortArray(initializer.ports());
62 ASSERT(isValidSource(m_source.get()));
65 MessageEvent::MessageEvent(const String& origin, const String& lastEventId, PassRefPtrWillBeRawPtr<EventTarget> source, MessagePortArray* ports)
66 : Event(EventTypeNames::message, false, false)
67 , m_dataType(DataTypeScriptValue)
68 , m_origin(origin)
69 , m_lastEventId(lastEventId)
70 , m_source(source)
71 , m_ports(ports)
73 ASSERT(isValidSource(m_source.get()));
76 MessageEvent::MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtrWillBeRawPtr<EventTarget> source, MessagePortArray* ports)
77 : Event(EventTypeNames::message, false, false)
78 , m_dataType(DataTypeSerializedScriptValue)
79 , m_dataAsSerializedScriptValue(data)
80 , m_origin(origin)
81 , m_lastEventId(lastEventId)
82 , m_source(source)
83 , m_ports(ports)
85 if (m_dataAsSerializedScriptValue)
86 m_dataAsSerializedScriptValue->registerMemoryAllocatedWithCurrentScriptContext();
87 ASSERT(isValidSource(m_source.get()));
90 MessageEvent::MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtrWillBeRawPtr<EventTarget> source, PassOwnPtr<MessagePortChannelArray> channels)
91 : Event(EventTypeNames::message, false, false)
92 , m_dataType(DataTypeSerializedScriptValue)
93 , m_dataAsSerializedScriptValue(data)
94 , m_origin(origin)
95 , m_lastEventId(lastEventId)
96 , m_source(source)
97 , m_channels(channels)
99 if (m_dataAsSerializedScriptValue)
100 m_dataAsSerializedScriptValue->registerMemoryAllocatedWithCurrentScriptContext();
101 ASSERT(isValidSource(m_source.get()));
104 MessageEvent::MessageEvent(const String& data, const String& origin)
105 : Event(EventTypeNames::message, false, false)
106 , m_dataType(DataTypeString)
107 , m_dataAsString(data)
108 , m_origin(origin)
112 MessageEvent::MessageEvent(Blob* data, const String& origin)
113 : Event(EventTypeNames::message, false, false)
114 , m_dataType(DataTypeBlob)
115 , m_dataAsBlob(data)
116 , m_origin(origin)
120 MessageEvent::MessageEvent(PassRefPtr<DOMArrayBuffer> data, const String& origin)
121 : Event(EventTypeNames::message, false, false)
122 , m_dataType(DataTypeArrayBuffer)
123 , m_dataAsArrayBuffer(data)
124 , m_origin(origin)
128 MessageEvent::~MessageEvent()
132 PassRefPtrWillBeRawPtr<MessageEvent> MessageEvent::create(const AtomicString& type, const MessageEventInit& initializer, ExceptionState& exceptionState)
134 if (initializer.source().get() && !isValidSource(initializer.source().get())) {
135 exceptionState.throwTypeError("The optional 'source' property is neither a Window nor MessagePort.");
136 return nullptr;
138 return adoptRefWillBeNoop(new MessageEvent(type, initializer));
141 void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, ScriptValue data, const String& origin, const String& lastEventId, DOMWindow* source, MessagePortArray* ports)
143 if (dispatched())
144 return;
146 initEvent(type, canBubble, cancelable);
148 m_dataType = DataTypeScriptValue;
149 m_dataAsScriptValue = data;
150 m_origin = origin;
151 m_lastEventId = lastEventId;
152 m_source = source;
153 m_ports = ports;
156 void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, DOMWindow* source, MessagePortArray* ports)
158 if (dispatched())
159 return;
161 initEvent(type, canBubble, cancelable);
163 m_dataType = DataTypeSerializedScriptValue;
164 m_dataAsSerializedScriptValue = data;
165 m_origin = origin;
166 m_lastEventId = lastEventId;
167 m_source = source;
168 m_ports = ports;
170 if (m_dataAsSerializedScriptValue)
171 m_dataAsSerializedScriptValue->registerMemoryAllocatedWithCurrentScriptContext();
174 const AtomicString& MessageEvent::interfaceName() const
176 return EventNames::MessageEvent;
179 MessagePortArray MessageEvent::ports(bool& isNull) const
181 // TODO(bashi): Currently we return a copied array because the binding
182 // layer could modify the content of the array while executing JS callbacks.
183 // Avoid copying once we can make sure that the binding layer won't
184 // modify the content.
185 if (m_ports) {
186 isNull = false;
187 return *m_ports;
189 isNull = true;
190 return MessagePortArray();
193 MessagePortArray MessageEvent::ports() const
195 bool unused;
196 return ports(unused);
199 void MessageEvent::entangleMessagePorts(ExecutionContext* context)
201 m_ports = MessagePort::entanglePorts(*context, m_channels.release());
204 DEFINE_TRACE(MessageEvent)
206 visitor->trace(m_dataAsBlob);
207 visitor->trace(m_source);
208 #if ENABLE(OILPAN)
209 visitor->trace(m_ports);
210 #endif
211 Event::trace(visitor);
214 v8::Local<v8::Object> MessageEvent::associateWithWrapper(v8::Isolate* isolate, const WrapperTypeInfo* wrapperType, v8::Local<v8::Object> wrapper)
216 wrapper = Event::associateWithWrapper(isolate, wrapperType, wrapper);
218 // Ensures a wrapper is created for the data to return now so that V8 knows how
219 // much memory is used via the wrapper. To keep the wrapper alive, it's set to
220 // the wrapper of the MessageEvent as a hidden value.
221 switch (dataType()) {
222 case MessageEvent::DataTypeScriptValue:
223 case MessageEvent::DataTypeSerializedScriptValue:
224 break;
225 case MessageEvent::DataTypeString:
226 V8HiddenValue::setHiddenValue(isolate, wrapper, V8HiddenValue::stringData(isolate), v8String(isolate, dataAsString()));
227 break;
228 case MessageEvent::DataTypeBlob:
229 break;
230 case MessageEvent::DataTypeArrayBuffer:
231 V8HiddenValue::setHiddenValue(isolate, wrapper, V8HiddenValue::arrayBufferData(isolate), toV8(dataAsArrayBuffer(), wrapper, isolate));
232 break;
235 return wrapper;
238 } // namespace blink