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 99137d6d4061
parent 276309 d8c83969224b (current diff)
parent 276292 871d92a1b070 (diff)
child 276311 d054c067bcf8
child 276314 2110ff129ead
child 276335 afc8558eac72
child 276374 4cfa9d84377b
push id29791
push usercbook@mozilla.com
push dateMon, 14 Dec 2015 10:56:16 +0000
treeherdermozilla-central@99137d6d4061 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone45.0a1
first release with
nightly linux32
99137d6d4061 / 45.0a1 / 20151214030220 / files
nightly linux64
99137d6d4061 / 45.0a1 / 20151214030220 / files
nightly mac
99137d6d4061 / 45.0a1 / 20151214030220 / files
nightly win32
99137d6d4061 / 45.0a1 / 20151214030220 / files
nightly win64
99137d6d4061 / 45.0a1 / 20151214030220 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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.