From fbc68ce44398447f5b5122711894c5868c97ced1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20R=C3=B8ed?= Date: Wed, 15 Apr 2026 21:32:42 +0200 Subject: [PATCH 1/2] fix(template-no-arguments-for-html-elements): extend allowlist with svg-tags Adds svg-tags to the html-tags allowlist so `` etc. are flagged alongside HTML elements. Documents accepted false negatives (custom elements, namespaced components, named blocks) via new test cases. Also adds a test for the scope-check path (`div` rebound in GJS is treated as a component, not flagged). --- ...template-no-arguments-for-html-elements.js | 19 +++++++++++++------ package.json | 3 ++- pnpm-lock.yaml | 3 +++ ...template-no-arguments-for-html-elements.js | 7 +++++++ 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/lib/rules/template-no-arguments-for-html-elements.js b/lib/rules/template-no-arguments-for-html-elements.js index b9f4750139..1bdea4f83a 100644 --- a/lib/rules/template-no-arguments-for-html-elements.js +++ b/lib/rules/template-no-arguments-for-html-elements.js @@ -1,6 +1,9 @@ -/** @type {import('eslint').Rule.RuleModule} */ const htmlTags = require('html-tags'); +const svgTags = require('svg-tags'); + +const ELEMENT_TAGS = new Set([...htmlTags, ...svgTags]); +/** @type {import('eslint').Rule.RuleModule} */ module.exports = { meta: { type: 'problem', @@ -16,27 +19,31 @@ module.exports = { noArgumentsForHtmlElements: '@arguments can only be used on components, not HTML elements. Use regular attributes instead.', }, + originallyFrom: { + name: 'ember-template-lint', + rule: 'lib/rules/no-arguments-for-html-elements.js', + docs: 'docs/rule/no-arguments-for-html-elements.md', + tests: 'test/unit/rules/no-arguments-for-html-elements-test.js', + }, }, create(context) { const sourceCode = context.sourceCode; - const HTML_ELEMENTS = new Set(htmlTags); return { GlimmerElementNode(node) { - // Check if this is an HTML element (lowercase) - if (!HTML_ELEMENTS.has(node.tag)) { + if (!ELEMENT_TAGS.has(node.tag)) { return; } - // If the tag name is a variable in scope, it's being used as a component, not an HTML element + // A known HTML/SVG tag can still be a component if it's bound in scope + // (block param, import, local). const scope = sourceCode.getScope(node.parent); const isVariable = scope.references.some((ref) => ref.identifier === node.parts[0]); if (isVariable) { return; } - // Check for @arguments for (const attr of node.attributes) { if (attr.type === 'GlimmerAttrNode' && attr.name.startsWith('@')) { context.report({ diff --git a/package.json b/package.json index de20f9800e..3a81e26b27 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,8 @@ "lodash.camelcase": "^4.3.0", "lodash.kebabcase": "^4.1.1", "requireindex": "^1.2.0", - "snake-case": "^3.0.3" + "snake-case": "^3.0.3", + "svg-tags": "^1.0.0" }, "devDependencies": { "@babel/core": "^7.25.9", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ea58f19332..00fc8ac744 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,6 +47,9 @@ importers: snake-case: specifier: ^3.0.3 version: 3.0.4 + svg-tags: + specifier: ^1.0.0 + version: 1.0.0 devDependencies: '@babel/core': specifier: ^7.25.9 diff --git a/tests/lib/rules/template-no-arguments-for-html-elements.js b/tests/lib/rules/template-no-arguments-for-html-elements.js index 330ba683e6..2b63b86eb0 100644 --- a/tests/lib/rules/template-no-arguments-for-html-elements.js +++ b/tests/lib/rules/template-no-arguments-for-html-elements.js @@ -13,6 +13,13 @@ ruleTester.run('template-no-arguments-for-html-elements', rule, { '', '', '', + // Custom elements aren't in the html-tags/svg-tags allowlists, so they're + // not flagged. Accepted false negative — web component namespace is open. + '', + // Namespaced/path component invocations aren't in the allowlists either. + '', + // Named blocks (colon-prefixed) aren't in the allowlists either. + '', `let div =