merge mozilla-inbound to mozilla-central a=merge
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Fri, 13 Nov 2015 12:06:41 +0100
changeset 308683 faf815a0fa9b052a38bce00c0c2aa1e2c9610936
parent 308644 0eaf345983b3afc2b426e25a3be93ebf0d93e6c1 (current diff)
parent 308682 fc9023a0d7619127c607db4e06986c8979c949ad (diff)
child 308684 4bb826a4f98af86c1accfaf96e1caacefb1fec6e
child 308743 62fdebd5b3ea2a57fb11583b9b07fb1a368759d1
child 308780 ac0817c70558088a897459bb2d85b6e952414fb3
child 308786 be03dc78777374c1d4680a4fc71b529a61f37dcc
child 308794 55174ceac7e5b3d3f00afbce746966c0efb2890d
child 308812 2987b998b7ce2fb92138f04d27d0a9a43faedeee
child 308824 f60318dd4abaa644b85b42ef82cd883047df2dc1
child 308825 cefe63e6f67d4536c3102ba391d1ef4d1813aaed
child 308827 f6303c2a0c6707f78da8e397decf6454aeffa8cd
child 308828 ad4c3cf4d2f9239cd8903686321ebae00cb04fb9
child 308829 24283c60158bc0123488c35c55596773478d7e9f
child 308831 202b199b9fcf37a687bef882f2513e191f079622
child 308980 c2735fad06cbe6a3bb00b4a866e5352232f146d6
child 309043 8aef15e4c8b25babfce498ce90b1caa72ef1c5a3
child 309047 0573bc105ca13574b1e33fd04aa18291cde4df51
child 309120 f829cd5055ba7aea0d81d6c9d77b478b5d018f0a
child 309514 f5410717776c7349ed5cd5b0e915fa23f92b01cc
push id7513
push useratolfsen@mozilla.com
push dateFri, 13 Nov 2015 14:03:43 +0000
reviewersmerge
milestone45.0a1
merge mozilla-inbound to mozilla-central a=merge
dom/security/test/csp/file_worker_redirect.html
dom/security/test/csp/file_worker_redirect.sjs
dom/security/test/csp/test_worker_redirect.html
dom/workers/test/serviceworkers/test_eval_not_allowed.html
dom/workers/test/serviceworkers/test_eval_not_allowed.html^headers^
--- a/browser/components/extensions/ext-bookmarks.js
+++ b/browser/components/extensions/ext-bookmarks.js
@@ -1,17 +1,16 @@
 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
 Cu.import("resource://gre/modules/PlacesUtils.jsm");
 var Bookmarks = PlacesUtils.bookmarks;
 
 Cu.import("resource://gre/modules/ExtensionUtils.jsm");
 var {
   EventManager,
-  ignoreEvent,
   runSafe,
 } = ExtensionUtils;
 
 XPCOMUtils.defineLazyModuleGetter(this, "Task",
                                   "resource://gre/modules/Task.jsm");
 
 function getTree(rootGuid, onlyChildren) {
   function convert(node, parent) {
--- a/browser/components/extensions/ext-browserAction.js
+++ b/browser/components/extensions/ext-browserAction.js
@@ -6,17 +6,16 @@ XPCOMUtils.defineLazyModuleGetter(this, 
                                   "resource:///modules/CustomizableUI.jsm");
 
 Cu.import("resource://devtools/shared/event-emitter.js");
 
 Cu.import("resource://gre/modules/ExtensionUtils.jsm");
 var {
   EventManager,
   DefaultWeakMap,
-  ignoreEvent,
   runSafe,
 } = ExtensionUtils;
 
 // WeakMap[Extension -> BrowserAction]
 var browserActionMap = new WeakMap();
 
 function browserActionOf(extension)
 {
--- a/browser/components/extensions/ext-pageAction.js
+++ b/browser/components/extensions/ext-pageAction.js
@@ -1,17 +1,16 @@
 /* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set sts=2 sw=2 et tw=80: */
 "use strict";
 
 Cu.import("resource://gre/modules/ExtensionUtils.jsm");
 var {
   EventManager,
   DefaultWeakMap,
-  ignoreEvent,
   runSafe,
 } = ExtensionUtils;
 
 // WeakMap[Extension -> PageAction]
 var pageActionMap = new WeakMap();
 
 
 // Handles URL bar icons, including the |page_action| manifest entry
--- a/browser/components/extensions/ext-tabs.js
+++ b/browser/components/extensions/ext-tabs.js
@@ -225,17 +225,17 @@ extensions.registerAPI((extension, conte
         return () => {
           AllWindowEvents.removeListener("progress", progressListener);
           AllWindowEvents.removeListener("TabAttrModified", listener);
           AllWindowEvents.removeListener("TabPinned", listener);
           AllWindowEvents.removeListener("TabUnpinned", listener);
         };
       }).api(),
 
-      onReplaced: ignoreEvent(),
+      onReplaced: ignoreEvent(context, "tabs.onReplaced"),
 
       onRemoved: new EventManager(context, "tabs.onRemoved", fire => {
         let tabListener = event => {
           let tab = event.originalTarget;
           let tabId = TabManager.getId(tab);
           let windowId = WindowManager.getId(tab.ownerDocument.defaultView);
           let removeInfo = {windowId, isWindowClosing: false};
           fire(tabId, removeInfo);
--- a/browser/components/extensions/ext-windows.js
+++ b/browser/components/extensions/ext-windows.js
@@ -1,16 +1,15 @@
 XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
                                    "@mozilla.org/browser/aboutnewtab-service;1",
                                    "nsIAboutNewTabService");
 
 Cu.import("resource://gre/modules/ExtensionUtils.jsm");
 var {
   EventManager,
-  ignoreEvent,
   runSafe,
 } = ExtensionUtils;
 
 extensions.registerAPI((extension, context) => {
   return {
     windows: {
       WINDOW_ID_CURRENT: WindowManager.WINDOW_ID_CURRENT,
       WINDOW_ID_NONE: WindowManager.WINDOW_ID_NONE,
--- a/dom/base/DOMRequest.cpp
+++ b/dom/base/DOMRequest.cpp
@@ -188,21 +188,17 @@ DOMRequest::FireDetailedError(DOMError* 
 void
 DOMRequest::FireEvent(const nsAString& aType, bool aBubble, bool aCancelable)
 {
   if (NS_FAILED(CheckInnerWindowCorrectness())) {
     return;
   }
 
   RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
-  nsresult rv = event->InitEvent(aType, aBubble, aCancelable);
-  if (NS_FAILED(rv)) {
-    return;
-  }
-
+  event->InitEvent(aType, aBubble, aCancelable);
   event->SetTrusted(true);
 
   bool dummy;
   DispatchEvent(event, &dummy);
 }
 
 void
 DOMRequest::RootResultVal()
--- a/dom/base/EventSource.cpp
+++ b/dom/base/EventSource.cpp
@@ -752,22 +752,17 @@ EventSource::AnnounceConnection()
   nsresult rv = CheckInnerWindowCorrectness();
   if (NS_FAILED(rv)) {
     return;
   }
 
   RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
 
   // it doesn't bubble, and it isn't cancelable
-  rv = event->InitEvent(NS_LITERAL_STRING("open"), false, false);
-  if (NS_FAILED(rv)) {
-    NS_WARNING("Failed to init the open event!!!");
-    return;
-  }
-
+  event->InitEvent(NS_LITERAL_STRING("open"), false, false);
   event->SetTrusted(true);
 
   rv = DispatchDOMEvent(nullptr, event, nullptr, nullptr);
   if (NS_FAILED(rv)) {
     NS_WARNING("Failed to dispatch the open event!!!");
     return;
   }
 }
@@ -808,22 +803,17 @@ EventSource::ReestablishConnection()
   rv = CheckInnerWindowCorrectness();
   if (NS_FAILED(rv)) {
     return;
   }
 
   RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
 
   // it doesn't bubble, and it isn't cancelable
-  rv = event->InitEvent(NS_LITERAL_STRING("error"), false, false);
-  if (NS_FAILED(rv)) {
-    NS_WARNING("Failed to init the error event!!!");
-    return;
-  }
-
+  event->InitEvent(NS_LITERAL_STRING("error"), false, false);
   event->SetTrusted(true);
 
   rv = DispatchDOMEvent(nullptr, event, nullptr, nullptr);
   if (NS_FAILED(rv)) {
     NS_WARNING("Failed to dispatch the error event!!!");
     return;
   }
 
@@ -959,22 +949,17 @@ EventSource::FailConnection()
   rv = CheckInnerWindowCorrectness();
   if (NS_FAILED(rv)) {
     return;
   }
 
   RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
 
   // it doesn't bubble, and it isn't cancelable
-  rv = event->InitEvent(NS_LITERAL_STRING("error"), false, false);
-  if (NS_FAILED(rv)) {
-    NS_WARNING("Failed to init the error event!!!");
-    return;
-  }
-
+  event->InitEvent(NS_LITERAL_STRING("error"), false, false);
   event->SetTrusted(true);
 
   rv = DispatchDOMEvent(nullptr, event, nullptr, nullptr);
   if (NS_FAILED(rv)) {
     NS_WARNING("Failed to dispatch the error event!!!");
     return;
   }
 }
--- a/dom/base/WebSocket.cpp
+++ b/dom/base/WebSocket.cpp
@@ -1802,19 +1802,17 @@ WebSocket::CreateAndDispatchSimpleEvent(
   nsresult rv = CheckInnerWindowCorrectness();
   if (NS_FAILED(rv)) {
     return NS_OK;
   }
 
   RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
 
   // it doesn't bubble, and it isn't cancelable
-  rv = event->InitEvent(aName, false, false);
-  NS_ENSURE_SUCCESS(rv, rv);
-
+  event->InitEvent(aName, false, false);
   event->SetTrusted(true);
 
   return DispatchDOMEvent(nullptr, event, nullptr, nullptr);
 }
 
 nsresult
 WebSocket::CreateAndDispatchMessageEvent(const nsACString& aData,
                                          bool aIsBinary)
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -3751,19 +3751,17 @@ nsresult GetEventAndTarget(nsIDocument* 
   nsCOMPtr<EventTarget> target(do_QueryInterface(aTarget));
   NS_ENSURE_TRUE(domDoc && target, NS_ERROR_INVALID_ARG);
 
   nsCOMPtr<nsIDOMEvent> event;
   nsresult rv =
     domDoc->CreateEvent(NS_LITERAL_STRING("Events"), getter_AddRefs(event));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = event->InitEvent(aEventName, aCanBubble, aCancelable);
-  NS_ENSURE_SUCCESS(rv, rv);
-
+  event->InitEvent(aEventName, aCanBubble, aCancelable);
   event->SetTrusted(aTrusted);
 
   rv = event->SetTarget(target);
   NS_ENSURE_SUCCESS(rv, rv);
 
   event.forget(aEvent);
   target.forget(aTargetOut);
   return NS_OK;
@@ -6611,32 +6609,16 @@ nsContentUtils::FindInternalContentViewe
       *aLoaderType = TYPE_CONTENT;
     }
     return docFactory.forget();
   }
 
   return nullptr;
 }
 
-bool
-nsContentUtils::GetContentSecurityPolicy(nsIContentSecurityPolicy** aCSP)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-
-  nsCOMPtr<nsIContentSecurityPolicy> csp;
-  nsresult rv = SubjectPrincipal()->GetCsp(getter_AddRefs(csp));
-  if (NS_FAILED(rv)) {
-    NS_ERROR("CSP: Failed to get CSP from principal.");
-    return false;
-  }
-
-  csp.forget(aCSP);
-  return true;
-}
-
 // static
 bool
 nsContentUtils::IsPatternMatching(nsAString& aValue, nsAString& aPattern,
                                   nsIDocument* aDocument)
 {
   NS_ASSERTION(aDocument, "aDocument should be a valid pointer (not null)");
 
   AutoJSAPI jsapi;
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -517,21 +517,16 @@ public:
    * Get the cache security manager service. Can return null if the layout
    * module has been shut down.
    */
   static nsIScriptSecurityManager* GetSecurityManager()
   {
     return sSecurityManager;
   }
 
-  /**
-   * Get the ContentSecurityPolicy for a JS context.
-   **/
-  static bool GetContentSecurityPolicy(nsIContentSecurityPolicy** aCSP);
-
   // Returns the subject principal. Guaranteed to return non-null. May only
   // be called when nsContentUtils is initialized.
   static nsIPrincipal* SubjectPrincipal();
 
   // Returns the prinipal of the given JS object. This may only be called on
   // the main thread for objects from the main thread's JSRuntime.
   static nsIPrincipal* ObjectPrincipal(JSObject* aObj);
 
--- a/dom/base/nsDOMDataChannel.cpp
+++ b/dom/base/nsDOMDataChannel.cpp
@@ -450,19 +450,17 @@ nsDOMDataChannel::OnSimpleEvent(nsISuppo
 
   nsresult rv = CheckInnerWindowCorrectness();
   if (NS_FAILED(rv)) {
     return NS_OK;
   }
 
   RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
 
-  rv = event->InitEvent(aName, false, false);
-  NS_ENSURE_SUCCESS(rv,rv);
-
+  event->InitEvent(aName, false, false);
   event->SetTrusted(true);
 
   return DispatchDOMEvent(nullptr, event, nullptr, nullptr);
 }
 
 nsresult
 nsDOMDataChannel::OnChannelConnected(nsISupports* aContext)
 {
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -9117,20 +9117,17 @@ NotifyPageHide(nsIDocument* aDocument, v
   return true;
 }
 
 static void
 DispatchCustomEventWithFlush(nsINode* aTarget, const nsAString& aEventType,
                              bool aBubbles, bool aOnlyChromeDispatch)
 {
   RefPtr<Event> event = NS_NewDOMEvent(aTarget, nullptr, nullptr);
-  nsresult rv = event->InitEvent(aEventType, aBubbles, false);
-  if (NS_FAILED(rv)) {
-    return;
-  }
+  event->InitEvent(aEventType, aBubbles, false);
   event->SetTrusted(true);
   if (aOnlyChromeDispatch) {
     event->GetInternalNSEvent()->mFlags.mOnlyChromeDispatch = true;
   }
   if (nsIPresShell* shell = aTarget->OwnerDoc()->GetShell()) {
     shell->GetPresContext()->
       RefreshDriver()->ScheduleEventDispatch(aTarget, event);
   }
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -11023,23 +11023,21 @@ nsGlobalWindow::Observe(nsISupports* aSu
   if (!nsCRT::strcmp(aTopic, NS_NETWORK_ACTIVITY_BLIP_UPLOAD_TOPIC) ||
       !nsCRT::strcmp(aTopic, NS_NETWORK_ACTIVITY_BLIP_DOWNLOAD_TOPIC)) {
     MOZ_ASSERT(IsInnerWindow());
     if (!IsCurrentInnerWindow()) {
       return NS_OK;
     }
 
     RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
-    nsresult rv = event->InitEvent(
+    event->InitEvent(
       !nsCRT::strcmp(aTopic, NS_NETWORK_ACTIVITY_BLIP_UPLOAD_TOPIC)
         ? NETWORK_UPLOAD_EVENT_NAME
         : NETWORK_DOWNLOAD_EVENT_NAME,
       false, false);
-    NS_ENSURE_SUCCESS(rv, rv);
-
     event->SetTrusted(true);
 
     bool dummy;
     return DispatchEvent(event, &dummy);
   }
 #endif // MOZ_B2G
 
   if (!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
@@ -11059,19 +11057,17 @@ nsGlobalWindow::Observe(nsISupports* aSu
     }
 
     // The event has to be dispatched only to the current inner window.
     if (!IsCurrentInnerWindow()) {
       return NS_OK;
     }
 
     RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
-    nsresult rv = event->InitEvent(NS_LITERAL_STRING("languagechange"), false, false);
-    NS_ENSURE_SUCCESS(rv, rv);
-
+    event->InitEvent(NS_LITERAL_STRING("languagechange"), false, false);
     event->SetTrusted(true);
 
     bool dummy;
     return DispatchEvent(event, &dummy);
   }
 
   NS_WARNING("unrecognized topic in nsGlobalWindow::Observe");
   return NS_ERROR_FAILURE;
--- a/dom/base/nsPerformance.cpp
+++ b/dom/base/nsPerformance.cpp
@@ -478,21 +478,17 @@ nsPerformance::Timing()
   return mTiming;
 }
 
 void
 nsPerformance::DispatchBufferFullEvent()
 {
   RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
   // it bubbles, and it isn't cancelable
-  nsresult rv = event->InitEvent(NS_LITERAL_STRING("resourcetimingbufferfull"),
-                                 true, false);
-  if (NS_FAILED(rv)) {
-    return;
-  }
+  event->InitEvent(NS_LITERAL_STRING("resourcetimingbufferfull"), true, false);
   event->SetTrusted(true);
   DispatchDOMEvent(nullptr, event, nullptr, nullptr);
 }
 
 nsPerformanceNavigation*
 nsPerformance::Navigation()
 {
   if (!mNavigation) {
--- a/dom/base/nsXMLHttpRequest.cpp
+++ b/dom/base/nsXMLHttpRequest.cpp
@@ -1685,18 +1685,20 @@ nsXMLHttpRequest::Open(const nsACString&
   }
   else {
     // Otherwise use CORS. Again, make sure that potential result documents
     // use the same principal as the loader.
     secFlags = nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS |
                nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
   }
 
-  // If we have the document, use it
-  if (doc) {
+  // If we have the document, use it. Unfortunately, for dedicated workers
+  // 'doc' ends up being the parent document, which is not the document
+  // that we want to use. So make sure to avoid using 'doc' in that situation.
+  if (doc && doc->NodePrincipal() == mPrincipal) {
     rv = NS_NewChannel(getter_AddRefs(mChannel),
                        uri,
                        doc,
                        secFlags,
                        nsIContentPolicy::TYPE_INTERNAL_XMLHTTPREQUEST,
                        loadGroup,
                        nullptr,   // aCallbacks
                        loadFlags);
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -15972,17 +15972,17 @@ class CGEventMethod(CGNativeMember):
             self.args.insert(0, Argument("mozilla::dom::EventTarget*", "aOwner"))
             constructorForNativeCaller = CGNativeMember.declare(self, cgClass)
 
         self.args = list(self.originalArgs)
         if needCx(None, self.arguments(), [], considerTypes=True, static=True):
             self.args.insert(0, Argument("JSContext*", "aCx"))
         if not self.isInit:
             self.args.insert(0, Argument("const GlobalObject&", "aGlobal"))
-        self.args.append(Argument('ErrorResult&', 'aRv'))
+            self.args.append(Argument('ErrorResult&', 'aRv'))
         return constructorForNativeCaller + CGNativeMember.declare(self, cgClass)
 
     def defineInit(self, cgClass):
         iface = self.descriptorProvider.interface
         members = ""
         while iface.identifier.name != "Event":
             i = 3  # Skip the boilerplate args: type, bubble,s cancelable.
             for m in iface.members:
@@ -15994,30 +15994,24 @@ class CGEventMethod(CGNativeMember):
                         continue
                     name = CGDictionary.makeMemberName(m.identifier.name)
                     members += "%s = %s;\n" % (name, self.args[i].name)
                     i += 1
             iface = iface.parent
 
         self.body = fill(
             """
-            nsresult rv = InitEvent(${typeArg}, ${bubblesArg}, ${cancelableArg});
-            if (NS_FAILED(rv)) {
-              aRv.Throw(rv);
-              return;
-            }
+            InitEvent(${typeArg}, ${bubblesArg}, ${cancelableArg});
             ${members}
             """,
             typeArg=self.args[0].name,
             bubblesArg=self.args[1].name,
             cancelableArg=self.args[2].name,
             members=members)
 
-        self.args.append(Argument('ErrorResult&', 'aRv'))
-
         return CGNativeMember.define(self, cgClass)
 
     def define(self, cgClass):
         self.args = list(self.originalArgs)
         if self.isInit:
             return self.defineInit(cgClass)
         members = ""
         holdJS = ""
--- a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
@@ -273,23 +273,16 @@ BluetoothDaemonProtocol::FetchResultHand
 
   return userData.forget();
 }
 
 //
 // Interface
 //
 
-/* returns the container structure of a variable; _t is the container's
- * type, _v the name of the variable, and _m is _v's field within _t
- */
-#define container(_t, _v, _m) \
-  ( (_t*)( ((const unsigned char*)(_v)) - offsetof(_t, _m) ) )
-
-
 static bool
 IsDaemonRunning()
 {
   char value[PROPERTY_VALUE_MAX];
   NS_WARN_IF(property_get("init.svc.bluetoothd", value, "") < 0);
   if (strcmp(value, "running")) {
     BT_LOGR("[RESTART] Bluetooth daemon state <%s>", value);
     return false;
--- a/dom/bluetooth/bluedroid/BluetoothOppManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothOppManager.cpp
@@ -1200,17 +1200,17 @@ BluetoothOppManager::SendConnectRequest(
 void
 BluetoothOppManager::SendPutHeaderRequest(const nsAString& aFileName,
                                           int aFileSize)
 {
   if (!mConnected) {
     return;
   }
 
-  uint8_t* req = new uint8_t[mRemoteMaxPacketLength];
+  auto req = MakeUnique<uint8_t[]>(mRemoteMaxPacketLength);
 
   int len = aFileName.Length();
   uint8_t* fileName = new uint8_t[(len + 1) * 2];
   const char16_t* fileNamePtr = aFileName.BeginReading();
 
   for (int i = 0; i < len; i++) {
     fileName[i * 2] = (uint8_t)(fileNamePtr[i] >> 8);
     fileName[i * 2 + 1] = (uint8_t)fileNamePtr[i];
@@ -1222,20 +1222,19 @@ BluetoothOppManager::SendPutHeaderReques
   int index = 3;
   index += AppendHeaderName(&req[index], mRemoteMaxPacketLength - index,
                             fileName, (len + 1) * 2);
   index += AppendHeaderLength(&req[index], aFileSize);
 
   // This is final put packet if file size equals to 0
   uint8_t opcode = (aFileSize > 0) ? ObexRequestCode::Put
                                    : ObexRequestCode::PutFinal;
-  SendObexData(req, opcode, index);
+  SendObexData(Move(req), opcode, index);
 
   delete [] fileName;
-  delete [] req;
 }
 
 void
 BluetoothOppManager::SendPutRequest(uint8_t* aFileBody,
                                     int aFileBodyLength)
 {
   if (!mConnected) {
     return;
@@ -1244,24 +1243,23 @@ BluetoothOppManager::SendPutRequest(uint
   int packetLeftSpace = mRemoteMaxPacketLength - kPutRequestHeaderSize;
   if (aFileBodyLength > packetLeftSpace) {
     BT_WARNING("Not allowed such a small MaxPacketLength value");
     return;
   }
 
   // Section 3.3.3 "Put", IrOBEX 1.2
   // [opcode:1][length:2][Headers:var]
-  uint8_t* req = new uint8_t[mRemoteMaxPacketLength];
+  auto req = MakeUnique<uint8_t[]>(mRemoteMaxPacketLength);
 
   int index = 3;
   index += AppendHeaderBody(&req[index], mRemoteMaxPacketLength - index,
                             aFileBody, aFileBodyLength);
 
-  SendObexData(req, ObexRequestCode::Put, index);
-  delete [] req;
+  SendObexData(Move(req), ObexRequestCode::Put, index);
 
   mSentFileLength += aFileBodyLength;
 }
 
 void
 BluetoothOppManager::SendPutFinalRequest()
 {
   if (!mConnected) {
@@ -1272,21 +1270,20 @@ BluetoothOppManager::SendPutFinalRequest
    * Section 2.2.9, "End-of-Body", IrObex 1.2
    * End-of-Body is used to identify the last chunk of the object body.
    * For most platforms, a PutFinal packet is sent with an zero length
    * End-of-Body header.
    */
 
   // [opcode:1][length:2]
   int index = 3;
-  uint8_t* req = new uint8_t[mRemoteMaxPacketLength];
+  auto req = MakeUnique<uint8_t[]>(mRemoteMaxPacketLength);
   index += AppendHeaderEndOfBody(&req[index]);
 
-  SendObexData(req, ObexRequestCode::PutFinal, index);
-  delete [] req;
+  SendObexData(Move(req), ObexRequestCode::PutFinal, index);
 
   mWaitingToSendPutFinal = false;
 }
 
 void
 BluetoothOppManager::SendDisconnectRequest()
 {
   if (!mConnected) {
@@ -1406,16 +1403,28 @@ BluetoothOppManager::SendObexData(uint8_
     mLastCommand = aOpcode;
   }
 
   SetObexPacketInfo(aData, aOpcode, aSize);
   mSocket->SendSocketData(new UnixSocketRawData(aData, aSize));
 }
 
 void
+BluetoothOppManager::SendObexData(UniquePtr<uint8_t[]> aData, uint8_t aOpcode,
+                                  int aSize)
+{
+  if (!mIsServer) {
+    mLastCommand = aOpcode;
+  }
+
+  SetObexPacketInfo(aData.get(), aOpcode, aSize);
+  mSocket->SendSocketData(new UnixSocketRawData(Move(aData), aSize));
+}
+
+void
 BluetoothOppManager::FileTransferComplete()
 {
   if (mSendTransferCompleteFlag) {
     return;
   }
 
   nsAutoString deviceAddressStr;
   AddressToString(mDeviceAddress, deviceAddressStr);
--- a/dom/bluetooth/bluedroid/BluetoothOppManager.h
+++ b/dom/bluetooth/bluedroid/BluetoothOppManager.h
@@ -7,16 +7,17 @@
 #ifndef mozilla_dom_bluetooth_bluedroid_BluetoothOppManager_h
 #define mozilla_dom_bluetooth_bluedroid_BluetoothOppManager_h
 
 #include "BluetoothCommon.h"
 #include "BluetoothProfileManagerBase.h"
 #include "BluetoothSocketObserver.h"
 #include "DeviceStorage.h"
 #include "mozilla/ipc/SocketBase.h"
+#include "mozilla/UniquePtr.h"
 #include "nsCOMArray.h"
 
 class nsIOutputStream;
 class nsIInputStream;
 class nsIVolumeMountLock;
 
 namespace mozilla {
 namespace dom {
@@ -96,16 +97,17 @@ private:
   void AfterOppDisconnected();
   void ValidateFileName();
   bool IsReservedChar(char16_t c);
   void ClearQueue();
   void RetrieveSentFileName();
   void NotifyAboutFileChange();
   bool AcquireSdcardMountLock();
   void SendObexData(uint8_t* aData, uint8_t aOpcode, int aSize);
+  void SendObexData(UniquePtr<uint8_t[]> aData, uint8_t aOpcode, int aSize);
   void AppendBlobToSend(const BluetoothAddress& aDeviceAddress, Blob* aBlob);
   void DiscardBlobsToSend();
   bool ProcessNextBatch();
   void ConnectInternal(const BluetoothAddress& aDeviceAddress);
 
   /**
    * Usually we won't get a full PUT packet in one operation, which means that
    * a packet may be devided into several parts and BluetoothOppManager should
--- a/dom/bluetooth/bluedroid/BluetoothPbapManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothPbapManager.cpp
@@ -971,17 +971,17 @@ BluetoothPbapManager::ReplyToGet(uint16_
    * If |mPhonebookSizeRequired| is true,
    * - Part 2: [headerId:1][length:2][PhonebookSize:4]
    * - Part 3: [headerId:1][length:2][EndOfBody:0]
    * Otherwise,
    * - Part 2a: [headerId:1][length:2][EndOfBody:0]
    *   or
    * - Part 2b: [headerId:1][length:2][Body:var]
    */
-  uint8_t* res = new uint8_t[mRemoteMaxPacketLength];
+  auto res = MakeUnique<uint8_t[]>(mRemoteMaxPacketLength);
   uint8_t opcode;
 
   // ---- Part 1: [response code:1][length:2] ---- //
   // [response code:1][length:2] will be set in |SendObexData|.
   // Reserve index for them here
   unsigned int index = kObexRespHeaderSize;
 
   if (mPhonebookSizeRequired) {
@@ -1058,18 +1058,17 @@ BluetoothPbapManager::ReplyToGet(uint16_
                                 remainingPacketSize,
                                 reinterpret_cast<uint8_t*>(buf.get()),
                                 numRead);
 
       opcode = ObexResponseCode::Continue;
     }
   }
 
-  SendObexData(res, opcode, index);
-  delete [] res;
+  SendObexData(Move(res), opcode, index);
 
   return true;
 }
 
 bool
 BluetoothPbapManager::GetInputStreamFromBlob(Blob* aBlob)
 {
   // PBAP can only handle one OBEX BODY transfer at the same time.
@@ -1104,16 +1103,24 @@ BluetoothPbapManager::ReplyError(uint8_t
 void
 BluetoothPbapManager::SendObexData(uint8_t* aData, uint8_t aOpcode, int aSize)
 {
   SetObexPacketInfo(aData, aOpcode, aSize);
   mSocket->SendSocketData(new UnixSocketRawData(aData, aSize));
 }
 
 void
+BluetoothPbapManager::SendObexData(UniquePtr<uint8_t[]> aData, uint8_t aOpcode,
+                                   int aSize)
+{
+  SetObexPacketInfo(aData.get(), aOpcode, aSize);
+  mSocket->SendSocketData(new UnixSocketRawData(Move(aData), aSize));
+}
+
+void
 BluetoothPbapManager::OnSocketConnectSuccess(BluetoothSocket* aSocket)
 {
   MOZ_ASSERT(aSocket);
   MOZ_ASSERT(aSocket == mServerSocket);
   MOZ_ASSERT(!mSocket);
 
   BT_LOGR("PBAP socket is connected");
 
--- a/dom/bluetooth/bluedroid/BluetoothPbapManager.h
+++ b/dom/bluetooth/bluedroid/BluetoothPbapManager.h
@@ -7,16 +7,17 @@
 #ifndef mozilla_dom_bluetooth_bluedroid_BluetoothPbapManager_h
 #define mozilla_dom_bluetooth_bluedroid_BluetoothPbapManager_h
 
 #include "BluetoothCommon.h"
 #include "BluetoothProfileManagerBase.h"
 #include "BluetoothSocketObserver.h"
 #include "mozilla/dom/bluetooth/BluetoothTypes.h"
 #include "mozilla/ipc/SocketBase.h"
+#include "mozilla/UniquePtr.h"
 #include "nsICryptoHash.h"
 #include "ObexBase.h"
 
 class nsICryptoHash;
 class nsIInputStream;
 namespace mozilla {
   namespace dom {
     class Blob;
@@ -149,16 +150,17 @@ private:
   void HandleShutdown();
 
   void ReplyToConnect(const nsAString& aPassword = EmptyString());
   void ReplyToDisconnectOrAbort();
   void ReplyToSetPath();
   bool ReplyToGet(uint16_t aPhonebookSize = 0);
   void ReplyError(uint8_t aError);
   void SendObexData(uint8_t* aData, uint8_t aOpcode, int aSize);
+  void SendObexData(UniquePtr<uint8_t[]> aData, uint8_t aOpcode, int aSize);
 
   ObexResponseCode SetPhoneBookPath(const ObexHeaderSet& aHeader,
                                     uint8_t flags);
   ObexResponseCode NotifyPbapRequest(const ObexHeaderSet& aHeader);
   ObexResponseCode NotifyPasswordRequest(const ObexHeaderSet& aHeader);
   void AppendNamedValueByTagId(const ObexHeaderSet& aHeader,
                                InfallibleTArray<BluetoothNamedValue>& aValues,
                                const AppParameterTag aTagId);
--- a/dom/bluetooth/bluez/BluetoothOppManager.cpp
+++ b/dom/bluetooth/bluez/BluetoothOppManager.cpp
@@ -1171,17 +1171,17 @@ BluetoothOppManager::SendConnectRequest(
 }
 
 void
 BluetoothOppManager::SendPutHeaderRequest(const nsAString& aFileName,
                                           int aFileSize)
 {
   if (!mConnected) return;
 
-  uint8_t* req = new uint8_t[mRemoteMaxPacketLength];
+  auto req = MakeUnique<uint8_t[]>(mRemoteMaxPacketLength);
 
   int len = aFileName.Length();
   uint8_t* fileName = new uint8_t[(len + 1) * 2];
   const char16_t* fileNamePtr = aFileName.BeginReading();
 
   for (int i = 0; i < len; i++) {
     fileName[i * 2] = (uint8_t)(fileNamePtr[i] >> 8);
     fileName[i * 2 + 1] = (uint8_t)fileNamePtr[i];
@@ -1193,43 +1193,41 @@ BluetoothOppManager::SendPutHeaderReques
   int index = 3;
   index += AppendHeaderName(&req[index], mRemoteMaxPacketLength - index,
                             fileName, (len + 1) * 2);
   index += AppendHeaderLength(&req[index], aFileSize);
 
   // This is final put packet if file size equals to 0
   uint8_t opcode = (aFileSize > 0) ? ObexRequestCode::Put
                                    : ObexRequestCode::PutFinal;
-  SendObexData(req, opcode, index);
+  SendObexData(Move(req), opcode, index);
 
   delete [] fileName;
-  delete [] req;
 }
 
 void
 BluetoothOppManager::SendPutRequest(uint8_t* aFileBody,
                                     int aFileBodyLength)
 {
   if (!mConnected) return;
   int packetLeftSpace = mRemoteMaxPacketLength - kPutRequestHeaderSize;
   if (aFileBodyLength > packetLeftSpace) {
     BT_WARNING("Not allowed such a small MaxPacketLength value");
     return;
   }
 
   // Section 3.3.3 "Put", IrOBEX 1.2
   // [opcode:1][length:2][Headers:var]
-  uint8_t* req = new uint8_t[mRemoteMaxPacketLength];
+  auto req = MakeUnique<uint8_t[]>(mRemoteMaxPacketLength);
 
   int index = 3;
   index += AppendHeaderBody(&req[index], mRemoteMaxPacketLength - index,
                             aFileBody, aFileBodyLength);
 
-  SendObexData(req, ObexRequestCode::Put, index);
-  delete [] req;
+  SendObexData(Move(req), ObexRequestCode::Put, index);
   mSentFileLength += aFileBodyLength;
 }
 
 void
 BluetoothOppManager::SendPutFinalRequest()
 {
   if (!mConnected) return;
 
@@ -1237,21 +1235,20 @@ BluetoothOppManager::SendPutFinalRequest
    * Section 2.2.9, "End-of-Body", IrObex 1.2
    * End-of-Body is used to identify the last chunk of the object body.
    * For most platforms, a PutFinal packet is sent with an zero length
    * End-of-Body header.
    */
 
   // [opcode:1][length:2]
   int index = 3;
-  uint8_t* req = new uint8_t[mRemoteMaxPacketLength];
+  auto req = MakeUnique<uint8_t[]>(mRemoteMaxPacketLength);
   index += AppendHeaderEndOfBody(&req[index]);
 
-  SendObexData(req, ObexRequestCode::PutFinal, index);
-  delete [] req;
+  SendObexData(Move(req), ObexRequestCode::PutFinal, index);
 
   mWaitingToSendPutFinal = false;
 }
 
 void
 BluetoothOppManager::SendDisconnectRequest()
 {
   if (!mConnected) return;
@@ -1363,16 +1360,28 @@ BluetoothOppManager::SendObexData(uint8_
     mLastCommand = aOpcode;
   }
 
   SetObexPacketInfo(aData, aOpcode, aSize);
   mSocket->SendSocketData(new UnixSocketRawData(aData, aSize));
 }
 
 void
+BluetoothOppManager::SendObexData(UniquePtr<uint8_t[]> aData, uint8_t aOpcode,
+                                  int aSize)
+{
+  if (!mIsServer) {
+    mLastCommand = aOpcode;
+  }
+
+  SetObexPacketInfo(aData.get(), aOpcode, aSize);
+  mSocket->SendSocketData(new UnixSocketRawData(Move(aData), aSize));
+}
+
+void
 BluetoothOppManager::FileTransferComplete()
 {
   if (mSendTransferCompleteFlag) {
     return;
   }
 
   nsAutoString connectedDeviceAddressStr;
   AddressToString(mConnectedDeviceAddress, connectedDeviceAddressStr);
--- a/dom/bluetooth/bluez/BluetoothOppManager.h
+++ b/dom/bluetooth/bluez/BluetoothOppManager.h
@@ -7,16 +7,17 @@
 #ifndef mozilla_dom_bluetooth_bluez_BluetoothOppManager_h
 #define mozilla_dom_bluetooth_bluez_BluetoothOppManager_h
 
 #include "BluetoothCommon.h"
 #include "BluetoothProfileManagerBase.h"
 #include "BluetoothSocketObserver.h"
 #include "DeviceStorage.h"
 #include "mozilla/ipc/SocketBase.h"
+#include "mozilla/UniquePtr.h"
 #include "nsCOMArray.h"
 
 class nsIOutputStream;
 class nsIInputStream;
 class nsIVolumeMountLock;
 
 namespace mozilla {
 namespace dom {
@@ -91,16 +92,17 @@ private:
   void AfterOppDisconnected();
   void ValidateFileName();
   bool IsReservedChar(char16_t c);
   void ClearQueue();
   void RetrieveSentFileName();
   void NotifyAboutFileChange();
   bool AcquireSdcardMountLock();
   void SendObexData(uint8_t* aData, uint8_t aOpcode, int aSize);
+  void SendObexData(UniquePtr<uint8_t[]> aData, uint8_t aOpcode, int aSize);
   void AppendBlobToSend(const BluetoothAddress& aDeviceAddress, Blob* aBlob);
   void DiscardBlobsToSend();
   bool ProcessNextBatch();
   void ConnectInternal(const BluetoothAddress& aDeviceAddress);
 
   /**
    * Usually we won't get a full PUT packet in one operation, which means that
    * a packet may be devided into several parts and BluetoothOppManager should
--- a/dom/bluetooth/common/webapi/BluetoothAdapter.cpp
+++ b/dom/bluetooth/common/webapi/BluetoothAdapter.cpp
@@ -1633,18 +1633,17 @@ BluetoothAdapter::DispatchDeviceEvent(co
   DispatchTrustedEvent(event);
 }
 
 void
 BluetoothAdapter::DispatchEmptyEvent(const nsAString& aType)
 {
   RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
 
-  nsresult rv = event->InitEvent(aType, false, false);
-  NS_ENSURE_SUCCESS_VOID(rv);
+  event->InitEvent(aType, false, false);
 
   DispatchTrustedEvent(event);
 }
 
 already_AddRefed<DOMRequest>
 BluetoothAdapter::Connect(BluetoothDevice& aDevice,
                           const Optional<short unsigned int>& aServiceUuid,
                           ErrorResult& aRv)
--- a/dom/bluetooth/common/webapi/BluetoothGatt.cpp
+++ b/dom/bluetooth/common/webapi/BluetoothGatt.cpp
@@ -237,21 +237,19 @@ void
 BluetoothGatt::UpdateConnectionState(BluetoothConnectionState aState)
 {
   BT_LOGR("GATT connection state changes to: %d", int(aState));
   mConnectionState = aState;
 
   // Dispatch connectionstatechanged event to application
   RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
 
-  nsresult rv =
-    event->InitEvent(NS_LITERAL_STRING(GATT_CONNECTION_STATE_CHANGED_ID),
-                     false,
-                     false);
-  NS_ENSURE_SUCCESS_VOID(rv);
+  event->InitEvent(NS_LITERAL_STRING(GATT_CONNECTION_STATE_CHANGED_ID),
+                   false,
+                   false);
 
   DispatchTrustedEvent(event);
 }
 
 void
 BluetoothGatt::HandleServicesDiscovered(const BluetoothValue& aValue)
 {
   MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothGattServiceId);
--- a/dom/events/AnimationEvent.cpp
+++ b/dom/events/AnimationEvent.cpp
@@ -39,17 +39,17 @@ AnimationEvent::Constructor(const Global
                             const nsAString& aType,
                             const AnimationEventInit& aParam,
                             ErrorResult& aRv)
 {
   nsCOMPtr<EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports());
   RefPtr<AnimationEvent> e = new AnimationEvent(t, nullptr, nullptr);
   bool trusted = e->Init(t);
 
-  aRv = e->InitEvent(aType, aParam.mBubbles, aParam.mCancelable);
+  e->InitEvent(aType, aParam.mBubbles, aParam.mCancelable);
 
   InternalAnimationEvent* internalEvent = e->mEvent->AsAnimationEvent();
   internalEvent->animationName = aParam.mAnimationName;
   internalEvent->elapsedTime = aParam.mElapsedTime;
   internalEvent->pseudoElement = aParam.mPseudoElement;
 
   e->SetTrusted(trusted);
   return e.forget();
--- a/dom/events/AsyncEventDispatcher.cpp
+++ b/dom/events/AsyncEventDispatcher.cpp
@@ -35,18 +35,17 @@ AsyncEventDispatcher::AsyncEventDispatch
 }
 
 NS_IMETHODIMP
 AsyncEventDispatcher::Run()
 {
   RefPtr<Event> event = mEvent ? mEvent->InternalDOMEvent() : nullptr;
   if (!event) {
     event = NS_NewDOMEvent(mTarget, nullptr, nullptr);
-    nsresult rv = event->InitEvent(mEventType, mBubbles, false);
-    NS_ENSURE_SUCCESS(rv, rv);
+    event->InitEvent(mEventType, mBubbles, false);
     event->SetTrusted(true);
   }
   if (mOnlyChromeDispatch) {
     MOZ_ASSERT(event->IsTrusted());
     event->GetInternalNSEvent()->mFlags.mOnlyChromeDispatch = true;
   }
   bool dummy;
   mTarget->DispatchEvent(event, &dummy);
--- a/dom/events/ClipboardEvent.cpp
+++ b/dom/events/ClipboardEvent.cpp
@@ -38,32 +38,27 @@ ClipboardEvent::InitClipboardEvent(const
                                    bool aCanBubble,
                                    bool aCancelable,
                                    nsIDOMDataTransfer* aClipboardData)
 {
   nsCOMPtr<DataTransfer> clipboardData = do_QueryInterface(aClipboardData);
   // Null clipboardData is OK
 
   ErrorResult rv;
-  InitClipboardEvent(aType, aCanBubble, aCancelable, clipboardData, rv);
+  InitClipboardEvent(aType, aCanBubble, aCancelable, clipboardData);
 
   return rv.StealNSResult();
 }
 
 void
 ClipboardEvent::InitClipboardEvent(const nsAString& aType, bool aCanBubble,
                                    bool aCancelable,
-                                   DataTransfer* aClipboardData,
-                                   ErrorResult& aError)
+                                   DataTransfer* aClipboardData)
 {
-  aError = Event::InitEvent(aType, aCanBubble, aCancelable);
-  if (aError.Failed()) {
-    return;
-  }
-
+  Event::InitEvent(aType, aCanBubble, aCancelable);
   mEvent->AsClipboardEvent()->clipboardData = aClipboardData;
 }
 
 already_AddRefed<ClipboardEvent>
 ClipboardEvent::Constructor(const GlobalObject& aGlobal,
                             const nsAString& aType,
                             const ClipboardEventInit& aParam,
                             ErrorResult& aRv)
@@ -81,17 +76,17 @@ ClipboardEvent::Constructor(const Global
       // checked properly within DataTransfer.
       clipboardData = new DataTransfer(ToSupports(e), eCopy, false, -1);
       clipboardData->SetData(aParam.mDataType, aParam.mData, aRv);
       NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
     }
   }
 
   e->InitClipboardEvent(aType, aParam.mBubbles, aParam.mCancelable,
-                        clipboardData, aRv);
+                        clipboardData);
   e->SetTrusted(trusted);
   return e.forget();
 }
 
 NS_IMETHODIMP
 ClipboardEvent::GetClipboardData(nsIDOMDataTransfer** aClipboardData)
 {
   NS_IF_ADDREF(*aClipboardData = GetClipboardData());
--- a/dom/events/ClipboardEvent.h
+++ b/dom/events/ClipboardEvent.h
@@ -41,18 +41,17 @@ public:
               const nsAString& aType,
               const ClipboardEventInit& aParam,
               ErrorResult& aRv);
 
   DataTransfer* GetClipboardData();
 
   void InitClipboardEvent(const nsAString& aType, bool aCanBubble,
                           bool aCancelable,
-                          DataTransfer* aClipboardData,
-                          ErrorResult& aError);
+                          DataTransfer* aClipboardData);
 
 protected:
   ~ClipboardEvent() {}
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/events/CommandEvent.cpp
+++ b/dom/events/CommandEvent.cpp
@@ -46,18 +46,17 @@ CommandEvent::GetCommand(nsAString& aCom
 }
 
 NS_IMETHODIMP
 CommandEvent::InitCommandEvent(const nsAString& aTypeArg,
                                bool aCanBubbleArg,
                                bool aCancelableArg,
                                const nsAString& aCommand)
 {
-  nsresult rv = Event::InitEvent(aTypeArg, aCanBubbleArg, aCancelableArg);
-  NS_ENSURE_SUCCESS(rv, rv);
+  Event::InitEvent(aTypeArg, aCanBubbleArg, aCancelableArg);
 
   mEvent->AsCommandEvent()->command = do_GetAtom(aCommand);
   return NS_OK;
 }
 
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/events/CustomEvent.cpp
+++ b/dom/events/CustomEvent.cpp
@@ -61,18 +61,17 @@ CustomEvent::WrapObjectInternal(JSContex
 }
 
 NS_IMETHODIMP
 CustomEvent::InitCustomEvent(const nsAString& aType,
                              bool aCanBubble,
                              bool aCancelable,
                              nsIVariant* aDetail)
 {
-  nsresult rv = Event::InitEvent(aType, aCanBubble, aCancelable);
-  NS_ENSURE_SUCCESS(rv, rv);
+  Event::InitEvent(aType, aCanBubble, aCancelable);
   mDetail = aDetail;
   return NS_OK;
 }
 
 void
 CustomEvent::InitCustomEvent(JSContext* aCx,
                              const nsAString& aType,
                              bool aCanBubble,
@@ -84,17 +83,17 @@ CustomEvent::InitCustomEvent(JSContext* 
   if (nsIXPConnect* xpc = nsContentUtils::XPConnect()) {
     xpc->JSToVariant(aCx, aDetail, getter_AddRefs(detail));
   }
 
   if (!detail) {
     aRv.Throw(NS_ERROR_FAILURE);
     return;
   }
-  aRv = InitCustomEvent(aType, aCanBubble, aCancelable, detail);
+  InitCustomEvent(aType, aCanBubble, aCancelable, detail);
 }
 
 NS_IMETHODIMP
 CustomEvent::GetDetail(nsIVariant** aDetail)
 {
   NS_IF_ADDREF(*aDetail = mDetail);
   return NS_OK;
 }
--- a/dom/events/DOMEventTargetHelper.cpp
+++ b/dom/events/DOMEventTargetHelper.cpp
@@ -258,18 +258,17 @@ DOMEventTargetHelper::DispatchEvent(nsID
   *aRetVal = (status != nsEventStatus_eConsumeNoDefault);
   return rv;
 }
 
 nsresult
 DOMEventTargetHelper::DispatchTrustedEvent(const nsAString& aEventName)
 {
   RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
-  nsresult rv = event->InitEvent(aEventName, false, false);
-  NS_ENSURE_SUCCESS(rv, rv);
+  event->InitEvent(aEventName, false, false);
 
   return DispatchTrustedEvent(event);
 }
 
 nsresult
 DOMEventTargetHelper::DispatchTrustedEvent(nsIDOMEvent* event)
 {
   event->SetTrusted(true);
--- a/dom/events/DeviceMotionEvent.cpp
+++ b/dom/events/DeviceMotionEvent.cpp
@@ -28,23 +28,19 @@ NS_INTERFACE_MAP_END_INHERITING(Event)
 void
 DeviceMotionEvent::InitDeviceMotionEvent(
                      const nsAString& aType,
                      bool aCanBubble,
                      bool aCancelable,
                      const DeviceAccelerationInit& aAcceleration,
                      const DeviceAccelerationInit& aAccelIncludingGravity,
                      const DeviceRotationRateInit& aRotationRate,
-                     Nullable<double> aInterval,
-                     ErrorResult& aRv)
+                     Nullable<double> aInterval)
 {
-  aRv = Event::InitEvent(aType, aCanBubble, aCancelable);
-  if (aRv.Failed()) {
-    return;
-  }
+  Event::InitEvent(aType, aCanBubble, aCancelable);
 
   mAcceleration = new DeviceAcceleration(this, aAcceleration.mX,
                                          aAcceleration.mY,
                                          aAcceleration.mZ);
 
   mAccelerationIncludingGravity =
     new DeviceAcceleration(this, aAccelIncludingGravity.mX,
                            aAccelIncludingGravity.mY,
@@ -59,20 +55,17 @@ DeviceMotionEvent::InitDeviceMotionEvent
 already_AddRefed<DeviceMotionEvent>
 DeviceMotionEvent::Constructor(const GlobalObject& aGlobal,
                                const nsAString& aType,
                                const DeviceMotionEventInit& aEventInitDict,
                                ErrorResult& aRv)
 {
   nsCOMPtr<EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports());
   RefPtr<DeviceMotionEvent> e = new DeviceMotionEvent(t, nullptr, nullptr);
-  aRv = e->InitEvent(aType, aEventInitDict.mBubbles, aEventInitDict.mCancelable);
-  if (aRv.Failed()) {
-    return nullptr;
-  }
+  e->InitEvent(aType, aEventInitDict.mBubbles, aEventInitDict.mCancelable);
   bool trusted = e->Init(t);
 
   e->mAcceleration = new DeviceAcceleration(e,
     aEventInitDict.mAcceleration.mX,
     aEventInitDict.mAcceleration.mY,
     aEventInitDict.mAcceleration.mZ);
 
   e->mAccelerationIncludingGravity = new DeviceAcceleration(e,
--- a/dom/events/DeviceMotionEvent.h
+++ b/dom/events/DeviceMotionEvent.h
@@ -123,18 +123,17 @@ public:
 
   void InitDeviceMotionEvent(
          const nsAString& aType,
          bool aCanBubble,
          bool aCancelable,
          const DeviceAccelerationInit& aAcceleration,
          const DeviceAccelerationInit& aAccelerationIncludingGravity,
          const DeviceRotationRateInit& aRotationRate,
-         Nullable<double> aInterval,
-         ErrorResult& aRv);
+         Nullable<double> aInterval);
 
   static already_AddRefed<DeviceMotionEvent>
   Constructor(const GlobalObject& aGlobal,
               const nsAString& aType,
               const DeviceMotionEventInit& aEventInitDict,
               ErrorResult& aRv);
 
 protected:
--- a/dom/events/Event.cpp
+++ b/dom/events/Event.cpp
@@ -409,17 +409,17 @@ already_AddRefed<Event>
 Event::Constructor(const GlobalObject& aGlobal,
                    const nsAString& aType,
                    const EventInit& aParam,
                    ErrorResult& aRv)
 {
   nsCOMPtr<mozilla::dom::EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports());
   RefPtr<Event> e = new Event(t, nullptr, nullptr);
   bool trusted = e->Init(t);
-  aRv = e->InitEvent(aType, aParam.mBubbles, aParam.mCancelable);
+  e->InitEvent(aType, aParam.mBubbles, aParam.mCancelable);
   e->SetTrusted(trusted);
   return e.forget();
 }
 
 uint16_t
 Event::EventPhase() const
 {
   // Note, remember to check that this works also
@@ -567,23 +567,23 @@ Event::SetEventType(const nsAString& aEv
                                              &(mEvent->mMessage));
   } else {
     mEvent->userType = nullptr;
     mEvent->mMessage = eUnidentifiedEvent;
     mEvent->typeString = aEventTypeArg;
   }
 }
 
-NS_IMETHODIMP
+void
 Event::InitEvent(const nsAString& aEventTypeArg,
                  bool aCanBubbleArg,
                  bool aCancelableArg)
 {
   // Make sure this event isn't already being dispatched.
-  NS_ENSURE_TRUE(!mEvent->mFlags.mIsBeingDispatched, NS_OK);
+  NS_ENSURE_TRUE_VOID(!mEvent->mFlags.mIsBeingDispatched);
 
   if (IsTrusted()) {
     // Ensure the caller is permitted to dispatch trusted DOM events.
     if (!nsContentUtils::ThreadsafeIsCallerChrome()) {
       SetTrusted(false);
     }
   }
 
@@ -595,17 +595,16 @@ Event::InitEvent(const nsAString& aEvent
   mEvent->mFlags.mDefaultPrevented = false;
   mEvent->mFlags.mDefaultPreventedByContent = false;
   mEvent->mFlags.mDefaultPreventedByChrome = false;
 
   // Clearing the old targets, so that the event is targeted correctly when
   // re-dispatching it.
   mEvent->target = nullptr;
   mEvent->originalTarget = nullptr;
-  return NS_OK;
 }
 
 NS_IMETHODIMP
 Event::DuplicatePrivateData()
 {
   NS_ASSERTION(mEvent, "No WidgetEvent for Event duplication!");
   if (mEventIsInternal) {
     return NS_OK;
@@ -1185,18 +1184,17 @@ Event::Deserialize(const IPC::Message* a
   NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &bubbles), false);
 
   bool cancelable = false;
   NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &cancelable), false);
 
   bool trusted = false;
   NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &trusted), false);
 
-  nsresult rv = InitEvent(type, bubbles, cancelable);
-  NS_ENSURE_SUCCESS(rv, false);
+  InitEvent(type, bubbles, cancelable);
   SetTrusted(trusted);
 
   return true;
 }
 
 NS_IMETHODIMP_(void)
 Event::SetOwner(mozilla::dom::EventTarget* aOwner)
 {
--- a/dom/events/Event.h
+++ b/dom/events/Event.h
@@ -201,22 +201,16 @@ public:
 
   bool IsSynthesized() const
   {
     return mEvent->mFlags.mIsSynthesizedForTests;
   }
 
   double TimeStamp() const;
 
-  void InitEvent(const nsAString& aType, bool aBubbles, bool aCancelable,
-                 ErrorResult& aRv)
-  {
-    aRv = InitEvent(aType, aBubbles, aCancelable);
-  }
-
   EventTarget* GetOriginalTarget() const;
   EventTarget* GetExplicitOriginalTarget() const;
   EventTarget* GetComposedTarget() const;
 
   bool GetPreventDefault() const;
 
   /**
    * @param aCalledByDefaultHandler     Should be true when this is called by
@@ -307,17 +301,17 @@ private:
   NS_IMETHOD GetCurrentTarget(nsIDOMEventTarget** aCurrentTarget) override { return _to GetCurrentTarget(aCurrentTarget); } \
   NS_IMETHOD GetEventPhase(uint16_t* aEventPhase) override { return _to GetEventPhase(aEventPhase); } \
   NS_IMETHOD GetBubbles(bool* aBubbles) override { return _to GetBubbles(aBubbles); } \
   NS_IMETHOD GetCancelable(bool* aCancelable) override { return _to GetCancelable(aCancelable); } \
   NS_IMETHOD GetTimeStamp(DOMTimeStamp* aTimeStamp) override { return _to GetTimeStamp(aTimeStamp); } \
   NS_IMETHOD StopPropagation(void) override { return _to StopPropagation(); } \
   NS_IMETHOD StopCrossProcessForwarding(void) override { return _to StopCrossProcessForwarding(); } \
   NS_IMETHOD PreventDefault(void) override { return _to PreventDefault(); } \
-  NS_IMETHOD InitEvent(const nsAString& eventTypeArg, bool canBubbleArg, bool cancelableArg) override { return _to InitEvent(eventTypeArg, canBubbleArg, cancelableArg); } \
+  void InitEvent(const nsAString& eventTypeArg, bool canBubbleArg, bool cancelableArg) override { _to InitEvent(eventTypeArg, canBubbleArg, cancelableArg); } \
   NS_IMETHOD GetDefaultPrevented(bool* aDefaultPrevented) override { return _to GetDefaultPrevented(aDefaultPrevented); } \
   NS_IMETHOD StopImmediatePropagation(void) override { return _to StopImmediatePropagation(); } \
   NS_IMETHOD GetOriginalTarget(nsIDOMEventTarget** aOriginalTarget) override { return _to GetOriginalTarget(aOriginalTarget); } \
   NS_IMETHOD GetExplicitOriginalTarget(nsIDOMEventTarget** aExplicitOriginalTarget) override { return _to GetExplicitOriginalTarget(aExplicitOriginalTarget); } \
   NS_IMETHOD GetPreventDefault(bool* aRetval) override { return _to GetPreventDefault(aRetval); } \
   NS_IMETHOD GetIsTrusted(bool* aIsTrusted) override { return _to GetIsTrusted(aIsTrusted); } \
   NS_IMETHOD SetTarget(nsIDOMEventTarget* aTarget) override { return _to SetTarget(aTarget); } \
   NS_IMETHOD_(bool) IsDispatchStopped(void) override { return _to IsDispatchStopped(); } \
--- a/dom/events/IMEContentObserver.cpp
+++ b/dom/events/IMEContentObserver.cpp
@@ -1400,17 +1400,18 @@ IMEContentObserver::TryToFlushPendingNot
 {
   if (!mQueuedSender || mSendingNotification != NOTIFY_IME_OF_NOTHING) {
     return;
   }
 
   MOZ_LOG(sIMECOLog, LogLevel::Debug,
     ("IMECO: 0x%p IMEContentObserver::TryToFlushPendingNotifications(), "
      "performing queued IMENotificationSender forcibly", this));
-  mQueuedSender->Run();
+  RefPtr<IMENotificationSender> queuedSender = mQueuedSender;
+  queuedSender->Run();
 }
 
 /******************************************************************************
  * mozilla::IMEContentObserver::AChangeEvent
  ******************************************************************************/
 
 bool
 IMEContentObserver::AChangeEvent::CanNotifyIME(
--- a/dom/events/MessageEvent.cpp
+++ b/dom/events/MessageEvent.cpp
@@ -126,21 +126,17 @@ MessageEvent::Constructor(const GlobalOb
 /* static */ already_AddRefed<MessageEvent>
 MessageEvent::Constructor(EventTarget* aEventTarget,
                           const nsAString& aType,
                           const MessageEventInit& aParam,
                           ErrorResult& aRv)
 {
   RefPtr<MessageEvent> event = new MessageEvent(aEventTarget, nullptr, nullptr);
 
-  aRv = event->InitEvent(aType, aParam.mBubbles, aParam.mCancelable);
-  if (aRv.Failed()) {
-    return nullptr;
-  }
-
+  event->InitEvent(aType, aParam.mBubbles, aParam.mCancelable);
   bool trusted = event->Init(aEventTarget);
   event->SetTrusted(trusted);
 
   event->mData = aParam.mData;
 
   mozilla::HoldJSObjects(event.get());
 
   if (aParam.mOrigin.WasPassed()) {
@@ -177,43 +173,36 @@ NS_IMETHODIMP
 MessageEvent::InitMessageEvent(const nsAString& aType,
                                bool aCanBubble,
                                bool aCancelable,
                                JS::Handle<JS::Value> aData,
                                const nsAString& aOrigin,
                                const nsAString& aLastEventId,
                                nsIDOMWindow* aSource)
 {
-  nsresult rv = Event::InitEvent(aType, aCanBubble, aCancelable);
-  NS_ENSURE_SUCCESS(rv, rv);
-
+  Event::InitEvent(aType, aCanBubble, aCancelable);
   mData = aData;
   mozilla::HoldJSObjects(this);
   mOrigin = aOrigin;
   mLastEventId = aLastEventId;
   mWindowSource = aSource;
 
   return NS_OK;
 }
 
 void
 MessageEvent::InitMessageEvent(JSContext* aCx, const nsAString& aType,
                                bool aCanBubble, bool aCancelable,
                                JS::Handle<JS::Value> aData,
                                const nsAString& aOrigin,
                                const nsAString& aLastEventId,
                                const Nullable<WindowProxyOrMessagePort>& aSource,
-                               const Nullable<Sequence<OwningNonNull<MessagePort>>>& aPorts,
-                               ErrorResult& aRv)
+                               const Nullable<Sequence<OwningNonNull<MessagePort>>>& aPorts)
 {
-  aRv = Event::InitEvent(aType, aCanBubble, aCancelable);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
+  Event::InitEvent(aType, aCanBubble, aCancelable);
   mData = aData;
   mozilla::HoldJSObjects(this);
   mOrigin = aOrigin;
   mLastEventId = aLastEventId;
 
   mWindowSource = nullptr;
   mPortSource = nullptr;
 
--- a/dom/events/MessageEvent.h
+++ b/dom/events/MessageEvent.h
@@ -78,18 +78,17 @@ public:
               const nsAString& aType,
               const MessageEventInit& aEventInit,
               ErrorResult& aRv);
 
   void InitMessageEvent(JSContext* aCx, const nsAString& aType, bool aCanBubble,
                         bool aCancelable, JS::Handle<JS::Value> aData,
                         const nsAString& aOrigin, const nsAString& aLastEventId,
                         const Nullable<WindowProxyOrMessagePort>& aSource,
-                        const Nullable<Sequence<OwningNonNull<MessagePort>>>& aPorts,
-                        ErrorResult& aRv);
+                        const Nullable<Sequence<OwningNonNull<MessagePort>>>& aPorts);
 
 protected:
   ~MessageEvent();
 
 private:
   JS::Heap<JS::Value> mData;
   nsString mOrigin;
   nsString mLastEventId;
--- a/dom/events/MutationEvent.cpp
+++ b/dom/events/MutationEvent.cpp
@@ -91,18 +91,17 @@ MutationEvent::InitMutationEvent(const n
                                  bool aCanBubbleArg,
                                  bool aCancelableArg,
                                  nsIDOMNode* aRelatedNodeArg,
                                  const nsAString& aPrevValueArg,
                                  const nsAString& aNewValueArg,
                                  const nsAString& aAttrNameArg,
                                  uint16_t aAttrChangeArg)
 {
-  nsresult rv = Event::InitEvent(aTypeArg, aCanBubbleArg, aCancelableArg);
-  NS_ENSURE_SUCCESS(rv, rv);
+  Event::InitEvent(aTypeArg, aCanBubbleArg, aCancelableArg);
 
   InternalMutationEvent* mutation = mEvent->AsMutationEvent();
   mutation->mRelatedNode = aRelatedNodeArg;
   if (!aPrevValueArg.IsEmpty())
     mutation->mPrevAttrValue = do_GetAtom(aPrevValueArg);
   if (!aNewValueArg.IsEmpty())
     mutation->mNewAttrValue = do_GetAtom(aNewValueArg);
   if (!aAttrNameArg.IsEmpty()) {
--- a/dom/events/SpeechRecognitionError.cpp
+++ b/dom/events/SpeechRecognitionError.cpp
@@ -24,31 +24,27 @@ already_AddRefed<SpeechRecognitionError>
 SpeechRecognitionError::Constructor(const GlobalObject& aGlobal,
                                     const nsAString& aType,
                                     const SpeechRecognitionErrorInit& aParam,
                                     ErrorResult& aRv)
 {
   nsCOMPtr<mozilla::dom::EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports());
   RefPtr<SpeechRecognitionError> e = new SpeechRecognitionError(t, nullptr, nullptr);
   bool trusted = e->Init(t);
-  e->InitSpeechRecognitionError(aType, aParam.mBubbles, aParam.mCancelable, aParam.mError, aParam.mMessage, aRv);
+  e->InitSpeechRecognitionError(aType, aParam.mBubbles, aParam.mCancelable, aParam.mError, aParam.mMessage);
   e->SetTrusted(trusted);
   return e.forget();
 }
 
 void
 SpeechRecognitionError::InitSpeechRecognitionError(const nsAString& aType,
                                                    bool aCanBubble,
                                                    bool aCancelable,
                                                    SpeechRecognitionErrorCode aError,
-                                                   const nsAString& aMessage,
-                                                   ErrorResult& aRv)
+                                                   const nsAString& aMessage)
 {
-  aRv = Event::InitEvent(aType, aCanBubble, aCancelable);
-  NS_ENSURE_TRUE_VOID(!aRv.Failed());
-
+  Event::InitEvent(aType, aCanBubble, aCancelable);
   mError = aError;
   mMessage = aMessage;
-  return;
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/events/SpeechRecognitionError.h
+++ b/dom/events/SpeechRecognitionError.h
@@ -44,18 +44,17 @@ public:
     return mError;
   }
 
   void
   InitSpeechRecognitionError(const nsAString& aType,
                              bool aCanBubble,
                              bool aCancelable,
                              SpeechRecognitionErrorCode aError,
-                             const nsAString& aMessage,
-                             ErrorResult& aRv);
+                             const nsAString& aMessage);
 
 protected:
   SpeechRecognitionErrorCode mError;
   nsString mMessage;
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/events/StorageEvent.cpp
+++ b/dom/events/StorageEvent.cpp
@@ -80,24 +80,19 @@ StorageEvent::Constructor(const GlobalOb
 }
 
 void
 StorageEvent::InitStorageEvent(const nsAString& aType, bool aCanBubble,
                                bool aCancelable, const nsAString& aKey,
                                const nsAString& aOldValue,
                                const nsAString& aNewValue,
                                const nsAString& aURL,
-                               DOMStorage* aStorageArea,
-                               ErrorResult& aRv)
+                               DOMStorage* aStorageArea)
 {
-  aRv = InitEvent(aType, aCanBubble, aCancelable);
-  if (aRv.Failed()) {
-    return;
-  }
-
+  InitEvent(aType, aCanBubble, aCancelable);
   mKey = aKey;
   mOldValue = aOldValue;
   mNewValue = aNewValue;
   mUrl = aURL;
   mStorageArea = aStorageArea;
 }
 
 } // namespace dom
--- a/dom/events/StorageEvent.h
+++ b/dom/events/StorageEvent.h
@@ -52,18 +52,17 @@ public:
   Constructor(const GlobalObject& aGlobal, const nsAString& aType,
               const StorageEventInit& aEventInitDict, ErrorResult& aRv);
 
   void InitStorageEvent(const nsAString& aType, bool aCanBubble,
                         bool aCancelable, const nsAString& aKey,
                         const nsAString& aOldValue,
                         const nsAString& aNewValue,
                         const nsAString& aURL,
-                        DOMStorage* aStorageArea,
-                        ErrorResult& aRv);
+                        DOMStorage* aStorageArea);
 
   void GetKey(nsString& aRetVal) const
   {
     aRetVal = mKey;
   }
 
   void GetOldValue(nsString& aRetVal) const
   {
--- a/dom/events/TouchEvent.cpp
+++ b/dom/events/TouchEvent.cpp
@@ -97,24 +97,19 @@ TouchEvent::InitTouchEvent(const nsAStri
                            nsIDOMWindow* aView,
                            int32_t aDetail,
                            bool aCtrlKey,
                            bool aAltKey,
                            bool aShiftKey,
                            bool aMetaKey,
                            TouchList* aTouches,
                            TouchList* aTargetTouches,
-                           TouchList* aChangedTouches,
-                           ErrorResult& aRv)
+                           TouchList* aChangedTouches)
 {
-  aRv = UIEvent::InitUIEvent(aType, aCanBubble, aCancelable, aView, aDetail);
-  if (aRv.Failed()) {
-    return;
-  }
-
+  UIEvent::InitUIEvent(aType, aCanBubble, aCancelable, aView, aDetail);
   mEvent->AsInputEvent()->InitBasicModifiers(aCtrlKey, aAltKey,
                                              aShiftKey, aMetaKey);
   mTouches = aTouches;
   mTargetTouches = aTargetTouches;
   mChangedTouches = aChangedTouches;
 }
 
 TouchList*
--- a/dom/events/TouchEvent.h
+++ b/dom/events/TouchEvent.h
@@ -110,18 +110,17 @@ public:
                       nsIDOMWindow* aView,
                       int32_t aDetail,
                       bool aCtrlKey,
                       bool aAltKey,
                       bool aShiftKey,
                       bool aMetaKey,
                       TouchList* aTouches,
                       TouchList* aTargetTouches,
-                      TouchList* aChangedTouches,
-                      ErrorResult& aRv);
+                      TouchList* aChangedTouches);
 
   static bool PrefEnabled(JSContext* aCx = nullptr,
                           JSObject* aGlobal = nullptr);
 
 protected:
   ~TouchEvent() {}
 
   RefPtr<TouchList> mTouches;
--- a/dom/events/TransitionEvent.cpp
+++ b/dom/events/TransitionEvent.cpp
@@ -39,17 +39,17 @@ TransitionEvent::Constructor(const Globa
                              const nsAString& aType,
                              const TransitionEventInit& aParam,
                              ErrorResult& aRv)
 {
   nsCOMPtr<EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports());
   RefPtr<TransitionEvent> e = new TransitionEvent(t, nullptr, nullptr);
   bool trusted = e->Init(t);
 
-  aRv = e->InitEvent(aType, aParam.mBubbles, aParam.mCancelable);
+  e->InitEvent(aType, aParam.mBubbles, aParam.mCancelable);
 
   InternalTransitionEvent* internalEvent = e->mEvent->AsTransitionEvent();
   internalEvent->propertyName = aParam.mPropertyName;
   internalEvent->elapsedTime = aParam.mElapsedTime;
   internalEvent->pseudoElement = aParam.mPseudoElement;
 
   e->SetTrusted(trusted);
   return e.forget();
--- a/dom/events/UIEvent.cpp
+++ b/dom/events/UIEvent.cpp
@@ -156,19 +156,17 @@ UIEvent::InitUIEvent(const nsAString& ty
                      bool cancelableArg,
                      nsIDOMWindow* viewArg,
                      int32_t detailArg)
 {
   if (viewArg) {
     nsCOMPtr<nsPIDOMWindow> view = do_QueryInterface(viewArg);
     NS_ENSURE_TRUE(view, NS_ERROR_INVALID_ARG);
   }
-  nsresult rv = Event::InitEvent(typeArg, canBubbleArg, cancelableArg);
-  NS_ENSURE_SUCCESS(rv, rv);
-  
+  Event::InitEvent(typeArg, canBubbleArg, cancelableArg);
   mDetail = detailArg;
   mView = viewArg;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 UIEvent::GetPageX(int32_t* aPageX)
--- a/dom/indexedDB/IDBEvents.cpp
+++ b/dom/indexedDB/IDBEvents.cpp
@@ -30,20 +30,19 @@ const char16_t* kVersionChangeEventType 
 already_AddRefed<nsIDOMEvent>
 CreateGenericEvent(EventTarget* aOwner,
                    const nsDependentString& aType,
                    Bubbles aBubbles,
                    Cancelable aCancelable)
 {
   RefPtr<Event> event = new Event(aOwner, nullptr, nullptr);
 
-  MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
-    event->InitEvent(aType,
-                     aBubbles == eDoesBubble ? true : false,
-                     aCancelable == eCancelable ? true : false)));
+  event->InitEvent(aType,
+                   aBubbles == eDoesBubble ? true : false,
+                   aCancelable == eCancelable ? true : false);
 
   event->SetTrusted(true);
 
   return event.forget();
 }
 
 // static
 already_AddRefed<IDBVersionChangeEvent>
@@ -53,17 +52,17 @@ IDBVersionChangeEvent::CreateInternal(Ev
                                       Nullable<uint64_t> aNewVersion)
 {
   RefPtr<IDBVersionChangeEvent> event =
     new IDBVersionChangeEvent(aOwner, aOldVersion);
   if (!aNewVersion.IsNull()) {
     event->mNewVersion.SetValue(aNewVersion.Value());
   }
 
-  MOZ_ALWAYS_TRUE(NS_SUCCEEDED(event->InitEvent(aType, false, false)));
+  event->InitEvent(aType, false, false);
 
   event->SetTrusted(true);
 
   return event.forget();
 }
 
 already_AddRefed<IDBVersionChangeEvent>
 IDBVersionChangeEvent::Constructor(const GlobalObject& aGlobal,
--- a/dom/indexedDB/test/mochitest.ini
+++ b/dom/indexedDB/test/mochitest.ini
@@ -177,17 +177,17 @@ skip-if = (buildapp == 'b2g' && toolkit 
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
 [test_file_array.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
 [test_file_cross_database_copying.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
 [test_file_delete.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
 [test_file_os_delete.html]
-skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
+skip-if = e10s || (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116, Bug 1183959 for e10s
 [test_file_put_get_object.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
 [test_file_put_get_values.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
 [test_file_replace.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
 [test_file_resurrection_delete.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
--- a/dom/interfaces/events/nsIDOMAnimationEvent.idl
+++ b/dom/interfaces/events/nsIDOMAnimationEvent.idl
@@ -6,14 +6,14 @@
 #include "nsIDOMEvent.idl"
 
 /**
  * Animation events are defined in:
  * http://www.w3.org/TR/css3-animations/#animation-events-
  * http://dev.w3.org/csswg/css3-animations/#animation-events-
  */
 
-[builtinclass, uuid(b1bea1bc-689b-4e07-8cbc-ef342725f9a6)]
+[builtinclass, uuid(772c7069-3f7d-42cf-97ab-b32f1c0b83da)]
 interface nsIDOMAnimationEvent : nsIDOMEvent {
   readonly attribute DOMString          animationName;
   readonly attribute float              elapsedTime;
   readonly attribute DOMString          pseudoElement;
 };
--- a/dom/interfaces/events/nsIDOMBeforeUnloadEvent.idl
+++ b/dom/interfaces/events/nsIDOMBeforeUnloadEvent.idl
@@ -10,17 +10,17 @@
  * sent to handlers of the "beforeunload" event. This event is
  * non-standard. Interface derived from Microsoft IE's event
  * implementation.
  *
  * http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/events.asp
  *
  */
 
-[builtinclass, uuid(ee7b8943-440e-4cc3-b25e-c17c8a821d8b)]
+[builtinclass, uuid(96abf41b-32a8-4ff6-a0d6-4ade4ddebf89)]
 interface nsIDOMBeforeUnloadEvent : nsIDOMEvent
 {
   /**
    * Attribute used to pass back a return value from a beforeunload
    * handler
    */
            attribute DOMString          returnValue;
 };
--- a/dom/interfaces/events/nsIDOMClipboardEvent.idl
+++ b/dom/interfaces/events/nsIDOMClipboardEvent.idl
@@ -3,17 +3,17 @@
  * 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 "domstubs.idl"
 #include "nsIDOMEvent.idl"
 
 interface nsIDOMDataTransfer;
 
-[builtinclass, uuid(8D92944A-F2E5-41F4-9CF3-D85043B90CAC)]
+[builtinclass, uuid(4ef84980-52c2-425c-b41a-2ee75ec5d497)]
 interface nsIDOMClipboardEvent : nsIDOMEvent
 {
   readonly attribute nsIDOMDataTransfer clipboardData;
 
   // The constructor must be used from script to initialize
   // clipboard events.
   [noscript] void initClipboardEvent(in DOMString typeArg,
                                      in boolean canBubbleArg,
--- a/dom/interfaces/events/nsIDOMCommandEvent.idl
+++ b/dom/interfaces/events/nsIDOMCommandEvent.idl
@@ -1,16 +1,16 @@
 /* -*- 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/. */
 
 #include "nsIDOMEvent.idl"
 
-[builtinclass, uuid(3fdc07cb-3b2e-4c6e-a054-008a4f302202)]
+[builtinclass, uuid(7efbe68a-811a-4159-801c-226948cfd08f)]
 interface nsIDOMCommandEvent : nsIDOMEvent
 {
   readonly attribute DOMString command;
 
   void initCommandEvent(in DOMString typeArg,
                         in boolean canBubbleArg,
                         in boolean canCancelArg,
                         in DOMString command);
--- a/dom/interfaces/events/nsIDOMCompositionEvent.idl
+++ b/dom/interfaces/events/nsIDOMCompositionEvent.idl
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=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 "nsIDOMUIEvent.idl"
 
-[builtinclass, uuid(ef545b90-a5f4-471c-b4f8-03b5e0f6fda2)]
+[builtinclass, uuid(5adfd99b-d3c7-4c6d-92d1-527264a71b50)]
 interface nsIDOMCompositionEvent : nsIDOMUIEvent
 {
   readonly attribute DOMString data;
   readonly attribute DOMString locale;
 
   void initCompositionEvent(in DOMString typeArg,
                             in boolean canBubbleArg,
                             in boolean cancelableArg,
--- a/dom/interfaces/events/nsIDOMCustomEvent.idl
+++ b/dom/interfaces/events/nsIDOMCustomEvent.idl
@@ -1,17 +1,17 @@
 /* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
 /* 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 "nsIDOMEvent.idl"
 interface nsIVariant;
 
-[builtinclass, uuid(b56ae6ca-c822-489e-be71-2a9f3c56082e)]
+[builtinclass, uuid(55fa3a13-4812-45a7-98b7-3be6cec2df43)]
 interface nsIDOMCustomEvent : nsIDOMEvent
 {
 
   readonly attribute nsIVariant detail;
 
   void initCustomEvent(in DOMString  typeArg, 
                        in boolean    canBubbleArg, 
                        in boolean    cancelableArg, 
--- a/dom/interfaces/events/nsIDOMDataContainerEvent.idl
+++ b/dom/interfaces/events/nsIDOMDataContainerEvent.idl
@@ -1,17 +1,17 @@
 /* -*- 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 "nsIDOMEvent.idl"
 #include "nsIVariant.idl"
 
-[builtinclass, uuid(dc6b39da-87ff-4b6f-b065-b52602602e06)]
+[builtinclass, uuid(31ceb43e-5f49-43bf-9a18-3b60a535c814)]
 interface nsIDOMDataContainerEvent : nsIDOMEvent
 {
   /**
    * Return the data associated with the given key.
    *
    * @param  key  the key
    * @return      the data associated with the key
    */
--- a/dom/interfaces/events/nsIDOMDragEvent.idl
+++ b/dom/interfaces/events/nsIDOMDragEvent.idl
@@ -3,17 +3,17 @@
  * 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 "domstubs.idl"
 #include "nsIDOMMouseEvent.idl"
 
 interface nsIDOMDataTransfer;
 
-[builtinclass, uuid(4d0fe952-7ca7-4730-a163-4454e39ed187)]
+[builtinclass, uuid(12aabbe9-7c70-4bf9-b133-a8d6a120679e)]
 interface nsIDOMDragEvent : nsIDOMMouseEvent
 {
   readonly attribute nsIDOMDataTransfer dataTransfer;
 
   void initDragEvent(in DOMString typeArg,
                      in boolean canBubbleArg,
                      in boolean cancelableArg,
                      in nsIDOMWindow aView,
--- a/dom/interfaces/events/nsIDOMEvent.idl
+++ b/dom/interfaces/events/nsIDOMEvent.idl
@@ -35,17 +35,17 @@ class EventTarget;
  * The nsIDOMEvent interface is the primary datatype for all events in
  * the Document Object Model.
  *
  * For more information on this interface please see 
  * http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html and
  * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
  */
 
-[builtinclass, uuid(63857daf-c084-4ea6-a8b9-6812e3176991)]
+[builtinclass, uuid(f58daacf-4d1a-4002-8fd7-06b614dfbcf6)]
 interface nsIDOMEvent : nsISupports
 {
   // PhaseType
   /**
    * The event isn't being dispatched.
    */
   const unsigned short      NONE                           = 0;
   /**
@@ -156,16 +156,17 @@ interface nsIDOMEvent : nsISupports
    *                       recommended that third parties adding their 
    *                       own events use their own prefix to avoid 
    *                       confusion and lessen the probability of 
    *                       conflicts with other new events.
    * @param   canBubbleArg Specifies whether or not the event can bubble.
    * @param   cancelableArg Specifies whether or not the event's default 
    *                        action can be prevented.
    */
+  [notxpcom,nostdcall]
   void                      initEvent(in DOMString eventTypeArg,
                                       in boolean canBubbleArg,
                                       in boolean cancelableArg);
 
   /**
    * Used to indicate whether preventDefault() has been called for this event.
    */
   readonly attribute boolean defaultPrevented;
--- a/dom/interfaces/events/nsIDOMFocusEvent.idl
+++ b/dom/interfaces/events/nsIDOMFocusEvent.idl
@@ -1,12 +1,12 @@
 /* -*- 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/. */
 
 #include "nsIDOMUIEvent.idl"
 
-[builtinclass, uuid(4faecbd6-1bcd-42d8-bc66-ec6b95050063)]
+[builtinclass, uuid(f2606aee-1801-4e4c-9700-af99e435c02c)]
 interface nsIDOMFocusEvent : nsIDOMUIEvent
 {
   readonly attribute nsIDOMEventTarget  relatedTarget;
 };
--- a/dom/interfaces/events/nsIDOMKeyEvent.idl
+++ b/dom/interfaces/events/nsIDOMKeyEvent.idl
@@ -1,16 +1,16 @@
 /* -*- 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/. */
 
 #include "nsIDOMUIEvent.idl"
 
-[builtinclass, uuid(d2b3e35f-8627-4732-a92d-cda54c8f8054)]
+[builtinclass, uuid(f4082a63-73c0-49ad-86e0-c406a54573f7)]
 interface nsIDOMKeyEvent : nsIDOMUIEvent
 {
   const unsigned long DOM_VK_CANCEL         = 0x03;
   const unsigned long DOM_VK_HELP           = 0x06;
   const unsigned long DOM_VK_BACK_SPACE     = 0x08;
   const unsigned long DOM_VK_TAB            = 0x09;
   const unsigned long DOM_VK_CLEAR          = 0x0C;
   const unsigned long DOM_VK_RETURN         = 0x0D;
--- a/dom/interfaces/events/nsIDOMMessageEvent.idl
+++ b/dom/interfaces/events/nsIDOMMessageEvent.idl
@@ -7,17 +7,17 @@
 
 /**
  * The nsIDOMMessageEvent interface is used for server-sent events and for
  * cross-domain messaging.
  *
  * For more information on this interface, please see
  * http://www.whatwg.org/specs/web-apps/current-work/#messageevent
  */
-[builtinclass, uuid(bb869a03-5fc0-4a1b-838a-342e5025fc05)]
+[builtinclass, uuid(4408a2f5-614f-40a3-8786-e16bd3f74e32)]
 interface nsIDOMMessageEvent : nsIDOMEvent
 {
   /**
    * Custom string data associated with this event.
    */
   [implicit_jscontext]
   readonly attribute jsval data;
   
--- a/dom/interfaces/events/nsIDOMMouseEvent.idl
+++ b/dom/interfaces/events/nsIDOMMouseEvent.idl
@@ -8,17 +8,17 @@
 /**
  * The nsIDOMMouseEvent interface is the datatype for all mouse events
  * in the Document Object Model.
  *
  * For more information on this interface please see
  * http://www.w3.org/TR/DOM-Level-2-Events/
  */
 
-[builtinclass, uuid(df068636-9a5b-11e3-b71f-2c27d728e7f9)]
+[builtinclass, uuid(dbebc4be-75c9-47ca-aee8-0a8b4ae14a87)]
 interface nsIDOMMouseEvent : nsIDOMUIEvent
 {
   readonly attribute long               screenX;
   readonly attribute long               screenY;
 
   readonly attribute long               mozMovementX;
   readonly attribute long               mozMovementY;
 
--- a/dom/interfaces/events/nsIDOMMouseScrollEvent.idl
+++ b/dom/interfaces/events/nsIDOMMouseScrollEvent.idl
@@ -1,16 +1,16 @@
 /* -*- 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/. */
 
 #include "nsIDOMMouseEvent.idl"
 
-[builtinclass, uuid(2bce5c03-5bed-4c22-8a6a-a3ac8f5563d7)]
+[builtinclass, uuid(00404ebe-4598-4c4e-a60a-d7491922f9db)]
 interface nsIDOMMouseScrollEvent : nsIDOMMouseEvent
 {
   const long HORIZONTAL_AXIS = 1;
   const long VERTICAL_AXIS = 2;
 
   readonly attribute long axis;
 
   void                initMouseScrollEvent(in DOMString typeArg,
--- a/dom/interfaces/events/nsIDOMMutationEvent.idl
+++ b/dom/interfaces/events/nsIDOMMutationEvent.idl
@@ -1,16 +1,16 @@
 /* -*- 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/. */
 
 #include "nsIDOMEvent.idl"
 
-[builtinclass, uuid(982d9800-1402-46e5-8ad2-56fb0f4905ef)]
+[builtinclass, uuid(df7e4cd9-e41f-4c8e-a764-2e3191d2f463)]
 interface nsIDOMMutationEvent : nsIDOMEvent
 {
   const unsigned short      MODIFICATION       = 1;
   const unsigned short      ADDITION           = 2;
   const unsigned short      REMOVAL            = 3;
 
   readonly attribute nsIDOMNode       relatedNode;
   readonly attribute DOMString        prevValue;
--- a/dom/interfaces/events/nsIDOMNotifyPaintEvent.idl
+++ b/dom/interfaces/events/nsIDOMNotifyPaintEvent.idl
@@ -7,17 +7,17 @@
 
 interface nsIDOMPaintRequestList;
 
 /**
  * The nsIDOMNotifyPaintEvent interface is used for the MozDOMAfterPaint
  * event, which fires at a window when painting has happened in
  * that window.
  */
-[builtinclass, uuid(ef68f0d5-5b55-4198-9e59-a5e2c57d3adc)]
+[builtinclass, uuid(550f660c-65a5-4e17-b828-3dbec7c44304)]
 interface nsIDOMNotifyPaintEvent : nsIDOMEvent
 {
   /**
    * Get a list of rectangles which are affected. The rectangles are in CSS pixels
    * relative to the viewport origin.
    * If the caller is not trusted (e.g., regular Web content) then only painting
    * caused by the current document is reported; in particular, painting in subdocuments
    * is not reported.
--- a/dom/interfaces/events/nsIDOMScrollAreaEvent.idl
+++ b/dom/interfaces/events/nsIDOMScrollAreaEvent.idl
@@ -1,16 +1,16 @@
 /* -*- 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/. */
 
 #include "nsIDOMUIEvent.idl"
 
-[builtinclass, uuid(49ab3d1d-f549-4cdb-904c-f6b6d3a0ec9e)]
+[builtinclass, uuid(05aaf2cf-27c3-4d3d-9e55-4c6a4cf700ec)]
 interface nsIDOMScrollAreaEvent : nsIDOMUIEvent
 {
   // Scroll area client rect
   readonly attribute float x;
   readonly attribute float y;
   readonly attribute float width;
   readonly attribute float height;
 
--- a/dom/interfaces/events/nsIDOMSimpleGestureEvent.idl
+++ b/dom/interfaces/events/nsIDOMSimpleGestureEvent.idl
@@ -99,17 +99,17 @@
  * Default behavior:
  *
  * Some operating systems support default behaviors for gesture events
  * when they are not handled by the application. Consumers should
  * use event.preventDefault() to prevent default behavior when
  * consuming events.
  */
 
-[builtinclass, uuid(d78656ab-9d68-4f03-83f9-7c7bee071aa7)]
+[builtinclass, uuid(1b9afbf0-2cf0-4a7b-99bc-cd35dbd5b637)]
 interface nsIDOMSimpleGestureEvent : nsIDOMMouseEvent
 {
   /* Swipe direction constants */
   const unsigned long DIRECTION_UP = 1;
   const unsigned long DIRECTION_DOWN = 2;
   const unsigned long DIRECTION_LEFT = 4;
   const unsigned long DIRECTION_RIGHT = 8;
 
--- a/dom/interfaces/events/nsIDOMTransitionEvent.idl
+++ b/dom/interfaces/events/nsIDOMTransitionEvent.idl
@@ -6,14 +6,14 @@
 #include "nsIDOMEvent.idl"
 
 /**
  * Transition events are defined in:
  * http://www.w3.org/TR/css3-transitions/#transition-events-
  * http://dev.w3.org/csswg/css3-transitions/#transition-events-
  */
 
-[builtinclass, uuid(a37171e0-9f43-41ea-a25c-0b78a3329683)]
+[builtinclass, uuid(acb69403-0dcb-4db0-9ffc-8a22cc56c4eb)]
 interface nsIDOMTransitionEvent : nsIDOMEvent {
   readonly attribute DOMString           propertyName;
   readonly attribute float               elapsedTime;
   readonly attribute DOMString           pseudoElement;
 };
--- a/dom/interfaces/events/nsIDOMUIEvent.idl
+++ b/dom/interfaces/events/nsIDOMUIEvent.idl
@@ -8,17 +8,17 @@
 /**
  * The nsIDOMUIEvent interface is the datatype for all UI events in the
  * Document Object Model.
  *
  * For more information on this interface please see
  * http://www.w3.org/TR/DOM-Level-2-Events/
  */
 
-[builtinclass, uuid(d73852f8-7bd6-477d-8233-117dbf83860b)]
+[builtinclass, uuid(db058d10-1db9-4cf9-bb4c-483c304a137f)]
 interface nsIDOMUIEvent : nsIDOMEvent
 {
   readonly attribute nsIDOMWindow       view;
   readonly attribute long               detail;
   void                      initUIEvent(in DOMString typeArg,
                                         in boolean canBubbleArg,
                                         in boolean cancelableArg,
                                         in nsIDOMWindow viewArg,
--- a/dom/interfaces/events/nsIDOMWheelEvent.idl
+++ b/dom/interfaces/events/nsIDOMWheelEvent.idl
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=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 "nsIDOMMouseEvent.idl"
 
-[builtinclass, uuid(86e2b577-7e61-4ed5-8ddd-c1533bf07137)]
+[builtinclass, uuid(f1ca2983-8559-43d1-be0e-1af8331755fd)]
 interface nsIDOMWheelEvent : nsIDOMMouseEvent
 {
   const unsigned long DOM_DELTA_PIXEL = 0x00;
   const unsigned long DOM_DELTA_LINE  = 0x01;
   const unsigned long DOM_DELTA_PAGE  = 0x02;
 
   // Note that DOM Level 3 Events defines the type of delta values as float.
   // However, we should use double for them.  Javascript engine always uses
--- a/dom/interfaces/smil/nsIDOMTimeEvent.idl
+++ b/dom/interfaces/smil/nsIDOMTimeEvent.idl
@@ -8,17 +8,17 @@
 /**
  * The SMIL TimeEvent interface.
  *
  * For more information please refer to:
  * http://www.w3.org/TR/SMIL/smil-timing.html#Events-TimeEvent
  * http://www.w3.org/TR/SVG/animate.html#InterfaceTimeEvent
  */
 
-[builtinclass, uuid(4a5a5fa6-2783-4171-b8bb-cae4ab06e6ff)]
+[builtinclass, uuid(7a1dc95e-2c05-4171-8bde-275f094dda1d)]
 interface nsIDOMTimeEvent : nsIDOMEvent
 {
   readonly attribute long detail;
   readonly attribute nsIDOMWindow view;
   
   void initTimeEvent(in DOMString typeArg,
                      in nsIDOMWindow viewArg,
                      in long detailArg);
--- a/dom/interfaces/xul/nsIDOMXULCommandEvent.idl
+++ b/dom/interfaces/xul/nsIDOMXULCommandEvent.idl
@@ -6,17 +6,17 @@
 
 /**
  * This interface is supported by command events, which are dispatched to
  * XUL elements as a result of mouse or keyboard activation.
  */
 
 #include "nsIDOMUIEvent.idl"
 
-[builtinclass, uuid(2d5b6e19-74bb-40af-9aac-59a1e53e3fcc)]
+[builtinclass, uuid(8aa1b009-4a88-4c85-bfba-87ee32fd789f)]
 interface nsIDOMXULCommandEvent : nsIDOMUIEvent
 {
   /**
    * Command events support the same set of modifier keys as mouse and key
    * events.
    */
   readonly attribute boolean ctrlKey;
   readonly attribute boolean shiftKey;
--- a/dom/media/MediaRecorder.cpp
+++ b/dom/media/MediaRecorder.cpp
@@ -1070,23 +1070,17 @@ MediaRecorder::DispatchSimpleEvent(const
 {
   MOZ_ASSERT(NS_IsMainThread(), "Not running on main thread");
   nsresult rv = CheckInnerWindowCorrectness();
   if (NS_FAILED(rv)) {
     return;
   }
 
   RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
-  rv = event->InitEvent(aStr, false, false);
-
-  if (NS_FAILED(rv)) {
-    NS_WARNING("Failed to init the error event!!!");
-    return;
-  }
-
+  event->InitEvent(aStr, false, false);
   event->SetTrusted(true);
 
   rv = DispatchDOMEvent(nullptr, event, nullptr, nullptr);
   if (NS_FAILED(rv)) {
     NS_ERROR("Failed to dispatch the event!!!");
     return;
   }
 }
--- a/dom/media/TextTrackList.cpp
+++ b/dom/media/TextTrackList.cpp
@@ -160,22 +160,17 @@ TextTrackList::DispatchTrackEvent(nsIDOM
   return DispatchTrustedEvent(aEvent);
 }
 
 void
 TextTrackList::CreateAndDispatchChangeEvent()
 {
   RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
 
-  nsresult rv = event->InitEvent(NS_LITERAL_STRING("change"), false, false);
-  if (NS_FAILED(rv)) {
-    NS_WARNING("Failed to init the change event!");
-    return;
-  }
-
+  event->InitEvent(NS_LITERAL_STRING("change"), false, false);
   event->SetTrusted(true);
 
   nsCOMPtr<nsIRunnable> eventRunner = new TrackEventRunner(this, event);
   NS_DispatchToMainThread(eventRunner);
 }
 
 void
 TextTrackList::CreateAndDispatchTrackEventRunner(TextTrack* aTrack,
--- a/dom/media/gmp/GMPVideoDecoderParent.cpp
+++ b/dom/media/gmp/GMPVideoDecoderParent.cpp
@@ -273,17 +273,16 @@ GMPVideoDecoderParent::Shutdown()
 // Note: Keep this sync'd up with Shutdown
 void
 GMPVideoDecoderParent::ActorDestroy(ActorDestroyReason aWhy)
 {
   LOGD(("GMPVideoDecoderParent[%p]::ActorDestroy reason=%d", this, aWhy));
 
   mIsOpen = false;
   mActorDestroyed = true;
-  mVideoHost.DoneWithAPI();
 
   // Ensure if we've received a destroy while waiting for a ResetComplete
   // or DrainComplete notification, we'll unblock the caller before processing
   // the error.
   UnblockResetAndDrain();
 
   if (mCallback) {
     // May call Close() (and Shutdown()) immediately or with a delay
--- a/dom/media/gmp/GMPVideoEncoderParent.cpp
+++ b/dom/media/gmp/GMPVideoEncoderParent.cpp
@@ -224,17 +224,16 @@ GMPVideoEncoderParent::Shutdown()
   }
   mShuttingDown = true;
 
   // Notify client we're gone!  Won't occur after Close()
   if (mCallback) {
     mCallback->Terminated();
     mCallback = nullptr;
   }
-  mVideoHost.DoneWithAPI();
 
   mIsOpen = false;
   if (!mActorDestroyed) {
     Unused << SendEncodingComplete();
   }
 }
 
 static void
@@ -264,17 +263,17 @@ GMPVideoEncoderParent::ActorDestroy(Acto
                      nsCOMPtr<nsIThread> >(&ShutdownEncodedThread, mEncodedThread));
     mEncodedThread = nullptr;
   }
   if (mPlugin) {
     // Ignore any return code. It is OK for this to fail without killing the process.
     mPlugin->VideoEncoderDestroyed(this);
     mPlugin = nullptr;
   }
-  mVideoHost.ActorDestroyed();
+  mVideoHost.ActorDestroyed(); // same as DoneWithAPI
 }
 
 static void
 EncodedCallback(GMPVideoEncoderCallbackProxy* aCallback,
                 GMPVideoEncodedFrame* aEncodedFrame,
                 nsTArray<uint8_t>* aCodecSpecificInfo,
                 nsCOMPtr<nsIThread> aThread)
 {
@@ -326,29 +325,39 @@ GMPVideoEncoderParent::RecvShutdown()
   Shutdown();
   return true;
 }
 
 bool
 GMPVideoEncoderParent::RecvParentShmemForPool(Shmem&& aFrameBuffer)
 {
   if (aFrameBuffer.IsWritable()) {
-    mVideoHost.SharedMemMgr()->MgrDeallocShmem(GMPSharedMem::kGMPFrameData,
-                                               aFrameBuffer);
+    // This test may be paranoia now that we don't shut down the VideoHost
+    // in ::Shutdown, but doesn't hurt
+    if (mVideoHost.SharedMemMgr()) {
+      mVideoHost.SharedMemMgr()->MgrDeallocShmem(GMPSharedMem::kGMPFrameData,
+                                                 aFrameBuffer);
+    } else {
+      LOGD(("%s::%s: %p Called in shutdown, ignoring and freeing directly", __CLASS__, __FUNCTION__, this));
+      DeallocShmem(aFrameBuffer);
+    }
   }
   return true;
 }
 
 bool
 GMPVideoEncoderParent::AnswerNeedShmem(const uint32_t& aEncodedBufferSize,
                                        Shmem* aMem)
 {
   ipc::Shmem mem;
 
-  if (!mVideoHost.SharedMemMgr()->MgrAllocShmem(GMPSharedMem::kGMPEncodedData,
+  // This test may be paranoia now that we don't shut down the VideoHost
+  // in ::Shutdown, but doesn't hurt
+  if (!mVideoHost.SharedMemMgr() ||
+      !mVideoHost.SharedMemMgr()->MgrAllocShmem(GMPSharedMem::kGMPEncodedData,
                                                 aEncodedBufferSize,
                                                 ipc::SharedMemory::TYPE_BASIC, &mem))
   {
     LOG(LogLevel::Error, ("%s::%s: Failed to get a shared mem buffer for Child! size %u",
                        __CLASS__, __FUNCTION__, aEncodedBufferSize));
     return false;
   }
   *aMem = mem;
--- a/dom/media/gmp/GMPVideoHost.cpp
+++ b/dom/media/gmp/GMPVideoHost.cpp
@@ -66,45 +66,38 @@ GMPVideoHostImpl::CreatePlane(GMPPlane**
 }
 
 GMPSharedMemManager*
 GMPVideoHostImpl::SharedMemMgr()
 {
   return mSharedMemMgr;
 }
 
+// XXX This should merge with ActorDestroyed
 void
 GMPVideoHostImpl::DoneWithAPI()
 {
+  ActorDestroyed();
+}
+
+void
+GMPVideoHostImpl::ActorDestroyed()
+{
   for (uint32_t i = mPlanes.Length(); i > 0; i--) {
     mPlanes[i - 1]->DoneWithAPI();
     mPlanes.RemoveElementAt(i - 1);
   }
   for (uint32_t i = mEncodedFrames.Length(); i > 0; i--) {
     mEncodedFrames[i - 1]->DoneWithAPI();
     mEncodedFrames.RemoveElementAt(i - 1);
   }
   mSharedMemMgr = nullptr;
 }
 
 void
-GMPVideoHostImpl::ActorDestroyed()
-{
-  for (uint32_t i = mPlanes.Length(); i > 0; i--) {
-    mPlanes[i - 1]->ActorDestroyed();
-    mPlanes.RemoveElementAt(i - 1);
-  }
-  for (uint32_t i = mEncodedFrames.Length(); i > 0; i--) {
-    mEncodedFrames[i - 1]->ActorDestroyed();
-    mEncodedFrames.RemoveElementAt(i - 1);
-  }
-  mSharedMemMgr = nullptr;
-}
-
-void
 GMPVideoHostImpl::PlaneCreated(GMPPlaneImpl* aPlane)
 {
   mPlanes.AppendElement(aPlane);
 }
 
 void
 GMPVideoHostImpl::PlaneDestroyed(GMPPlaneImpl* aPlane)
 {
--- a/dom/media/webaudio/FFTBlock.h
+++ b/dom/media/webaudio/FFTBlock.h
@@ -133,24 +133,25 @@ public:
 #endif
   }
 
   void Multiply(const FFTBlock& aFrame)
   {
     uint32_t halfSize = mFFTSize / 2;
     // DFTs are not packed.
     MOZ_ASSERT(mOutputBuffer[0].i == 0);
-    MOZ_ASSERT(mOutputBuffer[halfSize].i == 0);
     MOZ_ASSERT(aFrame.mOutputBuffer[0].i == 0);
-    MOZ_ASSERT(aFrame.mOutputBuffer[halfSize].i == 0);
 
     BufferComplexMultiply(mOutputBuffer.Elements()->f,
                           aFrame.mOutputBuffer.Elements()->f,
                           mOutputBuffer.Elements()->f,
-                          halfSize + 1);
+                          halfSize);
+    mOutputBuffer[halfSize].r *= aFrame.mOutputBuffer[halfSize].r;
+    // This would have been set to NaN if either real component was NaN.
+    mOutputBuffer[0].i = 0.0f;
   }
 
   // Perform a forward FFT on |aData|, assuming zeros after dataSize samples,
   // and pre-scale the generated internal frequency domain coefficients so
   // that GetInverseWithoutScaling() can be used to transform to the time
   // domain.  This is useful for convolution kernels.
   void PadAndMakeScaledDFT(const float* aData, size_t dataSize)
   {
--- a/dom/media/webaudio/blink/ReverbConvolver.cpp
+++ b/dom/media/webaudio/blink/ReverbConvolver.cpp
@@ -89,18 +89,24 @@ ReverbConvolver::ReverbConvolver(const f
     size_t stageOffset = 0;
     size_t stagePhase = 0;
     size_t fftSize = MinFFTSize;
     while (stageOffset < totalResponseLength) {
         size_t stageSize = fftSize / 2;
 
         // For the last stage, it's possible that stageOffset is such that we're straddling the end
         // of the impulse response buffer (if we use stageSize), so reduce the last stage's length...
-        if (stageSize + stageOffset > totalResponseLength)
+        if (stageSize + stageOffset > totalResponseLength) {
             stageSize = totalResponseLength - stageOffset;
+            // Use smallest FFT that is large enough to cover the last stage.
+            fftSize = MinFFTSize;
+            while (stageSize * 2 > fftSize) {
+              fftSize *= 2;
+            }
+        }
 
         // This "staggers" the time when each FFT happens so they don't all happen at the same time
         int renderPhase = convolverRenderPhase + stagePhase;
 
         nsAutoPtr<ReverbConvolverStage> stage
           (new ReverbConvolverStage(response, totalResponseLength,
                                     reverbTotalLatency, stageOffset, stageSize,
                                     fftSize, renderPhase,
--- a/dom/media/webaudio/test/mochitest.ini
+++ b/dom/media/webaudio/test/mochitest.ini
@@ -93,16 +93,17 @@ skip-if = toolkit == 'android' # bug 105
 [test_channelMergerNodeWithVolume.html]
 [test_channelSplitterNode.html]
 [test_channelSplitterNodeWithVolume.html]
 skip-if = (android_version == '18' && debug) # bug 1158417
 [test_convolverNode.html]
 [test_convolverNode_mono_mono.html]
 [test_convolverNodeChannelCount.html]
 [test_convolverNodeDelay.html]
+[test_convolverNodeFiniteInfluence.html]
 [test_convolverNodePassThrough.html]
 [test_convolverNodeWithGain.html]
 [test_currentTime.html]
 [test_decodeMultichannel.html]
 [test_decodeAudioDataPromise.html]
 [test_delayNode.html]
 [test_delayNodeAtMax.html]
 [test_delayNodeChannelChanges.html]
new file mode 100644
--- /dev/null
+++ b/dom/media/webaudio/test/test_convolverNodeFiniteInfluence.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<title>Test convolution effect has finite duration</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+promise_test(function() {
+
+  const responseLength = 256;
+  // Accept an influence period of twice the responseLength to accept FFT
+  // implementations.
+  const tolerancePeriod = 2 * responseLength;
+  const totalSize = tolerancePeriod + responseLength;
+
+  var context = new OfflineAudioContext(1, totalSize, 48000);
+
+  var responseBuffer =
+    context.createBuffer(1, responseLength, context.sampleRate);
+  var responseChannelData = responseBuffer.getChannelData(0);
+  responseChannelData[0] = 1;
+  responseChannelData[responseLength - 1] = 1;
+  var convolver = context.createConvolver();
+  convolver.buffer = responseBuffer;
+  convolver.connect(context.destination);
+
+  var sourceBuffer = context.createBuffer(1, totalSize, context.sampleRate);
+  sourceBuffer.getChannelData(0)[0] = NaN;
+  var source = context.createBufferSource();
+  source.buffer = sourceBuffer;
+  source.connect(convolver);
+  source.start();
+
+  return context.startRendering().
+    then((buffer) => {
+      var convolverOutput = buffer.getChannelData(0);
+      // There should be no non-zeros after the tolerance period.
+      var testIndex = tolerancePeriod;
+      for (;
+           testIndex < buffer.length - 1 && convolverOutput[testIndex] == 0;
+           ++testIndex) {
+      }
+      assert_equals(convolverOutput[testIndex], 0, "output at " + testIndex);
+    });
+});
+</script>
--- a/dom/media/webspeech/recognition/SpeechRecognition.cpp
+++ b/dom/media/webspeech/recognition/SpeechRecognition.cpp
@@ -865,19 +865,18 @@ SpeechRecognition::DispatchError(EventTy
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aErrorType == EVENT_RECOGNITIONSERVICE_ERROR ||
              aErrorType == EVENT_AUDIO_ERROR, "Invalid error type!");
 
   RefPtr<SpeechRecognitionError> srError =
     new SpeechRecognitionError(nullptr, nullptr, nullptr);
 
-  ErrorResult err;
   srError->InitSpeechRecognitionError(NS_LITERAL_STRING("error"), true, false,
-                                      aErrorCode, aMessage, err);
+                                      aErrorCode, aMessage);
 
   RefPtr<SpeechEvent> event = new SpeechEvent(this, aErrorType);
   event->mError = srError;
   NS_DispatchToMainThread(event);
 }
 
 /*
  * Buffer audio samples into mAudioSamplesBuffer until aBufferSize.
--- a/dom/network/TCPServerSocket.cpp
+++ b/dom/network/TCPServerSocket.cpp
@@ -154,18 +154,17 @@ TCPServerSocket::OnSocketAccepted(nsISer
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TCPServerSocket::OnStopListening(nsIServerSocket* aServer, nsresult aStatus)
 {
   if (aStatus != NS_BINDING_ABORTED) {
     RefPtr<Event> event = new Event(GetOwner());
-    nsresult rv = event->InitEvent(NS_LITERAL_STRING("error"), false, false);
-    NS_ENSURE_SUCCESS(rv, rv);
+    event->InitEvent(NS_LITERAL_STRING("error"), false, false);
     event->SetTrusted(true);
     bool dummy;
     DispatchEvent(event, &dummy);
 
     NS_WARNING("Server socket was closed by unexpected reason.");
     return NS_ERROR_FAILURE;
   }
   mServerSocket = nullptr;
--- a/dom/notification/DesktopNotification.cpp
+++ b/dom/notification/DesktopNotification.cpp
@@ -170,20 +170,17 @@ void
 DesktopNotification::DispatchNotificationEvent(const nsString& aName)
 {
   if (NS_FAILED(CheckInnerWindowCorrectness())) {
     return;
   }
 
   RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
   // it doesn't bubble, and it isn't cancelable
-  nsresult rv = event->InitEvent(aName, false, false);
-  if (NS_FAILED(rv)) {
-    return;
-  }
+  event->InitEvent(aName, false, false);
   event->SetTrusted(true);
   DispatchDOMEvent(nullptr, event, nullptr, nullptr);
 }
 
 nsresult
 DesktopNotification::SetAllow(bool aAllow)
 {
   mAllow = aAllow;
--- a/dom/notification/Notification.cpp
+++ b/dom/notification/Notification.cpp
@@ -1105,18 +1105,17 @@ Notification::DispatchNotificationClickE
   return false;
 }
 
 bool
 Notification::DispatchClickEvent()
 {
   AssertIsOnTargetThread();
   RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
-  nsresult rv = event->InitEvent(NS_LITERAL_STRING("click"), false, true);
-  NS_ENSURE_SUCCESS(rv, false);
+  event->InitEvent(NS_LITERAL_STRING("click"), false, true);
   event->SetTrusted(true);
   WantsPopupControlCheck popupControlCheck(event);
   bool doDefaultAction = true;
   DispatchEvent(event, &doDefaultAction);
   return doDefaultAction;
 }
 
 // Overrides dispatch and run handlers so we can directly dispatch from main
--- a/dom/plugins/base/nsNPAPIPluginInstance.h
+++ b/dom/plugins/base/nsNPAPIPluginInstance.h
@@ -26,16 +26,17 @@
 #include "AndroidBridge.h"
 #include <map>
 class PluginEventRunnable;
 class SharedPluginTexture;
 #endif
 
 #include "mozilla/TimeStamp.h"
 #include "mozilla/PluginLibrary.h"
+#include "mozilla/WeakPtr.h"
 
 class nsPluginStreamListenerPeer; // browser-initiated stream class
 class nsNPAPIPluginStreamListener; // plugin-initiated stream class
 class nsIPluginInstanceOwner;
 class nsIOutputStream;
 class nsPluginInstanceOwner;
 
 #if defined(OS_WIN)
@@ -71,21 +72,23 @@ public:
   uint32_t id;
   nsCOMPtr<nsITimer> timer;
   void (*callback)(NPP npp, uint32_t timerID);
   bool inCallback;
   bool needUnschedule;
 };
 
 class nsNPAPIPluginInstance final : public nsIAudioChannelAgentCallback
+                                  , public mozilla::SupportsWeakPtr<nsNPAPIPluginInstance>
 {
 private:
   typedef mozilla::PluginLibrary PluginLibrary;
 
 public:
+  MOZ_DECLARE_WEAKREFERENCE_TYPENAME(nsNPAPIPluginInstance)
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIAUDIOCHANNELAGENTCALLBACK
 
   nsresult Initialize(nsNPAPIPlugin *aPlugin, nsPluginInstanceOwner* aOwner, const nsACString& aMIMEType);
   nsresult Start();
   nsresult Stop();
   nsresult SetWindow(NPWindow* window);
   nsresult NewStreamFromPlugin(const char* type, const char* target, nsIOutputStream* *result);
--- a/dom/plugins/ipc/PluginAsyncSurrogate.cpp
+++ b/dom/plugins/ipc/PluginAsyncSurrogate.cpp
@@ -96,17 +96,16 @@ private:
   bool        mIsRecursive;
   static bool sHasEntered;
 };
 
 bool RecursionGuard::sHasEntered = false;
 
 PluginAsyncSurrogate::PluginAsyncSurrogate(PluginModuleParent* aParent)
   : mParent(aParent)
-  , mInstance(nullptr)
   , mMode(0)
   , mWindow(nullptr)
   , mAcceptCalls(false)
   , mInstantiated(false)
   , mAsyncSetWindow(false)
   , mInitCancelled(false)
   , mDestroyPending(false)
   , mAsyncCallsInFlight(0)
@@ -118,17 +117,20 @@ PluginAsyncSurrogate::~PluginAsyncSurrog
 {
 }
 
 bool
 PluginAsyncSurrogate::Init(NPMIMEType aPluginType, NPP aInstance, uint16_t aMode,
                            int16_t aArgc, char* aArgn[], char* aArgv[])
 {
   mMimeType = aPluginType;
-  mInstance = aInstance;
+  nsNPAPIPluginInstance* instance =
+    static_cast<nsNPAPIPluginInstance*>(aInstance->ndata);
+  MOZ_ASSERT(instance);
+  mInstance = instance;
   mMode = aMode;
   for (int i = 0; i < aArgc; ++i) {
     mNames.AppendElement(NullableString(aArgn[i]));
     mValues.AppendElement(NullableString(aArgv[i]));
   }
   return true;
 }
 
@@ -157,17 +159,21 @@ PluginAsyncSurrogate::Cast(NPP aInstance
     return nullptr;
   }
   return resolver->GetAsyncSurrogate();
 }
 
 nsresult
 PluginAsyncSurrogate::NPP_New(NPError* aError)
 {
-  nsresult rv = mParent->NPP_NewInternal(mMimeType.BeginWriting(), mInstance,
+  if (!mInstance) {
+    return NS_ERROR_NULL_POINTER;
+  }
+
+  nsresult rv = mParent->NPP_NewInternal(mMimeType.BeginWriting(), GetNPP(),
                                          mMode, mNames, mValues, nullptr,
                                          aError);
   if (NS_FAILED(rv)) {
     return rv;
   }
   return NS_OK;
 }
 
@@ -194,61 +200,72 @@ PluginAsyncSurrogate::NotifyDestroyPendi
 {
   PluginAsyncSurrogate* surrogate = Cast(aInstance);
   if (!surrogate) {
     return;
   }
   surrogate->NotifyDestroyPending();
 }
 
+NPP
+PluginAsyncSurrogate::GetNPP()
+{
+  MOZ_ASSERT(mInstance);
+  NPP npp;
+  DebugOnly<nsresult> rv = mInstance->GetNPP(&npp);
+  MOZ_ASSERT(NS_SUCCEEDED(rv));
+  return npp;
+}
+
 void
 PluginAsyncSurrogate::NotifyDestroyPending()
 {
   mDestroyPending = true;
-  nsJSNPRuntime::OnPluginDestroyPending(mInstance);
+  nsJSNPRuntime::OnPluginDestroyPending(GetNPP());
 }
 
 NPError
 PluginAsyncSurrogate::NPP_Destroy(NPSavedData** aSave)
 {
   NotifyDestroyPending();
   if (!WaitForInit()) {
     return NPERR_GENERIC_ERROR;
   }
-  return PluginModuleParent::NPP_Destroy(mInstance, aSave);
+  return PluginModuleParent::NPP_Destroy(GetNPP(), aSave);
 }
 
 NPError
 PluginAsyncSurrogate::NPP_GetValue(NPPVariable aVariable, void* aRetval)
 {
   if (aVariable != NPPVpluginScriptableNPObject) {
     if (!WaitForInit()) {
       return NPERR_GENERIC_ERROR;
     }
-    PluginInstanceParent* instance = PluginInstanceParent::Cast(mInstance);
+
+    PluginInstanceParent* instance = PluginInstanceParent::Cast(GetNPP());
     MOZ_ASSERT(instance);
     return instance->NPP_GetValue(aVariable, aRetval);
   }
 
-  NPObject* npobject = parent::_createobject(mInstance,
+  NPObject* npobject = parent::_createobject(GetNPP(),
                                              const_cast<NPClass*>(GetClass()));
   MOZ_ASSERT(npobject);
   MOZ_ASSERT(npobject->_class == GetClass());
   MOZ_ASSERT(npobject->referenceCount == 1);
   *(NPObject**)aRetval = npobject;
   return npobject ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
 }
 
 NPError
 PluginAsyncSurrogate::NPP_SetValue(NPNVariable aVariable, void* aValue)
 {
   if (!WaitForInit()) {
     return NPERR_GENERIC_ERROR;
   }
-  return PluginModuleParent::NPP_SetValue(mInstance, aVariable, aValue);
+  return PluginModuleParent::NPP_SetValue(GetNPP(), aVariable, aValue);
 }
 
 NPError
 PluginAsyncSurrogate::NPP_NewStream(NPMIMEType aType, NPStream* aStream,
                                     NPBool aSeekable, uint16_t* aStype)
 {
   mPendingNewStreamCalls.AppendElement(PendingNewStreamCall(aType, aStream,
                                                             aSeekable));
@@ -424,17 +441,20 @@ void
 PluginAsyncSurrogate::DestroyAsyncStream(NPStream* aStream)
 {
   MOZ_ASSERT(aStream);
   nsNPAPIPluginStreamListener* streamListener = GetStreamListener(aStream);
   MOZ_ASSERT(streamListener);
   // streamListener was suspended during async init. We must resume the stream
   // request prior to calling _destroystream for cleanup to work correctly.
   streamListener->ResumeRequest();
-  parent::_destroystream(mInstance, aStream, NPRES_DONE);
+  if (!mInstance) {
+    return;
+  }
+  parent::_destroystream(GetNPP(), aStream, NPRES_DONE);
 }
 
 /* static */ bool
 PluginAsyncSurrogate::SetStreamType(NPStream* aStream, uint16_t aStreamType)
 {
   nsNPAPIPluginStreamListener* streamListener = GetStreamListener(aStream);
   if (!streamListener) {
     return false;
@@ -564,22 +584,20 @@ PluginAsyncSurrogate::NotifyAsyncInitFai
     }
   }
   mPendingNewStreamCalls.Clear();
 
   // Make sure that any WaitForInit calls on this surrogate will fail, or else
   // we'll be perma-blocked
   mInitCancelled = true;
 
-  nsNPAPIPluginInstance* inst =
-    static_cast<nsNPAPIPluginInstance*>(mInstance->ndata);
-  if (!inst) {
+  if (!mInstance) {
       return;
   }
-  nsPluginInstanceOwner* owner = inst->GetOwner();
+  nsPluginInstanceOwner* owner = mInstance->GetOwner();
   if (owner) {
     owner->NotifyHostAsyncInitFailed();
   }
 }
 
 // static
 NPObject*
 PluginAsyncSurrogate::ScriptableAllocate(NPP aInstance, NPClass* aClass)
@@ -658,21 +676,21 @@ PluginAsyncSurrogate::ScriptableHasMetho
   }
   bool result = realObject->_class->hasMethod(realObject, aName);
   if (!result && checkPluginObject) {
     // We may be calling into this object because properties in the WebIDL
     // object hadn't been set yet. Now that we're further along in
     // initialization, we should try again.
     const NPNetscapeFuncs* npn = object->mSurrogate->mParent->GetNetscapeFuncs();
     NPObject* pluginObject = nullptr;
-    NPError nperror = npn->getvalue(object->mSurrogate->mInstance,
+    NPError nperror = npn->getvalue(object->mSurrogate->GetNPP(),
                                     NPNVPluginElementNPObject,
                                     (void*)&pluginObject);
     if (nperror == NPERR_NO_ERROR) {
-      NPPAutoPusher nppPusher(object->mSurrogate->mInstance);
+      NPPAutoPusher nppPusher(object->mSurrogate->GetNPP());
       result = pluginObject->_class->hasMethod(pluginObject, aName);
       npn->releaseobject(pluginObject);
       NPUTF8* idstr = npn->utf8fromidentifier(aName);
       npn->memfree(idstr);
     }
   }
   return result;
 }
@@ -711,20 +729,20 @@ PluginAsyncSurrogate::GetPropertyHelper(
     static_cast<ParentNPObject*>(realObject)->parent;
   if (!actor) {
     return false;
   }
   bool success = actor->GetPropertyHelper(aName, aHasProperty, aHasMethod, aResult);
   if (!success) {
     const NPNetscapeFuncs* npn = mParent->GetNetscapeFuncs();
     NPObject* pluginObject = nullptr;
-    NPError nperror = npn->getvalue(mInstance, NPNVPluginElementNPObject,
+    NPError nperror = npn->getvalue(GetNPP(), NPNVPluginElementNPObject,
                                     (void*)&pluginObject);
     if (nperror == NPERR_NO_ERROR) {
-      NPPAutoPusher nppPusher(mInstance);
+      NPPAutoPusher nppPusher(GetNPP());
       bool hasProperty = nsJSObjWrapper::HasOwnProperty(pluginObject, aName);
       NPUTF8* idstr = npn->utf8fromidentifier(aName);
       npn->memfree(idstr);
       bool hasMethod = false;
       if (hasProperty) {
         hasMethod = pluginObject->_class->hasMethod(pluginObject, aName);
         success = pluginObject->_class->getProperty(pluginObject, aName, aResult);
         idstr = npn->utf8fromidentifier(aName);
@@ -819,21 +837,21 @@ PluginAsyncSurrogate::ScriptableHasPrope
   const NPNetscapeFuncs* npn = object->mSurrogate->mParent->GetNetscapeFuncs();
   NPUTF8* idstr = npn->utf8fromidentifier(aName);
   npn->memfree(idstr);
   if (!result && checkPluginObject) {
     // We may be calling into this object because properties in the WebIDL
     // object hadn't been set yet. Now that we're further along in
     // initialization, we should try again.
     NPObject* pluginObject = nullptr;
-    NPError nperror = npn->getvalue(object->mSurrogate->mInstance,
+    NPError nperror = npn->getvalue(object->mSurrogate->GetNPP(),
                                     NPNVPluginElementNPObject,
                                     (void*)&pluginObject);
     if (nperror == NPERR_NO_ERROR) {
-      NPPAutoPusher nppPusher(object->mSurrogate->mInstance);
+      NPPAutoPusher nppPusher(object->mSurrogate->GetNPP());
       result = nsJSObjWrapper::HasOwnProperty(pluginObject, aName);
       npn->releaseobject(pluginObject);
       idstr = npn->utf8fromidentifier(aName);
       npn->memfree(idstr);
     }
   }
   return result;
 }
--- a/dom/plugins/ipc/PluginAsyncSurrogate.h
+++ b/dom/plugins/ipc/PluginAsyncSurrogate.h
@@ -55,17 +55,17 @@ public:
   void NotifyDestroyPending();
 
   virtual PluginAsyncSurrogate*
   GetAsyncSurrogate() { return this; }
 
   virtual PluginInstanceParent*
   GetInstance() { return nullptr; }
 
-  NPP GetNPP() { return mInstance; }
+  NPP GetNPP();
 
   bool GetPropertyHelper(NPObject* aObject, NPIdentifier aName,
                          bool* aHasProperty, bool* aHasMethod,
                          NPVariant* aResult);
 
   PluginModuleParent* GetParent() { return mParent; }
 
   bool IsDestroyPending() const { return mDestroyPending; }
@@ -136,17 +136,17 @@ private:
     NPStream*   mStream;
     NPBool      mSeekable;
   };
 
 private:
   PluginModuleParent*             mParent;
   // These values are used to construct the plugin instance
   nsCString                       mMimeType;
-  NPP                             mInstance;
+  mozilla::WeakPtr<nsNPAPIPluginInstance> mInstance;
   uint16_t                        mMode;
   InfallibleTArray<nsCString>     mNames;
   InfallibleTArray<nsCString>     mValues;
   // This is safe to store as a pointer because the spec says it will remain
   // valid until destruction or a subsequent NPP_SetWindow call.
   NPWindow*                       mWindow;
   nsTArray<PendingNewStreamCall>  mPendingNewStreamCalls;
   UniquePtr<PluginDestructionGuard> mPluginDestructionGuard;
--- a/dom/security/test/csp/file_main.html^headers^
+++ b/dom/security/test/csp/file_main.html^headers^
@@ -1,1 +1,1 @@
-Content-Security-Policy: default-src 'self' ; style-src 'unsafe-inline' 'self'
+Content-Security-Policy: default-src 'self' blob: ; style-src 'unsafe-inline' 'self'
--- a/dom/security/test/csp/file_main.js
+++ b/dom/security/test/csp/file_main.js
@@ -1,16 +1,28 @@
-// some javascript for the CSP XHR tests
-//
+function doXHR(uri) {
+  try {
+    var xhr = new XMLHttpRequest();
+    xhr.open("GET", uri);
+    xhr.send();
+  } catch(ex) {}
+}
 
+doXHR("http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs?testid=xhr_good");
+doXHR("http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid=xhr_bad");
+fetch("http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs?testid=fetch_good");
+fetch("http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid=fetch_bad");
+navigator.sendBeacon("http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs?testid=beacon_good");
 try {
-  var xhr_good = new XMLHttpRequest();
-  var xhr_good_uri ="http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs?testid=xhr_good";
-  xhr_good.open("GET", xhr_good_uri, true);
-  xhr_good.send(null);
-} catch(e) {}
+  navigator.sendBeacon("http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid=beacon_bad");
+} catch(ex) {}
+
+
+new Worker("file_main_worker.js").postMessage({inherited : false});
+
 
-try {
-  var xhr_bad = new XMLHttpRequest();
-  var xhr_bad_uri ="http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid=xhr_bad";
-  xhr_bad.open("GET", xhr_bad_uri, true);
-  xhr_bad.send(null);
-} catch(e) {}
+var blobxhr = new XMLHttpRequest();
+blobxhr.open("GET", "file_main_worker.js")
+blobxhr.responseType = "blob";
+blobxhr.send();
+blobxhr.onload = () => {
+  new Worker(URL.createObjectURL(blobxhr.response)).postMessage({inherited : true});
+}
new file mode 100644
--- /dev/null
+++ b/dom/security/test/csp/file_main_worker.js
@@ -0,0 +1,28 @@
+function doXHR(uri) {
+  try {
+    var xhr = new XMLHttpRequest();
+    xhr.open("GET", uri);
+    xhr.send();
+  } catch(ex) {}
+}
+
+var sameBase = "http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs?testid=";
+var crossBase = "http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid=";
+
+onmessage = (e) => {
+  for (base of [sameBase, crossBase]) {
+    var prefix;
+    var suffix;
+    if (e.data.inherited) {
+      prefix = base + "worker_inherited_"
+      suffix = base == sameBase ? "_good" : "_bad";
+    }
+    else {
+      prefix = base + "worker_"
+      suffix = base == sameBase ? "_same_good" : "_cross_good";
+    }
+    doXHR(prefix + "xhr" + suffix);
+    fetch(prefix + "fetch" + suffix);
+    try { importScripts(prefix + "script" + suffix); } catch(ex) {}
+  }
+}
--- a/dom/security/test/csp/file_redirects_main.html
+++ b/dom/security/test/csp/file_redirects_main.html
@@ -6,27 +6,28 @@
 <div id="container"></div>
 </body>
 
 <script>
 var thisSite = "http://mochi.test:8888";
 var otherSite = "http://example.com";
 var page = "/tests/dom/security/test/csp/file_redirects_page.sjs";
 
-var tests = { "font-src": thisSite+page+"?testid=font-src&csp=1",
-              "frame-src": thisSite+page+"?testid=frame-src&csp=1",
-              "img-src":  thisSite+page+"?testid=img-src&csp=1",
-              "media-src":  thisSite+page+"?testid=media-src&csp=1",
-              "object-src":  thisSite+page+"?testid=object-src&csp=1",
-              "script-src":  thisSite+page+"?testid=script-src&csp=1",
-              "style-src":  thisSite+page+"?testid=style-src&csp=1",
-              "worker":  thisSite+page+"?testid=worker&csp=1",
-              "xhr-src":  thisSite+page+"?testid=xhr-src&csp=1",
-              "script-src-from-worker": thisSite+page+"?testid=script-src-from-worker&csp=1",
-              "img-src-from-css":  thisSite+page+"?testid=img-src-from-css&csp=1",
+var tests = { "font-src": thisSite+page+"?testid=font-src",
+              "frame-src": thisSite+page+"?testid=frame-src",
+              "img-src":  thisSite+page+"?testid=img-src",
+              "media-src":  thisSite+page+"?testid=media-src",
+              "object-src":  thisSite+page+"?testid=object-src",
+              "script-src":  thisSite+page+"?testid=script-src",
+              "style-src":  thisSite+page+"?testid=style-src",
+              "worker":  thisSite+page+"?testid=worker",
+              "xhr-src":  thisSite+page+"?testid=xhr-src",
+              "from-worker": thisSite+page+"?testid=from-worker",
+              "from-blob-worker": thisSite+page+"?testid=from-blob-worker",
+              "img-src-from-css":  thisSite+page+"?testid=img-src-from-css",
             };
 
 var container = document.getElementById("container");
 
 // load each test in its own iframe
 for (tid in tests) {
   var i = document.createElement("iframe");
   i.id = tid;
--- a/dom/security/test/csp/file_redirects_page.sjs
+++ b/dom/security/test/csp/file_redirects_page.sjs
@@ -9,25 +9,23 @@ function handleRequest(request, response
   });
 
   response.setHeader("Cache-Control", "no-cache", false);
   response.setHeader("Content-Type", "text/html", false);
 
   var resource = "/tests/dom/security/test/csp/file_redirects_resource.sjs";
 
   // CSP header value
-  if (query["csp"] == 1) {
-    var additional = ""
-    if (query['testid'] == "worker") {
-      additional = "; script-src 'self' 'unsafe-inline'";
-    }
-    response.setHeader("Content-Security-Policy",
-        "default-src 'self' ; style-src 'self' 'unsafe-inline'" + additional,
-        false);
+  var additional = ""
+  if (query['testid'] == "worker") {
+    additional = "; script-src 'self' 'unsafe-inline'";
   }
+  response.setHeader("Content-Security-Policy",
+      "default-src 'self' blob: ; style-src 'self' 'unsafe-inline'" + additional,
+      false);
 
   // downloadable font that redirects to another site
   if (query["testid"] == "font-src") {
     var resp = '<style type="text/css"> @font-face { font-family:' +
                '"Redirecting Font"; src: url("' + resource +
                '?res=font&redir=other&id=font-src-redir")} #test{font-family:' +
                '"Redirecting Font"}</style></head><body>' +
                '<div id="test">test</div></body>';
@@ -85,18 +83,32 @@ function handleRequest(request, response
 
   // for bug949706
   if (query["testid"] == "img-src-from-css") {
     // loads a stylesheet, which in turn loads an image that redirects.
     response.write('<link rel="stylesheet" type="text/css" href="'+resource+'?res=cssLoader&id=img-src-redir-from-css">');
     return;
   }
 
-  if (query["testid"] == "script-src-from-worker") {
+  if (query["testid"] == "from-worker") {
     // loads a script; launches a worker; that worker uses importscript; which then gets redirected
     // So it's:
-    // <script "res=loadWorkerThatImports">
-    //   .. loads Worker("res=importScriptWorker")
+    // <script src="res=loadWorkerThatMakesRequests">
+    //   .. loads Worker("res=makeRequestsWorker")
     //         .. calls importScript("res=script")
-    response.write('<script src="'+resource+'?res=loadWorkerThatImports&id=script-src-redir-from-worker"></script>');
+    //         .. calls xhr("res=xhr-resp")
+    //         .. calls fetch("res=xhr-resp")
+    response.write('<script src="'+resource+'?res=loadWorkerThatMakesRequests&id=from-worker"></script>');
+    return;
+  }
+
+  if (query["testid"] == "from-blob-worker") {
+    // loads a script; launches a worker; that worker uses importscript; which then gets redirected
+    // So it's:
+    // <script src="res=loadBlobWorkerThatMakesRequests">
+    //   .. loads Worker("res=makeRequestsWorker")
+    //         .. calls importScript("res=script")
+    //         .. calls xhr("res=xhr-resp")
+    //         .. calls fetch("res=xhr-resp")
+    response.write('<script src="'+resource+'?res=loadBlobWorkerThatMakesRequests&id=from-blob-worker"></script>');
     return;
   }
 }
--- a/dom/security/test/csp/file_redirects_resource.sjs
+++ b/dom/security/test/csp/file_redirects_resource.sjs
@@ -97,39 +97,55 @@ function handleRequest(request, response
     let bgURL = thisSite + resource + '?redir=other&res=image&id=' + query["id"];
     response.setHeader("Content-Type", "text/css", false);
     response.write("body { background:url('" + bgURL + "'); }");
     return;
   }
 
   // script that loads an internal worker that uses importScripts on a redirect
   // to an external script.
-  if (query["res"] == "loadWorkerThatImports") {
+  if (query["res"] == "loadWorkerThatMakesRequests") {
     // this creates a worker (same origin) that imports a redirecting script.
-    let workerURL = thisSite + resource + '?res=importScriptWorker&id=' + query["id"];
+    let workerURL = thisSite + resource + '?res=makeRequestsWorker&id=' + query["id"];
     response.setHeader("Content-Type", "application/javascript", false);
-    response.write("var w=new Worker('" + workerURL + "'); w.onmessage=function(event){ alert(event.data); }");
+    response.write("new Worker('" + workerURL + "');");
+    return;
+  }
+
+  // script that loads an internal worker that uses importScripts on a redirect
+  // to an external script.
+  if (query["res"] == "loadBlobWorkerThatMakesRequests") {
+    // this creates a worker (same origin) that imports a redirecting script.
+    let workerURL = thisSite + resource + '?res=makeRequestsWorker&id=' + query["id"];
+    response.setHeader("Content-Type", "application/javascript", false);
+    response.write("var x = new XMLHttpRequest(); x.open('GET', '" + workerURL + "'); ");
+    response.write("x.responseType = 'blob'; x.send(); ");
+    response.write("x.onload = () => { new Worker(URL.createObjectURL(x.response)); };");
     return;
   }
 
   // source for a worker that simply calls importScripts on a script that
   // redirects.
-  if (query["res"] == "importScriptWorker") {
+  if (query["res"] == "makeRequestsWorker") {
     // this is code for a worker that imports a redirected script.
-    let scriptURL = thisSite + resource + "?redir=other&res=script&id=" + query["id"];
+    let scriptURL = thisSite + resource + "?redir=other&res=script&id=script-src-redir-" + query["id"];
+    let xhrURL = thisSite + resource + "?redir=other&res=xhr-resp&id=xhr-src-redir-" + query["id"];
+    let fetchURL = thisSite + resource + "?redir=other&res=xhr-resp&id=fetch-src-redir-" + query["id"];
     response.setHeader("Content-Type", "application/javascript", false);
-    response.write("importScripts('" + scriptURL + "');");
+    response.write("try { importScripts('" + scriptURL + "'); } catch(ex) {} ");
+    response.write("var x = new XMLHttpRequest(); x.open('GET', '" + xhrURL + "'); x.send();");
+    response.write("fetch('" + fetchURL + "');");
     return;
   }
 
   // script that invokes XHR
   if (query["res"] == "xhr") {
     response.setHeader("Content-Type", "application/javascript", false);
-    var resp = 'var x = new XMLHttpRequest();x.open("GET", "' + otherSite +
-               resource+'?res=xhr-resp&testid=xhr-src-redir", false);\n' +
+    var resp = 'var x = new XMLHttpRequest();x.open("GET", "' + thisSite +
+               resource+'?redir=other&res=xhr-resp&id=xhr-src-redir", false);\n' +
                'x.send(null);';
     response.write(resp);
     return;
   }
 
   // response to XHR
   if (query["res"] == "xhr-resp") {
     response.setHeader("Access-Control-Allow-Origin", "*", false);
deleted file mode 100644
--- a/dom/security/test/csp/file_worker_redirect.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-  <head>
-    <title>Bug 949706 - CSP: Correct handling of web workers importing scripts that get redirected</title>
-  </head>
-  <body>
-  <script src="file_worker_redirect.sjs?stage_0_script_loads_worker"></script>
-</body>
-</html>
deleted file mode 100644
--- a/dom/security/test/csp/file_worker_redirect.sjs
+++ /dev/null
@@ -1,37 +0,0 @@
-// testserver customized for the needs of:
-// Bug 949706 - CSP: Correct handling of web workers importing scripts that get redirected
-
-function handleRequest(request, response)
-{
-  response.setHeader("Cache-Control", "no-cache", false);
-  response.setHeader("Content-Type", "text/html", false);
-
-  var query = request.queryString;
-
-  if (query === "stage_0_script_loads_worker") {
-    var newWorker =
-      "var myWorker = new Worker(\"file_worker_redirect.sjs?stage_1_worker_import_scripts\");" +
-      "myWorker.onmessage = function (event) { parent.checkResult(\"allowed\"); };" +
-      "myWorker.onerror = function (event) { parent.checkResult(\"blocked\"); };";
-    response.write(newWorker);
-    return;
-  }
-
-  if (query === "stage_1_worker_import_scripts") {
-    response.write("importScripts(\"file_worker_redirect.sjs?stage_2_redirect_imported_script\");");
-    return;
-  }
-
-  if (query === "stage_2_redirect_imported_script") {
-    var newLocation =
-      "http://test1.example.com/tests/dom/security/test/csp/file_worker_redirect.sjs?stage_3_target_script";
-    response.setStatusLine("1.1", 302, "Found");
-    response.setHeader("Location", newLocation, false);
-    return;
-  }
-
-  if (query === "stage_3_target_script") {
-    response.write("postMessage(\"imported script loaded\");");
-    return;
-  }
-}
--- a/dom/security/test/csp/mochitest.ini
+++ b/dom/security/test/csp/mochitest.ini
@@ -35,16 +35,17 @@ support-files =
   file_inlinestyle_main.html
   file_inlinestyle_main.html^headers^
   file_inlinestyle_main_allowed.html
   file_inlinestyle_main_allowed.html^headers^
   file_invalid_source_expression.html
   file_main.html
   file_main.html^headers^
   file_main.js
+  file_main_worker.js
   file_web_manifest.html
   file_web_manifest_remote.html
   file_web_manifest_https.html
   file_web_manifest.json
   file_web_manifest.json^headers^
   file_web_manifest_https.json
   file_web_manifest_mixed_content.html
   file_bug836922_npolicies.html
@@ -110,18 +111,16 @@ support-files =
   file_subframe_run_js_if_allowed.html^headers^
   file_leading_wildcard.html
   file_multi_policy_injection_bypass.html
   file_multi_policy_injection_bypass.html^headers^
   file_multi_policy_injection_bypass_2.html
   file_multi_policy_injection_bypass_2.html^headers^
   file_null_baseuri.html
   file_form-action.html
-  file_worker_redirect.html
-  file_worker_redirect.sjs
   file_referrerdirective.html
   referrerdirective.sjs
   file_upgrade_insecure.html
   file_upgrade_insecure_server.sjs
   file_upgrade_insecure_wsh.py
   file_upgrade_insecure_reporting.html
   file_upgrade_insecure_reporting_server.sjs
   file_upgrade_insecure_referrer.html
@@ -194,17 +193,16 @@ skip-if = buildapp == 'b2g' # intermitte
 skip-if = buildapp == 'b2g' # intermittent orange (bug 1028490)
 [test_subframe_run_js_if_allowed.html]
 [test_leading_wildcard.html]
 [test_multi_policy_injection_bypass.html]
 [test_null_baseuri.html]
 [test_referrerdirective.html]
 skip-if = buildapp == 'b2g' #no ssl support
 [test_dual_header.html]
-[test_worker_redirect.html]
 [test_upgrade_insecure.html]
 # no ssl support as well as websocket tests do not work (see test_websocket.html)
 skip-if = buildapp == 'b2g' || buildapp == 'mulet' || toolkit == 'gonk' || toolkit == 'android'
 [test_upgrade_insecure_reporting.html]
 skip-if = buildapp == 'b2g' || toolkit == 'gonk' || toolkit == 'android'
 [test_upgrade_insecure_referrer.html]
 skip-if = buildapp == 'b2g' || toolkit == 'gonk' || toolkit == 'android'
 [test_upgrade_insecure_cors.html]
--- a/dom/security/test/csp/test_CSP.html
+++ b/dom/security/test/csp/test_CSP.html
@@ -20,16 +20,32 @@ window.tests = {
   style_good: -1,
   style_bad: -1,
   frame_good: -1,
   frame_bad: -1,
   script_good: -1,
   script_bad: -1,
   xhr_good: -1,
   xhr_bad: -1,
+  fetch_good: -1,
+  fetch_bad: -1,
+  beacon_good: -1,
+  beacon_bad: -1,
+  worker_xhr_same_good: -1,
+  worker_xhr_cross_good: -1,
+  worker_fetch_same_good: -1,
+  worker_fetch_cross_good: -1,
+  worker_script_same_good: -1,
+  worker_script_cross_good: -1,
+  worker_inherited_xhr_good: -1,
+  worker_inherited_xhr_bad: -1,
+  worker_inherited_fetch_good: -1,
+  worker_inherited_fetch_bad: -1,
+  worker_inherited_script_good: -1,
+  worker_inherited_script_bad: -1,
   media_good: -1,
   media_bad: -1,
   font_good: -1,
   font_bad: -1,
   object_good: -1,
   object_bad: -1,
 };
 
@@ -76,20 +92,21 @@ examiner.prototype  = {
     SpecialPowers.removeObserver(this, "csp-on-violate-policy");
     SpecialPowers.removeObserver(this, "specialpowers-http-notify-request");
   }
 }
 
 window.examiner = new examiner();
 
 window.testResult = function(testname, result, msg) {
-  //test already complete.... forget it... remember the first result.
+  // test already complete.... forget it... remember the first result.
   if (window.tests[testname] != -1)
     return;
 
+  ok(testname in window.tests, "It's a real test");
   window.tests[testname] = result;
   is(result, true, testname + ' test: ' + msg);
 
   // if any test is incomplete, keep waiting
   for (var v in window.tests)
     if(tests[v] == -1)
       return;
 
--- a/dom/security/test/csp/test_redirects.html
+++ b/dom/security/test/csp/test_redirects.html
@@ -81,20 +81,26 @@ var testExpectedResults = { "font-src": 
                             "script-src": true,
                             "script-src-redir": false,
                             "style-src": true,
                             "style-src-redir": false,
                             "worker": true,
                             "worker-redir": false,
                             "xhr-src": true,
                             "xhr-src-redir": false,
-                            "script-src-from-worker": true, /* test runs */
-                            "script-src-redir-from-worker": false, /* redir is blocked */
-                            "img-src-from-css": true, /* test runs */
-                            "img-src-redir-from-css": false, /* redir is blocked */
+                            "from-worker": true,
+                            "script-src-redir-from-worker": true, /* redir is allowed since policy isn't inherited */
+                            "xhr-src-redir-from-worker": true, /* redir is allowed since policy isn't inherited */
+                            "fetch-src-redir-from-worker": true, /* redir is allowed since policy isn't inherited */
+                            "from-blob-worker": true,
+                            "script-src-redir-from-blob-worker": false,
+                            "xhr-src-redir-from-blob-worker": false,
+                            "fetch-src-redir-from-blob-worker": false,
+                            "img-src-from-css": true,
+                            "img-src-redir-from-css": false,
                           };
 
 // takes the name of the test, the URL that was tested, and whether the
 // load occurred
 var testResult = function(testName, url, result) {
   log("  testName: "+testName+", result: "+result+", expected: "+testExpectedResults[testName]+"\n");
   is(result, testExpectedResults[testName], testName+" test: "+url);
 
deleted file mode 100644
--- a/dom/security/test/csp/test_worker_redirect.html
+++ /dev/null
@@ -1,76 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <title>Bug 949706 - CSP: Correct handling of web workers importing scripts that get redirected</title>
-  <!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-  <div id="content" style="visibility: hidden">
-    <iframe style="width:100%;" id="testframe"></iframe>
-  </div>
-
-<script class="testbody" type="text/javascript">
-
-/* Description of the test:
- * We load a page that loads a script which then instantiates a web worker,
- * where that web worker then imports a script which gets redirected.
- * We verify that the CSP applies correctly after the imported script of
- * the worker gets redirected. More specifically, the test works as follows:
- *
- * test_worker_redirect.html
- * -> loads file_worker_redirect.html file into iframe
- * -> loads worker file_worker_redirect.sjs?stage_0_script_loads_worker
- * -> creates script file_worker_redirect.sjs?stage_1_worker_import_scripts
- * -> redirects script file_worker_redirect.sjs?stage_2_redirect_imported_script
- * -> loads target script file_worker_redirect.sjs?stage_3_target_script
- *
- * Please note that we have to use 'unsafe-eval' in the policy
- * so that workers are actually permitted by the CSP.
- *
- * The main test is loaded using:
- *   http://mochi.test:8888
- * where the imported script gets redirected to:
- *   http://test1.example.com
- */
-
-var tests = [
-  {
-    policy: "default-src 'self'; script-src 'self' 'unsafe-eval'; child-src 'self' http://test1.example.com;",
-    expected: "allowed"
-  },
-  {
-    policy: "default-src 'self'; script-src 'self' 'unsafe-eval'; child-src 'self';",
-    expected: "blocked",
-  },
-];
-
-var counter = 0;
-var curTest;
-
-function checkResult(aResult) {
-  is(aResult, curTest.expected, "Should be (" + curTest.expected + ") in Test " + counter + "!");
-  loadNextTest();
-}
-
-function loadNextTest() {
-  if (counter == tests.length) {
-    SimpleTest.finish();
-    return;
-  }
-  curTest = tests[counter++];
-  var src = "file_testserver.sjs";
-  // append the file that should be served
-  src += "?file=" + escape("tests/dom/security/test/csp/file_worker_redirect.html");
-  // append the CSP that should be used to serve the file
-  src += "&csp=" + escape(curTest.policy);
-  document.getElementById("testframe").src = src;
-}
-
-SimpleTest.waitForExplicitFinish();
-loadNextTest();
-
-</script>
-</body>
-</html>
--- a/dom/smil/TimeEvent.cpp
+++ b/dom/smil/TimeEvent.cpp
@@ -59,19 +59,18 @@ TimeEvent::GetDetail(int32_t* aDetail)
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TimeEvent::InitTimeEvent(const nsAString& aTypeArg,
                          nsIDOMWindow* aViewArg,
                          int32_t aDetailArg)
 {
-  nsresult rv = Event::InitEvent(aTypeArg, false /*doesn't bubble*/,
-                                           false /*can't cancel*/);
-  NS_ENSURE_SUCCESS(rv, rv);
+  Event::InitEvent(aTypeArg, false /*doesn't bubble*/,
+                   false /*can't cancel*/);
 
   mDetail = aDetailArg;
   mView = aViewArg;
 
   return NS_OK;
 }
 
 } // namespace dom
--- a/dom/smil/TimeEvent.h
+++ b/dom/smil/TimeEvent.h
@@ -42,22 +42,16 @@ public:
     return mDetail;
   }
 
   nsIDOMWindow* GetView() const
   {
     return mView;
   }
 
-  void InitTimeEvent(const nsAString& aType, nsIDOMWindow* aView,
-                     int32_t aDetail, ErrorResult& aRv)
-  {
-    aRv = InitTimeEvent(aType, aView, aDetail);
-  }
-
 private:
   ~TimeEvent() {}
 
   nsCOMPtr<nsIDOMWindow> mView;
   int32_t mDetail;
 };
 
 } // namespace dom
--- a/dom/speakermanager/SpeakerManager.cpp
+++ b/dom/speakermanager/SpeakerManager.cpp
@@ -85,23 +85,17 @@ SpeakerManager::DispatchSimpleEvent(cons
 {
   MOZ_ASSERT(NS_IsMainThread(), "Not running on main thread");
   nsresult rv = CheckInnerWindowCorrectness();
   if (NS_FAILED(rv)) {
     return;
   }
 
   RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
-  rv = event->InitEvent(aStr, false, false);
-
-  if (NS_FAILED(rv)) {
-    NS_WARNING("Failed to init the error event!!!");
-    return;
-  }
-
+  event->InitEvent(aStr, false, false);
   event->SetTrusted(true);
 
   rv = DispatchDOMEvent(nullptr, event, nullptr, nullptr);
   if (NS_FAILED(rv)) {
     NS_ERROR("Failed to dispatch the event!!!");
     return;
   }
 }
--- a/dom/system/nsDeviceSensors.cpp
+++ b/dom/system/nsDeviceSensors.cpp
@@ -382,25 +382,23 @@ nsDeviceSensors::FireDOMMotionEvent(nsID
     return;
   }
 
   nsCOMPtr<nsIDOMEvent> event;
   domdoc->CreateEvent(NS_LITERAL_STRING("DeviceMotionEvent"), getter_AddRefs(event));
 
   DeviceMotionEvent* me = static_cast<DeviceMotionEvent*>(event.get());
 
-  ErrorResult rv;
   me->InitDeviceMotionEvent(NS_LITERAL_STRING("devicemotion"),
                             true,
                             false,
                             *mLastAcceleration,
                             *mLastAccelerationIncludingGravity,
                             *mLastRotationRate,
-                            Nullable<double>(DEFAULT_SENSOR_POLL),
-                            rv);
+                            Nullable<double>(DEFAULT_SENSOR_POLL));
 
   event->SetTrusted(true);
 
   bool defaultActionEnabled = true;
   target->DispatchEvent(event, &defaultActionEnabled);
 
   mLastRotationRate.reset();
   mLastAccelerationIncludingGravity.reset();
--- a/dom/webidl/CompositionEvent.webidl
+++ b/dom/webidl/CompositionEvent.webidl
@@ -12,16 +12,15 @@
 interface CompositionEvent : UIEvent
 {
   readonly attribute DOMString? data;
   readonly attribute DOMString  locale;
 };
 
 partial interface CompositionEvent
 {
-  [Throws]
   void initCompositionEvent(DOMString typeArg,
                             boolean canBubbleArg,
                             boolean cancelableArg,
                             Window? viewArg,
                             DOMString? dataArg,
                             DOMString localeArg);
 };
--- a/dom/webidl/DeviceMotionEvent.webidl
+++ b/dom/webidl/DeviceMotionEvent.webidl
@@ -42,17 +42,16 @@ dictionary DeviceMotionEventInit : Event
   DeviceAccelerationInit acceleration;
   DeviceAccelerationInit accelerationIncludingGravity;
   DeviceRotationRateInit rotationRate;
   double? interval = null;
 };
 
 // Mozilla extensions.
 partial interface DeviceMotionEvent {
-  [Throws]
   void initDeviceMotionEvent(DOMString type,
                              boolean canBubble,
                              boolean cancelable,
                              DeviceAccelerationInit acceleration,
                              DeviceAccelerationInit accelerationIncludingGravity,
                              DeviceRotationRateInit rotationRate,
                              double? interval);
 };
--- a/dom/webidl/DeviceOrientationEvent.webidl
+++ b/dom/webidl/DeviceOrientationEvent.webidl
@@ -8,17 +8,16 @@
 interface DeviceOrientationEvent : Event
 {
   readonly attribute double? alpha;
   readonly attribute double? beta;
   readonly attribute double? gamma;
   readonly attribute boolean absolute;
 
   // initDeviceOrientationEvent is a Gecko specific deprecated method.
-  [Throws]
   void initDeviceOrientationEvent(DOMString type,
                                   boolean canBubble,
                                   boolean cancelable,
                                   double? alpha,
                                   double? beta,
                                   double? gamma,
                                   boolean absolute);
 };
--- a/dom/webidl/DragEvent.webidl
+++ b/dom/webidl/DragEvent.webidl
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
 [Constructor(DOMString type, optional DragEventInit eventInitDict)]
 interface DragEvent : MouseEvent
 {
   readonly attribute DataTransfer? dataTransfer;
 
-  [Throws]
   void initDragEvent(DOMString type,
                      boolean canBubble,
                      boolean cancelable,
                      Window? aView,
                      long aDetail,
                      long aScreenX,
                      long aScreenY,
                      long aClientX,
--- a/dom/webidl/Event.webidl
+++ b/dom/webidl/Event.webidl
@@ -38,17 +38,16 @@ interface Event {
   [Pure]
   readonly attribute boolean defaultPrevented;
 
   [Unforgeable, Pure]
   readonly attribute boolean isTrusted;
   [Pure]
   readonly attribute DOMHighResTimeStamp timeStamp;
 
-  [Throws]
   void initEvent(DOMString type, boolean bubbles, boolean cancelable);
 };
 
 // Mozilla specific legacy stuff.
 partial interface Event {
   const long ALT_MASK     = 0x00000001;
   const long CONTROL_MASK = 0x00000002;
   const long SHIFT_MASK   = 0x00000004;
--- a/dom/webidl/HashChangeEvent.webidl
+++ b/dom/webidl/HashChangeEvent.webidl
@@ -5,17 +5,16 @@
  */
 
 [Constructor(DOMString type, optional HashChangeEventInit eventInitDict), LegacyEventInit]
 interface HashChangeEvent : Event
 {
   readonly attribute DOMString? oldURL;
   readonly attribute DOMString? newURL;
 
-  [Throws]
   void initHashChangeEvent(DOMString typeArg,
                            boolean canBubbleArg,
                            boolean cancelableArg,
                            DOMString? oldURLArg,
                            DOMString? newURLArg);
 };
 
 dictionary HashChangeEventInit : EventInit
--- a/dom/webidl/KeyEvent.webidl
+++ b/dom/webidl/KeyEvent.webidl
@@ -219,17 +219,16 @@ interface KeyEvent
   const unsigned long DOM_VK_PLAY           = 0xFA;
   const unsigned long DOM_VK_ZOOM           = 0xFB;
   const unsigned long DOM_VK_PA1            = 0xFD;
 
   // OEM specific virtual keyCode of Windows should pass through DOM keyCode
   // for compatibility with the other web browsers on Windows.
   const unsigned long DOM_VK_WIN_OEM_CLEAR  = 0xFE;
 
-  [Throws]
   void initKeyEvent(DOMString type,
                     boolean canBubble,
                     boolean cancelable,
                     Window? view,
                     boolean ctrlKey,
                     boolean altKey,
                     boolean shiftKey,
                     boolean metaKey,
--- a/dom/webidl/MessageEvent.webidl
+++ b/dom/webidl/MessageEvent.webidl
@@ -37,17 +37,16 @@ interface MessageEvent : Event {
 
   /**
    * Initializes this event with the given data, in a manner analogous to
    * the similarly-named method on the nsIDOMEvent interface, also setting the
    * data, origin, source, and lastEventId attributes of this appropriately.
    */
   readonly attribute MessagePortList? ports;
 
-  [Throws]
   void initMessageEvent(DOMString type, boolean bubbles, boolean cancelable,
                         any data, DOMString origin, DOMString lastEventId,
                         (WindowProxy or MessagePort)? source,
                         sequence<MessagePort>? ports);
 };
 
 dictionary MessageEventInit : EventInit {
   any data;
--- a/dom/webidl/MouseEvent.webidl
+++ b/dom/webidl/MouseEvent.webidl
@@ -27,17 +27,16 @@ interface MouseEvent : UIEvent {
   readonly attribute EventTarget?   relatedTarget;
   readonly attribute DOMString?     region;
 
   // Pointer Lock
   readonly attribute long           movementX;
   readonly attribute long           movementY;
 
   // Deprecated in DOM Level 3:
-  [Throws]
   void                              initMouseEvent(DOMString typeArg, 
                                                    boolean canBubbleArg, 
                                                    boolean cancelableArg, 
                                                    Window? viewArg,
                                                    long detailArg, 
                                                    long screenXArg, 
                                                    long screenYArg, 
                                                    long clientXArg, 
@@ -86,17 +85,16 @@ partial interface MouseEvent
   const unsigned short    MOZ_SOURCE_PEN        = 2;
   const unsigned short    MOZ_SOURCE_ERASER     = 3;
   const unsigned short    MOZ_SOURCE_CURSOR     = 4;
   const unsigned short    MOZ_SOURCE_TOUCH      = 5;
   const unsigned short    MOZ_SOURCE_KEYBOARD   = 6;
 
   readonly attribute unsigned short mozInputSource;
 
-  [Throws]
   void                initNSMouseEvent(DOMString typeArg,
                                        boolean canBubbleArg,
                                        boolean cancelableArg,
                                        Window? viewArg,
                                        long detailArg,
                                        long screenXArg,
                                        long screenYArg,
                                        long clientXArg,
--- a/dom/webidl/MouseScrollEvent.webidl
+++ b/dom/webidl/MouseScrollEvent.webidl
@@ -6,17 +6,16 @@
 
 interface MouseScrollEvent : MouseEvent
 {
   const long HORIZONTAL_AXIS = 1;
   const long VERTICAL_AXIS = 2;
 
   readonly attribute long axis;
 
-  [Throws]
   void initMouseScrollEvent(DOMString type,
                             boolean canBubble,
                             boolean cancelable,
                             Window? view,
                             long detail,
                             long screenX,
                             long screenY,
                             long clientX,
--- a/dom/webidl/ScrollAreaEvent.webidl
+++ b/dom/webidl/ScrollAreaEvent.webidl
@@ -6,17 +6,16 @@
 
 interface ScrollAreaEvent : UIEvent
 {
   readonly attribute float x;
   readonly attribute float y;
   readonly attribute float width;
   readonly attribute float height;
 
-  [Throws]
   void initScrollAreaEvent(DOMString type,
                            boolean canBubble,
                            boolean cancelable,
                            Window? view,
                            long detail,
                            float x,
                            float y,
                            float width,
--- a/dom/webidl/SimpleGestureEvent.webidl
+++ b/dom/webidl/SimpleGestureEvent.webidl
@@ -19,17 +19,16 @@ interface SimpleGestureEvent : MouseEven
   attribute unsigned long allowedDirections;
 
   readonly attribute unsigned long direction;
 
   readonly attribute double delta;
 
   readonly attribute unsigned long clickCount;
 
-  [Throws]
   void initSimpleGestureEvent(DOMString typeArg,
                               boolean canBubbleArg,
                               boolean cancelableArg,
                               Window? viewArg,
                               long detailArg,
                               long screenXArg,
                               long screenYArg,
                               long clientXArg,
--- a/dom/webidl/StorageEvent.webidl
+++ b/dom/webidl/StorageEvent.webidl
@@ -15,17 +15,16 @@ interface StorageEvent : Event
 {
   readonly attribute DOMString? key;
   readonly attribute DOMString? oldValue;
   readonly attribute DOMString? newValue;
   readonly attribute DOMString? url;
   readonly attribute Storage? storageArea;
 
   // Bug 1016053 - This is not spec compliant.
-  [Throws]
   void initStorageEvent(DOMString type,
                         boolean canBubble,
                         boolean cancelable,
                         DOMString? key,
                         DOMString? oldValue,
                         DOMString? newValue,
                         DOMString? url,
                         Storage? storageArea);
--- a/dom/webidl/TouchEvent.webidl
+++ b/dom/webidl/TouchEvent.webidl
@@ -10,17 +10,16 @@ interface TouchEvent : UIEvent {
   readonly attribute TouchList targetTouches;
   readonly attribute TouchList changedTouches;
 
   readonly attribute boolean altKey;
   readonly attribute boolean metaKey;
   readonly attribute boolean ctrlKey;
   readonly attribute boolean shiftKey;
 
-  [Throws]
   void initTouchEvent(DOMString type,
                       boolean canBubble,
                       boolean cancelable,
                       Window? view,
                       long detail,
                       boolean ctrlKey,
                       boolean altKey,
                       boolean shiftKey,
--- a/dom/webidl/XULCommandEvent.webidl
+++ b/dom/webidl/XULCommandEvent.webidl
@@ -9,17 +9,16 @@ interface XULCommandEvent : UIEvent
 {
   readonly attribute boolean ctrlKey;
   readonly attribute boolean shiftKey;
   readonly attribute boolean altKey;
   readonly attribute boolean metaKey;
 
   readonly attribute Event? sourceEvent;
 
-  [Throws]
   void initCommandEvent(DOMString type,
                         boolean canBubble,
                         boolean cancelable,
                         Window? view,
                         long detail,
                         boolean ctrlKey,
                         boolean altKey,
                         boolean shiftKey,
--- a/dom/workers/ScriptLoader.cpp
+++ b/dom/workers/ScriptLoader.cpp
@@ -117,16 +117,24 @@ ChannelFromScriptURL(nsIPrincipal* princ
   nsCOMPtr<nsIURI> uri;
   rv = nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(uri),
                                                  aScriptURL, parentDoc,
                                                  baseURI);
   if (NS_FAILED(rv)) {
     return NS_ERROR_DOM_SYNTAX_ERR;
   }
 
+  // If we have the document, use it. Unfortunately, for dedicated workers
+  // 'parentDoc' ends up being the parent document, which is not the document
+  // that we want to use. So make sure to avoid using 'parentDoc' in that
+  // situation.
+  if (parentDoc && parentDoc->NodePrincipal() != principal) {
+    parentDoc = nullptr;
+  }
+
   int16_t shouldLoad = nsIContentPolicy::ACCEPT;
   rv = NS_CheckContentLoadPolicy(aContentPolicyType, uri,
                                  principal, parentDoc,
                                  NS_LITERAL_CSTRING("text/javascript"),
                                  nullptr, &shouldLoad,
                                  nsContentUtils::GetContentPolicy(),
                                  secMan);
   if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
@@ -159,18 +167,21 @@ ChannelFromScriptURL(nsIPrincipal* princ
   else {
     rv = secMan->CheckLoadURIWithPrincipal(principal, uri, 0);
     NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_SECURITY_ERR);
   }
 
   aLoadFlags |= nsIChannel::LOAD_CLASSIFY_URI;
 
   nsCOMPtr<nsIChannel> channel;
-  // If we have the document, use it
-  if (parentDoc) {
+  // If we have the document, use it. Unfortunately, for dedicated workers
+  // 'parentDoc' ends up being the parent document, which is not the document
+  // that we want to use. So make sure to avoid using 'parentDoc' in that
+  // situation.
+  if (parentDoc && parentDoc->NodePrincipal() == principal) {
     rv = NS_NewChannel(getter_AddRefs(channel),
                        uri,
                        parentDoc,
                        nsILoadInfo::SEC_NORMAL,
                        aContentPolicyType,
                        loadGroup,
                        nullptr, // aCallbacks
                        aLoadFlags,
--- a/dom/workers/ServiceWorkerEvents.cpp
+++ b/dom/workers/ServiceWorkerEvents.cpp
@@ -1041,21 +1041,17 @@ ExtendableMessageEvent::Constructor(cons
 /* static */ already_AddRefed<ExtendableMessageEvent>
 ExtendableMessageEvent::Constructor(mozilla::dom::EventTarget* aEventTarget,
                                     const nsAString& aType,
                                     const ExtendableMessageEventInit& aOptions,
                                     ErrorResult& aRv)
 {
   RefPtr<ExtendableMessageEvent> event = new ExtendableMessageEvent(aEventTarget);
 
-  aRv = event->InitEvent(aType, aOptions.mBubbles, aOptions.mCancelable);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return nullptr;
-  }
-
+  event->InitEvent(aType, aOptions.mBubbles, aOptions.mCancelable);
   bool trusted = event->Init(aEventTarget);
   event->SetTrusted(trusted);
 
   event->mData = aOptions.mData;
   event->mOrigin = aOptions.mOrigin;
   event->mLastEventId = aOptions.mLastEventId;
 
   if (aOptions.mSource.WasPassed() && !aOptions.mSource.Value().IsNull()) {
--- a/dom/workers/ServiceWorkerMessageEvent.cpp
+++ b/dom/workers/ServiceWorkerMessageEvent.cpp
@@ -137,20 +137,17 @@ ServiceWorkerMessageEvent::Constructor(c
 ServiceWorkerMessageEvent::Constructor(EventTarget* aEventTarget,
                                        const nsAString& aType,
                                        const ServiceWorkerMessageEventInit& aParam,
                                        ErrorResult& aRv)
 {
   RefPtr<ServiceWorkerMessageEvent> event =
     new ServiceWorkerMessageEvent(aEventTarget, nullptr, nullptr);
 
-  aRv = event->InitEvent(aType, aParam.mBubbles, aParam.mCancelable);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return nullptr;
-  }
+  event->InitEvent(aType, aParam.mBubbles, aParam.mCancelable);
 
   bool trusted = event->Init(aEventTarget);
   event->SetTrusted(trusted);
 
   event->mData = aParam.mData;
 
   if (aParam.mOrigin.WasPassed()) {
     event->mOrigin = aParam.mOrigin.Value();
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -567,22 +567,17 @@ private:
     NS_ASSERTION(target, "This must never be null!");
 
     aWorkerPrivate->CloseHandlerStarted();
 
     WorkerGlobalScope* globalScope = aWorkerPrivate->GlobalScope();
 
     RefPtr<Event> event = NS_NewDOMEvent(globalScope, nullptr, nullptr);
 
-    nsresult rv = event->InitEvent(NS_LITERAL_STRING("close"), false, false);
-    if (NS_FAILED(rv)) {
-      Throw(aCx, rv);
-      return false;
-    }
-
+    event->InitEvent(NS_LITERAL_STRING("close"), false, false);
     event->SetTrusted(true);
 
     globalScope->DispatchDOMEvent(nullptr, event, nullptr, nullptr);
 
     return true;
   }
 
   NS_IMETHOD Cancel() override
@@ -3068,19 +3063,17 @@ WorkerPrivate::OfflineStatusChangeEventI
   if (aIsOffline) {
     eventType.AssignLiteral("offline");
   } else {
     eventType.AssignLiteral("online");
   }
 
   RefPtr<Event> event = NS_NewDOMEvent(globalScope, nullptr, nullptr);
 
-  nsresult rv = event->InitEvent(eventType, false, false);
-  NS_ENSURE_SUCCESS_VOID(rv);
-
+  event->InitEvent(eventType, false, false);
   event->SetTrusted(true);
 
   globalScope->DispatchDOMEvent(nullptr, event, nullptr, nullptr);
 }
 
 template <class Derived>
 bool
 WorkerPrivateParent<Derived>::RegisterSharedWorker(JSContext* aCx,
@@ -3411,16 +3404,26 @@ WorkerPrivateParent<Derived>::SetPrincip
   mLoadInfo.mPrincipal = aPrincipal;
   mLoadInfo.mPrincipalIsSystem = nsContentUtils::IsSystemPrincipal(aPrincipal);
   uint16_t appStatus = aPrincipal->GetAppStatus();
   mLoadInfo.mIsInPrivilegedApp =
     (appStatus == nsIPrincipal::APP_STATUS_CERTIFIED ||
      appStatus == nsIPrincipal::APP_STATUS_PRIVILEGED);
   mLoadInfo.mIsInCertifiedApp = (appStatus == nsIPrincipal::APP_STATUS_CERTIFIED);
 
+  aPrincipal->GetCsp(getter_AddRefs(mLoadInfo.mCSP));
+
+  if (mLoadInfo.mCSP) {
+    mLoadInfo.mCSP->GetAllowsEval(&mLoadInfo.mReportCSPViolations,
+                                  &mLoadInfo.mEvalAllowed);
+  } else {
+    mLoadInfo.mEvalAllowed = true;
+    mLoadInfo.mReportCSPViolations = false;
+  }
+
   mLoadInfo.mLoadGroup = aLoadGroup;
 
   mLoadInfo.mPrincipalInfo = new PrincipalInfo();
   mLoadInfo.mPrivateBrowsing = nsContentUtils::IsInPrivateBrowsing(aLoadGroup);
 
   MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
     PrincipalToPrincipalInfo(aPrincipal, mLoadInfo.mPrincipalInfo)));
 }
@@ -4336,30 +4339,16 @@ WorkerPrivate::GetLoadInfo(JSContext* aC
       loadInfo.mWindowID = UINT64_MAX;
       loadInfo.mStorageAllowed = true;
       loadInfo.mPrivateBrowsing = false;
     }
 
     MOZ_ASSERT(loadInfo.mPrincipal);
     MOZ_ASSERT(isChrome || !loadInfo.mDomain.IsEmpty());
 
-    if (!nsContentUtils::GetContentSecurityPolicy(getter_AddRefs(loadInfo.mCSP))) {
-      NS_WARNING("Failed to get CSP!");
-      return NS_ERROR_FAILURE;
-    }
-
-    if (loadInfo.mCSP) {
-      rv = loadInfo.mCSP->GetAllowsEval(&loadInfo.mReportCSPViolations,
-                                        &loadInfo.mEvalAllowed);
-      NS_ENSURE_SUCCESS(rv, rv);
-    } else {
-      loadInfo.mEvalAllowed = true;
-      loadInfo.mReportCSPViolations = false;
-    }
-
     if (!loadInfo.mLoadGroup || aLoadGroupBehavior == OverrideLoadGroup) {
       OverrideLoadInfoLoadGroup(loadInfo);
     }
     MOZ_ASSERT(NS_LoadGroupMatchesPrincipal(loadInfo.mLoadGroup,
                                             loadInfo.mPrincipal));
 
     rv = ChannelFromScriptURLMainThread(loadInfo.mPrincipal, loadInfo.mBaseURI,
                                         document, loadInfo.mLoadGroup,
--- a/dom/workers/test/csp_worker.js
+++ b/dom/workers/test/csp_worker.js
@@ -1,16 +1,28 @@
 /**
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 onmessage = function(event) {
-  if (event.data == 0) {
-    postMessage(eval('40 + 2'));
-  } else if (event.data > 0) {
-    var worker = new Worker('csp_worker.js');
-    worker.postMessage(event.data - 1);
-  } else if (event.data == -1) {
-    importScripts('data:application/javascript;base64,ZHVtcCgnaGVsbG8gd29ybGQnKQo=');
-  } else if (event.data == -2) {
-    importScripts('javascript:dump(123);');
+  if (event.data.do == "eval") {
+    var res;
+    try {
+      res = eval("40+2");
+    }
+    catch(ex) {
+      res = ex+"";
+    }
+    postMessage(res);
+  }
+  else if (event.data.do == "nest") {
+    var worker = new Worker(event.data.uri);
+    if (--event.data.level) {
+      worker.postMessage(event.data);
+    }
+    else {
+      worker.postMessage({ do: "eval" });
+    }
+    worker.onmessage = (e) => {
+      postMessage(e.data);
+    }
   }
 }
--- a/dom/workers/test/mochitest.ini
+++ b/dom/workers/test/mochitest.ini
@@ -182,17 +182,16 @@ skip-if = buildapp == 'b2g' # b2g(Failed
 [test_resolveWorker.html]
 [test_resolveWorker-assignment.html]
 [test_rvals.html]
 [test_sharedWorker.html]
 [test_sharedWorker_performance_user_timing.html]
 skip-if = (toolkit == 'gonk' && debug) # Bug 1176223
 [test_simpleThread.html]
 [test_suspend.html]
-skip-if = buildapp == 'b2g' || e10s # b2g(test timed out, might need more time) b2g-debug(test timed out, might need more time) b2g-desktop(test timed out, might need more time) e10s(Bug 1222495 - Sets preferences directly)
 [test_terminate.html]
 [test_terminateSyncXHR.html]
 [test_threadErrors.html]
 [test_threadTimeouts.html]
 [test_throwingOnerror.html]
 [test_timeoutTracing.html]
 [test_transferable.html]
 [test_url.html]
--- a/dom/workers/test/serviceworkers/mochitest.ini
+++ b/dom/workers/test/serviceworkers/mochitest.ini
@@ -171,17 +171,17 @@ support-files =
   thirdparty/iframe2.html
   thirdparty/register.html
   thirdparty/unregister.html
   thirdparty/sw.js
   register_https.html
   gzip_redirect_worker.js
   sw_clients/navigator.html
   eval_worker.js
-  test_eval_not_allowed.html^headers^
+  test_eval_allowed.html^headers^
   opaque_intercept_worker.js
   notify_loaded.js
   test_request_context.js
   fetch/plugin/worker.js
   fetch/plugin/plugins.html
   eventsource/*
   sw_clients/file_blob_upload_frame.html
   redirect_post.sjs
@@ -199,17 +199,16 @@ skip-if = release_build
 [test_claim.html]
 [test_claim_fetch.html]
 [test_claim_oninstall.html]
 [test_close.html]
 [test_controller.html]
 [test_cross_origin_url_after_redirect.html]
 [test_empty_serviceworker.html]
 [test_eval_allowed.html]
-[test_eval_not_allowed.html]
 [test_fetch_event.html]
 [test_force_refresh.html]
 [test_gzip_redirect.html]
 [test_https_fetch.html]
 [test_https_fetch_cloned_response.html]
 [test_https_origin_after_redirect.html]
 [test_https_origin_after_redirect_cached.html]
 [test_https_synth_fetch_from_cached_sw.html]
--- a/dom/workers/test/serviceworkers/test_eval_allowed.html
+++ b/dom/workers/test/serviceworkers/test_eval_allowed.html
@@ -14,19 +14,26 @@
 <div id="content" style="display: none"></div>
 <pre id="test"></pre>
 <script class="testbody" type="text/javascript">
   function register() {
     return navigator.serviceWorker.register("eval_worker.js");
   }
 
   function runTest() {
+    try {
+      eval("1");
+      ok(false, "should throw");
+    }
+    catch (ex) {
+      ok(true, "did throw");
+    }
     register()
       .then(function(swr) {
-        ok(true, "eval in service worker script didn't cause an issue");
+        ok(true, "eval restriction didn't get inherited");
         swr.unregister();
         SimpleTest.finish();
       }).catch(function(e) {
         ok(false, "Some test failed with error " + e);
         SimpleTest.finish();
       });
   }
 
rename from dom/workers/test/serviceworkers/test_eval_not_allowed.html^headers^
rename to dom/workers/test/serviceworkers/test_eval_allowed.html^headers^
deleted file mode 100644
--- a/dom/workers/test/serviceworkers/test_eval_not_allowed.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!--
-  Any copyright is dedicated to the Public Domain.
-  http://creativecommons.org/publicdomain/zero/1.0/
--->
-<!DOCTYPE HTML>
-<html>
-<head>
-  <title>Bug 1160458 - CSP activated by default in Service Workers</title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<p id="display"></p>
-<div id="content" style="display: none"></div>
-<pre id="test"></pre>
-<script class="testbody" type="text/javascript">
-  function register() {
-    return navigator.serviceWorker.register("eval_worker.js");
-  }
-
-  function runTest() {
-    register()
-      .then(function(swr) {
-        ok(false, "eval in service worker should not be allowed when the policy prevents it");
-        swr.unregister();
-        SimpleTest.finish();
-      }).catch(function() {
-        ok(true, "eval in service worker is not allowed when the policy prevents eval");
-        SimpleTest.finish();
-      }).catch(function(e) {
-        ok(false, "Some test failed with error " + e);
-        SimpleTest.finish();
-      });
-  }
-
-  SimpleTest.waitForExplicitFinish();
-  SpecialPowers.pushPrefEnv({"set": [
-    ["dom.serviceWorkers.exemptFromPerDomainMax", true],
-    ["dom.serviceWorkers.enabled", true],
-    ["dom.serviceWorkers.testing.enabled", true],
-    ['dom.serviceWorkers.interception.enabled', true],
-  ]}, runTest);
-</script>
-</pre>
-</body>
-</html>
--- a/dom/workers/test/serviceworkers/test_imagecache_max_age.html
+++ b/dom/workers/test/serviceworkers/test_imagecache_max_age.html
@@ -37,21 +37,18 @@
           // Wait for 100ms so that the image gets expired.
           setTimeout(function() {
             iframe.src = "/tests/dom/workers/test/serviceworkers/fetch/imagecache-maxage/index.html?new"
           }, 100);
           break;
         case 2:
           is(e.data.url, "image-40px.png", "Correct url expected");
           is(e.data.url2, "image-40px.png", "Correct url expected");
-          // TODO: Uncomment this check when bug 1217571 gets fixed.
-          // Currently because of bug 1217571, the QI in imgCacheValidator::OnStartRequest()
-          // to nsICachingChannel fails, which causes the check below to fail in non-e10s.
-          //is(e.data.width, 40, "Correct width expected");
-          //is(e.data.width2, 40, "Correct width expected");
+          is(e.data.width, 40, "Correct width expected");
+          is(e.data.width2, 40, "Correct width expected");
           iframe.src = "/tests/dom/workers/test/serviceworkers/fetch/imagecache-maxage/unregister.html";
           break;
         default:
           ok(false, "This should never happen");
         }
       } else if (e.data.status == "unregistrationdone") {
         window.onmessage = null;
         SimpleTest.finish();
--- a/dom/workers/test/test_csp.html^headers^
+++ b/dom/workers/test/test_csp.html^headers^
@@ -1,2 +1,2 @@
 Cache-Control: no-cache
-Content-Security-Policy: default-src 'self'
+Content-Security-Policy: default-src 'self' blob:
--- a/dom/workers/test/test_csp.js
+++ b/dom/workers/test/test_csp.js
@@ -1,50 +1,48 @@
 /**
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
-msg = null;
-var errors = 5;
+var tests = 3;
 
-onerror = function(event) {
-  ok(true, msg);
-  if (!--errors) SimpleTest.finish();
+SimpleTest.waitForExplicitFinish();
+
+testDone = function(event) {
+  if (!--tests) SimpleTest.finish();
 }
 
-msg = "No Eval allowed";
+// Workers don't inherit CSP
 worker = new Worker("csp_worker.js");
-worker.postMessage(0);
+worker.postMessage({ do: "eval" });
 worker.onmessage = function(event) {
-  ok(false, "Eval succeeded!");
-}
-
-msg = "No Eval allowed 2";
-worker = new Worker("csp_worker.js");
-worker.postMessage(4);
-worker.onmessage = function(event) {
-  ok(false, "Eval succeeded!");
+  is(event.data, 42, "Eval succeeded!");
+  testDone();
 }
 
-msg = "ImportScripts data:";
-worker = new Worker("csp_worker.js");
-worker.postMessage(-1);
-worker.onmessage = function(event) {
-  ok(false, "Eval succeeded!");
+// blob: workers *do* inherit CSP
+xhr = new XMLHttpRequest;
+xhr.open("GET", "csp_worker.js");
+xhr.responseType = "blob";
+xhr.send();
+xhr.onload = (e) => {
+  uri = URL.createObjectURL(e.target.response);
+  worker = new Worker(uri);
+  worker.postMessage({ do: "eval" })
+  worker.onmessage = function(event) {
+    is(event.data, "Error: call to eval() blocked by CSP", "Eval threw");
+    testDone();
+  }
 }
 
-msg = "ImportScripts javascript:";
-worker = new Worker("csp_worker.js");
-worker.postMessage(-2);
-worker.onmessage = function(event) {
-  ok(false, "Eval succeeded!");
+xhr = new XMLHttpRequest;
+xhr.open("GET", "csp_worker.js");
+xhr.responseType = "blob";
+xhr.send();
+xhr.onload = (e) => {
+  uri = URL.createObjectURL(e.target.response);
+  worker = new Worker(uri);
+  worker.postMessage({ do: "nest", uri: uri, level: 3 })
+  worker.onmessage = function(event) {
+    is(event.data, "Error: call to eval() blocked by CSP", "Eval threw in nested worker");
+    testDone();
+  }
 }
-
-msg = "Loading data:something";
-try {
-  worker = new Worker("data:application/javascript;base64,ZHVtcCgnaGVsbG8gd29ybGQnKQo=");
-  ok(false, "Should have thrown!");
-} catch (e) {
-  ok(true, "Threw as expected.");
-}
-
-worker = new Worker("javascript:dump(123);");
-SimpleTest.waitForExplicitFinish();
--- a/dom/workers/test/test_suspend.html
+++ b/dom/workers/test/test_suspend.html
@@ -26,37 +26,25 @@
   var suspended = false;
   var resumed = false;
   var finished = false;
 
   var interval;
   var oldMessageCount;
   var waitCount = 0;
 
-  function setCachePref(enabled) {
-    var prefBranch = SpecialPowers.Cc["@mozilla.org/preferences-service;1"]
-                                  .getService(SpecialPowers.Ci.nsIPrefBranch);
-    if (enabled) {
-      prefBranch.setBoolPref("browser.sessionhistory.cache_subframes", true);
-    }
-    else {
-      try {
-        prefBranch.clearUserPref("browser.sessionhistory.cache_subframes");
-      } catch (e) { /* Pref didn't exist, meh */ }
-    }
-  }
-
   function finishTest() {
     if (finished) {
       return;
     }
     finished = true;
-    setCachePref(false);
-    iframe.terminateWorker();
-    SimpleTest.finish();
+    SpecialPowers.flushPrefEnv(function () {
+      iframe.terminateWorker();
+      SimpleTest.finish();
+    });
   }
 
   function waitInterval() {
     if (finished) {
       return;
     }
     is(String(iframe.location), "about:blank", "Wrong url!");
     is(suspended, true, "Not suspended?");
@@ -79,40 +67,42 @@
 
   function suspendCallback() {
     if (finished) {
       return;
     }
     is(String(iframe.location), "about:blank", "Wrong url!");
     is(suspended, false, "Already suspended?");
     is(resumed, false, "Already resumed?");
-    setCachePref(false);
-    suspended = true;
-    var iframeElement = document.getElementById("workerFrame");
-    iframeElement.onload = badOnloadCallback;
-    oldMessageCount = lastCount;
-    interval = setInterval(waitInterval, 1000);
+    SpecialPowers.popPrefEnv(function () {
+      suspended = true;
+      var iframeElement = document.getElementById("workerFrame");
+      iframeElement.onload = badOnloadCallback;
+      oldMessageCount = lastCount;
+      interval = setInterval(waitInterval, 1000);
+    });
   }
 
   function messageCallback(data) {
     if (finished) {
       return;
     }
 
     if (!suspended) {
       ok(lastCount === undefined || lastCount == data - 1,
          "Got good data, lastCount = " + lastCount + ", data = " + data);
       lastCount = data;
       if (lastCount == 25) {
-        setCachePref(true);
-        iframe.location = "about:blank";
-        // We want suspend_iframe.html to go into bfcache, so we need to flush
-        // out all pending notifications. Otherwise, if they're flushed too
-        // late, they could kick us out of the bfcache again.
-        iframe.document.body.offsetTop;
+        SpecialPowers.pushPrefEnv({"set": [["browser.sessionhistory.cache_subframes", true]]}, function () {
+          iframe.location = "about:blank";
+          // We want suspend_iframe.html to go into bfcache, so we need to flush
+          // out all pending notifications. Otherwise, if they're flushed too
+          // late, they could kick us out of the bfcache again.
+          iframe.document.body.offsetTop;
+        });
       }
       return;
     }
 
     var newLocation =
       window.location.toString().replace("test_suspend.html",
                                          "suspend_iframe.html");
     is(newLocation.indexOf(iframe.location.toString()), 0, "Wrong url!");
--- a/embedding/components/windowwatcher/nsAutoWindowStateHelper.cpp
+++ b/embedding/components/windowwatcher/nsAutoWindowStateHelper.cpp
@@ -56,19 +56,17 @@ nsAutoWindowStateHelper::DispatchEventTo
     return true;
   }
 
   ErrorResult rv;
   RefPtr<Event> event = doc->CreateEvent(NS_LITERAL_STRING("Events"), rv);
   if (rv.Failed()) {
     return false;
   }
-  NS_ENSURE_TRUE(NS_SUCCEEDED(event->InitEvent(
-                   NS_ConvertASCIItoUTF16(aEventName), true, true)),
-                 false);
+  event->InitEvent(NS_ConvertASCIItoUTF16(aEventName), true, true);
   event->SetTrusted(true);
   event->GetInternalNSEvent()->mFlags.mOnlyChromeDispatch = true;
 
   nsCOMPtr<EventTarget> target = do_QueryInterface(mWindow);
   bool defaultActionEnabled;
   target->DispatchEvent(event, &defaultActionEnabled);
   return defaultActionEnabled;
 }
--- a/gfx/2d/DrawTargetD2D1.cpp
+++ b/gfx/2d/DrawTargetD2D1.cpp
@@ -249,30 +249,33 @@ DrawTargetD2D1::ClearRect(const Rect &aR
     mDC->PushAxisAlignedClip(clipRect, isPixelAligned ? D2D1_ANTIALIAS_MODE_ALIASED : D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
     mDC->Clear();
     mDC->PopAxisAlignedClip();
 
     PopClip();
     return;
   }
 
-  mDC->SetTarget(mTempBitmap);
-  mDC->Clear();
+  RefPtr<ID2D1CommandList> list;
+  mDC->CreateCommandList(getter_AddRefs(list));
+  mDC->SetTarget(list);
 
   IntRect addClipRect;
   RefPtr<ID2D1Geometry> geom = GetClippedGeometry(&addClipRect);
 
   RefPtr<ID2D1SolidColorBrush> brush;
   mDC->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White), getter_AddRefs(brush));
   mDC->PushAxisAlignedClip(D2D1::RectF(addClipRect.x, addClipRect.y, addClipRect.XMost(), addClipRect.YMost()), D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
   mDC->FillGeometry(geom, brush);
   mDC->PopAxisAlignedClip();
 
   mDC->SetTarget(mBitmap);
-  mDC->DrawImage(mTempBitmap, D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR, D2D1_COMPOSITE_MODE_DESTINATION_OUT);
+  list->Close();
+
+  mDC->DrawImage(list, D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR, D2D1_COMPOSITE_MODE_DESTINATION_OUT);
 
   PopClip();
 
   return;
 }
 
 void
 DrawTargetD2D1::MaskSurface(const Pattern &aSource,
@@ -856,28 +859,18 @@ DrawTargetD2D1::Init(ID3D11Texture2D* aT
   if (FAILED(hr)) {
     gfxCriticalError() << "[D2D1.1] CreateBitmapFromDxgiSurface failure Code: " << hexa(hr) << " format " << (int)aFormat;
     return false;
   }
 
   mFormat = aFormat;
   D3D11_TEXTURE2D_DESC desc;
   aTexture->GetDesc(&desc);
-  desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
   mSize.width = desc.Width;
   mSize.height = desc.Height;
-  props.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
-  props.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
-
-  hr = mDC->CreateBitmap(D2DIntSize(mSize), nullptr, 0, props, (ID2D1Bitmap1**)getter_AddRefs(mTempBitmap));
-
-  if (FAILED(hr)) {
-    gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(mSize))) << "[D2D1.1] 2CreateBitmap failure " << mSize << " Code: " << hexa(hr);
-    return false;
-  }
 
   // This single solid color brush system is not very 'threadsafe', however,
   // issueing multiple drawing commands simultaneously to a single drawtarget
   // from multiple threads is unexpected since there's no way to guarantee
   // ordering in that situation anyway.
   hr = mDC->CreateSolidColorBrush(D2D1::ColorF(0, 0), getter_AddRefs(mSolidColorBrush));
 
   if (FAILED(hr)) {
@@ -924,26 +917,16 @@ DrawTargetD2D1::Init(const IntSize &aSiz
   props.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET;
   hr = mDC->CreateBitmap(D2DIntSize(aSize), nullptr, 0, props, (ID2D1Bitmap1**)getter_AddRefs(mBitmap));
 
   if (FAILED(hr)) {
     gfxCriticalError() << "[D2D1.1] 3CreateBitmap failure " << aSize << " Code: " << hexa(hr) << " format " << (int)aFormat;
     return false;
   }
 
-  props.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
-  props.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
-
-  hr = mDC->CreateBitmap(D2DIntSize(aSize), nullptr, 0, props, (ID2D1Bitmap1**)getter_AddRefs(mTempBitmap));
-
-  if (FAILED(hr)) {
-    gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(aSize))) << "[D2D1.1] failed to create new TempBitmap " << aSize << " Code: " << hexa(hr);
-    return false;
-  }
-
   mDC->SetTarget(mBitmap);
 
   hr = mDC->CreateSolidColorBrush(D2D1::ColorF(0, 0), getter_AddRefs(mSolidColorBrush));
 
   if (FAILED(hr)) {
     gfxCriticalError() << "[D2D1.1] Failure creating solid color brush.";
     return false;
   }
@@ -1040,18 +1023,18 @@ DrawTargetD2D1::PrepareForDrawing(Compos
     if (aOp != CompositionOp::OP_OVER)
       mDC->SetPrimitiveBlend(D2DPrimitiveBlendMode(aOp));
 
     return;
   }
 
   PopAllClips();
 
-  mDC->SetTarget(mTempBitmap);
-  mDC->Clear(D2D1::ColorF(0, 0));
+  mDC->CreateCommandList(getter_AddRefs(mCommandList));
+  mDC->SetTarget(mCommandList);
 
   PushAllClips();
   FlushTransformToDC();
 }
 
 void
 DrawTargetD2D1::FinalizeDrawing(CompositionOp aOp, const Pattern &aPattern)
 {
@@ -1060,20 +1043,21 @@ DrawTargetD2D1::FinalizeDrawing(Composit
   if (D2DSupportsPrimitiveBlendMode(aOp) && patternSupported) {
     if (aOp != CompositionOp::OP_OVER)
       mDC->SetPrimitiveBlend(D2D1_PRIMITIVE_BLEND_SOURCE_OVER);
     return;
   }
 
   PopAllClips();
 
-  RefPtr<ID2D1Image> image;
-  mDC->GetTarget(getter_AddRefs(image));
+  mDC->SetTarget(mBitmap);
+  mCommandList->Close();
 
-  mDC->SetTarget(mBitmap);
+  RefPtr<ID2D1CommandList> source = mCommandList;
+  mCommandList = nullptr;
 
   mDC->SetTransform(D2D1::IdentityMatrix());
   mTransformDirty = true;
 
   if (patternSupported) {
     if (D2DSupportsCompositeMode(aOp)) {
       D2D1_RECT_F rect;
       bool isAligned;
@@ -1091,17 +1075,17 @@ DrawTargetD2D1::FinalizeDrawing(Composit
           }
           mDC->Flush();
 
           tmpBitmap->CopyFromBitmap(nullptr, mBitmap, nullptr);
         }
       } else {
         PushAllClips();
       }
-      mDC->DrawImage(image, D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR, D2DCompositionMode(aOp));
+      mDC->DrawImage(source, D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR, D2DCompositionMode(aOp));
 
       if (tmpBitmap) {
         RefPtr<ID2D1BitmapBrush> brush;
         RefPtr<ID2D1Geometry> inverseGeom = GetInverseClippedGeometry();
         mDC->CreateBitmapBrush(tmpBitmap, getter_AddRefs(brush));
 
         mDC->SetPrimitiveBlend(D2D1_PRIMITIVE_BLEND_COPY);
         mDC->FillGeometry(inverseGeom, brush);
@@ -1130,17 +1114,17 @@ DrawTargetD2D1::FinalizeDrawing(Composit
     // We also need to pop all the clips to make sure any drawn content will have made it to the final bitmap.
     mDC->Flush();
 
     // We need to use a copy here because affects don't accept a surface on
     // both their in- and outputs.
     tmpBitmap->CopyFromBitmap(nullptr, mBitmap, nullptr);
 
     mBlendEffect->SetInput(0, tmpBitmap);
-    mBlendEffect->SetInput(1, mTempBitmap);
+    mBlendEffect->SetInput(1, source);
     mBlendEffect->SetValue(D2D1_BLEND_PROP_MODE, D2DBlendMode(aOp));
 
     PushAllClips();
 
     mDC->DrawImage(mBlendEffect, D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR, D2D1_COMPOSITE_MODE_BOUNDED_SOURCE_COPY);
     return;
   }
 
@@ -1163,17 +1147,17 @@ DrawTargetD2D1::FinalizeDrawing(Composit
   radialGradientEffect->SetValue(RADIAL_PROP_STOP_COLLECTION,
                                  static_cast<const GradientStopsD2D*>(pat->mStops.get())->mStopCollection);
   radialGradientEffect->SetValue(RADIAL_PROP_CENTER_1, D2D1::Vector2F(pat->mCenter1.x, pat->mCenter1.y));
   radialGradientEffect->SetValue(RADIAL_PROP_CENTER_2, D2D1::Vector2F(pat->mCenter2.x, pat->mCenter2.y));
   radialGradientEffect->SetValue(RADIAL_PROP_RADIUS_1, pat->mRadius1);
   radialGradientEffect->SetValue(RADIAL_PROP_RADIUS_2, pat->mRadius2);
   radialGradientEffect->SetValue(RADIAL_PROP_RADIUS_2, pat->mRadius2);
   radialGradientEffect->SetValue(RADIAL_PROP_TRANSFORM, D2DMatrix(pat->mMatrix * mTransform));
-  radialGradientEffect->SetInput(0, image);
+  radialGradientEffect->SetInput(0, source);
 
   mDC->DrawImage(radialGradientEffect, D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR, D2DCompositionMode(aOp));
 }
 
 void
 DrawTargetD2D1::AddDependencyOnSource(SourceSurfaceD2D1* aSource)
 {
   if (aSource->mDrawTarget && !mDependingOnTargets.count(aSource->mDrawTarget)) {
--- a/gfx/2d/DrawTargetD2D1.h
+++ b/gfx/2d/DrawTargetD2D1.h
@@ -195,17 +195,17 @@ private:
   RefPtr<ID3D11Texture2D> mTexture;
   RefPtr<ID2D1Geometry> mCurrentClippedGeometry;
   // This is only valid if mCurrentClippedGeometry is non-null. And will
   // only be the intersection of all pixel-aligned retangular clips. This is in
   // device space.
   IntRect mCurrentClipBounds;
   mutable RefPtr<ID2D1DeviceContext> mDC;
   RefPtr<ID2D1Bitmap1> mBitmap;
-  RefPtr<ID2D1Bitmap1> mTempBitmap;
+  RefPtr<ID2D1CommandList> mCommandList;
   RefPtr<ID2D1Effect> mBlendEffect;
 
   RefPtr<ID2D1SolidColorBrush> mSolidColorBrush;
 
   // We store this to prevent excessive SetTextRenderingParams calls.
   RefPtr<IDWriteRenderingParams> mTextRenderingParams;
 
   // List of pushed clips.
--- a/gfx/gl/GLLibraryEGL.cpp
+++ b/gfx/gl/GLLibraryEGL.cpp
@@ -309,23 +309,22 @@ GLLibraryEGL::EnsureInitialized(bool for
     GLLibraryLoader::LoadSymbols(mEGLLibrary, &optionalSymbols[0], nullptr, nullptr,
                                  false);
 
 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 18
     MOZ_RELEASE_ASSERT(mSymbols.fQueryStringImplementationANDROID,
                        "Couldn't find eglQueryStringImplementationANDROID");
 #endif
 
-    //Initialize client extensions
-    InitExtensionsFromDisplay(EGL_NO_DISPLAY);
+    InitClientExtensions();
 
-    GLLibraryLoader::PlatformLookupFunction lookupFunction =
+    const auto lookupFunction =
         (GLLibraryLoader::PlatformLookupFunction)mSymbols.fGetProcAddress;
 
-#ifdef XP_WIN
+    // Client exts are ready. (But not display exts!)
     if (IsExtensionSupported(ANGLE_platform_angle_d3d)) {
         GLLibraryLoader::SymLoadStruct d3dSymbols[] = {
             { (PRFuncPtr*)&mSymbols.fGetPlatformDisplayEXT, { "eglGetPlatformDisplayEXT", nullptr } },
             { nullptr, { nullptr } }
         };
 
         bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                     &d3dSymbols[0],
@@ -333,74 +332,84 @@ GLLibraryEGL::EnsureInitialized(bool for
         if (!success) {
             NS_ERROR("EGL supports ANGLE_platform_angle_d3d without exposing its functions!");
 
             MarkExtensionUnsupported(ANGLE_platform_angle_d3d);
 
             mSymbols.fGetPlatformDisplayEXT = nullptr;
         }
     }
-#endif
-    mEGLDisplay = EGL_NO_DISPLAY;
+
     // Check the ANGLE support the system has
     nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
-    mIsANGLE = IsExtensionSupported(ANGLE_platform_angle_d3d);
+    mIsANGLE = IsExtensionSupported(ANGLE_platform_angle);
 
-    if (mIsANGLE) {
+    EGLDisplay chosenDisplay = nullptr;
+
+    if (IsExtensionSupported(ANGLE_platform_angle_d3d)) {
         bool accelAngleSupport = IsAccelAngleSupported(gfxInfo);
         bool warpAngleSupport = gfxPlatform::CanUseDirect3D11ANGLE();
 
         bool shouldTryAccel = forceAccel || accelAngleSupport;
         bool shouldTryWARP = !shouldTryAccel && warpAngleSupport;
         if (gfxPrefs::WebGLANGLEForceWARP()) {
             shouldTryWARP = true;
             shouldTryAccel = false;
         }
 
         // Fallback to a WARP display if non-WARP is blacklisted,
         // or if WARP is forced
         if (shouldTryWARP) {
-            mEGLDisplay = GetAndInitWARPDisplay(*this,
-                                                EGL_DEFAULT_DISPLAY);
-            if (mEGLDisplay != EGL_NO_DISPLAY) {
+            chosenDisplay = GetAndInitWARPDisplay(*this, EGL_DEFAULT_DISPLAY);
+            if (chosenDisplay) {
                 mIsWARP = true;
             }
         }
 
-        // If falling back to WARP did not work and we don't want to try
-        // using HW accelerated ANGLE, then fail
-        if (mEGLDisplay == EGL_NO_DISPLAY && !shouldTryAccel) {
-            NS_ERROR("Fallback WARP ANGLE context failed to initialize.");
-            return false;
-        }
+        if (!chosenDisplay) {
+            // If falling back to WARP did not work and we don't want to try
+            // using HW accelerated ANGLE, then fail
+            if (!shouldTryAccel) {
+                NS_ERROR("Fallback WARP ANGLE context failed to initialize.");
+                return false;
+            }
 
-        // Hardware accelerated ANGLE path
-        if (mEGLDisplay == EGL_NO_DISPLAY && shouldTryAccel) {
+            // Hardware accelerated ANGLE path
+
             // D3D11 ANGLE only works with OMTC; there's a bug in the non-OMTC layer
             // manager, and it's pointless to try to fix it.  We also don't try
             // D3D11 ANGLE if the layer manager is prefering D3D9 (hrm, do we care?)
             if (gfxPrefs::LayersOffMainThreadCompositionEnabled() &&
                 !gfxPrefs::LayersPreferD3D9())
             {
                 if (gfxPrefs::WebGLANGLEForceD3D11()) {
-                    mEGLDisplay = GetAndInitDisplay(*this,
-                                                    LOCAL_EGL_D3D11_ONLY_DISPLAY_ANGLE);
-                } else if (gfxPrefs::WebGLANGLETryD3D11() && gfxPlatform::CanUseDirect3D11ANGLE()) {
-                    mEGLDisplay = GetAndInitDisplay(*this,
-                                                    LOCAL_EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE);
+                    chosenDisplay = GetAndInitDisplay(*this,
+                                                      LOCAL_EGL_D3D11_ONLY_DISPLAY_ANGLE);
+                } else if (gfxPrefs::WebGLANGLETryD3D11() &&
+                           gfxPlatform::CanUseDirect3D11ANGLE())
+                {
+                    chosenDisplay = GetAndInitDisplay(*this,
+                                                      LOCAL_EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE);
                 }
             }
         }
+    } else {
+        chosenDisplay = GetAndInitDisplay(*this, EGL_DEFAULT_DISPLAY);
     }
 
-    if (mEGLDisplay == EGL_NO_DISPLAY) {
-        mEGLDisplay = GetAndInitDisplay(*this, EGL_DEFAULT_DISPLAY);
+    if (!chosenDisplay) {
+        NS_WARNING("Failed to initialize a display.");
+        return false;
     }
+    mEGLDisplay = chosenDisplay;
 
-    InitExtensionsFromDisplay(mEGLDisplay);
+    InitDisplayExtensions();
+
+    ////////////////////////////////////
+    // Alright, load display exts.
 
     if (IsExtensionSupported(KHR_lock_surface)) {
         GLLibraryLoader::SymLoadStruct lockSymbols[] = {
             { (PRFuncPtr*) &mSymbols.fLockSurface,   { "eglLockSurfaceKHR",   nullptr } },
             { (PRFuncPtr*) &mSymbols.fUnlockSurface, { "eglUnlockSurfaceKHR", nullptr } },
             { nullptr, { nullptr } }
         };
 
@@ -501,37 +510,75 @@ GLLibraryEGL::EnsureInitialized(bool for
         }
     }
 
     mInitialized = true;
     reporter.SetSuccessful();
     return true;
 }
 
-void
-GLLibraryEGL::InitExtensionsFromDisplay(EGLDisplay eglDisplay)
+template<size_t N>
+static void
+MarkExtensions(const char* rawExtString, bool shouldDumpExts, const char* extType,
+               std::bitset<N>* const out)
 {
-    std::vector<nsCString> driverExtensionList;
+    MOZ_ASSERT(rawExtString);
 
-    const char* rawExts = (const char*)fQueryString(eglDisplay, LOCAL_EGL_EXTENSIONS);
-    if (rawExts) {
-        nsDependentCString exts(rawExts);
-        SplitByChar(exts, ' ', &driverExtensionList);
-    } else {
-        NS_WARNING("Failed to load EGL extension list!");
+    const nsDependentCString extString(rawExtString);
+
+    std::vector<nsCString> extList;
+    SplitByChar(extString, ' ', &extList);
+
+    if (shouldDumpExts) {
+        printf_stderr("%u EGL %s extensions: (*: recognized)\n",
+                      (uint32_t)extList.size(), extType);
     }
 
+    MarkBitfieldByStrings(extList, shouldDumpExts, sEGLExtensionNames, out);
+}
+
+void
+GLLibraryEGL::InitClientExtensions()
+{
     const bool shouldDumpExts = GLContext::ShouldDumpExts();
-    if (shouldDumpExts) {
-        printf_stderr("%i EGL driver extensions: (*: recognized)\n",
-                      (uint32_t)driverExtensionList.size());
+
+    const char* rawExtString = nullptr;
+
+#ifndef ANDROID
+    // Bug 1209612: Crashes on a number of android drivers.
+    // Ideally we would only blocklist this there, but for now we don't need the client
+    // extension list on ANDROID (we mostly need it on ANGLE), and we'd rather not crash.
+    rawExtString = (const char*)fQueryString(nullptr, LOCAL_EGL_EXTENSIONS);
+#endif
+
+    if (!rawExtString) {
+        if (shouldDumpExts) {
+            printf_stderr("No EGL client extensions.\n");
+        }
+        return;
     }
 
-    MarkBitfieldByStrings(driverExtensionList, shouldDumpExts, sEGLExtensionNames,
-                          &mAvailableExtensions);
+    MarkExtensions(rawExtString, shouldDumpExts, "client", &mAvailableExtensions);
+}
+
+void
+GLLibraryEGL::InitDisplayExtensions()
+{
+    MOZ_ASSERT(mEGLDisplay);
+
+    const bool shouldDumpExts = GLContext::ShouldDumpExts();
+
+    const auto rawExtString = (const char*)fQueryString(mEGLDisplay,
+                                                        LOCAL_EGL_EXTENSIONS);
+    if (!rawExtString) {
+        NS_WARNING("Failed to query EGL display extensions!.");
+        return;
+    }
+
+    MarkExtensions(rawExtString, shouldDumpExts, "display", &mAvailableExtensions);
 }
 
 void
 GLLibraryEGL::DumpEGLConfig(EGLConfig cfg)
 {
     int attrval;
     int err;
 
--- a/gfx/gl/GLLibraryEGL.h
+++ b/gfx/gl/GLLibraryEGL.h
@@ -108,17 +108,18 @@ public:
     GLLibraryEGL()
         : mInitialized(false),
           mEGLLibrary(nullptr),
           mIsANGLE(false),
           mIsWARP(false)
     {
     }
 
-    void InitExtensionsFromDisplay(EGLDisplay eglDisplay);
+    void InitClientExtensions();
+    void InitDisplayExtensions();
 
     /**
      * Known GL extensions that can be queried by
      * IsExtensionSupported.  The results of this are cached, and as
      * such it's safe to use this even in performance critical code.
      * If you add to this array, remember to add to the string names
      * in GLContext.cpp.
      */
--- a/image/imgLoader.cpp
+++ b/image/imgLoader.cpp
@@ -20,17 +20,17 @@
 #include "nsContentUtils.h"
 #include "nsCORSListenerProxy.h"
 #include "nsNetUtil.h"
 #include "nsNetCID.h"
 #include "nsIProtocolHandler.h"
 #include "nsMimeTypes.h"
 #include "nsStreamUtils.h"
 #include "nsIHttpChannel.h"
-#include "nsICachingChannel.h"
+#include "nsICacheInfoChannel.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIProgressEventSink.h"
 #include "nsIChannelEventSink.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
 #include "nsIFileURL.h"
 #include "nsIFile.h"
 #include "nsCRT.h"
@@ -2341,17 +2341,17 @@ imgLoader::LoadImageWithChannel(nsIChann
       // Since aCanMakeNewChannel == false, we don't need to pass content policy
       // type/principal/etc
       if (ValidateEntry(entry, uri, nullptr, nullptr, RP_Default,
                         nullptr, aObserver, aCX, requestFlags,
                         nsIContentPolicy::TYPE_INVALID, false, nullptr,
                         nullptr, imgIRequest::CORS_NONE)) {
         request = entry->GetRequest();
       } else {
-        nsCOMPtr<nsICachingChannel> cacheChan(do_QueryInterface(channel));
+        nsCOMPtr<nsICacheInfoChannel> cacheChan(do_QueryInterface(channel));
         bool bUseCacheCopy;
 
         if (cacheChan) {
           cacheChan->IsFromCache(&bUseCacheCopy);
         } else {
           bUseCacheCopy = false;
         }
 
@@ -2717,17 +2717,17 @@ imgCacheValidator::OnStartRequest(nsIReq
     MOZ_ASSERT_UNREACHABLE("OnStartRequest delivered more than once?");
     aRequest->Cancel(NS_BINDING_ABORTED);
     return NS_ERROR_FAILURE;
   }
 
   // If this request is coming from cache and has the same URI as our
   // imgRequest, the request all our proxies are pointing at is valid, and all
   // we have to do is tell them to notify their listeners.
-  nsCOMPtr<nsICachingChannel> cacheChan(do_QueryInterface(aRequest));
+  nsCOMPtr<nsICacheInfoChannel> cacheChan(do_QueryInterface(aRequest));
   nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
   if (cacheChan && channel && !mRequest->CacheChanged(aRequest)) {
     bool isFromCache = false;
     cacheChan->IsFromCache(&isFromCache);
 
     nsCOMPtr<nsIURI> channelURI;
     channel->GetURI(getter_AddRefs(channelURI));
 
--- a/image/imgRequest.cpp
+++ b/image/imgRequest.cpp
@@ -12,33 +12,31 @@
 #include "DecodePool.h"
 #include "ProgressTracker.h"
 #include "ImageFactory.h"
 #include "Image.h"
 #include "MultipartImage.h"
 #include "RasterImage.h"
 
 #include "nsIChannel.h"
-#include "nsICachingChannel.h"
+#include "nsICacheInfoChannel.h"
 #include "nsIDocument.h"
 #include "nsIThreadRetargetableRequest.h"
 #include "nsIInputStream.h"
 #include "nsIMultiPartChannel.h"
 #include "nsIHttpChannel.h"
 #include "nsIApplicationCache.h"
 #include "nsIApplicationCacheChannel.h"
 #include "nsMimeTypes.h"
 
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsISupportsPrimitives.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsContentUtils.h"
 
-#include "nsICacheEntry.h"
-
 #include "plstr.h" // PL_strcasestr(...)
 #include "nsNetUtil.h"
 #include "nsIProtocolHandler.h"
 #include "imgIRequest.h"
 
 using namespace mozilla;
 using namespace mozilla::image;
 
@@ -581,32 +579,25 @@ imgRequest::UpdateCacheEntrySize()
   mCacheEntry->SetDataSize(size);
 }
 
 void
 imgRequest::SetCacheValidation(imgCacheEntry* aCacheEntry, nsIRequest* aRequest)
 {
   /* get the expires info */
   if (aCacheEntry) {
-    nsCOMPtr<nsICachingChannel> cacheChannel(do_QueryInterface(aRequest));
+    nsCOMPtr<nsICacheInfoChannel> cacheChannel(do_QueryInterface(aRequest));
     if (cacheChannel) {
-      nsCOMPtr<nsISupports> cacheToken;
-      cacheChannel->GetCacheToken(getter_AddRefs(cacheToken));
-      if (cacheToken) {
-        nsCOMPtr<nsICacheEntry> entryDesc(do_QueryInterface(cacheToken));
-        if (entryDesc) {
-          uint32_t expiration;
-          /* get the expiration time from the caching channel's token */
-          entryDesc->GetExpirationTime(&expiration);
-
-          // Expiration time defaults to 0. We set the expiration time on our
-          // entry if it hasn't been set yet.
-          if (aCacheEntry->GetExpiryTime() == 0) {
-            aCacheEntry->SetExpiryTime(expiration);
-          }
+      uint32_t expiration = 0;
+      /* get the expiration time from the caching channel's token */
+      if (NS_SUCCEEDED(cacheChannel->GetCacheTokenExpirationTime(&expiration))) {
+        // Expiration time defaults to 0. We set the expiration time on our
+        // entry if it hasn't been set yet.
+        if (aCacheEntry->GetExpiryTime() == 0) {
+          aCacheEntry->SetExpiryTime(expiration);
         }
       }
     }
 
     // Determine whether the cache entry must be revalidated when we try to use
     // it. Currently, only HTTP specifies this information...
     nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aRequest));
     if (httpChannel) {
new file mode 100644
--- /dev/null
+++ b/image/test/mochitest/bug1217571-iframe.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1217571
+-->
+<head>
+  <title>iframe for Bug 1217571</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+  <img src="damon.jpg">
+</div>
+</body>
+</html>
--- a/image/test/mochitest/mochitest.ini
+++ b/image/test/mochitest/mochitest.ini
@@ -27,16 +27,17 @@ support-files =
   bug733553.sjs
   bug767779.sjs
   bug89419-iframe.html
   bug89419.sjs
   bug900200.png
   bug900200-ref.png
   bug1180105.sjs
   bug1180105-waiter.sjs
+  bug1217571-iframe.html
   clear.gif
   clear.png
   clear2.gif
   clear2-results.gif
   damon.jpg
   error-early.png
   green.png
   green-background.html
@@ -84,16 +85,17 @@ skip-if = (toolkit == 'android' && proce
 [test_bug733553.html]
 [test_bug767779.html]
 [test_bug865919.html]
 [test_bug89419-1.html]
 skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
 [test_bug89419-2.html]
 skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
 [test_bug1180105.html]
+[test_bug1217571.html]
 [test_animation_operators.html]
 [test_drawDiscardedImage.html]
 skip-if = toolkit == "gonk" #Bug 997034 - canvas.toDataURL() often causes lost connection to device.
 [test_error_events.html]
 [test_short_gif_header.html]
 [test_image_buffer_limit.html]
 #skip-if = toolkit != "gonk" #Image buffer limit is only set for Firefox OS currently.
 disabled = bug 1060869
new file mode 100644
--- /dev/null
+++ b/image/test/mochitest/test_bug1217571.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1217571
+-->
+<head>
+  <title>Test for Bug 1217571</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=1217571">Mozilla Bug 1217571</a>
+<p id="display"></p>
+<iframe src="bug1217571-iframe.html"></iframe>
+<iframe src="bug1217571-iframe.html"></iframe>
+<pre id="test">
+<script type="application/javascript">
+/** Test for Bug 614392**/
+
+SimpleTest.waitForExplicitFinish();
+
+window.onload = function() {
+  // Each iframe loads the same image.  Both images should share the same
+  // container from the image cache.  Check that this holds true.
+  var iframes = document.getElementsByTagName("iframe");
+  var imgs = Array.from(iframes, function (f) {
+      return SpecialPowers.wrap(f.contentDocument.getElementsByTagName("img")[0]);
+  });
+  var containers = imgs.map(function (img) {
+      return img.QueryInterface(SpecialPowers.Ci.nsIImageLoadingContent)
+                .getRequest(SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST)
+                .image;
+  });
+
+  ok(SpecialPowers.compare(containers[0], containers[1]),
+     "containers for identical images in different iframes should be identical");
+
+  SimpleTest.finish();
+}
+
+</script>
+</pre>
+</body>
+</html>
--- a/ipc/unixsocket/SocketBase.cpp
+++ b/ipc/unixsocket/SocketBase.cpp
@@ -120,16 +120,25 @@ UnixSocketRawData::UnixSocketRawData(con
   MOZ_ASSERT(aData || !aSize);
 
   MOZ_COUNT_CTOR_INHERITED(UnixSocketRawData, UnixSocketIOBuffer);
 
   ResetBuffer(static_cast<uint8_t*>(memcpy(new uint8_t[aSize], aData, aSize)),
               0, aSize, aSize);
 }
 
+UnixSocketRawData::UnixSocketRawData(UniquePtr<uint8_t[]> aData, size_t aSize)
+{
+  MOZ_ASSERT(aData || !aSize);
+
+  MOZ_COUNT_CTOR_INHERITED(UnixSocketRawData, UnixSocketIOBuffer);
+
+  ResetBuffer(aData.release(), 0, aSize, aSize);
+}
+
 UnixSocketRawData::UnixSocketRawData(size_t aSize)
 {
   MOZ_COUNT_CTOR_INHERITED(UnixSocketRawData, UnixSocketIOBuffer);
 
   ResetBuffer(new uint8_t[aSize], 0, 0, aSize);
 }
 
 UnixSocketRawData::~UnixSocketRawData()
--- a/ipc/unixsocket/SocketBase.h
+++ b/ipc/unixsocket/SocketBase.h
@@ -6,16 +6,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
 #ifndef mozilla_ipc_SocketBase_h
 #define mozilla_ipc_SocketBase_h
 
 #include "base/message_loop.h"
 #include "nsAutoPtr.h"
+#include "mozilla/UniquePtr.h"
 
 namespace mozilla {
 namespace ipc {
 
 //
 // UnixSocketBuffer
 //
 
@@ -226,16 +227,25 @@ public:
    * new instance of |UnixSocketRawData|.
    *
    * @param aData The buffer to copy.
    * @param aSize The number of bytes in |aData|.
    */
   UnixSocketRawData(const void* aData, size_t aSize);
 
   /**
+   * This constructor takes ownership of the data in aData.  The
+   * data is assumed to be aSize bytes in length.
+   *
+   * @param aData The buffer to take ownership of.
+   * @param aSize The number of bytes in |aData|.
+   */
+  UnixSocketRawData(UniquePtr<uint8_t[]> aData, size_t aSize);
+
+  /**
    * This constructor reserves aSize bytes of space. Currently
    * it's only possible to fill this buffer by calling |Receive|.
    *
    * @param aSize The number of bytes to allocate.
    */
   UnixSocketRawData(size_t aSize);
 
   /**
--- a/js/src/builtin/Module.js
+++ b/js/src/builtin/Module.js
@@ -13,45 +13,46 @@ function ModuleGetExportedNames(exportSt
     // Step 1
     let module = this;
 
     // Step 2
     if (module in exportStarSet)
         return [];
 
     // Step 3
-    exportStarSet.push(module);
+    _DefineDataProperty(exportStarSet, exportStarSet.length, module);
 
     // Step 4
     let exportedNames = [];
+    let namesCount = 0;
 
     // Step 5
     let localExportEntries = module.localExportEntries;
     for (let i = 0; i < localExportEntries.length; i++) {
         let e = localExportEntries[i];
-        exportedNames.push(e.exportName);
+        _DefineDataProperty(exportedNames, namesCount++, e.exportName);
     }
 
     // Step 6
     let indirectExportEntries = module.indirectExportEntries;
     for (let i = 0; i < indirectExportEntries.length; i++) {
         let e = indirectExportEntries[i];
-        exportedNames.push(e.exportName);
+        _DefineDataProperty(exportedNames, namesCount++, e.exportName);
     }
 
     // Step 7
     let starExportEntries = module.starExportEntries;
     for (let i = 0; i < starExportEntries.length; i++) {
         let e = starExportEntries[i];
         let requestedModule = HostResolveImportedModule(module, e.moduleRequest);
         let starNames = requestedModule.getExportedNames(exportStarSet);
         for (let j = 0; j < starNames.length; j++) {
             let n = starNames[j];
             if (n !== "default" && !(n in exportedNames))
-                exportedNames.push(n);
+                _DefineDataProperty(exportedNames, namesCount++, n);
         }
     }
 
     return exportedNames;
 }
 
 // 15.2.1.16.3 ResolveExport(exportName, resolveSet, exportStarSet)
 function ModuleResolveExport(exportName, resolveSet = [], exportStarSet = [])
@@ -67,17 +68,17 @@ function ModuleResolveExport(exportName,
     // Step 2
     for (let i = 0; i < resolveSet.length; i++) {
         let r = resolveSet[i];
         if (r.module === module && r.exportName === exportName)
             return null;
     }
 
     // Step 3
-    resolveSet.push({module: module, exportName: exportName});
+    _DefineDataProperty(resolveSet, resolveSet.length, {module: module, exportName: exportName});
 
     // Step 4
     let localExportEntries = module.localExportEntries;
     for (let i = 0; i < localExportEntries.length; i++) {
         let e = localExportEntries[i];
         if (exportName === e.exportName)
             return {module: module, bindingName: e.localName};
     }
@@ -102,17 +103,17 @@ function ModuleResolveExport(exportName,
         ThrowSyntaxError(JSMSG_BAD_DEFAULT_EXPORT);
     }
 
     // Step 7
     if (module in exportStarSet)
         return null;
 
     // Step 8
-    exportStarSet.push(module);
+    _DefineDataProperty(exportStarSet, exportStarSet.length, module);
 
     // Step 9
     let starResolution = null;
 
     // Step 10
     let starExportEntries = module.starExportEntries;
     for (let i = 0; i < starExportEntries.length; i++) {
         let e = starExportEntries[i];
@@ -148,17 +149,17 @@ function GetModuleNamespace(module)
         let exportedNames = module.getExportedNames();
         let unambiguousNames = [];
         for (let i = 0; i < exportedNames.length; i++) {
             let name = exportedNames[i];
             let resolution = module.resolveExport(name);
             if (resolution === null)
                 ThrowSyntaxError(JSMSG_MISSING_NAMESPACE_EXPORT);
             if (resolution !== "ambiguous")
-                unambiguousNames.push(name);
+                _DefineDataProperty(unambiguousNames, unambiguousNames.length, name);
         }
         namespace = ModuleNamespaceCreate(module, unambiguousNames);
     }
 
     // Step 4
     return namespace;
 }
 
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Frame-eval-30.js
@@ -0,0 +1,19 @@
+// Test that Debugger.Frame.eval correctly throws on redeclaration.
+
+load(libdir + "evalInFrame.js");
+
+let x;
+
+function f() {
+  evalInFrame(1, "var x;");
+}
+
+var log = "";
+
+try {
+  f();
+} catch (e) {
+  log += "e";
+}
+
+assertEq(log, "e");
--- a/js/src/vm/Interpreter-inl.h
+++ b/js/src/vm/Interpreter-inl.h
@@ -324,150 +324,16 @@ SetNameOperation(JSContext* cx, JSScript
                                result);
     } else {
         ok = SetProperty(cx, scope, id, val, receiver, result);
     }
     return ok && result.checkStrictErrorOrWarning(cx, scope, id, strict);
 }
 
 inline bool
-CheckLexicalNameConflict(JSContext* cx, Handle<ClonedBlockObject*> lexicalScope,
-                         HandleObject varObj, HandlePropertyName name)
-{
-    mozilla::Maybe<frontend::Definition::Kind> redeclKind;
-    RootedId id(cx, NameToId(name));
-    RootedShape shape(cx);
-    if ((shape = lexicalScope->lookup(cx, name))) {
-        redeclKind = mozilla::Some(shape->writable() ? frontend::Definition::LET
-                                                     : frontend::Definition::CONSTANT);
-    } else if (varObj->isNative() && (shape = varObj->as<NativeObject>().lookup(cx, name))) {
-        if (!shape->configurable())
-            redeclKind = mozilla::Some(frontend::Definition::VAR);
-    } else {
-        Rooted<PropertyDescriptor> desc(cx);
-        if (!GetOwnPropertyDescriptor(cx, varObj, id, &desc))
-            return false;
-        if (desc.object() && desc.hasConfigurable() && !desc.configurable())
-            redeclKind = mozilla::Some(frontend::Definition::VAR);
-    }
-
-    if (redeclKind.isSome()) {
-        ReportRuntimeRedeclaration(cx, name, *redeclKind);
-        return false;
-    }
-
-    return true;
-}
-
-inline bool
-CheckVarNameConflict(JSContext* cx, Handle<ClonedBlockObject*> lexicalScope,
-                     HandlePropertyName name)
-{
-    if (Shape* shape = lexicalScope->lookup(cx, name)) {
-        ReportRuntimeRedeclaration(cx, name, shape->writable() ? frontend::Definition::LET
-                                                               : frontend::Definition::CONSTANT);
-        return false;
-    }
-    return true;
-}
-
-inline bool
-CheckVarNameConflict(JSContext* cx, Handle<CallObject*> callObj, HandlePropertyName name)
-{
-    RootedFunction fun(cx, &callObj->callee());
-    RootedScript script(cx, fun->nonLazyScript());
-    uint32_t bodyLevelLexicalsStart = script->bindings.numVars();
-
-    for (BindingIter bi(script); !bi.done(); bi++) {
-        if (name == bi->name() &&
-            bi.isBodyLevelLexical() &&
-            bi.localIndex() >= bodyLevelLexicalsStart)
-        {
-            ReportRuntimeRedeclaration(cx, name,
-                                       bi->kind() == Binding::CONSTANT
-                                       ? frontend::Definition::CONSTANT
-                                       : frontend::Definition::LET);
-            return false;
-        }
-    }
-
-    return true;
-}
-
-inline bool
-CheckGlobalDeclarationConflicts(JSContext* cx, HandleScript script,
-                                Handle<ClonedBlockObject*> lexicalScope,
-                                HandleObject varObj)
-{
-    // Due to the extensibility of the global lexical scope, we must check for
-    // redeclaring a binding.
-    //
-    // In the case of non-syntactic scope chains, we are checking
-    // redeclarations against the non-syntactic lexical scope and the
-    // variables object that the lexical scope corresponds to.
-    RootedPropertyName name(cx);
-    BindingIter bi(script);
-
-    for (uint32_t i = 0; i < script->bindings.numVars(); i++, bi++) {
-        name = bi->name();
-        if (!CheckVarNameConflict(cx, lexicalScope, name))
-            return false;
-    }
-
-    for (uint32_t i = 0; i < script->bindings.numBodyLevelLexicals(); i++, bi++) {
-        name = bi->name();
-        if (!CheckLexicalNameConflict(cx, lexicalScope, varObj, name))
-            return false;
-    }
-
-    return true;
-}
-
-inline bool
-CheckEvalDeclarationConflicts(JSContext* cx, HandleScript script,
-                              HandleObject scopeChain, HandleObject varObj)
-{
-    // We don't need to check body-level lexical bindings for conflict. Eval
-    // scripts always execute under their own lexical scope.
-    if (script->bindings.numVars() == 0)
-        return true;
-
-    RootedPropertyName name(cx);
-    RootedObject obj(cx, scopeChain);
-    Rooted<ClonedBlockObject*> lexicalScope(cx);
-
-    // ES6 18.2.1.2 step d
-    //
-    // Check that a direct eval will not hoist 'var' bindings over lexical
-    // bindings with the same name.
-    while (obj != varObj) {
-        if (obj->is<ClonedBlockObject>()) {
-            lexicalScope = &obj->as<ClonedBlockObject>();
-            for (BindingIter bi(script); !bi.done(); bi++) {
-                name = bi->name();
-                if (!CheckVarNameConflict(cx, lexicalScope, name))
-                    return false;
-            }
-        }
-        obj = obj->enclosingScope();
-    }
-
-    if (varObj->is<CallObject>()) {
-        Rooted<CallObject*> callObj(cx, &varObj->as<CallObject>());
-        for (BindingIter bi(script); !bi.done(); bi++) {
-            name = bi->name();
-            if (!CheckVarNameConflict(cx, callObj, name))
-                return false;
-        }
-    }
-
-    return true;
-}
-
-inline bool
 DefLexicalOperation(JSContext* cx, Handle<ClonedBlockObject*> lexicalScope,
                     HandleObject varObj, HandlePropertyName name, unsigned attrs)
 {
     // Redeclaration checks should have already been done.
     MOZ_ASSERT(CheckLexicalNameConflict(cx, lexicalScope, varObj, name));
     RootedId id(cx, NameToId(name));
     RootedValue uninitialized(cx, MagicValue(JS_UNINITIALIZED_LEXICAL));
     return NativeDefineProperty(cx, lexicalScope, id, uninitialized, nullptr, nullptr, attrs);
--- a/js/src/vm/ScopeObject.cpp
+++ b/js/src/vm/ScopeObject.cpp
@@ -9,16 +9,18 @@
 #include "mozilla/PodOperations.h"
 #include "mozilla/SizePrintfMacros.h"
 
 #include "jscompartment.h"
 #include "jsiter.h"
 
 #include "builtin/ModuleObject.h"
 
+#include "frontend/ParseNode.h"
+
 #include "vm/ArgumentsObject.h"
 #include "vm/GlobalObject.h"
 #include "vm/ProxyObject.h"
 #include "vm/Shape.h"
 #include "vm/Xdr.h"
 
 #include "jsatominlines.h"
 #include "jsobjinlines.h"
@@ -2918,16 +2920,162 @@ uint32_t
 js::StaticScopeChainLength(JSObject* staticScope)
 {
     uint32_t length = 0;
     for (StaticScopeIter<NoGC> ssi(staticScope); !ssi.done(); ssi++)
         length++;
     return length;
 }
 
+bool
+js::CheckLexicalNameConflict(JSContext* cx, Handle<ClonedBlockObject*> lexicalScope,
+                             HandleObject varObj, HandlePropertyName name)
+{
+    mozilla::Maybe<frontend::Definition::Kind> redeclKind;
+    RootedId id(cx, NameToId(name));
+    RootedShape shape(cx);
+    if ((shape = lexicalScope->lookup(cx, name))) {
+        redeclKind = mozilla::Some(shape->writable() ? frontend::Definition::LET
+                                                     : frontend::Definition::CONSTANT);
+    } else if (varObj->isNative() && (shape = varObj->as<NativeObject>().lookup(cx, name))) {
+        if (!shape->configurable())
+            redeclKind = mozilla::Some(frontend::Definition::VAR);
+    } else {
+        Rooted<PropertyDescriptor> desc(cx);
+        if (!GetOwnPropertyDescriptor(cx, varObj, id, &desc))
+            return false;
+        if (desc.object() && desc.hasConfigurable() && !desc.configurable())
+            redeclKind = mozilla::Some(frontend::Definition::VAR);
+    }
+
+    if (redeclKind.isSome()) {
+        ReportRuntimeRedeclaration(cx, name, *redeclKind);
+        return false;
+    }
+
+    return true;
+}
+
+bool
+js::CheckVarNameConflict(JSContext* cx, Handle<ClonedBlockObject*> lexicalScope,
+                         HandlePropertyName name)
+{
+    if (Shape* shape = lexicalScope->lookup(cx, name)) {
+        ReportRuntimeRedeclaration(cx, name, shape->writable() ? frontend::Definition::LET
+                                                               : frontend::Definition::CONSTANT);
+        return false;
+    }
+    return true;
+}
+
+static bool
+CheckVarNameConflict(JSContext* cx, Handle<CallObject*> callObj, HandlePropertyName name)
+{
+    RootedFunction fun(cx, &callObj->callee());
+    RootedScript script(cx, fun->nonLazyScript());
+    uint32_t bodyLevelLexicalsStart = script->bindings.numVars();
+
+    for (BindingIter bi(script); !bi.done(); bi++) {
+        if (name == bi->name() &&
+            bi.isBodyLevelLexical() &&
+            bi.localIndex() >= bodyLevelLexicalsStart)
+        {
+            ReportRuntimeRedeclaration(cx, name,
+                                       bi->kind() == Binding::CONSTANT
+                                       ? frontend::Definition::CONSTANT
+                                       : frontend::Definition::LET);
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool
+js::CheckGlobalDeclarationConflicts(JSContext* cx, HandleScript script,
+                                    Handle<ClonedBlockObject*> lexicalScope,
+                                    HandleObject varObj)
+{
+    // Due to the extensibility of the global lexical scope, we must check for
+    // redeclaring a binding.
+    //
+    // In the case of non-syntactic scope chains, we are checking
+    // redeclarations against the non-syntactic lexical scope and the
+    // variables object that the lexical scope corresponds to.
+    RootedPropertyName name(cx);
+    BindingIter bi(script);
+
+    for (uint32_t i = 0; i < script->bindings.numVars(); i++, bi++) {
+        name = bi->name();
+        if (!CheckVarNameConflict(cx, lexicalScope, name))
+            return false;
+    }
+
+    for (uint32_t i = 0; i < script->bindings.numBodyLevelLexicals(); i++, bi++) {
+        name = bi->name();
+        if (!CheckLexicalNameConflict(cx, lexicalScope, varObj, name))
+            return false;
+    }
+
+    return true;
+}
+
+template <class ScopeT>
+static bool
+CheckVarNameConflictsInScope(JSContext* cx, HandleScript script, HandleObject obj)
+{
+    Rooted<ScopeT*> scope(cx);
+
+    // We return true when the scope object is not ScopeT below, because
+    // ScopeT is either ClonedBlockObject or CallObject. No other scope
+    // objects can contain lexical bindings, and there are no other overloads
+    // for CheckVarNameConflict.
+
+    if (obj->is<ScopeT>())
+        scope = &obj->as<ScopeT>();
+    else if (obj->is<DebugScopeObject>() && obj->as<DebugScopeObject>().scope().is<ScopeT>())
+        scope = &obj->as<DebugScopeObject>().scope().as<ScopeT>();
+    else
+        return true;
+
+    RootedPropertyName name(cx);
+
+    for (BindingIter bi(script); !bi.done(); bi++) {
+        name = bi->name();
+        if (!CheckVarNameConflict(cx, scope, name))
+            return false;
+    }
+
+    return true;
+}
+
+bool
+js::CheckEvalDeclarationConflicts(JSContext* cx, HandleScript script,
+                                  HandleObject scopeChain, HandleObject varObj)
+{
+    // We don't need to check body-level lexical bindings for conflict. Eval
+    // scripts always execute under their own lexical scope.
+    if (script->bindings.numVars() == 0)
+        return true;
+
+    RootedObject obj(cx, scopeChain);
+
+    // ES6 18.2.1.2 step d
+    //
+    // Check that a direct eval will not hoist 'var' bindings over lexical
+    // bindings with the same name.
+    while (obj != varObj) {
+        if (!CheckVarNameConflictsInScope<ClonedBlockObject>(cx, script, obj))
+            return false;
+        obj = obj->enclosingScope();
+    }
+
+    return CheckVarNameConflictsInScope<CallObject>(cx, script, varObj);
+}
+
 #ifdef DEBUG
 
 void
 js::DumpStaticScopeChain(JSScript* script)
 {
     DumpStaticScopeChain(script->enclosingStaticScope());
 }
 
--- a/js/src/vm/ScopeObject.h
+++ b/js/src/vm/ScopeObject.h
@@ -1442,16 +1442,29 @@ ScopeIter::enclosingScope() const
 extern bool
 CreateScopeObjectsForScopeChain(JSContext* cx, AutoObjectVector& scopeChain,
                                 HandleObject dynamicTerminatingScope,
                                 MutableHandleObject dynamicScopeObj);
 
 bool HasNonSyntacticStaticScopeChain(JSObject* staticScope);
 uint32_t StaticScopeChainLength(JSObject* staticScope);
 
+bool CheckVarNameConflict(JSContext* cx, Handle<ClonedBlockObject*> lexicalScope,
+                          HandlePropertyName name);
+
+bool CheckLexicalNameConflict(JSContext* cx, Handle<ClonedBlockObject*> lexicalScope,
+                              HandleObject varObj, HandlePropertyName name);
+
+bool CheckGlobalDeclarationConflicts(JSContext* cx, HandleScript script,
+                                     Handle<ClonedBlockObject*> lexicalScope,
+                                     HandleObject varObj);
+
+bool CheckEvalDeclarationConflicts(JSContext* cx, HandleScript script,
+                                   HandleObject scopeChain, HandleObject varObj);
+
 #ifdef DEBUG
 void DumpStaticScopeChain(JSScript* script);
 void DumpStaticScopeChain(JSObject* staticScope);
 bool
 AnalyzeEntrainedVariables(JSContext* cx, HandleScript script);
 #endif
 
 } // namespace js
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -1059,16 +1059,17 @@ nsDocumentViewer::PermitUnload(bool *aPe
 
 
 nsresult
 nsDocumentViewer::PermitUnloadInternal(bool *aShouldPrompt,
                                        bool *aPermitUnload)
 {
   AutoDontWarnAboutSyncXHR disableSyncXHRWarning;
 
+  nsresult rv = NS_OK;
   *aPermitUnload = true;
 
   if (!mDocument
    || mInPermitUnload
    || mInPermitUnloadPrompt) {
     return NS_OK;
   }
 
@@ -1098,19 +1099,17 @@ nsDocumentViewer::PermitUnloadInternal(b
   // Now, fire an BeforeUnload event to the document and see if it's ok
   // to unload...
   nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(mDocument);
   nsCOMPtr<nsIDOMEvent> event;
   domDoc->CreateEvent(NS_LITERAL_STRING("beforeunloadevent"),
                       getter_AddRefs(event));
   nsCOMPtr<nsIDOMBeforeUnloadEvent> beforeUnload = do_QueryInterface(event);
   NS_ENSURE_STATE(beforeUnload);
-  nsresult rv = event->InitEvent(NS_LITERAL_STRING("beforeunload"),
-                                 false, true);
-  NS_ENSURE_SUCCESS(rv, rv);
+  event->InitEvent(NS_LITERAL_STRING("beforeunload"), false, true);
 
   // Dispatching to |window|, but using |document| as the target.
   event->SetTarget(mDocument);
   event->SetTrusted(true);
 
   // In evil cases we might be destroyed while handling the
   // onbeforeunload event, don't let that happen. (see also bug#331040)
   RefPtr<nsDocumentViewer> kungFuDeathGrip(this);
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -4896,21 +4896,17 @@ pref("layout.accessiblecaret.use_long_ta
 pref("dom.wakelock.enabled", false);
 
 // The URL of the Firefox Accounts auth server backend
 pref("identity.fxaccounts.auth.uri", "https://api.accounts.firefox.com/v1");
 
 // disable mozsample size for now
 pref("image.mozsamplesize.enabled", false);
 
-// Enable navigator.sendBeacon on all platforms except b2g because it doesn't
-// play nicely with Firefox OS apps yet.
-#ifndef MOZ_WIDGET_GONK
 pref("beacon.enabled", true);
-#endif
 
 // Camera prefs
 pref("camera.control.face_detection.enabled", true);
 
 
 // SW Cache API
 pref("dom.caches.enabled", true);
 
--- a/security/certverifier/ExtendedValidation.cpp
+++ b/security/certverifier/ExtendedValidation.cpp
@@ -354,31 +354,16 @@ static struct nsMyTrustedEVInfo myTruste
       0xB4, 0x13, 0xFB, 0x83, 0xD9, 0x65, 0xD0, 0x6D, 0x2F, 0xF2 },
     "MG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMd"
     "QWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0"
     "IEV4dGVybmFsIENBIFJvb3Q=",
     "AQ==",
     nullptr
   },
   {
-    // CN=UTN - DATACorp SGC,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US
-    "1.3.6.1.4.1.6449.1.2.1.5.1",
-    "Comodo EV OID",
-    SEC_OID_UNKNOWN,
-    { 0x85, 0xFB, 0x2F, 0x91, 0xDD, 0x12, 0x27, 0x5A, 0x01, 0x45, 0xB6,
-      0x36, 0x53, 0x4F, 0x84, 0x02, 0x4A, 0xD6, 0x8B, 0x69, 0xB8, 0xEE,
-      0x88, 0x68, 0x4F, 0xF7, 0x11, 0x37, 0x58, 0x05, 0xB3, 0x48 },
-    "MIGTMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFr"
-    "ZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsT"
-    "GGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNv"
-    "cnAgU0dD",
-    "RL4Mi1AAIbQR0ypoBqmtaQ==",
-    nullptr
-  },
-  {
     // CN=UTN-USERFirst-Hardware,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US
     "1.3.6.1.4.1.6449.1.2.1.5.1",
     "Comodo EV OID",
     SEC_OID_UNKNOWN,
     { 0x6E, 0xA5, 0x47, 0x41, 0xD0, 0x04, 0x66, 0x7E, 0xED, 0x1B, 0x48,
       0x16, 0x63, 0x4A, 0xA3, 0xA7, 0x9E, 0x6E, 0x4B, 0x96, 0x95, 0x0F,
       0x82, 0x79, 0xDA, 0xFC, 0x8D, 0x9B, 0xD8, 0x81, 0x21, 0x37 },
     "MIGXMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFr"
@@ -592,30 +577,16 @@ static struct nsMyTrustedEVInfo myTruste
     "MIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBh"
     "ZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ"
     "QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMT"
     "Hkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwOA==",
     "AMnN0+nVfSPO",
     nullptr
   },
   {
-    // CN=TC TrustCenter Universal CA III,OU=TC TrustCenter Universal CA,O=TC TrustCenter GmbH,C=DE
-    "1.2.276.0.44.1.1.1.4",
-    "TC TrustCenter EV OID",
-    SEC_OID_UNKNOWN,
-    { 0x30, 0x9B, 0x4A, 0x87, 0xF6, 0xCA, 0x56, 0xC9, 0x31, 0x69, 0xAA,
-      0xA9, 0x9C, 0x6D, 0x98, 0x88, 0x54, 0xD7, 0x89, 0x2B, 0xD5, 0x43,
-      0x7E, 0x2D, 0x07, 0xB2, 0x9C, 0xBE, 0xDA, 0x55, 0xD3, 0x5D },
-    "MHsxCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNUQyBUcnVzdENlbnRlciBHbWJIMSQw"
-    "IgYDVQQLExtUQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0ExKDAmBgNVBAMTH1RD"
-    "IFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQSBJSUk=",
-    "YyUAAQACFI0zFQLkbPQ=",
-    nullptr
-  },
-  {
     // CN=AffirmTrust Commercial,O=AffirmTrust,C=US
     "1.3.6.1.4.1.34697.2.1",
     "AffirmTrust EV OID a",
     SEC_OID_UNKNOWN,
     { 0x03, 0x76, 0xAB, 0x1D, 0x54, 0xC5, 0xF9, 0x80, 0x3C, 0xE4, 0xB2,
       0xE2, 0x01, 0xA0, 0xEE, 0x7E, 0xEF, 0x7B, 0x57, 0xB6, 0x36, 0xE8,
       0xA9, 0x3C, 0x9B, 0x8D, 0x48, 0x60, 0xC9, 0x6F, 0x5F, 0xA7 },
     "MEQxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEfMB0GA1UEAwwW"
@@ -698,30 +669,16 @@ static struct nsMyTrustedEVInfo myTruste
       0x9B, 0x1F, 0xBA, 0x1B, 0x09, 0x9E, 0x2D, 0x29, 0x9E, 0x0F, 0x45,
       0x48, 0xBB, 0x91, 0x4F, 0x36, 0x3B, 0xC0, 0xD4, 0x53, 0x1F },
     "MDgxCzAJBgNVBAYTAkVTMRQwEgYDVQQKDAtJWkVOUEUgUy5BLjETMBEGA1UEAwwK"
     "SXplbnBlLmNvbQ==",
     "ALC3WhZIX7/hy/WL1xnmfQ==",
     nullptr
   },
   {
-    // CN=A-Trust-nQual-03,OU=A-Trust-nQual-03,O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH,C=AT
-    "1.2.40.0.17.1.22",
-    "A-Trust EV OID",
-    SEC_OID_UNKNOWN,
-    { 0x79, 0x3C, 0xBF, 0x45, 0x59, 0xB9, 0xFD, 0xE3, 0x8A, 0xB2, 0x2D,
-      0xF1, 0x68, 0x69, 0xF6, 0x98, 0x81, 0xAE, 0x14, 0xC4, 0xB0, 0x13,
-      0x9A, 0xC7, 0x88, 0xA7, 0x8A, 0x1A, 0xFC, 0xCA, 0x02, 0xFB },
-    "MIGNMQswCQYDVQQGEwJBVDFIMEYGA1UECgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hl"
-    "cmhlaXRzc3lzdGVtZSBpbSBlbGVrdHIuIERhdGVudmVya2VociBHbWJIMRkwFwYD"
-    "VQQLDBBBLVRydXN0LW5RdWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5RdWFsLTAz",
-    "AWwe",
-    nullptr
-  },
-  {
     // CN=T-TeleSec GlobalRoot Class 3,OU=T-Systems Trust Center,O=T-Systems Enterprise Services GmbH,C=DE
     "1.3.6.1.4.1.7879.13.24.1",
     "T-Systems EV OID",
     SEC_OID_UNKNOWN,
     { 0xFD, 0x73, 0xDA, 0xD3, 0x1C, 0x64, 0x4F, 0xF1, 0xB4, 0x3B, 0xEF,
       0x0C, 0xCD, 0xDA, 0x96, 0x71, 0x0B, 0x9C, 0xD9, 0x87, 0x5E, 0xCA,
       0x7E, 0x31, 0x70, 0x7A, 0xF3, 0xE9, 0x6D, 0x52, 0x2B, 0xBD },
     "MIGCMQswCQYDVQQGEwJERTErMCkGA1UECgwiVC1TeXN0ZW1zIEVudGVycHJpc2Ug"
--- a/testing/mochitest/tests/SimpleTest/ExtensionTestUtils.js
+++ b/testing/mochitest/tests/SimpleTest/ExtensionTestUtils.js
@@ -1,11 +1,11 @@
 var ExtensionTestUtils = {};
 
-ExtensionTestUtils.loadExtension = function(ext)
+ExtensionTestUtils.loadExtension = function(ext, id = null)
 {
   var testResolve;
   var testDone = new Promise(resolve => { testResolve = resolve; });
 
   var messageHandler = new Map();
 
   function testHandler(kind, pass, msg, ...args) {
     if (kind == "test-eq") {
@@ -32,17 +32,17 @@ ExtensionTestUtils.loadExtension = funct
       if (!handler) {
         return;
       }
 
       handler(...args);
     },
   };
 
-  var extension = SpecialPowers.loadExtension(ext, handler);
+  var extension = SpecialPowers.loadExtension(id, ext, handler);
 
   extension.awaitMessage = (msg) => {
     return new Promise(resolve => {
       if (messageHandler.has(msg)) {
         throw new Error("only one message handler allowed");
       }
 
       messageHandler.set(msg, (...args) => {
--- a/testing/specialpowers/content/specialpowersAPI.js
+++ b/testing/specialpowers/content/specialpowersAPI.js
@@ -1998,19 +1998,21 @@ SpecialPowersAPI.prototype = {
   removeServiceWorkerDataForExampleDomain: function() {
     this.notifyObserversInParentProcess(null, "browser:purge-domain-data", "example.com");
   },
 
   cleanUpSTSData: function(origin, flags) {
     return this._sendSyncMessage('SPCleanUpSTSData', {origin: origin, flags: flags || 0});
   },
 
-  loadExtension: function(ext, handler) {
-    let uuidGenerator = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
-    let id = uuidGenerator.generateUUID().number;
+  loadExtension: function(id, ext, handler) {
+    if (!id) {
+      let uuidGenerator = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
+      id = uuidGenerator.generateUUID().number;
+    }
 
     let resolveStartup, resolveUnload, rejectStartup;
     let startupPromise = new Promise((resolve, reject) => {
       resolveStartup = resolve;
       rejectStartup = reject;
     });
     let unloadPromise = new Promise(resolve => { resolveUnload = resolve; });
 
--- a/testing/web-platform/meta/content-security-policy/blink-contrib/worker-eval-blocked.sub.html.ini
+++ b/testing/web-platform/meta/content-security-policy/blink-contrib/worker-eval-blocked.sub.html.ini
@@ -1,5 +1,5 @@
 [worker-eval-blocked.sub.html]
   type: testharness
-  [Violation report status OK.]
+  [Expecting alerts: ["eval blocked"\]]
     expected: FAIL
 
--- a/testing/web-platform/meta/content-security-policy/blink-contrib/worker-function-function-blocked.sub.html.ini
+++ b/testing/web-platform/meta/content-security-policy/blink-contrib/worker-function-function-blocked.sub.html.ini
@@ -1,5 +1,5 @@
 [worker-function-function-blocked.sub.html]
   type: testharness
-  [Violation report status OK.]
+  [Expecting alerts: ["Function() function blocked"\]]
     expected: FAIL
 
--- a/toolkit/components/extensions/Extension.jsm
+++ b/toolkit/components/extensions/Extension.jsm
@@ -32,16 +32,18 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
                                   "resource://gre/modules/NetUtil.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
                                   "resource://gre/modules/FileUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "OS",
                                   "resource://gre/modules/osfile.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
                                   "resource://gre/modules/PrivateBrowsingUtils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
+                                  "resource://gre/modules/Preferences.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Task",
                                   "resource://gre/modules/Task.jsm");
 
 Cu.import("resource://gre/modules/ExtensionManagement.jsm");
 
 // Register built-in parts of the API. Other parts may be registered
 // in browser/, mobile/, or b2g/.
 ExtensionManagement.registerScript("chrome://extensions/content/ext-alarms.js");
@@ -644,36 +646,64 @@ ExtensionData.prototype = {
 
     let localeData = yield this.readLocaleFile(locale);
 
     this.selectedLocale = locale;
     return localeData;
   }),
 };
 
+// All moz-extension URIs use a machine-specific UUID rather than the
+// extension's own ID in the host component. This makes it more
+// difficult for web pages to detect whether a user has a given add-on
+// installed (by trying to load a moz-extension URI referring to a
+// web_accessible_resource from the extension). getExtensionUUID
+// returns the UUID for a given add-on ID.
+function getExtensionUUID(id)
+{
+  const PREF_NAME = "extensions.webextensions.uuids";
+
+  let pref = Preferences.get(PREF_NAME, "{}");
+  let map = {};
+  try {
+    map = JSON.parse(pref);
+  } catch (e) {
+    Cu.reportError(`Error parsing ${PREF_NAME}.`);
+  }
+
+  if (id in map) {
+    return map[id];
+  }
+
+  let uuidGenerator = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
+  let uuid = uuidGenerator.generateUUID().number;
+  uuid = uuid.slice(1, -1); // Strip of { and } off the UUID.
+
+  map[id] = uuid;
+  Preferences.set(PREF_NAME, JSON.stringify(map));
+  return uuid;
+}
+
 // We create one instance of this class per extension. |addonData|
 // comes directly from bootstrap.js when initializing.
 this.Extension = function(addonData)
 {
   ExtensionData.call(this, addonData.resourceURI);
 
-  let uuidGenerator = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
-  let uuid = uuidGenerator.generateUUID().number;
-  uuid = uuid.slice(1, -1); // Strip of { and } off the UUID.
-  this.uuid = uuid;
+  this.uuid = getExtensionUUID(addonData.id);
 
   if (addonData.cleanupFile) {
     Services.obs.addObserver(this, "xpcom-shutdown", false);
     this.cleanupFile = addonData.cleanupFile || null;
     delete addonData.cleanupFile;
   }
 
   this.addonData = addonData;
   this.id = addonData.id;
-  this.baseURI = Services.io.newURI("moz-extension://" + uuid, null, null);
+  this.baseURI = Services.io.newURI("moz-extension://" + this.uuid, null, null);
   this.baseURI.QueryInterface(Ci.nsIURL);
   this.principal = this.createPrincipal();
 
   this.views = new Set();
 
   this.onStartup = null;
 
   this.hasShutdown = false;
--- a/toolkit/components/extensions/ExtensionContent.jsm
+++ b/toolkit/components/extensions/ExtensionContent.jsm
@@ -28,17 +28,16 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
                                   "resource://gre/modules/PrivateBrowsingUtils.jsm");
 
 Cu.import("resource://gre/modules/ExtensionUtils.jsm");
 var {
   runSafeSyncWithoutClone,
   MessageBroker,
   Messenger,
-  ignoreEvent,
   injectAPI,
   flushJarCache,
 } = ExtensionUtils;
 
 function isWhenBeforeOrSame(when1, when2)
 {
   let table = {"document_start": 0,
                "document_end": 1,
--- a/toolkit/components/extensions/ExtensionUtils.jsm
+++ b/toolkit/components/extensions/ExtensionUtils.jsm
@@ -240,22 +240,37 @@ SingletonEventManager.prototype = {
       addListener: (...args) => this.addListener(...args),
       removeListener: (...args) => this.removeListener(...args),
       hasListener: (...args) => this.hasListener(...args),
     };
   },
 };
 
 // Simple API for event listeners where events never fire.
-function ignoreEvent()
+function ignoreEvent(context, name)
 {
   return {
-    addListener: function(context, callback) {},
-    removeListener: function(context, callback) {},
-    hasListener: function(context, callback) {},
+    addListener: function(callback) {
+      let id = context.extension.id;
+      let frame = Components.stack.caller;
+      let msg = `In add-on ${id}, attempting to use listener "${name}", which is unimplemented.`;
+      let winID = context.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+        .getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID;
+      let scriptError = Cc["@mozilla.org/scripterror;1"]
+        .createInstance(Ci.nsIScriptError);
+      scriptError.initWithWindowID(msg, frame.filename, null,
+                                   frame.lineNumber, frame.columnNumber,
+                                   Ci.nsIScriptError.warningFlag,
+                                   "content javascript", winID);
+      let consoleService = Cc['@mozilla.org/consoleservice;1']
+        .getService(Ci.nsIConsoleService);
+      consoleService.logMessage(scriptError);
+    },
+    removeListener: function(callback) {},
+    hasListener: function(callback) {},
   };
 }
 
 // Copy an API object from |source| into the scope |dest|.
 function injectAPI(source, dest)
 {
   for (let prop in source) {
     // Skip names prefixed with '_'.
--- a/toolkit/components/extensions/ext-alarms.js
+++ b/toolkit/components/extensions/ext-alarms.js
@@ -1,14 +1,13 @@
 var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
 Cu.import("resource://gre/modules/ExtensionUtils.jsm");
 var {
   EventManager,
-  ignoreEvent,
   runSafe,
 } = ExtensionUtils;
 
 // WeakMap[Extension -> Set[Alarm]]
 var alarmsMap = new WeakMap();
 
 // WeakMap[Extension -> Set[callback]]
 var alarmCallbacksMap = new WeakMap();
--- a/toolkit/components/extensions/ext-cookies.js
+++ b/toolkit/components/extensions/ext-cookies.js
@@ -1,13 +1,12 @@
 const { interfaces: Ci, utils: Cu } = Components;
 Cu.import("resource://gre/modules/ExtensionUtils.jsm");
 var {
   EventManager,
-  ignoreEvent,
   runSafe,
 } = ExtensionUtils;
 
 // Cookies from private tabs currently can't be enumerated.
 var DEFAULT_STORE = "firefox-default";
 
 function convert(cookie) {
   let result = {
--- a/toolkit/components/extensions/ext-notifications.js
+++ b/toolkit/components/extensions/ext-notifications.js
@@ -133,13 +133,13 @@ extensions.registerPrivilegedAPI("notifi
 
         notificationCallbacksMap.get(extension).add(listener);
         return () => {
           notificationCallbacksMap.get(extension).delete(listener);
         };
       }).api(),
 
       // FIXME
-      onButtonClicked: ignoreEvent(),
-      onClicked: ignoreEvent(),
+      onButtonClicked: ignoreEvent(context, "notifications.onButtonClicked"),
+      onClicked: ignoreEvent(context, "notifications.onClicked"),
     },
   };
 });
--- a/toolkit/components/extensions/ext-runtime.js
+++ b/toolkit/components/extensions/ext-runtime.js
@@ -1,14 +1,18 @@
 var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
+XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
+                                  "resource://gre/modules/AppConstants.jsm");
+
 Cu.import("resource://gre/modules/ExtensionUtils.jsm");
 var {
   EventManager,
   ignoreEvent,
+  runSafe,
 } = ExtensionUtils;
 
 function processRuntimeConnectParams(win, ...args) {
   let extensionId, connectInfo;
 
   // connect("...") and connect("...", { ... })
   if (typeof args[0] == "string") {
     extensionId = args.shift();
@@ -32,17 +36,17 @@ extensions.registerAPI((extension, conte
     runtime: {
       onStartup: new EventManager(context, "runtime.onStartup", fire => {
         extension.onStartup = fire;
         return () => {
           extension.onStartup = null;
         };
       }).api(),
 
-      onInstalled: ignoreEvent(),
+      onInstalled: ignoreEvent(context, "runtime.onInstalled"),
 
       onMessage: context.messenger.onMessage("runtime.onMessage"),
 
       onConnect: context.messenger.onConnect("runtime.onConnect"),
 
       connect: function(...args) {
         let { extensionId, connectInfo } = processRuntimeConnectParams(context.contentWindow, ...args);
 
@@ -69,11 +73,29 @@ extensions.registerAPI((extension, conte
         return Cu.cloneInto(extension.manifest, context.cloneScope);
       },
 
       id: extension.id,
 
       getURL: function(url) {
         return extension.baseURI.resolve(url);
       },
+
+      getPlatformInfo: function(callback) {
+        let os = AppConstants.platform;
+        if (os == "macosx") {
+          os = "mac";
+        }
+
+        let abi = Services.appinfo.XPCOMABI;
+        let [arch, compiler] = abi.split("-");
+        if (arch == "x86") {
+          arch = "x86-32";
+        } else if (arch == "x86_64") {
+          arch = "x86-64";
+        }
+
+        let info = {os, arch};
+        runSafe(context, callback, info);
+      },
     },
   };
 });
--- a/toolkit/components/extensions/ext-storage.js
+++ b/toolkit/components/extensions/ext-storage.js
@@ -1,17 +1,16 @@
 var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
 XPCOMUtils.defineLazyModuleGetter(this, "ExtensionStorage",
                                   "resource://gre/modules/ExtensionStorage.jsm");
 
 Cu.import("resource://gre/modules/ExtensionUtils.jsm");
 var {
   EventManager,
-  ignoreEvent,
   runSafe,
 } = ExtensionUtils;
 
 extensions.registerPrivilegedAPI("storage", (extension, context) => {
   return {
     storage: {
       local: {
         get: function(keys, callback) {
--- a/toolkit/components/extensions/ext-webNavigation.js
+++ b/toolkit/components/extensions/ext-webNavigation.js
@@ -63,12 +63,12 @@ extensions.registerPrivilegedAPI("webNav
   return {
     webNavigation: {
       onBeforeNavigate: new WebNavigationEventManager(context, "onBeforeNavigate").api(),
       onCommitted: new WebNavigationEventManager(context, "onCommitted").api(),
       onDOMContentLoaded: new WebNavigationEventManager(context, "onDOMContentLoaded").api(),
       onCompleted: new WebNavigationEventManager(context, "onCompleted").api(),
       onErrorOccurred: new WebNavigationEventManager(context, "onErrorOccurred").api(),
       onReferenceFragmentUpdated: new WebNavigationEventManager(context, "onReferenceFragmentUpdated").api(),
-      onCreatedNavigationTarget: ignoreEvent(),
+      onCreatedNavigationTarget: ignoreEvent(context, "webNavigation.onCreatedNavigationTarget"),
     },
   };
 });
--- a/toolkit/components/extensions/ext-webRequest.js
+++ b/toolkit/components/extensions/ext-webRequest.js
@@ -6,16 +6,17 @@ XPCOMUtils.defineLazyModuleGetter(this, 
                                   "resource://gre/modules/MatchPattern.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "WebRequest",
                                   "resource://gre/modules/WebRequest.jsm");
 
 Cu.import("resource://gre/modules/ExtensionUtils.jsm");
 var {
   SingletonEventManager,
   runSafeSync,
+  ignoreEvent,
 } = ExtensionUtils;
 
 // EventManager-like class specifically for WebRequest. Inherits from
 // SingletonEventManager. Takes care of converting |details| parameter
 // when invoking listeners.
 function WebRequestEventManager(context, eventName)
 {
   let name = `webRequest.${eventName}`;
@@ -121,11 +122,15 @@ extensions.registerPrivilegedAPI("webReq
       onBeforeSendHeaders: new WebRequestEventManager(context, "onBeforeSendHeaders").api(),
       onSendHeaders: new WebRequestEventManager(context, "onSendHeaders").api(),
       onHeadersReceived: new WebRequestEventManager(context, "onHeadersReceived").api(),
       onResponseStarted: new WebRequestEventManager(context, "onResponseStarted").api(),
       onCompleted: new WebRequestEventManager(context, "onCompleted").api(),
       handlerBehaviorChanged: function() {
         // TODO: Flush all caches.
       },
+
+      // TODO
+      onBeforeRedirect: ignoreEvent(context, "webRequest.onBeforeRedirect"),
+      onErrorOccurred: ignoreEvent(context, "webRequest.onErrorOccurred"),
     },
   };
 });
--- a/toolkit/components/extensions/test/mochitest/mochitest.ini
+++ b/toolkit/components/extensions/test/mochitest/mochitest.ini
@@ -16,19 +16,21 @@ support-files =
   file_script_xhr.js
   file_sample.html
 
 [test_ext_simple.html]
 [test_ext_geturl.html]
 [test_ext_contentscript.html]
 [test_ext_webrequest.html]
 [test_ext_generate.html]
+[test_ext_localStorage.html]
 [test_ext_notifications.html]
 [test_ext_runtime_connect.html]
 [test_ext_runtime_disconnect.html]
+[test_ext_runtime_getPlatformInfo.html]
 [test_ext_sandbox_var.html]
 [test_ext_sendmessage_reply.html]
 [test_ext_sendmessage_doublereply.html]
 [test_ext_storage.html]
 [test_ext_background_runtime_connect_params.html]
 [test_ext_cookies.html]
 [test_ext_bookmarks.html]
 [test_ext_alarms.html]
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/test/mochitest/test_ext_localStorage.html
@@ -0,0 +1,60 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>WebExtension test</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
+  <script type="text/javascript" src="head.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+
+<script type="application/javascript;version=1.8">
+"use strict";
+
+function backgroundScript() {
+  var hasRun = localStorage.getItem("has-run");
+  var result;
+  if (!hasRun) {
+    localStorage.setItem("has-run", "yup");
+    localStorage.setItem("test-item", "item1");
+    result = "item1";
+  } else {
+    var data = localStorage.getItem("test-item");
+    if (data == "item1") {
+      localStorage.setItem("test-item", "item2");
+      result = "item2";
+    } else if (data == "item2") {
+      localStorage.removeItem("test-item");
+      result = "deleted";
+    } else if (!data) {
+      localStorage.clear();
+      result = "cleared";
+    }
+  }
+  browser.test.sendMessage("result", result);
+  browser.test.notifyPass("localStorage");
+}
+
+let extensionData = {
+  background: "(" + backgroundScript.toString() + ")()",
+};
+
+add_task(function* test_contentscript() {
+  let id = "test-webextension@mozilla.com";
+  const RESULTS = ["item1", "item2", "deleted", "cleared", "item1"];
+
+  for (let expected of RESULTS) {
+    let extension = ExtensionTestUtils.loadExtension(extensionData, id);
+    let [, actual] = yield Promise.all([extension.startup(), extension.awaitMessage("result")]);
+    yield extension.awaitFinish("localStorage");
+    yield extension.unload();
+
+    is(actual, expected, "got expected localStorage data");
+  }
+});
+</script>
+
+</body>
+</html>
--- a/toolkit/components/extensions/test/mochitest/test_ext_notifications.html
+++ b/toolkit/components/extensions/test/mochitest/test_ext_notifications.html
@@ -12,16 +12,19 @@
 <script type="application/javascript;version=1.8">
 
 add_task(function* test_notifications() {
   function backgroundScript() {
     browser.test.log("running background script");
 
     var opts = {title: "Testing Notification", message: "Carry on"};
 
+    // Test an unimplemented listener.
+    browser.notifications.onClicked.addListener(function() {});
+
     browser.notifications.create("5", opts, function(id) {
       browser.test.sendMessage("running", id);
       browser.test.notifyPass("background test passed");
     });
   }
 
   let extensionData = {
     manifest: {
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/test/mochitest/test_ext_runtime_getPlatformInfo.html
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>WebExtension test</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
+  <script type="text/javascript" src="head.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+
+<script type="application/javascript;version=1.8">
+"use strict";
+
+function backgroundScript() {
+  browser.runtime.getPlatformInfo(info => {
+    var validOSs = ["mac", "win", "android", "cros", "linux", "openbsd"];
+    var validArchs = ["arm", "x86-32", "x86-64"];
+
+    browser.test.assertTrue(validOSs.indexOf(info.os) != -1, "OS is valid");
+    browser.test.assertTrue(validArchs.indexOf(info.arch) != -1, "Architecture is valid");
+    browser.test.notifyPass("runtime.getPlatformInfo");
+  });
+}
+
+let extensionData = {
+  background: "(" + backgroundScript.toString() + ")()",
+};
+
+add_task(function* test_contentscript() {
+  let extension = ExtensionTestUtils.loadExtension(extensionData);
+  yield extension.startup();
+  yield extension.awaitFinish("runtime.getPlatformInfo");
+  yield extension.unload();
+});
+</script>
+
+</body>
+</html>
--- a/widget/gonk/libdisplay/DisplaySurface.h
+++ b/widget/gonk/libdisplay/DisplaySurface.h
@@ -73,18 +73,16 @@ public:
     // advanceFrame may be called again.
     virtual status_t advanceFrame() = 0;
 
     // onFrameCommitted is called after the frame has been committed to the
     // hardware composer. The surface collects the release fence for this
     // frame's buffer.
     virtual void onFrameCommitted() = 0;
 
-    virtual void dump(String8& result) const = 0;
-
     virtual void resizeBuffers(const uint32_t w, const uint32_t h) = 0;
 
     // setReleaseFenceFd stores a fence file descriptor that will signal when the
     // current buffer is no longer being read. This fence will be returned to
     // the producer when the current buffer is released by updateTexImage().
     // Multiple fences can be set for a given buffer; they will be merged into
     // a single union fence. The SurfaceTexture will close the file descriptor
     // when finished with it.
--- a/widget/gonk/libdisplay/FramebufferSurface.cpp
+++ b/widget/gonk/libdisplay/FramebufferSurface.cpp
@@ -197,15 +197,11 @@ void FramebufferSurface::onFrameCommitte
 
 status_t FramebufferSurface::compositionComplete()
 {
     // Actual implementaiton is in GonkDisplay::SwapBuffers()
     // XXX need to move that to here.
     return NO_ERROR;
 }
 
-void FramebufferSurface::dump(String8& result) const {
-    ConsumerBase::dump(result);
-}
-
 // ----------------------------------------------------------------------------
 }; // namespace android
 // ----------------------------------------------------------------------------
--- a/widget/gonk/libdisplay/FramebufferSurface.h
+++ b/widget/gonk/libdisplay/FramebufferSurface.h
@@ -36,19 +36,16 @@ public:
     FramebufferSurface(int disp, uint32_t width, uint32_t height, uint32_t format, const sp<StreamConsumer>& sc);
 
     // From DisplaySurface
     virtual status_t beginFrame(bool mustRecompose);
     virtual status_t prepareFrame(CompositionType compositionType);
     virtual status_t compositionComplete();
     virtual status_t advanceFrame();
     virtual void onFrameCommitted();
-    // Implementation of DisplaySurface::dump(). Note that ConsumerBase also
-    // has a non-virtual dump() with the same signature.
-    virtual void dump(String8& result) const;
     // Cannot resize a buffers in a FramebufferSurface. Only works with virtual
     // displays.
     virtual void resizeBuffers(const uint32_t /*w*/, const uint32_t /*h*/) { };
 
     // setReleaseFenceFd stores a fence file descriptor that will signal when the
     // current buffer is no longer being read. This fence will be returned to
     // the producer when the current buffer is released by updateTexImage().
     // Multiple fences can be set for a given buffer; they will be merged into
--- a/widget/gonk/libdisplay/GonkDisplay.h
+++ b/widget/gonk/libdisplay/GonkDisplay.h
@@ -71,17 +71,17 @@ public:
     virtual ANativeWindowBuffer* DequeueBuffer() = 0;
 
     virtual bool QueueBuffer(ANativeWindowBuffer* buf) = 0;
 
     virtual void UpdateDispSurface(EGLDisplay dpy, EGLSurface sur) = 0;
 
     virtual NativeData GetNativeData(
         GonkDisplay::DisplayType aDisplayType,
-        android::IGraphicBufferProducer* aProducer = nullptr) = 0;
+        android::IGraphicBufferProducer* aSink = nullptr) = 0;
 
     virtual void NotifyBootAnimationStopped() = 0;
 
     float xdpi;
     int32_t surfaceformat;
 };
 
 MOZ_EXPORT __attribute__ ((weak))
--- a/widget/gonk/libdisplay/GonkDisplayICS.cpp
+++ b/widget/gonk/libdisplay/GonkDisplayICS.cpp
@@ -201,17 +201,17 @@ GonkDisplayICS::UpdateDispSurface(EGLDis
 
 void
 GonkDisplayICS::SetDispReleaseFd(int fd)
 {
 }
 
 GonkDisplay::NativeData
 GonkDisplayICS::GetNativeData(GonkDisplay::DisplayType aDisplayType,
-                              android::IGraphicBufferProducer* aProducer)
+                              android::IGraphicBufferProducer* aSink)
 {
     MOZ_ASSERT(aDisplayType == DISPLAY_PRIMARY, "ICS gonk supports primary display only.");
 
     NativeData data;
     data.mNativeWindow = static_cast<ANativeWindow *>(mFBSurface.get());
     data.mXdpi = xdpi;
 
     return data;
--- a/widget/gonk/libdisplay/GonkDisplayICS.h
+++ b/widget/gonk/libdisplay/GonkDisplayICS.h
@@ -52,17 +52,17 @@ public:
 
     virtual int GetPrevDispAcquireFd()
     {
         return -1;
     }
 
     virtual NativeData GetNativeData(
         GonkDisplay::DisplayType aDisplayType,
-        android::IGraphicBufferProducer* aProducer = nullptr);
+        android::IGraphicBufferProducer* aSink = nullptr);
 
     virtual void NotifyBootAnimationStopped() {}
 
 private:
     hw_module_t const*        mModule;
     hwc_composer_device_t*    mHwc;
     android::sp<android::FramebufferNativeWindow> mFBSurface;
 };
--- a/widget/gonk/libdisplay/GonkDisplayJB.cpp
+++ b/widget/gonk/libdisplay/GonkDisplayJB.cpp
@@ -21,16 +21,19 @@
 #include <gui/GraphicBufferAlloc.h>
 #endif
 
 #include <hardware/hardware.h>
 #include <hardware/hwcomposer.h>
 #include <hardware/power.h>
 #include <suspend/autosuspend.h>
 
+#if ANDROID_VERSION >= 19
+#include "VirtualDisplaySurface.h"
+#endif
 #include "FramebufferSurface.h"
 #if ANDROID_VERSION == 17
 #include "GraphicBufferAlloc.h"
 #endif
 #include "mozilla/Assertions.h"
 
 #define DEFAULT_XDPI 75.0
 
@@ -105,46 +108,47 @@ GonkDisplayJB::GonkDisplayJB()
     err = hw_get_module(POWER_HARDWARE_MODULE_ID,
                                            (hw_module_t const**)&mPowerModule);
     if (!err)
         mPowerModule->init(mPowerModule);
     ALOGW_IF(err, "Couldn't load %s module (%s)", POWER_HARDWARE_MODULE_ID, strerror(-err));
 
     mAlloc = new GraphicBufferAlloc();
 
-    CreateSurface(mSTClient, mDispSurface, mWidth, mHeight);
+    CreateFramebufferSurface(mSTClient, mDispSurface, mWidth, mHeight);
 
     mList = (hwc_display_contents_1_t *)calloc(1, sizeof(*mList) + (sizeof(hwc_layer_1_t)*2));
 
     uint32_t usage = GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER;
     if (mFBDevice) {
         // If device uses fb, they can not use single buffer for boot animation
         mSTClient->perform(mSTClient.get(), NATIVE_WINDOW_SET_BUFFER_COUNT, 2);
         mSTClient->perform(mSTClient.get(), NATIVE_WINDOW_SET_USAGE, usage);
     } else if (mHwc) {
         PowerOnDisplay(HWC_DISPLAY_PRIMARY);
         // For devices w/ hwc v1.0 or no hwc, this buffer can not be created,
         // only create this buffer for devices w/ hwc version > 1.0.
-        CreateSurface(mBootAnimSTClient, mBootAnimDispSurface, mWidth, mHeight);
+        CreateFramebufferSurface(mBootAnimSTClient, mBootAnimDispSurface, mWidth, mHeight);
     }
 }
 
 GonkDisplayJB::~GonkDisplayJB()
 {
     if (mHwc)
         hwc_close_1(mHwc);
     if (mFBDevice)
         framebuffer_close(mFBDevice);
     free(mList);
 }
 
 void
-GonkDisplayJB::CreateSurface(android::sp<ANativeWindow>& aNativeWindow,
-                             android::sp<android::DisplaySurface>& aDisplaySurface,
-                             uint32_t aWidth, uint32_t aHeight)
+GonkDisplayJB::CreateFramebufferSurface(android::sp<ANativeWindow>& aNativeWindow,
+                                        android::sp<android::DisplaySurface>& aDisplaySurface,
+                                        uint32_t aWidth,
+                                        uint32_t aHeight)
 {
 #if ANDROID_VERSION >= 21
     sp<IGraphicBufferProducer> producer;
     sp<IGraphicBufferConsumer> consumer;
     BufferQueue::createBufferQueue(&producer, &consumer, mAlloc);
 #elif ANDROID_VERSION >= 19
     sp<BufferQueue> consumer = new BufferQueue(mAlloc);
     sp<IGraphicBufferProducer> producer = consumer;
@@ -161,16 +165,38 @@ GonkDisplayJB::CreateSurface(android::sp
     aNativeWindow = new SurfaceTextureClient(
         static_cast<sp<ISurfaceTexture>>(aDisplaySurface->getBufferQueue()));
 #else
     aNativeWindow = new Surface(producer);
 #endif
 }
 
 void
+GonkDisplayJB::CreateVirtualDisplaySurface(android::IGraphicBufferProducer* aSink,
+                                           android::sp<ANativeWindow>& aNativeWindow,
+                                           android::sp<android::DisplaySurface>& aDisplaySurface)
+{
+#if ANDROID_VERSION >= 21
+    sp<IGraphicBufferProducer> producer;
+    sp<IGraphicBufferConsumer> consumer;
+    BufferQueue::createBufferQueue(&producer, &consumer, mAlloc);
+#elif ANDROID_VERSION >= 19
+    sp<BufferQueue> consumer = new BufferQueue(mAlloc);
+    sp<IGraphicBufferProducer> producer = consumer;
+#endif
+
+#if ANDROID_VERSION >= 19
+    sp<VirtualDisplaySurface> virtualDisplay;
+    virtualDisplay = new VirtualDisplaySurface(-1, aSink, producer, consumer, String8("VirtualDisplaySurface"));
+    aDisplaySurface = virtualDisplay;
+    aNativeWindow = new Surface(virtualDisplay);
+#endif
+}
+
+void
 GonkDisplayJB::SetEnabled(bool enabled)
 {
     if (enabled) {
         autosuspend_disable();
         mPowerModule->setInteractive(mPowerModule, true);
     }
 
     if (!enabled && mEnabledCallback) {
@@ -381,17 +407,17 @@ GonkDisplayJB::PowerOnDisplay(int aDpy)
     }
 #else
     mHwc->blank(mHwc, aDpy, 0);
 #endif
 }
 
 GonkDisplay::NativeData
 GonkDisplayJB::GetNativeData(GonkDisplay::DisplayType aDisplayType,
-                             android::IGraphicBufferProducer* aProducer)
+                             android::IGraphicBufferProducer* aSink)
 {
     NativeData data;
 
     if (aDisplayType == DISPLAY_PRIMARY) {
         data.mNativeWindow = mSTClient;
         data.mDisplaySurface = mDispSurface;
         data.mXdpi = xdpi;
     } else if (aDisplayType == DISPLAY_EXTERNAL) {
@@ -404,21 +430,25 @@ GonkDisplayJB::GetNativeData(GonkDisplay
         };
         mHwc->getDisplayAttributes(mHwc, aDisplayType, 0, attrs, values);
         int width = values[0];
         int height = values[1];
         // FIXME!! values[2] returns 0 for external display, which doesn't
         // sound right, Bug 1169176 is the follow-up bug for this issue.
         data.mXdpi = values[2] ? values[2] / 1000.f : DEFAULT_XDPI;
         PowerOnDisplay(HWC_DISPLAY_EXTERNAL);
-        CreateSurface(data.mNativeWindow, data.mDisplaySurface, width, height);
+        CreateFramebufferSurface(data.mNativeWindow,
+                                 data.mDisplaySurface,
+                                 width,
+                                 height);
     } else if (aDisplayType == DISPLAY_VIRTUAL) {
-        // TODO: Bug 1161874 (the support of WifiDisplay) should fill up the
-        // implementation of virtual display.
-        MOZ_CRASH("Display type of virtual is not supported yet.");
+        data.mXdpi = xdpi;
+        CreateVirtualDisplaySurface(aSink,
+                                    data.mNativeWindow,
+                                    data.mDisplaySurface);
     }
 
     return data;
 }
 
 __attribute__ ((visibility ("default")))
 GonkDisplay*
 GetGonkDisplay()
--- a/widget/gonk/libdisplay/GonkDisplayJB.h
+++ b/widget/gonk/libdisplay/GonkDisplayJB.h
@@ -43,24 +43,28 @@ public:
     virtual bool QueueBuffer(ANativeWindowBuffer* buf);
 
     virtual void UpdateDispSurface(EGLDisplay dpy, EGLSurface sur);
 
     bool Post(buffer_handle_t buf, int fence);
 
     virtual NativeData GetNativeData(
         GonkDisplay::DisplayType aDisplayType,
-        android::IGraphicBufferProducer* aProducer = nullptr);
+        android::IGraphicBufferProducer* aSink = nullptr);
 
     virtual void NotifyBootAnimationStopped();
 
 private:
-    void CreateSurface(android::sp<ANativeWindow>& aNativeWindow,
-                       android::sp<android::DisplaySurface>& aDisplaySurface,
-                       uint32_t aWidth, uint32_t aHeight);
+    void CreateFramebufferSurface(android::sp<ANativeWindow>& aNativeWindow,
+                                  android::sp<android::DisplaySurface>& aDisplaySurface,
+                                  uint32_t aWidth, uint32_t aHeight);
+    void CreateVirtualDisplaySurface(android::IGraphicBufferProducer* aSink,
+                                     android::sp<ANativeWindow>& aNativeWindow,
+                                     android::sp<android::DisplaySurface>& aDisplaySurface);
+
     void PowerOnDisplay(int aDpy);
 
     int DoQueueBuffer(ANativeWindowBuffer* buf);
 
     hw_module_t const*        mModule;
     hw_module_t const*        mFBModule;
     hwc_composer_device_1_t*  mHwc;
     framebuffer_device_t*     mFBDevice;
--- a/widget/gonk/nsScreenManagerGonk.cpp
+++ b/widget/gonk/nsScreenManagerGonk.cpp
@@ -107,18 +107,20 @@ SurfaceFormatToColorDepth(int32_t aSurfa
     }
     return 24; // GGL_PIXEL_FORMAT_RGBX_8888
 }
 
 // nsScreenGonk.cpp
 
 nsScreenGonk::nsScreenGonk(uint32_t aId,
                            GonkDisplay::DisplayType aDisplayType,
-                           const GonkDisplay::NativeData& aNativeData)
+                           const GonkDisplay::NativeData& aNativeData,
+                           NotifyDisplayChangedEvent aEventVisibility)
     : mId(aId)
+    , mEventVisibility(aEventVisibility)
     , mNativeWindow(aNativeData.mNativeWindow)
     , mDpi(aNativeData.mXdpi)
     , mScreenRotation(nsIScreen::ROTATION_0_DEG)
     , mPhysicalScreenRotation(nsIScreen::ROTATION_0_DEG)
 #if ANDROID_VERSION >= 17
     , mDisplaySurface(aNativeData.mDisplaySurface)
 #endif
     , mIsMirroring(false)
@@ -176,16 +178,22 @@ nsScreenGonk::GetId(uint32_t *outId)
 }
 
 uint32_t
 nsScreenGonk::GetId()
 {
     return mId;
 }
 
+NotifyDisplayChangedEvent
+nsScreenGonk::GetEventVisibility()
+{
+    return mEventVisibility;
+}
+
 NS_IMETHODIMP
 nsScreenGonk::GetRect(int32_t *outLeft,  int32_t *outTop,
                       int32_t *outWidth, int32_t *outHeight)
 {
     *outLeft = mVirtualBounds.x;
     *outTop = mVirtualBounds.y;
 
     *outWidth = mVirtualBounds.width;
@@ -766,33 +774,38 @@ NotifyDisplayChange(uint32_t aId, bool a
 {
     NS_DispatchToMainThread(new NotifyTask(aId, aConnected));
 }
 
 } // end of unnamed namespace.
 
 nsresult
 nsScreenManagerGonk::AddScreen(GonkDisplay::DisplayType aDisplayType,
-                               android::IGraphicBufferProducer* aSink)
+                               android::IGraphicBufferProducer* aSink,
+                               NotifyDisplayChangedEvent aEventVisibility)
 {
     MOZ_ASSERT(NS_IsMainThread());
 
     NS_ENSURE_TRUE(aDisplayType < GonkDisplay::DisplayType::NUM_DISPLAY_TYPES,
                    NS_ERROR_FAILURE);
 
     uint32_t id = GetIdFromType(aDisplayType);
     NS_ENSURE_TRUE(!IsScreenConnected(id), NS_ERROR_FAILURE);
 
     GonkDisplay::NativeData nativeData =
         GetGonkDisplay()->GetNativeData(aDisplayType, aSink);
-    nsScreenGonk* screen = new nsScreenGonk(id, aDisplayType, nativeData);
-
+    nsScreenGonk* screen = new nsScreenGonk(id,
+                                            aDisplayType,
+                                            nativeData,
+                                            aEventVisibility);
     mScreens.AppendElement(screen);
 
-    NotifyDisplayChange(id, true);
+    if (aEventVisibility == NotifyDisplayChangedEvent::Observable) {
+        NotifyDisplayChange(id, true);
+    }
 
     // By default, non primary screen does mirroring.
     if (aDisplayType != GonkDisplay::DISPLAY_PRIMARY &&
         gfxPrefs::ScreenMirroringEnabled()) {
         screen->EnableMirroring();
     }
 
     return NS_OK;
@@ -801,25 +814,28 @@ nsScreenManagerGonk::AddScreen(GonkDispl
 nsresult
 nsScreenManagerGonk::RemoveScreen(GonkDisplay::DisplayType aDisplayType)
 {
     MOZ_ASSERT(NS_IsMainThread());
 
     NS_ENSURE_TRUE(aDisplayType < GonkDisplay::DisplayType::NUM_DISPLAY_TYPES,
                    NS_ERROR_FAILURE);
 
+    NotifyDisplayChangedEvent eventVisibility = NotifyDisplayChangedEvent::Observable;
     uint32_t screenId = GetIdFromType(aDisplayType);
     NS_ENSURE_TRUE(IsScreenConnected(screenId), NS_ERROR_FAILURE);
 
     for (size_t i = 0; i < mScreens.Length(); i++) {
         if (mScreens[i]->GetId() == screenId) {
             if (mScreens[i]->IsMirroring()) {
                 mScreens[i]->DisableMirroring();
             }
+            eventVisibility = mScreens[i]->GetEventVisibility();
             mScreens.RemoveElementAt(i);
             break;
         }
     }
 
-    NotifyDisplayChange(screenId, false);
-
+    if (eventVisibility == NotifyDisplayChangedEvent::Observable) {
+      NotifyDisplayChange(screenId, false);
+    }
     return NS_OK;
 }
--- a/widget/gonk/nsScreenManagerGonk.h
+++ b/widget/gonk/nsScreenManagerGonk.h
@@ -39,37 +39,44 @@ namespace android {
 };
 
 namespace mozilla {
 namespace gl {
     class GLContext;
 }
 }
 
+enum class NotifyDisplayChangedEvent : int8_t {
+  Observable,
+  Suppressed
+};
+
 class nsScreenGonk : public nsBaseScreen
 {
     typedef mozilla::hal::ScreenConfiguration ScreenConfiguration;
     typedef mozilla::GonkDisplay GonkDisplay;
 
 public:
     nsScreenGonk(uint32_t aId,
                  GonkDisplay::DisplayType aDisplayType,
-                 const GonkDisplay::NativeData& aNativeData);
+                 const GonkDisplay::NativeData& aNativeData,
+                 NotifyDisplayChangedEvent aEventVisibility);
 
     ~nsScreenGonk();
 
     NS_IMETHOD GetId(uint32_t* aId);
     NS_IMETHOD GetRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight);
     NS_IMETHOD GetAvailRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight);
     NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth);
     NS_IMETHOD GetColorDepth(int32_t* aColorDepth);
     NS_IMETHOD GetRotation(uint32_t* aRotation);
     NS_IMETHOD SetRotation(uint32_t  aRotation);
 
     uint32_t GetId();
+    NotifyDisplayChangedEvent GetEventVisibility();
     nsIntRect GetRect();
     float GetDpi();
     int32_t GetSurfaceFormat();
     ANativeWindow* GetNativeWindow();
     nsIntRect GetNaturalBoundsUntyped();
     uint32_t EffectiveScreenRotation();
     ScreenConfiguration GetConfiguration();
     bool IsPrimaryScreen();
@@ -109,16 +116,17 @@ public:
                     mozilla::gl::GLContext* aGLContext);
     hwc_display_t GetEGLDisplay();
     hwc_surface_t GetEGLSurface();
     void UpdateMirroringWidget(already_AddRefed<nsWindow>& aWindow); // Primary screen only
     nsWindow* GetMirroringWidget(); // Primary screen only
 
 protected:
     uint32_t mId;
+    NotifyDisplayChangedEvent mEventVisibility;
     int32_t mColorDepth;
     android::sp<ANativeWindow> mNativeWindow;
     float mDpi;
     int32_t mSurfaceFormat;
     nsIntRect mNaturalBounds; // Screen bounds w/o rotation taken into account.
     nsIntRect mVirtualBounds; // Screen bounds w/ rotation taken into account.
     uint32_t mScreenRotation;
     uint32_t mPhysicalScreenRotation;
@@ -150,17 +158,18 @@ public:
 
     static already_AddRefed<nsScreenManagerGonk> GetInstance();
     static already_AddRefed<nsScreenGonk> GetPrimaryScreen();
 
     void Initialize();
     void DisplayEnabled(bool aEnabled);
 
     nsresult AddScreen(GonkDisplay::DisplayType aDisplayType,
-                       android::IGraphicBufferProducer* aSink = nullptr);
+                       android::IGraphicBufferProducer* aSink = nullptr,
+                       NotifyDisplayChangedEvent aEventVisibility = NotifyDisplayChangedEvent::Observable);
 
     nsresult RemoveScreen(GonkDisplay::DisplayType aDisplayType);
 
 protected:
     ~nsScreenManagerGonk();
     void VsyncControl(bool aEnabled);
     uint32_t GetIdFromType(GonkDisplay::DisplayType aDisplayType);
     bool IsScreenConnected(uint32_t aId);
--- a/xpcom/components/nsComponentManager.cpp
+++ b/xpcom/components/nsComponentManager.cpp
@@ -1744,17 +1744,22 @@ nsComponentManagerImpl::IsContractIDRegi
 {
   if (NS_WARN_IF(!aClass)) {
     return NS_ERROR_INVALID_ARG;
   }
 
   nsFactoryEntry* entry = GetFactoryEntry(aClass, strlen(aClass));
 
   if (entry) {
-    *aResult = true;
+    // UnregisterFactory might have left a stale nsFactoryEntry in
+    // mContractIDs, so we should check to see whether this entry has
+    // anything useful.
+    *aResult = (bool(entry->mModule) ||
+                bool(entry->mFactory) ||
+                bool(entry->mServiceObject));
   } else {
     *aResult = false;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsComponentManagerImpl::EnumerateCIDs(nsISimpleEnumerator** aEnumerator)