Support for background-clip and background-origin in the background shorthand. (Bug 549809) r=roc
authorL. David Baron <dbaron@dbaron.org>
Tue, 08 Jun 2010 18:44:33 -0700
changeset 43358 63ccfca7cdb2
parent 43357 b5562d977e3a
child 43359 c0bd45ab931f
push id13666
push userdbaron@mozilla.com
push date2010-06-09 01:45 +0000
Treeherderresults
reviewersroc
bugs549809
milestone1.9.3a5pre
Support for background-clip and background-origin in the background shorthand. (Bug 549809) r=roc
layout/style/nsCSSDeclaration.cpp
layout/style/nsCSSParser.cpp
layout/style/test/property_database.js
layout/style/test/test_shorthand_property_getters.html
--- a/layout/style/nsCSSDeclaration.cpp
+++ b/layout/style/nsCSSDeclaration.cpp
@@ -1000,39 +1000,34 @@ nsCSSDeclaration::GetValue(nsCSSProperty
         AppendCSSValueToString(eCSSProperty_background_position,
                                position->mYValue, aValue);
         NS_ASSERTION(clip->mValue.GetUnit() == eCSSUnit_Enumerated &&
                      origin->mValue.GetUnit() == eCSSUnit_Enumerated,
                      "should not be inherit/initial within list and "
                      "should have returned early for real inherit/initial");
         if (clip->mValue.GetIntValue() != NS_STYLE_BG_CLIP_BORDER ||
             origin->mValue.GetIntValue() != NS_STYLE_BG_ORIGIN_PADDING) {
-#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.
           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);
+          // The shorthand only has a single clip/origin value which
+          // sets both properties.  So if they're different (and
+          // non-default), we can't represent the state using the
+          // shorthand.
           if (clip->mValue != origin->mValue) {
             aValue.Truncate();
             return NS_OK;
           }
 
           aValue.Append(PRUnichar(' '));
           AppendCSSValueToString(eCSSProperty_background_clip,
                                  clip->mValue, aValue);
-#else
-          aValue.Truncate();
-          return NS_OK;
-#endif
         }
 
         image = image->mNext;
         repeat = repeat->mNext;
         attachment = attachment->mNext;
         position = position->mNext;
         clip = clip->mNext;
         origin = origin->mNext;
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -6426,16 +6426,17 @@ CSSParserImpl::ParseBackgroundItem(CSSPa
   aItem.mSize.mYValue.SetAutoValue();
   aItem.mLastItem = PR_FALSE;
 
   PRBool haveColor = PR_FALSE,
          haveImage = PR_FALSE,
          haveRepeat = PR_FALSE,
          haveAttach = PR_FALSE,
          havePosition = PR_FALSE,
+         haveOrigin = PR_FALSE,
          haveSomething = PR_FALSE;
   while (GetToken(PR_TRUE)) {
     nsCSSTokenType tt = mToken.mType;
     UngetToken(); // ...but we'll still cheat and use mToken
     if (tt == eCSSToken_Symbol) {
       // ExpectEndProperty only looks for symbols, and nothing else will
       // show up as one.
       break;
@@ -6443,17 +6444,17 @@ CSSParserImpl::ParseBackgroundItem(CSSPa
 
     if (tt == eCSSToken_Ident) {
       nsCSSKeyword keyword = nsCSSKeywords::LookupKeyword(mToken.mIdent);
       PRInt32 dummy;
       if (keyword == eCSSKeyword_inherit ||
           keyword == eCSSKeyword__moz_initial) {
         if (haveSomething || !aFirstItem)
           return PR_FALSE;
-        haveColor = haveImage = haveRepeat = haveAttach = havePosition =
+        haveColor = haveImage = haveRepeat = haveAttach = havePosition = haveOrigin =
           PR_TRUE;
         GetToken(PR_TRUE); // undo the UngetToken above
         nsCSSValue val;
         if (keyword == eCSSKeyword_inherit) {
           val.SetInheritValue();
         } else {
           val.SetInitialValue();
         }
@@ -6501,21 +6502,16 @@ CSSParserImpl::ParseBackgroundItem(CSSPa
       } else if (nsCSSProps::FindKeyword(keyword,
                    nsCSSProps::kBackgroundPositionKTable, dummy)) {
         if (havePosition)
           return PR_FALSE;
         havePosition = PR_TRUE;
         if (!ParseBoxPositionValues(aItem.mPosition, PR_FALSE)) {
           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::kBackgroundOriginKTable, dummy)) {
         if (haveOrigin)
           return PR_FALSE;
         haveOrigin = PR_TRUE;
         if (!ParseSingleValueProperty(aItem.mOrigin,
                                       eCSSProperty_background_origin)) {
           NS_NOTREACHED("should be able to parse");
@@ -6523,17 +6519,16 @@ CSSParserImpl::ParseBackgroundItem(CSSPa
         }
         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);
         aItem.mClip = aItem.mOrigin;
-#endif
       } else {
         if (haveColor)
           return PR_FALSE;
         haveColor = PR_TRUE;
         if (!ParseSingleValueProperty(mTempData.mColor.mBackColor,
                                       eCSSProperty_background_color)) {
           return PR_FALSE;
         }
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -818,25 +818,19 @@ var gCSSProperties = {
 				"url(404.png), url(404.png)",
 				"url(404.png), url(404.png) transparent",
 				"url(404.png), url(404.png) red",
 				"repeat-x, fixed, none",
 				"0% top url(404.png), url(404.png) 0% top",
 				"fixed repeat-y top left url(404.png), repeat-x green",
 				"url(404.png), -moz-linear-gradient(20px 20px -45deg, blue, green) black",
 				/* test cases with clip+origin in the shorthand */
-	// This is commented out for now until we change
-	// -moz-background-clip to background-clip, -moz-background-origin
-	// to background-origin, change their value names to *-box, and add
-	// support for content-box on background-clip.
-	/*
 				"url(404.png) green padding-box",
 				"url(404.png) border-box transparent",
 				"content-box url(404.png) blue",
-	*/
 		],
 		invalid_values: [
 			/* mixes with keywords have to be in correct order */
 			"50% left", "top 50%",
 			/* bug 258080: don't accept background-position separated */
 			"left url(404.png) top", "top url(404.png) left",
 			/* not allowed to have color in non-bottom layer */
 			"url(404.png) transparent, url(404.png)",
--- a/layout/style/test/test_shorthand_property_getters.html
+++ b/layout/style/test/test_shorthand_property_getters.html
@@ -109,19 +109,19 @@ e.setAttribute("style", "font: medium se
 is(e.style.font, "", "should not have font shorthand");
 
 // For background, we can only express the value as a shorthand if
 // origin and clip are both their default, or if they're both the same.
 // ... or at least we will once we support them in the shorthand.
 e.setAttribute("style", "background: red");
 isnot(e.style.background, "", "should have background shorthand");
 e.setAttribute("style", "background: red; background-origin: border-box");
-is(e.style.background, "", "should not have background shorthand (origin:border-box)");
+isnot(e.style.background, "", "should have background shorthand (origin:border-box)");
 e.setAttribute("style", "background: red; background-clip: padding-box");
-is(e.style.background, "", "should not have background shorthand (clip:padding-box)");
+isnot(e.style.background, "", "should have background shorthand (clip:padding-box)");
 e.setAttribute("style", "background: red; background-origin: content-box");
 is(e.style.background, "", "should not have background shorthand (origin:content-box)");
 e.setAttribute("style", "background: red; background-clip: content-box");
 is(e.style.background, "", "should not have background shorthand (clip:content-box)");
 e.setAttribute("style", "background: red; background-clip: content-box; background-origin: content-box;");
 isnot(e.style.background, "", "should have background shorthand (clip:content-box;origin:content-box)");
 e.setAttribute("style", "background: red; -moz-background-size: 100% 100%");
 is(e.style.background, "", "should not have background shorthand (size:100% 100%)");
@@ -129,34 +129,33 @@ e.setAttribute("style", "background: red
 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)");
 
 // Check that we only serialize background when the lists (of layers) for
 // the subproperties are the same length.
-// XXX Should change background-clip to border-box,padding-box,border-box and
-// background-origin to border-box,padding-box,padding-box and background-size to
-// cover,auto,contain once serialization does clip/origin/size.
-e.setAttribute("style", "background-clip: border-box, border-box, border-box; background-origin: padding-box, padding-box, padding-box; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
+// XXX Should change  background-size to cover,auto,contain once
+// background-size is part of shorthand.
+e.setAttribute("style", "background-clip: border-box, padding-box, border-box; background-origin: border-box, padding-box, padding-box; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
 isnot(e.style.background, "", "should have background shorthand (all lists length 3)");
-e.setAttribute("style", "background-clip: border-box, border-box, border-box, border-box; background-origin: padding-box, padding-box, padding-box; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
+e.setAttribute("style", "background-clip: border-box, padding-box, border-box, border-box; background-origin: border-box, padding-box, padding-box; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
 is(e.style.background, "", "should not have background shorthand (background-clip too long)");
-e.setAttribute("style", "background-clip: border-box, border-box, border-box; background-origin: padding-box, padding-box; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
+e.setAttribute("style", "background-clip: border-box, padding-box, border-box; background-origin: padding-box, padding-box; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
 is(e.style.background, "", "should not have background shorthand (background-origin too short)");
-e.setAttribute("style", "background-clip: border-box, border-box, border-box; background-origin: padding-box, padding-box, padding-box; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png), none; background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
+e.setAttribute("style", "background-clip: border-box, padding-box, border-box; background-origin: border-box, padding-box, padding-box; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png), none; background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
 is(e.style.background, "", "should not have background shorthand (background-image too long)");
-e.setAttribute("style", "background-clip: border-box, border-box, border-box; background-origin: padding-box, padding-box, padding-box; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
+e.setAttribute("style", "background-clip: border-box, padding-box, border-box; background-origin: border-box, padding-box, padding-box; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
 is(e.style.background, "", "should not have background shorthand (background-attachment too short)");
-e.setAttribute("style", "background-clip: border-box, border-box, border-box; background-origin: padding-box, padding-box, padding-box; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px, bottom; background-repeat: repeat-x, repeat, no-repeat");
+e.setAttribute("style", "background-clip: border-box, padding-box, border-box; background-origin: border-box, padding-box, padding-box; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px, bottom; background-repeat: repeat-x, repeat, no-repeat");
 is(e.style.background, "", "should not have background shorthand (background-position too long)");
-e.setAttribute("style", "background-clip: border-box, border-box, border-box; background-origin: padding-box, padding-box, padding-box; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat");
+e.setAttribute("style", "background-clip: border-box, padding-box, border-box; background-origin: border-box, padding-box, padding-box; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat");
 is(e.style.background, "", "should not have background shorthand (background-repeat too short)");
-e.setAttribute("style", "background-clip: border-box, border-box, border-box; background-origin: padding-box, padding-box, padding-box; -moz-background-size: auto, auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
+e.setAttribute("style", "background-clip: border-box, padding-box, border-box; background-origin: border-box, padding-box, padding-box; -moz-background-size: auto, auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
 is(e.style.background, "", "should not have background shorthand (-moz-background-size too long)");
 
 // Check that we only serialize transition when the lists are the same length.
 e.setAttribute("style", "-moz-transition-property: color, width; -moz-transition-duration: 1s, 200ms; -moz-transition-timing-function: ease-in, linear; -moz-transition-delay: 0s, 1s");
 isnot(e.style.MozTransition, "", "should have -moz-transition shorthand (lists same length)");
 e.setAttribute("style", "-moz-transition-property: color, width, left; -moz-transition-duration: 1s, 200ms; -moz-transition-timing-function: ease-in, linear; -moz-transition-delay: 0s, 1s");
 is(e.style.MozTransition, "", "should not have -moz-transition shorthand (lists different lengths)");
 e.setAttribute("style", "-moz-transition-property: all; -moz-transition-duration: 1s, 200ms; -moz-transition-timing-function: ease-in, linear; -moz-transition-delay: 0s, 1s");