Home | History | Annotate | Download | only in events
      1 /*
      2  * Copyright (C) 2007 Henry Mason (hmason (at) 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/core/v8/ExceptionMessages.h"
     32 #include "bindings/core/v8/ExceptionState.h"
     33 #include "bindings/core/v8/custom/V8ArrayBufferCustom.h"
     34 
     35 namespace blink {
     36 
     37 static inline bool isValidSource(EventTarget* source)
     38 {
     39     return !source || source->toDOMWindow() || source->toMessagePort();
     40 }
     41 
     42 MessageEventInit::MessageEventInit()
     43 {
     44 }
     45 
     46 MessageEvent::MessageEvent()
     47     : m_dataType(DataTypeScriptValue)
     48 {
     49 }
     50 
     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(adoptPtrWillBeNoop(new MessagePortArray(initializer.ports)))
     58 {
     59     ASSERT(isValidSource(m_source.get()));
     60 }
     61 
     62 MessageEvent::MessageEvent(const String& origin, const String& lastEventId, PassRefPtrWillBeRawPtr<EventTarget> source, PassOwnPtrWillBeRawPtr<MessagePortArray> ports)
     63     : Event(EventTypeNames::message, false, false)
     64     , m_dataType(DataTypeScriptValue)
     65     , m_origin(origin)
     66     , m_lastEventId(lastEventId)
     67     , m_source(source)
     68     , m_ports(ports)
     69 {
     70     ASSERT(isValidSource(m_source.get()));
     71 }
     72 
     73 MessageEvent::MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtrWillBeRawPtr<EventTarget> source, PassOwnPtrWillBeRawPtr<MessagePortArray> ports)
     74     : Event(EventTypeNames::message, false, false)
     75     , m_dataType(DataTypeSerializedScriptValue)
     76     , m_dataAsSerializedScriptValue(data)
     77     , m_origin(origin)
     78     , m_lastEventId(lastEventId)
     79     , m_source(source)
     80     , m_ports(ports)
     81 {
     82     if (m_dataAsSerializedScriptValue)
     83         m_dataAsSerializedScriptValue->registerMemoryAllocatedWithCurrentScriptContext();
     84     ASSERT(isValidSource(m_source.get()));
     85 }
     86 
     87 MessageEvent::MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtrWillBeRawPtr<EventTarget> source, PassOwnPtr<MessagePortChannelArray> channels)
     88     : Event(EventTypeNames::message, false, false)
     89     , m_dataType(DataTypeSerializedScriptValue)
     90     , m_dataAsSerializedScriptValue(data)
     91     , m_origin(origin)
     92     , m_lastEventId(lastEventId)
     93     , m_source(source)
     94     , m_channels(channels)
     95 {
     96     if (m_dataAsSerializedScriptValue)
     97         m_dataAsSerializedScriptValue->registerMemoryAllocatedWithCurrentScriptContext();
     98     ASSERT(isValidSource(m_source.get()));
     99 }
    100 
    101 MessageEvent::MessageEvent(const String& data, const String& origin)
    102     : Event(EventTypeNames::message, false, false)
    103     , m_dataType(DataTypeString)
    104     , m_dataAsString(data)
    105     , m_origin(origin)
    106 {
    107 }
    108 
    109 MessageEvent::MessageEvent(PassRefPtrWillBeRawPtr<Blob> data, const String& origin)
    110     : Event(EventTypeNames::message, false, false)
    111     , m_dataType(DataTypeBlob)
    112     , m_dataAsBlob(data)
    113     , m_origin(origin)
    114 {
    115 }
    116 
    117 MessageEvent::MessageEvent(PassRefPtr<ArrayBuffer> data, const String& origin)
    118     : Event(EventTypeNames::message, false, false)
    119     , m_dataType(DataTypeArrayBuffer)
    120     , m_dataAsArrayBuffer(data)
    121     , m_origin(origin)
    122 {
    123 }
    124 
    125 MessageEvent::~MessageEvent()
    126 {
    127 }
    128 
    129 PassRefPtrWillBeRawPtr<MessageEvent> MessageEvent::create(const AtomicString& type, const MessageEventInit& initializer, ExceptionState& exceptionState)
    130 {
    131     if (initializer.source.get() && !isValidSource(initializer.source.get())) {
    132         exceptionState.throwTypeError("The optional 'source' property is neither a Window nor MessagePort.");
    133         return nullptr;
    134     }
    135     return adoptRefWillBeNoop(new MessageEvent(type, initializer));
    136 }
    137 
    138 void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& origin, const String& lastEventId, LocalDOMWindow* source, PassOwnPtrWillBeRawPtr<MessagePortArray> ports)
    139 {
    140     if (dispatched())
    141         return;
    142 
    143     initEvent(type, canBubble, cancelable);
    144 
    145     m_dataType = DataTypeScriptValue;
    146     m_origin = origin;
    147     m_lastEventId = lastEventId;
    148     m_source = source;
    149     m_ports = ports;
    150 }
    151 
    152 void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, LocalDOMWindow* source, PassOwnPtrWillBeRawPtr<MessagePortArray> ports)
    153 {
    154     if (dispatched())
    155         return;
    156 
    157     initEvent(type, canBubble, cancelable);
    158 
    159     m_dataType = DataTypeSerializedScriptValue;
    160     m_dataAsSerializedScriptValue = data;
    161     m_origin = origin;
    162     m_lastEventId = lastEventId;
    163     m_source = source;
    164     m_ports = ports;
    165 
    166     if (m_dataAsSerializedScriptValue)
    167         m_dataAsSerializedScriptValue->registerMemoryAllocatedWithCurrentScriptContext();
    168 }
    169 
    170 const AtomicString& MessageEvent::interfaceName() const
    171 {
    172     return EventNames::MessageEvent;
    173 }
    174 
    175 void MessageEvent::entangleMessagePorts(ExecutionContext* context)
    176 {
    177     m_ports = MessagePort::entanglePorts(*context, m_channels.release());
    178 }
    179 
    180 void MessageEvent::trace(Visitor* visitor)
    181 {
    182     visitor->trace(m_dataAsBlob);
    183     visitor->trace(m_source);
    184 #if ENABLE(OILPAN)
    185     visitor->trace(m_ports);
    186 #endif
    187     Event::trace(visitor);
    188 }
    189 
    190 v8::Handle<v8::Object> MessageEvent::associateWithWrapper(const WrapperTypeInfo* wrapperType, v8::Handle<v8::Object> wrapper, v8::Isolate* isolate)
    191 {
    192     Event::associateWithWrapper(wrapperType, wrapper, isolate);
    193 
    194     // Ensures a wrapper is created for the data to return now so that V8 knows how
    195     // much memory is used via the wrapper. To keep the wrapper alive, it's set to
    196     // the wrapper of the MessageEvent as a hidden value.
    197     switch (dataType()) {
    198     case MessageEvent::DataTypeScriptValue:
    199     case MessageEvent::DataTypeSerializedScriptValue:
    200         break;
    201     case MessageEvent::DataTypeString:
    202         V8HiddenValue::setHiddenValue(isolate, wrapper, V8HiddenValue::stringData(isolate), v8String(isolate, dataAsString()));
    203         break;
    204     case MessageEvent::DataTypeBlob:
    205         break;
    206     case MessageEvent::DataTypeArrayBuffer:
    207         V8HiddenValue::setHiddenValue(isolate, wrapper, V8HiddenValue::arrayBufferData(isolate), toV8(dataAsArrayBuffer(), wrapper, isolate));
    208         break;
    209     }
    210 
    211     return wrapper;
    212 }
    213 
    214 } // namespace blink
    215