Skip to content

Commit 46a01ec

Browse files
committed
Extract rule: template-no-at-ember-render-modifiers
1 parent a15aa2a commit 46a01ec

4 files changed

Lines changed: 275 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ rules in templates can be disabled with eslint directives with mustache or html
198198
| [template-no-action-modifiers](docs/rules/template-no-action-modifiers.md) | disallow usage of {{action}} modifiers | | | |
199199
| [template-no-arguments-for-html-elements](docs/rules/template-no-arguments-for-html-elements.md) | disallow @arguments on HTML elements | | | |
200200
| [template-no-array-prototype-extensions](docs/rules/template-no-array-prototype-extensions.md) | disallow usage of Ember Array prototype extensions | | | |
201+
| [template-no-at-ember-render-modifiers](docs/rules/template-no-at-ember-render-modifiers.md) | disallow usage of @ember/render-modifiers | | | |
201202
| [template-no-block-params-for-html-elements](docs/rules/template-no-block-params-for-html-elements.md) | disallow block params on HTML elements | | | |
202203
| [template-no-capital-arguments](docs/rules/template-no-capital-arguments.md) | disallow capital arguments (use lowercase @arg instead of @Arg) | | | |
203204
| [template-no-chained-this](docs/rules/template-no-chained-this.md) | disallow redundant `this.this` in templates | | 🔧 | |
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# ember/template-no-at-ember-render-modifiers
2+
3+
<!-- end auto-generated rule header -->
4+
5+
Disallows usage of modifiers from @ember/render-modifiers.
6+
7+
## Rule Details
8+
9+
The modifiers from `@ember/render-modifiers` (`{{did-insert}}`, `{{did-update}}`, `{{will-destroy}}`) should be replaced with alternatives from `ember-render-helpers` or other modern approaches.
10+
11+
## Examples
12+
13+
Examples of **incorrect** code for this rule:
14+
15+
```gjs
16+
<template>
17+
<div {{did-insert this.setup}}></div>
18+
</template>
19+
```
20+
21+
```gjs
22+
<template>
23+
<div {{did-update this.update}}></div>
24+
</template>
25+
```
26+
27+
```gjs
28+
<template>
29+
<div {{will-destroy this.cleanup}}></div>
30+
</template>
31+
```
32+
33+
Examples of **correct** code for this rule:
34+
35+
```gjs
36+
<template>
37+
<div {{on "click" this.handleClick}}></div>
38+
</template>
39+
```
40+
41+
## Migration
42+
43+
The migration path typically depends on what the render-modifier was used for, but if you need a custom modifier, the [`ember-modifier` README](https://github.com/ember-modifier/ember-modifier) covers everything you need to know for making custom modifiers.
44+
45+
For example, if render modifiers were used for setup/teardown, the migration to `ember-modifier` could be the following:
46+
47+
```js
48+
import Component from '@glimmer/component';
49+
import { modifier } from 'ember-modifier';
50+
51+
export default class MyComponent extends Component {
52+
myModifier = modifier((element) => {
53+
const handleEvent = () => {};
54+
55+
element.addEventListener('eventName', handleEvent);
56+
57+
return () => element.removeEventListener('eventName', handelEvent);
58+
});
59+
}
60+
```
61+
62+
```hbs
63+
<div {{this.myModifier}}>
64+
```
65+
66+
## References
67+
68+
- [eslint-plugin-ember template-no-at-ember-render-modifiers](https://github.com/ember-cli/eslint-plugin-ember/blob/master/docs/rules/template-no-at-ember-render-modifiers.md)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/** @type {import('eslint').Rule.RuleModule} */
2+
module.exports = {
3+
meta: {
4+
type: 'suggestion',
5+
docs: {
6+
description: 'disallow usage of @ember/render-modifiers',
7+
category: 'Best Practices',
8+
url: 'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/template-no-at-ember-render-modifiers.md',
9+
templateMode: 'both',
10+
},
11+
fixable: null,
12+
schema: [],
13+
messages: {
14+
noRenderModifiers:
15+
'Avoid using @ember/render-modifiers. Use (did-insert), (did-update), or (will-destroy) from ember-render-helpers instead.',
16+
},
17+
originallyFrom: {
18+
name: 'ember-template-lint',
19+
rule: 'lib/rules/no-at-ember-render-modifiers.js',
20+
docs: 'docs/rule/no-at-ember-render-modifiers.md',
21+
tests: 'test/unit/rules/no-at-ember-render-modifiers-test.js',
22+
},
23+
},
24+
25+
create(context) {
26+
return {
27+
GlimmerElementNode(node) {
28+
if (!node.modifiers) {
29+
return;
30+
}
31+
32+
for (const modifier of node.modifiers) {
33+
if (
34+
modifier.path &&
35+
modifier.path.type === 'GlimmerPathExpression' &&
36+
(modifier.path.original === 'did-insert' ||
37+
modifier.path.original === 'did-update' ||
38+
modifier.path.original === 'will-destroy')
39+
) {
40+
context.report({
41+
node: modifier,
42+
messageId: 'noRenderModifiers',
43+
});
44+
}
45+
}
46+
},
47+
};
48+
},
49+
};
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
//------------------------------------------------------------------------------
2+
// Requirements
3+
//------------------------------------------------------------------------------
4+
5+
const rule = require('../../../lib/rules/template-no-at-ember-render-modifiers');
6+
const RuleTester = require('eslint').RuleTester;
7+
8+
//------------------------------------------------------------------------------
9+
// Tests
10+
//------------------------------------------------------------------------------
11+
12+
const ruleTester = new RuleTester({
13+
parser: require.resolve('ember-eslint-parser'),
14+
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
15+
});
16+
17+
ruleTester.run('template-no-at-ember-render-modifiers', rule, {
18+
valid: [
19+
`<template>
20+
<div></div>
21+
</template>`,
22+
`<template>
23+
<div {{on "click" this.handleClick}}></div>
24+
</template>`,
25+
`<template>
26+
<MyComponent />
27+
</template>`,
28+
29+
'<template><div {{this.someModifier}}></div></template>',
30+
'<template><div {{someModifier}}></div></template>',
31+
'<template><div {{did-foo}}></div></template>',
32+
'<template>{{did-insert}}</template>',
33+
'<template>{{did-update}}</template>',
34+
'<template>{{will-destroy}}</template>',
35+
],
36+
37+
invalid: [
38+
{
39+
code: `<template>
40+
<div {{did-insert this.setup}}></div>
41+
</template>`,
42+
output: null,
43+
errors: [
44+
{
45+
message:
46+
'Avoid using @ember/render-modifiers. Use (did-insert), (did-update), or (will-destroy) from ember-render-helpers instead.',
47+
type: 'GlimmerElementModifierStatement',
48+
},
49+
],
50+
},
51+
{
52+
code: `<template>
53+
<div {{did-update this.update}}></div>
54+
</template>`,
55+
output: null,
56+
errors: [
57+
{
58+
message:
59+
'Avoid using @ember/render-modifiers. Use (did-insert), (did-update), or (will-destroy) from ember-render-helpers instead.',
60+
type: 'GlimmerElementModifierStatement',
61+
},
62+
],
63+
},
64+
{
65+
code: `<template>
66+
<div {{will-destroy this.cleanup}}></div>
67+
</template>`,
68+
output: null,
69+
errors: [
70+
{
71+
message:
72+
'Avoid using @ember/render-modifiers. Use (did-insert), (did-update), or (will-destroy) from ember-render-helpers instead.',
73+
type: 'GlimmerElementModifierStatement',
74+
},
75+
],
76+
},
77+
78+
{
79+
code: '<template><div {{did-insert}}></div></template>',
80+
output: null,
81+
errors: [
82+
{
83+
message:
84+
'Avoid using @ember/render-modifiers. Use (did-insert), (did-update), or (will-destroy) from ember-render-helpers instead.',
85+
},
86+
],
87+
},
88+
{
89+
code: '<template><div {{did-update}}></div></template>',
90+
output: null,
91+
errors: [
92+
{
93+
message:
94+
'Avoid using @ember/render-modifiers. Use (did-insert), (did-update), or (will-destroy) from ember-render-helpers instead.',
95+
},
96+
],
97+
},
98+
{
99+
code: '<template><div {{will-destroy}}></div></template>',
100+
output: null,
101+
errors: [
102+
{
103+
message:
104+
'Avoid using @ember/render-modifiers. Use (did-insert), (did-update), or (will-destroy) from ember-render-helpers instead.',
105+
},
106+
],
107+
},
108+
],
109+
});
110+
111+
const hbsRuleTester = new RuleTester({
112+
parser: require.resolve('ember-eslint-parser/hbs'),
113+
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
114+
});
115+
116+
hbsRuleTester.run('template-no-at-ember-render-modifiers (hbs)', rule, {
117+
valid: [
118+
'<div {{this.someModifier}}></div>',
119+
'<div {{someModifier}}></div>',
120+
'<div {{did-foo}}></div>',
121+
'{{did-insert}}',
122+
'{{did-update}}',
123+
'{{will-destroy}}',
124+
],
125+
invalid: [
126+
{
127+
code: '<div {{did-insert}}></div>',
128+
output: null,
129+
errors: [
130+
{
131+
message:
132+
'Avoid using @ember/render-modifiers. Use (did-insert), (did-update), or (will-destroy) from ember-render-helpers instead.',
133+
},
134+
],
135+
},
136+
{
137+
code: '<div {{did-update}}></div>',
138+
output: null,
139+
errors: [
140+
{
141+
message:
142+
'Avoid using @ember/render-modifiers. Use (did-insert), (did-update), or (will-destroy) from ember-render-helpers instead.',
143+
},
144+
],
145+
},
146+
{
147+
code: '<div {{will-destroy}}></div>',
148+
output: null,
149+
errors: [
150+
{
151+
message:
152+
'Avoid using @ember/render-modifiers. Use (did-insert), (did-update), or (will-destroy) from ember-render-helpers instead.',
153+
},
154+
],
155+
},
156+
],
157+
});

0 commit comments

Comments
 (0)