diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index 4be2372347..036d4bf054 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -1178,6 +1178,14 @@ protected: CSSParseResult ParseColor(nsCSSValue& aValue); +static bool +IsCSSTokenCalcFunction(const nsCSSToken& aToken) +{ + return aToken.mType == eCSSToken_Function && + (aToken.mIdent.LowerCaseEqualsLiteral("calc") || + aToken.mIdent.LowerCaseEqualsLiteral("-moz-calc")); +} + template bool ParseRGBColor(ComponentType& aR, ComponentType& aG, @@ -6779,7 +6787,7 @@ CSSParserImpl::ParseColor(nsCSSValue& aValue) if (GetToken(true)) { UngetToken(); } - if (mToken.mType == eCSSToken_Number) { // + if (mToken.mType == eCSSToken_Number || mToken.mType == eCSSToken_Function) { // uint8_t r, g, b, a; if (ParseRGBColor(r, g, b, a)) { @@ -6878,6 +6886,21 @@ CSSParserImpl::ParseColor(nsCSSValue& aValue) return CSSParseResult::NotFound; } +struct ReduceNumberCalcOps : public mozilla::css::BasicFloatCalcOps, + public mozilla::css::CSSValueInputCalcOps +{ + result_type ComputeLeafValue(const nsCSSValue& aValue) + { + MOZ_ASSERT(aValue.GetUnit() == eCSSUnit_Number, "unexpected unit"); + return aValue.GetFloatValue(); + } + + float ComputeNumber(const nsCSSValue& aValue) + { + return mozilla::css::ComputeCalc(aValue, *this); + } +}; + bool CSSParserImpl::ParseColorComponent(uint8_t& aComponent, Maybe aSeparator) { @@ -6886,14 +6909,24 @@ CSSParserImpl::ParseColorComponent(uint8_t& aComponent, Maybe aSeparator) return false; } - if (mToken.mType != eCSSToken_Number) { + float value; + + if (mToken.mType == eCSSToken_Number) + value = mToken.mNumber; + else if (IsCSSTokenCalcFunction(mToken)) { + nsCSSValue aValue; + if (!ParseCalc(aValue, VARIANT_LPN | VARIANT_CALC)) { + return false; + } + ReduceNumberCalcOps ops; + value = mozilla::css::ComputeCalc(aValue, ops); + } + else { REPORT_UNEXPECTED_TOKEN(PEExpectedNumber); UngetToken(); return false; } - float value = mToken.mNumber; - if (aSeparator && !ExpectSymbol(*aSeparator, true)) { REPORT_UNEXPECTED_TOKEN_CHAR(PEColorComponentBadTerm, *aSeparator); return false; @@ -6914,14 +6947,24 @@ CSSParserImpl::ParseColorComponent(float& aComponent, Maybe aSeparator) return false; } - if (mToken.mType != eCSSToken_Percentage) { + float value; + + if (mToken.mType == eCSSToken_Percentage) + value = mToken.mNumber; + else if (IsCSSTokenCalcFunction(mToken)) { + nsCSSValue aValue; + if (!ParseCalc(aValue, VARIANT_LPN | VARIANT_CALC)) { + return false; + } + ReduceNumberCalcOps ops; + value = mozilla::css::ComputeCalc(aValue, ops); + } + else { REPORT_UNEXPECTED_TOKEN(PEExpectedPercent); UngetToken(); return false; } - float value = mToken.mNumber; - if (aSeparator && !ExpectSymbol(*aSeparator, true)) { REPORT_UNEXPECTED_TOKEN_CHAR(PEColorComponentBadTerm, *aSeparator); return false; @@ -6947,6 +6990,17 @@ CSSParserImpl::ParseHue(float& aAngle) aAngle = mToken.mNumber; return true; } + + if (IsCSSTokenCalcFunction(mToken)) { + nsCSSValue aValue; + if (!ParseCalc(aValue, VARIANT_LPN | VARIANT_CALC)) { + return false; + } + ReduceNumberCalcOps ops; + aAngle = mozilla::css::ComputeCalc(aValue, ops); + return true; + } + UngetToken(); // @@ -7852,14 +7906,6 @@ CSSParserImpl::ParseOneOrLargerVariant(nsCSSValue& aValue, return result; } -static bool -IsCSSTokenCalcFunction(const nsCSSToken& aToken) -{ - return aToken.mType == eCSSToken_Function && - (aToken.mIdent.LowerCaseEqualsLiteral("calc") || - aToken.mIdent.LowerCaseEqualsLiteral("-moz-calc")); -} - // Assigns to aValue iff it returns CSSParseResult::Ok. CSSParseResult CSSParserImpl::ParseVariant(nsCSSValue& aValue, @@ -13817,21 +13863,6 @@ CSSParserImpl::ParseCalcAdditiveExpression(nsCSSValue& aValue, } } -struct ReduceNumberCalcOps : public mozilla::css::BasicFloatCalcOps, - public mozilla::css::CSSValueInputCalcOps -{ - result_type ComputeLeafValue(const nsCSSValue& aValue) - { - MOZ_ASSERT(aValue.GetUnit() == eCSSUnit_Number, "unexpected unit"); - return aValue.GetFloatValue(); - } - - float ComputeNumber(const nsCSSValue& aValue) - { - return mozilla::css::ComputeCalc(aValue, *this); - } -}; - // * If aVariantMask is VARIANT_NUMBER, this function parses the // production. // * If aVariantMask does not contain VARIANT_NUMBER, this function