Commit a4654257 authored by ch.dumez@sisa.samsung.com's avatar ch.dumez@sisa.samsung.com
Browse files

Set MessageEvent.source to the newly created port for shared workers' connect events

https://bugs.webkit.org/show_bug.cgi?id=121390

Reviewed by Darin Adler.

Source/WebCore:

Set MessageEvent.source to the newly created port for shared workers' connect events
instead of previously null, as per the latest specification:
http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#dom-messageevent-source
http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#dom-sharedworker

This behavior is consisent with Blink.

Test: fast/workers/shared-worker-messageevent-source.html

* dom/EventTarget.cpp:
(WebCore::EventTarget::isMessagePort):
* dom/EventTarget.h:
* dom/MessageEvent.cpp:
(WebCore::isValidSource):
(WebCore::MessageEvent::MessageEvent):
* dom/MessageEvent.h:
Use null String instead of an empty String as default value for origin and lastEventId.
This is more efficient and has no impact on the behavior on the JavaScript since a
null String is exposed as an empty one on JS side.
This change is covered by fast/events/constructors/message-event-constructor.html
* dom/MessageEvent.idl:
* dom/MessagePort.h:
* page/DOMWindow.cpp:
(WebCore::PostMessageTimer::event):
* workers/SharedWorkerGlobalScope.cpp:
(WebCore::createConnectEvent):

LayoutTests:

Add layout test to check that MessageEvent.source is set to the newly created port
for shared workers' connect events.

* fast/events/constructors/message-event-constructor-expected.txt:
* fast/events/constructors/message-event-constructor.html:
* fast/workers/resources/messageevent-source.js: Added.
(onconnect):
* fast/workers/shared-worker-messageevent-source-expected.txt: Added.
* fast/workers/shared-worker-messageevent-source.html: Added.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@155959 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 8a5da120
2013-09-17 Christophe Dumez <ch.dumez@sisa.samsung.com>
Set MessageEvent.source to the newly created port for shared workers' connect events
https://bugs.webkit.org/show_bug.cgi?id=121390
Reviewed by Darin Adler.
Add layout test to check that MessageEvent.source is set to the newly created port
for shared workers' connect events.
* fast/events/constructors/message-event-constructor-expected.txt:
* fast/events/constructors/message-event-constructor.html:
* fast/workers/resources/messageevent-source.js: Added.
(onconnect):
* fast/workers/shared-worker-messageevent-source-expected.txt: Added.
* fast/workers/shared-worker-messageevent-source.html: Added.
2013-09-17 Antti Koivisto <antti@apple.com>
 
RenderBR should not be RenderText
......@@ -60,8 +60,10 @@ PASS new MessageEvent('eventType', { get lastEventId() { return 123; } }).lastEv
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', { ports: [channel.port1], source: channel.port1 }).source is channel.port1
PASS new MessageEvent('eventType', { source: test_object }).source is null
PASS new MessageEvent('eventType', { source: document }).source is null
PASS new MessageEvent('eventType', { source: document.body }).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
......
......@@ -71,9 +71,14 @@ shouldThrow("new MessageEvent('eventType', { get data() { throw 'MessageEvent Er
shouldBe("new MessageEvent('eventType', { source: window }).source", "window");
shouldBe("new MessageEvent('eventType', { source: this }).source", "this");
// Non-window objects.
// MessagePort objects.
var channel = new MessageChannel();
shouldBe("new MessageEvent('eventType', { ports: [channel.port1], source: channel.port1 }).source", "channel.port1");
// Unacceptable source objects (not a Window or a MessagePort).
shouldBe("new MessageEvent('eventType', { source: test_object }).source", "null");
shouldBe("new MessageEvent('eventType', { source: document }).source", "null");
shouldBe("new MessageEvent('eventType', { source: document.body }).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");
......@@ -90,7 +95,6 @@ shouldThrow("new MessageEvent('eventType', { get source() { throw 'MessageEvent
// ports is passed.
// Valid message ports.
var channel = new MessageChannel();
var channel2 = new MessageChannel();
shouldBe("new MessageEvent('eventType', { ports: [channel.port1, channel.port2, channel2.port1] }).ports[0]", "channel.port1");
shouldBe("new MessageEvent('eventType', { ports: [channel.port1, channel.port2, channel2.port1] }).ports[1]", "channel.port2");
......
onconnect = function(event) {
if (event.__proto__ === MessageEvent.prototype)
event.ports[0].postMessage("PASS: event.__proto__ is MessageEvent.prototype");
else
event.ports[0].postMessage("FAIL: event.__proto__ is not MessageEvent.prototype");
if (event.source === event.ports[0])
event.ports[0].postMessage("PASS: event.source is event.ports[0]");
else
event.ports[0].postMessage("FAIL: event.source is not event.ports[0]");
event.ports[0].postMessage("DONE:");
};
Make sure that MessageEvent.source is properly set in connect event.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
Starting worker: resources/messageevent-source.js
PASS [Worker] event.__proto__ is MessageEvent.prototype
PASS [Worker] event.source is event.ports[0]
PASS successfullyParsed is true
TEST COMPLETE
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
</head>
<body>
<script>
description("Make sure that MessageEvent.source is properly set in connect event.");
startWorker("resources/messageevent-source.js", true);
</script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
2013-09-17 Christophe Dumez <ch.dumez@sisa.samsung.com>
Set MessageEvent.source to the newly created port for shared workers' connect events
https://bugs.webkit.org/show_bug.cgi?id=121390
Reviewed by Darin Adler.
Set MessageEvent.source to the newly created port for shared workers' connect events
instead of previously null, as per the latest specification:
http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#dom-messageevent-source
http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#dom-sharedworker
This behavior is consisent with Blink.
Test: fast/workers/shared-worker-messageevent-source.html
* dom/EventTarget.cpp:
(WebCore::EventTarget::isMessagePort):
* dom/EventTarget.h:
* dom/MessageEvent.cpp:
(WebCore::isValidSource):
(WebCore::MessageEvent::MessageEvent):
* dom/MessageEvent.h:
Use null String instead of an empty String as default value for origin and lastEventId.
This is more efficient and has no impact on the behavior on the JavaScript since a
null String is exposed as an empty one on JS side.
This change is covered by fast/events/constructors/message-event-constructor.html
* dom/MessageEvent.idl:
* dom/MessagePort.h:
* page/DOMWindow.cpp:
(WebCore::PostMessageTimer::event):
* workers/SharedWorkerGlobalScope.cpp:
(WebCore::createConnectEvent):
2013-09-17 Antti Koivisto <antti@apple.com>
 
RenderBR should not be RenderText
......@@ -68,6 +68,11 @@ DOMWindow* EventTarget::toDOMWindow()
return 0;
}
bool EventTarget::isMessagePort() const
{
return false;
}
bool EventTarget::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
{
return ensureEventTargetData().eventListenerMap.add(eventType, listener, useCapture);
......
......@@ -111,6 +111,7 @@ namespace WebCore {
virtual Node* toNode();
virtual DOMWindow* toDOMWindow();
virtual bool isMessagePort() const;
virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
......
......@@ -33,6 +33,11 @@
namespace WebCore {
static inline bool isValidSource(EventTarget* source)
{
return !source || source->toDOMWindow() || source->isMessagePort();
}
MessageEventInit::MessageEventInit()
{
}
......@@ -48,12 +53,12 @@ MessageEvent::MessageEvent(const AtomicString& type, const MessageEventInit& ini
, m_dataAsScriptValue(initializer.data)
, m_origin(initializer.origin)
, m_lastEventId(initializer.lastEventId)
, m_source(initializer.source)
, m_source(isValidSource(initializer.source.get()) ? initializer.source : 0)
, m_ports(adoptPtr(new MessagePortArray(initializer.ports)))
{
}
MessageEvent::MessageEvent(const ScriptValue& data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortArray> ports)
MessageEvent::MessageEvent(const ScriptValue& data, const String& origin, const String& lastEventId, PassRefPtr<EventTarget> source, PassOwnPtr<MessagePortArray> ports)
: Event(eventNames().messageEvent, false, false)
, m_dataType(DataTypeScriptValue)
, m_dataAsScriptValue(data)
......@@ -62,9 +67,10 @@ MessageEvent::MessageEvent(const ScriptValue& data, const String& origin, const
, m_source(source)
, m_ports(ports)
{
ASSERT(isValidSource(m_source.get()));
}
MessageEvent::MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortArray> ports)
MessageEvent::MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtr<EventTarget> source, PassOwnPtr<MessagePortArray> ports)
: Event(eventNames().messageEvent, false, false)
, m_dataType(DataTypeSerializedScriptValue)
, m_dataAsSerializedScriptValue(data)
......@@ -73,6 +79,7 @@ MessageEvent::MessageEvent(PassRefPtr<SerializedScriptValue> data, const String&
, m_source(source)
, m_ports(ports)
{
ASSERT(isValidSource(m_source.get()));
}
MessageEvent::MessageEvent(const String& data, const String& origin)
......@@ -80,7 +87,6 @@ MessageEvent::MessageEvent(const String& data, const String& origin)
, m_dataType(DataTypeString)
, m_dataAsString(data)
, m_origin(origin)
, m_lastEventId("")
{
}
......@@ -89,7 +95,6 @@ MessageEvent::MessageEvent(PassRefPtr<Blob> data, const String& origin)
, m_dataType(DataTypeBlob)
, m_dataAsBlob(data)
, m_origin(origin)
, m_lastEventId("")
{
}
......@@ -98,7 +103,6 @@ MessageEvent::MessageEvent(PassRefPtr<ArrayBuffer> data, const String& origin)
, m_dataType(DataTypeArrayBuffer)
, m_dataAsArrayBuffer(data)
, m_origin(origin)
, m_lastEventId("")
{
}
......
......@@ -38,7 +38,7 @@
namespace WebCore {
class DOMWindow;
class EventTarget;
struct MessageEventInit : public EventInit {
MessageEventInit();
......@@ -46,7 +46,7 @@ struct MessageEventInit : public EventInit {
ScriptValue data;
String origin;
String lastEventId;
RefPtr<DOMWindow> source;
RefPtr<EventTarget> source;
MessagePortArray ports;
};
......@@ -56,23 +56,23 @@ public:
{
return adoptRef(new MessageEvent);
}
static PassRefPtr<MessageEvent> create(PassOwnPtr<MessagePortArray> ports, const ScriptValue& data = ScriptValue(), const String& origin = "", const String& lastEventId = "", PassRefPtr<DOMWindow> source = 0)
static PassRefPtr<MessageEvent> create(PassOwnPtr<MessagePortArray> ports, const ScriptValue& data = ScriptValue(), const String& origin = String(), const String& lastEventId = String(), PassRefPtr<EventTarget> source = 0)
{
return adoptRef(new MessageEvent(data, origin, lastEventId, source, ports));
}
static PassRefPtr<MessageEvent> create(PassOwnPtr<MessagePortArray> ports, PassRefPtr<SerializedScriptValue> data, const String& origin = "", const String& lastEventId = "", PassRefPtr<DOMWindow> source = 0)
static PassRefPtr<MessageEvent> create(PassOwnPtr<MessagePortArray> ports, PassRefPtr<SerializedScriptValue> data, const String& origin = String(), const String& lastEventId = String(), PassRefPtr<EventTarget> source = 0)
{
return adoptRef(new MessageEvent(data, origin, lastEventId, source, ports));
}
static PassRefPtr<MessageEvent> create(const String& data, const String& origin = "")
static PassRefPtr<MessageEvent> create(const String& data, const String& origin = String())
{
return adoptRef(new MessageEvent(data, origin));
}
static PassRefPtr<MessageEvent> create(PassRefPtr<Blob> data, const String& origin = "")
static PassRefPtr<MessageEvent> create(PassRefPtr<Blob> data, const String& origin = String())
{
return adoptRef(new MessageEvent(data, origin));
}
static PassRefPtr<MessageEvent> create(PassRefPtr<ArrayBuffer> data, const String& origin = "")
static PassRefPtr<MessageEvent> create(PassRefPtr<ArrayBuffer> data, const String& origin = String())
{
return adoptRef(new MessageEvent(data, origin));
}
......@@ -87,7 +87,7 @@ public:
const String& origin() const { return m_origin; }
const String& lastEventId() const { return m_lastEventId; }
DOMWindow* source() const { return m_source.get(); }
EventTarget* source() const { return m_source.get(); }
MessagePortArray ports() const { return m_ports ? *m_ports : MessagePortArray(); }
// FIXME: Remove this when we have custom ObjC binding support.
......@@ -116,8 +116,8 @@ public:
private:
MessageEvent();
MessageEvent(const AtomicString&, const MessageEventInit&);
MessageEvent(const ScriptValue& data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortArray>);
MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortArray>);
MessageEvent(const ScriptValue& data, const String& origin, const String& lastEventId, PassRefPtr<EventTarget> source, PassOwnPtr<MessagePortArray>);
MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtr<EventTarget> source, PassOwnPtr<MessagePortArray>);
explicit MessageEvent(const String& data, const String& origin);
explicit MessageEvent(PassRefPtr<Blob> data, const String& origin);
......@@ -131,7 +131,7 @@ private:
RefPtr<ArrayBuffer> m_dataAsArrayBuffer;
String m_origin;
String m_lastEventId;
RefPtr<DOMWindow> m_source;
RefPtr<EventTarget> m_source;
OwnPtr<MessagePortArray> m_ports;
};
......
......@@ -32,7 +32,7 @@
] interface MessageEvent : Event {
[InitializedByEventConstructor] readonly attribute DOMString origin;
[InitializedByEventConstructor] readonly attribute DOMString lastEventId;
[InitializedByEventConstructor] readonly attribute DOMWindow source;
[InitializedByEventConstructor] readonly attribute EventTarget source; // May be a DOMWindow or a MessagePort.
#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
[InitializedByEventConstructor, CachedAttribute, CustomGetter] readonly attribute any data;
[InitializedByEventConstructor] readonly attribute MessagePort[] ports;
......
......@@ -75,6 +75,7 @@ namespace WebCore {
virtual const AtomicString& interfaceName() const OVERRIDE;
virtual ScriptExecutionContext* scriptExecutionContext() const OVERRIDE;
virtual bool isMessagePort() const OVERRIDE FINAL { return true; }
void dispatchMessages();
......
......@@ -138,7 +138,7 @@ public:
PassRefPtr<MessageEvent> event(ScriptExecutionContext* context)
{
OwnPtr<MessagePortArray> messagePorts = MessagePort::entanglePorts(*context, m_channels.release());
return MessageEvent::create(messagePorts.release(), m_message, m_origin, "", m_source);
return MessageEvent::create(messagePorts.release(), m_message, m_origin, String(), m_source);
}
SecurityOrigin* targetOrigin() const { return m_targetOrigin.get(); }
ScriptCallStack* stackTrace() const { return m_stackTrace.get(); }
......
......@@ -44,9 +44,10 @@
namespace WebCore {
PassRefPtr<MessageEvent> createConnectEvent(PassRefPtr<MessagePort> port)
PassRefPtr<MessageEvent> createConnectEvent(PassRefPtr<MessagePort> prpPort)
{
RefPtr<MessageEvent> event = MessageEvent::create(adoptPtr(new MessagePortArray(1, port)));
RefPtr<MessagePort> port = prpPort;
RefPtr<MessageEvent> event = MessageEvent::create(adoptPtr(new MessagePortArray(1, port)), ScriptValue(), String(), String(), port);
event->initEvent(eventNames().connectEvent, false, false);
return event.release();
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment