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;
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:
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:
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:
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;
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));
}
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
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;
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())
}
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();
}
private:
CSSCalcPrimitiveValue(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> value, bool isInteger)
- : CSSCalcExpressionNode(unitCategory((CSSPrimitiveValue::UnitTypes)value->primitiveType()), isInteger)
+ : CSSCalcExpressionNode(unitCategory(value->primitiveType()), isInteger)
, m_value(value)
{
}
};
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)
CalculationCategory newCategory = determineCategory(*leftSide, *rightSide, op);
if (newCategory == CalcOther)
- return 0;
+ return nullptr;
return adoptRefWillBeNoop(new CSSCalcBinaryOperation(leftSide, rightSide, op, newCategory));
}
// 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);
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);
}
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
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;
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: {
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:
}
class CSSCalcExpressionNodeParser {
- DISALLOW_ALLOCATION(); // Is only ever stack allocated.
+ STACK_ALLOCATED();
public:
PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> parseCalc(CSSParserValueList* tokens)
{
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)
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;
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)
CSSValue::traceAfterDispatch(visitor);
}
-} // namespace WebCore
+} // namespace blink