Remove support for fallback background colors. (Bug 496721) r+sr=bzbarsky
authorL. David Baron <dbaron@dbaron.org>
Tue, 16 Jun 2009 08:00:20 -0700
changeset 29266 37f8a33e4c54c159bda6f7057709ad2defda1553
parent 29265 c83c5f5c3b1973d4567b6fa12582b30db3cc1c14
child 29267 97e34ff5d496215fdf86ff5e79c626c6f4667413
push idunknown
push userunknown
push dateunknown
bugs496721
milestone1.9.2a1pre
Remove support for fallback background colors. (Bug 496721) r+sr=bzbarsky
accessible/src/base/nsTextAttrs.cpp
content/html/content/src/nsGenericHTMLElement.cpp
content/mathml/content/src/nsMathMLElement.cpp
layout/base/nsCSSRendering.cpp
layout/base/nsDisplayList.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsPresContext.cpp
layout/generic/nsFrame.cpp
layout/reftests/backgrounds/fallback-color-1.xhtml
layout/reftests/backgrounds/fallback-color-2.xhtml
layout/reftests/backgrounds/fallback-color-3.xhtml
layout/reftests/backgrounds/fallback-color-4.xhtml
layout/reftests/backgrounds/fallback-color-5.xhtml
layout/reftests/backgrounds/fallback-color-6.xhtml
layout/reftests/backgrounds/fallback-color-7.xhtml
layout/reftests/backgrounds/fallback-color-8.xhtml
layout/reftests/backgrounds/fallback-color-9.xhtml
layout/reftests/backgrounds/fallback-color-ref.xhtml
layout/reftests/backgrounds/reftest.list
layout/reftests/bugs/289480.html
layout/style/nsCSSDataBlock.cpp
layout/style/nsCSSParser.cpp
layout/style/nsCSSPropList.h
layout/style/nsCSSStruct.h
layout/style/nsComputedDOMStyle.cpp
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/accessible/src/base/nsTextAttrs.cpp
+++ b/accessible/src/base/nsTextAttrs.cpp
@@ -526,18 +526,18 @@ nsBGColorTextAttr::Format(const nscolor&
   aFormattedValue = value;
 }
 
 PRBool
 nsBGColorTextAttr::GetColor(nsIFrame *aFrame, nscolor *aColor)
 {
   const nsStyleBackground *styleBackground = aFrame->GetStyleBackground();
 
-  if (NS_GET_A(styleBackground->mFallbackBackgroundColor) > 0) {
-    *aColor = styleBackground->mFallbackBackgroundColor;
+  if (NS_GET_A(styleBackground->mBackgroundColor) > 0) {
+    *aColor = styleBackground->mBackgroundColor;
     return PR_TRUE;
   }
 
   nsIFrame *parentFrame = aFrame->GetParent();
   if (!parentFrame) {
     *aColor = aFrame->PresContext()->DefaultBackgroundColor();
     return PR_TRUE;
   }
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -1944,26 +1944,22 @@ nsGenericHTMLElement::MapBackgroundInto(
 
 void
 nsGenericHTMLElement::MapBGColorInto(const nsMappedAttributes* aAttributes,
                                      nsRuleData* aData)
 {
   if (!(aData->mSIDs & NS_STYLE_INHERIT_BIT(Background)))
     return;
 
-  if (aData->mColorData->mBackColor.mXValue.GetUnit() == eCSSUnit_Null &&
+  if (aData->mColorData->mBackColor.GetUnit() == eCSSUnit_Null &&
       aData->mPresContext->UseDocumentColors()) {
-    NS_ASSERTION(aData->mColorData->mBackColor.mYValue.GetUnit() ==
-                   eCSSUnit_Null,
-                 "half a property?");
     const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::bgcolor);
     nscolor color;
     if (value && value->GetColorValue(color)) {
-      aData->mColorData->mBackColor.mXValue.SetColorValue(color);
-      aData->mColorData->mBackColor.mYValue.SetColorValue(color);
+      aData->mColorData->mBackColor.SetColorValue(color);
     }
   }
 }
 
 void
 nsGenericHTMLElement::MapBackgroundAttributesInto(const nsMappedAttributes* aAttributes,
                                                   nsRuleData* aData)
 {
--- a/content/mathml/content/src/nsMathMLElement.cpp
+++ b/content/mathml/content/src/nsMathMLElement.cpp
@@ -372,25 +372,20 @@ nsMathMLElement::MapMathMLAttributesInto
   }
 
   if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Background)) {
     const nsAttrValue* value =
       aAttributes->GetAttr(nsGkAtoms::mathbackground_);
     if (!value) {
       value = aAttributes->GetAttr(nsGkAtoms::background);
     }
-    if (value &&
-        aData->mColorData->mBackColor.mXValue.GetUnit() == eCSSUnit_Null) {
-      NS_ASSERTION(aData->mColorData->mBackColor.mYValue.GetUnit()
-                     == eCSSUnit_Null,
-                   "half a property?");
+    if (value && aData->mColorData->mBackColor.GetUnit() == eCSSUnit_Null) {
       nscolor color;
       if (value->GetColorValue(color)) {
-        aData->mColorData->mBackColor.mXValue.SetColorValue(color);
-        aData->mColorData->mBackColor.mYValue.SetColorValue(color);
+        aData->mColorData->mBackColor.SetColorValue(color);
       }
     }
   }
 
   if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Color)) {
     const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::mathcolor_);
     if (!value) {
       value = aAttributes->GetAttr(nsGkAtoms::color);
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -1531,36 +1531,28 @@ nsCSSRendering::PaintBackgroundWithSC(ns
   PRBool drawBackgroundImage = PR_TRUE;
   PRBool drawBackgroundColor = PR_TRUE;
   PRBool usePrintSettings = aForFrame->HonorPrintBackgroundSettings();
   if (usePrintSettings) {
     drawBackgroundImage = aPresContext->GetBackgroundImageDraw();
     drawBackgroundColor = aPresContext->GetBackgroundColorDraw();
   }
 
-  nsStyleBackground::Image bottomImage(aColor.BottomLayer().mImage);
-  PRBool useFallbackColor = PR_FALSE;
-  if (bottomImage.mSpecified) {
-    if (!drawBackgroundImage ||
-        !UseImageRequestForBackground(bottomImage.mRequest)) {
-      bottomImage.mRequest = nsnull;
-    }
-    useFallbackColor = bottomImage.mRequest == nsnull;
-  } else {
-    NS_ASSERTION(bottomImage.mRequest == nsnull, "malformed image struct");
+  imgIRequest *bottomImage = aColor.BottomLayer().mImage;
+  if (!drawBackgroundImage || !UseImageRequestForBackground(bottomImage)) {
+    bottomImage = nsnull;
   }
 
   // If GetBackgroundColorDraw() is false, we are still expected to
   // draw color in the background of any frame that's not completely
   // transparent, but we are expected to use white instead of whatever
   // color was specified.
   nscolor bgColor;
   if (drawBackgroundColor) {
-    bgColor = useFallbackColor ? aColor.mFallbackBackgroundColor
-                               : aColor.mBackgroundColor;
+    bgColor = aColor.mBackgroundColor;
     if (NS_GET_A(bgColor) == 0)
       drawBackgroundColor = PR_FALSE;
   } else {
     bgColor = NS_RGB(255, 255, 255);
     if (drawBackgroundImage || !aColor.IsTransparent())
       drawBackgroundColor = PR_TRUE;
   }
 
@@ -1638,21 +1630,21 @@ nsCSSRendering::PaintBackgroundWithSC(ns
     return;
   }
 
   // Ensure we get invalidated for loads of the image.  We need to do
   // this here because this might be the only code that knows about the
   // association of the style data with the frame.
   aPresContext->SetupBackgroundImageLoaders(aForFrame, &aColor);
 
-  if (bottomImage.mRequest &&
+  if (bottomImage &&
       aColor.BottomLayer().mRepeat == NS_STYLE_BG_REPEAT_XY &&
       drawBackgroundColor) {
     nsCOMPtr<imgIContainer> image;
-    bottomImage.mRequest->GetImage(getter_AddRefs(image));
+    bottomImage->GetImage(getter_AddRefs(image));
     // If the image is completely opaque, we may not need to paint
     // the background color.
     nsCOMPtr<gfxIImageFrame> gfxImgFrame;
     image->GetCurrentFrame(getter_AddRefs(gfxImgFrame));
     if (gfxImgFrame) {
       gfxImgFrame->GetNeedsBackground(&drawBackgroundColor);
       if (!drawBackgroundColor) {
         // If the current frame is smaller than its container, we
@@ -1712,17 +1704,17 @@ PaintBackgroundLayer(nsPresContext* aPre
                      const nsRect& aBorderArea,
                      const nsRect& aBGClipRect,
                      const nsStyleBackground& aBackground,
                      const nsStyleBackground::Layer& aLayer,
                      const nsStyleBorder& aBorder,
                      PRBool aUsePrintSettings)
 {
   // Lookup the image
-  imgIRequest *req = aLayer.mImage.mRequest;
+  imgIRequest *req = aLayer.mImage;
   if (!UseImageRequestForBackground(req)) {
     // There's no image or it's not ready to be painted.
     return;
   }
 
   nsCOMPtr<imgIContainer> image;
   req->GetImage(getter_AddRefs(image));
 
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -545,19 +545,19 @@ nsDisplayBackground::IsOpaque(nsDisplayL
   if (bottomLayer.mClip != NS_STYLE_BG_CLIP_BORDER ||
       nsLayoutUtils::HasNonZeroCorner(mFrame->GetStyleBorder()->mBorderRadius))
     return PR_FALSE;
 
   if (NS_GET_A(bg->mBackgroundColor) == 255)
     return PR_TRUE;
 
   if (bottomLayer.mRepeat == NS_STYLE_BG_REPEAT_XY) {
-    if (bottomLayer.mImage.mRequest) {
+    if (bottomLayer.mImage) {
       nsCOMPtr<imgIContainer> container;
-      bottomLayer.mImage.mRequest->GetImage(getter_AddRefs(container));
+      bottomLayer.mImage->GetImage(getter_AddRefs(container));
       if (container) {
         PRUint32 nframes;
         container->GetNumFrames(&nframes);
         if (nframes == 1) {
           nsCOMPtr<gfxIImageFrame> imgFrame;
           container->GetCurrentFrame(getter_AddRefs(imgFrame));
           if (imgFrame) {
             nsCOMPtr<nsIImage> img(do_GetInterface(imgFrame));
@@ -580,17 +580,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.mRequest &&
+  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/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -3136,17 +3136,16 @@ nsLayoutUtils::GetFrameTransparency(nsIF
       !aFrame->GetFirstChild(nsnull)) {
     return eTransparencyOpaque;
   }
 
   const nsStyleBackground* bg;
   if (!nsCSSRendering::FindBackground(aFrame->PresContext(), aFrame, &bg))
     return eTransparencyTransparent;
   if (NS_GET_A(bg->mBackgroundColor) < 255 ||
-      NS_GET_A(bg->mFallbackBackgroundColor) < 255 ||
       // bottom layer's clip is used for the color
       bg->BottomLayer().mClip != NS_STYLE_BG_CLIP_BORDER)
     return eTransparencyTransparent;
   return eTransparencyOpaque;
 }
 
 static PRBool
 IsNonzeroCoord(const nsStyleCoord& aCoord)
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -1260,17 +1260,17 @@ nsPresContext::SetImageLoaders(nsIFrame*
 }
 
 void
 nsPresContext::SetupBackgroundImageLoaders(nsIFrame* aFrame,
                                      const nsStyleBackground* aStyleBackground)
 {
   nsRefPtr<nsImageLoader> loaders;
   NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, aStyleBackground) {
-    imgIRequest *image = aStyleBackground->mLayers[i].mImage.mRequest;
+    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
@@ -528,19 +528,19 @@ 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) {
-      imgIRequest *oldImage = oldBG->mLayers[i].mImage.mRequest;
+      imgIRequest *oldImage = oldBG->mLayers[i].mImage;
       imgIRequest *newImage = i < newBG->mImageCount
-                                ? newBG->mLayers[i].mImage.mRequest.get()
+                                ? 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;
       }
     }
@@ -4057,17 +4057,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.mRequest &&
+    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/backgrounds/fallback-color-1.xhtml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-	<head>
-		<title>css3-background: fallback colors</title>
-		<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
-		<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
-		<link rel="help" href="http://dev.w3.org/csswg/css3-background/#background-color" />
-		<meta name="flags" content="" />
-		<meta name="assert" content="Fallback color only applied when there is an image." />
-		<style type="text/css"><![CDATA[
-
-		div {
-			width: 100px;
-			height: 100px;
-			background: lime red;
-		}
-
-		]]></style>
-	</head>
-	<body>
-
-	<div></div>
-
-	</body>
-</html>
deleted file mode 100644
--- a/layout/reftests/backgrounds/fallback-color-2.xhtml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-	<head>
-		<title>css3-background: fallback colors</title>
-		<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
-		<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
-		<link rel="help" href="http://dev.w3.org/csswg/css3-background/#background-color" />
-		<meta name="flags" content="" />
-		<meta name="assert" content="Fallback color only applied when there is an image." />
-		<style type="text/css"><![CDATA[
-
-		div {
-			width: 100px;
-			height: 100px;
-			background-color: lime red;
-		}
-
-		]]></style>
-	</head>
-	<body>
-
-	<div></div>
-
-	</body>
-</html>
deleted file mode 100644
--- a/layout/reftests/backgrounds/fallback-color-3.xhtml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-	<head>
-		<title>css3-background: fallback colors</title>
-		<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
-		<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
-		<link rel="help" href="http://dev.w3.org/csswg/css3-background/#background-color" />
-		<meta name="flags" content="" />
-		<meta name="assert" content="Fallback color not applied when background image loads successfully." />
-		<style type="text/css"><![CDATA[
-
-		div {
-			width: 100px;
-			height: 100px;
-			background: url(transparent-32x32.png) lime red;
-		}
-
-		]]></style>
-	</head>
-	<body>
-
-	<div></div>
-
-	</body>
-</html>
deleted file mode 100644
--- a/layout/reftests/backgrounds/fallback-color-4.xhtml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-	<head>
-		<title>css3-background: fallback colors</title>
-		<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
-		<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
-		<link rel="help" href="http://dev.w3.org/csswg/css3-background/#background-color" />
-		<meta name="flags" content="" />
-		<meta name="assert" content="Fallback color applied when background image corrupted." />
-		<style type="text/css"><![CDATA[
-
-		div {
-			width: 100px;
-			height: 100px;
-			background: url(malformed.png) red lime;
-		}
-
-		]]></style>
-	</head>
-	<body>
-
-	<div></div>
-
-	</body>
-</html>
deleted file mode 100644
--- a/layout/reftests/backgrounds/fallback-color-5.xhtml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-	<head>
-		<title>css3-background: fallback colors</title>
-		<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
-		<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
-		<link rel="help" href="http://dev.w3.org/csswg/css3-background/#background-color" />
-		<meta name="flags" content="" />
-		<meta name="assert" content="Fallback color applied when background image missing." />
-		<style type="text/css"><![CDATA[
-
-		div {
-			width: 100px;
-			height: 100px;
-			background: url(404.png) red lime;
-		}
-
-		]]></style>
-	</head>
-	<body>
-
-	<div></div>
-
-	</body>
-</html>
deleted file mode 100644
--- a/layout/reftests/backgrounds/fallback-color-6.xhtml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-	<head>
-		<title>css3-background: fallback colors</title>
-		<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
-		<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
-		<link rel="help" href="http://dev.w3.org/csswg/css3-background/#background-color" />
-		<meta name="flags" content="" />
-		<meta name="assert" content="Fallback color is based on whether the *bottom-most* image is corrupted." />
-		<style type="text/css"><![CDATA[
-
-		div {
-			width: 100px;
-			height: 100px;
-			background: url(transparent-32x32.png), url(malformed.png) red lime;
-		}
-
-		]]></style>
-	</head>
-	<body>
-
-	<div></div>
-
-	</body>
-</html>
deleted file mode 100644
--- a/layout/reftests/backgrounds/fallback-color-7.xhtml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-	<head>
-		<title>css3-background: fallback colors</title>
-		<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
-		<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
-		<link rel="help" href="http://dev.w3.org/csswg/css3-background/#background-color" />
-		<meta name="flags" content="" />
-		<meta name="assert" content="Fallback color is based on whether the *bottom-most* image is corrupted." />
-		<style type="text/css"><![CDATA[
-
-		div {
-			width: 100px;
-			height: 100px;
-			background: url(malformed.png), url(transparent-32x32.png) lime red;
-		}
-
-		]]></style>
-	</head>
-	<body>
-
-	<div></div>
-
-	</body>
-</html>
deleted file mode 100644
--- a/layout/reftests/backgrounds/fallback-color-8.xhtml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-	<head>
-		<title>css3-background: fallback colors</title>
-		<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
-		<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
-		<link rel="help" href="http://dev.w3.org/csswg/css3-background/#background-color" />
-		<meta name="flags" content="" />
-		<meta name="assert" content="Fallback color is based on whether the *bottom-most* image is missing." />
-		<style type="text/css"><![CDATA[
-
-		div {
-			width: 100px;
-			height: 100px;
-			background: url(transparent-32x32.png), url(404.png) red lime;
-		}
-
-		]]></style>
-	</head>
-	<body>
-
-	<div></div>
-
-	</body>
-</html>
deleted file mode 100644
--- a/layout/reftests/backgrounds/fallback-color-9.xhtml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-	<head>
-		<title>css3-background: fallback colors</title>
-		<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
-		<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
-		<link rel="help" href="http://dev.w3.org/csswg/css3-background/#background-color" />
-		<meta name="flags" content="" />
-		<meta name="assert" content="Fallback color is based on whether the *bottom-most* image is missing." />
-		<style type="text/css"><![CDATA[
-
-		div {
-			width: 100px;
-			height: 100px;
-			background: url(404.png), url(transparent-32x32.png) lime red;
-		}
-
-		]]></style>
-	</head>
-	<body>
-
-	<div></div>
-
-	</body>
-</html>
deleted file mode 100644
--- a/layout/reftests/backgrounds/fallback-color-ref.xhtml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-	<head>
-		<title>css3-background: fallback colors</title>
-		<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
-		<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
-		<link rel="help" href="http://dev.w3.org/csswg/css3-background/#background-color" />
-		<meta name="flags" content="" />
-		<style type="text/css"><![CDATA[
-
-		div {
-			width: 100px;
-			height: 100px;
-			background: url(lime-32x32.png);
-		}
-
-		]]></style>
-	</head>
-	<body>
-
-	<div></div>
-
-	</body>
-</html>
--- a/layout/reftests/backgrounds/reftest.list
+++ b/layout/reftests/backgrounds/reftest.list
@@ -1,18 +1,8 @@
-== fallback-color-1.xhtml fallback-color-ref.xhtml
-== fallback-color-2.xhtml fallback-color-ref.xhtml
-== fallback-color-3.xhtml fallback-color-ref.xhtml
-== fallback-color-4.xhtml fallback-color-ref.xhtml
-== fallback-color-5.xhtml fallback-color-ref.xhtml
-== fallback-color-6.xhtml fallback-color-ref.xhtml
-== fallback-color-7.xhtml fallback-color-ref.xhtml
-== fallback-color-8.xhtml fallback-color-ref.xhtml
-== fallback-color-9.xhtml fallback-color-ref.xhtml
-!= fallback-color-ref.xhtml about:blank
 == layers-stacking-order.xhtml layers-stacking-order-ref.xhtml
 == layers-layer-count-cascade-1.xhtml layers-layer-count-1-ref.xhtml
 == layers-layer-count-inheritance-1.xhtml layers-layer-count-1-ref.xhtml
 == layers-layer-count-cascade-2.xhtml layers-layer-count-2-ref.xhtml
 == layers-layer-count-inheritance-2.xhtml layers-layer-count-2-ref.xhtml
 == continuous-inline-1a.html continuous-inline-1-ref.html
 == continuous-inline-1b.html continuous-inline-1-ref.html
 == continuous-inline-1c.html continuous-inline-1-ref.html
--- a/layout/reftests/bugs/289480.html
+++ b/layout/reftests/bugs/289480.html
@@ -93,17 +93,17 @@
    .parser { /* comment parsing test -- comment ends before the end of this line, the backslash should have no effect: \*/ }
    .parser { margin: 0 5em 1em; padding: 0 1em; width: 2em; height: 1em; error: \}; background: yellow; } /* setup with parsing test */
    * html .parser {  background: gray; }
    \.parser { padding: 2em; }
    .parser { m\argin: 2em; };
    .parser { height: 3em; }
    .parser { width: 200; }
    .parser { border: 5em solid red ! error; }
-   .parser { background: red pink pink; }
+   .parser { background: red pink; }
 
    /* line fourteen (last line of face): table */
    ul { display: table; padding: 0; margin: -1em 7em 0; background: red; }
    ul li { padding: 0; margin: 0; }
    ul li.first-part { display: table-cell; height: 1em; width: 1em; background: black; }
    ul li.second-part { display: table; height: 1em; width: 1em; background: black; } /* anonymous table cell wraps around this */
    ul li.third-part { display: table-cell; height: 0.5em; /* gets stretched to fit row */ width: 1em; background: black; }
    ul li.fourth-part { list-style: none; height: 1em; width: 1em; background: black; } /* anonymous table cell wraps around this */
--- a/layout/style/nsCSSDataBlock.cpp
+++ b/layout/style/nsCSSDataBlock.cpp
@@ -211,29 +211,53 @@ nsCSSCompressedDataBlock::MapRuleInfoInt
                             }
                         }
                         *target = *val;
                         if (iProp == eCSSProperty_font_family) {
                             // XXX Are there other things like this?
                             aRuleData->mFontData->mFamilyFromHTML = PR_FALSE;
                         }
                         else if (iProp == eCSSProperty_color ||
+                                 iProp == eCSSProperty_background_color ||
                                  iProp == eCSSProperty_border_top_color ||
                                  iProp == eCSSProperty_border_right_color_value ||
                                  iProp == eCSSProperty_border_right_color_ltr_source ||
                                  iProp == eCSSProperty_border_right_color_rtl_source ||
                                  iProp == eCSSProperty_border_bottom_color ||
                                  iProp == eCSSProperty_border_left_color_value ||
                                  iProp == eCSSProperty_border_left_color_ltr_source ||
                                  iProp == eCSSProperty_border_left_color_rtl_source ||
                                  iProp == eCSSProperty__moz_column_rule_color ||
                                  iProp == eCSSProperty_outline_color) {
                             if (ShouldIgnoreColors(aRuleData)) {
-                                // Ignore 'color', 'border-*-color', etc.
-                                *target = nsCSSValue();
+                                if (iProp == eCSSProperty_background_color) {
+                                    // Force non-'transparent' background
+                                    // colors to the user's default.
+                                    // We have the value in the form it was
+                                    // specified at this point, so we have to
+                                    // look for both the keyword 'transparent'
+                                    // and its equivalent in rgba notation.
+                                    nsCSSUnit u = target->GetUnit();
+                                    nsDependentString buf;
+                            
+                                    if ((u == eCSSUnit_Color &&
+                                         NS_GET_A(target->GetColorValue())
+                                         > 0) ||
+                                        (u == eCSSUnit_Ident &&
+                                         !nsGkAtoms::transparent->
+                                         Equals(target->GetStringValue(buf))) ||
+                                        (u == eCSSUnit_EnumColor)) {
+                                        target->SetColorValue(aRuleData->
+                                            mPresContext->
+                                            DefaultBackgroundColor());
+                                    }
+                                } else {
+                                    // Ignore 'color', 'border-*-color', etc.
+                                    *target = nsCSSValue();
+                                }
                             }
                         }
                     }
                     cursor += CDBValueStorage_advance;
                 } break;
 
                 case eCSSType_Rect: {
                     const nsCSSRect* val = RectAtCursor(cursor);
@@ -256,47 +280,16 @@ nsCSSCompressedDataBlock::MapRuleInfoInt
                                  val->mYValue.GetUnit() != eCSSUnit_Null, "oops");
                     nsCSSValuePair* target = static_cast<nsCSSValuePair*>(prop);
                     NS_ASSERTION((target->mXValue.GetUnit() == eCSSUnit_Null)
                               == (target->mYValue.GetUnit() == eCSSUnit_Null),
                                  "half a property?");
                     if (target->mXValue.GetUnit() == eCSSUnit_Null) {
                         target->mXValue = val->mXValue;
                         target->mYValue = val->mYValue;
-                        if (iProp == eCSSProperty_background_color &&
-                            ShouldIgnoreColors(aRuleData)) {
-                            // Force non-'transparent' background colors
-                            // to the user's default.  We have the value
-                            // in the form it was specified at this
-                            // point, so we have to look for both the
-                            // keyword 'transparent' and its equivalent
-                            // in rgba notation.
-                            nsCSSValue &colorVal = target->mXValue;
-                            nsCSSUnit u = colorVal.GetUnit();
-                            nsDependentString buf;
-                            
-                            if ((u == eCSSUnit_Color &&
-                                 NS_GET_A(colorVal.GetColorValue())
-                                 > 0) ||
-                                (u == eCSSUnit_Ident &&
-                                 !nsGkAtoms::transparent->
-                                 Equals(colorVal.GetStringValue(buf))) ||
-                                (u == eCSSUnit_EnumColor)) {
-                                colorVal.SetColorValue(aRuleData->
-                                    mPresContext->
-                                    DefaultBackgroundColor());
-                            }
-                            // We could consider using the fallback
-                            // background color for both values, but it
-                            // might not make sense if the author didn't
-                            // specify an image.  But since we're
-                            // dropping author images, we'll just use
-                            // the non-fallback for both.
-                            target->mYValue = target->mXValue;
-                        }
                     }
                     cursor += CDBValuePairStorage_advance;
                 } break;
 
                 case eCSSType_ValueList:
                     if (iProp == eCSSProperty_background_image ||
                         iProp == eCSSProperty_content) {
                         for (nsCSSValueList* l = ValueListAtCursor(cursor);
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -408,17 +408,16 @@ protected:
   struct BackgroundItemSimpleValueInfo {
     nsCSSValue BackgroundItem::*member;
     nsCSSProperty propID;
   };
 
   PRBool ParseBackgroundItem(BackgroundItem& aItem, PRBool aFirstItem);
 
   PRBool ParseBackgroundList(nsCSSProperty aPropID); // a single value prop-id
-  PRBool ParseBackgroundColor(PRBool aInShorthand);
   PRBool ParseBackgroundPosition();
   PRBool ParseBoxPositionValues(nsCSSValuePair& aOut);
   PRBool ParseBorderColor();
   PRBool ParseBorderColors(nsCSSValueList** aResult,
                            nsCSSProperty aProperty);
   PRBool ParseBorderImage();
   PRBool ParseBorderSpacing();
   PRBool ParseBorderSide(const nsCSSProperty aPropIDs[],
@@ -5008,18 +5007,16 @@ static const nsCSSProperty kOutlineRadiu
 PRBool
 CSSParserImpl::ParseProperty(nsCSSProperty aPropID)
 {
   NS_ASSERTION(aPropID < eCSSProperty_COUNT, "index out of range");
 
   switch (aPropID) {  // handle shorthand or multiple properties
   case eCSSProperty_background:
     return ParseBackground();
-  case eCSSProperty_background_color:
-    return ParseBackgroundColor(PR_FALSE);
   case eCSSProperty_background_position:
     return ParseBackgroundPosition();
   case eCSSProperty_background_attachment:
   case eCSSProperty__moz_background_clip:
   case eCSSProperty_background_image:
   case eCSSProperty__moz_background_origin:
   case eCSSProperty_background_repeat:
     return ParseBackgroundList(aPropID);
@@ -5269,17 +5266,16 @@ CSSParserImpl::ParseProperty(nsCSSProper
 
 PRBool
 CSSParserImpl::ParseSingleValueProperty(nsCSSValue& aValue,
                                         nsCSSProperty aPropID)
 {
   switch (aPropID) {
   case eCSSProperty_UNKNOWN:
   case eCSSProperty_background:
-  case eCSSProperty_background_color:
   case eCSSProperty_background_position:
   case eCSSProperty_border:
   case eCSSProperty_border_color:
   case eCSSProperty_border_bottom_colors:
   case eCSSProperty_border_image:
   case eCSSProperty_border_left_colors:
   case eCSSProperty_border_right_colors:
   case eCSSProperty_border_end_color:
@@ -5389,16 +5385,18 @@ CSSParserImpl::ParseSingleValueProperty(
   case eCSSProperty_background_attachment:
     // Used only internally.
     return ParseVariant(aValue, VARIANT_HK,
                         nsCSSProps::kBackgroundAttachmentKTable);
   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, nsnull);
   case eCSSProperty__moz_background_inline_policy:
     return ParseVariant(aValue, VARIANT_HK,
                         nsCSSProps::kBackgroundInlinePolicyKTable);
   case eCSSProperty__moz_background_origin:
     // Used only internally.
@@ -5938,18 +5936,17 @@ BoxPositionMaskToCSSValue(PRInt32 aMask,
 
 PRBool
 CSSParserImpl::ParseBackground()
 {
   nsAutoParseCompoundProperty compound(this);
 
   // These two are set through side-effects of ParseBackgroundItem.
   mTempData.SetPropertyBit(eCSSProperty_background_color);
-  mTempData.mColor.mBackColor.mXValue.SetColorValue(NS_RGBA(0, 0, 0, 0));
-  mTempData.mColor.mBackColor.mYValue.SetColorValue(NS_RGBA(0, 0, 0, 0));
+  mTempData.mColor.mBackColor.SetColorValue(NS_RGBA(0, 0, 0, 0));
 
   BackgroundItem bgitem;
   nsCSSValuePairList *positionHead = nsnull, **positionTail = &positionHead;
   static const BackgroundItemSimpleValueInfo simpleValues[] = {
     { &BackgroundItem::mImage,      eCSSProperty_background_image },
     { &BackgroundItem::mRepeat,     eCSSProperty_background_repeat },
     { &BackgroundItem::mAttachment, eCSSProperty_background_attachment },
     { &BackgroundItem::mClip,       eCSSProperty__moz_background_clip },
@@ -6063,17 +6060,17 @@ CSSParserImpl::ParseBackgroundItem(CSSPa
           PR_TRUE;
         GetToken(PR_TRUE); // undo the UngetToken above
         nsCSSValue val;
         if (keyword == eCSSKeyword_inherit) {
           val.SetInheritValue();
         } else {
           val.SetInitialValue();
         }
-        mTempData.mColor.mBackColor.SetBothValuesTo(val);
+        mTempData.mColor.mBackColor = val;
         aItem.mImage = val;
         aItem.mRepeat = val;
         aItem.mAttachment = val;
         aItem.mPosition.SetBothValuesTo(val);
         aItem.mClip = val;
         aItem.mOrigin = val;
         aItem.mLastItem = PR_TRUE;
         haveSomething = PR_TRUE;
@@ -6147,17 +6144,18 @@ CSSParserImpl::ParseBackgroundItem(CSSPa
         // When we support 'no-clip', this needs to be conditional on haveClip:
         aItem.mClip = aItem.mOrigin;
       // We'd support 'no-clip' as an additional |else| here.
 #endif
       } else {
         if (haveColor)
           return PR_FALSE;
         haveColor = PR_TRUE;
-        if (!ParseBackgroundColor(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")) {
       if (haveImage)
         return PR_FALSE;
@@ -6172,19 +6170,20 @@ CSSParserImpl::ParseBackgroundItem(CSSPa
       havePosition = PR_TRUE;
       if (!ParseBoxPositionValues(aItem.mPosition)) {
         return PR_FALSE;
       }
     } else {
       if (haveColor)
         return PR_FALSE;
       haveColor = PR_TRUE;
-      // Note: ParseBackgroundColor parses 'inherit' and 'initial', but
+      // Note: This parses 'inherit' and 'initial', but
       // we've already checked for them, so it's ok.
-      if (!ParseBackgroundColor(PR_TRUE)) {
+      if (!ParseSingleValueProperty(mTempData.mColor.mBackColor,
+                                    eCSSProperty_background_color)) {
         return PR_FALSE;
       }
       aItem.mLastItem = PR_TRUE;
     }
     haveSomething = PR_TRUE;
   }
 
   return haveSomething;
@@ -6226,42 +6225,16 @@ CSSParserImpl::ParseBackgroundList(nsCSS
     *source = head;
     mTempData.SetPropertyBit(aPropID);
     return PR_TRUE;
   }
   delete head;
   return PR_FALSE;
 }
 
-PRBool
-CSSParserImpl::ParseBackgroundColor(PRBool aInShorthand)
-{
-  nsCSSValuePair &backColor = mTempData.mColor.mBackColor;
-  mTempData.SetPropertyBit(eCSSProperty_background_color);
-  if (!ParseVariant(backColor.mXValue,
-                    aInShorthand ? VARIANT_COLOR : VARIANT_HC, nsnull)) {
-    return PR_FALSE;
-  }
-  backColor.mYValue = backColor.mXValue;
-  switch (backColor.mXValue.GetUnit()) {
-    case eCSSUnit_Inherit:
-    case eCSSUnit_Initial:
-      NS_ASSERTION(!aInShorthand,
-                   "should not get inherit or initial in shorthand");
-      return ExpectEndProperty(); // we're done
-    default:
-      break;
-  }
-
-  // Ignore success, since the value is optional.
-  ParseVariant(backColor.mYValue, VARIANT_COLOR, nsnull);
-
-  return aInShorthand || ExpectEndProperty();
-}
-
 // This function is very similar to ParseBackgroundList.
 PRBool
 CSSParserImpl::ParseBackgroundPosition()
 {
   // aPropID is a single value prop-id
   nsCSSValuePair valuePair;
   nsCSSValuePairList *head = nsnull, **tail = &head;
   for (;;) {
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -287,17 +287,17 @@ CSS_PROP_OUTLINE(-moz-outline-radius-bot
 CSS_PROP_OUTLINE(-moz-outline-radius-bottomleft, _moz_outline_radius_bottomLeft, MozOutlineRadiusBottomleft, 0, Margin, mOutlineRadius.mBottomLeft, eCSSType_ValuePair, nsnull)
 #ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
 CSS_PROP_FONT(-x-system-font, _x_system_font, X, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE, Font, mSystemFont, eCSSType_Value, kFontKTable)
 #endif
 CSS_PROP_BACKENDONLY(azimuth, azimuth, Azimuth, 0, Aural, mAzimuth, eCSSType_Value, kAzimuthKTable)
 CSS_PROP_SHORTHAND(background, background, Background, 0)
 CSS_PROP_BACKGROUND(background-attachment, background_attachment, BackgroundAttachment, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | CSS_PROPERTY_VALUE_LIST_USES_COMMAS, Color, mBackAttachment, eCSSType_ValueList, kBackgroundAttachmentKTable)
 CSS_PROP_BACKGROUND(-moz-background-clip, _moz_background_clip, MozBackgroundClip, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | CSS_PROPERTY_VALUE_LIST_USES_COMMAS, Color, mBackClip, eCSSType_ValueList, kBackgroundClipKTable)
-CSS_PROP_BACKGROUND(background-color, background_color, BackgroundColor, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE, Color, mBackColor, eCSSType_ValuePair, nsnull)
+CSS_PROP_BACKGROUND(background-color, background_color, BackgroundColor, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE, Color, mBackColor, eCSSType_Value, nsnull)
 CSS_PROP_BACKGROUND(background-image, background_image, BackgroundImage, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | CSS_PROPERTY_VALUE_LIST_USES_COMMAS, Color, mBackImage, eCSSType_ValueList, nsnull)
 CSS_PROP_BACKGROUND(-moz-background-inline-policy, _moz_background_inline_policy, MozBackgroundInlinePolicy, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE, Color, mBackInlinePolicy, eCSSType_Value, kBackgroundInlinePolicyKTable)
 CSS_PROP_BACKGROUND(-moz-background-origin, _moz_background_origin, MozBackgroundOrigin, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | CSS_PROPERTY_VALUE_LIST_USES_COMMAS, Color, mBackOrigin, eCSSType_ValueList, kBackgroundOriginKTable)
 CSS_PROP_BACKGROUND(background-position, background_position, BackgroundPosition, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | CSS_PROPERTY_VALUE_LIST_USES_COMMAS, Color, mBackPosition, eCSSType_ValuePairList, kBackgroundPositionKTable)
 CSS_PROP_BACKGROUND(background-repeat, background_repeat, BackgroundRepeat, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | CSS_PROPERTY_VALUE_LIST_USES_COMMAS, Color, mBackRepeat, eCSSType_ValueList, kBackgroundRepeatKTable)
 CSS_PROP_DISPLAY(-moz-binding, binding, MozBinding, 0, Display, mBinding, eCSSType_Value, nsnull) // XXX bug 3935
 CSS_PROP_SHORTHAND(border, border, Border, 0)
 CSS_PROP_SHORTHAND(border-bottom, border_bottom, BorderBottom, 0)
--- a/layout/style/nsCSSStruct.h
+++ b/layout/style/nsCSSStruct.h
@@ -302,17 +302,17 @@ private:
   nsRuleDataFont(const nsRuleDataFont& aOther); // NOT IMPLEMENTED
 };
 
 struct nsCSSColor : public nsCSSStruct  {
   nsCSSColor(void);
   ~nsCSSColor(void);
 
   nsCSSValue      mColor;
-  nsCSSValuePair  mBackColor;
+  nsCSSValue      mBackColor;
   nsCSSValueList* mBackImage;
   nsCSSValueList* mBackRepeat;
   nsCSSValueList* mBackAttachment;
   nsCSSValuePairList* mBackPosition;
   nsCSSValueList* mBackClip;
   nsCSSValueList* mBackOrigin;
   nsCSSValue      mBackInlinePolicy;
 private:
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -1212,52 +1212,27 @@ nsComputedDOMStyle::GetBackgroundClip(ns
                            &nsStyleBackground::mClipCount,
                            nsCSSProps::kBackgroundClipKTable,
                            aValue);
 }
 
 nsresult
 nsComputedDOMStyle::GetBackgroundColor(nsIDOMCSSValue** aValue)
 {
-  const nsStyleBackground* bg = GetStyleBackground();
-  nsresult rv;
-
-  if (bg->mBackgroundColor == bg->mFallbackBackgroundColor) {
-    nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
-    NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
-
-    rv = SetToRGBAColor(val, bg->mBackgroundColor);
-    if (NS_FAILED(rv)) {
-      delete val;
-      return rv;
-    }
-    rv = CallQueryInterface(val, aValue);
-  } else {
-    nsDOMCSSValueList *valueList = GetROCSSValueList(PR_FALSE);
-    NS_ENSURE_TRUE(valueList, NS_ERROR_OUT_OF_MEMORY);
-
-    for (PRUint32 i = 0; i < 2; ++i) {
-      nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
-      if (!val || !valueList->AppendCSSValue(val)) {
-        delete val;
-        delete valueList;
-        return NS_ERROR_OUT_OF_MEMORY;
-      }
-
-      rv = SetToRGBAColor(val, (i == 0) ? bg->mBackgroundColor
-                                        : bg->mFallbackBackgroundColor);
-      if (NS_FAILED(rv)) {
-        delete valueList;
-        return rv;
-      }
-    }
-    rv = CallQueryInterface(valueList, aValue);
+  nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
+  NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
+
+  const nsStyleBackground* color = GetStyleBackground();
+  nsresult rv = SetToRGBAColor(val, color->mBackgroundColor);
+  if (NS_FAILED(rv)) {
+    delete val;
+    return rv;
   }
 
-  return rv;
+  return CallQueryInterface(val, aValue);
 }
 
 nsresult
 nsComputedDOMStyle::GetBackgroundImage(nsIDOMCSSValue** aValue)
 {
   const nsStyleBackground* bg = GetStyleBackground();
 
   nsDOMCSSValueList *valueList = GetROCSSValueList(PR_TRUE);
@@ -1266,17 +1241,17 @@ nsComputedDOMStyle::GetBackgroundImage(n
   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;
     }
 
-    imgIRequest *image = bg->mLayers[i].mImage.mRequest;
+    imgIRequest *image = bg->mLayers[i].mImage;
     if (!image) {
       val->SetIdent(eCSSKeyword_none);
     } else {
       nsCOMPtr<nsIURI> uri;
       image->GetURI(getter_AddRefs(uri));
       val->SetURI(uri);
     }
   }
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -3797,32 +3797,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.mRequest = value.GetImageValue();
-      aComputedValue.mSpecified = PR_TRUE;
+      aComputedValue = value.GetImageValue();
     }
     else {
       NS_ASSERTION(eCSSUnit_None == value.GetUnit(), "unexpected unit");
-      aComputedValue.mRequest = nsnull;
-      aComputedValue.mSpecified = PR_FALSE;
+      aComputedValue = nsnull;
     }
   }
 };
 
 struct BackgroundPositionAxis {
   nsCSSValue nsCSSValuePairList::*specified;
   nsStyleBackground::Position::PositionCoord
     nsStyleBackground::Position::*result;
@@ -3953,43 +3951,33 @@ nsRuleNode::ComputeBackgroundData(void* 
                                   const nsRuleDataStruct& aData, 
                                   nsStyleContext* aContext, 
                                   nsRuleNode* aHighestNode,
                                   const RuleDetail aRuleDetail,
                                   const PRBool aCanStoreInRuleTree)
 {
   COMPUTE_START_RESET(Background, (), bg, parentBG, Color, colorData)
 
-  // background-color: color, string, inherit [pair]
-  if (eCSSUnit_Initial == colorData.mBackColor.mXValue.GetUnit()) {
+  // background-color: color, string, inherit
+  if (eCSSUnit_Initial == colorData.mBackColor.GetUnit()) {
     bg->mBackgroundColor = NS_RGBA(0, 0, 0, 0);
-  } else if (!SetColor(colorData.mBackColor.mXValue,
-                       parentBG->mBackgroundColor, mPresContext,
-                       aContext, bg->mBackgroundColor, canStoreInRuleTree)) {
-    NS_ASSERTION(eCSSUnit_Null == colorData.mBackColor.mXValue.GetUnit(),
-                 "unexpected color unit");
-  }
-
-  if (eCSSUnit_Initial == colorData.mBackColor.mYValue.GetUnit()) {
-    bg->mFallbackBackgroundColor = NS_RGBA(0, 0, 0, 0);
-  } else if (!SetColor(colorData.mBackColor.mYValue,
-                       parentBG->mFallbackBackgroundColor, mPresContext,
-                       aContext, bg->mFallbackBackgroundColor,
+  } else if (!SetColor(colorData.mBackColor, parentBG->mBackgroundColor,
+                       mPresContext, aContext, bg->mBackgroundColor,
                        canStoreInRuleTree)) {
-    NS_ASSERTION(eCSSUnit_Null == colorData.mBackColor.mYValue.GetUnit(),
+    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]
   SetBackgroundList(aContext, colorData.mBackImage, bg->mLayers,
                     parentBG->mLayers, &nsStyleBackground::Layer::mImage,
-                    nsStyleBackground::Image(), parentBG->mImageCount,
+                    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);
 
@@ -5672,18 +5660,17 @@ nsRuleNode::HasAuthorSpecifiedRules(nsSt
 
   /* We're relying on the use of |aStyleContext| not mutating it! */
   nsRuleData ruleData(inheritBits,
                       aStyleContext->PresContext(), aStyleContext);
   ruleData.mColorData = &colorData;
   ruleData.mMarginData = &marginData;
 
   nsCSSValue* backgroundValues[] = {
-    &colorData.mBackColor.mXValue,
-    &colorData.mBackColor.mYValue,
+    &colorData.mBackColor,
     &firstBackgroundImage
   };
 
   nsCSSValue* borderValues[] = {
     &marginData.mBorderColor.mTop,
     &marginData.mBorderStyle.mTop,
     &marginData.mBorderWidth.mTop,
     &marginData.mBorderColor.mRight,
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -1213,34 +1213,32 @@ nsChangeHint nsStyleColor::MaxDifference
 nsStyleBackground::nsStyleBackground()
   : mAttachmentCount(1)
   , mClipCount(1)
   , mOriginCount(1)
   , mRepeatCount(1)
   , mPositionCount(1)
   , mImageCount(1)
   , mBackgroundColor(NS_RGBA(0, 0, 0, 0))
-  , mFallbackBackgroundColor(NS_RGBA(0, 0, 0, 0))
   , mBackgroundInlinePolicy(NS_STYLE_BG_INLINE_POLICY_CONTINUOUS)
 {
   Layer *onlyLayer = mLayers.AppendElement();
   NS_ASSERTION(onlyLayer, "auto array must have room for 1 element");
   onlyLayer->SetInitialValues();
 }
 
 nsStyleBackground::nsStyleBackground(const nsStyleBackground& aSource)
   : mAttachmentCount(aSource.mAttachmentCount)
   , mClipCount(aSource.mClipCount)
   , mOriginCount(aSource.mOriginCount)
   , mRepeatCount(aSource.mRepeatCount)
   , mPositionCount(aSource.mPositionCount)
   , mImageCount(aSource.mImageCount)
   , mLayers(aSource.mLayers) // deep copy
   , mBackgroundColor(aSource.mBackgroundColor)
-  , mFallbackBackgroundColor(aSource.mFallbackBackgroundColor)
   , mBackgroundInlinePolicy(aSource.mBackgroundInlinePolicy)
 {
   // If the deep copy of mLayers failed, truncate the counts.
   PRUint32 count = mLayers.Length();
   if (count != aSource.mLayers.Length()) {
     NS_WARNING("truncating counts due to out-of-memory");
     mAttachmentCount = PR_MAX(mAttachmentCount, count);
     mClipCount = PR_MAX(mClipCount, count);
@@ -1253,17 +1251,16 @@ nsStyleBackground::nsStyleBackground(con
 
 nsStyleBackground::~nsStyleBackground()
 {
 }
 
 nsChangeHint nsStyleBackground::CalcDifference(const nsStyleBackground& aOther) const
 {
   if (mBackgroundColor != aOther.mBackgroundColor ||
-      mFallbackBackgroundColor != aOther.mFallbackBackgroundColor ||
       mBackgroundInlinePolicy != aOther.mBackgroundInlinePolicy ||
       mImageCount != aOther.mImageCount)
     return NS_STYLE_HINT_VISUAL;
 
   // We checked the image count above.
   NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, this) {
     if (mLayers[i] != aOther.mLayers[i])
       return NS_STYLE_HINT_VISUAL;
@@ -1279,88 +1276,65 @@ 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.mRequest) {
+    if (layer.mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED && layer.mImage) {
       return PR_TRUE;
     }
   }
   return PR_FALSE;
 }
 
 PRBool nsStyleBackground::IsTransparent() const
 {
-  return !BottomLayer().mImage.mRequest && mImageCount == 1 &&
+  return !BottomLayer().mImage && mImageCount == 1 &&
          NS_GET_A(mBackgroundColor) == 0;
 }
 
 void
 nsStyleBackground::Position::SetInitialValues()
 {
   mXPosition.mFloat = 0.0f;
   mYPosition.mFloat = 0.0f;
   mXIsPercent = PR_TRUE;
   mYIsPercent = PR_TRUE;
 }
 
-// Initialize to initial values
-nsStyleBackground::Image::Image()
-{
-  SetInitialValues();
-}
-
-nsStyleBackground::Image::~Image()
-{
-}
-
-void nsStyleBackground::Image::SetInitialValues()
-{
-  mRequest = nsnull;
-  mSpecified = PR_FALSE;
-}
-
-PRBool nsStyleBackground::Image::operator==(const Image& aOther) const
-{
-  return mSpecified == aOther.mSpecified &&
-         EqualImages(mRequest, aOther.mRequest);
-}
-
 nsStyleBackground::Layer::Layer()
 {
 }
 
 nsStyleBackground::Layer::~Layer()
 {
 }
 
 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();
-  mImage.SetInitialValues();
+  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 &&
-         mImage == aOther.mImage;
+         EqualImages(mImage, aOther.mImage);
 }
 
 // --------------------
 // nsStyleDisplay
 //
 
 nsStyleDisplay::nsStyleDisplay()
 {
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -189,53 +189,25 @@ struct nsStyleBackground {
              (mYIsPercent ? (mYPosition.mFloat == aOther.mYPosition.mFloat)
                           : (mYPosition.mCoord == aOther.mYPosition.mCoord));
     }
     PRBool operator!=(const Position& aOther) const {
       return !(*this == aOther);
     }
   };
 
-  /**
-   * We represent images as as struct because we need to distinguish the
-   * case where the imgIRequest is null because the winning
-   * background-image declaration specified no image from the case where
-   * the imgIRequest is null because the image that was specified was
-   * blocked or missing (e.g., missing file).
-   */
-  struct Image;
-  friend struct Image;
-  struct Image {
-    nsCOMPtr<imgIRequest> mRequest;
-    PRBool mSpecified; // if false, mRequest is guaranteed to be null
-
-    // These are not inline so that we can avoid #include "imgIRequest.h"
-
-    // Initialize to initial values
-    Image();
-    ~Image();
-    void SetInitialValues();
-
-    // An equality operator that compares the images using URL-equality
-    // rather than pointer-equality.
-    PRBool operator==(const Image& aOther) const;
-    PRBool operator!=(const Image& aOther) const {
-      return !(*this == aOther);
-    }
-  };
-
   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]
 
     // Initializes only mImage
     Layer();
     ~Layer();
 
     void SetInitialValues();
 
     // An equality operator that compares the images using URL-equality
@@ -267,17 +239,16 @@ struct nsStyleBackground {
   nsAutoTArray<Layer, 1> mLayers;
 
   const Layer& BottomLayer() const { return mLayers[mImageCount - 1]; }
 
   #define NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(var_, stylebg_) \
     for (PRUint32 var_ = (stylebg_)->mImageCount; var_-- != 0; )
 
   nscolor mBackgroundColor;       // [reset]
-  nscolor mFallbackBackgroundColor; // [reset]
 
   // FIXME: This (now background-break in css3-background) should
   // probably move into a different struct so that everything in
   // nsStyleBackground is set by the background shorthand.
   PRUint8 mBackgroundInlinePolicy; // [reset] See nsStyleConsts.h
 
   // True if this background is completely transparent.
   PRBool IsTransparent() const;
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -616,17 +616,17 @@ var gCSSProperties = {
 		subproperties: [ "background-attachment", "background-color", "background-image", "background-position", "background-repeat", "-moz-background-clip", "-moz-background-origin" ],
 		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%",
 		        /* multiple backgrounds */
 		        "url(404.png), url(404.png)",
 		        "url(404.png), url(404.png) transparent",
-		        "url(404.png), url(404.png) transparent red",
+		        "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",
 		        /* 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.
@@ -661,18 +661,18 @@ var gCSSProperties = {
 		initial_values: [ "scroll" ],
 		other_values: [ "fixed", "scroll,scroll", "fixed, scroll", "scroll, fixed, scroll", "fixed, fixed" ],
 		invalid_values: []
 	},
 	"background-color": {
 		domProp: "backgroundColor",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
-		initial_values: [ "transparent", "transparent transparent", "rgba(255, 127, 15, 0)", "hsla(240, 97%, 50%, 0.0)", "rgba(0, 0, 0, 0)", "rgba(255,255,255,-3.7)" ],
-		other_values: [ "green", "rgb(255, 0, 128)", "#fc2", "#96ed2a", "black", "rgba(255,255,0,3)", "transparent green", "green transparent", "blue fuchsia", "rgb(3,4,5) hsl(240, 50%, 50%)" ],
+		initial_values: [ "transparent", "rgba(255, 127, 15, 0)", "hsla(240, 97%, 50%, 0.0)", "rgba(0, 0, 0, 0)", "rgba(255,255,255,-3.7)" ],
+		other_values: [ "green", "rgb(255, 0, 128)", "#fc2", "#96ed2a", "black", "rgba(255,255,0,3)" ],
 		invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000", "rgb(255.0,0.387,3489)" ]
 	},
 	"background-image": {
 		domProp: "backgroundImage",
 		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==")',
--- 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.mRequest)
+    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
@@ -4112,17 +4112,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.mRequest ||
+  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 =
@@ -4152,17 +4152,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.mRequest ||
+  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) {
       widget->Scroll(PresContext()->AppUnitsToDevPixels(-delta), 0, nsnull);