Skip to content

Commit 57f55fc

Browse files
committed
fix(template-no-autofocus-attribute): narrow mustache check to native-input helpers (Copilot review)
Previously the GlimmerMustacheStatement visitor fired on ANY mustache with an autofocus hash pair — but arbitrary custom components taking 'autofocus' as a prop are opaque. We can't statically tell whether the prop forwards to a native <input autofocus> or is used for something else. Narrow to the two built-ins that deterministically render a native input: - {{input …}} - {{component "input" …}} Future: when type-aware linting lands (Glint integration or template- type-check), we can resolve custom components that forward 'autofocus' to a native <input> and flag those too. For now we stay conservative to avoid false positives on unrelated helpers.
1 parent c97a131 commit 57f55fc

2 files changed

Lines changed: 49 additions & 0 deletions

File tree

lib/rules/template-no-autofocus-attribute.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,28 @@ function isMustacheBooleanFalse(value) {
3939
*
4040
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog
4141
*/
42+
// Returns true for `{{input ...}}` and `{{component "input" ...}}` mustache
43+
// invocations — the only built-ins that deterministically render a native
44+
// <input> with forwarded attributes.
45+
function isNativeInputHelper(node) {
46+
const path = node.path;
47+
if (!path) {
48+
return false;
49+
}
50+
// Direct invocation: `{{input ...}}`.
51+
if (path.type === 'GlimmerPathExpression' && path.original === 'input') {
52+
return true;
53+
}
54+
// Contextual component: `{{component "input" ...}}`.
55+
if (path.type === 'GlimmerPathExpression' && path.original === 'component') {
56+
const firstParam = node.params && node.params[0];
57+
if (firstParam && firstParam.type === 'GlimmerStringLiteral' && firstParam.value === 'input') {
58+
return true;
59+
}
60+
}
61+
return false;
62+
}
63+
4264
function isInsideDialog(node) {
4365
if (node.type === 'GlimmerElementNode' && node.tag === 'dialog') {
4466
return true;
@@ -127,6 +149,25 @@ module.exports = {
127149
return;
128150
}
129151

152+
// Narrow to helpers that deterministically render a native `autofocus`
153+
// attribute. The rule's purpose is the HTML attribute; arbitrary
154+
// components taking an `autofocus` prop are opaque — we can't tell
155+
// statically whether that prop forwards to HTML or is used for
156+
// something else.
157+
// - `{{input ...}}` — Ember's classic input helper renders a native
158+
// <input> with forwarded attributes.
159+
// - `{{component "input" ...}}` — contextual component resolution
160+
// points at the same helper.
161+
//
162+
// FUTURE: when type-aware linting lands (e.g., Glint integration or
163+
// a template-type-check step), we can resolve custom components that
164+
// forward `autofocus` to a native <input> and flag those too. For now
165+
// we stay conservative to avoid false positives on unrelated helpers
166+
// that happen to take an `autofocus` prop.
167+
if (!isNativeInputHelper(node)) {
168+
return;
169+
}
170+
130171
// Mustache hash-pair `{{input autofocus=false}}` — boolean literal
131172
// false at the hash-pair level is unambiguous and renders no attr.
132173
// Note: `autofocus="false"` in mustache syntax IS still flagged — per

tests/lib/rules/template-no-autofocus-attribute.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ ruleTester.run('template-no-autofocus-attribute', rule, {
6262
</div>
6363
</dialog>
6464
</template>`,
65+
66+
// Custom helpers / components taking an `autofocus` prop are opaque —
67+
// we can't know whether the prop forwards to a native <input autofocus>
68+
// or is used for something else. Narrow to {{input}} / {{component
69+
// "input"}} which deterministically render native inputs.
70+
`<template>{{my-wrapper autofocus=true}}</template>`,
71+
`<template>{{some-component autofocus=true name="foo"}}</template>`,
72+
`<template>{{component "some-other-helper" autofocus=true}}</template>`,
6573
],
6674

6775
invalid: [

0 commit comments

Comments
 (0)