Changeset 127220 in webkit
- Timestamp:
- Aug 30, 2012 6:13:50 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 10 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r127217 r127220 1 2012-08-30 Luke Macpherson <macpherson@chromium.org> 2 3 Make it possible to use CSS Variables inside Calc expressions. 4 https://bugs.webkit.org/show_bug.cgi?id=95284 5 6 Reviewed by Tony Chang. 7 8 Allows calc expressions to contain unevaluated variables, which are then resolved in StyleResolver.cpp when building the RenderStyle tree. 9 10 Tests: 11 fast/css/variables/calc.html 12 13 * css/CSSCalculationValue.cpp: 14 (WebCore::unitCategory): 15 (WebCore): 16 (WebCore::CSSCalcValue::customSerializeResolvingVariables): 17 Generates a CSS expression with variables resolved into their corresponding values. 18 (WebCore::CSSCalcValue::hasVariableReference): 19 Returns true if the calculation's expression tree refers to a variable (that needs to be resolved). 20 (CSSCalcPrimitiveValue): 21 (WebCore::CSSCalcPrimitiveValue::serializeResolvingVariables): 22 Resolves the variable using the underlying CSSPrimitiveValue's serializeResolvingVariables function. 23 (WebCore::CSSCalcPrimitiveValue::hasVariableReference): 24 (WebCore::CSSCalcPrimitiveValue::toCalcValue): 25 (WebCore::CSSCalcPrimitiveValue::doubleValue): 26 (WebCore::CSSCalcPrimitiveValue::computeLengthPx): 27 (WebCore::CSSCalcBinaryOperation::create): 28 (CSSCalcBinaryOperation): 29 (WebCore::CSSCalcBinaryOperation::serializeResolvingVariables): 30 Builds a CSS expression for contained subtrees. 31 (WebCore::CSSCalcBinaryOperation::hasVariableReference): 32 Returns true if either subtree contains a variable. 33 * css/CSSCalculationValue.h: 34 (CSSCalcExpressionNode): 35 (CSSCalcValue): 36 * css/CSSGrammar.y: 37 * css/CSSParser.cpp: 38 (WebCore::CSSParser::validCalculationUnit): 39 * css/CSSPrimitiveValue.cpp: 40 (WebCore::CSSPrimitiveValue::primitiveType): 41 (WebCore::CSSPrimitiveValue::customSerializeResolvingVariables): 42 * css/StyleResolver.cpp: 43 (WebCore::StyleResolver::collectMatchingRulesForList): 44 1 45 2012-08-30 Max Vujovic <mvujovic@adobe.com> 2 46 -
trunk/Source/WebCore/css/CSSCalculationValue.cpp
r124884 r127220 69 69 case CSSPrimitiveValue::CSS_REMS: 70 70 return CalcLength; 71 #if ENABLE(CSS_VARIABLES) 72 case CSSPrimitiveValue::CSS_VARIABLE_NAME: 73 return CalcVariable; 74 #endif 71 75 default: 72 76 return CalcOther; 73 77 } 74 78 } 75 76 String CSSCalcValue::customCssText() const 79 80 static String buildCssText(const String& expression) 77 81 { 78 82 StringBuilder result; 79 80 83 result.append("-webkit-calc"); 81 String expression = m_expression->customCssText();82 84 bool expressionHasSingleTerm = expression[0] != '('; 83 85 if (expressionHasSingleTerm) … … 89 91 } 90 92 93 String CSSCalcValue::customCssText() const 94 { 95 return buildCssText(m_expression->customCssText()); 96 } 97 98 #if ENABLE(CSS_VARIABLES) 99 String CSSCalcValue::customSerializeResolvingVariables(const HashMap<AtomicString, String>& variables) const 100 { 101 return buildCssText(m_expression->serializeResolvingVariables(variables)); 102 } 103 104 bool CSSCalcValue::hasVariableReference() const 105 { 106 return m_expression->hasVariableReference(); 107 } 108 #endif 109 91 110 void CSSCalcValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const 92 111 { … … 130 149 return m_value->cssText(); 131 150 } 151 152 #if ENABLE(CSS_VARIABLES) 153 virtual String serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const 154 { 155 return m_value->customSerializeResolvingVariables(variables); 156 } 157 158 virtual bool hasVariableReference() const 159 { 160 return m_value->isVariableName(); 161 } 162 #endif 132 163 133 164 virtual PassOwnPtr<CalcExpressionNode> toCalcValue(RenderStyle* style, RenderStyle* rootStyle, double zoom) const … … 144 175 // to a CalcExpressionNode. CalcPercentNumber makes no sense as a Length. 145 176 case CalcPercentNumber: 177 #if ENABLE(CSS_VARIABLES) 178 case CalcVariable: 179 #endif 146 180 case CalcOther: 147 181 ASSERT_NOT_REACHED(); … … 159 193 case CalcPercentLength: 160 194 case CalcPercentNumber: 195 #if ENABLE(CSS_VARIABLES) 196 case CalcVariable: 197 #endif 161 198 case CalcOther: 162 199 ASSERT_NOT_REACHED(); … … 176 213 case CalcPercentLength: 177 214 case CalcPercentNumber: 215 #if ENABLE(CSS_VARIABLES) 216 case CalcVariable: 217 #endif 178 218 case CalcOther: 179 219 ASSERT_NOT_REACHED(); … … 192 232 explicit CSSCalcPrimitiveValue(CSSPrimitiveValue* value, bool isInteger) 193 233 : CSSCalcExpressionNode(unitCategory((CSSPrimitiveValue::UnitTypes)value->primitiveType()), isInteger) 194 , m_value(value) 234 , m_value(value) 195 235 { 196 236 } … … 206 246 { CalcOther, CalcPercentLength, CalcPercentLength, CalcOther, CalcPercentLength }, 207 247 }; 208 248 249 static CalculationCategory determineCategory(const CSSCalcExpressionNode& leftSide, const CSSCalcExpressionNode& rightSide, CalcOperator op) 250 { 251 CalculationCategory leftCategory = leftSide.category(); 252 CalculationCategory rightCategory = rightSide.category(); 253 254 if (leftCategory == CalcOther || rightCategory == CalcOther) 255 return CalcOther; 256 257 #if ENABLE(CSS_VARIABLES) 258 if (leftCategory == CalcVariable || rightCategory == CalcVariable) 259 return CalcVariable; 260 #endif 261 262 switch (op) { 263 case CalcAdd: 264 case CalcSubtract: 265 return addSubtractResult[leftCategory][rightCategory]; 266 case CalcMultiply: 267 if (leftCategory != CalcNumber && rightCategory != CalcNumber) 268 return CalcOther; 269 return leftCategory == CalcNumber ? rightCategory : leftCategory; 270 case CalcDivide: 271 if (rightCategory != CalcNumber || rightSide.isZero()) 272 return CalcOther; 273 return leftCategory; 274 } 275 276 ASSERT_NOT_REACHED(); 277 return CalcOther; 278 } 279 209 280 class CSSCalcBinaryOperation : public CSSCalcExpressionNode { 281 210 282 public: 211 283 static PassRefPtr<CSSCalcBinaryOperation> create(PassRefPtr<CSSCalcExpressionNode> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide, CalcOperator op) 212 284 { 213 CalculationCategory leftCategory = leftSide->category(); 214 CalculationCategory rightCategory = rightSide->category(); 215 CalculationCategory newCategory = CalcOther; 285 ASSERT(leftSide->category() != CalcOther && rightSide->category() != CalcOther); 216 286 217 ASSERT(leftCategory != CalcOther && rightCategory != CalcOther); 218 219 switch (op) { 220 case CalcAdd: 221 case CalcSubtract: 222 if (leftCategory == CalcOther || rightCategory == CalcOther) 223 return 0; 224 newCategory = addSubtractResult[leftCategory][rightCategory]; 225 break; 226 227 case CalcMultiply: 228 if (leftCategory != CalcNumber && rightCategory != CalcNumber) 229 return 0; 230 231 newCategory = leftCategory == CalcNumber ? rightCategory : leftCategory; 232 break; 233 234 case CalcDivide: 235 if (rightCategory != CalcNumber || rightSide->isZero()) 236 return 0; 237 newCategory = leftCategory; 238 break; 239 } 240 287 CalculationCategory newCategory = determineCategory(*leftSide, *rightSide, op); 288 241 289 if (newCategory == CalcOther) 242 290 return 0; 243 291 244 292 return adoptRef(new CSSCalcBinaryOperation(leftSide, rightSide, op, newCategory)); 245 293 } … … 280 328 } 281 329 282 virtual String customCssText() const330 static String buildCssText(const String& leftExpression, const String& rightExpression, CalcOperator op) 283 331 { 284 332 StringBuilder result; 285 333 result.append('('); 286 result.append( m_leftSide->customCssText());334 result.append(leftExpression); 287 335 result.append(' '); 288 result.append(static_cast<char>( m_operator));336 result.append(static_cast<char>(op)); 289 337 result.append(' '); 290 result.append( m_rightSide->customCssText());338 result.append(rightExpression); 291 339 result.append(')'); 292 340 293 return result.toString(); 294 } 341 return result.toString(); 342 } 343 344 virtual String customCssText() const 345 { 346 return buildCssText(m_leftSide->customCssText(), m_rightSide->customCssText(), m_operator); 347 } 348 349 #if ENABLE(CSS_VARIABLES) 350 virtual String serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const 351 { 352 return buildCssText(m_leftSide->serializeResolvingVariables(variables), m_rightSide->serializeResolvingVariables(variables), m_operator); 353 } 354 355 virtual bool hasVariableReference() const 356 { 357 return m_leftSide->hasVariableReference() || m_rightSide->hasVariableReference(); 358 } 359 #endif 295 360 296 361 private: -
trunk/Source/WebCore/css/CSSCalculationValue.h
r124768 r127220 53 53 CalcPercentNumber, 54 54 CalcPercentLength, 55 #if ENABLE(CSS_VARIABLES) 56 CalcVariable, 57 #endif 55 58 CalcOther 56 59 }; … … 65 68 virtual double computeLengthPx(RenderStyle* currentStyle, RenderStyle* rootStyle, double multiplier = 1.0, bool computingFontSize = false) const = 0; 66 69 virtual String customCssText() const = 0; 70 #if ENABLE(CSS_VARIABLES) 71 virtual String serializeResolvingVariables(const HashMap<AtomicString, String>&) const = 0; 72 virtual bool hasVariableReference() const = 0; 73 #endif 67 74 68 75 virtual void reportMemoryUsage(MemoryObjectInfo*) const = 0; … … 98 105 99 106 String customCssText() const; 107 #if ENABLE(CSS_VARIABLES) 108 String customSerializeResolvingVariables(const HashMap<AtomicString, String>&) const; 109 bool hasVariableReference() const; 110 #endif 100 111 101 112 void reportDescendantMemoryUsage(MemoryObjectInfo*) const; -
trunk/Source/WebCore/css/CSSGrammar.y
r125252 r127220 101 101 %} 102 102 103 %expect 6 2103 %expect 63 104 104 105 105 %nonassoc LOWEST_PREC … … 1551 1551 calc_func_term: 1552 1552 unary_term { $$ = $1; } 1553 | VARFUNCTION maybe_space IDENT ')' maybe_space { 1554 #if ENABLE(CSS_VARIABLES) 1555 $$.id = 0; 1556 $$.string = $3; 1557 $$.unit = CSSPrimitiveValue::CSS_VARIABLE_NAME; 1558 #endif 1559 } 1553 1560 | unary_operator unary_term { $$ = $2; $$.fValue *= $1; } 1554 1561 ; -
trunk/Source/WebCore/css/CSSParser.cpp
r127155 r127220 1444 1444 b = (unitflags & FPercent) && (unitflags & FNumber); 1445 1445 break; 1446 #if ENABLE(CSS_VARIABLES) 1447 case CalcVariable: 1448 b = true; 1449 break; 1450 #endif 1446 1451 case CalcOther: 1447 1452 break; -
trunk/Source/WebCore/css/CSSPrimitiveValue.cpp
r127155 r127220 187 187 case CalcPercentLength: 188 188 return CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_LENGTH; 189 #if ENABLE(CSS_VARIABLES) 190 case CalcVariable: 191 return CSSPrimitiveValue::CSS_UNKNOWN; // The type of a calculation containing a variable cannot be known until the value of the variable is determined. 192 #endif 189 193 case CalcOther: 190 194 return CSSPrimitiveValue::CSS_UNKNOWN; … … 1120 1124 String CSSPrimitiveValue::customSerializeResolvingVariables(const HashMap<AtomicString, String>& variables) const 1121 1125 { 1122 if ( m_primitiveUnitType == CSS_VARIABLE_NAME&& variables.contains(m_value.string))1126 if (isVariableName() && variables.contains(m_value.string)) 1123 1127 return variables.get(m_value.string); 1128 if (isCalculated()) 1129 return cssCalcValue()->customSerializeResolvingVariables(variables); 1124 1130 return customCssText(); 1125 1131 } -
trunk/Source/WebCore/css/StyleResolver.cpp
r127162 r127220 3362 3362 static bool hasVariableReference(CSSValue* value) 3363 3363 { 3364 if (value->isPrimitiveValue() && static_cast<CSSPrimitiveValue*>(value)->isVariableName()) 3365 return true; 3364 if (value->isPrimitiveValue()) { 3365 CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); 3366 if (CSSCalcValue* calcValue = primitiveValue->cssCalcValue()) 3367 return calcValue->hasVariableReference(); 3368 return primitiveValue->isVariableName(); 3369 } 3370 3371 if (value->isCalculationValue()) 3372 return static_cast<CSSCalcValue*>(value)->hasVariableReference(); 3366 3373 3367 3374 for (CSSValueListIterator i = value; i.hasMore(); i.advance()) {
Note: See TracChangeset
for help on using the changeset viewer.