0

[css-overflow-5] Add details relationship from scroll markers

Adds a details relation from ::scroll-marker pseudo-elements to their target.

AX-Relnotes: Adds details-from relation for ::scroll-marker pseudo-element details relation
Bug: 412626018
Change-Id: I3b0a5efcc7ea6fb5efa43b40d6a770beb4617ceb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6488224
Reviewed-by: Ken Buchanan <kenrb@chromium.org>
Reviewed-by: Vladimir Levin <vmpstr@chromium.org>
Commit-Queue: Robert Flack <flackr@chromium.org>
Reviewed-by: Aaron Leventhal <aleventhal@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1455118}
This commit is contained in:
Robert Flack
2025-05-02 11:55:57 -07:00
committed by Chromium LUCI CQ
parent cd95e73dd3
commit 82d3a064da
21 changed files with 96 additions and 42 deletions

@ -68,6 +68,7 @@ std::vector<ui::AXPropertyFilter> DumpAccessibilityTreeTest::DefaultFilters()
property_filters.emplace_back("value='http*'", AXPropertyFilter::DENY);
// Object attributes.value
property_filters.emplace_back("layout-guess:*", AXPropertyFilter::ALLOW);
property_filters.emplace_back("details-from:*", AXPropertyFilter::ALLOW);
property_filters.emplace_back("select*", AXPropertyFilter::ALLOW);
property_filters.emplace_back("selectedFromFocus=*", AXPropertyFilter::DENY);

@ -2009,6 +2009,7 @@ data/accessibility/css/carousel-positioned-buttons-expected-blink.txt
data/accessibility/css/carousel-positioned-buttons.html
data/accessibility/css/carousel-with-tabs-expected-android-assist-data.txt
data/accessibility/css/carousel-with-tabs-expected-android-external.txt
data/accessibility/css/carousel-with-tabs-expected-auralinux.txt
data/accessibility/css/carousel-with-tabs-expected-blink.txt
data/accessibility/css/carousel-with-tabs.html
data/accessibility/css/color-expected-android-assist-data.txt

@ -1,12 +1,12 @@
[document web]
++[section] description='comment' details-roles:comment
++[section] description='comment-group' details-roles:comment
++[section] description='comment-region' details-roles:*
++[section] description='comment-section' details-roles:*
++[section] description='definition' details-roles:definition
++[section] description='doc-endnote' details-roles:doc-endnote
++[section] description='doc-footnote' details-roles:doc-footnote
++[section] description='many' details-roles:comment definition doc-footnote
++[section] description='comment' details-from:aria-details details-roles:comment
++[section] description='comment-group' details-from:aria-details details-roles:comment
++[section] description='comment-region' details-from:aria-details details-roles:*
++[section] description='comment-section' details-from:aria-details details-roles:*
++[section] description='definition' details-from:aria-details details-roles:definition
++[section] description='doc-endnote' details-from:aria-details details-roles:doc-endnote
++[section] description='doc-footnote' details-from:aria-details details-roles:doc-footnote
++[section] description='many' details-from:aria-details details-roles:comment definition doc-footnote
++[section]
++++[static] name='x'
++[panel]

@ -1,12 +1,12 @@
ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
++IA2_ROLE_SECTION details-roles:comment description='comment' details='IA2_ROLE_COMMENT'
++IA2_ROLE_SECTION details-roles:comment description='comment-group' details='ROLE_SYSTEM_GROUPING'
++IA2_ROLE_SECTION details-roles:* description='comment-region' details='IA2_ROLE_SECTION'
++IA2_ROLE_SECTION details-roles:* description='comment-section' details='IA2_ROLE_SECTION'
++IA2_ROLE_SECTION details-roles:definition description='definition' details='ROLE_SYSTEM_GROUPING'
++IA2_ROLE_SECTION details-roles:doc-endnote description='doc-endnote' details='ROLE_SYSTEM_LISTITEM'
++IA2_ROLE_SECTION details-roles:doc-footnote description='doc-footnote' details='IA2_ROLE_FOOTNOTE'
++IA2_ROLE_SECTION details-roles:comment definition doc-footnote description='many' details='ROLE_SYSTEM_GROUPING,IA2_ROLE_COMMENT,ROLE_SYSTEM_GROUPING,IA2_ROLE_FOOTNOTE'
++IA2_ROLE_SECTION details-from:aria-details details-roles:comment description='comment' details='IA2_ROLE_COMMENT'
++IA2_ROLE_SECTION details-from:aria-details details-roles:comment description='comment-group' details='ROLE_SYSTEM_GROUPING'
++IA2_ROLE_SECTION details-from:aria-details details-roles:* description='comment-region' details='IA2_ROLE_SECTION'
++IA2_ROLE_SECTION details-from:aria-details details-roles:* description='comment-section' details='IA2_ROLE_SECTION'
++IA2_ROLE_SECTION details-from:aria-details details-roles:definition description='definition' details='ROLE_SYSTEM_GROUPING'
++IA2_ROLE_SECTION details-from:aria-details details-roles:doc-endnote description='doc-endnote' details='ROLE_SYSTEM_LISTITEM'
++IA2_ROLE_SECTION details-from:aria-details details-roles:doc-footnote description='doc-footnote' details='IA2_ROLE_FOOTNOTE'
++IA2_ROLE_SECTION details-from:aria-details details-roles:comment definition doc-footnote description='many' details='ROLE_SYSTEM_GROUPING,IA2_ROLE_COMMENT,ROLE_SYSTEM_GROUPING,IA2_ROLE_FOOTNOTE'
++IA2_ROLE_COMMENT
++++ROLE_SYSTEM_STATICTEXT name='x'
++ROLE_SYSTEM_GROUPING

@ -15,7 +15,7 @@ rootWebArea focusable name='Done'
++++++++++staticText name='Four'
++++++++++++inlineTextBox name='Four'
++++++tabList horizontal setSize=4 controlsIds=genericContainer
++++++++tab focusable name='alt text name' setSize=4 posInSet=1 selected=true
++++++++tab focusable name='<<content text name2' setSize=4 posInSet=2 selected=false
++++++++tab focusable name='scroll target name' setSize=4 posInSet=3 selected=false
++++++++tab focusable setSize=4 posInSet=4 selected=false
++++++++tab focusable name='alt text name' setSize=4 posInSet=1 selected=true detailsIds=genericContainer
++++++++tab focusable name='<<content text name2' setSize=4 posInSet=2 selected=false detailsIds=genericContainer
++++++++tab focusable name='scroll target name' setSize=4 posInSet=3 selected=false detailsIds=genericContainer
++++++++tab focusable setSize=4 posInSet=4 selected=false detailsIds=genericContainer

@ -14,6 +14,6 @@ rootWebArea focusable
++++++++++staticText name='Item'
++++++++++++inlineTextBox name='Item'
++++++tabList horizontal setSize=3 controlsIds=genericContainer
++++++++tab focusable setSize=3 posInSet=1 selected=true
++++++++tab focusable setSize=3 posInSet=2 selected=false
++++++++tab focusable setSize=3 posInSet=3 selected=false
++++++++tab focusable setSize=3 posInSet=1 selected=true detailsIds=genericContainer
++++++++tab focusable setSize=3 posInSet=2 selected=false detailsIds=genericContainer
++++++++tab focusable setSize=3 posInSet=3 selected=false detailsIds=genericContainer

@ -0,0 +1,16 @@
[document web]
++[push button] name='up' controller-for=[section]
++[push button] name='prev' controller-for=[section]
++[push button] name='next' controller-for=[section]
++[push button] name='down' controller-for=[section]
++[section] controlled-by=[page tab list,push button,push button,push button,push button]
++++[section] details-for=[page tab]
++++++[static] name='One'
++++[section] details-for=[page tab]
++++++[static] name='Two'
++++[section] details-for=[page tab]
++++++[static] name='Three'
++[page tab list] horizontal controller-for=[section]
++++[page tab] selectable selected details=[section] details-from:css-scroll-marker-pseudo-element
++++[page tab] selectable details=[section] details-from:css-scroll-marker-pseudo-element
++++[page tab] selectable details=[section] details-from:css-scroll-marker-pseudo-element

@ -16,6 +16,6 @@ rootWebArea focusable
++++++++++staticText name='Three'
++++++++++++inlineTextBox name='Three'
++++++tabList horizontal setSize=3 controlsIds=genericContainer
++++++++tab focusable setSize=3 posInSet=1 selected=true
++++++++tab focusable setSize=3 posInSet=2 selected=false
++++++++tab focusable setSize=3 posInSet=3 selected=false
++++++++tab focusable setSize=3 posInSet=1 selected=true detailsIds=genericContainer
++++++++tab focusable setSize=3 posInSet=2 selected=false detailsIds=genericContainer
++++++++tab focusable setSize=3 posInSet=3 selected=false detailsIds=genericContainer

@ -12,6 +12,6 @@ rootWebArea focusable
++++++++++staticText name='Three'
++++++++++++inlineTextBox name='Three'
++++++tabList horizontal setSize=3 controlsIds=genericContainer
++++++++tab focusable name='Two' setSize=3 posInSet=1 selected=false
++++++++tab focusable name='Three' setSize=3 posInSet=2 selected=false
++++++++tab focusable name='One' setSize=3 posInSet=3 selected=true
++++++++tab focusable name='Two' setSize=3 posInSet=1 selected=false detailsIds=genericContainer
++++++++tab focusable name='Three' setSize=3 posInSet=2 selected=false detailsIds=genericContainer
++++++++tab focusable name='One' setSize=3 posInSet=3 selected=true detailsIds=genericContainer

@ -5,10 +5,10 @@
++++[push button] name='d1 button - outside - custom action'
++++[push button] name='d1 button - outside - toggle-popover'
++++[push button] name='d1 button - outside & next - show-popover'
++++[push button] name='d2 button - outside - toggle-popover' expanded details=[panel] details-roles:popover
++++[push button] name='d2 button - outside - toggle-popover' expanded details=[panel] details-from:command-for details-roles:popover
++++[push button] name='d2 button - outside - unrelated action'
++++[push button] name='d2 button - outside - custom action'
++++[push button] name='d2 button - outside - toggle-popover' expanded details=[panel] details-roles:popover
++++[push button] name='d2 button - outside - toggle-popover' expanded details=[panel] details-from:command-for details-roles:popover
++++[push button] name='d2 button - outside & next - show-popover' expanded
++++[panel] details-for=[push button,push button]
++++++[push button] name='d2 button - inside - show-popover'
@ -16,10 +16,10 @@
++++++[push button] name='d2 button - inside - toggle-popover'
++++++[push button] name='d2 button - inside - related action'
++++++[push button] name='d2 button - inside - custom action'
++++[push button] name='d3 button - outside - toggle-popover' expanded details=[panel] details-roles:popover
++++[push button] name='d3 button - outside - toggle-popover' expanded details=[panel] details-from:command-for details-roles:popover
++++[push button] name='d3 button - outside - unrelated action'
++++[push button] name='d3 button - outside - custom action'
++++[push button] name='d3 button - outside - toggle-popover' expanded details=[panel] details-roles:popover
++++[push button] name='d3 button - outside - toggle-popover' expanded details=[panel] details-from:command-for details-roles:popover
++++[push button] name='d3 button - outside & next - show-popover' expanded
++++[panel] details-for=[push button,push button]
++++++[push button] name='d3 button - inside - show-popover'

@ -5,10 +5,10 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
++++ROLE_SYSTEM_PUSHBUTTON name='d1 button - outside - custom action' FOCUSABLE
++++ROLE_SYSTEM_PUSHBUTTON name='d1 button - outside - toggle-popover' COLLAPSED FOCUSABLE
++++ROLE_SYSTEM_PUSHBUTTON name='d1 button - outside & next - show-popover' COLLAPSED FOCUSABLE
++++ROLE_SYSTEM_PUSHBUTTON name='d2 button - outside - toggle-popover' EXPANDED FOCUSABLE details-roles:popover
++++ROLE_SYSTEM_PUSHBUTTON name='d2 button - outside - toggle-popover' EXPANDED FOCUSABLE details-from:command-for details-roles:popover
++++ROLE_SYSTEM_PUSHBUTTON name='d2 button - outside - unrelated action' FOCUSABLE
++++ROLE_SYSTEM_PUSHBUTTON name='d2 button - outside - custom action' FOCUSABLE
++++ROLE_SYSTEM_PUSHBUTTON name='d2 button - outside - toggle-popover' EXPANDED FOCUSABLE details-roles:popover
++++ROLE_SYSTEM_PUSHBUTTON name='d2 button - outside - toggle-popover' EXPANDED FOCUSABLE details-from:command-for details-roles:popover
++++ROLE_SYSTEM_PUSHBUTTON name='d2 button - outside & next - show-popover' EXPANDED FOCUSABLE
++++ROLE_SYSTEM_GROUPING ispopup:auto
++++++ROLE_SYSTEM_PUSHBUTTON name='d2 button - inside - show-popover' FOCUSABLE
@ -16,10 +16,10 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
++++++ROLE_SYSTEM_PUSHBUTTON name='d2 button - inside - toggle-popover' FOCUSABLE
++++++ROLE_SYSTEM_PUSHBUTTON name='d2 button - inside - related action' FOCUSABLE
++++++ROLE_SYSTEM_PUSHBUTTON name='d2 button - inside - custom action' FOCUSABLE
++++ROLE_SYSTEM_PUSHBUTTON name='d3 button - outside - toggle-popover' EXPANDED FOCUSABLE details-roles:popover
++++ROLE_SYSTEM_PUSHBUTTON name='d3 button - outside - toggle-popover' EXPANDED FOCUSABLE details-from:command-for details-roles:popover
++++ROLE_SYSTEM_PUSHBUTTON name='d3 button - outside - unrelated action' FOCUSABLE
++++ROLE_SYSTEM_PUSHBUTTON name='d3 button - outside - custom action' FOCUSABLE
++++ROLE_SYSTEM_PUSHBUTTON name='d3 button - outside - toggle-popover' EXPANDED FOCUSABLE details-roles:popover
++++ROLE_SYSTEM_PUSHBUTTON name='d3 button - outside - toggle-popover' EXPANDED FOCUSABLE details-from:command-for details-roles:popover
++++ROLE_SYSTEM_PUSHBUTTON name='d3 button - outside & next - show-popover' EXPANDED FOCUSABLE
++++ROLE_SYSTEM_GROUPING ispopup:manual
++++++ROLE_SYSTEM_PUSHBUTTON name='d3 button - inside - show-popover' FOCUSABLE

@ -1,7 +1,7 @@
[document web]
++[paragraph]
++++[static] name='This '
++++[section] details=[panel]
++++[section] details=[panel] details-from:aria-details
++++++[static] name='text'
++++[static] name=' has details'
++[panel] details-for=[section]

@ -1,7 +1,7 @@
ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
++IA2_ROLE_PARAGRAPH
++++ROLE_SYSTEM_STATICTEXT name='This '
++++IA2_ROLE_SECTION details='ROLE_SYSTEM_GROUPING'
++++IA2_ROLE_SECTION details-from:aria-details details='ROLE_SYSTEM_GROUPING'
++++++ROLE_SYSTEM_STATICTEXT name='text'
++++ROLE_SYSTEM_STATICTEXT name=' has details'
++ROLE_SYSTEM_GROUPING

@ -1,3 +1,3 @@
[document web]
++[paragraph]
++[paragraph] details-from:aria-details
++++[static] name='Self referential node'

@ -1,3 +1,3 @@
ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
++IA2_ROLE_PARAGRAPH
++IA2_ROLE_PARAGRAPH details-from:aria-details
++++ROLE_SYSTEM_STATICTEXT name='Self referential node'

@ -1,7 +1,7 @@
ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
++IA2_ROLE_PARAGRAPH
++++ROLE_SYSTEM_STATICTEXT name='This '
++++IA2_ROLE_SECTION details='ROLE_SYSTEM_GROUPING,ROLE_SYSTEM_GRAPHIC'
++++IA2_ROLE_SECTION details-from:aria-details details='ROLE_SYSTEM_GROUPING,ROLE_SYSTEM_GRAPHIC'
++++++ROLE_SYSTEM_STATICTEXT name='text'
++++ROLE_SYSTEM_STATICTEXT name=' has details'
++ROLE_SYSTEM_GROUPING

@ -2703,6 +2703,17 @@ void AXObject::SerializeComputedDetailsRelation(
ax::mojom::blink::IntListAttribute::kDetailsIds,
{static_cast<int32_t>(positioned_obj->AXObjectID())});
node_data->SetDetailsFrom(ax::mojom::blink::DetailsFrom::kCssAnchor);
return;
}
// Add aria-details for a scroll marker pseudo-element.
if (AXObject* marker_target = GetScrollMarkerTarget()) {
node_data->AddIntListAttribute(
ax::mojom::blink::IntListAttribute::kDetailsIds,
{static_cast<int32_t>(marker_target->AXObjectID())});
node_data->SetDetailsFrom(
ax::mojom::blink::DetailsFrom::kCssScrollMarkerPseudoElement);
return;
}
}
@ -2894,6 +2905,18 @@ AXObject* AXObject::GetPositionedObjectForAnchor(ui::AXNodeData* data) const {
return positioned_obj;
}
AXObject* AXObject::GetScrollMarkerTarget() const {
if (!GetElement() || !GetElement()->IsScrollMarkerPseudoElement()) {
return nullptr;
}
// The parent element of a ::scroll-marker pseudo-element is the originating
// element containing or preceeding the details which is scrolled into view
// when you interact with the pseudo-element.
// https://www.w3.org/TR/css-overflow-5/#scroll-navigation
return AXObjectCache().Get(GetElement()->parentElement());
}
// Try to get an aria-controls for an <input role="combobox">, because it
// helps identify focusable options in the listbox using activedescendant
// detection, even though the focus is on the textbox and not on the listbox

@ -938,6 +938,10 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
// added to the aria-details list.
AXObject* GetPositionedObjectForAnchor(ui::AXNodeData* node_data) const;
// Scroll marker pseudo-elements target their originating element which
// is located under a different parent in the layout tree.
AXObject* GetScrollMarkerTarget() const;
// Heuristic to get the listbox for an <input role="combobox">.
AXObject* GetControlsListboxForTextfieldCombobox() const;

@ -2478,6 +2478,8 @@ const char* ToString(ax::mojom::DetailsFrom details_from) {
return "interestTarget";
case ax::mojom::DetailsFrom::kCommandfor:
return "commandforAttribute";
case ax::mojom::DetailsFrom::kCssScrollMarkerPseudoElement:
return "cssScrollMarkerPseudoElement";
}
return "";

@ -1435,6 +1435,9 @@ enum DetailsFrom {
// The details comes from a commandFor attribute.
kCommandfor,
// The details comes from a scroll marker pseudo-element target.
kCssScrollMarkerPseudoElement,
};
// Next value: 4

@ -1482,6 +1482,10 @@ void AXPlatformNodeBase::ComputeAttributes(PlatformAttributeList* attributes) {
case ax::mojom::DetailsFrom::kCommandfor:
AddAttributeToList("details-from", "command-for", attributes);
break;
case ax::mojom::DetailsFrom::kCssScrollMarkerPseudoElement:
AddAttributeToList("details-from", "css-scroll-marker-pseudo-element",
attributes);
break;
}
}