Chromium Code Reviews| 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 "config.h" | 5 #include "config.h" |
| 6 #include "core/css/parser/CSSPropertyParser.h" | 6 #include "core/css/parser/CSSPropertyParser.h" |
| 7 | 7 |
| 8 #include "core/StylePropertyShorthand.h" | 8 #include "core/StylePropertyShorthand.h" |
| 9 #include "core/css/CSSCalculationValue.h" | 9 #include "core/css/CSSCalculationValue.h" |
| 10 #include "core/css/CSSCustomIdentValue.h" | 10 #include "core/css/CSSCustomIdentValue.h" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 45 | 45 |
| 46 CSSParserValueList valueList(range); | 46 CSSParserValueList valueList(range); |
| 47 if (!valueList.size()) | 47 if (!valueList.size()) |
| 48 return false; // Parser error | 48 return false; // Parser error |
| 49 CSSPropertyParser parser(&valueList, range, context, parsedProperties, ruleT ype); | 49 CSSPropertyParser parser(&valueList, range, context, parsedProperties, ruleT ype); |
| 50 CSSPropertyID resolvedProperty = resolveCSSPropertyID(unresolvedProperty); | 50 CSSPropertyID resolvedProperty = resolveCSSPropertyID(unresolvedProperty); |
| 51 bool parseSuccess; | 51 bool parseSuccess; |
| 52 | 52 |
| 53 if (ruleType == StyleRule::Viewport) { | 53 if (ruleType == StyleRule::Viewport) { |
| 54 parseSuccess = (RuntimeEnabledFeatures::cssViewportEnabled() || isUAShee tBehavior(context.mode())) | 54 parseSuccess = (RuntimeEnabledFeatures::cssViewportEnabled() || isUAShee tBehavior(context.mode())) |
| 55 && parser.parseViewportProperty(resolvedProperty, important); | 55 && parser.parseViewportDescriptor(resolvedProperty, important); |
| 56 } else if (ruleType == StyleRule::FontFace) { | 56 } else if (ruleType == StyleRule::FontFace) { |
| 57 parseSuccess = parser.parseFontFaceDescriptor(resolvedProperty); | 57 parseSuccess = parser.parseFontFaceDescriptor(resolvedProperty); |
| 58 } else { | 58 } else { |
| 59 parseSuccess = parser.parseValue(unresolvedProperty, important); | 59 parseSuccess = parser.parseValue(unresolvedProperty, important); |
| 60 } | 60 } |
| 61 | 61 |
| 62 // This doesn't count UA style sheets | 62 // This doesn't count UA style sheets |
| 63 if (parseSuccess && context.useCounter()) | 63 if (parseSuccess && context.useCounter()) |
| 64 context.useCounter()->count(context, unresolvedProperty); | 64 context.useCounter()->count(context, unresolvedProperty); |
| 65 | 65 |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 251 || (valueRange == ValueRangeNonNegative && token.numericValue() < 0) ) | 251 || (valueRange == ValueRangeNonNegative && token.numericValue() < 0) ) |
| 252 return nullptr; | 252 return nullptr; |
| 253 return cssValuePool().createValue(range.consumeIncludingWhitespace().num ericValue(), CSSPrimitiveValue::UnitType::Pixels); | 253 return cssValuePool().createValue(range.consumeIncludingWhitespace().num ericValue(), CSSPrimitiveValue::UnitType::Pixels); |
| 254 } | 254 } |
| 255 CalcParser calcParser(range, valueRange); | 255 CalcParser calcParser(range, valueRange); |
| 256 if (calcParser.value() && calcParser.value()->category() == CalcLength) | 256 if (calcParser.value() && calcParser.value()->category() == CalcLength) |
| 257 return calcParser.consumeValue(); | 257 return calcParser.consumeValue(); |
| 258 return nullptr; | 258 return nullptr; |
| 259 } | 259 } |
| 260 | 260 |
| 261 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumeLengthOrPercent(CSSParse rTokenRange& range, CSSParserMode cssParserMode, ValueRange valueRange, Unitless Quirk unitless = UnitlessQuirk::Forbid) | 261 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumePercent(CSSParserTokenRa nge& range, ValueRange valueRange) |
| 262 { | 262 { |
| 263 const CSSParserToken& token = range.peek(); | 263 const CSSParserToken& token = range.peek(); |
| 264 if (token.type() == DimensionToken || token.type() == NumberToken) | |
| 265 return consumeLength(range, cssParserMode, valueRange, unitless); | |
| 266 if (token.type() == PercentageToken) { | 264 if (token.type() == PercentageToken) { |
| 267 if (valueRange == ValueRangeNonNegative && token.numericValue() < 0) | 265 if (valueRange == ValueRangeNonNegative && token.numericValue() < 0) |
| 268 return nullptr; | 266 return nullptr; |
| 269 return cssValuePool().createValue(range.consumeIncludingWhitespace().num ericValue(), CSSPrimitiveValue::UnitType::Percentage); | 267 return cssValuePool().createValue(range.consumeIncludingWhitespace().num ericValue(), CSSPrimitiveValue::UnitType::Percentage); |
| 270 } | 268 } |
| 271 CalcParser calcParser(range, valueRange); | 269 CalcParser calcParser(range, valueRange); |
| 272 if (const CSSCalcValue* calculation = calcParser.value()) { | 270 if (const CSSCalcValue* calculation = calcParser.value()) { |
| 271 if (calculation->category() == CalcPercent) | |
| 272 return calcParser.consumeValue(); | |
| 273 } | |
| 274 return nullptr; | |
| 275 } | |
| 276 | |
| 277 static inline bool isCSSWideKeyword(const CSSValueID& id) | |
|
Timothy Loh
2015/10/08 01:05:21
not sure if this was supposed to be moved?
| |
| 278 { | |
| 279 return id == CSSValueInitial || id == CSSValueInherit || id == CSSValueUnset || id == CSSValueDefault; | |
| 280 } | |
| 281 | |
| 282 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumeLengthOrPercent(CSSParse rTokenRange& range, CSSParserMode cssParserMode, ValueRange valueRange, Unitless Quirk unitless = UnitlessQuirk::Forbid) | |
| 283 { | |
| 284 const CSSParserToken& token = range.peek(); | |
| 285 if (token.type() == DimensionToken || token.type() == NumberToken) | |
| 286 return consumeLength(range, cssParserMode, valueRange, unitless); | |
| 287 if (token.type() == PercentageToken) | |
| 288 return consumePercent(range, valueRange); | |
| 289 CalcParser calcParser(range, valueRange); | |
| 290 if (const CSSCalcValue* calculation = calcParser.value()) { | |
| 273 if (calculation->category() == CalcLength || calculation->category() == CalcPercent || calculation->category() == CalcPercentLength) | 291 if (calculation->category() == CalcLength || calculation->category() == CalcPercent || calculation->category() == CalcPercentLength) |
| 274 return calcParser.consumeValue(); | 292 return calcParser.consumeValue(); |
| 275 } | 293 } |
| 276 return nullptr; | 294 return nullptr; |
| 277 } | 295 } |
| 278 | 296 |
| 279 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumeAngle(CSSParserTokenRang e& range) | 297 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumeAngle(CSSParserTokenRang e& range) |
| 280 { | 298 { |
| 281 const CSSParserToken& token = range.peek(); | 299 const CSSParserToken& token = range.peek(); |
| 282 if (token.type() == DimensionToken) { | 300 if (token.type() == DimensionToken) { |
| 283 switch (token.unitType()) { | 301 switch (token.unitType()) { |
| 284 case CSSPrimitiveValue::UnitType::Degrees: | 302 case CSSPrimitiveValue::UnitType::Degrees: |
| 285 case CSSPrimitiveValue::UnitType::Radians: | 303 case CSSPrimitiveValue::UnitType::Radians: |
| 286 case CSSPrimitiveValue::UnitType::Gradians: | 304 case CSSPrimitiveValue::UnitType::Gradians: |
| 287 case CSSPrimitiveValue::UnitType::Turns: | 305 case CSSPrimitiveValue::UnitType::Turns: |
| 288 return cssValuePool().createValue(range.consumeIncludingWhitespace() .numericValue(), token.unitType()); | 306 return cssValuePool().createValue(range.consumeIncludingWhitespace() .numericValue(), token.unitType()); |
| 289 default: | 307 default: |
| 290 return nullptr; | 308 return nullptr; |
| 291 } | 309 } |
| 292 } | 310 } |
| 293 CalcParser calcParser(range, ValueRangeAll); | 311 CalcParser calcParser(range, ValueRangeAll); |
| 294 if (const CSSCalcValue* calculation = calcParser.value()) { | 312 if (const CSSCalcValue* calculation = calcParser.value()) { |
| 295 if (calculation->category() == CalcAngle) | 313 if (calculation->category() == CalcAngle) |
| 296 return calcParser.consumeValue(); | 314 return calcParser.consumeValue(); |
| 297 } | 315 } |
| 298 return nullptr; | 316 return nullptr; |
| 299 } | 317 } |
| 300 | 318 |
| 301 static inline bool isCSSWideKeyword(const CSSValueID& id) | |
| 302 { | |
| 303 return id == CSSValueInitial || id == CSSValueInherit || id == CSSValueUnset || id == CSSValueDefault; | |
| 304 } | |
| 305 | |
| 306 // Methods for consuming non-shorthand properties starts here. | 319 // Methods for consuming non-shorthand properties starts here. |
| 307 static PassRefPtrWillBeRawPtr<CSSValue> consumeWillChange(CSSParserTokenRange& r ange) | 320 static PassRefPtrWillBeRawPtr<CSSValue> consumeWillChange(CSSParserTokenRange& r ange) |
| 308 { | 321 { |
| 309 RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated (); | 322 RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated (); |
| 310 if (range.peek().id() == CSSValueAuto) { | 323 if (range.peek().id() == CSSValueAuto) { |
| 311 // FIXME: This will be read back as an empty string instead of auto | 324 // FIXME: This will be read back as an empty string instead of auto |
| 312 return values.release(); | 325 return values.release(); |
| 313 } | 326 } |
| 314 | 327 |
| 315 // Every comma-separated list of identifiers is a valid will-change value, | 328 // Every comma-separated list of identifiers is a valid will-change value, |
| (...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 901 RefPtrWillBeRawPtr<CSSValue> verticalSpacing = horizontalSpacing; | 914 RefPtrWillBeRawPtr<CSSValue> verticalSpacing = horizontalSpacing; |
| 902 if (!m_range.atEnd()) | 915 if (!m_range.atEnd()) |
| 903 verticalSpacing = consumeLength(m_range, m_context.mode(), ValueRangeNon Negative, UnitlessQuirk::Allow); | 916 verticalSpacing = consumeLength(m_range, m_context.mode(), ValueRangeNon Negative, UnitlessQuirk::Allow); |
| 904 if (!verticalSpacing || !m_range.atEnd()) | 917 if (!verticalSpacing || !m_range.atEnd()) |
| 905 return false; | 918 return false; |
| 906 addProperty(CSSPropertyWebkitBorderHorizontalSpacing, horizontalSpacing.rele ase(), important); | 919 addProperty(CSSPropertyWebkitBorderHorizontalSpacing, horizontalSpacing.rele ase(), important); |
| 907 addProperty(CSSPropertyWebkitBorderVerticalSpacing, verticalSpacing.release( ), important); | 920 addProperty(CSSPropertyWebkitBorderVerticalSpacing, verticalSpacing.release( ), important); |
| 908 return true; | 921 return true; |
| 909 } | 922 } |
| 910 | 923 |
| 924 static PassRefPtrWillBeRawPtr<CSSValue> consumeSingleViewportDescriptor(CSSParse rTokenRange& range, CSSPropertyID propId, CSSParserMode cssParserMode) | |
| 925 { | |
| 926 CSSValueID id = range.peek().id(); | |
| 927 switch (propId) { | |
| 928 case CSSPropertyMinWidth: | |
| 929 case CSSPropertyMaxWidth: | |
| 930 case CSSPropertyMinHeight: | |
| 931 case CSSPropertyMaxHeight: | |
| 932 if (id == CSSValueAuto || id == CSSValueInternalExtendToZoom) | |
| 933 return consumeIdent(range); | |
| 934 return consumeLengthOrPercent(range, cssParserMode, ValueRangeNonNegativ e); | |
| 935 case CSSPropertyMinZoom: | |
| 936 case CSSPropertyMaxZoom: | |
| 937 case CSSPropertyZoom: { | |
| 938 if (id == CSSValueAuto) | |
| 939 return consumeIdent(range); | |
| 940 RefPtrWillBeRawPtr<CSSValue> parsedValue = consumeNumber(range, ValueRan geNonNegative); | |
|
Timothy Loh
2015/10/08 01:05:21
I prefer:
if (RefPtrWillBeRawPtr<CSSValue> parsed
| |
| 941 if (!parsedValue) | |
| 942 parsedValue = consumePercent(range, ValueRangeNonNegative); | |
| 943 return parsedValue.release(); | |
| 944 } | |
| 945 case CSSPropertyUserZoom: | |
| 946 if (id == CSSValueZoom || id == CSSValueFixed) | |
| 947 return consumeIdent(range); | |
| 948 break; | |
| 949 case CSSPropertyOrientation: | |
| 950 if (id == CSSValueAuto || id == CSSValuePortrait || id == CSSValueLandsc ape) | |
| 951 return consumeIdent(range); | |
| 952 break; | |
| 953 default: | |
| 954 ASSERT_NOT_REACHED(); | |
| 955 break; | |
| 956 } | |
| 957 | |
| 958 return nullptr; | |
| 959 } | |
| 960 | |
| 961 bool CSSPropertyParser::parseViewportDescriptor(CSSPropertyID propId, bool impor tant) | |
| 962 { | |
| 963 ASSERT(RuntimeEnabledFeatures::cssViewportEnabled() || isUASheetBehavior(m_c ontext.mode())); | |
| 964 | |
| 965 m_range.consumeWhitespace(); | |
|
Timothy Loh
2015/10/08 01:05:21
We should probably do this up front somewhere so i
| |
| 966 RefPtrWillBeRawPtr<CSSValue> parsedValue = nullptr; | |
| 967 | |
| 968 switch (propId) { | |
| 969 case CSSPropertyWidth: { | |
| 970 RefPtrWillBeRawPtr<CSSValue> minWidth = consumeSingleViewportDescriptor( m_range, CSSPropertyMinWidth, m_context.mode()); | |
| 971 if (!minWidth) | |
| 972 return false; | |
| 973 RefPtrWillBeRawPtr<CSSValue> maxWidth = minWidth; | |
| 974 if (!m_range.atEnd()) | |
| 975 maxWidth = consumeSingleViewportDescriptor(m_range, CSSPropertyMaxWi dth, m_context.mode()); | |
| 976 if (!maxWidth || !m_range.atEnd()) | |
| 977 return false; | |
| 978 addProperty(CSSPropertyMinWidth, minWidth.release(), important); | |
| 979 addProperty(CSSPropertyMaxWidth, maxWidth.release(), important); | |
| 980 return true; | |
| 981 } | |
| 982 case CSSPropertyHeight: { | |
| 983 RefPtrWillBeRawPtr<CSSValue> minHeight = consumeSingleViewportDescriptor (m_range, CSSPropertyMinHeight, m_context.mode()); | |
| 984 if (!minHeight) | |
| 985 return false; | |
| 986 RefPtrWillBeRawPtr<CSSValue> maxHeight = minHeight; | |
| 987 if (!m_range.atEnd()) | |
| 988 maxHeight = consumeSingleViewportDescriptor(m_range, CSSPropertyMaxH eight, m_context.mode()); | |
| 989 if (!maxHeight || !m_range.atEnd()) | |
| 990 return false; | |
| 991 addProperty(CSSPropertyMinHeight, minHeight.release(), important); | |
| 992 addProperty(CSSPropertyMaxHeight, maxHeight.release(), important); | |
| 993 return true; | |
| 994 } | |
| 995 case CSSPropertyMinWidth: | |
| 996 case CSSPropertyMaxWidth: | |
| 997 case CSSPropertyMinHeight: | |
| 998 case CSSPropertyMaxHeight: | |
| 999 case CSSPropertyMinZoom: | |
| 1000 case CSSPropertyMaxZoom: | |
| 1001 case CSSPropertyZoom: | |
| 1002 case CSSPropertyUserZoom: | |
| 1003 case CSSPropertyOrientation: | |
| 1004 parsedValue = consumeSingleViewportDescriptor(m_range, propId, m_context .mode()); | |
|
Timothy Loh
2015/10/08 01:05:21
if we only set parsedValue here, we should just mo
| |
| 1005 break; | |
| 1006 default: | |
| 1007 return false; | |
| 1008 } | |
| 1009 | |
| 1010 if (!parsedValue || !m_range.atEnd()) | |
| 1011 return false; | |
| 1012 | |
| 1013 addProperty(propId, parsedValue.release(), important); | |
| 1014 return true; | |
| 1015 } | |
| 1016 | |
| 911 bool CSSPropertyParser::parseShorthand(CSSPropertyID propId, bool important) | 1017 bool CSSPropertyParser::parseShorthand(CSSPropertyID propId, bool important) |
| 912 { | 1018 { |
| 913 m_range.consumeWhitespace(); | 1019 m_range.consumeWhitespace(); |
| 914 CSSPropertyID oldShorthand = m_currentShorthand; | 1020 CSSPropertyID oldShorthand = m_currentShorthand; |
| 915 // TODO(rob.buis): Remove this when the legacy property parser is gone | 1021 // TODO(rob.buis): Remove this when the legacy property parser is gone |
| 916 m_currentShorthand = propId; | 1022 m_currentShorthand = propId; |
| 917 switch (propId) { | 1023 switch (propId) { |
| 918 case CSSPropertyWebkitMarginCollapse: { | 1024 case CSSPropertyWebkitMarginCollapse: { |
| 919 CSSValueID id = m_range.consumeIncludingWhitespace().id(); | 1025 CSSValueID id = m_range.consumeIncludingWhitespace().id(); |
| 920 if (!CSSParserFastPaths::isValidKeywordPropertyAndValue(CSSPropertyWebki tMarginBeforeCollapse, id)) | 1026 if (!CSSParserFastPaths::isValidKeywordPropertyAndValue(CSSPropertyWebki tMarginBeforeCollapse, id)) |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 961 } | 1067 } |
| 962 case CSSPropertyBorderSpacing: | 1068 case CSSPropertyBorderSpacing: |
| 963 return consumeBorderSpacing(important); | 1069 return consumeBorderSpacing(important); |
| 964 default: | 1070 default: |
| 965 m_currentShorthand = oldShorthand; | 1071 m_currentShorthand = oldShorthand; |
| 966 return false; | 1072 return false; |
| 967 } | 1073 } |
| 968 } | 1074 } |
| 969 | 1075 |
| 970 } // namespace blink | 1076 } // namespace blink |
| OLD | NEW |