Skip to content

Commit 6ba8aae

Browse files
committed
fix(template-no-aria-label-misuse): gate on isNativeElement to exclude custom/namespaced/shadowed tags (Copilot review)
1 parent 4705533 commit 6ba8aae

2 files changed

Lines changed: 15 additions & 6 deletions

File tree

lib/rules/template-no-aria-label-misuse.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// `roles.get(r).prohibitedProps` list drives the flag/allow decision.
55

66
const { roles, elementRoles } = require('aria-query');
7+
const { isNativeElement } = require('../utils/is-native-element');
78

89
function findAttr(node, name) {
910
return node.attributes?.find((attr) => attr.name === name);
@@ -17,11 +18,6 @@ function getStaticAttrString(node, name) {
1718
return attr.value.chars;
1819
}
1920

20-
function isHtmlElement(node) {
21-
const tag = node.tag || '';
22-
return /^[a-z]/.test(tag) && !tag.includes('.') && !tag.startsWith('@');
23-
}
24-
2521
// Score how well an elementRoles entry matches the given node. Returns `null`
2622
// if any constraint fails; otherwise the number of satisfied conditions
2723
// (higher = more specific, used to pick the best match).
@@ -162,10 +158,16 @@ module.exports = {
162158

163159
create(context) {
164160
const strictTabindex = Boolean(context.options[0]?.strictTabindex);
161+
const sourceCode = context.sourceCode || context.getSourceCode();
165162

166163
return {
167164
GlimmerElementNode(node) {
168-
if (!isHtmlElement(node)) {
165+
// Gate on `isNativeElement` to correctly exclude custom elements
166+
// (<my-widget>), colon-namespaced tags (<svg:rect>), named blocks
167+
// (<:slot>), PascalCase components, dotted/at-prefixed path tags,
168+
// and scope-shadowed bindings. The previous first-char regex was
169+
// permissive and misclassified custom elements as native HTML.
170+
if (!isNativeElement(node, sourceCode)) {
169171
return;
170172
}
171173
if (isExplicitlyDecorative(node)) {

tests/lib/rules/template-no-aria-label-misuse.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ const validHbs = [
3030
'<div aria-label=""></div>',
3131
// Ember component — skipped (role unknowable).
3232
'<MyButton aria-label="x" />',
33+
// Custom elements — not in HTML/SVG/MathML tag lists, skipped.
34+
'<my-widget aria-label="x"></my-widget>',
35+
'<emoji-picker aria-label="x"></emoji-picker>',
36+
// Colon-namespaced tags (SVG DOM prefix form) — not enumerable, skipped.
37+
'<svg:rect aria-label="x" />',
38+
// Named blocks (Ember component API) — skipped.
39+
'<:slot aria-label="x" />',
3340
// Elements with no aria-query entry — skipped ("when in doubt, don't flag").
3441
'<audio aria-label="silent"></audio>',
3542
'<input type="hidden" aria-label="x" />',

0 commit comments

Comments
 (0)