Skip to content

Commit 1584329

Browse files
Address code review feedback - improve autofixes and handle edge cases
Co-authored-by: NullVoxPopuli <[email protected]>
1 parent 906507c commit 1584329

5 files changed

Lines changed: 41 additions & 16 deletions

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,19 @@ module.exports = {
3535
messageId,
3636
data: { name: key },
3737
fix(fixer) {
38-
// Remove the duplicate attribute
39-
return fixer.remove(attr);
38+
// Remove the duplicate attribute including preceding whitespace
39+
const sourceCode = context.sourceCode;
40+
const text = sourceCode.getText();
41+
const attrStart = attr.range[0];
42+
const attrEnd = attr.range[1];
43+
44+
// Look for whitespace before the attribute
45+
let removeStart = attrStart;
46+
while (removeStart > 0 && /\s/.test(text[removeStart - 1])) {
47+
removeStart--;
48+
}
49+
50+
return fixer.removeRange([removeStart, attrEnd]);
4051
},
4152
});
4253
} else {

lib/rules/template-no-positive-tabindex.js

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ module.exports = {
7979
schema: [],
8080
messages: {
8181
positive: 'Avoid positive integer values for tabindex.',
82-
invalid: 'Tabindex values must be negative numeric.',
8382
},
8483
},
8584

@@ -94,14 +93,9 @@ module.exports = {
9493

9594
const tabindexValue = parseTabindexValue(tabindexAttr.value);
9695

97-
if (tabindexValue === null) {
98-
// Can't determine the value, might be a variable reference
99-
// Report as potentially invalid
100-
context.report({
101-
node: tabindexAttr,
102-
messageId: 'invalid',
103-
});
104-
} else if (tabindexValue > 0) {
96+
// Only report if we can determine the value and it's positive
97+
// Dynamic values (variables) cannot be validated at lint time
98+
if (tabindexValue !== null && tabindexValue > 0) {
10599
context.report({
106100
node: tabindexAttr,
107101
messageId: 'positive',

lib/rules/template-require-button-type.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,15 @@ module.exports = {
6666
node: typeAttr,
6767
messageId: 'invalid',
6868
fix(fixer) {
69-
return fixer.replaceText(typeAttr, 'type="button"');
69+
// Use context-aware default like we do for missing type
70+
const defaultType = hasParentForm(node) ? 'submit' : 'button';
71+
return fixer.replaceText(typeAttr, `type="${defaultType}"`);
7072
},
7173
});
7274
}
7375
}
76+
// Note: Dynamic type values (e.g., type={{this.dynamicType}}) cannot be
77+
// validated at lint time, so we don't report them as errors
7478
},
7579
};
7680
},

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ ruleTester.run('template-no-duplicate-attributes', rule, {
3838
<div class="foo" class="bar"></div>
3939
</template>`,
4040
output: `<template>
41-
<div class="foo" ></div>
41+
<div class="foo"></div>
4242
</template>`,
4343
errors: [{
4444
message: "Duplicate attribute 'class' found in the Element.",
@@ -50,7 +50,7 @@ ruleTester.run('template-no-duplicate-attributes', rule, {
5050
<input type="text" disabled type="email" />
5151
</template>`,
5252
output: `<template>
53-
<input type="text" disabled />
53+
<input type="text" disabled />
5454
</template>`,
5555
errors: [{
5656
message: "Duplicate attribute 'type' found in the Element.",
@@ -62,7 +62,7 @@ ruleTester.run('template-no-duplicate-attributes', rule, {
6262
{{helper foo="bar" foo="baz"}}
6363
</template>`,
6464
output: `<template>
65-
{{helper foo="bar" }}
65+
{{helper foo="bar"}}
6666
</template>`,
6767
errors: [{
6868
message: "Duplicate attribute 'foo' found in the MustacheStatement.",
@@ -76,7 +76,7 @@ ruleTester.run('template-no-duplicate-attributes', rule, {
7676
{{/if}}
7777
</template>`,
7878
output: `<template>
79-
{{#if condition key="a" }}
79+
{{#if condition key="a"}}
8080
content
8181
{{/if}}
8282
</template>`,

tests/lib/rules/template-require-button-type.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,21 @@ ruleTester.run('template-require-button-type', rule, {
7171
type: 'GlimmerAttrNode',
7272
}],
7373
},
74+
{
75+
code: `<template>
76+
<form>
77+
<button type="invalid">Submit</button>
78+
</form>
79+
</template>`,
80+
output: `<template>
81+
<form>
82+
<button type="submit">Submit</button>
83+
</form>
84+
</template>`,
85+
errors: [{
86+
message: 'Button type must be "button", "submit", or "reset"',
87+
type: 'GlimmerAttrNode',
88+
}],
89+
},
7490
],
7591
});

0 commit comments

Comments
 (0)