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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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) { |
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 DCHECK(CSSLengthValue::isSupportedLengthUnit(unit)); |
| 154 std::unique_ptr<UnitData> result(new UnitData()); |
| 155 result->set(unit, expressionNode->doubleValue()); |
| 156 return result; |
| 157 } |
| 158 |
| 159 const CSSCalcExpressionNode* left = expressionNode->leftExpressionNode(); |
| 160 const CSSCalcExpressionNode* right = expressionNode->rightExpressionNode(); |
| 161 CalcOperator op = expressionNode->operatorType(); |
| 162 |
| 163 if (op == CalcMultiply) { |
| 164 std::unique_ptr<UnitData> unitData = nullptr; |
| 165 double argument = 0; |
| 166 // One side should be a number. |
| 167 if (left->category() == CalculationCategory::CalcNumber) { |
| 168 unitData = UnitData::fromExpressionNode(right); |
| 169 argument = left->doubleValue(); |
| 170 } else if (right->category() == CalculationCategory::CalcNumber) { |
| 171 unitData = UnitData::fromExpressionNode(left); |
| 172 argument = right->doubleValue(); |
| 173 } else { |
| 174 NOTREACHED(); |
| 175 return nullptr; |
| 176 } |
| 177 DCHECK(unitData); |
| 178 unitData->multiply(argument); |
| 179 return unitData; |
| 180 } |
| 181 |
| 182 if (op == CalcDivide) { |
| 183 // Divisor must always be on the RHS. |
| 184 DCHECK_EQ(right->category(), CalculationCategory::CalcNumber); |
| 185 std::unique_ptr<UnitData> unitData = UnitData::fromExpressionNode(left); |
| 186 DCHECK(unitData); |
| 187 unitData->divide(right->doubleValue()); |
| 188 return unitData; |
| 189 } |
| 190 |
| 191 // Add and subtract. |
| 192 std::unique_ptr<UnitData> leftUnitData = UnitData::fromExpressionNode(left); |
| 193 std::unique_ptr<UnitData> rightUnitData = UnitData::fromExpressionNode(right); |
| 194 DCHECK(leftUnitData); |
| 195 DCHECK(rightUnitData); |
| 196 |
| 197 if (op == CalcAdd) |
| 198 leftUnitData->add(*rightUnitData); |
| 199 else if (op == CalcSubtract) |
| 200 leftUnitData->subtract(*rightUnitData); |
| 201 else |
| 202 NOTREACHED(); |
| 203 |
| 204 return leftUnitData; |
145 } | 205 } |
146 | 206 |
147 CSSCalcExpressionNode* CSSCalcLength::UnitData::toCSSCalcExpressionNode() | 207 CSSCalcExpressionNode* CSSCalcLength::UnitData::toCSSCalcExpressionNode() |
148 const { | 208 const { |
149 CSSCalcExpressionNode* node = nullptr; | 209 CSSCalcExpressionNode* node = nullptr; |
150 for (unsigned i = 0; i < CSSLengthValue::kNumSupportedUnits; ++i) { | 210 for (unsigned i = 0; i < CSSLengthValue::kNumSupportedUnits; ++i) { |
151 if (!hasAtIndex(i)) | 211 if (!hasAtIndex(i)) |
152 continue; | 212 continue; |
153 double value = getAtIndex(i); | 213 double value = getAtIndex(i); |
154 if (node) { | 214 if (node) { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 void CSSCalcLength::UnitData::divide(double x) { | 283 void CSSCalcLength::UnitData::divide(double x) { |
224 DCHECK_NE(x, 0); | 284 DCHECK_NE(x, 0); |
225 for (int i = 0; i < CSSLengthValue::kNumSupportedUnits; ++i) { | 285 for (int i = 0; i < CSSLengthValue::kNumSupportedUnits; ++i) { |
226 if (hasAtIndex(i)) { | 286 if (hasAtIndex(i)) { |
227 setAtIndex(i, getAtIndex(i) / x); | 287 setAtIndex(i, getAtIndex(i) / x); |
228 } | 288 } |
229 } | 289 } |
230 } | 290 } |
231 | 291 |
232 } // namespace blink | 292 } // namespace blink |
OLD | NEW |