Bug 759568 - Part 1. Parse background-clip:text;
MozReview-Commit-ID: HiKHnD3pvto
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -141,16 +141,17 @@ using namespace mozilla::layout;
using namespace mozilla::gfx;
#define GRID_ENABLED_PREF_NAME "layout.css.grid.enabled"
#define GRID_TEMPLATE_SUBGRID_ENABLED_PREF_NAME "layout.css.grid-template-subgrid-value.enabled"
#define WEBKIT_PREFIXES_ENABLED_PREF_NAME "layout.css.prefixes.webkit"
#define DISPLAY_CONTENTS_ENABLED_PREF_NAME "layout.css.display-contents.enabled"
#define TEXT_ALIGN_UNSAFE_ENABLED_PREF_NAME "layout.css.text-align-unsafe-value.enabled"
#define FLOAT_LOGICAL_VALUES_ENABLED_PREF_NAME "layout.css.float-logical-values.enabled"
+#define BG_CLIP_TEXT_ENABLED_PREF_NAME "layout.css.background-clip-text.enabled"
#ifdef DEBUG
// TODO: remove, see bug 598468.
bool nsLayoutUtils::gPreventAssertInCompareTreePosition = false;
#endif // DEBUG
typedef FrameMetrics::ViewID ViewID;
typedef nsStyleTransformMatrix::TransformReferenceBox TransformReferenceBox;
@@ -387,16 +388,45 @@ FloatLogicalValuesEnabledPrefChangeCallb
MOZ_ASSERT(sIndexOfInlineStartInClearTable >= 0);
nsCSSProps::kClearKTable[sIndexOfInlineStartInClearTable].mKeyword =
isFloatLogicalValuesEnabled ? eCSSKeyword_inline_start : eCSSKeyword_UNKNOWN;
MOZ_ASSERT(sIndexOfInlineEndInClearTable >= 0);
nsCSSProps::kClearKTable[sIndexOfInlineEndInClearTable].mKeyword =
isFloatLogicalValuesEnabled ? eCSSKeyword_inline_end : eCSSKeyword_UNKNOWN;
}
+static void
+BackgroundClipTextEnabledPrefChangeCallback(const char* aPrefName,
+ void* aClosure)
+{
+ NS_ASSERTION(strcmp(aPrefName, BG_CLIP_TEXT_ENABLED_PREF_NAME) == 0,
+ "Did you misspell " BG_CLIP_TEXT_ENABLED_PREF_NAME " ?");
+
+ static bool sIsBGClipKeywordIndexInitialized;
+ static int32_t sIndexOfTextInBGClipTable;
+ bool isBGClipTextEnabled =
+ Preferences::GetBool(BG_CLIP_TEXT_ENABLED_PREF_NAME, false);
+
+ if (!sIsBGClipKeywordIndexInitialized) {
+ // First run: find the position of "text" in kBackgroundClipKTable.
+ sIndexOfTextInBGClipTable =
+ nsCSSProps::FindIndexOfKeyword(eCSSKeyword_text,
+ nsCSSProps::kBackgroundClipKTable);
+
+ sIsBGClipKeywordIndexInitialized = true;
+ }
+
+ // OK -- now, stomp on or restore the "text" entry in kBackgroundClipKTable,
+ // depending on whether the pref is enabled vs. disabled.
+ if (sIndexOfTextInBGClipTable >= 0) {
+ nsCSSProps::kBackgroundClipKTable[sIndexOfTextInBGClipTable].mKeyword =
+ isBGClipTextEnabled ? eCSSKeyword_text : eCSSKeyword_UNKNOWN;
+ }
+}
+
template<typename TestType>
static bool
HasMatchingCurrentAnimations(const nsIFrame* aFrame, TestType&& aTest)
{
EffectSet* effects = EffectSet::GetEffectSet(aFrame);
if (!effects) {
return false;
}
@@ -7638,16 +7668,20 @@ nsLayoutUtils::Initialize()
DisplayContentsEnabledPrefChangeCallback(DISPLAY_CONTENTS_ENABLED_PREF_NAME,
nullptr);
TextAlignUnsafeEnabledPrefChangeCallback(TEXT_ALIGN_UNSAFE_ENABLED_PREF_NAME,
nullptr);
Preferences::RegisterCallback(FloatLogicalValuesEnabledPrefChangeCallback,
FLOAT_LOGICAL_VALUES_ENABLED_PREF_NAME);
FloatLogicalValuesEnabledPrefChangeCallback(FLOAT_LOGICAL_VALUES_ENABLED_PREF_NAME,
nullptr);
+ Preferences::RegisterCallback(BackgroundClipTextEnabledPrefChangeCallback,
+ BG_CLIP_TEXT_ENABLED_PREF_NAME);
+ BackgroundClipTextEnabledPrefChangeCallback(BG_CLIP_TEXT_ENABLED_PREF_NAME,
+ nullptr);
nsComputedDOMStyle::RegisterPrefChangeCallbacks();
}
/* static */
void
nsLayoutUtils::Shutdown()
{
--- a/layout/style/Declaration.cpp
+++ b/layout/style/Declaration.cpp
@@ -290,22 +290,26 @@ Declaration::GetImageLayerValue(
}
MOZ_ASSERT(clip->mValue.GetUnit() == eCSSUnit_Enumerated &&
origin->mValue.GetUnit() == eCSSUnit_Enumerated,
"should not have inherit/initial within list");
if (clip->mValue.GetIntValue() != NS_STYLE_IMAGELAYER_CLIP_BORDER ||
origin->mValue.GetIntValue() != NS_STYLE_IMAGELAYER_ORIGIN_PADDING) {
- MOZ_ASSERT(nsCSSProps::kKeywordTableTable[
- aTable[nsStyleImageLayers::origin]] ==
- nsCSSProps::kImageLayerOriginKTable);
- MOZ_ASSERT(nsCSSProps::kKeywordTableTable[
- aTable[nsStyleImageLayers::clip]] ==
- nsCSSProps::kImageLayerOriginKTable);
+#ifdef DEBUG
+ for (int i = 0; nsCSSProps::kImageLayerOriginKTable[i].mValue != -1 ; i++) {
+ // Ensure the keyword positions in origin and clip table are the same.
+ MOZ_ASSERT(nsCSSProps::kImageLayerOriginKTable[i].mKeyword ==
+ nsCSSProps::kBackgroundClipKTable[i].mKeyword);
+ // Ensure the keyword values in origin and clip table are the same.
+ MOZ_ASSERT(nsCSSProps::kImageLayerOriginKTable[i].mValue ==
+ nsCSSProps::kBackgroundClipKTable[i].mValue);
+ }
+#endif
static_assert(NS_STYLE_IMAGELAYER_CLIP_BORDER ==
NS_STYLE_IMAGELAYER_ORIGIN_BORDER &&
NS_STYLE_IMAGELAYER_CLIP_PADDING ==
NS_STYLE_IMAGELAYER_ORIGIN_PADDING &&
NS_STYLE_IMAGELAYER_CLIP_CONTENT ==
NS_STYLE_IMAGELAYER_ORIGIN_CONTENT,
"mask-clip and mask-origin style constants must agree");
aValue.Append(char16_t(' '));
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -12055,23 +12055,26 @@ CSSParserImpl::ParseImageLayersItem(
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).
- // 'background-clip' and 'background-origin' use the same keyword table
- MOZ_ASSERT(nsCSSProps::kKeywordTableTable[
- aTable[nsStyleImageLayers::origin]] ==
- nsCSSProps::kImageLayerOriginKTable);
- MOZ_ASSERT(nsCSSProps::kKeywordTableTable[
- aTable[nsStyleImageLayers::clip]] ==
- nsCSSProps::kImageLayerOriginKTable);
+#ifdef DEBUG
+ for (int i = 0; nsCSSProps::kImageLayerOriginKTable[i].mValue != -1 ; i++) {
+ // Ensure the keyword positions in origin and clip table are the same.
+ MOZ_ASSERT(nsCSSProps::kImageLayerOriginKTable[i].mKeyword ==
+ nsCSSProps::kBackgroundClipKTable[i].mKeyword);
+ // Ensure the keyword values in origin and clip table are the same.
+ MOZ_ASSERT(nsCSSProps::kImageLayerOriginKTable[i].mValue ==
+ nsCSSProps::kBackgroundClipKTable[i].mValue);
+ }
+#endif
static_assert(NS_STYLE_IMAGELAYER_CLIP_BORDER ==
NS_STYLE_IMAGELAYER_ORIGIN_BORDER &&
NS_STYLE_IMAGELAYER_CLIP_PADDING ==
NS_STYLE_IMAGELAYER_ORIGIN_PADDING &&
NS_STYLE_IMAGELAYER_CLIP_CONTENT ==
NS_STYLE_IMAGELAYER_ORIGIN_CONTENT,
"bg-clip and bg-origin style constants must agree");
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -545,17 +545,17 @@ CSS_PROP_BACKGROUND(
background_clip,
BackgroundClip,
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,
"",
VARIANT_KEYWORD, // used by list parsing
- kImageLayerOriginKTable,
+ kBackgroundClipKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
CSS_PROP_BACKGROUND(
background-color,
background_color,
BackgroundColor,
CSS_PROPERTY_PARSE_VALUE |
CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE |
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -885,24 +885,41 @@ const KTableEntry nsCSSProps::kImageLaye
{ eCSSKeyword_scroll, NS_STYLE_IMAGELAYER_ATTACHMENT_SCROLL },
{ eCSSKeyword_local, NS_STYLE_IMAGELAYER_ATTACHMENT_LOCAL },
{ eCSSKeyword_UNKNOWN, -1 }
};
static_assert(NS_STYLE_IMAGELAYER_CLIP_BORDER == NS_STYLE_IMAGELAYER_ORIGIN_BORDER &&
NS_STYLE_IMAGELAYER_CLIP_PADDING == NS_STYLE_IMAGELAYER_ORIGIN_PADDING &&
NS_STYLE_IMAGELAYER_CLIP_CONTENT == NS_STYLE_IMAGELAYER_ORIGIN_CONTENT,
- "bg-clip and bg-origin style constants must agree");
+ "Except background-clip:text, all the other background-clip and "
+ "background-origin style constants must agree");
+
const KTableEntry nsCSSProps::kImageLayerOriginKTable[] = {
{ eCSSKeyword_border_box, NS_STYLE_IMAGELAYER_ORIGIN_BORDER },
{ eCSSKeyword_padding_box, NS_STYLE_IMAGELAYER_ORIGIN_PADDING },
{ eCSSKeyword_content_box, NS_STYLE_IMAGELAYER_ORIGIN_CONTENT },
{ eCSSKeyword_UNKNOWN, -1 }
};
+KTableEntry nsCSSProps::kBackgroundClipKTable[] = {
+ { eCSSKeyword_border_box, NS_STYLE_IMAGELAYER_CLIP_BORDER },
+ { eCSSKeyword_padding_box, NS_STYLE_IMAGELAYER_CLIP_PADDING },
+ { eCSSKeyword_content_box, NS_STYLE_IMAGELAYER_CLIP_CONTENT },
+ // The next entry is controlled by the layout.css.background-clip-text.enabled
+ // pref.
+ { eCSSKeyword_text, NS_STYLE_IMAGELAYER_CLIP_TEXT },
+ { eCSSKeyword_UNKNOWN, -1 }
+};
+
+static_assert(ArrayLength(nsCSSProps::kImageLayerOriginKTable) ==
+ ArrayLength(nsCSSProps::kBackgroundClipKTable) - 1,
+ "background-clip has one more extra value, which is text, compare"
+ "to background-origin");
+
// Note: Don't change this table unless you update
// ParseImageLayerPosition!
const KTableEntry nsCSSProps::kImageLayerPositionKTable[] = {
{ eCSSKeyword_center, NS_STYLE_IMAGELAYER_POSITION_CENTER },
{ eCSSKeyword_top, NS_STYLE_IMAGELAYER_POSITION_TOP },
{ eCSSKeyword_bottom, NS_STYLE_IMAGELAYER_POSITION_BOTTOM },
{ eCSSKeyword_left, NS_STYLE_IMAGELAYER_POSITION_LEFT },
--- a/layout/style/nsCSSProps.h
+++ b/layout/style/nsCSSProps.h
@@ -673,16 +673,19 @@ public:
static const KTableEntry kImageLayerAttachmentKTable[];
static const KTableEntry kImageLayerOriginKTable[];
static const KTableEntry kImageLayerPositionKTable[];
static const KTableEntry kImageLayerRepeatKTable[];
static const KTableEntry kImageLayerRepeatPartKTable[];
static const KTableEntry kImageLayerSizeKTable[];
static const KTableEntry kImageLayerCompositeKTable[];
static const KTableEntry kImageLayerModeKTable[];
+ // Not const because we modify its entries when the pref
+ // "layout.css.background-clip.text" changes:
+ static KTableEntry kBackgroundClipKTable[];
static const KTableEntry kBlendModeKTable[];
static const KTableEntry kBorderCollapseKTable[];
static const KTableEntry kBorderColorKTable[];
static const KTableEntry kBorderImageRepeatKTable[];
static const KTableEntry kBorderImageSliceKTable[];
static const KTableEntry kBorderStyleKTable[];
static const KTableEntry kBorderWidthKTable[];
static const KTableEntry kBoxAlignKTable[];
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -1840,17 +1840,17 @@ nsComputedDOMStyle::DoGetBackgroundAttac
}
already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetBackgroundClip()
{
return GetBackgroundList(&nsStyleImageLayers::Layer::mClip,
&nsStyleImageLayers::mClipCount,
StyleBackground()->mImage,
- nsCSSProps::kImageLayerOriginKTable);
+ nsCSSProps::kBackgroundClipKTable);
}
already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetBackgroundColor()
{
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
SetToRGBAColor(val, StyleBackground()->mBackgroundColor);
return val.forget();
--- a/layout/style/nsStyleConsts.h
+++ b/layout/style/nsStyleConsts.h
@@ -262,20 +262,22 @@ enum class FillMode : uint32_t;
#define NS_STYLE_ANIMATION_PLAY_STATE_PAUSED 1
// See nsStyleImageLayers
#define NS_STYLE_IMAGELAYER_ATTACHMENT_SCROLL 0
#define NS_STYLE_IMAGELAYER_ATTACHMENT_FIXED 1
#define NS_STYLE_IMAGELAYER_ATTACHMENT_LOCAL 2
// See nsStyleImageLayers
-// Code depends on these constants having the same values as BG_ORIGIN_*
+// Code depends on these constants having the same values as IMAGELAYER_ORIGIN_*
#define NS_STYLE_IMAGELAYER_CLIP_BORDER 0
#define NS_STYLE_IMAGELAYER_CLIP_PADDING 1
#define NS_STYLE_IMAGELAYER_CLIP_CONTENT 2
+// One extra constant which does not exist in IMAGELAYER_ORIGIN_*
+#define NS_STYLE_IMAGELAYER_CLIP_TEXT 3
// A magic value that we use for our "pretend that background-clip is
// 'padding' when we have a solid border" optimization. This isn't
// actually equal to NS_STYLE_IMAGELAYER_CLIP_PADDING because using that
// causes antialiasing seams between the background and border. This
// is a backend-only value.
#define NS_STYLE_IMAGELAYER_CLIP_MOZ_ALMOST_PADDING 127
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -2417,16 +2417,20 @@ pref("layout.css.unprefixing-service.glo
#endif
// Is support for the :scope selector enabled?
pref("layout.css.scope-pseudo.enabled", true);
// Is support for background-blend-mode enabled?
pref("layout.css.background-blend-mode.enabled", true);
+// Keep this disabled on for now. See bug 1263516.
+// Is support for background-clip:text enabled?
+pref("layout.css.background-clip-text.enabled", false);
+
// Is support for CSS vertical text enabled?
pref("layout.css.vertical-text.enabled", true);
// Is support for CSS text-combine-upright (tate-chu-yoko) enabled?
pref("layout.css.text-combine-upright.enabled", false);
// Is support for object-fit and object-position enabled?
pref("layout.css.object-fit-and-position.enabled", true);