зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1692730 [wpt PR 27623] - Introduce <selectmenu> with basic shadow structure and some controller code, a=testonly
Automatic update from web-platform-tests Introduce <selectmenu> with basic shadow structure and some controller code Begin implementing the <selectmenu> element, a version of <select> with a fully author-customizable UI. See https://groups.google.com/u/1/a/chromium.org/g/blink-dev/c/9TcfjaOs5zg/m/WAiv6WpUAAAJ and associated links for additional context. Establish the basic shadow DOM structure, with a button (which includes an arrow icon and a container to show the value), and a listbox based on <popup>. There are <slot> elements to add <option>s to the popup and replace any of the default parts. Include some basic styles. The default button part looks something like the native <select>, but the default listbox will need more work to improve its appearance. Add basic controller code using NativeEventListeners. Clicking the button part opens the listbox <popup>, and the value property and text shown in the button are updated when an option is clicked. This controller code is applied to the default parts and to author-supplied parts that are included via the <slot>s. Add tests to validate some basic scenarios involving the controller code. Note, a couple of the selectmenu-value.tentative.html tests fail because updates to the value property are not yet synchronous (should they be?). There are many TODOs and open questions to investigate, but this change establishes a starting point for exploring an approach to customizable form controls. Bug: 1121840 Change-Id: I68c0513b0e30813cbaa3b69fc2acb9086c7400ba Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2693857 Commit-Queue: Dan Clark <daniec@microsoft.com> Reviewed-by: Mason Freed <masonfreed@chromium.org> Reviewed-by: Ionel Popescu <iopopesc@microsoft.com> Cr-Commit-Position: refs/heads/master@{#855581} -- wpt-commits: 6ba9b6bb71afb574b48982a6bffee37051b833f6 wpt-pr: 27623
This commit is contained in:
Родитель
24620776d1
Коммит
bef884ebfd
|
@ -0,0 +1,76 @@
|
|||
<!DOCTYPE html>
|
||||
<title>HTMLSelectMenuElement Test: popup</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-actions.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
|
||||
<selectmenu id="selectMenu0">
|
||||
<option>one</option>
|
||||
<option id="selectMenu0-child2">two</option>
|
||||
<div id="selectMenu0-child3">I'm a div with no part attr</div>
|
||||
<option>three</option>
|
||||
<option>four</option>
|
||||
</selectmenu>
|
||||
|
||||
<selectmenu id="selectMenu1">
|
||||
<div slot="button" part="button" id="selectMenu1-button">
|
||||
Custom button
|
||||
</div>
|
||||
<popup slot="listbox" part="listbox">
|
||||
<option>one</option>
|
||||
<option id="selectMenu1-child2">two</option>
|
||||
<div part="option" id="selectMenu1-child3">three</div>
|
||||
</popup>
|
||||
</selectmenu>
|
||||
|
||||
<selectmenu id="selectMenu2">
|
||||
<!-- Swap out the listbox part without providing a replacement -->
|
||||
<div slot="listbox"></div>
|
||||
</selectmenu>
|
||||
<script>
|
||||
|
||||
function clickOn(element) {
|
||||
const actions = new test_driver.Actions();
|
||||
return actions.pointerMove(0, 0, {origin: element})
|
||||
.pointerDown({button: actions.ButtonType.LEFT})
|
||||
.pointerUp({button: actions.ButtonType.LEFT})
|
||||
.send();
|
||||
}
|
||||
|
||||
promise_test(async () => {
|
||||
const selectMenu0 = document.getElementById("selectMenu0");
|
||||
const selectMenu0Child2 = document.getElementById("selectMenu0-child2");
|
||||
const selectMenu0Child3 = document.getElementById("selectMenu0-child3");
|
||||
assert_equals(selectMenu0.value, "one");
|
||||
await clickOn(selectMenu0);
|
||||
await clickOn(selectMenu0Child2);
|
||||
assert_equals(selectMenu0.value, "two");
|
||||
|
||||
await clickOn(selectMenu0);
|
||||
await clickOn(selectMenu0Child3);
|
||||
assert_equals(selectMenu0.value, "two", "Clicking a non-option should not change the value");
|
||||
}, "Opening the popup and clicking an option should change the selectmenu's value");
|
||||
|
||||
promise_test(async () => {
|
||||
const selectMenu1 = document.getElementById("selectMenu1");
|
||||
const selectMenu1Button = document.getElementById("selectMenu1-button");
|
||||
const selectMenu1Child2 = document.getElementById("selectMenu1-child2");
|
||||
const selectMenu1Child3 = document.getElementById("selectMenu1-child3");
|
||||
assert_equals(selectMenu1.value, "one");
|
||||
await clickOn(selectMenu1Button);
|
||||
await clickOn(selectMenu1Child2);
|
||||
assert_equals(selectMenu1.value, "two", "Clicking an <option> should change the value");
|
||||
|
||||
await clickOn(selectMenu1Button);
|
||||
await clickOn(selectMenu1Child3);
|
||||
assert_equals(selectMenu1.value, "three", "Clicking a <div part='option'> should change the value");
|
||||
}, "With custom button and popup: opening the popup and clicking an option should change the selectmenu's value");
|
||||
|
||||
promise_test(async () => {
|
||||
const selectMenu2 = document.getElementById("selectMenu2");
|
||||
await clickOn(selectMenu2);
|
||||
assert_equals(selectMenu2.value, "");
|
||||
}, "Clicking a popup with no listbox part does nothing");
|
||||
</script>
|
|
@ -0,0 +1,127 @@
|
|||
<!DOCTYPE html>
|
||||
<title>HTMLSelectMenuElement Test: value</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<selectmenu id="selectMenu0"></selectmenu>
|
||||
|
||||
<selectmenu id="selectMenu1">
|
||||
<option>one</option>
|
||||
<option>two</option>
|
||||
<div>I'm a div with no part attr</div>
|
||||
<option>three</option>
|
||||
<option>four</option>
|
||||
</selectmenu>
|
||||
|
||||
<selectmenu id="selectMenu2">
|
||||
<div part="option">one</div>
|
||||
<div part="option">two</div>
|
||||
<div>I'm a div with no part attr</div>
|
||||
<div part="option">three</div>
|
||||
<div part="option">four</div>
|
||||
</selectmenu>
|
||||
|
||||
<selectmenu id="selectMenu3">
|
||||
<div>I'm a div with no part attr</div>
|
||||
<option id="selectMenu3-child1">one</option>
|
||||
<div part="option" id="selectMenu3-child2">two</div>
|
||||
<option id="selectMenu3-child3">three</option>
|
||||
</selectmenu>
|
||||
|
||||
<selectmenu id="selectMenu4">
|
||||
<div part="option" id="selectMenu4-child1">two</div>
|
||||
<div part="option" id="selectMenu4-child2">two</div>
|
||||
</selectmenu>
|
||||
|
||||
<selectmenu id="selectMenu5">
|
||||
<div slot="button" part="button">
|
||||
<div part="selected-value" id="selectMenu5-custom-selected-value">Default custom selected-value text</div>
|
||||
</div>
|
||||
<option>one</option>
|
||||
<option>two</option>
|
||||
</selectmenu>
|
||||
|
||||
<selectmenu id="selectMenu6">
|
||||
<div slot="button" part="button">
|
||||
<div part="selected-value" id="selectMenu6-custom-selected-value">Default custom selected-value text</div>
|
||||
</div>
|
||||
<popup slot="listbox" part="listbox">
|
||||
<option>one</option>
|
||||
<div part="option">two</div>
|
||||
</popup>
|
||||
</selectmenu>
|
||||
|
||||
<script>
|
||||
|
||||
test(() => {
|
||||
const selectMenu0 = document.getElementById("selectMenu0");
|
||||
assert_equals(selectMenu0.value, "");
|
||||
selectMenu0.value = "something";
|
||||
assert_equals(selectMenu0.value, "", "Setting value should have no effect if there is no matching option");
|
||||
}, "Test that HTMLSelectMenu with no options has empty string for value");
|
||||
|
||||
test(() => {
|
||||
const selectMenu1 = document.getElementById("selectMenu1");
|
||||
assert_equals(selectMenu1.value, "one", "value should start with the text of the first option part");
|
||||
|
||||
selectMenu1.value = "three";
|
||||
assert_equals(selectMenu1.value, "three", "value can be set to the text of an option part");
|
||||
|
||||
selectMenu1.value = "I'm a div with no part attr";
|
||||
assert_equals(selectMenu1.value, "three", "Setting value should have no effect if there is no matching option");
|
||||
}, "Test value with HTMLOptionElement element option parts");
|
||||
|
||||
test(() => {
|
||||
const selectMenu2 = document.getElementById("selectMenu2");
|
||||
assert_equals(selectMenu2.value, "one", "value should start with the text of the first option part");
|
||||
|
||||
selectMenu2.value = "three";
|
||||
assert_equals(selectMenu2.value, "three", "value can be set to the text of an option part");
|
||||
|
||||
selectMenu2.value = "I'm a div with no part attr";
|
||||
assert_equals(selectMenu2.value, "three", "Setting value should have no effect if there is no matching option");
|
||||
}, "Test value with non-HTMLOptionElement element option parts");
|
||||
|
||||
test(() => {
|
||||
const selectMenu3 = document.getElementById("selectMenu3");
|
||||
assert_equals(selectMenu3.value, "one", "value should start with the text of the first option part");
|
||||
|
||||
document.getElementById("selectMenu3-child3").remove();
|
||||
assert_equals(selectMenu3.value, "one", "Removing a non-selected option should not change the value");
|
||||
|
||||
document.getElementById("selectMenu3-child1").remove();
|
||||
assert_equals(selectMenu3.value, "two", "When the selected option is removed, the new first option should become selected");
|
||||
|
||||
document.getElementById("selectMenu3-child2").remove();
|
||||
assert_equals(selectMenu3.value, "", "When all options are removed, value should be the empty string");
|
||||
}, "Test that value is updated when options are removed");
|
||||
|
||||
test(() => {
|
||||
const selectMenu4 = document.getElementById("selectMenu4");
|
||||
assert_equals(selectMenu4.value, "one", "value should start with the text of the first option part");
|
||||
|
||||
document.getElementById("selectMenu4-child1").setAttribute("part", "notOption");
|
||||
assert_equals(selectMenu4.value, "two", "Changing the part attribute of the selected option should remove its status as the selected option");
|
||||
}, "Test that value is updated when the part attribute is removed");
|
||||
|
||||
test(() => {
|
||||
const selectMenu5 = document.getElementById("selectMenu5");
|
||||
let customSelectedValuePart = document.getElementById("selectMenu5-custom-selected-value");
|
||||
assert_equals(selectMenu5.value, "one", "value should start with the text of the first option part");
|
||||
assert_equals(customSelectedValuePart.innerText, "one", "Custom selected value part should be set to initial value of selectmenu");
|
||||
|
||||
selectMenu5.value = "two";
|
||||
assert_equals(customSelectedValuePart.innerText, "two", "Custom selected value part should be updated when value of selectmenu changes");
|
||||
}, "Test that slotted-in selected-value part is updated to value of selectmenu");
|
||||
|
||||
test(() => {
|
||||
const selectMenu6 = document.getElementById("selectMenu6");
|
||||
let customSelectedValuePart = document.getElementById("selectMenu6-custom-selected-value");
|
||||
assert_equals(selectMenu6.value, "one", "value should start with the text of the first option part");
|
||||
assert_equals(customSelectedValuePart.innerText, "one", "Custom selected value part should be set to initial value of selectmenu");
|
||||
|
||||
selectMenu6.value = "two";
|
||||
assert_equals(customSelectedValuePart.innerText, "two", "Custom selected value part should be updated when value of selectmenu changes");
|
||||
}, "Test that option parts in a slotted-in listbox are reflected in the value property");
|
||||
|
||||
</script>
|
Загрузка…
Ссылка в новой задаче