tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit d92adb49f9f3d9975e85c64da3357b93ce88af29
parent 592bf213da405cddeea55e72cd73a7f2d5d90231
Author: Tim Giles <tgiles@mozilla.com>
Date:   Wed, 12 Nov 2025 16:30:20 +0000

Bug 1991743 - Add form behavior for SelectControl. r=mkennedy

In order for moz-radio-group to behave correctly when used in a form, we
needed to add the `formAssociated` property to the SelectControl class
and implement `setFormValue` and `formResetCallback`.

Differential Revision: https://phabricator.services.mozilla.com/D269048

Diffstat:
Mtoolkit/content/tests/widgets/test_moz_input_elems_in_form.html | 112++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
Mtoolkit/content/widgets/lit-select-control.mjs | 14++++++++++++++
2 files changed, 114 insertions(+), 12 deletions(-)

diff --git a/toolkit/content/tests/widgets/test_moz_input_elems_in_form.html b/toolkit/content/tests/widgets/test_moz_input_elems_in_form.html @@ -36,6 +36,14 @@ value="checkbox_val" checked="" ></moz-checkbox> + <moz-radio-group name="moz-radio-group" value="radio_val_1"> + <moz-radio value="radio_val_1"></moz-radio> + <moz-radio value="radio_val_2"></moz-radio> + </moz-radio-group> + <moz-select name="moz-select" value="select_val_1"> + <moz-option value="select_val_1"></moz-option> + <moz-option value="select_val_2"></moz-option> + </moz-select> <moz-toggle name="moz-toggle" value="toggle_val" @@ -61,6 +69,22 @@ checked="" form="form-attribute-id" ></moz-checkbox> + <moz-radio-group + name="moz-radio-group" + value="radio_val_1" + form="form-attribute-id" + > + <moz-radio value="radio_val_1"></moz-radio> + <moz-radio value="radio_val_2"></moz-radio> + </moz-radio-group> + <moz-select + name="moz-select" + value="select_val_1" + form="form-attribute-id" + > + <moz-option value="select_val_1"></moz-option> + <moz-option value="select_val_2"></moz-option> + </moz-select> <moz-toggle name="moz-toggle" value="toggle_val" @@ -93,6 +117,16 @@ "moz-checkbox, when checked, should have a submitted value" ); is( + formData.get("moz-radio-group"), + "radio_val_1", + "moz-radio-group should have a submitted value" + ); + is( + formData.get("moz-select"), + "select_val_1", + "moz-select should have a submitted value" + ); + is( formData.get("moz-toggle"), "toggle_val", "moz-toggle should have a submitted value" @@ -121,11 +155,19 @@ event.preventDefault(); const formData = new FormData(form); for (let [key, value] of formData) { - is( - value, - "non-default value", - `${key} should have a non-default submitted value` - ); + if (key === "moz-radio-group") { + is( + value, + "radio_val_2", + `${key} should have a non-default value` + ); + } else { + is( + value, + "non-default value", + `${key} should have a non-default submitted value` + ); + } } }; form.addEventListener( @@ -135,7 +177,11 @@ ); let fieldset = form.querySelector("moz-fieldset"); for (let c of fieldset.children) { - c.value = "non-default value"; + if (c.name === "moz-radio-group") { + c.value = "radio_val_2"; + } else { + c.value = "non-default value"; + } } // Wait for the input elements to update before clicking the @@ -198,6 +244,16 @@ "moz-checkbox should reset to default value" ); is( + formData.get("moz-radio-group"), + document.querySelector("moz-radio-group").getAttribute("value"), + "moz-radio-group should reset to default value" + ); + is( + formData.get("moz-select"), + document.querySelector("moz-select").getAttribute("value"), + "moz-select should reset to default value" + ); + is( formData.get("moz-toggle"), document.querySelector("moz-toggle").getAttribute("value"), "moz-toggle should reset to default value" @@ -268,6 +324,16 @@ "moz-checkbox, when checked, should have a submitted value" ); is( + formData.get("moz-radio-group"), + "radio_val_1", + "moz-radio-group should have a submitted value" + ); + is( + formData.get("moz-select"), + "select_val_1", + "moz-select should have a submitted value" + ); + is( formData.get("moz-toggle"), "toggle_val", "moz-toggle should have a submitted value" @@ -296,11 +362,19 @@ event.preventDefault(); const formData = new FormData(form); for (let [key, value] of formData) { - is( - value, - "non-default value", - `${key} should have a non-default submitted value` - ); + if (key === "moz-radio-group") { + is( + value, + "radio_val_2", + `${key} should have a non-default value` + ); + } else { + is( + value, + "non-default value", + `${key} should have a non-default submitted value` + ); + } } }; form.addEventListener( @@ -310,7 +384,11 @@ ); let fieldset = document.querySelector("div moz-fieldset"); for (let c of fieldset.children) { - c.value = "non-default value"; + if (c.name === "moz-radio-group") { + c.value = "radio_val_2"; + } else { + c.value = "non-default value"; + } } // Wait for the input elements to update before clicking the @@ -380,6 +458,16 @@ "moz-checkbox should reset to default value" ); is( + formData.get("moz-radio-group"), + document.querySelector("moz-radio-group").getAttribute("value"), + "moz-radio-group should reset to default value" + ); + is( + formData.get("moz-select"), + document.querySelector("moz-select").getAttribute("value"), + "moz-select should reset to default value" + ); + is( formData.get("moz-toggle"), document.querySelector("moz-toggle").getAttribute("value"), "moz-toggle should reset to default value" diff --git a/toolkit/content/widgets/lit-select-control.mjs b/toolkit/content/widgets/lit-select-control.mjs @@ -39,10 +39,12 @@ const NAVIGATION_DIRECTIONS = { * expected. */ export class SelectControlBaseElement extends MozLitElement { + static formAssociated = true; #childElements; #value; #checkedIndex; #focusedIndex; + #internals; static properties = { type: { type: String }, @@ -61,6 +63,7 @@ export class SelectControlBaseElement extends MozLitElement { set value(newValue) { this.#value = newValue; + this.#internals.setFormValue(newValue); this.childElements.forEach((item, index) => { let isChecked = this.value === item.value; item.checked = isChecked; @@ -136,11 +139,19 @@ export class SelectControlBaseElement extends MozLitElement { } return this.#childElements; } + get form() { + return this.#internals.form; + } + + formResetCallback() { + this.value = this.getAttribute("value"); + } constructor() { super(); this.type = "radio"; this.disabled = false; + this.#internals = this.attachInternals(); this.addEventListener("blur", e => this.handleBlur(e), true); this.addEventListener("keydown", e => this.handleKeydown(e)); } @@ -263,6 +274,9 @@ export class SelectControlBaseElement extends MozLitElement { item.role = childRole; }); } + if (changedProperties.has("value")) { + this.#internals.setFormValue(this.value); + } } handleSetName() {