Bug 677638 - Patch 1 - MessageChannel and MessagePort interfaces, r=smaug
authorAndrea Marchesini <amarchesini@mozilla.com>
Tue, 03 Sep 2013 14:38:49 +0200
changeset 145343 3f261800748f2ae00b57819a99cecdb34378dba4
parent 145342 b2c06efbc1457741e673470b7ef512b8c196b22f
child 145344 00c47683de8da5094c6cc8dd9c54e66165075507
push id25208
push userryanvm@gmail.com
push dateTue, 03 Sep 2013 21:41:13 +0000
treeherdermozilla-central@e3785e299ab6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs677638
milestone26.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 677638 - Patch 1 - MessageChannel and MessagePort interfaces, r=smaug
dom/base/MessageChannel.cpp
dom/base/MessageChannel.h
dom/base/MessagePort.cpp
dom/base/MessagePort.h
dom/base/moz.build
dom/base/test/Makefile.in
dom/base/test/test_messageChannel.html
dom/webidl/MessageChannel.webidl
dom/webidl/MessagePort.webidl
dom/webidl/WebIDL.mk
new file mode 100644
--- /dev/null
+++ b/dom/base/MessageChannel.cpp
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "MessageChannel.h"
+#include "mozilla/dom/MessageChannelBinding.h"
+#include "mozilla/dom/MessagePort.h"
+#include "nsContentUtils.h"
+#include "nsPIDOMWindow.h"
+
+namespace mozilla {
+namespace dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_3(MessageChannel, mWindow, mPort1, mPort2)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(MessageChannel)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(MessageChannel)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MessageChannel)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+MessageChannel::MessageChannel(nsPIDOMWindow* aWindow)
+  : mWindow(aWindow)
+{
+  MOZ_COUNT_CTOR(MessageChannel);
+  SetIsDOMBinding();
+
+  mPort1 = new MessagePort(mWindow);
+  mPort2 = new MessagePort(mWindow);
+
+  mPort1->Entangle(mPort2);
+  mPort2->Entangle(mPort1);
+}
+
+MessageChannel::~MessageChannel()
+{
+  MOZ_COUNT_DTOR(MessageChannel);
+}
+
+JSObject*
+MessageChannel::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
+{
+  return MessageChannelBinding::Wrap(aCx, aScope, this);
+}
+
+/* static */ already_AddRefed<MessageChannel>
+MessageChannel::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
+{
+  nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports());
+  if (!window) {
+    aRv.Throw(NS_ERROR_UNEXPECTED);
+    return nullptr;
+  }
+
+  nsRefPtr<MessageChannel> channel = new MessageChannel(window);
+  return channel.forget();
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/base/MessageChannel.h
@@ -0,0 +1,70 @@
+
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_MessageChannel_h
+#define mozilla_dom_MessageChannel_h
+
+#include "mozilla/Attributes.h"
+#include "mozilla/ErrorResult.h"
+#include "mozilla/dom/BindingDeclarations.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsWrapperCache.h"
+#include "nsCOMPtr.h"
+
+class nsPIDOMWindow;
+
+namespace mozilla {
+namespace dom {
+
+class MessagePort;
+
+class MessageChannel MOZ_FINAL : public nsISupports
+                               , public nsWrapperCache
+{
+public:
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MessageChannel)
+
+public:
+  MessageChannel(nsPIDOMWindow* aWindow);
+
+  ~MessageChannel();
+
+  nsPIDOMWindow*
+  GetParentObject() const
+  {
+    return mWindow;
+  }
+
+  virtual JSObject*
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
+
+  static already_AddRefed<MessageChannel>
+  Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
+
+  MessagePort*
+  Port1() const
+  {
+    return mPort1;
+  }
+
+  MessagePort*
+  Port2() const
+  {
+    return mPort2;
+  }
+
+private:
+  nsCOMPtr<nsPIDOMWindow> mWindow;
+
+  nsRefPtr<MessagePort> mPort1;
+  nsRefPtr<MessagePort> mPort2;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_MessageChannel_h
new file mode 100644
--- /dev/null
+++ b/dom/base/MessagePort.cpp
@@ -0,0 +1,86 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "MessagePort.h"
+#include "mozilla/dom/MessageChannel.h"
+#include "mozilla/dom/MessagePortBinding.h"
+#include "nsContentUtils.h"
+
+namespace mozilla {
+namespace dom {
+
+NS_IMPL_CYCLE_COLLECTION_INHERITED_1(MessagePort, nsDOMEventTargetHelper,
+                                     mEntangledPort)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MessagePort)
+NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
+
+NS_IMPL_ADDREF_INHERITED(MessagePort, nsDOMEventTargetHelper)
+NS_IMPL_RELEASE_INHERITED(MessagePort, nsDOMEventTargetHelper)
+
+MessagePort::MessagePort(nsPIDOMWindow* aWindow)
+  : nsDOMEventTargetHelper(aWindow)
+{
+  MOZ_COUNT_CTOR(MessagePort);
+  SetIsDOMBinding();
+}
+
+MessagePort::~MessagePort()
+{
+  MOZ_COUNT_DTOR(MessagePort);
+  Close();
+}
+
+JSObject*
+MessagePort::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
+{
+  return MessagePortBinding::Wrap(aCx, aScope, this);
+}
+
+void
+MessagePort::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
+                         const Optional<JS::Handle<JS::Value> >& aTransfer)
+{
+  if (!mEntangledPort) {
+    return;
+  }
+
+  // TODO
+}
+
+void
+MessagePort::Start()
+{
+  // TODO
+}
+
+void
+MessagePort::Close()
+{
+  if (!mEntangledPort) {
+    return;
+  }
+
+  // This avoids loops.
+  nsRefPtr<MessagePort> port = mEntangledPort;
+  mEntangledPort = nullptr;
+
+  // Let's disentangle the 2 ports symmetrically.
+  port->Close();
+}
+
+void
+MessagePort::Entangle(MessagePort* aMessagePort)
+{
+  MOZ_ASSERT(aMessagePort);
+  MOZ_ASSERT(aMessagePort != this);
+
+  Close();
+
+  mEntangledPort = aMessagePort;
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/base/MessagePort.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_MessagePort_h
+#define mozilla_dom_MessagePort_h
+
+#include "mozilla/Attributes.h"
+#include "mozilla/ErrorResult.h"
+#include "nsDOMEventTargetHelper.h"
+
+class nsPIDOMWindow;
+
+namespace mozilla {
+namespace dom {
+
+class MessagePort MOZ_FINAL : public nsDOMEventTargetHelper
+{
+public:
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_REALLY_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper)
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MessagePort,
+                                           nsDOMEventTargetHelper)
+
+  MessagePort(nsPIDOMWindow* aWindow);
+  ~MessagePort();
+
+  virtual JSObject*
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
+
+  void
+  PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
+              const Optional<JS::Handle<JS::Value> >& aTransfer);
+
+  void
+  Start();
+
+  void
+  Close();
+
+  IMPL_EVENT_HANDLER(message)
+
+  // Non WebIDL methods
+
+  // This method entangles this MessagePort with another one.
+  // If it is already entangled, it's disentangled first and enatangle to the
+  // new one.
+  void
+  Entangle(MessagePort* aMessagePort);
+
+private:
+  nsRefPtr<MessagePort> mEntangledPort;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_MessagePort_h
--- a/dom/base/moz.build
+++ b/dom/base/moz.build
@@ -50,28 +50,32 @@ EXPORTS += [
     'nsWrapperCacheInlines.h',
 ]
 
 EXPORTS.mozilla.dom += [
     'BarProps.h',
     'DOMCursor.h',
     'DOMError.h',
     'DOMRequest.h',
+    'MessageChannel.h',
+    'MessagePort.h',
     'ScreenOrientation.h',
     'StructuredCloneTags.h',
     'URL.h',
 ]
 
 CPP_SOURCES += [
     'BarProps.cpp',
     'Crypto.cpp',
     'DOMCursor.cpp',
     'DOMError.cpp',
     'DOMRequest.cpp',
     'Navigator.cpp',
+    'MessageChannel.cpp',
+    'MessagePort.cpp',
     'nsContentPermissionHelper.cpp',
     'nsDOMClassInfo.cpp',
     'nsDOMException.cpp',
     'nsDOMNavigationTiming.cpp',
     'nsDOMScriptObjectFactory.cpp',
     'nsDOMWindowList.cpp',
     'nsDOMWindowUtils.cpp',
     'nsFocusManager.cpp',
--- a/dom/base/test/Makefile.in
+++ b/dom/base/test/Makefile.in
@@ -26,16 +26,17 @@ MOCHITEST_FILES = \
   test_window_extensible.html \
   test_window_indexing.html \
   test_writable-replaceable.html \
   test_domcursor.html \
   test_named_frames.html \
   test_Image_constructor.html \
   test_setting_opener.html \
   test_error.html \
+  test_messageChannel.html \
   $(NULL)
 
 MOCHITEST_CHROME_FILES = \
    test_bug715041.xul \
    test_bug715041_removal.xul \
    test_domrequesthelper.xul \
    $(NULL)
 
new file mode 100644
--- /dev/null
+++ b/dom/base/test/test_messageChannel.html
@@ -0,0 +1,43 @@
+
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=677638
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 677638 - basic support</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=677638">Mozilla Bug 677638</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  <iframe name="x" id="x"></iframe>
+  <iframe name="y" id="y"></iframe>
+</div>
+<pre id="test">
+</pre>
+  <script type="application/javascript">
+
+  /** Test for Bug 677638 **/
+  var a = new MessageChannel();
+  ok(a, "MessageChannel created");
+
+  var port1 = a.port1;
+  ok(port1, "MessageChannel.port1 exists");
+  is(port1, a.port1, "MessageChannel.port1 is port1");
+
+  var port2 = a.port2;
+  ok(port2, "MessageChannel.port1 exists");
+  is(port2, a.port2, "MessageChannel.port2 is port2");
+
+  [ 'postMessage', 'start', 'close' ].forEach(function(e) {
+    ok(e in port1, "MessagePort1." + e + " exists");
+    ok(e in port2, "MessagePort2." + e + " exists");
+  });
+
+  </script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/webidl/MessageChannel.webidl
@@ -0,0 +1,14 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * For more information on this interface, please see
+ * http://www.whatwg.org/specs/web-apps/current-work/#channel-messaging
+ */
+
+[Constructor]
+interface MessageChannel {
+  readonly attribute MessagePort port1;
+  readonly attribute MessagePort port2;
+};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/MessagePort.webidl
@@ -0,0 +1,20 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * For more information on this interface, please see
+ * http://www.whatwg.org/specs/web-apps/current-work/#channel-messaging
+ */
+
+interface MessagePort : EventTarget {
+  // TODO void postMessage(any message, optional sequence<Transferable> transfer);
+  void postMessage(any message, optional any transfer);
+  void start();
+  void close();
+
+  // event handlers
+  [SetterThrows]
+           attribute EventHandler onmessage;
+};
+// MessagePort implements Transferable;
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -190,17 +190,19 @@ webidl_files = \
   MediaError.webidl \
   MediaRecorder.webidl \
   MediaSource.webidl \
   MediaStream.webidl \
   MediaStreamAudioDestinationNode.webidl \
   MediaStreamAudioSourceNode.webidl \
   MediaStreamEvent.webidl \
   MediaStreamTrack.webidl \
+  MessageChannel.webidl \
   MessageEvent.webidl \
+  MessagePort.webidl \
   MimeType.webidl \
   MimeTypeArray.webidl \
   MobileMessageManager.webidl \
   MouseEvent.webidl \
   MouseScrollEvent.webidl \
   MozActivity.webidl \
   MozMmsMessage.webidl \
   MozNamedAttrMap.webidl \