diff --git a/src/js/_enqueues/wp/updates.js b/src/js/_enqueues/wp/updates.js index dc342f281d..0743ac3780 100644 --- a/src/js/_enqueues/wp/updates.js +++ b/src/js/_enqueues/wp/updates.js @@ -2677,44 +2677,63 @@ $( window ).on( 'beforeunload', wp.updates.beforeunload ); /** - * Click handler for enabling and disabling plugin and theme auto-updates. + * Prevents the page form scrolling when activating auto-updates with the Spacebar key. * * @since 5.5.0 */ - $document.on( 'click', '.column-auto-updates a.toggle-auto-update, .theme-overlay a.toggle-auto-update', function( event ) { - var data, asset, type, $parent; - var $anchor = $( this ), - action = $anchor.attr( 'data-wp-action' ), - $label = $anchor.find( '.label' ); + $document.on( 'keydown', '.column-auto-updates .toggle-auto-update, .theme-overlay .toggle-auto-update', function( event ) { + if ( 32 === event.which ) { + event.preventDefault(); + } + } ); + + /** + * Click and keyup handler for enabling and disabling plugin and theme auto-updates. + * + * These controls can be either links or buttons. When JavaScript is enabled, + * we want them to behave like buttons. An ARIA role `button` is added via + * the JavaScript that targets elements with the CSS class `aria-button-if-js`. + * + * @since 5.5.0 + */ + $document.on( 'click keyup', '.column-auto-updates .toggle-auto-update, .theme-overlay .toggle-auto-update', function( event ) { + var data, asset, type, $parent, + $toggler = $( this ), + action = $toggler.attr( 'data-wp-action' ), + $label = $toggler.find( '.label' ); + + if ( 'keyup' === event.type && 32 !== event.which ) { + return; + } if ( 'themes' !== pagenow ) { - $parent = $anchor.closest( '.column-auto-updates' ); + $parent = $toggler.closest( '.column-auto-updates' ); } else { - $parent = $anchor.closest( '.theme-autoupdate' ); + $parent = $toggler.closest( '.theme-autoupdate' ); } event.preventDefault(); // Prevent multiple simultaneous requests. - if ( $anchor.attr( 'data-doing-ajax' ) === 'yes' ) { + if ( $toggler.attr( 'data-doing-ajax' ) === 'yes' ) { return; } - $anchor.attr( 'data-doing-ajax', 'yes' ); + $toggler.attr( 'data-doing-ajax', 'yes' ); switch ( pagenow ) { case 'plugins': case 'plugins-network': type = 'plugin'; - asset = $anchor.closest( 'tr' ).attr( 'data-plugin' ); + asset = $toggler.closest( 'tr' ).attr( 'data-plugin' ); break; case 'themes-network': type = 'theme'; - asset = $anchor.closest( 'tr' ).attr( 'data-slug' ); + asset = $toggler.closest( 'tr' ).attr( 'data-slug' ); break; case 'themes': type = 'theme'; - asset = $anchor.attr( 'data-slug' ); + asset = $toggler.attr( 'data-slug' ); break; } @@ -2728,7 +2747,7 @@ $label.text( __( 'Disabling...' ) ); } - $anchor.find( '.dashicons-update' ).removeClass( 'hidden' ); + $toggler.find( '.dashicons-update' ).removeClass( 'hidden' ); data = { action: 'toggle-auto-updates', @@ -2740,8 +2759,8 @@ $.post( window.ajaxurl, data ) .done( function( response ) { - var $enabled, $disabled, enabledNumber, disabledNumber, errorMessage; - var href = $anchor.attr( 'href' ); + var $enabled, $disabled, enabledNumber, disabledNumber, errorMessage, + href = $toggler.attr( 'href' ); if ( ! response.success ) { // if WP returns 0 for response (which can happen in a few cases), @@ -2784,25 +2803,27 @@ } if ( 'enable' === action ) { - href = href.replace( 'action=enable-auto-update', 'action=disable-auto-update' ); - $anchor.attr( { - 'data-wp-action': 'disable', - href: href - } ); + // The toggler control can be either a link or a button. + if ( $toggler[ 0 ].hasAttribute( 'href' ) ) { + href = href.replace( 'action=enable-auto-update', 'action=disable-auto-update' ); + $toggler.attr( 'href', href ); + } + $toggler.attr( 'data-wp-action', 'disable' ); $label.text( __( 'Disable auto-updates' ) ); $parent.find( '.auto-update-time' ).removeClass( 'hidden' ); - wp.a11y.speak( __( 'Enable auto-updates' ), 'polite' ); + wp.a11y.speak( __( 'Auto-updates enabled' ) ); } else { - href = href.replace( 'action=disable-auto-update', 'action=enable-auto-update' ); - $anchor.attr( { - 'data-wp-action': 'enable', - href: href - } ); + // The toggler control can be either a link or a button. + if ( $toggler[ 0 ].hasAttribute( 'href' ) ) { + href = href.replace( 'action=disable-auto-update', 'action=enable-auto-update' ); + $toggler.attr( 'href', href ); + } + $toggler.attr( 'data-wp-action', 'enable' ); $label.text( __( 'Enable auto-updates' ) ); $parent.find( '.auto-update-time' ).addClass( 'hidden' ); - wp.a11y.speak( __( 'Auto-updates disabled' ), 'polite' ); + wp.a11y.speak( __( 'Auto-updates disabled' ) ); } $document.trigger( 'wp-auto-update-setting-changed', { state: action, type: type, asset: asset } ); @@ -2816,7 +2837,7 @@ wp.a11y.speak( __( 'The request could not be completed.' ), 'polite' ); } ) .always( function() { - $anchor.removeAttr( 'data-doing-ajax' ).find( '.dashicons-update' ).addClass( 'hidden' ); + $toggler.removeAttr( 'data-doing-ajax' ).find( '.dashicons-update' ).addClass( 'hidden' ); } ); } ); diff --git a/src/wp-admin/css/common.css b/src/wp-admin/css/common.css index 78e7c9b071..7064e2c70e 100644 --- a/src/wp-admin/css/common.css +++ b/src/wp-admin/css/common.css @@ -1499,6 +1499,10 @@ div.error { animation: rotation 2s infinite linear; } +.theme-overlay .theme-autoupdate .dashicons-update.spin { + margin-right: 3px; +} + /* Updated icon (check mark). */ .updated-message p:before, .installed p:before, diff --git a/src/wp-admin/css/themes.css b/src/wp-admin/css/themes.css index 6136155021..ee7d21b765 100644 --- a/src/wp-admin/css/themes.css +++ b/src/wp-admin/css/themes.css @@ -684,6 +684,15 @@ body.folded .theme-browser ~ .theme-overlay .theme-wrap { text-decoration: none; } +.theme-overlay .toggle-auto-update { + /* Better align spin icon and text. */ + display: inline-flex; + align-items: center; + /* Prevents content after the auto-update toggler from jumping down and up. */ + min-height: 20px; /* Same height as the spinning dashicon. */ + vertical-align: top; +} + .theme-overlay .theme-description { color: #555; font-size: 15px; diff --git a/src/wp-admin/includes/class-wp-ms-themes-list-table.php b/src/wp-admin/includes/class-wp-ms-themes-list-table.php index 2a7dab15a7..83e75f49c3 100644 --- a/src/wp-admin/includes/class-wp-ms-themes-list-table.php +++ b/src/wp-admin/includes/class-wp-ms-themes-list-table.php @@ -744,7 +744,7 @@ class WP_MS_Themes_List_Table extends WP_List_Table { $url = add_query_arg( $query_args, 'themes.php' ); $html[] = sprintf( - '', + '', wp_nonce_url( $url, 'updates' ), $action ); diff --git a/src/wp-admin/includes/class-wp-plugins-list-table.php b/src/wp-admin/includes/class-wp-plugins-list-table.php index dce95dd773..9e5881976c 100644 --- a/src/wp-admin/includes/class-wp-plugins-list-table.php +++ b/src/wp-admin/includes/class-wp-plugins-list-table.php @@ -1076,7 +1076,7 @@ class WP_Plugins_List_Table extends WP_List_Table { $url = add_query_arg( $query_args, 'plugins.php' ); $html[] = sprintf( - '', + '', wp_nonce_url( $url, 'updates' ), $action ); diff --git a/src/wp-admin/themes.php b/src/wp-admin/themes.php index 086b4e3def..2dfa4eb3f5 100644 --- a/src/wp-admin/themes.php +++ b/src/wp-admin/themes.php @@ -562,14 +562,12 @@ function wp_theme_auto_update_setting_template() { $template = ' <# if ( data.autoupdate ) { #> - - - ' . __( 'Disable auto-updates' ) . ' - + + ' . __( 'Disable auto-updates' ) . ' + <# } else { #> - - - ' . __( 'Enable auto-updates' ) . ' + + ' . __( 'Enable auto-updates' ) . ' <# } #> <# if ( data.hasUpdate ) { #>