| <!DOCTYPE html> |
| <meta charset="utf-8"> |
| <title>CSS Color 4: Resolving color values</title> |
| <link rel="author" title="Chris Nardi" href="mailto:csnardi1@gmail.com"> |
| <link rel="help" href="https://drafts.csswg.org/css-color-4/#resolving-color-values"> |
| <meta name="assert" content="Tests if color values are resolved properly"> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| |
| <div id="parent" style="color: rgb(45, 23, 27)"> |
| <div id="inner"></div> |
| </div> |
| |
| <script> |
| function color_test(color, expected, reason) { |
| test(function() { |
| var element = document.getElementById('inner'); |
| // Random value not in our test data. |
| fail_value = "rgb(12, 34, 223)" |
| element.style.color = "black"; |
| element.style.cssText = "color: " + fail_value + "; color: " + color; |
| |
| if (expected === null) |
| assert_equals(getComputedStyle(element).color, fail_value); |
| else |
| assert_equals(getComputedStyle(element).color, expected); |
| }, `${reason}: ${color}`); |
| } |
| |
| function expected_value(rgb_channels) { |
| if (rgb_channels === null) |
| return null; |
| else if (rgb_channels.length === 3 || rgb_channels[3] == 1) |
| return "rgb(" + rgb_channels.slice(0, 3).join(", ") + ")"; |
| else |
| return "rgba(" + rgb_channels.join(", ") + ")"; |
| } |
| |
| tests = [ |
| // Keyword tests |
| ["", null, "Should not parse invalid keyword"], |
| [" /* hey */\n", null, "Should not parse invalid keyword"], |
| ["4", null, "Should not parse invalid keyword"], |
| ["top", null, "Should not parse invalid keyword"], |
| ["/**/transparent", [0, 0, 0, 0], "Should parse to completely transparent"], |
| ["transparent", [0, 0, 0, 0], "Should parse to completely transparent"], |
| [" transparent\n", [0, 0, 0, 0], "Should parse to completely transparent"], |
| ["TransParent", [0, 0, 0, 0], "Should parse to completely transparent"], |
| ["currentColor", [45, 23, 27], "Should be same as parent color"], |
| ["CURRENTcolor", [45, 23, 27], "Should be same as parent color"], |
| ["current-Color", null, "Should not parse invalid keyword"], |
| ["black", [0, 0, 0, 1], "Should parse as correct value"], |
| ["white", [255, 255, 255, 1], "Should parse as correct value"], |
| ["fuchsia", [255, 0, 255, 1], "Should parse as correct value"], |
| ["cyan", [0, 255, 255, 1], "Should parse as correct value"], |
| ["CyAn", [0, 255, 255, 1], "Should parse as cyan"], |
| |
| // Hex tests |
| ["#", null, "Should not parse invalid hex"], |
| ["#f", null, "Should not parse invalid hex"], |
| ["#ff", null, "Should not parse invalid hex"], |
| ["#fff", [255, 255, 255, 1], "Valid 3-digit hex"], |
| ["#ffg", null, "Should not parse invalid hex"], |
| ["#ffff", [255, 255, 255, 1], "Valid 4-digit hex"], |
| ["#fffg", null, "Should not parse invalid hex"], |
| ["#fffff", null, "Should not parse invalid hex"], |
| ["#ffffff", [255, 255, 255, 1], "Valid 6-digit hex"], |
| ["#fffffg", null, "Should not parse invalid hex"], |
| ["#fffffff", null, "Should not parse invalid hex"], |
| ["#ffffffff", [255, 255, 255, 1], "Valid 8-digit hex"], |
| ["#fffffffg", null, "Should not parse invalid hex"], |
| ["#fffffffff", null, "Should not parse invalid hex"], |
| ["#FFCc99", [255, 204, 153, 1], "Valid 6-digit hex"], |
| ["#369", [51, 102, 153, 1], "Valid 3-digit hex"], |
| |
| // RGB tests |
| ["rgb(00, 51, 102)", [0, 51, 102, 1], "Valid numbers should be parsed"], |
| ["r\\gb(00, 51, 102)", [0, 51, 102, 1], "Correct escape sequences should still parse"], |
| ["r\\67 b(00, 51, 102)", [0, 51, 102, 1], "Correct escape sequences should still parse"], |
| ["RGB(153, 204, 255)", [153, 204, 255, 1], "Capitalization should not affect parsing"], |
| ["rgB(0, 0, 0)", [0, 0, 0, 1], "Capitalization should not affect parsing"], |
| ["rgB(0, 51, 255)", [0, 51, 255, 1], "Capitalization should not affect parsing"], |
| ["rgb(0,51,255)", [0, 51, 255, 1], "Lack of whitespace should not affect parsing"], |
| ["rgb(0\t, 51 ,255)", [0, 51, 255, 1], "Whitespace should not affect parsing"], |
| ["rgb(/* R */0, /* G */51, /* B */255)", [0, 51, 255, 1], "Comments should be allowed within function"], |
| ["rgb(-51, 306, 0)", [0, 255, 0, 1], "Invalid values should be clamped to 0 and 255 respectively"], |
| ["rgb(42%, 3%, 50%)", [107, 8, 128, 1], "Valid percentages should be parsed"], |
| ["RGB(100%, 100%, 100%)", [255, 255, 255, 1], "Capitalization should not affect parsing"], |
| ["rgB(0%, 0%, 0%)", [0, 0, 0, 1], "Capitalization should not affect parsing"], |
| ["rgB(10%, 20%, 30%)", [26, 51, 77, 1], "Capitalization should not affect parsing"], |
| ["rgb(10%,20%,30%)", [26, 51, 77, 1], "Whitespace should not affect parsing"], |
| ["rgb(10%\t, 20% ,30%)", [26, 51, 77, 1], "Whitespace should not affect parsing"], |
| ["rgb(/* R */ 10%, /* G */ 20%, /* B */ 30%)", [26, 51, 77, 1], "Comments should not affect parsing"], |
| ["rgb(-12%, 110%, 1400%)", [0, 255, 255, 1], "Invalid values should be clamped to 0 and 255 respectively"], |
| ["rgb(10%, 50%, 0)", null, "Values must be all numbers or all percentages"], |
| ["rgb(255, 50%, 0%)", null, "Values must be all numbers or all percentages"], |
| ["rgb(0, 0 0)", null, "Comma optional syntax requires no commas at all"], |
| ["rgb(0, 0, 0deg)", null, "Angles are not accepted in the rgb function"], |
| ["rgb(0, 0, light)", null, "Keywords are not accepted in the rgb function"], |
| ["rgb()", null, "The rgb function requires 3 or 4 arguments"], |
| ["rgb(0)", null, "The rgb function requires 3 or 4 arguments"], |
| ["rgb(0, 0)", null, "The rgb function requires 3 or 4 arguments"], |
| ["rgb(0%)", null, "The rgb function requires 3 or 4 arguments"], |
| ["rgb(0%, 0%)", null, "The rgb function requires 3 or 4 arguments"], |
| ["rgb(0, 0, 0, 0)", [0, 0, 0, 0], "RGB and RGBA are synonyms"], |
| ["rgb(0%, 0%, 0%, 0%)", [0, 0, 0, 0], "RGB and RGBA are synonyms"], |
| ["rgb(0%, 0%, 0%, 0)", [0, 0, 0, 0], "RGB and RGBA are synonyms"], |
| ["rgba(0, 0, 0, 0)", [0, 0, 0, 0], "Valid numbers should be parsed"], |
| ["rgba(204, 0, 102, 0.3)", [204, 0, 102, 0.3], "Valid numbers should be parsed"], |
| ["RGBA(255, 255, 255, 0)", [255, 255, 255, 0], "Capitalization should not affect parsing"], |
| ["rgBA(0, 51, 255, 1)", [0, 51, 255, 1], "Capitalization should not affect parsing"], |
| ["rgba(0, 51, 255, 1.1)", [0, 51, 255, 1], "Invalid alpha values should be clamped to 0 and 1 respectively"], |
| ["rgba(0, 51, 255, 37)", [0, 51, 255, 1], "Invalid alpha values should be clamped to 0 and 1 respectively"], |
| ["rgba(0, 51, 255, 0.42)", [0, 51, 255, 0.42], "Valid numbers should be parsed"], |
| ["rgba(0, 51, 255, 0)", [0, 51, 255, 0], "Valid numbers should be parsed"], |
| ["rgba(0, 51, 255, -0.1)", [0, 51, 255, 0], "Invalid alpha values should be clamped to 0 and 1 respectively"], |
| ["rgba(0, 51, 255, -139)", [0, 51, 255, 0], "Invalid alpha values should be clamped to 0 and 1 respectively"], |
| ["RGBA(100%, 100%, 100%, 0)", [255, 255, 255, 0], "Capitalization should not affect parsing"], |
| ["rgba(42%, 3%, 50%, 0.3)", [107, 8, 128, 0.3], "Valid percentages should be parsed"], |
| ["rgBA(0%, 20%, 100%, 1)", [0, 51, 255, 1], "Capitalization should not affect parsing"], |
| ["rgba(0%, 20%, 100%, 1.1)", [0, 51, 255, 1], "Invalid alpha values should be clamped to 0 and 1 respectively"], |
| ["rgba(0%, 20%, 100%, 37)", [0, 51, 255, 1], "Invalid alpha values should be clamped to 0 and 1 respectively"], |
| ["rgba(0%, 20%, 100%, 0.42)", [0, 51, 255, 0.42], "Valid percentages should be parsed"], |
| ["rgba(0%, 20%, 100%, 0)", [0, 51, 255, 0], "Valid percentages should be parsed"], |
| ["rgba(0%, 20%, 100%, -0.1)", [0, 51, 255, 0], "Invalid alpha values should be clamped to 0 and 1 respectively"], |
| ["rgba(0%, 20%, 100%, -139)", [0, 51, 255, 0], "Invalid alpha values should be clamped to 0 and 1 respectively"], |
| ["rgba(255, 255, 255, 0%)", [255, 255, 255, 0], "Percent alpha values are accepted in rgb/rgba"], |
| ["rgba(0%, 0%, 0%, 0%)", [0, 0, 0, 0], "Percent alpha values are accepted in rgb/rgba"], |
| ["rgba(0%, 0%, 0%)", [0, 0, 0, 1], "RGB and RGBA are synonyms"], |
| ["rgba(0, 0, 0)", [0, 0, 0, 1], "RGB and RGBA are synonyms"], |
| ["rgba(10%, 50%, 0, 1)", null, "Values must be all numbers or all percentages"], |
| ["rgba(255, 50%, 0%, 1)", null, "Values must be all numbers or all percentages"], |
| ["rgba(0, 0, 0 0)", null, "Comma optional syntax requires no commas at all"], |
| ["rgba(0, 0, 0, 0deg)", null, "Angles are not accepted in the rgb function"], |
| ["rgba(0, 0, 0, light)", null, "Keywords are not accepted in the rgb function"], |
| ["rgba()", null, "The rgba function requires 3 or 4 arguments"], |
| ["rgba(0)", null, "The rgba function requires 3 or 4 arguments"], |
| ["rgba(0, 0, 0, 0, 0)", null, "The rgba function requires 3 or 4 arguments"], |
| ["rgba(0%)", null, "The rgba function requires 3 or 4 arguments"], |
| ["rgba(0%, 0%)", null, "The rgba function requires 3 or 4 arguments"], |
| ["rgba(0%, 0%, 0%, 0%, 0%)", null, "The rgba function requires 3 or 4 arguments"], |
| |
| // HSL tests |
| ["HSL(0, 0%, 0%)", [0, 0, 0, 1], "Capitalization should not affect parsing"], |
| ["hsL(0, 100%, 50%)", [255, 0, 0, 1], "Capitalization should not affect parsing"], |
| ["hsl(60, 100%, 37.5%)", [191, 191, 0, 1], "Valid numbers should be parsed"], |
| ["hsl(780, 100%, 37.5%)", [191, 191, 0, 1], "Angles are represented as a part of a circle and wrap around"], |
| ["hsl(-300, 100%, 37.5%)", [191, 191, 0, 1], "Angles are represented as a part of a circle and wrap around"], |
| ["hsl(300, 50%, 50%)", [191, 64, 191, 1], "Valid numbers should be parsed"], |
| ["hsl(30deg, 100%, 100%)", [255, 255, 255, 1], "Angles are accepted in HSL/HSLA"], |
| ["hsl(0, 0%, 0%, 0%)", [0, 0, 0, 0], "HSL and HSLA are synonyms"], |
| ["hsl(10, 50%, 0)", null, "The second and third parameters of hsl/hsla must be a percent"], |
| ["hsl(50%, 50%, 0%)", null, "The first parameter of hsl/hsla must be a number or angle"], |
| ["hsl(0, 0% 0%)", null, "Comma optional syntax requires no commas at all"], |
| ["hsl(0, 0%, light)", null, "Keywords are not accepted in the hsl function"], |
| ["hsl()", null, "The hsl function requires 3 or 4 arguments"], |
| ["hsl(0)", null, "The hsl function requires 3 or 4 arguments"], |
| ["hsl(0, 0%)", null, "The hsl function requires 3 or 4 arguments"], |
| ["HSLA(-300, 100%, 37.5%, 1)", [191, 191, 0, 1], "Angles are represented as a part of a circle and wrap around"], |
| ["hsLA(-300, 100%, 37.5%, 12)", [191, 191, 0, 1], "Invalid alpha values should be clamped to 0 and 1 respectively"], |
| ["hsla(-300, 100%, 37.5%, 0.2)", [191, 191, 0, 0.2], "Angles are represented as a part of a circle and wrap around"], |
| ["hsla(-300, 100%, 37.5%, 0)", [191, 191, 0, 0], "Angles are represented as a part of a circle and wrap around"], |
| ["hsla(-300, 100%, 37.5%, -3)", [191, 191, 0, 0], "Invalid alpha values should be clamped to 0 and 1 respectively"], |
| ["hsla(0, 0%, 0%, 50%)", [0, 0, 0, 0.5], "Percent alpha values are accepted in hsl/hsla"], |
| ["hsla(30deg, 100%, 100%, 1)", [255, 255, 255, 1], "Angles are accepted in HSL/HSLA"], |
| ["hsla(10, 50%, 0, 1)", null, "The second and third parameters of hsl/hsla must be a percent"], |
| ["hsla(50%, 50%, 0%, 1)", null, "The first parameter of hsl/hsla must be a number or angle"], |
| ["hsla(0, 0% 0%, 1)", null, "Comma optional syntax requires no commas at all"], |
| ["hsla(0, 0%, light, 1)", null, "Keywords are not accepted in the hsla function"], |
| ["hsla()", null, "The hsla function requires 3 or 4 arguments"], |
| ["hsla(0)", null, "The hsla function requires 3 or 4 arguments"], |
| ["hsla(0, 0%)", null, "The hsla function requires 3 or 4 arguments"], |
| ["hsla(0, 0%, 0%, 1, 0%)", null, "The hsla function requires 3 or 4 arguments"] |
| ] |
| |
| for (var value in tests) { |
| items_to_test = tests[value]; |
| color_test(items_to_test[0], expected_value(items_to_test[1]), items_to_test[2]); |
| } |
| </script> |