Skip to content

Commit 5264837

Browse files
authored
Merge branch 'WordPress:trunk' into trunk
2 parents 619bbc0 + 0029901 commit 5264837

10 files changed

Lines changed: 118 additions & 38 deletions

src/wp-admin/css/common.css

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,13 +514,15 @@ code {
514514
}
515515

516516
.widefat th,
517+
.widefat tbody td.check-column,
517518
.widefat thead td,
518519
.widefat tfoot td {
519520
text-align: left;
520521
line-height: 1.3em;
521522
font-size: 14px;
522523
}
523524

525+
.widefat td.check-column input,
524526
.widefat th input,
525527
.updates-table td input,
526528
.widefat thead td input,
@@ -536,12 +538,14 @@ code {
536538
vertical-align: top;
537539
}
538540

539-
.widefat tbody th.check-column {
541+
.widefat tbody th.check-column,
542+
.widefat tbody td.check-column {
540543
padding: 9px 0 22px;
541544
}
542545

543546
.widefat thead td.check-column,
544547
.widefat tbody th.check-column,
548+
.widefat tbody td.check-column,
545549
.updates-table tbody td.check-column,
546550
.widefat tfoot td.check-column {
547551
padding: 11px 0 0 3px;

src/wp-admin/css/forms.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1967,7 +1967,8 @@ table.form-table td .updated p {
19671967
margin-left: 0;
19681968
}
19691969

1970-
.wp-list-table.privacy_requests tr:not(.inline-edit-row):not(.no-items) td.column-primary:not(.check-column) {
1970+
.wp-list-table.privacy_requests tr:not(.inline-edit-row):not(.no-items) td.column-primary:not(.check-column),
1971+
.wp-list-table.privacy_requests tr:not(.inline-edit-row):not(.no-items) th.column-primary:not(.check-column) {
19711972
display: table-cell;
19721973
}
19731974

src/wp-admin/css/list-tables.css

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -222,11 +222,13 @@
222222
background-color: #fcf9e8;
223223
}
224224

225-
#the-comment-list .unapproved th.check-column {
225+
#the-comment-list .unapproved th.check-column,
226+
#the-comment-list .unapproved td.check-column {
226227
border-left: 4px solid #d63638;
227228
}
228229

229-
#the-comment-list .unapproved th.check-column input {
230+
#the-comment-list .unapproved th.check-column input,
231+
#the-comment-list .unapproved td.check-column input {
230232
margin-left: 4px;
231233
}
232234

@@ -1221,11 +1223,13 @@ ul.cat-checklist input[name="post_category[]"]:indeterminate::before {
12211223
------------------------------------------------------------------------------*/
12221224

12231225
.plugins tbody th.check-column,
1226+
.plugins tbody td.check-column,
12241227
.plugins tbody {
12251228
padding: 8px 0 0 2px;
12261229
}
12271230

1228-
.plugins tbody th.check-column input[type=checkbox] {
1231+
.plugins tbody th.check-column input[type=checkbox],
1232+
.plugins tbody td.check-column input[type=checkbox] {
12291233
margin-top: 4px;
12301234
}
12311235

@@ -1235,7 +1239,8 @@ ul.cat-checklist input[name="post_category[]"]:indeterminate::before {
12351239

12361240
.plugins thead td.check-column,
12371241
.plugins tfoot td.check-column,
1238-
.plugins .inactive th.check-column {
1242+
.plugins .inactive th.check-column,
1243+
.plugins .inactive td.check-column {
12391244
padding-left: 6px;
12401245
}
12411246

@@ -1325,6 +1330,7 @@ ul.cat-checklist input[name="post_category[]"]:indeterminate::before {
13251330
}
13261331

13271332
.plugins .active th.check-column,
1333+
.plugins .active td.check-column,
13281334
.plugin-update-tr.active td {
13291335
border-left: 4px solid var(--wp-admin-theme-color);
13301336
}
@@ -1410,7 +1416,8 @@ ul.cat-checklist input[name="post_category[]"]:indeterminate::before {
14101416
text-decoration: underline;
14111417
}
14121418

1413-
.plugins tr.paused th.check-column {
1419+
.plugins tr.paused th.check-column,
1420+
.plugins tr.paused td.check-column {
14141421
border-left: 4px solid #b32d2e;
14151422
}
14161423

@@ -1909,7 +1916,8 @@ div.action-links,
19091916
}
19101917

19111918
.wp-list-table th.column-primary ~ th,
1912-
.wp-list-table tr:not(.inline-edit-row):not(.no-items) td.column-primary ~ td:not(.check-column) {
1919+
.wp-list-table tr:not(.inline-edit-row):not(.no-items) td.column-primary ~ td:not(.check-column),
1920+
.wp-list-table tr:not(.inline-edit-row):not(.no-items) th.column-primary ~ td:not(.check-column) {
19131921
display: none;
19141922
}
19151923

@@ -1918,7 +1926,8 @@ div.action-links,
19181926
}
19191927

19201928
/* Checkboxes need to show */
1921-
.wp-list-table tr th.check-column {
1929+
.wp-list-table tr th.check-column,
1930+
.wp-list-table tr td.check-column {
19221931
display: table-cell;
19231932
}
19241933

@@ -1936,11 +1945,13 @@ div.action-links,
19361945
width: auto !important; /* needs to override some columns that are more specifically targeted */
19371946
}
19381947

1939-
.wp-list-table td.column-primary {
1948+
.wp-list-table td.column-primary,
1949+
.wp-list-table th.column-primary {
19401950
padding-right: 50px; /* space for toggle button */
19411951
}
19421952

1943-
.wp-list-table tr:not(.inline-edit-row):not(.no-items) td.column-primary ~ td:not(.check-column) {
1953+
.wp-list-table tr:not(.inline-edit-row):not(.no-items) td.column-primary ~ td:not(.check-column),
1954+
.wp-list-table tr:not(.inline-edit-row):not(.no-items) th.column-primary ~ td:not(.check-column) {
19441955
padding: 3px 8px 3px 35%;
19451956
}
19461957

@@ -2269,12 +2280,14 @@ div.action-links,
22692280
}
22702281

22712282
.plugins tr.active + tr.inactive th.check-column,
2283+
.plugins tr.active + tr.inactive td.check-column,
22722284
.plugins tr.active + tr.inactive td.column-description,
22732285
.plugins .plugin-update-tr:before {
22742286
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.1);
22752287
}
22762288

22772289
.plugins tr.active + tr.inactive th.check-column,
2290+
.plugins tr.active + tr.inactive td.check-column,
22782291
.plugins tr.active + tr.inactive td {
22792292
border-top: none;
22802293
}
@@ -2309,13 +2322,15 @@ div.action-links,
23092322
line-height: 1.5;
23102323
}
23112324

2312-
.plugins tbody th.check-column {
2325+
.plugins tbody th.check-column,
2326+
.plugins tbody td.check-column {
23132327
padding: 8px 0 0 5px;
23142328
}
23152329

23162330
.plugins thead td.check-column,
23172331
.plugins tfoot td.check-column,
2318-
.plugins .inactive th.check-column {
2332+
.plugins .inactive th.check-column,
2333+
.plugins .inactive td.check-column {
23192334
padding-left: 9px;
23202335
}
23212336

src/wp-admin/includes/class-wp-list-table.php

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1767,6 +1767,26 @@ protected function column_default( $item, $column_name ) {}
17671767
*/
17681768
protected function column_cb( $item ) {}
17691769

1770+
/**
1771+
* Returns a clean, human-readable label for the primary column's row header.
1772+
*
1773+
* Used as the `aria-label` attribute value on the `<th scope="row">` element,
1774+
* giving screen readers a concise cell name instead of computing it from
1775+
* the full cell content (which may include row action links, excerpts, etc.).
1776+
*
1777+
* Subclasses should override this method to return the item's primary
1778+
* identifier (e.g. post title, plugin name, username). Return an empty string
1779+
* to omit the attribute.
1780+
*
1781+
* @since 6.9.0
1782+
*
1783+
* @param object|array $item The current item.
1784+
* @return string The aria-label value, or an empty string.
1785+
*/
1786+
protected function get_primary_column_aria_label( $item ) {
1787+
return '';
1788+
}
1789+
17701790
/**
17711791
* Generates the columns for a single row of the table.
17721792
*
@@ -1796,9 +1816,9 @@ protected function single_row_columns( $item ) {
17961816
$attributes = "class='$classes' $data";
17971817

17981818
if ( 'cb' === $column_name ) {
1799-
echo '<th scope="row" class="check-column">';
1819+
echo '<td class="check-column">';
18001820
echo $this->column_cb( $item );
1801-
echo '</th>';
1821+
echo '</td>';
18021822
} elseif ( method_exists( $this, '_column_' . $column_name ) ) {
18031823
echo call_user_func(
18041824
array( $this, '_column_' . $column_name ),
@@ -1807,16 +1827,29 @@ protected function single_row_columns( $item ) {
18071827
$data,
18081828
$primary
18091829
);
1810-
} elseif ( method_exists( $this, 'column_' . $column_name ) ) {
1811-
echo "<td $attributes>";
1812-
echo call_user_func( array( $this, 'column_' . $column_name ), $item );
1813-
echo $this->handle_row_actions( $item, $column_name, $primary );
1814-
echo '</td>';
18151830
} else {
1816-
echo "<td $attributes>";
1817-
echo $this->column_default( $item, $column_name );
1831+
$is_primary = ( $primary === $column_name );
1832+
$tag = $is_primary ? 'th' : 'td';
1833+
$scope = $is_primary ? ' scope="row"' : '';
1834+
1835+
$aria_label = '';
1836+
if ( $is_primary ) {
1837+
$label = $this->get_primary_column_aria_label( $item );
1838+
if ( '' !== $label ) {
1839+
$aria_label = ' aria-label="' . esc_attr( $label ) . '"';
1840+
}
1841+
}
1842+
1843+
echo "<$tag $attributes$scope$aria_label>";
1844+
1845+
if ( method_exists( $this, 'column_' . $column_name ) ) {
1846+
echo call_user_func( array( $this, 'column_' . $column_name ), $item );
1847+
} else {
1848+
echo $this->column_default( $item, $column_name );
1849+
}
1850+
18181851
echo $this->handle_row_actions( $item, $column_name, $primary );
1819-
echo '</td>';
1852+
echo "</$tag>";
18201853
}
18211854
}
18221855
}

src/wp-admin/includes/class-wp-ms-themes-list-table.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -940,11 +940,11 @@ public function single_row_columns( $item ) {
940940

941941
switch ( $column_name ) {
942942
case 'cb':
943-
echo '<th scope="row" class="check-column">';
943+
echo '<td class="check-column">';
944944

945945
$this->column_cb( $item );
946946

947-
echo '</th>';
947+
echo '</td>';
948948
break;
949949

950950
case 'name':
@@ -966,11 +966,11 @@ public function single_row_columns( $item ) {
966966
}
967967
}
968968

969-
echo "<td class='theme-title column-primary{$extra_classes}'><strong>" . $item->display( 'Name' ) . $active_theme_label . '</strong>';
969+
echo "<th scope='row' class='theme-title column-primary{$extra_classes}' aria-label='" . esc_attr( $item->display( 'Name' ) ) . "'><strong>" . $item->display( 'Name' ) . $active_theme_label . '</strong>';
970970

971971
$this->column_name( $item );
972972

973-
echo '</td>';
973+
echo '</th>';
974974
break;
975975

976976
case 'description':

src/wp-admin/includes/class-wp-plugins-list-table.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,12 +1233,12 @@ public function single_row( $item ) {
12331233

12341234
switch ( $column_name ) {
12351235
case 'cb':
1236-
echo "<th scope='row' class='check-column'>$checkbox</th>";
1236+
echo "<td class='check-column'>$checkbox</td>";
12371237
break;
12381238
case 'name':
1239-
echo "<td class='plugin-title column-primary'><strong>$plugin_name</strong>";
1239+
echo "<th scope='row' class='plugin-title column-primary' aria-label='" . esc_attr( $plugin_name ) . "'><strong>$plugin_name</strong>";
12401240
echo $this->row_actions( $actions, true );
1241-
echo '</td>';
1241+
echo '</th>';
12421242
break;
12431243
case 'description':
12441244
$classes = 'column-description desc';

src/wp-admin/includes/class-wp-posts-list-table.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,10 +1114,28 @@ public function column_cb( $item ) {
11141114
* @param string $primary
11151115
*/
11161116
protected function _column_title( $post, $classes, $data, $primary ) {
1117-
echo '<td class="' . $classes . ' page-title" ', $data, '>';
1117+
$aria_label = $this->get_primary_column_aria_label( $post );
1118+
$aria_attr = ( '' !== $aria_label ) ? ' aria-label="' . esc_attr( $aria_label ) . '"' : '';
1119+
echo '<th scope="row" class="' . $classes . ' page-title" ', $data, $aria_attr, '>';
11181120
echo $this->column_title( $post );
11191121
echo $this->handle_row_actions( $post, 'title', $primary );
1120-
echo '</td>';
1122+
echo '</th>';
1123+
}
1124+
1125+
/**
1126+
* Returns a clean label for the primary (title) column's row header `aria-label`.
1127+
*
1128+
* Provides screen readers with just the post title as the row header name,
1129+
* preventing them from computing the name from the full cell content
1130+
* (which includes row action links, post states, and possibly an excerpt).
1131+
*
1132+
* @since 6.9.0
1133+
*
1134+
* @param WP_Post $item The current post object.
1135+
* @return string The post title, or 'no title' if no title.
1136+
*/
1137+
protected function get_primary_column_aria_label( $item ) {
1138+
return isset( $item->post_title ) && ! empty( $item->post_title ) ? $item->post_title : __( 'no title' );
11211139
}
11221140

11231141
/**

src/wp-admin/includes/class-wp-screen.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ final class WP_Screen {
8989
* have a `$parent_base` of 'edit'.
9090
*
9191
* @since 3.3.0
92-
* @var string|null
92+
* @var ?string
9393
*/
9494
public $parent_base;
9595

@@ -99,7 +99,7 @@ final class WP_Screen {
9999
* Some `$parent_file` values are 'edit.php?post_type=page', 'edit.php', and 'options-general.php'.
100100
*
101101
* @since 3.3.0
102-
* @var string|null
102+
* @var ?string
103103
*/
104104
public $parent_file;
105105

@@ -186,7 +186,7 @@ final class WP_Screen {
186186
* Stores the 'screen_settings' section of screen options.
187187
*
188188
* @since 3.3.0
189-
* @var string
189+
* @var ?string
190190
*/
191191
private $_screen_settings;
192192

src/wp-admin/includes/class-wp-users-list-table.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -563,9 +563,16 @@ public function single_row( $user_object, $style = '', $role = '', $numposts = 0
563563
$attributes = "class='$classes' $data";
564564

565565
if ( 'cb' === $column_name ) {
566-
$row .= "<th scope='row' class='check-column'>$checkbox</th>";
566+
$row .= "<td class='check-column'>$checkbox</td>";
567567
} else {
568-
$row .= "<td $attributes>";
568+
$is_primary = ( $primary === $column_name );
569+
$tag = $is_primary ? 'th' : 'td';
570+
$scope = $is_primary ? ' scope="row"' : '';
571+
$aria_label = '';
572+
if ( $is_primary ) {
573+
$aria_label = ' aria-label="' . esc_attr( $user_object->user_login ) . '"';
574+
}
575+
$row .= "<$tag $attributes$scope$aria_label>";
569576
switch ( $column_name ) {
570577
case 'username':
571578
$row .= "$avatar $edit";
@@ -628,7 +635,8 @@ public function single_row( $user_object, $style = '', $role = '', $numposts = 0
628635
if ( $primary === $column_name ) {
629636
$row .= $this->row_actions( $actions );
630637
}
631-
$row .= '</td>';
638+
$tag = ( $primary === $column_name ) ? 'th' : 'td';
639+
$row .= "</$tag>";
632640
}
633641
}
634642
$row .= '</tr>';

src/wp-includes/formatting.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2186,6 +2186,7 @@ function sanitize_user( $username, $strict = false ) {
21862186
*
21872187
* @param string $key String key.
21882188
* @return string Sanitized key.
2189+
* @phpstan-return lowercase-string
21892190
*/
21902191
function sanitize_key( $key ) {
21912192
$sanitized_key = '';

0 commit comments

Comments
 (0)