Backed out changeset c14980a16210 (bug 948265) so it can address review comments first, despite the CLOSED TREE
authorWes Kocher <wkocher@mozilla.com>
Fri, 28 Feb 2014 14:48:31 -0800
changeset 171366 57cd2113f04409db47f71fa5f4f43a675e8d25a0
parent 171365 b8c1ff82160e557b0d08f75abd4161fa309df22d
child 171367 49d61a8f1e5c40e16d599a055e14f6371472e813
push id26324
push useremorley@mozilla.com
push dateMon, 03 Mar 2014 14:45:05 +0000
treeherdermozilla-central@73ab6437a1de [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs948265
milestone30.0a1
backs outc14980a16210e7240183b2387938577314d6ce64
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset c14980a16210 (bug 948265) so it can address review comments first, despite the CLOSED TREE
content/base/src/nsGkAtomList.h
content/base/src/nsTreeSanitizer.cpp
content/svg/content/src/SVGFilterElement.cpp
content/svg/content/src/SVGFilterElement.h
content/svg/content/test/dataTypes-helper.svg
content/svg/content/test/test_dataTypes.html
content/svg/content/test/test_dataTypesModEvents.html
dom/webidl/SVGFilterElement.webidl
layout/reftests/svg/filters/feDiffuseLighting-1.svg
layout/reftests/svg/filters/feDisplacementMap-scale-01.svg
layout/reftests/svg/filters/feDistantLight-filterRes-01-ref.svg
layout/reftests/svg/filters/feDistantLight-filterRes-01.svg
layout/reftests/svg/filters/feSpecularLighting-1.svg
layout/reftests/svg/filters/filter-filterRes-high-01.svg
layout/reftests/svg/filters/filter-filterRes-high-02.svg
layout/reftests/svg/filters/filter-filterRes-low-01.svg
layout/reftests/svg/filters/reftest.list
layout/reftests/svg/smil/anim-feGaussianBlur-01.svg
layout/reftests/svg/smil/anim-filter-filterRes-01.svg
layout/reftests/svg/smil/reftest.list
layout/svg/crashtests/453754-1.svg
layout/svg/crashtests/474700-1.svg
layout/svg/nsSVGFilterFrame.cpp
layout/svg/nsSVGFilterFrame.h
layout/svg/nsSVGFilterInstance.cpp
layout/svg/nsSVGFilterInstance.h
parser/html/javasrc/AttributeName.java
parser/html/nsHtml5AtomList.h
parser/html/nsHtml5AttributeName.cpp
parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests11.dat
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -1270,16 +1270,17 @@ GK_ATOM(fePointLight, "fePointLight")
 GK_ATOM(feSpecularLighting, "feSpecularLighting")
 GK_ATOM(feSpotLight, "feSpotLight")
 GK_ATOM(feTile, "feTile")
 GK_ATOM(feTurbulence, "feTurbulence")
 GK_ATOM(fill, "fill")
 GK_ATOM(fill_opacity, "fill-opacity")
 GK_ATOM(fill_rule, "fill-rule")
 GK_ATOM(filter, "filter")
+GK_ATOM(filterRes, "filterRes")
 GK_ATOM(filterUnits, "filterUnits")
 GK_ATOM(flood_color, "flood-color")
 GK_ATOM(flood_opacity, "flood-opacity")
 GK_ATOM(font_face, "font-face")
 GK_ATOM(font_face_format, "font-face-format")
 GK_ATOM(font_face_name, "font-face-name")
 GK_ATOM(font_face_src, "font-face-src")
 GK_ATOM(font_face_uri, "font-face-uri")
--- a/content/base/src/nsTreeSanitizer.cpp
+++ b/content/base/src/nsTreeSanitizer.cpp
@@ -411,16 +411,17 @@ nsIAtom** const kAttributesSVG[] = {
   &nsGkAtoms::edgeMode, // edgeMode
   &nsGkAtoms::elevation, // elevation
   // enable-background
   &nsGkAtoms::end, // end
   &nsGkAtoms::fill, // fill
   &nsGkAtoms::fill_opacity, // fill-opacity
   &nsGkAtoms::fill_rule, // fill-rule
   &nsGkAtoms::filter, // filter
+  &nsGkAtoms::filterRes, // filterRes
   &nsGkAtoms::filterUnits, // filterUnits
   &nsGkAtoms::flood_color, // flood-color
   &nsGkAtoms::flood_opacity, // flood-opacity
   // XXX focusable
   &nsGkAtoms::font, // font
   &nsGkAtoms::font_family, // font-family
   &nsGkAtoms::font_size, // font-size
   &nsGkAtoms::font_size_adjust, // font-size-adjust
--- a/content/svg/content/src/SVGFilterElement.cpp
+++ b/content/svg/content/src/SVGFilterElement.cpp
@@ -25,16 +25,21 @@ SVGFilterElement::WrapNode(JSContext *aC
 nsSVGElement::LengthInfo SVGFilterElement::sLengthInfo[4] =
 {
   { &nsGkAtoms::x, -10, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::X },
   { &nsGkAtoms::y, -10, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::Y },
   { &nsGkAtoms::width, 120, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::X },
   { &nsGkAtoms::height, 120, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::Y },
 };
 
+nsSVGElement::IntegerPairInfo SVGFilterElement::sIntegerPairInfo[1] =
+{
+  { &nsGkAtoms::filterRes, 0 }
+};
+
 nsSVGElement::EnumInfo SVGFilterElement::sEnumInfo[2] =
 {
   { &nsGkAtoms::filterUnits,
     sSVGUnitTypesMap,
     SVG_UNIT_TYPE_OBJECTBOUNDINGBOX
   },
   { &nsGkAtoms::primitiveUnits,
     sSVGUnitTypesMap,
@@ -95,16 +100,36 @@ SVGFilterElement::FilterUnits()
 }
 
 already_AddRefed<SVGAnimatedEnumeration>
 SVGFilterElement::PrimitiveUnits()
 {
   return mEnumAttributes[PRIMITIVEUNITS].ToDOMAnimatedEnum(this);
 }
 
+already_AddRefed<SVGAnimatedInteger>
+SVGFilterElement::FilterResX()
+{
+  return mIntegerPairAttributes[FILTERRES].ToDOMAnimatedInteger(nsSVGIntegerPair::eFirst,
+                                                                this);
+}
+
+already_AddRefed<SVGAnimatedInteger>
+SVGFilterElement::FilterResY()
+{
+  return mIntegerPairAttributes[FILTERRES].ToDOMAnimatedInteger(nsSVGIntegerPair::eSecond,
+                                                                this);
+}
+
+void
+SVGFilterElement::SetFilterRes(uint32_t filterResX, uint32_t filterResY)
+{
+  mIntegerPairAttributes[FILTERRES].SetBaseValues(filterResX, filterResY, this);
+}
+
 already_AddRefed<SVGAnimatedString>
 SVGFilterElement::Href()
 {
   return mStringAttributes[HREF].ToDOMAnimatedString(this);
 }
 
 //----------------------------------------------------------------------
 // nsIContent methods
@@ -156,16 +181,23 @@ SVGFilterElement::HasValidDimensions() c
 
 nsSVGElement::LengthAttributesInfo
 SVGFilterElement::GetLengthInfo()
 {
   return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
                               ArrayLength(sLengthInfo));
 }
 
+nsSVGElement::IntegerPairAttributesInfo
+SVGFilterElement::GetIntegerPairInfo()
+{
+  return IntegerPairAttributesInfo(mIntegerPairAttributes, sIntegerPairInfo,
+                                   ArrayLength(sIntegerPairInfo));
+}
+
 nsSVGElement::EnumAttributesInfo
 SVGFilterElement::GetEnumInfo()
 {
   return EnumAttributesInfo(mEnumAttributes, sEnumInfo,
                             ArrayLength(sEnumInfo));
 }
 
 nsSVGElement::StringAttributesInfo
--- a/content/svg/content/src/SVGFilterElement.h
+++ b/content/svg/content/src/SVGFilterElement.h
@@ -49,28 +49,36 @@ public:
 
   // WebIDL
   already_AddRefed<SVGAnimatedLength> X();
   already_AddRefed<SVGAnimatedLength> Y();
   already_AddRefed<SVGAnimatedLength> Width();
   already_AddRefed<SVGAnimatedLength> Height();
   already_AddRefed<SVGAnimatedEnumeration> FilterUnits();
   already_AddRefed<SVGAnimatedEnumeration> PrimitiveUnits();
+  already_AddRefed<SVGAnimatedInteger> FilterResX();
+  already_AddRefed<SVGAnimatedInteger> FilterResY();
+  void SetFilterRes(uint32_t filterResX, uint32_t filterResY);
   already_AddRefed<SVGAnimatedString> Href();
 
 protected:
 
   virtual LengthAttributesInfo GetLengthInfo() MOZ_OVERRIDE;
+  virtual IntegerPairAttributesInfo GetIntegerPairInfo() MOZ_OVERRIDE;
   virtual EnumAttributesInfo GetEnumInfo() MOZ_OVERRIDE;
   virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
 
   enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT };
   nsSVGLength2 mLengthAttributes[4];
   static LengthInfo sLengthInfo[4];
 
+  enum { FILTERRES };
+  nsSVGIntegerPair mIntegerPairAttributes[1];
+  static IntegerPairInfo sIntegerPairInfo[1];
+
   enum { FILTERUNITS, PRIMITIVEUNITS };
   nsSVGEnum mEnumAttributes[2];
   static EnumInfo sEnumInfo[2];
 
   enum { HREF };
   nsSVGString mStringAttributes[1];
   static StringInfo sStringInfo[1];
 };
--- a/content/svg/content/test/dataTypes-helper.svg
+++ b/content/svg/content/test/dataTypes-helper.svg
@@ -1,11 +1,12 @@
 <?xml version="1.0"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="750">
   <defs>
+    <!-- <integer-optional-integer> (filterRes) -->
     <filter id="filter">
       <!-- <boolean> (preserveAlpha) -->
       <!-- <enum> (edgeMode) -->
       <!-- <number> (divisor) -->
       <!-- <integer> (targetX) -->
       <!-- <string> (result) -->
       <feConvolveMatrix id="convolve"/>
       <!-- <number-optional-number> (stdDeviation) -->
--- a/content/svg/content/test/test_dataTypes.html
+++ b/content/svg/content/test/test_dataTypes.html
@@ -117,16 +117,66 @@ function runTests()
   convolve.targetX.baseVal = 7;
   is(convolve.targetX.animVal, 7, "integer animVal");
   is(convolve.getAttribute("targetX"), "7", "integer attribute");
   convolve.setAttribute("targetX", "");
   ok(convolve.getAttribute("targetX") === "", "empty integer attribute");
   convolve.removeAttribute("targetX");
   ok(convolve.getAttribute("targetX") === null, "removed integer attribute");
 
+  // integer-optional-integer attribute
+
+  filter.setAttribute("filterRes", "100");
+  is(filter.filterResX.baseVal, 100, "integer-optional-integer first baseVal");
+  is(filter.filterResX.animVal, 100, "integer-optional-integer first animVal");
+  is(filter.filterResY.baseVal, 100, "integer-optional-integer second baseVal");
+  is(filter.filterResY.animVal, 100, "integer-optional-integer second animVal");
+
+  filter.filterResX.baseVal = 50;
+  is(filter.filterResX.animVal, 50, "integer-optional-integer first animVal");
+  is(filter.filterResY.animVal, 100, "integer-optional-integer second animVal");
+  is(filter.getAttribute("filterRes"), "50, 100", "integer-optional-integer attribute");
+
+  filter.filterResY.baseVal = 50;
+  is(filter.getAttribute("filterRes"), "50", "integer-optional-integer attribute");
+
+  filter.setFilterRes(80, 90);
+  is(filter.filterResX.baseVal, 80, "integer-optional-integer first baseVal");
+  is(filter.filterResX.animVal, 80, "integer-optional-integer first animVal");
+  is(filter.filterResY.baseVal, 90, "integer-optional-integer second baseVal");
+  is(filter.filterResY.animVal, 90, "integer-optional-integer second animVal");
+
+  // 32 bit integer range
+  filter.setFilterRes(-2147483648, 2147483647);
+  is(filter.filterResX.baseVal, -2147483648, "integer-optional-integer first baseVal");
+  is(filter.filterResX.animVal, -2147483648, "integer-optional-integer first animVal");
+  is(filter.filterResY.baseVal, 2147483647, "integer-optional-integer second baseVal");
+  is(filter.filterResY.animVal, 2147483647, "integer-optional-integer second animVal");
+
+  // too big, clamp
+  filter.setAttribute("filterRes", "-2147483649, 2147483648");
+  is(filter.filterResX.baseVal, -2147483648, "integer-optional-integer first baseVal");
+  is(filter.filterResX.animVal, -2147483648, "integer-optional-integer first animVal");
+  is(filter.filterResY.baseVal, 2147483647, "integer-optional-integer second baseVal");
+  is(filter.filterResY.animVal, 2147483647, "integer-optional-integer second animVal");
+
+  // invalid
+  filter.setAttribute("filterRes", "-00000000000invalid, 214748364720invalid");
+  is(filter.filterResX.baseVal, 0, "integer-optional-integer first baseVal");
+  is(filter.filterResX.animVal, 0, "integer-optional-integer first animVal");
+  is(filter.filterResY.baseVal, 0, "integer-optional-integer second baseVal");
+  is(filter.filterResY.animVal, 0, "integer-optional-integer second animVal");
+
+  filter.setAttribute("filterRes", "");
+  ok(filter.getAttribute("filterRes") === "",
+     "empty integer-optional-integer attribute");
+  filter.removeAttribute("filterRes");
+  ok(filter.getAttribute("filterRes") === null,
+     "removed integer-optional-integer attribute");
+
   // angle attribute
 
   marker.setAttribute("orient", "90deg");
   is(marker.orientAngle.baseVal.value, 90, "angle baseVal");
   is(marker.orientAngle.animVal.value, 90, "angle animVal");
 
   var baseAngle = marker.orientAngle.baseVal;
   var animAngle = marker.orientAngle.animVal;
--- a/content/svg/content/test/test_dataTypesModEvents.html
+++ b/content/svg/content/test/test_dataTypesModEvents.html
@@ -122,16 +122,31 @@ function runTests()
   eventChecker.expect("");
   convolve.setAttribute("targetX", "8");
   // Check redundant change when comparing attribute value to typed value
   eventChecker.expect("remove add");
   convolve.removeAttribute("targetX");
   convolve.setAttribute("targetX", "8");
   convolve.targetX.baseVal = 8;
 
+  // integer-optional-integer attribute
+
+  eventChecker.watchAttr(filter, "filterRes");
+  eventChecker.expect("add modify remove add");
+  filter.setAttribute("filterRes", "60, 70");
+  filter.filterResX.baseVal = 50;
+  filter.removeAttribute("filterRes");
+  filter.removeAttributeNS(null, "filterRes");
+  filter.setAttribute("filterRes", "50, 60");
+
+  eventChecker.expect("");
+  filter.filterResX.baseVal = 50;
+  filter.setAttribute("filterRes", "50, 60");
+  filter.filterResY.baseVal = 60;
+
   // angle attribute
 
   eventChecker.watchAttr(marker, "orient");
   eventChecker.expect("add modify modify modify modify modify remove add");
   marker.setAttribute("orient", "90deg");
   marker.orientAngle.baseVal.value = 12;
   marker.orientAngle.baseVal.valueInSpecifiedUnits = 23;
   marker.orientAngle.baseVal.valueAsString = "34";
--- a/dom/webidl/SVGFilterElement.webidl
+++ b/dom/webidl/SVGFilterElement.webidl
@@ -12,15 +12,18 @@
 
 interface SVGFilterElement : SVGElement {
   readonly attribute SVGAnimatedEnumeration filterUnits;
   readonly attribute SVGAnimatedEnumeration primitiveUnits;
   readonly attribute SVGAnimatedLength x;
   readonly attribute SVGAnimatedLength y;
   readonly attribute SVGAnimatedLength width;
   readonly attribute SVGAnimatedLength height;
+  readonly attribute SVGAnimatedInteger filterResX;
+  readonly attribute SVGAnimatedInteger filterResY;
 
+  void setFilterRes(unsigned long filterResX, unsigned long filterResY);
   // ImageData apply(ImageData source);
 };
 
 SVGFilterElement implements SVGURIReference;
 SVGFilterElement implements SVGUnitTypes;
 
--- a/layout/reftests/svg/filters/feDiffuseLighting-1.svg
+++ b/layout/reftests/svg/filters/feDiffuseLighting-1.svg
@@ -1,17 +1,17 @@
 <!--
      Any copyright is dedicated to the Public Domain.
      http://creativecommons.org/publicdomain/zero/1.0/
 -->
 <svg xmlns='http://www.w3.org/2000/svg' width='100px' height='100px'>
   <!--
     A basic test for the <feDiffuseLighting> filter primitive.
-    Setting kernelUnitLength on the <feDiffuseLighting> should allow us to
-    assume pixel perfection.
+    Setting filterRes on the <filter> and kernelUnitLength on the
+    <feDiffuseLighting> should allow us to assume pixel perfection.
     -->
-  <filter id='f' x='0' y='0' width='1' height='1'>
+  <filter id='f' x='0' y='0' width='1' height='1' filterRes='100 100'>
     <feDiffuseLighting kernelUnitLength='1'>
       <feDistantLight/>
     </feDiffuseLighting>
   </filter>
   <path d='M0,0 h100 v100 h-100 z M20,20 v60 h60 v-60 z' filter='url(#f)'/>
 </svg>
--- a/layout/reftests/svg/filters/feDisplacementMap-scale-01.svg
+++ b/layout/reftests/svg/filters/feDisplacementMap-scale-01.svg
@@ -1,15 +1,15 @@
 <!--
      Any copyright is dedicated to the Public Domain.
      http://creativecommons.org/publicdomain/zero/1.0/
 -->
 <svg xmlns="http://www.w3.org/2000/svg">
   <title>Test that directionless filter primitive attributes are resolved to user units correctly</title>
   <!-- https://bugzilla.mozilla.org/show_bug.cgi?id=619967 -->
-  <filter id="f" filterUnits="userSpaceOnUse" x="0" y="0" width="400" height="200" color-interpolation-filters="sRGB">
+  <filter id="f" filterUnits="userSpaceOnUse" x="0" y="0" width="400" height="200" filterRes="400 100" color-interpolation-filters="sRGB">
     <feFlood flood-color="#800" result="map"/>
     <feDisplacementMap in="SourceGraphic" in2="map" xChannelSelector="R" yChannelSelector="G" scale="100"/>
   </filter>
   <rect width="100%" height="100%" fill="lime"/>
   <rect y="82" width="300" height="8" fill="red"/>
   <rect width="400" height="200" fill="lime" filter="url(#f)"/>
 </svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/filters/feDistantLight-filterRes-01-ref.svg
@@ -0,0 +1,19 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg">
+  <title>Reference for feDistantLight with filterRes larger than filter region</title>
+
+  <!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=610466 -->
+  <defs>
+    <filter id="f" x="0" y="0" width="0.5" height="0.5" filterRes="50 50">
+      <feDiffuseLighting kernelUnitLength="1" lighting-color="lime">
+        <feDistantLight elevation="100"/>
+      </feDiffuseLighting>
+    </filter>
+  </defs>
+  <svg clip="rect(1px 48px 48px 1px)">
+    <path d="M0,0 h100 v100 h-100 z" filter="url(#f)"/>
+  </svg>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/filters/feDistantLight-filterRes-01.svg
@@ -0,0 +1,19 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg">
+  <title>Testcase for feDistantLight with filterRes larger than filter region</title>
+
+  <!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=610466 -->
+  <defs>
+    <filter id="f" x="0" y="0" width="0.5" height="0.5" filterRes="60 60">
+      <feDiffuseLighting kernelUnitLength="1" lighting-color="lime">
+        <feDistantLight elevation="100"/>
+      </feDiffuseLighting>
+    </filter>
+  </defs>
+  <svg clip="rect(1px 48px 48px 1px)">
+    <path d="M0,0 h100 v100 h-100 z" filter="url(#f)"/>
+  </svg>
+</svg>
--- a/layout/reftests/svg/filters/feSpecularLighting-1.svg
+++ b/layout/reftests/svg/filters/feSpecularLighting-1.svg
@@ -1,19 +1,19 @@
 <!--
      Any copyright is dedicated to the Public Domain.
      http://creativecommons.org/publicdomain/zero/1.0/
 -->
 <svg xmlns='http://www.w3.org/2000/svg'>
   <!--
     A basic test for the <feSpecularLighting> filter primitive.
-    Setting kernelUnitLength on the <feSpecularLighting> should allow us to
-    assume pixel perfection.
+    Setting filterRes on the <filter> and kernelUnitLength on the
+    <feSpecularLighting> should allow us to assume pixel perfection.
     -->
-  <filter id='f' x='0' y='0' width='1' height='1' color-interpolation-filters='sRGB'>
+  <filter id='f' x='0' y='0' width='1' height='1' filterRes='100 100' color-interpolation-filters='sRGB'>
     <feSpecularLighting kernelUnitLength='1' result='a'>
       <feDistantLight azimuth='45'/>
     </feSpecularLighting>
     <feComposite in='a' in2='SourceAlpha' operator='in' result='b'/>
     <feComposite in='SourceGraphic' in2='b' operator='arithmetic' k1='0' k2='1' k3='1' k4='0' x='10' y='10' width='80' height='80'/>
   </filter>
   <rect width='100' height='100' fill='blue'/>
   <path d='M0,0 h100 v100 h-100 z M20,20 v60 h60 v-60 z' filter='url(#f)'/>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/filters/filter-filterRes-high-01.svg
@@ -0,0 +1,20 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg" version="1.0">
+  <desc>
+    This test checks that the implicit offscreen surface scaling implied by
+    a high 'filterRes' interacts correctly with other transforms. Specifically
+    you should see no red if the red filtered circle paints only on the pixels
+    that it should paint on.
+  </desc>
+  <filter id="filter" x="0" y="0" width="1" height="1" filterRes="1000 1000">
+    <feGaussianBlur stdDeviation="0.001"/>
+  </filter>
+  <rect width="100%" height="100%" fill="lime"/>
+  <g transform="translate(50, 0)">
+    <circle fill="red" cx="100" cy="100" r="98" transform="translate(50, 0)" filter="url(#filter)"/>
+  </g>
+  <circle fill="lime" cx="200" cy="100" r="100"/>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/filters/filter-filterRes-high-02.svg
@@ -0,0 +1,20 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg" version="1.0">
+  <desc>
+    This test checks that the implicit offscreen surface scaling implied by
+    a high 'filterRes' interacts correctly with other transforms. Specifically
+    you should see no red if the lime filtered circle paints on all the pixels
+    that it should paint on.
+  </desc>
+  <filter id="filter" x="0" y="0" width="1" height="1" filterRes="1000 1000">
+    <feGaussianBlur stdDeviation="0.001"/>
+  </filter>
+  <rect width="100%" height="100%" fill="lime"/>
+  <circle fill="red" cx="200" cy="100" r="98"/>
+  <g transform="translate(50, 0)">
+    <circle fill="lime" cx="100" cy="100" r="100" transform="translate(50, 0)" filter="url(#filter)"/>
+  </g>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/filters/filter-filterRes-low-01.svg
@@ -0,0 +1,22 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg" version="1.0">
+  <desc>
+    This test checks that the implicit offscreen surface scaling implied by
+    a high 'filterRes' interacts correctly with other transforms. Specifically
+    you should see only green if the red filtered circle paints only on
+    the pixels that it should paint on.
+  </desc>
+  <filter id="filter" x="0" y="0" width="1" height="1" filterRes="50 50">
+    <feGaussianBlur stdDeviation="0.001"/>
+  </filter>
+  <rect width="100%" height="100%" fill="lime"/>
+  <g transform="translate(50, 0)">
+    <!-- The filterRes is quartered, so we need r to be 5 pixels less, plus
+         one less for antialiasing, otherwise the circle will get fringe effects. -->
+    <circle fill="red" cx="100" cy="100" r="94" transform="translate(50, 0)" filter="url(#filter)"/>
+  </g>
+  <circle fill="lime" cx="200" cy="100" r="100"/>
+</svg>
--- a/layout/reftests/svg/filters/reftest.list
+++ b/layout/reftests/svg/filters/reftest.list
@@ -46,16 +46,19 @@ fuzzy(1,6400) == feGaussianBlur-1.svg fe
 == feOffset-2.svg feOffset-2-ref.svg
 
 == feTile-1.svg feTile-1-ref.svg
 == feTile-2.svg feTile-2-ref.svg
 
 # no tests for feTurbulence
 
 == filter-clipped-rect-01.svg pass.svg
+== filter-filterRes-high-01.svg pass.svg
+== filter-filterRes-high-02.svg pass.svg
+random-if(d2d) == filter-filterRes-low-01.svg pass.svg
 == filter-inner-svg-01.svg pass.svg
 == filter-inner-svg-02.svg pass.svg
 == filter-inner-svg-03.svg pass.svg
 fails == filter-marked-line-01.svg pass.svg # bug 477704
 == filter-kernelUnitLength-01.svg filter-kernelUnitLength-01-ref.svg
 == filter-marked-line-02.svg pass.svg
 == filter-marked-line-03.svg pass.svg
 == filter-marked-line-04.svg pass.svg
@@ -77,16 +80,18 @@ fails == filter-marked-line-01.svg pass.
 skip-if(B2G) fuzzy(1,26732) == feComposite-paint-01.svg feComposite-paint-01-ref.svg
 fuzzy(1,10000) == feConvolveMatrix-bias-01.svg feConvolveMatrix-bias-01-ref.svg
 == feConvolveMatrix-order-01.svg feConvolveMatrix-order-01-ref.svg
 
 == feDisplacementMap-alpha-01.svg pass.svg
 fuzzy(2,500) == feDisplacementMap-colour-01.svg feDisplacementMap-colour-01-ref.svg
 skip-if(B2G) == feDisplacementMap-scale-01.svg pass.svg
 
+skip-if(B2G) fuzzy-if(cocoaWidget,4,184) == feDistantLight-filterRes-01.svg feDistantLight-filterRes-01-ref.svg
+
 == feDropShadow-01.svg feDropShadow-01-ref.svg
 
 == feGaussianBlur-alpha-01.svg feGaussianBlur-alpha-01-ref.svg
 
 == feMorphology-radius-negative-01.svg pass.svg
 == feMorphology-radius-negative-02.svg pass.svg
 == feMorphology-radius-zero-01.svg pass.svg
 == feMorphology-radius-zero-02.svg pass.svg
--- a/layout/reftests/svg/smil/anim-feGaussianBlur-01.svg
+++ b/layout/reftests/svg/smil/anim-feGaussianBlur-01.svg
@@ -3,17 +3,17 @@
      http://creativecommons.org/publicdomain/zero/1.0/
 -->
 <svg xmlns="http://www.w3.org/2000/svg"
      xmlns:xlink="http://www.w3.org/1999/xlink"
      class="reftest-wait"
      onload="setTimeAndSnapshot(1.9999, true)">
   <title>Test animation of the "stdDeviation" &lt;number-optional-number&gt; attribute on "feGaussianBlur" elements</title>
   <script xlink:href="smil-util.js" type="text/javascript"/>
-  <filter id="filter" x="0" y="0" width="1" height="1">
+  <filter id="filter" x="0" y="0" width="1" height="1" filterRes="1000">
     <feGaussianBlur stdDeviation="50">
       <animate attributeName="stdDeviation"
                calcMode="linear"
                begin="0s" dur="2s"
                from="100,100" to="0"
                fill="freeze"/>
     </feGaussianBlur>
   </filter>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/smil/anim-filter-filterRes-01.svg
@@ -0,0 +1,24 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg"
+     xmlns:xlink="http://www.w3.org/1999/xlink"
+     class="reftest-wait"
+     onload="setTimeAndSnapshot(101, true)">
+  <title>Test animation of the "filterRes" &lt;integer-optional-integer&gt; attribute on "filter" elements</title>
+  <script xlink:href="smil-util.js" type="text/javascript"/>
+  <filter id="filter" x="0" y="0" width="1" height="1" filterRes="10 10">
+    <animate attributeName="filterRes"
+             calcMode="linear"
+             begin="100s" dur="2s"
+             from="0" to="2000 2000"
+             fill="freeze"/>
+    <feGaussianBlur stdDeviation="0.001"/>
+  </filter>
+  <rect width="100%" height="100%" fill="lime"/>
+  <g transform="translate(50, 0)">
+    <circle fill="red" cx="100" cy="100" r="98" transform="translate(50, 0)" filter="url(#filter)"/>
+  </g>
+  <circle fill="lime" cx="200" cy="100" r="100"/>
+</svg>
--- a/layout/reftests/svg/smil/reftest.list
+++ b/layout/reftests/svg/smil/reftest.list
@@ -110,16 +110,19 @@ skip-if(B2G) == anim-offset-01.svg lime.
 == anim-pathLength-01.svg anim-pathLength-01-ref.svg
 
 # animate some <number-optional-number> attributes:
 == anim-feGaussianBlur-01.svg lime.svg
 
 # animate some <integer> attributes:
 skip-if(B2G) == anim-feTurbulence-numOctaves-01.svg anim-feTurbulence-numOctaves-01-ref.svg # bug 773482
 
+# animate some <integer-optional-integer> attributes:
+skip-if(B2G) random-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) == anim-filter-filterRes-01.svg lime.svg # bug 818177
+
 # animate some <angle> attributes:
 skip-if(B2G) == anim-marker-orient-01.svg lime.svg # bug 773482
 skip-if(B2G) == anim-marker-orient-02.svg lime.svg # bug 773482
 
 #animate points list:
 skip-if(B2G) == anim-polygon-points-01.svg anim-polygon-points-01-ref.svg
 == anim-polyline-points-01.svg anim-polyline-points-01-ref.svg
 
--- a/layout/svg/crashtests/453754-1.svg
+++ b/layout/svg/crashtests/453754-1.svg
@@ -1,7 +1,7 @@
 <svg xmlns="http://www.w3.org/2000/svg">
 
-  <filter id="f" height="-1"/>
+  <filter id="f" height="-1" filterRes="1"/>
 
   <rect filter="url(#f)" />
 
 </svg>
--- a/layout/svg/crashtests/474700-1.svg
+++ b/layout/svg/crashtests/474700-1.svg
@@ -1,1 +1,1 @@
-<svg xmlns="http://www.w3.org/2000/svg"><filter id="f1" height="-2"/><rect width="50" height="100" filter="url(#f1)"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg"><filter id="f1" filterRes="10 20" height="-2"/><rect width="50" height="100" filter="url(#f1)"/></svg>
--- a/layout/svg/nsSVGFilterFrame.cpp
+++ b/layout/svg/nsSVGFilterFrame.cpp
@@ -62,16 +62,32 @@ nsSVGFilterFrame::GetEnumValue(uint32_t 
   AutoFilterReferencer filterRef(this);
 
   nsSVGFilterFrame *next = GetReferencedFilterIfNotInUse();
   return next ? next->GetEnumValue(aIndex, aDefault) :
     static_cast<SVGFilterElement *>(aDefault)->
       mEnumAttributes[aIndex].GetAnimValue();
 }
 
+const nsSVGIntegerPair *
+nsSVGFilterFrame::GetIntegerPairValue(uint32_t aIndex, nsIContent *aDefault)
+{
+  const nsSVGIntegerPair *thisIntegerPair =
+    &static_cast<SVGFilterElement *>(mContent)->mIntegerPairAttributes[aIndex];
+
+  if (thisIntegerPair->IsExplicitlySet())
+    return thisIntegerPair;
+
+  AutoFilterReferencer filterRef(this);
+
+  nsSVGFilterFrame *next = GetReferencedFilterIfNotInUse();
+  return next ? next->GetIntegerPairValue(aIndex, aDefault) :
+    &static_cast<SVGFilterElement *>(aDefault)->mIntegerPairAttributes[aIndex];
+}
+
 const nsSVGLength2 *
 nsSVGFilterFrame::GetLengthValue(uint32_t aIndex, nsIContent *aDefault)
 {
   const nsSVGLength2 *thisLength =
     &static_cast<SVGFilterElement *>(mContent)->mLengthAttributes[aIndex];
 
   if (thisLength->IsExplicitlySet())
     return thisLength;
@@ -166,16 +182,17 @@ nsSVGFilterFrame::AttributeChanged(int32
                                    nsIAtom* aAttribute,
                                    int32_t  aModType)
 {
   if (aNameSpaceID == kNameSpaceID_None &&
       (aAttribute == nsGkAtoms::x ||
        aAttribute == nsGkAtoms::y ||
        aAttribute == nsGkAtoms::width ||
        aAttribute == nsGkAtoms::height ||
+       aAttribute == nsGkAtoms::filterRes ||
        aAttribute == nsGkAtoms::filterUnits ||
        aAttribute == nsGkAtoms::primitiveUnits)) {
     nsSVGEffects::InvalidateDirectRenderingObservers(this);
   } else if (aNameSpaceID == kNameSpaceID_XLink &&
              aAttribute == nsGkAtoms::href) {
     // Blow away our reference, if any
     Properties().Delete(nsSVGEffects::HrefProperty());
     mNoHRefURI = false;
--- a/layout/svg/nsSVGFilterFrame.h
+++ b/layout/svg/nsSVGFilterFrame.h
@@ -80,16 +80,21 @@ private:
   nsSVGFilterFrame* GetReferencedFilterIfNotInUse();
 
   // Accessors to lookup filter attributes
   uint16_t GetEnumValue(uint32_t aIndex, nsIContent *aDefault);
   uint16_t GetEnumValue(uint32_t aIndex)
   {
     return GetEnumValue(aIndex, mContent);
   }
+  const nsSVGIntegerPair *GetIntegerPairValue(uint32_t aIndex, nsIContent *aDefault);
+  const nsSVGIntegerPair *GetIntegerPairValue(uint32_t aIndex)
+  {
+    return GetIntegerPairValue(aIndex, mContent);
+  }
   const nsSVGLength2 *GetLengthValue(uint32_t aIndex, nsIContent *aDefault);
   const nsSVGLength2 *GetLengthValue(uint32_t aIndex)
   {
     return GetLengthValue(aIndex, mContent);
   }
   const mozilla::dom::SVGFilterElement *GetFilterContent(nsIContent *aDefault);
   const mozilla::dom::SVGFilterElement *GetFilterContent()
   {
--- a/layout/svg/nsSVGFilterInstance.cpp
+++ b/layout/svg/nsSVGFilterInstance.cpp
@@ -47,19 +47,19 @@ nsSVGFilterInstance::nsSVGFilterInstance
 
   mPrimitiveUnits =
     mFilterFrame->GetEnumValue(SVGFilterElement::PRIMITIVEUNITS);
 
   // Get the filter region (in the filtered element's user space):
 
   // XXX if filterUnits is set (or has defaulted) to objectBoundingBox, we
   // should send a warning to the error console if the author has used lengths
-  // with units. This is a common mistake and can result in the filter region
-  // being *massive* below (because we ignore the units and interpret the number
-  // as a factor of the bbox width/height). We should also send a warning if the
+  // with units. This is a common mistake and can result in filterRes being
+  // *massive* below (because we ignore the units and interpret the number as
+  // a factor of the bbox width/height). We should also send a warning if the
   // user uses a number without units (a future SVG spec should really
   // deprecate that, since it's too confusing for a bare number to be sometimes
   // interpreted as a fraction of the bounding box and sometimes as user-space
   // units). So really only percentage values should be used in this case.
   
   nsSVGLength2 XYWH[4];
   NS_ABORT_IF_FALSE(sizeof(mFilterElement->mLengthAttributes) == sizeof(XYWH),
                     "XYWH size incorrect");
@@ -76,41 +76,66 @@ nsSVGFilterInstance::nsSVGFilterInstance
     XYWH, mTargetBBox, mTargetFrame);
 
   if (mFilterRegion.Width() <= 0 || mFilterRegion.Height() <= 0) {
     // 0 disables rendering, < 0 is error. dispatch error console warning
     // or error as appropriate.
     return;
   }
 
-  // Calculate the width and height of the pixel buffer of the
+  // Calculate filterRes (the width and height of the pixel buffer of the
   // temporary offscreen surface that we would/will create to paint into when
-  // painting the entire filtered element and, if necessary, adjust
+  // painting the entire filtered element) and, if necessary, adjust
   // mFilterRegion out slightly so that it aligns with pixel boundaries of this
   // buffer:
 
-  // Match filter space as closely as possible to the pixel density of the
-  // nearest outer 'svg' device space:
-  gfxMatrix canvasTM =
-    nsSVGUtils::GetCanvasTM(mTargetFrame, nsISVGChildFrame::FOR_OUTERSVG_TM);
-  if (canvasTM.IsSingular()) {
-    // nothing to draw
-    return;
+  gfxIntSize filterRes;
+  const nsSVGIntegerPair* filterResAttrs =
+    mFilterFrame->GetIntegerPairValue(SVGFilterElement::FILTERRES);
+  if (filterResAttrs->IsExplicitlySet()) {
+    int32_t filterResX = filterResAttrs->GetAnimValue(nsSVGIntegerPair::eFirst);
+    int32_t filterResY = filterResAttrs->GetAnimValue(nsSVGIntegerPair::eSecond);
+    if (filterResX <= 0 || filterResY <= 0) {
+      // 0 disables rendering, < 0 is error. dispatch error console warning?
+      return;
+    }
+
+    mFilterRegion.Scale(filterResX, filterResY);
+    mFilterRegion.RoundOut();
+    mFilterRegion.Scale(1.0 / filterResX, 1.0 / filterResY);
+    // We don't care if this overflows, because we can handle upscaling/
+    // downscaling to filterRes
+    bool overflow;
+    filterRes =
+      nsSVGUtils::ConvertToSurfaceSize(gfxSize(filterResX, filterResY),
+                                       &overflow);
+    // XXX we could send a warning to the error console if the author specified
+    // filterRes doesn't align well with our outer 'svg' device space.
+  } else {
+    // Match filterRes as closely as possible to the pixel density of the nearest
+    // outer 'svg' device space:
+    gfxMatrix canvasTM =
+      nsSVGUtils::GetCanvasTM(mTargetFrame, nsISVGChildFrame::FOR_OUTERSVG_TM);
+    if (canvasTM.IsSingular()) {
+      // nothing to draw
+      return;
+    }
+
+    gfxSize scale = canvasTM.ScaleFactors(true);
+    mFilterRegion.Scale(scale.width, scale.height);
+    mFilterRegion.RoundOut();
+    // We don't care if this overflows, because we can handle upscaling/
+    // downscaling to filterRes
+    bool overflow;
+    filterRes = nsSVGUtils::ConvertToSurfaceSize(mFilterRegion.Size(),
+                                                 &overflow);
+    mFilterRegion.Scale(1.0 / scale.width, 1.0 / scale.height);
   }
 
-  gfxSize scale = canvasTM.ScaleFactors(true);
-  mFilterRegion.Scale(scale.width, scale.height);
-  mFilterRegion.RoundOut();
-
-  // We don't care if this overflows, because we can handle upscaling/
-  // downscaling to filter space.
-  bool overflow;
-  mFilterSpaceBounds.SetRect(nsIntPoint(0, 0),
-    nsSVGUtils::ConvertToSurfaceSize(mFilterRegion.Size(), &overflow));
-  mFilterRegion.Scale(1.0 / scale.width, 1.0 / scale.height);
+  mFilterSpaceBounds.SetRect(nsIntPoint(0, 0), filterRes);
 
   mInitialized = true;
 }
 
 nsSVGFilterFrame*
 nsSVGFilterInstance::GetFilterFrame()
 {
   if (mFilter.GetType() != NS_STYLE_FILTER_URL) {
--- a/layout/svg/nsSVGFilterInstance.h
+++ b/layout/svg/nsSVGFilterInstance.h
@@ -69,16 +69,19 @@ public:
    * space, after it has been adjusted out (if necessary) so that its edges
    * coincide with pixel boundaries of the offscreen surface into which the
    * filtered output would/will be painted.
    */
   gfxRect GetFilterRegion() const { return mFilterRegion; }
 
   /**
    * Returns the size of the user specified "filter region", in filter space.
+   * The size will be {filterRes.x by filterRes.y}, whether the user specified
+   * the filter's filterRes attribute explicitly, or the implementation chose
+   * the filterRes values.
    */
   nsIntRect GetFilterSpaceBounds() const { return mFilterSpaceBounds; }
 
   float GetPrimitiveNumber(uint8_t aCtxType, const nsSVGNumber2 *aNumber) const
   {
     return GetPrimitiveNumber(aCtxType, aNumber->GetAnimValue());
   }
   float GetPrimitiveNumber(uint8_t aCtxType, const nsSVGNumberPair *aNumberPair,
--- a/parser/html/javasrc/AttributeName.java
+++ b/parser/html/javasrc/AttributeName.java
@@ -1003,16 +1003,17 @@ public final class AttributeName
     public static final AttributeName AMPLITUDE = new AttributeName(ALL_NO_NS, SAME_LOCAL("amplitude"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
     public static final AttributeName ARIA_LIVE = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-live"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
     public static final AttributeName CLIP_RULE = new AttributeName(ALL_NO_NS, SAME_LOCAL("clip-rule"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
     public static final AttributeName CLIP_PATH = new AttributeName(ALL_NO_NS, SAME_LOCAL("clip-path"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
     public static final AttributeName EQUALROWS = new AttributeName(ALL_NO_NS, SAME_LOCAL("equalrows"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
     public static final AttributeName ELEVATION = new AttributeName(ALL_NO_NS, SAME_LOCAL("elevation"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
     public static final AttributeName DIRECTION = new AttributeName(ALL_NO_NS, SAME_LOCAL("direction"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
     public static final AttributeName DRAGGABLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("draggable"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FILTERRES = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("filterres", "filterRes"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
     public static final AttributeName FILL_RULE = new AttributeName(ALL_NO_NS, SAME_LOCAL("fill-rule"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
     public static final AttributeName FONTSTYLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("fontstyle"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
     public static final AttributeName FONT_SIZE = new AttributeName(ALL_NO_NS, SAME_LOCAL("font-size"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
     public static final AttributeName KEYPOINTS = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("keypoints", "keyPoints"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
     public static final AttributeName HIDEFOCUS = new AttributeName(ALL_NO_NS, SAME_LOCAL("hidefocus"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
     public static final AttributeName ONMESSAGE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onmessage"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
     public static final AttributeName INTERCEPT = new AttributeName(ALL_NO_NS, SAME_LOCAL("intercept"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
     public static final AttributeName ONDRAGEND = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondragend"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
@@ -1584,16 +1585,17 @@ public final class AttributeName
     AMPLITUDE,
     ARIA_LIVE,
     CLIP_RULE,
     CLIP_PATH,
     EQUALROWS,
     ELEVATION,
     DIRECTION,
     DRAGGABLE,
+    FILTERRES,
     FILL_RULE,
     FONTSTYLE,
     FONT_SIZE,
     KEYPOINTS,
     HIDEFOCUS,
     ONMESSAGE,
     INTERCEPT,
     ONDRAGEND,
--- a/parser/html/nsHtml5AtomList.h
+++ b/parser/html/nsHtml5AtomList.h
@@ -353,16 +353,18 @@ HTML5_ATOM(aria_grab, "aria-grab")
 HTML5_ATOM(amplitude, "amplitude")
 HTML5_ATOM(aria_live, "aria-live")
 HTML5_ATOM(clip_rule, "clip-rule")
 HTML5_ATOM(clip_path, "clip-path")
 HTML5_ATOM(equalrows, "equalrows")
 HTML5_ATOM(elevation, "elevation")
 HTML5_ATOM(direction, "direction")
 HTML5_ATOM(draggable, "draggable")
+HTML5_ATOM(filterres, "filterres")
+HTML5_ATOM(filterRes, "filterRes")
 HTML5_ATOM(fill_rule, "fill-rule")
 HTML5_ATOM(fontstyle, "fontstyle")
 HTML5_ATOM(font_size, "font-size")
 HTML5_ATOM(keypoints, "keypoints")
 HTML5_ATOM(keyPoints, "keyPoints")
 HTML5_ATOM(hidefocus, "hidefocus")
 HTML5_ATOM(onmessage, "onmessage")
 HTML5_ATOM(intercept, "intercept")
--- a/parser/html/nsHtml5AttributeName.cpp
+++ b/parser/html/nsHtml5AttributeName.cpp
@@ -1099,16 +1099,17 @@ nsHtml5AttributeName::initializeStatics(
   ATTR_AMPLITUDE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::amplitude), ALL_NO_PREFIX);
   ATTR_ARIA_LIVE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_live), ALL_NO_PREFIX);
   ATTR_CLIP_RULE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::clip_rule), ALL_NO_PREFIX);
   ATTR_CLIP_PATH = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::clip_path), ALL_NO_PREFIX);
   ATTR_EQUALROWS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::equalrows), ALL_NO_PREFIX);
   ATTR_ELEVATION = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::elevation), ALL_NO_PREFIX);
   ATTR_DIRECTION = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::direction), ALL_NO_PREFIX);
   ATTR_DRAGGABLE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::draggable), ALL_NO_PREFIX);
+  ATTR_FILTERRES = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::filterres, nsHtml5Atoms::filterRes), ALL_NO_PREFIX);
   ATTR_FILL_RULE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::fill_rule), ALL_NO_PREFIX);
   ATTR_FONTSTYLE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::fontstyle), ALL_NO_PREFIX);
   ATTR_FONT_SIZE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::font_size), ALL_NO_PREFIX);
   ATTR_KEYPOINTS = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::keypoints, nsHtml5Atoms::keyPoints), ALL_NO_PREFIX);
   ATTR_HIDEFOCUS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::hidefocus), ALL_NO_PREFIX);
   ATTR_ONMESSAGE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onmessage), ALL_NO_PREFIX);
   ATTR_INTERCEPT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::intercept), ALL_NO_PREFIX);
   ATTR_ONDRAGEND = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::ondragend), ALL_NO_PREFIX);
--- a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests11.dat
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests11.dat
@@ -1,10 +1,10 @@
 #data
-<!DOCTYPE html><body><svg attributeName='' attributeType='' baseFrequency='' baseProfile='' calcMode='' clipPathUnits='' contentScriptType='' contentStyleType='' diffuseConstant='' edgeMode='' externalResourcesRequired='' filterUnits='' glyphRef='' gradientTransform='' gradientUnits='' kernelMatrix='' kernelUnitLength='' keyPoints='' keySplines='' keyTimes='' lengthAdjust='' limitingConeAngle='' markerHeight='' markerUnits='' markerWidth='' maskContentUnits='' maskUnits='' numOctaves='' pathLength='' patternContentUnits='' patternTransform='' patternUnits='' pointsAtX='' pointsAtY='' pointsAtZ='' preserveAlpha='' preserveAspectRatio='' primitiveUnits='' refX='' refY='' repeatCount='' repeatDur='' requiredExtensions='' requiredFeatures='' specularConstant='' specularExponent='' spreadMethod='' startOffset='' stdDeviation='' stitchTiles='' surfaceScale='' systemLanguage='' tableValues='' targetX='' targetY='' textLength='' viewBox='' viewTarget='' xChannelSelector='' yChannelSelector='' zoomAndPan=''></svg>
+<!DOCTYPE html><body><svg attributeName='' attributeType='' baseFrequency='' baseProfile='' calcMode='' clipPathUnits='' contentScriptType='' contentStyleType='' diffuseConstant='' edgeMode='' externalResourcesRequired='' filterRes='' filterUnits='' glyphRef='' gradientTransform='' gradientUnits='' kernelMatrix='' kernelUnitLength='' keyPoints='' keySplines='' keyTimes='' lengthAdjust='' limitingConeAngle='' markerHeight='' markerUnits='' markerWidth='' maskContentUnits='' maskUnits='' numOctaves='' pathLength='' patternContentUnits='' patternTransform='' patternUnits='' pointsAtX='' pointsAtY='' pointsAtZ='' preserveAlpha='' preserveAspectRatio='' primitiveUnits='' refX='' refY='' repeatCount='' repeatDur='' requiredExtensions='' requiredFeatures='' specularConstant='' specularExponent='' spreadMethod='' startOffset='' stdDeviation='' stitchTiles='' surfaceScale='' systemLanguage='' tableValues='' targetX='' targetY='' textLength='' viewBox='' viewTarget='' xChannelSelector='' yChannelSelector='' zoomAndPan=''></svg>
 #errors
 #document
 | <!DOCTYPE html>
 | <html>
 |   <head>
 |   <body>
 |     <svg svg>
 |       attributeName=""
@@ -13,16 +13,17 @@
 |       baseProfile=""
 |       calcMode=""
 |       clipPathUnits=""
 |       contentScriptType=""
 |       contentStyleType=""
 |       diffuseConstant=""
 |       edgeMode=""
 |       externalResourcesRequired=""
+|       filterRes=""
 |       filterUnits=""
 |       glyphRef=""
 |       gradientTransform=""
 |       gradientUnits=""
 |       kernelMatrix=""
 |       kernelUnitLength=""
 |       keyPoints=""
 |       keySplines=""
@@ -65,17 +66,17 @@
 |       textLength=""
 |       viewBox=""
 |       viewTarget=""
 |       xChannelSelector=""
 |       yChannelSelector=""
 |       zoomAndPan=""
 
 #data
-<!DOCTYPE html><BODY><SVG ATTRIBUTENAME='' ATTRIBUTETYPE='' BASEFREQUENCY='' BASEPROFILE='' CALCMODE='' CLIPPATHUNITS='' CONTENTSCRIPTTYPE='' CONTENTSTYLETYPE='' DIFFUSECONSTANT='' EDGEMODE='' EXTERNALRESOURCESREQUIRED='' FILTERUNITS='' GLYPHREF='' GRADIENTTRANSFORM='' GRADIENTUNITS='' KERNELMATRIX='' KERNELUNITLENGTH='' KEYPOINTS='' KEYSPLINES='' KEYTIMES='' LENGTHADJUST='' LIMITINGCONEANGLE='' MARKERHEIGHT='' MARKERUNITS='' MARKERWIDTH='' MASKCONTENTUNITS='' MASKUNITS='' NUMOCTAVES='' PATHLENGTH='' PATTERNCONTENTUNITS='' PATTERNTRANSFORM='' PATTERNUNITS='' POINTSATX='' POINTSATY='' POINTSATZ='' PRESERVEALPHA='' PRESERVEASPECTRATIO='' PRIMITIVEUNITS='' REFX='' REFY='' REPEATCOUNT='' REPEATDUR='' REQUIREDEXTENSIONS='' REQUIREDFEATURES='' SPECULARCONSTANT='' SPECULAREXPONENT='' SPREADMETHOD='' STARTOFFSET='' STDDEVIATION='' STITCHTILES='' SURFACESCALE='' SYSTEMLANGUAGE='' TABLEVALUES='' TARGETX='' TARGETY='' TEXTLENGTH='' VIEWBOX='' VIEWTARGET='' XCHANNELSELECTOR='' YCHANNELSELECTOR='' ZOOMANDPAN=''></SVG>
+<!DOCTYPE html><BODY><SVG ATTRIBUTENAME='' ATTRIBUTETYPE='' BASEFREQUENCY='' BASEPROFILE='' CALCMODE='' CLIPPATHUNITS='' CONTENTSCRIPTTYPE='' CONTENTSTYLETYPE='' DIFFUSECONSTANT='' EDGEMODE='' EXTERNALRESOURCESREQUIRED='' FILTERRES='' FILTERUNITS='' GLYPHREF='' GRADIENTTRANSFORM='' GRADIENTUNITS='' KERNELMATRIX='' KERNELUNITLENGTH='' KEYPOINTS='' KEYSPLINES='' KEYTIMES='' LENGTHADJUST='' LIMITINGCONEANGLE='' MARKERHEIGHT='' MARKERUNITS='' MARKERWIDTH='' MASKCONTENTUNITS='' MASKUNITS='' NUMOCTAVES='' PATHLENGTH='' PATTERNCONTENTUNITS='' PATTERNTRANSFORM='' PATTERNUNITS='' POINTSATX='' POINTSATY='' POINTSATZ='' PRESERVEALPHA='' PRESERVEASPECTRATIO='' PRIMITIVEUNITS='' REFX='' REFY='' REPEATCOUNT='' REPEATDUR='' REQUIREDEXTENSIONS='' REQUIREDFEATURES='' SPECULARCONSTANT='' SPECULAREXPONENT='' SPREADMETHOD='' STARTOFFSET='' STDDEVIATION='' STITCHTILES='' SURFACESCALE='' SYSTEMLANGUAGE='' TABLEVALUES='' TARGETX='' TARGETY='' TEXTLENGTH='' VIEWBOX='' VIEWTARGET='' XCHANNELSELECTOR='' YCHANNELSELECTOR='' ZOOMANDPAN=''></SVG>
 #errors
 #document
 | <!DOCTYPE html>
 | <html>
 |   <head>
 |   <body>
 |     <svg svg>
 |       attributeName=""
@@ -84,16 +85,17 @@
 |       baseProfile=""
 |       calcMode=""
 |       clipPathUnits=""
 |       contentScriptType=""
 |       contentStyleType=""
 |       diffuseConstant=""
 |       edgeMode=""
 |       externalResourcesRequired=""
+|       filterRes=""
 |       filterUnits=""
 |       glyphRef=""
 |       gradientTransform=""
 |       gradientUnits=""
 |       kernelMatrix=""
 |       kernelUnitLength=""
 |       keyPoints=""
 |       keySplines=""
@@ -136,17 +138,17 @@
 |       textLength=""
 |       viewBox=""
 |       viewTarget=""
 |       xChannelSelector=""
 |       yChannelSelector=""
 |       zoomAndPan=""
 
 #data
-<!DOCTYPE html><body><svg attributename='' attributetype='' basefrequency='' baseprofile='' calcmode='' clippathunits='' contentscripttype='' contentstyletype='' diffuseconstant='' edgemode='' externalresourcesrequired='' filterunits='' glyphref='' gradienttransform='' gradientunits='' kernelmatrix='' kernelunitlength='' keypoints='' keysplines='' keytimes='' lengthadjust='' limitingconeangle='' markerheight='' markerunits='' markerwidth='' maskcontentunits='' maskunits='' numoctaves='' pathlength='' patterncontentunits='' patterntransform='' patternunits='' pointsatx='' pointsaty='' pointsatz='' preservealpha='' preserveaspectratio='' primitiveunits='' refx='' refy='' repeatcount='' repeatdur='' requiredextensions='' requiredfeatures='' specularconstant='' specularexponent='' spreadmethod='' startoffset='' stddeviation='' stitchtiles='' surfacescale='' systemlanguage='' tablevalues='' targetx='' targety='' textlength='' viewbox='' viewtarget='' xchannelselector='' ychannelselector='' zoomandpan=''></svg>
+<!DOCTYPE html><body><svg attributename='' attributetype='' basefrequency='' baseprofile='' calcmode='' clippathunits='' contentscripttype='' contentstyletype='' diffuseconstant='' edgemode='' externalresourcesrequired='' filterres='' filterunits='' glyphref='' gradienttransform='' gradientunits='' kernelmatrix='' kernelunitlength='' keypoints='' keysplines='' keytimes='' lengthadjust='' limitingconeangle='' markerheight='' markerunits='' markerwidth='' maskcontentunits='' maskunits='' numoctaves='' pathlength='' patterncontentunits='' patterntransform='' patternunits='' pointsatx='' pointsaty='' pointsatz='' preservealpha='' preserveaspectratio='' primitiveunits='' refx='' refy='' repeatcount='' repeatdur='' requiredextensions='' requiredfeatures='' specularconstant='' specularexponent='' spreadmethod='' startoffset='' stddeviation='' stitchtiles='' surfacescale='' systemlanguage='' tablevalues='' targetx='' targety='' textlength='' viewbox='' viewtarget='' xchannelselector='' ychannelselector='' zoomandpan=''></svg>
 #errors
 #document
 | <!DOCTYPE html>
 | <html>
 |   <head>
 |   <body>
 |     <svg svg>
 |       attributeName=""
@@ -155,16 +157,17 @@
 |       baseProfile=""
 |       calcMode=""
 |       clipPathUnits=""
 |       contentScriptType=""
 |       contentStyleType=""
 |       diffuseConstant=""
 |       edgeMode=""
 |       externalResourcesRequired=""
+|       filterRes=""
 |       filterUnits=""
 |       glyphRef=""
 |       gradientTransform=""
 |       gradientUnits=""
 |       kernelMatrix=""
 |       kernelUnitLength=""
 |       keyPoints=""
 |       keySplines=""
@@ -207,17 +210,17 @@
 |       textLength=""
 |       viewBox=""
 |       viewTarget=""
 |       xChannelSelector=""
 |       yChannelSelector=""
 |       zoomAndPan=""
 
 #data
-<!DOCTYPE html><body><math attributeName='' attributeType='' baseFrequency='' baseProfile='' calcMode='' clipPathUnits='' contentScriptType='' contentStyleType='' diffuseConstant='' edgeMode='' externalResourcesRequired='' filterUnits='' glyphRef='' gradientTransform='' gradientUnits='' kernelMatrix='' kernelUnitLength='' keyPoints='' keySplines='' keyTimes='' lengthAdjust='' limitingConeAngle='' markerHeight='' markerUnits='' markerWidth='' maskContentUnits='' maskUnits='' numOctaves='' pathLength='' patternContentUnits='' patternTransform='' patternUnits='' pointsAtX='' pointsAtY='' pointsAtZ='' preserveAlpha='' preserveAspectRatio='' primitiveUnits='' refX='' refY='' repeatCount='' repeatDur='' requiredExtensions='' requiredFeatures='' specularConstant='' specularExponent='' spreadMethod='' startOffset='' stdDeviation='' stitchTiles='' surfaceScale='' systemLanguage='' tableValues='' targetX='' targetY='' textLength='' viewBox='' viewTarget='' xChannelSelector='' yChannelSelector='' zoomAndPan=''></math>
+<!DOCTYPE html><body><math attributeName='' attributeType='' baseFrequency='' baseProfile='' calcMode='' clipPathUnits='' contentScriptType='' contentStyleType='' diffuseConstant='' edgeMode='' externalResourcesRequired='' filterRes='' filterUnits='' glyphRef='' gradientTransform='' gradientUnits='' kernelMatrix='' kernelUnitLength='' keyPoints='' keySplines='' keyTimes='' lengthAdjust='' limitingConeAngle='' markerHeight='' markerUnits='' markerWidth='' maskContentUnits='' maskUnits='' numOctaves='' pathLength='' patternContentUnits='' patternTransform='' patternUnits='' pointsAtX='' pointsAtY='' pointsAtZ='' preserveAlpha='' preserveAspectRatio='' primitiveUnits='' refX='' refY='' repeatCount='' repeatDur='' requiredExtensions='' requiredFeatures='' specularConstant='' specularExponent='' spreadMethod='' startOffset='' stdDeviation='' stitchTiles='' surfaceScale='' systemLanguage='' tableValues='' targetX='' targetY='' textLength='' viewBox='' viewTarget='' xChannelSelector='' yChannelSelector='' zoomAndPan=''></math>
 #errors
 #document
 | <!DOCTYPE html>
 | <html>
 |   <head>
 |   <body>
 |     <math math>
 |       attributename=""
@@ -226,16 +229,17 @@
 |       baseprofile=""
 |       calcmode=""
 |       clippathunits=""
 |       contentscripttype=""
 |       contentstyletype=""
 |       diffuseconstant=""
 |       edgemode=""
 |       externalresourcesrequired=""
+|       filterres=""
 |       filterunits=""
 |       glyphref=""
 |       gradienttransform=""
 |       gradientunits=""
 |       kernelmatrix=""
 |       kernelunitlength=""
 |       keypoints=""
 |       keysplines=""