Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / css / CSSCalculationValue.cpp
index 58ce6d7..ee079d5 100644 (file)
@@ -45,15 +45,12 @@ enum ParseState {
     NoMoreTokens
 };
 
-namespace WebCore {
+namespace blink {
 
-DEFINE_GC_INFO(CSSCalcExpressionNode);
-
-static CalculationCategory unitCategory(CSSPrimitiveValue::UnitTypes type)
+static CalculationCategory unitCategory(CSSPrimitiveValue::UnitType type)
 {
     switch (type) {
     case CSSPrimitiveValue::CSS_NUMBER:
-    case CSSPrimitiveValue::CSS_PARSER_INTEGER:
         return CalcNumber;
     case CSSPrimitiveValue::CSS_PERCENTAGE:
         return CalcPercent;
@@ -72,16 +69,26 @@ static CalculationCategory unitCategory(CSSPrimitiveValue::UnitTypes type)
     case CSSPrimitiveValue::CSS_VMIN:
     case CSSPrimitiveValue::CSS_VMAX:
         return CalcLength;
+    case CSSPrimitiveValue::CSS_DEG:
+    case CSSPrimitiveValue::CSS_GRAD:
+    case CSSPrimitiveValue::CSS_RAD:
+    case CSSPrimitiveValue::CSS_TURN:
+        return CalcAngle;
+    case CSSPrimitiveValue::CSS_MS:
+    case CSSPrimitiveValue::CSS_S:
+        return CalcTime;
+    case CSSPrimitiveValue::CSS_HZ:
+    case CSSPrimitiveValue::CSS_KHZ:
+        return CalcFrequency;
     default:
         return CalcOther;
     }
 }
 
-static bool hasDoubleValue(CSSPrimitiveValue::UnitTypes type)
+static bool hasDoubleValue(CSSPrimitiveValue::UnitType type)
 {
     switch (type) {
     case CSSPrimitiveValue::CSS_NUMBER:
-    case CSSPrimitiveValue::CSS_PARSER_INTEGER:
     case CSSPrimitiveValue::CSS_PERCENTAGE:
     case CSSPrimitiveValue::CSS_EMS:
     case CSSPrimitiveValue::CSS_EXS:
@@ -96,6 +103,7 @@ static bool hasDoubleValue(CSSPrimitiveValue::UnitTypes type)
     case CSSPrimitiveValue::CSS_DEG:
     case CSSPrimitiveValue::CSS_RAD:
     case CSSPrimitiveValue::CSS_GRAD:
+    case CSSPrimitiveValue::CSS_TURN:
     case CSSPrimitiveValue::CSS_MS:
     case CSSPrimitiveValue::CSS_S:
     case CSSPrimitiveValue::CSS_HZ:
@@ -120,10 +128,7 @@ static bool hasDoubleValue(CSSPrimitiveValue::UnitTypes type)
     case CSSPrimitiveValue::CSS_RGBCOLOR:
     case CSSPrimitiveValue::CSS_PAIR:
     case CSSPrimitiveValue::CSS_UNICODE_RANGE:
-    case CSSPrimitiveValue::CSS_PARSER_OPERATOR:
     case CSSPrimitiveValue::CSS_PARSER_HEXCOLOR:
-    case CSSPrimitiveValue::CSS_PARSER_IDENTIFIER:
-    case CSSPrimitiveValue::CSS_TURN:
     case CSSPrimitiveValue::CSS_COUNTER_NAME:
     case CSSPrimitiveValue::CSS_SHAPE:
     case CSSPrimitiveValue::CSS_QUAD:
@@ -176,9 +181,7 @@ double CSSCalcValue::computeLengthPx(const CSSToLengthConversionData& conversion
     return clampToPermittedRange(m_expression->computeLengthPx(conversionData));
 }
 
-CSSCalcExpressionNode::~CSSCalcExpressionNode()
-{
-}
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CSSCalcExpressionNode)
 
 class CSSCalcPrimitiveValue FINAL : public CSSCalcExpressionNode {
     WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
@@ -189,10 +192,10 @@ public:
         return adoptRefWillBeNoop(new CSSCalcPrimitiveValue(value, isInteger));
     }
 
-    static PassRefPtrWillBeRawPtr<CSSCalcPrimitiveValue> create(double value, CSSPrimitiveValue::UnitTypes type, bool isInteger)
+    static PassRefPtrWillBeRawPtr<CSSCalcPrimitiveValue> create(double value, CSSPrimitiveValue::UnitType type, bool isInteger)
     {
         if (std::isnan(value) || std::isinf(value))
-            return 0;
+            return nullptr;
         return adoptRefWillBeNoop(new CSSCalcPrimitiveValue(CSSPrimitiveValue::create(value, type).get(), isInteger));
     }
 
@@ -206,23 +209,19 @@ public:
         return m_value->cssText();
     }
 
-    virtual PassOwnPtr<CalcExpressionNode> toCalcValue(const CSSToLengthConversionData& conversionData) const OVERRIDE
+    virtual void accumulatePixelsAndPercent(const CSSToLengthConversionData& conversionData, PixelsAndPercent& value, float multiplier) const OVERRIDE
     {
         switch (m_category) {
-        case CalcNumber:
-            return adoptPtr(new CalcExpressionNumber(m_value->getFloatValue()));
         case CalcLength:
-            return adoptPtr(new CalcExpressionLength(Length(m_value->computeLength<float>(conversionData), WebCore::Fixed)));
+            value.pixels += m_value->computeLength<float>(conversionData) * multiplier;
+            break;
         case CalcPercent:
-        case CalcPercentLength:
-            return adoptPtr(new CalcExpressionLength(m_value->convertToLength<FixedConversion | PercentConversion>(conversionData)));
-        // Only types that could be part of a Length expression can be converted
-        // to a CalcExpressionNode. CalcPercentNumber makes no sense as a Length.
-        case CalcPercentNumber:
-        case CalcOther:
+            ASSERT(m_value->isPercentage());
+            value.percent += m_value->getDoubleValue() * multiplier;
+            break;
+        default:
             ASSERT_NOT_REACHED();
         }
-        return nullptr;
     }
 
     virtual double doubleValue() const OVERRIDE
@@ -238,11 +237,14 @@ public:
         switch (m_category) {
         case CalcLength:
             return m_value->computeLength<double>(conversionData);
-        case CalcPercent:
         case CalcNumber:
+        case CalcPercent:
             return m_value->getDoubleValue();
+        case CalcAngle:
+        case CalcFrequency:
         case CalcPercentLength:
         case CalcPercentNumber:
+        case CalcTime:
         case CalcOther:
             ASSERT_NOT_REACHED();
             break;
@@ -251,6 +253,12 @@ public:
         return 0;
     }
 
+    virtual void accumulateLengthArray(CSSLengthArray& lengthArray, double multiplier) const
+    {
+        ASSERT(category() != CalcNumber);
+        m_value->accumulateLengthArray(lengthArray, multiplier);
+    }
+
     virtual bool equals(const CSSCalcExpressionNode& other) const OVERRIDE
     {
         if (type() != other.type())
@@ -260,9 +268,9 @@ public:
     }
 
     virtual Type type() const OVERRIDE { return CssCalcPrimitiveValue; }
-    virtual CSSPrimitiveValue::UnitTypes primitiveType() const OVERRIDE
+    virtual CSSPrimitiveValue::UnitType primitiveType() const OVERRIDE
     {
-        return CSSPrimitiveValue::UnitTypes(m_value->primitiveType());
+        return m_value->primitiveType();
     }
 
 
@@ -274,7 +282,7 @@ public:
 
 private:
     CSSCalcPrimitiveValue(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> value, bool isInteger)
-        : CSSCalcExpressionNode(unitCategory((CSSPrimitiveValue::UnitTypes)value->primitiveType()), isInteger)
+        : CSSCalcExpressionNode(unitCategory(value->primitiveType()), isInteger)
         , m_value(value)
     {
     }
@@ -283,12 +291,15 @@ private:
 };
 
 static const CalculationCategory addSubtractResult[CalcOther][CalcOther] = {
-//                        CalcNumber         CalcLength         CalcPercent        CalcPercentNumber  CalcPercentLength
-/* CalcNumber */        { CalcNumber,        CalcOther,         CalcPercentNumber, CalcPercentNumber, CalcOther },
-/* CalcLength */        { CalcOther,         CalcLength,        CalcPercentLength, CalcOther,         CalcPercentLength },
-/* CalcPercent */       { CalcPercentNumber, CalcPercentLength, CalcPercent,       CalcPercentNumber, CalcPercentLength },
-/* CalcPercentNumber */ { CalcPercentNumber, CalcOther,         CalcPercentNumber, CalcPercentNumber, CalcOther },
-/* CalcPercentLength */ { CalcOther,         CalcPercentLength, CalcPercentLength, CalcOther,         CalcPercentLength },
+//                        CalcNumber         CalcLength         CalcPercent        CalcPercentNumber  CalcPercentLength  CalcAngle  CalcTime   CalcFrequency
+/* CalcNumber */        { CalcNumber,        CalcOther,         CalcPercentNumber, CalcPercentNumber, CalcOther,         CalcOther, CalcOther, CalcOther     },
+/* CalcLength */        { CalcOther,         CalcLength,        CalcPercentLength, CalcOther,         CalcPercentLength, CalcOther, CalcOther, CalcOther     },
+/* CalcPercent */       { CalcPercentNumber, CalcPercentLength, CalcPercent,       CalcPercentNumber, CalcPercentLength, CalcOther, CalcOther, CalcOther     },
+/* CalcPercentNumber */ { CalcPercentNumber, CalcOther,         CalcPercentNumber, CalcPercentNumber, CalcOther,         CalcOther, CalcOther, CalcOther     },
+/* CalcPercentLength */ { CalcOther,         CalcPercentLength, CalcPercentLength, CalcOther,         CalcPercentLength, CalcOther, CalcOther, CalcOther     },
+/* CalcAngle  */        { CalcOther,         CalcOther,         CalcOther,         CalcOther,         CalcOther,         CalcAngle, CalcOther, CalcOther     },
+/* CalcTime */          { CalcOther,         CalcOther,         CalcOther,         CalcOther,         CalcOther,         CalcOther, CalcTime,  CalcOther     },
+/* CalcFrequency */     { CalcOther,         CalcOther,         CalcOther,         CalcOther,         CalcOther,         CalcOther, CalcOther, CalcFrequency }
 };
 
 static CalculationCategory determineCategory(const CSSCalcExpressionNode& leftSide, const CSSCalcExpressionNode& rightSide, CalcOperator op)
@@ -333,7 +344,7 @@ public:
 
         CalculationCategory newCategory = determineCategory(*leftSide, *rightSide, op);
         if (newCategory == CalcOther)
-            return 0;
+            return nullptr;
 
         return adoptRefWillBeNoop(new CSSCalcBinaryOperation(leftSide, rightSide, op, newCategory));
     }
@@ -348,21 +359,20 @@ public:
 
         // Simplify numbers.
         if (leftCategory == CalcNumber && rightCategory == CalcNumber) {
-            CSSPrimitiveValue::UnitTypes evaluationType = isInteger ? CSSPrimitiveValue::CSS_PARSER_INTEGER : CSSPrimitiveValue::CSS_NUMBER;
-            return CSSCalcPrimitiveValue::create(evaluateOperator(leftSide->doubleValue(), rightSide->doubleValue(), op), evaluationType, isInteger);
+            return CSSCalcPrimitiveValue::create(evaluateOperator(leftSide->doubleValue(), rightSide->doubleValue(), op), CSSPrimitiveValue::CSS_NUMBER, isInteger);
         }
 
         // Simplify addition and subtraction between same types.
         if (op == CalcAdd || op == CalcSubtract) {
             if (leftCategory == rightSide->category()) {
-                CSSPrimitiveValue::UnitTypes leftType = leftSide->primitiveType();
+                CSSPrimitiveValue::UnitType leftType = leftSide->primitiveType();
                 if (hasDoubleValue(leftType)) {
-                    CSSPrimitiveValue::UnitTypes rightType = rightSide->primitiveType();
+                    CSSPrimitiveValue::UnitType rightType = rightSide->primitiveType();
                     if (leftType == rightType)
                         return CSSCalcPrimitiveValue::create(evaluateOperator(leftSide->doubleValue(), rightSide->doubleValue(), op), leftType, isInteger);
                     CSSPrimitiveValue::UnitCategory leftUnitCategory = CSSPrimitiveValue::unitCategory(leftType);
                     if (leftUnitCategory != CSSPrimitiveValue::UOther && leftUnitCategory == CSSPrimitiveValue::unitCategory(rightType)) {
-                        CSSPrimitiveValue::UnitTypes canonicalType = CSSPrimitiveValue::canonicalUnitTypeForCategory(leftUnitCategory);
+                        CSSPrimitiveValue::UnitType canonicalType = CSSPrimitiveValue::canonicalUnitTypeForCategory(leftUnitCategory);
                         if (canonicalType != CSSPrimitiveValue::CSS_UNKNOWN) {
                             double leftValue = leftSide->doubleValue() * CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(leftType);
                             double rightValue = rightSide->doubleValue() * CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(rightType);
@@ -378,16 +388,16 @@ public:
             if (!numberSide)
                 return create(leftSide, rightSide, op);
             if (numberSide == leftSide && op == CalcDivide)
-                return 0;
+                return nullptr;
             CSSCalcExpressionNode* otherSide = leftSide == numberSide ? rightSide.get() : leftSide.get();
 
             double number = numberSide->doubleValue();
             if (std::isnan(number) || std::isinf(number))
-                return 0;
+                return nullptr;
             if (op == CalcDivide && !number)
-                return 0;
+                return nullptr;
 
-            CSSPrimitiveValue::UnitTypes otherType = otherSide->primitiveType();
+            CSSPrimitiveValue::UnitType otherType = otherSide->primitiveType();
             if (hasDoubleValue(otherType))
                 return CSSCalcPrimitiveValue::create(evaluateOperator(otherSide->doubleValue(), number, op), otherType, isInteger);
         }
@@ -400,15 +410,31 @@ public:
         return !doubleValue();
     }
 
-    virtual PassOwnPtr<CalcExpressionNode> toCalcValue(const CSSToLengthConversionData& conversionData) const OVERRIDE
+    virtual void accumulatePixelsAndPercent(const CSSToLengthConversionData& conversionData, PixelsAndPercent& value, float multiplier) const OVERRIDE
     {
-        OwnPtr<CalcExpressionNode> left(m_leftSide->toCalcValue(conversionData));
-        if (!left)
-            return nullptr;
-        OwnPtr<CalcExpressionNode> right(m_rightSide->toCalcValue(conversionData));
-        if (!right)
-            return nullptr;
-        return adoptPtr(new CalcExpressionBinaryOperation(left.release(), right.release(), m_operator));
+        switch (m_operator) {
+        case CalcAdd:
+            m_leftSide->accumulatePixelsAndPercent(conversionData, value, multiplier);
+            m_rightSide->accumulatePixelsAndPercent(conversionData, value, multiplier);
+            break;
+        case CalcSubtract:
+            m_leftSide->accumulatePixelsAndPercent(conversionData, value, multiplier);
+            m_rightSide->accumulatePixelsAndPercent(conversionData, value, -multiplier);
+            break;
+        case CalcMultiply:
+            ASSERT((m_leftSide->category() == CalcNumber) != (m_rightSide->category() == CalcNumber));
+            if (m_leftSide->category() == CalcNumber)
+                m_rightSide->accumulatePixelsAndPercent(conversionData, value, multiplier * m_leftSide->doubleValue());
+            else
+                m_leftSide->accumulatePixelsAndPercent(conversionData, value, multiplier * m_rightSide->doubleValue());
+            break;
+        case CalcDivide:
+            ASSERT(m_rightSide->category() == CalcNumber);
+            m_leftSide->accumulatePixelsAndPercent(conversionData, value, multiplier / m_rightSide->doubleValue());
+            break;
+        default:
+            ASSERT_NOT_REACHED();
+        }
     }
 
     virtual double doubleValue() const OVERRIDE
@@ -423,6 +449,33 @@ public:
         return evaluate(leftValue, rightValue);
     }
 
+    virtual void accumulateLengthArray(CSSLengthArray& lengthArray, double multiplier) const
+    {
+        switch (m_operator) {
+        case CalcAdd:
+            m_leftSide->accumulateLengthArray(lengthArray, multiplier);
+            m_rightSide->accumulateLengthArray(lengthArray, multiplier);
+            break;
+        case CalcSubtract:
+            m_leftSide->accumulateLengthArray(lengthArray, multiplier);
+            m_rightSide->accumulateLengthArray(lengthArray, -multiplier);
+            break;
+        case CalcMultiply:
+            ASSERT((m_leftSide->category() == CalcNumber) != (m_rightSide->category() == CalcNumber));
+            if (m_leftSide->category() == CalcNumber)
+                m_rightSide->accumulateLengthArray(lengthArray, multiplier * m_leftSide->doubleValue());
+            else
+                m_leftSide->accumulateLengthArray(lengthArray, multiplier * m_rightSide->doubleValue());
+            break;
+        case CalcDivide:
+            ASSERT(m_rightSide->category() == CalcNumber);
+            m_leftSide->accumulateLengthArray(lengthArray, multiplier / m_rightSide->doubleValue());
+            break;
+        default:
+            ASSERT_NOT_REACHED();
+        }
+    }
+
     static String buildCSSText(const String& leftExpression, const String& rightExpression, CalcOperator op)
     {
         StringBuilder result;
@@ -455,13 +508,11 @@ public:
 
     virtual Type type() const OVERRIDE { return CssCalcBinaryOperation; }
 
-    virtual CSSPrimitiveValue::UnitTypes primitiveType() const OVERRIDE
+    virtual CSSPrimitiveValue::UnitType primitiveType() const OVERRIDE
     {
         switch (m_category) {
         case CalcNumber:
             ASSERT(m_leftSide->category() == CalcNumber && m_rightSide->category() == CalcNumber);
-            if (m_isInteger)
-                return CSSPrimitiveValue::CSS_PARSER_INTEGER;
             return CSSPrimitiveValue::CSS_NUMBER;
         case CalcLength:
         case CalcPercent: {
@@ -469,11 +520,17 @@ public:
                 return m_rightSide->primitiveType();
             if (m_rightSide->category() == CalcNumber)
                 return m_leftSide->primitiveType();
-            CSSPrimitiveValue::UnitTypes leftType = m_leftSide->primitiveType();
+            CSSPrimitiveValue::UnitType leftType = m_leftSide->primitiveType();
             if (leftType == m_rightSide->primitiveType())
                 return leftType;
             return CSSPrimitiveValue::CSS_UNKNOWN;
         }
+        case CalcAngle:
+            return CSSPrimitiveValue::CSS_DEG;
+        case CalcTime:
+            return CSSPrimitiveValue::CSS_MS;
+        case CalcFrequency:
+            return CSSPrimitiveValue::CSS_HZ;
         case CalcPercentLength:
         case CalcPercentNumber:
         case CalcOther:
@@ -546,7 +603,7 @@ static ParseState checkDepthAndIndex(int* depth, unsigned index, CSSParserValueL
 }
 
 class CSSCalcExpressionNodeParser {
-    DISALLOW_ALLOCATION(); // Is only ever stack allocated.
+    STACK_ALLOCATED();
 public:
     PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> parseCalc(CSSParserValueList* tokens)
     {
@@ -555,15 +612,15 @@ public:
         bool ok = parseValueExpression(tokens, 0, &index, &result);
         ASSERT_WITH_SECURITY_IMPLICATION(index <= tokens->size());
         if (!ok || index != tokens->size())
-            return 0;
+            return nullptr;
         return result.value;
     }
 
 private:
     struct Value {
-        DISALLOW_ALLOCATION(); // Is only ever stack allocated.
+        STACK_ALLOCATED();
     public:
-        RefPtrWillBeRawPtr<CSSCalcExpressionNode> value;
+        RefPtrWillBeMember<CSSCalcExpressionNode> value;
     };
 
     char operatorValue(CSSParserValueList* tokens, unsigned index)
@@ -580,14 +637,15 @@ private:
     bool parseValue(CSSParserValueList* tokens, unsigned* index, Value* result)
     {
         CSSParserValue* parserValue = tokens->valueAt(*index);
-        if (parserValue->unit == CSSParserValue::Operator)
+        if (parserValue->unit >= CSSParserValue::Operator)
             return false;
 
-        RefPtr<CSSValue> value = parserValue->createCSSValue();
-        if (!value || !value->isPrimitiveValue())
+        CSSPrimitiveValue::UnitType type = static_cast<CSSPrimitiveValue::UnitType>(parserValue->unit);
+        if (unitCategory(type) == CalcOther)
             return false;
 
-        result->value = CSSCalcPrimitiveValue::create(toCSSPrimitiveValue(value.get()), parserValue->isInt);
+        result->value = CSSCalcPrimitiveValue::create(
+            CSSPrimitiveValue::create(parserValue->fValue, type), parserValue->isInt);
 
         ++*index;
         return true;
@@ -682,84 +740,29 @@ PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode
     return CSSCalcBinaryOperation::create(leftSide, rightSide, op);
 }
 
-PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode(const CalcExpressionNode* node, float zoom)
+PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode(double pixels, double percent)
 {
-    switch (node->type()) {
-    case CalcExpressionNodeNumber: {
-        float value = toCalcExpressionNumber(node)->value();
-        return createExpressionNode(CSSPrimitiveValue::create(value, CSSPrimitiveValue::CSS_NUMBER), value == trunc(value));
-    }
-    case CalcExpressionNodeLength:
-        return createExpressionNode(toCalcExpressionLength(node)->length(), zoom);
-    case CalcExpressionNodeBinaryOperation: {
-        const CalcExpressionBinaryOperation* binaryNode = toCalcExpressionBinaryOperation(node);
-        return createExpressionNode(createExpressionNode(binaryNode->leftSide(), zoom), createExpressionNode(binaryNode->rightSide(), zoom), binaryNode->getOperator());
-    }
-    case CalcExpressionNodeBlendLength: {
-        // FIXME(crbug.com/269320): Create a CSSCalcExpressionNode equivalent of CalcExpressionBlendLength.
-        const CalcExpressionBlendLength* blendNode = toCalcExpressionBlendLength(node);
-        const double progress = blendNode->progress();
-        const bool isInteger = !progress || (progress == 1);
-        return createExpressionNode(
-            createExpressionNode(
-                createExpressionNode(blendNode->from(), zoom),
-                createExpressionNode(CSSPrimitiveValue::create(1 - progress, CSSPrimitiveValue::CSS_NUMBER), isInteger),
-                CalcMultiply),
-            createExpressionNode(
-                createExpressionNode(blendNode->to(), zoom),
-                createExpressionNode(CSSPrimitiveValue::create(progress, CSSPrimitiveValue::CSS_NUMBER), isInteger),
-                CalcMultiply),
-            CalcAdd);
-    }
-    case CalcExpressionNodeUndefined:
-        ASSERT_NOT_REACHED();
-        return 0;
-    }
-    ASSERT_NOT_REACHED();
-    return 0;
-}
-
-PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode(const Length& length, float zoom)
-{
-    switch (length.type()) {
-    case Percent:
-    case Fixed:
-        return createExpressionNode(CSSPrimitiveValue::create(length, zoom), length.value() == trunc(length.value()));
-    case Calculated:
-        return createExpressionNode(length.calculationValue()->expression(), zoom);
-    case Auto:
-    case Intrinsic:
-    case MinIntrinsic:
-    case MinContent:
-    case MaxContent:
-    case FillAvailable:
-    case FitContent:
-    case ExtendToZoom:
-    case DeviceWidth:
-    case DeviceHeight:
-    case Undefined:
-        ASSERT_NOT_REACHED();
-        return 0;
-    }
-    ASSERT_NOT_REACHED();
-    return 0;
+    return createExpressionNode(
+        createExpressionNode(CSSPrimitiveValue::create(pixels, CSSPrimitiveValue::CSS_PX), pixels == trunc(pixels)),
+        createExpressionNode(CSSPrimitiveValue::create(percent, CSSPrimitiveValue::CSS_PERCENTAGE), percent == trunc(percent)),
+        CalcAdd);
 }
 
 PassRefPtrWillBeRawPtr<CSSCalcValue> CSSCalcValue::create(CSSParserString name, CSSParserValueList* parserValueList, ValueRange range)
 {
     CSSCalcExpressionNodeParser parser;
-    RefPtrWillBeRawPtr<CSSCalcExpressionNode> expression;
+    RefPtrWillBeRawPtr<CSSCalcExpressionNode> expression = nullptr;
 
     if (equalIgnoringCase(name, "calc(") || equalIgnoringCase(name, "-webkit-calc("))
         expression = parser.parseCalc(parserValueList);
     // FIXME calc (http://webkit.org/b/16662) Add parsing for min and max here
 
-    return expression ? adoptRefCountedWillBeRefCountedGarbageCollected(new CSSCalcValue(expression, range)) : 0;
+    return expression ? adoptRefWillBeNoop(new CSSCalcValue(expression, range)) : nullptr;
 }
 
 PassRefPtrWillBeRawPtr<CSSCalcValue> CSSCalcValue::create(PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> expression, ValueRange range)
 {
-    return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSCalcValue(expression, range));
+    return adoptRefWillBeNoop(new CSSCalcValue(expression, range));
 }
 
 void CSSCalcValue::traceAfterDispatch(Visitor* visitor)
@@ -768,4 +771,4 @@ void CSSCalcValue::traceAfterDispatch(Visitor* visitor)
     CSSValue::traceAfterDispatch(visitor);
 }
 
-} // namespace WebCore
+} // namespace blink