static PassRefPtrWillBeRawPtr<CSSValueList> parseSimpleTransformList(CharType*& pos, CharType* end) { RefPtrWillBeRawPtr<CSSValueList> transformList = nullptr; while (pos < end) { while (pos < end && isCSSSpace(*pos)) ++pos; RefPtrWillBeRawPtr<CSSFunctionValue> transformValue = parseSimpleTransformValue(pos, end); if (!transformValue) return nullptr; if (!transformList) transformList = CSSValueList::createSpaceSeparated(); transformList->append(transformValue.release()); if (pos < end) { if (isCSSSpace(*pos)) return nullptr; } } return transformList.release(); }
static bool transformCanLikelyUseFastPath(const CharType* chars, unsigned length) { // Very fast scan that attempts to reject most transforms that couldn't // take the fast path. This avoids doing the malloc and string->double // conversions in parseSimpleTransformValue only to discard them when we // run into a transform component we don't understand. unsigned i = 0; while (i < length) { if (isCSSSpace(chars[i])) { ++i; continue; } if (length - i < kShortestValidTransformStringLength) return false; switch (toASCIILower(chars[i])) { case 't': // translate, translateX, translateY, translateZ, translate3d. if (toASCIILower(chars[i + 8]) != 'e') return false; i += 9; break; case 'm': // matrix3d. if (toASCIILower(chars[i + 7]) != 'd') return false; i += 8; break; case 's': // scale3d. if (toASCIILower(chars[i + 6]) != 'd') return false; i += 7; break; default: // All other things, ex. rotate. return false; } size_t argumentsEnd = WTF::find(chars, length, ')', i); if (argumentsEnd == kNotFound) return false; // Advance to the end of the arguments. i = argumentsEnd + 1; } return i == length; }
static CSSValueList* parseSimpleTransformList(const CharType* chars, unsigned length) { if (!transformCanLikelyUseFastPath(chars, length)) return nullptr; const CharType*& pos = chars; const CharType* end = chars + length; CSSValueList* transformList = nullptr; while (pos < end) { while (pos < end && isCSSSpace(*pos)) ++pos; if (pos >= end) break; CSSFunctionValue* transformValue = parseSimpleTransformValue(pos, end); if (!transformValue) return nullptr; if (!transformList) transformList = CSSValueList::createSpaceSeparated(); transformList->append(*transformValue); } return transformList; }