diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index 32c6ddc1b71c..af92d93337ad 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -544,6 +544,19 @@ CSS_PROP_BACKGROUND( kBackgroundInlinePolicyKTable, CSS_PROP_NO_OFFSET, eStyleAnimType_None) +CSS_PROP_BACKGROUND( + background-blend-mode, + background_blend_mode, + BackgroundBlendMode, + CSS_PROPERTY_PARSE_VALUE_LIST | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | + CSS_PROPERTY_APPLIES_TO_PLACEHOLDER | + CSS_PROPERTY_VALUE_LIST_USES_COMMAS, + "layout.css.background-blend-mode.enabled", + VARIANT_KEYWORD, // used by list parsing + kBlendModeKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) CSS_PROP_BACKGROUND( background-origin, background_origin, diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index fda61e30fe8d..dcdb1c5ed39b 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -2010,6 +2010,14 @@ nsComputedDOMStyle::DoGetBackgroundInlinePolicy() return val; } +CSSValue* +nsComputedDOMStyle::DoGetBackgroundBlendMode() +{ + return GetBackgroundList(&nsStyleBackground::Layer::mBlendMode, + &nsStyleBackground::mBlendModeCount, + nsCSSProps::kBlendModeKTable); +} + CSSValue* nsComputedDOMStyle::DoGetBackgroundOrigin() { diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h index 9f3867d8293a..2cc2d6b61f18 100644 --- a/layout/style/nsComputedDOMStyle.h +++ b/layout/style/nsComputedDOMStyle.h @@ -260,6 +260,7 @@ private: mozilla::dom::CSSValue* DoGetBackgroundRepeat(); mozilla::dom::CSSValue* DoGetBackgroundClip(); mozilla::dom::CSSValue* DoGetBackgroundInlinePolicy(); + mozilla::dom::CSSValue* DoGetBackgroundBlendMode(); mozilla::dom::CSSValue* DoGetBackgroundOrigin(); mozilla::dom::CSSValue* DoGetBackgroundSize(); diff --git a/layout/style/nsComputedDOMStylePropertyList.h b/layout/style/nsComputedDOMStylePropertyList.h index b9d607f50e8f..efb55411cfc5 100644 --- a/layout/style/nsComputedDOMStylePropertyList.h +++ b/layout/style/nsComputedDOMStylePropertyList.h @@ -53,6 +53,7 @@ COMPUTED_STYLE_PROP(animation_timing_function, AnimationTimingFunction) COMPUTED_STYLE_PROP(backface_visibility, BackfaceVisibility) //// COMPUTED_STYLE_PROP(background, Background) COMPUTED_STYLE_PROP(background_attachment, BackgroundAttachment) +COMPUTED_STYLE_PROP(background_blend_mode, BackgroundBlendMode) COMPUTED_STYLE_PROP(background_clip, BackgroundClip) COMPUTED_STYLE_PROP(background_color, BackgroundColor) COMPUTED_STYLE_PROP(background_image, BackgroundImage) diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 13b83cb06335..3069b873b4a5 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -6050,6 +6050,14 @@ nsRuleNode::ComputeBackgroundData(void* aStartStruct, parentBG->mBackgroundInlinePolicy, NS_STYLE_BG_INLINE_POLICY_CONTINUOUS, 0, 0, 0, 0); + // background-blend-mode: enum, inherit, initial [list] + SetBackgroundList(aContext, *aRuleData->ValueForBackgroundBlendMode(), + bg->mLayers, + parentBG->mLayers, &nsStyleBackground::Layer::mBlendMode, + uint8_t(NS_STYLE_BLEND_NORMAL), parentBG->mBlendModeCount, + bg->mBlendModeCount, maxItemCount, rebuild, + canStoreInRuleTree); + // background-origin: enum, inherit, initial [list] SetBackgroundList(aContext, *aRuleData->ValueForBackgroundOrigin(), bg->mLayers, @@ -6092,6 +6100,8 @@ nsRuleNode::ComputeBackgroundData(void* aStartStruct, bg->mAttachmentCount, fillCount); FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mClip, bg->mClipCount, fillCount); + FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mBlendMode, + bg->mBlendModeCount, fillCount); FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mOrigin, bg->mOriginCount, fillCount); FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mPosition, diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 95e58f5c4f9c..ad8479a59646 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -1904,6 +1904,7 @@ nsStyleBackground::nsStyleBackground() , mPositionCount(1) , mImageCount(1) , mSizeCount(1) + , mBlendModeCount(1) , mBackgroundColor(NS_RGBA(0, 0, 0, 0)) , mBackgroundInlinePolicy(NS_STYLE_BG_INLINE_POLICY_CONTINUOUS) { @@ -1921,6 +1922,7 @@ nsStyleBackground::nsStyleBackground(const nsStyleBackground& aSource) , mPositionCount(aSource.mPositionCount) , mImageCount(aSource.mImageCount) , mSizeCount(aSource.mSizeCount) + , mBlendModeCount(aSource.mBlendModeCount) , mLayers(aSource.mLayers) // deep copy , mBackgroundColor(aSource.mBackgroundColor) , mBackgroundInlinePolicy(aSource.mBackgroundInlinePolicy) @@ -1937,6 +1939,7 @@ nsStyleBackground::nsStyleBackground(const nsStyleBackground& aSource) mPositionCount = std::max(mPositionCount, count); mImageCount = std::max(mImageCount, count); mSizeCount = std::max(mSizeCount, count); + mBlendModeCount = std::max(mSizeCount, count); } } @@ -2144,6 +2147,7 @@ nsStyleBackground::Layer::SetInitialValues() mClip = NS_STYLE_BG_CLIP_BORDER; mOrigin = NS_STYLE_BG_ORIGIN_PADDING; mRepeat.SetInitialValues(); + mBlendMode = NS_STYLE_BLEND_NORMAL; mPosition.SetInitialValues(); mSize.SetInitialValues(); mImage.SetNull(); @@ -2168,6 +2172,7 @@ nsStyleBackground::Layer::operator==(const Layer& aOther) const mClip == aOther.mClip && mOrigin == aOther.mOrigin && mRepeat == aOther.mRepeat && + mBlendMode == aOther.mBlendMode && mPosition == aOther.mPosition && mSize == aOther.mSize && mImage == aOther.mImage; diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 62bfb5161131..9d45a92fee4d 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -443,6 +443,7 @@ struct nsStyleBackground { uint8_t mAttachment; // [reset] See nsStyleConsts.h uint8_t mClip; // [reset] See nsStyleConsts.h uint8_t mOrigin; // [reset] See nsStyleConsts.h + uint8_t mBlendMode; // [reset] See nsStyleConsts.h Repeat mRepeat; // [reset] See nsStyleConsts.h Position mPosition; // [reset] nsStyleImage mImage; // [reset] @@ -488,7 +489,8 @@ struct nsStyleBackground { mRepeatCount, mPositionCount, mImageCount, - mSizeCount; + mSizeCount, + mBlendModeCount; // Layers are stored in an array, matching the top-to-bottom order in // which they are specified in CSS. The number of layers to be used // should come from the background-image property. We create diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index 3e585c86fd53..4fcf577a84d1 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -4762,6 +4762,18 @@ if (SpecialPowers.getBoolPref("layout.css.mix-blend-mode.enabled")) { }; } +if (SpecialPowers.getBoolPref("layout.css.background-blend-mode.enabled")) { + gCSSProperties["background-blend-mode"] = { + domProp: "backgroundBlendMode", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: [ "normal" ], + other_values: [ "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", + "hard-light", "soft-light", "difference", "exclusion", "hue", "saturation", "color", "luminosity" ], + invalid_values: [] + }; +} + if (SpecialPowers.getBoolPref("layout.css.unset-value.enabled")) { gCSSProperties["animation-direction"].invalid_values.push("normal, unset"); gCSSProperties["animation-name"].invalid_values.push("bounce, unset", "unset, bounce"); diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index a38e4ee2ec71..37470293a48b 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -1919,6 +1919,13 @@ pref("layout.css.scope-pseudo.enabled", false); pref("layout.css.scope-pseudo.enabled", true); #endif +// Is support for background-blend-mode enabled? +#ifdef RELEASE_BUILD +pref("layout.css.background-blend-mode.enabled", false); +#else +pref("layout.css.background-blend-mode.enabled", true); +#endif + // Is support for CSS vertical text enabled? pref("layout.css.vertical-text.enabled", false);