mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-04 21:18:35 +00:00
Bug 1074522 - Implement ellipse()/circle() parsing and style computing. r=dbaron
This commit is contained in:
parent
63ad03e0f0
commit
62628a69a2
@ -106,6 +106,9 @@ PEColorSaturationEOF=saturation
|
||||
PEColorLightnessEOF=lightness
|
||||
PEColorOpacityEOF=opacity in color value
|
||||
PEExpectedNumber=Expected a number but found '%1$S'.
|
||||
PEPositionEOF=<position>
|
||||
PEExpectedPosition=Expected <position> but found '%1$S'.
|
||||
PEExpectedRadius=Expected radius but found '%1$S'.
|
||||
PEExpectedCloseParen=Expected ')' but found '%1$S'.
|
||||
PEDeclEndEOF=';' or '}' to end declaration
|
||||
PEParseDeclarationNoColon=Expected ':' but found '%1$S'.
|
||||
|
@ -965,6 +965,7 @@ protected:
|
||||
/* Functions for basic shapes */
|
||||
bool ParseBasicShape(nsCSSValue& aValue, bool* aConsumedTokens);
|
||||
bool ParsePolygonFunction(nsCSSValue& aValue);
|
||||
bool ParseCircleOrEllipseFunction(nsCSSKeyword, nsCSSValue& aValue);
|
||||
|
||||
/* Functions for transform Parsing */
|
||||
bool ParseSingleTransform(bool aIsPrefixed, nsCSSValue& aValue);
|
||||
@ -13843,6 +13844,63 @@ CSSParserImpl::ParsePolygonFunction(nsCSSValue& aValue)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseCircleOrEllipseFunction(nsCSSKeyword aKeyword,
|
||||
nsCSSValue& aValue)
|
||||
{
|
||||
nsCSSValue radiusX, radiusY, position;
|
||||
bool hasRadius = false, hasPosition = false;
|
||||
|
||||
int32_t mask = VARIANT_LPCALC | VARIANT_NONNEGATIVE_DIMENSION |
|
||||
VARIANT_KEYWORD;
|
||||
if (ParseVariant(radiusX, mask, nsCSSProps::kShapeRadiusKTable)) {
|
||||
if (aKeyword == eCSSKeyword_ellipse) {
|
||||
if (!ParseVariant(radiusY, mask, nsCSSProps::kShapeRadiusKTable)) {
|
||||
REPORT_UNEXPECTED_TOKEN(PEExpectedRadius);
|
||||
SkipUntil(')');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
hasRadius = true;
|
||||
}
|
||||
|
||||
if (!ExpectSymbol(')', true)) {
|
||||
if (!GetToken(true)) {
|
||||
REPORT_UNEXPECTED_EOF(PEPositionEOF);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mToken.mType != eCSSToken_Ident ||
|
||||
!mToken.mIdent.LowerCaseEqualsLiteral("at") ||
|
||||
!ParsePositionValue(position)) {
|
||||
REPORT_UNEXPECTED_TOKEN(PEExpectedPosition);
|
||||
SkipUntil(')');
|
||||
return false;
|
||||
}
|
||||
if (!ExpectSymbol(')', true)) {
|
||||
REPORT_UNEXPECTED_TOKEN(PEExpectedCloseParen);
|
||||
SkipUntil(')');
|
||||
return false;
|
||||
}
|
||||
hasPosition = true;
|
||||
}
|
||||
|
||||
size_t count = aKeyword == eCSSKeyword_circle ? 2 : 3;
|
||||
nsRefPtr<nsCSSValue::Array> functionArray =
|
||||
aValue.InitFunction(aKeyword, count);
|
||||
if (hasRadius) {
|
||||
functionArray->Item(1) = radiusX;
|
||||
if (aKeyword == eCSSKeyword_ellipse) {
|
||||
functionArray->Item(2) = radiusY;
|
||||
}
|
||||
}
|
||||
if (hasPosition) {
|
||||
functionArray->Item(count) = position;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseBasicShape(nsCSSValue& aValue, bool* aConsumedTokens)
|
||||
{
|
||||
@ -13861,6 +13919,9 @@ CSSParserImpl::ParseBasicShape(nsCSSValue& aValue, bool* aConsumedTokens)
|
||||
switch (keyword) {
|
||||
case eCSSKeyword_polygon:
|
||||
return ParsePolygonFunction(aValue);
|
||||
case eCSSKeyword_circle:
|
||||
case eCSSKeyword_ellipse:
|
||||
return ParseCircleOrEllipseFunction(keyword, aValue);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -1891,6 +1891,12 @@ const KTableValue nsCSSProps::kClipShapeSizingKTable[] = {
|
||||
eCSSKeyword_UNKNOWN,-1
|
||||
};
|
||||
|
||||
const KTableValue nsCSSProps::kShapeRadiusKTable[] = {
|
||||
eCSSKeyword_closest_side, NS_RADIUS_CLOSEST_SIDE,
|
||||
eCSSKeyword_farthest_side, NS_RADIUS_FARTHEST_SIDE,
|
||||
eCSSKeyword_UNKNOWN, -1
|
||||
};
|
||||
|
||||
const KTableValue nsCSSProps::kFilterFunctionKTable[] = {
|
||||
eCSSKeyword_blur, NS_STYLE_FILTER_BLUR,
|
||||
eCSSKeyword_brightness, NS_STYLE_FILTER_BRIGHTNESS,
|
||||
|
@ -537,6 +537,7 @@ public:
|
||||
static const KTableValue kBoxPackKTable[];
|
||||
static const KTableValue kClipShapeSizingKTable[];
|
||||
static const KTableValue kDominantBaselineKTable[];
|
||||
static const KTableValue kShapeRadiusKTable[];
|
||||
static const KTableValue kFillRuleKTable[];
|
||||
static const KTableValue kFilterFunctionKTable[];
|
||||
static const KTableValue kImageRenderingKTable[];
|
||||
|
@ -852,6 +852,56 @@ nsCSSValue::AppendPolygonToString(nsCSSProperty aProperty, nsAString& aResult,
|
||||
array->Item(index).AppendToString(aProperty, aResult, aSerialization);
|
||||
}
|
||||
|
||||
inline void
|
||||
nsCSSValue::AppendPositionCoordinateToString(
|
||||
const nsCSSValue& aValue, nsCSSProperty aProperty,
|
||||
nsAString& aResult, Serialization aSerialization) const
|
||||
{
|
||||
if (aValue.GetUnit() == eCSSUnit_Enumerated) {
|
||||
int32_t intValue = aValue.GetIntValue();
|
||||
AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
|
||||
nsCSSProps::kShapeRadiusKTable), aResult);
|
||||
} else {
|
||||
aValue.AppendToString(aProperty, aResult, aSerialization);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSValue::AppendCircleOrEllipseToString(nsCSSKeyword aFunctionId,
|
||||
nsCSSProperty aProperty,
|
||||
nsAString& aResult,
|
||||
Serialization aSerialization) const
|
||||
{
|
||||
const nsCSSValue::Array* array = GetArrayValue();
|
||||
size_t count = aFunctionId == eCSSKeyword_circle ? 2 : 3;
|
||||
NS_ABORT_IF_FALSE(array->Count() == count + 1, "wrong number of arguments");
|
||||
|
||||
bool hasRadii = array->Item(1).GetUnit() != eCSSUnit_Null;
|
||||
|
||||
AppendPositionCoordinateToString(array->Item(1), aProperty,
|
||||
aResult, aSerialization);
|
||||
|
||||
if (hasRadii && aFunctionId == eCSSKeyword_ellipse) {
|
||||
aResult.Append(' ');
|
||||
AppendPositionCoordinateToString(array->Item(2), aProperty,
|
||||
aResult, aSerialization);
|
||||
}
|
||||
|
||||
// Any position specified?
|
||||
if (array->Item(count).GetUnit() != eCSSUnit_Array) {
|
||||
NS_ABORT_IF_FALSE(array->Item(count).GetUnit() == eCSSUnit_Null,
|
||||
"unexpected value");
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasRadii) {
|
||||
aResult.Append(' ');
|
||||
}
|
||||
aResult.AppendLiteral("at ");
|
||||
array->Item(count).AppendToString(eCSSProperty_background_position,
|
||||
aResult, aSerialization);
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult,
|
||||
Serialization aSerialization) const
|
||||
@ -991,6 +1041,12 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult,
|
||||
AppendPolygonToString(aProperty, aResult, aSerialization);
|
||||
break;
|
||||
|
||||
case eCSSKeyword_circle:
|
||||
case eCSSKeyword_ellipse:
|
||||
AppendCircleOrEllipseToString(functionId, aProperty, aResult,
|
||||
aSerialization);
|
||||
break;
|
||||
|
||||
default: {
|
||||
// Now, step through the function contents, writing each of
|
||||
// them as we go.
|
||||
|
@ -721,7 +721,14 @@ private:
|
||||
|
||||
void AppendPolygonToString(nsCSSProperty aProperty, nsAString& aResult,
|
||||
Serialization aValueSerialization) const;
|
||||
|
||||
void AppendPositionCoordinateToString(const nsCSSValue& aValue,
|
||||
nsCSSProperty aProperty,
|
||||
nsAString& aResult,
|
||||
Serialization aSerialization) const;
|
||||
void AppendCircleOrEllipseToString(
|
||||
nsCSSKeyword aFunctionId,
|
||||
nsCSSProperty aProperty, nsAString& aResult,
|
||||
Serialization aValueSerialization) const;
|
||||
protected:
|
||||
nsCSSUnit mUnit;
|
||||
union {
|
||||
|
@ -5175,41 +5175,93 @@ nsComputedDOMStyle::DoGetStopColor()
|
||||
return val;
|
||||
}
|
||||
|
||||
inline void AppendBasicShapeTypeToString(nsStyleBasicShape::Type aType,
|
||||
nsAutoString& aString)
|
||||
{
|
||||
nsCSSKeyword functionName;
|
||||
switch (aType) {
|
||||
case nsStyleBasicShape::Type::ePolygon:
|
||||
functionName = eCSSKeyword_polygon;
|
||||
break;
|
||||
case nsStyleBasicShape::Type::eCircle:
|
||||
functionName = eCSSKeyword_circle;
|
||||
break;
|
||||
case nsStyleBasicShape::Type::eEllipse:
|
||||
functionName = eCSSKeyword_ellipse;
|
||||
break;
|
||||
default:
|
||||
NS_NOTREACHED("unexpected type");
|
||||
}
|
||||
AppendASCIItoUTF16(nsCSSKeywords::GetStringValue(functionName),
|
||||
aString);
|
||||
}
|
||||
|
||||
CSSValue*
|
||||
nsComputedDOMStyle::CreatePrimitiveValueForClipPath(
|
||||
const nsStyleBasicShape* aStyleBasicShape, uint8_t aSizingBox)
|
||||
{
|
||||
nsDOMCSSValueList* valueList = GetROCSSValueList(false);
|
||||
|
||||
if (aStyleBasicShape &&
|
||||
aStyleBasicShape->GetShapeType() == nsStyleBasicShape::Type::ePolygon) {
|
||||
if (aStyleBasicShape) {
|
||||
nsStyleBasicShape::Type type = aStyleBasicShape->GetShapeType();
|
||||
// Shape function name and opening parenthesis.
|
||||
nsAutoString shapeFunctionString;
|
||||
AppendASCIItoUTF16(nsCSSKeywords::GetStringValue(eCSSKeyword_polygon),
|
||||
shapeFunctionString);
|
||||
AppendBasicShapeTypeToString(type, shapeFunctionString);
|
||||
shapeFunctionString.Append('(');
|
||||
bool hasEvenOdd = aStyleBasicShape->GetFillRule() ==
|
||||
NS_STYLE_FILL_RULE_EVENODD;
|
||||
if (hasEvenOdd) {
|
||||
shapeFunctionString.AppendLiteral("evenodd");
|
||||
}
|
||||
for (size_t i = 0; i < aStyleBasicShape->Coordinates().Length(); i += 2) {
|
||||
nsAutoString coordString;
|
||||
if (i > 0 || hasEvenOdd) {
|
||||
shapeFunctionString.AppendLiteral(", ");
|
||||
switch (type) {
|
||||
case nsStyleBasicShape::Type::ePolygon: {
|
||||
bool hasEvenOdd = aStyleBasicShape->GetFillRule() ==
|
||||
NS_STYLE_FILL_RULE_EVENODD;
|
||||
if (hasEvenOdd) {
|
||||
shapeFunctionString.AppendLiteral("evenodd");
|
||||
}
|
||||
for (size_t i = 0;
|
||||
i < aStyleBasicShape->Coordinates().Length(); i += 2) {
|
||||
nsAutoString coordString;
|
||||
if (i > 0 || hasEvenOdd) {
|
||||
shapeFunctionString.AppendLiteral(", ");
|
||||
}
|
||||
SetCssTextToCoord(coordString,
|
||||
aStyleBasicShape->Coordinates()[i]);
|
||||
shapeFunctionString.Append(coordString);
|
||||
shapeFunctionString.Append(' ');
|
||||
SetCssTextToCoord(coordString,
|
||||
aStyleBasicShape->Coordinates()[i + 1]);
|
||||
shapeFunctionString.Append(coordString);
|
||||
}
|
||||
break;
|
||||
}
|
||||
SetCssTextToCoord(coordString,
|
||||
aStyleBasicShape->Coordinates()[i]);
|
||||
shapeFunctionString.Append(coordString);
|
||||
shapeFunctionString.Append(' ');
|
||||
SetCssTextToCoord(coordString,
|
||||
aStyleBasicShape->Coordinates()[i + 1]);
|
||||
shapeFunctionString.Append(coordString);
|
||||
case nsStyleBasicShape::Type::eCircle:
|
||||
case nsStyleBasicShape::Type::eEllipse: {
|
||||
const nsTArray<nsStyleCoord>& radii = aStyleBasicShape->Coordinates();
|
||||
NS_ABORT_IF_FALSE(radii.Length() ==
|
||||
(nsStyleBasicShape::Type::eCircle ? 1 : 2),
|
||||
"wrong number of radii");
|
||||
for (size_t i = 0; i < radii.Length(); ++i) {
|
||||
nsAutoString radius;
|
||||
nsRefPtr<nsROCSSPrimitiveValue> value = new nsROCSSPrimitiveValue;
|
||||
bool clampNegativeCalc = true;
|
||||
SetValueToCoord(value, radii[i], clampNegativeCalc, nullptr,
|
||||
nsCSSProps::kShapeRadiusKTable);
|
||||
value->GetCssText(radius);
|
||||
shapeFunctionString.Append(radius);
|
||||
shapeFunctionString.Append(' ');
|
||||
}
|
||||
shapeFunctionString.AppendLiteral("at ");
|
||||
|
||||
nsRefPtr<nsDOMCSSValueList> position = GetROCSSValueList(false);
|
||||
nsAutoString positionString;
|
||||
SetValueToPosition(aStyleBasicShape->GetPosition(), position);
|
||||
position->GetCssText(positionString);
|
||||
shapeFunctionString.Append(positionString);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
NS_NOTREACHED("unexpected type");
|
||||
}
|
||||
shapeFunctionString.Append(')');
|
||||
nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue;
|
||||
val->SetString(shapeFunctionString);
|
||||
valueList->AppendCSSValue(val);
|
||||
nsROCSSPrimitiveValue* functionValue = new nsROCSSPrimitiveValue;
|
||||
functionValue->SetString(shapeFunctionString);
|
||||
valueList->AppendCSSValue(functionValue);
|
||||
}
|
||||
|
||||
if (aSizingBox == NS_STYLE_CLIP_SHAPE_SIZING_NOBOX) {
|
||||
|
@ -8801,6 +8801,7 @@ nsRuleNode::SetStyleClipPathToCSSValue(nsStyleClipPath* aStyleClipPath,
|
||||
nsCSSKeyword functionName =
|
||||
(nsCSSKeyword)shapeFunction->Item(0).GetIntValue();
|
||||
if (functionName == eCSSKeyword_polygon) {
|
||||
NS_ABORT_IF_FALSE(!basicShape, "did not expect value");
|
||||
basicShape = new nsStyleBasicShape(nsStyleBasicShape::ePolygon);
|
||||
NS_ABORT_IF_FALSE(shapeFunction->Count() > 1,
|
||||
"polygon has wrong number of arguments");
|
||||
@ -8830,6 +8831,46 @@ nsRuleNode::SetStyleClipPathToCSSValue(nsStyleClipPath* aStyleClipPath,
|
||||
NS_ABORT_IF_FALSE(didSetCoordY, "unexpected y coordinate unit");
|
||||
curPair = curPair->mNext;
|
||||
}
|
||||
} else if (functionName == eCSSKeyword_circle ||
|
||||
functionName == eCSSKeyword_ellipse) {
|
||||
nsStyleBasicShape::Type type = functionName == eCSSKeyword_circle ?
|
||||
nsStyleBasicShape::eCircle :
|
||||
nsStyleBasicShape::eEllipse;
|
||||
NS_ABORT_IF_FALSE(!basicShape, "did not expect value");
|
||||
basicShape = new nsStyleBasicShape(type);
|
||||
int32_t mask = SETCOORD_PERCENT | SETCOORD_LENGTH |
|
||||
SETCOORD_STORE_CALC | SETCOORD_ENUMERATED;
|
||||
size_t count = type == nsStyleBasicShape::eCircle ? 2 : 3;
|
||||
NS_ABORT_IF_FALSE(shapeFunction->Count() == count + 1,
|
||||
"unexpected arguments count");
|
||||
NS_ABORT_IF_FALSE(type == nsStyleBasicShape::eCircle ||
|
||||
(shapeFunction->Item(1).GetUnit() == eCSSUnit_Null) ==
|
||||
(shapeFunction->Item(2).GetUnit() == eCSSUnit_Null),
|
||||
"ellipse should have two radii or none");
|
||||
for (size_t j = 1; j < count; ++j) {
|
||||
const nsCSSValue& val = shapeFunction->Item(j);
|
||||
nsStyleCoord radius;
|
||||
if (val.GetUnit() != eCSSUnit_Null) {
|
||||
DebugOnly<bool> didSetRadius = SetCoord(val, radius,
|
||||
nsStyleCoord(), mask,
|
||||
aStyleContext,
|
||||
aPresContext,
|
||||
aCanStoreInRuleTree);
|
||||
NS_ABORT_IF_FALSE(didSetRadius, "unexpected radius unit");
|
||||
} else {
|
||||
radius.SetIntValue(NS_RADIUS_CLOSEST_SIDE, eStyleUnit_Enumerated);
|
||||
}
|
||||
basicShape->Coordinates().AppendElement(radius);
|
||||
}
|
||||
const nsCSSValue& positionVal = shapeFunction->Item(count);
|
||||
if (positionVal.GetUnit() == eCSSUnit_Array) {
|
||||
ComputePositionValue(aStyleContext, positionVal,
|
||||
basicShape->GetPosition(),
|
||||
aCanStoreInRuleTree);
|
||||
} else {
|
||||
NS_ABORT_IF_FALSE(positionVal.GetUnit() == eCSSUnit_Null,
|
||||
"expected no value");
|
||||
}
|
||||
} else {
|
||||
// XXX Handle more basic shape functions later.
|
||||
NS_NOTREACHED("unexpected basic shape function");
|
||||
|
@ -77,8 +77,8 @@ static inline mozilla::css::Side operator++(mozilla::css::Side& side, int) {
|
||||
|
||||
// Basic Shapes
|
||||
#define NS_STYLE_BASIC_SHAPE_POLYGON 0
|
||||
//#define NS_STYLE_BASIC_SHAPE_CIRCLE 1
|
||||
//#define NS_STYLE_BASIC_SHAPE_ELLIPSE 2
|
||||
#define NS_STYLE_BASIC_SHAPE_CIRCLE 1
|
||||
#define NS_STYLE_BASIC_SHAPE_ELLIPSE 2
|
||||
//#define NS_STYLE_BASIC_SHAPE_INSET 3
|
||||
|
||||
// box-shadow
|
||||
@ -155,6 +155,9 @@ static inline mozilla::css::Side operator++(mozilla::css::Side& side, int) {
|
||||
#define NS_STYLE_ORIENT_VERTICAL 1
|
||||
#define NS_STYLE_ORIENT_AUTO 2
|
||||
|
||||
#define NS_RADIUS_FARTHEST_SIDE 0
|
||||
#define NS_RADIUS_CLOSEST_SIDE 1
|
||||
|
||||
// stack-sizing
|
||||
#define NS_STYLE_STACK_SIZING_IGNORE 0
|
||||
#define NS_STYLE_STACK_SIZING_STRETCH_TO_FIT 1
|
||||
|
@ -2831,14 +2831,15 @@ class nsStyleBasicShape MOZ_FINAL {
|
||||
public:
|
||||
enum Type {
|
||||
// eInset,
|
||||
// eCircle,
|
||||
// eEllipse,
|
||||
eCircle,
|
||||
eEllipse,
|
||||
ePolygon
|
||||
};
|
||||
|
||||
explicit nsStyleBasicShape(Type type)
|
||||
: mType(type)
|
||||
{
|
||||
mPosition.SetInitialPercentValues(0.5f);
|
||||
}
|
||||
|
||||
Type GetShapeType() const { return mType; }
|
||||
@ -2850,15 +2851,31 @@ public:
|
||||
mFillRule = aFillRule;
|
||||
}
|
||||
|
||||
typedef nsStyleBackground::Position Position;
|
||||
Position& GetPosition() {
|
||||
NS_ASSERTION(mType == eCircle || mType == eEllipse,
|
||||
"expected circle or ellipse");
|
||||
return mPosition;
|
||||
}
|
||||
const Position& GetPosition() const {
|
||||
NS_ASSERTION(mType == eCircle || mType == eEllipse,
|
||||
"expected circle or ellipse");
|
||||
return mPosition;
|
||||
}
|
||||
|
||||
// mCoordinates has coordinates for polygon or radii for
|
||||
// ellipse and circle.
|
||||
nsTArray<nsStyleCoord>& Coordinates()
|
||||
{
|
||||
NS_ASSERTION(mType == ePolygon, "expected polygon");
|
||||
NS_ASSERTION(mType == ePolygon || mType == eCircle || mType == eEllipse,
|
||||
"expected polygon, circle or ellipse");
|
||||
return mCoordinates;
|
||||
}
|
||||
|
||||
const nsTArray<nsStyleCoord>& Coordinates() const
|
||||
{
|
||||
NS_ASSERTION(mType == ePolygon, "expected polygon");
|
||||
NS_ASSERTION(mType == ePolygon || mType == eCircle || mType == eEllipse,
|
||||
"expected polygon, circle or ellipse");
|
||||
return mCoordinates;
|
||||
}
|
||||
|
||||
@ -2866,7 +2883,8 @@ public:
|
||||
{
|
||||
return mType == aOther.mType &&
|
||||
mFillRule == aOther.mFillRule &&
|
||||
mCoordinates == aOther.mCoordinates;
|
||||
mCoordinates == aOther.mCoordinates &&
|
||||
mPosition == aOther.mPosition;
|
||||
}
|
||||
bool operator!=(const nsStyleBasicShape& aOther) const {
|
||||
return !(*this == aOther);
|
||||
@ -2879,7 +2897,10 @@ private:
|
||||
|
||||
Type mType;
|
||||
int32_t mFillRule;
|
||||
// mCoordinates has coordinates for polygon or radii for
|
||||
// ellipse and circle.
|
||||
nsTArray<nsStyleCoord> mCoordinates;
|
||||
Position mPosition;
|
||||
};
|
||||
|
||||
struct nsStyleClipPath
|
||||
|
@ -4622,6 +4622,39 @@ if (SpecialPowers.getBoolPref("layout.css.clip-path-shapes.enabled")) {
|
||||
"polygon(evenodd, 20pt 20cm) fill-box",
|
||||
"polygon(evenodd, 20ex 20pc) stroke-box",
|
||||
"polygon(evenodd, 20rem 20in) view-box",
|
||||
|
||||
"circle()",
|
||||
"circle(at center)",
|
||||
"circle(at top left 20px)",
|
||||
"circle(at bottom right)",
|
||||
"circle(20%)",
|
||||
"circle(300px)",
|
||||
"circle(calc(20px + 30px))",
|
||||
"circle(farthest-side)",
|
||||
"circle(closest-side)",
|
||||
"circle(closest-side at center)",
|
||||
"circle(farthest-side at top)",
|
||||
"circle(20px at top right)",
|
||||
"circle(40% at 50% 100%)",
|
||||
"circle(calc(20% + 20%) at right bottom)",
|
||||
"circle() padding-box",
|
||||
|
||||
"ellipse()",
|
||||
"ellipse(at center)",
|
||||
"ellipse(at top left 20px)",
|
||||
"ellipse(at bottom right)",
|
||||
"ellipse(20% 20%)",
|
||||
"ellipse(300px 50%)",
|
||||
"ellipse(calc(20px + 30px) 10%)",
|
||||
"ellipse(farthest-side closest-side)",
|
||||
"ellipse(closest-side farthest-side)",
|
||||
"ellipse(farthest-side farthest-side)",
|
||||
"ellipse(closest-side closest-side)",
|
||||
"ellipse(closest-side closest-side at center)",
|
||||
"ellipse(20% farthest-side at top)",
|
||||
"ellipse(20px 50% at top right)",
|
||||
"ellipse(closest-side 40% at 50% 100%)",
|
||||
"ellipse(calc(20% + 20%) calc(20px + 20cm) at right bottom)",
|
||||
],
|
||||
invalid_values: [
|
||||
"url(#test) url(#tes2)",
|
||||
@ -4656,11 +4689,47 @@ if (SpecialPowers.getBoolPref("layout.css.clip-path-shapes.enabled")) {
|
||||
"margin-box farthest-side",
|
||||
"nonsense() border-box",
|
||||
"border-box nonsense()",
|
||||
|
||||
"circle(at)",
|
||||
"circle(at 20% 20% 30%)",
|
||||
"circle(20px 2px at center)",
|
||||
"circle(2at center)",
|
||||
"circle(closest-corner)",
|
||||
"circle(at center top closest-side)",
|
||||
"circle(-20px)",
|
||||
"circle(farthest-side closest-side)",
|
||||
"circle(20% 20%)",
|
||||
"circle(at farthest-side)",
|
||||
|
||||
"ellipse(at)",
|
||||
"ellipse(at 20% 20% 30%)",
|
||||
"ellipse(20px at center)",
|
||||
"ellipse(-20px 20px)",
|
||||
"ellipse(closest-corner farthest-corner)",
|
||||
"ellipse(20px -20px)",
|
||||
"ellipse(-20px -20px)",
|
||||
"ellipse(farthest-side)",
|
||||
"ellipse(20%)",
|
||||
"ellipse(at farthest-side farthest-side)",
|
||||
|
||||
"polygon(at)",
|
||||
"polygon(at 20% 20% 30%)",
|
||||
"polygon(20px at center)",
|
||||
"polygon(2px 2at center)",
|
||||
"polygon(closest-corner farthest-corner)",
|
||||
"polygon(at center top closest-side closest-side)",
|
||||
"polygon(40% at 50% 100%)",
|
||||
"polygon(40% farthest-side 20px at 50% 100%)",
|
||||
],
|
||||
unbalanced_values: [
|
||||
"polygon(30% 30%",
|
||||
"polygon(nonzero, 20% 20px",
|
||||
"polygon(evenodd, 20px 20px",
|
||||
|
||||
"circle(",
|
||||
"circle(40% at 50% 100%",
|
||||
"ellipse(",
|
||||
"ellipse(40% at 50% 100%",
|
||||
]
|
||||
};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user