Reviewed by Sam Weinig, Anders Carlsson, and (unofficially) Adam Barth.
authorap@webkit.org <ap@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Sep 2008 10:15:11 +0000 (10:15 +0000)
committerap@webkit.org <ap@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Sep 2008 10:15:11 +0000 (10:15 +0000)
        https://bugs.webkit.org/show_bug.cgi?id=20879
        Implement HTML5 channel messaging

        Tests: fast/events/message-channel-gc.html
               fast/events/message-port-deleted-document.html
               fast/events/message-port-deleted-frame.html
               fast/events/message-port-inactive-document.html
               fast/events/message-port.html
               http/tests/security/MessagePort/event-listener-context.html

        * Configurations/WebCore.xcconfig:
        Removed unused  ENABLE_CROSS_DOCUMENT_MESSAGING macro.

        * DerivedSources.make:
        Added MessageChannel and MessagePort.

        * WebCore.pro: Made MessageEvent compilation unconditional, as it could not possibly be
        turmed off anyway. Added new files.

        * GNUmakefile.am:
        * WebCore.pro:
        * WebCore.vcproj/WebCore.vcproj:
        * WebCore.xcodeproj/project.pbxproj:
        * WebCoreSources.bkl:
        Added new files.

        * bindings/js/JSDOMWindowBase.h:
        * bindings/js/JSDOMWindowBase.cpp: (WebCore::JSDOMWindowBase::getValueProperty):
        Added suport for window.MessageChannel constructor.

        * bindings/js/JSDOMWindowCustom.cpp: (WebCore::JSDOMWindow::postMessage):
        * page/DOMWindow.cpp:
        (WebCore::DOMWindow::postMessage):
        * page/DOMWindow.h:
        * page/DOMWindow.idl:
        Added support for three-argument postMessage (that posts a MessagePort).

        * dom/EventTarget.cpp:
        (WebCore::EventTarget::toMessagePort):
        * dom/EventTarget.h:
        * bindings/js/JSEventTargetBase.cpp: (WebCore::toJS): Added MessagePort as yet another
        EventTarget variant.

        * bindings/js/JSMessageChannelConstructor.h:
        * bindings/js/JSMessageChannelConstructor.cpp: Added a custom constructor, so that it could
        take a browsing context (document) parameter.

        * bindings/js/JSMessageChannelCustom.cpp: Added.
        (WebCore::JSMessageChannel::mark): JSMessageChannel uses a custom mark function to mark
        port1 and port2 that it owns.

        * bindings/js/JSMessagePortCustom.cpp: Added.
        (WebCore::JSMessagePort::startConversation):
        (WebCore::JSMessagePort::addEventListener):
        (WebCore::JSMessagePort::removeEventListener):
        (WebCore::JSMessagePort::dispatchEvent):
        (WebCore::JSMessagePort::setOnmessage):
        (WebCore::JSMessagePort::onmessage):
        (WebCore::JSMessagePort::setOnclose):
        (WebCore::JSMessagePort::onclose):
        (WebCore::JSMessagePort::mark):
        * dom/MessagePort.cpp: Added.
        * dom/MessagePort.h: Added.
        * dom/MessagePort.idl: Added.
        Added a MessagePort implementation. Currently, it is not thread-safe at all, and only works
        with Documents as contexts, but in the future, it will be used for communication with worker
        threads.

        * bindings/objc/DOMInternal.h: Include "DOMMessagePortInternal.h". The new APIs do not
        really have Obj-C bindings, as they are far from being final, but a MessagePort stub is
        needed for MessageEvent.

        * bindings/scripts/CodeGeneratorJS.pm: Include PlatformString.h for MessagePort happiness.

        * dom/Document.cpp:
        (WebCore::MessagePortTimer::MessagePortTimer):
        (WebCore::MessagePortTimer::fired):
        (WebCore::Document::processMessagePortMessagesSoon):
        (WebCore::Document::~Document):
        (WebCore::Document::dispatchMessagePortEvents):
        (WebCore::Document::createdMessagePort):
        (WebCore::Document::destroyedMessagePort):
        * dom/Document.h:
        Document keeps track of all MessagePort objects that were created when it was fully active
        in its context.

        * dom/EventNames.h: Added closeEvent.

        * dom/MessageChannel.cpp: Added.
        (WebCore::MessageChannel::MessageChannel):
        (WebCore::MessageChannel::~MessageChannel):
        * dom/MessageChannel.h: Added.
        (WebCore::MessageChannel::create):
        (WebCore::MessageChannel::port1):
        (WebCore::MessageChannel::port2):
        * dom/MessageChannel.idl: Added.
        Addded JSMessageChannel implementation.

        * dom/MessageEvent.cpp:
        (WebCore::MessageEvent::MessageEvent):
        (WebCore::MessageEvent::initMessageEvent):
        * dom/MessageEvent.h:
        (WebCore::MessageEvent::create):
        (WebCore::MessageEvent::messagePort):
        * dom/MessageEvent.idl:
        MessageEvent has a MessagePort member now, making it possible to pass ports across
        documents.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@36891 268f45cc-cd09-0410-ab3c-d52691b4dbfc

53 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/dom/Window/window-properties-expected.txt
LayoutTests/fast/events/message-channel-gc-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/message-channel-gc.html [new file with mode: 0644]
LayoutTests/fast/events/message-port-deleted-document-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/message-port-deleted-document.html [new file with mode: 0644]
LayoutTests/fast/events/message-port-deleted-frame-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/message-port-deleted-frame.html [new file with mode: 0644]
LayoutTests/fast/events/message-port-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/message-port-inactive-document-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/message-port-inactive-document.html [new file with mode: 0644]
LayoutTests/fast/events/message-port.html [new file with mode: 0644]
LayoutTests/fast/events/resources/message-port-iframe.html [new file with mode: 0644]
LayoutTests/http/tests/security/MessagePort/event-listener-context-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/MessagePort/event-listener-context.html [new file with mode: 0644]
LayoutTests/http/tests/security/MessagePort/resources/attacker-frame.html [new file with mode: 0644]
LayoutTests/http/tests/security/MessagePort/resources/banking-site.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/Configurations/WebCore.xcconfig
WebCore/DerivedSources.cpp
WebCore/DerivedSources.make
WebCore/GNUmakefile.am
WebCore/WebCore.pro
WebCore/WebCore.vcproj/WebCore.vcproj
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/WebCoreSources.bkl
WebCore/bindings/js/JSDOMWindowBase.cpp
WebCore/bindings/js/JSDOMWindowBase.h
WebCore/bindings/js/JSDOMWindowCustom.cpp
WebCore/bindings/js/JSEventTargetBase.cpp
WebCore/bindings/js/JSMessageChannelConstructor.cpp [new file with mode: 0644]
WebCore/bindings/js/JSMessageChannelConstructor.h [new file with mode: 0644]
WebCore/bindings/js/JSMessageChannelCustom.cpp [new file with mode: 0644]
WebCore/bindings/js/JSMessagePortCustom.cpp [new file with mode: 0644]
WebCore/bindings/objc/DOMInternal.h
WebCore/bindings/scripts/CodeGeneratorJS.pm
WebCore/dom/Document.cpp
WebCore/dom/Document.h
WebCore/dom/EventNames.h
WebCore/dom/EventTarget.cpp
WebCore/dom/EventTarget.h
WebCore/dom/MessageChannel.cpp [new file with mode: 0644]
WebCore/dom/MessageChannel.h [new file with mode: 0644]
WebCore/dom/MessageChannel.idl [new file with mode: 0644]
WebCore/dom/MessageEvent.cpp
WebCore/dom/MessageEvent.h
WebCore/dom/MessageEvent.idl
WebCore/dom/MessagePort.cpp [new file with mode: 0644]
WebCore/dom/MessagePort.h [new file with mode: 0644]
WebCore/dom/MessagePort.idl [new file with mode: 0644]
WebCore/page/DOMWindow.cpp
WebCore/page/DOMWindow.h
WebCore/page/DOMWindow.idl

index e606570..c3f566a 100644 (file)
@@ -1,3 +1,29 @@
+2008-09-24  Alexey Proskuryakov  <ap@webkit.org>
+
+        Reviewed by Sam Weinig, Anders Carlsson, and (unofficially) Adam Barth.
+
+        https://bugs.webkit.org/show_bug.cgi?id=20879
+        Implement HTML5 channel messaging
+
+        * fast/dom/Window/window-properties-expected.txt:
+        * fast/events/message-channel-gc-expected.txt: Added.
+        * fast/events/message-channel-gc.html: Added.
+        * fast/events/message-port-deleted-document-expected.txt: Added.
+        * fast/events/message-port-deleted-document.html: Added.
+        * fast/events/message-port-deleted-frame-expected.txt: Added.
+        * fast/events/message-port-deleted-frame.html: Added.
+        * fast/events/message-port-expected.txt: Added.
+        * fast/events/message-port-inactive-document-expected.txt: Added.
+        * fast/events/message-port-inactive-document.html: Added.
+        * fast/events/message-port.html: Added.
+        * fast/events/resources/message-port-iframe.html: Added.
+        * http/tests/security/MessagePort: Added.
+        * http/tests/security/MessagePort/event-listener-context-expected.txt: Added.
+        * http/tests/security/MessagePort/event-listener-context.html: Added.
+        * http/tests/security/MessagePort/resources: Added.
+        * http/tests/security/MessagePort/resources/attacker-frame.html: Added.
+        * http/tests/security/MessagePort/resources/banking-site.html: Added.
+
 2008-09-25  David Smith  <catfish.man@gmail.com>
 
         Reviewed by Eric Seidel
index eec3b61..1cd836b 100644 (file)
@@ -901,6 +901,8 @@ window.MediaList.prototype [object MediaListPrototype]
 window.MediaList.prototype.appendMedium [function]
 window.MediaList.prototype.deleteMedium [function]
 window.MediaList.prototype.item [function]
+window.MessageChannel [object MessageChannelConstructor]
+window.MessageChannel.prototype [object MessageChannelPrototype]
 window.MessageEvent [object MessageEventConstructor]
 window.MessageEvent.prototype [printed above as window.Event.prototype]
 window.MouseEvent [object MouseEventConstructor]
diff --git a/LayoutTests/fast/events/message-channel-gc-expected.txt b/LayoutTests/fast/events/message-channel-gc-expected.txt
new file mode 100644 (file)
index 0000000..54c75e0
--- /dev/null
@@ -0,0 +1,8 @@
+Test some cases of MessagePort garbage collection.
+
+Should be 'bar': bar
+onmessage
+message listener
+onclose
+close listener
+
diff --git a/LayoutTests/fast/events/message-channel-gc.html b/LayoutTests/fast/events/message-channel-gc.html
new file mode 100644 (file)
index 0000000..5e49e9d
--- /dev/null
@@ -0,0 +1,46 @@
+<body>
+<p>Test some cases of MessagePort garbage collection.</p>
+<pre id=log></pre>
+<script>
+function gc()
+{
+    if (window.GCController)
+        return GCController.collect();
+
+    for (var i = 0; i < 10000; i++) { // > force garbage collection (FF requires about 9K allocations before a collect)
+        var s = new String("abc");
+    }
+}
+
+function log(message)
+{
+    document.getElementById("log").innerHTML += message + "<br>";
+}
+
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.waitUntilDone();
+}
+
+var channel = new MessageChannel;
+channel.port1.foo = "bar";
+
+gc();
+log("Should be 'bar': " + channel.port1.foo);
+
+channel.port1.onmessage = function() { log("onmessage"); }
+channel.port1.onclose = function() { log("onclose"); setTimeout(function() { if (window.layoutTestController) layoutTestController.notifyDone() }, 0) }
+channel.port1.addEventListener("close", function() { log("close listener"); }, false);
+channel.port1.addEventListener("message", function() { log("message listener"); }, false);
+
+gc();
+channel.port1.start();
+channel.port2.postMessage("msg");
+
+gc();
+channel.port1.close();
+channel.port2.close();
+
+gc();
+</script>
+</body>
diff --git a/LayoutTests/fast/events/message-port-deleted-document-expected.txt b/LayoutTests/fast/events/message-port-deleted-document-expected.txt
new file mode 100644 (file)
index 0000000..5c24d88
--- /dev/null
@@ -0,0 +1,4 @@
+Test that destroying a document doesn't cause a crash when posting a message to a MessagePort it owned.
+
+Didn't crash: SUCCESS
+
diff --git a/LayoutTests/fast/events/message-port-deleted-document.html b/LayoutTests/fast/events/message-port-deleted-document.html
new file mode 100644 (file)
index 0000000..c1e2e07
--- /dev/null
@@ -0,0 +1,71 @@
+<body>
+<p>Test that destroying a document doesn't cause a crash when posting a message to a MessagePort it owned.</p>
+<pre id=log></pre>
+<script>
+function gc()
+{
+    if (window.GCController)
+        return GCController.collect();
+
+    for (var i = 0; i < 10000; i++) { // > force garbage collection (FF requires about 9K allocations before a collect)
+        var s = new String("abc");
+    }
+}
+
+function log(message)
+{
+    document.getElementById("log").innerHTML += message + "<br>";
+}
+
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.waitUntilDone();
+}
+
+var mainPort;
+
+function test()
+{
+    var channel = new MessageChannel;
+    window.frames[0].postMessage("msg", channel.port2, "*");
+    mainPort = channel.port1;
+    mainPort.start();
+
+    mainPort.postMessage("ping");
+    mainPort.onmessage = test2;
+}
+
+function test2()
+{
+    var frameElement = document.getElementsByTagName("iframe")[0];
+    frameElement.parentNode.removeChild(frameElement);
+    frameElement = null;
+
+    gc();
+    setTimeout(test3, 10);
+}
+
+function test3()
+{
+    gc();
+    mainPort.postMessage("ping");
+    mainPort.onmessage = function(evt) {
+        if (evt.data == "pong")
+            log("Unexpected response: FAIL");
+    };
+    setTimeout(test4, 10);
+}
+
+function test4()
+{
+    mainPort.close();
+
+    log("Didn't crash: SUCCESS");
+
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+
+</script>
+<iframe src="resources/message-port-iframe.html" onload="test()"></iframe>
+</body>
diff --git a/LayoutTests/fast/events/message-port-deleted-frame-expected.txt b/LayoutTests/fast/events/message-port-deleted-frame-expected.txt
new file mode 100644 (file)
index 0000000..25e190a
--- /dev/null
@@ -0,0 +1,4 @@
+Test that destroying a frame doesn't cause a crash when posting a message to a MessagePort it owned.
+
+Didn't crash: SUCCESS
+
diff --git a/LayoutTests/fast/events/message-port-deleted-frame.html b/LayoutTests/fast/events/message-port-deleted-frame.html
new file mode 100644 (file)
index 0000000..69fa2b3
--- /dev/null
@@ -0,0 +1,71 @@
+<body>
+<p>Test that destroying a frame doesn't cause a crash when posting a message to a MessagePort it owned.</p>
+<pre id=log></pre>
+<script>
+function gc()
+{
+    if (window.GCController)
+        return GCController.collect();
+
+    for (var i = 0; i < 10000; i++) { // > force garbage collection (FF requires about 9K allocations before a collect)
+        var s = new String("abc");
+    }
+}
+
+function log(message)
+{
+    document.getElementById("log").innerHTML += message + "<br>";
+}
+
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.waitUntilDone();
+}
+
+var mainPort;
+var frameDoc;
+
+function test()
+{
+    frameDoc = window.frames[0].document;
+    var channel = new MessageChannel;
+    window.frames[0].postMessage("msg", channel.port2, "*");
+    mainPort = channel.port1;
+    mainPort.start();
+
+    mainPort.postMessage("ping");
+    mainPort.onmessage = test2;
+}
+
+function test2()
+{
+    var frameElement = document.getElementsByTagName("iframe")[0];
+    frameElement.parentNode.removeChild(frameElement);
+    frameElement = null;
+
+    gc();
+    setTimeout(test3, 10);
+}
+
+function test3()
+{
+    gc();
+    mainPort.postMessage("ping");
+    mainPort.onmessage = function(evt) {
+        if (evt.data == "pong")
+            log("Unexpected response: FAIL");
+    };
+    setTimeout(test4, 10);
+}
+
+function test4()
+{
+    log("Didn't crash: SUCCESS");
+
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+
+</script>
+<iframe src="resources/message-port-iframe.html" onload="test()"></iframe>
+</body>
diff --git a/LayoutTests/fast/events/message-port-expected.txt b/LayoutTests/fast/events/message-port-expected.txt
new file mode 100644 (file)
index 0000000..d74247e
--- /dev/null
@@ -0,0 +1,8 @@
+Test cross-frame MessagePort communication.
+
+Simple exchange: SUCCESS
+Posted port: SUCCESS
+Conversation: SUCCESS
+A port is active: SUCCESS
+A closed port is inactive: SUCCESS
+
diff --git a/LayoutTests/fast/events/message-port-inactive-document-expected.txt b/LayoutTests/fast/events/message-port-inactive-document-expected.txt
new file mode 100644 (file)
index 0000000..ecb4e30
--- /dev/null
@@ -0,0 +1,4 @@
+Test that messaging an inactive frameless document works as expected.
+
+Didn't crash, freeze or respond: SUCCESS
+
diff --git a/LayoutTests/fast/events/message-port-inactive-document.html b/LayoutTests/fast/events/message-port-inactive-document.html
new file mode 100644 (file)
index 0000000..b380624
--- /dev/null
@@ -0,0 +1,72 @@
+<body>
+<p>Test that messaging an inactive frameless document works as expected.</p>
+<pre id=log></pre>
+<script>
+function gc()
+{
+    if (window.GCController)
+        return GCController.collect();
+
+    for (var i = 0; i < 10000; i++) { // > force garbage collection (FF requires about 9K allocations before a collect)
+        var s = new String("abc");
+    }
+}
+
+function log(message)
+{
+    document.getElementById("log").innerHTML += message + "<br>";
+}
+
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.waitUntilDone();
+}
+
+var document;
+var mainPort;
+
+function test()
+{
+    document = window.frames[0].document;
+    var channel = new MessageChannel;
+    window.frames[0].postMessage("msg", channel.port2, "*");
+    mainPort = channel.port1;
+    mainPort.start();
+
+    mainPort.postMessage("ping");
+    mainPort.onmessage = test2;
+}
+
+function test2()
+{
+    var frameElement = document.getElementsByTagName("iframe")[0];
+    frameElement.src = "resources/window-opened.html";
+    frameElement.onload = test3;
+    gc();
+}
+
+function test3()
+{
+    gc();
+    mainPort.postMessage("alert FAIL: the document is inactive.");
+    mainPort.postMessage("freeze");
+    mainPort.postMessage("ping");
+    mainPort.onmessage = function(evt) {
+        log("Unexpected response: FAIL");
+    };
+    setTimeout(test4, 10);
+}
+
+function test4()
+{
+    mainPort.close();
+
+    log("Didn't crash, freeze or respond: SUCCESS");
+
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+
+</script>
+<iframe src="resources/message-port-iframe.html" onload="test()" width=0 height=0 frameborder=0></iframe>
+</body>
diff --git a/LayoutTests/fast/events/message-port.html b/LayoutTests/fast/events/message-port.html
new file mode 100644 (file)
index 0000000..e30b2e2
--- /dev/null
@@ -0,0 +1,74 @@
+<body>
+<p>Test cross-frame MessagePort communication.</p>
+<pre id=log></pre>
+<script>
+function log(message)
+{
+    document.getElementById("log").innerHTML += message + "<br>";
+}
+
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.waitUntilDone();
+}
+
+var mainPort;
+
+function test()
+{
+    var channel = new MessageChannel;
+    window.frames[0].postMessage("msg", channel.port2, "*");
+    mainPort = channel.port1;
+    mainPort.postMessage("ping");
+    mainPort.onmessage = function(evt) {
+        if (evt.data == "pong" && evt.origin == "")
+            log("Simple exchange: SUCCESS");
+        else
+            log("Simple exchange: FAIL. Got message '" + evt.data + "' from '" + evt.origin + "'.");
+    };
+    mainPort.start();
+    setTimeout(test2, 50);
+}
+
+function test2()
+{
+    var channel = new MessageChannel;
+    mainPort.postMessage("newPort", channel.port2);
+    channel.port1.onmessage = function(evt) {
+        if (evt.data == "yo" && evt.origin == "")
+            log("Posted port: SUCCESS");
+        else
+            log("Posted port: FAIL. Got message '" + evt.data + "' from '" + evt.origin + "'.");
+    };
+    channel.port1.start();
+    setTimeout(test3, 50);
+}
+
+function test3()
+{
+    var port = mainPort.startConversation("newConversation");
+    port.onmessage = function(evt) {
+        if (evt.data == "hey" && evt.origin == "")
+            log("Conversation: SUCCESS");
+        else
+            log("Conversation: FAIL. Got message '" + evt.data + "' from '" + evt.origin + "'.");
+    };
+    port.start();
+    setTimeout(test4, 50);
+}
+
+function test4()
+{
+    log("A port is active: " + (mainPort.active ? "SUCCESS" : "FAIL"));
+
+    mainPort.close();
+
+    log("A closed port is inactive: " + (mainPort.active ? "FAIL" : "SUCCESS"));
+
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+
+</script>
+<iframe src="resources/message-port-iframe.html" onload="test()"></iframe>
+</body>
diff --git a/LayoutTests/fast/events/resources/message-port-iframe.html b/LayoutTests/fast/events/resources/message-port-iframe.html
new file mode 100644 (file)
index 0000000..4946e8a
--- /dev/null
@@ -0,0 +1,24 @@
+<script>
+var port;
+function onMessage(evt) {
+    if (evt.data == "ping")
+        port.postMessage("pong");
+    else if (evt.data == "newPort")
+        evt.messagePort.postMessage("yo");
+    else if (evt.data == "newConversation")
+        if (evt.origin == "")
+            evt.messagePort.postMessage("hey");
+        else
+            alert("Incorrect security origin in conversation: '" + evt.origin + "'.");
+    else if (/alert.+/.test(evt.data))
+        alert(evt.data.substr(6));
+    else if (evt.data == "freeze")
+        while (1) {}
+}
+
+window.addEventListener("message", function(evt) {
+    port = evt.messagePort;
+    port.onmessage = onMessage;
+    port.start();
+}, false);
+</script>
diff --git a/LayoutTests/http/tests/security/MessagePort/event-listener-context-expected.txt b/LayoutTests/http/tests/security/MessagePort/event-listener-context-expected.txt
new file mode 100644 (file)
index 0000000..18c2e82
--- /dev/null
@@ -0,0 +1,4 @@
+Test that JS code cannot be planted into an unsuspecting subframe via MessagePort and navigation.
+
+PASS
+
diff --git a/LayoutTests/http/tests/security/MessagePort/event-listener-context.html b/LayoutTests/http/tests/security/MessagePort/event-listener-context.html
new file mode 100644 (file)
index 0000000..2484a1b
--- /dev/null
@@ -0,0 +1,46 @@
+<body>
+<p>Test that JS code cannot be planted into an unsuspecting subframe via MessagePort and navigation.</p>
+<pre id=log></pre>
+<script>
+function log(message)
+{
+    document.getElementById("log").innerHTML += message + "<br>";
+}
+
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.waitUntilDone();
+}
+
+var closure;
+var mainPort;
+var failed;
+
+function test()
+{
+    failed = false;
+    closure = window.frames[0].createClosure();
+    document.getElementsByTagName("iframe")[0].onload = test2;
+    window.frames[0].location = "resources/banking-site.html";
+}
+
+function test2()
+{
+    mainPort = closure();
+    mainPort.postMessage("ping");
+    mainPort.onmessage = function(evt) { if (/sensitive/.test(evt.data)) failed = true; }
+    mainPort.start();
+    setTimeout(test3, 100);
+}
+
+function test3()
+{
+    log(failed ? "FAIL" : "PASS");
+
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+
+</script>
+<iframe src="resources/attacker-frame.html" onload="test()"></iframe>
+</body>
diff --git a/LayoutTests/http/tests/security/MessagePort/resources/attacker-frame.html b/LayoutTests/http/tests/security/MessagePort/resources/attacker-frame.html
new file mode 100644 (file)
index 0000000..ae7cb03
--- /dev/null
@@ -0,0 +1,15 @@
+<script>
+
+window.createClosure = function() {
+    var MessageChannelConstructor = window.MessageChannel;
+    var channel;
+    return function() {
+        channel = new MessageChannelConstructor;
+        channel.port1.onmessage = function() { channel.port1.postMessage(document.body.innerHTML) }
+        channel.port1.addEventListener("message", function() { channel.port1.postMessage(document.body.innerHTML) }, false);
+        channel.port1.start();
+        return channel.port2;
+    }
+}
+</script>
+<p>Attacker iframe.</p>
diff --git a/LayoutTests/http/tests/security/MessagePort/resources/banking-site.html b/LayoutTests/http/tests/security/MessagePort/resources/banking-site.html
new file mode 100644 (file)
index 0000000..ae973fb
--- /dev/null
@@ -0,0 +1 @@
+<p>Highly sensitive information.</p>
index 5393ddb..3655fc5 100644 (file)
@@ -1,3 +1,115 @@
+2008-09-24  Alexey Proskuryakov  <ap@webkit.org>
+
+        Reviewed by Sam Weinig, Anders Carlsson, and (unofficially) Adam Barth.
+
+        https://bugs.webkit.org/show_bug.cgi?id=20879
+        Implement HTML5 channel messaging
+
+        Tests: fast/events/message-channel-gc.html
+               fast/events/message-port-deleted-document.html
+               fast/events/message-port-deleted-frame.html
+               fast/events/message-port-inactive-document.html
+               fast/events/message-port.html
+               http/tests/security/MessagePort/event-listener-context.html
+
+        * Configurations/WebCore.xcconfig:
+        Removed unused  ENABLE_CROSS_DOCUMENT_MESSAGING macro.
+
+        * DerivedSources.make:
+        Added MessageChannel and MessagePort.
+
+        * WebCore.pro: Made MessageEvent compilation unconditional, as it could not possibly be
+        turmed off anyway. Added new files.
+
+        * GNUmakefile.am:
+        * WebCore.pro:
+        * WebCore.vcproj/WebCore.vcproj:
+        * WebCore.xcodeproj/project.pbxproj:
+        * WebCoreSources.bkl:
+        Added new files.
+
+        * bindings/js/JSDOMWindowBase.h:
+        * bindings/js/JSDOMWindowBase.cpp: (WebCore::JSDOMWindowBase::getValueProperty):
+        Added suport for window.MessageChannel constructor.
+
+        * bindings/js/JSDOMWindowCustom.cpp: (WebCore::JSDOMWindow::postMessage):
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::postMessage):
+        * page/DOMWindow.h:
+        * page/DOMWindow.idl:
+        Added support for three-argument postMessage (that posts a MessagePort).
+
+        * dom/EventTarget.cpp:
+        (WebCore::EventTarget::toMessagePort):
+        * dom/EventTarget.h:
+        * bindings/js/JSEventTargetBase.cpp: (WebCore::toJS): Added MessagePort as yet another
+        EventTarget variant.
+
+        * bindings/js/JSMessageChannelConstructor.h:
+        * bindings/js/JSMessageChannelConstructor.cpp: Added a custom constructor, so that it could
+        take a browsing context (document) parameter.
+
+        * bindings/js/JSMessageChannelCustom.cpp: Added.
+        (WebCore::JSMessageChannel::mark): JSMessageChannel uses a custom mark function to mark
+        port1 and port2 that it owns.
+
+        * bindings/js/JSMessagePortCustom.cpp: Added.
+        (WebCore::JSMessagePort::startConversation):
+        (WebCore::JSMessagePort::addEventListener):
+        (WebCore::JSMessagePort::removeEventListener):
+        (WebCore::JSMessagePort::dispatchEvent):
+        (WebCore::JSMessagePort::setOnmessage):
+        (WebCore::JSMessagePort::onmessage):
+        (WebCore::JSMessagePort::setOnclose):
+        (WebCore::JSMessagePort::onclose):
+        (WebCore::JSMessagePort::mark):
+        * dom/MessagePort.cpp: Added.
+        * dom/MessagePort.h: Added.
+        * dom/MessagePort.idl: Added.
+        Added a MessagePort implementation. Currently, it is not thread-safe at all, and only works
+        with Documents as contexts, but in the future, it will be used for communication with worker
+        threads.
+
+        * bindings/objc/DOMInternal.h: Include "DOMMessagePortInternal.h". The new APIs do not
+        really have Obj-C bindings, as they are far from being final, but a MessagePort stub is
+        needed for MessageEvent.
+
+        * bindings/scripts/CodeGeneratorJS.pm: Include PlatformString.h for MessagePort happiness.
+
+        * dom/Document.cpp:
+        (WebCore::MessagePortTimer::MessagePortTimer):
+        (WebCore::MessagePortTimer::fired):
+        (WebCore::Document::processMessagePortMessagesSoon):
+        (WebCore::Document::~Document):
+        (WebCore::Document::dispatchMessagePortEvents):
+        (WebCore::Document::createdMessagePort):
+        (WebCore::Document::destroyedMessagePort):
+        * dom/Document.h:
+        Document keeps track of all MessagePort objects that were created when it was fully active
+        in its context.
+
+        * dom/EventNames.h: Added closeEvent.
+
+        * dom/MessageChannel.cpp: Added.
+        (WebCore::MessageChannel::MessageChannel):
+        (WebCore::MessageChannel::~MessageChannel):
+        * dom/MessageChannel.h: Added.
+        (WebCore::MessageChannel::create):
+        (WebCore::MessageChannel::port1):
+        (WebCore::MessageChannel::port2):
+        * dom/MessageChannel.idl: Added.
+        Addded JSMessageChannel implementation.
+
+        * dom/MessageEvent.cpp:
+        (WebCore::MessageEvent::MessageEvent):
+        (WebCore::MessageEvent::initMessageEvent):
+        * dom/MessageEvent.h:
+        (WebCore::MessageEvent::create):
+        (WebCore::MessageEvent::messagePort):
+        * dom/MessageEvent.idl:
+        MessageEvent has a MessagePort member now, making it possible to pass ports across
+        documents.
+
 2008-09-25  David Smith  <catfish.man@gmail.com>
 
         Reviewed by Eric Seidel
index e13bdd7..7907fba 100644 (file)
@@ -15,7 +15,7 @@ PRODUCT_NAME = WebCore;
 OTHER_LDFLAGS = -l$(SQLITE3_LIBRARY) -lobjc -sub_library libobjc -umbrella WebKit;
 
 // This needs to be kept sorted, and in sync with FEATURE_DEFINES in JavaScriptCore.xcconfig, WebKit.xcconfig and the default settings of build-webkit.
-FEATURE_DEFINES = ENABLE_CROSS_DOCUMENT_MESSAGING ENABLE_DATABASE ENABLE_DOM_STORAGE ENABLE_ICONDATABASE ENABLE_OFFLINE_WEB_APPLICATIONS ENABLE_SVG ENABLE_SVG_ANIMATION ENABLE_SVG_AS_IMAGE ENABLE_SVG_FONTS ENABLE_SVG_FOREIGN_OBJECT ENABLE_SVG_USE ENABLE_VIDEO ENABLE_XPATH ENABLE_XSLT;
+FEATURE_DEFINES = ENABLE_DATABASE ENABLE_DOM_STORAGE ENABLE_ICONDATABASE ENABLE_OFFLINE_WEB_APPLICATIONS ENABLE_SVG ENABLE_SVG_ANIMATION ENABLE_SVG_AS_IMAGE ENABLE_SVG_FONTS ENABLE_SVG_FOREIGN_OBJECT ENABLE_SVG_USE ENABLE_VIDEO ENABLE_XPATH ENABLE_XSLT;
 
 SQLITE3_LIBRARY = $(SQLITE3_LIBRARY_$(MAC_OS_X_VERSION_MAJOR));
 SQLITE3_LIBRARY_ = WebCoreSQLite3;
index b8b9529..77a6c89 100644 (file)
 #include "JSLocation.cpp"
 #include "JSMediaError.cpp"
 #include "JSMediaList.cpp"
+#include "JSMessageChannel.cpp"
 #include "JSMessageEvent.cpp"
+#include "JSMessagePort.cpp"
 #include "JSMimeType.cpp"
 #include "JSMimeTypeArray.cpp"
 #include "JSMouseEvent.cpp"
index 0927377..5539d76 100644 (file)
@@ -160,7 +160,9 @@ DOM_CLASSES = \
     Location \
     MediaError \
     MediaList \
+    MessageChannel \
     MessageEvent \
+    MessagePort \
     MimeType \
     MimeTypeArray \
     MouseEvent \
index f698b15..b7ea3d2 100644 (file)
@@ -282,8 +282,12 @@ webcore_built_sources += \
        DerivedSources/JSLocation.h \
        DerivedSources/JSMediaList.cpp \
        DerivedSources/JSMediaList.h \
+       DerivedSources/JSMessageChannel.cpp \
+       DerivedSources/JSMessageChannel.h \
        DerivedSources/JSMessageEvent.cpp \
        DerivedSources/JSMessageEvent.h \
+       DerivedSources/JSMessagePort.cpp \
+       DerivedSources/JSMessagePort.h \
        DerivedSources/JSMimeType.cpp \
        DerivedSources/JSMimeType.h \
        DerivedSources/JSMimeTypeArray.cpp \
@@ -406,7 +410,9 @@ IDL_BINDINGS +=  \
        WebCore/dom/Event.idl \
        WebCore/dom/EventException.idl \
        WebCore/dom/KeyboardEvent.idl \
+       WebCore/dom/MessageChannel.idl \
        WebCore/dom/MessageEvent.idl \
+       WebCore/dom/MessagePort.idl \
        WebCore/dom/MouseEvent.idl \
        WebCore/dom/MutationEvent.idl \
        WebCore/dom/NamedNodeMap.idl \
@@ -674,6 +680,10 @@ webcore_sources += \
        WebCore/bindings/js/JSJavaScriptCallFrameCustom.cpp \
        WebCore/bindings/js/JSLocationCustom.cpp \
        WebCore/bindings/js/JSLocationCustom.h \
+       WebCore/bindings/js/JSMessageChannelConstructor.cpp \
+       WebCore/bindings/js/JSMessageChannelConstructor.h \
+       WebCore/bindings/js/JSMessageChannelCustom.cpp \
+       WebCore/bindings/js/JSMessagePortCustom.cpp \
        WebCore/bindings/js/JSMimeTypeArrayCustom.cpp \
        WebCore/bindings/js/JSNSResolver.cpp \
        WebCore/bindings/js/JSNSResolver.h \
@@ -937,8 +947,12 @@ webcore_sources += \
        WebCore/dom/MappedAttribute.cpp \
        WebCore/dom/MappedAttribute.h \
        WebCore/dom/MappedAttributeEntry.h \
+       WebCore/dom/MessageChannel.cpp \
+       WebCore/dom/MessageChannel.h \
        WebCore/dom/MessageEvent.cpp \
        WebCore/dom/MessageEvent.h \
+       WebCore/dom/MessagePort.cpp \
+       WebCore/dom/MessagePort.h \
        WebCore/dom/MouseEvent.cpp \
        WebCore/dom/MouseEvent.h \
        WebCore/dom/MouseRelatedEvent.cpp \
index a4c089b..99731c1 100644 (file)
@@ -58,7 +58,6 @@ win32-g++ {
 }
 
 # Optional components (look for defs in config.h and included files!)
-!contains(DEFINES, ENABLE_CROSS_DOCUMENT_MESSAGING=.): DEFINES += ENABLE_CROSS_DOCUMENT_MESSAGING=1
 !contains(DEFINES, ENABLE_DASHBOARD_SUPPORT=.): DEFINES += ENABLE_DASHBOARD_SUPPORT=0
 !contains(DEFINES, ENABLE_DATABASE=.): DEFINES += ENABLE_DATABASE=1
 !contains(DEFINES, ENABLE_ICONDATABASE=.): DEFINES += ENABLE_ICONDATABASE=1
@@ -246,6 +245,9 @@ IDL_BINDINGS += \
 #    dom/EventTarget.idl \
     dom/KeyboardEvent.idl \
     dom/MouseEvent.idl \
+    dom/MessageChannel.idl \
+    dom/MessageEvent.idl \
+    dom/MessagePort.idl \
     dom/MutationEvent.idl \
     dom/NamedNodeMap.idl \
     dom/Node.idl \
@@ -419,6 +421,9 @@ SOURCES += \
     bindings/js/JSXSLTProcessorCustom.cpp \
     bindings/js/JSPluginCustom.cpp \
     bindings/js/JSPluginArrayCustom.cpp \
+    bindings/js/JSMessageChannelConstructor.cpp \
+    bindings/js/JSMessageChannelCustom.cpp \
+    bindings/js/JSMessagePortCustom.cpp \
     bindings/js/JSMimeTypeArrayCustom.cpp \
     bindings/js/JSDOMBinding.cpp \
     bindings/js/JSEventListener.cpp \
@@ -524,6 +529,9 @@ SOURCES += \
     dom/ExceptionCode.cpp \
     dom/KeyboardEvent.cpp \
     dom/MappedAttribute.cpp \
+    dom/MessageChannel.cpp \
+    dom/MessageEvent.cpp \
+    dom/MessagePort.cpp \
     dom/MouseEvent.cpp \
     dom/MouseRelatedEvent.cpp \
     dom/MutationEvent.cpp \
@@ -1122,16 +1130,6 @@ contains(DEFINES, ENABLE_NETSCAPE_PLUGIN_API=1) {
 
 }
 
-contains(DEFINES, ENABLE_CROSS_DOCUMENT_MESSAGING=1) {
-    FEATURE_DEFINES_JAVASCRIPT += ENABLE_CROSS_DOCUMENT_MESSAGING=1
-
-    SOURCES += \
-        dom/MessageEvent.cpp
-
-    IDL_BINDINGS += \
-        dom/MessageEvent.idl
-}
-
 contains(DEFINES, ENABLE_DASHBOARD_SUPPORT=0) {
     DASHBOARDSUPPORTCSSPROPERTIES -= $$PWD/css/DashboardSupportCSSPropertyNames.in
 }
index 3ca978c..d012f08 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="windows-1251"?>\r
 <VisualStudioProject\r
        ProjectType="Visual C++"\r
-       Version="8.00"\r
+       Version="8,00"\r
        Name="WebCore"\r
        ProjectGUID="{1C16337B-ACF3-4D03-AA90-851C5B5EADA6}"\r
        RootNamespace="WebCore"\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSMessageChannel.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSMessageEvent.h"\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSMessagePort.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSMimeType.h"\r
                                >\r
                        </File>\r
                                RelativePath="..\platform\ScrollTypes.h"\r
                                >\r
                        </File>\r
-                        <File\r
-                               RelativePath="..\platform\ScrollView.cpp"\r
-                               >\r
-                       </File>\r
                        <File\r
                                RelativePath="..\platform\ScrollView.h"\r
                                >\r
                                                </FileConfiguration>\r
                                        </File>\r
                                        <File\r
-                                               RelativePath="..\platform\network\cf\FormDataStreamCFNet.cpp"\r
+                                               RelativePath="..\platform\network\cf\DNSCFNet.cpp"\r
                                                >\r
                                                <FileConfiguration\r
                                                        Name="Debug_Cairo|Win32"\r
                                                </FileConfiguration>\r
                                        </File>\r
                                        <File\r
-                                               RelativePath="..\platform\network\cf\FormDataStreamCFNet.h"\r
+                                               RelativePath="..\platform\network\cf\FormDataStreamCFNet.cpp"\r
                                                >\r
                                                <FileConfiguration\r
                                                        Name="Debug_Cairo|Win32"\r
                                                        ExcludedFromBuild="true"\r
                                                        >\r
                                                        <Tool\r
-                                                               Name="VCCustomBuildTool"\r
+                                                               Name="VCCLCompilerTool"\r
                                                        />\r
                                                </FileConfiguration>\r
                                                <FileConfiguration\r
                                                        ExcludedFromBuild="true"\r
                                                        >\r
                                                        <Tool\r
-                                                               Name="VCCustomBuildTool"\r
+                                                               Name="VCCLCompilerTool"\r
                                                        />\r
                                                </FileConfiguration>\r
                                        </File>\r
                                        <File\r
-                                               RelativePath="..\platform\network\cf\ResourceError.h"\r
+                                               RelativePath="..\platform\network\cf\FormDataStreamCFNet.h"\r
                                                >\r
                                                <FileConfiguration\r
                                                        Name="Debug_Cairo|Win32"\r
                                                </FileConfiguration>\r
                                        </File>\r
                                        <File\r
-                                               RelativePath="..\platform\network\cf\ResourceErrorCF.cpp"\r
+                                               RelativePath="..\platform\network\cf\ResourceError.h"\r
                                                >\r
                                                <FileConfiguration\r
                                                        Name="Debug_Cairo|Win32"\r
                                                        ExcludedFromBuild="true"\r
                                                        >\r
                                                        <Tool\r
-                                                               Name="VCCLCompilerTool"\r
+                                                               Name="VCCustomBuildTool"\r
                                                        />\r
                                                </FileConfiguration>\r
                                                <FileConfiguration\r
                                                        ExcludedFromBuild="true"\r
                                                        >\r
                                                        <Tool\r
-                                                               Name="VCCLCompilerTool"\r
+                                                               Name="VCCustomBuildTool"\r
                                                        />\r
                                                </FileConfiguration>\r
                                        </File>\r
                                        <File\r
-                                               RelativePath="..\platform\network\cf\ResourceHandleCFNet.cpp"\r
+                                               RelativePath="..\platform\network\cf\ResourceErrorCF.cpp"\r
                                                >\r
                                                <FileConfiguration\r
                                                        Name="Debug_Cairo|Win32"\r
                                                </FileConfiguration>\r
                                        </File>\r
                                        <File\r
-                                               RelativePath="..\platform\network\cf\ResourceRequest.h"\r
+                                               RelativePath="..\platform\network\cf\ResourceHandleCFNet.cpp"\r
                                                >\r
                                                <FileConfiguration\r
                                                        Name="Debug_Cairo|Win32"\r
                                                        ExcludedFromBuild="true"\r
                                                        >\r
                                                        <Tool\r
-                                                               Name="VCCustomBuildTool"\r
+                                                               Name="VCCLCompilerTool"\r
                                                        />\r
                                                </FileConfiguration>\r
                                                <FileConfiguration\r
                                                        ExcludedFromBuild="true"\r
                                                        >\r
                                                        <Tool\r
-                                                               Name="VCCustomBuildTool"\r
+                                                               Name="VCCLCompilerTool"\r
                                                        />\r
                                                </FileConfiguration>\r
                                        </File>\r
                                        <File\r
-                                               RelativePath="..\platform\network\cf\ResourceRequestCFNet.cpp"\r
+                                               RelativePath="..\platform\network\cf\ResourceRequest.h"\r
                                                >\r
                                                <FileConfiguration\r
                                                        Name="Debug_Cairo|Win32"\r
                                                        ExcludedFromBuild="true"\r
                                                        >\r
                                                        <Tool\r
-                                                               Name="VCCLCompilerTool"\r
+                                                               Name="VCCustomBuildTool"\r
                                                        />\r
                                                </FileConfiguration>\r
                                                <FileConfiguration\r
                                                        ExcludedFromBuild="true"\r
                                                        >\r
                                                        <Tool\r
-                                                               Name="VCCLCompilerTool"\r
+                                                               Name="VCCustomBuildTool"\r
                                                        />\r
                                                </FileConfiguration>\r
                                        </File>\r
                                        <File\r
-                                               RelativePath="..\platform\network\cf\DNSCFNet.cpp"\r
+                                               RelativePath="..\platform\network\cf\ResourceRequestCFNet.cpp"\r
                                                >\r
                                                <FileConfiguration\r
                                                        Name="Debug_Cairo|Win32"\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath="..\dom\MessageChannel.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\dom\MessageChannel.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath="..\dom\MessageEvent.cpp"\r
                                >\r
                                <FileConfiguration\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath="..\dom\MessagePort.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\dom\MessagePort.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath="..\dom\MouseEvent.cpp"\r
                                >\r
                                <FileConfiguration\r
                                </FileConfiguration>\r
                        </File>\r
                        <File\r
+                               RelativePath="..\dom\XMLTokenizer.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath="..\dom\XMLTokenizerLibxml2.cpp"\r
                                >\r
                                <FileConfiguration\r
                                        />\r
                                </FileConfiguration>\r
                        </File>\r
-                       <File\r
-                               RelativePath="..\dom\XMLTokenizer.h"\r
-                               >\r
-                       </File>\r
                </Filter>\r
                <Filter\r
                        Name="editing"\r
                                        >\r
                                </File>\r
                                <File\r
-                                       RelativePath="..\bindings\js\JSHTMLAllCollection.h"\r
+                                       RelativePath="..\bindings\js\JSHTMLAllCollection.cpp"\r
                                        >\r
                                </File>\r
                                <File\r
-                                       RelativePath="..\bindings\js\JSHTMLAllCollection.cpp"\r
+                                       RelativePath="..\bindings\js\JSHTMLAllCollection.h"\r
                                        >\r
                                </File>\r
                                <File\r
                                        >\r
                                </File>\r
                                <File\r
+                                       RelativePath="..\bindings\js\JSMessageChannelConstructor.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\bindings\js\JSMessageChannelConstructor.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\bindings\js\JSMessageChannelCustom.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\bindings\js\JSMessagePortCustom.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
                                        RelativePath="..\bindings\js\JSMimeTypeArrayCustom.cpp"\r
                                        >\r
                                </File>\r
index 7574058..1a99011 100644 (file)
                DD763BB20992C2C900740B8E /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DD763BB10992C2C900740B8E /* libxml2.dylib */; };
                DD7CDF250A23CF9800069928 /* CSSUnknownRule.h in Headers */ = {isa = PBXBuildFile; fileRef = A80E6CCE0A1989CA007FB8C5 /* CSSUnknownRule.h */; };
                DDE63ED50B7D45A800226998 /* DOMTextEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 933A14750B7D1BAF00A53FFD /* DOMTextEvent.h */; };
+               E107400D0E77BDC00033AF24 /* JSMessageChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E107400B0E77BDC00033AF24 /* JSMessageChannel.cpp */; };
+               E107400E0E77BDC00033AF24 /* JSMessageChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = E107400C0E77BDC00033AF24 /* JSMessageChannel.h */; };
+               E10743240E7835830033AF24 /* JSMessageChannelConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E10743230E7835830033AF24 /* JSMessageChannelConstructor.cpp */; };
+               E10743270E7835A50033AF24 /* JSMessageChannelConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = E10743260E7835A50033AF24 /* JSMessageChannelConstructor.h */; };
                E10B937C0B73C00A003ED890 /* JSCustomXPathNSResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = E10B937B0B73C00A003ED890 /* JSCustomXPathNSResolver.h */; };
                E10B93C30B73C291003ED890 /* JSCustomXPathNSResolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E10B93C20B73C291003ED890 /* JSCustomXPathNSResolver.cpp */; };
                E10B9B6C0B747599003ED890 /* NativeXPathNSResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = E10B9B6A0B747599003ED890 /* NativeXPathNSResolver.h */; };
                E17A4A1C0D97991D00FC10C6 /* DOMSVGAltGlyphElementInternal.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = 65AA6BAE0D974A00000541AE /* DOMSVGAltGlyphElementInternal.h */; };
                E1A302BC0DE8370300C52F2C /* StringBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = E1A302BB0DE8370300C52F2C /* StringBuilder.h */; };
                E1A302C10DE8376900C52F2C /* StringBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1A302C00DE8376900C52F2C /* StringBuilder.cpp */; };
+               E1A5F99B0E7EAA2500AF85EA /* JSMessageChannelCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1A5F99A0E7EAA2500AF85EA /* JSMessageChannelCustom.cpp */; };
+               E1ACAF4C0E791AAF0087D12B /* DOMMessagePort.mm in Sources */ = {isa = PBXBuildFile; fileRef = E1ACAF4A0E791AAF0087D12B /* DOMMessagePort.mm */; };
+               E1ACAF4D0E791AAF0087D12B /* DOMMessagePort.h in Headers */ = {isa = PBXBuildFile; fileRef = E1ACAF4B0E791AAF0087D12B /* DOMMessagePort.h */; };
+               E1ADECBF0E76ACF1004A1A5E /* MessagePort.h in Headers */ = {isa = PBXBuildFile; fileRef = E1ADECBD0E76ACF1004A1A5E /* MessagePort.h */; };
+               E1ADECC00E76ACF1004A1A5E /* MessagePort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1ADECBE0E76ACF1004A1A5E /* MessagePort.cpp */; };
+               E1ADECC70E76AD1F004A1A5E /* MessagePort.idl in Resources */ = {isa = PBXBuildFile; fileRef = E1ADECC60E76AD1F004A1A5E /* MessagePort.idl */; };
+               E1ADECCE0E76AD8B004A1A5E /* MessageChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = E1ADECCC0E76AD8B004A1A5E /* MessageChannel.h */; };
+               E1ADECCF0E76AD8B004A1A5E /* MessageChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1ADECCD0E76AD8B004A1A5E /* MessageChannel.cpp */; };
+               E1ADECD10E76ADAB004A1A5E /* MessageChannel.idl in Resources */ = {isa = PBXBuildFile; fileRef = E1ADECD00E76ADAB004A1A5E /* MessageChannel.idl */; };
+               E1ADED470E76B8DD004A1A5E /* JSMessagePortCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1ADED460E76B8DD004A1A5E /* JSMessagePortCustom.cpp */; };
+               E1ADEDD50E76BD60004A1A5E /* DOMMessagePortInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = E1ADEDD40E76BD60004A1A5E /* DOMMessagePortInternal.h */; };
+               E1ADEDDA0E76BD93004A1A5E /* JSMessagePort.h in Headers */ = {isa = PBXBuildFile; fileRef = E1ADEDD80E76BD93004A1A5E /* JSMessagePort.h */; };
+               E1ADEDDB0E76BD93004A1A5E /* JSMessagePort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1ADEDD90E76BD93004A1A5E /* JSMessagePort.cpp */; };
                E1BE512D0CF6C512002EA959 /* XSLTUnicodeSort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1BE512B0CF6C512002EA959 /* XSLTUnicodeSort.cpp */; };
                E1BE512E0CF6C512002EA959 /* XSLTUnicodeSort.h in Headers */ = {isa = PBXBuildFile; fileRef = E1BE512C0CF6C512002EA959 /* XSLTUnicodeSort.h */; };
                E1E6EEA40B628DA8005F2F70 /* JSHTMLSelectElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1E6EEA30B628DA8005F2F70 /* JSHTMLSelectElement.cpp */; };
                DD05FE0B0B8BA3C6009ACDFE /* WebCoreObjCExtras.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WebCoreObjCExtras.h; sourceTree = "<group>"; };
                DD05FE0C0B8BA3C6009ACDFE /* WebCoreObjCExtras.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 30; path = WebCoreObjCExtras.c; sourceTree = "<group>"; };
                DD763BB10992C2C900740B8E /* libxml2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.dylib; path = /usr/lib/libxml2.dylib; sourceTree = "<absolute>"; };
+               E107400B0E77BDC00033AF24 /* JSMessageChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMessageChannel.cpp; sourceTree = "<group>"; };
+               E107400C0E77BDC00033AF24 /* JSMessageChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMessageChannel.h; sourceTree = "<group>"; };
+               E10743230E7835830033AF24 /* JSMessageChannelConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMessageChannelConstructor.cpp; sourceTree = "<group>"; };
+               E10743260E7835A50033AF24 /* JSMessageChannelConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMessageChannelConstructor.h; sourceTree = "<group>"; };
                E10B937B0B73C00A003ED890 /* JSCustomXPathNSResolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCustomXPathNSResolver.h; sourceTree = "<group>"; };
                E10B93C20B73C291003ED890 /* JSCustomXPathNSResolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCustomXPathNSResolver.cpp; sourceTree = "<group>"; };
                E10B9B6A0B747599003ED890 /* NativeXPathNSResolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeXPathNSResolver.h; sourceTree = "<group>"; };
                E12EDBE90B308E0B002704B6 /* EventTarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventTarget.cpp; sourceTree = "<group>"; };
                E1A302BB0DE8370300C52F2C /* StringBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringBuilder.h; sourceTree = "<group>"; };
                E1A302C00DE8376900C52F2C /* StringBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringBuilder.cpp; sourceTree = "<group>"; };
+               E1A5F99A0E7EAA2500AF85EA /* JSMessageChannelCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMessageChannelCustom.cpp; sourceTree = "<group>"; };
+               E1ACAF4A0E791AAF0087D12B /* DOMMessagePort.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMMessagePort.mm; sourceTree = "<group>"; };
+               E1ACAF4B0E791AAF0087D12B /* DOMMessagePort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMMessagePort.h; sourceTree = "<group>"; };
+               E1ADECBD0E76ACF1004A1A5E /* MessagePort.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = MessagePort.h; sourceTree = "<group>"; };
+               E1ADECBE0E76ACF1004A1A5E /* MessagePort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MessagePort.cpp; sourceTree = "<group>"; };
+               E1ADECC60E76AD1F004A1A5E /* MessagePort.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MessagePort.idl; sourceTree = "<group>"; };
+               E1ADECCC0E76AD8B004A1A5E /* MessageChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageChannel.h; sourceTree = "<group>"; };
+               E1ADECCD0E76AD8B004A1A5E /* MessageChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MessageChannel.cpp; sourceTree = "<group>"; };
+               E1ADECD00E76ADAB004A1A5E /* MessageChannel.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MessageChannel.idl; sourceTree = "<group>"; };
+               E1ADED460E76B8DD004A1A5E /* JSMessagePortCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMessagePortCustom.cpp; sourceTree = "<group>"; };
+               E1ADEDD40E76BD60004A1A5E /* DOMMessagePortInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMMessagePortInternal.h; sourceTree = "<group>"; };
+               E1ADEDD80E76BD93004A1A5E /* JSMessagePort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMessagePort.h; sourceTree = "<group>"; };
+               E1ADEDD90E76BD93004A1A5E /* JSMessagePort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMessagePort.cpp; sourceTree = "<group>"; };
                E1BE512B0CF6C512002EA959 /* XSLTUnicodeSort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XSLTUnicodeSort.cpp; sourceTree = "<group>"; };
                E1BE512C0CF6C512002EA959 /* XSLTUnicodeSort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XSLTUnicodeSort.h; sourceTree = "<group>"; };
                E1E6EEA30B628DA8005F2F70 /* JSHTMLSelectElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLSelectElement.cpp; sourceTree = "<group>"; };
                                85DF343F0AAFC0ED00E59AE3 /* DOMKeyboardEventPrivate.h */,
                                75793ED00D0CE85B007FC0AC /* DOMMessageEvent.h */,
                                75793ED10D0CE85B007FC0AC /* DOMMessageEvent.mm */,
+                               E1ACAF4A0E791AAF0087D12B /* DOMMessagePort.mm */,
+                               E1ACAF4B0E791AAF0087D12B /* DOMMessagePort.h */,
                                857E0B230AB043460036E447 /* DOMMouseEvent.h */,
                                857E0B240AB043460036E447 /* DOMMouseEvent.mm */,
                                857E0B2B0AB043FC0036E447 /* DOMMouseEventPrivate.h */,
                                85989DC50ACC8BBD00A0BC51 /* DOMKeyboardEventInternal.h */,
                                85E711820AC5D5350053270F /* DOMMediaListInternal.h */,
                                75793ED20D0CE85B007FC0AC /* DOMMessageEventInternal.h */,
+                               E1ADEDD40E76BD60004A1A5E /* DOMMessagePortInternal.h */,
                                85989DC60ACC8BBD00A0BC51 /* DOMMouseEventInternal.h */,
                                85989DC70ACC8BBD00A0BC51 /* DOMMutationEventInternal.h */,
                                85E711830AC5D5350053270F /* DOMNamedNodeMapInternal.h */,
                                B28BC3190D135E5400CDBA27 /* JSEventTargetBase.lut.h */,
                                A86629CE09DA2B47009633A5 /* JSKeyboardEvent.cpp */,
                                A86629CD09DA2B47009633A5 /* JSKeyboardEvent.h */,
+                               E107400B0E77BDC00033AF24 /* JSMessageChannel.cpp */,
+                               E107400C0E77BDC00033AF24 /* JSMessageChannel.h */,
                                75793EC60D0CE72D007FC0AC /* JSMessageEvent.cpp */,
                                75793EC70D0CE72D007FC0AC /* JSMessageEvent.h */,
+                               E1ADEDD80E76BD93004A1A5E /* JSMessagePort.h */,
+                               E1ADEDD90E76BD93004A1A5E /* JSMessagePort.cpp */,
                                A86629CC09DA2B47009633A5 /* JSMouseEvent.cpp */,
                                A86629CB09DA2B47009633A5 /* JSMouseEvent.h */,
                                65DF31E709D1CC60000BE325 /* JSMutationEvent.cpp */,
                                C09158850DB4209200E55AF4 /* JSInspectedObjectWrapper.h */,
                                C09158860DB4209200E55AF4 /* JSInspectorCallbackWrapper.cpp */,
                                C09158870DB4209200E55AF4 /* JSInspectorCallbackWrapper.h */,
+                               E10743230E7835830033AF24 /* JSMessageChannelConstructor.cpp */,
+                               E10743260E7835A50033AF24 /* JSMessageChannelConstructor.h */,
                                BCD9C26C0C17AA81005C90A2 /* JSNamedNodesCollection.cpp */,
                                BCD9C26D0C17AA81005C90A2 /* JSNamedNodesCollection.h */,
                                BCB7735E0C17853D00132BA4 /* JSNodeFilterCondition.cpp */,
                                AB4CB4EA0B8BDA3D009F40B0 /* JSHTMLSelectElementCustom.h */,
                                1C5FAEE60DCFDA6800D58F78 /* JSJavaScriptCallFrameCustom.cpp */,
                                BCE1C43F0D9830F4003B02F2 /* JSLocationCustom.cpp */,
+                               E1A5F99A0E7EAA2500AF85EA /* JSMessageChannelCustom.cpp */,
+                               E1ADED460E76B8DD004A1A5E /* JSMessagePortCustom.cpp */,
                                A9C6E6460D7465CA006442E9 /* JSMimeTypeArrayCustom.cpp */,
                                BCD9C25F0C17AA67005C90A2 /* JSNamedNodeMapCustom.cpp */,
                                A9C6E6480D7465D8006442E9 /* JSNavigatorCustom.cpp */,
                                A8C4A7F409D563270003AC8D /* MappedAttribute.cpp */,
                                A8C4A7F309D563270003AC8D /* MappedAttribute.h */,
                                A8C4A84B09D5649D0003AC8D /* MappedAttributeEntry.h */,
+                               E1ADECCD0E76AD8B004A1A5E /* MessageChannel.cpp */,
+                               E1ADECCC0E76AD8B004A1A5E /* MessageChannel.h */,
+                               E1ADECD00E76ADAB004A1A5E /* MessageChannel.idl */,
                                75793E800D0CE0B3007FC0AC /* MessageEvent.cpp */,
                                75793E810D0CE0B3007FC0AC /* MessageEvent.h */,
                                75793E820D0CE0B3007FC0AC /* MessageEvent.idl */,
+                               E1ADECBE0E76ACF1004A1A5E /* MessagePort.cpp */,
+                               E1ADECBD0E76ACF1004A1A5E /* MessagePort.h */,
+                               E1ADECC60E76AD1F004A1A5E /* MessagePort.idl */,
                                85031B2F0A44EFC700F992E0 /* MouseEvent.cpp */,
                                85031B300A44EFC700F992E0 /* MouseEvent.h */,
                                141B94E509EC4223000E9413 /* MouseEvent.idl */,
                                316FE0820E6CCC2800BF6088 /* DOMWebKitCSSKeyframesRuleInternal.h in Headers */,
                                7284ADDE0E6FEB31002EEFBD /* UserStyleSheetLoader.h in Headers */,
                                E47B4BE80E71241600038854 /* CachedResourceHandle.h in Headers */,
+                               E1ADECBF0E76ACF1004A1A5E /* MessagePort.h in Headers */,
+                               E1ADECCE0E76AD8B004A1A5E /* MessageChannel.h in Headers */,
+                               E1ADEDD50E76BD60004A1A5E /* DOMMessagePortInternal.h in Headers */,
+                               E1ADEDDA0E76BD93004A1A5E /* JSMessagePort.h in Headers */,
+                               E107400E0E77BDC00033AF24 /* JSMessageChannel.h in Headers */,
+                               E10743270E7835A50033AF24 /* JSMessageChannelConstructor.h in Headers */,
+                               E1ACAF4D0E791AAF0087D12B /* DOMMessagePort.h in Headers */,
                                63D7B32D0E78CD3F00F7617C /* NodeRenderStyle.h in Headers */,
                                63459C650E79CD33008ADFAF /* CSSNthSelector.h in Headers */,
                                29FFBB830E7C5A3D00407730 /* AccessibilityList.h in Headers */,
                                1AB1AE7A0C051FDE00139F4F /* zoomInCursor.png in Resources */,
                                1AB1AE7B0C051FDE00139F4F /* zoomOutCursor.png in Resources */,
                                BCEF45400E676AC1001C1287 /* TextMetrics.idl in Resources */,
+                               E1ADECC70E76AD1F004A1A5E /* MessagePort.idl in Resources */,
+                               E1ADECD10E76ADAB004A1A5E /* MessageChannel.idl in Resources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                316FE0810E6CCC2800BF6088 /* DOMWebKitCSSKeyframesRule.mm in Sources */,
                                7284ADDD0E6FEB31002EEFBD /* UserStyleSheetLoader.cpp in Sources */,
                                E47B4BE90E71241600038854 /* CachedResourceHandle.cpp in Sources */,
+                               E1ADECC00E76ACF1004A1A5E /* MessagePort.cpp in Sources */,
+                               E1ADECCF0E76AD8B004A1A5E /* MessageChannel.cpp in Sources */,
+                               E1ADED470E76B8DD004A1A5E /* JSMessagePortCustom.cpp in Sources */,
+                               E1ADEDDB0E76BD93004A1A5E /* JSMessagePort.cpp in Sources */,
+                               E107400D0E77BDC00033AF24 /* JSMessageChannel.cpp in Sources */,
+                               E10743240E7835830033AF24 /* JSMessageChannelConstructor.cpp in Sources */,
+                               E1ACAF4C0E791AAF0087D12B /* DOMMessagePort.mm in Sources */,
+                               E1A5F99B0E7EAA2500AF85EA /* JSMessageChannelCustom.cpp in Sources */,
                                63459C660E79CD33008ADFAF /* CSSNthSelector.cpp in Sources */,
                                29FFBB820E7C5A3D00407730 /* AccessibilityList.cpp in Sources */,
                                54C50F7B0E801DF3009832A0 /* XMLTokenizerLibxml2.cpp in Sources */,
index 832cf36..8e0ec09 100644 (file)
@@ -81,6 +81,9 @@ This file contains the list of files needed to build WebCore.
         bindings/js/JSInspectorCallbackWrapper.cpp
         bindings/js/JSJavaScriptCallFrameCustom.cpp
         bindings/js/JSLocationCustom.cpp
+        bindings/js/JSMessageChannelConstructor.cpp
+        bindings/js/JSMessageChannelCustom.cpp
+        bindings/js/JSMessagePortCustom.cpp
         bindings/js/JSMimeTypeArrayCustom.cpp
         bindings/js/JSNamedNodeMapCustom.cpp
         bindings/js/JSNamedNodesCollection.cpp
@@ -302,7 +305,9 @@ This file contains the list of files needed to build WebCore.
         DerivedSources/WebCore/JSKeyboardEvent.cpp
         DerivedSources/WebCore/JSLocation.cpp
         DerivedSources/WebCore/JSMediaList.cpp
+        DerivedSources/WebCore/JSMessageChannel.cpp
         DerivedSources/WebCore/JSMessageEvent.cpp
+        DerivedSources/WebCore/JSMessagePort.cpp
         DerivedSources/WebCore/JSMimeType.cpp
         DerivedSources/WebCore/JSMimeTypeArray.cpp
         DerivedSources/WebCore/JSMouseEvent.cpp
@@ -391,7 +396,9 @@ This file contains the list of files needed to build WebCore.
         dom/ExceptionCode.cpp
         dom/KeyboardEvent.cpp
         dom/MappedAttribute.cpp
+        dom/MessageChannel.cpp
         dom/MessageEvent.cpp
+        dom/MessagePort.cpp
         dom/MouseEvent.cpp
         dom/MouseRelatedEvent.cpp
         dom/MutationEvent.cpp
index 4de963d..b6ca22d 100644 (file)
@@ -45,6 +45,7 @@
 #include "JSHTMLCollection.h"
 #include "JSHTMLOptionElementConstructor.h"
 #include "JSImageConstructor.h"
+#include "JSMessageChannelConstructor.h"
 #include "JSNode.h"
 #include "JSXMLHttpRequestConstructor.h"
 #include "Logging.h"
@@ -188,6 +189,7 @@ const ClassInfo JSDOMWindowBase::s_info = { "Window", 0, &JSDOMWindowBaseTable,
 # -- Constructors --
   Audio                 WebCore::JSDOMWindowBase::Audio              DontDelete
   Image                 WebCore::JSDOMWindowBase::Image              DontDelete
+  MessageChannel        WebCore::JSDOMWindowBase::MessageChannel     DontDelete
   Option                WebCore::JSDOMWindowBase::Option             DontDelete
   XMLHttpRequest        WebCore::JSDOMWindowBase::XMLHttpRequest     DontDelete
   XSLTProcessor         WebCore::JSDOMWindowBase::XSLTProcessor      DontDelete
@@ -450,6 +452,10 @@ JSValue *JSDOMWindowBase::getValueProperty(ExecState *exec, int token) const
         // FIXME: this property (and the few below) probably shouldn't create a new object every
         // time
         return new (exec) JSImageConstructor(exec, impl()->frame()->document());
+    case MessageChannel:
+        if (!allowsAccessFrom(exec))
+            return jsUndefined();
+        return new (exec) JSMessageChannelConstructor(exec, impl()->frame()->document());
     case Option:
         if (!allowsAccessFrom(exec))
             return jsUndefined();
index 584f796..708a6bf 100644 (file)
@@ -147,7 +147,7 @@ namespace WebCore {
             OnWebKitTransitionEnd,
 
             // Constructors
-            Audio, Image, Option, XMLHttpRequest, XSLTProcessor
+            Audio, Image, MessageChannel, Option, XMLHttpRequest, XSLTProcessor
         };
 
     private:
index 945cfc5..7942b60 100644 (file)
@@ -28,6 +28,8 @@
 #include "FrameLoader.h"
 #include "FrameTree.h"
 #include "JSDOMWindowShell.h"
+#include "JSMessagePort.h"
+#include "MessagePort.h"
 #include "Settings.h"
 #include "ScriptController.h"
 #include <kjs/JSObject.h>
@@ -175,12 +177,14 @@ JSValue* JSDOMWindow::postMessage(ExecState* exec, const ArgList& args)
     if (exec->hadException())
         return jsUndefined();
 
-    String targetOrigin = valueToStringWithUndefinedOrNullCheck(exec, args.at(exec, 1));
+    MessagePort* messagePort = (args.size() == 2) ? 0 : toMessagePort(args.at(exec, 1));
+
+    String targetOrigin = valueToStringWithUndefinedOrNullCheck(exec, args.at(exec, (args.size() == 2) ? 1 : 2));
     if (exec->hadException())
         return jsUndefined();
 
     ExceptionCode ec = 0;
-    window->postMessage(message, targetOrigin, source, ec);
+    window->postMessage(message, messagePort, targetOrigin, source, ec);
     setDOMException(exec, ec);
 
     return jsUndefined();
index aaff129..37d97da 100644 (file)
@@ -31,6 +31,7 @@
 #include "JSDOMWindow.h"
 #include "JSEventListener.h"
 #include "JSEventTargetNode.h"
+#include "JSMessagePort.h"
 #include "JSXMLHttpRequestUpload.h"
 #include <kjs/Error.h>
 
@@ -294,6 +295,9 @@ JSValue* toJS(ExecState* exec, EventTarget* target)
         // DOMApplicationCache is always created via JS, so we don't need to use cacheDOMObject() here.
         return getCachedDOMObjectWrapper(cache);
 #endif
+
+    if (MessagePort* messagePort = target->toMessagePort())
+        return toJS(exec, messagePort);
     
     ASSERT_NOT_REACHED();
     return jsNull();
diff --git a/WebCore/bindings/js/JSMessageChannelConstructor.cpp b/WebCore/bindings/js/JSMessageChannelConstructor.cpp
new file mode 100644 (file)
index 0000000..7cde005
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "JSMessageChannelConstructor.h"
+
+#include "JSMessageChannel.h"
+#include "MessageChannel.h"
+
+using namespace JSC;
+
+namespace WebCore {
+
+const ClassInfo JSMessageChannelConstructor::s_info = { "MessageChannelConstructor", 0, 0, 0 };
+
+JSMessageChannelConstructor::JSMessageChannelConstructor(ExecState* exec, Document* document)
+    : DOMObject(JSMessageChannelConstructor::createStructureID(exec->lexicalGlobalObject()->objectPrototype()))
+    , m_document(document)
+{
+    putDirect(exec->propertyNames().prototype, JSMessageChannelPrototype::self(exec), None);
+}
+
+ConstructType JSMessageChannelConstructor::getConstructData(ConstructData& constructData)
+{
+    constructData.native.function = construct;
+    return ConstructTypeHost;
+}
+
+JSObject* JSMessageChannelConstructor::construct(ExecState* exec, JSObject* constructor, const ArgList&)
+{
+    return static_cast<JSObject*>(toJS(exec, MessageChannel::create(static_cast<JSMessageChannelConstructor*>(constructor)->m_document)));
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/js/JSMessageChannelConstructor.h b/WebCore/bindings/js/JSMessageChannelConstructor.h
new file mode 100644 (file)
index 0000000..2f1e89c
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef JSMessageChannelConstructor_h
+#define JSMessageChannelConstructor_h
+
+#include "JSDOMBinding.h"
+
+namespace WebCore {
+
+    class Frame;
+
+    class JSMessageChannelConstructor : public DOMObject {
+    public:
+        JSMessageChannelConstructor(JSC::ExecState*, Document*);
+        virtual const JSC::ClassInfo* classInfo() const { return &s_info; }
+        static const JSC::ClassInfo s_info;
+
+        virtual bool implementsHasInstance() const { return true; }
+        static JSC::JSObject* construct(JSC::ExecState*, JSC::JSObject*, const JSC::ArgList&);
+        virtual JSC::ConstructType getConstructData(JSC::ConstructData&);
+
+    private:
+        Document* m_document;
+    };
+
+} // namespace WebCore
+
+#endif // JSMessageChannelConstructor_h
diff --git a/WebCore/bindings/js/JSMessageChannelCustom.cpp b/WebCore/bindings/js/JSMessageChannelCustom.cpp
new file mode 100644 (file)
index 0000000..62a785c
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "JSMessageChannel.h"
+
+#include "MessageChannel.h"
+
+using namespace JSC;
+
+namespace WebCore {
+    
+void JSMessageChannel::mark()
+{
+    DOMObject::mark();
+
+    if (MessagePort* port = m_impl->port1()) {
+        DOMObject* wrapper = getCachedDOMObjectWrapper(port);
+        if (wrapper && !wrapper->marked())
+            wrapper->mark();
+    }
+
+    if (MessagePort* port = m_impl->port2()) {
+        DOMObject* wrapper = getCachedDOMObjectWrapper(port);
+        if (wrapper && !wrapper->marked())
+            wrapper->mark();
+    }
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/js/JSMessagePortCustom.cpp b/WebCore/bindings/js/JSMessagePortCustom.cpp
new file mode 100644 (file)
index 0000000..a1c0fed
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "JSMessagePort.h"
+
+#include "AtomicString.h"
+#include "Event.h"
+#include "Frame.h"
+#include "JSDOMWindowCustom.h"
+#include "JSEvent.h"
+#include "JSEventListener.h"
+#include "MessagePort.h"
+
+using namespace JSC;
+
+namespace WebCore {
+    
+JSValue* JSMessagePort::startConversation(ExecState* exec, const ArgList& args)
+{
+    DOMWindow* window = asJSDOMWindow(exec->lexicalGlobalObject())->impl();
+    const UString& message = args.at(exec, 0)->toString(exec);
+
+    return toJS(exec, impl()->startConversation(window->document(), message).get());
+}
+
+JSValue* JSMessagePort::addEventListener(ExecState* exec, const ArgList& args)
+{
+    Document* document = impl()->document();
+    if (!document)
+        return jsUndefined();
+    JSDOMWindow* window = toJSDOMWindow(document->frame());
+    if (!window)
+        return jsUndefined();
+    RefPtr<JSUnprotectedEventListener> listener = window->findOrCreateJSUnprotectedEventListener(exec, args.at(exec, 1), true);
+    if (!listener)
+        return jsUndefined();
+    impl()->addEventListener(args.at(exec, 0)->toString(exec), listener.release(), args.at(exec, 2)->toBoolean(exec));
+    return jsUndefined();
+}
+
+JSValue* JSMessagePort::removeEventListener(ExecState* exec, const ArgList& args)
+{
+    Document* document = impl()->document();
+    if (!document)
+        return jsUndefined();
+    JSDOMWindow* window = toJSDOMWindow(document->frame());
+    if (!window)
+        return jsUndefined();
+    JSUnprotectedEventListener* listener = window->findJSUnprotectedEventListener(exec, args.at(exec, 1), true);
+    if (!listener)
+        return jsUndefined();
+    impl()->removeEventListener(args.at(exec, 0)->toString(exec), listener, args.at(exec, 2)->toBoolean(exec));
+    return jsUndefined();
+    
+}
+    
+JSValue* JSMessagePort::dispatchEvent(JSC::ExecState* exec, const ArgList& args)
+{
+    ExceptionCode ec = 0;
+    
+    bool result = impl()->dispatchEvent(toEvent(args.at(exec, 0)), ec);
+    setDOMException(exec, ec);
+    return jsBoolean(result);    
+}
+
+void JSMessagePort::setOnmessage(ExecState* exec, JSValue* value)
+{
+    Document* document = impl()->document();
+    if (!document)
+        return;
+    JSDOMWindow* window = toJSDOMWindow(document->frame());
+    if (!window)
+        return;
+    impl()->setOnMessageListener(window->findOrCreateJSUnprotectedEventListener(exec, value, true));
+}
+
+JSValue* JSMessagePort::onmessage(ExecState*) const
+{
+    if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(impl()->onMessageListener()))
+        if (JSObject* listenerObj = listener->listenerObj())
+            return listenerObj;
+    return jsNull();
+}
+
+void JSMessagePort::setOnclose(ExecState* exec, JSValue* value)
+{
+    Document* document = impl()->document();
+    if (!document)
+        return;
+    JSDOMWindow* window = toJSDOMWindow(document->frame());
+    if (!window)
+        return;
+    impl()->setOnCloseListener(window->findOrCreateJSUnprotectedEventListener(exec, value, true));
+}
+
+JSValue* JSMessagePort::onclose(ExecState*) const
+{
+    if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(impl()->onCloseListener()))
+        if (JSObject* listenerObj = listener->listenerObj())
+            return listenerObj;
+    return jsNull();
+}
+
+void JSMessagePort::mark()
+{
+    DOMObject::mark();
+    if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(m_impl->onMessageListener()))
+        listener->mark();
+
+    if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(m_impl->onCloseListener()))
+        listener->mark();
+
+    if (MessagePort* entangledPort = m_impl->entangledPort()) {
+        DOMObject* wrapper = getCachedDOMObjectWrapper(entangledPort);
+        if (wrapper && !wrapper->marked())
+            wrapper->mark();
+    }
+
+    typedef MessagePort::EventListenersMap EventListenersMap;
+    typedef MessagePort::ListenerVector ListenerVector;
+    EventListenersMap& eventListeners = m_impl->eventListeners();
+    for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) {
+        for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) {
+            JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(vecIter->get());
+            listener->mark();
+        }
+    }
+}
+
+} // namespace WebCore
index cfe4594..a1ca9fe 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004-2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple, Inc.  All rights reserved.
  * Copyright (C) 2006 James G. Speth (speth@end.com)
  * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
  *
 #import "DOMHTMLUListElementInternal.h"
 #import "DOMKeyboardEventInternal.h"
 #import "DOMMediaListInternal.h"
+#import "DOMMessagePortInternal.h"
 #import "DOMMouseEventInternal.h"
 #import "DOMMutationEventInternal.h"
 #import "DOMNamedNodeMapInternal.h"
index 440ce6d..505a1cc 100644 (file)
@@ -195,7 +195,7 @@ sub AddIncludesForType
         $implIncludes{"CanvasStyle.h"} = 1;
     }
 
-    if ($type eq "CanvasGradient" or $type eq "XPathNSResolver") {
+    if ($type eq "CanvasGradient" or $type eq "XPathNSResolver" or $type eq "MessagePort") {
         $implIncludes{"PlatformString.h"} = 1;
     }
 
index 260268b..90823c9 100644 (file)
@@ -75,6 +75,7 @@
 #include "KeyboardEvent.h"
 #include "Logging.h"
 #include "MessageEvent.h"
+#include "MessagePort.h"
 #include "MouseEvent.h"
 #include "MouseEventWithHitTestResults.h"
 #include "MutationEvent.h"
@@ -261,6 +262,23 @@ static bool acceptsEditingFocus(Node *node)
 
 static HashSet<Document*>* changedDocuments = 0;
 
+class MessagePortTimer : public TimerBase {
+public:
+    MessagePortTimer(PassRefPtr<Document> document)
+        : m_document(document)
+    {
+    }
+
+private:
+    virtual void fired()
+    {
+        m_document->dispatchMessagePortEvents();
+        delete this;
+    }
+
+    RefPtr<Document> m_document;
+};
+
 Document::Document(Frame* frame, bool isXHTML)
     : ContainerNode(0)
     , m_domtree_version(0)
@@ -274,6 +292,7 @@ Document::Document(Frame* frame, bool isXHTML)
 #endif
     , m_xmlVersion("1.0")
     , m_xmlStandalone(false)
+    , m_firedMessagePortTimer(false)
 #if ENABLE(XBL)
     , m_bindingManager(new XBLBindingManager(this))
 #endif
@@ -448,6 +467,18 @@ Document::~Document()
     if (m_styleSheets)
         m_styleSheets->documentDestroyed();
 
+    HashSet<MessagePort*>::iterator messagePortsEnd = m_messagePorts.end();
+    for (HashSet<MessagePort*>::iterator iter = m_messagePorts.begin(); iter != m_messagePorts.end(); ++iter) {
+        ASSERT((*iter)->document() == this);
+        (*iter)->contextDestroyed();
+        if ((*iter)->entangledPort()) {
+            RefPtr<MessagePort> survivingPort = (*iter)->entangledPort();
+            (*iter)->unentangle();
+            if (survivingPort->document() != this) // Otherwise, survivingPort won't really survive.
+                survivingPort->queueCloseEvent();
+        }
+    }
+
     m_document = 0;
 }
 
@@ -4340,6 +4371,47 @@ HTMLCanvasElement* Document::getCSSCanvasElement(const String& name)
     return result.get();
 }
 
+void Document::processMessagePortMessagesSoon()
+{
+    if (m_firedMessagePortTimer)
+        return;
+
+    MessagePortTimer* timer = new MessagePortTimer(this);
+    timer->startOneShot(0);
+
+    m_firedMessagePortTimer = true;
+}
+
+void Document::dispatchMessagePortEvents()
+{
+    RefPtr<Document> protect(this);
+
+    // Make a frozen copy.
+    Vector<MessagePort*> ports;
+    copyToVector(m_messagePorts, ports);
+
+    m_firedMessagePortTimer = false;
+
+    unsigned portCount = ports.size();
+    for (unsigned i = 0; i < portCount; ++i) {
+        MessagePort* port = ports[i];
+        if (m_messagePorts.contains(port) && port->queueIsOpen())
+            port->dispatchMessages();
+    }
+}
+
+void Document::createdMessagePort(MessagePort* port)
+{
+    ASSERT(port);
+    m_messagePorts.add(port);
+}
+
+void Document::destroyedMessagePort(MessagePort* port)
+{
+    ASSERT(port);
+    m_messagePorts.remove(port);
+}
+
 void Document::initDNSPrefetch()
 {
     m_haveExplicitlyDisabledDNSPrefetch = false;
index b7c5fbd..9dbfc22 100644 (file)
@@ -85,6 +85,7 @@ namespace WebCore {
     class ImageLoader;
     class IntPoint;
     class JSNode;
+    class MessagePort;
     class MouseEventWithHitTestResults;
     class NodeFilter;
     class NodeIterator;
@@ -762,7 +763,12 @@ public:
     // Extension for manipulating canvas drawing contexts for use in CSS
     CanvasRenderingContext2D* getCSSCanvasContext(const String& type, const String& name, int width, int height);
     HTMLCanvasElement* getCSSCanvasElement(const String& name);
-    
+
+    void processMessagePortMessagesSoon();
+    void dispatchMessagePortEvents();
+    void createdMessagePort(MessagePort*);
+    void destroyedMessagePort(MessagePort*);
+
     bool isDNSPrefetchEnabled() const { return m_isDNSPrefetchEnabled; }
     void initDNSPrefetch();
     void parseDNSPrefetchControlHeader(const String&);
@@ -920,6 +926,9 @@ private:
 
     String m_contentLanguage;
 
+    bool m_firedMessagePortTimer;
+    HashSet<MessagePort*> m_messagePorts;
+
 public:
     bool inPageCache();
     void setInPageCache(bool flag);
index d289829..802613c 100644 (file)
@@ -38,6 +38,7 @@ namespace WebCore { namespace EventNames {
     macro(change) \
     macro(checking) \
     macro(click) \
+    macro(close) \
     macro(contextmenu) \
     macro(copy) \
     macro(cut) \
index 951aba7..12b6e8c 100644 (file)
@@ -73,6 +73,11 @@ SVGElementInstance* EventTarget::toSVGElementInstance()
 }
 #endif
 
+MessagePort* EventTarget::toMessagePort()
+{
+    return 0;
+}
+
 #ifndef NDEBUG
 void forbidEventDispatch()
 {
index b6cf9d5..58fc06a 100644 (file)
@@ -41,9 +41,10 @@ namespace WebCore {
     class Event;
     class EventListener;
     class EventTargetNode;
+    class MessagePort;
+    class RegisteredEventListener;
     class SVGElementInstance;
     class XMLHttpRequest;
-    class RegisteredEventListener;
     class XMLHttpRequestUpload;
 
     typedef int ExceptionCode;
@@ -53,6 +54,7 @@ namespace WebCore {
 
     class EventTarget {
     public:
+        virtual MessagePort* toMessagePort();
         virtual EventTargetNode* toNode();
         virtual XMLHttpRequest* toXMLHttpRequest();
         virtual XMLHttpRequestUpload* toXMLHttpRequestUpload();
diff --git a/WebCore/dom/MessageChannel.cpp b/WebCore/dom/MessageChannel.cpp
new file mode 100644 (file)
index 0000000..98b24af
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ *
+ */
+
+#include "config.h"
+#include "MessageChannel.h"
+
+#include "MessagePort.h"
+
+namespace WebCore {
+
+MessageChannel::MessageChannel(Document* document)
+    : m_port1(MessagePort::create(document))
+    , m_port2(MessagePort::create(document))
+{
+    MessagePort::entangle(m_port1.get(), m_port2.get());
+}
+
+MessageChannel::~MessageChannel()
+{
+}
+
+} // namespace WebCore
diff --git a/WebCore/dom/MessageChannel.h b/WebCore/dom/MessageChannel.h
new file mode 100644 (file)
index 0000000..9fec0f7
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ *
+ */
+
+#ifndef MessageChannel_h
+#define MessageChannel_h
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+    class Document;
+    class MessagePort;
+
+    class MessageChannel : public RefCounted<MessageChannel> {
+    public:
+        static PassRefPtr<MessageChannel> create(Document* document) { return adoptRef(new MessageChannel(document)); }
+        ~MessageChannel();
+
+        MessagePort* port1() const { return m_port1.get(); }
+        MessagePort* port2() const { return m_port2.get(); }
+
+    private:
+        MessageChannel(Document*);
+
+        RefPtr<MessagePort> m_port1;
+        RefPtr<MessagePort> m_port2;
+    };
+
+} // namespace WebCore
+
+#endif // MessageChannel_h
diff --git a/WebCore/dom/MessageChannel.idl b/WebCore/dom/MessageChannel.idl
new file mode 100644 (file)
index 0000000..00dd699
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ *
+ */
+
+module events {
+
+    interface [CustomMarkFunction] MessageChannel {
+
+        readonly attribute MessagePort port1;
+        readonly attribute MessagePort port2;
+
+    };
+
+}
index 5b378bb..3957109 100644 (file)
@@ -39,12 +39,13 @@ MessageEvent::MessageEvent()
 {
 }
 
-MessageEvent::MessageEvent(const String& data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source)
+MessageEvent::MessageEvent(const String& data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassRefPtr<MessagePort> messagePort)
     : Event(messageEvent, false, true)
     , m_data(data)
     , m_origin(origin)
     , m_lastEventId(lastEventId)
     , m_source(source)
+    , m_messagePort(messagePort)
 {
 }
 
@@ -52,7 +53,7 @@ MessageEvent::~MessageEvent()
 {
 }
 
-void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& data, const String& origin, const String& lastEventId, DOMWindow* source)
+void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& data, const String& origin, const String& lastEventId, DOMWindow* source, MessagePort* messagePort)
 {
     if (dispatched())
         return;
@@ -63,6 +64,7 @@ void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bo
     m_origin = origin;
     m_lastEventId = lastEventId;
     m_source = source;
+    m_messagePort = messagePort;
 }
 
 bool MessageEvent::isMessageEvent() const 
index a199d3e..87a6745 100644 (file)
@@ -29,6 +29,7 @@
 #define MessageEvent_h
 
 #include "Event.h"
+#include "MessagePort.h"
 
 namespace WebCore {
 
@@ -40,29 +41,31 @@ namespace WebCore {
         {
             return adoptRef(new MessageEvent);
         }
-        static PassRefPtr<MessageEvent> create(const String& data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source)
+        static PassRefPtr<MessageEvent> create(const String& data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassRefPtr<MessagePort> messagePort)
         {
-            return adoptRef(new MessageEvent(data, origin, lastEventId, source));
+            return adoptRef(new MessageEvent(data, origin, lastEventId, source, messagePort));
         }
         virtual ~MessageEvent();
 
-        void initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& data, const String& origin, const String& lastEventId, DOMWindow* source);
+        void initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& data, const String& origin, const String& lastEventId, DOMWindow* source, MessagePort*);
         
         const String& data() const { return m_data; }
         const String& origin() const { return m_origin; }
         const String& lastEventId() const { return m_lastEventId; }
         DOMWindow* source() const { return m_source.get(); }
+        MessagePort* messagePort() const { return m_messagePort.get(); }
         
         virtual bool isMessageEvent() const;
 
     private:    
         MessageEvent();
-        MessageEvent(const String& data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source);
+        MessageEvent(const String& data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassRefPtr<MessagePort> messagePort);
 
         String m_data;
         String m_origin;
         String m_lastEventId;
         RefPtr<DOMWindow> m_source;
+        RefPtr<MessagePort> m_messagePort;
     };
 
 } // namespace WebCore
index 10161ef..5390c43 100644 (file)
@@ -34,8 +34,9 @@ module events {
         readonly attribute DOMString origin;
         readonly attribute DOMString lastEventId;
         readonly attribute DOMWindow source;
+        readonly attribute MessagePort messagePort;
         
-        void initMessageEvent(in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in DOMString dataArg, in DOMString originArg, in DOMString lastEventIdArg, in DOMWindow sourceArg);
+        void initMessageEvent(in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in DOMString dataArg, in DOMString originArg, in DOMString lastEventIdArg, in DOMWindow sourceArg, in MessagePort messagePort);
 
     };
 
diff --git a/WebCore/dom/MessagePort.cpp b/WebCore/dom/MessagePort.cpp
new file mode 100644 (file)
index 0000000..7bc8038
--- /dev/null
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ *
+ */
+
+#include "config.h"
+#include "MessagePort.h"
+
+#include "AtomicString.h"
+#include "Document.h"
+#include "DOMWindow.h"
+#include "EventException.h"
+#include "EventNames.h"
+#include "MessageEvent.h"
+#include "SecurityOrigin.h"
+#include "Timer.h"
+
+namespace WebCore {
+
+class CloseMessagePortTimer : public TimerBase {
+public:
+    CloseMessagePortTimer(PassRefPtr<MessagePort> port)
+        : m_port(port)
+    {
+        ASSERT(m_port);
+    }
+
+private:
+    virtual void fired()
+    {
+        ASSERT(!m_port->active());
+
+        // Closing may destroy the port, dispatch any remaining messages now.
+        if (m_port->queueIsOpen())
+            m_port->dispatchMessages();
+
+        m_port->dispatchCloseEvent();
+        delete this;
+    }
+
+    RefPtr<MessagePort> m_port;
+};
+
+MessagePort::MessagePort(Document* document)
+    : m_entangledPort(0)
+    , m_queueIsOpen(false)
+    , m_document(document)
+{
+    document->createdMessagePort(this);
+}
+
+MessagePort::~MessagePort()
+{
+    if (m_entangledPort)
+        unentangle();
+
+    if (m_document)
+        m_document->destroyedMessagePort(this);
+}
+
+PassRefPtr<MessagePort> MessagePort::clone(Document* newOwner, ExceptionCode& ec)
+{
+    if (!m_entangledPort) {
+        ec = INVALID_STATE_ERR;
+        return 0;
+    }
+
+    RefPtr<MessagePort> remotePort = m_entangledPort;
+    RefPtr<MessagePort> newPort = MessagePort::create(newOwner);
+
+    // Move all the events in the port message queue of original port to the port message queue of new port, if any, leaving the new port's port message queue in its initial closed state.
+    // If events are posted (e.g. from a worker thread) while this code is executing, there is no guarantee whether they end up in the original or new port's message queue.
+    RefPtr<Event> event;
+    while (m_messageQueue.tryGetMessage(event))
+        newPort->m_messageQueue.append(event);
+
+    entangle(remotePort.get(), newPort.get()); // The port object will be unentangled.
+    return newPort;
+}
+
+void MessagePort::postMessage(const String& message, ExceptionCode& ec)
+{
+    postMessage(message, 0, ec);
+}
+
+void MessagePort::postMessage(const String& message, MessagePort* dataPort, ExceptionCode& ec)
+{
+    if (!m_entangledPort || !m_document || !m_entangledPort->m_document)
+        return;
+
+    RefPtr<MessagePort> newMessagePort;
+    if (dataPort) {
+        if (dataPort == this || dataPort == m_entangledPort) {
+            ec = INVALID_ACCESS_ERR;
+            return;
+        }
+        newMessagePort = dataPort->clone(m_entangledPort->m_document, ec);
+        if (ec)
+            return;
+    }
+
+    m_entangledPort->m_messageQueue.append(MessageEvent::create(message, "", "", m_document->domWindow(), newMessagePort.get()));
+    if (m_entangledPort->m_queueIsOpen)
+        m_entangledPort->m_document->processMessagePortMessagesSoon();
+}
+
+PassRefPtr<MessagePort> MessagePort::startConversation(Document* scriptContextDocument, const String& message)
+{
+    RefPtr<MessagePort> port1 = MessagePort::create(scriptContextDocument);
+    if (!m_entangledPort || !m_document || !m_entangledPort->m_document)
+        return port1;
+    RefPtr<MessagePort> port2 = MessagePort::create(m_entangledPort->m_document);
+
+    entangle(port1.get(), port2.get());
+
+    m_entangledPort->m_messageQueue.append(MessageEvent::create(message, "", "", m_document->domWindow(), port2.get()));
+    if (m_entangledPort->m_queueIsOpen)
+        m_entangledPort->m_document->processMessagePortMessagesSoon();
+    return port1;
+}
+
+void MessagePort::start()
+{
+    if (m_queueIsOpen || !m_document)
+        return;
+
+    m_queueIsOpen = true;
+    m_document->processMessagePortMessagesSoon();
+}
+
+void MessagePort::close()
+{
+    if (!m_entangledPort)
+        return;
+
+    MessagePort* otherPort = m_entangledPort;
+    unentangle();
+
+    queueCloseEvent();
+    otherPort->queueCloseEvent();
+}
+
+void MessagePort::entangle(MessagePort* port1, MessagePort* port2)
+{
+    if (port1->m_entangledPort) {
+        ASSERT(port1->m_entangledPort != port2);
+        port1->unentangle();
+    }
+
+    if (port2->m_entangledPort) {
+        ASSERT(port2->m_entangledPort != port1);
+        port2->unentangle();
+    }
+
+    port1->m_entangledPort = port2;
+    port2->m_entangledPort = port1;
+}
+
+void MessagePort::unentangle()
+{
+    ASSERT(this == m_entangledPort->m_entangledPort);
+
+    m_entangledPort->m_entangledPort = 0;
+    m_entangledPort = 0;
+}
+
+void MessagePort::dispatchMessages()
+{
+    // Messages for documents that are not fully active get dispatched too, but JSAbstractEventListener::handleEvent() doesn't call handlers for these.
+    ASSERT(queueIsOpen());
+
+    RefPtr<Event> evt;
+    while (m_messageQueue.tryGetMessage(evt)) {
+
+        ASSERT(evt->type() == EventNames::messageEvent);
+
+        if (m_onMessageListener) {
+            evt->setTarget(this);
+            evt->setCurrentTarget(this);
+            m_onMessageListener->handleEvent(evt.get(), false);
+        }
+
+        ExceptionCode ec = 0;
+        dispatchEvent(evt.release(), ec, false);
+        ASSERT(!ec);
+    }
+}
+
+void MessagePort::queueCloseEvent()
+{
+    CloseMessagePortTimer* timer = new CloseMessagePortTimer(this);
+    timer->startOneShot(0);
+}
+
+void MessagePort::dispatchCloseEvent()
+{
+    RefPtr<Event> evt = Event::create(EventNames::closeEvent, false, true);
+    if (m_onCloseListener) {
+        evt->setTarget(this);
+        evt->setCurrentTarget(this);
+        m_onCloseListener->handleEvent(evt.get(), false);
+    }
+
+    ExceptionCode ec = 0;
+    dispatchEvent(evt.release(), ec, false);
+    ASSERT(!ec);
+}
+
+void MessagePort::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool)
+{
+    EventListenersMap::iterator iter = m_eventListeners.find(eventType.impl());
+    if (iter == m_eventListeners.end()) {
+        ListenerVector listeners;
+        listeners.append(eventListener);
+        m_eventListeners.add(eventType.impl(), listeners);
+    } else {
+        ListenerVector& listeners = iter->second;
+        for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
+            if (*listenerIter == eventListener)
+                return;
+        }
+        
+        listeners.append(eventListener);
+        m_eventListeners.add(eventType.impl(), listeners);
+    }    
+}
+
+void MessagePort::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool useCapture)
+{
+    EventListenersMap::iterator iter = m_eventListeners.find(eventType.impl());
+    if (iter == m_eventListeners.end())
+        return;
+    
+    ListenerVector& listeners = iter->second;
+    for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
+        if (*listenerIter == eventListener) {
+            listeners.remove(listenerIter - listeners.begin());
+            return;
+        }
+    }
+}
+
+bool MessagePort::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec, bool tempEvent)
+{
+    if (event->type().isEmpty()) {
+        ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
+        return true;
+    }
+    
+    ListenerVector listenersCopy = m_eventListeners.get(event->type().impl());
+    for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) {
+        event->setTarget(this);
+        event->setCurrentTarget(this);
+        listenerIter->get()->handleEvent(event.get(), false);
+    }
+    
+    return !event->defaultPrevented();
+}
+
+} // namespace WebCore
diff --git a/WebCore/dom/MessagePort.h b/WebCore/dom/MessagePort.h
new file mode 100644 (file)
index 0000000..d83cee3
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ *
+ */
+
+#ifndef MessagePort_h
+#define MessagePort_h
+
+#include "EventListener.h"
+#include "EventTarget.h"
+
+#include <wtf/HashMap.h>
+#include <wtf/MessageQueue.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+    class AtomicStringImpl;
+    class Document;
+    class Event;
+    class String;
+
+    class MessagePort : public RefCounted<MessagePort>, public EventTarget {
+    public:
+        static PassRefPtr<MessagePort> create(Document* document) { return adoptRef(new MessagePort(document)); }
+        ~MessagePort();
+
+        PassRefPtr<MessagePort> clone(Document*, ExceptionCode&);
+
+        bool active() const { return m_entangledPort; }
+        void postMessage(const String& message, ExceptionCode&);
+        void postMessage(const String& message, MessagePort*, ExceptionCode&);
+        PassRefPtr<MessagePort> startConversation(Document*, const String& message);
+        void start();
+        void close();
+
+        bool queueIsOpen() const { return m_queueIsOpen; }
+
+        MessagePort* entangledPort() { return m_entangledPort; }
+        static void entangle(MessagePort*, MessagePort*);
+        void unentangle();
+
+        void contextDestroyed() { m_document = 0; } 
+        Document* document() { return m_document; }
+        virtual MessagePort* toMessagePort() { return this; }
+
+        void dispatchMessages();
+        void queueCloseEvent();
+        void dispatchCloseEvent();
+
+        virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
+        virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
+        virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&, bool tempEvent = false);
+
+        typedef Vector<RefPtr<EventListener> > ListenerVector;
+        typedef HashMap<AtomicStringImpl*, ListenerVector> EventListenersMap;
+        EventListenersMap& eventListeners() { return m_eventListeners; }
+
+        using RefCounted<MessagePort>::ref;
+        using RefCounted<MessagePort>::deref;
+
+        void setOnMessageListener(PassRefPtr<EventListener> eventListener) { m_onMessageListener = eventListener; }
+        EventListener* onMessageListener() const { return m_onMessageListener.get(); }
+
+        void setOnCloseListener(PassRefPtr<EventListener> eventListener) { m_onCloseListener = eventListener; }
+        EventListener* onCloseListener() const { return m_onCloseListener.get(); }
+
+    private:
+        MessagePort(Document*);
+
+        virtual void refEventTarget() { ref(); }
+        virtual void derefEventTarget() { deref(); }
+
+        MessagePort* m_entangledPort;
+        MessageQueue<RefPtr<Event> > m_messageQueue;
+        bool m_queueIsOpen;
+
+        Document* m_document; // Will be 0 if the context does not contain a document (e.g. if it's a worker thread).
+
+        RefPtr<EventListener> m_onMessageListener;
+        RefPtr<EventListener> m_onCloseListener;
+
+        EventListenersMap m_eventListeners;
+    };
+
+} // namespace WebCore
+
+#endif // MessagePort_h
diff --git a/WebCore/dom/MessagePort.idl b/WebCore/dom/MessagePort.idl
new file mode 100644 (file)
index 0000000..ad0d6f3
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ *
+ */
+
+module events {
+
+    interface [CustomMarkFunction] MessagePort {
+// We need to have something as an ObjC binding, because MessagePort is used in MessageEvent, which already has one,
+// but we don't want to actually expose the API while it is in flux.
+#if defined(LANGUAGE_JAVASCRIPT)
+        readonly attribute boolean active;
+        void postMessage(in DOMString message, in [Optional] MessagePort messagePort)
+            raises(DOMException);
+        [Custom] MessagePort startConversation(in DOMString message);
+        void start();
+        void close();
+
+        // event handler attributes
+        attribute [Custom] EventListener onmessage;
+        attribute [Custom] EventListener onclose;
+
+        // EventTarget interface
+        [Custom] void addEventListener(in DOMString type, 
+                                       in EventListener listener, 
+                                       in boolean useCapture);
+        [Custom] void removeEventListener(in DOMString type, 
+                                          in EventListener listener, 
+                                          in boolean useCapture);
+        [Custom] boolean dispatchEvent(in Event evt)
+            raises(EventException);
+#endif
+    };
+
+}
index 055c531..056a3aa 100644 (file)
@@ -347,7 +347,7 @@ Storage* DOMWindow::localStorage() const
 }
 #endif
 
-void DOMWindow::postMessage(const String& message, const String& targetOrigin, DOMWindow* source, ExceptionCode& ec)
+void DOMWindow::postMessage(const String& message, MessagePort* messagePort, const String& targetOrigin, DOMWindow* source, ExceptionCode& ec)
 {
     if (!m_frame)
         return;
@@ -363,6 +363,12 @@ void DOMWindow::postMessage(const String& message, const String& targetOrigin, D
         }
     }
 
+    RefPtr<MessagePort> newMessagePort;
+    if (messagePort)
+        newMessagePort = messagePort->clone(document(), ec);
+    if (ec)
+        return;
+
     // Capture the source of the message.  We need to do this synchronously
     // in order to capture the source of the message correctly.
     Document* sourceDocument = source->document();
@@ -371,7 +377,7 @@ void DOMWindow::postMessage(const String& message, const String& targetOrigin, D
     String sourceOrigin = sourceDocument->securityOrigin()->toString();
 
     // Schedule the message.
-    PostMessageTimer* timer = new PostMessageTimer(this, MessageEvent::create(message, sourceOrigin, "", source), target.get());
+    PostMessageTimer* timer = new PostMessageTimer(this, MessageEvent::create(message, sourceOrigin, "", source, newMessagePort), target.get());
     timer->startOneShot(0);
 }
 
index 932c26c..57b3a33 100644 (file)
@@ -47,6 +47,7 @@ namespace WebCore {
     class Frame;
     class History;
     class Location;
+    class MessagePort;
     class Navigator;
     class PostMessageTimer;
     class Screen;
@@ -175,7 +176,7 @@ namespace WebCore {
         DOMApplicationCache* applicationCache() const;
 #endif
 
-        void postMessage(const String& message, const String& targetOrigin, DOMWindow* source, ExceptionCode&);
+        void postMessage(const String& message, MessagePort*, const String& targetOrigin, DOMWindow* source, ExceptionCode&);
         void postMessageTimerFired(PostMessageTimer*);
 
         void scrollBy(int x, int y) const;
index 6ab06e5..7455def 100644 (file)
@@ -151,7 +151,7 @@ module window {
                  attribute [Replaceable] Console console;
 
         // cross-document messaging
-        [DoNotCheckDomainSecurity, Custom] void postMessage(in DOMString message, in DOMString targetOrigin)
+        [DoNotCheckDomainSecurity, Custom] void postMessage(in DOMString message, in [Optional] MessagePort messagePort, in DOMString targetOrigin)
             raises(DOMException);
 
 #if defined(LANGUAGE_JAVASCRIPT)