Merge m-c to inbound. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Wed, 26 Aug 2015 14:33:07 -0400
changeset 288187 13cd9ed4b792b79ab7b18d3b008482c6078382d7
parent 288032 4d45f860006cbfac37911d101b847ee176254067 (current diff)
parent 288070 fea87cbeaa6b64510dff835549ed906fe405d558 (diff)
child 288188 0d8d4b4178e4ae9777133cc78e26947c11429fb7
push id4816
push userpehrsons@gmail.com
push dateThu, 27 Aug 2015 07:20:58 +0000
reviewersmerge
milestone43.0a1
Merge m-c to inbound. a=merge
browser/base/content/test/plugins/browser_pluginplaypreview.js
browser/base/content/test/plugins/browser_pluginplaypreview2.js
browser/base/content/test/plugins/browser_pluginplaypreview3.js
browser/base/content/test/plugins/plugin_test_w_src.html
dom/plugins/base/nsPluginPlayPreviewInfo.cpp
dom/plugins/base/nsPluginPlayPreviewInfo.h
testing/web-platform/meta/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/message-event.html.ini
testing/web-platform/mozilla/meta/service-workers/service-worker/registration.https.html.ini
toolkit/themes/osx/global/toolbar/toolbar-background-inactive.png
toolkit/themes/osx/global/toolbar/toolbar-background.gif
--- a/accessible/base/nsCoreUtils.cpp
+++ b/accessible/base/nsCoreUtils.cpp
@@ -113,43 +113,43 @@ nsCoreUtils::DispatchClickEvent(nsITreeB
   DispatchMouseEvent(NS_MOUSE_BUTTON_DOWN, cnvdX, cnvdY,
                      tcContent, tcFrame, presShell, rootWidget);
 
   DispatchMouseEvent(NS_MOUSE_BUTTON_UP, cnvdX, cnvdY,
                      tcContent, tcFrame, presShell, rootWidget);
 }
 
 void
-nsCoreUtils::DispatchMouseEvent(uint32_t aEventType, int32_t aX, int32_t aY,
+nsCoreUtils::DispatchMouseEvent(EventMessage aMessage, int32_t aX, int32_t aY,
                                 nsIContent *aContent, nsIFrame *aFrame,
                                 nsIPresShell *aPresShell, nsIWidget *aRootWidget)
 {
-  WidgetMouseEvent event(true, aEventType, aRootWidget,
+  WidgetMouseEvent event(true, aMessage, aRootWidget,
                          WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal);
 
   event.refPoint = LayoutDeviceIntPoint(aX, aY);
 
   event.clickCount = 1;
   event.button = WidgetMouseEvent::eLeftButton;
   event.time = PR_IntervalNow();
   event.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
 
   nsEventStatus status = nsEventStatus_eIgnore;
   aPresShell->HandleEventWithTarget(&event, aFrame, aContent, &status);
 }
 
 void
-nsCoreUtils::DispatchTouchEvent(uint32_t aEventType, int32_t aX, int32_t aY,
+nsCoreUtils::DispatchTouchEvent(EventMessage aMessage, int32_t aX, int32_t aY,
                                 nsIContent* aContent, nsIFrame* aFrame,
                                 nsIPresShell* aPresShell, nsIWidget* aRootWidget)
 {
   if (!dom::TouchEvent::PrefEnabled())
     return;
 
-  WidgetTouchEvent event(true, aEventType, aRootWidget);
+  WidgetTouchEvent event(true, aMessage, aRootWidget);
 
   event.time = PR_IntervalNow();
 
   // XXX: Touch has an identifier of -1 to hint that it is synthesized.
   nsRefPtr<dom::Touch> t = new dom::Touch(-1, LayoutDeviceIntPoint(aX, aY),
                                           nsIntPoint(1, 1), 0.0f, 1.0f);
   t->SetTarget(aContent);
   event.touches.AppendElement(t);
--- a/accessible/base/nsCoreUtils.h
+++ b/accessible/base/nsCoreUtils.h
@@ -1,16 +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/. */
 
 #ifndef nsCoreUtils_h_
 #define nsCoreUtils_h_
 
+#include "mozilla/EventForwards.h"
 #include "nsIContent.h"
 #include "nsIDocument.h" // for GetShell()
 #include "nsIPresShell.h"
 
 #include "nsPoint.h"
 #include "nsTArray.h"
 
 class nsRange;
@@ -44,40 +45,42 @@ public:
    */
   static void DispatchClickEvent(nsITreeBoxObject *aTreeBoxObj,
                                  int32_t aRowIndex, nsITreeColumn *aColumn,
                                  const nsAString& aPseudoElt = EmptyString());
 
   /**
    * Send mouse event to the given element.
    *
-   * @param aEventType   [in] an event type (see BasicEvents.h for constants)
+   * @param aMessage     [in] an event message (see EventForwards.h)
    * @param aX           [in] x coordinate in dev pixels
    * @param aY           [in] y coordinate in dev pixels
    * @param aContent     [in] the element
    * @param aFrame       [in] frame of the element
    * @param aPresShell   [in] the presshell for the element
    * @param aRootWidget  [in] the root widget of the element
    */
-  static void DispatchMouseEvent(uint32_t aEventType, int32_t aX, int32_t aY,
+  static void DispatchMouseEvent(mozilla::EventMessage aMessage,
+                                 int32_t aX, int32_t aY,
                                  nsIContent *aContent, nsIFrame *aFrame,
                                  nsIPresShell *aPresShell, nsIWidget *aRootWidget);
 
   /**
    * Send a touch event with a single touch point to the given element.
    *
-   * @param aEventType   [in] an event type (see BasicEvents.h for constants)
+   * @param aMessage     [in] an event message (see EventForwards.h)
    * @param aX           [in] x coordinate in dev pixels
    * @param aY           [in] y coordinate in dev pixels
    * @param aContent     [in] the element
    * @param aFrame       [in] frame of the element
    * @param aPresShell   [in] the presshell for the element
    * @param aRootWidget  [in] the root widget of the element
    */
-  static void DispatchTouchEvent(uint32_t aEventType, int32_t aX, int32_t aY,
+  static void DispatchTouchEvent(mozilla::EventMessage aMessage,
+                                 int32_t aX, int32_t aY,
                                  nsIContent* aContent, nsIFrame* aFrame,
                                  nsIPresShell* aPresShell, nsIWidget* aRootWidget);
 
   /**
    * Return an accesskey registered on the given element by
    * EventStateManager or 0 if there is no registered accesskey.
    *
    * @param aContent - the given element.
--- a/accessible/windows/ia2/moz.build
+++ b/accessible/windows/ia2/moz.build
@@ -42,11 +42,14 @@ LOCAL_INCLUDES += [
     '/accessible/windows',
     '/accessible/windows/msaa',
     '/accessible/xpcom',
     '/accessible/xul',
 ]
 
 FINAL_LIBRARY = 'xul'
 
+if CONFIG['GNU_CXX']:
+    CXXFLAGS += ['-Wshadow']
+
 FAIL_ON_WARNINGS = True
 
 include('/ipc/chromium/chromium-config.mozbuild')
--- a/accessible/windows/msaa/moz.build
+++ b/accessible/windows/msaa/moz.build
@@ -57,9 +57,12 @@ LOCAL_INCLUDES += [
     '/accessible/xul',
     '/dom/base',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
+if CONFIG['GNU_CXX']:
+    CXXFLAGS += ['-Wshadow']
+
 FAIL_ON_WARNINGS = True
--- a/accessible/windows/sdn/moz.build
+++ b/accessible/windows/sdn/moz.build
@@ -16,9 +16,12 @@ LOCAL_INCLUDES += [
     '/accessible/html',
     '/accessible/windows/msaa',
     '/accessible/xpcom',
     '/accessible/xul',
 ]
 
 FINAL_LIBRARY = 'xul'
 
+if CONFIG['GNU_CXX']:
+    CXXFLAGS += ['-Wshadow']
+
 FAIL_ON_WARNINGS = True
--- a/b2g/app/moz.build
+++ b/b2g/app/moz.build
@@ -70,16 +70,19 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk
 
 DISABLE_STL_WRAPPING = True
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     OS_LIBS += [
         'version',
     ]
 
+if CONFIG['GNU_CXX']:
+    CXXFLAGS += ['-Wshadow']
+
 FAIL_ON_WARNINGS = True
 
 JS_PREFERENCE_FILES += [
     'b2g.js',
 ]
 
 DIST_FILES += [
   'ua-update.json.in',
--- a/browser/app/moz.build
+++ b/browser/app/moz.build
@@ -79,9 +79,12 @@ DISABLE_STL_WRAPPING = True
 if CONFIG['MOZ_LINKER']:
     OS_LIBS += CONFIG['MOZ_ZLIB_LIBS']
 
 if CONFIG['HAVE_CLOCK_MONOTONIC']:
     OS_LIBS += CONFIG['REALTIME_LIBS']
 
 JAR_MANIFESTS += ['jar.mn']
 
+if CONFIG['GNU_CXX']:
+    CXXFLAGS += ['-Wshadow']
+
 FAIL_ON_WARNINGS = True
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -7561,16 +7561,26 @@ var TabContextMenu = {
     let bookmarkAllTabs = document.getElementById("context_bookmarkAllTabs");
     bookmarkAllTabs.hidden = this.contextTab.pinned;
     if (!bookmarkAllTabs.hidden)
       PlacesCommandHook.updateBookmarkAllTabsCommand();
 
     // Hide "Move to Group" if it's a pinned tab.
     document.getElementById("context_tabViewMenu").hidden =
       (this.contextTab.pinned || !TabView.firstUseExperienced);
+
+    // Adjust the state of the toggle mute menu item.
+    let toggleMute = document.getElementById("context_toggleMuteTab");
+    if (this.contextTab.hasAttribute("muted")) {
+      toggleMute.label = gNavigatorBundle.getString("unmuteTab.label");
+      toggleMute.accessKey = gNavigatorBundle.getString("unmuteTab.accesskey");
+    } else {
+      toggleMute.label = gNavigatorBundle.getString("muteTab.label");
+      toggleMute.accessKey = gNavigatorBundle.getString("muteTab.accesskey");
+    }
   }
 };
 
 XPCOMUtils.defineLazyModuleGetter(this, "gDevTools",
                                   "resource:///modules/devtools/gDevTools.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "gDevToolsBrowser",
                                   "resource:///modules/devtools/gDevTools.jsm");
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -78,16 +78,17 @@
 #undef FULL_BROWSER_WINDOW
 
   <popupset id="mainPopupSet">
     <menupopup id="tabContextMenu"
                onpopupshowing="if (event.target == this) TabContextMenu.updateContextMenu(this);"
                onpopuphidden="if (event.target == this) TabContextMenu.contextTab = null;">
       <menuitem id="context_reloadTab" label="&reloadTab.label;" accesskey="&reloadTab.accesskey;"
                 oncommand="gBrowser.reloadTab(TabContextMenu.contextTab);"/>
+      <menuitem id="context_toggleMuteTab" oncommand="TabContextMenu.contextTab.toggleMuteAudio();"/>
       <menuseparator/>
       <menuitem id="context_pinTab" label="&pinTab.label;"
                 accesskey="&pinTab.accesskey;"
                 oncommand="gBrowser.pinTab(TabContextMenu.contextTab);"/>
       <menuitem id="context_unpinTab" label="&unpinTab.label;" hidden="true"
                 accesskey="&unpinTab.accesskey;"
                 oncommand="gBrowser.unpinTab(TabContextMenu.contextTab);"/>
       <menu id="context_tabViewMenu" label="&moveToGroup.label;"
--- a/browser/base/content/test/general/browser_audioTabIcon.js
+++ b/browser/base/content/test/general/browser_audioTabIcon.js
@@ -71,16 +71,37 @@ function* test_mute_tab(tab, icon, expec
 }
 
 function get_tab_attributes(tab) {
   const ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
   let {attributes} = JSON.parse(ss.getTabState(tab));
   return attributes;
 }
 
+function* test_muting_using_menu(tab, expectMuted) {
+  // Show the popup menu
+  let contextMenu = document.getElementById("tabContextMenu");
+  let popupShownPromise = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
+  EventUtils.synthesizeMouseAtCenter(tab, {type: "contextmenu", button: 2});
+  yield popupShownPromise;
+
+  // Check the menu
+  let expectedLabel = expectMuted ? "Unmute Tab" : "Mute Tab";
+  let toggleMute = document.getElementById("context_toggleMuteTab");
+  is(toggleMute.label, expectedLabel, "Correct label expected");
+  is(toggleMute.accessKey, "M", "Correct accessKey expected");
+
+  // Click on the menu and wait for the tab to be muted.
+  let mutedPromise = get_wait_for_mute_promise(tab, !expectMuted);
+  let popupHiddenPromise = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden");
+  EventUtils.synthesizeMouseAtCenter(toggleMute, {});
+  yield popupHiddenPromise;
+  yield mutedPromise;
+}
+
 function* test_playing_icon_on_tab(tab, browser, isPinned) {
   let icon = document.getAnonymousElementByAttribute(tab, "anonid",
                                                      isPinned ? "overlay-icon" : "soundplaying-icon");
 
   yield ContentTask.spawn(browser, {}, function* () {
     let audio = content.document.querySelector("audio");
     audio.play();
   });
@@ -115,16 +136,22 @@ function* test_playing_icon_on_tab(tab, 
      !tab.hasAttribute("soundplaying"), "Tab should still be muted but not playing");
 
   yield test_tooltip(icon, "Unmute tab");
 
   yield test_mute_tab(tab, icon, false);
 
   ok(!tab.hasAttribute("muted") &&
      !tab.hasAttribute("soundplaying"), "Tab should not be be muted or playing");
+
+  // Make sure it's possible to mute using the context menu.
+  yield test_muting_using_menu(tab, false);
+
+  // Make sure it's possible to unmute using the context menu.
+  yield test_muting_using_menu(tab, true);
 }
 
 function* test_swapped_browser(oldTab, newBrowser, isPlaying) {
   ok(oldTab.hasAttribute("muted"), "Expected the correct muted attribute on the old tab");
   is(oldTab.hasAttribute("soundplaying"), isPlaying, "Expected the correct soundplaying attribute on the old tab");
 
   let newTab = gBrowser.getTabForBrowser(newBrowser);
   let AttrChangePromise = BrowserTestUtils.waitForEvent(newTab, "TabAttrModified", false, event => {
--- a/browser/base/content/test/plugins/browser.ini
+++ b/browser/base/content/test/plugins/browser.ini
@@ -29,17 +29,16 @@ support-files =
   plugin_overlayed.html
   plugin_positioned.html
   plugin_small.html
   plugin_small_2.html
   plugin_syncRemoved.html
   plugin_test.html
   plugin_test2.html
   plugin_test3.html
-  plugin_test_w_src.html
   plugin_two_types.html
   plugin_unknown.html
   plugin_crashCommentAndURL.html
   plugin_zoom.html
 
 [browser_bug743421.js]
 [browser_bug744745.js]
 [browser_bug787619.js]
@@ -71,17 +70,11 @@ skip-if = (os == 'win' && os_version == 
 [browser_plugin_reloading.js]
 [browser_blocklist_content.js]
 skip-if = !e10s
 [browser_globalplugin_crashinfobar.js]
 skip-if = !crashreporter
 [browser_pluginCrashCommentAndURL.js]
 skip-if = !crashreporter
 [browser_pageInfo_plugins.js]
-[browser_pluginplaypreview.js]
-skip-if = e10s # bug 1148827
-[browser_pluginplaypreview2.js]
-skip-if = e10s # bug 1148827
-[browser_pluginplaypreview3.js]
-skip-if = e10s # bug 1148827
 [browser_pluginCrashReportNonDeterminism.js]
 skip-if = !crashreporter || os == 'linux' # Bug 1152811
 
deleted file mode 100644
--- a/browser/base/content/test/plugins/browser_pluginplaypreview.js
+++ /dev/null
@@ -1,317 +0,0 @@
-var rootDir = getRootDirectory(gTestPath);
-const gTestRoot = rootDir;
-
-var gTestBrowser = null;
-var gNextTest = null;
-var gNextTestSkip = 0;
-var gPlayPreviewPluginActualEvents = 0;
-var gPlayPreviewPluginExpectedEvents = 1;
-
-var gPlayPreviewRegistration = null;
-
-function registerPlayPreview(mimeType, targetUrl) {
-
-  function StreamConverterFactory() {}
-  StreamConverterFactory.prototype = {
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory]),
-    _targetConstructor: null,
-
-    register: function register(targetConstructor) {
-      this._targetConstructor = targetConstructor;
-      var proto = targetConstructor.prototype;
-      var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
-      registrar.registerFactory(proto.classID, proto.classDescription,
-                                proto.contractID, this);
-    },
-
-    unregister: function unregister() {
-      var proto = this._targetConstructor.prototype;
-      var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
-      registrar.unregisterFactory(proto.classID, this);
-      this._targetConstructor = null;
-    },
-
-    // nsIFactory
-    createInstance: function createInstance(aOuter, iid) {
-      if (aOuter !== null)
-        throw Cr.NS_ERROR_NO_AGGREGATION;
-      return (new (this._targetConstructor)).QueryInterface(iid);
-    },
-
-    // nsIFactory
-    lockFactory: function lockFactory(lock) {
-      // No longer used as of gecko 1.7.
-      throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-    }
-  };
-
-  function OverlayStreamConverter() {}
-  OverlayStreamConverter.prototype = {
-    QueryInterface: XPCOMUtils.generateQI([
-        Ci.nsISupports,
-        Ci.nsIStreamConverter,
-        Ci.nsIStreamListener,
-        Ci.nsIRequestObserver
-    ]),
-
-    classID: Components.ID('{4c6030f7-e20a-264f-0f9b-ada3a9e97384}'),
-    classDescription: 'overlay-test-data Component',
-    contractID: '@mozilla.org/streamconv;1?from=application/x-moz-playpreview&to=*/*',
-
-    // nsIStreamConverter::convert
-    convert: function(aFromStream, aFromType, aToType, aCtxt) {
-      throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-    },
-
-    // nsIStreamConverter::asyncConvertData
-    asyncConvertData: function(aFromType, aToType, aListener, aCtxt) {
-      var isValidRequest = false;
-      try {
-        var request = aCtxt;
-        request.QueryInterface(Ci.nsIChannel);
-        var spec = request.URI.spec;
-        var expectedSpec = 'data:application/x-moz-playpreview;,' + mimeType;
-        isValidRequest = (spec == expectedSpec);
-      } catch (e) { }
-      if (!isValidRequest)
-        throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-
-      // Store the listener passed to us
-      this.listener = aListener;
-    },
-
-    // nsIStreamListener::onDataAvailable
-    onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, aCount) {
-      // Do nothing since all the data loading is handled by the viewer.
-      ok(false, "onDataAvailable should not be called");
-    },
-
-    // nsIRequestObserver::onStartRequest
-    onStartRequest: function(aRequest, aContext) {
-
-      // Setup the request so we can use it below.
-      aRequest.QueryInterface(Ci.nsIChannel);
-      // Cancel the request so the viewer can handle it.
-      aRequest.cancel(Cr.NS_BINDING_ABORTED);
-
-      // Create a new channel that is viewer loaded as a resource.
-      var ioService = Services.io;
-      var channel = ioService.newChannel2(targetUrl,
-                                          null,
-                                          null,
-                                          null,      // aLoadingNode
-                                          Services.scriptSecurityManager.getSystemPrincipal(),
-                                          null,      // aTriggeringPrincipal
-                                          Ci.nsILoadInfo.SEC_NORMAL,
-                                          Ci.nsIContentPolicy.TYPE_OTHER);
-      channel.asyncOpen(this.listener, aContext);
-    },
-
-    // nsIRequestObserver::onStopRequest
-    onStopRequest: function(aRequest, aContext, aStatusCode) {
-      // Do nothing.
-    }
-  };
-
-  var ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
-  ph.registerPlayPreviewMimeType(mimeType, true); // ignoring CTP rules
-
-  var factory = new StreamConverterFactory();
-  factory.register(OverlayStreamConverter);
-
-  return (gPlayPreviewRegistration = {
-    unregister: function() {
-      ph.unregisterPlayPreviewMimeType(mimeType);
-      factory.unregister();
-      gPlayPreviewRegistration = null;
-    }
-  });
-}
-
-function unregisterPlayPreview() {
-  gPlayPreviewRegistration.unregister();
-}
-
-Components.utils.import('resource://gre/modules/XPCOMUtils.jsm');
-Components.utils.import("resource://gre/modules/Services.jsm");
-
-
-function test() {
-  waitForExplicitFinish();
-  registerCleanupFunction(function() {
-    if (gPlayPreviewRegistration)
-      gPlayPreviewRegistration.unregister();
-    Services.prefs.clearUserPref("plugins.click_to_play");
-  });
-
-  var newTab = gBrowser.addTab();
-  gBrowser.selectedTab = newTab;
-  gTestBrowser = gBrowser.selectedBrowser;
-  gTestBrowser.addEventListener("load", pageLoad, true);
-  gTestBrowser.addEventListener("PluginBindingAttached", handleBindingAttached, true, true);
-
-  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED);
-  registerPlayPreview('application/x-test', 'about:');
-  prepareTest(test1a, gTestRoot + "plugin_test.html", 1);
-}
-
-function finishTest() {
-  gTestBrowser.removeEventListener("load", pageLoad, true);
-  gTestBrowser.removeEventListener("PluginBindingAttached", handleBindingAttached, true, true);
-  gBrowser.removeCurrentTab();
-  window.focus();
-  finish();
-}
-
-function handleBindingAttached(evt) {
-  if (evt.target instanceof Ci.nsIObjectLoadingContent &&
-      evt.target.pluginFallbackType == Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW)
-    gPlayPreviewPluginActualEvents++;
-}
-
-function pageLoad() {
-  // The plugin events are async dispatched and can come after the load event
-  // This just allows the events to fire before we then go on to test the states
-
-  // iframe might triggers load event as well, making sure we skip some to let
-  // all iframes on the page be loaded as well
-  if (gNextTestSkip) {
-    gNextTestSkip--;
-    return;
-  }
-  executeSoon(gNextTest);
-}
-
-function prepareTest(nextTest, url, skip) {
-  gNextTest = nextTest;
-  gNextTestSkip = skip;
-  gTestBrowser.contentWindow.location = url;
-}
-
-// Tests a page with normal play preview registration (1/2)
-function test1a() {
-  var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
-  ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 1a, Should not have displayed the blocked plugin notification");
-
-  var pluginInfo = getTestPlugin();
-  ok(pluginInfo, "Should have a test plugin");
-
-  var doc = gTestBrowser.contentDocument;
-  var plugin = doc.getElementById("test");
-  var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
-  is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 1a, plugin fallback type should be PLUGIN_PLAY_PREVIEW");
-  ok(!objLoadingContent.activated, "Test 1a, Plugin should not be activated");
-
-  var overlay = doc.getAnonymousElementByAttribute(plugin, "class", "previewPluginContent");
-  ok(overlay, "Test 1a, the overlay div is expected");
-
-  var iframe = overlay.getElementsByClassName("previewPluginContentFrame")[0];
-  ok(iframe && iframe.localName == "iframe", "Test 1a, the overlay iframe is expected");
-  var iframeHref = iframe.contentWindow.location.href;
-  ok(iframeHref == "about:", "Test 1a, the overlay about: content is expected");
-
-  var rect = iframe.getBoundingClientRect();
-  ok(rect.width == 200, "Test 1a, Plugin with id=" + plugin.id + " overlay rect should have 200px width before being replaced by actual plugin");
-  ok(rect.height == 200, "Test 1a, Plugin with id=" + plugin.id + " overlay rect should have 200px height before being replaced by actual plugin");
-
-  var e = overlay.ownerDocument.createEvent("CustomEvent");
-  e.initCustomEvent("MozPlayPlugin", true, true, null);
-  overlay.dispatchEvent(e);
-  var condition = function() objLoadingContent.activated;
-  waitForCondition(condition, test1b, "Test 1a, Waited too long for plugin to stop play preview");
-}
-
-// Tests that activating via MozPlayPlugin through the notification works (part 2/2)
-function test1b() {
-  var plugin = gTestBrowser.contentDocument.getElementById("test");
-  var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
-  ok(objLoadingContent.activated, "Test 1b, Plugin should be activated");
-
-  is(gPlayPreviewPluginActualEvents, gPlayPreviewPluginExpectedEvents,
-     "There should be exactly one PluginPlayPreview event");
-
-  unregisterPlayPreview();
-
-  prepareTest(test2, gTestRoot + "plugin_test.html");
-}
-
-// Tests a page with a working plugin in it -- the mime type was just unregistered.
-function test2() {
-  var plugin = gTestBrowser.contentDocument.getElementById("test");
-  var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
-  ok(objLoadingContent.activated, "Test 2, Plugin should be activated");
-
-  registerPlayPreview('application/x-unknown', 'about:');
-
-  prepareTest(test3, gTestRoot + "plugin_test.html");
-}
-
-// Tests a page with a working plugin in it -- diffent play preview type is reserved.
-function test3() {
-  var plugin = gTestBrowser.contentDocument.getElementById("test");
-  var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
-  ok(objLoadingContent.activated, "Test 3, Plugin should be activated");
-
-  unregisterPlayPreview();
-
-  registerPlayPreview('application/x-test', 'about:');
-  Services.prefs.setBoolPref("plugins.click_to_play", true);
-  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
-  prepareTest(test4a, gTestRoot + "plugin_test.html", 1);
-}
-
-// Test a fallback to the click-to-play
-function test4a() {
-  var doc = gTestBrowser.contentDocument;
-  var plugin = doc.getElementById("test");
-  var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
-  is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 4a, plugin fallback type should be PLUGIN_PLAY_PREVIEW");
-  ok(!objLoadingContent.activated, "Test 4a, Plugin should not be activated");
-
-  var overlay = doc.getAnonymousElementByAttribute(plugin, "class", "previewPluginContent");
-  ok(overlay, "Test 4a, the overlay div is expected");
-
-  var e = overlay.ownerDocument.createEvent("CustomEvent");
-  e.initCustomEvent("MozPlayPlugin", true, true, true);
-  overlay.dispatchEvent(e);
-  var condition = function() objLoadingContent.pluginFallbackType == Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY;
-  waitForCondition(condition, test4b, "Test 4a, Waited too long for plugin to stop play preview");
-}
-
-function test4b() {
-  var doc = gTestBrowser.contentDocument;
-  var plugin = doc.getElementById("test");
-  var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
-  ok(objLoadingContent.pluginFallbackType != Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 4b, plugin fallback type should not be PLUGIN_PLAY_PREVIEW");
-  ok(!objLoadingContent.activated, "Test 4b, Plugin should not be activated");
-
-  prepareTest(test5a, gTestRoot + "plugin_test.html", 1);
-}
-
-// Test a bypass of the click-to-play
-function test5a() {
-  var doc = gTestBrowser.contentDocument;
-  var plugin = doc.getElementById("test");
-  var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
-  is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 5a, plugin fallback type should be PLUGIN_PLAY_PREVIEW");
-  ok(!objLoadingContent.activated, "Test 5a, Plugin should not be activated");
-
-  var overlay = doc.getAnonymousElementByAttribute(plugin, "class", "previewPluginContent");
-  ok(overlay, "Test 5a, the overlay div is expected");
-
-  var e = overlay.ownerDocument.createEvent("CustomEvent");
-  e.initCustomEvent("MozPlayPlugin", true, true, false);
-  overlay.dispatchEvent(e);
-  var condition = function() objLoadingContent.activated;
-  waitForCondition(condition, test5b, "Test 5a, Waited too long for plugin to stop play preview");
-}
-
-function test5b() {
-  var doc = gTestBrowser.contentDocument;
-  var plugin = doc.getElementById("test");
-  var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
-  ok(objLoadingContent.activated, "Test 5b, Plugin should be activated");
-
-  finishTest();
-}
-
deleted file mode 100644
--- a/browser/base/content/test/plugins/browser_pluginplaypreview2.js
+++ /dev/null
@@ -1,171 +0,0 @@
-var rootDir = getRootDirectory(gTestPath);
-const gTestRoot = rootDir;
-
-var gTestBrowser = null;
-var gNextTest = null;
-var gNextTestSkip = 0;
-var gPlayPreviewPluginActualEvents = 0;
-var gPlayPreviewPluginExpectedEvents = 1;
-
-var gPlayPreviewRegistration = null;
-
-function registerPlayPreview(mimeType, targetUrl) {
-  var ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
-  ph.registerPlayPreviewMimeType(mimeType, false, targetUrl);
-
-  return (gPlayPreviewRegistration = {
-    unregister: function() {
-      ph.unregisterPlayPreviewMimeType(mimeType);
-      gPlayPreviewRegistration = null;
-    }
-  });
-}
-
-function unregisterPlayPreview() {
-  gPlayPreviewRegistration.unregister();
-}
-
-Components.utils.import('resource://gre/modules/XPCOMUtils.jsm');
-Components.utils.import("resource://gre/modules/Services.jsm");
-
-
-function test() {
-  waitForExplicitFinish();
-  registerCleanupFunction(function() {
-    if (gPlayPreviewRegistration)
-      gPlayPreviewRegistration.unregister();
-    Services.prefs.clearUserPref("plugins.click_to_play");
-  });
-
-  var newTab = gBrowser.addTab();
-  gBrowser.selectedTab = newTab;
-  gTestBrowser = gBrowser.selectedBrowser;
-  gTestBrowser.addEventListener("load", pageLoad, true);
-  gTestBrowser.addEventListener("PluginBindingAttached", handleBindingAttached, true, true);
-
-  Services.prefs.setBoolPref("plugins.click_to_play", true);
-  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
-
-  registerPlayPreview('application/x-test', 'about:');
-  prepareTest(test1a, gTestRoot + "plugin_test.html", 1);
-}
-
-function finishTest() {
-  gTestBrowser.removeEventListener("load", pageLoad, true);
-  gTestBrowser.removeEventListener("PluginBindingAttached", handleBindingAttached, true, true);
-  gBrowser.removeCurrentTab();
-  window.focus();
-  finish();
-}
-
-function handleBindingAttached(evt) {
-  if (evt.target instanceof Ci.nsIObjectLoadingContent &&
-      evt.target.pluginFallbackType == Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW)
-    gPlayPreviewPluginActualEvents++;
-}
-
-function pageLoad() {
-  // The plugin events are async dispatched and can come after the load event
-  // This just allows the events to fire before we then go on to test the states
-
-  // iframe might triggers load event as well, making sure we skip some to let
-  // all iframes on the page be loaded as well
-  if (gNextTestSkip) {
-    gNextTestSkip--;
-    return;
-  }
-  executeSoon(gNextTest);
-}
-
-function prepareTest(nextTest, url, skip) {
-  gNextTest = nextTest;
-  gNextTestSkip = skip;
-  gTestBrowser.contentWindow.location = url;
-}
-
-// Tests a page with normal play preview registration (1/2)
-function test1a() {
-  var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
-  ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 1a, Should not have displayed the blocked plugin notification");
-
-  var pluginInfo = getTestPlugin();
-  ok(pluginInfo, "Should have a test plugin");
-
-  var doc = gTestBrowser.contentDocument;
-  var plugin = doc.getElementById("test");
-  var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
-  is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 1a, plugin fallback type should be PLUGIN_PLAY_PREVIEW");
-  ok(!objLoadingContent.activated, "Test 1a, Plugin should not be activated");
-
-  var overlay = doc.getAnonymousElementByAttribute(plugin, "class", "previewPluginContent");
-  ok(overlay, "Test 1a, the overlay div is expected");
-
-  var iframe = overlay.getElementsByClassName("previewPluginContentFrame")[0];
-  ok(iframe && iframe.localName == "iframe", "Test 1a, the overlay iframe is expected");
-  var iframeHref = iframe.contentWindow.location.href;
-  ok(iframeHref == "about:", "Test 1a, the overlay about: content is expected");
-
-  var rect = iframe.getBoundingClientRect();
-  ok(rect.width == 200, "Test 1a, Plugin with id=" + plugin.id + " overlay rect should have 200px width before being replaced by actual plugin");
-  ok(rect.height == 200, "Test 1a, Plugin with id=" + plugin.id + " overlay rect should have 200px height before being replaced by actual plugin");
-
-  var e = overlay.ownerDocument.createEvent("CustomEvent");
-  e.initCustomEvent("MozPlayPlugin", true, true, null);
-  overlay.dispatchEvent(e);
-  var condition = function() objLoadingContent.activated;
-  waitForCondition(condition, test1b, "Test 1a, Waited too long for plugin to stop play preview");
-}
-
-// Tests that activating via MozPlayPlugin through the notification works (part 2/2)
-function test1b() {
-  var plugin = gTestBrowser.contentDocument.getElementById("test");
-  var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
-  ok(objLoadingContent.activated, "Test 1b, Plugin should be activated");
-
-  is(gPlayPreviewPluginActualEvents, gPlayPreviewPluginExpectedEvents,
-     "There should be exactly one PluginPlayPreview event");
-
-  unregisterPlayPreview();
-
-  prepareTest(test2, gTestRoot + "plugin_test.html");
-}
-
-// Tests a page with a working plugin in it -- the mime type was just unregistered.
-function test2() {
-  var doc = gTestBrowser.contentDocument;
-  var plugin = doc.getElementById("test");
-  var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
-  ok(objLoadingContent.pluginFallbackType != Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 2, plugin fallback type should not be PLUGIN_PLAY_PREVIEW");
-  ok(!objLoadingContent.activated, "Test 2, Plugin should not be activated");
-
-  registerPlayPreview('application/x-unknown', 'about:');
-
-  prepareTest(test3, gTestRoot + "plugin_test.html");
-}
-
-// Tests a page with a working plugin in it -- diffent play preview type is reserved.
-function test3() {
-  var doc = gTestBrowser.contentDocument;
-  var plugin = doc.getElementById("test");
-  var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
-  ok(objLoadingContent.pluginFallbackType != Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 3, plugin fallback type should not be PLUGIN_PLAY_PREVIEW");
-  ok(!objLoadingContent.activated, "Test 3, Plugin should not be activated");
-
-  unregisterPlayPreview();
-
-  registerPlayPreview('application/x-test', 'about:');
-  Services.prefs.setBoolPref("plugins.click_to_play", false);
-  var plugin = getTestPlugin();
-  plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
-  prepareTest(test4, gTestRoot + "plugin_test.html");
-}
-
-// Tests a page with a working plugin in it -- click-to-play is off
-function test4() {
-  var plugin = gTestBrowser.contentDocument.getElementById("test");
-  var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
-  ok(objLoadingContent.activated, "Test 4, Plugin should be activated");
-
-  finishTest();
-}
-
deleted file mode 100644
--- a/browser/base/content/test/plugins/browser_pluginplaypreview3.js
+++ /dev/null
@@ -1,130 +0,0 @@
-var rootDir = getRootDirectory(gTestPath);
-const gTestRoot = rootDir;
-
-var gTestBrowser = null;
-var gNextTest = null;
-var gNextTestSkip = 0;
-
-var gPlayPreviewRegistration = null;
-
-var gTestPluginType = 'application/x-test';
-var gTestPluginPreviewUrl = 'about:';
-
-function registerPlayPreview(whitelist) {
-  var ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
-  ph.registerPlayPreviewMimeType(gTestPluginType, true,
-                                 gTestPluginPreviewUrl, whitelist);
-
-  return (gPlayPreviewRegistration = {
-    unregister: function() {
-      ph.unregisterPlayPreviewMimeType(gTestPluginType);
-      gPlayPreviewRegistration = null;
-    }
-  });
-}
-
-function unregisterPlayPreview() {
-  gPlayPreviewRegistration.unregister();
-}
-
-Components.utils.import('resource://gre/modules/XPCOMUtils.jsm');
-Components.utils.import("resource://gre/modules/Services.jsm");
-
-
-function test() {
-  waitForExplicitFinish();
-  registerCleanupFunction(function() {
-    if (gPlayPreviewRegistration) {
-      gPlayPreviewRegistration.unregister();
-    }
-  });
-
-  var newTab = gBrowser.addTab();
-  gBrowser.selectedTab = newTab;
-  gTestBrowser = gBrowser.selectedBrowser;
-  gTestBrowser.addEventListener("load", pageLoad, true);
-
-  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED);
-
-  registerPlayPreview('@*plugin_test.html');
-  prepareTest(test1a, gTestRoot + "plugin_test.html", 1);
-}
-
-function finishTest() {
-  gTestBrowser.removeEventListener("load", pageLoad, true);
-  gBrowser.removeCurrentTab();
-  window.focus();
-  finish();
-}
-
-function pageLoad() {
-  // The plugin events are async dispatched and can come after the load event
-  // This just allows the events to fire before we then go on to test the states
-
-  // iframe might triggers load event as well, making sure we skip some to let
-  // all iframes on the page be loaded as well
-  if (gNextTestSkip) {
-    gNextTestSkip--;
-    return;
-  }
-  executeSoon(gNextTest);
-}
-
-function prepareTest(nextTest, url, skip) {
-  gNextTest = nextTest;
-  gNextTestSkip = skip;
-  gTestBrowser.contentWindow.location = url;
-}
-
-// Tests plugin on a whitelisted page.
-function test1a() {
-  var plugin = gTestBrowser.contentDocument.getElementById("test");
-  var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
-  is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 1a, plugin fallback type should be PLUGIN_PLAY_PREVIEW");
-  ok(!objLoadingContent.activated, "Test 1a, Plugin should not be activated");
-
-  unregisterPlayPreview();
-
-  registerPlayPreview('@*plugin_wrong.html');
-  var plugin = getTestPlugin();
-  plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
-  prepareTest(test1b, gTestRoot + "plugin_test.html");
-}
-
-// Tests plugin on a non-whitelisted page.
-function test1b() {
-  var plugin = gTestBrowser.contentDocument.getElementById("test");
-  var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
-  ok(objLoadingContent.activated, "Test 1b, Plugin should be activated");
-
-  unregisterPlayPreview();
-
-  registerPlayPreview('*browser_pluginplaypreview3.js');
-  var plugin = getTestPlugin();
-  plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
-  prepareTest(test2a, gTestRoot + "plugin_test_w_src.html");
-}
-
-// Tests plugin with whitelisted src/data.
-function test2a() {
-  var plugin = gTestBrowser.contentDocument.getElementById("test");
-  var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
-  ok(!objLoadingContent.activated, "Test 2a, Plugin should not be activated");
-
-  unregisterPlayPreview();
-
-  registerPlayPreview('*plugin_test_w_src.html');
-  var plugin = getTestPlugin();
-  plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
-  prepareTest(test2b, gTestRoot + "plugin_test_w_src.html");
-}
-
-// Tests plugin with non-whitelisted src/data.
-function test2b() {
-  var plugin = gTestBrowser.contentDocument.getElementById("test");
-  var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
-  ok(objLoadingContent.activated, "Test 2b, Plugin should be activated");
-
-  finishTest();
-}
-
deleted file mode 100644
--- a/browser/base/content/test/plugins/plugin_test_w_src.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-</head>
-<body>
-<embed id="test" src="browser_pluginplaypreview3.js" style="width: 200px; height: 200px" type="application/x-test">
-</body>
-</html>
--- a/browser/components/places/tests/browser/browser.ini
+++ b/browser/components/places/tests/browser/browser.ini
@@ -15,23 +15,24 @@ support-files =
 [browser_0_library_left_pane_migration.js]
 [browser_410196_paste_into_tags.js]
 [browser_416459_cut.js]
 [browser_423515.js]
 [browser_425884.js]
 [browser_435851_copy_query.js]
 [browser_475045.js]
 [browser_555547.js]
+[browser_bookmarklet_windowOpen.js]
+support-files =
+  pageopeningwindow.html
 [browser_bookmarkProperties_addFolderDefaultButton.js]
 [browser_bookmarkProperties_addKeywordForThisSearch.js]
 [browser_bookmarkProperties_readOnlyRoot.js]
-[browser_bookmarklet_windowOpen.js]
-support-files =
-  pageopeningwindow.html
 [browser_bookmarksProperties.js]
+skip-if = (os == 'win' && os_version == "6.2") # Bug 1178709
 [browser_drag_bookmarks_on_toolbar.js]
 skip-if = e10s # Bug ?????? - test fails - "Number of dragged items should be the same. - Got 0, expected 1"
 [browser_forgetthissite_single.js]
 [browser_history_sidebar_search.js]
 skip-if = e10s && (os == 'linux' || os == 'mac') # Bug 1116457
 [browser_library_batch_delete.js]
 [browser_library_commands.js]
 [browser_library_downloads.js]
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -766,8 +766,13 @@ e10s.offerPopup.noThanks.accesskey = N
 e10s.postActivationInfobar.message = You're now helping to test multi-process in %S! Please report problems you find.
 e10s.postActivationInfobar.learnMore.label = Learn More
 e10s.postActivationInfobar.learnMore.accesskey = L
 e10s.accessibilityNotice.mainMessage = Multi-process does not yet support accessibility features. Multi-process will be disabled if you restart %S. Would you like to restart?
 e10s.accessibilityNotice.disableAndRestart.label = Disable and Restart
 e10s.accessibilityNotice.disableAndRestart.accesskey = R
 e10s.accessibilityNotice.dontDisable.label = Don't Disable
 e10s.accessibilityNotice.dontDisable.accesskey = D
+
+muteTab.label = Mute Tab
+muteTab.accesskey = M
+unmuteTab.label = Unmute Tab
+unmuteTab.accesskey = M
--- a/browser/modules/PluginContent.jsm
+++ b/browser/modules/PluginContent.jsm
@@ -306,18 +306,16 @@ PluginContent.prototype = {
       case Ci.nsIObjectLoadingContent.PLUGIN_OUTDATED:
         return "PluginOutdated";
       case Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY:
         return "PluginClickToPlay";
       case Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE:
         return "PluginVulnerableUpdatable";
       case Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE:
         return "PluginVulnerableNoUpdate";
-      case Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW:
-        return "PluginPlayPreview";
       default:
         // Not all states map to a handler
         return null;
     }
   },
 
   handleEvent: function (event) {
     let eventType = event.type;
@@ -412,20 +410,16 @@ PluginContent.prototype = {
             eventType == "PluginVulnerableNoUpdate") {
           let vulnerabilityString = gNavigatorBundle.GetStringFromName(eventType);
           let vulnerabilityText = this.getPluginUI(plugin, "vulnerabilityStatus");
           vulnerabilityText.textContent = vulnerabilityString;
         }
         shouldShowNotification = true;
         break;
 
-      case "PluginPlayPreview":
-        this._handlePlayPreviewEvent(plugin);
-        break;
-
       case "PluginDisabled":
         let manageLink = this.getPluginUI(plugin, "managePluginsLink");
         this.addLinkClickCallback(manageLink, "forwardCallback", "managePlugins");
         shouldShowNotification = true;
         break;
 
       case "PluginInstantiated":
         shouldShowNotification = true;
@@ -526,45 +520,28 @@ PluginContent.prototype = {
     let permissionString = pluginHost.getPermissionStringForType(objLoadingContent.actualType);
     let principal = objLoadingContent.ownerDocument.defaultView.top.document.nodePrincipal;
     let pluginPermission = Services.perms.testPermissionFromPrincipal(principal, permissionString);
 
     let isFallbackTypeValid =
       objLoadingContent.pluginFallbackType >= Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY &&
       objLoadingContent.pluginFallbackType <= Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE;
 
-    if (objLoadingContent.pluginFallbackType == Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW) {
-      // checking if play preview is subject to CTP rules
-      let playPreviewInfo = pluginHost.getPlayPreviewInfo(objLoadingContent.actualType);
-      isFallbackTypeValid = !playPreviewInfo.ignoreCTP;
-    }
-
     return !objLoadingContent.activated &&
            pluginPermission != Ci.nsIPermissionManager.DENY_ACTION &&
            isFallbackTypeValid;
   },
 
   hideClickToPlayOverlay: function (plugin) {
     let overlay = this.getPluginUI(plugin, "main");
     if (overlay) {
       overlay.classList.remove("visible");
     }
   },
 
-  stopPlayPreview: function (plugin, playPlugin) {
-    let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
-    if (objLoadingContent.activated)
-      return;
-
-    if (playPlugin)
-      objLoadingContent.playPlugin();
-    else
-      objLoadingContent.cancelPlayPreview();
-  },
-
   // Forward a link click callback to the chrome process.
   forwardCallback: function (name) {
     this.global.sendAsyncMessage("PluginContent:LinkClickCallback", { name: name });
   },
 
   submitReport: function submitReport(plugin) {
     if (!AppConstants.MOZ_CRASHREPORTER) {
       return;
@@ -636,59 +613,16 @@ PluginContent.prototype = {
         event.button == 0 &&
         event.isTrusted) {
       this._showClickToPlayNotification(plugin, true);
     event.stopPropagation();
     event.preventDefault();
     }
   },
 
-  _handlePlayPreviewEvent: function (plugin) {
-    let doc = plugin.ownerDocument;
-    let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
-    let pluginInfo = this._getPluginInfo(plugin);
-    let playPreviewInfo = pluginHost.getPlayPreviewInfo(pluginInfo.mimetype);
-
-    let previewContent = this.getPluginUI(plugin, "previewPluginContent");
-    let iframe = previewContent.getElementsByClassName("previewPluginContentFrame")[0];
-    if (!iframe) {
-      // lazy initialization of the iframe
-      iframe = doc.createElementNS("http://www.w3.org/1999/xhtml", "iframe");
-      iframe.className = "previewPluginContentFrame";
-      previewContent.appendChild(iframe);
-
-      // Force a style flush, so that we ensure our binding is attached.
-      plugin.clientTop;
-    }
-    iframe.src = playPreviewInfo.redirectURL;
-
-    // MozPlayPlugin event can be dispatched from the extension chrome
-    // code to replace the preview content with the native plugin
-    let playPluginHandler = (event) => {
-      if (!event.isTrusted)
-        return;
-
-      previewContent.removeEventListener("MozPlayPlugin", playPluginHandler, true);
-
-      let playPlugin = !event.detail;
-      this.stopPlayPreview(plugin, playPlugin);
-
-      // cleaning up: removes overlay iframe from the DOM
-      let iframe = previewContent.getElementsByClassName("previewPluginContentFrame")[0];
-      if (iframe)
-        previewContent.removeChild(iframe);
-    };
-
-    previewContent.addEventListener("MozPlayPlugin", playPluginHandler, true);
-
-    if (!playPreviewInfo.ignoreCTP) {
-      this._showClickToPlayNotification(plugin, false);
-    }
-  },
-
   reshowClickToPlayNotification: function () {
     let contentWindow = this.global.content;
     let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                            .getInterface(Ci.nsIDOMWindowUtils);
     let plugins = cwu.plugins;
     for (let plugin of plugins) {
       let overlay = this.getPluginUI(plugin, "main");
       if (overlay)
--- a/build/autoconf/icu.m4
+++ b/build/autoconf/icu.m4
@@ -286,16 +286,17 @@ if test -z "$BUILDING_JS" -o -n "$JS_STA
           ICU_CFLAGS="$ICU_CFLAGS -DU_STATIC_IMPLEMENTATION"
           if test "$GNU_CC"; then
             ICU_CFLAGS="$ICU_CFLAGS -fvisibility=hidden"
             ICU_CXXFLAGS="$ICU_CXXFLAGS -fvisibility=hidden"
           fi
         fi
 
         (export AR="$AR"
+         export RANLIB="$RANLIB"
          export CC="$CC"
          export CXX="$CXX"
          export LD="$LD"
          export ARFLAGS="$ARFLAGS"
          export CPPFLAGS="$ICU_CPPFLAGS $CPPFLAGS"
          export CFLAGS="$ICU_CFLAGS"
          export CXXFLAGS="$ICU_CXXFLAGS"
          export LDFLAGS="$ICU_LDFLAGS $LDFLAGS"
--- a/docshell/build/moz.build
+++ b/docshell/build/moz.build
@@ -20,9 +20,12 @@ LOCAL_INCLUDES += [
     '/uriloader/prefetch',
 ]
 
 if CONFIG["MOZ_WIDGET_TOOLKIT"] == "cocoa":
     LOCAL_INCLUDES += ['/uriloader/exthandler/mac']
 
 FINAL_LIBRARY = 'xul'
 
+if CONFIG['GNU_CXX']:
+    CXXFLAGS += ['-Wshadow']
+
 FAIL_ON_WARNINGS = True
--- a/dom/apps/moz.build
+++ b/dom/apps/moz.build
@@ -46,15 +46,18 @@ EXTRA_PP_JS_MODULES += [
     'AppsUtils.jsm',
     'ImportExport.jsm',
     'InterAppCommService.jsm',
     'OperatorApps.jsm',
     'ScriptPreloader.jsm',
     'Webapps.jsm',
 ]
 
+if CONFIG['GNU_CXX']:
+    CXXFLAGS += ['-Wshadow']
+
 FAIL_ON_WARNINGS = True
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '/js/xpconnect/wrappers',
 ]
--- a/dom/archivereader/moz.build
+++ b/dom/archivereader/moz.build
@@ -16,16 +16,19 @@ EXPORTS.mozilla.dom.archivereader += [
 UNIFIED_SOURCES += [
     'ArchiveEvent.cpp',
     'ArchiveReader.cpp',
     'ArchiveRequest.cpp',
     'ArchiveZipEvent.cpp',
     'ArchiveZipFile.cpp',
 ]
 
+if CONFIG['GNU_CXX']:
+    CXXFLAGS += ['-Wshadow']
+
 FAIL_ON_WARNINGS = True
 
 LOCAL_INCLUDES += [
     '../base',
 ]
 
 FINAL_LIBRARY = 'xul'
 
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -828,16 +828,18 @@ nsIContent::PreHandleEvent(EventChainPre
               eventType.EqualsLiteral("reset") ||
               eventType.EqualsLiteral("resize") ||
               eventType.EqualsLiteral("scroll") ||
               eventType.EqualsLiteral("selectstart")) {
             stopEvent = true;
           }
         }
         break;
+      default:
+        break;
     }
 
     if (stopEvent) {
       // If we do stop propagation, we still want to propagate
       // the event to chrome (nsPIDOMWindow::GetParentTarget()).
       // The load event is special in that we don't ever propagate it
       // to chrome.
       nsCOMPtr<nsPIDOMWindow> win = OwnerDoc()->GetWindow();
--- a/dom/base/StructuredCloneHelper.cpp
+++ b/dom/base/StructuredCloneHelper.cpp
@@ -127,17 +127,16 @@ StructuredCloneHelperInternal::~Structur
   MOZ_ASSERT(mShutdownCalled);
 #endif
 }
 
 void
 StructuredCloneHelperInternal::Shutdown()
 {
 #ifdef DEBUG
-  MOZ_ASSERT(!mShutdownCalled, "Shutdown already called!");
   mShutdownCalled = true;
 #endif
 
   mBuffer = nullptr;
 }
 
 bool
 StructuredCloneHelperInternal::Write(JSContext* aCx,
@@ -165,17 +164,16 @@ StructuredCloneHelperInternal::Write(JSC
 bool
 StructuredCloneHelperInternal::Read(JSContext* aCx,
                                     JS::MutableHandle<JS::Value> aValue)
 {
   MOZ_ASSERT(mBuffer, "Read() without Write() is not allowed.");
   MOZ_ASSERT(!mShutdownCalled, "This method cannot be called after Shutdown.");
 
   bool ok = mBuffer->read(aCx, aValue, &gCallbacks, this);
-  mBuffer = nullptr;
   return ok;
 }
 
 bool
 StructuredCloneHelperInternal::ReadTransferCallback(JSContext* aCx,
                                                     JSStructuredCloneReader* aReader,
                                                     uint32_t aTag,
                                                     void* aContent,
@@ -249,36 +247,52 @@ StructuredCloneHelper::Read(nsISupports*
   mozilla::AutoRestore<nsISupports*> guard(mParent);
   mParent = aParent;
 
   if (!StructuredCloneHelperInternal::Read(aCx, aValue)) {
     JS_ClearPendingException(aCx);
     aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
   }
 
-  mBlobImplArray.Clear();
+  // If we are tranferring something, we cannot call 'Read()' more than once.
+  if (mSupportsTransferring) {
+    mBlobImplArray.Clear();
+    Shutdown();
+  }
 }
 
 void
 StructuredCloneHelper::ReadFromBuffer(nsISupports* aParent,
                                       JSContext* aCx,
                                       uint64_t* aBuffer,
                                       size_t aBufferLength,
                                       JS::MutableHandle<JS::Value> aValue,
                                       ErrorResult& aRv)
 {
+  ReadFromBuffer(aParent, aCx, aBuffer, aBufferLength,
+                 JS_STRUCTURED_CLONE_VERSION, aValue, aRv);
+}
+
+void
+StructuredCloneHelper::ReadFromBuffer(nsISupports* aParent,
+                                      JSContext* aCx,
+                                      uint64_t* aBuffer,
+                                      size_t aBufferLength,
+                                      uint32_t aAlgorithmVersion,
+                                      JS::MutableHandle<JS::Value> aValue,
+                                      ErrorResult& aRv)
+{
   MOZ_ASSERT(!mBuffer, "ReadFromBuffer() must be called without a Write().");
   MOZ_ASSERT(aBuffer);
 
   mozilla::AutoRestore<nsISupports*> guard(mParent);
   mParent = aParent;
 
-  if (!JS_ReadStructuredClone(aCx, aBuffer, aBufferLength,
-                              JS_STRUCTURED_CLONE_VERSION, aValue,
-                              &gCallbacks, this)) {
+  if (!JS_ReadStructuredClone(aCx, aBuffer, aBufferLength, aAlgorithmVersion,
+                              aValue, &gCallbacks, this)) {
     JS_ClearPendingException(aCx);
     aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
   }
 }
 
 void
 StructuredCloneHelper::MoveBufferDataToArray(FallibleTArray<uint8_t>& aArray,
                                              ErrorResult& aRv)
--- a/dom/base/StructuredCloneHelper.h
+++ b/dom/base/StructuredCloneHelper.h
@@ -155,20 +155,34 @@ public:
   // and/or the PortIdentifiers.
   void ReadFromBuffer(nsISupports* aParent,
                       JSContext* aCx,
                       uint64_t* aBuffer,
                       size_t aBufferLength,
                       JS::MutableHandle<JS::Value> aValue,
                       ErrorResult &aRv);
 
+  void ReadFromBuffer(nsISupports* aParent,
+                      JSContext* aCx,
+                      uint64_t* aBuffer,
+                      size_t aBufferLength,
+                      uint32_t aAlgorithmVersion,
+                      JS::MutableHandle<JS::Value> aValue,
+                      ErrorResult &aRv);
+
   // Use this method to free a buffer generated by MoveToBuffer().
   void FreeBuffer(uint64_t* aBuffer,
                   size_t aBufferLength);
 
+  bool HasClonedDOMObjects() const
+  {
+    return !mBlobImplArray.IsEmpty() ||
+           !mClonedImages.IsEmpty();
+  }
+
   nsTArray<nsRefPtr<BlobImpl>>& BlobImpls()
   {
     MOZ_ASSERT(mSupportsCloning, "Blobs cannot be taken/set if cloning is not supported.");
     return mBlobImplArray;
   }
 
   const nsTArray<nsRefPtr<MessagePortBase>>& GetTransferredPorts() const
   {
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -661,39 +661,39 @@ nsContentUtils::InitializeModifierString
   sMetaText = new nsString(metaModifier);
   sOSText = new nsString(osModifier);
   sAltText = new nsString(altModifier);
   sControlText = new nsString(controlModifier);
   sModifierSeparator = new nsString(modifierSeparator);  
 }
 
 // Because of SVG/SMIL we have several atoms mapped to the same
-// id, but we can rely on ID_TO_EVENT to map id to only one atom.
+// id, but we can rely on MESSAGE_TO_EVENT to map id to only one atom.
 static bool
 ShouldAddEventToStringEventTable(const EventNameMapping& aMapping)
 {
-  switch(aMapping.mId) {
-#define ID_TO_EVENT(name_, id_, type_, struct_) \
-  case id_: return nsGkAtoms::on##name_ == aMapping.mAtom;
+  switch(aMapping.mMessage) {
+#define MESSAGE_TO_EVENT(name_, message_, type_, struct_) \
+  case message_: return nsGkAtoms::on##name_ == aMapping.mAtom;
 #include "mozilla/EventNameList.h"
-#undef ID_TO_EVENT
+#undef MESSAGE_TO_EVENT
   default:
     break;
   }
   return false;
 }
 
 bool
 nsContentUtils::InitializeEventTable() {
   NS_ASSERTION(!sAtomEventTable, "EventTable already initialized!");
   NS_ASSERTION(!sStringEventTable, "EventTable already initialized!");
 
   static const EventNameMapping eventArray[] = {
-#define EVENT(name_,  _id, _type, _class)          \
-    { nsGkAtoms::on##name_, _id, _type, _class },
+#define EVENT(name_,  _message, _type, _class)          \
+    { nsGkAtoms::on##name_, _type, _message, _class },
 #define WINDOW_ONLY_EVENT EVENT
 #define NON_IDL_EVENT EVENT
 #include "mozilla/EventNameList.h"
 #undef WINDOW_ONLY_EVENT
 #undef NON_IDL_EVENT
 #undef EVENT
     { nullptr }
   };
@@ -719,19 +719,19 @@ nsContentUtils::InitializeEventTable() {
 
 void
 nsContentUtils::InitializeTouchEventTable()
 {
   static bool sEventTableInitialized = false;
   if (!sEventTableInitialized && sAtomEventTable && sStringEventTable) {
     sEventTableInitialized = true;
     static const EventNameMapping touchEventArray[] = {
-#define EVENT(name_,  _id, _type, _class)
-#define TOUCH_EVENT(name_,  _id, _type, _class)      \
-      { nsGkAtoms::on##name_, _id, _type, _class },
+#define EVENT(name_,  _message, _type, _class)
+#define TOUCH_EVENT(name_,  _message, _type, _class)      \
+      { nsGkAtoms::on##name_, _type, _message, _class },
 #include "mozilla/EventNameList.h"
 #undef TOUCH_EVENT
 #undef EVENT
       { nullptr }
     };
     // Subtract one from the length because of the trailing null
     for (uint32_t i = 0; i < ArrayLength(touchEventArray) - 1; ++i) {
       sAtomEventTable->Put(touchEventArray[i].mAtom, touchEventArray[i]);
@@ -3650,23 +3650,23 @@ nsContentUtils::IsEventAttributeName(nsI
   if (name[0] != 'o' || name[1] != 'n')
     return false;
 
   EventNameMapping mapping;
   return (sAtomEventTable->Get(aName, &mapping) && mapping.mType & aType);
 }
 
 // static
-uint32_t
-nsContentUtils::GetEventId(nsIAtom* aName)
+EventMessage
+nsContentUtils::GetEventMessage(nsIAtom* aName)
 {
   if (aName) {
     EventNameMapping mapping;
     if (sAtomEventTable->Get(aName, &mapping)) {
-      return mapping.mId;
+      return mapping.mMessage;
     }
   }
 
   return NS_USER_DEFINED_EVENT;
 }
 
 // static
 mozilla::EventClassID
@@ -3675,41 +3675,42 @@ nsContentUtils::GetEventClassID(const ns
   EventNameMapping mapping;
   if (sStringEventTable->Get(aName, &mapping))
     return mapping.mEventClassID;
 
   return eBasicEventClass;
 }
 
 nsIAtom*
-nsContentUtils::GetEventIdAndAtom(const nsAString& aName,
-                                  mozilla::EventClassID aEventClassID,
-                                  uint32_t* aEventID)
+nsContentUtils::GetEventMessageAndAtom(const nsAString& aName,
+                                       mozilla::EventClassID aEventClassID,
+                                       EventMessage* aEventMessage)
 {
   EventNameMapping mapping;
   if (sStringEventTable->Get(aName, &mapping)) {
-    *aEventID = mapping.mEventClassID == aEventClassID ? mapping.mId :
-                                                         NS_USER_DEFINED_EVENT;
+    *aEventMessage =
+      mapping.mEventClassID == aEventClassID ? mapping.mMessage :
+                                               NS_USER_DEFINED_EVENT;
     return mapping.mAtom;
   }
 
   // If we have cached lots of user defined event names, clear some of them.
   if (sUserDefinedEvents->Count() > 127) {
     while (sUserDefinedEvents->Count() > 64) {
       nsIAtom* first = sUserDefinedEvents->ObjectAt(0);
       sStringEventTable->Remove(Substring(nsDependentAtomString(first), 2));
       sUserDefinedEvents->RemoveObjectAt(0);
     }
   }
 
-  *aEventID = NS_USER_DEFINED_EVENT;
+  *aEventMessage = NS_USER_DEFINED_EVENT;
   nsCOMPtr<nsIAtom> atom = do_GetAtom(NS_LITERAL_STRING("on") + aName);
   sUserDefinedEvents->AppendObject(atom);
   mapping.mAtom = atom;
-  mapping.mId = NS_USER_DEFINED_EVENT;
+  mapping.mMessage = NS_USER_DEFINED_EVENT;
   mapping.mType = EventNameType_None;
   mapping.mEventClassID = eBasicEventClass;
   sStringEventTable->Put(aName, mapping);
   return mapping.mAtom;
 }
 
 static
 nsresult GetEventAndTarget(nsIDocument* aDoc, nsISupports* aTarget,
@@ -7701,17 +7702,17 @@ nsContentUtils::SendKeyEvent(nsIWidget* 
                              int32_t aModifiers,
                              uint32_t aAdditionalFlags,
                              bool* aDefaultActionTaken)
 {
   // get the widget to send the event to
   if (!aWidget)
     return NS_ERROR_FAILURE;
 
-  int32_t msg;
+  EventMessage msg;
   if (aType.EqualsLiteral("keydown"))
     msg = NS_KEY_DOWN;
   else if (aType.EqualsLiteral("keyup"))
     msg = NS_KEY_UP;
   else if (aType.EqualsLiteral("keypress"))
     msg = NS_KEY_PRESS;
   else
     return NS_ERROR_FAILURE;
@@ -7814,17 +7815,17 @@ nsContentUtils::SendMouseEvent(nsCOMPtr<
                                bool *aPreventDefault,
                                bool aIsSynthesized)
 {
   nsPoint offset;
   nsCOMPtr<nsIWidget> widget = GetWidget(aPresShell, &offset);
   if (!widget)
     return NS_ERROR_FAILURE;
 
-  int32_t msg;
+  EventMessage msg;
   bool contextMenuKey = false;
   if (aType.EqualsLiteral("mousedown"))
     msg = NS_MOUSE_BUTTON_DOWN;
   else if (aType.EqualsLiteral("mouseup"))
     msg = NS_MOUSE_BUTTON_UP;
   else if (aType.EqualsLiteral("mousemove"))
     msg = NS_MOUSE_MOVE;
   else if (aType.EqualsLiteral("mouseover"))
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -160,18 +160,18 @@ enum EventNameType {
   EventNameType_All = 0xFFFF
 };
 
 struct EventNameMapping
 {
   // This holds pointers to nsGkAtoms members, and is therefore safe as a
   // non-owning reference.
   nsIAtom* MOZ_NON_OWNING_REF mAtom;
-  uint32_t mId;
   int32_t  mType;
+  mozilla::EventMessage mMessage;
   mozilla::EventClassID mEventClassID;
 };
 
 struct nsShortcutCandidate {
   nsShortcutCandidate(uint32_t aCharCode, bool aIgnoreShift) :
     mCharCode(aCharCode), mIgnoreShift(aIgnoreShift)
   {
   }
@@ -1095,45 +1095,45 @@ public:
    * defined above.
    *
    * @param aName the event name to look up
    * @param aType the type of content
    */
   static bool IsEventAttributeName(nsIAtom* aName, int32_t aType);
 
   /**
-   * Return the event id for the event with the given name. The name is the
-   * event name with the 'on' prefix. Returns NS_USER_DEFINED_EVENT if the
+   * Return the event message for the event with the given name. The name is
+   * the event name with the 'on' prefix. Returns NS_USER_DEFINED_EVENT if the
    * event doesn't match a known event name.
    *
    * @param aName the event name to look up
    */
-  static uint32_t GetEventId(nsIAtom* aName);
+  static mozilla::EventMessage GetEventMessage(nsIAtom* aName);
 
   /**
    * Return the EventClassID for the event with the given name. The name is the
    * event name *without* the 'on' prefix. Returns eBasicEventClass if the event
    * is not known to be of any particular event class.
    *
    * @param aName the event name to look up
    */
   static mozilla::EventClassID GetEventClassID(const nsAString& aName);
 
   /**
-   * Return the event id and atom for the event with the given name.
+   * Return the event message and atom for the event with the given name.
    * The name is the event name *without* the 'on' prefix.
    * Returns NS_USER_DEFINED_EVENT on the aEventID if the
    * event doesn't match a known event name in the category.
    *
    * @param aName the event name to look up
    * @param aEventClassID only return event id for aEventClassID
    */
-  static nsIAtom* GetEventIdAndAtom(const nsAString& aName,
-                                    mozilla::EventClassID aEventClassID,
-                                    uint32_t* aEventID);
+  static nsIAtom* GetEventMessageAndAtom(const nsAString& aName,
+                                         mozilla::EventClassID aEventClassID,
+                                         mozilla::EventMessage* aEventMessage);
 
   /**
    * Used only during traversal of the XPCOM graph by the cycle
    * collector: push a pointer to the listener manager onto the
    * children deque, if it exists. Do nothing if there is no listener
    * manager.
    *
    * Crucially: does not perform any refcounting operations.
@@ -1691,26 +1691,22 @@ public:
    * Case insensitive comparison between two strings. However it only ignores
    * case for ASCII characters a-z.
    */
   static bool EqualsIgnoreASCIICase(const nsAString& aStr1,
                                     const nsAString& aStr2);
 
   /**
    * Convert ASCII A-Z to a-z.
-   * @return NS_OK on success, or NS_ERROR_OUT_OF_MEMORY if making the string
-   * writable needs to allocate memory and that allocation fails.
    */
   static void ASCIIToLower(nsAString& aStr);
   static void ASCIIToLower(const nsAString& aSource, nsAString& aDest);
 
   /**
    * Convert ASCII a-z to A-Z.
-   * @return NS_OK on success, or NS_ERROR_OUT_OF_MEMORY if making the string
-   * writable needs to allocate memory and that allocation fails.
    */
   static void ASCIIToUpper(nsAString& aStr);
   static void ASCIIToUpper(const nsAString& aSource, nsAString& aDest);
 
   /**
    * Return whether aStr contains an ASCII uppercase character.
    */
   static bool StringContainsASCIIUpper(const nsAString& aStr);
--- a/dom/base/nsCopySupport.cpp
+++ b/dom/base/nsCopySupport.cpp
@@ -616,24 +616,28 @@ IsSelectionInsideRuby(nsISelection* aSel
     if (!IsInsideRuby(n)) {
       return false;
     }
   }
   return true;
 }
 
 bool
-nsCopySupport::FireClipboardEvent(int32_t aType, int32_t aClipboardType, nsIPresShell* aPresShell,
-                                  nsISelection* aSelection, bool* aActionTaken)
+nsCopySupport::FireClipboardEvent(EventMessage aEventMessage,
+                                  int32_t aClipboardType,
+                                  nsIPresShell* aPresShell,
+                                  nsISelection* aSelection,
+                                  bool* aActionTaken)
 {
   if (aActionTaken) {
     *aActionTaken = false;
   }
 
-  NS_ASSERTION(aType == NS_CUT || aType == NS_COPY || aType == NS_PASTE,
+  NS_ASSERTION(aEventMessage == NS_CUT || aEventMessage == NS_COPY ||
+               aEventMessage == NS_PASTE,
                "Invalid clipboard event type");
 
   nsCOMPtr<nsIPresShell> presShell = aPresShell;
   if (!presShell)
     return false;
 
   nsCOMPtr<nsIDocument> doc = presShell->GetDocument();
   if (!doc)
@@ -679,31 +683,32 @@ nsCopySupport::FireClipboardEvent(int32_
   const bool chromeShell =
     docShell && docShell->ItemType() == nsIDocShellTreeItem::typeChrome;
 
   // next, fire the cut, copy or paste event
   bool doDefault = true;
   nsRefPtr<DataTransfer> clipboardData;
   if (chromeShell || Preferences::GetBool("dom.event.clipboardevents.enabled", true)) {
     clipboardData =
-      new DataTransfer(piWindow, aType, aType == NS_PASTE, aClipboardType);
+      new DataTransfer(piWindow, aEventMessage, aEventMessage == NS_PASTE,
+                       aClipboardType);
 
     nsEventStatus status = nsEventStatus_eIgnore;
-    InternalClipboardEvent evt(true, aType);
+    InternalClipboardEvent evt(true, aEventMessage);
     evt.clipboardData = clipboardData;
     EventDispatcher::Dispatch(content, presShell->GetPresContext(), &evt,
                               nullptr, &status);
     // If the event was cancelled, don't do the clipboard operation
     doDefault = (status != nsEventStatus_eConsumeNoDefault);
   }
 
   // No need to do anything special during a paste. Either an event listener
   // took care of it and cancelled the event, or the caller will handle it.
   // Return true to indicate that the event wasn't cancelled.
-  if (aType == NS_PASTE) {
+  if (aEventMessage == NS_PASTE) {
     // Clear and mark the clipboardData as readonly. This prevents someone
     // from reading the clipboard contents after the paste event has fired.
     if (clipboardData) {
       clipboardData->ClearAll();
       clipboardData->SetReadOnly();
     }
 
     if (aActionTaken) {
@@ -733,17 +738,17 @@ nsCopySupport::FireClipboardEvent(int32_
     if (formControl) {
       if (formControl->GetType() == NS_FORM_INPUT_PASSWORD) {
         return false;
       }
     }
 
     // when cutting non-editable content, do nothing
     // XXX this is probably the wrong editable flag to check
-    if (aType != NS_CUT || content->IsEditable()) {
+    if (aEventMessage != NS_CUT || content->IsEditable()) {
       // get the data from the selection if any
       bool isCollapsed;
       sel->GetIsCollapsed(&isCollapsed);
       if (isCollapsed) {
         if (aActionTaken) {
           *aActionTaken = true;
         }
         return false;
--- a/dom/base/nsCopySupport.h
+++ b/dom/base/nsCopySupport.h
@@ -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/. */
 
 #ifndef nsCopySupport_h__
 #define nsCopySupport_h__
 
-#include "nscore.h"
+#include "mozilla/EventForwards.h"
 
 class nsINode;
 class nsISelection;
 class nsIDocument;
 class nsIImageLoadingContent;
 class nsIContent;
 class nsITransferable;
 class nsACString;
@@ -59,17 +59,17 @@ class nsCopySupport
     /**
      * Returns true if a copy operation is currently permitted based on the
      * current focus and selection within the specified document.
      */
     static bool CanCopy(nsIDocument* aDocument);
 
     /**
      * Fires a cut, copy or paste event, on the given presshell, depending
-     * on the value of aType, which should be either NS_CUT, NS_COPY or
+     * on the value of aEventMessage, which should be either NS_CUT, NS_COPY or
      * NS_PASTE, and perform the default copy action if the event was not
      * cancelled.
      *
      * If aSelection is specified, then this selection is used as the target
      * of the operation. Otherwise, GetSelectionForCopy is used to retrieve
      * the current selection.
      *
      * This will fire a cut, copy or paste event at the node at the start
@@ -83,16 +83,16 @@ class nsCopySupport
      *
      * aClipboardType specifies which clipboard to use, from nsIClipboard.
      *
      * If aActionTaken is non-NULL, it will be set to true if an action was
      * taken, whether it be the default action or the default being prevented.
      *
      * If the event is cancelled or an error occurs, false will be returned.
      */
-    static bool FireClipboardEvent(int32_t aType,
+    static bool FireClipboardEvent(mozilla::EventMessage aEventMessage,
                                    int32_t aClipboardType,
                                    nsIPresShell* aPresShell,
                                    nsISelection* aSelection,
                                    bool* aActionTaken = nullptr);
 };
 
 #endif
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -695,17 +695,17 @@ nsDOMWindowUtils::SendPointerEventCommon
 
   // get the widget to send the event to
   nsPoint offset;
   nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
   if (!widget) {
     return NS_ERROR_FAILURE;
   }
 
-  int32_t msg;
+  EventMessage msg;
   if (aType.EqualsLiteral("pointerdown")) {
     msg = NS_POINTER_DOWN;
   } else if (aType.EqualsLiteral("pointerup")) {
     msg = NS_POINTER_UP;
   } else if (aType.EqualsLiteral("pointermove")) {
     msg = NS_POINTER_MOVE;
   } else if (aType.EqualsLiteral("pointerover")) {
     msg = NS_POINTER_OVER;
@@ -974,17 +974,17 @@ nsDOMWindowUtils::SendTouchEventCommon(c
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
 
   // get the widget to send the event to
   nsPoint offset;
   nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
   if (!widget) {
     return NS_ERROR_NULL_POINTER;
   }
-  int32_t msg;
+  EventMessage msg;
   if (aType.EqualsLiteral("touchstart")) {
     msg = NS_TOUCH_START;
   } else if (aType.EqualsLiteral("touchmove")) {
     msg = NS_TOUCH_MOVE;
   } else if (aType.EqualsLiteral("touchend")) {
     msg = NS_TOUCH_END;
   } else if (aType.EqualsLiteral("touchcancel")) {
     msg = NS_TOUCH_CANCEL;
@@ -1309,17 +1309,17 @@ nsDOMWindowUtils::SendSimpleGestureEvent
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
 
   // get the widget to send the event to
   nsPoint offset;
   nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
   if (!widget)
     return NS_ERROR_FAILURE;
 
-  int32_t msg;
+  EventMessage msg;
   if (aType.EqualsLiteral("MozSwipeGestureStart"))
     msg = NS_SIMPLE_GESTURE_SWIPE_START;
   else if (aType.EqualsLiteral("MozSwipeGestureUpdate"))
     msg = NS_SIMPLE_GESTURE_SWIPE_UPDATE;
   else if (aType.EqualsLiteral("MozSwipeGestureEnd"))
     msg = NS_SIMPLE_GESTURE_SWIPE_END;
   else if (aType.EqualsLiteral("MozSwipeGesture"))
     msg = NS_SIMPLE_GESTURE_SWIPE;
@@ -1936,32 +1936,47 @@ nsDOMWindowUtils::SendQueryContentEvent(
   NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
 
   // get the widget to send the event to
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget) {
     return NS_ERROR_FAILURE;
   }
 
-  if (aType != NS_QUERY_SELECTED_TEXT &&
-      aType != NS_QUERY_TEXT_CONTENT &&
-      aType != NS_QUERY_CARET_RECT &&
-      aType != NS_QUERY_TEXT_RECT &&
-      aType != NS_QUERY_EDITOR_RECT &&
-      aType != NS_QUERY_CHARACTER_AT_POINT) {
-    return NS_ERROR_INVALID_ARG;
+  EventMessage message;
+  switch (aType) {
+    case QUERY_SELECTED_TEXT:
+      message = NS_QUERY_SELECTED_TEXT;
+      break;
+    case QUERY_TEXT_CONTENT:
+      message = NS_QUERY_TEXT_CONTENT;
+      break;
+    case QUERY_CARET_RECT:
+      message = NS_QUERY_CARET_RECT;
+      break;
+    case QUERY_TEXT_RECT:
+      message = NS_QUERY_TEXT_RECT;
+      break;
+    case QUERY_EDITOR_RECT:
+      message = NS_QUERY_EDITOR_RECT;
+      break;
+    case QUERY_CHARACTER_AT_POINT:
+      message = NS_QUERY_CHARACTER_AT_POINT;
+      break;
+    default:
+      return NS_ERROR_INVALID_ARG;
   }
 
   nsCOMPtr<nsIWidget> targetWidget = widget;
   LayoutDeviceIntPoint pt(aX, aY);
 
   bool useNativeLineBreak =
     !(aAdditionalFlags & QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK);
 
-  if (aType == QUERY_CHARACTER_AT_POINT) {
+  if (message == NS_QUERY_CHARACTER_AT_POINT) {
     // Looking for the widget at the point.
     WidgetQueryContentEvent dummyEvent(true, NS_QUERY_CONTENT_STATE, widget);
     dummyEvent.mUseNativeLineBreak = useNativeLineBreak;
     InitEvent(dummyEvent, &pt);
     nsIFrame* popupFrame =
       nsLayoutUtils::GetPopupFrameForEventCoordinates(presContext->GetRootPresContext(), &dummyEvent);
 
     nsIntRect widgetBounds;
@@ -1978,20 +1993,20 @@ nsDOMWindowUtils::SendQueryContentEvent(
     // Fire the event on the widget at the point
     if (popupFrame) {
       targetWidget = popupFrame->GetNearestWidget();
     }
   }
 
   pt += widget->WidgetToScreenOffset() - targetWidget->WidgetToScreenOffset();
 
-  WidgetQueryContentEvent queryEvent(true, aType, targetWidget);
+  WidgetQueryContentEvent queryEvent(true, message, targetWidget);
   InitEvent(queryEvent, &pt);
 
-  switch (aType) {
+  switch (message) {
     case NS_QUERY_TEXT_CONTENT:
       queryEvent.InitForQueryTextContent(aOffset, aLength, useNativeLineBreak);
       break;
     case NS_QUERY_CARET_RECT:
       queryEvent.InitForQueryCaretRect(aOffset, useNativeLineBreak);
       break;
     case NS_QUERY_TEXT_RECT:
       queryEvent.InitForQueryTextRect(aOffset, aLength, useNativeLineBreak);
@@ -2051,17 +2066,17 @@ nsDOMWindowUtils::SendContentCommandEven
 {
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
 
   // get the widget to send the event to
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget)
     return NS_ERROR_FAILURE;
 
-  int32_t msg;
+  EventMessage msg;
   if (aType.EqualsLiteral("cut"))
     msg = NS_CONTENT_COMMAND_CUT;
   else if (aType.EqualsLiteral("copy"))
     msg = NS_CONTENT_COMMAND_COPY;
   else if (aType.EqualsLiteral("paste"))
     msg = NS_CONTENT_COMMAND_PASTE;
   else if (aType.EqualsLiteral("delete"))
     msg = NS_CONTENT_COMMAND_DELETE;
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -92,35 +92,39 @@ PRLogModuleInfo* gFocusNavigationLog;
     MOZ_LOG(log, LogLevel::Debug, (format, tag.get()));             \
   }
 
 #define LOGCONTENT(format, content) LOGTAG(gFocusLog, format, content)
 #define LOGCONTENTNAVIGATION(format, content) LOGTAG(gFocusNavigationLog, format, content)
 
 struct nsDelayedBlurOrFocusEvent
 {
-  nsDelayedBlurOrFocusEvent(uint32_t aType,
+  nsDelayedBlurOrFocusEvent(EventMessage aEventMessage,
                             nsIPresShell* aPresShell,
                             nsIDocument* aDocument,
                             EventTarget* aTarget)
-   : mType(aType),
-     mPresShell(aPresShell),
-     mDocument(aDocument),
-     mTarget(aTarget) { }
+    : mPresShell(aPresShell)
+    , mDocument(aDocument)
+    , mTarget(aTarget)
+    , mEventMessage(aEventMessage)
+ {
+ }
 
   nsDelayedBlurOrFocusEvent(const nsDelayedBlurOrFocusEvent& aOther)
-   : mType(aOther.mType),
-     mPresShell(aOther.mPresShell),
-     mDocument(aOther.mDocument),
-     mTarget(aOther.mTarget) { }
-
-  uint32_t mType;
+    : mPresShell(aOther.mPresShell)
+    , mDocument(aOther.mDocument)
+    , mTarget(aOther.mTarget)
+    , mEventMessage(aOther.mEventMessage)
+  {
+  }
+
   nsCOMPtr<nsIPresShell> mPresShell;
   nsCOMPtr<nsIDocument> mDocument;
   nsCOMPtr<EventTarget> mTarget;
+  EventMessage mEventMessage;
 };
 
 inline void ImplCycleCollectionUnlink(nsDelayedBlurOrFocusEvent& aField)
 {
   aField.mPresShell = nullptr;
   aField.mDocument = nullptr;
   aField.mTarget = nullptr;
 }
@@ -1033,21 +1037,21 @@ nsFocusManager::FireDelayedEvents(nsIDoc
       if (!aDocument->GetInnerWindow() ||
           !aDocument->GetInnerWindow()->IsCurrentInnerWindow()) {
         // If the document was navigated away from or is defunct, don't bother
         // firing events on it. Note the symmetry between this condition and
         // the similar one in nsDocument.cpp:FireOrClearDelayedEvents.
         mDelayedBlurFocusEvents.RemoveElementAt(i);
         --i;
       } else if (!aDocument->EventHandlingSuppressed()) {
-        uint32_t type = mDelayedBlurFocusEvents[i].mType;
+        EventMessage message = mDelayedBlurFocusEvents[i].mEventMessage;
         nsCOMPtr<EventTarget> target = mDelayedBlurFocusEvents[i].mTarget;
         nsCOMPtr<nsIPresShell> presShell = mDelayedBlurFocusEvents[i].mPresShell;
         mDelayedBlurFocusEvents.RemoveElementAt(i);
-        SendFocusOrBlurEvent(type, presShell, aDocument, target, 0, false);
+        SendFocusOrBlurEvent(message, presShell, aDocument, target, 0, false);
         --i;
       }
     }
   }
 
   return NS_OK;
 }
 
@@ -1956,48 +1960,54 @@ nsFocusManager::Focus(nsPIDOMWindow* aWi
 
   if (clearFirstFocusEvent)
     mFirstFocusEvent = nullptr;
 }
 
 class FocusBlurEvent : public nsRunnable
 {
 public:
-  FocusBlurEvent(nsISupports* aTarget, uint32_t aType,
+  FocusBlurEvent(nsISupports* aTarget, EventMessage aEventMessage,
                  nsPresContext* aContext, bool aWindowRaised,
                  bool aIsRefocus)
-  : mTarget(aTarget), mType(aType), mContext(aContext),
-    mWindowRaised(aWindowRaised), mIsRefocus(aIsRefocus) {}
+    : mTarget(aTarget)
+    , mContext(aContext)
+    , mEventMessage(aEventMessage)
+    , mWindowRaised(aWindowRaised)
+    , mIsRefocus(aIsRefocus)
+  {
+  }
 
   NS_IMETHOD Run()
   {
-    InternalFocusEvent event(true, mType);
+    InternalFocusEvent event(true, mEventMessage);
     event.mFlags.mBubbles = false;
     event.fromRaise = mWindowRaised;
     event.isRefocus = mIsRefocus;
     return EventDispatcher::Dispatch(mTarget, mContext, &event);
   }
 
   nsCOMPtr<nsISupports>   mTarget;
-  uint32_t                mType;
   nsRefPtr<nsPresContext> mContext;
+  EventMessage            mEventMessage;
   bool                    mWindowRaised;
   bool                    mIsRefocus;
 };
 
 void
-nsFocusManager::SendFocusOrBlurEvent(uint32_t aType,
+nsFocusManager::SendFocusOrBlurEvent(EventMessage aEventMessage,
                                      nsIPresShell* aPresShell,
                                      nsIDocument* aDocument,
                                      nsISupports* aTarget,
                                      uint32_t aFocusMethod,
                                      bool aWindowRaised,
                                      bool aIsRefocus)
 {
-  NS_ASSERTION(aType == NS_FOCUS_CONTENT || aType == NS_BLUR_CONTENT,
+  NS_ASSERTION(aEventMessage == NS_FOCUS_CONTENT ||
+               aEventMessage == NS_BLUR_CONTENT,
                "Wrong event type for SendFocusOrBlurEvent");
 
   nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(aTarget);
 
   nsCOMPtr<nsINode> n = do_QueryInterface(aTarget);
   if (!n) {
     nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aTarget);
     n = win ? win->GetExtantDoc() : nullptr;
@@ -2010,42 +2020,44 @@ nsFocusManager::SendFocusOrBlurEvent(uin
   if (aFocusMethod && !dontDispatchEvent &&
       aDocument && aDocument->EventHandlingSuppressed()) {
     // aFlags is always 0 when aWindowRaised is true so this won't be called
     // on a window raise.
     NS_ASSERTION(!aWindowRaised, "aWindowRaised should not be set");
 
     for (uint32_t i = mDelayedBlurFocusEvents.Length(); i > 0; --i) {
       // if this event was already queued, remove it and append it to the end
-      if (mDelayedBlurFocusEvents[i - 1].mType == aType &&
+      if (mDelayedBlurFocusEvents[i - 1].mEventMessage == aEventMessage &&
           mDelayedBlurFocusEvents[i - 1].mPresShell == aPresShell &&
           mDelayedBlurFocusEvents[i - 1].mDocument == aDocument &&
           mDelayedBlurFocusEvents[i - 1].mTarget == eventTarget) {
         mDelayedBlurFocusEvents.RemoveElementAt(i - 1);
       }
     }
 
     mDelayedBlurFocusEvents.AppendElement(
-      nsDelayedBlurOrFocusEvent(aType, aPresShell, aDocument, eventTarget));
+      nsDelayedBlurOrFocusEvent(aEventMessage, aPresShell,
+                                aDocument, eventTarget));
     return;
   }
 
 #ifdef ACCESSIBILITY
   nsAccessibilityService* accService = GetAccService();
   if (accService) {
-    if (aType == NS_FOCUS_CONTENT)
+    if (aEventMessage == NS_FOCUS_CONTENT) {
       accService->NotifyOfDOMFocus(aTarget);
-    else
+    } else {
       accService->NotifyOfDOMBlur(aTarget);
+    }
   }
 #endif
 
   if (!dontDispatchEvent) {
     nsContentUtils::AddScriptRunner(
-      new FocusBlurEvent(aTarget, aType, aPresShell->GetPresContext(),
+      new FocusBlurEvent(aTarget, aEventMessage, aPresShell->GetPresContext(),
                          aWindowRaised, aIsRefocus));
   }
 }
 
 void
 nsFocusManager::ScrollIntoView(nsIPresShell* aPresShell,
                                nsIContent* aContent,
                                uint32_t aFlags)
--- a/dom/base/nsFocusManager.h
+++ b/dom/base/nsFocusManager.h
@@ -275,22 +275,22 @@ protected:
              bool aIsNewDocument,
              bool aFocusChanged,
              bool aWindowRaised,
              bool aAdjustWidget);
 
   /**
    * Fires a focus or blur event at aTarget.
    *
-   * aType should be either NS_FOCUS_CONTENT or NS_BLUR_CONTENT. For blur
-   * events, aFocusMethod should normally be non-zero.
+   * aEventMessage should be either NS_FOCUS_CONTENT or NS_BLUR_CONTENT.
+   * For blur events, aFocusMethod should normally be non-zero.
    *
    * aWindowRaised should only be true if called from WindowRaised.
    */
-  void SendFocusOrBlurEvent(uint32_t aType,
+  void SendFocusOrBlurEvent(mozilla::EventMessage aEventMessage,
                             nsIPresShell* aPresShell,
                             nsIDocument* aDocument,
                             nsISupports* aTarget,
                             uint32_t aFocusMethod,
                             bool aWindowRaised,
                             bool aIsRefocus = false);
 
   /**
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -3039,17 +3039,17 @@ nsGlobalWindow::GetJSContextForEventHand
   return nullptr;
 }
 
 nsresult
 nsGlobalWindow::PreHandleEvent(EventChainPreVisitor& aVisitor)
 {
   NS_PRECONDITION(IsInnerWindow(), "PreHandleEvent is used on outer window!?");
   static uint32_t count = 0;
-  uint32_t msg = aVisitor.mEvent->mMessage;
+  EventMessage msg = aVisitor.mEvent->mMessage;
 
   aVisitor.mCanHandle = true;
   aVisitor.mForceContentDispatch = true; //FIXME! Bug 329119
   if ((msg == NS_MOUSE_MOVE) && gEntropyCollector) {
     //Chances are this counter will overflow during the life of the
     //process, but that's OK for our case. Means we get a little
     //more entropy.
     if (count++ % 100 == 0) {
@@ -6613,17 +6613,16 @@ nsGlobalWindow::FinishFullscreenChange(b
 
     ErrorResult rv;
     mWakeLock = pmService->NewWakeLock(NS_LITERAL_STRING("DOM_Fullscreen"),
                                        this, rv);
     NS_WARN_IF_FALSE(!rv.Failed(), "Failed to lock the wakelock");
   } else if (mWakeLock && !mFullScreen) {
     ErrorResult rv;
     mWakeLock->Unlock(rv);
-    NS_WARN_IF_FALSE(!rv.Failed(), "Failed to unlock the wakelock.");
     mWakeLock = nullptr;
   }
 }
 
 bool
 nsGlobalWindow::FullScreen() const
 {
   MOZ_ASSERT(IsOuterWindow());
@@ -14528,17 +14527,17 @@ bool
 nsGlobalWindow::GetIsPrerendered()
 {
   nsIDocShell* docShell = GetDocShell();
   return docShell && docShell->GetIsPrerendered();
 }
 
 #ifdef MOZ_B2G
 void
-nsGlobalWindow::EnableNetworkEvent(uint32_t aType)
+nsGlobalWindow::EnableNetworkEvent(EventMessage aEventMessage)
 {
   MOZ_ASSERT(IsInnerWindow());
 
   nsCOMPtr<nsIPermissionManager> permMgr =
     services::GetPermissionManager();
   if (!permMgr) {
     NS_ERROR("No PermissionManager available!");
     return;
@@ -14553,55 +14552,59 @@ nsGlobalWindow::EnableNetworkEvent(uint3
   }
 
   nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
   if (!os) {
     NS_ERROR("ObserverService should be available!");
     return;
   }
 
-  switch (aType) {
+  switch (aEventMessage) {
     case NS_NETWORK_UPLOAD_EVENT:
       if (!mNetworkUploadObserverEnabled) {
         mNetworkUploadObserverEnabled = true;
         os->AddObserver(mObserver, NS_NETWORK_ACTIVITY_BLIP_UPLOAD_TOPIC, false);
       }
       break;
     case NS_NETWORK_DOWNLOAD_EVENT:
       if (!mNetworkDownloadObserverEnabled) {
         mNetworkDownloadObserverEnabled = true;
         os->AddObserver(mObserver, NS_NETWORK_ACTIVITY_BLIP_DOWNLOAD_TOPIC, false);
       }
       break;
-  }
-}
-
-void
-nsGlobalWindow::DisableNetworkEvent(uint32_t aType)
+    default:
+      break;
+  }
+}
+
+void
+nsGlobalWindow::DisableNetworkEvent(EventMessage aEventMessage)
 {
   MOZ_ASSERT(IsInnerWindow());
 
   nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
   if (!os) {
     return;
   }
 
-  switch (aType) {
+  switch (aEventMessage) {
     case NS_NETWORK_UPLOAD_EVENT:
       if (mNetworkUploadObserverEnabled) {
         mNetworkUploadObserverEnabled = false;
         os->RemoveObserver(mObserver, NS_NETWORK_ACTIVITY_BLIP_UPLOAD_TOPIC);
       }
       break;
     case NS_NETWORK_DOWNLOAD_EVENT:
       if (mNetworkDownloadObserverEnabled) {
         mNetworkDownloadObserverEnabled = false;
         os->RemoveObserver(mObserver, NS_NETWORK_ACTIVITY_BLIP_DOWNLOAD_TOPIC);
       }
       break;
+    default:
+      break;
   }
 }
 #endif // MOZ_B2G
 
 void
 nsGlobalWindow::RedefineProperty(JSContext* aCx, const char* aPropName,
                                  JS::Handle<JS::Value> aValue,
                                  ErrorResult& aError)
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -672,18 +672,19 @@ public:
   virtual void EnableDeviceSensor(uint32_t aType) override;
   virtual void DisableDeviceSensor(uint32_t aType) override;
 
   virtual void EnableTimeChangeNotifications() override;
   virtual void DisableTimeChangeNotifications() override;
 
 #ifdef MOZ_B2G
   // Inner windows only.
-  virtual void EnableNetworkEvent(uint32_t aType) override;
-  virtual void DisableNetworkEvent(uint32_t aType) override;
+  virtual void EnableNetworkEvent(mozilla::EventMessage aEventMessage) override;
+  virtual void DisableNetworkEvent(
+                 mozilla::EventMessage aEventMessage) override;
 #endif // MOZ_B2G
 
   virtual nsresult SetArguments(nsIArray* aArguments) override;
 
   void MaybeForgiveSpamCount();
   bool IsClosedOrClosing() {
     return (mIsClosed ||
             mInClose ||
--- a/dom/base/nsGlobalWindowCommands.cpp
+++ b/dom/base/nsGlobalWindowCommands.cpp
@@ -515,23 +515,25 @@ nsClipboardCommand::DoCommand(const char
   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
 
   nsIDocShell *docShell = window->GetDocShell();
   NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
   NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
 
-  int32_t eventType = NS_COPY;
+  EventMessage eventMessage = NS_COPY;
   if (strcmp(aCommandName, "cmd_cut") == 0) {
-    eventType = NS_CUT;
+    eventMessage = NS_CUT;
   }
 
   bool actionTaken = false;
-  nsCopySupport::FireClipboardEvent(eventType, nsIClipboard::kGlobalClipboard, presShell, nullptr, &actionTaken);
+  nsCopySupport::FireClipboardEvent(eventMessage,
+                                    nsIClipboard::kGlobalClipboard,
+                                    presShell, nullptr, &actionTaken);
 
   if (!strcmp(aCommandName, "cmd_copyAndCollapseToEnd")) {
     dom::Selection *sel =
       presShell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL);
     NS_ENSURE_TRUE(sel, NS_ERROR_FAILURE);
     sel->CollapseToEnd();
   }
 
--- a/dom/base/nsIObjectLoadingContent.idl
+++ b/dom/base/nsIObjectLoadingContent.idl
@@ -20,17 +20,17 @@ class nsNPAPIPluginInstance;
 
 /**
  * This interface represents a content node that loads objects.
  *
  * Please make sure to update the MozObjectLoadingContent WebIDL
  * interface to mirror this interface when changing it.
  */
 
-[scriptable, uuid(5efbd411-5bbe-4de1-9f3a-1c3459696eb2)]
+[scriptable, uuid(2eb3195e-3eea-4083-bb1d-d2d70fa35ccb)]
 interface nsIObjectLoadingContent : nsISupports
 {
   /**
    * See notes in nsObjectLoadingContent.h
    */
   const unsigned long TYPE_LOADING  = 0;
   const unsigned long TYPE_IMAGE    = 1;
   const unsigned long TYPE_PLUGIN   = 2;
@@ -60,18 +60,16 @@ interface nsIObjectLoadingContent : nsIS
   /// ** Furthermore, values >= PLUGIN_CLICK_TO_PLAY and
   ///    <= PLUGIN_VULNERABLE_NO_UPDATE are click-to-play types.
   // The plugin is disabled until the user clicks on it
   const unsigned long PLUGIN_CLICK_TO_PLAY        = 8;
   // The plugin is vulnerable (update available)
   const unsigned long PLUGIN_VULNERABLE_UPDATABLE = 9;
   // The plugin is vulnerable (no update available)
   const unsigned long PLUGIN_VULNERABLE_NO_UPDATE = 10;
-  // The plugin is in play preview mode
-  const unsigned long PLUGIN_PLAY_PREVIEW         = 11;
 
   /**
    * The actual mime type (the one we got back from the network
    * request) for the element.
    */
   readonly attribute ACString actualType;
 
   /**
@@ -123,33 +121,32 @@ interface nsIObjectLoadingContent : nsIS
    */
   [noscript] void pluginDestroyed();
   [noscript] void pluginCrashed(in nsIPluginTag pluginTag,
                                 in AString pluginDumpID,
                                 in AString browserDumpID,
                                 in boolean submittedCrashReport);
 
   /**
-   * This method will play a plugin that has been stopped by the
-   * click-to-play plugins or play-preview features.
+   * This method will play a plugin that has been stopped by click-to-play.
    */
   void playPlugin();
 
   /**
    * Forces a re-evaluation and reload of the tag, optionally invalidating its
    * click-to-play state.  This can be used when the MIME type that provides a
    * type has changed, for instance, to force the tag to re-evalulate the
    * handler to use.
    */
   void reload(in boolean aClearActivation);
 
   /**
    * This attribute will return true if the current content type has been
    * activated, either explicitly or by passing checks that would have it be
-   * click-to-play or play-preview.
+   * click-to-play.
    */
   readonly attribute boolean activated;
 
   [noscript] void stopPluginInstance();
 
   [noscript] void syncStartPluginInstance();
   [noscript] void asyncStartPluginInstance();
 
@@ -180,20 +177,15 @@ interface nsIObjectLoadingContent : nsIS
 
   /**
    * If this object currently owns a running plugin, regardless of whether or
    * not one is pending spawn/despawn.
    */
   readonly attribute bool hasRunningPlugin;
 
   /**
-   * This method will disable the play-preview plugin state.
-   */
-  void cancelPlayPreview();
-
-  /**
    * If this plugin runs out-of-process, it has a runID to differentiate
    * between different times the plugin process has been instantiated.
    *
    * This throws NS_ERROR_NOT_IMPLEMENTED for in-process plugins.
    */
   readonly attribute unsigned long runID;
 };
--- a/dom/base/nsObjectLoadingContent.cpp
+++ b/dom/base/nsObjectLoadingContent.cpp
@@ -710,17 +710,16 @@ nsObjectLoadingContent::nsObjectLoadingC
   : mType(eType_Loading)
   , mFallbackType(eFallbackAlternate)
   , mRunID(0)
   , mHasRunID(false)
   , mChannelLoaded(false)
   , mInstantiating(false)
   , mNetworkCreated(true)
   , mActivated(false)
-  , mPlayPreviewCanceled(false)
   , mIsStopping(false)
   , mIsLoading(false)
   , mScriptRequested(false) {}
 
 nsObjectLoadingContent::~nsObjectLoadingContent()
 {
   // Should have been unbound from the tree at this point, and
   // CheckPluginStopEvent keeps us alive
@@ -1401,18 +1400,16 @@ nsObjectLoadingContent::ObjectState() co
     case eType_Null:
       switch (mFallbackType) {
         case eFallbackSuppressed:
           return NS_EVENT_STATE_SUPPRESSED;
         case eFallbackUserDisabled:
           return NS_EVENT_STATE_USERDISABLED;
         case eFallbackClickToPlay:
           return NS_EVENT_STATE_TYPE_CLICK_TO_PLAY;
-        case eFallbackPlayPreview:
-          return NS_EVENT_STATE_TYPE_PLAY_PREVIEW;
         case eFallbackDisabled:
           return NS_EVENT_STATE_BROKEN | NS_EVENT_STATE_HANDLER_DISABLED;
         case eFallbackBlocklisted:
           return NS_EVENT_STATE_BROKEN | NS_EVENT_STATE_HANDLER_BLOCKED;
         case eFallbackCrashed:
           return NS_EVENT_STATE_BROKEN | NS_EVENT_STATE_HANDLER_CRASHED;
         case eFallbackUnsupported: {
           // Check to see if plugins are blocked on this platform.
@@ -3117,32 +3114,31 @@ nsObjectLoadingContent::PlayPlugin()
   if (!nsContentUtils::IsCallerChrome())
     return NS_OK;
 
   if (!mActivated) {
     mActivated = true;
     LOG(("OBJLC [%p]: Activated by user", this));
   }
 
-  // If we're in a click-to-play or play preview state, we need to reload
+  // If we're in a click-to-play state, reload.
   // Fallback types >= eFallbackClickToPlay are plugin-replacement types, see
   // header
   if (mType == eType_Null && mFallbackType >= eFallbackClickToPlay) {
     return LoadObject(true, true);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsObjectLoadingContent::Reload(bool aClearActivation)
 {
   if (aClearActivation) {
     mActivated = false;
-    mPlayPreviewCanceled = false;
   }
 
   return LoadObject(true, true);
 }
 
 NS_IMETHODIMP
 nsObjectLoadingContent::GetActivated(bool *aActivated)
 {
@@ -3173,32 +3169,16 @@ NS_IMETHODIMP
 nsObjectLoadingContent::GetHasRunningPlugin(bool *aHasPlugin)
 {
   NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
   *aHasPlugin = HasRunningPlugin();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsObjectLoadingContent::CancelPlayPreview()
-{
-  if (!nsContentUtils::IsCallerChrome())
-    return NS_ERROR_NOT_AVAILABLE;
-
-  mPlayPreviewCanceled = true;
-
-  // If we're in play preview state already, reload
-  if (mType == eType_Null && mFallbackType == eFallbackPlayPreview) {
-    return LoadObject(true, true);
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 nsObjectLoadingContent::GetRunID(uint32_t* aRunID)
 {
   if (NS_WARN_IF(!nsContentUtils::IsCallerChrome())) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   if (NS_WARN_IF(!aRunID)) {
     return NS_ERROR_INVALID_POINTER;
   }
@@ -3233,52 +3213,25 @@ nsObjectLoadingContent::ShouldPlay(Fallb
     // Plugins running OOP from the chrome process along with plugins running
     // OOP from the content process will hang. Let's prevent that situation.
     aReason = eFallbackDisabled;
     return false;
   }
 
   nsRefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
 
-  nsCOMPtr<nsIPluginPlayPreviewInfo> playPreviewInfo;
-  bool isPlayPreviewSpecified = NS_SUCCEEDED(pluginHost->GetPlayPreviewInfo(
-    mContentType, getter_AddRefs(playPreviewInfo)));
-  if (isPlayPreviewSpecified) {
-    // Checking PlayPreview whitelist as well.
-    nsCString uriSpec, baseSpec;
-    if (mURI) {
-      mURI->GetSpec(uriSpec);
-    }
-    if (mBaseURI) {
-      mBaseURI->GetSpec(baseSpec);
-    }
-    playPreviewInfo->CheckWhitelist(baseSpec, uriSpec, &isPlayPreviewSpecified);
-  }
-  bool ignoreCTP = false;
-  if (isPlayPreviewSpecified) {
-    playPreviewInfo->GetIgnoreCTP(&ignoreCTP);
-  }
-  if (isPlayPreviewSpecified && !mPlayPreviewCanceled &&
-      ignoreCTP) {
-    // play preview in ignoreCTP mode is shown even if the native plugin
-    // is not present/installed
-    aReason = eFallbackPlayPreview;
-    return false;
-  }
   // at this point if it's not a plugin, we let it play/fallback
   if (!aIgnoreCurrentType && mType != eType_Plugin) {
     return true;
   }
 
   // Order of checks:
   // * Assume a default of click-to-play
   // * If globally disabled, per-site permissions cannot override.
   // * If blocklisted, override the reason with the blocklist reason
-  // * If not blocklisted but playPreview, override the reason with the
-  //   playPreview reason.
   // * Check per-site permissions and follow those if specified.
   // * Honor per-plugin disabled permission
   // * Blocklisted plugins are forced to CtP
   // * Check per-plugin permission and follow that.
 
   aReason = eFallbackClickToPlay;
 
   uint32_t enabledState = nsIPluginTag::STATE_DISABLED;
@@ -3304,22 +3257,16 @@ nsObjectLoadingContent::ShouldPlay(Fallb
 
   if (blocklistState == nsIBlocklistService::STATE_VULNERABLE_UPDATE_AVAILABLE) {
     aReason = eFallbackVulnerableUpdatable;
   }
   else if (blocklistState == nsIBlocklistService::STATE_VULNERABLE_NO_UPDATE) {
     aReason = eFallbackVulnerableNoUpdate;
   }
 
-  if (aReason == eFallbackClickToPlay && isPlayPreviewSpecified &&
-      !mPlayPreviewCanceled && !ignoreCTP) {
-    // play preview in click-to-play mode is shown instead of standard CTP UI
-    aReason = eFallbackPlayPreview;
-  }
-
   // Check the permission manager for permission based on the principal of
   // the toplevel content.
 
   nsCOMPtr<nsIContent> thisContent = do_QueryInterface(static_cast<nsIObjectLoadingContent*>(this));
   MOZ_ASSERT(thisContent);
   nsIDocument* ownerDoc = thisContent->OwnerDoc();
 
   nsCOMPtr<nsIDOMWindow> window = ownerDoc->GetWindow();
--- a/dom/base/nsObjectLoadingContent.h
+++ b/dom/base/nsObjectLoadingContent.h
@@ -89,19 +89,16 @@ class nsObjectLoadingContent : public ns
       /// ** Furthermore, values >= eFallbackClickToPlay and
       ///    <= eFallbackVulnerableNoUpdate are click-to-play types.
       // The plugin is disabled until the user clicks on it
       eFallbackClickToPlay = nsIObjectLoadingContent::PLUGIN_CLICK_TO_PLAY,
       // The plugin is vulnerable (update available)
       eFallbackVulnerableUpdatable = nsIObjectLoadingContent::PLUGIN_VULNERABLE_UPDATABLE,
       // The plugin is vulnerable (no update available)
       eFallbackVulnerableNoUpdate = nsIObjectLoadingContent::PLUGIN_VULNERABLE_NO_UPDATE,
-      // The plugin is disabled and play preview content is displayed until
-      // the extension code enables it by sending the MozPlayPlugin event
-      eFallbackPlayPreview = nsIObjectLoadingContent::PLUGIN_PLAY_PREVIEW
     };
 
     nsObjectLoadingContent();
     virtual ~nsObjectLoadingContent();
 
     NS_DECL_NSIREQUESTOBSERVER
     NS_DECL_NSISTREAMLISTENER
     NS_DECL_NSIFRAMELOADEROWNER
@@ -220,20 +217,16 @@ class nsObjectLoadingContent : public ns
     uint32_t PluginFallbackType() const
     {
       return mFallbackType;
     }
     bool HasRunningPlugin() const
     {
       return !!mInstanceOwner;
     }
-    void CancelPlayPreview(mozilla::ErrorResult& aRv)
-    {
-      aRv = CancelPlayPreview();
-    }
     void SwapFrameLoaders(nsXULElement& aOtherOwner, mozilla::ErrorResult& aRv)
     {
       aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
     }
     void LegacyCall(JSContext* aCx, JS::Handle<JS::Value> aThisVal,
                     const mozilla::dom::Sequence<JS::Value>& aArguments,
                     JS::MutableHandle<JS::Value> aRetval,
                     mozilla::ErrorResult& aRv);
@@ -617,26 +610,23 @@ class nsObjectLoadingContent : public ns
     // created using NS_FROM_PARSER_NETWORK flag. If the element is modified,
     // it may lose the flag.
     bool                        mNetworkCreated : 1;
 
     // Used to keep track of whether or not a plugin has been explicitly
     // activated by PlayPlugin(). (see ShouldPlay())
     bool                        mActivated : 1;
 
-    // Used to keep track of whether or not a plugin is blocked by play-preview.
-    bool                        mPlayPreviewCanceled : 1;
-
     // Protects DoStopPlugin from reentry (bug 724781).
     bool                        mIsStopping : 1;
 
     // Protects LoadObject from re-entry
     bool                        mIsLoading : 1;
 
-    // For plugin stand-in types (click-to-play, play preview, ...) tracks
+    // For plugin stand-in types (click-to-play) tracks
     // whether content js has tried to access the plugin script object.
     bool                        mScriptRequested : 1;
 
     nsWeakFrame                 mPrintFrame;
 
     nsRefPtr<nsPluginInstanceOwner> mInstanceOwner;
     nsTArray<mozilla::dom::MozPluginParameter> mCachedAttributes;
     nsTArray<mozilla::dom::MozPluginParameter> mCachedParameters;
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -57,18 +57,18 @@ enum PopupControlState {
 enum UIStateChangeType
 {
   UIStateChangeType_NoChange,
   UIStateChangeType_Set,
   UIStateChangeType_Clear
 };
 
 #define NS_PIDOMWINDOW_IID \
-{ 0x2aebbbd7, 0x154b, 0x4341, \
-  { 0x8d, 0x02, 0x7f, 0x70, 0xf8, 0x3e, 0xf7, 0xa1 } }
+{ 0x052e675a, 0xacd3, 0x48d1, \
+  { 0x8a, 0xcd, 0xbf, 0xff, 0xbd, 0x24, 0x4c, 0xed } }
 
 class nsPIDOMWindow : public nsIDOMWindowInternal
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_PIDOMWINDOW_IID)
 
   virtual nsPIDOMWindow* GetPrivateRoot() = 0;
 
@@ -638,25 +638,25 @@ public:
 
 #ifdef MOZ_B2G
   /**
    * Tell the window that it should start to listen to the network event of the
    * given aType.
    *
    * Inner windows only.
    */
-  virtual void EnableNetworkEvent(uint32_t aType) = 0;
+  virtual void EnableNetworkEvent(mozilla::EventMessage aEventMessage) = 0;
 
   /**
    * Tell the window that it should stop to listen to the network event of the
    * given aType.
    *
    * Inner windows only.
    */
-  virtual void DisableNetworkEvent(uint32_t aType) = 0;
+  virtual void DisableNetworkEvent(mozilla::EventMessage aEventMessage) = 0;
 #endif // MOZ_B2G
 
   /**
    * Tell this window that there is an observer for gamepad input
    *
    * Inner windows only.
    */
   virtual void SetHasGamepadEventListener(bool aHasGamepad = true) = 0;
--- a/dom/base/nsScriptElement.cpp
+++ b/dom/base/nsScriptElement.cpp
@@ -54,20 +54,20 @@ nsScriptElement::ScriptEvaluated(nsresul
   if (!aIsInline) {
     nsCOMPtr<nsIContent> cont =
       do_QueryInterface((nsIScriptElement*) this);
 
     nsRefPtr<nsPresContext> presContext =
       nsContentUtils::GetContextForContent(cont);
 
     nsEventStatus status = nsEventStatus_eIgnore;
-    uint32_t type = NS_SUCCEEDED(aResult) ? NS_LOAD : NS_LOAD_ERROR;
-    WidgetEvent event(true, type);
+    EventMessage message = NS_SUCCEEDED(aResult) ? NS_LOAD : NS_LOAD_ERROR;
+    WidgetEvent event(true, message);
     // Load event doesn't bubble.
-    event.mFlags.mBubbles = (type != NS_LOAD);
+    event.mFlags.mBubbles = (message != NS_LOAD);
 
     EventDispatcher::Dispatch(cont, presContext, &event, nullptr, &status);
   }
 
   return rv;
 }
 
 void
--- a/dom/base/nsScriptLoader.cpp
+++ b/dom/base/nsScriptLoader.cpp
@@ -631,52 +631,59 @@ nsScriptLoader::ProcessScriptElement(nsI
           SRICheck::IntegrityMetadata(integrity, mDocument, &sriMetadata);
         }
       }
 
       request = new nsScriptLoadRequest(aElement, version, ourCORSMode,
                                         sriMetadata);
       request->mURI = scriptURI;
       request->mIsInline = false;
-      request->mLoading = true;
+      request->mProgress = nsScriptLoadRequest::Progress_Loading;
       request->mReferrerPolicy = ourRefPolicy;
 
       // set aScriptFromHead to false so we don't treat non preloaded scripts as
       // blockers for full page load. See bug 792438.
       rv = StartLoad(request, type, false);
       if (NS_FAILED(rv)) {
         // Asynchronously report the load failure
         NS_DispatchToCurrentThread(
           NS_NewRunnableMethod(aElement,
                                &nsIScriptElement::FireErrorEvent));
         return false;
       }
     }
 
+    // Should still be in loading stage of script.
+    NS_ASSERTION(!request->InCompilingStage(),
+                 "Request should not yet be in compiling stage.");
+
     request->mJSVersion = version;
 
     if (aElement->GetScriptAsync()) {
       request->mIsAsync = true;
-      if (!request->mLoading) {
+      if (request->IsDoneLoading()) {
         mLoadedAsyncRequests.AppendElement(request);
         // The script is available already. Run it ASAP when the event
         // loop gets a chance to spin.
+
+        // KVKV TODO: Instead of processing immediately, try off-thread-parsing
+        // it and only schedule a ProcessRequest if that fails.
         ProcessPendingRequestsAsync();
       } else {
         mLoadingAsyncRequests.AppendElement(request);
       }
       return false;
     }
     if (!aElement->GetParserCreated()) {
       // Violate the HTML5 spec in order to make LABjs and the "order" plug-in
       // for RequireJS work with their Gecko-sniffed code path. See
       // http://lists.w3.org/Archives/Public/public-html/2010Oct/0088.html
       request->mIsNonAsyncScriptInserted = true;
       mNonAsyncExternalScriptInsertedRequests.AppendElement(request);
-      if (!request->mLoading) {
+      if (request->IsDoneLoading()) {
         // The script is available already. Run it ASAP when the event
         // loop gets a chance to spin.
         ProcessPendingRequestsAsync();
       }
       return false;
     }
     // we now have a parser-inserted request that may or may not be still
     // loading
@@ -695,24 +702,24 @@ nsScriptLoader::ProcessScriptElement(nsI
     }
 
     if (aElement->GetParserCreated() == FROM_PARSER_XSLT) {
       // Need to maintain order for XSLT-inserted scripts
       NS_ASSERTION(!mParserBlockingRequest,
           "Parser-blocking scripts and XSLT scripts in the same doc!");
       request->mIsXSLT = true;
       mXSLTRequests.AppendElement(request);
-      if (!request->mLoading) {
+      if (request->IsDoneLoading()) {
         // The script is available already. Run it ASAP when the event
         // loop gets a chance to spin.
         ProcessPendingRequestsAsync();
       }
       return true;
     }
-    if (!request->mLoading && ReadyToExecuteScripts()) {
+    if (request->IsDoneLoading() && ReadyToExecuteScripts()) {
       // The request has already been loaded and there are no pending style
       // sheets. If the script comes from the network stream, cheat for
       // performance reasons and avoid a trip through the event loop.
       if (aElement->GetParserCreated() == FROM_PARSER_NETWORK) {
         return ProcessRequest(request) == NS_ERROR_HTMLPARSER_BLOCK;
       }
       // Otherwise, we've got a document.written script, make a trip through
       // the event loop to hide the preload effects from the scripts on the
@@ -745,17 +752,17 @@ nsScriptLoader::ProcessScriptElement(nsI
   if (!CSPAllowsInlineScript(aElement, mDocument)) {
     return false;
   }
 
   // Inline scripts ignore ther CORS mode and are always CORS_NONE
   request = new nsScriptLoadRequest(aElement, version, CORS_NONE,
                                     SRIMetadata()); // SRI doesn't apply
   request->mJSVersion = version;
-  request->mLoading = false;
+  request->mProgress = nsScriptLoadRequest::Progress_DoneLoading;
   request->mIsInline = true;
   request->mURI = mDocument->GetDocumentURI();
   request->mLineNo = aElement->GetScriptLineNumber();
 
   if (aElement->GetParserCreated() == FROM_PARSER_XSLT &&
       (!ReadyToExecuteScripts() || !mXSLTRequests.isEmpty())) {
     // Need to maintain order for XSLT-inserted scripts
     NS_ASSERTION(!mParserBlockingRequest,
@@ -814,19 +821,21 @@ public:
   }
 
   NS_DECL_NSIRUNNABLE
 };
 
 } /* anonymous namespace */
 
 nsresult
-nsScriptLoader::ProcessOffThreadRequest(nsScriptLoadRequest* aRequest, void **aOffThreadToken)
+nsScriptLoader::ProcessOffThreadRequest(nsScriptLoadRequest* aRequest)
 {
-  nsresult rv = ProcessRequest(aRequest, aOffThreadToken);
+  MOZ_ASSERT(aRequest->mProgress == nsScriptLoadRequest::Progress_Compiling);
+  aRequest->mProgress = nsScriptLoadRequest::Progress_DoneCompiling;
+  nsresult rv = ProcessRequest(aRequest);
   mDocument->UnblockOnload(false);
   return rv;
 }
 
 NotifyOffThreadScriptLoadCompletedRunnable::~NotifyOffThreadScriptLoadCompletedRunnable()
 {
   if (MOZ_UNLIKELY(mRequest || mLoader) && !NS_IsMainThread()) {
     nsCOMPtr<nsIThread> mainThread;
@@ -848,24 +857,18 @@ NotifyOffThreadScriptLoadCompletedRunnab
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   // We want these to be dropped on the main thread, once we return from this
   // function.
   nsRefPtr<nsScriptLoadRequest> request = mRequest.forget();
   nsRefPtr<nsScriptLoader> loader = mLoader.forget();
 
-  nsresult rv = loader->ProcessOffThreadRequest(request, &mToken);
-
-  if (mToken) {
-    // The result of the off thread parse was not actually needed to process
-    // the request (disappearing window, some other error, ...). Finish the
-    // request to avoid leaks in the JS engine.
-    JS::FinishOffThreadScript(nullptr, xpc::GetJSRuntime(), mToken);
-  }
+  request->mOffThreadToken = mToken;
+  nsresult rv = loader->ProcessOffThreadRequest(request);
 
   return rv;
 }
 
 static void
 OffThreadScriptLoaderCallback(void *aToken, void *aCallbackData)
 {
   nsRefPtr<NotifyOffThreadScriptLoadCompletedRunnable> aRunnable =
@@ -906,33 +909,48 @@ nsScriptLoader::AttemptAsyncScriptParse(
   if (!JS::CompileOffThread(cx, options,
                             aRequest->mScriptTextBuf, aRequest->mScriptTextLength,
                             OffThreadScriptLoaderCallback,
                             static_cast<void*>(runnable))) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   mDocument->BlockOnload();
+  aRequest->mProgress = nsScriptLoadRequest::Progress_Compiling;
 
   unused << runnable.forget();
   return NS_OK;
 }
 
 nsresult
-nsScriptLoader::ProcessRequest(nsScriptLoadRequest* aRequest, void **aOffThreadToken)
+nsScriptLoader::CompileOffThreadOrProcessRequest(nsScriptLoadRequest* aRequest)
 {
   NS_ASSERTION(nsContentUtils::IsSafeToRunScript(),
                "Processing requests when running scripts is unsafe.");
+  NS_ASSERTION(!aRequest->mOffThreadToken,
+               "Candidate for off-thread compile is already parsed off-thread");
+  NS_ASSERTION(!aRequest->InCompilingStage(),
+               "Candidate for off-thread compile is already in compiling stage.");
 
-  if (!aOffThreadToken) {
-    nsresult rv = AttemptAsyncScriptParse(aRequest);
-    if (rv != NS_ERROR_FAILURE)
-      return rv;
+  nsresult rv = AttemptAsyncScriptParse(aRequest);
+  if (rv != NS_ERROR_FAILURE) {
+    return rv;
   }
 
+  return ProcessRequest(aRequest);
+}
+
+nsresult
+nsScriptLoader::ProcessRequest(nsScriptLoadRequest* aRequest)
+{
+  NS_ASSERTION(nsContentUtils::IsSafeToRunScript(),
+               "Processing requests when running scripts is unsafe.");
+  NS_ASSERTION(aRequest->IsReadyToRun(),
+               "Processing a request that is not ready to run.");
+
   NS_ENSURE_ARG(aRequest);
   nsAutoString textData;
   const char16_t* scriptBuf = nullptr;
   size_t scriptLength = 0;
   JS::SourceBufferHolder::Ownership giveScriptOwnership =
     JS::SourceBufferHolder::NoOwnership;
 
   nsCOMPtr<nsIDocument> doc;
@@ -990,17 +1008,17 @@ nsScriptLoader::ProcessRequest(nsScriptL
   }
 
   nsresult rv = NS_OK;
   if (runScript) {
     if (doc) {
       doc->BeginEvaluatingExternalScript();
     }
     aRequest->mElement->BeginEvaluating();
-    rv = EvaluateScript(aRequest, srcBuf, aOffThreadToken);
+    rv = EvaluateScript(aRequest, srcBuf);
     aRequest->mElement->EndEvaluating();
     if (doc) {
       doc->EndEvaluatingExternalScript();
     }
 
     nsContentUtils::DispatchTrustedEvent(scriptElem->OwnerDoc(),
                                          scriptElem,
                                          NS_LITERAL_STRING("afterscriptexecute"),
@@ -1008,16 +1026,25 @@ nsScriptLoader::ProcessRequest(nsScriptL
   }
 
   FireScriptEvaluated(rv, aRequest);
 
   if (parserCreated) {
     mCurrentParserInsertedScript = oldParserInsertedScript;
   }
 
+  if (aRequest->mOffThreadToken) {
+    // The request was parsed off-main-thread, but the result of the off
+    // thread parse was not actually needed to process the request
+    // (disappearing window, some other error, ...). Finish the
+    // request to avoid leaks in the JS engine.
+    JS::FinishOffThreadScript(nullptr, xpc::GetJSRuntime(), aRequest->mOffThreadToken);
+    aRequest->mOffThreadToken = nullptr;
+  }
+
   return rv;
 }
 
 void
 nsScriptLoader::FireScriptAvailable(nsresult aResult,
                                     nsScriptLoadRequest* aRequest)
 {
   for (int32_t i = 0; i < mObservers.Count(); i++) {
@@ -1098,18 +1125,17 @@ nsScriptLoader::FillCompileOptionsForReq
                                               /* aAllowWrapping = */ true))) {
     MOZ_ASSERT(elementVal.isObject());
     aOptions->setElement(&elementVal.toObject());
   }
 }
 
 nsresult
 nsScriptLoader::EvaluateScript(nsScriptLoadRequest* aRequest,
-                               JS::SourceBufferHolder& aSrcBuf,
-                               void** aOffThreadToken)
+                               JS::SourceBufferHolder& aSrcBuf)
 {
   // We need a document to evaluate scripts.
   if (!mDocument) {
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsIContent> scriptContent(do_QueryInterface(aRequest->mElement));
   nsIDocument* ownerDoc = scriptContent->OwnerDoc();
@@ -1164,17 +1190,17 @@ nsScriptLoader::EvaluateScript(nsScriptL
       // of the master document too.
       masterScriptUpdater.emplace(master->ScriptLoader(),
                                   aRequest->mElement);
     }
 
     JS::CompileOptions options(entryScript.cx());
     FillCompileOptionsForRequest(entryScript, aRequest, global, &options);
     rv = nsJSUtils::EvaluateString(entryScript.cx(), aSrcBuf, global, options,
-                                   aOffThreadToken);
+                                   aRequest->OffThreadTokenPtr());
   }
 
   context->SetProcessingScriptTag(oldProcessingScriptTag);
   return rv;
 }
 
 void
 nsScriptLoader::ProcessPendingRequestsAsync()
@@ -1186,49 +1212,50 @@ nsScriptLoader::ProcessPendingRequestsAs
     NS_DispatchToCurrentThread(ev);
   }
 }
 
 void
 nsScriptLoader::ProcessPendingRequests()
 {
   nsRefPtr<nsScriptLoadRequest> request;
+
   if (mParserBlockingRequest &&
-      !mParserBlockingRequest->mLoading &&
+      mParserBlockingRequest->IsReadyToRun() &&
       ReadyToExecuteScripts()) {
     request.swap(mParserBlockingRequest);
     UnblockParser(request);
     ProcessRequest(request);
     ContinueParserAsync(request);
   }
 
   while (ReadyToExecuteScripts() && 
          !mXSLTRequests.isEmpty() &&
-         !mXSLTRequests.getFirst()->mLoading) {
+         mXSLTRequests.getFirst()->IsReadyToRun()) {
     request = mXSLTRequests.StealFirst();
     ProcessRequest(request);
   }
 
   while (mEnabled && !mLoadedAsyncRequests.isEmpty()) {
     request = mLoadedAsyncRequests.StealFirst();
-    ProcessRequest(request);
+    CompileOffThreadOrProcessRequest(request);
   }
 
   while (mEnabled && !mNonAsyncExternalScriptInsertedRequests.isEmpty() &&
-         !mNonAsyncExternalScriptInsertedRequests.getFirst()->mLoading) {
+         mNonAsyncExternalScriptInsertedRequests.getFirst()->IsReadyToRun()) {
     // Violate the HTML5 spec and execute these in the insertion order in
     // order to make LABjs and the "order" plug-in for RequireJS work with
     // their Gecko-sniffed code path. See
     // http://lists.w3.org/Archives/Public/public-html/2010Oct/0088.html
     request = mNonAsyncExternalScriptInsertedRequests.StealFirst();
     ProcessRequest(request);
   }
 
   if (mDocumentParsingDone && mXSLTRequests.isEmpty()) {
-    while (!mDeferRequests.isEmpty() && !mDeferRequests.getFirst()->mLoading) {
+    while (!mDeferRequests.isEmpty() && mDeferRequests.getFirst()->IsReadyToRun()) {
       request = mDeferRequests.StealFirst();
       ProcessRequest(request);
     }
   }
 
   while (!mPendingChildLoaders.IsEmpty() && ReadyToExecuteScripts()) {
     nsRefPtr<nsScriptLoader> child = mPendingChildLoaders[0];
     mPendingChildLoaders.RemoveElementAt(0);
@@ -1431,20 +1458,26 @@ nsScriptLoader::OnStreamComplete(nsIStre
                                  nsresult aStatus,
                                  uint32_t aStringLen,
                                  const uint8_t* aString)
 {
   nsScriptLoadRequest* request = static_cast<nsScriptLoadRequest*>(aContext);
   NS_ASSERTION(request, "null request in stream complete handler");
   NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
 
+  nsCOMPtr<nsIHttpChannel> httpChannel;
+  {
+    nsCOMPtr<nsIRequest> req;
+    aLoader->GetRequest(getter_AddRefs(req));
+    httpChannel = do_QueryInterface(req);
+  } // throw away req, we only need the channel
+
   nsresult rv = NS_ERROR_SRI_CORRUPT;
   if (request->mIntegrity.IsEmpty() ||
-      NS_SUCCEEDED(SRICheck::VerifyIntegrity(request->mIntegrity,
-                                             request->mURI,
+      NS_SUCCEEDED(SRICheck::VerifyIntegrity(request->mIntegrity, httpChannel,
                                              request->mCORSMode, aStringLen,
                                              aString, mDocument))) {
     rv = PrepareLoadedRequest(request, aLoader, aStatus, aStringLen, aString);
   }
 
   if (NS_FAILED(rv)) {
     /*
      * Handle script not loading error because source was a tracking URL.
@@ -1587,17 +1620,17 @@ nsScriptLoader::PrepareLoadedRequest(nsS
                mLoadingAsyncRequests.Contains(aRequest) ||
                mNonAsyncExternalScriptInsertedRequests.Contains(aRequest) ||
                mXSLTRequests.Contains(aRequest)  ||
                mPreloads.Contains(aRequest, PreloadRequestComparator()) ||
                mParserBlockingRequest,
                "aRequest should be pending!");
 
   // Mark this as loaded
-  aRequest->mLoading = false;
+  aRequest->mProgress = nsScriptLoadRequest::Progress_DoneLoading;
 
   // And if it's async, move it to the loaded list.  aRequest->mIsAsync really
   // _should_ be in a list, but the consequences if it's not are bad enough we
   // want to avoid trying to move it if it's not.
   if (aRequest->mIsAsync) {
     MOZ_ASSERT(aRequest->isInList());
     if (aRequest->isInList()) {
       nsRefPtr<nsScriptLoadRequest> req = mLoadingAsyncRequests.Steal(aRequest);
@@ -1656,17 +1689,17 @@ nsScriptLoader::PreloadURI(nsIURI *aURI,
   }
 
   nsRefPtr<nsScriptLoadRequest> request =
     new nsScriptLoadRequest(nullptr, 0,
                             Element::StringToCORSMode(aCrossOrigin),
                             sriMetadata);
   request->mURI = aURI;
   request->mIsInline = false;
-  request->mLoading = true;
+  request->mProgress = nsScriptLoadRequest::Progress_Loading;
   request->mReferrerPolicy = aReferrerPolicy;
 
   nsresult rv = StartLoad(request, aType, aScriptFromHead);
   if (NS_FAILED(rv)) {
     return;
   }
 
   PreloadInfo *pi = mPreloads.AppendElement();
--- a/dom/base/nsScriptLoader.h
+++ b/dom/base/nsScriptLoader.h
@@ -55,24 +55,25 @@ class nsScriptLoadRequest final : public
   friend class nsScriptLoadRequestList;
 
 public:
   nsScriptLoadRequest(nsIScriptElement* aElement,
                       uint32_t aVersion,
                       mozilla::CORSMode aCORSMode,
                       const mozilla::dom::SRIMetadata &aIntegrity)
     : mElement(aElement),
-      mLoading(true),
+      mProgress(Progress_Loading),
       mIsInline(true),
       mHasSourceMapURL(false),
       mIsDefer(false),
       mIsAsync(false),
       mIsNonAsyncScriptInserted(false),
       mIsXSLT(false),
       mIsCanceled(false),
+      mOffThreadToken(nullptr),
       mScriptTextBuf(nullptr),
       mScriptTextLength(0),
       mJSVersion(aVersion),
       mLineNo(1),
       mCORSMode(aCORSMode),
       mIntegrity(aIntegrity),
       mReferrerPolicy(mozilla::net::RP_Default)
   {
@@ -99,28 +100,51 @@ public:
     mIsCanceled = true;
   }
 
   bool IsCanceled() const
   {
     return mIsCanceled;
   }
 
+  void** OffThreadTokenPtr()
+  {
+    return mOffThreadToken ?  &mOffThreadToken : nullptr;
+  }
+
+  enum Progress {
+    Progress_Loading,
+    Progress_DoneLoading,
+    Progress_Compiling,
+    Progress_DoneCompiling
+  };
+  bool IsReadyToRun() {
+    return mProgress == Progress_DoneLoading ||
+           mProgress == Progress_DoneCompiling;
+  }
+  bool IsDoneLoading() {
+    return mProgress == Progress_DoneLoading;
+  }
+  bool InCompilingStage() {
+    return (mProgress == Progress_Compiling) || (mProgress == Progress_DoneCompiling);
+  }
+
   using super::getNext;
   using super::isInList;
 
   nsCOMPtr<nsIScriptElement> mElement;
-  bool mLoading;          // Are we still waiting for a load to complete?
+  Progress mProgress;     // Are we still waiting for a load to complete?
   bool mIsInline;         // Is the script inline or loaded?
   bool mHasSourceMapURL;  // Does the HTTP header have a source map url?
   bool mIsDefer;          // True if we live in mDeferRequests.
   bool mIsAsync;          // True if we live in mLoadingAsyncRequests or mLoadedAsyncRequests.
   bool mIsNonAsyncScriptInserted; // True if we live in mNonAsyncExternalScriptInsertedRequests
   bool mIsXSLT;           // True if we live in mXSLTRequests.
   bool mIsCanceled;       // True if we have been explicitly canceled.
+  void* mOffThreadToken;  // Off-thread parsing token.
   nsString mSourceMapURL; // Holds source map url for loaded scripts
   char16_t* mScriptTextBuf; // Holds script text for non-inline scripts. Don't
   size_t mScriptTextLength; // use nsString so we can give ownership to jsapi.
   uint32_t mJSVersion;
   nsCOMPtr<nsIURI> mURI;
   nsCOMPtr<nsIPrincipal> mOriginPrincipal;
   nsAutoCString mURL;   // Keep the URI's filename alive during off thread parsing.
   int32_t mLineNo;
@@ -380,18 +404,17 @@ public:
                           const nsAString& aIntegrity,
                           bool aScriptFromHead,
                           const mozilla::net::ReferrerPolicy aReferrerPolicy);
 
   /**
    * Process a request that was deferred so that the script could be compiled
    * off thread.
    */
-  nsresult ProcessOffThreadRequest(nsScriptLoadRequest *aRequest,
-                                   void **aOffThreadToken);
+  nsresult ProcessOffThreadRequest(nsScriptLoadRequest *aRequest);
 
   bool AddPendingChildLoader(nsScriptLoader* aChild) {
     return mPendingChildLoaders.AppendElement(aChild) != nullptr;
   }
 
 private:
   virtual ~nsScriptLoader();
 
@@ -441,25 +464,24 @@ private:
    * Return whether just this loader is ready to execute scripts.
    */
   bool SelfReadyToExecuteScripts()
   {
     return mEnabled && !mBlockerCount;
   }
 
   nsresult AttemptAsyncScriptParse(nsScriptLoadRequest* aRequest);
-  nsresult ProcessRequest(nsScriptLoadRequest* aRequest,
-                          void **aOffThreadToken = nullptr);
+  nsresult ProcessRequest(nsScriptLoadRequest* aRequest);
+  nsresult CompileOffThreadOrProcessRequest(nsScriptLoadRequest* aRequest);
   void FireScriptAvailable(nsresult aResult,
                            nsScriptLoadRequest* aRequest);
   void FireScriptEvaluated(nsresult aResult,
                            nsScriptLoadRequest* aRequest);
   nsresult EvaluateScript(nsScriptLoadRequest* aRequest,
-                          JS::SourceBufferHolder& aSrcBuf,
-                          void **aOffThreadToken);
+                          JS::SourceBufferHolder& aSrcBuf);
 
   already_AddRefed<nsIScriptGlobalObject> GetScriptGlobalObject();
   void FillCompileOptionsForRequest(const mozilla::dom::AutoJSAPI &jsapi,
                                     nsScriptLoadRequest *aRequest,
                                     JS::Handle<JSObject *> aScopeChain,
                                     JS::CompileOptions *aOptions);
 
   nsresult PrepareLoadedRequest(nsScriptLoadRequest* aRequest,
--- a/dom/base/nsStructuredCloneContainer.cpp
+++ b/dom/base/nsStructuredCloneContainer.cpp
@@ -8,170 +8,220 @@
 
 #include "nsCOMPtr.h"
 #include "nsIGlobalObject.h"
 #include "nsIVariant.h"
 #include "nsIXPConnect.h"
 #include "nsServiceManagerUtils.h"
 #include "nsContentUtils.h"
 #include "jsapi.h"
-#include "jsfriendapi.h"
-#include "js/StructuredClone.h"
 #include "xpcpublic.h"
 
 #include "mozilla/Base64.h"
+#include "mozilla/dom/StructuredCloneHelper.h"
 #include "mozilla/dom/ScriptSettings.h"
 
 using namespace mozilla;
+using namespace mozilla::dom;
 
 NS_IMPL_ADDREF(nsStructuredCloneContainer)
 NS_IMPL_RELEASE(nsStructuredCloneContainer)
 
 NS_INTERFACE_MAP_BEGIN(nsStructuredCloneContainer)
   NS_INTERFACE_MAP_ENTRY(nsIStructuredCloneContainer)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 nsStructuredCloneContainer::nsStructuredCloneContainer()
-  : mData(nullptr), mSize(0), mVersion(0)
+  : StructuredCloneHelper(CloningSupported, TransferringNotSupported)
+  , mState(eNotInitialized) , mData(nullptr), mSize(0), mVersion(0)
 {
 }
 
 nsStructuredCloneContainer::~nsStructuredCloneContainer()
 {
-  free(mData);
+  if (mData) {
+    free(mData);
+  }
 }
 
-nsresult
+NS_IMETHODIMP
 nsStructuredCloneContainer::InitFromJSVal(JS::Handle<JS::Value> aData,
                                           JSContext* aCx)
 {
-  NS_ENSURE_STATE(!mData);
-
-  uint64_t* jsBytes = nullptr;
-  bool success = JS_WriteStructuredClone(aCx, aData, &jsBytes, &mSize,
-                                           nullptr, nullptr,
-                                           JS::UndefinedHandleValue);
-  NS_ENSURE_STATE(success);
-  NS_ENSURE_STATE(jsBytes);
-
-  // Copy jsBytes into our own buffer.
-  mData = (uint64_t*) malloc(mSize);
-  if (!mData) {
-    mSize = 0;
-    mVersion = 0;
-
-    JS_ClearStructuredClone(jsBytes, mSize, nullptr, nullptr);
+  if (mState != eNotInitialized) {
     return NS_ERROR_FAILURE;
   }
-  else {
-    mVersion = JS_STRUCTURED_CLONE_VERSION;
+
+  ErrorResult rv;
+  Write(aCx, aData, rv);
+  if (NS_WARN_IF(rv.Failed())) {
+    return rv.StealNSResult();
   }
 
-  memcpy(mData, jsBytes, mSize);
-
-  JS_ClearStructuredClone(jsBytes, mSize, nullptr, nullptr);
+  mState = eInitializedFromJSVal;
   return NS_OK;
 }
 
-nsresult
+NS_IMETHODIMP
 nsStructuredCloneContainer::InitFromBase64(const nsAString &aData,
                                            uint32_t aFormatVersion,
-                                           JSContext *aCx)
+                                           JSContext* aCx)
 {
-  NS_ENSURE_STATE(!mData);
+  if (mState != eNotInitialized) {
+    return NS_ERROR_FAILURE;
+  }
 
   NS_ConvertUTF16toUTF8 data(aData);
 
   nsAutoCString binaryData;
   nsresult rv = Base64Decode(data, binaryData);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Copy the string's data into our own buffer.
   mData = (uint64_t*) malloc(binaryData.Length());
   NS_ENSURE_STATE(mData);
   memcpy(mData, binaryData.get(), binaryData.Length());
 
   mSize = binaryData.Length();
   mVersion = aFormatVersion;
+
+  mState = eInitializedFromBase64;
   return NS_OK;
 }
 
 nsresult
 nsStructuredCloneContainer::DeserializeToJsval(JSContext* aCx,
                                                JS::MutableHandle<JS::Value> aValue)
 {
   aValue.setNull();
   JS::Rooted<JS::Value> jsStateObj(aCx);
-  bool hasTransferable = false;
-  bool success = JS_ReadStructuredClone(aCx, mData, mSize, mVersion,
-                                        &jsStateObj, nullptr, nullptr) &&
-                 JS_StructuredCloneHasTransferables(mData, mSize,
-                                                    &hasTransferable);
-  // We want to be sure that mData doesn't contain transferable objects
-  MOZ_ASSERT(!hasTransferable);
-  NS_ENSURE_STATE(success && !hasTransferable);
+
+  if (mState == eInitializedFromJSVal) {
+    ErrorResult rv;
+    Read(nullptr, aCx, &jsStateObj, rv);
+    if (NS_WARN_IF(rv.Failed())) {
+      return rv.StealNSResult();
+    }
+  } else {
+    MOZ_ASSERT(mState == eInitializedFromBase64);
+    MOZ_ASSERT(mData);
+
+    ErrorResult rv;
+    ReadFromBuffer(nullptr, aCx, mData, mSize, mVersion, &jsStateObj, rv);
+    if (NS_WARN_IF(rv.Failed())) {
+      return rv.StealNSResult();
+    }
+  }
 
   aValue.set(jsStateObj);
   return NS_OK;
 }
 
-nsresult
-nsStructuredCloneContainer::DeserializeToVariant(JSContext *aCx,
-                                                 nsIVariant **aData)
+NS_IMETHODIMP
+nsStructuredCloneContainer::DeserializeToVariant(JSContext* aCx,
+                                                 nsIVariant** aData)
 {
-  NS_ENSURE_STATE(mData);
   NS_ENSURE_ARG_POINTER(aData);
   *aData = nullptr;
 
+  if (mState == eNotInitialized) {
+    return NS_ERROR_FAILURE;
+  }
+
   // Deserialize to a JS::Value.
   JS::Rooted<JS::Value> jsStateObj(aCx);
   nsresult rv = DeserializeToJsval(aCx, &jsStateObj);
-  NS_ENSURE_SUCCESS(rv, rv);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
 
   // Now wrap the JS::Value as an nsIVariant.
   nsCOMPtr<nsIVariant> varStateObj;
   nsCOMPtr<nsIXPConnect> xpconnect = do_GetService(nsIXPConnect::GetCID());
   NS_ENSURE_STATE(xpconnect);
   xpconnect->JSValToVariant(aCx, jsStateObj, getter_AddRefs(varStateObj));
   NS_ENSURE_STATE(varStateObj);
 
-  NS_ADDREF(*aData = varStateObj);
+  varStateObj.forget(aData);
   return NS_OK;
 }
 
-nsresult
+NS_IMETHODIMP
 nsStructuredCloneContainer::GetDataAsBase64(nsAString &aOut)
 {
-  NS_ENSURE_STATE(mData);
   aOut.Truncate();
 
-  nsAutoCString binaryData(reinterpret_cast<char*>(mData), mSize);
+  if (mState == eNotInitialized) {
+    return NS_ERROR_FAILURE;
+  }
+
+  uint64_t* data;
+  size_t size;
+
+  if (mState == eInitializedFromJSVal) {
+    if (HasClonedDOMObjects()) {
+      return NS_ERROR_FAILURE;
+    }
+
+    data = BufferData();
+    size = BufferSize();
+  } else {
+    MOZ_ASSERT(mState == eInitializedFromBase64);
+    MOZ_ASSERT(mData);
+
+    data = mData;
+    size = mSize;
+  }
+
+  nsAutoCString binaryData(reinterpret_cast<char*>(data), size);
   nsAutoCString base64Data;
   nsresult rv = Base64Encode(binaryData, base64Data);
-  NS_ENSURE_SUCCESS(rv, rv);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
 
-  aOut.Assign(NS_ConvertASCIItoUTF16(base64Data));
+  CopyASCIItoUTF16(base64Data, aOut);
   return NS_OK;
 }
 
-nsresult
-nsStructuredCloneContainer::GetSerializedNBytes(uint64_t *aSize)
+NS_IMETHODIMP
+nsStructuredCloneContainer::GetSerializedNBytes(uint64_t* aSize)
 {
-  NS_ENSURE_STATE(mData);
   NS_ENSURE_ARG_POINTER(aSize);
 
+  if (mState == eNotInitialized) {
+    return NS_ERROR_FAILURE;
+  }
+
+  if (mState == eInitializedFromJSVal) {
+    *aSize = BufferSize();
+    return NS_OK;
+  }
+
+  MOZ_ASSERT(mState == eInitializedFromBase64);
+
   // mSize is a size_t, while aSize is a uint64_t.  We rely on an implicit cast
   // here so that we'll get a compile error if a size_t-to-uint64_t cast is
   // narrowing.
   *aSize = mSize;
 
   return NS_OK;
 }
 
-nsresult
-nsStructuredCloneContainer::GetFormatVersion(uint32_t *aFormatVersion)
+NS_IMETHODIMP
+nsStructuredCloneContainer::GetFormatVersion(uint32_t* aFormatVersion)
 {
-  NS_ENSURE_STATE(mData);
   NS_ENSURE_ARG_POINTER(aFormatVersion);
+
+  if (mState == eNotInitialized) {
+    return NS_ERROR_FAILURE;
+  }
+
+  if (mState == eInitializedFromJSVal) {
+    *aFormatVersion = JS_STRUCTURED_CLONE_VERSION;
+    return NS_OK;
+  }
+
+  MOZ_ASSERT(mState == eInitializedFromBase64);
   *aFormatVersion = mVersion;
   return NS_OK;
 }
--- a/dom/base/nsStructuredCloneContainer.h
+++ b/dom/base/nsStructuredCloneContainer.h
@@ -4,38 +4,47 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsStructuredCloneContainer_h__
 #define nsStructuredCloneContainer_h__
 
 #include "nsIStructuredCloneContainer.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/dom/StructuredCloneHelper.h"
 
 #define NS_STRUCTUREDCLONECONTAINER_CONTRACTID \
   "@mozilla.org/docshell/structured-clone-container;1"
 #define NS_STRUCTUREDCLONECONTAINER_CID \
 { /* 38bd0634-0fd4-46f0-b85f-13ced889eeec */       \
   0x38bd0634,                                      \
   0x0fd4,                                          \
   0x46f0,                                          \
   {0xb8, 0x5f, 0x13, 0xce, 0xd8, 0x89, 0xee, 0xec} \
 }
 
-class nsStructuredCloneContainer final : public nsIStructuredCloneContainer
+class nsStructuredCloneContainer final
+  : public nsIStructuredCloneContainer
+  , public mozilla::dom::StructuredCloneHelper
 {
   public:
     nsStructuredCloneContainer();
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSISTRUCTUREDCLONECONTAINER
 
   private:
     ~nsStructuredCloneContainer();
 
+    enum {
+      eNotInitialized = 0,
+      eInitializedFromJSVal,
+      eInitializedFromBase64,
+    } mState;
+
     uint64_t* mData;
 
     // This needs to be size_t rather than a PR-type so it matches the JS API.
     size_t mSize;
     uint32_t mVersion;
 };
 
 #endif
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -735,29 +735,31 @@ skip-if = buildapp == 'b2g' || buildapp 
 [test_html_colors_quirks.html]
 [test_html_colors_standards.html]
 [test_html_in_xhr.html]
 [test_htmlcopyencoder.html]
 [test_htmlcopyencoder.xhtml]
 [test_ipc_messagemanager_blob.html]
 skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 936226
 [test_meta_viewport0.html]
-skip-if = buildapp != 'b2g'     # meta-viewport tag support is only on b2g
+skip-if = (os != 'b2g' && os != 'android')    # meta-viewport tag support is mobile-only
 [test_meta_viewport1.html]
-skip-if = buildapp != 'b2g'     # meta-viewport tag support is only on b2g
+skip-if = (os != 'b2g' && os != 'android')    # meta-viewport tag support is mobile-only
 [test_meta_viewport2.html]
-skip-if = buildapp != 'b2g'     # meta-viewport tag support is only on b2g
+skip-if = (os != 'b2g' && os != 'android')    # meta-viewport tag support is mobile-only
 [test_meta_viewport3.html]
-skip-if = buildapp != 'b2g'     # meta-viewport tag support is only on b2g
+skip-if = (os != 'b2g' && os != 'android')    # meta-viewport tag support is mobile-only
 [test_meta_viewport4.html]
-skip-if = buildapp != 'b2g'     # meta-viewport tag support is only on b2g
+skip-if = (os != 'b2g' && os != 'android')    # meta-viewport tag support is mobile-only
 [test_meta_viewport5.html]
-skip-if = buildapp != 'b2g'     # meta-viewport tag support is only on b2g
+skip-if = (os != 'b2g' && os != 'android')    # meta-viewport tag support is mobile-only
 [test_meta_viewport6.html]
-skip-if = buildapp != 'b2g'     # meta-viewport tag support is only on b2g
+skip-if = (os != 'b2g' && os != 'android')    # meta-viewport tag support is mobile-only
+[test_meta_viewport7.html]
+skip-if = (os != 'b2g' && os != 'android')    # meta-viewport tag support is mobile-only
 [test_mozfiledataurl.html]
 skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || e10s #TIMED_OUT
 [test_mozMatchesSelector.html]
 [test_mutationobservers.html]
 skip-if = buildapp == 'b2g' || e10s # b2g(bug 901385, showmodaldialog) b2g-debug(bug 901385, showmodaldialog) b2g-desktop(bug 901385, showmodaldialog)
 [test_nodelist_holes.html]
 [test_object.html]
 skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || e10s # b2g(needs plugin support) b2g-debug(needs plugin support) b2g-desktop(needs plugin support)
new file mode 100644
--- /dev/null
+++ b/dom/base/test/test_meta_viewport7.html
@@ -0,0 +1,114 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>meta viewport test</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <meta name="viewport" content="width=320">
+  <script src="viewport_helpers.js"></script>
+</head>
+<body>
+  <p>Dynamic viewport updates</p>
+  <script type="application/javascript;version=1.7">
+    "use strict";
+
+    SimpleTest.waitForExplicitFinish();
+
+    let tests = [];
+
+    tests.push(function test1() {
+      SpecialPowers.pushPrefEnv(scaleRatio(1.0),
+        function() {
+          updateViewport("width=device-width");
+          let info = getViewportInfo(800, 480);
+          is(info.defaultZoom, 1,    "initial zoom is 100%");
+          is(info.width,       800,  "width is the same as the displayWidth");
+          is(info.height,      480,  "height is the same as the displayHeight");
+          is(info.autoSize,    true, "width=device-width enables autoSize");
+          is(info.allowZoom,   true, "zooming is enabled by default");
+
+          info = getViewportInfo(900, 600);
+          is(info.width,       900,  "changing the displayWidth changes the width");
+          is(info.height,      600,  "changing the displayHeight changes the height");
+
+          nextTest();
+        });
+    });
+
+    tests.push(function test2() {
+      SpecialPowers.pushPrefEnv(scaleRatio(1.0),
+        function() {
+          updateViewport("width=320");
+          let info = getViewportInfo(800, 80);
+          is(info.defaultZoom, 2.5,   "initial zoom fits the displayWidth");
+          is(info.width,       320,   "width is set explicitly");
+          is(info.height,      40,   "height is at the absolute minimum");
+          is(info.autoSize,    false, "width=device-width enables autoSize");
+          is(info.allowZoom,   true,  "zooming is enabled by default");
+
+          info = getViewportInfo(480, 800);
+          is(info.defaultZoom, 1.5,   "initial zoom fits the new displayWidth");
+          is(info.width,       320,   "explicit width is unchanged");
+          is(info.height,      533,   "height changes proportional to displayHeight");
+
+          nextTest();
+        });
+    });
+
+    tests.push(function test3() {
+      SpecialPowers.pushPrefEnv(scaleRatio(1.0),
+        function() {
+          updateViewport("user-scalable=no");
+          let info = getViewportInfo(800, 480);
+          is(info.allowZoom,   false, "zooming is explicitly disabled");
+
+          nextTest();
+        });
+    });
+
+    tests.push(function test4() {
+      SpecialPowers.pushPrefEnv(scaleRatio(1.0),
+        function() {
+          updateViewport("user-scalable=yes");
+          let info = getViewportInfo(800, 480);
+          is(info.allowZoom,   true,  "zooming is explicitly allowed");
+
+          nextTest();
+        });
+    });
+
+    function getViewportInfo(aDisplayWidth, aDisplayHeight) {
+      let defaultZoom = {}, allowZoom = {}, minZoom = {}, maxZoom = {},
+          width = {}, height = {}, autoSize = {};
+
+      let cwu = SpecialPowers.getDOMWindowUtils(window);
+      cwu.getViewportInfo(aDisplayWidth, aDisplayHeight, defaultZoom, allowZoom,
+                          minZoom, maxZoom, width, height, autoSize);
+      return {
+        defaultZoom: defaultZoom.value,
+        minZoom: minZoom.value,
+        maxZoom: maxZoom.value,
+        width: width.value,
+        height: height.value,
+        autoSize: autoSize.value,
+        allowZoom: allowZoom.value
+      };
+    }
+
+    function updateViewport(content) {
+      let meta = document.querySelector("meta[name=viewport]");
+      meta.content = content;
+    }
+
+    function nextTest() {
+      if (tests.length) {
+        (tests.shift())();
+      } else {
+        SimpleTest.finish();
+      }
+    }
+    addEventListener("load", nextTest);
+  </script>
+</body>
+</html>
--- a/dom/bindings/Errors.msg
+++ b/dom/bindings/Errors.msg
@@ -46,16 +46,17 @@ MSG_DEF(MSG_DOM_DECODING_FAILED, 0, JSEX
 MSG_DEF(MSG_NOT_FINITE, 1, JSEXN_TYPEERR, "{0} is not a finite floating-point value.")
 MSG_DEF(MSG_INVALID_VERSION, 0, JSEXN_TYPEERR, "0 (Zero) is not a valid database version.")
 MSG_DEF(MSG_INVALID_BYTESTRING, 2, JSEXN_TYPEERR, "Cannot convert string to ByteString because the character"
         " at index {0} has value {1} which is greater than 255.")
 MSG_DEF(MSG_NOT_DATE, 1, JSEXN_TYPEERR, "{0} is not a date.")
 MSG_DEF(MSG_INVALID_ADVANCE_COUNT, 0, JSEXN_TYPEERR, "0 (Zero) is not a valid advance count.")
 MSG_DEF(MSG_DEFINEPROPERTY_ON_GSP, 0, JSEXN_TYPEERR, "Not allowed to define a property on the named properties object.")
 MSG_DEF(MSG_INVALID_URL, 1, JSEXN_TYPEERR, "{0} is not a valid URL.")
+MSG_DEF(MSG_URL_HAS_CREDENTIALS, 1, JSEXN_TYPEERR, "{0} is an url with embedded credentials.")
 MSG_DEF(MSG_METADATA_NOT_CONFIGURED, 0, JSEXN_TYPEERR, "Either size or lastModified should be true.")
 MSG_DEF(MSG_INVALID_READ_SIZE, 0, JSEXN_TYPEERR, "0 (Zero) is not a valid read size.")
 MSG_DEF(MSG_HEADERS_IMMUTABLE, 0, JSEXN_TYPEERR, "Headers are immutable and cannot be modified.")
 MSG_DEF(MSG_INVALID_HEADER_NAME, 1, JSEXN_TYPEERR, "{0} is an invalid header name.")
 MSG_DEF(MSG_INVALID_HEADER_VALUE, 1, JSEXN_TYPEERR, "{0} is an invalid header value.")
 MSG_DEF(MSG_INVALID_HEADER_SEQUENCE, 0, JSEXN_TYPEERR, "Headers require name/value tuples when being initialized by a sequence.")
 MSG_DEF(MSG_PERMISSION_DENIED_TO_PASS_ARG, 1, JSEXN_TYPEERR, "Permission denied to pass cross-origin object as {0}.")
 MSG_DEF(MSG_MISSING_REQUIRED_DICTIONARY_MEMBER, 1, JSEXN_TYPEERR, "Missing required {0}.")
--- a/dom/camera/CameraCommon.h
+++ b/dom/camera/CameraCommon.h
@@ -2,24 +2,16 @@
 /* vim: set ts=2 et sw=2 tw=40: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef DOM_CAMERA_CAMERACOMMON_H
 #define DOM_CAMERA_CAMERACOMMON_H
 
-#ifndef __func__
-#ifdef __FUNCTION__
-#define __func__ __FUNCTION__
-#else
-#define __func__ __FILE__
-#endif
-#endif
-
 #include "mozilla/Logging.h"
 
 extern PRLogModuleInfo* GetCameraLog();
 #define DOM_CAMERA_LOG( type, ... ) MOZ_LOG(GetCameraLog(), (mozilla::LogLevel)type, ( __VA_ARGS__ ))
 
 #define DOM_CAMERA_LOGA( ... )      DOM_CAMERA_LOG( mozilla::LogLevel::Error, __VA_ARGS__ )
 
 /**
--- a/dom/canvas/compiledtest/moz.build
+++ b/dom/canvas/compiledtest/moz.build
@@ -3,13 +3,16 @@
 # 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/.
 
 GeckoCppUnitTests([
     'TestWebGLElementArrayCache',
 ])
 
+if CONFIG['GNU_CXX']:
+    CXXFLAGS += ['-Wshadow']
+
 FAIL_ON_WARNINGS = True
 
 LOCAL_INCLUDES += [
     '../',
 ]
--- a/dom/devicestorage/nsDeviceStorage.h
+++ b/dom/devicestorage/nsDeviceStorage.h
@@ -4,16 +4,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/. */
 
 #ifndef nsDeviceStorage_h
 #define nsDeviceStorage_h
 
 class nsPIDOMWindow;
 #include "mozilla/Attributes.h"
+#include "mozilla/Logging.h"
 #include "mozilla/dom/devicestorage/DeviceStorageRequestChild.h"
 
 #include "DOMRequest.h"
 #include "DOMCursor.h"
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsDOMClassInfoID.h"
 #include "nsIClassInfo.h"
@@ -37,21 +38,16 @@ class ErrorResult;
 namespace dom {
 class Blob;
 } // namespace dom
 } // namespace mozilla
 
 //#define DS_LOGGING 1
 
 #ifdef DS_LOGGING
-/* Polyfill __func__ on MSVC to pass to the log. */
-#ifdef _MSC_VER
-#define __func__ __FUNCTION__
-#endif
-
 #define DS_LOG_DEBUG(msg, ...)  printf_stderr("[%s:%d] " msg "\n", __func__, __LINE__, ##__VA_ARGS__)
 #define DS_LOG_INFO DS_LOG_DEBUG
 #define DS_LOG_WARN DS_LOG_DEBUG
 #define DS_LOG_ERROR DS_LOG_DEBUG
 #else
 #define DS_LOG_DEBUG(msg, ...)
 #define DS_LOG_INFO(msg, ...)
 #define DS_LOG_WARN(msg, ...)
--- a/dom/events/AnimationEvent.cpp
+++ b/dom/events/AnimationEvent.cpp
@@ -10,17 +10,17 @@
 
 namespace mozilla {
 namespace dom {
 
 AnimationEvent::AnimationEvent(EventTarget* aOwner,
                                nsPresContext* aPresContext,
                                InternalAnimationEvent* aEvent)
   : Event(aOwner, aPresContext,
-          aEvent ? aEvent : new InternalAnimationEvent(false, 0))
+          aEvent ? aEvent : new InternalAnimationEvent(false, NS_EVENT_NULL))
 {
   if (aEvent) {
     mEventIsInternal = false;
   }
   else {
     mEventIsInternal = true;
     mEvent->time = PR_Now();
   }
--- a/dom/events/BeforeAfterKeyboardEvent.cpp
+++ b/dom/events/BeforeAfterKeyboardEvent.cpp
@@ -12,17 +12,18 @@ namespace mozilla {
 namespace dom {
 
 BeforeAfterKeyboardEvent::BeforeAfterKeyboardEvent(
                                        EventTarget* aOwner,
                                        nsPresContext* aPresContext,
                                        InternalBeforeAfterKeyboardEvent* aEvent)
   : KeyboardEvent(aOwner, aPresContext,
                   aEvent ? aEvent :
-                           new InternalBeforeAfterKeyboardEvent(false, 0,
+                           new InternalBeforeAfterKeyboardEvent(false,
+                                                                NS_EVENT_NULL,
                                                                 nullptr))
 {
   MOZ_ASSERT(mEvent->mClass == eBeforeAfterKeyboardEventClass,
              "event type mismatch eBeforeAfterKeyboardEventClass");
 
   if (!aEvent) {
     mEventIsInternal = true;
     mEvent->time = PR_Now();
--- a/dom/events/ClipboardEvent.cpp
+++ b/dom/events/ClipboardEvent.cpp
@@ -11,17 +11,17 @@
 
 namespace mozilla {
 namespace dom {
 
 ClipboardEvent::ClipboardEvent(EventTarget* aOwner,
                                nsPresContext* aPresContext,
                                InternalClipboardEvent* aEvent)
   : Event(aOwner, aPresContext,
-          aEvent ? aEvent : new InternalClipboardEvent(false, 0))
+          aEvent ? aEvent : new InternalClipboardEvent(false, NS_EVENT_NULL))
 {
   if (aEvent) {
     mEventIsInternal = false;
   } else {
     mEventIsInternal = true;
     mEvent->time = PR_Now();
   }
 }
--- a/dom/events/CompositionEvent.cpp
+++ b/dom/events/CompositionEvent.cpp
@@ -10,17 +10,18 @@
 
 namespace mozilla {
 namespace dom {
 
 CompositionEvent::CompositionEvent(EventTarget* aOwner,
                                    nsPresContext* aPresContext,
                                    WidgetCompositionEvent* aEvent)
   : UIEvent(aOwner, aPresContext,
-            aEvent ? aEvent : new WidgetCompositionEvent(false, 0, nullptr))
+            aEvent ? aEvent :
+                     new WidgetCompositionEvent(false, NS_EVENT_NULL, nullptr))
 {
   NS_ASSERTION(mEvent->mClass == eCompositionEventClass,
                "event type mismatch");
 
   if (aEvent) {
     mEventIsInternal = false;
   } else {
     mEventIsInternal = true;
--- a/dom/events/DataTransfer.cpp
+++ b/dom/events/DataTransfer.cpp
@@ -150,19 +150,19 @@ DataTransfer::Constructor(const GlobalOb
   nsAutoCString onEventType("on");
   AppendUTF16toUTF8(aEventType, onEventType);
   nsCOMPtr<nsIAtom> eventTypeAtom = do_GetAtom(onEventType);
   if (!eventTypeAtom) {
     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     return nullptr;
   }
 
-  uint32_t eventType = nsContentUtils::GetEventId(eventTypeAtom);
+  EventMessage eventMessage = nsContentUtils::GetEventMessage(eventTypeAtom);
   nsRefPtr<DataTransfer> transfer = new DataTransfer(aGlobal.GetAsSupports(),
-                                                     eventType, aIsExternal,
+                                                     eventMessage, aIsExternal,
                                                      -1);
   return transfer.forget();
 }
 
 JSObject*
 DataTransfer::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return DataTransferBinding::Wrap(aCx, this, aGivenProto);
--- a/dom/events/DragEvent.cpp
+++ b/dom/events/DragEvent.cpp
@@ -11,17 +11,18 @@
 
 namespace mozilla {
 namespace dom {
 
 DragEvent::DragEvent(EventTarget* aOwner,
                      nsPresContext* aPresContext,
                      WidgetDragEvent* aEvent)
   : MouseEvent(aOwner, aPresContext,
-               aEvent ? aEvent : new WidgetDragEvent(false, 0, nullptr))
+               aEvent ? aEvent :
+                        new WidgetDragEvent(false, NS_EVENT_NULL, nullptr))
 {
   if (aEvent) {
     mEventIsInternal = false;
   }
   else {
     mEventIsInternal = true;
     mEvent->time = PR_Now();
     mEvent->refPoint.x = mEvent->refPoint.y = 0;
--- a/dom/events/Event.cpp
+++ b/dom/events/Event.cpp
@@ -101,17 +101,17 @@ Event::ConstructorInit(EventTarget* aOwn
             mEventIsInternal = false;
           }
           else {
             mEventIsInternal = true;
           }
           ...
         }
      */
-    mEvent = new WidgetEvent(false, 0);
+    mEvent = new WidgetEvent(false, NS_EVENT_NULL);
     mEvent->time = PR_Now();
   }
 
   InitPresContextData(aPresContext);
 }
 
 void
 Event::InitPresContextData(nsPresContext* aPresContext)
@@ -558,18 +558,18 @@ Event::PreventDefaultInternal(bool aCall
 }
 
 void
 Event::SetEventType(const nsAString& aEventTypeArg)
 {
   if (mIsMainThreadEvent) {
     mEvent->typeString.Truncate();
     mEvent->userType =
-      nsContentUtils::GetEventIdAndAtom(aEventTypeArg, mEvent->mClass,
-                                        &(mEvent->mMessage));
+      nsContentUtils::GetEventMessageAndAtom(aEventTypeArg, mEvent->mClass,
+                                             &(mEvent->mMessage));
   } else {
     mEvent->userType = nullptr;
     mEvent->mMessage = NS_USER_DEFINED_EVENT;
     mEvent->typeString = aEventTypeArg;
   }
 }
 
 NS_IMETHODIMP
@@ -721,30 +721,34 @@ Event::GetEventPopupControlState(WidgetE
           abuse = openControlled;
         }
         break;
       case NS_FORM_CHANGE :
         if (PopupAllowedForEvent("change")) {
           abuse = openControlled;
         }
         break;
+      default:
+        break;
       }
     }
     break;
   case eEditorInputEventClass:
     // For this following event only allow popups if it's triggered
     // while handling user input. See
     // nsPresShell::HandleEventInternal() for details.
     if (EventStateManager::IsHandlingUserInput()) {
       switch(aEvent->mMessage) {
       case NS_EDITOR_INPUT:
         if (PopupAllowedForEvent("input")) {
           abuse = openControlled;
         }
         break;
+      default:
+        break;
       }
     }
     break;
   case eInputEventClass:
     // For this following event only allow popups if it's triggered
     // while handling user input. See
     // nsPresShell::HandleEventInternal() for details.
     if (EventStateManager::IsHandlingUserInput()) {
@@ -752,16 +756,18 @@ Event::GetEventPopupControlState(WidgetE
       case NS_FORM_CHANGE :
         if (PopupAllowedForEvent("change")) {
           abuse = openControlled;
         }
         break;
       case NS_XUL_COMMAND:
         abuse = openControlled;
         break;
+      default:
+        break;
       }
     }
     break;
   case eKeyboardEventClass:
     if (aEvent->mFlags.mIsTrusted) {
       uint32_t key = aEvent->AsKeyboardEvent()->keyCode;
       switch(aEvent->mMessage) {
       case NS_KEY_PRESS :
@@ -780,32 +786,36 @@ Event::GetEventPopupControlState(WidgetE
           abuse = openControlled;
         }
         break;
       case NS_KEY_DOWN :
         if (PopupAllowedForEvent("keydown")) {
           abuse = openControlled;
         }
         break;
+      default:
+        break;
       }
     }
     break;
   case eTouchEventClass:
     if (aEvent->mFlags.mIsTrusted) {
       switch (aEvent->mMessage) {
       case NS_TOUCH_START :
         if (PopupAllowedForEvent("touchstart")) {
           abuse = openControlled;
         }
         break;
       case NS_TOUCH_END :
         if (PopupAllowedForEvent("touchend")) {
           abuse = openControlled;
         }
         break;
+      default:
+        break;
       }
     }
     break;
   case eMouseEventClass:
     if (aEvent->mFlags.mIsTrusted &&
         aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) {
       switch(aEvent->mMessage) {
       case NS_MOUSE_BUTTON_UP :
@@ -827,16 +837,18 @@ Event::GetEventPopupControlState(WidgetE
           abuse = openAllowed;
         }
         break;
       case NS_MOUSE_DOUBLECLICK :
         if (PopupAllowedForEvent("dblclick")) {
           abuse = openControlled;
         }
         break;
+      default:
+        break;
       }
     }
     break;
   case eFormEventClass:
     // For these following events only allow popups if they're
     // triggered while handling user input. See
     // nsPresShell::HandleEventInternal() for details.
     if (EventStateManager::IsHandlingUserInput()) {
@@ -846,16 +858,18 @@ Event::GetEventPopupControlState(WidgetE
           abuse = openControlled;
         }
         break;
       case NS_FORM_RESET :
         if (PopupAllowedForEvent("reset")) {
           abuse = openControlled;
         }
         break;
+      default:
+        break;
       }
     }
     break;
   default:
     break;
   }
 
   return abuse;
@@ -1021,23 +1035,23 @@ Event::GetOffsetCoords(nsPresContext* aP
   }
   return CSSIntPoint(0, 0);
 }
 
 // To be called ONLY by Event::GetType (which has the additional
 // logic for handling user-defined events).
 // static
 const char*
-Event::GetEventName(uint32_t aEventType)
+Event::GetEventName(EventMessage aEventType)
 {
   switch(aEventType) {
-#define ID_TO_EVENT(name_, _id, _type, _struct) \
-  case _id: return #name_;
+#define MESSAGE_TO_EVENT(name_, _message, _type, _struct) \
+  case _message: return #name_;
 #include "mozilla/EventNameList.h"
-#undef ID_TO_EVENT
+#undef MESSAGE_TO_EVENT
   default:
     break;
   }
   // XXXldb We can hit this case for WidgetEvent objects that we didn't
   // create and that are not user defined events since this function and
   // SetEventType are incomplete.  (But fixing that requires fixing the
   // arrays in nsEventListenerManager too, since the events for which
   // this is a problem generally *are* created by Event.)
--- a/dom/events/Event.h
+++ b/dom/events/Event.h
@@ -119,17 +119,17 @@ public:
 
   static PopupControlState GetEventPopupControlState(WidgetEvent* aEvent,
                                                      nsIDOMEvent* aDOMEvent = nullptr);
 
   static void PopupAllowedEventsChanged();
 
   static void Shutdown();
 
-  static const char* GetEventName(uint32_t aEventType);
+  static const char* GetEventName(EventMessage aEventType);
   static CSSIntPoint GetClientCoords(nsPresContext* aPresContext,
                                      WidgetEvent* aEvent,
                                      LayoutDeviceIntPoint aPoint,
                                      CSSIntPoint aDefaultPoint);
   static CSSIntPoint GetPageCoords(nsPresContext* aPresContext,
                                    WidgetEvent* aEvent,
                                    LayoutDeviceIntPoint aPoint,
                                    CSSIntPoint aDefaultPoint);
--- a/dom/events/EventListenerManager.cpp
+++ b/dom/events/EventListenerManager.cpp
@@ -47,34 +47,34 @@
 #include "nsSandboxFlags.h"
 #include "xpcpublic.h"
 
 namespace mozilla {
 
 using namespace dom;
 using namespace hal;
 
-#define EVENT_TYPE_EQUALS(ls, type, userType, typeString, allEvents) \
-  ((ls->mEventType == type &&                                        \
-    (ls->mEventType != NS_USER_DEFINED_EVENT ||                      \
-    (mIsMainThreadELM && ls->mTypeAtom == userType) ||               \
-    (!mIsMainThreadELM && ls->mTypeString.Equals(typeString)))) ||   \
+#define EVENT_TYPE_EQUALS(ls, message, userType, typeString, allEvents) \
+  ((ls->mEventMessage == message &&                                     \
+    (ls->mEventMessage != NS_USER_DEFINED_EVENT ||                      \
+    (mIsMainThreadELM && ls->mTypeAtom == userType) ||                  \
+    (!mIsMainThreadELM && ls->mTypeString.Equals(typeString)))) ||      \
    (allEvents && ls->mAllEvents))
 
 static const uint32_t kAllMutationBits =
   NS_EVENT_BITS_MUTATION_SUBTREEMODIFIED |
   NS_EVENT_BITS_MUTATION_NODEINSERTED |
   NS_EVENT_BITS_MUTATION_NODEREMOVED |
   NS_EVENT_BITS_MUTATION_NODEREMOVEDFROMDOCUMENT |
   NS_EVENT_BITS_MUTATION_NODEINSERTEDINTODOCUMENT |
   NS_EVENT_BITS_MUTATION_ATTRMODIFIED |
   NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED;
 
 static uint32_t
-MutationBitForEventType(uint32_t aEventType)
+MutationBitForEventType(EventMessage aEventType)
 {
   switch (aEventType) {
     case NS_MUTATION_SUBTREEMODIFIED:
       return NS_EVENT_BITS_MUTATION_SUBTREEMODIFIED;
     case NS_MUTATION_NODEINSERTED:
       return NS_EVENT_BITS_MUTATION_NODEINSERTED;
     case NS_MUTATION_NODEREMOVED:
       return NS_EVENT_BITS_MUTATION_NODEREMOVED;
@@ -89,29 +89,36 @@ MutationBitForEventType(uint32_t aEventT
     default:
       break;
   }
   return 0;
 }
 
 uint32_t EventListenerManager::sMainThreadCreatedCount = 0;
 
-EventListenerManager::EventListenerManager(EventTarget* aTarget)
-  : mMayHavePaintEventListener(false)
+EventListenerManagerBase::EventListenerManagerBase()
+  : mNoListenerForEvent(NS_EVENT_NULL)
+  , mMayHavePaintEventListener(false)
   , mMayHaveMutationListeners(false)
   , mMayHaveCapturingListeners(false)
   , mMayHaveSystemGroupListeners(false)
   , mMayHaveTouchEventListener(false)
   , mMayHaveMouseEnterLeaveEventListener(false)
   , mMayHavePointerEnterLeaveEventListener(false)
   , mMayHaveKeyEventListener(false)
   , mMayHaveInputOrCompositionEventListener(false)
   , mClearingListeners(false)
   , mIsMainThreadELM(NS_IsMainThread())
-  , mNoListenerForEvent(0)
+{
+  static_assert(sizeof(EventListenerManagerBase) == sizeof(uint32_t),
+                "Keep the size of EventListenerManagerBase size compact!");
+}
+
+EventListenerManager::EventListenerManager(EventTarget* aTarget)
+  : EventListenerManagerBase()
   , mTarget(aTarget)
 {
   NS_ASSERTION(aTarget, "unexpected null pointer");
 
   if (mIsMainThreadELM) {
     ++sMainThreadCreatedCount;
   }
 }
@@ -210,25 +217,27 @@ EventListenerManager::GetTargetAsInnerWi
 
   NS_ASSERTION(window->IsInnerWindow(), "Target should not be an outer window");
   return window.forget();
 }
 
 void
 EventListenerManager::AddEventListenerInternal(
                         const EventListenerHolder& aListenerHolder,
-                        uint32_t aType,
+                        EventMessage aEventMessage,
                         nsIAtom* aTypeAtom,
                         const nsAString& aTypeString,
                         const EventListenerFlags& aFlags,
                         bool aHandler,
                         bool aAllEvents)
 {
-  MOZ_ASSERT((NS_IsMainThread() && aType && aTypeAtom) || // Main thread
-             (!NS_IsMainThread() && aType && !aTypeString.IsEmpty()) || // non-main-thread
+  MOZ_ASSERT(// Main thread
+             (NS_IsMainThread() && aEventMessage && aTypeAtom) ||
+             // non-main-thread
+             (!NS_IsMainThread() && aEventMessage && !aTypeString.IsEmpty()) ||
              aAllEvents, "Missing type"); // all-events listener
 
   if (!aListenerHolder || mClearingListeners) {
     return;
   }
 
   // Since there is no public API to call us with an EventListenerHolder, we
   // know that there's an EventListenerHolder on the stack holding a strong ref
@@ -236,31 +245,30 @@ EventListenerManager::AddEventListenerIn
 
   Listener* listener;
   uint32_t count = mListeners.Length();
   for (uint32_t i = 0; i < count; i++) {
     listener = &mListeners.ElementAt(i);
     // mListener == aListenerHolder is the last one, since it can be a bit slow.
     if (listener->mListenerIsHandler == aHandler &&
         listener->mFlags == aFlags &&
-        EVENT_TYPE_EQUALS(listener, aType, aTypeAtom, aTypeString,
+        EVENT_TYPE_EQUALS(listener, aEventMessage, aTypeAtom, aTypeString,
                           aAllEvents) &&
         listener->mListener == aListenerHolder) {
       return;
     }
   }
 
   mNoListenerForEvent = NS_EVENT_NULL;
   mNoListenerForEventAtom = nullptr;
 
   listener = aAllEvents ? mListeners.InsertElementAt(0) :
                           mListeners.AppendElement();
   listener->mListener = aListenerHolder;
-  MOZ_ASSERT(aType < PR_UINT16_MAX);
-  listener->mEventType = aType;
+  listener->mEventMessage = aEventMessage;
   listener->mTypeString = aTypeString;
   listener->mTypeAtom = aTypeAtom;
   listener->mFlags = aFlags;
   listener->mListenerIsHandler = aHandler;
   listener->mHandlerIsString = false;
   listener->mAllEvents = aAllEvents;
 
   // Detect the type of event listener.
@@ -279,38 +287,39 @@ EventListenerManager::AddEventListenerIn
 
   if (aFlags.mInSystemGroup) {
     mMayHaveSystemGroupListeners = true;
   }
   if (aFlags.mCapture) {
     mMayHaveCapturingListeners = true;
   }
 
-  if (aType == NS_AFTERPAINT) {
+  if (aEventMessage == NS_AFTERPAINT) {
     mMayHavePaintEventListener = true;
     nsPIDOMWindow* window = GetInnerWindowForTarget();
     if (window) {
       window->SetHasPaintEventListeners();
     }
-  } else if (aType >= NS_MUTATION_START && aType <= NS_MUTATION_END) {
+  } else if (aEventMessage >= NS_MUTATION_START &&
+             aEventMessage <= NS_MUTATION_END) {
     // For mutation listeners, we need to update the global bit on the DOM window.
     // Otherwise we won't actually fire the mutation event.
     mMayHaveMutationListeners = true;
     // Go from our target to the nearest enclosing DOM window.
     nsPIDOMWindow* window = GetInnerWindowForTarget();
     if (window) {
       nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
       if (doc) {
         doc->WarnOnceAbout(nsIDocument::eMutationEvent);
       }
-      // If aType is NS_MUTATION_SUBTREEMODIFIED, we need to listen all
+      // If aEventMessage is NS_MUTATION_SUBTREEMODIFIED, we need to listen all
       // mutations. nsContentUtils::HasMutationListeners relies on this.
-      window->SetMutationListeners((aType == NS_MUTATION_SUBTREEMODIFIED) ?
-                                   kAllMutationBits :
-                                   MutationBitForEventType(aType));
+      window->SetMutationListeners(
+        (aEventMessage == NS_MUTATION_SUBTREEMODIFIED) ?
+          kAllMutationBits : MutationBitForEventType(aEventMessage));
     }
   } else if (aTypeAtom == nsGkAtoms::ondeviceorientation) {
     EnableDevice(NS_DEVICE_ORIENTATION);
   } else if (aTypeAtom == nsGkAtoms::ondeviceproximity || aTypeAtom == nsGkAtoms::onuserproximity) {
     EnableDevice(NS_DEVICE_PROXIMITY);
   } else if (aTypeAtom == nsGkAtoms::ondevicelight) {
     EnableDevice(NS_DEVICE_LIGHT);
   } else if (aTypeAtom == nsGkAtoms::ondevicemotion) {
@@ -338,17 +347,18 @@ EventListenerManager::AddEventListenerIn
              aTypeAtom == nsGkAtoms::ontouchcancel) {
     mMayHaveTouchEventListener = true;
     nsPIDOMWindow* window = GetInnerWindowForTarget();
     // we don't want touchevent listeners added by scrollbars to flip this flag
     // so we ignore listeners created with system event flag
     if (window && !aFlags.mInSystemGroup) {
       window->SetHasTouchEventListeners();
     }
-  } else if (aType >= NS_POINTER_EVENT_START && aType <= NS_POINTER_LOST_CAPTURE) {
+  } else if (aEventMessage >= NS_POINTER_EVENT_START &&
+             aEventMessage <= NS_POINTER_LOST_CAPTURE) {
     nsPIDOMWindow* window = GetInnerWindowForTarget();
     if (aTypeAtom == nsGkAtoms::onpointerenter ||
         aTypeAtom == nsGkAtoms::onpointerleave) {
       mMayHavePointerEnterLeaveEventListener = true;
       if (window) {
 #ifdef DEBUG
         nsCOMPtr<nsIDocument> d = window->GetExtantDoc();
         NS_WARN_IF_FALSE(!nsContentUtils::IsChromeDoc(d),
@@ -367,18 +377,18 @@ EventListenerManager::AddEventListenerIn
       nsCOMPtr<nsIDocument> d = window->GetExtantDoc();
       NS_WARN_IF_FALSE(!nsContentUtils::IsChromeDoc(d),
                        "Please do not use mouseenter/leave events in chrome. "
                        "They are slower than mouseover/out!");
 #endif
       window->SetHasMouseEnterLeaveEventListeners();
     }
 #ifdef MOZ_GAMEPAD
-  } else if (aType >= NS_GAMEPAD_START &&
-             aType <= NS_GAMEPAD_END) {
+  } else if (aEventMessage >= NS_GAMEPAD_START &&
+             aEventMessage <= NS_GAMEPAD_END) {
     nsPIDOMWindow* window = GetInnerWindowForTarget();
     if (window) {
       window->SetHasGamepadEventListener();
     }
 #endif
   } else if (aTypeAtom == nsGkAtoms::onkeydown ||
              aTypeAtom == nsGkAtoms::onkeypress ||
              aTypeAtom == nsGkAtoms::onkeyup) {
@@ -400,40 +410,40 @@ EventListenerManager::AddEventListenerIn
 
   if (mIsMainThreadELM && mTarget) {
     EventListenerService::NotifyAboutMainThreadListenerChange(mTarget,
                                                               aTypeAtom);
   }
 }
 
 bool
-EventListenerManager::IsDeviceType(uint32_t aType)
+EventListenerManager::IsDeviceType(EventMessage aEventMessage)
 {
-  switch (aType) {
+  switch (aEventMessage) {
     case NS_DEVICE_ORIENTATION:
     case NS_DEVICE_MOTION:
     case NS_DEVICE_LIGHT:
     case NS_DEVICE_PROXIMITY:
     case NS_USER_PROXIMITY:
       return true;
     default:
       break;
   }
   return false;
 }
 
 void
-EventListenerManager::EnableDevice(uint32_t aType)
+EventListenerManager::EnableDevice(EventMessage aEventMessage)
 {
   nsCOMPtr<nsPIDOMWindow> window = GetTargetAsInnerWindow();
   if (!window) {
     return;
   }
 
-  switch (aType) {
+  switch (aEventMessage) {
     case NS_DEVICE_ORIENTATION:
       window->EnableDeviceSensor(SENSOR_ORIENTATION);
       break;
     case NS_DEVICE_PROXIMITY:
     case NS_USER_PROXIMITY:
       window->EnableDeviceSensor(SENSOR_PROXIMITY);
       break;
     case NS_DEVICE_LIGHT:
@@ -446,24 +456,24 @@ EventListenerManager::EnableDevice(uint3
       break;
     default:
       NS_WARNING("Enabling an unknown device sensor.");
       break;
   }
 }
 
 void
-EventListenerManager::DisableDevice(uint32_t aType)
+EventListenerManager::DisableDevice(EventMessage aEventMessage)
 {
   nsCOMPtr<nsPIDOMWindow> window = GetTargetAsInnerWindow();
   if (!window) {
     return;
   }
 
-  switch (aType) {
+  switch (aEventMessage) {
     case NS_DEVICE_ORIENTATION:
       window->DisableDeviceSensor(SENSOR_ORIENTATION);
       break;
     case NS_DEVICE_MOTION:
       window->DisableDeviceSensor(SENSOR_ACCELERATION);
       window->DisableDeviceSensor(SENSOR_LINEAR_ACCELERATION);
       window->DisableDeviceSensor(SENSOR_GYROSCOPE);
       break;
@@ -478,40 +488,40 @@ EventListenerManager::DisableDevice(uint
       NS_WARNING("Disabling an unknown device sensor.");
       break;
   }
 }
 
 void
 EventListenerManager::RemoveEventListenerInternal(
                         const EventListenerHolder& aListenerHolder,
-                        uint32_t aType,
+                        EventMessage aEventMessage,
                         nsIAtom* aUserType,
                         const nsAString& aTypeString,
                         const EventListenerFlags& aFlags,
                         bool aAllEvents)
 {
-  if (!aListenerHolder || !aType || mClearingListeners) {
+  if (!aListenerHolder || !aEventMessage || mClearingListeners) {
     return;
   }
 
   Listener* listener;
 
   uint32_t count = mListeners.Length();
   uint32_t typeCount = 0;
-  bool deviceType = IsDeviceType(aType);
+  bool deviceType = IsDeviceType(aEventMessage);
 #ifdef MOZ_B2G
-  bool timeChangeEvent = (aType == NS_MOZ_TIME_CHANGE_EVENT);
-  bool networkEvent = (aType == NS_NETWORK_UPLOAD_EVENT ||
-                       aType == NS_NETWORK_DOWNLOAD_EVENT);
+  bool timeChangeEvent = (aEventMessage == NS_MOZ_TIME_CHANGE_EVENT);
+  bool networkEvent = (aEventMessage == NS_NETWORK_UPLOAD_EVENT ||
+                       aEventMessage == NS_NETWORK_DOWNLOAD_EVENT);
 #endif // MOZ_B2G
 
   for (uint32_t i = 0; i < count; ++i) {
     listener = &mListeners.ElementAt(i);
-    if (EVENT_TYPE_EQUALS(listener, aType, aUserType, aTypeString,
+    if (EVENT_TYPE_EQUALS(listener, aEventMessage, aUserType, aTypeString,
                           aAllEvents)) {
       ++typeCount;
       if (listener->mListener == aListenerHolder &&
           listener->mFlags.EqualsIgnoringTrustness(aFlags)) {
         nsRefPtr<EventListenerManager> kungFuDeathGrip(this);
         mListeners.RemoveElementAt(i);
         --count;
         mNoListenerForEvent = NS_EVENT_NULL;
@@ -532,123 +542,123 @@ EventListenerManager::RemoveEventListene
           return;
         }
         --typeCount;
       }
     }
   }
 
   if (!aAllEvents && deviceType && typeCount == 0) {
-    DisableDevice(aType);
+    DisableDevice(aEventMessage);
 #ifdef MOZ_B2G
   } else if (timeChangeEvent && typeCount == 0) {
     nsCOMPtr<nsPIDOMWindow> window = GetTargetAsInnerWindow();
     if (window) {
       window->DisableTimeChangeNotifications();
     }
   } else if (!aAllEvents && networkEvent && typeCount == 0) {
     nsCOMPtr<nsPIDOMWindow> window = GetTargetAsInnerWindow();
     if (window) {
-      window->DisableNetworkEvent(aType);
+      window->DisableNetworkEvent(aEventMessage);
     }
 #endif // MOZ_B2G
   }
 }
 
 bool
 EventListenerManager::ListenerCanHandle(Listener* aListener,
                                         WidgetEvent* aEvent)
 {
   // This is slightly different from EVENT_TYPE_EQUALS in that it returns
   // true even when aEvent->mMessage == NS_USER_DEFINED_EVENT and
-  // aListener=>mEventType != NS_USER_DEFINED_EVENT as long as the atoms are
+  // aListener=>mEventMessage != NS_USER_DEFINED_EVENT as long as the atoms are
   // the same
   if (aListener->mAllEvents) {
     return true;
   }
   if (aEvent->mMessage == NS_USER_DEFINED_EVENT) {
     if (mIsMainThreadELM) {
       return aListener->mTypeAtom == aEvent->userType;
     }
     return aListener->mTypeString.Equals(aEvent->typeString);
   }
   MOZ_ASSERT(mIsMainThreadELM);
-  return aListener->mEventType == aEvent->mMessage;
+  return aListener->mEventMessage == aEvent->mMessage;
 }
 
 void
 EventListenerManager::AddEventListenerByType(
                         const EventListenerHolder& aListenerHolder,
                         const nsAString& aType,
                         const EventListenerFlags& aFlags)
 {
   nsCOMPtr<nsIAtom> atom =
     mIsMainThreadELM ? do_GetAtom(NS_LITERAL_STRING("on") + aType) : nullptr;
-  uint32_t type = nsContentUtils::GetEventId(atom);
-  AddEventListenerInternal(aListenerHolder, type, atom, aType, aFlags);
+  EventMessage message = nsContentUtils::GetEventMessage(atom);
+  AddEventListenerInternal(aListenerHolder, message, atom, aType, aFlags);
 }
 
 void
 EventListenerManager::RemoveEventListenerByType(
                         const EventListenerHolder& aListenerHolder,
                         const nsAString& aType,
                         const EventListenerFlags& aFlags)
 {
   nsCOMPtr<nsIAtom> atom =
     mIsMainThreadELM ? do_GetAtom(NS_LITERAL_STRING("on") + aType) : nullptr;
-  uint32_t type = nsContentUtils::GetEventId(atom);
-  RemoveEventListenerInternal(aListenerHolder, type, atom, aType, aFlags);
+  EventMessage message = nsContentUtils::GetEventMessage(atom);
+  RemoveEventListenerInternal(aListenerHolder, message, atom, aType, aFlags);
 }
 
 EventListenerManager::Listener*
-EventListenerManager::FindEventHandler(uint32_t aEventType,
+EventListenerManager::FindEventHandler(EventMessage aEventMessage,
                                        nsIAtom* aTypeAtom,
                                        const nsAString& aTypeString)
 {
   // Run through the listeners for this type and see if a script
   // listener is registered
   Listener* listener;
   uint32_t count = mListeners.Length();
   for (uint32_t i = 0; i < count; ++i) {
     listener = &mListeners.ElementAt(i);
     if (listener->mListenerIsHandler &&
-        EVENT_TYPE_EQUALS(listener, aEventType, aTypeAtom, aTypeString,
+        EVENT_TYPE_EQUALS(listener, aEventMessage, aTypeAtom, aTypeString,
                           false)) {
       return listener;
     }
   }
   return nullptr;
 }
 
 EventListenerManager::Listener*
 EventListenerManager::SetEventHandlerInternal(
                         nsIAtom* aName,
                         const nsAString& aTypeString,
                         const TypedEventHandler& aTypedHandler,
                         bool aPermitUntrustedEvents)
 {
   MOZ_ASSERT(aName || !aTypeString.IsEmpty());
 
-  uint32_t eventType = nsContentUtils::GetEventId(aName);
-  Listener* listener = FindEventHandler(eventType, aName, aTypeString);
+  EventMessage eventMessage = nsContentUtils::GetEventMessage(aName);
+  Listener* listener = FindEventHandler(eventMessage, aName, aTypeString);
 
   if (!listener) {
     // If we didn't find a script listener or no listeners existed
     // create and add a new one.
     EventListenerFlags flags;
     flags.mListenerIsJSListener = true;
 
     nsCOMPtr<JSEventHandler> jsEventHandler;
     NS_NewJSEventHandler(mTarget, aName,
                          aTypedHandler, getter_AddRefs(jsEventHandler));
     EventListenerHolder listenerHolder(jsEventHandler);
-    AddEventListenerInternal(listenerHolder, eventType, aName, aTypeString,
+    AddEventListenerInternal(listenerHolder, eventMessage, aName, aTypeString,
                              flags, true);
 
-    listener = FindEventHandler(eventType, aName, aTypeString);
+    listener = FindEventHandler(eventMessage, aName, aTypeString);
   } else {
     JSEventHandler* jsEventHandler = listener->GetJSEventHandler();
     MOZ_ASSERT(jsEventHandler,
                "How can we have an event handler with no JSEventHandler?");
 
     bool same = jsEventHandler->GetTypedEventHandler() == aTypedHandler;
     // Possibly the same listener, but update still the context and scope.
     jsEventHandler->SetHandler(aTypedHandler);
@@ -771,18 +781,18 @@ EventListenerManager::SetEventHandler(ns
 void
 EventListenerManager::RemoveEventHandler(nsIAtom* aName,
                                          const nsAString& aTypeString)
 {
   if (mClearingListeners) {
     return;
   }
 
-  uint32_t eventType = nsContentUtils::GetEventId(aName);
-  Listener* listener = FindEventHandler(eventType, aName, aTypeString);
+  EventMessage eventMessage = nsContentUtils::GetEventMessage(aName);
+  Listener* listener = FindEventHandler(eventMessage, aName, aTypeString);
 
   if (listener) {
     mListeners.RemoveElementAt(uint32_t(listener - &mListeners.ElementAt(0)));
     mNoListenerForEvent = NS_EVENT_NULL;
     mNoListenerForEventAtom = nullptr;
     if (mTarget && aName) {
       mTarget->EventListenerRemoved(aName);
     }
@@ -1234,40 +1244,40 @@ EventListenerManager::RemoveListenerForA
 
 bool
 EventListenerManager::HasMutationListeners()
 {
   if (mMayHaveMutationListeners) {
     uint32_t count = mListeners.Length();
     for (uint32_t i = 0; i < count; ++i) {
       Listener* listener = &mListeners.ElementAt(i);
-      if (listener->mEventType >= NS_MUTATION_START &&
-          listener->mEventType <= NS_MUTATION_END) {
+      if (listener->mEventMessage >= NS_MUTATION_START &&
+          listener->mEventMessage <= NS_MUTATION_END) {
         return true;
       }
     }
   }
 
   return false;
 }
 
 uint32_t
 EventListenerManager::MutationListenerBits()
 {
   uint32_t bits = 0;
   if (mMayHaveMutationListeners) {
     uint32_t count = mListeners.Length();
     for (uint32_t i = 0; i < count; ++i) {
       Listener* listener = &mListeners.ElementAt(i);
-      if (listener->mEventType >= NS_MUTATION_START &&
-          listener->mEventType <= NS_MUTATION_END) {
-        if (listener->mEventType == NS_MUTATION_SUBTREEMODIFIED) {
+      if (listener->mEventMessage >= NS_MUTATION_START &&
+          listener->mEventMessage <= NS_MUTATION_END) {
+        if (listener->mEventMessage == NS_MUTATION_SUBTREEMODIFIED) {
           return kAllMutationBits;
         }
-        bits |= MutationBitForEventType(listener->mEventType);
+        bits |= MutationBitForEventType(listener->mEventMessage);
       }
     }
   }
   return bits;
 }
 
 bool
 EventListenerManager::HasListenersFor(const nsAString& aEventName)
@@ -1347,18 +1357,18 @@ EventListenerManager::GetListenerInfo(ns
 }
 
 bool
 EventListenerManager::HasUnloadListeners()
 {
   uint32_t count = mListeners.Length();
   for (uint32_t i = 0; i < count; ++i) {
     Listener* listener = &mListeners.ElementAt(i);
-    if (listener->mEventType == NS_PAGE_UNLOAD ||
-        listener->mEventType == NS_BEFORE_PAGE_UNLOAD) {
+    if (listener->mEventMessage == NS_PAGE_UNLOAD ||
+        listener->mEventMessage == NS_BEFORE_PAGE_UNLOAD) {
       return true;
     }
   }
   return false;
 }
 
 void
 EventListenerManager::SetEventHandler(nsIAtom* aEventName,
@@ -1419,18 +1429,18 @@ EventListenerManager::SetEventHandler(
                           !mIsMainThreadELM ||
                           !nsContentUtils::IsCallerChrome());
 }
 
 const TypedEventHandler*
 EventListenerManager::GetTypedEventHandler(nsIAtom* aEventName,
                                            const nsAString& aTypeString)
 {
-  uint32_t eventType = nsContentUtils::GetEventId(aEventName);
-  Listener* listener = FindEventHandler(eventType, aEventName, aTypeString);
+  EventMessage eventMessage = nsContentUtils::GetEventMessage(aEventName);
+  Listener* listener = FindEventHandler(eventMessage, aEventName, aTypeString);
 
   if (!listener) {
     return nullptr;
   }
 
   JSEventHandler* jsEventHandler = listener->GetJSEventHandler();
 
   if (listener->mHandlerIsString) {
--- a/dom/events/EventListenerManager.h
+++ b/dom/events/EventListenerManager.h
@@ -141,31 +141,51 @@ inline EventListenerFlags AllEventsAtSys
 {
   EventListenerFlags flags;
   flags.mCapture = true;
   flags.mInSystemGroup = true;
   flags.mAllowUntrustedEvents = true;
   return flags;
 }
 
+class EventListenerManagerBase
+{
+protected:
+  EventListenerManagerBase();
+
+  EventMessage mNoListenerForEvent;
+  uint16_t mMayHavePaintEventListener : 1;
+  uint16_t mMayHaveMutationListeners : 1;
+  uint16_t mMayHaveCapturingListeners : 1;
+  uint16_t mMayHaveSystemGroupListeners : 1;
+  uint16_t mMayHaveTouchEventListener : 1;
+  uint16_t mMayHaveMouseEnterLeaveEventListener : 1;
+  uint16_t mMayHavePointerEnterLeaveEventListener : 1;
+  uint16_t mMayHaveKeyEventListener : 1;
+  uint16_t mMayHaveInputOrCompositionEventListener : 1;
+  uint16_t mClearingListeners : 1;
+  uint16_t mIsMainThreadELM : 1;
+  // uint16_t mUnused : 5;
+};
+
 /*
  * Event listener manager
  */
 
-class EventListenerManager final
+class EventListenerManager final : public EventListenerManagerBase
 {
   ~EventListenerManager();
 
 public:
   struct Listener
   {
     EventListenerHolder mListener;
     nsCOMPtr<nsIAtom> mTypeAtom; // for the main thread
     nsString mTypeString; // for non-main-threads
-    uint16_t mEventType;
+    EventMessage mEventMessage;
 
     enum ListenerType : uint8_t
     {
       eNativeListener = 0,
       eJSEventListener,
       eWrappedJSListener,
       eWebIDLListener,
       eListenerTypeCount
@@ -444,35 +464,35 @@ protected:
    */
   nsresult CompileEventHandlerInternal(Listener* aListener,
                                        const nsAString* aBody,
                                        dom::Element* aElement);
 
   /**
    * Find the Listener for the "inline" event listener for aTypeAtom.
    */
-  Listener* FindEventHandler(uint32_t aEventType,
+  Listener* FindEventHandler(EventMessage aEventMessage,
                              nsIAtom* aTypeAtom,
                              const nsAString& aTypeString);
 
   /**
    * Set the "inline" event listener for aName to aHandler.  aHandler may be
    * have no actual handler set to indicate that we should lazily get and
    * compile the string for this listener, but in that case aContext and
    * aScopeGlobal must be non-null.  Otherwise, aContext and aScopeGlobal are
    * allowed to be null.
    */
   Listener* SetEventHandlerInternal(nsIAtom* aName,
                                     const nsAString& aTypeString,
                                     const TypedEventHandler& aHandler,
                                     bool aPermitUntrustedEvents);
 
-  bool IsDeviceType(uint32_t aType);
-  void EnableDevice(uint32_t aType);
-  void DisableDevice(uint32_t aType);
+  bool IsDeviceType(EventMessage aEventMessage);
+  void EnableDevice(EventMessage aEventMessage);
+  void DisableDevice(EventMessage aEventMessage);
 
 public:
   /**
    * Set the "inline" event listener for aEventName to aHandler.  If
    * aHandler is null, this will actually remove the event listener
    */
   void SetEventHandler(nsIAtom* aEventName,
                        const nsAString& aTypeString,
@@ -524,52 +544,44 @@ protected:
                         const EventListenerHolder& aListener,
                         bool aUseCapture,
                         bool aWantsUntrusted);
   void RemoveEventListener(const nsAString& aType,
                            const EventListenerHolder& aListener,
                            bool aUseCapture);
 
   void AddEventListenerInternal(const EventListenerHolder& aListener,
-                                uint32_t aType,
+                                EventMessage aEventMessage,
                                 nsIAtom* aTypeAtom,
                                 const nsAString& aTypeString,
                                 const EventListenerFlags& aFlags,
                                 bool aHandler = false,
                                 bool aAllEvents = false);
   void RemoveEventListenerInternal(const EventListenerHolder& aListener,
-                                   uint32_t aType,
+                                   EventMessage aEventMessage,
                                    nsIAtom* aUserType,
                                    const nsAString& aTypeString,
                                    const EventListenerFlags& aFlags,
                                    bool aAllEvents = false);
   void RemoveAllListeners();
   const EventTypeData* GetTypeDataForIID(const nsIID& aIID);
   const EventTypeData* GetTypeDataForEventName(nsIAtom* aName);
   nsPIDOMWindow* GetInnerWindowForTarget();
   already_AddRefed<nsPIDOMWindow> GetTargetAsInnerWindow() const;
 
   bool ListenerCanHandle(Listener* aListener, WidgetEvent* aEvent);
 
+  // BE AWARE, a lot of instances of EventListenerManager will be created.
+  // Therefor, we need to keep this class compact.  When you add integer
+  // members, please add them to EventListemerManagerBase and check the size
+  // at build time.
+
   already_AddRefed<nsIScriptGlobalObject>
   GetScriptGlobalAndDocument(nsIDocument** aDoc);
 
-  uint32_t mMayHavePaintEventListener : 1;
-  uint32_t mMayHaveMutationListeners : 1;
-  uint32_t mMayHaveCapturingListeners : 1;
-  uint32_t mMayHaveSystemGroupListeners : 1;
-  uint32_t mMayHaveTouchEventListener : 1;
-  uint32_t mMayHaveMouseEnterLeaveEventListener : 1;
-  uint32_t mMayHavePointerEnterLeaveEventListener : 1;
-  uint32_t mMayHaveKeyEventListener : 1;
-  uint32_t mMayHaveInputOrCompositionEventListener : 1;
-  uint32_t mClearingListeners : 1;
-  uint32_t mIsMainThreadELM : 1;
-  uint32_t mNoListenerForEvent : 21;
-
   nsAutoTObserverArray<Listener, 2> mListeners;
   dom::EventTarget* MOZ_NON_OWNING_REF mTarget;
   nsCOMPtr<nsIAtom> mNoListenerForEventAtom;
 
   friend class ELMCreationDetector;
   static uint32_t sMainThreadCreatedCount;
 };
 
--- a/dom/events/EventNameList.h
+++ b/dom/events/EventNameList.h
@@ -6,17 +6,17 @@
 
 /*
  * This file contains the list of event names that are exposed via IDL
  * on various objects.  It is designed to be used as inline input to
  * various consumers through the magic of C preprocessing.
  *
  * Each entry consists of 4 pieces of information:
  * 1) The name of the event
- * 2) The event ID (see BasicEvents.h)
+ * 2) The event message
  * 3) The event type (see the EventNameType enum in nsContentUtils.h)
  * 4) The event struct type for this event.
  * Items 2-4 might be empty strings for events for which they don't make sense.
  *
  * Event names that are exposed as content attributes on HTML elements
  * and as IDL attributes on Elements, Documents and Windows and have
  * no forwarding behavior should be enclosed in the EVENT macro.
  *
@@ -47,55 +47,55 @@
  * Event names that are not exposed as IDL attributes at all should be
  * enclosed in NON_IDL_EVENT.  If NON_IDL_EVENT is not defined, it
  * will be defined to the empty string.
  *
  * If you change which macros event names are enclosed in, please
  * update the tests for bug 689564 and bug 659350 as needed.
  */
 
-#ifdef ID_TO_EVENT
+#ifdef MESSAGE_TO_EVENT
 #ifdef EVENT
 #error "Don't define EVENT"
 #endif /* EVENT */
 #ifdef WINDOW_ONLY_EVENT
 #error "Don't define WINDOW_ONLY_EVENT"
 #endif /* WINDOW_ONLY_EVENT */
 #ifdef TOUCH_EVENT
 #error "Don't define TOUCH_EVENT"
 #endif /* TOUCH_EVENT */
 #ifdef DOCUMENT_ONLY_EVENT
 #error "Don't define DOCUMENT_ONLY_EVENT"
 #endif /* DOCUMENT_ONLY_EVENT */
 #ifdef NON_IDL_EVENT
 #error "Don't define NON_IDL_EVENT"
 #endif /* NON_IDL_EVENT */
 
-#define EVENT ID_TO_EVENT
-#define WINDOW_ONLY_EVENT ID_TO_EVENT
-#define TOUCH_EVENT ID_TO_EVENT
-#define DOCUMENT_ONLY_EVENT ID_TO_EVENT
-#define NON_IDL_EVENT ID_TO_EVENT
+#define EVENT MESSAGE_TO_EVENT
+#define WINDOW_ONLY_EVENT MESSAGE_TO_EVENT
+#define TOUCH_EVENT MESSAGE_TO_EVENT
+#define DOCUMENT_ONLY_EVENT MESSAGE_TO_EVENT
+#define NON_IDL_EVENT MESSAGE_TO_EVENT
 #endif
 
 #ifdef DEFINED_FORWARDED_EVENT
 #error "Don't define DEFINED_FORWARDED_EVENT"
 #endif /* DEFINED_FORWARDED_EVENT */
 
 #ifndef FORWARDED_EVENT
 #define FORWARDED_EVENT EVENT
 #define DEFINED_FORWARDED_EVENT
 #endif /* FORWARDED_EVENT */
 
 #ifdef DEFINED_WINDOW_ONLY_EVENT
 #error "Don't define DEFINED_WINDOW_ONLY_EVENT"
 #endif /* DEFINED_WINDOW_ONLY_EVENT */
 
 #ifndef WINDOW_ONLY_EVENT
-#define WINDOW_ONLY_EVENT(_name, _id, _type, _struct)
+#define WINDOW_ONLY_EVENT(_name, _message, _type, _struct)
 #define DEFINED_WINDOW_ONLY_EVENT
 #endif /* WINDOW_ONLY_EVENT */
 
 #ifdef DEFINED_WINDOW_EVENT
 #error "Don't define DEFINED_WINDOW_EVENT"
 #endif /* DEFINED_WINDOW_EVENT */
 
 #ifndef WINDOW_EVENT
@@ -103,35 +103,35 @@
 #define DEFINED_WINDOW_EVENT
 #endif /* WINDOW_EVENT */
 
 #ifdef DEFINED_TOUCH_EVENT
 #error "Don't define DEFINED_TOUCH_EVENT"
 #endif /* DEFINED_TOUCH_EVENT */
 
 #ifndef TOUCH_EVENT
-#define TOUCH_EVENT(_name, _id, _type, _struct)
+#define TOUCH_EVENT(_name, _message, _type, _struct)
 #define DEFINED_TOUCH_EVENT
 #endif /* TOUCH_EVENT */
 
 #ifdef DEFINED_DOCUMENT_ONLY_EVENT
 #error "Don't define DEFINED_DOCUMENT_ONLY_EVENT"
 #endif /* DEFINED_DOCUMENT_ONLY_EVENT */
 
 #ifndef DOCUMENT_ONLY_EVENT
-#define DOCUMENT_ONLY_EVENT(_name, _id, _type, _struct)
+#define DOCUMENT_ONLY_EVENT(_name, _message, _type, _struct)
 #define DEFINED_DOCUMENT_ONLY_EVENT
 #endif /* DOCUMENT_ONLY_EVENT */
 
 #ifdef DEFINED_NON_IDL_EVENT
 #error "Don't define DEFINED_NON_IDL_EVENT"
 #endif /* DEFINED_NON_IDL_EVENT */
 
 #ifndef NON_IDL_EVENT
-#define NON_IDL_EVENT(_name, _id, _type, _struct)
+#define NON_IDL_EVENT(_name, _message, _type, _struct)
 #define DEFINED_NON_IDL_EVENT
 #endif /* NON_IDL_EVENT */
 
 #ifdef DEFINED_ERROR_EVENT
 #error "Don't define DEFINED_ERROR_EVENT"
 #endif /* DEFINED_ERROR_EVENT */
 
 #ifndef ERROR_EVENT
@@ -758,48 +758,48 @@ NON_IDL_EVENT(SVGScroll,
               EventNameType_None,
               eBasicEventClass)
 
 NON_IDL_EVENT(SVGZoom,
               NS_SVG_ZOOM,
               EventNameType_None,
               eSVGZoomEventClass)
 
-// Only map the ID to the real event name when ID_TO_EVENT is defined.
-#ifndef ID_TO_EVENT
+// Only map the ID to the real event name when MESSAGE_TO_EVENT is defined.
+#ifndef MESSAGE_TO_EVENT
 // This is a bit hackish, but SVG's event names are weird.
 NON_IDL_EVENT(zoom,
               NS_SVG_ZOOM,
               EventNameType_SVGSVG,
               eBasicEventClass)
 #endif
-// Only map the ID to the real event name when ID_TO_EVENT is defined.
-#ifndef ID_TO_EVENT
+// Only map the ID to the real event name when MESSAGE_TO_EVENT is defined.
+#ifndef MESSAGE_TO_EVENT
 NON_IDL_EVENT(begin,
               NS_SMIL_BEGIN,
               EventNameType_SMIL,
               eBasicEventClass)
 #endif
 NON_IDL_EVENT(beginEvent,
               NS_SMIL_BEGIN,
               EventNameType_None,
               eSMILTimeEventClass)
-// Only map the ID to the real event name when ID_TO_EVENT is defined.
-#ifndef ID_TO_EVENT
+// Only map the ID to the real event name when MESSAGE_TO_EVENT is defined.
+#ifndef MESSAGE_TO_EVENT
 NON_IDL_EVENT(end,
               NS_SMIL_END,
               EventNameType_SMIL,
               eBasicEventClass)
 #endif
 NON_IDL_EVENT(endEvent,
               NS_SMIL_END,
               EventNameType_None,
               eSMILTimeEventClass)
-// Only map the ID to the real event name when ID_TO_EVENT is defined.
-#ifndef ID_TO_EVENT
+// Only map the ID to the real event name when MESSAGE_TO_EVENT is defined.
+#ifndef MESSAGE_TO_EVENT
 NON_IDL_EVENT(repeat,
               NS_SMIL_REPEAT,
               EventNameType_SMIL,
               eBasicEventClass)
 #endif
 NON_IDL_EVENT(repeatEvent,
               NS_SMIL_REPEAT,
               EventNameType_None,
@@ -962,16 +962,16 @@ NON_IDL_EVENT(complete,
 #undef ERROR_EVENT
 #endif /* DEFINED_ERROR_EVENT */
 
 #ifdef DEFINED_BEFOREUNLOAD_EVENT
 #undef DEFINED_BEFOREUNLOAD_EVENT
 #undef BEFOREUNLOAD_EVENT
 #endif /* BEFOREUNLOAD_EVENT */
 
-#ifdef ID_TO_EVENT
+#ifdef MESSAGE_TO_EVENT
 #undef EVENT
 #undef WINDOW_ONLY_EVENT
 #undef TOUCH_EVENT
 #undef DOCUMENT_ONLY_EVENT
 #undef NON_IDL_EVENT
-#endif /* ID_TO_EVENT */
+#endif /* MESSAGE_TO_EVENT */
 
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -620,17 +620,17 @@ EventStateManager::PreHandleEvent(nsPres
       // then fall through...
     } else {
       if (sPointerEventEnabled) {
         // We should synthetize corresponding pointer events
         GeneratePointerEnterExit(NS_POINTER_LEAVE, mouseEvent);
       }
       GenerateMouseEnterExit(mouseEvent);
       //This is a window level mouse exit event and should stop here
-      aEvent->mMessage = 0;
+      aEvent->mMessage = NS_EVENT_NULL;
       break;
     }
   case NS_MOUSE_MOVE:
   case NS_POINTER_DOWN:
   case NS_POINTER_MOVE: {
     // on the Mac, GenerateDragGesture() may not return until the drag
     // has completed and so |aTargetFrame| may have been deleted (moving
     // a bookmark, for example).  If this is the case, however, we know
@@ -831,16 +831,18 @@ EventStateManager::PreHandleEvent(nsPres
       WidgetCompositionEvent* compositionEvent = aEvent->AsCompositionEvent();
       WidgetQueryContentEvent selectedText(true, NS_QUERY_SELECTED_TEXT,
                                            compositionEvent->widget);
       DoQuerySelectedText(&selectedText);
       NS_ASSERTION(selectedText.mSucceeded, "Failed to get selected text");
       compositionEvent->mData = selectedText.mReply.mString;
     }
     break;
+  default:
+    break;
   }
   return NS_OK;
 }
 
 // static
 int32_t
 EventStateManager::GetAccessModifierMaskFor(nsISupports* aDocShell)
 {
@@ -1189,16 +1191,18 @@ CrossProcessSafeEvent(const WidgetEvent&
       return false;
     }
   case eDragEventClass:
     switch (aEvent.mMessage) {
     case NS_DRAGDROP_OVER:
     case NS_DRAGDROP_EXIT:
     case NS_DRAGDROP_DROP:
       return true;
+    default:
+      break;
     }
   default:
     return false;
   }
 }
 
 bool
 EventStateManager::HandleCrossProcessEvent(WidgetEvent* aEvent,
@@ -3327,16 +3331,19 @@ EventStateManager::PostHandleEvent(nsPre
       nsCOMPtr<nsIContent> targetContent;
       mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(targetContent));
       if (!NodeAllowsClickThrough(targetContent)) {
         *aStatus = nsEventStatus_eConsumeNoDefault;
       }
     }
     break;
 #endif
+
+  default:
+    break;
   }
 
   //Reset target frame to null to avoid mistargeting after reentrant event
   mCurrentTarget = nullptr;
   mCurrentTargetContent = nullptr;
 
   return ret;
 }
@@ -3680,17 +3687,17 @@ EventStateManager::IsHandlingUserInput()
 
   TimeDuration timeout = nsContentUtils::HandlingUserInputTimeout();
   return timeout <= TimeDuration(0) ||
          (TimeStamp::Now() - sHandlingInputStart) <= timeout;
 }
 
 static void
 CreateMouseOrPointerWidgetEvent(WidgetMouseEvent* aMouseEvent,
-                                uint32_t aMessage,
+                                EventMessage aMessage,
                                 nsIContent* aRelatedContent,
                                 nsAutoPtr<WidgetMouseEvent>& aNewEvent)
 {
   WidgetPointerEvent* sourcePointer = aMouseEvent->AsPointerEvent();
   if (sourcePointer) {
     PROFILER_LABEL("Input", "DispatchPointerEvent",
       js::ProfileEntry::Category::EVENTS);
 
@@ -3720,17 +3727,17 @@ CreateMouseOrPointerWidgetEvent(WidgetMo
   aNewEvent->buttons = aMouseEvent->buttons;
   aNewEvent->pressure = aMouseEvent->pressure;
   aNewEvent->mPluginEvent = aMouseEvent->mPluginEvent;
   aNewEvent->inputSource = aMouseEvent->inputSource;
 }
 
 nsIFrame*
 EventStateManager::DispatchMouseOrPointerEvent(WidgetMouseEvent* aMouseEvent,
-                                               uint32_t aMessage,
+                                               EventMessage aMessage,
                                                nsIContent* aTargetContent,
                                                nsIContent* aRelatedContent)
 {
   // http://dvcs.w3.org/hg/webevents/raw-file/default/mouse-lock.html#methods
   // "[When the mouse is locked on an element...e]vents that require the concept
   // of a mouse cursor must not be dispatched (for example: mouseover, mouseout).
   if (sIsPointerLocked &&
       (aMessage == NS_MOUSELEAVE ||
@@ -3809,20 +3816,21 @@ EventStateManager::DispatchMouseOrPointe
   return targetFrame;
 }
 
 class EnterLeaveDispatcher
 {
 public:
   EnterLeaveDispatcher(EventStateManager* aESM,
                        nsIContent* aTarget, nsIContent* aRelatedTarget,
-                       WidgetMouseEvent* aMouseEvent, uint32_t aType)
+                       WidgetMouseEvent* aMouseEvent,
+                       EventMessage aEventMessage)
     : mESM(aESM)
     , mMouseEvent(aMouseEvent)
-    , mType(aType)
+    , mEventMessage(aEventMessage)
   {
     nsPIDOMWindow* win =
       aTarget ? aTarget->OwnerDoc()->GetInnerWindow() : nullptr;
     if (aMouseEvent->AsPointerEvent() ? win && win->HasPointerEnterLeaveEventListeners() :
                                         win && win->HasMouseEnterLeaveEventListeners()) {
       mRelatedTarget = aRelatedTarget ?
         aRelatedTarget->FindFirstNonChromeOnlyAccessContent() : nullptr;
       nsINode* commonParent = nullptr;
@@ -3839,35 +3847,35 @@ public:
         // mouseenter/leave is fired only on elements.
         current = current->GetParent();
       }
     }
   }
 
   ~EnterLeaveDispatcher()
   {
-    if (mType == NS_MOUSEENTER ||
-        mType == NS_POINTER_ENTER) {
+    if (mEventMessage == NS_MOUSEENTER ||
+        mEventMessage == NS_POINTER_ENTER) {
       for (int32_t i = mTargets.Count() - 1; i >= 0; --i) {
-        mESM->DispatchMouseOrPointerEvent(mMouseEvent, mType, mTargets[i],
-                                          mRelatedTarget);
+        mESM->DispatchMouseOrPointerEvent(mMouseEvent, mEventMessage,
+                                          mTargets[i], mRelatedTarget);
       }
     } else {
       for (int32_t i = 0; i < mTargets.Count(); ++i) {
-        mESM->DispatchMouseOrPointerEvent(mMouseEvent, mType, mTargets[i],
-                                          mRelatedTarget);
+        mESM->DispatchMouseOrPointerEvent(mMouseEvent, mEventMessage,
+                                          mTargets[i], mRelatedTarget);
       }
     }
   }
 
   EventStateManager* mESM;
   nsCOMArray<nsIContent> mTargets;
   nsCOMPtr<nsIContent> mRelatedTarget;
   WidgetMouseEvent* mMouseEvent;
-  uint32_t mType;
+  EventMessage mEventMessage;
 };
 
 void
 EventStateManager::NotifyMouseOut(WidgetMouseEvent* aMouseEvent,
                                   nsIContent* aMovingInto)
 {
   OverOutElementsWrapper* wrapper = GetWrapperByEventID(aMouseEvent);
 
@@ -4050,17 +4058,18 @@ GetWindowInnerRectCenter(nsPIDOMWindow* 
   int32_t cssScreenY = aContext->DevPixelsToIntCSSPixels(screen.y);
 
   return LayoutDeviceIntPoint(
     aContext->CSSPixelsToDevPixels(innerX - cssScreenX + innerWidth / 2),
     aContext->CSSPixelsToDevPixels(innerY - cssScreenY + innerHeight / 2));
 }
 
 void
-EventStateManager::GeneratePointerEnterExit(uint32_t aMessage, WidgetMouseEvent* aEvent)
+EventStateManager::GeneratePointerEnterExit(EventMessage aMessage,
+                                            WidgetMouseEvent* aEvent)
 {
   WidgetPointerEvent pointerEvent(*aEvent);
   pointerEvent.mMessage = aMessage;
   GenerateMouseEnterExit(&pointerEvent);
 }
 
 void
 EventStateManager::GenerateMouseEnterExit(WidgetMouseEvent* aMouseEvent)
@@ -4173,16 +4182,18 @@ EventStateManager::GenerateMouseEnterExi
 
       // Reset sLastRefPoint, so that we'll know not to report any
       // movement the next time we re-enter the window.
       sLastRefPoint = kInvalidRefPoint;
 
       NotifyMouseOut(aMouseEvent, nullptr);
     }
     break;
+  default:
+    break;
   }
 
   // reset mCurretTargetContent to what it was
   mCurrentTargetContent = targetBeforeEvent;
 }
 
 OverOutElementsWrapper*
 EventStateManager::GetWrapperByEventID(WidgetMouseEvent* aEvent)
@@ -4319,35 +4330,38 @@ EventStateManager::GenerateDragDropEnter
         FireDragEnterOrExit(lastDragOverFramePresContext,
                             aDragEvent, NS_DRAGDROP_LEAVE,
                             nullptr, lastContent, sLastDragOverFrame);
 
         sLastDragOverFrame = nullptr;
       }
     }
     break;
+
+  default:
+    break;
   }
 
   //reset mCurretTargetContent to what it was
   mCurrentTargetContent = targetBeforeEvent;
 
   // Now flush all pending notifications, for better responsiveness.
   FlushPendingEvents(aPresContext);
 }
 
 void
 EventStateManager::FireDragEnterOrExit(nsPresContext* aPresContext,
                                        WidgetDragEvent* aDragEvent,
-                                       uint32_t aMsg,
+                                       EventMessage aMessage,
                                        nsIContent* aRelatedTarget,
                                        nsIContent* aTargetContent,
                                        nsWeakFrame& aTargetFrame)
 {
   nsEventStatus status = nsEventStatus_eIgnore;
-  WidgetDragEvent event(aDragEvent->mFlags.mIsTrusted, aMsg,
+  WidgetDragEvent event(aDragEvent->mFlags.mIsTrusted, aMessage,
                         aDragEvent->widget);
   event.refPoint = aDragEvent->refPoint;
   event.modifiers = aDragEvent->modifiers;
   event.buttons = aDragEvent->buttons;
   event.relatedTarget = aRelatedTarget;
   event.inputSource = aDragEvent->inputSource;
 
   mCurrentTargetContent = aTargetContent;
@@ -4355,25 +4369,29 @@ EventStateManager::FireDragEnterOrExit(n
   if (aTargetContent != aRelatedTarget) {
     //XXX This event should still go somewhere!!
     if (aTargetContent) {
       EventDispatcher::Dispatch(aTargetContent, aPresContext, &event,
                                 nullptr, &status);
     }
 
     // adjust the drag hover if the dragenter event was cancelled or this is a drag exit
-    if (status == nsEventStatus_eConsumeNoDefault || aMsg == NS_DRAGDROP_EXIT)
-      SetContentState((aMsg == NS_DRAGDROP_ENTER) ? aTargetContent : nullptr,
+    if (status == nsEventStatus_eConsumeNoDefault ||
+        aMessage == NS_DRAGDROP_EXIT) {
+      SetContentState((aMessage == NS_DRAGDROP_ENTER) ?
+                        aTargetContent : nullptr,
                       NS_EVENT_STATE_DRAGOVER);
+    }
 
     // collect any changes to moz cursor settings stored in the event's
     // data transfer.
-    if (aMsg == NS_DRAGDROP_LEAVE || aMsg == NS_DRAGDROP_EXIT ||
-        aMsg == NS_DRAGDROP_ENTER)
+    if (aMessage == NS_DRAGDROP_LEAVE || aMessage == NS_DRAGDROP_EXIT ||
+        aMessage == NS_DRAGDROP_ENTER) {
       UpdateDragDataTransfer(&event);
+    }
   }
 
   // Finally dispatch the event to the frame
   if (aTargetFrame)
     aTargetFrame->HandleEvent(aPresContext, &event, &status);
 }
 
 void
--- a/dom/events/EventStateManager.h
+++ b/dom/events/EventStateManager.h
@@ -298,23 +298,24 @@ protected:
                     nsIFrame* aTargetFrame,
                     nsEventStatus* aStatus);
   /**
    * Turn a GUI mouse/pointer event into a mouse/pointer event targeted at the specified
    * content.  This returns the primary frame for the content (or null
    * if it goes away during the event).
    */
   nsIFrame* DispatchMouseOrPointerEvent(WidgetMouseEvent* aMouseEvent,
-                                        uint32_t aMessage,
+                                        EventMessage aMessage,
                                         nsIContent* aTargetContent,
                                         nsIContent* aRelatedContent);
   /**
    * Synthesize DOM pointerover and pointerout events
    */
-  void GeneratePointerEnterExit(uint32_t aMessage, WidgetMouseEvent* aEvent);
+  void GeneratePointerEnterExit(EventMessage aMessage,
+                                WidgetMouseEvent* aEvent);
   /**
    * Synthesize DOM and frame mouseover and mouseout events from this
    * MOUSE_MOVE or MOUSE_EXIT event.
    */
   void GenerateMouseEnterExit(WidgetMouseEvent* aMouseEvent);
   /**
    * Tell this ESM and ESMs in parent documents that the mouse is
    * over some content in this document.
@@ -346,17 +347,17 @@ protected:
    * new target.
    *
    * @param aRelatedTarget relatedTarget to set for the event
    * @param aTargetContent target to set for the event
    * @param aTargetFrame target frame for the event
    */
   void FireDragEnterOrExit(nsPresContext* aPresContext,
                            WidgetDragEvent* aDragEvent,
-                           uint32_t aMsg,
+                           EventMessage aMessage,
                            nsIContent* aRelatedTarget,
                            nsIContent* aTargetContent,
                            nsWeakFrame& aTargetFrame);
   /**
    * Update the initial drag session data transfer with any changes that occur
    * on cloned data transfer objects used for events.
    */
   void UpdateDragDataTransfer(WidgetDragEvent* dragEvent);
--- a/dom/events/EventStates.h
+++ b/dom/events/EventStates.h
@@ -257,18 +257,16 @@ private:
 // Handler for click to play plugin (vulnerable w/no update)
 #define NS_EVENT_STATE_VULNERABLE_NO_UPDATE NS_DEFINE_EVENT_STATE_MACRO(40)
 // Platform does not support plugin content (some mobile platforms)
 #define NS_EVENT_STATE_TYPE_UNSUPPORTED_PLATFORM NS_DEFINE_EVENT_STATE_MACRO(41)
 // Element is ltr (for :dir pseudo-class)
 #define NS_EVENT_STATE_LTR NS_DEFINE_EVENT_STATE_MACRO(42)
 // Element is rtl (for :dir pseudo-class)
 #define NS_EVENT_STATE_RTL NS_DEFINE_EVENT_STATE_MACRO(43)
-// Handler for play preview plugin
-#define NS_EVENT_STATE_TYPE_PLAY_PREVIEW NS_DEFINE_EVENT_STATE_MACRO(44)
 // Element is highlighted (devtools inspector)
 #define NS_EVENT_STATE_DEVTOOLS_HIGHLIGHTED NS_DEFINE_EVENT_STATE_MACRO(45)
 // Element is an unresolved custom element candidate
 #define NS_EVENT_STATE_UNRESOLVED NS_DEFINE_EVENT_STATE_MACRO(46)
 
 // Event state that is used for values that need to be parsed but do nothing.
 #define NS_EVENT_STATE_IGNORE NS_DEFINE_EVENT_STATE_MACRO(63)
 
--- a/dom/events/IMEStateManager.cpp
+++ b/dom/events/IMEStateManager.cpp
@@ -129,17 +129,17 @@ GetIMEStateSetOpenName(IMEState::Open aO
     case IMEState::CLOSED:
       return "CLOSED";
     default:
       return "illegal value";
   }
 }
 
 static const char*
-GetEventMessageName(uint32_t aMessage)
+GetEventMessageName(EventMessage aMessage)
 {
   switch (aMessage) {
     case NS_COMPOSITION_START:
       return "NS_COMPOSITION_START";
     case NS_COMPOSITION_END:
       return "NS_COMPOSITION_END";
     case NS_COMPOSITION_UPDATE:
       return "NS_COMPOSITION_UPDATE";
--- a/dom/events/InputEvent.cpp
+++ b/dom/events/InputEvent.cpp
@@ -10,17 +10,19 @@
 
 namespace mozilla {
 namespace dom {
 
 InputEvent::InputEvent(EventTarget* aOwner,
                        nsPresContext* aPresContext,
                        InternalEditorInputEvent* aEvent)
   : UIEvent(aOwner, aPresContext,
-            aEvent ? aEvent : new InternalEditorInputEvent(false, 0, nullptr))
+            aEvent ? aEvent :
+                     new InternalEditorInputEvent(false, NS_EVENT_NULL,
+                                                  nullptr))
 {
   NS_ASSERTION(mEvent->mClass == eEditorInputEventClass,
                "event type mismatch");
 
   if (aEvent) {
     mEventIsInternal = false;
   } else {
     mEventIsInternal = true;
--- a/dom/events/InternalMutationEvent.h
+++ b/dom/events/InternalMutationEvent.h
@@ -14,17 +14,17 @@
 
 namespace mozilla {
 
 class InternalMutationEvent : public WidgetEvent
 {
 public:
   virtual InternalMutationEvent* AsMutationEvent() override { return this; }
 
-  InternalMutationEvent(bool aIsTrusted, uint32_t aMessage)
+  InternalMutationEvent(bool aIsTrusted, EventMessage aMessage)
     : WidgetEvent(aIsTrusted, aMessage, eMutationEventClass)
     , mAttrChange(0)
   {
     mFlags.mCancelable = false;
   }
 
   virtual WidgetEvent* Duplicate() const override
   {
--- a/dom/events/KeyboardEvent.cpp
+++ b/dom/events/KeyboardEvent.cpp
@@ -10,17 +10,18 @@
 
 namespace mozilla {
 namespace dom {
 
 KeyboardEvent::KeyboardEvent(EventTarget* aOwner,
                              nsPresContext* aPresContext,
                              WidgetKeyboardEvent* aEvent)
   : UIEvent(aOwner, aPresContext,
-            aEvent ? aEvent : new WidgetKeyboardEvent(false, 0, nullptr))
+            aEvent ? aEvent :
+                     new WidgetKeyboardEvent(false, NS_EVENT_NULL, nullptr))
   , mInitializedByCtor(false)
   , mInitializedWhichValue(0)
 {
   if (aEvent) {
     mEventIsInternal = false;
   }
   else {
     mEventIsInternal = true;
@@ -156,16 +157,18 @@ KeyboardEvent::CharCode()
   case NS_KEY_DOWN:
   case NS_KEY_AFTER_DOWN:
   case NS_KEY_BEFORE_UP:
   case NS_KEY_UP:
   case NS_KEY_AFTER_UP:
     return 0;
   case NS_KEY_PRESS:
     return mEvent->AsKeyboardEvent()->charCode;
+  default:
+    break;
   }
   return 0;
 }
 
 NS_IMETHODIMP
 KeyboardEvent::GetKeyCode(uint32_t* aKeyCode)
 {
   NS_ENSURE_ARG_POINTER(aKeyCode);
@@ -208,16 +211,18 @@ KeyboardEvent::Which()
       //more closely mirror the values that 4.x gave for RETURN and BACKSPACE
       {
         uint32_t keyCode = mEvent->AsKeyboardEvent()->keyCode;
         if (keyCode == NS_VK_RETURN || keyCode == NS_VK_BACK) {
           return keyCode;
         }
         return CharCode();
       }
+    default:
+      break;
   }
 
   return 0;
 }
 
 NS_IMETHODIMP
 KeyboardEvent::GetLocation(uint32_t* aLocation)
 {
--- a/dom/events/MouseEvent.cpp
+++ b/dom/events/MouseEvent.cpp
@@ -12,18 +12,19 @@
 
 namespace mozilla {
 namespace dom {
 
 MouseEvent::MouseEvent(EventTarget* aOwner,
                        nsPresContext* aPresContext,
                        WidgetMouseEventBase* aEvent)
   : UIEvent(aOwner, aPresContext,
-            aEvent ? aEvent : new WidgetMouseEvent(false, 0, nullptr,
-                                                   WidgetMouseEvent::eReal))
+            aEvent ? aEvent :
+                     new WidgetMouseEvent(false, NS_EVENT_NULL, nullptr,
+                                          WidgetMouseEvent::eReal))
 {
   // There's no way to make this class' ctor allocate an WidgetMouseScrollEvent.
   // It's not that important, though, since a scroll event is not a real
   // DOM event.
 
   WidgetMouseEvent* mouseEvent = mEvent->AsMouseEvent();
   if (aEvent) {
     mEventIsInternal = false;
--- a/dom/events/MouseScrollEvent.cpp
+++ b/dom/events/MouseScrollEvent.cpp
@@ -10,17 +10,19 @@
 
 namespace mozilla {
 namespace dom {
 
 MouseScrollEvent::MouseScrollEvent(EventTarget* aOwner,
                                    nsPresContext* aPresContext,
                                    WidgetMouseScrollEvent* aEvent)
   : MouseEvent(aOwner, aPresContext,
-               aEvent ? aEvent : new WidgetMouseScrollEvent(false, 0, nullptr))
+               aEvent ? aEvent :
+                        new WidgetMouseScrollEvent(false, NS_EVENT_NULL,
+                                                   nullptr))
 {
   if (aEvent) {
     mEventIsInternal = false;
   } else {
     mEventIsInternal = true;
     mEvent->time = PR_Now();
     mEvent->refPoint.x = mEvent->refPoint.y = 0;
     static_cast<WidgetMouseEventBase*>(mEvent)->inputSource =
--- a/dom/events/MutationEvent.cpp
+++ b/dom/events/MutationEvent.cpp
@@ -12,17 +12,17 @@ class nsPresContext;
 
 namespace mozilla {
 namespace dom {
 
 MutationEvent::MutationEvent(EventTarget* aOwner,
                              nsPresContext* aPresContext,
                              InternalMutationEvent* aEvent)
   : Event(aOwner, aPresContext,
-          aEvent ? aEvent : new InternalMutationEvent(false, 0))
+          aEvent ? aEvent : new InternalMutationEvent(false, NS_EVENT_NULL))
 {
   mEventIsInternal = (aEvent == nullptr);
 }
 
 NS_INTERFACE_MAP_BEGIN(MutationEvent)
   NS_INTERFACE_MAP_ENTRY(nsIDOMMutationEvent)
 NS_INTERFACE_MAP_END_INHERITING(Event)
 
--- a/dom/events/NotifyPaintEvent.cpp
+++ b/dom/events/NotifyPaintEvent.cpp
@@ -13,22 +13,22 @@
 #include "nsContentUtils.h"
 
 namespace mozilla {
 namespace dom {
 
 NotifyPaintEvent::NotifyPaintEvent(EventTarget* aOwner,
                                    nsPresContext* aPresContext,
                                    WidgetEvent* aEvent,
-                                   uint32_t aEventType,
+                                   EventMessage aEventMessage,
                                    nsInvalidateRequestList* aInvalidateRequests)
   : Event(aOwner, aPresContext, aEvent)
 {
   if (mEvent) {
-    mEvent->mMessage = aEventType;
+    mEvent->mMessage = aEventMessage;
   }
   if (aInvalidateRequests) {
     mInvalidateRequests.AppendElements(Move(aInvalidateRequests->mRequests));
   }
 }
 
 NS_INTERFACE_MAP_BEGIN(NotifyPaintEvent)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNotifyPaintEvent)
@@ -161,16 +161,16 @@ NotifyPaintEvent::Deserialize(const IPC:
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 already_AddRefed<NotifyPaintEvent>
 NS_NewDOMNotifyPaintEvent(EventTarget* aOwner,
                           nsPresContext* aPresContext,
                           WidgetEvent* aEvent,
-                          uint32_t aEventType,
+                          EventMessage aEventMessage,
                           nsInvalidateRequestList* aInvalidateRequests) 
 {
   nsRefPtr<NotifyPaintEvent> it =
-    new NotifyPaintEvent(aOwner, aPresContext, aEvent, aEventType,
+    new NotifyPaintEvent(aOwner, aPresContext, aEvent, aEventMessage,
                          aInvalidateRequests);
   return it.forget();
 }
--- a/dom/events/NotifyPaintEvent.h
+++ b/dom/events/NotifyPaintEvent.h
@@ -23,17 +23,17 @@ class PaintRequestList;
 class NotifyPaintEvent : public Event,
                          public nsIDOMNotifyPaintEvent
 {
 
 public:
   NotifyPaintEvent(EventTarget* aOwner,
                    nsPresContext* aPresContext,
                    WidgetEvent* aEvent,
-                   uint32_t aEventType,
+                   EventMessage aEventMessage,
                    nsInvalidateRequestList* aInvalidateRequests);
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSIDOMNOTIFYPAINTEVENT
 
   // Forward to base class
   NS_FORWARD_TO_EVENT_NO_SERIALIZATION_NO_DUPLICATION
@@ -67,12 +67,14 @@ private:
 } // namespace dom
 } // namespace mozilla
 
 // This empties aInvalidateRequests.
 already_AddRefed<mozilla::dom::NotifyPaintEvent>
 NS_NewDOMNotifyPaintEvent(mozilla::dom::EventTarget* aOwner,
                           nsPresContext* aPresContext,
                           mozilla::WidgetEvent* aEvent,
-                          uint32_t aEventType = 0,
-                          nsInvalidateRequestList* aInvalidateRequests = nullptr);
+                          mozilla::EventMessage aEventMessage =
+                            mozilla::NS_EVENT_NULL,
+                          nsInvalidateRequestList* aInvalidateRequests =
+                            nullptr);
 
 #endif // mozilla_dom_NotifyPaintEvent_h_
--- a/dom/events/PointerEvent.cpp
+++ b/dom/events/PointerEvent.cpp
@@ -12,17 +12,18 @@
 
 namespace mozilla {
 namespace dom {
 
 PointerEvent::PointerEvent(EventTarget* aOwner,
                            nsPresContext* aPresContext,
                            WidgetPointerEvent* aEvent)
   : MouseEvent(aOwner, aPresContext,
-               aEvent ? aEvent : new WidgetPointerEvent(false, 0, nullptr))
+               aEvent ? aEvent :
+                        new WidgetPointerEvent(false, NS_EVENT_NULL, nullptr))
 {
   NS_ASSERTION(mEvent->mClass == ePointerEventClass,
                "event type mismatch ePointerEventClass");
 
   WidgetMouseEvent* mouseEvent = mEvent->AsMouseEvent();
   if (aEvent) {
     mEventIsInternal = false;
   } else {
--- a/dom/events/SimpleGestureEvent.cpp
+++ b/dom/events/SimpleGestureEvent.cpp
@@ -11,17 +11,18 @@
 namespace mozilla {
 namespace dom {
 
 SimpleGestureEvent::SimpleGestureEvent(EventTarget* aOwner,
                                        nsPresContext* aPresContext,
                                        WidgetSimpleGestureEvent* aEvent)
   : MouseEvent(aOwner, aPresContext,
                aEvent ? aEvent :
-                        new WidgetSimpleGestureEvent(false, 0, nullptr))
+                        new WidgetSimpleGestureEvent(false, NS_EVENT_NULL,
+                                                     nullptr))
 {
   NS_ASSERTION(mEvent->mClass == eSimpleGestureEventClass,
                "event type mismatch");
 
   if (aEvent) {
     mEventIsInternal = false;
   } else {
     mEventIsInternal = true;
--- a/dom/events/TextComposition.cpp
+++ b/dom/events/TextComposition.cpp
@@ -95,17 +95,17 @@ TextComposition::MaybeDispatchCompositio
   }
   CloneAndDispatchAs(aCompositionEvent, NS_COMPOSITION_UPDATE);
   return IsValidStateForComposition(aCompositionEvent->widget);
 }
 
 BaseEventFlags
 TextComposition::CloneAndDispatchAs(
                    const WidgetCompositionEvent* aCompositionEvent,
-                   uint32_t aMessage,
+                   EventMessage aMessage,
                    nsEventStatus* aStatus,
                    EventDispatchingCallback* aCallBack)
 {
   MOZ_RELEASE_ASSERT(!mTabParent);
 
   MOZ_ASSERT(IsValidStateForComposition(aCompositionEvent->widget),
              "Should be called only when it's safe to dispatch an event");
 
@@ -432,17 +432,17 @@ TextComposition::NotityUpdateComposition
   } else {
     return;
   }
 
   NotifyIME(NOTIFY_IME_OF_COMPOSITION_UPDATE);
 }
 
 void
-TextComposition::DispatchCompositionEventRunnable(uint32_t aEventMessage,
+TextComposition::DispatchCompositionEventRunnable(EventMessage aEventMessage,
                                                   const nsAString& aData,
                                                   bool aIsSynthesizingCommit)
 {
   nsContentUtils::AddScriptRunner(
     new CompositionEventDispatcher(this, mNode, aEventMessage, aData,
                                    aIsSynthesizingCommit));
 }
 
@@ -580,23 +580,23 @@ TextComposition::HasEditor() const
 
 /******************************************************************************
  * TextComposition::CompositionEventDispatcher
  ******************************************************************************/
 
 TextComposition::CompositionEventDispatcher::CompositionEventDispatcher(
                                                TextComposition* aComposition,
                                                nsINode* aEventTarget,
-                                               uint32_t aEventMessage,
+                                               EventMessage aEventMessage,
                                                const nsAString& aData,
                                                bool aIsSynthesizedEvent)
   : mTextComposition(aComposition)
   , mEventTarget(aEventTarget)
+  , mData(aData)
   , mEventMessage(aEventMessage)
-  , mData(aData)
   , mIsSynthesizedEvent(aIsSynthesizedEvent)
 {
 }
 
 NS_IMETHODIMP
 TextComposition::CompositionEventDispatcher::Run()
 {
   // The widget can be different from the widget which has dispatched
--- a/dom/events/TextComposition.h
+++ b/dom/events/TextComposition.h
@@ -314,17 +314,17 @@ private:
   /**
    * CloneAndDispatchAs() dispatches a composition event which is
    * duplicateed from aCompositionEvent and set the aMessage.
    *
    * @return Returns BaseEventFlags which is the result of dispatched event.
    */
   BaseEventFlags CloneAndDispatchAs(
                    const WidgetCompositionEvent* aCompositionEvent,
-                   uint32_t aMessage,
+                   EventMessage aMessage,
                    nsEventStatus* aStatus = nullptr,
                    EventDispatchingCallback* aCallBack = nullptr);
 
   /**
    * If IME has already dispatched compositionend event but it was discarded
    * by PresShell due to not safe to dispatch, this returns true.
    */
   bool WasNativeCompositionEndEventDiscarded() const
@@ -348,26 +348,26 @@ private:
    * CompositionEventDispatcher dispatches the specified composition (or text)
    * event.
    */
   class CompositionEventDispatcher : public nsRunnable
   {
   public:
     CompositionEventDispatcher(TextComposition* aTextComposition,
                                nsINode* aEventTarget,
-                               uint32_t aEventMessage,
+                               EventMessage aEventMessage,
                                const nsAString& aData,
                                bool aIsSynthesizedEvent = false);
     NS_IMETHOD Run() override;
 
   private:
     nsRefPtr<TextComposition> mTextComposition;
     nsCOMPtr<nsINode> mEventTarget;
-    uint32_t mEventMessage;
     nsString mData;
+    EventMessage mEventMessage;
     bool mIsSynthesizedEvent;
 
     CompositionEventDispatcher() {};
   };
 
   /**
    * DispatchCompositionEventRunnable() dispatches a composition event to the
    * content.  Be aware, if you use this method, nsPresShellEventCB isn't used.
@@ -376,17 +376,17 @@ private:
    *          destroyed by this method call.
    *
    * @param aEventMessage       Must be one of composition events.
    * @param aData               Used for mData value.
    * @param aIsSynthesizingCommit   true if this is called for synthesizing
    *                                commit or cancel composition.  Otherwise,
    *                                false.
    */
-  void DispatchCompositionEventRunnable(uint32_t aEventMessage,
+  void DispatchCompositionEventRunnable(EventMessage aEventMessage,
                                         const nsAString& aData,
                                         bool aIsSynthesizingCommit = false);
 };
 
 /**
  * TextCompositionArray manages the instances of TextComposition class.
  * Managing with array is enough because only one composition is typically
  * there.  Even if user switches native IME context, it's very rare that
--- a/dom/events/TouchEvent.cpp
+++ b/dom/events/TouchEvent.cpp
@@ -58,17 +58,18 @@ TouchList::IdentifiedTouch(int32_t aIden
 /******************************************************************************
  * TouchEvent
  *****************************************************************************/
 
 TouchEvent::TouchEvent(EventTarget* aOwner,
                        nsPresContext* aPresContext,
                        WidgetTouchEvent* aEvent)
   : UIEvent(aOwner, aPresContext,
-            aEvent ? aEvent : new WidgetTouchEvent(false, 0, nullptr))
+            aEvent ? aEvent :
+                     new WidgetTouchEvent(false, NS_EVENT_NULL, nullptr))
 {
   if (aEvent) {
     mEventIsInternal = false;
 
     for (uint32_t i = 0; i < aEvent->touches.Length(); ++i) {
       Touch* touch = aEvent->touches[i];
       touch->InitializePoints(mPresContext, aEvent);
     }
--- a/dom/events/TransitionEvent.cpp
+++ b/dom/events/TransitionEvent.cpp
@@ -10,17 +10,17 @@
 
 namespace mozilla {
 namespace dom {
 
 TransitionEvent::TransitionEvent(EventTarget* aOwner,
                                  nsPresContext* aPresContext,
                                  InternalTransitionEvent* aEvent)
   : Event(aOwner, aPresContext,
-          aEvent ? aEvent : new InternalTransitionEvent(false, 0))
+          aEvent ? aEvent : new InternalTransitionEvent(false, NS_EVENT_NULL))
 {
   if (aEvent) {
     mEventIsInternal = false;
   }
   else {
     mEventIsInternal = true;
     mEvent->time = PR_Now();
   }
--- a/dom/events/UIEvent.cpp
+++ b/dom/events/UIEvent.cpp
@@ -24,17 +24,17 @@
 
 namespace mozilla {
 namespace dom {
 
 UIEvent::UIEvent(EventTarget* aOwner,
                  nsPresContext* aPresContext,
                  WidgetGUIEvent* aEvent)
   : Event(aOwner, aPresContext,
-          aEvent ? aEvent : new InternalUIEvent(false, 0, nullptr))
+          aEvent ? aEvent : new InternalUIEvent(false, NS_EVENT_NULL, nullptr))
   , mClientPoint(0, 0)
   , mLayerPoint(0, 0)
   , mPagePoint(0, 0)
   , mMovementPoint(0, 0)
   , mIsPointerLocked(EventStateManager::sIsPointerLocked)
   , mLastClientPoint(EventStateManager::sLastClientPoint)
 {
   if (aEvent) {
--- a/dom/events/WheelEvent.cpp
+++ b/dom/events/WheelEvent.cpp
@@ -11,17 +11,18 @@
 namespace mozilla {
 namespace dom {
 
 WheelEvent::WheelEvent(EventTarget* aOwner,
                        nsPresContext* aPresContext,
                        WidgetWheelEvent* aWheelEvent)
   : MouseEvent(aOwner, aPresContext,
                aWheelEvent ? aWheelEvent :
-                             new WidgetWheelEvent(false, 0, nullptr))
+                             new WidgetWheelEvent(false, NS_EVENT_NULL,
+                                                  nullptr))
   , mAppUnitsPerDevPixel(0)
 {
   if (aWheelEvent) {
     mEventIsInternal = false;
     // If the delta mode is pixel, the WidgetWheelEvent's delta values are in
     // device pixels.  However, JS contents need the delta values in CSS pixels.
     // We should store the value of mAppUnitsPerDevPixel here because
     // it might be changed by changing zoom or something.
--- a/dom/events/WheelHandlingHelper.cpp
+++ b/dom/events/WheelHandlingHelper.cpp
@@ -213,16 +213,18 @@ WheelTransaction::OnEvent(WidgetEvent* a
     case NS_MOUSE_BUTTON_UP:
     case NS_MOUSE_BUTTON_DOWN:
     case NS_MOUSE_DOUBLECLICK:
     case NS_MOUSE_CLICK:
     case NS_CONTEXTMENU:
     case NS_DRAGDROP_DROP:
       EndTransaction();
       return;
+    default:
+      break;
   }
 }
 
 /* static */ void
 WheelTransaction::Shutdown()
 {
   NS_IF_RELEASE(sTimer);
 }
--- a/dom/events/XULCommandEvent.cpp
+++ b/dom/events/XULCommandEvent.cpp
@@ -9,17 +9,18 @@
 
 namespace mozilla {
 namespace dom {
 
 XULCommandEvent::XULCommandEvent(EventTarget* aOwner,
                                  nsPresContext* aPresContext,
                                  WidgetInputEvent* aEvent)
   : UIEvent(aOwner, aPresContext,
-            aEvent ? aEvent : new WidgetInputEvent(false, 0, nullptr))
+            aEvent ? aEvent :
+                     new WidgetInputEvent(false, NS_EVENT_NULL, nullptr))
 {
   if (aEvent) {
     mEventIsInternal = false;
   }
   else {
     mEventIsInternal = true;
     mEvent->time = PR_Now();
   }
--- a/dom/fetch/Request.cpp
+++ b/dom/fetch/Request.cpp
@@ -11,16 +11,17 @@
 
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/Headers.h"
 #include "mozilla/dom/Fetch.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/URL.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/dom/workers/bindings/URL.h"
+#include "mozilla/unused.h"
 
 #include "WorkerPrivate.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(Request)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(Request)
@@ -76,17 +77,27 @@ GetRequestURLFromDocument(nsIDocument* a
 {
   MOZ_ASSERT(aDocument);
   MOZ_ASSERT(NS_IsMainThread());
 
   nsCOMPtr<nsIURI> baseURI = aDocument->GetBaseURI();
   nsCOMPtr<nsIURI> resolvedURI;
   aRv = NS_NewURI(getter_AddRefs(resolvedURI), aInput, nullptr, baseURI);
   if (NS_WARN_IF(aRv.Failed())) {
-      return;
+    aRv.ThrowTypeError(MSG_INVALID_URL, &aInput);
+    return;
+  }
+
+  // This fails with URIs with weird protocols, even when they are valid,
+  // so we ignore the failure
+  nsAutoCString credentials;
+  unused << resolvedURI->GetUserPass(credentials);
+  if (!credentials.IsEmpty()) {
+    aRv.ThrowTypeError(MSG_URL_HAS_CREDENTIALS, &aInput);
+    return;
   }
 
   nsCOMPtr<nsIURI> resolvedURIClone;
   // We use CloneIgnoringRef to strip away the fragment even if the original URI
   // is immutable.
   aRv = resolvedURI->CloneIgnoringRef(getter_AddRefs(resolvedURIClone));
   if (NS_WARN_IF(aRv.Failed())) {
     return;
@@ -105,16 +116,26 @@ void
 GetRequestURLFromChrome(const nsAString& aInput, nsAString& aRequestURL,
                         ErrorResult& aRv)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsCOMPtr<nsIURI> uri;
   aRv = NS_NewURI(getter_AddRefs(uri), aInput, nullptr, nullptr);
   if (NS_WARN_IF(aRv.Failed())) {
+    aRv.ThrowTypeError(MSG_INVALID_URL, &aInput);
+    return;
+  }
+
+  // This fails with URIs with weird protocols, even when they are valid,
+  // so we ignore the failure
+  nsAutoCString credentials;
+  unused << uri->GetUserPass(credentials);
+  if (!credentials.IsEmpty()) {
+    aRv.ThrowTypeError(MSG_URL_HAS_CREDENTIALS, &aInput);
     return;
   }
 
   nsCOMPtr<nsIURI> uriClone;
   // We use CloneIgnoringRef to strip away the fragment even if the original URI
   // is immutable.
   aRv = uri->CloneIgnoringRef(getter_AddRefs(uriClone));
   if (NS_WARN_IF(aRv.Failed())) {
@@ -137,16 +158,34 @@ GetRequestURLFromWorker(const GlobalObje
   workers::WorkerPrivate* worker = workers::GetCurrentThreadWorkerPrivate();
   MOZ_ASSERT(worker);
   worker->AssertIsOnWorkerThread();
 
   NS_ConvertUTF8toUTF16 baseURL(worker->GetLocationInfo().mHref);
   nsRefPtr<workers::URL> url =
     workers::URL::Constructor(aGlobal, aInput, baseURL, aRv);
   if (NS_WARN_IF(aRv.Failed())) {
+    aRv.ThrowTypeError(MSG_INVALID_URL, &aInput);
+    return;
+  }
+
+  nsString username;
+  url->GetUsername(username, aRv);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return;
+  }
+
+  nsString password;
+  url->GetPassword(password, aRv);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return;
+  }
+
+  if (!username.IsEmpty() || !password.IsEmpty()) {
+    aRv.ThrowTypeError(MSG_URL_HAS_CREDENTIALS, &aInput);
     return;
   }
 
   url->SetHash(EmptyString(), aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
 
--- a/dom/html/HTMLButtonElement.cpp
+++ b/dom/html/HTMLButtonElement.cpp
@@ -195,17 +195,17 @@ HTMLButtonElement::ParseAttribute(int32_
     }
   }
 
   return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
                                               aResult);
 }
 
 bool
-HTMLButtonElement::IsDisabledForEvents(uint32_t aMessage)
+HTMLButtonElement::IsDisabledForEvents(EventMessage aMessage)
 {
   nsIFormControlFrame* formControlFrame = GetFormControlFrame(false);
   nsIFrame* formFrame = do_QueryFrame(formControlFrame);
   return IsElementDisabledForEvents(aMessage, formFrame);
 }
 
 nsresult
 HTMLButtonElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
--- a/dom/html/HTMLButtonElement.h
+++ b/dom/html/HTMLButtonElement.h
@@ -47,17 +47,17 @@ public:
   NS_DECL_NSIDOMHTMLBUTTONELEMENT
 
   // overriden nsIFormControl methods
   NS_IMETHOD_(uint32_t) GetType() const override { return mType; }
   NS_IMETHOD Reset() override;
   NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission) override;
   NS_IMETHOD SaveState() override;
   bool RestoreState(nsPresState* aState) override;
-  virtual bool IsDisabledForEvents(uint32_t aMessage) override;
+  virtual bool IsDisabledForEvents(EventMessage aMessage) override;
 
   virtual void FieldSetDisabledChanged(bool aNotify) override;
 
   // nsIDOMEventTarget
   virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) override;
   virtual nsresult PostHandleEvent(
                      EventChainPostVisitor& aVisitor) override;
 
--- a/dom/html/HTMLFieldSetElement.cpp
+++ b/dom/html/HTMLFieldSetElement.cpp
@@ -58,17 +58,17 @@ NS_IMPL_ELEMENT_CLONE(HTMLFieldSetElemen
 
 NS_IMPL_BOOL_ATTR(HTMLFieldSetElement, Disabled, disabled)
 NS_IMPL_STRING_ATTR(HTMLFieldSetElement, Name, name)
 
 // nsIConstraintValidation
 NS_IMPL_NSICONSTRAINTVALIDATION(HTMLFieldSetElement)
 
 bool
-HTMLFieldSetElement::IsDisabledForEvents(uint32_t aMessage)
+HTMLFieldSetElement::IsDisabledForEvents(EventMessage aMessage)
 {
   return IsElementDisabledForEvents(aMessage, nullptr);
 }
 
 // nsIContent
 nsresult
 HTMLFieldSetElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
 {
--- a/dom/html/HTMLFieldSetElement.h
+++ b/dom/html/HTMLFieldSetElement.h
@@ -46,17 +46,17 @@ public:
   virtual nsresult InsertChildAt(nsIContent* aChild, uint32_t aIndex,
                                      bool aNotify) override;
   virtual void RemoveChildAt(uint32_t aIndex, bool aNotify) override;
 
   // nsIFormControl
   NS_IMETHOD_(uint32_t) GetType() const override { return NS_FORM_FIELDSET; }
   NS_IMETHOD Reset() override;
   NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission) override;
-  virtual bool IsDisabledForEvents(uint32_t aMessage) override;
+  virtual bool IsDisabledForEvents(EventMessage aMessage) override;
   virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;
 
   const nsIContent* GetFirstLegend() const { return mFirstLegend; }
 
   void AddElement(nsGenericHTMLFormElement* aElement);
 
   void RemoveElement(nsGenericHTMLFormElement* aElement);
 
--- a/dom/html/HTMLFormElement.cpp
+++ b/dom/html/HTMLFormElement.cpp
@@ -530,17 +530,17 @@ HTMLFormElement::WillHandleEvent(EventCh
   }
   return NS_OK;
 }
 
 nsresult
 HTMLFormElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
 {
   if (aVisitor.mEvent->originalTarget == static_cast<nsIContent*>(this)) {
-    uint32_t msg = aVisitor.mEvent->mMessage;
+    EventMessage msg = aVisitor.mEvent->mMessage;
     if (msg == NS_FORM_SUBMIT) {
       // let the form know not to defer subsequent submissions
       mDeferSubmission = false;
     }
 
     if (aVisitor.mEventStatus == nsEventStatus_eIgnore) {
       switch (msg) {
         case NS_FORM_RESET:
@@ -550,18 +550,20 @@ HTMLFormElement::PostHandleEvent(EventCh
             // tell the form to forget a possible pending submission.
             // the reason is that the script returned true (the event was
             // ignored) so if there is a stored submission, it will miss
             // the name/value of the submitting element, thus we need
             // to forget it and the form element will build a new one
             mPendingSubmission = nullptr;
           }
           DoSubmitOrReset(aVisitor.mEvent, msg);
+          break;
         }
-        break;
+        default:
+          break;
       }
     } else {
       if (msg == NS_FORM_SUBMIT) {
         // tell the form to flush a possible pending submission.
         // the reason is that the script returned false (the event was
         // not ignored) so if there is a stored submission, it needs to
         // be submitted immediatelly.
         FlushPendingSubmission();
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -3035,17 +3035,17 @@ HTMLInputElement::NeedToInitializeEditor
   case NS_SCROLLPORT_OVERFLOW:
     return false;
   default:
     return true;
   }
 }
 
 bool
-HTMLInputElement::IsDisabledForEvents(uint32_t aMessage)
+HTMLInputElement::IsDisabledForEvents(EventMessage aMessage)
 {
   return IsElementDisabledForEvents(aMessage, GetPrimaryFrame());
 }
 
 nsresult
 HTMLInputElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
 {
   // Do not process any DOM events if the element is disabled
@@ -3657,16 +3657,18 @@ HTMLInputElement::PostHandleEvent(EventC
         if (mForm) {
           // tell the form that we are about to exit a click handler
           // so the form knows not to defer subsequent submissions
           // the pending ones that were created during the handler
           // will be flushed or forgoten.
           mForm->OnSubmitClickEnd();
         }
         break;
+      default:
+        break;
     }
   }
 
   // Reset the flag for other content besides this text field
   aVisitor.mEvent->mFlags.mNoContentDispatch = noContentDispatch;
 
   // now check to see if the event was "cancelled"
   if (mCheckedIsToggled && outerActivateEvent) {
@@ -4151,16 +4153,19 @@ HTMLInputElement::PostHandleEventForRang
       }
       break;
 
     case NS_TOUCH_CANCEL:
       if (mIsDraggingRange) {
         CancelRangeThumbDrag();
       }
       break;
+
+    default:
+      break;
   }
 }
 
 void
 HTMLInputElement::MaybeLoadImage()
 {
   // Our base URI may have changed; claim that our URI changed, and the
   // nsImageLoadingContent will decide whether a new image load is warranted.
--- a/dom/html/HTMLInputElement.h
+++ b/dom/html/HTMLInputElement.h
@@ -144,17 +144,17 @@ public:
 
   // Overriden nsIFormControl methods
   NS_IMETHOD_(uint32_t) GetType() const override { return mType; }
   NS_IMETHOD Reset() override;
   NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission) override;
   NS_IMETHOD SaveState() override;
   virtual bool RestoreState(nsPresState* aState) override;
   virtual bool AllowDrop() override;
-  virtual bool IsDisabledForEvents(uint32_t aMessage) override;
+  virtual bool IsDisabledForEvents(EventMessage aMessage) override;
 
   virtual void FieldSetDisabledChanged(bool aNotify) override;
 
   // nsIContent
   virtual bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, int32_t *aTabIndex) override;
 
   virtual bool ParseAttribute(int32_t aNamespaceID,
                                 nsIAtom* aAttribute,
--- a/dom/html/HTMLLabelElement.cpp
+++ b/dom/html/HTMLLabelElement.cpp
@@ -192,16 +192,19 @@ HTMLLabelElement::PostHandleEvent(EventC
           eventFlags.mMultipleActionsPrevented = true;
           DispatchClickEvent(aVisitor.mPresContext, mouseEvent,
                              content, false, &eventFlags, &status);
           // Do we care about the status this returned?  I don't think we do...
           // Don't run another <label> off of this click
           mouseEvent->mFlags.mMultipleActionsPrevented = true;
         }
         break;
+
+      default:
+        break;
     }
     mHandlingEvent = false;
   }
   return NS_OK;
 }
 
 nsresult
 HTMLLabelElement::Reset()
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -2329,17 +2329,16 @@ HTMLMediaElement::WakeLockCreate()
 }
 
 void
 HTMLMediaElement::WakeLockRelease()
 {
   if (mWakeLock) {
     ErrorResult rv;
     mWakeLock->Unlock(rv);
-    NS_WARN_IF_FALSE(!rv.Failed(), "Failed to unlock the wakelock.");
     mWakeLock = nullptr;
   }
 }
 
 bool HTMLMediaElement::ParseAttribute(int32_t aNamespaceID,
                                       nsIAtom* aAttribute,
                                       const nsAString& aValue,
                                       nsAttrValue& aResult)
--- a/dom/html/HTMLMetaElement.cpp
+++ b/dom/html/HTMLMetaElement.cpp
@@ -51,16 +51,23 @@ HTMLMetaElement::SetItemValueText(const 
 
 nsresult
 HTMLMetaElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                               const nsAttrValue* aValue, bool aNotify)
 {
   if (aNameSpaceID == kNameSpaceID_None) {
     if (aName == nsGkAtoms::content) {
       nsIDocument *document = GetUncomposedDoc();
+      if (document && AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
+                                  nsGkAtoms::viewport, eIgnoreCase)) {
+        nsAutoString content;
+        nsresult rv = GetContent(content);
+        NS_ENSURE_SUCCESS(rv, rv);
+        nsContentUtils::ProcessViewportInfo(document, content);
+      }
       CreateAndDispatchEvent(document, NS_LITERAL_STRING("DOMMetaChanged"));
     }
   }
 
   return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue,
                                             aNotify);
 }
 
--- a/dom/html/HTMLObjectElement.cpp
+++ b/dom/html/HTMLObjectElement.cpp
@@ -219,16 +219,18 @@ HTMLObjectElement::HandleFocusBlurPlugin
     case NS_FOCUS_CONTENT: {
       OnFocusBlurPlugin(aElement, true);
       break;
     }
     case NS_BLUR_CONTENT: {
       OnFocusBlurPlugin(aElement, false);
       break;
     }
+    default:
+      break;
   }
 }
 
 NS_IMETHODIMP
 HTMLObjectElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
 {
   HandleFocusBlurPlugin(this, aVisitor.mEvent);
   return NS_OK;
--- a/dom/html/HTMLSelectElement.cpp
+++ b/dom/html/HTMLSelectElement.cpp
@@ -1482,17 +1482,17 @@ HTMLSelectElement::IsAttributeMapped(con
 
 nsMapRuleToAttributesFunc
 HTMLSelectElement::GetAttributeMappingFunction() const
 {
   return &MapAttributesIntoRule;
 }
 
 bool
-HTMLSelectElement::IsDisabledForEvents(uint32_t aMessage)
+HTMLSelectElement::IsDisabledForEvents(EventMessage aMessage)
 {
   nsIFormControlFrame* formControlFrame = GetFormControlFrame(false);
   nsIFrame* formFrame = nullptr;
   if (formControlFrame) {
     formFrame = do_QueryFrame(formControlFrame);
   }
   return IsElementDisabledForEvents(aMessage, formFrame);
 }
--- a/dom/html/HTMLSelectElement.h
+++ b/dom/html/HTMLSelectElement.h
@@ -286,17 +286,17 @@ public:
   virtual void RemoveChildAt(uint32_t aIndex, bool aNotify) override;
 
   // Overriden nsIFormControl methods
   NS_IMETHOD_(uint32_t) GetType() const override { return NS_FORM_SELECT; }
   NS_IMETHOD Reset() override;
   NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission) override;
   NS_IMETHOD SaveState() override;
   virtual bool RestoreState(nsPresState* aState) override;
-  virtual bool IsDisabledForEvents(uint32_t aMessage) override;
+  virtual bool IsDisabledForEvents(EventMessage aMessage) override;
 
   virtual void FieldSetDisabledChanged(bool aNotify) override;
 
   EventStates IntrinsicState() const override;
 
   /**
    * To be called when stuff is added under a child of the select--but *before*
    * they are actually added.
--- a/dom/html/HTMLTextAreaElement.cpp
+++ b/dom/html/HTMLTextAreaElement.cpp
@@ -464,17 +464,17 @@ HTMLTextAreaElement::IsAttributeMapped(c
 
 nsMapRuleToAttributesFunc
 HTMLTextAreaElement::GetAttributeMappingFunction() const
 {
   return &MapAttributesIntoRule;
 }
 
 bool
-HTMLTextAreaElement::IsDisabledForEvents(uint32_t aMessage)
+HTMLTextAreaElement::IsDisabledForEvents(EventMessage aMessage)
 {
   nsIFormControlFrame* formControlFrame = GetFormControlFrame(false);
   nsIFrame* formFrame = do_QueryFrame(formControlFrame);
   return IsElementDisabledForEvents(aMessage, formFrame);
 }
 
 nsresult
 HTMLTextAreaElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
--- a/dom/html/HTMLTextAreaElement.h
+++ b/dom/html/HTMLTextAreaElement.h
@@ -70,17 +70,17 @@ public:
   NS_IMETHOD SetUserInput(const nsAString& aInput) override;
 
   // nsIFormControl
   NS_IMETHOD_(uint32_t) GetType() const override { return NS_FORM_TEXTAREA; }
   NS_IMETHOD Reset() override;
   NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission) override;
   NS_IMETHOD SaveState() override;
   virtual bool RestoreState(nsPresState* aState) override;
-  virtual bool IsDisabledForEvents(uint32_t aMessage) override;
+  virtual bool IsDisabledForEvents(EventMessage aMessage) override;
 
   virtual void FieldSetDisabledChanged(bool aNotify) override;
 
   virtual EventStates IntrinsicState() const override;
 
   // nsITextControlElemet
   NS_IMETHOD SetValueChanged(bool aValueChanged) override;
   NS_IMETHOD_(bool) IsSingleLineTextControl() const override;
--- a/dom/html/HTMLVideoElement.cpp
+++ b/dom/html/HTMLVideoElement.cpp
@@ -248,17 +248,16 @@ HTMLVideoElement::WakeLockRelease()
 void
 HTMLVideoElement::UpdateScreenWakeLock()
 {
   bool hidden = OwnerDoc()->Hidden();
 
   if (mScreenWakeLock && (mPaused || hidden)) {
     ErrorResult rv;
     mScreenWakeLock->Unlock(rv);
-    NS_WARN_IF_FALSE(!rv.Failed(), "Failed to unlock the wakelock.");
     mScreenWakeLock = nullptr;
     return;
   }
 
   if (!mScreenWakeLock && !mPaused && !hidden && HasVideo()) {
     nsRefPtr<power::PowerManagerService> pmService =
       power::PowerManagerService::GetInstance();
     NS_ENSURE_TRUE_VOID(pmService);
--- a/dom/html/nsGenericHTMLElement.cpp
+++ b/dom/html/nsGenericHTMLElement.cpp
@@ -2264,16 +2264,18 @@ nsGenericHTMLFormElement::PreHandleEvent
       }
       case NS_BLUR_CONTENT:
       {
         nsIFormControlFrame* formControlFrame = GetFormControlFrame(true);
         if (formControlFrame)
           formControlFrame->SetFocus(false, false);
         break;
       }
+      default:
+        break;
     }
   }
 
   return nsGenericHTMLElement::PreHandleEvent(aVisitor);
 }
 
 /* virtual */
 bool
@@ -2449,18 +2451,18 @@ nsGenericHTMLFormElement::FormIdUpdated(
   NS_ASSERTION(element->IsHTMLElement(), "aData should be an HTML element");
 
   element->UpdateFormOwner(false, aNewElement);
 
   return true;
 }
 
 bool 
-nsGenericHTMLFormElement::IsElementDisabledForEvents(uint32_t aMessage, 
-                                                    nsIFrame* aFrame)
+nsGenericHTMLFormElement::IsElementDisabledForEvents(EventMessage aMessage,
+                                                     nsIFrame* aFrame)
 {
   bool disabled = IsDisabled();
   if (!disabled && aFrame) {
     const nsStyleUserInterface* uiStyle = aFrame->StyleUserInterface();
     disabled = uiStyle->mUserInput == NS_STYLE_USER_INPUT_NONE ||
       uiStyle->mUserInput == NS_STYLE_USER_INPUT_DISABLED;
 
   }
--- a/dom/html/nsGenericHTMLElement.h
+++ b/dom/html/nsGenericHTMLElement.h
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef nsGenericHTMLElement_h___
 #define nsGenericHTMLElement_h___
 
 #include "mozilla/Attributes.h"
+#include "mozilla/EventForwards.h"
 #include "nsMappedAttributeElement.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsNameSpaceManager.h"  // for kNameSpaceID_None
 #include "nsIFormControl.h"
 #include "nsGkAtoms.h"
 #include "nsContentCreatorFunctions.h"
 #include "mozilla/ErrorResult.h"
 #include "nsIDOMHTMLMenuElement.h"
@@ -1403,17 +1404,18 @@ protected:
    * This method is a a callback for IDTargetObserver (from nsIDocument).
    * It will be called each time the element associated with the id in @form
    * changes.
    */
   static bool FormIdUpdated(Element* aOldElement, Element* aNewElement,
                               void* aData);
 
   // Returns true if the event should not be handled from PreHandleEvent
-  bool IsElementDisabledForEvents(uint32_t aMessage, nsIFrame* aFrame);
+  bool IsElementDisabledForEvents(mozilla::EventMessage aMessage,
+                                  nsIFrame* aFrame);
 
   // The focusability state of this form control.  eUnfocusable means that it
   // shouldn't be focused at all, eInactiveWindow means it's in an inactive
   // window, eActiveWindow means it's in an active window.
   enum FocusTristate {
     eUnfocusable,
     eInactiveWindow,
     eActiveWindow
--- a/dom/html/nsIFormControl.h
+++ b/dom/html/nsIFormControl.h
@@ -1,17 +1,19 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef nsIFormControl_h___
 #define nsIFormControl_h___
 
+#include "mozilla/EventForwards.h"
 #include "nsISupports.h"
+
 class nsIDOMHTMLFormElement;
 class nsPresState;
 class nsFormSubmission;
 
 namespace mozilla {
 namespace dom {
 class Element;
 class HTMLFieldSetElement;
@@ -190,17 +192,17 @@ public:
   inline bool IsSubmittableControl() const;
 
   /**
    * Returns whether this form control can have draggable children.
    * @return whether this form control can have draggable children.
    */
   inline bool AllowDraggableChildren() const;
 
-  virtual bool IsDisabledForEvents(uint32_t aMessage)
+  virtual bool IsDisabledForEvents(mozilla::EventMessage aMessage)
   {
     return false;
   }
 protected:
 
   /**
    * Returns whether mType corresponds to a single line text control type.
    * @param aExcludePassword to have NS_FORM_INPUT_PASSWORD ignored.
--- a/dom/indexedDB/IDBTransaction.cpp
+++ b/dom/indexedDB/IDBTransaction.cpp
@@ -849,17 +849,17 @@ DOMError*
 IDBTransaction::GetError() const
 {
   AssertIsOnOwningThread();
 
   return mError;
 }
 
 already_AddRefed<DOMStringList>
-IDBTransaction::ObjectStoreNames()
+IDBTransaction::ObjectStoreNames() const
 {
   AssertIsOnOwningThread();
 
   if (mMode == IDBTransaction::VERSION_CHANGE) {
     return mDatabase->ObjectStoreNames();
   }
 
   nsRefPtr<DOMStringList> list = new DOMStringList();
--- a/dom/indexedDB/IDBTransaction.h
+++ b/dom/indexedDB/IDBTransaction.h
@@ -276,17 +276,17 @@ public:
   void
   Abort(ErrorResult& aRv);
 
   IMPL_EVENT_HANDLER(abort)
   IMPL_EVENT_HANDLER(complete)
   IMPL_EVENT_HANDLER(error)
 
   already_AddRefed<DOMStringList>
-  ObjectStoreNames();
+  ObjectStoreNames() const;
 
   void
   FireCompleteOrAbortEvents(nsresult aResult);
 
   // Only for VERSION_CHANGE transactions.
   int64_t
   NextObjectStoreId();
 
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -1086,18 +1086,16 @@ interface nsIDOMWindowUtils : nsISupport
   nsIQueryContentEventResult sendQueryContentEvent(
                                in unsigned long aType,
                                in unsigned long aOffset,
                                in unsigned long aLength,
                                in long aX,
                                in long aY,
                                [optional] in unsigned long aAdditionalFlags);
 
-  // NOTE: following values are same as NS_QUERY_* in BasicEvents.h
-
   /**
    * QUERY_SELECTED_TEXT queries the first selection range's information.
    *
    * @param aOffset   Not used.
    * @param aLength   Not used.
    * @param aX        Not used.
    * @param aY        Not used.
    *
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -60,16 +60,17 @@ using mozilla::CSSToScreenScale from "Un
 using mozilla::CommandInt from "mozilla/EventForwards.h";
 using mozilla::Modifiers from "mozilla/EventForwards.h";
 using mozilla::layers::GeckoContentController::APZStateChange from "mozilla/layers/GeckoContentController.h";
 using mozilla::WritingMode from "mozilla/WritingModes.h";
 using mozilla::layers::TouchBehaviorFlags from "mozilla/layers/APZUtils.h";
 using nsIWidget::TouchPointerState from "nsIWidget.h";
 using struct LookAndFeelInt from "mozilla/widget/WidgetMessageUtils.h";
 using struct mozilla::OwningSerializedStructuredCloneBuffer from "ipc/IPCMessageUtils.h";
+using mozilla::EventMessage from "mozilla/EventForwards.h";
 using nsEventStatus from "mozilla/EventForwards.h";
 
 namespace mozilla {
 namespace dom {
 
 struct NativeKeyBinding
 {
   CommandInt[] singleLineCommands;
@@ -271,17 +272,17 @@ parent:
 
     /**
      * OnEventNeedingAckHandled() is called after a child process dispatches a
      * composition event or a selection event which is sent from the parent
      * process.
      *
      * message      The message value of the handled event.
      */
-    prio(urgent) async OnEventNeedingAckHandled(uint32_t message);
+    prio(urgent) async OnEventNeedingAckHandled(EventMessage message);
 
     /**
      * Tells chrome to start plugin IME.  If this results in a string getting
      * committed, the result is in aCommitted (otherwise aCommitted is empty).
      *
      * aKeyboardEvent     The event with which plugin IME is to be started
      * panelX and panelY  Location in screen coordinates of the IME input panel
      *                    (should be just under the plugin)
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -2105,17 +2105,17 @@ TabParent::RecvNotifyIMEPositionChange(c
     widget->GetIMEUpdatePreference();
   if (updatePreference.WantPositionChanged()) {
     mContentCache.MaybeNotifyIME(widget, aIMENotification);
   }
   return true;
 }
 
 bool
-TabParent::RecvOnEventNeedingAckHandled(const uint32_t& aMessage)
+TabParent::RecvOnEventNeedingAckHandled(const EventMessage& aMessage)
 {
   // This is called when the child process receives WidgetCompositionEvent or
   // WidgetSelectionEvent.
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget) {
     return true;
   }
 
@@ -2886,18 +2886,18 @@ TabParent::InjectTouchEvent(const nsAStr
                             int32_t* aYs,
                             uint32_t* aRxs,
                             uint32_t* aRys,
                             float* aRotationAngles,
                             float* aForces,
                             uint32_t aCount,
                             int32_t aModifiers)
 {
-  uint32_t msg;
-  nsContentUtils::GetEventIdAndAtom(aType, eTouchEventClass, &msg);
+  EventMessage msg;
+  nsContentUtils::GetEventMessageAndAtom(aType, eTouchEventClass, &msg);
   if (msg != NS_TOUCH_START && msg != NS_TOUCH_MOVE &&
       msg != NS_TOUCH_END && msg != NS_TOUCH_CANCEL) {
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget) {
     return NS_ERROR_FAILURE;
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -174,17 +174,17 @@ public:
                                                 const widget::IMENotification& aEventMessage) override;
     virtual bool RecvNotifyIMESelection(const ContentCache& aContentCache,
                                         const widget::IMENotification& aEventMessage) override;
     virtual bool RecvUpdateContentCache(const ContentCache& aContentCache) override;
     virtual bool RecvNotifyIMEMouseButtonEvent(const widget::IMENotification& aEventMessage,
                                                bool* aConsumedByIME) override;
     virtual bool RecvNotifyIMEPositionChange(const ContentCache& aContentCache,
                                              const widget::IMENotification& aEventMessage) override;
-    virtual bool RecvOnEventNeedingAckHandled(const uint32_t& aMessage) override;
+    virtual bool RecvOnEventNeedingAckHandled(const EventMessage& aMessage) override;
     virtual bool RecvEndIMEComposition(const bool& aCancel,
                                        bool* aNoCompositionEvent,
                                        nsString* aComposition) override;
     virtual bool RecvStartPluginIME(const WidgetKeyboardEvent& aKeyboardEvent,
                                     const int32_t& aPanelX,
                                     const int32_t& aPanelY,
                                     nsString* aCommitted) override;
     virtual bool RecvSetPluginFocused(const bool& aFocused) override;
--- a/dom/media/MediaDecoderReader.cpp
+++ b/dom/media/MediaDecoderReader.cpp
@@ -295,18 +295,17 @@ public:
   }
 
   NS_METHOD Run()
   {
     MOZ_ASSERT(mReader->OnTaskQueue());
 
     // Make sure ResetDecode hasn't been called in the mean time.
     if (!mReader->mBaseVideoPromise.IsEmpty()) {
-      mReader->RequestVideoData(/* aSkip = */ true, mTimeThreshold,
-                                /* aForceDecodeAhead = */ false);
+      mReader->RequestVideoData(/* aSkip = */ true, mTimeThreshold);
     }
 
     return NS_OK;
   }
 
 private:
   nsRefPtr<MediaDecoderReader> mReader;
   const int64_t mTimeThreshold;
@@ -333,18 +332,17 @@ public:
   }
 
 private:
   nsRefPtr<MediaDecoderReader> mReader;
 };
 
 nsRefPtr<MediaDecoderReader::VideoDataPromise>
 MediaDecoderReader::RequestVideoData(bool aSkipToNextKeyframe,
-                                     int64_t aTimeThreshold,
-                                     bool aForceDecodeAhead)
+                                     int64_t aTimeThreshold)
 {
   nsRefPtr<VideoDataPromise> p = mBaseVideoPromise.Ensure(__func__);
   bool skip = aSkipToNextKeyframe;
   while (VideoQueue().GetSize() == 0 &&
          !VideoQueue().IsFinished()) {
     if (!DecodeVideoFrame(skip, aTimeThreshold)) {
       VideoQueue().Finish();
     } else if (skip) {
--- a/dom/media/MediaDecoderReader.h
+++ b/dom/media/MediaDecoderReader.h
@@ -143,17 +143,17 @@ public:
 
   // Requests one video sample from the reader.
   //
   // Don't hold the decoder monitor while calling this, as the implementation
   // may try to wait on something that needs the monitor and deadlock.
   // If aSkipToKeyframe is true, the decode should skip ahead to the
   // the next keyframe at or after aTimeThreshold microseconds.
   virtual nsRefPtr<VideoDataPromise>
-  RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThreshold, bool aForceDecodeAhead);
+  RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThreshold);
 
   friend class ReRequestVideoWithSkipTask;
   friend class ReRequestAudioTask;
 
   // By default, the state machine polls the reader once per second when it's
   // in buffering mode. Some readers support a promise-based mechanism by which
   // they notify the state machine when the data arrives.
   virtual bool IsWaitForDataSupported() { return false; }
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -166,17 +166,16 @@ static TimeDuration UsecsToDuration(int6
 }
 
 static int64_t DurationToUsecs(TimeDuration aDuration) {
   return static_cast<int64_t>(aDuration.ToSeconds() * USECS_PER_S);
 }
 
 static const uint32_t MIN_VIDEO_QUEUE_SIZE = 3;
 static const uint32_t MAX_VIDEO_QUEUE_SIZE = 10;
-static const uint32_t SCARCE_VIDEO_QUEUE_SIZE = 1;
 static const uint32_t VIDEO_QUEUE_SEND_TO_COMPOSITOR_SIZE = 9999;
 
 static uint32_t sVideoQueueDefaultSize = MAX_VIDEO_QUEUE_SIZE;
 static uint32_t sVideoQueueHWAccelSize = MIN_VIDEO_QUEUE_SIZE;
 static uint32_t sVideoQueueSendToCompositorSize = VIDEO_QUEUE_SEND_TO_COMPOSITOR_SIZE;
 
 MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
                                                    MediaDecoderReader* aReader,
@@ -1705,36 +1704,34 @@ MediaDecoderStateMachine::RequestVideoDa
   // Time the video decode, so that if it's slow, we can increase our low
   // audio threshold to reduce the chance of an audio underrun while we're
   // waiting for a video decode to complete.
   mVideoDecodeStartTime = TimeStamp::Now();
 
   bool skipToNextKeyFrame = mSentFirstFrameLoadedEvent &&
     NeedToSkipToNextKeyframe();
   int64_t currentTime = mState == DECODER_STATE_SEEKING ? 0 : GetMediaTime();
-  bool forceDecodeAhead = mSentFirstFrameLoadedEvent && !IsSeeking() &&
-    static_cast<uint32_t>(VideoQueue().GetSize()) <= SCARCE_VIDEO_QUEUE_SIZE;
 
   SAMPLE_LOG("Queueing video task - queued=%i, decoder-queued=%o, skip=%i, time=%lld",
              VideoQueue().GetSize(), mReader->SizeOfVideoQueueInFrames(), skipToNextKeyFrame,
              currentTime);
 
   if (mSentFirstFrameLoadedEvent) {
     mVideoDataRequest.Begin(
       InvokeAsync(DecodeTaskQueue(), mReader.get(), __func__,
                   &MediaDecoderReader::RequestVideoData,
-                  skipToNextKeyFrame, currentTime, forceDecodeAhead)
+                  skipToNextKeyFrame, currentTime)
       ->Then(OwnerThread(), __func__, this,
              &MediaDecoderStateMachine::OnVideoDecoded,
              &MediaDecoderStateMachine::OnVideoNotDecoded));
   } else {
     mVideoDataRequest.Begin(
       InvokeAsync(DecodeTaskQueue(), mReader.get(), __func__,
                   &MediaDecoderReader::RequestVideoData,
-                  skipToNextKeyFrame, currentTime, forceDecodeAhead)
+                  skipToNextKeyFrame, currentTime)
       ->Then(OwnerThread(), __func__, mStartTimeRendezvous.get(),
              &StartTimeRendezvous::ProcessFirstSample<VideoDataPromise>,
              &StartTimeRendezvous::FirstSampleRejected<VideoData>)
       ->CompletionPromise()
       ->Then(OwnerThread(), __func__, this,
              &MediaDecoderStateMachine::OnVideoDecoded,
              &MediaDecoderStateMachine::OnVideoNotDecoded));
   }
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -305,27 +305,33 @@ MediaFormatReader::OnDemuxerInitDone(nsr
 
   // To decode, we need valid video and a place to put it.
   bool videoActive = !!mDemuxer->GetNumberTracks(TrackInfo::kVideoTrack) &&
     mDecoder->GetImageContainer();
 
   if (videoActive) {
     // We currently only handle the first video track.
     mVideo.mTrackDemuxer = mDemuxer->GetTrackDemuxer(TrackInfo::kVideoTrack, 0);
-    MOZ_ASSERT(mVideo.mTrackDemuxer);
+    if (!mVideo.mTrackDemuxer) {
+      mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
+      return;
+    }
     mInfo.mVideo = *mVideo.mTrackDemuxer->GetInfo()->GetAsVideoInfo();
     mVideo.mCallback = new DecoderCallback(this, TrackInfo::kVideoTrack);
     mVideo.mTimeRanges = mVideo.mTrackDemuxer->GetBuffered();
     mTrackDemuxersMayBlock |= mVideo.mTrackDemuxer->GetSamplesMayBlock();
   }
 
   bool audioActive = !!mDemuxer->GetNumberTracks(TrackInfo::kAudioTrack);
   if (audioActive) {
     mAudio.mTrackDemuxer = mDemuxer->GetTrackDemuxer(TrackInfo::kAudioTrack, 0);
-    MOZ_ASSERT(mAudio.mTrackDemuxer);
+    if (!mAudio.mTrackDemuxer) {
+      mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
+      return;
+    }
     mInfo.mAudio = *mAudio.mTrackDemuxer->GetInfo()->GetAsAudioInfo();
     mAudio.mCallback = new DecoderCallback(this, TrackInfo::kAudioTrack);
     mAudio.mTimeRanges = mAudio.mTrackDemuxer->GetBuffered();
     mTrackDemuxersMayBlock |= mAudio.mTrackDemuxer->GetSamplesMayBlock();
   }
 
   UniquePtr<EncryptionInfo> crypto = mDemuxer->GetCrypto();
 
@@ -366,22 +372,28 @@ MediaFormatReader::OnDemuxerInitDone(nsr
 
   if (!videoActive && !audioActive) {
     mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
     return;
   }
   if (videoActive) {
     mVideoTrackDemuxer =
       mMainThreadDemuxer->GetTrackDemuxer(TrackInfo::kVideoTrack, 0);
-    MOZ_ASSERT(mVideoTrackDemuxer);
+    if (!mVideoTrackDemuxer) {
+      mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
+      return;
+    }
   }
   if (audioActive) {
     mAudioTrackDemuxer =
       mMainThreadDemuxer->GetTrackDemuxer(TrackInfo::kAudioTrack, 0);
-    MOZ_ASSERT(mAudioTrackDemuxer);
+    if (!mAudioTrackDemuxer) {
+      mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
+      return;
+    }
   }
 
   if (IsWaitingOnCDMResource()) {
     // Decoder can't be allocated before CDM resource is ready, so resolving the
     // mMetadataPromise here to wait for CDM on MDSM.
     mInitDone = true;
     nsRefPtr<MetadataHolder> metadata = new MetadataHolder();
     metadata->mInfo = mInfo;
@@ -620,18 +632,17 @@ MediaFormatReader::ShouldSkip(bool aSkip
   if (NS_FAILED(rv)) {
     return aSkipToNextKeyframe;
   }
   return nextKeyframe < aTimeThreshold && nextKeyframe.ToMicroseconds() >= 0;
 }
 
 nsRefPtr<MediaDecoderReader::VideoDataPromise>
 MediaFormatReader::RequestVideoData(bool aSkipToNextKeyframe,
-                                    int64_t aTimeThreshold,
-                                    bool aForceDecodeAhead)
+                                     int64_t aTimeThreshold)
 {
   MOZ_ASSERT(OnTaskQueue());
   MOZ_DIAGNOSTIC_ASSERT(mSeekPromise.IsEmpty(), "No sample requests allowed while seeking");
   MOZ_DIAGNOSTIC_ASSERT(!mVideo.HasPromise(), "No duplicate sample requests");
   MOZ_DIAGNOSTIC_ASSERT(!mVideo.mSeekRequest.Exists() ||
                         mVideo.mTimeThreshold.isSome());
   MOZ_DIAGNOSTIC_ASSERT(!mSkipRequest.Exists(), "called mid-skipping");
   MOZ_DIAGNOSTIC_ASSERT(!IsSeeking(), "called mid-seek");
@@ -647,27 +658,28 @@ MediaFormatReader::RequestVideoData(bool
     return VideoDataPromise::CreateAndReject(CANCELED, __func__);
   }
 
   if (mShutdown) {
     NS_WARNING("RequestVideoData on shutdown MediaFormatReader!");
     return VideoDataPromise::CreateAndReject(CANCELED, __func__);
   }
 
-  mVideo.mForceDecodeAhead = aForceDecodeAhead;
   media::TimeUnit timeThreshold{media::TimeUnit::FromMicroseconds(aTimeThreshold)};
   if (ShouldSkip(aSkipToNextKeyframe, timeThreshold)) {
+    mVideo.mDecodingRequested = false;
     Flush(TrackInfo::kVideoTrack);
     nsRefPtr<VideoDataPromise> p = mVideo.mPromise.Ensure(__func__);
     SkipVideoDemuxToNextKeyFrame(timeThreshold);
     return p;
   }
 
   nsRefPtr<VideoDataPromise> p = mVideo.mPromise.Ensure(__func__);
-  ScheduleUpdate(TrackInfo::kVideoTrack);
+  NotifyDecodingRequested(TrackInfo::kVideoTrack);
+
   return p;
 }
 
 void
 MediaFormatReader::OnDemuxFailed(TrackType aTrack, DemuxerFailureReason aFailure)
 {
   MOZ_ASSERT(OnTaskQueue());
   LOG("Failed to demux %s, failure:%d",
@@ -739,17 +751,17 @@ MediaFormatReader::RequestAudioData()
   }
 
   if (mShutdown) {
     NS_WARNING("RequestAudioData on shutdown MediaFormatReader!");
     return AudioDataPromise::CreateAndReject(CANCELED, __func__);
   }
 
   nsRefPtr<AudioDataPromise> p = mAudio.mPromise.Ensure(__func__);
-  ScheduleUpdate(TrackType::kAudioTrack);
+  NotifyDecodingRequested(TrackInfo::kAudioTrack);
 
   return p;
 }
 
 void
 MediaFormatReader::DoDemuxAudio()
 {
   // TODO Use DecodeAhead value rather than 1.
@@ -835,35 +847,43 @@ MediaFormatReader::NotifyEndOfStream(Tra
 {
   MOZ_ASSERT(OnTaskQueue());
   auto& decoder = GetDecoderData(aTrack);
   decoder.mDemuxEOS = true;
   decoder.mNeedDraining = true;
   ScheduleUpdate(aTrack);
 }
 
+void
+MediaFormatReader::NotifyDecodingRequested(TrackType aTrack)
+{
+  MOZ_ASSERT(OnTaskQueue());
+  auto& decoder = GetDecoderData(aTrack);
+  decoder.mDecodingRequested = true;
+  ScheduleUpdate(aTrack);
+}
+
 bool
 MediaFormatReader::NeedInput(DecoderData& aDecoder)
 {
   MOZ_ASSERT(OnTaskQueue());
   // We try to keep a few more compressed samples input than decoded samples
   // have been output, provided the state machine has requested we send it a
   // decoded sample. To account for H.264 streams which may require a longer
   // run of input than we input, decoders fire an "input exhausted" callback,
   // which overrides our "few more samples" threshold.
   return
     !aDecoder.mDraining &&
     !aDecoder.mError &&
-    (aDecoder.HasPromise() || aDecoder.mForceDecodeAhead) &&
+    aDecoder.mDecodingRequested &&
     !aDecoder.mDemuxRequest.Exists() &&
-    aDecoder.mOutput.IsEmpty() &&
+    aDecoder.mOutput.Length() <= aDecoder.mDecodeAhead &&
     (aDecoder.mInputExhausted || !aDecoder.mQueuedSamples.IsEmpty() ||
      aDecoder.mTimeThreshold.isSome() ||
-     aDecoder.mForceDecodeAhead ||
-     aDecoder.mNumSamplesInput - aDecoder.mNumSamplesOutput < aDecoder.mDecodeAhead);
+     aDecoder.mNumSamplesInput - aDecoder.mNumSamplesOutput <= aDecoder.mDecodeAhead);
 }
 
 void
 MediaFormatReader::ScheduleUpdate(TrackType aTrack)
 {
   MOZ_ASSERT(OnTaskQueue());
   if (mShutdown) {
     return;
@@ -1172,26 +1192,28 @@ MediaFormatReader::Update(TrackType aTra
   }
 
   if (decoder.mNeedDraining) {
     DrainDecoder(aTrack);
     return;
   }
 
   if (!NeedInput(decoder)) {
-    LOGV("No need for additional input");
+    LOGV("No need for additional input (pending:%u)",
+         uint32_t(decoder.mOutput.Length()));
     return;
   }
 
   needInput = true;
 
-  LOGV("Update(%s) ni=%d no=%d ie=%d, in:%llu out:%llu qs=%u sid:%u",
+  LOGV("Update(%s) ni=%d no=%d ie=%d, in:%llu out:%llu qs=%u pending:%u ahead:%d sid:%u",
        TrackTypeToStr(aTrack), needInput, needOutput, decoder.mInputExhausted,
        decoder.mNumSamplesInput, decoder.mNumSamplesOutput,
-       uint32_t(size_t(decoder.mSizeOfQueue)), decoder.mLastStreamSourceID);
+       uint32_t(size_t(decoder.mSizeOfQueue)), uint32_t(decoder.mOutput.Length()),
+       !decoder.HasPromise(), decoder.mLastStreamSourceID);
 
   // Demux samples if we don't have some.
   RequestDemuxSamples(aTrack);
   // Decode all pending demuxed samples.
   DecodeDemuxedSamples(aTrack, a);
 }
 
 void
@@ -1360,16 +1382,17 @@ MediaFormatReader::Flush(TrackType aTrac
 
 void
 MediaFormatReader::SkipVideoDemuxToNextKeyFrame(media::TimeUnit aTimeThreshold)
 {
   MOZ_ASSERT(OnTaskQueue());
 
   MOZ_ASSERT(mVideo.mDecoder);
   MOZ_ASSERT(mVideo.HasPromise());
+  MOZ_ASSERT(!mVideo.mDecodingRequested);
   LOG("Skipping up to %lld", aTimeThreshold.ToMicroseconds());
 
   if (mVideo.mError) {
     mVideo.RejectPromise(DECODE_ERROR, __func__);
     return;
   }
 
   mSkipRequest.Begin(mVideo.mTrackDemuxer->SkipToNextRandomAccessPoint(aTimeThreshold)
@@ -1383,42 +1406,42 @@ void
 MediaFormatReader::OnVideoSkipCompleted(uint32_t aSkipped)
 {
   MOZ_ASSERT(OnTaskQueue());
   LOG("Skipping succeeded, skipped %u frames", aSkipped);
   mSkipRequest.Complete();
   mDecoder->NotifyDecodedFrames(aSkipped, 0, aSkipped);
   MOZ_ASSERT(!mVideo.mError); // We have flushed the decoder, no frame could
                               // have been decoded (and as such errored)
-  ScheduleUpdate(TrackInfo::kVideoTrack);
+  NotifyDecodingRequested(TrackInfo::kVideoTrack);
 }
 
 void
 MediaFormatReader::OnVideoSkipFailed(MediaTrackDemuxer::SkipFailureHolder aFailure)
 {
   MOZ_ASSERT(OnTaskQueue());
   LOG("Skipping failed, skipped %u frames", aFailure.mSkipped);
   mSkipRequest.Complete();
   mDecoder->NotifyDecodedFrames(aFailure.mSkipped, 0, aFailure.mSkipped);
   MOZ_ASSERT(mVideo.HasPromise());
   switch (aFailure.mFailure) {
     case DemuxerFailureReason::END_OF_STREAM:
       NotifyEndOfStream(TrackType::kVideoTrack);
-      mVideo.RejectPromise(END_OF_STREAM, __func__);
       break;
     case DemuxerFailureReason::WAITING_FOR_DATA:
       NotifyWaitingForData(TrackType::kVideoTrack);
-      mVideo.RejectPromise(WAITING_FOR_DATA, __func__);
       break;
     case DemuxerFailureReason::CANCELED:
     case DemuxerFailureReason::SHUTDOWN:
+      if (mVideo.HasPromise()) {
+        mVideo.RejectPromise(CANCELED, __func__);
+      }
       break;
     default:
       NotifyError(TrackType::kVideoTrack);
-      mVideo.RejectPromise(DECODE_ERROR, __func__);
       break;
   }
 }
 
 nsRefPtr<MediaDecoderReader::SeekPromise>
 MediaFormatReader::Seek(int64_t aTime, int64_t aUnused)
 {
   MOZ_ASSERT(OnTaskQueue());
--- a/dom/media/MediaFormatReader.h
+++ b/dom/media/MediaFormatReader.h
@@ -30,28 +30,28 @@ public:
   virtual ~MediaFormatReader();
 
   nsresult Init(MediaDecoderReader* aCloneDonor) override;
 
   size_t SizeOfVideoQueueInFrames() override;
   size_t SizeOfAudioQueueInFrames() override;
 
   nsRefPtr<VideoDataPromise>
-  RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThreshold, bool aForceDecodeAhead) override;
+  RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThreshold) override;
 
   nsRefPtr<AudioDataPromise> RequestAudioData() override;
 
   bool HasVideo() override
   {
-    return mInfo.HasVideo();
+    return mVideo.mTrackDemuxer;
   }
 
   bool HasAudio() override
   {
-    return mInfo.HasAudio();
+    return mAudio.mTrackDemuxer;
   }
 
   nsRefPtr<MetadataPromise> AsyncReadMetadata() override;
 
   void ReadUpdatedMetadata(MediaInfo* aInfo) override;
 
   nsRefPtr<SeekPromise>
   Seek(int64_t aTime, int64_t aUnused) override;
@@ -125,16 +125,17 @@ private:
   // Drain the current decoder.
   void DrainDecoder(TrackType aTrack);
   void NotifyNewOutput(TrackType aTrack, MediaData* aSample);
   void NotifyInputExhausted(TrackType aTrack);
   void NotifyDrainComplete(TrackType aTrack);
   void NotifyError(TrackType aTrack);
   void NotifyWaitingForData(TrackType aTrack);
   void NotifyEndOfStream(TrackType aTrack);
+  void NotifyDecodingRequested(TrackType aTrack);
 
   void ExtractCryptoInitData(nsTArray<uint8_t>& aInitData);
 
   // Initializes mLayersBackendType if possible.
   void InitLayersBackendType();
 
   // DecoderCallback proxies the MediaDataDecoderCallback calls to these
   // functions.
@@ -186,23 +187,23 @@ private:
 
   struct DecoderData {
     DecoderData(MediaFormatReader* aOwner,
                 MediaData::Type aType,
                 uint32_t aDecodeAhead)
       : mOwner(aOwner)
       , mType(aType)
       , mDecodeAhead(aDecodeAhead)
-      , mForceDecodeAhead(false)
       , mUpdateScheduled(false)
       , mDemuxEOS(false)
       , mWaitingForData(false)
       , mReceivedNewData(false)
       , mDiscontinuity(true)
       , mDecoderInitialized(false)
+      , mDecodingRequested(false)
       , mOutputRequested(false)
       , mInputExhausted(false)
       , mError(false)
       , mNeedDraining(false)
       , mDraining(false)
       , mDrainComplete(false)
       , mNumSamplesInput(0)
       , mNumSamplesOutput(0)
@@ -221,17 +222,16 @@ private:
     // TaskQueue on which decoder can choose to decode.
     // Only non-null up until the decoder is created.
     nsRefPtr<FlushableTaskQueue> mTaskQueue;
     // Callback that receives output and error notifications from the decoder.
     nsAutoPtr<DecoderCallback> mCallback;
 
     // Only accessed from reader's task queue.
     uint32_t mDecodeAhead;
-    bool mForceDecodeAhead;
     bool mUpdateScheduled;
     bool mDemuxEOS;
     bool mWaitingForData;
     bool mReceivedNewData;
     bool mDiscontinuity;
 
     // Pending seek.
     MozPromiseRequestHolder<MediaTrackDemuxer::SeekPromise> mSeekRequest;
@@ -244,16 +244,17 @@ private:
     {
       MOZ_ASSERT(mOwner->OnTaskQueue());
       return !mWaitingPromise.IsEmpty();
     }
 
     // MediaDataDecoder handler's variables.
     // False when decoder is created. True when decoder Init() promise is resolved.
     bool mDecoderInitialized;
+    bool mDecodingRequested;
     bool mOutputRequested;
     bool mInputExhausted;
     bool mError;
     bool mNeedDraining;
     bool mDraining;
     bool mDrainComplete;
     // If set, all decoded samples prior mTimeThreshold will be dropped.
     // Used for internal seeking when a change of stream is detected.
@@ -263,31 +264,31 @@ private:
     // state machine upon request.
     nsTArray<nsRefPtr<MediaData>> mOutput;
     uint64_t mNumSamplesInput;
     uint64_t mNumSamplesOutput;
     uint64_t mNumSamplesOutputTotal;
 
     // These get overriden in the templated concrete class.
     // Indicate if we have a pending promise for decoded frame.
+    // Rejecting the promise will stop the reader from decoding ahead.
     virtual bool HasPromise() = 0;
     virtual void RejectPromise(MediaDecoderReader::NotDecodedReason aReason,
                                const char* aMethodName) = 0;
 
     void ResetDemuxer()
     {
       // Clear demuxer related data.
       mDemuxRequest.DisconnectIfExists();
       mTrackDemuxer->Reset();
     }
 
     void ResetState()
     {
       MOZ_ASSERT(mOwner->OnTaskQueue());
-      mForceDecodeAhead = false;
       mDemuxEOS = false;
       mWaitingForData = false;
       mReceivedNewData = false;
       mDiscontinuity = true;
       mQueuedSamples.Clear();
       mOutputRequested = false;
       mInputExhausted = false;
       mNeedDraining = false;
@@ -329,16 +330,17 @@ private:
       return !mPromise.IsEmpty();
     }
 
     void RejectPromise(MediaDecoderReader::NotDecodedReason aReason,
                        const char* aMethodName) override
     {
       MOZ_ASSERT(mOwner->OnTaskQueue());
       mPromise.Reject(aReason, aMethodName);
+      mDecodingRequested = false;
     }
   };
 
   DecoderDataWithPromise<AudioDataPromise> mAudio;
   DecoderDataWithPromise<VideoDataPromise> mVideo;
 
   // Returns true when the decoder for this track needs input.
   bool NeedInput(DecoderData& aDecoder);
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -674,17 +674,17 @@ RTCPeerConnection.prototype = {
     // This entry-point handles both new and legacy call sig. Decipher which one
     let onSuccess;
     if (typeof optionsOrOnSuccess == "function") {
       onSuccess = optionsOrOnSuccess;
     } else {
       options = optionsOrOnSuccess;
     }
     return this._legacyCatch(onSuccess, onError, () => {
-      // TODO: Remove old constraint-like RTCOptions support soon (Bug 1064223).
+      // TODO: Remove error on constraint-like RTCOptions next cycle (1197021).
       // Note that webidl bindings make o.mandatory implicit but not o.optional.
       function convertLegacyOptions(o) {
         // Detect (mandatory OR optional) AND no other top-level members.
         let lcy = ((o.mandatory && Object.keys(o.mandatory).length) || o.optional) &&
             Object.keys(o).length == (o.mandatory? 1 : 0) + (o.optional? 1 : 0);
         if (!lcy) {
           return false;
         }
@@ -711,20 +711,21 @@ RTCPeerConnection.prototype = {
           if (o[k] === undefined) {
             delete o[k];
           }
         });
         return true;
       }
 
       if (options && convertLegacyOptions(options)) {
-        this.logWarning(
-          "Mandatory/optional in createOffer options is deprecated! Use " +
+        this.logError(
+          "Mandatory/optional in createOffer options no longer works! Use " +
             JSON.stringify(options) + " instead (note the case difference)!",
           null, 0);
+        options = {};
       }
 
       let origin = Cu.getWebIDLCallerPrincipal().origin;
       return this._chain(() => {
         let p = Promise.all([this.getPermission(), this._certificateReady])
           .then(() => new this._win.Promise((resolve, reject) => {
             this._onCreateOfferSuccess = resolve;
             this._onCreateOfferFailure = reject;
--- a/dom/media/gtest/TestMP4Demuxer.cpp
+++ b/dom/media/gtest/TestMP4Demuxer.cpp
@@ -421,8 +421,18 @@ TEST(MP4Demuxer, GetNextKeyframe)
         binding->mVideoTrack->GetNextRandomAccessPoint(&time);
         EXPECT_EQ(time.ToMicroseconds(), 1000000);
         binding->mTaskQueue->BeginShutdown();
       },
       DO_FAIL
     );
   });
 }
+
+TEST(MP4Demuxer, ZeroInMoov)
+{
+  nsRefPtr<MP4DemuxerBinding> binding = new MP4DemuxerBinding("short-zero-in-moov.mp4");
+  binding->RunTestAndWait([binding] () {
+    // It demuxes without error. That is sufficient.
+    binding->mTaskQueue->BeginShutdown();
+  });
+}
+
--- a/dom/media/gtest/moz.build
+++ b/dom/media/gtest/moz.build
@@ -40,16 +40,17 @@ if CONFIG['MOZ_RUST']:
 
 TEST_HARNESS_FILES.gtest += [
     '../test/gizmo-frag.mp4',
     '../test/gizmo.mp4',
     'dash_dashinit.mp4',
     'mediasource_test.mp4',
     'noise.mp3',
     'noise_vbr.mp3',
+    'short-zero-in-moov.mp4',
     'test.webm',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 LOCAL_INCLUDES += [
     '/dom/media',
     '/dom/media/eme',
new file mode 100644
index 0000000000000000000000000000000000000000..577318c8fa8aaf3bc8541844c07d3a5092ea489c
GIT binary patch
literal 13655
zc%1E92UJtb);^&tAiathqzFh!sL}*Pnt*`P6(J1>1QL?adly6yse&R(2c?LpAk6}Z
zD2g;ex}XS1^&%?eKjC`sMc;e>dTV*t`u}y8JDD?kX7=7Qd(U@fGA9WD08l5g9|23k
zy8{3fK*_-*hww(h-3bbC000=Ah!_k2$b4}}BgmjkIUVihX6c~r`}(*226xh=UP1eX
z=jMIoloX)SP!yhsfx_h#p+q@(1x2V63<XCi%7YCCGN6F0iJ7jxv;tJyN(YogV^Cm&
z4xZqL!#I(laxj>@v>Xghk#-@I397QPK0ZD&-dHpSk3)FK;EB$%lwM?9$nH2$22UVk
z@g5{qC<=i@pfuo6BF0HW9*V{wad?!Q23!@U3WFj%5I8>)Mg!(6uL|>pgT~!48ZH=L
zD9H;6a>`Hw$q!TouMR}C23!UPDuEZMJJuJ2cA!{<gBlJ*goiUm1Fi%`xe)R02nSFV
z4kZ&YI2@J)atD16qETd!L3z4sz`!9O(EfN2jD{Rs3J!-lAxLBg0?7?aph)~~z?0yB
zcXA?O$QsgeP_hdV)Bp|1L2-Dz8^Q%FIs91(CE>6r%wH8Ss0VSY6BO1RL8c4@>p{j4
zaR^WdtViO!hzLIi6yBYHAcJKT7$Y(ff%O1QfPzE>MaGGUaL16qXdxX4ejtxUYsi5-
z0*xS0+(0@Yu?R{}Xe<%4<(Ll!>+C{Cf*hWJ@o;d)6TsHrD+!>g8^#Z`ts$of`^GxB
zV?8wF6rdy&#sh=$B5NqXpj*9DVoJo2TtIaq%HdCUDeXj*28!qebw`4MrMLwaH00!E
zU{FtrGa4`%C6Fah3~%KKUkxP{kRg#V1Pui!mH^HYhzM{JL0bq<5CD|v1VRA-5`{Sv
z2`F!Fj8U(0cJA?uzuRt}HqX_bbca3NxPSRPZ=yY|CygT@nlizBImhqhnL`js0ALRt
zvVpOFcvE=4`5;~AXPBU`hiGOB_LW7~^R}4OVu++e`VoYZ#ZLcKC25<QDx<adOst~*
z4g84!^+#92sS7us_2<?+u_v5pJ#6hWo22tH(<yGsID4`3E<!&B!#MAG<W_It(0P7@
zBm_f@&03xrdXKrveyrM&zQ8=fCD}%0QN1nzZM#Dth~9z4I0KfVdvKi*RbVVH6Zf?!
zIo^rb++J6c7eZ}*L;J~K{Avd0=Dht{VirVTwd^3ii0j31X4UYi!KEFSb{vSiO4wL8
zuuPd6i=h@QrG|3rO^h>(PC58me1QvKE)RE-18Do^8w#E0`7S4LF;>rTov{5XeVxuQ
zcwt3zqkED{x=FCQ%LQ7u=!ZGNk=0uJfOn`z*Z-N=lp*RCQ-0v2cnv*Yhg{};qi_SP
z(Z|m0tc`^D3r0rc1tuHZQ|B)xPt^Ncn}cgdhjykAPA6oeFcR=SQ%k=i1mLl3ie$?@
zwLjy$mhMg}`gQ%71m#L<T=QqWC7YokN4^2x=p45UR2uK?+Dd9iWCA^PiW(2k$>6UI
zy7#E_ScQk1{fC5yZ+uL#c!rvtl=^fxzoU0vyk;lfK0w*{81u=Iyr$)W$1)k-%Cd8>
z)|Fi*nq<r)g3cHk3-Dy^<dlsn{1`U|QQRZwXw_pi_C7>3aw-&hrbwTUVLjawppwAn
zEJ%JG&#+-Tm5MRC`arCi=+K^bVED{tBOuSl(txfqUJYJk;p&VvviKnI@-TL!?6vO5
z&68EDCb{-5`?$EyWi0qjFHJnxzffis=cKpl{t~}eW{5ha$NY3}>?dsvwa1aCh51x8
z&x%X3UE<Rj9@SEtp@$@%({tG6mL9U<e@pMJNa|YDlBimaB5aRCONPNkg%5Wx4UFve
zYPTe_Um1K}r&LjqmCkSC>cFJES2go2hh}kjo{|}Uw~8dsNp3D1Gh7K*lsA3xDPKmp
z^&083$4YLz%J%zOUV-O$`2e7a_u{&i<-~lI89$kPzg{x5Rh+l|#8K{3E4jOFie+hu
z59XWqm(44A%jl4A8lH3eZSHg;?l~$b?~vkekIgC^br0yPI(<+iF2^MXc1M(-e|_T4
ztcGtXyyiyl<EL}N<pr&m$SS0$guvt|20O>LR{hf4@iQ0b8Msl;Hb<V@T{Aq`c0n?g
z-Cj6<X0oiZav;b~iFCoPR4Y!};_+#7wsY6r%O$0(RM`jDq_Z$W*c+dT=UyJ-X*U@5
z^IpCPPp+U+cqUz2Lib1t%adeedL?KMm(Woya_PZX;Dbh-S(|=cXZfnRpM(5cejj_{
z(aX}@j$QX8{FXD9C&H5J_s)#%7|utvcS(PycOE>Pn~`ZLNdNLFNjaK{BM1TY#7ChX
zA-t1k+hc%ZHker*r9CV7oTLmYi3%i2q3g83xR3x7Kp`4xN0_3rtZ2_fG3Qy1B0$h9
zc!YyjlMg8@8F+dhi)tgzpVeN|SwFm%TqT#i$-j18Mad)WkQv=IH*b?m`K+!`trH^|
z&HWDJpD}7$3<FogifjC2%0&(GY$Pr_+<DZ((qePw$rYY65gp~P1tWP(`#VR=E=xTv
zY;0*fu*)PXKQRSTlsS~_EOCVY3@hiSw{UOk)dt&RuNOjre-<4SlKK{M#V7Iism#Kq
z%hJ<Q_oeF`d}kI!D(KBS>%6!^mv~$CFgzBio-Xv1BbZO1YjrxKhqmeobBt(PM`KL$
zhEBozI~MyU79Q8J^At)p70~Nk6S}sB$Bz$$tuZ<9c)XJD`?ScCGaVRks&1egIs4&t
z+wgRnQX;_^{lQZ_+4tSL+O!(dJtq<J($><_QfulOlRV)oI{P#4Rh_vQ$Bt#DT}Q`^
z>U-68lbqV6VB=Z}_Z0cUX|B>3<xl1t<iF@p>E2nf+qCb)WxUI}Zd!e7u*|#ow)wQd
zdH*M>V{@x#^v@<=4q-XF7Gu)oQKZ{8mgFlUd(1M-cvs939o^O8k>+aZRo(`fp$g~n
z`SHEl-K#4#e$_?I{jcvN*Y`-d3yx;A4UC(MEk6I^)9wA}wYDI2-p!JdlCaJryiQ{)
zZ5m7P!!bj<?q7b(E0FpiJ>a^x(%WZgHi&t;e;4ynaN%~+&eT;GN|uNOcTsThZut5j
zev@|6CY1Jh!W;94uGWKqt&`vGun)0>oBrCi3FWc<5}&Et`}@ioPzlmD*2b~tJW7yU
zN<#uer-s+Ax>bmjy6H`Slo=O0+48!U?PI!a%<=KN%&IkysSX)=l{LQ~l<eU3$*63;
zt*3Hg|2^_#m|Qy5;u7D<w`M|bDr6kKUPL(>s!P;X+;WB9udeH^Pnawpc1D>_SxyXh
ze;vw#IuO-;q>X6u&;o)zeGD%pr1h7u3!7aVwb)%fJD2Al-HRznpPKfnz;n(f8Zz8j
z_Ucqz&SO?tLwj?ix(I~j$!gPHS$ccdu8KJWxTo`Q>7!}R+0N5#4^lP5Xyi}z@+M3l
z4v2QUfAe$jTT3JOvuB1Hx6FJeT8d>evclg!2`PEwpY1GkG21-4r#*;FkEZWjG#Qop
z?VUiz89Rl#DcdWKFc%f%Waciq9F{WPXY{O}6m~Wj%=HlPtkK%R@<&>x6A7!kJ~QmC
ztV-RX*%NpLXY6n{vL8s26~iUvOD{mRnl25+d}L$L>|G8YlU4T+SHt)f^Oo6v4(^}5
zq4NUJs*~#pXMec=UU37SePNV!ynOVqa&7pMMN`v<ZlX)2Oy2z24>#`i+wT^cVU|&H
z<vR|$$U$mLg!9;{=y%sk)MWI_$Mhpg?F)2Px|Bt4Ts+X%`?e+z?IrNrU1i0Ufe1Cb
zYDbUZ^bX!DLGgq({kDbkkieTuEvJ_vpO&Sj_~;s&HM8wqtBohQcz$xLyJVEsvVn->
zNu8jU|AN<f$9=(MkDF}VZA-+5;uI);BeV7D`2JgseL}}@3y@GcfEPG2Sj0ahCiLts
z0(`f__=j%3ohxy>Z9!Ahcv5I4L@#OduAJ2vn<Ea<30;_b-C3PwX~oY?dChU#G7OC-
zK1>v3?;#%!kyF!V^-W2?xHfwDY>0;u!@XM*{kv|_gF76oKBj3&A-o|frQ0!5Q01s?
zw4|WN2$NdT0fzUt9vwP^i#1;?=K8{!9sXYS+Qp~zT=J5`XI<h>K5Cat)qirTxyF}U
z<!kLck6Z1Uw6o)ll6|<*>hOj9YK3IB7k(Bo*EG!Z7&UvEZ*vJ0+3AYj=il{AtLgen
zq(FETlM1bw3hm9F6LLA%w8w_-<hm)9Tvw0+U($n84N^6;hya$b2`p_8qeRht26bXe
z6_bVfPy?@znbpzUNg3o|9izbdkk8rbp<wQ+3acJAC4$|3-{S+Bh7I&cl*sIh+<h~?
zP5;$`N-q@15V*CV4pkhou;>L;Py*Hl<F&e#G4>}6cw*UB>nnvT3iQawVRpLu`?OIn
zg3_IyOQ(qz$`{AFV4py_qxVYo04@6QD}wT`5Xy5A2)oB!;%|<Ik8J!sOa4EDAVq(&
z)S=*|Svwo$dg8$*K;E~LBdW_)3@+H(`*J0=;?@KCE0@YvvX;aLi3$a=-bXnxS|r(`
z52#92;y&i)$2^EGF`UkhvgPqYE}am=!NRA3T%r>!7?Hl|zMED#iXBu<H;d%5teJZj
z@c6u09cRw##U7Q4r#saY&j&OaH1T%rbd8RBCGXY#^fYZm;~w#}r>>z9zVJ-h^P?Gt
z%pak{(Tke!E0Eh<WfF{S1d@T|NtY!K83T6t_5z=in>jm~2gA#R461u)*_-zZ2{1TP
zT%u`WZ`pf1Fjh4Q>W9nz)F#p{P?5tC(+xoOY>xh)#QXm#?S88Da|RCn8S=+q$WJ7C
zI@6?H3ezk;Si%w)@ZvJHfzC9`L;U8?kMtiz!;U|t4ru}}y^!p1^5I6{ifCo)q5A$k
zI?ISpGcK3#%AX<u2vQBme1P2*QZ-|aKNn$-71tAoXp|jS5DuSheSc6!E~Nf?f@t$t
zMCoD;)0f2g157-P(_iP;=Z>4Vu)L6%npqo-FnnhxwVX(xVOp?EpvkH5W$if6vKA(`
z!ki~l9<=|eQPQrZN}U6TVEm@@cble0I-+J*MjiI>v8BwFc43xJz0i)}5RN;ZQ=*b^
zTPUet8PFD-cOlJNO!3HH_bNHUE4@f|Ilj3Mn$t}G#!mdX8kBpSEhOfv%J(<$dNW?+
za`}Gt#l06}tx}danlKDO+M~Y~^6dnvtNR)Ct;HV%Q=}^eOx87Lcf>Lq5bXfm4TiPa
zo6I-fbI%+SQfIR`@k*4MO4Je7`I>M$a$a-eaNdzM+k{2AXu?gM(1ybG_NIByV}<jz
z>6UV?LtpBGrHT~s{U?tSEH2d+mUtSkfA-(7Hn`B<NO;H)(0mL(K6wOTz#?<GxBk=-
zLIk$CK8~Mwp=@u$vHSN=hb4Iw?pYbGHP;@<47k^-7vRr-e@Tgt1DafLyasbJ#^pCt
z7o+o5K(rg$d&H>Ibt8UtmTfP4c9u1xX7$`xI-<H><hr2fj;r5;$(QEv1C`T}I^%^(
zLYMVV%aECcSc(o^@YxLg`APWa5MK7D)JMOMxj)}aUG3M8ztZQkjfywYEbu+pYZhSg
zYYW~^yPy7?{y}gJ2-D7tH7wG0xoFH_y}5Bvi_w(S(iG;o->ibF56E?W-MxQrmX^9A
zcR!P)b_JAZad*E3j!k)VMiJZ8Wu<gs@QvR1M9skSX=l=N&Vv>B^JBNudKe;y^Vf%}
zP5VOZ>sDFF2RWGf^bN2LRrmG;>bi$`PEs!)ASyR^7b$#j_mVPf@Sjd*Fq`)MQoF<5
z|MBr>W7c+_3j1^QMYsyNHgiNe!W!!uOLjG_9rLVk^eYu$ay=mU(W;L2<IqAwI^!q3
zaBJ*FD+GQi_o(`N5q|;Xd;Z(zTq#s#XheUp!1xQuxnT`@pDVCj!=b5<Fe}-P<G!5?
zGIh0Fsl_syX$qMeIr)d|l0?NrR^E-?GdmH8e3$=;<zw<|+1v4LbW>IGZVy+}F>hL;
zC3M^lJS8*su_p6B+&tS^+hOEi&%2LFat~eZ((MXWOod#m2xI5OE4Vmm#&~d8mZwzE
ze?Rw=iL5yH0zB``f;aMhib>Y2Coxx1+Y)zdp(?6UovKR3qE+aJjqA}mP1?hx<mFH2
z+7i&+`$IcezeIHW+PJn8q^{|w^r=JtjQL$k%md;D&DHzj+5-7Hx(8)8IGUWn4+|ge
z{94|()6XvN;Iu)svkP_Eq+~Y%@0T0LYCQKh`(77(5h=1#d7*=Fk+rO>Y8?rfn9f_o
zvg+EL<uPq%`q&p#+zboQ?<|~Tk5(>oZyOMPk`(92_GYAsZ0M_A%7C*EA1m0ca(HZ3
zQnBOW)#}o=OQ;)+)M!LOlNHB>&!1j9G0uy0D|F5p243D_%ilWi?g)Ob&OB|fD2!J1
zyf8<2@B-<izto0{L0NZ%{)EJ<xSf(%WsAo<MaD~(q#|~u_hZ=Pv%_TM9MDDXOYzkH
zxWz-!zBv+WtWIm!vhhHv5LYONnCUg6Zf%C+UC!DQxeR)v$ks?(wgH8%NyBoFkr7s=
z>ph-2r<F5W4}Sh0cR^9PxOmeetaE~7p<Q9xTKidw0IJ=aO+P<b{~S`z2>m$&gg;~c
zigL^>_iRhi%~F0BRoYa$U<%0-`i=gj@~=C6JK^C!X<!sgE0FA#Z>P)_I|ZJ#V~&ts
z|4f!V;=J?>>*w9}?bg#X0|$FH&sV9&FW6+qsGPUrkQy(_v2$l}CRJ63+(q3FuNSOl
zlt-G<sNI~jccxQq!H8NbBj77frZmz`f>W*A>5Eq7-#G|OmoV`hih9R9uwQ(%bS-NW
zCEZf)(@euQuV4Fet$`MKH~dShiV0^z(&gDBVvFvM0&;Q=W&C+u3zxrYBnQ){Cc{&#
zdi!;%9m_t8zcfid?{n?+s~onYlZop&M`k5#Mpe8=%g%k7i9IZ=;j_$W6h)g6eMUg$
z;cLr`*cBO%s6wU@>+Jkoh1{XDe9?b`?ZwtJjU+KWs3uL)%rHrqA31tOp7I=N@YiO(
zo&Ltnobnv$xc3fVqC(yG%Kf>0rs{$X964BUGyizw*U4c!?QU=S8FldB0IWf>A5%{L
zxqUTf;U@@^9-+*MLHDj5RJrZkA7_$us_BqS+1XLSTT>FE$2C(w1P+c*O3)1LG^cqS
zWU;y$bjC@(eY7U=fgKB->cs@9+fNvLXc#gyj|$KBCXFE>DW;R9PmbBdWTa@c2EI@z
z*T#H!c6*_5!0V2plg+M0QHdbU&1>AFuhjh49iAqRSl=3R5w4J@;_T*XaAebFv&w3r
z6UXshiwfQwAa2BaVAaU6%I$z_<puK~ng?l_5zqbK2{D9LFxLgMbiG8Xsg*Y|TD!=q
zoO-^Q%BQ~+VLx=j_|rWe;-woEL2=f>K5IN~JfS+UKK-zL1yMCoaj@_9aq}r>zlntg
z3(*-_<_j%ajgh|}R^5L=Zae+-VfBY|5>qK>LSY%}YS3$g!@;jOawwnK*U$Zm`F8r*
z+x*94Qn6IDbE`-&(_+A#P!lR&rZJWx^=H3AzMcL)m~SmDb26nO1)tZhM6U%O!=;X?
z)0xF|3o`!-`F8sILf(8cZZF_0@L)QW!>;W{WbZXsTSbvfGvl{nS{UR7L~LNqn@5!=
zRx}4UpKpXLZ#2$tUfI-K+|-=;x)=VMJm_EX{EQBh$bMmd1((iTJ!U4Oe!$9AJP@D*
z#NKfPwADWv9QVK~!7?uxKUn(=qsfRgMv4h>Fc^mNuI+udq4{n-<mSpDRKc5`=)l9g
z2q6_-(8@V}m<uYH^>2vN|0kjs5@4L7Ff>C2@sO|>OQO}ii{2%r^h%;FBSevX>~cE}
z@kwy*aP$<Z==PnxrgVet(SYz_Jq@0bARoP!3lS0$a~eIhcdVv|PL_J%O1Y5PxL2Lp
zm^9bl$rh7ln-v=74&~+b>blfzX&KeGA{={5FEW(HzOyX30Ipql-3aa^)tphqjeKg+
z{Tp|LqN12Ox2;pb7UieeVlICg{XdS<-%0`iK&R-A$9sc3&fVJu{e3evI318-00L0n
ze-Y$+sUOQ)|9hX*06^78CL-KG{uJ45t524HwFbHRFPi^FzYxl0VXG*DL6b>fE`Y(2
z$bV^2?9zPGr80F#V-X+&bw~f`I}A*mfaRmDg0u@7NBpCO@|*qbl2(-8@EagJ&^Qc5
z2J*!n>)}Mv_IBSgx_y`;=-=A}&_s;WHaD2Oh&brC0oIbpNF2zgk;o+UHkoM3-xmHu
zC@79E00tmq@Si09g?Kk9U!=o8t2z)gz`QvI@Hm6{^?q&bFSt<3M1dDx`Z&&Z2temD
z^QL`Y6Ge+e-U{m<ee9(Cv4Y|)INI&?lw^bYOLhmaB}ntFedo9QkMbXSRR2x8IM^5J
zTOHN6_8)UfQU~Syw|NX2rBMe(UV_OLEVqGa;P(WH0uwFBfBDv(0*Q>mZyP&^hn=Dz
zQo&n=Lks}8K)?7D0ANoJ00_kcfGFh;CXxROtf{`aFubh}0@?1}pS9l?wZ1R@Cs@~j
zx3bpnx{$U14D0Jh0N}XRzk@Xi@8z*w@&s5$Z-aH=H(0Zh+`lvW-$2^!8>F3ofV8zc
zK>_hEZc_oQe+(5Qc?=1?1tRLu(9nHgBMq2yYH@ApY@|>UEm%Xv&PoSn5K5e(+b~Kg
zbN+=RDoQxDw&8~c_#QWZlqrdJTRjB>bl-TFA8-YZ1p@X5A^*Mkj~Jvs1V%LxoB_=(
zmjG@P0N@AbT`(U2_C*7L7>Gdt>4hd!LTcxZA^#Ctq3!bwVuOev5OCY)S{nO1m_&=o
ecuI$R(1<PNtvNA9csnU7%E0Ah;4nE##s2`fl)MT6
--- a/dom/media/mediasink/AudioSink.h
+++ b/dom/media/mediasink/AudioSink.h
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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/. */
 #if !defined(AudioSink_h__)
 #define AudioSink_h__
 
+#include "mozilla/MozPromise.h"
 #include "mozilla/nsRefPtr.h"
 #include "nsISupportsImpl.h"
 
 namespace mozilla {
 
 class MediaData;
 template <class T> class MediaQueue;
 
--- a/dom/media/mediasink/DecodedAudioDataSink.cpp
+++ b/dom/media/mediasink/DecodedAudioDataSink.cpp
@@ -40,16 +40,20 @@ DecodedAudioDataSink::DecodedAudioDataSi
   , mLastGoodPosition(0)
   , mInfo(aInfo)
   , mChannel(aChannel)
   , mStopAudioThread(false)
   , mPlaying(true)
 {
 }
 
+DecodedAudioDataSink::~DecodedAudioDataSink()
+{
+}
+
 void
 DecodedAudioDataSink::SetState(State aState)
 {
   AssertOnAudioThread();
   mPendingState = Some(aState);
 }
 
 void
--- a/dom/media/mediasink/DecodedAudioDataSink.h
+++ b/dom/media/mediasink/DecodedAudioDataSink.h
@@ -2,27 +2,31 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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/. */
 #if !defined(DecodedAudioDataSink_h__)
 #define DecodedAudioDataSink_h__
 
 #include "AudioSink.h"
+#include "MediaEventSource.h"
 #include "MediaInfo.h"
 #include "mozilla/nsRefPtr.h"
 #include "nsISupportsImpl.h"
 
 #include "mozilla/dom/AudioChannelBinding.h"
 #include "mozilla/Atomics.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/MozPromise.h"
 #include "mozilla/ReentrantMonitor.h"
 
 namespace mozilla {
+
+class AudioStream;
+
 namespace media {
 
 class DecodedAudioDataSink : public AudioSink {
 public:
 
   DecodedAudioDataSink(MediaQueue<MediaData>& aAudioQueue,
                        int64_t aStartTime,
                        const AudioInfo& aInfo,
@@ -54,17 +58,17 @@ private:
   enum State {
     AUDIOSINK_STATE_INIT,
     AUDIOSINK_STATE_PLAYING,
     AUDIOSINK_STATE_COMPLETE,
     AUDIOSINK_STATE_SHUTDOWN,
     AUDIOSINK_STATE_ERROR
   };
 
-  virtual ~DecodedAudioDataSink() {}
+  virtual ~DecodedAudioDataSink();
 
   void DispatchTask(already_AddRefed<nsIRunnable>&& event);
   void SetState(State aState);
   void ScheduleNextLoop();
   void ScheduleNextLoopCrossThread();
 
   void OnAudioQueueEvent();
   void ConnectListener();
--- a/dom/media/mediasource/ContainerParser.cpp
+++ b/dom/media/mediasource/ContainerParser.cpp
@@ -17,21 +17,16 @@
 #include "MP4Stream.h"
 #include "mp4_demuxer/AtomType.h"
 #include "mp4_demuxer/ByteReader.h"
 #endif
 #include "SourceBufferResource.h"
 
 extern PRLogModuleInfo* GetMediaSourceSamplesLog();
 
-/* Polyfill __func__ on MSVC to pass to the log. */
-#ifdef _MSC_VER
-#define __func__ __FUNCTION__
-#endif
-
 #define STRINGIFY(x) #x
 #define TOSTRING(x) STRINGIFY(x)
 #define MSE_DEBUG(name, arg, ...) MOZ_LOG(GetMediaSourceSamplesLog(), mozilla::LogLevel::Debug, (TOSTRING(name) "(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
 #define MSE_DEBUGV(name, arg, ...) MOZ_LOG(GetMediaSourceSamplesLog(), mozilla::LogLevel::Verbose, (TOSTRING(name) "(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
 
 namespace mozilla {
 
 ContainerParser::ContainerParser(const nsACString& aType)
--- a/dom/media/mediasource/MediaSourceReader.cpp
+++ b/dom/media/mediasource/MediaSourceReader.cpp
@@ -41,17 +41,16 @@ extern PRLogModuleInfo* GetMediaSourceLo
 #define EOS_FUZZ_US 125000
 
 namespace mozilla {
 
 MediaSourceReader::MediaSourceReader(MediaSourceDecoder* aDecoder)
   : MediaDecoderReader(aDecoder)
   , mLastAudioTime(0)
   , mLastVideoTime(0)
-  , mForceVideoDecodeAhead(false)
   , mOriginalSeekTime(-1)
   , mPendingSeekTime(-1)
   , mWaitingForSeekData(false)
   , mSeekToEnd(false)
   , mTimeThreshold(0)
   , mDropAudioBeforeThreshold(false)
   , mDropVideoBeforeThreshold(false)
   , mAudioDiscontinuity(false)
@@ -302,19 +301,17 @@ MediaSourceReader::OnAudioNotDecoded(Not
   if (mLastAudioTime - lastAudioTime >= EOS_FUZZ_US) {
     // No decoders are available to switch to. We will re-attempt from the last
     // failing position.
     mLastAudioTime = lastAudioTime;
   }
 }
 
 nsRefPtr<MediaDecoderReader::VideoDataPromise>
-MediaSourceReader::RequestVideoData(bool aSkipToNextKeyframe,
-                                    int64_t aTimeThreshold,
-                                    bool aForceDecodeAhead)
+MediaSourceReader::RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThreshold)
 {
   MOZ_ASSERT(OnTaskQueue());
   MOZ_DIAGNOSTIC_ASSERT(mSeekPromise.IsEmpty(), "No sample requests allowed while seeking");
   MOZ_DIAGNOSTIC_ASSERT(mVideoPromise.IsEmpty(), "No duplicate sample requests");
   nsRefPtr<VideoDataPromise> p = mVideoPromise.Ensure(__func__);
   MSE_DEBUGV("RequestVideoData(%d, %lld), mLastVideoTime=%lld",
              aSkipToNextKeyframe, aTimeThreshold, mLastVideoTime);
   if (!mVideoTrack) {
@@ -328,17 +325,16 @@ MediaSourceReader::RequestVideoData(bool
     mDropVideoBeforeThreshold = true;
   }
   if (IsSeeking()) {
     MSE_DEBUG("called mid-seek. Rejecting.");
     mVideoPromise.Reject(CANCELED, __func__);
     return p;
   }
   MOZ_DIAGNOSTIC_ASSERT(!mVideoSeekRequest.Exists());
-  mForceVideoDecodeAhead = aForceDecodeAhead;
 
   SwitchSourceResult ret = SwitchVideoSource(&mLastVideoTime);
   switch (ret) {
     case SOURCE_NEW:
       GetVideoReader()->ResetDecode();
       mVideoSeekRequest.Begin(GetVideoReader()->Seek(GetReaderVideoTime(mLastVideoTime), 0)
                              ->Then(OwnerThread(), __func__, this,
                                     &MediaSourceReader::CompleteVideoSeekAndDoRequest,
@@ -362,18 +358,17 @@ MediaSourceReader::RequestVideoData(bool
 
   return p;
 }
 
 void
 MediaSourceReader::DoVideoRequest()
 {
   mVideoRequest.Begin(GetVideoReader()->RequestVideoData(mDropVideoBeforeThreshold,
-                                                         GetReaderVideoTime(mTimeThreshold),
-                                                         mForceVideoDecodeAhead)
+                                                         GetReaderVideoTime(mTimeThreshold))
                       ->Then(OwnerThread(), __func__, this,
                              &MediaSourceReader::OnVideoDecoded,
                              &MediaSourceReader::OnVideoNotDecoded));
 }
 
 void
 MediaSourceReader::OnVideoDecoded(VideoData* aSample)
 {
@@ -889,19 +884,16 @@ MediaSourceReader::ResetDecode()
   // Do the same for any data wait promises.
   mAudioWaitPromise.RejectIfExists(WaitForDataRejectValue(MediaData::AUDIO_DATA, WaitForDataRejectValue::CANCELED), __func__);
   mVideoWaitPromise.RejectIfExists(WaitForDataRejectValue(MediaData::VIDEO_DATA, WaitForDataRejectValue::CANCELED), __func__);
 
   // Reset miscellaneous seeking state.
   mWaitingForSeekData = false;
   mPendingSeekTime = -1;
 
-  // Reset force video decode ahead.
-  mForceVideoDecodeAhead = false;
-
   // Reset all the readers.
   if (GetAudioReader()) {
     GetAudioReader()->ResetDecode();
   }
   if (GetVideoReader()) {
     GetVideoReader()->ResetDecode();
   }
 
--- a/dom/media/mediasource/MediaSourceReader.h
+++ b/dom/media/mediasource/MediaSourceReader.h
@@ -44,17 +44,17 @@ public:
   // registered TrackBuffers essential for initialization.
   void PrepareInitialization();
 
   bool IsWaitingMediaResources() override;
   bool IsWaitingOnCDMResource() override;
 
   nsRefPtr<AudioDataPromise> RequestAudioData() override;
   nsRefPtr<VideoDataPromise>
-  RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThreshold, bool aForceDecodeAhead) override;
+  RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThreshold) override;
 
   virtual size_t SizeOfVideoQueueInFrames() override;
   virtual size_t SizeOfAudioQueueInFrames() override;
 
   virtual void ReleaseMediaResources() override;
 
   void OnAudioDecoded(AudioData* aSample);
   void OnAudioNotDecoded(NotDecodedReason aReason);
@@ -250,18 +250,16 @@ private:
 #ifdef MOZ_EME
   nsRefPtr<CDMProxy> mCDMProxy;
 #endif
 
   // These are read and written on the decode task queue threads.
   int64_t mLastAudioTime;
   int64_t mLastVideoTime;
 
-  bool mForceVideoDecodeAhead;
-
   MozPromiseRequestHolder<SeekPromise> mAudioSeekRequest;
   MozPromiseRequestHolder<SeekPromise> mVideoSeekRequest;
   MozPromiseHolder<SeekPromise> mSeekPromise;
 
   // Temporary seek information while we wait for the data
   // to be added to the track buffer.
   int64_t mOriginalSeekTime;
   int64_t mPendingSeekTime;
--- a/dom/media/mediasource/ResourceQueue.cpp
+++ b/dom/media/mediasource/ResourceQueue.cpp
@@ -7,21 +7,16 @@
 #include "ResourceQueue.h"
 #include "nsDeque.h"
 #include "MediaData.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/Logging.h"
 
 extern PRLogModuleInfo* GetSourceBufferResourceLog();
 
-/* Polyfill __func__ on MSVC to pass to the log. */
-#ifdef _MSC_VER
-#define __func__ __FUNCTION__
-#endif
-
 #define SBR_DEBUG(arg, ...) MOZ_LOG(GetSourceBufferResourceLog(), mozilla::LogLevel::Debug, ("ResourceQueue(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
 #define SBR_DEBUGV(arg, ...) MOZ_LOG(GetSourceBufferResourceLog(), mozilla::LogLevel::Verbose, ("ResourceQueue(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
 
 namespace mozilla {
 
 ResourceItem::ResourceItem(MediaByteBuffer* aData)
   : mData(aData)
 {
--- a/dom/media/mediasource/SourceBufferDecoder.cpp
+++ b/dom/media/mediasource/SourceBufferDecoder.cpp
@@ -6,20 +6,16 @@
 
 #include "MediaSourceUtils.h"
 #include "SourceBufferDecoder.h"
 #include "mozilla/Logging.h"
 #include "AbstractMediaDecoder.h"
 #include "MediaDecoderReader.h"
 
 extern PRLogModuleInfo* GetMediaSourceLog();
-/* Polyfill __func__ on MSVC to pass to the log. */
-#ifdef _MSC_VER
-#define __func__ __FUNCTION__
-#endif
 
 #define MSE_DEBUG(arg, ...) MOZ_LOG(GetMediaSourceLog(), mozilla::LogLevel::Debug, ("SourceBufferDecoder(%p:%s)::%s: " arg, this, mResource->GetContentType().get(), __func__, ##__VA_ARGS__))
 
 namespace mozilla {
 
 class ReentrantMonitor;
 
 namespace layers {
--- a/dom/media/omx/AudioOffloadPlayer.cpp
+++ b/dom/media/omx/AudioOffloadPlayer.cpp
@@ -740,14 +740,13 @@ void AudioOffloadPlayer::WakeLockCreate(
 
 void AudioOffloadPlayer::WakeLockRelease()
 {
   MOZ_ASSERT(NS_IsMainThread());
   AUDIO_OFFLOAD_LOG(LogLevel::Debug, ("%s", __FUNCTION__));
   if (mWakeLock) {
     ErrorResult rv;
     mWakeLock->Unlock(rv);
-    NS_WARN_IF_FALSE(!rv.Failed(), "Failed to unlock the wakelock.");
     mWakeLock = nullptr;
   }
 }
 
 } // namespace mozilla
--- a/dom/media/omx/MediaCodecReader.cpp
+++ b/dom/media/omx/MediaCodecReader.cpp
@@ -348,18 +348,17 @@ MediaCodecReader::RequestAudioData()
     DispatchAudioTask();
   }
   MOZ_ASSERT(mAudioTrack.mAudioPromise.IsEmpty());
   return mAudioTrack.mAudioPromise.Ensure(__func__);
 }
 
 nsRefPtr<MediaDecoderReader::VideoDataPromise>
 MediaCodecReader::RequestVideoData(bool aSkipToNextKeyframe,
-                                   int64_t aTimeThreshold,
-                                   bool aForceDecodeAhead)
+                                   int64_t aTimeThreshold)
 {
   MOZ_ASSERT(OnTaskQueue());
   MOZ_ASSERT(HasVideo());
 
   int64_t threshold = sInvalidTimestampUs;
   if (aSkipToNextKeyframe && IsValidTimestampUs(aTimeThreshold)) {
     threshold = aTimeThreshold;
   }
--- a/dom/media/omx/MediaCodecReader.h
+++ b/dom/media/omx/MediaCodecReader.h
@@ -78,18 +78,17 @@ protected:
 public:
 
   // Flush the TaskQueue, flush MediaCodec and raise the mDiscontinuity.
   virtual nsresult ResetDecode() override;
 
   // Disptach a DecodeVideoFrameTask to decode video data.
   virtual nsRefPtr<VideoDataPromise>
   RequestVideoData(bool aSkipToNextKeyframe,
-                   int64_t aTimeThreshold,
-                   bool aForceDecodeAhead) override;
+                   int64_t aTimeThreshold) override;
 
   // Disptach a DecodeAduioDataTask to decode video data.
   virtual nsRefPtr<AudioDataPromise> RequestAudioData() override;
 
   virtual bool HasAudio();
   virtual bool HasVideo();
 
   virtual nsRefPtr<MediaDecoderReader::MetadataPromise> AsyncReadMetadata() override;
--- a/dom/media/omx/RtspMediaCodecReader.cpp
+++ b/dom/media/omx/RtspMediaCodecReader.cpp
@@ -77,23 +77,20 @@ nsRefPtr<MediaDecoderReader::AudioDataPr
 RtspMediaCodecReader::RequestAudioData()
 {
   EnsureActive();
   return MediaCodecReader::RequestAudioData();
 }
 
 nsRefPtr<MediaDecoderReader::VideoDataPromise>
 RtspMediaCodecReader::RequestVideoData(bool aSkipToNextKeyframe,
-                                       int64_t aTimeThreshold,
-                                       bool aForceDecodeAhead)
+                                       int64_t aTimeThreshold)
 {
   EnsureActive();
-  return MediaCodecReader::RequestVideoData(aSkipToNextKeyframe,
-                                            aTimeThreshold,
-                                            aForceDecodeAhead);
+  return MediaCodecReader::RequestVideoData(aSkipToNextKeyframe, aTimeThreshold);
 }
 
 nsRefPtr<MediaDecoderReader::MetadataPromise>
 RtspMediaCodecReader::AsyncReadMetadata()
 {
   mRtspResource->DisablePlayoutDelay();
   EnsureActive();
 
--- a/dom/media/omx/RtspMediaCodecReader.h
+++ b/dom/media/omx/RtspMediaCodecReader.h
@@ -48,18 +48,17 @@ public:
     return media::TimeIntervals::Invalid();
   }
 
   virtual void SetIdle() override;
 
   // Disptach a DecodeVideoFrameTask to decode video data.
   virtual nsRefPtr<VideoDataPromise>
   RequestVideoData(bool aSkipToNextKeyframe,
-                   int64_t aTimeThreshold,
-                   bool aForceDecodeAhead) override;
+                   int64_t aTimeThreshold) override;
 
   // Disptach a DecodeAudioDataTask to decode audio data.
   virtual nsRefPtr<AudioDataPromise> RequestAudioData() override;
 
   virtual nsRefPtr<MediaDecoderReader::MetadataPromise> AsyncReadMetadata()
     override;
 
   virtual void HandleResourceAllocated() override;
--- a/dom/media/platforms/apple/AppleVDADecoder.h
+++ b/dom/media/platforms/apple/AppleVDADecoder.h
@@ -82,17 +82,17 @@ public:
   }
 
   void DispatchOutputTask(already_AddRefed<nsIRunnable> aTask)
   {
     nsCOMPtr<nsIRunnable> task = aTask;
     if (mIsShutDown || mIsFlushing) {
       return;
     }
-    mTaskQueue->Dispatch(task.forget());
+    mTaskQueue->Dispatch(task.forget(), AbstractThread::DontAssertDispatchSuccess);
   }
 
   nsresult OutputFrame(CFRefPtr<CVPixelBufferRef> aImage,
                        AppleFrameRef aFrameRef);
 
 protected:
   // Flush and Drain operation, always run
   virtual void ProcessFlush();
--- a/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp
@@ -27,16 +27,17 @@ struct AvFormatLib
 
 template <int V> class FFmpegDecoderModule
 {
 public:
   static already_AddRefed<PlatformDecoderModule> Create();
 };
 
 static const AvFormatLib sLibs[] = {
+  { "libavformat-ffmpeg.so.56", FFmpegDecoderModule<55>::Create, 55 },
   { "libavformat.so.56", FFmpegDecoderModule<55>::Create, 55 },
   { "libavformat.so.55", FFmpegDecoderModule<55>::Create, 55 },
   { "libavformat.so.54", FFmpegDecoderModule<54>::Create, 54 },
   { "libavformat.so.53", FFmpegDecoderModule<53>::Create, 53 },
   { "libavformat.56.dylib", FFmpegDecoderModule<55>::Create, 55 },
   { "libavformat.55.dylib", FFmpegDecoderModule<55>::Create, 55 },
   { "libavformat.54.dylib", FFmpegDecoderModule<54>::Create, 54 },
   { "libavformat.53.dylib", FFmpegDecoderModule<53>::Create, 53 },
--- a/dom/media/test/test_media_selection.html
+++ b/dom/media/test/test_media_selection.html
@@ -15,16 +15,17 @@ if (SpecialPowers.Services.appinfo.name 
 }
 
 var manager = new MediaTestManager;
 
 function maketest(attach_media, name, type, check_metadata) {
   return function (token) {
     var e = document.createElement('video');
     e.preload = "metadata";
+    token = name + "-" + token;
     manager.started(token);
     var errorRun = false;
     if (check_metadata) {
       e.addEventListener('loadedmetadata', function () {
           ok(e.readyState >= HTMLMediaElement.HAVE_METADATA,
              'test ' +  token + ' readyState ' + e.readyState + ' expected >= ' + HTMLMediaElement.HAVE_METADATA);
           is(e.currentSrc.substring(e.currentSrc.length - name.length), name, 'test ' + token);
           // The load can go idle due to cache size limits
--- a/dom/media/tests/mochitest/mochitest.ini
+++ b/dom/media/tests/mochitest/mochitest.ini
@@ -84,16 +84,17 @@ skip-if = buildapp == 'b2g' || buildapp 
 [test_peerConnection_bug825703.html]
 [test_peerConnection_bug827843.html]
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
 [test_peerConnection_bug834153.html]
 [test_peerConnection_bug1013809.html]
 skip-if = toolkit == 'gonk' # B2G emulator is too slow to handle a two-way audio call reliably
 [test_peerConnection_bug1042791.html]
 skip-if = buildapp == 'b2g' || buildapp == 'mulet' || os == 'android' # bug 1043403 # Bug 1141029 Mulet parity with B2G Desktop for TC
+[test_peerConnection_bug1064223.html]
 [test_peerConnection_capturedVideo.html]
 tags=capturestream
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
 [test_peerConnection_captureStream_canvas_2d.html]
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
 [test_peerConnection_captureStream_canvas_webgl.html]
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
 # [test_peerConnection_certificates.html] # bug 1180968
--- a/dom/media/tests/mochitest/pc.js
+++ b/dom/media/tests/mochitest/pc.js
@@ -1249,72 +1249,16 @@ PeerConnectionWrapper.prototype = {
    */
   countTracksInConstraint : function(type, constraints) {
     if (!Array.isArray(constraints)) {
       return 0;
     }
     return constraints.reduce((sum, c) => sum + (c[type] ? 1 : 0), 0);
   },
 
-  /**
-   * Checks for audio in given offer options.
-   *
-   * @param options
-   *        The options to be examined.
-   */
-  audioInOfferOptions : function(options) {
-    if (!options) {
-      return 0;
-    }
-
-    var offerToReceiveAudio = options.offerToReceiveAudio;
-
-    // TODO: Remove tests of old constraint-like RTCOptions soon (Bug 1064223).
-    if (options.mandatory && options.mandatory.OfferToReceiveAudio !== undefined) {
-      offerToReceiveAudio = options.mandatory.OfferToReceiveAudio;
-    } else if (options.optional && options.optional[0] &&
-               options.optional[0].OfferToReceiveAudio !== undefined) {
-      offerToReceiveAudio = options.optional[0].OfferToReceiveAudio;
-    }
-
-    if (offerToReceiveAudio) {
-      return 1;
-    } else {
-      return 0;
-    }
-  },
-
-  /**
-   * Checks for video in given offer options.
-   *
-   * @param options
-   *        The options to be examined.
-   */
-  videoInOfferOptions : function(options) {
-    if (!options) {
-      return 0;
-    }
-
-    var offerToReceiveVideo = options.offerToReceiveVideo;
-
-    // TODO: Remove tests of old constraint-like RTCOptions soon (Bug 1064223).
-    if (options.mandatory && options.mandatory.OfferToReceiveVideo !== undefined) {
-      offerToReceiveVideo = options.mandatory.OfferToReceiveVideo;
-    } else if (options.optional && options.optional[0] &&
-               options.optional[0].OfferToReceiveVideo !== undefined) {
-      offerToReceiveVideo = options.optional[0].OfferToReceiveVideo;
-    }
-
-    if (offerToReceiveVideo) {
-      return 1;
-    } else {
-      return 0;
-    }
-  },
-
   checkLocalMediaTracks : function() {
     var observed = {};
     info(this + " Checking local tracks " + JSON.stringify(this.expectedLocalTrackInfoById));
     this._pc.getSenders().forEach(sender => {
       this.checkTrackIsExpected(sender.track, this.expectedLocalTrackInfoById, observed);
     });
 
     Object.keys(this.expectedLocalTrackInfoById).forEach(
@@ -1381,32 +1325,32 @@ PeerConnectionWrapper.prototype = {
     } else {
       this.remoteRequiresTrickleIce = requiresTrickleIce;
     }
 
     //TODO: how can we check for absence/presence of m=application?
 
     var audioTracks =
         this.countTracksInConstraint('audio', offerConstraintsList) ||
-      this.audioInOfferOptions(offerOptions);
+        ((offerOptions && offerOptions.offerToReceiveAudio) ? 1 : 0);
 
     info("expected audio tracks: " + audioTracks);
     if (audioTracks == 0) {
       ok(!desc.sdp.includes("m=audio"), "audio m-line is absent from SDP");
     } else {
       ok(desc.sdp.includes("m=audio"), "audio m-line is present in SDP");
       ok(desc.sdp.includes("a=rtpmap:109 opus/48000/2"), "OPUS codec is present in SDP");
       //TODO: ideally the rtcp-mux should be for the m=audio, and not just
       //      anywhere in the SDP (JS SDP parser bug 1045429)
       ok(desc.sdp.includes("a=rtcp-mux"), "RTCP Mux is offered in SDP");
     }
 
     var videoTracks =
         this.countTracksInConstraint('video', offerConstraintsList) ||
-      this.videoInOfferOptions(offerOptions);
+        ((offerOptions && offerOptions.offerToReceiveVideo) ? 1 : 0);
 
     info("expected video tracks: " + videoTracks);
     if (videoTracks == 0) {
       ok(!desc.sdp.includes("m=video"), "video m-line is absent from SDP");
     } else {
       ok(desc.sdp.includes("m=video"), "video m-line is present in SDP");
       if (this.h264) {
         ok(desc.sdp.includes("a=rtpmap:126 H264/90000"), "H.264 codec is present in SDP");
@@ -1762,21 +1706,21 @@ PeerConnectionWrapper.prototype = {
     isnot(numIceConnections, 0, "Number of ICE connections according to stats is not zero");
     if (answer.sdp.includes('a=group:BUNDLE')) {
       is(numIceConnections, 1, "stats reports exactly 1 ICE connection");
     } else {
       // This code assumes that no media sections have been rejected due to
       // codec mismatch or other unrecoverable negotiation failures.
       var numAudioTracks =
           this.countTracksInConstraint('audio', offerConstraintsList) ||
-        this.audioInOfferOptions(offerOptions);
+          ((offerOptions && offerOptions.offerToReceiveAudio) ? 1 : 0);
 
       var numVideoTracks =
           this.countTracksInConstraint('video', offerConstraintsList) ||
-        this.videoInOfferOptions(offerOptions);
+          ((offerOptions && offerOptions.offerToReceiveVideo) ? 1 : 0);
 
       var numDataTracks = this.dataChannels.length;
 
       var numAudioVideoDataTracks = numAudioTracks + numVideoTracks + numDataTracks;
       info("expected audio + video + data tracks: " + numAudioVideoDataTracks);
       is(numAudioVideoDataTracks, numIceConnections, "stats ICE connections matches expected A/V tracks");
     }
   },
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_bug1064223.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <script type="application/javascript" src="pc.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+  createHTML({
+    bug: "1064223",
+    title: "CreateOffer fails without streams or modern RTCOfferOptions"
+  });
+
+  runNetworkTest(function () {
+    var pc = new mozRTCPeerConnection();
+    var options = { mandatory: { OfferToReceiveVideo: true } }; // obsolete
+
+    pc.createOffer(options).then(() => ok(false, "createOffer must fail"),
+                                 e => is(e.name, "InternalError",
+                                         "createOffer must fail"))
+    .catch(e => ok(false, e.message))
+    .then(() => {
+      pc.close();
+      networkTestFinished();
+    })
+    .catch(e => ok(false, e.message));
+  });
+</script>
+</pre>
+</body>
+</html>
--- a/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveAudio.html
+++ b/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveAudio.html
@@ -9,17 +9,15 @@
   createHTML({
     bug: "850275",
     title: "Simple offer media constraint test with audio"
   });
 
   runNetworkTest(function() {
     var test = new PeerConnectionTest();
     test.setMediaConstraints([], [{audio: true}]);
-    // TODO: Stop using old constraint-like RTCOptions soon (Bug 1064223).
-    // Watch out for case-difference when fixing: { offerToReceiveAudio: true }
-    test.setOfferOptions({ mandatory: { OfferToReceiveAudio: true } });
+    test.setOfferOptions({ offerToReceiveAudio: true });
     test.run();
   });
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideo.html
+++ b/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideo.html
@@ -9,17 +9,15 @@
   createHTML({
     bug: "850275",
     title: "Simple offer media constraint test with video"
   });
 
   runNetworkTest(function() {
     var test = new PeerConnectionTest();
     test.setMediaConstraints([], [{video: true}]);
-    // TODO: Stop using old constraint-like RTCOptions soon (Bug 1064223).
-    // Watch out for case-difference when fixing: { offerToReceiveVideo: true }
-    test.setOfferOptions({ optional: [{ OfferToReceiveVideo: true }] });
+    test.setOfferOptions({ offerToReceiveVideo: true });
     test.run();
   });
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/webspeech/recognition/models/dict/en-US.dic
+++ b/dom/media/webspeech/recognition/models/dict/en-US.dic
@@ -132986,16 +132986,17 @@ zerilli	Z ER IY L IY
 zeringue	Z EH R IH NG
 zerkle	Z IH R K AH L
 zerlina	Z ER L IY N AH
 zerlinda	Z ER L IY N D AH
 zermeno	Z ER M EH N OW
 zern	Z IH R N
 zero	Z IH R OW
 0	Z IH R OW
+0(2)	OW
 zero's	Z IH R OW Z
 zero's(2)	Z IY R OW Z
 zero(2)	Z IY R OW
 zeroed	Z IH R OW D
 zeroed(2)	Z IY R OW D
 zeroes	Z IH R OW Z
 zeroes(2)	Z IY R OW Z
 zeroing	Z IY R OW IH NG
--- a/dom/plugins/base/moz.build
+++ b/dom/plugins/base/moz.build
@@ -27,33 +27,31 @@ EXPORTS += [
     'nsJSNPRuntime.h',
     'nsNPAPIPluginInstance.h',
     'nsPluginDirServiceProvider.h',
     'nsPluginHost.h',
     'nsPluginInstanceOwner.h',
     'nsPluginLogging.h',
     'nsPluginNativeWindow.h',
     'nsPluginNativeWindowGtk.h',
-    'nsPluginPlayPreviewInfo.h',
     'nsPluginsCID.h',
     'nsPluginsDir.h',
     'nsPluginTags.h',
 ]
 
 EXPORTS.mozilla += [
     'PluginPRLibrary.h',
 ]
 
 UNIFIED_SOURCES += [
     'nsJSNPRuntime.cpp',
     'nsNPAPIPluginInstance.cpp',
     'nsNPAPIPluginStreamListener.cpp',
     'nsPluginInstanceOwner.cpp',
     'nsPluginModule.cpp',
-    'nsPluginPlayPreviewInfo.cpp',
     'nsPluginStreamListenerPeer.cpp',
     'nsPluginTags.cpp',
     'PluginPRLibrary.cpp',
 ]
 
 SOURCES += [
     'nsNPAPIPlugin.cpp', # Conflict with X11 headers
     'nsPluginHost.cpp',  # Conflict with NS_NPAPIPLUGIN_CALLBACK
--- a/dom/plugins/base/nsIPluginHost.idl
+++ b/dom/plugins/base/nsIPluginHost.idl
@@ -7,41 +7,26 @@
 #include "nsISupports.idl"
 #include "nsIPluginTag.idl"
 
 %{C++
 #define MOZ_PLUGIN_HOST_CONTRACTID \
   "@mozilla.org/plugin/host;1"
 %}
 
-[scriptable, uuid(57069ada-2845-46ef-b57f-233596d1c02c)]
-interface nsIPluginPlayPreviewInfo : nsISupports
-{
-  readonly attribute AUTF8String mimeType;
-  readonly attribute boolean     ignoreCTP;
-  readonly attribute AUTF8String redirectURL;
-  readonly attribute AUTF8String whitelist;
-
-  /**
-   * Checks if pageURI and objectURI matches once of the entries in
-   * the whitelist. If whitelist is empty, returns true. 
-   */
-  boolean checkWhitelist(in AUTF8String pageURI, in AUTF8String objectURI);
-};
-
 [scriptable, function, uuid(9c311778-7c2c-4ad8-b439-b8a2786a20dd)]
 interface nsIClearSiteDataCallback : nsISupports
 {
     /**
      * callback with the result from a call to clearSiteData
      */
     void callback(in nsresult rv);
 };
 
-[scriptable, uuid(0f73bbd2-fc89-41df-b31b-38c09903d187)]
+[scriptable, uuid(f938f5ba-7093-42cd-a559-af8039d99204)]
 interface nsIPluginHost : nsISupports
 {
   /**
    * Causes the plugins directory to be searched again for new plugin
    * libraries.
    */
   void reloadPlugins();
 
@@ -98,37 +83,16 @@ interface nsIPluginHost : nsISupports
    * @param domain: the domain to test. If this argument is null, test if data
    *                is stored for any site. The base domain for the given domain
    *                will be determined; if any data for the base domain or its
    *                subdomains is found, return true.
    */
   boolean siteHasData(in nsIPluginTag plugin, in AUTF8String domain);
 
   /**
-   * Registers the play preview plugin mode for specific mime type
-   *
-   * @param mimeType: specifies plugin mime type.
-   * @param ignoreCTP: if true, the play preview ignores CTP rules, e.g.
-                       whitelisted websites, will not notify about plugin
-                       presence in the address bar.
-   * @param redirectURL: specifies url for the overlay iframe
-   * @param whitelist: specifies plugin whitelist in form of comma separated
-   *                   "[@page_url object_url|@page_url|object_url]" entries,
-   *                    e.g. @http://example.org/* http://example.org/t.swf
-   */
-  void registerPlayPreviewMimeType(in AUTF8String mimeType,
-                                   [optional] in boolean ignoreCTP,
-                                   [optional] in AUTF8String redirectURL,
-                                   [optional] in AUTF8String whitelist);
-
-  void unregisterPlayPreviewMimeType(in AUTF8String mimeType);
-
-  nsIPluginPlayPreviewInfo getPlayPreviewInfo(in AUTF8String mimeType);
-
-  /**
    * Get the "permission string" for the plugin.  This is a string that can be
    * passed to the permission manager to see whether the plugin is allowed to
    * run, for example.  This will typically be based on the plugin's "nice name"
    * and its blocklist state.
    *
    * @mimeType The MIME type we're interested in.
    * @excludeFlags Set of the EXCLUDE_* flags above, defaulting to EXCLUDE_NONE.
    */
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -1593,68 +1593,16 @@ nsPluginHost::UnregisterFakePlugin(const
       mFakePlugins.RemoveElementAt(i);
       return NS_OK;
     }
   }
 
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsPluginHost::RegisterPlayPreviewMimeType(const nsACString& mimeType,
-                                          bool ignoreCTP,
-                                          const nsACString& redirectURL,
-                                          const nsACString& whitelist)
-{
-  nsAutoCString mt(mimeType);
-  nsAutoCString url(redirectURL);
-  if (url.Length() == 0) {
-    // using default play preview iframe URL, if redirectURL is not specified
-    url.AssignLiteral("data:application/x-moz-playpreview;,");
-    url.Append(mimeType);
-  }
-  nsAutoCString wl(whitelist);
-
-  nsRefPtr<nsPluginPlayPreviewInfo> playPreview =
-    new nsPluginPlayPreviewInfo(mt.get(), ignoreCTP, url.get(), wl.get());
-  mPlayPreviewMimeTypes.AppendElement(playPreview);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPluginHost::UnregisterPlayPreviewMimeType(const nsACString& mimeType)
-{
-  nsAutoCString mimeTypeToRemove(mimeType);
-  for (uint32_t i = mPlayPreviewMimeTypes.Length(); i > 0; i--) {
-    nsRefPtr<nsPluginPlayPreviewInfo> pp = mPlayPreviewMimeTypes[i - 1];
-    if (PL_strcasecmp(pp.get()->mMimeType.get(), mimeTypeToRemove.get()) == 0) {
-      mPlayPreviewMimeTypes.RemoveElementAt(i - 1);
-      break;
-    }
-  }
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPluginHost::GetPlayPreviewInfo(const nsACString& mimeType,
-                                 nsIPluginPlayPreviewInfo** aResult)
-{
-  nsAutoCString mimeTypeToFind(mimeType);
-  for (uint32_t i = 0; i < mPlayPreviewMimeTypes.Length(); i++) {
-    nsRefPtr<nsPluginPlayPreviewInfo> pp = mPlayPreviewMimeTypes[i];
-    if (PL_strcasecmp(pp.get()->mMimeType.get(), mimeTypeToFind.get()) == 0) {
-      *aResult = new nsPluginPlayPreviewInfo(pp.get());
-      NS_ADDREF(*aResult);
-      return NS_OK;
-    }
-  }
-  *aResult = nullptr;
-  return NS_ERROR_NOT_AVAILABLE;
-}
-
 // FIXME-jsplugins Is this method actually needed?
 NS_IMETHODIMP
 nsPluginHost::GetFakePlugin(const nsACString & aMimeType,
                             nsIFakePluginTag** aResult)
 {
   nsRefPtr<nsFakePluginTag> result = FindFakePluginForType(aMimeType, false);
   if (result) {
     result.forget(aResult);
--- a/dom/plugins/base/nsPluginHost.h
+++ b/dom/plugins/base/nsPluginHost.h
@@ -7,17 +7,16 @@
 #define nsPluginHost_h_
 
 #include "nsIPluginHost.h"
 #include "nsIObserver.h"
 #include "nsCOMPtr.h"
 #include "prlink.h"
 #include "prclist.h"
 #include "nsIPluginTag.h"
-#include "nsPluginPlayPreviewInfo.h"
 #include "nsPluginsDir.h"
 #include "nsPluginDirServiceProvider.h"
 #include "nsAutoPtr.h"
 #include "nsWeakPtr.h"
 #include "nsIPrompt.h"
 #include "nsWeakReference.h"
 #include "MainThreadUtils.h"
 #include "nsTArray.h"
@@ -364,17 +363,16 @@ private:
 
   // On certain platforms, we only want to load certain plugins. This function
   // centralizes loading rules.
   bool ShouldAddPlugin(nsPluginTag* aPluginTag);
 
   nsRefPtr<nsPluginTag> mPlugins;
   nsRefPtr<nsPluginTag> mCachedPlugins;
   nsRefPtr<nsInvalidPluginTag> mInvalidPlugins;
-  nsTArray< nsRefPtr<nsPluginPlayPreviewInfo> > mPlayPreviewMimeTypes;
 
   nsTArray< nsRefPtr<nsFakePluginTag> > mFakePlugins;
 
   bool mPluginsLoaded;
 
   // set by pref plugin.override_internal_types
   bool mOverrideInternalTypes;
 
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -2132,16 +2132,18 @@ nsEventStatus nsPluginInstanceOwner::Pro
         pPluginEvent = &pluginEvent;
         break;
       case NS_BLUR_CONTENT:
         pluginEvent.event = WM_KILLFOCUS;
         pluginEvent.wParam = 0;
         pluginEvent.lParam = 0;
         pPluginEvent = &pluginEvent;
         break;
+      default:
+        break;
     }
   }
 
   if (pPluginEvent && !pPluginEvent->event) {
     // Don't send null events to plugins.
     NS_WARNING("nsPluginFrame ProcessEvent: trying to send null event to plugin.");
     return rv;
   }
@@ -2166,16 +2168,18 @@ nsEventStatus nsPluginInstanceOwner::Pro
     case eMouseEventClass:
       {
         switch (anEvent.mMessage)
           {
           case NS_MOUSE_CLICK:
           case NS_MOUSE_DOUBLECLICK:
             // Button up/down events sent instead.
             return rv;
+          default:
+            break;
           }
 
         // Get reference point relative to plugin origin.
         const nsPresContext* presContext = mPluginFrame->PresContext();
         nsPoint appPoint =
           nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mPluginFrame) -
           mPluginFrame->GetContentRectRelativeToSelf().TopLeft();
         nsIntPoint pluginPoint(presContext->AppUnitsToDevPixels(appPoint.x),
@@ -2258,16 +2262,18 @@ nsEventStatus nsPluginInstanceOwner::Pro
                   event.button = 1;
                   break;
                 }
               // information lost:
               event.subwindow = None;
               event.same_screen = True;
             }
             break;
+          default:
+            break;
           }
       }
       break;
 
    //XXX case eMouseScrollEventClass: not received.
 
    case eKeyboardEventClass:
       if (anEvent.mPluginEvent)
@@ -2289,16 +2295,18 @@ nsEventStatus nsPluginInstanceOwner::Pro
                 event.type = XKeyPress;
               break;
             case NS_KEY_PRESS:
               event.type = XKeyPress;
               break;
             case NS_KEY_UP:
               event.type = KeyRelease;
               break;
+            default:
+              break;
             }
 #endif
 
           // Information that could be obtained from pluginEvent but we may not
           // want to promise to provide:
           event.subwindow = None;
           event.x = 0;
           event.y = 0;
@@ -2312,30 +2320,31 @@ nsEventStatus nsPluginInstanceOwner::Pro
           // DOMKeyCodeToGdkKeyCode(keyEvent.keyCode) and
           // gdk_keymap_get_entries_for_keyval will be useful, but the
           // mappings will not be unique.
           NS_WARNING("Synthesized key event not sent to plugin");
         }
       break;
 
     default:
-      switch (anEvent.mMessage)
-        {
+      switch (anEvent.mMessage) {
         case NS_FOCUS_CONTENT:
         case NS_BLUR_CONTENT:
           {
             XFocusChangeEvent &event = pluginEvent.xfocus;
             event.type =
               anEvent.mMessage == NS_FOCUS_CONTENT ? FocusIn : FocusOut;
             // information lost:
             event.mode = -1;
             event.detail = NotifyDetailNone;
           }
           break;
-        }
+        default:
+          break;
+      }
     }
 
   if (!pluginEvent.type) {
     return rv;
   }
 
   // Fill in (useless) generic event information.
   XAnyEvent& event = pluginEvent.xany;
@@ -2366,16 +2375,18 @@ nsEventStatus nsPluginInstanceOwner::Pro
     case eMouseEventClass:
       {
         switch (anEvent.mMessage)
           {
           case NS_MOUSE_CLICK:
           case NS_MOUSE_DOUBLECLICK:
             // Button up/down events sent instead.
             return rv;
+          default:
+            break;
           }
 
         // Get reference point relative to plugin origin.
         const nsPresContext* presContext = mPluginFrame->PresContext();
         nsPoint appPoint =
           nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mPluginFrame) -
           mPluginFrame->GetContentRectRelativeToSelf().TopLeft();
         nsIntPoint pluginPoint(presContext->AppUnitsToDevPixels(appPoint.x),
@@ -2407,16 +2418,18 @@ nsEventStatus nsPluginInstanceOwner::Pro
               event.inSize = sizeof(ANPEvent);
               event.eventType = kMouse_ANPEventType;
               event.data.mouse.action = kUp_ANPMouseAction;
               event.data.mouse.x = pluginPoint.x;
               event.data.mouse.y = pluginPoint.y;
               mInstance->HandleEvent(&event, nullptr, NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
             }
             break;
+          default:
+            break;
           }
       }
       break;
 
     case eKeyboardEventClass:
      {
        const WidgetKeyboardEvent& keyEvent = *anEvent.AsKeyboardEvent();
        LOG("Firing eKeyboardEventClass %d %d\n",
deleted file mode 100644
--- a/dom/plugins/base/nsPluginPlayPreviewInfo.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-/* -*- 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 "nsPluginPlayPreviewInfo.h"
-#include "nsWildCard.h"
-
-using namespace mozilla;
-
-nsPluginPlayPreviewInfo::nsPluginPlayPreviewInfo(const char* aMimeType,
-                                                 bool aIgnoreCTP,
-                                                 const char* aRedirectURL,
-                                                 const char* aWhitelist)
-  : mMimeType(aMimeType), mIgnoreCTP(aIgnoreCTP), mRedirectURL(aRedirectURL),
-    mWhitelist(aWhitelist) {}
-
-nsPluginPlayPreviewInfo::nsPluginPlayPreviewInfo(
-  const nsPluginPlayPreviewInfo* aSource)
-{
-  MOZ_ASSERT(aSource);
-
-  mMimeType = aSource->mMimeType;
-  mIgnoreCTP = aSource->mIgnoreCTP;
-  mRedirectURL = aSource->mRedirectURL;
-  mWhitelist = aSource->mWhitelist;
-}
-
-nsPluginPlayPreviewInfo::~nsPluginPlayPreviewInfo()
-{
-}
-
-NS_IMPL_ISUPPORTS(nsPluginPlayPreviewInfo, nsIPluginPlayPreviewInfo)
-
-NS_IMETHODIMP
-nsPluginPlayPreviewInfo::GetMimeType(nsACString& aMimeType)
-{
-  aMimeType = mMimeType;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPluginPlayPreviewInfo::GetIgnoreCTP(bool* aIgnoreCTP)
-{
-  *aIgnoreCTP = mIgnoreCTP;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPluginPlayPreviewInfo::GetRedirectURL(nsACString& aRedirectURL)
-{
-  aRedirectURL = mRedirectURL;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPluginPlayPreviewInfo::GetWhitelist(nsACString& aWhitelist)
-{
-  aWhitelist = mWhitelist;
-  return NS_OK;
-}
-
-/* static */ nsresult
-nsPluginPlayPreviewInfo::CheckWhitelist(const nsACString& aPageURI,
-                                        const nsACString& aObjectURI,
-                                        const nsACString& aWhitelist,
-                                        bool *_retval)
-{
-  if (aWhitelist.Length() == 0) {
-    // Considering empty whitelist as '*' entry.
-    *_retval = true;
-    return NS_OK;
-  }
-
-  // Parses whitelist as comma separated entries of
-  //   [@page_url object_url|@page_url|object_url]
-  // where page_url and object_url pattern matches for aPageURI
-  // and aObjectURI, and performs matching as the same time.
-  nsACString::const_iterator start, end;
-  aWhitelist.BeginReading(start);
-  aWhitelist.EndReading(end);
-
-  nsAutoCString pageURI(aPageURI);
-  nsAutoCString objectURI(aObjectURI);
-  nsACString::const_iterator pos = start, entryStart, entryEnd;
-  nsACString::const_iterator pagePatternStart, pagePatternEnd;
-  nsACString::const_iterator objectPatternStart, objectPatternEnd;
-  int matchResult;
-  bool matched, didMatching;
-  while (pos != end) {
-    matched = true;
-    didMatching = false;
-    entryStart = pos;
-    // Looking for end of the entry.
-    while (pos != end && *pos != ',') {
-      pos++;
-    }
-    entryEnd = pos;
-    if (entryStart != entryEnd && *entryStart == '@') {
-      // Pattern for aPageURL is found, finding a space or end of the entry.
-      pagePatternStart = entryStart;
-      pagePatternStart++;
-      pagePatternEnd = pagePatternStart;
-      while (pagePatternEnd != entryEnd && *pagePatternEnd != ' ') {
-        pagePatternEnd++;
-      }
-      nsAutoCString pagePattern(Substring(pagePatternStart, pagePatternEnd));
-      matchResult = NS_WildCardMatch(pageURI.get(), pagePattern.get(), true);
-      matched &= matchResult == MATCH;
-      didMatching = true;
-      objectPatternStart = pagePatternEnd;
-    } else {
-      objectPatternStart = entryStart;
-    }
-    while (objectPatternStart != entryEnd && *objectPatternStart == ' ') {
-      objectPatternStart++;
-    }
-    if (objectPatternStart != entryEnd) {
-      // Pattern for aObjectURL is found, removing trailing spaces.
-      objectPatternEnd = entryEnd;
-      --objectPatternEnd;
-      while (objectPatternStart != objectPatternEnd &&
-             *objectPatternEnd == ' ') {
-        objectPatternEnd--;
-      };
-      objectPatternEnd++;
-      nsAutoCString objectPattern(Substring(objectPatternStart,
-                                            objectPatternEnd));
-      matchResult = NS_WildCardMatch(objectURI.get(), objectPattern.get(), true);
-      matched &= matchResult == MATCH;
-      didMatching = true;
-    }
-    // Ignoring match result for empty entries.
-    if (didMatching && matched) {
-      *_retval = true;
-      return NS_OK;
-    }
-    if (pos == end) {
-      break;
-    }
-    pos++;
-  }
-
-  *_retval = false;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPluginPlayPreviewInfo::CheckWhitelist(const nsACString& aPageURI,
-                                        const nsACString& aObjectURI,
-                                        bool *_retval)
-{
-  return CheckWhitelist(aPageURI, aObjectURI, mWhitelist, _retval);
-}
deleted file mode 100644
--- a/dom/plugins/base/nsPluginPlayPreviewInfo.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef nsPluginPlayPreviewInfo_h_
-#define nsPluginPlayPreviewInfo_h_
-
-#include "nsString.h"
-#include "nsIPluginHost.h"
-
-class nsPluginPlayPreviewInfo : public nsIPluginPlayPreviewInfo
-{
-  virtual ~nsPluginPlayPreviewInfo();
-
-public:
-   NS_DECL_ISUPPORTS
-   NS_DECL_NSIPLUGINPLAYPREVIEWINFO
-
-  nsPluginPlayPreviewInfo(const char* aMimeType,
-                          bool aIgnoreCTP,
-                          const char* aRedirectURL,
-                          const char* aWhitelist);
-  explicit nsPluginPlayPreviewInfo(const nsPluginPlayPreviewInfo* aSource);
-
-  /** This function checks aPageURI and aObjectURI against the whitelist
-   *  specified in aWhitelist. This is public static function because this
-   *  whitelist checking code needs to be accessed without any instances of
-   *  nsIPluginPlayPreviewInfo. In particular, the Shumway whitelist is
-   *  obtained directly from prefs and compared using this code for telemetry
-   *  purposes.
-   */
-  static nsresult CheckWhitelist(const nsACString& aPageURI,
-                                 const nsACString& aObjectURI,
-                                 const nsACString& aWhitelist,
-                                 bool *_retval);
-
-  nsCString mMimeType;
-  bool      mIgnoreCTP;
-  nsCString mRedirectURL;
-  nsCString mWhitelist;
-};
-
-
-#endif // nsPluginPlayPreviewInfo_h_
--- a/dom/plugins/ipc/PluginInstanceChild.cpp
+++ b/dom/plugins/ipc/PluginInstanceChild.cpp
@@ -99,28 +99,24 @@ struct RunnableMethodTraits<PluginInstan
  * We can't use gfxPlatform::CreateDrawTargetForSurface() because calling
  * gfxPlatform::GetPlatform() instantiates the prefs service, and that's not
  * allowed from processes other than the main process. So we have our own
  * version here.
  */
 static RefPtr<DrawTarget>
 CreateDrawTargetForSurface(gfxASurface *aSurface)
 {
-  SurfaceFormat format;
-  if (aSurface->GetContentType() == gfxContentType::ALPHA) {
-    format = SurfaceFormat::A8;
-  } else if (aSurface->GetContentType() == gfxContentType::COLOR) {
-    format = SurfaceFormat::B8G8R8X8;
-  } else {
-    format = SurfaceFormat::B8G8R8A8;
-  }
+  SurfaceFormat format = aSurface->GetSurfaceFormat();
   RefPtr<DrawTarget> drawTarget =
     Factory::CreateDrawTargetForCairoSurface(aSurface->CairoSurface(),
                                              aSurface->GetSize(),
                                              &format);
+  if (!drawTarget) {
+    NS_RUNTIMEABORT("CreateDrawTargetForSurface failed in plugin");
+  }
   aSurface->SetData(&kDrawTarget, drawTarget, nullptr);
   return drawTarget;
 }
 
 PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface,
                                          const nsCString& aMimeType,
                                          const uint16_t& aMode,
                                          const InfallibleTArray<nsCString>& aNames,
@@ -3252,21 +3248,38 @@ PluginInstanceChild::PaintRectToSurface(
                      DrawOptions(1.f, CompositionOp::OP_SOURCE));
         dt->PopClip();
         dt->Flush();
     }
 
     PaintRectToPlatformSurface(plPaintRect, renderSurface);
 
     if (renderSurface != aSurface) {
+      RefPtr<DrawTarget> dt;
+      if (aSurface == mCurrentSurface &&
+          aSurface->GetType() == gfxSurfaceType::Image &&
+          aSurface->GetSurfaceFormat() == SurfaceFormat::B8G8R8X8) {
+        gfxImageSurface* imageSurface = static_cast<gfxImageSurface*>(aSurface);
+        // Bug 1196927 - Reinterpret target surface as BGRA to fill alpha with opaque.
+        // Certain backends (i.e. Skia) may not truly support BGRX formats, so they must
+        // be emulated by filling the alpha channel opaque as if it was BGRA data. Cairo
+        // leaves the alpha zeroed out for BGRX, so we cause Cairo to fill it as opaque
+        // by handling the copy target as a BGRA surface.
+        dt = Factory::CreateDrawTargetForData(BackendType::CAIRO,
+                                              imageSurface->Data(),
+                                              imageSurface->GetSize(),
+                                              imageSurface->Stride(),
+                                              SurfaceFormat::B8G8R8A8);
+      } else {
         // Copy helper surface content to target
-        RefPtr<DrawTarget> dt = CreateDrawTargetForSurface(aSurface);
-        RefPtr<SourceSurface> surface =
-            gfxPlatform::GetSourceSurfaceForSurface(dt, renderSurface);
-        dt->CopySurface(surface, aRect, aRect.TopLeft());
+        dt = CreateDrawTargetForSurface(aSurface);
+      }
+      RefPtr<SourceSurface> surface =
+        gfxPlatform::GetSourceSurfaceForSurface(dt, renderSurface);
+      dt->CopySurface(surface, aRect, aRect.TopLeft());
     }
 }
 
 void
 PluginInstanceChild::PaintRectWithAlphaExtraction(const nsIntRect& aRect,
                                                   gfxASurface* aSurface)
 {
     MOZ_ASSERT(aSurface->GetContentType() == gfxContentType::COLOR_ALPHA,
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -162,36 +162,17 @@ PluginInstanceParent::InitMetadata(const
         return false;
     }
     // Ensure that the src attribute is absolute
     nsRefPtr<nsPluginInstanceOwner> owner = GetOwner();
     if (!owner) {
         return false;
     }
     nsCOMPtr<nsIURI> baseUri(owner->GetBaseURI());
-    nsresult rv = NS_MakeAbsoluteURI(mSrcAttribute, aSrcAttribute, baseUri);
-    if (NS_FAILED(rv)) {
-        return false;
-    }
-    // Check the whitelist
-    nsAutoCString baseUrlSpec;
-    rv = baseUri->GetSpec(baseUrlSpec);
-    if (NS_FAILED(rv)) {
-        return false;
-    }
-    auto whitelist = Preferences::GetCString(kShumwayWhitelistPref);
-    // Empty whitelist is interpreted by CheckWhitelist as "allow everything,"
-    // which is not valid for our use case and should be treated as a failure.
-    if (whitelist.IsEmpty()) {
-        return false;
-    }
-    rv = nsPluginPlayPreviewInfo::CheckWhitelist(baseUrlSpec, mSrcAttribute,
-                                                 whitelist,
-                                                 &mIsWhitelistedForShumway);
-    return NS_SUCCEEDED(rv);
+    return NS_SUCCEEDED(NS_MakeAbsoluteURI(mSrcAttribute, aSrcAttribute, baseUri));
 }
 
 void
 PluginInstanceParent::ActorDestroy(ActorDestroyReason why)
 {
 #if defined(OS_WIN)
     if (why == AbnormalShutdown) {
         // If the plugin process crashes, this is the only
--- a/dom/push/moz.build
+++ b/dom/push/moz.build
@@ -33,15 +33,18 @@ XPCSHELL_TESTS_MANIFESTS += [
 EXPORTS.mozilla.dom += [
     'PushManager.h',
 ]
 
 UNIFIED_SOURCES += [
     'PushManager.cpp',
 ]
 
+if CONFIG['GNU_CXX']:
+    CXXFLAGS += ['-Wshadow']
+
 FAIL_ON_WARNINGS = True
 
 LOCAL_INCLUDES += [
     '../workers',
 ]
 
 FINAL_LIBRARY = 'xul'
--- a/dom/security/SRICheck.cpp
+++ b/dom/security/SRICheck.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "SRICheck.h"
 
 #include "mozilla/Base64.h"
 #include "mozilla/Logging.h"
 #include "mozilla/Preferences.h"
 #include "nsContentUtils.h"
+#include "nsIChannel.h"
 #include "nsICryptoHash.h"
 #include "nsIDocument.h"
 #include "nsIProtocolHandler.h"
 #include "nsIScriptError.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIURI.h"
 #include "nsNetUtil.h"
 #include "nsWhitespaceTokenizer.h"
@@ -36,48 +37,58 @@ namespace mozilla {
 namespace dom {
 
 /**
  * Returns whether or not the sub-resource about to be loaded is eligible
  * for integrity checks. If it's not, the checks will be skipped and the
  * sub-resource will be loaded.
  */
 static nsresult
-IsEligible(nsIURI* aRequestURI, const CORSMode aCORSMode,
+IsEligible(nsIChannel* aChannel, const CORSMode aCORSMode,
            const nsIDocument* aDocument)
 {
-  NS_ENSURE_ARG_POINTER(aRequestURI);
+  NS_ENSURE_ARG_POINTER(aChannel);
   NS_ENSURE_ARG_POINTER(aDocument);
 
-  nsAutoCString requestSpec;
-  nsresult rv = aRequestURI->GetSpec(requestSpec);
-  NS_ENSURE_SUCCESS(rv, rv);
-  NS_ConvertUTF8toUTF16 requestSpecUTF16(requestSpec);
-
   // Was the sub-resource loaded via CORS?
   if (aCORSMode != CORS_NONE) {
     SRILOG(("SRICheck::IsEligible, CORS mode"));
     return NS_OK;
   }
 
+  nsCOMPtr<nsIURI> finalURI;
+  nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(finalURI));
+  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsIURI> originalURI;
+  rv = aChannel->GetOriginalURI(getter_AddRefs(originalURI));
+  NS_ENSURE_SUCCESS(rv, rv);
+  nsAutoCString requestSpec;
+  rv = originalURI->GetSpec(requestSpec);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (MOZ_LOG_TEST(GetSriLog(), mozilla::LogLevel::Debug)) {
+    nsAutoCString documentSpec, finalSpec;
+    aDocument->GetDocumentURI()->GetAsciiSpec(documentSpec);
+    if (finalURI) {
+      finalURI->GetSpec(finalSpec);
+    }
+    SRILOG(("SRICheck::IsEligible, documentURI=%s; requestURI=%s; finalURI=%s",
+            documentSpec.get(), requestSpec.get(), finalSpec.get()));
+  }
+
   // Is the sub-resource same-origin?
   nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
   if (NS_SUCCEEDED(ssm->CheckSameOriginURI(aDocument->GetDocumentURI(),
-                                           aRequestURI, false))) {
+                                           finalURI, false))) {
     SRILOG(("SRICheck::IsEligible, same-origin"));
     return NS_OK;
   }
-  if (MOZ_LOG_TEST(GetSriLog(), mozilla::LogLevel::Debug)) {
-    nsAutoCString documentURI;
-    aDocument->GetDocumentURI()->GetAsciiSpec(documentURI);
-    // documentURI will be empty if GetAsciiSpec failed
-    SRILOG(("SRICheck::IsEligible, NOT same origin: documentURI=%s; requestURI=%s",
-            documentURI.get(), requestSpec.get()));
-  }
+  SRILOG(("SRICheck::IsEligible, NOT same origin"));
 
+  NS_ConvertUTF8toUTF16 requestSpecUTF16(requestSpec);
   const char16_t* params[] = { requestSpecUTF16.get() };
   nsContentUtils::ReportToConsole(nsIScriptError::errorFlag,
                                   NS_LITERAL_CSTRING("Sub-resource Integrity"),
                                   aDocument,
                                   nsContentUtils::eSECURITY_PROPERTIES,
                                   "IneligibleResource",
                                   params, ArrayLength(params));
   return NS_ERROR_SRI_NOT_ELIGIBLE;
@@ -222,49 +233,53 @@ SRICheck::IntegrityMetadata(const nsAStr
       SRILOG(("SRICheck::IntegrityMetadata, no valid metadata found"));
     }
   }
   return NS_OK;
 }
 
 /* static */ nsresult
 SRICheck::VerifyIntegrity(const SRIMetadata& aMetadata,
-                          nsIURI* aRequestURI,
+                          nsIChannel* aChannel,
                           const CORSMode aCORSMode,
                           const nsAString& aString,
                           const nsIDocument* aDocument)
 {
   NS_ConvertUTF16toUTF8 utf8Hash(aString);
-  return VerifyIntegrity(aMetadata, aRequestURI, aCORSMode, utf8Hash.Length(),
+  return VerifyIntegrity(aMetadata, aChannel, aCORSMode, utf8Hash.Length(),
                          (uint8_t*)utf8Hash.get(), aDocument);
 }
 
 /* static */ nsresult
 SRICheck::VerifyIntegrity(const SRIMetadata& aMetadata,
-                          nsIURI* aRequestURI,
+                          nsIChannel* aChannel,
                           const CORSMode aCORSMode,
                           uint32_t aStringLen,
                           const uint8_t* aString,
                           const nsIDocument* aDocument)
 {
   if (MOZ_LOG_TEST(GetSriLog(), mozilla::LogLevel::Debug)) {
     nsAutoCString requestURL;
-    aRequestURI->GetAsciiSpec(requestURL);
-    // requestURL will be empty if GetAsciiSpec fails
+    nsCOMPtr<nsIURI> originalURI;
+    if (NS_SUCCEEDED(aChannel->GetOriginalURI(getter_AddRefs(originalURI))) &&
+        originalURI) {
+      originalURI->GetAsciiSpec(requestURL);
+      // requestURL will be empty if GetAsciiSpec fails
+    }
     SRILOG(("SRICheck::VerifyIntegrity, url=%s (length=%u)",
             requestURL.get(), aStringLen));
   }
 
   MOZ_ASSERT(!aMetadata.IsEmpty()); // should be checked by caller
 
   // IntegrityMetadata() checks this and returns "no metadata" if
   // it's disabled so we should never make it this far
   MOZ_ASSERT(Preferences::GetBool("security.sri.enable", false));
 
-  if (NS_FAILED(IsEligible(aRequestURI, aCORSMode, aDocument))) {
+  if (NS_FAILED(IsEligible(aChannel, aCORSMode, aDocument))) {
     return NS_OK; // ignore non-CORS resources for forward-compatibility
   }
   if (!aMetadata.IsValid()) {
     nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
                                     NS_LITERAL_CSTRING("Sub-resource Integrity"),
                                     aDocument,
                                     nsContentUtils::eSECURITY_PROPERTIES,
                                     "NoValidMetadata");
--- a/dom/security/SRICheck.h
+++ b/dom/security/SRICheck.h
@@ -6,18 +6,18 @@
 
 #ifndef mozilla_dom_SRICheck_h
 #define mozilla_dom_SRICheck_h
 
 #include "mozilla/CORSMode.h"
 #include "nsCOMPtr.h"
 #include "SRIMetadata.h"
 
+class nsIChannel;
 class nsIDocument;
-class nsIHttpChannel;
 class nsIScriptSecurityManager;
 class nsIStreamLoader;
 class nsIURI;
 
 namespace mozilla {
 namespace dom {
 
 class SRICheck final
@@ -34,27 +34,27 @@ public:
                                     const nsIDocument* aDocument,
                                     SRIMetadata* outMetadata);
 
   /**
    * Process the integrity attribute of the element.  A result of false
    * must prevent the resource from loading.
    */
   static nsresult VerifyIntegrity(const SRIMetadata& aMetadata,
-                                  nsIURI* aRequestURI,
+                                  nsIChannel* aChannel,
                                   const CORSMode aCORSMode,
                                   const nsAString& aString,
                                   const nsIDocument* aDocument);
 
   /**
    * Process the integrity attribute of the element.  A result of false
    * must prevent the resource from loading.
    */
   static nsresult VerifyIntegrity(const SRIMetadata& aMetadata,
-                                  nsIURI* aRequestURI,
+                                  nsIChannel* aChannel,
                                   const CORSMode aCORSMode,
                                   uint32_t aStringLen,
                                   const uint8_t* aString,
                                   const nsIDocument* aDocument);
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/security/nsCORSListenerProxy.cpp
+++ b/dom/security/nsCORSListenerProxy.cpp
@@ -543,16 +543,28 @@ nsCORSListenerProxy::CheckRequestApprove
 
   // Test that things worked on a HTTP level
   nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(aRequest);
   if (!http) {
     LogBlockedRequest(aRequest, "CORSRequestNotHttp", nullptr);
     return NS_ERROR_DOM_BAD_URI;
   }
 
+  nsCOMPtr<nsIHttpChannelInternal> internal = do_QueryInterface(aRequest);
+  NS_ENSURE_STATE(internal);
+  bool responseSynthesized = false;
+  if (NS_SUCCEEDED(internal->GetResponseSynthesized(&responseSynthesized)) &&
+      responseSynthesized) {
+    // For synthesized responses, we don't need to perform any checks.
+    // Note: This would be unsafe if we ever changed our behavior to allow
+    // service workers to intercept CORS preflights.
+    MOZ_ASSERT(!mIsPreflight);
+    return NS_OK;
+  }
+
   // Check the Access-Control-Allow-Origin header
   nsAutoCString allowedOriginHeader;
   rv = http->GetResponseHeader(
     NS_LITERAL_CSTRING("Access-Control-Allow-Origin"), allowedOriginHeader);
   if (NS_FAILED(rv)) {
     LogBlockedRequest(aRequest, "CORSMissingAllowOrigin", nullptr);
     return rv;
   }
@@ -1320,16 +1332,21 @@ NS_StartCORSPreflight(nsIChannel* aReque
   NS_ASSERTION(preHttp, "Failed to QI to nsIHttpChannel!");
 
   rv = preHttp->SetRequestMethod(NS_LITERAL_CSTRING("OPTIONS"));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Preflight requests should never be intercepted by service workers.
   nsCOMPtr<nsIHttpChannelInternal> preInternal = do_QueryInterface(preflightChannel);
   if (preInternal) {
+    // NOTE: We ignore CORS checks on synthesized responses (see the CORS
+    // preflights, then we need to extend the GetResponseSynthesized() check in
+    // nsCORSListenerProxy::CheckRequestApproved()). If we change our behavior
+    // here and allow service workers to intercept CORS preflights, then that
+    // check won't be safe any more.
     preInternal->ForceNoIntercept();
   }
   
   // Set up listener which will start the original channel
   nsCOMPtr<nsIStreamListener> preflightListener =
     new nsCORSPreflightListener(aRequestChannel, aListener, nullptr, aPrincipal,
                                 method, aWithCredentials);
   NS_ENSURE_TRUE(preflightListener, NS_ERROR_OUT_OF_MEMORY);
--- a/dom/security/test/sri/iframe_script_crossdomain.html
+++ b/dom/security/test/sri/iframe_script_crossdomain.html
@@ -39,16 +39,30 @@
   function bad_onloadCalled() {
     window.onloadCalled = true;
   }
 
   function good_onerrorCalled() {
     window.onerrorCalled = true;
   }
 
+  function good_incorrect301Loaded() {
+    ok(true, "A non-CORS load redirected to a different origin was loaded correctly despite an incorrect hash value.");
+  }
+  function bad_incorrect301Blocked() {
+    ok(false, "Non-CORS loads redirecting to a different origin should be loaded despite an incorrect hash value!");
+  }
+
+  function good_correct301Loaded() {
+    ok(true, "A non-CORS load redirected to a different origin was loaded correctly.");
+  }
+  function bad_correct301Blocked() {
+    ok(false, "Non-CORS loads redirecting to a different origin should be loaded!");
+  }
+
   window.onload = function() {
     SimpleTest.finish()
   }
 </script>
 
 <!-- cors-enabled. should be loaded -->
 <script src="http://example.com/tests/dom/security/test/sri/script_crossdomain1.js"
         crossorigin=""
@@ -68,16 +82,28 @@
         onerror="bad_nonsriBlocked()"></script>
 
 <!-- non-cors with invalid metadata. should trigger onload -->
 <script src="http://example.com/tests/dom/security/test/sri/script_crossdomain4.js"
         integrity="sha256-bogus"
         onload="good_nonCORSInvalidLoaded()"
         onerror="bad_nonCORSInvalidBlocked()"></script>
 
+<!-- non-cors that's same-origin initially but redirected to another origin -->
+<script src="script_301.js"
+        integrity="sha384-invalid"
+        onerror="bad_incorrect301Blocked()"
+        onload="good_incorrect301Loaded()"></script>
+
+<!-- non-cors that's same-origin initially but redirected to another origin -->
+<script src="script_301.js"
+        integrity="sha384-1NpiDI6decClMaTWSCAfUjTdx1BiOffsCPgH4lW5hCLwmHk0VyV/g6B9Sw2kD2K3"
+        onerror="bad_correct301Blocked()"
+        onload="good_correct301Loaded()"></script>
+
 <script>
   ok(window.hasCORSLoaded, "CORS-enabled resource with a correct hash");
   ok(!window.hasNonCORSLoaded, "Correct hash, but non-CORS, should be blocked");
   ok(!window.onloadCalled, "Failed loads should not call onload when they're cross-domain");
   ok(window.onerrorCalled, "Failed loads should call onerror when they're cross-domain");
 </script>
 </body>
 </html>
copy from dom/security/test/sri/iframe_style_sameorigin.html
copy to dom/security/test/sri/iframe_style_crossdomain.html
--- a/dom/security/test/sri/iframe_style_sameorigin.html
+++ b/dom/security/test/sri/iframe_style_crossdomain.html
@@ -1,74 +1,51 @@
 <!DOCTYPE HTML>
 <!-- Any copyright is dedicated to the Public Domain.
      http://creativecommons.org/publicdomain/zero/1.0/ -->
 <html>
 <head>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="application/javascript">
-    function check_styles() {
-      var redText = document.getElementById('red-text');
-      var blackText = document.getElementById('black-text');
-      var redTextColor = window.getComputedStyle(redText, null).getPropertyValue('color');
-      var blackTextColor = window.getComputedStyle(blackText, null).getPropertyValue('color');
-      ok(redTextColor == 'rgb(255, 0, 0)', "The first part should be red.");
-      ok(blackTextColor == 'rgb(0, 0, 0)', "The second part should still be black.");
-    }
-
     SimpleTest.waitForExplicitFinish();
     window.onload = function() {
-      check_styles();
       SimpleTest.finish();
     }
   </script>
   <script>
     function good_correctHashLoaded() {
-      ok(true, "A stylesheet was correctly loaded when integrity matched");
+      ok(true, "A non-CORS cross-domain stylesheet was correctly loaded when integrity matched.");
     }
     function bad_correctHashBlocked() {
-      ok(false, "We should load stylesheets with hashes that match!");
+      ok(false, "We should load non-CORS cross-domain stylesheets with hashes that match!");
     }
 
-    function good_emptyIntegrityLoaded() {
-      ok(true, "A stylesheet was correctly loaded when the integrity attribute was empty");
+    function good_incorrectHashLoaded() {
+      ok(true, "A non-CORS cross-domain stylesheet was correctly loaded even when integrity didn't match.");
     }
-    function bad_emptyIntegrityBlocked() {
-      ok(false, "We should load stylesheets with empty integrity attributes!");
+    function bad_incorrectHashBlocked() {
+      ok(false, "We should load non-CORS cross-domain stylesheets even when hashes don't match!");
     }
 
-    function good_incorrectHashBlocked() {
-      ok(true, "A stylesheet was correctly blocked, because the hash digest was wrong");
-    }
-    function bad_incorrectHashLoaded() {
-      ok(false, "We should not load stylesheets with hashes that do not match the content!");
-    }
   </script>
 
-  <!-- valid sha256 hash. should trigger onload -->
-  <link rel="stylesheet" href="style1.css"
+  <!-- valid non-CORS sha256 hash. should trigger onload -->
+  <link rel="stylesheet" href="style_301.css"
         integrity="sha256-qs8lnkunWoVldk5d5E+652yth4VTSHohlBKQvvgGwa8="
         onerror="bad_correctHashBlocked()"
         onload="good_correctHashLoaded()">
 
-  <!-- empty metadata. should trigger onload -->
-  <link rel="stylesheet" href="style2.css"
-        integrity=""
-        onerror="bad_emptyIntegrityBlocked()"
-        onload="good_emptyIntegrityLoaded()">
-
-  <!-- invalid sha256 hash. should trigger onerror -->
-  <link rel="stylesheet" href="style3.css"
+  <!-- invalid non-CORS sha256 hash. should trigger onload -->
+  <link rel="stylesheet" href="style_301.css?again"
         integrity="sha256-bogus"
-        onerror="good_incorrectHashBlocked()"
-        onload="bad_incorrectHashLoaded()">
+        onerror="bad_incorrectHashBlocked()"
+        onload="good_incorrectHashLoaded()">
 </head>
 <body>
-<p><span id="red-text">This should be red </span> and
-  <span id="black-text">this should stay black.</p>
+<p><span id="red-text">This should be red.</span></p>
 <p id="display"></p>
 <div id="content" style="display: none">
 </div>
 <pre id="test">
 </pre>
 </body>
 </html>
--- a/dom/security/test/sri/mochitest.ini
+++ b/dom/security/test/sri/mochitest.ini
@@ -1,30 +1,35 @@
 [DEFAULT]
 support-files =
   iframe_script_crossdomain.html
   iframe_script_sameorigin.html
   iframe_sri_disabled.html
+  iframe_style_crossdomain.html
   iframe_style_sameorigin.html
   script_crossdomain1.js
   script_crossdomain1.js^headers^
   script_crossdomain2.js
   script_crossdomain3.js
   script_crossdomain3.js^headers^
   script_crossdomain4.js
   script_crossdomain4.js^headers^
+  script_crossdomain5.js
+  script_crossdomain5.js^headers^
   script.js
   script.js^headers^
+  script_301.js
+  script_301.js^headers^
   script_302.js
   script_302.js^headers^
   script_401.js
   script_401.js^headers^
   style1.css
   style2.css
   style3.css
+  style_301.css
+  style_301.css^headers^
 
 [test_script_sameorigin.html]
-
 [test_script_crossdomain.html]
-
 [test_sri_disabled.html]
-
+[test_style_crossdomain.html]
 [test_style_sameorigin.html]
new file mode 100644
--- /dev/null
+++ b/dom/security/test/sri/script_301.js
@@ -0,0 +1,1 @@
+var load=false;
new file mode 100644
--- /dev/null
+++ b/dom/security/test/sri/script_301.js^headers^
@@ -0,0 +1,2 @@
+HTTP 301 Moved Permanently
+Location: http://example.com/tests/dom/security/test/sri/script_crossdomain5.js
copy from dom/security/test/sri/script_crossdomain4.js
copy to dom/security/test/sri/script_crossdomain5.js
new file mode 100644
--- /dev/null
+++ b/dom/security/test/sri/script_crossdomain5.js^headers^
@@ -0,0 +1,1 @@
+Access-Control-Allow-Origin: *
copy from dom/security/test/sri/style1.css
copy to dom/security/test/sri/style_301.css
new file mode 100644
--- /dev/null
+++ b/dom/security/test/sri/style_301.css^headers^
@@ -0,0 +1,2 @@
+HTTP 301 Moved Permanently
+Location: http://example.com/tests/dom/security/test/sri/style1.css
copy from dom/security/test/sri/test_style_sameorigin.html
copy to dom/security/test/sri/test_style_crossdomain.html
--- a/dom/security/test/sri/test_style_sameorigin.html
+++ b/dom/security/test/sri/test_style_crossdomain.html
@@ -1,18 +1,18 @@
 <!DOCTYPE HTML>
 <!-- Any copyright is dedicated to the Public Domain.
      http://creativecommons.org/publicdomain/zero/1.0/ -->
 <html>
 <head>
   <meta charset="utf-8">
-  <title>Same-origin stylesheet tests for Bug 992096</title>
+  <title>Cross-domain stylesheet tests for Bug 1196740</title>
   <script>
     SpecialPowers.setBoolPref("security.sri.enable", true);
   </script>
 </head>
 <body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=992096">Mozilla Bug 992096</a>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1196740">Mozilla Bug 1196740</a>
 <div>
-  <iframe src="iframe_style_sameorigin.html" height="100%" width="90%" frameborder="0"></iframe>
+  <iframe src="iframe_style_crossdomain.html" height="100%" width="90%" frameborder="0"></iframe>
 </div>
 </body>
 </html>
--- a/dom/smil/TimeEvent.cpp
+++ b/dom/smil/TimeEvent.cpp
@@ -12,17 +12,17 @@
 
 namespace mozilla {
 namespace dom {
 
 TimeEvent::TimeEvent(EventTarget* aOwner,
                      nsPresContext* aPresContext,
                      InternalSMILTimeEvent* aEvent)
   : Event(aOwner, aPresContext,
-          aEvent ? aEvent : new InternalSMILTimeEvent(false, 0))
+          aEvent ? aEvent : new InternalSMILTimeEvent(false, NS_EVENT_NULL))
   , mDetail(mEvent->AsSMILTimeEvent()->detail)
 {
   if (aEvent) {
     mEventIsInternal = false;
   } else {
     mEventIsInternal = true;
   }
 
--- a/dom/smil/nsSMILTimedElement.cpp
+++ b/dom/smil/nsSMILTimedElement.cpp
@@ -77,22 +77,25 @@ nsSMILTimedElement::InstanceTimeComparat
 // Helper class: AsyncTimeEventRunner
 
 namespace
 {
   class AsyncTimeEventRunner : public nsRunnable
   {
   protected:
     nsRefPtr<nsIContent> mTarget;
-    uint32_t             mMsg;
+    EventMessage         mMsg;
     int32_t              mDetail;
 
   public:
-    AsyncTimeEventRunner(nsIContent* aTarget, uint32_t aMsg, int32_t aDetail)
-      : mTarget(aTarget), mMsg(aMsg), mDetail(aDetail)
+    AsyncTimeEventRunner(nsIContent* aTarget, EventMessage aMsg,
+                         int32_t aDetail)
+      : mTarget(aTarget)
+      , mMsg(aMsg)
+      , mDetail(aDetail)
     {
     }
 
     NS_IMETHOD Run()
     {
       InternalSMILTimeEvent event(true, mMsg);
       event.detail = mDetail;
 
@@ -2360,17 +2363,17 @@ nsSMILTimedElement::NotifyChangedInterva
 
   for (uint32_t i = 0; i < times.Length(); ++i) {
     times[i]->HandleChangedInterval(container, aBeginObjectChanged,
                                     aEndObjectChanged);
   }
 }
 
 void
-nsSMILTimedElement::FireTimeEventAsync(uint32_t aMsg, int32_t aDetail)
+nsSMILTimedElement::FireTimeEventAsync(EventMessage aMsg, int32_t aDetail)
 {
   if (!mAnimationElement)
     return;
 
   nsCOMPtr<nsIRunnable> event =
     new AsyncTimeEventRunner(mAnimationElement, aMsg, aDetail);
   NS_DispatchToMainThread(event);
 }
--- a/dom/smil/nsSMILTimedElement.h
+++ b/dom/smil/nsSMILTimedElement.h
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef NS_SMILTIMEDELEMENT_H_
 #define NS_SMILTIMEDELEMENT_H_
 
+#include "mozilla/EventForwards.h"
 #include "mozilla/Move.h"
 #include "nsSMILInterval.h"
 #include "nsSMILInstanceTime.h"
 #include "nsSMILMilestone.h"
 #include "nsSMILTimeValueSpec.h"
 #include "nsSMILRepeatCount.h"
 #include "nsSMILTypes.h"
 #include "nsTArray.h"
@@ -534,17 +535,18 @@ protected:
   //      a consistent state to receive callbacks, and
   // (ii) after calling these methods we must assume that the state of the
   //      element may have changed.
   void              NotifyNewInterval();
   void              NotifyChangedInterval(nsSMILInterval* aInterval,
                                           bool aBeginObjectChanged,
                                           bool aEndObjectChanged);
 
-  void              FireTimeEventAsync(uint32_t aMsg, int32_t aDetail);
+  void              FireTimeEventAsync(mozilla::EventMessage aMsg,
+                                       int32_t aDetail);
   const nsSMILInstanceTime* GetEffectiveBeginInstance() const;
   const nsSMILInterval* GetPreviousInterval() const;
   bool              HasPlayed() const { return !mOldIntervals.IsEmpty(); }
   bool              HasClientInFillRange() const;
   bool              EndHasEventConditions() const;
   bool              AreEndTimesDependentOn(
                       const nsSMILInstanceTime* aBase) const;
 
--- a/dom/svg/SVGSVGElement.cpp
+++ b/dom/svg/SVGSVGElement.cpp
@@ -465,17 +465,17 @@ void
 SVGSVGElement::SetZoomAndPan(uint16_t aZoomAndPan, ErrorResult& rv)
 {
   if (aZoomAndPan == SVG_ZOOMANDPAN_DISABLE ||
       aZoomAndPan == SVG_ZOOMANDPAN_MAGNIFY) {
     mEnumAttributes[ZOOMANDPAN].SetBaseValue(aZoomAndPan, this);
     return;
   }
 
-  rv.ThrowRangeError(MSG_INVALID_ZOOMANDPAN_VALUE_ERROR, &aZoomAndPan);
+  rv.ThrowRangeError(MSG_INVALID_ZOOMANDPAN_VALUE_ERROR);
 }
 
 //----------------------------------------------------------------------
 // helper methods for implementing SVGZoomEvent:
 
 void
 SVGSVGElement::SetCurrentScaleTranslate(float s, float x, float y)
 {
--- a/dom/tests/mochitest/fetch/test_fetch_cors.js
+++ b/dom/tests/mochitest/fetch/test_fetch_cors.js
@@ -734,20 +734,23 @@ function testModeCors() {
       req.url += "&preflightStatus=" + test.preflightStatus;
     if (test.responseHeaders)
       req.url += "&responseHeaders=" + escape(test.responseHeaders.toSource());
     if (test.exposeHeaders)
       req.url += "&exposeHeaders=" + escape(test.exposeHeaders);
     if (test.preflightBody)
       req.url += "&preflightBody=" + escape(test.preflightBody);
 
-    var request = new Request(req.url, { method: req.method, mode: "cors",
-                                         headers: req.headers, body: req.body });
-    fetches.push((function(test, request) {
-      return fetch(request).then(function(res) {
+    fetches.push((function(test) {
+      return new Promise(function(resolve) {
+        resolve(new Request(req.url, { method: req.method, mode: "cors",
+                                         headers: req.headers, body: req.body }));
+      }).then(function(request) {
+        return fetch(request);
+      }).then(function(res) {
         ok(test.pass, "Expected test to pass for " + test.toSource());
         if (test.status) {
           is(res.status, test.status, "wrong status in test for " + test.toSource());
           is(res.statusText, test.statusMessage, "wrong status text for " + test.toSource());
         }
         else {
           is(res.status, 200, "wrong status in test for " + test.toSource());
           is(res.statusText, "OK", "wrong status text for " + test.toSource());
@@ -762,31 +765,31 @@ function testModeCors() {
             else {
               is(res.headers.get(header), test.responseHeaders[header],
                  "|Headers.get()|wrong response header (" + header + ") in test for " +
                  test.toSource());
             }
           }
         }
 
-        return res.text().then(function(v) {
-          if (test.method !== "HEAD") {
-            is(v, "<res>hello pass</res>\n",
-               "wrong responseText in test for " + test.toSource());
-          }
-          else {
-            is(v, "",
-               "wrong responseText in HEAD test for " + test.toSource());
-          }
-        });
-      }, function(e) {
-          ok(!test.pass, "Expected test failure for " + test.toSource());
-          ok(e instanceof TypeError, "Exception should be TypeError for " + test.toSource());
+        return res.text();
+      }).then(function(v) {
+        if (test.method !== "HEAD") {
+          is(v, "<res>hello pass</res>\n",
+             "wrong responseText in test for " + test.toSource());
+        }
+        else {
+          is(v, "",
+             "wrong responseText in HEAD test for " + test.toSource());
+        }
+      }).catch(function(e) {
+        ok(!test.pass, "Expected test failure for " + test.toSource());
+        ok(e instanceof TypeError, "Exception should be TypeError for " + test.toSource());
       });
-    })(test, request));
+    })(test));
   }
 
   return Promise.all(fetches);
 }
 
 function testCrossOriginCredentials() {
   var tests = [
            { pass: 1,
--- a/dom/tests/mochitest/fetch/test_request.js
+++ b/dom/tests/mochitest/fetch/test_request.js
@@ -214,16 +214,41 @@ function testMethod() {
   var r = new Request("", { method: "patch", body: "hello" });
 }
 
 function testUrlFragment() {
   var req = new Request("./request#withfragment");
   is(req.url, (new URL("./request", self.location.href)).href, "request.url should be serialized with exclude fragment flag set");
 }
 
+function testUrlMalformed() {
+  try {
+    var req = new Request("http:// example.com");
+    ok(false, "Creating a Request with a malformed URL should throw a TypeError");
+  } catch(e) {
+    is(e.name, "TypeError", "Creating a Request with a malformed URL should throw a TypeError");
+  }
+}
+
+function testUrlCredentials() {
+  try {
+    var req = new Request("http://user@example.com");
+    ok(false, "URLs with credentials should be rejected");
+  } catch(e) {
+    is(e.name, "TypeError", "URLs with credentials should be rejected");
+  }
+
+  try {
+    var req = new Request("http://user:password@example.com");
+    ok(false, "URLs with credentials should be rejected");
+  } catch(e) {
+    is(e.name, "TypeError", "URLs with credentials should be rejected");
+  }
+}
+
 function testBodyUsed() {
   var req = new Request("./bodyused", { method: 'post', body: "Sample body" });
   is(req.bodyUsed, false, "bodyUsed is initially false.");
   return req.text().then((v) => {
     is(v, "Sample body", "Body should match");
     is(req.bodyUsed, true, "After reading body, bodyUsed should be true.");
   }).then((v) => {
     return req.blob().then((v) => {
@@ -466,16 +491,18 @@ function testRequestConsumedByFailedCons
   }
   ok(!r1.bodyUsed, 'Initial request should not be consumed by failed Request constructor');
 }
 
 function runTest() {
   testDefaultCtor();
   testSimpleUrlParse();
   testUrlFragment();
+  testUrlCredentials();
+  testUrlMalformed();
   testMethod();
   testBug1109574();
   testHeaderGuard();
   testModeCorsPreflightEnumValue();
   testBug1154268();
   testRequestConsumedByFailedConstructor();
 
   return Promise.resolve()
--- a/dom/webidl/HTMLObjectElement.webidl
+++ b/dom/webidl/HTMLObjectElement.webidl
@@ -124,19 +124,16 @@ interface MozObjectLoadingContent {
   [ChromeOnly]
   const unsigned long PLUGIN_CLICK_TO_PLAY        = 8;
   // The plugin is vulnerable (update available)
   [ChromeOnly]
   const unsigned long PLUGIN_VULNERABLE_UPDATABLE = 9;
   // The plugin is vulnerable (no update available)
   [ChromeOnly]
   const unsigned long PLUGIN_VULNERABLE_NO_UPDATE = 10;
-  // The plugin is in play preview mode
-  [ChromeOnly]
-  const unsigned long PLUGIN_PLAY_PREVIEW         = 11;
 
   /**
    * The actual mime type (the one we got back from the network
    * request) for the element.
    */
   [ChromeOnly]
   readonly attribute DOMString actualType;
 
@@ -158,35 +155,35 @@ interface MozObjectLoadingContent {
 
   [ChromeOnly]
   sequence<MozPluginParameter> getPluginAttributes();
 
   [ChromeOnly]
   sequence<MozPluginParameter> getPluginParameters();
 
   /**
-   * This method will play a plugin that has been stopped by the
-   * click-to-play plugins or play-preview features.
+   * This method will play a plugin that has been stopped by the click-to-play
+   * feature.
    */
   [ChromeOnly, Throws]
   void playPlugin();
 
   /**
    * Forces a re-evaluation and reload of the tag, optionally invalidating its
    * click-to-play state.  This can be used when the MIME type that provides a
    * type has changed, for instance, to force the tag to re-evalulate the
    * handler to use.
    */
   [ChromeOnly, Throws]
   void reload(boolean aClearActivation);
 
   /**
    * This attribute will return true if the current content type has been
    * activated, either explicitly or by passing checks that would have it be
-   * click-to-play or play-preview.
+   * click-to-play.
    */
   [ChromeOnly]
   readonly attribute boolean activated;
 
   /**
    * The URL of the data/src loaded in the object. This may be null (i.e.
    * an <embed> with no src).
    */
@@ -201,22 +198,16 @@ interface MozObjectLoadingContent {
 
   /**
    * If this object currently owns a running plugin, regardless of whether or
    * not one is pending spawn/despawn.
    */
   [ChromeOnly]
   readonly attribute boolean hasRunningPlugin;
 
-  /**
-   * This method will disable the play-preview plugin state.
-   */
-  [ChromeOnly, Throws]
-  void cancelPlayPreview();
-
   [ChromeOnly, Throws]
   readonly attribute unsigned long runID;
 };
 
 /**
  * Name:Value pair type used for passing parameters to NPAPI or javascript
  * plugins.
  */
--- a/dom/workers/ServiceWorkerContainer.cpp
+++ b/dom/workers/ServiceWorkerContainer.cpp
@@ -3,16 +3,17 @@
 /* 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 "ServiceWorkerContainer.h"
 
 #include "nsIDocument.h"
 #include "nsIServiceWorkerManager.h"
+#include "nsIURL.h"
 #include "nsNetUtil.h"
 #include "nsPIDOMWindow.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 
 #include "nsCycleCollectionParticipant.h"
 #include "nsServiceManagerUtils.h"
 
@@ -95,16 +96,43 @@ ServiceWorkerContainer::RemoveReadyPromi
 }
 
 JSObject*
 ServiceWorkerContainer::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return ServiceWorkerContainerBinding::Wrap(aCx, this, aGivenProto);
 }
 
+static nsresult
+CheckForSlashEscapedCharsInPath(nsIURI* aURI)
+{
+  MOZ_ASSERT(aURI);
+
+  // A URL that can't be downcast to a standard URL is an invalid URL and should
+  // be treated as such and fail with SecurityError.
+  nsCOMPtr<nsIURL> url(do_QueryInterface(aURI));
+  if (NS_WARN_IF(!url)) {
+    return NS_ERROR_DOM_SECURITY_ERR;
+  }
+
+  nsAutoCString path;
+  nsresult rv = url->GetFilePath(path);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  ToLowerCase(path);
+  if (path.Find("%2f") != kNotFound ||
+      path.Find("%5c") != kNotFound) {
+    return NS_ERROR_DOM_TYPE_ERR;
+  }
+
+  return NS_OK;
+}
+
 already_AddRefed<Promise>
 ServiceWorkerContainer::Register(const nsAString& aScriptURL,
                                  const RegistrationOptions& aOptions,
                                  ErrorResult& aRv)
 {
   nsCOMPtr<nsISupports> promise;
 
   nsCOMPtr<nsIServiceWorkerManager> swm = mozilla::services::GetServiceWorkerManager();
@@ -139,16 +167,21 @@ ServiceWorkerContainer::Register(const n
   nsresult rv;
   nsCOMPtr<nsIURI> scriptURI;
   rv = NS_NewURI(getter_AddRefs(scriptURI), aScriptURL, nullptr, baseURI);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     aRv.ThrowTypeError(MSG_INVALID_URL, &aScriptURL);
     return nullptr;
   }
 
+  aRv = CheckForSlashEscapedCharsInPath(scriptURI);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return nullptr;
+  }
+
   // In ServiceWorkerContainer.register() the scope argument is parsed against
   // different base URLs depending on whether it was passed or not.
   nsCOMPtr<nsIURI> scopeURI;
 
   // Step 4. If none passed, parse against script's URL
   if (!aOptions.mScope.WasPassed()) {
     NS_NAMED_LITERAL_STRING(defaultScope, "./");
     rv = NS_NewURI(getter_AddRefs(scopeURI), defaultScope,
@@ -166,16 +199,21 @@ ServiceWorkerContainer::Register(const n
                    nullptr, baseURI);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       nsAutoCString spec;
       baseURI->GetSpec(spec);
       NS_ConvertUTF8toUTF16 wSpec(spec);
       aRv.ThrowTypeError(MSG_INVALID_SCOPE, &aOptions.mScope.Value(), &wSpec);
       return nullptr;
     }
+
+    aRv = CheckForSlashEscapedCharsInPath(scopeURI);
+    if (NS_WARN_IF(aRv.Failed())) {
+      return nullptr;
+    }
   }
 
   // The spec says that the "client" passed to Register() must be the global
   // where the ServiceWorkerContainer was retrieved from.
   nsCOMPtr<nsPIDOMWindow> window = GetOwner();
   MOZ_ASSERT(window);
   aRv = swm->Register(window, scopeURI, scriptURI, getter_AddRefs(promise));
   if (aRv.Failed()) {
--- a/dom/workers/ServiceWorkerManager.cpp
+++ b/dom/workers/ServiceWorkerManager.cpp
@@ -569,17 +569,17 @@ public:
 
   void
   UpdateFailed(nsresult aStatus) override
   {
     mPromise->MaybeReject(aStatus);
   }
 
   void
-  UpdateFailed(const ErrorEventInit& aErrorDesc) override
+  UpdateFailed(JSExnType aExnType, const ErrorEventInit& aErrorDesc) override
   {
     AutoJSAPI jsapi;
     jsapi.Init(mWindow);
 
     JSContext* cx = jsapi.cx();
 
     JS::Rooted<JS::Value> fnval(cx);
     if (!ToJSValue(cx, aErrorDesc.mFilename, &fnval)) {
@@ -593,17 +593,18 @@ public:
     if (!ToJSValue(cx, aErrorDesc.mMessage, &msgval)) {
       JS_ClearPendingException(cx);
       mPromise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
       return;
     }
     JS::Rooted<JSString*> msg(cx, msgval.toString());
 
     JS::Rooted<JS::Value> error(cx);
-    if (!JS::CreateError(cx, JSEXN_ERR, nullptr, fn, aErrorDesc.mLineno,
+    if ((aExnType < JSEXN_ERR) ||
+        !JS::CreateError(cx, aExnType, nullptr, fn, aErrorDesc.mLineno,
                          aErrorDesc.mColno, nullptr, msg, &error)) {
       JS_ClearPendingException(cx);
       mPromise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
       return;
     }
 
     mPromise->MaybeReject(cx, error);
   }
@@ -970,23 +971,27 @@ public:
   }
 
   void
   ComparisonResult(nsresult aStatus, bool aInCacheAndEqual,
                    const nsAString& aNewCacheName,
                    const nsACString& aMaxScope) override
   {
     nsRefPtr<ServiceWorkerRegisterJob> kungFuDeathGrip = this;
-    if (mCanceled) {
+    if (NS_WARN_IF(mCanceled)) {
       Fail(NS_ERROR_DOM_TYPE_ERR);
       return;
     }
 
     if (NS_WARN_IF(NS_FAILED(aStatus))) {
-      Fail(NS_ERROR_DOM_TYPE_ERR);
+      if (aStatus == NS_ERROR_DOM_SECURITY_ERR) {
+        Fail(aStatus);
+      } else {
+        Fail(NS_ERROR_DOM_TYPE_ERR);
+      }
       return;
     }
 
     if (aInCacheAndEqual) {
       Succeed();
       Done(NS_OK);
       return;
     }
@@ -1096,27 +1101,27 @@ public:
       data->mSetOfScopesBeingUpdated.Remove(aScopeKey);
     }
     Fail(NS_ERROR_DOM_ABORT_ERR);
   }
 
   // Public so our error handling code can use it.
   // Callers MUST hold a strong ref before calling this!
   void
-  Fail(const ErrorEventInit& aError)
+  Fail(JSExnType aExnType, const ErrorEventInit& aError)
   {
     MOZ_ASSERT(mCallback);
     nsRefPtr<ServiceWorkerUpdateFinishCallback> callback = mCallback.forget();
     // With cancellation support, we may only be running with one reference
     // from another object like a stream loader or something.
     // UpdateFailed may do something with that, so hold a ref to ourself since
     // FailCommon relies on it.
     // FailCommon does check for cancellation, but let's be safe here.
     nsRefPtr<ServiceWorkerRegisterJob> kungFuDeathGrip = this;
-    callback->UpdateFailed(aError);
+    callback->UpdateFailed(aExnType, aError);
     FailCommon(NS_ERROR_DOM_JS_EXCEPTION);
   }
 
   // Public so our error handling code can continue with a successful worker.
   void
   ContinueInstall()
   {
     // mRegistration will be null if we have already Fail()ed.
@@ -2922,17 +2927,18 @@ ServiceWorkerManager::HandleError(JSCont
                                   nsIPrincipal* aPrincipal,
                                   const nsCString& aScope,
                                   const nsString& aWorkerURL,
                                   nsString aMessage,
                                   nsString aFilename,
                                   nsString aLine,
                                   uint32_t aLineNumber,
                                   uint32_t aColumnNumber,
-                                  uint32_t aFlags)
+                                  uint32_t aFlags,
+                                  JSExnType aExnType)
 {
   AssertIsOnMainThread();
   MOZ_ASSERT(aPrincipal);
   MOZ_ASSERT(!JSREPORT_IS_WARNING(aFlags));
 
   nsAutoCString scopeKey;
   nsresult rv = PrincipalToScopeKey(aPrincipal, scopeKey);
   if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -2962,17 +2968,17 @@ ServiceWorkerManager::HandleError(JSCont
     init.mFilename = aFilename;
     init.mLineno = aLineNumber;
     init.mColno = aColumnNumber;
 
   NS_WARNING(nsPrintfCString(
               "Script error caused ServiceWorker registration to fail: %s:%u '%s'",
               NS_ConvertUTF16toUTF8(aFilename).get(), aLineNumber,
               NS_ConvertUTF16toUTF8(aMessage).get()).get());
-    regJob->Fail(init);
+    regJob->Fail(aExnType, init);
   }
 
   return true;
 }
 
 void
 ServiceWorkerRegistrationInfo::FinishActivate(bool aSuccess)
 {
--- a/dom/workers/ServiceWorkerManager.h
+++ b/dom/workers/ServiceWorkerManager.h
@@ -143,17 +143,17 @@ public:
   void UpdateSucceeded(ServiceWorkerRegistrationInfo* aInfo)
   { }
 
   virtual
   void UpdateFailed(nsresult aStatus)
   { }
 
   virtual
-  void UpdateFailed(const ErrorEventInit& aDesc)
+  void UpdateFailed(JSExnType aExnType, const ErrorEventInit& aDesc)
   { }
 };
 
 /*
  * Wherever the spec treats a worker instance and a description of said worker
  * as the same thing; i.e. "Resolve foo with
  * _GetNewestWorker(serviceWorkerRegistration)", we represent the description
  * by this class and spawn a ServiceWorker in the right global when required.
@@ -370,17 +370,18 @@ public:
               nsIPrincipal* aPrincipal,
               const nsCString& aScope,
               const nsString& aWorkerURL,
               nsString aMessage,
               nsString aFilename,
               nsString aLine,
               uint32_t aLineNumber,
               uint32_t aColumnNumber,
-              uint32_t aFlags);
+              uint32_t aFlags,
+              JSExnType aExnType);
 
   void
   GetAllClients(nsIPrincipal* aPrincipal,
                 const nsCString& aScope,
                 nsTArray<ServiceWorkerClientInfo>& aControlledDocuments);
 
   void
   MaybeClaimClient(nsIDocument* aDocument,
--- a/dom/workers/ServiceWorkerScriptCache.cpp
+++ b/dom/workers/ServiceWorkerScriptCache.cpp
@@ -361,17 +361,17 @@ public:
 
   void
   NetworkFinished(nsresult aStatus)
   {
     AssertIsOnMainThread();
 
     mNetworkFinished = true;
 
-    if (NS_FAILED(aStatus)) {
+    if (NS_WARN_IF(NS_FAILED(aStatus))) {
       if (mCC) {
         mCC->Abort();
       }
 
       ComparisonFinished(aStatus, false);
       return;
     }
 
@@ -381,17 +381,17 @@ public:
   void
   CacheFinished(nsresult aStatus, bool aInCache)
   {
     AssertIsOnMainThread();
 
     mCacheFinished = true;
     mInCache = aInCache;
 
-    if (NS_FAILED(aStatus)) {
+    if (NS_WARN_IF(NS_FAILED(aStatus))) {
       if (mCN) {
         mCN->Abort();
       }
 
       ComparisonFinished(aStatus, false);
       return;
     }
 
@@ -402,17 +402,17 @@ public:
   MaybeCompare()
   {
     AssertIsOnMainThread();
 
     if (!mNetworkFinished || (mCC && !mCacheFinished)) {
       return;
     }
 
-    if (!mCC || !mInCache) {
+    if (NS_WARN_IF(!mCC || !mInCache)) {
       ComparisonFinished(NS_OK, false);
       return;
     }
 
     ComparisonFinished(NS_OK, mCC->Buffer().Equals(mCN->Buffer()));
   }
 
   // This class manages 2 promises: 1 is to retrieve Cache object, and 2 is to
@@ -531,17 +531,17 @@ private:
   }
 
   void
   ComparisonFinished(nsresult aStatus, bool aIsEqual)
   {
     AssertIsOnMainThread();
     MOZ_ASSERT(mCallback);
 
-    if (NS_FAILED(aStatus)) {
+    if (NS_WARN_IF(NS_FAILED(aStatus))) {
       Fail(aStatus);
       return;
     }
 
     if (aIsEqual) {
       mCallback->ComparisonResult(aStatus, aIsEqual, EmptyString(), mMaxScope);
       Cleanup();
       return;
@@ -690,17 +690,21 @@ CompareNetwork::OnStreamComplete(nsIStre
   AssertIsOnMainThread();
 
   // If no channel, Abort() has been called.
   if (!mChannel) {
     return NS_OK;
   }
 
   if (NS_WARN_IF(NS_FAILED(aStatus))) {
-    mManager->NetworkFinished(aStatus);
+    if (aStatus == NS_ERROR_REDIRECT_LOOP) {
+      mManager->NetworkFinished(NS_ERROR_DOM_SECURITY_ERR);
+    } else {
+      mManager->NetworkFinished(aStatus);
+    }
     return NS_OK;
   }
 
   nsCOMPtr<nsIRequest> request;
   nsresult rv = aLoader->GetRequest(getter_AddRefs(request));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     mManager->NetworkFinished(rv);
     return NS_OK;
@@ -710,28 +714,42 @@ CompareNetwork::OnStreamComplete(nsIStre
   if (httpChannel) {
     bool requestSucceeded;
     rv = httpChannel->GetRequestSucceeded(&requestSucceeded);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       mManager->NetworkFinished(rv);
       return NS_OK;
     }
 
-    if (!requestSucceeded) {
+    if (NS_WARN_IF(!requestSucceeded)) {
       mManager->NetworkFinished(NS_ERROR_FAILURE);
       return NS_OK;
     }
 
     nsAutoCString maxScope;
     // Note: we explicitly don't check for the return value here, because the
-    // absense of the header is not an error condition.
+    // absence of the header is not an error condition.
     unused << httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Service-Worker-Allowed"),
                                              maxScope);
 
     mManager->SetMaxScope(maxScope);
+
+    nsAutoCString mimeType;
+    rv = httpChannel->GetContentType(mimeType);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      mManager->NetworkFinished(NS_ERROR_DOM_SECURITY_ERR);
+      return rv;
+    }
+
+    if (!mimeType.LowerCaseEqualsLiteral("text/javascript") &&
+        !mimeType.LowerCaseEqualsLiteral("application/x-javascript") &&
+        !mimeType.LowerCaseEqualsLiteral("application/javascript")) {
+      mManager->NetworkFinished(NS_ERROR_DOM_SECURITY_ERR);
+      return rv;
+    }
   }
   else {
     // The only supported request schemes are http, https, and app.
     // Above, we check to ensure that the request is http or https
     // based on the channel qi.  Here we test the scheme to ensure
     // that it is app.  Otherwise, bail.
     nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
     if (NS_WARN_IF(!channel)) {
@@ -747,24 +765,22 @@ CompareNetwork::OnStreamComplete(nsIStre
 
     nsAutoCString scheme;
     rv = uri->GetScheme(scheme);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       mManager->NetworkFinished(rv);
       return NS_OK;
     }
 
-    if (!scheme.LowerCaseEqualsLiteral("app")) {
+    if (NS_WARN_IF(!scheme.LowerCaseEqualsLiteral("app"))) {
       mManager->NetworkFinished(NS_ERROR_FAILURE);
       return NS_OK;      
     }
   }
 
-  // FIXME(nsm): "Extract mime type..."
-
   char16_t* buffer = nullptr;
   size_t len = 0;
 
   rv = nsScriptLoader::ConvertToUTF16(httpChannel, aString, aLen,
                                       NS_LITERAL_STRING("UTF-8"), nullptr,
                                       buffer, len);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     mManager->NetworkFinished(rv);
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -1142,17 +1142,17 @@ public:
       xpc::Throw(aCx, NS_ERROR_DOM_DATA_CLONE_ERR);
       return false;
     }
 
     nsRefPtr<MessageEvent> event = new MessageEvent(aTarget, nullptr, nullptr);
     nsresult rv =
       event->InitMessageEvent(NS_LITERAL_STRING("message"),
                               false /* non-bubbling */,
-                              true /* cancelable */,
+                              false /* non-cancelable */,
                               messageData,
                               EmptyString(),
                               EmptyString(),
                               nullptr);
     if (mEventSource) {
       nsRefPtr<ServiceWorkerClient> client =
         new ServiceWorkerWindowClient(aTarget, *mEventSource);
       event->SetSource(client);
@@ -1361,28 +1361,29 @@ class ReportErrorRunnable final : public
 {
   nsString mMessage;
   nsString mFilename;
   nsString mLine;
   uint32_t mLineNumber;
   uint32_t mColumnNumber;
   uint32_t mFlags;
   uint32_t mErrorNumber;
+  JSExnType mExnType;
 
 public:
   // aWorkerPrivate is the worker thread we're on (or the main thread, if null)
   // aTarget is the worker object that we are going to fire an error at
   // (if any).
   static bool
   ReportError(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
               bool aFireAtScope, WorkerPrivate* aTarget,
               const nsString& aMessage, const nsString& aFilename,
               const nsString& aLine, uint32_t aLineNumber,
               uint32_t aColumnNumber, uint32_t aFlags,
-              uint32_t aErrorNumber, uint64_t aInnerWindowId)
+              uint32_t aErrorNumber, JSExnType aExnType, uint64_t aInnerWindowId)
   {
     if (aWorkerPrivate) {
       aWorkerPrivate->AssertIsOnWorkerThread();
     }
     else {
       AssertIsOnMainThread();
     }
 
@@ -1477,35 +1478,36 @@ public:
       }
     }
 
     // Now fire a runnable to do the same on the parent's thread if we can.
     if (aWorkerPrivate) {
       nsRefPtr<ReportErrorRunnable> runnable =
         new ReportErrorRunnable(aWorkerPrivate, aMessage, aFilename, aLine,
                                 aLineNumber, aColumnNumber, aFlags,
-                                aErrorNumber);
+                                aErrorNumber, aExnType);
       return runnable->Dispatch(aCx);
     }
 
     // Otherwise log an error to the error console.
     LogErrorToConsole(aMessage, aFilename, aLine, aLineNumber, aColumnNumber,
                       aFlags, aInnerWindowId);
     return true;
   }
 
 private:
   ReportErrorRunnable(WorkerPrivate* aWorkerPrivate, const nsString& aMessage,
                       const nsString& aFilename, const nsString& aLine,
                       uint32_t aLineNumber, uint32_t aColumnNumber,
-                      uint32_t aFlags, uint32_t aErrorNumber)
+                      uint32_t aFlags, uint32_t aErrorNumber,
+                      JSExnType aExnType)
   : WorkerRunnable(aWorkerPrivate, ParentThreadUnchangedBusyCount),
     mMessage(aMessage), mFilename(aFilename), mLine(aLine),
     mLineNumber(aLineNumber), mColumnNumber(aColumnNumber), mFlags(aFlags),
-    mErrorNumber(aErrorNumber)
+    mErrorNumber(aErrorNumber), mExnType(aExnType)
   { }
 
   virtual void
   PostDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
                bool aDispatchResult) override
   {
     aWorkerPrivate->AssertIsOnWorkerThread();
 
@@ -1539,17 +1541,17 @@ private:
         if (aWorkerPrivate->IsServiceWorker() && !JSREPORT_IS_WARNING(mFlags)) {
           nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
           MOZ_ASSERT(swm);
           bool handled = swm->HandleError(aCx, aWorkerPrivate->GetPrincipal(),
                                           aWorkerPrivate->SharedWorkerName(),
                                           aWorkerPrivate->ScriptURL(),
                                           mMessage,
                                           mFilename, mLine, mLineNumber,
-                                          mColumnNumber, mFlags);
+                                          mColumnNumber, mFlags, mExnType);
           if (handled) {
             return true;
           }
         }
 
         aWorkerPrivate->BroadcastErrorToSharedWorkers(aCx, mMessage, mFilename,
                                                       mLine, mLineNumber,
                                                       mColumnNumber, mFlags);
@@ -1568,17 +1570,17 @@ private:
     // Don't fire this event if the JS object has been disconnected from the
     // private object.
     if (!workerIsAcceptingEvents) {
       return true;
     }
 
     return ReportError(aCx, parent, fireAtScope, aWorkerPrivate, mMessage,
                        mFilename, mLine, mLineNumber, mColumnNumber, mFlags,
-                       mErrorNumber, innerWindowId);
+                       mErrorNumber, mExnType, innerWindowId);
   }
 };
 
 class TimerRunnable final : public WorkerRunnable
 {
 public:
   explicit TimerRunnable(WorkerPrivate* aWorkerPrivate)
   : WorkerRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount)
@@ -6378,16 +6380,17 @@ WorkerPrivate::ReportError(JSContext* aC
   NS_ASSERTION(mErrorHandlerRecursionCount == 0 ||
                mErrorHandlerRecursionCount == 1,
                "Bad recursion logic!");
 
   JS_ClearPendingException(aCx);
 
   nsString message, filename, line;
   uint32_t lineNumber, columnNumber, flags, errorNumber;
+  JSExnType exnType = JSEXN_ERR;
 
   if (aReport) {
     // ErrorEvent objects don't have a |name| field the way ES |Error| objects
     // do. Traditionally (and mostly by accident), the |message| field of
     // ErrorEvent has corresponded to |Name: Message| of the original Error
     // object. Things have been cleaned up in the JS engine, so now we need to
     // format this string explicitly.
     JS::Rooted<JSString*> messageStr(aCx,
@@ -6399,16 +6402,18 @@ WorkerPrivate::ReportError(JSContext* aC
       }
     }
     filename = NS_ConvertUTF8toUTF16(aReport->filename);
     line = aReport->uclinebuf;
     lineNumber = aReport->lineno;
     columnNumber = aReport->uctokenptr - aReport->uclinebuf;
     flags = aReport->flags;
     errorNumber = aReport->errorNumber;
+    MOZ_ASSERT(aReport->exnType >= JSEXN_NONE && aReport->exnType < JSEXN_LIMIT);
+    exnType = JSExnType(aReport->exnType);
   }
   else {
     lineNumber = columnNumber = errorNumber = 0;
     flags = nsIScriptError::errorFlag | nsIScriptError::exceptionFlag;
   }
 
   if (message.IsEmpty()) {
     message = NS_ConvertUTF8toUTF16(aMessage);
@@ -6420,17 +6425,17 @@ WorkerPrivate::ReportError(JSContext* aC
   // if there was an error in the close handler or if we ran out of memory.
   bool fireAtScope = mErrorHandlerRecursionCount == 1 &&
                      !mCloseHandlerStarted &&
                      errorNumber != JSMSG_OUT_OF_MEMORY &&
                      JS::CurrentGlobalOrNull(aCx);
 
   if (!ReportErrorRunnable::ReportError(aCx, this, fireAtScope, nullptr, message,
                                         filename, line, lineNumber,
-                                        columnNumber, flags, errorNumber, 0)) {
+                                        columnNumber, flags, errorNumber, exnType, 0)) {
     JS_ReportPendingException(aCx);
   }
 
   mErrorHandlerRecursionCount--;
 }
 
 int32_t
 WorkerPrivate::SetTimeout(JSContext* aCx,
--- a/dom/workers/test/serviceworkers/mochitest.ini
+++ b/dom/workers/test/serviceworkers/mochitest.ini
@@ -242,10 +242,11 @@ skip-if = toolkit == "android" || toolki
 [test_strict_mode_warning.html]
 [test_third_party_iframes.html]
 [test_unregister.html]
 [test_workerUnregister.html]
 [test_workerUpdate.html]
 [test_workerupdatefoundevent.html]
 [test_opaque_intercept.html]
 [test_fetch_event_client_postmessage.html]
+[test_escapedSlashes.html]
 [test_eventsource_intercept.html]
 [test_not_intercept_plugin.html]
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/serviceworkers/test_escapedSlashes.html
@@ -0,0 +1,102 @@
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for escaped slashes in navigator.serviceWorker.register</title>
+  <script type="text/javascript" src="http://mochi.test:8888/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="http://mochi.test:8888/tests/SimpleTest/test.css" />
+  <base href="https://mozilla.org/">
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test"></pre>
+<script class="testbody" type="text/javascript">
+
+var tests = [
+  { status:  true,
+    scriptURL: "a.js?foo%2fbar",
+    scopeURL: null },
+  { status:  false,
+    scriptURL: "foo%2fbar",
+    scopeURL: null },
+  { status:  true,
+    scriptURL: "a.js?foo%2Fbar",
+    scopeURL: null },
+  { status:  false,
+    scriptURL: "foo%2Fbar",
+    scopeURL: null },
+  { status:  true,
+    scriptURL: "a.js?foo%5cbar",
+    scopeURL: null },
+  { status:  false,
+    scriptURL: "foo%5cbar",
+    scopeURL: null },
+  { status:  true,
+    scriptURL: "a.js?foo%2Cbar",
+    scopeURL: null },
+  { status:  false,
+    scriptURL: "foo%5Cbar",
+    scopeURL: null },
+  { status:  true,
+    scriptURL: "ok.js",
+    scopeURL: "/scope?foo%2fbar"},
+  { status:  false,
+    scriptURL: "ok.js",
+    scopeURL: "/foo%2fbar"},
+  { status:  true,
+    scriptURL: "ok.js",
+    scopeURL: "/scope?foo%2Fbar"},
+  { status:  false,
+    scriptURL: "ok.js",
+    scopeURL: "foo%2Fbar"},
+  { status:  true,
+    scriptURL: "ok.js",
+    scopeURL: "/scope?foo%5cbar"},
+  { status:  false,
+    scriptURL: "ok.js",
+    scopeURL: "foo%5cbar"},
+  { status:  true,
+    scriptURL: "ok.js",
+    scopeURL: "/scope?foo%5Cbar"},
+  { status:  false,
+    scriptURL: "ok.js",
+    scopeURL: "foo%5Cbar"},
+];
+
+function runTest() {
+  if (!tests.length) {
+    SimpleTest.finish();
+    return;
+  }
+
+  var test = tests.shift();
+  navigator.serviceWorker.register(test.scriptURL, test.scopeURL)
+    .then(reg => {
+      ok(false, "Register should fail");
+    }, err => {
+      if (!test.status) {
+        is(err.name, "TypeError", "Registration should fail with TypeError");
+      } else {
+        ok(test.status, "Register should fail");
+      }
+    })
+    .then(runTest);
+}
+
+SimpleTest.waitForExplicitFinish();
+onload = function() {
+  SpecialPowers.pushPrefEnv({"set": [
+    ["dom.serviceWorkers.exemptFromPerDomainMax", true],
+    ["dom.serviceWorkers.testing.enabled", true],
+    ["dom.serviceWorkers.enabled", true],
+  ]}, runTest);
+};
+
+</script>
+</body>
+</html>
--- a/dom/workers/test/serviceworkers/test_installation_simple.html
+++ b/dom/workers/test/serviceworkers/test_installation_simple.html
@@ -85,19 +85,19 @@
         ok(false, "404 response should fail with TypeError");
       }, function(e) {
         ok(e.name === "TypeError", "404 response should fail with TypeError");
       });
   }
 
   function redirectError() {
     return navigator.serviceWorker.register("redirect_serviceworker.sjs", { scope: "redirect_error/" }).then(function(swr) {
-        ok(false, "redirection should fail with TypeError");
+        ok(false, "redirection should fail");
       }, function (e) {
-        ok(e.name === "TypeError", "redirection should fail with TypeError");
+        ok(e.name === "SecurityError", "redirection should fail with SecurityError");
       });
   }
 
   function parseError() {
     var p = navigator.serviceWorker.register("parse_error_worker.js", { scope: "parse_error/" });
     return p.then(function(wr) {
       ok(false, "Registration should fail with parse error");
       return navigator.serviceWorker.getRegistration("parse_error/").then(function(swr) {
--- a/dom/xml/moz.build
+++ b/dom/xml/moz.build
@@ -26,16 +26,19 @@ UNIFIED_SOURCES += [
     'nsXMLElement.cpp',
     'nsXMLFragmentContentSink.cpp',
     'nsXMLPrettyPrinter.cpp',
     'ProcessingInstruction.cpp',
     'XMLDocument.cpp',
     'XMLStylesheetProcessingInstruction.cpp',
 ]
 
+if CONFIG['GNU_CXX']:
+    CXXFLAGS += ['-Wshadow']
+
 FAIL_ON_WARNINGS = True
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '/caps',
     '/dom/base',
     '/dom/html',
--- a/dom/xslt/xml/moz.build
+++ b/dom/xslt/xml/moz.build
@@ -4,16 +4,19 @@
 # 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/.
 
 UNIFIED_SOURCES += [
     'txXMLParser.cpp',
     'txXMLUtils.cpp',
 ]
 
+if CONFIG['GNU_CXX']:
+    CXXFLAGS += ['-Wshadow']
+
 FAIL_ON_WARNINGS = True
 
 LOCAL_INCLUDES += [
     '../base',
     '../xpath',
     '../xslt',
     '/dom/base',
 ]
--- a/editor/libeditor/nsEditorEventListener.cpp
+++ b/editor/libeditor/nsEditorEventListener.cpp
@@ -464,16 +464,18 @@ nsEditorEventListener::HandleEvent(nsIDO
       return HandleText(aEvent);
     // compositionstart
     case NS_COMPOSITION_START:
       return HandleStartComposition(aEvent);
     // compositionend
     case NS_COMPOSITION_END:
       HandleEndComposition(aEvent);
       return NS_OK;
+    default:
+      break;
   }
 
   nsAutoString eventType;
   aEvent->GetType(eventType);
   // We should accept "focus" and "blur" event even if it's synthesized with
   // wrong interface for compatibility with older Gecko.
   if (eventType.EqualsLiteral("focus")) {
     return Focus(aEvent);
--- a/editor/libeditor/nsEditorUtils.cpp
+++ b/editor/libeditor/nsEditorUtils.cpp
@@ -26,19 +26,21 @@ class nsRange;
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 /******************************************************************************
  * nsAutoSelectionReset
  *****************************************************************************/
 
-nsAutoSelectionReset::nsAutoSelectionReset(Selection* aSel, nsEditor* aEd)
+nsAutoSelectionReset::nsAutoSelectionReset(Selection* aSel, nsEditor* aEd
+                                           MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
   : mSel(nullptr), mEd(nullptr)
 {
+  MOZ_GUARD_OBJECT_NOTIFIER_INIT;
   if (!aSel || !aEd) return;    // not much we can do, bail.
   if (aEd->ArePreservingSelection()) return;   // we already have initted mSavedSel, so this must be nested call.
   mSel = aSel;
   mEd = aEd;
   if (mSel)
   {
     mEd->PreserveSelectionAcrossActions(mSel);
   }
@@ -61,32 +63,34 @@ nsAutoSelectionReset::Abort()
     mEd->StopPreservingSelection();
 }
 
 
 /******************************************************************************
  * some helper classes for iterating the dom tree
  *****************************************************************************/
 
-nsDOMIterator::nsDOMIterator(nsINode& aNode)
+nsDOMIterator::nsDOMIterator(nsINode& aNode MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
 {
+  MOZ_GUARD_OBJECT_NOTIFIER_INIT;
   mIter = NS_NewContentIterator();
   DebugOnly<nsresult> res = mIter->Init(&aNode);
   MOZ_ASSERT(NS_SUCCEEDED(res));
 }
 
 nsresult
 nsDOMIterator::Init(nsRange& aRange)
 {
   mIter = NS_NewContentIterator();
   return mIter->Init(&aRange);
 }
 
-nsDOMIterator::nsDOMIterator()
+nsDOMIterator::nsDOMIterator(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)
 {
+  MOZ_GUARD_OBJECT_NOTIFIER_INIT;
 }
 
 nsDOMIterator::~nsDOMIterator()
 {
 }
 
 void