Bug 1708702 - Add to radio group after handling type change r=edgar

The previous assumption was that mType would be updated before AfterSetAttr(), but that assumption is invalidated by bug 1347640. This patch moves the radio group addition part to the position after HandleTypeChange() is called.

Differential Revision: https://phabricator.services.mozilla.com/D114038
This commit is contained in:
Kagami Sascha Rosylight 2021-05-03 08:53:02 +00:00
parent 93d94e1a32
commit 69d0e90d28
2 changed files with 42 additions and 27 deletions

View File

@ -1136,24 +1136,25 @@ nsresult HTMLInputElement::BeforeSetAttr(int32_t aNameSpaceID, nsAtom* aName,
const nsAttrValueOrString* aValue,
bool aNotify) {
if (aNameSpaceID == kNameSpaceID_None) {
//
// When name or type changes, radio should be removed from radio group.
// (type changes are handled in the form itself currently)
// If we are not done creating the radio, we also should not do it.
//
if ((aName == nsGkAtoms::name || (aName == nsGkAtoms::type && !mForm)) &&
mType == NS_FORM_INPUT_RADIO && (mForm || mDoneCreating)) {
WillRemoveFromRadioGroup();
} else if (aNotify && aName == nsGkAtoms::disabled) {
if (aNotify && aName == nsGkAtoms::disabled) {
mDisabledChanged = true;
} else if (mType == NS_FORM_INPUT_RADIO && aName == nsGkAtoms::required) {
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
}
if (container && ((aValue && !HasAttr(aNameSpaceID, aName)) ||
(!aValue && HasAttr(aNameSpaceID, aName)))) {
nsAutoString name;
GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
container->RadioRequiredWillChange(name, !!aValue);
// When name or type changes, radio should be removed from radio group.
// If we are not done creating the radio, we also should not do it.
if (mType == NS_FORM_INPUT_RADIO) {
if ((aName == nsGkAtoms::name || (aName == nsGkAtoms::type && !mForm)) &&
(mForm || mDoneCreating)) {
WillRemoveFromRadioGroup();
} else if (aName == nsGkAtoms::required) {
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
if (container && ((aValue && !HasAttr(aNameSpaceID, aName)) ||
(!aValue && HasAttr(aNameSpaceID, aName)))) {
nsAutoString name;
GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
container->RadioRequiredWillChange(name, !!aValue);
}
}
}
@ -1172,17 +1173,6 @@ nsresult HTMLInputElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
nsIPrincipal* aSubjectPrincipal,
bool aNotify) {
if (aNameSpaceID == kNameSpaceID_None) {
//
// When name or type changes, radio should be added to radio group.
// (type changes are handled in the form itself currently)
// If we are not done creating the radio, we also should not do it.
//
if ((aName == nsGkAtoms::name || (aName == nsGkAtoms::type && !mForm)) &&
mType == NS_FORM_INPUT_RADIO && (mForm || mDoneCreating)) {
AddedToRadioGroup();
UpdateValueMissingValidityStateForRadio(false);
}
if (aName == nsGkAtoms::src) {
mSrcTriggeringPrincipal = nsContentUtils::GetAttrTriggeringPrincipal(
this, aValue ? aValue->GetStringValue() : EmptyString(),
@ -1241,6 +1231,14 @@ nsresult HTMLInputElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
}
}
// When name or type changes, radio should be added to radio group.
// If we are not done creating the radio, we also should not do it.
if ((aName == nsGkAtoms::name || (aName == nsGkAtoms::type && !mForm)) &&
mType == NS_FORM_INPUT_RADIO && (mForm || mDoneCreating)) {
AddedToRadioGroup();
UpdateValueMissingValidityStateForRadio(false);
}
if (aName == nsGkAtoms::required || aName == nsGkAtoms::disabled ||
aName == nsGkAtoms::readonly) {
if (aName == nsGkAtoms::disabled) {

View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<title>Morphed radio input</title>
<link rel="author" title="Kagami Sascha Rosylight" href="mailto:krosylight@mozilla.com">
<link rel="help" href="https://html.spec.whatwg.org/#radio-button-state-(type=radio)">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<input id="radio" type="radio" name="name_7" checked>
<input id="text" name="name_7" checked>
<script>
"use strict";
test(() => {
text.type = 'radio';
assert_false(radio.checked);
}, "Setting type attribute must unset checkedness of other elements");
</script>