Merge m-c to b-i FIREFOX_AURORA_45_BASE
authorPhil Ringnalda <philringnalda@gmail.com>
Sun, 13 Dec 2015 22:37:10 -0800
changeset 276310 99137d6d4061f408ae0869122649d8bdf489cc30
parent 276309 d8c83969224bff44b29a1c900a67c951cc1c820e (current diff)
parent 276292 871d92a1b0701ad79780989bf2ae335d4a19f138 (diff)
child 276311 d054c067bcf8603fc06db416f11ca3d2d9552e2d
child 276314 2110ff129ead3eefb0aeae4cc96e7daa0d74a1ac
child 276335 afc8558eac72996c2d24f3257ee045bd1ee2a196
child 276374 4cfa9d84377ba4b1438234a2cb81f4ebfdbf0b54
push idunknown
push userunknown
push dateunknown
milestone45.0a1
Merge m-c to b-i
js/src/jit-test/tests/gc/bug-1226888.js
js/src/tests/js1_8_5/extensions/sharedtypedarray.js
--- a/browser/extensions/loop/skin/shared/loop.css
+++ b/browser/extensions/loop/skin/shared/loop.css
@@ -159,17 +159,17 @@
       -moz-image-region: rect(0, 224px, 32px, 192px);
     }
   }
 
   notification[value="loop-sharing-notification"] {
     -moz-appearance: none;
     height: 40px;
     background-color: #00a9dc;
-    box-shadow: 0 40px 1px rgba(0,0,0,.5) inset;
+    box-shadow: 0 -1px 1px rgba(0,0,0,.4) inset;
   }
 
   notification[value="loop-sharing-notification"].paused {
     background-color: #ebebeb;
   }
 
   notification[value="loop-sharing-notification"] .notification-inner {
     color: #fff;
@@ -179,30 +179,24 @@
   notification[value="loop-sharing-notification"].paused .notification-inner {
     color: #00a9dc;
   }
 
   notification[value="loop-sharing-notification"] .notification-button {
     -moz-appearance: none;
     background-color: #fff;
     border: 0;
-    border-right: solid 1px #ebebeb;
     width: 100px;
     height: 40px;
     margin: 0;
     list-style-image: url(chrome://loop/content/shared/img/pause-12x12.svg);
-    box-shadow: 0 40px 1px rgba(0,0,0,.5) inset;
+    box-shadow: 0 -1px 1px rgba(0,0,0,.5) inset;
     text-shadow: none;
   }
 
-  notification[value="loop-sharing-notification"] .notification-button:-moz-locale-dir(rtl) {
-    border-right: 0;
-    border-left: solid 1px #ebebeb;
-  }
-
   notification[value="loop-sharing-notification"].paused .notification-button {
     background-color: #57bd35;
     color: #fff;
     list-style-image: url(chrome://loop/content/shared/img/play-12x12.svg);
   }
 
   notification[value="loop-sharing-notification"].paused .notification-button:hover {
     background-color: #39a017;
@@ -212,17 +206,16 @@
   notification[value="loop-sharing-notification"].paused .notification-button-default:hover {
     background-color: #ebebeb;
   }
 
   notification[value="loop-sharing-notification"] .notification-button-default,
   notification[value="loop-sharing-notification"].paused .notification-button-default {
     color: #d92215;
     background-color: #fff;
-    border-right: 0;
     list-style-image: url(chrome://loop/content/shared/img/stop-12x12.svg);
   }
 
   notification[value="loop-sharing-notification"] .notification-button .button-icon {
     display: block;
     -moz-margin-end: 6px;
   }
 
--- a/browser/extensions/pdfjs/README.mozilla
+++ b/browser/extensions/pdfjs/README.mozilla
@@ -1,3 +1,3 @@
 This is the pdf.js project output, https://github.com/mozilla/pdf.js
 
-Current extension version is: 1.3.72
+Current extension version is: 1.3.76
--- a/browser/extensions/pdfjs/content/build/pdf.js
+++ b/browser/extensions/pdfjs/content/build/pdf.js
@@ -15,18 +15,18 @@
 /*jshint globalstrict: false */
 /* globals PDFJS */
 
 // Initializing PDFJS global object (if still undefined)
 if (typeof PDFJS === 'undefined') {
   (typeof window !== 'undefined' ? window : this).PDFJS = {};
 }
 
-PDFJS.version = '1.3.72';
-PDFJS.build = '4d6f3c8';
+PDFJS.version = '1.3.76';
+PDFJS.build = 'f7ec866';
 
 (function pdfjsWrapper() {
   // Use strict in our context only - users might not want it
   'use strict';
 
 
 
 var globalScope = (typeof window === 'undefined') ? this : window;
@@ -6399,18 +6399,16 @@ var TilingPattern = (function TilingPatt
       return ctx.createPattern(temporaryPatternCanvas, 'repeat');
     }
   };
 
   return TilingPattern;
 })();
 
 
-PDFJS.disableFontFace = false;
-
 function FontLoader(docId) {
   this.docId = docId;
   this.styleElement = null;
 }
 FontLoader.prototype = {
   insertRule: function fontLoaderInsertRule(rule) {
     var styleElement = this.styleElement;
     if (!styleElement) {
@@ -6423,16 +6421,17 @@ FontLoader.prototype = {
     var styleSheet = styleElement.sheet;
     styleSheet.insertRule(rule, styleSheet.cssRules.length);
   },
 
   clear: function fontLoaderClear() {
     var styleElement = this.styleElement;
     if (styleElement) {
       styleElement.parentNode.removeChild(styleElement);
+      styleElement = this.styleElement = null;
     }
   },
   bind: function fontLoaderBind(fonts, callback) {
     assert(!isWorker, 'bind() shall be called from main thread');
   
     for (var i = 0, ii = fonts.length; i < ii; i++) {
       var font = fonts[i];
       if (font.attached) {
--- a/browser/extensions/pdfjs/content/build/pdf.worker.js
+++ b/browser/extensions/pdfjs/content/build/pdf.worker.js
@@ -15,18 +15,18 @@
 /*jshint globalstrict: false */
 /* globals PDFJS */
 
 // Initializing PDFJS global object (if still undefined)
 if (typeof PDFJS === 'undefined') {
   (typeof window !== 'undefined' ? window : this).PDFJS = {};
 }
 
-PDFJS.version = '1.3.72';
-PDFJS.build = '4d6f3c8';
+PDFJS.version = '1.3.76';
+PDFJS.build = 'f7ec866';
 
 (function pdfjsWrapper() {
   // Use strict in our context only - users might not want it
   'use strict';
 
 
 
 var globalScope = (typeof window === 'undefined') ? this : window;
--- a/dom/svg/SVGFragmentIdentifier.cpp
+++ b/dom/svg/SVGFragmentIdentifier.cpp
@@ -35,257 +35,168 @@ IgnoreWhitespace(char16_t aChar)
 static SVGViewElement*
 GetViewElement(nsIDocument* aDocument, const nsAString& aId)
 {
   Element* element = aDocument->GetElementById(aId);
   return (element && element->IsSVGElement(nsGkAtoms::view)) ?
             static_cast<SVGViewElement*>(element) : nullptr;
 }
 
-void
-SVGFragmentIdentifier::SaveOldPreserveAspectRatio(SVGSVGElement* root)
+// Handles setting/clearing the root's mSVGView pointer.
+class MOZ_RAII AutoSVGViewHandler
 {
-  if (root->mPreserveAspectRatio.IsExplicitlySet()) {
-    root->SetPreserveAspectRatioProperty(root->mPreserveAspectRatio.GetBaseValue());
+public:
+  explicit AutoSVGViewHandler(SVGSVGElement* aRoot
+                              MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
+    : mRoot(aRoot), mValid(false) {
+    MOZ_GUARD_OBJECT_NOTIFIER_INIT;
+    mWasOverridden = mRoot->UseCurrentView();
+    mRoot->mSVGView = nullptr;
+    mRoot->mCurrentViewID = nullptr;
   }
-}
-
-void 
-SVGFragmentIdentifier::RestoreOldPreserveAspectRatio(SVGSVGElement* root)
-{
-  const SVGPreserveAspectRatio* oldPARPtr = root->GetPreserveAspectRatioProperty();
-  if (oldPARPtr) {
-    root->mPreserveAspectRatio.SetBaseValue(*oldPARPtr, root);
-  } else if (root->mPreserveAspectRatio.IsExplicitlySet()) {
-    ErrorResult error;
-    root->RemoveAttribute(NS_LITERAL_STRING("preserveAspectRatio"), error);
-  }
-}
 
-void 
-SVGFragmentIdentifier::SaveOldViewBox(SVGSVGElement* root)
-{
-  if (root->mViewBox.IsExplicitlySet()) {
-    root->SetViewBoxProperty(root->mViewBox.GetBaseValue());
+  ~AutoSVGViewHandler() {
+    if (!mWasOverridden && !mValid) {
+      // we weren't overridden before and we aren't
+      // overridden now so nothing has changed.
+      return;
+    }
+    if (mValid) {
+      mRoot->mSVGView = mSVGView;
+    }
+    mRoot->InvalidateTransformNotifyFrame();
   }
-}
 
-void 
-SVGFragmentIdentifier::RestoreOldViewBox(SVGSVGElement* root)
-{
-  const nsSVGViewBoxRect* oldViewBoxPtr = root->GetViewBoxProperty();
-  if (oldViewBoxPtr) {
-    root->mViewBox.SetBaseValue(*oldViewBoxPtr, root);
-  } else if (root->mViewBox.IsExplicitlySet()) {
-    ErrorResult error;
-    root->RemoveAttribute(NS_LITERAL_STRING("viewBox"), error);
+  void CreateSVGView() {
+    MOZ_ASSERT(!mSVGView, "CreateSVGView should not be called multiple times");
+    mSVGView = new SVGView();
   }
-}
+
+  bool ProcessAttr(const nsAString& aToken, const nsAString &aParams) {
+
+    MOZ_ASSERT(mSVGView, "CreateSVGView should have been called");
+
+    // SVGViewAttributes may occur in any order, but each type may only occur
+    // at most one time in a correctly formed SVGViewSpec.
+    // If we encounter any attribute more than once or get any syntax errors
+    // we're going to return false and cancel any changes.
 
-void 
-SVGFragmentIdentifier::SaveOldZoomAndPan(SVGSVGElement* root)
-{
-  if (root->mEnumAttributes[SVGSVGElement::ZOOMANDPAN].IsExplicitlySet()) {
-    root->SetZoomAndPanProperty(root->mEnumAttributes[SVGSVGElement::ZOOMANDPAN].GetBaseValue());
+    if (IsMatchingParameter(aToken, NS_LITERAL_STRING("viewBox"))) {
+      if (mSVGView->mViewBox.IsExplicitlySet() ||
+          NS_FAILED(mSVGView->mViewBox.SetBaseValueString(
+                      aParams, mRoot, false))) {
+        return false;
+      }
+    } else if (IsMatchingParameter(aToken, NS_LITERAL_STRING("preserveAspectRatio"))) {
+      if (mSVGView->mPreserveAspectRatio.IsExplicitlySet() ||
+          NS_FAILED(mSVGView->mPreserveAspectRatio.SetBaseValueString(
+                      aParams, mRoot, false))) {
+        return false;
+      }
+    } else if (IsMatchingParameter(aToken, NS_LITERAL_STRING("transform"))) {
+      if (mSVGView->mTransforms) {
+        return false;
+      }
+      mSVGView->mTransforms = new nsSVGAnimatedTransformList();
+      if (NS_FAILED(mSVGView->mTransforms->SetBaseValueString(aParams))) {
+        return false;
+      }
+    } else if (IsMatchingParameter(aToken, NS_LITERAL_STRING("zoomAndPan"))) {
+      if (mSVGView->mZoomAndPan.IsExplicitlySet()) {
+        return false;
+      }
+      nsIAtom* valAtom = NS_GetStaticAtom(aParams);
+      if (!valAtom ||
+          NS_FAILED(mSVGView->mZoomAndPan.SetBaseValueAtom(
+                      valAtom, mRoot))) {
+        return false;
+      }
+    } else {
+      // We don't support viewTarget currently
+      return false;
+    }
+    return true;
   }
-}
-
-void
-SVGFragmentIdentifier::RestoreOldZoomAndPan(SVGSVGElement* root)
-{
-  uint16_t oldZoomAndPan = root->GetZoomAndPanProperty();
-  if (oldZoomAndPan != SVG_ZOOMANDPAN_UNKNOWN) {
-    root->mEnumAttributes[SVGSVGElement::ZOOMANDPAN].SetBaseValue(oldZoomAndPan, root);
-  } else if (root->mEnumAttributes[SVGSVGElement::ZOOMANDPAN].IsExplicitlySet()) {
-    ErrorResult error;
-    root->RemoveAttribute(NS_LITERAL_STRING("zoomAndPan"), error);
-  }
-}
 
-void 
-SVGFragmentIdentifier::SaveOldTransform(SVGSVGElement* root)
-{
-  nsSVGAnimatedTransformList* transformList = root->GetAnimatedTransformList();
-
-  if (transformList && transformList->IsExplicitlySet()) {
-    root->SetTransformProperty(transformList->GetBaseValue());
+  void SetValid() {
+    mValid = true;
   }
-}
 
-void 
-SVGFragmentIdentifier::RestoreOldTransform(SVGSVGElement* root)
-{
-  const SVGTransformList* oldTransformPtr = root->GetTransformProperty();
-  if (oldTransformPtr) {
-    root->GetAnimatedTransformList(nsSVGElement::DO_ALLOCATE)->SetBaseValue(*oldTransformPtr);
-  } else {
-    nsSVGAnimatedTransformList* transformList = root->GetAnimatedTransformList();
-    if (transformList && transformList->IsExplicitlySet()) {
-      ErrorResult error;
-      root->RemoveAttribute(NS_LITERAL_STRING("transform"), error);
-    }
-  }
-}
+private:
+  SVGSVGElement*     mRoot;
+  nsAutoPtr<SVGView> mSVGView;
+  bool               mValid;
+  bool               mWasOverridden;
+  MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
+};
 
 bool
 SVGFragmentIdentifier::ProcessSVGViewSpec(const nsAString& aViewSpec,
-                                          SVGSVGElement* root)
+                                          SVGSVGElement* aRoot)
 {
+  AutoSVGViewHandler viewHandler(aRoot);
+
   if (!IsMatchingParameter(aViewSpec, NS_LITERAL_STRING("svgView"))) {
     return false;
   }
 
-  // SVGViewAttributes may occur in any order, but each type may only occur
-  // at most one time in a correctly formed SVGViewSpec.
-  // If we encounter any attribute more than once or get any syntax errors
-  // we're going to return false and cancel any changes.
-  
-  bool viewBoxFound = false;
-  bool preserveAspectRatioFound = false;
-  bool transformFound = false;
-  bool zoomAndPanFound = false;
-
   // Each token is a SVGViewAttribute
   int32_t bracketPos = aViewSpec.FindChar('(');
   uint32_t lengthOfViewSpec = aViewSpec.Length() - bracketPos - 2;
   nsCharSeparatedTokenizerTemplate<IgnoreWhitespace> tokenizer(
     Substring(aViewSpec, bracketPos + 1, lengthOfViewSpec), ';');
 
   if (!tokenizer.hasMoreTokens()) {
     return false;
   }
+  viewHandler.CreateSVGView();
+
   do {
 
     nsAutoString token(tokenizer.nextToken());
 
     bracketPos = token.FindChar('(');
     if (bracketPos < 1 || token.Last() != ')') {
       // invalid SVGViewAttribute syntax
       return false;
     }
 
     const nsAString &params =
       Substring(token, bracketPos + 1, token.Length() - bracketPos - 2);
 
-    if (IsMatchingParameter(token, NS_LITERAL_STRING("viewBox"))) {
-      if (viewBoxFound ||
-          NS_FAILED(root->mViewBox.SetBaseValueString(
-                      params, root, true))) {
-        return false;
-      }
-      viewBoxFound = true;
-    } else if (IsMatchingParameter(token, NS_LITERAL_STRING("preserveAspectRatio"))) {
-      if (preserveAspectRatioFound ||
-          NS_FAILED(root->mPreserveAspectRatio.SetBaseValueString(
-                      params, root, true))) {
-        return false;
-      }
-      preserveAspectRatioFound = true;
-    } else if (IsMatchingParameter(token, NS_LITERAL_STRING("transform"))) {
-      if (transformFound ||
-          NS_FAILED(root->GetAnimatedTransformList(nsSVGElement::DO_ALLOCATE)->
-                      SetBaseValueString(params))) {
-        return false;
-      }
-      transformFound = true;
-    } else if (IsMatchingParameter(token, NS_LITERAL_STRING("zoomAndPan"))) {
-      if (zoomAndPanFound) {
-        return false;
-      }
-      nsIAtom* valAtom = NS_GetStaticAtom(params);
-      if (!valAtom) {
-        return false;
-      }
-      const nsSVGEnumMapping* mapping = SVGSVGElement::sZoomAndPanMap;
-      while (mapping->mKey) {
-        if (valAtom == *(mapping->mKey)) {
-          // If we've got a valid zoomAndPan value, then set it on our root element.
-          if (NS_FAILED(root->mEnumAttributes[SVGSVGElement::ZOOMANDPAN].SetBaseValue(
-                          mapping->mVal, root))) {
-            return false;
-          }
-          break;
-        }
-        mapping++;
-      }
-      if (!mapping->mKey) {
-          // Unrecognised zoomAndPan value
-          return false;
-      }
-      zoomAndPanFound = true;
-    } else {
-      // We don't support viewTarget currently
+    if (!viewHandler.ProcessAttr(token, params)) {
       return false;
     }
+
   } while (tokenizer.hasMoreTokens());
 
-  if (root->mUseCurrentView) {
-    // A previous SVGViewSpec may have overridden some attributes.
-    // If they are no longer overridden we need to restore the old values.
-    if (!transformFound) {
-      RestoreOldTransform(root);
-    }
-    if (!viewBoxFound) {
-      RestoreOldViewBox(root);
-    }
-    if (!preserveAspectRatioFound) {
-      RestoreOldPreserveAspectRatio(root);
-    }
-    if (!zoomAndPanFound) {
-      RestoreOldZoomAndPan(root);
-    }
-  }
-
+  viewHandler.SetValid();
   return true;
 }
 
 bool
 SVGFragmentIdentifier::ProcessFragmentIdentifier(nsIDocument* aDocument,
                                                  const nsAString& aAnchorName)
 {
   MOZ_ASSERT(aDocument->GetRootElement()->IsSVGElement(nsGkAtoms::svg),
              "expecting an SVG root element");
 
   SVGSVGElement* rootElement =
     static_cast<SVGSVGElement*>(aDocument->GetRootElement());
 
-  if (!rootElement->mUseCurrentView) {
-    SaveOldViewBox(rootElement);
-    SaveOldPreserveAspectRatio(rootElement);
-    SaveOldZoomAndPan(rootElement);
-  }
-
   const SVGViewElement* viewElement = GetViewElement(aDocument, aAnchorName);
 
   if (viewElement) {
     if (!rootElement->mCurrentViewID) {
       rootElement->mCurrentViewID = new nsString();
     }
     *rootElement->mCurrentViewID = aAnchorName;
-    rootElement->mUseCurrentView = true;
+    rootElement->mSVGView = nullptr;
     rootElement->InvalidateTransformNotifyFrame();
     // not an svgView()-style fragment identifier, return false so the caller
     // continues processing to match any :target pseudo elements
     return false;
   }
 
-  bool wasOverridden = !!rootElement->mCurrentViewID;
-  rootElement->mCurrentViewID = nullptr;
-
-  rootElement->mUseCurrentView = ProcessSVGViewSpec(aAnchorName, rootElement);
-  if (rootElement->mUseCurrentView) {
-    return true;
-  }
-  RestoreOldViewBox(rootElement);
-  rootElement->ClearViewBoxProperty();
-  RestoreOldPreserveAspectRatio(rootElement);
-  rootElement->ClearPreserveAspectRatioProperty();
-  RestoreOldZoomAndPan(rootElement);
-  rootElement->ClearZoomAndPanProperty();
-  RestoreOldTransform(rootElement);
-  rootElement->ClearTransformProperty();
-  if (wasOverridden) {
-    rootElement->InvalidateTransformNotifyFrame();
-  }
-  return false;
+  return ProcessSVGViewSpec(aAnchorName, rootElement);
 }
 
 } // namespace mozilla
--- a/dom/svg/SVGFragmentIdentifier.h
+++ b/dom/svg/SVGFragmentIdentifier.h
@@ -37,24 +37,13 @@ public:
                                         const nsAString &aAnchorName);
 
 private:
  /**
   * Parse an SVG ViewSpec and set applicable attributes on the root element.
   * @return true if there is a valid ViewSpec
   */
   static bool ProcessSVGViewSpec(const nsAString &aViewSpec, dom::SVGSVGElement *root);
-
-  // Save and restore things we override in case we want to go back e.g. the
-  // user presses the back button
-  static void SaveOldPreserveAspectRatio(dom::SVGSVGElement *root);
-  static void RestoreOldPreserveAspectRatio(dom::SVGSVGElement *root);
-  static void SaveOldViewBox(dom::SVGSVGElement *root);
-  static void RestoreOldViewBox(dom::SVGSVGElement *root);
-  static void SaveOldZoomAndPan(dom::SVGSVGElement *root);
-  static void RestoreOldZoomAndPan(dom::SVGSVGElement *root);
-  static void SaveOldTransform(dom::SVGSVGElement *root);
-  static void RestoreOldTransform(dom::SVGSVGElement *root);
 };
 
 } // namespace mozilla
 
 #endif // MOZILLA_SVGFRAGMENTIDENTIFIER_H__
--- a/dom/svg/SVGSVGElement.cpp
+++ b/dom/svg/SVGSVGElement.cpp
@@ -106,16 +106,24 @@ DOMSVGTranslatePoint::MatrixTransform(SV
   float d = matrix.D(), e = matrix.E(), f = matrix.F();
   float x = mPt.GetX();
   float y = mPt.GetY();
 
   nsCOMPtr<nsISVGPoint> point = new DOMSVGPoint(a*x + c*y + e, b*x + d*y + f);
   return point.forget();
 }
 
+SVGView::SVGView()
+{
+  mZoomAndPan.Init(SVGSVGElement::ZOOMANDPAN,
+                   SVG_ZOOMANDPAN_MAGNIFY);
+  mViewBox.Init();
+  mPreserveAspectRatio.Init();
+}
+
 nsSVGElement::LengthInfo SVGSVGElement::sLengthInfo[4] =
 {
   { &nsGkAtoms::x, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::X },
   { &nsGkAtoms::y, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::Y },
   { &nsGkAtoms::width, 100, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::X },
   { &nsGkAtoms::height, 100, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::Y },
 };
 
@@ -171,18 +179,17 @@ SVGSVGElement::SVGSVGElement(already_Add
     mCurrentScale(1.0f),
     mPreviousTranslate(0.0f, 0.0f),
     mPreviousScale(1.0f),
     mStartAnimationOnBindToTree(aFromParser == NOT_FROM_PARSER ||
                                 aFromParser == FROM_PARSER_FRAGMENT ||
                                 aFromParser == FROM_PARSER_XSLT),
     mImageNeedsTransformInvalidation(false),
     mIsPaintingSVGImageElement(false),
-    mHasChildrenOnlyTransform(false),
-    mUseCurrentView(false)
+    mHasChildrenOnlyTransform(false)
 {
 }
 
 //----------------------------------------------------------------------
 // nsIDOMNode methods
 
 // From NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGSVGElement)
 nsresult
@@ -252,17 +259,17 @@ float
 SVGSVGElement::ScreenPixelToMillimeterY()
 {
   return ScreenPixelToMillimeterX();
 }
 
 bool
 SVGSVGElement::UseCurrentView()
 {
-  return mUseCurrentView;
+  return mSVGView || mCurrentViewID;
 }
 
 float
 SVGSVGElement::CurrentScale()
 {
   return mCurrentScale;
 }
 
@@ -447,22 +454,16 @@ already_AddRefed<DOMSVGAnimatedPreserveA
 SVGSVGElement::PreserveAspectRatio()
 {
   return mPreserveAspectRatio.ToDOMAnimatedPreserveAspectRatio(this);
 }
 
 uint16_t
 SVGSVGElement::ZoomAndPan()
 {
-  SVGViewElement* viewElement = GetCurrentViewElement();
-  if (viewElement && viewElement->mEnumAttributes[
-                       SVGViewElement::ZOOMANDPAN].IsExplicitlySet()) {
-    return viewElement->mEnumAttributes[
-             SVGViewElement::ZOOMANDPAN].GetAnimValue();
-  }
   return mEnumAttributes[ZOOMANDPAN].GetAnimValue();
 }
 
 void
 SVGSVGElement::SetZoomAndPan(uint16_t aZoomAndPan, ErrorResult& rv)
 {
   if (aZoomAndPan == SVG_ZOOMANDPAN_DISABLE ||
       aZoomAndPan == SVG_ZOOMANDPAN_MAGNIFY) {
@@ -836,16 +837,19 @@ nsSVGViewBoxRect
 SVGSVGElement::GetViewBoxWithSynthesis(
   float aViewportWidth, float aViewportHeight) const
 {
   // The logic here should match HasViewBoxRect().
   SVGViewElement* viewElement = GetCurrentViewElement();
   if (viewElement && viewElement->mViewBox.HasRect()) {
     return viewElement->mViewBox.GetAnimValue();
   }
+  if (mSVGView && mSVGView->mViewBox.HasRect()) {
+    return mSVGView->mViewBox.GetAnimValue();
+  }
   if (mViewBox.HasRect()) {
     return mViewBox.GetAnimValue();
   }
 
   if (ShouldSynthesizeViewBox()) {
     // Special case -- fake a viewBox, using height & width attrs.
     // (Use |this| as context, since if we get here, we're outermost <svg>.)
     return nsSVGViewBoxRect(0, 0,
@@ -873,25 +877,29 @@ SVGSVGElement::GetPreserveAspectRatioWit
   }
 
   SVGViewElement* viewElement = GetCurrentViewElement();
 
   // This check is equivalent to "!HasViewBoxRect() && ShouldSynthesizeViewBox()".
   // We're just holding onto the viewElement that HasViewBoxRect() would look up,
   // so that we don't have to look it up again later.
   if (!((viewElement && viewElement->mViewBox.HasRect()) ||
+        (mSVGView && mSVGView->mViewBox.HasRect()) ||
         mViewBox.HasRect()) &&
       ShouldSynthesizeViewBox()) {
     // If we're synthesizing a viewBox, use preserveAspectRatio="none";
     return SVGPreserveAspectRatio(SVG_PRESERVEASPECTRATIO_NONE, SVG_MEETORSLICE_SLICE);
   }
 
   if (viewElement && viewElement->mPreserveAspectRatio.IsExplicitlySet()) {
     return viewElement->mPreserveAspectRatio.GetAnimValue();
   }
+  if (mSVGView && mSVGView->mPreserveAspectRatio.IsExplicitlySet()) {
+    return mSVGView->mPreserveAspectRatio.GetAnimValue();
+  }
   return mPreserveAspectRatio.GetAnimValue();
 }
 
 //----------------------------------------------------------------------
 // SVGSVGElement
 
 float
 SVGSVGElement::GetLength(uint8_t aCtxType)
@@ -899,16 +907,18 @@ SVGSVGElement::GetLength(uint8_t aCtxTyp
   float h, w;
 
   SVGViewElement* viewElement = GetCurrentViewElement();
   const nsSVGViewBoxRect* viewbox = nullptr;
 
   // The logic here should match HasViewBoxRect().
   if (viewElement && viewElement->mViewBox.HasRect()) {
     viewbox = &viewElement->mViewBox.GetAnimValue();
+  } else if (mSVGView && mSVGView->mViewBox.HasRect()) {
+    viewbox = &mSVGView->mViewBox.GetAnimValue();
   } else if (mViewBox.HasRect()) {
     viewbox = &mViewBox.GetAnimValue();
   }
 
   if (viewbox) {
     w = viewbox->width;
     h = viewbox->height;
   } else if (IsInner()) {
@@ -941,19 +951,22 @@ SVGSVGElement::GetLength(uint8_t aCtxTyp
 
 //----------------------------------------------------------------------
 // nsSVGElement methods
 
 /* virtual */ gfxMatrix
 SVGSVGElement::PrependLocalTransformsTo(
   const gfxMatrix &aMatrix, SVGTransformTypes aWhich) const
 {
-  // 'transform' attribute:
+  // 'transform' attribute (or an override from a fragment identifier):
   gfxMatrix fromUserSpace =
-    SVGSVGElementBase::PrependLocalTransformsTo(aMatrix, aWhich);
+    SVGContentUtils::PrependLocalTransformsTo(
+      aMatrix, aWhich, mAnimateMotionTransform,
+      mSVGView && mSVGView->mTransforms ? mSVGView->mTransforms : mTransforms);
+
   if (aWhich == eUserSpaceToParent) {
     return fromUserSpace;
   }
 
   if (IsInner()) {
     float x, y;
     const_cast<SVGSVGElement*>(this)->GetAnimatedLengthValues(&x, &y, nullptr);
     if (aWhich == eAllTransforms) {
@@ -970,16 +983,25 @@ SVGSVGElement::PrependLocalTransformsTo(
     zoomPanTM.Scale(mCurrentScale, mCurrentScale);
     return ThebesMatrix(GetViewBoxTransform()) * zoomPanTM * fromUserSpace;
   }
 
   // outer-<svg>, but inline in some other content:
   return ThebesMatrix(GetViewBoxTransform()) * fromUserSpace;
 }
 
+nsSVGAnimatedTransformList*
+SVGSVGElement::GetAnimatedTransformList(uint32_t aFlags)
+{
+  if (!(aFlags & DO_ALLOCATE) && mSVGView && mSVGView->mTransforms) {
+    return mSVGView->mTransforms;
+  }
+  return SVGSVGElementBase::GetAnimatedTransformList(aFlags);
+}
+
 /* virtual */ bool
 SVGSVGElement::HasValidDimensions() const
 {
   return !IsInner() ||
     ((!mLengthAttributes[ATTR_WIDTH].IsExplicitlySet() ||
        mLengthAttributes[ATTR_WIDTH].GetAnimValInSpecifiedUnits() > 0) &&
      (!mLengthAttributes[ATTR_HEIGHT].IsExplicitlySet() ||
        mLengthAttributes[ATTR_HEIGHT].GetAnimValInSpecifiedUnits() > 0));
@@ -1010,17 +1032,18 @@ SVGSVGElement::GetPreserveAspectRatio()
 {
   return &mPreserveAspectRatio;
 }
 
 bool
 SVGSVGElement::HasViewBoxRect() const
 {
   SVGViewElement* viewElement = GetCurrentViewElement();
-  if (viewElement && viewElement->mViewBox.HasRect()) {
+  if ((viewElement && viewElement->mViewBox.HasRect()) ||
+      (mSVGView && mSVGView->mViewBox.HasRect())) {
     return true;
   }
   return mViewBox.HasRect();
 }
 
 bool
 SVGSVGElement::ShouldSynthesizeViewBox() const
 {
@@ -1131,116 +1154,16 @@ SVGSVGElement::FlushImageTransformInvali
              "Should only be called on image documents");
 
   if (mImageNeedsTransformInvalidation) {
     InvalidateTransformNotifyFrame();
     mImageNeedsTransformInvalidation = false;
   }
 }
 
-bool
-SVGSVGElement::SetViewBoxProperty(const nsSVGViewBoxRect& aViewBox)
-{
-  nsSVGViewBoxRect* pViewBoxOverridePtr = new nsSVGViewBoxRect(aViewBox);
-  nsresult rv = SetProperty(nsGkAtoms::viewBox,
-                            pViewBoxOverridePtr,
-                            nsINode::DeleteProperty<nsSVGViewBoxRect>,
-                            true);
-  MOZ_ASSERT(rv != NS_PROPTABLE_PROP_OVERWRITTEN,
-             "Setting override value when it's already set...?");
-
-  if (MOZ_UNLIKELY(NS_FAILED(rv))) {
-    // property-insertion failed (e.g. OOM in property-table code)
-    delete pViewBoxOverridePtr;
-    return false;
-  }
-  return true;
-}
-
-const nsSVGViewBoxRect*
-SVGSVGElement::GetViewBoxProperty() const
-{
-  void* valPtr = GetProperty(nsGkAtoms::viewBox);
-  if (valPtr) {
-    return static_cast<nsSVGViewBoxRect*>(valPtr);
-  }
-  return nullptr;
-}
-
-bool
-SVGSVGElement::ClearViewBoxProperty()
-{
-  void* valPtr = UnsetProperty(nsGkAtoms::viewBox);
-  delete static_cast<nsSVGViewBoxRect*>(valPtr);
-  return valPtr;
-}
-
-bool
-SVGSVGElement::SetZoomAndPanProperty(uint16_t aValue)
-{
-  nsresult rv = SetProperty(nsGkAtoms::zoomAndPan,
-                            reinterpret_cast<void*>(aValue),
-                            nullptr, true);
-  MOZ_ASSERT(rv != NS_PROPTABLE_PROP_OVERWRITTEN,
-             "Setting override value when it's already set...?");
-
-  return NS_SUCCEEDED(rv);
-}
-
-uint16_t
-SVGSVGElement::GetZoomAndPanProperty() const
-{
-  void* valPtr = GetProperty(nsGkAtoms::zoomAndPan);
-  if (valPtr) {
-    return reinterpret_cast<uintptr_t>(valPtr);
-  }
-  return SVG_ZOOMANDPAN_UNKNOWN;
-}
-
-bool
-SVGSVGElement::ClearZoomAndPanProperty()
-{
-  return UnsetProperty(nsGkAtoms::zoomAndPan);
-}
-
-bool
-SVGSVGElement::SetTransformProperty(const SVGTransformList& aTransform)
-{
-  SVGTransformList* pTransformOverridePtr = new SVGTransformList(aTransform);
-  nsresult rv = SetProperty(nsGkAtoms::transform,
-                            pTransformOverridePtr,
-                            nsINode::DeleteProperty<SVGTransformList>,
-                            true);
-  MOZ_ASSERT(rv != NS_PROPTABLE_PROP_OVERWRITTEN,
-             "Setting override value when it's already set...?");
-
-  if (MOZ_UNLIKELY(NS_FAILED(rv))) {
-    // property-insertion failed (e.g. OOM in property-table code)
-    delete pTransformOverridePtr;
-    return false;
-  }
-  return true;
-}
-
-const SVGTransformList*
-SVGSVGElement::GetTransformProperty() const
-{
-  void* valPtr = GetProperty(nsGkAtoms::transform);
-  if (valPtr) {
-    return static_cast<SVGTransformList*>(valPtr);
-  }
-  return nullptr;
-}
-
-bool
-SVGSVGElement::ClearTransformProperty()
-{
-  return UnsetProperty(nsGkAtoms::transform);
-}
-
 int32_t
 SVGSVGElement::GetIntrinsicWidth()
 {
   if (mLengthAttributes[ATTR_WIDTH].IsPercentage()) {
     return -1;
   }
   // Passing |this| as a SVGSVGElement* invokes the variant of GetAnimValue
   // that uses the passed argument as the context, but that's fine since we
--- a/dom/svg/SVGSVGElement.h
+++ b/dom/svg/SVGSVGElement.h
@@ -28,16 +28,17 @@ class nsSVGInnerSVGFrame;
 
 namespace mozilla {
 class AutoSVGRenderingState;
 class DOMSVGAnimatedPreserveAspectRatio;
 class DOMSVGLength;
 class DOMSVGNumber;
 class EventChainPreVisitor;
 class SVGFragmentIdentifier;
+class AutoSVGViewHandler;
 
 namespace dom {
 class SVGAngle;
 class SVGAnimatedRect;
 class SVGMatrix;
 class SVGTransform;
 class SVGViewElement;
 class SVGIRect;
@@ -80,23 +81,39 @@ public:
   {}
   bool operator!=(const svgFloatSize& rhs) {
     return width != rhs.width || height != rhs.height;
   }
   float width;
   float height;
 };
 
+// Stores svgView arguments of SVG fragment identifiers.
+class SVGView {
+  friend class mozilla::AutoSVGViewHandler;
+  friend class mozilla::dom::SVGSVGElement;
+public:
+  SVGView();
+
+private:
+  nsSVGEnum                             mZoomAndPan;
+  nsSVGViewBox                          mViewBox;
+  SVGAnimatedPreserveAspectRatio        mPreserveAspectRatio;
+  nsAutoPtr<nsSVGAnimatedTransformList> mTransforms;
+};
+
 typedef SVGGraphicsElement SVGSVGElementBase;
 
 class SVGSVGElement final : public SVGSVGElementBase
 {
   friend class ::nsSVGOuterSVGFrame;
   friend class ::nsSVGInnerSVGFrame;
+  friend class mozilla::dom::SVGView;
   friend class mozilla::SVGFragmentIdentifier;
+  friend class mozilla::AutoSVGViewHandler;
   friend class mozilla::AutoSVGRenderingState;
 
   SVGSVGElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
                 FromParser aFromParser);
   virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   friend nsresult (::NS_NewSVGSVGElement(nsIContent **aResult,
                                          already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
@@ -136,16 +153,18 @@ public:
   virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) override;
 
   virtual bool IsEventAttributeName(nsIAtom* aName) override;
 
   // nsSVGElement specializations:
   virtual gfxMatrix PrependLocalTransformsTo(
     const gfxMatrix &aMatrix,
     SVGTransformTypes aWhich = eAllTransforms) const override;
+  virtual nsSVGAnimatedTransformList*
+	  GetAnimatedTransformList(uint32_t aFlags = 0) override;
   virtual bool HasValidDimensions() const override;
 
   // SVGSVGElement methods:
   float GetLength(uint8_t mCtxType);
 
   // public helpers:
 
   /**
@@ -281,29 +300,21 @@ private:
   SVGViewElement* GetCurrentViewElement() const;
 
   // Methods for <image> elements to override my "PreserveAspectRatio" value.
   // These are private so that only our friends (AutoSVGRenderingState in
   // particular) have access.
   void SetImageOverridePreserveAspectRatio(const SVGPreserveAspectRatio& aPAR);
   void ClearImageOverridePreserveAspectRatio();
 
-  // Set/Clear properties to hold old or override versions of attributes
+  // Set/Clear properties to hold old version of preserveAspectRatio
+  // when it's being overridden by an <image> element that we are inside of.
   bool SetPreserveAspectRatioProperty(const SVGPreserveAspectRatio& aPAR);
   const SVGPreserveAspectRatio* GetPreserveAspectRatioProperty() const;
   bool ClearPreserveAspectRatioProperty();
-  bool SetViewBoxProperty(const nsSVGViewBoxRect& aViewBox);
-  const nsSVGViewBoxRect* GetViewBoxProperty() const;
-  bool ClearViewBoxProperty();
-  bool SetZoomAndPanProperty(uint16_t aValue);
-  uint16_t GetZoomAndPanProperty() const;
-  bool ClearZoomAndPanProperty();
-  bool SetTransformProperty(const SVGTransformList& aValue);
-  const SVGTransformList* GetTransformProperty() const;
-  bool ClearTransformProperty();
 
   bool IsRoot() const {
     NS_ASSERTION((IsInDoc() && !GetParent()) ==
                  (OwnerDoc() && (OwnerDoc()->GetRootElement() == this)),
                  "Can't determine if we're root");
     return IsInDoc() && !GetParent();
   }
 
@@ -364,17 +375,20 @@ private:
   static EnumInfo sEnumInfo[1];
 
   virtual nsSVGViewBox *GetViewBox() override;
   virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio() override;
 
   nsSVGViewBox                   mViewBox;
   SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
 
+  // mCurrentViewID and mSVGView are mutually exclusive; we can have
+  // at most one non-null.
   nsAutoPtr<nsString>            mCurrentViewID;
+  nsAutoPtr<SVGView>             mSVGView;
 
   // The size of the rectangular SVG viewport into which we render. This is
   // not (necessarily) the same as the content area. See:
   //
   //   http://www.w3.org/TR/SVG11/coords.html#ViewportSpace
   //
   // XXXjwatt Currently only used for outer <svg>, but maybe we could use -1 to
   // flag this as an inner <svg> to save the overhead of GetCtx calls?
@@ -396,17 +410,16 @@ private:
   // For outermost <svg> elements created from parsing, animation is started by
   // the onload event in accordance with the SVG spec, but for <svg> elements
   // created by script or promoted from inner <svg> to outermost <svg> we need
   // to manually kick off animation when they are bound to the tree.
   bool     mStartAnimationOnBindToTree;
   bool     mImageNeedsTransformInvalidation;
   bool     mIsPaintingSVGImageElement;
   bool     mHasChildrenOnlyTransform;
-  bool     mUseCurrentView;
 };
 
 } // namespace dom
 
 // Helper class to automatically manage temporary changes to an SVG document's
 // state for rendering purposes.
 class MOZ_RAII AutoSVGRenderingState
 {
--- a/dom/svg/test/test_fragments.html
+++ b/dom/svg/test/test_fragments.html
@@ -19,73 +19,98 @@ https://bugzilla.mozilla.org/show_bug.cg
 <script class="testbody" type="application/javascript">
 SimpleTest.waitForExplicitFinish();
 
 function Test(svgFragmentIdentifier, valid, viewBoxString,
               preserveAspectRatioString, zoomAndPanString)
 {
     this.svgFragmentIdentifier = svgFragmentIdentifier;
     this.valid = valid;
-    this.viewBoxString = viewBoxString;
-    this.preserveAspectRatioString = preserveAspectRatioString;
-    this.zoomAndPanString = zoomAndPanString;
 }
 
 function runTests()
 {
   var svg = $("svg");
   var doc = svg.contentWindow.document;
-  
+  var rootElement = doc.rootElement;
+
   var tests = [
-      new Test("unknown", false, null, null, null),
-      new Test("svgView(viewBox(0,0,200,200))", true, "0 0 200 200", null, null),
-      new Test("svgView(preserveAspectRatio(xMaxYMin slice))", true, null, "xMaxYMin slice", null),
-      new Test("svgView(viewBox(1,2,3,4);preserveAspectRatio(xMinYMax))", true, "1 2 3 4", "xMinYMax meet", null),
-      new Test("svgView(viewBox(none))", true, "none", null, null),
-      new Test("svgView(zoomAndPan(disable))", true, null, null, "disable"),
-      new Test("svgView(transform(translate(-10,-20) scale(2) rotate(45) translate(5,10)))", true, null, null, null),
+      new Test("unknown", false),
+      new Test("svgView(viewBox(0,0,200,200))", true),
+      new Test("svgView(preserveAspectRatio(xMaxYMin slice))", true),
+      new Test("svgView(viewBox(1,2,3,4);preserveAspectRatio(xMinYMax))", true),
+      new Test("svgView(viewBox(none))", true),
+      new Test("svgView(zoomAndPan(disable))", true),
+      new Test("svgView(transform(translate(-10,-20) scale(2) rotate(45) translate(5,10)))", true),
       // No duplicates allowed
-      new Test("svgView(zoomAndPan(disable);zoomAndPan(disable))", false, null, null, null),
-      new Test("svgView(viewBox(0,0,200,200);viewBox(0,0,200,200))", false, null, null, null),
-      new Test("svgView(preserveAspectRatio(xMaxYMin);preserveAspectRatio(xMaxYMin))", false, null, null, null),
-      new Test("svgView(transform(translate(0,200));transform(translate(0,200)))", false, null, null, null),
+      new Test("svgView(zoomAndPan(disable);zoomAndPan(disable))", false),
+      new Test("svgView(viewBox(0,0,200,200);viewBox(0,0,200,200))", false),
+      new Test("svgView(preserveAspectRatio(xMaxYMin);preserveAspectRatio(xMaxYMin))", false),
+      new Test("svgView(transform(translate(0,200));transform(translate(0,200)))", false),
       // No invalid values allowed
-      new Test("svgView(viewBox(bad)", false, null, null, null),
-      new Test("svgView(preserveAspectRatio(bad))", false, null, null, null),
-      new Test("svgView(zoomAndPan(bad))", false, null, null, null),
-      new Test("svgView(transform(bad))", false, null, null, null),
-      new Test("svgView", false, null, null, null),
-      new Test("svgView(", false, null, null, null),
-      new Test("svgView()", false, null, null, null),
+      new Test("svgView(viewBox(bad)", false),
+      new Test("svgView(preserveAspectRatio(bad))", false),
+      new Test("svgView(zoomAndPan(bad))", false),
+      new Test("svgView(transform(bad))", false),
+      new Test("svgView", false),
+      new Test("svgView(", false),
+      new Test("svgView()", false),
       // Be sure we verify that there's a closing paren for svgView()
       // (and not too many closing parens)
-      new Test("svgView(zoomAndPan(disable)", false, null, null, null),
-      new Test("svgView(zoomAndPan(disable) ", false, null, null, null),
-      new Test("svgView(zoomAndPan(disable)]", false, null, null, null),
-      new Test("svgView(zoomAndPan(disable)))", false, null, null, null)
+      new Test("svgView(zoomAndPan(disable)", false),
+      new Test("svgView(zoomAndPan(disable) ", false),
+      new Test("svgView(zoomAndPan(disable)]", false),
+      new Test("svgView(zoomAndPan(disable)))", false)
   ];
 
   var src = svg.getAttribute("src");
-  for (var i = 0; i < tests.length; i++) {
-    var test = tests[i];
-    svg.setAttribute("src", src + "#" + test.svgFragmentIdentifier);
-    is(doc.rootElement.useCurrentView, test.valid,
-       "Expected " + test.svgFragmentIdentifier + " to be " +
-       (test.valid ? "valid" : "invalid"));
+
+  is(false, rootElement.hasAttribute("viewBox"),
+     "expecting to start without a viewBox set");
+  is(false, rootElement.hasAttribute("preserveAspectRatio"),
+     "expecting to start without preserveAspectRatio set");
+  is(false, rootElement.hasAttribute("zoomAndPan"),
+     "expecting to start without zoomAndPan set");
+
+  for (var j = 0; j < 2; j++) {
+    var initialViewBox = rootElement.getAttribute("viewBox");
+    var initialPreserveAspectRatio =
+      rootElement.getAttribute("preserveAspectRatio");
+    var initialZoomAndPan = rootElement.getAttribute("zoomAndPan");
+    var initialTransform = rootElement.getAttribute("transform");
 
-    is(doc.rootElement.getAttribute("viewBox"),
-       test.viewBoxString, "unexpected viewBox");
+    for (var i = 0; i < tests.length; i++) {
+      var test = tests[i];
+      svg.setAttribute("src", src + "#" + test.svgFragmentIdentifier);
+      is(rootElement.useCurrentView, test.valid,
+         "Expected " + test.svgFragmentIdentifier + " to be " +
+         (test.valid ? "valid" : "invalid"));
+
+      // check that assigning a viewSpec does not modify the underlying
+      // attribute values.
+      is(rootElement.getAttribute("viewBox"),
+         initialViewBox, "unexpected viewBox");
 
-    is(doc.rootElement.getAttribute("preserveAspectRatio"),
-       test.preserveAspectRatioString, "unexpected preserveAspectRatio");
+      is(rootElement.getAttribute("preserveAspectRatio"),
+         initialPreserveAspectRatio, "unexpected preserveAspectRatio");
+
+      is(rootElement.getAttribute("zoomAndPan"),
+         initialZoomAndPan, "unexpected zoomAndPan");
 
-    is(doc.rootElement.getAttribute("zoomAndPan"),
-       test.zoomAndPanString, "unexpected zoomAndPan");
+      is(rootElement.getAttribute("transform"),
+         initialTransform, "unexpected transform");
+    }
+
+    // repeat tests with underlying attributes set to values
+    rootElement.setAttribute("viewBox", "0 0 100 100");
+    rootElement.setAttribute("preserveAspectRatio", "none");
+    rootElement.setAttribute("zoomAndPan", "disable");
+    rootElement.setAttribute("transform", "translate(10,10)");
   }
 
   SimpleTest.finish();
 }
 
-window.addEventListener("load", runTests, false);
+$(svg).addEventListener("load", runTests, false);
 </script>
 </pre>
 </body>
 </html>
--- a/dom/system/gonk/AudioManager.cpp
+++ b/dom/system/gonk/AudioManager.cpp
@@ -1282,19 +1282,17 @@ AudioManager::SelectDeviceFromDevices(ui
       device = AUDIO_DEVICE_OUT_SPDIF;
     } else if ((device & AUDIO_DEVICE_OUT_AUX_LINE) != 0) {
        device = AUDIO_DEVICE_OUT_AUX_LINE;
 #endif
     } else {
        device &= AUDIO_DEVICE_OUT_ALL_A2DP;
     }
   }
-#if ANDROID_VERSION >= 17
   MOZ_ASSERT(audio_is_output_device(device));
-#endif
   return device;
 }
 AudioManager::VolumeStreamState::VolumeStreamState(AudioManager& aManager,
                                                    int32_t aStreamType)
   : mManager(aManager)
   , mStreamType(aStreamType)
   , mLastDevices(0)
   , mIsDevicesChanged(true)
--- a/dom/system/gonk/android_audio/AudioSystem.h
+++ b/dom/system/gonk/android_audio/AudioSystem.h
@@ -542,26 +542,31 @@ enum {
     AUDIO_DEVICE_IN_ALL_SCO = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
     AUDIO_DEVICE_IN_ALL_USB = (AUDIO_DEVICE_IN_USB_ACCESSORY |
                                AUDIO_DEVICE_IN_USB_DEVICE),
 };
 
 typedef uint32_t audio_devices_t;
 #endif
 
-#if ANDROID_VERSION >= 17
-static inline bool audio_is_output_device(audio_devices_t device)
+static inline bool audio_is_output_device(uint32_t device)
 {
+#if ANDROID_VERSION < 17
+    if ((__builtin_popcount(device) == 1) && ((device & ~AUDIO_DEVICE_OUT_ALL) == 0))
+        return true;
+    else
+        return false;
+#else
     if (((device & AUDIO_DEVICE_BIT_IN) == 0) &&
             (__builtin_popcount(device) == 1) && ((device & ~AUDIO_DEVICE_OUT_ALL) == 0))
         return true;
     else
         return false;
+#endif
 }
-#endif
 
 /* device connection states used for audio_policy->set_device_connection_state()
  *  */
 typedef enum {
     AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
     AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
 
     AUDIO_POLICY_DEVICE_STATE_CNT,
--- a/gfx/thebes/gfxWindowsNativeDrawing.cpp
+++ b/gfx/thebes/gfxWindowsNativeDrawing.cpp
@@ -7,16 +7,17 @@
 
 #include "nsMathUtils.h"
 
 #include "gfxWindowsNativeDrawing.h"
 #include "gfxWindowsSurface.h"
 #include "gfxAlphaRecovery.h"
 #include "gfxPattern.h"
 #include "mozilla/gfx/2D.h"
+#include "mozilla/gfx/Helpers.h"
 #include "gfx2DGlue.h"
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 
 enum {
     RENDER_STATE_INIT,
 
@@ -247,36 +248,32 @@ gfxWindowsNativeDrawing::PaintToContext(
             NS_ERROR("Alpha recovery failure");
             return;
         }
         RefPtr<DataSourceSurface> source =
             Factory::CreateWrappingDataSourceSurface(black->Data(),
                                                      black->Stride(),
                                                      black->GetSize(),
                                                      SurfaceFormat::B8G8R8A8);
+        {
+            DrawTarget* dt = mContext->GetDrawTarget();
+            AutoRestoreTransform autoRestoreTransform(dt);
 
-        mContext->Save();
-        mContext->SetMatrix(
-          mContext->CurrentMatrix().Translate(mNativeRect.TopLeft()));
-        mContext->NewPath();
-        mContext->Rectangle(gfxRect(gfxPoint(0.0, 0.0), mNativeRect.Size()));
-
-        RefPtr<gfxPattern> pat = new gfxPattern(source, Matrix());
+            Matrix newTransform = dt->GetTransform();
+            newTransform.PreTranslate(ToPoint(mNativeRect.TopLeft()));
+            dt->SetTransform(newTransform);
 
-        gfxMatrix m;
-        m.Scale(mScale.width, mScale.height);
-        pat->SetMatrix(m);
-
-        if (mNativeDrawFlags & DO_NEAREST_NEIGHBOR_FILTERING)
-            pat->SetFilter(Filter::LINEAR);
-
-        pat->SetExtend(ExtendMode::CLAMP);
-        mContext->SetPattern(pat);
-        mContext->Fill();
-        mContext->Restore();
+            Rect rect(Point(0.0, 0.0), ToSize(mNativeRect.Size()));
+            Matrix m = Matrix::Scaling(1.0 / mScale.width, 1.0 / mScale.height);
+            Filter filter = (mNativeDrawFlags & DO_NEAREST_NEIGHBOR_FILTERING)
+                          ? Filter::LINEAR
+                          : Filter::GOOD;
+            SurfacePattern pat(source, ExtendMode::CLAMP, m, filter);
+            dt->FillRect(rect, pat);
+        }
 
         mRenderState = RENDER_STATE_DONE;
     } else {
         NS_ERROR("Invalid RenderState in gfxWindowsNativeDrawing::PaintToContext");
     }
 }
 
 void
--- a/js/src/jit-test/tests/gc/bug-1226888.js
+++ b/js/src/jit-test/tests/gc/bug-1226888.js
@@ -1,8 +1,11 @@
+if (!this.hasOwnProperty("TypedObject"))
+  quit();
+
 setJitCompilerOption('ion.forceinlineCaches', 1);
 // Adapted from randomly chosen test: js/src/jit-test/tests/TypedObject/jit-write-references.js
 with({}) {}
 v = new new TypedObject.StructType({
     f: TypedObject.Any
 })
 gc();
 function g() {
--- a/js/src/jsapi-tests/testTypedArrays.cpp
+++ b/js/src/jsapi-tests/testTypedArrays.cpp
@@ -48,26 +48,28 @@ BEGIN_TEST(testTypedArrays)
         TestArrayFromBuffer<JS_NewUint8ClampedArrayWithBuffer, JS_NewUint8ClampedArrayFromArray, uint8_t, false, JS_GetUint8ClampedArrayData>(cx) &&
         TestArrayFromBuffer<JS_NewInt16ArrayWithBuffer, JS_NewInt16ArrayFromArray, int16_t, false, JS_GetInt16ArrayData>(cx) &&
         TestArrayFromBuffer<JS_NewUint16ArrayWithBuffer, JS_NewUint16ArrayFromArray, uint16_t, false, JS_GetUint16ArrayData>(cx) &&
         TestArrayFromBuffer<JS_NewInt32ArrayWithBuffer, JS_NewInt32ArrayFromArray, int32_t, false, JS_GetInt32ArrayData>(cx) &&
         TestArrayFromBuffer<JS_NewUint32ArrayWithBuffer, JS_NewUint32ArrayFromArray, uint32_t, false, JS_GetUint32ArrayData>(cx) &&
         TestArrayFromBuffer<JS_NewFloat32ArrayWithBuffer, JS_NewFloat32ArrayFromArray, float, false, JS_GetFloat32ArrayData>(cx) &&
         TestArrayFromBuffer<JS_NewFloat64ArrayWithBuffer, JS_NewFloat64ArrayFromArray, double, false, JS_GetFloat64ArrayData>(cx);
 
+#ifdef ENABLE_SHARED_ARRAY_BUFFER
     ok = ok &&
         TestArrayFromBuffer<JS_NewInt8ArrayWithBuffer, JS_NewInt8ArrayFromArray, int8_t, true, JS_GetInt8ArrayData>(cx) &&
         TestArrayFromBuffer<JS_NewUint8ArrayWithBuffer, JS_NewUint8ArrayFromArray, uint8_t, true, JS_GetUint8ArrayData>(cx) &&
         TestArrayFromBuffer<JS_NewUint8ClampedArrayWithBuffer, JS_NewUint8ClampedArrayFromArray, uint8_t, true, JS_GetUint8ClampedArrayData>(cx) &&
         TestArrayFromBuffer<JS_NewInt16ArrayWithBuffer, JS_NewInt16ArrayFromArray, int16_t, true, JS_GetInt16ArrayData>(cx) &&
         TestArrayFromBuffer<JS_NewUint16ArrayWithBuffer, JS_NewUint16ArrayFromArray, uint16_t, true, JS_GetUint16ArrayData>(cx) &&
         TestArrayFromBuffer<JS_NewInt32ArrayWithBuffer, JS_NewInt32ArrayFromArray, int32_t, true, JS_GetInt32ArrayData>(cx) &&
         TestArrayFromBuffer<JS_NewUint32ArrayWithBuffer, JS_NewUint32ArrayFromArray, uint32_t, true, JS_GetUint32ArrayData>(cx) &&
         TestArrayFromBuffer<JS_NewFloat32ArrayWithBuffer, JS_NewFloat32ArrayFromArray, float, true, JS_GetFloat32ArrayData>(cx) &&
         TestArrayFromBuffer<JS_NewFloat64ArrayWithBuffer, JS_NewFloat64ArrayFromArray, double, true, JS_GetFloat64ArrayData>(cx);
+#endif // ENABLE_SHARED_ARRAY_BUFFER
 
     return ok;
 }
 
 // Shared memory can only be mapped by a TypedArray by creating the
 // TypedArray with a SharedArrayBuffer explicitly, so no tests here.
 
 template<JSObject* Create(JSContext*, uint32_t),
--- a/js/src/tests/js1_8_5/extensions/sharedtypedarray.js
+++ b/js/src/tests/js1_8_5/extensions/sharedtypedarray.js
@@ -7,18 +7,20 @@
 
 // Minimal test cases.  Note that on 64-bit a SharedArrayBuffer is
 // very expensive under these rules - a 4GB area is reserved for it.
 // So don't go allocating a ton of them.
 //
 // These tests cannot test that sharing works across workers.  There
 // are or will be tests, in dom/workers, that do that.
 
-if (!this.SharedArrayBuffer)
+if (!this.SharedArrayBuffer) {
+    reportCompare(true,true);
     quit(0);
+}
 
 var b;
 
 function testSharedArrayBuffer() {
     b = new SharedArrayBuffer("4096"); // Test string conversion, too
     assertEq(b instanceof SharedArrayBuffer, true);
     assertEq(b.byteLength, 4096);
 
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -5719,18 +5719,24 @@ nsRuleNode::ComputeDisplayData(void* aSt
   SetDiscrete(*aRuleData->ValueForPosition(), display->mPosition, conditions,
               SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL,
               parentDisplay->mPosition,
               NS_STYLE_POSITION_STATIC, 0, 0, 0, 0);
   // If an element is put in the top layer, while it is not absolutely
   // positioned, the position value should be computed to 'absolute' per
   // the Fullscreen API spec.
   if (display->mTopLayer != NS_STYLE_TOP_LAYER_NONE &&
-      !display->IsAbsolutelyPositionedStyle()) {
-    display->mPosition = NS_STYLE_POSITION_ABSOLUTE;
+      // XXX We currently only support fixed top layer element. But per
+      // spec it should check IsAbsolutelyPositionedStyle() instead.
+      // This should be fixed as soon as we support <dialog> element
+      // in bug 840640. We have to restrict it now because addons may
+      // mess with UA-only styles and cause crashes. See bug 1230508.
+      display->mPosition != NS_STYLE_POSITION_FIXED) {
+    // XXX And we should set other values to absolute instead of fixed.
+    display->mPosition = NS_STYLE_POSITION_FIXED;
     // We cannot cache this struct because otherwise it may be used as
     // an aStartStruct for some other elements.
     conditions.SetUncacheable();
   }
 
   // clear: enum, inherit, initial
   SetDiscrete(*aRuleData->ValueForClear(), display->mBreakType, conditions,
               SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL,
--- a/layout/svg/nsFilterInstance.cpp
+++ b/layout/svg/nsFilterInstance.cpp
@@ -53,30 +53,30 @@ UserSpaceMetricsForFrame(nsIFrame* aFram
     nsSVGElement* element = static_cast<nsSVGElement*>(aFrame->GetContent());
     return MakeUnique<SVGElementMetrics>(element);
   }
   return MakeUnique<NonSVGFrameUserSpaceMetrics>(aFrame);
 }
 
 nsresult
 nsFilterInstance::PaintFilteredFrame(nsIFrame *aFilteredFrame,
-                                     gfxContext& aContext,
+                                     DrawTarget* aDrawTarget,
                                      const gfxMatrix& aTransform,
                                      nsSVGFilterPaintCallback *aPaintCallback,
                                      const nsRegion *aDirtyArea)
 {
   auto& filterChain = aFilteredFrame->StyleSVGReset()->mFilters;
   UniquePtr<UserSpaceMetrics> metrics = UserSpaceMetricsForFrame(aFilteredFrame);
   nsFilterInstance instance(aFilteredFrame, aFilteredFrame->GetContent(), *metrics,
                             filterChain, aPaintCallback, aTransform,
                             aDirtyArea, nullptr, nullptr, nullptr);
   if (!instance.IsInitialized()) {
     return NS_OK;
   }
-  return instance.Render(&aContext);
+  return instance.Render(aDrawTarget);
 }
 
 nsRegion
 nsFilterInstance::GetPostFilterDirtyArea(nsIFrame *aFilteredFrame,
                                          const nsRegion& aPreFilterDirtyRegion)
 {
   if (aPreFilterDirtyRegion.IsEmpty()) {
     return nsRegion();
@@ -452,44 +452,44 @@ nsFilterInstance::BuildSourceImage(DrawT
 
   mSourceGraphic.mSourceSurface = offscreenDT->Snapshot();
   mSourceGraphic.mSurfaceRect = neededRect;
 
   return NS_OK;
 }
 
 nsresult
-nsFilterInstance::Render(gfxContext* aContext)
+nsFilterInstance::Render(DrawTarget* aDrawTarget)
 {
   MOZ_ASSERT(mTargetFrame, "Need a frame for rendering");
 
-  nsIntRect filterRect = mPostFilterDirtyRegion.GetBounds().Intersect(OutputFilterSpaceBounds());
+  nsIntRect filterRect =
+    mPostFilterDirtyRegion.GetBounds().Intersect(OutputFilterSpaceBounds());
   gfxMatrix ctm = GetFilterSpaceToDeviceSpaceTransform();
 
   if (filterRect.IsEmpty() || ctm.IsSingular()) {
     return NS_OK;
   }
 
-  RefPtr<DrawTarget> dt = aContext->GetDrawTarget();
-
-  AutoRestoreTransform autoRestoreTransform(dt);
-  Matrix newTM = ToMatrix(ctm).PreTranslate(filterRect.x, filterRect.y) * dt->GetTransform();
-  dt->SetTransform(newTM);
+  AutoRestoreTransform autoRestoreTransform(aDrawTarget);
+  Matrix newTM = ToMatrix(ctm).PreTranslate(filterRect.x, filterRect.y) *
+                 aDrawTarget->GetTransform();
+  aDrawTarget->SetTransform(newTM);
 
   ComputeNeededBoxes();
 
-  nsresult rv = BuildSourceImage(dt);
+  nsresult rv = BuildSourceImage(aDrawTarget);
   if (NS_FAILED(rv))
     return rv;
-  rv = BuildSourcePaints(dt);
+  rv = BuildSourcePaints(aDrawTarget);
   if (NS_FAILED(rv))
     return rv;
 
   FilterSupport::RenderFilterDescription(
-    dt, mFilterDescription, IntRectToRect(filterRect),
+    aDrawTarget, mFilterDescription, IntRectToRect(filterRect),
     mSourceGraphic.mSourceSurface, mSourceGraphic.mSurfaceRect,
     mFillPaint.mSourceSurface, mFillPaint.mSurfaceRect,
     mStrokePaint.mSourceSurface, mStrokePaint.mSurfaceRect,
     mInputImages, Point(0, 0));
 
   return NS_OK;
 }
 
--- a/layout/svg/nsFilterInstance.h
+++ b/layout/svg/nsFilterInstance.h
@@ -72,17 +72,17 @@ public:
 
   /**
    * Paint the given filtered frame.
    * @param aDirtyArea The area than needs to be painted, in aFilteredFrame's
    *   frame space (i.e. relative to its origin, the top-left corner of its
    *   border box).
    */
   static nsresult PaintFilteredFrame(nsIFrame *aFilteredFrame,
-                                     gfxContext& aContext,
+                                     DrawTarget* aDrawTarget,
                                      const gfxMatrix& aTransform,
                                      nsSVGFilterPaintCallback *aPaintCallback,
                                      const nsRegion* aDirtyArea);
 
   /**
    * Returns the post-filter area that could be dirtied when the given
    * pre-filter area of aFilteredFrame changes.
    * @param aPreFilterDirtyRegion The pre-filter area of aFilteredFrame that has
@@ -145,22 +145,22 @@ public:
                    const gfxRect *aOverrideBBox = nullptr);
 
   /**
    * Returns true if the filter instance was created successfully.
    */
   bool IsInitialized() const { return mInitialized; }
 
   /**
-   * Draws the filter output into aContext. The area that
+   * Draws the filter output into aDrawTarget. The area that
    * needs to be painted must have been specified before calling this method
    * by passing it as the aPostFilterDirtyRegion argument to the
    * nsFilterInstance constructor.
    */
-  nsresult Render(gfxContext* aContext);
+  nsresult Render(DrawTarget* aDrawTarget);
 
   const FilterDescription& ExtractDescriptionAndAdditionalImages(nsTArray<RefPtr<SourceSurface>>& aOutAdditionalImages)
   {
     mInputImages.SwapElements(aOutAdditionalImages);
     return mFilterDescription;
   }
 
   /**
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -585,17 +585,18 @@ nsSVGIntegrationUtils::PaintFramesWithEf
 
   /* Paint the child */
   if (effectProperties.HasValidFilter()) {
     RegularFramePaintCallback callback(aBuilder, aLayerManager,
                                        offsetToUserSpace);
 
     nsRegion dirtyRegion = aDirtyRect - offsetToBoundingBox;
     gfxMatrix tm = nsSVGIntegrationUtils::GetCSSPxToDevPxMatrix(aFrame);
-    nsFilterInstance::PaintFilteredFrame(aFrame, *target, tm, &callback, &dirtyRegion);
+    nsFilterInstance::PaintFilteredFrame(aFrame, target->GetDrawTarget(),
+                                         tm, &callback, &dirtyRegion);
   } else {
     target->SetMatrix(matrixAutoSaveRestore.Matrix());
     BasicLayerManager* basic = static_cast<BasicLayerManager*>(aLayerManager);
     RefPtr<gfxContext> oldCtx = basic->GetTarget();
     basic->SetTarget(target);
     aLayerManager->EndTransaction(FrameLayerBuilder::DrawPaintedLayer, aBuilder);
     basic->SetTarget(oldCtx);
   }
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -685,18 +685,19 @@ nsSVGUtils::PaintFrameWithEffects(nsIFra
                                       aDirtyRect->width, aDirtyRect->height));
       tmpDirtyRegion =
         nsLayoutUtils::RoundGfxRectToAppRect(
           dirtyBounds, aFrame->PresContext()->AppUnitsPerCSSPixel()) -
         aFrame->GetPosition();
       dirtyRegion = &tmpDirtyRegion;
     }
     SVGPaintCallback paintCallback;
-    nsFilterInstance::PaintFilteredFrame(aFrame, *target, aTransform,
-                                         &paintCallback, dirtyRegion);
+    nsFilterInstance::PaintFilteredFrame(aFrame, target->GetDrawTarget(),
+                                         aTransform, &paintCallback,
+                                         dirtyRegion);
   } else {
     svgChildFrame->PaintSVG(*target, aTransform, aDirtyRect);
   }
 
   if (clipPathFrame && isTrivialClip) {
     aContext.Restore();
   }
 
--- a/security/manager/ssl/nsNSSComponent.cpp
+++ b/security/manager/ssl/nsNSSComponent.cpp
@@ -1059,16 +1059,18 @@ nsNSSComponent::InitializeNSS()
 
   bool requireSafeNegotiation =
     Preferences::GetBool("security.ssl.require_safe_negotiation",
                          REQUIRE_SAFE_NEGOTIATION_DEFAULT);
   SSL_OptionSetDefault(SSL_REQUIRE_SAFE_NEGOTIATION, requireSafeNegotiation);
 
   SSL_OptionSetDefault(SSL_ENABLE_RENEGOTIATION, SSL_RENEGOTIATE_REQUIRES_XTN);
 
+  SSL_OptionSetDefault(SSL_ENABLE_EXTENDED_MASTER_SECRET, true);
+
   SSL_OptionSetDefault(SSL_ENABLE_FALSE_START,
                        Preferences::GetBool("security.ssl.enable_false_start",
                                             FALSE_START_ENABLED_DEFAULT));
 
   // SSL_ENABLE_NPN and SSL_ENABLE_ALPN also require calling
   // SSL_SetNextProtoNego in order for the extensions to be negotiated.
   // WebRTC does not do that so it will not use NPN or ALPN even when these
   // preferences are true.