Repository navigation
Conversation
Nested treeitems had no group parent (Axe aria-required-parent), and the open/closed/loading images had no alt text (Axe image-alt). Mark the image wrapper aria-hidden and give each non-root node's child container role=group. Addresses rstudio/rstudio#19244
aria-expanded conveys open/closed but not loading, so the comment no longer claims it covers the loading image. The image test now asserts the child it inspects is expandable, since a leaf renders a placeholder without the image. Addresses rstudio/rstudio#19244
gtritchie
commented
Oct 23, 2026
gtritchie
left a comment
Member
Author
There was a problem hiding this comment.
No blocking issues. The change fixes both violations it targets, and I found no regressions.
I checked this by building HTML copies of the CellTree DOM before and after the change and running axe-core 4.13 and Chromium's accessibility tree on them. Before the change, axe reports aria-required-parent on nested items and image-alt on the expand images. After the change, it reports neither.
Remaining issues, both of which predate this PR:
- The top-level "Show more" link is a direct child of
role="tree". The root node's anchor is in the root's content container, so the tree element owns it directly. When the link is visible, axe reportsaria-required-children("Element has children which are not allowed: a"). The same link inside a nested item passes. In RStudio this only happens when the object browser has more than 512 top-level items (ObjectBrowsersets that page size), so it is rare. Fixing it means moving the link out of the tree element or giving it a role the tree allows, which is outside the scope of this PR. Worth an issue if anyone reports it. - The "No data" message is part of the nested item's accessible name. It is a sibling of the new group inside the treeitem, so Chromium names an open, empty nested item "emptyTable No data". This PR improves naming overall: before it, every item's name included the text of all its descendants (e.g. "schema table1 col1 loadingTable"). The new group stops that everywhere except for this message.
Optional:
testChildContainerRolescovers only the first open. The code keepsrole="group"after a redraw (loadChildStatecopiessavedChild.childContainer) and after a close followed by a reopen (ensureChildContainerreuses the container), but no test asserts either.
LGTM.
gtritchie
added a commit
to rstudio/rstudio
that referenced
this pull request
Oct 23, 2026
…Enter to view a table (#19248) * Name icon columns and type icons in the connection list The type and explore columns had empty <th> elements and the type icon had no alt text. Give both headers visually hidden text and render the type icon with its connection type as alt, escaping the package-supplied icon source. Base64ImageCell had no other users, so a Connection-aware cell replaces it. Addresses #19244 * Open connection tables with Enter in the object browser The View table icon only responded to clicks, and object icons had no alt text. Enter on a table item now opens the data viewer, the icon's alt carries the action label (so it reaches the item's name), object icons use their type as alt, and icon attributes are escaped. Addresses #19244 * Cover the object browser tree fixes in the NEWS entry The CellTree group role and decorative arrow fixes in the GWT fork ship in the same release, so describe them alongside the RStudio-side changes. Addresses #19244 * Ignore modified and repeated Enter in the object browser Ctrl/Cmd/Alt/Shift+Enter and each auto-repeated keydown also opened a data viewer. Act only on a plain, non-repeated Enter, and have render() and the key handler share one check for whether an item offers View table. Addresses #19244 * Test opening a connection table with Enter Addresses #19244 * Update GWT to 2.13.1-montauk-daisy-4 Picks up the CellTree fix from rstudio/gwt#22: nested tree items get a group parent and the expand/collapse images are hidden from screen readers. Addresses #19244 * Share one isRepeating helper for key-repeat checks ObjectExplorerDataGrid and the connections ObjectBrowserModel each had the same JSNI check for event.repeat. Move it to KeyboardShortcut, next to getModifierValue, and use it from both. Addresses #19244 * Share one helper for visually hidden header text The Files pane checkbox and icon columns and the two Connections pane icon columns each built the same visually hidden span by hand. Add SafeHtmlUtil.visuallyHiddenText and use it at all four sites. Addresses #19244 * Test Enter key guards in the connection object browser Add a test that Shift+Enter and a repeated Enter on a table item send no preview request, counting connection_preview_object requests because a second preview of an open table reuses its viewer. Keydowns are dispatched to the item so a refresh of the object tree can't divert them. The plain Enter test now checks that no viewer is open beforehand, and focuses the item again if the tree dropped focus before the key landed. Addresses #19244 * Correct two comments in the Enter key handling and its test Playwright can send a repeated keydown with a second keyboard.down, so the test helper's comment no longer claims otherwise. Restore the reason for ignoring repeated keydowns at the call site, lost when the helper moved. Addresses #19244
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Axe reports two problems in
CellTree, seen in RStudio's Connections pane object browser. Addresses rstudio/rstudio#19244.groupparent (aria-required-parent). EachCellTreeNodeViewelement hasrole="treeitem"and renders its children inside itself, through an animation frame, a content container and a child container, none of which has a role. A nested item's closest ancestor with a role is therefore its parenttreeitem. Top-level items pass because theCellTreeelement hasrole="tree".image-alt).CellTree.getImageHtml()builds them withAbstractImagePrototype, which emits an<img>with noalt.Changes
CellTreeNodeView.ensureChildContainer()gives the child containerrole="group"for every node except the root. This produces treeitem > group > treeitem, as in the APG tree pattern. The root's children stay direct descendants of therole="tree"element. The group holds only child items: the empty message and the "show more" link are siblings of the child container in the content container.imageWrappertemplate, which wraps all three images, getsaria-hidden="true". The item'saria-expandedalready conveys the open/closed state. Leaf items render a separate placeholder<div>with no image and are unchanged.Testing
New tests in
CellTreeTest, both of which failed before the change:testChildContainerRoles: a top-level item's closest ancestor with a role is the tree. Every nested item, down to a leaf, is in agroupwhose closest ancestor with a role is its parent item.testExpandImagesHiddenFromAssistiveTech: the image wrapper isaria-hiddenfor an open item, a closed item, an item closed again after being opened, and the loading image.Results:
CellTreeTestandAnimatedCellTreeTestpass in HtmlUnit (48 tests).checkstylepasses, andant clean dist-devbuilds.aria-required-parenton every nested item andimage-alton every arrow.RStudio needs no code change for this: the fix ships when RStudio's
GWT_VERSIONmoves to the release that contains it.