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 |