Bug 1313004 - ServiceWorkerMessageEvent can be generated code, r=qdot
authorAndrea Marchesini <amarchesini@mozilla.com>
Wed, 26 Oct 2016 22:00:17 +0200
changeset 319689 8d3f88cdf3b9ea908e3c246eaf57275ef945ed06
parent 319688 6ab0347c02134b3b9b9c6a17042010b6b2f67656
child 319690 8571b4c5d6dda5274c690e155dffd047a65d85ea
push id30876
push usercbook@mozilla.com
push dateThu, 27 Oct 2016 14:45:11 +0000
treeherdermozilla-central@9888f1a23001 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersqdot
bugs1313004
milestone52.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 1313004 - ServiceWorkerMessageEvent can be generated code, r=qdot
dom/base/PostMessageEvent.cpp
dom/base/StructuredCloneHolder.cpp
dom/base/StructuredCloneHolder.h
dom/events/MessageEvent.cpp
dom/events/MessageEvent.h
dom/messagechannel/MessagePort.cpp
dom/webidl/ServiceWorkerMessageEvent.webidl
dom/webidl/moz.build
dom/workers/ServiceWorkerClient.cpp
dom/workers/ServiceWorkerEvents.cpp
dom/workers/ServiceWorkerEvents.h
dom/workers/ServiceWorkerMessageEvent.cpp
dom/workers/ServiceWorkerMessageEvent.h
dom/workers/WorkerPrivate.cpp
dom/workers/moz.build
--- a/dom/base/PostMessageEvent.cpp
+++ b/dom/base/PostMessageEvent.cpp
@@ -139,24 +139,25 @@ PostMessageEvent::Run()
   nsCOMPtr<mozilla::dom::EventTarget> eventTarget = do_QueryObject(targetWindow);
   RefPtr<MessageEvent> event =
     new MessageEvent(eventTarget, nullptr, nullptr);
 
 
   Nullable<WindowProxyOrMessagePort> source;
   source.SetValue().SetAsWindowProxy() = mSource ? mSource->AsOuter() : nullptr;
 
+  Sequence<OwningNonNull<MessagePort>> ports;
+  if (!TakeTransferredPortsAsSequence(ports)) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+
   event->InitMessageEvent(nullptr, NS_LITERAL_STRING("message"),
                           false /*non-bubbling */, false /*cancelable */,
                           messageData, mCallerOrigin,
-                          EmptyString(), source,
-                          Sequence<OwningNonNull<MessagePort>>());
-
-  nsTArray<RefPtr<MessagePort>> ports = TakeTransferredPorts();
-  event->SetPorts(Move(ports));
+                          EmptyString(), source, ports);
 
   // We can't simply call dispatchEvent on the window because doing so ends
   // up flipping the trusted bit on the event, and we don't want that to
   // happen because then untrusted content can call postMessage on a chrome
   // window if it can get a reference to it.
 
   nsIPresShell *shell = targetWindow->GetExtantDoc()->GetShell();
   RefPtr<nsPresContext> presContext;
--- a/dom/base/StructuredCloneHolder.cpp
+++ b/dom/base/StructuredCloneHolder.cpp
@@ -1274,10 +1274,25 @@ StructuredCloneHolder::CustomFreeTransfe
     MOZ_ASSERT(aContent);
     ImageBitmapCloneData* data =
       static_cast<ImageBitmapCloneData*>(aContent);
     delete data;
     return;
   }
 }
 
+bool
+StructuredCloneHolder::TakeTransferredPortsAsSequence(Sequence<OwningNonNull<mozilla::dom::MessagePort>>& aPorts)
+{
+  nsTArray<RefPtr<MessagePort>> ports = TakeTransferredPorts();
+
+  aPorts.Clear();
+  for (uint32_t i = 0, len = ports.Length(); i < len; ++i) {
+    if (!aPorts.AppendElement(ports[i].forget(), fallible)) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
 } // dom namespace
 } // mozilla namespace
--- a/dom/base/StructuredCloneHolder.h
+++ b/dom/base/StructuredCloneHolder.h
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_StructuredCloneHolder_h
 #define mozilla_dom_StructuredCloneHolder_h
 
 #include "js/StructuredClone.h"
 #include "mozilla/Move.h"
 #include "mozilla/UniquePtr.h"
+#include "mozilla/dom/BindingDeclarations.h"
 #include "nsISupports.h"
 #include "nsTArray.h"
 
 #ifdef DEBUG
 #include "nsIThread.h"
 #endif
 
 namespace mozilla {
@@ -202,16 +203,21 @@ public:
   // MessagePorts are not thread-safe and they must be retrieved in the thread
   // where they are created.
   nsTArray<RefPtr<MessagePort>>&& TakeTransferredPorts()
   {
     MOZ_ASSERT(mSupportsTransferring);
     return Move(mTransferredPorts);
   }
 
+  // This method uses TakeTransferredPorts() to populate a sequence of
+  // MessagePorts for WebIDL binding classes.
+  bool
+  TakeTransferredPortsAsSequence(Sequence<OwningNonNull<mozilla::dom::MessagePort>>& aPorts);
+
   nsTArray<MessagePortIdentifier>& PortIdentifiers() const
   {
     MOZ_ASSERT(mSupportsTransferring);
     return mPortIdentifiers;
   }
 
   nsTArray<RefPtr<gfx::DataSourceSurface>>& GetSurfaces()
   {
--- a/dom/events/MessageEvent.cpp
+++ b/dom/events/MessageEvent.cpp
@@ -171,22 +171,15 @@ MessageEvent::InitMessageEvent(JSContext
 
 void
 MessageEvent::GetPorts(nsTArray<RefPtr<MessagePort>>& aPorts)
 {
   aPorts = mPorts;
 }
 
 void
-MessageEvent::SetPorts(nsTArray<RefPtr<MessagePort>>&& aPorts)
-{
-  MOZ_ASSERT(mPorts.IsEmpty());
-  mPorts = Move(aPorts);
-}
-
-void
 MessageEvent::SetSource(mozilla::dom::MessagePort* aPort)
 {
   mPortSource = aPort;
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/events/MessageEvent.h
+++ b/dom/events/MessageEvent.h
@@ -44,18 +44,16 @@ public:
   void GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData,
                ErrorResult& aRv);
   void GetOrigin(nsAString&) const;
   void GetLastEventId(nsAString&) const;
   void GetSource(Nullable<OwningWindowProxyOrMessagePort>& aValue) const;
 
   void GetPorts(nsTArray<RefPtr<MessagePort>>& aPorts);
 
-  void SetPorts(nsTArray<RefPtr<MessagePort>>&& aPorts);
-
   // Non WebIDL methods
   void SetSource(mozilla::dom::MessagePort* aPort);
 
   void SetSource(nsPIDOMWindowInner* aWindow)
   {
     mWindowSource = aWindow;
   }
 
--- a/dom/messagechannel/MessagePort.cpp
+++ b/dom/messagechannel/MessagePort.cpp
@@ -129,27 +129,28 @@ private:
     }
 
     // Create the event
     nsCOMPtr<mozilla::dom::EventTarget> eventTarget =
       do_QueryInterface(mPort->GetOwner());
     RefPtr<MessageEvent> event =
       new MessageEvent(eventTarget, nullptr, nullptr);
 
+    Sequence<OwningNonNull<MessagePort>> ports;
+    if (!mData->TakeTransferredPortsAsSequence(ports)) {
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
+
     event->InitMessageEvent(nullptr, NS_LITERAL_STRING("message"),
                             false /* non-bubbling */,
                             false /* cancelable */, value, EmptyString(),
-                            EmptyString(), nullptr,
-                            Sequence<OwningNonNull<MessagePort>>());
+                            EmptyString(), nullptr, ports);
     event->SetTrusted(true);
     event->SetSource(mPort);
 
-    nsTArray<RefPtr<MessagePort>> ports = mData->TakeTransferredPorts();
-    event->SetPorts(Move(ports));
-
     bool dummy;
     mPort->DispatchEvent(static_cast<dom::Event*>(event.get()), &dummy);
 
     return NS_OK;
   }
 
 private:
   ~PostMessageRunnable()
--- a/dom/webidl/ServiceWorkerMessageEvent.webidl
+++ b/dom/webidl/ServiceWorkerMessageEvent.webidl
@@ -10,17 +10,16 @@
 
 [Pref="dom.serviceWorkers.enabled",
  Constructor(DOMString type, optional ServiceWorkerMessageEventInit eventInitDict),
  Exposed=Window]
 interface ServiceWorkerMessageEvent : Event {
   /**
    * Custom data associated with this event.
    */
-  [GetterThrows]
   readonly attribute any data;
 
   /**
    * The origin of the site from which this event originated.
    */
   readonly attribute DOMString origin;
 
   /**
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -405,17 +405,16 @@ WEBIDL_FILES = [
     'ScreenOrientation.webidl',
     'ScriptProcessorNode.webidl',
     'ScrollAreaEvent.webidl',
     'ScrollBoxObject.webidl',
     'Selection.webidl',
     'ServiceWorker.webidl',
     'ServiceWorkerContainer.webidl',
     'ServiceWorkerGlobalScope.webidl',
-    'ServiceWorkerMessageEvent.webidl',
     'ServiceWorkerRegistration.webidl',
     'SettingChangeNotification.webidl',
     'SettingsManager.webidl',
     'ShadowRoot.webidl',
     'SharedWorker.webidl',
     'SharedWorkerGlobalScope.webidl',
     'SimpleGestureEvent.webidl',
     'SocketCommon.webidl',
@@ -766,16 +765,17 @@ GENERATED_EVENTS_WEBIDL_FILES = [
     'PluginCrashedEvent.webidl',
     'PopStateEvent.webidl',
     'PopupBlockedEvent.webidl',
     'PresentationConnectionAvailableEvent.webidl',
     'PresentationConnectionClosedEvent.webidl',
     'ProgressEvent.webidl',
     'RecordErrorEvent.webidl',
     'ScrollViewChangeEvent.webidl',
+    'ServiceWorkerMessageEvent.webidl',
     'StyleRuleChangeEvent.webidl',
     'StyleSheetApplicableStateChangeEvent.webidl',
     'StyleSheetChangeEvent.webidl',
     'TCPServerSocketEvent.webidl',
     'TCPSocketErrorEvent.webidl',
     'TCPSocketEvent.webidl',
     'TrackEvent.webidl',
     'UDPMessageEvent.webidl',
--- a/dom/workers/ServiceWorkerClient.cpp
+++ b/dom/workers/ServiceWorkerClient.cpp
@@ -160,22 +160,24 @@ private:
     }
     init.mOrigin = NS_ConvertUTF8toUTF16(origin);
 
     RefPtr<ServiceWorker> serviceWorker = aTargetContainer->GetController();
     if (serviceWorker) {
       init.mSource.SetValue().SetAsServiceWorker() = serviceWorker;
     }
 
+    if (!TakeTransferredPortsAsSequence(init.mPorts)) {
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
+
     RefPtr<ServiceWorkerMessageEvent> event =
       ServiceWorkerMessageEvent::Constructor(aTargetContainer,
-                                             NS_LITERAL_STRING("message"), init, rv);
-
-    nsTArray<RefPtr<MessagePort>> ports = TakeTransferredPorts();
-    event->SetPorts(Move(ports));
+                                             NS_LITERAL_STRING("message"),
+                                             init);
 
     event->SetTrusted(true);
     bool status = false;
     aTargetContainer->DispatchEvent(static_cast<dom::Event*>(event.get()),
                                     &status);
 
     if (!status) {
       return NS_ERROR_FAILURE;
--- a/dom/workers/ServiceWorkerEvents.cpp
+++ b/dom/workers/ServiceWorkerEvents.cpp
@@ -1248,23 +1248,16 @@ ExtendableMessageEvent::Constructor(mozi
 
 void
 ExtendableMessageEvent::GetPorts(nsTArray<RefPtr<MessagePort>>& aPorts)
 {
   aPorts = mPorts;
 }
 
 void
-ExtendableMessageEvent::SetPorts(nsTArray<RefPtr<MessagePort>>&& aPorts)
-{
-  MOZ_ASSERT(mPorts.IsEmpty());
-  mPorts = Move(aPorts);
-}
-
-void
 ExtendableMessageEvent::SetSource(ServiceWorkerClient* aClient)
 {
   mClient = aClient;
 }
 
 void
 ExtendableMessageEvent::SetSource(ServiceWorker* aServiceWorker)
 {
--- a/dom/workers/ServiceWorkerEvents.h
+++ b/dom/workers/ServiceWorkerEvents.h
@@ -304,18 +304,16 @@ public:
   NS_IMETHOD GetLastEventId(nsAString& aLastEventId)
   {
     aLastEventId = mLastEventId;
     return NS_OK;
   }
 
   void GetPorts(nsTArray<RefPtr<MessagePort>>& aPorts);
 
-  void SetPorts(nsTArray<RefPtr<MessagePort>>&& aPorts);
-
   void SetSource(ServiceWorkerClient* aClient);
 
   void SetSource(ServiceWorker* aServiceWorker);
 };
 
 END_WORKERS_NAMESPACE
 
 #endif /* mozilla_dom_workers_serviceworkerevents_h__ */
deleted file mode 100644
--- a/dom/workers/ServiceWorkerMessageEvent.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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 "mozilla/dom/ServiceWorkerMessageEvent.h"
-#include "mozilla/dom/ServiceWorkerMessageEventBinding.h"
-#include "mozilla/dom/MessagePort.h"
-#include "mozilla/dom/MessagePortBinding.h"
-
-#include "mozilla/HoldDropJSObjects.h"
-#include "jsapi.h"
-
-#include "ServiceWorker.h"
-
-namespace mozilla {
-namespace dom {
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(ServiceWorkerMessageEvent)
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ServiceWorkerMessageEvent, Event)
-  tmp->mData.setUndefined();
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mServiceWorker)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessagePort)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mPorts)
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServiceWorkerMessageEvent, Event)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mServiceWorker)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessagePort)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPorts)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(ServiceWorkerMessageEvent, Event)
-  NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mData)
-NS_IMPL_CYCLE_COLLECTION_TRACE_END
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServiceWorkerMessageEvent)
-NS_INTERFACE_MAP_END_INHERITING(Event)
-
-NS_IMPL_ADDREF_INHERITED(ServiceWorkerMessageEvent, Event)
-NS_IMPL_RELEASE_INHERITED(ServiceWorkerMessageEvent, Event)
-
-ServiceWorkerMessageEvent::ServiceWorkerMessageEvent(EventTarget* aOwner,
-                                                     nsPresContext* aPresContext,
-                                                     WidgetEvent* aEvent)
-  : Event(aOwner, aPresContext, aEvent)
-  , mData(JS::UndefinedValue())
-{
-  mozilla::HoldJSObjects(this);
-}
-
-ServiceWorkerMessageEvent::~ServiceWorkerMessageEvent()
-{
-  mData.setUndefined();
-  DropJSObjects(this);
-}
-
-JSObject*
-ServiceWorkerMessageEvent::WrapObjectInternal(JSContext* aCx,
-                                              JS::Handle<JSObject*> aGivenProto)
-{
-  return mozilla::dom::ServiceWorkerMessageEventBinding::Wrap(aCx, this, aGivenProto);
-}
-
-
-void
-ServiceWorkerMessageEvent::GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData,
-                                   ErrorResult& aRv) const
-{
-  aData.set(mData);
-  if (!JS_WrapValue(aCx, aData)) {
-    aRv.Throw(NS_ERROR_FAILURE);
-  }
-}
-
-void
-ServiceWorkerMessageEvent::GetOrigin(nsAString& aOrigin) const
-{
-  aOrigin = mOrigin;
-}
-
-void
-ServiceWorkerMessageEvent::GetLastEventId(nsAString& aLastEventId) const
-{
-  aLastEventId = mLastEventId;
-}
-
-void
-ServiceWorkerMessageEvent::GetSource(Nullable<OwningServiceWorkerOrMessagePort>& aValue) const
-{
-  if (mServiceWorker) {
-    aValue.SetValue().SetAsServiceWorker() = mServiceWorker;
-  } else if (mMessagePort) {
-    aValue.SetValue().SetAsMessagePort() = mMessagePort;
-  }
-}
-
-void
-ServiceWorkerMessageEvent::SetSource(mozilla::dom::MessagePort* aPort)
-{
-  mMessagePort = aPort;
-}
-
-void
-ServiceWorkerMessageEvent::SetSource(workers::ServiceWorker* aServiceWorker)
-{
-  mServiceWorker = aServiceWorker;
-}
-
-void
-ServiceWorkerMessageEvent::GetPorts(nsTArray<RefPtr<MessagePort>>& aPorts)
-{
-  aPorts = mPorts;
-}
-
-void
-ServiceWorkerMessageEvent::SetPorts(nsTArray<RefPtr<MessagePort>>&& aPorts)
-{
-  MOZ_ASSERT(mPorts.IsEmpty());
-  mPorts = Move(aPorts);
-}
-
-/* static */ already_AddRefed<ServiceWorkerMessageEvent>
-ServiceWorkerMessageEvent::Constructor(const GlobalObject& aGlobal,
-                                       const nsAString& aType,
-                                       const ServiceWorkerMessageEventInit& aParam,
-                                       ErrorResult& aRv)
-{
-  nsCOMPtr<EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports());
-  return Constructor(t, aType, aParam, aRv);
-}
-
-/* static */ already_AddRefed<ServiceWorkerMessageEvent>
-ServiceWorkerMessageEvent::Constructor(EventTarget* aEventTarget,
-                                       const nsAString& aType,
-                                       const ServiceWorkerMessageEventInit& aParam,
-                                       ErrorResult& aRv)
-{
-  RefPtr<ServiceWorkerMessageEvent> event =
-    new ServiceWorkerMessageEvent(aEventTarget, nullptr, nullptr);
-
-  event->InitEvent(aType, aParam.mBubbles, aParam.mCancelable);
-
-  bool trusted = event->Init(aEventTarget);
-  event->SetTrusted(trusted);
-
-  event->mData = aParam.mData;
-  event->mOrigin = aParam.mOrigin;
-  event->mLastEventId = aParam.mLastEventId;
-
-  if (!aParam.mSource.IsNull()) {
-    if (aParam.mSource.Value().IsServiceWorker()) {
-      event->mServiceWorker = aParam.mSource.Value().GetAsServiceWorker();
-    } else if (aParam.mSource.Value().IsMessagePort()) {
-      event->mMessagePort = aParam.mSource.Value().GetAsMessagePort();
-    }
-  }
-
-  event->mPorts.AppendElements(aParam.mPorts);
-
-  return event.forget();
-}
-
-} // namespace dom
-} // namespace mozilla
deleted file mode 100644
--- a/dom/workers/ServiceWorkerMessageEvent.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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_serviceworkermessageevent_h__
-#define mozilla_dom_serviceworkermessageevent_h__
-
-#include "mozilla/dom/Event.h"
-
-namespace mozilla {
-namespace dom {
-
-struct ServiceWorkerMessageEventInit;
-class MessagePort;
-class OwningServiceWorkerOrMessagePort;
-
-namespace workers {
-
-class ServiceWorker;
-
-}
-
-class ServiceWorkerMessageEvent final : public Event
-{
-public:
-  ServiceWorkerMessageEvent(EventTarget* aOwner,
-                            nsPresContext* aPresContext,
-                            WidgetEvent* aEvent);
-
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(ServiceWorkerMessageEvent, Event)
-
-  // Forward to base class
-  NS_FORWARD_TO_EVENT
-
-  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
-  void GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData,
-               ErrorResult& aRv) const;
-
-  void GetOrigin(nsAString& aOrigin) const;
-
-  void GetLastEventId(nsAString& aLastEventId) const;
-
-  void GetSource(Nullable<OwningServiceWorkerOrMessagePort>& aValue) const;
-
-  void GetPorts(nsTArray<RefPtr<MessagePort>>& aPorts);
-
-  void SetSource(mozilla::dom::MessagePort* aPort);
-
-  void SetSource(workers::ServiceWorker* aServiceWorker);
-
-  void SetPorts(nsTArray<RefPtr<MessagePort>>&& aPorts);
-
-  static already_AddRefed<ServiceWorkerMessageEvent>
-  Constructor(const GlobalObject& aGlobal,
-              const nsAString& aType,
-              const ServiceWorkerMessageEventInit& aEventInit,
-              ErrorResult& aRv);
-
-  static already_AddRefed<ServiceWorkerMessageEvent>
-  Constructor(EventTarget* aEventTarget,
-              const nsAString& aType,
-              const ServiceWorkerMessageEventInit& aEventInit,
-              ErrorResult& aRv);
-
-protected:
-  ~ServiceWorkerMessageEvent();
-
-private:
-  JS::Heap<JS::Value> mData;
-  nsString mOrigin;
-  nsString mLastEventId;
-  RefPtr<workers::ServiceWorker> mServiceWorker;
-  RefPtr<MessagePort> mMessagePort;
-  nsTArray<RefPtr<MessagePort>> mPorts;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif /* mozilla_dom_workers_serviceworkermessageevent_h__ */
-
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -678,56 +678,58 @@ public:
       timelines->AddMarkerForAllObservedDocShells(end);
     }
 
     if (NS_WARN_IF(rv.Failed())) {
       xpc::Throw(aCx, rv.StealNSResult());
       return false;
     }
 
-    nsTArray<RefPtr<MessagePort>> ports = TakeTransferredPorts();
+    Sequence<OwningNonNull<MessagePort>> ports;
+    if (!TakeTransferredPortsAsSequence(ports)) {
+      return false;
+    }
 
     nsCOMPtr<nsIDOMEvent> domEvent;
     RefPtr<ExtendableMessageEvent> extendableEvent;
     // For messages dispatched to service worker, use ExtendableMessageEvent
     // https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#extendablemessage-event-section
     if (mEventSource) {
       RefPtr<ServiceWorkerClient> client =
         new ServiceWorkerWindowClient(aTarget, *mEventSource);
 
       RootedDictionary<ExtendableMessageEventInit> init(aCx);
 
       init.mBubbles = false;
       init.mCancelable = false;
 
       init.mData = messageData;
+      init.mPorts = ports;
 
       ErrorResult rv;
       extendableEvent = ExtendableMessageEvent::Constructor(
         aTarget, NS_LITERAL_STRING("message"), init, rv);
       if (NS_WARN_IF(rv.Failed())) {
         rv.SuppressException();
         return false;
       }
       extendableEvent->SetSource(client);
-      extendableEvent->SetPorts(Move(ports));
 
       domEvent = do_QueryObject(extendableEvent);
     } else {
       RefPtr<MessageEvent> event = new MessageEvent(aTarget, nullptr, nullptr);
       event->InitMessageEvent(nullptr,
                               NS_LITERAL_STRING("message"),
                               false /* non-bubbling */,
                               false /* cancelable */,
                               messageData,
                               EmptyString(),
                               EmptyString(),
                               nullptr,
-                              Sequence<OwningNonNull<MessagePort>>());
-      event->SetPorts(Move(ports));
+                              ports);
       domEvent = do_QueryObject(event);
     }
 
     domEvent->SetTrusted(true);
 
     nsEventStatus dummy = nsEventStatus_eIgnore;
     aTarget->DispatchDOMEvent(nullptr, domEvent, nullptr, &dummy);
 
@@ -6484,28 +6486,26 @@ WorkerPrivate::ConnectMessagePort(JSCont
   if (globalObject.Failed()) {
     return false;
   }
 
   RootedDictionary<MessageEventInit> init(aCx);
   init.mBubbles = false;
   init.mCancelable = false;
   init.mSource.SetValue().SetAsMessagePort() = port;
+  if (!init.mPorts.AppendElement(port.forget(), fallible)) {
+    return false;
+  }
 
   RefPtr<MessageEvent> event =
     MessageEvent::Constructor(globalObject,
                               NS_LITERAL_STRING("connect"), init, rv);
 
   event->SetTrusted(true);
 
-  nsTArray<RefPtr<MessagePort>> ports;
-  ports.AppendElement(port);
-
-  event->SetPorts(Move(ports));
-
   nsCOMPtr<nsIDOMEvent> domEvent = do_QueryObject(event);
 
   nsEventStatus dummy = nsEventStatus_eIgnore;
   globalScope->DispatchDOMEvent(nullptr, domEvent, nullptr, &dummy);
 
   return true;
 }
 
--- a/dom/workers/moz.build
+++ b/dom/workers/moz.build
@@ -5,17 +5,16 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 # Public stuff.
 EXPORTS.mozilla.dom += [
     'FileReaderSync.h',
     'ServiceWorkerCommon.h',
     'ServiceWorkerContainer.h',
     'ServiceWorkerEvents.h',
-    'ServiceWorkerMessageEvent.h',
     'ServiceWorkerRegistrar.h',
     'ServiceWorkerRegistration.h',
     'WorkerLocation.h',
     'WorkerNavigator.h',
     'WorkerPrefs.h',
     'WorkerPrivate.h',
     'WorkerRunnable.h',
     'WorkerScope.h',
@@ -61,17 +60,16 @@ UNIFIED_SOURCES += [
     'ServiceWorkerEvents.cpp',
     'ServiceWorkerInfo.cpp',
     'ServiceWorkerJob.cpp',
     'ServiceWorkerJobQueue.cpp',
     'ServiceWorkerManager.cpp',
     'ServiceWorkerManagerChild.cpp',
     'ServiceWorkerManagerParent.cpp',
     'ServiceWorkerManagerService.cpp',
-    'ServiceWorkerMessageEvent.cpp',
     'ServiceWorkerPrivate.cpp',
     'ServiceWorkerRegisterJob.cpp',
     'ServiceWorkerRegistrar.cpp',
     'ServiceWorkerRegistration.cpp',
     'ServiceWorkerRegistrationInfo.cpp',
     'ServiceWorkerScriptCache.cpp',
     'ServiceWorkerUnregisterJob.cpp',
     'ServiceWorkerUpdateJob.cpp',