| Index: Source/core/css/parser/CSSPropertyParser.cpp
|
| diff --git a/Source/core/css/parser/CSSPropertyParser.cpp b/Source/core/css/parser/CSSPropertyParser.cpp
|
| index 10b55b207e1a9d87621a2c67b128c0698129f6b1..b79e63ded206cfab11ec9e95c766a34b04816eea 100644
|
| --- a/Source/core/css/parser/CSSPropertyParser.cpp
|
| +++ b/Source/core/css/parser/CSSPropertyParser.cpp
|
| @@ -51,6 +51,7 @@
|
| #include "core/css/CSSTimingFunctionValue.h"
|
| #include "core/css/CSSUnicodeRangeValue.h"
|
| #include "core/css/CSSValuePool.h"
|
| +#include "core/css/CSSVariableValue.h"
|
| #include "core/css/Counter.h"
|
| #include "core/css/HashTools.h"
|
| #include "core/css/Pair.h"
|
| @@ -216,6 +217,9 @@ bool CSSPropertyParser::validCalculationUnit(CSSParserValue* value, Units unitfl
|
| case CalcFrequency:
|
| b = (unitflags & FFrequency);
|
| break;
|
| + case CalcVariable:
|
| + b = true;
|
| + break;
|
| case CalcOther:
|
| break;
|
| }
|
| @@ -238,6 +242,9 @@ bool CSSPropertyParser::validUnit(CSSParserValue* value, Units unitflags, CSSPar
|
| if (isCalculation(value))
|
| return validCalculationUnit(value, unitflags, releaseCalc);
|
|
|
| + if (RuntimeEnabledFeatures::cssVariablesEnabled() && isVariableReference(value))
|
| + return true;
|
| +
|
| if (unitflags & FNonNeg && value->fValue < 0)
|
| return false;
|
| switch (value->unit) {
|
| @@ -297,6 +304,8 @@ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSPropertyParser::createPrimitiveNume
|
| ASSERT(isCalculation(value));
|
| return CSSPrimitiveValue::create(m_parsedCalculation.release());
|
| }
|
| + if (isVariableReference(value))
|
| + return createPrimitiveVariableReferenceValue(value);
|
|
|
| ASSERT((value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
|
| || (value->unit >= CSSPrimitiveValue::CSS_TURN && value->unit <= CSSPrimitiveValue::CSS_CHS)
|
| @@ -305,6 +314,12 @@ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSPropertyParser::createPrimitiveNume
|
| return cssValuePool().createValue(value->fValue, static_cast<CSSPrimitiveValue::UnitType>(value->unit));
|
| }
|
|
|
| +inline PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSPropertyParser::createPrimitiveVariableReferenceValue(CSSParserValue* value)
|
| +{
|
| + ASSERT(value->unit == CSSParserValue::VariableValue);
|
| + return CSSPrimitiveValue::create(value->variableData);
|
| +}
|
| +
|
| inline PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSPropertyParser::createPrimitiveStringValue(CSSParserValue* value)
|
| {
|
| ASSERT(value->unit == CSSPrimitiveValue::CSS_STRING || value->unit == CSSPrimitiveValue::CSS_IDENT);
|
| @@ -395,6 +410,8 @@ inline PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSPropertyParser::parseValidPr
|
| return CSSPrimitiveValue::createAllowingMarginQuirk(value->fValue, CSSPrimitiveValue::CSS_EMS);
|
| if (isCalculation(value))
|
| return CSSPrimitiveValue::create(m_parsedCalculation.release());
|
| + if (isVariableReference(value))
|
| + return createPrimitiveVariableReferenceValue(value);
|
|
|
| return nullptr;
|
| }
|
| @@ -444,8 +461,16 @@ bool CSSPropertyParser::parseValue(CSSPropertyID unresolvedProperty, bool import
|
| return true;
|
| }
|
|
|
| +
|
| int num = inShorthand() ? 1 : m_valueList->size();
|
|
|
| + if (RuntimeEnabledFeatures::cssVariablesEnabled() && isVariableReference(value)) {
|
| + // We don't expand the shorthand here because crazypants.
|
| + m_parsedProperties.append(CSSProperty(propId, createPrimitiveVariableReferenceValue(value), important, false, 0, m_implicitShorthand));
|
| + m_valueList->next();
|
| + return true;
|
| + }
|
| +
|
| if (CSSParserFastPaths::isKeywordPropertyID(propId)) {
|
| if (!CSSParserFastPaths::isValidKeywordPropertyAndValue(propId, id))
|
| return false;
|
| @@ -1494,7 +1519,6 @@ bool CSSPropertyParser::parseValue(CSSPropertyID unresolvedProperty, bool import
|
| case CSSPropertyUserZoom:
|
| validPrimitive = false;
|
| break;
|
| -
|
| case CSSPropertyScrollSnapPointsX:
|
| case CSSPropertyScrollSnapPointsY:
|
| parsedValue = parseScrollSnapPoints();
|
| @@ -1504,8 +1528,6 @@ bool CSSPropertyParser::parseValue(CSSPropertyID unresolvedProperty, bool import
|
| break;
|
| case CSSPropertyScrollSnapDestination:
|
| parsedValue = parsePosition(m_valueList);
|
| - break;
|
| -
|
| default:
|
| return parseSVGValue(propId, important);
|
| }
|
| @@ -5158,6 +5180,11 @@ bool CSSPropertyParser::isCalculation(CSSParserValue* value)
|
| || value->function->id == CSSValueWebkitCalc);
|
| }
|
|
|
| +bool CSSPropertyParser::isVariableReference(CSSParserValue* value)
|
| +{
|
| + return value->unit == CSSParserValue::VariableValue;
|
| +}
|
| +
|
| inline int CSSPropertyParser::colorIntFromValue(CSSParserValue* v)
|
| {
|
| bool isPercent;
|
| @@ -5526,15 +5553,19 @@ PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseReflect()
|
| // Direction comes first.
|
| CSSParserValue* val = m_valueList->current();
|
| RefPtrWillBeRawPtr<CSSPrimitiveValue> direction = nullptr;
|
| - switch (val->id) {
|
| - case CSSValueAbove:
|
| - case CSSValueBelow:
|
| - case CSSValueLeft:
|
| - case CSSValueRight:
|
| - direction = cssValuePool().createIdentifierValue(val->id);
|
| - break;
|
| - default:
|
| - return nullptr;
|
| + if (isVariableReference(val)) {
|
| + direction = createPrimitiveVariableReferenceValue(val);
|
| + } else {
|
| + switch (val->id) {
|
| + case CSSValueAbove:
|
| + case CSSValueBelow:
|
| + case CSSValueLeft:
|
| + case CSSValueRight:
|
| + direction = cssValuePool().createIdentifierValue(val->id);
|
| + break;
|
| + default:
|
| + return nullptr;
|
| + }
|
| }
|
|
|
| // The offset comes next.
|
| @@ -7794,22 +7825,34 @@ bool CSSPropertyParser::parseViewportShorthand(CSSPropertyID propId, CSSProperty
|
| }
|
|
|
| template <typename CharacterType>
|
| +static bool isVariableDefinition(const CharacterType* propertyName, unsigned length)
|
| +{
|
| + return (length >= 2 && propertyName[0] == '-' && propertyName[1] == '-');
|
| +}
|
| +
|
| +template <typename CharacterType>
|
| static CSSPropertyID unresolvedCSSPropertyID(const CharacterType* propertyName, unsigned length)
|
| {
|
| char buffer[maxCSSPropertyNameLength + 1]; // 1 for null character
|
|
|
| for (unsigned i = 0; i != length; ++i) {
|
| CharacterType c = propertyName[i];
|
| - if (c == 0 || c >= 0x7F)
|
| + if (c == 0 || c >= 0x7F) {
|
| + if (isVariableDefinition(propertyName, length))
|
| + return CSSPropertyVariable;
|
| return CSSPropertyInvalid; // illegal character
|
| + }
|
| buffer[i] = toASCIILower(c);
|
| }
|
| buffer[length] = '\0';
|
|
|
| const char* name = buffer;
|
| const Property* hashTableEntry = findProperty(name, length);
|
| - if (!hashTableEntry)
|
| + if (!hashTableEntry) {
|
| + if (isVariableDefinition(propertyName, length))
|
| + return CSSPropertyVariable;
|
| return CSSPropertyInvalid;
|
| + }
|
| CSSPropertyID property = static_cast<CSSPropertyID>(hashTableEntry->id);
|
| if (!CSSPropertyMetadata::isEnabledProperty(property))
|
| return CSSPropertyInvalid;
|
| @@ -7822,8 +7865,11 @@ CSSPropertyID unresolvedCSSPropertyID(const String& string)
|
|
|
| if (!length)
|
| return CSSPropertyInvalid;
|
| - if (length > maxCSSPropertyNameLength)
|
| + if (length > maxCSSPropertyNameLength) {
|
| + if (string.is8Bit() ? isVariableDefinition(string.characters8(), length) : isVariableDefinition(string.characters8(), length))
|
| + return CSSPropertyVariable;
|
| return CSSPropertyInvalid;
|
| + }
|
|
|
| return string.is8Bit() ? unresolvedCSSPropertyID(string.characters8(), length) : unresolvedCSSPropertyID(string.characters16(), length);
|
| }
|
|
|