Title: [96179] trunk
Revision
96179
Author
[email protected]
Date
2011-09-27 19:02:18 -0700 (Tue, 27 Sep 2011)

Log Message

Implement a MessageEvent constructor for JSC
https://bugs.webkit.org/show_bug.cgi?id=68883

Patch by Kentaro Hara <[email protected]> on 2011-09-27
Reviewed by Adam Barth.

Source/WebCore:

The spec for MessageEvent is here:
http://www.whatwg.org/specs/web-apps/current-work/#messageevent

Currently, some tests in fast/events/constructors/message-event-constructor.html
are failing or crashing in DRT, as we commented in the test file.
This is because MessageEvent.data is implemented as SerializedScriptValue,
and thus it cannot keep ScriptValue passed by _javascript_.
This is the same issue as the bug (https://bugs.webkit.org/show_bug.cgi?id=68345).
We will soon make a follow-up patch to fix these failures, after this
patch is landed.

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

* bindings/generic/EventConstructors.h: Added a definition for the MessageEvent constructor.
* bindings/js/JSDictionary.cpp:
(WebCore::JSDictionary::convertValue): Generates MessagePortArray from the list of message ports in the format of JSValues.
* bindings/js/JSDictionary.h:
* bindings/js/JSEventConstructors.cpp: Added #includes for MessageEvent.
* dom/MessageEvent.cpp:
(WebCore::MessageEventInit::MessageEventInit):
(WebCore::MessageEvent::MessageEvent):
(WebCore::MessageEvent::initMessageEvent):
* dom/MessageEvent.h: Added a definition for MessageEvent. Removed an extra leading spaces.
(WebCore::MessageEvent::create):
(WebCore::MessageEvent::origin):
(WebCore::MessageEvent::lastEventId):
(WebCore::MessageEvent::source):
(WebCore::MessageEvent::ports):
(WebCore::MessageEvent::dataType):
(WebCore::MessageEvent::dataAsSerializedScriptValue):
(WebCore::MessageEvent::dataAsString):
(WebCore::MessageEvent::dataAsBlob):
(WebCore::MessageEvent::dataAsArrayBuffer):
* dom/MessageEvent.idl: Makes MessageEvent constructible.

LayoutTests:

message-event-constructor.html checks the behavior of the MessageEvent constructor.

* fast/dom/constructed-objects-prototypes-expected.txt: Now window has MessageEvent.
* fast/events/constructors/message-event-constructor-expected.txt: Added.
* fast/events/constructors/message-event-constructor.html: Added.
* platform/chromium/test_expectations.txt: Skipped message-event-constructor.html, since V8 does not yet have the MessageEvent constructor.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (96178 => 96179)


--- trunk/LayoutTests/ChangeLog	2011-09-28 01:52:21 UTC (rev 96178)
+++ trunk/LayoutTests/ChangeLog	2011-09-28 02:02:18 UTC (rev 96179)
@@ -1,3 +1,17 @@
+2011-09-27  Kentaro Hara  <[email protected]>
+
+        Implement a MessageEvent constructor for JSC
+        https://bugs.webkit.org/show_bug.cgi?id=68883
+
+        Reviewed by Adam Barth.
+
+        message-event-constructor.html checks the behavior of the MessageEvent constructor.
+
+        * fast/dom/constructed-objects-prototypes-expected.txt: Now window has MessageEvent.
+        * fast/events/constructors/message-event-constructor-expected.txt: Added.
+        * fast/events/constructors/message-event-constructor.html: Added.
+        * platform/chromium/test_expectations.txt: Skipped message-event-constructor.html, since V8 does not yet have the MessageEvent constructor.
+
 2011-09-27  Eric Uhrhane  <[email protected]>
 
         [Chromium/FileWriter] race condition in FileWriter completion can lead to assert

Modified: trunk/LayoutTests/fast/dom/constructed-objects-prototypes-expected.txt (96178 => 96179)


--- trunk/LayoutTests/fast/dom/constructed-objects-prototypes-expected.txt	2011-09-28 01:52:21 UTC (rev 96178)
+++ trunk/LayoutTests/fast/dom/constructed-objects-prototypes-expected.txt	2011-09-28 02:02:18 UTC (rev 96179)
@@ -23,6 +23,8 @@
 PASS (new inner.Image()).constructor.isInner is true
 PASS (new inner.MessageChannel()).isInner is true
 PASS (new inner.MessageChannel()).constructor.isInner is true
+PASS (new inner.MessageEvent()).isInner is true
+PASS (new inner.MessageEvent()).constructor.isInner is true
 PASS (new inner.Option()).isInner is true
 PASS (new inner.Option()).constructor.isInner is true
 PASS (new inner.PageTransitionEvent()).isInner is true

Added: trunk/LayoutTests/fast/events/constructors/message-event-constructor-expected.txt (0 => 96179)


--- trunk/LayoutTests/fast/events/constructors/message-event-constructor-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/events/constructors/message-event-constructor-expected.txt	2011-09-28 02:02:18 UTC (rev 96179)
@@ -0,0 +1,107 @@
+This tests the constructor for the MessageEvent DOM class.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS new MessageEvent('eventType').bubbles is false
+PASS new MessageEvent('eventType').cancelable is false
+PASS new MessageEvent('eventType').data is null
+PASS new MessageEvent('eventType').origin is ""
+PASS new MessageEvent('eventType').lastEventId is ""
+PASS new MessageEvent('eventType').source is null
+PASS new MessageEvent('eventType').ports is []
+PASS new MessageEvent('eventType', { bubbles: false }).bubbles is false
+PASS new MessageEvent('eventType', { bubbles: true }).bubbles is true
+PASS new MessageEvent('eventType', { cancelable: false }).cancelable is false
+PASS new MessageEvent('eventType', { cancelable: true }).cancelable is true
+FAIL new MessageEvent('eventType', { data: test_object }).data should be [object Object]. Was [object Object].
+PASS new MessageEvent('eventType', { data: undefined }).data is undefined
+PASS new MessageEvent('eventType', { data: null }).data is null
+PASS new MessageEvent('eventType', { data: false }).data is false
+PASS new MessageEvent('eventType', { data: true }).data is true
+PASS new MessageEvent('eventType', { data: '' }).data is ""
+PASS new MessageEvent('eventType', { data: 'chocolate' }).data is "chocolate"
+PASS new MessageEvent('eventType', { data: 12345 }).data is 12345
+PASS new MessageEvent('eventType', { data: 18446744073709551615 }).data is 18446744073709552000
+PASS new MessageEvent('eventType', { data: NaN }).data is NaN
+PASS new MessageEvent('eventType', { data: {valueOf: function () { return test_object; } } }).data == test_object is false
+PASS new MessageEvent('eventType', { get data() { return 123; } }).data is 123
+PASS new MessageEvent('eventType', { get data() { throw 'MessageEvent Error'; } }) threw exception MessageEvent Error.
+PASS new MessageEvent('eventType', { origin: 'melancholy' }).origin is "melancholy"
+PASS new MessageEvent('eventType', { origin: '' }).origin is ""
+PASS new MessageEvent('eventType', { origin: undefined }).origin is "undefined"
+PASS new MessageEvent('eventType', { origin: null }).origin is "null"
+PASS new MessageEvent('eventType', { origin: false }).origin is "false"
+PASS new MessageEvent('eventType', { origin: true }).origin is "true"
+PASS new MessageEvent('eventType', { origin: 12345 }).origin is "12345"
+PASS new MessageEvent('eventType', { origin: 18446744073709551615 }).origin is "18446744073709552000"
+PASS new MessageEvent('eventType', { origin: NaN }).origin is "NaN"
+PASS new MessageEvent('eventType', { origin: [] }).origin is ""
+PASS new MessageEvent('eventType', { origin: [1, 2, 3] }).origin is "1,2,3"
+PASS new MessageEvent('eventType', { origin: {melancholy: 12345} }).origin is "[object Object]"
+PASS new MessageEvent('eventType', { origin: {valueOf: function () { return 'melancholy'; } } }).origin is "[object Object]"
+PASS new MessageEvent('eventType', { get origin() { return 123; } }).origin is "123"
+PASS new MessageEvent('eventType', { get origin() { throw 'MessageEvent Error'; } }) threw exception MessageEvent Error.
+PASS new MessageEvent('eventType', { lastEventId: 'melancholy' }).lastEventId is "melancholy"
+PASS new MessageEvent('eventType', { lastEventId: '' }).lastEventId is ""
+PASS new MessageEvent('eventType', { lastEventId: undefined }).lastEventId is "undefined"
+PASS new MessageEvent('eventType', { lastEventId: null }).lastEventId is "null"
+PASS new MessageEvent('eventType', { lastEventId: false }).lastEventId is "false"
+PASS new MessageEvent('eventType', { lastEventId: true }).lastEventId is "true"
+PASS new MessageEvent('eventType', { lastEventId: 12345 }).lastEventId is "12345"
+PASS new MessageEvent('eventType', { lastEventId: 18446744073709551615 }).lastEventId is "18446744073709552000"
+PASS new MessageEvent('eventType', { lastEventId: NaN }).lastEventId is "NaN"
+PASS new MessageEvent('eventType', { lastEventId: [] }).lastEventId is ""
+PASS new MessageEvent('eventType', { lastEventId: [1, 2, 3] }).lastEventId is "1,2,3"
+PASS new MessageEvent('eventType', { lastEventId: {melancholy: 12345} }).lastEventId is "[object Object]"
+PASS new MessageEvent('eventType', { lastEventId: {valueOf: function () { return 'melancholy'; } } }).lastEventId is "[object Object]"
+PASS new MessageEvent('eventType', { get lastEventId() { return 123; } }).lastEventId is "123"
+PASS new MessageEvent('eventType', { get lastEventId() { throw 'MessageEvent Error'; } }) threw exception MessageEvent Error.
+PASS new MessageEvent('eventType', { source: window }).source is window
+PASS new MessageEvent('eventType', { source: this }).source is this
+PASS new MessageEvent('eventType', { source: test_object }).source is null
+PASS new MessageEvent('eventType', { source: document }).source is null
+PASS new MessageEvent('eventType', { source: undefined }).source is null
+PASS new MessageEvent('eventType', { source: null }).source is null
+PASS new MessageEvent('eventType', { source: false }).source is null
+PASS new MessageEvent('eventType', { source: true }).source is null
+PASS new MessageEvent('eventType', { source: '' }).source is null
+PASS new MessageEvent('eventType', { source: 'chocolate' }).source is null
+PASS new MessageEvent('eventType', { source: 12345 }).source is null
+PASS new MessageEvent('eventType', { source: 18446744073709551615 }).source is null
+PASS new MessageEvent('eventType', { source: NaN }).source is null
+PASS new MessageEvent('eventType', { source: {valueOf: function () { return window; } } }).source == window is false
+PASS new MessageEvent('eventType', { get source() { return 123; } }).source is null
+PASS new MessageEvent('eventType', { get source() { throw 'MessageEvent Error'; } }) threw exception MessageEvent Error.
+PASS new MessageEvent('eventType', { ports: [channel.port1, channel.port2, channel.port2] }).ports[0] is channel.port1
+PASS new MessageEvent('eventType', { ports: [channel.port1, channel.port2, channel.port2] }).ports[1] is channel.port2
+PASS new MessageEvent('eventType', { ports: [channel.port1, channel.port2, channel.port2] }).ports[2] is channel.port2
+PASS new MessageEvent('eventType', { ports: [] }).ports is []
+PASS new MessageEvent('eventType', { ports: undefined }).ports is []
+PASS new MessageEvent('eventType', { ports: null }).ports is []
+PASS new MessageEvent('eventType', { ports: [1, 2, 3] }).ports[2] threw exception TypeError: Type error.
+PASS new MessageEvent('eventType', { ports: test_object }).ports threw exception TypeError: Type error.
+PASS new MessageEvent('eventType', { ports: document }).ports threw exception TypeError: Type error.
+PASS new MessageEvent('eventType', { ports: false }).ports threw exception TypeError: Type error.
+PASS new MessageEvent('eventType', { ports: true }).ports threw exception TypeError: Type error.
+PASS new MessageEvent('eventType', { ports: '' }).ports threw exception TypeError: Type error.
+PASS new MessageEvent('eventType', { ports: 'chocolate' }).ports threw exception TypeError: Type error.
+PASS new MessageEvent('eventType', { ports: 12345 }).ports threw exception TypeError: Type error.
+PASS new MessageEvent('eventType', { ports: 18446744073709551615 }).ports threw exception TypeError: Type error.
+PASS new MessageEvent('eventType', { ports: NaN }).ports threw exception TypeError: Type error.
+PASS new MessageEvent('eventType', { get ports() { return 123; } }).ports threw exception TypeError: Type error.
+PASS new MessageEvent('eventType', { get ports() { throw 'MessageEvent Error'; } }) threw exception MessageEvent Error.
+PASS new MessageEvent('eventType', { ports: {valueOf: function () { return [channel.port1, channel.port2, channel.port2]; } } }).ports[0] threw exception TypeError: Type error.
+PASS 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
+PASS 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
+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].
+PASS 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"
+PASS 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"
+PASS new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel.port2] }).source is window
+PASS new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel.port2] }).ports[0] is channel.port1
+PASS new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel.port2] }).ports[1] is channel.port2
+PASS new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel.port2] }).ports[2] is channel.port2
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/events/constructors/message-event-constructor.html (0 => 96179)


--- trunk/LayoutTests/fast/events/constructors/message-event-constructor.html	                        (rev 0)
+++ trunk/LayoutTests/fast/events/constructors/message-event-constructor.html	2011-09-28 02:02:18 UTC (rev 96179)
@@ -0,0 +1,138 @@
+<!DOCTYPE html>
+<html>
+<head>
+<link rel="stylesheet" href=""
+<script src=""
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+
+description("This tests the constructor for the MessageEvent DOM class.");
+
+var test_object = {nyannyan: 123};
+
+// No initializer is passed.
+shouldBe("new MessageEvent('eventType').bubbles", "false");
+shouldBe("new MessageEvent('eventType').cancelable", "false");
+shouldBe("new MessageEvent('eventType').data", "null");
+shouldBeEqualToString("new MessageEvent('eventType').origin", "");
+shouldBeEqualToString("new MessageEvent('eventType').lastEventId", "");
+shouldBe("new MessageEvent('eventType').source", "null");
+shouldBe("new MessageEvent('eventType').ports", "[]");
+
+// bubbles is passed.
+shouldBe("new MessageEvent('eventType', { bubbles: false }).bubbles", "false");
+shouldBe("new MessageEvent('eventType', { bubbles: true }).bubbles", "true");
+
+// cancelable is passed.
+shouldBe("new MessageEvent('eventType', { cancelable: false }).cancelable", "false");
+shouldBe("new MessageEvent('eventType', { cancelable: true }).cancelable", "true");
+
+// data is passed.
+// FIXME(haraken): This fails because MessageEvent.data cannot handle ScriptValue.
+shouldBe("new MessageEvent('eventType', { data: test_object }).data", "test_object");
+// FIXME(haraken): When we pass a DOM object, it crashes in DRT (it returns TypeError in non-DRT build).
+// shouldBe("new MessageEvent('eventType', { data: document }).data", "document");
+shouldBe("new MessageEvent('eventType', { data: undefined }).data", "undefined");
+shouldBe("new MessageEvent('eventType', { data: null }).data", "null");
+shouldBe("new MessageEvent('eventType', { data: false }).data", "false");
+shouldBe("new MessageEvent('eventType', { data: true }).data", "true");
+shouldBeEqualToString("new MessageEvent('eventType', { data: '' }).data", "");
+shouldBeEqualToString("new MessageEvent('eventType', { data: 'chocolate' }).data", "chocolate");
+shouldBe("new MessageEvent('eventType', { data: 12345 }).data", "12345");
+shouldBe("new MessageEvent('eventType', { data: 18446744073709551615 }).data", "18446744073709552000");
+shouldBe("new MessageEvent('eventType', { data: NaN }).data", "NaN");
+// Note that valueOf() is not called, when the left hand side is evaluated.
+shouldBeFalse("new MessageEvent('eventType', { data: {valueOf: function () { return test_object; } } }).data == test_object");
+shouldBe("new MessageEvent('eventType', { get data() { return 123; } }).data", "123");
+shouldThrow("new MessageEvent('eventType', { get data() { throw 'MessageEvent Error'; } })");
+
+// origin or lastEventId is passed.
+["origin", "lastEventId"].forEach(function (attr) {
+    // Strings.
+    shouldBeEqualToString("new MessageEvent('eventType', { " + attr + ": 'melancholy' })." + attr, "melancholy");
+    shouldBeEqualToString("new MessageEvent('eventType', { " + attr + ": '' })." + attr, "");
+
+    // Non-strings.
+    shouldBeEqualToString("new MessageEvent('eventType', { " + attr + ": undefined })." + attr, "undefined");
+    shouldBeEqualToString("new MessageEvent('eventType', { " + attr + ": null })." + attr, "null");
+    shouldBeEqualToString("new MessageEvent('eventType', { " + attr + ": false })." + attr, "false");
+    shouldBeEqualToString("new MessageEvent('eventType', { " + attr + ": true })." + attr, "true");
+    shouldBeEqualToString("new MessageEvent('eventType', { " + attr + ": 12345 })." + attr, "12345");
+    shouldBeEqualToString("new MessageEvent('eventType', { " + attr + ": 18446744073709551615 })." + attr, "18446744073709552000");
+    shouldBeEqualToString("new MessageEvent('eventType', { " + attr + ": NaN })." + attr, "NaN");
+    shouldBeEqualToString("new MessageEvent('eventType', { " + attr + ": [] })." + attr, "");
+    shouldBeEqualToString("new MessageEvent('eventType', { " + attr + ": [1, 2, 3] })." + attr, "1,2,3");
+    shouldBeEqualToString("new MessageEvent('eventType', { " + attr + ": {melancholy: 12345} })." + attr, "[object Object]");
+    shouldBeEqualToString("new MessageEvent('eventType', { " + attr + ": {valueOf: function () { return 'melancholy'; } } })." + attr, "[object Object]");
+    shouldBeEqualToString("new MessageEvent('eventType', { get " + attr + "() { return 123; } })." + attr, "123");
+    shouldThrow("new MessageEvent('eventType', { get " + attr + "() { throw 'MessageEvent Error'; } })");
+});
+
+// source is passed.
+// Window objects.
+shouldBe("new MessageEvent('eventType', { source: window }).source", "window");
+shouldBe("new MessageEvent('eventType', { source: this }).source", "this");
+
+// Non-window objects.
+shouldBe("new MessageEvent('eventType', { source: test_object }).source", "null");
+shouldBe("new MessageEvent('eventType', { source: document }).source", "null");
+shouldBe("new MessageEvent('eventType', { source: undefined }).source", "null");
+shouldBe("new MessageEvent('eventType', { source: null }).source", "null");
+shouldBe("new MessageEvent('eventType', { source: false }).source", "null");
+shouldBe("new MessageEvent('eventType', { source: true }).source", "null");
+shouldBe("new MessageEvent('eventType', { source: '' }).source", "null");
+shouldBe("new MessageEvent('eventType', { source: 'chocolate' }).source", "null");
+shouldBe("new MessageEvent('eventType', { source: 12345 }).source", "null");
+shouldBe("new MessageEvent('eventType', { source: 18446744073709551615 }).source", "null");
+shouldBe("new MessageEvent('eventType', { source: NaN }).source", "null");
+// Note that valueOf() is not called, when the left hand side is evaluated.
+shouldBeFalse("new MessageEvent('eventType', { source: {valueOf: function () { return window; } } }).source == window");
+shouldBe("new MessageEvent('eventType', { get source() { return 123; } }).source", "null");
+shouldThrow("new MessageEvent('eventType', { get source() { throw 'MessageEvent Error'; } })");
+
+// ports is passed.
+// Valid message ports.
+var channel = new MessageChannel();
+shouldBe("new MessageEvent('eventType', { ports: [channel.port1, channel.port2, channel.port2] }).ports[0]", "channel.port1");
+shouldBe("new MessageEvent('eventType', { ports: [channel.port1, channel.port2, channel.port2] }).ports[1]", "channel.port2");
+shouldBe("new MessageEvent('eventType', { ports: [channel.port1, channel.port2, channel.port2] }).ports[2]", "channel.port2");
+shouldBe("new MessageEvent('eventType', { ports: [] }).ports", "[]");
+shouldBe("new MessageEvent('eventType', { ports: undefined }).ports", "[]");
+shouldBe("new MessageEvent('eventType', { ports: null }).ports", "[]");
+
+// Invalid message ports.
+shouldThrow("new MessageEvent('eventType', { ports: [1, 2, 3] }).ports[2]");
+shouldThrow("new MessageEvent('eventType', { ports: test_object }).ports");
+shouldThrow("new MessageEvent('eventType', { ports: document }).ports");
+shouldThrow("new MessageEvent('eventType', { ports: false }).ports");
+shouldThrow("new MessageEvent('eventType', { ports: true }).ports");
+shouldThrow("new MessageEvent('eventType', { ports: '' }).ports");
+shouldThrow("new MessageEvent('eventType', { ports: 'chocolate' }).ports");
+shouldThrow("new MessageEvent('eventType', { ports: 12345 }).ports");
+shouldThrow("new MessageEvent('eventType', { ports: 18446744073709551615 }).ports");
+shouldThrow("new MessageEvent('eventType', { ports: NaN }).ports");
+shouldThrow("new MessageEvent('eventType', { get ports() { return 123; } }).ports");
+shouldThrow("new MessageEvent('eventType', { get ports() { throw 'MessageEvent Error'; } })");
+// Note that valueOf() is not called, when the left hand side is evaluated.
+shouldThrow("new MessageEvent('eventType', { ports: {valueOf: function () { return [channel.port1, channel.port2, channel.port2]; } } }).ports[0]");
+
+// All initializers are passed.
+shouldBe("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");
+shouldBe("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");
+// FIXME(haraken): This fails because MessageEvent.data cannot handle ScriptValue.
+shouldBe("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");
+shouldBeEqualToString("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");
+shouldBeEqualToString("new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel.port2] }).lastEventId", "excellent");
+shouldBe("new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel.port2] }).source", "window");
+shouldBe("new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel.port2] }).ports[0]", "channel.port1");
+shouldBe("new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel.port2] }).ports[1]", "channel.port2");
+shouldBe("new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel.port2] }).ports[2]", "channel.port2");
+
+var successfullyParsed = true;
+</script>
+<script src=""
+</body>
+</html>

Modified: trunk/LayoutTests/platform/chromium/test_expectations.txt (96178 => 96179)


--- trunk/LayoutTests/platform/chromium/test_expectations.txt	2011-09-28 01:52:21 UTC (rev 96178)
+++ trunk/LayoutTests/platform/chromium/test_expectations.txt	2011-09-28 02:02:18 UTC (rev 96179)
@@ -81,6 +81,9 @@
 BUGWK60877 SKIP : loader/navigation-while-deferring-loads.html = FAIL
 BUGWK60877 SKIP : loader/load-defer-resume-crash.html = FAIL
 
+// This will soon be fixed after implementing a MessageEvent constructor for V8.
+BUGWK68883 : fast/events/constructors/message-event-constructor.html = FAIL
+
 // CSS3 Selectors3 test suite
 BUGCR89468 : css3/selectors3 = PASS FAIL
 

Modified: trunk/Source/WebCore/ChangeLog (96178 => 96179)


--- trunk/Source/WebCore/ChangeLog	2011-09-28 01:52:21 UTC (rev 96178)
+++ trunk/Source/WebCore/ChangeLog	2011-09-28 02:02:18 UTC (rev 96179)
@@ -1,3 +1,45 @@
+2011-09-27  Kentaro Hara  <[email protected]>
+
+        Implement a MessageEvent constructor for JSC
+        https://bugs.webkit.org/show_bug.cgi?id=68883
+
+        Reviewed by Adam Barth.
+
+        The spec for MessageEvent is here:
+        http://www.whatwg.org/specs/web-apps/current-work/#messageevent
+
+        Currently, some tests in fast/events/constructors/message-event-constructor.html
+        are failing or crashing in DRT, as we commented in the test file.
+        This is because MessageEvent.data is implemented as SerializedScriptValue,
+        and thus it cannot keep ScriptValue passed by _javascript_.
+        This is the same issue as the bug (https://bugs.webkit.org/show_bug.cgi?id=68345).
+        We will soon make a follow-up patch to fix these failures, after this
+        patch is landed.
+
+        Test: fast/events/constructors/message-event-constructor.html
+
+        * bindings/generic/EventConstructors.h: Added a definition for the MessageEvent constructor.
+        * bindings/js/JSDictionary.cpp:
+        (WebCore::JSDictionary::convertValue): Generates MessagePortArray from the list of message ports in the format of JSValues.
+        * bindings/js/JSDictionary.h:
+        * bindings/js/JSEventConstructors.cpp: Added #includes for MessageEvent.
+        * dom/MessageEvent.cpp:
+        (WebCore::MessageEventInit::MessageEventInit):
+        (WebCore::MessageEvent::MessageEvent):
+        (WebCore::MessageEvent::initMessageEvent):
+        * dom/MessageEvent.h: Added a definition for MessageEvent. Removed an extra leading spaces.
+        (WebCore::MessageEvent::create):
+        (WebCore::MessageEvent::origin):
+        (WebCore::MessageEvent::lastEventId):
+        (WebCore::MessageEvent::source):
+        (WebCore::MessageEvent::ports):
+        (WebCore::MessageEvent::dataType):
+        (WebCore::MessageEvent::dataAsSerializedScriptValue):
+        (WebCore::MessageEvent::dataAsString):
+        (WebCore::MessageEvent::dataAsBlob):
+        (WebCore::MessageEvent::dataAsArrayBuffer):
+        * dom/MessageEvent.idl: Makes MessageEvent constructible.
+
 2011-09-27  Eric Uhrhane  <[email protected]>
 
         [Chromium/FileWriter] race condition in FileWriter completion can lead to assert

Modified: trunk/Source/WebCore/bindings/generic/EventConstructors.h (96178 => 96179)


--- trunk/Source/WebCore/bindings/generic/EventConstructors.h	2011-09-28 01:52:21 UTC (rev 96178)
+++ trunk/Source/WebCore/bindings/generic/EventConstructors.h	2011-09-28 02:02:18 UTC (rev 96179)
@@ -99,7 +99,18 @@
         FILL_PROPERTY(reason) \
     DICTIONARY_END(CloseEvent)
 
+#define INSTANTIATE_INITIALIZING_CONSTRUCTOR_FOR_MESSAGE_EVENT(DICTIONARY_START, DICTIONARY_END, FILL_PARENT_PROPERTIES, FILL_PROPERTY) \
+    \
+    DICTIONARY_START(MessageEvent) \
+        FILL_PARENT_PROPERTIES(Event) \
+        FILL_PROPERTY(data) \
+        FILL_PROPERTY(origin) \
+        FILL_PROPERTY(lastEventId) \
+        FILL_PROPERTY(source) \
+        FILL_PROPERTY(ports) \
+    DICTIONARY_END(MessageEvent)
 
+
 #define INSTANTIATE_ALL_EVENT_INITIALIZING_CONSTRUCTORS(DICTIONARY_START, DICTIONARY_END, FILL_PARENT_PROPERTIES, FILL_PROPERTY) \
     INSTANTIATE_INITIALIZING_CONSTRUCTOR_FOR_EVENT(DICTIONARY_START, DICTIONARY_END, FILL_PARENT_PROPERTIES, FILL_PROPERTY) \
     INSTANTIATE_INITIALIZING_CONSTRUCTOR_FOR_CUSTOM_EVENT(DICTIONARY_START, DICTIONARY_END, FILL_PARENT_PROPERTIES, FILL_PROPERTY) \
@@ -110,6 +121,7 @@
     INSTANTIATE_INITIALIZING_CONSTRUCTOR_FOR_POP_STATE_EVENT(DICTIONARY_START, DICTIONARY_END, FILL_PARENT_PROPERTIES, FILL_PROPERTY) \
     INSTANTIATE_INITIALIZING_CONSTRUCTOR_FOR_ERROR_EVENT(DICTIONARY_START, DICTIONARY_END, FILL_PARENT_PROPERTIES, FILL_PROPERTY) \
     INSTANTIATE_INITIALIZING_CONSTRUCTOR_FOR_CLOSE_EVENT(DICTIONARY_START, DICTIONARY_END, FILL_PARENT_PROPERTIES, FILL_PROPERTY) \
+    INSTANTIATE_INITIALIZING_CONSTRUCTOR_FOR_MESSAGE_EVENT(DICTIONARY_START, DICTIONARY_END, FILL_PARENT_PROPERTIES, FILL_PROPERTY) \
 
 } // namespace WebCore
 

Modified: trunk/Source/WebCore/bindings/js/JSDictionary.cpp (96178 => 96179)


--- trunk/Source/WebCore/bindings/js/JSDictionary.cpp	2011-09-28 01:52:21 UTC (rev 96178)
+++ trunk/Source/WebCore/bindings/js/JSDictionary.cpp	2011-09-28 02:02:18 UTC (rev 96179)
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (C) 2011 Apple Inc. All rights reserved.
  *
@@ -29,6 +28,7 @@
 
 #include "JSDOMWindow.h"
 #include "JSEventTarget.h"
+#include "JSMessagePortCustom.h"
 #include "JSNode.h"
 #include "SerializedScriptValue.h"
 #include "ScriptValue.h"
@@ -119,4 +119,9 @@
     result = toNode(value);
 }
 
+void JSDictionary::convertValue(ExecState* exec, JSValue value, MessagePortArray& result)
+{
+    fillMessagePortArray(exec, value, result);
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/bindings/js/JSDictionary.h (96178 => 96179)


--- trunk/Source/WebCore/bindings/js/JSDictionary.h	2011-09-28 01:52:21 UTC (rev 96178)
+++ trunk/Source/WebCore/bindings/js/JSDictionary.h	2011-09-28 02:02:18 UTC (rev 96179)
@@ -26,6 +26,7 @@
 #ifndef JSDictionary_h
 #define JSDictionary_h
 
+#include "MessagePort.h"
 #include <interpreter/CallFrame.h>
 #include <wtf/Forward.h>
 
@@ -71,6 +72,7 @@
     static void convertValue(JSC::ExecState*, JSC::JSValue, RefPtr<DOMWindow>& result);
     static void convertValue(JSC::ExecState*, JSC::JSValue, RefPtr<EventTarget>& result);
     static void convertValue(JSC::ExecState*, JSC::JSValue, RefPtr<Node>& result);
+    static void convertValue(JSC::ExecState*, JSC::JSValue, MessagePortArray& result);
 
     JSC::ExecState* m_exec;
     JSC::JSObject* m_initializerObject;

Modified: trunk/Source/WebCore/bindings/js/JSEventConstructors.cpp (96178 => 96179)


--- trunk/Source/WebCore/bindings/js/JSEventConstructors.cpp	2011-09-28 01:52:21 UTC (rev 96178)
+++ trunk/Source/WebCore/bindings/js/JSEventConstructors.cpp	2011-09-28 02:02:18 UTC (rev 96179)
@@ -37,10 +37,12 @@
 #include "JSErrorEvent.h"
 #include "JSEvent.h"
 #include "JSHashChangeEvent.h"
+#include "JSMessageEvent.h"
 #include "JSPageTransitionEvent.h"
 #include "JSPopStateEvent.h"
 #include "JSProgressEvent.h"
 #include "JSWebKitAnimationEvent.h"
+#include "MessageEvent.h"
 #include "PageTransitionEvent.h"
 #include "PopStateEvent.h"
 #include "ProgressEvent.h"

Modified: trunk/Source/WebCore/dom/MessageEvent.cpp (96178 => 96179)


--- trunk/Source/WebCore/dom/MessageEvent.cpp	2011-09-28 01:52:21 UTC (rev 96178)
+++ trunk/Source/WebCore/dom/MessageEvent.cpp	2011-09-28 02:02:18 UTC (rev 96179)
@@ -33,12 +33,28 @@
 
 namespace WebCore {
 
+MessageEventInit::MessageEventInit()
+    : data(SerializedScriptValue::create())
+{
+}
+
 MessageEvent::MessageEvent()
     : m_dataType(DataTypeSerializedScriptValue)
     , m_dataAsSerializedScriptValue(SerializedScriptValue::create())
 {
 }
 
+MessageEvent::MessageEvent(const AtomicString& type, const MessageEventInit& initializer)
+    : Event(type, initializer)
+    , m_dataType(DataTypeSerializedScriptValue)
+    , m_dataAsSerializedScriptValue(initializer.data)
+    , m_origin(initializer.origin)
+    , m_lastEventId(initializer.lastEventId)
+    , m_source(initializer.source)
+    , m_ports(adoptPtr(new MessagePortArray(initializer.ports)))
+{
+}
+
 MessageEvent::MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortArray> ports)
     : Event(eventNames().messageEvent, false, false)
     , m_dataType(DataTypeSerializedScriptValue)
@@ -85,7 +101,7 @@
 {
     if (dispatched())
         return;
-        
+
     initEvent(type, canBubble, cancelable);
 
     m_dataType = DataTypeSerializedScriptValue;

Modified: trunk/Source/WebCore/dom/MessageEvent.h (96178 => 96179)


--- trunk/Source/WebCore/dom/MessageEvent.h	2011-09-28 01:52:21 UTC (rev 96178)
+++ trunk/Source/WebCore/dom/MessageEvent.h	2011-09-28 02:02:18 UTC (rev 96179)
@@ -37,79 +37,95 @@
 
 namespace WebCore {
 
-    class DOMWindow;
+class DOMWindow;
 
-    class MessageEvent : public Event {
-    public:
-        static PassRefPtr<MessageEvent> create()
-        {
-            return adoptRef(new MessageEvent);
-        }
-        static PassRefPtr<MessageEvent> create(PassOwnPtr<MessagePortArray> ports, PassRefPtr<SerializedScriptValue> data = "" const String& origin = "", const String& lastEventId = "", PassRefPtr<DOMWindow> source = 0)
-        {
-            return adoptRef(new MessageEvent(data, origin, lastEventId, source, ports));
-        }
-        static PassRefPtr<MessageEvent> create(const String& data)
-        {
-            return adoptRef(new MessageEvent(data));
-        }
-        static PassRefPtr<MessageEvent> create(PassRefPtr<Blob> data)
-        {
-            return adoptRef(new MessageEvent(data));
-        }
-        static PassRefPtr<MessageEvent> create(PassRefPtr<ArrayBuffer> data)
-        {
-            return adoptRef(new MessageEvent(data));
-        }
-        virtual ~MessageEvent();
+struct MessageEventInit : public EventInit {
+    MessageEventInit();
 
-        void initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, DOMWindow* source, PassOwnPtr<MessagePortArray>);
+    RefPtr<SerializedScriptValue> data;
+    String origin;
+    String lastEventId;
+    RefPtr<DOMWindow> source;
+    MessagePortArray ports;
+};
 
-        const String& origin() const { return m_origin; }
-        const String& lastEventId() const { return m_lastEventId; }
-        DOMWindow* source() const { return m_source.get(); }
-        MessagePortArray* ports() const { return m_ports.get(); }
+class MessageEvent : public Event {
+public:
+    static PassRefPtr<MessageEvent> create()
+    {
+        return adoptRef(new MessageEvent);
+    }
+    static PassRefPtr<MessageEvent> create(PassOwnPtr<MessagePortArray> ports, PassRefPtr<SerializedScriptValue> data = "" const String& origin = "", const String& lastEventId = "", PassRefPtr<DOMWindow> source = 0)
+    {
+        return adoptRef(new MessageEvent(data, origin, lastEventId, source, ports));
+    }
+    static PassRefPtr<MessageEvent> create(const String& data)
+    {
+        return adoptRef(new MessageEvent(data));
+    }
+    static PassRefPtr<MessageEvent> create(PassRefPtr<Blob> data)
+    {
+        return adoptRef(new MessageEvent(data));
+    }
+    static PassRefPtr<MessageEvent> create(PassRefPtr<ArrayBuffer> data)
+    {
+        return adoptRef(new MessageEvent(data));
+    }
+    static PassRefPtr<MessageEvent> create(const AtomicString& type, const MessageEventInit& initializer)
+    {
+        return adoptRef(new MessageEvent(type, initializer));
+    }
+    virtual ~MessageEvent();
 
-        // FIXME: Remove this when we have custom ObjC binding support.
-        SerializedScriptValue* data() const;
+    void initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, DOMWindow* source, PassOwnPtr<MessagePortArray>);
 
-        // FIXME: remove this when we update the ObjC bindings (bug #28774).
-        MessagePort* messagePort();
-        // FIXME: remove this when we update the ObjC bindings (bug #28774).
-        void initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, DOMWindow* source, MessagePort*);
+    const String& origin() const { return m_origin; }
+    const String& lastEventId() const { return m_lastEventId; }
+    DOMWindow* source() const { return m_source.get(); }
+    MessagePortArray* ports() const { return m_ports.get(); }
 
-        virtual bool isMessageEvent() const;
+    // FIXME: Remove this when we have custom ObjC binding support.
+    SerializedScriptValue* data() const;
 
-        enum DataType {
-            DataTypeSerializedScriptValue,
-            DataTypeString,
-            DataTypeBlob,
-            DataTypeArrayBuffer
-        };
-        DataType dataType() const { return m_dataType; }
-        SerializedScriptValue* dataAsSerializedScriptValue() const { return m_dataAsSerializedScriptValue.get(); }
-        String dataAsString() const { return m_dataAsString; }
-        Blob* dataAsBlob() const { return m_dataAsBlob.get(); }
-        ArrayBuffer* dataAsArrayBuffer() const { return m_dataAsArrayBuffer.get(); }
+    // FIXME: remove this when we update the ObjC bindings (bug #28774).
+    MessagePort* messagePort();
+    // FIXME: remove this when we update the ObjC bindings (bug #28774).
+    void initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, DOMWindow* source, MessagePort*);
 
-    private:
-        MessageEvent();
-        MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortArray>);
-        explicit MessageEvent(const String& data);
-        explicit MessageEvent(PassRefPtr<Blob> data);
-        explicit MessageEvent(PassRefPtr<ArrayBuffer> data);
+    virtual bool isMessageEvent() const;
 
-        DataType m_dataType;
-        RefPtr<SerializedScriptValue> m_dataAsSerializedScriptValue;
-        String m_dataAsString;
-        RefPtr<Blob> m_dataAsBlob;
-        RefPtr<ArrayBuffer> m_dataAsArrayBuffer;
-        String m_origin;
-        String m_lastEventId;
-        RefPtr<DOMWindow> m_source;
-        OwnPtr<MessagePortArray> m_ports;
+    enum DataType {
+        DataTypeSerializedScriptValue,
+        DataTypeString,
+        DataTypeBlob,
+        DataTypeArrayBuffer
     };
+    DataType dataType() const { return m_dataType; }
+    SerializedScriptValue* dataAsSerializedScriptValue() const { return m_dataAsSerializedScriptValue.get(); }
+    String dataAsString() const { return m_dataAsString; }
+    Blob* dataAsBlob() const { return m_dataAsBlob.get(); }
+    ArrayBuffer* dataAsArrayBuffer() const { return m_dataAsArrayBuffer.get(); }
 
+private:
+    MessageEvent();
+    MessageEvent(const AtomicString&, const MessageEventInit&);
+    MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortArray>);
+
+    explicit MessageEvent(const String& data);
+    explicit MessageEvent(PassRefPtr<Blob> data);
+    explicit MessageEvent(PassRefPtr<ArrayBuffer> data);
+
+    DataType m_dataType;
+    RefPtr<SerializedScriptValue> m_dataAsSerializedScriptValue;
+    String m_dataAsString;
+    RefPtr<Blob> m_dataAsBlob;
+    RefPtr<ArrayBuffer> m_dataAsArrayBuffer;
+    String m_origin;
+    String m_lastEventId;
+    RefPtr<DOMWindow> m_source;
+    OwnPtr<MessagePortArray> m_ports;
+};
+
 } // namespace WebCore
 
 #endif // MessageEvent_h

Modified: trunk/Source/WebCore/dom/MessageEvent.idl (96178 => 96179)


--- trunk/Source/WebCore/dom/MessageEvent.idl	2011-09-28 01:52:21 UTC (rev 96178)
+++ trunk/Source/WebCore/dom/MessageEvent.idl	2011-09-28 02:02:18 UTC (rev 96179)
@@ -28,7 +28,9 @@
 module events {
 
     interface [
-        NoStaticTables
+        NoStaticTables,
+        CanBeConstructed,
+        CustomConstructFunction
     ] MessageEvent : Event {
         readonly attribute DOMString origin;
         readonly attribute DOMString lastEventId;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to