[go: nahoru, domu]

Support posinset/setsize on <summary> inside <details name>.

This creates an internal DisclosureTriangleGrouped role in order to
distinguish summary elements that are inside a <details> element with a
name attribute, and supports posinset/setsize on such elements.

Bug: 1444057
AX-Relnotes: n/a
Change-Id: I01bbaeaeac68c92ebefaaeb7e3b78b69468b8707
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5062340
Commit-Queue: David Baron <dbaron@chromium.org>
Reviewed-by: Nektarios Paisios <nektar@chromium.org>
Reviewed-by: Joe Mason <joenotcharles@google.com>
Reviewed-by: Aaron Leventhal <aleventhal@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1232242}
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc
index 784495ac..021b6cb 100644
--- a/content/browser/accessibility/browser_accessibility.cc
+++ b/content/browser/accessibility/browser_accessibility.cc
@@ -1620,6 +1620,7 @@
     case ax::mojom::Role::kDirectory:
       return content_client->GetLocalizedString(IDS_AX_ROLE_DIRECTORY);
     case ax::mojom::Role::kDisclosureTriangle:
+    case ax::mojom::Role::kDisclosureTriangleGrouped:
       return content_client->GetLocalizedString(
           IDS_AX_ROLE_DISCLOSURE_TRIANGLE);
     case ax::mojom::Role::kDocument:
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
index 626f1e5..c165b8b7 100644
--- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -1775,6 +1775,10 @@
   RunHtmlTest(FILE_PATH_LITERAL("details.html"));
 }
 
+IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityDetailsName) {
+  RunHtmlTest(FILE_PATH_LITERAL("details-name.html"));
+}
+
 IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityDfn) {
   RunHtmlTest(FILE_PATH_LITERAL("dfn.html"));
 }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTreeTest.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTreeTest.java
index b523008..cc5b6ba 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTreeTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTreeTest.java
@@ -1478,6 +1478,12 @@
 
     @Test
     @SmallTest
+    public void test_details_name() {
+        performHtmlTest("details-name.html");
+    }
+
+    @Test
+    @SmallTest
     public void test_dfn() {
         performHtmlTest("dfn.html");
     }
diff --git a/content/test/content_test_bundle_data.filelist b/content/test/content_test_bundle_data.filelist
index 7e780ab..05f0fe2 100644
--- a/content/test/content_test_bundle_data.filelist
+++ b/content/test/content_test_bundle_data.filelist
@@ -3139,6 +3139,16 @@
 data/accessibility/html/details-expected-mac.txt
 data/accessibility/html/details-expected-uia-win.txt
 data/accessibility/html/details-expected-win.txt
+data/accessibility/html/details-name-expected-android-assist-data.txt
+data/accessibility/html/details-name-expected-android-external.txt
+data/accessibility/html/details-name-expected-android.txt
+data/accessibility/html/details-name-expected-auralinux.txt
+data/accessibility/html/details-name-expected-blink.txt
+data/accessibility/html/details-name-expected-fuchsia.txt
+data/accessibility/html/details-name-expected-mac.txt
+data/accessibility/html/details-name-expected-uia-win.txt
+data/accessibility/html/details-name-expected-win.txt
+data/accessibility/html/details-name.html
 data/accessibility/html/details.html
 data/accessibility/html/dfn-expected-android-assist-data.txt
 data/accessibility/html/dfn-expected-android-external.txt
diff --git a/content/test/data/accessibility/html/details-name-expected-android-assist-data.txt b/content/test/data/accessibility/html/details-name-expected-android-assist-data.txt
new file mode 100644
index 0000000..314a2ed8
--- /dev/null
+++ b/content/test/data/accessibility/html/details-name-expected-android-assist-data.txt
@@ -0,0 +1,16 @@
+WebView textSize:16.00 style:0 bundle:[display="", htmlTag="#document"]
+++View textSize:16.00 style:0 bundle:[display="block", htmlTag="details"]
+++++View textSize:16.00 style:0 bundle:[display="list-item", htmlTag="summary"]
+++++++TextView text:"the summary" textSize:16.00 style:0 bundle:[display="", htmlTag=""]
+++View textSize:16.00 style:0 bundle:[display="block", htmlTag="section"]
+++++View textSize:16.00 style:0 bundle:[display="block", htmlTag="details", name="properties", open=""]
+++++++View textSize:16.00 style:0 bundle:[display="list-item", htmlTag="summary"]
+++++++++TextView text:"materials" textSize:16.00 style:0 bundle:[display="", htmlTag=""]
+++++++View textSize:16.00 style:0 bundle:[display="block", htmlTag="p"]
+++++++++TextView text:"Info about what it's made of." textSize:16.00 style:0 bundle:[display="", htmlTag=""]
+++++View textSize:16.00 style:0 bundle:[display="block", htmlTag="details", name="properties"]
+++++++View textSize:16.00 style:0 bundle:[display="list-item", htmlTag="summary"]
+++++++++TextView text:"dimensions" textSize:16.00 style:0 bundle:[display="", htmlTag=""]
+++++View textSize:16.00 style:0 bundle:[display="block", htmlTag="details", name="properties"]
+++++++View textSize:16.00 style:0 bundle:[display="list-item", htmlTag="summary"]
+++++++++TextView text:"origin" textSize:16.00 style:0 bundle:[display="", htmlTag=""]
diff --git a/content/test/data/accessibility/html/details-name-expected-android-external.txt b/content/test/data/accessibility/html/details-name-expected-android-external.txt
new file mode 100644
index 0000000..13b00d43
--- /dev/null
+++ b/content/test/data/accessibility/html/details-name-expected-android-external.txt
@@ -0,0 +1,11 @@
+WebView focusable focused scrollable actions:[CLEAR_FOCUS, AX_FOCUS] bundle:[chromeRole="rootWebArea"]
+++View actions:[AX_FOCUS] bundle:[chromeRole="details"]
+++++View text:"the summary" clickable focusable actions:[FOCUS, CLICK, AX_FOCUS, NEXT, PREVIOUS, EXPAND] bundle:[chromeRole="disclosureTriangle", clickableScore="300", roleDescription="disclosure triangle"]
+++View actions:[AX_FOCUS] bundle:[chromeRole="section"]
+++++View actions:[AX_FOCUS] bundle:[chromeRole="details"]
+++++++View text:"materials" clickable focusable actions:[FOCUS, CLICK, AX_FOCUS, NEXT, PREVIOUS, COLLAPSE] bundle:[chromeRole="disclosureTriangleGrouped", clickableScore="300", roleDescription="disclosure triangle"]
+++++++TextView text:"Info about what it's made of." actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="paragraph"]
+++++View actions:[AX_FOCUS] bundle:[chromeRole="details"]
+++++++View text:"dimensions" clickable focusable actions:[FOCUS, CLICK, AX_FOCUS, NEXT, PREVIOUS, EXPAND] bundle:[chromeRole="disclosureTriangleGrouped", clickableScore="300", roleDescription="disclosure triangle"]
+++++View actions:[AX_FOCUS] bundle:[chromeRole="details"]
+++++++View text:"origin" clickable focusable actions:[FOCUS, CLICK, AX_FOCUS, NEXT, PREVIOUS, EXPAND] bundle:[chromeRole="disclosureTriangleGrouped", clickableScore="300", roleDescription="disclosure triangle"]
diff --git a/content/test/data/accessibility/html/details-name-expected-android.txt b/content/test/data/accessibility/html/details-name-expected-android.txt
new file mode 100644
index 0000000..da4a807
--- /dev/null
+++ b/content/test/data/accessibility/html/details-name-expected-android.txt
@@ -0,0 +1,11 @@
+android.webkit.WebView focusable focused scrollable
+++android.view.View
+++++android.view.View role_description='disclosure triangle' clickable collapsed focusable name='the summary'
+++android.view.View
+++++android.view.View
+++++++android.view.View role_description='disclosure triangle' clickable expanded focusable name='materials'
+++++++android.widget.TextView name='Info about what it's made of.'
+++++android.view.View
+++++++android.view.View role_description='disclosure triangle' clickable collapsed focusable name='dimensions' item_index=1 row_index=1
+++++android.view.View
+++++++android.view.View role_description='disclosure triangle' clickable collapsed focusable name='origin' item_index=2 row_index=2
diff --git a/content/test/data/accessibility/html/details-name-expected-auralinux.txt b/content/test/data/accessibility/html/details-name-expected-auralinux.txt
new file mode 100644
index 0000000..4363566
--- /dev/null
+++ b/content/test/data/accessibility/html/details-name-expected-auralinux.txt
@@ -0,0 +1,16 @@
+[document web] focusable focused
+++[panel]
+++++[toggle button] name='the summary' expandable focusable
+++++++[static] name='the summary'
+++[section]
+++++[panel]
+++++++[toggle button] name='materials' expandable expanded focusable posinset:1 setsize:3
+++++++++[static] name='materials'
+++++++[paragraph]
+++++++++[static] name='Info about what it's made of.'
+++++[panel]
+++++++[toggle button] name='dimensions' expandable focusable posinset:2 setsize:3
+++++++++[static] name='dimensions'
+++++[panel]
+++++++[toggle button] name='origin' expandable focusable posinset:3 setsize:3
+++++++++[static] name='origin'
diff --git a/content/test/data/accessibility/html/details-name-expected-blink.txt b/content/test/data/accessibility/html/details-name-expected-blink.txt
new file mode 100644
index 0000000..3ee45f5
--- /dev/null
+++ b/content/test/data/accessibility/html/details-name-expected-blink.txt
@@ -0,0 +1,54 @@
+rootWebArea
+++genericContainer ignored
+++++genericContainer ignored
+++++++details
+++++++++genericContainer ignored
+++++++++++disclosureTriangle collapsed name='the summary'
+++++++++++++listMarker ignored
+++++++++++++++staticText ignored name='%E2%96%B8 '
+++++++++++++staticText name='the summary'
+++++++++++++++inlineTextBox name='the summary'
+++++++++genericContainer ignored
+++++++++++staticText ignored invisible name='<newline>    '
+++++++++++staticText ignored invisible name='<newline>    '
+++++++++++paragraph ignored invisible
+++++++++++++staticText ignored invisible name='The details, shown when expanded.'
+++++++++++staticText ignored invisible name='<newline>  '
+++++++section
+++++++++details
+++++++++++genericContainer ignored
+++++++++++++disclosureTriangleGrouped name='materials' setSize=3 posInSet=1
+++++++++++++++listMarker ignored
+++++++++++++++++staticText ignored name='%E2%96%BE '
+++++++++++++++staticText name='materials'
+++++++++++++++++inlineTextBox name='materials'
+++++++++++genericContainer ignored
+++++++++++++paragraph
+++++++++++++++staticText name='Info about what it's made of.'
+++++++++++++++++inlineTextBox name='Info about what it's made of.'
+++++++++details
+++++++++++genericContainer ignored
+++++++++++++disclosureTriangleGrouped collapsed name='dimensions' setSize=3 posInSet=2
+++++++++++++++listMarker ignored
+++++++++++++++++staticText ignored name='%E2%96%B8 '
+++++++++++++++staticText name='dimensions'
+++++++++++++++++inlineTextBox name='dimensions'
+++++++++++genericContainer ignored
+++++++++++++staticText ignored invisible name='<newline>      '
+++++++++++++staticText ignored invisible name='<newline>      '
+++++++++++++paragraph ignored invisible
+++++++++++++++staticText ignored invisible name='Info about how big it is.'
+++++++++++++staticText ignored invisible name='<newline>    '
+++++++++details
+++++++++++genericContainer ignored
+++++++++++++disclosureTriangleGrouped collapsed name='origin' setSize=3 posInSet=3
+++++++++++++++listMarker ignored
+++++++++++++++++staticText ignored name='%E2%96%B8 '
+++++++++++++++staticText name='origin'
+++++++++++++++++inlineTextBox name='origin'
+++++++++++genericContainer ignored
+++++++++++++staticText ignored invisible name='<newline>      '
+++++++++++++staticText ignored invisible name='<newline>      '
+++++++++++++paragraph ignored invisible
+++++++++++++++staticText ignored invisible name='Info about where it was built.'
+++++++++++++staticText ignored invisible name='<newline>    '
diff --git a/content/test/data/accessibility/html/details-name-expected-fuchsia.txt b/content/test/data/accessibility/html/details-name-expected-fuchsia.txt
new file mode 100644
index 0000000..50ec8db9
--- /dev/null
+++ b/content/test/data/accessibility/html/details-name-expected-fuchsia.txt
@@ -0,0 +1,54 @@
+UNKNOWN focusable has_input_focus
+++UNKNOWN hidden
+++++UNKNOWN hidden
+++++++UNKNOWN
+++++++++UNKNOWN hidden
+++++++++++UNKNOWN focusable label='the summary' actions='{DEFAULT}'
+++++++++++++LIST_ELEMENT_MARKER hidden
+++++++++++++++STATIC_TEXT hidden label='%E2%96%B8 '
+++++++++++++STATIC_TEXT label='the summary' actions='{DEFAULT}'
+++++++++++++++UNKNOWN label='the summary'
+++++++++UNKNOWN hidden
+++++++++++STATIC_TEXT hidden label='<newline>    '
+++++++++++STATIC_TEXT hidden label='<newline>    '
+++++++++++PARAGRAPH hidden
+++++++++++++STATIC_TEXT hidden label='The details, shown when expanded.'
+++++++++++STATIC_TEXT hidden label='<newline>  '
+++++++UNKNOWN
+++++++++UNKNOWN
+++++++++++UNKNOWN hidden
+++++++++++++UNKNOWN focusable label='materials' actions='{DEFAULT}'
+++++++++++++++LIST_ELEMENT_MARKER hidden
+++++++++++++++++STATIC_TEXT hidden label='%E2%96%BE '
+++++++++++++++STATIC_TEXT label='materials' actions='{DEFAULT}'
+++++++++++++++++UNKNOWN label='materials'
+++++++++++UNKNOWN hidden
+++++++++++++PARAGRAPH
+++++++++++++++STATIC_TEXT label='Info about what it's made of.'
+++++++++++++++++UNKNOWN label='Info about what it's made of.'
+++++++++UNKNOWN
+++++++++++UNKNOWN hidden
+++++++++++++UNKNOWN focusable label='dimensions' actions='{DEFAULT}'
+++++++++++++++LIST_ELEMENT_MARKER hidden
+++++++++++++++++STATIC_TEXT hidden label='%E2%96%B8 '
+++++++++++++++STATIC_TEXT label='dimensions' actions='{DEFAULT}'
+++++++++++++++++UNKNOWN label='dimensions'
+++++++++++UNKNOWN hidden
+++++++++++++STATIC_TEXT hidden label='<newline>      '
+++++++++++++STATIC_TEXT hidden label='<newline>      '
+++++++++++++PARAGRAPH hidden
+++++++++++++++STATIC_TEXT hidden label='Info about how big it is.'
+++++++++++++STATIC_TEXT hidden label='<newline>    '
+++++++++UNKNOWN
+++++++++++UNKNOWN hidden
+++++++++++++UNKNOWN focusable label='origin' actions='{DEFAULT}'
+++++++++++++++LIST_ELEMENT_MARKER hidden
+++++++++++++++++STATIC_TEXT hidden label='%E2%96%B8 '
+++++++++++++++STATIC_TEXT label='origin' actions='{DEFAULT}'
+++++++++++++++++UNKNOWN label='origin'
+++++++++++UNKNOWN hidden
+++++++++++++STATIC_TEXT hidden label='<newline>      '
+++++++++++++STATIC_TEXT hidden label='<newline>      '
+++++++++++++PARAGRAPH hidden
+++++++++++++++STATIC_TEXT hidden label='Info about where it was built.'
+++++++++++++STATIC_TEXT hidden label='<newline>    '
diff --git a/content/test/data/accessibility/html/details-name-expected-mac.txt b/content/test/data/accessibility/html/details-name-expected-mac.txt
new file mode 100644
index 0000000..0e9ae9a
--- /dev/null
+++ b/content/test/data/accessibility/html/details-name-expected-mac.txt
@@ -0,0 +1,16 @@
+AXWebArea AXRoleDescription='HTML content'
+++AXGroup AXRoleDescription='details'
+++++AXButton AXExpanded=0 AXRoleDescription='disclosure triangle' AXTitle='the summary'
+++++++AXStaticText AXRoleDescription='text' AXValue='the summary'
+++AXGroup AXRoleDescription='group'
+++++AXGroup AXRoleDescription='details'
+++++++AXButton AXARIAPosInSet=1 AXARIASetSize=3 AXExpanded=1 AXRoleDescription='disclosure triangle' AXTitle='materials'
+++++++++AXStaticText AXRoleDescription='text' AXValue='materials'
+++++++AXGroup AXRoleDescription='group'
+++++++++AXStaticText AXRoleDescription='text' AXValue='Info about what it's made of.'
+++++AXGroup AXRoleDescription='details'
+++++++AXButton AXARIAPosInSet=2 AXARIASetSize=3 AXExpanded=0 AXRoleDescription='disclosure triangle' AXTitle='dimensions'
+++++++++AXStaticText AXRoleDescription='text' AXValue='dimensions'
+++++AXGroup AXRoleDescription='details'
+++++++AXButton AXARIAPosInSet=3 AXARIASetSize=3 AXExpanded=0 AXRoleDescription='disclosure triangle' AXTitle='origin'
+++++++++AXStaticText AXRoleDescription='text' AXValue='origin'
diff --git a/content/test/data/accessibility/html/details-name-expected-uia-win.txt b/content/test/data/accessibility/html/details-name-expected-uia-win.txt
new file mode 100644
index 0000000..afa4e3d
--- /dev/null
+++ b/content/test/data/accessibility/html/details-name-expected-uia-win.txt
@@ -0,0 +1,16 @@
+Document PositionInSet=0 SizeOfSet=0
+++Group LocalizedControlType='details' PositionInSet=0 SizeOfSet=0
+++++Button Name='the summary' PositionInSet=0 SizeOfSet=0 ExpandCollapse.ExpandCollapseState='Collapsed'
+++++++Text Name='the summary' PositionInSet=0 SizeOfSet=0
+++Group PositionInSet=0 SizeOfSet=0
+++++Group LocalizedControlType='details' PositionInSet=0 SizeOfSet=0
+++++++Button Name='materials' PositionInSet=1 SizeOfSet=3 ExpandCollapse.ExpandCollapseState='Expanded'
+++++++++Text Name='materials' PositionInSet=0 SizeOfSet=0
+++++++Group IsControlElement=false PositionInSet=0 SizeOfSet=0
+++++++++Text Name='Info about what it's made of.' PositionInSet=0 SizeOfSet=0
+++++Group LocalizedControlType='details' PositionInSet=0 SizeOfSet=0
+++++++Button Name='dimensions' PositionInSet=2 SizeOfSet=3 ExpandCollapse.ExpandCollapseState='Collapsed'
+++++++++Text Name='dimensions' PositionInSet=0 SizeOfSet=0
+++++Group LocalizedControlType='details' PositionInSet=0 SizeOfSet=0
+++++++Button Name='origin' PositionInSet=3 SizeOfSet=3 ExpandCollapse.ExpandCollapseState='Collapsed'
+++++++++Text Name='origin' PositionInSet=0 SizeOfSet=0
diff --git a/content/test/data/accessibility/html/details-name-expected-win.txt b/content/test/data/accessibility/html/details-name-expected-win.txt
new file mode 100644
index 0000000..779b3078
--- /dev/null
+++ b/content/test/data/accessibility/html/details-name-expected-win.txt
@@ -0,0 +1,16 @@
+ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
+++ROLE_SYSTEM_GROUPING
+++++ROLE_SYSTEM_PUSHBUTTON name='the summary' COLLAPSED FOCUSABLE
+++++++ROLE_SYSTEM_STATICTEXT name='the summary'
+++IA2_ROLE_SECTION
+++++ROLE_SYSTEM_GROUPING
+++++++ROLE_SYSTEM_PUSHBUTTON name='materials' EXPANDED FOCUSABLE setsize:3 posinset:1
+++++++++ROLE_SYSTEM_STATICTEXT name='materials'
+++++++IA2_ROLE_PARAGRAPH
+++++++++ROLE_SYSTEM_STATICTEXT name='Info about what it's made of.'
+++++ROLE_SYSTEM_GROUPING
+++++++ROLE_SYSTEM_PUSHBUTTON name='dimensions' COLLAPSED FOCUSABLE setsize:3 posinset:2
+++++++++ROLE_SYSTEM_STATICTEXT name='dimensions'
+++++ROLE_SYSTEM_GROUPING
+++++++ROLE_SYSTEM_PUSHBUTTON name='origin' COLLAPSED FOCUSABLE setsize:3 posinset:3
+++++++++ROLE_SYSTEM_STATICTEXT name='origin'
diff --git a/content/test/data/accessibility/html/details-name.html b/content/test/data/accessibility/html/details-name.html
new file mode 100644
index 0000000..0796b9c6
--- /dev/null
+++ b/content/test/data/accessibility/html/details-name.html
@@ -0,0 +1,46 @@
+<!--
+@BLINK-ALLOW:setSize*
+@BLINK-ALLOW:posInSet*
+@AURALINUX-ALLOW:expand*
+@AURALINUX-ALLOW:focus*
+@AURALINUX-ALLOW:posinset*
+@AURALINUX-ALLOW:setsize*
+@MAC-ALLOW:AXARIAPosInSet
+@MAC-ALLOW:AXARIASetSize
+@MAC-ALLOW:AXExpanded=*
+@MAC-ALLOW:AXRoleDescription
+@UIA-WIN-ALLOW:LocalizedControlType='details'
+@UIA-WIN-ALLOW:PositionInSet*
+@UIA-WIN-ALLOW:SizeOfSet*
+@WIN-ALLOW:COLLAPSED
+@WIN-ALLOW:EXPANDED
+@WIN-ALLOW:localized_extended_role=*
+@WIN-ALLOW:posinset*
+@WIN-ALLOW:setsize*
+-->
+<!DOCTYPE html>
+<html>
+<body>
+  <details>
+    <summary>the summary</summary>
+    <p>The details, shown when expanded.</p>
+  </details>
+
+  <section>
+    <details open name=properties>
+      <summary>materials</summary>
+      <p>Info about what it's made of.</p>
+    </details>
+
+    <details name=properties>
+      <summary>dimensions</summary>
+      <p>Info about how big it is.</p>
+    </details>
+
+    <details name=properties>
+      <summary>origin</summary>
+      <p>Info about where it was built.</p>
+    </details>
+  </section>
+</body>
+</html>
diff --git a/extensions/common/api/automation.idl b/extensions/common/api/automation.idl
index 0c2e3fb..7945864 100644
--- a/extensions/common/api/automation.idl
+++ b/extensions/common/api/automation.idl
@@ -177,6 +177,7 @@
     dialog,
     directory,
     disclosureTriangle,
+    disclosureTriangleGrouped,
     // --------------------------------------------------------------
     // DPub Roles:
     // https://www.w3.org/TR/dpub-aam-1.0/#mapping_role_table
diff --git a/third_party/blink/renderer/core/html/html_details_element.h b/third_party/blink/renderer/core/html/html_details_element.h
index 63399de..d7edc0d 100644
--- a/third_party/blink/renderer/core/html/html_details_element.h
+++ b/third_party/blink/renderer/core/html/html_details_element.h
@@ -51,13 +51,15 @@
   bool HandleInvokeInternal(HTMLElement& invoker,
                             AtomicString& action) override;
 
- private:
-  void DispatchPendingEvent(const AttributeModificationReason);
-
+  // The name attribute for grouping of related details; empty string
+  // means no grouping.
   const AtomicString& GetName() const {
     return FastGetAttribute(html_names::kNameAttr);
   }
 
+ private:
+  void DispatchPendingEvent(const AttributeModificationReason);
+
   // Return all the <details> elements in the group created by the name
   // attribute, excluding |this|, in tree order.  If there is no such group
   // (e.g., because there is no name attribute), returns an empty list.
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
index e030d68..dc6d540 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -86,6 +86,7 @@
 #include "third_party/blink/renderer/core/html/forms/radio_input_type.h"
 #include "third_party/blink/renderer/core/html/forms/text_control_element.h"
 #include "third_party/blink/renderer/core/html/html_anchor_element.h"
+#include "third_party/blink/renderer/core/html/html_details_element.h"
 #include "third_party/blink/renderer/core/html/html_div_element.h"
 #include "third_party/blink/renderer/core/html/html_dlist_element.h"
 #include "third_party/blink/renderer/core/html/html_element.h"
@@ -1348,8 +1349,14 @@
     ContainerNode* parent = LayoutTreeBuilderTraversal::Parent(*GetNode());
     if (ToHTMLSlotElementIfSupportsAssignmentOrNull(parent))
       parent = LayoutTreeBuilderTraversal::Parent(*parent);
-    if (parent && IsA<HTMLDetailsElement>(parent))
-      return ax::mojom::blink::Role::kDisclosureTriangle;
+    if (HTMLDetailsElement* parent_details =
+            DynamicTo<HTMLDetailsElement>(parent)) {
+      if (parent_details->GetName().empty()) {
+        return ax::mojom::blink::Role::kDisclosureTriangle;
+      } else {
+        return ax::mojom::blink::Role::kDisclosureTriangleGrouped;
+      }
+    }
     return ax::mojom::blink::Role::kGenericContainer;
   }
 
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc
index b5ecd2c..72a56d5c 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -4776,6 +4776,7 @@
   switch (RoleValue()) {
     case ax::mojom::blink::Role::kButton:
     case ax::mojom::blink::Role::kDisclosureTriangle:
+    case ax::mojom::blink::Role::kDisclosureTriangleGrouped:
     case ax::mojom::blink::Role::kToggleButton:
       return ax::mojom::blink::DefaultActionVerb::kPress;
     case ax::mojom::blink::Role::kListBoxOption:
@@ -4816,6 +4817,7 @@
     case ax::mojom::blink::Role::kComboBoxMenuButton:
     case ax::mojom::blink::Role::kComboBoxSelect:
     case ax::mojom::blink::Role::kDisclosureTriangle:
+    case ax::mojom::blink::Role::kDisclosureTriangleGrouped:
     case ax::mojom::blink::Role::kListBox:
     case ax::mojom::blink::Role::kLink:
     case ax::mojom::blink::Role::kPopUpButton:
@@ -7102,6 +7104,7 @@
     case ax::mojom::blink::Role::kDocNoteRef:
     case ax::mojom::blink::Role::kDocGlossRef:
     case ax::mojom::blink::Role::kDisclosureTriangle:
+    case ax::mojom::blink::Role::kDisclosureTriangleGrouped:
     case ax::mojom::blink::Role::kHeading:
     case ax::mojom::blink::Role::kLayoutTableCell:
     case ax::mojom::blink::Role::kLineBreak:
diff --git a/third_party/closure_compiler/externs/automation.js b/third_party/closure_compiler/externs/automation.js
index ec562d2..1305bce 100644
--- a/third_party/closure_compiler/externs/automation.js
+++ b/third_party/closure_compiler/externs/automation.js
@@ -186,6 +186,7 @@
   DIALOG: 'dialog',
   DIRECTORY: 'directory',
   DISCLOSURE_TRIANGLE: 'disclosureTriangle',
+  DISCLOSURE_TRIANGLE_GROUPED: 'disclosureTriangleGrouped',
   DOC_ABSTRACT: 'docAbstract',
   DOC_ACKNOWLEDGMENTS: 'docAcknowledgments',
   DOC_AFTERWORD: 'docAfterword',
@@ -422,8 +423,7 @@
   SET_ACCESSIBILITY_FOCUS: 'setAccessibilityFocus',
   SET_SCROLL_OFFSET: 'setScrollOffset',
   SET_SELECTION: 'setSelection',
-  SET_SEQUENTIAL_FOCUS_NAVIGATION_STARTING_POINT:
-      'setSequentialFocusNavigationStartingPoint',
+  SET_SEQUENTIAL_FOCUS_NAVIGATION_STARTING_POINT: 'setSequentialFocusNavigationStartingPoint',
   SET_VALUE: 'setValue',
   SHOW_CONTEXT_MENU: 'showContextMenu',
   SIGNAL_END_OF_TEST: 'signalEndOfTest',
diff --git a/ui/accessibility/ax_enum_util.cc b/ui/accessibility/ax_enum_util.cc
index a4904b87..3ba813d 100644
--- a/ui/accessibility/ax_enum_util.cc
+++ b/ui/accessibility/ax_enum_util.cc
@@ -214,6 +214,8 @@
       return "directory";
     case ax::mojom::Role::kDisclosureTriangle:
       return "disclosureTriangle";
+    case ax::mojom::Role::kDisclosureTriangleGrouped:
+      return "disclosureTriangleGrouped";
     case ax::mojom::Role::kDocAbstract:
       return "docAbstract";
     case ax::mojom::Role::kDocAcknowledgments:
@@ -640,6 +642,8 @@
     return ax::mojom::Role::kDirectory;
   } else if (role == "kDisclosureTriangle") {
     return ax::mojom::Role::kDisclosureTriangle;
+  } else if (role == "kDisclosureTriangleGrouped") {
+    return ax::mojom::Role::kDisclosureTriangleGrouped;
   } else if (role == "kDocAbstract") {
     return ax::mojom::Role::kDocAbstract;
   } else if (role == "kDocAcknowledgments") {
diff --git a/ui/accessibility/ax_enums.mojom b/ui/accessibility/ax_enums.mojom
index 389eccf..ced8cf0df 100644
--- a/ui/accessibility/ax_enums.mojom
+++ b/ui/accessibility/ax_enums.mojom
@@ -112,8 +112,8 @@
 // Web: this attribute is only used in web content.
 //
 // Native: this attribute is only used in native UI.
-// Next version: 5
-// Next value: 210
+// Next version: 6
+// Next value: 211
 [Extensible, Stable, Uuid="d258eb73-e0cc-490c-b881-80ee11d3fec2"]
 enum Role {
   [Default]kUnknown = 181, // The role has not been set.
@@ -162,6 +162,7 @@
   kDialog = 35,
   kDirectory = 36,
   kDisclosureTriangle = 37,
+  [MinVersion=5] kDisclosureTriangleGrouped = 210,
   // --------------------------------------------------------------
   // DPub Roles:
   // https://www.w3.org/TR/dpub-aam-1.0/#mapping_role_table
diff --git a/ui/accessibility/ax_node.cc b/ui/accessibility/ax_node.cc
index f365805..7099630 100644
--- a/ui/accessibility/ax_node.cc
+++ b/ui/accessibility/ax_node.cc
@@ -1738,9 +1738,12 @@
 bool AXNode::SetRoleMatchesItemRole(const AXNode* ordered_set) const {
   ax::mojom::Role item_role = GetRole();
 
-  // Tree grid rows should be treated as ordered set items.
-  if (IsRowInTreeGrid(ordered_set))
+  // Tree grid rows and grouped disclosure triangles should be treated as
+  // ordered set items.
+  if (IsRowInTreeGrid(ordered_set) ||
+      item_role == ax::mojom::Role::kDisclosureTriangleGrouped) {
     return true;
+  }
 
   // Switch on role of ordered set
   switch (ordered_set->GetRole()) {
@@ -1793,6 +1796,7 @@
 
 bool AXNode::IsIgnoredContainerForOrderedSet() const {
   return IsIgnored() || IsEmbeddedGroup() ||
+         GetRole() == ax::mojom::Role::kDetails ||
          GetRole() == ax::mojom::Role::kLabelText ||
          GetRole() == ax::mojom::Role::kListItem ||
          GetRole() == ax::mojom::Role::kGenericContainer ||
diff --git a/ui/accessibility/ax_node_data_unittest.cc b/ui/accessibility/ax_node_data_unittest.cc
index 41610f4..4e5ea52 100644
--- a/ui/accessibility/ax_node_data_unittest.cc
+++ b/ui/accessibility/ax_node_data_unittest.cc
@@ -171,6 +171,7 @@
       ax::mojom::Role::kDate,
       ax::mojom::Role::kDateTime,
       ax::mojom::Role::kDisclosureTriangle,
+      ax::mojom::Role::kDisclosureTriangleGrouped,
       ax::mojom::Role::kDocBackLink,
       ax::mojom::Role::kDocBiblioRef,
       ax::mojom::Role::kDocGlossRef,
@@ -346,6 +347,7 @@
        ax::mojom::Role::kComboBoxMenuButton,
        ax::mojom::Role::kComboBoxSelect,
        ax::mojom::Role::kDisclosureTriangle,
+       ax::mojom::Role::kDisclosureTriangleGrouped,
        ax::mojom::Role::kTextFieldWithComboBox,
        ax::mojom::Role::kTreeItem};
 
diff --git a/ui/accessibility/ax_role_properties.cc b/ui/accessibility/ax_role_properties.cc
index f27fdb81..64a7080 100644
--- a/ui/accessibility/ax_role_properties.cc
+++ b/ui/accessibility/ax_role_properties.cc
@@ -117,6 +117,7 @@
     case ax::mojom::Role::kDate:
     case ax::mojom::Role::kDateTime:
     case ax::mojom::Role::kDisclosureTriangle:
+    case ax::mojom::Role::kDisclosureTriangleGrouped:
     case ax::mojom::Role::kDocBackLink:
     case ax::mojom::Role::kDocBiblioRef:
     case ax::mojom::Role::kDocGlossRef:
@@ -215,6 +216,7 @@
     case ax::mojom::Role::kDate:
     case ax::mojom::Role::kDateTime:
     case ax::mojom::Role::kDisclosureTriangle:
+    case ax::mojom::Role::kDisclosureTriangleGrouped:
     case ax::mojom::Role::kInputTime:
     case ax::mojom::Role::kListBox:
     case ax::mojom::Role::kListGrid:
@@ -369,6 +371,7 @@
   switch (role) {
     case ax::mojom::Role::kArticle:
     case ax::mojom::Role::kComment:
+    case ax::mojom::Role::kDisclosureTriangleGrouped:
     case ax::mojom::Role::kListItem:
     case ax::mojom::Role::kMenuItem:
     case ax::mojom::Role::kMenuItemRadio:
@@ -926,6 +929,7 @@
     case ax::mojom::Role::kDescriptionListTerm:
     case ax::mojom::Role::kDirectory:
     case ax::mojom::Role::kDisclosureTriangle:
+    case ax::mojom::Role::kDisclosureTriangleGrouped:
     case ax::mojom::Role::kDocBackLink:
     case ax::mojom::Role::kDocBiblioEntry:
     case ax::mojom::Role::kDocBiblioRef:
@@ -1048,6 +1052,7 @@
     case ax::mojom::Role::kComboBoxMenuButton:
     case ax::mojom::Role::kComboBoxSelect:
     case ax::mojom::Role::kDisclosureTriangle:
+    case ax::mojom::Role::kDisclosureTriangleGrouped:
     case ax::mojom::Role::kTextFieldWithComboBox:
     case ax::mojom::Role::kTreeItem:
       return true;
diff --git a/ui/accessibility/ax_tree.cc b/ui/accessibility/ax_tree.cc
index a206f03..3e552d38 100644
--- a/ui/accessibility/ax_tree.cc
+++ b/ui/accessibility/ax_tree.cc
@@ -2500,12 +2500,15 @@
                                             const AXNode* ordered_set) {
   DCHECK(ordered_set);
 
-  // Set items role::kComment and role::kRadioButton are special cases and do
-  // not necessarily need to be contained in an ordered set.
+  // Set items role::kComment and role::kDisclosureTriangleGrouped and
+  // role::kRadioButton are special cases and do not necessarily need to be
+  // contained in an ordered set.
   if (node.GetRole() != ax::mojom::Role::kComment &&
+      node.GetRole() != ax::mojom::Role::kDisclosureTriangleGrouped &&
       node.GetRole() != ax::mojom::Role::kRadioButton &&
-      !node.SetRoleMatchesItemRole(ordered_set) && !node.IsOrderedSet())
+      !node.SetRoleMatchesItemRole(ordered_set) && !node.IsOrderedSet()) {
     return;
+  }
 
   // Find all items within ordered_set and add to |items_map_to_be_populated|.
   OrderedSetItemsMap items_map_to_be_populated;
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc
index 5b75b39..33ccac4 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux.cc
+++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -2697,6 +2697,7 @@
     case ax::mojom::Role::kDirectory:
       return ATK_ROLE_LIST;
     case ax::mojom::Role::kDisclosureTriangle:
+    case ax::mojom::Role::kDisclosureTriangleGrouped:
       return ATK_ROLE_TOGGLE_BUTTON;
     case ax::mojom::Role::kDocCover:
       return ATK_ROLE_IMAGE;
diff --git a/ui/accessibility/platform/ax_platform_node_cocoa.mm b/ui/accessibility/platform/ax_platform_node_cocoa.mm
index 39b59f0..57fd954 100644
--- a/ui/accessibility/platform/ax_platform_node_cocoa.mm
+++ b/ui/accessibility/platform/ax_platform_node_cocoa.mm
@@ -555,6 +555,7 @@
     case ax::mojom::Role::kDirectory:
       return NSAccessibilityListRole;
     case ax::mojom::Role::kDisclosureTriangle:
+    case ax::mojom::Role::kDisclosureTriangleGrouped:
       // If Mac supports AXExpandedChanged event with
       // NSAccessibilityDisclosureTriangleRole, We should update
       // ax::mojom::Role::kDisclosureTriangle mapping to
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc
index bef4fb4..fd752be 100644
--- a/ui/accessibility/platform/ax_platform_node_win.cc
+++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -930,6 +930,7 @@
               UIA_WindowControlTypeId, L"dialog"};
 
     case ax::mojom::Role::kDisclosureTriangle:
+    case ax::mojom::Role::kDisclosureTriangleGrouped:
       return {UIALocalizationStrategy::kSupply, UIA_ButtonControlTypeId,
               L"button"};
 
@@ -6460,6 +6461,7 @@
       return ROLE_SYSTEM_DIALOG;
 
     case ax::mojom::Role::kDisclosureTriangle:
+    case ax::mojom::Role::kDisclosureTriangleGrouped:
       return ROLE_SYSTEM_PUSHBUTTON;
 
     case ax::mojom::Role::kDirectory: