Changeset 97697 in webkit


Ignore:
Timestamp:
Oct 17, 2011 6:50:06 PM (12 years ago)
Author:
haraken@chromium.org
Message:

MessageEvent.data can be stored as ScriptValue.
https://bugs.webkit.org/show_bug.cgi?id=68978

Reviewed by Hajime Morita.

Source/WebCore:

Currently, the following test cases fail or crash:

  • shouldBe("new MessageEvent('eventType', { data: test_object }).data", "test_object") -> FAIL
  • new MessageEvent('eventType', { data: document }).data -> CRASH

This is because MessageEvent.data is implemented just as SerializedScriptValue
and it cannot keep ScriptValue passed by JavaScript. This patch makes the following changes:

  • If MessageEvent is constructed with ScriptValue, it is stored as ScriptValue internally.

When MessageEvent.data is called, the ScriptValue is returned.

  • If MessageEvent is constructed with SerializedScriptValue, it is stored as

SerializedScriptValue internally (since we cannot deserialize it into ScriptValue
at this point because of lack of ExecState). When MessageEvent.data is called,
the SerializedScriptValue is deserialized into the corresponding ScriptValue,
and the ScriptValue is returned.

This patch does not make a fix for ObjC bindings code, since we need to first fix
the bug 28774, as commented in dom/MessageEvent.h and dom/MessageEvent.cpp.

Test: fast/events/constructors/message-event-constructor.html

  • bindings/js/JSMessageEventCustom.cpp:

(WebCore::JSMessageEvent::data): Custom getter for MessageEvent.data. Supported ScriptValue.
(WebCore::JSMessageEvent::initMessageEvent): Changed SerializedScriptValue to ScriptValue.

  • bindings/v8/custom/V8MessageEventCustom.cpp:

(WebCore::V8MessageEvent::dataAccessorGetter): Custom getter for MessageEvent.data. Supported ScriptValue.
(WebCore::V8MessageEvent::portsAccessorGetter): Removed extra spaces.
(WebCore::V8MessageEvent::initMessageEventCallback): Changed SerializedScriptValue to ScriptValue.

  • dom/MessageEvent.cpp:

(WebCore::MessageEvent::MessageEvent): Supported ScriptValue.
(WebCore::MessageEvent::initMessageEvent): Supported ScriptValue.
(WebCore::MessageEvent::isMessageEvent): Removed extra spaces.

  • dom/MessageEvent.h: Added DataType::DataTypeScriptValue.

(WebCore::MessageEvent::create): Supported ScriptValue.
(WebCore::MessageEvent::dataAsScriptValue): Getter for data. Insert ASSERT() to guarantee that this accessor is not called for unintended type of data.
(WebCore::MessageEvent::dataAsSerializedScriptValue): Ditto.
(WebCore::MessageEvent::dataAsString): Ditto.
(WebCore::MessageEvent::dataAsBlob): Ditto.
(WebCore::MessageEvent::dataAsArrayBuffer): Ditto.

  • dom/MessageEvent.idl: Changed SerializedScriptValue to DOMObject (i.e. ScriptValue). This patch does not touch an ObjC part.

LayoutTests:

Removed failures and crashes.

  • fast/events/constructors/message-event-constructor-expected.txt:
  • fast/events/constructors/message-event-constructor.html:
Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r97693 r97697  
     12011-10-17  Kentaro Hara  <haraken@chromium.org>
     2
     3        MessageEvent.data can be stored as ScriptValue.
     4        https://bugs.webkit.org/show_bug.cgi?id=68978
     5
     6        Reviewed by Hajime Morita.
     7
     8        Removed failures and crashes.
     9
     10        * fast/events/constructors/message-event-constructor-expected.txt:
     11        * fast/events/constructors/message-event-constructor.html:
     12
    1132011-10-12  Ojan Vafai  <ojan@chromium.org>
    214
  • trunk/LayoutTests/fast/events/constructors/message-event-constructor-expected.txt

    r96179 r97697  
    1515PASS new MessageEvent('eventType', { cancelable: false }).cancelable is false
    1616PASS new MessageEvent('eventType', { cancelable: true }).cancelable is true
    17 FAIL new MessageEvent('eventType', { data: test_object }).data should be [object Object]. Was [object Object].
     17PASS new MessageEvent('eventType', { data: test_object }).data is test_object
     18PASS new MessageEvent('eventType', { data: document }).data is document
    1819PASS new MessageEvent('eventType', { data: undefined }).data is undefined
    1920PASS new MessageEvent('eventType', { data: null }).data is null
     
    9596PASS new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel.port2] }).bubbles is true
    9697PASS new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel.port2] }).cancelable is true
    97 FAIL new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel.port2] }).data should be [object Object]. Was [object Object].
     98PASS new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel.port2] }).data is test_object
    9899PASS new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel.port2] }).origin is "wonderful"
    99100PASS new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel.port2] }).lastEventId is "excellent"
  • trunk/LayoutTests/fast/events/constructors/message-event-constructor.html

    r97566 r97697  
    3030
    3131// data is passed.
    32 // FIXME(haraken): This fails because MessageEvent.data cannot handle ScriptValue.
    3332shouldBe("new MessageEvent('eventType', { data: test_object }).data", "test_object");
    34 // FIXME(haraken): When we pass a DOM object, it crashes in DRT (it returns TypeError in non-DRT build).
    35 // shouldBe("new MessageEvent('eventType', { data: document }).data", "document");
     33shouldBe("new MessageEvent('eventType', { data: document }).data", "document");
    3634shouldBe("new MessageEvent('eventType', { data: undefined }).data", "undefined");
    3735shouldBe("new MessageEvent('eventType', { data: null }).data", "null");
     
    121119shouldBe("new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel.port2] }).bubbles", "true");
    122120shouldBe("new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel.port2] }).cancelable", "true");
    123 // FIXME(haraken): This fails because MessageEvent.data cannot handle ScriptValue.
    124121shouldBe("new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel.port2] }).data", "test_object");
    125122shouldBeEqualToString("new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel.port2] }).origin", "wonderful");
  • trunk/Source/WebCore/ChangeLog

    r97696 r97697  
     12011-10-17  Kentaro Hara  <haraken@chromium.org>
     2
     3        MessageEvent.data can be stored as ScriptValue.
     4        https://bugs.webkit.org/show_bug.cgi?id=68978
     5
     6        Reviewed by Hajime Morita.
     7
     8        Currently, the following test cases fail or crash:
     9
     10        - shouldBe("new MessageEvent('eventType', { data: test_object }).data", "test_object") -> FAIL
     11        - new MessageEvent('eventType', { data: document }).data -> CRASH
     12
     13        This is because MessageEvent.data is implemented just as SerializedScriptValue
     14        and it cannot keep ScriptValue passed by JavaScript. This patch makes the following changes:
     15
     16        - If MessageEvent is constructed with ScriptValue, it is stored as ScriptValue internally.
     17        When MessageEvent.data is called, the ScriptValue is returned.
     18        - If MessageEvent is constructed with SerializedScriptValue, it is stored as
     19        SerializedScriptValue internally (since we cannot deserialize it into ScriptValue
     20        at this point because of lack of ExecState). When MessageEvent.data is called,
     21        the SerializedScriptValue is deserialized into the corresponding ScriptValue,
     22        and the ScriptValue is returned.
     23
     24        This patch does not make a fix for ObjC bindings code, since we need to first fix
     25        the bug 28774, as commented in dom/MessageEvent.h and dom/MessageEvent.cpp.
     26
     27        Test: fast/events/constructors/message-event-constructor.html
     28
     29        * bindings/js/JSMessageEventCustom.cpp:
     30        (WebCore::JSMessageEvent::data): Custom getter for MessageEvent.data. Supported ScriptValue.
     31        (WebCore::JSMessageEvent::initMessageEvent): Changed SerializedScriptValue to ScriptValue.
     32        * bindings/v8/custom/V8MessageEventCustom.cpp:
     33        (WebCore::V8MessageEvent::dataAccessorGetter): Custom getter for MessageEvent.data. Supported ScriptValue.
     34        (WebCore::V8MessageEvent::portsAccessorGetter): Removed extra spaces.
     35        (WebCore::V8MessageEvent::initMessageEventCallback): Changed SerializedScriptValue to ScriptValue.
     36        * dom/MessageEvent.cpp:
     37        (WebCore::MessageEvent::MessageEvent): Supported ScriptValue.
     38        (WebCore::MessageEvent::initMessageEvent): Supported ScriptValue.
     39        (WebCore::MessageEvent::isMessageEvent): Removed extra spaces.
     40        * dom/MessageEvent.h: Added DataType::DataTypeScriptValue.
     41        (WebCore::MessageEvent::create): Supported ScriptValue.
     42        (WebCore::MessageEvent::dataAsScriptValue): Getter for data. Insert ASSERT() to guarantee that this accessor is not called for unintended type of data.
     43        (WebCore::MessageEvent::dataAsSerializedScriptValue): Ditto.
     44        (WebCore::MessageEvent::dataAsString): Ditto.
     45        (WebCore::MessageEvent::dataAsBlob): Ditto.
     46        (WebCore::MessageEvent::dataAsArrayBuffer): Ditto.
     47        * dom/MessageEvent.idl: Changed SerializedScriptValue to DOMObject (i.e. ScriptValue). This patch does not touch an ObjC part.
     48
    1492011-10-17  Shinya Kawanaka  <shinyak@google.com>
    250
  • trunk/Source/WebCore/bindings/js/JSMessageEventCustom.cpp

    r97576 r97697  
    5353    JSValue result;
    5454    switch (event->dataType()) {
     55    case MessageEvent::DataTypeScriptValue: {
     56        ScriptValue scriptValue = event->dataAsScriptValue();
     57        if (scriptValue.hasNoValue())
     58            result = jsNull();
     59        else
     60            result = scriptValue.jsValue();
     61        break;
     62    }
     63
    5564    case MessageEvent::DataTypeSerializedScriptValue:
    5665        if (SerializedScriptValue* serializedValue = event->dataAsSerializedScriptValue()) {
  • trunk/Source/WebCore/bindings/v8/custom/V8MessageEventCustom.cpp

    r97516 r97697  
    5252    v8::Handle<v8::Value> result;
    5353    switch (event->dataType()) {
     54    case MessageEvent::DataTypeScriptValue: {
     55        ScriptValue scriptValue = event->dataAsScriptValue();
     56        if (scriptValue.hasNoValue())
     57            result = v8::Null();
     58        else
     59            result = scriptValue.v8Value();
     60        break;
     61    }
     62
    5463    case MessageEvent::DataTypeSerializedScriptValue:
    5564        if (SerializedScriptValue* serializedValue = event->dataAsSerializedScriptValue())
     
    8998    if (!ports)
    9099        return v8::Array::New(0);
    91    
     100
    92101    MessagePortArray portsCopy(*ports);
    93102
     
    106115    bool canBubbleArg = args[1]->BooleanValue();
    107116    bool cancelableArg = args[2]->BooleanValue();
    108     RefPtr<SerializedScriptValue> dataArg = SerializedScriptValue::create(args[3]);
     117    ScriptValue dataArg = ScriptValue(args[3]);
    109118    String originArg = v8ValueToWebCoreString(args[4]);
    110119    String lastEventIdArg = v8ValueToWebCoreString(args[5]);
     
    124133            return v8::Undefined();
    125134    }
    126     event->initMessageEvent(typeArg, canBubbleArg, cancelableArg, dataArg.release(), originArg, lastEventIdArg, sourceArg, portArray.release());
     135    event->initMessageEvent(typeArg, canBubbleArg, cancelableArg, dataArg, originArg, lastEventIdArg, sourceArg, portArray.release());
    127136    v8::PropertyAttribute dataAttr = static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly);
    128137    SerializedScriptValue::deserializeAndSetProperty(args.Holder(), "data", dataAttr, event->dataAsSerializedScriptValue());
  • trunk/Source/WebCore/dom/MessageEvent.cpp

    r96179 r97697  
    3535
    3636MessageEventInit::MessageEventInit()
    37     : data(SerializedScriptValue::create())
    3837{
    3938}
    4039
    4140MessageEvent::MessageEvent()
    42     : m_dataType(DataTypeSerializedScriptValue)
    43     , m_dataAsSerializedScriptValue(SerializedScriptValue::create())
     41    : m_dataType(DataTypeScriptValue)
    4442{
    4543}
     
    4745MessageEvent::MessageEvent(const AtomicString& type, const MessageEventInit& initializer)
    4846    : Event(type, initializer)
    49     , m_dataType(DataTypeSerializedScriptValue)
    50     , m_dataAsSerializedScriptValue(initializer.data)
     47    , m_dataType(DataTypeScriptValue)
     48    , m_dataAsScriptValue(initializer.data)
    5149    , m_origin(initializer.origin)
    5250    , m_lastEventId(initializer.lastEventId)
    5351    , m_source(initializer.source)
    5452    , m_ports(adoptPtr(new MessagePortArray(initializer.ports)))
     53{
     54}
     55
     56MessageEvent::MessageEvent(const ScriptValue& data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortArray> ports)
     57    : Event(eventNames().messageEvent, false, false)
     58    , m_dataType(DataTypeScriptValue)
     59    , m_dataAsScriptValue(data)
     60    , m_origin(origin)
     61    , m_lastEventId(lastEventId)
     62    , m_source(source)
     63    , m_ports(ports)
    5564{
    5665}
     
    98107}
    99108
     109void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, const ScriptValue& data, const String& origin, const String& lastEventId, DOMWindow* source, PassOwnPtr<MessagePortArray> ports)
     110{
     111    if (dispatched())
     112        return;
     113
     114    initEvent(type, canBubble, cancelable);
     115
     116    m_dataType = DataTypeScriptValue;
     117    m_dataAsScriptValue = data;
     118    m_origin = origin;
     119    m_lastEventId = lastEventId;
     120    m_source = source;
     121    m_ports = ports;
     122}
     123
    100124void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, DOMWindow* source, PassOwnPtr<MessagePortArray> ports)
    101125{
     
    130154}
    131155
     156// FIXME: remove this when we update the ObjC bindings (bug #28774).
    132157void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, DOMWindow* source, MessagePort* port)
    133158{
     
    140165}
    141166
    142 bool MessageEvent::isMessageEvent() const 
     167bool MessageEvent::isMessageEvent() const
    143168{
    144169    return true;
  • trunk/Source/WebCore/dom/MessageEvent.h

    r96179 r97697  
    3434#include "Event.h"
    3535#include "MessagePort.h"
     36#include "ScriptValue.h"
    3637#include "SerializedScriptValue.h"
    3738
     
    4344    MessageEventInit();
    4445
    45     RefPtr<SerializedScriptValue> data;
     46    ScriptValue data;
    4647    String origin;
    4748    String lastEventId;
     
    5657        return adoptRef(new MessageEvent);
    5758    }
    58     static PassRefPtr<MessageEvent> create(PassOwnPtr<MessagePortArray> ports, PassRefPtr<SerializedScriptValue> data = 0, const String& origin = "", const String& lastEventId = "", PassRefPtr<DOMWindow> source = 0)
     59    static PassRefPtr<MessageEvent> create(PassOwnPtr<MessagePortArray> ports, const ScriptValue& data = ScriptValue(), const String& origin = "", const String& lastEventId = "", PassRefPtr<DOMWindow> source = 0)
     60    {
     61        return adoptRef(new MessageEvent(data, origin, lastEventId, source, ports));
     62    }
     63    static PassRefPtr<MessageEvent> create(PassOwnPtr<MessagePortArray> ports, PassRefPtr<SerializedScriptValue> data, const String& origin = "", const String& lastEventId = "", PassRefPtr<DOMWindow> source = 0)
    5964    {
    6065        return adoptRef(new MessageEvent(data, origin, lastEventId, source, ports));
     
    7883    virtual ~MessageEvent();
    7984
     85    void initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, const ScriptValue& data, const String& origin, const String& lastEventId, DOMWindow* source, PassOwnPtr<MessagePortArray>);
    8086    void initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, DOMWindow* source, PassOwnPtr<MessagePortArray>);
    8187
     
    8793    // FIXME: Remove this when we have custom ObjC binding support.
    8894    SerializedScriptValue* data() const;
    89 
    9095    // FIXME: remove this when we update the ObjC bindings (bug #28774).
    9196    MessagePort* messagePort();
     
    96101
    97102    enum DataType {
     103        DataTypeScriptValue,
    98104        DataTypeSerializedScriptValue,
    99105        DataTypeString,
     
    102108    };
    103109    DataType dataType() const { return m_dataType; }
    104     SerializedScriptValue* dataAsSerializedScriptValue() const { return m_dataAsSerializedScriptValue.get(); }
    105     String dataAsString() const { return m_dataAsString; }
    106     Blob* dataAsBlob() const { return m_dataAsBlob.get(); }
    107     ArrayBuffer* dataAsArrayBuffer() const { return m_dataAsArrayBuffer.get(); }
     110    ScriptValue dataAsScriptValue() const { ASSERT(m_dataType == DataTypeScriptValue); return m_dataAsScriptValue; }
     111    SerializedScriptValue* dataAsSerializedScriptValue() const { ASSERT(m_dataType == DataTypeSerializedScriptValue); return m_dataAsSerializedScriptValue.get(); }
     112    String dataAsString() const { ASSERT(m_dataType == DataTypeString); return m_dataAsString; }
     113    Blob* dataAsBlob() const { ASSERT(m_dataType == DataTypeBlob); return m_dataAsBlob.get(); }
     114    ArrayBuffer* dataAsArrayBuffer() const { ASSERT(m_dataType == DataTypeArrayBuffer); return m_dataAsArrayBuffer.get(); }
    108115
    109116private:
    110117    MessageEvent();
    111118    MessageEvent(const AtomicString&, const MessageEventInit&);
     119    MessageEvent(const ScriptValue& data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortArray>);
    112120    MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortArray>);
    113121
     
    117125
    118126    DataType m_dataType;
     127    ScriptValue m_dataAsScriptValue;
    119128    RefPtr<SerializedScriptValue> m_dataAsSerializedScriptValue;
    120129    String m_dataAsString;
  • trunk/Source/WebCore/dom/MessageEvent.idl

    r96788 r97697  
    3737        readonly attribute DOMWindow source;
    3838#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
    39         readonly attribute [CachedAttribute, CustomGetter] any data;
     39        readonly attribute [CachedAttribute, CustomGetter] DOMObject data;
    4040        readonly attribute [CustomGetter] Array ports;
    4141
     
    4343                                       in [Optional=CallWithDefaultValue] boolean canBubbleArg,
    4444                                       in [Optional=CallWithDefaultValue] boolean cancelableArg,
    45                                        in [Optional=CallWithDefaultValue] SerializedScriptValue dataArg,
     45                                       in [Optional=CallWithDefaultValue] DOMObject dataArg,
    4646                                       in [Optional=CallWithDefaultValue] DOMString originArg,
    4747                                       in [Optional=CallWithDefaultValue] DOMString lastEventIdArg,
     
    5252                                             in [Optional=CallWithDefaultValue] boolean canBubbleArg,
    5353                                             in [Optional=CallWithDefaultValue] boolean cancelableArg,
    54                                              in [Optional=CallWithDefaultValue] SerializedScriptValue dataArg,
     54                                             in [Optional=CallWithDefaultValue] DOMObject dataArg,
    5555                                             in [Optional=CallWithDefaultValue] DOMString originArg,
    5656                                             in [Optional=CallWithDefaultValue] DOMString lastEventIdArg,
Note: See TracChangeset for help on using the changeset viewer.