OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 double CSSCalcValue::doubleValue() const | 172 double CSSCalcValue::doubleValue() const |
173 { | 173 { |
174 return clampToPermittedRange(m_expression->doubleValue()); | 174 return clampToPermittedRange(m_expression->doubleValue()); |
175 } | 175 } |
176 | 176 |
177 double CSSCalcValue::computeLengthPx(const CSSToLengthConversionData& conversion
Data) const | 177 double CSSCalcValue::computeLengthPx(const CSSToLengthConversionData& conversion
Data) const |
178 { | 178 { |
179 return clampToPermittedRange(m_expression->computeLengthPx(conversionData)); | 179 return clampToPermittedRange(m_expression->computeLengthPx(conversionData)); |
180 } | 180 } |
181 | 181 |
182 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CSSCalcExpressionNode) | |
183 | |
184 class CSSCalcPrimitiveValue final : public CSSCalcExpressionNode { | 182 class CSSCalcPrimitiveValue final : public CSSCalcExpressionNode { |
185 WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED(CSSCalcPrimitiveValue); | 183 WTF_MAKE_FAST_ALLOCATED(CSSCalcPrimitiveValue); |
186 public: | 184 public: |
187 | 185 |
188 static PassRefPtrWillBeRawPtr<CSSCalcPrimitiveValue> create(PassRefPtrWillBe
RawPtr<CSSPrimitiveValue> value, bool isInteger) | 186 static PassRefPtr<CSSCalcPrimitiveValue> create(PassRefPtr<CSSPrimitiveValue
> value, bool isInteger) |
189 { | 187 { |
190 return adoptRefWillBeNoop(new CSSCalcPrimitiveValue(value, isInteger)); | 188 return adoptRef(new CSSCalcPrimitiveValue(value, isInteger)); |
191 } | 189 } |
192 | 190 |
193 static PassRefPtrWillBeRawPtr<CSSCalcPrimitiveValue> create(double value, CS
SPrimitiveValue::UnitType type, bool isInteger) | 191 static PassRefPtr<CSSCalcPrimitiveValue> create(double value, CSSPrimitiveVa
lue::UnitType type, bool isInteger) |
194 { | 192 { |
195 if (std::isnan(value) || std::isinf(value)) | 193 if (std::isnan(value) || std::isinf(value)) |
196 return nullptr; | 194 return nullptr; |
197 return adoptRefWillBeNoop(new CSSCalcPrimitiveValue(CSSPrimitiveValue::c
reate(value, type).get(), isInteger)); | 195 return adoptRef(new CSSCalcPrimitiveValue(CSSPrimitiveValue::create(valu
e, type).get(), isInteger)); |
198 } | 196 } |
199 | 197 |
200 bool isZero() const override | 198 bool isZero() const override |
201 { | 199 { |
202 return !m_value->getDoubleValue(); | 200 return !m_value->getDoubleValue(); |
203 } | 201 } |
204 | 202 |
205 String customCSSText() const override | 203 String customCSSText() const override |
206 { | 204 { |
207 return m_value->cssText(); | 205 return m_value->cssText(); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 return compareCSSValuePtr(m_value, static_cast<const CSSCalcPrimitiveVal
ue&>(other).m_value); | 263 return compareCSSValuePtr(m_value, static_cast<const CSSCalcPrimitiveVal
ue&>(other).m_value); |
266 } | 264 } |
267 | 265 |
268 Type type() const override { return CssCalcPrimitiveValue; } | 266 Type type() const override { return CssCalcPrimitiveValue; } |
269 CSSPrimitiveValue::UnitType typeWithCalcResolved() const override | 267 CSSPrimitiveValue::UnitType typeWithCalcResolved() const override |
270 { | 268 { |
271 return m_value->typeWithCalcResolved(); | 269 return m_value->typeWithCalcResolved(); |
272 } | 270 } |
273 | 271 |
274 | 272 |
275 DEFINE_INLINE_VIRTUAL_TRACE() | |
276 { | |
277 visitor->trace(m_value); | |
278 CSSCalcExpressionNode::trace(visitor); | |
279 } | |
280 | |
281 private: | 273 private: |
282 CSSCalcPrimitiveValue(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> value, bool
isInteger) | 274 CSSCalcPrimitiveValue(PassRefPtr<CSSPrimitiveValue> value, bool isInteger) |
283 : CSSCalcExpressionNode(unitCategory(value->typeWithCalcResolved()), isI
nteger) | 275 : CSSCalcExpressionNode(unitCategory(value->typeWithCalcResolved()), isI
nteger) |
284 , m_value(value) | 276 , m_value(value) |
285 { | 277 { |
286 } | 278 } |
287 | 279 |
288 RefPtrWillBeMember<CSSPrimitiveValue> m_value; | 280 RefPtr<CSSPrimitiveValue> m_value; |
289 }; | 281 }; |
290 | 282 |
291 static const CalculationCategory addSubtractResult[CalcOther][CalcOther] = { | 283 static const CalculationCategory addSubtractResult[CalcOther][CalcOther] = { |
292 // CalcNumber CalcLength CalcPercent
CalcPercentNumber CalcPercentLength CalcAngle CalcTime CalcFrequency | 284 // CalcNumber CalcLength CalcPercent
CalcPercentNumber CalcPercentLength CalcAngle CalcTime CalcFrequency |
293 /* CalcNumber */ { CalcNumber, CalcOther, CalcPercentNumbe
r, CalcPercentNumber, CalcOther, CalcOther, CalcOther, CalcOther }, | 285 /* CalcNumber */ { CalcNumber, CalcOther, CalcPercentNumbe
r, CalcPercentNumber, CalcOther, CalcOther, CalcOther, CalcOther }, |
294 /* CalcLength */ { CalcOther, CalcLength, CalcPercentLengt
h, CalcOther, CalcPercentLength, CalcOther, CalcOther, CalcOther }, | 286 /* CalcLength */ { CalcOther, CalcLength, CalcPercentLengt
h, CalcOther, CalcPercentLength, CalcOther, CalcOther, CalcOther }, |
295 /* CalcPercent */ { CalcPercentNumber, CalcPercentLength, CalcPercent,
CalcPercentNumber, CalcPercentLength, CalcOther, CalcOther, CalcOther }, | 287 /* CalcPercent */ { CalcPercentNumber, CalcPercentLength, CalcPercent,
CalcPercentNumber, CalcPercentLength, CalcOther, CalcOther, CalcOther }, |
296 /* CalcPercentNumber */ { CalcPercentNumber, CalcOther, CalcPercentNumbe
r, CalcPercentNumber, CalcOther, CalcOther, CalcOther, CalcOther }, | 288 /* CalcPercentNumber */ { CalcPercentNumber, CalcOther, CalcPercentNumbe
r, CalcPercentNumber, CalcOther, CalcOther, CalcOther, CalcOther }, |
297 /* CalcPercentLength */ { CalcOther, CalcPercentLength, CalcPercentLengt
h, CalcOther, CalcPercentLength, CalcOther, CalcOther, CalcOther }, | 289 /* CalcPercentLength */ { CalcOther, CalcPercentLength, CalcPercentLengt
h, CalcOther, CalcPercentLength, CalcOther, CalcOther, CalcOther }, |
298 /* CalcAngle */ { CalcOther, CalcOther, CalcOther,
CalcOther, CalcOther, CalcAngle, CalcOther, CalcOther }, | 290 /* CalcAngle */ { CalcOther, CalcOther, CalcOther,
CalcOther, CalcOther, CalcAngle, CalcOther, CalcOther }, |
(...skipping 30 matching lines...) Expand all Loading... |
329 static bool isIntegerResult(const CSSCalcExpressionNode* leftSide, const CSSCalc
ExpressionNode* rightSide, CalcOperator op) | 321 static bool isIntegerResult(const CSSCalcExpressionNode* leftSide, const CSSCalc
ExpressionNode* rightSide, CalcOperator op) |
330 { | 322 { |
331 // Not testing for actual integer values. | 323 // Not testing for actual integer values. |
332 // Performs W3C spec's type checking for calc integers. | 324 // Performs W3C spec's type checking for calc integers. |
333 // http://www.w3.org/TR/css3-values/#calc-type-checking | 325 // http://www.w3.org/TR/css3-values/#calc-type-checking |
334 return op != CalcDivide && leftSide->isInteger() && rightSide->isInteger(); | 326 return op != CalcDivide && leftSide->isInteger() && rightSide->isInteger(); |
335 } | 327 } |
336 | 328 |
337 class CSSCalcBinaryOperation final : public CSSCalcExpressionNode { | 329 class CSSCalcBinaryOperation final : public CSSCalcExpressionNode { |
338 public: | 330 public: |
339 static PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> create(PassRefPtrWillBe
RawPtr<CSSCalcExpressionNode> leftSide, PassRefPtrWillBeRawPtr<CSSCalcExpression
Node> rightSide, CalcOperator op) | 331 static PassRefPtr<CSSCalcExpressionNode> create(PassRefPtr<CSSCalcExpression
Node> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide, CalcOperator op) |
340 { | 332 { |
341 ASSERT(leftSide->category() != CalcOther && rightSide->category() != Cal
cOther); | 333 ASSERT(leftSide->category() != CalcOther && rightSide->category() != Cal
cOther); |
342 | 334 |
343 CalculationCategory newCategory = determineCategory(*leftSide, *rightSid
e, op); | 335 CalculationCategory newCategory = determineCategory(*leftSide, *rightSid
e, op); |
344 if (newCategory == CalcOther) | 336 if (newCategory == CalcOther) |
345 return nullptr; | 337 return nullptr; |
346 | 338 |
347 return adoptRefWillBeNoop(new CSSCalcBinaryOperation(leftSide, rightSide
, op, newCategory)); | 339 return adoptRef(new CSSCalcBinaryOperation(leftSide, rightSide, op, newC
ategory)); |
348 } | 340 } |
349 | 341 |
350 static PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> createSimplified(PassRe
fPtrWillBeRawPtr<CSSCalcExpressionNode> leftSide, PassRefPtrWillBeRawPtr<CSSCalc
ExpressionNode> rightSide, CalcOperator op) | 342 static PassRefPtr<CSSCalcExpressionNode> createSimplified(PassRefPtr<CSSCalc
ExpressionNode> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide, CalcOpera
tor op) |
351 { | 343 { |
352 CalculationCategory leftCategory = leftSide->category(); | 344 CalculationCategory leftCategory = leftSide->category(); |
353 CalculationCategory rightCategory = rightSide->category(); | 345 CalculationCategory rightCategory = rightSide->category(); |
354 ASSERT(leftCategory != CalcOther && rightCategory != CalcOther); | 346 ASSERT(leftCategory != CalcOther && rightCategory != CalcOther); |
355 | 347 |
356 bool isInteger = isIntegerResult(leftSide.get(), rightSide.get(), op); | 348 bool isInteger = isIntegerResult(leftSide.get(), rightSide.get(), op); |
357 | 349 |
358 // Simplify numbers. | 350 // Simplify numbers. |
359 if (leftCategory == CalcNumber && rightCategory == CalcNumber) { | 351 if (leftCategory == CalcNumber && rightCategory == CalcNumber) { |
360 return CSSCalcPrimitiveValue::create(evaluateOperator(leftSide->doub
leValue(), rightSide->doubleValue(), op), CSSPrimitiveValue::UnitType::Number, i
sInteger); | 352 return CSSCalcPrimitiveValue::create(evaluateOperator(leftSide->doub
leValue(), rightSide->doubleValue(), op), CSSPrimitiveValue::UnitType::Number, i
sInteger); |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 return CSSPrimitiveValue::UnitType::Hertz; | 523 return CSSPrimitiveValue::UnitType::Hertz; |
532 case CalcPercentLength: | 524 case CalcPercentLength: |
533 case CalcPercentNumber: | 525 case CalcPercentNumber: |
534 case CalcOther: | 526 case CalcOther: |
535 return CSSPrimitiveValue::UnitType::Unknown; | 527 return CSSPrimitiveValue::UnitType::Unknown; |
536 } | 528 } |
537 ASSERT_NOT_REACHED(); | 529 ASSERT_NOT_REACHED(); |
538 return CSSPrimitiveValue::UnitType::Unknown; | 530 return CSSPrimitiveValue::UnitType::Unknown; |
539 } | 531 } |
540 | 532 |
541 DEFINE_INLINE_VIRTUAL_TRACE() | |
542 { | |
543 visitor->trace(m_leftSide); | |
544 visitor->trace(m_rightSide); | |
545 CSSCalcExpressionNode::trace(visitor); | |
546 } | |
547 | |
548 private: | 533 private: |
549 CSSCalcBinaryOperation(PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> leftSid
e, PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> rightSide, CalcOperator op, Cal
culationCategory category) | 534 CSSCalcBinaryOperation(PassRefPtr<CSSCalcExpressionNode> leftSide, PassRefPt
r<CSSCalcExpressionNode> rightSide, CalcOperator op, CalculationCategory categor
y) |
550 : CSSCalcExpressionNode(category, isIntegerResult(leftSide.get(), rightS
ide.get(), op)) | 535 : CSSCalcExpressionNode(category, isIntegerResult(leftSide.get(), rightS
ide.get(), op)) |
551 , m_leftSide(leftSide) | 536 , m_leftSide(leftSide) |
552 , m_rightSide(rightSide) | 537 , m_rightSide(rightSide) |
553 , m_operator(op) | 538 , m_operator(op) |
554 { | 539 { |
555 } | 540 } |
556 | 541 |
557 static CSSCalcExpressionNode* getNumberSide(CSSCalcExpressionNode* leftSide,
CSSCalcExpressionNode* rightSide) | 542 static CSSCalcExpressionNode* getNumberSide(CSSCalcExpressionNode* leftSide,
CSSCalcExpressionNode* rightSide) |
558 { | 543 { |
559 if (leftSide->category() == CalcNumber) | 544 if (leftSide->category() == CalcNumber) |
(...skipping 18 matching lines...) Expand all Loading... |
578 case CalcMultiply: | 563 case CalcMultiply: |
579 return leftValue * rightValue; | 564 return leftValue * rightValue; |
580 case CalcDivide: | 565 case CalcDivide: |
581 if (rightValue) | 566 if (rightValue) |
582 return leftValue / rightValue; | 567 return leftValue / rightValue; |
583 return std::numeric_limits<double>::quiet_NaN(); | 568 return std::numeric_limits<double>::quiet_NaN(); |
584 } | 569 } |
585 return 0; | 570 return 0; |
586 } | 571 } |
587 | 572 |
588 const RefPtrWillBeMember<CSSCalcExpressionNode> m_leftSide; | 573 const RefPtr<CSSCalcExpressionNode> m_leftSide; |
589 const RefPtrWillBeMember<CSSCalcExpressionNode> m_rightSide; | 574 const RefPtr<CSSCalcExpressionNode> m_rightSide; |
590 const CalcOperator m_operator; | 575 const CalcOperator m_operator; |
591 }; | 576 }; |
592 | 577 |
593 static ParseState checkDepthAndIndex(int* depth, CSSParserTokenRange tokens) | 578 static ParseState checkDepthAndIndex(int* depth, CSSParserTokenRange tokens) |
594 { | 579 { |
595 (*depth)++; | 580 (*depth)++; |
596 if (tokens.atEnd()) | 581 if (tokens.atEnd()) |
597 return NoMoreTokens; | 582 return NoMoreTokens; |
598 if (*depth > maxExpressionDepth) | 583 if (*depth > maxExpressionDepth) |
599 return TooDeep; | 584 return TooDeep; |
600 return OK; | 585 return OK; |
601 } | 586 } |
602 | 587 |
603 class CSSCalcExpressionNodeParser { | 588 class CSSCalcExpressionNodeParser { |
604 STACK_ALLOCATED(); | 589 STACK_ALLOCATED(); |
605 public: | 590 public: |
606 PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> parseCalc(CSSParserTokenRange
tokens) | 591 PassRefPtr<CSSCalcExpressionNode> parseCalc(CSSParserTokenRange tokens) |
607 { | 592 { |
608 Value result; | 593 Value result; |
609 tokens.consumeWhitespace(); | 594 tokens.consumeWhitespace(); |
610 bool ok = parseValueExpression(tokens, 0, &result); | 595 bool ok = parseValueExpression(tokens, 0, &result); |
611 if (!ok || !tokens.atEnd()) | 596 if (!ok || !tokens.atEnd()) |
612 return nullptr; | 597 return nullptr; |
613 return result.value; | 598 return result.value; |
614 } | 599 } |
615 | 600 |
616 private: | 601 private: |
617 struct Value { | 602 struct Value { |
618 STACK_ALLOCATED(); | 603 STACK_ALLOCATED(); |
619 public: | 604 public: |
620 RefPtrWillBeMember<CSSCalcExpressionNode> value; | 605 RefPtr<CSSCalcExpressionNode> value; |
621 }; | 606 }; |
622 | 607 |
623 char operatorValue(const CSSParserToken& token) | 608 char operatorValue(const CSSParserToken& token) |
624 { | 609 { |
625 if (token.type() == DelimiterToken) | 610 if (token.type() == DelimiterToken) |
626 return token.delimiter(); | 611 return token.delimiter(); |
627 return 0; | 612 return 0; |
628 } | 613 } |
629 | 614 |
630 bool parseValue(CSSParserTokenRange& tokens, Value* result) | 615 bool parseValue(CSSParserTokenRange& tokens, Value* result) |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
713 | 698 |
714 return true; | 699 return true; |
715 } | 700 } |
716 | 701 |
717 bool parseValueExpression(CSSParserTokenRange& tokens, int depth, Value* res
ult) | 702 bool parseValueExpression(CSSParserTokenRange& tokens, int depth, Value* res
ult) |
718 { | 703 { |
719 return parseAdditiveValueExpression(tokens, depth, result); | 704 return parseAdditiveValueExpression(tokens, depth, result); |
720 } | 705 } |
721 }; | 706 }; |
722 | 707 |
723 PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode
(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> value, bool isInteger) | 708 PassRefPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode(PassRefPtr<
CSSPrimitiveValue> value, bool isInteger) |
724 { | 709 { |
725 return CSSCalcPrimitiveValue::create(value, isInteger); | 710 return CSSCalcPrimitiveValue::create(value, isInteger); |
726 } | 711 } |
727 | 712 |
728 PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode
(PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> leftSide, PassRefPtrWillBeRawPtr<
CSSCalcExpressionNode> rightSide, CalcOperator op) | 713 PassRefPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode(PassRefPtr<
CSSCalcExpressionNode> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide, Ca
lcOperator op) |
729 { | 714 { |
730 return CSSCalcBinaryOperation::create(leftSide, rightSide, op); | 715 return CSSCalcBinaryOperation::create(leftSide, rightSide, op); |
731 } | 716 } |
732 | 717 |
733 PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode
(double pixels, double percent) | 718 PassRefPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode(double pixe
ls, double percent) |
734 { | 719 { |
735 return createExpressionNode( | 720 return createExpressionNode( |
736 createExpressionNode(CSSPrimitiveValue::create(pixels, CSSPrimitiveValue
::UnitType::Pixels), pixels == trunc(pixels)), | 721 createExpressionNode(CSSPrimitiveValue::create(pixels, CSSPrimitiveValue
::UnitType::Pixels), pixels == trunc(pixels)), |
737 createExpressionNode(CSSPrimitiveValue::create(percent, CSSPrimitiveValu
e::UnitType::Percentage), percent == trunc(percent)), | 722 createExpressionNode(CSSPrimitiveValue::create(percent, CSSPrimitiveValu
e::UnitType::Percentage), percent == trunc(percent)), |
738 CalcAdd); | 723 CalcAdd); |
739 } | 724 } |
740 | 725 |
741 PassRefPtrWillBeRawPtr<CSSCalcValue> CSSCalcValue::create(const CSSParserTokenRa
nge& tokens, ValueRange range) | 726 PassRefPtr<CSSCalcValue> CSSCalcValue::create(const CSSParserTokenRange& tokens,
ValueRange range) |
742 { | 727 { |
743 CSSCalcExpressionNodeParser parser; | 728 CSSCalcExpressionNodeParser parser; |
744 RefPtrWillBeRawPtr<CSSCalcExpressionNode> expression = parser.parseCalc(toke
ns); | 729 RefPtr<CSSCalcExpressionNode> expression = parser.parseCalc(tokens); |
745 | 730 |
746 return expression ? adoptRefWillBeNoop(new CSSCalcValue(expression, range))
: nullptr; | 731 return expression ? adoptRef(new CSSCalcValue(expression, range)) : nullptr; |
747 } | 732 } |
748 | 733 |
749 PassRefPtrWillBeRawPtr<CSSCalcValue> CSSCalcValue::create(PassRefPtrWillBeRawPtr
<CSSCalcExpressionNode> expression, ValueRange range) | 734 PassRefPtr<CSSCalcValue> CSSCalcValue::create(PassRefPtr<CSSCalcExpressionNode>
expression, ValueRange range) |
750 { | 735 { |
751 return adoptRefWillBeNoop(new CSSCalcValue(expression, range)); | 736 return adoptRef(new CSSCalcValue(expression, range)); |
752 } | 737 } |
753 | 738 |
754 } // namespace blink | 739 } // namespace blink |
OLD | NEW |