| 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 "core/css/parser/CSSParserFastPaths.h" | 5 #include "core/css/parser/CSSParserFastPaths.h" |
| 6 | 6 |
| 7 #include "core/StylePropertyShorthand.h" | 7 #include "core/StylePropertyShorthand.h" |
| 8 #include "core/css/CSSFunctionValue.h" | 8 #include "core/css/CSSFunctionValue.h" |
| 9 #include "core/css/CSSValuePool.h" | 9 #include "core/css/CSSValuePool.h" |
| 10 #include "core/css/parser/CSSParserIdioms.h" | 10 #include "core/css/parser/CSSParserIdioms.h" |
| (...skipping 883 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 894 double number = charactersToDouble(pos, argumentLength, &ok); | 894 double number = charactersToDouble(pos, argumentLength, &ok); |
| 895 if (!ok) | 895 if (!ok) |
| 896 return false; | 896 return false; |
| 897 transformValue->append(cssValuePool().createValue(number, CSSPrimitiveVa
lue::UnitType::Number)); | 897 transformValue->append(cssValuePool().createValue(number, CSSPrimitiveVa
lue::UnitType::Number)); |
| 898 pos += argumentLength + 1; | 898 pos += argumentLength + 1; |
| 899 --expectedCount; | 899 --expectedCount; |
| 900 } | 900 } |
| 901 return true; | 901 return true; |
| 902 } | 902 } |
| 903 | 903 |
| 904 static const int kShortestValidTransformStringLength = 12; | |
| 905 | |
| 906 template <typename CharType> | 904 template <typename CharType> |
| 907 static CSSFunctionValue* parseSimpleTransformValue(CharType*& pos, CharType* end
) | 905 static CSSFunctionValue* parseSimpleTransformValue(CharType*& pos, CharType* end
) |
| 908 { | 906 { |
| 909 if (end - pos < kShortestValidTransformStringLength) | 907 static const int shortestValidTransformStringLength = 12; |
| 908 |
| 909 if (end - pos < shortestValidTransformStringLength) |
| 910 return nullptr; | 910 return nullptr; |
| 911 | 911 |
| 912 const bool isTranslate = toASCIILower(pos[0]) == 't' | 912 const bool isTranslate = toASCIILower(pos[0]) == 't' |
| 913 && toASCIILower(pos[1]) == 'r' | 913 && toASCIILower(pos[1]) == 'r' |
| 914 && toASCIILower(pos[2]) == 'a' | 914 && toASCIILower(pos[2]) == 'a' |
| 915 && toASCIILower(pos[3]) == 'n' | 915 && toASCIILower(pos[3]) == 'n' |
| 916 && toASCIILower(pos[4]) == 's' | 916 && toASCIILower(pos[4]) == 's' |
| 917 && toASCIILower(pos[5]) == 'l' | 917 && toASCIILower(pos[5]) == 'l' |
| 918 && toASCIILower(pos[6]) == 'a' | 918 && toASCIILower(pos[6]) == 'a' |
| 919 && toASCIILower(pos[7]) == 't' | 919 && toASCIILower(pos[7]) == 't' |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 980 CSSFunctionValue* transformValue = CSSFunctionValue::create(CSSValueScal
e3d); | 980 CSSFunctionValue* transformValue = CSSFunctionValue::create(CSSValueScal
e3d); |
| 981 if (!parseTransformNumberArguments(pos, end, 3, transformValue)) | 981 if (!parseTransformNumberArguments(pos, end, 3, transformValue)) |
| 982 return nullptr; | 982 return nullptr; |
| 983 return transformValue; | 983 return transformValue; |
| 984 } | 984 } |
| 985 | 985 |
| 986 return nullptr; | 986 return nullptr; |
| 987 } | 987 } |
| 988 | 988 |
| 989 template <typename CharType> | 989 template <typename CharType> |
| 990 static bool transformCanLikelyUseFastPath(const CharType* chars, unsigned length
) | 990 static CSSValueList* parseSimpleTransformList(CharType*& pos, CharType* end) |
| 991 { | 991 { |
| 992 // Very fast scan that attempts to reject most transforms that couldn't | |
| 993 // take the fast path. This avoids doing the malloc and string->double | |
| 994 // conversions in parseSimpleTransformValue only to discard them when we | |
| 995 // run into a transform component we don't understand. | |
| 996 unsigned i = 0; | |
| 997 while (i < length) { | |
| 998 if (isCSSSpace(chars[i])) { | |
| 999 ++i; | |
| 1000 continue; | |
| 1001 } | |
| 1002 if (length - i < kShortestValidTransformStringLength) | |
| 1003 return false; | |
| 1004 switch (toASCIILower(chars[i])) { | |
| 1005 case 't': | |
| 1006 // translate, translateX, translateY, translateZ, translate3d. | |
| 1007 if (toASCIILower(chars[i + 8]) != 'e') | |
| 1008 return false; | |
| 1009 i += 9; | |
| 1010 break; | |
| 1011 case 'm': | |
| 1012 // matrix3d. | |
| 1013 if (toASCIILower(chars[i + 7]) != 'd') | |
| 1014 return false; | |
| 1015 i += 8; | |
| 1016 break; | |
| 1017 case 's': | |
| 1018 // scale3d. | |
| 1019 if (toASCIILower(chars[i + 6]) != 'd') | |
| 1020 return false; | |
| 1021 i += 7; | |
| 1022 break; | |
| 1023 default: | |
| 1024 // All other things, ex. rotate. | |
| 1025 return false; | |
| 1026 } | |
| 1027 // Advance to the end of the arguments. | |
| 1028 i = WTF::find(chars, length, ')', i) + 1; | |
| 1029 } | |
| 1030 return i == length; | |
| 1031 } | |
| 1032 | |
| 1033 template <typename CharType> | |
| 1034 static CSSValueList* parseSimpleTransformList(const CharType* chars, unsigned le
ngth) | |
| 1035 { | |
| 1036 if (!transformCanLikelyUseFastPath(chars, length)) | |
| 1037 return nullptr; | |
| 1038 const CharType*& pos = chars; | |
| 1039 const CharType* end = chars + length; | |
| 1040 CSSValueList* transformList = nullptr; | 992 CSSValueList* transformList = nullptr; |
| 1041 while (pos < end) { | 993 while (pos < end) { |
| 1042 while (pos < end && isCSSSpace(*pos)) | 994 while (pos < end && isCSSSpace(*pos)) |
| 1043 ++pos; | 995 ++pos; |
| 1044 if (pos >= end) | 996 if (pos >= end) |
| 1045 break; | 997 break; |
| 1046 CSSFunctionValue* transformValue = parseSimpleTransformValue(pos, end); | 998 CSSFunctionValue* transformValue = parseSimpleTransformValue(pos, end); |
| 1047 if (!transformValue) | 999 if (!transformValue) |
| 1048 return nullptr; | 1000 return nullptr; |
| 1049 if (!transformList) | 1001 if (!transformList) |
| 1050 transformList = CSSValueList::createSpaceSeparated(); | 1002 transformList = CSSValueList::createSpaceSeparated(); |
| 1051 transformList->append(transformValue); | 1003 transformList->append(transformValue); |
| 1052 } | 1004 } |
| 1053 return transformList; | 1005 return transformList; |
| 1054 } | 1006 } |
| 1055 | 1007 |
| 1056 static CSSValue* parseSimpleTransform(CSSPropertyID propertyID, const String& st
ring) | 1008 static CSSValue* parseSimpleTransform(CSSPropertyID propertyID, const String& st
ring) |
| 1057 { | 1009 { |
| 1058 ASSERT(!string.isEmpty()); | 1010 ASSERT(!string.isEmpty()); |
| 1059 | 1011 |
| 1060 if (propertyID != CSSPropertyTransform) | 1012 if (propertyID != CSSPropertyTransform) |
| 1061 return nullptr; | 1013 return nullptr; |
| 1062 if (string.is8Bit()) | 1014 if (string.is8Bit()) { |
| 1063 return parseSimpleTransformList(string.characters8(), string.length()); | 1015 const LChar* pos = string.characters8(); |
| 1064 return parseSimpleTransformList(string.characters16(), string.length()); | 1016 const LChar* end = pos + string.length(); |
| 1017 return parseSimpleTransformList(pos, end); |
| 1018 } |
| 1019 const UChar* pos = string.characters16(); |
| 1020 const UChar* end = pos + string.length(); |
| 1021 return parseSimpleTransformList(pos, end); |
| 1065 } | 1022 } |
| 1066 | 1023 |
| 1067 CSSValue* CSSParserFastPaths::maybeParseValue(CSSPropertyID propertyID, const St
ring& string, CSSParserMode parserMode) | 1024 CSSValue* CSSParserFastPaths::maybeParseValue(CSSPropertyID propertyID, const St
ring& string, CSSParserMode parserMode) |
| 1068 { | 1025 { |
| 1069 if (CSSValue* length = parseSimpleLengthValue(propertyID, string, parserMode
)) | 1026 if (CSSValue* length = parseSimpleLengthValue(propertyID, string, parserMode
)) |
| 1070 return length; | 1027 return length; |
| 1071 if (isColorPropertyID(propertyID)) | 1028 if (isColorPropertyID(propertyID)) |
| 1072 return parseColor(string, parserMode); | 1029 return parseColor(string, parserMode); |
| 1073 if (CSSValue* keyword = parseKeywordValue(propertyID, string, parserMode)) | 1030 if (CSSValue* keyword = parseKeywordValue(propertyID, string, parserMode)) |
| 1074 return keyword; | 1031 return keyword; |
| 1075 if (CSSValue* transform = parseSimpleTransform(propertyID, string)) | 1032 if (CSSValue* transform = parseSimpleTransform(propertyID, string)) |
| 1076 return transform; | 1033 return transform; |
| 1077 return nullptr; | 1034 return nullptr; |
| 1078 } | 1035 } |
| 1079 | 1036 |
| 1080 } // namespace blink | 1037 } // namespace blink |
| OLD | NEW |