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