Extract rule: template-require-presentational-children#2611
Conversation
NullVoxPopuli-ai-agent
left a comment
There was a problem hiding this comment.
Review: template-require-presentational-children (PR #2611)
Comparison with ember-template-lint source
General correctness:
-
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 forrole="presentation"orrole="none"on<ul>,<table>, etc. with their semantic children (li, tr, td, etc.). ThePRESENTATIONAL_CHILDRENmap 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. -
role="none"check difference: In the original ETL,getAllElementNodeDescendantschecks ifattributeTextValue(findAttribute(childNode, 'role')) !== 'presentation'. This means it only skips nodes withrole="presentation"— NOTrole="none". The ESLint version'shasPresentationalRole()checks for both"none"and"presentation", which is technically more correct per the ARIA spec but diverges from the original. -
Recursion into presentational children: The original ETL's
getAllElementNodeDescendantsdoes NOT recurse into children of presentational nodes (it returns[...descendants]where descendants is only populated viahasChildrencheck, but the node itself is excluded and its children are still walked). Actually, looking more carefully, the original DOES recurse — it callsgetAllElementNodeDescendants(childNode)regardless and just excludes the presentational node itself from the results. The ESLint version also always recurses. This matches. -
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. -
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
Split from #2371.