diff --git a/README.md b/README.md index 79c8cec965..657d0390c3 100644 --- a/README.md +++ b/README.md @@ -277,6 +277,7 @@ To disable a rule for an entire `.gjs`/`.gts` file, use a regular ESLint file-le | [template-no-pointer-down-event-binding](docs/rules/template-no-pointer-down-event-binding.md) | disallow pointer down event bindings | ๐Ÿ“‹ | | | | [template-no-positive-tabindex](docs/rules/template-no-positive-tabindex.md) | disallow positive tabindex values | ๐Ÿ“‹ | | | | [template-no-redundant-role](docs/rules/template-no-redundant-role.md) | disallow redundant role attributes | ๐Ÿ“‹ | ๐Ÿ”ง | | +| [template-no-role-presentation-on-focusable](docs/rules/template-no-role-presentation-on-focusable.md) | disallow role="presentation" / role="none" on focusable elements | | | | | [template-no-unsupported-role-attributes](docs/rules/template-no-unsupported-role-attributes.md) | disallow ARIA attributes that are not supported by the element role | ๐Ÿ“‹ | ๐Ÿ”ง | | | [template-no-whitespace-within-word](docs/rules/template-no-whitespace-within-word.md) | disallow excess whitespace within words (e.g. "W e l c o m e") | ๐Ÿ“‹ | | | | [template-require-aria-activedescendant-tabindex](docs/rules/template-require-aria-activedescendant-tabindex.md) | require non-interactive elements with aria-activedescendant to have tabindex | ๐Ÿ“‹ | ๐Ÿ”ง | | @@ -584,6 +585,8 @@ If you have any suggestions, ideas, or problems, feel free to [create an issue]( ### Creating a New Rule +If your rule inspects template attribute values (e.g. mustache forms like `attr={{X}}` or `attr="{{X}}"`), read [docs/glimmer-attribute-behavior.md](docs/glimmer-attribute-behavior.md) first โ€” Glimmer's actual rendering behavior is non-obvious for several common forms, and the doc has the empirically-verified table. + - [Create an issue](https://github.com/ember-cli/eslint-plugin-ember/issues/new) with a description of the proposed rule - Create files for the [new rule](https://eslint.org/docs/developer-guide/working-with-rules): - `lib/rules/new-rule.js` (implementation, see [no-proxies](lib/rules/no-proxies.js) for an example) diff --git a/docs/glimmer-attribute-behavior.md b/docs/glimmer-attribute-behavior.md new file mode 100644 index 0000000000..f0b47761d0 --- /dev/null +++ b/docs/glimmer-attribute-behavior.md @@ -0,0 +1,330 @@ +# Glimmer attribute rendering behavior + +Reference for rule authors. Most template lint rules need to answer: "given an attribute written as `attr={{X}}` or `attr="{{X}}"` or `attr="value"`, what does it actually do at runtime?" The answer is non-obvious โ€” Glimmer's bare-mustache and concat-mustache forms coerce values differently per attribute kind, HTML serialization can disagree with the live IDL property, and several intuitive mental models are wrong. + +This doc captures empirically-verified rendering behavior. Every cell in every table below comes from rendering the template under [ยง To reproduce the reference table](#to-reproduce-the-reference-table) in an Ember dev app and inspecting `outerHTML` plus the relevant IDL property in devtools. **No extrapolation.** If a form isn't in a table, it hasn't been verified โ€” extend the reproduction template and add the row. + +> Read this before writing or modifying any rule that inspects attribute values via `GlimmerBooleanLiteral`, `GlimmerStringLiteral`, `GlimmerConcatStatement`, or `GlimmerTextNode`. + +## Reference table + +Five per-attribute tables, one per representative attribute kind. IDs (`m1`โ€“`m19`, `h1`โ€“`h15`, `d1`โ€“`d10`, `t1`โ€“`t7`, `i1`โ€“`i5`) cross-reference the reproduction template below. + +### `