Skip to content

Extract rule: template-require-presentational-children#2611

Open
NullVoxPopuli wants to merge 1 commit intoember-cli:masterfrom
NullVoxPopuli:nvp/template-lint-extract-rule-template-require-presentational-children
Open

Extract rule: template-require-presentational-children#2611
NullVoxPopuli wants to merge 1 commit intoember-cli:masterfrom
NullVoxPopuli:nvp/template-lint-extract-rule-template-require-presentational-children

Conversation

@NullVoxPopuli
Copy link
Contributor

Split from #2371.

Copy link

@NullVoxPopuli-ai-agent NullVoxPopuli-ai-agent left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: template-require-presentational-children (PR #2611)

Comparison with ember-template-lint source

General correctness:

  1. Significant behavioral difference — Case 1 (presentational role on parent elements): The ESLint version adds a whole new "Case 1" that the original ETL rule does NOT have. The original ETL only checks ROLES_THAT_CANNOT_SUPPORT_SEMANTIC_CHILDREN (button, checkbox, img, etc.). It does NOT check for role="presentation" or role="none" on <ul>, <table>, etc. with their semantic children (li, tr, td, etc.). The PRESENTATIONAL_CHILDREN map and associated logic is entirely new behavior not present in the original rule. While this may be useful, it should be documented as an intentional enhancement, not a migration.

  2. role="none" check difference: In the original ETL, getAllElementNodeDescendants checks if attributeTextValue(findAttribute(childNode, 'role')) !== 'presentation'. This means it only skips nodes with role="presentation" — NOT role="none". The ESLint version's hasPresentationalRole() checks for both "none" and "presentation", which is technically more correct per the ARIA spec but diverges from the original.

  3. Recursion into presentational children: The original ETL's getAllElementNodeDescendants does NOT recurse into children of presentational nodes (it returns [...descendants] where descendants is only populated via hasChildren check, but the node itself is excluded and its children are still walked). Actually, looking more carefully, the original DOES recurse — it calls getAllElementNodeDescendants(childNode) regardless and just excludes the presentational node itself from the results. The ESLint version also always recurses. This matches.

  4. Error message difference: Original: "<ul> has a role of presentation, it cannot have semantic descendants like <li>". ESLint version: "Element <ul> has role=\"presentation\" but contains semantic child <li>. Presentational elements should only contain presentational children." — different wording.

  5. Only checks direct children for Case 1: In the new Case 1 (presentational parent), only direct children are checked, not deeper descendants. If <ul role="presentation"><div><li>...</li></div></ul> is used, the nested <li> wouldn't be caught. However, since Case 1 is new behavior not in the original, this is just a note for completeness.

Scope analysis (gjs/gts):

Not applicable. This rule checks HTML element tags and role attribute values only — no helper/component name matching is involved.

Tests: Good coverage including the new Case 1, ETL-matching tests, named blocks, SVG skipping, and additionalNonSemanticTags option.

Summary: The main concern is the undocumented addition of "Case 1" behavior that wasn't in the original ETL rule. Consider either documenting this as an intentional enhancement or splitting it into a separate concern.

🤖 Automated review comparing with ember-template-lint source

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants