Skip to content

Commit 743c905

Browse files
committed
Merge branch 'trunk' of https://github.com/WordPress/wordpress-develop into iapi-load-on-client-navigation
2 parents c448ed8 + 25420f0 commit 743c905

35 files changed

+2126
-307
lines changed

.github/workflows/reusable-test-gutenberg-build-process.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ jobs:
3434
# - Checks out the Gutenberg plugin into the plugins directory.
3535
# - Sets up Node.js.
3636
# - Logs debug information about the GitHub Action runner.
37-
# - Installs Core npm dependencies.
3837
# - Installs Gutenberg npm dependencies.
3938
# - Runs the Gutenberg build process.
39+
# - Installs Core npm dependencies.
4040
# - Builds WordPress to run from the relevant location (src or build).
4141
# - Builds Gutenberg.
4242
# - Ensures version-controlled files are not modified or deleted.
@@ -78,9 +78,6 @@ jobs:
7878
curl --version
7979
git --version
8080
81-
- name: Install Core Dependencies
82-
run: npm ci
83-
8481
- name: Install Gutenberg Dependencies
8582
run: npm ci
8683
working-directory: ${{ env.GUTENBERG_DIRECTORY }}
@@ -89,6 +86,9 @@ jobs:
8986
run: npm run build
9087
working-directory: ${{ env.GUTENBERG_DIRECTORY }}
9188

89+
- name: Install Core Dependencies
90+
run: npm ci
91+
9292
- name: Build WordPress to run from ${{ inputs.directory }}
9393
run: npm run ${{ inputs.directory == 'src' && 'build:dev' || 'build' }}
9494

src/js/_enqueues/admin/user-profile.js

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@
2020
$form,
2121
originalFormContent,
2222
$passwordWrapper,
23-
successTimeout;
23+
successTimeout,
24+
isMac = window.navigator.platform ? window.navigator.platform.indexOf( 'Mac' ) !== -1 : false,
25+
ua = navigator.userAgent.toLowerCase(),
26+
isSafari = window.safari !== 'undefined' && typeof window.safari === 'object',
27+
isFirefox = ua.indexOf( 'firefox' ) !== -1;
2428

2529
function generatePassword() {
2630
if ( typeof zxcvbn !== 'function' ) {
@@ -80,6 +84,8 @@
8084
$pass1.removeClass( 'short bad good strong' );
8185
showOrHideWeakPasswordCheckbox();
8286
} );
87+
88+
bindCapsLockWarning( $pass1 );
8389
}
8490

8591
function resetToggle( show ) {
@@ -213,6 +219,8 @@
213219
} else {
214220
// Password field for the login form.
215221
$pass1 = $( '#user_pass' );
222+
223+
bindCapsLockWarning( $pass1 );
216224
}
217225

218226
/*
@@ -332,6 +340,79 @@
332340
}
333341
}
334342

343+
/**
344+
* Bind Caps Lock detection to a password input field.
345+
*
346+
* @param {jQuery} $input The password input field.
347+
*/
348+
function bindCapsLockWarning( $input ) {
349+
var $capsWarning,
350+
$capsIcon,
351+
$capsText,
352+
capsLockOn = false;
353+
354+
// Skip warning on macOS Safari + Firefox (they show native indicators).
355+
if ( isMac && ( isSafari || isFirefox ) ) {
356+
return;
357+
}
358+
359+
$capsWarning = $( '<div id="caps-warning" class="caps-warning"></div>' );
360+
$capsIcon = $( '<span class="caps-icon" aria-hidden="true"><svg viewBox="0 0 24 26" xmlns="http://www.w3.org/2000/svg" fill="#3c434a" stroke="#3c434a" stroke-width="0.5"><path d="M12 5L19 15H16V19H8V15H5L12 5Z"/><rect x="8" y="21" width="8" height="1.5" rx="0.75"/></svg></span>' );
361+
$capsText = $( '<span>', { 'class': 'caps-warning-text', text: __( 'Caps lock is on.' ) } );
362+
$capsWarning.append( $capsIcon, $capsText );
363+
364+
$input.parent( 'div' ).append( $capsWarning );
365+
366+
$input.on( 'keydown', function( jqEvent ) {
367+
var event = jqEvent.originalEvent;
368+
369+
// Skip if key is not a printable character.
370+
// Key length > 1 usually means non-printable (e.g., "Enter", "Tab").
371+
if ( event.ctrlKey || event.metaKey || event.altKey || ! event.key || event.key.length !== 1 ) {
372+
return;
373+
}
374+
375+
var state = isCapsLockOn( event );
376+
377+
// React when the state changes or if caps lock is on when the user starts typing.
378+
if ( state !== capsLockOn ) {
379+
capsLockOn = state;
380+
381+
if ( capsLockOn ) {
382+
$capsWarning.show();
383+
// Don't duplicate existing screen reader Caps lock notifications.
384+
if ( event.key !== 'CapsLock' ) {
385+
wp.a11y.speak( __( 'Caps lock is on.' ), 'assertive' );
386+
}
387+
} else {
388+
$capsWarning.hide();
389+
}
390+
}
391+
} );
392+
393+
$input.on( 'blur', function() {
394+
if ( ! document.hasFocus() ) {
395+
return;
396+
}
397+
capsLockOn = false;
398+
$capsWarning.hide();
399+
} );
400+
}
401+
402+
/**
403+
* Determines if Caps Lock is currently enabled.
404+
*
405+
* On macOS Safari and Firefox, the native warning is preferred,
406+
* so this function returns false to suppress custom warnings.
407+
*
408+
* @param {KeyboardEvent} e The keydown event object.
409+
*
410+
* @return {boolean} True if Caps Lock is on, false otherwise.
411+
*/
412+
function isCapsLockOn( event ) {
413+
return event.getModifierState( 'CapsLock' );
414+
}
415+
335416
function showOrHideWeakPasswordCheckbox() {
336417
var passStrengthResult = $('#pass-strength-result');
337418

src/js/_enqueues/lib/nav-menu.js

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,14 +1406,25 @@
14061406

14071407
updateQuickSearchResults : function(input) {
14081408
var panel, params,
1409-
minSearchLength = 2,
1410-
q = input.val();
1409+
minSearchLength = 1,
1410+
q = input.val(),
1411+
pageSearchChecklist = $( '#page-search-checklist' );
14111412

14121413
/*
1413-
* Minimum characters for a search. Also avoid a new Ajax search when
1414-
* the pressed key (e.g. arrows) doesn't change the searched term.
1414+
* Avoid a new Ajax search when the pressed key (e.g. arrows)
1415+
* doesn't change the searched term.
14151416
*/
1416-
if ( q.length < minSearchLength || api.lastSearch == q ) {
1417+
if ( api.lastSearch == q ) {
1418+
return;
1419+
}
1420+
1421+
/*
1422+
* Reset results when search is less than or equal to
1423+
* minimum characters for searched term.
1424+
*/
1425+
if ( q.length <= minSearchLength ) {
1426+
pageSearchChecklist.empty();
1427+
wp.a11y.speak( wp.i18n.__( 'Search results cleared' ) );
14171428
return;
14181429
}
14191430

@@ -1770,12 +1781,14 @@
17701781
$item;
17711782

17721783
if( ! $items.length ) {
1784+
let noResults = wp.i18n.__( 'No results found.' );
17731785
const li = $( '<li>' );
1774-
const p = $( '<p>', { text: wp.i18n.__( 'No results found.' ) } );
1786+
const p = $( '<p>', { text: noResults } );
17751787
li.append( p );
17761788
$('.categorychecklist', panel).empty().append( li );
17771789
$( '.spinner', panel ).removeClass( 'is-active' );
17781790
wrapper.addClass( 'has-no-menu-item' );
1791+
wp.a11y.speak( noResults, 'assertive' );
17791792
return;
17801793
}
17811794

@@ -1802,6 +1815,7 @@
18021815
});
18031816

18041817
$('.categorychecklist', panel).html( $items );
1818+
wp.a11y.speak( wp.i18n.sprintf( wp.i18n.__( '%d Search Results Found' ), $items.length ), 'assertive' );
18051819
$( '.spinner', panel ).removeClass( 'is-active' );
18061820
wrapper.removeClass( 'has-no-menu-item' );
18071821

src/wp-admin/css/forms.css

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,37 @@ fieldset label,
713713
display: inline-block;
714714
}
715715

716+
/* Caps lock warning */
717+
.wp-pwd .caps-warning {
718+
display: none;
719+
position: relative;
720+
background: #fcf9e8;
721+
border: 1px solid #f0c33c;
722+
color: #1d2327;
723+
padding: 6px 10px;
724+
top: -8px;
725+
}
726+
727+
.profile-php .wp-pwd .caps-warning {
728+
padding: 3px 5px;
729+
top: -4px;
730+
border-radius: 4px;
731+
}
732+
733+
.wp-pwd .caps-icon {
734+
display: inline-flex;
735+
justify-content: center;
736+
width: 20px;
737+
height: 20px;
738+
margin-right: 5px;
739+
vertical-align: middle;
740+
}
741+
742+
.wp-pwd .caps-warning-text {
743+
vertical-align: middle;
744+
}
745+
/* Caps lock warning */
746+
716747
p.search-box {
717748
display: flex;
718749
flex-wrap: wrap;
@@ -1640,6 +1671,10 @@ table.form-table td .updated p {
16401671
padding: 8px;
16411672
}
16421673

1674+
.profile-php .wp-pwd .caps-warning {
1675+
padding: 8px;
1676+
}
1677+
16431678
.password-input-wrapper {
16441679
display: block;
16451680
}

src/wp-admin/includes/admin-filters.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,6 @@
172172
// Font management.
173173
add_action( 'admin_print_styles', 'wp_print_font_faces', 50 );
174174
add_action( 'admin_print_styles', 'wp_print_font_faces_from_style_variations', 50 );
175+
176+
// Load Press This.
177+
add_action( 'press_this_init', 'wp_load_press_this' );

src/wp-admin/includes/class-plugin-upgrader.php

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ public function upgrade( $plugin, $args = array() ) {
206206
}
207207

208208
// Get the URL to the zip file.
209-
$r = $current->response[ $plugin ];
209+
$upgrade_data = $current->response[ $plugin ];
210210

211211
add_filter( 'upgrader_pre_install', array( $this, 'deactivate_plugin_before_upgrade' ), 10, 2 );
212212
add_filter( 'upgrader_pre_install', array( $this, 'active_before' ), 10, 2 );
@@ -223,7 +223,7 @@ public function upgrade( $plugin, $args = array() ) {
223223

224224
$this->run(
225225
array(
226-
'package' => $r->package,
226+
'package' => $upgrade_data->package,
227227
'destination' => WP_PLUGIN_DIR,
228228
'clear_destination' => true,
229229
'clear_working' => true,
@@ -301,8 +301,8 @@ public function bulk_upgrade( $plugins, $args = array() ) {
301301
$this->skin->header();
302302

303303
// Connect to the filesystem first.
304-
$res = $this->fs_connect( array( WP_CONTENT_DIR, WP_PLUGIN_DIR ) );
305-
if ( ! $res ) {
304+
$connected = $this->fs_connect( array( WP_CONTENT_DIR, WP_PLUGIN_DIR ) );
305+
if ( ! $connected ) {
306306
$this->skin->footer();
307307
return false;
308308
}
@@ -341,32 +341,32 @@ public function bulk_upgrade( $plugins, $args = array() ) {
341341
}
342342

343343
// Get the URL to the zip file.
344-
$r = $current->response[ $plugin ];
344+
$upgrade_data = $current->response[ $plugin ];
345345

346346
$this->skin->plugin_active = is_plugin_active( $plugin );
347347

348-
if ( isset( $r->requires ) && ! is_wp_version_compatible( $r->requires ) ) {
348+
if ( isset( $upgrade_data->requires ) && ! is_wp_version_compatible( $upgrade_data->requires ) ) {
349349
$result = new WP_Error(
350350
'incompatible_wp_required_version',
351351
sprintf(
352352
/* translators: 1: Current WordPress version, 2: WordPress version required by the new plugin version. */
353353
__( 'Your WordPress version is %1$s, however the new plugin version requires %2$s.' ),
354354
$wp_version,
355-
$r->requires
355+
$upgrade_data->requires
356356
)
357357
);
358358

359359
$this->skin->before( $result );
360360
$this->skin->error( $result );
361361
$this->skin->after();
362-
} elseif ( isset( $r->requires_php ) && ! is_php_version_compatible( $r->requires_php ) ) {
362+
} elseif ( isset( $upgrade_data->requires_php ) && ! is_php_version_compatible( $upgrade_data->requires_php ) ) {
363363
$result = new WP_Error(
364364
'incompatible_php_required_version',
365365
sprintf(
366366
/* translators: 1: Current PHP version, 2: PHP version required by the new plugin version. */
367367
__( 'The PHP version on your server is %1$s, however the new plugin version requires %2$s.' ),
368368
PHP_VERSION,
369-
$r->requires_php
369+
$upgrade_data->requires_php
370370
)
371371
);
372372

@@ -377,7 +377,7 @@ public function bulk_upgrade( $plugins, $args = array() ) {
377377
add_filter( 'upgrader_source_selection', array( $this, 'check_package' ) );
378378
$result = $this->run(
379379
array(
380-
'package' => $r->package,
380+
'package' => $upgrade_data->package,
381381
'destination' => WP_PLUGIN_DIR,
382382
'clear_destination' => true,
383383
'clear_working' => true,
@@ -478,9 +478,9 @@ public function check_package( $source ) {
478478
$files = glob( $working_directory . '*.php' );
479479
if ( $files ) {
480480
foreach ( $files as $file ) {
481-
$info = get_plugin_data( $file, false, false );
482-
if ( ! empty( $info['Name'] ) ) {
483-
$this->new_plugin_data = $info;
481+
$new_plugin_data = get_plugin_data( $file, false, false );
482+
if ( ! empty( $new_plugin_data['Name'] ) ) {
483+
$this->new_plugin_data = $new_plugin_data;
484484
break;
485485
}
486486
}
@@ -490,8 +490,8 @@ public function check_package( $source ) {
490490
return new WP_Error( 'incompatible_archive_no_plugins', $this->strings['incompatible_archive'], __( 'No valid plugins were found.' ) );
491491
}
492492

493-
$requires_php = isset( $info['RequiresPHP'] ) ? $info['RequiresPHP'] : null;
494-
$requires_wp = isset( $info['RequiresWP'] ) ? $info['RequiresWP'] : null;
493+
$requires_php = isset( $new_plugin_data['RequiresPHP'] ) ? $new_plugin_data['RequiresPHP'] : null;
494+
$requires_wp = isset( $new_plugin_data['RequiresWP'] ) ? $new_plugin_data['RequiresWP'] : null;
495495

496496
if ( ! is_php_version_compatible( $requires_php ) ) {
497497
$error = sprintf(
@@ -542,9 +542,9 @@ public function plugin_info() {
542542
}
543543

544544
// Assume the requested plugin is the first in the list.
545-
$pluginfiles = array_keys( $plugin );
545+
$plugin_files = array_keys( $plugin );
546546

547-
return $this->result['destination_name'] . '/' . $pluginfiles[0];
547+
return $this->result['destination_name'] . '/' . $plugin_files[0];
548548
}
549549

550550
/**

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ public function prepare_items() {
151151
'order' => $order,
152152
'post_type' => $post_type,
153153
'update_comment_post_cache' => true,
154+
'type__not_in' => array( 'note' ),
154155
);
155156

156157
/**

src/wp-admin/includes/comment.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ function get_pending_comments_num( $post_id ) {
157157
$post_id_array = array_map( 'intval', $post_id_array );
158158
$post_id_in = "'" . implode( "', '", $post_id_array ) . "'";
159159

160-
$pending = $wpdb->get_results( "SELECT comment_post_ID, COUNT(comment_ID) as num_comments FROM $wpdb->comments WHERE comment_post_ID IN ( $post_id_in ) AND comment_approved = '0' GROUP BY comment_post_ID", ARRAY_A );
160+
$pending = $wpdb->get_results( "SELECT comment_post_ID, COUNT(comment_ID) as num_comments FROM $wpdb->comments WHERE comment_post_ID IN ( $post_id_in ) AND comment_approved = '0' AND comment_type != 'note' GROUP BY comment_post_ID", ARRAY_A );
161161

162162
if ( $single ) {
163163
if ( empty( $pending ) ) {

0 commit comments

Comments
 (0)