| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/CSSParserFastPaths.h" | 6 #include "core/css/parser/CSSParserFastPaths.h" |
| 7 | 7 |
| 8 #include "core/StylePropertyShorthand.h" | 8 #include "core/StylePropertyShorthand.h" |
| 9 #include "core/css/CSSFunctionValue.h" | 9 #include "core/css/CSSFunctionValue.h" |
| 10 #include "core/css/CSSValuePool.h" | 10 #include "core/css/CSSValuePool.h" |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 } | 78 } |
| 79 | 79 |
| 80 // We rely on charactersToDouble for validation as well. The function | 80 // We rely on charactersToDouble for validation as well. The function |
| 81 // will set "ok" to "false" if the entire passed-in character range does | 81 // will set "ok" to "false" if the entire passed-in character range does |
| 82 // not represent a double. | 82 // not represent a double. |
| 83 bool ok; | 83 bool ok; |
| 84 number = charactersToDouble(characters, length, &ok); | 84 number = charactersToDouble(characters, length, &ok); |
| 85 return ok; | 85 return ok; |
| 86 } | 86 } |
| 87 | 87 |
| 88 static PassRefPtrWillBeRawPtr<CSSValue> parseSimpleLengthValue(CSSPropertyID pro
pertyId, const String& string, CSSParserMode cssParserMode) | 88 static PassRefPtr<CSSValue> parseSimpleLengthValue(CSSPropertyID propertyId, con
st String& string, CSSParserMode cssParserMode) |
| 89 { | 89 { |
| 90 ASSERT(!string.isEmpty()); | 90 ASSERT(!string.isEmpty()); |
| 91 bool acceptsNegativeNumbers = false; | 91 bool acceptsNegativeNumbers = false; |
| 92 | 92 |
| 93 // In @viewport, width and height are shorthands, not simple length values. | 93 // In @viewport, width and height are shorthands, not simple length values. |
| 94 if (isCSSViewportParsingEnabledForMode(cssParserMode) || !isSimpleLengthProp
ertyID(propertyId, acceptsNegativeNumbers)) | 94 if (isCSSViewportParsingEnabledForMode(cssParserMode) || !isSimpleLengthProp
ertyID(propertyId, acceptsNegativeNumbers)) |
| 95 return nullptr; | 95 return nullptr; |
| 96 | 96 |
| 97 unsigned length = string.length(); | 97 unsigned length = string.length(); |
| 98 double number; | 98 double number; |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 return false; | 426 return false; |
| 427 if (current != end) | 427 if (current != end) |
| 428 return false; | 428 return false; |
| 429 rgb = makeRGB(red, green, blue); | 429 rgb = makeRGB(red, green, blue); |
| 430 return true; | 430 return true; |
| 431 } | 431 } |
| 432 | 432 |
| 433 return false; | 433 return false; |
| 434 } | 434 } |
| 435 | 435 |
| 436 PassRefPtrWillBeRawPtr<CSSValue> CSSParserFastPaths::parseColor(const String& st
ring, CSSParserMode parserMode) | 436 PassRefPtr<CSSValue> CSSParserFastPaths::parseColor(const String& string, CSSPar
serMode parserMode) |
| 437 { | 437 { |
| 438 ASSERT(!string.isEmpty()); | 438 ASSERT(!string.isEmpty()); |
| 439 CSSParserString cssString; | 439 CSSParserString cssString; |
| 440 cssString.init(string); | 440 cssString.init(string); |
| 441 CSSValueID valueID = cssValueKeywordID(cssString); | 441 CSSValueID valueID = cssValueKeywordID(cssString); |
| 442 if (CSSPropertyParser::isColorKeyword(valueID)) { | 442 if (CSSPropertyParser::isColorKeyword(valueID)) { |
| 443 if (!isValueAllowedInMode(valueID, parserMode)) | 443 if (!isValueAllowedInMode(valueID, parserMode)) |
| 444 return nullptr; | 444 return nullptr; |
| 445 return cssValuePool().createIdentifierValue(valueID); | 445 return cssValuePool().createIdentifierValue(valueID); |
| 446 } | 446 } |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 798 case CSSPropertyScrollSnapType: | 798 case CSSPropertyScrollSnapType: |
| 799 return true; | 799 return true; |
| 800 case CSSPropertyAlignItems: | 800 case CSSPropertyAlignItems: |
| 801 case CSSPropertyAlignSelf: | 801 case CSSPropertyAlignSelf: |
| 802 return !RuntimeEnabledFeatures::cssGridLayoutEnabled(); | 802 return !RuntimeEnabledFeatures::cssGridLayoutEnabled(); |
| 803 default: | 803 default: |
| 804 return false; | 804 return false; |
| 805 } | 805 } |
| 806 } | 806 } |
| 807 | 807 |
| 808 static PassRefPtrWillBeRawPtr<CSSValue> parseKeywordValue(CSSPropertyID property
Id, const String& string) | 808 static PassRefPtr<CSSValue> parseKeywordValue(CSSPropertyID propertyId, const St
ring& string) |
| 809 { | 809 { |
| 810 ASSERT(!string.isEmpty()); | 810 ASSERT(!string.isEmpty()); |
| 811 | 811 |
| 812 if (!CSSParserFastPaths::isKeywordPropertyID(propertyId)) { | 812 if (!CSSParserFastPaths::isKeywordPropertyID(propertyId)) { |
| 813 // All properties accept the values of "initial" and "inherit". | 813 // All properties accept the values of "initial" and "inherit". |
| 814 String lowerCaseString = string.lower(); | 814 String lowerCaseString = string.lower(); |
| 815 if (lowerCaseString != "initial" && lowerCaseString != "inherit") | 815 if (lowerCaseString != "initial" && lowerCaseString != "inherit") |
| 816 return nullptr; | 816 return nullptr; |
| 817 | 817 |
| 818 // Parse initial/inherit shorthands using the CSSPropertyParser. | 818 // Parse initial/inherit shorthands using the CSSPropertyParser. |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 870 if (!ok) | 870 if (!ok) |
| 871 return false; | 871 return false; |
| 872 transformValue->append(cssValuePool().createValue(number, CSSPrimitiveVa
lue::UnitType::Number)); | 872 transformValue->append(cssValuePool().createValue(number, CSSPrimitiveVa
lue::UnitType::Number)); |
| 873 pos += argumentLength + 1; | 873 pos += argumentLength + 1; |
| 874 --expectedCount; | 874 --expectedCount; |
| 875 } | 875 } |
| 876 return true; | 876 return true; |
| 877 } | 877 } |
| 878 | 878 |
| 879 template <typename CharType> | 879 template <typename CharType> |
| 880 static PassRefPtrWillBeRawPtr<CSSFunctionValue> parseSimpleTransformValue(CharTy
pe*& pos, CharType* end) | 880 static PassRefPtr<CSSFunctionValue> parseSimpleTransformValue(CharType*& pos, Ch
arType* end) |
| 881 { | 881 { |
| 882 static const int shortestValidTransformStringLength = 12; | 882 static const int shortestValidTransformStringLength = 12; |
| 883 | 883 |
| 884 if (end - pos < shortestValidTransformStringLength) | 884 if (end - pos < shortestValidTransformStringLength) |
| 885 return nullptr; | 885 return nullptr; |
| 886 | 886 |
| 887 const bool isTranslate = toASCIILower(pos[0]) == 't' | 887 const bool isTranslate = toASCIILower(pos[0]) == 't' |
| 888 && toASCIILower(pos[1]) == 'r' | 888 && toASCIILower(pos[1]) == 'r' |
| 889 && toASCIILower(pos[2]) == 'a' | 889 && toASCIILower(pos[2]) == 'a' |
| 890 && toASCIILower(pos[3]) == 'n' | 890 && toASCIILower(pos[3]) == 'n' |
| (...skipping 19 matching lines...) Expand all Loading... |
| 910 expectedArgumentCount = 2; | 910 expectedArgumentCount = 2; |
| 911 argumentStart = 10; | 911 argumentStart = 10; |
| 912 } else if (c9 == '3' && toASCIILower(pos[10]) == 'd' && pos[11] == '(')
{ | 912 } else if (c9 == '3' && toASCIILower(pos[10]) == 'd' && pos[11] == '(')
{ |
| 913 transformType = CSSValueTranslate3d; | 913 transformType = CSSValueTranslate3d; |
| 914 expectedArgumentCount = 3; | 914 expectedArgumentCount = 3; |
| 915 argumentStart = 12; | 915 argumentStart = 12; |
| 916 } else { | 916 } else { |
| 917 return nullptr; | 917 return nullptr; |
| 918 } | 918 } |
| 919 pos += argumentStart; | 919 pos += argumentStart; |
| 920 RefPtrWillBeRawPtr<CSSFunctionValue> transformValue = CSSFunctionValue::
create(transformType); | 920 RefPtr<CSSFunctionValue> transformValue = CSSFunctionValue::create(trans
formType); |
| 921 if (!parseTransformTranslateArguments(pos, end, expectedArgumentCount, t
ransformValue.get())) | 921 if (!parseTransformTranslateArguments(pos, end, expectedArgumentCount, t
ransformValue.get())) |
| 922 return nullptr; | 922 return nullptr; |
| 923 return transformValue.release(); | 923 return transformValue.release(); |
| 924 } | 924 } |
| 925 | 925 |
| 926 const bool isMatrix3d = toASCIILower(pos[0]) == 'm' | 926 const bool isMatrix3d = toASCIILower(pos[0]) == 'm' |
| 927 && toASCIILower(pos[1]) == 'a' | 927 && toASCIILower(pos[1]) == 'a' |
| 928 && toASCIILower(pos[2]) == 't' | 928 && toASCIILower(pos[2]) == 't' |
| 929 && toASCIILower(pos[3]) == 'r' | 929 && toASCIILower(pos[3]) == 'r' |
| 930 && toASCIILower(pos[4]) == 'i' | 930 && toASCIILower(pos[4]) == 'i' |
| 931 && toASCIILower(pos[5]) == 'x' | 931 && toASCIILower(pos[5]) == 'x' |
| 932 && pos[6] == '3' | 932 && pos[6] == '3' |
| 933 && toASCIILower(pos[7]) == 'd' | 933 && toASCIILower(pos[7]) == 'd' |
| 934 && pos[8] == '('; | 934 && pos[8] == '('; |
| 935 | 935 |
| 936 if (isMatrix3d) { | 936 if (isMatrix3d) { |
| 937 pos += 9; | 937 pos += 9; |
| 938 RefPtrWillBeRawPtr<CSSFunctionValue> transformValue = CSSFunctionValue::
create(CSSValueMatrix3d); | 938 RefPtr<CSSFunctionValue> transformValue = CSSFunctionValue::create(CSSVa
lueMatrix3d); |
| 939 if (!parseTransformNumberArguments(pos, end, 16, transformValue.get())) | 939 if (!parseTransformNumberArguments(pos, end, 16, transformValue.get())) |
| 940 return nullptr; | 940 return nullptr; |
| 941 return transformValue.release(); | 941 return transformValue.release(); |
| 942 } | 942 } |
| 943 | 943 |
| 944 const bool isScale3d = toASCIILower(pos[0]) == 's' | 944 const bool isScale3d = toASCIILower(pos[0]) == 's' |
| 945 && toASCIILower(pos[1]) == 'c' | 945 && toASCIILower(pos[1]) == 'c' |
| 946 && toASCIILower(pos[2]) == 'a' | 946 && toASCIILower(pos[2]) == 'a' |
| 947 && toASCIILower(pos[3]) == 'l' | 947 && toASCIILower(pos[3]) == 'l' |
| 948 && toASCIILower(pos[4]) == 'e' | 948 && toASCIILower(pos[4]) == 'e' |
| 949 && pos[5] == '3' | 949 && pos[5] == '3' |
| 950 && toASCIILower(pos[6]) == 'd' | 950 && toASCIILower(pos[6]) == 'd' |
| 951 && pos[7] == '('; | 951 && pos[7] == '('; |
| 952 | 952 |
| 953 if (isScale3d) { | 953 if (isScale3d) { |
| 954 pos += 8; | 954 pos += 8; |
| 955 RefPtrWillBeRawPtr<CSSFunctionValue> transformValue = CSSFunctionValue::
create(CSSValueScale3d); | 955 RefPtr<CSSFunctionValue> transformValue = CSSFunctionValue::create(CSSVa
lueScale3d); |
| 956 if (!parseTransformNumberArguments(pos, end, 3, transformValue.get())) | 956 if (!parseTransformNumberArguments(pos, end, 3, transformValue.get())) |
| 957 return nullptr; | 957 return nullptr; |
| 958 return transformValue.release(); | 958 return transformValue.release(); |
| 959 } | 959 } |
| 960 | 960 |
| 961 return nullptr; | 961 return nullptr; |
| 962 } | 962 } |
| 963 | 963 |
| 964 template <typename CharType> | 964 template <typename CharType> |
| 965 static PassRefPtrWillBeRawPtr<CSSValueList> parseSimpleTransformList(CharType*&
pos, CharType* end) | 965 static PassRefPtr<CSSValueList> parseSimpleTransformList(CharType*& pos, CharTyp
e* end) |
| 966 { | 966 { |
| 967 RefPtrWillBeRawPtr<CSSValueList> transformList = nullptr; | 967 RefPtr<CSSValueList> transformList = nullptr; |
| 968 while (pos < end) { | 968 while (pos < end) { |
| 969 while (pos < end && isCSSSpace(*pos)) | 969 while (pos < end && isCSSSpace(*pos)) |
| 970 ++pos; | 970 ++pos; |
| 971 RefPtrWillBeRawPtr<CSSFunctionValue> transformValue = parseSimpleTransfo
rmValue(pos, end); | 971 RefPtr<CSSFunctionValue> transformValue = parseSimpleTransformValue(pos,
end); |
| 972 if (!transformValue) | 972 if (!transformValue) |
| 973 return nullptr; | 973 return nullptr; |
| 974 if (!transformList) | 974 if (!transformList) |
| 975 transformList = CSSValueList::createSpaceSeparated(); | 975 transformList = CSSValueList::createSpaceSeparated(); |
| 976 transformList->append(transformValue.release()); | 976 transformList->append(transformValue.release()); |
| 977 if (pos < end) { | 977 if (pos < end) { |
| 978 if (isCSSSpace(*pos)) | 978 if (isCSSSpace(*pos)) |
| 979 return nullptr; | 979 return nullptr; |
| 980 } | 980 } |
| 981 } | 981 } |
| 982 return transformList.release(); | 982 return transformList.release(); |
| 983 } | 983 } |
| 984 | 984 |
| 985 static PassRefPtrWillBeRawPtr<CSSValue> parseSimpleTransform(CSSPropertyID prope
rtyID, const String& string) | 985 static PassRefPtr<CSSValue> parseSimpleTransform(CSSPropertyID propertyID, const
String& string) |
| 986 { | 986 { |
| 987 ASSERT(!string.isEmpty()); | 987 ASSERT(!string.isEmpty()); |
| 988 | 988 |
| 989 if (propertyID != CSSPropertyTransform) | 989 if (propertyID != CSSPropertyTransform) |
| 990 return nullptr; | 990 return nullptr; |
| 991 if (string.is8Bit()) { | 991 if (string.is8Bit()) { |
| 992 const LChar* pos = string.characters8(); | 992 const LChar* pos = string.characters8(); |
| 993 const LChar* end = pos + string.length(); | 993 const LChar* end = pos + string.length(); |
| 994 return parseSimpleTransformList(pos, end); | 994 return parseSimpleTransformList(pos, end); |
| 995 } | 995 } |
| 996 const UChar* pos = string.characters16(); | 996 const UChar* pos = string.characters16(); |
| 997 const UChar* end = pos + string.length(); | 997 const UChar* end = pos + string.length(); |
| 998 return parseSimpleTransformList(pos, end); | 998 return parseSimpleTransformList(pos, end); |
| 999 } | 999 } |
| 1000 | 1000 |
| 1001 PassRefPtrWillBeRawPtr<CSSValue> CSSParserFastPaths::maybeParseValue(CSSProperty
ID propertyID, const String& string, CSSParserMode parserMode) | 1001 PassRefPtr<CSSValue> CSSParserFastPaths::maybeParseValue(CSSPropertyID propertyI
D, const String& string, CSSParserMode parserMode) |
| 1002 { | 1002 { |
| 1003 if (RefPtrWillBeRawPtr<CSSValue> length = parseSimpleLengthValue(propertyID,
string, parserMode)) | 1003 if (RefPtr<CSSValue> length = parseSimpleLengthValue(propertyID, string, par
serMode)) |
| 1004 return length.release(); | 1004 return length.release(); |
| 1005 if (isColorPropertyID(propertyID)) | 1005 if (isColorPropertyID(propertyID)) |
| 1006 return parseColor(string, parserMode); | 1006 return parseColor(string, parserMode); |
| 1007 if (RefPtrWillBeRawPtr<CSSValue> keyword = parseKeywordValue(propertyID, str
ing)) | 1007 if (RefPtr<CSSValue> keyword = parseKeywordValue(propertyID, string)) |
| 1008 return keyword.release(); | 1008 return keyword.release(); |
| 1009 if (RefPtrWillBeRawPtr<CSSValue> transform = parseSimpleTransform(propertyID
, string)) | 1009 if (RefPtr<CSSValue> transform = parseSimpleTransform(propertyID, string)) |
| 1010 return transform.release(); | 1010 return transform.release(); |
| 1011 return nullptr; | 1011 return nullptr; |
| 1012 } | 1012 } |
| 1013 | 1013 |
| 1014 } // namespace blink | 1014 } // namespace blink |
| OLD | NEW |