| 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 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 double CSSCalcValue::doubleValue() const | 163 double CSSCalcValue::doubleValue() const |
| 164 { | 164 { |
| 165 return clampToPermittedRange(m_expression->doubleValue()); | 165 return clampToPermittedRange(m_expression->doubleValue()); |
| 166 } | 166 } |
| 167 | 167 |
| 168 double CSSCalcValue::computeLengthPx(const CSSToLengthConversionData& conversion
Data) const | 168 double CSSCalcValue::computeLengthPx(const CSSToLengthConversionData& conversion
Data) const |
| 169 { | 169 { |
| 170 return clampToPermittedRange(m_expression->computeLengthPx(conversionData)); | 170 return clampToPermittedRange(m_expression->computeLengthPx(conversionData)); |
| 171 } | 171 } |
| 172 | 172 |
| 173 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CSSCalcExpressionNode) | |
| 174 | |
| 175 class CSSCalcPrimitiveValue final : public CSSCalcExpressionNode { | 173 class CSSCalcPrimitiveValue final : public CSSCalcExpressionNode { |
| 176 USING_FAST_MALLOC_WILL_BE_REMOVED(CSSCalcPrimitiveValue); | |
| 177 public: | 174 public: |
| 178 | 175 |
| 179 static PassRefPtrWillBeRawPtr<CSSCalcPrimitiveValue> create(PassRefPtrWillBe
RawPtr<CSSPrimitiveValue> value, bool isInteger) | 176 static RawPtr<CSSCalcPrimitiveValue> create(RawPtr<CSSPrimitiveValue> value,
bool isInteger) |
| 180 { | 177 { |
| 181 return adoptRefWillBeNoop(new CSSCalcPrimitiveValue(value, isInteger)); | 178 return (new CSSCalcPrimitiveValue(value, isInteger)); |
| 182 } | 179 } |
| 183 | 180 |
| 184 static PassRefPtrWillBeRawPtr<CSSCalcPrimitiveValue> create(double value, CS
SPrimitiveValue::UnitType type, bool isInteger) | 181 static RawPtr<CSSCalcPrimitiveValue> create(double value, CSSPrimitiveValue:
:UnitType type, bool isInteger) |
| 185 { | 182 { |
| 186 if (std::isnan(value) || std::isinf(value)) | 183 if (std::isnan(value) || std::isinf(value)) |
| 187 return nullptr; | 184 return nullptr; |
| 188 return adoptRefWillBeNoop(new CSSCalcPrimitiveValue(CSSPrimitiveValue::c
reate(value, type).get(), isInteger)); | 185 return (new CSSCalcPrimitiveValue(CSSPrimitiveValue::create(value, type)
.get(), isInteger)); |
| 189 } | 186 } |
| 190 | 187 |
| 191 bool isZero() const override | 188 bool isZero() const override |
| 192 { | 189 { |
| 193 return !m_value->getDoubleValue(); | 190 return !m_value->getDoubleValue(); |
| 194 } | 191 } |
| 195 | 192 |
| 196 String customCSSText() const override | 193 String customCSSText() const override |
| 197 { | 194 { |
| 198 return m_value->cssText(); | 195 return m_value->cssText(); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 } | 260 } |
| 264 | 261 |
| 265 | 262 |
| 266 DEFINE_INLINE_VIRTUAL_TRACE() | 263 DEFINE_INLINE_VIRTUAL_TRACE() |
| 267 { | 264 { |
| 268 visitor->trace(m_value); | 265 visitor->trace(m_value); |
| 269 CSSCalcExpressionNode::trace(visitor); | 266 CSSCalcExpressionNode::trace(visitor); |
| 270 } | 267 } |
| 271 | 268 |
| 272 private: | 269 private: |
| 273 CSSCalcPrimitiveValue(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> value, bool
isInteger) | 270 CSSCalcPrimitiveValue(RawPtr<CSSPrimitiveValue> value, bool isInteger) |
| 274 : CSSCalcExpressionNode(unitCategory(value->typeWithCalcResolved()), isI
nteger) | 271 : CSSCalcExpressionNode(unitCategory(value->typeWithCalcResolved()), isI
nteger) |
| 275 , m_value(value) | 272 , m_value(value) |
| 276 { | 273 { |
| 277 } | 274 } |
| 278 | 275 |
| 279 RefPtrWillBeMember<CSSPrimitiveValue> m_value; | 276 Member<CSSPrimitiveValue> m_value; |
| 280 }; | 277 }; |
| 281 | 278 |
| 282 static const CalculationCategory addSubtractResult[CalcOther][CalcOther] = { | 279 static const CalculationCategory addSubtractResult[CalcOther][CalcOther] = { |
| 283 // CalcNumber CalcLength CalcPercent
CalcPercentNumber CalcPercentLength CalcAngle CalcTime CalcFrequency | 280 // CalcNumber CalcLength CalcPercent
CalcPercentNumber CalcPercentLength CalcAngle CalcTime CalcFrequency |
| 284 /* CalcNumber */ { CalcNumber, CalcOther, CalcPercentNumbe
r, CalcPercentNumber, CalcOther, CalcOther, CalcOther, CalcOther }, | 281 /* CalcNumber */ { CalcNumber, CalcOther, CalcPercentNumbe
r, CalcPercentNumber, CalcOther, CalcOther, CalcOther, CalcOther }, |
| 285 /* CalcLength */ { CalcOther, CalcLength, CalcPercentLengt
h, CalcOther, CalcPercentLength, CalcOther, CalcOther, CalcOther }, | 282 /* CalcLength */ { CalcOther, CalcLength, CalcPercentLengt
h, CalcOther, CalcPercentLength, CalcOther, CalcOther, CalcOther }, |
| 286 /* CalcPercent */ { CalcPercentNumber, CalcPercentLength, CalcPercent,
CalcPercentNumber, CalcPercentLength, CalcOther, CalcOther, CalcOther }, | 283 /* CalcPercent */ { CalcPercentNumber, CalcPercentLength, CalcPercent,
CalcPercentNumber, CalcPercentLength, CalcOther, CalcOther, CalcOther }, |
| 287 /* CalcPercentNumber */ { CalcPercentNumber, CalcOther, CalcPercentNumbe
r, CalcPercentNumber, CalcOther, CalcOther, CalcOther, CalcOther }, | 284 /* CalcPercentNumber */ { CalcPercentNumber, CalcOther, CalcPercentNumbe
r, CalcPercentNumber, CalcOther, CalcOther, CalcOther, CalcOther }, |
| 288 /* CalcPercentLength */ { CalcOther, CalcPercentLength, CalcPercentLengt
h, CalcOther, CalcPercentLength, CalcOther, CalcOther, CalcOther }, | 285 /* CalcPercentLength */ { CalcOther, CalcPercentLength, CalcPercentLengt
h, CalcOther, CalcPercentLength, CalcOther, CalcOther, CalcOther }, |
| 289 /* CalcAngle */ { CalcOther, CalcOther, CalcOther,
CalcOther, CalcOther, CalcAngle, CalcOther, CalcOther }, | 286 /* CalcAngle */ { CalcOther, CalcOther, CalcOther,
CalcOther, CalcOther, CalcAngle, CalcOther, CalcOther }, |
| (...skipping 30 matching lines...) Expand all Loading... |
| 320 static bool isIntegerResult(const CSSCalcExpressionNode* leftSide, const CSSCalc
ExpressionNode* rightSide, CalcOperator op) | 317 static bool isIntegerResult(const CSSCalcExpressionNode* leftSide, const CSSCalc
ExpressionNode* rightSide, CalcOperator op) |
| 321 { | 318 { |
| 322 // Not testing for actual integer values. | 319 // Not testing for actual integer values. |
| 323 // Performs W3C spec's type checking for calc integers. | 320 // Performs W3C spec's type checking for calc integers. |
| 324 // http://www.w3.org/TR/css3-values/#calc-type-checking | 321 // http://www.w3.org/TR/css3-values/#calc-type-checking |
| 325 return op != CalcDivide && leftSide->isInteger() && rightSide->isInteger(); | 322 return op != CalcDivide && leftSide->isInteger() && rightSide->isInteger(); |
| 326 } | 323 } |
| 327 | 324 |
| 328 class CSSCalcBinaryOperation final : public CSSCalcExpressionNode { | 325 class CSSCalcBinaryOperation final : public CSSCalcExpressionNode { |
| 329 public: | 326 public: |
| 330 static PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> create(PassRefPtrWillBe
RawPtr<CSSCalcExpressionNode> leftSide, PassRefPtrWillBeRawPtr<CSSCalcExpression
Node> rightSide, CalcOperator op) | 327 static RawPtr<CSSCalcExpressionNode> create(RawPtr<CSSCalcExpressionNode> le
ftSide, RawPtr<CSSCalcExpressionNode> rightSide, CalcOperator op) |
| 331 { | 328 { |
| 332 ASSERT(leftSide->category() != CalcOther && rightSide->category() != Cal
cOther); | 329 ASSERT(leftSide->category() != CalcOther && rightSide->category() != Cal
cOther); |
| 333 | 330 |
| 334 CalculationCategory newCategory = determineCategory(*leftSide, *rightSid
e, op); | 331 CalculationCategory newCategory = determineCategory(*leftSide, *rightSid
e, op); |
| 335 if (newCategory == CalcOther) | 332 if (newCategory == CalcOther) |
| 336 return nullptr; | 333 return nullptr; |
| 337 | 334 |
| 338 return adoptRefWillBeNoop(new CSSCalcBinaryOperation(leftSide, rightSide
, op, newCategory)); | 335 return (new CSSCalcBinaryOperation(leftSide, rightSide, op, newCategory)
); |
| 339 } | 336 } |
| 340 | 337 |
| 341 static PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> createSimplified(PassRe
fPtrWillBeRawPtr<CSSCalcExpressionNode> leftSide, PassRefPtrWillBeRawPtr<CSSCalc
ExpressionNode> rightSide, CalcOperator op) | 338 static RawPtr<CSSCalcExpressionNode> createSimplified(RawPtr<CSSCalcExpressi
onNode> leftSide, RawPtr<CSSCalcExpressionNode> rightSide, CalcOperator op) |
| 342 { | 339 { |
| 343 CalculationCategory leftCategory = leftSide->category(); | 340 CalculationCategory leftCategory = leftSide->category(); |
| 344 CalculationCategory rightCategory = rightSide->category(); | 341 CalculationCategory rightCategory = rightSide->category(); |
| 345 ASSERT(leftCategory != CalcOther && rightCategory != CalcOther); | 342 ASSERT(leftCategory != CalcOther && rightCategory != CalcOther); |
| 346 | 343 |
| 347 bool isInteger = isIntegerResult(leftSide.get(), rightSide.get(), op); | 344 bool isInteger = isIntegerResult(leftSide.get(), rightSide.get(), op); |
| 348 | 345 |
| 349 // Simplify numbers. | 346 // Simplify numbers. |
| 350 if (leftCategory == CalcNumber && rightCategory == CalcNumber) { | 347 if (leftCategory == CalcNumber && rightCategory == CalcNumber) { |
| 351 return CSSCalcPrimitiveValue::create(evaluateOperator(leftSide->doub
leValue(), rightSide->doubleValue(), op), CSSPrimitiveValue::UnitType::Number, i
sInteger); | 348 return CSSCalcPrimitiveValue::create(evaluateOperator(leftSide->doub
leValue(), rightSide->doubleValue(), op), CSSPrimitiveValue::UnitType::Number, i
sInteger); |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 } | 527 } |
| 531 | 528 |
| 532 DEFINE_INLINE_VIRTUAL_TRACE() | 529 DEFINE_INLINE_VIRTUAL_TRACE() |
| 533 { | 530 { |
| 534 visitor->trace(m_leftSide); | 531 visitor->trace(m_leftSide); |
| 535 visitor->trace(m_rightSide); | 532 visitor->trace(m_rightSide); |
| 536 CSSCalcExpressionNode::trace(visitor); | 533 CSSCalcExpressionNode::trace(visitor); |
| 537 } | 534 } |
| 538 | 535 |
| 539 private: | 536 private: |
| 540 CSSCalcBinaryOperation(PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> leftSid
e, PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> rightSide, CalcOperator op, Cal
culationCategory category) | 537 CSSCalcBinaryOperation(RawPtr<CSSCalcExpressionNode> leftSide, RawPtr<CSSCal
cExpressionNode> rightSide, CalcOperator op, CalculationCategory category) |
| 541 : CSSCalcExpressionNode(category, isIntegerResult(leftSide.get(), rightS
ide.get(), op)) | 538 : CSSCalcExpressionNode(category, isIntegerResult(leftSide.get(), rightS
ide.get(), op)) |
| 542 , m_leftSide(leftSide) | 539 , m_leftSide(leftSide) |
| 543 , m_rightSide(rightSide) | 540 , m_rightSide(rightSide) |
| 544 , m_operator(op) | 541 , m_operator(op) |
| 545 { | 542 { |
| 546 } | 543 } |
| 547 | 544 |
| 548 static CSSCalcExpressionNode* getNumberSide(CSSCalcExpressionNode* leftSide,
CSSCalcExpressionNode* rightSide) | 545 static CSSCalcExpressionNode* getNumberSide(CSSCalcExpressionNode* leftSide,
CSSCalcExpressionNode* rightSide) |
| 549 { | 546 { |
| 550 if (leftSide->category() == CalcNumber) | 547 if (leftSide->category() == CalcNumber) |
| (...skipping 18 matching lines...) Expand all Loading... |
| 569 case CalcMultiply: | 566 case CalcMultiply: |
| 570 return leftValue * rightValue; | 567 return leftValue * rightValue; |
| 571 case CalcDivide: | 568 case CalcDivide: |
| 572 if (rightValue) | 569 if (rightValue) |
| 573 return leftValue / rightValue; | 570 return leftValue / rightValue; |
| 574 return std::numeric_limits<double>::quiet_NaN(); | 571 return std::numeric_limits<double>::quiet_NaN(); |
| 575 } | 572 } |
| 576 return 0; | 573 return 0; |
| 577 } | 574 } |
| 578 | 575 |
| 579 const RefPtrWillBeMember<CSSCalcExpressionNode> m_leftSide; | 576 const Member<CSSCalcExpressionNode> m_leftSide; |
| 580 const RefPtrWillBeMember<CSSCalcExpressionNode> m_rightSide; | 577 const Member<CSSCalcExpressionNode> m_rightSide; |
| 581 const CalcOperator m_operator; | 578 const CalcOperator m_operator; |
| 582 }; | 579 }; |
| 583 | 580 |
| 584 static ParseState checkDepthAndIndex(int* depth, CSSParserTokenRange tokens) | 581 static ParseState checkDepthAndIndex(int* depth, CSSParserTokenRange tokens) |
| 585 { | 582 { |
| 586 (*depth)++; | 583 (*depth)++; |
| 587 if (tokens.atEnd()) | 584 if (tokens.atEnd()) |
| 588 return NoMoreTokens; | 585 return NoMoreTokens; |
| 589 if (*depth > maxExpressionDepth) | 586 if (*depth > maxExpressionDepth) |
| 590 return TooDeep; | 587 return TooDeep; |
| 591 return OK; | 588 return OK; |
| 592 } | 589 } |
| 593 | 590 |
| 594 class CSSCalcExpressionNodeParser { | 591 class CSSCalcExpressionNodeParser { |
| 595 STACK_ALLOCATED(); | 592 STACK_ALLOCATED(); |
| 596 public: | 593 public: |
| 597 PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> parseCalc(CSSParserTokenRange
tokens) | 594 RawPtr<CSSCalcExpressionNode> parseCalc(CSSParserTokenRange tokens) |
| 598 { | 595 { |
| 599 Value result; | 596 Value result; |
| 600 tokens.consumeWhitespace(); | 597 tokens.consumeWhitespace(); |
| 601 bool ok = parseValueExpression(tokens, 0, &result); | 598 bool ok = parseValueExpression(tokens, 0, &result); |
| 602 if (!ok || !tokens.atEnd()) | 599 if (!ok || !tokens.atEnd()) |
| 603 return nullptr; | 600 return nullptr; |
| 604 return result.value; | 601 return result.value; |
| 605 } | 602 } |
| 606 | 603 |
| 607 private: | 604 private: |
| 608 struct Value { | 605 struct Value { |
| 609 STACK_ALLOCATED(); | 606 STACK_ALLOCATED(); |
| 610 public: | 607 public: |
| 611 RefPtrWillBeMember<CSSCalcExpressionNode> value; | 608 Member<CSSCalcExpressionNode> value; |
| 612 }; | 609 }; |
| 613 | 610 |
| 614 char operatorValue(const CSSParserToken& token) | 611 char operatorValue(const CSSParserToken& token) |
| 615 { | 612 { |
| 616 if (token.type() == DelimiterToken) | 613 if (token.type() == DelimiterToken) |
| 617 return token.delimiter(); | 614 return token.delimiter(); |
| 618 return 0; | 615 return 0; |
| 619 } | 616 } |
| 620 | 617 |
| 621 bool parseValue(CSSParserTokenRange& tokens, Value* result) | 618 bool parseValue(CSSParserTokenRange& tokens, Value* result) |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 | 702 |
| 706 return true; | 703 return true; |
| 707 } | 704 } |
| 708 | 705 |
| 709 bool parseValueExpression(CSSParserTokenRange& tokens, int depth, Value* res
ult) | 706 bool parseValueExpression(CSSParserTokenRange& tokens, int depth, Value* res
ult) |
| 710 { | 707 { |
| 711 return parseAdditiveValueExpression(tokens, depth, result); | 708 return parseAdditiveValueExpression(tokens, depth, result); |
| 712 } | 709 } |
| 713 }; | 710 }; |
| 714 | 711 |
| 715 PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode
(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> value, bool isInteger) | 712 RawPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode(RawPtr<CSSPrimi
tiveValue> value, bool isInteger) |
| 716 { | 713 { |
| 717 return CSSCalcPrimitiveValue::create(value, isInteger); | 714 return CSSCalcPrimitiveValue::create(value, isInteger); |
| 718 } | 715 } |
| 719 | 716 |
| 720 PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode
(PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> leftSide, PassRefPtrWillBeRawPtr<
CSSCalcExpressionNode> rightSide, CalcOperator op) | 717 RawPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode(RawPtr<CSSCalcE
xpressionNode> leftSide, RawPtr<CSSCalcExpressionNode> rightSide, CalcOperator o
p) |
| 721 { | 718 { |
| 722 return CSSCalcBinaryOperation::create(leftSide, rightSide, op); | 719 return CSSCalcBinaryOperation::create(leftSide, rightSide, op); |
| 723 } | 720 } |
| 724 | 721 |
| 725 PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode
(double pixels, double percent) | 722 RawPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode(double pixels,
double percent) |
| 726 { | 723 { |
| 727 return createExpressionNode( | 724 return createExpressionNode( |
| 728 createExpressionNode(CSSPrimitiveValue::create(pixels, CSSPrimitiveValue
::UnitType::Pixels), pixels == trunc(pixels)), | 725 createExpressionNode(CSSPrimitiveValue::create(pixels, CSSPrimitiveValue
::UnitType::Pixels), pixels == trunc(pixels)), |
| 729 createExpressionNode(CSSPrimitiveValue::create(percent, CSSPrimitiveValu
e::UnitType::Percentage), percent == trunc(percent)), | 726 createExpressionNode(CSSPrimitiveValue::create(percent, CSSPrimitiveValu
e::UnitType::Percentage), percent == trunc(percent)), |
| 730 CalcAdd); | 727 CalcAdd); |
| 731 } | 728 } |
| 732 | 729 |
| 733 PassRefPtrWillBeRawPtr<CSSCalcValue> CSSCalcValue::create(const CSSParserTokenRa
nge& tokens, ValueRange range) | 730 RawPtr<CSSCalcValue> CSSCalcValue::create(const CSSParserTokenRange& tokens, Val
ueRange range) |
| 734 { | 731 { |
| 735 CSSCalcExpressionNodeParser parser; | 732 CSSCalcExpressionNodeParser parser; |
| 736 RefPtrWillBeRawPtr<CSSCalcExpressionNode> expression = parser.parseCalc(toke
ns); | 733 RawPtr<CSSCalcExpressionNode> expression = parser.parseCalc(tokens); |
| 737 | 734 |
| 738 return expression ? adoptRefWillBeNoop(new CSSCalcValue(expression, range))
: nullptr; | 735 return expression ? (new CSSCalcValue(expression, range)) : nullptr; |
| 739 } | 736 } |
| 740 | 737 |
| 741 PassRefPtrWillBeRawPtr<CSSCalcValue> CSSCalcValue::create(PassRefPtrWillBeRawPtr
<CSSCalcExpressionNode> expression, ValueRange range) | 738 RawPtr<CSSCalcValue> CSSCalcValue::create(RawPtr<CSSCalcExpressionNode> expressi
on, ValueRange range) |
| 742 { | 739 { |
| 743 return adoptRefWillBeNoop(new CSSCalcValue(expression, range)); | 740 return (new CSSCalcValue(expression, range)); |
| 744 } | 741 } |
| 745 | 742 |
| 746 } // namespace blink | 743 } // namespace blink |
| OLD | NEW |