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 |