OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/cssom/CSSCalcLength.h" | 5 #include "core/css/cssom/CSSCalcLength.h" |
6 | 6 |
7 #include "bindings/core/v8/ExceptionState.h" | 7 #include "bindings/core/v8/ExceptionState.h" |
8 #include "core/css/CSSCalculationValue.h" | 8 #include "core/css/CSSCalculationValue.h" |
9 #include "core/css/CSSPrimitiveValue.h" | 9 #include "core/css/CSSPrimitiveValue.h" |
10 #include "core/css/cssom/CSSCalcDictionary.h" | 10 #include "core/css/cssom/CSSCalcDictionary.h" |
11 #include "core/css/cssom/CSSSimpleLength.h" | 11 #include "core/css/cssom/CSSSimpleLength.h" |
12 #include "wtf/Vector.h" | 12 #include "wtf/Vector.h" |
13 | 13 |
14 namespace blink { | 14 namespace blink { |
15 | 15 |
16 namespace { | 16 namespace { |
17 | 17 |
18 static CSSPrimitiveValue::UnitType unitFromIndex(int index) { | 18 static CSSPrimitiveValue::UnitType unitFromIndex(int index) { |
19 DCHECK(index < CSSLengthValue::kNumSupportedUnits); | |
19 int lowestValue = static_cast<int>(CSSPrimitiveValue::UnitType::Percentage); | 20 int lowestValue = static_cast<int>(CSSPrimitiveValue::UnitType::Percentage); |
20 return static_cast<CSSPrimitiveValue::UnitType>(index + lowestValue); | 21 return static_cast<CSSPrimitiveValue::UnitType>(index + lowestValue); |
21 } | 22 } |
22 | 23 |
23 int indexForUnit(CSSPrimitiveValue::UnitType unit) { | 24 int indexForUnit(CSSPrimitiveValue::UnitType unit) { |
24 return (static_cast<int>(unit) - | 25 return (static_cast<int>(unit) - |
25 static_cast<int>(CSSPrimitiveValue::UnitType::Percentage)); | 26 static_cast<int>(CSSPrimitiveValue::UnitType::Percentage)); |
26 } | 27 } |
27 | 28 |
28 } // namespace | 29 } // namespace |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
133 | 134 |
134 CSSValue* CSSCalcLength::toCSSValue() const { | 135 CSSValue* CSSCalcLength::toCSSValue() const { |
135 CSSCalcExpressionNode* node = m_unitData.toCSSCalcExpressionNode(); | 136 CSSCalcExpressionNode* node = m_unitData.toCSSCalcExpressionNode(); |
136 if (node) | 137 if (node) |
137 return CSSPrimitiveValue::create(CSSCalcValue::create(node)); | 138 return CSSPrimitiveValue::create(CSSCalcValue::create(node)); |
138 return nullptr; | 139 return nullptr; |
139 } | 140 } |
140 | 141 |
141 std::unique_ptr<CSSCalcLength::UnitData> | 142 std::unique_ptr<CSSCalcLength::UnitData> |
142 CSSCalcLength::UnitData::fromExpressionNode( | 143 CSSCalcLength::UnitData::fromExpressionNode( |
143 const CSSCalcExpressionNode* expressionNode) { | 144 const CSSCalcExpressionNode* expressionNode) { |
alancutter (OOO until 2018)
2016/10/13 22:19:05
This UnitData type would be a great representation
meade_UTC10
2016/11/16 19:28:21
I agree, but I don't want to block typed om on ref
| |
144 return nullptr; | 145 CalculationCategory category = expressionNode->category(); |
146 DCHECK(category == CalculationCategory::CalcLength || | |
147 category == CalculationCategory::CalcPercentLength || | |
148 category == CalculationCategory::CalcPercent); | |
149 | |
150 if (expressionNode->getType() == | |
151 CSSCalcExpressionNode::Type::CssCalcPrimitiveValue) { | |
152 CSSPrimitiveValue::UnitType unit = expressionNode->typeWithCalcResolved(); | |
153 if (!CSSLengthValue::isSupportedLengthUnit(unit)) { | |
154 return nullptr; | |
155 } | |
156 std::unique_ptr<UnitData> result(new UnitData()); | |
157 result->set(unit, expressionNode->doubleValue()); | |
158 return result; | |
159 } | |
160 | |
161 const CSSCalcExpressionNode* left = expressionNode->leftExpressionNode(); | |
162 const CSSCalcExpressionNode* right = expressionNode->rightExpressionNode(); | |
163 CalcOperator op = expressionNode->operatorType(); | |
164 | |
165 if (op == CalcMultiply) { | |
166 std::unique_ptr<UnitData> unitData = nullptr; | |
167 double argument = 0; | |
168 // One side should be a number. | |
169 if (left->category() == CalculationCategory::CalcNumber) { | |
170 unitData = UnitData::fromExpressionNode(right); | |
171 argument = left->doubleValue(); | |
172 } else if (right->category() == CalculationCategory::CalcNumber) { | |
173 unitData = UnitData::fromExpressionNode(left); | |
174 argument = right->doubleValue(); | |
175 } else { | |
176 return nullptr; | |
177 } | |
178 if (!unitData) | |
179 return nullptr; | |
180 unitData->multiply(argument); | |
181 return unitData; | |
182 } | |
183 | |
184 if (op == CalcDivide) { | |
185 // Divisor must always be on the RHS. | |
186 if (right->category() != CalculationCategory::CalcNumber) | |
187 return nullptr; | |
188 std::unique_ptr<UnitData> unitData = UnitData::fromExpressionNode(left); | |
189 if (!unitData) | |
190 return nullptr; | |
191 unitData->divide(right->doubleValue()); | |
192 return unitData; | |
193 } | |
194 | |
195 // Add and subtract. | |
196 std::unique_ptr<UnitData> leftUnitData = UnitData::fromExpressionNode(left); | |
197 std::unique_ptr<UnitData> rightUnitData = UnitData::fromExpressionNode(right); | |
198 if (!leftUnitData || !rightUnitData) { | |
199 return nullptr; | |
200 } | |
201 | |
202 if (op == CalcAdd) | |
203 leftUnitData->add(*rightUnitData); | |
204 else if (op == CalcSubtract) | |
205 leftUnitData->subtract(*rightUnitData); | |
206 else | |
207 NOTREACHED(); | |
208 | |
209 return leftUnitData; | |
145 } | 210 } |
146 | 211 |
147 CSSCalcExpressionNode* CSSCalcLength::UnitData::toCSSCalcExpressionNode() | 212 CSSCalcExpressionNode* CSSCalcLength::UnitData::toCSSCalcExpressionNode() |
148 const { | 213 const { |
149 CSSCalcExpressionNode* node = nullptr; | 214 CSSCalcExpressionNode* node = nullptr; |
150 for (unsigned i = 0; i < CSSLengthValue::kNumSupportedUnits; ++i) { | 215 for (unsigned i = 0; i < CSSLengthValue::kNumSupportedUnits; ++i) { |
151 if (!hasAtIndex(i)) | 216 if (!hasAtIndex(i)) |
152 continue; | 217 continue; |
153 double value = getAtIndex(i); | 218 double value = getAtIndex(i); |
154 if (node) { | 219 if (node) { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
223 void CSSCalcLength::UnitData::divide(double x) { | 288 void CSSCalcLength::UnitData::divide(double x) { |
224 DCHECK_NE(x, 0); | 289 DCHECK_NE(x, 0); |
225 for (int i = 0; i < CSSLengthValue::kNumSupportedUnits; ++i) { | 290 for (int i = 0; i < CSSLengthValue::kNumSupportedUnits; ++i) { |
226 if (hasAtIndex(i)) { | 291 if (hasAtIndex(i)) { |
227 setAtIndex(i, getAtIndex(i) / x); | 292 setAtIndex(i, getAtIndex(i) / x); |
228 } | 293 } |
229 } | 294 } |
230 } | 295 } |
231 | 296 |
232 } // namespace blink | 297 } // namespace blink |
OLD | NEW |