Changeset 278364 in webkit


Ignore:
Timestamp:
Jun 2, 2021 10:38:56 AM (14 months ago)
Author:
weinig@apple.com
Message:

Add support for "relative color syntax" for color()
https://bugs.webkit.org/show_bug.cgi?id=226513

Reviewed by Darin Adler.

Source/WebCore:

CSS Color 5 has recently been update to support relative color syntax for
the color() function in addition to the existing rgb(), hsl(), hwb(), lab()
and lch().

Took the opertunity to refactor other relative color syntax parsing to share
more code between relative and non-relative parsers using a shared function
with lambdas to differentiate the component consumers. This was done for all
the color types except rgb() and hsl(), which have notable differences in
parsing between the relative and non-relative version.

  • css/parser/CSSPropertyParserHelpers.cpp:

(WebCore::CSSPropertyParserHelpers::parseNonRelativeRGBParameters):
(WebCore::CSSPropertyParserHelpers::parseRGBParameters):
(WebCore::CSSPropertyParserHelpers::colorByNormalizingHSLComponents):
(WebCore::CSSPropertyParserHelpers::parseRelativeHSLParameters):
(WebCore::CSSPropertyParserHelpers::parseNonRelativeHSLParameters):
(WebCore::CSSPropertyParserHelpers::parseHSLParameters):
(WebCore::CSSPropertyParserHelpers::parseHWBParameters):
(WebCore::CSSPropertyParserHelpers::parseRelativeHWBParameters):
(WebCore::CSSPropertyParserHelpers::parseNonRelativeHWBParameters):
(WebCore::CSSPropertyParserHelpers::parseLabParameters):
(WebCore::CSSPropertyParserHelpers::parseRelativeLabParameters):
(WebCore::CSSPropertyParserHelpers::parseNonRelativeLabParameters):
(WebCore::CSSPropertyParserHelpers::parseLCHParameters):
(WebCore::CSSPropertyParserHelpers::parseRelativeLCHParameters):
(WebCore::CSSPropertyParserHelpers::parseNonRelativeLCHParameters):
(WebCore::CSSPropertyParserHelpers::parseColorFunctionForRGBTypes):
(WebCore::CSSPropertyParserHelpers::parseRelativeColorFunctionForRGBTypes):
(WebCore::CSSPropertyParserHelpers::parseColorFunctionForXYZParameters):
(WebCore::CSSPropertyParserHelpers::parseRelativeColorFunctionForXYZParameters):
(WebCore::CSSPropertyParserHelpers::parseRelativeColorFunctionParameters):
(WebCore::CSSPropertyParserHelpers::parseNonRelativeColorFunctionParameters):
(WebCore::CSSPropertyParserHelpers::parseColorFunctionParameters):

LayoutTests:

Updated test and results now that we support relative color syntax
for color(srgb ...), color(a98-rgb ...), color(rec2020 ...),
color(prophoto-rgb ...) and color(xyz ...).

  • fast/css/parsing-relative-color-syntax-expected.txt:
  • fast/css/parsing-relative-color-syntax.html:
Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r278362 r278364  
     12021-06-02  Sam Weinig  <weinig@apple.com>
     2
     3        Add support for "relative color syntax" for color()
     4        https://bugs.webkit.org/show_bug.cgi?id=226513
     5
     6        Reviewed by Darin Adler.
     7
     8        Updated test and results now that we support relative color syntax
     9        for color(srgb ...), color(a98-rgb ...), color(rec2020 ...),
     10        color(prophoto-rgb ...) and color(xyz ...).
     11
     12        * fast/css/parsing-relative-color-syntax-expected.txt:
     13        * fast/css/parsing-relative-color-syntax.html:
     14
    1152021-06-02  Kyle Piddington  <kpiddington@apple.com>
    216
  • trunk/LayoutTests/fast/css/parsing-relative-color-syntax-expected.txt

    r278304 r278364  
    286286PASS computedStyle("background-color", "lch(from lch(70% 45 30) x c h)") is "rgba(0, 0, 0, 0)"
    287287PASS computedStyle("background-color", "lch(from lch(70% 45 30) l g b)") is "rgba(0, 0, 0, 0)"
     288
     289color(from ... ${color} ...)
     290PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb r g b)") is "color(srgb 0.7 0.5 0.3)"
     291PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb r g b / alpha)") is "color(srgb 0.7 0.5 0.3)"
     292PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b)") is "color(srgb 0.7 0.5 0.3)"
     293PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / alpha)") is "color(srgb 0.7 0.5 0.3 / 0.4)"
     294PASS computedStyle("background-color", "color(from color(from color(srgb 0.7 0.5 0.3) srgb r g b) srgb r g b)") is "color(srgb 0.7 0.5 0.3)"
     295PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb 0 0 0)") is "color(srgb 0 0 0)"
     296PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb 0 0 0)") is "color(srgb 0 0 0)"
     297PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb 0 0 0 / 0)") is "color(srgb 0 0 0 / 0)"
     298PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb 0 0 0 / 0)") is "color(srgb 0 0 0 / 0)"
     299PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb 0 g b / alpha)") is "color(srgb 0 0.5 0.3)"
     300PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb r 0 b / alpha)") is "color(srgb 0.7 0 0.3)"
     301PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb r g 0 / alpha)") is "color(srgb 0.7 0.5 0)"
     302PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb r g b / 0)") is "color(srgb 0.7 0.5 0.3 / 0)"
     303PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb 0 g b / alpha)") is "color(srgb 0 0.5 0.3 / 0.4)"
     304PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r 0 b / alpha)") is "color(srgb 0.7 0 0.3 / 0.4)"
     305PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g 0 / alpha)") is "color(srgb 0.7 0.5 0 / 0.4)"
     306PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / 0)") is "color(srgb 0.7 0.5 0.3 / 0)"
     307PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb 0.2 g b / alpha)") is "color(srgb 0.2 0.5 0.3)"
     308PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb 20% g b / alpha)") is "color(srgb 0.2 0.5 0.3)"
     309PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb r 0.2 b / alpha)") is "color(srgb 0.7 0.2 0.3)"
     310PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb r 20% b / alpha)") is "color(srgb 0.7 0.2 0.3)"
     311PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb r g 0.2 / alpha)") is "color(srgb 0.7 0.5 0.2)"
     312PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb r g 20% / alpha)") is "color(srgb 0.7 0.5 0.2)"
     313PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb r g b / 0.2)") is "color(srgb 0.7 0.5 0.3 / 0.2)"
     314PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb r g b / 20%)") is "color(srgb 0.7 0.5 0.3 / 0.2)"
     315PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb 0.2 g b / alpha)") is "color(srgb 0.2 0.5 0.3 / 0.4)"
     316PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb 20% g b / alpha)") is "color(srgb 0.2 0.5 0.3 / 0.4)"
     317PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r 0.2 b / alpha)") is "color(srgb 0.7 0.2 0.3 / 0.4)"
     318PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r 20% b / alpha)") is "color(srgb 0.7 0.2 0.3 / 0.4)"
     319PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g 0.2 / alpha)") is "color(srgb 0.7 0.5 0.2 / 0.4)"
     320PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g 20% / alpha)") is "color(srgb 0.7 0.5 0.2 / 0.4)"
     321PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / 0.2)") is "color(srgb 0.7 0.5 0.3 / 0.2)"
     322PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / 20%)") is "color(srgb 0.7 0.5 0.3 / 0.2)"
     323PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb g b r)") is "color(srgb 0.5 0.3 0.7)"
     324PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb b alpha r / g)") is "color(srgb 0.3 1 0.7 / 0.5)"
     325PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb r r r / r)") is "color(srgb 0.7 0.7 0.7 / 0.7)"
     326PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb alpha alpha alpha / alpha)") is "color(srgb 1 1 1)"
     327PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb g b r)") is "color(srgb 0.5 0.3 0.7)"
     328PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb b alpha r / g)") is "color(srgb 0.3 0.4 0.7 / 0.5)"
     329PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r r r / r)") is "color(srgb 0.7 0.7 0.7 / 0.7)"
     330PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb alpha alpha alpha / alpha)") is "color(srgb 0.4 0.4 0.4 / 0.4)"
     331PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb calc(r) calc(g) calc(b))") is "color(srgb 0.7 0.5 0.3)"
     332PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb calc(r) calc(g) calc(b) / calc(alpha))") is "color(srgb 0.7 0.5 0.3 / 0.4)"
     333PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb 10deg g b)") is "rgba(0, 0, 0, 0)"
     334PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb r 10deg b)") is "rgba(0, 0, 0, 0)"
     335PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb r g 10deg)") is "rgba(0, 0, 0, 0)"
     336PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb r g b / 10deg)") is "rgba(0, 0, 0, 0)"
     337PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb red g b)") is "rgba(0, 0, 0, 0)"
     338PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb x g b)") is "rgba(0, 0, 0, 0)"
     339PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb l g b)") is "rgba(0, 0, 0, 0)"
     340
     341color(from ... ${color} ...)
     342PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b)") is "color(a98-rgb 0.7 0.5 0.3)"
     343PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / alpha)") is "color(a98-rgb 0.7 0.5 0.3)"
     344PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b)") is "color(a98-rgb 0.7 0.5 0.3)"
     345PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / alpha)") is "color(a98-rgb 0.7 0.5 0.3 / 0.4)"
     346PASS computedStyle("background-color", "color(from color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b) a98-rgb r g b)") is "color(a98-rgb 0.7 0.5 0.3)"
     347PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0 0 0)") is "color(a98-rgb 0 0 0)"
     348PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0 0 0)") is "color(a98-rgb 0 0 0)"
     349PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0 0 0 / 0)") is "color(a98-rgb 0 0 0 / 0)"
     350PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0 0 0 / 0)") is "color(a98-rgb 0 0 0 / 0)"
     351PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0 g b / alpha)") is "color(a98-rgb 0 0.5 0.3)"
     352PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r 0 b / alpha)") is "color(a98-rgb 0.7 0 0.3)"
     353PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g 0 / alpha)") is "color(a98-rgb 0.7 0.5 0)"
     354PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / 0)") is "color(a98-rgb 0.7 0.5 0.3 / 0)"
     355PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb 0 g b / alpha)") is "color(a98-rgb 0 0.5 0.3 / 0.4)"
     356PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r 0 b / alpha)") is "color(a98-rgb 0.7 0 0.3 / 0.4)"
     357PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g 0 / alpha)") is "color(a98-rgb 0.7 0.5 0 / 0.4)"
     358PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / 0)") is "color(a98-rgb 0.7 0.5 0.3 / 0)"
     359PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0.2 g b / alpha)") is "color(a98-rgb 0.2 0.5 0.3)"
     360PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 20% g b / alpha)") is "color(a98-rgb 0.2 0.5 0.3)"
     361PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r 0.2 b / alpha)") is "color(a98-rgb 0.7 0.2 0.3)"
     362PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r 20% b / alpha)") is "color(a98-rgb 0.7 0.2 0.3)"
     363PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g 0.2 / alpha)") is "color(a98-rgb 0.7 0.5 0.2)"
     364PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g 20% / alpha)") is "color(a98-rgb 0.7 0.5 0.2)"
     365PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / 0.2)") is "color(a98-rgb 0.7 0.5 0.3 / 0.2)"
     366PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / 20%)") is "color(a98-rgb 0.7 0.5 0.3 / 0.2)"
     367PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb 0.2 g b / alpha)") is "color(a98-rgb 0.2 0.5 0.3 / 0.4)"
     368PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb 20% g b / alpha)") is "color(a98-rgb 0.2 0.5 0.3 / 0.4)"
     369PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r 0.2 b / alpha)") is "color(a98-rgb 0.7 0.2 0.3 / 0.4)"
     370PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r 20% b / alpha)") is "color(a98-rgb 0.7 0.2 0.3 / 0.4)"
     371PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g 0.2 / alpha)") is "color(a98-rgb 0.7 0.5 0.2 / 0.4)"
     372PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g 20% / alpha)") is "color(a98-rgb 0.7 0.5 0.2 / 0.4)"
     373PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / 0.2)") is "color(a98-rgb 0.7 0.5 0.3 / 0.2)"
     374PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / 20%)") is "color(a98-rgb 0.7 0.5 0.3 / 0.2)"
     375PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb g b r)") is "color(a98-rgb 0.5 0.3 0.7)"
     376PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb b alpha r / g)") is "color(a98-rgb 0.3 1 0.7 / 0.5)"
     377PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r r r / r)") is "color(a98-rgb 0.7 0.7 0.7 / 0.7)"
     378PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb alpha alpha alpha / alpha)") is "color(a98-rgb 1 1 1)"
     379PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb g b r)") is "color(a98-rgb 0.5 0.3 0.7)"
     380PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb b alpha r / g)") is "color(a98-rgb 0.3 0.4 0.7 / 0.5)"
     381PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r r r / r)") is "color(a98-rgb 0.7 0.7 0.7 / 0.7)"
     382PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb alpha alpha alpha / alpha)") is "color(a98-rgb 0.4 0.4 0.4 / 0.4)"
     383PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb calc(r) calc(g) calc(b))") is "color(a98-rgb 0.7 0.5 0.3)"
     384PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb calc(r) calc(g) calc(b) / calc(alpha))") is "color(a98-rgb 0.7 0.5 0.3 / 0.4)"
     385PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 10deg g b)") is "rgba(0, 0, 0, 0)"
     386PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r 10deg b)") is "rgba(0, 0, 0, 0)"
     387PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g 10deg)") is "rgba(0, 0, 0, 0)"
     388PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / 10deg)") is "rgba(0, 0, 0, 0)"
     389PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb red g b)") is "rgba(0, 0, 0, 0)"
     390PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb x g b)") is "rgba(0, 0, 0, 0)"
     391PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb l g b)") is "rgba(0, 0, 0, 0)"
     392
     393color(from ... ${color} ...)
     394PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b)") is "color(rec2020 0.7 0.5 0.3)"
     395PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / alpha)") is "color(rec2020 0.7 0.5 0.3)"
     396PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b)") is "color(rec2020 0.7 0.5 0.3)"
     397PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / alpha)") is "color(rec2020 0.7 0.5 0.3 / 0.4)"
     398PASS computedStyle("background-color", "color(from color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b) rec2020 r g b)") is "color(rec2020 0.7 0.5 0.3)"
     399PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 0 0 0)") is "color(rec2020 0 0 0)"
     400PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 0 0 0)") is "color(rec2020 0 0 0)"
     401PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 0 0 0 / 0)") is "color(rec2020 0 0 0 / 0)"
     402PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 0 0 0 / 0)") is "color(rec2020 0 0 0 / 0)"
     403PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 0 g b / alpha)") is "color(rec2020 0 0.5 0.3)"
     404PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 r 0 b / alpha)") is "color(rec2020 0.7 0 0.3)"
     405PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g 0 / alpha)") is "color(rec2020 0.7 0.5 0)"
     406PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / 0)") is "color(rec2020 0.7 0.5 0.3 / 0)"
     407PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 0 g b / alpha)") is "color(rec2020 0 0.5 0.3 / 0.4)"
     408PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r 0 b / alpha)") is "color(rec2020 0.7 0 0.3 / 0.4)"
     409PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g 0 / alpha)") is "color(rec2020 0.7 0.5 0 / 0.4)"
     410PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / 0)") is "color(rec2020 0.7 0.5 0.3 / 0)"
     411PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 0.2 g b / alpha)") is "color(rec2020 0.2 0.5 0.3)"
     412PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 20% g b / alpha)") is "color(rec2020 0.2 0.5 0.3)"
     413PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 r 0.2 b / alpha)") is "color(rec2020 0.7 0.2 0.3)"
     414PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 r 20% b / alpha)") is "color(rec2020 0.7 0.2 0.3)"
     415PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g 0.2 / alpha)") is "color(rec2020 0.7 0.5 0.2)"
     416PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g 20% / alpha)") is "color(rec2020 0.7 0.5 0.2)"
     417PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / 0.2)") is "color(rec2020 0.7 0.5 0.3 / 0.2)"
     418PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / 20%)") is "color(rec2020 0.7 0.5 0.3 / 0.2)"
     419PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 0.2 g b / alpha)") is "color(rec2020 0.2 0.5 0.3 / 0.4)"
     420PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 20% g b / alpha)") is "color(rec2020 0.2 0.5 0.3 / 0.4)"
     421PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r 0.2 b / alpha)") is "color(rec2020 0.7 0.2 0.3 / 0.4)"
     422PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r 20% b / alpha)") is "color(rec2020 0.7 0.2 0.3 / 0.4)"
     423PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g 0.2 / alpha)") is "color(rec2020 0.7 0.5 0.2 / 0.4)"
     424PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g 20% / alpha)") is "color(rec2020 0.7 0.5 0.2 / 0.4)"
     425PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / 0.2)") is "color(rec2020 0.7 0.5 0.3 / 0.2)"
     426PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / 20%)") is "color(rec2020 0.7 0.5 0.3 / 0.2)"
     427PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 g b r)") is "color(rec2020 0.5 0.3 0.7)"
     428PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 b alpha r / g)") is "color(rec2020 0.3 1 0.7 / 0.5)"
     429PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 r r r / r)") is "color(rec2020 0.7 0.7 0.7 / 0.7)"
     430PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 alpha alpha alpha / alpha)") is "color(rec2020 1 1 1)"
     431PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 g b r)") is "color(rec2020 0.5 0.3 0.7)"
     432PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 b alpha r / g)") is "color(rec2020 0.3 0.4 0.7 / 0.5)"
     433PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r r r / r)") is "color(rec2020 0.7 0.7 0.7 / 0.7)"
     434PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 alpha alpha alpha / alpha)") is "color(rec2020 0.4 0.4 0.4 / 0.4)"
     435PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 calc(r) calc(g) calc(b))") is "color(rec2020 0.7 0.5 0.3)"
     436PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 calc(r) calc(g) calc(b) / calc(alpha))") is "color(rec2020 0.7 0.5 0.3 / 0.4)"
     437PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 10deg g b)") is "rgba(0, 0, 0, 0)"
     438PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 r 10deg b)") is "rgba(0, 0, 0, 0)"
     439PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g 10deg)") is "rgba(0, 0, 0, 0)"
     440PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / 10deg)") is "rgba(0, 0, 0, 0)"
     441PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 red g b)") is "rgba(0, 0, 0, 0)"
     442PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 x g b)") is "rgba(0, 0, 0, 0)"
     443PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 l g b)") is "rgba(0, 0, 0, 0)"
     444
     445color(from ... ${color} ...)
     446PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b)") is "color(prophoto-rgb 0.7 0.5 0.3)"
     447PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / alpha)") is "color(prophoto-rgb 0.7 0.5 0.3)"
     448PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b)") is "color(prophoto-rgb 0.7 0.5 0.3)"
     449PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / alpha)") is "color(prophoto-rgb 0.7 0.5 0.3 / 0.4)"
     450PASS computedStyle("background-color", "color(from color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b) prophoto-rgb r g b)") is "color(prophoto-rgb 0.7 0.5 0.3)"
     451PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0 0 0)") is "color(prophoto-rgb 0 0 0)"
     452PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0 0 0)") is "color(prophoto-rgb 0 0 0)"
     453PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0 0 0 / 0)") is "color(prophoto-rgb 0 0 0 / 0)"
     454PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0 0 0 / 0)") is "color(prophoto-rgb 0 0 0 / 0)"
     455PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0 g b / alpha)") is "color(prophoto-rgb 0 0.5 0.3)"
     456PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r 0 b / alpha)") is "color(prophoto-rgb 0.7 0 0.3)"
     457PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g 0 / alpha)") is "color(prophoto-rgb 0.7 0.5 0)"
     458PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / 0)") is "color(prophoto-rgb 0.7 0.5 0.3 / 0)"
     459PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb 0 g b / alpha)") is "color(prophoto-rgb 0 0.5 0.3 / 0.4)"
     460PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r 0 b / alpha)") is "color(prophoto-rgb 0.7 0 0.3 / 0.4)"
     461PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g 0 / alpha)") is "color(prophoto-rgb 0.7 0.5 0 / 0.4)"
     462PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / 0)") is "color(prophoto-rgb 0.7 0.5 0.3 / 0)"
     463PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0.2 g b / alpha)") is "color(prophoto-rgb 0.2 0.5 0.3)"
     464PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 20% g b / alpha)") is "color(prophoto-rgb 0.2 0.5 0.3)"
     465PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r 0.2 b / alpha)") is "color(prophoto-rgb 0.7 0.2 0.3)"
     466PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r 20% b / alpha)") is "color(prophoto-rgb 0.7 0.2 0.3)"
     467PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g 0.2 / alpha)") is "color(prophoto-rgb 0.7 0.5 0.2)"
     468PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g 20% / alpha)") is "color(prophoto-rgb 0.7 0.5 0.2)"
     469PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / 0.2)") is "color(prophoto-rgb 0.7 0.5 0.3 / 0.2)"
     470PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / 20%)") is "color(prophoto-rgb 0.7 0.5 0.3 / 0.2)"
     471PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb 0.2 g b / alpha)") is "color(prophoto-rgb 0.2 0.5 0.3 / 0.4)"
     472PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb 20% g b / alpha)") is "color(prophoto-rgb 0.2 0.5 0.3 / 0.4)"
     473PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r 0.2 b / alpha)") is "color(prophoto-rgb 0.7 0.2 0.3 / 0.4)"
     474PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r 20% b / alpha)") is "color(prophoto-rgb 0.7 0.2 0.3 / 0.4)"
     475PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g 0.2 / alpha)") is "color(prophoto-rgb 0.7 0.5 0.2 / 0.4)"
     476PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g 20% / alpha)") is "color(prophoto-rgb 0.7 0.5 0.2 / 0.4)"
     477PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / 0.2)") is "color(prophoto-rgb 0.7 0.5 0.3 / 0.2)"
     478PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / 20%)") is "color(prophoto-rgb 0.7 0.5 0.3 / 0.2)"
     479PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb g b r)") is "color(prophoto-rgb 0.5 0.3 0.7)"
     480PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb b alpha r / g)") is "color(prophoto-rgb 0.3 1 0.7 / 0.5)"
     481PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r r r / r)") is "color(prophoto-rgb 0.7 0.7 0.7 / 0.7)"
     482PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb alpha alpha alpha / alpha)") is "color(prophoto-rgb 1 1 1)"
     483PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb g b r)") is "color(prophoto-rgb 0.5 0.3 0.7)"
     484PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb b alpha r / g)") is "color(prophoto-rgb 0.3 0.4 0.7 / 0.5)"
     485PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r r r / r)") is "color(prophoto-rgb 0.7 0.7 0.7 / 0.7)"
     486PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb alpha alpha alpha / alpha)") is "color(prophoto-rgb 0.4 0.4 0.4 / 0.4)"
     487PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb calc(r) calc(g) calc(b))") is "color(prophoto-rgb 0.7 0.5 0.3)"
     488PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb calc(r) calc(g) calc(b) / calc(alpha))") is "color(prophoto-rgb 0.7 0.5 0.3 / 0.4)"
     489PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 10deg g b)") is "rgba(0, 0, 0, 0)"
     490PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r 10deg b)") is "rgba(0, 0, 0, 0)"
     491PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g 10deg)") is "rgba(0, 0, 0, 0)"
     492PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / 10deg)") is "rgba(0, 0, 0, 0)"
     493PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb red g b)") is "rgba(0, 0, 0, 0)"
     494PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb x g b)") is "rgba(0, 0, 0, 0)"
     495PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb l g b)") is "rgba(0, 0, 0, 0)"
     496
     497color(from ... xyz ...)
     498PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz x y z)") is "color(xyz 7 -20.5 100)"
     499PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz x y z / alpha)") is "color(xyz 7 -20.5 100)"
     500PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100 / 40%) xyz x y z)") is "color(xyz 7 -20.5 100)"
     501PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / alpha)") is "color(xyz 7 -20.5 100 / 0.4)"
     502PASS computedStyle("background-color", "color(from color(from color(xyz 7 -20.5 100) xyz x y z) xyz x y z)") is "color(xyz 7 -20.5 100)"
     503PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz 0 0 0)") is "color(xyz 0 0 0)"
     504PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz 0 0 0)") is "color(xyz 0 0 0)"
     505PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz 0 0 0 / 0)") is "color(xyz 0 0 0 / 0)"
     506PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz 0 0 0 / 0)") is "color(xyz 0 0 0 / 0)"
     507PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz 0 y z / alpha)") is "color(xyz 0 -20.5 100)"
     508PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz x 0 z / alpha)") is "color(xyz 7 0 100)"
     509PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz x y 0 / alpha)") is "color(xyz 7 -20.5 0)"
     510PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz x y z / 0)") is "color(xyz 7 -20.5 100 / 0)"
     511PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100 / 40%) xyz 0 y z / alpha)") is "color(xyz 0 -20.5 100 / 0.4)"
     512PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100 / 40%) xyz x 0 z / alpha)") is "color(xyz 7 0 100 / 0.4)"
     513PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100 / 40%) xyz x y 0 / alpha)") is "color(xyz 7 -20.5 0 / 0.4)"
     514PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / 0)") is "color(xyz 7 -20.5 100 / 0)"
     515PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz 0.2 y z / alpha)") is "color(xyz 0.2 -20.5 100)"
     516PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz x 0.2 z / alpha)") is "color(xyz 7 0.2 100)"
     517PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz x y 0.2 / alpha)") is "color(xyz 7 -20.5 0.2)"
     518PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz x y z / 0.2)") is "color(xyz 7 -20.5 100 / 0.2)"
     519PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz x y z / 20%)") is "color(xyz 7 -20.5 100 / 0.2)"
     520PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100 / 40%) xyz 0.2 y z / alpha)") is "color(xyz 0.2 -20.5 100 / 0.4)"
     521PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100 / 40%) xyz x 0.2 z / alpha)") is "color(xyz 7 0.2 100 / 0.4)"
     522PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100 / 40%) xyz x y 0.2 / alpha)") is "color(xyz 7 -20.5 0.2 / 0.4)"
     523PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / 0.2)") is "color(xyz 7 -20.5 100 / 0.2)"
     524PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz y z x)") is "color(xyz -20.5 100 7)"
     525PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz x x x / x)") is "color(xyz 7 7 7)"
     526PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100 / 40%) xyz y z x)") is "color(xyz -20.5 100 7)"
     527PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100 / 40%) xyz x x x / x)") is "color(xyz 7 7 7)"
     528PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz z alpha x / y)") is "rgba(0, 0, 0, 0)"
     529PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz alpha alpha alpha / alpha)") is "rgba(0, 0, 0, 0)"
     530PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100 / 40%) xyz z alpha x / y)") is "rgba(0, 0, 0, 0)"
     531PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100 / 40%) xyz alpha alpha alpha / alpha)") is "rgba(0, 0, 0, 0)"
     532PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz calc(x) calc(y) calc(z))") is "color(xyz 7 -20.5 100)"
     533PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100 / 40%) xyz calc(x) calc(y) calc(z) / calc(alpha))") is "color(xyz 7 -20.5 100 / 0.4)"
     534PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz 10deg y z)") is "rgba(0, 0, 0, 0)"
     535PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz x 10deg z)") is "rgba(0, 0, 0, 0)"
     536PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz x y 10deg)") is "rgba(0, 0, 0, 0)"
     537PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz x y z / 10deg)") is "rgba(0, 0, 0, 0)"
     538PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz red y)") is "rgba(0, 0, 0, 0)"
     539PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz r y z)") is "rgba(0, 0, 0, 0)"
     540PASS computedStyle("background-color", "color(from color(xyz 7 -20.5 100) xyz l y z)") is "rgba(0, 0, 0, 0)"
     541
     542Spec Examples
    288543PASS computedStyle("background-color", "rgb(from var(--bg-color) r g b / 80%)") is "rgba(0, 0, 255, 0.8)"
    289544PASS computedStyle("background-color", "lch(from var(--color) calc(l / 2) c h)") is "lch(23.138971% 67.989716 134.39125)"
  • trunk/LayoutTests/fast/css/parsing-relative-color-syntax.html

    r278304 r278364  
    445445
    446446
    447     // Spec examples:
     447    for (const color of [ "srgb", "a98-rgb", "rec2020", "prophoto-rgb" ]) {
     448        debug('');
     449        debug('color(from ... ${color} ...)');
     450
     451        // Testing no modifications.
     452        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r g b)`,                              `color(${color} 0.7 0.5 0.3)`);
     453        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r g b / alpha)`,                      `color(${color} 0.7 0.5 0.3)`);
     454        testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} r g b)`,                        `color(${color} 0.7 0.5 0.3)`);
     455        testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} r g b / alpha)`,                `color(${color} 0.7 0.5 0.3 / 0.4)`);
     456
     457        // Test nesting relative colors.
     458        testComputed(`color(from color(from color(${color} 0.7 0.5 0.3) ${color} r g b) ${color} r g b)`,   `color(${color} 0.7 0.5 0.3)`);
     459
     460        // Testing replacement with 0.
     461        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} 0 0 0)`,                              `color(${color} 0 0 0)`);
     462        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} 0 0 0)`,                              `color(${color} 0 0 0)`);
     463        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} 0 0 0 / 0)`,                          `color(${color} 0 0 0 / 0)`);
     464        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} 0 0 0 / 0)`,                          `color(${color} 0 0 0 / 0)`);
     465        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} 0 g b / alpha)`,                      `color(${color} 0 0.5 0.3)`);
     466        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r 0 b / alpha)`,                      `color(${color} 0.7 0 0.3)`);
     467        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r g 0 / alpha)`,                      `color(${color} 0.7 0.5 0)`);
     468        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r g b / 0)`,                          `color(${color} 0.7 0.5 0.3 / 0)`);
     469        testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} 0 g b / alpha)`,                `color(${color} 0 0.5 0.3 / 0.4)`);
     470        testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} r 0 b / alpha)`,                `color(${color} 0.7 0 0.3 / 0.4)`);
     471        testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} r g 0 / alpha)`,                `color(${color} 0.7 0.5 0 / 0.4)`);
     472        testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} r g b / 0)`,                    `color(${color} 0.7 0.5 0.3 / 0)`);
     473
     474        // Testing replacement with a constant.
     475        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} 0.2 g b / alpha)`,                    `color(${color} 0.2 0.5 0.3)`);
     476        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} 20% g b / alpha)`,                    `color(${color} 0.2 0.5 0.3)`);
     477        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r 0.2 b / alpha)`,                    `color(${color} 0.7 0.2 0.3)`);
     478        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r 20% b / alpha)`,                    `color(${color} 0.7 0.2 0.3)`);
     479        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r g 0.2 / alpha)`,                    `color(${color} 0.7 0.5 0.2)`);
     480        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r g 20% / alpha)`,                    `color(${color} 0.7 0.5 0.2)`);
     481        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r g b / 0.2)`,                        `color(${color} 0.7 0.5 0.3 / 0.2)`);
     482        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r g b / 20%)`,                        `color(${color} 0.7 0.5 0.3 / 0.2)`);
     483        testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} 0.2 g b / alpha)`,              `color(${color} 0.2 0.5 0.3 / 0.4)`);
     484        testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} 20% g b / alpha)`,              `color(${color} 0.2 0.5 0.3 / 0.4)`);
     485        testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} r 0.2 b / alpha)`,              `color(${color} 0.7 0.2 0.3 / 0.4)`);
     486        testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} r 20% b / alpha)`,              `color(${color} 0.7 0.2 0.3 / 0.4)`);
     487        testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} r g 0.2 / alpha)`,              `color(${color} 0.7 0.5 0.2 / 0.4)`);
     488        testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} r g 20% / alpha)`,              `color(${color} 0.7 0.5 0.2 / 0.4)`);
     489        testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} r g b / 0.2)`,                  `color(${color} 0.7 0.5 0.3 / 0.2)`);
     490        testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} r g b / 20%)`,                  `color(${color} 0.7 0.5 0.3 / 0.2)`);
     491
     492        // Testing valid permutation (types match).
     493        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} g b r)`,                              `color(${color} 0.5 0.3 0.7)`);
     494        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} b alpha r / g)`,                      `color(${color} 0.3 1 0.7 / 0.5)`);
     495        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r r r / r)`,                          `color(${color} 0.7 0.7 0.7 / 0.7)`);
     496        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} alpha alpha alpha / alpha)`,          `color(${color} 1 1 1)`);
     497        testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} g b r)`,                        `color(${color} 0.5 0.3 0.7)`);
     498        testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} b alpha r / g)`,                `color(${color} 0.3 0.4 0.7 / 0.5)`);
     499        testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} r r r / r)`,                    `color(${color} 0.7 0.7 0.7 / 0.7)`);
     500        testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} alpha alpha alpha / alpha)`,    `color(${color} 0.4 0.4 0.4 / 0.4)`);
     501
     502        // Testing with calc().
     503        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} calc(r) calc(g) calc(b))`,                        `color(${color} 0.7 0.5 0.3)`);
     504        testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} calc(r) calc(g) calc(b) / calc(alpha))`,    `color(${color} 0.7 0.5 0.3 / 0.4)`);
     505
     506        // Testing invalid values.
     507        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} 10deg g b)`,                          `rgba(0, 0, 0, 0)`);
     508        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r 10deg b)`,                          `rgba(0, 0, 0, 0)`);
     509        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r g 10deg)`,                          `rgba(0, 0, 0, 0)`);
     510        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r g b / 10deg)`,                      `rgba(0, 0, 0, 0)`);
     511
     512        // Testing invalid component names
     513        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} red g b)`,                            `rgba(0, 0, 0, 0)`);
     514        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} x g b)`,                              `rgba(0, 0, 0, 0)`);
     515        testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} l g b)`,                              `rgba(0, 0, 0, 0)`);
     516    }
     517
     518    debug('');
     519    debug('color(from ... xyz ...)');
     520
     521    // Testing no modifications.
     522    testComputed(`color(from color(xyz 7 -20.5 100) xyz x y z)`,                              `color(xyz 7 -20.5 100)`);
     523    testComputed(`color(from color(xyz 7 -20.5 100) xyz x y z / alpha)`,                      `color(xyz 7 -20.5 100)`);
     524    testComputed(`color(from color(xyz 7 -20.5 100 / 40%) xyz x y z)`,                        `color(xyz 7 -20.5 100)`);
     525    testComputed(`color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / alpha)`,                `color(xyz 7 -20.5 100 / 0.4)`);
     526
     527    // Test nesting relative colors.
     528    testComputed(`color(from color(from color(xyz 7 -20.5 100) xyz x y z) xyz x y z)`,        `color(xyz 7 -20.5 100)`);
     529
     530    // Testing replacement with 0.
     531    testComputed(`color(from color(xyz 7 -20.5 100) xyz 0 0 0)`,                              `color(xyz 0 0 0)`);
     532    testComputed(`color(from color(xyz 7 -20.5 100) xyz 0 0 0)`,                              `color(xyz 0 0 0)`);
     533    testComputed(`color(from color(xyz 7 -20.5 100) xyz 0 0 0 / 0)`,                          `color(xyz 0 0 0 / 0)`);
     534    testComputed(`color(from color(xyz 7 -20.5 100) xyz 0 0 0 / 0)`,                          `color(xyz 0 0 0 / 0)`);
     535    testComputed(`color(from color(xyz 7 -20.5 100) xyz 0 y z / alpha)`,                      `color(xyz 0 -20.5 100)`);
     536    testComputed(`color(from color(xyz 7 -20.5 100) xyz x 0 z / alpha)`,                      `color(xyz 7 0 100)`);
     537    testComputed(`color(from color(xyz 7 -20.5 100) xyz x y 0 / alpha)`,                      `color(xyz 7 -20.5 0)`);
     538    testComputed(`color(from color(xyz 7 -20.5 100) xyz x y z / 0)`,                          `color(xyz 7 -20.5 100 / 0)`);
     539    testComputed(`color(from color(xyz 7 -20.5 100 / 40%) xyz 0 y z / alpha)`,                `color(xyz 0 -20.5 100 / 0.4)`);
     540    testComputed(`color(from color(xyz 7 -20.5 100 / 40%) xyz x 0 z / alpha)`,                `color(xyz 7 0 100 / 0.4)`);
     541    testComputed(`color(from color(xyz 7 -20.5 100 / 40%) xyz x y 0 / alpha)`,                `color(xyz 7 -20.5 0 / 0.4)`);
     542    testComputed(`color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / 0)`,                    `color(xyz 7 -20.5 100 / 0)`);
     543
     544    // Testing replacement with a constant.
     545    testComputed(`color(from color(xyz 7 -20.5 100) xyz 0.2 y z / alpha)`,                    `color(xyz 0.2 -20.5 100)`);
     546    testComputed(`color(from color(xyz 7 -20.5 100) xyz x 0.2 z / alpha)`,                    `color(xyz 7 0.2 100)`);
     547    testComputed(`color(from color(xyz 7 -20.5 100) xyz x y 0.2 / alpha)`,                    `color(xyz 7 -20.5 0.2)`);
     548    testComputed(`color(from color(xyz 7 -20.5 100) xyz x y z / 0.2)`,                        `color(xyz 7 -20.5 100 / 0.2)`);
     549    testComputed(`color(from color(xyz 7 -20.5 100) xyz x y z / 20%)`,                        `color(xyz 7 -20.5 100 / 0.2)`);
     550    testComputed(`color(from color(xyz 7 -20.5 100 / 40%) xyz 0.2 y z / alpha)`,              `color(xyz 0.2 -20.5 100 / 0.4)`);
     551    testComputed(`color(from color(xyz 7 -20.5 100 / 40%) xyz x 0.2 z / alpha)`,              `color(xyz 7 0.2 100 / 0.4)`);
     552    testComputed(`color(from color(xyz 7 -20.5 100 / 40%) xyz x y 0.2 / alpha)`,              `color(xyz 7 -20.5 0.2 / 0.4)`);
     553    testComputed(`color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / 0.2)`,                  `color(xyz 7 -20.5 100 / 0.2)`);
     554
     555    // Testing valid permutation (types match).
     556    testComputed(`color(from color(xyz 7 -20.5 100) xyz y z x)`,                              `color(xyz -20.5 100 7)`);
     557    testComputed(`color(from color(xyz 7 -20.5 100) xyz x x x / x)`,                          `color(xyz 7 7 7)`);
     558    testComputed(`color(from color(xyz 7 -20.5 100 / 40%) xyz y z x)`,                        `color(xyz -20.5 100 7)`);
     559    testComputed(`color(from color(xyz 7 -20.5 100 / 40%) xyz x x x / x)`,                    `color(xyz 7 7 7)`);
     560
     561    // Testing invalid permutation (types don't match).
     562    testComputed(`color(from color(xyz 7 -20.5 100) xyz z alpha x / y)`,                      `rgba(0, 0, 0, 0)`);
     563    testComputed(`color(from color(xyz 7 -20.5 100) xyz alpha alpha alpha / alpha)`,          `rgba(0, 0, 0, 0)`);
     564    testComputed(`color(from color(xyz 7 -20.5 100 / 40%) xyz z alpha x / y)`,                `rgba(0, 0, 0, 0)`);
     565    testComputed(`color(from color(xyz 7 -20.5 100 / 40%) xyz alpha alpha alpha / alpha)`,    `rgba(0, 0, 0, 0)`);
     566
     567    // Testing with calc().
     568    testComputed(`color(from color(xyz 7 -20.5 100) xyz calc(x) calc(y) calc(z))`,                        `color(xyz 7 -20.5 100)`);
     569    testComputed(`color(from color(xyz 7 -20.5 100 / 40%) xyz calc(x) calc(y) calc(z) / calc(alpha))`,    `color(xyz 7 -20.5 100 / 0.4)`);
     570
     571    // Testing invalid values.
     572    testComputed(`color(from color(xyz 7 -20.5 100) xyz 10deg y z)`,                          `rgba(0, 0, 0, 0)`);
     573    testComputed(`color(from color(xyz 7 -20.5 100) xyz x 10deg z)`,                          `rgba(0, 0, 0, 0)`);
     574    testComputed(`color(from color(xyz 7 -20.5 100) xyz x y 10deg)`,                          `rgba(0, 0, 0, 0)`);
     575    testComputed(`color(from color(xyz 7 -20.5 100) xyz x y z / 10deg)`,                      `rgba(0, 0, 0, 0)`);
     576
     577    // Testing invalid component names
     578    testComputed(`color(from color(xyz 7 -20.5 100) xyz red y)`,                              `rgba(0, 0, 0, 0)`);
     579    testComputed(`color(from color(xyz 7 -20.5 100) xyz r y z)`,                              `rgba(0, 0, 0, 0)`);
     580    testComputed(`color(from color(xyz 7 -20.5 100) xyz l y z)`,                              `rgba(0, 0, 0, 0)`);
     581
     582
     583    debug('');
     584    debug('Spec Examples');
     585
    448586    // Example 11.
    449587    testComputed(`rgb(from var(--bg-color) r g b / 80%)`, `rgba(0, 0, 255, 0.8)`);
    450    
     588
    451589    // Example 12.
    452590    testComputed(`lch(from var(--color) calc(l / 2) c h)`, `lch(23.138971% 67.989716 134.39125)`);
    453    
     591
    454592    // Example 13.
    455593    testComputed(`rgb(from var(--color) calc(r * .3 + g * .59 + b * .11) calc(r * .3 + g * .59 + b * .11) calc(r * .3 + g * .59 + b * .11))`, `rgb(76, 76, 76)`)
     
    466604    testComputed(`lab(from var(--mycolor) l a b / calc(alpha * 0.8))`, `lab(62.751923% 52.45802 -34.117283 / 0.8)`);
    467605    testComputed(`lab(from var(--mycolor) l a b / calc(alpha - 20%))`, `lab(62.751923% 52.45802 -34.117283 / 0.8)`);
    468    
     606
    469607    // Example 17.
    470608    testComputed(`lab(from var(--mycolor) l 0 0)`, `lab(62.751923% 0 0)`);
  • trunk/Source/WebCore/ChangeLog

    r278359 r278364  
     12021-06-02  Sam Weinig  <weinig@apple.com>
     2
     3        Add support for "relative color syntax" for color()
     4        https://bugs.webkit.org/show_bug.cgi?id=226513
     5
     6        Reviewed by Darin Adler.
     7
     8        CSS Color 5 has recently been update to support relative color syntax for
     9        the color() function in addition to the existing rgb(), hsl(), hwb(), lab()
     10        and lch().
     11
     12        Took the opertunity to refactor other relative color syntax parsing to share
     13        more code between relative and non-relative parsers using a shared function
     14        with lambdas to differentiate the component consumers. This was done for all
     15        the color types except rgb() and hsl(), which have notable differences in
     16        parsing between the relative and non-relative version.
     17
     18        * css/parser/CSSPropertyParserHelpers.cpp:
     19        (WebCore::CSSPropertyParserHelpers::parseNonRelativeRGBParameters):
     20        (WebCore::CSSPropertyParserHelpers::parseRGBParameters):
     21        (WebCore::CSSPropertyParserHelpers::colorByNormalizingHSLComponents):
     22        (WebCore::CSSPropertyParserHelpers::parseRelativeHSLParameters):
     23        (WebCore::CSSPropertyParserHelpers::parseNonRelativeHSLParameters):
     24        (WebCore::CSSPropertyParserHelpers::parseHSLParameters):
     25        (WebCore::CSSPropertyParserHelpers::parseHWBParameters):
     26        (WebCore::CSSPropertyParserHelpers::parseRelativeHWBParameters):
     27        (WebCore::CSSPropertyParserHelpers::parseNonRelativeHWBParameters):
     28        (WebCore::CSSPropertyParserHelpers::parseLabParameters):
     29        (WebCore::CSSPropertyParserHelpers::parseRelativeLabParameters):
     30        (WebCore::CSSPropertyParserHelpers::parseNonRelativeLabParameters):
     31        (WebCore::CSSPropertyParserHelpers::parseLCHParameters):
     32        (WebCore::CSSPropertyParserHelpers::parseRelativeLCHParameters):
     33        (WebCore::CSSPropertyParserHelpers::parseNonRelativeLCHParameters):
     34        (WebCore::CSSPropertyParserHelpers::parseColorFunctionForRGBTypes):
     35        (WebCore::CSSPropertyParserHelpers::parseRelativeColorFunctionForRGBTypes):
     36        (WebCore::CSSPropertyParserHelpers::parseColorFunctionForXYZParameters):
     37        (WebCore::CSSPropertyParserHelpers::parseRelativeColorFunctionForXYZParameters):
     38        (WebCore::CSSPropertyParserHelpers::parseRelativeColorFunctionParameters):
     39        (WebCore::CSSPropertyParserHelpers::parseNonRelativeColorFunctionParameters):
     40        (WebCore::CSSPropertyParserHelpers::parseColorFunctionParameters):
     41
    1422021-06-02  Youenn Fablet  <youenn@apple.com>
    243
  • trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp

    r278311 r278364  
    15001500}
    15011501
    1502 enum class RGBFunctionMode { RGB, RGBA };
    1503 
    1504 template<RGBFunctionMode Mode> static Color parseRGBParameters(CSSParserTokenRange& range, const CSSParserContext& context)
    1505 {
    1506     ASSERT(range.peek().functionId() == CSSValueRgb || range.peek().functionId() == CSSValueRgba);
    1507     auto args = consumeFunction(range);
    1508 
    1509     if constexpr (Mode == RGBFunctionMode::RGB) {
    1510         if (context.relativeColorSyntaxEnabled && args.peek().id() == CSSValueFrom)
    1511             return parseRelativeRGBParameters(args, context);
    1512     }
    1513 
     1502static Color parseNonRelativeRGBParameters(CSSParserTokenRange& args)
     1503{
    15141504    struct InitialComponent {
    15151505        double value;
     
    15701560}
    15711561
     1562enum class RGBFunctionMode { RGB, RGBA };
     1563
     1564template<RGBFunctionMode Mode> static Color parseRGBParameters(CSSParserTokenRange& range, const CSSParserContext& context)
     1565{
     1566    ASSERT(range.peek().functionId() == (Mode == RGBFunctionMode::RGB ? CSSValueRgb : CSSValueRgba));
     1567    auto args = consumeFunction(range);
     1568
     1569    if constexpr (Mode == RGBFunctionMode::RGB) {
     1570        if (context.relativeColorSyntaxEnabled && args.peek().id() == CSSValueFrom)
     1571            return parseRelativeRGBParameters(args, context);
     1572    }
     1573    return parseNonRelativeRGBParameters(args);
     1574}
     1575
     1576static Color colorByNormalizingHSLComponents(double hue, double saturation, double lightness, double alpha)
     1577{
     1578    auto normalizedHue = normalizeHue(hue);
     1579    auto normalizedSaturation = std::clamp(saturation, 0.0, 100.0);
     1580    auto normalizedLightness = std::clamp(lightness, 0.0, 100.0);
     1581    auto normalizedAlpha = std::clamp(alpha, 0.0, 1.0);
     1582
     1583    // NOTE: The explicit conversion to SRGBA<uint8_t> is intentional for performance (no extra allocation for
     1584    // the extended color) and compatability, forcing serialiazation to use the rgb()/rgba() form.
     1585    return convertColor<SRGBA<uint8_t>>(HSLA<float> { static_cast<float>(normalizedHue), static_cast<float>(normalizedSaturation), static_cast<float>(normalizedLightness), static_cast<float>(normalizedAlpha) });
     1586}
     1587
    15721588static Color parseRelativeHSLParameters(CSSParserTokenRange& args, const CSSParserContext& context)
    15731589{
     
    16071623        return { };
    16081624
    1609     auto normalizedHue = normalizeHue(*hue);
    1610     auto normalizedSaturation = std::clamp(*saturation, 0.0, 100.0);
    1611     auto normalizedLightness = std::clamp(*lightness, 0.0, 100.0);
    1612     auto normalizedAlpha = std::clamp(*alpha, 0.0, 1.0);
    1613 
    1614     return convertColor<SRGBA<uint8_t>>(HSLA<float> { static_cast<float>(normalizedHue), static_cast<float>(normalizedSaturation), static_cast<float>(normalizedLightness), static_cast<float>(normalizedAlpha) });
     1625    return colorByNormalizingHSLComponents(*hue, *saturation, *lightness, *alpha);
     1626}
     1627
     1628static Color parseNonRelativeHSLParameters(CSSParserTokenRange& args, const CSSParserContext& context)
     1629{
     1630    auto hue = consumeAngleRawOrNumberRaw(args, context.mode);
     1631    if (!hue)
     1632        return { };
     1633
     1634    auto syntax = consumeCommaIncludingWhitespace(args) ? RGBOrHSLSeparatorSyntax::Commas : RGBOrHSLSeparatorSyntax::WhitespaceSlash;
     1635
     1636    auto saturation = consumePercentRaw(args);
     1637    if (!saturation)
     1638        return { };
     1639
     1640    if (!consumeRGBOrHSLSeparator(args, syntax))
     1641        return { };
     1642
     1643    auto lightness = consumePercentRaw(args);
     1644    if (!lightness)
     1645        return { };
     1646
     1647    auto alpha = consumeRGBOrHSLOptionalAlpha(args, syntax);
     1648    if (!alpha)
     1649        return { };
     1650
     1651    if (!args.atEnd())
     1652        return { };
     1653
     1654    return colorByNormalizingHSLComponents(*hue, *saturation, *lightness, *alpha);
    16151655}
    16161656
     
    16191659template<HSLFunctionMode Mode> static Color parseHSLParameters(CSSParserTokenRange& range, const CSSParserContext& context)
    16201660{
    1621     ASSERT(range.peek().functionId() == CSSValueHsl || range.peek().functionId() == CSSValueHsla);
     1661    ASSERT(range.peek().functionId() == (Mode == HSLFunctionMode::HSL ? CSSValueHsl : CSSValueHsla));
    16221662    auto args = consumeFunction(range);
    16231663
     
    16271667    }
    16281668
    1629     auto hue = consumeAngleRawOrNumberRaw(args, context.mode);
    1630     if (!hue)
    1631         return { };
    1632 
    1633     auto syntax = consumeCommaIncludingWhitespace(args) ? RGBOrHSLSeparatorSyntax::Commas : RGBOrHSLSeparatorSyntax::WhitespaceSlash;
    1634 
    1635     auto saturation = consumePercentRaw(args);
    1636     if (!saturation)
    1637         return { };
    1638 
    1639     if (!consumeRGBOrHSLSeparator(args, syntax))
    1640         return { };
    1641 
    1642     auto lightness = consumePercentRaw(args);
    1643     if (!lightness)
    1644         return { };
    1645 
    1646     auto alpha = consumeRGBOrHSLOptionalAlpha(args, syntax);
    1647     if (!alpha)
    1648         return { };
    1649 
    1650     if (!args.atEnd())
    1651         return { };
    1652 
    1653     auto normalizedHue = normalizeHue(*hue);
    1654     auto normalizedSaturation = std::clamp(*saturation, 0.0, 100.0);
    1655     auto normalizedLightness = std::clamp(*lightness, 0.0, 100.0);
    1656     auto normalizedAlpha = std::clamp(*alpha, 0.0, 1.0);
    1657 
    1658     return convertColor<SRGBA<uint8_t>>(HSLA<float> { static_cast<float>(normalizedHue), static_cast<float>(normalizedSaturation), static_cast<float>(normalizedLightness), static_cast<float>(normalizedAlpha) });
     1669    return parseNonRelativeHSLParameters(args, context);
    16591670}
    16601671
     
    16841695}
    16851696
     1697template<typename ConsumerForHue, typename ConsumerForWhitenessAndBlackness, typename ConsumerForAlpha>
     1698static Color parseHWBParameters(CSSParserTokenRange& args, ConsumerForHue&& hueConsumer, ConsumerForWhitenessAndBlackness&& whitenessAndBlacknessConsumer, ConsumerForAlpha&& alphaConsumer)
     1699{
     1700    auto hue = hueConsumer(args);
     1701    if (!hue)
     1702        return { };
     1703
     1704    auto whiteness = whitenessAndBlacknessConsumer(args);
     1705    if (!whiteness)
     1706        return { };
     1707
     1708    auto blackness = whitenessAndBlacknessConsumer(args);
     1709    if (!blackness)
     1710        return { };
     1711
     1712    auto alpha = alphaConsumer(args);
     1713    if (!alpha)
     1714        return { };
     1715
     1716    if (!args.atEnd())
     1717        return { };
     1718
     1719    auto normalizedHue = normalizeHue(*hue);
     1720    auto [normalizedWhitness, normalizedBlackness] = normalizeWhitenessBlackness(*whiteness, *blackness);
     1721
     1722    // NOTE: The explicit conversion to SRGBA<uint8_t> is intentional for performance (no extra allocation for
     1723    // the extended color) and compatability, forcing serialiazation to use the rgb()/rgba() form.
     1724    return convertColor<SRGBA<uint8_t>>(HWBA<float> { static_cast<float>(normalizedHue), static_cast<float>(normalizedWhitness), static_cast<float>(normalizedBlackness), static_cast<float>(*alpha) });
     1725}
     1726
    16861727static Color parseRelativeHWBParameters(CSSParserTokenRange& args, const CSSParserContext& context)
    16871728{
     
    17021743    };
    17031744
    1704     auto hue = consumeAngleRawOrNumberRawAllowingSymbolTableIdent(args, symbolTable, context.mode);
    1705     if (!hue)
    1706         return { };
    1707 
    1708     auto whiteness = consumePercentAllowingSymbolTableIdent(args, symbolTable);
    1709     if (!whiteness)
    1710         return { };
    1711 
    1712     auto blackness = consumePercentAllowingSymbolTableIdent(args, symbolTable);
    1713     if (!blackness)
    1714         return { };
    1715 
    1716     auto alpha = consumeOptionalAlphaAllowingSymbolTableIdent(args, symbolTable);
    1717     if (!alpha)
    1718         return { };
    1719 
    1720     if (!args.atEnd())
    1721         return { };
    1722 
    1723     auto normalizedHue = normalizeHue(*hue);
    1724     auto [normalizedWhitness, normalizedBlackness] = normalizeWhitenessBlackness(*whiteness, *blackness);
    1725 
    1726     return convertColor<SRGBA<uint8_t>>(HWBA<float> { static_cast<float>(normalizedHue), static_cast<float>(normalizedWhitness), static_cast<float>(normalizedBlackness), static_cast<float>(*alpha) });
     1745    auto hueConsumer = [&symbolTable, &context](auto& args) { return consumeAngleRawOrNumberRawAllowingSymbolTableIdent(args, symbolTable, context.mode); };
     1746    auto whitenessAndBlacknessConsumer = [&symbolTable](auto& args) { return consumePercentAllowingSymbolTableIdent(args, symbolTable); };
     1747    auto alphaConsumer = [&symbolTable](auto& args) { return consumeOptionalAlphaAllowingSymbolTableIdent(args, symbolTable); };
     1748
     1749    return parseHWBParameters(args, WTFMove(hueConsumer), WTFMove(whitenessAndBlacknessConsumer), WTFMove(alphaConsumer));
     1750}
     1751
     1752static Color parseNonRelativeHWBParameters(CSSParserTokenRange& args, const CSSParserContext& context)
     1753{
     1754    auto hueConsumer = [&context](auto& args) { return consumeAngleRawOrNumberRaw(args, context.mode); };
     1755    auto whitenessAndBlacknessConsumer = [](auto& args) { return consumePercentRaw(args); };
     1756    auto alphaConsumer = [](auto& args) { return consumeOptionalAlpha(args); };
     1757
     1758    return parseHWBParameters(args, WTFMove(hueConsumer), WTFMove(whitenessAndBlacknessConsumer), WTFMove(alphaConsumer));
    17271759}
    17281760
     
    17381770    if (context.relativeColorSyntaxEnabled && args.peek().id() == CSSValueFrom)
    17391771        return parseRelativeHWBParameters(args, context);
    1740 
    1741     auto hue = consumeAngleRawOrNumberRaw(args, context.mode);
    1742     if (!hue)
    1743         return { };
    1744 
    1745     auto whiteness = consumePercentRaw(args);
    1746     if (!whiteness)
    1747         return { };
    1748 
    1749     auto blackness = consumePercentRaw(args);
    1750     if (!blackness)
    1751         return { };
    1752 
    1753     auto alpha = consumeOptionalAlpha(args);
     1772    return parseNonRelativeHWBParameters(args, context);
     1773}
     1774
     1775template<typename ConsumerForLightness, typename ConsumerForAB, typename ConsumerForAlpha>
     1776static Color parseLabParameters(CSSParserTokenRange& args, ConsumerForLightness&& lightnessConsumer, ConsumerForAB&& abConsumer, ConsumerForAlpha&& alphaConsumer)
     1777{
     1778    auto lightness = lightnessConsumer(args);
     1779    if (!lightness)
     1780        return { };
     1781
     1782    auto aValue = abConsumer(args);
     1783    if (!aValue)
     1784        return { };
     1785
     1786    auto bValue = abConsumer(args);
     1787    if (!bValue)
     1788        return { };
     1789
     1790    auto alpha = alphaConsumer(args);
    17541791    if (!alpha)
    17551792        return { };
     
    17581795        return { };
    17591796
    1760     auto normalizedHue = normalizeHue(*hue);
    1761     auto [normalizedWhitness, normalizedBlackness] = normalizeWhitenessBlackness(*whiteness, *blackness);
    1762 
    1763     return convertColor<SRGBA<uint8_t>>(HWBA<float> { static_cast<float>(normalizedHue), static_cast<float>(normalizedWhitness), static_cast<float>(normalizedBlackness), static_cast<float>(*alpha) });
     1797    auto normalizedLightness = std::max(0.0, *lightness);
     1798
     1799    return Lab<float> { static_cast<float>(normalizedLightness), static_cast<float>(*aValue), static_cast<float>(*bValue), static_cast<float>(*alpha) };
    17641800}
    17651801
     
    17821818    };
    17831819
    1784     auto lightness = consumePercentAllowingSymbolTableIdent(args, symbolTable);
    1785     if (!lightness)
    1786         return { };
    1787 
    1788     auto aValue = consumeNumberAllowingSymbolTableIdent(args, symbolTable);
    1789     if (!aValue)
    1790         return { };
    1791 
    1792     auto bValue = consumeNumberAllowingSymbolTableIdent(args, symbolTable);
    1793     if (!bValue)
    1794         return { };
    1795 
    1796     auto alpha = consumeOptionalAlphaAllowingSymbolTableIdent(args, symbolTable);
    1797     if (!alpha)
    1798         return { };
    1799 
    1800     if (!args.atEnd())
    1801         return { };
    1802 
    1803     auto normalizedLightness = std::max(0.0, *lightness);
    1804 
    1805     return Lab<float> { static_cast<float>(normalizedLightness), static_cast<float>(*aValue), static_cast<float>(*bValue), static_cast<float>(*alpha) };
     1820    auto lightnessConsumer = [&symbolTable](auto& args) { return consumePercentAllowingSymbolTableIdent(args, symbolTable); };
     1821    auto abConsumer = [&symbolTable](auto& args) { return consumeNumberAllowingSymbolTableIdent(args, symbolTable); };
     1822    auto alphaConsumer = [&symbolTable](auto& args) { return consumeOptionalAlphaAllowingSymbolTableIdent(args, symbolTable); };
     1823
     1824    return parseLabParameters(args, WTFMove(lightnessConsumer), WTFMove(abConsumer), WTFMove(alphaConsumer));
     1825}
     1826
     1827static Color parseNonRelativeLabParameters(CSSParserTokenRange& args)
     1828{
     1829    auto lightnessConsumer = [](auto& args) { return consumePercentRaw(args); };
     1830    auto abConsumer = [](auto& args) { return consumeNumberRaw(args); };
     1831    auto alphaConsumer = [](auto& args) { return consumeOptionalAlpha(args); };
     1832
     1833    return parseLabParameters(args, WTFMove(lightnessConsumer), WTFMove(abConsumer), WTFMove(alphaConsumer));
    18061834}
    18071835
     
    18171845    if (context.relativeColorSyntaxEnabled && args.peek().id() == CSSValueFrom)
    18181846        return parseRelativeLabParameters(args, context);
    1819 
    1820     auto lightness = consumePercentRaw(args);
     1847    return parseNonRelativeLabParameters(args);
     1848}
     1849
     1850template<typename ConsumerForLightness, typename ConsumerForChroma, typename ConsumerForHue, typename ConsumerForAlpha>
     1851static Color parseLCHParameters(CSSParserTokenRange& args, ConsumerForLightness&& lightnessConsumer, ConsumerForChroma&& chromaConsumer, ConsumerForHue&& hueConsumer, ConsumerForAlpha&& alphaConsumer)
     1852{
     1853    auto lightness = lightnessConsumer(args);
    18211854    if (!lightness)
    18221855        return { };
    18231856
    1824     auto aValue = consumeNumberRaw(args);
    1825     if (!aValue)
    1826         return { };
    1827 
    1828     auto bValue = consumeNumberRaw(args);
    1829     if (!bValue)
    1830         return { };
    1831 
    1832     auto alpha = consumeOptionalAlpha(args);
     1857    auto chroma = chromaConsumer(args);
     1858    if (!chroma)
     1859        return { };
     1860
     1861    auto hue = hueConsumer(args);
     1862    if (!hue)
     1863        return { };
     1864
     1865    auto alpha = alphaConsumer(args);
    18331866    if (!alpha)
    18341867        return { };
     
    18381871
    18391872    auto normalizedLightness = std::max(0.0, *lightness);
    1840 
    1841     return Lab<float> { static_cast<float>(normalizedLightness), static_cast<float>(*aValue), static_cast<float>(*bValue), static_cast<float>(*alpha) };
     1873    auto normalizedChroma = std::max(0.0, *chroma);
     1874    auto normalizedHue = normalizeHue(*hue);
     1875
     1876    return LCHA<float> { static_cast<float>(normalizedLightness), static_cast<float>(normalizedChroma), static_cast<float>(normalizedHue), static_cast<float>(*alpha) };
    18421877}
    18431878
     
    18601895    };
    18611896
    1862     auto lightness = consumePercentAllowingSymbolTableIdent(args, symbolTable);
    1863     if (!lightness)
    1864         return { };
    1865 
    1866     auto chroma = consumeNumberAllowingSymbolTableIdent(args, symbolTable);
    1867     if (!chroma)
    1868         return { };
    1869 
    1870     auto hue = consumeAngleRawOrNumberRawAllowingSymbolTableIdent(args, symbolTable, context.mode);
    1871     if (!hue)
    1872         return { };
    1873 
    1874     auto alpha = consumeOptionalAlphaAllowingSymbolTableIdent(args, symbolTable);
    1875     if (!alpha)
    1876         return { };
    1877 
    1878     if (!args.atEnd())
    1879         return { };
    1880 
    1881     auto normalizedLightness = std::max(0.0, *lightness);
    1882     auto normalizedChroma = std::max(0.0, *chroma);
    1883     auto normalizedHue = normalizeHue(*hue);
    1884 
    1885     return LCHA<float> { static_cast<float>(normalizedLightness), static_cast<float>(normalizedChroma), static_cast<float>(normalizedHue), static_cast<float>(*alpha) };
     1897    auto lightnessConsumer = [&symbolTable](auto& args) { return consumePercentAllowingSymbolTableIdent(args, symbolTable); };
     1898    auto chromaConsumer = [&symbolTable](auto& args) { return consumeNumberAllowingSymbolTableIdent(args, symbolTable); };
     1899    auto hueConsumer = [&symbolTable, &context](auto& args) { return consumeAngleRawOrNumberRawAllowingSymbolTableIdent(args, symbolTable, context.mode); };
     1900    auto alphaConsumer = [&symbolTable](auto& args) { return consumeOptionalAlphaAllowingSymbolTableIdent(args, symbolTable); };
     1901
     1902    return parseLCHParameters(args, WTFMove(lightnessConsumer), WTFMove(chromaConsumer), WTFMove(hueConsumer), WTFMove(alphaConsumer));
     1903}
     1904
     1905static Color parseNonRelativeLCHParameters(CSSParserTokenRange& args, const CSSParserContext& context)
     1906{
     1907    auto lightnessConsumer = [](auto& args) { return consumePercentRaw(args); };
     1908    auto chromaConsumer = [](auto& args) { return consumeNumberRaw(args); };
     1909    auto hueConsumer = [&context](auto& args) { return consumeAngleRawOrNumberRaw(args, context.mode); };
     1910    auto alphaConsumer = [](auto& args) { return consumeOptionalAlpha(args); };
     1911
     1912    return parseLCHParameters(args, WTFMove(lightnessConsumer), WTFMove(chromaConsumer), WTFMove(hueConsumer), WTFMove(alphaConsumer));
    18861913}
    18871914
     
    18971924    if (context.relativeColorSyntaxEnabled && args.peek().id() == CSSValueFrom)
    18981925        return parseRelativeLCHParameters(args, context);
    1899 
    1900     auto lightness = consumePercentRaw(args);
    1901     if (!lightness)
    1902         return { };
    1903 
    1904     auto chroma = consumeNumberRaw(args);
    1905     if (!chroma)
    1906         return { };
    1907 
    1908     auto hue = consumeAngleRawOrNumberRaw(args, context.mode);
    1909     if (!hue)
    1910         return { };
    1911 
    1912     auto alpha = consumeOptionalAlpha(args);
     1926    return parseNonRelativeLCHParameters(args, context);
     1927}
     1928
     1929template<typename ColorType, typename ConsumerForRGB, typename ConsumerForAlpha>
     1930static Color parseColorFunctionForRGBTypes(CSSParserTokenRange& args, ConsumerForRGB&& rgbConsumer, ConsumerForAlpha&& alphaConsumer)
     1931{
     1932    double channels[3] = { 0, 0, 0 };
     1933    for (auto& channel : channels) {
     1934        auto value = rgbConsumer(args);
     1935        if (!value)
     1936            break;
     1937        channel = *value;
     1938    }
     1939
     1940    auto alpha = alphaConsumer(args);
    19131941    if (!alpha)
    19141942        return { };
     
    19171945        return { };
    19181946
    1919     auto normalizedLightness = std::max(0.0, *lightness);
    1920     auto normalizedChroma = std::max(0.0, *chroma);
    1921     auto normalizedHue = normalizeHue(*hue);
    1922 
    1923     return LCHA<float> { static_cast<float>(normalizedLightness), static_cast<float>(normalizedChroma), static_cast<float>(normalizedHue), static_cast<float>(*alpha) };
    1924 }
    1925 
    1926 template<typename ColorType> static Color parseColorFunctionForRGBTypes(CSSParserTokenRange& args, const CSSParserContext& context)
     1947    auto normalizedRed = std::clamp(channels[0], 0.0, 1.0);
     1948    auto normalizedGreen = std::clamp(channels[1], 0.0, 1.0);
     1949    auto normalizedBlue = std::clamp(channels[2], 0.0, 1.0);
     1950
     1951    return { ColorType { static_cast<float>(normalizedRed), static_cast<float>(normalizedGreen), static_cast<float>(normalizedBlue), static_cast<float>(*alpha) }, Color::Flags::UseColorFunctionSerialization };
     1952}
     1953
     1954template<typename ColorType> static Color parseRelativeColorFunctionForRGBTypes(CSSParserTokenRange& args, Color originColor, const CSSParserContext& context)
    19271955{
    19281956    ASSERT(args.peek().id() == CSSValueA98Rgb || args.peek().id() == CSSValueDisplayP3 || args.peek().id() == CSSValueProphotoRgb || args.peek().id() == CSSValueRec2020 || args.peek().id() == CSSValueSRGB);
     
    19341962    consumeIdentRaw(args);
    19351963
     1964    auto originColorAsColorType = originColor.toColorTypeLossy<ColorType>();
     1965
     1966    CSSCalcSymbolTable symbolTable {
     1967        { CSSValueR, CSSUnitType::CSS_PERCENTAGE, originColorAsColorType.red * 100.0 },
     1968        { CSSValueG, CSSUnitType::CSS_PERCENTAGE, originColorAsColorType.green * 100.0 },
     1969        { CSSValueB, CSSUnitType::CSS_PERCENTAGE, originColorAsColorType.blue * 100.0 },
     1970        { CSSValueAlpha, CSSUnitType::CSS_PERCENTAGE, originColorAsColorType.alpha * 100.0 }
     1971    };
     1972
     1973    auto consumeRGB = [&symbolTable](auto& args) { return consumeNumberRawOrPercentDividedBy100RawAllowingSymbolTableIdent(args, symbolTable, ValueRange::All); };
     1974    auto consumeAlpha = [&symbolTable](auto& args) { return consumeOptionalAlphaAllowingSymbolTableIdent(args, symbolTable); };
     1975
     1976    return parseColorFunctionForRGBTypes<ColorType>(args, WTFMove(consumeRGB), WTFMove(consumeAlpha));
     1977}
     1978
     1979template<typename ColorType> static Color parseColorFunctionForRGBTypes(CSSParserTokenRange& args, const CSSParserContext& context)
     1980{
     1981    ASSERT(args.peek().id() == CSSValueA98Rgb || args.peek().id() == CSSValueDisplayP3 || args.peek().id() == CSSValueProphotoRgb || args.peek().id() == CSSValueRec2020 || args.peek().id() == CSSValueSRGB);
     1982
     1983    // Support sRGB and Display-P3 regardless of the setting as we have shipped support for them for a while.
     1984    if (!context.cssColor4 && (args.peek().id() == CSSValueA98Rgb || args.peek().id() == CSSValueProphotoRgb || args.peek().id() == CSSValueRec2020))
     1985        return { };
     1986
     1987    consumeIdentRaw(args);
     1988
     1989    auto consumeRGB = [](auto& args) { return consumeNumberRawOrPercentDividedBy100Raw(args); };
     1990    auto consumeAlpha = [](auto& args) { return consumeOptionalAlpha(args); };
     1991
     1992    return parseColorFunctionForRGBTypes<ColorType>(args, WTFMove(consumeRGB), WTFMove(consumeAlpha));
     1993}
     1994
     1995template<typename ConsumerForXYZ, typename ConsumerForAlpha>
     1996static Color parseColorFunctionForXYZParameters(CSSParserTokenRange& args, ConsumerForXYZ&& xyzConsumer, ConsumerForAlpha&& alphaConsumer)
     1997{
    19361998    double channels[3] = { 0, 0, 0 };
    1937     for (int i = 0; i < 3; ++i) {
    1938         auto value = consumeNumberRawOrPercentDividedBy100Raw(args);
     1999    for (auto& channel : channels) {
     2000        auto value = xyzConsumer(args);
    19392001        if (!value)
    19402002            break;
    1941         channels[i] = *value;
    1942     }
    1943 
    1944     auto alpha = consumeOptionalAlpha(args);
     2003        channel = *value;
     2004    }
     2005
     2006    auto alpha = alphaConsumer(args);
    19452007    if (!alpha)
    19462008        return { };
    19472009
    1948     return { ColorType { clampTo<float>(channels[0], 0.0, 1.0), clampTo<float>(channels[1], 0.0, 1.0), clampTo<float>(channels[2], 0.0, 1.0), static_cast<float>(*alpha) }, Color::Flags::UseColorFunctionSerialization };
     2010    if (!args.atEnd())
     2011        return { };
     2012
     2013    return { XYZA<float, WhitePoint::D50> { static_cast<float>(channels[0]), static_cast<float>(channels[1]), static_cast<float>(channels[2]), static_cast<float>(*alpha) }, Color::Flags::UseColorFunctionSerialization };
     2014}
     2015
     2016static Color parseRelativeColorFunctionForXYZParameters(CSSParserTokenRange& args, Color originColor, const CSSParserContext& context)
     2017{
     2018    ASSERT(args.peek().id() == CSSValueXyz);
     2019
     2020    if (!context.cssColor4)
     2021        return { };
     2022
     2023    consumeIdentRaw(args);
     2024
     2025    auto originColorAsXYZ = originColor.toColorTypeLossy<XYZA<float, WhitePoint::D50>>();
     2026
     2027    CSSCalcSymbolTable symbolTable {
     2028        { CSSValueX, CSSUnitType::CSS_NUMBER, originColorAsXYZ.x },
     2029        { CSSValueY, CSSUnitType::CSS_NUMBER, originColorAsXYZ.y },
     2030        { CSSValueZ, CSSUnitType::CSS_NUMBER, originColorAsXYZ.z },
     2031        { CSSValueAlpha, CSSUnitType::CSS_PERCENTAGE, originColorAsXYZ.alpha * 100.0 }
     2032    };
     2033
     2034    auto consumeXYZ = [&symbolTable](auto& args) { return consumeNumberAllowingSymbolTableIdent(args, symbolTable); };
     2035    auto consumeAlpha = [&symbolTable](auto& args) { return consumeOptionalAlphaAllowingSymbolTableIdent(args, symbolTable); };
     2036
     2037    return parseColorFunctionForXYZParameters(args, WTFMove(consumeXYZ), WTFMove(consumeAlpha));
    19492038}
    19502039
     
    19582047    consumeIdentRaw(args);
    19592048
    1960     double channels[3] = { 0, 0, 0 };
    1961     [&] {
    1962         auto x = consumeNumberRaw(args);
    1963         if (!x)
    1964             return;
    1965         channels[0] = *x;
    1966 
    1967         auto y = consumeNumberRaw(args);
    1968         if (!y)
    1969             return;
    1970         channels[1] = *y;
    1971 
    1972         auto z = consumeNumberRaw(args);
    1973         if (!z)
    1974             return;
    1975         channels[2] = *z;
    1976     }();
    1977 
    1978     auto alpha = consumeOptionalAlpha(args);
    1979     if (!alpha)
    1980         return { };
    1981 
    1982     return { XYZA<float, WhitePoint::D50> { static_cast<float>(channels[0]), static_cast<float>(channels[1]), static_cast<float>(channels[2]), static_cast<float>(*alpha) }, Color::Flags::UseColorFunctionSerialization };
     2049    auto consumeXYZ = [](auto& args) { return consumeNumberRaw(args); };
     2050    auto consumeAlpha = [](auto& args) { return consumeOptionalAlpha(args); };
     2051
     2052    return parseColorFunctionForXYZParameters(args, WTFMove(consumeXYZ), WTFMove(consumeAlpha));
     2053}
     2054
     2055static Color parseRelativeColorFunctionParameters(CSSParserTokenRange& args, const CSSParserContext& context)
     2056{
     2057    ASSERT(args.peek().id() == CSSValueFrom);
     2058    consumeIdentRaw(args);
     2059
     2060    auto originColor = consumeOriginColor(args, context);
     2061    if (!originColor.isValid())
     2062        return { };
     2063
     2064    switch (args.peek().id()) {
     2065    case CSSValueA98Rgb:
     2066        return parseRelativeColorFunctionForRGBTypes<A98RGB<float>>(args, WTFMove(originColor), context);
     2067    case CSSValueDisplayP3:
     2068        return parseRelativeColorFunctionForRGBTypes<DisplayP3<float>>(args, WTFMove(originColor), context);
     2069    case CSSValueProphotoRgb:
     2070        return parseRelativeColorFunctionForRGBTypes<ProPhotoRGB<float>>(args, WTFMove(originColor), context);
     2071    case CSSValueRec2020:
     2072        return parseRelativeColorFunctionForRGBTypes<Rec2020<float>>(args, WTFMove(originColor), context);
     2073    case CSSValueSRGB:
     2074        return parseRelativeColorFunctionForRGBTypes<SRGBA<float>>(args, WTFMove(originColor), context);
     2075    case CSSValueXyz:
     2076        return parseRelativeColorFunctionForXYZParameters(args, WTFMove(originColor), context);
     2077    default:
     2078        return { };
     2079    }
     2080
     2081    ASSERT_NOT_REACHED();
     2082    return { };
     2083}
     2084
     2085static Color parseNonRelativeColorFunctionParameters(CSSParserTokenRange& args, const CSSParserContext& context)
     2086{
     2087    switch (args.peek().id()) {
     2088    case CSSValueA98Rgb:
     2089        return parseColorFunctionForRGBTypes<A98RGB<float>>(args, context);
     2090    case CSSValueDisplayP3:
     2091        return parseColorFunctionForRGBTypes<DisplayP3<float>>(args, context);
     2092    case CSSValueProphotoRgb:
     2093        return parseColorFunctionForRGBTypes<ProPhotoRGB<float>>(args, context);
     2094    case CSSValueRec2020:
     2095        return parseColorFunctionForRGBTypes<Rec2020<float>>(args, context);
     2096    case CSSValueSRGB:
     2097        return parseColorFunctionForRGBTypes<SRGBA<float>>(args, context);
     2098    case CSSValueXyz:
     2099        return parseColorFunctionForXYZParameters(args, context);
     2100    default:
     2101        return { };
     2102    }
     2103
     2104    ASSERT_NOT_REACHED();
     2105    return { };
    19832106}
    19842107
     
    19882111    auto args = consumeFunction(range);
    19892112
    1990     Color color;
    1991     switch (args.peek().id()) {
    1992     case CSSValueA98Rgb:
    1993         color = parseColorFunctionForRGBTypes<A98RGB<float>>(args, context);
    1994         break;
    1995     case CSSValueDisplayP3:
    1996         color = parseColorFunctionForRGBTypes<DisplayP3<float>>(args, context);
    1997         break;
    1998     case CSSValueProphotoRgb:
    1999         color = parseColorFunctionForRGBTypes<ProPhotoRGB<float>>(args, context);
    2000         break;
    2001     case CSSValueRec2020:
    2002         color = parseColorFunctionForRGBTypes<Rec2020<float>>(args, context);
    2003         break;
    2004     case CSSValueSRGB:
    2005         color = parseColorFunctionForRGBTypes<SRGBA<float>>(args, context);
    2006         break;
    2007     case CSSValueXyz:
    2008         color = parseColorFunctionForXYZParameters(args, context);
    2009         break;
    2010     default:
    2011         return { };
    2012     }
    2013 
    2014     if (!color.isValid())
    2015         return { };
    2016 
    2017     if (!args.atEnd())
    2018         return { };
    2019 
    2020     ASSERT(color.usesColorFunctionSerialization());
     2113    auto color = [&] {
     2114        if (context.relativeColorSyntaxEnabled && args.peek().id() == CSSValueFrom)
     2115            return parseRelativeColorFunctionParameters(args, context);
     2116        return parseNonRelativeColorFunctionParameters(args, context);
     2117    }();
     2118
     2119    ASSERT(!color.isValid() || color.usesColorFunctionSerialization());
    20212120    return color;
    20222121}
Note: See TracChangeset for help on using the changeset viewer.