Skip to content

Commit 367ee0b

Browse files
Merge pull request ember-cli#2689 from johanrd/day_fix/template-no-block-params-for-html-elements
Post-merge-review: extend allowlist with svg-tags on template-no-block-params-for-html-elements
2 parents 2707d89 + aaaef3e commit 367ee0b

4 files changed

Lines changed: 41 additions & 12 deletions

File tree

lib/rules/template-no-block-params-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 block params
4648
if (node.blockParams && node.blockParams.length > 0) {
4749
context.report({
4850
node,

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
"aria-query": "^5.3.2",
6767
"css-tree": "^3.0.1",
6868
"editorconfig": "^3.0.2",
69-
"ember-eslint-parser": "^0.9.0",
69+
"ember-eslint-parser": "^0.10.0",
7070
"ember-rfc176-data": "^0.3.18",
7171
"eslint-utils": "^3.0.0",
7272
"estraverse": "^5.3.0",

pnpm-lock.yaml

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

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ ruleTester.run('template-no-block-params-for-html-elements', rule, {
1717
'<template><MyComponent as |item|>{{item.name}}</MyComponent></template>',
1818
'<template>{{#each this.items as |item|}}<li>{{item}}</li>{{/each}}</template>',
1919
'<template><button>Click</button></template>',
20+
// Custom elements aren't in the html-tags/svg-tags allowlists, so they're
21+
// not flagged. Accepted false negative — web component namespace is open.
22+
'<template><my-element as |x|>{{x}}</my-element></template>',
23+
// Namespaced/path component invocations aren't in the allowlists either.
24+
'<template><NS.Foo as |x|>{{x}}</NS.Foo></template>',
2025
],
2126

2227
invalid: [
@@ -50,5 +55,27 @@ ruleTester.run('template-no-block-params-for-html-elements', rule, {
5055
},
5156
],
5257
},
58+
{
59+
// SVG element — in svg-tags allowlist.
60+
code: '<template><circle as |r|>{{r}}</circle></template>',
61+
output: null,
62+
errors: [
63+
{
64+
message: 'Block params can only be used with components, not HTML elements.',
65+
type: 'GlimmerElementNode',
66+
},
67+
],
68+
},
69+
{
70+
// MathML element — in mathml-tag-names allowlist.
71+
code: '<template><mfrac as |num|>{{num}}</mfrac></template>',
72+
output: null,
73+
errors: [
74+
{
75+
message: 'Block params can only be used with components, not HTML elements.',
76+
type: 'GlimmerElementNode',
77+
},
78+
],
79+
},
5380
],
5481
});

0 commit comments

Comments
 (0)