| Differences between
and this patch
- a/Source/WebCore/ChangeLog +38 lines
Lines 1-3 a/Source/WebCore/ChangeLog_sec1
1
2013-03-26  Alan Cutter  <alancutter@chromium.org>
2
3
        Simplify parsed CSS Calc expressions
4
        https://bugs.webkit.org/show_bug.cgi?id=111149
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        Added basic simplification of numbers and units in CSS calc expressions at parse time.
9
10
        Test: css3/calc/simplification.html
11
12
        * css/CSSCalculationValue.cpp:
13
        (WebCore::hasDoubleValue):
14
        (WebCore):
15
        (CSSCalcPrimitiveValue):
16
        (WebCore::CSSCalcPrimitiveValue::create):
17
        (WebCore::CSSCalcPrimitiveValue::doubleValue):
18
        (WebCore::CSSCalcPrimitiveValue::primitiveType):
19
        (WebCore::isIntegerResult):
20
        (WebCore::CSSCalcBinaryOperation::create):
21
        (CSSCalcBinaryOperation):
22
        (WebCore::CSSCalcBinaryOperation::createSimplified):
23
        (WebCore::CSSCalcBinaryOperation::primitiveType):
24
        (WebCore::CSSCalcBinaryOperation::CSSCalcBinaryOperation):
25
        (WebCore::CSSCalcBinaryOperation::getNumberSide):
26
        (WebCore::CSSCalcBinaryOperation::evaluate):
27
        (WebCore::CSSCalcBinaryOperation::evaluateOperator):
28
        (WebCore::CSSCalcExpressionNodeParser::parseValueTerm):
29
        (WebCore::CSSCalcExpressionNodeParser::parseValueMultiplicativeExpression):
30
        (WebCore::CSSCalcExpressionNodeParser::parseAdditiveValueExpression):
31
        * css/CSSCalculationValue.h:
32
        (CSSCalcExpressionNode):
33
        * css/CSSPrimitiveValue.cpp:
34
        (WebCore::CSSPrimitiveValue::unitCategory):
35
        (WebCore::CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor):
36
        * css/CSSPrimitiveValue.h:
37
        (CSSPrimitiveValue):
38
1
2013-03-26  Tim Horton  <timothy_horton@apple.com>
39
2013-03-26  Tim Horton  <timothy_horton@apple.com>
2
40
3
        [ca] Tell CA to clean up unused resources if a given WebProcess won't be drawing
41
        [ca] Tell CA to clean up unused resources if a given WebProcess won't be drawing
- a/Source/WebCore/css/CSSCalculationValue.cpp -32 / +210 lines
Lines 78-83 static CalculationCategory unitCategory(CSSPrimitiveValue::UnitTypes type) a/Source/WebCore/css/CSSCalculationValue.cpp_sec1
78
    }
78
    }
79
}
79
}
80
80
81
static bool hasDoubleValue(CSSPrimitiveValue::UnitTypes type)
82
{
83
    switch (type) {
84
    case CSSPrimitiveValue::CSS_NUMBER:
85
    case CSSPrimitiveValue::CSS_PARSER_INTEGER:
86
    case CSSPrimitiveValue::CSS_PERCENTAGE:
87
    case CSSPrimitiveValue::CSS_EMS:
88
    case CSSPrimitiveValue::CSS_EXS:
89
    case CSSPrimitiveValue::CSS_CHS:
90
    case CSSPrimitiveValue::CSS_REMS:
91
    case CSSPrimitiveValue::CSS_PX:
92
    case CSSPrimitiveValue::CSS_CM:
93
    case CSSPrimitiveValue::CSS_MM:
94
    case CSSPrimitiveValue::CSS_IN:
95
    case CSSPrimitiveValue::CSS_PT:
96
    case CSSPrimitiveValue::CSS_PC:
97
    case CSSPrimitiveValue::CSS_DEG:
98
    case CSSPrimitiveValue::CSS_RAD:
99
    case CSSPrimitiveValue::CSS_GRAD:
100
    case CSSPrimitiveValue::CSS_MS:
101
    case CSSPrimitiveValue::CSS_S:
102
    case CSSPrimitiveValue::CSS_HZ:
103
    case CSSPrimitiveValue::CSS_KHZ:
104
    case CSSPrimitiveValue::CSS_DIMENSION:
105
    case CSSPrimitiveValue::CSS_VW:
106
    case CSSPrimitiveValue::CSS_VH:
107
    case CSSPrimitiveValue::CSS_VMIN:
108
    case CSSPrimitiveValue::CSS_VMAX:
109
    case CSSPrimitiveValue::CSS_DPPX:
110
    case CSSPrimitiveValue::CSS_DPI:
111
    case CSSPrimitiveValue::CSS_DPCM:
112
        return true;
113
    case CSSPrimitiveValue::CSS_UNKNOWN:
114
    case CSSPrimitiveValue::CSS_STRING:
115
    case CSSPrimitiveValue::CSS_URI:
116
    case CSSPrimitiveValue::CSS_IDENT:
117
    case CSSPrimitiveValue::CSS_ATTR:
118
    case CSSPrimitiveValue::CSS_COUNTER:
119
    case CSSPrimitiveValue::CSS_RECT:
120
    case CSSPrimitiveValue::CSS_RGBCOLOR:
121
    case CSSPrimitiveValue::CSS_PAIR:
122
#if ENABLE(DASHBOARD_SUPPORT)
123
    case CSSPrimitiveValue::CSS_DASHBOARD_REGION:
124
#endif
125
    case CSSPrimitiveValue::CSS_UNICODE_RANGE:
126
    case CSSPrimitiveValue::CSS_PARSER_OPERATOR:
127
    case CSSPrimitiveValue::CSS_PARSER_HEXCOLOR:
128
    case CSSPrimitiveValue::CSS_PARSER_IDENTIFIER:
129
    case CSSPrimitiveValue::CSS_TURN:
130
    case CSSPrimitiveValue::CSS_COUNTER_NAME:
131
    case CSSPrimitiveValue::CSS_SHAPE:
132
    case CSSPrimitiveValue::CSS_QUAD:
133
    case CSSPrimitiveValue::CSS_CALC:
134
    case CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_NUMBER:
135
    case CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_LENGTH:
136
#if ENABLE(CSS_VARIABLES)
137
    case CSSPrimitiveValue::CSS_VARIABLE_NAME:
138
#endif
139
        return false;
140
    };
141
    ASSERT_NOT_REACHED();
142
    return false;
143
}
144
81
static String buildCssText(const String& expression)
145
static String buildCssText(const String& expression)
82
{
146
{
83
    StringBuilder result;
147
    StringBuilder result;
Lines 145-151 public: a/Source/WebCore/css/CSSCalculationValue.cpp_sec2
145
    {
209
    {
146
        return adoptRef(new CSSCalcPrimitiveValue(value, isInteger));
210
        return adoptRef(new CSSCalcPrimitiveValue(value, isInteger));
147
    }
211
    }
148
    
212
213
    static PassRefPtr<CSSCalcPrimitiveValue> create(double value, CSSPrimitiveValue::UnitTypes type, bool isInteger)
214
    {
215
        if (std::isnan(value) || std::isinf(value))
216
            return 0;
217
        return adoptRef(new CSSCalcPrimitiveValue(CSSPrimitiveValue::create(value, type).get(), isInteger));
218
    }
219
149
    virtual bool isZero() const
220
    virtual bool isZero() const
150
    {
221
    {
151
        return !m_value->getDoubleValue();
222
        return !m_value->getDoubleValue();
Lines 192-211 public: a/Source/WebCore/css/CSSCalculationValue.cpp_sec3
192
263
193
    virtual double doubleValue() const
264
    virtual double doubleValue() const
194
    {
265
    {
195
        switch (m_category) {
266
        if (hasDoubleValue(primitiveType()))
196
        case CalcNumber:
197
        case CalcPercent:                
198
            return m_value->getDoubleValue();
267
            return m_value->getDoubleValue();
199
        case CalcLength:
268
200
        case CalcPercentLength:
269
        ASSERT_NOT_REACHED();
201
        case CalcPercentNumber:
202
#if ENABLE(CSS_VARIABLES)
203
        case CalcVariable:
204
#endif
205
        case CalcOther:
206
            ASSERT_NOT_REACHED();
207
            break;
208
        }
209
        return 0;
270
        return 0;
210
    }
271
    }
211
    
272
    
Lines 245-250 public: a/Source/WebCore/css/CSSCalculationValue.cpp_sec4
245
306
246
    virtual Type type() const { return CssCalcPrimitiveValue; }
307
    virtual Type type() const { return CssCalcPrimitiveValue; }
247
    
308
    
309
    virtual CSSPrimitiveValue::UnitTypes primitiveType() const
310
    {
311
        return CSSPrimitiveValue::UnitTypes(m_value->primitiveType());
312
    }
313
248
private:
314
private:
249
    explicit CSSCalcPrimitiveValue(CSSPrimitiveValue* value, bool isInteger)
315
    explicit CSSCalcPrimitiveValue(CSSPrimitiveValue* value, bool isInteger)
250
        : CSSCalcExpressionNode(unitCategory((CSSPrimitiveValue::UnitTypes)value->primitiveType()), isInteger)
316
        : CSSCalcExpressionNode(unitCategory((CSSPrimitiveValue::UnitTypes)value->primitiveType()), isInteger)
Lines 256-267 private: a/Source/WebCore/css/CSSCalculationValue.cpp_sec5
256
};
322
};
257
323
258
static const CalculationCategory addSubtractResult[CalcOther][CalcOther] = {
324
static const CalculationCategory addSubtractResult[CalcOther][CalcOther] = {
259
    { CalcNumber,        CalcOther,         CalcPercentNumber, CalcPercentNumber, CalcOther },
325
//                        CalcNumber         CalcLength         CalcPercent        CalcPercentNumber  CalcPercentLength
260
    { CalcOther,         CalcLength,        CalcPercentLength, CalcOther,         CalcPercentLength },
326
/* CalcNumber */        { CalcNumber,        CalcOther,         CalcPercentNumber, CalcPercentNumber, CalcOther },
261
    { CalcPercentNumber, CalcPercentLength, CalcPercent,       CalcPercentNumber, CalcPercentLength },
327
/* CalcLength */        { CalcOther,         CalcLength,        CalcPercentLength, CalcOther,         CalcPercentLength },
262
    { CalcPercentNumber, CalcOther,         CalcPercentNumber, CalcPercentNumber, CalcOther },
328
/* CalcPercent */       { CalcPercentNumber, CalcPercentLength, CalcPercent,       CalcPercentNumber, CalcPercentLength },
263
    { CalcOther,         CalcPercentLength, CalcPercentLength, CalcOther,         CalcPercentLength },
329
/* CalcPercentNumber */ { CalcPercentNumber, CalcOther,         CalcPercentNumber, CalcPercentNumber, CalcOther },
264
};    
330
/* CalcPercentLength */ { CalcOther,         CalcPercentLength, CalcPercentLength, CalcOther,         CalcPercentLength },
331
};
265
332
266
static CalculationCategory determineCategory(const CSSCalcExpressionNode& leftSide, const CSSCalcExpressionNode& rightSide, CalcOperator op)
333
static CalculationCategory determineCategory(const CSSCalcExpressionNode& leftSide, const CSSCalcExpressionNode& rightSide, CalcOperator op)
267
{
334
{
Lines 294-314 static CalculationCategory determineCategory(const CSSCalcExpressionNode& leftSi a/Source/WebCore/css/CSSCalculationValue.cpp_sec6
294
    return CalcOther;
361
    return CalcOther;
295
}
362
}
296
363
364
static bool isIntegerResult(const CSSCalcExpressionNode* leftSide, const CSSCalcExpressionNode* rightSide, CalcOperator op)
365
{
366
    // Not testing for actual integer values.
367
    // Performs W3C spec's type checking for calc integers.
368
    // http://www.w3.org/TR/css3-values/#calc-type-checking
369
    return op != CalcDivide && leftSide->isInteger() && rightSide->isInteger();
370
}
371
297
class CSSCalcBinaryOperation : public CSSCalcExpressionNode {
372
class CSSCalcBinaryOperation : public CSSCalcExpressionNode {
298
373
299
public:
374
public:
300
    static PassRefPtr<CSSCalcBinaryOperation> create(PassRefPtr<CSSCalcExpressionNode> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide, CalcOperator op)
375
    static PassRefPtr<CSSCalcExpressionNode> create(PassRefPtr<CSSCalcExpressionNode> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide, CalcOperator op)
301
    {
376
    {
302
        ASSERT(leftSide->category() != CalcOther && rightSide->category() != CalcOther);
377
        ASSERT(leftSide->category() != CalcOther && rightSide->category() != CalcOther);
303
        
304
        CalculationCategory newCategory = determineCategory(*leftSide, *rightSide, op);
305
378
379
        CalculationCategory newCategory = determineCategory(*leftSide, *rightSide, op);
306
        if (newCategory == CalcOther)
380
        if (newCategory == CalcOther)
307
            return 0;
381
            return 0;
308
382
309
        return adoptRef(new CSSCalcBinaryOperation(leftSide, rightSide, op, newCategory));
383
        return adoptRef(new CSSCalcBinaryOperation(leftSide, rightSide, op, newCategory));
310
    }
384
    }
311
    
385
386
    static PassRefPtr<CSSCalcExpressionNode> createSimplified(PassRefPtr<CSSCalcExpressionNode> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide, CalcOperator op)
387
    {
388
        CalculationCategory leftCategory = leftSide->category();
389
        CalculationCategory rightCategory = rightSide->category();
390
        ASSERT(leftCategory != CalcOther && rightCategory != CalcOther);
391
392
        bool isInteger = isIntegerResult(leftSide.get(), rightSide.get(), op);
393
394
        // Simplify numbers.
395
        if (leftCategory == CalcNumber && rightCategory == CalcNumber) {
396
            CSSPrimitiveValue::UnitTypes evaluationType = isInteger ? CSSPrimitiveValue::CSS_PARSER_INTEGER : CSSPrimitiveValue::CSS_NUMBER;
397
            return CSSCalcPrimitiveValue::create(evaluateOperator(leftSide->doubleValue(), rightSide->doubleValue(), op), evaluationType, isInteger);
398
        }
399
400
        // Simplify addition and subtraction between same types.
401
        if (op == CalcAdd || op == CalcSubtract) {
402
            if (leftCategory == rightSide->category()) {
403
                CSSPrimitiveValue::UnitTypes leftType = leftSide->primitiveType();
404
                if (hasDoubleValue(leftType)) {
405
                    CSSPrimitiveValue::UnitTypes rightType = rightSide->primitiveType();
406
                    if (leftType == rightType)
407
                        return CSSCalcPrimitiveValue::create(evaluateOperator(leftSide->doubleValue(), rightSide->doubleValue(), op), leftType, isInteger);
408
                    CSSPrimitiveValue::UnitCategory leftUnitCategory = CSSPrimitiveValue::unitCategory(leftType);
409
                    if (leftUnitCategory != CSSPrimitiveValue::UOther && leftUnitCategory == CSSPrimitiveValue::unitCategory(rightType)) {
410
                        CSSPrimitiveValue::UnitTypes canonicalType = CSSPrimitiveValue::canonicalUnitTypeForCategory(leftUnitCategory);
411
                        if (canonicalType != CSSPrimitiveValue::CSS_UNKNOWN) {
412
                            double leftValue = leftSide->doubleValue() * CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(leftType);
413
                            double rightValue = rightSide->doubleValue() * CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(rightType);
414
                            return CSSCalcPrimitiveValue::create(evaluateOperator(leftValue, rightValue, op), canonicalType, isInteger);
415
                        }
416
                    }
417
                }
418
            }
419
        } else {
420
            // Simplify multiplying or dividing by a number for simplifiable types.
421
            ASSERT(op == CalcMultiply || op == CalcDivide);
422
            CSSCalcExpressionNode* numberSide = getNumberSide(leftSide.get(), rightSide.get());
423
            if (!numberSide)
424
                return create(leftSide, rightSide, op);
425
            if (numberSide == leftSide && op == CalcDivide)
426
                return 0;
427
            CSSCalcExpressionNode* otherSide = leftSide == numberSide ? rightSide.get() : leftSide.get();
428
429
            double number = numberSide->doubleValue();
430
            if (std::isnan(number) || std::isinf(number))
431
                return 0;
432
            if (op == CalcDivide && !number)
433
                return 0;
434
435
            CSSPrimitiveValue::UnitTypes otherType = otherSide->primitiveType();
436
            if (hasDoubleValue(otherType))
437
                return CSSCalcPrimitiveValue::create(evaluateOperator(otherSide->doubleValue(), number, op), otherType, isInteger);
438
        }
439
440
        return create(leftSide, rightSide, op);
441
    }
442
312
    virtual bool isZero() const
443
    virtual bool isZero() const
313
    {
444
    {
314
        return !doubleValue();
445
        return !doubleValue();
Lines 388-405 public: a/Source/WebCore/css/CSSCalculationValue.cpp_sec7
388
519
389
    virtual Type type() const { return CssCalcBinaryOperation; }
520
    virtual Type type() const { return CssCalcBinaryOperation; }
390
521
522
    virtual CSSPrimitiveValue::UnitTypes primitiveType() const
523
    {
524
        switch (m_category) {
525
        case CalcNumber:
526
            ASSERT(m_leftSide->category() == CalcNumber && m_rightSide->category() == CalcNumber);
527
            if (m_isInteger)
528
                return CSSPrimitiveValue::CSS_PARSER_INTEGER;
529
            return CSSPrimitiveValue::CSS_NUMBER;
530
        case CalcLength:
531
        case CalcPercent: {
532
            if (m_leftSide->category() == CalcNumber)
533
                return m_rightSide->primitiveType();
534
            if (m_rightSide->category() == CalcNumber)
535
                return m_leftSide->primitiveType();
536
            CSSPrimitiveValue::UnitTypes leftType = m_leftSide->primitiveType();
537
            if (leftType == m_rightSide->primitiveType())
538
                return leftType;
539
            return CSSPrimitiveValue::CSS_UNKNOWN;
540
        }
541
#if ENABLE(CSS_VARIABLES)
542
        case CalcVariable:
543
            return CSSPrimitiveValue::CSS_VARIABLE_NAME;
544
#endif
545
        case CalcPercentLength:
546
        case CalcPercentNumber:
547
        case CalcOther:
548
            return CSSPrimitiveValue::CSS_UNKNOWN;
549
        }
550
        ASSERT_NOT_REACHED();
551
        return CSSPrimitiveValue::CSS_UNKNOWN;
552
    }
553
554
391
private:
555
private:
392
    CSSCalcBinaryOperation(PassRefPtr<CSSCalcExpressionNode> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide, CalcOperator op, CalculationCategory category)
556
    CSSCalcBinaryOperation(PassRefPtr<CSSCalcExpressionNode> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide, CalcOperator op, CalculationCategory category)
393
        : CSSCalcExpressionNode(category, leftSide->isInteger() && rightSide->isInteger())
557
        : CSSCalcExpressionNode(category, isIntegerResult(leftSide.get(), rightSide.get(), op))
394
        , m_leftSide(leftSide)
558
        , m_leftSide(leftSide)
395
        , m_rightSide(rightSide)
559
        , m_rightSide(rightSide)
396
        , m_operator(op)
560
        , m_operator(op)
397
    {
561
    {
398
    }
562
    }
399
    
563
400
    double evaluate(double leftValue, double rightValue) const
564
    static CSSCalcExpressionNode* getNumberSide(CSSCalcExpressionNode* leftSide, CSSCalcExpressionNode* rightSide)
565
    {
566
        if (leftSide->category() == CalcNumber)
567
            return leftSide;
568
        if (rightSide->category() == CalcNumber)
569
            return rightSide;
570
        return 0;
571
    }
572
573
    double evaluate(double leftSide, double rightSide) const
401
    {
574
    {
402
        switch (m_operator) {
575
        return evaluateOperator(leftSide, rightSide, m_operator);
576
    }
577
578
    static double evaluateOperator(double leftValue, double rightValue, CalcOperator op)
579
    {
580
        switch (op) {
403
        case CalcAdd:
581
        case CalcAdd:
404
            return leftValue + rightValue;
582
            return leftValue + rightValue;
405
        case CalcSubtract:
583
        case CalcSubtract:
Lines 413-419 private: a/Source/WebCore/css/CSSCalculationValue.cpp_sec8
413
        }
591
        }
414
        return 0;
592
        return 0;
415
    }
593
    }
416
    
594
417
    const RefPtr<CSSCalcExpressionNode> m_leftSide;
595
    const RefPtr<CSSCalcExpressionNode> m_leftSide;
418
    const RefPtr<CSSCalcExpressionNode> m_rightSide;
596
    const RefPtr<CSSCalcExpressionNode> m_rightSide;
419
    const CalcOperator m_operator;
597
    const CalcOperator m_operator;
Lines 479-485 private: a/Source/WebCore/css/CSSCalculationValue.cpp_sec9
479
    {
657
    {
480
        if (checkDepthAndIndex(&depth, *index, tokens) != OK)
658
        if (checkDepthAndIndex(&depth, *index, tokens) != OK)
481
            return false;    
659
            return false;    
482
        
660
483
        if (operatorValue(tokens, *index) == '(') {
661
        if (operatorValue(tokens, *index) == '(') {
484
            unsigned currentIndex = *index + 1;
662
            unsigned currentIndex = *index + 1;
485
            if (!parseValueExpression(tokens, depth, &currentIndex, result))
663
            if (!parseValueExpression(tokens, depth, &currentIndex, result))
Lines 512-518 private: a/Source/WebCore/css/CSSCalculationValue.cpp_sec10
512
            if (!parseValueTerm(tokens, depth, index, &rhs))
690
            if (!parseValueTerm(tokens, depth, index, &rhs))
513
                return false;
691
                return false;
514
692
515
            result->value = CSSCalcBinaryOperation::create(result->value, rhs.value, static_cast<CalcOperator>(operatorCharacter));
693
            result->value = CSSCalcBinaryOperation::createSimplified(result->value, rhs.value, static_cast<CalcOperator>(operatorCharacter));
516
            if (!result->value)
694
            if (!result->value)
517
                return false;
695
                return false;
518
        }
696
        }
Lines 539-545 private: a/Source/WebCore/css/CSSCalculationValue.cpp_sec11
539
            if (!parseValueMultiplicativeExpression(tokens, depth, index, &rhs))
717
            if (!parseValueMultiplicativeExpression(tokens, depth, index, &rhs))
540
                return false;
718
                return false;
541
719
542
            result->value = CSSCalcBinaryOperation::create(result->value, rhs.value, static_cast<CalcOperator>(operatorCharacter));
720
            result->value = CSSCalcBinaryOperation::createSimplified(result->value, rhs.value, static_cast<CalcOperator>(operatorCharacter));
543
            if (!result->value)
721
            if (!result->value)
544
                return false;
722
                return false;
545
        }
723
        }
- a/Source/WebCore/css/CSSCalculationValue.h +2 lines
Lines 32-37 a/Source/WebCore/css/CSSCalculationValue.h_sec1
32
#define CSSCalculationValue_h
32
#define CSSCalculationValue_h
33
33
34
#include "CSSParserValues.h"
34
#include "CSSParserValues.h"
35
#include "CSSPrimitiveValue.h"
35
#include "CSSValue.h"
36
#include "CSSValue.h"
36
#include "CalculationValue.h"
37
#include "CalculationValue.h"
37
#include <wtf/PassOwnPtr.h>
38
#include <wtf/PassOwnPtr.h>
Lines 80-85 public: a/Source/WebCore/css/CSSCalculationValue.h_sec2
80
    virtual Type type() const = 0;
81
    virtual Type type() const = 0;
81
82
82
    CalculationCategory category() const { return m_category; }    
83
    CalculationCategory category() const { return m_category; }    
84
    virtual CSSPrimitiveValue::UnitTypes primitiveType() const = 0;
83
    bool isInteger() const { return m_isInteger; }
85
    bool isInteger() const { return m_isInteger; }
84
    
86
    
85
protected:
87
protected:
- a/Source/WebCore/css/CSSPrimitiveValue.cpp -2 / +2 lines
Lines 131-137 static inline bool isValidCSSUnitTypeForDoubleConversion(CSSPrimitiveValue::Unit a/Source/WebCore/css/CSSPrimitiveValue.cpp_sec1
131
    return false;
131
    return false;
132
}
132
}
133
133
134
static CSSPrimitiveValue::UnitCategory unitCategory(CSSPrimitiveValue::UnitTypes type)
134
CSSPrimitiveValue::UnitCategory CSSPrimitiveValue::unitCategory(CSSPrimitiveValue::UnitTypes type)
135
{
135
{
136
    // Here we violate the spec (http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSPrimitiveValue) and allow conversions
136
    // Here we violate the spec (http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSPrimitiveValue) and allow conversions
137
    // between CSS_PX and relative lengths (see cssPixelsPerInch comment in CSSHelper.h for the topic treatment).
137
    // between CSS_PX and relative lengths (see cssPixelsPerInch comment in CSSHelper.h for the topic treatment).
Lines 596-602 void CSSPrimitiveValue::setFloatValue(unsigned short, double, ExceptionCode& ec) a/Source/WebCore/css/CSSPrimitiveValue.cpp_sec2
596
    ec = NO_MODIFICATION_ALLOWED_ERR;
596
    ec = NO_MODIFICATION_ALLOWED_ERR;
597
}
597
}
598
598
599
static double conversionToCanonicalUnitsScaleFactor(unsigned short unitType)
599
double CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(unsigned short unitType)
600
{
600
{
601
    double factor = 1.0;
601
    double factor = 1.0;
602
    // FIXME: the switch can be replaced by an array of scale factors.
602
    // FIXME: the switch can be replaced by an array of scale factors.
- a/Source/WebCore/css/CSSPrimitiveValue.h -1 / +4 lines
Lines 150-155 public: a/Source/WebCore/css/CSSPrimitiveValue.h_sec1
150
#endif
150
#endif
151
        UOther
151
        UOther
152
    };
152
    };
153
    static UnitCategory unitCategory(CSSPrimitiveValue::UnitTypes);
153
154
154
    bool isAngle() const
155
    bool isAngle() const
155
    {
156
    {
Lines 324-329 public: a/Source/WebCore/css/CSSPrimitiveValue.h_sec2
324
325
325
    void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
326
    void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
326
327
328
    static UnitTypes canonicalUnitTypeForCategory(UnitCategory);
329
    static double conversionToCanonicalUnitsScaleFactor(unsigned short unitType);
330
327
private:
331
private:
328
    // FIXME: int vs. unsigned overloading is too subtle to distinguish the color and identifier cases.
332
    // FIXME: int vs. unsigned overloading is too subtle to distinguish the color and identifier cases.
329
    CSSPrimitiveValue(int ident);
333
    CSSPrimitiveValue(int ident);
Lines 349-355 private: a/Source/WebCore/css/CSSPrimitiveValue.h_sec3
349
    static void create(unsigned); // compile-time guard
353
    static void create(unsigned); // compile-time guard
350
    template<typename T> operator T*(); // compile-time guard
354
    template<typename T> operator T*(); // compile-time guard
351
355
352
    static UnitTypes canonicalUnitTypeForCategory(UnitCategory category);
353
356
354
    void init(PassRefPtr<Counter>);
357
    void init(PassRefPtr<Counter>);
355
    void init(PassRefPtr<Rect>);
358
    void init(PassRefPtr<Rect>);
- a/LayoutTests/ChangeLog +11 lines
Lines 1-3 a/LayoutTests/ChangeLog_sec1
1
2013-03-26  Alan Cutter  <alancutter@chromium.org>
2
3
        Simplify parsed CSS Calc expressions
4
        https://bugs.webkit.org/show_bug.cgi?id=111149
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        * css3/calc/cssom-expected.txt:
9
        * css3/calc/simplification-expected.txt: Added.
10
        * css3/calc/simplification.html: Added.
11
1
2013-03-26  Mark Lam  <mark.lam@apple.com>
12
2013-03-26  Mark Lam  <mark.lam@apple.com>
2
13
3
        Greening the mac bots.
14
        Greening the mac bots.
- a/LayoutTests/css3/calc/cssom-expected.txt -5 / +5 lines
Lines 1-15 a/LayoutTests/css3/calc/cssom-expected.txt_sec1
1
This tests calc() and the CSSOM
1
This tests calc() and the CSSOM
2
2
3
10px => calc(10px)
3
10px => calc(10px)
4
10px + 15px => calc(10px + 15px)
4
10px + 15px => calc(25px)
5
100% => calc(100%)
5
100% => calc(100%)
6
100% - 10px => calc(100% - 10px)
6
100% - 10px => calc(100% - 10px)
7
10px + 10px * 5 => calc(10px + (10px * 5))
7
10px + 10px * 5 => calc(60px)
8
5px + 2em + 6in => calc((5px + 2em) + 6in)
8
5px + 2em + 6in => calc((5px + 2em) + 6in)
9
100% - 10px / 2 => calc(100% - (10px / 2))
9
100% - 10px / 2 => calc(100% - 5px)
10
1px + 2em - 3rem + 4in => calc(((1px + 2em) - 3rem) + 4in)
10
1px + 2em - 3rem + 4in => calc(((1px + 2em) - 3rem) + 4in)
11
100px * (1 + 2 * 3 - 4 / 5) => calc(100px * ((1 + (2 * 3)) - (4 / 5)))
11
100px * (1 + 2 * 3 - 4 / 5) => calc(620px)
12
(100px) + 200px => calc(100px + 200px)
12
(100px) + 200px => calc(300px)
13
((((((((((100px)))))))))) => calc(100px)
13
((((((((((100px)))))))))) => calc(100px)
14
flimstix => calc(100px)
14
flimstix => calc(100px)
15
15
- a/LayoutTests/css3/calc/simplification-expected.txt +21 lines
Line 0 a/LayoutTests/css3/calc/simplification-expected.txt_sec1
1
This tests parse time simplification in calc()
2
3
100px * (25 + 5) => calc(3000px)
4
100em * (25 - 5) => calc(2000em)
5
100ex * (2 * 5 - 5) => calc(500ex)
6
100cm * (5 - 4 / 5) => calc(420cm)
7
100mm * (2.4 * 5 - 8 / 5) => calc(1040mm)
8
100in * (6 * (5 - 4) / 8) => calc(75in)
9
1px * (3 + 1/(7 + 1/(15 + 1/(1 + 1/(292 + 1/(1 + 1/(1 + 1/(1 + 1)))))))) => calc(3.1415926535583574px)
10
100pc * 20 + 100rem * 10 - 100ch * 5 + 100pc => calc(((2000pc + 1000rem) - 500ch) + 100pc)
11
((100px + 20 * 5px) * 10 - 5 * (10em * 5 + 10em)) * 2 => calc((2000px - 300em) * 2)
12
100px + 1in => calc(196px)
13
10 * 10px + 0.5 * 2in => calc(196px)
14
100px + 1in + 10% => calc(196px + 10%)
15
100px - 1in => calc(4px)
16
50cm + 50cm => calc(100cm)
17
50cm + 10in + 100mm => calc(3227.7165354330705px)
18
100px + 1em => calc(100px + 1em)
19
100px + 1em + 100px => calc((100px + 1em) + 100px)
20
1em + 1rem => calc(1em + 1rem)
21
- a/LayoutTests/css3/calc/simplification.html +36 lines
Line 0 a/LayoutTests/css3/calc/simplification.html_sec1
1
<!DOCTYPE HTML>
2
<div id="dummy"></div>
3
<div id="results">This tests parse time simplification in calc()<br><br></div>
4
<script>
5
if (window.testRunner)
6
    window.testRunner.dumpAsText();
7
8
var tests = [
9
    "100px * (25 + 5)",
10
    "100em * (25 - 5)",
11
    "100ex * (2 * 5 - 5)",
12
    "100cm * (5 - 4 / 5)",
13
    "100mm * (2.4 * 5 - 8 / 5)",
14
    "100in * (6 * (5 - 4) / 8)",
15
    "1px * (3 + 1/(7 + 1/(15 + 1/(1 + 1/(292 + 1/(1 + 1/(1 + 1/(1 + 1))))))))",
16
    "100pc * 20 + 100rem * 10 - 100ch * 5 + 100pc",
17
    "((100px + 20 * 5px) * 10 - 5 * (10em * 5 + 10em)) * 2",
18
    "100px + 1in",
19
    "10 * 10px + 0.5 * 2in",
20
    "100px + 1in + 10%",
21
    "100px - 1in",
22
    "50cm + 50cm",
23
    "50cm + 10in + 100mm",
24
    "100px + 1em",
25
    "100px + 1em + 100px",
26
    "1em + 1rem",
27
];
28
29
var results = document.getElementById("results");
30
var dummy = document.getElementById("dummy");
31
for (var i = 0; i < tests.length; ++i) {
32
    var expression = tests[i];
33
    dummy.style.width = 'calc(' + expression + ')';
34
    results.innerHTML += expression + " => " + dummy.style.width + "<br>";
35
}
36
</script>

Return to Bug 111149