Skip to content

Commit a578a8d

Browse files
Fix linting issues in template rules - address CI failures
Co-authored-by: NullVoxPopuli <[email protected]>
1 parent fb53ebd commit a578a8d

40 files changed

Lines changed: 338 additions & 177 deletions

docs/rules/template-deprecated-render-helper.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@ Disallows the {{render}} helper which is deprecated.
99
## Examples
1010

1111
Incorrect:
12+
1213
```gjs
1314
<template>{{render "user"}}</template>
1415
```
1516

1617
Correct:
18+
1719
```gjs
1820
<template><User /></template>
1921
```

docs/rules/template-no-forbidden-elements.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
<!-- end auto-generated rule header -->
44

5+
## Config
6+
7+
This rule takes an array of element names to forbid.
8+
59
## Examples
610

711
See ember-template-lint documentation.

lib/rules/template-deprecated-render-helper.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ module.exports = {
1313
schema: [],
1414
messages: {
1515
deprecated:
16-
'The `{{render}}` helper is deprecated in favor of using components. See https://emberjs.com/deprecations/v2.x/#toc_code-render-code-helper',
16+
'The render helper is deprecated in favor of using components. See https://emberjs.com/deprecations/v2.x/#toc_code-render-code-helper',
1717
},
1818
},
1919

lib/rules/template-link-rel-noopener.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,17 @@ module.exports = {
1818
create(context) {
1919
return {
2020
GlimmerElementNode(node) {
21-
if (node.tag !== 'a') return;
22-
21+
if (node.tag !== 'a') {
22+
return;
23+
}
24+
2325
const targetAttr = node.attributes?.find((a) => a.name === 'target');
24-
if (!targetAttr?.value || targetAttr.value.type !== 'GlimmerTextNode') return;
25-
if (targetAttr.value.chars !== '_blank') return;
26+
if (!targetAttr?.value || targetAttr.value.type !== 'GlimmerTextNode') {
27+
return;
28+
}
29+
if (targetAttr.value.chars !== '_blank') {
30+
return;
31+
}
2632

2733
const relAttr = node.attributes?.find((a) => a.name === 'rel');
2834
const hasProperRel =

lib/rules/template-no-abstract-roles.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ module.exports = {
2727
fixable: null,
2828
schema: [],
2929
messages: {
30-
abstractRole: '{{role}} is an abstract role, and is not a valid value for the role attribute.',
30+
abstractRole:
31+
'{{role}} is an abstract role, and is not a valid value for the role attribute.',
3132
},
3233
},
3334

lib/rules/template-no-action.js

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,22 @@
1+
function isActionHelper(node) {
2+
if (!node.path || node.path.type !== 'GlimmerPathExpression') {
3+
return false;
4+
}
5+
6+
// Check if it's the action helper (not this.action or @action)
7+
const path = node.path;
8+
if (path.original === 'action') {
9+
// Check head.type to avoid deprecated data/this properties
10+
const head = path.head;
11+
if (head && (head.type === 'AtHead' || head.type === 'ThisHead')) {
12+
return false;
13+
}
14+
return true;
15+
}
16+
17+
return false;
18+
}
19+
120
/** @type {import('eslint').Rule.RuleModule} */
221
module.exports = {
322
meta: {
@@ -12,31 +31,13 @@ module.exports = {
1231
fixable: null,
1332
schema: [],
1433
messages: {
15-
subExpression: 'Do not use `action` as (action ...). Instead, use the `on` modifier and `fn` helper.',
16-
mustache: 'Do not use `action` as {{action ...}}. Instead, use the `on` modifier and `fn` helper.',
34+
subExpression:
35+
'Do not use `action` as (action ...). Instead, use the `on` modifier and `fn` helper.',
36+
mustache: 'Do not use `action` in templates. Instead, use the `on` modifier and `fn` helper.',
1737
},
1838
},
1939

2040
create(context) {
21-
function isActionHelper(node) {
22-
if (!node.path || node.path.type !== 'GlimmerPathExpression') {
23-
return false;
24-
}
25-
26-
// Check if it's the action helper (not this.action or @action)
27-
const path = node.path;
28-
if (path.original === 'action') {
29-
// Check head.type to avoid deprecated data/this properties
30-
const head = path.head;
31-
if (head && (head.type === 'AtHead' || head.type === 'ThisHead')) {
32-
return false;
33-
}
34-
return true;
35-
}
36-
37-
return false;
38-
}
39-
4041
return {
4142
GlimmerSubExpression(node) {
4243
if (isActionHelper(node)) {

lib/rules/template-no-duplicate-attributes.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,13 @@ module.exports = {
4040
const text = sourceCode.getText();
4141
const attrStart = attr.range[0];
4242
const attrEnd = attr.range[1];
43-
43+
4444
// Look for whitespace before the attribute
4545
let removeStart = attrStart;
4646
while (removeStart > 0 && /\s/.test(text[removeStart - 1])) {
4747
removeStart--;
4848
}
49-
49+
5050
return fixer.removeRange([removeStart, attrEnd]);
5151
},
5252
});

lib/rules/template-no-input-tagname.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ module.exports = {
1414
},
1515
create(context) {
1616
function check(node) {
17-
if (!node.path) return;
17+
if (!node.path) {
18+
return;
19+
}
1820
const attrs = node.hash?.pairs || [];
1921
const hasTagName = attrs.some((a) => a.key === 'tagName');
20-
22+
2123
if (node.path.original === 'input' && hasTagName) {
2224
context.report({ node, messageId: 'unexpected' });
2325
} else if (

lib/rules/template-no-obsolete-elements.js

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,33 @@
1-
const OBSOLETE = ['acronym', 'applet', 'basefont', 'bgsound', 'big', 'blink', 'center', 'dir', 'font', 'frame', 'frameset', 'isindex', 'keygen', 'listing', 'marquee', 'menuitem', 'multicol', 'nextid', 'nobr', 'noembed', 'noframes', 'plaintext', 's', 'spacer', 'strike', 'tt', 'u', 'xmp'];
1+
const OBSOLETE = [
2+
'acronym',
3+
'applet',
4+
'basefont',
5+
'bgsound',
6+
'big',
7+
'blink',
8+
'center',
9+
'dir',
10+
'font',
11+
'frame',
12+
'frameset',
13+
'isindex',
14+
'keygen',
15+
'listing',
16+
'marquee',
17+
'menuitem',
18+
'multicol',
19+
'nextid',
20+
'nobr',
21+
'noembed',
22+
'noframes',
23+
'plaintext',
24+
's',
25+
'spacer',
26+
'strike',
27+
'tt',
28+
'u',
29+
'xmp',
30+
];
231
/** @type {import('eslint').Rule.RuleModule} */
332
module.exports = {
433
meta: {

lib/rules/template-no-quoteless-attributes.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ module.exports = {
1919
return {
2020
GlimmerAttrNode(node) {
2121
// Check if attribute has text value without quotes
22-
if (node.value?.type === 'GlimmerTextNode' && !node.value.chars.match(/^["']/)) {
22+
if (node.value?.type === 'GlimmerTextNode' && !/^["']/.test(node.value.chars)) {
2323
const sourceCode = context.sourceCode;
2424
const attrText = sourceCode.getText(node);
25-
25+
2626
// If value looks unquoted (no = or =value without quotes)
2727
if (/=\s*[^"'{]/.test(attrText)) {
2828
const type = node.name?.startsWith('@') ? 'Argument' : 'Attribute';

0 commit comments

Comments
 (0)