Chromium Code Reviews| 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 |