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/CSSBasicShapeValues.h" |
9 #include "core/css/CSSBorderImage.h" | |
9 #include "core/css/CSSCalculationValue.h" | 10 #include "core/css/CSSCalculationValue.h" |
10 #include "core/css/CSSContentDistributionValue.h" | 11 #include "core/css/CSSContentDistributionValue.h" |
11 #include "core/css/CSSCounterValue.h" | 12 #include "core/css/CSSCounterValue.h" |
12 #include "core/css/CSSCrossfadeValue.h" | 13 #include "core/css/CSSCrossfadeValue.h" |
13 #include "core/css/CSSCursorImageValue.h" | 14 #include "core/css/CSSCursorImageValue.h" |
14 #include "core/css/CSSCustomIdentValue.h" | 15 #include "core/css/CSSCustomIdentValue.h" |
15 #include "core/css/CSSFontFaceSrcValue.h" | 16 #include "core/css/CSSFontFaceSrcValue.h" |
16 #include "core/css/CSSFontFeatureValue.h" | 17 #include "core/css/CSSFontFeatureValue.h" |
17 #include "core/css/CSSFunctionValue.h" | 18 #include "core/css/CSSFunctionValue.h" |
18 #include "core/css/CSSImageSetValue.h" | 19 #include "core/css/CSSImageSetValue.h" |
(...skipping 2980 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2999 if (!xLength) | 3000 if (!xLength) |
3000 return nullptr; | 3001 return nullptr; |
3001 RefPtrWillBeRawPtr<CSSPrimitiveValue> yLength = consumeLengthOrPercent(a rgs, context.mode(), ValueRangeAll); | 3002 RefPtrWillBeRawPtr<CSSPrimitiveValue> yLength = consumeLengthOrPercent(a rgs, context.mode(), ValueRangeAll); |
3002 if (!yLength) | 3003 if (!yLength) |
3003 return nullptr; | 3004 return nullptr; |
3004 shape->appendPoint(xLength.release(), yLength.release()); | 3005 shape->appendPoint(xLength.release(), yLength.release()); |
3005 } while (consumeCommaIncludingWhitespace(args)); | 3006 } while (consumeCommaIncludingWhitespace(args)); |
3006 return shape.release(); | 3007 return shape.release(); |
3007 } | 3008 } |
3008 | 3009 |
3009 static void completeBorderRadii(RefPtrWillBeRawPtr<CSSPrimitiveValue> radii[4]) | 3010 static void complete4Sides(RefPtrWillBeRawPtr<CSSPrimitiveValue> side[4]) |
3010 { | 3011 { |
3011 if (radii[3]) | 3012 if (side[3]) |
3012 return; | 3013 return; |
3013 if (!radii[2]) { | 3014 if (!side[2]) { |
3014 if (!radii[1]) | 3015 if (!side[1]) |
3015 radii[1] = radii[0]; | 3016 side[1] = side[0]; |
3016 radii[2] = radii[0]; | 3017 side[2] = side[0]; |
3017 } | 3018 } |
3018 radii[3] = radii[1]; | 3019 side[3] = side[1]; |
3019 } | 3020 } |
3020 | 3021 |
3021 static bool consumeRadii(RefPtrWillBeRawPtr<CSSPrimitiveValue> horizontalRadii[4 ], RefPtrWillBeRawPtr<CSSPrimitiveValue> verticalRadii[4], CSSParserTokenRange& range, CSSParserMode cssParserMode, bool useLegacyParsing) | 3022 static bool consumeRadii(RefPtrWillBeRawPtr<CSSPrimitiveValue> horizontalRadii[4 ], RefPtrWillBeRawPtr<CSSPrimitiveValue> verticalRadii[4], CSSParserTokenRange& range, CSSParserMode cssParserMode, bool useLegacyParsing) |
3022 { | 3023 { |
3023 #if ENABLE(OILPAN) | 3024 #if ENABLE(OILPAN) |
3024 // Unconditionally zero initialize the arrays of raw pointers. | 3025 // Unconditionally zero initialize the arrays of raw pointers. |
3025 memset(horizontalRadii, 0, 4 * sizeof(horizontalRadii[0])); | 3026 memset(horizontalRadii, 0, 4 * sizeof(horizontalRadii[0])); |
3026 memset(verticalRadii, 0, 4 * sizeof(verticalRadii[0])); | 3027 memset(verticalRadii, 0, 4 * sizeof(verticalRadii[0])); |
3027 #endif | 3028 #endif |
3028 unsigned i = 0; | 3029 unsigned i = 0; |
3029 for (; i < 4 && !range.atEnd() && range.peek().type() != DelimiterToken; ++i ) { | 3030 for (; i < 4 && !range.atEnd() && range.peek().type() != DelimiterToken; ++i ) { |
3030 horizontalRadii[i] = consumeLengthOrPercent(range, cssParserMode, ValueR angeNonNegative); | 3031 horizontalRadii[i] = consumeLengthOrPercent(range, cssParserMode, ValueR angeNonNegative); |
3031 if (!horizontalRadii[i]) | 3032 if (!horizontalRadii[i]) |
3032 return false; | 3033 return false; |
3033 } | 3034 } |
3034 if (!horizontalRadii[0]) | 3035 if (!horizontalRadii[0]) |
3035 return false; | 3036 return false; |
3036 if (range.atEnd()) { | 3037 if (range.atEnd()) { |
3037 // Legacy syntax: -webkit-border-radius: l1 l2; is equivalent to border- radius: l1 / l2; | 3038 // Legacy syntax: -webkit-border-radius: l1 l2; is equivalent to border- radius: l1 / l2; |
3038 if (useLegacyParsing && i == 2) { | 3039 if (useLegacyParsing && i == 2) { |
3039 verticalRadii[0] = horizontalRadii[1]; | 3040 verticalRadii[0] = horizontalRadii[1]; |
3040 horizontalRadii[1] = nullptr; | 3041 horizontalRadii[1] = nullptr; |
3041 } else { | 3042 } else { |
3042 completeBorderRadii(horizontalRadii); | 3043 complete4Sides(horizontalRadii); |
3043 for (unsigned i = 0; i < 4; ++i) | 3044 for (unsigned i = 0; i < 4; ++i) |
3044 verticalRadii[i] = horizontalRadii[i]; | 3045 verticalRadii[i] = horizontalRadii[i]; |
3045 return true; | 3046 return true; |
3046 } | 3047 } |
3047 } else { | 3048 } else { |
3048 if (range.peek().type() != DelimiterToken || range.peek().delimiter() != '/') | 3049 if (range.peek().type() != DelimiterToken || range.peek().delimiter() != '/') |
3049 return false; | 3050 return false; |
3050 range.consumeIncludingWhitespace(); | 3051 range.consumeIncludingWhitespace(); |
3051 for (i = 0; i < 4 && !range.atEnd(); ++i) { | 3052 for (i = 0; i < 4 && !range.atEnd(); ++i) { |
3052 verticalRadii[i] = consumeLengthOrPercent(range, cssParserMode, Valu eRangeNonNegative); | 3053 verticalRadii[i] = consumeLengthOrPercent(range, cssParserMode, Valu eRangeNonNegative); |
3053 if (!verticalRadii[i]) | 3054 if (!verticalRadii[i]) |
3054 return false; | 3055 return false; |
3055 } | 3056 } |
3056 if (!verticalRadii[0] || !range.atEnd()) | 3057 if (!verticalRadii[0] || !range.atEnd()) |
3057 return false; | 3058 return false; |
3058 } | 3059 } |
3059 completeBorderRadii(horizontalRadii); | 3060 complete4Sides(horizontalRadii); |
3060 completeBorderRadii(verticalRadii); | 3061 complete4Sides(verticalRadii); |
3061 return true; | 3062 return true; |
3062 } | 3063 } |
3063 | 3064 |
3064 static PassRefPtrWillBeRawPtr<CSSBasicShapeInsetValue> consumeBasicShapeInset(CS SParserTokenRange& args, const CSSParserContext& context) | 3065 static PassRefPtrWillBeRawPtr<CSSBasicShapeInsetValue> consumeBasicShapeInset(CS SParserTokenRange& args, const CSSParserContext& context) |
3065 { | 3066 { |
3066 RefPtrWillBeRawPtr<CSSBasicShapeInsetValue> shape = CSSBasicShapeInsetValue: :create(); | 3067 RefPtrWillBeRawPtr<CSSBasicShapeInsetValue> shape = CSSBasicShapeInsetValue: :create(); |
3067 RefPtrWillBeRawPtr<CSSPrimitiveValue> top = consumeLengthOrPercent(args, con text.mode(), ValueRangeAll); | 3068 RefPtrWillBeRawPtr<CSSPrimitiveValue> top = consumeLengthOrPercent(args, con text.mode(), ValueRangeAll); |
3068 if (!top) | 3069 if (!top) |
3069 return nullptr; | 3070 return nullptr; |
3070 RefPtrWillBeRawPtr<CSSPrimitiveValue> right = nullptr; | 3071 RefPtrWillBeRawPtr<CSSPrimitiveValue> right = nullptr; |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3181 if (position == CSSValueInvalid && distribution == CSSValueInvalid) | 3182 if (position == CSSValueInvalid && distribution == CSSValueInvalid) |
3182 return nullptr; | 3183 return nullptr; |
3183 | 3184 |
3184 // The grammar states that <overflow-position> must be associated to <conten t-position>. | 3185 // The grammar states that <overflow-position> must be associated to <conten t-position>. |
3185 if (overflow != CSSValueInvalid && position == CSSValueInvalid) | 3186 if (overflow != CSSValueInvalid && position == CSSValueInvalid) |
3186 return nullptr; | 3187 return nullptr; |
3187 | 3188 |
3188 return CSSContentDistributionValue::create(distribution, position, overflow) ; | 3189 return CSSContentDistributionValue::create(distribution, position, overflow) ; |
3189 } | 3190 } |
3190 | 3191 |
3192 static PassRefPtrWillBeRawPtr<CSSValue> consumeBorderImageRepeat(CSSParserTokenR ange& range) | |
3193 { | |
3194 RefPtrWillBeRawPtr<CSSPrimitiveValue> firstValue = nullptr; | |
Timothy Loh
2016/02/02 10:57:36
first -> horizontal, second -> vertical
Why not j
| |
3195 if (!identMatches<CSSValueStretch, CSSValueRepeat, CSSValueSpace, CSSValueRo und>(range.peek().id())) | |
3196 return nullptr; | |
3197 firstValue = consumeIdent(range); | |
3198 | |
3199 RefPtrWillBeRawPtr<CSSPrimitiveValue> secondValue = nullptr; | |
3200 if (identMatches<CSSValueStretch, CSSValueRepeat, CSSValueSpace, CSSValueRou nd>(range.peek().id())) | |
3201 secondValue = consumeIdent(range); | |
3202 else | |
3203 secondValue = firstValue; | |
3204 | |
3205 return CSSValuePair::create(firstValue.release(), secondValue.release(), CSS ValuePair::DropIdenticalValues); | |
3206 } | |
3207 | |
3208 static PassRefPtrWillBeRawPtr<CSSValue> consumeBorderImageSlice(CSSPropertyID pr operty, CSSParserTokenRange& range, CSSParserMode cssParserMode) | |
3209 { | |
3210 bool fill = consumeIdent<CSSValueFill>(range); | |
3211 RefPtrWillBeRawPtr<CSSPrimitiveValue> slices[4]; | |
3212 #if ENABLE(OILPAN) | |
3213 // Unconditionally zero initialize the arrays of raw pointers. | |
3214 memset(slices, 0, 4 * sizeof(slices[0])); | |
3215 #endif | |
3216 RefPtrWillBeRawPtr<CSSPrimitiveValue> value = nullptr; | |
Timothy Loh
2016/02/02 10:57:36
Better to declare this inside the loop since it's
| |
3217 for (size_t index = 0; index < 4; ++index) { | |
3218 value = consumePercent(range, ValueRangeNonNegative); | |
3219 if (!value) | |
3220 value = consumeNumber(range, ValueRangeNonNegative); | |
3221 if (!value) | |
3222 break; | |
3223 slices[index] = value; | |
3224 } | |
3225 if (!slices[0]) | |
3226 return nullptr; | |
3227 if (consumeIdent<CSSValueFill>(range)) { | |
Timothy Loh
2016/02/02 10:57:36
Maybe nicer as follows:
if (!fill && consumeIdent
| |
3228 if (fill) | |
3229 return nullptr; | |
3230 fill = true; | |
3231 } | |
3232 complete4Sides(slices); | |
3233 // FIXME: For backwards compatibility, -webkit-border-image, -webkit-mask-bo x-image and -webkit-box-reflect have to do a fill by default. | |
3234 // FIXME: What do we do with -webkit-box-reflect and -webkit-mask-box-image? Probably just have to leave them filling... | |
3235 if (property == CSSPropertyWebkitBorderImage || property == CSSPropertyWebki tMaskBoxImage || property == CSSPropertyWebkitBoxReflect) | |
3236 fill = true; | |
3237 return CSSBorderImageSliceValue::create(CSSQuadValue::create(slices[0].relea se(), slices[1].release(), slices[2].release(), slices[3].release(), CSSQuadValu e::SerializeAsQuad), fill); | |
3238 } | |
3239 | |
3240 static PassRefPtrWillBeRawPtr<CSSValue> consumeBorderImageOutset(CSSParserTokenR ange& range) | |
3241 { | |
3242 RefPtrWillBeRawPtr<CSSPrimitiveValue> outsets[4]; | |
3243 #if ENABLE(OILPAN) | |
3244 // Unconditionally zero initialize the arrays of raw pointers. | |
3245 memset(outsets, 0, 4 * sizeof(outsets[0])); | |
3246 #endif | |
3247 RefPtrWillBeRawPtr<CSSPrimitiveValue> value = nullptr; | |
3248 for (size_t index = 0; index < 4; ++index) { | |
3249 value = consumeNumber(range, ValueRangeNonNegative); | |
3250 if (!value) | |
3251 value = consumeLength(range, HTMLStandardMode, ValueRangeNonNegative ); | |
3252 if (!value) | |
3253 break; | |
3254 outsets[index] = value; | |
3255 } | |
3256 if (!outsets[0]) | |
3257 return nullptr; | |
3258 complete4Sides(outsets); | |
3259 return CSSQuadValue::create(outsets[0].release(), outsets[1].release(), outs ets[2].release(), outsets[3].release(), CSSQuadValue::SerializeAsQuad); | |
3260 } | |
3261 | |
3262 static PassRefPtrWillBeRawPtr<CSSValue> consumeBorderImageWidth(CSSParserTokenRa nge& range) | |
3263 { | |
3264 RefPtrWillBeRawPtr<CSSPrimitiveValue> widths[4]; | |
3265 #if ENABLE(OILPAN) | |
3266 // Unconditionally zero initialize the arrays of raw pointers. | |
3267 memset(widths, 0, 4 * sizeof(widths[0])); | |
3268 #endif | |
3269 RefPtrWillBeRawPtr<CSSPrimitiveValue> value = nullptr; | |
3270 for (size_t index = 0; index < 4; ++index) { | |
3271 value = consumeNumber(range, ValueRangeNonNegative); | |
3272 if (!value) | |
3273 value = consumeLengthOrPercent(range, HTMLStandardMode, ValueRangeNo nNegative, UnitlessQuirk::Forbid); | |
3274 if (!value && range.peek().id() == CSSValueAuto) | |
Timothy Loh
2016/02/02 10:57:36
How about
if (!value)
value = consumeIdent<CS
| |
3275 value = consumeIdent(range); | |
3276 if (!value) | |
3277 break; | |
3278 widths[index] = value; | |
3279 } | |
3280 if (!widths[0]) | |
3281 return nullptr; | |
3282 complete4Sides(widths); | |
3283 return CSSQuadValue::create(widths[0].release(), widths[1].release(), widths [2].release(), widths[3].release(), CSSQuadValue::SerializeAsQuad); | |
3284 } | |
3285 | |
3191 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty ID unresolvedProperty) | 3286 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty ID unresolvedProperty) |
3192 { | 3287 { |
3193 CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty); | 3288 CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty); |
3194 if (CSSParserFastPaths::isKeywordPropertyID(property)) { | 3289 if (CSSParserFastPaths::isKeywordPropertyID(property)) { |
3195 if (!CSSParserFastPaths::isValidKeywordPropertyAndValue(property, m_rang e.peek().id())) | 3290 if (!CSSParserFastPaths::isValidKeywordPropertyAndValue(property, m_rang e.peek().id())) |
3196 return nullptr; | 3291 return nullptr; |
3197 return consumeIdent(m_range); | 3292 return consumeIdent(m_range); |
3198 } | 3293 } |
3199 switch (property) { | 3294 switch (property) { |
3200 case CSSPropertyWillChange: | 3295 case CSSPropertyWillChange: |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3485 case CSSPropertyVerticalAlign: | 3580 case CSSPropertyVerticalAlign: |
3486 return consumeVerticalAlign(m_range, m_context.mode()); | 3581 return consumeVerticalAlign(m_range, m_context.mode()); |
3487 case CSSPropertyShapeOutside: | 3582 case CSSPropertyShapeOutside: |
3488 return consumeShapeOutside(m_range, m_context); | 3583 return consumeShapeOutside(m_range, m_context); |
3489 case CSSPropertyWebkitClipPath: | 3584 case CSSPropertyWebkitClipPath: |
3490 return consumeClipPath(m_range, m_context); | 3585 return consumeClipPath(m_range, m_context); |
3491 case CSSPropertyJustifyContent: | 3586 case CSSPropertyJustifyContent: |
3492 case CSSPropertyAlignContent: | 3587 case CSSPropertyAlignContent: |
3493 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled()); | 3588 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled()); |
3494 return consumeContentDistributionOverflowPosition(m_range); | 3589 return consumeContentDistributionOverflowPosition(m_range); |
3590 case CSSPropertyBorderImageRepeat: | |
3591 case CSSPropertyWebkitMaskBoxImageRepeat: | |
3592 return consumeBorderImageRepeat(m_range); | |
3593 case CSSPropertyBorderImageSlice: | |
3594 case CSSPropertyWebkitMaskBoxImageSlice: | |
3595 return consumeBorderImageSlice(property, m_range, m_context.mode()); | |
3596 case CSSPropertyBorderImageOutset: | |
3597 case CSSPropertyWebkitMaskBoxImageOutset: | |
3598 return consumeBorderImageOutset(m_range); | |
3599 case CSSPropertyBorderImageWidth: | |
3600 case CSSPropertyWebkitMaskBoxImageWidth: | |
3601 return consumeBorderImageWidth(m_range); | |
3495 default: | 3602 default: |
3496 CSSParserValueList valueList(m_range); | 3603 CSSParserValueList valueList(m_range); |
3497 if (valueList.size()) { | 3604 if (valueList.size()) { |
3498 m_valueList = &valueList; | 3605 m_valueList = &valueList; |
3499 if (RefPtrWillBeRawPtr<CSSValue> result = legacyParseValue(unresolve dProperty)) { | 3606 if (RefPtrWillBeRawPtr<CSSValue> result = legacyParseValue(unresolve dProperty)) { |
3500 while (!m_range.atEnd()) | 3607 while (!m_range.atEnd()) |
3501 m_range.consume(); | 3608 m_range.consume(); |
3502 return result.release(); | 3609 return result.release(); |
3503 } | 3610 } |
3504 } | 3611 } |
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4145 m_currentShorthand = oldShorthand; | 4252 m_currentShorthand = oldShorthand; |
4146 CSSParserValueList valueList(m_range); | 4253 CSSParserValueList valueList(m_range); |
4147 if (!valueList.size()) | 4254 if (!valueList.size()) |
4148 return false; | 4255 return false; |
4149 m_valueList = &valueList; | 4256 m_valueList = &valueList; |
4150 return legacyParseShorthand(unresolvedProperty, important); | 4257 return legacyParseShorthand(unresolvedProperty, important); |
4151 } | 4258 } |
4152 } | 4259 } |
4153 | 4260 |
4154 } // namespace blink | 4261 } // namespace blink |
OLD | NEW |