1 /*
2 * Copyright (C) 2007 Henry Mason (hmason@mac.com)
3 * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
4 *
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.
13 *
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.
25 *
26 */
27
28 #include "config.h"
29 #include "core/events/MessageEvent.h"
30
31 #include "bindings/v8/ExceptionMessages.h"
32 #include "bindings/v8/ExceptionState.h"
33
34 namespace WebCore {
35
isValidSource(EventTarget * source)36 static inline bool isValidSource(EventTarget* source)
37 {
38 return !source || source->toDOMWindow() || source->toMessagePort();
39 }
40
MessageEventInit()41 MessageEventInit::MessageEventInit()
42 {
43 }
44
MessageEvent()45 MessageEvent::MessageEvent()
46 : m_dataType(DataTypeScriptValue)
47 {
48 ScriptWrappable::init(this);
49 }
50
MessageEvent(const AtomicString & type,const MessageEventInit & initializer)51 MessageEvent::MessageEvent(const AtomicString& type, const MessageEventInit& initializer)
52 : Event(type, initializer)
53 , m_dataType(DataTypeScriptValue)
54 , m_origin(initializer.origin)
55 , m_lastEventId(initializer.lastEventId)
56 , m_source(isValidSource(initializer.source.get()) ? initializer.source : nullptr)
57 , m_ports(adoptPtr(new MessagePortArray(initializer.ports)))
58 {
59 ScriptWrappable::init(this);
60 ASSERT(isValidSource(m_source.get()));
61 }
62
MessageEvent(const String & origin,const String & lastEventId,PassRefPtrWillBeRawPtr<EventTarget> source,PassOwnPtr<MessagePortArray> ports)63 MessageEvent::MessageEvent(const String& origin, const String& lastEventId, PassRefPtrWillBeRawPtr<EventTarget> source, PassOwnPtr<MessagePortArray> ports)
64 : Event(EventTypeNames::message, false, false)
65 , m_dataType(DataTypeScriptValue)
66 , m_origin(origin)
67 , m_lastEventId(lastEventId)
68 , m_source(source)
69 , m_ports(ports)
70 {
71 ScriptWrappable::init(this);
72 ASSERT(isValidSource(m_source.get()));
73 }
74
MessageEvent(PassRefPtr<SerializedScriptValue> data,const String & origin,const String & lastEventId,PassRefPtrWillBeRawPtr<EventTarget> source,PassOwnPtr<MessagePortArray> ports)75 MessageEvent::MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtrWillBeRawPtr<EventTarget> source, PassOwnPtr<MessagePortArray> ports)
76 : Event(EventTypeNames::message, false, false)
77 , m_dataType(DataTypeSerializedScriptValue)
78 , m_dataAsSerializedScriptValue(data)
79 , m_origin(origin)
80 , m_lastEventId(lastEventId)
81 , m_source(source)
82 , m_ports(ports)
83 {
84 ScriptWrappable::init(this);
85 if (m_dataAsSerializedScriptValue)
86 m_dataAsSerializedScriptValue->registerMemoryAllocatedWithCurrentScriptContext();
87 ASSERT(isValidSource(m_source.get()));
88 }
89
MessageEvent(PassRefPtr<SerializedScriptValue> data,const String & origin,const String & lastEventId,PassRefPtrWillBeRawPtr<EventTarget> source,PassOwnPtr<MessagePortChannelArray> channels)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)
98 {
99 ScriptWrappable::init(this);
100 if (m_dataAsSerializedScriptValue)
101 m_dataAsSerializedScriptValue->registerMemoryAllocatedWithCurrentScriptContext();
102 ASSERT(isValidSource(m_source.get()));
103 }
104
MessageEvent(const String & data,const String & origin)105 MessageEvent::MessageEvent(const String& data, const String& origin)
106 : Event(EventTypeNames::message, false, false)
107 , m_dataType(DataTypeString)
108 , m_dataAsString(data)
109 , m_origin(origin)
110 {
111 ScriptWrappable::init(this);
112 }
113
MessageEvent(PassRefPtrWillBeRawPtr<Blob> data,const String & origin)114 MessageEvent::MessageEvent(PassRefPtrWillBeRawPtr<Blob> data, const String& origin)
115 : Event(EventTypeNames::message, false, false)
116 , m_dataType(DataTypeBlob)
117 , m_dataAsBlob(data)
118 , m_origin(origin)
119 {
120 ScriptWrappable::init(this);
121 }
122
MessageEvent(PassRefPtr<ArrayBuffer> data,const String & origin)123 MessageEvent::MessageEvent(PassRefPtr<ArrayBuffer> data, const String& origin)
124 : Event(EventTypeNames::message, false, false)
125 , m_dataType(DataTypeArrayBuffer)
126 , m_dataAsArrayBuffer(data)
127 , m_origin(origin)
128 {
129 ScriptWrappable::init(this);
130 }
131
~MessageEvent()132 MessageEvent::~MessageEvent()
133 {
134 }
135
create(const AtomicString & type,const MessageEventInit & initializer,ExceptionState & exceptionState)136 PassRefPtrWillBeRawPtr<MessageEvent> MessageEvent::create(const AtomicString& type, const MessageEventInit& initializer, ExceptionState& exceptionState)
137 {
138 if (initializer.source.get() && !isValidSource(initializer.source.get())) {
139 exceptionState.throwTypeError("The optional 'source' property is neither a Window nor MessagePort.");
140 return nullptr;
141 }
142 return adoptRefWillBeNoop(new MessageEvent(type, initializer));
143 }
144
initMessageEvent(const AtomicString & type,bool canBubble,bool cancelable,const String & origin,const String & lastEventId,LocalDOMWindow * source,PassOwnPtr<MessagePortArray> ports)145 void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& origin, const String& lastEventId, LocalDOMWindow* source, PassOwnPtr<MessagePortArray> ports)
146 {
147 if (dispatched())
148 return;
149
150 initEvent(type, canBubble, cancelable);
151
152 m_dataType = DataTypeScriptValue;
153 m_origin = origin;
154 m_lastEventId = lastEventId;
155 m_source = source;
156 m_ports = ports;
157 }
158
initMessageEvent(const AtomicString & type,bool canBubble,bool cancelable,PassRefPtr<SerializedScriptValue> data,const String & origin,const String & lastEventId,LocalDOMWindow * source,PassOwnPtr<MessagePortArray> ports)159 void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, LocalDOMWindow* source, PassOwnPtr<MessagePortArray> ports)
160 {
161 if (dispatched())
162 return;
163
164 initEvent(type, canBubble, cancelable);
165
166 m_dataType = DataTypeSerializedScriptValue;
167 m_dataAsSerializedScriptValue = data;
168 m_origin = origin;
169 m_lastEventId = lastEventId;
170 m_source = source;
171 m_ports = ports;
172
173 if (m_dataAsSerializedScriptValue)
174 m_dataAsSerializedScriptValue->registerMemoryAllocatedWithCurrentScriptContext();
175 }
176
interfaceName() const177 const AtomicString& MessageEvent::interfaceName() const
178 {
179 return EventNames::MessageEvent;
180 }
181
entangleMessagePorts(ExecutionContext * context)182 void MessageEvent::entangleMessagePorts(ExecutionContext* context)
183 {
184 m_ports = MessagePort::entanglePorts(*context, m_channels.release());
185 }
186
trace(Visitor * visitor)187 void MessageEvent::trace(Visitor* visitor)
188 {
189 visitor->trace(m_dataAsBlob);
190 visitor->trace(m_source);
191 Event::trace(visitor);
192 }
193
194 } // namespace WebCore
195