Add -moz-background-clip: content. (Bug 549809) r=roc
authorL. David Baron <dbaron@dbaron.org>
Tue, 08 Jun 2010 18:44:32 -0700
changeset 43355 665863f2ac31
parent 43354 f9e8bdcb48cd
child 43356 0f920bd875d7
push id13666
push userdbaron@mozilla.com
push date2010-06-09 01:45 +0000
treeherdermozilla-central@979aceadf808 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs549809
milestone1.9.3a5pre
Add -moz-background-clip: content. (Bug 549809) r=roc
layout/base/nsCSSRendering.cpp
layout/base/nsStyleConsts.h
layout/reftests/backgrounds/background-clip-1-ref.html
layout/reftests/backgrounds/background-clip-1.html
layout/reftests/backgrounds/reftest.list
layout/style/nsCSSDeclaration.cpp
layout/style/nsCSSParser.cpp
layout/style/nsCSSPropList.h
layout/style/nsCSSProps.cpp
layout/style/nsCSSProps.h
layout/style/nsComputedDOMStyle.cpp
layout/style/test/property_database.js
layout/style/test/test_shorthand_property_getters.html
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -1549,19 +1549,22 @@ SetupBackgroundClip(gfxContext *aCtx, PR
                     /* OUT: */
                     nsRect* aBGClipArea, nsRect* aDirtyRect,
                     gfxRect* aDirtyRectGfx)
 {
   *aBGClipArea = aBorderArea;
   PRBool radiiAreOuter = PR_TRUE;
   gfxCornerSizes clippedRadii = aBGRadii;
   if (aBackgroundClip != NS_STYLE_BG_CLIP_BORDER) {
-    NS_ASSERTION(aBackgroundClip == NS_STYLE_BG_CLIP_PADDING,
-                 "unexpected background-clip");
     nsMargin border = aForFrame->GetUsedBorder();
+    if (aBackgroundClip != NS_STYLE_BG_CLIP_PADDING) {
+      NS_ASSERTION(aBackgroundClip == NS_STYLE_BG_CLIP_CONTENT,
+                   "unexpected background-clip");
+      border += aForFrame->GetUsedPadding();
+    }
     aForFrame->ApplySkipSides(border);
     aBGClipArea->Deflate(border);
 
     if (aHaveRoundedCorners) {
       gfxFloat borderSizes[4] = {
         gfxFloat(border.top / aAppUnitsPerPixel),
         gfxFloat(border.right / aAppUnitsPerPixel),
         gfxFloat(border.bottom / aAppUnitsPerPixel),
@@ -2264,18 +2267,19 @@ nsCSSRendering::PaintBackgroundWithSC(ns
       ctx->Fill();
     }
   }
 
   if (drawBackgroundImage) {
     NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, bg) {
       const nsStyleBackground::Layer &layer = bg->mLayers[i];
       if (!aBGClipRect) {
-        PRUint8 newBackgroundClip =
-          isSolidBorder ? NS_STYLE_BG_CLIP_PADDING : layer.mClip;
+        PRUint8 newBackgroundClip = layer.mClip;
+        if (isSolidBorder && newBackgroundClip == NS_STYLE_BG_CLIP_BORDER)
+          newBackgroundClip = NS_STYLE_BG_CLIP_PADDING;
         if (currentBackgroundClip != newBackgroundClip) {
           currentBackgroundClip = newBackgroundClip;
           SetupBackgroundClip(ctx, currentBackgroundClip, aForFrame,
                               aBorderArea, aDirtyRect, haveRoundedCorners,
                               bgRadii, appUnitsPerPixel, &autoSR,
                               &bgClipArea, &dirtyRect, &dirtyRectGfx);
         }
       }
@@ -2421,25 +2425,23 @@ PaintBackgroundLayer(nsPresContext* aPre
   } else {
     bgPositioningArea = nsRect(nsPoint(0,0), aBorderArea.Size());
   }
 
   // Background images are tiled over the 'background-clip' area
   // but the origin of the tiling is based on the 'background-origin' area
   if (aLayer.mOrigin != NS_STYLE_BG_ORIGIN_BORDER && geometryFrame) {
     nsMargin border = geometryFrame->GetUsedBorder();
-    geometryFrame->ApplySkipSides(border);
-    bgPositioningArea.Deflate(border);
     if (aLayer.mOrigin != NS_STYLE_BG_ORIGIN_PADDING) {
-      nsMargin padding = geometryFrame->GetUsedPadding();
-      geometryFrame->ApplySkipSides(padding);
-      bgPositioningArea.Deflate(padding);
+      border += geometryFrame->GetUsedPadding();
       NS_ASSERTION(aLayer.mOrigin == NS_STYLE_BG_ORIGIN_CONTENT,
                    "unknown background-origin value");
     }
+    geometryFrame->ApplySkipSides(border);
+    bgPositioningArea.Deflate(border);
   }
 
   // For background-attachment:fixed backgrounds, we'll limit the area
   // where the background can be drawn to the viewport.
   nsRect bgClipRect = aBGClipRect;
 
   // Compute the anchor point.
   //
--- a/layout/base/nsStyleConsts.h
+++ b/layout/base/nsStyleConsts.h
@@ -243,18 +243,17 @@ static inline mozilla::css::Side operato
 // See nsStyleBackground
 #define NS_STYLE_BG_ATTACHMENT_SCROLL     0
 #define NS_STYLE_BG_ATTACHMENT_FIXED      1
 
 // See nsStyleBackground
 // Code depends on these constants having the same values as BG_ORIGIN_*
 #define NS_STYLE_BG_CLIP_BORDER           0
 #define NS_STYLE_BG_CLIP_PADDING          1
-// When we add NS_STYLE_BG_CLIP_CONTENT, we should add the PR_STATIC_ASSERTs
-// to the places that assert equality for BORDER and PADDING.
+#define NS_STYLE_BG_CLIP_CONTENT          2
 
 // See nsStyleBackground
 #define NS_STYLE_BG_INLINE_POLICY_EACH_BOX      0
 #define NS_STYLE_BG_INLINE_POLICY_CONTINUOUS    1
 #define NS_STYLE_BG_INLINE_POLICY_BOUNDING_BOX  2
 
 // See nsStyleBackground
 // Code depends on these constants having the same values as BG_CLIP_*
new file mode 100644
--- /dev/null
+++ b/layout/reftests/backgrounds/background-clip-1-ref.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML>
+<title>background-clip</title>
+<style type="text/css">
+
+div {
+  position: absolute;
+}
+
+div.color {
+  top: 10px;
+  background-color: blue;
+}
+
+div.image {
+  top: 110px;
+  background-color: blue;
+}
+
+div.border {
+  left: 18px;
+  margin-top: 1px;
+  width: 76px;
+  height: 42px;
+}
+
+div.padding {
+  left: 130px;
+  margin-top: 4px;
+  width: 55px;
+  height: 33px;
+}
+
+div.content {
+  left: 237px;
+  margin-top: 9px;
+  width: 37px;
+  height: 19px;
+}
+
+</style>
+<div class="color border"></div>
+<div class="color padding"></div>
+<div class="color content"></div>
+<div class="image border"></div>
+<div class="image padding"></div>
+<div class="image content"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/backgrounds/background-clip-1.html
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML>
+<title>background-clip</title>
+<style type="text/css">
+
+div {
+  position: absolute;
+  margin: 1px 2px 4px 8px;
+  border: transparent solid;
+  border-width: 3px 9px 6px 12px;
+  padding: 5px 11px 9px 7px;
+  width: 37px;
+  height: 19px;
+  /*
+   * content box: 37 x 19
+   * padding box: 55 x 33
+   * border  box: 76 x 42
+   * margin  box: 86 x 47
+   */
+}
+
+div.color {
+  top: 10px;
+  background-color: blue;
+}
+
+div.image {
+  top: 110px;
+  background-image: url(blue-32x32.png);
+}
+
+div.border {
+  -moz-background-clip: border;
+  left: 10px;
+}
+
+div.padding {
+  -moz-background-clip: padding;
+  left: 110px;
+}
+
+div.content {
+  -moz-background-clip: content;
+  left: 210px;
+}
+
+</style>
+<div class="color border"></div>
+<div class="color padding"></div>
+<div class="color content"></div>
+<div class="image border"></div>
+<div class="image padding"></div>
+<div class="image content"></div>
--- a/layout/reftests/backgrounds/reftest.list
+++ b/layout/reftests/backgrounds/reftest.list
@@ -21,16 +21,18 @@
 == continuous-inline-2b.html continuous-inline-2-ref.html
 == continuous-inline-3.html continuous-inline-3-ref.html
 == continuous-inline-4a.html continuous-inline-4-ref.html
 == continuous-inline-4b.html continuous-inline-4-ref.html
 == continuous-inline-5a.html continuous-inline-5-ref.html
 == continuous-inline-5b.html continuous-inline-5-ref.html
 == background-redraw-237766.html background-redraw-237766-ref.html
 
+== background-clip-1.html background-clip-1-ref.html
+
 == background-size-auto-auto.html background-size-auto-ref.html
 == background-size-auto.html background-size-auto-ref.html
 == background-size-contain.html background-size-contain-ref.html
 == background-size-cover.html background-size-cover-ref.html
 == background-size-auto-length.html background-size-auto-length-ref.html
 == background-size-length-auto.html background-size-auto-length-ref.html
 == background-size-length.html background-size-auto-length-ref.html
 == background-size-auto-percent.html background-size-auto-length-ref.html
--- a/layout/style/nsCSSDeclaration.cpp
+++ b/layout/style/nsCSSDeclaration.cpp
@@ -1009,18 +1009,18 @@ nsCSSDeclaration::GetValue(nsCSSProperty
     // 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.
           PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_BORDER ==
                            NS_STYLE_BG_ORIGIN_BORDER);
           PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_PADDING ==
                            NS_STYLE_BG_ORIGIN_PADDING);
-          // PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_CONTENT == /* does not exist */
-          //                  NS_STYLE_BG_ORIGIN_CONTENT);
+          PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_CONTENT ==
+                           NS_STYLE_BG_ORIGIN_CONTENT);
           if (clip->mValue != origin->mValue) {
             aValue.Truncate();
             return NS_OK;
           }
 
           aValue.Append(PRUnichar(' '));
           AppendCSSValueToString(eCSSProperty__moz_background_clip,
                                  clip->mValue, aValue);
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -5751,17 +5751,17 @@ CSSParserImpl::ParseSingleValueProperty(
     return ParseAzimuth(aValue);
   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);
+                        nsCSSProps::kBackgroundOriginKTable);
   case eCSSProperty_background_color:
     return ParseVariant(aValue, VARIANT_HC, nsnull);
   case eCSSProperty_background_image:
     // Used only internally.
     return ParseVariant(aValue,
                         VARIANT_HUO | VARIANT_GRADIENT | VARIANT_IMAGE_RECT,
                         nsnull);
   case eCSSProperty__moz_background_inline_policy:
@@ -6507,39 +6507,31 @@ CSSParserImpl::ParseBackgroundItem(CSSPa
           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,
-                   nsCSSProps::kBackgroundClipKTable, dummy)) {
-        // For now, we use the background-clip table rather than have a special
-        // background-origin table, because we don't support 'content-box' on
-        // background-origin.
-        NS_ASSERTION(
-          nsCSSProps::kBackgroundClipKTable[0] == eCSSKeyword_border &&
-          nsCSSProps::kBackgroundClipKTable[2] == eCSSKeyword_padding &&
-          nsCSSProps::kBackgroundClipKTable[4] == eCSSKeyword_UNKNOWN,
-          "need to rewrite this code");
+                   nsCSSProps::kBackgroundOriginKTable, dummy)) {
         if (haveOrigin)
           return PR_FALSE;
         haveOrigin = PR_TRUE;
         if (!ParseSingleValueProperty(aItem.mOrigin,
                                       eCSSProperty__moz_background_origin)) {
           NS_NOTREACHED("should be able to parse");
           return PR_FALSE;
         }
         PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_BORDER ==
                          NS_STYLE_BG_ORIGIN_BORDER);
         PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_PADDING ==
                          NS_STYLE_BG_ORIGIN_PADDING);
-        // PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_CONTENT == /* does not exist */
-        //                  NS_STYLE_BG_ORIGIN_CONTENT);
+        PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_CONTENT ==
+                         NS_STYLE_BG_ORIGIN_CONTENT);
         // 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;
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -453,17 +453,17 @@ 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,
+    kBackgroundOriginKTable,
     CSS_PROP_NO_OFFSET,
     eStyleAnimType_None)
 CSS_PROP_BACKGROUND(
     background-color,
     background_color,
     BackgroundColor,
     CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE |
         CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED,
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -515,29 +515,26 @@ const PRInt32 nsCSSProps::kAzimuthKTable
 };
 
 const PRInt32 nsCSSProps::kBackgroundAttachmentKTable[] = {
   eCSSKeyword_fixed, NS_STYLE_BG_ATTACHMENT_FIXED,
   eCSSKeyword_scroll, NS_STYLE_BG_ATTACHMENT_SCROLL,
   eCSSKeyword_UNKNOWN,-1
 };
 
-const PRInt32 nsCSSProps::kBackgroundClipKTable[] = {
-  eCSSKeyword_border,     NS_STYLE_BG_CLIP_BORDER,
-  eCSSKeyword_padding,    NS_STYLE_BG_CLIP_PADDING,
-  eCSSKeyword_UNKNOWN,-1
-};
-
 const PRInt32 nsCSSProps::kBackgroundInlinePolicyKTable[] = {
   eCSSKeyword_each_box,     NS_STYLE_BG_INLINE_POLICY_EACH_BOX,
   eCSSKeyword_continuous,   NS_STYLE_BG_INLINE_POLICY_CONTINUOUS,
   eCSSKeyword_bounding_box, NS_STYLE_BG_INLINE_POLICY_BOUNDING_BOX,
   eCSSKeyword_UNKNOWN,-1
 };
 
+PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_BORDER == NS_STYLE_BG_ORIGIN_BORDER);
+PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_PADDING == NS_STYLE_BG_ORIGIN_PADDING);
+PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_CONTENT == NS_STYLE_BG_ORIGIN_CONTENT);
 const PRInt32 nsCSSProps::kBackgroundOriginKTable[] = {
   eCSSKeyword_border,     NS_STYLE_BG_ORIGIN_BORDER,
   eCSSKeyword_padding,    NS_STYLE_BG_ORIGIN_PADDING,
   eCSSKeyword_content,    NS_STYLE_BG_ORIGIN_CONTENT,
   eCSSKeyword_UNKNOWN,-1
 };
 
 // Note: Don't change this table unless you update
--- a/layout/style/nsCSSProps.h
+++ b/layout/style/nsCSSProps.h
@@ -240,17 +240,16 @@ public:
 #define CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(iter_, prop_)                    \
   for (const nsCSSProperty* iter_ = nsCSSProps::SubpropertyEntryFor(prop_);   \
        *iter_ != eCSSProperty_UNKNOWN; ++iter_)
 
   // Keyword/Enum value tables
   static const PRInt32 kAppearanceKTable[];
   static const PRInt32 kAzimuthKTable[];
   static const PRInt32 kBackgroundAttachmentKTable[];
-  static const PRInt32 kBackgroundClipKTable[];
   static const PRInt32 kBackgroundInlinePolicyKTable[];
   static const PRInt32 kBackgroundOriginKTable[];
   static const PRInt32 kBackgroundPositionKTable[];
   static const PRInt32 kBackgroundRepeatKTable[];
   static const PRInt32 kBackgroundSizeKTable[];
   static const PRInt32 kBorderCollapseKTable[];
   static const PRInt32 kBorderColorKTable[];
   static const PRInt32 kBorderImageKTable[];
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -1351,17 +1351,17 @@ nsComputedDOMStyle::GetBackgroundAttachm
                            aValue);
 }
 
 nsresult
 nsComputedDOMStyle::GetBackgroundClip(nsIDOMCSSValue** aValue)
 {
   return GetBackgroundList(&nsStyleBackground::Layer::mClip,
                            &nsStyleBackground::mClipCount,
-                           nsCSSProps::kBackgroundClipKTable,
+                           nsCSSProps::kBackgroundOriginKTable,
                            aValue);
 }
 
 nsresult
 nsComputedDOMStyle::GetBackgroundColor(nsIDOMCSSValue** aValue)
 {
   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -74,20 +74,19 @@ var gCSSProperties = {
 	"-moz-background-clip": {
 		/*
 		 * When we rename this to 'background-clip', we also
 		 * need to rename the values to match the spec.
 		 */
 		domProp: "MozBackgroundClip",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
-		/* XXX Need to add support for "content" -- important for symmetry when handling background shorthand */
 		initial_values: [ "border" ],
-		other_values: [ "padding", "border, padding", "padding, padding, padding", "border, border" ],
-		invalid_values: [ "content", "margin", "border border" ]
+		other_values: [ "content", "padding", "border, padding", "padding, padding, padding", "border, border" ],
+		invalid_values: [ "margin", "border border" ]
 	},
 	"-moz-background-inline-policy": {
 		domProp: "MozBackgroundInlinePolicy",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		initial_values: [ "continuous" ],
 		other_values: ["bounding-box", "each-box" ],
 		invalid_values: []
--- a/layout/style/test/test_shorthand_property_getters.html
+++ b/layout/style/test/test_shorthand_property_getters.html
@@ -114,21 +114,20 @@ is(e.style.font, "", "should not have fo
 e.setAttribute("style", "background: red");
 isnot(e.style.background, "", "should have background shorthand");
 e.setAttribute("style", "background: red; -moz-background-origin: border");
 is(e.style.background, "", "should not have background shorthand (origin:border)");
 e.setAttribute("style", "background: red; -moz-background-clip: padding");
 is(e.style.background, "", "should not have background shorthand (clip:padding)");
 e.setAttribute("style", "background: red; -moz-background-origin: content");
 is(e.style.background, "", "should not have background shorthand (origin:content)");
-// -moz-background-clip:content not yet supported
-//e.setAttribute("style", "background: red; -moz-background-clip: content");
-//is(e.style.background, "", "should not have background shorthand (clip:content)");
-//e.setAttribute("style", "background: red; -moz-background-clip: content; -moz-background-origin: content;");
-//isnot(e.style.background, "", "should have background shorthand (clip:content;origin:content)");
+e.setAttribute("style", "background: red; -moz-background-clip: content");
+is(e.style.background, "", "should not have background shorthand (clip:content)");
+e.setAttribute("style", "background: red; -moz-background-clip: content; -moz-background-origin: content;");
+isnot(e.style.background, "", "should have background shorthand (clip:content;origin:content)");
 e.setAttribute("style", "background: red; -moz-background-size: 100% 100%");
 is(e.style.background, "", "should not have background shorthand (size:100% 100%)");
 e.setAttribute("style", "background: red; -moz-background-size: 100% auto");
 is(e.style.background, "", "should not have background shorthand (size:100% auto)");
 e.setAttribute("style", "background: red; -moz-background-size: auto 100%");
 is(e.style.background, "", "should not have background shorthand (size:auto 100%)");
 e.setAttribute("style", "background: red; -moz-background-inline-policy: each-box");
 isnot(e.style.background, "", "should have background shorthand (-moz-background-inline-policy not relevant)");