Chromium Task Manager - TableView Accessibility(part 4)
This CL format the ICU syntax of the IDS string for table rows. Also use ListFormatter to format the header name and the task name for task group. With this change. The AX name for table header for macOS would be, col1, col2, col3 and col4 the row name for task group would be . col1, col2, col3 and col4. Another task in the same task group: taskA col1, col2, col3 and col4. Other 3 tasks in the same task group: taskA, taskB and taskC Screenshot demo: header - https://screenshot.googleplex.com/8sLV9Xvp4ptUZvn task group - https://screenshot.googleplex.com/5wNACdTACp2oCgo https://screenshot.googleplex.com/84ojrjUy3Ytesqm Bug: 396213873 Change-Id: I9415379a18670f97e11ef5ae42302546c2707a64 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6334691 Reviewed-by: Peter Kasting <pkasting@chromium.org> Reviewed-by: Michael Wojcicka <mwoj@google.com> Commit-Queue: Zhengzheng Liu <zhzhliu@chromium.org> Cr-Commit-Position: refs/heads/main@{#1432462}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
6445fbe646
commit
1d31234adb
chrome
app
browser
ui
test
@ -4944,7 +4944,11 @@ are declared in tools/grit/grit_args.gni.
|
||||
<ph name="NUM_HANDLES">$1<ex>300</ex></ph> (<ph name="NUM_KILOBYTES_LIVE">$2<ex>500</ex></ph> peak)
|
||||
</message>
|
||||
<message name="IDS_TASK_MANAGER_TASK_GROUP_CONNECT_TEXT" desc="The text used to connect tasks in the same task group for accessibility features. [ICU_Syntax]">
|
||||
{NUM_TASKS, plural, =1 {<ph name="TASK_ROW">{TASK_ROW}<ex>MyTask</ex></ph>} other {<ph name="TASK_ROW">{TASK_ROW}<ex>MyTask</ex></ph>. Other <ph name="OTHER_TASK_NUM">{OTHER_TASK_NUM}<ex>2</ex></ph> tasks in the same task group: <ph name="OTHER_TASKS">{OTHER_TASKS}<ex>TaskA TaskB</ex></ph>}}
|
||||
{NUM_TASKS, plural,
|
||||
=0 {<ph name="TASK_ROW">{TASK_ROW}<ex>MyTask</ex></ph>}
|
||||
=1 {<ph name="TASK_ROW">{TASK_ROW}<ex>MyTask</ex></ph>. Another task in the same task group: <ph name="OTHER_TASKS">{OTHER_TASKS}<ex>TaskA</ex></ph>}
|
||||
other {<ph name="TASK_ROW">{TASK_ROW}<ex>MyTask</ex></ph>. Other # tasks in the same task group: <ph name="OTHER_TASKS">{OTHER_TASKS}<ex>TaskA, TaskB, and TaskC</ex></ph>}
|
||||
}
|
||||
</message>
|
||||
<message name="IDS_TASK_MANAGER_WEB_BROWSER_CELL_TEXT" desc="The text of the web browser process row">
|
||||
Browser
|
||||
|
@ -1 +1 @@
|
||||
2f2eeb1e1832bc4a02d45522418b098f4ef6b26b
|
||||
17c4bc1d9cf5e3644df73df5110178c8875e436a
|
@ -22,6 +22,8 @@
|
||||
#include "base/i18n/rtl.h"
|
||||
#include "base/i18n/string_search.h"
|
||||
#include "base/i18n/time_formatting.h"
|
||||
#include "base/i18n/unicodestring.h"
|
||||
#include "base/numerics/safe_conversions.h"
|
||||
#include "base/process/process_handle.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
@ -42,6 +44,8 @@
|
||||
#include "components/nacl/common/nacl_switches.h"
|
||||
#include "components/prefs/scoped_user_pref_update.h"
|
||||
#include "content/public/common/result_codes.h"
|
||||
#include "third_party/icu/source/common/unicode/utypes.h"
|
||||
#include "third_party/icu/source/i18n/unicode/listformatter.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/base/models/image_model.h"
|
||||
#include "ui/base/models/table_model_observer.h"
|
||||
@ -723,7 +727,7 @@ std::u16string TaskManagerTableModel::GetAXNameForHeader(
|
||||
}
|
||||
|
||||
CHECK(!visible_column_titles.empty());
|
||||
return base::JoinString(visible_column_titles, u" ");
|
||||
return FormatListToString(visible_column_titles);
|
||||
}
|
||||
|
||||
std::u16string TaskManagerTableModel::GetAXNameForRow(
|
||||
@ -779,13 +783,35 @@ std::u16string TaskManagerTableModel::GetAXNameForRow(
|
||||
}
|
||||
}
|
||||
|
||||
const int other_tasks_size = static_cast<int>(other_task_titles.size());
|
||||
|
||||
return base::i18n::MessageFormatter::FormatWithNamedArgs(
|
||||
l10n_util::GetStringUTF16(IDS_TASK_MANAGER_TASK_GROUP_CONNECT_TEXT),
|
||||
"NUM_TASKS", other_tasks_size + 1, "TASK_ROW",
|
||||
base::JoinString(column_names, u" "), "OTHER_TASK_NUM", other_tasks_size,
|
||||
"OTHER_TASKS", base::JoinString(other_task_titles, u" "));
|
||||
"NUM_TASKS", base::checked_cast<int>(other_task_titles.size()),
|
||||
"TASK_ROW", FormatListToString(column_names), "OTHER_TASKS",
|
||||
FormatListToString(other_task_titles));
|
||||
}
|
||||
|
||||
std::u16string TaskManagerTableModel::FormatListToString(
|
||||
base::span<const std::u16string> items) {
|
||||
if (items.empty()) {
|
||||
return std::u16string();
|
||||
}
|
||||
|
||||
std::vector<icu::UnicodeString> strings;
|
||||
strings.reserve(items.size());
|
||||
for (const auto& item : items) {
|
||||
strings.emplace_back(item.data(), item.size());
|
||||
}
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
const auto formatter =
|
||||
base::WrapUnique(icu::ListFormatter::createInstance(status));
|
||||
CHECK(U_SUCCESS(status));
|
||||
|
||||
icu::UnicodeString formatted;
|
||||
formatter->format(strings.data(), strings.size(), formatted, status);
|
||||
CHECK(U_SUCCESS(status));
|
||||
|
||||
return base::i18n::UnicodeStringToString16(formatted);
|
||||
}
|
||||
|
||||
void TaskManagerTableModel::GetRowsGroupRange(size_t row_index,
|
||||
|
@ -99,6 +99,9 @@ class TaskManagerTableModel : public TaskManagerObserver,
|
||||
size_t row,
|
||||
const std::vector<int>& visible_column_ids) override;
|
||||
|
||||
static std::u16string FormatListToString(
|
||||
base::span<const std::u16string> items);
|
||||
|
||||
void FilterTaskList(TaskIdList& tasks);
|
||||
|
||||
// task_manager::TaskManagerObserver:
|
||||
|
@ -0,0 +1,44 @@
|
||||
// Copyright 2025 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "chrome/browser/ui/task_manager/task_manager_table_model.h"
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
using TaskManagerTableModelTest = testing::Test;
|
||||
|
||||
namespace {
|
||||
bool ContainsSubstringsInOrder(std::u16string_view text,
|
||||
const std::vector<std::u16string>& substrings) {
|
||||
for (const auto& substring : substrings) {
|
||||
size_t found_pos = text.find(substring);
|
||||
if (found_pos == std::u16string_view::npos) {
|
||||
return false;
|
||||
}
|
||||
text.remove_prefix(found_pos + substring.length());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST_F(TaskManagerTableModelTest, FormatListToString) {
|
||||
std::vector<std::u16string> tasks;
|
||||
|
||||
EXPECT_EQ(task_manager::TaskManagerTableModel::FormatListToString(tasks),
|
||||
std::u16string());
|
||||
|
||||
tasks.push_back(u"task1");
|
||||
EXPECT_TRUE(ContainsSubstringsInOrder(
|
||||
task_manager::TaskManagerTableModel::FormatListToString(tasks), tasks));
|
||||
tasks.push_back(u"task2");
|
||||
EXPECT_TRUE(ContainsSubstringsInOrder(
|
||||
task_manager::TaskManagerTableModel::FormatListToString(tasks), tasks));
|
||||
tasks.push_back(u"task3");
|
||||
EXPECT_TRUE(ContainsSubstringsInOrder(
|
||||
task_manager::TaskManagerTableModel::FormatListToString(tasks), tasks));
|
||||
}
|
@ -6260,6 +6260,7 @@ test("unit_tests") {
|
||||
"../browser/ui/passwords/password_cross_domain_confirmation_popup_controller_impl_unittest.cc",
|
||||
"../browser/ui/plus_addresses/plus_address_creation_controller_desktop_unittest.cc",
|
||||
"../browser/ui/plus_addresses/plus_address_menu_model_unittest.cc",
|
||||
"../browser/ui/task_manager/task_manager_table_model_unittest.cc",
|
||||
"../browser/ui/user_education/recent_session_policy_unittest.cc",
|
||||
"../browser/ui/webui/profile_internals/profile_internals_handler_unittest.cc",
|
||||
"../browser/user_education/browser_user_education_storage_service_unittest.cc",
|
||||
|
Reference in New Issue
Block a user