Skip to content

Commit 688cf6b

Browse files
Merge pull request #2424 from NullVoxPopuli/nvp/template-lint-extract-rule-template-no-action-modifiers
Extract rule: template-no-action-modifiers
2 parents 4fc9ccc + 02c44c0 commit 688cf6b

4 files changed

Lines changed: 158 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ rules in templates can be disabled with eslint directives with mustache or html
190190
| Name | Description | 💼 | 🔧 | 💡 |
191191
| :----------------------------------------------------------------------------------------------- | :-------------------------------------------------------- | :- | :- | :- |
192192
| [template-builtin-component-arguments](docs/rules/template-builtin-component-arguments.md) | disallow setting certain attributes on builtin components | | | |
193+
| [template-no-action-modifiers](docs/rules/template-no-action-modifiers.md) | disallow usage of {{action}} modifiers | | | |
193194
| [template-no-arguments-for-html-elements](docs/rules/template-no-arguments-for-html-elements.md) | disallow @arguments on HTML elements | | | |
194195
| [template-no-debugger](docs/rules/template-no-debugger.md) | disallow {{debugger}} in templates | | | |
195196
| [template-no-log](docs/rules/template-no-log.md) | disallow {{log}} in templates | | | |
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# ember/template-no-action-modifiers
2+
3+
<!-- end auto-generated rule header -->
4+
5+
💼 This rule is enabled in the following [configs](https://github.com/ember-cli/eslint-plugin-ember#-configurations): `strict-gjs`, `strict-gts`.
6+
7+
Disallow usage of `{{action}}` modifiers in templates.
8+
9+
The `{{action}}` modifier has been deprecated in favor of the `{{on}}` modifier. The `{{on}}` modifier provides a more explicit and flexible way to handle events.
10+
11+
## Rule Details
12+
13+
This rule disallows using `{{action}}` as an element modifier.
14+
15+
## Examples
16+
17+
### Incorrect ❌
18+
19+
```gjs
20+
<template>
21+
<button {{action "save"}}>Save</button>
22+
</template>
23+
```
24+
25+
```gjs
26+
<template>
27+
<div {{action "onClick"}}>Click me</div>
28+
</template>
29+
```
30+
31+
```gjs
32+
<template>
33+
<form {{action "submit" on="submit"}}>Submit</form>
34+
</template>
35+
```
36+
37+
### Correct ✅
38+
39+
```gjs
40+
<template>
41+
<button {{on "click" this.handleClick}}>Save</button>
42+
</template>
43+
```
44+
45+
```gjs
46+
<template>
47+
<div {{on "click" this.onClick}}>Click me</div>
48+
</template>
49+
```
50+
51+
```gjs
52+
<template>
53+
<form {{on "submit" this.handleSubmit}}>Submit</form>
54+
</template>
55+
```
56+
57+
## Related Rules
58+
59+
- [template-no-action](./template-no-action.md)
60+
61+
## References
62+
63+
- [Ember Octane Guide - Element Modifiers](https://guides.emberjs.com/release/components/template-lifecycle-dom-and-modifiers/)
64+
- [eslint-plugin-ember template-no-action](https://github.com/ember-cli/eslint-plugin-ember/blob/master/docs/rules/template-no-action.md)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/** @type {import('eslint').Rule.RuleModule} */
2+
module.exports = {
3+
meta: {
4+
type: 'suggestion',
5+
docs: {
6+
description: 'disallow usage of {{action}} modifiers',
7+
category: 'Best Practices',
8+
strictGjs: true,
9+
strictGts: true,
10+
url: 'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/template-no-action-modifiers.md',
11+
},
12+
fixable: null,
13+
schema: [],
14+
messages: {
15+
noActionModifier: 'Do not use action modifiers. Use on modifier with a function instead.',
16+
},
17+
},
18+
19+
create(context) {
20+
function checkForActionModifier(node) {
21+
// Check if this is an action modifier (not action helper in mustache)
22+
if (
23+
node.path &&
24+
node.path.type === 'GlimmerPathExpression' &&
25+
node.path.original === 'action' &&
26+
node.path.head?.type !== 'AtHead' &&
27+
node.path.head?.type !== 'ThisHead'
28+
) {
29+
context.report({
30+
node,
31+
messageId: 'noActionModifier',
32+
});
33+
}
34+
}
35+
36+
return {
37+
GlimmerElementModifierStatement(node) {
38+
checkForActionModifier(node);
39+
},
40+
};
41+
},
42+
};
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
const rule = require('../../../lib/rules/template-no-action-modifiers');
2+
const RuleTester = require('eslint').RuleTester;
3+
4+
const ruleTester = new RuleTester({
5+
parser: require.resolve('ember-eslint-parser'),
6+
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
7+
});
8+
9+
ruleTester.run('template-no-action-modifiers', rule, {
10+
valid: [
11+
'<template><button {{on "click" this.handleClick}}>Click</button></template>',
12+
'<template><div {{on "mouseenter" this.onHover}}>Hover</div></template>',
13+
'<template><form {{on "submit" this.handleSubmit}}>Submit</form></template>',
14+
'<template>{{action "myAction"}}</template>',
15+
'<template>{{this.action}}</template>',
16+
'<template>{{@action}}</template>',
17+
],
18+
19+
invalid: [
20+
{
21+
code: '<template><button {{action "save"}}>Save</button></template>',
22+
output: null,
23+
errors: [
24+
{
25+
message: 'Do not use action modifiers. Use on modifier with a function instead.',
26+
type: 'GlimmerElementModifierStatement',
27+
},
28+
],
29+
},
30+
{
31+
code: '<template><div {{action "onClick"}}>Click me</div></template>',
32+
output: null,
33+
errors: [
34+
{
35+
message: 'Do not use action modifiers. Use on modifier with a function instead.',
36+
type: 'GlimmerElementModifierStatement',
37+
},
38+
],
39+
},
40+
{
41+
code: '<template><form {{action "submit" on="submit"}}>Submit</form></template>',
42+
output: null,
43+
errors: [
44+
{
45+
message: 'Do not use action modifiers. Use on modifier with a function instead.',
46+
type: 'GlimmerElementModifierStatement',
47+
},
48+
],
49+
},
50+
],
51+
});

0 commit comments

Comments
 (0)