commit 2002947047756f9326c0d39df377e653834f5226
parent 8d8e707917a06369603b4428c2db8c6fa88590d9
Author: Emilio Cobos Álvarez <emilio@crisal.io>
Date: Thu, 8 Jan 2026 21:09:22 +0000
Bug 2009101 - Make selected attribute also check radio buttons. r=smaug
This matches the previous behavior, though it's a bit weird tbh. I guess
you can make the argument that html <option selected> also toggles
:checked, so...
Differential Revision: https://phabricator.services.mozilla.com/D278270
Diffstat:
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/dom/xul/XULButtonElement.cpp b/dom/xul/XULButtonElement.cpp
@@ -245,8 +245,7 @@ void XULButtonElement::ExecuteMenu(Modifiers aModifiers, int16_t aButton,
// Flip "checked" state if we're a checkbox menu, or an un-checked radio menu.
bool needToFlipChecked = false;
if (*menuType == MenuType::Checkbox ||
- (*menuType == MenuType::Radio &&
- !State().HasState(ElementState::CHECKED))) {
+ (*menuType == MenuType::Radio && !GetBoolAttr(nsGkAtoms::checked))) {
needToFlipChecked = !AttrValueIs(kNameSpaceID_None, nsGkAtoms::autocheck,
nsGkAtoms::_false, eCaseMatters);
}
@@ -722,8 +721,15 @@ void XULButtonElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
if (aNamespaceID != kNameSpaceID_None) {
return;
}
- if (aName == nsGkAtoms::checked && mCheckable) {
- SetStates(ElementState::CHECKED, !!aValue, aNotify);
+ if (mCheckable &&
+ (aName == nsGkAtoms::checked || aName == nsGkAtoms::selected)) {
+ // <menuitem> uses checked for type=radio / type=checkbox and selected for
+ // menulists. <radio> uses selected, but <checkbox> uses checked. We just
+ // make both work for simplicity (also matches historical behavior).
+ const bool checked =
+ aValue || GetBoolAttr(aName == nsGkAtoms::checked ? nsGkAtoms::selected
+ : nsGkAtoms::checked);
+ SetStates(ElementState::CHECKED, checked, aNotify);
}
if (aName == nsGkAtoms::disabled) {
SetStates(ElementState::DISABLED, !!aValue, aNotify);
@@ -734,7 +740,7 @@ void XULButtonElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
const bool shouldUncheckSiblings = [&] {
if (aName == nsGkAtoms::type || aName == nsGkAtoms::name) {
return *GetMenuType() == MenuType::Radio &&
- State().HasState(ElementState::CHECKED);
+ GetBoolAttr(nsGkAtoms::checked);
}
if (aName == nsGkAtoms::checked && aValue) {
return *GetMenuType() == MenuType::Radio;