| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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/properties/CSSPropertyAPITransform.h" | 5 #include "core/css/properties/CSSPropertyAPITransform.h" |
| 6 | 6 |
| 7 #include "core/css/CSSFunctionValue.h" | 7 #include "core/css/CSSFunctionValue.h" |
| 8 #include "core/css/CSSValueList.h" | 8 #include "core/css/CSSValueList.h" |
| 9 #include "core/css/parser/CSSParserContext.h" | 9 #include "core/css/parser/CSSParserContext.h" |
| 10 #include "core/css/parser/CSSPropertyParserHelpers.h" | 10 #include "core/css/parser/CSSPropertyParserHelpers.h" |
| 11 #include "platform/Length.h" | 11 #include "platform/Length.h" |
| 12 | 12 |
| 13 namespace blink { | 13 namespace blink { |
| 14 | 14 |
| 15 using namespace CSSPropertyParserHelpers; |
| 16 |
| 15 namespace { | 17 namespace { |
| 16 | 18 |
| 17 bool ConsumeNumbers(CSSParserTokenRange& args, | 19 bool ConsumeNumbers(CSSParserTokenRange& args, |
| 18 CSSFunctionValue*& transform_value, | 20 CSSFunctionValue*& transform_value, |
| 19 unsigned number_of_arguments) { | 21 unsigned number_of_arguments) { |
| 20 do { | 22 do { |
| 21 CSSValue* parsed_value = | 23 CSSValue* parsed_value = ConsumeNumber(args, kValueRangeAll); |
| 22 CSSPropertyParserHelpers::ConsumeNumber(args, kValueRangeAll); | |
| 23 if (!parsed_value) | 24 if (!parsed_value) |
| 24 return false; | 25 return false; |
| 25 transform_value->Append(*parsed_value); | 26 transform_value->Append(*parsed_value); |
| 26 if (--number_of_arguments && | 27 if (--number_of_arguments && !ConsumeCommaIncludingWhitespace(args)) { |
| 27 !CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args)) { | |
| 28 return false; | 28 return false; |
| 29 } | 29 } |
| 30 } while (number_of_arguments); | 30 } while (number_of_arguments); |
| 31 return true; | 31 return true; |
| 32 } | 32 } |
| 33 | 33 |
| 34 bool ConsumePerspective(CSSParserTokenRange& args, | 34 bool ConsumePerspective(CSSParserTokenRange& args, |
| 35 const CSSParserContext* context, | 35 const CSSParserContext* context, |
| 36 CSSFunctionValue*& transform_value, | 36 CSSFunctionValue*& transform_value, |
| 37 bool use_legacy_parsing) { | 37 bool use_legacy_parsing) { |
| 38 CSSPrimitiveValue* parsed_value = CSSPropertyParserHelpers::ConsumeLength( | 38 CSSPrimitiveValue* parsed_value = |
| 39 args, context->Mode(), kValueRangeNonNegative); | 39 ConsumeLength(args, context->Mode(), kValueRangeNonNegative); |
| 40 if (!parsed_value && use_legacy_parsing) { | 40 if (!parsed_value && use_legacy_parsing) { |
| 41 double perspective; | 41 double perspective; |
| 42 if (!CSSPropertyParserHelpers::ConsumeNumberRaw(args, perspective) || | 42 if (!ConsumeNumberRaw(args, perspective) || perspective < 0) { |
| 43 perspective < 0) { | |
| 44 return false; | 43 return false; |
| 45 } | 44 } |
| 46 context->Count(UseCounter::kUnitlessPerspectiveInTransformProperty); | 45 context->Count(UseCounter::kUnitlessPerspectiveInTransformProperty); |
| 47 parsed_value = CSSPrimitiveValue::Create( | 46 parsed_value = CSSPrimitiveValue::Create( |
| 48 perspective, CSSPrimitiveValue::UnitType::kPixels); | 47 perspective, CSSPrimitiveValue::UnitType::kPixels); |
| 49 } | 48 } |
| 50 if (!parsed_value) | 49 if (!parsed_value) |
| 51 return false; | 50 return false; |
| 52 transform_value->Append(*parsed_value); | 51 transform_value->Append(*parsed_value); |
| 53 return true; | 52 return true; |
| 54 } | 53 } |
| 55 | 54 |
| 56 bool ConsumeTranslate3d(CSSParserTokenRange& args, | 55 bool ConsumeTranslate3d(CSSParserTokenRange& args, |
| 57 CSSParserMode css_parser_mode, | 56 CSSParserMode css_parser_mode, |
| 58 CSSFunctionValue*& transform_value) { | 57 CSSFunctionValue*& transform_value) { |
| 59 unsigned number_of_arguments = 2; | 58 unsigned number_of_arguments = 2; |
| 60 CSSValue* parsed_value = nullptr; | 59 CSSValue* parsed_value = nullptr; |
| 61 do { | 60 do { |
| 62 parsed_value = CSSPropertyParserHelpers::ConsumeLengthOrPercent( | 61 parsed_value = |
| 63 args, css_parser_mode, kValueRangeAll); | 62 ConsumeLengthOrPercent(args, css_parser_mode, kValueRangeAll); |
| 64 if (!parsed_value) | 63 if (!parsed_value) |
| 65 return false; | 64 return false; |
| 66 transform_value->Append(*parsed_value); | 65 transform_value->Append(*parsed_value); |
| 67 if (!CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args)) | 66 if (!ConsumeCommaIncludingWhitespace(args)) |
| 68 return false; | 67 return false; |
| 69 } while (--number_of_arguments); | 68 } while (--number_of_arguments); |
| 70 parsed_value = CSSPropertyParserHelpers::ConsumeLength(args, css_parser_mode, | 69 parsed_value = ConsumeLength(args, css_parser_mode, kValueRangeAll); |
| 71 kValueRangeAll); | |
| 72 if (!parsed_value) | 70 if (!parsed_value) |
| 73 return false; | 71 return false; |
| 74 transform_value->Append(*parsed_value); | 72 transform_value->Append(*parsed_value); |
| 75 return true; | 73 return true; |
| 76 } | 74 } |
| 77 | 75 |
| 78 CSSValue* ConsumeTransformValue(CSSParserTokenRange& range, | 76 CSSValue* ConsumeTransformValue(CSSParserTokenRange& range, |
| 79 const CSSParserContext* context, | 77 const CSSParserContext* context, |
| 80 bool use_legacy_parsing) { | 78 bool use_legacy_parsing) { |
| 81 CSSValueID function_id = range.Peek().FunctionId(); | 79 CSSValueID function_id = range.Peek().FunctionId(); |
| 82 if (function_id == CSSValueInvalid) | 80 if (function_id == CSSValueInvalid) |
| 83 return nullptr; | 81 return nullptr; |
| 84 CSSParserTokenRange args = CSSPropertyParserHelpers::ConsumeFunction(range); | 82 CSSParserTokenRange args = ConsumeFunction(range); |
| 85 if (args.AtEnd()) | 83 if (args.AtEnd()) |
| 86 return nullptr; | 84 return nullptr; |
| 87 CSSFunctionValue* transform_value = CSSFunctionValue::Create(function_id); | 85 CSSFunctionValue* transform_value = CSSFunctionValue::Create(function_id); |
| 88 CSSValue* parsed_value = nullptr; | 86 CSSValue* parsed_value = nullptr; |
| 89 switch (function_id) { | 87 switch (function_id) { |
| 90 case CSSValueRotate: | 88 case CSSValueRotate: |
| 91 case CSSValueRotateX: | 89 case CSSValueRotateX: |
| 92 case CSSValueRotateY: | 90 case CSSValueRotateY: |
| 93 case CSSValueRotateZ: | 91 case CSSValueRotateZ: |
| 94 case CSSValueSkewX: | 92 case CSSValueSkewX: |
| 95 case CSSValueSkewY: | 93 case CSSValueSkewY: |
| 96 case CSSValueSkew: | 94 case CSSValueSkew: |
| 97 parsed_value = CSSPropertyParserHelpers::ConsumeAngle(args); | 95 parsed_value = ConsumeAngle(args, *context, UnitlessQuirk::kAllow, |
| 96 UseCounter::kZeroAngleTransform); |
| 98 if (!parsed_value) | 97 if (!parsed_value) |
| 99 return nullptr; | 98 return nullptr; |
| 100 if (function_id == CSSValueSkew && | 99 if (function_id == CSSValueSkew && |
| 101 CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args)) { | 100 ConsumeCommaIncludingWhitespace(args)) { |
| 102 transform_value->Append(*parsed_value); | 101 transform_value->Append(*parsed_value); |
| 103 parsed_value = CSSPropertyParserHelpers::ConsumeAngle(args); | 102 parsed_value = ConsumeAngle(args, *context, UnitlessQuirk::kAllow, |
| 103 UseCounter::kZeroAngleTransform); |
| 104 if (!parsed_value) | 104 if (!parsed_value) |
| 105 return nullptr; | 105 return nullptr; |
| 106 } | 106 } |
| 107 break; | 107 break; |
| 108 case CSSValueScaleX: | 108 case CSSValueScaleX: |
| 109 case CSSValueScaleY: | 109 case CSSValueScaleY: |
| 110 case CSSValueScaleZ: | 110 case CSSValueScaleZ: |
| 111 case CSSValueScale: | 111 case CSSValueScale: |
| 112 parsed_value = | 112 parsed_value = ConsumeNumber(args, kValueRangeAll); |
| 113 CSSPropertyParserHelpers::ConsumeNumber(args, kValueRangeAll); | |
| 114 if (!parsed_value) | 113 if (!parsed_value) |
| 115 return nullptr; | 114 return nullptr; |
| 116 if (function_id == CSSValueScale && | 115 if (function_id == CSSValueScale && |
| 117 CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args)) { | 116 ConsumeCommaIncludingWhitespace(args)) { |
| 118 transform_value->Append(*parsed_value); | 117 transform_value->Append(*parsed_value); |
| 119 parsed_value = | 118 parsed_value = ConsumeNumber(args, kValueRangeAll); |
| 120 CSSPropertyParserHelpers::ConsumeNumber(args, kValueRangeAll); | |
| 121 if (!parsed_value) | 119 if (!parsed_value) |
| 122 return nullptr; | 120 return nullptr; |
| 123 } | 121 } |
| 124 break; | 122 break; |
| 125 case CSSValuePerspective: | 123 case CSSValuePerspective: |
| 126 if (!ConsumePerspective(args, context, transform_value, | 124 if (!ConsumePerspective(args, context, transform_value, |
| 127 use_legacy_parsing)) { | 125 use_legacy_parsing)) { |
| 128 return nullptr; | 126 return nullptr; |
| 129 } | 127 } |
| 130 break; | 128 break; |
| 131 case CSSValueTranslateX: | 129 case CSSValueTranslateX: |
| 132 case CSSValueTranslateY: | 130 case CSSValueTranslateY: |
| 133 case CSSValueTranslate: | 131 case CSSValueTranslate: |
| 134 parsed_value = CSSPropertyParserHelpers::ConsumeLengthOrPercent( | 132 parsed_value = |
| 135 args, context->Mode(), kValueRangeAll); | 133 ConsumeLengthOrPercent(args, context->Mode(), kValueRangeAll); |
| 136 if (!parsed_value) | 134 if (!parsed_value) |
| 137 return nullptr; | 135 return nullptr; |
| 138 if (function_id == CSSValueTranslate && | 136 if (function_id == CSSValueTranslate && |
| 139 CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args)) { | 137 ConsumeCommaIncludingWhitespace(args)) { |
| 140 transform_value->Append(*parsed_value); | 138 transform_value->Append(*parsed_value); |
| 141 parsed_value = CSSPropertyParserHelpers::ConsumeLengthOrPercent( | 139 parsed_value = |
| 142 args, context->Mode(), kValueRangeAll); | 140 ConsumeLengthOrPercent(args, context->Mode(), kValueRangeAll); |
| 143 if (!parsed_value) | 141 if (!parsed_value) |
| 144 return nullptr; | 142 return nullptr; |
| 145 } | 143 } |
| 146 break; | 144 break; |
| 147 case CSSValueTranslateZ: | 145 case CSSValueTranslateZ: |
| 148 parsed_value = CSSPropertyParserHelpers::ConsumeLength( | 146 parsed_value = ConsumeLength(args, context->Mode(), kValueRangeAll); |
| 149 args, context->Mode(), kValueRangeAll); | |
| 150 break; | 147 break; |
| 151 case CSSValueMatrix: | 148 case CSSValueMatrix: |
| 152 case CSSValueMatrix3d: | 149 case CSSValueMatrix3d: |
| 153 if (!ConsumeNumbers(args, transform_value, | 150 if (!ConsumeNumbers(args, transform_value, |
| 154 (function_id == CSSValueMatrix3d) ? 16 : 6)) { | 151 (function_id == CSSValueMatrix3d) ? 16 : 6)) { |
| 155 return nullptr; | 152 return nullptr; |
| 156 } | 153 } |
| 157 break; | 154 break; |
| 158 case CSSValueScale3d: | 155 case CSSValueScale3d: |
| 159 if (!ConsumeNumbers(args, transform_value, 3)) | 156 if (!ConsumeNumbers(args, transform_value, 3)) |
| 160 return nullptr; | 157 return nullptr; |
| 161 break; | 158 break; |
| 162 case CSSValueRotate3d: | 159 case CSSValueRotate3d: |
| 163 if (!ConsumeNumbers(args, transform_value, 3) || | 160 if (!ConsumeNumbers(args, transform_value, 3) || |
| 164 !CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args)) { | 161 !ConsumeCommaIncludingWhitespace(args)) { |
| 165 return nullptr; | 162 return nullptr; |
| 166 } | 163 } |
| 167 parsed_value = CSSPropertyParserHelpers::ConsumeAngle(args); | 164 parsed_value = ConsumeAngle(args, *context, UnitlessQuirk::kAllow, |
| 165 UseCounter::kZeroAngleTransform); |
| 168 if (!parsed_value) | 166 if (!parsed_value) |
| 169 return nullptr; | 167 return nullptr; |
| 170 break; | 168 break; |
| 171 case CSSValueTranslate3d: | 169 case CSSValueTranslate3d: |
| 172 if (!ConsumeTranslate3d(args, context->Mode(), transform_value)) | 170 if (!ConsumeTranslate3d(args, context->Mode(), transform_value)) |
| 173 return nullptr; | 171 return nullptr; |
| 174 break; | 172 break; |
| 175 default: | 173 default: |
| 176 return nullptr; | 174 return nullptr; |
| 177 } | 175 } |
| 178 if (parsed_value) | 176 if (parsed_value) |
| 179 transform_value->Append(*parsed_value); | 177 transform_value->Append(*parsed_value); |
| 180 if (!args.AtEnd()) | 178 if (!args.AtEnd()) |
| 181 return nullptr; | 179 return nullptr; |
| 182 return transform_value; | 180 return transform_value; |
| 183 } | 181 } |
| 184 | 182 |
| 185 } // namespace | 183 } // namespace |
| 186 | 184 |
| 187 const CSSValue* CSSPropertyAPITransform::parseSingleValue( | 185 const CSSValue* CSSPropertyAPITransform::parseSingleValue( |
| 188 CSSParserTokenRange& range, | 186 CSSParserTokenRange& range, |
| 189 const CSSParserContext& context, | 187 const CSSParserContext& context, |
| 190 CSSPropertyID unresolved_property) { | 188 CSSPropertyID unresolved_property) { |
| 191 if (range.Peek().Id() == CSSValueNone) | 189 if (range.Peek().Id() == CSSValueNone) |
| 192 return CSSPropertyParserHelpers::ConsumeIdent(range); | 190 return ConsumeIdent(range); |
| 193 | 191 |
| 194 CSSValueList* list = CSSValueList::CreateSpaceSeparated(); | 192 CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| 195 do { | 193 do { |
| 196 CSSValue* parsed_transform_value = ConsumeTransformValue( | 194 CSSValue* parsed_transform_value = ConsumeTransformValue( |
| 197 range, &context, | 195 range, &context, |
| 198 unresolved_property == CSSPropertyAliasWebkitTransform); | 196 unresolved_property == CSSPropertyAliasWebkitTransform); |
| 199 if (!parsed_transform_value) | 197 if (!parsed_transform_value) |
| 200 return nullptr; | 198 return nullptr; |
| 201 list->Append(*parsed_transform_value); | 199 list->Append(*parsed_transform_value); |
| 202 } while (!range.AtEnd()); | 200 } while (!range.AtEnd()); |
| 203 | 201 |
| 204 return list; | 202 return list; |
| 205 } | 203 } |
| 206 | 204 |
| 207 } // namespace blink | 205 } // namespace blink |
| OLD | NEW |