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
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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)");