Skip to content

Post-merge-review: fix template-no-passed-in-event-handlers ignore-config format and event list#2662

Merged
NullVoxPopuli merged 6 commits intoember-cli:masterfrom
johanrd:night_fix/template-no-passed-in-event-handlers
Apr 16, 2026
Merged

Post-merge-review: fix template-no-passed-in-event-handlers ignore-config format and event list#2662
NullVoxPopuli merged 6 commits intoember-cli:masterfrom
johanrd:night_fix/template-no-passed-in-event-handlers

Conversation

@johanrd
Copy link
Copy Markdown
Contributor

@johanrd johanrd commented Apr 13, 2026

What's broken on master

Two independent issues:

  1. ignore-config format broken for angle-bracket invocations. The port compares ignoredAttrs.includes(attr.name) where attr.name === '@click'. The docs say to configure { Foo: ['click'] } (bare name, no @) — but with the current code that never matches. Upstream slices the @ off first (no-passed-in-event-handlers.js L107–112) and explicitly rejects @-prefixed ignore entries as invalid config.

  2. Event list diverged from upstream. Master includes mouseMove, mouseEnter, mouseLeave — these are native DOM events but don't have corresponding Ember classic-event method aliases (the mechanism the rule is protecting against). Upstream omits them.

Fix

  • Match ignore config against argName (the @-stripped form).
  • Drop mouseMove / mouseEnter / mouseLeave from EMBER_EVENTS to align with upstream.

Test plan

  • 72/72 tests pass on the branch
  • 8 existing tests changed from ['@click'] to ['click'] (the documented format). All 8 fail on master with the format fix reverted.
  • 3 new valid tests confirm mouseMove / mouseEnter / mouseLeave are no longer flagged.

Out of scope

The component-detection broadening (covering <this.X>, <@x>, <ns.X>) was reverted — those forms are better addressed via scope analysis if ember-eslint-parser exposes richer HBS scope.

…e config with upstream

- Remove mouseMove, mouseEnter, mouseLeave from event list (not in upstream)
- Use bare names (without @) in ignore config for angle bracket invocations
- Remove unnecessary PascalCase gate on ElementNode visitor
@johanrd johanrd force-pushed the night_fix/template-no-passed-in-event-handlers branch from be7fce9 to 050d2bf Compare April 13, 2026 10:01
@johanrd johanrd marked this pull request as ready for review April 13, 2026 10:29
'contextMenu',
'click',
'doubleClick',
'mouseMove',
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why were these removed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mouseMove, mouseEnter, and mouseLeave were removed to align with the upstream ember-template-lint no-passed-in-event-handlers list. Those three are native DOM events but don't have corresponding Ember classic-event method aliases (the mechanism the rule is protecting against).

GlimmerElementNode(node) {
// Only check component invocations (PascalCase)
if (!/^[A-Z]/.test(node.tag)) {
// Only check component invocations. In GTS, dashed tags like <my-button>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we might be able to check if something is a reference via the scope manager?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, though, is the rule even relevant in GJS/GTS? The pattern it guards against (@OnClick={{handler}} passed to a classic component's event method) is a classic component convention. In strict mode all components are Glimmer components and there's no classic event system (right?), so no component would consume these args that way. Should this perhaps be templateMode: 'loose' (HBS-only)?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's still relevant yes, as a classic is just a compoennt that extends from @ember/component, which can be used in strict mode

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay, good point.

we might be able to check if something is a reference via the scope manager?

To my understanding, scope does work for direct tag references in GTS — scope.references would resolve <Foo> if Foo is imported. But the three forms this PR specifically adds (<this.MyComponent>, <@someComponent>, <ns.Widget>) are property accesses and argument references, not direct variable bindings, so scope analysis doesn't reach them even in GTS.

In HBS mode the scope manager is intentionally empty, so scope alone can't carry the full check in either case. The current heuristic covers all four forms in both modes. We could layer a scope check on top for the GTS direct-reference case? (even if it wouldn't replace the heuristic fully?). not sure at all.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds like we have a bug in our scope implementation that we need to fix.

We could layer a scope check on top for the GTS direct-reference case? (even if it wouldn't replace the heuristic fully?). not sure at all.

It could replace the heuristic fully (because component is not defined by casing, but by <syntax>, like... you don't know that <div> isn't a component without scope analysis). the heuristic is only needed when scope would not be available (and is imperfect due to app tree merging).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't able to solve 'replacing the heuristic fully' so I just reverted the component-detection broadening from this PR to move on the other parts.

johanrd added 3 commits April 13, 2026 20:53
…event-handlers

Removes the PascalCase-OR-@-OR-this.-OR-dot heuristic and the associated
tests for <this.MyComponent>, <@someComponent>, <ns.Widget>, <my-button>,
<custom-el>. Reverts to master's PascalCase-only gate.

Better addressed by scope analysis once ember-eslint-parser exposes
richer HBS scope — revisit as a separate PR then.

Keeps the ignore-config format fix (argName without @) and the event
list alignment with upstream.
@johanrd johanrd changed the title Post-merge-review: Fix template-no-passed-in-event-handlers: correct event list, fix ignore-config format, broaden component detection Post-merge-review: fix template-no-passed-in-event-handlers ignore-config format and event list Apr 15, 2026
@johanrd johanrd requested a review from NullVoxPopuli April 15, 2026 20:13
@NullVoxPopuli NullVoxPopuli merged commit 2707d89 into ember-cli:master Apr 16, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants