diff --git a/accessibility-checker-engine/src/v4/rules/widget_tabbable_single.ts b/accessibility-checker-engine/src/v4/rules/widget_tabbable_single.ts index c7c6fd72c..3fb933900 100644 --- a/accessibility-checker-engine/src/v4/rules/widget_tabbable_single.ts +++ b/accessibility-checker-engine/src/v4/rules/widget_tabbable_single.ts @@ -76,13 +76,13 @@ export const widget_tabbable_single: Rule = { while (count < 2 && nw.nextNode() && nw.node != ruleContext) { if (nw.node.nodeType == 1 && !nw.bEndTag && CommonUtil.isTabbable(nw.node)) { // Radio inputs with the same name natively are only one tab stop - if (nw.node.nodeName.toLowerCase() === 'input' && (nw.node as Element).getAttribute("type") === 'radio') { + /**if (nw.node.nodeName.toLowerCase() === 'input' && (nw.node as Element).getAttribute("type") === 'radio') { let curName = (nw.node as Element).getAttribute("name"); if (name.includes(curName)) continue; else name.push(curName); - } + }*/ ++count; } } diff --git a/accessibility-checker-engine/src/v4/util/CommonUtil.ts b/accessibility-checker-engine/src/v4/util/CommonUtil.ts index f3054ff7b..d4ba33b63 100644 --- a/accessibility-checker-engine/src/v4/util/CommonUtil.ts +++ b/accessibility-checker-engine/src/v4/util/CommonUtil.ts @@ -49,7 +49,32 @@ export class CommonUtil { }, "iframe": true, "input": function (element): boolean { - return element.getAttribute("type") !== "hidden" && !element.hasAttribute("disabled"); + if (element.hasAttribute("disabled") || element.getAttribute("type") === "hidden") return false; + if (element.getAttribute("type") === "radio") { + const name = element.getAttribute("name"); + if (!name || name.trim().length === 0) return true; //single radio, no group + let doc = element.ownerDocument; + const group = doc.querySelectorAll("input[type='radio'][name='" + name.trim() +"']"); + if (group.length === 0 || group.length === 1) return true; //single radio with the name, no others in group + + let checked = null; + for (let i = 0; i < group.length; i++) { + if ((group[i] as HTMLInputElement).checked) + checked = group[i]; + } + //only last one applies if multiple radios with 'checked' attributes + if (checked !== null) { + if (DOMUtil.sameNode(checked, element)) + return true; + return false; + } else { + // if nothing checked yet, return true if it's the first element + if (DOMUtil.sameNode(group[0], element)) + return true; + return false; + } + } else + return true; }, "select": function (element): boolean { return !element.hasAttribute("disabled"); diff --git a/accessibility-checker-engine/test/v2/checker/accessibility/rules/widget_tabbable_single_ruleunit/fieldset.html b/accessibility-checker-engine/test/v2/checker/accessibility/rules/widget_tabbable_single_ruleunit/fieldset.html new file mode 100755 index 000000000..8a071e64e --- /dev/null +++ b/accessibility-checker-engine/test/v2/checker/accessibility/rules/widget_tabbable_single_ruleunit/fieldset.html @@ -0,0 +1,296 @@ + + + + +
+