Index: third_party/WebKit/Source/core/css/cssom/CSSCalcLength.cpp |
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSCalcLength.cpp b/third_party/WebKit/Source/core/css/cssom/CSSCalcLength.cpp |
index c574e2166a332e2469785132ffbecdddee114a7d..2a3920bf1178acd57279c6ece8145cd6845e2cfd 100644 |
--- a/third_party/WebKit/Source/core/css/cssom/CSSCalcLength.cpp |
+++ b/third_party/WebKit/Source/core/css/cssom/CSSCalcLength.cpp |
@@ -16,6 +16,7 @@ namespace blink { |
namespace { |
static CSSPrimitiveValue::UnitType unitFromIndex(int index) { |
+ DCHECK(index < CSSLengthValue::kNumSupportedUnits); |
int lowestValue = static_cast<int>(CSSPrimitiveValue::UnitType::Percentage); |
return static_cast<CSSPrimitiveValue::UnitType>(index + lowestValue); |
} |
@@ -141,7 +142,71 @@ CSSValue* CSSCalcLength::toCSSValue() const { |
std::unique_ptr<CSSCalcLength::UnitData> |
CSSCalcLength::UnitData::fromExpressionNode( |
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
|
- return nullptr; |
+ CalculationCategory category = expressionNode->category(); |
+ DCHECK(category == CalculationCategory::CalcLength || |
+ category == CalculationCategory::CalcPercentLength || |
+ category == CalculationCategory::CalcPercent); |
+ |
+ if (expressionNode->getType() == |
+ CSSCalcExpressionNode::Type::CssCalcPrimitiveValue) { |
+ CSSPrimitiveValue::UnitType unit = expressionNode->typeWithCalcResolved(); |
+ if (!CSSLengthValue::isSupportedLengthUnit(unit)) { |
+ return nullptr; |
+ } |
+ std::unique_ptr<UnitData> result(new UnitData()); |
+ result->set(unit, expressionNode->doubleValue()); |
+ return result; |
+ } |
+ |
+ const CSSCalcExpressionNode* left = expressionNode->leftExpressionNode(); |
+ const CSSCalcExpressionNode* right = expressionNode->rightExpressionNode(); |
+ CalcOperator op = expressionNode->operatorType(); |
+ |
+ if (op == CalcMultiply) { |
+ std::unique_ptr<UnitData> unitData = nullptr; |
+ double argument = 0; |
+ // One side should be a number. |
+ if (left->category() == CalculationCategory::CalcNumber) { |
+ unitData = UnitData::fromExpressionNode(right); |
+ argument = left->doubleValue(); |
+ } else if (right->category() == CalculationCategory::CalcNumber) { |
+ unitData = UnitData::fromExpressionNode(left); |
+ argument = right->doubleValue(); |
+ } else { |
+ return nullptr; |
+ } |
+ if (!unitData) |
+ return nullptr; |
+ unitData->multiply(argument); |
+ return unitData; |
+ } |
+ |
+ if (op == CalcDivide) { |
+ // Divisor must always be on the RHS. |
+ if (right->category() != CalculationCategory::CalcNumber) |
+ return nullptr; |
+ std::unique_ptr<UnitData> unitData = UnitData::fromExpressionNode(left); |
+ if (!unitData) |
+ return nullptr; |
+ unitData->divide(right->doubleValue()); |
+ return unitData; |
+ } |
+ |
+ // Add and subtract. |
+ std::unique_ptr<UnitData> leftUnitData = UnitData::fromExpressionNode(left); |
+ std::unique_ptr<UnitData> rightUnitData = UnitData::fromExpressionNode(right); |
+ if (!leftUnitData || !rightUnitData) { |
+ return nullptr; |
+ } |
+ |
+ if (op == CalcAdd) |
+ leftUnitData->add(*rightUnitData); |
+ else if (op == CalcSubtract) |
+ leftUnitData->subtract(*rightUnitData); |
+ else |
+ NOTREACHED(); |
+ |
+ return leftUnitData; |
} |
CSSCalcExpressionNode* CSSCalcLength::UnitData::toCSSCalcExpressionNode() |