From ac20ee9ffda40fd1c1714ec3a000bbf27c3eee33 Mon Sep 17 00:00:00 2001 From: Martin Hodovan Date: Tue, 13 May 2014 17:08:43 +0000 Subject: ASSERTION FAILED: leftCategory != CalcOther && rightCategory != CalcOther in WebCore::CSSCalcBinaryOperation::createSimplified https://bugs.webkit.org/show_bug.cgi?id=132870 Source/WebCore: According to the standard, calc() should be able to handle angle, time and frequency values as well: http://www.w3.org/TR/css3-values/#calc Patch by Martin Hodovan on 2014-05-13 Reviewed by Darin Adler. Test: fast/css/calc-with-angle-time-frequency.html * css/CSSCalculationValue.cpp: (WebCore::unitCategory): (WebCore::CSSCalcPrimitiveValue::createCalcExpression): (WebCore::CSSCalcPrimitiveValue::computeLengthPx): (WebCore::CSSCalcPrimitiveValue::addSubtractResult): (WebCore::CSSCalcPrimitiveValue::determineCategory): (WebCore::CSSCalcBinaryOperation::primitiveType) * css/CSSCalculationValue.h: extending CalculationCategory * css/CSSParser.cpp: (WebCore::CSSParser::validCalculationUnit): * css/CSSPrimitiveValue.cpp: (WebCore::CSSPrimitiveValue::primitiveType): LayoutTests: Added test contains calc() expressions with angle, time and frequency values, covering all the newly introduced unit types, each of which used to fail. Patch by Martin Hodovan on 2014-05-13 Reviewed by Darin Adler. * fast/css/calc-with-angle-time-frequency-expected.txt: Added. * fast/css/calc-with-angle-time-frequency.html: Added. git-svn-id: http://svn.webkit.org/repository/webkit/trunk@168685 268f45cc-cd09-0410-ab3c-d52691b4dbfc Change-Id: Id342e513bef2aa147dbfc94d2fc5a72e51fd0f57 Reviewed-by: Allan Sandfeld Jensen --- Source/WebCore/css/CSSCalculationValue.cpp | 35 ++++++++++++++++++++++++++---- Source/WebCore/css/CSSCalculationValue.h | 3 +++ Source/WebCore/css/CSSParser.cpp | 23 ++++++++++++++------ Source/WebCore/css/CSSPrimitiveValue.cpp | 10 +++++++-- 4 files changed, 58 insertions(+), 13 deletions(-) diff --git a/Source/WebCore/css/CSSCalculationValue.cpp b/Source/WebCore/css/CSSCalculationValue.cpp index b42a520c2..60fd22adf 100644 --- a/Source/WebCore/css/CSSCalculationValue.cpp +++ b/Source/WebCore/css/CSSCalculationValue.cpp @@ -57,8 +57,6 @@ static CalculationCategory unitCategory(CSSPrimitiveValue::UnitTypes type) case CSSPrimitiveValue::CSS_NUMBER: case CSSPrimitiveValue::CSS_PARSER_INTEGER: return CalcNumber; - case CSSPrimitiveValue::CSS_PERCENTAGE: - return CalcPercent; case CSSPrimitiveValue::CSS_EMS: case CSSPrimitiveValue::CSS_EXS: case CSSPrimitiveValue::CSS_PX: @@ -70,6 +68,19 @@ static CalculationCategory unitCategory(CSSPrimitiveValue::UnitTypes type) case CSSPrimitiveValue::CSS_REMS: case CSSPrimitiveValue::CSS_CHS: return CalcLength; + case CSSPrimitiveValue::CSS_PERCENTAGE: + return CalcPercent; + case CSSPrimitiveValue::CSS_DEG: + case CSSPrimitiveValue::CSS_RAD: + case CSSPrimitiveValue::CSS_GRAD: + 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; #if ENABLE(CSS_VARIABLES) case CSSPrimitiveValue::CSS_VARIABLE_NAME: return CalcVariable; @@ -254,6 +265,9 @@ public: // 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 CalcAngle: + case CalcTime: + case CalcFrequency: #if ENABLE(CSS_VARIABLES) case CalcVariable: #endif @@ -281,6 +295,9 @@ public: return m_value->getDoubleValue(); case CalcPercentLength: case CalcPercentNumber: + case CalcAngle: + case CalcTime: + case CalcFrequency: #if ENABLE(CSS_VARIABLES) case CalcVariable: #endif @@ -316,7 +333,7 @@ private: RefPtr m_value; }; -static const CalculationCategory addSubtractResult[CalcOther][CalcOther] = { +static const CalculationCategory addSubtractResult[CalcAngle][CalcAngle] = { // CalcNumber CalcLength CalcPercent CalcPercentNumber CalcPercentLength { CalcNumber, CalcOther, CalcPercentNumber, CalcPercentNumber, CalcOther }, // CalcNumber { CalcOther, CalcLength, CalcPercentLength, CalcOther, CalcPercentLength }, // CalcLength @@ -341,7 +358,11 @@ static CalculationCategory determineCategory(const CSSCalcExpressionNode& leftSi switch (op) { case CalcAdd: case CalcSubtract: - return addSubtractResult[leftCategory][rightCategory]; + if (leftCategory < CalcAngle || rightCategory < CalcAngle) + return addSubtractResult[leftCategory][rightCategory]; + if (leftCategory == rightCategory) + return leftCategory; + return CalcOther; case CalcMultiply: if (leftCategory != CalcNumber && rightCategory != CalcNumber) return CalcOther; @@ -532,6 +553,12 @@ public: #endif case CalcPercentLength: case CalcPercentNumber: + case CalcAngle: + return CSSPrimitiveValue::CSS_DEG; + case CalcTime: + return CSSPrimitiveValue::CSS_MS; + case CalcFrequency: + return CSSPrimitiveValue::CSS_HZ; case CalcOther: return CSSPrimitiveValue::CSS_UNKNOWN; } diff --git a/Source/WebCore/css/CSSCalculationValue.h b/Source/WebCore/css/CSSCalculationValue.h index 13a17a3b7..27ff176f1 100644 --- a/Source/WebCore/css/CSSCalculationValue.h +++ b/Source/WebCore/css/CSSCalculationValue.h @@ -54,6 +54,9 @@ enum CalculationCategory { CalcPercent, CalcPercentNumber, CalcPercentLength, + CalcAngle, + CalcTime, + CalcFrequency, #if ENABLE(CSS_VARIABLES) CalcVariable, #endif diff --git a/Source/WebCore/css/CSSParser.cpp b/Source/WebCore/css/CSSParser.cpp index 54fd5e238..99ee8043a 100644 --- a/Source/WebCore/css/CSSParser.cpp +++ b/Source/WebCore/css/CSSParser.cpp @@ -1609,6 +1609,13 @@ bool CSSParser::validCalculationUnit(CSSParserValue* value, Units unitflags, Rel bool b = false; switch (m_parsedCalculation->category()) { + case CalcNumber: + b = (unitflags & FNumber); + if (!b && (unitflags & FInteger) && m_parsedCalculation->isInt()) + b = true; + if (b && mustBeNonNegative && m_parsedCalculation->isNegative()) + b = false; + break; case CalcLength: b = (unitflags & FLength); break; @@ -1617,19 +1624,21 @@ bool CSSParser::validCalculationUnit(CSSParserValue* value, Units unitflags, Rel if (b && mustBeNonNegative && m_parsedCalculation->isNegative()) b = false; break; - case CalcNumber: - b = (unitflags & FNumber); - if (!b && (unitflags & FInteger) && m_parsedCalculation->isInt()) - b = true; - if (b && mustBeNonNegative && m_parsedCalculation->isNegative()) - b = false; - break; case CalcPercentLength: b = (unitflags & FPercent) && (unitflags & FLength); break; case CalcPercentNumber: b = (unitflags & FPercent) && (unitflags & FNumber); break; + case CalcAngle: + b = (unitflags & FAngle); + break; + case CalcTime: + b = (unitflags & FTime); + break; + case CalcFrequency: + b = (unitflags & FFrequency); + break; #if ENABLE(CSS_VARIABLES) case CalcVariable: b = true; diff --git a/Source/WebCore/css/CSSPrimitiveValue.cpp b/Source/WebCore/css/CSSPrimitiveValue.cpp index bd544aab5..32f0121b6 100644 --- a/Source/WebCore/css/CSSPrimitiveValue.cpp +++ b/Source/WebCore/css/CSSPrimitiveValue.cpp @@ -193,14 +193,20 @@ unsigned short CSSPrimitiveValue::primitiveType() const switch (m_value.calc->category()) { case CalcNumber: return CSSPrimitiveValue::CSS_NUMBER; - case CalcPercent: - return CSSPrimitiveValue::CSS_PERCENTAGE; case CalcLength: return CSSPrimitiveValue::CSS_PX; + case CalcPercent: + return CSSPrimitiveValue::CSS_PERCENTAGE; case CalcPercentNumber: return CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_NUMBER; case CalcPercentLength: return CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_LENGTH; + case CalcAngle: + return CSSPrimitiveValue::CSS_DEG; + case CalcTime: + return CSSPrimitiveValue::CSS_MS; + case CalcFrequency: + return CSSPrimitiveValue::CSS_HZ; #if ENABLE(CSS_VARIABLES) case CalcVariable: return CSSPrimitiveValue::CSS_UNKNOWN; // The type of a calculation containing a variable cannot be known until the value of the variable is determined. -- cgit v1.2.1