⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 278290 in webkit


Ignore:
Timestamp:
May 31, 2021, 6:17:13 PM (5 years ago)
Author:
commit-queue@webkit.org
Message:

Unreviewed, reverting r278261.
https://bugs.webkit.org/show_bug.cgi?id=226477

Broke windows build

Reverted changeset:

"Support calc() on components inside relative color syntax
colors"
https://bugs.webkit.org/show_bug.cgi?id=226272
https://trac.webkit.org/changeset/278261

Location:
trunk
Files:
2 deleted
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r278282 r278290  
     12021-05-31  Commit Queue  <commit-queue@webkit.org>
     2
     3        Unreviewed, reverting r278261.
     4        https://bugs.webkit.org/show_bug.cgi?id=226477
     5
     6        Broke windows build
     7
     8        Reverted changeset:
     9
     10        "Support calc() on components inside relative color syntax
     11        colors"
     12        https://bugs.webkit.org/show_bug.cgi?id=226272
     13        https://trac.webkit.org/changeset/278261
     14
    1152021-05-31  Arcady Goldmints-Orlov  <agoldmints@igalia.com>
    216
  • trunk/LayoutTests/fast/css/parsing-relative-color-syntax-expected.txt

    r278268 r278290  
    4343PASS computedStyle("background-color", "rgb(from rgb(10%, 20%, 30%, 40%) r 25 b / 25%)") is "rgba(26, 25, 77, 0.25)"
    4444PASS computedStyle("background-color", "rgb(from rgb(10%, 20%, 30%, 40%) r g 25 / 25%)") is "rgba(26, 51, 25, 0.25)"
    45 PASS computedStyle("background-color", "rgb(from rebeccapurple g b r)") is "rgb(51, 153, 102)"
    46 PASS computedStyle("background-color", "rgb(from rebeccapurple b alpha r / g)") is "rgba(153, 255, 102, 0.2)"
    47 PASS computedStyle("background-color", "rgb(from rebeccapurple r r r / r)") is "rgba(102, 102, 102, 0.4)"
    48 PASS computedStyle("background-color", "rgb(from rebeccapurple alpha alpha alpha / alpha)") is "rgb(255, 255, 255)"
    49 PASS computedStyle("background-color", "rgb(from rgb(10%, 20%, 30%, 40%) g b r)") is "rgb(51, 77, 26)"
    50 PASS computedStyle("background-color", "rgb(from rgb(10%, 20%, 30%, 40%) b alpha r / g)") is "rgba(77, 102, 26, 0.2)"
    51 PASS computedStyle("background-color", "rgb(from rgb(10%, 20%, 30%, 40%) r r r / r)") is "rgba(26, 26, 26, 0.1)"
    52 PASS computedStyle("background-color", "rgb(from rgb(10%, 20%, 30%, 40%) alpha alpha alpha / alpha)") is "rgba(102, 102, 102, 0.4)"
    53 PASS computedStyle("background-color", "rgb(from rebeccapurple r 10% 10)") is "rgb(102, 26, 10)"
    54 PASS computedStyle("background-color", "rgb(from rebeccapurple r 10 10%)") is "rgb(102, 10, 26)"
    55 PASS computedStyle("background-color", "rgb(from rebeccapurple 0% 10 10)") is "rgb(0, 10, 10)"
    56 PASS computedStyle("background-color", "rgb(from rgb(10%, 20%, 30%, 40%) r 10% 10)") is "rgb(26, 26, 10)"
    57 PASS computedStyle("background-color", "rgb(from rgb(10%, 20%, 30%, 40%) r 10 10%)") is "rgb(26, 10, 26)"
    58 PASS computedStyle("background-color", "rgb(from rgb(10%, 20%, 30%, 40%) 0% 10 10)") is "rgb(0, 10, 10)"
    59 PASS computedStyle("background-color", "rgb(from rebeccapurple calc(r) calc(g) calc(b))") is "rgb(102, 51, 153)"
    60 PASS computedStyle("background-color", "rgb(from rebeccapurple r calc(g * .5) 10)") is "rgb(102, 26, 10)"
    61 PASS computedStyle("background-color", "rgb(from rebeccapurple r calc(b * .5) 10)") is "rgb(102, 77, 10)"
    62 PASS computedStyle("background-color", "rgb(from rebeccapurple r calc(b * .5 + g * .5) 10)") is "rgb(102, 102, 10)"
    63 PASS computedStyle("background-color", "rgb(from rebeccapurple r calc(b * .5 - g * .5) 10)") is "rgb(102, 51, 10)"
    64 PASS computedStyle("background-color", "rgb(from rebeccapurple r calc(b * .5 - g * .5) 10)") is "rgb(102, 51, 10)"
    65 PASS computedStyle("background-color", "rgb(from rgb(10%, 20%, 30%, 40%) calc(r) calc(g) calc(b) / calc(alpha))") is "rgba(26, 51, 77, 0.4)"
     45PASS computedStyle("background-color", "rgb(from rebeccapurple g b r)") is "rgba(0, 0, 0, 0)"
     46PASS computedStyle("background-color", "rgb(from rebeccapurple b alpha r / g)") is "rgba(0, 0, 0, 0)"
     47PASS computedStyle("background-color", "rgb(from rebeccapurple r r r / r)") is "rgba(0, 0, 0, 0)"
     48PASS computedStyle("background-color", "rgb(from rebeccapurple alpha alpha alpha / alpha)") is "rgba(0, 0, 0, 0)"
     49PASS computedStyle("background-color", "rgb(from rgb(10%, 20%, 30%, 40%) g b r)") is "rgba(0, 0, 0, 0)"
     50PASS computedStyle("background-color", "rgb(from rgb(10%, 20%, 30%, 40%) b alpha r / g)") is "rgba(0, 0, 0, 0)"
     51PASS computedStyle("background-color", "rgb(from rgb(10%, 20%, 30%, 40%) r r r / r)") is "rgba(0, 0, 0, 0)"
     52PASS computedStyle("background-color", "rgb(from rgb(10%, 20%, 30%, 40%) alpha alpha alpha / alpha)") is "rgba(0, 0, 0, 0)"
     53PASS computedStyle("background-color", "rgb(from rebeccapurple r 10% 10)") is "rgba(0, 0, 0, 0)"
     54PASS computedStyle("background-color", "rgb(from rebeccapurple r 10 10%)") is "rgba(0, 0, 0, 0)"
     55PASS computedStyle("background-color", "rgb(from rebeccapurple 0% 10 10)") is "rgba(0, 0, 0, 0)"
     56PASS computedStyle("background-color", "rgb(from rgb(10%, 20%, 30%, 40%) r 10% 10)") is "rgba(0, 0, 0, 0)"
     57PASS computedStyle("background-color", "rgb(from rgb(10%, 20%, 30%, 40%) r 10 10%)") is "rgba(0, 0, 0, 0)"
     58PASS computedStyle("background-color", "rgb(from rgb(10%, 20%, 30%, 40%) 0% 10 10)") is "rgba(0, 0, 0, 0)"
    6659PASS computedStyle("background-color", "rgb(from rebeccapurple red g b)") is "rgba(0, 0, 0, 0)"
    6760PASS computedStyle("background-color", "rgb(from rebeccapurple l g b)") is "rgba(0, 0, 0, 0)"
     
    9992PASS computedStyle("background-color", "hsl(from rgb(10%, 20%, 30%, 40%) h s 25% / alpha)") is "rgba(32, 63, 95, 0.4)"
    10093PASS computedStyle("background-color", "hsl(from rgb(10%, 20%, 30%, 40%) h s l / .25)") is "rgba(26, 51, 77, 0.25)"
    101 PASS computedStyle("background-color", "hsl(from rebeccapurple h l s)") is "rgb(128, 77, 179)"
    102 PASS computedStyle("background-color", "hsl(from rebeccapurple h alpha l / s)") is "rgba(102, 0, 204, 0.5)"
    103 PASS computedStyle("background-color", "hsl(from rebeccapurple h l l / l)") is "rgba(102, 61, 143, 0.4)"
    104 PASS computedStyle("background-color", "hsl(from rebeccapurple h alpha alpha / alpha)") is "rgb(255, 255, 255)"
    105 PASS computedStyle("background-color", "hsl(from rgb(10%, 20%, 30%, 40%) h l s)") is "rgb(101, 126, 152)"
    106 PASS computedStyle("background-color", "hsl(from rgb(10%, 20%, 30%, 40%) h alpha l / s)") is "rgba(31, 51, 72, 0.494)"
    107 PASS computedStyle("background-color", "hsl(from rgb(10%, 20%, 30%, 40%) h l l / l)") is "rgba(41, 51, 62, 0.204)"
    108 PASS computedStyle("background-color", "hsl(from rgb(10%, 20%, 30%, 40%) h alpha alpha / alpha)") is "rgba(61, 101, 143, 0.4)"
    109 PASS computedStyle("background-color", "hsl(from rebeccapurple s h l)") is "rgba(0, 0, 0, 0)"
    110 PASS computedStyle("background-color", "hsl(from rebeccapurple s s s / s)") is "rgba(0, 0, 0, 0)"
    111 PASS computedStyle("background-color", "hsl(from rebeccapurple h h h / h)") is "rgba(0, 0, 0, 0)"
    112 PASS computedStyle("background-color", "hsl(from rebeccapurple alpha alpha alpha / alpha)") is "rgba(0, 0, 0, 0)"
    113 PASS computedStyle("background-color", "hsl(from rgb(10%, 20%, 30%, 40%) s h l)") is "rgba(0, 0, 0, 0)"
    114 PASS computedStyle("background-color", "hsl(from rgb(10%, 20%, 30%, 40%) s s s / s)") is "rgba(0, 0, 0, 0)"
    115 PASS computedStyle("background-color", "hsl(from rgb(10%, 20%, 30%, 40%) h h h / h)") is "rgba(0, 0, 0, 0)"
    116 PASS computedStyle("background-color", "hsl(from rgb(10%, 20%, 30%, 40%) alpha alpha alpha / alpha)") is "rgba(0, 0, 0, 0)"
    117 PASS computedStyle("background-color", "hsl(from rebeccapurple calc(h) calc(s) calc(l))") is "rgb(102, 51, 153)"
    118 PASS computedStyle("background-color", "hsl(from rgb(10%, 20%, 30%, 40%) calc(h) calc(s) calc(l) / calc(alpha))") is "rgba(26, 51, 77, 0.4)"
     94PASS computedStyle("background-color", "hsl(from rebeccapurple h l s)") is "rgba(0, 0, 0, 0)"
     95PASS computedStyle("background-color", "hsl(from rebeccapurple h alpha l / s)") is "rgba(0, 0, 0, 0)"
     96PASS computedStyle("background-color", "hsl(from rebeccapurple h l l / l)") is "rgba(0, 0, 0, 0)"
     97PASS computedStyle("background-color", "hsl(from rebeccapurple h alpha alpha / alpha)") is "rgba(0, 0, 0, 0)"
     98PASS computedStyle("background-color", "hsl(from rgb(10%, 20%, 30%, 40%) h l s)") is "rgba(0, 0, 0, 0)"
     99PASS computedStyle("background-color", "hsl(from rgb(10%, 20%, 30%, 40%) h alpha l / s)") is "rgba(0, 0, 0, 0)"
     100PASS computedStyle("background-color", "hsl(from rgb(10%, 20%, 30%, 40%) h l l / l)") is "rgba(0, 0, 0, 0)"
     101PASS computedStyle("background-color", "hsl(from rgb(10%, 20%, 30%, 40%) h alpha alpha / alpha)") is "rgba(0, 0, 0, 0)"
    119102PASS computedStyle("background-color", "hsl(from rebeccapurple h 10% 10)") is "rgba(0, 0, 0, 0)"
    120103PASS computedStyle("background-color", "hsl(from rebeccapurple h 10 10%)") is "rgba(0, 0, 0, 0)"
     
    158141PASS computedStyle("background-color", "hwb(from rgb(10%, 20%, 30%, 40%) h w 25% / alpha)") is "rgba(26, 107, 191, 0.4)"
    159142PASS computedStyle("background-color", "hwb(from rgb(10%, 20%, 30%, 40%) h w b / .25)") is "rgba(26, 51, 77, 0.25)"
    160 PASS computedStyle("background-color", "hwb(from rebeccapurple h b w)") is "rgb(153, 102, 204)"
    161 PASS computedStyle("background-color", "hwb(from rebeccapurple h alpha w / b)") is "rgba(213, 213, 213, 0.4)"
    162 PASS computedStyle("background-color", "hwb(from rebeccapurple h w w / w)") is "rgba(128, 51, 204, 0.2)"
    163 PASS computedStyle("background-color", "hwb(from rebeccapurple h alpha alpha / alpha)") is "rgb(128, 128, 128)"
    164 PASS computedStyle("background-color", "hwb(from rgb(10%, 20%, 30%, 40%) h b w)") is "rgb(178, 203, 229)"
    165 PASS computedStyle("background-color", "hwb(from rgb(10%, 20%, 30%, 40%) h alpha w / b)") is "rgba(102, 164, 229, 0.698)"
    166 PASS computedStyle("background-color", "hwb(from rgb(10%, 20%, 30%, 40%) h w w / w)") is "rgba(26, 126, 229, 0.1)"
    167 PASS computedStyle("background-color", "hwb(from rgb(10%, 20%, 30%, 40%) h alpha alpha / alpha)") is "rgba(102, 127, 153, 0.4)"
    168 PASS computedStyle("background-color", "hwb(from rebeccapurple w h b)") is "rgba(0, 0, 0, 0)"
    169 PASS computedStyle("background-color", "hwb(from rebeccapurple b b b / b)") is "rgba(0, 0, 0, 0)"
    170 PASS computedStyle("background-color", "hwb(from rebeccapurple h h h / h)") is "rgba(0, 0, 0, 0)"
    171 PASS computedStyle("background-color", "hwb(from rebeccapurple alpha alpha alpha / alpha)") is "rgba(0, 0, 0, 0)"
    172 PASS computedStyle("background-color", "hwb(from rgb(10%, 20%, 30%, 40%) w b h)") is "rgba(0, 0, 0, 0)"
    173 PASS computedStyle("background-color", "hwb(from rgb(10%, 20%, 30%, 40%) b b b / b)") is "rgba(0, 0, 0, 0)"
    174 PASS computedStyle("background-color", "hwb(from rgb(10%, 20%, 30%, 40%) h h h / h)") is "rgba(0, 0, 0, 0)"
    175 PASS computedStyle("background-color", "hwb(from rgb(10%, 20%, 30%, 40%) alpha alpha alpha / alpha)") is "rgba(0, 0, 0, 0)"
    176 PASS computedStyle("background-color", "hwb(from rebeccapurple calc(h) calc(w) calc(b))") is "rgb(102, 51, 153)"
    177 PASS computedStyle("background-color", "hwb(from rgb(10%, 20%, 30%, 40%) calc(h) calc(w) calc(b) / calc(alpha))") is "rgba(26, 51, 77, 0.4)"
     143PASS computedStyle("background-color", "hwb(from rebeccapurple h b w)") is "rgba(0, 0, 0, 0)"
     144PASS computedStyle("background-color", "hwb(from rebeccapurple h alpha w / b)") is "rgba(0, 0, 0, 0)"
     145PASS computedStyle("background-color", "hwb(from rebeccapurple h w w / w)") is "rgba(0, 0, 0, 0)"
     146PASS computedStyle("background-color", "hwb(from rebeccapurple h alpha alpha / alpha)") is "rgba(0, 0, 0, 0)"
     147PASS computedStyle("background-color", "hwb(from rgb(10%, 20%, 30%, 40%) h b w)") is "rgba(0, 0, 0, 0)"
     148PASS computedStyle("background-color", "hwb(from rgb(10%, 20%, 30%, 40%) h alpha w / b)") is "rgba(0, 0, 0, 0)"
     149PASS computedStyle("background-color", "hwb(from rgb(10%, 20%, 30%, 40%) h w w / w)") is "rgba(0, 0, 0, 0)"
     150PASS computedStyle("background-color", "hwb(from rgb(10%, 20%, 30%, 40%) h alpha alpha / alpha)") is "rgba(0, 0, 0, 0)"
    178151PASS computedStyle("background-color", "hwb(from rebeccapurple h 10% 10)") is "rgba(0, 0, 0, 0)"
    179152PASS computedStyle("background-color", "hwb(from rebeccapurple h 10 10%)") is "rgba(0, 0, 0, 0)"
     
    210183PASS computedStyle("background-color", "lab(from lab(25% 20 50 / 40%) l a 35 / alpha)") is "lab(25% 20 35 / 0.4)"
    211184PASS computedStyle("background-color", "lab(from lab(25% 20 50 / 40%) l a b / .35)") is "lab(25% 20 50 / 0.35)"
    212 PASS computedStyle("background-color", "lab(from lab(25% 20 50) l b a)") is "lab(25% 50 20)"
    213 PASS computedStyle("background-color", "lab(from lab(25% 20 50) l a a / a)") is "lab(25% 20 20)"
    214 PASS computedStyle("background-color", "lab(from lab(25% 20 50 / 40%) l b a)") is "lab(25% 50 20)"
    215 PASS computedStyle("background-color", "lab(from lab(25% 20 50 / 40%) l a a / a)") is "lab(25% 20 20)"
     185PASS computedStyle("background-color", "lab(from lab(25% 20 50) l b a)") is "rgba(0, 0, 0, 0)"
    216186PASS computedStyle("background-color", "lab(from lab(25% 20 50) l alpha a / b)") is "rgba(0, 0, 0, 0)"
     187PASS computedStyle("background-color", "lab(from lab(25% 20 50) l a a / a)") is "rgba(0, 0, 0, 0)"
    217188PASS computedStyle("background-color", "lab(from lab(25% 20 50) l alpha alpha / alpha)") is "rgba(0, 0, 0, 0)"
     189PASS computedStyle("background-color", "lab(from lab(25% 20 50 / 40%) l b a)") is "rgba(0, 0, 0, 0)"
    218190PASS computedStyle("background-color", "lab(from lab(25% 20 50 / 40%) l alpha a / b)") is "rgba(0, 0, 0, 0)"
     191PASS computedStyle("background-color", "lab(from lab(25% 20 50 / 40%) l a a / a)") is "rgba(0, 0, 0, 0)"
    219192PASS computedStyle("background-color", "lab(from lab(25% 20 50 / 40%) l alpha alpha / alpha)") is "rgba(0, 0, 0, 0)"
    220 PASS computedStyle("background-color", "lab(from lab(25% 20 50) calc(l) calc(a) calc(b))") is "lab(25% 20 50)"
    221 PASS computedStyle("background-color", "lab(from lab(25% 20 50 / 40%) calc(l) calc(a) calc(b) / calc(alpha))") is "lab(25% 20 50 / 0.4)"
    222193PASS computedStyle("background-color", "lab(from lab(25% 20 50) l 10% 10)") is "rgba(0, 0, 0, 0)"
    223194PASS computedStyle("background-color", "lab(from lab(25% 20 50) l 10 10%)") is "rgba(0, 0, 0, 0)"
     
    261232PASS computedStyle("background-color", "lch(from lch(70% 45 30 / 40%) l c 25deg / alpha)") is "lch(70% 45 25 / 0.4)"
    262233PASS computedStyle("background-color", "lch(from lch(70% 45 30 / 40%) l c h / .25)") is "lch(70% 45 30 / 0.25)"
    263 PASS computedStyle("background-color", "lch(from lch(70% 45 30) alpha c h / l)") is "lch(100% 45 30 / 0.7)"
    264 PASS computedStyle("background-color", "lch(from lch(70% 45 30) l c c / alpha)") is "lch(70% 45 45)"
    265 PASS computedStyle("background-color", "lch(from lch(70% 45 30) alpha c h / alpha)") is "lch(100% 45 30)"
    266 PASS computedStyle("background-color", "lch(from lch(70% 45 30) alpha c c / alpha)") is "lch(100% 45 45)"
    267 PASS computedStyle("background-color", "lch(from lch(70% 45 30 / 40%) alpha c h / l)") is "lch(40% 45 30 / 0.7)"
    268 PASS computedStyle("background-color", "lch(from lch(70% 45 30 / 40%) l c c / alpha)") is "lch(70% 45 45 / 0.4)"
    269 PASS computedStyle("background-color", "lch(from lch(70% 45 30 / 40%) alpha c h / alpha)") is "lch(40% 45 30 / 0.4)"
    270 PASS computedStyle("background-color", "lch(from lch(70% 45 30 / 40%) alpha c c / alpha)") is "lch(40% 45 45 / 0.4)"
    271 PASS computedStyle("background-color", "lch(from lch(70% 45 30) h l c / alpha)") is "rgba(0, 0, 0, 0)"
    272 PASS computedStyle("background-color", "lch(from lch(70% 45 30) c c c / c)") is "rgba(0, 0, 0, 0)"
    273 PASS computedStyle("background-color", "lch(from lch(70% 45 30) alpha alpha alpha / alpha)") is "rgba(0, 0, 0, 0)"
    274 PASS computedStyle("background-color", "lch(from lch(70% 45 30 / 40%) h l c / alpha)") is "rgba(0, 0, 0, 0)"
    275 PASS computedStyle("background-color", "lch(from lch(70% 45 30 / 40%) c c c / c)") is "rgba(0, 0, 0, 0)"
    276 PASS computedStyle("background-color", "lch(from lch(70% 45 30 / 40%) alpha alpha alpha / alpha)") is "rgba(0, 0, 0, 0)"
    277 PASS computedStyle("background-color", "lch(from lch(70% 45 30) calc(l) calc(c) calc(h))") is "lch(70% 45 30)"
    278 PASS computedStyle("background-color", "lch(from lch(70% 45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))") is "lch(70% 45 30 / 0.4)"
     234PASS computedStyle("background-color", "lch(from lch(70% 45 30) alpha c h / l)") is "rgba(0, 0, 0, 0)"
     235PASS computedStyle("background-color", "lch(from lch(70% 45 30) alpha c h / alpha)") is "rgba(0, 0, 0, 0)"
     236PASS computedStyle("background-color", "lch(from lch(70% 45 30 / 40%) alpha c h / l)") is "rgba(0, 0, 0, 0)"
     237PASS computedStyle("background-color", "lch(from lch(70% 45 30 / 40%) alpha c h / alpha)") is "rgba(0, 0, 0, 0)"
    279238PASS computedStyle("background-color", "lch(from lch(70% 45 30) l 10% h)") is "rgba(0, 0, 0, 0)"
    280239PASS computedStyle("background-color", "lch(from lch(70% 45 30) l c 10%)") is "rgba(0, 0, 0, 0)"
     
    286245PASS computedStyle("background-color", "lch(from lch(70% 45 30) x c h)") is "rgba(0, 0, 0, 0)"
    287246PASS computedStyle("background-color", "lch(from lch(70% 45 30) l g b)") is "rgba(0, 0, 0, 0)"
    288 PASS computedStyle("background-color", "rgb(from var(--bg-color) r g b / 80%)") is "rgba(0, 0, 255, 0.8)"
    289 PASS computedStyle("background-color", "lch(from var(--color) calc(l / 2) c h)") is "lch(23.138971% 67.989716 134.39125)"
    290 PASS computedStyle("background-color", "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))") is "rgb(76, 76, 76)"
    291 PASS computedStyle("background-color", "lch(from var(--color) l 0 h)") is "lch(46.277943% 0 134.39125)"
    292 PASS computedStyle("background-color", "rgb(from indianred 255 g b)") is "rgb(255, 92, 92)"
    293 PASS computedStyle("background-color", "hsl(from var(--accent) calc(h + 180deg) s l)") is "rgb(178, 32, 40)"
    294 PASS computedStyle("background-color", "lab(from var(--mycolor) l a b / 100%)") is "lab(62.751923% 52.45802 -34.117283)"
    295 PASS computedStyle("background-color", "lab(from var(--mycolor) l a b / calc(alpha * 0.8))") is "lab(62.751923% 52.45802 -34.117283 / 0.8)"
    296 PASS computedStyle("background-color", "lab(from var(--mycolor) l a b / calc(alpha - 20%))") is "lab(62.751923% 52.45802 -34.117283 / 0.8)"
    297 PASS computedStyle("background-color", "lab(from var(--mycolor) l 0 0)") is "lab(62.751923% 0 0)"
    298 PASS computedStyle("background-color", "lch(from peru calc(l * 0.8) c h)") is "lch(49.80138% 54.003296 63.680317)"
    299 PASS computedStyle("background-color", "LCH(from var(--accent) l c calc(h + 180deg))") is "lch(65.49473% 39.446903 10.114471)"
    300 PASS computedStyle("background-color", "lch(from var(--mycolor) l 0 h)") is "lch(62.751923% 0 326.96112)"
    301 PASS computedStyle("background-color", "var(--mygray)") is "lch(62.751923% 0 326.96112)"
    302 PASS computedStyle("background-color", "lch(from var(--mygray) l 30 h)") is "lch(62.751923% 30 326.96112)"
    303247PASS successfullyParsed is true
    304248
  • trunk/LayoutTests/fast/css/parsing-relative-color-syntax.html

    r278268 r278290  
    22<html>
    33    <script src="../../resources/js-test-pre.js"></script>
    4     <style>
    5         html {
    6             --bg-color: blue;
    7             --color: green;
    8             --accent: lightseagreen;
    9             --mycolor: orchid;
    10             --mygray: lch(from var(--mycolor) l 0 h);
    11         }
    12     </style>
    134</head>
    145<body>
     
    10596    testComputed(`rgb(from rgb(10%, 20%, 30%, 40%) r g 25 / 25%)`, `rgba(26, 51, 25, 0.25)`);
    10697
    107     // Testing permutation.
    108     testComputed(`rgb(from rebeccapurple g b r)`, `rgb(51, 153, 102)`);
    109     testComputed(`rgb(from rebeccapurple b alpha r / g)`, `rgba(153, 255, 102, 0.2)`);
    110     testComputed(`rgb(from rebeccapurple r r r / r)`, `rgba(102, 102, 102, 0.4)`);
    111     testComputed(`rgb(from rebeccapurple alpha alpha alpha / alpha)`, `rgb(255, 255, 255)`);
    112     testComputed(`rgb(from rgb(10%, 20%, 30%, 40%) g b r)`, `rgb(51, 77, 26)`);
    113     testComputed(`rgb(from rgb(10%, 20%, 30%, 40%) b alpha r / g)`, `rgba(77, 102, 26, 0.2)`);
    114     testComputed(`rgb(from rgb(10%, 20%, 30%, 40%) r r r / r)`, `rgba(26, 26, 26, 0.1)`);
    115     testComputed(`rgb(from rgb(10%, 20%, 30%, 40%) alpha alpha alpha / alpha)`, `rgba(102, 102, 102, 0.4)`);
    116 
    117     // Testing mixes of number and percentage. (These would not be allowed in the non-relative syntax).
    118     testComputed(`rgb(from rebeccapurple r 10% 10)`, `rgb(102, 26, 10)`);
    119     testComputed(`rgb(from rebeccapurple r 10 10%)`, `rgb(102, 10, 26)`);
    120     testComputed(`rgb(from rebeccapurple 0% 10 10)`, `rgb(0, 10, 10)`);
    121     testComputed(`rgb(from rgb(10%, 20%, 30%, 40%) r 10% 10)`, `rgb(26, 26, 10)`);
    122     testComputed(`rgb(from rgb(10%, 20%, 30%, 40%) r 10 10%)`, `rgb(26, 10, 26)`);
    123     testComputed(`rgb(from rgb(10%, 20%, 30%, 40%) 0% 10 10)`, `rgb(0, 10, 10)`);
    124 
    125     // Testing with calc().
    126     testComputed(`rgb(from rebeccapurple calc(r) calc(g) calc(b))`, `rgb(102, 51, 153)`);
    127     testComputed(`rgb(from rebeccapurple r calc(g * .5) 10)`, `rgb(102, 26, 10)`);
    128     testComputed(`rgb(from rebeccapurple r calc(b * .5) 10)`, `rgb(102, 77, 10)`);
    129     testComputed(`rgb(from rebeccapurple r calc(b * .5 + g * .5) 10)`, `rgb(102, 102, 10)`);
    130     testComputed(`rgb(from rebeccapurple r calc(b * .5 - g * .5) 10)`, `rgb(102, 51, 10)`);
    131     testComputed(`rgb(from rebeccapurple r calc(b * .5 - g * .5) 10)`, `rgb(102, 51, 10)`);
    132     testComputed(`rgb(from rgb(10%, 20%, 30%, 40%) calc(r) calc(g) calc(b) / calc(alpha))`, `rgba(26, 51, 77, 0.4)`);
     98    // Testing permutation (unclear if this is allowed per-spec, we disallow it).
     99    testComputed(`rgb(from rebeccapurple g b r)`, `rgba(0, 0, 0, 0)`);
     100    testComputed(`rgb(from rebeccapurple b alpha r / g)`, `rgba(0, 0, 0, 0)`);
     101    testComputed(`rgb(from rebeccapurple r r r / r)`, `rgba(0, 0, 0, 0)`);
     102    testComputed(`rgb(from rebeccapurple alpha alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`);
     103    testComputed(`rgb(from rgb(10%, 20%, 30%, 40%) g b r)`, `rgba(0, 0, 0, 0)`);
     104    testComputed(`rgb(from rgb(10%, 20%, 30%, 40%) b alpha r / g)`, `rgba(0, 0, 0, 0)`);
     105    testComputed(`rgb(from rgb(10%, 20%, 30%, 40%) r r r / r)`, `rgba(0, 0, 0, 0)`);
     106    testComputed(`rgb(from rgb(10%, 20%, 30%, 40%) alpha alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`);
     107
     108    // Testing invalid mixes of number and percentage
     109    testComputed(`rgb(from rebeccapurple r 10% 10)`, `rgba(0, 0, 0, 0)`);
     110    testComputed(`rgb(from rebeccapurple r 10 10%)`, `rgba(0, 0, 0, 0)`);
     111    testComputed(`rgb(from rebeccapurple 0% 10 10)`, `rgba(0, 0, 0, 0)`);
     112    testComputed(`rgb(from rgb(10%, 20%, 30%, 40%) r 10% 10)`, `rgba(0, 0, 0, 0)`);
     113    testComputed(`rgb(from rgb(10%, 20%, 30%, 40%) r 10 10%)`, `rgba(0, 0, 0, 0)`);
     114    testComputed(`rgb(from rgb(10%, 20%, 30%, 40%) 0% 10 10)`, `rgba(0, 0, 0, 0)`);
    133115
    134116    // Testing invalid component names
     
    180162    testComputed(`hsl(from rgb(10%, 20%, 30%, 40%) h s l / .25)`, `rgba(26, 51, 77, 0.25)`);
    181163
    182     // Testing valid permutation (types match).
    183     testComputed(`hsl(from rebeccapurple h l s)`, `rgb(128, 77, 179)`);
    184     testComputed(`hsl(from rebeccapurple h alpha l / s)`, `rgba(102, 0, 204, 0.5)`);
    185     testComputed(`hsl(from rebeccapurple h l l / l)`, `rgba(102, 61, 143, 0.4)`);
    186     testComputed(`hsl(from rebeccapurple h alpha alpha / alpha)`, `rgb(255, 255, 255)`);
    187     testComputed(`hsl(from rgb(10%, 20%, 30%, 40%) h l s)`, `rgb(101, 126, 152)`);
    188     testComputed(`hsl(from rgb(10%, 20%, 30%, 40%) h alpha l / s)`, `rgba(31, 51, 72, 0.494)`);
    189     testComputed(`hsl(from rgb(10%, 20%, 30%, 40%) h l l / l)`, `rgba(41, 51, 62, 0.204)`);
    190     testComputed(`hsl(from rgb(10%, 20%, 30%, 40%) h alpha alpha / alpha)`, `rgba(61, 101, 143, 0.4)`);
    191 
    192     // Testing invalid permutation (types don't match).
    193     testComputed(`hsl(from rebeccapurple s h l)`, `rgba(0, 0, 0, 0)`);
    194     testComputed(`hsl(from rebeccapurple s s s / s)`, `rgba(0, 0, 0, 0)`);
    195     testComputed(`hsl(from rebeccapurple h h h / h)`, `rgba(0, 0, 0, 0)`);
    196     testComputed(`hsl(from rebeccapurple alpha alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`);
    197     testComputed(`hsl(from rgb(10%, 20%, 30%, 40%) s h l)`, `rgba(0, 0, 0, 0)`);
    198     testComputed(`hsl(from rgb(10%, 20%, 30%, 40%) s s s / s)`, `rgba(0, 0, 0, 0)`);
    199     testComputed(`hsl(from rgb(10%, 20%, 30%, 40%) h h h / h)`, `rgba(0, 0, 0, 0)`);
    200     testComputed(`hsl(from rgb(10%, 20%, 30%, 40%) alpha alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`);
    201 
    202     // Testing with calc().
    203     testComputed(`hsl(from rebeccapurple calc(h) calc(s) calc(l))`, `rgb(102, 51, 153)`);
    204     testComputed(`hsl(from rgb(10%, 20%, 30%, 40%) calc(h) calc(s) calc(l) / calc(alpha))`, `rgba(26, 51, 77, 0.4)`);
     164    // Testing permutation (unclear if this is allowed per-spec, we disallow it).
     165    testComputed(`hsl(from rebeccapurple h l s)`, `rgba(0, 0, 0, 0)`);
     166    testComputed(`hsl(from rebeccapurple h alpha l / s)`, `rgba(0, 0, 0, 0)`);
     167    testComputed(`hsl(from rebeccapurple h l l / l)`, `rgba(0, 0, 0, 0)`);
     168    testComputed(`hsl(from rebeccapurple h alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`);
     169    testComputed(`hsl(from rgb(10%, 20%, 30%, 40%) h l s)`, `rgba(0, 0, 0, 0)`);
     170    testComputed(`hsl(from rgb(10%, 20%, 30%, 40%) h alpha l / s)`, `rgba(0, 0, 0, 0)`);
     171    testComputed(`hsl(from rgb(10%, 20%, 30%, 40%) h l l / l)`, `rgba(0, 0, 0, 0)`);
     172    testComputed(`hsl(from rgb(10%, 20%, 30%, 40%) h alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`);
    205173
    206174    // Testing invalid values.
     
    261229    testComputed(`hwb(from rgb(10%, 20%, 30%, 40%) h w b / .25)`, `rgba(26, 51, 77, 0.25)`);
    262230
    263     // Testing valid permutation (types match).
    264     testComputed(`hwb(from rebeccapurple h b w)`, `rgb(153, 102, 204)`);
    265     testComputed(`hwb(from rebeccapurple h alpha w / b)`, `rgba(213, 213, 213, 0.4)`);
    266     testComputed(`hwb(from rebeccapurple h w w / w)`, `rgba(128, 51, 204, 0.2)`);
    267     testComputed(`hwb(from rebeccapurple h alpha alpha / alpha)`, `rgb(128, 128, 128)`);
    268     testComputed(`hwb(from rgb(10%, 20%, 30%, 40%) h b w)`, `rgb(178, 203, 229)`);
    269     testComputed(`hwb(from rgb(10%, 20%, 30%, 40%) h alpha w / b)`, `rgba(102, 164, 229, 0.698)`);
    270     testComputed(`hwb(from rgb(10%, 20%, 30%, 40%) h w w / w)`, `rgba(26, 126, 229, 0.1)`);
    271     testComputed(`hwb(from rgb(10%, 20%, 30%, 40%) h alpha alpha / alpha)`, `rgba(102, 127, 153, 0.4)`);
    272 
    273     // Testing invalid permutation (types don't match).
    274     testComputed(`hwb(from rebeccapurple w h b)`, `rgba(0, 0, 0, 0)`);
    275     testComputed(`hwb(from rebeccapurple b b b / b)`, `rgba(0, 0, 0, 0)`);
    276     testComputed(`hwb(from rebeccapurple h h h / h)`, `rgba(0, 0, 0, 0)`);
    277     testComputed(`hwb(from rebeccapurple alpha alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`);
    278     testComputed(`hwb(from rgb(10%, 20%, 30%, 40%) w b h)`, `rgba(0, 0, 0, 0)`);
    279     testComputed(`hwb(from rgb(10%, 20%, 30%, 40%) b b b / b)`, `rgba(0, 0, 0, 0)`);
    280     testComputed(`hwb(from rgb(10%, 20%, 30%, 40%) h h h / h)`, `rgba(0, 0, 0, 0)`);
    281     testComputed(`hwb(from rgb(10%, 20%, 30%, 40%) alpha alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`);
    282 
    283     // Testing with calc().
    284     testComputed(`hwb(from rebeccapurple calc(h) calc(w) calc(b))`, `rgb(102, 51, 153)`);
    285     testComputed(`hwb(from rgb(10%, 20%, 30%, 40%) calc(h) calc(w) calc(b) / calc(alpha))`, `rgba(26, 51, 77, 0.4)`);
     231    // Testing permutation (unclear if this is allowed per-spec, we disallow it).
     232    testComputed(`hwb(from rebeccapurple h b w)`, `rgba(0, 0, 0, 0)`);
     233    testComputed(`hwb(from rebeccapurple h alpha w / b)`, `rgba(0, 0, 0, 0)`);
     234    testComputed(`hwb(from rebeccapurple h w w / w)`, `rgba(0, 0, 0, 0)`);
     235    testComputed(`hwb(from rebeccapurple h alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`);
     236    testComputed(`hwb(from rgb(10%, 20%, 30%, 40%) h b w)`, `rgba(0, 0, 0, 0)`);
     237    testComputed(`hwb(from rgb(10%, 20%, 30%, 40%) h alpha w / b)`, `rgba(0, 0, 0, 0)`);
     238    testComputed(`hwb(from rgb(10%, 20%, 30%, 40%) h w w / w)`, `rgba(0, 0, 0, 0)`);
     239    testComputed(`hwb(from rgb(10%, 20%, 30%, 40%) h alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`);
    286240
    287241    // Testing invalid values.
     
    335289    testComputed(`lab(from lab(25% 20 50 / 40%) l a b / .35)`, `lab(25% 20 50 / 0.35)`);
    336290
    337     // Testing valid permutation (types match).
    338     testComputed(`lab(from lab(25% 20 50) l b a)`, `lab(25% 50 20)`);
    339     testComputed(`lab(from lab(25% 20 50) l a a / a)`, `lab(25% 20 20)`);
    340     testComputed(`lab(from lab(25% 20 50 / 40%) l b a)`, `lab(25% 50 20)`);
    341     testComputed(`lab(from lab(25% 20 50 / 40%) l a a / a)`, `lab(25% 20 20)`);
    342 
    343     // Testing invalid permutation (types don't match).
     291    // Testing permutation (unclear if this is allowed per-spec, we disallow it).
     292    testComputed(`lab(from lab(25% 20 50) l b a)`, `rgba(0, 0, 0, 0)`);
    344293    testComputed(`lab(from lab(25% 20 50) l alpha a / b)`, `rgba(0, 0, 0, 0)`);
     294    testComputed(`lab(from lab(25% 20 50) l a a / a)`, `rgba(0, 0, 0, 0)`);
    345295    testComputed(`lab(from lab(25% 20 50) l alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`);
     296    testComputed(`lab(from lab(25% 20 50 / 40%) l b a)`, `rgba(0, 0, 0, 0)`);
    346297    testComputed(`lab(from lab(25% 20 50 / 40%) l alpha a / b)`, `rgba(0, 0, 0, 0)`);
     298    testComputed(`lab(from lab(25% 20 50 / 40%) l a a / a)`, `rgba(0, 0, 0, 0)`);
    347299    testComputed(`lab(from lab(25% 20 50 / 40%) l alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`);
    348 
    349     // Testing with calc().
    350     testComputed(`lab(from lab(25% 20 50) calc(l) calc(a) calc(b))`, `lab(25% 20 50)`);
    351     testComputed(`lab(from lab(25% 20 50 / 40%) calc(l) calc(a) calc(b) / calc(alpha))`, `lab(25% 20 50 / 0.4)`);
    352300
    353301    // Testing invalid values.
     
    408356    testComputed(`lch(from lch(70% 45 30 / 40%) l c h / .25)`, `lch(70% 45 30 / 0.25)`);
    409357
    410     // Testing valid permutation (types match).
    411     // NOTE: 'c' is a vaild hue, as hue is <angle>|<number>.
    412     testComputed(`lch(from lch(70% 45 30) alpha c h / l)`, `lch(100% 45 30 / 0.7)`);
    413     testComputed(`lch(from lch(70% 45 30) l c c / alpha)`, `lch(70% 45 45)`);
    414     testComputed(`lch(from lch(70% 45 30) alpha c h / alpha)`, `lch(100% 45 30)`);
    415     testComputed(`lch(from lch(70% 45 30) alpha c c / alpha)`, `lch(100% 45 45)`);
    416     testComputed(`lch(from lch(70% 45 30 / 40%) alpha c h / l)`, `lch(40% 45 30 / 0.7)`);
    417     testComputed(`lch(from lch(70% 45 30 / 40%) l c c / alpha)`, `lch(70% 45 45 / 0.4)`);
    418     testComputed(`lch(from lch(70% 45 30 / 40%) alpha c h / alpha)`, `lch(40% 45 30 / 0.4)`);
    419     testComputed(`lch(from lch(70% 45 30 / 40%) alpha c c / alpha)`, `lch(40% 45 45 / 0.4)`);
    420 
    421     // Testing invalid permutation (types don't match).
    422     testComputed(`lch(from lch(70% 45 30) h l c / alpha)`, `rgba(0, 0, 0, 0)`);
    423     testComputed(`lch(from lch(70% 45 30) c c c / c)`, `rgba(0, 0, 0, 0)`);
    424     testComputed(`lch(from lch(70% 45 30) alpha alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`);
    425     testComputed(`lch(from lch(70% 45 30 / 40%) h l c / alpha)`, `rgba(0, 0, 0, 0)`);
    426     testComputed(`lch(from lch(70% 45 30 / 40%) c c c / c)`, `rgba(0, 0, 0, 0)`);
    427     testComputed(`lch(from lch(70% 45 30 / 40%) alpha alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`);
    428 
    429     // Testing with calc().
    430     testComputed(`lch(from lch(70% 45 30) calc(l) calc(c) calc(h))`, `lch(70% 45 30)`);
    431     testComputed(`lch(from lch(70% 45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))`, `lch(70% 45 30 / 0.4)`);
     358    // Testing permutation (unclear if this is allowed per-spec, we disallow it).
     359    testComputed(`lch(from lch(70% 45 30) alpha c h / l)`, `rgba(0, 0, 0, 0)`);
     360    testComputed(`lch(from lch(70% 45 30) alpha c h / alpha)`, `rgba(0, 0, 0, 0)`);
     361    testComputed(`lch(from lch(70% 45 30 / 40%) alpha c h / l)`, `rgba(0, 0, 0, 0)`);
     362    testComputed(`lch(from lch(70% 45 30 / 40%) alpha c h / alpha)`, `rgba(0, 0, 0, 0)`);
    432363
    433364    // Testing invalid values.
     
    443374    testComputed(`lch(from lch(70% 45 30) x c h)`, `rgba(0, 0, 0, 0)`);
    444375    testComputed(`lch(from lch(70% 45 30) l g b)`, `rgba(0, 0, 0, 0)`);
    445 
    446 
    447     // Spec examples:
    448     // Example 11.
    449     testComputed(`rgb(from var(--bg-color) r g b / 80%)`, `rgba(0, 0, 255, 0.8)`);
    450    
    451     // Example 12.
    452     testComputed(`lch(from var(--color) calc(l / 2) c h)`, `lch(23.138971% 67.989716 134.39125)`);
    453    
    454     // Example 13.
    455     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)`)
    456     testComputed(`lch(from var(--color) l 0 h)`, `lch(46.277943% 0 134.39125)`)
    457 
    458     // Example 14.
    459     testComputed(`rgb(from indianred 255 g b)`, `rgb(255, 92, 92)`);
    460 
    461     // Example 15.
    462     testComputed(`hsl(from var(--accent) calc(h + 180deg) s l)`, `rgb(178, 32, 40)`);
    463 
    464     // Example 16.
    465     testComputed(`lab(from var(--mycolor) l a b / 100%)`, `lab(62.751923% 52.45802 -34.117283)`);
    466     testComputed(`lab(from var(--mycolor) l a b / calc(alpha * 0.8))`, `lab(62.751923% 52.45802 -34.117283 / 0.8)`);
    467     testComputed(`lab(from var(--mycolor) l a b / calc(alpha - 20%))`, `lab(62.751923% 52.45802 -34.117283 / 0.8)`);
    468    
    469     // Example 17.
    470     testComputed(`lab(from var(--mycolor) l 0 0)`, `lab(62.751923% 0 0)`);
    471 
    472     // Example 18.
    473     testComputed(`lch(from peru calc(l * 0.8) c h)`, `lch(49.80138% 54.003296 63.680317)`);
    474 
    475     // Example 19.
    476     testComputed(`LCH(from var(--accent) l c calc(h + 180deg))`, `lch(65.49473% 39.446903 10.114471)`);
    477 
    478     // Example 20.
    479     testComputed(`lch(from var(--mycolor) l 0 h)`, `lch(62.751923% 0 326.96112)`);
    480     testComputed(`var(--mygray)`, `lch(62.751923% 0 326.96112)`);
    481     testComputed(`lch(from var(--mygray) l 30 h)`, `lch(62.751923% 30 326.96112)`);
    482    
    483376</script>
    484377   
  • trunk/Source/WebCore/ChangeLog

    r278289 r278290  
     12021-05-31  Commit Queue  <commit-queue@webkit.org>
     2
     3        Unreviewed, reverting r278261.
     4        https://bugs.webkit.org/show_bug.cgi?id=226477
     5
     6        Broke windows build
     7
     8        Reverted changeset:
     9
     10        "Support calc() on components inside relative color syntax
     11        colors"
     12        https://bugs.webkit.org/show_bug.cgi?id=226272
     13        https://trac.webkit.org/changeset/278261
     14
    1152021-05-31  Chris Dumez  <cdumez@apple.com>
    216
  • trunk/Source/WebCore/Sources.txt

    r278261 r278290  
    832832css/calc/CSSCalcOperationNode.cpp
    833833css/calc/CSSCalcPrimitiveValueNode.cpp
    834 css/calc/CSSCalcSymbolTable.cpp
    835834css/calc/CSSCalcValue.cpp
    836835css/parser/CSSAtRuleID.cpp
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r278261 r278290  
    40784078                BC6D44ED0C07F2ED0072D2C9 /* JSHTMLEmbedElement.h in Headers */ = {isa = PBXBuildFile; fileRef = BC6D44EB0C07F2ED0072D2C9 /* JSHTMLEmbedElement.h */; };
    40794079                BC6D6E2609AF943500F59759 /* ScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = BC6D6E2509AF943500F59759 /* ScrollView.h */; settings = {ATTRIBUTES = (Private, ); }; };
    4080                 BC709DE0266323CF00B9A21C /* CSSCalcSymbolTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BC709DDE266323CE00B9A21C /* CSSCalcSymbolTable.h */; };
    40814080                BC772B3C0C4EA91E0083285F /* CSSHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = BC772B360C4EA91E0083285F /* CSSHelper.h */; settings = {ATTRIBUTES = (Private, ); }; };
    40824081                BC772C470C4EB2C60083285F /* XMLHttpRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = BC772C450C4EB2C60083285F /* XMLHttpRequest.h */; };
     
    1430614305                BC6D6E2509AF943500F59759 /* ScrollView.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ScrollView.h; sourceTree = "<group>"; };
    1430714306                BC6EB84526266B61003225A7 /* ColorLuminance.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ColorLuminance.cpp; sourceTree = "<group>"; };
    14308                 BC709DDE266323CE00B9A21C /* CSSCalcSymbolTable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSSCalcSymbolTable.h; sourceTree = "<group>"; };
    14309                 BC709DDF266323CE00B9A21C /* CSSCalcSymbolTable.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CSSCalcSymbolTable.cpp; sourceTree = "<group>"; };
    1431014307                BC772B360C4EA91E0083285F /* CSSHelper.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSSHelper.h; sourceTree = "<group>"; };
    1431114308                BC772C440C4EB2C60083285F /* XMLHttpRequest.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = XMLHttpRequest.cpp; sourceTree = "<group>"; };
     
    2796027957                                BCF164542662A1220002F7EF /* CSSCalcPrimitiveValueNode.cpp */,
    2796127958                                BCF164532662A1220002F7EF /* CSSCalcPrimitiveValueNode.h */,
    27962                                 BC709DDF266323CE00B9A21C /* CSSCalcSymbolTable.cpp */,
    27963                                 BC709DDE266323CE00B9A21C /* CSSCalcSymbolTable.h */,
    2796427959                                49AE2D8C134EE50C0072920A /* CSSCalcValue.cpp */,
    2796527960                                49AE2D8D134EE50C0072920A /* CSSCalcValue.h */,
     
    3467534670                                BCAA487014A052530088FAC4 /* PlatformEventFactoryMac.h in Headers */,
    3467634671                                A723F77B1484CA4C008C6DBE /* PlatformExportMacros.h in Headers */,
    34677                                 BC709DE0266323CF00B9A21C /* CSSCalcSymbolTable.h in Headers */,
    3467834672                                515BE1951D54F5FB00DD7C68 /* PlatformGamepad.h in Headers */,
    3467934673                                726D56E2253AE28D0002EF90 /* PlatformImage.h in Headers */,
  • trunk/Source/WebCore/css/calc/CSSCalcExpressionNodeParser.cpp

    r278261 r278290  
    3232#include "CSSCalcOperationNode.h"
    3333#include "CSSCalcPrimitiveValueNode.h"
    34 #include "CSSCalcSymbolTable.h"
    3534#include "CSSCalcValue.h"
    3635#include "CSSParserToken.h"
    3736#include "CSSParserTokenRange.h"
    38 #include "CSSValueKeywords.h"
    3937#include "Logging.h"
    4038
     
    183181bool CSSCalcExpressionNodeParser::parseValue(CSSParserTokenRange& tokens, RefPtr<CSSCalcExpressionNode>& result)
    184182{
    185     auto makeCSSCalcPrimitiveValueNode = [&] (CSSUnitType type, double value) -> bool {
    186         if (calcUnitCategory(type) == CalculationCategory::Other)
    187             return false;
    188        
    189         result = CSSCalcPrimitiveValueNode::create(CSSPrimitiveValue::create(value, type));
    190         return true;
    191     };
    192 
    193     auto token = tokens.consumeIncludingWhitespace();
    194 
    195     switch (token.type()) {
    196     case IdentToken: {
    197         auto value = m_symbolTable.get(token.id());
    198         if (!value)
    199             return false;
    200         return makeCSSCalcPrimitiveValueNode(value->type, value->value);
    201     }
    202 
    203     case NumberToken:
    204     case PercentageToken:
    205     case DimensionToken:
    206         return makeCSSCalcPrimitiveValueNode(token.unitType(), token.numericValue());
    207 
    208     default:
    209         return false;
    210     }
    211 
    212     ASSERT_NOT_REACHED();
    213     return false;
     183    // FIXME: Add code here to parse CSSValidID for named constants.
     184
     185    CSSParserToken token = tokens.consumeIncludingWhitespace();
     186    if (!(token.type() == NumberToken || token.type() == PercentageToken || token.type() == DimensionToken))
     187        return false;
     188   
     189    auto type = token.unitType();
     190    if (calcUnitCategory(type) == CalculationCategory::Other)
     191        return false;
     192   
     193    result = CSSCalcPrimitiveValueNode::create(CSSPrimitiveValue::create(token.numericValue(), type));
     194   
     195    return true;
    214196}
    215197
  • trunk/Source/WebCore/css/calc/CSSCalcExpressionNodeParser.h

    r278261 r278290  
    2626#pragma once
    2727
     28#include "CSSValueKeywords.h"
    2829#include "CalcOperator.h"
    2930#include "CalculationCategory.h"
     
    3233
    3334class CSSCalcExpressionNode;
    34 class CSSCalcSymbolTable;
    3535class CSSParserToken;
    3636class CSSParserTokenRange;
    3737
    38 enum CSSValueID : uint16_t;
    39 
    4038class CSSCalcExpressionNodeParser {
    4139public:
    42     explicit CSSCalcExpressionNodeParser(CalculationCategory destinationCategory, const CSSCalcSymbolTable& symbolTable)
     40    explicit CSSCalcExpressionNodeParser(CalculationCategory destinationCategory)
    4341        : m_destinationCategory(destinationCategory)
    44         , m_symbolTable(symbolTable)
    4542    {
    4643    }
     
    5956
    6057    CalculationCategory m_destinationCategory;
    61     const CSSCalcSymbolTable& m_symbolTable;
    6258};
    6359
  • trunk/Source/WebCore/css/calc/CSSCalcValue.cpp

    r278283 r278290  
    4242#include "CSSParserTokenRange.h"
    4343#include "CSSPrimitiveValueMappings.h"
    44 #include "CSSValueKeywords.h"
    4544#include "CalcExpressionBlendLength.h"
    4645#include "CalcExpressionInversion.h"
     
    306305}
    307306
    308 RefPtr<CSSCalcValue> CSSCalcValue::create(CSSValueID function, const CSSParserTokenRange& tokens, CalculationCategory destinationCategory, ValueRange range, const CSSCalcSymbolTable& symbolTable)
    309 {
    310     CSSCalcExpressionNodeParser parser(destinationCategory, symbolTable);
     307RefPtr<CSSCalcValue> CSSCalcValue::create(CSSValueID function, const CSSParserTokenRange& tokens, CalculationCategory destinationCategory, ValueRange range)
     308{
     309    CSSCalcExpressionNodeParser parser(destinationCategory);
    311310    auto expression = parser.parseCalc(tokens, function);
    312311    if (!expression)
     
    316315    return result;
    317316}
    318 
    319 RefPtr<CSSCalcValue> CSSCalcValue::create(CSSValueID function, const CSSParserTokenRange& tokens, CalculationCategory destinationCategory, ValueRange range)
    320 {
    321     return create(function, tokens, destinationCategory, range, { });
    322 }
    323 
     317   
    324318RefPtr<CSSCalcValue> CSSCalcValue::create(const CalculationValue& value, const RenderStyle& style)
    325319{
  • trunk/Source/WebCore/css/calc/CSSCalcValue.h

    r278261 r278290  
    3232
    3333#include "CSSValue.h"
     34#include "CSSValueKeywords.h"
    3435#include "CalculationValue.h"
    3536#include <wtf/Forward.h>
     
    3940
    4041class CSSCalcExpressionNode;
    41 class CSSCalcSymbolTable;
    4242class CSSParserTokenRange;
    4343class CSSToLengthConversionData;
     
    4848enum class ValueRange : uint8_t;
    4949
    50 enum CSSValueID : uint16_t;
    51 
    5250class CSSCalcValue final : public CSSValue {
    5351public:
    54     static RefPtr<CSSCalcValue> create(CSSValueID function, const CSSParserTokenRange&, CalculationCategory destinationCategory, ValueRange, const CSSCalcSymbolTable&);
    5552    static RefPtr<CSSCalcValue> create(CSSValueID function, const CSSParserTokenRange&, CalculationCategory destinationCategory, ValueRange);
    5653    static RefPtr<CSSCalcValue> create(const CalculationValue&, const RenderStyle&);
  • trunk/Source/WebCore/css/makevalues.pl

    r278261 r278290  
    165165#include <string.h>
    166166#include <wtf/Forward.h>
    167 #include <wtf/HashFunctions.h>
    168 #include <wtf/HashTraits.h>
    169167
    170168namespace WebCore {
    171169
    172 enum CSSValueID : uint16_t {
     170enum CSSValueID {
    173171    CSSValueInvalid = 0,
    174172EOF
     
    207205
    208206} // namespace WebCore
    209 
    210 namespace WTF {
    211 template<> struct DefaultHash<WebCore::CSSValueID> : IntHash<unsigned> { };
    212 template<> struct HashTraits<WebCore::CSSValueID> : StrongEnumHashTraits<WebCore::CSSValueID> { };
    213 } // namespace WTF
    214 
    215207EOF
    216208close HEADER;
  • trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp

    r278269 r278290  
    3131#include "CSSPropertyParserHelpers.h"
    3232
    33 #include "CSSCalcSymbolTable.h"
    3433#include "CSSCalcValue.h"
    3534#include "CSSCanvasValue.h"
     
    101100class CalcParser {
    102101public:
    103     explicit CalcParser(CSSParserTokenRange& range, CalculationCategory destinationCategory, ValueRange valueRange = ValueRange::All, const CSSCalcSymbolTable& symbolTable = { }, CSSValuePool& cssValuePool = CSSValuePool::singleton())
     102    explicit CalcParser(CSSParserTokenRange& range, CalculationCategory destinationCategory, ValueRange valueRange = ValueRange::All, CSSValuePool& cssValuePool = CSSValuePool::singleton())
    104103        : m_sourceRange(range)
    105104        , m_range(range)
     
    109108        auto functionId = token.functionId();
    110109        if (CSSCalcValue::isCalcFunction(functionId))
    111             m_calcValue = CSSCalcValue::create(functionId, consumeFunction(m_range), destinationCategory, valueRange, symbolTable);
     110            m_calcValue = CSSCalcValue::create(functionId, consumeFunction(m_range), destinationCategory, valueRange);
    112111    }
    113112
     
    117116    {
    118117        if (!m_calcValue)
    119             return nullptr;
    120         m_sourceRange = m_range;
    121         return m_valuePool.createValue(WTFMove(m_calcValue));
    122     }
    123 
    124     RefPtr<CSSPrimitiveValue> consumeValueIfCategory(CalculationCategory category)
    125     {
    126         if (!m_calcValue || m_calcValue->category() != category)
    127118            return nullptr;
    128119        m_sourceRange = m_range;
     
    228219
    229220    CalcParser calcParser(range, CalculationCategory::Number);
    230     if (auto calculation = calcParser.value(); calculation && calculation->category() == CalculationCategory::Number)
     221    if (const CSSCalcValue* calculation = calcParser.value()) {
     222        if (calculation->category() != CalculationCategory::Number)
     223            return std::nullopt;
    231224        return calcParser.consumeIntegerTypeRaw<IntType>(minimumValue);
     225    }
    232226
    233227    return std::nullopt;
     
    280274    if (token.type() == FunctionToken) {
    281275        CalcParser calcParser(range, CalculationCategory::Number, valueRange);
    282         return calcParser.consumeValueIfCategory(CalculationCategory::Number);
     276        if (const auto* calcValue = calcParser.value()) {
     277            if (calcValue->category() == CalculationCategory::Number)
     278                return calcParser.consumeValue();
     279        }
     280        return nullptr;
    283281    }
    284282
     
    402400    if (token.type() == FunctionToken) {
    403401        CalcParser calcParser(range, CalculationCategory::Length, valueRange);
    404         return calcParser.consumeValueIfCategory(CalculationCategory::Length);
     402        if (calcParser.value() && calcParser.value()->category() == CalculationCategory::Length)
     403            return calcParser.consumeValue();
    405404    }
    406405
     
    436435    const CSSParserToken& token = range.peek();
    437436    if (token.type() == FunctionToken) {
    438         CalcParser calcParser(range, CalculationCategory::Percent, valueRange, { }, cssValuePool);
    439         return calcParser.consumeValueIfCategory(CalculationCategory::Percent);
     437        CalcParser calcParser(range, CalculationCategory::Percent, valueRange, cssValuePool);
     438        if (const CSSCalcValue* calculation = calcParser.value()) {
     439            if (calculation->category() == CalculationCategory::Percent)
     440                return calcParser.consumeValue();
     441        }
     442        return nullptr;
    440443    }
    441444
     
    478481
    479482    CalcParser calcParser(range, CalculationCategory::Length, valueRange);
    480     if (auto calculation = calcParser.value(); calculation && canConsumeCalcValue(calculation->category(), cssParserMode))
    481         return calcParser.consumeLengthOrPercentRaw();
     483    if (const CSSCalcValue* calculation = calcParser.value()) {
     484        if (canConsumeCalcValue(calculation->category(), cssParserMode))
     485            return calcParser.consumeLengthOrPercentRaw();
     486    }
    482487    return std::nullopt;
    483488}
     
    488493    if (token.type() == FunctionToken) {
    489494        CalcParser calcParser(range, CalculationCategory::Length, valueRange);
    490         if (auto calculation = calcParser.value(); calculation && canConsumeCalcValue(calculation->category(), cssParserMode))
    491             return calcParser.consumeValue();
     495        if (const CSSCalcValue* calculation = calcParser.value()) {
     496            if (canConsumeCalcValue(calculation->category(), cssParserMode))
     497                return calcParser.consumeValue();
     498        }
    492499        return nullptr;
    493500    }
     
    538545    const CSSParserToken& token = range.peek();
    539546    if (token.type() == FunctionToken) {
    540         CalcParser calcParser(range, CalculationCategory::Angle, ValueRange::All, { }, cssValuePool);
    541         return calcParser.consumeValueIfCategory(CalculationCategory::Angle);
     547        CalcParser calcParser(range, CalculationCategory::Angle, ValueRange::All, cssValuePool);
     548        if (const CSSCalcValue* calculation = calcParser.value()) {
     549            if (calculation->category() == CalculationCategory::Angle)
     550                return calcParser.consumeValue();
     551        }
     552        return nullptr;
    542553    }
    543554
     
    551562{
    552563    const CSSParserToken& token = range.peek();
    553     switch (token.type()) {
    554     case DimensionToken:
     564    if (token.type() == DimensionToken) {
    555565        switch (token.unitType()) {
    556566        case CSSUnitType::CSS_DEG:
     
    560570            return CSSValuePool::singleton().createValue(range.consumeIncludingWhitespace().numericValue(), token.unitType());
    561571        default:
    562             break;
    563         }
    564         break;
    565    
    566     case NumberToken:
    567         if (shouldAcceptUnitlessValue(token.numericValue(), cssParserMode, unitless, unitlessZero))
    568             return CSSValuePool::singleton().createValue(range.consumeIncludingWhitespace().numericValue(), CSSUnitType::CSS_DEG);
    569         break;
    570 
    571     case PercentageToken:
     572            return nullptr;
     573        }
     574    }
     575    if (token.type() == NumberToken && shouldAcceptUnitlessValue(token.numericValue(), cssParserMode, unitless, unitlessZero))
     576        return CSSValuePool::singleton().createValue(range.consumeIncludingWhitespace().numericValue(), CSSUnitType::CSS_DEG);
     577
     578    if (token.type() == PercentageToken)
    572579        return consumePercent(range, valueRange);
    573580
    574     case FunctionToken: {
    575         CalcParser angleCalcParser(range, CalculationCategory::Angle, valueRange);
    576         if (const CSSCalcValue* calculation = angleCalcParser.value()) {
    577             if (calculation->category() == CalculationCategory::Angle)
    578                 return angleCalcParser.consumeValue();
    579         }
    580 
    581         CalcParser percentCalcParser(range, CalculationCategory::Percent, valueRange);
    582         if (const CSSCalcValue* calculation = percentCalcParser.value()) {
    583             if (calculation->category() == CalculationCategory::Percent)
    584                 return percentCalcParser.consumeValue();
    585         }
    586    
    587         break;
    588     }
    589    
    590     default:
    591         break;
    592     }
    593 
     581     if (token.type() != FunctionToken)
     582         return nullptr;
     583
     584    CalcParser angleCalcParser(range, CalculationCategory::Angle, valueRange);
     585    if (const CSSCalcValue* calculation = angleCalcParser.value()) {
     586        if (calculation->category() == CalculationCategory::Angle)
     587            return angleCalcParser.consumeValue();
     588    }
     589
     590    CalcParser percentCalcParser(range, CalculationCategory::Percent, valueRange);
     591    if (const CSSCalcValue* calculation = percentCalcParser.value()) {
     592        if (calculation->category() == CalculationCategory::Percent)
     593            return percentCalcParser.consumeValue();
     594    }
    594595    return nullptr;
    595596}
     
    614615
    615616    CalcParser calcParser(range, CalculationCategory::Time, valueRange);
    616     return calcParser.consumeValueIfCategory(CalculationCategory::Time);
     617    if (const CSSCalcValue* calculation = calcParser.value()) {
     618        if (calculation->category() == CalculationCategory::Time)
     619            return calcParser.consumeValue();
     620    }
     621    return nullptr;
    617622}
    618623
     
    740745
    741746    if (auto alphaParameter = consumeNumberOrPercentDividedBy100Raw(range))
    742         return std::clamp(*alphaParameter, 0.0, 1.0);
     747        return clampTo(*alphaParameter, 0.0, 1.0);
    743748
    744749    return std::nullopt;
    745750}
    746751
    747 static std::optional<double> consumeOptionalAlphaOrIdent(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable)
    748 {
    749     if (!consumeSlashIncludingWhitespace(range))
    750         return 1.0;
    751 
    752     auto normalizePercent = [](double percent) {
    753         return std::clamp(percent / 100.0, 0.0, 1.0);
    754     };
    755 
    756     auto normalizeNumber = [](double alpha) {
    757         return std::clamp(alpha, 0.0, 1.0);
    758     };
    759 
    760     const CSSParserToken& token = range.peek();
    761 
    762     switch (token.type()) {
    763     case FunctionToken: {
    764         CalcParser percentageCalcParser(range, CalculationCategory::Percent, ValueRange::All, symbolTable);
    765         if (auto percent = percentageCalcParser.consumePercentRaw())
    766             return normalizePercent(*percent);
    767        
    768         CalcParser numberCalcParser(range, CalculationCategory::Number, ValueRange::All, symbolTable);
    769         if (auto number = numberCalcParser.consumeNumberRaw())
    770             return normalizeNumber(*number);
    771 
    772         return std::nullopt;
    773     }
    774 
    775     case PercentageToken:
    776         if (std::isinf(token.numericValue()))
    777             return std::nullopt;
    778         return normalizePercent(range.consumeIncludingWhitespace().numericValue());
    779 
    780     case NumberToken:
    781         return normalizeNumber(range.consumeIncludingWhitespace().numericValue());
    782 
    783     case IdentToken:
    784         if (auto variable = symbolTable.get(range.consumeIncludingWhitespace().id())) {
    785             switch (variable->type) {
    786             case CSSUnitType::CSS_PERCENTAGE:
    787                 return normalizePercent(variable->value);
    788 
    789             case CSSUnitType::CSS_NUMBER:
    790                 return normalizeNumber(variable->value);
    791 
    792             default:
    793                 return std::nullopt;
    794             }
    795         }
    796         return std::nullopt;
    797 
    798     default:
    799         return std::nullopt;
    800     }
    801 
    802     ASSERT_NOT_REACHED();
     752template<CSSValueID... allowedIdents> static std::optional<Variant<double, CSSValueID>> consumeOptionalAlphaOrIdent(CSSParserTokenRange& range)
     753{
     754    if (auto alpha = consumeOptionalAlpha(range))
     755        return { *alpha };
     756
     757    if (auto ident = consumeIdentRaw<allowedIdents...>(range))
     758        return { *ident };
     759
    803760    return std::nullopt;
    804761}
     
    812769}
    813770
    814 static std::optional<double> consumeHueOrIdent(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable)
    815 {
    816     const CSSParserToken& token = range.peek();
    817 
    818     switch (token.type()) {
    819     case FunctionToken: {
    820         CalcParser angleCalcParser(range, CalculationCategory::Angle, ValueRange::All, symbolTable);
    821         if (auto angle = angleCalcParser.consumeAngleRaw())
    822             return CSSPrimitiveValue::computeDegrees(angle->type, angle->value);
    823        
    824         CalcParser numberCalcParser(range, CalculationCategory::Number, ValueRange::All, symbolTable);
    825         return numberCalcParser.consumeNumberRaw();
    826     }
    827    
    828     case DimensionToken: {
    829         auto unitType = token.unitType();
    830         switch (unitType) {
    831         case CSSUnitType::CSS_DEG:
    832         case CSSUnitType::CSS_RAD:
    833         case CSSUnitType::CSS_GRAD:
    834         case CSSUnitType::CSS_TURN:
    835             return CSSPrimitiveValue::computeDegrees(unitType, range.consumeIncludingWhitespace().numericValue());
    836         default:
    837             return std::nullopt;
    838         }
    839     }
    840    
    841     case NumberToken:
    842         return range.consumeIncludingWhitespace().numericValue();
    843 
    844     case IdentToken:
    845         if (auto variable = symbolTable.get(range.consumeIncludingWhitespace().id())) {
    846             switch (variable->type) {
    847             case CSSUnitType::CSS_DEG:
    848             case CSSUnitType::CSS_RAD:
    849             case CSSUnitType::CSS_GRAD:
    850             case CSSUnitType::CSS_TURN:
    851                 return CSSPrimitiveValue::computeDegrees(variable->type, variable->value);
    852 
    853             case CSSUnitType::CSS_NUMBER:
    854                 return variable->value;
    855 
    856             default:
    857                 return std::nullopt;
    858             }
    859         }
    860         return std::nullopt;
    861 
     771template<CSSValueID... allowedIdents> static std::optional<Variant<double, CSSValueID>> consumeHueOrIdent(CSSParserTokenRange& range, const CSSParserContext& context)
     772{
     773    if (auto hue = consumeHue(range, context))
     774        return { *hue };
     775
     776    if (auto ident = consumeIdentRaw<allowedIdents...>(range))
     777        return { *ident };
     778
     779    return std::nullopt;
     780}
     781
     782static double normalizeHue(double hue)
     783{
     784    return std::fmod(std::fmod(hue, 360.0) + 360.0, 360.0);
     785}
     786
     787template<CSSValueID... allowedIdents> static std::optional<Variant<double, CSSValueID>> consumeNumberOrIdent(CSSParserTokenRange& range)
     788{
     789    if (auto number = consumeNumberRaw(range))
     790        return { *number };
     791
     792    if (auto ident = consumeIdentRaw<allowedIdents...>(range))
     793        return { *ident };
     794
     795    return std::nullopt;
     796}
     797
     798template<CSSValueID... allowedIdents> static std::optional<Variant<double, CSSValueID>> consumePercentOrIdent(CSSParserTokenRange& range)
     799{
     800    if (auto percent = consumePercentRaw(range))
     801        return { *percent };
     802
     803    if (auto ident = consumeIdentRaw<allowedIdents...>(range))
     804        return { *ident };
     805
     806    return std::nullopt;
     807}
     808
     809template<CSSValueID C1, CSSValueID C2, CSSValueID C3, CSSValueID AlphaChannel, typename ColorType> static auto extractChannelValue(CSSValueID channel, const ColorType& originColor) -> typename ColorType::ComponentType
     810{
     811    auto components = asColorComponents(originColor);
     812    switch (channel) {
     813    case C1:
     814        return components[0];
     815    case C2:
     816        return components[1];
     817    case C3:
     818        return components[2];
     819    case AlphaChannel:
     820        return components[3];
    862821    default:
    863         return std::nullopt;
    864     }
    865 
    866     ASSERT_NOT_REACHED();
    867     return std::nullopt;
    868 }
    869 
    870 static double normalizeHue(double hue)
    871 {
    872     return std::fmod(std::fmod(hue, 360.0) + 360.0, 360.0);
    873 }
    874 
    875 static std::optional<double> consumeNumberOrIdent(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable)
    876 {
    877     const CSSParserToken& token = range.peek();
    878 
    879     switch (token.type()) {
    880     case FunctionToken: {
    881         CalcParser calcParser(range, CalculationCategory::Number, ValueRange::All, symbolTable);
    882         return calcParser.consumeNumberRaw();
    883     }
    884 
    885     case NumberToken:
    886         return range.consumeIncludingWhitespace().numericValue();
    887 
    888     case IdentToken:
    889         if (auto variable = symbolTable.get(range.consumeIncludingWhitespace().id())) {
    890             switch (variable->type) {
    891             case CSSUnitType::CSS_NUMBER:
    892                 return variable->value;
    893 
    894             default:
    895                 return std::nullopt;
    896             }
    897         }
    898         return std::nullopt;
    899 
    900     default:
    901         return std::nullopt;
    902     }
    903 
    904     ASSERT_NOT_REACHED();
    905     return std::nullopt;
    906 }
    907 
    908 static std::optional<double> consumePercentOrIdent(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable)
    909 {
    910     const CSSParserToken& token = range.peek();
    911 
    912     switch (token.type()) {
    913     case FunctionToken: {
    914         CalcParser calcParser(range, CalculationCategory::Percent, ValueRange::All, symbolTable);
    915         return calcParser.consumePercentRaw();
    916     }
    917 
    918     case PercentageToken:
    919         if (std::isinf(token.numericValue()))
    920             return std::nullopt;
    921         return range.consumeIncludingWhitespace().numericValue();
    922 
    923     case IdentToken:
    924         if (auto variable = symbolTable.get(range.consumeIncludingWhitespace().id())) {
    925             switch (variable->type) {
    926             case CSSUnitType::CSS_PERCENTAGE:
    927                 return variable->value;
    928 
    929             default:
    930                 return std::nullopt;
    931             }
    932         }
    933         return std::nullopt;
    934 
    935     default:
    936         return std::nullopt;
    937     }
    938 
    939     ASSERT_NOT_REACHED();
    940     return std::nullopt;
     822        ASSERT_NOT_REACHED();
     823    }
     824
     825    return 0;
     826}
     827
     828template<CSSValueID C1, CSSValueID C2, CSSValueID C3, CSSValueID AlphaChannel, typename ColorType, typename ValueTransformer> static decltype(auto) resolveRelativeColorChannel(const Variant<double, CSSValueID>& parsedChannel, const ColorType& originColor, ValueTransformer&& valueTransformer)
     829{
     830    return switchOn(parsedChannel,
     831        [&] (double value) {
     832            return valueTransformer(value);
     833        },
     834        [&] (CSSValueID channel) {
     835            return extractChannelValue<C1, C2, C3, AlphaChannel>(channel, originColor);
     836        }
     837    );
     838}
     839
     840template<CSSValueID C1, CSSValueID C2, CSSValueID C3, CSSValueID AlphaChannel, typename ColorType> static decltype(auto) resolveRelativeColorChannel(const Variant<double, CSSValueID>& parsedChannel, const ColorType& originColor)
     841{
     842    return resolveRelativeColorChannel<C1, C2, C3, AlphaChannel>(parsedChannel, originColor, [](auto value) { return value; });
    941843}
    942844
    943845enum class RGBComponentType { Number, Percentage };
    944 
    945 static std::optional<uint8_t> consumeNumberOrPercentOrIdentNormalizedForRelativeRGB(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable)
    946 {
    947     auto normalizePercent = [](double percent) {
    948         return convertPrescaledSRGBAFloatToSRGBAByte(percent / 100.0 * 255.0);
    949     };
    950 
    951     auto normalizeNumber = [](double number) {
    952         return convertPrescaledSRGBAFloatToSRGBAByte(number);
    953     };
    954 
    955     const CSSParserToken& token = range.peek();
    956 
    957     switch (token.type()) {
    958     case FunctionToken: {
    959         CalcParser percentageCalcParser(range, CalculationCategory::Percent, ValueRange::All, symbolTable);
    960         if (auto percent = percentageCalcParser.consumePercentRaw())
    961             return normalizePercent(*percent);
    962        
    963         CalcParser numberCalcParser(range, CalculationCategory::Number, ValueRange::All, symbolTable);
    964         if (auto number = numberCalcParser.consumeNumberRaw())
    965             return normalizeNumber(*number);
    966        
    967         return std::nullopt;
    968     }
    969 
    970     case PercentageToken:
    971         if (std::isinf(token.numericValue()))
    972             return std::nullopt;
    973         return normalizePercent(range.consumeIncludingWhitespace().numericValue());
    974 
    975     case NumberToken:
    976         return normalizeNumber(range.consumeIncludingWhitespace().numericValue());
    977 
    978     case IdentToken:
    979         if (auto variable = symbolTable.get(range.consumeIncludingWhitespace().id())) {
    980             switch (variable->type) {
    981             case CSSUnitType::CSS_PERCENTAGE:
    982                 return normalizePercent(variable->value);
    983 
    984             case CSSUnitType::CSS_NUMBER:
    985                 return normalizeNumber(variable->value);
    986 
    987             default:
    988                 return std::nullopt;
    989             }
    990         }
    991         return std::nullopt;
    992 
    993     default:
    994         return std::nullopt;
    995     }
    996 
    997     ASSERT_NOT_REACHED();
    998     return std::nullopt;
    999 }
    1000846
    1001847static uint8_t clampRGBComponent(double value, RGBComponentType componentType)
     
    1077923        return { };
    1078924
    1079     auto originColorAsSRGB = originColor.toColorTypeLossy<SRGBA<float>>();
    1080 
    1081     CSSCalcSymbolTable symbolTable {
    1082         { CSSValueR, CSSUnitType::CSS_PERCENTAGE, originColorAsSRGB.red * 100.0 },
    1083         { CSSValueG, CSSUnitType::CSS_PERCENTAGE, originColorAsSRGB.green * 100.0 },
    1084         { CSSValueB, CSSUnitType::CSS_PERCENTAGE, originColorAsSRGB.blue * 100.0 },
    1085         { CSSValueAlpha, CSSUnitType::CSS_PERCENTAGE, originColorAsSRGB.alpha * 100.0 }
     925    std::optional<RGBComponentType> componentType;
     926    auto redResult = consumeRelativeRGBComponent<CSSValueR>(args, componentType);
     927    if (!redResult)
     928        return { };
     929    auto red = redResult->value;
     930    componentType = redResult->type;
     931
     932    auto greenResult = consumeRelativeRGBComponent<CSSValueG>(args, componentType);
     933    if (!greenResult)
     934        return { };
     935    auto green = greenResult->value;
     936    componentType = greenResult->type;
     937
     938    auto blueResult = consumeRelativeRGBComponent<CSSValueB>(args, componentType);
     939    if (!blueResult)
     940        return { };
     941    auto blue = blueResult->value;
     942    componentType = blueResult->type;
     943
     944    auto alpha = consumeOptionalAlphaOrIdent<CSSValueAlpha>(args);
     945    if (!alpha)
     946        return { };
     947
     948    if (!args.atEnd())
     949        return { };
     950
     951    // After parsing, convert identifiers to values from the origin color.
     952
     953    // FIXME: Do we want to being doing this in uint8_t values? Or should we use
     954    // higher precision and clamp at the end? It won't make a difference until we
     955    // support calculations on the origin's components.
     956    auto originColorAsSRGB = originColor.toSRGBALossy<uint8_t>();
     957
     958    auto resolvedComponentType = componentType.value_or(RGBComponentType::Percentage);
     959    auto channelResolver = [resolvedComponentType](auto value) {
     960        return clampRGBComponent(value, resolvedComponentType);
    1086961    };
    1087962
    1088     auto red = consumeNumberOrPercentOrIdentNormalizedForRelativeRGB(args, symbolTable);
    1089     if (!red)
    1090         return { };
    1091 
    1092     auto green = consumeNumberOrPercentOrIdentNormalizedForRelativeRGB(args, symbolTable);
    1093     if (!green)
    1094         return { };
    1095 
    1096     auto blue = consumeNumberOrPercentOrIdentNormalizedForRelativeRGB(args, symbolTable);
    1097     if (!blue)
    1098         return { };
    1099 
    1100     auto alpha = consumeOptionalAlphaOrIdent(args, symbolTable);
    1101     if (!alpha)
    1102         return { };
    1103 
    1104     if (!args.atEnd())
    1105         return { };
    1106 
    1107     auto normalizedAlpha = convertFloatAlphaTo<uint8_t>(*alpha);
    1108 
    1109     return SRGBA<uint8_t> { *red, *green, *blue, normalizedAlpha };
     963    auto resolvedRed = resolveRelativeColorChannel<CSSValueR, CSSValueG, CSSValueB, CSSValueAlpha>(red, originColorAsSRGB, channelResolver);
     964    auto resolvedGreen = resolveRelativeColorChannel<CSSValueR, CSSValueG, CSSValueB, CSSValueAlpha>(green, originColorAsSRGB, channelResolver);
     965    auto resolvedBlue = resolveRelativeColorChannel<CSSValueR, CSSValueG, CSSValueB, CSSValueAlpha>(blue, originColorAsSRGB, channelResolver);
     966    auto resolvedAlpha = resolveRelativeColorChannel<CSSValueR, CSSValueG, CSSValueB, CSSValueAlpha>(*alpha, originColorAsSRGB, [](auto value) {
     967        return convertFloatAlphaTo<uint8_t>(value);
     968    });
     969
     970    return SRGBA<uint8_t> { resolvedRed, resolvedGreen, resolvedBlue, resolvedAlpha };
    1110971}
    1111972
     
    11891050        return { };
    11901051
     1052    auto hue = consumeHueOrIdent<CSSValueH>(args, context);
     1053    if (!hue)
     1054        return { };
     1055
     1056    auto saturation = consumePercentOrIdent<CSSValueS>(args);
     1057    if (!saturation)
     1058        return { };
     1059
     1060    auto lightness = consumePercentOrIdent<CSSValueL>(args);
     1061    if (!lightness)
     1062        return { };
     1063
     1064    auto alpha = consumeOptionalAlphaOrIdent<CSSValueAlpha>(args);
     1065    if (!alpha)
     1066        return { };
     1067
     1068    if (!args.atEnd())
     1069        return { };
     1070
     1071    // After parsing, convert identifiers to values from the origin color.
     1072
    11911073    auto originColorAsHSL = originColor.toColorTypeLossy<HSLA<float>>();
    11921074
    1193     CSSCalcSymbolTable symbolTable {
    1194         { CSSValueH, CSSUnitType::CSS_DEG, originColorAsHSL.hue },
    1195         { CSSValueS, CSSUnitType::CSS_PERCENTAGE, originColorAsHSL.saturation },
    1196         { CSSValueL, CSSUnitType::CSS_PERCENTAGE, originColorAsHSL.lightness },
    1197         { CSSValueAlpha, CSSUnitType::CSS_PERCENTAGE, originColorAsHSL.alpha * 100.0 }
    1198     };
    1199 
    1200     auto hue = consumeHueOrIdent(args, symbolTable);
    1201     if (!hue)
    1202         return { };
    1203 
    1204     auto saturation = consumePercentOrIdent(args, symbolTable);
    1205     if (!saturation)
    1206         return { };
    1207 
    1208     auto lightness = consumePercentOrIdent(args, symbolTable);
    1209     if (!lightness)
    1210         return { };
    1211 
    1212     auto alpha = consumeOptionalAlphaOrIdent(args, symbolTable);
    1213     if (!alpha)
    1214         return { };
    1215 
    1216     if (!args.atEnd())
    1217         return { };
    1218 
    1219     auto normalizedHue = normalizeHue(*hue);
    1220     auto normalizedSaturation = std::clamp(*saturation, 0.0, 100.0);
    1221     auto normalizedLightness = std::clamp(*lightness, 0.0, 100.0);
    1222     auto normalizedAlpha = std::clamp(*alpha, 0.0, 1.0);
    1223 
    1224     return convertColor<SRGBA<uint8_t>>(HSLA<float> { static_cast<float>(normalizedHue), static_cast<float>(normalizedSaturation), static_cast<float>(normalizedLightness), static_cast<float>(normalizedAlpha) });
     1075    auto resolvedHue = resolveRelativeColorChannel<CSSValueH, CSSValueS, CSSValueL, CSSValueAlpha>(*hue, originColorAsHSL, [](auto hue) {
     1076        return normalizeHue(hue);
     1077    });
     1078    auto resolvedSaturation = resolveRelativeColorChannel<CSSValueH, CSSValueS, CSSValueL, CSSValueAlpha>(*saturation, originColorAsHSL, [](auto saturation) {
     1079        return clampTo(saturation, 0.0, 100.0);
     1080    });
     1081    auto resolvedLightness = resolveRelativeColorChannel<CSSValueH, CSSValueS, CSSValueL, CSSValueAlpha>(*lightness, originColorAsHSL, [](auto lightness) {
     1082        return clampTo(lightness, 0.0, 100.0);
     1083    });
     1084    auto resolvedAlpha = resolveRelativeColorChannel<CSSValueH, CSSValueS, CSSValueL, CSSValueAlpha>(*alpha, originColorAsHSL);
     1085
     1086    return convertColor<SRGBA<uint8_t>>(HSLA<float> { static_cast<float>(resolvedHue), static_cast<float>(resolvedSaturation), static_cast<float>(resolvedLightness), static_cast<float>(resolvedAlpha) });
    12251087}
    12261088
     
    12621124
    12631125    auto normalizedHue = normalizeHue(*hue);
    1264     auto normalizedSaturation = std::clamp(*saturation, 0.0, 100.0);
    1265     auto normalizedLightness = std::clamp(*lightness, 0.0, 100.0);
    1266     auto normalizedAlpha = std::clamp(*alpha, 0.0, 1.0);
     1126    auto normalizedSaturation = clampTo(*saturation, 0.0, 100.0);
     1127    auto normalizedLightness = clampTo(*lightness, 0.0, 100.0);
     1128    auto normalizedAlpha = clampTo(*alpha, 0.0, 1.0);
    12671129
    12681130    return convertColor<SRGBA<uint8_t>>(HSLA<float> { static_cast<float>(normalizedHue), static_cast<float>(normalizedSaturation), static_cast<float>(normalizedLightness), static_cast<float>(normalizedAlpha) });
    12691131}
    12701132
    1271 template<typename ComponentType> struct WhitenessBlackness {
     1133template<typename ComponentType>
     1134struct WhitenessBlackness {
    12721135    ComponentType whiteness;
    12731136    ComponentType blackness;
     
    13031166        return { };
    13041167
     1168    auto hue = consumeHueOrIdent<CSSValueH>(args, context);
     1169    if (!hue)
     1170        return { };
     1171
     1172    auto whiteness = consumePercentOrIdent<CSSValueW>(args);
     1173    if (!whiteness)
     1174        return { };
     1175
     1176    auto blackness = consumePercentOrIdent<CSSValueB>(args);
     1177    if (!blackness)
     1178        return { };
     1179
     1180    auto alpha = consumeOptionalAlphaOrIdent<CSSValueAlpha>(args);
     1181    if (!alpha)
     1182        return { };
     1183
     1184    if (!args.atEnd())
     1185        return { };
     1186
     1187    // After parsing, convert identifiers to values from the origin color.
     1188
    13051189    auto originColorAsHWB = originColor.toColorTypeLossy<HWBA<float>>();
    13061190
    1307     CSSCalcSymbolTable symbolTable {
    1308         { CSSValueH, CSSUnitType::CSS_DEG, originColorAsHWB.hue },
    1309         { CSSValueW, CSSUnitType::CSS_PERCENTAGE, originColorAsHWB.whiteness },
    1310         { CSSValueB, CSSUnitType::CSS_PERCENTAGE, originColorAsHWB.blackness },
    1311         { CSSValueAlpha, CSSUnitType::CSS_PERCENTAGE, originColorAsHWB.alpha * 100.0 }
    1312     };
    1313 
    1314     auto hue = consumeHueOrIdent(args, symbolTable);
     1191    auto resolvedHue = resolveRelativeColorChannel<CSSValueH, CSSValueW, CSSValueB, CSSValueAlpha>(*hue, originColorAsHWB, [](auto hue) {
     1192        return normalizeHue(hue);
     1193    });
     1194    auto resolvedWhiteness = resolveRelativeColorChannel<CSSValueH, CSSValueW, CSSValueB, CSSValueAlpha>(*whiteness, originColorAsHWB);
     1195    auto resolvedBlackness = resolveRelativeColorChannel<CSSValueH, CSSValueW, CSSValueB, CSSValueAlpha>(*blackness, originColorAsHWB);
     1196    auto resolvedAlpha = resolveRelativeColorChannel<CSSValueH, CSSValueW, CSSValueB, CSSValueAlpha>(*alpha, originColorAsHWB);
     1197
     1198    auto [normalizedWhitness, normalizedBlackness] = normalizeWhitenessBlackness(resolvedWhiteness, resolvedBlackness);
     1199
     1200    return convertColor<SRGBA<uint8_t>>(HWBA<float> { static_cast<float>(resolvedHue), static_cast<float>(normalizedWhitness), static_cast<float>(normalizedBlackness), static_cast<float>(resolvedAlpha) });
     1201}
     1202
     1203static Color parseHWBParameters(CSSParserTokenRange& range, const CSSParserContext& context)
     1204{
     1205    ASSERT(range.peek().functionId() == CSSValueHwb);
     1206
     1207    if (!context.cssColor4)
     1208        return { };
     1209
     1210    auto args = consumeFunction(range);
     1211
     1212    if (context.relativeColorSyntaxEnabled && args.peek().id() == CSSValueFrom)
     1213        return parseRelativeHWBParameters(args, context);
     1214
     1215    auto hue = consumeHue(args, context);
    13151216    if (!hue)
    13161217        return { };
    13171218
    1318     auto whiteness = consumePercentOrIdent(args, symbolTable);
     1219    auto whiteness = consumePercentRaw(args);
    13191220    if (!whiteness)
    13201221        return { };
    13211222
    1322     auto blackness = consumePercentOrIdent(args, symbolTable);
     1223    auto blackness = consumePercentRaw(args);
    13231224    if (!blackness)
    13241225        return { };
    13251226
    1326     auto alpha = consumeOptionalAlphaOrIdent(args, symbolTable);
     1227    auto alpha = consumeOptionalAlpha(args);
    13271228    if (!alpha)
    13281229        return { };
     
    13371238}
    13381239
    1339 static Color parseHWBParameters(CSSParserTokenRange& range, const CSSParserContext& context)
    1340 {
    1341     ASSERT(range.peek().functionId() == CSSValueHwb);
     1240static Color parseRelativeLabParameters(CSSParserTokenRange& args, const CSSParserContext& context)
     1241{
     1242    ASSERT(args.peek().id() == CSSValueFrom);
     1243    consumeIdentRaw(args);
     1244
     1245    auto originColor = consumeOriginColor(args, context);
     1246    if (!originColor.isValid())
     1247        return { };
     1248
     1249    auto lightness = consumePercentOrIdent<CSSValueL>(args);
     1250    if (!lightness)
     1251        return { };
     1252
     1253    auto aValue = consumeNumberOrIdent<CSSValueA>(args);
     1254    if (!aValue)
     1255        return { };
     1256
     1257    auto bValue = consumeNumberOrIdent<CSSValueB>(args);
     1258    if (!bValue)
     1259        return { };
     1260
     1261    auto alpha = consumeOptionalAlphaOrIdent<CSSValueAlpha>(args);
     1262    if (!alpha)
     1263        return { };
     1264
     1265    if (!args.atEnd())
     1266        return { };
     1267
     1268    // After parsing, convert identifiers to values from the origin color.
     1269
     1270    auto originColorAsLab = originColor.toColorTypeLossy<Lab<float>>();
     1271
     1272    auto resolvedLightness = resolveRelativeColorChannel<CSSValueL, CSSValueA, CSSValueB, CSSValueAlpha>(*lightness, originColorAsLab, [](auto lightness) {
     1273        return std::max(0.0, lightness);
     1274    });
     1275    auto resolvedAValue = resolveRelativeColorChannel<CSSValueL, CSSValueA, CSSValueB, CSSValueAlpha>(*aValue, originColorAsLab);
     1276    auto resolvedBValue = resolveRelativeColorChannel<CSSValueL, CSSValueA, CSSValueB, CSSValueAlpha>(*bValue, originColorAsLab);
     1277    auto resolvedAlpha = resolveRelativeColorChannel<CSSValueL, CSSValueA, CSSValueB, CSSValueAlpha>(*alpha, originColorAsLab);
     1278
     1279    return Lab<float> { static_cast<float>(resolvedLightness), static_cast<float>(resolvedAValue), static_cast<float>(resolvedBValue), static_cast<float>(resolvedAlpha) };
     1280}
     1281
     1282static Color parseLabParameters(CSSParserTokenRange& range, const CSSParserContext& context)
     1283{
     1284    ASSERT(range.peek().functionId() == CSSValueLab);
    13421285
    13431286    if (!context.cssColor4)
     
    13471290
    13481291    if (context.relativeColorSyntaxEnabled && args.peek().id() == CSSValueFrom)
    1349         return parseRelativeHWBParameters(args, context);
    1350 
    1351     auto hue = consumeHue(args, context);
    1352     if (!hue)
    1353         return { };
    1354 
    1355     auto whiteness = consumePercentRaw(args);
    1356     if (!whiteness)
    1357         return { };
    1358 
    1359     auto blackness = consumePercentRaw(args);
    1360     if (!blackness)
     1292        return parseRelativeLabParameters(args, context);
     1293
     1294    auto lightness = consumePercentRaw(args);
     1295    if (!lightness)
     1296        return { };
     1297
     1298    auto aValue = consumeNumberRaw(args);
     1299    if (!aValue)
     1300        return { };
     1301
     1302    auto bValue = consumeNumberRaw(args);
     1303    if (!bValue)
    13611304        return { };
    13621305
     
    13681311        return { };
    13691312
    1370     auto normalizedHue = normalizeHue(*hue);
    1371     auto [normalizedWhitness, normalizedBlackness] = normalizeWhitenessBlackness(*whiteness, *blackness);
    1372 
    1373     return convertColor<SRGBA<uint8_t>>(HWBA<float> { static_cast<float>(normalizedHue), static_cast<float>(normalizedWhitness), static_cast<float>(normalizedBlackness), static_cast<float>(*alpha) });
    1374 }
    1375 
    1376 static Color parseRelativeLabParameters(CSSParserTokenRange& args, const CSSParserContext& context)
     1313    auto normalizedLightness = std::max(0.0, *lightness);
     1314
     1315    return Lab<float> { static_cast<float>(normalizedLightness), static_cast<float>(*aValue), static_cast<float>(*bValue), static_cast<float>(*alpha) };
     1316}
     1317
     1318static Color parseRelativeLCHParameters(CSSParserTokenRange& args, const CSSParserContext& context)
    13771319{
    13781320    ASSERT(args.peek().id() == CSSValueFrom);
     
    13831325        return { };
    13841326
    1385     auto originColorAsLab = originColor.toColorTypeLossy<Lab<float>>();
    1386 
    1387     CSSCalcSymbolTable symbolTable {
    1388         { CSSValueL, CSSUnitType::CSS_PERCENTAGE, originColorAsLab.lightness },
    1389         { CSSValueA, CSSUnitType::CSS_NUMBER, originColorAsLab.a },
    1390         { CSSValueB, CSSUnitType::CSS_NUMBER, originColorAsLab.b },
    1391         { CSSValueAlpha, CSSUnitType::CSS_PERCENTAGE, originColorAsLab.alpha * 100.0 }
    1392     };
    1393 
    1394     auto lightness = consumePercentOrIdent(args, symbolTable);
     1327    auto lightness = consumePercentOrIdent<CSSValueL>(args);
    13951328    if (!lightness)
    13961329        return { };
    13971330
    1398     auto aValue = consumeNumberOrIdent(args, symbolTable);
    1399     if (!aValue)
    1400         return { };
    1401 
    1402     auto bValue = consumeNumberOrIdent(args, symbolTable);
    1403     if (!bValue)
    1404         return { };
    1405 
    1406     auto alpha = consumeOptionalAlphaOrIdent(args, symbolTable);
     1331    auto chroma = consumeNumberOrIdent<CSSValueC>(args);
     1332    if (!chroma)
     1333        return { };
     1334
     1335    auto hue = consumeHueOrIdent<CSSValueH>(args, context);
     1336    if (!hue)
     1337        return { };
     1338
     1339    auto alpha = consumeOptionalAlphaOrIdent<CSSValueAlpha>(args);
    14071340    if (!alpha)
    14081341        return { };
     
    14111344        return { };
    14121345
    1413     auto normalizedLightness = std::max(0.0, *lightness);
    1414 
    1415     return Lab<float> { static_cast<float>(normalizedLightness), static_cast<float>(*aValue), static_cast<float>(*bValue), static_cast<float>(*alpha) };
    1416 }
    1417 
    1418 static Color parseLabParameters(CSSParserTokenRange& range, const CSSParserContext& context)
    1419 {
    1420     ASSERT(range.peek().functionId() == CSSValueLab);
    1421 
    1422     if (!context.cssColor4)
    1423         return { };
    1424 
    1425     auto args = consumeFunction(range);
    1426 
    1427     if (context.relativeColorSyntaxEnabled && args.peek().id() == CSSValueFrom)
    1428         return parseRelativeLabParameters(args, context);
    1429 
    1430     auto lightness = consumePercentRaw(args);
    1431     if (!lightness)
    1432         return { };
    1433 
    1434     auto aValue = consumeNumberRaw(args);
    1435     if (!aValue)
    1436         return { };
    1437 
    1438     auto bValue = consumeNumberRaw(args);
    1439     if (!bValue)
    1440         return { };
    1441 
    1442     auto alpha = consumeOptionalAlpha(args);
    1443     if (!alpha)
    1444         return { };
    1445 
    1446     if (!args.atEnd())
    1447         return { };
    1448 
    1449     auto normalizedLightness = std::max(0.0, *lightness);
    1450 
    1451     return Lab<float> { static_cast<float>(normalizedLightness), static_cast<float>(*aValue), static_cast<float>(*bValue), static_cast<float>(*alpha) };
    1452 }
    1453 
    1454 static Color parseRelativeLCHParameters(CSSParserTokenRange& args, const CSSParserContext& context)
    1455 {
    1456     ASSERT(args.peek().id() == CSSValueFrom);
    1457     consumeIdentRaw(args);
    1458 
    1459     auto originColor = consumeOriginColor(args, context);
    1460     if (!originColor.isValid())
    1461         return { };
    1462 
    14631346    auto originColorAsLCH = originColor.toColorTypeLossy<LCHA<float>>();
    14641347
    1465     CSSCalcSymbolTable symbolTable {
    1466         { CSSValueL, CSSUnitType::CSS_PERCENTAGE, originColorAsLCH.lightness },
    1467         { CSSValueC, CSSUnitType::CSS_NUMBER, originColorAsLCH.chroma },
    1468         { CSSValueH, CSSUnitType::CSS_DEG, originColorAsLCH.hue },
    1469         { CSSValueAlpha, CSSUnitType::CSS_PERCENTAGE, originColorAsLCH.alpha * 100.0 }
    1470     };
    1471 
    1472     auto lightness = consumePercentOrIdent(args, symbolTable);
    1473     if (!lightness)
    1474         return { };
    1475 
    1476     auto chroma = consumeNumberOrIdent(args, symbolTable);
    1477     if (!chroma)
    1478         return { };
    1479 
    1480     auto hue = consumeHueOrIdent(args, symbolTable);
    1481     if (!hue)
    1482         return { };
    1483 
    1484     auto alpha = consumeOptionalAlphaOrIdent(args, symbolTable);
    1485     if (!alpha)
    1486         return { };
    1487 
    1488     if (!args.atEnd())
    1489         return { };
    1490 
    1491     auto normalizedLightness = std::max(0.0, *lightness);
    1492     auto normalizedChroma = std::max(0.0, *chroma);
    1493     auto normalizedHue = normalizeHue(*hue);
    1494 
    1495     return LCHA<float> { static_cast<float>(normalizedLightness), static_cast<float>(normalizedChroma), static_cast<float>(normalizedHue), static_cast<float>(*alpha) };
     1348    auto resolvedLightness = resolveRelativeColorChannel<CSSValueL, CSSValueC, CSSValueH, CSSValueAlpha>(*lightness, originColorAsLCH, [](auto lightness) {
     1349        return std::max(0.0, lightness);
     1350    });
     1351    auto resolvedChroma = resolveRelativeColorChannel<CSSValueL, CSSValueC, CSSValueH, CSSValueAlpha>(*chroma, originColorAsLCH, [](auto chroma) {
     1352        return std::max(0.0, chroma);
     1353    });
     1354    auto resolvedHue = resolveRelativeColorChannel<CSSValueL, CSSValueC, CSSValueH, CSSValueAlpha>(*hue, originColorAsLCH, [](auto hue) {
     1355        return normalizeHue(hue);
     1356    });
     1357    auto resolvedAlpha = resolveRelativeColorChannel<CSSValueL, CSSValueC, CSSValueH, CSSValueAlpha>(*alpha, originColorAsLCH);
     1358
     1359    return LCHA<float> { static_cast<float>(resolvedLightness), static_cast<float>(resolvedChroma), static_cast<float>(resolvedHue), static_cast<float>(resolvedAlpha) };
    14961360}
    14971361
Note: See TracChangeset for help on using the changeset viewer.