bool CSSPropertyParser::validCalculationUnit(CSSParserValue* value, Units unitflags, ReleaseParsedCalcValueCondition releaseCalc)
{
- bool mustBeNonNegative = unitflags & FNonNeg;
+ bool mustBeNonNegative = unitflags & (FNonNeg | FPositiveInteger);
if (!parseCalculation(value, mustBeNonNegative ? ValueRangeNonNegative : ValueRangeAll))
return false;
case CalcLength:
b = (unitflags & FLength);
break;
- case CalcPercent:
- b = (unitflags & FPercent);
- if (b && mustBeNonNegative && m_parsedCalculation->isNegative())
- b = false;
- break;
case CalcNumber:
b = (unitflags & FNumber);
- if (!b && (unitflags & FInteger) && m_parsedCalculation->isInt())
+ if (!b && (unitflags & (FInteger | FPositiveInteger)) && m_parsedCalculation->isInt())
b = true;
if (b && mustBeNonNegative && m_parsedCalculation->isNegative())
b = false;
+ // Always resolve calc() to a CSS_NUMBER in the CSSParserValue if there are no non-numbers specified in the unitflags.
+ if (b && !(unitflags & ~(FInteger | FNumber | FPositiveInteger | FNonNeg))) {
+ double number = m_parsedCalculation->doubleValue();
+ if ((unitflags & FPositiveInteger) && number <= 0) {
+ b = false;
+ } else {
+ delete value->function;
+ value->unit = CSSPrimitiveValue::CSS_NUMBER;
+ value->fValue = number;
+ value->isInt = m_parsedCalculation->isInt();
+ }
+ m_parsedCalculation.release();
+ return b;
+ }
+ break;
+ case CalcPercent:
+ b = (unitflags & FPercent);
+ if (b && mustBeNonNegative && m_parsedCalculation->isNegative())
+ b = false;
break;
case CalcPercentLength:
b = (unitflags & FPercent) && (unitflags & FLength);
Vector<int> coords;
value = m_valueList->next();
- while (value && value->unit == CSSPrimitiveValue::CSS_NUMBER) {
+ while (value && validUnit(value, FNumber)) {
coords.append(int(value->fValue));
value = m_valueList->next();
}
validPrimitive = validUnit(value, FLength | FNonNeg);
break;
case CSSPropertyWebkitColumnSpan: // none | all | 1 (will be dropped in the unprefixed property)
- if (id == CSSValueAll || id == CSSValueNone)
- validPrimitive = true;
- else
- validPrimitive = validUnit(value, FNumber | FNonNeg) && value->fValue == 1;
+ validPrimitive = id == CSSValueAll || id == CSSValueNone || (value->unit == CSSPrimitiveValue::CSS_NUMBER && value->fValue == 1);
break;
case CSSPropertyWebkitColumnWidth: // auto | <length>
parsedValue = parseColumnWidth();
CSSParserValue* value = m_valueList->current();
// Always parse lengths in strict mode here, since it would be ambiguous otherwise when used in
// the 'columns' shorthand property.
- if (value->id == CSSValueAuto
- || (validUnit(value, FLength | FNonNeg, HTMLStandardMode) && value->fValue)) {
+ if (value->id == CSSValueAuto || (validUnit(value, FLength | FNonNeg, HTMLStandardMode) && (m_parsedCalculation || value->fValue != 0))) {
RefPtrWillBeRawPtr<CSSValue> parsedValue = parseValidPrimitive(value->id, value);
m_valueList->next();
return parsedValue;
addProperty(CSSPropertyFontWeight, cssValuePool().createIdentifierValue(value->id), important);
return true;
}
- if (validUnit(value, FInteger | FNonNeg, HTMLQuirksMode)) {
+ if (value->unit == CSSPrimitiveValue::CSS_NUMBER) {
int weight = static_cast<int>(value->fValue);
if (!(weight % 100) && weight >= 100 && weight <= 900) {
addProperty(CSSPropertyFontWeight, cssValuePool().createIdentifierValue(static_cast<CSSValueID>(CSSValue100 + weight / 100 - 1)), important);
template bool CSSPropertyParser::fastParseColor(RGBA32&, const String&, bool strict);
-inline double CSSPropertyParser::parsedDouble(CSSParserValue *v, ReleaseParsedCalcValueCondition releaseCalc)
-{
- const double result = m_parsedCalculation ? m_parsedCalculation->doubleValue() : v->fValue;
- if (releaseCalc == ReleaseParsedCalcValue)
- m_parsedCalculation.release();
- return result;
-}
-
bool CSSPropertyParser::isCalculation(CSSParserValue* value)
{
return (value->unit == CSSParserValue::Function)
inline int CSSPropertyParser::colorIntFromValue(CSSParserValue* v)
{
bool isPercent;
+ double value;
- if (m_parsedCalculation)
+ if (m_parsedCalculation) {
isPercent = m_parsedCalculation->category() == CalcPercent;
- else
+ value = m_parsedCalculation->doubleValue();
+ m_parsedCalculation.release();
+ } else {
isPercent = v->unit == CSSPrimitiveValue::CSS_PERCENTAGE;
-
- const double value = parsedDouble(v, ReleaseParsedCalcValue);
+ value = v->fValue;
+ }
if (value <= 0.0)
return 0;
v = args->next();
if (!validUnit(v, FNumber, HTMLStandardMode))
return false;
- const double value = parsedDouble(v, ReleaseParsedCalcValue);
// Convert the floating pointer number of alpha to an integer in the range [0, 256),
// with an equal distribution across all 256 values.
- colorArray[3] = static_cast<int>(std::max(0.0, std::min(1.0, value)) * nextafter(256.0, 0.0));
+ colorArray[3] = static_cast<int>(std::max(0.0, std::min(1.0, v->fValue)) * nextafter(256.0, 0.0));
}
return true;
}
if (!validUnit(v, FNumber, HTMLStandardMode))
return false;
// normalize the Hue value and change it to be between 0 and 1.0
- colorArray[0] = (((static_cast<int>(parsedDouble(v, ReleaseParsedCalcValue)) % 360) + 360) % 360) / 360.0;
+ colorArray[0] = (((static_cast<int>(v->fValue) % 360) + 360) % 360) / 360.0;
for (int i = 1; i < 3; i++) {
v = args->next();
if (v->unit != CSSParserValue::Operator && v->iValue != ',')
v = args->next();
if (!validUnit(v, FPercent, HTMLStandardMode))
return false;
- colorArray[i] = std::max(0.0, std::min(100.0, parsedDouble(v, ReleaseParsedCalcValue))) / 100.0; // needs to be value between 0 and 1.0
+ double percentValue = m_parsedCalculation ? m_parsedCalculation.release()->doubleValue() : v->fValue;
+ colorArray[i] = std::max(0.0, std::min(100.0, percentValue)) / 100.0; // needs to be value between 0 and 1.0
}
if (parseAlpha) {
v = args->next();
v = args->next();
if (!validUnit(v, FNumber, HTMLStandardMode))
return false;
- colorArray[3] = std::max(0.0, std::min(1.0, parsedDouble(v, ReleaseParsedCalcValue)));
+ colorArray[3] = std::max(0.0, std::min(1.0, v->fValue));
}
return true;
}
if (args->size()) {
CSSParserValue* value = args->current();
- if (!validUnit(value, FNumber | FPercent | FNonNeg, HTMLStandardMode))
+ // FIXME (crbug.com/397061): Support calc expressions like calc(10% + 0.5)
+ if (value->unit != CSSPrimitiveValue::CSS_PERCENTAGE && !validUnit(value, FNumber | FNonNeg, HTMLStandardMode))
return nullptr;
double amount = value->fValue;
+ if (amount < 0)
+ return nullptr;
// Saturate and Contrast allow values over 100%.
if (filterType != CSSFilterValue::SaturateFilterOperation
if (args->size()) {
CSSParserValue* value = args->current();
- if (!validUnit(value, FNumber | FPercent, HTMLStandardMode))
+ // FIXME (crbug.com/397061): Support calc expressions like calc(10% + 0.5)
+ if (value->unit != CSSPrimitiveValue::CSS_PERCENTAGE && !validUnit(value, FNumber, HTMLStandardMode))
return nullptr;
filterValue->append(cssValuePool().createValue(value->fValue, static_cast<CSSPrimitiveValue::UnitType>(value->unit)));