diff --git a/README.md b/README.md index 1915c88d5c..ac324cfe32 100644 --- a/README.md +++ b/README.md @@ -210,6 +210,7 @@ rules in templates can be disabled with eslint directives with mustache or html | [template-no-element-event-actions](docs/rules/template-no-element-event-actions.md) | disallow element event actions (use {{on}} modifier instead) | | | | | [template-no-inline-event-handlers](docs/rules/template-no-inline-event-handlers.md) | disallow DOM event handler attributes | | | | | [template-no-inline-styles](docs/rules/template-no-inline-styles.md) | disallow inline styles | | | | +| [template-no-input-block](docs/rules/template-no-input-block.md) | disallow block usage of {{input}} helper | | | | | [template-no-input-placeholder](docs/rules/template-no-input-placeholder.md) | disallow placeholder attribute on input elements | | | | | [template-no-input-tagname](docs/rules/template-no-input-tagname.md) | disallow tagName attribute on {{input}} helper | | | | | [template-no-invalid-meta](docs/rules/template-no-invalid-meta.md) | disallow invalid meta tags | | | | diff --git a/docs/rules/template-no-input-block.md b/docs/rules/template-no-input-block.md new file mode 100644 index 0000000000..53217ff4d2 --- /dev/null +++ b/docs/rules/template-no-input-block.md @@ -0,0 +1,26 @@ +# ember/template-no-input-block + +> **HBS Only**: This rule applies to classic `.hbs` template files only (loose mode). It is not relevant for `gjs`/`gts` files (strict mode), where these patterns cannot occur. + + + +Use of the block form of the handlebars `input` helper will result in an error at runtime. + +## Examples + +This rule **forbids** the following: + +```hbs +{{#input}}Some Content{{/input}} +``` + +This rule **allows** the following: + +```hbs +{{input type='text' value=this.firstName disabled=this.entryNotAllowed size='50'}} +``` + +## References + +- [Ember api/input component](https://api.emberjs.com/ember/release/classes/Ember.Templates.components/methods/Input?anchor=Input) +- [rfcs/built in components](https://emberjs.github.io/rfcs/0459-angle-bracket-built-in-components.html) diff --git a/lib/rules/template-no-input-block.js b/lib/rules/template-no-input-block.js new file mode 100644 index 0000000000..5ad5344a4c --- /dev/null +++ b/lib/rules/template-no-input-block.js @@ -0,0 +1,29 @@ +/** @type {import('eslint').Rule.RuleModule} */ +module.exports = { + meta: { + type: 'problem', + docs: { + description: 'disallow block usage of {{input}} helper', + category: 'Best Practices', + url: 'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/template-no-input-block.md', + templateMode: 'loose', + }, + schema: [], + messages: { blockUsage: 'Unexpected block usage. The input helper may only be used inline.' }, + originallyFrom: { + name: 'ember-template-lint', + rule: 'lib/rules/no-input-block.js', + docs: 'docs/rule/no-input-block.md', + tests: 'test/unit/rules/no-input-block-test.js', + }, + }, + create(context) { + return { + GlimmerBlockStatement(node) { + if (node.path?.type === 'GlimmerPathExpression' && node.path.original === 'input') { + context.report({ node, messageId: 'blockUsage' }); + } + }, + }; + }, +}; diff --git a/tests/lib/rules/template-no-input-block.js b/tests/lib/rules/template-no-input-block.js new file mode 100644 index 0000000000..ba969fb301 --- /dev/null +++ b/tests/lib/rules/template-no-input-block.js @@ -0,0 +1,41 @@ +const rule = require('../../../lib/rules/template-no-input-block'); +const RuleTester = require('eslint').RuleTester; + +const ruleTester = new RuleTester({ + parser: require.resolve('ember-eslint-parser'), + parserOptions: { ecmaVersion: 2022, sourceType: 'module' }, +}); +ruleTester.run('template-no-input-block', rule, { + valid: [ + '', + '', + '', + '', + ], + invalid: [ + { + code: '', + output: null, + errors: [{ messageId: 'blockUsage' }], + }, + ], +}); + +const hbsRuleTester = new RuleTester({ + parser: require.resolve('ember-eslint-parser/hbs'), + parserOptions: { + ecmaVersion: 2022, + sourceType: 'module', + }, +}); + +hbsRuleTester.run('template-no-input-block', rule, { + valid: ['{{button}}', '{{#x-button}}{{/x-button}}', '{{input}}'], + invalid: [ + { + code: '{{#input}}{{/input}}', + output: null, + errors: [{ message: 'Unexpected block usage. The input helper may only be used inline.' }], + }, + ], +});