Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(38)

Side by Side Diff: Source/core/css/CSSCalculationValue.cpp

Issue 1239983004: Make CSSCalcValue work with CSSParserTokenRange (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Fix autoclose problem Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 574 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 return std::numeric_limits<double>::quiet_NaN(); 585 return std::numeric_limits<double>::quiet_NaN();
586 } 586 }
587 return 0; 587 return 0;
588 } 588 }
589 589
590 const RefPtrWillBeMember<CSSCalcExpressionNode> m_leftSide; 590 const RefPtrWillBeMember<CSSCalcExpressionNode> m_leftSide;
591 const RefPtrWillBeMember<CSSCalcExpressionNode> m_rightSide; 591 const RefPtrWillBeMember<CSSCalcExpressionNode> m_rightSide;
592 const CalcOperator m_operator; 592 const CalcOperator m_operator;
593 }; 593 };
594 594
595 static ParseState checkDepthAndIndex(int* depth, unsigned index, CSSParserValueL ist* tokens) 595 static ParseState checkDepthAndIndex(int* depth, CSSParserTokenRange tokens)
596 { 596 {
597 (*depth)++; 597 (*depth)++;
598 if (tokens.atEnd())
599 return NoMoreTokens;
598 if (*depth > maxExpressionDepth) 600 if (*depth > maxExpressionDepth)
599 return TooDeep; 601 return TooDeep;
600 if (index >= tokens->size())
601 return NoMoreTokens;
602 return OK; 602 return OK;
603 } 603 }
604 604
605 class CSSCalcExpressionNodeParser { 605 class CSSCalcExpressionNodeParser {
606 STACK_ALLOCATED(); 606 STACK_ALLOCATED();
607 public: 607 public:
608 PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> parseCalc(CSSParserValueList* tokens) 608 PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> parseCalc(CSSParserTokenRange tokens)
609 { 609 {
610 unsigned index = 0;
611 Value result; 610 Value result;
612 bool ok = parseValueExpression(tokens, 0, &index, &result); 611 bool ok = parseValueExpression(tokens, 0, &result);
613 ASSERT_WITH_SECURITY_IMPLICATION(index <= tokens->size()); 612 if (!ok || !tokens.atEnd())
614 if (!ok || index != tokens->size())
615 return nullptr; 613 return nullptr;
616 return result.value; 614 return result.value;
617 } 615 }
618 616
619 private: 617 private:
620 struct Value { 618 struct Value {
621 STACK_ALLOCATED(); 619 STACK_ALLOCATED();
622 public: 620 public:
623 RefPtrWillBeMember<CSSCalcExpressionNode> value; 621 RefPtrWillBeMember<CSSCalcExpressionNode> value;
624 }; 622 };
625 623
626 char operatorValue(CSSParserValueList* tokens, unsigned index) 624 char operatorValue(CSSParserTokenRange& tokens)
Timothy Loh 2015/07/21 07:33:17 I don't think this function helps, or at least it
rwlbuis 2015/07/22 02:19:06 Perhaps. I did not want to change the original cod
Timothy Loh 2015/07/28 08:17:40 I think this function makes it hard to verify that
627 { 625 {
628 if (index >= tokens->size()) 626 tokens.consumeWhitespace();
629 return 0; 627 // Use peek since we do not want to consume in case
630 CSSParserValue* value = tokens->valueAt(index); 628 // the operator is not the expected mult/add operation.
631 if (value->unit != CSSParserValue::Operator) 629 CSSParserToken value = tokens.peek();
632 return 0; 630 if (value.type() == DelimiterToken)
633 631 return value.delimiter();
634 return value->iValue; 632 if (value.type() == LeftParenthesisToken)
633 return '(';
634 if (value.type() == RightParenthesisToken)
635 return ')';
636 return 0;
635 } 637 }
636 638
637 bool parseValue(CSSParserValueList* tokens, unsigned* index, Value* result) 639 bool parseValue(CSSParserTokenRange& tokens, Value* result)
638 { 640 {
639 CSSParserValue* parserValue = tokens->valueAt(*index); 641 CSSParserToken token = tokens.consumeSkippingWhitespace();
640 if (parserValue->unit >= CSSParserValue::Operator) 642 CSSPrimitiveValue::UnitType type = token.unitType();
alancutter (OOO until 2018) 2015/07/21 07:44:26 This line should stay after the token.type() check
rwlbuis 2015/07/21 21:29:52 Done.
643 if (!(token.type() == NumberToken || token.type() == PercentageToken || token.type() == DimensionToken))
641 return false; 644 return false;
642 645
643 CSSPrimitiveValue::UnitType type = static_cast<CSSPrimitiveValue::UnitTy pe>(parserValue->unit);
644 if (unitCategory(type) == CalcOther) 646 if (unitCategory(type) == CalcOther)
645 return false; 647 return false;
646 648
647 result->value = CSSCalcPrimitiveValue::create( 649 result->value = CSSCalcPrimitiveValue::create(
648 CSSPrimitiveValue::create(parserValue->fValue, type), parserValue->i sInt); 650 CSSPrimitiveValue::create(token.numericValue(), type), token.numeric ValueType() == IntegerValueType);
649 651
650 ++*index;
651 return true; 652 return true;
652 } 653 }
653 654
654 bool parseValueTerm(CSSParserValueList* tokens, int depth, unsigned* index, Value* result) 655 bool parseValueTerm(CSSParserTokenRange& tokens, int depth, Value* result)
655 { 656 {
656 if (checkDepthAndIndex(&depth, *index, tokens) != OK) 657 if (checkDepthAndIndex(&depth, tokens) != OK)
657 return false; 658 return false;
658 659
659 if (operatorValue(tokens, *index) == '(') { 660 if (operatorValue(tokens) == '(') {
660 unsigned currentIndex = *index + 1; 661 tokens.consume();
661 if (!parseValueExpression(tokens, depth, &currentIndex, result)) 662 if (!parseValueExpression(tokens, depth, result))
662 return false; 663 return false;
663 664
664 if (operatorValue(tokens, currentIndex) != ')') 665 if (operatorValue(tokens) != ')')
665 return false; 666 return false;
666 *index = currentIndex + 1; 667 tokens.consume();
667 return true; 668 return true;
668 } 669 }
669 670
670 return parseValue(tokens, index, result); 671 return parseValue(tokens, result);
671 } 672 }
672 673
673 bool parseValueMultiplicativeExpression(CSSParserValueList* tokens, int dept h, unsigned* index, Value* result) 674 bool parseValueMultiplicativeExpression(CSSParserTokenRange& tokens, int dep th, Value* result)
674 { 675 {
675 if (checkDepthAndIndex(&depth, *index, tokens) != OK) 676 if (checkDepthAndIndex(&depth, tokens) != OK)
676 return false; 677 return false;
677 678
678 if (!parseValueTerm(tokens, depth, index, result)) 679 if (!parseValueTerm(tokens, depth, result))
679 return false; 680 return false;
680 681
681 while (*index < tokens->size() - 1) { 682 while (!tokens.atEnd()) {
682 char operatorCharacter = operatorValue(tokens, *index); 683 char operatorCharacter = operatorValue(tokens);
683 if (operatorCharacter != CalcMultiply && operatorCharacter != CalcDi vide) 684 if (operatorCharacter != CalcMultiply && operatorCharacter != CalcDi vide)
684 break; 685 break;
685 ++*index; 686 tokens.consume();
686 687
687 Value rhs; 688 Value rhs;
688 if (!parseValueTerm(tokens, depth, index, &rhs)) 689 if (!parseValueTerm(tokens, depth, &rhs))
689 return false; 690 return false;
690 691
691 result->value = CSSCalcBinaryOperation::createSimplified(result->val ue, rhs.value, static_cast<CalcOperator>(operatorCharacter)); 692 result->value = CSSCalcBinaryOperation::createSimplified(result->val ue, rhs.value, static_cast<CalcOperator>(operatorCharacter));
692 if (!result->value) 693 if (!result->value)
693 return false; 694 return false;
694 } 695 }
695 696
696 ASSERT_WITH_SECURITY_IMPLICATION(*index <= tokens->size());
697 return true; 697 return true;
698 } 698 }
699 699
700 bool parseAdditiveValueExpression(CSSParserValueList* tokens, int depth, uns igned* index, Value* result) 700 bool parseAdditiveValueExpression(CSSParserTokenRange& tokens, int depth, Va lue* result)
701 { 701 {
702 if (checkDepthAndIndex(&depth, *index, tokens) != OK) 702 if (checkDepthAndIndex(&depth, tokens) != OK)
703 return false; 703 return false;
704 704
705 if (!parseValueMultiplicativeExpression(tokens, depth, index, result)) 705 if (!parseValueMultiplicativeExpression(tokens, depth, result))
706 return false; 706 return false;
707 707
708 while (*index < tokens->size() - 1) { 708 while (!tokens.atEnd()) {
709 char operatorCharacter = operatorValue(tokens, *index); 709 char operatorCharacter = operatorValue(tokens);
710 if (operatorCharacter != CalcAdd && operatorCharacter != CalcSubtrac t) 710 if (operatorCharacter != CalcAdd && operatorCharacter != CalcSubtrac t)
711 break; 711 break;
712 ++*index; 712 if (operatorCharacter == CalcAdd && (&tokens.peek() - 1)->type() != WhitespaceToken)
713 return false; // calc(1px+ 2px) is invalid
Timothy Loh 2015/07/21 07:33:17 Probably need to check the other side too, calc(1p
rwlbuis 2015/07/22 02:19:06 I think it works, I found a similar test in calc-e
Timothy Loh 2015/07/28 08:17:40 I didn't see any such tests. You need to check the
714 tokens.consume();
713 715
714 Value rhs; 716 Value rhs;
715 if (!parseValueMultiplicativeExpression(tokens, depth, index, &rhs)) 717 if (!parseValueMultiplicativeExpression(tokens, depth, &rhs))
716 return false; 718 return false;
717 719
718 result->value = CSSCalcBinaryOperation::createSimplified(result->val ue, rhs.value, static_cast<CalcOperator>(operatorCharacter)); 720 result->value = CSSCalcBinaryOperation::createSimplified(result->val ue, rhs.value, static_cast<CalcOperator>(operatorCharacter));
719 if (!result->value) 721 if (!result->value)
720 return false; 722 return false;
721 } 723 }
722 724
723 ASSERT_WITH_SECURITY_IMPLICATION(*index <= tokens->size());
724 return true; 725 return true;
725 } 726 }
726 727
727 bool parseValueExpression(CSSParserValueList* tokens, int depth, unsigned* i ndex, Value* result) 728 bool parseValueExpression(CSSParserTokenRange& tokens, int depth, Value* res ult)
728 { 729 {
729 return parseAdditiveValueExpression(tokens, depth, index, result); 730 return parseAdditiveValueExpression(tokens, depth, result);
730 } 731 }
731 }; 732 };
732 733
733 PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode (PassRefPtrWillBeRawPtr<CSSPrimitiveValue> value, bool isInteger) 734 PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode (PassRefPtrWillBeRawPtr<CSSPrimitiveValue> value, bool isInteger)
734 { 735 {
735 return CSSCalcPrimitiveValue::create(value, isInteger); 736 return CSSCalcPrimitiveValue::create(value, isInteger);
736 } 737 }
737 738
738 PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode (PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> leftSide, PassRefPtrWillBeRawPtr< CSSCalcExpressionNode> rightSide, CalcOperator op) 739 PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode (PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> leftSide, PassRefPtrWillBeRawPtr< CSSCalcExpressionNode> rightSide, CalcOperator op)
739 { 740 {
740 return CSSCalcBinaryOperation::create(leftSide, rightSide, op); 741 return CSSCalcBinaryOperation::create(leftSide, rightSide, op);
741 } 742 }
742 743
743 PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode (double pixels, double percent) 744 PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode (double pixels, double percent)
744 { 745 {
745 return createExpressionNode( 746 return createExpressionNode(
746 createExpressionNode(CSSPrimitiveValue::create(pixels, CSSPrimitiveValue ::CSS_PX), pixels == trunc(pixels)), 747 createExpressionNode(CSSPrimitiveValue::create(pixels, CSSPrimitiveValue ::CSS_PX), pixels == trunc(pixels)),
747 createExpressionNode(CSSPrimitiveValue::create(percent, CSSPrimitiveValu e::CSS_PERCENTAGE), percent == trunc(percent)), 748 createExpressionNode(CSSPrimitiveValue::create(percent, CSSPrimitiveValu e::CSS_PERCENTAGE), percent == trunc(percent)),
748 CalcAdd); 749 CalcAdd);
749 } 750 }
750 751
751 PassRefPtrWillBeRawPtr<CSSCalcValue> CSSCalcValue::create(CSSParserValueList* pa rserValueList, ValueRange range) 752 PassRefPtrWillBeRawPtr<CSSCalcValue> CSSCalcValue::create(const CSSParserTokenRa nge& parserValueList, ValueRange range)
alancutter (OOO until 2018) 2015/07/21 07:44:26 s/parserValueList/tokens/
rwlbuis 2015/07/21 21:29:52 Done.
752 { 753 {
753 CSSCalcExpressionNodeParser parser; 754 CSSCalcExpressionNodeParser parser;
754 RefPtrWillBeRawPtr<CSSCalcExpressionNode> expression = parser.parseCalc(pars erValueList); 755 RefPtrWillBeRawPtr<CSSCalcExpressionNode> expression = parser.parseCalc(pars erValueList);
755 756
756 return expression ? adoptRefWillBeNoop(new CSSCalcValue(expression, range)) : nullptr; 757 return expression ? adoptRefWillBeNoop(new CSSCalcValue(expression, range)) : nullptr;
757 } 758 }
758 759
759 PassRefPtrWillBeRawPtr<CSSCalcValue> CSSCalcValue::create(PassRefPtrWillBeRawPtr <CSSCalcExpressionNode> expression, ValueRange range) 760 PassRefPtrWillBeRawPtr<CSSCalcValue> CSSCalcValue::create(PassRefPtrWillBeRawPtr <CSSCalcExpressionNode> expression, ValueRange range)
760 { 761 {
761 return adoptRefWillBeNoop(new CSSCalcValue(expression, range)); 762 return adoptRefWillBeNoop(new CSSCalcValue(expression, range));
762 } 763 }
763 764
764 DEFINE_TRACE_AFTER_DISPATCH(CSSCalcValue) 765 DEFINE_TRACE_AFTER_DISPATCH(CSSCalcValue)
765 { 766 {
766 visitor->trace(m_expression); 767 visitor->trace(m_expression);
767 CSSValue::traceAfterDispatch(visitor); 768 CSSValue::traceAfterDispatch(visitor);
768 } 769 }
769 770
770 } // namespace blink 771 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698