selectmenu: Add support for :open and :closed

This was discussed here: https://github.com/openui/open-ui/issues/547

Bug: 1121840
Change-Id: I44de1f38ce4c754b1046c2eea3837955ab026447
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4370850
Reviewed-by: Xiaocheng Hu <xiaochengh@chromium.org>
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1122593}
diff --git a/html/semantics/forms/the-selectmenu-element/selectmenu-pseudo-open-closed.tentative.html b/html/semantics/forms/the-selectmenu-element/selectmenu-pseudo-open-closed.tentative.html
new file mode 100644
index 0000000..b1400e0
--- /dev/null
+++ b/html/semantics/forms/the-selectmenu-element/selectmenu-pseudo-open-closed.tentative.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<link rel=author href="mailto:jarhar@chromium.org">
+<link rel=help href="https://github.com/openui/open-ui/issues/547">
+<link rel=help href="https://drafts.csswg.org/selectors/#open-state">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<selectmenu id=myselectmenu>
+  <button id=custombutton slot=button behavior=button>button</button>
+  <option>one</option>
+  <option>two</option>
+</selectmenu>
+
+<script>
+test(() => {
+  assert_false(myselectmenu.matches(':open'),
+    'Selectmenu should not match :open while it is closed.');
+  assert_true(myselectmenu.matches(':closed'),
+    'Selectmenu should match :closed while it is closed.');
+
+  custombutton.click();
+
+  assert_true(myselectmenu.matches(':open'),
+    'Selectmenu should match :open while it is open.');
+  assert_false(myselectmenu.matches(':closed'),
+    'Selectmenu should not match :closed while it is open.');
+}, 'Selectmenu should support :open and :closed pseudo selectors.');
+</script>
+
+<selectmenu id=selectmenuinvalidation>
+  <button slot=button behavior=button>button</button>
+  <option>one</option>
+  <option>two</option>
+</selectmenu>
+<style>
+selectmenu:closed {
+  background-color: red;
+}
+selectmenu:open {
+  background-color: green;
+}
+</style>
+
+<script>
+test(() => {
+  const selectmenu = document.getElementById('selectmenuinvalidation');
+  const button = selectmenu.querySelector('button');
+  const option = selectmenu.querySelector('option');
+
+  assert_equals(getComputedStyle(selectmenu).backgroundColor, 'rgb(255, 0, 0)',
+    'The style rules from :closed should apply when the selectmenu is closed.');
+
+  button.click();
+  assert_equals(getComputedStyle(selectmenu).backgroundColor, 'rgb(0, 128, 0)',
+    'The style rules from :open should apply when the selectmenu is open.');
+
+  option.click();
+  assert_equals(getComputedStyle(selectmenu).backgroundColor, 'rgb(255, 0, 0)',
+    'The style rules from :closed should apply when the selectmenu is opened and closed again.');
+}, 'Selectmenu :open and :closed should invalidate correctly.');
+</script>