Form input type=color
diff --git a/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/color.window-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/color.window-expected.txt
new file mode 100644
index 0000000000000..aadc381eab19a
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/color.window-expected.txt
@@ -0,0 +1,196 @@
+
+PASS Testing the empty string with color space 'limited-srgb' and without alpha (setAttribute("value"))
+PASS Testing the empty string with color space 'limited-srgb' and without alpha (value)
+PASS Testing the empty string with color space 'limited-srgb' and with alpha (setAttribute("value"))
+PASS Testing the empty string with color space 'limited-srgb' and with alpha (value)
+PASS Testing the empty string with color space 'display-p3' and without alpha (setAttribute("value"))
+PASS Testing the empty string with color space 'display-p3' and without alpha (value)
+PASS Testing the empty string with color space 'display-p3' and with alpha (setAttribute("value"))
+PASS Testing the empty string with color space 'display-p3' and with alpha (value)
+PASS Testing no value with color space 'limited-srgb' and without alpha (setAttribute("value"))
+PASS Testing no value with color space 'limited-srgb' and without alpha (value)
+PASS Testing no value with color space 'limited-srgb' and with alpha (setAttribute("value"))
+PASS Testing no value with color space 'limited-srgb' and with alpha (value)
+PASS Testing no value with color space 'display-p3' and without alpha (setAttribute("value"))
+PASS Testing no value with color space 'display-p3' and without alpha (value)
+PASS Testing no value with color space 'display-p3' and with alpha (setAttribute("value"))
+PASS Testing no value with color space 'display-p3' and with alpha (value)
+PASS Testing '#ffffff' with color space 'limited-srgb' and without alpha (setAttribute("value"))
+PASS Testing '#ffffff' with color space 'limited-srgb' and without alpha (value)
+PASS Testing '#ffffff' with color space 'limited-srgb' and with alpha (setAttribute("value"))
+PASS Testing '#ffffff' with color space 'limited-srgb' and with alpha (value)
+PASS Testing '#ffffff' with color space 'display-p3' and without alpha (setAttribute("value"))
+PASS Testing '#ffffff' with color space 'display-p3' and without alpha (value)
+PASS Testing '#ffffff' with color space 'display-p3' and with alpha (setAttribute("value"))
+PASS Testing '#ffffff' with color space 'display-p3' and with alpha (value)
+PASS Testing '#ffffff08' with color space 'limited-srgb' and without alpha (setAttribute("value"))
+PASS Testing '#ffffff08' with color space 'limited-srgb' and without alpha (value)
+PASS Testing '#ffffff08' with color space 'limited-srgb' and with alpha (setAttribute("value"))
+PASS Testing '#ffffff08' with color space 'limited-srgb' and with alpha (value)
+PASS Testing '#ffffff08' with color space 'display-p3' and without alpha (setAttribute("value"))
+PASS Testing '#ffffff08' with color space 'display-p3' and without alpha (value)
+PASS Testing '#ffffff08' with color space 'display-p3' and with alpha (setAttribute("value"))
+PASS Testing '#ffffff08' with color space 'display-p3' and with alpha (value)
+PASS Testing '#FFFFFF' with color space 'limited-srgb' and without alpha (setAttribute("value"))
+PASS Testing '#FFFFFF' with color space 'limited-srgb' and without alpha (value)
+PASS Testing '#FFFFFF' with color space 'limited-srgb' and with alpha (setAttribute("value"))
+PASS Testing '#FFFFFF' with color space 'limited-srgb' and with alpha (value)
+PASS Testing '#FFFFFF' with color space 'display-p3' and without alpha (setAttribute("value"))
+PASS Testing '#FFFFFF' with color space 'display-p3' and without alpha (value)
+PASS Testing '#FFFFFF' with color space 'display-p3' and with alpha (setAttribute("value"))
+PASS Testing '#FFFFFF' with color space 'display-p3' and with alpha (value)
+PASS Testing '#0F0F0F' with color space 'limited-srgb' and without alpha (setAttribute("value"))
+PASS Testing '#0F0F0F' with color space 'limited-srgb' and without alpha (value)
+PASS Testing '#0F0F0F' with color space 'limited-srgb' and with alpha (setAttribute("value"))
+PASS Testing '#0F0F0F' with color space 'limited-srgb' and with alpha (value)
+PASS Testing '#0F0F0F' with color space 'display-p3' and without alpha (setAttribute("value"))
+PASS Testing '#0F0F0F' with color space 'display-p3' and without alpha (value)
+PASS Testing '#0F0F0F' with color space 'display-p3' and with alpha (setAttribute("value"))
+PASS Testing '#0F0F0F' with color space 'display-p3' and with alpha (value)
+PASS Testing '#fff' with color space 'limited-srgb' and without alpha (setAttribute("value"))
+PASS Testing '#fff' with color space 'limited-srgb' and without alpha (value)
+PASS Testing '#fff' with color space 'limited-srgb' and with alpha (setAttribute("value"))
+PASS Testing '#fff' with color space 'limited-srgb' and with alpha (value)
+PASS Testing '#fff' with color space 'display-p3' and without alpha (setAttribute("value"))
+PASS Testing '#fff' with color space 'display-p3' and without alpha (value)
+PASS Testing '#fff' with color space 'display-p3' and with alpha (setAttribute("value"))
+PASS Testing '#fff' with color space 'display-p3' and with alpha (value)
+PASS Testing 'fffffff' with color space 'limited-srgb' and without alpha (setAttribute("value"))
+PASS Testing 'fffffff' with color space 'limited-srgb' and without alpha (value)
+PASS Testing 'fffffff' with color space 'limited-srgb' and with alpha (setAttribute("value"))
+PASS Testing 'fffffff' with color space 'limited-srgb' and with alpha (value)
+PASS Testing 'fffffff' with color space 'display-p3' and without alpha (setAttribute("value"))
+PASS Testing 'fffffff' with color space 'display-p3' and without alpha (value)
+PASS Testing 'fffffff' with color space 'display-p3' and with alpha (setAttribute("value"))
+PASS Testing 'fffffff' with color space 'display-p3' and with alpha (value)
+PASS Testing '#gggggg' with color space 'limited-srgb' and without alpha (setAttribute("value"))
+PASS Testing '#gggggg' with color space 'limited-srgb' and without alpha (value)
+PASS Testing '#gggggg' with color space 'limited-srgb' and with alpha (setAttribute("value"))
+PASS Testing '#gggggg' with color space 'limited-srgb' and with alpha (value)
+PASS Testing '#gggggg' with color space 'display-p3' and without alpha (setAttribute("value"))
+PASS Testing '#gggggg' with color space 'display-p3' and without alpha (value)
+PASS Testing '#gggggg' with color space 'display-p3' and with alpha (setAttribute("value"))
+PASS Testing '#gggggg' with color space 'display-p3' and with alpha (value)
+PASS Testing 'foobar' with color space 'limited-srgb' and without alpha (setAttribute("value"))
+PASS Testing 'foobar' with color space 'limited-srgb' and without alpha (value)
+PASS Testing 'foobar' with color space 'limited-srgb' and with alpha (setAttribute("value"))
+PASS Testing 'foobar' with color space 'limited-srgb' and with alpha (value)
+PASS Testing 'foobar' with color space 'display-p3' and without alpha (setAttribute("value"))
+PASS Testing 'foobar' with color space 'display-p3' and without alpha (value)
+PASS Testing 'foobar' with color space 'display-p3' and with alpha (setAttribute("value"))
+PASS Testing 'foobar' with color space 'display-p3' and with alpha (value)
+PASS Testing '#ffffff\0' with color space 'limited-srgb' and without alpha (setAttribute("value"))
+PASS Testing '#ffffff\0' with color space 'limited-srgb' and without alpha (value)
+PASS Testing '#ffffff\0' with color space 'limited-srgb' and with alpha (setAttribute("value"))
+PASS Testing '#ffffff\0' with color space 'limited-srgb' and with alpha (value)
+PASS Testing '#ffffff\0' with color space 'display-p3' and without alpha (setAttribute("value"))
+PASS Testing '#ffffff\0' with color space 'display-p3' and without alpha (value)
+PASS Testing '#ffffff\0' with color space 'display-p3' and with alpha (setAttribute("value"))
+PASS Testing '#ffffff\0' with color space 'display-p3' and with alpha (value)
+PASS Testing '#ffffff;' with color space 'limited-srgb' and without alpha (setAttribute("value"))
+PASS Testing '#ffffff;' with color space 'limited-srgb' and without alpha (value)
+PASS Testing '#ffffff;' with color space 'limited-srgb' and with alpha (setAttribute("value"))
+PASS Testing '#ffffff;' with color space 'limited-srgb' and with alpha (value)
+PASS Testing '#ffffff;' with color space 'display-p3' and without alpha (setAttribute("value"))
+PASS Testing '#ffffff;' with color space 'display-p3' and without alpha (value)
+PASS Testing '#ffffff;' with color space 'display-p3' and with alpha (setAttribute("value"))
+PASS Testing '#ffffff;' with color space 'display-p3' and with alpha (value)
+PASS Testing ' #ffffff' with color space 'limited-srgb' and without alpha (setAttribute("value"))
+PASS Testing ' #ffffff' with color space 'limited-srgb' and without alpha (value)
+PASS Testing ' #ffffff' with color space 'limited-srgb' and with alpha (setAttribute("value"))
+PASS Testing ' #ffffff' with color space 'limited-srgb' and with alpha (value)
+PASS Testing ' #ffffff' with color space 'display-p3' and without alpha (setAttribute("value"))
+PASS Testing ' #ffffff' with color space 'display-p3' and without alpha (value)
+PASS Testing ' #ffffff' with color space 'display-p3' and with alpha (setAttribute("value"))
+PASS Testing ' #ffffff' with color space 'display-p3' and with alpha (value)
+PASS Testing '#ffffff ' with color space 'limited-srgb' and without alpha (setAttribute("value"))
+PASS Testing '#ffffff ' with color space 'limited-srgb' and without alpha (value)
+PASS Testing '#ffffff ' with color space 'limited-srgb' and with alpha (setAttribute("value"))
+PASS Testing '#ffffff ' with color space 'limited-srgb' and with alpha (value)
+PASS Testing '#ffffff ' with color space 'display-p3' and without alpha (setAttribute("value"))
+PASS Testing '#ffffff ' with color space 'display-p3' and without alpha (value)
+PASS Testing '#ffffff ' with color space 'display-p3' and with alpha (setAttribute("value"))
+PASS Testing '#ffffff ' with color space 'display-p3' and with alpha (value)
+PASS Testing ' #ffffff ' with color space 'limited-srgb' and without alpha (setAttribute("value"))
+PASS Testing ' #ffffff ' with color space 'limited-srgb' and without alpha (value)
+PASS Testing ' #ffffff ' with color space 'limited-srgb' and with alpha (setAttribute("value"))
+PASS Testing ' #ffffff ' with color space 'limited-srgb' and with alpha (value)
+PASS Testing ' #ffffff ' with color space 'display-p3' and without alpha (setAttribute("value"))
+PASS Testing ' #ffffff ' with color space 'display-p3' and without alpha (value)
+PASS Testing ' #ffffff ' with color space 'display-p3' and with alpha (setAttribute("value"))
+PASS Testing ' #ffffff ' with color space 'display-p3' and with alpha (value)
+PASS Testing 'crimson' with color space 'limited-srgb' and without alpha (setAttribute("value"))
+PASS Testing 'crimson' with color space 'limited-srgb' and without alpha (value)
+PASS Testing 'crimson' with color space 'limited-srgb' and with alpha (setAttribute("value"))
+PASS Testing 'crimson' with color space 'limited-srgb' and with alpha (value)
+PASS Testing 'crimson' with color space 'display-p3' and without alpha (setAttribute("value"))
+PASS Testing 'crimson' with color space 'display-p3' and without alpha (value)
+PASS Testing 'crimson' with color space 'display-p3' and with alpha (setAttribute("value"))
+PASS Testing 'crimson' with color space 'display-p3' and with alpha (value)
+PASS Testing 'bisque' with color space 'limited-srgb' and without alpha (setAttribute("value"))
+PASS Testing 'bisque' with color space 'limited-srgb' and without alpha (value)
+PASS Testing 'bisque' with color space 'limited-srgb' and with alpha (setAttribute("value"))
+PASS Testing 'bisque' with color space 'limited-srgb' and with alpha (value)
+PASS Testing 'bisque' with color space 'display-p3' and without alpha (setAttribute("value"))
+PASS Testing 'bisque' with color space 'display-p3' and without alpha (value)
+PASS Testing 'bisque' with color space 'display-p3' and with alpha (setAttribute("value"))
+PASS Testing 'bisque' with color space 'display-p3' and with alpha (value)
+PASS Testing 'currentColor' with color space 'limited-srgb' and without alpha (setAttribute("value"))
+PASS Testing 'currentColor' with color space 'limited-srgb' and without alpha (value)
+PASS Testing 'currentColor' with color space 'limited-srgb' and with alpha (setAttribute("value"))
+PASS Testing 'currentColor' with color space 'limited-srgb' and with alpha (value)
+PASS Testing 'currentColor' with color space 'display-p3' and without alpha (setAttribute("value"))
+PASS Testing 'currentColor' with color space 'display-p3' and without alpha (value)
+PASS Testing 'currentColor' with color space 'display-p3' and with alpha (setAttribute("value"))
+PASS Testing 'currentColor' with color space 'display-p3' and with alpha (value)
+PASS Testing 'transparent' with color space 'limited-srgb' and without alpha (setAttribute("value"))
+PASS Testing 'transparent' with color space 'limited-srgb' and without alpha (value)
+PASS Testing 'transparent' with color space 'limited-srgb' and with alpha (setAttribute("value"))
+PASS Testing 'transparent' with color space 'limited-srgb' and with alpha (value)
+PASS Testing 'transparent' with color space 'display-p3' and without alpha (setAttribute("value"))
+PASS Testing 'transparent' with color space 'display-p3' and without alpha (value)
+PASS Testing 'transparent' with color space 'display-p3' and with alpha (setAttribute("value"))
+PASS Testing 'transparent' with color space 'display-p3' and with alpha (value)
+PASS Testing 'inherit' with color space 'limited-srgb' and without alpha (setAttribute("value"))
+PASS Testing 'inherit' with color space 'limited-srgb' and without alpha (value)
+PASS Testing 'inherit' with color space 'limited-srgb' and with alpha (setAttribute("value"))
+PASS Testing 'inherit' with color space 'limited-srgb' and with alpha (value)
+PASS Testing 'inherit' with color space 'display-p3' and without alpha (setAttribute("value"))
+PASS Testing 'inherit' with color space 'display-p3' and without alpha (value)
+PASS Testing 'inherit' with color space 'display-p3' and with alpha (setAttribute("value"))
+PASS Testing 'inherit' with color space 'display-p3' and with alpha (value)
+PASS Testing 'rgb(1,1,1)' with color space 'limited-srgb' and without alpha (setAttribute("value"))
+PASS Testing 'rgb(1,1,1)' with color space 'limited-srgb' and without alpha (value)
+PASS Testing 'rgb(1,1,1)' with color space 'limited-srgb' and with alpha (setAttribute("value"))
+PASS Testing 'rgb(1,1,1)' with color space 'limited-srgb' and with alpha (value)
+PASS Testing 'rgb(1,1,1)' with color space 'display-p3' and without alpha (setAttribute("value"))
+PASS Testing 'rgb(1,1,1)' with color space 'display-p3' and without alpha (value)
+PASS Testing 'rgb(1,1,1)' with color space 'display-p3' and with alpha (setAttribute("value"))
+PASS Testing 'rgb(1,1,1)' with color space 'display-p3' and with alpha (value)
+PASS Testing 'rgb(1,1,1,1)' with color space 'limited-srgb' and without alpha (setAttribute("value"))
+PASS Testing 'rgb(1,1,1,1)' with color space 'limited-srgb' and without alpha (value)
+PASS Testing 'rgb(1,1,1,1)' with color space 'limited-srgb' and with alpha (setAttribute("value"))
+PASS Testing 'rgb(1,1,1,1)' with color space 'limited-srgb' and with alpha (value)
+PASS Testing 'rgb(1,1,1,1)' with color space 'display-p3' and without alpha (setAttribute("value"))
+PASS Testing 'rgb(1,1,1,1)' with color space 'display-p3' and without alpha (value)
+PASS Testing 'rgb(1,1,1,1)' with color space 'display-p3' and with alpha (setAttribute("value"))
+PASS Testing 'rgb(1,1,1,1)' with color space 'display-p3' and with alpha (value)
+PASS Testing 'rgb(1,1,1,0.5)' with color space 'limited-srgb' and without alpha (setAttribute("value"))
+PASS Testing 'rgb(1,1,1,0.5)' with color space 'limited-srgb' and without alpha (value)
+PASS Testing 'rgb(1,1,1,0.5)' with color space 'limited-srgb' and with alpha (setAttribute("value"))
+PASS Testing 'rgb(1,1,1,0.5)' with color space 'limited-srgb' and with alpha (value)
+PASS Testing 'rgb(1,1,1,0.5)' with color space 'display-p3' and without alpha (setAttribute("value"))
+PASS Testing 'rgb(1,1,1,0.5)' with color space 'display-p3' and without alpha (value)
+PASS Testing 'rgb(1,1,1,0.5)' with color space 'display-p3' and with alpha (setAttribute("value"))
+PASS Testing 'rgb(1,1,1,0.5)' with color space 'display-p3' and with alpha (value)
+PASS Testing '#FFFFFὊ9' with color space 'limited-srgb' and without alpha (setAttribute("value"))
+PASS Testing '#FFFFFὊ9' with color space 'limited-srgb' and without alpha (value)
+PASS Testing '#FFFFFὊ9' with color space 'limited-srgb' and with alpha (setAttribute("value"))
+PASS Testing '#FFFFFὊ9' with color space 'limited-srgb' and with alpha (value)
+PASS Testing '#FFFFFὊ9' with color space 'display-p3' and without alpha (setAttribute("value"))
+PASS Testing '#FFFFFὊ9' with color space 'display-p3' and without alpha (value)
+PASS Testing '#FFFFFὊ9' with color space 'display-p3' and with alpha (setAttribute("value"))
+PASS Testing '#FFFFFὊ9' with color space 'display-p3' and with alpha (value)
+PASS System colors are parsed
+PASS Display P3 colors can be out-of-bounds
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/color.window.html b/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/color.window.html
new file mode 100644
index 0000000000000..7f4c27e415bf9
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/color.window.html
@@ -0,0 +1 @@
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/color.window.js b/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/color.window.js
new file mode 100644
index 0000000000000..28ec9ec4d8652
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/color.window.js
@@ -0,0 +1,254 @@
+// META: script=/css/support/color-testcommon.js
+
+// While assert_equals is fine for hex, it's not for hexalpha, p3, and p3alpha. We use the default
+// epsilon of 0.0001.
+const assert_colors = set_up_fuzzy_color_test();
+
+[
+ {
+ value: "",
+ hex: "#000000",
+ hexalpha: "color(srgb 0 0 0)",
+ p3: "color(display-p3 0 0 0)",
+ p3alpha: "color(display-p3 0 0 0)"
+ },
+ {
+ hex: "#000000",
+ hexalpha: "color(srgb 0 0 0)",
+ p3: "color(display-p3 0 0 0)",
+ p3alpha: "color(display-p3 0 0 0)"
+ },
+ {
+ value: "#ffffff",
+ hex: "#ffffff",
+ hexalpha: "color(srgb 1 1 1)",
+ p3: "color(display-p3 1 1 1)",
+ p3alpha: "color(display-p3 1 1 1)"
+ },
+ {
+ value: "#ffffff08",
+ hex: "#ffffff",
+ hexalpha: "color(srgb 1 1 1 / 0.031373)",
+ p3: "color(display-p3 1 1 1)",
+ p3alpha: "color(display-p3 1 1 1 / 0.031373)"
+ },
+ {
+ value: "#FFFFFF",
+ hex: "#ffffff",
+ hexalpha: "color(srgb 1 1 1)",
+ p3: "color(display-p3 1 1 1)",
+ p3alpha: "color(display-p3 1 1 1)"
+ },
+ {
+ value: "#0F0F0F",
+ hex: "#0f0f0f",
+ hexalpha: "color(srgb 0.058824 0.058824 0.058824)",
+ p3: "color(display-p3 0.058824 0.058824 0.058824)",
+ p3alpha: "color(display-p3 0.058824 0.058824 0.058824)"
+ },
+ {
+ value: "#fff",
+ hex: "#ffffff",
+ hexalpha: "color(srgb 1 1 1)",
+ p3: "color(display-p3 1 1 1)",
+ p3alpha: "color(display-p3 1 1 1)"
+ },
+ {
+ value: "fffffff",
+ hex: "#000000",
+ hexalpha: "color(srgb 0 0 0)",
+ p3: "color(display-p3 0 0 0)",
+ p3alpha: "color(display-p3 0 0 0)"
+ },
+ {
+ value: "#gggggg",
+ hex: "#000000",
+ hexalpha: "color(srgb 0 0 0)",
+ p3: "color(display-p3 0 0 0)",
+ p3alpha: "color(display-p3 0 0 0)"
+ },
+ {
+ value: "foobar",
+ hex: "#000000",
+ hexalpha: "color(srgb 0 0 0)",
+ p3: "color(display-p3 0 0 0)",
+ p3alpha: "color(display-p3 0 0 0)"
+ },
+ {
+ value: "#ffffff\u0000",
+ hex: "#000000",
+ hexalpha: "color(srgb 0 0 0)",
+ p3: "color(display-p3 0 0 0)",
+ p3alpha: "color(display-p3 0 0 0)"
+ },
+ {
+ value: "#ffffff;",
+ hex: "#000000",
+ hexalpha: "color(srgb 0 0 0)",
+ p3: "color(display-p3 0 0 0)",
+ p3alpha: "color(display-p3 0 0 0)"
+ },
+ {
+ value: " #ffffff",
+ hex: "#ffffff",
+ hexalpha: "color(srgb 1 1 1)",
+ p3: "color(display-p3 1 1 1)",
+ p3alpha: "color(display-p3 1 1 1)"
+ },
+ {
+ value: "#ffffff ",
+ hex: "#ffffff",
+ hexalpha: "color(srgb 1 1 1)",
+ p3: "color(display-p3 1 1 1)",
+ p3alpha: "color(display-p3 1 1 1)"
+ },
+ {
+ value: " #ffffff ",
+ hex: "#ffffff",
+ hexalpha: "color(srgb 1 1 1)",
+ p3: "color(display-p3 1 1 1)",
+ p3alpha: "color(display-p3 1 1 1)"
+ },
+ {
+ value: "crimson",
+ hex: "#dc143c",
+ hexalpha: "color(srgb 0.862745 0.078431 0.235294)",
+ p3: "color(display-p3 0.791711 0.191507 0.257367)",
+ p3alpha: "color(display-p3 0.791711 0.191507 0.257367)"
+ },
+ {
+ value: "bisque",
+ hex: "#ffe4c4",
+ hexalpha: "color(srgb 1 0.894118 0.768627)",
+ p3: "color(display-p3 0.982297 0.8979 0.783276)",
+ p3alpha: "color(display-p3 0.982297 0.8979 0.783276)"
+ },
+ {
+ value: "currentColor",
+ hex: "#000000",
+ hexalpha: "color(srgb 0 0 0)",
+ p3: "color(display-p3 0 0 0)",
+ p3alpha: "color(display-p3 0 0 0)"
+ },
+ {
+ value: "transparent",
+ hex: "#000000",
+ hexalpha: "color(srgb 0 0 0 / 0)",
+ p3: "color(display-p3 0 0 0)",
+ p3alpha: "color(display-p3 0 0 0 / 0)"
+ },
+ {
+ value: "inherit",
+ hex: "#000000",
+ hexalpha: "color(srgb 0 0 0)",
+ p3: "color(display-p3 0 0 0)",
+ p3alpha: "color(display-p3 0 0 0)"
+ },
+ {
+ value: "rgb(1,1,1)",
+ hex: "#010101",
+ hexalpha: "color(srgb 0.003922 0.003922 0.003922)",
+ p3: "color(display-p3 0.003922 0.003922 0.003922)",
+ p3alpha: "color(display-p3 0.003922 0.003922 0.003922)"
+ },
+ {
+ value: "rgb(1,1,1,1)",
+ hex: "#010101",
+ hexalpha: "color(srgb 0.003922 0.003922 0.003922)",
+ p3: "color(display-p3 0.003922 0.003922 0.003922)",
+ p3alpha: "color(display-p3 0.003922 0.003922 0.003922)"
+ },
+ {
+ value: "rgb(1,1,1,0.5)",
+ hex: "#010101",
+ hexalpha: "color(srgb 0.003922 0.003922 0.003922 / 0.501961)",
+ p3: "color(display-p3 0.003922 0.003922 0.003922)",
+ p3alpha: "color(display-p3 0.003922 0.003922 0.003922 / 0.501961)"
+ },
+ {
+ value: "#FFFFF\u1F4A9",
+ hex: "#000000",
+ hexalpha: "color(srgb 0 0 0)",
+ p3: "color(display-p3 0 0 0)",
+ p3alpha: "color(display-p3 0 0 0)"
+ }
+].forEach(({ value, hex, hexalpha, p3, p3alpha }) => {
+ ["limited-srgb", "display-p3"].forEach(colorSpace => {
+ [false, true].forEach(alpha => {
+ const nameValue = value === "" ? "the empty string" : value === undefined ? "no value" : "'" + value + "'";
+ test(() => {
+ const input = document.createElement("input");
+ input.type = "color";
+ if (value !== undefined) {
+ input.setAttribute("value", value);
+ }
+ assert_equals(input.value, hex, "value is hex");
+ input.colorSpace = colorSpace;
+ assert_equals(input.colorSpace, colorSpace, "color space");
+ if (colorSpace === "limited-srgb") {
+ assert_equals(input.value, hex, "value is hex");
+ } else {
+ assert_colors(input.value, p3);
+ }
+ input.alpha = alpha;
+ assert_equals(input.alpha, alpha, "alpha");
+ if (colorSpace === "limited-srgb" && !alpha) {
+ assert_equals(input.value, hex, "value is hex");
+ } else if (colorSpace === "limited-srgb" && alpha) {
+ assert_colors(input.value, hexalpha);
+ } else if (colorSpace === "display-p3" && !alpha) {
+ assert_colors(input.value, p3);
+ } else {
+ assert_colors(input.value, p3alpha);
+ }
+ }, `Testing ${nameValue} with color space '${colorSpace}' and ${alpha ? 'with' : ' without'} alpha (setAttribute("value"))`);
+
+ test(() => {
+ const input = document.createElement("input");
+ input.type = "color";
+ // In this test we set alpha before we set value to avoid the value sanitization algorithm
+ // taking away the alpha channel from the input.
+ input.alpha = true;
+ if (value !== undefined) {
+ input.value = value;
+ }
+ assert_colors(input.value, hexalpha);
+ input.colorSpace = colorSpace;
+ assert_equals(input.colorSpace, colorSpace, "color space");
+ if (colorSpace === "limited-srgb") {
+ assert_colors(input.value, hexalpha);
+ } else {
+ assert_colors(input.value, p3alpha);
+ }
+ input.alpha = alpha;
+ assert_equals(input.alpha, alpha, "alpha");
+ if (colorSpace === "limited-srgb" && !alpha) {
+ assert_equals(input.value, hex, "value is hex");
+ } else if (colorSpace === "limited-srgb" && alpha) {
+ assert_colors(input.value, hexalpha);
+ } else if (colorSpace === "display-p3" && !alpha) {
+ assert_colors(input.value, p3);
+ } else {
+ assert_colors(input.value, p3alpha);
+ }
+ }, `Testing ${nameValue} with color space '${colorSpace}' and ${alpha ? 'with' : ' without'} alpha (value)`);
+ });
+ });
+});
+
+test(() => {
+ const input = document.createElement("input");
+ input.type = "color";
+ assert_equals(input.value, "#000000");
+ input.value = "ActiveBorder";
+ assert_not_equals(input.value, "#000000");
+}, "System colors are parsed");
+
+test(() => {
+ const input = document.createElement("input");
+ input.type = "color";
+ input.alpha = true;
+ input.colorSpace = "display-p3";
+ input.value = "color(display-p3 3 none .2 / .6)";
+ assert_equals(input.value, "color(display-p3 3 0 0.2 / 0.6)");
+}, "Display P3 colors can be out-of-bounds");
diff --git a/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/w3c-import.log
index 3104a429fa67c..88fd85576dad4 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/w3c-import.log
+++ b/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/w3c-import.log
@@ -25,7 +25,9 @@ List of files:
/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/click-user-gesture.html
/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/clone.html
/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/cloning-steps.html
-/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/color.html
+/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/color-attributes.window.js
+/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/color.tentative.html
+/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/color.window.js
/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/date.html
/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/datetime-local-trailing-zeros.html
/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/datetime-local.html
diff --git a/LayoutTests/platform/glib/TestExpectations b/LayoutTests/platform/glib/TestExpectations
index 9d4ece4d746b6..be818e72038c9 100644
--- a/LayoutTests/platform/glib/TestExpectations
+++ b/LayoutTests/platform/glib/TestExpectations
@@ -157,6 +157,10 @@ fast/history/page-cache-indexed-closed-db.html [ Pass ]
fast/multicol/multicol-with-child-renderLayer-for-input.html [ Pass ]
+# Enhanced
+imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/color-attributes.window.html [ Skip ]
+imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/color.window.html [ Skip ]
+
# permessage-deflate WebSocket extension.
http/tests/websocket/tests/hybi/imported/blink/permessage-deflate-comp-bit-onoff.html [ Pass ]
http/tests/websocket/tests/hybi/imported/blink/permessage-deflate-parameter.html [ Pass ]
diff --git a/LayoutTests/platform/mac-wk1/TestExpectations b/LayoutTests/platform/mac-wk1/TestExpectations
index 2af6c0e611cfe..77db1b42a88d8 100644
--- a/LayoutTests/platform/mac-wk1/TestExpectations
+++ b/LayoutTests/platform/mac-wk1/TestExpectations
@@ -1120,7 +1120,9 @@ editing/pasteboard/drag-and-drop-color-input.html [ Skip ]
fast/css/pseudo-visited-background-color-on-input.html [ ImageOnlyFailure ]
fast/css/read-only-read-write-input-basics.html [ ImageOnlyFailure ]
fast/forms/color [ Skip ]
-imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/color.html [ Skip ]
+imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/color-attributes.window.html [ Skip ]
+imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/color.tentative.html [ Skip ]
+imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/color.window.html [ Skip ]
imported/w3c/web-platform-tests/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-color-input-background-color-001.html [ ImageOnlyFailure ]
imported/w3c/web-platform-tests/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-color-input-background-size-001.html [ ImageOnlyFailure ]
diff --git a/LayoutTests/platform/wpe/TestExpectations b/LayoutTests/platform/wpe/TestExpectations
index 0768546a79eeb..20cc2b72147bd 100644
--- a/LayoutTests/platform/wpe/TestExpectations
+++ b/LayoutTests/platform/wpe/TestExpectations
@@ -956,7 +956,8 @@ webkit.org/b/186262 imported/w3c/web-platform-tests/css/css-text/word-break/word
webkit.org/b/186262 imported/w3c/web-platform-tests/css/css-text/word-break/word-break-normal-lo-000.html [ ImageOnlyFailure ]
webkit.org/b/180645 imported/w3c/web-platform-tests/html/semantics/forms/textfieldselection/selection-not-application.html [ Failure ]
-webkit.org/b/180645 imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/color.html [ Failure ]
+webkit.org/b/180645 imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/color.tentative.html [ Failure ]
+
webkit.org/b/180645 imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/valueMode.html [ Failure ]
webkit.org/b/180645 accessibility/color-input-value-changes.html [ Timeout ]
diff --git a/Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml b/Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml
index 93a487add2ada..e085907f2a68e 100644
--- a/Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml
+++ b/Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml
@@ -3582,6 +3582,21 @@ InputTypeColorEnabled:
default: false
sharedPreferenceForWebProcess: true
+InputTypeColorEnhancementsEnabled:
+ type: bool
+ status: unstable
+ category: html
+ condition: ENABLE(INPUT_TYPE_COLOR)
+ humanReadableName: "HTML alpha and colorspace attribute support for color inputs"
+ humanReadableDescription: "Enable HTML alpha and colorspace attribute support for input elements of type color"
+ defaultValue:
+ WebKitLegacy:
+ default: false
+ WebKit:
+ default: false
+ WebCore:
+ default: false
+
InputTypeDateEnabled:
type: bool
status: embedder
diff --git a/Source/WebCore/html/ColorInputType.cpp b/Source/WebCore/html/ColorInputType.cpp
index 3facbb31f0ac5..2ac0a607ff5cc 100644
--- a/Source/WebCore/html/ColorInputType.cpp
+++ b/Source/WebCore/html/ColorInputType.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 Google Inc. All rights reserved.
- * Copyright (C) 2015-2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -37,6 +37,7 @@
#include "AXObjectCache.h"
#include "CSSPropertyNames.h"
+#include "CSSPropertyParserConsumer+Color.h"
#include "Chrome.h"
#include "Color.h"
#include "ColorSerialization.h"
@@ -64,6 +65,12 @@ WTF_MAKE_TZONE_ALLOCATED_IMPL(ColorInputType);
using namespace HTMLNames;
+using LazySlowPathColorParsingParameters = std::tuple<
+ CSSPropertyParserHelpers::CSSColorParsingOptions,
+ CSSUnresolvedColorResolutionState,
+ std::optional
+>;
+
// https://html.spec.whatwg.org/multipage/infrastructure.html#valid-simple-colour
static bool isValidSimpleColor(StringView string)
{
@@ -86,6 +93,59 @@ static std::optional> parseSimpleColorValue(StringView string)
return { { toASCIIHexValue(string[1], string[2]), toASCIIHexValue(string[3], string[4]), toASCIIHexValue(string[5], string[6]) } };
}
+static LazySlowPathColorParsingParameters colorParsingParameters()
+{
+ return {
+ CSSPropertyParserHelpers::CSSColorParsingOptions {
+ .allowedColorTypes = { StyleColor::CSSColorType::Absolute, StyleColor::CSSColorType::Current, StyleColor::CSSColorType::System }
+ },
+ CSSUnresolvedColorResolutionState {
+ .resolvedCurrentColor = Color::black
+ },
+ std::nullopt
+ };
+}
+
+static std::optional parseColorValue(StringView string, HTMLInputElement& context)
+{
+ if (context.colorSpace().isNull())
+ return parseSimpleColorValue(string);
+
+ auto parserContext = context.document().cssParserContext();
+ parserContext.mode = HTMLStandardMode;
+ auto color = CSSPropertyParserHelpers::parseColorRaw(string.toString(), parserContext, [] {
+ return colorParsingParameters();
+ });
+
+ if (!color.isValid())
+ return { };
+
+ return color;
+}
+
+static String serializeColorValue(Color input, HTMLInputElement& context)
+{
+ auto alpha = context.alpha();
+ auto colorSpace = context.colorSpace();
+
+ if (!alpha)
+ input = input.opaqueColor();
+
+ if (colorSpace.isNull() || colorSpace == "limited-srgb"_s) {
+ auto inputAsRGBA = input.toColorTypeLossy>();
+ // When the alpha attribute is set the specification requires the modern color() serialization.
+ if (alpha)
+ input = { inputAsRGBA, { Color::Flags::UseColorFunctionSerialization } };
+ else
+ input = inputAsRGBA.resolved();
+ } else {
+ ASSERT(colorSpace == "display-p3"_s);
+ input = input.toColorTypeLossy>().resolved();
+ }
+
+ return serializationForHTML(input);
+}
+
ColorInputType::~ColorInputType()
{
endColorChooser();
@@ -124,21 +184,27 @@ bool ColorInputType::supportsRequired() const
String ColorInputType::fallbackValue() const
{
- return "#000000"_s;
+ ASSERT(element());
+ return serializeColorValue(Color::black, *element());
}
String ColorInputType::sanitizeValue(const String& proposedValue) const
{
- if (!isValidSimpleColor(proposedValue))
+ ASSERT(element());
+ auto color = parseColorValue(proposedValue, *element());
+
+ if (!color)
return fallbackValue();
- return proposedValue.convertToASCIILowercase();
+ return serializeColorValue(*color, *element());
}
Color ColorInputType::valueAsColor() const
{
ASSERT(element());
- return parseSimpleColorValue(element()->value()).value();
+ auto color = parseColorValue(element()->value(), *element());
+ ASSERT(!!color);
+ return *color;
}
void ColorInputType::createShadowSubtree()
@@ -231,7 +297,8 @@ bool ColorInputType::shouldRespectListAttribute()
bool ColorInputType::typeMismatchFor(const String& value) const
{
- return !isValidSimpleColor(value);
+ ASSERT(element());
+ return !!parseColorValue(value, *element());
}
bool ColorInputType::shouldResetOnDocumentActivation()
@@ -246,13 +313,12 @@ void ColorInputType::didChooseColor(const Color& color)
if (element()->isDisabledFormControl())
return;
- auto sRGBAColor = color.toColorTypeLossy>().resolved();
- auto sRGBColor = sRGBAColor.colorWithAlphaByte(255);
- if (sRGBColor == valueAsColor())
+ auto serializedColor = serializeColorValue(color, *element());
+ if (serializedColor == element()->value())
return;
EventQueueScope scope;
- element()->setValueFromRenderer(serializationForHTML(sRGBColor));
+ element()->setValueFromRenderer(serializedColor);
updateColorSwatch();
element()->dispatchFormControlChangeEvent();
@@ -312,7 +378,7 @@ Vector ColorInputType::suggestedColors() const
ASSERT(element());
if (auto dataList = element()->dataList()) {
for (auto& option : dataList->suggestions()) {
- if (auto color = parseSimpleColorValue(option.value()))
+ if (auto color = parseColorValue(option.value(), *element()))
suggestions.append(*color);
}
}
@@ -322,8 +388,9 @@ Vector ColorInputType::suggestedColors() const
void ColorInputType::selectColor(StringView string)
{
- if (auto color = parseSimpleColorValue(string))
- didChooseColor(color.value());
+ ASSERT(element());
+ if (auto color = parseColorValue(string, *element()))
+ didChooseColor(*color);
}
} // namespace WebCore
diff --git a/Source/WebCore/html/HTMLAttributeNames.in b/Source/WebCore/html/HTMLAttributeNames.in
index 3642dab5140ec..6e32a1ee4d09d 100644
--- a/Source/WebCore/html/HTMLAttributeNames.in
+++ b/Source/WebCore/html/HTMLAttributeNames.in
@@ -12,6 +12,7 @@ align
alink
allow
allowfullscreen
+alpha
alt
archive
aria-activedescendant
@@ -103,6 +104,7 @@ code
codebase
codetype
color
+colorspace
cols
colspan
command
diff --git a/Source/WebCore/html/HTMLInputElement.cpp b/Source/WebCore/html/HTMLInputElement.cpp
index 77686e149d0bd..8622ae5238b91 100644
--- a/Source/WebCore/html/HTMLInputElement.cpp
+++ b/Source/WebCore/html/HTMLInputElement.cpp
@@ -899,6 +899,15 @@ void HTMLInputElement::attributeChanged(const QualifiedName& name, const AtomStr
#endif
}
break;
+#if ENABLE(INPUT_TYPE_COLOR)
+ case AttributeNames::alphaAttr:
+ case AttributeNames::colorspaceAttr:
+ if (isColorControl() && document().settings().inputTypeColorEnhancementsEnabled()) {
+ updateValueIfNeeded();
+ updateValidity();
+ }
+ break;
+#endif
default:
break;
}
@@ -1564,6 +1573,30 @@ void HTMLInputElement::setShowAutoFillButton(AutoFillButtonType autoFillButtonTy
cache->autofillTypeChanged(*this);
}
+#if ENABLE(INPUT_TYPE_COLOR)
+bool HTMLInputElement::alpha()
+{
+ return document().settings().inputTypeColorEnhancementsEnabled() && hasAttributeWithoutSynchronization(alphaAttr);
+}
+
+String HTMLInputElement::colorSpace()
+{
+ if (!document().settings().inputTypeColorEnhancementsEnabled())
+ return nullString();
+
+ if (equalLettersIgnoringASCIICase(attributeWithoutSynchronization(colorspaceAttr), "display-p3"_s))
+ return "display-p3"_s;
+
+ return "limited-srgb"_s;
+}
+
+void HTMLInputElement::setColorSpace(const AtomString& value)
+{
+ ASSERT(document().settings().inputTypeColorEnhancementsEnabled());
+ setAttributeWithoutSynchronization(colorspaceAttr, value);
+}
+#endif // ENABLE(INPUT_TYPE_COLOR)
+
FileList* HTMLInputElement::files()
{
if (auto* fileInputType = dynamicDowncast(*m_inputType))
diff --git a/Source/WebCore/html/HTMLInputElement.h b/Source/WebCore/html/HTMLInputElement.h
index f3d342d5c117d..b2784397d0ab1 100644
--- a/Source/WebCore/html/HTMLInputElement.h
+++ b/Source/WebCore/html/HTMLInputElement.h
@@ -65,8 +65,15 @@ class HTMLInputElement final : public HTMLTextFormControlElement {
static Ref create(const QualifiedName&, Document&, HTMLFormElement*, bool createdByParser);
virtual ~HTMLInputElement();
+#if ENABLE(INPUT_TYPE_COLOR)
+ bool alpha();
+#endif
bool checked() const { return m_isChecked; }
WEBCORE_EXPORT void setChecked(bool, WasSetByJavaScript = WasSetByJavaScript::Yes);
+#if ENABLE(INPUT_TYPE_COLOR)
+ String colorSpace();
+ void setColorSpace(const AtomString&);
+#endif
WEBCORE_EXPORT FileList* files();
WEBCORE_EXPORT void setFiles(RefPtr&&, WasSetByJavaScript = WasSetByJavaScript::No);
FileList* filesForBindings() { return files(); }
diff --git a/Source/WebCore/html/HTMLInputElement.idl b/Source/WebCore/html/HTMLInputElement.idl
index 9109ac586c1e4..3b5a1eb7801ef 100644
--- a/Source/WebCore/html/HTMLInputElement.idl
+++ b/Source/WebCore/html/HTMLInputElement.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2024 Apple Inc. All rights reserved.
* Copyright (C) 2006 Samuel Weinig
* Copyright (C) 2012 Samsung Electronics. All rights reserved.
*
@@ -25,10 +25,12 @@
Exposed=Window
] interface HTMLInputElement : HTMLElement {
[CEReactions=NotNeeded, Reflect] attribute DOMString accept;
+ [Conditional=INPUT_TYPE_COLOR, EnabledBySetting=InputTypeColorEnhancementsEnabled, CEReactions=NotNeeded, Reflect] attribute boolean alpha;
[CEReactions=NotNeeded, Reflect] attribute DOMString alt;
[CEReactions=NotNeeded] attribute [AtomString] DOMString autocomplete;
[CEReactions=NotNeeded, Reflect=checked] attribute boolean defaultChecked;
attribute boolean checked;
+ [Conditional=INPUT_TYPE_COLOR, EnabledBySetting=InputTypeColorEnhancementsEnabled, CEReactions=NotNeeded] attribute [AtomString] DOMString colorSpace;
[CEReactions=NotNeeded, Reflect] attribute DOMString dirName;
[CEReactions=NotNeeded, Reflect] attribute boolean disabled;
readonly attribute HTMLFormElement form;