Changeset 292150 in webkit


Ignore:
Timestamp:
Mar 31, 2022 3:21:18 AM (4 months ago)
Author:
commit-queue@webkit.org
Message:

Implement units for CSS Typed OM
https://bugs.webkit.org/show_bug.cgi?id=238532

Patch by Alex Christensen <achristensen@webkit.org> on 2022-03-31
Reviewed by Simon Fraser.

LayoutTests/imported/w3c:

  • web-platform-tests/css/css-typed-om/stylevalue-serialization/cssUnitValue.tentative-expected.txt:
  • web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/add-two-types.tentative-expected.txt:
  • web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/arithmetic.tentative-expected.txt:
  • web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/create-a-type.tentative-expected.txt:
  • web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/cssMathInvert-type-expected.txt:
  • web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/cssMathNegate-type-expected.txt:
  • web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/cssMathValue.tentative-expected.txt:
  • web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/cssUnitValue-expected.txt:
  • web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/cssnumericvalue-multiply-two-types.tentative-expected.txt:
  • web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/to.tentative-expected.txt:

Source/WebCore:

This feature is off by default and this part is covered by WPT tests.

  • css/typedom/CSSNumericFactory.h:
  • css/typedom/CSSNumericValue.cpp:

(WebCore::negate):
(WebCore::invert):
(WebCore::operationOnValuesOfSameUnit):
(WebCore::CSSNumericValue::addInternal):
(WebCore::CSSNumericValue::add):
(WebCore::CSSNumericValue::sub):
(WebCore::CSSNumericValue::multiplyInternal):
(WebCore::CSSNumericValue::mul):
(WebCore::CSSNumericValue::to):
(WebCore::CSSNumericValue::toSum):
(WebCore::CSSNumericValue::type): Deleted.

  • css/typedom/CSSNumericValue.h:

(WebCore::CSSNumericValue::type const):
(WebCore::CSSNumericValue::CSSNumericValue):

  • css/typedom/CSSUnitValue.cpp:

(WebCore::numericType):
(WebCore::parseUnit):
(WebCore::CSSUnitValue::unit const):
(WebCore::CSSUnitValue::unitSerialization const):
(WebCore::CSSUnitValue::create):
(WebCore::CSSUnitValue::CSSUnitValue):

  • css/typedom/CSSUnitValue.h:
  • css/typedom/numeric/CSSMathInvert.cpp:

(WebCore::negatedType):
(WebCore::CSSMathInvert::CSSMathInvert):

  • css/typedom/numeric/CSSMathNegate.cpp:

(WebCore::copyType):
(WebCore::CSSMathNegate::CSSMathNegate):

  • css/typedom/numeric/CSSMathProduct.cpp:

(WebCore::multiplyTypes):
(WebCore::CSSMathProduct::create):
(WebCore::CSSMathProduct::CSSMathProduct):
(WebCore::CSSMathProduct::values const): Deleted.

  • css/typedom/numeric/CSSMathProduct.h:
  • css/typedom/numeric/CSSMathSum.cpp:

(WebCore::addTypes):
(WebCore::CSSMathSum::create):
(WebCore::CSSMathSum::CSSMathSum):

  • css/typedom/numeric/CSSMathSum.h:
  • css/typedom/numeric/CSSMathValue.h:

(WebCore::CSSMathValue::CSSMathValue):

  • css/typedom/numeric/CSSNumericArray.cpp:

(WebCore::CSSNumericArray::create):

  • css/typedom/numeric/CSSNumericBaseType.h:

(WebCore::eachBaseType):
(WebCore::debugString):
(): Deleted.

  • css/typedom/numeric/CSSNumericType.h:

(WebCore::CSSNumericType::operator== const):
(WebCore::CSSNumericType::valueForType):
(WebCore::CSSNumericType::applyPercentHint):
(WebCore::CSSNumericType::debugString const):
(): Deleted.

  • css/typedom/numeric/CSSNumericType.idl:
Location:
trunk
Files:
31 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r292117 r292150  
     12022-03-31  Alex Christensen  <achristensen@webkit.org>
     2
     3        Implement units for CSS Typed OM
     4        https://bugs.webkit.org/show_bug.cgi?id=238532
     5
     6        Reviewed by Simon Fraser.
     7
     8        * web-platform-tests/css/css-typed-om/stylevalue-serialization/cssUnitValue.tentative-expected.txt:
     9        * web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/add-two-types.tentative-expected.txt:
     10        * web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/arithmetic.tentative-expected.txt:
     11        * web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/create-a-type.tentative-expected.txt:
     12        * web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/cssMathInvert-type-expected.txt:
     13        * web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/cssMathNegate-type-expected.txt:
     14        * web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/cssMathValue.tentative-expected.txt:
     15        * web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/cssUnitValue-expected.txt:
     16        * web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/cssnumericvalue-multiply-two-types.tentative-expected.txt:
     17        * web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/to.tentative-expected.txt:
     18
    1192022-03-30  Antti Koivisto  <antti@apple.com>
    220
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-typed-om/stylevalue-serialization/cssUnitValue.tentative-expected.txt

    r282758 r292150  
    11
    2 FAIL CSSUnitValue with length unit constructed from IDL serializes correctly assert_equals: expected "3.14px" but got "3px"
    3 FAIL CSSUnitValue with unit "percent" constructed from IDL serializes correctly assert_equals: expected "3.14%" but got "3percent"
    4 FAIL CSSUnitValue with unit "number" constructed from IDL serializes correctly assert_equals: expected "3.14" but got "3number"
    5 FAIL CSSUnitValue with integer values constructed from IDL serializes correctly assert_equals: expected "3" but got "3number"
    6 FAIL CSSKeywordValue from DOMString modified by "value" setter serializes correctly assert_equals: expected "3.14px" but got "3px"
    7 FAIL CSSKeywordValue from CSSOM modified by "value" setter serializes correctly assert_equals: expected "3.14px" but got "3px"
     2PASS CSSUnitValue with length unit constructed from IDL serializes correctly
     3PASS CSSUnitValue with unit "percent" constructed from IDL serializes correctly
     4PASS CSSUnitValue with unit "number" constructed from IDL serializes correctly
     5PASS CSSUnitValue with integer values constructed from IDL serializes correctly
     6PASS CSSKeywordValue from DOMString modified by "value" setter serializes correctly
     7PASS CSSKeywordValue from CSSOM modified by "value" setter serializes correctly
    88
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/add-two-types.tentative-expected.txt

    r282356 r292150  
    11
    2 FAIL Adding two types with different non-null percent hints throws TypeError assert_throws_js: function "() => new CSSMathSum(a, b)" did not throw
    3 FAIL Adding two types with the same nonzero values returns same type assert_equals: length expected 1 but got 0
    4 FAIL Adding two types with empty maps with returns empty map assert_equals: length expected (undefined) undefined but got (number) 0
    5 FAIL Adding a type with percent returns type with percent hint assert_equals: length expected 1 but got 0
    6 FAIL Adding a type with percent 2 returns type with percent hint throws TypeError assert_throws_js: function "() => new CSSMathSum(a, b)" did not throw
    7 FAIL Adding a type with a percent hint returns a type with the percent hint assert_equals: length expected 1 but got 0
    8 FAIL Adding two types with the same percent hint returns a type with the percent hint assert_equals: length expected 1 but got 0
     2PASS Adding two types with different non-null percent hints throws TypeError
     3PASS Adding two types with the same nonzero values returns same type
     4PASS Adding two types with empty maps with returns empty map
     5PASS Adding a type with percent returns type with percent hint
     6PASS Adding a type with percent 2 returns type with percent hint throws TypeError
     7PASS Adding a type with a percent hint returns a type with the percent hint
     8PASS Adding two types with the same percent hint returns a type with the percent hint
    99
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/arithmetic.tentative-expected.txt

    r291597 r292150  
    6161PASS Calling CSSNumericValue.div inverts all argument values
    6262PASS Can not divide with CSSUnitValue which has zero value and number type
    63 FAIL CSSNumericValue.add should throw TypeError when the types are different. assert_throws_js: function "() => CSS.number(3).add(CSS.px(10) ,CSS.number(0))" did not throw
    64 FAIL CSSNumericValue.sub should throw TypeError when the types are different. assert_throws_js: function "() => CSS.number(3).sub(CSS.px(10) ,CSS.number(0))" did not throw
     63PASS CSSNumericValue.add should throw TypeError when the types are different.
     64PASS CSSNumericValue.sub should throw TypeError when the types are different.
    6565
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/create-a-type.tentative-expected.txt

    r282356 r292150  
    11
    2 FAIL Creating a type from "number" returns {} assert_equals: length expected (undefined) undefined but got (number) 0
    3 FAIL Creating a type from "percent" returns { percent: 1 } assert_equals: length expected (undefined) undefined but got (number) 0
    4 FAIL Creating a type from <length> returns { length: 1 } assert_equals: length expected 1 but got 0
    5 FAIL Creating a type from <angle> returns { angle: 1 } assert_equals: length expected (undefined) undefined but got (number) 0
    6 FAIL Creating a type from <time> returns { time: 1 } assert_equals: length expected (undefined) undefined but got (number) 0
    7 FAIL Creating a type from <frequency> returns { frequency: 1 } assert_equals: length expected (undefined) undefined but got (number) 0
    8 FAIL Creating a type from <resolution> returns { resolution: 1 } assert_equals: length expected (undefined) undefined but got (number) 0
    9 FAIL Creating a type from <flex> returns { flex: 1 } assert_equals: length expected (undefined) undefined but got (number) 0
     2PASS Creating a type from "number" returns {}
     3PASS Creating a type from "percent" returns { percent: 1 }
     4PASS Creating a type from <length> returns { length: 1 }
     5PASS Creating a type from <angle> returns { angle: 1 }
     6PASS Creating a type from <time> returns { time: 1 }
     7PASS Creating a type from <frequency> returns { frequency: 1 }
     8PASS Creating a type from <resolution> returns { resolution: 1 }
     9PASS Creating a type from <flex> returns { flex: 1 }
    1010
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/cssMathInvert-type-expected.txt

    r282356 r292150  
    11
    2 FAIL Inverting a type with empty map returns the empty map assert_equals: length expected (undefined) undefined but got (number) 0
    3 FAIL Inverting a type negates all its exponents assert_equals: length expected -1 but got 0
    4 FAIL Inverting an inverted type returns the original type assert_equals: length expected 1 but got 0
     2PASS Inverting a type with empty map returns the empty map
     3PASS Inverting a type negates all its exponents
     4PASS Inverting an inverted type returns the original type
    55
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/cssMathNegate-type-expected.txt

    r282356 r292150  
    11
    2 FAIL Negating a type with empty map returns the empty map assert_equals: length expected (undefined) undefined but got (number) 0
    3 FAIL Negating a type returns the same type assert_equals: length expected 1 but got 0
     2PASS Negating a type with empty map returns the empty map
     3PASS Negating a type returns the same type
    44
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/cssMathValue.tentative-expected.txt

    r282356 r292150  
    11
    2 FAIL Constructing a CSSMathSum with no arguments throws a SyntaxError assert_throws_dom: function "() => new subclass()" did not throw
     2PASS Constructing a CSSMathSum with no arguments throws a SyntaxError
    33PASS CSSMathSum can be constructed from a single number CSSUnitValue
    44PASS CSSMathSum can be constructed from more than one number CSSUnitValue
    55PASS CSSMathSum.operator is readonly
    6 FAIL Constructing a CSSMathProduct with no arguments throws a SyntaxError assert_throws_dom: function "() => new subclass()" did not throw
     6PASS Constructing a CSSMathProduct with no arguments throws a SyntaxError
    77PASS CSSMathProduct can be constructed from a single number CSSUnitValue
    88PASS CSSMathProduct can be constructed from more than one number CSSUnitValue
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/cssUnitValue-expected.txt

    r281127 r292150  
    11
    2 FAIL Constructing CSSUnitValue with an unknown unit throws a TypeError assert_throws_js: function "() => new CSSUnitValue(0, 'lemon')" did not throw
    3 FAIL Constructing CSSUnitValue with a empty string unit throws a TypeError assert_throws_js: function "() => new CSSUnitValue(0, '')" did not throw
     2PASS Constructing CSSUnitValue with an unknown unit throws a TypeError
     3PASS Constructing CSSUnitValue with a empty string unit throws a TypeError
    44PASS CSSUnitValue can be constructed with number
    55PASS CSSUnitValue can be constructed with percent
     
    1919PASS CSSUnitValue can be constructed with cm
    2020PASS CSSUnitValue can be constructed with mm
    21 FAIL CSSUnitValue can be constructed with Q assert_equals: unit is same as given by constructor expected "q" but got "Q"
     21PASS CSSUnitValue can be constructed with Q
    2222PASS CSSUnitValue can be constructed with in
    2323PASS CSSUnitValue can be constructed with pt
     
    3030PASS CSSUnitValue can be constructed with s
    3131PASS CSSUnitValue can be constructed with ms
    32 FAIL CSSUnitValue can be constructed with Hz assert_equals: unit is same as given by constructor expected "hz" but got "Hz"
    33 FAIL CSSUnitValue can be constructed with kHz assert_equals: unit is same as given by constructor expected "khz" but got "kHz"
     32PASS CSSUnitValue can be constructed with Hz
     33PASS CSSUnitValue can be constructed with kHz
    3434PASS CSSUnitValue can be constructed with dpi
    3535PASS CSSUnitValue can be constructed with dpcm
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/cssnumericvalue-multiply-two-types.tentative-expected.txt

    r282356 r292150  
    11
    2 FAIL Multiplying two types with different non-null percent hints throws TypeError assert_throws_js: function "() => new CSSMathProduct(a, b)" did not throw
    3 FAIL Multiplying two types with same base types adds exponents assert_equals: length expected 2 but got 0
    4 FAIL Multiplying two types with different base types adds exponents assert_equals: length expected 1 but got 0
    5 FAIL Multiplying two types respects the sign of the exponents assert_equals: length expected 1 but got 0
    6 FAIL Multiplying a type with no exponents is a no-op assert_equals: length expected 1 but got 0
    7 FAIL Multiplying a type with percent hint applies the percent hint assert_equals: length expected 2 but got 0
    8 FAIL Multiplying two types with same percent hint applies the percent hint assert_equals: length expected 2 but got 0
     2PASS Multiplying two types with different non-null percent hints throws TypeError
     3PASS Multiplying two types with same base types adds exponents
     4PASS Multiplying two types with different base types adds exponents
     5PASS Multiplying two types respects the sign of the exponents
     6PASS Multiplying a type with no exponents is a no-op
     7PASS Multiplying a type with percent hint applies the percent hint
     8PASS Multiplying two types with same percent hint applies the percent hint
    99
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-typed-om/stylevalue-subclasses/numeric-objects/to.tentative-expected.txt

    r282356 r292150  
    1414FAIL Converting a CSSMathNegate to a single unit negates its value assert_approx_equals: expected -1 +/- 0.000001 but got 1
    1515FAIL Converting a CSSMathInvert to a single unit inverts its value and units assert_approx_equals: expected 2 +/- 0.000001 but got 1
    16 FAIL Converting a complex expression to a single unit assert_approx_equals: expected 3500 +/- 0.000001 but got 1
     16FAIL Converting a complex expression to a single unit Type error
    1717
  • trunk/Source/WebCore/ChangeLog

    r292148 r292150  
     12022-03-31  Alex Christensen  <achristensen@webkit.org>
     2
     3        Implement units for CSS Typed OM
     4        https://bugs.webkit.org/show_bug.cgi?id=238532
     5
     6        Reviewed by Simon Fraser.
     7
     8        This feature is off by default and this part is covered by WPT tests.
     9
     10        * css/typedom/CSSNumericFactory.h:
     11        * css/typedom/CSSNumericValue.cpp:
     12        (WebCore::negate):
     13        (WebCore::invert):
     14        (WebCore::operationOnValuesOfSameUnit):
     15        (WebCore::CSSNumericValue::addInternal):
     16        (WebCore::CSSNumericValue::add):
     17        (WebCore::CSSNumericValue::sub):
     18        (WebCore::CSSNumericValue::multiplyInternal):
     19        (WebCore::CSSNumericValue::mul):
     20        (WebCore::CSSNumericValue::to):
     21        (WebCore::CSSNumericValue::toSum):
     22        (WebCore::CSSNumericValue::type): Deleted.
     23        * css/typedom/CSSNumericValue.h:
     24        (WebCore::CSSNumericValue::type const):
     25        (WebCore::CSSNumericValue::CSSNumericValue):
     26        * css/typedom/CSSUnitValue.cpp:
     27        (WebCore::numericType):
     28        (WebCore::parseUnit):
     29        (WebCore::CSSUnitValue::unit const):
     30        (WebCore::CSSUnitValue::unitSerialization const):
     31        (WebCore::CSSUnitValue::create):
     32        (WebCore::CSSUnitValue::CSSUnitValue):
     33        * css/typedom/CSSUnitValue.h:
     34        * css/typedom/numeric/CSSMathInvert.cpp:
     35        (WebCore::negatedType):
     36        (WebCore::CSSMathInvert::CSSMathInvert):
     37        * css/typedom/numeric/CSSMathNegate.cpp:
     38        (WebCore::copyType):
     39        (WebCore::CSSMathNegate::CSSMathNegate):
     40        * css/typedom/numeric/CSSMathProduct.cpp:
     41        (WebCore::multiplyTypes):
     42        (WebCore::CSSMathProduct::create):
     43        (WebCore::CSSMathProduct::CSSMathProduct):
     44        (WebCore::CSSMathProduct::values const): Deleted.
     45        * css/typedom/numeric/CSSMathProduct.h:
     46        * css/typedom/numeric/CSSMathSum.cpp:
     47        (WebCore::addTypes):
     48        (WebCore::CSSMathSum::create):
     49        (WebCore::CSSMathSum::CSSMathSum):
     50        * css/typedom/numeric/CSSMathSum.h:
     51        * css/typedom/numeric/CSSMathValue.h:
     52        (WebCore::CSSMathValue::CSSMathValue):
     53        * css/typedom/numeric/CSSNumericArray.cpp:
     54        (WebCore::CSSNumericArray::create):
     55        * css/typedom/numeric/CSSNumericBaseType.h:
     56        (WebCore::eachBaseType):
     57        (WebCore::debugString):
     58        (): Deleted.
     59        * css/typedom/numeric/CSSNumericType.h:
     60        (WebCore::CSSNumericType::operator== const):
     61        (WebCore::CSSNumericType::valueForType):
     62        (WebCore::CSSNumericType::applyPercentHint):
     63        (WebCore::CSSNumericType::debugString const):
     64        (): Deleted.
     65        * css/typedom/numeric/CSSNumericType.idl:
     66
    1672022-03-31  Zan Dobersek  <zdobersek@igalia.com>
    268
  • trunk/Source/WebCore/css/parser/CSSParserToken.cpp

    r291474 r292150  
    4545{
    4646    ASSERT(data);
    47     ASSERT(length);
    4847    switch (length) {
    4948    case 1:
     
    329328}
    330329
    331 static CSSUnitType stringToUnitType(StringView stringView)
     330CSSUnitType CSSParserToken::stringToUnitType(StringView stringView)
    332331{
    333332    if (stringView.is8Bit())
  • trunk/Source/WebCore/css/parser/CSSParserToken.h

    r279498 r292150  
    106106    CSSParserToken(HashTokenType, StringView);
    107107
     108    static CSSUnitType stringToUnitType(StringView);
     109
    108110    bool operator==(const CSSParserToken& other) const;
    109111    bool operator!=(const CSSParserToken& other) const { return !(*this == other); }
  • trunk/Source/WebCore/css/typedom/CSSNumericFactory.h

    r291863 r292150  
    4444    explicit CSSNumericFactory(DOMCSSNamespace&) { }
    4545
    46     static Ref<CSSUnitValue> number(double value) { return CSSUnitValue::create(value, "number"_s); }
    47     static Ref<CSSUnitValue> percent(double value) { return CSSUnitValue::create(value, "percent"_s); }
     46    static Ref<CSSUnitValue> number(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_NUMBER); }
     47    static Ref<CSSUnitValue> percent(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_PERCENTAGE); }
    4848
    4949
    5050    // <length>
    51     static Ref<CSSUnitValue> em(double value) { return CSSUnitValue::create(value, "em"_s); }
    52     static Ref<CSSUnitValue> ex(double value) { return CSSUnitValue::create(value, "ex"_s); }
    53     static Ref<CSSUnitValue> ch(double value) { return CSSUnitValue::create(value, "ch"_s); }
    54     static Ref<CSSUnitValue> ic(double value) { return CSSUnitValue::create(value, "ic"_s); }
    55     static Ref<CSSUnitValue> rem(double value) { return CSSUnitValue::create(value, "rem"_s); }
    56     static Ref<CSSUnitValue> lh(double value) { return CSSUnitValue::create(value, "lh"_s); }
    57     static Ref<CSSUnitValue> rlh(double value) { return CSSUnitValue::create(value, "rlh"_s); }
    58     static Ref<CSSUnitValue> vw(double value) { return CSSUnitValue::create(value, "vw"_s); }
    59     static Ref<CSSUnitValue> vh(double value) { return CSSUnitValue::create(value, "vh"_s); }
    60     static Ref<CSSUnitValue> vi(double value) { return CSSUnitValue::create(value, "vi"_s); }
    61     static Ref<CSSUnitValue> vb(double value) { return CSSUnitValue::create(value, "vb"_s); }
    62     static Ref<CSSUnitValue> vmin(double value) { return CSSUnitValue::create(value, "vmin"_s); }
    63     static Ref<CSSUnitValue> vmax(double value) { return CSSUnitValue::create(value, "vmax"_s); }
    64     static Ref<CSSUnitValue> cm(double value) { return CSSUnitValue::create(value, "cm"_s); }
    65     static Ref<CSSUnitValue> mm(double value) { return CSSUnitValue::create(value, "mm"_s); }
    66     static Ref<CSSUnitValue> q(double value) { return CSSUnitValue::create(value, "q"_s); }
    67     static Ref<CSSUnitValue> in(double value) { return CSSUnitValue::create(value, "in"_s); }
    68     static Ref<CSSUnitValue> pt(double value) { return CSSUnitValue::create(value, "pt"_s); }
    69     static Ref<CSSUnitValue> pc(double value) { return CSSUnitValue::create(value, "pc"_s); }
    70     static Ref<CSSUnitValue> px(double value) { return CSSUnitValue::create(value, "px"_s); }
    71     static Ref<CSSUnitValue> cqw(double value) { return CSSUnitValue::create(value, "cqw"_s); }
    72     static Ref<CSSUnitValue> cqh(double value) { return CSSUnitValue::create(value, "cqh"_s); }
    73     static Ref<CSSUnitValue> cqi(double value) { return CSSUnitValue::create(value, "cqi"_s); }
    74     static Ref<CSSUnitValue> cqb(double value) { return CSSUnitValue::create(value, "cqb"_s); }
    75     static Ref<CSSUnitValue> cqmin(double value) { return CSSUnitValue::create(value, "cqmin"_s); }
    76     static Ref<CSSUnitValue> cqmax(double value) { return CSSUnitValue::create(value, "cqmax"_s); }
     51    static Ref<CSSUnitValue> em(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_EMS); }
     52    static Ref<CSSUnitValue> ex(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_EXS); }
     53    static Ref<CSSUnitValue> ch(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_CHS); }
     54    static Ref<CSSUnitValue> ic(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_IC); }
     55    static Ref<CSSUnitValue> rem(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_REMS); }
     56    static Ref<CSSUnitValue> lh(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_LHS); }
     57    static Ref<CSSUnitValue> rlh(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_RLHS); }
     58    static Ref<CSSUnitValue> vw(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_VW); }
     59    static Ref<CSSUnitValue> vh(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_VH); }
     60    static Ref<CSSUnitValue> vi(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_VI); }
     61    static Ref<CSSUnitValue> vb(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_VB); }
     62    static Ref<CSSUnitValue> vmin(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_VMIN); }
     63    static Ref<CSSUnitValue> vmax(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_VMAX); }
     64    static Ref<CSSUnitValue> cm(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_CM); }
     65    static Ref<CSSUnitValue> mm(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_MM); }
     66    static Ref<CSSUnitValue> q(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_Q); }
     67    static Ref<CSSUnitValue> in(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_IN); }
     68    static Ref<CSSUnitValue> pt(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_PT); }
     69    static Ref<CSSUnitValue> pc(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_PC); }
     70    static Ref<CSSUnitValue> px(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_PX); }
     71    static Ref<CSSUnitValue> cqw(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_CQW); }
     72    static Ref<CSSUnitValue> cqh(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_CQH); }
     73    static Ref<CSSUnitValue> cqi(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_CQI); }
     74    static Ref<CSSUnitValue> cqb(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_CQB); }
     75    static Ref<CSSUnitValue> cqmin(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_CQMIN); }
     76    static Ref<CSSUnitValue> cqmax(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_CQMAX); }
    7777
    7878
    7979    // <angle>
    80     static Ref<CSSUnitValue> deg(double value) { return CSSUnitValue::create(value, "deg"_s); }
    81     static Ref<CSSUnitValue> grad(double value) { return CSSUnitValue::create(value, "grad"_s); }
    82     static Ref<CSSUnitValue> rad(double value) { return CSSUnitValue::create(value, "rad"_s); }
    83     static Ref<CSSUnitValue> turn(double value) { return CSSUnitValue::create(value, "turn"_s); }
     80    static Ref<CSSUnitValue> deg(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_DEG); }
     81    static Ref<CSSUnitValue> grad(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_GRAD); }
     82    static Ref<CSSUnitValue> rad(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_RAD); }
     83    static Ref<CSSUnitValue> turn(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_TURN); }
    8484
    8585
    8686    // <time>
    87     static Ref<CSSUnitValue> s(double value) { return CSSUnitValue::create(value, "s"_s); }
    88     static Ref<CSSUnitValue> ms(double value) { return CSSUnitValue::create(value, "ms"_s); }
     87    static Ref<CSSUnitValue> s(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_S); }
     88    static Ref<CSSUnitValue> ms(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_MS); }
    8989
    9090
    9191    // <frequency>
    92     static Ref<CSSUnitValue> hz(double value) { return CSSUnitValue::create(value, "hz"_s); }
    93     static Ref<CSSUnitValue> kHz(double value) { return CSSUnitValue::create(value, "khz"_s); }
     92    static Ref<CSSUnitValue> hz(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_HZ); }
     93    static Ref<CSSUnitValue> kHz(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_KHZ); }
    9494
    9595
    9696    // <resolution>
    97     static Ref<CSSUnitValue> dpi(double value) { return CSSUnitValue::create(value, "dpi"_s); }
    98     static Ref<CSSUnitValue> dpcm(double value) { return CSSUnitValue::create(value, "dpcm"_s); }
    99     static Ref<CSSUnitValue> dppx(double value) { return CSSUnitValue::create(value, "dppx"_s); }
     97    static Ref<CSSUnitValue> dpi(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_DPI); }
     98    static Ref<CSSUnitValue> dpcm(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_DPCM); }
     99    static Ref<CSSUnitValue> dppx(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_DPPX); }
    100100
    101101
    102102    // <flex>
    103     static Ref<CSSUnitValue> fr(double value) { return CSSUnitValue::create(value, "fr"_s); }
     103    static Ref<CSSUnitValue> fr(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_FR); }
    104104
    105105
  • trunk/Source/WebCore/css/typedom/CSSNumericValue.cpp

    r291863 r292150  
    5757        return mathNegate->value();
    5858    if (auto* unitValue = dynamicDowncast<CSSUnitValue>(value.get()))
    59         return CSSUnitValue::create(-unitValue->value(), unitValue->unit());
     59        return CSSUnitValue::create(-unitValue->value(), unitValue->unitEnum());
    6060    return CSSMathNegate::create(WTFMove(value));
    6161}
     
    6868
    6969    if (auto* unitValue = dynamicDowncast<CSSUnitValue>(value.get())) {
    70         // FIXME: units should be either AtomicStrings or CSSUnitType enumeration values.
    71         if (unitValue->unit() == "number") {
     70        if (unitValue->unitEnum() == CSSUnitType::CSS_NUMBER) {
    7271            if (unitValue->value() == 0.0 || unitValue->value() == -0.0)
    7372                return Exception { RangeError };
    74             return Ref<CSSNumericValue> { CSSUnitValue::create(1.0 / unitValue->value(), unitValue->unit()) };
     73            return Ref<CSSNumericValue> { CSSUnitValue::create(1.0 / unitValue->value(), unitValue->unitEnum()) };
    7574        }
    7675    }
     
    8483    bool allValuesHaveSameUnit = values.size() && WTF::allOf(values, [&] (const Ref<CSSNumericValue>& value) {
    8584        auto* unitValue = dynamicDowncast<CSSUnitValue>(value.get());
    86         return unitValue ? unitValue->unit() == downcast<CSSUnitValue>(values[0].get()).unit() : false;
     85        return unitValue ? unitValue->unitEnum() == downcast<CSSUnitValue>(values[0].get()).unitEnum() : false;
    8786    });
    8887    if (allValuesHaveSameUnit) {
    8988        auto& firstUnitValue = downcast<CSSUnitValue>(values[0].get());
    90         String unit = firstUnitValue.unit();
     89        auto unit = firstUnitValue.unitEnum();
    9190        double result = firstUnitValue.value();
    9291        for (size_t i = 1; i < values.size(); i++)
     
    108107}
    109108
    110 Ref<CSSNumericValue> CSSNumericValue::addInternal(Vector<Ref<CSSNumericValue>>&& numericValues)
     109ExceptionOr<Ref<CSSNumericValue>> CSSNumericValue::addInternal(Vector<Ref<CSSNumericValue>>&& numericValues)
    111110{
    112111    // https://drafts.css-houdini.org/css-typed-om/#dom-cssnumericvalue-add
     
    114113
    115114    if (auto result = operationOnValuesOfSameUnit(std::plus<double>(), values))
    116         return *result;
    117 
    118     // FIXME: Implement step 4 to check that the types can be added.
    119 
    120     return CSSMathSum::create(WTFMove(values));
    121 }
    122 
    123 Ref<CSSNumericValue> CSSNumericValue::add(FixedVector<CSSNumberish>&& values)
     115        return { *result };
     116
     117    auto sum = CSSMathSum::create(WTFMove(values));
     118    if (sum.hasException())
     119        return sum.releaseException();
     120    return Ref<CSSNumericValue> { sum.releaseReturnValue() };
     121}
     122
     123ExceptionOr<Ref<CSSNumericValue>> CSSNumericValue::add(FixedVector<CSSNumberish>&& values)
    124124{
    125125    return addInternal(WTF::map(WTFMove(values), rectifyNumberish));
    126126}
    127127
    128 Ref<CSSNumericValue> CSSNumericValue::sub(FixedVector<CSSNumberish>&& values)
     128ExceptionOr<Ref<CSSNumericValue>> CSSNumericValue::sub(FixedVector<CSSNumberish>&& values)
    129129{
    130130    return addInternal(WTF::map(WTFMove(values), [] (CSSNumberish&& numberish) {
     
    133133}
    134134
    135 Ref<CSSNumericValue> CSSNumericValue::multiplyInternal(Vector<Ref<CSSNumericValue>>&& numericValues)
     135ExceptionOr<Ref<CSSNumericValue>> CSSNumericValue::multiplyInternal(Vector<Ref<CSSNumericValue>>&& numericValues)
    136136{
    137137    // https://drafts.css-houdini.org/css-typed-om/#dom-cssnumericvalue-mul
     
    145145        std::optional<size_t> nonNumberUnitIndex;
    146146        for (size_t i = 0; i < values.size(); i++) {
    147             auto& unit = downcast<CSSUnitValue>(values[i].get()).unit();
    148             if (unit == "number")
     147            auto unit = downcast<CSSUnitValue>(values[i].get()).unitEnum();
     148            if (unit == CSSUnitType::CSS_NUMBER)
    149149                continue;
    150150            if (nonNumberUnitIndex) {
     
    158158            for (const Ref<CSSNumericValue>& value : values)
    159159                product *= downcast<CSSUnitValue>(value.get()).value();
    160             String unit = nonNumberUnitIndex ? downcast<CSSUnitValue>(values[*nonNumberUnitIndex].get()).unit() : "number"_s;
    161             return CSSUnitValue::create(product, unit);
     160            auto unit = nonNumberUnitIndex ? downcast<CSSUnitValue>(values[*nonNumberUnitIndex].get()).unitEnum() : CSSUnitType::CSS_NUMBER;
     161            return { CSSUnitValue::create(product, unit) };
    162162        }
    163163    }
    164164
    165     // FIXME: Implement step 5 to produce a unit of the correct type.
    166 
    167     return CSSMathProduct::create(WTFMove(values));
    168 }
    169 
    170 Ref<CSSNumericValue> CSSNumericValue::mul(FixedVector<CSSNumberish>&& values)
     165    auto product = CSSMathProduct::create(WTFMove(values));
     166    if (product.hasException())
     167        return product.releaseException();
     168    return Ref<CSSNumericValue> { product.releaseReturnValue() };
     169}
     170
     171ExceptionOr<Ref<CSSNumericValue>> CSSNumericValue::mul(FixedVector<CSSNumberish>&& values)
    171172{
    172173    return multiplyInternal(WTF::map(WTFMove(values), rectifyNumberish));
     
    236237    // https://drafts.css-houdini.org/css-typed-om/#dom-cssnumericvalue-to
    237238    // FIXME: add impl.
    238     return CSSUnitValue::create(1.0, "number"_s);
    239 }
    240 
    241 Ref<CSSMathSum> CSSNumericValue::toSum(FixedVector<String>&& units)
     239    return CSSUnitValue::create(1.0, CSSUnitType::CSS_NUMBER);
     240}
     241
     242ExceptionOr<Ref<CSSMathSum>> CSSNumericValue::toSum(FixedVector<String>&& units)
    242243{
    243244    UNUSED_PARAM(units);
     
    247248}
    248249
    249 CSSNumericType CSSNumericValue::type()
    250 {
    251     // https://drafts.css-houdini.org/css-typed-om/#dom-cssnumericvalue-type
    252     // FIXME: add impl.
    253     return CSSNumericType { };
    254 }
    255 
    256250ExceptionOr<Ref<CSSNumericValue>> CSSNumericValue::parse(String&& cssText)
    257251{
  • trunk/Source/WebCore/css/typedom/CSSNumericValue.h

    r291867 r292150  
    2828#if ENABLE(CSS_TYPED_OM)
    2929
     30#include "CSSNumericType.h"
    3031#include "CSSStyleValue.h"
    3132#include <variant>
     
    3738class CSSUnitValue;
    3839class CSSMathSum;
    39 struct CSSNumericType;
    4040
    4141template<typename> class ExceptionOr;
     
    4747public:
    4848
    49     Ref<CSSNumericValue> add(FixedVector<CSSNumberish>&&);
    50     Ref<CSSNumericValue> sub(FixedVector<CSSNumberish>&&);
    51     Ref<CSSNumericValue> mul(FixedVector<CSSNumberish>&&);
     49    ExceptionOr<Ref<CSSNumericValue>> add(FixedVector<CSSNumberish>&&);
     50    ExceptionOr<Ref<CSSNumericValue>> sub(FixedVector<CSSNumberish>&&);
     51    ExceptionOr<Ref<CSSNumericValue>> mul(FixedVector<CSSNumberish>&&);
    5252    ExceptionOr<Ref<CSSNumericValue>> div(FixedVector<CSSNumberish>&&);
    5353    Ref<CSSNumericValue> min(FixedVector<CSSNumberish>&&);
     
    5757   
    5858    Ref<CSSUnitValue> to(String&&);
    59     Ref<CSSMathSum> toSum(FixedVector<String>&&);
    60     CSSNumericType type();
     59    ExceptionOr<Ref<CSSMathSum>> toSum(FixedVector<String>&&);
     60
     61    const CSSNumericType& type() const { return m_type; }
    6162   
    6263    static ExceptionOr<Ref<CSSNumericValue>> parse(String&&);
     
    6667
    6768protected:
    68     Ref<CSSNumericValue> addInternal(Vector<Ref<CSSNumericValue>>&&);
    69     Ref<CSSNumericValue> multiplyInternal(Vector<Ref<CSSNumericValue>>&&);
     69    ExceptionOr<Ref<CSSNumericValue>> addInternal(Vector<Ref<CSSNumericValue>>&&);
     70    ExceptionOr<Ref<CSSNumericValue>> multiplyInternal(Vector<Ref<CSSNumericValue>>&&);
    7071    template<typename T> Vector<Ref<CSSNumericValue>> prependItemsOfTypeOrThis(Vector<Ref<CSSNumericValue>>&&);
    7172
    72     CSSNumericValue() = default;
     73    CSSNumericValue(CSSNumericType type = { })
     74        : m_type(WTFMove(type)) { }
     75
     76    CSSNumericType m_type;
    7377};
    7478
  • trunk/Source/WebCore/css/typedom/CSSUnitValue.cpp

    r280968 r292150  
    3333#if ENABLE(CSS_TYPED_OM)
    3434
     35#include "CSSParserToken.h"
     36#include "CSSPrimitiveValue.h"
    3537#include <wtf/IsoMallocInlines.h>
    3638
     
    3941WTF_MAKE_ISO_ALLOCATED_IMPL(CSSUnitValue);
    4042
     43static std::optional<CSSNumericType> numericType(CSSUnitType unit)
     44{
     45    // https://drafts.css-houdini.org/css-typed-om/#cssnumericvalue-create-a-type
     46    CSSNumericType type;
     47    switch (unitCategory(unit)) {
     48    case CSSUnitCategory::Number:
     49        return { WTFMove(type) };
     50    case CSSUnitCategory::Percent:
     51        type.percent = 1;
     52        return { WTFMove(type) };
     53    case CSSUnitCategory::Length:
     54        type.length = 1;
     55        return { WTFMove(type) };
     56    case CSSUnitCategory::Angle:
     57        type.angle = 1;
     58        return { WTFMove(type) };
     59    case CSSUnitCategory::Time:
     60        type.time = 1;
     61        return { WTFMove(type) };
     62    case CSSUnitCategory::Frequency:
     63        type.frequency = 1;
     64        return { WTFMove(type) };
     65    case CSSUnitCategory::Resolution:
     66        type.resolution = 1;
     67        return { WTFMove(type) };
     68    case CSSUnitCategory::Other:
     69        if (unit == CSSUnitType::CSS_FR) {
     70            type.flex = 1;
     71            return { WTFMove(type) };
     72        }
     73        break;
     74    }
     75   
     76    return std::nullopt;
     77}
     78
     79static CSSUnitType parseUnit(const String& unit)
     80{
     81    if (unit == "number"_s)
     82        return CSSUnitType::CSS_NUMBER;
     83    if (unit == "percent"_s)
     84        return CSSUnitType::CSS_PERCENTAGE;
     85
     86    // FIXME: Remove these when LineHeightUnitsEnabled is changed back to true or removed
     87    // https://bugs.webkit.org/show_bug.cgi?id=211351
     88    if (unit == "lh"_s)
     89        return CSSUnitType::CSS_LHS;
     90    if (unit == "rlh"_s)
     91        return CSSUnitType::CSS_RLHS;
     92
     93    return CSSParserToken::stringToUnitType(unit);
     94}
     95
     96String CSSUnitValue::unit() const
     97{
     98    switch (m_unit) {
     99    case CSSUnitType::CSS_NUMBER:
     100        return "number"_s;
     101    case CSSUnitType::CSS_PERCENTAGE:
     102        return "percent"_s;
     103    default:
     104        break;
     105    }
     106    return unitSerialization();
     107}
     108
     109String CSSUnitValue::unitSerialization() const
     110{
     111    return CSSPrimitiveValue::unitTypeString(m_unit);
     112}
     113
     114ExceptionOr<Ref<CSSUnitValue>> CSSUnitValue::create(double value, const String& unit)
     115{
     116    auto parsedUnit = parseUnit(unit);
     117    if (parsedUnit == CSSUnitType::CSS_UNKNOWN)
     118        return Exception { TypeError };
     119    auto type = numericType(parsedUnit);
     120    if (!type)
     121        return Exception { TypeError };
     122    auto unitValue = adoptRef(*new CSSUnitValue(value, parsedUnit));
     123    unitValue->m_type = WTFMove(*type);
     124    return unitValue;
     125}
     126
     127CSSUnitValue::CSSUnitValue(double value, CSSUnitType unit)
     128    : CSSNumericValue(numericType(unit).value_or(CSSNumericType()))
     129    , m_value(value)
     130    , m_unit(unit)
     131{
     132}
     133
    41134} // namespace WebCore
    42135
  • trunk/Source/WebCore/css/typedom/CSSUnitValue.h

    r291597 r292150  
    3535namespace WebCore {
    3636
     37enum class CSSUnitType : uint8_t;
     38
    3739class CSSUnitValue final : public CSSNumericValue {
    3840    WTF_MAKE_ISO_ALLOCATED(CSSUnitValue);
    3941public:
    40     static Ref<CSSUnitValue> create(double value, const String& unit)
    41     {
    42         return adoptRef(*new CSSUnitValue(value, unit));
    43     }
     42    static ExceptionOr<Ref<CSSUnitValue>> create(double value, const String& unit);
     43    static Ref<CSSUnitValue> create(double value, CSSUnitType unit) { return adoptRef(*new CSSUnitValue(value, unit)); }
    4444
    45     // FIXME: not correct.
    46     String toString() const final { return makeString((int) m_value, m_unit); }
     45    String toString() const final { return makeString(FormattedCSSNumber::create(m_value), unitSerialization()); }
    4746
    4847    double value() const { return m_value; }
    4948    void setValue(double value) { m_value = value; }
    50     const String& unit() const { return m_unit; }
    51     void setUnit(const String& unit) { m_unit = unit; }
     49    String unit() const;
     50    String unitSerialization() const;
     51    CSSUnitType unitEnum() const { return m_unit; }
    5252
    5353private:
    54     CSSUnitValue(double value, const String& unit)
    55         : m_value(value)
    56         , m_unit(unit)
    57     {
    58     }
     54    CSSUnitValue(double, CSSUnitType);
    5955
    6056    CSSStyleValueType getType() const final { return CSSStyleValueType::CSSUnitValue; }
    6157
    6258    double m_value;
    63     String m_unit;
     59    const CSSUnitType m_unit;
    6460};
    6561
  • trunk/Source/WebCore/css/typedom/numeric/CSSMathInvert.cpp

    r291597 r292150  
    4242}
    4343
     44static CSSNumericType negatedType(const CSSNumberish& numberish)
     45{
     46    // https://drafts.css-houdini.org/css-typed-om/#type-of-a-cssmathvalue
     47    return WTF::switchOn(numberish,
     48        [] (double) { return CSSNumericType(); },
     49        [] (const RefPtr<CSSNumericValue>& value) {
     50            if (!value)
     51                return CSSNumericType();
     52            CSSNumericType type = value->type();
     53            auto negate = [] (auto& optional) {
     54                if (optional)
     55                    optional = *optional * -1;
     56            };
     57            negate(type.length);
     58            negate(type.angle);
     59            negate(type.time);
     60            negate(type.frequency);
     61            negate(type.resolution);
     62            negate(type.flex);
     63            negate(type.percent);
     64            return type;
     65        }
     66    );
     67}
     68
    4469CSSMathInvert::CSSMathInvert(CSSNumberish&& numberish)
    45     : m_value(CSSNumericValue::rectifyNumberish(WTFMove(numberish)))
     70    : CSSMathValue(negatedType(numberish))
     71    , m_value(CSSNumericValue::rectifyNumberish(WTFMove(numberish)))
    4672{
    4773}
  • trunk/Source/WebCore/css/typedom/numeric/CSSMathNegate.cpp

    r291597 r292150  
    3737WTF_MAKE_ISO_ALLOCATED_IMPL(CSSMathNegate);
    3838
     39static CSSNumericType copyType(const CSSNumberish& numberish)
     40{
     41    return WTF::switchOn(numberish,
     42        [] (double) { return CSSNumericType(); },
     43        [] (const RefPtr<CSSNumericValue>& value) {
     44            if (!value)
     45                return CSSNumericType();
     46            return value->type();
     47        }
     48    );
     49}
     50
    3951CSSMathNegate::CSSMathNegate(CSSNumberish&& numberish)
    40     : m_value(CSSNumericValue::rectifyNumberish(WTFMove(numberish)))
     52    : CSSMathValue(copyType(numberish))
     53    , m_value(CSSNumericValue::rectifyNumberish(WTFMove(numberish)))
    4154{
    4255}
    4356
    4457CSSMathNegate::CSSMathNegate(Ref<CSSNumericValue>&& value)
    45     : m_value(WTFMove(value))
     58    : CSSMathValue(value->type())
     59    , m_value(WTFMove(value))
    4660{
    4761}
  • trunk/Source/WebCore/css/typedom/numeric/CSSMathProduct.cpp

    r291597 r292150  
    2727#include "CSSMathProduct.h"
    2828
    29 #include "CSSNumericArray.h"
    30 
    3129#if ENABLE(CSS_TYPED_OM)
    3230
     31#include "CSSNumericArray.h"
     32#include "ExceptionOr.h"
    3333#include <wtf/IsoMallocInlines.h>
    3434
     
    3737WTF_MAKE_ISO_ALLOCATED_IMPL(CSSMathProduct);
    3838
    39 CSSMathProduct::CSSMathProduct(FixedVector<CSSNumberish>&& numberishes)
    40     : m_values(CSSNumericArray::create(WTFMove(numberishes)))
     39static std::optional<CSSNumericType> multiplyTypes(const CSSNumericType& a, const CSSNumericType& b)
    4140{
     41    // https://drafts.css-houdini.org/css-typed-om/#cssnumericvalue-multiply-two-types
     42    if (a.percentHint && b.percentHint && *a.percentHint != *b.percentHint)
     43        return std::nullopt;
     44
     45    auto add = [] (auto left, auto right) -> std::optional<unsigned> {
     46        if (!left)
     47            return right;
     48        if (!right)
     49            return left;
     50        return *left + *right;
     51    };
     52   
     53    return { {
     54        add(a.length, b.length),
     55        add(a.angle, b.angle),
     56        add(a.time, b.time),
     57        add(a.frequency, b.frequency),
     58        add(a.resolution, b.resolution),
     59        add(a.flex, b.flex),
     60        add(a.percent, b.percent),
     61        a.percentHint ? a.percentHint : b.percentHint
     62    } };
    4263}
    4364
    44 CSSMathProduct::CSSMathProduct(Vector<Ref<CSSNumericValue>>&& values)
    45     : m_values(CSSNumericArray::create(WTFMove(values)))
     65ExceptionOr<Ref<CSSMathProduct>> CSSMathProduct::create(FixedVector<CSSNumberish> numberishes)
    4666{
     67    return create(WTF::map(WTFMove(numberishes), rectifyNumberish));
    4768}
    4869
    49 const CSSNumericArray& CSSMathProduct::values() const
     70ExceptionOr<Ref<CSSMathProduct>> CSSMathProduct::create(Vector<Ref<CSSNumericValue>> values)
    5071{
    51     return m_values.get();
     72    if (values.isEmpty())
     73        return Exception { SyntaxError };
     74   
     75    std::optional<CSSNumericType> type = values[0]->type();
     76    for (size_t i = 1; i < values.size(); i++) {
     77        type = multiplyTypes(*type, values[i]->type());
     78        if (!type)
     79            return Exception { TypeError };
     80    }
     81
     82    return adoptRef(*new CSSMathProduct(WTFMove(values), WTFMove(*type)));
     83}
     84
     85CSSMathProduct::CSSMathProduct(Vector<Ref<CSSNumericValue>> values, CSSNumericType type)
     86    : CSSMathValue(WTFMove(type))
     87    , m_values(CSSNumericArray::create(WTFMove(values)))
     88{
    5289}
    5390
  • trunk/Source/WebCore/css/typedom/numeric/CSSMathProduct.h

    r291597 r292150  
    3838    WTF_MAKE_ISO_ALLOCATED(CSSMathProduct);
    3939public:
    40     template<typename... Args> static Ref<CSSMathProduct> create(Args&&... args) { return adoptRef(*new CSSMathProduct(std::forward<Args>(args)...)); }
    41     const CSSNumericArray& values() const;
     40    static ExceptionOr<Ref<CSSMathProduct>> create(FixedVector<CSSNumberish>);
     41    static ExceptionOr<Ref<CSSMathProduct>> create(Vector<Ref<CSSNumericValue>>);
     42    const CSSNumericArray& values() const { return m_values.get(); }
    4243
    4344private:
     
    4546    CSSStyleValueType getType() const final { return CSSStyleValueType::CSSMathProduct; }
    4647
    47     CSSMathProduct(FixedVector<CSSNumberish>&&);
    48     CSSMathProduct(Vector<Ref<CSSNumericValue>>&&);
     48    CSSMathProduct(Vector<Ref<CSSNumericValue>>, CSSNumericType);
    4949    Ref<CSSNumericArray> m_values;
    5050};
  • trunk/Source/WebCore/css/typedom/numeric/CSSMathSum.cpp

    r291597 r292150  
    2727#include "CSSMathSum.h"
    2828
    29 #include "CSSNumericArray.h"
    30 
    3129#if ENABLE(CSS_TYPED_OM)
    3230
     31#include "CSSNumericArray.h"
     32#include <wtf/Algorithms.h>
    3333#include <wtf/IsoMallocInlines.h>
    3434
     
    3737WTF_MAKE_ISO_ALLOCATED_IMPL(CSSMathSum);
    3838
    39 CSSMathSum::CSSMathSum(FixedVector<CSSNumberish>&& numberishes)
    40     : m_values(CSSNumericArray::create(WTFMove(numberishes)))
     39static std::optional<CSSNumericType> addTypes(CSSNumericType a, CSSNumericType b)
    4140{
     41    // https://drafts.css-houdini.org/css-typed-om/#cssnumericvalue-add-two-types
     42    if (a.percentHint && b.percentHint && *a.percentHint != *b.percentHint)
     43        return std::nullopt;
     44
     45    if (a.percentHint)
     46        b.applyPercentHint(*a.percentHint);
     47    if (b.percentHint)
     48        a.applyPercentHint(*b.percentHint);
     49
     50    if (a == b)
     51        return { WTFMove(a) };
     52
     53    for (auto type : eachBaseType()) {
     54        if (type == CSSNumericBaseType::Percent)
     55            continue;
     56        if (!a.valueForType(type) && !b.valueForType(type))
     57            continue;
     58        a.applyPercentHint(type);
     59        b.applyPercentHint(type);
     60        if (a.valueForType(type) != b.valueForType(type))
     61            return std::nullopt;
     62    }
     63
     64    return { WTFMove(a) };
    4265}
    4366
    44 CSSMathSum::CSSMathSum(Vector<Ref<CSSNumericValue>>&& values)
    45     : m_values(CSSNumericArray::create(WTFMove(values)))
     67ExceptionOr<Ref<CSSMathSum>> CSSMathSum::create(FixedVector<CSSNumberish> numberishes)
     68{
     69    return create(WTF::map(WTFMove(numberishes), rectifyNumberish));
     70}
     71
     72ExceptionOr<Ref<CSSMathSum>> CSSMathSum::create(Vector<Ref<CSSNumericValue>> values)
     73{
     74    if (values.isEmpty())
     75        return Exception { SyntaxError };
     76
     77    std::optional<CSSNumericType> type = values[0]->type();
     78    for (size_t i = 1; i < values.size(); i++) {
     79        type = addTypes(*type, values[i]->type());
     80        if (!type)
     81            return Exception { TypeError };
     82    }
     83
     84    return adoptRef(*new CSSMathSum(WTFMove(values), WTFMove(*type)));
     85}
     86
     87CSSMathSum::CSSMathSum(Vector<Ref<CSSNumericValue>> values, CSSNumericType type)
     88    : CSSMathValue(WTFMove(type))
     89    , m_values(CSSNumericArray::create(WTFMove(values)))
    4690{
    4791}
  • trunk/Source/WebCore/css/typedom/numeric/CSSMathSum.h

    r291597 r292150  
    3939    WTF_MAKE_ISO_ALLOCATED(CSSMathSum);
    4040public:
    41     template<typename... Args> static Ref<CSSMathSum> create(Args&&... args) { return adoptRef(*new CSSMathSum(std::forward<Args>(args)...)); }
     41    static ExceptionOr<Ref<CSSMathSum>> create(FixedVector<CSSNumberish>);
     42    static ExceptionOr<Ref<CSSMathSum>> create(Vector<Ref<CSSNumericValue>>);
    4243    const CSSNumericArray& values() const { return m_values.get(); }
    4344
     
    4647    CSSStyleValueType getType() const override { return CSSStyleValueType::CSSMathSum; }
    4748
    48     CSSMathSum(FixedVector<CSSNumberish>&&);
    49     CSSMathSum(Vector<Ref<CSSNumericValue>>&&);
     49    CSSMathSum(Vector<Ref<CSSNumericValue>>, CSSNumericType);
    5050    Ref<CSSNumericArray> m_values;
    5151};
  • trunk/Source/WebCore/css/typedom/numeric/CSSMathValue.h

    r291597 r292150  
    3636class CSSMathValue : public CSSNumericValue {
    3737public:
     38    CSSMathValue(CSSNumericType type = { })
     39        : CSSNumericValue(WTFMove(type)) { }
    3840    virtual CSSMathOperator getOperator() const = 0;
    3941};
  • trunk/Source/WebCore/css/typedom/numeric/CSSNumericArray.cpp

    r291597 r292150  
    3939WTF_MAKE_ISO_ALLOCATED_IMPL(CSSNumericArray);
    4040
    41 Ref<CSSNumericArray> CSSNumericArray::create(const FixedVector<CSSNumberish>& numberishes)
     41Ref<CSSNumericArray> CSSNumericArray::create(FixedVector<CSSNumberish>&& numberishes)
    4242{
    43     return adoptRef(*new CSSNumericArray(WTF::map(numberishes, [](auto& numberish) -> Ref<CSSNumericValue> {
    44         return CSSNumericValue::rectifyNumberish(const_cast<CSSNumberish&&>(numberish));
    45     })));
     43    return adoptRef(*new CSSNumericArray(WTF::map(WTFMove(numberishes), CSSNumericValue::rectifyNumberish)));
    4644}
    4745
  • trunk/Source/WebCore/css/typedom/numeric/CSSNumericArray.h

    r291597 r292150  
    4141    WTF_MAKE_ISO_ALLOCATED(CSSNumericArray);
    4242public:
    43     static Ref<CSSNumericArray> create(const FixedVector<CSSNumberish>&);
     43    static Ref<CSSNumericArray> create(FixedVector<CSSNumberish>&&);
    4444    static Ref<CSSNumericArray> create(Vector<Ref<CSSNumericValue>>&&);
    4545    size_t length() const { return m_array.size(); };
  • trunk/Source/WebCore/css/typedom/numeric/CSSNumericBaseType.h

    r282356 r292150  
    2828#if ENABLE(CSS_TYPED_OM)
    2929
     30#include <array>
     31
    3032namespace WebCore {
    3133
    32 enum class CSSNumericBaseType: uint8_t {
     34enum class CSSNumericBaseType : uint8_t {
    3335    Length,
    3436    Angle,
     
    4042};
    4143
     44constexpr std::array<CSSNumericBaseType, 7> eachBaseType()
     45{
     46    return {
     47        CSSNumericBaseType::Length,
     48        CSSNumericBaseType::Angle,
     49        CSSNumericBaseType::Time,
     50        CSSNumericBaseType::Frequency,
     51        CSSNumericBaseType::Resolution,
     52        CSSNumericBaseType::Flex,
     53        CSSNumericBaseType::Percent
     54    };
     55}
     56
     57constexpr const char* debugString(CSSNumericBaseType type)
     58{
     59    switch (type) {
     60    case CSSNumericBaseType::Length:
     61        return "length";
     62    case CSSNumericBaseType::Angle:
     63        return "angle";
     64    case CSSNumericBaseType::Time:
     65        return "time";
     66    case CSSNumericBaseType::Frequency:
     67        return "frequency";
     68    case CSSNumericBaseType::Resolution:
     69        return "resolution";
     70    case CSSNumericBaseType::Flex:
     71        return "flex";
     72    case CSSNumericBaseType::Percent:
     73        return "percent";
     74    }
     75    return "invalid";
     76}
     77
    4278} // namespace WebCore
    4379
  • trunk/Source/WebCore/css/typedom/numeric/CSSNumericType.h

    r291597 r292150  
    3030#include "CSSNumericBaseType.h"
    3131#include <optional>
     32#include <wtf/text/StringConcatenateNumbers.h>
    3233
    3334namespace WebCore {
    3435
     36// https://drafts.css-houdini.org/css-typed-om/#dom-cssnumericvalue-type
    3537struct CSSNumericType {
    36     long length { 0 };
    37     long angle { 0 };
    38     long time { 0 };
    39     long frequency { 0 };
    40     long resolution { 0 };
    41     long flex { 0 };
    42     long percent { 0 };
     38    std::optional<long> length;
     39    std::optional<long> angle;
     40    std::optional<long> time;
     41    std::optional<long> frequency;
     42    std::optional<long> resolution;
     43    std::optional<long> flex;
     44    std::optional<long> percent;
    4345    std::optional<CSSNumericBaseType> percentHint;
     46
     47    bool operator==(const CSSNumericType& other) const
     48    {
     49        return length == other.length
     50            && angle == other.angle
     51            && time == other.time
     52            && frequency == other.frequency
     53            && resolution == other.resolution
     54            && flex == other.flex
     55            && percent == other.percent
     56            && percentHint == other.percentHint;
     57    }
     58
     59    std::optional<long>& valueForType(CSSNumericBaseType type)
     60    {
     61        switch (type) {
     62        case CSSNumericBaseType::Length:
     63            return length;
     64        case CSSNumericBaseType::Angle:
     65            return angle;
     66        case CSSNumericBaseType::Time:
     67            return time;
     68        case CSSNumericBaseType::Frequency:
     69            return frequency;
     70        case CSSNumericBaseType::Resolution:
     71            return resolution;
     72        case CSSNumericBaseType::Flex:
     73            return flex;
     74        case CSSNumericBaseType::Percent:
     75            return percent;
     76        }
     77        RELEASE_ASSERT_NOT_REACHED();
     78    }
     79
     80    void applyPercentHint(CSSNumericBaseType hint)
     81    {
     82        // https://drafts.css-houdini.org/css-typed-om/#apply-the-percent-hint
     83        auto& optional = valueForType(hint);
     84        if (!optional)
     85            optional = 0;
     86        if (percent)
     87            *optional += *std::exchange(percent, 0);
     88        percentHint = hint;
     89    }
     90
     91    String debugString() const
     92    {
     93        return makeString("{",
     94            length ? makeString(" length:", *length) : String(),
     95            angle ? makeString(" angle:", *angle) : String(),
     96            time ? makeString(" time:", *time) : String(),
     97            frequency ? makeString(" frequency:", *frequency) : String(),
     98            resolution ? makeString(" resolution:", *resolution) : String(),
     99            flex ? makeString(" flex:", *flex) : String(),
     100            percent ? makeString(" percent:", *percent) : String(),
     101            percentHint ? makeString(" percentHint:", WebCore::debugString(*percentHint)) : String(),
     102        " }");
     103    }
    44104};
    45105
  • trunk/Source/WebCore/css/typedom/numeric/CSSNumericType.idl

    r282356 r292150  
    2424*/
    2525
     26// https://drafts.css-houdini.org/css-typed-om/#dom-cssnumericvalue-type
     27
    2628[
    2729    Conditional=CSS_TYPED_OM,
Note: See TracChangeset for help on using the changeset viewer.