зеркало из https://github.com/mozilla/gecko-dev.git
Bug 550426 - Add support for {background,mask}-position-{x,y}, most of the style system changes. r=dbaron
MozReview-Commit-ID: JgZIoj43aZv --HG-- extra : rebase_source : cf90a8cf7c10ee90f4c312b7ff5c1107aa8571f2
This commit is contained in:
Родитель
7189351aab
Коммит
1a43349a44
|
@ -201,6 +201,41 @@ Declaration::GetAuthoredValue(nsCSSProperty aProperty, nsAString& aValue) const
|
|||
GetValue(aProperty, aValue, nsCSSValue::eAuthorSpecified);
|
||||
}
|
||||
|
||||
static void
|
||||
AppendSingleImageLayerPositionValue(const nsCSSValue& aPositionX,
|
||||
const nsCSSValue& aPositionY,
|
||||
const nsCSSProperty aTable[],
|
||||
nsAString& aValue,
|
||||
nsCSSValue::Serialization aSerialization)
|
||||
{
|
||||
// We need to make sure that we don't serialize to an invalid 3-value form.
|
||||
// The 3-value form is only valid if both edges are present.
|
||||
const nsCSSValue &xEdge = aPositionX.GetArrayValue()->Item(0);
|
||||
const nsCSSValue &xOffset = aPositionX.GetArrayValue()->Item(1);
|
||||
const nsCSSValue &yEdge = aPositionY.GetArrayValue()->Item(0);
|
||||
const nsCSSValue &yOffset = aPositionY.GetArrayValue()->Item(1);
|
||||
bool xHasEdge = (eCSSUnit_Enumerated == xEdge.GetUnit());
|
||||
bool xHasBoth = xHasEdge && (eCSSUnit_Null != xOffset.GetUnit());
|
||||
bool yHasEdge = (eCSSUnit_Enumerated == yEdge.GetUnit());
|
||||
bool yHasBoth = yHasEdge && (eCSSUnit_Null != yOffset.GetUnit());
|
||||
|
||||
if (yHasBoth && !xHasEdge) {
|
||||
// Output 4-value form by adding the x edge.
|
||||
aValue.AppendLiteral("left ");
|
||||
}
|
||||
aPositionX.AppendToString(aTable[nsStyleImageLayers::positionX],
|
||||
aValue, aSerialization);
|
||||
|
||||
aValue.Append(char16_t(' '));
|
||||
|
||||
if (xHasBoth && !yHasEdge) {
|
||||
// Output 4-value form by adding the y edge.
|
||||
aValue.AppendLiteral("top ");
|
||||
}
|
||||
aPositionY.AppendToString(aTable[nsStyleImageLayers::positionY],
|
||||
aValue, aSerialization);
|
||||
}
|
||||
|
||||
void
|
||||
Declaration::GetImageLayerValue(
|
||||
nsCSSCompressedDataBlock *data,
|
||||
|
@ -221,8 +256,10 @@ Declaration::GetImageLayerValue(
|
|||
data->ValueFor(aTable[nsStyleImageLayers::image])->GetListValue();
|
||||
const nsCSSValuePairList *repeat =
|
||||
data->ValueFor(aTable[nsStyleImageLayers::repeat])->GetPairListValue();
|
||||
const nsCSSValueList *position =
|
||||
data->ValueFor(aTable[nsStyleImageLayers::position])->GetListValue();
|
||||
const nsCSSValueList *positionX =
|
||||
data->ValueFor(aTable[nsStyleImageLayers::positionX])->GetListValue();
|
||||
const nsCSSValueList *positionY =
|
||||
data->ValueFor(aTable[nsStyleImageLayers::positionY])->GetListValue();
|
||||
const nsCSSValueList *clip =
|
||||
data->ValueFor(aTable[nsStyleImageLayers::clip])->GetListValue();
|
||||
const nsCSSValueList *origin =
|
||||
|
@ -274,8 +311,8 @@ Declaration::GetImageLayerValue(
|
|||
}
|
||||
|
||||
aValue.Append(char16_t(' '));
|
||||
position->mValue.AppendToString(aTable[nsStyleImageLayers::position],
|
||||
aValue, aSerialization);
|
||||
AppendSingleImageLayerPositionValue(positionX->mValue, positionY->mValue,
|
||||
aTable, aValue, aSerialization);
|
||||
|
||||
if (size->mXValue.GetUnit() != eCSSUnit_Auto ||
|
||||
size->mYValue.GetUnit() != eCSSUnit_Auto) {
|
||||
|
@ -337,7 +374,8 @@ Declaration::GetImageLayerValue(
|
|||
|
||||
image = image->mNext;
|
||||
repeat = repeat->mNext;
|
||||
position = position->mNext;
|
||||
positionX = positionX->mNext;
|
||||
positionY = positionY->mNext;
|
||||
clip = clip->mNext;
|
||||
origin = origin->mNext;
|
||||
size = size->mNext;
|
||||
|
@ -348,7 +386,8 @@ Declaration::GetImageLayerValue(
|
|||
if (!image) {
|
||||
// This layer is an background layer
|
||||
if (aTable == nsStyleImageLayers::kBackgroundLayerTable) {
|
||||
if (repeat || position || clip || origin || size || attachment) {
|
||||
if (repeat || positionX || positionY || clip || origin || size ||
|
||||
attachment) {
|
||||
// Uneven length lists, so can't be serialized as shorthand.
|
||||
aValue.Truncate();
|
||||
return;
|
||||
|
@ -360,7 +399,8 @@ Declaration::GetImageLayerValue(
|
|||
#else
|
||||
MOZ_ASSERT_UNREACHABLE("Should never get here when mask-as-shorthand is disable");
|
||||
#endif
|
||||
if (repeat || position || clip || origin || size || composite || mode) {
|
||||
if (repeat || positionX || positionY || clip || origin || size ||
|
||||
composite || mode) {
|
||||
// Uneven length lists, so can't be serialized as shorthand.
|
||||
aValue.Truncate();
|
||||
return;
|
||||
|
@ -371,7 +411,8 @@ Declaration::GetImageLayerValue(
|
|||
|
||||
// This layer is an background layer
|
||||
if (aTable == nsStyleImageLayers::kBackgroundLayerTable) {
|
||||
if (!repeat || !position || !clip || !origin || !size || !attachment) {
|
||||
if (!repeat || !positionX || !positionY || !clip || !origin || !size ||
|
||||
!attachment) {
|
||||
// Uneven length lists, so can't be serialized as shorthand.
|
||||
aValue.Truncate();
|
||||
return;
|
||||
|
@ -383,7 +424,7 @@ Declaration::GetImageLayerValue(
|
|||
#else
|
||||
MOZ_ASSERT_UNREACHABLE("Should never get here when mask-as-shorthand is disable");
|
||||
#endif
|
||||
if (!repeat || !position || !clip || !origin || !size ||
|
||||
if (!repeat || !positionX || !positionY || !clip || !origin || !size ||
|
||||
!composite || !mode) {
|
||||
// Uneven length lists, so can't be serialized as shorthand.
|
||||
aValue.Truncate();
|
||||
|
@ -395,6 +436,39 @@ Declaration::GetImageLayerValue(
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Declaration::GetImageLayerPositionValue(
|
||||
nsCSSCompressedDataBlock *data,
|
||||
nsAString& aValue,
|
||||
nsCSSValue::Serialization aSerialization,
|
||||
const nsCSSProperty aTable[]) const
|
||||
{
|
||||
// We know from above that all subproperties were specified.
|
||||
// However, we still can't represent that in the shorthand unless
|
||||
// they're all lists of the same length. So if they're different
|
||||
// lengths, we need to bail out.
|
||||
const nsCSSValueList *positionX =
|
||||
data->ValueFor(aTable[nsStyleImageLayers::positionX])->GetListValue();
|
||||
const nsCSSValueList *positionY =
|
||||
data->ValueFor(aTable[nsStyleImageLayers::positionY])->GetListValue();
|
||||
for (;;) {
|
||||
AppendSingleImageLayerPositionValue(positionX->mValue, positionY->mValue,
|
||||
aTable, aValue, aSerialization);
|
||||
positionX = positionX->mNext;
|
||||
positionY = positionY->mNext;
|
||||
|
||||
if (!positionX || !positionY) {
|
||||
if (positionX || positionY) {
|
||||
// Uneven length lists, so can't be serialized as shorthand.
|
||||
aValue.Truncate();
|
||||
}
|
||||
return;
|
||||
}
|
||||
aValue.Append(char16_t(','));
|
||||
aValue.Append(char16_t(' '));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue,
|
||||
nsCSSValue::Serialization aSerialization) const
|
||||
|
@ -669,12 +743,22 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue,
|
|||
nsStyleImageLayers::kBackgroundLayerTable);
|
||||
break;
|
||||
}
|
||||
case eCSSProperty_background_position: {
|
||||
GetImageLayerPositionValue(data, aValue, aSerialization,
|
||||
nsStyleImageLayers::kBackgroundLayerTable);
|
||||
break;
|
||||
}
|
||||
#ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
|
||||
case eCSSProperty_mask: {
|
||||
GetImageLayerValue(data, aValue, aSerialization,
|
||||
nsStyleImageLayers::kMaskLayerTable);
|
||||
break;
|
||||
}
|
||||
case eCSSProperty_mask_position: {
|
||||
GetImageLayerPositionValue(data, aValue, aSerialization,
|
||||
nsStyleImageLayers::kMaskLayerTable);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case eCSSProperty_font: {
|
||||
// systemFont might not be present; other values are guaranteed to be
|
||||
|
|
|
@ -375,6 +375,11 @@ private:
|
|||
nsCSSValue::Serialization aSerialization,
|
||||
const nsCSSProperty aTable[]) const;
|
||||
|
||||
void GetImageLayerPositionValue(nsCSSCompressedDataBlock *data,
|
||||
nsAString& aValue,
|
||||
nsCSSValue::Serialization aSerialization,
|
||||
const nsCSSProperty aTable[]) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Returns the property at the given index in the ordered list of
|
||||
|
|
|
@ -865,19 +865,22 @@ protected:
|
|||
nsCSSValueList* mAttachment; // A property for background layer only
|
||||
nsCSSValueList* mClip;
|
||||
nsCSSValueList* mOrigin;
|
||||
nsCSSValueList* mPosition;
|
||||
nsCSSValueList* mPositionX;
|
||||
nsCSSValueList* mPositionY;
|
||||
nsCSSValuePairList* mSize;
|
||||
nsCSSValueList* mComposite; // A property for mask layer only
|
||||
nsCSSValueList* mMode; // A property for mask layer only
|
||||
ImageLayersShorthandParseState(
|
||||
nsCSSValue& aColor, nsCSSValueList* aImage, nsCSSValuePairList* aRepeat,
|
||||
nsCSSValueList* aAttachment, nsCSSValueList* aClip,
|
||||
nsCSSValueList* aOrigin, nsCSSValueList* aPosition,
|
||||
nsCSSValueList* aOrigin,
|
||||
nsCSSValueList* aPositionX, nsCSSValueList* aPositionY,
|
||||
nsCSSValuePairList* aSize, nsCSSValueList* aComposite,
|
||||
nsCSSValueList* aMode) :
|
||||
mColor(aColor), mImage(aImage), mRepeat(aRepeat),
|
||||
mAttachment(aAttachment), mClip(aClip), mOrigin(aOrigin),
|
||||
mPosition(aPosition), mSize(aSize), mComposite(aComposite),
|
||||
mPositionX(aPositionX), mPositionY(aPositionY),
|
||||
mSize(aSize), mComposite(aComposite),
|
||||
mMode(aMode) {};
|
||||
};
|
||||
|
||||
|
@ -888,7 +891,8 @@ protected:
|
|||
bool ParseValueList(nsCSSProperty aPropID); // a single value prop-id
|
||||
bool ParseImageLayerRepeat(nsCSSProperty aPropID);
|
||||
bool ParseImageLayerRepeatValues(nsCSSValuePair& aValue);
|
||||
bool ParseImageLayerPosition(nsCSSProperty aPropID);
|
||||
bool ParseImageLayerPosition(const nsCSSProperty aTable[]);
|
||||
bool ParseImageLayerPositionCoord(nsCSSProperty aPropID, bool aIsHorizontal);
|
||||
|
||||
// ParseBoxPositionValues parses the CSS 2.1 background-position syntax,
|
||||
// which is still used by some properties. See ParsePositionValue
|
||||
|
@ -899,7 +903,9 @@ protected:
|
|||
// ParsePositionValue parses a CSS <position> value, which is used by
|
||||
// the 'background-position' property.
|
||||
bool ParsePositionValue(nsCSSValue& aOut);
|
||||
bool ParsePositionValueSeparateCoords(nsCSSValue& aOutX, nsCSSValue& aOutY);
|
||||
|
||||
bool ParseImageLayerPositionCoordItem(nsCSSValue& aOut, bool aIsHorizontal);
|
||||
bool ParseImageLayerSize(nsCSSProperty aPropID);
|
||||
bool ParseImageLayerSizeValues(nsCSSValuePair& aOut);
|
||||
bool ParseBorderColor();
|
||||
|
@ -11426,7 +11432,11 @@ CSSParserImpl::ParsePropertyByFunction(nsCSSProperty aPropID)
|
|||
case eCSSProperty_background_repeat:
|
||||
return ParseImageLayerRepeat(eCSSProperty_background_repeat);
|
||||
case eCSSProperty_background_position:
|
||||
return ParseImageLayerPosition(eCSSProperty_background_position);
|
||||
return ParseImageLayerPosition(nsStyleImageLayers::kBackgroundLayerTable);
|
||||
case eCSSProperty_background_position_x:
|
||||
case eCSSProperty_background_position_y:
|
||||
return ParseImageLayerPositionCoord(aPropID,
|
||||
aPropID == eCSSProperty_background_position_x);
|
||||
case eCSSProperty_background_size:
|
||||
return ParseImageLayerSize(eCSSProperty_background_size);
|
||||
case eCSSProperty_border:
|
||||
|
@ -11608,7 +11618,11 @@ CSSParserImpl::ParsePropertyByFunction(nsCSSProperty aPropID)
|
|||
case eCSSProperty_mask_repeat:
|
||||
return ParseImageLayerRepeat(eCSSProperty_mask_repeat);
|
||||
case eCSSProperty_mask_position:
|
||||
return ParseImageLayerPosition(eCSSProperty_mask_position);
|
||||
return ParseImageLayerPosition(nsStyleImageLayers::kMaskLayerTable);
|
||||
case eCSSProperty_mask_position_x:
|
||||
case eCSSProperty_mask_position_y:
|
||||
return ParseImageLayerPositionCoord(aPropID,
|
||||
aPropID == eCSSProperty_mask_position_x);
|
||||
case eCSSProperty_mask_size:
|
||||
return ParseImageLayerSize(eCSSProperty_mask_size);
|
||||
#endif
|
||||
|
@ -11889,12 +11903,13 @@ CSSParserImpl::ParseImageLayers(const nsCSSProperty aTable[])
|
|||
return true;
|
||||
}
|
||||
|
||||
nsCSSValue image, repeat, attachment, clip, origin, position, size,
|
||||
nsCSSValue image, repeat, attachment, clip, origin, positionX, positionY, size,
|
||||
composite, maskMode;
|
||||
ImageLayersShorthandParseState state(color, image.SetListValue(),
|
||||
repeat.SetPairListValue(),
|
||||
attachment.SetListValue(), clip.SetListValue(),
|
||||
origin.SetListValue(), position.SetListValue(),
|
||||
origin.SetListValue(),
|
||||
positionX.SetListValue(), positionY.SetListValue(),
|
||||
size.SetPairListValue(), composite.SetListValue(),
|
||||
maskMode.SetListValue());
|
||||
|
||||
|
@ -11928,7 +11943,9 @@ CSSParserImpl::ParseImageLayers(const nsCSSProperty aTable[])
|
|||
nsCSSValueList);
|
||||
APPENDNEXT(nsStyleImageLayers::origin, state.mOrigin,
|
||||
nsCSSValueList);
|
||||
APPENDNEXT(nsStyleImageLayers::position, state.mPosition,
|
||||
APPENDNEXT(nsStyleImageLayers::positionX, state.mPositionX,
|
||||
nsCSSValueList);
|
||||
APPENDNEXT(nsStyleImageLayers::positionY, state.mPositionY,
|
||||
nsCSSValueList);
|
||||
APPENDNEXT(nsStyleImageLayers::size, state.mSize,
|
||||
nsCSSValuePairList);
|
||||
|
@ -11957,7 +11974,8 @@ CSSParserImpl::ParseImageLayers(const nsCSSProperty aTable[])
|
|||
APPENDVALUE(aTable[nsStyleImageLayers::repeat], repeat);
|
||||
APPENDVALUE(aTable[nsStyleImageLayers::clip], clip);
|
||||
APPENDVALUE(aTable[nsStyleImageLayers::origin], origin);
|
||||
APPENDVALUE(aTable[nsStyleImageLayers::position], position);
|
||||
APPENDVALUE(aTable[nsStyleImageLayers::positionX], positionX);
|
||||
APPENDVALUE(aTable[nsStyleImageLayers::positionY], positionY);
|
||||
APPENDVALUE(aTable[nsStyleImageLayers::size], size);
|
||||
APPENDVALUE(aTable[nsStyleImageLayers::color], color);
|
||||
APPENDVALUE(aTable[nsStyleImageLayers::attachment], attachment);
|
||||
|
@ -12016,10 +12034,13 @@ CSSParserImpl::ParseImageLayersItem(
|
|||
eCSSUnit_Enumerated);
|
||||
aState.mOrigin->mValue.SetIntValue(NS_STYLE_IMAGELAYER_ORIGIN_PADDING,
|
||||
eCSSUnit_Enumerated);
|
||||
RefPtr<nsCSSValue::Array> positionArr = nsCSSValue::Array::Create(4);
|
||||
aState.mPosition->mValue.SetArrayValue(positionArr, eCSSUnit_Array);
|
||||
positionArr->Item(1).SetPercentValue(0.0f);
|
||||
positionArr->Item(3).SetPercentValue(0.0f);
|
||||
|
||||
RefPtr<nsCSSValue::Array> positionXArr = nsCSSValue::Array::Create(2);
|
||||
RefPtr<nsCSSValue::Array> positionYArr = nsCSSValue::Array::Create(2);
|
||||
aState.mPositionX->mValue.SetArrayValue(positionXArr, eCSSUnit_Array);
|
||||
aState.mPositionY->mValue.SetArrayValue(positionYArr, eCSSUnit_Array);
|
||||
positionXArr->Item(1).SetPercentValue(0.0f);
|
||||
positionYArr->Item(1).SetPercentValue(0.0f);
|
||||
aState.mSize->mXValue.SetAutoValue();
|
||||
aState.mSize->mYValue.SetAutoValue();
|
||||
aState.mComposite->mValue.SetIntValue(NS_STYLE_MASK_COMPOSITE_ADD,
|
||||
|
@ -12092,7 +12113,9 @@ CSSParserImpl::ParseImageLayersItem(
|
|||
if (havePositionAndSize)
|
||||
return false;
|
||||
havePositionAndSize = true;
|
||||
if (!ParsePositionValue(aState.mPosition->mValue)) {
|
||||
|
||||
if (!ParsePositionValueSeparateCoords(aState.mPositionX->mValue,
|
||||
aState.mPositionY->mValue)) {
|
||||
return false;
|
||||
}
|
||||
if (ExpectSymbol('/', true)) {
|
||||
|
@ -12204,7 +12227,8 @@ CSSParserImpl::ParseImageLayersItem(
|
|||
if (havePositionAndSize)
|
||||
return false;
|
||||
havePositionAndSize = true;
|
||||
if (!ParsePositionValue(aState.mPosition->mValue)) {
|
||||
if (!ParsePositionValueSeparateCoords(aState.mPositionX->mValue,
|
||||
aState.mPositionY->mValue)) {
|
||||
return false;
|
||||
}
|
||||
if (ExpectSymbol('/', true)) {
|
||||
|
@ -12313,16 +12337,54 @@ CSSParserImpl::ParseImageLayerRepeatValues(nsCSSValuePair& aValue)
|
|||
return false;
|
||||
}
|
||||
|
||||
// This function is very similar to ParseScrollSnapCoordinate,
|
||||
// ParseImageLayers, ParseImageLayerSize.
|
||||
bool
|
||||
CSSParserImpl::ParseImageLayerPosition(nsCSSProperty aPropID)
|
||||
CSSParserImpl::ParseImageLayerPosition(const nsCSSProperty aTable[])
|
||||
{
|
||||
// 'initial', 'inherit' and 'unset' stand alone, no list permitted.
|
||||
nsCSSValue position;
|
||||
if (ParseSingleTokenVariant(position, VARIANT_INHERIT, nullptr)) {
|
||||
AppendValue(aTable[nsStyleImageLayers::positionX], position);
|
||||
AppendValue(aTable[nsStyleImageLayers::positionY], position);
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCSSValue itemValueX;
|
||||
nsCSSValue itemValueY;
|
||||
if (!ParsePositionValueSeparateCoords(itemValueX, itemValueY)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCSSValue valueX;
|
||||
nsCSSValue valueY;
|
||||
nsCSSValueList* itemX = valueX.SetListValue();
|
||||
nsCSSValueList* itemY = valueY.SetListValue();
|
||||
for (;;) {
|
||||
itemX->mValue = itemValueX;
|
||||
itemY->mValue = itemValueY;
|
||||
if (!ExpectSymbol(',', true)) {
|
||||
break;
|
||||
}
|
||||
if (!ParsePositionValueSeparateCoords(itemValueX, itemValueY)) {
|
||||
return false;
|
||||
}
|
||||
itemX->mNext = new nsCSSValueList;
|
||||
itemY->mNext = new nsCSSValueList;
|
||||
itemX = itemX->mNext;
|
||||
itemY = itemY->mNext;
|
||||
}
|
||||
AppendValue(aTable[nsStyleImageLayers::positionX], valueX);
|
||||
AppendValue(aTable[nsStyleImageLayers::positionY], valueY);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseImageLayerPositionCoord(nsCSSProperty aPropID, bool aIsHorizontal)
|
||||
{
|
||||
nsCSSValue value;
|
||||
// 'initial', 'inherit' and 'unset' stand alone, no list permitted.
|
||||
if (!ParseSingleTokenVariant(value, VARIANT_INHERIT, nullptr)) {
|
||||
nsCSSValue itemValue;
|
||||
if (!ParsePositionValue(itemValue)) {
|
||||
if (!ParseImageLayerPositionCoordItem(itemValue, aIsHorizontal)) {
|
||||
return false;
|
||||
}
|
||||
nsCSSValueList* item = value.SetListValue();
|
||||
|
@ -12331,7 +12393,7 @@ CSSParserImpl::ParseImageLayerPosition(nsCSSProperty aPropID)
|
|||
if (!ExpectSymbol(',', true)) {
|
||||
break;
|
||||
}
|
||||
if (!ParsePositionValue(itemValue)) {
|
||||
if (!ParseImageLayerPositionCoordItem(itemValue, aIsHorizontal)) {
|
||||
return false;
|
||||
}
|
||||
item->mNext = new nsCSSValueList;
|
||||
|
@ -12631,6 +12693,80 @@ CSSParserImpl::ParsePositionValue(nsCSSValue& aOut)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParsePositionValueSeparateCoords(nsCSSValue& aOutX, nsCSSValue& aOutY)
|
||||
{
|
||||
nsCSSValue scratch;
|
||||
if (!ParsePositionValue(scratch)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Separate the four values into two pairs of two values for X and Y.
|
||||
RefPtr<nsCSSValue::Array> valueX = nsCSSValue::Array::Create(2);
|
||||
RefPtr<nsCSSValue::Array> valueY = nsCSSValue::Array::Create(2);
|
||||
aOutX.SetArrayValue(valueX, eCSSUnit_Array);
|
||||
aOutY.SetArrayValue(valueY, eCSSUnit_Array);
|
||||
|
||||
RefPtr<nsCSSValue::Array> value = scratch.GetArrayValue();
|
||||
valueX->Item(0) = value->Item(0);
|
||||
valueX->Item(1) = value->Item(1);
|
||||
valueY->Item(0) = value->Item(2);
|
||||
valueY->Item(1) = value->Item(3);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Parses one item in a list of values for the 'background-position-x' or
|
||||
// 'background-position-y' property. Does not support the start/end keywords.
|
||||
// Spec reference: https://drafts.csswg.org/css-backgrounds-4/#propdef-background-position-x
|
||||
bool
|
||||
CSSParserImpl::ParseImageLayerPositionCoordItem(nsCSSValue& aOut, bool aIsHorizontal)
|
||||
{
|
||||
RefPtr<nsCSSValue::Array> value = nsCSSValue::Array::Create(2);
|
||||
aOut.SetArrayValue(value, eCSSUnit_Array);
|
||||
|
||||
nsCSSValue &edge = value->Item(0),
|
||||
&offset = value->Item(1);
|
||||
|
||||
nsCSSValue edgeOrOffset;
|
||||
CSSParseResult result =
|
||||
ParseVariant(edgeOrOffset, VARIANT_LPCALC | VARIANT_KEYWORD,
|
||||
nsCSSProps::kImageLayerPositionKTable);
|
||||
if (result != CSSParseResult::Ok) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (edgeOrOffset.GetUnit() == eCSSUnit_Enumerated) {
|
||||
edge = edgeOrOffset;
|
||||
|
||||
// The edge can be followed by an optional offset.
|
||||
result = ParseVariant(offset, VARIANT_LPCALC, nullptr);
|
||||
if (result == CSSParseResult::Error) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
offset = edgeOrOffset;
|
||||
}
|
||||
|
||||
// Keywords for horizontal properties cannot be vertical keywords, and
|
||||
// keywords for vertical properties cannot be horizontal keywords.
|
||||
// Also, if an offset is specified, the edge cannot be center.
|
||||
int32_t edgeEnum =
|
||||
edge.GetUnit() == eCSSUnit_Enumerated ? edge.GetIntValue() : 0;
|
||||
int32_t allowedKeywords =
|
||||
(aIsHorizontal ? (BG_LEFT | BG_RIGHT) : (BG_TOP | BG_BOTTOM)) |
|
||||
(offset.GetUnit() == eCSSUnit_Null ? BG_CENTER : 0);
|
||||
if (edgeEnum & ~allowedKeywords) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_ASSERTION((eCSSUnit_Enumerated == edge.GetUnit() ||
|
||||
eCSSUnit_Null == edge.GetUnit()) &&
|
||||
eCSSUnit_Enumerated != offset.GetUnit(),
|
||||
"Unexpected units");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// This function is very similar to ParseScrollSnapCoordinate,
|
||||
// ParseImageLayers, and ParseImageLayerPosition.
|
||||
bool
|
||||
|
|
|
@ -383,6 +383,14 @@ CSS_PROP_ALIAS(-webkit-mask-position,
|
|||
mask_position,
|
||||
WebkitMaskPosition,
|
||||
WEBKIT_PREFIX_PREF)
|
||||
CSS_PROP_ALIAS(-webkit-mask-position-x,
|
||||
mask_position_x,
|
||||
WebkitMaskPositionX,
|
||||
WEBKIT_PREFIX_PREF)
|
||||
CSS_PROP_ALIAS(-webkit-mask-position-y,
|
||||
mask_position_y,
|
||||
WebkitMaskPositionY,
|
||||
WEBKIT_PREFIX_PREF)
|
||||
CSS_PROP_ALIAS(-webkit-mask-repeat,
|
||||
mask_repeat,
|
||||
WebkitMaskRepeat,
|
||||
|
|
|
@ -567,15 +567,35 @@ CSS_PROP_BACKGROUND(
|
|||
kImageLayerOriginKTable,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_BACKGROUND(
|
||||
CSS_PROP_SHORTHAND(
|
||||
background-position,
|
||||
background_position,
|
||||
BackgroundPosition,
|
||||
CSS_PROPERTY_PARSE_FUNCTION |
|
||||
CSS_PROPERTY_UNITLESS_LENGTH_QUIRK,
|
||||
"")
|
||||
CSS_PROP_BACKGROUND(
|
||||
background-position-x,
|
||||
background_position_x,
|
||||
BackgroundPositionX,
|
||||
CSS_PROPERTY_PARSE_FUNCTION |
|
||||
CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE |
|
||||
CSS_PROPERTY_APPLIES_TO_PLACEHOLDER |
|
||||
CSS_PROPERTY_VALUE_LIST_USES_COMMAS |
|
||||
CSS_PROPERTY_STORES_CALC,
|
||||
"",
|
||||
0,
|
||||
kImageLayerPositionKTable,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_Custom)
|
||||
CSS_PROP_BACKGROUND(
|
||||
background-position-y,
|
||||
background_position_y,
|
||||
BackgroundPositionY,
|
||||
CSS_PROPERTY_PARSE_FUNCTION |
|
||||
CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE |
|
||||
CSS_PROPERTY_APPLIES_TO_PLACEHOLDER |
|
||||
CSS_PROPERTY_VALUE_LIST_USES_COMMAS |
|
||||
CSS_PROPERTY_UNITLESS_LENGTH_QUIRK |
|
||||
CSS_PROPERTY_STORES_CALC,
|
||||
"",
|
||||
0,
|
||||
|
@ -2714,10 +2734,29 @@ CSS_PROP_SVGRESET(
|
|||
kImageLayerOriginKTable,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_SVGRESET(
|
||||
CSS_PROP_SHORTHAND(
|
||||
mask-position,
|
||||
mask_position,
|
||||
MaskPosition,
|
||||
CSS_PROPERTY_PARSE_FUNCTION |
|
||||
CSS_PROPERTY_UNITLESS_LENGTH_QUIRK,
|
||||
"")
|
||||
CSS_PROP_SVGRESET(
|
||||
mask-position-x,
|
||||
mask_position_x,
|
||||
MaskPositionX,
|
||||
CSS_PROPERTY_PARSE_FUNCTION |
|
||||
CSS_PROPERTY_VALUE_LIST_USES_COMMAS |
|
||||
CSS_PROPERTY_STORES_CALC,
|
||||
"",
|
||||
0,
|
||||
kImageLayerPositionKTable,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_Custom)
|
||||
CSS_PROP_SVGRESET(
|
||||
mask-position-y,
|
||||
mask_position_y,
|
||||
MaskPositionY,
|
||||
CSS_PROPERTY_PARSE_FUNCTION |
|
||||
CSS_PROPERTY_VALUE_LIST_USES_COMMAS |
|
||||
CSS_PROPERTY_STORES_CALC,
|
||||
|
|
|
@ -2625,13 +2625,20 @@ static const nsCSSProperty gBackgroundSubpropTable[] = {
|
|||
eCSSProperty_background_image,
|
||||
eCSSProperty_background_repeat,
|
||||
eCSSProperty_background_attachment,
|
||||
eCSSProperty_background_position,
|
||||
eCSSProperty_background_clip,
|
||||
eCSSProperty_background_origin,
|
||||
eCSSProperty_background_position_x,
|
||||
eCSSProperty_background_position_y,
|
||||
eCSSProperty_background_size,
|
||||
eCSSProperty_UNKNOWN
|
||||
};
|
||||
|
||||
static const nsCSSProperty gBackgroundPositionSubpropTable[] = {
|
||||
eCSSProperty_background_position_x,
|
||||
eCSSProperty_background_position_y,
|
||||
eCSSProperty_UNKNOWN
|
||||
};
|
||||
|
||||
static const nsCSSProperty gBorderSubpropTable[] = {
|
||||
eCSSProperty_border_top_width,
|
||||
eCSSProperty_border_right_width,
|
||||
|
@ -2965,7 +2972,8 @@ static const nsCSSProperty gScrollSnapTypeSubpropTable[] = {
|
|||
static const nsCSSProperty gMaskSubpropTable[] = {
|
||||
eCSSProperty_mask_image,
|
||||
eCSSProperty_mask_repeat,
|
||||
eCSSProperty_mask_position,
|
||||
eCSSProperty_mask_position_x,
|
||||
eCSSProperty_mask_position_y,
|
||||
eCSSProperty_mask_clip,
|
||||
eCSSProperty_mask_origin,
|
||||
eCSSProperty_mask_size,
|
||||
|
@ -2973,6 +2981,11 @@ static const nsCSSProperty gMaskSubpropTable[] = {
|
|||
eCSSProperty_mask_mode,
|
||||
eCSSProperty_UNKNOWN
|
||||
};
|
||||
static const nsCSSProperty gMaskPositionSubpropTable[] = {
|
||||
eCSSProperty_mask_position_x,
|
||||
eCSSProperty_mask_position_y,
|
||||
eCSSProperty_UNKNOWN
|
||||
};
|
||||
#endif
|
||||
// FIXME: mask-border tables should be added when we implement
|
||||
// mask-border properties.
|
||||
|
|
|
@ -934,7 +934,7 @@ nsCSSValue::AppendCircleOrEllipseToString(nsCSSKeyword aFunctionId,
|
|||
aResult.Append(' ');
|
||||
}
|
||||
aResult.AppendLiteral("at ");
|
||||
array->Item(count).AppendToString(eCSSProperty_background_position,
|
||||
array->Item(count).AppendToString(eCSSProperty_object_position,
|
||||
aResult, aSerialization);
|
||||
}
|
||||
|
||||
|
@ -1549,12 +1549,12 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult,
|
|||
aResult.AppendLiteral("to");
|
||||
if (!(gradient->mBgPos.mXValue.GetIntValue() & NS_STYLE_IMAGELAYER_POSITION_CENTER)) {
|
||||
aResult.Append(' ');
|
||||
gradient->mBgPos.mXValue.AppendToString(eCSSProperty_background_position,
|
||||
gradient->mBgPos.mXValue.AppendToString(eCSSProperty_background_position_x,
|
||||
aResult, aSerialization);
|
||||
}
|
||||
if (!(gradient->mBgPos.mYValue.GetIntValue() & NS_STYLE_IMAGELAYER_POSITION_CENTER)) {
|
||||
aResult.Append(' ');
|
||||
gradient->mBgPos.mYValue.AppendToString(eCSSProperty_background_position,
|
||||
gradient->mBgPos.mYValue.AppendToString(eCSSProperty_background_position_y,
|
||||
aResult, aSerialization);
|
||||
}
|
||||
needSep = true;
|
||||
|
@ -1572,12 +1572,12 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult,
|
|||
aResult.AppendLiteral("at ");
|
||||
}
|
||||
if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None) {
|
||||
gradient->mBgPos.mXValue.AppendToString(eCSSProperty_background_position,
|
||||
gradient->mBgPos.mXValue.AppendToString(eCSSProperty_background_position_x,
|
||||
aResult, aSerialization);
|
||||
aResult.Append(' ');
|
||||
}
|
||||
if (gradient->mBgPos.mYValue.GetUnit() != eCSSUnit_None) {
|
||||
gradient->mBgPos.mYValue.AppendToString(eCSSProperty_background_position,
|
||||
gradient->mBgPos.mYValue.AppendToString(eCSSProperty_background_position_y,
|
||||
aResult, aSerialization);
|
||||
aResult.Append(' ');
|
||||
}
|
||||
|
|
|
@ -2159,9 +2159,14 @@ nsComputedDOMStyle::DoGetImageLayerImage(const nsStyleImageLayers& aLayers)
|
|||
already_AddRefed<CSSValue>
|
||||
nsComputedDOMStyle::DoGetImageLayerPosition(const nsStyleImageLayers& aLayers)
|
||||
{
|
||||
RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
|
||||
if (aLayers.mPositionXCount != aLayers.mPositionYCount) {
|
||||
// No value to return. We can't express this combination of
|
||||
// values as a shorthand.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0, i_end = aLayers.mPositionCount; i < i_end; ++i) {
|
||||
RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
|
||||
for (uint32_t i = 0, i_end = aLayers.mPositionXCount; i < i_end; ++i) {
|
||||
RefPtr<nsDOMCSSValueList> itemList = GetROCSSValueList(false);
|
||||
|
||||
SetValueToPosition(aLayers.mLayers[i].mPosition, itemList);
|
||||
|
|
|
@ -6627,6 +6627,9 @@ ComputePositionValue(nsStyleContext* aStyleContext,
|
|||
"unexpected unit for CSS <position> value");
|
||||
|
||||
RefPtr<nsCSSValue::Array> positionArray = aValue.GetArrayValue();
|
||||
NS_ASSERTION(positionArray->Count() == 4,
|
||||
"unexpected number of values in CSS <position> value");
|
||||
|
||||
const nsCSSValue &xEdge = positionArray->Item(0);
|
||||
const nsCSSValue &xOffset = positionArray->Item(1);
|
||||
const nsCSSValue &yEdge = positionArray->Item(2);
|
||||
|
@ -6649,19 +6652,33 @@ ComputePositionValue(nsStyleContext* aStyleContext,
|
|||
aConditions);
|
||||
}
|
||||
|
||||
template <>
|
||||
struct BackgroundItemComputer<nsCSSValueList, nsStyleImageLayers::Position>
|
||||
/* Helper function to convert the -x or -y part of a CSS <position> specified
|
||||
* value into its computed-style form. */
|
||||
static void
|
||||
ComputePositionCoordValue(nsStyleContext* aStyleContext,
|
||||
const nsCSSValue& aValue,
|
||||
nsStyleImageLayers::Position::PositionCoord& aComputedValue,
|
||||
RuleNodeCacheConditions& aConditions)
|
||||
{
|
||||
static void ComputeValue(nsStyleContext* aStyleContext,
|
||||
const nsCSSValueList* aSpecifiedValue,
|
||||
nsStyleImageLayers::Position& aComputedValue,
|
||||
RuleNodeCacheConditions& aConditions)
|
||||
{
|
||||
ComputePositionValue(aStyleContext, aSpecifiedValue->mValue,
|
||||
aComputedValue, aConditions);
|
||||
}
|
||||
};
|
||||
NS_ASSERTION(aValue.GetUnit() == eCSSUnit_Array,
|
||||
"unexpected unit for position coord value");
|
||||
|
||||
RefPtr<nsCSSValue::Array> positionArray = aValue.GetArrayValue();
|
||||
NS_ASSERTION(positionArray->Count() == 2,
|
||||
"unexpected number of values, expecting one edge and one offset");
|
||||
|
||||
const nsCSSValue &edge = positionArray->Item(0);
|
||||
const nsCSSValue &offset = positionArray->Item(1);
|
||||
|
||||
NS_ASSERTION((eCSSUnit_Enumerated == edge.GetUnit() ||
|
||||
eCSSUnit_Null == edge.GetUnit()) &&
|
||||
eCSSUnit_Enumerated != offset.GetUnit(),
|
||||
"Invalid background position");
|
||||
|
||||
ComputePositionCoord(aStyleContext, edge, offset,
|
||||
&aComputedValue,
|
||||
aConditions);
|
||||
}
|
||||
|
||||
struct BackgroundSizeAxis {
|
||||
nsCSSValue nsCSSValuePairList::* specified;
|
||||
|
@ -6827,6 +6844,76 @@ SetImageLayerList(nsStyleContext* aStyleContext,
|
|||
aMaxItemCount = aItemCount;
|
||||
}
|
||||
|
||||
// The same as SetImageLayerList, but for values stored in
|
||||
// layer.mPosition.*aResultLocation instead of layer.*aResultLocation.
|
||||
// This code is duplicated because it would be annoying to make
|
||||
// SetImageLayerList generic enough to handle both cases.
|
||||
static void
|
||||
SetImageLayerPositionCoordList(
|
||||
nsStyleContext* aStyleContext,
|
||||
const nsCSSValue& aValue,
|
||||
nsStyleAutoArray<nsStyleImageLayers::Layer>& aLayers,
|
||||
const nsStyleAutoArray<nsStyleImageLayers::Layer>& aParentLayers,
|
||||
nsStyleImageLayers::Position::PositionCoord
|
||||
nsStyleImageLayers::Position::* aResultLocation,
|
||||
nsStyleImageLayers::Position::PositionCoord aInitialValue,
|
||||
uint32_t aParentItemCount,
|
||||
uint32_t& aItemCount,
|
||||
uint32_t& aMaxItemCount,
|
||||
bool& aRebuild,
|
||||
RuleNodeCacheConditions& aConditions)
|
||||
{
|
||||
switch (aValue.GetUnit()) {
|
||||
case eCSSUnit_Null:
|
||||
break;
|
||||
|
||||
case eCSSUnit_Inherit:
|
||||
aRebuild = true;
|
||||
aConditions.SetUncacheable();
|
||||
aLayers.EnsureLengthAtLeast(aParentItemCount);
|
||||
aItemCount = aParentItemCount;
|
||||
for (uint32_t i = 0; i < aParentItemCount; ++i) {
|
||||
aLayers[i].mPosition.*aResultLocation = aParentLayers[i].mPosition.*aResultLocation;
|
||||
}
|
||||
break;
|
||||
|
||||
case eCSSUnit_Initial:
|
||||
case eCSSUnit_Unset:
|
||||
aRebuild = true;
|
||||
aItemCount = 1;
|
||||
aLayers[0].mPosition.*aResultLocation = aInitialValue;
|
||||
break;
|
||||
|
||||
case eCSSUnit_List:
|
||||
case eCSSUnit_ListDep: {
|
||||
aRebuild = true;
|
||||
aItemCount = 0;
|
||||
const nsCSSValueList* item = aValue.GetListValue();
|
||||
do {
|
||||
NS_ASSERTION(item->mValue.GetUnit() != eCSSUnit_Null &&
|
||||
item->mValue.GetUnit() != eCSSUnit_Inherit &&
|
||||
item->mValue.GetUnit() != eCSSUnit_Initial &&
|
||||
item->mValue.GetUnit() != eCSSUnit_Unset,
|
||||
"unexpected unit");
|
||||
++aItemCount;
|
||||
aLayers.EnsureLengthAtLeast(aItemCount);
|
||||
|
||||
ComputePositionCoordValue(aStyleContext, item->mValue,
|
||||
aLayers[aItemCount-1].mPosition.*aResultLocation,
|
||||
aConditions);
|
||||
item = item->mNext;
|
||||
} while (item);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
MOZ_ASSERT(false, "unexpected unit");
|
||||
}
|
||||
|
||||
if (aItemCount > aMaxItemCount)
|
||||
aMaxItemCount = aItemCount;
|
||||
}
|
||||
|
||||
template <class ComputedValueItem>
|
||||
static void
|
||||
SetImageLayerPairList(nsStyleContext* aStyleContext,
|
||||
|
@ -6911,6 +6998,24 @@ FillBackgroundList(
|
|||
}
|
||||
}
|
||||
|
||||
// The same as FillBackgroundList, but for values stored in
|
||||
// layer.mPosition.*aResultLocation instead of layer.*aResultLocation.
|
||||
static void
|
||||
FillBackgroundPositionCoordList(
|
||||
nsStyleAutoArray<nsStyleImageLayers::Layer>& aLayers,
|
||||
nsStyleImageLayers::Position::PositionCoord
|
||||
nsStyleImageLayers::Position::* aResultLocation,
|
||||
uint32_t aItemCount, uint32_t aFillCount)
|
||||
{
|
||||
NS_PRECONDITION(aFillCount <= aLayers.Length(), "unexpected array length");
|
||||
for (uint32_t sourceLayer = 0, destLayer = aItemCount;
|
||||
destLayer < aFillCount;
|
||||
++sourceLayer, ++destLayer) {
|
||||
aLayers[destLayer].mPosition.*aResultLocation =
|
||||
aLayers[sourceLayer].mPosition.*aResultLocation;
|
||||
}
|
||||
}
|
||||
|
||||
const void*
|
||||
nsRuleNode::ComputeBackgroundData(void* aStartStruct,
|
||||
const nsRuleData* aRuleData,
|
||||
|
@ -6995,15 +7100,27 @@ nsRuleNode::ComputeBackgroundData(void* aStartStruct,
|
|||
bg->mImage.mOriginCount, maxItemCount, rebuild,
|
||||
conditions);
|
||||
|
||||
// background-position: enum, length, percent (flags), inherit [pair list]
|
||||
nsStyleImageLayers::Position initialPosition;
|
||||
initialPosition.SetInitialPercentValues(0.0f);
|
||||
SetImageLayerList(aContext, *aRuleData->ValueForBackgroundPosition(),
|
||||
// background-position-x/y: enum, length, percent (flags), inherit [list]
|
||||
nsStyleImageLayers::Position::PositionCoord initialPositionCoord;
|
||||
initialPositionCoord.mPercent = 0.0f;
|
||||
initialPositionCoord.mLength = 0;
|
||||
initialPositionCoord.mHasPercent = true;
|
||||
|
||||
SetImageLayerPositionCoordList(
|
||||
aContext, *aRuleData->ValueForBackgroundPositionX(),
|
||||
bg->mImage.mLayers,
|
||||
parentBG->mImage.mLayers,
|
||||
&nsStyleImageLayers::Layer::mPosition,
|
||||
initialPosition, parentBG->mImage.mPositionCount,
|
||||
bg->mImage.mPositionCount, maxItemCount, rebuild,
|
||||
&nsStyleImageLayers::Position::mXPosition,
|
||||
initialPositionCoord, parentBG->mImage.mPositionXCount,
|
||||
bg->mImage.mPositionXCount, maxItemCount, rebuild,
|
||||
conditions);
|
||||
SetImageLayerPositionCoordList(
|
||||
aContext, *aRuleData->ValueForBackgroundPositionY(),
|
||||
bg->mImage.mLayers,
|
||||
parentBG->mImage.mLayers,
|
||||
&nsStyleImageLayers::Position::mYPosition,
|
||||
initialPositionCoord, parentBG->mImage.mPositionYCount,
|
||||
bg->mImage.mPositionYCount, maxItemCount, rebuild,
|
||||
conditions);
|
||||
|
||||
// background-size: enum, length, auto, inherit, initial [pair list]
|
||||
|
@ -7041,9 +7158,12 @@ nsRuleNode::ComputeBackgroundData(void* aStartStruct,
|
|||
FillBackgroundList(bg->mImage.mLayers,
|
||||
&nsStyleImageLayers::Layer::mOrigin,
|
||||
bg->mImage.mOriginCount, fillCount);
|
||||
FillBackgroundList(bg->mImage.mLayers,
|
||||
&nsStyleImageLayers::Layer::mPosition,
|
||||
bg->mImage.mPositionCount, fillCount);
|
||||
FillBackgroundPositionCoordList(bg->mImage.mLayers,
|
||||
&nsStyleImageLayers::Position::mXPosition,
|
||||
bg->mImage.mPositionXCount, fillCount);
|
||||
FillBackgroundPositionCoordList(bg->mImage.mLayers,
|
||||
&nsStyleImageLayers::Position::mYPosition,
|
||||
bg->mImage.mPositionYCount, fillCount);
|
||||
FillBackgroundList(bg->mImage.mLayers,
|
||||
&nsStyleImageLayers::Layer::mSize,
|
||||
bg->mImage.mSizeCount, fillCount);
|
||||
|
@ -9792,15 +9912,27 @@ nsRuleNode::ComputeSVGResetData(void* aStartStruct,
|
|||
svgReset->mMask.mOriginCount, maxItemCount, rebuild,
|
||||
conditions);
|
||||
|
||||
// mask-position: enum, length, percent (flags), inherit [pair list]
|
||||
nsStyleImageLayers::Position initialPosition;
|
||||
initialPosition.SetInitialPercentValues(0.0f);
|
||||
SetImageLayerList(aContext, *aRuleData->ValueForMaskPosition(),
|
||||
// mask-position-x/y: enum, length, percent (flags), inherit [list]
|
||||
nsStyleImageLayers::Position::PositionCoord initialPositionCoord;
|
||||
initialPositionCoord.mPercent = 0.0f;
|
||||
initialPositionCoord.mLength = 0;
|
||||
initialPositionCoord.mHasPercent = true;
|
||||
|
||||
SetImageLayerPositionCoordList(
|
||||
aContext, *aRuleData->ValueForMaskPositionX(),
|
||||
svgReset->mMask.mLayers,
|
||||
parentSVGReset->mMask.mLayers,
|
||||
&nsStyleImageLayers::Layer::mPosition,
|
||||
initialPosition, parentSVGReset->mMask.mPositionCount,
|
||||
svgReset->mMask.mPositionCount, maxItemCount, rebuild,
|
||||
&nsStyleImageLayers::Position::mXPosition,
|
||||
initialPositionCoord, parentSVGReset->mMask.mPositionXCount,
|
||||
svgReset->mMask.mPositionXCount, maxItemCount, rebuild,
|
||||
conditions);
|
||||
SetImageLayerPositionCoordList(
|
||||
aContext, *aRuleData->ValueForMaskPositionY(),
|
||||
svgReset->mMask.mLayers,
|
||||
parentSVGReset->mMask.mLayers,
|
||||
&nsStyleImageLayers::Position::mYPosition,
|
||||
initialPositionCoord, parentSVGReset->mMask.mPositionYCount,
|
||||
svgReset->mMask.mPositionYCount, maxItemCount, rebuild,
|
||||
conditions);
|
||||
|
||||
// mask-size: enum, length, auto, inherit, initial [pair list]
|
||||
|
@ -9854,9 +9986,12 @@ nsRuleNode::ComputeSVGResetData(void* aStartStruct,
|
|||
FillBackgroundList(svgReset->mMask.mLayers,
|
||||
&nsStyleImageLayers::Layer::mOrigin,
|
||||
svgReset->mMask.mOriginCount, fillCount);
|
||||
FillBackgroundList(svgReset->mMask.mLayers,
|
||||
&nsStyleImageLayers::Layer::mPosition,
|
||||
svgReset->mMask.mPositionCount, fillCount);
|
||||
FillBackgroundPositionCoordList(svgReset->mMask.mLayers,
|
||||
&nsStyleImageLayers::Position::mXPosition,
|
||||
svgReset->mMask.mPositionXCount, fillCount);
|
||||
FillBackgroundPositionCoordList(svgReset->mMask.mLayers,
|
||||
&nsStyleImageLayers::Position::mYPosition,
|
||||
svgReset->mMask.mPositionYCount, fillCount);
|
||||
FillBackgroundList(svgReset->mMask.mLayers,
|
||||
&nsStyleImageLayers::Layer::mSize,
|
||||
svgReset->mMask.mSizeCount, fillCount);
|
||||
|
|
|
@ -2281,7 +2281,8 @@ const nsCSSProperty nsStyleImageLayers::kBackgroundLayerTable[] = {
|
|||
eCSSProperty_background_color, // color
|
||||
eCSSProperty_background_image, // image
|
||||
eCSSProperty_background_repeat, // repeat
|
||||
eCSSProperty_background_position, // position
|
||||
eCSSProperty_background_position_x, // positionX
|
||||
eCSSProperty_background_position_y, // positionY
|
||||
eCSSProperty_background_clip, // clip
|
||||
eCSSProperty_background_origin, // origin
|
||||
eCSSProperty_background_size, // size
|
||||
|
@ -2296,7 +2297,8 @@ const nsCSSProperty nsStyleImageLayers::kMaskLayerTable[] = {
|
|||
eCSSProperty_UNKNOWN, // color
|
||||
eCSSProperty_mask_image, // image
|
||||
eCSSProperty_mask_repeat, // repeat
|
||||
eCSSProperty_mask_position, // position
|
||||
eCSSProperty_mask_position_x, // positionX
|
||||
eCSSProperty_mask_position_y, // positionY
|
||||
eCSSProperty_mask_clip, // clip
|
||||
eCSSProperty_mask_origin, // origin
|
||||
eCSSProperty_mask_size, // size
|
||||
|
@ -2311,7 +2313,8 @@ nsStyleImageLayers::nsStyleImageLayers()
|
|||
, mClipCount(1)
|
||||
, mOriginCount(1)
|
||||
, mRepeatCount(1)
|
||||
, mPositionCount(1)
|
||||
, mPositionXCount(1)
|
||||
, mPositionYCount(1)
|
||||
, mImageCount(1)
|
||||
, mSizeCount(1)
|
||||
, mMaskModeCount(1)
|
||||
|
@ -2327,7 +2330,8 @@ nsStyleImageLayers::nsStyleImageLayers(const nsStyleImageLayers &aSource)
|
|||
, mClipCount(aSource.mClipCount)
|
||||
, mOriginCount(aSource.mOriginCount)
|
||||
, mRepeatCount(aSource.mRepeatCount)
|
||||
, mPositionCount(aSource.mPositionCount)
|
||||
, mPositionXCount(aSource.mPositionXCount)
|
||||
, mPositionYCount(aSource.mPositionYCount)
|
||||
, mImageCount(aSource.mImageCount)
|
||||
, mSizeCount(aSource.mSizeCount)
|
||||
, mMaskModeCount(aSource.mMaskModeCount)
|
||||
|
@ -2344,7 +2348,8 @@ nsStyleImageLayers::nsStyleImageLayers(const nsStyleImageLayers &aSource)
|
|||
mClipCount = std::max(mClipCount, count);
|
||||
mOriginCount = std::max(mOriginCount, count);
|
||||
mRepeatCount = std::max(mRepeatCount, count);
|
||||
mPositionCount = std::max(mPositionCount, count);
|
||||
mPositionXCount = std::max(mPositionXCount, count);
|
||||
mPositionYCount = std::max(mPositionYCount, count);
|
||||
mImageCount = std::max(mImageCount, count);
|
||||
mSizeCount = std::max(mSizeCount, count);
|
||||
mMaskModeCount = std::max(mMaskModeCount, count);
|
||||
|
@ -2394,7 +2399,8 @@ nsStyleImageLayers::CalcDifference(const nsStyleImageLayers& aOther) const
|
|||
mMaskModeCount != aOther.mMaskModeCount ||
|
||||
mOriginCount != aOther.mOriginCount ||
|
||||
mRepeatCount != aOther.mRepeatCount ||
|
||||
mPositionCount != aOther.mPositionCount ||
|
||||
mPositionXCount != aOther.mPositionXCount ||
|
||||
mPositionYCount != aOther.mPositionYCount ||
|
||||
mSizeCount != aOther.mSizeCount) {
|
||||
NS_UpdateHint(hint, nsChangeHint_NeutralChange);
|
||||
}
|
||||
|
|
|
@ -527,7 +527,8 @@ struct nsStyleImageLayers {
|
|||
color,
|
||||
image,
|
||||
repeat,
|
||||
position,
|
||||
positionX,
|
||||
positionY,
|
||||
clip,
|
||||
origin,
|
||||
size,
|
||||
|
@ -737,7 +738,8 @@ struct nsStyleImageLayers {
|
|||
mClipCount,
|
||||
mOriginCount,
|
||||
mRepeatCount,
|
||||
mPositionCount,
|
||||
mPositionXCount,
|
||||
mPositionYCount,
|
||||
mImageCount,
|
||||
mSizeCount,
|
||||
mMaskModeCount,
|
||||
|
|
|
@ -158,6 +158,43 @@ is(e.style.background, "", "should not have background shorthand (background-rep
|
|||
e.setAttribute("style", "background-clip: border-box, padding-box, border-box; background-origin: border-box, padding-box, padding-box; background-size: cover, auto, contain, contain; 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-size too long)");
|
||||
|
||||
// Check that we only serialize background-position when the lists (of layers) for
|
||||
// the -x/-y subproperties are the same length.
|
||||
e.setAttribute("style", "background-position-x: 10%, left 2em, right; background-position-y: top 2em, bottom, 10%");
|
||||
is(e.style.backgroundPosition, "left 10% top 2em, left 2em bottom, right 10%", "should have background-position shorthand (both lists length 3)");
|
||||
e.setAttribute("style", "background-position-x: 10%, left 2em; background-position-y: top 2em, bottom, 10%");
|
||||
is(e.style.backgroundPosition, "", "should not have background-position shorthand (background-position-x too short)");
|
||||
e.setAttribute("style", "background-position-x: 10%, left 2em, right; background-position-y: top 2em");
|
||||
is(e.style.backgroundPosition, "", "should not have background-position shorthand (background-position-y too short)");
|
||||
|
||||
// Check that background-position serialization doesn't produce invalid values.
|
||||
e.setAttribute("style", "background-position: 0px");
|
||||
is(e.style.backgroundPosition, "0px center", "1-value form should be accepted, with implied center value for background-position-y");
|
||||
e.setAttribute("style", "background-position: 0px center");
|
||||
is(e.style.backgroundPosition, "0px center", "2-value form 'x-offset' 'y-edge' should be accepted, and serialize to 2-value form");
|
||||
e.setAttribute("style", "background-position: left 0px center");
|
||||
is(e.style.backgroundPosition, "left 0px center", "3-value form 'x-edge' 'x-offset' 'y-edge' should be accepted and serialize to 3-value form");
|
||||
e.setAttribute("style", "background-position: left top 0px");
|
||||
is(e.style.backgroundPosition, "left top 0px", "3-value form 'x-edge' 'y-edge' 'y-offset' should be accepted and serialize to 3-value form");
|
||||
e.setAttribute("style", "background-position: left 0px top 0px");
|
||||
is(e.style.backgroundPosition, "left 0px top 0px", "4-value form should be accepted and serialize to 4-value form");
|
||||
e.setAttribute("style", "background-position-x: 0px; background-position-y: center");
|
||||
is(e.style.backgroundPosition, "0px center", "should always serialize to 2-value form if setting -x and -y with the 1-value form");
|
||||
e.setAttribute("style", "background-position-x: 0px; background-position-y: 0px");
|
||||
is(e.style.backgroundPosition, "0px 0px", "should always serialize to 2-value form if setting -x and -y with the 1-value form");
|
||||
e.setAttribute("style", "background-position-x: center; background-position-y: 0px");
|
||||
is(e.style.backgroundPosition, "center 0px", "should always serialize to 2-value form if setting -x and -y with the 1-value form");
|
||||
e.setAttribute("style", "background-position-x: left; background-position-y: top");
|
||||
is(e.style.backgroundPosition, "left top", "should always serialize to 2-value form if setting -x and -y with the 1-value form");
|
||||
e.setAttribute("style", "background-position-x: left 0px; background-position-y: center");
|
||||
is(e.style.backgroundPosition, "left 0px center", "should always serialize to 3-value form if both -x and -y specified an edge");
|
||||
e.setAttribute("style", "background-position-x: right; background-position-y: top 0px");
|
||||
is(e.style.backgroundPosition, "right top 0px", "should always serialize to 3-value form if both -x and -y specified an edge");
|
||||
e.setAttribute("style", "background-position-x: left 0px; background-position-y: 0px");
|
||||
is(e.style.backgroundPosition, "left 0px top 0px", "should serialize to 4-value form if 3-value form would only have one edge");
|
||||
e.setAttribute("style", "background-position-x: 0px; background-position-y: top 0px");
|
||||
is(e.style.backgroundPosition, "left 0px top 0px", "should serialize to 4-value form if 3-value form would only have one edge");
|
||||
|
||||
// Check that we only serialize transition when the lists are the same length.
|
||||
e.setAttribute("style", "transition-property: color, width; transition-duration: 1s, 200ms; transition-timing-function: ease-in, linear; transition-delay: 0s, 1s");
|
||||
isnot(e.style.transition, "", "should have transition shorthand (lists same length)");
|
||||
|
|
Загрузка…
Ссылка в новой задаче