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