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 |