Skip to content

Commit 707de8d

Browse files
Merge pull request #2687 from johanrd/day_fix/template-no-arguments-for-html-elements
Post-merge-review: Fix template-no-arguments-for-html-elements: add svg and mathml elements
2 parents fd67dd9 + 0ef88a7 commit 707de8d

File tree

4 files changed

+48
-7
lines changed

4 files changed

+48
-7
lines changed

lib/rules/template-no-arguments-for-html-elements.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
/** @type {import('eslint').Rule.RuleModule} */
21
const htmlTags = require('html-tags');
2+
const svgTags = require('svg-tags');
3+
const { mathmlTagNames } = require('mathml-tag-names');
4+
5+
const ELEMENT_TAGS = new Set([...htmlTags, ...svgTags, ...mathmlTagNames]);
36

7+
/** @type {import('eslint').Rule.RuleModule} */
48
module.exports = {
59
meta: {
610
type: 'problem',
@@ -26,23 +30,21 @@ module.exports = {
2630

2731
create(context) {
2832
const sourceCode = context.sourceCode;
29-
const HTML_ELEMENTS = new Set(htmlTags);
3033

3134
return {
3235
GlimmerElementNode(node) {
33-
// Check if this is an HTML element (lowercase)
34-
if (!HTML_ELEMENTS.has(node.tag)) {
36+
if (!ELEMENT_TAGS.has(node.tag)) {
3537
return;
3638
}
3739

38-
// If the tag name is a variable in scope, it's being used as a component, not an HTML element
40+
// A known HTML/SVG tag can still be a component if it's bound in scope
41+
// (block param, import, local).
3942
const scope = sourceCode.getScope(node.parent);
4043
const isVariable = scope.references.some((ref) => ref.identifier === node.parts[0]);
4144
if (isVariable) {
4245
return;
4346
}
4447

45-
// Check for @arguments
4648
for (const attr of node.attributes) {
4749
if (attr.type === 'GlimmerAttrNode' && attr.name.startsWith('@')) {
4850
context.report({

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,10 @@
7474
"language-tags": "^1.0.9",
7575
"lodash.camelcase": "^4.3.0",
7676
"lodash.kebabcase": "^4.1.1",
77+
"mathml-tag-names": "^4.0.0",
7778
"requireindex": "^1.2.0",
78-
"snake-case": "^3.0.3"
79+
"snake-case": "^3.0.3",
80+
"svg-tags": "^1.0.0"
7981
},
8082
"devDependencies": {
8183
"@babel/core": "^7.25.9",

pnpm-lock.yaml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/lib/rules/template-no-arguments-for-html-elements.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ ruleTester.run('template-no-arguments-for-html-elements', rule, {
1313
'<template><MyComponent @title="Hello" @onClick={{this.handler}} /></template>',
1414
'<template><CustomButton @disabled={{true}} /></template>',
1515
'<template><input value={{this.value}} /></template>',
16+
// Custom elements aren't in the html-tags/svg-tags allowlists, so they're
17+
// not flagged. Accepted false negative — web component namespace is open.
18+
'<template><my-element @foo="x" /></template>',
19+
// Namespaced/path component invocations aren't in the allowlists either.
20+
'<template><NS.Foo @bar="baz" /></template>',
21+
// Named blocks (colon-prefixed) aren't in the allowlists either.
22+
'<template><Thing><:slot @item="x">content</:slot></Thing></template>',
1623
`let div = <template>{{@greeting}}</template>
1724
1825
<template>
@@ -54,5 +61,29 @@ ruleTester.run('template-no-arguments-for-html-elements', rule, {
5461
},
5562
],
5663
},
64+
{
65+
// SVG element — in svg-tags allowlist.
66+
code: '<template><circle @r="5" /></template>',
67+
output: null,
68+
errors: [
69+
{
70+
message:
71+
'@arguments can only be used on components, not HTML elements. Use regular attributes instead.',
72+
type: 'GlimmerAttrNode',
73+
},
74+
],
75+
},
76+
{
77+
// MathML element — in mathml-tag-names allowlist.
78+
code: '<template><mfrac @numerator="x" /></template>',
79+
output: null,
80+
errors: [
81+
{
82+
message:
83+
'@arguments can only be used on components, not HTML elements. Use regular attributes instead.',
84+
type: 'GlimmerAttrNode',
85+
},
86+
],
87+
},
5788
],
5889
});

0 commit comments

Comments
 (0)