OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/css/parser/CSSPropertyParser.h" | 5 #include "core/css/parser/CSSPropertyParser.h" |
6 | 6 |
7 #include "core/StylePropertyShorthand.h" | 7 #include "core/StylePropertyShorthand.h" |
| 8 #include "core/css/CSSBasicShapeValues.h" |
8 #include "core/css/CSSCalculationValue.h" | 9 #include "core/css/CSSCalculationValue.h" |
9 #include "core/css/CSSCounterValue.h" | 10 #include "core/css/CSSCounterValue.h" |
10 #include "core/css/CSSCrossfadeValue.h" | 11 #include "core/css/CSSCrossfadeValue.h" |
11 #include "core/css/CSSCursorImageValue.h" | 12 #include "core/css/CSSCursorImageValue.h" |
12 #include "core/css/CSSCustomIdentValue.h" | 13 #include "core/css/CSSCustomIdentValue.h" |
13 #include "core/css/CSSFontFaceSrcValue.h" | 14 #include "core/css/CSSFontFaceSrcValue.h" |
14 #include "core/css/CSSFontFeatureValue.h" | 15 #include "core/css/CSSFontFeatureValue.h" |
15 #include "core/css/CSSFunctionValue.h" | 16 #include "core/css/CSSFunctionValue.h" |
16 #include "core/css/CSSImageSetValue.h" | 17 #include "core/css/CSSImageSetValue.h" |
17 #include "core/css/CSSPathValue.h" | 18 #include "core/css/CSSPathValue.h" |
(...skipping 2716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2734 } else if (id == CSSValueWebkitLinearGradient) { | 2735 } else if (id == CSSValueWebkitLinearGradient) { |
2735 // FIXME: This should send a deprecation message. | 2736 // FIXME: This should send a deprecation message. |
2736 if (context.useCounter()) | 2737 if (context.useCounter()) |
2737 context.useCounter()->count(UseCounter::DeprecatedWebKitLinearGradie
nt); | 2738 context.useCounter()->count(UseCounter::DeprecatedWebKitLinearGradie
nt); |
2738 result = consumeLinearGradient(args, context.mode(), NonRepeating, CSSPr
efixedLinearGradient); | 2739 result = consumeLinearGradient(args, context.mode(), NonRepeating, CSSPr
efixedLinearGradient); |
2739 } else if (id == CSSValueWebkitRepeatingLinearGradient) { | 2740 } else if (id == CSSValueWebkitRepeatingLinearGradient) { |
2740 // FIXME: This should send a deprecation message. | 2741 // FIXME: This should send a deprecation message. |
2741 if (context.useCounter()) | 2742 if (context.useCounter()) |
2742 context.useCounter()->count(UseCounter::DeprecatedWebKitRepeatingLin
earGradient); | 2743 context.useCounter()->count(UseCounter::DeprecatedWebKitRepeatingLin
earGradient); |
2743 result = consumeLinearGradient(args, context.mode(), Repeating, CSSPrefi
xedLinearGradient); | 2744 result = consumeLinearGradient(args, context.mode(), Repeating, CSSPrefi
xedLinearGradient); |
| 2745 } else if (id == CSSValueRepeatingLinearGradient) { |
| 2746 result = consumeLinearGradient(args, context.mode(), Repeating, CSSLinea
rGradient); |
2744 } else if (id == CSSValueLinearGradient) { | 2747 } else if (id == CSSValueLinearGradient) { |
2745 result = consumeLinearGradient(args, context.mode(), NonRepeating, CSSLi
nearGradient); | 2748 result = consumeLinearGradient(args, context.mode(), NonRepeating, CSSLi
nearGradient); |
2746 } else if (id == CSSValueWebkitGradient) { | 2749 } else if (id == CSSValueWebkitGradient) { |
2747 // FIXME: This should send a deprecation message. | 2750 // FIXME: This should send a deprecation message. |
2748 if (context.useCounter()) | 2751 if (context.useCounter()) |
2749 context.useCounter()->count(UseCounter::DeprecatedWebKitGradient); | 2752 context.useCounter()->count(UseCounter::DeprecatedWebKitGradient); |
2750 result = consumeDeprecatedGradient(args, context.mode()); | 2753 result = consumeDeprecatedGradient(args, context.mode()); |
2751 } else if (id == CSSValueWebkitRadialGradient) { | 2754 } else if (id == CSSValueWebkitRadialGradient) { |
2752 // FIXME: This should send a deprecation message. | 2755 // FIXME: This should send a deprecation message. |
2753 if (context.useCounter()) | 2756 if (context.useCounter()) |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2927 } | 2930 } |
2928 | 2931 |
2929 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumeVerticalAlign(CSSParserT
okenRange& range, CSSParserMode cssParserMode) | 2932 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumeVerticalAlign(CSSParserT
okenRange& range, CSSParserMode cssParserMode) |
2930 { | 2933 { |
2931 RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue = consumeIdentRange(range,
CSSValueBaseline, CSSValueWebkitBaselineMiddle); | 2934 RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue = consumeIdentRange(range,
CSSValueBaseline, CSSValueWebkitBaselineMiddle); |
2932 if (!parsedValue) | 2935 if (!parsedValue) |
2933 parsedValue = consumeLengthOrPercent(range, cssParserMode, ValueRangeAll
, UnitlessQuirk::Allow); | 2936 parsedValue = consumeLengthOrPercent(range, cssParserMode, ValueRangeAll
, UnitlessQuirk::Allow); |
2934 return parsedValue.release(); | 2937 return parsedValue.release(); |
2935 } | 2938 } |
2936 | 2939 |
| 2940 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumeShapeRadius(CSSParserTok
enRange& args, CSSParserMode cssParserMode) |
| 2941 { |
| 2942 if (identMatches<CSSValueClosestSide, CSSValueFarthestSide>(args.peek().id()
)) |
| 2943 return consumeIdent(args); |
| 2944 return consumeLengthOrPercent(args, cssParserMode, ValueRangeNonNegative); |
| 2945 } |
| 2946 |
| 2947 static PassRefPtrWillBeRawPtr<CSSBasicShapeCircleValue> consumeBasicShapeCircle(
CSSParserTokenRange& args, const CSSParserContext& context) |
| 2948 { |
| 2949 // spec: https://drafts.csswg.org/css-shapes/#supported-basic-shapes |
| 2950 // circle( [<shape-radius>]? [at <position>]? ) |
| 2951 RefPtrWillBeRawPtr<CSSBasicShapeCircleValue> shape = CSSBasicShapeCircleValu
e::create(); |
| 2952 if (RefPtrWillBeRawPtr<CSSPrimitiveValue> radius = consumeShapeRadius(args,
context.mode())) |
| 2953 shape->setRadius(radius.release()); |
| 2954 if (consumeIdent<CSSValueAt>(args)) { |
| 2955 RefPtrWillBeRawPtr<CSSValue> centerX = nullptr; |
| 2956 RefPtrWillBeRawPtr<CSSValue> centerY = nullptr; |
| 2957 if (!consumePosition(args, context.mode(), UnitlessQuirk::Forbid, center
X, centerY)) |
| 2958 return nullptr; |
| 2959 shape->setCenterX(centerX); |
| 2960 shape->setCenterY(centerY); |
| 2961 } |
| 2962 return shape.release(); |
| 2963 } |
| 2964 |
| 2965 static PassRefPtrWillBeRawPtr<CSSBasicShapeEllipseValue> consumeBasicShapeEllips
e(CSSParserTokenRange& args, const CSSParserContext& context) |
| 2966 { |
| 2967 // spec: https://drafts.csswg.org/css-shapes/#supported-basic-shapes |
| 2968 // ellipse( [<shape-radius>{2}]? [at <position>]? ) |
| 2969 RefPtrWillBeRawPtr<CSSBasicShapeEllipseValue> shape = CSSBasicShapeEllipseVa
lue::create(); |
| 2970 if (RefPtrWillBeRawPtr<CSSPrimitiveValue> radiusX = consumeShapeRadius(args,
context.mode())) { |
| 2971 shape->setRadiusX(radiusX); |
| 2972 if (RefPtrWillBeRawPtr<CSSPrimitiveValue> radiusY = consumeShapeRadius(a
rgs, context.mode())) |
| 2973 shape->setRadiusY(radiusY); |
| 2974 } |
| 2975 if (consumeIdent<CSSValueAt>(args)) { |
| 2976 RefPtrWillBeRawPtr<CSSValue> centerX = nullptr; |
| 2977 RefPtrWillBeRawPtr<CSSValue> centerY = nullptr; |
| 2978 if (!consumePosition(args, context.mode(), UnitlessQuirk::Forbid, center
X, centerY)) |
| 2979 return nullptr; |
| 2980 shape->setCenterX(centerX); |
| 2981 shape->setCenterY(centerY); |
| 2982 } |
| 2983 return shape.release(); |
| 2984 } |
| 2985 |
| 2986 static PassRefPtrWillBeRawPtr<CSSBasicShapePolygonValue> consumeBasicShapePolygo
n(CSSParserTokenRange& args, const CSSParserContext& context) |
| 2987 { |
| 2988 RefPtrWillBeRawPtr<CSSBasicShapePolygonValue> shape = CSSBasicShapePolygonVa
lue::create(); |
| 2989 if (identMatches<CSSValueEvenodd, CSSValueNonzero>(args.peek().id())) { |
| 2990 shape->setWindRule(args.consumeIncludingWhitespace().id() == CSSValueEve
nodd ? RULE_EVENODD : RULE_NONZERO); |
| 2991 if (!consumeCommaIncludingWhitespace(args)) |
| 2992 return nullptr; |
| 2993 } |
| 2994 |
| 2995 do { |
| 2996 RefPtrWillBeRawPtr<CSSPrimitiveValue> xLength = consumeLengthOrPercent(a
rgs, context.mode(), ValueRangeAll); |
| 2997 if (!xLength) |
| 2998 return nullptr; |
| 2999 RefPtrWillBeRawPtr<CSSPrimitiveValue> yLength = consumeLengthOrPercent(a
rgs, context.mode(), ValueRangeAll); |
| 3000 if (!yLength) |
| 3001 return nullptr; |
| 3002 shape->appendPoint(xLength.release(), yLength.release()); |
| 3003 } while (consumeCommaIncludingWhitespace(args)); |
| 3004 return shape.release(); |
| 3005 } |
| 3006 |
| 3007 static void completeBorderRadii(RefPtrWillBeRawPtr<CSSPrimitiveValue> radii[4]) |
| 3008 { |
| 3009 if (radii[3]) |
| 3010 return; |
| 3011 if (!radii[2]) { |
| 3012 if (!radii[1]) |
| 3013 radii[1] = radii[0]; |
| 3014 radii[2] = radii[0]; |
| 3015 } |
| 3016 radii[3] = radii[1]; |
| 3017 } |
| 3018 |
| 3019 static bool consumeRadii(RefPtrWillBeRawPtr<CSSPrimitiveValue> horizontalRadii[4
], RefPtrWillBeRawPtr<CSSPrimitiveValue> verticalRadii[4], CSSParserTokenRange&
range, CSSParserMode cssParserMode, bool useLegacyParsing) |
| 3020 { |
| 3021 #if ENABLE(OILPAN) |
| 3022 // Unconditionally zero initialize the arrays of raw pointers. |
| 3023 memset(horizontalRadii, 0, 4 * sizeof(horizontalRadii[0])); |
| 3024 memset(verticalRadii, 0, 4 * sizeof(verticalRadii[0])); |
| 3025 #endif |
| 3026 unsigned i = 0; |
| 3027 for (; i < 4 && !range.atEnd() && range.peek().type() != DelimiterToken; ++i
) { |
| 3028 horizontalRadii[i] = consumeLengthOrPercent(range, cssParserMode, ValueR
angeNonNegative); |
| 3029 if (!horizontalRadii[i]) |
| 3030 return false; |
| 3031 } |
| 3032 if (!horizontalRadii[0]) |
| 3033 return false; |
| 3034 if (range.atEnd()) { |
| 3035 // Legacy syntax: -webkit-border-radius: l1 l2; is equivalent to border-
radius: l1 / l2; |
| 3036 if (useLegacyParsing && i == 2) { |
| 3037 verticalRadii[0] = horizontalRadii[1]; |
| 3038 horizontalRadii[1] = nullptr; |
| 3039 } else { |
| 3040 completeBorderRadii(horizontalRadii); |
| 3041 for (unsigned i = 0; i < 4; ++i) |
| 3042 verticalRadii[i] = horizontalRadii[i]; |
| 3043 return true; |
| 3044 } |
| 3045 } else { |
| 3046 if (range.peek().type() != DelimiterToken || range.peek().delimiter() !=
'/') |
| 3047 return false; |
| 3048 range.consumeIncludingWhitespace(); |
| 3049 for (i = 0; i < 4 && !range.atEnd(); ++i) { |
| 3050 verticalRadii[i] = consumeLengthOrPercent(range, cssParserMode, Valu
eRangeNonNegative); |
| 3051 if (!verticalRadii[i]) |
| 3052 return false; |
| 3053 } |
| 3054 if (!verticalRadii[0] || !range.atEnd()) |
| 3055 return false; |
| 3056 } |
| 3057 completeBorderRadii(horizontalRadii); |
| 3058 completeBorderRadii(verticalRadii); |
| 3059 return true; |
| 3060 } |
| 3061 |
| 3062 static PassRefPtrWillBeRawPtr<CSSBasicShapeInsetValue> consumeBasicShapeInset(CS
SParserTokenRange& args, const CSSParserContext& context) |
| 3063 { |
| 3064 RefPtrWillBeRawPtr<CSSBasicShapeInsetValue> shape = CSSBasicShapeInsetValue:
:create(); |
| 3065 RefPtrWillBeRawPtr<CSSPrimitiveValue> top = consumeLengthOrPercent(args, con
text.mode(), ValueRangeAll); |
| 3066 if (!top) |
| 3067 return nullptr; |
| 3068 RefPtrWillBeRawPtr<CSSPrimitiveValue> right = nullptr; |
| 3069 RefPtrWillBeRawPtr<CSSPrimitiveValue> bottom = nullptr; |
| 3070 RefPtrWillBeRawPtr<CSSPrimitiveValue> left = nullptr; |
| 3071 if ((right = consumeLengthOrPercent(args, context.mode(), ValueRangeAll))) { |
| 3072 if ((bottom = consumeLengthOrPercent(args, context.mode(), ValueRangeAll
))) |
| 3073 left = consumeLengthOrPercent(args, context.mode(), ValueRangeAll); |
| 3074 } |
| 3075 if (left) |
| 3076 shape->updateShapeSize4Values(top.get(), right.get(), bottom.get(), left
.get()); |
| 3077 else if (bottom) |
| 3078 shape->updateShapeSize3Values(top.get(), right.get(), bottom.get()); |
| 3079 else if (right) |
| 3080 shape->updateShapeSize2Values(top.get(), right.get()); |
| 3081 else |
| 3082 shape->updateShapeSize1Value(top.get()); |
| 3083 |
| 3084 if (consumeIdent<CSSValueRound>(args)) { |
| 3085 RefPtrWillBeRawPtr<CSSPrimitiveValue> horizontalRadii[4]; |
| 3086 RefPtrWillBeRawPtr<CSSPrimitiveValue> verticalRadii[4]; |
| 3087 if (!consumeRadii(horizontalRadii, verticalRadii, args, context.mode(),
false)) |
| 3088 return nullptr; |
| 3089 shape->setTopLeftRadius(CSSValuePair::create(horizontalRadii[0].release(
), verticalRadii[0].release(), CSSValuePair::DropIdenticalValues)); |
| 3090 shape->setTopRightRadius(CSSValuePair::create(horizontalRadii[1].release
(), verticalRadii[1].release(), CSSValuePair::DropIdenticalValues)); |
| 3091 shape->setBottomRightRadius(CSSValuePair::create(horizontalRadii[2].rele
ase(), verticalRadii[2].release(), CSSValuePair::DropIdenticalValues)); |
| 3092 shape->setBottomLeftRadius(CSSValuePair::create(horizontalRadii[3].relea
se(), verticalRadii[3].release(), CSSValuePair::DropIdenticalValues)); |
| 3093 } |
| 3094 return shape.release(); |
| 3095 } |
| 3096 |
| 3097 static PassRefPtrWillBeRawPtr<CSSValue> consumeBasicShape(CSSParserTokenRange& r
ange, const CSSParserContext& context) |
| 3098 { |
| 3099 RefPtrWillBeRawPtr<CSSValue> shape = nullptr; |
| 3100 if (range.peek().type() != FunctionToken) |
| 3101 return nullptr; |
| 3102 CSSValueID id = range.peek().functionId(); |
| 3103 CSSParserTokenRange rangeCopy = range; |
| 3104 CSSParserTokenRange args = consumeFunction(rangeCopy); |
| 3105 if (id == CSSValueCircle) |
| 3106 shape = consumeBasicShapeCircle(args, context); |
| 3107 else if (id == CSSValueEllipse) |
| 3108 shape = consumeBasicShapeEllipse(args, context); |
| 3109 else if (id == CSSValuePolygon) |
| 3110 shape = consumeBasicShapePolygon(args, context); |
| 3111 else if (id == CSSValueInset) |
| 3112 shape = consumeBasicShapeInset(args, context); |
| 3113 if (!shape || !args.atEnd()) |
| 3114 return nullptr; |
| 3115 range = rangeCopy; |
| 3116 return shape.release(); |
| 3117 } |
| 3118 |
| 3119 static PassRefPtrWillBeRawPtr<CSSValue> consumeClipPath(CSSParserTokenRange& ran
ge, const CSSParserContext& context) |
| 3120 { |
| 3121 if (range.peek().id() == CSSValueNone) |
| 3122 return consumeIdent(range); |
| 3123 String url = consumeUrl(range); |
| 3124 if (!url.isNull()) |
| 3125 return CSSURIValue::create(url); |
| 3126 return consumeBasicShape(range, context); |
| 3127 } |
| 3128 |
| 3129 static PassRefPtrWillBeRawPtr<CSSValue> consumeShapeOutside(CSSParserTokenRange&
range, const CSSParserContext& context) |
| 3130 { |
| 3131 if (range.peek().id() == CSSValueNone) |
| 3132 return consumeIdent(range); |
| 3133 if (RefPtrWillBeRawPtr<CSSValue> imageValue = consumeImage(range, context)) |
| 3134 return imageValue.release(); |
| 3135 RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated()
; |
| 3136 if (RefPtrWillBeRawPtr<CSSValue> boxValue = consumeIdent<CSSValueContentBox,
CSSValuePaddingBox, CSSValueBorderBox, CSSValueMarginBox>(range)) |
| 3137 list->append(boxValue.release()); |
| 3138 if (RefPtrWillBeRawPtr<CSSValue> shapeValue = consumeBasicShape(range, conte
xt)) { |
| 3139 list->append(shapeValue.release()); |
| 3140 if (list->length() < 2) { |
| 3141 if (RefPtrWillBeRawPtr<CSSValue> boxValue = consumeIdent<CSSValueCon
tentBox, CSSValuePaddingBox, CSSValueBorderBox, CSSValueMarginBox>(range)) |
| 3142 list->append(boxValue.release()); |
| 3143 } |
| 3144 } |
| 3145 if (!list->length()) |
| 3146 return nullptr; |
| 3147 return list.release(); |
| 3148 } |
| 3149 |
2937 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty
ID unresolvedProperty) | 3150 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty
ID unresolvedProperty) |
2938 { | 3151 { |
2939 CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty); | 3152 CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty); |
2940 if (CSSParserFastPaths::isKeywordPropertyID(property)) { | 3153 if (CSSParserFastPaths::isKeywordPropertyID(property)) { |
2941 if (!CSSParserFastPaths::isValidKeywordPropertyAndValue(property, m_rang
e.peek().id())) | 3154 if (!CSSParserFastPaths::isValidKeywordPropertyAndValue(property, m_rang
e.peek().id())) |
2942 return nullptr; | 3155 return nullptr; |
2943 return consumeIdent(m_range); | 3156 return consumeIdent(m_range); |
2944 } | 3157 } |
2945 switch (property) { | 3158 switch (property) { |
2946 case CSSPropertyWillChange: | 3159 case CSSPropertyWillChange: |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3223 case CSSPropertyWebkitBoxFlexGroup: | 3436 case CSSPropertyWebkitBoxFlexGroup: |
3224 return consumeInteger(m_range, 0); | 3437 return consumeInteger(m_range, 0); |
3225 case CSSPropertyOrder: | 3438 case CSSPropertyOrder: |
3226 return consumeInteger(m_range); | 3439 return consumeInteger(m_range); |
3227 case CSSPropertyTextUnderlinePosition: | 3440 case CSSPropertyTextUnderlinePosition: |
3228 // auto | [ under || [ left | right ] ], but we only support auto | unde
r for now | 3441 // auto | [ under || [ left | right ] ], but we only support auto | unde
r for now |
3229 ASSERT(RuntimeEnabledFeatures::css3TextDecorationsEnabled()); | 3442 ASSERT(RuntimeEnabledFeatures::css3TextDecorationsEnabled()); |
3230 return consumeIdent<CSSValueAuto, CSSValueUnder>(m_range); | 3443 return consumeIdent<CSSValueAuto, CSSValueUnder>(m_range); |
3231 case CSSPropertyVerticalAlign: | 3444 case CSSPropertyVerticalAlign: |
3232 return consumeVerticalAlign(m_range, m_context.mode()); | 3445 return consumeVerticalAlign(m_range, m_context.mode()); |
| 3446 case CSSPropertyShapeOutside: |
| 3447 return consumeShapeOutside(m_range, m_context); |
| 3448 case CSSPropertyWebkitClipPath: |
| 3449 return consumeClipPath(m_range, m_context); |
3233 default: | 3450 default: |
3234 CSSParserValueList valueList(m_range); | 3451 CSSParserValueList valueList(m_range); |
3235 if (valueList.size()) { | 3452 if (valueList.size()) { |
3236 m_valueList = &valueList; | 3453 m_valueList = &valueList; |
3237 if (RefPtrWillBeRawPtr<CSSValue> result = legacyParseValue(unresolve
dProperty)) { | 3454 if (RefPtrWillBeRawPtr<CSSValue> result = legacyParseValue(unresolve
dProperty)) { |
3238 while (!m_range.atEnd()) | 3455 while (!m_range.atEnd()) |
3239 m_range.consume(); | 3456 m_range.consume(); |
3240 return result.release(); | 3457 return result.release(); |
3241 } | 3458 } |
3242 } | 3459 } |
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3741 left = right; | 3958 left = right; |
3742 | 3959 |
3743 addProperty(longhands[0], top.release(), important); | 3960 addProperty(longhands[0], top.release(), important); |
3744 addProperty(longhands[1], right.release(), important); | 3961 addProperty(longhands[1], right.release(), important); |
3745 addProperty(longhands[2], bottom.release(), important); | 3962 addProperty(longhands[2], bottom.release(), important); |
3746 addProperty(longhands[3], left.release(), important); | 3963 addProperty(longhands[3], left.release(), important); |
3747 | 3964 |
3748 return m_range.atEnd(); | 3965 return m_range.atEnd(); |
3749 } | 3966 } |
3750 | 3967 |
3751 static bool consumeRadii(RefPtrWillBeRawPtr<CSSPrimitiveValue> horizontalRadii[4
], RefPtrWillBeRawPtr<CSSPrimitiveValue> verticalRadii[4], CSSParserTokenRange&
range, CSSParserMode cssParserMode, bool useLegacyParsing) | |
3752 { | |
3753 #if ENABLE(OILPAN) | |
3754 // Unconditionally zero initialize the arrays of raw pointers. | |
3755 memset(horizontalRadii, 0, 4 * sizeof(horizontalRadii[0])); | |
3756 memset(verticalRadii, 0, 4 * sizeof(verticalRadii[0])); | |
3757 #endif | |
3758 unsigned i = 0; | |
3759 for (; i < 4 && !range.atEnd() && range.peek().type() != DelimiterToken; ++i
) { | |
3760 horizontalRadii[i] = consumeLengthOrPercent(range, cssParserMode, ValueR
angeNonNegative); | |
3761 if (!horizontalRadii[i]) | |
3762 return false; | |
3763 } | |
3764 if (!horizontalRadii[0]) | |
3765 return false; | |
3766 if (range.atEnd()) { | |
3767 // Legacy syntax: -webkit-border-radius: l1 l2; is equivalent to border-
radius: l1 / l2; | |
3768 if (useLegacyParsing && i == 2) { | |
3769 verticalRadii[0] = horizontalRadii[1]; | |
3770 horizontalRadii[1] = nullptr; | |
3771 } else { | |
3772 completeBorderRadii(horizontalRadii); | |
3773 for (unsigned i = 0; i < 4; ++i) | |
3774 verticalRadii[i] = horizontalRadii[i]; | |
3775 return true; | |
3776 } | |
3777 } else { | |
3778 if (range.peek().type() != DelimiterToken || range.peek().delimiter() !=
'/') | |
3779 return false; | |
3780 range.consumeIncludingWhitespace(); | |
3781 for (i = 0; i < 4 && !range.atEnd(); ++i) { | |
3782 verticalRadii[i] = consumeLengthOrPercent(range, cssParserMode, Valu
eRangeNonNegative); | |
3783 if (!verticalRadii[i]) | |
3784 return false; | |
3785 } | |
3786 if (!verticalRadii[0] || !range.atEnd()) | |
3787 return false; | |
3788 } | |
3789 completeBorderRadii(horizontalRadii); | |
3790 completeBorderRadii(verticalRadii); | |
3791 return true; | |
3792 } | |
3793 | |
3794 bool CSSPropertyParser::parseShorthand(CSSPropertyID unresolvedProperty, bool im
portant) | 3968 bool CSSPropertyParser::parseShorthand(CSSPropertyID unresolvedProperty, bool im
portant) |
3795 { | 3969 { |
3796 CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty); | 3970 CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty); |
3797 | 3971 |
3798 CSSPropertyID oldShorthand = m_currentShorthand; | 3972 CSSPropertyID oldShorthand = m_currentShorthand; |
3799 // TODO(rob.buis): Remove this when the legacy property parser is gone | 3973 // TODO(rob.buis): Remove this when the legacy property parser is gone |
3800 m_currentShorthand = property; | 3974 m_currentShorthand = property; |
3801 switch (property) { | 3975 switch (property) { |
3802 case CSSPropertyWebkitMarginCollapse: { | 3976 case CSSPropertyWebkitMarginCollapse: { |
3803 CSSValueID id = m_range.consumeIncludingWhitespace().id(); | 3977 CSSValueID id = m_range.consumeIncludingWhitespace().id(); |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3926 m_currentShorthand = oldShorthand; | 4100 m_currentShorthand = oldShorthand; |
3927 CSSParserValueList valueList(m_range); | 4101 CSSParserValueList valueList(m_range); |
3928 if (!valueList.size()) | 4102 if (!valueList.size()) |
3929 return false; | 4103 return false; |
3930 m_valueList = &valueList; | 4104 m_valueList = &valueList; |
3931 return legacyParseShorthand(unresolvedProperty, important); | 4105 return legacyParseShorthand(unresolvedProperty, important); |
3932 } | 4106 } |
3933 } | 4107 } |
3934 | 4108 |
3935 } // namespace blink | 4109 } // namespace blink |
OLD | NEW |