| 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 "core/css/CSSCalculationValue.h" | 7 #include "core/css/CSSCalculationValue.h" |
| 8 #include "core/css/CSSPrimitiveValue.h" | 8 #include "core/css/CSSPrimitiveValue.h" |
| 9 #include "core/css/CSSValue.h" |
| 9 #include "core/css/cssom/CSSSimpleLength.h" | 10 #include "core/css/cssom/CSSSimpleLength.h" |
| 10 #include "core/css/cssom/CalcDictionary.h" | 11 #include "core/css/cssom/CalcDictionary.h" |
| 12 #include "core/css/cssom/CalcDictionaryHelper.h" |
| 11 #include "wtf/Vector.h" | 13 #include "wtf/Vector.h" |
| 12 | 14 |
| 15 #include <iostream> |
| 16 |
| 13 namespace blink { | 17 namespace blink { |
| 14 | 18 |
| 15 CSSCalcLength::CSSCalcLength() : m_values(CSSLengthValue::kNumSupportedUnits), m
_hasValues(CSSLengthValue::kNumSupportedUnits) {} | 19 CSSCalcLength::CSSCalcLength() : m_values(CSSLengthValue::kNumSupportedUnits), m
_hasValues(CSSLengthValue::kNumSupportedUnits) {} |
| 16 | 20 |
| 17 CSSCalcLength::CSSCalcLength(const CSSCalcLength& other) : | 21 CSSCalcLength::CSSCalcLength(const CSSCalcLength& other) : |
| 18 m_values(other.m_values), | 22 m_values(other.m_values), |
| 19 m_hasValues(other.m_hasValues) | 23 m_hasValues(other.m_hasValues) |
| 20 {} | 24 {} |
| 21 | 25 |
| 22 CSSCalcLength::CSSCalcLength(const CSSSimpleLength& other) : | 26 CSSCalcLength::CSSCalcLength(const CSSSimpleLength& other) : |
| 23 m_values(CSSLengthValue::kNumSupportedUnits), m_hasValues(CSSLengthValue::kN
umSupportedUnits) | 27 m_values(CSSLengthValue::kNumSupportedUnits), m_hasValues(CSSLengthValue::kN
umSupportedUnits) |
| 24 { | 28 { |
| 25 set(other.value(), other.lengthUnit()); | 29 set(other.value(), other.lengthUnit()); |
| 26 } | 30 } |
| 27 | 31 |
| 28 CSSCalcLength* CSSCalcLength::create(const CSSLengthValue* length) | 32 CSSCalcLength* CSSCalcLength::create(const CSSLengthValue* length) |
| 29 { | 33 { |
| 30 if (length->type() == SimpleLengthType) { | 34 if (length->type() == SimpleLengthType) { |
| 31 const CSSSimpleLength* simpleLength = toCSSSimpleLength(length); | 35 const CSSSimpleLength* simpleLength = toCSSSimpleLength(length); |
| 32 return new CSSCalcLength(*simpleLength); | 36 return new CSSCalcLength(*simpleLength); |
| 33 } | 37 } |
| 34 | 38 |
| 35 return new CSSCalcLength(*toCSSCalcLength(length)); | 39 return new CSSCalcLength(*toCSSCalcLength(length)); |
| 36 } | 40 } |
| 37 | 41 |
| 38 CSSCalcLength* CSSCalcLength::create(const CalcDictionary& dictionary, Exception
State& exceptionState) | 42 CSSCalcLength* CSSCalcLength::create(const CalcDictionary& dictionary) |
| 39 { | 43 { |
| 40 CSSCalcLength* result = new CSSCalcLength(); | 44 CSSCalcLength* result = new CSSCalcLength(); |
| 41 int numSet = 0; | 45 int numSet = 0; |
| 42 | 46 |
| 43 #define setFromDictValue(name, camelName, primitiveName) \ | 47 #define setFromDictValue(name, camelName, primitiveName) \ |
| 44 if (dictionary.has##camelName()) { \ | 48 if (dictionary.has##camelName()) { \ |
| 45 result->set(dictionary.name(), CSSPrimitiveValue::UnitType::primitiveNam
e); \ | 49 result->set(dictionary.name(), CSSPrimitiveValue::UnitType::primitiveNam
e); \ |
| 46 numSet++; \ | 50 numSet++; \ |
| 47 } | 51 } |
| 48 | 52 |
| 49 setFromDictValue(px, Px, Pixels) | 53 setFromDictValue(px, Px, Pixels) |
| 50 setFromDictValue(percent, Percent, Percentage) | 54 setFromDictValue(percent, Percent, Percentage) |
| 51 setFromDictValue(em, Em, Ems) | 55 setFromDictValue(em, Em, Ems) |
| 52 setFromDictValue(ex, Ex, Exs) | 56 setFromDictValue(ex, Ex, Exs) |
| 53 setFromDictValue(ch, Ch, Chs) | 57 setFromDictValue(ch, Ch, Chs) |
| 54 setFromDictValue(rem, Rem, Rems) | 58 setFromDictValue(rem, Rem, Rems) |
| 55 setFromDictValue(vw, Vw, ViewportWidth) | 59 setFromDictValue(vw, Vw, ViewportWidth) |
| 56 setFromDictValue(vh, Vh, ViewportHeight) | 60 setFromDictValue(vh, Vh, ViewportHeight) |
| 57 setFromDictValue(vmin, Vmin, ViewportMin) | 61 setFromDictValue(vmin, Vmin, ViewportMin) |
| 58 setFromDictValue(vmax, Vmax, ViewportMax) | 62 setFromDictValue(vmax, Vmax, ViewportMax) |
| 59 setFromDictValue(cm, Cm, Centimeters) | 63 setFromDictValue(cm, Cm, Centimeters) |
| 60 setFromDictValue(mm, Mm, Millimeters) | 64 setFromDictValue(mm, Mm, Millimeters) |
| 61 setFromDictValue(in, In, Inches) | 65 setFromDictValue(in, In, Inches) |
| 62 setFromDictValue(pc, Pc, Picas) | 66 setFromDictValue(pc, Pc, Picas) |
| 63 setFromDictValue(pt, Pt, Points) | 67 setFromDictValue(pt, Pt, Points) |
| 64 | 68 |
| 65 if (numSet == 0) { | 69 if (numSet == 0) |
| 70 return nullptr; |
| 71 |
| 72 return result; |
| 73 } |
| 74 |
| 75 CSSCalcLength* CSSCalcLength::create(const CalcDictionary& dictionary, Exception
State& exceptionState) |
| 76 { |
| 77 CSSCalcLength* result = CSSCalcLength::create(dictionary); |
| 78 if (!result) { |
| 66 exceptionState.throwTypeError("Must specify at least one value in CalcDi
ctionary for creating a CSSCalcLength."); | 79 exceptionState.throwTypeError("Must specify at least one value in CalcDi
ctionary for creating a CSSCalcLength."); |
| 67 } | 80 } |
| 68 return result; | 81 return result; |
| 69 } | 82 } |
| 70 | 83 |
| 84 CSSCalcLength* CSSCalcLength::populateCalcLengthFromExpressionNode(const CSSCalc
ExpressionNode* expressionNode) |
| 85 { |
| 86 std::cout << "populateCalcLengthFromExpressionNode" << std::endl; |
| 87 if (expressionNode->getType() == CSSCalcExpressionNode::Type::CssCalcPrimiti
veValue) { |
| 88 std::cout << "node is simple" << std::endl; |
| 89 CSSPrimitiveValue::UnitType unit = expressionNode->typeWithCalcResolved(
); |
| 90 int unitIndex = CSSCalcLength::indexForUnit(unit); |
| 91 if (unitIndex < 0 || unitIndex >= kNumSupportedUnits) { |
| 92 std::cout << "Didn't recognize unit." << std::endl; |
| 93 return nullptr; |
| 94 } |
| 95 CSSCalcLength* result = new CSSCalcLength(); |
| 96 result->setAtIndex(expressionNode->doubleValue(), unitIndex); |
| 97 return result; |
| 98 } |
| 99 |
| 100 const CSSCalcExpressionNode* left = expressionNode->getLHS(); |
| 101 const CSSCalcExpressionNode* right = expressionNode->getRHS(); |
| 102 CalcOperator op = expressionNode->op(); |
| 103 |
| 104 CSSCalcLength* leftDict = nullptr; |
| 105 CSSCalcLength* rightDict = nullptr; |
| 106 if (op == CalcMultiply) { |
| 107 // One side should be a plain number. |
| 108 if (left->getType() == CSSCalcExpressionNode::Type::CssCalcPrimitiveValu
e) { |
| 109 rightDict = populateCalcLengthFromExpressionNode(right); |
| 110 if (!rightDict || left->typeWithCalcResolved() != CSSPrimitiveValue:
:UnitType::Number) { |
| 111 if (!rightDict) |
| 112 std::cout << "!rightDict" << std::endl; |
| 113 else |
| 114 std::cout << "left wasn't a number value" << std::endl; |
| 115 return nullptr; |
| 116 } |
| 117 rightDict->multiplyInternal(left->doubleValue()); |
| 118 } else if (right->getType() == CSSCalcExpressionNode::Type::CssCalcPrimi
tiveValue) { |
| 119 leftDict = populateCalcLengthFromExpressionNode(left); |
| 120 if (!leftDict || right->typeWithCalcResolved() != CSSPrimitiveValue:
:UnitType::Number) { |
| 121 if (!leftDict) |
| 122 std::cout << "!leftDict" << std::endl; |
| 123 else |
| 124 std::cout << "right wasn't a number value" << std::endl; |
| 125 return nullptr; |
| 126 } |
| 127 leftDict->multiplyInternal(right->doubleValue()); |
| 128 } else { |
| 129 std::cout << "Neither side was a primitive value" << std::endl; |
| 130 return nullptr; |
| 131 } |
| 132 } |
| 133 |
| 134 leftDict = populateCalcLengthFromExpressionNode(left); |
| 135 rightDict = populateCalcLengthFromExpressionNode(right); |
| 136 if (!leftDict || !rightDict) { |
| 137 std::cout << "One of left or right didn't expand to a dict" << std::endl
; |
| 138 return nullptr; |
| 139 } |
| 140 |
| 141 if (op == CalcAdd) { |
| 142 //CalcDictionaryHelper::add(leftDict, rightDict); |
| 143 return leftDict; |
| 144 } else if (op == CalcSubtract) { |
| 145 //CalcDictionaryHelper::subtract(leftDict, rightDict); |
| 146 return leftDict; |
| 147 } |
| 148 |
| 149 std::cout << "Unrecognized op" << std::endl; |
| 150 return nullptr; |
| 151 |
| 152 /* |
| 153 if (expressionNode->getType() == CSSCalcExpressionNode::Type::CssCalcPrimiti
veValue) { |
| 154 if (operation == CalcAdd || operation == CalcSubtract) { |
| 155 int unitIndex = CSSCalcLength::indexForUnit(expressionNode->typeWith
CalcResolved()); |
| 156 if (unitIndex < 0 || unitIndex >= kNumSupportedUnits) { |
| 157 std::cout << "Didn't recognize unit." << std::endl; |
| 158 *error = true; |
| 159 } else { |
| 160 if (operation == CalcAdd) |
| 161 std::cout << "Adding "; |
| 162 else |
| 163 std::cout << "Subtracting "; |
| 164 std::cout << expressionNode->doubleValue(); |
| 165 std::cout << " "; |
| 166 std::cout << int(expressionNode->typeWithCalcResolved()) << std:
:endl; |
| 167 calcLength->setAtIndex( |
| 168 operation == CalcAdd ? |
| 169 calcLength->getAtIndex(unitIndex) + expressionNode->doub
leValue() : |
| 170 calcLength->getAtIndex(unitIndex) - expressionNode->doub
leValue(), |
| 171 unitIndex); |
| 172 } |
| 173 } else if (operation == CalcMultiply) { |
| 174 std::cout << "Multiplying " << expressionNode->doubleValue() << std:
:endl; |
| 175 calcLength->multiplyInternal(expressionNode->doubleValue()); |
| 176 } else if (operation == CalcDivide) { |
| 177 std::cout << "Dividing " << expressionNode->doubleValue() << std::en
dl; |
| 178 calcLength->divideInternal(expressionNode->doubleValue()); |
| 179 } else { |
| 180 std::cout << "Didn't recognize operator." << std::endl; |
| 181 *error = true; |
| 182 } |
| 183 return; |
| 184 } |
| 185 |
| 186 populateCalcLengthFromExpressionNode(expressionNode->getLHS(), CalcAdd, calc
Length, error); |
| 187 populateCalcLengthFromExpressionNode(expressionNode->getRHS(), expressionNod
e->op(), calcLength, error); |
| 188 */ |
| 189 } |
| 190 |
| 191 CSSCalcLength* CSSCalcLength::fromCSSValue(const CSSValue& value) |
| 192 { |
| 193 if (!value.isPrimitiveValue()) |
| 194 return nullptr; |
| 195 const CSSPrimitiveValue& primitiveValue = toCSSPrimitiveValue(value); |
| 196 if (!primitiveValue.isLength() || !primitiveValue.isCalculated()) |
| 197 return nullptr; |
| 198 |
| 199 const CSSCalcValue* calcValue = primitiveValue.cssCalcValue(); |
| 200 return populateCalcLengthFromExpressionNode(calcValue->expressionNode()); |
| 201 } |
| 202 |
| 71 bool CSSCalcLength::containsPercent() const | 203 bool CSSCalcLength::containsPercent() const |
| 72 { | 204 { |
| 73 return has(CSSPrimitiveValue::UnitType::Percentage); | 205 return has(CSSPrimitiveValue::UnitType::Percentage); |
| 74 } | 206 } |
| 75 | 207 |
| 76 CSSLengthValue* CSSCalcLength::addInternal(const CSSLengthValue* other, Exceptio
nState& exceptionState) | 208 CSSLengthValue* CSSCalcLength::addInternal(const CSSLengthValue* other, Exceptio
nState& exceptionState) |
| 77 { | 209 { |
| 78 CSSCalcLength* result = CSSCalcLength::create(other, exceptionState); | 210 CSSCalcLength* result = CSSCalcLength::create(other, exceptionState); |
| 79 for (int i = 0; i < CSSLengthValue::kNumSupportedUnits; ++i) { | 211 for (int i = 0; i < CSSLengthValue::kNumSupportedUnits; ++i) { |
| 80 if (hasAtIndex(i)) { | 212 if (hasAtIndex(i)) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 94 result->setAtIndex(getAtIndex(i) - o->getAtIndex(i), i); | 226 result->setAtIndex(getAtIndex(i) - o->getAtIndex(i), i); |
| 95 } | 227 } |
| 96 } | 228 } |
| 97 } else { | 229 } else { |
| 98 const CSSSimpleLength* o = toCSSSimpleLength(other); | 230 const CSSSimpleLength* o = toCSSSimpleLength(other); |
| 99 result->set(get(o->lengthUnit()) - o->value(), o->lengthUnit()); | 231 result->set(get(o->lengthUnit()) - o->value(), o->lengthUnit()); |
| 100 } | 232 } |
| 101 return result; | 233 return result; |
| 102 } | 234 } |
| 103 | 235 |
| 104 CSSLengthValue* CSSCalcLength::multiplyInternal(double x, ExceptionState& except
ionState) | 236 CSSLengthValue* CSSCalcLength::multiplyInternal(double x) |
| 105 { | 237 { |
| 106 CSSCalcLength* result = CSSCalcLength::create(this, exceptionState); | 238 CSSCalcLength* result = CSSCalcLength::create(this); |
| 107 for (unsigned i = 0; i < CSSLengthValue::kNumSupportedUnits; ++i) { | 239 for (unsigned i = 0; i < CSSLengthValue::kNumSupportedUnits; ++i) { |
| 108 if (hasAtIndex(i)) { | 240 if (hasAtIndex(i)) { |
| 109 result->setAtIndex(getAtIndex(i) * x, i); | 241 result->setAtIndex(getAtIndex(i) * x, i); |
| 110 } | 242 } |
| 111 } | 243 } |
| 112 return result; | 244 return result; |
| 113 } | 245 } |
| 114 | 246 |
| 115 CSSLengthValue* CSSCalcLength::divideInternal(double x, ExceptionState& exceptio
nState) | 247 CSSLengthValue* CSSCalcLength::divideInternal(double x) |
| 116 { | 248 { |
| 117 CSSCalcLength* result = CSSCalcLength::create(this, exceptionState); | 249 CSSCalcLength* result = CSSCalcLength::create(this); |
| 118 for (unsigned i = 0; i < CSSLengthValue::kNumSupportedUnits; ++i) { | 250 for (unsigned i = 0; i < CSSLengthValue::kNumSupportedUnits; ++i) { |
| 119 if (hasAtIndex(i)) { | 251 if (hasAtIndex(i)) { |
| 120 result->setAtIndex(getAtIndex(i) / x, i); | 252 result->setAtIndex(getAtIndex(i) / x, i); |
| 121 } | 253 } |
| 122 } | 254 } |
| 123 return result; | 255 return result; |
| 124 } | 256 } |
| 125 | 257 |
| 126 CSSValue* CSSCalcLength::toCSSValue() const | 258 CSSValue* CSSCalcLength::toCSSValue() const |
| 127 { | 259 { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 142 } | 274 } |
| 143 return CSSPrimitiveValue::create(CSSCalcValue::create(node)); | 275 return CSSPrimitiveValue::create(CSSCalcValue::create(node)); |
| 144 } | 276 } |
| 145 | 277 |
| 146 int CSSCalcLength::indexForUnit(CSSPrimitiveValue::UnitType unit) | 278 int CSSCalcLength::indexForUnit(CSSPrimitiveValue::UnitType unit) |
| 147 { | 279 { |
| 148 return (static_cast<int>(unit) - static_cast<int>(CSSPrimitiveValue::UnitTyp
e::Percentage)); | 280 return (static_cast<int>(unit) - static_cast<int>(CSSPrimitiveValue::UnitTyp
e::Percentage)); |
| 149 } | 281 } |
| 150 | 282 |
| 151 } // namespace blink | 283 } // namespace blink |
| OLD | NEW |