Backed out changeset c086fca6fc55
authorDão Gottwald <dao@mozilla.com>
Fri, 31 Jul 2009 14:35:48 +0200
changeset 30965 e5de4e7260fe33d1f4c65154b3ef3cf49f952502
parent 30964 c086fca6fc5508a4d4031af7e5756acf2c8929cd
child 30966 042be0229acec2d827beaf6845049f28aa5aa50d
push idunknown
push userunknown
push dateunknown
milestone1.9.2a1pre
backs outc086fca6fc5508a4d4031af7e5756acf2c8929cd
Backed out changeset c086fca6fc55
layout/base/nsCSSRendering.cpp
layout/base/nsCSSRendering.h
layout/base/nsDisplayList.cpp
layout/base/nsPresContext.cpp
layout/generic/nsFrame.cpp
layout/reftests/css-gradients/linear-keywords-ref.html
layout/reftests/css-gradients/linear-keywords.html
layout/reftests/css-gradients/linear-mix-ref.html
layout/reftests/css-gradients/linear-mix.html
layout/reftests/css-gradients/linear-percent-ref.html
layout/reftests/css-gradients/linear-percent.html
layout/reftests/css-gradients/linear-ref.html
layout/reftests/css-gradients/linear.html
layout/reftests/css-gradients/nostops-ref.html
layout/reftests/css-gradients/nostops.html
layout/reftests/css-gradients/onestop-ref.html
layout/reftests/css-gradients/onestop.html
layout/reftests/css-gradients/radial-ref.html
layout/reftests/css-gradients/radial.html
layout/reftests/css-gradients/reftest.list
layout/reftests/css-gradients/twostops-ref.html
layout/reftests/css-gradients/twostops.html
layout/reftests/reftest.list
layout/style/nsCSSDeclaration.cpp
layout/style/nsCSSParser.cpp
layout/style/nsCSSValue.cpp
layout/style/nsCSSValue.h
layout/style/nsComputedDOMStyle.cpp
layout/style/nsComputedDOMStyle.h
layout/style/nsRuleNode.cpp
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
layout/style/test/property_database.js
layout/tables/nsTablePainter.cpp
layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -1508,22 +1508,19 @@ DetermineBackgroundColorInternal(nsPresC
   aDrawBackgroundImage = PR_TRUE;
   aDrawBackgroundColor = PR_TRUE;
 
   if (aFrame->HonorPrintBackgroundSettings()) {
     aDrawBackgroundImage = aPresContext->GetBackgroundImageDraw();
     aDrawBackgroundColor = aPresContext->GetBackgroundColorDraw();
   }
 
-  if (aBackground.BottomLayer().mImage.GetType() == eBackgroundImage_Image) {
-    aBottomImage = aBackground.BottomLayer().mImage.GetImageData();
-    if (!aDrawBackgroundImage || !HaveCompleteBackgroundImage(aBottomImage)) {
-      aBottomImage = nsnull;
-    }
-  } else {
+  aBottomImage = aBackground.BottomLayer().mImage;
+
+  if (!aDrawBackgroundImage || !HaveCompleteBackgroundImage(aBottomImage)) {
     aBottomImage = nsnull;
   }
 
   nscolor bgColor;
   if (aDrawBackgroundColor) {
     bgColor = aBackground.mBackgroundColor;
     if (NS_GET_A(bgColor) == 0)
       aDrawBackgroundColor = PR_FALSE;
@@ -1553,94 +1550,16 @@ nsCSSRendering::DetermineBackgroundColor
   return DetermineBackgroundColorInternal(aPresContext,
                                           aBackground,
                                           aFrame,
                                           drawBackgroundImage,
                                           drawBackgroundColor,
                                           bottomImage);
 }
 
-static gfxFloat
-ConvertGradientValueToPixels(const nsStyleCoord& aCoord,
-                             nscoord aFillLength,
-                             nscoord aAppUnitsPerPixel)
-{
-  switch (aCoord.GetUnit()) {
-    case eStyleUnit_Percent:
-      return aCoord.GetPercentValue() * aFillLength / aAppUnitsPerPixel;
-    case eStyleUnit_Coord:
-      return aCoord.GetCoordValue() / aAppUnitsPerPixel;
-    default:
-      NS_WARNING("Unexpected coord unit");
-      return 0;
-  }
-}
-
-void
-nsCSSRendering::PaintGradient(nsPresContext* aPresContext,
-                              nsIRenderingContext& aRenderingContext,
-                              nsStyleGradient* aGradient,
-                              const nsRect& aDirtyRect,
-                              const nsRect& aOneCellArea,
-                              const nsRect& aFillArea,
-                              PRBool aRepeat)
-{
-  gfxContext *ctx = aRenderingContext.ThebesContext();
-  nscoord appUnitsPerPixel = aPresContext->AppUnitsPerDevPixel();
-
-  gfxRect dirtyRect = RectToGfxRect(aDirtyRect, appUnitsPerPixel);
-  gfxRect areaToFill = RectToGfxRect(aFillArea, appUnitsPerPixel);
-  gfxRect oneCellArea = RectToGfxRect(aOneCellArea, appUnitsPerPixel);
-  gfxPoint fillOrigin = oneCellArea.TopLeft();
-
-  areaToFill = areaToFill.Intersect(dirtyRect);
-  if (areaToFill.IsEmpty())
-    return;
-
-  gfxFloat gradX0 = ConvertGradientValueToPixels(aGradient->mStartX,
-                        aOneCellArea.width, appUnitsPerPixel);
-  gfxFloat gradY0 = ConvertGradientValueToPixels(aGradient->mStartY,
-                        aOneCellArea.height, appUnitsPerPixel);
-  gfxFloat gradX1 = ConvertGradientValueToPixels(aGradient->mEndX,
-                        aOneCellArea.width, appUnitsPerPixel);
-  gfxFloat gradY1 = ConvertGradientValueToPixels(aGradient->mEndY,
-                        aOneCellArea.height, appUnitsPerPixel);
-
-  nsRefPtr<gfxPattern> gradientPattern;
-  if (aGradient->mIsRadial) {
-    gfxFloat gradRadius0 = double(aGradient->mStartRadius) / appUnitsPerPixel;
-    gfxFloat gradRadius1 = double(aGradient->mEndRadius) / appUnitsPerPixel;
-    gradientPattern = new gfxPattern(gradX0, gradY0, gradRadius0,
-                                     gradX1, gradY1, gradRadius1);
-  } else {
-    gradientPattern = new gfxPattern(gradX0, gradY0, gradX1, gradY1);
-  }
-
-  if (!gradientPattern || gradientPattern->CairoStatus())
-    return;
-
-  for (PRUint32 i = 0; i < aGradient->mStops.Length(); i++) {
-    gradientPattern->AddColorStop(aGradient->mStops[i].mPosition,
-                                  gfxRGBA(aGradient->mStops[i].mColor));
-  }
-
-  if (aRepeat)
-    gradientPattern->SetExtend(gfxPattern::EXTEND_REPEAT);
-
-  ctx->Save();
-  ctx->NewPath();
-  // The fill origin is part of the translate call so the pattern starts at
-  // the desired point, rather than (0,0).
-  ctx->Translate(fillOrigin);
-  ctx->SetPattern(gradientPattern);
-  ctx->Rectangle(areaToFill - fillOrigin, PR_TRUE);
-  ctx->Fill();
-  ctx->Restore();
-}
-
 void
 nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
                                       nsIRenderingContext& aRenderingContext,
                                       nsIFrame* aForFrame,
                                       const nsRect& aDirtyRect,
                                       const nsRect& aBorderArea,
                                       const nsStyleBackground& aBackground,
                                       const nsStyleBorder& aBorder,
@@ -1887,16 +1806,36 @@ PaintBackgroundLayer(nsPresContext* aPre
    *   background-image
    *   background-break, background-origin
    *   background-attachment (postfix for background-{origin,break} if 'fixed')
    *   background-size
    *   background-position
    *   background-repeat
    */
 
+  // Lookup the image
+  imgIRequest *req = aLayer.mImage;
+  if (!HaveCompleteBackgroundImage(req))
+    return;
+
+  nsCOMPtr<imgIContainer> image;
+  req->GetImage(getter_AddRefs(image));
+  req = nsnull;
+
+  nsIntSize imageIntSize;
+  image->GetWidth(&imageIntSize.width);
+  image->GetHeight(&imageIntSize.height);
+
+  nsSize imageSize;
+  imageSize.width = nsPresContext::CSSPixelsToAppUnits(imageIntSize.width);
+  imageSize.height = nsPresContext::CSSPixelsToAppUnits(imageIntSize.height);
+
+  if (imageSize.width == 0 || imageSize.height == 0)
+    return;
+
   // relative to aBorderArea
   nsRect bgPositioningArea(0, 0, 0, 0);
 
   nsIAtom* frameType = aForFrame->GetType();
   nsIFrame* geometryFrame = aForFrame;
   if (frameType == nsGkAtoms::inlineFrame ||
       frameType == nsGkAtoms::positionedInlineFrame) {
     // XXXjwalden Strictly speaking this is not quite faithful to how
@@ -1941,42 +1880,16 @@ PaintBackgroundLayer(nsPresContext* aPre
       nsMargin padding = geometryFrame->GetUsedPadding();
       geometryFrame->ApplySkipSides(padding);
       bgPositioningArea.Deflate(padding);
       NS_ASSERTION(aLayer.mOrigin == NS_STYLE_BG_ORIGIN_CONTENT,
                    "unknown background-origin value");
     }
   }
 
-  nsSize imageSize;
-  nsCOMPtr<imgIContainer> image;
-  if (aLayer.mImage.GetType() == eBackgroundImage_Image) {
-    // Lookup the image
-    imgIRequest *req = aLayer.mImage.GetImageData();
-    if (!HaveCompleteBackgroundImage(req))
-      return;
-
-    req->GetImage(getter_AddRefs(image));
-    req = nsnull;
-
-    nsIntSize imageIntSize;
-    image->GetWidth(&imageIntSize.width);
-    image->GetHeight(&imageIntSize.height);
-
-    imageSize.width = nsPresContext::CSSPixelsToAppUnits(imageIntSize.width);
-    imageSize.height = nsPresContext::CSSPixelsToAppUnits(imageIntSize.height);
-  } else if (aLayer.mImage.GetType() == eBackgroundImage_Gradient) {
-    imageSize = bgPositioningArea.Size();
-  } else {
-    return;
-  }
-
-  if (imageSize.width == 0 || imageSize.height == 0)
-    return;
-
   // Compute the anchor point.
   //
   // relative to aBorderArea.TopLeft() (which is where the top-left
   // of aForFrame's border-box will be rendered)
   nsPoint imageTopLeft, anchor, offset;
   if (NS_STYLE_BG_ATTACHMENT_FIXED == aLayer.mAttachment) {
     // If it's a fixed background attachment, then the image is placed
     // relative to the viewport, which is the area of the root frame
@@ -2076,26 +1989,19 @@ PaintBackgroundLayer(nsPresContext* aPre
     fillArea.width = aBGClipRect.width;
   }
   if (repeat & NS_STYLE_BG_REPEAT_Y) {
     fillArea.y = aBGClipRect.y;
     fillArea.height = aBGClipRect.height;
   }
   fillArea.IntersectRect(fillArea, aBGClipRect);
 
-  if (aLayer.mImage.GetType() == eBackgroundImage_Image) {
-    nsLayoutUtils::DrawImage(&aRenderingContext, image,
-        nsLayoutUtils::GetGraphicsFilterForFrame(aForFrame),
-        destArea, fillArea, anchor + aBorderArea.TopLeft(), aDirtyRect);
-  } else {
-    nsCSSRendering::PaintGradient(aPresContext, aRenderingContext,
-                  aLayer.mImage.GetGradientData(),
-                  aDirtyRect, destArea, fillArea,
-                  (repeat != NS_STYLE_BG_REPEAT_OFF));
-  }
+  nsLayoutUtils::DrawImage(&aRenderingContext, image,
+      nsLayoutUtils::GetGraphicsFilterForFrame(aForFrame),
+      destArea, fillArea, anchor + aBorderArea.TopLeft(), aDirtyRect);
 }
 
 static void
 DrawBorderImage(nsPresContext*       aPresContext,
                 nsIRenderingContext& aRenderingContext,
                 nsIFrame*            aForFrame,
                 const nsRect&        aBorderArea,
                 const nsStyleBorder& aBorderStyle,
--- a/layout/base/nsCSSRendering.h
+++ b/layout/base/nsCSSRendering.h
@@ -123,27 +123,16 @@ struct nsCSSRendering {
    * Not used for controls, because the native theme may differ.
    */
   static void PaintFocus(nsPresContext* aPresContext,
                          nsIRenderingContext& aRenderingContext,
                          const nsRect& aFocusRect,
                          nscolor aColor);
 
   /**
-   * Render a gradient for an element.
-   */
-  static void PaintGradient(nsPresContext* aPresContext,
-                            nsIRenderingContext& aRenderingContext,
-                            nsStyleGradient* aGradient,
-                            const nsRect& aDirtyRect,
-                            const nsRect& aOneCellArea,
-                            const nsRect& aFillArea,
-                            PRBool aRepeat);
-
-  /**
    * Gets the root frame for the frame
    */
   static nsIFrame* FindRootFrame(nsIFrame* aForFrame);
 
   /**
    * @return PR_TRUE if |aFrame| is a canvas frame, in the CSS sense.
    */
   static PRBool IsCanvasFrame(nsIFrame* aFrame);
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -557,19 +557,19 @@ nsDisplayBackground::IsOpaque(nsDisplayL
       nsLayoutUtils::HasNonZeroCorner(mFrame->GetStyleBorder()->mBorderRadius))
     return PR_FALSE;
 
   if (NS_GET_A(bg->mBackgroundColor) == 255 &&
       !nsCSSRendering::IsCanvasFrame(mFrame))
     return PR_TRUE;
 
   if (bottomLayer.mRepeat == NS_STYLE_BG_REPEAT_XY) {
-    if (bottomLayer.mImage.GetType() == eBackgroundImage_Image) {
+    if (bottomLayer.mImage) {
       nsCOMPtr<imgIContainer> container;
-      bottomLayer.mImage.GetImageData()->GetImage(getter_AddRefs(container));
+      bottomLayer.mImage->GetImage(getter_AddRefs(container));
       if (container) {
         PRBool animated;
         container->GetAnimated(&animated);
         if (!animated) {
           PRBool isOpaque;
           if (NS_SUCCEEDED(container->GetCurrentFrameIsOpaque(&isOpaque)))
             return isOpaque;
         }
@@ -586,17 +586,17 @@ nsDisplayBackground::IsUniform(nsDisplay
   if (mIsThemed)
     return PR_FALSE;
 
   const nsStyleBackground* bg;
   PRBool hasBG =
     nsCSSRendering::FindBackground(mFrame->PresContext(), mFrame, &bg);
   if (!hasBG)
     return PR_TRUE;
-  if (bg->BottomLayer().mImage.GetType() == eBackgroundImage_Null &&
+  if (!bg->BottomLayer().mImage &&
       bg->mImageCount == 1 &&
       !nsLayoutUtils::HasNonZeroCorner(mFrame->GetStyleBorder()->mBorderRadius) &&
       bg->BottomLayer().mClip == NS_STYLE_BG_CLIP_BORDER)
     return PR_TRUE;
   return PR_FALSE;
 }
 
 PRBool
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -1263,20 +1263,18 @@ nsPresContext::SetImageLoaders(nsIFrame*
 }
 
 void
 nsPresContext::SetupBackgroundImageLoaders(nsIFrame* aFrame,
                                      const nsStyleBackground* aStyleBackground)
 {
   nsRefPtr<nsImageLoader> loaders;
   NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, aStyleBackground) {
-    if (aStyleBackground->mLayers[i].mImage.GetType() == eBackgroundImage_Image) {
-      imgIRequest *image = aStyleBackground->mLayers[i].mImage.GetImageData();
-      loaders = nsImageLoader::Create(aFrame, image, PR_FALSE, loaders);
-    }
+    imgIRequest *image = aStyleBackground->mLayers[i].mImage;
+    loaders = nsImageLoader::Create(aFrame, image, PR_FALSE, loaders);
   }
   SetImageLoaders(aFrame, BACKGROUND_IMAGE, loaders);
 }
 
 void
 nsPresContext::SetupBorderImageLoaders(nsIFrame* aFrame,
                                        const nsStyleBorder* aStyleBorder)
 {
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -527,18 +527,21 @@ nsFrame::DidSetStyleContext(nsStyleConte
     // We want to do this conservatively because some frames paint their
     // backgrounds from some other frame's style data, and we don't want
     // to clear those notifiers unless we have to.  (They'll be reset
     // when we paint, although we could miss a notification in that
     // interval.)
     const nsStyleBackground *oldBG = aOldStyleContext->GetStyleBackground();
     const nsStyleBackground *newBG = GetStyleBackground();
     NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, oldBG) {
-      if (i >= newBG->mImageCount ||
-          oldBG->mLayers[i].mImage != newBG->mLayers[i].mImage) {
+      imgIRequest *oldImage = oldBG->mLayers[i].mImage;
+      imgIRequest *newImage = i < newBG->mImageCount
+                                ? newBG->mLayers[i].mImage.get()
+                                : nsnull;
+      if (oldImage && !EqualImages(oldImage, newImage)) {
         // stop the image loading for the frame, the image has changed
         PresContext()->SetImageLoaders(this,
           nsPresContext::BACKGROUND_IMAGE, nsnull);
         break;
       }
     }
   }
 
@@ -4084,17 +4087,17 @@ nsIFrame::CheckInvalidateSizeChange(cons
     }
   }
 
   // Invalidate the old frame background if the frame has a background
   // whose position depends on the size of the frame
   const nsStyleBackground *bg = GetStyleBackground();
   NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, bg) {
     const nsStyleBackground::Layer &layer = bg->mLayers[i];
-    if (layer.mImage.GetType() != eBackgroundImage_Null &&
+    if (layer.mImage &&
         (layer.mPosition.mXIsPercent || layer.mPosition.mYIsPercent)) {
       Invalidate(nsRect(0, 0, aOldRect.width, aOldRect.height));
       return;
     }
   }
 }
 
 // Define the MAX_FRAME_DEPTH to be the ContentSink's MAX_REFLOW_DEPTH plus
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-keywords-ref.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml" 
-      class="reftest-wait">
-<head>
-<script>
-function doDraw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  var grad = ctx.createLinearGradient(0,0,150,300);
-  grad.addColorStop(0, '#0000ff');
-  grad.addColorStop(1, '#000000');
-
-  ctx.fillStyle = grad;
-  ctx.fillRect(0,0,300,300);
-
-  document.documentElement.removeAttribute('class');
-}
-</script>
-</head>
-<body onload="doDraw();">
-<canvas id="canvas" width="300" height="300"/>
-</body>
-</html>
-
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-keywords.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: -moz-linear-gradient(left top, center bottom, from(#0000ff), to(#000000)) no-repeat; width: 300px; height: 300px;"><br></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-mix-ref.html
+++ /dev/null
@@ -1,34 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml" 
-      class="reftest-wait">
-<head>
-<script>
-function doDraw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  var grad = ctx.createLinearGradient(150,20,270,130);
-  grad.addColorStop(0, '#0000ff');
-  grad.addColorStop(1, '#000000');
-
-  ctx.fillStyle = grad;
-  ctx.fillRect(0,0,300,300);
-
-  ctx = document.getElementById('canvas2').getContext('2d');
-
-  grad = ctx.createLinearGradient(30,300,300,50);
-  grad.addColorStop(0, '#00ff00');
-  grad.addColorStop(1, '#000000');
-
-  ctx.fillStyle = grad;
-  ctx.fillRect(0,0,300,300);
-
-  document.documentElement.removeAttribute('class');
-}
-</script>
-</head>
-<body onload="doDraw();">
-<canvas id="canvas" width="300" height="300"></canvas>
-<br/><br/>
-<canvas id="canvas2" width="300" height="300"></canvas>
-</body>
-</html>
-
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-mix.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<div style="background: -moz-linear-gradient(center 20px, 90% 130px, from(#0000ff), to(#000000)) no-repeat; width: 300px; height: 300px;"><br></div>
-<br>
-<div style="background: -moz-linear-gradient(10% bottom, right 50px, from(#00ff00), to(#000000)) no-repeat; width: 300px; height: 300px;"><br></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-percent-ref.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml" 
-      class="reftest-wait">
-<head>
-<script>
-function doDraw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  var grad = ctx.createLinearGradient(30,60,240,270);
-  grad.addColorStop(0, '#0000ff');
-  grad.addColorStop(1, '#000000');
-
-  ctx.fillStyle = grad;
-  ctx.fillRect(0,0,300,300);
-
-  document.documentElement.removeAttribute('class');
-}
-</script>
-</head>
-<body onload="doDraw();">
-<canvas id="canvas" width="300" height="300"/>
-</body>
-</html>
-
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-percent.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: -moz-linear-gradient(10% 20%, 80% 90%, from(#0000ff), to(#000000)) no-repeat; width: 300px; height: 300px;"><br></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-ref.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml" 
-      class="reftest-wait">
-<head>
-<script>
-function doDraw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  var grad = ctx.createLinearGradient(10,20,50,100);
-  grad.addColorStop(0, 'red');
-  grad.addColorStop(1, 'rgb(100, 200, 0)');
-  grad.addColorStop(0.5, '#7777FF');
-
-  ctx.fillStyle = grad;
-  ctx.fillRect(0,0,300,300);
-
-  document.documentElement.removeAttribute('class');
-}
-</script>
-</head>
-<body onload="doDraw();">
-<canvas id="canvas" width="300" height="300"/>
-</body>
-</html>
-
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: -moz-linear-gradient(10px 20px, 50px 100px, from(red), to(rgb(100, 200, 0)), color-stop(0.5, #7777FF)) no-repeat; width: 300px; height: 300px;"><br></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/nostops-ref.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml" 
-      class="reftest-wait">
-<head>
-<script>
-function doDraw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  var grad = ctx.createLinearGradient(0,0,150,300);
-
-  ctx.fillStyle = grad;
-  ctx.fillRect(0,0,300,300);
-
-  document.documentElement.removeAttribute('class');
-}
-</script>
-</head>
-<body onload="doDraw();">
-<canvas id="canvas" width="300" height="300"/>
-</body>
-</html>
-
deleted file mode 100644
--- a/layout/reftests/css-gradients/nostops.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: -moz-linear-gradient(left top, center bottom) no-repeat; width: 300px; height: 300px;"><br></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/onestop-ref.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml" 
-      class="reftest-wait">
-<head>
-<script>
-function doDraw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  var grad = ctx.createLinearGradient(0,0,150,300);
-  grad.addColorStop(0.5, '#0000ff');
-
-  ctx.fillStyle = grad;
-  ctx.fillRect(0,0,300,300);
-
-  document.documentElement.removeAttribute('class');
-}
-</script>
-</head>
-<body onload="doDraw();">
-<canvas id="canvas" width="300" height="300"/>
-</body>
-</html>
-
deleted file mode 100644
--- a/layout/reftests/css-gradients/onestop.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: -moz-linear-gradient(left top, center bottom, color-stop(0.5, #0000ff)) no-repeat; width: 300px; height: 300px;"><br></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/radial-ref.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml" 
-      class="reftest-wait">
-<head>
-<script>
-function doDraw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  var radgrad = ctx.createRadialGradient(45,45,10,52,50,30);
-  radgrad.addColorStop(0, '#A7D30C');
-  radgrad.addColorStop(0.9, '#019F62');
-  radgrad.addColorStop(1, 'rgba(1,159,98,0)');
-
-  ctx.fillStyle = radgrad;
-  ctx.fillRect(0,0,150,150);
-
-  document.documentElement.removeAttribute('class');
-}
-</script>
-</head>
-<body onload="doDraw();">
-<canvas id="canvas" width="300" height="300"/>
-</body>
-</html>
-
deleted file mode 100644
--- a/layout/reftests/css-gradients/radial.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: -moz-radial-gradient(45px 45px, 10px, 52px 50px, 30px, from(#a7d30c), color-stop(90%, #019f62), to(rgba(1, 159, 98, 0))) no-repeat; width: 300px; height: 300px;"><br></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/reftest.list
+++ /dev/null
@@ -1,8 +0,0 @@
-== linear.html linear-ref.html
-== radial.html radial-ref.html
-== linear-keywords.html linear-keywords-ref.html
-== linear-percent.html linear-percent-ref.html
-== linear-mix.html linear-mix-ref.html
-== nostops.html nostops-ref.html
-== onestop.html onestop-ref.html
-== twostops.html twostops-ref.html
deleted file mode 100644
--- a/layout/reftests/css-gradients/twostops-ref.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml" 
-      class="reftest-wait">
-<head>
-<script>
-function doDraw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  var grad = ctx.createLinearGradient(0,0,150,300);
-  grad.addColorStop(0.5, '#0000ff');
-  grad.addColorStop(0.5, '#ff0000');
-
-  ctx.fillStyle = grad;
-  ctx.fillRect(0,0,300,300);
-
-  document.documentElement.removeAttribute('class');
-}
-</script>
-</head>
-<body onload="doDraw();">
-<canvas id="canvas" width="300" height="300"/>
-</body>
-</html>
-
deleted file mode 100644
--- a/layout/reftests/css-gradients/twostops.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: -moz-linear-gradient(left top, center bottom, color-stop(0.5, #0000ff), color-stop(0.5, #ff0000)) no-repeat; width: 300px; height: 300px;"><br></div>
--- a/layout/reftests/reftest.list
+++ b/layout/reftests/reftest.list
@@ -36,19 +36,16 @@ include bugs/reftest.list
 include canvas/reftest.list
 
 # css @import tests
 include css-import/reftest.list
 
 # css character encoding tests
 include css-charset/reftest.list
 
-# css gradients
-include css-gradients/reftest.list
-
 # css media queries (tests for print mode)
 include css-mediaqueries/reftest.list
 
 # css values and units
 include css-valuesandunits/reftest.list
 
 # columns/
 include columns/reftest.list
--- a/layout/style/nsCSSDeclaration.cpp
+++ b/layout/style/nsCSSDeclaration.cpp
@@ -408,59 +408,16 @@ nsCSSDeclaration::AppendCSSValueToString
     tmpStr.AppendFloat(aValue.GetPercentValue() * 100.0f);
     aResult.Append(tmpStr);
   }
   else if (eCSSUnit_Percent < unit) {  // length unit
     nsAutoString tmpStr;
     tmpStr.AppendFloat(aValue.GetFloatValue());
     aResult.Append(tmpStr);
   }
-  else if (eCSSUnit_Gradient == unit) {
-    nsCSSValueGradient* gradient = aValue.GetGradientValue();
-
-    if (gradient->mIsRadial)
-      aResult.AppendLiteral("-moz-radial-gradient(");
-    else
-      aResult.AppendLiteral("-moz-linear-gradient(");
-
-    AppendCSSValueToString(eCSSProperty_background_position,
-                           gradient->mStartX, aResult);
-    aResult.AppendLiteral(" ");
-
-    AppendCSSValueToString(eCSSProperty_background_position,
-                           gradient->mStartY, aResult);
-    aResult.AppendLiteral(", ");
-
-    if (gradient->mIsRadial) {
-      AppendCSSValueToString(aProperty, gradient->mStartRadius, aResult);
-      aResult.AppendLiteral(", ");
-    }
-
-    AppendCSSValueToString(eCSSProperty_background_position,
-                           gradient->mEndX, aResult);
-    aResult.AppendLiteral(" ");
-
-    AppendCSSValueToString(eCSSProperty_background_position,
-                           gradient->mEndY, aResult);
-
-    if (gradient->mIsRadial) {
-      aResult.AppendLiteral(", ");
-      AppendCSSValueToString(aProperty, gradient->mEndRadius, aResult);
-    }
-
-    for (PRUint32 i = 0; i < gradient->mStops.Length(); i++) {
-      aResult.AppendLiteral(", color-stop(");
-      AppendCSSValueToString(aProperty, gradient->mStops[i].mLocation, aResult);
-      aResult.AppendLiteral(", ");
-      AppendCSSValueToString(aProperty, gradient->mStops[i].mColor, aResult);
-      aResult.AppendLiteral(")");
-    }
-
-    aResult.AppendLiteral(")");
-  }
 
   switch (unit) {
     case eCSSUnit_Null:         break;
     case eCSSUnit_Auto:         aResult.AppendLiteral("auto");     break;
     case eCSSUnit_Inherit:      aResult.AppendLiteral("inherit");  break;
     case eCSSUnit_Initial:      aResult.AppendLiteral("-moz-initial"); break;
     case eCSSUnit_None:         aResult.AppendLiteral("none");     break;
     case eCSSUnit_Normal:       aResult.AppendLiteral("normal");   break;
@@ -484,17 +441,16 @@ nsCSSDeclaration::AppendCSSValueToString
     case eCSSUnit_Font_Format:  break;
     case eCSSUnit_Function:     break;
     case eCSSUnit_Integer:      break;
     case eCSSUnit_Enumerated:   break;
     case eCSSUnit_EnumColor:    break;
     case eCSSUnit_Color:        break;
     case eCSSUnit_Percent:      aResult.Append(PRUnichar('%'));    break;
     case eCSSUnit_Number:       break;
-    case eCSSUnit_Gradient:     break;
 
     case eCSSUnit_Inch:         aResult.AppendLiteral("in");   break;
     case eCSSUnit_Millimeter:   aResult.AppendLiteral("mm");   break;
     case eCSSUnit_Centimeter:   aResult.AppendLiteral("cm");   break;
     case eCSSUnit_Point:        aResult.AppendLiteral("pt");   break;
     case eCSSUnit_Pica:         aResult.AppendLiteral("pc");   break;
 
     case eCSSUnit_EM:           aResult.AppendLiteral("em");   break;
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -61,16 +61,17 @@
 #include "nsNetUtil.h"
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsUnicharUtils.h"
 #include "nsIAtom.h"
 #include "nsCOMArray.h"
 #include "nsColor.h"
+#include "nsStyleConsts.h"
 #include "nsCSSPseudoClasses.h"
 #include "nsCSSPseudoElements.h"
 #include "nsCSSAnonBoxes.h"
 #include "nsINameSpaceManager.h"
 #include "nsXMLNameSpaceMap.h"
 #include "nsThemeConstants.h"
 #include "nsContentErrors.h"
 #include "nsPrintfCString.h"
@@ -101,17 +102,16 @@
 #define VARIANT_COUNTER         0x000800  //
 #define VARIANT_ATTR            0x001000  //
 #define VARIANT_IDENTIFIER      0x002000  // D
 #define VARIANT_AUTO            0x010000  // A
 #define VARIANT_INHERIT         0x020000  // H eCSSUnit_Initial, eCSSUnit_Inherit
 #define VARIANT_NONE            0x040000  // O
 #define VARIANT_NORMAL          0x080000  // M
 #define VARIANT_SYSFONT         0x100000  // eCSSUnit_System_Font
-#define VARIANT_GRADIENT        0x200000  // eCSSUnit_Gradient
 
 // Common combinations of variants
 #define VARIANT_AL   (VARIANT_AUTO | VARIANT_LENGTH)
 #define VARIANT_LP   (VARIANT_LENGTH | VARIANT_PERCENT)
 #define VARIANT_AH   (VARIANT_AUTO | VARIANT_INHERIT)
 #define VARIANT_AHLP (VARIANT_AH | VARIANT_LP)
 #define VARIANT_AHI  (VARIANT_AH | VARIANT_INTEGER)
 #define VARIANT_AHK  (VARIANT_AH | VARIANT_KEYWORD)
@@ -417,17 +417,17 @@ protected:
     nsCSSValue BackgroundItem::*member;
     nsCSSProperty propID;
   };
 
   PRBool ParseBackgroundItem(BackgroundItem& aItem, PRBool aFirstItem);
 
   PRBool ParseBackgroundList(nsCSSProperty aPropID); // a single value prop-id
   PRBool ParseBackgroundPosition();
-  PRBool ParseBoxPositionValues(nsCSSValuePair& aOut, PRBool aAcceptsInherit);
+  PRBool ParseBoxPositionValues(nsCSSValuePair& aOut);
   PRBool ParseBackgroundSize();
   PRBool ParseBackgroundSizeValues(nsCSSValuePair& aOut);
   PRBool ParseBorderColor();
   PRBool ParseBorderColors(nsCSSValueList** aResult,
                            nsCSSProperty aProperty);
   PRBool ParseBorderImage();
   PRBool ParseBorderSpacing();
   PRBool ParseBorderSide(const nsCSSProperty aPropIDs[],
@@ -505,18 +505,16 @@ protected:
   PRBool ParsePositiveNonZeroVariant(nsCSSValue& aValue,
                                      PRInt32 aVariantMask,
                                      const PRInt32 aKeywordTable[]);
   PRBool ParseCounter(nsCSSValue& aValue);
   PRBool ParseAttr(nsCSSValue& aValue);
   PRBool ParseURL(nsCSSValue& aValue);
   PRBool TranslateDimension(nsCSSValue& aValue, PRInt32 aVariantMask,
                             float aNumber, const nsString& aUnit);
-  PRBool ParseGradientStop(nsCSSValueGradient* aGradient);
-  PRBool ParseGradient(nsCSSValue& aValue, PRBool aIsRadial);
 
   void SetParsingCompoundProperty(PRBool aBool) {
     NS_ASSERTION(aBool == PR_TRUE || aBool == PR_FALSE, "bad PRBool value");
     mParsingCompoundProperty = aBool;
   }
   PRBool IsParsingCompoundProperty(void) const {
     return mParsingCompoundProperty;
   }
@@ -4510,25 +4508,16 @@ CSSParserImpl::ParseVariant(nsCSSValue& 
   if (((aVariantMask & VARIANT_URL) != 0) &&
       (eCSSToken_Function == tk->mType) &&
       tk->mIdent.LowerCaseEqualsLiteral("url")) {
     if (ParseURL(aValue)) {
       return PR_TRUE;
     }
     return PR_FALSE;
   }
-  if ((aVariantMask & VARIANT_GRADIENT) != 0 &&
-      eCSSToken_Function == tk->mType) {
-    // a generated gradient
-    if (tk->mIdent.LowerCaseEqualsLiteral("-moz-linear-gradient"))
-      return ParseGradient(aValue, PR_FALSE);
-
-    if (tk->mIdent.LowerCaseEqualsLiteral("-moz-radial-gradient"))
-      return ParseGradient(aValue, PR_TRUE);
-  }
   if ((aVariantMask & VARIANT_COLOR) != 0) {
     if ((mNavQuirkMode && !IsParsingCompoundProperty()) || // NONSTANDARD: Nav interprets 'xxyyzz' values even without '#' prefix
         (eCSSToken_ID == tk->mType) ||
         (eCSSToken_Ref == tk->mType) ||
         (eCSSToken_Ident == tk->mType) ||
         ((eCSSToken_Function == tk->mType) &&
          (tk->mIdent.LowerCaseEqualsLiteral("rgb") ||
           tk->mIdent.LowerCaseEqualsLiteral("hsl") ||
@@ -4768,191 +4757,16 @@ CSSParserImpl::ParseURL(nsCSSValue& aVal
   if (NS_UNLIKELY(!urlVal)) {
     mScanner.SetLowLevelError(NS_ERROR_OUT_OF_MEMORY);
     return PR_FALSE;
   }
   aValue.SetURLValue(urlVal);
   return PR_TRUE;
 }
 
-PRBool
-CSSParserImpl::ParseGradientStop(nsCSSValueGradient* aGradient)
-{
-  if (!GetToken(PR_TRUE))
-    return PR_FALSE;
-
-  if (eCSSToken_Function != mToken.mType) {
-    UngetToken();
-    return PR_FALSE;
-  }
-
-  if (mToken.mIdent.LowerCaseEqualsLiteral("from")) {
-    // Start of the gradient
-    if (!ExpectSymbol('(', PR_FALSE)) {
-      NS_ABORT_IF_FALSE(PR_FALSE, "function token without (");
-    }
-
-    nsCSSValue fromFloat(0.0f, eCSSUnit_Percent);
-    nsCSSValue fromColor;
-    if (!ParseVariant(fromColor, VARIANT_COLOR, nsnull)) {
-      SkipUntil(')');
-      return PR_FALSE;
-    }
-
-    if (!ExpectSymbol(')', PR_TRUE)) {
-      SkipUntil(')');
-      return PR_FALSE;
-    }
-
-    aGradient->mStops.AppendElement(nsCSSValueGradientStop(fromFloat, fromColor));
-    return PR_TRUE;
-  }
-
-  if (mToken.mIdent.LowerCaseEqualsLiteral("to")) {
-    // End of the gradient
-    if (!ExpectSymbol('(', PR_FALSE)) {
-      NS_ABORT_IF_FALSE(PR_FALSE, "function token without (");
-    }
-
-    nsCSSValue toFloat(1.0f, eCSSUnit_Percent);
-    nsCSSValue toColor;
-    if (!ParseVariant(toColor, VARIANT_COLOR, nsnull)) {
-      SkipUntil(')');
-      return PR_FALSE;
-    }
-
-    if (!ExpectSymbol(')', PR_TRUE)) {
-      SkipUntil(')');
-      return PR_FALSE;
-    }
-
-    aGradient->mStops.AppendElement(nsCSSValueGradientStop(toFloat, toColor));
-    return PR_TRUE;
-  }
-
-  if (mToken.mIdent.LowerCaseEqualsLiteral("color-stop")) {
-    // Some kind of gradient stop, somewhere...
-    if (!ExpectSymbol('(', PR_FALSE)) {
-      NS_ABORT_IF_FALSE(PR_FALSE, "function token without (");
-    }
-
-    nsCSSValue stopFloat;
-    if (!ParseVariant(stopFloat, VARIANT_PERCENT | VARIANT_NUMBER, nsnull)) {
-      SkipUntil(')');
-      return PR_FALSE;
-    }
-
-    // Check for a sane position value, and clamp it if it isn't
-    if (stopFloat.GetUnit() == eCSSUnit_Percent) {
-      if (stopFloat.GetPercentValue() > 1.0)
-        stopFloat.SetPercentValue(1.0);
-      else if (stopFloat.GetPercentValue() < 0.0)
-        stopFloat.SetPercentValue(0.0);
-    } else {
-      if (stopFloat.GetFloatValue() > 1.0)
-        stopFloat.SetFloatValue(1.0, eCSSUnit_Number);
-      else if (stopFloat.GetFloatValue() < 0.0)
-        stopFloat.SetFloatValue(0.0, eCSSUnit_Number);
-    }
-
-    if (!ExpectSymbol(',', PR_TRUE)) {
-      SkipUntil(')');
-      return PR_FALSE;
-    }
-
-    nsCSSValue stopColor;
-    if (!ParseVariant(stopColor, VARIANT_COLOR, nsnull)) {
-      SkipUntil(')');
-      return PR_FALSE;
-    }
-
-    if (!ExpectSymbol(')', PR_TRUE)) {
-      SkipUntil(')');
-      return PR_FALSE;
-    }
-
-    aGradient->mStops.AppendElement(nsCSSValueGradientStop(stopFloat, stopColor));
-    return PR_TRUE;
-  }
-
-  // No idea what this is
-  return PR_FALSE;
-}
-
-PRBool
-CSSParserImpl::ParseGradient(nsCSSValue& aValue,
-                             PRBool aIsRadial)
-{
-  if (!ExpectSymbol('(', PR_FALSE)) {
-    NS_ABORT_IF_FALSE(PR_FALSE, "function token without (");
-  }
-
-  nsCSSValuePair startPos;
-  if (!ParseBoxPositionValues(startPos, PR_FALSE))
-    return PR_FALSE;
-
-  if (!ExpectSymbol(',', PR_TRUE)) {
-    SkipUntil(')');
-    return PR_FALSE;
-  }
-
-  nsCSSValue startRadius;
-  if (aIsRadial) {
-    if (!ParseNonNegativeVariant(startRadius, VARIANT_LENGTH, nsnull)) {
-      SkipUntil(')');
-      return PR_FALSE;
-    }
-
-    if (!ExpectSymbol(',', PR_TRUE)) {
-      SkipUntil(')');
-      return PR_FALSE;
-    }
-  }
-
-  nsCSSValuePair endPos;
-  if (!ParseBoxPositionValues(endPos, PR_FALSE)) {
-    SkipUntil(')');
-    return PR_FALSE;
-  }
-
-  nsCSSValue endRadius;
-  if (aIsRadial) {
-    if (!ExpectSymbol(',', PR_TRUE)) {
-      SkipUntil(')');
-      return PR_FALSE;
-    }
-
-    if (!ParseNonNegativeVariant(endRadius, VARIANT_LENGTH, nsnull)) {
-      SkipUntil(')');
-      return PR_FALSE;
-    }
-  }
-
-  nsRefPtr<nsCSSValueGradient> cssGradient =
-    new nsCSSValueGradient(aIsRadial, startPos.mXValue, startPos.mYValue,
-                           startRadius, endPos.mXValue, endPos.mYValue,
-                           endRadius);
-
-  // Do optional stop functions
-  while (ExpectSymbol(',', PR_TRUE)) {
-    if (!ParseGradientStop(cssGradient)) {
-      SkipUntil(')');
-      return PR_FALSE;
-    }
-  }
-
-  if (!ExpectSymbol(')', PR_TRUE)) {
-    SkipUntil(')');
-    return PR_FALSE;
-  }
-
-  aValue.SetGradientValue(cssGradient);
-  return PR_TRUE;
-}
-
 PRInt32
 CSSParserImpl::ParseChoice(nsCSSValue aValues[],
                            const nsCSSProperty aPropIDs[], PRInt32 aNumIDs)
 {
   PRInt32 found = 0;
   nsAutoParseCompoundProperty compound(this);
 
   PRInt32 loop;
@@ -5602,17 +5416,17 @@ CSSParserImpl::ParseSingleValueProperty(
   case eCSSProperty__moz_background_clip:
     // Used only internally.
     return ParseVariant(aValue, VARIANT_HK,
                         nsCSSProps::kBackgroundClipKTable);
   case eCSSProperty_background_color:
     return ParseVariant(aValue, VARIANT_HC, nsnull);
   case eCSSProperty_background_image:
     // Used only internally.
-    return ParseVariant(aValue, VARIANT_HUO | VARIANT_GRADIENT, nsnull);
+    return ParseVariant(aValue, VARIANT_HUO, nsnull);
   case eCSSProperty__moz_background_inline_policy:
     return ParseVariant(aValue, VARIANT_HK,
                         nsCSSProps::kBackgroundInlinePolicyKTable);
   case eCSSProperty__moz_background_origin:
     // Used only internally.
     return ParseVariant(aValue, VARIANT_HK,
                         nsCSSProps::kBackgroundOriginKTable);
   case eCSSProperty_background_repeat:
@@ -6336,17 +6150,17 @@ CSSParserImpl::ParseBackgroundItem(CSSPa
           NS_NOTREACHED("should be able to parse");
           return PR_FALSE;
         }
       } else if (nsCSSProps::FindKeyword(keyword,
                    nsCSSProps::kBackgroundPositionKTable, dummy)) {
         if (havePosition)
           return PR_FALSE;
         havePosition = PR_TRUE;
-        if (!ParseBoxPositionValues(aItem.mPosition, PR_FALSE)) {
+        if (!ParseBoxPositionValues(aItem.mPosition)) {
           return PR_FALSE;
         }
 #if 0
     // This is commented out for now until we change
     // -moz-background-clip to background-clip, -moz-background-origin
     // to background-origin, change their value names to *-box, and add
     // support for content-box on background-clip.
       } else if (nsCSSProps::FindKeyword(keyword,
@@ -6383,31 +6197,29 @@ CSSParserImpl::ParseBackgroundItem(CSSPa
         haveColor = PR_TRUE;
         if (!ParseSingleValueProperty(mTempData.mColor.mBackColor,
                                       eCSSProperty_background_color)) {
           return PR_FALSE;
         }
         aItem.mLastItem = PR_TRUE;
       }
     } else if (eCSSToken_Function == tt &&
-               (mToken.mIdent.LowerCaseEqualsLiteral("url") ||
-                mToken.mIdent.LowerCaseEqualsLiteral("-moz-linear-gradient") ||
-                mToken.mIdent.LowerCaseEqualsLiteral("-moz-radial-gradient"))) {
+               mToken.mIdent.LowerCaseEqualsLiteral("url")) {
       if (haveImage)
         return PR_FALSE;
       haveImage = PR_TRUE;
       if (!ParseSingleValueProperty(aItem.mImage,
                                     eCSSProperty_background_image)) {
         return PR_FALSE;
       }
     } else if (mToken.IsDimension() || tt == eCSSToken_Percentage) {
       if (havePosition)
         return PR_FALSE;
       havePosition = PR_TRUE;
-      if (!ParseBoxPositionValues(aItem.mPosition, PR_FALSE)) {
+      if (!ParseBoxPositionValues(aItem.mPosition)) {
         return PR_FALSE;
       }
     } else {
       if (haveColor)
         return PR_FALSE;
       haveColor = PR_TRUE;
       // Note: This parses 'inherit' and 'initial', but
       // we've already checked for them, so it's ok.
@@ -6468,21 +6280,25 @@ CSSParserImpl::ParseBackgroundList(nsCSS
 // This function is very similar to ParseBackgroundList and ParseBackgroundSize.
 PRBool
 CSSParserImpl::ParseBackgroundPosition()
 {
   // aPropID is a single value prop-id
   nsCSSValuePair valuePair;
   nsCSSValuePairList *head = nsnull, **tail = &head;
   for (;;) {
-    if (!ParseBoxPositionValues(valuePair, !head)) {
+    if (!ParseBoxPositionValues(valuePair)) {
       break;
     }
     PRBool inheritOrInitial = valuePair.mXValue.GetUnit() == eCSSUnit_Inherit ||
                               valuePair.mXValue.GetUnit() == eCSSUnit_Initial;
+    if (inheritOrInitial && head) {
+      // inherit and initial are only allowed on their own
+      break;
+    }
     nsCSSValuePairList *item = new nsCSSValuePairList;
     if (!item) {
       mScanner.SetLowLevelError(NS_ERROR_OUT_OF_MEMORY);
       break;
     }
     item->mXValue = valuePair.mXValue;
     item->mYValue = valuePair.mYValue;
     *tail = item;
@@ -6502,27 +6318,24 @@ CSSParserImpl::ParseBackgroundPosition()
 }
 
 /**
  * Parses two values that correspond to positions in a box.  These can be
  * values corresponding to percentages of the box, raw offsets, or keywords
  * like "top," "left center," etc.
  *
  * @param aOut The nsCSSValuePair in which to place the result.
- * @param aAcceptsInherit If true, 'inherit' and 'initial' are legal values
  * @return Whether or not the operation succeeded.
  */
-PRBool CSSParserImpl::ParseBoxPositionValues(nsCSSValuePair &aOut,
-                                             PRBool aAcceptsInherit)
+PRBool CSSParserImpl::ParseBoxPositionValues(nsCSSValuePair &aOut)
 {
   // First try a percentage or a length value
   nsCSSValue &xValue = aOut.mXValue,
              &yValue = aOut.mYValue;
-  PRInt32 variantMask = aAcceptsInherit ? VARIANT_HLP : VARIANT_LP;
-  if (ParseVariant(xValue, variantMask, nsnull)) {
+  if (ParseVariant(xValue, VARIANT_HLP, nsnull)) {
     if (eCSSUnit_Inherit == xValue.GetUnit() ||
         eCSSUnit_Initial == xValue.GetUnit()) {  // both are inherited or both are set to initial
       yValue = xValue;
       return PR_TRUE;
     }
     // We have one percentage/length. Get the optional second
     // percentage/length/keyword.
     if (ParseVariant(yValue, VARIANT_LP, nsnull)) {
@@ -7767,17 +7580,17 @@ PRBool CSSParserImpl::ParseMozTransform(
   mTempData.mDisplay.mTransform = transformList;
 
   return PR_TRUE;
 }
 
 PRBool CSSParserImpl::ParseMozTransformOrigin()
 {
   /* Read in a box position, fail if we can't. */
-  if (!ParseBoxPositionValues(mTempData.mDisplay.mTransformOrigin, PR_TRUE) ||
+  if (!ParseBoxPositionValues(mTempData.mDisplay.mTransformOrigin) ||
       !ExpectEndProperty())
     return PR_FALSE;
 
   /* Set the property bit and return. */
   mTempData.SetPropertyBit(eCSSProperty__moz_transform_origin);
   return PR_TRUE;
 }
 
--- a/layout/style/nsCSSValue.cpp
+++ b/layout/style/nsCSSValue.cpp
@@ -119,23 +119,16 @@ nsCSSValue::nsCSSValue(nsCSSValue::URL* 
 
 nsCSSValue::nsCSSValue(nsCSSValue::Image* aValue)
   : mUnit(eCSSUnit_Image)
 {
   mValue.mImage = aValue;
   mValue.mImage->AddRef();
 }
 
-nsCSSValue::nsCSSValue(nsCSSValueGradient* aValue)
-  : mUnit(eCSSUnit_Gradient)
-{
-  mValue.mGradient = aValue;
-  mValue.mGradient->AddRef();
-}
-
 nsCSSValue::nsCSSValue(const nsCSSValue& aCopy)
   : mUnit(aCopy.mUnit)
 {
   if (mUnit <= eCSSUnit_RectIsAuto) {
     // nothing to do, but put this important case first
   }
   else if (eCSSUnit_Percent <= mUnit) {
     mValue.mFloat = aCopy.mValue.mFloat;
@@ -157,20 +150,16 @@ nsCSSValue::nsCSSValue(const nsCSSValue&
   else if (eCSSUnit_URL == mUnit) {
     mValue.mURL = aCopy.mValue.mURL;
     mValue.mURL->AddRef();
   }
   else if (eCSSUnit_Image == mUnit) {
     mValue.mImage = aCopy.mValue.mImage;
     mValue.mImage->AddRef();
   }
-  else if (eCSSUnit_Gradient == mUnit) {
-    mValue.mGradient = aCopy.mValue.mGradient;
-    mValue.mGradient->AddRef();
-  }
   else {
     NS_NOTREACHED("unknown unit");
   }
 }
 
 nsCSSValue& nsCSSValue::operator=(const nsCSSValue& aCopy)
 {
   if (this != &aCopy) {
@@ -200,19 +189,16 @@ PRBool nsCSSValue::operator==(const nsCS
       return *mValue.mArray == *aOther.mValue.mArray;
     }
     else if (eCSSUnit_URL == mUnit) {
       return *mValue.mURL == *aOther.mValue.mURL;
     }
     else if (eCSSUnit_Image == mUnit) {
       return *mValue.mImage == *aOther.mValue.mImage;
     }
-    else if (eCSSUnit_Gradient == mUnit) {
-      return *mValue.mGradient == *aOther.mValue.mGradient;
-    }
     else {
       return mValue.mFloat == aOther.mValue.mFloat;
     }
   }
   return PR_FALSE;
 }
 
 imgIRequest* nsCSSValue::GetImageValue() const
@@ -252,18 +238,16 @@ void nsCSSValue::DoReset()
   if (UnitHasStringValue()) {
     mValue.mString->Release();
   } else if (eCSSUnit_Array <= mUnit && mUnit <= eCSSUnit_Function) {
     mValue.mArray->Release();
   } else if (eCSSUnit_URL == mUnit) {
     mValue.mURL->Release();
   } else if (eCSSUnit_Image == mUnit) {
     mValue.mImage->Release();
-  } else if (eCSSUnit_Gradient == mUnit) {
-    mValue.mGradient->Release();
   }
   mUnit = eCSSUnit_Null;
 }
 
 void nsCSSValue::SetIntValue(PRInt32 aValue, nsCSSUnit aUnit)
 {
   NS_ASSERTION(aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated ||
                aUnit == eCSSUnit_EnumColor, "not an int value");
@@ -337,24 +321,16 @@ void nsCSSValue::SetURLValue(nsCSSValue:
 void nsCSSValue::SetImageValue(nsCSSValue::Image* aValue)
 {
   Reset();
   mUnit = eCSSUnit_Image;
   mValue.mImage = aValue;
   mValue.mImage->AddRef();
 }
 
-void nsCSSValue::SetGradientValue(nsCSSValueGradient* aValue)
-{
-  Reset();
-  mUnit = eCSSUnit_Gradient;
-  mValue.mGradient = aValue;
-  mValue.mGradient->AddRef();
-}
-
 void nsCSSValue::SetAutoValue()
 {
   Reset();
   mUnit = eCSSUnit_Auto;
 }
 
 void nsCSSValue::SetInheritValue()
 {
@@ -458,22 +434,25 @@ nsCSSValue::URL::URL(nsIURI* aURI, nsStr
                      nsIPrincipal* aOriginPrincipal)
   : mURI(aURI),
     mString(aString),
     mReferrer(aReferrer),
     mOriginPrincipal(aOriginPrincipal),
     mRefCnt(0)
 {
   NS_PRECONDITION(aOriginPrincipal, "Must have an origin principal");
+  
   mString->AddRef();
+  MOZ_COUNT_CTOR(nsCSSValue::URL);
 }
 
 nsCSSValue::URL::~URL()
 {
   mString->Release();
+  MOZ_COUNT_DTOR(nsCSSValue::URL);
 }
 
 PRBool
 nsCSSValue::URL::operator==(const URL& aOther) const
 {
   PRBool eq;
   return NS_strcmp(GetBufferValue(mString),
                    GetBufferValue(aOther.mString)) == 0 &&
@@ -501,54 +480,23 @@ nsCSSValue::URL::URIEquals(const URL& aO
                                                  &eq)) && eq));
 }
 
 nsCSSValue::Image::Image(nsIURI* aURI, nsStringBuffer* aString,
                          nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal,
                          nsIDocument* aDocument)
   : URL(aURI, aString, aReferrer, aOriginPrincipal)
 {
+  MOZ_COUNT_CTOR(nsCSSValue::Image);
+
   if (mURI &&
       nsContentUtils::CanLoadImage(mURI, aDocument, aDocument,
                                    aOriginPrincipal)) {
     nsContentUtils::LoadImage(mURI, aDocument, aOriginPrincipal, aReferrer,
                               nsnull, nsIRequest::LOAD_NORMAL,
                               getter_AddRefs(mRequest));
   }
 }
 
 nsCSSValue::Image::~Image()
 {
-}
-
-nsCSSValueGradientStop::nsCSSValueGradientStop(const nsCSSValue& aLocation,
-                                               const nsCSSValue& aColor)
-  : mLocation(aLocation),
-    mColor(aColor)
-{ 
-  MOZ_COUNT_CTOR(nsCSSValueGradientStop);
-}
-
-nsCSSValueGradientStop::nsCSSValueGradientStop(const nsCSSValueGradientStop& aOther)
-  : mLocation(aOther.mLocation),
-    mColor(aOther.mColor)
-{ 
-  MOZ_COUNT_CTOR(nsCSSValueGradientStop);
+  MOZ_COUNT_DTOR(nsCSSValue::Image);
 }
-
-nsCSSValueGradientStop::~nsCSSValueGradientStop()
-{
-  MOZ_COUNT_DTOR(nsCSSValueGradientStop);
-}
-
-nsCSSValueGradient::nsCSSValueGradient(PRBool aIsRadial, const nsCSSValue& aStartX,
-           const nsCSSValue& aStartY, const nsCSSValue& aStartRadius, const nsCSSValue& aEndX,
-           const nsCSSValue& aEndY, const nsCSSValue& aEndRadius)
-  : mIsRadial(aIsRadial),
-    mStartX(aStartX),
-    mStartY(aStartY),
-    mEndX(aEndX),
-    mEndY(aEndY),
-    mStartRadius(aStartRadius),
-    mEndRadius(aEndRadius),
-    mRefCnt(0)
-{ 
-}
--- a/layout/style/nsCSSValue.h
+++ b/layout/style/nsCSSValue.h
@@ -44,17 +44,16 @@
 #include "nsString.h"
 #include "nsCoord.h"
 #include "nsCSSProperty.h"
 #include "nsIURI.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsCRTGlue.h"
 #include "nsStringBuffer.h"
-#include "nsTArray.h"
 
 class imgIRequest;
 class nsIDocument;
 class nsIPrincipal;
 
 // Deletes a linked list iteratively to avoid blowing up the stack (bug 456196).
 #define NS_CSS_DELETE_LIST_MEMBER(type_, ptr_, member_)                        \
   {                                                                            \
@@ -108,17 +107,16 @@ enum nsCSSUnit {
   eCSSUnit_Array        = 20,     // (nsCSSValue::Array*) a list of values
   eCSSUnit_Counter      = 21,     // (nsCSSValue::Array*) a counter(string,[string]) value
   eCSSUnit_Counters     = 22,     // (nsCSSValue::Array*) a counters(string,string[,string]) value
   eCSSUnit_Function     = 23,     // (nsCSSValue::Array*) a function with parameters.  First elem of array is name,
                                   //  the rest of the values are arguments.
 
   eCSSUnit_URL          = 30,     // (nsCSSValue::URL*) value
   eCSSUnit_Image        = 31,     // (nsCSSValue::Image*) value
-  eCSSUnit_Gradient     = 32,     // (nsCSSValueGradient*) value
   eCSSUnit_Integer      = 50,     // (int) simple value
   eCSSUnit_Enumerated   = 51,     // (int) value has enumerated meaning
   eCSSUnit_EnumColor    = 80,     // (int) enumerated color (kColorKTable)
   eCSSUnit_Color        = 81,     // (nscolor) an RGBA value
   eCSSUnit_Percent      = 90,     // (float) 1.0 == 100%) value is percentage of something
   eCSSUnit_Number       = 91,     // (float) value is numeric (usually multiplier, different behavior that percent)
 
   // Length units - fixed
@@ -152,18 +150,16 @@ enum nsCSSUnit {
   eCSSUnit_Hertz        = 2000,    // (float) 1/seconds
   eCSSUnit_Kilohertz    = 2001,    // (float) 1000 Hertz
 
   // Time units
   eCSSUnit_Seconds      = 3000,    // (float) Standard time
   eCSSUnit_Milliseconds = 3001     // (float) 1/1000 second
 };
 
-struct nsCSSValueGradient;
-
 class nsCSSValue {
 public:
   struct Array;
   friend struct Array;
 
   struct URL;
   friend struct URL;
 
@@ -179,17 +175,16 @@ public:
 
   nsCSSValue(PRInt32 aValue, nsCSSUnit aUnit) NS_HIDDEN;
   nsCSSValue(float aValue, nsCSSUnit aUnit) NS_HIDDEN;
   nsCSSValue(const nsString& aValue, nsCSSUnit aUnit) NS_HIDDEN;
   explicit nsCSSValue(nscolor aValue) NS_HIDDEN;
   nsCSSValue(Array* aArray, nsCSSUnit aUnit) NS_HIDDEN;
   explicit nsCSSValue(URL* aValue) NS_HIDDEN;
   explicit nsCSSValue(Image* aValue) NS_HIDDEN;
-  explicit nsCSSValue(nsCSSValueGradient* aValue) NS_HIDDEN;
   nsCSSValue(const nsCSSValue& aCopy) NS_HIDDEN;
   ~nsCSSValue() { Reset(); }
 
   NS_HIDDEN_(nsCSSValue&)  operator=(const nsCSSValue& aCopy);
   NS_HIDDEN_(PRBool)      operator==(const nsCSSValue& aOther) const;
 
   PRBool operator!=(const nsCSSValue& aOther) const
   {
@@ -266,22 +261,16 @@ public:
   nsIURI* GetURLValue() const
   {
     NS_ASSERTION(mUnit == eCSSUnit_URL || mUnit == eCSSUnit_Image,
                  "not a URL value");
     return mUnit == eCSSUnit_URL ?
       mValue.mURL->mURI : mValue.mImage->mURI;
   }
 
-  nsCSSValueGradient* GetGradientValue() const
-  {
-    NS_ASSERTION(mUnit == eCSSUnit_Gradient, "not a gradient value");
-    return mValue.mGradient;
-  }
-
   URL* GetURLStructValue() const
   {
     // Not allowing this for Image values, because if the caller takes
     // a ref to them they won't be able to delete them properly.
     NS_ASSERTION(mUnit == eCSSUnit_URL, "not a URL value");
     return mValue.mURL;
   }
 
@@ -313,17 +302,16 @@ public:
   NS_HIDDEN_(void)  SetIntValue(PRInt32 aValue, nsCSSUnit aUnit);
   NS_HIDDEN_(void)  SetPercentValue(float aValue);
   NS_HIDDEN_(void)  SetFloatValue(float aValue, nsCSSUnit aUnit);
   NS_HIDDEN_(void)  SetStringValue(const nsString& aValue, nsCSSUnit aUnit);
   NS_HIDDEN_(void)  SetColorValue(nscolor aValue);
   NS_HIDDEN_(void)  SetArrayValue(nsCSSValue::Array* aArray, nsCSSUnit aUnit);
   NS_HIDDEN_(void)  SetURLValue(nsCSSValue::URL* aURI);
   NS_HIDDEN_(void)  SetImageValue(nsCSSValue::Image* aImage);
-  NS_HIDDEN_(void)  SetGradientValue(nsCSSValueGradient* aGradient);
   NS_HIDDEN_(void)  SetAutoValue();
   NS_HIDDEN_(void)  SetInheritValue();
   NS_HIDDEN_(void)  SetInitialValue();
   NS_HIDDEN_(void)  SetNoneValue();
   NS_HIDDEN_(void)  SetNormalValue();
   NS_HIDDEN_(void)  SetSystemFontValue();
   NS_HIDDEN_(void)  SetDummyValue();
   NS_HIDDEN_(void)  SetDummyInheritValue();
@@ -362,68 +350,49 @@ public:
     nsCOMPtr<nsIPrincipal> mOriginPrincipal;
 
     void AddRef() {
       if (mRefCnt == PR_UINT32_MAX) {
         NS_WARNING("refcount overflow, leaking nsCSSValue::URL");
         return;
       }
       ++mRefCnt;
-      NS_LOG_ADDREF(this, mRefCnt, "nsCSSValue::URL", sizeof(*this));
     }
     void Release() {
       if (mRefCnt == PR_UINT32_MAX) {
         NS_WARNING("refcount overflow, leaking nsCSSValue::URL");
         return;
       }
-      --mRefCnt;
-      NS_LOG_RELEASE(this, mRefCnt, "nsCSSValue::URL");
-      if (mRefCnt == 0)
+      if (--mRefCnt == 0)
         delete this;
     }
   protected:
     nsrefcnt mRefCnt;
-
-    // not to be implemented
-    URL(const URL& aOther);
-    URL& operator=(const URL& aOther);
   };
 
   struct Image : public URL {
     // Not making the constructor and destructor inline because that would
     // force us to include imgIRequest.h, which leads to REQUIRES hell, since
     // this header is included all over.
     // aString must not be null.
     Image(nsIURI* aURI, nsStringBuffer* aString, nsIURI* aReferrer,
           nsIPrincipal* aOriginPrincipal, nsIDocument* aDocument) NS_HIDDEN;
     ~Image() NS_HIDDEN;
 
     // Inherit operator== from nsCSSValue::URL
 
     nsCOMPtr<imgIRequest> mRequest; // null == image load blocked or somehow failed
 
-    // Override AddRef and Release to not only log ourselves correctly, but
-    // also so that we delete correctly without a virtual destructor
-    void AddRef() {
-      if (mRefCnt == PR_UINT32_MAX) {
-        NS_WARNING("refcount overflow, leaking nsCSSValue::Image");
-        return;
-      }
-      ++mRefCnt;
-      NS_LOG_ADDREF(this, mRefCnt, "nsCSSValue::Image", sizeof(*this));
-    }
-
+    // Override Release so we delete correctly without a virtual destructor
     void Release() {
       if (mRefCnt == PR_UINT32_MAX) {
         NS_WARNING("refcount overflow, leaking nsCSSValue::Image");
         return;
       }
-      --mRefCnt;
-      NS_LOG_RELEASE(this, mRefCnt, "nsCSSValue::Image");
-      if (mRefCnt == 0)
+      if (--mRefCnt == 0)
         delete this;
     }
   };
 
 private:
   static const PRUnichar* GetBufferValue(nsStringBuffer* aBuffer) {
     return static_cast<PRUnichar*>(aBuffer->Data());
   }
@@ -435,115 +404,19 @@ protected:
     float      mFloat;
     // Note: the capacity of the buffer may exceed the length of the string.
     // If we're of a string type, mString is not null.
     nsStringBuffer* mString;
     nscolor    mColor;
     Array*     mArray;
     URL*       mURL;
     Image*     mImage;
-    nsCSSValueGradient* mGradient;
   }         mValue;
 };
 
-struct nsCSSValueGradientStop {
-public:
-  nsCSSValueGradientStop(const nsCSSValue& aLocation, const nsCSSValue& aColor) NS_HIDDEN;
-  // needed to keep bloat logs happy when we use the nsTArray in nsCSSValueGradient
-  nsCSSValueGradientStop(const nsCSSValueGradientStop& aOther) NS_HIDDEN;
-  ~nsCSSValueGradientStop() NS_HIDDEN;
-
-  nsCSSValue mLocation;
-  nsCSSValue mColor;
-
-  PRBool operator==(const nsCSSValueGradientStop& aOther) const
-  {
-    return (mLocation == aOther.mLocation &&
-            mColor == aOther.mColor);
-  }
-
-  PRBool operator!=(const nsCSSValueGradientStop& aOther) const
-  {
-    return !(*this == aOther);
-  }
-};
-
-struct nsCSSValueGradient {
-  nsCSSValueGradient(PRBool aIsRadial, const nsCSSValue& aStartX, const nsCSSValue& aStartY,
-           const nsCSSValue& aStartRadius, const nsCSSValue& aEndX, const nsCSSValue& aEndY,
-           const nsCSSValue& aEndRadius) NS_HIDDEN;
-
-  // true if gradient is radial, false if it is linear
-  PRPackedBool mIsRadial;
-  nsCSSValue mStartX;
-  nsCSSValue mStartY;
-
-  nsCSSValue mEndX;
-  nsCSSValue mEndY;
-
-  // Only meaningful if mIsRadial is true
-  nsCSSValue mStartRadius;
-  nsCSSValue mEndRadius;
-
-  nsTArray<nsCSSValueGradientStop> mStops;
-
-  PRBool operator==(const nsCSSValueGradient& aOther) const
-  {
-    if (mIsRadial != aOther.mIsRadial ||
-        mStartX != aOther.mStartX ||
-        mStartY != aOther.mStartY ||
-        mStartRadius != aOther.mStartRadius ||
-        mEndX != aOther.mEndX ||
-        mEndY != aOther.mEndY ||
-        mEndRadius != aOther.mEndRadius)
-      return PR_FALSE;
-
-    if (mStops.Length() != aOther.mStops.Length())
-      return PR_FALSE;
-
-    for (PRUint32 i = 0; i < mStops.Length(); i++) {
-      if (mStops[i] != aOther.mStops[i])
-        return PR_FALSE;
-    }
-
-    return PR_TRUE;
-  }
-
-  PRBool operator!=(const nsCSSValueGradient& aOther) const
-  {
-    return !(*this == aOther);
-  }
-
-  void AddRef() {
-    if (mRefCnt == PR_UINT32_MAX) {
-      NS_WARNING("refcount overflow, leaking nsCSSValue::Gradient");
-      return;
-    }
-    ++mRefCnt;
-    NS_LOG_ADDREF(this, mRefCnt, "nsCSSValue::Gradient", sizeof(*this));
-  }
-  void Release() {
-    if (mRefCnt == PR_UINT32_MAX) {
-      NS_WARNING("refcount overflow, leaking nsCSSValue::Gradient");
-      return;
-    }
-    --mRefCnt;
-    NS_LOG_RELEASE(this, mRefCnt, "nsCSSValue::Gradient");
-    if (mRefCnt == 0)
-      delete this;
-  }
-
-private:
-  nsrefcnt mRefCnt;
-
-  // not to be implemented
-  nsCSSValueGradient(const nsCSSValueGradient& aOther);
-  nsCSSValueGradient& operator=(const nsCSSValueGradient& aOther);
-};
-
 struct nsCSSValue::Array {
 
   // return |Array| with reference count of zero
   static Array* Create(PRUint16 aItemCount) {
     return new (aItemCount) Array(aItemCount);
   }
 
   nsCSSValue& operator[](PRUint16 aIndex) {
@@ -630,15 +503,13 @@ private:
     CSSVALUE_LIST_FOR_EXTRA_VALUES(val) {
       val->~nsCSSValue();
     }
   }
 
 #undef CSSVALUE_LIST_FOR_EXTRA_VALUES
 
 private:
-  // not to be implemented
-  Array(const Array& aOther);
-  Array& operator=(const Array& aOther);
+  Array(const Array& aOther); // not to be implemented
 };
 
 #endif /* nsCSSValue_h___ */
 
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -1245,144 +1245,39 @@ nsComputedDOMStyle::GetBackgroundColor(n
   if (NS_FAILED(rv)) {
     delete val;
     return rv;
   }
 
   return CallQueryInterface(val, aValue);
 }
 
-static void
-AppendCSSGradientLength(const nsStyleCoord& aValue,
-                        nsROCSSPrimitiveValue* aPrimitive,
-                        nsAString& aString)
-{
-  nsAutoString tokenString;
-  if (aValue.GetUnit() == eStyleUnit_Coord)
-    aPrimitive->SetAppUnits(aValue.GetCoordValue());
-  else
-    aPrimitive->SetPercent(aValue.GetPercentValue());
-  aPrimitive->GetCssText(tokenString);
-  aString.Append(tokenString);
-}
-
-static void
-AppendCSSGradientRadius(const nscoord aValue,
-                        nsROCSSPrimitiveValue* aPrimitive,
-                        nsAString& aString)
-{
-  nsAutoString tokenString;
-  aPrimitive->SetAppUnits(aValue);
-  aPrimitive->GetCssText(tokenString);
-  aString.Append(tokenString);
-}
-
-nsresult
-nsComputedDOMStyle::GetCSSGradientString(const nsStyleGradient* aGradient,
-                                         nsAString& aString)
-{
-  if (aGradient->mIsRadial)
-    aString.AssignLiteral("-moz-radial-gradient(");
-  else
-    aString.AssignLiteral("-moz-linear-gradient(");
-
-  nsROCSSPrimitiveValue *tmpVal = GetROCSSPrimitiveValue();
-  if (!tmpVal)
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  // starting X position
-  AppendCSSGradientLength(aGradient->mStartX, tmpVal, aString);
-  aString.AppendLiteral(" ");
-
-  // starting Y position
-  AppendCSSGradientLength(aGradient->mStartY, tmpVal, aString);
-  aString.AppendLiteral(", ");
-
-  // starting radius
-  if (aGradient->mIsRadial) {
-    AppendCSSGradientRadius(aGradient->mStartRadius, tmpVal, aString);
-    aString.AppendLiteral(", ");
-  }
-
-  // ending X position
-  AppendCSSGradientLength(aGradient->mEndX, tmpVal, aString);
-  aString.AppendLiteral(" ");
-
-  // ending Y position
-  AppendCSSGradientLength(aGradient->mEndY, tmpVal, aString);
-
-  // ending radius
-  if (aGradient->mIsRadial) {
-    aString.AppendLiteral(", ");
-    AppendCSSGradientRadius(aGradient->mStartRadius, tmpVal, aString);
-  }
-
-  // color stops
-  for (PRUint32 i = 0; i < aGradient->mStops.Length(); ++i) {
-    nsAutoString tokenString;
-    aString.AppendLiteral(", color-stop(");
-
-    tmpVal->SetPercent(aGradient->mStops[i].mPosition);
-    tmpVal->GetCssText(tokenString);
-    aString.Append(tokenString);
-    aString.AppendLiteral(", ");
-
-    nsresult rv = SetToRGBAColor(tmpVal, aGradient->mStops[i].mColor);
-    if (NS_FAILED(rv)) {
-      delete tmpVal;
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-
-    tmpVal->GetCssText(tokenString);
-    aString.Append(tokenString);
-    aString.AppendLiteral(")");
-  }
-
-  delete tmpVal;
-  aString.AppendLiteral(")");
-  return NS_OK;
-}
-
 nsresult
 nsComputedDOMStyle::GetBackgroundImage(nsIDOMCSSValue** aValue)
 {
   const nsStyleBackground* bg = GetStyleBackground();
 
   nsDOMCSSValueList *valueList = GetROCSSValueList(PR_TRUE);
   NS_ENSURE_TRUE(valueList, NS_ERROR_OUT_OF_MEMORY);
 
   for (PRUint32 i = 0, i_end = bg->mImageCount; i < i_end; ++i) {
     nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
     if (!val || !valueList->AppendCSSValue(val)) {
       delete val;
       delete valueList;
       return NS_ERROR_OUT_OF_MEMORY;
     }
 
-    const nsStyleBackground::Image &image = bg->mLayers[i].mImage;
-    if (image.GetType() == eBackgroundImage_Image) {
-      imgIRequest *req = image.GetImageData();
-      if (!req) {
-        val->SetIdent(eCSSKeyword_none);
-      } else {
-        nsCOMPtr<nsIURI> uri;
-        req->GetURI(getter_AddRefs(uri));
-        val->SetURI(uri);
-      }
-    } else if (image.GetType() == eBackgroundImage_Gradient) {
-      nsAutoString gradientString;
-      nsresult rv = GetCSSGradientString(image.GetGradientData(),
-                                         gradientString);
-      if (NS_FAILED(rv)) {
-        delete valueList;
-        return rv;
-      }
-      val->SetString(gradientString);
+    imgIRequest *image = bg->mLayers[i].mImage;
+    if (!image) {
+      val->SetIdent(eCSSKeyword_none);
     } else {
-      val->SetIdent(eCSSKeyword_none);
+      nsCOMPtr<nsIURI> uri;
+      image->GetURI(getter_AddRefs(uri));
+      val->SetURI(uri);
     }
   }
 
   return CallQueryInterface(valueList, aValue);
 }
 
 nsresult
 nsComputedDOMStyle::GetBackgroundInlinePolicy(nsIDOMCSSValue** aValue)
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -126,19 +126,16 @@ private:
                              PRBool aIsBoxShadow,
                              nsIDOMCSSValue** aValue);
 
   nsresult GetBackgroundList(PRUint8 nsStyleBackground::Layer::* aMember,
                              PRUint32 nsStyleBackground::* aCount,
                              const PRInt32 aTable[],
                              nsIDOMCSSValue** aResult);
 
-  nsresult GetCSSGradientString(const nsStyleGradient* aGradient,
-                                nsAString& aString);
-
   /* Properties Queryable as CSSValues */
 
   nsresult GetAppearance(nsIDOMCSSValue** aValue);
 
   /* Box properties */
   nsresult GetBoxAlign(nsIDOMCSSValue** aValue);
   nsresult GetBoxDirection(nsIDOMCSSValue** aValue);
   nsresult GetBoxFlex(nsIDOMCSSValue** aValue);
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -466,91 +466,16 @@ static PRBool SetColor(const nsCSSValue&
   else if (eCSSUnit_Inherit == unit) {
     aResult = aParentColor;
     result = PR_TRUE;
     aCanStoreInRuleTree = PR_FALSE;
   }
   return result;
 }
 
-static void SetGradientCoord(const nsCSSValue& aValue, nsPresContext* aPresContext,
-                             nsStyleContext* aContext, nsStyleCoord& aResult,
-                             PRBool& aCanStoreInRuleTree)
-{
-  // If coordinate is an enumerated type, handle it explicitly.
-  if (aValue.GetUnit() == eCSSUnit_Enumerated) {
-    aResult.SetPercentValue(GetFloatFromBoxPosition(aValue.GetIntValue()));
-    return;
-  }
-
-  // OK to pass bad aParentCoord since we're not passing SETCOORD_INHERIT
-  PRBool result = SetCoord(aValue, aResult, nsStyleCoord(), SETCOORD_LP,
-                           aContext, aPresContext, aCanStoreInRuleTree);
-  NS_ABORT_IF_FALSE(result, "Incorrect data structure created by parsing code");
-}
-
-static void SetGradient(const nsCSSValue& aValue, nsPresContext* aPresContext,
-                        nsStyleContext* aContext, nsStyleGradient& aResult,
-                        PRBool& aCanStoreInRuleTree)
-{
-  NS_ABORT_IF_FALSE(aValue.GetUnit() == eCSSUnit_Gradient,
-                    "The given data is not a gradient");
-
-  nsCSSValueGradient* gradient = aValue.GetGradientValue();
-  aResult.mIsRadial = gradient->mIsRadial;
-
-  // start values
-  SetGradientCoord(gradient->mStartX, aPresContext, aContext,
-                   aResult.mStartX, aCanStoreInRuleTree);
-
-  SetGradientCoord(gradient->mStartY, aPresContext, aContext,
-                   aResult.mStartY, aCanStoreInRuleTree);
-
-  if (gradient->mIsRadial) {
-    NS_ABORT_IF_FALSE(gradient->mStartRadius.IsLengthUnit(),
-                      "Incorrect data structure created by parsing code");
-    aResult.mStartRadius = CalcLength(gradient->mStartRadius, aContext,
-                                      aPresContext, aCanStoreInRuleTree);
-  }
-
-  // end values
-  SetGradientCoord(gradient->mEndX, aPresContext, aContext,
-                   aResult.mEndX, aCanStoreInRuleTree);
-
-  SetGradientCoord(gradient->mEndY, aPresContext, aContext,
-                   aResult.mEndY, aCanStoreInRuleTree);
-
-  if (gradient->mIsRadial) {
-    NS_ABORT_IF_FALSE(gradient->mEndRadius.IsLengthUnit(),
-                      "Incorrect data structure created by parsing code");
-    aResult.mEndRadius = CalcLength(gradient->mEndRadius, aContext,
-                                    aPresContext, aCanStoreInRuleTree);
-  }
-
-  // stops
-  for (PRUint32 i = 0; i < gradient->mStops.Length(); i++) {
-    nsStyleGradientStop stop;
-    nsCSSValueGradientStop &valueStop = gradient->mStops[i];
-
-    if (valueStop.mLocation.GetUnit() == eCSSUnit_Percent)
-      stop.mPosition = valueStop.mLocation.GetPercentValue();
-    else
-      stop.mPosition = valueStop.mLocation.GetFloatValue();
-
-    // inherit is not a valid color for stops, so we pass in a dummy
-    // parent color
-    NS_ASSERTION(valueStop.mColor.GetUnit() != eCSSUnit_Inherit,
-                 "inherit is not a valid color for gradient stops");
-    SetColor(valueStop.mColor, NS_RGB(0, 0, 0), aPresContext,
-             aContext, stop.mColor, aCanStoreInRuleTree);
-
-    aResult.mStops.AppendElement(stop);
-  }
-}
-
 // flags for SetDiscrete - align values with SETCOORD_* constants
 // where possible
 
 #define SETDSC_NORMAL                 0x01   // N
 #define SETDSC_AUTO                   0x02   // A
 #define SETDSC_INTEGER                0x40   // I
 #define SETDSC_ENUMERATED             0x80   // E
 #define SETDSC_NONE                   0x100  // O
@@ -3873,40 +3798,30 @@ struct BackgroundItemComputer<nsCSSValue
                            PRBool& aCanStoreInRuleTree)
   {
     SetDiscrete(aSpecifiedValue->mValue, aComputedValue, aCanStoreInRuleTree,
                 SETDSC_ENUMERATED, PRUint8(0), 0, 0, 0, 0, 0);
   }
 };
 
 NS_SPECIALIZE_TEMPLATE
-struct BackgroundItemComputer<nsCSSValueList, nsStyleBackground::Image>
+struct BackgroundItemComputer<nsCSSValueList, nsCOMPtr<imgIRequest> >
 {
   static void ComputeValue(nsStyleContext* aStyleContext,
                            const nsCSSValueList* aSpecifiedValue,
-                           nsStyleBackground::Image& aComputedValue,
+                           nsCOMPtr<imgIRequest>& aComputedValue,
                            PRBool& aCanStoreInRuleTree)
   {
     const nsCSSValue &value = aSpecifiedValue->mValue;
     if (eCSSUnit_Image == value.GetUnit()) {
-      aComputedValue.SetImageData(value.GetImageValue());
-    }
-    else if (eCSSUnit_Gradient == value.GetUnit()) {
-      nsStyleGradient* gradient = new nsStyleGradient();
-      if (gradient) {
-        SetGradient(value, aStyleContext->PresContext(), aStyleContext,
-                    *gradient, aCanStoreInRuleTree);
-        aComputedValue.SetGradientData(gradient);
-      } else {
-        aComputedValue.SetNull();
-      }
+      aComputedValue = value.GetImageValue();
     }
     else {
       NS_ASSERTION(eCSSUnit_None == value.GetUnit(), "unexpected unit");
-      aComputedValue.SetNull();
+      aComputedValue = nsnull;
     }
   }
 };
 
 struct BackgroundPositionAxis {
   nsCSSValue nsCSSValuePairList::*specified;
   nsStyleBackground::Position::PositionCoord
     nsStyleBackground::Position::*result;
@@ -4136,21 +4051,20 @@ nsRuleNode::ComputeBackgroundData(void* 
     NS_ASSERTION(eCSSUnit_Null == colorData.mBackColor.GetUnit(),
                  "unexpected color unit");
   }
 
   PRUint32 maxItemCount = 1;
   PRBool rebuild = PR_FALSE;
 
   // background-image: url (stored as image), none, inherit [list]
-  nsStyleBackground::Image initialImage;
   SetBackgroundList(aContext, colorData.mBackImage, bg->mLayers,
                     parentBG->mLayers, &nsStyleBackground::Layer::mImage,
-                    initialImage, parentBG->mImageCount, bg->mImageCount,
-                    maxItemCount, rebuild, canStoreInRuleTree);
+                    nsCOMPtr<imgIRequest>(nsnull), parentBG->mImageCount,
+                    bg->mImageCount, maxItemCount, rebuild, canStoreInRuleTree);
 
   // background-repeat: enum, inherit, initial [list]
   SetBackgroundList(aContext, colorData.mBackRepeat, bg->mLayers,
                     parentBG->mLayers, &nsStyleBackground::Layer::mRepeat,
                     PRUint8(NS_STYLE_BG_REPEAT_XY), parentBG->mRepeatCount,
                     bg->mRepeatCount, maxItemCount, rebuild, canStoreInRuleTree);
 
   // background-attachment: enum, inherit, initial [list]
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -1202,61 +1202,16 @@ nsChangeHint nsStyleColor::CalcDifferenc
 /* static */
 nsChangeHint nsStyleColor::MaxDifference()
 {
   return NS_STYLE_HINT_VISUAL;
 }
 #endif
 
 // --------------------
-// nsStyleGradient
-//
-PRBool
-nsStyleGradient::operator==(const nsStyleGradient& aOther) const
-{
-  NS_ABORT_IF_FALSE(mIsRadial || (mStartRadius == 0 && mEndRadius == 0),
-                    "incorrect unused radius values");
-  NS_ABORT_IF_FALSE(aOther.mIsRadial ||
-                    (aOther.mStartRadius == 0 && aOther.mEndRadius == 0),
-                    "incorrect unused radius values");
-
-  if (mIsRadial != aOther.mIsRadial ||
-      mStartX != aOther.mStartX ||
-      mStartY != aOther.mStartY ||
-      mStartRadius != aOther.mStartRadius ||
-      mEndX != aOther.mEndX ||
-      mEndY != aOther.mEndY ||
-      mEndRadius != aOther.mEndRadius)
-    return PR_FALSE;
-
-  if (mStops.Length() != aOther.mStops.Length())
-    return PR_FALSE;
-
-  for (PRUint32 i = 0; i < mStops.Length(); i++) {
-    if (mStops[i].mPosition != aOther.mStops[i].mPosition ||
-        mStops[i].mColor != aOther.mStops[i].mColor)
-      return PR_FALSE;
-  }
-
-  return PR_TRUE;
-}
-
-nsStyleGradient::nsStyleGradient(void)
-  : mIsRadial(PR_FALSE)
-  , mStartRadius(0)
-  , mEndRadius(0)
-  , mRefCnt(0)
-{
-  mStartX.SetCoordValue(0);
-  mStartY.SetCoordValue(0);
-  mEndX.SetCoordValue(0);
-  mEndY.SetCoordValue(0);
-}
-
-// --------------------
 // nsStyleBackground
 //
 
 nsStyleBackground::nsStyleBackground()
   : mAttachmentCount(1)
   , mClipCount(1)
   , mOriginCount(1)
   , mRepeatCount(1)
@@ -1324,28 +1279,26 @@ nsChangeHint nsStyleBackground::MaxDiffe
   return NS_STYLE_HINT_VISUAL;
 }
 #endif
 
 PRBool nsStyleBackground::HasFixedBackground() const
 {
   NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, this) {
     const Layer &layer = mLayers[i];
-    if (layer.mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED &&
-        layer.mImage.GetType() != eBackgroundImage_Null) {
+    if (layer.mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED && layer.mImage) {
       return PR_TRUE;
     }
   }
   return PR_FALSE;
 }
 
 PRBool nsStyleBackground::IsTransparent() const
 {
-  return BottomLayer().mImage.GetType() == eBackgroundImage_Null &&
-         mImageCount == 1 &&
+  return !BottomLayer().mImage && mImageCount == 1 &&
          NS_GET_A(mBackgroundColor) == 0;
 }
 
 void
 nsStyleBackground::Position::SetInitialValues()
 {
   mXPosition.mFloat = 0.0f;
   mYPosition.mFloat = 0.0f;
@@ -1405,120 +1358,28 @@ void
 nsStyleBackground::Layer::SetInitialValues()
 {
   mAttachment = NS_STYLE_BG_ATTACHMENT_SCROLL;
   mClip = NS_STYLE_BG_CLIP_BORDER;
   mOrigin = NS_STYLE_BG_ORIGIN_PADDING;
   mRepeat = NS_STYLE_BG_REPEAT_XY;
   mPosition.SetInitialValues();
   mSize.SetInitialValues();
-  mImage.SetNull();
+  mImage = nsnull;
 }
 
 PRBool nsStyleBackground::Layer::operator==(const Layer& aOther) const
 {
   return mAttachment == aOther.mAttachment &&
          mClip == aOther.mClip &&
          mOrigin == aOther.mOrigin &&
          mRepeat == aOther.mRepeat &&
          mPosition == aOther.mPosition &&
          mSize == aOther.mSize &&
-         mImage == aOther.mImage;
-}
-
-nsStyleBackground::Image::Image()
-{
-  MOZ_COUNT_CTOR(nsStyleBackground::Image);
-  mType = eBackgroundImage_Null;
-}
-
-nsStyleBackground::Image::~Image()
-{
-  MOZ_COUNT_DTOR(nsStyleBackground::Image);
-  if (mType != eBackgroundImage_Null)
-    SetNull();
-}
-
-nsStyleBackground::Image::Image(const nsStyleBackground::Image& aOther)
-{
-  // We need our own copy constructor because we don't want
-  // to copy the reference count
-  MOZ_COUNT_CTOR(nsStyleBackground::Image);
-  DoCopy(aOther);
-}
-
-nsStyleBackground::Image&
-nsStyleBackground::Image::operator=(const nsStyleBackground::Image& aOther)
-{
-  DoCopy(aOther);
-  return *this;
-}
-
-void nsStyleBackground::Image::DoCopy(const nsStyleBackground::Image& aOther)
-{
-  if (this == &aOther)
-    return;
-
-  SetNull();
-
-  if (aOther.mType == eBackgroundImage_Image)
-    SetImageData(aOther.mImage);
-  else if (aOther.mType == eBackgroundImage_Gradient)
-    SetGradientData(aOther.mGradient);
-}
-
-void nsStyleBackground::Image::SetImageData(imgIRequest* aImage)
-{
-  NS_IF_ADDREF(aImage);
-
-  if (mType != eBackgroundImage_Null)
-    SetNull();
-
-  if (aImage) {
-    mImage = aImage;
-    mType = eBackgroundImage_Image;
-  }
-}
-
-void nsStyleBackground::Image::SetGradientData(nsStyleGradient* aGradient)
-{
-  if (aGradient)
-    aGradient->AddRef();
-
-  if (mType != eBackgroundImage_Null)
-    SetNull();
-
-  if (aGradient) {
-    mGradient = aGradient;
-    mType = eBackgroundImage_Gradient;
-  }
-}
-
-void nsStyleBackground::Image::SetNull()
-{
-  if (mType == eBackgroundImage_Gradient)
-    mGradient->Release();
-  else if (mType == eBackgroundImage_Image)
-    NS_RELEASE(mImage);
-
-  mType = eBackgroundImage_Null;
-}
-
-PRBool nsStyleBackground::Image::operator==(const Image& aOther) const
-{
-  if (mType != aOther.mType)
-    return PR_FALSE;
-
-  if (mType == eBackgroundImage_Image)
-    return EqualImages(mImage, aOther.mImage);
-
-  if (mType == eBackgroundImage_Gradient)
-    return *mGradient == *aOther.mGradient;
-
-  return PR_TRUE;
+         EqualImages(mImage, aOther.mImage);
 }
 
 // --------------------
 // nsStyleDisplay
 //
 
 nsStyleDisplay::nsStyleDisplay()
 {
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -119,78 +119,16 @@ struct nsStyleFont {
   PRInt8  mScriptLevel;          // [inherited]
   // The value mSize would have had if scriptminsize had never been applied
   nscoord mScriptUnconstrainedSize;
   nscoord mScriptMinSize;        // [inherited] length
   float   mScriptSizeMultiplier; // [inherited]
 #endif
 };
 
-struct nsStyleGradientStop {
-  nscolor mColor;
-  float mPosition; // 0.0 - 1.0
-};
-
-class nsStyleGradient {
-public:
-  nsStyleGradient();
-
-  PRPackedBool mIsRadial;
-
-  nsStyleCoord mStartX; // percent or coord
-  nsStyleCoord mStartY; // percent or coord
-
-  nsStyleCoord mEndX; // percent or coord
-  nsStyleCoord mEndY; // percent or coord
-
-  nscoord mStartRadius;
-  nscoord mEndRadius;
-
-  // stops are in the order specified in the stylesheet
-  nsTArray<nsStyleGradientStop> mStops;
-
-  nsrefcnt AddRef() {
-    if (mRefCnt == PR_UINT32_MAX) {
-      NS_WARNING("refcount overflow, leaking nsStyleGradient");
-      return mRefCnt;
-    }
-    ++mRefCnt;
-    NS_LOG_ADDREF(this, mRefCnt, "nsStyleGradient", sizeof(*this));
-    return mRefCnt;
-  }
-
-  nsrefcnt Release() {
-    if (mRefCnt == PR_UINT32_MAX) {
-      NS_WARNING("refcount overflow, leaking nsStyleGradient");
-      return mRefCnt;
-    }
-    --mRefCnt;
-    NS_LOG_RELEASE(this, mRefCnt, "nsStyleGradient");
-    if (mRefCnt == 0) {
-      delete this;
-      return 0;
-    }
-    return mRefCnt;
-  }
-
-  PRBool operator==(const nsStyleGradient& aOther) const;
-  PRBool operator!=(const nsStyleGradient& aOther) const {
-    return !(*this == aOther);
-  };
-
-private:
-  nsrefcnt mRefCnt;
-
-  ~nsStyleGradient() {}
-
-  // Not to be implemented
-  nsStyleGradient(const nsStyleGradient& aOther);
-  nsStyleGradient& operator=(const nsStyleGradient& aOther);
-};
-
 struct nsStyleColor {
   nsStyleColor(nsPresContext* aPresContext);
   nsStyleColor(const nsStyleColor& aOther);
   ~nsStyleColor(void) {}
 
   nsChangeHint CalcDifference(const nsStyleColor& aOther) const;
 #ifdef DEBUG
   static nsChangeHint MaxDifference();
@@ -204,22 +142,16 @@ struct nsStyleColor {
     aContext->FreeToShell(sizeof(nsStyleColor), this);
   }
 
   // Don't add ANY members to this struct!  We can achieve caching in the rule
   // tree (rather than the style tree) by letting color stay by itself! -dwh
   nscolor mColor;                 // [inherited]
 };
 
-enum nsStyleBackgroundImageType {
-  eBackgroundImage_Null,
-  eBackgroundImage_Image,
-  eBackgroundImage_Gradient
-};
-
 struct nsStyleBackground {
   nsStyleBackground();
   nsStyleBackground(const nsStyleBackground& aOther);
   ~nsStyleBackground();
 
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->AllocateFromShell(sz);
   }
@@ -291,65 +223,25 @@ struct nsStyleBackground {
     void SetInitialValues();
 
     PRBool operator==(const Size& aOther) const;
     PRBool operator!=(const Size& aOther) const {
       return !(*this == aOther);
     }
   };
 
-  struct Image;
-  friend struct Image;
-  struct Image {
-  public:
-    Image();
-    ~Image();
-    Image(const Image& aOther);
-    Image& operator=(const Image& aOther);
-
-    void SetImageData(imgIRequest* aImage);
-    void SetGradientData(nsStyleGradient* aGradient);
-    void SetNull();
-
-    nsStyleBackgroundImageType GetType() const {
-      return mType;
-    };
-    imgIRequest* GetImageData() const {
-      NS_ASSERTION(mType == eBackgroundImage_Image, "Data is not an image!");
-      return mImage;
-    };
-    nsStyleGradient* GetGradientData() const {
-      NS_ASSERTION(mType == eBackgroundImage_Gradient, "Data is not a gradient!");
-      return mGradient;
-    };
-
-    PRBool operator==(const Image& aOther) const;
-    PRBool operator!=(const Image& aOther) const {
-      return !(*this == aOther);
-    }
-
-  private:
-    void DoCopy(const Image& aOther);
-
-    nsStyleBackgroundImageType mType;
-    union {
-      imgIRequest* mImage;
-      nsStyleGradient* mGradient;
-    };
-  };
-
   struct Layer;
   friend struct Layer;
   struct Layer {
     PRUint8 mAttachment;                // [reset] See nsStyleConsts.h
     PRUint8 mClip;                      // [reset] See nsStyleConsts.h
     PRUint8 mOrigin;                    // [reset] See nsStyleConsts.h
     PRUint8 mRepeat;                    // [reset] See nsStyleConsts.h
     Position mPosition;                 // [reset]
-    Image mImage;                       // [reset]
+    nsCOMPtr<imgIRequest> mImage;       // [reset]
     Size mSize;                         // [reset]
 
     // Initializes only mImage
     Layer();
     ~Layer();
 
     void SetInitialValues();
 
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -620,25 +620,24 @@ var gCSSProperties = {
 	"background": {
 		domProp: "background",
 		inherited: false,
 		type: CSS_TYPE_TRUE_SHORTHAND,
 		subproperties: [ "background-attachment", "background-color", "background-image", "background-position", "background-repeat", "-moz-background-clip", "-moz-background-origin", "-moz-background-size" ],
 		initial_values: [ "transparent", "none", "repeat", "scroll", "0% 0%", "top left", "left top", "transparent none", "top left none", "left top none", "none left top", "none top left", "none 0% 0%", "transparent none repeat scroll top left", "left top repeat none scroll transparent" ],
 		other_values: [
 		        /* without multiple backgrounds */
-		        "green", "none green repeat scroll left top", "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==)", "repeat url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==') transparent left top scroll", "repeat-x", "repeat-y", "no-repeat", "none repeat-y transparent scroll 0% 0%", "fixed", "0% top transparent fixed repeat none", "top", "left", "50% 50%", "center", "bottom right scroll none transparent repeat", "50% transparent", "transparent 50%", "50%", "-moz-radial-gradient(10% bottom, 30px, 20px 20px, 10px, from(#ffffff), to(black)) scroll no-repeat", "-moz-linear-gradient(10px 10px, 20px 20px, from(red), to(blue)) repeat",
+		        "green", "none green repeat scroll left top", "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==)", "repeat url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==') transparent left top scroll", "repeat-x", "repeat-y", "no-repeat", "none repeat-y transparent scroll 0% 0%", "fixed", "0% top transparent fixed repeat none", "top", "left", "50% 50%", "center", "bottom right scroll none transparent repeat", "50% transparent", "transparent 50%", "50%",
 		        /* multiple backgrounds */
 		        "url(404.png), url(404.png)",
 		        "url(404.png), url(404.png) transparent",
 		        "url(404.png), url(404.png) red",
 		        "repeat-x, fixed, none",
 		        "0% top url(404.png), url(404.png) 0% top",
 		        "fixed repeat-y top left url(404.png), repeat-x green",
-		        "url(404.png), -moz-linear-gradient(20px 20px, 30px 30px, from(blue), to(green)) black",
 		        /* test cases with clip+origin in the shorthand */
     // This is commented out for now until we change
     // -moz-background-clip to background-clip, -moz-background-origin
     // to background-origin, change their value names to *-box, and add
     // support for content-box on background-clip.
     /*
 		        "url(404.png) green padding-box",
 		        "url(404.png) border-box transparent",
@@ -684,40 +683,19 @@ var gCSSProperties = {
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		initial_values: [ "none" ],
 		other_values: [ "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==)", "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==')", 'url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==")',
 			"none, none",
 			"none, none, none, none, none",
 			"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==), none",
 			"none, url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==), none",
-			"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==), url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==)",
-
-            "-moz-radial-gradient(45px 60px, 10px, 52px 50px, 30px, from(red), color-stop(90%, #019f62), to(rgba(1, 159, 98, 0)))",
-            "-moz-linear-gradient(20% center, left bottom, color-stop(0, #ffff00), to(green))",
-            "-moz-radial-gradient(50% 50%, 60px, 10% 20%, 20px, to(red), from(pink), color-stop(0.94, goldenrod))",
-            "-moz-linear-gradient(20px 10px, 100px top, from(rgb(10, 100, 0)), color-stop(1, rgba(10, 20, 30, 0.4)))",
-            "-moz-radial-gradient(center top, 10px, right bottom, 20px, color-stop(0.7, green), color-stop(20%, #ccddee), from(rgb(1, 2, 3)), color-stop(0.95, #aa0012))",
-            "-moz-linear-gradient(10px 20%, -50px -10%, from(green))",
-            "-moz-linear-gradient(10px 10px, 20px 20px)",
-            "-moz-linear-gradient(10px 10px, 20px 20px, color-stop(314%, blue))",
-            "-moz-linear-gradient(10px 10px, 20px 20px, color-stop(-0.2, green))",
-            "-moz-linear-gradient( 10px  10px  , 40px 20px ,  from(blue)  )"
+			"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==), url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==)"
 		],
-		invalid_values: [ "-moz-linear-gradient(10px 10px, 20px, 30px 30px, 40px, from(blue), to(red))",
-                          "-moz-radial-gradient(20px 20px, 10px 10px, from(green), to(#ff00ff))",
-                          "-moz-radial-gradient(10px 10px, 20%, 40px 40px, 10px, from(green), to(#ff00ff))",
-                          "-moz-linear-gradient(10px, 20px, 30px, 40px, color-stop(0.5, #00ccff))",
-                          "-moz-linear-gradient(20px 20px, from(blue), to(red))",
-                          "-moz-linear-gradient(40px 40px, 10px 10px, from(blue) to(red) color-stop(10%, fuchsia))",
-                          "-moz-linear-gradient(20px 20px 30px, 10px 10px, from(red), to(#ff0000))",
-                          "-moz-radial-gradient(left top, center, 20px 20px, 10px, from(blue), to(red))",
-                          "-moz-linear-gradient(left left, top top, from(blue))",
-                          "-moz-linear-gradient(inherit, 10px 10px, from(blue))",
-                          "-moz-linear-gradient()" ]
+		invalid_values: []
 	},
 	"background-position": {
 		domProp: "backgroundPosition",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		/* is "0px 0px" an initial value or not? */
 		initial_values: [ "top left", "left top", "0% 0%", "0% top", "left 0%" ],
 		other_values: [ "top", "left", "right", "bottom", "center", "center bottom", "bottom center", "center right", "right center", "center top", "top center", "center left", "left center", "right bottom", "bottom right", "50%", "top left, top left", "top left, top right", "top right, top left", "left top, 0% 0%", "10% 20%, 30%, 40%", "top left, bottom right", "right bottom, left top", "0%", "0px", "30px", "0%, 10%, 20%, 30%", "top, top, top, top, top" ],
--- a/layout/tables/nsTablePainter.cpp
+++ b/layout/tables/nsTablePainter.cpp
@@ -197,17 +197,17 @@ inline PRBool
 TableBackgroundPainter::TableBackgroundData::ShouldSetBCBorder()
 {
   /* we only need accurate border data when positioning background images*/
   if (!mBackground) {
     return PR_FALSE;
   }
 
   NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, mBackground) {
-    if (mBackground->mLayers[i].mImage.GetType() != eBackgroundImage_Null)
+    if (mBackground->mLayers[i].mImage)
       return PR_TRUE;
   }
   return PR_FALSE;
 }
 
 nsresult
 TableBackgroundPainter::TableBackgroundData::SetBCBorder(nsMargin& aBorder,
                                                          TableBackgroundPainter* aPainter)
--- a/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
+++ b/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
@@ -4113,17 +4113,17 @@ nsTreeBodyFrame::ScrollInternal(const Sc
       return NS_OK;
   }
 
   mTopRowIndex += delta;
 
   // See if we have a transparent background or a background image.  
   // If we do, then we cannot blit.
   const nsStyleBackground* background = GetStyleBackground();
-  if (background->BottomLayer().mImage.GetType() != eBackgroundImage_Null ||
+  if (background->BottomLayer().mImage ||
       background->mImageCount > 1 ||
       NS_GET_A(background->mBackgroundColor) < 255 ||
       PR_ABS(delta)*mRowHeight >= mRect.height) {
     Invalidate();
   } else {
     nsIWidget* widget = nsLeafBoxFrame::GetView()->GetWidget();
     if (widget) {
       nscoord rowHeightAsPixels =
@@ -4170,17 +4170,17 @@ nsTreeBodyFrame::ScrollHorzInternal(cons
     aPosition = mHorzWidth - bounds.width;
 
   PRInt32 delta = aPosition - mHorzPosition;
   mHorzPosition = aPosition;
 
   // See if we have a transparent background or a background image.  
   // If we do, then we cannot blit.
   const nsStyleBackground* background = GetStyleBackground();
-  if (background->BottomLayer().mImage.GetType() != eBackgroundImage_Null ||
+  if (background->BottomLayer().mImage ||
       background->mImageCount > 1 ||
       NS_GET_A(background->mBackgroundColor) < 255 ||
       PR_ABS(delta) >= mRect.width) {
     Invalidate();
   } else {
     nsIWidget* widget = nsLeafBoxFrame::GetView()->GetWidget();
     if (widget) {
       nsIntPoint deltaPt(PresContext()->AppUnitsToDevPixels(-delta), 0);