From c1b4c32f63697bbe28eab8481b59c23d2b0b1f12 Mon Sep 17 00:00:00 2001
From: Oliver Bartsch <bo@cedev.de>
Date: Thu, 13 Jun 2024 12:14:55 +0200
Subject: [PATCH] [BUGFIX] Add aria-label to the selection options toggle
 button
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The toggle button to open the selection options
of the multi record selection component does now
provide an aria-label to make it accessible for
screen readers.

Resolves: #104089
Releases: main, 12.4
Change-Id: I89af5e4f5a0f8dd87be5d532bdd894bd2636502e
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/84686
Tested-by: Oliver Bartsch <bo@cedev.de>
Reviewed-by: Jasmina Ließmann <minapokhalo+typo3@gmail.com>
Reviewed-by: Oliver Bartsch <bo@cedev.de>
Tested-by: Michael Telgkamp <michael.telgkamp@mindscreen.de>
Tested-by: Jasmina Ließmann <minapokhalo+typo3@gmail.com>
Tested-by: Andreas Nedbal <andy@pixelde.su>
Reviewed-by: Andreas Nedbal <andy@pixelde.su>
Reviewed-by: Michael Telgkamp <michael.telgkamp@mindscreen.de>
Tested-by: core-ci <typo3@b13.com>
---
 .../workspaces/renderable/record-table.ts         |  2 +-
 .../Form/Element/SelectCheckBoxElement.php        | 15 ++++++++-------
 .../Classes/RecordList/DatabaseRecordList.php     |  2 +-
 .../Resources/Private/Language/locallang_core.xlf |  3 +++
 typo3/sysext/filelist/Classes/FileList.php        |  2 +-
 .../Private/Templates/Management/Overview.html    |  2 +-
 .../Private/Templates/RecyclerModule.html         |  2 +-
 .../Private/Templates/Management/Overview.html    |  2 +-
 .../Resources/Private/Partials/TaskList.html      |  1 +
 .../Private/Templates/Management/Overview.html    |  2 +-
 .../Public/JavaScript/renderable/record-table.js  |  2 +-
 11 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/Build/Sources/TypeScript/workspaces/renderable/record-table.ts b/Build/Sources/TypeScript/workspaces/renderable/record-table.ts
index c0ef023b000d..7d48887658f0 100644
--- a/Build/Sources/TypeScript/workspaces/renderable/record-table.ts
+++ b/Build/Sources/TypeScript/workspaces/renderable/record-table.ts
@@ -89,7 +89,7 @@ export class RecordTableElement extends LitElement {
           <tr>
             <th>
               <div class="btn-group dropdown">
-                <button type="button" class="dropdown-toggle dropdown-toggle-link t3js-multi-record-selection-check-actions-toggle" data-bs-toggle="dropdown" data-bs-boundary="window" aria-expanded="false">
+                <button type="button" class="dropdown-toggle dropdown-toggle-link t3js-multi-record-selection-check-actions-toggle" data-bs-toggle="dropdown" data-bs-boundary="window" aria-expanded="false" aria-label="${TYPO3.lang['labels.openSelectionOptions']}">
                   <typo3-backend-icon identifier="actions-selection" size="small"></typo3-backend-icon>
                 </button>
                 <ul class="dropdown-menu t3js-multi-record-selection-check-actions">
diff --git a/typo3/sysext/backend/Classes/Form/Element/SelectCheckBoxElement.php b/typo3/sysext/backend/Classes/Form/Element/SelectCheckBoxElement.php
index e11c45bed052..697524f1087f 100644
--- a/typo3/sysext/backend/Classes/Form/Element/SelectCheckBoxElement.php
+++ b/typo3/sysext/backend/Classes/Form/Element/SelectCheckBoxElement.php
@@ -306,45 +306,46 @@ class SelectCheckBoxElement extends AbstractFormElement
 
     protected function getRecordSelectionCheckActions(): string
     {
+        $lang = $this->getLanguageService();
         return '
             <div class="btn-group dropdown">
-                <button type="button" class="dropdown-toggle dropdown-toggle-link t3js-multi-record-selection-check-actions-toggle" data-bs-toggle="dropdown" data-bs-boundary="window" aria-expanded="false">
+                <button type="button" class="dropdown-toggle dropdown-toggle-link t3js-multi-record-selection-check-actions-toggle" data-bs-toggle="dropdown" data-bs-boundary="window" aria-expanded="false" aria-label="' . htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.openSelectionOptions')) . '">
                     <core:icon identifier="actions-selection" size="small" />
                     ' . $this->iconFactory->getIcon('actions-selection', IconSize::SMALL)->render() . '
                 </button>
                 <ul class="dropdown-menu t3js-multi-record-selection-check-actions">
                     <li>
-                        <button type="button" class="dropdown-item disabled" data-multi-record-selection-check-action="check-all" title="' . $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.checkAll') . '">
+                        <button type="button" class="dropdown-item disabled" data-multi-record-selection-check-action="check-all" title="' . htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.checkAll')) . '">
                             <span class="dropdown-item-columns">
                                 <span class="dropdown-item-column dropdown-item-column-icon" aria-hidden="true">
                                     ' . $this->iconFactory->getIcon('actions-selection-elements-all', IconSize::SMALL)->render() . '
                                 </span>
                                 <span class="dropdown-item-column dropdown-item-column-title">
-                                    ' . $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.checkAll') . '
+                                    ' . htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.checkAll')) . '
                                 </span>
                             </span>
                         </button>
                     </li>
                     <li>
-                        <button type="button" class="dropdown-item disabled" data-multi-record-selection-check-action="check-none" title="' . $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.uncheckAll') . '">
+                        <button type="button" class="dropdown-item disabled" data-multi-record-selection-check-action="check-none" title="' . htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.uncheckAll')) . '">
                             <span class="dropdown-item-columns">
                                 <span class="dropdown-item-column dropdown-item-column-icon" aria-hidden="true">
                                     ' . $this->iconFactory->getIcon('actions-selection-elements-none', IconSize::SMALL)->render() . '
                                 </span>
                                 <span class="dropdown-item-column dropdown-item-column-title">
-                                    ' . $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.uncheckAll') . '
+                                    ' . htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.uncheckAll')) . '
                                 </span>
                             </span>
                         </button>
                     </li>
                     <li>
-                        <button type="button" class="dropdown-item" data-multi-record-selection-check-action="toggle" title="' . $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.toggleSelection') . '">
+                        <button type="button" class="dropdown-item" data-multi-record-selection-check-action="toggle" title="' . htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.toggleSelection')) . '">
                             <span class="dropdown-item-columns">
                                 <span class="dropdown-item-column dropdown-item-column-icon" aria-hidden="true">
                                     ' . $this->iconFactory->getIcon('actions-selection-elements-invert', IconSize::SMALL)->render() . '
                                 </span>
                                 <span class="dropdown-item-column dropdown-item-column-title">
-                                    ' . $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.toggleSelection') . '
+                                    ' . htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.toggleSelection')) . '
                                 </span>
                             </span>
                         </button>
diff --git a/typo3/sysext/backend/Classes/RecordList/DatabaseRecordList.php b/typo3/sysext/backend/Classes/RecordList/DatabaseRecordList.php
index f3e611fac20d..270b7fa16d2b 100644
--- a/typo3/sysext/backend/Classes/RecordList/DatabaseRecordList.php
+++ b/typo3/sysext/backend/Classes/RecordList/DatabaseRecordList.php
@@ -3140,7 +3140,7 @@ class DatabaseRecordList
 
         return '
             <div class="btn-group dropdown">
-                <button type="button" class="dropdown-toggle dropdown-toggle-link t3js-multi-record-selection-check-actions-toggle" data-bs-toggle="dropdown" data-bs-boundary="window" aria-expanded="false">
+                <button type="button" class="dropdown-toggle dropdown-toggle-link t3js-multi-record-selection-check-actions-toggle" data-bs-toggle="dropdown" data-bs-boundary="window" aria-expanded="false" aria-label="' . htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.openSelectionOptions')) . '">
                     ' . $this->iconFactory->getIcon('actions-selection', IconSize::SMALL) . '
                 </button>
                 <ul class="dropdown-menu t3js-multi-record-selection-check-actions">
diff --git a/typo3/sysext/core/Resources/Private/Language/locallang_core.xlf b/typo3/sysext/core/Resources/Private/Language/locallang_core.xlf
index b81f9d16930c..366bad678e08 100644
--- a/typo3/sysext/core/Resources/Private/Language/locallang_core.xlf
+++ b/typo3/sysext/core/Resources/Private/Language/locallang_core.xlf
@@ -451,6 +451,9 @@ Do you want to continue WITHOUT saving?</source>
 			<trans-unit id="labels.setAllCheckboxes" resname="labels.setAllCheckboxes">
 				<source>Select All Checkboxes</source>
 			</trans-unit>
+			<trans-unit id="labels.openSelectionOptions" resname="labels.openSelectionOptions">
+				<source>Open selection options</source>
+			</trans-unit>
 			<trans-unit id="labels.checkAll" resname="labels.checkAll">
 				<source>Check all</source>
 			</trans-unit>
diff --git a/typo3/sysext/filelist/Classes/FileList.php b/typo3/sysext/filelist/Classes/FileList.php
index 64ffde9abb5e..f14c045a5950 100644
--- a/typo3/sysext/filelist/Classes/FileList.php
+++ b/typo3/sysext/filelist/Classes/FileList.php
@@ -1420,7 +1420,7 @@ class FileList
 
         return '
             <div class="btn-group dropdown">
-                <button type="button" class="dropdown-toggle dropdown-toggle-link t3js-multi-record-selection-check-actions-toggle" data-bs-toggle="dropdown" data-bs-boundary="window" aria-expanded="false">
+                <button type="button" class="dropdown-toggle dropdown-toggle-link t3js-multi-record-selection-check-actions-toggle" data-bs-toggle="dropdown" data-bs-boundary="window" aria-expanded="false" aria-label="' . htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.openSelectionOptions')) . '">
                     ' . $this->iconFactory->getIcon('actions-selection', IconSize::SMALL) . '
                 </button>
                 <ul class="dropdown-menu t3js-multi-record-selection-check-actions">
diff --git a/typo3/sysext/reactions/Resources/Private/Templates/Management/Overview.html b/typo3/sysext/reactions/Resources/Private/Templates/Management/Overview.html
index 8ee9ad29d561..39911427af10 100644
--- a/typo3/sysext/reactions/Resources/Private/Templates/Management/Overview.html
+++ b/typo3/sysext/reactions/Resources/Private/Templates/Management/Overview.html
@@ -66,7 +66,7 @@
             <tr>
                 <th class="col-checkbox">
                     <div class="btn-group dropdown">
-                        <button type="button" class="dropdown-toggle dropdown-toggle-link t3js-multi-record-selection-check-actions-toggle" data-bs-toggle="dropdown" data-bs-boundary="window" aria-expanded="false">
+                        <button type="button" class="dropdown-toggle dropdown-toggle-link t3js-multi-record-selection-check-actions-toggle" data-bs-toggle="dropdown" data-bs-boundary="window" aria-expanded="false" aria-label="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.openSelectionOptions')}">
                             <core:icon identifier="actions-selection" size="small" />
                         </button>
                         <ul class="dropdown-menu t3js-multi-record-selection-check-actions">
diff --git a/typo3/sysext/recycler/Resources/Private/Templates/RecyclerModule.html b/typo3/sysext/recycler/Resources/Private/Templates/RecyclerModule.html
index 830195a2b48c..cfa73a7c8468 100644
--- a/typo3/sysext/recycler/Resources/Private/Templates/RecyclerModule.html
+++ b/typo3/sysext/recycler/Resources/Private/Templates/RecyclerModule.html
@@ -68,7 +68,7 @@
 
 <f:section name="multiRecordSelectionCheckboxActions">
     <div class="btn-group dropdown">
-        <button type="button" class="dropdown-toggle dropdown-toggle-link t3js-multi-record-selection-check-actions-toggle" data-bs-toggle="dropdown" data-bs-boundary="window" aria-expanded="false">
+        <button type="button" class="dropdown-toggle dropdown-toggle-link t3js-multi-record-selection-check-actions-toggle" data-bs-toggle="dropdown" data-bs-boundary="window" aria-expanded="false" aria-label="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.openSelectionOptions')}">
             <core:icon identifier="actions-selection" size="small" />
             <span class="visually-hidden"><f:translate id="LLL:EXT:recycler/Resources/Private/Language/locallang.xlf:button.dropdown.multiselect"/></span>
         </button>
diff --git a/typo3/sysext/redirects/Resources/Private/Templates/Management/Overview.html b/typo3/sysext/redirects/Resources/Private/Templates/Management/Overview.html
index 477e3f1bfdc3..e9925adff9ee 100644
--- a/typo3/sysext/redirects/Resources/Private/Templates/Management/Overview.html
+++ b/typo3/sysext/redirects/Resources/Private/Templates/Management/Overview.html
@@ -70,7 +70,7 @@
                 <tr>
                     <th>
                         <div class="btn-group dropdown">
-                            <a href="javascript:;" class="dropdown-toggle t3js-multi-record-selection-check-actions-toggle" data-bs-toggle="dropdown" data-bs-boundary="window" aria-expanded="false">
+                            <a href="javascript:;" class="dropdown-toggle t3js-multi-record-selection-check-actions-toggle" data-bs-toggle="dropdown" data-bs-boundary="window" aria-expanded="false" aria-label="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.openSelectionOptions')}">
                                 <core:icon identifier="actions-selection" size="small" />
                             </a>
                             <ul class="dropdown-menu t3js-multi-record-selection-check-actions">
diff --git a/typo3/sysext/scheduler/Resources/Private/Partials/TaskList.html b/typo3/sysext/scheduler/Resources/Private/Partials/TaskList.html
index b169279256a7..7c0d98d362ec 100644
--- a/typo3/sysext/scheduler/Resources/Private/Partials/TaskList.html
+++ b/typo3/sysext/scheduler/Resources/Private/Partials/TaskList.html
@@ -203,6 +203,7 @@
                                                 data-bs-toggle="dropdown"
                                                 data-bs-boundary="window"
                                                 aria-expanded="false"
+                                                aria-label="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.openSelectionOptions')}"
                                             >
                                                 <core:icon identifier="actions-selection" size="small" />
                                             </button>
diff --git a/typo3/sysext/webhooks/Resources/Private/Templates/Management/Overview.html b/typo3/sysext/webhooks/Resources/Private/Templates/Management/Overview.html
index a66f2e716abe..62bda2ad75a1 100644
--- a/typo3/sysext/webhooks/Resources/Private/Templates/Management/Overview.html
+++ b/typo3/sysext/webhooks/Resources/Private/Templates/Management/Overview.html
@@ -237,7 +237,7 @@
 
 <f:section name="multiRecordSelectionCheckboxActions">
     <div class="btn-group dropdown">
-        <button type="button" class="dropdown-toggle dropdown-toggle-link t3js-multi-record-selection-check-actions-toggle" data-bs-toggle="dropdown" data-bs-boundary="window" aria-expanded="false">
+        <button type="button" class="dropdown-toggle dropdown-toggle-link t3js-multi-record-selection-check-actions-toggle" data-bs-toggle="dropdown" data-bs-boundary="window" aria-expanded="false" aria-label="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.openSelectionOptions')}">
             <core:icon identifier="actions-selection" size="small" />
         </button>
         <ul class="dropdown-menu t3js-multi-record-selection-check-actions">
diff --git a/typo3/sysext/workspaces/Resources/Public/JavaScript/renderable/record-table.js b/typo3/sysext/workspaces/Resources/Public/JavaScript/renderable/record-table.js
index 6b207d8be312..f68e6f498a1a 100644
--- a/typo3/sysext/workspaces/Resources/Public/JavaScript/renderable/record-table.js
+++ b/typo3/sysext/workspaces/Resources/Public/JavaScript/renderable/record-table.js
@@ -17,7 +17,7 @@ var __decorate=function(e,t,n,a){var o,l=arguments.length,i=l<3?t:null===a?a=Obj
           <tr>
             <th>
               <div class="btn-group dropdown">
-                <button type="button" class="dropdown-toggle dropdown-toggle-link t3js-multi-record-selection-check-actions-toggle" data-bs-toggle="dropdown" data-bs-boundary="window" aria-expanded="false">
+                <button type="button" class="dropdown-toggle dropdown-toggle-link t3js-multi-record-selection-check-actions-toggle" data-bs-toggle="dropdown" data-bs-boundary="window" aria-expanded="false" aria-label="${TYPO3.lang["labels.openSelectionOptions"]}">
                   <typo3-backend-icon identifier="actions-selection" size="small"></typo3-backend-icon>
                 </button>
                 <ul class="dropdown-menu t3js-multi-record-selection-check-actions">
-- 
GitLab