Conversation
Check that <ul>, <ol> and <dl> elements only contain the children the HTML content model allows, following the specification rather than a relaxed reading of it: a <dl> wraps every name-value group or none of them, a <div> inside a <dl> holds exactly one group, every group must be well formed, and children are matched by element name rather than by role.
🦋 Changeset detectedLatest commit: e9f470a The changes in this PR will be included in the next version bump. This PR includes changesets to release 76 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
🟡 Changes recommended
Flattened-tree and namespace handling can produce incorrect results, and the required API report is outdated.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Adds stable rule SIA-R119 to validate HTML list content models.
Changes:
- Implements validation for
<ul>,<ol>, and<dl>. - Adds comprehensive rule tests.
- Exports the rule and adds release metadata.
File summaries
| File | Description |
|---|---|
.changeset/brave-lists-gather.md |
Documents the new rule. |
packages/alfa-rules/src/rules.ts |
Exports R119. |
packages/alfa-rules/src/sia-r119/rule.ts |
Implements list validation. |
packages/alfa-rules/src/tsconfig.json |
Includes the rule source. |
packages/alfa-rules/test/sia-r119/rule.spec.tsx |
Tests rule behavior. |
packages/alfa-rules/test/tsconfig.json |
Includes the new tests. |
Review details
Suppressed comments (4)
packages/alfa-rules/src/sia-r119/rule.ts:85
- This also checks flattened-tree text rather than direct DOM text. For example, text in the light DOM of a shadow-host
<div>wrapper can be hidden by its shadow root and escape the<dl>group validation. Use the default DOM-tree traversal, matching the content model being validated.
.children(Node.fullTree)
packages/alfa-rules/src/sia-r119/rule.ts:91
- This accepts any element whose local name is
li, including a foreign-namespace element created withcreateElementNS. The content model requires an HTML<li>, so include the HTML namespace in the predicate.
const disallowed = elementChildren(target).reject(hasName("li"));
packages/alfa-rules/src/sia-r119/rule.ts:135
- A wrapper can similarly pass with foreign-namespace
dt/ddchildren becausehasNamecompares only the local name. Validate that the wrapper children are HTML elements before treating them as a well-formed group.
if (!children.reject(hasName("dt", "dd")).isEmpty()) {
packages/alfa-rules/src/sia-r119/rule.ts:100
- The allowed direct children are matched only by local name, which lets foreign-namespace
div,dt, orddelements satisfy the HTML<dl>content model. RequireNamespace.HTMLin this predicate so those nodes are reported as disallowed.
const disallowed = children.reject(hasName("div", "dt", "dd"));
- Files reviewed: 6/6 changed files
- Comments generated: 3
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
🟡 Changes recommended
The text check can produce incorrect results for elements with shadow content, and one diagnostic is inaccurate for description lists.
Get a fresh assessment by requesting another Copilot review.
Review details
- Files reviewed: 6/6 changed files
- Comments generated: 2
- Review effort level: Balanced
There was a problem hiding this comment.
🔵 Needs a closer look
Flat-tree traversal produces incorrect HTML content-model results for slotted children.
Review details
Suppressed comments (1)
packages/alfa-rules/src/sia-r119/rule.ts:101
Node.fullTreeuses flat-tree traversal (packages/alfa-dom/src/node/node.ts:397-407), which replaces a direct<slot>with assigned light-DOM nodes (packages/alfa-dom/src/node/slotable/element.ts:174-186). HTML content models constrain actual DOM children, so<ul><slot></slot></ul>remains invalid even when<li>nodes are assigned; assigned text is likewise not direct list text. This currently makes the rule contradict its stated HTML-spec check and causes the slot tests to lock in incorrect results. Use defaultchildren()for both element and text checks, remove thestraySlotsworkaround, and update the slot expectations accordingly.
.children(Node.fullTree)
- Files reviewed: 6/6 changed files
- Comments generated: 0 new
- Review effort level: Balanced
@copilot The case you originally raised is already caught. |
There was a problem hiding this comment.
🔵 Needs a closer look
Flattened-tree traversal validates slotted content instead of the lists’ actual DOM children.
Review details
Suppressed comments (2)
packages/alfa-rules/src/sia-r119/rule.ts:101
Node.fullTreerequests flattened traversal (packages/alfa-dom/src/node/node.ts:403-407), andElement.childrenconsequently replaces a direct<slot>with its assigned nodes (packages/alfa-dom/src/node/slotable/element.ts:174-189). This makes a shadow-tree<ul><slot></slot></ul>pass whenever<li>nodes are assigned, even though the list's actual child is the disallowed<slot>. Content-model validation should usechildren()and remove the shadow-dependentstraySlotsexception; the slot tests that currently expect this case to pass need to be updated as part of the fix.
.children(Node.fullTree)
packages/alfa-rules/src/sia-r119/rule.ts:108
- The text check also uses the flattened tree, so assigned light-DOM text is reported as direct text of the list. For
<ul><slot></slot></ul>with text assigned to the slot, the actual invalid child is<slot>, but this short-circuits withHasDisallowedTextinstead. Inspect defaultchildren()here so only actual direct text nodes participate in the content-model check, and update the corresponding test expectation.
.children(Node.fullTree)
- Files reviewed: 6/6 changed files
- Comments generated: 0 new
- Review effort level: Balanced
@copilot review your suggestion against cons of using |
... I withdraw the blanket recommendation to switch to
Default traversal is appropriate for a strict direct-DOM HTML conformance check. Flattened traversal serves the assembled-list accessibility check explicitly intended by the new slot tests. Those are different contracts; my earlier suggestion privileged the former without accounting for the latter. Given the intended slot support, I recommend keeping the current traversal and |
Description
<ul>,<ol>, and<dl>only contain the child element types the HTML spec allows.Jira Ticket
A11Y-12317
A11Y-12318