--- a/layout/reftests/backgrounds/reftest.list
+++ b/layout/reftests/backgrounds/reftest.list
@@ -176,12 +176,12 @@ fuzzy-if(skiaContent,1,8) == background-
fuzzy(30,474) fuzzy-if(skiaContent,31,474) == background-tiling-zoom-1.html background-tiling-zoom-1-ref.html
skip-if(!cocoaWidget) == background-repeat-resampling.html background-repeat-resampling-ref.html
fuzzy-if(winWidget,102,2032) fuzzy-if(skiaContent,102,2811) == background-clip-text-1a.html background-clip-text-1-ref.html
fuzzy-if(winWidget,102,2032) fuzzy-if(skiaContent,102,2811) == background-clip-text-1b.html background-clip-text-1-ref.html
fuzzy-if(winWidget,102,2032) fuzzy-if(skiaContent,102,2811) == background-clip-text-1c.html background-clip-text-1-ref.html
-fuzzy-if(winWidget,102,2032) fuzzy-if(skiaContent,102,2811) fails-if(stylo) == background-clip-text-1d.html background-clip-text-1-ref.html
+fuzzy-if(winWidget,102,2032) fuzzy-if(skiaContent,102,2811) == background-clip-text-1d.html background-clip-text-1-ref.html
fuzzy-if(winWidget,102,2032) fuzzy-if(skiaContent,102,2811) == background-clip-text-1e.html background-clip-text-1-ref.html
== background-clip-text-2.html background-clip-text-2-ref.html
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -12304,21 +12304,26 @@ CSSParserImpl::ParseImageLayersItem(
aState.mMode->mValue.SetIntValue(NS_STYLE_MASK_MODE_MATCH_SOURCE,
eCSSUnit_Enumerated);
bool haveColor = false,
haveImage = false,
haveRepeat = false,
haveAttach = false,
havePositionAndSize = false,
haveOrigin = false,
+ haveClip = false,
haveComposite = false,
haveMode = false,
haveSomething = false;
- const KTableEntry* originTable = nsCSSProps::kKeywordTableTable[aTable[nsStyleImageLayers::origin]];
+ const KTableEntry* originTable =
+ nsCSSProps::kKeywordTableTable[aTable[nsStyleImageLayers::origin]];
+ const KTableEntry* clipTable =
+ nsCSSProps::kKeywordTableTable[aTable[nsStyleImageLayers::clip]];
+
while (GetToken(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;
}
@@ -12382,41 +12387,42 @@ CSSParserImpl::ParseImageLayersItem(
nsCSSProps::FindKeyword(keyword, originTable, dummy)) {
haveOrigin = true;
if (ParseSingleValueProperty(aState.mOrigin->mValue,
aTable[nsStyleImageLayers::origin]) !=
CSSParseResult::Ok) {
NS_NOTREACHED("should be able to parse");
return false;
}
-
- // The spec allows a second box value (for background-clip),
- // immediately following the first one (for background-origin).
-
+ // Set clip value to origin if clip is not set yet.
+ // Note that we don't set haveClip here so that it can be
+ // overridden if we see it later.
+ if (!haveClip) {
#ifdef DEBUG
- const KTableEntry* clipTable = nsCSSProps::kKeywordTableTable[aTable[nsStyleImageLayers::clip]];
- for (size_t i = 0; originTable[i].mValue != -1; i++) {
- // For each keyword & value in kOriginKTable, ensure that
- // kBackgroundKTable has a matching entry at the same position.
- MOZ_ASSERT(originTable[i].mKeyword == clipTable[i].mKeyword);
- MOZ_ASSERT(originTable[i].mValue == clipTable[i].mValue);
- }
+ for (size_t i = 0; originTable[i].mValue != -1; i++) {
+ // For each keyword & value in kOriginKTable, ensure that
+ // kBackgroundKTable has a matching entry at the same position.
+ MOZ_ASSERT(originTable[i].mKeyword == clipTable[i].mKeyword);
+ MOZ_ASSERT(originTable[i].mValue == clipTable[i].mValue);
+ }
#endif
- CSSParseResult result =
- ParseSingleValueProperty(aState.mClip->mValue,
- aTable[nsStyleImageLayers::clip]);
- MOZ_ASSERT(result != CSSParseResult::Error,
- "how can failing to parse a single background-clip value "
- "consume tokens?");
- if (result == CSSParseResult::NotFound) {
- // When exactly one <box> value is set, it is used for both
- // 'background-origin' and 'background-clip'.
- // See assertions above showing these values are compatible.
aState.mClip->mValue = aState.mOrigin->mValue;
}
+ } else if (!haveClip &&
+ nsCSSProps::FindKeyword(keyword, clipTable, dummy)) {
+ // It is important that we try parsing clip later than origin
+ // because if there are two <box> / <geometry-box> values, the
+ // first should be origin, and the second should be clip.
+ haveClip = true;
+ if (ParseSingleValueProperty(aState.mClip->mValue,
+ aTable[nsStyleImageLayers::clip]) !=
+ CSSParseResult::Ok) {
+ NS_NOTREACHED("should be able to parse");
+ return false;
+ }
} else if (!haveComposite &&
aTable[nsStyleImageLayers::composite] !=
eCSSProperty_UNKNOWN &&
nsCSSProps::FindKeyword(
keyword, nsCSSProps::kImageLayerCompositeKTable, dummy)) {
haveComposite = true;
if (ParseSingleValueProperty(aState.mComposite->mValue,
aTable[nsStyleImageLayers::composite]) !=
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -2199,33 +2199,41 @@ var gCSSProperties = {
"top left / 100px calc(20px)",
"bottom right scroll none transparent repeat",
"50% transparent",
"transparent 50%",
"50%",
"radial-gradient(at 10% bottom, #ffffff, black) scroll no-repeat",
"repeating-radial-gradient(at 10% bottom, #ffffff, black) scroll no-repeat",
"-moz-element(#test) lime",
- /* multiple backgrounds */
- "url(404.png), url(404.png)",
- "url(404.png), url(404.png) transparent",
- "url(404.png), url(404.png) red",
- "repeat-x, fixed, none",
- "0% top url(404.png), url(404.png) 0% top",
- "fixed repeat-y top left url(404.png), repeat-x green",
- "top left / contain, bottom right / cover",
- /* test cases with clip+origin in the shorthand */
- "url(404.png) green padding-box",
- "url(404.png) border-box transparent",
- "content-box url(404.png) blue",
- "url(404.png) green padding-box padding-box",
- "url(404.png) green padding-box border-box",
- "content-box border-box url(404.png) blue",
- "url(404.png) green padding-box text",
- "content-box text url(404.png) blue"
+ /* multiple backgrounds */
+ "url(404.png), url(404.png)",
+ "url(404.png), url(404.png) transparent",
+ "url(404.png), url(404.png) red",
+ "repeat-x, fixed, none",
+ "0% top url(404.png), url(404.png) 0% top",
+ "fixed repeat-y top left url(404.png), repeat-x green",
+ "top left / contain, bottom right / cover",
+ /* test cases with clip+origin in the shorthand */
+ "url(404.png) green padding-box",
+ "url(404.png) border-box transparent",
+ "content-box url(404.png) blue",
+ "url(404.png) green padding-box padding-box",
+ "url(404.png) green padding-box border-box",
+ "content-box border-box url(404.png) blue",
+ "url(404.png) green padding-box text",
+ "content-box text url(404.png) blue",
+ /* clip and origin separated in the shorthand */
+ "url(404.png) padding-box green border-box",
+ "url(404.png) padding-box green padding-box",
+ "transparent padding-box url(404.png) border-box",
+ "transparent padding-box url(404.png) padding-box",
+ /* text */
+ "text",
+ "text border-box",
],
invalid_values: [
/* mixes with keywords have to be in correct order */
"50% left", "top 50%",
/* no quirks mode colors */
"radial-gradient(at 10% bottom, ffffff, black) scroll no-repeat",
/* no quirks mode lengths */
"linear-gradient(red -99, yellow, green, blue 120%)",
@@ -2237,26 +2245,19 @@ var gCSSProperties = {
"url(404.png) transparent, url(404.png) transparent",
"url(404.png) transparent red, url(404.png) transparent red",
"url(404.png) red, url(404.png) red",
"url(404.png) rgba(0, 0, 0, 0), url(404.png)",
"url(404.png) rgb(255, 0, 0), url(404.png)",
"url(404.png) rgba(0, 0, 0, 0), url(404.png) rgba(0, 0, 0, 0)",
"url(404.png) rgba(0, 0, 0, 0) rgb(255, 0, 0), url(404.png) rgba(0, 0, 0, 0) rgb(255, 0, 0)",
"url(404.png) rgb(255, 0, 0), url(404.png) rgb(255, 0, 0)",
- /* clip and origin separated in the shorthand */
- "url(404.png) padding-box green border-box",
- "url(404.png) padding-box green padding-box",
- "transparent padding-box url(404.png) border-box",
- "transparent padding-box url(404.png) padding-box",
/* error inside functions */
"-moz-image-rect(url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==), rubbish, 50%, 30%, 0) transparent",
"-moz-element(#a rubbish) black",
- "text",
- "text border-box",
"content-box text text",
"padding-box text url(404.png) text",
]
},
"background-attachment": {
domProp: "backgroundAttachment",
inherited: false,
type: CSS_TYPE_LONGHAND,
@@ -7058,28 +7059,28 @@ if (SupportsMaskShorthand()) {
"top left / contain, bottom right / cover",
/* test cases with clip+origin in the shorthand */
"url(404.png) alpha padding-box",
"url(404.png) border-box alpha",
"content-box url(404.png)",
"url(404.png) alpha padding-box padding-box",
"url(404.png) alpha padding-box border-box",
"content-box border-box url(404.png)",
+ "alpha padding-box url(404.png) border-box",
+ "alpha padding-box url(404.png) padding-box",
],
invalid_values: [
/* mixes with keywords have to be in correct order */
"50% left", "top 50%",
/* no quirks mode colors */
"radial-gradient(at 10% bottom, ffffff, black) add no-repeat",
/* no quirks mode lengths */
"linear-gradient(red -99, yellow, green, blue 120%)",
/* bug 258080: don't accept background-position separated */
"left url(404.png) top", "top url(404.png) left",
- "alpha padding-box url(404.png) border-box",
- "alpha padding-box url(404.png) padding-box",
"-moz-element(#a rubbish)",
"left top / match-source"
]
};
gCSSProperties["mask-clip"] = {
domProp: "maskClip",
inherited: false,
type: CSS_TYPE_LONGHAND,