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 RefPtrWillBeRawPtr<CSSPrimitiveValue> consumeBorderImageRepeatKeyword(CSS
ParserTokenRange& range) |
| 3193 { |
| 3194 return consumeIdent<CSSValueStretch, CSSValueRepeat, CSSValueSpace, CSSValue
Round>(range); |
| 3195 } |
| 3196 |
| 3197 static PassRefPtrWillBeRawPtr<CSSValue> consumeBorderImageRepeat(CSSParserTokenR
ange& range) |
| 3198 { |
| 3199 RefPtrWillBeRawPtr<CSSPrimitiveValue> horizontal = consumeBorderImageRepeatK
eyword(range); |
| 3200 if (!horizontal) |
| 3201 return nullptr; |
| 3202 RefPtrWillBeRawPtr<CSSPrimitiveValue> vertical = consumeBorderImageRepeatKey
word(range); |
| 3203 if (!vertical) |
| 3204 vertical = horizontal; |
| 3205 return CSSValuePair::create(horizontal.release(), vertical.release(), CSSVal
uePair::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 for (size_t index = 0; index < 4; ++index) { |
| 3217 RefPtrWillBeRawPtr<CSSPrimitiveValue> value = consumePercent(range, Valu
eRangeNonNegative); |
| 3218 if (!value) |
| 3219 value = consumeNumber(range, ValueRangeNonNegative); |
| 3220 if (!value) |
| 3221 break; |
| 3222 slices[index] = value; |
| 3223 } |
| 3224 if (!slices[0]) |
| 3225 return nullptr; |
| 3226 if (consumeIdent<CSSValueFill>(range)) { |
| 3227 if (fill) |
| 3228 return nullptr; |
| 3229 fill = true; |
| 3230 } |
| 3231 complete4Sides(slices); |
| 3232 // FIXME: For backwards compatibility, -webkit-border-image, -webkit-mask-bo
x-image and -webkit-box-reflect have to do a fill by default. |
| 3233 // FIXME: What do we do with -webkit-box-reflect and -webkit-mask-box-image?
Probably just have to leave them filling... |
| 3234 if (property == CSSPropertyWebkitBorderImage || property == CSSPropertyWebki
tMaskBoxImage || property == CSSPropertyWebkitBoxReflect) |
| 3235 fill = true; |
| 3236 return CSSBorderImageSliceValue::create(CSSQuadValue::create(slices[0].relea
se(), slices[1].release(), slices[2].release(), slices[3].release(), CSSQuadValu
e::SerializeAsQuad), fill); |
| 3237 } |
| 3238 |
| 3239 static PassRefPtrWillBeRawPtr<CSSValue> consumeBorderImageOutset(CSSParserTokenR
ange& range) |
| 3240 { |
| 3241 RefPtrWillBeRawPtr<CSSPrimitiveValue> outsets[4]; |
| 3242 #if ENABLE(OILPAN) |
| 3243 // Unconditionally zero initialize the arrays of raw pointers. |
| 3244 memset(outsets, 0, 4 * sizeof(outsets[0])); |
| 3245 #endif |
| 3246 RefPtrWillBeRawPtr<CSSPrimitiveValue> value = nullptr; |
| 3247 for (size_t index = 0; index < 4; ++index) { |
| 3248 value = consumeNumber(range, ValueRangeNonNegative); |
| 3249 if (!value) |
| 3250 value = consumeLength(range, HTMLStandardMode, ValueRangeNonNegative
); |
| 3251 if (!value) |
| 3252 break; |
| 3253 outsets[index] = value; |
| 3254 } |
| 3255 if (!outsets[0]) |
| 3256 return nullptr; |
| 3257 complete4Sides(outsets); |
| 3258 return CSSQuadValue::create(outsets[0].release(), outsets[1].release(), outs
ets[2].release(), outsets[3].release(), CSSQuadValue::SerializeAsQuad); |
| 3259 } |
| 3260 |
| 3261 static PassRefPtrWillBeRawPtr<CSSValue> consumeBorderImageWidth(CSSParserTokenRa
nge& range) |
| 3262 { |
| 3263 RefPtrWillBeRawPtr<CSSPrimitiveValue> widths[4]; |
| 3264 #if ENABLE(OILPAN) |
| 3265 // Unconditionally zero initialize the arrays of raw pointers. |
| 3266 memset(widths, 0, 4 * sizeof(widths[0])); |
| 3267 #endif |
| 3268 RefPtrWillBeRawPtr<CSSPrimitiveValue> value = nullptr; |
| 3269 for (size_t index = 0; index < 4; ++index) { |
| 3270 value = consumeNumber(range, ValueRangeNonNegative); |
| 3271 if (!value) |
| 3272 value = consumeLengthOrPercent(range, HTMLStandardMode, ValueRangeNo
nNegative, UnitlessQuirk::Forbid); |
| 3273 if (!value) |
| 3274 value = consumeIdent<CSSValueAuto>(range); |
| 3275 if (!value) |
| 3276 break; |
| 3277 widths[index] = value; |
| 3278 } |
| 3279 if (!widths[0]) |
| 3280 return nullptr; |
| 3281 complete4Sides(widths); |
| 3282 return CSSQuadValue::create(widths[0].release(), widths[1].release(), widths
[2].release(), widths[3].release(), CSSQuadValue::SerializeAsQuad); |
| 3283 } |
| 3284 |
3191 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty
ID unresolvedProperty) | 3285 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty
ID unresolvedProperty) |
3192 { | 3286 { |
3193 CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty); | 3287 CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty); |
3194 if (CSSParserFastPaths::isKeywordPropertyID(property)) { | 3288 if (CSSParserFastPaths::isKeywordPropertyID(property)) { |
3195 if (!CSSParserFastPaths::isValidKeywordPropertyAndValue(property, m_rang
e.peek().id())) | 3289 if (!CSSParserFastPaths::isValidKeywordPropertyAndValue(property, m_rang
e.peek().id())) |
3196 return nullptr; | 3290 return nullptr; |
3197 return consumeIdent(m_range); | 3291 return consumeIdent(m_range); |
3198 } | 3292 } |
3199 switch (property) { | 3293 switch (property) { |
3200 case CSSPropertyWillChange: | 3294 case CSSPropertyWillChange: |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3485 case CSSPropertyVerticalAlign: | 3579 case CSSPropertyVerticalAlign: |
3486 return consumeVerticalAlign(m_range, m_context.mode()); | 3580 return consumeVerticalAlign(m_range, m_context.mode()); |
3487 case CSSPropertyShapeOutside: | 3581 case CSSPropertyShapeOutside: |
3488 return consumeShapeOutside(m_range, m_context); | 3582 return consumeShapeOutside(m_range, m_context); |
3489 case CSSPropertyWebkitClipPath: | 3583 case CSSPropertyWebkitClipPath: |
3490 return consumeClipPath(m_range, m_context); | 3584 return consumeClipPath(m_range, m_context); |
3491 case CSSPropertyJustifyContent: | 3585 case CSSPropertyJustifyContent: |
3492 case CSSPropertyAlignContent: | 3586 case CSSPropertyAlignContent: |
3493 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled()); | 3587 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled()); |
3494 return consumeContentDistributionOverflowPosition(m_range); | 3588 return consumeContentDistributionOverflowPosition(m_range); |
| 3589 case CSSPropertyBorderImageRepeat: |
| 3590 case CSSPropertyWebkitMaskBoxImageRepeat: |
| 3591 return consumeBorderImageRepeat(m_range); |
| 3592 case CSSPropertyBorderImageSlice: |
| 3593 case CSSPropertyWebkitMaskBoxImageSlice: |
| 3594 return consumeBorderImageSlice(property, m_range, m_context.mode()); |
| 3595 case CSSPropertyBorderImageOutset: |
| 3596 case CSSPropertyWebkitMaskBoxImageOutset: |
| 3597 return consumeBorderImageOutset(m_range); |
| 3598 case CSSPropertyBorderImageWidth: |
| 3599 case CSSPropertyWebkitMaskBoxImageWidth: |
| 3600 return consumeBorderImageWidth(m_range); |
3495 default: | 3601 default: |
3496 CSSParserValueList valueList(m_range); | 3602 CSSParserValueList valueList(m_range); |
3497 if (valueList.size()) { | 3603 if (valueList.size()) { |
3498 m_valueList = &valueList; | 3604 m_valueList = &valueList; |
3499 if (RefPtrWillBeRawPtr<CSSValue> result = legacyParseValue(unresolve
dProperty)) { | 3605 if (RefPtrWillBeRawPtr<CSSValue> result = legacyParseValue(unresolve
dProperty)) { |
3500 while (!m_range.atEnd()) | 3606 while (!m_range.atEnd()) |
3501 m_range.consume(); | 3607 m_range.consume(); |
3502 return result.release(); | 3608 return result.release(); |
3503 } | 3609 } |
3504 } | 3610 } |
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4145 m_currentShorthand = oldShorthand; | 4251 m_currentShorthand = oldShorthand; |
4146 CSSParserValueList valueList(m_range); | 4252 CSSParserValueList valueList(m_range); |
4147 if (!valueList.size()) | 4253 if (!valueList.size()) |
4148 return false; | 4254 return false; |
4149 m_valueList = &valueList; | 4255 m_valueList = &valueList; |
4150 return legacyParseShorthand(unresolvedProperty, important); | 4256 return legacyParseShorthand(unresolvedProperty, important); |
4151 } | 4257 } |
4152 } | 4258 } |
4153 | 4259 |
4154 } // namespace blink | 4260 } // namespace blink |
OLD | NEW |