merge mozilla-inbound to mozilla-central a=merge
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Mon, 26 Jan 2015 14:09:03 +0100
changeset 225642 4368f39456904bcfe89e0829046489d87b1511b6
parent 225624 5d635f799d9067c24ed09b374bbc3d56815a7b54 (current diff)
parent 225641 5f52e0321f3c85b9bd37d0ebb635a7b214f3e30c (diff)
child 225643 95c76c3b01726526eb9ff8152c8d3f8c94a86006
push id10990
push usercbook@mozilla.com
push dateMon, 26 Jan 2015 14:06:38 +0000
treeherderfx-team@54be9bcdacd9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone38.0a1
merge mozilla-inbound to mozilla-central a=merge
mfbt/TypedEnum.h
mfbt/TypedEnumInternal.h
--- a/accessible/base/RelationType.h
+++ b/accessible/base/RelationType.h
@@ -2,18 +2,16 @@
 /* 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/. */
 
 #ifndef mozilla_a11y_relationtype_h_
 #define mozilla_a11y_relationtype_h_
 
-#include "mozilla/TypedEnum.h"
-
 namespace mozilla {
 namespace a11y {
 
 enum class RelationType {
 
   /**
    * This object is labelled by a target object.
    */
--- a/browser/devtools/app-manager/app-projects.js
+++ b/browser/devtools/app-manager/app-projects.js
@@ -79,16 +79,18 @@ const IDB = {
     };
 
     return deferred.promise;
   },
 
   add: function(project) {
     let deferred = promise.defer();
 
+    project = JSON.parse(JSON.stringify(project));
+
     if (!project.location) {
       // We need to make sure this object has a `.location` property.
       deferred.reject("Missing location property on project object.");
     } else {
       let transaction = IDB._db.transaction(["projects"], "readwrite");
       let objectStore = transaction.objectStore("projects");
       let request = objectStore.add(project);
       request.onerror = function(event) {
--- a/configure.in
+++ b/configure.in
@@ -47,17 +47,17 @@ dnl ====================================
 _SUBDIR_HOST_LDFLAGS="$HOST_LDFLAGS"
 _SUBDIR_CONFIG_ARGS="$ac_configure_args"
 
 dnl Set the version number of the libs included with mozilla
 dnl ========================================================
 MOZJPEG=62
 MOZPNG=10616
 NSPR_VERSION=4
-NSPR_MINVER=4.10.3
+NSPR_MINVER=4.10.8
 NSS_VERSION=3
 
 dnl Set the minimum version of toolkit libs used by mozilla
 dnl ========================================================
 GLIB_VERSION=1.2.0
 PERL_VERSION=5.006
 CAIRO_VERSION=1.10
 PANGO_VERSION=1.22.0
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -4708,17 +4708,33 @@ nsDocument::SetScriptGlobalObject(nsIScr
     SendToConsole(messages);
   }
 
   // Set our visibility state, but do not fire the event.  This is correct
   // because either we're coming out of bfcache (in which case IsVisible() will
   // still test false at this point and no state change will happen) or we're
   // doing the initial document load and don't want to fire the event for this
   // change.
+  dom::VisibilityState oldState = mVisibilityState;
   mVisibilityState = GetVisibilityState();
+  // When the visibility is changed, notify it to observers.
+  // Some observers need the notification, for example HTMLMediaElement uses
+  // it to update internal media resource allocation.
+  // When video is loaded via VideoDocument, HTMLMediaElement and MediaDecoder
+  // creation are already done before nsDocument::SetScriptGlobalObject() call.
+  // MediaDecoder decides whether starting decoding is decided based on
+  // document's visibility. When the MediaDecoder is created,
+  // nsDocument::SetScriptGlobalObject() is not yet called and document is
+  // hidden state. Therefore the MediaDecoder decides that decoding is
+  // not yet necessary. But soon after nsDocument::SetScriptGlobalObject()
+  // call, the document becomes not hidden. At the time, MediaDecoder needs
+  // to know it and needs to start updating decoding.
+  if (oldState != mVisibilityState) {
+    EnumerateActivityObservers(NotifyActivityChanged, nullptr);
+  }
 
   // The global in the template contents owner document should be the same.
   if (mTemplateContentsOwner && mTemplateContentsOwner != this) {
     mTemplateContentsOwner->SetScriptGlobalObject(aScriptGlobalObject);
   }
 
   nsCOMPtr<nsIChannel> channel = GetChannel();
   if (!mMaybeServiceWorkerControlled && channel) {
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -8435,20 +8435,20 @@ class CGEnum(CGThing):
         return self.enum.identifier.name + "Values"
 
     def nEnumStrings(self):
         return len(self.enum.values()) + 1
 
     def declare(self):
         decl = fill(
             """
-            MOZ_BEGIN_ENUM_CLASS(${name}, uint32_t)
+            enum class ${name} : uint32_t {
               $*{enums}
               EndGuard_
-            MOZ_END_ENUM_CLASS(${name})
+            };
             """,
             name=self.enum.identifier.name,
             enums=",\n".join(map(getEnumValueName, self.enum.values())) + ",\n")
         strings = CGNamespace(self.stringsNamespace(),
                               CGGeneric(declare="extern const EnumEntry %s[%d];\n"
                                         % (ENUM_ENTRY_VARIABLE_NAME, self.nEnumStrings())))
         return decl + "\n" + strings.declare()
 
--- a/dom/canvas/CanvasGradient.h
+++ b/dom/canvas/CanvasGradient.h
@@ -18,20 +18,20 @@ namespace mozilla {
 namespace dom {
 
 class CanvasGradient : public nsWrapperCache
 {
 public:
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(CanvasGradient)
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(CanvasGradient)
 
-  MOZ_BEGIN_NESTED_ENUM_CLASS(Type, uint8_t)
+  enum class Type : uint8_t {
     LINEAR = 0,
     RADIAL
-  MOZ_END_NESTED_ENUM_CLASS(Type)
+  };
 
   Type GetType()
   {
     return mType;
   }
 
   mozilla::gfx::GradientStops *
   GetGradientStopsForTarget(mozilla::gfx::DrawTarget *aRT)
@@ -70,14 +70,12 @@ protected:
 
   nsRefPtr<CanvasRenderingContext2D> mContext;
   nsTArray<mozilla::gfx::GradientStop> mRawStops;
   mozilla::RefPtr<mozilla::gfx::GradientStops> mStops;
   Type mType;
   virtual ~CanvasGradient() {}
 };
 
-MOZ_FINISH_NESTED_ENUM_CLASS(CanvasGradient::Type)
-
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_CanvasGradient_h
--- a/dom/canvas/CanvasPattern.h
+++ b/dom/canvas/CanvasPattern.h
@@ -24,22 +24,22 @@ class SVGMatrix;
 
 class CanvasPattern MOZ_FINAL : public nsWrapperCache
 {
   ~CanvasPattern() {}
 public:
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(CanvasPattern)
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(CanvasPattern)
 
-  MOZ_BEGIN_NESTED_ENUM_CLASS(RepeatMode, uint8_t)
+  enum class RepeatMode : uint8_t {
     REPEAT,
     REPEATX,
     REPEATY,
     NOREPEAT
-  MOZ_END_NESTED_ENUM_CLASS(RepeatMode)
+  };
 
   CanvasPattern(CanvasRenderingContext2D* aContext,
                 gfx::SourceSurface* aSurface,
                 RepeatMode aRepeat,
                 nsIPrincipal* principalForSecurityCheck,
                 bool forceWriteOnly,
                 bool CORSUsed)
     : mContext(aContext)
@@ -69,14 +69,12 @@ public:
   RefPtr<gfx::SourceSurface> mSurface;
   nsCOMPtr<nsIPrincipal> mPrincipal;
   mozilla::gfx::Matrix mTransform;
   const bool mForceWriteOnly;
   const bool mCORSUsed;
   const RepeatMode mRepeat;
 };
 
-MOZ_FINISH_NESTED_ENUM_CLASS(CanvasPattern::RepeatMode)
-
 }
 }
 
 #endif // mozilla_dom_CanvasPattern_h
--- a/dom/canvas/CanvasRenderingContext2D.h
+++ b/dom/canvas/CanvasRenderingContext2D.h
@@ -538,27 +538,27 @@ public:
   // this rect is in mTarget's current user space
   void RedrawUser(const gfxRect &r);
 
   // nsISupports interface + CC
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(CanvasRenderingContext2D)
 
-  MOZ_BEGIN_NESTED_ENUM_CLASS(CanvasMultiGetterType, uint8_t)
+  enum class CanvasMultiGetterType : uint8_t {
     STRING = 0,
     PATTERN = 1,
     GRADIENT = 2
-  MOZ_END_NESTED_ENUM_CLASS(CanvasMultiGetterType)
+  };
 
-  MOZ_BEGIN_NESTED_ENUM_CLASS(Style, uint8_t)
+  enum class Style : uint8_t {
     STROKE = 0,
     FILL,
     MAX
-  MOZ_END_NESTED_ENUM_CLASS(Style)
+  };
 
   nsINode* GetParentObject()
   {
     return mCanvasElement;
   }
 
   void LineTo(const mozilla::gfx::Point& aPoint)
   {
@@ -886,41 +886,39 @@ protected:
       return mozilla::gfx::CompositionOp::OP_OVER;
     }
 
     return CurrentState().op;
   }
 
   // text
 
-public: // These enums are public only to accomodate non-C++11 legacy path of
-        // MOZ_FINISH_NESTED_ENUM_CLASS. Can move back to protected as soon
-        // as that legacy path is dropped.
-  MOZ_BEGIN_NESTED_ENUM_CLASS(TextAlign, uint8_t)
+protected:
+  enum class TextAlign : uint8_t {
     START,
     END,
     LEFT,
     RIGHT,
     CENTER
-  MOZ_END_NESTED_ENUM_CLASS(TextAlign)
+  };
 
-  MOZ_BEGIN_NESTED_ENUM_CLASS(TextBaseline, uint8_t)
+  enum class TextBaseline : uint8_t {
     TOP,
     HANGING,
     MIDDLE,
     ALPHABETIC,
     IDEOGRAPHIC,
     BOTTOM
-  MOZ_END_NESTED_ENUM_CLASS(TextBaseline)
+  };
 
-  MOZ_BEGIN_NESTED_ENUM_CLASS(TextDrawOperation, uint8_t)
+  enum class TextDrawOperation : uint8_t {
     FILL,
     STROKE,
     MEASURE
-  MOZ_END_NESTED_ENUM_CLASS(TextDrawOperation)
+  };
 
 protected:
   gfxFontGroup *GetCurrentFontStyle();
 
   /*
     * Implementation of the fillText, strokeText, and measure functions with
     * the operation abstracted to a flag.
     */
@@ -1099,18 +1097,12 @@ protected:
     if (perCSSPixel)
       *perCSSPixel = cssPixel;
   }
 
   friend struct CanvasBidiProcessor;
   friend class CanvasDrawObserver;
 };
 
-MOZ_FINISH_NESTED_ENUM_CLASS(CanvasRenderingContext2D::CanvasMultiGetterType)
-MOZ_FINISH_NESTED_ENUM_CLASS(CanvasRenderingContext2D::Style)
-MOZ_FINISH_NESTED_ENUM_CLASS(CanvasRenderingContext2D::TextAlign)
-MOZ_FINISH_NESTED_ENUM_CLASS(CanvasRenderingContext2D::TextBaseline)
-MOZ_FINISH_NESTED_ENUM_CLASS(CanvasRenderingContext2D::TextDrawOperation)
-
 }
 }
 
 #endif /* CanvasRenderingContext2D_h */
--- a/dom/canvas/WebGLTexelConversions.cpp
+++ b/dom/canvas/WebGLTexelConversions.cpp
@@ -32,17 +32,17 @@ class WebGLImageConverter
     bool mAlreadyRun;
     bool mSuccess;
 
     /*
      * Returns sizeof(texel)/sizeof(type). The point is that we will iterate over
      * texels with typed pointers and this value will tell us by how much we need
      * to increment these pointers to advance to the next texel.
      */
-    template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format>
+    template<WebGLTexelFormat Format>
     static size_t NumElementsPerTexelForFormat() {
         switch (Format) {
             case WebGLTexelFormat::R8:
             case WebGLTexelFormat::A8:
             case WebGLTexelFormat::R16F:
             case WebGLTexelFormat::A16F:
             case WebGLTexelFormat::R32F:
             case WebGLTexelFormat::A32F:
@@ -73,19 +73,19 @@ class WebGLImageConverter
     /*
      * This is the completely format-specific templatized conversion function,
      * that will be instantiated hundreds of times for all different combinations.
      * It is important to avoid generating useless code here. In particular, many
      * instantiations of this function template will never be called, so we try
      * to return immediately in these cases to allow the compiler to avoid generating
      * useless code.
      */
-    template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) SrcFormat,
-             MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) DstFormat,
-             MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelPremultiplicationOp) PremultiplicationOp>
+    template<WebGLTexelFormat SrcFormat,
+             WebGLTexelFormat DstFormat,
+             WebGLTexelPremultiplicationOp PremultiplicationOp>
     void run()
     {
         // check for never-called cases. We early-return to allow the compiler
         // to avoid generating this code. It would be tempting to abort() instead,
         // as returning early does leave the destination surface with uninitialized
         // data, but that would not allow the compiler to avoid generating this code.
         // So instead, we return early, so Success() will return false, and the caller
         // must check that and abort in that case. See WebGLContext::ConvertImage.
@@ -146,19 +146,19 @@ class WebGLImageConverter
 
         typedef
             typename DataTypeForFormat<SrcFormat>::Type
             SrcType;
         typedef
             typename DataTypeForFormat<DstFormat>::Type
             DstType;
 
-        const MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) IntermediateSrcFormat
+        const WebGLTexelFormat IntermediateSrcFormat
             = IntermediateFormat<SrcFormat>::Value;
-        const MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) IntermediateDstFormat
+        const WebGLTexelFormat IntermediateDstFormat
             = IntermediateFormat<DstFormat>::Value;
         typedef
             typename DataTypeForFormat<IntermediateSrcFormat>::Type
             IntermediateSrcType;
         typedef
             typename DataTypeForFormat<IntermediateDstFormat>::Type
             IntermediateDstType;
 
@@ -213,18 +213,18 @@ class WebGLImageConverter
             srcRowStart += srcStrideInElements;
             dstRowStart += dstStrideInElements;
         }
 
         mSuccess = true;
         return;
     }
 
-    template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) SrcFormat,
-             MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) DstFormat>
+    template<WebGLTexelFormat SrcFormat,
+             WebGLTexelFormat DstFormat>
     void run(WebGLTexelPremultiplicationOp premultiplicationOp)
     {
         #define WEBGLIMAGECONVERTER_CASE_PREMULTIPLICATIONOP(PremultiplicationOp) \
             case PremultiplicationOp: \
                 return run<SrcFormat, DstFormat, PremultiplicationOp>();
 
         switch (premultiplicationOp) {
             WEBGLIMAGECONVERTER_CASE_PREMULTIPLICATIONOP(WebGLTexelPremultiplicationOp::None)
@@ -232,17 +232,17 @@ class WebGLImageConverter
             WEBGLIMAGECONVERTER_CASE_PREMULTIPLICATIONOP(WebGLTexelPremultiplicationOp::Unpremultiply)
             default:
                 MOZ_ASSERT(false, "unhandled case. Coding mistake?");
         }
 
         #undef WEBGLIMAGECONVERTER_CASE_PREMULTIPLICATIONOP
     }
 
-    template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) SrcFormat>
+    template<WebGLTexelFormat SrcFormat>
     void run(WebGLTexelFormat dstFormat,
              WebGLTexelPremultiplicationOp premultiplicationOp)
     {
         #define WEBGLIMAGECONVERTER_CASE_DSTFORMAT(DstFormat) \
             case DstFormat: \
                 return run<SrcFormat, DstFormat>(premultiplicationOp);
 
         switch (dstFormat) {
--- a/dom/canvas/WebGLTexelConversions.h
+++ b/dom/canvas/WebGLTexelConversions.h
@@ -142,86 +142,86 @@ unpackFromFloat16(uint16_t v)
     }
 
     f32Bits |= uint32_t(exp + (-15 + 127)) << 23;
     f32Bits |= uint32_t(v & 0x03FF) << 13;
 
     return f32Value;
 }
 
-MOZ_BEGIN_ENUM_CLASS(WebGLTexelPremultiplicationOp, int)
+enum class WebGLTexelPremultiplicationOp : int {
     None,
     Premultiply,
     Unpremultiply
-MOZ_END_ENUM_CLASS(WebGLTexelPremultiplicationOp)
+};
 
 namespace WebGLTexelConversions {
 
-template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format>
+template<WebGLTexelFormat Format>
 struct IsFloatFormat
 {
     static const bool Value =
         Format == WebGLTexelFormat::RGBA32F ||
         Format == WebGLTexelFormat::RGB32F ||
         Format == WebGLTexelFormat::RA32F ||
         Format == WebGLTexelFormat::R32F ||
         Format == WebGLTexelFormat::A32F;
 };
 
-template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format>
+template<WebGLTexelFormat Format>
 struct IsHalfFloatFormat
 {
     static const bool Value =
         Format == WebGLTexelFormat::RGBA16F ||
         Format == WebGLTexelFormat::RGB16F ||
         Format == WebGLTexelFormat::RA16F ||
         Format == WebGLTexelFormat::R16F ||
         Format == WebGLTexelFormat::A16F;
 };
 
-template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format>
+template<WebGLTexelFormat Format>
 struct Is16bppFormat
 {
     static const bool Value =
         Format == WebGLTexelFormat::RGBA4444 ||
         Format == WebGLTexelFormat::RGBA5551 ||
         Format == WebGLTexelFormat::RGB565;
 };
 
-template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format,
+template<WebGLTexelFormat Format,
          bool IsFloat = IsFloatFormat<Format>::Value,
          bool Is16bpp = Is16bppFormat<Format>::Value,
          bool IsHalfFloat = IsHalfFloatFormat<Format>::Value>
 struct DataTypeForFormat
 {
     typedef uint8_t Type;
 };
 
-template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format>
+template<WebGLTexelFormat Format>
 struct DataTypeForFormat<Format, true, false, false>
 {
     typedef float Type;
 };
 
-template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format>
+template<WebGLTexelFormat Format>
 struct DataTypeForFormat<Format, false, true, false>
 {
     typedef uint16_t Type;
 };
 
-template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format>
+template<WebGLTexelFormat Format>
 struct DataTypeForFormat<Format, false, false, true>
 {
     typedef uint16_t Type;
 };
 
-template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format>
+template<WebGLTexelFormat Format>
 struct IntermediateFormat
 {
-    static const MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Value
+    static const WebGLTexelFormat Value
         = IsFloatFormat<Format>::Value
           ? WebGLTexelFormat::RGBA32F
           : IsHalfFloatFormat<Format>::Value ? WebGLTexelFormat::RGBA16F
                                              : WebGLTexelFormat::RGBA8;
 };
 
 inline GLenum
 GLFormatForTexelFormat(WebGLTexelFormat format) {
@@ -327,17 +327,17 @@ MOZ_ALWAYS_INLINE bool HasColor(WebGLTex
 /****** BEGIN CODE SHARED WITH WEBKIT ******/
 
 // the pack/unpack functions here are originally from this file:
 //   http://trac.webkit.org/browser/trunk/WebCore/platform/graphics/GraphicsContext3D.cpp
 
 //----------------------------------------------------------------------
 // Pixel unpacking routines.
 
-template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format, typename SrcType, typename DstType>
+template<WebGLTexelFormat Format, typename SrcType, typename DstType>
 MOZ_ALWAYS_INLINE void
 unpack(const SrcType* __restrict src,
        DstType* __restrict dst)
 {
     MOZ_ASSERT(false, "Unimplemented texture format conversion");
 }
 
 template<> MOZ_ALWAYS_INLINE void
@@ -532,18 +532,18 @@ unpack<WebGLTexelFormat::A16F, uint16_t,
     dst[2] = kFloat16Value_Zero;
     dst[3] = src[0];
 }
 
 //----------------------------------------------------------------------
 // Pixel packing routines.
 //
 
-template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format,
-         MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelPremultiplicationOp) PremultiplicationOp,
+template<WebGLTexelFormat Format,
+         WebGLTexelPremultiplicationOp PremultiplicationOp,
          typename SrcType,
          typename DstType>
 MOZ_ALWAYS_INLINE void
 pack(const SrcType* __restrict src,
      DstType* __restrict dst)
 {
     MOZ_ASSERT(false, "Unimplemented texture format conversion");
 }
--- a/dom/canvas/WebGLTypes.h
+++ b/dom/canvas/WebGLTypes.h
@@ -1,18 +1,16 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef WEBGLTYPES_H_
 #define WEBGLTYPES_H_
 
-#include "mozilla/TypedEnum.h"
-
 // Most WebIDL typedefs are identical to their OpenGL counterparts.
 #include "GLTypes.h"
 
 // Manual reflection of WebIDL typedefs that are different from their
 // OpenGL counterparts.
 typedef int64_t WebGLsizeiptr;
 typedef int64_t WebGLintptr;
 typedef bool WebGLboolean;
@@ -41,66 +39,66 @@ namespace mozilla {
  *       with zero bytes, which means it's either opaque or transparent black
  *       depending on whether the image format has alpha.
  *
  * Why are there _two_ separate enums there, WebGLContextFakeBlackStatus
  * and WebGLTextureFakeBlackStatus? That's because each texture must know the precise
  * reason why it needs to be faked (incomplete texture vs. uninitialized image data),
  * whereas the WebGL context can only know whether _any_ faking is currently needed at all.
  */
-MOZ_BEGIN_ENUM_CLASS(WebGLContextFakeBlackStatus, uint8_t)
+enum class WebGLContextFakeBlackStatus : uint8_t {
   Unknown,
   NotNeeded,
   Needed
-MOZ_END_ENUM_CLASS(WebGLContextFakeBlackStatus)
+};
 
-MOZ_BEGIN_ENUM_CLASS(WebGLTextureFakeBlackStatus, uint8_t)
+enum class WebGLTextureFakeBlackStatus : uint8_t {
   Unknown,
   NotNeeded,
   IncompleteTexture,
   UninitializedImageData
-MOZ_END_ENUM_CLASS(WebGLTextureFakeBlackStatus)
+};
 
 /*
  * Implementing WebGL (or OpenGL ES 2.0) on top of desktop OpenGL requires
  * emulating the vertex attrib 0 array when it's not enabled. Indeed,
  * OpenGL ES 2.0 allows drawing without vertex attrib 0 array enabled, but
  * desktop OpenGL does not allow that.
  */
-MOZ_BEGIN_ENUM_CLASS(WebGLVertexAttrib0Status, uint8_t)
+enum class WebGLVertexAttrib0Status : uint8_t {
     Default, // default status - no emulation needed
     EmulatedUninitializedArray, // need an artificial attrib 0 array, but contents may be left uninitialized
     EmulatedInitializedArray // need an artificial attrib 0 array, and contents must be initialized
-MOZ_END_ENUM_CLASS(WebGLVertexAttrib0Status)
+};
 
 /*
  * Enum to track the status of image data (renderbuffer or texture image) presence
  * and initialization.
  *
  * - NoImageData is the initial state before any image data is allocated.
  * - InitializedImageData is the state after image data is allocated and initialized.
  * - UninitializedImageData is an intermediate state where data is allocated but not
  *   initialized. It is the state that renderbuffers are in after a renderbufferStorage call,
  *   and it is the state that texture images are in after a texImage2D call with null data.
  */
-MOZ_BEGIN_ENUM_CLASS(WebGLImageDataStatus, uint8_t)
+enum class WebGLImageDataStatus : uint8_t {
     NoImageData,
     UninitializedImageData,
     InitializedImageData
-MOZ_END_ENUM_CLASS(WebGLImageDataStatus)
+};
 
 /*
  * The formats that may participate, either as source or destination formats,
  * in WebGL texture conversions. This includes:
  *  - all the formats accepted by WebGL.texImage2D, e.g. RGBA4444
  *  - additional formats provided by extensions, e.g. RGB32F
  *  - additional source formats, depending on browser details, used when uploading
  *    textures from DOM elements. See gfxImageSurface::Format().
  */
-MOZ_BEGIN_ENUM_CLASS(WebGLTexelFormat, uint8_t)
+enum class WebGLTexelFormat : uint8_t {
     // returned by SurfaceFromElementResultToImageSurface to indicate absence of image data
     None,
     // common value for formats for which format conversions are not supported
     FormatNotSupportingAnyConversion,
     // dummy pseudo-format meaning "use the other format".
     // For example, if SrcFormat=Auto and DstFormat=RGB8, then the source
     // is implicitly treated as being RGB8 itself.
     Auto,
@@ -123,34 +121,34 @@ MOZ_BEGIN_ENUM_CLASS(WebGLTexelFormat, u
     RGB32F, // OES_texture_float
     // 4-channel formats
     RGBA8,
     BGRA8, // used for DOM elements
     RGBA5551,
     RGBA4444,
     RGBA16F, // OES_texture_half_float
     RGBA32F // OES_texture_float
-MOZ_END_ENUM_CLASS(WebGLTexelFormat)
+};
 
-MOZ_BEGIN_ENUM_CLASS(WebGLTexImageFunc, uint8_t)
+enum class WebGLTexImageFunc : uint8_t {
     TexImage,
     TexSubImage,
     CopyTexImage,
     CopyTexSubImage,
     CompTexImage,
     CompTexSubImage,
-MOZ_END_ENUM_CLASS(WebGLTexImageFunc)
+};
 
-MOZ_BEGIN_ENUM_CLASS(WebGLTexDimensions, uint8_t)
+enum class WebGLTexDimensions : uint8_t {
     Tex2D,
     Tex3D
-MOZ_END_ENUM_CLASS(WebGLTexDimensions)
+};
 
 // Please keep extensions in alphabetic order.
-MOZ_BEGIN_ENUM_CLASS(WebGLExtensionID, uint8_t)
+enum class WebGLExtensionID : uint8_t {
     ANGLE_instanced_arrays,
     EXT_blend_minmax,
     EXT_color_buffer_half_float,
     EXT_frag_depth,
     EXT_sRGB,
     EXT_shader_texture_lod,
     EXT_texture_filter_anisotropic,
     OES_element_index_uint,
@@ -167,13 +165,13 @@ MOZ_BEGIN_ENUM_CLASS(WebGLExtensionID, u
     WEBGL_compressed_texture_s3tc,
     WEBGL_debug_renderer_info,
     WEBGL_debug_shaders,
     WEBGL_depth_texture,
     WEBGL_draw_buffers,
     WEBGL_lose_context,
     Max,
     Unknown
-MOZ_END_ENUM_CLASS(WebGLExtensionID)
+};
 
 } // namespace mozilla
 
 #endif
--- a/dom/events/EventStateManager.h
+++ b/dom/events/EventStateManager.h
@@ -2,17 +2,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_EventStateManager_h_
 #define mozilla_EventStateManager_h_
 
 #include "mozilla/EventForwards.h"
-#include "mozilla/TypedEnum.h"
 
 #include "nsIObserver.h"
 #include "nsWeakReference.h"
 #include "nsCOMPtr.h"
 #include "nsCOMArray.h"
 #include "nsCycleCollectionParticipant.h"
 #include "mozilla/TimeStamp.h"
 #include "nsIFrame.h"
--- a/dom/html/HTMLCanvasElement.h
+++ b/dom/html/HTMLCanvasElement.h
@@ -2,17 +2,16 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #if !defined(mozilla_dom_HTMLCanvasElement_h)
 #define mozilla_dom_HTMLCanvasElement_h
 
 #include "mozilla/Attributes.h"
-#include "mozilla/TypedEnum.h"
 #include "nsIDOMHTMLCanvasElement.h"
 #include "nsGenericHTMLElement.h"
 #include "nsGkAtoms.h"
 #include "nsSize.h"
 #include "nsError.h"
 
 #include "mozilla/gfx/Rect.h"
 
@@ -31,21 +30,21 @@ class SourceSurface;
 
 namespace dom {
 
 class File;
 class FileCallback;
 class HTMLCanvasPrintState;
 class PrintCallback;
 
-MOZ_BEGIN_ENUM_CLASS(CanvasContextType, uint8_t)
+enum class CanvasContextType : uint8_t {
   Canvas2D,
   WebGL1,
   WebGL2
-MOZ_END_ENUM_CLASS(CanvasContextType)
+};
 
 class HTMLCanvasElement MOZ_FINAL : public nsGenericHTMLElement,
                                     public nsIDOMHTMLCanvasElement
 {
   enum {
     DEFAULT_CANVAS_WIDTH = 300,
     DEFAULT_CANVAS_HEIGHT = 150
   };
--- a/dom/media/MediaDecoderReader.h
+++ b/dom/media/MediaDecoderReader.h
@@ -8,18 +8,16 @@
 
 #include "AbstractMediaDecoder.h"
 #include "MediaInfo.h"
 #include "MediaData.h"
 #include "MediaPromise.h"
 #include "MediaQueue.h"
 #include "AudioCompactor.h"
 
-#include "mozilla/TypedEnum.h"
-
 namespace mozilla {
 
 namespace dom {
 class TimeRanges;
 }
 
 class MediaDecoderReader;
 class SharedDecoderManager;
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -1020,21 +1020,21 @@ protected:
   // can't keep up with the decode, and cause us to pause playback. So we
   // have a "preroll" stage, where we ignore the results of our "low data"
   // logic during the first few frames of our decode. This occurs during
   // playback. The flags below are true when the corresponding stream is
   // being "prerolled".
   bool mIsAudioPrerolling;
   bool mIsVideoPrerolling;
 
-  MOZ_BEGIN_NESTED_ENUM_CLASS(RequestStatus)
+  enum class RequestStatus {
     Idle,
     Pending,
     Waiting
-  MOZ_END_NESTED_ENUM_CLASS(RequestStatus)
+  };
 
   // True when we have dispatched a task to the decode task queue to request
   // decoded audio/video, and/or we are waiting for the requested sample to be
   // returned by callback from the Reader.
   RequestStatus mAudioRequestStatus;
   RequestStatus mVideoRequestStatus;
 
   RequestStatus& RequestStatusRef(MediaData::Type aType)
--- a/dom/media/webaudio/AudioEventTimeline.h
+++ b/dom/media/webaudio/AudioEventTimeline.h
@@ -5,17 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef AudioEventTimeline_h_
 #define AudioEventTimeline_h_
 
 #include <algorithm>
 #include "mozilla/Assertions.h"
 #include "mozilla/FloatingPoint.h"
-#include "mozilla/TypedEnum.h"
 #include "mozilla/PodOperations.h"
 
 #include "nsTArray.h"
 #include "math.h"
 #include "WebAudioUtils.h"
 
 namespace mozilla {
 
--- a/dom/media/webaudio/MediaBufferDecoder.cpp
+++ b/dom/media/webaudio/MediaBufferDecoder.cpp
@@ -77,21 +77,21 @@ private:
   // Therefore, it is not safe to do anything fancy with it in this class.
   // Really, this class is only used because nsRunnableMethod doesn't support
   // methods accepting arguments.
   WebAudioDecodeJob& mDecodeJob;
   WebAudioDecodeJob::ResultFn mFunction;
   WebAudioDecodeJob::ErrorCode mErrorCode;
 };
 
-MOZ_BEGIN_ENUM_CLASS(PhaseEnum, int)
+enum class PhaseEnum : int {
   Decode,
   AllocateBuffer,
   Done
-MOZ_END_ENUM_CLASS(PhaseEnum)
+};
 
 class MediaDecodeTask : public nsRunnable
 {
 public:
   MediaDecodeTask(const char* aContentType, uint8_t* aBuffer,
                   uint32_t aLength,
                   WebAudioDecodeJob& aDecodeJob)
     : mContentType(aContentType)
--- a/dom/svg/SVGPreserveAspectRatio.h
+++ b/dom/svg/SVGPreserveAspectRatio.h
@@ -2,17 +2,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_CONTENT_SVGPRESERVEASPECTRATIO_H_
 #define MOZILLA_CONTENT_SVGPRESERVEASPECTRATIO_H_
 
 #include "mozilla/HashFunctions.h"  // for HashGeneric
-#include "mozilla/TypedEnum.h"
 
 #include "nsWrapperCache.h"
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "mozilla/ErrorResult.h"
 #include "nsSVGElement.h"
 
 namespace mozilla {
--- a/dom/workers/ServiceWorkerCommon.h
+++ b/dom/workers/ServiceWorkerCommon.h
@@ -7,19 +7,19 @@
 #ifndef mozilla_dom_ServiceWorkerCommon_h
 #define mozilla_dom_ServiceWorkerCommon_h
 
 namespace mozilla {
 namespace dom {
 
 // Use multiples of 2 since they can be bitwise ORed when calling
 // InvalidateServiceWorkerRegistrationWorker.
-MOZ_BEGIN_ENUM_CLASS(WhichServiceWorker)
+enum class WhichServiceWorker {
   INSTALLING_WORKER = 1,
   WAITING_WORKER    = 2,
   ACTIVE_WORKER     = 4,
-MOZ_END_ENUM_CLASS(WhichServiceWorker)
+};
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(WhichServiceWorker)
 
 } // dom namespace
 } // mozilla namespace
 
 #endif // mozilla_dom_ServiceWorkerCommon_h
--- a/dom/workers/ServiceWorkerManager.h
+++ b/dom/workers/ServiceWorkerManager.h
@@ -6,17 +6,16 @@
 #define mozilla_dom_workers_serviceworkermanager_h
 
 #include "nsIServiceWorkerManager.h"
 #include "nsCOMPtr.h"
 
 #include "mozilla/Attributes.h"
 #include "mozilla/LinkedList.h"
 #include "mozilla/Preferences.h"
-#include "mozilla/TypedEnum.h"
 #include "mozilla/TypedEnumBits.h"
 #include "mozilla/WeakPtr.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/ServiceWorkerBinding.h" // For ServiceWorkerState
 #include "mozilla/dom/ServiceWorkerCommon.h"
 #include "nsClassHashtable.h"
 #include "nsDataHashtable.h"
--- a/editor/libeditor/nsEditor.h
+++ b/editor/libeditor/nsEditor.h
@@ -2,17 +2,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __editor_h__
 #define __editor_h__
 
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc.
-#include "mozilla/TypedEnum.h"          // for MOZ_BEGIN_ENUM_CLASS, etc.
 #include "mozilla/dom/Text.h"
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsCOMArray.h"                 // for nsCOMArray
 #include "nsCOMPtr.h"                   // for already_AddRefed, nsCOMPtr
 #include "nsCycleCollectionParticipant.h"
 #include "nsGkAtoms.h"
 #include "nsIEditor.h"                  // for nsIEditor::EDirection, etc
 #include "nsIEditorIMESupport.h"        // for NS_DECL_NSIEDITORIMESUPPORT, etc
@@ -85,17 +84,17 @@ struct IMEState;
 } // namespace widget
 } // namespace mozilla
 
 #define kMOZEditorBogusNodeAttrAtom nsGkAtoms::mozeditorbogusnode
 #define kMOZEditorBogusNodeValue NS_LITERAL_STRING("TRUE")
 
 // This is int32_t instead of int16_t because nsIInlineSpellChecker.idl's
 // spellCheckAfterEditorChange is defined to take it as a long.
-MOZ_BEGIN_ENUM_CLASS(EditAction, int32_t)
+enum class EditAction : int32_t {
   ignore = -1,
   none = 0,
   undo,
   redo,
   insertNode,
   createNode,
   deleteNode,
   splitNode,
@@ -123,17 +122,17 @@ MOZ_BEGIN_ENUM_CLASS(EditAction, int32_t
   insertQuotation     = 3009,
   htmlPaste           = 3012,
   loadHTML            = 3013,
   resetTextProperties = 3014,
   setAbsolutePosition = 3015,
   removeAbsolutePosition = 3016,
   decreaseZIndex      = 3017,
   increaseZIndex      = 3018
-MOZ_END_ENUM_CLASS(EditAction)
+};
 
 inline bool operator!(const EditAction& aOp)
 {
   return aOp == EditAction::none;
 }
 
 /** implementation of an editor object.  it will be the controller/focal point 
  *  for the main editor services. i.e. the GUIManager, publishing, transaction 
--- a/gfx/2d/Blur.cpp
+++ b/gfx/2d/Blur.cpp
@@ -12,16 +12,20 @@
 
 #include "mozilla/CheckedInt.h"
 #include "mozilla/Constants.h"
 
 #include "2D.h"
 #include "DataSurfaceHelpers.h"
 #include "Tools.h"
 
+#ifdef BUILD_ARM_NEON
+#include "mozilla/arm.h"
+#endif
+
 using namespace std;
 
 namespace mozilla {
 namespace gfx {
 
 /**
  * Box blur involves looking at one pixel, and setting its value to the average
  * of its neighbouring pixels.
@@ -539,26 +543,37 @@ AlphaBoxBlur::Blur(uint8_t* aData)
       }
       // bufLen is a byte count, but here we want a multiple of 32-bit ints, so
       // we divide by 4.
       AlignedArray<uint32_t> integralImage((bufLen / 4) + ((bufLen % 4) ? 1 : 0));
 
       if (!integralImage) {
         return;
       }
+
 #ifdef USE_SSE2
       if (Factory::HasSSE2()) {
         BoxBlur_SSE2(aData, horizontalLobes[0][0], horizontalLobes[0][1], verticalLobes[0][0],
                      verticalLobes[0][1], integralImage, integralImageStride);
         BoxBlur_SSE2(aData, horizontalLobes[1][0], horizontalLobes[1][1], verticalLobes[1][0],
                      verticalLobes[1][1], integralImage, integralImageStride);
         BoxBlur_SSE2(aData, horizontalLobes[2][0], horizontalLobes[2][1], verticalLobes[2][0],
                      verticalLobes[2][1], integralImage, integralImageStride);
       } else
 #endif
+#ifdef BUILD_ARM_NEON
+      if (mozilla::supports_neon()) {
+        BoxBlur_NEON(aData, horizontalLobes[0][0], horizontalLobes[0][1], verticalLobes[0][0],
+                     verticalLobes[0][1], integralImage, integralImageStride);
+        BoxBlur_NEON(aData, horizontalLobes[1][0], horizontalLobes[1][1], verticalLobes[1][0],
+                     verticalLobes[1][1], integralImage, integralImageStride);
+        BoxBlur_NEON(aData, horizontalLobes[2][0], horizontalLobes[2][1], verticalLobes[2][0],
+                     verticalLobes[2][1], integralImage, integralImageStride);
+      } else
+#endif
       {
         BoxBlur_C(aData, horizontalLobes[0][0], horizontalLobes[0][1], verticalLobes[0][0],
                   verticalLobes[0][1], integralImage, integralImageStride);
         BoxBlur_C(aData, horizontalLobes[1][0], horizontalLobes[1][1], verticalLobes[1][0],
                   verticalLobes[1][1], integralImage, integralImageStride);
         BoxBlur_C(aData, horizontalLobes[2][0], horizontalLobes[2][1], verticalLobes[2][0],
                   verticalLobes[2][1], integralImage, integralImageStride);
       }
--- a/gfx/2d/Blur.h
+++ b/gfx/2d/Blur.h
@@ -119,16 +119,21 @@ public:
 private:
 
   void BoxBlur_C(uint8_t* aData,
                  int32_t aLeftLobe, int32_t aRightLobe, int32_t aTopLobe,
                  int32_t aBottomLobe, uint32_t *aIntegralImage, size_t aIntegralImageStride);
   void BoxBlur_SSE2(uint8_t* aData,
                     int32_t aLeftLobe, int32_t aRightLobe, int32_t aTopLobe,
                     int32_t aBottomLobe, uint32_t *aIntegralImage, size_t aIntegralImageStride);
+#ifdef BUILD_ARM_NEON
+  void BoxBlur_NEON(uint8_t* aData,
+                    int32_t aLeftLobe, int32_t aRightLobe, int32_t aTopLobe,
+                    int32_t aBottomLobe, uint32_t *aIntegralImage, size_t aIntegralImageStride);
+#endif
 
   static CheckedInt<int32_t> RoundUpToMultipleOf4(int32_t aVal);
 
   /**
    * A rect indicating the area where blurring is unnecessary, and the blur
    * algorithm should skip over it.
    */
   IntRect mSkipRect;
new file mode 100644
--- /dev/null
+++ b/gfx/2d/BlurNEON.cpp
@@ -0,0 +1,288 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "Blur.h"
+#include <arm_neon.h>
+
+namespace mozilla {
+namespace gfx {
+
+MOZ_ALWAYS_INLINE
+uint16x4_t Divide(uint32x4_t aValues, uint32x2_t aDivisor)
+{
+  uint64x2_t roundingAddition = vdupq_n_u64(int64_t(1) << 31);
+  uint64x2_t multiplied21 = vmull_u32(vget_low_u32(aValues), aDivisor);
+  uint64x2_t multiplied43 = vmull_u32(vget_high_u32(aValues), aDivisor);
+  return vqmovn_u32(vcombine_u32(vshrn_n_u64(vaddq_u64(multiplied21, roundingAddition), 32),
+                                 vshrn_n_u64(vaddq_u64(multiplied43, roundingAddition), 32)));
+}
+
+MOZ_ALWAYS_INLINE
+uint16x4_t BlurFourPixels(const uint32x4_t& aTopLeft, const uint32x4_t& aTopRight,
+                          const uint32x4_t& aBottomRight, const uint32x4_t& aBottomLeft,
+                          const uint32x2_t& aDivisor)
+{
+  uint32x4_t values = vaddq_u32(vsubq_u32(vsubq_u32(aBottomRight, aTopRight), aBottomLeft), aTopLeft);
+  return Divide(values, aDivisor);
+}
+
+MOZ_ALWAYS_INLINE
+void LoadIntegralRowFromRow(uint32_t *aDest, const uint8_t *aSource,
+                            int32_t aSourceWidth, int32_t aLeftInflation,
+                            int32_t aRightInflation)
+{
+  int32_t currentRowSum = 0;
+
+  for (int x = 0; x < aLeftInflation; x++) {
+    currentRowSum += aSource[0];
+    aDest[x] = currentRowSum;
+  }
+  for (int x = aLeftInflation; x < (aSourceWidth + aLeftInflation); x++) {
+    currentRowSum += aSource[(x - aLeftInflation)];
+    aDest[x] = currentRowSum;
+  }
+  for (int x = (aSourceWidth + aLeftInflation); x < (aSourceWidth + aLeftInflation + aRightInflation); x++) {
+    currentRowSum += aSource[aSourceWidth - 1];
+    aDest[x] = currentRowSum;
+  }
+}
+
+MOZ_ALWAYS_INLINE void
+GenerateIntegralImage_NEON(int32_t aLeftInflation, int32_t aRightInflation,
+                           int32_t aTopInflation, int32_t aBottomInflation,
+                           uint32_t *aIntegralImage, size_t aIntegralImageStride,
+                           uint8_t *aSource, int32_t aSourceStride, const IntSize &aSize)
+{
+  MOZ_ASSERT(!(aLeftInflation & 3));
+
+  uint32_t stride32bit = aIntegralImageStride / 4;
+  IntSize integralImageSize(aSize.width + aLeftInflation + aRightInflation,
+                            aSize.height + aTopInflation + aBottomInflation);
+
+  LoadIntegralRowFromRow(aIntegralImage, aSource, aSize.width, aLeftInflation, aRightInflation);
+
+  for (int y = 1; y < aTopInflation + 1; y++) {
+    uint32_t *intRow = aIntegralImage + (y * stride32bit);
+    uint32_t *intPrevRow = aIntegralImage + (y - 1) * stride32bit;
+    uint32_t *intFirstRow = aIntegralImage;
+
+    for (int x = 0; x < integralImageSize.width; x += 4) {
+      uint32x4_t firstRow = vld1q_u32(intFirstRow + x);
+      uint32x4_t previousRow = vld1q_u32(intPrevRow + x);
+      vst1q_u32(intRow + x, vaddq_u32(firstRow, previousRow));
+    }
+  }
+
+  for (int y = aTopInflation + 1; y < (aSize.height + aTopInflation); y++) {
+    uint32x4_t currentRowSum = vdupq_n_u32(0);
+    uint32_t *intRow = aIntegralImage + (y * stride32bit);
+    uint32_t *intPrevRow = aIntegralImage + (y - 1) * stride32bit;
+    uint8_t *sourceRow = aSource + aSourceStride * (y - aTopInflation);
+
+    uint32_t pixel = sourceRow[0];
+    for (int x = 0; x < aLeftInflation; x += 4) {
+      uint32_t temp[4];
+      temp[0] = pixel;
+      temp[1] = temp[0] + pixel;
+      temp[2] = temp[1] + pixel;
+      temp[3] = temp[2] + pixel;
+      uint32x4_t sumPixels = vld1q_u32(temp);
+      sumPixels = vaddq_u32(sumPixels, currentRowSum);
+      currentRowSum = vdupq_n_u32(vgetq_lane_u32(sumPixels, 3));
+      vst1q_u32(intRow + x, vaddq_u32(sumPixels, vld1q_u32(intPrevRow + x)));
+    }
+
+    for (int x = aLeftInflation; x < (aSize.width + aLeftInflation); x += 4) {
+      // It's important to shuffle here. When we exit this loop currentRowSum
+      // has to be set to sumPixels, so that the following loop can get the
+      // correct pixel for the currentRowSum. The highest order pixel in
+      // currentRowSum could've originated from accumulation in the stride.
+      currentRowSum = vdupq_n_u32(vgetq_lane_u32(currentRowSum, 3));
+
+      uint32_t temp[4];
+      temp[0] = *(sourceRow + (x - aLeftInflation));
+      temp[1] = temp[0] + *(sourceRow + (x - aLeftInflation) + 1);
+      temp[2] = temp[1] + *(sourceRow + (x - aLeftInflation) + 2);
+      temp[3] = temp[2] + *(sourceRow + (x - aLeftInflation) + 3);
+      uint32x4_t sumPixels = vld1q_u32(temp);
+      sumPixels = vaddq_u32(sumPixels, currentRowSum);
+      currentRowSum = sumPixels;
+      vst1q_u32(intRow + x, vaddq_u32(sumPixels, vld1q_u32(intPrevRow + x)));
+    }
+
+    pixel = sourceRow[aSize.width - 1];
+    int x = (aSize.width + aLeftInflation);
+    if ((aSize.width & 3)) {
+      // Deal with unaligned portion. Get the correct pixel from currentRowSum,
+      // see explanation above.
+      uint32_t intCurrentRowSum = ((uint32_t*)&currentRowSum)[(aSize.width % 4) - 1];
+      for (; x < integralImageSize.width; x++) {
+        // We could be unaligned here!
+        if (!(x & 3)) {
+          // aligned!
+          currentRowSum = vdupq_n_u32(intCurrentRowSum);
+          break;
+        }
+        intCurrentRowSum += pixel;
+        intRow[x] = intPrevRow[x] + intCurrentRowSum;
+      }
+    } else {
+      currentRowSum = vdupq_n_u32(vgetq_lane_u32(currentRowSum, 3));
+    }
+
+    for (; x < integralImageSize.width; x += 4) {
+      uint32_t temp[4];
+      temp[0] = pixel;
+      temp[1] = temp[0] + pixel;
+      temp[2] = temp[1] + pixel;
+      temp[3] = temp[2] + pixel;
+      uint32x4_t sumPixels = vld1q_u32(temp);
+      sumPixels = vaddq_u32(sumPixels, currentRowSum);
+      currentRowSum = vdupq_n_u32(vgetq_lane_u32(sumPixels, 3));
+      vst1q_u32(intRow + x, vaddq_u32(sumPixels, vld1q_u32(intPrevRow + x)));
+    }
+  }
+
+  if (aBottomInflation) {
+    // Store the last valid row of our source image in the last row of
+    // our integral image. This will be overwritten with the correct values
+    // in the upcoming loop.
+    LoadIntegralRowFromRow(aIntegralImage + (integralImageSize.height - 1) * stride32bit,
+                           aSource + (aSize.height - 1) * aSourceStride, aSize.width, aLeftInflation, aRightInflation);
+
+    for (int y = aSize.height + aTopInflation; y < integralImageSize.height; y++) {
+      uint32_t *intRow = aIntegralImage + (y * stride32bit);
+      uint32_t *intPrevRow = aIntegralImage + (y - 1) * stride32bit;
+      uint32_t *intLastRow = aIntegralImage + (integralImageSize.height - 1) * stride32bit;
+      for (int x = 0; x < integralImageSize.width; x += 4) {
+        vst1q_u32(intRow + x,
+                        vaddq_u32(vld1q_u32(intLastRow + x),
+                                  vld1q_u32(intPrevRow + x)));
+      }
+    }
+  }
+}
+
+/**
+ * Attempt to do an in-place box blur using an integral image.
+ */
+void
+AlphaBoxBlur::BoxBlur_NEON(uint8_t* aData,
+                           int32_t aLeftLobe,
+                           int32_t aRightLobe,
+                           int32_t aTopLobe,
+                           int32_t aBottomLobe,
+                           uint32_t *aIntegralImage,
+                           size_t aIntegralImageStride)
+{
+  IntSize size = GetSize();
+
+  MOZ_ASSERT(size.height > 0);
+
+  // Our 'left' or 'top' lobe will include the current pixel. i.e. when
+  // looking at an integral image the value of a pixel at 'x,y' is calculated
+  // using the value of the integral image values above/below that.
+  aLeftLobe++;
+  aTopLobe++;
+  int32_t boxSize = (aLeftLobe + aRightLobe) * (aTopLobe + aBottomLobe);
+
+  MOZ_ASSERT(boxSize > 0);
+
+  if (boxSize == 1) {
+      return;
+  }
+
+  uint32_t reciprocal = uint32_t((uint64_t(1) << 32) / boxSize);
+  uint32_t stride32bit = aIntegralImageStride / 4;
+  int32_t leftInflation = RoundUpToMultipleOf4(aLeftLobe).value();
+
+  GenerateIntegralImage_NEON(leftInflation, aRightLobe, aTopLobe, aBottomLobe,
+                             aIntegralImage, aIntegralImageStride, aData,
+                             mStride, size);
+
+  uint32x2_t divisor = vdup_n_u32(reciprocal);
+
+  // This points to the start of the rectangle within the IntegralImage that overlaps
+  // the surface being blurred.
+  uint32_t *innerIntegral = aIntegralImage + (aTopLobe * stride32bit) + leftInflation;
+  IntRect skipRect = mSkipRect;
+  int32_t stride = mStride;
+  uint8_t *data = aData;
+
+  for (int32_t y = 0; y < size.height; y++) {
+    bool inSkipRectY = y > skipRect.y && y < skipRect.YMost();
+    uint32_t *topLeftBase = innerIntegral + ((y - aTopLobe) * ptrdiff_t(stride32bit) - aLeftLobe);
+    uint32_t *topRightBase = innerIntegral + ((y - aTopLobe) * ptrdiff_t(stride32bit) + aRightLobe);
+    uint32_t *bottomRightBase = innerIntegral + ((y + aBottomLobe) * ptrdiff_t(stride32bit) + aRightLobe);
+    uint32_t *bottomLeftBase = innerIntegral + ((y + aBottomLobe) * ptrdiff_t(stride32bit) - aLeftLobe);
+
+    int32_t x = 0;
+    // Process 16 pixels at a time for as long as possible.
+    for (; x <= size.width - 16; x += 16) {
+      if (inSkipRectY && x > skipRect.x && x < skipRect.XMost()) {
+        x = skipRect.XMost() - 16;
+        // Trigger early jump on coming loop iterations, this will be reset
+        // next line anyway.
+        inSkipRectY = false;
+        continue;
+      }
+
+      uint32x4_t topLeft;
+      uint32x4_t topRight;
+      uint32x4_t bottomRight;
+      uint32x4_t bottomLeft;
+      topLeft = vld1q_u32(topLeftBase + x);
+      topRight = vld1q_u32(topRightBase + x);
+      bottomRight = vld1q_u32(bottomRightBase + x);
+      bottomLeft = vld1q_u32(bottomLeftBase + x);
+      uint16x4_t result1 = BlurFourPixels(topLeft, topRight, bottomRight, bottomLeft, divisor);
+
+      topLeft = vld1q_u32(topLeftBase + x + 4);
+      topRight = vld1q_u32(topRightBase + x + 4);
+      bottomRight = vld1q_u32(bottomRightBase + x + 4);
+      bottomLeft = vld1q_u32(bottomLeftBase + x + 4);
+      uint16x4_t result2 = BlurFourPixels(topLeft, topRight, bottomRight, bottomLeft, divisor);
+
+      topLeft = vld1q_u32(topLeftBase + x + 8);
+      topRight = vld1q_u32(topRightBase + x + 8);
+      bottomRight = vld1q_u32(bottomRightBase + x + 8);
+      bottomLeft = vld1q_u32(bottomLeftBase + x + 8);
+      uint16x4_t result3 = BlurFourPixels(topLeft, topRight, bottomRight, bottomLeft, divisor);
+
+      topLeft = vld1q_u32(topLeftBase + x + 12);
+      topRight = vld1q_u32(topRightBase + x + 12);
+      bottomRight = vld1q_u32(bottomRightBase + x + 12);
+      bottomLeft = vld1q_u32(bottomLeftBase + x + 12);
+      uint16x4_t result4 = BlurFourPixels(topLeft, topRight, bottomRight, bottomLeft, divisor);
+
+      uint8x8_t combine1 = vqmovn_u16(vcombine_u16(result1, result2));
+      uint8x8_t combine2 = vqmovn_u16(vcombine_u16(result3, result4));
+      uint8x16_t final = vcombine_u8(combine1, combine2);
+      vst1q_u8(data + stride * y + x, final);
+    }
+
+    // Process the remaining pixels 4 bytes at a time.
+    for (; x < size.width; x += 4) {
+      if (inSkipRectY && x > skipRect.x && x < skipRect.XMost()) {
+        x = skipRect.XMost() - 4;
+        // Trigger early jump on coming loop iterations, this will be reset
+        // next line anyway.
+        inSkipRectY = false;
+        continue;
+      }
+
+      uint32x4_t topLeft = vld1q_u32(topLeftBase + x);
+      uint32x4_t topRight = vld1q_u32(topRightBase + x);
+      uint32x4_t bottomRight = vld1q_u32(bottomRightBase + x);
+      uint32x4_t bottomLeft = vld1q_u32(bottomLeftBase + x);
+      uint16x4_t result = BlurFourPixels(topLeft, topRight, bottomRight, bottomLeft, divisor);
+      uint32x2_t final = vreinterpret_u32_u8(vmovn_u16(vcombine_u16(result, vdup_n_u16(0))));
+      *(uint32_t*)(data + stride * y + x) = vget_lane_u32(final, 0);
+    }
+  }
+}
+
+}
+}
+
--- a/gfx/2d/DrawCommand.h
+++ b/gfx/2d/DrawCommand.h
@@ -8,17 +8,17 @@
 
 #include "2D.h"
 #include "Filters.h"
 #include <vector>
 
 namespace mozilla {
 namespace gfx {
 
-MOZ_BEGIN_ENUM_CLASS(CommandType, int8_t)
+enum class CommandType : int8_t {
   DRAWSURFACE = 0,
   DRAWFILTER,
   DRAWSURFACEWITHSHADOW,
   CLEARRECT,
   COPYSURFACE,
   COPYRECT,
   FILLRECT,
   STROKERECT,
@@ -27,17 +27,17 @@ MOZ_BEGIN_ENUM_CLASS(CommandType, int8_t
   FILL,
   FILLGLYPHS,
   MASK,
   MASKSURFACE,
   PUSHCLIP,
   PUSHCLIPRECT,
   POPCLIP,
   SETTRANSFORM
-MOZ_END_ENUM_CLASS(CommandType)
+};
 
 class DrawingCommand
 {
 public:
   virtual ~DrawingCommand() {}
 
   virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix& aTransform) = 0;
 
--- a/gfx/2d/Logging.h
+++ b/gfx/2d/Logging.h
@@ -16,17 +16,16 @@
 #endif
 
 #if defined(MOZ_WIDGET_GONK) || defined(MOZ_WIDGET_ANDROID)
 #include "nsDebug.h"
 #endif
 #include "Point.h"
 #include "BaseRect.h"
 #include "Matrix.h"
-#include "mozilla/TypedEnum.h"
 
 #ifdef WIN32
 // This file gets included from nsGlobalWindow.cpp, which doesn't like
 // having windows.h included in it. Since OutputDebugStringA is the only
 // thing we need from windows.h, we just declare it here directly.
 // Note: the function's documented signature is
 //  WINBASEAPI void WINAPI OutputDebugStringA(LPCSTR lpOutputString)
 // but if we don't include windows.h, the macros WINBASEAPI, WINAPI, and 
@@ -220,21 +219,21 @@ class NoLog
 public:
   NoLog() {}
   ~NoLog() {}
 
   template<typename T>
   NoLog &operator <<(const T &aLogText) { return *this; }
 };
 
-MOZ_BEGIN_ENUM_CLASS(LogOptions, int)
+enum class LogOptions : int {
   NoNewline = 0x01,
   AutoPrefix = 0x02,
   AssertOnCall = 0x04
-MOZ_END_ENUM_CLASS(LogOptions)
+};
 
 template<typename T>
 struct Hexa {
   explicit Hexa(T aVal) : mVal(aVal) {}
   T mVal;
 };
 template<typename T>
 Hexa<T> hexa(T val) { return Hexa<T>(val); }
--- a/gfx/2d/PathHelpers.h
+++ b/gfx/2d/PathHelpers.h
@@ -3,17 +3,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_GFX_PATHHELPERS_H_
 #define MOZILLA_GFX_PATHHELPERS_H_
 
 #include "2D.h"
 #include "mozilla/Constants.h"
-#include "mozilla/TypedEnum.h"
 #include "UserData.h"
 
 namespace mozilla {
 namespace gfx {
 
 template <typename T>
 void ArcToBezier(T* aSink, const Point &aOrigin, const Size &aRadius,
                  float aStartAngle, float aEndAngle, bool aAntiClockwise)
--- a/gfx/2d/Types.h
+++ b/gfx/2d/Types.h
@@ -1,66 +1,64 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_GFX_TYPES_H_
 #define MOZILLA_GFX_TYPES_H_
 
-#include "mozilla/TypedEnum.h"
-
 #include <stddef.h>
 #include <stdint.h>
 
 namespace mozilla {
 namespace gfx {
 
 typedef float Float;
 
-MOZ_BEGIN_ENUM_CLASS(SurfaceType, int8_t)
+enum class SurfaceType : int8_t {
   DATA, /* Data surface - bitmap in memory */
   D2D1_BITMAP, /* Surface wrapping a ID2D1Bitmap */
   D2D1_DRAWTARGET, /* Surface made from a D2D draw target */
   CAIRO, /* Surface wrapping a cairo surface */
   CAIRO_IMAGE, /* Data surface wrapping a cairo image surface */
   COREGRAPHICS_IMAGE, /* Surface wrapping a CoreGraphics Image */
   COREGRAPHICS_CGCONTEXT, /* Surface wrapping a CG context */
   SKIA, /* Surface wrapping a Skia bitmap */
   DUAL_DT, /* Snapshot of a dual drawtarget */
   D2D1_1_IMAGE, /* A D2D 1.1 ID2D1Image SourceSurface */
   RECORDING, /* Surface used for recording */
   TILED /* Surface from a tiled DrawTarget */
-MOZ_END_ENUM_CLASS(SurfaceType)
+};
 
-MOZ_BEGIN_ENUM_CLASS(SurfaceFormat, int8_t)
+enum class SurfaceFormat : int8_t {
   B8G8R8A8,
   B8G8R8X8,
   R8G8B8A8,
   R8G8B8X8,
   R5G6B5,
   A8,
   YUV,
   UNKNOWN
-MOZ_END_ENUM_CLASS(SurfaceFormat)
+};
 
 inline bool IsOpaque(SurfaceFormat aFormat)
 {
   switch (aFormat) {
   case SurfaceFormat::B8G8R8X8:
   case SurfaceFormat::R8G8B8X8:
   case SurfaceFormat::R5G6B5:
   case SurfaceFormat::YUV:
     return true;
   default:
     return false;
   }
 }
 
-MOZ_BEGIN_ENUM_CLASS(FilterType, int8_t)
+enum class FilterType : int8_t {
   BLEND = 0,
   TRANSFORM,
   MORPHOLOGY,
   COLOR_MATRIX,
   FLOOD,
   TILE,
   TABLE_TRANSFER,
   DISCRETE_TRANSFER,
@@ -77,76 +75,76 @@ MOZ_BEGIN_ENUM_CLASS(FilterType, int8_t)
   POINT_SPECULAR,
   SPOT_DIFFUSE,
   SPOT_SPECULAR,
   DISTANT_DIFFUSE,
   DISTANT_SPECULAR,
   CROP,
   PREMULTIPLY,
   UNPREMULTIPLY
-MOZ_END_ENUM_CLASS(FilterType)
+};
 
-MOZ_BEGIN_ENUM_CLASS(DrawTargetType, int8_t)
+enum class DrawTargetType : int8_t {
   SOFTWARE_RASTER = 0,
   HARDWARE_RASTER,
   VECTOR
-MOZ_END_ENUM_CLASS(DrawTargetType)
+};
 
-MOZ_BEGIN_ENUM_CLASS(BackendType, int8_t)
+enum class BackendType : int8_t {
   NONE = 0,
   DIRECT2D,
   COREGRAPHICS,
   COREGRAPHICS_ACCELERATED,
   CAIRO,
   SKIA,
   RECORDING,
   DIRECT2D1_1
-MOZ_END_ENUM_CLASS(BackendType)
+};
 
-MOZ_BEGIN_ENUM_CLASS(FontType, int8_t)
+enum class FontType : int8_t {
   DWRITE,
   GDI,
   MAC,
   SKIA,
   CAIRO,
   COREGRAPHICS
-MOZ_END_ENUM_CLASS(FontType)
+};
 
-MOZ_BEGIN_ENUM_CLASS(NativeSurfaceType, int8_t)
+enum class NativeSurfaceType : int8_t {
   D3D10_TEXTURE,
   CAIRO_SURFACE,
   CAIRO_CONTEXT,
   CGCONTEXT,
   CGCONTEXT_ACCELERATED,
   OPENGL_TEXTURE
-MOZ_END_ENUM_CLASS(NativeSurfaceType)
+};
 
-MOZ_BEGIN_ENUM_CLASS(NativeFontType, int8_t)
+enum class NativeFontType : int8_t {
   DWRITE_FONT_FACE,
   GDI_FONT_FACE,
   MAC_FONT_FACE,
   SKIA_FONT_FACE,
   CAIRO_FONT_FACE
-MOZ_END_ENUM_CLASS(NativeFontType)
+};
 
-MOZ_BEGIN_ENUM_CLASS(FontStyle, int8_t)
+enum class FontStyle : int8_t {
   NORMAL,
   ITALIC,
   BOLD,
   BOLD_ITALIC
-MOZ_END_ENUM_CLASS(FontStyle)
+};
 
-MOZ_BEGIN_ENUM_CLASS(FontHinting, int8_t)
+enum class FontHinting : int8_t {
   NONE,
   LIGHT,
   NORMAL,
   FULL
-MOZ_END_ENUM_CLASS(FontHinting)
+};
 
-MOZ_BEGIN_ENUM_CLASS(CompositionOp, int8_t)
+enum class CompositionOp : int8_t {
   OP_OVER,
   OP_ADD,
   OP_ATOP,
   OP_OUT,
   OP_IN,
   OP_SOURCE,
   OP_DEST_IN,
   OP_DEST_OUT,
@@ -164,68 +162,68 @@ MOZ_BEGIN_ENUM_CLASS(CompositionOp, int8
   OP_SOFT_LIGHT,
   OP_DIFFERENCE,
   OP_EXCLUSION,
   OP_HUE,
   OP_SATURATION,
   OP_COLOR,
   OP_LUMINOSITY,
   OP_COUNT
-MOZ_END_ENUM_CLASS(CompositionOp)
+};
 
-MOZ_BEGIN_ENUM_CLASS(ExtendMode, int8_t)
+enum class ExtendMode : int8_t {
   CLAMP,
   REPEAT,
   REFLECT
-MOZ_END_ENUM_CLASS(ExtendMode)
+};
 
-MOZ_BEGIN_ENUM_CLASS(FillRule, int8_t)
+enum class FillRule : int8_t {
   FILL_WINDING,
   FILL_EVEN_ODD
-MOZ_END_ENUM_CLASS(FillRule)
+};
 
-MOZ_BEGIN_ENUM_CLASS(AntialiasMode, int8_t)
+enum class AntialiasMode : int8_t {
   NONE,
   GRAY,
   SUBPIXEL,
   DEFAULT
-MOZ_END_ENUM_CLASS(AntialiasMode)
+};
 
-MOZ_BEGIN_ENUM_CLASS(Filter, int8_t)
+enum class Filter : int8_t {
   GOOD,
   LINEAR,
   POINT
-MOZ_END_ENUM_CLASS(Filter)
+};
 
-MOZ_BEGIN_ENUM_CLASS(PatternType, int8_t)
+enum class PatternType : int8_t {
   COLOR,
   SURFACE,
   LINEAR_GRADIENT,
   RADIAL_GRADIENT
-MOZ_END_ENUM_CLASS(PatternType)
+};
 
-MOZ_BEGIN_ENUM_CLASS(JoinStyle, int8_t)
+enum class JoinStyle : int8_t {
   BEVEL,
   ROUND,
   MITER, //!< Mitered if within the miter limit, else, if the backed supports
          //!< it (D2D), the miter is clamped. If the backend does not support
          //!< miter clamping the behavior is as for MITER_OR_BEVEL.
   MITER_OR_BEVEL //!< Mitered if within the miter limit, else beveled.
-MOZ_END_ENUM_CLASS(JoinStyle)
+};
 
-MOZ_BEGIN_ENUM_CLASS(CapStyle, int8_t)
+enum class CapStyle : int8_t {
   BUTT,
   ROUND,
   SQUARE
-MOZ_END_ENUM_CLASS(CapStyle)
+};
 
-MOZ_BEGIN_ENUM_CLASS(SamplingBounds, int8_t)
+enum class SamplingBounds : int8_t {
   UNBOUNDED,
   BOUNDED
-MOZ_END_ENUM_CLASS(SamplingBounds)
+};
 
 /* Color is stored in non-premultiplied form */
 struct Color
 {
 public:
   Color()
     : r(0.0f), g(0.0f), b(0.0f), a(0.0f)
   {}
--- a/gfx/2d/moz.build
+++ b/gfx/2d/moz.build
@@ -131,16 +131,20 @@ SOURCES += [
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     SOURCES += [
         'MacIOSurface.cpp',
         'QuartzSupport.mm',
     ]
 
+if CONFIG['CPU_ARCH'] == 'arm' and CONFIG['BUILD_ARM_NEON']:
+    SOURCES += ['BlurNEON.cpp']
+    SOURCES['BlurNEON.cpp'].flags += ['-mfpu=neon']
+
 FAIL_ON_WARNINGS = True
 
 MSVC_ENABLE_PGO = True
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
--- a/gfx/gl/AndroidNativeWindow.h
+++ b/gfx/gl/AndroidNativeWindow.h
@@ -7,29 +7,28 @@
 #ifndef AndroidNativeWindow_h__
 #define AndroidNativeWindow_h__
 #ifdef MOZ_WIDGET_ANDROID
 
 #include <jni.h>
 #include "GLDefs.h"
 
 #include "nsISupports.h"
-#include "mozilla/TypedEnum.h"
 #include "mozilla/gfx/2D.h"
 
 
 namespace mozilla {
 namespace gl {
 
-MOZ_BEGIN_ENUM_CLASS(AndroidWindowFormat)
+enum class AndroidWindowFormat {
   Unknown = -1,
   RGBA_8888 = 1,
   RGBX_8888 = 1 << 1,
   RGB_565 = 1 << 2
-MOZ_END_ENUM_CLASS(AndroidWindowFormat)
+};
 
 /**
  * This class is a wrapper around Android's SurfaceTexture class.
  * Usage is pretty much exactly like the Java class, so see
  * the Android documentation for details.
  */
 class AndroidNativeWindow {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AndroidNativeWindow)
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -79,17 +79,17 @@ namespace mozilla {
     namespace layers {
         class ColorTextureLayerProgram;
     }
 }
 
 namespace mozilla {
 namespace gl {
 
-MOZ_BEGIN_ENUM_CLASS(GLFeature)
+enum class GLFeature {
     bind_buffer_offset,
     blend_minmax,
     clear_buffers,
     copy_buffer,
     depth_texture,
     draw_buffers,
     draw_instanced,
     draw_range_elements,
@@ -129,53 +129,53 @@ MOZ_BEGIN_ENUM_CLASS(GLFeature)
     texture_half_float_linear,
     texture_non_power_of_two,
     texture_storage,
     transform_feedback2,
     uniform_buffer_object,
     uniform_matrix_nonsquare,
     vertex_array_object,
     EnumMax
-MOZ_END_ENUM_CLASS(GLFeature)
-
-MOZ_BEGIN_ENUM_CLASS(ContextProfile, uint8_t)
+};
+
+enum class ContextProfile : uint8_t {
     Unknown = 0,
     OpenGL, // only for IsAtLeast's <profile> parameter
     OpenGLCore,
     OpenGLCompatibility,
     OpenGLES
-MOZ_END_ENUM_CLASS(ContextProfile)
-
-MOZ_BEGIN_ENUM_CLASS(GLVendor)
+};
+
+enum class GLVendor {
     Intel,
     NVIDIA,
     ATI,
     Qualcomm,
     Imagination,
     Nouveau,
     Vivante,
     VMware,
     Other
-MOZ_END_ENUM_CLASS(GLVendor)
-
-MOZ_BEGIN_ENUM_CLASS(GLRenderer)
+};
+
+enum class GLRenderer {
     Adreno200,
     Adreno205,
     AdrenoTM200,
     AdrenoTM205,
     AdrenoTM320,
     SGX530,
     SGX540,
     Tegra,
     AndroidEmulator,
     GalliumLlvmpipe,
     IntelHD3000,
     MicrosoftBasicRenderDriver,
     Other
-MOZ_END_ENUM_CLASS(GLRenderer)
+};
 
 class GLContext
     : public GLLibraryLoader
     , public GenericAtomicRefCounted
 {
 // -----------------------------------------------------------------------------
 // basic enums
 public:
--- a/gfx/gl/GLContextFeatures.cpp
+++ b/gfx/gl/GLContextFeatures.cpp
@@ -11,38 +11,38 @@
 #include "nsCocoaFeatures.h"
 #endif
 
 namespace mozilla {
 namespace gl {
 
 const size_t kMAX_EXTENSION_GROUP_SIZE = 5;
 
-MOZ_BEGIN_ENUM_CLASS(GLVersion, uint32_t)
+enum class GLVersion : uint32_t {
     NONE  = 0,   // Feature is not supported natively by GL
     GL1_2 = 120,
     GL1_3 = 130,
     GL2   = 200,
     GL2_1 = 210,
     GL3   = 300,
     GL3_1 = 310,
     GL3_2 = 320,
     GL3_3 = 330,
     GL4   = 400,
     GL4_1 = 410,
     GL4_2 = 420,
     GL4_3 = 430,
-MOZ_END_ENUM_CLASS(GLVersion)
+};
 
-MOZ_BEGIN_ENUM_CLASS(GLESVersion, uint32_t)
+enum class GLESVersion : uint32_t {
     NONE  = 0,   // Feature is not support natively by GL ES
     ES2   = 200,
     ES3   = 300,
     ES3_1 = 310,
-MOZ_END_ENUM_CLASS(GLESVersion)
+};
 
 // ARB_ES2_compatibility is natively supported in OpenGL 4.1.
 static const GLVersion kGLCoreVersionForES2Compat = GLVersion::GL4_1;
 
 // ARB_ES3_compatibility is natively supported in OpenGL 4.3.
 static const GLVersion kGLCoreVersionForES3Compat = GLVersion::GL4_3;
 
 struct FeatureInfo
--- a/gfx/gl/GLContextTypes.h
+++ b/gfx/gl/GLContextTypes.h
@@ -2,35 +2,34 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GLCONTEXT_TYPES_H_
 #define GLCONTEXT_TYPES_H_
 
 #include "GLTypes.h"
-#include "mozilla/TypedEnum.h"
 
 namespace mozilla {
 namespace gl {
 
 class GLContext;
 
-MOZ_BEGIN_ENUM_CLASS(GLContextType)
+enum class GLContextType {
     Unknown,
     WGL,
     CGL,
     GLX,
     EGL
-MOZ_END_ENUM_CLASS(GLContextType)
+};
 
-MOZ_BEGIN_ENUM_CLASS(OriginPos, uint8_t)
+enum class OriginPos : uint8_t {
   TopLeft,
   BottomLeft
-MOZ_END_ENUM_CLASS(OriginPos)
+};
 
 struct GLFormats
 {
     // Constructs a zeroed object:
     GLFormats();
 
     GLenum color_texInternalFormat;
     GLenum color_texFormat;
--- a/gfx/gl/SurfaceTypes.h
+++ b/gfx/gl/SurfaceTypes.h
@@ -1,17 +1,16 @@
 /* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef SURFACE_TYPES_H_
 #define SURFACE_TYPES_H_
 
-#include "mozilla/TypedEnum.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/Attributes.h"
 #include <stdint.h>
 
 namespace mozilla {
 namespace layers {
 class ISurfaceAllocator;
 }
@@ -62,36 +61,36 @@ struct SurfaceCaps MOZ_FINAL
         SurfaceCaps caps;
 
         caps.any = true;
 
         return caps;
     }
 };
 
-MOZ_BEGIN_ENUM_CLASS(SharedSurfaceType, uint8_t)
+enum class SharedSurfaceType : uint8_t {
     Unknown = 0,
 
     Basic,
     GLTextureShare,
     EGLImageShare,
     EGLSurfaceANGLE,
     DXGLInterop,
     DXGLInterop2,
     Gralloc,
     IOSurface,
 
     Max
-MOZ_END_ENUM_CLASS(SharedSurfaceType)
+};
 
-MOZ_BEGIN_ENUM_CLASS(AttachmentType, uint8_t)
+enum class AttachmentType : uint8_t {
     Screen = 0,
 
     GLTexture,
     GLRenderbuffer,
 
     Max
-MOZ_END_ENUM_CLASS(AttachmentType)
+};
 
 } /* namespace gfx */
 } /* namespace mozilla */
 
 #endif /* SURFACE_TYPES_H_ */
--- a/gfx/ipc/GfxMessageUtils.h
+++ b/gfx/ipc/GfxMessageUtils.h
@@ -29,23 +29,17 @@
 
 #ifdef _MSC_VER
 #pragma warning( disable : 4800 )
 #endif
 
 namespace mozilla {
 
 typedef gfxImageFormat PixelFormat;
-#if defined(MOZ_HAVE_CXX11_STRONG_ENUMS)
 typedef ::GraphicsFilter GraphicsFilterType;
-#else
-// If we don't have support for enum classes, then we need to use the actual
-// enum type here instead of the simulated enum class.
-typedef GraphicsFilter::Enum GraphicsFilterType;
-#endif
 
 } // namespace mozilla
 
 namespace IPC {
 
 template<>
 struct ParamTraits<mozilla::gfx::Matrix>
 {
@@ -193,119 +187,119 @@ struct ParamTraits<gfxRect>
            ReadParam(aMsg, aIter, &aResult->y) &&
            ReadParam(aMsg, aIter, &aResult->width) &&
            ReadParam(aMsg, aIter, &aResult->height);
   }
 };
 
 template <>
 struct ParamTraits<gfxContentType>
-  : public ContiguousTypedEnumSerializer<
+  : public ContiguousEnumSerializer<
              gfxContentType,
              gfxContentType::COLOR,
              gfxContentType::SENTINEL>
 {};
 
 template <>
 struct ParamTraits<gfxSurfaceType>
-  : public ContiguousTypedEnumSerializer<
+  : public ContiguousEnumSerializer<
              gfxSurfaceType,
              gfxSurfaceType::Image,
              gfxSurfaceType::Max>
 {};
 
 template <>
 struct ParamTraits<mozilla::GraphicsFilterType>
   : public ContiguousEnumSerializer<
              mozilla::GraphicsFilterType,
              GraphicsFilter::FILTER_FAST,
              GraphicsFilter::FILTER_SENTINEL>
 {};
 
 template <>
 struct ParamTraits<mozilla::layers::LayersBackend>
-  : public ContiguousTypedEnumSerializer<
+  : public ContiguousEnumSerializer<
              mozilla::layers::LayersBackend,
              mozilla::layers::LayersBackend::LAYERS_NONE,
              mozilla::layers::LayersBackend::LAYERS_LAST>
 {};
 
 template <>
 struct ParamTraits<mozilla::layers::ScaleMode>
-  : public ContiguousTypedEnumSerializer<
+  : public ContiguousEnumSerializer<
              mozilla::layers::ScaleMode,
              mozilla::layers::ScaleMode::SCALE_NONE,
              mozilla::layers::ScaleMode::SENTINEL>
 {};
 
 template <>
 struct ParamTraits<gfxImageFormat>
-  : public ContiguousTypedEnumSerializer<
+  : public ContiguousEnumSerializer<
              gfxImageFormat,
              gfxImageFormat::ARGB32,
              gfxImageFormat::Unknown>
 {};
 
 template <>
 struct ParamTraits<mozilla::gfx::AttributeName>
   : public ContiguousEnumSerializer<
              mozilla::gfx::AttributeName,
              mozilla::gfx::eBlendBlendmode,
              mozilla::gfx::eLastAttributeName>
 {};
 
 template <>
 struct ParamTraits<mozilla::gfx::AttributeType>
-  : public ContiguousTypedEnumSerializer<
+  : public ContiguousEnumSerializer<
              mozilla::gfx::AttributeType,
              mozilla::gfx::AttributeType::eBool,
              mozilla::gfx::AttributeType::Max>
 {};
 
 template <>
 struct ParamTraits<mozilla::gfx::PrimitiveType>
-  : public ContiguousTypedEnumSerializer<
+  : public ContiguousEnumSerializer<
              mozilla::gfx::PrimitiveType,
              mozilla::gfx::PrimitiveType::Empty,
              mozilla::gfx::PrimitiveType::Max>
 {};
 
 template <>
 struct ParamTraits<mozilla::gfx::ColorSpace>
-  : public ContiguousTypedEnumSerializer<
+  : public ContiguousEnumSerializer<
              mozilla::gfx::ColorSpace,
              mozilla::gfx::ColorSpace::SRGB,
              mozilla::gfx::ColorSpace::Max>
 {};
 
 template <>
 struct ParamTraits<mozilla::layers::TextureFlags>
-  : public BitFlagsTypedEnumSerializer<
+  : public BitFlagsEnumSerializer<
             mozilla::layers::TextureFlags,
             mozilla::layers::TextureFlags::ALL_BITS>
 {};
 
 template <>
 struct ParamTraits<mozilla::layers::TextureIdentifier>
-  : public ContiguousTypedEnumSerializer<
+  : public ContiguousEnumSerializer<
              mozilla::layers::TextureIdentifier,
              mozilla::layers::TextureIdentifier::Front,
              mozilla::layers::TextureIdentifier::HighBound>
 {};
 
 template <>
 struct ParamTraits<mozilla::layers::DeprecatedTextureHostFlags>
-  : public BitFlagsTypedEnumSerializer<
+  : public BitFlagsEnumSerializer<
              mozilla::layers::DeprecatedTextureHostFlags,
              mozilla::layers::DeprecatedTextureHostFlags::ALL_BITS>
 {};
 
 template <>
 struct ParamTraits<mozilla::layers::DiagnosticTypes>
-  : public BitFlagsTypedEnumSerializer<
+  : public BitFlagsEnumSerializer<
              mozilla::layers::DiagnosticTypes,
              mozilla::layers::DiagnosticTypes::ALL_BITS>
 {};
 
 /*
 template <>
 struct ParamTraits<mozilla::PixelFormat>
   : public EnumSerializer<mozilla::PixelFormat,
@@ -849,25 +843,25 @@ struct ParamTraits<mozilla::layers::Text
     return ReadParam(aMsg, aIter, &aResult->mCompositableType) &&
            ReadParam(aMsg, aIter, &aResult->mDeprecatedTextureHostFlags) &&
            ReadParam(aMsg, aIter, &aResult->mTextureFlags);
   }
 };
 
 template <>
 struct ParamTraits<mozilla::layers::CompositableType>
-  : public ContiguousTypedEnumSerializer<
+  : public ContiguousEnumSerializer<
              mozilla::layers::CompositableType,
              mozilla::layers::CompositableType::UNKNOWN,
              mozilla::layers::CompositableType::COUNT>
 {};
 
 template <>
 struct ParamTraits<mozilla::gfx::SurfaceFormat>
-  : public ContiguousTypedEnumSerializer<
+  : public ContiguousEnumSerializer<
              mozilla::gfx::SurfaceFormat,
              mozilla::gfx::SurfaceFormat::B8G8R8A8,
              mozilla::gfx::SurfaceFormat::UNKNOWN>
 {};
 
 template <>
 struct ParamTraits<mozilla::layers::ScrollableLayerGuid>
 {
--- a/gfx/layers/CompositorTypes.h
+++ b/gfx/layers/CompositorTypes.h
@@ -8,29 +8,28 @@
 
 #include <stdint.h>                     // for uint32_t
 #include <sys/types.h>                  // for int32_t
 #include "LayersTypes.h"                // for LayersBackend, etc
 #include "nsXULAppAPI.h"                // for GeckoProcessType, etc
 #include "mozilla/gfx/Types.h"
 #include "mozilla/EnumSet.h"
 
-#include "mozilla/TypedEnum.h"
 #include "mozilla/TypedEnumBits.h"
 
 namespace mozilla {
 namespace layers {
 
 /**
  * Flags used by texture clients and texture hosts. These are passed from client
  * side to host side when textures and compositables are created. Usually set
  * by the compositableCient, they may be modified by either the compositable or
  * texture clients.
  */
-MOZ_BEGIN_ENUM_CLASS(TextureFlags, uint32_t)
+enum class TextureFlags : uint32_t {
   NO_FLAGS           = 0,
   // Use nearest-neighbour texture filtering (as opposed to linear filtering).
   USE_NEAREST_FILTER = 1 << 0,
   // The compositor assumes everything is origin-top-left by default.
   ORIGIN_BOTTOM_LEFT = 1 << 1,
   // Force the texture to be represented using a single tile (note that this means
   // tiled textures, not tiled layers).
   DISALLOW_BIGIMAGE  = 1 << 2,
@@ -62,105 +61,105 @@ MOZ_BEGIN_ENUM_CLASS(TextureFlags, uint3
   IMMEDIATE_UPLOAD   = 1 << 8,
   // The texture is part of a component-alpha pair
   COMPONENT_ALPHA    = 1 << 9,
 
   // OR union of all valid bits
   ALL_BITS           = (1 << 10) - 1,
   // the default flags
   DEFAULT = NO_FLAGS
-MOZ_END_ENUM_CLASS(TextureFlags)
+};
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(TextureFlags)
 
 static inline bool
 TextureRequiresLocking(TextureFlags aFlags)
 {
   // If we're not double buffered, or uploading
   // within a transaction, then we need to support
   // locking correctly.
   return !(aFlags & (TextureFlags::IMMEDIATE_UPLOAD |
                      TextureFlags::IMMUTABLE));
 }
 
 /**
  * The type of debug diagnostic to enable.
  */
-MOZ_BEGIN_ENUM_CLASS(DiagnosticTypes, uint8_t)
+enum class DiagnosticTypes : uint8_t {
   NO_DIAGNOSTIC    = 0,
   TILE_BORDERS     = 1 << 0,
   LAYER_BORDERS    = 1 << 1,
   BIGIMAGE_BORDERS = 1 << 2,
   FLASH_BORDERS    = 1 << 3,
   ALL_BITS         = (1 << 4) - 1
-MOZ_END_ENUM_CLASS(DiagnosticTypes)
+};
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(DiagnosticTypes)
 
 #define DIAGNOSTIC_FLASH_COUNTER_MAX 100
 
 /**
  * Information about the object that is being diagnosed.
  */
-MOZ_BEGIN_ENUM_CLASS(DiagnosticFlags, uint16_t)
+enum class DiagnosticFlags : uint16_t {
   NO_DIAGNOSTIC   = 0,
   IMAGE           = 1 << 0,
   CONTENT         = 1 << 1,
   CANVAS          = 1 << 2,
   COLOR           = 1 << 3,
   CONTAINER       = 1 << 4,
   TILE            = 1 << 5,
   BIGIMAGE        = 1 << 6,
   COMPONENT_ALPHA = 1 << 7,
   REGION_RECT     = 1 << 8
-MOZ_END_ENUM_CLASS(DiagnosticFlags)
+};
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(DiagnosticFlags)
 
 /**
  * See gfx/layers/Effects.h
  */
-MOZ_BEGIN_ENUM_CLASS(EffectTypes, uint8_t)
+enum class EffectTypes : uint8_t {
   MASK,
   BLEND_MODE,
   COLOR_MATRIX,
   MAX_SECONDARY, // sentinel for the count of secondary effect types
   RGB,
   YCBCR,
   COMPONENT_ALPHA,
   SOLID_COLOR,
   RENDER_TARGET,
   VR_DISTORTION,
   MAX  //sentinel for the count of all effect types
-MOZ_END_ENUM_CLASS(EffectTypes)
+};
 
 /**
  * How the Compositable should manage textures.
  */
-MOZ_BEGIN_ENUM_CLASS(CompositableType, uint8_t)
+enum class CompositableType : uint8_t {
   UNKNOWN,
   CONTENT_INC,     // painted layer interface, only sends incremental
                    // updates to a texture on the compositor side.
   CONTENT_TILED,   // tiled painted layer
   IMAGE,           // image with single buffering
   IMAGE_OVERLAY,   // image without buffer
   IMAGE_BRIDGE,    // ImageBridge protocol
   CONTENT_SINGLE,  // painted layer interface, single buffering
   CONTENT_DOUBLE,  // painted layer interface, double buffering
   COUNT
-MOZ_END_ENUM_CLASS(CompositableType)
+};
 
 /**
  * How the texture host is used for composition,
  * XXX - Only used by ContentClientIncremental
  */
-MOZ_BEGIN_ENUM_CLASS(DeprecatedTextureHostFlags, uint8_t)
+enum class DeprecatedTextureHostFlags : uint8_t {
   DEFAULT = 0,       // The default texture host for the given SurfaceDescriptor
   TILED = 1 << 0,    // A texture host that supports tiling
   COPY_PREVIOUS = 1 << 1, // Texture contents should be initialized
                                       // from the previous texture.
   ALL_BITS = (1 << 2) - 1
-MOZ_END_ENUM_CLASS(DeprecatedTextureHostFlags)
+};
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(DeprecatedTextureHostFlags)
 
 #ifdef XP_WIN
 typedef void* SyncHandle;
 #else
 typedef uintptr_t SyncHandle;
 #endif // XP_WIN
 
@@ -196,23 +195,23 @@ struct TextureFactoryIdentifier
 };
 
 /**
  * Identify a texture to a compositable. Many textures can have the same id, but
  * the id is unique for any texture owned by a particular compositable.
  * XXX - We don't really need this, it will be removed along with the incremental
  * ContentClient/Host.
  */
-MOZ_BEGIN_ENUM_CLASS(TextureIdentifier, uint8_t)
+enum class TextureIdentifier : uint8_t {
   Front = 1,
   Back = 2,
   OnWhiteFront = 3,
   OnWhiteBack = 4,
   HighBound
-MOZ_END_ENUM_CLASS(TextureIdentifier)
+};
 
 /**
  * Information required by the compositor from the content-side for creating or
  * using compositables and textures.
  * XXX - TextureInfo is a bad name: this information is useful for the compositable,
  * not the Texture. And ith new Textures, only the compositable type is really
  * useful. This may (should) be removed in the near future.
  */
@@ -244,31 +243,31 @@ struct TextureInfo
   }
 };
 
 /**
  * How a SurfaceDescriptor will be opened.
  *
  * See ShadowLayerForwarder::OpenDescriptor for example.
  */
-MOZ_BEGIN_ENUM_CLASS(OpenMode, uint8_t)
+enum class OpenMode : uint8_t {
   OPEN_NONE        = 0,
   OPEN_READ        = 0x1,
   OPEN_WRITE       = 0x2,
   OPEN_READ_WRITE  = OPEN_READ|OPEN_WRITE,
   OPEN_READ_ONLY   = OPEN_READ,
   OPEN_WRITE_ONLY  = OPEN_WRITE
-MOZ_END_ENUM_CLASS(OpenMode)
+};
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(OpenMode)
 
 // The kinds of mask texture a shader can support
 // We rely on the items in this enum being sequential
-MOZ_BEGIN_ENUM_CLASS(MaskType, uint8_t)
+enum class MaskType : uint8_t {
   MaskNone = 0,   // no mask layer
   Mask2d,         // mask layer for layers with 2D transforms
   Mask3d,         // mask layer for layers with 3D transforms
   NumMaskTypes
-MOZ_END_ENUM_CLASS(MaskType)
+};
 
 } // namespace layers
 } // namespace mozilla
 
 #endif
--- a/gfx/layers/ImageTypes.h
+++ b/gfx/layers/ImageTypes.h
@@ -1,21 +1,19 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GFX_IMAGETYPES_H
 #define GFX_IMAGETYPES_H
 
-#include "mozilla/TypedEnum.h"
-
 namespace mozilla {
 
-MOZ_BEGIN_ENUM_CLASS(ImageFormat)
+enum class ImageFormat {
   /**
    * The PLANAR_YCBCR format creates a PlanarYCbCrImage. All backends should
    * support this format, because the Ogg video decoder depends on it.
    * The maximum image width and height is 16384.
    */
   PLANAR_YCBCR,
 
   /**
@@ -79,21 +77,21 @@ MOZ_BEGIN_ENUM_CLASS(ImageFormat)
    */
   D3D9_RGB32_TEXTURE,
 
   /**
    * An Image type carries an opaque handle once for each stream.
    * The opaque handle would be a platform specific identifier.
    */
   OVERLAY_IMAGE
-MOZ_END_ENUM_CLASS(ImageFormat)
+};
 
-MOZ_BEGIN_ENUM_CLASS(StereoMode)
+enum class StereoMode {
   MONO,
   LEFT_RIGHT,
   RIGHT_LEFT,
   BOTTOM_TOP,
   TOP_BOTTOM
-MOZ_END_ENUM_CLASS(StereoMode)
+};
 
 } // namespace
 
 #endif
--- a/gfx/layers/LayersTypes.h
+++ b/gfx/layers/LayersTypes.h
@@ -5,17 +5,16 @@
 
 #ifndef GFX_LAYERSTYPES_H
 #define GFX_LAYERSTYPES_H
 
 #include <stdint.h>                     // for uint32_t
 #include "nsPoint.h"                    // for nsIntPoint
 #include "nsRegion.h"
 
-#include "mozilla/TypedEnum.h"
 #include "mozilla/TypedEnumBits.h"
 
 #ifdef MOZ_WIDGET_GONK
 #include <ui/GraphicBuffer.h>
 #endif
 #if defined(DEBUG) || defined(PR_LOGGING)
 #  include <stdio.h>            // FILE
 #  include "prlog.h"            // for PR_LOG
@@ -41,58 +40,58 @@ class GraphicBuffer;
 namespace mozilla {
 namespace layers {
 
 class TextureHost;
 
 #undef NONE
 #undef OPAQUE
 
-MOZ_BEGIN_ENUM_CLASS(LayersBackend, int8_t)
+enum class LayersBackend : int8_t {
   LAYERS_NONE = 0,
   LAYERS_BASIC,
   LAYERS_OPENGL,
   LAYERS_D3D9,
   LAYERS_D3D10,
   LAYERS_D3D11,
   LAYERS_CLIENT,
   LAYERS_LAST
-MOZ_END_ENUM_CLASS(LayersBackend)
+};
 
-MOZ_BEGIN_ENUM_CLASS(BufferMode, int8_t)
+enum class BufferMode : int8_t {
   BUFFER_NONE,
   BUFFERED
-MOZ_END_ENUM_CLASS(BufferMode)
+};
 
-MOZ_BEGIN_ENUM_CLASS(DrawRegionClip, int8_t)
+enum class DrawRegionClip : int8_t {
   DRAW,
   NONE
-MOZ_END_ENUM_CLASS(DrawRegionClip)
+};
 
-MOZ_BEGIN_ENUM_CLASS(SurfaceMode, int8_t)
+enum class SurfaceMode : int8_t {
   SURFACE_NONE = 0,
   SURFACE_OPAQUE,
   SURFACE_SINGLE_CHANNEL_ALPHA,
   SURFACE_COMPONENT_ALPHA
-MOZ_END_ENUM_CLASS(SurfaceMode)
+};
 
 // LayerRenderState for Composer2D
 // We currently only support Composer2D using gralloc. If we want to be backed
 // by other surfaces we will need a more generic LayerRenderState.
-MOZ_BEGIN_ENUM_CLASS(LayerRenderStateFlags, int8_t)
+enum class LayerRenderStateFlags : int8_t {
   LAYER_RENDER_STATE_DEFAULT = 0,
   ORIGIN_BOTTOM_LEFT = 1 << 0,
   BUFFER_ROTATION = 1 << 1,
   // Notify Composer2D to swap the RB pixels of gralloc buffer
   FORMAT_RB_SWAP = 1 << 2,
   // We record opaqueness here alongside the actual surface we're going to
   // render. This avoids confusion when a layer might return different kinds
   // of surfaces over time (e.g. video frames).
   OPAQUE = 1 << 3
-MOZ_END_ENUM_CLASS(LayerRenderStateFlags)
+};
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(LayerRenderStateFlags)
 
 // The 'ifdef MOZ_WIDGET_GONK' sadness here is because we don't want to include
 // android::sp unless we have to.
 struct LayerRenderState {
   LayerRenderState()
 #ifdef MOZ_WIDGET_GONK
     : mFlags(LayerRenderStateFlags::LAYER_RENDER_STATE_DEFAULT)
@@ -146,22 +145,22 @@ struct LayerRenderState {
   android::sp<android::GraphicBuffer> mSurface;
   int32_t mOverlayId;
   // size of mSurface
   nsIntSize mSize;
   TextureHost* mTexture;
 #endif
 };
 
-MOZ_BEGIN_ENUM_CLASS(ScaleMode, int8_t)
+enum class ScaleMode : int8_t {
   SCALE_NONE,
   STRETCH,
   SENTINEL
 // Unimplemented - PRESERVE_ASPECT_RATIO_CONTAIN
-MOZ_END_ENUM_CLASS(ScaleMode)
+};
 
 struct EventRegions {
   nsIntRegion mHitRegion;
   nsIntRegion mDispatchToContentHitRegion;
 
   EventRegions()
   {
   }
--- a/gfx/layers/client/TextureClient.h
+++ b/gfx/layers/client/TextureClient.h
@@ -84,19 +84,19 @@ typedef uintptr_t SyncHandle;
 class SyncObject : public RefCounted<SyncObject>
 {
 public:
   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SyncObject)
   virtual ~SyncObject() { }
 
   static TemporaryRef<SyncObject> CreateSyncObject(SyncHandle aHandle);
 
-  MOZ_BEGIN_NESTED_ENUM_CLASS(SyncType)
+  enum class SyncType {
     D3D11,
-  MOZ_END_NESTED_ENUM_CLASS(SyncType)
+  };
 
   virtual SyncType GetSyncType() = 0;
   virtual void FinalizeFrame() = 0;
 
 protected:
   SyncObject() { }
 };
 
--- a/gfx/src/FilterSupport.h
+++ b/gfx/src/FilterSupport.h
@@ -3,17 +3,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __FilterSupport_h
 #define __FilterSupport_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/RefPtr.h"
-#include "mozilla/TypedEnum.h"
 #include "mozilla/gfx/Rect.h"
 #include "mozilla/gfx/Matrix.h"
 #include "mozilla/gfx/2D.h"
 #include "nsClassHashtable.h"
 #include "nsTArray.h"
 #include "nsRegion.h"
 
 namespace mozilla {
@@ -157,31 +156,31 @@ enum AttributeName {
   eLastAttributeName
 };
 
 class DrawTarget;
 class SourceSurface;
 class FilterNode;
 struct FilterAttribute;
 
-MOZ_BEGIN_ENUM_CLASS(AttributeType)
+enum class AttributeType {
   eBool,
   eUint,
   eFloat,
   eSize,
   eIntSize,
   eIntPoint,
   eMatrix,
   eMatrix5x4,
   ePoint3D,
   eColor,
   eAttributeMap,
   eFloats,
   Max
-MOZ_END_ENUM_CLASS(AttributeType)
+};
 
 // Limits
 const float kMaxStdDeviation = 500;
 
 // A class that stores values of different types, keyed by an attribute name.
 // The Get*() methods assert that they're called for the same type that the
 // attribute was Set() with.
 // AttributeMaps can be nested because AttributeMap is a valid attribute type.
@@ -226,26 +225,26 @@ public:
   typedef bool (*AttributeHandleCallback)(AttributeName aName, AttributeType aType, void* aUserData);
   void EnumerateRead(AttributeHandleCallback aCallback, void* aUserData) const;
   uint32_t Count() const;
 
 private:
   mutable nsClassHashtable<nsUint32HashKey, FilterAttribute>  mMap;
 };
 
-MOZ_BEGIN_ENUM_CLASS(ColorSpace)
+enum class ColorSpace {
   SRGB,
   LinearRGB,
   Max
-MOZ_END_ENUM_CLASS(ColorSpace)
+};
 
-MOZ_BEGIN_ENUM_CLASS(AlphaModel)
+enum class AlphaModel {
   Unpremultiplied,
   Premultiplied
-MOZ_END_ENUM_CLASS(AlphaModel)
+};
 
 class ColorModel {
 public:
   static ColorModel PremulSRGB()
   {
     return ColorModel(ColorSpace::SRGB, AlphaModel::Premultiplied);
   }
 
@@ -263,17 +262,17 @@ public:
   {
     return (uint8_t(mColorSpace) << 1) + uint8_t(mAlphaModel);
   }
 
   ColorSpace mColorSpace;
   AlphaModel mAlphaModel;
 };
 
-MOZ_BEGIN_ENUM_CLASS(PrimitiveType)
+enum class PrimitiveType {
   Empty = 0,
   Blend,
   Morphology,
   ColorMatrix,
   Flood,
   Tile,
   ComponentTransfer,
   ConvolveMatrix,
@@ -284,17 +283,17 @@ MOZ_BEGIN_ENUM_CLASS(PrimitiveType)
   Merge,
   Image,
   GaussianBlur,
   DropShadow,
   DiffuseLighting,
   SpecularLighting,
   ToAlpha,
   Max
-MOZ_END_ENUM_CLASS(PrimitiveType)
+};
 
 /**
  * A data structure to carry attributes for a given primitive that's part of a
  * filter. Will be serializable via IPDL, so it must not contain complex
  * functionality.
  * Used as part of a FilterDescription.
  */
 class FilterPrimitiveDescription MOZ_FINAL {
--- a/gfx/src/nsRegion.h
+++ b/gfx/src/nsRegion.h
@@ -13,17 +13,16 @@
 #include "mozilla/ToString.h"           // for mozilla::ToString
 #include "nsCoord.h"                    // for nscoord
 #include "nsError.h"                    // for nsresult
 #include "nsPoint.h"                    // for nsIntPoint, nsPoint
 #include "nsRect.h"                     // for nsIntRect, nsRect
 #include "nsMargin.h"                   // for nsIntMargin
 #include "nsStringGlue.h"               // for nsCString
 #include "xpcom-config.h"               // for CPP_THROW_NEW
-#include "mozilla/TypedEnum.h"          // for the VisitEdges typed enum
 #include "mozilla/Move.h"               // for mozilla::Move
 
 class nsIntRegion;
 class gfx3DMatrix;
 
 #include "pixman.h"
 
 /* For information on the internal representation look at pixman-region.c
@@ -35,22 +34,22 @@ class gfx3DMatrix;
  * representation. This means that nsIntRegion will have more predictable
  * performance characteristics than the old nsRegion and should not become
  * degenerate.
  *
  * The pixman region code originates from X11 which has spread to a variety of
  * projects including Qt, Gtk, Wine. It should perform reasonably well.
  */
 
-MOZ_BEGIN_ENUM_CLASS(VisitSide)
+enum class VisitSide {
 	TOP,
 	BOTTOM,
 	LEFT,
 	RIGHT
-MOZ_END_ENUM_CLASS(VisitSide)
+};
 
 class nsRegionRectIterator;
 
 class nsRegion
 {
 
   friend class nsRegionRectIterator;
 
--- a/gfx/thebes/DrawMode.h
+++ b/gfx/thebes/DrawMode.h
@@ -1,27 +1,25 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef DrawMode_h
 #define DrawMode_h
 
-#include "mozilla/TypedEnum.h"
-
 // Options for how the text should be drawn
-MOZ_BEGIN_ENUM_CLASS(DrawMode, int)
+enum class DrawMode : int {
   // GLYPH_FILL and GLYPH_STROKE draw into the current context
   //  and may be used together with bitwise OR.
   GLYPH_FILL = 1,
   // Note: using GLYPH_STROKE will destroy the current path.
   GLYPH_STROKE = 2,
   // Appends glyphs to the current path. Can NOT be used with
   //  GLYPH_FILL or GLYPH_STROKE.
   GLYPH_PATH = 4,
   // When GLYPH_FILL and GLYPH_STROKE are both set, draws the
   //  stroke underneath the fill.
   GLYPH_STROKE_UNDERNEATH = 8
-MOZ_END_ENUM_CLASS(DrawMode)
+};
 
 #endif
 
--- a/gfx/thebes/GraphicsFilter.h
+++ b/gfx/thebes/GraphicsFilter.h
@@ -1,22 +1,20 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GraphicsFilter_h
 #define GraphicsFilter_h
 
-#include "mozilla/TypedEnum.h"
-
-MOZ_BEGIN_ENUM_CLASS(GraphicsFilter, int)
+enum class GraphicsFilter : int {
   FILTER_FAST,
   FILTER_GOOD,
   FILTER_BEST,
   FILTER_NEAREST,
   FILTER_BILINEAR,
   FILTER_GAUSSIAN,
   FILTER_SENTINEL
-MOZ_END_ENUM_CLASS(GraphicsFilter)
+};
 
 #endif
 
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GFX_PREFS_H
 #define GFX_PREFS_H
 
 #include <stdint.h>
 #include "mozilla/Assertions.h"
 #include "mozilla/Constants.h"   // for M_PI
-#include "mozilla/TypedEnum.h"
 
 // First time gfxPrefs::GetSingleton() needs to be called on the main thread,
 // before any of the methods accessing the values are used, but after
 // the Preferences system has been initialized.
 
 // The static methods to access the preference value are safe to call
 // from any thread after that first call.
 
@@ -73,24 +72,24 @@ class gfxPrefs;
 class gfxPrefs MOZ_FINAL
 {
 private:
   /// See Logging.h.  This lets Moz2D access preference values it owns.
   PreferenceAccessImpl* mMoz2DPrefAccess;
 
 private:
   // Enums for the update policy.
-  MOZ_BEGIN_NESTED_ENUM_CLASS(UpdatePolicy)
+  enum class UpdatePolicy {
     Skip, // Set the value to default, skip any Preferences calls
     Once, // Evaluate the preference once, unchanged during the session
     Live  // Evaluate the preference and set callback so it stays current/live
-  MOZ_END_NESTED_ENUM_CLASS(UpdatePolicy)
+  };
 
   // Since we cannot use const char*, use a function that returns it.
-  template <MOZ_ENUM_CLASS_ENUM_TYPE(UpdatePolicy) Update, class T, T Default(void), const char* Pref(void)>
+  template <UpdatePolicy Update, class T, T Default(void), const char* Pref(void)>
   class PrefTemplate
   {
   public:
     PrefTemplate()
     : mValue(Default())
     {
       Register(Update, Pref());
     }
--- a/gfx/thebes/gfxTypes.h
+++ b/gfx/thebes/gfxTypes.h
@@ -2,17 +2,16 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GFX_TYPES_H
 #define GFX_TYPES_H
 
 #include <stdint.h>
-#include "mozilla/TypedEnum.h"
 
 typedef struct _cairo_surface cairo_surface_t;
 typedef struct _cairo_user_data_key cairo_user_data_key_t;
 
 typedef void (*thebes_destroy_func_t) (void *data);
 
 /**
  * Currently needs to be 'double' for Cairo compatibility. Could
@@ -34,36 +33,36 @@ typedef double gfxFloat;
  *                    punctuation break and whitespace break (bug 389710).
  *                   As and when we implement it, text-wrap: unrestricted will
  *                    mean that priorities are ignored and all line-break
  *                    opportunities are equal.
  *
  * @see gfxTextRun::BreakAndMeasureText
  * @see nsLineLayout::NotifyOptionalBreakPosition
  */
-MOZ_BEGIN_ENUM_CLASS(gfxBreakPriority)
+enum class gfxBreakPriority {
   eNoBreak       = 0,
   eWordWrapBreak,
   eNormalBreak
-MOZ_END_ENUM_CLASS(gfxBreakPriority)
+};
 
 /**
   * The format for an image surface. For all formats with alpha data, 0
   * means transparent, 1 or 255 means fully opaque.
   */
-MOZ_BEGIN_ENUM_CLASS(gfxImageFormat)
+enum class gfxImageFormat {
   ARGB32, ///< ARGB data in native endianness, using premultiplied alpha
   RGB24,  ///< xRGB data in native endianness
   A8,     ///< Only an alpha channel
   A1,     ///< Packed transparency information (one byte refers to 8 pixels)
   RGB16_565,  ///< RGB_565 data in native endianness
   Unknown
-MOZ_END_ENUM_CLASS(gfxImageFormat)
+};
 
-MOZ_BEGIN_ENUM_CLASS(gfxSurfaceType)
+enum class gfxSurfaceType {
   Image,
   PDF,
   PS,
   Xlib,
   Xcb,
   Glitz,           // unused, but needed for cairo parity
   Quartz,
   Win32,
@@ -80,29 +79,29 @@ MOZ_BEGIN_ENUM_CLASS(gfxSurfaceType)
   GL,
   DRM,
   Tee,
   XML,
   Skia,
   Subsurface,
   D2D,
   Max
-MOZ_END_ENUM_CLASS(gfxSurfaceType)
+};
 
-MOZ_BEGIN_ENUM_CLASS(gfxContentType)
+enum class gfxContentType {
   COLOR       = 0x1000,
   ALPHA       = 0x2000,
   COLOR_ALPHA = 0x3000,
   SENTINEL    = 0xffff
-MOZ_END_ENUM_CLASS(gfxContentType)
+};
 
 /**
   * The memory used by a gfxASurface (as reported by KnownMemoryUsed()) can
   * either live in this process's heap, in this process but outside the
   * heap, or in another process altogether.
   */
-MOZ_BEGIN_ENUM_CLASS(gfxMemoryLocation)
+enum class gfxMemoryLocation {
   IN_PROCESS_HEAP,
   IN_PROCESS_NONHEAP,
   OUT_OF_PROCESS
-MOZ_END_ENUM_CLASS(gfxMemoryLocation)
+};
 
 #endif /* GFX_TYPES_H */
--- a/gfx/thebes/gfxVR.h
+++ b/gfx/thebes/gfxVR.h
@@ -12,20 +12,20 @@
 #include "nsRefPtr.h"
 
 #include "mozilla/gfx/2D.h"
 #include "mozilla/EnumeratedArray.h"
 
 namespace mozilla {
 namespace gfx {
 
-MOZ_BEGIN_ENUM_CLASS(VRHMDType, uint16_t)
+enum class VRHMDType : uint16_t {
   Oculus,
   NumHMDTypes
-MOZ_END_ENUM_CLASS(VRHMDType)
+};
 
 struct VRFieldOfView {
   static VRFieldOfView FromCSSPerspectiveInfo(double aPerspectiveDistance,
                                               const Point& aPerspectiveOrigin,
                                               const Point& aTransformOrigin,
                                               const Rect& aContentRectangle)
   {
     /**/
--- a/image/decoders/EXIF.h
+++ b/image/decoders/EXIF.h
@@ -2,29 +2,28 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_IMAGELIB_EXIF_H
 #define MOZILLA_IMAGELIB_EXIF_H
 
 #include <stdint.h>
-#include "mozilla/TypedEnum.h"
 #include "nsDebug.h"
 
 #include "Orientation.h"
 
 namespace mozilla {
 namespace image {
 
-MOZ_BEGIN_ENUM_CLASS(ByteOrder, uint8_t)
+enum class ByteOrder : uint8_t {
   Unknown,
   LittleEndian,
   BigEndian
-MOZ_END_ENUM_CLASS(ByteOrder)
+};
 
 struct EXIFData
 {
   EXIFData() { }
   explicit EXIFData(Orientation aOrientation) : orientation(aOrientation) { }
 
   const Orientation orientation;
 };
--- a/image/src/DecodePool.h
+++ b/image/src/DecodePool.h
@@ -7,17 +7,16 @@
  * DecodePool manages the threads used for decoding raster images.
  */
 
 #ifndef MOZILLA_IMAGELIB_DECODEPOOL_H_
 #define MOZILLA_IMAGELIB_DECODEPOOL_H_
 
 #include "mozilla/Mutex.h"
 #include "mozilla/StaticPtr.h"
-#include <mozilla/TypedEnum.h>
 #include "nsCOMPtr.h"
 #include "nsIEventTarget.h"
 #include "nsIObserver.h"
 
 class nsIThread;
 class nsIThreadPool;
 
 namespace mozilla {
--- a/image/src/Orientation.h
+++ b/image/src/Orientation.h
@@ -2,32 +2,31 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_IMAGELIB_ORIENTATION_H_
 #define MOZILLA_IMAGELIB_ORIENTATION_H_
 
 #include <stdint.h>
-#include "mozilla/TypedEnum.h"
 
 namespace mozilla {
 namespace image {
 
-MOZ_BEGIN_ENUM_CLASS(Angle, uint8_t)
+enum class Angle : uint8_t {
   D0,
   D90,
   D180,
   D270
-MOZ_END_ENUM_CLASS(Angle)
+};
 
-MOZ_BEGIN_ENUM_CLASS(Flip, uint8_t)
+enum class Flip : uint8_t {
   Unflipped,
   Horizontal
-MOZ_END_ENUM_CLASS(Flip)
+};
 
 /**
  * A struct that describes an image's orientation as a rotation optionally
  * followed by a reflection. This may be used to be indicate an image's inherent
  * orientation or a desired orientation for the image.
  */
 struct Orientation
 {
--- a/image/src/RasterImage.h
+++ b/image/src/RasterImage.h
@@ -25,17 +25,16 @@
 #include "imgFrame.h"
 #include "nsThreadUtils.h"
 #include "DecodePool.h"
 #include "Orientation.h"
 #include "nsIObserver.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/TimeStamp.h"
-#include "mozilla/TypedEnum.h"
 #include "mozilla/WeakPtr.h"
 #include "mozilla/UniquePtr.h"
 #ifdef DEBUG
   #include "imgIContainerDebug.h"
 #endif
 
 class nsIInputStream;
 class nsIThreadPool;
@@ -128,21 +127,21 @@ class Image;
 }
 
 namespace image {
 
 class Decoder;
 class FrameAnimator;
 class SourceBuffer;
 
-MOZ_BEGIN_ENUM_CLASS(DecodeStrategy, uint8_t)
+enum class DecodeStrategy : uint8_t {
   ASYNC,
   SYNC_FOR_SMALL_IMAGES,
   SYNC_IF_POSSIBLE
-MOZ_END_ENUM_CLASS(DecodeStrategy)
+};
 
 class RasterImage MOZ_FINAL : public ImageResource
                             , public nsIProperties
                             , public SupportsWeakPtr<RasterImage>
 #ifdef DEBUG
                             , public imgIContainerDebug
 #endif
 {
--- a/image/src/SurfaceCache.h
+++ b/image/src/SurfaceCache.h
@@ -112,26 +112,26 @@ VectorSurfaceKey(const gfx::IntSize& aSi
                  float aAnimationTime)
 {
   // We don't care about aFlags for VectorImage because none of the flags we
   // have right now influence VectorImage's rendering. If we add a new flag that
   // *does* affect how a VectorImage renders, we'll have to change this.
   return SurfaceKey(aSize, aSVGContext, aAnimationTime, 0);
 }
 
-MOZ_BEGIN_ENUM_CLASS(Lifetime, uint8_t)
+enum class Lifetime : uint8_t {
   Transient,
   Persistent
-MOZ_END_ENUM_CLASS(Lifetime)
+};
 
-MOZ_BEGIN_ENUM_CLASS(InsertOutcome, uint8_t)
+enum class InsertOutcome : uint8_t {
   SUCCESS,                 // Success (but see Insert documentation).
   FAILURE,                 // Couldn't insert (e.g., for capacity reasons).
   FAILURE_ALREADY_PRESENT  // A surface with the same key is already present.
-MOZ_END_ENUM_CLASS(InsertOutcome)
+};
 
 /**
  * SurfaceCache is an imagelib-global service that allows caching of temporary
  * surfaces. Surfaces normally expire from the cache automatically if they go
  * too long without being accessed.
  *
  * SurfaceCache does not hold surfaces directly; instead, it holds imgFrame
  * objects, which hold surfaces but also layer on additional features specific
--- a/image/src/imgFrame.h
+++ b/image/src/imgFrame.h
@@ -5,51 +5,50 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef imgFrame_h
 #define imgFrame_h
 
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Monitor.h"
 #include "mozilla/Move.h"
-#include "mozilla/TypedEnum.h"
 #include "mozilla/VolatileBuffer.h"
 #include "gfxDrawable.h"
 #include "imgIContainer.h"
 #include "MainThreadUtils.h"
 
 namespace mozilla {
 namespace image {
 
 class ImageRegion;
 class DrawableFrameRef;
 class RawAccessFrameRef;
 
-MOZ_BEGIN_ENUM_CLASS(BlendMethod, int8_t)
+enum class BlendMethod : int8_t {
   // All color components of the frame, including alpha, overwrite the current
   // contents of the frame's output buffer region.
   SOURCE,
 
   // The frame should be composited onto the output buffer based on its alpha,
   // using a simple OVER operation.
   OVER
-MOZ_END_ENUM_CLASS(BlendMethod)
+};
 
-MOZ_BEGIN_ENUM_CLASS(DisposalMethod, int8_t)
+enum class DisposalMethod : int8_t {
   CLEAR_ALL = -1,  // Clear the whole image, revealing what's underneath.
   NOT_SPECIFIED,   // Leave the frame and let the new frame draw on top.
   KEEP,            // Leave the frame and let the new frame draw on top.
   CLEAR,           // Clear the frame's area, revealing what's underneath.
   RESTORE_PREVIOUS // Restore the previous (composited) frame.
-MOZ_END_ENUM_CLASS(DisposalMethod)
+};
 
-MOZ_BEGIN_ENUM_CLASS(Opacity, uint8_t)
+enum class Opacity : uint8_t {
   OPAQUE,
   SOME_TRANSPARENCY
-MOZ_END_ENUM_CLASS(Opacity)
+};
 
 
 /**
  * AnimationData contains all of the information necessary for using an imgFrame
  * as part of an animation.
  *
  * It includes pointers to the raw image data of the underlying imgFrame, but
  * does not own that data. A RawAccessFrameRef for the underlying imgFrame must
--- a/image/src/imgLoader.h
+++ b/image/src/imgLoader.h
@@ -201,20 +201,20 @@ public:
   const_iterator end() const;
 
 private:
   queueContainer mQueue;
   bool mDirty;
   uint32_t mSize;
 };
 
-MOZ_BEGIN_ENUM_CLASS(AcceptedMimeTypes, uint8_t)
+enum class AcceptedMimeTypes : uint8_t {
   IMAGES,
   IMAGES_AND_DOCUMENTS,
-MOZ_END_ENUM_CLASS(AcceptedMimeTypes)
+};
 
 class imgLoader MOZ_FINAL : public imgILoader,
                             public nsIContentSniffer,
                             public imgICache,
                             public nsSupportsWeakReference,
                             public nsIObserver
 {
   virtual ~imgLoader();
--- a/ipc/glue/IPCMessageUtils.h
+++ b/ipc/glue/IPCMessageUtils.h
@@ -11,17 +11,16 @@
 #include "chrome/common/ipc_message_utils.h"
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/TimeStamp.h"
 #ifdef XP_WIN
 #include "mozilla/TimeStamp_windows.h"
 #endif
-#include "mozilla/TypedEnum.h"
 #include "mozilla/TypeTraits.h"
 #include "mozilla/IntegerTypeTraits.h"
 
 #include <stdint.h>
 
 #include "nsID.h"
 #include "nsMemory.h"
 #include "nsString.h"
@@ -124,64 +123,41 @@ struct EnumSerializer {
     *aResult = paramType(value);
     return true;
   }
 };
 
 template <typename E,
           E MinLegal,
           E HighBound>
-struct ContiguousEnumValidator
-{
-  static bool IsLegalValue(E e)
-  {
-    return MinLegal <= e && e < HighBound;
-  }
-};
-
-template <typename E,
-          MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) MinLegal,
-          MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) HighBound>
-class ContiguousTypedEnumValidator
+class ContiguousEnumValidator
 {
   // Silence overzealous -Wtype-limits bug in GCC fixed in GCC 4.8:
   // "comparison of unsigned expression >= 0 is always true"
   // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11856
   template <typename T>
   static bool IsLessThanOrEqual(T a, T b) { return a <= b; }
 
 public:
   static bool IsLegalValue(E e)
   {
-    typedef MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) ActualEnumType;
-    return IsLessThanOrEqual(MinLegal, ActualEnumType(e)) &&
-           ActualEnumType(e) < HighBound;
+    return IsLessThanOrEqual(MinLegal, e) && e < HighBound;
   }
 };
 
 template <typename E,
           E AllBits>
 struct BitFlagsEnumValidator
 {
   static bool IsLegalValue(E e)
   {
     return (e & AllBits) == e;
   }
 };
 
-template <typename E,
-          MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) AllBits>
-struct BitFlagsTypedEnumValidator
-{
-  static bool IsLegalValue(E e)
-  {
-    return (e & AllBits) == e;
-  }
-};
-
 /**
  * Specialization of EnumSerializer for enums with contiguous enum values.
  *
  * Provide two values: MinLegal, HighBound. An enum value x will be
  * considered legal if MinLegal <= x < HighBound.
  *
  * For example, following is definition of serializer for enum type FOO.
  * \code
@@ -197,29 +173,16 @@ template <typename E,
           E MinLegal,
           E HighBound>
 struct ContiguousEnumSerializer
   : EnumSerializer<E,
                    ContiguousEnumValidator<E, MinLegal, HighBound>>
 {};
 
 /**
- * Similar to ContiguousEnumSerializer, but for MFBT typed enums
- * as constructed by MOZ_BEGIN_ENUM_CLASS. This can go away when
- * we drop MOZ_BEGIN_ENUM_CLASS and use C++11 enum classes directly.
- */
-template <typename E,
-          MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) MinLegal,
-          MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) HighBound>
-struct ContiguousTypedEnumSerializer
-  : EnumSerializer<E,
-                   ContiguousTypedEnumValidator<E, MinLegal, HighBound>>
-{};
-
-/**
  * Specialization of EnumSerializer for enums representing bit flags.
  *
  * Provide one value: AllBits. An enum value x will be
  * considered legal if (x & AllBits) == x;
  *
  * Example:
  * \code
  * enum FOO {
@@ -236,28 +199,16 @@ struct ContiguousTypedEnumSerializer
  */
 template <typename E,
           E AllBits>
 struct BitFlagsEnumSerializer
   : EnumSerializer<E,
                    BitFlagsEnumValidator<E, AllBits>>
 {};
 
-/**
- * Similar to BitFlagsEnumSerializer, but for MFBT typed enums
- * as constructed by MOZ_BEGIN_ENUM_CLASS. This can go away when
- * we drop MOZ_BEGIN_ENUM_CLASS and use C++11 enum classes directly.
- */
-template <typename E,
-          MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) AllBits>
-struct BitFlagsTypedEnumSerializer
-  : EnumSerializer<E,
-                   BitFlagsTypedEnumValidator<E, AllBits>>
-{};
-
 template <>
 struct ParamTraits<base::ChildPrivileges>
   : public ContiguousEnumSerializer<base::ChildPrivileges,
                                     base::PRIVILEGES_DEFAULT,
                                     base::PRIVILEGES_LAST>
 { };
 
 template<>
--- a/js/public/Class.h
+++ b/js/public/Class.h
@@ -579,17 +579,21 @@ Valueify(const JSClass *c)
 
 /*
  * Enumeration describing possible values of the [[Class]] internal property
  * value of objects.
  */
 enum ESClassValue {
     ESClass_Object, ESClass_Array, ESClass_Number, ESClass_String,
     ESClass_Boolean, ESClass_RegExp, ESClass_ArrayBuffer, ESClass_SharedArrayBuffer,
-    ESClass_Date, ESClass_Set, ESClass_Map
+    ESClass_Date, ESClass_Set, ESClass_Map,
+
+    // Special snowflake for the ES6 IsArray method.
+    // Please don't use it without calling that function.
+    ESClass_IsArray
 };
 
 /*
  * Return whether the given object has the given [[Class]] internal property
  * value. Beware, this query says nothing about the js::Class of the JSObject
  * so the caller must not assume anything about obj's representation (e.g., obj
  * may be a proxy).
  */
--- a/js/public/ProfilingStack.h
+++ b/js/public/ProfilingStack.h
@@ -2,18 +2,16 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef js_ProfilingStack_h
 #define js_ProfilingStack_h
 
-#include "mozilla/TypedEnum.h"
-
 #include "jsbytecode.h"
 #include "jstypes.h"
 
 #include "js/Utility.h"
 
 struct JSRuntime;
 
 namespace js {
@@ -68,30 +66,30 @@ class ProfileEntry
         // into baseline.
         OSR = 0x08,
 
         // Mask for removing all flags except the category information.
         CATEGORY_MASK = ~IS_CPP_ENTRY & ~FRAME_LABEL_COPY & ~BEGIN_PSEUDO_JS & ~OSR
     };
 
     // Keep these in sync with browser/devtools/profiler/utils/global.js
-    MOZ_BEGIN_NESTED_ENUM_CLASS(Category, uint32_t)
+    enum class Category : uint32_t {
         OTHER    = 0x10,
         CSS      = 0x20,
         JS       = 0x40,
         GC       = 0x80,
         CC       = 0x100,
         NETWORK  = 0x200,
         GRAPHICS = 0x400,
         STORAGE  = 0x800,
         EVENTS   = 0x1000,
 
         FIRST    = OTHER,
         LAST     = EVENTS
-    MOZ_END_NESTED_ENUM_CLASS(Category)
+    };
 
     // All of these methods are marked with the 'volatile' keyword because SPS's
     // representation of the stack is stored such that all ProfileEntry
     // instances are volatile. These methods would not be available unless they
     // were marked as volatile as well.
 
     bool isCpp() const volatile { return hasFlag(IS_CPP_ENTRY); }
     bool isJs() const volatile { return !isCpp(); }
--- a/js/src/frontend/FoldConstants.cpp
+++ b/js/src/frontend/FoldConstants.cpp
@@ -2,17 +2,16 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "frontend/FoldConstants.h"
 
 #include "mozilla/FloatingPoint.h"
-#include "mozilla/TypedEnum.h"
 
 #include "jslibmath.h"
 
 #include "frontend/ParseNode.h"
 #include "frontend/Parser.h"
 #include "js/Conversions.h"
 
 #include "jscntxtinlines.h"
@@ -247,29 +246,29 @@ Boolish(ParseNode *pn)
 
       default:
         return Unknown;
     }
 }
 
 // Expressions that appear in a few specific places are treated specially
 // during constant folding. This enum tells where a parse node appears.
-MOZ_BEGIN_ENUM_CLASS(SyntacticContext, int)
+enum class SyntacticContext : int {
     // pn is an expression, and it appears in a context where only its side
     // effects and truthiness matter: the condition of an if statement,
     // conditional expression, while loop, or for(;;) loop; or an operand of &&
     // or || in such a context.
     Condition,
 
     // pn is the operand of the 'delete' keyword.
     Delete,
 
     // Any other syntactic context.
     Other
-MOZ_END_ENUM_CLASS(SyntacticContext)
+};
 
 static SyntacticContext
 condIf(const ParseNode *pn, ParseNodeKind kind)
 {
     return pn->isKind(kind) ? SyntacticContext::Condition : SyntacticContext::Other;
 }
 
 static bool
--- a/js/src/jit/BacktrackingAllocator.cpp
+++ b/js/src/jit/BacktrackingAllocator.cpp
@@ -307,16 +307,41 @@ BacktrackingAllocator::tryGroupReusedReg
     usedReg.setCanonicalSpillExclude(inputOf(reg.ins()));
 
     return tryGroupRegisters(use, def);
 }
 
 bool
 BacktrackingAllocator::groupAndQueueRegisters()
 {
+    // If there is an OSR block, group parameters in that block with the
+    // corresponding parameters in the initial block.
+    if (MBasicBlock *osr = graph.mir().osrBlock()) {
+        size_t originalVreg = 1;
+        for (LInstructionIterator iter = osr->lir()->begin(); iter != osr->lir()->end(); iter++) {
+            if (iter->isParameter()) {
+                for (size_t i = 0; i < iter->numDefs(); i++) {
+                    DebugOnly<bool> found = false;
+                    uint32_t paramVreg = iter->getDef(i)->virtualRegister();
+                    for (; originalVreg < paramVreg; originalVreg++) {
+                        if (*vregs[originalVreg].def()->output() == *iter->getDef(i)->output()) {
+                            MOZ_ASSERT(vregs[originalVreg].ins()->isParameter());
+                            if (!tryGroupRegisters(originalVreg, paramVreg))
+                                return false;
+                            MOZ_ASSERT(vregs[originalVreg].group() == vregs[paramVreg].group());
+                            found = true;
+                            break;
+                        }
+                    }
+                    MOZ_ASSERT(found);
+                }
+            }
+        }
+    }
+
     // Try to group registers with their reused inputs.
     // Virtual register number 0 is unused.
     MOZ_ASSERT(vregs[0u].numIntervals() == 0);
     for (size_t i = 1; i < graph.numVirtualRegisters(); i++) {
         BacktrackingVirtualRegister &reg = vregs[i];
         if (!reg.numIntervals())
             continue;
 
@@ -349,27 +374,24 @@ BacktrackingAllocator::groupAndQueueRegi
 
         BacktrackingVirtualRegister &reg = vregs[i];
         MOZ_ASSERT(reg.numIntervals() <= 2);
         MOZ_ASSERT(!reg.canonicalSpill());
 
         if (!reg.numIntervals())
             continue;
 
-        // Disable this for now; see bugs 906858, 931487, and 932465.
-#if 0
         // Eagerly set the canonical spill slot for registers which are fixed
         // for that slot, and reuse it for other registers in the group.
         LDefinition *def = reg.def();
         if (def->policy() == LDefinition::FIXED && !def->output()->isRegister()) {
             reg.setCanonicalSpill(*def->output());
             if (reg.group() && reg.group()->spill.isUse())
                 reg.group()->spill = *def->output();
         }
-#endif
 
         // Place all intervals for this register on the allocation queue.
         // During initial queueing use single queue items for groups of
         // registers, so that they will be allocated together and reduce the
         // risk of unnecessary conflicts. This is in keeping with the idea that
         // register groups are effectively single registers whose value changes
         // during execution. If any intervals in the group are evicted later
         // then they will be reallocated individually.
--- a/js/src/jit/IonTypes.h
+++ b/js/src/jit/IonTypes.h
@@ -3,17 +3,16 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jit_IonTypes_h
 #define jit_IonTypes_h
 
 #include "mozilla/HashFunctions.h"
-#include "mozilla/TypedEnum.h"
 
 #include "jstypes.h"
 
 #include "js/Value.h"
 
 namespace js {
 namespace jit {
 
@@ -627,25 +626,25 @@ enum ABIFunctionType
         (ArgType_General << (ArgType_Shift * 2)),
 
     // int f(int, double)
     Args_Int_IntDouble = Args_General0 |
         (ArgType_Double << (ArgType_Shift * 1)) |
         (ArgType_General << (ArgType_Shift * 2))
 };
 
-MOZ_BEGIN_ENUM_CLASS(BarrierKind, uint32_t)
+enum class BarrierKind : uint32_t {
     // No barrier is needed.
     NoBarrier,
 
     // The barrier only has to check the value's type tag is in the TypeSet.
     // Specific object types don't have to be checked.
     TypeTagOnly,
 
     // Check if the value is in the TypeSet, including the object type if it's
     // an object.
     TypeSet
-MOZ_END_ENUM_CLASS(BarrierKind)
+};
 
 } // namespace jit
 } // namespace js
 
 #endif /* jit_IonTypes_h */
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -8,17 +8,16 @@
 
 #ifndef jsapi_h
 #define jsapi_h
 
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Range.h"
 #include "mozilla/RangedPtr.h"
-#include "mozilla/TypedEnum.h"
 
 #include <stdarg.h>
 #include <stddef.h>
 #include <stdint.h>
 #include <stdio.h>
 
 #include "jsalloc.h"
 #include "jspubtd.h"
@@ -4475,21 +4474,21 @@ GetSymbolFor(JSContext *cx, HandleString
  *
  * This function is infallible. If it returns null, that means the symbol's
  * [[Description]] is undefined.
  */
 JS_PUBLIC_API(JSString *)
 GetSymbolDescription(HandleSymbol symbol);
 
 /* Well-known symbols. */
-MOZ_BEGIN_ENUM_CLASS(SymbolCode, uint32_t)
+enum class SymbolCode : uint32_t {
     iterator,                       // well-known Symbol.iterator
     InSymbolRegistry = 0xfffffffe,  // created by Symbol.for() or JS::GetSymbolFor()
     UniqueSymbol = 0xffffffff       // created by Symbol() or JS::NewSymbol()
-MOZ_END_ENUM_CLASS(SymbolCode)
+};
 
 /* For use in loops that iterate over the well-known symbols. */
 const size_t WellKnownSymbolLimit = 1;
 
 /*
  * Return the SymbolCode telling what sort of symbol `symbol` is.
  *
  * A symbol's SymbolCode never changes once it is created.
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -2671,17 +2671,18 @@ js::array_concat(JSContext *cx, unsigned
 
     /* Loop over [0, argc] to concat args into narr, expanding all Arrays. */
     for (unsigned i = 0; i <= argc; i++) {
         if (!CheckForInterrupt(cx))
             return false;
         HandleValue v = HandleValue::fromMarkedLocation(&p[i]);
         if (v.isObject()) {
             RootedObject obj(cx, &v.toObject());
-            if (ObjectClassIs(obj, ESClass_Array, cx)) {
+            // This should be IsConcatSpreadable
+            if (IsArray(obj, cx)) {
                 uint32_t alength;
                 if (!GetLengthProperty(cx, obj, &alength))
                     return false;
                 RootedValue tmp(cx);
                 for (uint32_t slot = 0; slot < alength; slot++) {
                     bool hole;
                     if (!CheckForInterrupt(cx) || !GetElement(cx, obj, slot, &hole, &tmp))
                         return false;
@@ -3034,17 +3035,21 @@ array_filter(JSContext *cx, unsigned arg
     args.rval().setObject(*arr);
     return true;
 }
 
 static bool
 array_isArray(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
-    bool isArray = args.length() > 0 && IsObjectWithClass(args[0], ESClass_Array, cx);
+    bool isArray = false;
+    if (args.get(0).isObject()) {
+        RootedObject obj(cx, &args[0].toObject());
+        isArray = IsArray(obj, cx);
+    }
     args.rval().setBoolean(isArray);
     return true;
 }
 
 static bool
 IsArrayConstructor(const Value &v)
 {
     // This must only return true if v is *the* Array constructor for the
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -4,17 +4,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jsfriendapi_h
 #define jsfriendapi_h
 
 #include "mozilla/Casting.h"
 #include "mozilla/MemoryReporting.h"
-#include "mozilla/TypedEnum.h"
 #include "mozilla/UniquePtr.h"
 
 #include "jsapi.h" // For JSAutoByteString.  See bug 1033916.
 #include "jsbytecode.h"
 #include "jspubtd.h"
 
 #include "js/CallArgs.h"
 #include "js/CallNonGenericMethod.h"
--- a/js/src/jsinfer.h
+++ b/js/src/jsinfer.h
@@ -5,17 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* Definitions related to javascript type inference. */
 
 #ifndef jsinfer_h
 #define jsinfer_h
 
 #include "mozilla/MemoryReporting.h"
-#include "mozilla/TypedEnum.h"
 
 #include "jsalloc.h"
 #include "jsfriendapi.h"
 #include "jstypes.h"
 
 #include "ds/IdValuePair.h"
 #include "ds/LifoAlloc.h"
 #include "gc/Barrier.h"
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -714,17 +714,20 @@ GuessArrayGCKind(size_t numSlots)
 inline bool
 ObjectClassIs(HandleObject obj, ESClassValue classValue, JSContext *cx)
 {
     if (MOZ_UNLIKELY(obj->is<ProxyObject>()))
         return Proxy::objectClassIs(obj, classValue, cx);
 
     switch (classValue) {
       case ESClass_Object: return obj->is<PlainObject>();
-      case ESClass_Array: return obj->is<ArrayObject>();
+      case ESClass_Array:
+      case ESClass_IsArray:
+        // There difference between those is only relevant for proxies.
+        return obj->is<ArrayObject>();
       case ESClass_Number: return obj->is<NumberObject>();
       case ESClass_String: return obj->is<StringObject>();
       case ESClass_Boolean: return obj->is<BooleanObject>();
       case ESClass_RegExp: return obj->is<RegExpObject>();
       case ESClass_ArrayBuffer: return obj->is<ArrayBufferObject>();
       case ESClass_SharedArrayBuffer: return obj->is<SharedArrayBufferObject>();
       case ESClass_Date: return obj->is<DateObject>();
       case ESClass_Set: return obj->is<SetObject>();
@@ -737,16 +740,26 @@ inline bool
 IsObjectWithClass(const Value &v, ESClassValue classValue, JSContext *cx)
 {
     if (!v.isObject())
         return false;
     RootedObject obj(cx, &v.toObject());
     return ObjectClassIs(obj, classValue, cx);
 }
 
+// ES6 7.2.2
+inline bool
+IsArray(HandleObject obj, JSContext *cx)
+{
+    if (obj->is<ArrayObject>())
+        return true;
+
+    return ObjectClassIs(obj, ESClass_IsArray, cx);
+}
+
 inline bool
 Unbox(JSContext *cx, HandleObject obj, MutableHandleValue vp)
 {
     if (MOZ_UNLIKELY(obj->is<ProxyObject>()))
         return Proxy::boxedValue_unbox(cx, obj, vp);
 
     if (obj->is<BooleanObject>())
         vp.setBoolean(obj->as<BooleanObject>().unbox());
--- a/js/src/json.cpp
+++ b/js/src/json.cpp
@@ -317,17 +317,17 @@ JO(JSContext *cx, HandleObject obj, Stri
 
     if (!scx->sb.append('{'))
         return false;
 
     /* Steps 5-7. */
     Maybe<AutoIdVector> ids;
     const AutoIdVector *props;
     if (scx->replacer && !scx->replacer->isCallable()) {
-        MOZ_ASSERT(JS_IsArrayObject(cx, scx->replacer));
+        MOZ_ASSERT(IsArray(scx->replacer, cx));
         props = &scx->propertyList;
     } else {
         MOZ_ASSERT_IF(scx->replacer, scx->propertyList.length() == 0);
         ids.emplace(cx);
         if (!GetPropertyKeys(cx, obj, JSITER_OWNONLY, ids.ptr()))
             return false;
         props = ids.ptr();
     }
@@ -502,17 +502,17 @@ Str(JSContext *cx, const Value &v, Strin
     }
 
     /* Step 10. */
     MOZ_ASSERT(v.isObject());
     RootedObject obj(cx, &v.toObject());
 
     scx->depth++;
     bool ok;
-    if (ObjectClassIs(obj, ESClass_Array, cx))
+    if (IsArray(obj, cx))
         ok = JA(cx, obj, scx);
     else
         ok = JO(cx, obj, scx);
     scx->depth--;
 
     return ok;
 }
 
@@ -524,17 +524,17 @@ js_Stringify(JSContext *cx, MutableHandl
     RootedObject replacer(cx, replacer_);
     RootedValue space(cx, space_);
 
     /* Step 4. */
     AutoIdVector propertyList(cx);
     if (replacer) {
         if (replacer->isCallable()) {
             /* Step 4a(i): use replacer to transform values.  */
-        } else if (ObjectClassIs(replacer, ESClass_Array, cx)) {
+        } else if (IsArray(replacer, cx)) {
             /*
              * Step 4b: The spec algorithm is unhelpfully vague about the exact
              * steps taken when the replacer is an array, regarding the exact
              * sequence of [[Get]] calls for the array's elements, when its
              * overall length is calculated, whether own or own plus inherited
              * properties are considered, and so on.  A rewrite was proposed in
              * <https://mail.mozilla.org/pipermail/es5-discuss/2011-April/003976.html>,
              * whose steps are copied below, and which are implemented here.
@@ -555,17 +555,18 @@ js_Stringify(JSContext *cx, MutableHandl
              *      6. If item is not undefined and item is not currently an
              *         element of PropertyList then,
              *         a. Append item to the end of PropertyList.
              *      7. Let i be i + 1.
              */
 
             /* Step 4b(ii). */
             uint32_t len;
-            JS_ALWAYS_TRUE(GetLengthProperty(cx, replacer, &len));
+            if (!GetLengthProperty(cx, replacer, &len))
+                return false;
             if (replacer->is<ArrayObject>() && !replacer->isIndexed())
                 len = Min(len, replacer->as<ArrayObject>().getDenseInitializedLength());
 
             // Cap the initial size to a moderately small value.  This avoids
             // ridiculous over-allocation if an array with bogusly-huge length
             // is passed in.  If we end up having to add elements past this
             // size, the set will naturally resize to accommodate them.
             const uint32_t MaxInitialSize = 1024;
@@ -688,17 +689,17 @@ Walk(JSContext *cx, HandleObject holder,
     RootedValue val(cx);
     if (!GetProperty(cx, holder, holder, name, &val))
         return false;
 
     /* Step 2. */
     if (val.isObject()) {
         RootedObject obj(cx, &val.toObject());
 
-        if (ObjectClassIs(obj, ESClass_Array, cx)) {
+        if (IsArray(obj, cx)) {
             /* Step 2a(ii). */
             uint32_t length;
             if (!GetLengthProperty(cx, obj, &length))
                 return false;
 
             /* Step 2a(i), 2a(iii-iv). */
             RootedId id(cx);
             RootedValue newElement(cx);
--- a/js/src/proxy/ScriptedDirectProxyHandler.cpp
+++ b/js/src/proxy/ScriptedDirectProxyHandler.cpp
@@ -1090,16 +1090,60 @@ ScriptedDirectProxyHandler::construct(JS
     if (!args.rval().isObject()) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_PROXY_CONSTRUCT_OBJECT);
         return false;
     }
     return true;
 }
 
 bool
+ScriptedDirectProxyHandler::nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
+                                       CallArgs args) const
+{
+    ReportIncompatible(cx, args);
+    return false;
+}
+
+bool
+ScriptedDirectProxyHandler::objectClassIs(HandleObject proxy, ESClassValue classValue,
+                                          JSContext *cx) const
+{
+    // Special case IsArray. In every other instance ES wants to have exactly
+    // one object type and not a proxy around it, so return false.
+    if (classValue != ESClass_IsArray)
+        return false;
+
+    // In ES6 IsArray is supposed to poke at the Proxy target, instead we do this here.
+    // The reason for this is that we have proxies for which looking at the target might
+    // be impossible. So instead we use our little objectClassIs function that just works
+    // already across different wrappers.
+    RootedObject target(cx, proxy->as<ProxyObject>().target());
+    if (!target)
+        return false;
+
+    return IsArray(target, cx);
+}
+
+bool
+ScriptedDirectProxyHandler::regexp_toShared(JSContext *cx, HandleObject proxy,
+                                            RegExpGuard *g) const
+{
+    MOZ_CRASH("Should not end up in ScriptedDirectProxyHandler::regexp_toShared");
+    return false;
+}
+
+bool
+ScriptedDirectProxyHandler::boxedValue_unbox(JSContext *cx, HandleObject proxy,
+                                             MutableHandleValue vp) const
+{
+    MOZ_CRASH("Should not end up in ScriptedDirectProxyHandler::boxedValue_unbox");
+    return false;
+}
+
+bool
 ScriptedDirectProxyHandler::isCallable(JSObject *obj) const
 {
     MOZ_ASSERT(obj->as<ProxyObject>().handler() == &ScriptedDirectProxyHandler::singleton);
     uint32_t callConstruct = obj->as<ProxyObject>().extra(IS_CALLCONSTRUCT_EXTRA).toPrivateUint32();
     return !!(callConstruct & IS_CALLABLE);
 }
 
 bool
--- a/js/src/proxy/ScriptedDirectProxyHandler.h
+++ b/js/src/proxy/ScriptedDirectProxyHandler.h
@@ -59,16 +59,26 @@ class ScriptedDirectProxyHandler : publi
     // Kick getOwnEnumerablePropertyKeys out to ownPropertyKeys and then
     // filter. [[GetOwnProperty]] could potentially change the enumerability of
     // the target's properties.
     virtual bool getOwnEnumerablePropertyKeys(JSContext *cx, HandleObject proxy,
                                               AutoIdVector &props) const MOZ_OVERRIDE {
         return BaseProxyHandler::getOwnEnumerablePropertyKeys(cx, proxy, props);
     }
 
+    // A scripted proxy should not be treated as generic in most contexts.
+    virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
+                            CallArgs args) const MOZ_OVERRIDE;
+    virtual bool objectClassIs(HandleObject obj, ESClassValue classValue,
+                               JSContext *cx) const MOZ_OVERRIDE;
+    virtual bool regexp_toShared(JSContext *cx, HandleObject proxy,
+                                 RegExpGuard *g) const MOZ_OVERRIDE;
+    virtual bool boxedValue_unbox(JSContext *cx, HandleObject proxy,
+                                  MutableHandleValue vp) const MOZ_OVERRIDE;
+
     virtual bool isCallable(JSObject *obj) const MOZ_OVERRIDE;
     virtual bool isConstructor(JSObject *obj) const MOZ_OVERRIDE;
 
     virtual bool isScripted() const MOZ_OVERRIDE { return true; }
 
     static const char family;
     static const ScriptedDirectProxyHandler singleton;
 
--- a/js/src/tests/ecma_6/TypedArray/entries.js
+++ b/js/src/tests/ecma_6/TypedArray/entries.js
@@ -30,20 +30,19 @@ for (var constructor of constructors) {
     if (typeof newGlobal === "function") {
         var entries = newGlobal()[constructor.name].prototype.entries;
         assertDeepEq([...entries.call(new constructor(2))], [[0, 0], [1, 0]]);
         arr = newGlobal()[constructor.name](2);
         assertEq([...constructor.prototype.entries.call(arr)].toString(), "0,0,1,0");
     }
 
     // Throws if `this` isn't a TypedArray.
-    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
+    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+                            new Proxy(new constructor(), {})];
     invalidReceivers.forEach(invalidReceiver => {
         assertThrowsInstanceOf(() => {
             constructor.prototype.entries.call(invalidReceiver);
         }, TypeError, "Assert that entries fails if this value is not a TypedArray");
     });
-    // FIXME: Should throw exception if `this` is a proxy, see bug 1115361.
-    constructor.prototype.entries.call(new Proxy(new constructor(), {}));
 }
 
 if (typeof reportCompare === "function")
     reportCompare(true, true);
--- a/js/src/tests/ecma_6/TypedArray/every-and-some.js
+++ b/js/src/tests/ecma_6/TypedArray/every-and-some.js
@@ -106,24 +106,23 @@ for (var constructor of constructors) {
     if (typeof newGlobal === "function") {
         var every = newGlobal()[constructor.name].prototype.every;
         var sum = 0;
         assertEq(every.call(new constructor([1, 2, 3]), v => sum += v), true);
         assertEq(sum, 6);
     }
 
     // Throws if `this` isn't a TypedArray.
-    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
+    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+                            new Proxy(new constructor(), {})];
     invalidReceivers.forEach(invalidReceiver => {
         assertThrowsInstanceOf(() => {
             constructor.prototype.every.call(invalidReceiver, () => true);
         }, TypeError, "Assert that every fails if this value is not a TypedArray");
     });
-    // FIXME: Should throw exception if `this` is a proxy, see bug 1115361.
-    constructor.prototype.every.call(new Proxy(new constructor(), {}), () => true);
 
     // Test that the length getter is never called.
     assertEq(Object.defineProperty(new constructor([1, 2, 3]), "length", {
         get() {
             throw new Error("length accessor called");
         }
     }).every(() => true), true);
 }
@@ -232,30 +231,29 @@ for (var constructor of constructors) {
         assertEq(some.call(new constructor([1, 2, 3]), v => {
             sum += v;
             return false;
         }), false);
         assertEq(sum, 6);
     }
 
     // Throws if `this` isn't a TypedArray.
-    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
+    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+                            new Proxy(new constructor(), {})];
     invalidReceivers.forEach(invalidReceiver => {
         assertThrowsInstanceOf(() => {
             constructor.prototype.some.call(invalidReceiver, () => true);
         }, TypeError, "Assert that some fails if this value is not a TypedArray");
     });
-    // FIXME: Should throw exception if `this` is a proxy, see bug 1115361.
-    constructor.prototype.some.call(new Proxy(new constructor(), {}), () => false);
 
     // Test that the length getter is never called.
     assertEq(Object.defineProperty(new constructor([1, 2, 3]), "length", {
         get() {
             throw new Error("length accessor called");
         }
     }).some(() => false), false);
 }
 
 assertEq(new Float32Array([undefined, , NaN]).some(v => v === v), false);
 assertEq(new Float64Array([undefined, , NaN]).some(v => v === v), false);
 
 if (typeof reportCompare === "function")
-    reportCompare(true, true);
\ No newline at end of file
+    reportCompare(true, true);
--- a/js/src/tests/ecma_6/TypedArray/fill.js
+++ b/js/src/tests/ecma_6/TypedArray/fill.js
@@ -48,24 +48,23 @@ for (var constructor of constructors) {
 
     // Called from other globals.
     if (typeof newGlobal === "function") {
         var fill = newGlobal()[constructor.name].prototype.fill;
         assertDeepEq(fill.call(new constructor([3, 2, 1]), 2), new constructor([2, 2, 2]));
     }
 
     // Throws if `this` isn't a TypedArray.
-    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./]
+    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+                            new Proxy(new constructor(), {})];
     invalidReceivers.forEach(invalidReceiver => {
         assertThrowsInstanceOf(() => {
             constructor.prototype.fill.call(invalidReceiver, 1);
         }, TypeError);
     });
-    // FIXME: Should throw exception if `this` is a proxy, see bug 1115361.
-    constructor.prototype.fill.call(new Proxy(new constructor(), {}));
 
     // Test that the length getter is never called.
     Object.defineProperty(new constructor([1, 2, 3]), "length", {
         get() {
             throw new Error("length accessor called");
         }
     }).fill(1);
 }
--- a/js/src/tests/ecma_6/TypedArray/includes.js
+++ b/js/src/tests/ecma_6/TypedArray/includes.js
@@ -30,24 +30,23 @@ for (var constructor of constructors) {
 
     // Called from other globals.
     if (typeof newGlobal === "function") {
         var includes = newGlobal()[constructor.name].prototype.includes;
         assertEq(includes.call(new constructor([1, 2, 3]), 2), true);
     }
 
     // Throws if `this` isn't a TypedArray.
-    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
+    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+                            new Proxy(new constructor(), {})];
     invalidReceivers.forEach(invalidReceiver => {
         assertThrowsInstanceOf(() => {
             constructor.prototype.includes.call(invalidReceiver);
         }, TypeError, "Assert that reverse fails if this value is not a TypedArray");
     });
-    // FIXME: Should throw exception if `this` is a proxy, see bug 1115361.
-    constructor.prototype.includes.call(new Proxy(new constructor(), {}));
 
     // Test that the length getter is never called.
     assertEq(Object.defineProperty(new constructor([1, 2, 3]), "length", {
         get() {
             throw new Error("length accessor called");
         }
     }).includes(2), true);
 }
--- a/js/src/tests/ecma_6/TypedArray/indexOf-and-lastIndexOf.js
+++ b/js/src/tests/ecma_6/TypedArray/indexOf-and-lastIndexOf.js
@@ -36,24 +36,23 @@ for (var constructor of constructors) {
     assertEq(new constructor([1, 2, 3, 4, 5]).indexOf(1, 1), -1);
     assertEq(new constructor([1, 2, 3, 4, 5]).indexOf(1, -100), 0);
     assertEq(new constructor([1, 2, 3, 4, 5]).indexOf(3, 100), -1);
     assertEq(new constructor([1, 2, 3, 4, 5]).indexOf(5, -1), 4);
     assertEq(new constructor([1, 2, 1, 2, 1]).indexOf(1, 2), 2);
     assertEq(new constructor([1, 2, 1, 2, 1]).indexOf(1, -2), 4);
 
     // Throws if `this` isn't a TypedArray.
-    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
+    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+                            new Proxy(new constructor(), {})];
     invalidReceivers.forEach(invalidReceiver => {
         assertThrowsInstanceOf(() => {
             constructor.prototype.indexOf.call(invalidReceiver);
         }, TypeError, "Assert that indexOf fails if this value is not a TypedArray");
     });
-    // FIXME: Should throw exception if `this` is a proxy, see bug 1115361.
-    constructor.prototype.indexOf.call(new Proxy(new constructor(), {}));
 
     // test that this.length is never called
     assertEq(Object.defineProperty(new constructor([0, 1, 2, 3, 5]), "length", {
         get() {
             throw new Error("length accessor called");
         }
     }).indexOf(1), 1);
 }
@@ -89,24 +88,23 @@ for (var constructor of constructors) {
     assertEq(new constructor([1, 2, 3, 4, 5]).lastIndexOf(1, 1), 0);
     assertEq(new constructor([1, 2, 3, 4, 5]).lastIndexOf(1, -100), -1);
     assertEq(new constructor([1, 2, 3, 4, 5]).lastIndexOf(3, 100), 2);
     assertEq(new constructor([1, 2, 3, 4, 5]).lastIndexOf(5, -1), 4);
     assertEq(new constructor([1, 2, 1, 2, 1]).lastIndexOf(1, 2), 2);
     assertEq(new constructor([1, 2, 1, 2, 1]).lastIndexOf(1, -2), 2);
 
     // Throws if `this` isn't a TypedArray.
-    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
+    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+                            new Proxy(new constructor(), {})];
     invalidReceivers.forEach(invalidReceiver => {
         assertThrowsInstanceOf(() => {
             constructor.prototype.lastIndexOf.call(invalidReceiver);
         }, TypeError, "Assert that lastIndexOf fails if this value is not a TypedArray");
     });
-    // FIXME: Should throw exception if `this` is a proxy, see bug 1115361.
-    constructor.prototype.lastIndexOf.call(new Proxy(new constructor(), {}));
 
     // Test that the length getter is never called.
     assertEq(Object.defineProperty(new constructor([0, 1, 2, 3, 5]), "length", {
         get() {
             throw new Error("length accessor called");
         }
     }).lastIndexOf(1), 1);
 }
--- a/js/src/tests/ecma_6/TypedArray/join.js
+++ b/js/src/tests/ecma_6/TypedArray/join.js
@@ -31,24 +31,23 @@ for (var constructor of constructors) {
 
     // Called from other globals.
     if (typeof newGlobal === "function") {
         var join = newGlobal()[constructor.name].prototype.join;
         assertEq(join.call(new constructor([1, 2, 3]), "\t"), "1\t2\t3");
     }
 
     // Throws if `this` isn't a TypedArray.
-    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
+    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+                            new Proxy(new constructor(), {})];
     invalidReceivers.forEach(invalidReceiver => {
         assertThrowsInstanceOf(() => {
             constructor.prototype.join.call(invalidReceiver);
         }, TypeError, "Assert that join fails if this value is not a TypedArray");
     });
-    // FIXME: Should throw exception if `this` is a proxy, see bug 1115361.
-    constructor.prototype.join.call(new Proxy(new constructor(), {}));
 
     // Test that the length getter is never called.
     assertEq(Object.defineProperty(new constructor([1, 2, 3]), "length", {
         get() {
             throw new Error("length accessor called");
         }
     }).join("\0"), "1\0002\0003");
 }
--- a/js/src/tests/ecma_6/TypedArray/keys.js
+++ b/js/src/tests/ecma_6/TypedArray/keys.js
@@ -30,20 +30,19 @@ for (var constructor of constructors) {
     if (typeof newGlobal === "function") {
         var keys = newGlobal()[constructor.name].prototype.keys;
         assertDeepEq([...keys.call(new constructor(2))], [0, 1]);
         arr = newGlobal()[constructor.name](2);
         assertEq([...constructor.prototype.keys.call(arr)].toString(), "0,1");
     }
 
     // Throws if `this` isn't a TypedArray.
-    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
+    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+                            new Proxy(new constructor(), {})];
     invalidReceivers.forEach(invalidReceiver => {
         assertThrowsInstanceOf(() => {
             constructor.prototype.keys.call(invalidReceiver);
         }, TypeError, "Assert that keys fails if this value is not a TypedArray");
     });
-    // FIXME: Should throw exception if `this` is a proxy, see bug 1115361.
-    constructor.prototype.keys.call(new Proxy(new constructor(), {}));
 }
 
 if (typeof reportCompare === "function")
     reportCompare(true, true);
--- a/js/src/tests/ecma_6/TypedArray/reduce-and-reduceRight.js
+++ b/js/src/tests/ecma_6/TypedArray/reduce-and-reduceRight.js
@@ -82,24 +82,23 @@ for (var constructor of constructors) {
 
     // Called from other globals.
     if (typeof newGlobal === "function") {
         var reduce = newGlobal()[constructor.name].prototype.reduce;
         assertEq(reduce.call(arr, (previous, current) => Math.min(previous, current)), 1);
     }
 
     // Throws if `this` isn't a TypedArray.
-    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
+    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+                            new Proxy(new constructor(3), {})];
     invalidReceivers.forEach(invalidReceiver => {
         assertThrowsInstanceOf(() => {
             constructor.prototype.reduce.call(invalidReceiver, () => {});
         }, TypeError, "Assert that reduce fails if this value is not a TypedArray");
     });
-    // FIXME: Should throw exception if `this` is a proxy, see bug 1115361.
-    constructor.prototype.reduce.call(new Proxy(new constructor(3), {}), () => {});
 
     // Test that the length getter is never called.
     assertEq(Object.defineProperty(arr, "length", {
         get() {
             throw new Error("length accessor called");
         }
     }).reduce((previous, current) => Math.max(previous, current)), 5);
 }
@@ -176,27 +175,26 @@ for (var constructor of constructors) {
 
     // Called from other globals.
     if (typeof newGlobal === "function") {
         var reduceRight = newGlobal()[constructor.name].prototype.reduceRight;
         assertEq(reduceRight.call(arr, (previous, current) => Math.min(previous, current)), 1);
     }
 
     // Throws if `this` isn't a TypedArray.
-    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
+    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+                            new Proxy(new constructor(3), {})];
     invalidReceivers.forEach(invalidReceiver => {
         assertThrowsInstanceOf(() => {
             constructor.prototype.reduceRight.call(invalidReceiver, () => {});
         }, TypeError, "Assert that reduceRight fails if this value is not a TypedArray");
     });
-    // FIXME: Should throw exception if `this` is a proxy, see bug 1115361.
-    constructor.prototype.reduceRight.call(new Proxy(new constructor(3), {}), () => {});
 
     // Test that the length getter is never called.
     assertEq(Object.defineProperty(arr, "length", {
         get() {
             throw new Error("length accessor called");
         }
     }).reduceRight((previous, current) => Math.max(previous, current)), 5);
 }
 
 if (typeof reportCompare === "function")
-    reportCompare(true, true);
\ No newline at end of file
+    reportCompare(true, true);
--- a/js/src/tests/ecma_6/TypedArray/reverse.js
+++ b/js/src/tests/ecma_6/TypedArray/reverse.js
@@ -25,24 +25,23 @@ for (var constructor of constructors) {
 
     // Called from other globals.
     if (typeof newGlobal === "function") {
         var reverse = newGlobal()[constructor.name].prototype.reverse;
         assertDeepEq(reverse.call(new constructor([3, 2, 1])), new constructor([1, 2, 3]));
     }
 
     // Throws if `this` isn't a TypedArray.
-    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
+    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+                            new Proxy(new constructor(), {})];
     invalidReceivers.forEach(invalidReceiver => {
         assertThrowsInstanceOf(() => {
             constructor.prototype.reverse.call(invalidReceiver);
         }, TypeError, "Assert that reverse fails if this value is not a TypedArray");
     });
-    // FIXME: Should throw exception if `this` is a proxy, see bug 1115361.
-    constructor.prototype.reverse.call(new Proxy(new constructor(), {}));
 
     // Test that the length getter is never called.
     Object.defineProperty(new constructor([1, 2, 3]), "length", {
         get() {
             throw new Error("length accessor called");
         }
     }).reverse();
 }
--- a/js/src/tests/ecma_6/TypedArray/values.js
+++ b/js/src/tests/ecma_6/TypedArray/values.js
@@ -31,20 +31,19 @@ for (var constructor of constructors) {
     if (typeof newGlobal === "function") {
         var values = newGlobal()[constructor.name].prototype.values;
         assertDeepEq([...values.call(new constructor([42, 36]))], [42, 36]);
         arr = newGlobal()[constructor.name]([42, 36]);
         assertEq([...constructor.prototype.values.call(arr)].toString(), "42,36");
     }
 
     // Throws if `this` isn't a TypedArray.
-    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
+    var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+                            new Proxy(new constructor(), {})];
     invalidReceivers.forEach(invalidReceiver => {
         assertThrowsInstanceOf(() => {
             constructor.prototype.values.call(invalidReceiver);
         }, TypeError, "Assert that values fails if this value is not a TypedArray");
     });
-    // FIXME: Should throw exception if `this` is a proxy, see bug 1115361.
-    constructor.prototype.values.call(new Proxy(new constructor(), {}));
 }
 
 if (typeof reportCompare === "function")
     reportCompare(true, true);
--- a/js/src/vm/RegExpObject.h
+++ b/js/src/vm/RegExpObject.h
@@ -484,16 +484,17 @@ bool
 ParseRegExpFlags(JSContext *cx, JSString *flagStr, RegExpFlag *flagsOut);
 
 /* Assuming ObjectClassIs(obj, ESClass_RegExp), return a RegExpShared for obj. */
 inline bool
 RegExpToShared(JSContext *cx, HandleObject obj, RegExpGuard *g)
 {
     if (obj->is<RegExpObject>())
         return obj->as<RegExpObject>().getShared(cx, g);
+    MOZ_ASSERT(Proxy::objectClassIs(obj, ESClass_RegExp, cx));
     return Proxy::regexp_toShared(cx, obj, g);
 }
 
 template<XDRMode mode>
 bool
 XDRScriptRegExpObject(XDRState<mode> *xdr, MutableHandle<RegExpObject*> objp);
 
 extern JSObject *
--- a/js/src/vm/StructuredClone.cpp
+++ b/js/src/vm/StructuredClone.cpp
@@ -26,17 +26,16 @@
  * the ArrayBuffer has been read, then it is updated with the actual typed
  * array object.
  */
 
 #include "js/StructuredClone.h"
 
 #include "mozilla/Endian.h"
 #include "mozilla/FloatingPoint.h"
-#include "mozilla/TypedEnum.h"
 
 #include <algorithm>
 
 #include "jsapi.h"
 #include "jscntxt.h"
 #include "jsdate.h"
 #include "jswrapper.h"
 
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -2486,16 +2486,17 @@ PaintedLayerData::Accumulate(ContainerSt
       }
     } else {
       FLB_LOG_PAINTED_LAYER_DECISION(this, "  Layer is not a solid color: Display item is not uniform over the visible bound\n");
       mIsSolidColorInVisibleRegion = false;
     }
 
     mVisibleRegion.Or(mVisibleRegion, aVisibleRect);
     mVisibleRegion.SimplifyOutward(4);
+    mDrawRegion.Or(mDrawRegion, mVisibleRegion);
     mDrawRegion.Or(mDrawRegion, aDrawRect);
     mDrawRegion.SimplifyOutward(4);
   }
 
   if (!aClippedOpaqueRegion.IsEmpty()) {
     nsIntRegionRectIterator iter(aClippedOpaqueRegion);
     for (const nsIntRect* r = iter.Next(); r; r = iter.Next()) {
       // We don't use SimplifyInward here since it's not defined exactly
--- a/layout/base/SelectionCarets.cpp
+++ b/layout/base/SelectionCarets.cpp
@@ -766,18 +766,20 @@ SelectionCarets::DragSelection(const nsP
     return nsEventStatus_eConsumeNoDefault;
   }
 
   int32_t rangeCount = selection->GetRangeCount();
   if (rangeCount <= 0) {
     return nsEventStatus_eConsumeNoDefault;
   }
 
+  // Limit the drag behavior not to cross the end of last selection range
+  // when drag the start frame and vice versa
   nsRefPtr<nsRange> range = mDragMode == START_FRAME ?
-    selection->GetRangeAt(0) : selection->GetRangeAt(rangeCount - 1);
+    selection->GetRangeAt(rangeCount - 1) : selection->GetRangeAt(0);
   if (!CompareRangeWithContentOffset(range, fs, offsets, mDragMode)) {
     return nsEventStatus_eConsumeNoDefault;
   }
 
   nsIFrame* anchorFrame;
   selection->GetPrimaryFrameForAnchorNode(&anchorFrame);
   if (!anchorFrame) {
     return nsEventStatus_eConsumeNoDefault;
--- a/layout/base/UnitTransforms.h
+++ b/layout/base/UnitTransforms.h
@@ -14,29 +14,29 @@ namespace mozilla {
 
 // Convenience functions for converting an entity from one strongly-typed
 // coordinate system to another without changing the values it stores (this
 // can be thought of as a cast).
 // To use these functions, you must provide a justification for each use!
 // Feel free to add more justifications to PixelCastJustification, along with
 // a comment that explains under what circumstances it is appropriate to use.
 
-MOZ_BEGIN_ENUM_CLASS(PixelCastJustification, uint8_t)
+enum class PixelCastJustification : uint8_t {
   // For the root layer, Screen Pixel = Parent Layer Pixel.
   ScreenIsParentLayerForRoot,
   // For the root composition size we want to view it as layer pixels in any layer
   ParentLayerToLayerForRootComposition,
   // The Layer coordinate space for one layer is the ParentLayer coordinate
   // space for its children
   MovingDownToChildren,
   // The transform that is usually used to convert between two coordinate
   // systems is not available (for example, because the object that stores it
   // is being destroyed), so fall back to the identity.
   TransformNotAvailable
-MOZ_END_ENUM_CLASS(PixelCastJustification)
+};
 
 template <class TargetUnits, class SourceUnits>
 gfx::SizeTyped<TargetUnits> ViewAs(const gfx::SizeTyped<SourceUnits>& aSize, PixelCastJustification) {
   return gfx::SizeTyped<TargetUnits>(aSize.width, aSize.height);
 }
 template <class TargetUnits, class SourceUnits>
 gfx::IntSizeTyped<TargetUnits> ViewAs(const gfx::IntSizeTyped<SourceUnits>& aSize, PixelCastJustification) {
   return gfx::IntSizeTyped<TargetUnits>(aSize.width, aSize.height);
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -158,20 +158,20 @@ public:
    */
   static nsIScrollableFrame* FindScrollableFrameFor(ViewID aId);
 
   /**
    * Get display port for the given element.
    */
   static bool GetDisplayPort(nsIContent* aContent, nsRect *aResult = nullptr);
 
-  MOZ_BEGIN_NESTED_ENUM_CLASS(RepaintMode, uint8_t)
+  enum class RepaintMode : uint8_t {
     Repaint,
     DoNotRepaint
-  MOZ_END_NESTED_ENUM_CLASS(RepaintMode)
+  };
 
   /**
    * Set the display port margins for a content element to be used with a
    * display port base (see SetDisplayPortBase()).
    * See also nsIDOMWindowUtils.setDisplayPortMargins.
    * @param aContent the content element for which to set the margins
    * @param aPresShell the pres shell for the document containing the element
    * @param aMargins the margins to set
@@ -2572,18 +2572,16 @@ private:
   static void DoLogTestDataForPaint(mozilla::layers::LayerManager* aManager,
                                     ViewID aScrollId,
                                     const std::string& aKey,
                                     const std::string& aValue);
 
   static bool IsAPZTestLoggingEnabled();
 };
 
-MOZ_FINISH_NESTED_ENUM_CLASS(nsLayoutUtils::RepaintMode)
-
 template<typename PointType, typename RectType, typename CoordType>
 /* static */ bool
 nsLayoutUtils::PointIsCloserToRect(PointType aPoint, const RectType& aRect,
                                    CoordType& aClosestXDistance,
                                    CoordType& aClosestYDistance)
 {
   CoordType fromLeft = aPoint.x - aRect.x;
   CoordType fromRight = aPoint.x - aRect.XMost();
--- a/layout/base/tests/marionette/test_selectioncarets.py
+++ b/layout/base/tests/marionette/test_selectioncarets.py
@@ -12,16 +12,17 @@ from gestures import long_press_without_
 
 class SelectionCaretsTest(MarionetteTestCase):
     _long_press_time = 1        # 1 second
     _input_selector = (By.ID, 'input')
     _textarea_selector = (By.ID, 'textarea')
     _textarea_rtl_selector = (By.ID, 'textarea_rtl')
     _contenteditable_selector = (By.ID, 'contenteditable')
     _content_selector = (By.ID, 'content')
+    _contenteditable2_selector = (By.ID, 'contenteditable2')
 
     def setUp(self):
         # Code to execute before a tests are run.
         MarionetteTestCase.setUp(self)
         self.actions = Actions(self.marionette)
 
     def openTestHtml(self, enabled=True):
         '''Open html for testing and locate elements, and enable/disable touch
@@ -33,16 +34,17 @@ class SelectionCaretsTest(MarionetteTest
         test_html = self.marionette.absolute_url('test_selectioncarets.html')
         self.marionette.navigate(test_html)
 
         self._input = self.marionette.find_element(*self._input_selector)
         self._textarea = self.marionette.find_element(*self._textarea_selector)
         self._textarea_rtl = self.marionette.find_element(*self._textarea_rtl_selector)
         self._contenteditable = self.marionette.find_element(*self._contenteditable_selector)
         self._content = self.marionette.find_element(*self._content_selector)
+        self._contenteditable2 = self.marionette.find_element(*self._contenteditable2_selector)
 
     def _first_word_location(self, el):
         '''Get the location (x, y) of the first word in el.
 
         Note: this function has a side effect which changes focus to the
         target element el.
 
         '''
@@ -110,27 +112,37 @@ class SelectionCaretsTest(MarionetteTest
 
     def _test_minimum_select_one_character(self, el, assertFunc,
                                            x=None, y=None):
         sel = SelectionManager(el)
         original_content = sel.content
         words = original_content.split()
         self.assertTrue(len(words) >= 1, 'Expect at least one word in the content.')
 
+        # Get the location of the selection carets at the end of the content for
+        # later use.
+        sel.select_all()
+        (_, _), (end_caret_x, end_caret_y) = sel.selection_carets_location()
+        el.tap()
+
         # Goal: Select the first character.
         target_content = original_content[0]
 
         if x and y:
             # If we got x and y from the arguments, use it as a hint of the
             # location of the first word
             pass
         else:
             x, y = self._first_word_location(el)
         self._long_press_to_select(el, x, y)
 
+        # Move the right caret to the end of the content.
+        (caret1_x, caret1_y), (caret2_x, caret2_y) = sel.selection_carets_location()
+        self.actions.flick(el, caret2_x, caret2_y, end_caret_x, end_caret_y).perform()
+
         # Move the right caret to the position of the left caret.
         (caret1_x, caret1_y), (caret2_x, caret2_y) = sel.selection_carets_location()
         self.actions.flick(el, caret2_x, caret2_y, caret1_x, caret1_y,).perform()
 
         assertFunc(target_content, sel.selected_content)
 
     def _test_focus_obtained_by_long_press(self, el1, el2):
         '''Test the focus could be changed from el1 to el2 by long press.
@@ -304,8 +316,16 @@ class SelectionCaretsTest(MarionetteTest
     def test_content_non_editable_focus_obtained_by_long_press_from_textarea(self):
         self.openTestHtml(enabled=True)
         self._test_focus_obtained_by_long_press(self._textarea, self._content)
 
     def test_content_non_editable_focus_obtained_by_long_press_from_contenteditable(self):
         self.openTestHtml(enabled=True)
         self._test_focus_obtained_by_long_press(self._contenteditable, self._content)
 
+    ########################################################################
+    # <div> contenteditable2 test cases with selection carets enabled
+    ########################################################################
+    def test_contenteditable_minimum_select_one_character(self):
+        self.openTestHtml(enabled=True)
+        self._test_minimum_select_one_character(self._contenteditable2, self.assertEqual)
+
+
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -23,17 +23,16 @@
 #include <stdio.h>
 #include "nsQueryFrame.h"
 #include "nsStyleContext.h"
 #include "nsStyleStruct.h"
 #include "nsHTMLReflowMetrics.h"
 #include "nsFrameList.h"
 #include "mozilla/layout/FrameChildList.h"
 #include "FramePropertyTable.h"
-#include "mozilla/TypedEnum.h"
 #include "nsDirection.h"
 #include "WritingModes.h"
 #include <algorithm>
 #include "nsITheme.h"
 #include "nsLayoutUtils.h"
 #include "nsFrameState.h"
 #include "CaretAssociationHint.h"
 
@@ -311,20 +310,20 @@ typedef uint32_t nsReflowStatus;
 void NS_MergeReflowStatusInto(nsReflowStatus* aPrimary,
                               nsReflowStatus aSecondary);
 
 //----------------------------------------------------------------------
 
 /**
  * DidReflow status values.
  */
-MOZ_BEGIN_ENUM_CLASS(nsDidReflowStatus, uint32_t)
+enum class nsDidReflowStatus : uint32_t {
   NOT_FINISHED,
   FINISHED
-MOZ_END_ENUM_CLASS(nsDidReflowStatus)
+};
 
 /**
  * When there is no scrollable overflow rect, the visual overflow rect
  * may be stored as four 1-byte deltas each strictly LESS THAN 0xff, for
  * the four edges of the rectangle, or the four bytes may be read as a
  * single 32-bit "overflow-rect type" value including at least one 0xff
  * byte as an indicator that the value does NOT represent four deltas.
  * If all four deltas are zero, this means that no overflow rect has
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1120431-1-ref.html
@@ -0,0 +1,202 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+    <style>
+      .container-ext {
+        padding-left: 180px;
+        padding-right: 180px;
+      }
+      
+      .headline {
+        line-height: 30px;
+        text-shadow: 1px 1px rgba(255, 255, 255, 0.3);
+      }
+      
+      ul {
+        list-style: none;
+      }
+      
+      .headline-left {
+        left: 30px;
+      }
+      
+      .headline-right {
+        top: 20px !important;
+        /*bottom:370px !important;*/
+        right: 20px;
+      }
+      
+      .headline-active {
+        position: fixed;
+        top: 100px;
+      }
+      
+      .list-author:before,
+      .list-author:after {
+        content: "\200e";
+        display: table;
+      }
+      .list-author:after {
+        clear: both;
+      }
+      
+      .list-author-vocal {
+        float: left;
+        margin-right: 10px;
+      }
+      
+      .ff { position: fixed; }
+    </style>
+  </head>
+  <body>
+    <div class="container-ext">
+      
+      <div class="headline headline-left headline-active">
+          <ul class="list-author">
+            <li class="list-author-vocal">
+              A
+            </li>
+            <li class="list-author-vocal">
+              B
+            </li>
+            <li class="list-author-vocal">
+              C
+            </li>
+            <li class="list-author-vocal">
+              D
+            </li>
+            <li class="list-author-vocal">
+              E
+            </li>
+          </ul>
+          <ul class="list-author">
+            <li class="list-author-vocal">
+              F
+            </li>
+            <li class="list-author-vocal">
+              G
+            </li>
+            <li class="list-author-vocal">
+              H
+            </li>
+            <li class="list-author-vocal">
+              I
+            </li>
+            <li class="list-author-vocal">
+              J
+            </li>
+          </ul>
+          <ul class="list-author">
+            <li class="list-author-vocal">
+              K
+            </li>
+            <li class="list-author-vocal">
+              L
+            </li>
+            <li class="list-author-vocal">
+              M
+            </li>
+            <li class="list-author-vocal">
+              N
+            </li>
+            <li class="list-author-vocal">
+              O
+            </li>
+          </ul>
+          <ul class="list-author">
+            <li class="list-author-vocal active">
+              P
+            </li>
+            <li class="list-author-vocal">
+              R
+            </li>
+            <li class="list-author-vocal">
+              S
+            </li>
+            <li class="list-author-vocal">
+              T
+            </li>
+            <li class="list-author-vocal">
+              V
+            </li>
+          </ul>
+          <ul class="list-author">
+            <li class="list-author-vocal">
+              W
+            </li>
+            <li class="list-author-vocal">
+              Y
+            </li>
+            <li class="list-author-vocal">
+              Z
+            </li>
+          </ul>
+<div class="ff" style="left: 69px; top: 115px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 173px; top: 115px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 173px; top: 115px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 173px; top: 115px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 173px; top: 115px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 173px; top: 115px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 173px; top: 115px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 145px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 161px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 162px; top: 161px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 162px; top: 161px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 162px; top: 161px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 162px; top: 161px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 162px; top: 161px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 162px; top: 161px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 191px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 177px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 177px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 177px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 177px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 177px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 177px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 237px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 253px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 168px; top: 253px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 168px; top: 253px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 168px; top: 253px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 168px; top: 253px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 168px; top: 253px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 168px; top: 253px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 283px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 299px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 135px; top: 299px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 135px; top: 299px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 135px; top: 299px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 135px; top: 299px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 329px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 345px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 68px; top: 352px; width: 41px; height: 19px; background: blue;"></div>
+<div class="ff" style="left: 68px; top: 382px; width: 41px; height: 19px; background: blue;"></div>
+<div class="ff" style="left: 68px; top: 412px; width: 41px; height: 19px; background: blue;"></div>
+<div class="ff" style="left: 68px; top: 442px; width: 41px; height: 19px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 465px; width: 3px; height: 3px; background: blue;"></div>
+
+          <ul class="list-author">
+          <li>
+            Word
+          </li>
+          <li>
+            Word
+          </li>
+          <li>
+            Word
+          </li>
+          <li>
+            Word
+          </li>
+        </ul>
+      </div> <!-- headline headline-left headline-active -->
+      
+      <div style="position:relative;">
+        <div style="height: 4000px; background: red;">
+        </div>
+      </div>
+    </div> <!-- container-ext -->
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1120431-1.html
@@ -0,0 +1,205 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+    <style>
+      .container-ext {
+        padding-left: 180px;
+        padding-right: 180px;
+      }
+      
+      .headline {
+        line-height: 30px;
+        text-shadow: 1px 1px rgba(255, 255, 255, 0.3);
+      }
+      
+      ul {
+        list-style: none;
+      }
+      
+      .headline-left {
+        left: 30px;
+      }
+      
+      .headline-right {
+        top: 20px !important;
+        /*bottom:370px !important;*/
+        right: 20px;
+      }
+      
+      .headline-active {
+        position: fixed;
+        top: 100px;
+      }
+      
+      .list-author:before,
+      .list-author:after {
+        content: "\200e";
+        display: table;
+      }
+      .list-author:after {
+        clear: both;
+      }
+      
+      .list-author-vocal {
+        float: left;
+        margin-right: 10px;
+      }
+      
+      .ff { position: fixed; }
+    </style>
+  </head>
+  <body>
+    <div class="container-ext">
+      
+      <div class="headline headline-left headline-active">
+          <ul class="list-author">
+            <li class="list-author-vocal">
+              A
+            </li>
+            <li class="list-author-vocal">
+              B
+            </li>
+            <li class="list-author-vocal">
+              C
+            </li>
+            <li class="list-author-vocal">
+              D
+            </li>
+            <li class="list-author-vocal">
+              E
+            </li>
+          </ul>
+          <ul class="list-author">
+            <li class="list-author-vocal">
+              F
+            </li>
+            <li class="list-author-vocal">
+              G
+            </li>
+            <li class="list-author-vocal">
+              H
+            </li>
+            <li class="list-author-vocal">
+              I
+            </li>
+            <li class="list-author-vocal">
+              J
+            </li>
+          </ul>
+          <ul class="list-author">
+            <li class="list-author-vocal">
+              K
+            </li>
+            <li class="list-author-vocal">
+              L
+            </li>
+            <li class="list-author-vocal">
+              M
+            </li>
+            <li class="list-author-vocal">
+              N
+            </li>
+            <li class="list-author-vocal">
+              O
+            </li>
+          </ul>
+          <ul class="list-author">
+            <li class="list-author-vocal active">
+              P
+            </li>
+            <li class="list-author-vocal">
+              R
+            </li>
+            <li class="list-author-vocal">
+              S
+            </li>
+            <li class="list-author-vocal">
+              T
+            </li>
+            <li class="list-author-vocal">
+              V
+            </li>
+          </ul>
+          <ul class="list-author">
+            <li class="list-author-vocal">
+              W
+            </li>
+            <li class="list-author-vocal">
+              Y
+            </li>
+            <li class="list-author-vocal">
+              Z
+            </li>
+          </ul>
+<div class="ff" style="left: 69px; top: 115px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 173px; top: 115px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 173px; top: 115px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 173px; top: 115px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 173px; top: 115px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 173px; top: 115px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 173px; top: 115px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 145px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 161px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 162px; top: 161px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 162px; top: 161px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 162px; top: 161px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 162px; top: 161px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 162px; top: 161px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 162px; top: 161px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 191px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 177px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 177px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 177px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 177px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 177px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 177px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 237px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 253px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 168px; top: 253px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 168px; top: 253px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 168px; top: 253px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 168px; top: 253px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 168px; top: 253px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 168px; top: 253px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 283px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 299px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 135px; top: 299px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 135px; top: 299px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 135px; top: 299px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 135px; top: 299px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 329px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 345px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 68px; top: 352px; width: 41px; height: 19px; background: blue;"></div>
+<div class="ff" style="left: 68px; top: 382px; width: 41px; height: 19px; background: blue;"></div>
+<div class="ff" style="left: 68px; top: 412px; width: 41px; height: 19px; background: blue;"></div>
+<div class="ff" style="left: 68px; top: 442px; width: 41px; height: 19px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 465px; width: 3px; height: 3px; background: blue;"></div>
+
+          <ul class="list-author">
+          <li>
+            Word
+          </li>
+          <li>
+            Word
+          </li>
+          <li>
+            Word
+          </li>
+          <li>
+            Word
+          </li>
+        </ul>
+      </div> <!-- headline headline-left headline-active -->
+      <div class="headline headline-right headline-active">
+        ­<!--&#x200e;f--><div style="width: 2px; height: 2px; background: white;"></div>
+      </div>
+      
+      <div style="position:relative;">
+        <div style="height: 4000px; background: red;">
+        </div>
+      </div>
+    </div> <!-- container-ext -->
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1120431-2-ref.html
@@ -0,0 +1,204 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+    <style>
+      .container-ext {
+        padding-left: 180px;
+        padding-right: 180px;
+      }
+      
+      .headline {
+        line-height: 30px;
+        text-shadow: 1px 1px rgba(255, 255, 255, 0.3);
+      }
+      
+      ul {
+        list-style: none;
+      }
+      
+      .headline-left {
+        left: 30px;
+      }
+      
+      .headline-right {
+        top: 20px !important;
+        /*bottom:370px !important;*/
+        right: 20px;
+      }
+      
+      .headline-active {
+        position: fixed;
+        top: 100px;
+      }
+      
+      .list-author:before,
+      .list-author:after {
+        content: "\200e";
+        display: table;
+      }
+      .list-author:after {
+        clear: both;
+      }
+      
+      .list-author-vocal {
+        float: left;
+        margin-right: 10px;
+      }
+      
+      .ff { position: fixed; }
+    </style>
+  </head>
+  <body>
+    <div class="container-ext">
+      
+      <div class="headline headline-left headline-active">
+          <ul class="list-author">
+            <li class="list-author-vocal">
+              A
+            </li>
+            <li class="list-author-vocal">
+              B
+            </li>
+            <li class="list-author-vocal">
+              C
+            </li>
+            <li class="list-author-vocal">
+              D
+            </li>
+            <li class="list-author-vocal">
+              E
+            </li>
+          </ul>
+          <ul class="list-author">
+            <li class="list-author-vocal">
+              F
+            </li>
+            <li class="list-author-vocal">
+              G
+            </li>
+            <li class="list-author-vocal">
+              H
+            </li>
+            <li class="list-author-vocal">
+              I
+            </li>
+            <li class="list-author-vocal">
+              J
+            </li>
+          </ul>
+          <ul class="list-author">
+            <li class="list-author-vocal">
+              K
+            </li>
+            <li class="list-author-vocal">
+              L
+            </li>
+            <li class="list-author-vocal">
+              M
+            </li>
+            <li class="list-author-vocal">
+              N
+            </li>
+            <li class="list-author-vocal">
+              O
+            </li>
+          </ul>
+          <ul class="list-author">
+            <li class="list-author-vocal active">
+              P
+            </li>
+            <li class="list-author-vocal">
+              R
+            </li>
+            <li class="list-author-vocal">
+              S
+            </li>
+            <li class="list-author-vocal">
+              T
+            </li>
+            <li class="list-author-vocal">
+              V
+            </li>
+          </ul>
+          <ul class="list-author">
+            <li class="list-author-vocal">
+              W
+            </li>
+            <li class="list-author-vocal">
+              Y
+            </li>
+            <li class="list-author-vocal">
+              Z
+            </li>
+          </ul>
+<div class="ff" style="left: 69px; top: 115px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 173px; top: 115px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 173px; top: 115px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 173px; top: 115px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 173px; top: 115px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 173px; top: 115px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 173px; top: 115px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 145px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 161px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 162px; top: 161px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 162px; top: 161px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 162px; top: 161px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 162px; top: 161px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 162px; top: 161px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 162px; top: 161px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 191px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 177px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 177px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 177px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 177px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 177px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 177px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 237px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 253px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 168px; top: 253px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 168px; top: 253px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 168px; top: 253px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 168px; top: 253px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 168px; top: 253px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 168px; top: 253px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 283px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 299px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 135px; top: 299px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 135px; top: 299px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 135px; top: 299px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 135px; top: 299px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 329px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 345px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 68px; top: 352px; width: 41px; height: 19px; background: blue;"></div>
+<div class="ff" style="left: 68px; top: 382px; width: 41px; height: 19px; background: blue;"></div>
+<div class="ff" style="left: 68px; top: 412px; width: 41px; height: 19px; background: blue;"></div>
+<div class="ff" style="left: 68px; top: 442px; width: 41px; height: 19px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 465px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 469px; width: 3px; height: 3px; background: blue;"></div><!-- only needed after whitespace opt -->
+<div class="ff" style="left: 69px; top: 473px; width: 3px; height: 3px; background: blue;"></div><!-- only needed after whitespace opt -->
+
+          <ul class="list-author">
+          <li>
+            Word
+          </li>
+          <li>
+            Word
+          </li>
+          <li>
+            Word
+          </li>
+          <li>
+            Word
+          </li>
+        </ul>
+      </div> <!-- headline headline-left headline-active -->
+      
+      <div style="position:relative;">
+        <div style="height: 4000px; background: red;">
+        </div>
+      </div>
+    </div> <!-- container-ext -->
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1120431-2.html
@@ -0,0 +1,207 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+    <style>
+      .container-ext {
+        padding-left: 180px;
+        padding-right: 180px;
+      }
+      
+      .headline {
+        line-height: 30px;
+        text-shadow: 1px 1px rgba(255, 255, 255, 0.3);
+      }
+      
+      ul {
+        list-style: none;
+      }
+      
+      .headline-left {
+        left: 30px;
+      }
+      
+      .headline-right {
+        top: 20px !important;
+        /*bottom:370px !important;*/
+        right: 20px;
+      }
+      
+      .headline-active {
+        position: fixed;
+        top: 100px;
+      }
+      
+      .list-author:before,
+      .list-author:after {
+        content: "\200e";
+        display: table;
+      }
+      .list-author:after {
+        clear: both;
+      }
+      
+      .list-author-vocal {
+        float: left;
+        margin-right: 10px;
+      }
+      
+      .ff { position: fixed; }
+    </style>
+  </head>
+  <body>
+    <div class="container-ext">
+      
+      <div class="headline headline-left headline-active">
+          <ul class="list-author">
+            <li class="list-author-vocal">
+              A
+            </li>
+            <li class="list-author-vocal">
+              B
+            </li>
+            <li class="list-author-vocal">
+              C
+            </li>
+            <li class="list-author-vocal">
+              D
+            </li>
+            <li class="list-author-vocal">
+              E
+            </li>
+          </ul>
+          <ul class="list-author">
+            <li class="list-author-vocal">
+              F
+            </li>
+            <li class="list-author-vocal">
+              G
+            </li>
+            <li class="list-author-vocal">
+              H
+            </li>
+            <li class="list-author-vocal">
+              I
+            </li>
+            <li class="list-author-vocal">
+              J
+            </li>
+          </ul>
+          <ul class="list-author">
+            <li class="list-author-vocal">
+              K
+            </li>
+            <li class="list-author-vocal">
+              L
+            </li>
+            <li class="list-author-vocal">
+              M
+            </li>
+            <li class="list-author-vocal">
+              N
+            </li>
+            <li class="list-author-vocal">
+              O
+            </li>
+          </ul>
+          <ul class="list-author">
+            <li class="list-author-vocal active">
+              P
+            </li>
+            <li class="list-author-vocal">
+              R
+            </li>
+            <li class="list-author-vocal">
+              S
+            </li>
+            <li class="list-author-vocal">
+              T
+            </li>
+            <li class="list-author-vocal">
+              V
+            </li>
+          </ul>
+          <ul class="list-author">
+            <li class="list-author-vocal">
+              W
+            </li>
+            <li class="list-author-vocal">
+              Y
+            </li>
+            <li class="list-author-vocal">
+              Z
+            </li>
+          </ul>
+<div class="ff" style="left: 69px; top: 115px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 173px; top: 115px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 173px; top: 115px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 173px; top: 115px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 173px; top: 115px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 173px; top: 115px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 173px; top: 115px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 145px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 161px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 162px; top: 161px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 162px; top: 161px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 162px; top: 161px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 162px; top: 161px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 162px; top: 161px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 162px; top: 161px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 191px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 177px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 177px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 177px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 177px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 177px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 177px; top: 207px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 237px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 253px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 168px; top: 253px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 168px; top: 253px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 168px; top: 253px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 168px; top: 253px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 168px; top: 253px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 168px; top: 253px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 283px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 299px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 135px; top: 299px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 135px; top: 299px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 135px; top: 299px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 135px; top: 299px; width: 4px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 329px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 345px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 68px; top: 352px; width: 41px; height: 19px; background: blue;"></div>
+<div class="ff" style="left: 68px; top: 382px; width: 41px; height: 19px; background: blue;"></div>
+<div class="ff" style="left: 68px; top: 412px; width: 41px; height: 19px; background: blue;"></div>
+<div class="ff" style="left: 68px; top: 442px; width: 41px; height: 19px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 465px; width: 3px; height: 3px; background: blue;"></div>
+<div class="ff" style="left: 69px; top: 469px; width: 3px; height: 3px; background: blue;"></div><!-- only needed after whitespace opt -->
+<div class="ff" style="left: 69px; top: 473px; width: 3px; height: 3px; background: blue;"></div><!-- only needed after whitespace opt -->
+
+          <ul class="list-author">
+          <li>
+            Word
+          </li>
+          <li>
+            Word
+          </li>
+          <li>
+            Word
+          </li>
+          <li>
+            Word
+          </li>
+        </ul>
+      </div> <!-- headline headline-left headline-active -->
+      <div class="headline headline-right headline-active">
+        ­<!--&#x200e;f--><div style="width: 2px; height: 2px; background: white;"></div>
+      </div>
+      
+      <div style="position:relative;">
+        <div style="height: 4000px; background: red;">
+        </div>
+      </div>
+    </div> <!-- container-ext -->
+  </body>
+</html>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1851,8 +1851,10 @@ test-pref(layout.testing.overlay-scrollb
 fuzzy-if(winWidget&&!layersGPUAccelerated,1,31) fuzzy-if(B2G,128,75) == 1081185-1.html 1081185-1-ref.html   # fuzzy with event-regions, see bug 1107843
 == 1097437-1.html 1097437-1-ref.html
 == 1103258-1.html 1103258-1-ref.html # assertion crash test with layers culling test
 == 1105137-1.html 1105137-1-ref.html
 fuzzy-if(d2d,36,304) HTTP(..) == 1116480-1-fakeitalic-overflow.html 1116480-1-fakeitalic-overflow-ref.html
 == 1111753-1.html about:blank
 == 1119117-1a.html 1119117-1-ref.html
 == 1119117-1b.html 1119117-1-ref.html
+== 1120431-1.html 1120431-1-ref.html
+== 1120431-2.html 1120431-2-ref.html
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -69,24 +69,24 @@ nsCSSProps::kParserVariantTable[eCSSProp
 // in the grid-template-columns and grid-template-rows properties,
 // to limit high memory usage from small stylesheets.
 // Must be a positive integer. Should be large-ish.
 #define GRID_TEMPLATE_MAX_REPETITIONS 10000
 
 // End-of-array marker for mask arguments to ParseBitmaskValues
 #define MASK_END_VALUE  (-1)
 
-MOZ_BEGIN_ENUM_CLASS(CSSParseResult, int32_t)
+enum class CSSParseResult : int32_t {
   // Parsed something successfully:
   Ok,
   // Did not find what we were looking for, but did not consume any token:
   NotFound,
   // Unexpected token or token value, too late for UngetToken() to be enough:
   Error
-MOZ_END_ENUM_CLASS(CSSParseResult)
+};
 
 namespace {
 
 // Rule processing function
 typedef void (* RuleAppendFunc) (css::Rule* aRule, void* aData);
 static void AssignRuleToPointer(css::Rule* aRule, void* aPointer);
 static void AppendRuleToSheet(css::Rule* aRule, void* aParser);
 
--- a/layout/style/nsCSSRuleProcessor.cpp
+++ b/layout/style/nsCSSRuleProcessor.cpp
@@ -48,17 +48,16 @@
 #include "nsStyleSet.h"
 #include "mozilla/dom/Element.h"
 #include "nsNthIndexCache.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/Likely.h"
-#include "mozilla/TypedEnum.h"
 #include "mozilla/TypedEnumBits.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 #define VISITED_PSEUDO_PREF "layout.css.visited_links_enabled"
 
 static bool gSupportVisitedPseudo = true;
@@ -1402,34 +1401,34 @@ struct NodeMatchContext {
   {
   }
 };
 
 /**
  * Additional information about a selector (without combinators) that is
  * being matched.
  */
-MOZ_BEGIN_ENUM_CLASS(SelectorMatchesFlags, uint8_t)
+enum class SelectorMatchesFlags : uint8_t {
   NONE = 0,
 
   // The selector's flags are unknown.  This happens when you don't know
   // if you're starting from the top of a selector.  Only used in cases
   // where it's acceptable for matching to return a false positive.
   // (It's not OK to return a false negative.)
   UNKNOWN = 1 << 0,
 
   // The selector is part of a compound selector which has been split in
   // half, where the other half is a pseudo-element.  The current
   // selector is not a pseudo-element itself.
   HAS_PSEUDO_ELEMENT = 1 << 1,
 
   // The selector is part of an argument to a functional pseudo-class or
   // pseudo-element.
   IS_PSEUDO_CLASS_ARGUMENT = 1 << 2
-MOZ_END_ENUM_CLASS(SelectorMatchesFlags)
+};
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(SelectorMatchesFlags)
 
 static bool ValueIncludes(const nsSubstring& aValueList,
                             const nsSubstring& aValue,
                             const nsStringComparator& aComparator)
 {
   const char16_t *p = aValueList.BeginReading(),
               *p_end = aValueList.EndReading();
--- a/mfbt/EnumeratedArray.h
+++ b/mfbt/EnumeratedArray.h
@@ -5,47 +5,45 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* EnumeratedArray is like Array, but indexed by a typed enum. */
 
 #ifndef mozilla_EnumeratedArray_h
 #define mozilla_EnumeratedArray_h
 
 #include "mozilla/Array.h"
-#include "mozilla/TypedEnum.h"
 
 namespace mozilla {
 
 /**
  * EnumeratedArray is a fixed-size array container for use when an
- * array is indexed by a specific enum class, as currently implemented
- * by MOZ_BEGIN_ENUM_CLASS.
+ * array is indexed by a specific enum class.
  *
  * This provides type safety by guarding at compile time against accidentally
  * indexing such arrays with unrelated values. This also removes the need
  * for manual casting when using a typed enum value to index arrays.
  *
  * Aside from the typing of indices, EnumeratedArray is similar to Array.
  *
  * Example:
  *
- *   MOZ_BEGIN_ENUM_CLASS(AnimalSpecies)
+ *   enum class AnimalSpecies {
  *     Cow,
  *     Sheep,
  *     Count
- *   MOZ_END_ENUM_CLASS(AnimalSpecies)
+ *   };
  *
  *   EnumeratedArray<AnimalSpecies, AnimalSpecies::Count, int> headCount;
  *
  *   headCount[AnimalSpecies::Cow] = 17;
  *   headCount[AnimalSpecies::Sheep] = 30;
  *
  */
 template<typename IndexType,
-         MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(IndexType) SizeAsEnumValue,
+         IndexType SizeAsEnumValue,
          typename ValueType>
 class EnumeratedArray
 {
 public:
   static const size_t kSize = size_t(SizeAsEnumValue);
 
 private:
   Array<ValueType, kSize> mArray;
deleted file mode 100644
--- a/mfbt/TypedEnum.h
+++ /dev/null
@@ -1,256 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* Macros to emulate C++11 typed enums and enum classes. */
-
-#ifndef mozilla_TypedEnum_h
-#define mozilla_TypedEnum_h
-
-#include "mozilla/TypedEnumInternal.h"
-#include "mozilla/MacroArgs.h"
-
-#if defined(__cplusplus)
-
-/**
- * MOZ_BEGIN_ENUM_CLASS and MOZ_END_ENUM_CLASS provide access to the
- * strongly-typed enumeration feature of C++11 ("enum class").  If supported
- * by the compiler, an enum defined using these macros will not be implicitly
- * converted to any other type, and its enumerators will be scoped using the
- * enumeration name.  Place MOZ_BEGIN_ENUM_CLASS(EnumName [, type]) in place of
- * "enum EnumName {", and MOZ_END_ENUM_CLASS(EnumName) in place of the closing
- * "};".  For example,
- *
- *   MOZ_BEGIN_ENUM_CLASS(Enum, int32_t)
- *     A,
- *     B = 6
- *   MOZ_END_ENUM_CLASS(Enum)
- *
- * This will make "Enum::A" and "Enum::B" appear in the global scope, but "A"
- * and "B" will not.  In compilers that support C++11 strongly-typed
- * enumerations, implicit conversions of Enum values to numeric types will
- * fail.  In other compilers, Enum itself will actually be defined as a class,
- * and some implicit conversions will fail while others will succeed.
- *
- * The optional type argument specifies the underlying type for the enum where
- * supported, as with MOZ_ENUM_TYPE().  As with MOZ_ENUM_TYPE(), it will do
- * nothing on compilers that do not support it.
- *
- * MOZ_{BEGIN,END}_ENUM_CLASS doesn't work for defining enum classes nested
- * inside classes.  To define an enum class nested inside another class, use
- * MOZ_{BEGIN,END}_NESTED_ENUM_CLASS, and place a MOZ_FINISH_NESTED_ENUM_CLASS
- * in namespace scope to handle bits that can only be implemented with
- * namespace-scoped code.  For example:
- *
- *   class FooBar
- *   {
- *     MOZ_BEGIN_NESTED_ENUM_CLASS(Enum, int32_t)
- *       A,
- *       B = 6
- *     MOZ_END_NESTED_ENUM_CLASS(Enum)
- *   };
- *
- *   MOZ_FINISH_NESTED_ENUM_CLASS(FooBar::Enum)
- */
-#if defined(MOZ_HAVE_CXX11_STRONG_ENUMS)
-  /*
-   * All compilers that support strong enums also support an explicit
-   * underlying type, so no extra check is needed.
-   */
-
-   /* Single-argument form. */
-#  define MOZ_BEGIN_NESTED_ENUM_CLASS_HELPER1(Name) \
-     enum class Name {
-   /* Two-argument form. */
-#  define MOZ_BEGIN_NESTED_ENUM_CLASS_HELPER2(Name, type) \
-     enum class Name : type {
-#  define MOZ_END_NESTED_ENUM_CLASS(Name) \
-     };
-#  define MOZ_FINISH_NESTED_ENUM_CLASS(Name) /* nothing */
-
-  /*
-   * MOZ_ENUM_CLASS_ENUM_TYPE allows using enum classes
-   * as template parameter types. For that, we need integer types.
-   * In the present case where the compiler supports strong enums,
-   * these are already integer types so there is nothing more to do.
-   */
-#  define MOZ_ENUM_CLASS_ENUM_TYPE(Name) Name
-  /*
-   * See the comment below about MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE.
-   */
-#  define MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(Name) Name
-#else
-   /**
-    * We need Name to both name a type, and scope the provided enumerator
-    * names.  Namespaces and classes both provide scoping, but namespaces
-    * aren't types, so we need to use a class that wraps the enum values.  We
-    * have an implicit conversion from the inner enum type to the class, so
-    * statements like
-    *
-    *   Enum x = Enum::A;
-    *
-    * will still work.  We need to define an implicit conversion from the class
-    * to the inner enum as well, so that (for instance) switch statements will
-    * work.  This means that the class can be implicitly converted to a numeric
-    * value as well via the enum type, since C++ allows an implicit
-    * user-defined conversion followed by a standard conversion to still be
-    * implicit.
-    *
-    * We have an explicit constructor from int defined, so that casts like
-    * (Enum)7 will still work.  We also have a zero-argument constructor with
-    * no arguments, so declaration without initialization (like "Enum foo;")
-    * will work.
-    *
-    * Additionally, we'll delete as many operators as possible for the inner
-    * enum type, so statements like this will still fail:
-    *
-    *   f(5 + Enum::B); // deleted operator+
-    *
-    * But we can't prevent things like this, because C++ doesn't allow
-    * overriding conversions or assignment operators for enums:
-    *
-    *   int x = Enum::A;
-    *   int f()
-    *   {
-    *     return Enum::A;
-    *   }
-    */
-
-   /* Single-argument form. */
-#  define MOZ_BEGIN_NESTED_ENUM_CLASS_HELPER1(Name) \
-     class Name \
-     { \
-     public: \
-       enum Enum \
-       {
-   /* Two-argument form. */
-#  define MOZ_BEGIN_NESTED_ENUM_CLASS_HELPER2(Name, type) \
-     class Name \
-     { \
-     public: \
-       enum Enum : type \
-       {
-#  define MOZ_END_NESTED_ENUM_CLASS(Name) \
-       }; \
-       Name() {} \
-       MOZ_CONSTEXPR Name(Enum aEnum) : mEnum(aEnum) {} \
-       template<typename Other> \
-       explicit MOZ_CONSTEXPR Name(Other num) : mEnum((Enum)num) {} \
-       MOZ_CONSTEXPR operator Enum() const { return mEnum; } \
-       explicit MOZ_CONSTEXPR Name(const mozilla::CastableTypedEnumResult<Name>& aOther) \
-         : mEnum(aOther.get()) \
-       {} \
-     private: \
-       Enum mEnum; \
-     };
-#  define MOZ_FINISH_NESTED_ENUM_CLASS(Name) \
-     inline int operator+(const int&, const Name::Enum&) = delete; \
-     inline int operator+(const Name::Enum&, const int&) = delete; \
-     inline int operator-(const int&, const Name::Enum&) = delete; \
-     inline int operator-(const Name::Enum&, const int&) = delete; \
-     inline int operator*(const int&, const Name::Enum&) = delete; \
-     inline int operator*(const Name::Enum&, const int&) = delete; \
-     inline int operator/(const int&, const Name::Enum&) = delete; \
-     inline int operator/(const Name::Enum&, const int&) = delete; \
-     inline int operator%(const int&, const Name::Enum&) = delete; \
-     inline int operator%(const Name::Enum&, const int&) = delete; \
-     inline int operator+(const Name::Enum&) = delete; \
-     inline int operator-(const Name::Enum&) = delete; \
-     inline int& operator++(Name::Enum&) = delete; \
-     inline int operator++(Name::Enum&, int) = delete; \
-     inline int& operator--(Name::Enum&) = delete; \
-     inline int operator--(Name::Enum&, int) = delete; \
-     inline bool operator==(const int&, const Name::Enum&) = delete; \
-     inline bool operator==(const Name::Enum&, const int&) = delete; \
-     inline bool operator!=(const int&, const Name::Enum&) = delete; \
-     inline bool operator!=(const Name::Enum&, const int&) = delete; \
-     inline bool operator>(const int&, const Name::Enum&) = delete; \
-     inline bool operator>(const Name::Enum&, const int&) = delete; \
-     inline bool operator<(const int&, const Name::Enum&) = delete; \
-     inline bool operator<(const Name::Enum&, const int&) = delete; \
-     inline bool operator>=(const int&, const Name::Enum&) = delete; \
-     inline bool operator>=(const Name::Enum&, const int&) = delete; \
-     inline bool operator<=(const int&, const Name::Enum&) = delete; \
-     inline bool operator<=(const Name::Enum&, const int&) = delete; \
-     inline bool operator!(const Name::Enum&) = delete; \
-     inline bool operator&&(const bool&, const Name::Enum&) = delete; \
-     inline bool operator&&(const Name::Enum&, const bool&) = delete; \
-     inline bool operator||(const bool&, const Name::Enum&) = delete; \
-     inline bool operator||(const Name::Enum&, const bool&) = delete; \
-     inline int operator&(const int&, const Name::Enum&) = delete; \
-     inline int operator&(const Name::Enum&, const int&) = delete; \
-     inline int operator|(const int&, const Name::Enum&) = delete; \
-     inline int operator|(const Name::Enum&, const int&) = delete; \
-     inline int operator^(const int&, const Name::Enum&) = delete; \
-     inline int operator^(const Name::Enum&, const int&) = delete; \
-     inline int operator<<(const int&, const Name::Enum&) = delete; \
-     inline int operator<<(const Name::Enum&, const int&) = delete; \
-     inline int operator>>(const int&, const Name::Enum&) = delete; \
-     inline int operator>>(const Name::Enum&, const int&) = delete; \
-     inline int& operator+=(int&, const Name::Enum&) = delete; \
-     inline int& operator-=(int&, const Name::Enum&) = delete; \
-     inline int& operator*=(int&, const Name::Enum&) = delete; \
-     inline int& operator/=(int&, const Name::Enum&) = delete; \
-     inline int& operator%=(int&, const Name::Enum&) = delete; \
-     inline int& operator&=(int&, const Name::Enum&) = delete; \
-     inline int& operator|=(int&, const Name::Enum&) = delete; \
-     inline int& operator^=(int&, const Name::Enum&) = delete; \
-     inline int& operator<<=(int&, const Name::Enum&) = delete; \
-     inline int& operator>>=(int&, const Name::Enum&) = delete;
-
-  /*
-   * MOZ_ENUM_CLASS_ENUM_TYPE allows using enum classes
-   * as template parameter types. For that, we need integer types.
-   * In the present case, the integer type is the Enum nested type.
-   */
-#  define MOZ_ENUM_CLASS_ENUM_TYPE(Name) Name::Enum
-  /*
-   * MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE is a variant of MOZ_ENUM_CLASS_ENUM_TYPE
-   * to be used when the enum class at hand depends on template parameters.
-   *
-   * Indeed, if T depends on template parameters, in order to name a nested type
-   * in T, C++ does not allow to just write "T::NestedType". Instead, we have
-   * to write "typename T::NestedType". The role of this macro is to add
-   * this "typename" keywords where needed.
-   *
-   * Example:
-   *
-   *    template<typename T, MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(T) Value>
-   *    struct S {};
-   *
-   *    MOZ_BEGIN_ENUM_CLASS(E)
-   *      Foo,
-   *      Bar
-   *    MOZ_END_ENUM_CLASS(E)
-   *
-   *    S<E, E::Bar> s;
-   *
-   * In this example, the second template parameter to S is meant to be of type
-   * T, but on non-C++11 compilers, type T is a class type, not an integer
-   * type, so it is not accepted as the type of a constant template parameter.
-   * One would then want to use MOZ_ENUM_CLASS_ENUM_TYPE(T), but that doesn't
-   * work either as T depends on template parameters (more specifically here, T
-   * _is_ a template parameter) so as MOZ_ENUM_CLASS_ENUM_TYPE(T) expands to
-   * T::Enum, we are missing the required "typename" keyword. So here,
-   * MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE is needed.
-   */
-#  define MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(Name) typename Name::Enum
-#endif
-
-#  define MOZ_BEGIN_NESTED_ENUM_CLASS_GLUE(a, b) a b
-#  define MOZ_BEGIN_NESTED_ENUM_CLASS(...) \
-     MOZ_BEGIN_NESTED_ENUM_CLASS_GLUE( \
-       MOZ_PASTE_PREFIX_AND_ARG_COUNT(MOZ_BEGIN_NESTED_ENUM_CLASS_HELPER, \
-                                      __VA_ARGS__), \
-       (__VA_ARGS__))
-
-#  define MOZ_BEGIN_ENUM_CLASS(...) MOZ_BEGIN_NESTED_ENUM_CLASS(__VA_ARGS__)
-#  define MOZ_END_ENUM_CLASS(Name) \
-     MOZ_END_NESTED_ENUM_CLASS(Name) \
-     MOZ_FINISH_NESTED_ENUM_CLASS(Name)
-
-#endif /* __cplusplus */
-
-#endif /* mozilla_TypedEnum_h */
--- a/mfbt/TypedEnumBits.h
+++ b/mfbt/TypedEnumBits.h
@@ -6,21 +6,65 @@
 
 /*
  * MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS allows using a typed enum as bit flags.
  */
 
 #ifndef mozilla_TypedEnumBits_h
 #define mozilla_TypedEnumBits_h
 
+#include "mozilla/Attributes.h"
 #include "mozilla/IntegerTypeTraits.h"
-#include "mozilla/TypedEnumInternal.h"
 
 namespace mozilla {
 
+/*
+ * The problem that CastableTypedEnumResult aims to solve is that
+ * typed enums are not convertible to bool, and there is no way to make them
+ * be, yet user code wants to be able to write
+ *
+ *   if (myFlags & Flags::SOME_PARTICULAR_FLAG)              (1)
+ *
+ * There are different approaches to solving this. Most of them require
+ * adapting user code. For example, we could implement operator! and have
+ * the user write
+ *
+ *   if (!!(myFlags & Flags::SOME_PARTICULAR_FLAG))          (2)
+ *
+ * Or we could supply a IsNonZero() or Any() function returning whether
+ * an enum value is nonzero, and have the user write
+ *
+ *   if (Any(Flags & Flags::SOME_PARTICULAR_FLAG))           (3)
+ *
+ * But instead, we choose to preserve the original user syntax (1) as it
+ * is inherently more readable, and to ease porting existing code to typed
+ * enums. We achieve this by having operator& and other binary bitwise
+ * operators have as return type a class, CastableTypedEnumResult,
+ * that wraps a typed enum but adds bool convertibility.
+ */
+template<typename E>
+class CastableTypedEnumResult
+{
+private:
+  const E mValue;
+
+public:
+  explicit MOZ_CONSTEXPR CastableTypedEnumResult(E aValue)
+    : mValue(aValue)
+  {}
+
+  MOZ_CONSTEXPR operator E() const { return mValue; }
+
+  template<typename DestinationType>
+  MOZ_EXPLICIT_CONVERSION MOZ_CONSTEXPR
+  operator DestinationType() const { return DestinationType(mValue); }
+
+  MOZ_CONSTEXPR bool operator !() const { return !bool(mValue); }
+};
+
 #define MOZ_CASTABLETYPEDENUMRESULT_BINOP(Op, OtherType, ReturnType) \
 template<typename E> \
 MOZ_CONSTEXPR ReturnType \
 operator Op(const OtherType& aE, const CastableTypedEnumResult<E>& aR) \
 { \
   return ReturnType(aE Op OtherType(aR)); \
 } \
 template<typename E> \
@@ -64,42 +108,16 @@ operator Op(E& aR1, \
 MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(&=)
 MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(|=)
 MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(^=)
 
 #undef MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP
 
 #undef MOZ_CASTABLETYPEDENUMRESULT_BINOP
 
-#ifndef MOZ_HAVE_CXX11_STRONG_ENUMS
-
-#define MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(Op, ReturnType) \
-template<typename E> \
-MOZ_CONSTEXPR ReturnType \
-operator Op(typename E::Enum aE, const CastableTypedEnumResult<E>& aR) \
-{ \
-  return ReturnType(aE Op E(aR)); \
-} \
-template<typename E> \
-MOZ_CONSTEXPR ReturnType \
-operator Op(const CastableTypedEnumResult<E>& aR, typename E::Enum aE) \
-{ \
-  return ReturnType(E(aR) Op aE); \
-}
-
-MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(|, CastableTypedEnumResult<E>)
-MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(&, CastableTypedEnumResult<E>)
-MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(^, CastableTypedEnumResult<E>)
-MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(==, bool)
-MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(!=, bool)
-
-#undef MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11
-
-#endif // not MOZ_HAVE_CXX11_STRONG_ENUMS
-
 namespace detail {
 template<typename E>
 struct UnsignedIntegerTypeForEnum
   : UnsignedStdintTypeForSize<sizeof(E)>
 {};
 }
 
 } // namespace mozilla
@@ -114,71 +132,25 @@ struct UnsignedIntegerTypeForEnum
    } \
  \
    inline Name& \
    operator Op##=(Name& a, Name b) \
    { \
      return a = a Op b; \
    }
 
-#define MOZ_MAKE_ENUM_CLASS_OPS_IMPL(Name) \
+/**
+ * MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS generates standard bitwise operators
+ * for the given enum type. Use this to enable using an enum type as bit-field.
+ */
+#define MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Name) \
    MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, |) \
    MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, &) \
    MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, ^) \
    inline MOZ_CONSTEXPR mozilla::CastableTypedEnumResult<Name> \
    operator~(Name a) \
    { \
      typedef mozilla::CastableTypedEnumResult<Name> Result; \
      typedef mozilla::detail::UnsignedIntegerTypeForEnum<Name>::Type U; \
      return Result(Name(~(U(a)))); \
    }
 
-#ifndef MOZ_HAVE_CXX11_STRONG_ENUMS
-#  define MOZ_MAKE_ENUM_CLASS_BITWISE_BINOP_EXTRA_NON_CXX11(Name, Op) \
-     inline MOZ_CONSTEXPR mozilla::CastableTypedEnumResult<Name> \
-     operator Op(Name a, Name::Enum b) \
-     { \
-       return a Op Name(b); \
-     } \
- \
-     inline MOZ_CONSTEXPR mozilla::CastableTypedEnumResult<Name> \
-     operator Op(Name::Enum a, Name b) \
-     { \
-       return Name(a) Op b; \
-     } \
- \
-     inline MOZ_CONSTEXPR mozilla::CastableTypedEnumResult<Name> \
-     operator Op(Name::Enum a, Name::Enum b) \
-     { \
-       return Name(a) Op Name(b); \
-     } \
- \
-     inline Name& \
-     operator Op##=(Name& a, Name::Enum b) \
-     { \
-       return a = a Op Name(b); \
-    }
-
-#  define MOZ_MAKE_ENUM_CLASS_OPS_EXTRA_NON_CXX11(Name) \
-     MOZ_MAKE_ENUM_CLASS_BITWISE_BINOP_EXTRA_NON_CXX11(Name, |) \
-     MOZ_MAKE_ENUM_CLASS_BITWISE_BINOP_EXTRA_NON_CXX11(Name, &) \
-     MOZ_MAKE_ENUM_CLASS_BITWISE_BINOP_EXTRA_NON_CXX11(Name, ^) \
-     inline MOZ_CONSTEXPR mozilla::CastableTypedEnumResult<Name> \
-     operator~(Name::Enum a) \
-     { \
-       return ~(Name(a)); \
-     }
-#endif
-
-/**
- * MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS generates standard bitwise operators
- * for the given enum type. Use this to enable using an enum type as bit-field.
- */
-#ifdef MOZ_HAVE_CXX11_STRONG_ENUMS
-#  define MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Name) \
-     MOZ_MAKE_ENUM_CLASS_OPS_IMPL(Name)
-#else
-#  define MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Name) \
-     MOZ_MAKE_ENUM_CLASS_OPS_IMPL(Name) \
-     MOZ_MAKE_ENUM_CLASS_OPS_EXTRA_NON_CXX11(Name)
-#endif
-
 #endif // mozilla_TypedEnumBits_h
deleted file mode 100644
--- a/mfbt/TypedEnumInternal.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* Internal stuff needed by TypedEnum.h and TypedEnumBits.h. */
-
-// NOTE: When we can assume C++11 enum class support and TypedEnum.h goes away,
-// we should then consider folding TypedEnumInternal.h into TypedEnumBits.h.
-
-#ifndef mozilla_TypedEnumInternal_h
-#define mozilla_TypedEnumInternal_h
-
-#include "mozilla/Attributes.h"
-
-#if defined(__cplusplus)
-
-#if defined(__clang__)
-   /*
-    * Per Clang documentation, "Note that marketing version numbers should not
-    * be used to check for language features, as different vendors use different
-    * numbering schemes. Instead, use the feature checking macros."
-    */
-#  ifndef __has_extension
-#    define __has_extension __has_feature /* compatibility, for older versions of clang */
-#  endif
-#  if __has_extension(cxx_strong_enums)
-#    define MOZ_HAVE_CXX11_STRONG_ENUMS
-#  endif
-#elif defined(__GNUC__)
-#  if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
-#    if MOZ_GCC_VERSION_AT_LEAST(4, 6, 3)
-#      define MOZ_HAVE_CXX11_STRONG_ENUMS
-#    endif
-#  endif
-#elif defined(_MSC_VER)
-#  define MOZ_HAVE_CXX11_STRONG_ENUMS
-#endif
-
-namespace mozilla {
-
-/*
- * The problem that CastableTypedEnumResult aims to solve is that
- * typed enums are not convertible to bool, and there is no way to make them
- * be, yet user code wants to be able to write
- *
- *   if (myFlags & Flags::SOME_PARTICULAR_FLAG)              (1)
- *
- * There are different approaches to solving this. Most of them require
- * adapting user code. For example, we could implement operator! and have
- * the user write
- *
- *   if (!!(myFlags & Flags::SOME_PARTICULAR_FLAG))          (2)
- *
- * Or we could supply a IsNonZero() or Any() function returning whether
- * an enum value is nonzero, and have the user write
- *
- *   if (Any(Flags & Flags::SOME_PARTICULAR_FLAG))           (3)
- *
- * But instead, we choose to preserve the original user syntax (1) as it
- * is inherently more readable, and to ease porting existing code to typed
- * enums. We achieve this by having operator& and other binary bitwise
- * operators have as return type a class, CastableTypedEnumResult,
- * that wraps a typed enum but adds bool convertibility.
- */
-template<typename E>
-class CastableTypedEnumResult
-{
-private:
-  const E mValue;
-
-public:
-  explicit MOZ_CONSTEXPR CastableTypedEnumResult(E aValue)
-    : mValue(aValue)
-  {}
-
-  MOZ_CONSTEXPR operator E() const { return mValue; }
-
-  template<typename DestinationType>
-  MOZ_EXPLICIT_CONVERSION MOZ_CONSTEXPR
-  operator DestinationType() const { return DestinationType(mValue); }
-
-  MOZ_CONSTEXPR bool operator !() const { return !bool(mValue); }
-
-#ifndef MOZ_HAVE_CXX11_STRONG_ENUMS
-  // This get() method is used to implement a constructor in the
-  // non-c++11 fallback path for MOZ_BEGIN_ENUM_CLASS, taking a
-  // CastableTypedEnumResult. If we try to implement it using the
-  // above conversion operator E(), then at least clang 3.3
-  // (when forced to take the non-c++11 fallback path) compiles
-  // this constructor to an infinite recursion. So we introduce this
-  // get() method, that does exactly the same as the conversion operator,
-  // to work around this.
-  MOZ_CONSTEXPR E get() const { return mValue; }
-#endif
-};
-
-} // namespace mozilla
-
-#endif // __cplusplus
-
-#endif // mozilla_TypedEnumInternal_h
--- a/mfbt/moz.build
+++ b/mfbt/moz.build
@@ -64,19 +64,17 @@ EXPORTS.mozilla = [
     'SegmentedVector.h',
     'SHA1.h',
     'SizePrintfMacros.h',
     'SplayTree.h',
     'TaggedAnonymousMemory.h',
     'TemplateLib.h',
     'ThreadLocal.h',
     'ToString.h',
-    'TypedEnum.h',
     'TypedEnumBits.h',
-    'TypedEnumInternal.h',
     'Types.h',
     'TypeTraits.h',
     'UniquePtr.h',
     'Vector.h',
     'WeakPtr.h',
     'unused.h',
 ]
 
--- a/mfbt/tests/TestTypedEnum.cpp
+++ b/mfbt/tests/TestTypedEnum.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
-#include "mozilla/TypedEnum.h"
 #include "mozilla/TypedEnumBits.h"
 
 #include <stdint.h>
 
 // A rough feature check for is_literal_type. Not very carefully checked.
 // Feel free to amend as needed.
 // We leave ANDROID out because it's using stlport which doesn't have std::is_literal_type.
 #if __cplusplus >= 201103L && !defined(ANDROID)
@@ -50,78 +49,78 @@ RequireLiteralType()
 
 template<typename T>
 void
 RequireLiteralType(const T&)
 {
   RequireLiteralType<T>();
 }
 
-MOZ_BEGIN_ENUM_CLASS(AutoEnum)
+enum class AutoEnum {
   A,
   B = -3,
   C
-MOZ_END_ENUM_CLASS(AutoEnum)
+};
 
-MOZ_BEGIN_ENUM_CLASS(CharEnum, char)
+enum class CharEnum : char {
   A,
   B = 3,
   C
-MOZ_END_ENUM_CLASS(CharEnum)
+};
 
-MOZ_BEGIN_ENUM_CLASS(AutoEnumBitField)
+enum class AutoEnumBitField {
   A = 0x10,
   B = 0x20,
   C
-MOZ_END_ENUM_CLASS(AutoEnumBitField)
+};
 
-MOZ_BEGIN_ENUM_CLASS(CharEnumBitField, char)
+enum class CharEnumBitField : char {
   A = 0x10,
   B,
   C = 0x40
-MOZ_END_ENUM_CLASS(CharEnumBitField)
+};
 
 struct Nested
 {
-  MOZ_BEGIN_NESTED_ENUM_CLASS(AutoEnum)
+  enum class AutoEnum {
     A,
     B,
     C = -1
-  MOZ_END_NESTED_ENUM_CLASS(AutoEnum)
+  };
 
-  MOZ_BEGIN_NESTED_ENUM_CLASS(CharEnum, char)
+  enum class CharEnum : char {
     A = 4,
     B,
     C = 1
-  MOZ_END_NESTED_ENUM_CLASS(CharEnum)
+  };
 
-  MOZ_BEGIN_NESTED_ENUM_CLASS(AutoEnumBitField)
+  enum class AutoEnumBitField {
     A,
     B = 0x20,
     C
-  MOZ_END_NESTED_ENUM_CLASS(AutoEnumBitField)
+  };
 
-  MOZ_BEGIN_NESTED_ENUM_CLASS(CharEnumBitField, char)
+  enum class CharEnumBitField : char {
     A = 1,
     B = 1,
     C = 1
-  MOZ_END_NESTED_ENUM_CLASS(CharEnumBitField)
+  };
 };
 
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(AutoEnumBitField)
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(CharEnumBitField)
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Nested::AutoEnumBitField)
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Nested::CharEnumBitField)
 
 #define MAKE_STANDARD_BITFIELD_FOR_TYPE(IntType)                   \
-  MOZ_BEGIN_ENUM_CLASS(BitFieldFor_##IntType, IntType)             \
+  enum class BitFieldFor_##IntType : IntType {                     \
     A = 1,                                                         \
     B = 2,                                                         \
     C = 4,                                                         \
-  MOZ_END_ENUM_CLASS(BitFieldFor_##IntType)                        \
+  };                                                               \
   MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(BitFieldFor_##IntType)
 
 MAKE_STANDARD_BITFIELD_FOR_TYPE(int8_t)
 MAKE_STANDARD_BITFIELD_FOR_TYPE(uint8_t)
 MAKE_STANDARD_BITFIELD_FOR_TYPE(int16_t)
 MAKE_STANDARD_BITFIELD_FOR_TYPE(uint16_t)
 MAKE_STANDARD_BITFIELD_FOR_TYPE(int32_t)
 MAKE_STANDARD_BITFIELD_FOR_TYPE(uint32_t)
@@ -149,17 +148,17 @@ MAKE_STANDARD_BITFIELD_FOR_TYPE(unsigned
 #undef MAKE_STANDARD_BITFIELD_FOR_TYPE
 
 template<typename T>
 void
 TestNonConvertibilityForOneType()
 {
   using mozilla::IsConvertible;
 
-#if defined(MOZ_HAVE_CXX11_STRONG_ENUMS) && defined(MOZ_HAVE_EXPLICIT_CONVERSION)
+#if defined(MOZ_HAVE_EXPLICIT_CONVERSION)
   static_assert(!IsConvertible<T, bool>::value, "should not be convertible");
   static_assert(!IsConvertible<T, int>::value, "should not be convertible");
   static_assert(!IsConvertible<T, uint64_t>::value, "should not be convertible");
 #endif
 
   static_assert(!IsConvertible<bool, T>::value, "should not be convertible");
   static_assert(!IsConvertible<int, T>::value, "should not be convertible");
   static_assert(!IsConvertible<uint64_t, T>::value, "should not be convertible");
@@ -438,62 +437,62 @@ void TestNoConversionsBetweenUnrelatedTy
                 "should not be convertible");
   static_assert(!IsConvertible<decltype(T1::A | T1::B), decltype(T2::A)>::value,
                 "should not be convertible");
   static_assert(!IsConvertible<decltype(T1::A | T1::B), decltype(T2::A | T2::B)>::value,
                 "should not be convertible");
 #endif
 }
 
-MOZ_BEGIN_ENUM_CLASS(Int8EnumWithHighBits, int8_t)
+enum class Int8EnumWithHighBits : int8_t {
   A = 0x20,
   B = 0x40
-MOZ_END_ENUM_CLASS(Int8EnumWithHighBits)
+};
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Int8EnumWithHighBits)
 
-MOZ_BEGIN_ENUM_CLASS(Uint8EnumWithHighBits, uint8_t)
+enum class Uint8EnumWithHighBits : uint8_t {
   A = 0x40,
   B = 0x80
-MOZ_END_ENUM_CLASS(Uint8EnumWithHighBits)
+};
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Uint8EnumWithHighBits)
 
-MOZ_BEGIN_ENUM_CLASS(Int16EnumWithHighBits, int16_t)
+enum class Int16EnumWithHighBits : int16_t {
   A = 0x2000,
   B = 0x4000
-MOZ_END_ENUM_CLASS(Int16EnumWithHighBits)
+};
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Int16EnumWithHighBits)
 
-MOZ_BEGIN_ENUM_CLASS(Uint16EnumWithHighBits, uint16_t)
+enum class Uint16EnumWithHighBits : uint16_t {
   A = 0x4000,
   B = 0x8000
-MOZ_END_ENUM_CLASS(Uint16EnumWithHighBits)
+};
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Uint16EnumWithHighBits)
 
-MOZ_BEGIN_ENUM_CLASS(Int32EnumWithHighBits, int32_t)
+enum class Int32EnumWithHighBits : int32_t {
   A = 0x20000000,
   B = 0x40000000
-MOZ_END_ENUM_CLASS(Int32EnumWithHighBits)
+};
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Int32EnumWithHighBits)
 
-MOZ_BEGIN_ENUM_CLASS(Uint32EnumWithHighBits, uint32_t)
+enum class Uint32EnumWithHighBits : uint32_t {
   A = 0x40000000u,
   B = 0x80000000u
-MOZ_END_ENUM_CLASS(Uint32EnumWithHighBits)
+};
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Uint32EnumWithHighBits)
 
-MOZ_BEGIN_ENUM_CLASS(Int64EnumWithHighBits, int64_t)
+enum class Int64EnumWithHighBits : int64_t {
   A = 0x2000000000000000ll,
   B = 0x4000000000000000ll
-MOZ_END_ENUM_CLASS(Int64EnumWithHighBits)
+};
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Int64EnumWithHighBits)
 
-MOZ_BEGIN_ENUM_CLASS(Uint64EnumWithHighBits, uint64_t)
+enum class Uint64EnumWithHighBits : uint64_t {
   A = 0x4000000000000000ull,
   B = 0x8000000000000000ull
-MOZ_END_ENUM_CLASS(Uint64EnumWithHighBits)
+};
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Uint64EnumWithHighBits)
 
 // Checks that we don't accidentally truncate high bits by coercing to the wrong
 // integer type internally when implementing bitwise ops.
 template<typename EnumType, typename IntType>
 void TestIsNotTruncated()
 {
   EnumType a = EnumType::A;
--- a/testing/marionette/client/marionette/www/test_selectioncarets.html
+++ b/testing/marionette/client/marionette/www/test_selectioncarets.html
@@ -4,20 +4,27 @@
 
 <!DOCTYPE html>
 <html id="html">
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     <title>Bug 1019441: Marionette tests for selection carets</title>
   </head>
   <body>
+  <style>
+    *
+    {
+      -moz-user-select:none;
+    }
+  </style>
     <div><input id="input" value="ABC DEF GHI"></div>
     <br />
     <div><textarea id="textarea" rows="4" cols="8">ABC DEF GHI JKL MNO PQR</textarea></div>
     <br />
     <div><textarea dir="rtl" id="textarea_rtl" rows="8" cols="8">موزيلا فيرفكس موزيلا فيرفكس</textarea></div>
     <br />
-    <div style="width: 10em; height: 4em; word-wrap: break-word; overflow: auto;" contenteditable="true" id="contenteditable">ABC DEF GHI</div>
+    <div style="width: 10em; height: 4em; word-wrap: break-word; overflow: auto; -moz-user-select:text" contenteditable="true" id="contenteditable">ABC DEF GHI</div>
     <br />
-    <div style="width: 10em; height: 4em; word-wrap: break-word; overflow: auto;" id="content">ABC DEF GHI</div>
+    <div style="width: 10em; height: 4em; word-wrap: break-word; overflow: auto; -moz-user-select:text" id="content">ABC DEF GHI</div>
     <br />
+    <div style="width: 10em; height: 8em; overflow: auto; -moz-user-select:text" id="contenteditable2" contenteditable="true">First Line<br></br>Second Line<br></br>Third Line</div>
   </body>
 </html>
--- a/toolkit/components/remote/nsGTKRemoteService.h
+++ b/toolkit/components/remote/nsGTKRemoteService.h
@@ -40,15 +40,15 @@ private:
 
 
   static gboolean HandlePropertyChange(GtkWidget *widget,
                                        GdkEventProperty *event,
                                        nsIWeakReference* aThis);
 
 
   virtual void SetDesktopStartupIDOrTimestamp(const nsACString& aDesktopStartupID,
-                                              uint32_t aTimestamp);
+                                              uint32_t aTimestamp) MOZ_OVERRIDE;
 
   nsInterfaceHashtable<nsPtrHashKey<GtkWidget>, nsIWeakReference> mWindows;
   GtkWidget* mServerWindow;  
 };
 
 #endif // __nsGTKRemoteService_h__
--- a/toolkit/components/remote/nsQtRemoteService.h
+++ b/toolkit/components/remote/nsQtRemoteService.h
@@ -21,17 +21,17 @@ public:
   NS_DECL_NSIREMOTESERVICE  
 
   nsQtRemoteService();
 
 private:
   virtual ~nsQtRemoteService();
 
   virtual void SetDesktopStartupIDOrTimestamp(const nsACString& aDesktopStartupID,
-                                              uint32_t aTimestamp);
+                                              uint32_t aTimestamp) MOZ_OVERRIDE;
 
   void PropertyNotifyEvent(XEvent *evt);
   friend class MozQRemoteEventHandlerWidget;
 
   QWindow *mServerWindow;
 };
 
 #endif // __nsQtRemoteService_h__
--- a/toolkit/xre/glxtest.cpp
+++ b/toolkit/xre/glxtest.cpp
@@ -29,16 +29,18 @@
 
 #ifdef __SUNPRO_CC
 #include <stdio.h>
 #endif
 
 #include "X11/Xlib.h"
 #include "X11/Xutil.h"
 
+#include "mozilla/unused.h"
+
 // stuff from glx.h
 typedef struct __GLXcontextRec *GLXContext;
 typedef XID GLXPixmap;
 typedef XID GLXDrawable;
 /* GLX 1.3 and later */
 typedef struct __GLXFBConfigRec *GLXFBConfig;
 typedef XID GLXFBConfigID;
 typedef XID GLXContextID;
@@ -76,32 +78,32 @@ static func_ptr_type cast(void *ptr)
 {
   return reinterpret_cast<func_ptr_type>(
            reinterpret_cast<size_t>(ptr)
          );
 }
 
 static void fatal_error(const char *str)
 {
-  write(write_end_of_the_pipe, str, strlen(str));
-  write(write_end_of_the_pipe, "\n", 1);
+  mozilla::unused << write(write_end_of_the_pipe, str, strlen(str));
+  mozilla::unused << write(write_end_of_the_pipe, "\n", 1);
   _exit(EXIT_FAILURE);
 }
 
 static int
 x_error_handler(Display *, XErrorEvent *ev)
 {
   enum { bufsize = 1024 };
   char buf[bufsize];
   int length = snprintf(buf, bufsize,
                         "X error occurred in GLX probe, error_code=%d, request_code=%d, minor_code=%d\n",
                         ev->error_code,
                         ev->request_code,
                         ev->minor_code);
-  write(write_end_of_the_pipe, buf, length);
+  mozilla::unused << write(write_end_of_the_pipe, buf, length);
   _exit(EXIT_FAILURE);
   return 0;
 }
 
 
 // glxtest is declared inside extern "C" so that the name is not mangled.
 // The name is used in build/valgrind/x86_64-redhat-linux-gnu.sup to suppress
 // memory leak errors because we run it inside a short lived fork and we don't
@@ -244,17 +246,17 @@ void glxtest()
   //   XCloseDisplay(dpy);
   // but this can cause 1-minute stalls on certain setups using Nouveau, see bug 973192
   XSync(dpy, False);
 #endif
 
   dlclose(libgl);
 
   ///// Finally write data to the pipe
-  write(write_end_of_the_pipe, buf, length);
+  mozilla::unused << write(write_end_of_the_pipe, buf, length);
 }
 
 }
 
 /** \returns true in the child glxtest process, false in the parent process */
 bool fire_glxtest_process()
 {
   int pfd[2];
--- a/widget/EventForwards.h
+++ b/widget/EventForwards.h
@@ -3,18 +3,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_EventForwards_h__
 #define mozilla_EventForwards_h__
 
 #include <stdint.h>
 
-#include "mozilla/TypedEnum.h"
-
 /**
  * XXX Following enums should be in BasicEvents.h.  However, currently, it's
  *     impossible to use foward delearation for enum.
  */
 
 /**
  * Return status for event processors.
  */
--- a/widget/android/NativeJSContainer.cpp
+++ b/widget/android/NativeJSContainer.cpp
@@ -640,20 +640,20 @@ struct HasProperty
     }
 
     static Type FromValue(JNIEnv* env, jobject instance,
                           JSContext* cx, JS::HandleValue val) {
         return JNI_TRUE;
     }
 };
 
-MOZ_BEGIN_ENUM_CLASS(FallbackOption)
+enum class FallbackOption {
     THROW,
     RETURN,
-MOZ_END_ENUM_CLASS(FallbackOption)
+};
 
 template <class Property>
 typename Property::Type
 GetProperty(JNIEnv* env, jobject instance, jstring name,
             FallbackOption option = FallbackOption::THROW,
             typename Property::Type fallback = typename Property::Type())
 {
     MOZ_ASSERT(env);
--- a/widget/cocoa/VibrancyManager.h
+++ b/widget/cocoa/VibrancyManager.h
@@ -3,35 +3,34 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef VibrancyManager_h
 #define VibrancyManager_h
 
 #include "mozilla/Assertions.h"
-#include "mozilla/TypedEnum.h"
 #include "nsClassHashtable.h"
 #include "nsRegion.h"
 #include "nsTArray.h"
 
 #import <Foundation/NSGeometry.h>
 
 @class NSColor;
 @class NSView;
 class nsChildView;
 class nsIntRegion;
 
 namespace mozilla {
 
-MOZ_BEGIN_ENUM_CLASS(VibrancyType)
+enum class VibrancyType {
   LIGHT,
   DARK,
   TOOLTIP
-MOZ_END_ENUM_CLASS(VibrancyType)
+};
 
 /**
  * VibrancyManager takes care of updating the vibrant regions of a window.
  * Vibrancy is a visual look that was introduced on OS X starting with 10.10.
  * An app declares vibrant window regions to the window server, and the window
  * server will display a blurred rendering of the screen contents from behind
  * the window in these areas, behind the actual window contents. Consequently,
  * the effect is only visible in areas where the window contents are not
--- a/xpcom/base/CycleCollectedJSRuntime.h
+++ b/xpcom/base/CycleCollectedJSRuntime.h
@@ -207,17 +207,17 @@ private:
     FinalizeNow,
   };
 
   void FinalizeDeferredThings(DeferredFinalizeType aType);
 
 public:
   // Two conditions, JSOutOfMemory and JSLargeAllocationFailure, are noted in
   // crash reports. Here are the values that can appear in the reports:
-  MOZ_BEGIN_NESTED_ENUM_CLASS(OOMState, uint32_t)
+  enum class OOMState : uint32_t {
     // The condition has never happened. No entry appears in the crash report.
     OK,
 
     // We are currently reporting the given condition.
     // 
     // Suppose a crash report contains "JSLargeAllocationFailure:
     // Reporting". This means we crashed while executing memory-pressure
     // observers, trying to shake loose some memory. The large allocation in
@@ -235,17 +235,17 @@ public:
     // had executed yet.
     Reported,
 
     // The condition has happened, but a GC cycle ended since then.
     //
     // GC is taken as a proxy for "we've been banging on the heap a good bit
     // now and haven't crashed; the OOM was probably handled correctly".
     Recovered
-  MOZ_END_NESTED_ENUM_CLASS(OOMState)
+  };
 
 private:
   void AnnotateAndSetOutOfMemory(OOMState* aStatePtr, OOMState aNewState);
   void OnGC(JSGCStatus aStatus);
   void OnOutOfMemory();
   void OnLargeAllocationFailure();
 
 public:
@@ -311,18 +311,16 @@ private:
   nsCOMPtr<nsIException> mPendingException;
 
   nsTArray<nsRefPtr<nsIRunnable>> mPromiseMicroTaskQueue;
 
   OOMState mOutOfMemoryState;
   OOMState mLargeAllocationFailureState;
 };
 
-MOZ_FINISH_NESTED_ENUM_CLASS(CycleCollectedJSRuntime::OOMState)
-
 void TraceScriptHolder(nsISupports* aHolder, JSTracer* aTracer);
 
 // Returns true if the JSGCTraceKind is one the cycle collector cares about.
 inline bool AddToCCKind(JSGCTraceKind aKind)
 {
   return aKind == JSTRACE_OBJECT || aKind == JSTRACE_SCRIPT;
 }
 
--- a/xpcom/base/nsError.h
+++ b/xpcom/base/nsError.h
@@ -3,17 +3,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsError_h__
 #define nsError_h__
 
 #include "mozilla/Likely.h"
-#include "mozilla/TypedEnum.h"
 
 #include <stdint.h>
 
 /*
  * To add error code to your module, you need to do the following:
  *
  * 1) Add a module offset code.  Add yours to the bottom of the list
  *    right below this comment, adding 1.
@@ -117,38 +116,30 @@
  * doesn't really work for nsresult.  We need constants like NS_OK with type
  * nsresult, but they can't be used in (e.g.) switch cases if they're objects.
  * But if we define them to be of type nsresult::Enum instead, that causes
  *   return foo ? F() : NS_ERROR_FAILURE;
  * to fail, because nsresult and nsresult::Enum are two distinct types and
  * either can be converted to the other, so it's ambiguous.  So we have to fall
  * back to a regular enum.
  */
-#if defined(MOZ_HAVE_CXX11_STRONG_ENUMS)
+#if defined(__cplusplus)
   typedef enum class tag_nsresult : uint32_t
   {
     #undef ERROR
     #define ERROR(key, val) key = val
     #include "ErrorList.h"
     #undef ERROR
   } nsresult;
 
   /*
    * enum classes don't place their initializers in the global scope, so we need
    * #define's for compatibility with old code.
    */
   #include "ErrorListCxxDefines.h"
-#elif defined(__cplusplus)
-  typedef enum tag_nsresult : uint32_t
-  {
-    #undef ERROR
-    #define ERROR(key, val) key = val
-    #include "ErrorList.h"
-    #undef ERROR
-  } nsresult;
 #else
   /*
    * C doesn't have any way to fix the type underlying an enum, and enum
    * initializers can't have values outside the range of 'int'.  So typedef
    * nsresult to the correct unsigned type, and fall back to using #defines for
    * all error constants.
    */
   typedef uint32_t nsresult;
--- a/xpcom/base/nsMemoryReporterManager.cpp
+++ b/xpcom/base/nsMemoryReporterManager.cpp
@@ -151,17 +151,17 @@ ResidentUniqueDistinguishedAmount(int64_
 class ResidentUniqueReporter MOZ_FINAL : public nsIMemoryReporter
 {
   ~ResidentUniqueReporter() {}
 
 public:
   NS_DECL_ISUPPORTS
 
   NS_METHOD CollectReports(nsIHandleReportCallback* aHandleReport,
-                           nsISupports* aData, bool aAnonymize)
+                           nsISupports* aData, bool aAnonymize) MOZ_OVERRIDE
   {
     int64_t amount = 0;
     nsresult rv = ResidentUniqueDistinguishedAmount(&amount);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return MOZ_COLLECT_REPORT(
       "resident-unique", KIND_OTHER, UNITS_BYTES, amount,
 "Memory mapped by the process that is present in physical memory and not "
--- a/xpcom/glue/EnumeratedArrayCycleCollection.h
+++ b/xpcom/glue/EnumeratedArrayCycleCollection.h
@@ -6,30 +6,30 @@
 
 #ifndef EnumeratedArrayCycleCollection_h_
 #define EnumeratedArrayCycleCollection_h_
 
 #include "mozilla/EnumeratedArray.h"
 #include "nsCycleCollectionTraversalCallback.h"
 
 template<typename IndexType,
-         MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(IndexType) SizeAsEnumValue,
+         IndexType SizeAsEnumValue,
          typename ValueType>
 inline void
 ImplCycleCollectionUnlink(mozilla::EnumeratedArray<IndexType,
                                                    SizeAsEnumValue,
                                                    ValueType>& aField)
 {
   for (size_t i = 0; i < size_t(SizeAsEnumValue); ++i) {
     aField[IndexType(i)] = nullptr;
   }
 }
 
 template<typename IndexType,
-         MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(IndexType) SizeAsEnumValue,
+         IndexType SizeAsEnumValue,
          typename ValueType>
 inline void
 ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
                             mozilla::EnumeratedArray<IndexType,
                                                      SizeAsEnumValue,
                                                      ValueType>& aField,
                             const char* aName,
                             uint32_t aFlags = 0)
--- a/xpcom/glue/pldhash.h
+++ b/xpcom/glue/pldhash.h
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef pldhash_h___
 #define pldhash_h___
 /*
  * Double hashing, a la Knuth 6.
  */
+#include "mozilla/Attributes.h" // for MOZ_ALWAYS_INLINE
 #include "mozilla/fallible.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Types.h"
 #include "nscore.h"
 
 #ifdef PL_DHASHMETER
 #include <stdio.h>
 #endif