Merge mozilla-central to autoland
authorarthur.iakab <aiakab@mozilla.com>
Wed, 24 Oct 2018 07:17:07 +0300
changeset 491053 c3e9b06cc27d0555af93b5c8feba00614f904052
parent 491052 39abbcc4230bd8f4e6a6f54c5b771eff57cbb0df (current diff)
parent 491047 079c7a062b23950449e9ce1ef809ff43026cc259 (diff)
child 491054 02d8210b89048b964a604d60b25b94d95b579cfb
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
milestone65.0a1
Merge mozilla-central to autoland
dom/canvas/test/imagebitmap_extensions.html
dom/canvas/test/imagebitmap_extensions.js
dom/canvas/test/imagebitmap_extensions_data.js
dom/canvas/test/imagebitmap_extensions_on_worker.js
dom/canvas/test/imagebitmap_extensions_prepareSources.js
dom/canvas/test/test_imagebitmap_extensions.html
dom/canvas/test/test_imagebitmap_extensions_on_worker.html
taskcluster/scripts/misc/build-mingw32-fxc2.sh
--- a/browser/components/payments/test/browser/browser.ini
+++ b/browser/components/payments/test/browser/browser.ini
@@ -6,17 +6,17 @@ prefs =
   extensions.formautofill.creditCards.available=true
 skip-if = !e10s # Bug 1365964 - Payment Request isn't implemented for non-e10s
 support-files =
   blank_page.html
 
 [browser_address_edit.js]
 skip-if = verify && debug && os == 'mac'
 [browser_card_edit.js]
-skip-if = (verify && debug && os == 'mac') || (os == 'linux' && debug) # bug 1465673
+skip-if = debug && (os == 'mac' || os == 'linux') # bug 1465673
 [browser_change_shipping.js]
 [browser_dropdowns.js]
 [browser_host_name.js]
 [browser_onboarding_wizard.js]
 [browser_openPreferences.js]
 [browser_payment_completion.js]
 [browser_profile_storage.js]
 [browser_request_serialization.js]
--- a/dom/base/DOMPrefsInternal.h
+++ b/dom/base/DOMPrefsInternal.h
@@ -9,17 +9,16 @@
 // The format is as follows:
 //
 //   DOM_WEBIDL_PREF(foo_bar)
 //
 //   * This defines DOMPrefs::foo_bar(JSContext* aCx, JSObject* aObj) which
 //     returns the value of StaticPrefs::foo_bar().
 //     This is allows the use of DOMPrefs in WebIDL files.
 
-DOM_WEBIDL_PREF(canvas_imagebitmap_extensions_enabled)
 DOM_WEBIDL_PREF(dom_caches_enabled)
 DOM_WEBIDL_PREF(dom_webnotifications_serviceworker_enabled)
 DOM_WEBIDL_PREF(dom_webnotifications_requireinteraction_enabled)
 DOM_WEBIDL_PREF(dom_serviceWorkers_enabled)
 DOM_WEBIDL_PREF(dom_storageManager_enabled)
 DOM_WEBIDL_PREF(dom_testing_structuredclonetester_enabled)
 DOM_WEBIDL_PREF(dom_promise_rejection_events_enabled)
 DOM_WEBIDL_PREF(dom_push_enabled)
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -3090,17 +3090,18 @@ nsGlobalWindowInner::GetOwnPropertyNames
     aRv.NoteJSContextException(aCx);
   }
 }
 
 /* static */ bool
 nsGlobalWindowInner::IsPrivilegedChromeWindow(JSContext* aCx, JSObject* aObj)
 {
   // For now, have to deal with XPConnect objects here.
-  return xpc::WindowOrNull(aObj)->IsChromeWindow() &&
+  nsGlobalWindowInner* win = xpc::WindowOrNull(aObj);
+  return win && win->IsChromeWindow() &&
          nsContentUtils::ObjectPrincipal(aObj) == nsContentUtils::GetSystemPrincipal();
 }
 
 /* static */ bool
 nsGlobalWindowInner::OfflineCacheAllowedForContext(JSContext* aCx, JSObject* aObj)
 {
   return IsSecureContextOrObjectIsFromSecureContext(aCx, aObj) ||
          Preferences::GetBool("browser.cache.offline.insecure.enable");
@@ -7710,58 +7711,28 @@ nsGlobalWindowInner::FireOnNewGlobalObje
 #error "Never include windows.h in this file!"
 #endif
 
 already_AddRefed<Promise>
 nsGlobalWindowInner::CreateImageBitmap(JSContext* aCx,
                                        const ImageBitmapSource& aImage,
                                        ErrorResult& aRv)
 {
-  if (aImage.IsArrayBuffer() || aImage.IsArrayBufferView()) {
-    aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
-    return nullptr;
-  }
-
   return ImageBitmap::Create(this, aImage, Nothing(), aRv);
 }
 
 already_AddRefed<Promise>
 nsGlobalWindowInner::CreateImageBitmap(JSContext* aCx,
                                        const ImageBitmapSource& aImage,
                                        int32_t aSx, int32_t aSy, int32_t aSw, int32_t aSh,
                                        ErrorResult& aRv)
 {
-  if (aImage.IsArrayBuffer() || aImage.IsArrayBufferView()) {
-    aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
-    return nullptr;
-  }
-
   return ImageBitmap::Create(this, aImage, Some(gfx::IntRect(aSx, aSy, aSw, aSh)), aRv);
 }
 
-already_AddRefed<mozilla::dom::Promise>
-nsGlobalWindowInner::CreateImageBitmap(JSContext* aCx,
-                                       const ImageBitmapSource& aImage,
-                                       int32_t aOffset, int32_t aLength,
-                                       ImageBitmapFormat aFormat,
-                                       const Sequence<ChannelPixelLayout>& aLayout,
-                                       ErrorResult& aRv)
-{
-  if (!StaticPrefs::canvas_imagebitmap_extensions_enabled()) {
-    aRv.Throw(NS_ERROR_TYPE_ERR);
-    return nullptr;
-  }
-  if (aImage.IsArrayBuffer() || aImage.IsArrayBufferView()) {
-    return ImageBitmap::Create(this, aImage, aOffset, aLength, aFormat, aLayout,
-                               aRv);
-  }
-  aRv.Throw(NS_ERROR_TYPE_ERR);
-  return nullptr;
-}
-
 mozilla::dom::TabGroup*
 nsGlobalWindowInner::TabGroupInner()
 {
   // If we don't have a TabGroup yet, try to get it from the outer window and
   // cache it.
   if (!mTabGroup) {
     nsGlobalWindowOuter* outer = GetOuterWindowInternal();
     // This will never be called without either an outer window, or a cached tab group.
--- a/dom/base/nsGlobalWindowInner.h
+++ b/dom/base/nsGlobalWindowInner.h
@@ -919,25 +919,16 @@ public:
                     mozilla::ErrorResult& aRv);
 
   already_AddRefed<mozilla::dom::Promise>
   CreateImageBitmap(JSContext* aCx,
                     const mozilla::dom::ImageBitmapSource& aImage,
                     int32_t aSx, int32_t aSy, int32_t aSw, int32_t aSh,
                     mozilla::ErrorResult& aRv);
 
-  already_AddRefed<mozilla::dom::Promise>
-  CreateImageBitmap(JSContext* aCx,
-                    const mozilla::dom::ImageBitmapSource& aImage,
-                    int32_t aOffset, int32_t aLength,
-                    mozilla::dom::ImageBitmapFormat aFormat,
-                    const mozilla::dom::Sequence<mozilla::dom::ChannelPixelLayout>& aLayout,
-                    mozilla::ErrorResult& aRv);
-
-
   // ChromeWindow bits.  Do NOT call these unless your window is in
   // fact chrome.
   uint16_t WindowState();
   bool IsFullyOccluded();
   nsIBrowserDOMWindow* GetBrowserDOMWindow(mozilla::ErrorResult& aError);
   void SetBrowserDOMWindow(nsIBrowserDOMWindow* aBrowserWindow,
                            mozilla::ErrorResult& aError);
   void GetAttention(mozilla::ErrorResult& aError);
--- a/dom/base/test/chrome/file_bug1139964.xul
+++ b/dom/base/test/chrome/file_bug1139964.xul
@@ -27,27 +27,27 @@ https://bugzilla.mozilla.org/show_bug.cg
                        hasWindow: ("Window" in this),
                      });
   }
 
   function processListener(m) {
     ppm.removeMessageListener(msgName, processListener);
     ok(m.data.hasPromise, "ProcessGlobal should have Promise object in the global scope!");
     ok(m.data.hasTextEncoder, "ProcessGlobal should have TextEncoder object in the global scope!");
-    ok(!m.data.hasWindow, "ProcessGlobal should not have Window object in the global scope!");
+    ok(m.data.hasWindow, "ProcessGlobal should have Window object in the global scope!");
 
     messageManager.addMessageListener(msgName, tabListener)
     messageManager.loadFrameScript("data:,(" + mmScriptForPromiseTest.toString() + ")()", true);
   }
 
   function tabListener(m) {
     messageManager.removeMessageListener(msgName, tabListener);
     ok(m.data.hasPromise, "TabChildGlobal should have Promise object in the global scope!");
     ok(m.data.hasTextEncoder, "TabChildGlobal should have TextEncoder object in the global scope!");
-    ok(!m.data.hasWindow, "TabChildGlobal should not have Window object in the global scope!");
+    ok(m.data.hasWindow, "TabChildGlobal should have Window object in the global scope!");
 
     opener.setTimeout("done()", 0);
     window.close();
   }
 
   function run() {
     ppm.addMessageListener(msgName, processListener)
     ppm.loadProcessScript("data:,(" + mmScriptForPromiseTest.toString() + ")()", true);
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -459,20 +459,16 @@ DOMInterfaces = {
     'headerFile': 'IDBEvents.h',
 },
 
 'IID': {
     'nativeType': 'nsIJSID',
     'headerFile': 'xpcjsid.h',
 },
 
-'ImageBitmap': {
-    'implicitJSContext': [ 'mapDataInto' ],
-},
-
 'ImageCapture': {
     'binaryNames': { 'videoStreamTrack': 'GetVideoStreamTrack' }
 },
 
 'ImageData': {
     'wrapperCache': False,
 },
 
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -2968,49 +2968,63 @@ class CGCreateInterfaceObjectsMethod(CGA
         getConstructorProto += "(aCx)"
 
         needInterfaceObject = self.descriptor.interface.hasInterfaceObject()
         needInterfacePrototypeObject = self.descriptor.interface.hasInterfacePrototypeObject()
 
         # if we don't need to create anything, why are we generating this?
         assert needInterfaceObject or needInterfacePrototypeObject
 
+        def maybecrash(reason):
+            if self.descriptor.name == "Document":
+                return 'MOZ_CRASH("Bug 1405521/1488480: %s");\n' % reason
+            return ""
+
         getParentProto = fill(
             """
             JS::${type}<JSObject*> parentProto(${getParentProto});
             if (!parentProto) {
+              $*{maybeCrash}
               return;
             }
             """,
+            maybeCrash=maybecrash("Can't get Node.prototype"),
             type=parentProtoType,
             getParentProto=getParentProto)
 
         getConstructorProto = fill(
             """
             JS::${type}<JSObject*> constructorProto(${getConstructorProto});
             if (!constructorProto) {
+              $*{maybeCrash}
               return;
             }
             """,
+            maybeCrash=maybecrash("Can't get Node"),
             type=constructorProtoType,
             getConstructorProto=getConstructorProto)
 
         idsToInit = []
         # There is no need to init any IDs in bindings that don't want Xrays.
         if self.descriptor.wantsXrays:
             if self.properties.hasNonChromeOnly():
                 idsToInit.append("sNativeProperties")
             if self.properties.hasChromeOnly():
                 idsToInit.append("sChromeOnlyNativeProperties")
         if len(idsToInit) > 0:
             initIdCalls = ["!InitIds(aCx, %s.Upcast())" % (properties)
                            for properties in idsToInit]
             idsInitedFlag = CGGeneric("static bool sIdsInited = false;\n")
             setFlag = CGGeneric("sIdsInited = true;\n")
-            initIdConditionals = [CGIfWrapper(CGGeneric("return;\n"), call)
+            initIdConditionals = [CGIfWrapper(CGGeneric(fill(
+                """
+                $*{maybeCrash}
+                return;
+                """,
+                maybeCrash=maybecrash("Can't init IDs"))), call)
                                   for call in initIdCalls]
             initIds = CGList([idsInitedFlag,
                               CGIfWrapper(CGList(initIdConditionals + [setFlag]),
                                           "!sIdsInited && NS_IsMainThread()")])
         else:
             initIds = None
 
         prefCacheData = []
@@ -3203,20 +3217,22 @@ class CGCreateInterfaceObjectsMethod(CGA
                 holderProto = "*protoCache"
             createUnforgeableHolder = CGGeneric(fill(
                 """
                 JS::Rooted<JSObject*> unforgeableHolder(aCx);
                 {
                   JS::Rooted<JSObject*> holderProto(aCx, ${holderProto});
                   unforgeableHolder = JS_NewObjectWithoutMetadata(aCx, ${holderClass}, holderProto);
                   if (!unforgeableHolder) {
+                    $*{maybeCrash}
                     $*{failureCode}
                   }
                 }
                 """,
+                maybeCrash=maybecrash("Can't create unforgeable holder"),
                 holderProto=holderProto,
                 holderClass=holderClass,
                 failureCode=failureCode))
             defineUnforgeables = InitUnforgeablePropertiesOnHolder(self.descriptor,
                                                                    self.properties,
                                                                    failureCode)
             createUnforgeableHolder = CGList(
                 [createUnforgeableHolder, defineUnforgeables])
@@ -3542,22 +3558,32 @@ def InitUnforgeablePropertiesOnHolder(de
     """
     assert (properties.unforgeableAttrs.hasNonChromeOnly() or
             properties.unforgeableAttrs.hasChromeOnly() or
             properties.unforgeableMethods.hasNonChromeOnly() or
             properties.unforgeableMethods.hasChromeOnly())
 
     unforgeables = []
 
+    if descriptor.name == "Document":
+        maybeCrash = dedent(
+            """
+            MOZ_CRASH("Bug 1405521/1488480: Can't define unforgeable attributes");
+            """);
+    else:
+        maybeCrash = "";
+
     defineUnforgeableAttrs = fill(
         """
         if (!DefineUnforgeableAttributes(aCx, ${holderName}, %s)) {
+          $*{maybeCrash}
           $*{failureCode}
         }
         """,
+        maybeCrash=maybeCrash,
         failureCode=failureCode,
         holderName=holderName)
     defineUnforgeableMethods = fill(
         """
         if (!DefineUnforgeableMethods(aCx, ${holderName}, %s)) {
           $*{failureCode}
         }
         """,
@@ -17194,17 +17220,17 @@ class GlobalGenRoots():
         # Done.
         return curr
 
     @staticmethod
     def ResolveSystemBinding(config):
         curr = CGList([], "\n")
 
         descriptors = config.getDescriptors(hasInterfaceObject=True,
-                                            isExposedInSystemGlobals=True,
+                                            isExposedInWindow=True,
                                             register=True)
         properties = [desc.name for desc in descriptors]
 
         curr.append(CGStringTable("IdString", properties, static=True))
 
         initValues = []
         for desc in descriptors:
             bindingNS = toBindingNamespace(desc.name)
@@ -17239,17 +17265,17 @@ class GlobalGenRoots():
         curr = CGNamespace.build(['mozilla', 'dom'],
                                  CGWrapper(curr, post='\n'))
         curr = CGWrapper(curr, post='\n')
 
         # Add the includes
         defineIncludes = [CGHeaders.getDeclarationFilename(desc.interface)
                           for desc in config.getDescriptors(hasInterfaceObject=True,
                                                             register=True,
-                                                            isExposedInSystemGlobals=True)]
+                                                            isExposedInWindow=True)]
         defineIncludes.append("nsThreadUtils.h")  # For NS_IsMainThread
         defineIncludes.append("js/Id.h")  # For jsid
         defineIncludes.append("mozilla/dom/WebIDLGlobalNameHash.h")
 
         curr = CGHeaders([], [], [], [], [], defineIncludes,
                          'ResolveSystemBinding', curr)
 
         # Add include guards.
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -245,18 +245,16 @@ class Configuration(DescriptorProvider):
             elif key == 'isNavigatorProperty':
                 getter = lambda x: x.interface.isNavigatorProperty()
             elif key == 'isExposedInAnyWorker':
                 getter = lambda x: x.interface.isExposedInAnyWorker()
             elif key == 'isExposedInWorkerDebugger':
                 getter = lambda x: x.interface.isExposedInWorkerDebugger()
             elif key == 'isExposedInAnyWorklet':
                 getter = lambda x: x.interface.isExposedInAnyWorklet()
-            elif key == 'isExposedInSystemGlobals':
-                getter = lambda x: x.interface.isExposedInSystemGlobals()
             elif key == 'isExposedInWindow':
                 getter = lambda x: x.interface.isExposedInWindow()
             else:
                 # Have to watch out: just closing over "key" is not enough,
                 # since we're about to mutate its value
                 getter = (lambda attrName: lambda x: getattr(x, attrName))(key)
             tofilter.append((getter, val))
         for f in tofilter:
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -322,16 +322,23 @@ class IDLScope(IDLObject):
     def _lookupIdentifier(self, identifier):
         return self._dict[identifier.name]
 
     def lookupIdentifier(self, identifier):
         assert isinstance(identifier, IDLIdentifier)
         assert identifier.scope == self
         return self._lookupIdentifier(identifier)
 
+    def addIfaceGlobalNames(self, interfaceName, globalNames):
+        """Record the global names (from |globalNames|) that can be used in
+        [Exposed] to expose things in a global named |interfaceName|"""
+        self.globalNames.update(globalNames)
+        for name in globalNames:
+            self.globalNameMapping[name].add(interfaceName)
+
 
 class IDLIdentifier(IDLObject):
     def __init__(self, location, scope, name):
         IDLObject.__init__(self, location)
 
         self.name = name
         assert isinstance(scope, IDLScope)
         self.scope = scope
@@ -499,31 +506,30 @@ class IDLExposureMixins():
 
         globalNameSetToExposureSet(scope, self._exposureGlobalNames,
                                    self.exposureSet)
 
     def isExposedInWindow(self):
         return 'Window' in self.exposureSet
 
     def isExposedOnMainThread(self):
-        return (self.isExposedInWindow() or
-                self.isExposedInSystemGlobals())
+        return self.isExposedInWindow()
+
+    def isExposedOffMainThread(self):
+        return len(self.exposureSet - {'Window', 'FakeTestPrimaryGlobal'}) > 0
 
     def isExposedInAnyWorker(self):
         return len(self.getWorkerExposureSet()) > 0
 
     def isExposedInWorkerDebugger(self):
         return len(self.getWorkerDebuggerExposureSet()) > 0
 
     def isExposedInAnyWorklet(self):
         return len(self.getWorkletExposureSet()) > 0
 
-    def isExposedInSystemGlobals(self):
-        return 'BackstagePass' in self.exposureSet
-
     def isExposedInSomeButNotAllWorkers(self):
         """
         Returns true if the Exposed extended attribute for this interface
         exposes it in some worker globals but not others.  The return value does
         not depend on whether the interface is exposed in Window or System
         globals.
         """
         if not self.isExposedInAnyWorker():
@@ -1318,20 +1324,19 @@ class IDLInterfaceOrNamespace(IDLObjectW
 
             # Check that the name of a [BindingAlias] doesn't conflict with an
             # interface member.
             if member.isAttr():
                 for bindingAlias in member.bindingAliases:
                     checkDuplicateNames(member, bindingAlias, "BindingAlias")
 
 
-        if (self.getExtendedAttribute("Pref") and
-            self._exposureGlobalNames != set([self.parentScope.primaryGlobalName])):
-            raise WebIDLError("[Pref] used on an interface that is not %s-only" %
-                              self.parentScope.primaryGlobalName,
+        if self.getExtendedAttribute("Pref") and self.isExposedOffMainThread():
+            raise WebIDLError("[Pref] used on an interface that is not "
+                              "main-thread-only",
                               [self.location])
 
         # Conditional exposure makes no sense for interfaces with no
         # interface object, unless they're navigator properties.
         # And SecureContext makes sense for interfaces with no interface object,
         # since it is also propagated to interface members.
         if (self.isExposedConditionally(exclusions=["SecureContext"]) and
             not self.hasInterfaceObject() and
@@ -1705,33 +1710,32 @@ class IDLInterface(IDLInterfaceOrNamespa
                                       [attr.location, self.location])
             elif identifier == "Global":
                 if attr.hasValue():
                     self.globalNames = [attr.value()]
                 elif attr.hasArgs():
                     self.globalNames = attr.args()
                 else:
                     self.globalNames = [self.identifier.name]
-                self.parentScope.globalNames.update(self.globalNames)
-                for globalName in self.globalNames:
-                    self.parentScope.globalNameMapping[globalName].add(self.identifier.name)
+                self.parentScope.addIfaceGlobalNames(self.identifier.name,
+                                                     self.globalNames)
                 self._isOnGlobalProtoChain = True
             elif identifier == "PrimaryGlobal":
                 if not attr.noArguments():
                     raise WebIDLError("[PrimaryGlobal] must take no arguments",
                                       [attr.location])
                 if self.parentScope.primaryGlobalAttr is not None:
                     raise WebIDLError(
                         "[PrimaryGlobal] specified twice",
                         [attr.location,
                          self.parentScope.primaryGlobalAttr.location])
                 self.parentScope.primaryGlobalAttr = attr
                 self.parentScope.primaryGlobalName = self.identifier.name
-                self.parentScope.globalNames.add(self.identifier.name)
-                self.parentScope.globalNameMapping[self.identifier.name].add(self.identifier.name)
+                self.parentScope.addIfaceGlobalNames(self.identifier.name,
+                                                     [self.identifier.name])
                 self._isOnGlobalProtoChain = True
             elif identifier == "SecureContext":
                 if not attr.noArguments():
                     raise WebIDLError("[%s] must take no arguments" % identifier,
                                       [attr.location])
                 # This gets propagated to all our members.
                 for member in self.members:
                     if member.getExtendedAttribute("SecureContext"):
@@ -3567,20 +3571,19 @@ class IDLInterfaceMember(IDLObjectWithId
     def finish(self, scope):
         # We better be exposed _somewhere_.
         if (len(self._exposureGlobalNames) == 0):
             print self.identifier.name
         assert len(self._exposureGlobalNames) != 0
         IDLExposureMixins.finish(self, scope)
 
     def validate(self):
-        if (self.getExtendedAttribute("Pref") and
-            self.exposureSet != set([self._globalScope.primaryGlobalName])):
+        if self.getExtendedAttribute("Pref") and self.isExposedOffMainThread():
             raise WebIDLError("[Pref] used on an interface member that is not "
-                              "%s-only" % self._globalScope.primaryGlobalName,
+                              "main-thread-only",
                               [self.location])
 
         if self.isAttr() or self.isMethod():
             if self.affects == "Everything" and self.dependsOn != "Everything":
                 raise WebIDLError("Interface member is flagged as affecting "
                                   "everything but not depending on everything. "
                                   "That seems rather unlikely.",
                                   [self.location])
@@ -6891,26 +6894,23 @@ class Parser(Tokenizer):
                                     # We're not pickling for now, until it
                                     # becomes a speedup again.
                                     # , picklefile='WebIDLGrammar.pkl'
             )
         finally:
             logger.reportGrammarErrors()
 
         self._globalScope = IDLScope(BuiltinLocation("<Global Scope>"), None, None)
+
         # To make our test harness work, pretend like we have a primary global already.
         # Note that we _don't_ set _globalScope.primaryGlobalAttr,
         # so we'll still be able to detect multiple PrimaryGlobal extended attributes.
         self._globalScope.primaryGlobalName = "FakeTestPrimaryGlobal"
-        self._globalScope.globalNames.add("FakeTestPrimaryGlobal")
-        self._globalScope.globalNameMapping["FakeTestPrimaryGlobal"].add("FakeTestPrimaryGlobal")
-        # And we add the special-cased "System" global name, which
-        # doesn't have any corresponding interfaces.
-        self._globalScope.globalNames.add("System")
-        self._globalScope.globalNameMapping["System"].add("BackstagePass")
+        self._globalScope.addIfaceGlobalNames("FakeTestPrimaryGlobal", ["FakeTestPrimaryGlobal"])
+
         self._installBuiltins(self._globalScope)
         self._productions = []
 
         self._filename = "<builtin>"
         self.lexer.input(Parser._builtins)
         self._filename = None
 
         self.parser.parse(lexer=self.lexer, tracking=True)
--- a/dom/canvas/ImageBitmap.cpp
+++ b/dom/canvas/ImageBitmap.cpp
@@ -13,19 +13,22 @@
 #include "mozilla/dom/StructuredCloneTags.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/dom/WorkerRef.h"
 #include "mozilla/dom/WorkerRunnable.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/Swizzle.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/ScopeExit.h"
+#include "nsNetUtil.h"
+#include "nsStreamUtils.h"
 #include "ImageBitmapColorUtils.h"
 #include "ImageBitmapUtils.h"
 #include "ImageUtils.h"
+#include "imgLoader.h"
 #include "imgTools.h"
 
 using namespace mozilla::gfx;
 using namespace mozilla::layers;
 using mozilla::dom::HTMLMediaElement_Binding::NETWORK_EMPTY;
 using mozilla::dom::HTMLMediaElement_Binding::HAVE_METADATA;
 
 namespace mozilla {
@@ -477,17 +480,17 @@ GetSurfaceFromElement(nsIGlobalObject* a
   if (!CheckSecurityForHTMLElements(res)) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return nullptr;
   }
 
   RefPtr<SourceSurface> surface = res.GetSourceSurface();
 
   if (NS_WARN_IF(!surface)) {
-    aRv.Throw(NS_ERROR_NOT_AVAILABLE);
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return nullptr;
   }
 
   return surface.forget();
 }
 
 /*
  * The specification doesn't allow to create an ImegeBitmap from a vector image.
@@ -517,17 +520,16 @@ HasRasterImage(HTMLImageElement& aImageE
 ImageBitmap::ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData,
                          gfxAlphaType aAlphaType)
   : mParent(aGlobal)
   , mData(aData)
   , mSurface(nullptr)
   , mDataWrapper(new ImageUtils(mData))
   , mPictureRect(0, 0, aData->GetSize().width, aData->GetSize().height)
   , mAlphaType(aAlphaType)
-  , mIsCroppingAreaOutSideOfSourceImage(false)
   , mAllocatedImageData(false)
 {
   MOZ_ASSERT(aData, "aData is null in ImageBitmap constructor.");
 
   mShutdownObserver = new ImageBitmapShutdownObserver(this);
   mShutdownObserver->RegisterObserver();
 }
 
@@ -564,33 +566,16 @@ ImageBitmap::OnShutdown()
 }
 
 void
 ImageBitmap::SetPictureRect(const IntRect& aRect, ErrorResult& aRv)
 {
   mPictureRect = FixUpNegativeDimension(aRect, aRv);
 }
 
-void
-ImageBitmap::SetIsCroppingAreaOutSideOfSourceImage(const IntSize& aSourceSize,
-                                                   const Maybe<IntRect>& aCroppingRect)
-{
-  // No cropping at all.
-  if (aCroppingRect.isNothing()) {
-    mIsCroppingAreaOutSideOfSourceImage = false;
-    return;
-  }
-
-  if (aCroppingRect->X() < 0 || aCroppingRect->Y() < 0 ||
-      aCroppingRect->Width() > aSourceSize.width ||
-      aCroppingRect->Height() > aSourceSize.height) {
-    mIsCroppingAreaOutSideOfSourceImage = true;
-  }
-}
-
 static already_AddRefed<SourceSurface>
 ConvertColorFormatIfNeeded(RefPtr<SourceSurface> aSurface)
 {
   const SurfaceFormat srcFormat = aSurface->GetFormat();
   if (srcFormat == SurfaceFormat::R8G8B8A8 ||
       srcFormat == SurfaceFormat::B8G8R8A8 ||
       srcFormat == SurfaceFormat::R8G8B8X8 ||
       srcFormat == SurfaceFormat::B8G8R8X8 ||
@@ -795,17 +780,16 @@ ImageBitmap::ToCloneData() const
   if (!mData) {
     // A closed image cannot be cloned.
     return nullptr;
   }
 
   UniquePtr<ImageBitmapCloneData> result(new ImageBitmapCloneData());
   result->mPictureRect = mPictureRect;
   result->mAlphaType = mAlphaType;
-  result->mIsCroppingAreaOutSideOfSourceImage = mIsCroppingAreaOutSideOfSourceImage;
   RefPtr<SourceSurface> surface = mData->GetAsSourceSurface();
   result->mSurface = surface->GetDataSurface();
   MOZ_ASSERT(result->mSurface);
 
   return result;
 }
 
 /* static */ already_AddRefed<ImageBitmap>
@@ -824,19 +808,16 @@ ImageBitmap::CreateFromCloneData(nsIGlob
                                  ImageBitmapCloneData* aData)
 {
   RefPtr<layers::Image> data = CreateImageFromSurface(aData->mSurface);
 
   RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, aData->mAlphaType);
 
   ret->mAllocatedImageData = true;
 
-  ret->mIsCroppingAreaOutSideOfSourceImage =
-    aData->mIsCroppingAreaOutSideOfSourceImage;
-
   ErrorResult rv;
   ret->SetPictureRect(aData->mPictureRect, rv);
   return ret.forget();
 }
 
 /* static */ already_AddRefed<ImageBitmap>
 ImageBitmap::CreateFromOffscreenCanvas(nsIGlobalObject* aGlobal,
                                        OffscreenCanvas& aOffscreenCanvas,
@@ -903,19 +884,16 @@ ImageBitmap::CreateInternal(nsIGlobalObj
 
   RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
 
   // Set the picture rectangle.
   if (ret && aCropRect.isSome()) {
     ret->SetPictureRect(aCropRect.ref(), aRv);
   }
 
-  // Set mIsCroppingAreaOutSideOfSourceImage.
-  ret->SetIsCroppingAreaOutSideOfSourceImage(surface->GetSize(), aCropRect);
-
   return ret.forget();
 }
 
 /* static */ already_AddRefed<ImageBitmap>
 ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl,
                             const Maybe<IntRect>& aCropRect, ErrorResult& aRv)
 {
   aVideoEl.MarkAsContentSource(mozilla::dom::HTMLVideoElement::CallerAPI::CREATE_IMAGEBITMAP);
@@ -949,19 +927,16 @@ ImageBitmap::CreateInternal(nsIGlobalObj
   }
   RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
 
   // Set the picture rectangle.
   if (ret && aCropRect.isSome()) {
     ret->SetPictureRect(aCropRect.ref(), aRv);
   }
 
-  // Set mIsCroppingAreaOutSideOfSourceImage.
-  ret->SetIsCroppingAreaOutSideOfSourceImage(data->GetSize(), aCropRect);
-
   return ret.forget();
 }
 
 /* static */ already_AddRefed<ImageBitmap>
 ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLCanvasElement& aCanvasEl,
                             const Maybe<IntRect>& aCropRect, ErrorResult& aRv)
 {
   if (aCanvasEl.Width() == 0 || aCanvasEl.Height() == 0) {
@@ -991,42 +966,39 @@ ImageBitmap::CreateInternal(nsIGlobalObj
     cropRect.MoveTo(0, 0);
     needToReportMemoryAllocation = true;
   }
   else {
     croppedSurface = surface;
   }
 
   if (NS_WARN_IF(!croppedSurface)) {
-    aRv.Throw(NS_ERROR_NOT_AVAILABLE);
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return nullptr;
   }
 
   // Create an Image from the SourceSurface.
   RefPtr<layers::Image> data = CreateImageFromSurface(croppedSurface);
 
   if (NS_WARN_IF(!data)) {
-    aRv.Throw(NS_ERROR_NOT_AVAILABLE);
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return nullptr;
   }
 
   RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
 
   if (needToReportMemoryAllocation) {
     ret->mAllocatedImageData = true;
   }
 
   // Set the picture rectangle.
   if (ret && aCropRect.isSome()) {
     ret->SetPictureRect(cropRect, aRv);
   }
 
-  // Set mIsCroppingAreaOutSideOfSourceImage.
-  ret->SetIsCroppingAreaOutSideOfSourceImage(surface->GetSize(), aCropRect);
-
   return ret.forget();
 }
 
 /* static */ already_AddRefed<ImageBitmap>
 ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, ImageData& aImageData,
                             const Maybe<IntRect>& aCropRect, ErrorResult& aRv)
 {
   // Copy data into SourceSurface.
@@ -1066,31 +1038,28 @@ ImageBitmap::CreateInternal(nsIGlobalObj
                                                        FORMAT,
                                                        imageSize,
                                                        aCropRect,
                                                        getter_AddRefs(data));
     task->Dispatch(Canceling, aRv);
   }
 
   if (NS_WARN_IF(!data)) {
-    aRv.Throw(NS_ERROR_NOT_AVAILABLE);
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return nullptr;
   }
 
   // Create an ImageBimtap.
   RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, alphaType);
 
   ret->mAllocatedImageData = true;
 
   // The cropping information has been handled in the CreateImageFromRawData()
   // function.
 
-  // Set mIsCroppingAreaOutSideOfSourceImage.
-  ret->SetIsCroppingAreaOutSideOfSourceImage(imageSize, aCropRect);
-
   return ret.forget();
 }
 
 /* static */ already_AddRefed<ImageBitmap>
 ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, CanvasRenderingContext2D& aCanvasCtx,
                             const Maybe<IntRect>& aCropRect, ErrorResult& aRv)
 {
   // Check origin-clean.
@@ -1123,47 +1092,36 @@ ImageBitmap::CreateInternal(nsIGlobalObj
 
   ret->mAllocatedImageData = true;
 
   // Set the picture rectangle.
   if (ret && aCropRect.isSome()) {
     ret->SetPictureRect(aCropRect.ref(), aRv);
   }
 
-  // Set mIsCroppingAreaOutSideOfSourceImage.
-  ret->SetIsCroppingAreaOutSideOfSourceImage(surface->GetSize(), aCropRect);
-
   return ret.forget();
 }
 
 /* static */ already_AddRefed<ImageBitmap>
 ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, ImageBitmap& aImageBitmap,
                             const Maybe<IntRect>& aCropRect, ErrorResult& aRv)
 {
   if (!aImageBitmap.mData) {
-    aRv.Throw(NS_ERROR_NOT_AVAILABLE);
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return nullptr;
   }
 
   RefPtr<layers::Image> data = aImageBitmap.mData;
   RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, aImageBitmap.mAlphaType);
 
   // Set the picture rectangle.
   if (ret && aCropRect.isSome()) {
     ret->SetPictureRect(aCropRect.ref(), aRv);
   }
 
-  // Set mIsCroppingAreaOutSideOfSourceImage.
-  if (aImageBitmap.mIsCroppingAreaOutSideOfSourceImage == true) {
-    ret->mIsCroppingAreaOutSideOfSourceImage = true;
-  } else {
-    ret->SetIsCroppingAreaOutSideOfSourceImage(aImageBitmap.mPictureRect.Size(),
-                                               aCropRect);
-  }
-
   return ret.forget();
 }
 
 class FulfillImageBitmapPromise
 {
 protected:
   FulfillImageBitmapPromise(Promise* aPromise, ImageBitmap* aImageBitmap)
   : mPromise(aPromise)
@@ -1229,58 +1187,58 @@ AsyncFulfillImageBitmapPromise(Promise* 
     task->Dispatch(); // Actually, to the current worker-thread.
   }
 }
 
 class CreateImageBitmapFromBlobRunnable;
 
 class CreateImageBitmapFromBlob final : public CancelableRunnable
                                       , public imgIContainerCallback
+                                      , public nsIInputStreamCallback
 {
   friend class CreateImageBitmapFromBlobRunnable;
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_IMGICONTAINERCALLBACK
+  NS_DECL_NSIINPUTSTREAMCALLBACK
 
   static already_AddRefed<CreateImageBitmapFromBlob>
   Create(Promise* aPromise,
          nsIGlobalObject* aGlobal,
          Blob& aBlob,
          const Maybe<IntRect>& aCropRect,
          nsIEventTarget* aMainThreadEventTarget);
 
   NS_IMETHOD Run() override
   {
     MOZ_ASSERT(IsCurrentThread());
 
-    nsresult rv = StartDecodeAndCropBlob();
+    nsresult rv = StartMimeTypeAndDecodeAndCropBlob();
     if (NS_WARN_IF(NS_FAILED(rv))) {
-      DecodeAndCropBlobCompletedMainThread(nullptr, rv);
+      MimeTypeAndDecodeAndCropBlobCompletedMainThread(nullptr, rv);
     }
 
     return NS_OK;
   }
 
   // Called by the WorkerRef.
   void WorkerShuttingDown();
 
 private:
   CreateImageBitmapFromBlob(Promise* aPromise,
                             nsIGlobalObject* aGlobal,
                             already_AddRefed<nsIInputStream> aInputStream,
-                            const nsACString& aMimeType,
                             const Maybe<IntRect>& aCropRect,
                             nsIEventTarget* aMainThreadEventTarget)
     : CancelableRunnable("dom::CreateImageBitmapFromBlob")
     , mMutex("dom::CreateImageBitmapFromBlob::mMutex")
     , mPromise(aPromise)
     , mGlobalObject(aGlobal)
     , mInputStream(std::move(aInputStream))
-    , mMimeType(aMimeType)
     , mCropRect(aCropRect)
     , mOriginalCropRect(aCropRect)
     , mMainThreadEventTarget(aMainThreadEventTarget)
     , mThread(GetCurrentVirtualThread())
   {
   }
 
   virtual ~CreateImageBitmapFromBlob()
@@ -1288,55 +1246,63 @@ private:
   }
 
   bool IsCurrentThread() const
   {
     return mThread == GetCurrentVirtualThread();
   }
 
   // Called on the owning thread.
-  nsresult StartDecodeAndCropBlob();
+  nsresult StartMimeTypeAndDecodeAndCropBlob();
 
   // Will be called when the decoding + cropping is completed on the
   // main-thread. This could the not the owning thread!
-  void DecodeAndCropBlobCompletedMainThread(layers::Image* aImage,
-                                            nsresult aStatus);
+  void MimeTypeAndDecodeAndCropBlobCompletedMainThread(layers::Image* aImage,
+                                                       nsresult aStatus);
 
   // Will be called when the decoding + cropping is completed on the owning
   // thread.
-  void DecodeAndCropBlobCompletedOwningThread(layers::Image* aImage,
-                                              nsresult aStatus);
+  void MimeTypeAndDecodeAndCropBlobCompletedOwningThread(layers::Image* aImage,
+                                                         nsresult aStatus);
+
+  // This is called on the main-thread only.
+  nsresult MimeTypeAndDecodeAndCropBlob();
 
   // This is called on the main-thread only.
-  nsresult DecodeAndCropBlob();
+  nsresult DecodeAndCropBlob(const nsACString& aMimeType);
+
+  // This is called on the main-thread only.
+  nsresult GetMimeTypeSync(nsACString& aMimeType);
+
+  // This is called on the main-thread only.
+  nsresult GetMimeTypeAsync();
 
   Mutex mMutex;
 
   // The access to this object is protected by mutex but is always nullified on
   // the owning thread.
   RefPtr<ThreadSafeWorkerRef> mWorkerRef;
 
   // Touched only on the owning thread.
   RefPtr<Promise> mPromise;
 
   // Touched only on the owning thread.
   nsCOMPtr<nsIGlobalObject> mGlobalObject;
 
   nsCOMPtr<nsIInputStream> mInputStream;
-  nsCString mMimeType;
   Maybe<IntRect> mCropRect;
   Maybe<IntRect> mOriginalCropRect;
   IntSize mSourceSize;
 
   nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
   void* mThread;
 };
 
 NS_IMPL_ISUPPORTS_INHERITED(CreateImageBitmapFromBlob, CancelableRunnable,
-                            imgIContainerCallback)
+                            imgIContainerCallback, nsIInputStreamCallback)
 
 class CreateImageBitmapFromBlobRunnable : public WorkerRunnable
 {
 public:
   explicit CreateImageBitmapFromBlobRunnable(WorkerPrivate* aWorkerPrivate,
                                              CreateImageBitmapFromBlob* aTask,
                                              layers::Image* aImage,
                                              nsresult aStatus)
@@ -1344,17 +1310,17 @@ public:
     , mTask(aTask)
     , mImage(aImage)
     , mStatus(aStatus)
   {}
 
   bool
   WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
   {
-    mTask->DecodeAndCropBlobCompletedOwningThread(mImage, mStatus);
+    mTask->MimeTypeAndDecodeAndCropBlobCompletedOwningThread(mImage, mStatus);
     return true;
   }
 
 private:
   RefPtr<CreateImageBitmapFromBlob> mTask;
   RefPtr<layers::Image> mImage;
   nsresult mStatus;
 };
@@ -1422,17 +1388,17 @@ ImageBitmap::Create(nsIGlobalObject* aGl
                "Creating ImageBitmap from CanvasRenderingContext2D off the main thread.");
     imageBitmap = CreateInternal(aGlobal, aSrc.GetAsCanvasRenderingContext2D(), aCropRect, aRv);
   } else if (aSrc.IsImageBitmap()) {
     imageBitmap = CreateInternal(aGlobal, aSrc.GetAsImageBitmap(), aCropRect, aRv);
   } else if (aSrc.IsBlob()) {
     AsyncCreateImageBitmapFromBlob(promise, aGlobal, aSrc.GetAsBlob(), aCropRect);
     return promise.forget();
   } else {
-    aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+    MOZ_CRASH("Unsupported type!");
     return nullptr;
   }
 
   if (!aRv.Failed()) {
     AsyncFulfillImageBitmapPromise(promise, imageBitmap);
   }
 
   return promise.forget();
@@ -1449,25 +1415,26 @@ ImageBitmap::ReadStructuredClone(JSConte
   MOZ_ASSERT(aReader);
   // aParent might be null.
 
   uint32_t picRectX_;
   uint32_t picRectY_;
   uint32_t picRectWidth_;
   uint32_t picRectHeight_;
   uint32_t alphaType_;
-  uint32_t isCroppingAreaOutSideOfSourceImage_;
+  uint32_t dummy;
 
   if (!JS_ReadUint32Pair(aReader, &picRectX_, &picRectY_) ||
       !JS_ReadUint32Pair(aReader, &picRectWidth_, &picRectHeight_) ||
-      !JS_ReadUint32Pair(aReader, &alphaType_,
-                                  &isCroppingAreaOutSideOfSourceImage_)) {
+      !JS_ReadUint32Pair(aReader, &alphaType_, &dummy)) {
     return nullptr;
   }
 
+  MOZ_ASSERT(dummy == 0);
+
   int32_t picRectX = BitwiseCast<int32_t>(picRectX_);
   int32_t picRectY = BitwiseCast<int32_t>(picRectY_);
   int32_t picRectWidth = BitwiseCast<int32_t>(picRectWidth_);
   int32_t picRectHeight = BitwiseCast<int32_t>(picRectHeight_);
   const auto alphaType = BitwiseCast<gfxAlphaType>(alphaType_);
 
   // Create a new ImageBitmap.
   MOZ_ASSERT(!aClonedSurfaces.IsEmpty());
@@ -1483,19 +1450,16 @@ ImageBitmap::ReadStructuredClone(JSConte
 #ifdef FUZZING
     if (aIndex >= aClonedSurfaces.Length()) {
       return nullptr;
     }
 #endif
     RefPtr<layers::Image> img = CreateImageFromSurface(aClonedSurfaces[aIndex]);
     RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(aParent, img, alphaType);
 
-    imageBitmap->mIsCroppingAreaOutSideOfSourceImage =
-      isCroppingAreaOutSideOfSourceImage_;
-
     ErrorResult error;
     imageBitmap->SetPictureRect(IntRect(picRectX, picRectY,
                                         picRectWidth, picRectHeight), error);
     if (NS_WARN_IF(error.Failed())) {
       error.SuppressException();
       return nullptr;
     }
 
@@ -1517,26 +1481,24 @@ ImageBitmap::WriteStructuredClone(JSStru
   MOZ_ASSERT(aWriter);
   MOZ_ASSERT(aImageBitmap);
 
   const uint32_t picRectX = BitwiseCast<uint32_t>(aImageBitmap->mPictureRect.x);
   const uint32_t picRectY = BitwiseCast<uint32_t>(aImageBitmap->mPictureRect.y);
   const uint32_t picRectWidth = BitwiseCast<uint32_t>(aImageBitmap->mPictureRect.width);
   const uint32_t picRectHeight = BitwiseCast<uint32_t>(aImageBitmap->mPictureRect.height);
   const uint32_t alphaType = BitwiseCast<uint32_t>(aImageBitmap->mAlphaType);
-  const uint32_t isCroppingAreaOutSideOfSourceImage = aImageBitmap->mIsCroppingAreaOutSideOfSourceImage ? 1 : 0;
 
   // Indexing the cloned surfaces and send the index to the receiver.
   uint32_t index = aClonedSurfaces.Length();
 
   if (NS_WARN_IF(!JS_WriteUint32Pair(aWriter, SCTAG_DOM_IMAGEBITMAP, index)) ||
       NS_WARN_IF(!JS_WriteUint32Pair(aWriter, picRectX, picRectY)) ||
       NS_WARN_IF(!JS_WriteUint32Pair(aWriter, picRectWidth, picRectHeight)) ||
-      NS_WARN_IF(!JS_WriteUint32Pair(aWriter, alphaType,
-                                              isCroppingAreaOutSideOfSourceImage))) {
+      NS_WARN_IF(!JS_WriteUint32Pair(aWriter, alphaType, 0))) {
     return false;
   }
 
   RefPtr<SourceSurface> surface =
     aImageBitmap->mData->GetAsSourceSurface();
   RefPtr<DataSourceSurface> snapshot = surface->GetDataSurface();
   RefPtr<DataSourceSurface> dstDataSurface;
   {
@@ -1553,583 +1515,16 @@ ImageBitmap::WriteStructuredClone(JSStru
   if (NS_WARN_IF(!dstDataSurface)) {
     return false;
   }
   Factory::CopyDataSourceSurface(snapshot, dstDataSurface);
   aClonedSurfaces.AppendElement(dstDataSurface);
   return true;
 }
 
-// ImageBitmap extensions.
-ImageBitmapFormat
-ImageBitmap::FindOptimalFormat(const Optional<Sequence<ImageBitmapFormat>>& aPossibleFormats,
-                               ErrorResult& aRv)
-{
-  if (!mDataWrapper) {
-    aRv.Throw(NS_ERROR_NOT_AVAILABLE);
-    return ImageBitmapFormat::EndGuard_;
-  }
-
-  ImageBitmapFormat platformFormat = mDataWrapper->GetFormat();
-
-  if (!aPossibleFormats.WasPassed() ||
-      aPossibleFormats.Value().Contains(platformFormat)) {
-    return platformFormat;
-  } else {
-    // If no matching is found, FindBestMatchingFromat() returns
-    // ImageBitmapFormat::EndGuard_ and we throw an exception.
-    ImageBitmapFormat optimalFormat =
-      FindBestMatchingFromat(platformFormat, aPossibleFormats.Value());
-
-    if (optimalFormat == ImageBitmapFormat::EndGuard_) {
-      aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
-    }
-
-    return optimalFormat;
-  }
-}
-
-int32_t
-ImageBitmap::MappedDataLength(ImageBitmapFormat aFormat, ErrorResult& aRv)
-{
-  if (!mDataWrapper) {
-    aRv.Throw(NS_ERROR_NOT_AVAILABLE);
-    return 0;
-  }
-
-  if (aFormat == mDataWrapper->GetFormat()) {
-    return mDataWrapper->GetBufferLength();
-  } else {
-    return CalculateImageBufferSize(aFormat, Width(), Height());
-  }
-}
-
-template<typename T>
-class MapDataIntoBufferSource
-{
-protected:
-  MapDataIntoBufferSource(JSContext* aCx,
-                          Promise *aPromise,
-                          ImageBitmap *aImageBitmap,
-                          const T& aBuffer,
-                          int32_t aOffset,
-                          ImageBitmapFormat aFormat)
-  : mPromise(aPromise)
-  , mImageBitmap(aImageBitmap)
-  , mBuffer(aCx, aBuffer.Obj())
-  , mOffset(aOffset)
-  , mFormat(aFormat)
-  {
-    MOZ_ASSERT(mPromise);
-    MOZ_ASSERT(JS_IsArrayBufferObject(mBuffer) ||
-               JS_IsArrayBufferViewObject(mBuffer));
-  }
-
-  virtual ~MapDataIntoBufferSource() = default;
-
-  void DoMapDataIntoBufferSource()
-  {
-    ErrorResult error;
-
-    auto rejectByDefault =
-      MakeScopeExit([this, &error]() {
-        this->mPromise->MaybeReject(error);
-      });
-
-    if (!mImageBitmap->mDataWrapper) {
-      error.Throw(NS_ERROR_NOT_AVAILABLE);
-      return;
-    }
-
-    // Prepare destination buffer.
-    uint8_t* bufferData = nullptr;
-    uint32_t bufferLength = 0;
-    bool isSharedMemory = false;
-    if (JS_IsArrayBufferObject(mBuffer)) {
-      js::GetArrayBufferLengthAndData(mBuffer, &bufferLength, &isSharedMemory, &bufferData);
-    } else if (JS_IsArrayBufferViewObject(mBuffer)) {
-      js::GetArrayBufferViewLengthAndData(mBuffer, &bufferLength, &isSharedMemory, &bufferData);
-    } else {
-      error.Throw(NS_ERROR_NOT_IMPLEMENTED);
-      return;
-    }
-
-    if (NS_WARN_IF(!bufferData) || NS_WARN_IF(!bufferLength)) {
-      error.Throw(NS_ERROR_NOT_AVAILABLE);
-      return;
-    }
-
-    // Check length.
-    const int32_t neededBufferLength =
-      mImageBitmap->MappedDataLength(mFormat, error);
-
-    if (((int32_t)bufferLength - mOffset) < neededBufferLength) {
-      error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
-      return;
-    }
-
-    // Call ImageBitmapFormatUtils.
-    UniquePtr<ImagePixelLayout> layout =
-      mImageBitmap->mDataWrapper->MapDataInto(bufferData,
-                                              mOffset,
-                                              bufferLength,
-                                              mFormat,
-                                              error);
-
-    if (NS_WARN_IF(!layout)) {
-      return;
-    }
-
-    rejectByDefault.release();
-    mPromise->MaybeResolve(*layout);
-  }
-
-  RefPtr<Promise> mPromise;
-  RefPtr<ImageBitmap> mImageBitmap;
-  JS::PersistentRooted<JSObject*> mBuffer;
-  int32_t mOffset;
-  ImageBitmapFormat mFormat;
-};
-
-template<typename T>
-class MapDataIntoBufferSourceTask final : public Runnable,
-                                          public MapDataIntoBufferSource<T>
-{
-public:
-  MapDataIntoBufferSourceTask(JSContext* aCx,
-                              Promise* aPromise,
-                              ImageBitmap* aImageBitmap,
-                              const T& aBuffer,
-                              int32_t aOffset,
-                              ImageBitmapFormat aFormat)
-    : Runnable("dom::MapDataIntoBufferSourceTask")
-    , MapDataIntoBufferSource<T>(aCx,
-                                 aPromise,
-                                 aImageBitmap,
-                                 aBuffer,
-                                 aOffset,
-                                 aFormat)
-  {
-  }
-
-  virtual ~MapDataIntoBufferSourceTask() = default;
-
-  NS_IMETHOD Run() override
-  {
-    MapDataIntoBufferSource<T>::DoMapDataIntoBufferSource();
-    return NS_OK;
-  }
-};
-
-template<typename T>
-class MapDataIntoBufferSourceWorkerTask final : public WorkerSameThreadRunnable,
-                                                public MapDataIntoBufferSource<T>
-{
-public:
-  MapDataIntoBufferSourceWorkerTask(JSContext* aCx,
-                                    Promise *aPromise,
-                                    ImageBitmap *aImageBitmap,
-                                    const T& aBuffer,
-                                    int32_t aOffset,
-                                    ImageBitmapFormat aFormat)
-  : WorkerSameThreadRunnable(GetCurrentThreadWorkerPrivate()),
-    MapDataIntoBufferSource<T>(aCx, aPromise, aImageBitmap, aBuffer, aOffset, aFormat)
-  {
-  }
-
-  virtual ~MapDataIntoBufferSourceWorkerTask() = default;
-
-  bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
-  {
-    MapDataIntoBufferSource<T>::DoMapDataIntoBufferSource();
-    return true;
-  }
-};
-
-void AsyncMapDataIntoBufferSource(JSContext* aCx,
-                                  Promise *aPromise,
-                                  ImageBitmap *aImageBitmap,
-                                  const ArrayBufferViewOrArrayBuffer& aBuffer,
-                                  int32_t aOffset,
-                                  ImageBitmapFormat aFormat)
-{
-  MOZ_ASSERT(aCx);
-  MOZ_ASSERT(aPromise);
-  MOZ_ASSERT(aImageBitmap);
-
-  if (NS_IsMainThread()) {
-    nsCOMPtr<nsIRunnable> task;
-
-    if (aBuffer.IsArrayBuffer()) {
-      const ArrayBuffer& buffer = aBuffer.GetAsArrayBuffer();
-      task = new MapDataIntoBufferSourceTask<ArrayBuffer>(aCx, aPromise, aImageBitmap, buffer, aOffset, aFormat);
-    } else if (aBuffer.IsArrayBufferView()) {
-      const ArrayBufferView& bufferView = aBuffer.GetAsArrayBufferView();
-      task = new MapDataIntoBufferSourceTask<ArrayBufferView>(aCx, aPromise, aImageBitmap, bufferView, aOffset, aFormat);
-    }
-
-    NS_DispatchToCurrentThread(task); // Actually, to the main-thread.
-  } else {
-    RefPtr<WorkerSameThreadRunnable> task;
-
-    if (aBuffer.IsArrayBuffer()) {
-      const ArrayBuffer& buffer = aBuffer.GetAsArrayBuffer();
-      task = new MapDataIntoBufferSourceWorkerTask<ArrayBuffer>(aCx, aPromise, aImageBitmap, buffer, aOffset, aFormat);
-    } else if (aBuffer.IsArrayBufferView()) {
-      const ArrayBufferView& bufferView = aBuffer.GetAsArrayBufferView();
-      task = new MapDataIntoBufferSourceWorkerTask<ArrayBufferView>(aCx, aPromise, aImageBitmap, bufferView, aOffset, aFormat);
-    }
-
-    task->Dispatch(); // Actually, to the current worker-thread.
-  }
-}
-
-already_AddRefed<Promise>
-ImageBitmap::MapDataInto(JSContext* aCx,
-                         ImageBitmapFormat aFormat,
-                         const ArrayBufferViewOrArrayBuffer& aBuffer,
-                         int32_t aOffset, ErrorResult& aRv)
-{
-  MOZ_ASSERT(aCx, "No JSContext while calling ImageBitmap::MapDataInto().");
-
-  RefPtr<Promise> promise = Promise::Create(mParent, aRv);
-
-  if (NS_WARN_IF(aRv.Failed())) {
-    return nullptr;
-  }
-
-  if (!mDataWrapper) {
-    aRv.Throw(NS_ERROR_NOT_AVAILABLE);
-    return promise.forget();
-
-  }
-
-  // Check for cases that should throws.
-  // Case 1:
-  // If image bitmap was cropped to the source rectangle so that it contains any
-  // transparent black pixels (cropping area is outside of the source image),
-  // then reject promise with IndexSizeError and abort these steps.
-  if (mIsCroppingAreaOutSideOfSourceImage) {
-    aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
-    return promise.forget();
-  }
-
-  // Case 2:
-  // If the image bitmap is going to be accessed in YUV422/YUV422 series with a
-  // cropping area starts at an odd x or y coordinate.
-  if (aFormat == ImageBitmapFormat::YUV422P ||
-      aFormat == ImageBitmapFormat::YUV420P ||
-      aFormat == ImageBitmapFormat::YUV420SP_NV12 ||
-      aFormat == ImageBitmapFormat::YUV420SP_NV21) {
-    if ((mPictureRect.x & 1) || (mPictureRect.y & 1)) {
-      aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
-      return promise.forget();
-    }
-  }
-
-  AsyncMapDataIntoBufferSource(aCx, promise, this, aBuffer, aOffset, aFormat);
-  return promise.forget();
-}
-
-// ImageBitmapFactories extensions.
-static SurfaceFormat
-ImageFormatToSurfaceFromat(mozilla::dom::ImageBitmapFormat aFormat)
-{
-  switch(aFormat) {
-  case ImageBitmapFormat::RGBA32:
-    return SurfaceFormat::R8G8B8A8;
-  case ImageBitmapFormat::BGRA32:
-    return SurfaceFormat::B8G8R8A8;
-  case ImageBitmapFormat::RGB24:
-    return SurfaceFormat::R8G8B8;
-  case ImageBitmapFormat::BGR24:
-    return SurfaceFormat::B8G8R8;
-  case ImageBitmapFormat::GRAY8:
-    return SurfaceFormat::A8;
-  case ImageBitmapFormat::HSV:
-    return SurfaceFormat::HSV;
-  case ImageBitmapFormat::Lab:
-    return SurfaceFormat::Lab;
-  case ImageBitmapFormat::DEPTH:
-    return SurfaceFormat::Depth;
-  default:
-    return SurfaceFormat::UNKNOWN;
-  }
-}
-
-static already_AddRefed<layers::Image>
-CreateImageFromBufferSourceRawData(const uint8_t*aBufferData,
-                                   uint32_t aBufferLength,
-                                   mozilla::dom::ImageBitmapFormat aFormat,
-                                   const Sequence<ChannelPixelLayout>& aLayout)
-{
-  MOZ_ASSERT(aBufferData);
-  MOZ_ASSERT(aBufferLength > 0);
-
-  switch(aFormat) {
-  case ImageBitmapFormat::RGBA32:
-  case ImageBitmapFormat::BGRA32:
-  case ImageBitmapFormat::RGB24:
-  case ImageBitmapFormat::BGR24:
-  case ImageBitmapFormat::GRAY8:
-  case ImageBitmapFormat::HSV:
-  case ImageBitmapFormat::Lab:
-  case ImageBitmapFormat::DEPTH:
-  {
-    const nsTArray<ChannelPixelLayout>& channels = aLayout;
-    MOZ_ASSERT(channels.Length() != 0, "Empty Channels.");
-
-    const SurfaceFormat srcFormat = ImageFormatToSurfaceFromat(aFormat);
-    const uint32_t srcStride = channels[0].mStride;
-    const IntSize srcSize(channels[0].mWidth, channels[0].mHeight);
-
-    RefPtr<DataSourceSurface> dstDataSurface =
-      Factory::CreateDataSourceSurfaceWithStride(srcSize, srcFormat, srcStride);
-
-    if (NS_WARN_IF(!dstDataSurface)) {
-      return nullptr;
-    }
-
-    // Copy the raw data into the newly created DataSourceSurface.
-    DataSourceSurface::ScopedMap dstMap(dstDataSurface, DataSourceSurface::WRITE);
-    if (NS_WARN_IF(!dstMap.IsMapped())) {
-      return nullptr;
-    }
-
-    const uint8_t* srcBufferPtr = aBufferData;
-    uint8_t* dstBufferPtr = dstMap.GetData();
-
-    for (int i = 0; i < srcSize.height; ++i) {
-      memcpy(dstBufferPtr, srcBufferPtr, srcStride);
-      srcBufferPtr += srcStride;
-      dstBufferPtr += dstMap.GetStride();
-    }
-
-    // Create an Image from the BGRA SourceSurface.
-    RefPtr<SourceSurface> surface = dstDataSurface;
-    RefPtr<layers::Image> image = CreateImageFromSurface(surface);
-
-    if (NS_WARN_IF(!image)) {
-      return nullptr;
-    }
-
-    return image.forget();
-  }
-  case ImageBitmapFormat::YUV444P:
-  case ImageBitmapFormat::YUV422P:
-  case ImageBitmapFormat::YUV420P:
-  case ImageBitmapFormat::YUV420SP_NV12:
-  case ImageBitmapFormat::YUV420SP_NV21:
-  {
-    // Prepare the PlanarYCbCrData.
-    const ChannelPixelLayout& yLayout = aLayout[0];
-    const ChannelPixelLayout& uLayout = aFormat != ImageBitmapFormat::YUV420SP_NV21 ? aLayout[1] : aLayout[2];
-    const ChannelPixelLayout& vLayout = aFormat != ImageBitmapFormat::YUV420SP_NV21 ? aLayout[2] : aLayout[1];
-
-    layers::PlanarYCbCrData data;
-
-    // Luminance buffer
-    data.mYChannel = const_cast<uint8_t*>(aBufferData + yLayout.mOffset);
-    data.mYStride = yLayout.mStride;
-    data.mYSize = gfx::IntSize(yLayout.mWidth, yLayout.mHeight);
-    data.mYSkip = yLayout.mSkip;
-
-    // Chroma buffers
-    data.mCbChannel = const_cast<uint8_t*>(aBufferData + uLayout.mOffset);
-    data.mCrChannel = const_cast<uint8_t*>(aBufferData + vLayout.mOffset);
-    data.mCbCrStride = uLayout.mStride;
-    data.mCbCrSize = gfx::IntSize(uLayout.mWidth, uLayout.mHeight);
-    data.mCbSkip = uLayout.mSkip;
-    data.mCrSkip = vLayout.mSkip;
-
-    // Picture rectangle.
-    // We set the picture rectangle to exactly the size of the source image to
-    // keep the full original data.
-    data.mPicX = 0;
-    data.mPicY = 0;
-    data.mPicSize = data.mYSize;
-
-    // Create a layers::Image and set data.
-    if (aFormat == ImageBitmapFormat::YUV444P ||
-        aFormat == ImageBitmapFormat::YUV422P ||
-        aFormat == ImageBitmapFormat::YUV420P) {
-      RefPtr<layers::PlanarYCbCrImage> image =
-        new layers::RecyclingPlanarYCbCrImage(new layers::BufferRecycleBin());
-
-      if (NS_WARN_IF(!image)) {
-        return nullptr;
-      }
-
-      // Set Data.
-      if (NS_WARN_IF(!image->CopyData(data))) {
-        return nullptr;
-      }
-
-      return image.forget();
-    } else {
-      RefPtr<layers::NVImage>image = new layers::NVImage();
-
-      if (NS_WARN_IF(!image)) {
-        return nullptr;
-      }
-
-      // Set Data.
-      if (NS_WARN_IF(!image->SetData(data))) {
-        return nullptr;
-      }
-
-      return image.forget();
-    }
-  }
-  default:
-    return nullptr;
-  }
-}
-
-/*
- * This is a synchronous task.
- * This class is used to create a layers::CairoImage from raw data in the main
- * thread. While creating an ImageBitmap from an BufferSource, we need to create
- * a SouceSurface from the BufferSource raw data and then set the SourceSurface
- * into a layers::CairoImage. However, the layers::CairoImage asserts the
- * setting operation in the main thread, so if we are going to create an
- * ImageBitmap from an BufferSource off the main thread, we post an event to the
- * main thread to create a layers::CairoImage from an BufferSource raw data.
- *
- * TODO: Once the layers::CairoImage is constructible off the main thread, which
- *       means the SouceSurface could be released anywhere, we do not need this
- *       task anymore.
- */
-class CreateImageFromBufferSourceRawDataInMainThreadSyncTask final :
-  public WorkerMainThreadRunnable
-{
-public:
-  CreateImageFromBufferSourceRawDataInMainThreadSyncTask(const uint8_t* aBuffer,
-                                                         uint32_t aBufferLength,
-                                                         mozilla::dom::ImageBitmapFormat aFormat,
-                                                         const Sequence<ChannelPixelLayout>& aLayout,
-                                                         /*output*/ layers::Image** aImage)
-  : WorkerMainThreadRunnable(GetCurrentThreadWorkerPrivate(),
-                             NS_LITERAL_CSTRING("ImageBitmap-extensions :: Create Image from BufferSource Raw Data"))
-  , mImage(aImage)
-  , mBuffer(aBuffer)
-  , mBufferLength(aBufferLength)
-  , mFormat(aFormat)
-  , mLayout(aLayout)
-  {
-    MOZ_ASSERT(!(*aImage), "Don't pass an existing Image into CreateImageFromBufferSourceRawDataInMainThreadSyncTask.");
-  }
-
-  bool MainThreadRun() override
-  {
-    RefPtr<layers::Image> image =
-      CreateImageFromBufferSourceRawData(mBuffer, mBufferLength, mFormat, mLayout);
-
-    if (NS_WARN_IF(!image)) {
-      return true;
-    }
-
-    image.forget(mImage);
-
-    return true;
-  }
-
-private:
-  layers::Image** mImage;
-  const uint8_t* mBuffer;
-  uint32_t mBufferLength;
-  mozilla::dom::ImageBitmapFormat mFormat;
-  const Sequence<ChannelPixelLayout>& mLayout;
-};
-
-/*static*/ already_AddRefed<Promise>
-ImageBitmap::Create(nsIGlobalObject* aGlobal,
-                    const ImageBitmapSource& aBuffer,
-                    int32_t aOffset, int32_t aLength,
-                    mozilla::dom::ImageBitmapFormat aFormat,
-                    const Sequence<ChannelPixelLayout>& aLayout,
-                    ErrorResult& aRv)
-{
-  MOZ_ASSERT(aGlobal);
-
-  RefPtr<Promise> promise = Promise::Create(aGlobal, aRv);
-
-  if (NS_WARN_IF(aRv.Failed())) {
-    return nullptr;
-  }
-
-  uint8_t* bufferData = nullptr;
-  uint32_t bufferLength = 0;
-
-  if (aBuffer.IsArrayBuffer()) {
-    const ArrayBuffer& buffer = aBuffer.GetAsArrayBuffer();
-    buffer.ComputeLengthAndData();
-    bufferData = buffer.Data();
-    bufferLength = buffer.Length();
-  } else if (aBuffer.IsArrayBufferView()) {
-    const ArrayBufferView& bufferView = aBuffer.GetAsArrayBufferView();
-    bufferView.ComputeLengthAndData();
-    bufferData = bufferView.Data();
-    bufferLength = bufferView.Length();
-  } else {
-    aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
-    return promise.forget();
-  }
-
-  MOZ_ASSERT(bufferData && bufferLength > 0, "Cannot read data from BufferSource.");
-
-  // Check the buffer.
-  if (((uint32_t)(aOffset + aLength) > bufferLength)) {
-    aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
-    return promise.forget();
-  }
-
-  // Create and Crop the raw data into a layers::Image
-  RefPtr<layers::Image> data;
-  if (NS_IsMainThread()) {
-    data = CreateImageFromBufferSourceRawData(bufferData + aOffset, bufferLength,
-                                              aFormat, aLayout);
-  } else {
-    RefPtr<CreateImageFromBufferSourceRawDataInMainThreadSyncTask> task =
-      new CreateImageFromBufferSourceRawDataInMainThreadSyncTask(bufferData + aOffset,
-                                                                 bufferLength,
-                                                                 aFormat,
-                                                                 aLayout,
-                                                                 getter_AddRefs(data));
-    task->Dispatch(Canceling, aRv);
-    if (aRv.Failed()) {
-      return promise.forget();
-    }
-  }
-
-  if (NS_WARN_IF(!data)) {
-    aRv.Throw(NS_ERROR_NOT_AVAILABLE);
-    return promise.forget();
-  }
-
-  // Create an ImageBimtap.
-  // Assume the data from an external buffer is not alpha-premultiplied.
-  RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(aGlobal, data,
-                                                    gfxAlphaType::NonPremult);
-
-  imageBitmap->mAllocatedImageData = true;
-
-  // We don't need to call SetPictureRect() here because there is no cropping
-  // supported and the ImageBitmap's mPictureRect is the size of the source
-  // image in default
-
-  // We don't need to set mIsCroppingAreaOutSideOfSourceImage here because there
-  // is no cropping supported and the mIsCroppingAreaOutSideOfSourceImage is
-  // false in default.
-
-  AsyncFulfillImageBitmapPromise(promise, imageBitmap);
-
-  return promise.forget();
-}
-
 size_t
 ImageBitmap::GetAllocatedSize() const
 {
   if (!mAllocatedImageData) {
     return 0;
   }
 
   // Calculate how many bytes are used.
@@ -2162,24 +1557,29 @@ CreateImageBitmapFromBlob::Create(Promis
   // Get the internal stream of the blob.
   nsCOMPtr<nsIInputStream> stream;
   ErrorResult error;
   aBlob.Impl()->CreateInputStream(getter_AddRefs(stream), error);
   if (NS_WARN_IF(error.Failed())) {
     return nullptr;
   }
 
-  // Get the MIME type string of the blob.
-  // The type will be checked in the DecodeImageAsync() method.
-  nsAutoString mimeTypeUTF16;
-  aBlob.Impl()->GetType(mimeTypeUTF16);
-  NS_ConvertUTF16toUTF8 mimeType(mimeTypeUTF16);
+  if (!NS_InputStreamIsBuffered(stream)) {
+    nsCOMPtr<nsIInputStream> bufferedStream;
+    nsresult rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream),
+                                   stream.forget(), 4096);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return nullptr;
+    }
+
+    stream = bufferedStream;
+  }
 
   RefPtr<CreateImageBitmapFromBlob> task =
-    new CreateImageBitmapFromBlob(aPromise, aGlobal, stream.forget(), mimeType,
+    new CreateImageBitmapFromBlob(aPromise, aGlobal, stream.forget(),
                                   aCropRect, aMainThreadEventTarget);
 
   // Nothing to do for the main-thread.
   if (NS_IsMainThread()) {
     return task.forget();
   }
 
   // Let's use a WorkerRef to keep the worker alive if this is not the
@@ -2196,85 +1596,150 @@ CreateImageBitmapFromBlob::Create(Promis
     return nullptr;
   }
 
   task->mWorkerRef = new ThreadSafeWorkerRef(workerRef);
   return task.forget();
 }
 
 nsresult
-CreateImageBitmapFromBlob::StartDecodeAndCropBlob()
+CreateImageBitmapFromBlob::StartMimeTypeAndDecodeAndCropBlob()
 {
   MOZ_ASSERT(IsCurrentThread());
 
   // Workers.
   if (!NS_IsMainThread()) {
     RefPtr<CreateImageBitmapFromBlob> self = this;
     nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
-      "CreateImageBitmapFromBlob::DecodeAndCropBlob",
+      "CreateImageBitmapFromBlob::MimeTypeAndDecodeAndCropBlob",
       [self]() {
-        nsresult rv = self->DecodeAndCropBlob();
+        nsresult rv = self->MimeTypeAndDecodeAndCropBlob();
         if (NS_WARN_IF(NS_FAILED(rv))) {
-          self->DecodeAndCropBlobCompletedMainThread(nullptr, rv);
+          self->MimeTypeAndDecodeAndCropBlobCompletedMainThread(nullptr, rv);
         }
       });
 
     return mMainThreadEventTarget->Dispatch(r.forget());
   }
 
   // Main-thread.
-  return DecodeAndCropBlob();
+  return MimeTypeAndDecodeAndCropBlob();
 }
 
 nsresult
-CreateImageBitmapFromBlob::DecodeAndCropBlob()
+CreateImageBitmapFromBlob::MimeTypeAndDecodeAndCropBlob()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
+  nsAutoCString mimeType;
+  nsresult rv = GetMimeTypeSync(mimeType);
+  if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
+    return GetMimeTypeAsync();
+  }
+
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  return DecodeAndCropBlob(mimeType);
+}
+
+nsresult
+CreateImageBitmapFromBlob::DecodeAndCropBlob(const nsACString& aMimeType)
+{
   // Get the Component object.
   nsCOMPtr<imgITools> imgtool = do_GetService(NS_IMGTOOLS_CID);
   if (NS_WARN_IF(!imgtool)) {
     return NS_ERROR_FAILURE;
   }
 
   // Decode image.
-  nsCOMPtr<imgIContainer> imgContainer;
-  nsresult rv = imgtool->DecodeImageAsync(mInputStream, mMimeType, this,
+  nsresult rv = imgtool->DecodeImageAsync(mInputStream, aMimeType, this,
                                           mMainThreadEventTarget);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return NS_OK;
 }
 
+static nsresult
+sniff_cb(nsIInputStream* aInputStream,
+         void* aClosure,
+         const char* aFromRawSegment,
+         uint32_t aToOffset,
+         uint32_t aCount,
+         uint32_t* aWriteCount)
+{
+  nsACString* mimeType = static_cast<nsACString*>(aClosure);
+  MOZ_ASSERT(mimeType);
+
+  if (aCount > 0) {
+    imgLoader::GetMimeTypeFromContent(aFromRawSegment, aCount, *mimeType);
+  }
+
+  *aWriteCount = 0;
+
+  // We don't want to consume data from the stream.
+  return NS_ERROR_FAILURE;
+}
+
+nsresult
+CreateImageBitmapFromBlob::GetMimeTypeSync(nsACString& aMimeType)
+{
+  uint32_t dummy;
+  return mInputStream->ReadSegments(sniff_cb, &aMimeType, 128, &dummy);
+}
+
+nsresult
+CreateImageBitmapFromBlob::GetMimeTypeAsync()
+{
+  nsCOMPtr<nsIAsyncInputStream> asyncInputStream =
+    do_QueryInterface(mInputStream);
+  if (NS_WARN_IF(!asyncInputStream)) {
+    // If the stream is not async, why are we here?
+    return NS_ERROR_FAILURE;
+  }
+
+  return asyncInputStream->AsyncWait(this, 0, 128, mMainThreadEventTarget);
+}
+
+NS_IMETHODIMP
+CreateImageBitmapFromBlob::OnInputStreamReady(nsIAsyncInputStream* aStream)
+{
+  // The stream should have data now. Let's start from scratch again.
+  return MimeTypeAndDecodeAndCropBlob();
+}
+
 NS_IMETHODIMP
 CreateImageBitmapFromBlob::OnImageReady(imgIContainer* aImgContainer,
                                         nsresult aStatus)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (NS_FAILED(aStatus)) {
-    DecodeAndCropBlobCompletedMainThread(nullptr, aStatus);
+    MimeTypeAndDecodeAndCropBlobCompletedMainThread(nullptr, aStatus);
     return NS_OK;
   }
 
   MOZ_ASSERT(aImgContainer);
 
   // Get the surface out.
   uint32_t frameFlags = imgIContainer::FLAG_SYNC_DECODE | imgIContainer::FLAG_WANT_DATA_SURFACE;
   uint32_t whichFrame = imgIContainer::FRAME_FIRST;
   RefPtr<SourceSurface> surface = aImgContainer->GetFrame(whichFrame, frameFlags);
 
   if (NS_WARN_IF(!surface)) {
-    DecodeAndCropBlobCompletedMainThread(nullptr, NS_ERROR_FAILURE);
+    MimeTypeAndDecodeAndCropBlobCompletedMainThread(nullptr,
+                                                    NS_ERROR_DOM_INVALID_STATE_ERR);
     return NS_OK;
   }
 
-  // Store the sourceSize value for the DecodeAndCropBlobCompletedMainThread call.
+  // Store the sourceSize value for the
+  // MimeTypeAndDecodeAndCropBlobCompletedMainThread call.
   mSourceSize = surface->GetSize();
 
   // Crop the source surface if needed.
   RefPtr<SourceSurface> croppedSurface = surface;
 
   if (mCropRect.isSome()) {
     // The blob is just decoded into a RasterImage and not optimized yet, so the
     // _surface_ we get is a DataSourceSurface which wraps the RasterImage's
@@ -2289,35 +1754,37 @@ CreateImageBitmapFromBlob::OnImageReady(
     //       decode the blob off the main thread. Re-check if we should do
     //       cropping at this moment again there.
     RefPtr<DataSourceSurface> dataSurface = surface->GetDataSurface();
     croppedSurface = CropAndCopyDataSourceSurface(dataSurface, mCropRect.ref());
     mCropRect->MoveTo(0, 0);
   }
 
   if (NS_WARN_IF(!croppedSurface)) {
-    DecodeAndCropBlobCompletedMainThread(nullptr, NS_ERROR_FAILURE);
+    MimeTypeAndDecodeAndCropBlobCompletedMainThread(nullptr,
+                                                    NS_ERROR_DOM_INVALID_STATE_ERR);
     return NS_OK;
   }
 
   // Create an Image from the source surface.
   RefPtr<layers::Image> image = CreateImageFromSurface(croppedSurface);
 
   if (NS_WARN_IF(!image)) {
-    DecodeAndCropBlobCompletedMainThread(nullptr, NS_ERROR_FAILURE);
+    MimeTypeAndDecodeAndCropBlobCompletedMainThread(nullptr,
+                                                    NS_ERROR_DOM_INVALID_STATE_ERR);
     return NS_OK;
   }
 
-  DecodeAndCropBlobCompletedMainThread(image, NS_OK);
+  MimeTypeAndDecodeAndCropBlobCompletedMainThread(image, NS_OK);
   return NS_OK;
 }
 
 void
-CreateImageBitmapFromBlob::DecodeAndCropBlobCompletedMainThread(layers::Image* aImage,
-                                                                nsresult aStatus)
+CreateImageBitmapFromBlob::MimeTypeAndDecodeAndCropBlobCompletedMainThread(layers::Image* aImage,
+                                                                           nsresult aStatus)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (!IsCurrentThread()) {
     MutexAutoLock lock(mMutex);
 
     if (!mWorkerRef) {
       // The worker is already gone.
@@ -2326,22 +1793,22 @@ CreateImageBitmapFromBlob::DecodeAndCrop
 
     RefPtr<CreateImageBitmapFromBlobRunnable> r =
       new CreateImageBitmapFromBlobRunnable(mWorkerRef->Private(),
                                             this, aImage, aStatus);
     r->Dispatch();
     return;
   }
 
-  DecodeAndCropBlobCompletedOwningThread(aImage, aStatus);
+  MimeTypeAndDecodeAndCropBlobCompletedOwningThread(aImage, aStatus);
 }
 
 void
-CreateImageBitmapFromBlob::DecodeAndCropBlobCompletedOwningThread(layers::Image* aImage,
-                                                                  nsresult aStatus)
+CreateImageBitmapFromBlob::MimeTypeAndDecodeAndCropBlobCompletedOwningThread(layers::Image* aImage,
+                                                                             nsresult aStatus)
 {
   MOZ_ASSERT(IsCurrentThread());
 
   if (!mPromise) {
     // The worker is going to be released soon. No needs to continue.
     return;
   }
 
@@ -2357,20 +1824,16 @@ CreateImageBitmapFromBlob::DecodeAndCrop
   if (NS_WARN_IF(NS_FAILED(aStatus))) {
     mPromise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
     return;
   }
 
   // Create ImageBitmap object.
   RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(mGlobalObject, aImage);
 
-  // Set mIsCroppingAreaOutSideOfSourceImage.
-  imageBitmap->SetIsCroppingAreaOutSideOfSourceImage(mSourceSize,
-                                                     mOriginalCropRect);
-
   if (mCropRect.isSome()) {
     ErrorResult rv;
     imageBitmap->SetPictureRect(mCropRect.ref(), rv);
 
     if (rv.Failed()) {
       mPromise->MaybeReject(rv);
       return;
     }
--- a/dom/canvas/ImageBitmap.h
+++ b/dom/canvas/ImageBitmap.h
@@ -36,38 +36,35 @@ namespace layers {
 class Image;
 }
 
 namespace dom {
 class OffscreenCanvas;
 
 class ArrayBufferViewOrArrayBuffer;
 class CanvasRenderingContext2D;
-struct ChannelPixelLayout;
 class CreateImageBitmapFromBlob;
 class CreateImageBitmapFromBlobTask;
 class CreateImageBitmapFromBlobWorkerTask;
 class File;
 class HTMLCanvasElement;
 class HTMLImageElement;
 class HTMLVideoElement;
 enum class ImageBitmapFormat : uint8_t;
 class ImageData;
 class ImageUtils;
-template<typename T> class MapDataIntoBufferSource;
 class Promise;
 class PostMessageEvent; // For StructuredClone between windows.
 class ImageBitmapShutdownObserver;
 
 struct ImageBitmapCloneData final
 {
   RefPtr<gfx::DataSourceSurface> mSurface;
   gfx::IntRect mPictureRect;
   gfxAlphaType mAlphaType;
-  bool mIsCroppingAreaOutSideOfSourceImage;
 };
 
 /*
  * ImageBitmap is an opaque handler to several kinds of image-like objects from
  * HTMLImageElement, HTMLVideoElement, HTMLCanvasElement, ImageData to
  * CanvasRenderingContext2D and Image Blob.
  *
  * An ImageBitmap could be painted to a canvas element.
@@ -130,57 +127,32 @@ public:
   CreateFromOffscreenCanvas(nsIGlobalObject* aGlobal,
                             OffscreenCanvas& aOffscreenCanvas,
                             ErrorResult& aRv);
 
   static already_AddRefed<Promise>
   Create(nsIGlobalObject* aGlobal, const ImageBitmapSource& aSrc,
          const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv);
 
-  static already_AddRefed<Promise>
-  Create(nsIGlobalObject* aGlobal,
-         const ImageBitmapSource& aBuffer,
-         int32_t aOffset, int32_t aLength,
-         mozilla::dom::ImageBitmapFormat aFormat,
-         const Sequence<mozilla::dom::ChannelPixelLayout>& aLayout,
-         ErrorResult& aRv);
-
   static JSObject*
   ReadStructuredClone(JSContext* aCx,
                       JSStructuredCloneReader* aReader,
                       nsIGlobalObject* aParent,
                       const nsTArray<RefPtr<gfx::DataSourceSurface>>& aClonedSurfaces,
                       uint32_t aIndex);
 
   static bool
   WriteStructuredClone(JSStructuredCloneWriter* aWriter,
                        nsTArray<RefPtr<gfx::DataSourceSurface>>& aClonedSurfaces,
                        ImageBitmap* aImageBitmap);
 
   friend CreateImageBitmapFromBlob;
   friend CreateImageBitmapFromBlobTask;
   friend CreateImageBitmapFromBlobWorkerTask;
 
-  template<typename T>
-  friend class MapDataIntoBufferSource;
-
-  // Mozilla Extensions
-  ImageBitmapFormat
-  FindOptimalFormat(const Optional<Sequence<ImageBitmapFormat>>& aPossibleFormats,
-                    ErrorResult& aRv);
-
-  int32_t
-  MappedDataLength(ImageBitmapFormat aFormat, ErrorResult& aRv);
-
-  already_AddRefed<Promise>
-  MapDataInto(JSContext* aCx,
-              ImageBitmapFormat aFormat,
-              const ArrayBufferViewOrArrayBuffer& aBuffer,
-              int32_t aOffset, ErrorResult& aRv);
-
   size_t GetAllocatedSize() const;
 
   void OnShutdown();
 
 protected:
 
   /*
    * The default value of aIsPremultipliedAlpha is TRUE because that the
@@ -203,19 +175,16 @@ protected:
    */
   ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData,
               gfxAlphaType aAlphaType = gfxAlphaType::Premult);
 
   virtual ~ImageBitmap();
 
   void SetPictureRect(const gfx::IntRect& aRect, ErrorResult& aRv);
 
-  void SetIsCroppingAreaOutSideOfSourceImage(const gfx::IntSize& aSourceSize,
-                                             const Maybe<gfx::IntRect>& aCroppingRect);
-
   static already_AddRefed<ImageBitmap>
   CreateInternal(nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl,
                  const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv);
 
   static already_AddRefed<ImageBitmap>
   CreateInternal(nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl,
                  const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv);
 
@@ -274,25 +243,16 @@ protected:
    */
   gfx::IntRect mPictureRect;
 
   const gfxAlphaType mAlphaType;
 
   RefPtr<ImageBitmapShutdownObserver> mShutdownObserver;
 
   /*
-   * Set mIsCroppingAreaOutSideOfSourceImage if image bitmap was cropped to the
-   * source rectangle so that it contains any transparent black pixels (cropping
-   * area is outside of the source image).
-   * This is used in mapDataInto() to check if we should reject promise with
-   * IndexSizeError.
-   */
-  bool mIsCroppingAreaOutSideOfSourceImage;
-
-  /*
    * Whether this object allocated allocated and owns the image data.
    */
   bool mAllocatedImageData;
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/canvas/ImageBitmapSource.h
+++ b/dom/canvas/ImageBitmapSource.h
@@ -6,16 +6,15 @@
 
 #ifndef mozilla_dom_ImageBitmapSource_h
 #define mozilla_dom_ImageBitmapSource_h
 
 namespace mozilla {
 namespace dom {
 
 // So we don't have to forward declare this elsewhere.
-class HTMLImageElementOrHTMLVideoElementOrHTMLCanvasElementOrBlobOrImageDataOrCanvasRenderingContext2DOrImageBitmapOrArrayBufferViewOrArrayBuffer;
-typedef HTMLImageElementOrHTMLVideoElementOrHTMLCanvasElementOrBlobOrImageDataOrCanvasRenderingContext2DOrImageBitmapOrArrayBufferViewOrArrayBuffer
-        ImageBitmapSource;
+class HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmapOrBlobOrCanvasRenderingContext2DOrImageData;
+typedef HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmapOrBlobOrCanvasRenderingContext2DOrImageData ImageBitmapSource;
 
 }
 }
 
 #endif
--- a/dom/canvas/ImageBitmapUtils.cpp
+++ b/dom/canvas/ImageBitmapUtils.cpp
@@ -2725,26 +2725,16 @@ uint8_t
 GetChannelCountOfImageFormat(ImageBitmapFormat aFormat)
 {
   UtilsUniquePtr format = Utils::GetUtils(aFormat);
   MOZ_ASSERT(format, "Cannot get a valid ImageBitmapFormatUtils instance.");
 
   return format->GetChannelCount();
 }
 
-uint32_t
-CalculateImageBufferSize(ImageBitmapFormat aFormat,
-                         uint32_t aWidth, uint32_t aHeight)
-{
-  UtilsUniquePtr format = Utils::GetUtils(aFormat);
-  MOZ_ASSERT(format, "Cannot get a valid ImageBitmapFormatUtils instance.");
-
-  return format->NeededBufferSize(aWidth, aHeight);
-}
-
 UniquePtr<ImagePixelLayout>
 CopyAndConvertImageData(ImageBitmapFormat aSrcFormat,
                         const uint8_t* aSrcBuffer,
                         const ImagePixelLayout* aSrcLayout,
                         ImageBitmapFormat aDstFormat,
                         uint8_t* aDstBuffer)
 {
   MOZ_ASSERT(aSrcBuffer, "Convert color from a null buffer.");
--- a/dom/canvas/ImageBitmapUtils.h
+++ b/dom/canvas/ImageBitmapUtils.h
@@ -44,24 +44,16 @@ CreatePixelLayoutFromPlanarYCbCrData(con
 
 /*
  * Get the number of channels of the given ImageBitmapFormat.
  */
 uint8_t
 GetChannelCountOfImageFormat(ImageBitmapFormat aFormat);
 
 /*
- * Get the needed buffer size to store the image data in the given
- * ImageBitmapFormat with the given width and height.
- */
-uint32_t
-CalculateImageBufferSize(ImageBitmapFormat aFormat,
-                         uint32_t aWidth, uint32_t aHeight);
-
-/*
  * This function always copies the image data in _aSrcBuffer_ into _aDstBuffer_
  * and it also performs color conversion if the _aSrcFormat_ and the
  * _aDstFormat_ are different.
  *
  * The source image is stored in the _aSrcBuffer_ and the corresponding pixel
  * layout is described by the _aSrcLayout_.
  *
  * The copied and converted image will be stored in the _aDstBuffer_, which
--- a/dom/canvas/ImageUtils.cpp
+++ b/dom/canvas/ImageUtils.cpp
@@ -120,48 +120,16 @@ public:
   GetBufferLength() const
   {
     DataSourceSurface::ScopedMap map(Surface(), DataSourceSurface::READ);
     const uint32_t stride = map.GetStride();
     const IntSize size = Surface()->GetSize();
     return (uint32_t)(size.height * stride);
   }
 
-  virtual UniquePtr<ImagePixelLayout>
-  MapDataInto(uint8_t* aBuffer,
-              uint32_t aOffset,
-              uint32_t aBufferLength,
-              ImageBitmapFormat aFormat,
-              ErrorResult& aRv) const
-  {
-    DataSourceSurface::ScopedMap map(Surface(), DataSourceSurface::READ);
-    if (!map.IsMapped()) {
-      aRv.Throw(NS_ERROR_ILLEGAL_VALUE);
-      return nullptr;
-    }
-
-    // Copy or convert data.
-    UniquePtr<ImagePixelLayout> srcLayout =
-      CreateDefaultPixelLayout(GetFormat(), Surface()->GetSize().width,
-                               Surface()->GetSize().height, map.GetStride());
-
-    // Prepare destination buffer.
-    uint8_t* dstBuffer = aBuffer + aOffset;
-    UniquePtr<ImagePixelLayout> dstLayout =
-      CopyAndConvertImageData(GetFormat(), map.GetData(), srcLayout.get(),
-                              aFormat, dstBuffer);
-
-    if (!dstLayout) {
-      aRv.Throw(NS_ERROR_NOT_AVAILABLE);
-      return nullptr;
-    }
-
-    return dstLayout;
-  }
-
 protected:
   Impl() {}
 
   DataSourceSurface* Surface() const
   {
     if (!mSurface) {
       RefPtr<SourceSurface> surface = mImage->GetAsSourceSurface();
       MOZ_ASSERT(surface);
@@ -198,41 +166,16 @@ public:
   uint32_t GetBufferLength() const override
   {
     if (mImage->GetFormat() == ImageFormat::PLANAR_YCBCR) {
       return mImage->AsPlanarYCbCrImage()->GetDataSize();
     }
     return mImage->AsNVImage()->GetBufferSize();
   }
 
-  UniquePtr<ImagePixelLayout> MapDataInto(uint8_t* aBuffer,
-                                          uint32_t aOffset,
-                                          uint32_t aBufferLength,
-                                          ImageBitmapFormat aFormat,
-                                          ErrorResult& aRv) const override
-  {
-    // Prepare source buffer and pixel layout.
-    const PlanarYCbCrData* data = GetPlanarYCbCrData();
-
-    UniquePtr<ImagePixelLayout> srcLayout =
-      CreatePixelLayoutFromPlanarYCbCrData(data);
-
-    // Do conversion.
-    UniquePtr<ImagePixelLayout> dstLayout =
-      CopyAndConvertImageData(GetFormat(), data->mYChannel, srcLayout.get(),
-                              aFormat, aBuffer+aOffset);
-
-    if (!dstLayout) {
-      aRv.Throw(NS_ERROR_NOT_AVAILABLE);
-      return nullptr;
-    }
-
-    return dstLayout;
-  }
-
 private:
   const PlanarYCbCrData* GetPlanarYCbCrData() const
   {
     if (mImage->GetFormat() == ImageFormat::PLANAR_YCBCR) {
       return mImage->AsPlanarYCbCrImage()->GetData();
     }
     return mImage->AsNVImage()->GetData();
   }
@@ -272,22 +215,10 @@ ImageUtils::GetFormat() const
 
 uint32_t
 ImageUtils::GetBufferLength() const
 {
   MOZ_ASSERT(mImpl);
   return mImpl->GetBufferLength();
 }
 
-UniquePtr<ImagePixelLayout>
-ImageUtils::MapDataInto(uint8_t* aBuffer,
-                        uint32_t aOffset,
-                        uint32_t aBufferLength,
-                        ImageBitmapFormat aFormat,
-                        ErrorResult& aRv) const
-{
-  MOZ_ASSERT(mImpl);
-  MOZ_ASSERT(aBuffer, "Map data into a null buffer.");
-  return mImpl->MapDataInto(aBuffer, aOffset, aBufferLength, aFormat, aRv);
-}
-
 } // namespace dom
 } // namespace mozilla
--- a/dom/canvas/ImageUtils.h
+++ b/dom/canvas/ImageUtils.h
@@ -27,20 +27,16 @@ typedef nsTArray<ChannelPixelLayout> Ima
 
 /*
  * ImageUtils is a wrapper around layers::Image. It provides three unified
  * methods to all sub-classes of layers::Image, which are:
  *
  * (1) GetFormat() converts the image's format into ImageBitmapFormat enum.
  * (2) GetBufferLength() returns the number of bytes that are used to store
  *     the image's underlying raw data.
- * (3) MapDataInto() writes the image's underlying raw data into a given
- *     ArrayBuffer in the given format. (If the given format is different from
- *     the existing format, the ImageUtils uses the ImageBitmapFormatUtils to
- *     performa color conversion.)
  *
  * In theory, the functionalities of this class could be merged into the
  * interface of layers::Image. However, this is designed as a isolated wrapper
  * because we don't want to pollute the layers::Image's interface with methods
  * that are only meaningful to the ImageBitmap.
  */
 class ImageUtils
 {
@@ -54,20 +50,16 @@ public:
 
   explicit ImageUtils(layers::Image* aImage);
   ~ImageUtils();
 
   ImageBitmapFormat GetFormat() const;
 
   uint32_t GetBufferLength() const;
 
-  UniquePtr<ImagePixelLayout>
-  MapDataInto(uint8_t* aBuffer, uint32_t aOffset, uint32_t aBufferLength,
-              ImageBitmapFormat aFormat, ErrorResult& aRv) const;
-
 protected:
   Impl* mImpl;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif /* mozilla_dom_ImageBitmapFormatUtils_h */
deleted file mode 100644
--- a/dom/canvas/test/imagebitmap_extensions.html
+++ /dev/null
@@ -1,49 +0,0 @@
-<!DOCTYPE HTML>
-<head>
-  <title>Test ImageBitmap Extensions (Bug 1141979)</title>
-  <meta charset="utf-8">
-  <script src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" href="/tests/SimpleTest/test.css">
-</head>
-<body>
-<script src="imagebitmap_extensions_prepareSources.js"></script>
-<script src="imagebitmap_extensions_data.js"></script>
-<script src="imagebitmap_extensions.js"></script>
-<script type="text/javascript">
-
-runTests();
-
-function ok(expect, msg) {
-  window.parent.postMessage({"type": "status", status: !!expect, msg: msg}, "*");
-}
-
-function runTests() {
-
-  prepareSources().
-    then( function() { return Promise.all([testAccessing_randomTest("Video", gVideo, 20), // video might use slightly different frames
-                                           testAccessing_randomTest("Image", gImage, 0),
-                                           testAccessing_randomTest("Canvas", gCanvas, 0),
-                                           testAccessing_randomTest("Ctx", gCtx, 0),
-                                           testAccessing_randomTest("ImageData", gImageData, 0),
-                                           testAccessing_randomTest("ImageBitmap", gImageBitmap, 0),
-                                           testAccessing_randomTest("PNG", gPNGBlob, 0),
-                                           testAccessing_randomTest("JPEG", gJPEGBlob, 10) // JPEG loses information
-                                          ]); }).
-    then( function() { return Promise.all([testCreateFromArrayBffer_randomTest("Video", gVideo, 20), // video might use slightly different frames
-                                           testCreateFromArrayBffer_randomTest("Image", gImage, 0),
-                                           testCreateFromArrayBffer_randomTest("Canvas", gCanvas, 0),
-                                           testCreateFromArrayBffer_randomTest("Ctx", gCtx, 0),
-                                           testCreateFromArrayBffer_randomTest("ImageData", gImageData, 0),
-                                           testCreateFromArrayBffer_randomTest("ImageBitmap", gImageBitmap, 0),
-                                           testCreateFromArrayBffer_randomTest("PNG", gPNGBlob, 0),
-                                           testCreateFromArrayBffer_randomTest("JPEG", gJPEGBlob, 10) // JPEG loses information
-                                          ]); }).
-    then(testDraw()).
-    then(testExceptions).
-    then(testColorConversions()).
-    then(function() { return testInvalidAccess([gVideo, gImage, gCanvas, gCtx, gImageData, gImageBitmap, gPNGBlob, gJPEGBlob]); } ).
-    then(function() {window.parent.postMessage({"type": "finish"}, "*");}, function(ev) { failed(ev); window.parent.postMessage({"type": "finish"}, "*"); });
-}
-
-</script>
-</body>
deleted file mode 100644
--- a/dom/canvas/test/imagebitmap_extensions.js
+++ /dev/null
@@ -1,526 +0,0 @@
-function failed(ex) {
-  ok(false, "Promise failure: " + ex);
-}
-
-function isPixel(sourceType, bitmapFormat, imageData, bitmapImageData, x, y, tolerance) {
-  if (imageData.width != bitmapImageData.width ||
-    imageData.height != bitmapImageData.height) {
-    ok(false, "Wrong dimension");
-  }
-
-  var index = 4 * (y * imageData.width + x);
-
-  var pr = imageData.data[index+0],
-      pg = imageData.data[index+1],
-      pb = imageData.data[index+2],
-      pa = imageData.data[index+3];
-
-  if (bitmapFormat == "RGBA32" || bitmapFormat == "RGBX32") {
-    var bpr = bitmapImageData.data[index+0],
-        bpg = bitmapImageData.data[index+1],
-        bpb = bitmapImageData.data[index+2],
-        bpa = bitmapImageData.data[index+3];
-  }
-  else if (bitmapFormat == "BGRA32" || bitmapFormat == "BGRX32") {
-    var bpb = bitmapImageData.data[index+0],
-        bpg = bitmapImageData.data[index+1],
-        bpr = bitmapImageData.data[index+2],
-        bpa = bitmapImageData.data[index+3];
-  }
-  else {
-    // format might be one of the followings: "R5G6B5", "A8", "YUV", ""
-    ok(false, "Not supported ImageFormat: " + bitmapFormat);
-  }
-
-  ok(pr - tolerance <= bpr && bpr <= pr + tolerance &&
-     pg - tolerance <= bpg && bpg <= pg + tolerance &&
-     pb - tolerance <= bpb && bpb <= pb + tolerance &&
-     pa - tolerance <= bpa && bpa <= pa + tolerance,
-     "pixel[" + x + "][" + y + "]: " + sourceType + " is "+pr+","+pg+","+pb+","+pa+"; ImageBitmap is "+ bpr + "," + bpg + "," + bpb + "," + bpa);
-}
-
-function promiseThrows(p, name) {
-  var didThrow;
-  return p.then(function() { didThrow = false; },
-                function() { didThrow = true; })
-          .then(function() { ok(didThrow, name); });
-}
-
-function testExceptions() {
-  return Promise.all([
-    promiseThrows(testColorConversion("GRAY8", "RGBA32", undefined, true), "[Exception] Cannot convert from GRAY8 to RGBA32"),
-    promiseThrows(testColorConversion("GRAY8", "BGRA32", undefined, true), "[Exception] Cannot convert from GRAY8 to BGRA32"),
-    promiseThrows(testColorConversion("GRAY8", "RGB24", undefined, true), "[Exception] Cannot convert from GRAY8 to RGB24"),
-    promiseThrows(testColorConversion("GRAY8", "BGR24", undefined, true), "[Exception] Cannot convert from GRAY8 to BGR24"),
-    promiseThrows(testColorConversion("GRAY8", "YUV444P", undefined, true), "[Exception] Cannot convert from GRAY8 to YUV444P"),
-    promiseThrows(testColorConversion("GRAY8", "YUV422P", undefined, true), "[Exception] Cannot convert from GRAY8 to YUV422P"),
-    promiseThrows(testColorConversion("GRAY8", "YUV420P", undefined, true), "[Exception] Cannot convert from GRAY8 to YUV420P"),
-    promiseThrows(testColorConversion("GRAY8", "YUV420SP_NV12", undefined, true), "[Exception] Cannot convert from GRAY8 to YUV420SP_NV12"),
-    promiseThrows(testColorConversion("GRAY8", "YUV420SP_NV21", undefined, true), "[Exception] Cannot convert from GRAY8 to YUV420SP_NV21"),
-    promiseThrows(testColorConversion("GRAY8", "HSV", undefined, true), "[Exception] Cannot convert from GRAY8 to HSV"),
-    promiseThrows(testColorConversion("GRAY8", "Lab", undefined, true), "[Exception] Cannot convert from GRAY8 to Lab"),
-    promiseThrows(testColorConversion("GRAY8", "DEPTH", undefined, true), "[Exception] Cannot convert from GRAY8 to DEPTH"),
-
-    promiseThrows(testColorConversion("DEPTH", "RGBA32", undefined, true), "[Exception] Cannot convert from DEPTH to RGBA32"),
-    promiseThrows(testColorConversion("DEPTH", "BGRA32", undefined, true), "[Exception] Cannot convert from DEPTH to BGRA32"),
-    promiseThrows(testColorConversion("DEPTH", "RGB24", undefined, true), "[Exception] Cannot convert from DEPTH to RGB24"),
-    promiseThrows(testColorConversion("DEPTH", "BGR24", undefined, true), "[Exception] Cannot convert from DEPTH to BGR24"),
-    promiseThrows(testColorConversion("DEPTH", "GRAY8", undefined, true), "[Exception] Cannot convert from DEPTH to GRAY8"),
-    promiseThrows(testColorConversion("DEPTH", "YUV444P", undefined, true), "[Exception] Cannot convert from DEPTH to YUV444P"),
-    promiseThrows(testColorConversion("DEPTH", "YUV422P", undefined, true), "[Exception] Cannot convert from DEPTH to YUV422P"),
-    promiseThrows(testColorConversion("DEPTH", "YUV420P", undefined, true), "[Exception] Cannot convert from DEPTH to YUV420P"),
-    promiseThrows(testColorConversion("DEPTH", "YUV420SP_NV12", undefined, true), "[Exception] Cannot convert from DEPTH to YUV420SP_NV12"),
-    promiseThrows(testColorConversion("DEPTH", "YUV420SP_NV21", undefined, true), "[Exception] Cannot convert from DEPTH to YUV420SP_NV21"),
-    promiseThrows(testColorConversion("DEPTH", "HSV", undefined, true), "[Exception] Cannot convert from DEPTH to HSV"),
-    promiseThrows(testColorConversion("DEPTH", "Lab", undefined, true), "[Exception] Cannot convert from DEPTH to Lab"),
-
-    promiseThrows(testColorConversion("RGBA32", "DEPTH", undefined, true), "[Exception] Cannot convert from RGBA32 to DEPTH"),
-    promiseThrows(testColorConversion("BGRA32", "DEPTH", undefined, true), "[Exception] Cannot convert from BGRA32 to DEPTH"),
-    promiseThrows(testColorConversion("RGB24", "DEPTH", undefined, true), "[Exception] Cannot convert from RGB24 to DEPTH"),
-    promiseThrows(testColorConversion("BGR24", "DEPTH", undefined, true), "[Exception] Cannot convert from BGR24 to DEPTH"),
-    promiseThrows(testColorConversion("YUV444P", "DEPTH", undefined, true), "[Exception] Cannot convert from YUV444P to DEPTH"),
-    promiseThrows(testColorConversion("YUV422P", "DEPTH", undefined, true), "[Exception] Cannot convert from YUV422P to DEPTH"),
-    promiseThrows(testColorConversion("YUV420P", "DEPTH", undefined, true), "[Exception] Cannot convert from YUV420P to DEPTH"),
-    promiseThrows(testColorConversion("YUV420SP_NV12", "DEPTH", undefined, true), "[Exception] Cannot convert from YUV420SP_NV12 to DEPTH"),
-    promiseThrows(testColorConversion("YUV420SP_NV21", "DEPTH", undefined, true), "[Exception] Cannot convert from YUV420SP_NV21 to DEPTH"),
-    promiseThrows(testColorConversion("HSV", "DEPTH", undefined, true), "[Exception] Cannot convert from HSV to DEPTH"),
-    promiseThrows(testColorConversion("Lab", "DEPTH", undefined, true), "[Exception] Cannot convert from Lab to DEPTH"),
-  ]);
-}
-
-function testInvalidAccess(sources) {
-
-  function callMapDataIntoWithImageBitmapCroppedOutSideOfTheSourceImage(source) {
-    return new Promise(function(resolve, reject) {
-      var p = createImageBitmap(source, -1, -1, 2, 2);
-      p.then(
-        function(bitmap) {
-          var format = bitmap.findOptimalFormat();
-          var length = bitmap.mappedDataLength(format);
-          var buffer = new ArrayBuffer(length);
-          bitmap.mapDataInto(format, buffer, 0).then(
-            function(layout) { resolve(); },
-            function(error) { reject(error); }
-          );
-        },
-        function() { resolve(); });
-    });
-  };
-
-  var testCases = sources.map( function(source) {
-    return promiseThrows(callMapDataIntoWithImageBitmapCroppedOutSideOfTheSourceImage(source),
-                         "[Exception] mapDataInto() should throw with transparent black."); });
-
-  return Promise.all(testCases);
-}
-
-function testColorConversions() {
-  return Promise.all([// From RGBA32
-                      testColorConversion("RGBA32", "RGBA32"),
-                      testColorConversion("RGBA32", "BGRA32"),
-                      testColorConversion("RGBA32", "RGB24"),
-                      testColorConversion("RGBA32", "BGR24"),
-                      testColorConversion("RGBA32", "GRAY8"),
-                      testColorConversion("RGBA32", "YUV444P"),
-                      testColorConversion("RGBA32", "YUV422P"),
-                      testColorConversion("RGBA32", "YUV420P", 2),
-                      testColorConversion("RGBA32", "YUV420SP_NV12"),
-                      testColorConversion("RGBA32", "YUV420SP_NV21"),
-                      testColorConversion("RGBA32", "HSV", 0.01),
-                      testColorConversion("RGBA32", "Lab", 0.5),
-
-                      // From BGRA32
-                      testColorConversion("BGRA32", "RGBA32"),
-                      testColorConversion("BGRA32", "BGRA32"),
-                      testColorConversion("BGRA32", "RGB24"),
-                      testColorConversion("BGRA32", "BGR24"),
-                      testColorConversion("BGRA32", "GRAY8"),
-                      testColorConversion("BGRA32", "YUV444P", 3),
-                      testColorConversion("BGRA32", "YUV422P", 2),
-                      testColorConversion("BGRA32", "YUV420P", 2),
-                      testColorConversion("BGRA32", "YUV420SP_NV12", 2),
-                      testColorConversion("BGRA32", "YUV420SP_NV21", 2),
-                      testColorConversion("BGRA32", "HSV", 0.01),
-                      testColorConversion("BGRA32", "Lab", 0.5),
-
-                      // From RGB24
-                      testColorConversion("RGB24", "RGBA32"),
-                      testColorConversion("RGB24", "BGRA32"),
-                      testColorConversion("RGB24", "RGB24"),
-                      testColorConversion("RGB24", "BGR24"),
-                      testColorConversion("RGB24", "GRAY8"),
-                      testColorConversion("RGB24", "YUV444P"),
-                      testColorConversion("RGB24", "YUV422P"),
-                      testColorConversion("RGB24", "YUV420P"),
-                      testColorConversion("RGB24", "YUV420SP_NV12"),
-                      testColorConversion("RGB24", "YUV420SP_NV21"),
-                      testColorConversion("RGB24", "HSV", 0.01),
-                      testColorConversion("RGB24", "Lab", 0.5),
-
-                      // From BGR24
-                      testColorConversion("BGR24", "RGBA32"),
-                      testColorConversion("BGR24", "BGRA32"),
-                      testColorConversion("BGR24", "RGB24"),
-                      testColorConversion("BGR24", "BGR24"),
-                      testColorConversion("BGR24", "GRAY8"),
-                      testColorConversion("BGR24", "YUV444P"),
-                      testColorConversion("BGR24", "YUV422P"),
-                      testColorConversion("BGR24", "YUV420P"),
-                      testColorConversion("BGR24", "YUV420SP_NV12"),
-                      testColorConversion("BGR24", "YUV420SP_NV21"),
-                      testColorConversion("BGR24", "HSV", 0.01),
-                      testColorConversion("BGR24", "Lab", 0.5),
-
-                      // From YUV444P
-                      testColorConversion("YUV444P", "RGBA32"),
-                      testColorConversion("YUV444P", "BGRA32"),
-                      testColorConversion("YUV444P", "RGB24"),
-                      testColorConversion("YUV444P", "BGR24"),
-                      testColorConversion("YUV444P", "GRAY8"),
-                      testColorConversion("YUV444P", "YUV444P"),
-                      testColorConversion("YUV444P", "YUV422P", 4),
-                      testColorConversion("YUV444P", "YUV420P", 3),
-                      testColorConversion("YUV444P", "YUV420SP_NV12", 3),
-                      testColorConversion("YUV444P", "YUV420SP_NV21", 3),
-                      testColorConversion("YUV444P", "HSV", 0.01),
-                      testColorConversion("YUV444P", "Lab", 0.01),
-
-                      // From YUV422P
-                      testColorConversion("YUV422P", "RGBA32"),
-                      testColorConversion("YUV422P", "BGRA32", 2),
-                      testColorConversion("YUV422P", "RGB24"),
-                      testColorConversion("YUV422P", "BGR24"),
-                      testColorConversion("YUV422P", "GRAY8"),
-                      testColorConversion("YUV422P", "YUV444P", 3),
-                      testColorConversion("YUV422P", "YUV422P"),
-                      testColorConversion("YUV422P", "YUV420P"),
-                      testColorConversion("YUV422P", "YUV420SP_NV12"),
-                      testColorConversion("YUV422P", "YUV420SP_NV21"),
-                      testColorConversion("YUV422P", "HSV", 0.01),
-                      testColorConversion("YUV422P", "Lab", 0.01),
-
-                      // From YUV420P
-                      testColorConversion("YUV420P", "RGBA32", 2),
-                      testColorConversion("YUV420P", "BGRA32", 2),
-                      testColorConversion("YUV420P", "RGB24"),
-                      testColorConversion("YUV420P", "BGR24"),
-                      testColorConversion("YUV420P", "GRAY8"),
-                      testColorConversion("YUV420P", "YUV444P", 3),
-                      testColorConversion("YUV420P", "YUV422P", 1),
-                      testColorConversion("YUV420P", "YUV420P"),
-                      testColorConversion("YUV420P", "YUV420SP_NV12"),
-                      testColorConversion("YUV420P", "YUV420SP_NV21"),
-                      testColorConversion("YUV420P", "HSV", 0.01),
-                      testColorConversion("YUV420P", "Lab", 0.01),
-
-                      // From NV12
-                      testColorConversion("YUV420SP_NV12", "RGBA32"),
-                      testColorConversion("YUV420SP_NV12", "BGRA32", 2),
-                      testColorConversion("YUV420SP_NV12", "RGB24"),
-                      testColorConversion("YUV420SP_NV12", "BGR24"),
-                      testColorConversion("YUV420SP_NV12", "GRAY8"),
-                      testColorConversion("YUV420SP_NV12", "YUV444P", 3),
-                      testColorConversion("YUV420SP_NV12", "YUV422P", 1),
-                      testColorConversion("YUV420SP_NV12", "YUV420P"),
-                      testColorConversion("YUV420SP_NV12", "YUV420SP_NV12"),
-                      testColorConversion("YUV420SP_NV12", "YUV420SP_NV21"),
-                      testColorConversion("YUV420SP_NV12", "HSV", 0.01),
-                      testColorConversion("YUV420SP_NV12", "Lab", 0.01),
-
-                      // From NV21
-                      testColorConversion("YUV420SP_NV21", "RGBA32"),
-                      testColorConversion("YUV420SP_NV21", "BGRA32", 2),
-                      testColorConversion("YUV420SP_NV21", "RGB24"),
-                      testColorConversion("YUV420SP_NV21", "BGR24"),
-                      testColorConversion("YUV420SP_NV21", "GRAY8"),
-                      testColorConversion("YUV420SP_NV21", "YUV444P", 3),
-                      testColorConversion("YUV420SP_NV21", "YUV422P", 1),
-                      testColorConversion("YUV420SP_NV21", "YUV420P"),
-                      testColorConversion("YUV420SP_NV21", "YUV420SP_NV12"),
-                      testColorConversion("YUV420SP_NV21", "YUV420SP_NV21"),
-                      testColorConversion("YUV420SP_NV21", "HSV", 0.01),
-                      testColorConversion("YUV420SP_NV21", "Lab", 0.01),
-
-                      // From HSV
-                      testColorConversion("HSV", "RGBA32"),
-                      testColorConversion("HSV", "BGRA32"),
-                      testColorConversion("HSV", "RGB24"),
-                      testColorConversion("HSV", "BGR24"),
-                      testColorConversion("HSV", "GRAY8"),
-                      testColorConversion("HSV", "YUV444P"),
-                      testColorConversion("HSV", "YUV422P"),
-                      testColorConversion("HSV", "YUV420P"),
-                      testColorConversion("HSV", "YUV420SP_NV12"),
-                      testColorConversion("HSV", "YUV420SP_NV21"),
-                      testColorConversion("HSV", "HSV", 0),
-                      testColorConversion("HSV", "Lab", 0.5),
-
-                      // From Lab
-                      testColorConversion("Lab", "RGBA32", 1),
-                      testColorConversion("Lab", "BGRA32", 1),
-                      testColorConversion("Lab", "RGB24", 1),
-                      testColorConversion("Lab", "BGR24", 1),
-                      testColorConversion("Lab", "GRAY8", 1),
-                      testColorConversion("Lab", "YUV444P", 1),
-                      testColorConversion("Lab", "YUV422P", 1),
-                      testColorConversion("Lab", "YUV420P", 1),
-                      testColorConversion("Lab", "YUV420SP_NV12", 1),
-                      testColorConversion("Lab", "YUV420SP_NV21", 1),
-                      testColorConversion("Lab", "HSV", 0.5),
-                      testColorConversion("Lab", "Lab", 0),
-
-                      // From GRAY8
-                      testColorConversion("GRAY8", "GRAY8"),
-
-                      // From DEPTH
-                      testColorConversion("DEPTH", "DEPTH", 0, Uint16Array),
-                     ]);
-}
-
-function testDraw() {
-  return Promise.all([doOneDrawTest("RGB24"),
-                      doOneDrawTest("BGR24"),
-                      doOneDrawTest("YUV444P", 5),
-                      doOneDrawTest("YUV422P", 2),
-                      doOneDrawTest("YUV420P", 2),
-                      doOneDrawTest("YUV420SP_NV12", 2),
-                      doOneDrawTest("YUV420SP_NV21", 2),
-                      doOneDrawTest("HSV", 2),
-                      doOneDrawTest("Lab", 2)]);
-}
-
-// Create an ImageBitmap, _bitmap_, from the _source_.
-// Read the underlying data of _bitmap_ into _bitmapBuffer_.
-// Compare the _bitmapBuffer_ with gGroundTruthImageData.
-function testAccessing_randomTest(sourceType, source, duration) {
-  return new Promise(function(resolve, reject) {
-    var p  = createImageBitmap(source);
-    p.then(
-      function(bitmap) {
-        bitmapFormat = "RGBA32";
-        var bitmapBufferLength = bitmap.mappedDataLength(bitmapFormat);
-
-        var bitmapBuffer = new ArrayBuffer(bitmapBufferLength);
-        var bitmapBufferView = new Uint8ClampedArray(bitmapBuffer, 0, bitmapBufferLength);
-        var promise = bitmap.mapDataInto(bitmapFormat, bitmapBuffer, 0);
-        promise.then(
-          function(bitmapPixelLayout) {
-            // Prepare.
-            bitmapImageData = new ImageData(bitmapBufferView, bitmap.width, bitmap.height);
-
-            // Test.
-            for (var t = 0; t < 50; ++t) {
-              var randomX = Math.floor(Math.random() * 240);
-              var randomY = Math.floor(Math.random() * 175);
-              isPixel(sourceType, "RGBA32", gGroundTruthImageData, bitmapImageData, randomX, randomY, duration);
-            }
-
-            resolve();
-          },
-          function(ev) { failed(ev); reject(); });
-      },
-      function(ev) { failed(ev); reject(); });
-  });
-}
-
-// Create an ImageBitmap, _bitmap_, from the _source_.
-// Read the underlying data of _bitmap_ into _bitmapBuffer_.
-// Create another ImageBitmap, _bitmap2_, from _bitmapBuffer_.
-// Read the underlying data of _bitmap2_ into _bitmapBuffer2_.
-// Compare the _bitmapBuffer2_ with gGroundTruthImageData.
-function testCreateFromArrayBffer_randomTest(sourceType, source, duration) {
-  return new Promise(function(resolve, reject) {
-    var p  = createImageBitmap(source);
-    p.then(
-      function(bitmap) {
-        bitmapFormat = "RGBA32";
-        var bitmapBufferLength = bitmap.mappedDataLength(bitmapFormat);
-
-        var bitmapBuffer = new ArrayBuffer(bitmapBufferLength);
-        var bitmapBufferView = new Uint8ClampedArray(bitmapBuffer, 0, bitmapBufferLength);
-        var promiseMapDataInto = bitmap.mapDataInto(bitmapFormat, bitmapBuffer, 0);
-        promiseMapDataInto.then(
-          function(bitmapPixelLayout) {
-            // Create a new ImageBitmap from an ArrayBuffer.
-            var p2 = createImageBitmap(bitmapBufferView,
-                                       0,
-                                       bitmapBufferLength,
-                                       bitmapFormat,
-                                       bitmapPixelLayout);
-
-            p2.then(
-              function(bitmap2) {
-                bitmapFormat2 = "RGBA32";
-                var bitmapBufferLength2 = bitmap2.mappedDataLength(bitmapFormat2);
-
-                var bitmapBuffer2 = new ArrayBuffer(bitmapBufferLength2);
-                var bitmapBufferView2 = new Uint8ClampedArray(bitmapBuffer2, 0, bitmapBufferLength2);
-                var promise2 = bitmap2.mapDataInto(bitmapFormat2, bitmapBuffer2, 0);
-                promise2.then(
-                  function(bitmapPixelLayout2) {
-                    // Prepare.
-                    var bitmapImageData2 = new ImageData(bitmapBufferView2, bitmap2.width, bitmap2.height);
-
-                    // Test.
-                    for (var t = 0; t < 50; ++t) {
-                      var randomX = Math.floor(Math.random() * 240);
-                      var randomY = Math.floor(Math.random() * 175);
-                      isPixel(sourceType, "RGBA32", gGroundTruthImageData, bitmapImageData2, randomX, randomY, duration);
-                    }
-
-                    resolve();
-                  },
-                  function(ev) { failed(ev); reject(); });
-              },
-              function(ev) { console.log("p2 rejected!"); failed(ev); reject(); });
-          },
-          function(ev) { console.log("promiseMapDataInto rejected!"); failed(ev); reject(); });
-      },
-      function(ev) { failed(ev); reject(); });
-  });
-}
-
-function testColorConversion(sourceFromat, destinationFormat, tolerance, shouldThrow) {
-
-  tolerance = tolerance || 0;
-  shouldThrow = shouldThrow || false;
-
-  return new Promise(function(resolve, reject) {
-    var [srcData, dstData] = getTestData(sourceFromat, destinationFormat);
-
-    ok(!!srcData, "Get valid srcData of type:" + sourceFromat);
-    ok(!!dstData, "Get valid dstData of type:" + destinationFormat);
-
-    // printInfo(sourceFromat, srcData);
-    // printInfo(destinationFormat, dstData);
-
-    // Create a new ImageBitmap from an ArrayBuffer.
-    var p = createImageBitmap(srcData.buffer,
-                              0,
-                              srcData.bufferLength,
-                              srcData.format,
-                              srcData.pixelLayout);
-
-    p.then(
-      function(srcBitmap) {
-        ok(!!srcBitmap, "Should get a valid srcBitmap.");
-        ok(srcBitmap.findOptimalFormat() == sourceFromat, "srcBitmap.findOptimalFormat():" + srcBitmap.findOptimalFormat() +
-                                                          " should equal to sourceFromat:" + sourceFromat);
-
-        var dstBufferLength = srcBitmap.mappedDataLength(destinationFormat);
-        var dstBuffer = new ArrayBuffer(dstBufferLength);
-        var dstBufferView = new dstData.ArrayType(dstBuffer, 0, dstBufferLength / dstData.ArrayType.BYTES_PER_ELEMENT);
-
-        // Do color conversion here.
-        var p2 = srcBitmap.mapDataInto(destinationFormat, dstBuffer, 0);
-        p2.then(
-          function(dstPixelLayout) {
-            var dataPixalLayout = dstData.pixelLayout;
-
-            // Check pixel layout.
-            ok(dstPixelLayout.length == dstData.channelCount, "dstPixelLayout.length:" + dstPixelLayout.length +
-                                                              " should equal to dstData.channelCount:" + dstData.channelCount);
-
-            for (var c = 0; c < dstData.channelCount; ++c) {
-              var dstChannelLayout = dstPixelLayout[c];
-              var dataChannelLayout = dataPixalLayout[c];
-              ok(dstChannelLayout.width == dataChannelLayout.width, "channel[" + c + "] dstChannelLayout.width:" + dstChannelLayout.width + " should equal to dataChannelLayout.width:" + dataChannelLayout.width);
-              ok(dstChannelLayout.height == dataChannelLayout.height, "channel[" + c + "] dstChannelLayout.height:" + dstChannelLayout.height + " should equal to dataChannelLayout.height:" + dataChannelLayout.height);
-              ok(dstChannelLayout.skip == dataChannelLayout.skip, "channel[" + c + "] dstChannelLayout.skip:" + dstChannelLayout.skip + " should equal to dataChannelLayout.skip:" + dataChannelLayout.skip);
-
-              for (var i = 0; i < dstChannelLayout.height; ++i) {
-                for (var j = 0; j < dstChannelLayout.width; ++j) {
-                  var byteOffset = dstChannelLayout.offset + i * dstChannelLayout.stride + j * (dstChannelLayout.skip + 1) * dstData.ArrayType.BYTES_PER_ELEMENT;
-                  var view = new dstData.ArrayType(dstBuffer, byteOffset, 1);
-                  var dstBufferViewValue = view[0];
-                  var dstDataValue = dstData.getPixelValue(i, j, c);
-                  ok(Math.abs(dstBufferViewValue - dstDataValue) <= tolerance,
-                     "[" + sourceFromat + " -> " + destinationFormat + "] pixel(" + i + "," + j + ") channnel(" + c +
-                     "): dstBufferViewValue:" + dstBufferViewValue +
-                     " should equal to dstDataValue:" + dstDataValue);
-                }
-              }
-            }
-
-            resolve();
-          },
-          function(ev) {
-            // If the "mapDataInto" throws, the flow goes here.
-            if (!shouldThrow) { failed(ev); }
-            reject();
-          }
-        );
-      },
-      function(ev) {
-        reject(ev);
-      }
-    );
-  });
-}
-
-function doOneDrawTest(sourceFromat, tolerance) {
-  tolerance = tolerance || 0;
-  var destinationFormat = "RGBA32";
-
-  return new Promise(function(resolve, reject) {
-
-    var [srcData, dstData] = getTestData(sourceFromat, destinationFormat);
-    ok(!!srcData, "Get valid srcData of type:" + sourceFromat);
-    ok(!!dstData, "Get valid dstData of type:" + destinationFormat);
-
-    var p = createImageBitmap(srcData.buffer,
-                              0,
-                              srcData.bufferLength,
-                              srcData.format,
-                              srcData.pixelLayout);
-
-    p.then(
-      function(srcBitmap) {
-        ok(!!srcBitmap, "Should get a valid srcBitmap.");
-        ok(srcBitmap.findOptimalFormat() == sourceFromat, "srcBitmap.findOptimalFormat():" + srcBitmap.findOptimalFormat() +
-                                                          " should equal to sourceFromat:" + sourceFromat);
-
-        var canvas = document.createElement("canvas");
-        canvas.width = srcBitmap.width;
-        canvas.height = srcBitmap.height;
-        var ctx = canvas.getContext("2d");
-
-        ctx.drawImage(srcBitmap, 0, 0, srcBitmap.width, srcBitmap.height);
-
-        // Get an ImageData from the canvas.
-        var imageData = ctx.getImageData(0, 0, srcBitmap.width, srcBitmap.height);
-
-        for (var i = 0; i < srcBitmap.height; ++i) {
-          for (var j = 0; j < srcBitmap.width; ++j) {
-            var pixelOffset = i * srcBitmap.width * dstData.channelCount + j * dstData.channelCount;
-            var dstImageDataValue_R = imageData.data[pixelOffset + 0];
-            var dstImageDataValue_G = imageData.data[pixelOffset + 1];
-            var dstImageDataValue_B = imageData.data[pixelOffset + 2];
-            var dstImageDataValue_A = imageData.data[pixelOffset + 3];
-
-            var logPrefix = "[" + sourceFromat + " -> " + destinationFormat + "] pixel(" + i + "," + j + ")";
-
-            var dstDataValue_R = dstData.getPixelValue(i, j, 0);
-            var dstDataValue_G = dstData.getPixelValue(i, j, 1);
-            var dstDataValue_B = dstData.getPixelValue(i, j, 2);
-            var dstDataValue_A = dstData.getPixelValue(i, j, 3);
-            ok(Math.abs(dstImageDataValue_R - dstDataValue_R) <= tolerance,
-               logPrefix + "channnel(R): dstImageDataValue:" + dstImageDataValue_R + " should equal to dstDataValue_R: " + dstDataValue_R);
-            ok(Math.abs(dstImageDataValue_G - dstDataValue_G) <= tolerance,
-               logPrefix + "channnel(G): dstImageDataValue:" + dstImageDataValue_G + " should equal to dstDataValue_G: " + dstDataValue_G);
-            ok(Math.abs(dstImageDataValue_B - dstDataValue_B) <= tolerance,
-               logPrefix + "channnel(B): dstImageDataValue:" + dstImageDataValue_B + " should equal to dstDataValue_B: " + dstDataValue_B);
-            ok(Math.abs(dstImageDataValue_A - dstDataValue_A) <= tolerance,
-               logPrefix + "channnel(A): dstImageDataValue:" + dstImageDataValue_A + " should equal to dstDataValue_A: " + dstDataValue_A);
-          }
-        }
-
-        resolve();
-      },
-      function(ev) {
-        failed(ev);
-        reject(ev);
-      }
-    );
-  });
-}
\ No newline at end of file
deleted file mode 100644
--- a/dom/canvas/test/imagebitmap_extensions_data.js
+++ /dev/null
@@ -1,1066 +0,0 @@
-class Image {
-  constructor(channelCount, format, ArrayType) {
-    this.channelCount = channelCount;
-    this.format = format;
-    this.ArrayType = ArrayType;
-    this.pixelLayout = [];
-    this.buffer = undefined;
-    this.data = undefined;
-  };
-};
-
-class TypedSimpleImage extends Image {
-  constructor(width, height, channelCount, format, ArrayType) {
-    super(channelCount, format, ArrayType);
-    this.width = width;
-    this.height = height;
-    this.stride = this.width * this.channelCount * this.ArrayType.BYTES_PER_ELEMENT;
-    this.bufferLength = this.height * this.stride;
-    this.buffer = new ArrayBuffer(this.bufferLength);
-    this.data = new this.ArrayType(this.buffer, 0, this.height * this.width * this.channelCount);
-
-    // initialize pixel layout
-    for (var c = 0; c < this.channelCount; ++c) {
-      this.pixelLayout.push({offset:c * this.ArrayType.BYTES_PER_ELEMENT,
-                             width:this.width,
-                             height:this.height,
-                             dataType:"uint8",
-                             stride:this.stride,
-                             skip:(this.channelCount - 1)});
-    }
-  };
-
-  getPixelValue(i, j, c) {
-    var dataChannelLayout = this.pixelLayout[c];
-    return this.data[i * this.width * this.channelCount + j * this.channelCount + c];
-  }
-};
-
-class Uint8SimpleImage extends TypedSimpleImage {
-  constructor(width, height, channelCount, format) {
-    super(width, height, channelCount, format, Uint8ClampedArray);
-  };
-};
-
-class Uint16SimpleImage extends TypedSimpleImage {
-  constructor(width, height, channelCount, format) {
-    super(width, height, channelCount, format, Uint16Array);
-  };
-};
-
-class FloatSimpleImage extends TypedSimpleImage {
-  constructor(width, height, channelCount, format) {
-    super(width, height, channelCount, format, Float32Array);
-  };
-};
-
-class DoubleSimpleImage extends TypedSimpleImage {
-  constructor(width, height, channelCount, format) {
-    super(width, height, channelCount, format, Float64Array);
-  };
-};
-
-class RGBA32Data extends Uint8SimpleImage {
-  constructor() {
-    super(3, 3, 4, "RGBA32");
-
-    var i = 0;
-    this.data[i + 0] = 0;   this.data[i + 1] = 0;   this.data[i + 2] = 0;   this.data[i + 3] = 255;
-    this.data[i + 4] = 255; this.data[i + 5] = 0;   this.data[i + 6] = 0;   this.data[i + 7] = 255;
-    this.data[i + 8] = 0;   this.data[i + 9] = 255; this.data[i + 10] = 0;  this.data[i + 11] = 255;
-
-    i += this.stride;
-    this.data[i + 0] = 0;   this.data[i + 1] = 0;   this.data[i + 2] = 255;  this.data[i + 3] = 255;
-    this.data[i + 4] = 255; this.data[i + 5] = 255; this.data[i + 6] = 0;    this.data[i + 7] = 255;
-    this.data[i + 8] = 0;   this.data[i + 9] = 255; this.data[i + 10] = 255; this.data[i + 11] = 255;
-
-    i += this.stride;
-    this.data[i + 0] = 255;  this.data[i + 1] = 0;   this.data[i + 2] = 255;  this.data[i + 3] = 255;
-    this.data[i + 4] = 255;  this.data[i + 5] = 255; this.data[i + 6] = 255;  this.data[i + 7] = 255;
-    this.data[i + 8] = 128;  this.data[i + 9] = 128; this.data[i + 10] = 128; this.data[i + 11] = 255;
-  };
-};
-
-class BGRA32Data extends Uint8SimpleImage {
-  constructor() {
-    super(3, 3, 4, "BGRA32");
-
-    var i = 0;
-    this.data[i + 2] = 0;   this.data[i + 1] = 0;   this.data[i + 0] = 0;   this.data[i + 3] = 255;
-    this.data[i + 6] = 255; this.data[i + 5] = 0;   this.data[i + 4] = 0;   this.data[i + 7] = 255;
-    this.data[i + 10] = 0;  this.data[i + 9] = 255; this.data[i + 8] = 0;   this.data[i + 11] = 255;
-
-    i += this.stride;
-    this.data[i + 2] = 0;   this.data[i + 1] = 0;   this.data[i + 0] = 255;  this.data[i + 3] = 255;
-    this.data[i + 6] = 255; this.data[i + 5] = 255; this.data[i + 4] = 0;    this.data[i + 7] = 255;
-    this.data[i + 10] = 0;  this.data[i + 9] = 255; this.data[i + 8] = 255;  this.data[i + 11] = 255;
-
-    i += this.stride;
-    this.data[i + 2] = 255;  this.data[i + 1] = 0;   this.data[i + 0] = 255; this.data[i + 3] = 255;
-    this.data[i + 6] = 255;  this.data[i + 5] = 255; this.data[i + 4] = 255; this.data[i + 7] = 255;
-    this.data[i + 10] = 128; this.data[i + 9] = 128; this.data[i + 8] = 128; this.data[i + 11] = 255;
-  };
-};
-
-class RGB24Data extends Uint8SimpleImage {
-  constructor() {
-    super(3, 3, 3, "RGB24");
-
-    var i = 0;
-    this.data[i + 0] = 0;   this.data[i + 1] = 0;   this.data[i + 2] = 0;
-    this.data[i + 3] = 255; this.data[i + 4] = 0;   this.data[i + 5] = 0;
-    this.data[i + 6] = 0;   this.data[i + 7] = 255; this.data[i + 8] = 0;
-
-    i += this.stride;
-    this.data[i + 0] = 0;   this.data[i + 1] = 0;   this.data[i + 2] = 255;
-    this.data[i + 3] = 255; this.data[i + 4] = 255; this.data[i + 5] = 0;
-    this.data[i + 6] = 0;   this.data[i + 7] = 255; this.data[i + 8] = 255;
-
-    i += this.stride;
-    this.data[i + 0] = 255;  this.data[i + 1] = 0;   this.data[i + 2] = 255;
-    this.data[i + 3] = 255;  this.data[i + 4] = 255; this.data[i + 5] = 255;
-    this.data[i + 6] = 128;  this.data[i + 7] = 128; this.data[i + 8] = 128;
-  };
-};
-
-class BGR24Data extends Uint8SimpleImage {
-  constructor() {
-    super(3, 3, 3, "BGR24");
-
-    var i = 0;
-    this.data[i + 2] = 0;   this.data[i + 1] = 0;   this.data[i + 0] = 0;
-    this.data[i + 5] = 255; this.data[i + 4] = 0;   this.data[i + 3] = 0;
-    this.data[i + 8] = 0;   this.data[i + 7] = 255; this.data[i + 6] = 0;
-
-    i += this.stride;
-    this.data[i + 2] = 0;   this.data[i + 1] = 0;   this.data[i + 0] = 255;
-    this.data[i + 5] = 255; this.data[i + 4] = 255; this.data[i + 3] = 0;
-    this.data[i + 8] = 0;   this.data[i + 7] = 255; this.data[i + 6] = 255;
-
-    i += this.stride;
-    this.data[i + 2] = 255; this.data[i + 1] = 0;   this.data[i + 0] = 255;
-    this.data[i + 5] = 255; this.data[i + 4] = 255; this.data[i + 3] = 255;
-    this.data[i + 8] = 128; this.data[i + 7] = 128; this.data[i + 6] = 128;
-  };
-};
-
-class Gray8Data extends Uint8SimpleImage {
-  constructor() {
-    super(3, 3, 1, "GRAY8");
-
-    var i = 0;
-    this.data[i + 0] = 0;   this.data[i + 1] = 76;   this.data[i + 2] = 149;
-
-    i += this.stride;
-    this.data[i + 0] = 29;   this.data[i + 1] = 225;   this.data[i + 2] = 178;
-
-    i += this.stride;
-    this.data[i + 0] = 105; this.data[i + 1] = 255;   this.data[i + 2] = 127;
-  };
-};
-
-class RGBA32DataFromYUV444PData extends Uint8SimpleImage {
-  constructor(redIndex, greenIndex, blueIndex, alphaIndex) {
-
-    // Get the exact format.
-    var channelCount_ = !!alphaIndex ? 4 : 3;
-    var format_;
-    if (redIndex == 0) {
-      if (channelCount_ == 3) {
-        format_ = "RGBA32";
-      } else  {
-        format_ = "RGB24";
-      }
-    } else if (redIndex == 2) {
-      if (channelCount_ == 3) {
-        format_ = "BGRA32";
-      } else  {
-        format_ = "BGR24";
-      }
-    } else {
-      return undefined;
-    }
-
-    // Call parent's consturctor.
-    super(3, 3, channelCount_, format_);
-
-    // Calculate parameters for setting data.
-    var rIndex = redIndex;        // 0 or 2
-    var gIndex = 1;
-    var bIndex = redIndex ^ 2;    // 0 or 2
-    var aIndex = alphaIndex || 0; // If alphaIndex == undefined --> aIndex = 0;
-    var shift0 = 0;
-    var shift1 = channelCount_;
-    var shift2 = channelCount_ * 2;
-
-    // Set the data.
-    var i = 0;
-    this.data[i + aIndex + shift0] = 255;   this.data[i + rIndex + shift0] = 0;   this.data[i + gIndex + shift0] = 0;   this.data[i + bIndex + shift0] = 0;
-    this.data[i + aIndex + shift1] = 255;   this.data[i + rIndex + shift1] = 254; this.data[i + gIndex + shift1] = 0;   this.data[i + bIndex + shift1] = 0;
-    this.data[i + aIndex + shift2] = 255;   this.data[i + rIndex + shift2] = 0;   this.data[i + gIndex + shift2] = 253; this.data[i + bIndex + shift2] = 1;
-
-    i += this.stride;
-    this.data[i + aIndex + shift0] = 255;   this.data[i + rIndex + shift0] = 0;   this.data[i + gIndex + shift0] = 0;   this.data[i + bIndex + shift0] = 251;
-    this.data[i + aIndex + shift1] = 255;   this.data[i + rIndex + shift1] = 253; this.data[i + gIndex + shift1] = 253; this.data[i + bIndex + shift1] = 2;
-    this.data[i + aIndex + shift2] = 255;   this.data[i + rIndex + shift2] = 0;   this.data[i + gIndex + shift2] = 253; this.data[i + bIndex + shift2] = 252;
-
-    i += this.stride;
-    this.data[i + aIndex + shift0] = 255;   this.data[i + rIndex + shift0] = 255; this.data[i + gIndex + shift0] = 0;   this.data[i + bIndex + shift0] = 252;
-    this.data[i + aIndex + shift1] = 255;   this.data[i + rIndex + shift1] = 253; this.data[i + gIndex + shift1] = 253; this.data[i + bIndex + shift1] = 253;
-    this.data[i + aIndex + shift2] = 255;   this.data[i + rIndex + shift2] = 127; this.data[i + gIndex + shift2] = 127; this.data[i + bIndex + shift2] = 127;
-  };
-};
-
-class RGBA32DataFromYUV422PData extends Uint8SimpleImage {
-  constructor(redIndex, greenIndex, blueIndex, alphaIndex) {
-
-    // Get the exact format.
-    var channelCount_ = !!alphaIndex ? 4 : 3;
-    var format_;
-    if (redIndex == 0) {
-      if (channelCount_ == 3) {
-        format_ = "RGBA32";
-      } else  {
-        format_ = "RGB24";
-      }
-    } else if (redIndex == 2) {
-      if (channelCount_ == 3) {
-        format_ = "BGRA32";
-      } else  {
-        format_ = "BGR24";
-      }
-    } else {
-      return undefined;
-    }
-
-    // Call parent's consturctor.
-    super(3, 3, channelCount_, format_);
-
-    // Calculate parameters for setting data.
-    var rIndex = redIndex;        // 0 or 2
-    var gIndex = 1;
-    var bIndex = redIndex ^ 2;    // 0 or 2
-    var aIndex = alphaIndex || 0; // If alphaIndex == undefined --> aIndex = 0;
-    var shift0 = 0;
-    var shift1 = channelCount_;
-    var shift2 = channelCount_ * 2;
-
-    // Set the data.
-    var i = 0;
-    this.data[i + aIndex + shift0] = 255;   this.data[i + rIndex + shift0] = 89;  this.data[i + gIndex + shift0] = 0;   this.data[i + bIndex + shift0] = 0;
-    this.data[i + aIndex + shift1] = 255;   this.data[i + rIndex + shift1] = 165; this.data[i + gIndex + shift1] = 38;  this.data[i + bIndex + shift1] = 38;
-    this.data[i + aIndex + shift2] = 255;   this.data[i + rIndex + shift2] = 0;   this.data[i + gIndex + shift2] = 253; this.data[i + bIndex + shift2] = 1;
-
-    i += this.stride;
-    this.data[i + aIndex + shift0] = 255;   this.data[i + rIndex + shift0] = 28;  this.data[i + gIndex + shift0] = 28;  this.data[i + bIndex + shift0] = 28;
-    this.data[i + aIndex + shift1] = 255;   this.data[i + rIndex + shift1] = 224; this.data[i + gIndex + shift1] = 224; this.data[i + bIndex + shift1] = 224;
-    this.data[i + aIndex + shift2] = 255;   this.data[i + rIndex + shift2] = 0;   this.data[i + gIndex + shift2] = 253; this.data[i + bIndex + shift2] = 252;
-
-    i += this.stride;
-    this.data[i + aIndex + shift0] = 255;   this.data[i + rIndex + shift0] = 180; this.data[i + gIndex + shift0] = 52;  this.data[i + bIndex + shift0] = 178;
-    this.data[i + aIndex + shift1] = 255;   this.data[i + rIndex + shift1] = 255; this.data[i + gIndex + shift1] = 200; this.data[i + bIndex + shift1] = 255;
-    this.data[i + aIndex + shift2] = 255;   this.data[i + rIndex + shift2] = 127; this.data[i + gIndex + shift2] = 127; this.data[i + bIndex + shift2] = 127;
-  };
-};
-
-class RGBA32DataFromYUV420PData extends Uint8SimpleImage {
-  constructor(redIndex, greenIndex, blueIndex, alphaIndex) {
-
-    // Get the exact format.
-    var channelCount_ = !!alphaIndex ? 4 : 3;
-    var format_;
-    if (redIndex == 0) {
-      if (channelCount_ == 3) {
-        format_ = "RGBA32";
-      } else  {
-        format_ = "RGB24";
-      }
-    } else if (redIndex == 2) {
-      if (channelCount_ == 3) {
-        format_ = "BGRA32";
-      } else  {
-        format_ = "BGR24";
-      }
-    } else {
-      return undefined;
-    }
-
-    // Call parent's consturctor.
-    super(3, 3, channelCount_, format_);
-
-    // Calculate parameters for setting data.
-    var rIndex = redIndex;        // 0 or 2
-    var gIndex = 1;
-    var bIndex = redIndex ^ 2;    // 0 or 2
-    var aIndex = alphaIndex || 0; // If alphaIndex == undefined --> aIndex = 0;
-    var shift0 = 0;
-    var shift1 = channelCount_;
-    var shift2 = channelCount_ * 2;
-
-    // Set the data.
-    var i = 0;
-    this.data[i + aIndex + shift0] = 255;   this.data[i + rIndex + shift0] = 44;  this.data[i + gIndex + shift0] = 0;   this.data[i + bIndex + shift0] = 0;
-    this.data[i + aIndex + shift1] = 255;   this.data[i + rIndex + shift1] = 120; this.data[i + gIndex + shift1] = 57;  this.data[i + bIndex + shift1] = 58;
-    this.data[i + aIndex + shift2] = 255;   this.data[i + rIndex + shift2] = 0;   this.data[i + gIndex + shift2] = 238; this.data[i + bIndex + shift2] = 112;
-
-    i += this.stride;
-    this.data[i + aIndex + shift0] = 255;   this.data[i + rIndex + shift0] = 73;  this.data[i + gIndex + shift0] = 9;   this.data[i + bIndex + shift0] = 11;
-    this.data[i + aIndex + shift1] = 255;   this.data[i + rIndex + shift1] = 255; this.data[i + gIndex + shift1] = 205; this.data[i + bIndex + shift1] = 206;
-    this.data[i + aIndex + shift2] = 255;   this.data[i + rIndex + shift2] = 12;  this.data[i + gIndex + shift2] = 255; this.data[i + bIndex + shift2] = 141;
-
-    i += this.stride;
-    this.data[i + aIndex + shift0] = 255;   this.data[i + rIndex + shift0] = 180; this.data[i + gIndex + shift0] = 52;  this.data[i + bIndex + shift0] = 178;
-    this.data[i + aIndex + shift1] = 255;   this.data[i + rIndex + shift1] = 255; this.data[i + gIndex + shift1] = 200; this.data[i + bIndex + shift1] = 255;
-    this.data[i + aIndex + shift2] = 255;   this.data[i + rIndex + shift2] = 127; this.data[i + gIndex + shift2] = 127; this.data[i + bIndex + shift2] = 127;
-  };
-};
-
-class Gray8DataFromYUVData extends Uint8SimpleImage {
-  constructor() {
-    super(3, 3, 1, "GRAY8");
-
-    var i = 0;
-    this.data[i + 0] = 16;  this.data[i + 1] = 82;   this.data[i + 2] = 144;
-
-    i += this.stride;
-    this.data[i + 0] = 41;  this.data[i + 1] = 210;  this.data[i + 2] = 169;
-
-    i += this.stride;
-    this.data[i + 0] = 107; this.data[i + 1] = 235;  this.data[i + 2] = 126;
-  };
-};
-
-class YUVImage extends Image {
-  constructor(yWidth, yHeight, uWidth, uHeight, vWidth, vHeight, format) {
-    super(3, format, Uint8ClampedArray);
-    this.yWidth = yWidth;
-    this.yHeight = yHeight;
-    this.yStride = this.yWidth * this.ArrayType.BYTES_PER_ELEMENT;
-    this.uWidth = uWidth;
-    this.uHeight = uHeight;
-    this.uStride = this.uWidth * this.ArrayType.BYTES_PER_ELEMENT;
-    this.vWidth = vWidth;
-    this.vHeight = vHeight;
-    this.vStride = this.vWidth * this.ArrayType.BYTES_PER_ELEMENT;
-    this.bufferLength = this.yHeight * this.yStride +
-                        this.uHeight * this.uStride +
-                        this.vHeight * this.vStride
-    this.buffer = new ArrayBuffer(this.bufferLength);
-    this.data = new this.ArrayType(this.buffer, 0, this.bufferLength);
-    this.yData = new this.ArrayType(this.buffer, 0, this.yHeight * this.yStride);
-    this.uData = new this.ArrayType(this.buffer,
-                                    this.yHeight * this.yStride,
-                                    this.uHeight * this.uStride);
-    this.vData = new this.ArrayType(this.buffer,
-                                    this.yHeight * this.yStride + this.uHeight * this.uStride,
-                                    this.vHeight * this.vStride);
-
-    // Initialize pixel layout.
-    // y channel.
-    this.pixelLayout.push({offset:0,
-                           width:this.yWidth,
-                           height:this.yHeight,
-                           dataType:"uint8",
-                           stride:this.yStride,
-                           skip:0});
-
-    // u channel.
-    this.pixelLayout.push({offset:(this.yHeight * this.yStride),
-                           width:this.uWidth,
-                           height:this.uHeight,
-                           dataType:"uint8",
-                           stride:this.uStride,
-                           skip:0});
-
-    // v channel.
-    this.pixelLayout.push({offset:(this.yHeight * this.yStride + this.uHeight * this.uStride),
-                           width:this.vWidth,
-                           height:this.vHeight,
-                           dataType:"uint8",
-                           stride:this.vStride,
-                           skip:0});
-  };
-
-  getPixelValue(i, j, c) {
-    var dataChannelLayout = this.pixelLayout[c];
-    return this.data[dataChannelLayout.offset + i * dataChannelLayout.stride + j * (dataChannelLayout.skip + 1)];
-  }
-};
-
-class YUV444PData extends YUVImage {
-  constructor() {
-    super(3, 3, 3, 3, 3, 3, "YUV444P");
-
-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
-
-    this.uData[0] = 128; this.uData[1] = 90;  this.uData[2] = 54;
-    this.uData[3] = 240; this.uData[4] = 16;  this.uData[5] = 166;
-    this.uData[6] = 202; this.uData[7] = 128; this.uData[8] = 128;
-
-    this.vData[0] = 128; this.vData[1] = 240; this.vData[2] = 34;
-    this.vData[3] = 110; this.vData[4] = 146; this.vData[5] = 16;
-    this.vData[6] = 222; this.vData[7] = 128; this.vData[8] = 128;
-  }
-};
-
-class YUV444PDataFromYUV422PData extends YUVImage {
-  constructor() {
-    super(3, 3, 3, 3, 3, 3, "YUV444P");
-
-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
-
-    this.uData[0] = 108; this.uData[1] = 81;  this.uData[2] = 53;
-    this.uData[3] = 126; this.uData[4] = 112; this.uData[5] = 98;
-    this.uData[6] = 144; this.uData[7] = 144; this.uData[8] = 144;
-
-    this.vData[0] = 182; this.vData[1] = 108; this.vData[2] = 33;
-    this.vData[3] = 166; this.vData[4] = 109; this.vData[5] = 51;
-    this.vData[6] = 150; this.vData[7] = 110; this.vData[8] = 70;
-  }
-};
-
-class YUV444PDataFromYUV420PData extends YUVImage {
-  constructor() {
-    super(3, 3, 3, 3, 3, 3, "YUV444P");
-
-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
-
-    this.uData[0] = 118; this.uData[1] = 113; this.uData[2] = 109;
-    this.uData[3] = 140; this.uData[4] = 128; this.uData[5] = 117;
-    this.uData[6] = 162; this.uData[7] = 144; this.uData[8] = 126;
-
-    this.vData[0] = 154; this.vData[1] = 90;  this.vData[2] = 24;
-    this.vData[3] = 163; this.vData[4] = 119; this.vData[5] = 75;
-    this.vData[6] = 172; this.vData[7] = 149; this.vData[8] = 126;
-  }
-};
-
-class YUV422PData extends YUVImage {
-  constructor() {
-    super(3, 3, 2, 3, 2, 3, "YUV422P");
-
-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
-
-    this.uData[0] = 109; this.uData[1] = 54;
-    this.uData[2] = 128; this.uData[3] = 166;
-    this.uData[4] = 165; this.uData[5] = 128;
-
-    this.vData[0] = 184; this.vData[1] = 34;
-    this.vData[2] = 128; this.vData[3] = 16;
-    this.vData[4] = 175; this.vData[5] = 128;
-  }
-};
-
-class YUV422PDataFromYUV444PData extends YUVImage {
-  constructor() {
-    super(3, 3, 2, 3, 2, 3, "YUV422P");
-
-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
-
-    this.uData[0] = 133; this.uData[1] = 78;
-    this.uData[2] = 164; this.uData[3] = 109;
-    this.uData[4] = 180; this.uData[5] = 125;
-
-    this.vData[0] = 145; this.vData[1] = 74;
-    this.vData[2] = 165; this.vData[3] = 95;
-    this.vData[4] = 175; this.vData[5] = 105;
-  }
-};
-
-class YUV422PDataFromYUV420PData extends YUVImage {
-  constructor() {
-    super(3, 3, 2, 3, 2, 3, "YUV422P");
-
-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
-
-    this.uData[0] = 119; this.uData[1] = 110;
-    this.uData[2] = 149; this.uData[3] = 121;
-    this.uData[4] = 164; this.uData[5] = 127;
-
-    this.vData[0] = 156; this.vData[1] = 25;
-    this.vData[2] = 168; this.vData[3] = 93;
-    this.vData[4] = 174; this.vData[5] = 127;
-  }
-};
-
-class YUV420PData extends YUVImage {
-  constructor() {
-    super(3, 3, 2, 2, 2, 2, "YUV420P");
-
-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
-
-    this.uData[0] = 119; this.uData[1] = 110;
-    this.uData[2] = 165; this.uData[3] = 128;
-
-    this.vData[0] = 156; this.vData[1] = 25;
-    this.vData[2] = 175; this.vData[3] = 128;
-  }
-};
-
-class YUV420PDataFromYUV444PData extends YUVImage {
-  constructor() {
-    super(3, 3, 2, 2, 2, 2, "YUV420P");
-
-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
-
-    this.uData[0] = 133; this.uData[1] = 78;
-    this.uData[2] = 181; this.uData[3] = 126;
-
-    this.vData[0] = 145; this.vData[1] = 74;
-    this.vData[2] = 176; this.vData[3] = 106;
-  }
-};
-
-class YUV420PDataFromYUV422PData extends YUVImage {
-  constructor() {
-    super(3, 3, 2, 2, 2, 2, "YUV420P");
-
-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
-
-    this.uData[0] = 109; this.uData[1] = 54;
-    this.uData[2] = 147; this.uData[3] = 147;
-
-    this.vData[0] = 184; this.vData[1] = 34;
-    this.vData[2] = 152; this.vData[3] = 72;
-  }
-};
-
-class NVImage extends Image {
-  constructor(yWidth, yHeight, uvWidth, uvHeight, format) {
-    super(3, format, Uint8ClampedArray);
-    this.yWidth = yWidth;
-    this.yHeight = yHeight;
-    this.yStride = this.yWidth * this.ArrayType.BYTES_PER_ELEMENT;
-    this.uvWidth = uvWidth;
-    this.uvHeight = uvHeight;
-    this.uvStride = this.uvWidth * 2 * this.ArrayType.BYTES_PER_ELEMENT;
-    this.bufferLength = this.yHeight * this.yStride + this.uvHeight * this.uvStride;
-    this.buffer = new ArrayBuffer(this.bufferLength);
-    this.data = new this.ArrayType(this.buffer, 0, this.bufferLength);
-    this.yData = new this.ArrayType(this.buffer, 0, this.yHeight * this.yStride);
-    this.uvData = new this.ArrayType(this.buffer,
-                                     this.yHeight * this.yStride,
-                                     this.uvHeight * this.uvStride);
-
-    // Initialize pixel layout.
-    // y channel.
-    this.pixelLayout.push({offset:0,
-                           width:this.yWidth,
-                           height:this.yHeight,
-                           dataType:"uint8",
-                           stride:this.yStride,
-                           skip:0});
-    // v channel.
-    this.pixelLayout.push({offset:(this.yHeight * this.yStride),
-                           width:this.uvWidth,
-                           height:this.uvHeight,
-                           dataType:"uint8",
-                           stride:this.uvStride,
-                           skip:1});
-
-    // u channel.
-    this.pixelLayout.push({offset:(this.yHeight * this.yStride + this.ArrayType.BYTES_PER_ELEMENT),
-                           width:this.uvWidth,
-                           height:this.uvHeight,
-                           dataType:"uint8",
-                           stride:this.uvStride,
-                           skip:1});
-  };
-
-  getPixelValue(i, j, c) {
-    var dataChannelLayout = this.pixelLayout[c];
-    return this.data[dataChannelLayout.offset + i * dataChannelLayout.stride + j * (dataChannelLayout.skip + 1)];
-  }
-};
-
-class NV12Data extends NVImage {
-  constructor() {
-    super(3, 3, 2, 2, "YUV420SP_NV12");
-
-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
-
-    // U
-    this.uvData[0] = 119;
-    this.uvData[2] = 110;
-    this.uvData[4] = 165;
-    this.uvData[6] = 128;
-
-    // V
-    this.uvData[1] = 156;
-    this.uvData[3] = 25;
-    this.uvData[5] = 175;
-    this.uvData[7] = 128;
-  };
-};
-
-class NV12DataFromYUV444PData extends NVImage {
-  constructor() {
-    super(3, 3, 2, 2, "YUV420SP_NV12");
-
-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
-
-    // U
-    this.uvData[0] = 133;
-    this.uvData[2] = 78;
-    this.uvData[4] = 181;
-    this.uvData[6] = 126;
-
-    // V
-    this.uvData[1] = 145;
-    this.uvData[3] = 74;
-    this.uvData[5] = 176;
-    this.uvData[7] = 106;
-  };
-};
-
-class NV12DataFromYUV422PData extends NVImage {
-  constructor() {
-    super(3, 3, 2, 2, "YUV420SP_NV12");
-
-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
-
-    // U
-    this.uvData[0] = 109;
-    this.uvData[2] = 54;
-    this.uvData[4] = 147;
-    this.uvData[6] = 147;
-
-    // V
-    this.uvData[1] = 184;
-    this.uvData[3] = 34;
-    this.uvData[5] = 152;
-    this.uvData[7] = 72;
-  };
-};
-
-class NV21Data extends NVImage {
-  constructor() {
-    super(3, 3, 2, 2, "YUV420SP_NV21");
-
-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
-
-    // U
-    this.uvData[1] = 119;
-    this.uvData[3] = 110;
-    this.uvData[5] = 165;
-    this.uvData[7] = 128;
-
-    // V
-    this.uvData[0] = 156;
-    this.uvData[2] = 25;
-    this.uvData[4] = 175;
-    this.uvData[6] = 128;
-  };
-};
-
-class NV21DataFromYUV444PData extends NVImage {
-  constructor() {
-    super(3, 3, 2, 2, "YUV420SP_NV12");
-
-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
-
-    // V
-    this.uvData[1] = 133;
-    this.uvData[3] = 78;
-    this.uvData[5] = 181;
-    this.uvData[7] = 126;
-
-    // U
-    this.uvData[0] = 145;
-    this.uvData[2] = 74;
-    this.uvData[4] = 176;
-    this.uvData[6] = 106;
-  };
-};
-
-class NV21DataFromYUV422PData extends NVImage {
-  constructor() {
-    super(3, 3, 2, 2, "YUV420SP_NV12");
-
-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
-
-    // V
-    this.uvData[1] = 109;
-    this.uvData[3] = 54;
-    this.uvData[5] = 147;
-    this.uvData[7] = 147;
-
-    // U
-    this.uvData[0] = 184;
-    this.uvData[2] = 34;
-    this.uvData[4] = 152;
-    this.uvData[6] = 72;
-  };
-};
-
-class HSVData extends FloatSimpleImage {
-  constructor() {
-    super(3, 3, 3, "HSV");
-
-    var i = 0;
-    this.data[i + 0] = 0.0;   this.data[i + 1] = 0.0; this.data[i + 2] = 0.0;
-    this.data[i + 3] = 0.0;   this.data[i + 4] = 1.0; this.data[i + 5] = 1.0;
-    this.data[i + 6] = 120.0; this.data[i + 7] = 1.0; this.data[i + 8] = 1.0;
-
-    i += this.width * this.channelCount;
-    this.data[i + 0] = 240.0; this.data[i + 1] = 1.0; this.data[i + 2] = 1.0;
-    this.data[i + 3] = 60.0;  this.data[i + 4] = 1.0; this.data[i + 5] = 1.0;
-    this.data[i + 6] = 180.0; this.data[i + 7] = 1.0; this.data[i + 8] = 1.0;
-
-    i += this.width * this.channelCount;
-    this.data[i + 0] = 300.0; this.data[i + 1] = 1.0; this.data[i + 2] = 1.0;
-    this.data[i + 3] = 0.0;   this.data[i + 4] = 0.0; this.data[i + 5] = 1.0;
-    this.data[i + 6] = 0.0;   this.data[i + 7] = 0.0; this.data[i + 8] = 0.50196081;
-  };
-};
-
-class HSVDataFromLabData extends FloatSimpleImage {
-  constructor() {
-    super(3, 3, 3, "HSV");
-
-    var i = 0;
-    this.data[i + 0] = 0.0;   this.data[i + 1] = 0.0; this.data[i + 2] = 0.0;
-    this.data[i + 3] = 0.0;   this.data[i + 4] = 1.0; this.data[i + 5] = 0.996078;
-    this.data[i + 6] = 120.0; this.data[i + 7] = 1.0; this.data[i + 8] = 1.0;
-
-    i += this.width * this.channelCount;
-    this.data[i + 0] = 240.0;       this.data[i + 1] = 1.0; this.data[i + 2] = 1.0;
-    this.data[i + 3] = 60.235294;   this.data[i + 4] = 1.0; this.data[i + 5] = 1.0;
-    this.data[i + 6] = 179.764706;  this.data[i + 7] = 1.0; this.data[i + 8] = 1.0;
-
-    i += this.width * this.channelCount;
-    this.data[i + 0] = 300.0;       this.data[i + 1] = 1.0;       this.data[i + 2] = 1.0;
-    this.data[i + 3] = 0.0;         this.data[i + 4] = 0.003922;  this.data[i + 5] = 1.0;
-    this.data[i + 6] = 59.999998;   this.data[i + 7] = 0.007813;  this.data[i + 8] = 0.501961;
-  };
-};
-
-class HSVDataFromYUV444PData extends FloatSimpleImage {
-  constructor() {
-    super(3, 3, 3, "HSV");
-
-    var i = 0;
-    this.data[i + 0] = 0.0;                 this.data[i + 1] = 0.0;                 this.data[i + 2] = 0.0;
-    this.data[i + 3] = 0.0;                 this.data[i + 4] = 1.0000000001003937;  this.data[i + 5] = 0.996078431372549;
-    this.data[i + 6] = 120.23715415017372;  this.data[i + 7] = 1.0000000001007905;  this.data[i + 8] = 0.9921568627450981;
-
-    i += this.width * this.channelCount;
-    this.data[i + 0] = 240.0;               this.data[i + 1] = 1.0000000001015936;  this.data[i + 2] = 0.984313725490196;
-    this.data[i + 3] = 59.99999999390438;   this.data[i + 4] = 0.9920948617608696;  this.data[i + 5] = 0.9921568627450981;
-    this.data[i + 6] = 179.76284584377885;  this.data[i + 7] = 1.0000000001007905;  this.data[i + 8] = 0.9921568627450981;
-
-    i += this.width * this.channelCount;
-    this.data[i + 0] = 300.7058823588706;   this.data[i + 1] = 1.0000000001;        this.data[i + 2] = 1.0;
-    this.data[i + 3] = 0.0;                 this.data[i + 4] = 0.0;                 this.data[i + 5] = 0.9921568627450981;
-    this.data[i + 6] = 0.0;                 this.data[i + 7] = 0.0;                 this.data[i + 8] = 0.4980392156862745;
-  };
-};
-
-class HSVDataFromYUV422PData extends FloatSimpleImage {
-  constructor() {
-    super(3, 3, 3, "HSV");
-
-    var i = 0;
-    this.data[i + 0] = 0.0;                 this.data[i + 1] = 1.0000000002865168; this.data[i + 2] = 0.34901960784313724;
-    this.data[i + 3] = 0.0;                 this.data[i + 4] = 0.7696969698515151; this.data[i + 5] = 0.6470588235294118;
-    this.data[i + 6] = 120.23715415017372;  this.data[i + 7] = 1.0000000001007905; this.data[i + 8] = 0.9921568627450981;
-
-    i += this.width * this.channelCount;
-    this.data[i + 0] = 0;                   this.data[i + 1] = 0.0;                 this.data[i + 2] = 0.10980392156862745;
-    this.data[i + 3] = 0;                   this.data[i + 4] = 0.0;                 this.data[i + 5] = 0.8784313725490196;
-    this.data[i + 6] = 179.76284584377885;  this.data[i + 7] = 1.0000000001007905;  this.data[i + 8] = 0.9921568627450981;
-
-    i += this.width * this.channelCount;
-    this.data[i + 0] = 300.93750001176636;  this.data[i + 1] = 0.7111111112527777;  this.data[i + 2] = 0.7058823529411765;
-    this.data[i + 3] = 300.0000000278182;   this.data[i + 4] = 0.21568627460980394; this.data[i + 5] = 1.0;
-    this.data[i + 6] = 0.0;                 this.data[i + 7] = 0.0;                 this.data[i + 8] = 0.4980392156862745;
-  };
-};
-
-class HSVDataFromYUV420PData extends FloatSimpleImage {
-  constructor() {
-    super(3, 3, 3, "HSV");
-
-    var i = 0;
-    this.data[i + 0] = 0.0;                 this.data[i + 1] = 1.0000000005795455;  this.data[i + 2] = 0.17254901960784313;
-    this.data[i + 3] = 359.04761904800455;  this.data[i + 4] = 0.5250000002125;     this.data[i + 5] = 0.47058823529411764;
-    this.data[i + 6] = 148.23529411462184;  this.data[i + 7] = 1.000000000107143;   this.data[i + 8] = 0.9333333333333333;
-
-    i += this.width * this.channelCount;
-    this.data[i + 0] = 358.1250000007471;   this.data[i + 1] = 0.8767123291164385;  this.data[i + 2] = 0.28627450980392155;
-    this.data[i + 3] = 358.800000000612;    this.data[i + 4] = 0.196078431472549;   this.data[i + 5] = 1.0;
-    this.data[i + 6] = 151.85185184850937;  this.data[i + 7] = 0.9529411765705882;  this.data[i + 8] = 1.0;
-
-    i += this.width * this.channelCount;
-    this.data[i + 0] = 300.93750001176636;  this.data[i + 1] = 0.7111111112527777;  this.data[i + 2] = 0.7058823529411765;
-    this.data[i + 3] = 300.0000000278182;   this.data[i + 4] = 0.21568627460980394; this.data[i + 5] = 1.0;
-    this.data[i + 6] = 0.0;                 this.data[i + 7] = 0.0;                 this.data[i + 8] = 0.4980392156862745;
-  };
-};
-
-class LabData extends FloatSimpleImage {
-  constructor() {
-    super(3, 3, 3, "Lab");
-
-    var i = 0;
-    this.data[i + 0] = 0.0;       this.data[i + 1] = 0.0;         this.data[i + 2] = 0.0;
-    this.data[i + 3] = 53.240585; this.data[i + 4] = 80.094185;   this.data[i + 5] = 67.201538;
-    this.data[i + 6] = 87.7351;   this.data[i + 7] = -86.181252;  this.data[i + 8] = 83.177483;
-
-    i += this.width * this.channelCount;
-    this.data[i + 0] = 32.29567;  this.data[i + 1] = 79.186989;   this.data[i + 2] = -107.86176;
-    this.data[i + 3] = 97.139511; this.data[i + 4] = -21.552414;  this.data[i + 5] = 94.475792;
-    this.data[i + 6] = 91.113297; this.data[i + 7] = -48.088551;  this.data[i + 8] = -14.130962;
-
-    i += this.width * this.channelCount;
-    this.data[i + 0] = 60.323502; this.data[i + 1] = 98.235161;   this.data[i + 2] = -60.825493;
-    this.data[i + 3] = 100.0;     this.data[i + 4] = 0.0;         this.data[i + 5] = 0.0;
-    this.data[i + 6] = 53.585014; this.data[i + 7] = 0.0;         this.data[i + 8] = 0.0;
-  };
-};
-
-class LabDataFromYUV444PData extends FloatSimpleImage {
-  constructor() {
-    super(3, 3, 3, "HSV");
-
-    var i = 0;
-    this.data[i + 0] = 0.0;                 this.data[i + 1] = 0.0;                 this.data[i + 2] = 0.0;
-    this.data[i + 3] = 53.034610465388056;  this.data[i + 4] = 79.85590203914461;   this.data[i + 5] = 67.0016253024788;
-    this.data[i + 6] = 87.11875689267448;   this.data[i + 7] = -85.65429374039535;  this.data[i + 8] = 82.60623202041464;
-
-    i += this.width * this.channelCount;
-    this.data[i + 0] = 31.720345672804157;  this.data[i + 1] = 78.24367895044873;   this.data[i + 2] = -106.5768337072531;
-    this.data[i + 3] = 96.46792120648958;   this.data[i + 4] = -21.409519847697347; this.data[i + 5] = 93.77548135780542;
-    this.data[i + 6] = 90.44660871821826;   this.data[i + 7] = -48.089026724461526; this.data[i + 8] = -13.571034820412686;
-
-    i += this.width * this.channelCount;
-    this.data[i + 0] = 60.151950936932494;  this.data[i + 1] = 97.82071254270292;   this.data[i + 2] = -59.43734830934828;
-    this.data[i + 3] = 99.30958687208283;   this.data[i + 4] = 0.0;                 this.data[i + 5] = 0.0;
-    this.data[i + 6] = 53.19277745493915;   this.data[i + 7] = 0.0;                 this.data[i + 8] = 0.0;
-  };
-};
-
-class LabDataFromYUV422PData extends FloatSimpleImage {
-  constructor() {
-    super(3, 3, 3, "HSV");
-
-    var i = 0;
-    this.data[i + 0] = 16.127781199491146; this.data[i + 1] = 37.16386506574049;  this.data[i + 2] = 25.043689417354877;
-    this.data[i + 3] = 36.981683077525915; this.data[i + 4] = 50.903511613481115; this.data[i + 5] = 32.31142038484883;
-    this.data[i + 6] = 87.11875689267448;  this.data[i + 7] = -85.65429374039535; this.data[i + 8] = 82.60623202041464;
-
-    i += this.width * this.channelCount;
-    this.data[i + 0] = 10.268184311230112; this.data[i + 1] = 0.0;                 this.data[i + 2] = 0.0;
-    this.data[i + 3] = 89.1772802290269;   this.data[i + 4] = 0.0;                 this.data[i + 5] = 0.0;
-    this.data[i + 6] = 90.44660871821826;  this.data[i + 7] = -48.089026724461526; this.data[i + 8] = -13.571034820412686;
-
-    i += this.width * this.channelCount;
-    this.data[i + 0] = 46.144074613608296; this.data[i + 1] = 65.16894552944552;  this.data[i + 2] = -40.267933584999625;
-    this.data[i + 3] = 86.8938834807636;   this.data[i + 4] = 28.462923575986455; this.data[i + 5] = -19.464966592414633;
-    this.data[i + 6] = 53.19277745493915;  this.data[i + 7] = 0.0;                this.data[i + 8] = 0.0;
-  };
-};
-
-class LabDataFromYUV420PData extends FloatSimpleImage {
-  constructor() {
-    super(3, 3, 3, "HSV");
-
-    var i = 0;
-    this.data[i + 0] = 4.838519820745088;  this.data[i + 1] = 21.141105340568455; this.data[i + 2] = 7.645700032099379;
-    this.data[i + 3] = 32.31563239702677;  this.data[i + 4] = 27.57546933915833;  this.data[i + 5] = 12.300896526188554;
-    this.data[i + 6] = 83.08065258991849;  this.data[i + 7] = -73.895752859582;   this.data[i + 8] = 47.405921341516176;
-
-    i += this.width * this.channelCount;
-    this.data[i + 0] = 13.450503010545155; this.data[i + 1] = 29.406984528513203;  this.data[i + 2] = 16.333350166067607;
-    this.data[i + 3] = 86.69267491397105;  this.data[i + 4] = 17.77388194061319;   this.data[i + 5] = 6.21670853560361;
-    this.data[i + 6] = 88.693447032887;    this.data[i + 7] = -74.34828426368617;  this.data[i + 8] = 40.64106565615555;
-
-    i += this.width * this.channelCount;
-    this.data[i + 0] = 46.144074613608296; this.data[i + 1] = 65.16894552944552;  this.data[i + 2] = -40.267933584999625;
-    this.data[i + 3] = 86.8938834807636;   this.data[i + 4] = 28.462923575986455; this.data[i + 5] = -19.464966592414633;
-    this.data[i + 6] = 53.19277745493915;  this.data[i + 7] = 0.0;                this.data[i + 8] = 0.0;
-  };
-};
-
-class DepthData extends Uint16SimpleImage {
-  constructor() {
-    super(3, 3, 1, "DEPTH");
-
-    var i = 0;
-    this.data[i + 0] = 2;   this.data[i + 1] = 4;   this.data[i + 2] = 8;
-
-    i += this.width * this.channelCount;
-    this.data[i + 0] = 16;  this.data[i + 1] = 32;  this.data[i + 2] = 64;
-
-    i += this.width * this.channelCount;
-    this.data[i + 0] = 128; this.data[i + 1] = 256; this.data[i + 2] = 512;
-  };
-};
-
-function getData(format, originalFormat) {
-  if (format == "RGBA32") {
-    if (originalFormat == "YUV444P") {
-      return new RGBA32DataFromYUV444PData(0, 1, 2, 3);
-    } else if (originalFormat == "YUV422P") {
-      return new RGBA32DataFromYUV422PData(0, 1, 2, 3);
-    } else if (originalFormat == "YUV420P" ||
-               originalFormat == "YUV420SP_NV12" ||
-               originalFormat == "YUV420SP_NV21") {
-      return new RGBA32DataFromYUV420PData(0, 1, 2, 3);
-    } else {
-      return new RGBA32Data();
-    }
-  } else if (format == "BGRA32") {
-    if (originalFormat == "YUV444P") {
-      return new RGBA32DataFromYUV444PData(2, 1, 0, 3);
-    } else if (originalFormat == "YUV422P") {
-      return new RGBA32DataFromYUV422PData(2, 1, 0, 3);
-    } else if (originalFormat == "YUV420P" ||
-               originalFormat == "YUV420SP_NV12" ||
-               originalFormat == "YUV420SP_NV21") {
-      return new RGBA32DataFromYUV420PData(2, 1, 0, 3);
-    } else {
-      return new BGRA32Data();
-    }
-  } else if (format == "RGB24") {
-    if (originalFormat == "YUV444P") {
-      return new RGBA32DataFromYUV444PData(0, 1, 2);
-    } else if (originalFormat == "YUV422P") {
-      return new RGBA32DataFromYUV422PData(0, 1, 2);
-    } else if (originalFormat == "YUV420P" ||
-               originalFormat == "YUV420SP_NV12" ||
-               originalFormat == "YUV420SP_NV21") {
-      return new RGBA32DataFromYUV420PData(0, 1, 2);
-    } else {
-      return new RGB24Data();
-    }
-  } else if (format == "BGR24") {
-    if (originalFormat == "YUV444P") {
-      return new RGBA32DataFromYUV444PData(2, 1, 0);
-    } else if (originalFormat == "YUV422P") {
-      return new RGBA32DataFromYUV422PData(2, 1, 0);
-    } else if (originalFormat == "YUV420P" ||
-               originalFormat == "YUV420SP_NV12" ||
-               originalFormat == "YUV420SP_NV21") {
-      return new RGBA32DataFromYUV420PData(2, 1, 0);
-    } else {
-      return new BGR24Data();
-    }
-  } else if (format == "GRAY8") {
-    if (originalFormat == "YUV444P" ||
-        originalFormat == "YUV422P" ||
-        originalFormat == "YUV420P" ||
-        originalFormat == "YUV420SP_NV12" ||
-        originalFormat == "YUV420SP_NV21") {
-      return  new Gray8DataFromYUVData();
-    } else {
-      return new Gray8Data();
-    }
-  } else if (format == "YUV444P") {
-    if (originalFormat == "YUV422P") {
-      return new YUV444PDataFromYUV422PData();
-    } else if (originalFormat == "YUV420P" ||
-               originalFormat == "YUV420SP_NV12" ||
-               originalFormat == "YUV420SP_NV21") {
-      return new YUV444PDataFromYUV420PData();
-    } else {
-      return new YUV444PData();
-    }
-  } else if (format == "YUV422P") {
-    if (originalFormat == "YUV444P") {
-      return new YUV422PDataFromYUV444PData();
-    } else if (originalFormat == "YUV420P" ||
-               originalFormat == "YUV420SP_NV12" ||
-               originalFormat == "YUV420SP_NV21") {
-      return new YUV422PDataFromYUV420PData();
-    } else {
-      return new YUV422PData();
-    }
-  } else if (format == "YUV420P") {
-    if (originalFormat == "YUV444P") {
-      return new YUV420PDataFromYUV444PData();
-    } else if (originalFormat == "YUV422P") {
-      return new YUV420PDataFromYUV422PData();
-    } else {
-      return new YUV420PData();
-    }
-  } else if (format == "YUV420SP_NV12") {
-    if (originalFormat == "YUV444P") {
-      return new NV12DataFromYUV444PData();
-    } else if (originalFormat == "YUV422P") {
-      return new NV12DataFromYUV422PData();
-    } else {
-      return new NV12Data();
-    }
-  } else if (format == "YUV420SP_NV21") {
-    if (originalFormat == "YUV444P") {
-      return new NV21DataFromYUV444PData();
-    } else if (originalFormat == "YUV422P") {
-      return new NV21DataFromYUV422PData();
-    } else {
-      return new NV21Data();
-    }
-  } else if (format == "HSV") {
-    if (originalFormat == "YUV444P") {
-      return new HSVDataFromYUV444PData();
-    } else if (originalFormat == "YUV422P") {
-      return new HSVDataFromYUV422PData();
-    } else if (originalFormat == "YUV420P" ||
-               originalFormat == "YUV420SP_NV12" ||
-               originalFormat == "YUV420SP_NV21") {
-      return new HSVDataFromYUV420PData();
-    } else if (originalFormat == "Lab") {
-      return new HSVDataFromLabData();
-    } else {
-      return new HSVData();
-    }
-  } else if (format == "Lab") {
-    if (originalFormat == "YUV444P") {
-      return new LabDataFromYUV444PData();
-    } else if (originalFormat == "YUV422P") {
-      return new LabDataFromYUV422PData();
-    } else if (originalFormat == "YUV420P" ||
-               originalFormat == "YUV420SP_NV12" ||
-               originalFormat == "YUV420SP_NV21") {
-      return new LabDataFromYUV420PData();
-    } else {
-      return new LabData();
-    }
-  } else if (format == "DEPTH") {
-    return new DepthData();
-  }
-}
-
-function getTestData(sourceFromat, destinationFormat) {
-  return [getData(sourceFromat), getData(destinationFormat, sourceFromat)];
-}
\ No newline at end of file
deleted file mode 100644
--- a/dom/canvas/test/imagebitmap_extensions_on_worker.js
+++ /dev/null
@@ -1,47 +0,0 @@
-importScripts("imagebitmap_extensions_data.js");
-importScripts("imagebitmap_extensions.js");
-
-var gGroundTruthImageData;
-var gImageData;
-var gImageBitmap;
-var gPNGBlob;
-var gJPEGBlob;
-
-onmessage = function(event) {
-  if (event.data.type == "setSources") {
-    gGroundTruthImageData = event.data.groundTruthImageData;
-    gImageData = event.data.imageData;
-    gImageBitmap = event.data.imageBitmap;
-    gPNGBlob = event.data.pngBlob;
-    gJPEGBlob = event.data.jpegBlob;
-
-    ok(!!gGroundTruthImageData, "Get gGroundTruthImageData!");
-    ok(!!gImageData, "Get gImageData!");
-    ok(!!gImageBitmap, "Get gImageBitmap!");
-    ok(!!gPNGBlob, "Get gPNGBlob!");
-    ok(!!gJPEGBlob, "Get gJPEGBlob!");
-
-    runTests();
-  }
-};
-
-function ok(expect, msg) {
-  postMessage({"type": "status", status: !!expect, msg: msg});
-}
-
-function runTests() {
-  testExceptions().
-  then(testColorConversions()).
-  then( function() { return Promise.all([testAccessing_randomTest("ImageData", gImageData, 0),
-                                         testAccessing_randomTest("ImageBitmap", gImageBitmap, 0),
-                                         testAccessing_randomTest("PNG", gPNGBlob, 0),
-                                         testAccessing_randomTest("JPEG", gJPEGBlob, 10) // JPEG loses information
-                                        ]); }).
-  then( function() { return Promise.all([testCreateFromArrayBffer_randomTest("ImageData", gImageData, 0),
-                                         testCreateFromArrayBffer_randomTest("ImageBitmap", gImageBitmap, 0),
-                                         testCreateFromArrayBffer_randomTest("PNG", gPNGBlob, 0),
-                                         testCreateFromArrayBffer_randomTest("JPEG", gJPEGBlob, 10) // JPEG loses information
-                                        ]); }).
-  then(function() { return testInvalidAccess([gImageData, gImageBitmap, gPNGBlob, gJPEGBlob]); } ).
-  then(function() {postMessage({"type": "finish"});}, function(ev) { failed(ev); postMessage({"type": "finish"}); });
-}
\ No newline at end of file
deleted file mode 100644
--- a/dom/canvas/test/imagebitmap_extensions_prepareSources.js
+++ /dev/null
@@ -1,94 +0,0 @@
-var gImage;
-var gVideo;
-var gCanvas;
-var gCtx;
-var gImageData;
-var gImageBitmap;
-var gPNGBlob;
-var gJPEGBlob;
-
-var gGroundTruthImageData;
-
-function prepareSources() {
-  gVideo = document.createElement("video");
-  gVideo.src = "http://example.com/tests/dom/canvas/test/crossorigin/video.sjs?name=tests/dom/canvas/test/320x240.ogv&type=video/ogg&cors=anonymous";
-  gVideo.crossOrigin = "anonymous";
-  gVideo.autoplay = "true"
-
-
-  gCanvas = document.createElement("canvas");
-  gCtx = gCanvas.getContext("2d");
-
-  var resolver;
-  var promise = new Promise(function(resolve, reject) {
-    resolver = resolve;
-  });
-
-  // Prepare video.
-  gVideo.onloadeddata = function() {
-    ok(gVideo, "[Prepare Sources] gVideo is ok.");
-
-    // Prepare canvas.
-    gCanvas.width = gVideo.videoWidth;
-    gCanvas.height = gVideo.videoHeight;
-    gCtx.drawImage(gVideo, 0, 0);
-    ok(gCanvas, "[Prepare Sources] gCanvas is ok.");
-    ok(gCtx, "[Prepare Sources] gCtx is ok.");
-
-    // Prepare gGroundTruthImageData.
-    gGroundTruthImageData = gCtx.getImageData(0, 0, gCanvas.width, gCanvas.height);
-    ok(gGroundTruthImageData, "[Prepare Sources] gGroundTruthImageData is ok.");
-
-    // Prepare image.
-    gImage = document.createElement("img");
-    gImage.src = gCanvas.toDataURL();
-    var resolverImage;
-    var promiseImage = new Promise(function(resolve, reject) {
-      resolverImage = resolve;
-    });
-    gImage.onload = function() {
-      resolverImage(true);
-    }
-
-    // Prepare ImageData.
-    gImageData = gCtx.getImageData(0, 0, gCanvas.width, gCanvas.height);
-    ok(gImageData, "[Prepare Sources] gImageData is ok.");
-
-    // Prepapre PNG Blob.
-    var promisePNGBlob = new Promise(function(resolve, reject) {
-      gCanvas.toBlob(function(blob) {
-        gPNGBlob = blob;
-        ok(gPNGBlob, "[Prepare Sources] gPNGBlob is ok.");
-        resolve(true);
-      });
-    });
-
-    // Prepare JPEG Blob.
-    var promiseJPEGBlob = new Promise(function(resolve, reject) {
-      gCanvas.toBlob(function(blob) {
-        gJPEGBlob = blob;
-        ok(gJPEGBlob, "[Prepare Sources] gJPEGBlob is ok.");
-        resolve(true);
-      }, "image/jpeg", 1.00);
-    });
-
-    // Prepare ImageBitmap.
-    var promiseImageBitmap = new Promise(function(resolve, reject) {
-      var p = createImageBitmap(gCanvas);
-      p.then(function(bitmap) {
-        gImageBitmap = bitmap;
-        ok(gImageBitmap, "[Prepare Sources] gImageBitmap is ok.");
-        resolve(true);
-      });
-    });
-
-    resolver(Promise.all([
-      promiseImage,
-      promisePNGBlob,
-      promiseJPEGBlob,
-      promiseImageBitmap
-    ]))
-  }
-
-  return promise;
-}
\ No newline at end of file
--- a/dom/canvas/test/mochitest.ini
+++ b/dom/canvas/test/mochitest.ini
@@ -21,21 +21,16 @@ support-files =
   image_rgrg-256x256.png
   image_rrgg-256x256.png
   image_transparent.png
   image_transparent50.png
   image_yellow.png
   image_yellow75.png
   imagebitmap_bug1239300.js
   imagebitmap_bug1239752.js
-  imagebitmap_extensions.html
-  imagebitmap_extensions.js
-  imagebitmap_extensions_data.js
-  imagebitmap_extensions_on_worker.js
-  imagebitmap_extensions_prepareSources.js
   imagebitmap_on_worker.js
   imagebitmap_structuredclone.js
   imagebitmap_structuredclone_iframe.html
   imagebitmap_structuredclone_utils.js
   offscreencanvas.js
   offscreencanvas_mask.svg
   offscreencanvas_neuter.js
   offscreencanvas_serviceworker_inner.html
@@ -233,25 +228,16 @@ support-files = file_drawWindow_source.h
 [test_imagebitmap.html]
 skip-if = android_version == '17' || android_version == '19' # bug 1336581
 tags = imagebitmap
 [test_imagebitmap_close.html]
 tags = imagebitmap
 [test_imagebitmap_cropping.html]
 skip-if = android_version >= '17' # bug 1336581
 tags = imagebitmap
-[test_imagebitmap_extensions.html]
-skip-if = android_version >= '17' # bug 1336581
-tags = imagebitmap
-[test_imagebitmap_extensions_on_worker.html]
-skip-if = android_version == '19' # bug 1338256
-tags = imagebitmap
-[test_imagebitmap_on_worker.html]
-skip-if = android_version >= '17' # bug 1336581
-tags = imagebitmap
 [test_imagebitmap_structuredclone.html]
 tags = imagebitmap
 [test_imagebitmap_structuredclone_iframe.html]
 tags = imagebitmap
 [test_imagebitmap_structuredclone_window.html]
 tags = imagebitmap
 [test_imagebitmap_transfer.html]
 tags = imagebitmap
@@ -306,8 +292,9 @@ skip-if = 1
 [test_offscreencanvas_sizechange.html]
 subsuite = gpu
 tags = offscreencanvas
 skip-if = 1
 [test_offscreencanvas_subworker.html]
 subsuite = gpu
 tags = offscreencanvas
 skip-if = 1
+[test_invalid_mime_type_blob.html]
deleted file mode 100644
--- a/dom/canvas/test/test_imagebitmap_extensions.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE HTML>
-<heand>
-  <title>Test ImageBitmap Extensions (Bug 1141979)</title>
-  <meta charset="utf-8">
-  <script src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" href="/tests/SimpleTest/test.css">
-</head>
-<body>
-  <div id="content"><div>
-  <script type="text/javascript">
-    SimpleTest.waitForExplicitFinish();
-
-    // The createImageBitmap() method is part of Window whose
-    // prototype was created before the preference is set. So I create another
-    // iframe with the right preference setting so that the
-    // createImageBitmap() will be visible.
-    SpecialPowers.pushPrefEnv({'set': [
-      ['canvas.imagebitmap_extensions.enabled', true],
-      ['gfx.ycbcr.accurate-conversion', true]
-    ]}, function() {
-      var div = document.getElementById("content");
-      ok(div, "Parent exists");
-
-      var ifr = document.createElement("iframe");
-      ifr.setAttribute('src', "imagebitmap_extensions.html");
-      div.appendChild(ifr);
-    });
-
-    window.onmessage = function(event) {
-      if (event.data.type == "status") {
-        ok(event.data.status, event.data.msg);
-      } else if (event.data.type == "finish") {
-        SimpleTest.finish();
-      }
-    }
-  </script>
-</body>
deleted file mode 100644
--- a/dom/canvas/test/test_imagebitmap_extensions_on_worker.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<!DOCTYPE HTML>
-<heand>
-  <title>Test ImageBitmap Extensions On Worker (Bug 1141979)</title>
-  <meta charset="utf-8">
-  <script src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" href="/tests/SimpleTest/test.css">
-</head>
-<body>
-  <div id="content"><div>
-  <script src="imagebitmap_extensions_prepareSources.js"></script>
-  <script type="text/javascript">
-
-    var worker;
-
-    SimpleTest.waitForExplicitFinish();
-    SpecialPowers.pushPrefEnv({'set': [
-      ['canvas.imagebitmap_extensions.enabled', true]
-    ]}, function() {
-          worker = new Worker("imagebitmap_extensions_on_worker.js");
-          worker.onmessage = function(event) {
-            if (event.data.type == "status") {
-              ok(event.data.status, event.data.msg);
-            } else if (event.data.type == "finish") {
-              SimpleTest.finish();
-            }
-          };
-
-          ok(!!worker, "Worker created successfully.");
-          prepareSources().then(function() {
-            worker.postMessage({"type": "setSources",
-                                "groundTruthImageData": gGroundTruthImageData,
-                                "imageData": gImageData,
-                                "imageBitmap": gImageBitmap,
-                                "pngBlob": gPNGBlob,
-                                "jpegBlob": gJPEGBlob});
-          });
-    });
-  </script>
-</body>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/test_invalid_mime_type_blob.html
@@ -0,0 +1,85 @@
+<!DOCTYPE HTML>
+<title>createImageBitmap from Blob with invalid type</title>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" href="/tests/SimpleTest/test.css">
+<body>
+<script>
+
+function syncBlob() {
+  info("Let's create a small memory blob...");
+
+  // A 1x1 PNG image.
+  // Source: https://commons.wikimedia.org/wiki/File:1x1.png (Public Domain)
+  const IMAGE = atob("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAA" +
+                     "ACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=");
+
+  let bytes = new Array(IMAGE.length);
+  for (let i = 0; i < IMAGE.length; i++) {
+    bytes[i] = IMAGE.charCodeAt(i);
+  }
+
+  let blob = new Blob([new Uint8Array(bytes)], { type: "text/html"});
+  window.createImageBitmap(blob)
+  .then(imageBitmap => {
+    ok(true, "Image created!");
+    is(imageBitmap.width, 1, "Image is 1x1");
+    is(imageBitmap.height, 1, "Image is 1x1");
+  })
+  .then(next);
+}
+
+function asyncBlob() {
+  info("Let's create a big memory blob...");
+
+  // A 1x1 PNG image.
+  // Source: https://commons.wikimedia.org/wiki/File:1x1.png (Public Domain)
+  const IMAGE = atob("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAA" +
+                     "ACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=");
+
+  let bytes = new Array(IMAGE.length);
+  for (let i = 0; i < IMAGE.length; i++) {
+    bytes[i] = IMAGE.charCodeAt(i);
+  }
+
+  let array = [];
+  for (let i = 0; i < 20000; ++i) {
+    array.push(new Uint8Array(bytes));
+  }
+
+  let blob = new Blob(array, { type: "text/html"});
+  ok(blob.size > 1000000, "More than 1mb");
+
+  let bc = new BroadcastChannel('a');
+  bc.onmessage = e => {
+    window.createImageBitmap(e.data)
+    .then(imageBitmap => {
+      ok(true, "Image created!");
+      is(imageBitmap.width, 1, "Image is 1x1");
+      is(imageBitmap.height, 1, "Image is 1x1");
+    })
+    .then(next);
+  }
+
+  new BroadcastChannel('a').postMessage(blob);
+}
+
+let tests = [
+ syncBlob,
+ asyncBlob,
+];
+
+function next() {
+  if (tests.length == 0) {
+    SimpleTest.finish();
+    return;
+  }
+
+  let test = tests.shift();
+  test();
+}
+
+SimpleTest.waitForExplicitFinish();
+next();
+</script>
+</body>
+</html>
--- a/dom/chrome-webidl/BrowsingContext.webidl
+++ b/dom/chrome-webidl/BrowsingContext.webidl
@@ -1,16 +1,16 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 interface nsIDocShell;
 
-[Exposed=(Window, System), ChromeOnly]
+[Exposed=Window, ChromeOnly]
 interface BrowsingContext {
   readonly attribute BrowsingContext? parent;
 
   sequence<BrowsingContext> getChildren();
 
   readonly attribute nsIDocShell? docShell;
 
   readonly attribute unsigned long long id;
--- a/dom/chrome-webidl/ChannelWrapper.webidl
+++ b/dom/chrome-webidl/ChannelWrapper.webidl
@@ -36,17 +36,17 @@ enum MozContentPolicyType {
   "speculative",
   "other"
 };
 
 /**
  * A thin wrapper around nsIChannel and nsIHttpChannel that allows JS
  * callers to access them without XPConnect overhead.
  */
-[ChromeOnly, Exposed=System]
+[ChromeOnly, Exposed=Window]
 interface ChannelWrapper : EventTarget {
   /**
    * Returns the wrapper instance for the given channel. The same wrapper is
    * always returned for a given channel.
    */
   static ChannelWrapper get(MozChannel channel);
 
   /**
--- a/dom/chrome-webidl/ChromeUtils.webidl
+++ b/dom/chrome-webidl/ChromeUtils.webidl
@@ -9,28 +9,28 @@
  *
  * For JS callers, this behaves like a normal QueryInterface function. When
  * called with a supported interface, it returns its `this` object. When
  * called with an unsupported interface, it throws NS_ERROR_NO_INTERFACE.
  *
  * C++ callers use a fast path, and never call the JSAPI or WebIDL methods of
  * this object.
  */
-[ChromeOnly, Exposed=(Window,System)]
+[ChromeOnly, Exposed=Window]
 interface MozQueryInterface {
   [Throws]
   legacycaller any (IID aIID);
 };
 
 /**
  * A collection of static utility methods that are only exposed to system code.
  * This is exposed in all the system globals where we can expose stuff by
  * default, so should only include methods that are **thread-safe**.
  */
-[ChromeOnly, Exposed=(Window,System,Worker)]
+[ChromeOnly, Exposed=(Window,Worker)]
 namespace ChromeUtils {
   /**
    * Serialize a snapshot of the heap graph, as seen by |JS::ubi::Node| and
    * restricted by |boundaries|, and write it to the provided file path.
    *
    * @param boundaries        The portion of the heap graph to write.
    *
    * @returns                 The path to the file the heap snapshot was written
@@ -143,17 +143,17 @@ namespace ChromeUtils {
    * IF YOU ADD NEW METHODS HERE, MAKE SURE THEY ARE THREAD-SAFE.
    */
 };
 
 /**
  * Additional ChromeUtils methods that are _not_ thread-safe, and hence not
  * exposed in workers.
  */
-[Exposed=(Window,System)]
+[Exposed=Window]
 partial namespace ChromeUtils {
   /**
    * A helper that converts OriginAttributesDictionary to a opaque suffix string.
    *
    * @param originAttrs       The originAttributes from the caller.
    */
   ByteString
   originAttributesToSuffix(optional OriginAttributesDictionary originAttrs);
--- a/dom/chrome-webidl/DominatorTree.webidl
+++ b/dom/chrome-webidl/DominatorTree.webidl
@@ -33,17 +33,17 @@ typedef unsigned long long NodeSize;
  *     the original node wasn't (directly or indirectly) referencing them. In
  *     other words, the retained size is the shallow size of a node plus the
  *     shallow sizes of every other node it dominates. For example, the root
  *     node in a binary tree might have a small shallow size that does not take
  *     up much space itself, but it dominates the rest of the binary tree and
  *     its retained size is therefore significant (assuming no external
  *     references into the tree).
  */
-[ChromeOnly, Exposed=(Window,System,Worker)]
+[ChromeOnly, Exposed=(Window,Worker)]
 interface DominatorTree {
   /**
    * The `NodeId` for the root of the dominator tree. This is a "meta-root" in
    * that it has an edge to each GC root in the heap snapshot this dominator
    * tree was created from.
    */
   readonly attribute NodeId root;
 
--- a/dom/chrome-webidl/HeapSnapshot.webidl
+++ b/dom/chrome-webidl/HeapSnapshot.webidl
@@ -2,17 +2,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/.
  */
 
 /**
  * A HeapSnapshot represents a snapshot of the heap graph
  */
-[ChromeOnly, Exposed=(Window,System,Worker)]
+[ChromeOnly, Exposed=(Window,Worker)]
 interface HeapSnapshot {
   /**
    * A time stamp of when the heap snapshot was taken, if available. Units are
    * microseconds since midnight (00:00:00) 1 January 1970 UTC.
    */
   readonly attribute unsigned long long? creationTime;
 
   /**
--- a/dom/chrome-webidl/MatchGlob.webidl
+++ b/dom/chrome-webidl/MatchGlob.webidl
@@ -4,17 +4,17 @@
 
 /**
  * Represents a simple glob pattern matcher. Any occurrence of "*" in the glob
  * pattern matches any literal string of characters in the string being
  * compared. Additionally, if created with `allowQuestion = true`, any
  * occurrence of "?" in the glob matches any single literal character.
  */
 [Constructor(DOMString glob, optional boolean allowQuestion = true),
- ChromeOnly, Exposed=(Window,System)]
+ ChromeOnly, Exposed=Window]
 interface MatchGlob {
   /**
    * Returns true if the string matches the glob.
    */
   boolean matches(DOMString string);
 
   /**
    * The glob string this MatchGlob represents.
--- a/dom/chrome-webidl/MatchPattern.webidl
+++ b/dom/chrome-webidl/MatchPattern.webidl
@@ -25,17 +25,17 @@ interface URI;
  *      or a subdomain pattern, with "*." followed by a domain name, to match
  *      that domain name or any subdomain thereof.
  *    - <path>
  *      A glob pattern for paths to match. A "*" may appear anywhere within
  *      the path, and will match any string of characters. If no "*" appears,
  *      the URL path must exactly match the pattern path.
  */
 [Constructor(DOMString pattern, optional MatchPatternOptions options),
- ChromeOnly, Exposed=(Window,System)]
+ ChromeOnly, Exposed=Window]
 interface MatchPattern {
   /**
    * Returns true if the given URI matches the pattern.
    *
    * If explicit is true, only explicit domain matches, without wildcards, are
    * considered.
    */
   [Throws]
@@ -69,17 +69,17 @@ interface MatchPattern {
   readonly attribute DOMString pattern;
 };
 
 /**
  * A set of MatchPattern objects, which implements the MatchPattern API and
  * matches when any of its sub-patterns matches.
  */
 [Constructor(sequence<(DOMString or MatchPattern)> patterns, optional MatchPatternOptions options),
- ChromeOnly, Exposed=(Window,System)]
+ ChromeOnly, Exposed=Window]
 interface MatchPatternSet {
   /**
    * Returns true if the given URI matches any sub-pattern.
    *
    * If explicit is true, only explicit domain matches, without wildcards, are
    * considered.
    */
   [Throws]
--- a/dom/chrome-webidl/MozDocumentObserver.webidl
+++ b/dom/chrome-webidl/MozDocumentObserver.webidl
@@ -4,14 +4,14 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
 callback interface MozDocumentCallback {
   void onNewDocument(MozDocumentMatcher matcher, WindowProxy window);
   void onPreloadDocument(MozDocumentMatcher matcher, LoadInfo loadInfo);
 };
 
-[ChromeOnly, Constructor(MozDocumentCallback callbacks), Exposed=System]
+[ChromeOnly, Constructor(MozDocumentCallback callbacks), Exposed=Window]
 interface MozDocumentObserver {
   [Throws]
   void observe(sequence<MozDocumentMatcher> matchers);
   void disconnect();
 };
--- a/dom/chrome-webidl/PlacesEvent.webidl
+++ b/dom/chrome-webidl/PlacesEvent.webidl
@@ -7,22 +7,22 @@ enum PlacesEventType {
   "page-visited",
   /**
    * data: PlacesBookmarkAddition. Fired whenever a bookmark
    * (or a bookmark folder/separator) is created.
    */
   "bookmark-added",
 };
 
-[ChromeOnly, Exposed=(Window,System)]
+[ChromeOnly, Exposed=Window]
 interface PlacesEvent {
   readonly attribute PlacesEventType type;
 };
 
-[ChromeOnly, Exposed=(Window,System)]
+[ChromeOnly, Exposed=Window]
 interface PlacesVisit : PlacesEvent {
   /**
    * URL of the visit.
    */
   readonly attribute DOMString url;
 
   /**
    * Id of the visit.
@@ -71,17 +71,17 @@ interface PlacesVisit : PlacesEvent {
    * and might be null if it is not known.
    */
   readonly attribute DOMString? lastKnownTitle;
 };
 
 /**
  * Base class for properties that are common to all bookmark events.
  */
-[ChromeOnly, Exposed=(Window,System)]
+[ChromeOnly, Exposed=Window]
 interface PlacesBookmark : PlacesEvent {
   /**
    * The id of the item.
    */
   readonly attribute long long id;
 
   /**
    * The id of the folder to which the item belongs.
@@ -130,17 +130,17 @@ dictionary PlacesBookmarkAdditionInit {
   required ByteString parentGuid;
   required unsigned short source;
   required long index;
   required DOMString title;
   required unsigned long long dateAdded;
   required boolean isTagging;
 };
 
-[ChromeOnly, Exposed=(Window,System), Constructor(PlacesBookmarkAdditionInit initDict)]
+[ChromeOnly, Exposed=Window, Constructor(PlacesBookmarkAdditionInit initDict)]
 interface PlacesBookmarkAddition : PlacesBookmark {
   /**
    * The item's index in the folder.
    */
   readonly attribute long index;
 
   /**
    * The title of the added item.
--- a/dom/chrome-webidl/PlacesObservers.webidl
+++ b/dom/chrome-webidl/PlacesObservers.webidl
@@ -1,23 +1,23 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
 callback PlacesEventCallback = void (sequence<PlacesEvent> events);
 
-[ChromeOnly, Exposed=(Window,System),
+[ChromeOnly, Exposed=Window,
  Constructor(PlacesEventCallback callback)]
 interface PlacesWeakCallbackWrapper {
 };
 
 // Global singleton which should handle all events for places.
-[ChromeOnly, Exposed=(Window,System)]
+[ChromeOnly, Exposed=Window]
 namespace PlacesObservers {
   [Throws]
   void addListener(sequence<PlacesEventType> eventTypes,
                    PlacesEventCallback listener);
   [Throws]
   void addListener(sequence<PlacesEventType> eventTypes,
                    PlacesWeakCallbackWrapper listener);
   [Throws]
--- a/dom/chrome-webidl/PrecompiledScript.webidl
+++ b/dom/chrome-webidl/PrecompiledScript.webidl
@@ -3,17 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
 /**
  * Represents a pre-compiled JS script, which can be repeatedly executed in
  * different globals without being re-parsed.
  */
-[ChromeOnly, Exposed=(Window,System)]
+[ChromeOnly, Exposed=Window]
 interface PrecompiledScript {
   /**
    * Executes the script in the context of, and with the security principal
    * of, the given object's global. If compiled with a return value, returns
    * the value of the script's last expression. Otherwise returns undefined.
    */
   [Throws]
   any executeInGlobal(object global);
--- a/dom/chrome-webidl/PrioEncoder.webidl
+++ b/dom/chrome-webidl/PrioEncoder.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-[ChromeOnly, Exposed=(Window,System)]
+[ChromeOnly, Exposed=Window]
 namespace PrioEncoder {
   [Throws, NewObject]
   PrioEncodedData encode(ByteString batchID, PrioParams params);
 };
 
 dictionary PrioParams {
   required boolean browserIsUserDefault;
   required boolean newTabPageEnabled;
--- a/dom/chrome-webidl/PromiseDebugging.webidl
+++ b/dom/chrome-webidl/PromiseDebugging.webidl
@@ -45,17 +45,17 @@ callback interface UncaughtRejectionObse
    * chain anymore.
    *
    * @param p A Promise that was previously left in uncaught state is
    * now caught, i.e. it is not the last in its chain anymore.
    */
   void onConsumed(object p);
 };
 
-[ChromeOnly, Exposed=(Window,System)]
+[ChromeOnly, Exposed=Window]
 interface PromiseDebugging {
   /**
    * The various functions on this interface all expect to take promises but
    * don't want the WebIDL behavior of assimilating random passed-in objects
    * into promises.  They also want to treat Promise subclass instances as
    * promises instead of wrapping them in a vanilla Promise, which is what the
    * IDL spec says to do.  So we list all our arguments as "object" instead of
    * "Promise" and check for them being a Promise internally.
--- a/dom/chrome-webidl/StructuredCloneHolder.webidl
+++ b/dom/chrome-webidl/StructuredCloneHolder.webidl
@@ -3,17 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
 /**
  * A holder for structured-clonable data which can itself be cloned with
  * little overhead, and deserialized into an arbitrary global.
  */
-[ChromeOnly, Exposed=(Window,System,Worker),
+[ChromeOnly, Exposed=(Window,Worker),
  /**
   * Serializes the given value to an opaque structured clone blob, and
   * returns the result.
   *
   * The serialization happens in the compartment of the given global or, if no
   * global is provided, the compartment of the data value.
   */
  Constructor(any data, optional object? global = null)]
--- a/dom/chrome-webidl/WebExtensionContentScript.webidl
+++ b/dom/chrome-webidl/WebExtensionContentScript.webidl
@@ -4,17 +4,17 @@
 
 interface LoadInfo;
 interface URI;
 interface WindowProxy;
 
 typedef (MatchPatternSet or sequence<DOMString>) MatchPatternSetOrStringSequence;
 typedef (MatchGlob or DOMString) MatchGlobOrString;
 
-[Constructor(MozDocumentMatcherInit options), ChromeOnly, Exposed=System]
+[Constructor(MozDocumentMatcherInit options), ChromeOnly, Exposed=Window]
 interface MozDocumentMatcher {
   /**
    * Returns true if the script's match and exclude patterns match the given
    * URI, without reference to attributes such as `allFrames`.
    */
   boolean matchesURI(URI uri);
 
   /**
@@ -127,17 +127,17 @@ enum ContentScriptRunAt {
   /**
    * The first point after the page and all of its resources has fully loaded
    * when the event loop is idle, and can run scripts without delaying a paint
    * event.
    */
   "document_idle",
 };
 
-[Constructor(WebExtensionPolicy extension, WebExtensionContentScriptInit options), ChromeOnly, Exposed=System]
+[Constructor(WebExtensionPolicy extension, WebExtensionContentScriptInit options), ChromeOnly, Exposed=Window]
 interface WebExtensionContentScript : MozDocumentMatcher {
   /**
    * The earliest point in the load cycle at which this script should run. For
    * static content scripts, in extensions which were present at browser
    * startup, the browser makes every effort to make sure that the script runs
    * no later than this point in the load cycle. For dynamic content scripts,
    * and scripts from extensions installed during this session, the scripts
    * may run at a later point.
--- a/dom/chrome-webidl/WebExtensionPolicy.webidl
+++ b/dom/chrome-webidl/WebExtensionPolicy.webidl
@@ -6,17 +6,17 @@ interface URI;
 interface WindowProxy;
 
 callback WebExtensionLocalizeCallback = DOMString (DOMString unlocalizedText);
 
 /**
  * Defines the platform-level policies for a WebExtension, including its
  * permissions and the characteristics of its moz-extension: URLs.
  */
-[Constructor(WebExtensionInit options), ChromeOnly, Exposed=System]
+[Constructor(WebExtensionInit options), ChromeOnly, Exposed=Window]
 interface WebExtensionPolicy {
   /**
    * The add-on's internal ID, as specified in its manifest.json file or its
    * XPI signature.
    */
   [Constant, StoreInSlot]
   readonly attribute DOMString id;
 
--- a/dom/webidl/AbortController.webidl
+++ b/dom/webidl/AbortController.webidl
@@ -2,14 +2,14 @@
 /* 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/.
  *
  * The origin of this IDL file is
  * https://dom.spec.whatwg.org/#abortcontroller
  */
 
-[Constructor(), Exposed=(Window,Worker,System)]
+[Constructor(), Exposed=(Window,Worker)]
 interface AbortController {
   readonly attribute AbortSignal signal;
 
   void abort();
 };
--- a/dom/webidl/AbortSignal.webidl
+++ b/dom/webidl/AbortSignal.webidl
@@ -2,14 +2,14 @@
 /* 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/.
  *
  * The origin of this IDL file is
  * https://dom.spec.whatwg.org/#abortsignal
  */
 
-[Exposed=(Window,Worker,System)]
+[Exposed=(Window,Worker)]
 interface AbortSignal : EventTarget {
   readonly attribute boolean aborted;
 
   attribute EventHandler onabort;
 };
--- a/dom/webidl/AbstractWorker.webidl
+++ b/dom/webidl/AbstractWorker.webidl
@@ -1,10 +1,10 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-[NoInterfaceObject, Exposed=(Window,Worker,System)]
+[NoInterfaceObject, Exposed=(Window,Worker)]
 interface AbstractWorker {
     attribute EventHandler onerror;
 };
--- a/dom/webidl/AddonManager.webidl
+++ b/dom/webidl/AddonManager.webidl
@@ -77,13 +77,13 @@ interface AddonManager : EventTarget {
    * @return A promise that resolves to an instance of AddonInstall.
    */
   Promise<AddonInstall> createInstall(optional addonInstallOptions options);
 
   // Indicator to content whether permissions prompts are enabled
   readonly attribute boolean permissionPromptsEnabled;
 };
 
-[ChromeOnly,Exposed=System,HeaderFile="mozilla/AddonManagerWebAPI.h"]
+[ChromeOnly,Exposed=Window,HeaderFile="mozilla/AddonManagerWebAPI.h"]
 interface AddonManagerPermissions {
   static boolean isHostPermitted(DOMString host);
 };
 
--- a/dom/webidl/Console.webidl
+++ b/dom/webidl/Console.webidl
@@ -3,17 +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/.
  *
  * For more information on this interface, please see
  * https://console.spec.whatwg.org/#console-namespace
  */
 
-[Exposed=(Window,Worker,WorkerDebugger,Worklet,System),
+[Exposed=(Window,Worker,WorkerDebugger,Worklet),
  ClassString="Console",
  ProtoObjectHack]
 namespace console {
 
   // NOTE: if you touch this namespace, remember to update the ConsoleInstance
   // interface as well!
 
   // Logging
@@ -141,17 +141,17 @@ dictionary ConsoleCounter {
 };
 
 dictionary ConsoleCounterError {
   DOMString label = "";
   DOMString error = "";
 };
 
 [ChromeOnly,
- Exposed=(Window,Worker,WorkerDebugger,Worklet,System)]
+ Exposed=(Window,Worker,WorkerDebugger,Worklet)]
 // This is basically a copy of the console namespace.
 interface ConsoleInstance {
   // Logging
   void assert(optional boolean condition = false, any... data);
   void clear();
   void count(optional DOMString label = "default");
   void countReset(optional DOMString label = "default");
   void debug(any... data);
--- a/dom/webidl/DOMError.webidl
+++ b/dom/webidl/DOMError.webidl
@@ -6,16 +6,16 @@
  * The origin of this IDL file is
  * http://dom.spec.whatwg.org/#domerror
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 [Constructor(DOMString name, optional DOMString message = ""),
- Exposed=(Window,Worker,System)]
+ Exposed=(Window,Worker)]
 interface DOMError {
   [Constant, UseCounter]
   readonly attribute DOMString name;
 
   [Constant, UseCounter]
   readonly attribute DOMString message;
 };
--- a/dom/webidl/DOMException.webidl
+++ b/dom/webidl/DOMException.webidl
@@ -11,17 +11,17 @@
  */
 
 
 // This is the WebIDL version of nsIException.  This is mostly legacy stuff.
 
 interface StackFrame;
 
 [NoInterfaceObject,
- Exposed=(Window,Worker,System)]
+ Exposed=(Window,Worker)]
 interface ExceptionMembers
 {
   // The nsresult associated with this exception.
   readonly attribute unsigned long           result;
 
   // Filename location.  This is the location that caused the
   // error, which may or may not be a source file location.
   // For example, standard language errors would generally have
@@ -61,17 +61,17 @@ interface Exception {
   stringifier;
 };
 
 Exception implements ExceptionMembers;
 
 // XXXkhuey this is an 'exception', not an interface, but we don't have any
 // parser or codegen mechanisms for dealing with exceptions.
 [ExceptionClass,
- Exposed=(Window, Worker,System),
+ Exposed=(Window, Worker),
  Constructor(optional DOMString message = "", optional DOMString name)]
 interface DOMException {
   // The name of the error code (ie, a string repr of |result|).
   readonly attribute DOMString               name;
   // A custom message set by the thrower.
   readonly attribute DOMString               message;
   readonly attribute unsigned short code;
 
--- a/dom/webidl/DOMRequest.webidl
+++ b/dom/webidl/DOMRequest.webidl
@@ -1,27 +1,27 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 enum DOMRequestReadyState { "pending", "done" };
 
-[Exposed=(Window,Worker,System), NoInterfaceObject]
+[Exposed=(Window,Worker), NoInterfaceObject]
 interface DOMRequestShared {
   readonly attribute DOMRequestReadyState readyState;
 
   readonly attribute any result;
   readonly attribute DOMException? error;
 
   attribute EventHandler onsuccess;
   attribute EventHandler onerror;
 };
 
-[Exposed=(Window,Worker,System)]
+[Exposed=(Window,Worker)]
 interface DOMRequest : EventTarget {
   // The [TreatNonCallableAsNull] annotation is required since then() should do
   // nothing instead of throwing errors when non-callable arguments are passed.
   // See documentation for Promise.then to see why we return "any".
   [NewObject, Throws]
   any then([TreatNonCallableAsNull] optional AnyCallback? fulfillCallback = null,
            [TreatNonCallableAsNull] optional AnyCallback? rejectCallback = null);
 
--- a/dom/webidl/DOMStringList.webidl
+++ b/dom/webidl/DOMStringList.webidl
@@ -5,14 +5,14 @@
  *
  * The origin of this IDL file is
  * http://www.w3.org/TR/2012/WD-dom-20120105/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
-[Exposed=(Window,Worker,System)]
+[Exposed=(Window,Worker)]
 interface DOMStringList {
   readonly attribute unsigned long length;
   getter DOMString? item(unsigned long index);
   boolean contains(DOMString string);
 };
--- a/dom/webidl/ErrorEvent.webidl
+++ b/dom/webidl/ErrorEvent.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 [Constructor(DOMString type, optional ErrorEventInit eventInitDict),
- Exposed=(Window,Worker,System)]
+ Exposed=(Window,Worker)]
 interface ErrorEvent : Event
 {
   readonly attribute DOMString message;
   readonly attribute DOMString filename;
   readonly attribute unsigned long lineno;
   readonly attribute unsigned long colno;
   readonly attribute any error;
 };
--- a/dom/webidl/Event.webidl
+++ b/dom/webidl/Event.webidl
@@ -6,17 +6,17 @@
  * The origin of this IDL file is
  * http://www.w3.org/TR/2012/WD-dom-20120105/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 [Constructor(DOMString type, optional EventInit eventInitDict),
- Exposed=(Window,Worker,System), ProbablyShortLivingWrapper]
+ Exposed=(Window,Worker), ProbablyShortLivingWrapper]
 interface Event {
   [Pure]
   readonly attribute DOMString type;
   [Pure, BindingAlias="srcElement"]
   readonly attribute EventTarget? target;
   [Pure]
   readonly attribute EventTarget? currentTarget;
 
--- a/dom/webidl/EventTarget.webidl
+++ b/dom/webidl/EventTarget.webidl
@@ -21,17 +21,17 @@ dictionary EventListenerOptions {
 dictionary AddEventListenerOptions : EventListenerOptions {
   boolean passive;
   boolean once = false;
   [ChromeOnly]
   boolean wantUntrusted;
 };
 
 [Constructor,
- Exposed=(Window,Worker,WorkerDebugger,AudioWorklet,System)]
+ Exposed=(Window,Worker,WorkerDebugger,AudioWorklet)]
 interface EventTarget {
   /* Passing null for wantsUntrusted means "default behavior", which
      differs in content and chrome.  In content that default boolean
      value is true, while in chrome the default boolean value is
      false. */
   [Throws]
   void addEventListener(DOMString type,
                         EventListener? listener,
@@ -60,11 +60,11 @@ partial interface EventTarget {
   [ChromeOnly]
   EventHandler getEventHandler(DOMString type);
 };
 
 // Mozilla extension to make firing events on event targets from
 // chrome easier.  This returns the window which can be used to create
 // events to fire at this EventTarget, or null if there isn't one.
 partial interface EventTarget {
-  [ChromeOnly, Exposed=(Window,System), BinaryName="ownerGlobalForBindings"]
+  [ChromeOnly, Exposed=Window, BinaryName="ownerGlobalForBindings"]
   readonly attribute WindowProxy? ownerGlobal;
 };
--- a/dom/webidl/FileReader.webidl
+++ b/dom/webidl/FileReader.webidl
@@ -6,17 +6,17 @@
  * The origin of this IDL file is
  * https://w3c.github.io/FileAPI/#APIASynch
  *
  * Copyright © 2013 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 [Constructor,
- Exposed=(Window,Worker,System)]
+ Exposed=(Window,Worker)]
 interface FileReader : EventTarget {
   // async read methods
   [Throws]
   void readAsArrayBuffer(Blob blob);
   [Throws]
   void readAsBinaryString(Blob filedata);
   [Throws]
   void readAsText(Blob blob, optional DOMString label);
--- a/dom/webidl/IDBCursor.webidl
+++ b/dom/webidl/IDBCursor.webidl
@@ -9,17 +9,17 @@
 
 enum IDBCursorDirection {
     "next",
     "nextunique",
     "prev",
     "prevunique"
 };
 
-[Exposed=(Window,Worker,System)]
+[Exposed=(Window,Worker)]
 interface IDBCursor {
     readonly    attribute (IDBObjectStore or IDBIndex) source;
 
     readonly    attribute IDBCursorDirection           direction;
 
     [Throws]
     readonly    attribute any                          key;
 
@@ -37,13 +37,13 @@ interface IDBCursor {
 
     [Throws]
     void       continuePrimaryKey(any key, any primaryKey);
 
     [Throws]
     IDBRequest delete ();
 };
 
-[Exposed=(Window,Worker,System)]
+[Exposed=(Window,Worker)]
 interface IDBCursorWithValue : IDBCursor {
     [Throws]
     readonly    attribute any value;
 };
--- a/dom/webidl/IDBDatabase.webidl
+++ b/dom/webidl/IDBDatabase.webidl
@@ -5,17 +5,17 @@
  *
  * The origin of this IDL file is
  * https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBObjectStoreParameters
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
-[Exposed=(Window,Worker,System)]
+[Exposed=(Window,Worker)]
 interface IDBDatabase : EventTarget {
     readonly    attribute DOMString          name;
     readonly    attribute unsigned long long version;
 
     readonly    attribute DOMStringList      objectStoreNames;
 
     [Throws]
     IDBObjectStore createObjectStore (DOMString name, optional IDBObjectStoreParameters optionalParameters);
--- a/dom/webidl/IDBFactory.webidl
+++ b/dom/webidl/IDBFactory.webidl
@@ -18,17 +18,17 @@ dictionary IDBOpenDBOptions
   StorageType storage;
 };
 
 /**
  * Interface that defines the indexedDB property on a window.  See
  * http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBFactory
  * for more information.
  */
-[Exposed=(Window,Worker,System)]
+[Exposed=(Window,Worker)]
 interface IDBFactory {
   [Throws, NeedsCallerType]
   IDBOpenDBRequest
   open(DOMString name,
        [EnforceRange] unsigned long long version);
 
   [Throws, NeedsCallerType]
   IDBOpenDBRequest
--- a/dom/webidl/IDBFileHandle.webidl
+++ b/dom/webidl/IDBFileHandle.webidl
@@ -3,17 +3,17 @@
  * You can obtaone at http://mozilla.org/MPL/2.0/. */
 
 dictionary IDBFileMetadataParameters
 {
   boolean size = true;
   boolean lastModified = true;
 };
 
-[Exposed=(Window,System)]
+[Exposed=(Window)]
 interface IDBFileHandle : EventTarget
 {
   readonly attribute IDBMutableFile? mutableFile;
   // this is deprecated due to renaming in the spec
   readonly attribute IDBMutableFile? fileHandle; // now mutableFile
   readonly attribute FileMode mode;
   readonly attribute boolean active;
   attribute unsigned long long? location;
--- a/dom/webidl/IDBFileRequest.webidl
+++ b/dom/webidl/IDBFileRequest.webidl
@@ -1,14 +1,14 @@
 /* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-[Exposed=(Window,System)]
+[Exposed=Window]
 interface IDBFileRequest : DOMRequest {
   readonly attribute IDBFileHandle? fileHandle;
   // this is deprecated due to renaming in the spec
   readonly attribute IDBFileHandle? lockedFile; // now fileHandle
 
   attribute EventHandler onprogress;
 };
--- a/dom/webidl/IDBIndex.webidl
+++ b/dom/webidl/IDBIndex.webidl
@@ -13,17 +13,17 @@ dictionary IDBIndexParameters {
     // <null>:   Not locale-aware, uses normal JS sorting.
     // <string>: Always sorted based on the rules of the specified
     //           locale (e.g. "en-US", etc.).
     // "auto":   Sorted by the platform default, may change based on
     //           user agent options.
     DOMString? locale = null;
 };
 
-[Exposed=(Window,Worker,System)]
+[Exposed=(Window,Worker)]
 interface IDBIndex {
     [SetterThrows]
     attribute DOMString name;
 
     readonly    attribute IDBObjectStore objectStore;
 
     [Throws]
     readonly    attribute any            keyPath;
--- a/dom/webidl/IDBKeyRange.webidl
+++ b/dom/webidl/IDBKeyRange.webidl
@@ -4,17 +4,17 @@
 /*
  * The origin of this IDL file is
  * https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
-[Exposed=(Window,Worker,System)]
+[Exposed=(Window,Worker)]
 interface IDBKeyRange {
   [Throws]
   readonly attribute any     lower;
   [Throws]
   readonly attribute any     upper;
   [Constant]
   readonly attribute boolean lowerOpen;
   [Constant]
@@ -28,14 +28,14 @@ interface IDBKeyRange {
   [NewObject, Throws]
   static IDBKeyRange lowerBound (any lower, optional boolean open = false);
   [NewObject, Throws]
   static IDBKeyRange upperBound (any upper, optional boolean open = false);
   [NewObject, Throws]
   static IDBKeyRange bound (any lower, any upper, optional boolean lowerOpen = false, optional boolean upperOpen = false);
 };
 
-[Exposed=(Window,Worker,System),
+[Exposed=(Window,Worker),
  Func="mozilla::dom::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
 interface IDBLocaleAwareKeyRange : IDBKeyRange {
   [NewObject, Throws]
   static IDBLocaleAwareKeyRange bound (any lower, any upper, optional boolean lowerOpen = false, optional boolean upperOpen = false);
 };
--- a/dom/webidl/IDBMutableFile.webidl
+++ b/dom/webidl/IDBMutableFile.webidl
@@ -1,14 +1,14 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-[Exposed=(Window,System)]
+[Exposed=Window]
 interface IDBMutableFile : EventTarget {
   readonly attribute DOMString name;
   readonly attribute DOMString type;
 
   readonly attribute IDBDatabase database;
 
   [Throws, UseCounter]
   IDBFileHandle open(optional FileMode mode = "readonly");
--- a/dom/webidl/IDBObjectStore.webidl
+++ b/dom/webidl/IDBObjectStore.webidl
@@ -7,17 +7,17 @@
  * https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBObjectStore
  */
 
 dictionary IDBObjectStoreParameters {
     (DOMString or sequence<DOMString>)? keyPath = null;
     boolean                             autoIncrement = false;
 };
 
-[Exposed=(Window,Worker,System)]
+[Exposed=(Window,Worker)]
 interface IDBObjectStore {
     [SetterThrows]
     attribute DOMString name;
 
     [Throws]
     readonly    attribute any            keyPath;
 
     readonly    attribute DOMStringList  indexNames;
--- a/dom/webidl/IDBOpenDBRequest.webidl
+++ b/dom/webidl/IDBOpenDBRequest.webidl
@@ -2,14 +2,14 @@
 /* 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/.
  *
  * The origin of this IDL file is
  * https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBOpenDBRequest
  */
 
-[Exposed=(Window,Worker,System)]
+[Exposed=(Window,Worker)]
 interface IDBOpenDBRequest : IDBRequest {
                 attribute EventHandler onblocked;
 
                 attribute EventHandler onupgradeneeded;
 };
--- a/dom/webidl/IDBRequest.webidl
+++ b/dom/webidl/IDBRequest.webidl
@@ -8,17 +8,17 @@
  * https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBRequestReadyState
  */
 
 enum IDBRequestReadyState {
     "pending",
     "done"
 };
 
-[Exposed=(Window,Worker,System)]
+[Exposed=(Window,Worker)]
 interface IDBRequest : EventTarget {
     [Throws]
     readonly    attribute any                  result;
 
     [Throws]
     readonly    attribute DOMException?        error;
 
     readonly    attribute (IDBObjectStore or IDBIndex or IDBCursor)? source;
--- a/dom/webidl/IDBTransaction.webidl
+++ b/dom/webidl/IDBTransaction.webidl
@@ -14,17 +14,17 @@ enum IDBTransactionMode {
     // The "readwriteflush" mode is only available when the
     // |IndexedDatabaseManager::ExperimentalFeaturesEnabled()| function returns
     // true. This mode is not yet part of the standard.
     "readwriteflush",
     "cleanup",
     "versionchange"
 };
 
-[Exposed=(Window,Worker,System)]
+[Exposed=(Window,Worker)]
 interface IDBTransaction : EventTarget {
     [Throws]
     readonly    attribute IDBTransactionMode mode;
     readonly    attribute IDBDatabase        db;
 
     readonly    attribute DOMException?      error;
 
     [Throws]
--- a/dom/webidl/IDBVersionChangeEvent.webidl
+++ b/dom/webidl/IDBVersionChangeEvent.webidl
@@ -11,14 +11,14 @@
  */
 
 dictionary IDBVersionChangeEventInit : EventInit {
     unsigned long long  oldVersion = 0;
     unsigned long long? newVersion = null;
 };
 
 [Constructor(DOMString type, optional IDBVersionChangeEventInit eventInitDict),
- Exposed=(Window,Worker,System)]
+ Exposed=(Window,Worker)]
 interface IDBVersionChangeEvent : Event {
     readonly    attribute unsigned long long  oldVersion;
     readonly    attribute unsigned long long? newVersion;
 };
 
--- a/dom/webidl/IdleDeadline.webidl
+++ b/dom/webidl/IdleDeadline.webidl
@@ -2,14 +2,14 @@
 /* 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/.
  *
  * The origin of this IDL file is:
  * https://w3c.github.io/requestidlecallback/
  */
 
-[Exposed=(Window,System),
+[Exposed=Window,
  Func="nsGlobalWindowInner::IsRequestIdleCallbackEnabled"]
 interface IdleDeadline {
   DOMHighResTimeStamp timeRemaining();
   readonly attribute boolean didTimeout;
 };
--- a/dom/webidl/ImageBitmap.webidl
+++ b/dom/webidl/ImageBitmap.webidl
@@ -5,35 +5,27 @@
  *
  * The origin of this IDL file is
  * https://html.spec.whatwg.org/multipage/webappapis.html#images
  *
  * The origin of the extended IDL file is
  * http://w3c.github.io/mediacapture-worker/#imagebitmap-extensions
  */
 
-// Extensions
-// Bug 1141979 - [FoxEye] Extend ImageBitmap with interfaces to access its
-// underlying image data
-//
-// Note:
-// Our overload resolution implementation doesn't deal with a union as the
-// distinguishing argument which means we cannot overload functions via union
-// types, a.k.a. we cannot overload createImageBitmap() via ImageBitmapSource
-// and BufferSource. Here, we work around this issue by adding the BufferSource
-// into ImageBitmapSource.
+// This is needed because we don't support SVG element as canvas image source.
+// See bug 1500768.
+typedef (HTMLImageElement or
+         HTMLCanvasElement or
+         HTMLVideoElement or
+         ImageBitmap) CanvasImageSourceExcludedSVG;
 
-typedef (HTMLImageElement or
-         HTMLVideoElement or
-         HTMLCanvasElement or
+typedef (CanvasImageSourceExcludedSVG or
          Blob or
-         ImageData or
-         CanvasRenderingContext2D or
-         ImageBitmap or
-         BufferSource) ImageBitmapSource;
+         CanvasRenderingContext2D or // This is out of spec.
+         ImageData) ImageBitmapSource;
 
 [Exposed=(Window,Worker)]
 interface ImageBitmap {
   [Constant]
   readonly attribute unsigned long width;
   [Constant]
   readonly attribute unsigned long height;
 };
@@ -396,17 +388,8 @@ dictionary ChannelPixelLayout {
     required unsigned long              width;
     required unsigned long              height;
     required ChannelPixelLayoutDataType dataType;
     required unsigned long              stride;
     required unsigned long              skip;
 };
 
 typedef sequence<ChannelPixelLayout> ImagePixelLayout;
-
-partial interface ImageBitmap {
-    [Throws, Func="mozilla::dom::DOMPrefs::canvas_imagebitmap_extensions_enabled"]
-    ImageBitmapFormat               findOptimalFormat (optional sequence<ImageBitmapFormat> aPossibleFormats);
-    [Throws, Func="mozilla::dom::DOMPrefs::canvas_imagebitmap_extensions_enabled"]
-    long                            mappedDataLength (ImageBitmapFormat aFormat);
-    [Throws, Func="mozilla::dom::DOMPrefs::canvas_imagebitmap_extensions_enabled"]
-    Promise<ImagePixelLayout> mapDataInto (ImageBitmapFormat aFormat, BufferSource aBuffer, long aOffset);
-};
--- a/dom/webidl/LegacyQueryInterface.webidl
+++ b/dom/webidl/LegacyQueryInterface.webidl
@@ -5,20 +5,20 @@
  */
 
 interface nsISupports;
 interface IID;
 
 [NoInterfaceObject,
  // Need Exposed here, because this is a mixin onto things like Event
  // that are exposed in workers.
- Exposed=(Window,Worker,System)]
+ Exposed=(Window,Worker)]
 interface LegacyQueryInterface {
   // Legacy QueryInterface, only exposed to chrome code on the main thread.
-  [Exposed=(Window,System), ChromeOnly]
+  [Exposed=Window, ChromeOnly]
   nsISupports QueryInterface(IID iid);
 };
 
 DOMParser implements LegacyQueryInterface;
 Document implements LegacyQueryInterface;
 DocumentFragment implements LegacyQueryInterface;
 Element implements LegacyQueryInterface;
 Event implements LegacyQueryInterface;
--- a/dom/webidl/MessageChannel.webidl
+++ b/dom/webidl/MessageChannel.webidl
@@ -2,13 +2,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
  * For more information on this interface, please see
  * http://www.whatwg.org/specs/web-apps/current-work/#channel-messaging
  */
 
-[Constructor, Exposed=(Window,Worker,System)]
+[Constructor, Exposed=(Window,Worker)]
 interface MessageChannel {
   readonly attribute MessagePort port1;
   readonly attribute MessagePort port2;
 };
--- a/dom/webidl/MessageEvent.webidl
+++ b/dom/webidl/MessageEvent.webidl
@@ -3,17 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
  * For more information on this interface, please see
  * https://html.spec.whatwg.org/#messageevent
  */
 
 [Constructor(DOMString type, optional MessageEventInit eventInitDict),
- Exposed=(Window,Worker,System)]
+ Exposed=(Window,Worker)]
 interface MessageEvent : Event {
   /**
    * Custom data associated with this event.
    */
   [GetterThrows]
   readonly attribute any data;
 
   /**
--- a/dom/webidl/MessagePort.webidl
+++ b/dom/webidl/MessagePort.webidl
@@ -2,17 +2,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/.
  *
  * For more information on this interface, please see
  * http://www.whatwg.org/specs/web-apps/current-work/#channel-messaging
  */
 
-[Exposed=(Window,Worker,AudioWorklet,System)]
+[Exposed=(Window,Worker,AudioWorklet)]
 interface MessagePort : EventTarget {
   [Throws]
   void postMessage(any message, optional sequence<object> transferable = []);
 
   void start();
   void close();
 
   // event handlers
--- a/dom/webidl/Promise.webidl
+++ b/dom/webidl/Promise.webidl
@@ -9,12 +9,11 @@
 
 callback PromiseJobCallback = void();
 
 [TreatNonCallableAsNull]
 callback AnyCallback = any (any value);
 
 // Hack to allow us to have JS owning and properly tracing/CCing/etc a
 // PromiseNativeHandler.
-[NoInterfaceObject,
- Exposed=(Window,Worker,System)]
+[NoInterfaceObject, Exposed=(Window,Worker)]
 interface PromiseNativeHandler {
 };
--- a/dom/webidl/StreamFilter.webidl
+++ b/dom/webidl/StreamFilter.webidl
@@ -52,17 +52,17 @@ enum StreamFilterStatus {
    */
   "failed",
 };
 
 /**
  * An interface which allows an extension to intercept, and optionally modify,
  * response data from an HTTP request.
  */
-[Exposed=(Window,System),
+[Exposed=Window,
  Func="mozilla::extensions::StreamFilter::IsAllowedInContext"]
 interface StreamFilter : EventTarget {
   /**
    * Creates a stream filter for the given add-on and the given extension ID.
    */
   [ChromeOnly]
   static StreamFilter create(unsigned long long requestId, DOMString addonId);
 
--- a/dom/webidl/StreamFilterDataEvent.webidl
+++ b/dom/webidl/StreamFilterDataEvent.webidl
@@ -8,17 +8,17 @@
  * content. It allows monitoring and filtering of HTTP response stream data.
  *
  * This API should currently be considered experimental, and is not defined by
  * any standard.
  */
 
 [Constructor(DOMString type, optional StreamFilterDataEventInit eventInitDict),
  Func="mozilla::extensions::StreamFilter::IsAllowedInContext",
- Exposed=(Window,System)]
+ Exposed=Window]
 interface StreamFilterDataEvent : Event {
   /**
    * Contains a chunk of data read from the input stream.
    */
   [Pure]
   readonly attribute ArrayBuffer data;
 };
 
--- a/dom/webidl/TCPServerSocket.webidl
+++ b/dom/webidl/TCPServerSocket.webidl
@@ -10,17 +10,17 @@
  */
 
 dictionary ServerSocketOptions {
   TCPSocketBinaryType binaryType = "string";
 };
 
 [Constructor(unsigned short port, optional ServerSocketOptions options, optional unsigned short backlog = 0),
  Func="mozilla::dom::TCPSocket::ShouldTCPSocketExist",
- Exposed=(Window,System)]
+ Exposed=Window]
 interface TCPServerSocket : EventTarget {
   /**
    * The port of this server socket object.
    */
   readonly attribute unsigned short localPort;
 
   /**
    * The "connect" event is dispatched when a client connection is accepted.
--- a/dom/webidl/TCPServerSocketEvent.webidl
+++ b/dom/webidl/TCPServerSocketEvent.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 [Constructor(DOMString type, optional TCPServerSocketEventInit eventInitDict),
  Func="mozilla::dom::TCPSocket::ShouldTCPSocketExist",
- Exposed=(Window,System)]
+ Exposed=Window]
 interface TCPServerSocketEvent : Event {
   readonly attribute TCPSocket socket;
 };
 
 dictionary TCPServerSocketEventInit : EventInit {
   TCPSocket? socket = null;
 };
--- a/dom/webidl/TCPSocket.webidl
+++ b/dom/webidl/TCPSocket.webidl
@@ -36,17 +36,17 @@ interface LegacyMozTCPSocket {
   TCPSocket open(DOMString host, unsigned short port, optional SocketOptions options);
 
   [Throws]
   TCPServerSocket listen(unsigned short port, optional ServerSocketOptions options, optional unsigned short backlog = 0);
 };
 
 [Constructor(DOMString host, unsigned short port, optional SocketOptions options),
  Func="mozilla::dom::TCPSocket::ShouldTCPSocketExist",
- Exposed=(Window,System)]
+ Exposed=Window]
 interface TCPSocket : EventTarget {
   /**
    * Upgrade an insecure connection to use TLS. Throws if the ready state is not OPEN.
    */
   [Throws] void upgradeToSecure();
 
   /**
    * The UTF16 host of this socket object.
--- a/dom/webidl/TCPSocketErrorEvent.webidl
+++ b/dom/webidl/TCPSocketErrorEvent.webidl
@@ -6,17 +6,17 @@
 /* Dispatched as part of the "error" event in the following situations:
 * - if there's an error detected when the TCPSocket closes
 * - if there's an internal error while sending data
 * - if there's an error connecting to the host
 */
 
 [Constructor(DOMString type, optional TCPSocketErrorEventInit eventInitDict),
  Func="mozilla::dom::TCPSocket::ShouldTCPSocketExist",
- Exposed=(Window,System)]
+ Exposed=Window]
 interface TCPSocketErrorEvent : Event {
   readonly attribute DOMString name;
   readonly attribute DOMString message;
 };
 
 dictionary TCPSocketErrorEventInit : EventInit
 {
   DOMString name = "";
--- a/dom/webidl/TCPSocketEvent.webidl
+++ b/dom/webidl/TCPSocketEvent.webidl
@@ -6,17 +6,17 @@
 /**
  * TCPSocketEvent is the event dispatched for all of the events described by TCPSocket,
  * except the "error" event. It contains the socket that was associated with the event,
  * the type of event, and the data associated with the event if the event is a "data" event.
  */
 
 [Constructor(DOMString type, optional TCPSocketEventInit eventInitDict),
  Func="mozilla::dom::TCPSocket::ShouldTCPSocketExist",
- Exposed=(Window,System)]
+ Exposed=Window]
 interface TCPSocketEvent : Event {
   /**
    * If the event is a "data" event, data will be the bytes read from the network;
    * if the binaryType of the socket was "arraybuffer", this value will be of type
    * ArrayBuffer, otherwise, it will be a ByteString.
    *
    * For other events, data will be an empty string.
    */
--- a/dom/webidl/TextDecoder.webidl
+++ b/dom/webidl/TextDecoder.webidl
@@ -6,17 +6,17 @@
  * The origin of this IDL file is
  * http://encoding.spec.whatwg.org/#interface-textdecoder
  *
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 [Constructor(optional DOMString label = "utf-8", optional TextDecoderOptions options),
- Exposed=(Window,Worker,System)]
+ Exposed=(Window,Worker)]
 interface TextDecoder {
   [Constant]
   readonly attribute DOMString encoding;
   [Constant]
   readonly attribute boolean fatal;
   [Constant]
   readonly attribute boolean ignoreBOM;
   [Throws]
--- a/dom/webidl/TextEncoder.webidl
+++ b/dom/webidl/TextEncoder.webidl
@@ -5,18 +5,17 @@
  *
  * The origin of this IDL file is
  * http://encoding.spec.whatwg.org/#interface-textencoder
  *
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
-[Constructor,
- Exposed=(Window,Worker,System)]
+[Constructor, Exposed=(Window,Worker)]
 interface TextEncoder {
   [Constant]
   readonly attribute DOMString encoding;
   /*
    * This is spec-wise USVString but marking it as
    * DOMString to avoid duplicate work. Since the
    * UTF-16 to UTF-8 converter performs processing
    * that's equivalent to first converting a
--- a/dom/webidl/URLSearchParams.webidl
+++ b/dom/webidl/URLSearchParams.webidl
@@ -9,17 +9,17 @@
  * To the extent possible under law, the editors have waived all copyright
  * and related or neighboring rights to this work. In addition, as of 17
  * February 2013, the editors have made this specification available under
  * the Open Web Foundation Agreement Version 1.0, which is available at
  * http://www.openwebfoundation.org/legal/the-owf-1-0-agreements/owfa-1-0.
  */
 
 [Constructor(optional (sequence<sequence<USVString>> or record<USVString, USVString> or USVString) init = ""),
- Exposed=(Window,Worker,WorkerDebugger,System)]
+ Exposed=(Window,Worker,WorkerDebugger)]
 interface URLSearchParams {
   void append(USVString name, USVString value);
   void delete(USVString name);
   USVString? get(USVString name);
   sequence<USVString> getAll(USVString name);
   boolean has(USVString name);
   void set(USVString name, USVString value);
 
--- a/dom/webidl/WindowOrWorkerGlobalScope.webidl
+++ b/dom/webidl/WindowOrWorkerGlobalScope.webidl
@@ -60,23 +60,8 @@ partial interface WindowOrWorkerGlobalSc
    readonly attribute IDBFactory? indexedDB;
 };
 
 // https://w3c.github.io/ServiceWorker/#self-caches
 partial interface WindowOrWorkerGlobalScope {
   [Throws, Func="mozilla::dom::DOMPrefs::dom_caches_enabled", SameObject]
   readonly attribute CacheStorage caches;
 };
-
-// Mozilla extensions
-partial interface WindowOrWorkerGlobalScope {
-  // Extensions to ImageBitmap bits.
-  // Bug 1141979 - [FoxEye] Extend ImageBitmap with interfaces to access its
-  // underlying image data
-  //
-  // Note:
-  // Overloaded functions cannot have different "extended attributes",
-  // so I cannot add preference on the extended version of createImageBitmap().
-  // To work around, I will then check the preference at run time and throw if
-  // the preference is set to be false.
-  [Throws]
-  Promise<ImageBitmap> createImageBitmap(ImageBitmapSource aImage, long aOffset, long aLength, ImageBitmapFormat aFormat, ImagePixelLayout aLayout);
-};
--- a/dom/webidl/Worker.webidl
+++ b/dom/webidl/Worker.webidl
@@ -8,17 +8,17 @@
  *
  * © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and Opera
  * Software ASA.
  * You are granted a license to use, reproduce and create derivative works of
  * this document.
  */
 
 [Constructor(USVString scriptURL, optional WorkerOptions options),
- Exposed=(Window,DedicatedWorker,SharedWorker,System)]
+ Exposed=(Window,DedicatedWorker,SharedWorker)]
 interface Worker : EventTarget {
   void terminate();
 
   [Throws]
   void postMessage(any message, optional sequence<object> transfer = []);
 
   attribute EventHandler onmessage;
   attribute EventHandler onmessageerror;
@@ -29,11 +29,11 @@ Worker implements AbstractWorker;
 dictionary WorkerOptions {
   // WorkerType type = "classic"; TODO: Bug 1247687
   // RequestCredentials credentials = "omit"; // credentials is only used if type is "module" TODO: Bug 1247687
   DOMString name = "";
 };
 
 [Constructor(USVString scriptURL),
  Func="mozilla::dom::ChromeWorker::WorkerAvailable",
- Exposed=(Window,DedicatedWorker,SharedWorker,System)]
+ Exposed=(Window,DedicatedWorker,SharedWorker)]
 interface ChromeWorker : Worker {
 };
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -479,60 +479,28 @@ WorkerGlobalScope::GetIndexedDB(ErrorRes
   return indexedDB.forget();
 }
 
 already_AddRefed<Promise>
 WorkerGlobalScope::CreateImageBitmap(JSContext* aCx,
                                      const ImageBitmapSource& aImage,
                                      ErrorResult& aRv)
 {
-  if (aImage.IsArrayBuffer() || aImage.IsArrayBufferView()) {
-    aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
-    return nullptr;
-  }
-
   return ImageBitmap::Create(this, aImage, Nothing(), aRv);
 }
 
 already_AddRefed<Promise>
 WorkerGlobalScope::CreateImageBitmap(JSContext* aCx,
                                      const ImageBitmapSource& aImage,
                                      int32_t aSx, int32_t aSy, int32_t aSw, int32_t aSh,
                                      ErrorResult& aRv)
 {
-  if (aImage.IsArrayBuffer() || aImage.IsArrayBufferView()) {
-    aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
-    return nullptr;
-  }
-
   return ImageBitmap::Create(this, aImage, Some(gfx::IntRect(aSx, aSy, aSw, aSh)), aRv);
 }
 
-already_AddRefed<mozilla::dom::Promise>
-WorkerGlobalScope::CreateImageBitmap(JSContext* aCx,
-                                     const ImageBitmapSource& aImage,
-                                     int32_t aOffset, int32_t aLength,
-                                     ImageBitmapFormat aFormat,
-                                     const Sequence<ChannelPixelLayout>& aLayout,
-                                     ErrorResult& aRv)
-{
-  if (!StaticPrefs::canvas_imagebitmap_extensions_enabled()) {
-    aRv.Throw(NS_ERROR_TYPE_ERR);
-    return nullptr;
-  }
-
-  if (aImage.IsArrayBuffer() || aImage.IsArrayBufferView()) {
-    return ImageBitmap::Create(this, aImage, aOffset, aLength, aFormat, aLayout,
-                               aRv);
-  } else {
-    aRv.Throw(NS_ERROR_TYPE_ERR);
-    return nullptr;
-  }
-}
-
 nsresult
 WorkerGlobalScope::Dispatch(TaskCategory aCategory,
                             already_AddRefed<nsIRunnable>&& aRunnable)
 {
   return EventTargetFor(aCategory)->Dispatch(std::move(aRunnable),
                                              NS_DISPATCH_NORMAL);
 }
 
--- a/dom/workers/WorkerScope.h
+++ b/dom/workers/WorkerScope.h
@@ -186,24 +186,16 @@ public:
                     const ImageBitmapSource& aImage, ErrorResult& aRv);
 
   already_AddRefed<Promise>
   CreateImageBitmap(JSContext* aCx,
                     const ImageBitmapSource& aImage,
                     int32_t aSx, int32_t aSy, int32_t aSw, int32_t aSh,
                     ErrorResult& aRv);
 
-  already_AddRefed<mozilla::dom::Promise>
-  CreateImageBitmap(JSContext* aCx,
-                    const ImageBitmapSource& aImage,
-                    int32_t aOffset, int32_t aLength,
-                    mozilla::dom::ImageBitmapFormat aFormat,
-                    const mozilla::dom::Sequence<mozilla::dom::ChannelPixelLayout>& aLayout,
-                    mozilla::ErrorResult& aRv);
-
   bool
   WindowInteractionAllowed() const
   {
     return mWindowInteractionsAllowed > 0;
   }
 
   void
   AllowWindowInteraction()
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -9971,125 +9971,172 @@ CreateSimpleClipRegion(const nsDisplayMa
 {
   nsIFrame* frame = aDisplayItem.Frame();
   auto* style = frame->StyleSVGReset();
   MOZ_ASSERT(style->HasClipPath() || style->HasMask());
   if (style->HasMask()) {
     return Nothing();
   }
 
-  // TODO(emilio): We should be able to still generate a clip and pass the
-  // opacity down to StackingContextHelper instead.
-  if (frame->StyleEffects()->mOpacity != 1.0) {
-    return Nothing();
-  }
-
   auto& clipPath = style->mClipPath;
   if (clipPath.GetType() != StyleShapeSourceType::Shape) {
     return Nothing();
   }
 
-  // TODO(emilio): We should be able to also simplify most of the circle() and
-  // ellipse() shapes.
   auto& shape = clipPath.GetBasicShape();
-  if (shape->GetShapeType() != StyleBasicShapeType::Inset) {
+  if (shape->GetShapeType() == StyleBasicShapeType::Polygon) {
     return Nothing();
   }
 
+  auto appUnitsPerDevPixel = frame->PresContext()->AppUnitsPerDevPixel();
   const nsRect refBox =
     nsLayoutUtils::ComputeGeometryBox(frame, clipPath.GetReferenceBox());
 
-  const nsRect insetRect =
-    ShapeUtils::ComputeInsetRect(shape, refBox) + aDisplayItem.ToReferenceFrame();
-
-  auto appUnitsPerDevPixel = frame->PresContext()->AppUnitsPerDevPixel();
-
-  nscoord radii[8] = { 0 };
   AutoTArray<wr::ComplexClipRegion, 1> clipRegions;
-  if (ShapeUtils::ComputeInsetRadii(shape, insetRect, refBox, radii)) {
-    clipRegions.AppendElement(wr::ToComplexClipRegion(
-      insetRect, radii, appUnitsPerDevPixel));
-  }
-
-  auto rect = wr::ToRoundedLayoutRect(
-    LayoutDeviceRect::FromAppUnits(insetRect, appUnitsPerDevPixel));
+
+  wr::LayoutRect rect;
+  switch (shape->GetShapeType()) {
+    case StyleBasicShapeType::Inset: {
+      const nsRect insetRect =
+        ShapeUtils::ComputeInsetRect(shape, refBox) + aDisplayItem.ToReferenceFrame();
+
+      nscoord radii[8] = { 0 };
+
+      if (ShapeUtils::ComputeInsetRadii(shape, insetRect, refBox, radii)) {
+        clipRegions.AppendElement(wr::ToComplexClipRegion(
+          insetRect, radii, appUnitsPerDevPixel));
+      }
+
+      rect = wr::ToRoundedLayoutRect(
+        LayoutDeviceRect::FromAppUnits(insetRect, appUnitsPerDevPixel));
+      break;
+    }
+    case StyleBasicShapeType::Ellipse:
+    case StyleBasicShapeType::Circle: {
+      nsPoint center = ShapeUtils::ComputeCircleOrEllipseCenter(shape, refBox);
+
+      nsSize radii;
+      if (shape->GetShapeType() == StyleBasicShapeType::Ellipse) {
+        radii = ShapeUtils::ComputeEllipseRadii(shape, center, refBox);
+      } else {
+        nscoord radius = ShapeUtils::ComputeCircleRadius(shape, center, refBox);
+        radii = { radius, radius };
+      }
+
+      nsRect ellipseRect(
+        aDisplayItem.ToReferenceFrame() + center - nsPoint(radii.width, radii.height),
+        radii * 2);
+
+      nscoord ellipseRadii[8];
+      NS_FOR_CSS_HALF_CORNERS(corner) {
+        ellipseRadii[corner] = HalfCornerIsX(corner) ? radii.width : radii.height;
+      }
+
+      clipRegions.AppendElement(wr::ToComplexClipRegion(
+          ellipseRect, ellipseRadii, appUnitsPerDevPixel));
+
+      rect = wr::ToRoundedLayoutRect(
+        LayoutDeviceRect::FromAppUnits(ellipseRect, appUnitsPerDevPixel));
+      break;
+    }
+    default:
+      // Please don't add more exceptions, try to find a way to define the clip
+      // without using a mask image.
+      //
+      // And if you _really really_ need to add an exception, add it to where
+      // the polygon check is.
+      MOZ_ASSERT_UNREACHABLE("Unhandled shape id?");
+      return Nothing();
+  }
   wr::WrClipId clipId =
     aBuilder.DefineClip(Nothing(), rect, &clipRegions, nullptr);
   return Some(clipId);
 }
 
-static Maybe<wr::WrClipId>
+enum class HandleOpacity
+{
+  No,
+  Yes,
+};
+
+static Maybe<Pair<wr::WrClipId, HandleOpacity>>
 CreateWRClipPathAndMasks(nsDisplayMasksAndClipPaths* aDisplayItem,
                          const LayoutDeviceRect& aBounds,
                          wr::IpcResourceUpdateQueue& aResources,
                          wr::DisplayListBuilder& aBuilder,
                          const StackingContextHelper& aSc,
                          layers::WebRenderLayerManager* aManager,
                          nsDisplayListBuilder* aDisplayListBuilder)
 {
   if (auto clip = CreateSimpleClipRegion(*aDisplayItem, aBuilder)) {
-    return clip;
+    return Some(MakePair(*clip, HandleOpacity::Yes));
   }
 
   Maybe<wr::WrImageMask> mask = aManager->CommandBuilder().BuildWrMaskImage(
     aDisplayItem, aBuilder, aResources, aSc, aDisplayListBuilder, aBounds);
   if (!mask) {
     return Nothing();
   }
 
   wr::WrClipId clipId =
     aBuilder.DefineClip(Nothing(),
                         wr::ToRoundedLayoutRect(aBounds),
                         nullptr,
                         mask.ptr());
 
-  return Some(clipId);
+  return Some(MakePair(clipId, HandleOpacity::No));
 }
 
 bool
 nsDisplayMasksAndClipPaths::CreateWebRenderCommands(
   mozilla::wr::DisplayListBuilder& aBuilder,
   mozilla::wr::IpcResourceUpdateQueue& aResources,
   const StackingContextHelper& aSc,
   mozilla::layers::WebRenderLayerManager* aManager,
   nsDisplayListBuilder* aDisplayListBuilder)
 {
   bool snap;
   auto appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
   nsRect displayBounds = GetBounds(aDisplayListBuilder, &snap);
   LayoutDeviceRect bounds =
     LayoutDeviceRect::FromAppUnits(displayBounds, appUnitsPerDevPixel);
 
-  Maybe<wr::WrClipId> clip =
+  Maybe<Pair<wr::WrClipId, HandleOpacity>> clip =
     CreateWRClipPathAndMasks(
       this, bounds, aResources, aBuilder, aSc, aManager, aDisplayListBuilder);
 
   Maybe<StackingContextHelper> layer;
   const StackingContextHelper* sc = &aSc;
   if (clip) {
     // Create a new stacking context to attach the mask to, ensuring the mask is
     // applied to the aggregate, and not the individual elements.
 
     // The stacking context shouldn't have any offset.
     bounds.MoveTo(0, 0);
 
+    wr::WrClipId clipId = clip->first();
+
+    Maybe<float> opacity = clip->second() == HandleOpacity::Yes
+      ? Some(mFrame->StyleEffects()->mOpacity)
+      : Nothing();
+
     layer.emplace(aSc,
                   aBuilder,
                   /*aFilters: */ nsTArray<wr::WrFilterOp>(),
                   /*aBounds: */ bounds,
                   /*aBoundTransform: */ nullptr,
                   /*aAnimation: */ nullptr,
-                  /*aOpacity: */ nullptr,
+                  /*aOpacity: */ opacity.ptrOr(nullptr),
                   /*aTransform: */ nullptr,
                   /*aPerspective: */ nullptr,
                   /*aMixBlendMode: */ gfx::CompositionOp::OP_OVER,
                   /*aBackfaceVisible: */ true,
                   /*aIsPreserve3D: */ false,
                   /*aTransformForScrollData: */ Nothing(),
-                  /*aClipNodeId: */ clip.ptr());
+                  /*aClipNodeId: */ &clipId);
     sc = layer.ptr();
     // The whole stacking context will be clipped by us, so no need to have any
     // parent for the children context's clip.
     aManager->CommandBuilder().PushOverrideForASR(GetActiveScrolledRoot(),
                                                   Nothing());
   }
 
   nsDisplayEffectsBase::CreateWebRenderCommands(
--- a/layout/reftests/font-inflation/reftest.list
+++ b/layout/reftests/font-inflation/reftest.list
@@ -70,17 +70,17 @@ test-pref(font.size.inflation.emPerLine,
 # Ordinarily, reftests use a browser.viewport.desktopWidth of 800px, same as the
 # size of the reftest document.  The failure condition of the test below however
 # depends on the initial window size being smaller than the viewport the
 # MobileViewportManager eventually calculates, so we use a bigger value here.
 test-pref(font.size.inflation.emPerLine,20) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) test-pref(browser.viewport.desktopWidth,1000) == fixed-width-body-viewport.html fixed-width-body-viewport-ref.html
 
 # The tests below use nonzero values of the lineThreshold preference.
 test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == text-1.html text-1.html
-test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == list-1.html list-1-ref.html # Bug 1392106
+test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) skip-if(cocoaWidget) == list-1.html list-1-ref.html # Bug 1392106, Bug 1434812
 test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-1a.html threshold-1a.html
 test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-1b.html threshold-1b-ref.html
 test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-1c.html threshold-1c-ref.html
 test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-2.html threshold-2-ref.html
 test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-3.html threshold-3-ref.html
 test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-scope-float-1.html threshold-scope-float-1-ref.html
 test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-scope-float-2.html threshold-scope-float-2-ref.html
 test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-scope-float-overflow-1.html threshold-scope-float-overflow-1-ref.html
--- a/layout/reftests/svg/svg-integration/clip-path/reftest.list
+++ b/layout/reftests/svg/svg-integration/clip-path/reftest.list
@@ -11,46 +11,46 @@
 == clip-path-polygon-007.html clip-path-stripes-001-ref.html
 == clip-path-polygon-008.html clip-path-stripes-002-ref.html
 == clip-path-polygon-009.html clip-path-square-002-ref.html
 == clip-path-polygon-010.html clip-path-stripes-001-ref.html
 == clip-path-polygon-011.html clip-path-stripes-001-ref.html
 == clip-path-polygon-012.html clip-path-stripes-001-ref.html
 fuzzy-if(skiaContent,0-1,0-20) fuzzy-if(webrender&&gtkWidget,8-8,20-20) fails-if(webrender&&!gtkWidget) == clip-path-polygon-013.html clip-path-stripes-003-ref.html
 
-fuzzy-if(webrender,64-64,714-714) == clip-path-circle-001.html clip-path-circle-001-ref.html
-fuzzy-if(webrender,64-64,714-714) == clip-path-circle-002.html clip-path-circle-001-ref.html
-fuzzy-if(webrender,64-64,714-714) == clip-path-circle-003.html clip-path-circle-001-ref.html
-fuzzy-if(webrender,64-64,714-714) == clip-path-circle-004.html clip-path-circle-001-ref.html
-fuzzy-if(webrender,64-64,714-714) == clip-path-circle-005.html clip-path-circle-002-ref.html
-fuzzy-if(webrender,64-64,714-714) == clip-path-circle-006.html clip-path-circle-001-ref.html
-fuzzy-if(webrender,64-64,714-714) == clip-path-circle-007.html clip-path-circle-002-ref.html
-fuzzy-if(webrender,64-64,714-714) == clip-path-circle-008.html clip-path-circle-002-ref.html
-fuzzy-if(webrender,64-64,714-714) == clip-path-circle-009.html clip-path-circle-003-ref.html
-fuzzy-if(webrender,64-64,714-714) == clip-path-circle-010.html clip-path-circle-004-ref.html
-fuzzy-if(webrender,64-64,714-714) == clip-path-circle-011.html clip-path-circle-005-ref.html
-fuzzy-if(webrender,64-64,714-714) == clip-path-circle-012.html clip-path-circle-006-ref.html
-fuzzy-if(webrender,64-64,714-714) == clip-path-circle-013.html clip-path-circle-002-ref.html
-fuzzy-if(webrender,64-64,714-714) == clip-path-circle-014.html clip-path-circle-007-ref.html
-fuzzy-if(webrender,64-64,714-714) == clip-path-circle-015.html clip-path-circle-008-ref.html
-fuzzy-if(webrender,64-64,714-714) == clip-path-circle-016.html clip-path-circle-009-ref.html
-fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-16,0-9) fuzzy-if(webrender,64-64,714-714) == clip-path-circle-017.html clip-path-circle-007-ref.html
-fuzzy-if(webrender,64-64,714-714) == clip-path-circle-018.html clip-path-circle-010-ref.html
-fuzzy-if(webrender,64-64,714-714) == clip-path-circle-019.html clip-path-circle-002-ref.html
-fuzzy-if(webrender,64-64,714-714) == clip-path-circle-020.html clip-path-circle-002-ref.html
+fuzzy-if(webrender,35-35,703-703) == clip-path-circle-001.html clip-path-circle-001-ref.html
+fuzzy-if(webrender,35-35,703-703) == clip-path-circle-002.html clip-path-circle-001-ref.html
+fuzzy-if(webrender,35-35,703-703) == clip-path-circle-003.html clip-path-circle-001-ref.html
+fuzzy-if(webrender,35-35,703-703) == clip-path-circle-004.html clip-path-circle-001-ref.html
+fuzzy-if(webrender,35-35,703-703) == clip-path-circle-005.html clip-path-circle-002-ref.html
+fuzzy-if(webrender,35-35,703-703) == clip-path-circle-006.html clip-path-circle-001-ref.html
+fuzzy-if(webrender,35-35,703-703) == clip-path-circle-007.html clip-path-circle-002-ref.html
+fuzzy-if(webrender,35-35,703-703) == clip-path-circle-008.html clip-path-circle-002-ref.html
+fuzzy-if(webrender,35-35,703-703) == clip-path-circle-009.html clip-path-circle-003-ref.html
+fuzzy-if(webrender,35-35,703-703) == clip-path-circle-010.html clip-path-circle-004-ref.html
+fuzzy-if(webrender,35-35,703-703) == clip-path-circle-011.html clip-path-circle-005-ref.html
+fuzzy-if(webrender,35-35,703-703) == clip-path-circle-012.html clip-path-circle-006-ref.html
+fuzzy-if(webrender,35-35,703-703) == clip-path-circle-013.html clip-path-circle-002-ref.html
+fuzzy-if(webrender,35-35,703-703) == clip-path-circle-014.html clip-path-circle-007-ref.html
+fuzzy-if(webrender,35-35,703-703) == clip-path-circle-015.html clip-path-circle-008-ref.html
+fuzzy-if(webrender,35-35,703-703) == clip-path-circle-016.html clip-path-circle-009-ref.html
+fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-16,0-9) fuzzy-if(webrender,35-35,703-703) == clip-path-circle-017.html clip-path-circle-007-ref.html
+fuzzy-if(webrender,35-35,703-703) == clip-path-circle-018.html clip-path-circle-010-ref.html
+fuzzy-if(webrender,35-35,703-703) == clip-path-circle-019.html clip-path-circle-002-ref.html
+fuzzy-if(webrender,35-35,703-703) == clip-path-circle-020.html clip-path-circle-002-ref.html
 == clip-path-circle-021.html clip-path-circle-021-ref.html
 
-fuzzy-if(webrender,64-64,1106-1106) == clip-path-ellipse-001.html clip-path-ellipse-001-ref.html
-fuzzy-if(webrender,64-64,1106-1106) == clip-path-ellipse-002.html clip-path-ellipse-001-ref.html
-fuzzy-if(webrender,64-64,1106-1106) == clip-path-ellipse-003.html clip-path-ellipse-001-ref.html
-fuzzy-if(webrender,64-64,1106-1106) == clip-path-ellipse-004.html clip-path-ellipse-001-ref.html
-fuzzy-if(webrender,64-64,1106-1106) == clip-path-ellipse-005.html clip-path-ellipse-001-ref.html
-fuzzy-if(webrender,64-64,1106-1106) == clip-path-ellipse-006.html clip-path-ellipse-001-ref.html
-fuzzy-if(webrender,64-64,1106-1106) == clip-path-ellipse-007.html clip-path-ellipse-001-ref.html
-fuzzy-if(webrender,64-64,1106-1106) == clip-path-ellipse-008.html clip-path-ellipse-001-ref.html
+fuzzy-if(webrender,36-36,1100-1100) == clip-path-ellipse-001.html clip-path-ellipse-001-ref.html
+fuzzy-if(webrender,36-36,1100-1100) == clip-path-ellipse-002.html clip-path-ellipse-001-ref.html
+fuzzy-if(webrender,36-36,1100-1100) == clip-path-ellipse-003.html clip-path-ellipse-001-ref.html
+fuzzy-if(webrender,36-36,1100-1100) == clip-path-ellipse-004.html clip-path-ellipse-001-ref.html
+fuzzy-if(webrender,36-36,1100-1100) == clip-path-ellipse-005.html clip-path-ellipse-001-ref.html
+fuzzy-if(webrender,36-36,1100-1100) == clip-path-ellipse-006.html clip-path-ellipse-001-ref.html
+fuzzy-if(webrender,36-36,1100-1100) == clip-path-ellipse-007.html clip-path-ellipse-001-ref.html
+fuzzy-if(webrender,36-36,1100-1100) == clip-path-ellipse-008.html clip-path-ellipse-001-ref.html
 
 == clip-path-inset-001a.html clip-path-inset-001-ref.html
 == clip-path-inset-001b.html clip-path-inset-001-ref.html
 == clip-path-inset-001c.html clip-path-inset-001-ref.html
 # Anti-aliasing behavior for masking and borders is different
 fuzzy-if(!webrender,0-64,0-146) == clip-path-inset-002a.html clip-path-inset-002-ref.html
 fuzzy-if(!webrender,0-64,0-146) == clip-path-inset-002b.html clip-path-inset-002-ref.html
 fuzzy-if(!webrender,0-64,0-146) == clip-path-inset-002c.html clip-path-inset-002-ref.html
--- a/layout/reftests/w3c-css/submitted/masking/reftest.list
+++ b/layout/reftests/w3c-css/submitted/masking/reftest.list
@@ -84,17 +84,17 @@ fails == mask-origin-2.html mask-origin-
 == mask-size-percent.html mask-size-percent-percent-ref.html
 == mask-size-percent-auto.html mask-size-percent-percent-ref.html
 == mask-size-percent-length.html mask-size-percent-percent-ref.html
 == mask-size-percent-percent.html mask-size-percent-percent-ref.html
 == mask-size-percent-percent-stretch.html mask-size-percent-percent-stretch-ref.html
 
 fuzzy-if(winWidget,0-1,0-21) fuzzy-if(skiaContent,0-1,0-60) fuzzy-if(webrender,0-64,0-371) == clip-path-contentBox-1a.html clip-path-geometryBox-1-ref.html
 fuzzy-if(winWidget,0-16,0-21) fuzzy-if(skiaContent,0-1,0-60) == clip-path-contentBox-1b.html clip-path-geometryBox-1-ref.html
-fuzzy-if(winWidget,0-16,0-21) fuzzy-if(skiaContent,0-1,0-60) fuzzy-if(webrender,64-64,371-371) == clip-path-contentBox-1c.html clip-path-geometryBox-1-ref.html
+fuzzy-if(winWidget,0-16,0-21) fuzzy-if(skiaContent,0-1,0-60) fuzzy-if(webrender,35-35,360-360) == clip-path-contentBox-1c.html clip-path-geometryBox-1-ref.html
 fuzzy-if(winWidget,0-16,0-21) fuzzy-if(skiaContent,0-1,0-60) fuzzy-if(webrender,0-64,0-371) == clip-path-paddingBox-1a.html clip-path-geometryBox-1-ref.html
 fuzzy-if(winWidget,0-16,0-21) fuzzy-if(skiaContent,0-1,0-60) == clip-path-paddingBox-1b.html clip-path-geometryBox-1-ref.html
 fuzzy-if(winWidget,0-16,0-21) fuzzy-if(skiaContent,0-1,0-60) fuzzy-if(webrender,0-64,0-371) == clip-path-paddingBox-1c.html clip-path-geometryBox-1-ref.html
 fuzzy(0-64,0-371) == clip-path-borderBox-1a.html clip-path-geometryBox-1-ref.html
 fuzzy-if(winWidget,0-16,0-21) fuzzy-if(skiaContent,0-1,0-60) == clip-path-borderBox-1b.html clip-path-geometryBox-1-ref.html
 fuzzy(0-64,0-371) == clip-path-borderBox-1c.html clip-path-geometryBox-1-ref.html
 fuzzy-if(winWidget,0-16,0-21) fuzzy-if(skiaContent,0-1,0-60) == clip-path-marginBox-1a.html clip-path-geometryBox-1-ref.html
 fuzzy(0-64,0-371) == clip-path-fillBox-1a.html clip-path-geometryBox-1-ref.html
--- a/modules/libpref/init/StaticPrefList.h
+++ b/modules/libpref/init/StaticPrefList.h
@@ -245,23 +245,16 @@ VARCACHE_PREF(
 // Time in milliseconds for PaymentResponse to wait for
 // the Web page to call complete().
 VARCACHE_PREF(
   "dom.payments.response.timeout",
    dom_payments_response_timeout,
   uint32_t, 5000
 )
 
-// Disable the ImageBitmap-extensions for now.
-VARCACHE_PREF(
-  "canvas.imagebitmap_extensions.enabled",
-   canvas_imagebitmap_extensions_enabled,
-  RelaxedAtomicBool, false
-)
-
 // SW Cache API
 VARCACHE_PREF(
   "dom.caches.enabled",
    dom_caches_enabled,
   RelaxedAtomicBool, true
 )
 
 VARCACHE_PREF(
--- a/taskcluster/ci/build/windows.yml
+++ b/taskcluster/ci/build/windows.yml
@@ -949,17 +949,17 @@ win32-mingwclang/opt:
         - mingw32-rust
         - linux64-upx
         - linux64-wine
         - linux64-sccache
         - linux64-cbindgen
         - linux64-node
         - linux64-clang-trunk-mingw-x86
         - linux64-mingw32-nsis
-        - linux64-mingw32-fxc2
+        - linux64-mingw-fxc2-x86
 
 win32-mingwclang/debug:
     description: "Win32 MinGW-Clang Debug"
     index:
         product: firefox
         job-name: win32-mingwclang-debug
     treeherder:
         platform: windows-mingw32/all
@@ -985,17 +985,17 @@ win32-mingwclang/debug:
         - mingw32-rust
         - linux64-upx
         - linux64-wine
         - linux64-sccache
         - linux64-cbindgen
         - linux64-node
         - linux64-clang-trunk-mingw-x86
         - linux64-mingw32-nsis
-        - linux64-mingw32-fxc2
+        - linux64-mingw-fxc2-x86
 
 win64-mingwclang/opt:
     description: "Win64 MinGW-Clang Opt"
     index:
         product: firefox
         job-name: win64-mingwclang-opt
     treeherder:
         platform: windows-mingw32/all
@@ -1021,17 +1021,17 @@ win64-mingwclang/opt:
         - mingw32-rust
         - linux64-upx
         - linux64-wine
         - linux64-sccache
         - linux64-cbindgen
         - linux64-node
         - linux64-clang-trunk-mingw-x64
         - linux64-mingw32-nsis
-        - linux64-mingw32-fxc2
+        - linux64-mingw-fxc2-x86
 
 win64-mingwclang/debug:
     description: "Win64 MinGW-Clang Debug"
     index:
         product: firefox
         job-name: win64-mingwclang-debug
     treeherder:
         platform: windows-mingw32/all
@@ -1057,9 +1057,9 @@ win64-mingwclang/debug:
         - mingw32-rust
         - linux64-upx
         - linux64-wine
         - linux64-sccache
         - linux64-cbindgen
         - linux64-node
         - linux64-clang-trunk-mingw-x64
         - linux64-mingw32-nsis
-        - linux64-mingw32-fxc2
+        - linux64-mingw-fxc2-x86
--- a/taskcluster/ci/test/test-platforms.yml
+++ b/taskcluster/ci/test/test-platforms.yml
@@ -304,37 +304,39 @@ android-em-4.2-x86/opt:
     test-sets:
         - android-x86-tests
 
 android-em-7.0-x86/opt:
     build-platform: android-x86/opt
     test-sets:
         - android-x86-kvm-tests
 
+# Bug 1501364 - Temporarily disable Bitbar android hardware tests
+
 # android-hw test platforms execute on real devices attached to Autophone hosts.
 
 # android-hw-g5-7-0 Motorola Moto G5 Android 7.0
 
-android-hw-g5-7-0-arm7-api-16/opt:
-    build-platform: android-api-16/opt
-    test-sets:
-        - android-hw-arm7-raptor
-        - raptor-fetch-geckoview
+# android-hw-g5-7-0-arm7-api-16/opt:
+#     build-platform: android-api-16/opt
+#     test-sets:
+#         - android-hw-arm7-raptor
+#         - raptor-fetch-geckoview
 
 # android-hw-p2-8-0 Google Pixel 2 Android 8.0
 
-android-hw-p2-8-0-arm7-api-16/opt:
-    build-platform: android-api-16/opt
-    test-sets:
-        - android-hw-arm7-opt-unittests
-        - android-hw-arm7-raptor
-        - raptor-fetch-geckoview
+# android-hw-p2-8-0-arm7-api-16/opt:
+#     build-platform: android-api-16/opt
+#     test-sets:
+#         - android-hw-arm7-opt-unittests
+#         - android-hw-arm7-raptor
+#         - raptor-fetch-geckoview
 
-android-hw-p2-8-0-arm7-api-16/debug:
-    build-platform: android-api-16/debug
-    test-sets:
-        - android-hw-arm7-debug-unittests
+# android-hw-p2-8-0-arm7-api-16/debug:
+#     build-platform: android-api-16/debug
+#     test-sets:
+#         - android-hw-arm7-debug-unittests
 
-android-hw-p2-8-0-android-aarch64/opt:
-    build-platform: android-aarch64/opt
-    test-sets:
-        - android-hw-aarch64-opt-unittests
-        - android-hw-aarch64-raptor
+# android-hw-p2-8-0-android-aarch64/opt:
+#     build-platform: android-aarch64/opt
+#     test-sets:
+#         - android-hw-aarch64-opt-unittests
+#         - android-hw-aarch64-raptor
--- a/taskcluster/ci/toolchain/linux.yml
+++ b/taskcluster/ci/toolchain/linux.yml
@@ -805,28 +805,29 @@ linux64-mingw32-nsis:
         script: build-mingw32-nsis.sh
         resources:
             - 'build/unix/build-gcc/build-gcc.sh'
             - 'taskcluster/scripts/misc/build-gcc-mingw32.sh'
         toolchain-artifact: public/build/nsis.tar.xz
     toolchains:
         - linux64-mingw32-gcc
 
-linux64-mingw32-fxc2:
-    description: "fxc2.exe build for MinGW32 Cross Compile"
+linux64-mingw-fxc2-x86:
+    description: "fxc2.exe x86 build for MinGW Cross Compile"
     treeherder:
         kind: build
         platform: toolchains/opt
-        symbol: TMW(mingw32-fxc2)
+        symbol: TMW(mingw-fxc2-x86)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
         docker-image: {in-tree: mingw32-build}
         max-run-time: 1800
     run:
         using: toolchain-script
-        script: build-mingw32-fxc2.sh
+        script: build-mingw-fxc2-x86.sh
         resources:
-            - 'build/unix/build-gcc/build-gcc.sh'
-            - 'taskcluster/scripts/misc/build-gcc-mingw32.sh'
+            - 'build/build-clang/build-clang.py'
+            - 'build/build-clang/clang-trunk-mingw.json'
+            - 'taskcluster/scripts/misc/build-clang-trunk-mingw.sh'
         toolchain-artifact: public/build/fxc2.tar.xz
     toolchains:
-        - linux64-mingw32-gcc
+        - linux64-clang-trunk-mingw-x86
--- a/taskcluster/scripts/misc/build-clang-trunk-mingw.sh
+++ b/taskcluster/scripts/misc/build-clang-trunk-mingw.sh
@@ -27,17 +27,17 @@ UPLOAD_DIR=$HOME/artifacts
 
 TOOLCHAIN_DIR=$WORKSPACE/moz-toolchain
 INSTALL_DIR=$TOOLCHAIN_DIR/build/stage3/clang
 CROSS_PREFIX_DIR=$INSTALL_DIR/$machine-w64-mingw32
 SRC_DIR=$TOOLCHAIN_DIR/src
 
 make_flags="-j$(nproc)"
 
-mingw_version=cfd85ebed773810429bf2164c3a985895b7dbfe3
+mingw_version=c69c7a706d767c5ca3c7d1c70887fcd8e1f940b3
 libunwind_version=1f89d78bb488bc71cfdee8281fc0834e9fbe5dce
 
 binutils_version=2.27
 binutils_ext=bz2
 binutils_sha=369737ce51587f92466041a97ab7d2358c6d9e1b6490b3940eb09fb0a9a6ac88
 
 # This is default value of _WIN32_WINNT. Gecko configure script explicitly sets this,
 # so this is not used to build Gecko itself. We default to 0x600, which is Windows Vista.
rename from taskcluster/scripts/misc/build-mingw32-fxc2.sh
rename to taskcluster/scripts/misc/build-mingw-fxc2-x86.sh
--- a/taskcluster/scripts/misc/build-mingw32-fxc2.sh
+++ b/taskcluster/scripts/misc/build-mingw-fxc2-x86.sh
@@ -6,30 +6,29 @@ HOME_DIR=$WORKSPACE/build
 INSTALL_DIR=$WORKSPACE/fxc2
 TOOLTOOL_DIR=$WORKSPACE/build/src
 UPLOAD_DIR=$HOME/artifacts
 
 mkdir -p $INSTALL_DIR/bin
 
 cd $TOOLTOOL_DIR
 . taskcluster/scripts/misc/tooltool-download.sh
-export PATH="$TOOLTOOL_DIR/mingw32/bin:$PATH"
+export PATH="$TOOLTOOL_DIR/clang/bin:$PATH"
 
 cd $WORKSPACE
 
 # --------------
 
-git clone -n https://github.com/mozilla/fxc2.git fxc2-clone
+git clone -n https://github.com/tomrittervg/fxc2.git fxc2-clone
 cd fxc2-clone
-git checkout 82527b81104e5e21390d3ddcd328700c67ce73d4 # Asserts integrity of the clone (right?)
-make -j$(nproc)
+git checkout 502ef40807a472ba845f1cbdeac95ecab1aea2fd # Asserts integrity of the clone (right?)
+make -j$(nproc) x86
 
 cp fxc2.exe $INSTALL_DIR/bin/
-cp d3dcompiler_47.dll $INSTALL_DIR/bin/
-cp $TOOLTOOL_DIR/mingw32/i686-w64-mingw32/bin/libwinpthread-1.dll $INSTALL_DIR/bin/
+cp dll/d3dcompiler_47_32.dll $INSTALL_DIR/bin/d3dcompiler_47.dll
 
 # --------------
 
 cd $WORKSPACE
 tar caf fxc2.tar.xz fxc2
 
 mkdir -p $UPLOAD_DIR
 cp fxc2.tar.* $UPLOAD_DIR
--- a/taskcluster/scripts/misc/build-wine.sh
+++ b/taskcluster/scripts/misc/build-wine.sh
@@ -12,20 +12,19 @@ root_dir=$HOME_DIR
 data_dir=$HOME_DIR/src/build/unix/build-gcc
 
 . $data_dir/download-tools.sh
 
 cd $WORKSPACE
 
 # --------------
 $GPG --import $data_dir/DA23579A74D4AD9AF9D3F945CEFAC8EAAF17519D.key
-
-download_and_check http://dl.winehq.org/wine/source/2.0/ wine-2.0.1.tar.xz.sign
-tar xaf $TMPDIR/wine-2.0.1.tar.xz
-cd wine-2.0.1
+download_and_check http://dl.winehq.org/wine/source/3.0/ wine-3.0.3.tar.xz.sign
+tar xaf $TMPDIR/wine-3.0.3.tar.xz
+cd wine-3.0.3
 ./configure --prefix=$INSTALL_DIR/
 make -j$(nproc)
 make install
 
 # --------------
 
 cd $WORKSPACE/
 tar caf wine.tar.xz wine
--- a/testing/web-platform/meta/2dcontext/imagebitmap/createImageBitmap-invalid-args.html.ini
+++ b/testing/web-platform/meta/2dcontext/imagebitmap/createImageBitmap-invalid-args.html.ini
@@ -1,88 +1,34 @@
 [createImageBitmap-invalid-args.html]
-  [createImageBitmap with an oversized canvas source rejects with a RangeError.]
-    expected: FAIL
-
-  [createImageBitmap with an invalid OffscreenCanvas source rejects with a RangeError.]
-    expected: FAIL
-
-  [createImageBitmap with a broken image source rejects with an InvalidStateError.]
-    expected: FAIL
-
-  [createImageBitmap with an available but undecodable image source rejects with an InvalidStateError.]
-    expected: FAIL
-
-  [createImageBitmap with an HTMLCanvasElement source and oversized (unallocatable) crop region]
-    expected: FAIL
-
-  [createImageBitmap with an HTMLVideoElement source and oversized (unallocatable) crop region]
-    expected: FAIL
-
-  [createImageBitmap with an HTMLImageElement source and sw set to 0]
-    expected: FAIL
-
-  [createImageBitmap with an HTMLImageElement source and oversized (unallocatable) crop region]
-    expected: FAIL
-
   [createImageBitmap with an OffscreenCanvas source and sw set to 0]
     expected: FAIL
 
   [createImageBitmap with an OffscreenCanvas source and sh set to 0]
     expected: FAIL
 
   [createImageBitmap with an OffscreenCanvas source and oversized (unallocatable) crop region]
     expected: FAIL
 
-  [createImageBitmap with an ImageData source and oversized (unallocatable) crop region]
-    expected: FAIL
-
-  [createImageBitmap with an ImageBitmap source and oversized (unallocatable) crop region]
-    expected: FAIL
-
-  [createImageBitmap with an oversized canvas source.]
-    expected: FAIL
-
   [createImageBitmap with an invalid OffscreenCanvas source.]
     expected: FAIL
 
   [createImageBitmap with a broken image source.]
     expected: FAIL
 
   [createImageBitmap with an available but undecodable image source.]
     expected: FAIL
 
-  [createImageBitmap with a closed ImageBitmap.]
-    expected: FAIL
-
-  [createImageBitmap with a bitmap HTMLImageElement source and oversized (unallocatable) crop region]
-    expected: FAIL
-
   [createImageBitmap with a bitmap SVGImageElement source and sw set to 0]
     expected: FAIL
 
   [createImageBitmap with a bitmap SVGImageElement source and sh set to 0]
     expected: FAIL
 
-  [createImageBitmap with a bitmap SVGImageElement source and oversized (unallocatable) crop region]
-    expected: FAIL
-
   [createImageBitmap with a vector SVGImageElement source and sw set to 0]
     expected: FAIL
 
   [createImageBitmap with a vector SVGImageElement source and sh set to 0]
     expected: FAIL
 
-  [createImageBitmap with a vector SVGImageElement source and oversized (unallocatable) crop region]
-    expected: FAIL
-
   [createImageBitmap with CanvasRenderingContext2D image source.]
     expected: FAIL
 
-  [createImageBitmap with Uint8Array image source.]
-    expected: FAIL
-
-  [createImageBitmap with ArrayBuffer image source.]
-    expected: FAIL
-
-  [createImageBitmap with an HTMLVideoElement from a data URL source and oversized (unallocatable) crop region]
-    expected: FAIL
-
--- a/testing/web-platform/meta/css/css-masking/clip-path/clip-path-circle-001.html.ini
+++ b/testing/web-platform/meta/css/css-masking/clip-path/clip-path-circle-001.html.ini
@@ -1,2 +1,3 @@
 [clip-path-circle-001.html]
-  expected: FAIL
+  expected:
+    if not webrender: FAIL
--- a/testing/web-platform/meta/css/css-masking/clip-path/clip-path-circle-002.html.ini
+++ b/testing/web-platform/meta/css/css-masking/clip-path/clip-path-circle-002.html.ini
@@ -1,2 +1,3 @@
 [clip-path-circle-002.html]
-  expected: FAIL
+  expected:
+    if not webrender: FAIL
--- a/testing/web-platform/meta/css/css-masking/clip-path/clip-path-circle-003.html.ini
+++ b/testing/web-platform/meta/css/css-masking/clip-path/clip-path-circle-003.html.ini
@@ -1,2 +1,3 @@
 [clip-path-circle-003.html]
-  expected: FAIL
+  expected:
+    if not webrender: FAIL
--- a/testing/web-platform/meta/css/css-masking/clip-path/clip-path-circle-004.html.ini
+++ b/testing/web-platform/meta/css/css-masking/clip-path/clip-path-circle-004.html.ini
@@ -1,2 +1,3 @@
 [clip-path-circle-004.html]
-  expected: FAIL
+  expected:
+    if not webrender: FAIL
--- a/testing/web-platform/meta/css/css-masking/clip-path/clip-path-circle-005.html.ini
+++ b/testing/web-platform/meta/css/css-masking/clip-path/clip-path-circle-005.html.ini
@@ -1,2 +1,3 @@
 [clip-path-circle-005.html]
-  expected: FAIL
+  expected:
+    if not webrender: FAIL
--- a/testing/web-platform/meta/css/css-masking/clip-path/clip-path-circle-006.html.ini
+++ b/testing/web-platform/meta/css/css-masking/clip-path/clip-path-circle-006.html.ini
@@ -1,2 +1,3 @@
 [clip-path-circle-006.html]
-  expected: FAIL
+  expected:
+    if not webrender: FAIL
--- a/testing/web-platform/meta/css/css-masking/clip-path/clip-path-circle-007.html.ini
+++ b/testing/web-platform/meta/css/css-masking/clip-path/clip-path-circle-007.html.ini
@@ -1,2 +1,3 @@
 [clip-path-circle-007.html]
-  expected: FAIL
+  expected:
+    if not webrender: FAIL
--- a/testing/web-platform/meta/css/css-masking/clip-path/clip-path-circle-008.html.ini
+++ b/testing/web-platform/meta/css/css-masking/clip-path/clip-path-circle-008.html.ini
@@ -1,2 +1,3 @@
 [clip-path-circle-008.html]
-  expected: FAIL
+  expected:
+    if not webrender: FAIL
--- a/testing/web-platform/meta/css/css-masking/clip-path/clip-path-ellipse-001.html.ini
+++ b/testing/web-platform/meta/css/css-masking/clip-path/clip-path-ellipse-001.html.ini
@@ -1,10 +1,3 @@
 [clip-path-ellipse-001.html]
   expected:
-    if webrender: FAIL
-    if os == "linux": FAIL
-    if debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
-    if debug and not webrender and e10s and (os == "win") and (version == "10.0.15063") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and not webrender and e10s and (os == "win") and (version == "10.0.15063") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
-    if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+    if not webrender: FAIL
--- a/testing/web-platform/meta/css/css-masking/clip-path/clip-path-ellipse-002.html.ini
+++ b/testing/web-platform/meta/css/css-masking/clip-path/clip-path-ellipse-002.html.ini
@@ -1,11 +1,3 @@
 [clip-path-ellipse-002.html]
   expected:
-    if debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
-    if os == "linux": FAIL
-    if debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
-    if debug and not webrender and e10s and (os == "win") and (version == "10.0.15063") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and not webrender and e10s and (os == "win") and (version == "10.0.15063") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
-    if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+    if not webrender: FAIL
--- a/testing/web-platform/meta/css/css-masking/clip-path/clip-path-ellipse-003.html.ini
+++ b/testing/web-platform/meta/css/css-masking/clip-path/clip-path-ellipse-003.html.ini
@@ -1,11 +1,3 @@
 [clip-path-ellipse-003.html]
   expected:
-    if debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
-    if os == "linux": FAIL
-    if debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
-    if debug and not webrender and e10s and (os == "win") and (version == "10.0.15063") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and not webrender and e10s and (os == "win") and (version == "10.0.15063") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
-    if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+    if not webrender: FAIL
--- a/testing/web-platform/meta/css/css-masking/clip-path/clip-path-ellipse-004.html.ini
+++ b/testing/web-platform/meta/css/css-masking/clip-path/clip-path-ellipse-004.html.ini
@@ -1,11 +1,3 @@
 [clip-path-ellipse-004.html]
   expected:
-    if debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
-    if os == "linux": FAIL
-    if debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
-    if debug and not webrender and e10s and (os == "win") and (version == "10.0.15063") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and not webrender and e10s and (os == "win") and (version == "10.0.15063") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
-    if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+    if not webrender: FAIL
--- a/testing/web-platform/meta/css/css-masking/clip-path/clip-path-ellipse-005.html.ini
+++ b/testing/web-platform/meta/css/css-masking/clip-path/clip-path-ellipse-005.html.ini
@@ -1,11 +1,3 @@
 [clip-path-ellipse-005.html]
   expected:
-    if debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
-    if os == "linux": FAIL
-    if debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
-    if debug and not webrender and e10s and (os == "win") and (version == "10.0.15063") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and not webrender and e10s and (os == "win") and (version == "10.0.15063") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
-    if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+    if not webrender: FAIL
--- a/testing/web-platform/meta/css/css-masking/clip-path/clip-path-ellipse-006.html.ini
+++ b/testing/web-platform/meta/css/css-masking/clip-path/clip-path-ellipse-006.html.ini
@@ -1,11 +1,3 @@
 [clip-path-ellipse-006.html]
   expected:
-    if debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
-    if os == "linux": FAIL
-    if debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
-    if debug and not webrender and e10s and (os == "win") and (version == "10.0.15063") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and not webrender and e10s and (os == "win") and (version == "10.0.15063") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
-    if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+    if not webrender: FAIL
--- a/testing/web-platform/meta/css/css-masking/clip-path/clip-path-ellipse-007.html.ini
+++ b/testing/web-platform/meta/css/css-masking/clip-path/clip-path-ellipse-007.html.ini
@@ -1,11 +1,3 @@
 [clip-path-ellipse-007.html]
   expected:
-    if debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
-    if os == "linux": FAIL
-    if debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
-    if debug and not webrender and e10s and (os == "win") and (version == "10.0.15063") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and not webrender and e10s and (os == "win") and (version == "10.0.15063") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
-    if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+    if not webrender: FAIL
--- a/testing/web-platform/meta/css/css-masking/clip-path/clip-path-ellipse-008.html.ini
+++ b/testing/web-platform/meta/css/css-masking/clip-path/clip-path-ellipse-008.html.ini
@@ -1,11 +1,3 @@
 [clip-path-ellipse-008.html]
   expected:
-    if debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL
-    if os == "linux": FAIL
-    if debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
-    if debug and not webrender and e10s and (os == "win") and (version == "10.0.15063") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and not webrender and e10s and (os == "win") and (version == "10.0.15063") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
-    if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
+    if not webrender: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/2dcontext/imagebitmap/createImageBitmap-blob-invalidtype.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<title>createImageBitmap: blob with wrong mime type</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<script>
+promise_test(t => {
+  // Source: https://commons.wikimedia.org/wiki/File:1x1.png (Public Domain)
+  const IMAGE = atob("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAA" +
+                     "ACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=");
+
+  let bytes = new Array(IMAGE.length);
+  for (let i = 0; i < IMAGE.length; i++) {
+    bytes[i] = IMAGE.charCodeAt(i);
+  }
+
+  let blob = new Blob([new Uint8Array(bytes)], { type: "text/html"});
+
+  return window.createImageBitmap(blob)
+    .then(imageBitmap => {
+      assert_true(true, "Image created!");
+      assert_equals(imageBitmap.width, 1, "Image is 1x1");
+      assert_equals(imageBitmap.height, 1, "Image is 1x1");
+    });
+});
+</script>
--- a/testing/web-platform/tests/2dcontext/imagebitmap/createImageBitmap-invalid-args.html
+++ b/testing/web-platform/tests/2dcontext/imagebitmap/createImageBitmap-invalid-args.html
@@ -60,27 +60,33 @@ testCases = [
     description: 'createImageBitmap with <sourceType> source and sh set to 0',
     promiseTestFunction:
       (source, t) => {
         return promise_rejects(t, new RangeError(),
             createImageBitmap(source, 0, 0, 10, 0));
       }
   },
   {
-    // This case is not explicitly documented in the specification for
-    // createImageBitmap, but it is expected that internal failures cause
-    // InvalidStateError.
-    //
-    // Note: https://bugs.chromium.org/p/chromium/issues/detail?id=799025
     description: 'createImageBitmap with <sourceType> source and oversized ' +
         '(unallocatable) crop region',
     promiseTestFunction:
       (source, t) => {
-        return promise_rejects(t, new DOMException('', 'InvalidStateError'),
-            createImageBitmap(source, 0, 0, 100000000, 100000000));
+        return createImageBitmap(source, 0, 0, 100000000, 100000000)
+          .then(i => {
+            assert_equals(i.width, 100000000);
+            assert_equals(i.height, 100000000);
+          })
+          .catch(e => {
+            // This case is not explicitly documented in the specification for
+            // createImageBitmap, but it is expected that internal failures
+            // cause InvalidStateError.
+            //
+            // Note: https://bugs.chromium.org/p/chromium/issues/detail?id=799025
+            assert_throws(e, function() { throw e }, new DOMException('', 'InvalidStateError'));
+          });
       }
   },
 ];
 
 // Generate the test matrix for each sourceType + testCase combo.
 imageSourceTypes.forEach(imageSourceType => {
   testCases.forEach(testCase => {
     let description = testCase.description.replace('<sourceType>',
--- a/toolkit/mozapps/update/updater/macbuild/Contents/Info.plist.in
+++ b/toolkit/mozapps/update/updater/macbuild/Contents/Info.plist.in
@@ -1,41 +1,38 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <plist version="1.0">
 <dict>
 	<key>CFBundleDevelopmentRegion</key>
 	<string>English</string>
+	<key>CFBundleDisplayName</key>
+	<string>updater</string>
 	<key>CFBundleExecutable</key>
 	<string>org.mozilla.updater</string>
 	<key>CFBundleIconFile</key>
 	<string>updater.icns</string>
 	<key>CFBundleIdentifier</key>
 	<string>org.mozilla.updater</string>
 	<key>CFBundleInfoDictionaryVersion</key>
 	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>updater</string>
 	<key>CFBundlePackageType</key>
 	<string>APPL</string>
 	<key>CFBundleSignature</key>
 	<string>????</string>
 	<key>CFBundleVersion</key>
 	<string>1.0</string>
+	<key>LSHasLocalizedDisplayName</key>
+	<true/>
 	<key>NSMainNibFile</key>
 	<string>MainMenu</string>
 	<key>NSPrincipalClass</key>
 	<string>NSApplication</string>
-	<key>LSMinimumSystemVersion</key>
-	<string>10.5</string>
-	<key>LSMinimumSystemVersionByArchitecture</key>
-	<dict>
-		<key>i386</key>
-		<string>10.5.0</string>
-		<key>x86_64</key>
-		<string>10.6.0</string>
-	</dict>
 	<key>LSUIElement</key>
 	<true/>
 	<key>SMAuthorizedClients</key>
 	<array>
 		<string>identifier "%MOZ_MACBUNDLE_ID%" and ((anchor apple generic and certificate leaf[field.1.2.840.113635.100.6.1.9]) or (anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] and certificate leaf[field.1.2.840.113635.100.6.1.13] and certificate leaf[subject.OU] = "43AQ936H96"))</string>
 	</array>
 </dict>
 </plist>
--- a/toolkit/mozapps/update/updater/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in
+++ b/toolkit/mozapps/update/updater/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in
@@ -1,7 +1,8 @@
 /* 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/. */
 
 /* Localized versions of Info.plist keys */
 
-CFBundleName = "%APP_NAME% Software Update";
+CFBundleName = "Software Update";
+CFBundleDisplayName = "%APP_NAME% Software Update";