From 748d595b5c042bb454427ff8299b880674819994 Mon Sep 17 00:00:00 2001 From: Gary Pendergast Date: Thu, 5 Feb 2015 04:18:57 +0000 Subject: [PATCH] Shiny Updates: Add ajax-y updates to the plugin list page, and ajax-y updates and installs to the plugin card page. This also includes JS architecture that can be expanded to support theme, core and language pack updates. Props pento, ericlewis, lgladdy, adamsilverstein, DrewAPicture See #29820 git-svn-id: https://develop.svn.wordpress.org/trunk@31333 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/admin-ajax.php | 2 +- src/wp-admin/css/list-tables.css | 48 ++- src/wp-admin/includes/ajax-actions.php | 78 ++++ .../class-wp-plugin-install-list-table.php | 6 +- src/wp-admin/includes/plugin-install.php | 5 +- src/wp-admin/includes/update.php | 5 +- src/wp-admin/js/plugin-install.js | 4 - src/wp-admin/js/updates.js | 353 +++++++++++++++++- src/wp-admin/plugin-install.php | 2 + src/wp-admin/plugins.php | 4 +- src/wp-includes/script-loader.php | 12 + 11 files changed, 488 insertions(+), 31 deletions(-) diff --git a/src/wp-admin/admin-ajax.php b/src/wp-admin/admin-ajax.php index a3571afb58..d50aa42003 100644 --- a/src/wp-admin/admin-ajax.php +++ b/src/wp-admin/admin-ajax.php @@ -61,7 +61,7 @@ $core_actions_post = array( 'query-attachments', 'save-attachment', 'save-attachment-compat', 'send-link-to-editor', 'send-attachment-to-editor', 'save-attachment-order', 'heartbeat', 'get-revision-diffs', 'save-user-color-scheme', 'update-widget', 'query-themes', 'parse-embed', 'set-attachment-thumbnail', - 'parse-media-shortcode', 'destroy-sessions' + 'parse-media-shortcode', 'destroy-sessions', 'install-plugin', 'update-plugin' ); // Register core Ajax calls. diff --git a/src/wp-admin/css/list-tables.css b/src/wp-admin/css/list-tables.css index a7f067fb07..f461635fd7 100644 --- a/src/wp-admin/css/list-tables.css +++ b/src/wp-admin/css/list-tables.css @@ -1143,7 +1143,11 @@ ul.cat-checklist { .upgrade .plugins tr:last-of-type td, .upgrade .plugins tr:last-of-type th, .plugins tr.active + tr.inactive.update th, -.plugins tr.active + tr.inactive.update td { +.plugins tr.active + tr.inactive.update td, +.plugins .updated td, +.plugins .updated th, +.plugins tr.active + tr.inactive.updated th, +.plugins tr.active + tr.inactive.updated td { -webkit-box-shadow: none; box-shadow: none; } @@ -1154,7 +1158,8 @@ tr.active.update + tr.plugin-update-tr .plugin-update { background-color: #fef7f1; } -.plugins .active th.check-column { +.plugins .active th.check-column, +.plugin-update-tr.active td { border-left: 4px solid #2ea2cc; } @@ -1199,18 +1204,49 @@ tr.active.update + tr.plugin-update-tr .plugin-update { background-color: rgba(0,0,0,0.03); } -.plugin-update-tr .update-message:before { +.plugin-update-tr .update-message:before, +.plugin-card .update-now:before, +.plugin-card .install-now:before { color: #d54e21; - content: '\f463'; display: inline-block; font: normal 20px/1 'dashicons'; speak: none; - margin: 0 8px 0 -2px; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; vertical-align: top; } +.plugin-update-tr .update-message:before, +.plugin-card .update-now:before { + content: '\f463'; +} + +.plugin-update-tr .update-message:before { + margin: 0 8px 0 -2px; +} + +.plugin-card .update-now:before, +.plugin-card .install-now:before { + margin: 3px 5px 0 -2px; +} + +.plugin-update-tr .updating-message:before, +.plugin-card .updating-message:before { + content: '\f463'; + -webkit-animation: rotation 2s infinite linear; +} + +@-webkit-keyframes rotation { + from {-webkit-transform: rotate(0deg);} + to {-webkit-transform: rotate(359deg);} +} + +.plugin-update-tr .updated-message:before, +.plugin-card .updated-message:before { + color: #79ba49; + content: '\f147'; +} + .plugins .plugin-update { padding: 0; border: none; @@ -1223,7 +1259,7 @@ tr.active + tr.plugin-update-tr .plugin-update { background-color: #f7fcfe; } -tr.active + tr.plugin-update-tr .plugin-update .update-message { +tr.active + tr.plugin-update-tr:not(.updated) .plugin-update .update-message { background-color: #fcf3ef; } diff --git a/src/wp-admin/includes/ajax-actions.php b/src/wp-admin/includes/ajax-actions.php index 23cb62fae3..b75033c5d6 100644 --- a/src/wp-admin/includes/ajax-actions.php +++ b/src/wp-admin/includes/ajax-actions.php @@ -2828,3 +2828,81 @@ function wp_ajax_destroy_sessions() { wp_send_json_success( array( 'message' => $message ) ); } + +/** + * AJAX handler for installing a plugin. + * + * @since 4.2.0 + */ +function wp_ajax_install_plugin() { + check_ajax_referer( 'updates' ); + + include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' ); + include_once( ABSPATH . 'wp-admin/includes/plugin-install.php' ); + + $status = array( + 'install' => 'plugin', + 'slug' => sanitize_key( $_POST['slug'] ), + ); + + $api = plugins_api( 'plugin_information', array( + 'slug' => sanitize_key( $_POST['slug'] ), + 'fields' => array( 'sections' => false ) + ) ); + + if ( is_wp_error( $api ) ) { + $status['error'] = $api->get_error_message(); + wp_send_json_error( $status ); + } + + $upgrader = new Plugin_Upgrader( new Automatic_Upgrader_Skin() ); + $result = $upgrader->install( $api->download_link ); + + if ( is_wp_error( $result ) ) { + $status['error'] = $result->get_error_message(); + wp_send_json_error( $status ); + } + + $plugin_status = install_plugin_install_status( array( 'slug' => sanitize_key( $_POST['slug'] ) ) ); + activate_plugin( $plugin_status['file'] ); + + wp_send_json_success( $status ); +} + +/** + * AJAX handler for updating a plugin. + * + * @since 4.2.0 + */ +function wp_ajax_update_plugin() { + check_ajax_referer( 'updates' ); + + include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' ); + + $plugin = urldecode( $_POST['plugin'] ); + + $status = array( + 'update' => 'plugin', + 'plugin' => $plugin, + 'slug' => sanitize_key( $_POST['slug'] ), + ); + + $current = get_site_transient( 'update_plugins' ); + if ( empty( $current ) ) { + wp_update_plugins(); + } + + $upgrader = new Plugin_Upgrader( new Automatic_Upgrader_Skin() ); + $result = $upgrader->bulk_upgrade( array( $plugin ) ); + + if ( is_array( $result ) ) { + $result = $result[ $plugin ]; + } + + if ( is_wp_error( $result ) ) { + $status['error'] = $result->get_error_message(); + wp_send_json_error( $status ); + } + + wp_send_json_success( $status ); +} diff --git a/src/wp-admin/includes/class-wp-plugin-install-list-table.php b/src/wp-admin/includes/class-wp-plugin-install-list-table.php index b523d48c43..c2040bc504 100644 --- a/src/wp-admin/includes/class-wp-plugin-install-list-table.php +++ b/src/wp-admin/includes/class-wp-plugin-install-list-table.php @@ -402,14 +402,14 @@ class WP_Plugin_Install_List_Table extends WP_List_Table { case 'install': if ( $status['url'] ) { /* translators: 1: Plugin name and version. */ - $action_links[] = '' . __( 'Install Now' ) . ''; + $action_links[] = '' . __( 'Install Now' ) . ''; } break; case 'update_available': if ( $status['url'] ) { /* translators: 1: Plugin name and version */ - $action_links[] = '' . __( 'Update Now' ) . ''; + $action_links[] = '' . __( 'Update Now' ) . ''; } break; @@ -449,7 +449,7 @@ class WP_Plugin_Install_List_Table extends WP_List_Table { $date_format = __( 'M j, Y @ G:i' ); $last_updated_timestamp = strtotime( $plugin['last_updated'] ); ?> -
+
diff --git a/src/wp-admin/includes/plugin-install.php b/src/wp-admin/includes/plugin-install.php index 5cb74413ae..f9b487add1 100644 --- a/src/wp-admin/includes/plugin-install.php +++ b/src/wp-admin/includes/plugin-install.php @@ -276,6 +276,7 @@ function install_plugin_install_status($api, $loop = false) { // Default to a "new" plugin $status = 'install'; $url = false; + $update_file = false; /* * Check to see if this plugin is known to be installed, @@ -304,6 +305,7 @@ function install_plugin_install_status($api, $loop = false) { } else { $key = array_keys( $installed_plugin ); $key = array_shift( $key ); //Use the first plugin regardless of the name, Could have issues for multiple-plugins in one directory if they share different version numbers + $update_file = $api->slug . '/' . $key; if ( version_compare($api->version, $installed_plugin[ $key ]['Version'], '=') ){ $status = 'latest_installed'; } elseif ( version_compare($api->version, $installed_plugin[ $key ]['Version'], '<') ) { @@ -327,7 +329,8 @@ function install_plugin_install_status($api, $loop = false) { if ( isset($_GET['from']) ) $url .= '&from=' . urlencode( wp_unslash( $_GET['from'] ) ); - return compact('status', 'url', 'version'); + $file = $update_file; + return compact( 'status', 'url', 'version', 'file' ); } /** diff --git a/src/wp-admin/includes/update.php b/src/wp-admin/includes/update.php index 5639459547..b78fbfeaba 100644 --- a/src/wp-admin/includes/update.php +++ b/src/wp-admin/includes/update.php @@ -276,14 +276,15 @@ function wp_plugin_update_row( $file, $plugin_data ) { $wp_list_table = _get_list_table('WP_Plugins_List_Table'); if ( is_network_admin() || !is_multisite() ) { - echo '
'; + $active_class = ( is_plugin_active( $plugin_data['plugin'] ) ) ? ' active' : ''; + echo '
'; if ( ! current_user_can( 'update_plugins' ) ) { printf( __('There is a new version of %1$s available. View version %4$s details.'), $plugin_name, esc_url($details_url), esc_attr($plugin_name), $r->new_version ); } elseif ( empty($r->package) ) { printf( __('There is a new version of %1$s available. View version %4$s details. Automatic update is unavailable for this plugin.'), $plugin_name, esc_url($details_url), esc_attr($plugin_name), $r->new_version ); } else { - printf( __('There is a new version of %1$s available. View version %4$s details or update now.'), $plugin_name, esc_url($details_url), esc_attr($plugin_name), $r->new_version, wp_nonce_url( self_admin_url('update.php?action=upgrade-plugin&plugin=') . $file, 'upgrade-plugin_' . $file) ); + printf( __( 'There is a new version of %1$s available. View version %4$s details or update now.' ), $plugin_name, esc_url( $details_url ), esc_attr( $plugin_name ), $r->new_version, wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $file, 'upgrade-plugin_' . $file ) ); } /** * Fires at the end of the update message container in each diff --git a/src/wp-admin/js/plugin-install.js b/src/wp-admin/js/plugin-install.js index 7403769e8b..36a6bdc57d 100644 --- a/src/wp-admin/js/plugin-install.js +++ b/src/wp-admin/js/plugin-install.js @@ -69,8 +69,4 @@ jQuery( document ).ready( function( $ ) { $( '#section-holder div.section' ).hide(); // Hide 'em all. $( '#section-' + tab ).show(); }); - - $( 'a.install-now' ).click( function() { - return confirm( plugininstallL10n.ays ); - }); }); diff --git a/src/wp-admin/js/updates.js b/src/wp-admin/js/updates.js index b03e4ba8f0..025d977ece 100644 --- a/src/wp-admin/js/updates.js +++ b/src/wp-admin/js/updates.js @@ -5,43 +5,370 @@ window.wp = window.wp || {}; wp.updates = {}; /** - * Decrement update counts throughout the various menus + * User nonce for ajax calls. + * + * @since 4.2.0 + * + * @var string + */ + wp.updates.ajaxNonce = window._wpUpdatesSettings.ajax_nonce; + + /** + * Localized strings. + * + * @since 4.2.0 + * + * @var object + */ + wp.updates.l10n = window._wpUpdatesSettings.l10n; + + /** + * Flag if we're waiting for an install/update to complete. + * + * @since 4.2.0 + * + * @var bool + */ + wp.updates.updateLock = false; + + /** + * If the user tries to install/update a plugin while an install/update is + * already happening, it can be placed in this queue to perform later. + * + * @since 4.2.0 + * + * @var array + */ + wp.updates.updateQueue = []; + + /** + * Decrement update counts throughout the various menus. + * + * @since 3.9.0 * * @param {string} updateType */ wp.updates.decrementCount = function( upgradeType ) { - var count, pluginCount, $elem; + var count, + pluginCount, + $adminBarUpdateCount = $( '#wp-admin-bar-updates .ab-label' ), + $dashboardNavMenuUpdateCount = $( 'a[href="update-core.php"] .update-plugins' ) + $pluginsMenuItem = $( '#menu-plugins' ); - $elem = $( '#wp-admin-bar-updates .ab-label' ); - count = $elem.text(); + + count = $adminBarUpdateCount.text(); count = parseInt( count, 10 ) - 1; if ( count < 0 || isNaN( count ) ) { return; } $( '#wp-admin-bar-updates .ab-item' ).removeAttr( 'title' ); - $elem.text( count ); + $adminBarUpdateCount.text( count ); - $elem = $( 'a[href="update-core.php"] .update-plugins' ); - $elem.each( function( index, elem ) { + + $dashboardNavMenuUpdateCount.each( function( index, elem ) { elem.className = elem.className.replace( /count-\d+/, 'count-' + count ); } ); - $elem.removeAttr( 'title' ); - $elem.find( '.update-count' ).text( count ); + $dashboardNavMenuUpdateCount.removeAttr( 'title' ); + $dashboardNavMenuUpdateCount.find( '.update-count' ).text( count ); if ( 'plugin' === upgradeType ) { - $elem = $( '#menu-plugins' ); - pluginCount = $elem.find( '.plugin-count' ).eq(0).text(); + pluginCount = $pluginsMenuItem.find( '.plugin-count' ).eq(0).text(); pluginCount = parseInt( pluginCount, 10 ) - 1; if ( pluginCount < 0 || isNaN( pluginCount ) ) { return; } - $elem.find( '.plugin-count' ).text( pluginCount ); - $elem.find( '.update-plugins' ).each( function( index, elem ) { + $pluginsMenuItem.find( '.plugin-count' ).text( pluginCount ); + $pluginsMenuItem.find( '.update-plugins' ).each( function( index, elem ) { elem.className = elem.className.replace( /count-\d+/, 'count-' + pluginCount ); } ); + + if (pluginCount > 0 ) { + $( '.subsubsub .upgrade .count' ).text( '(' + pluginCount + ')' ); + } else { + $( '.subsubsub .upgrade' ).remove(); + } } }; + /** + * Send an Ajax request to the server to update a plugin. + * + * @since 4.2.0 + * + * @param {string} plugin + * @param {string} slug + */ + wp.updates.updatePlugin = function( plugin, slug ) { + var $message; + if ( 'plugins' === pagenow || 'plugins-network' === pagenow ) { + $message = $( '#' + slug ).next().find( '.update-message' ); + } else if ( 'plugin-install' === pagenow ) { + $message = $( '.plugin-card-' + slug ).find( '.update-now' ); + } + + $message.addClass( 'updating-message' ); + $message.text( wp.updates.l10n.updating ); + + if ( wp.updates.updateLock ) { + wp.updates.updateQueue.push( { + type: 'update-plugin', + data: { + plugin: plugin, + slug: slug + } + } ); + return; + } + + wp.updates.updateLock = true; + + var data = { + 'action': 'update-plugin', + '_ajax_nonce': wp.updates.ajaxNonce, + 'plugin': plugin, + 'slug': slug + }; + + $.ajax( { + type: 'post', + url: ajaxurl, + data: data, + complete: wp.updates.updateRequestComplete + } ); + }; + + /** + * After an update attempt has completed, deal with the response. + * + * @since 4.2.0 + * + * @param {jqXHR} jqxhr The jQuery XMLHttpRequest for the request. + */ + wp.updates.updateRequestComplete = function( jqxhr ) { + wp.updates.updateLock = false; + if ( jqxhr.responseJSON && jqxhr.responseJSON.success ) { + wp.updates.updateSuccess( jqxhr.responseJSON ); + } else { + var alertText = wp.updates.l10n.updateFailed; + if ( jqxhr.responseJSON && jqxhr.responseJSON.data && jqxhr.responseJSON.data.error ) { + alertText += ': ' + jqxhr.responseJSON.data.error; + } + alert( alertText ); + if ( jqxhr.responseJSON && jqxhr.responseJSON.data && jqxhr.responseJSON.data.slug ) { + wp.updates.updateError( jqxhr.responseJSON ); + } + } + /** + * Check the queue. + */ + wp.updates.queueChecker(); + } + + /** + * On a successful plugin update, update the UI with the result. + * + * @since 4.2.0 + * + * @param {object} response + */ + wp.updates.updateSuccess = function( response ) { + var $message; + if ( 'plugins' === pagenow || 'plugins-network' === pagenow ) { + $message = $( '#' + response.data.slug ).next().find( '.update-message' ); + $( '#' + response.data.slug ).addClass( 'updated' ).removeClass( 'update' ); + $( '#' + response.data.slug + '-update' ).addClass( 'updated' ).removeClass( 'update' ); + } else if ( 'plugin-install' === pagenow ) { + $message = $( '.plugin-card-' + response.data.slug ).find( '.update-now' ); + $message.addClass( 'button-disabled' ); + } + + $message.removeClass( 'updating-message' ).addClass( 'updated-message' ); + $message.text( wp.updates.l10n.updated ); + + wp.updates.decrementCount( 'plugin' ); + }; + + /** + * On a plugin update error, update the UI appropriately. + * + * @since 4.2.0 + * + * @param {object} response + */ + wp.updates.updateError = function( response ) { + var $message; + if ( 'plugins' === pagenow || 'plugins-network' === pagenow ) { + $message = $( '#' + response.data.slug ).next().find( '.update-message' ); + } else if ( 'plugin-install' === pagenow ) { + $message = $( '.plugin-card-' + response.data.slug ).find( '.update-now' ); + } + $message.removeClass( 'updating-message' ); + $message.text( wp.updates.l10n.updateFailed ); + }; + + /** + * Send an Ajax request to the server to install a plugin. + * + * @since 4.2.0 + * + * @param {string} slug + */ + wp.updates.installPlugin = function( slug ) { + var $message = $( '.plugin-card-' + slug ).find( '.install-now' ); + + $message.addClass( 'updating-message' ); + $message.text( wp.updates.l10n.installing ); + + if ( wp.updates.updateLock ) { + wp.updates.updateQueue.push( { + type: 'install-plugin', + data: { + slug: slug + } + } ); + return; + } + + wp.updates.updateLock = true; + + var data = { + 'action': 'install-plugin', + '_ajax_nonce': wp.updates.ajaxNonce, + 'slug': slug + }; + + $.ajax( { + type: 'post', + url: ajaxurl, + data: data, + complete: wp.updates.installRequestComplete + } ); + }; + + + /** + * After an installation attempt has completed, deal with the response. + * + * @since 4.2.0 + * + * @param {jqXHR} jqxhr The jQuery XMLHttpRequest for the request. + */ + wp.updates.installRequestComplete = function( jqxhr ) { + wp.updates.updateLock = false; + if ( jqxhr.responseJSON && jqxhr.responseJSON.success ) { + wp.updates.installSuccess( jqxhr.responseJSON ); + } else { + var alertText = wp.updates.l10n.installFailed; + if ( jqxhr.responseJSON && jqxhr.responseJSON.data && jqxhr.responseJSON.data.error ) { + alertText += ': ' + jqxhr.responseJSON.data.error; + } + alert( alertText ); + if ( jqxhr.responseJSON && jqxhr.responseJSON.data && jqxhr.responseJSON.data.slug ) { + wp.updates.installError( jqxhr.responseJSON ); + } + } + /** + * Check the queue. + */ + wp.updates.queueChecker(); + }; + + /** + * On plugin install success, update the UI with the result. + * + * @since 4.2.0 + * + * @param {object} response + */ + wp.updates.installSuccess = function( response ) { + var $message = $( '.plugin-card-' + response.data.slug ).find( '.install-now' ); + + $message.removeClass( 'updating-message' ).addClass( 'updated-message button-disabled' ); + $message.text( wp.updates.l10n.installed ); + }; + + /** + * On plugin install failure, update the UI appropriately. + * + * @since 4.2.0 + * + * @param {object} response + */ + wp.updates.installError = function( response ) { + var $message = $( '.plugin-card-' + response.data.slug ).find( '.install-now' ); + + $message.removeClass( 'updating-message' ); + $message.text( wp.updates.l10n.installNow ); + }; + + + /** + * If an install/update job has been placed in the queue, queueChecker pulls it out and runs it. + * + * @since 4.2.0 + */ + wp.updates.queueChecker = function() { + if ( wp.updates.updateLock || wp.updates.updateQueue.length <= 0 ) { + return; + } + + var job = wp.updates.updateQueue.shift(); + + switch ( job.type ) { + case 'update-plugin': + wp.updates.updatePlugin( job.data.plugin, job.data.slug ); + break; + case 'install-plugin': + wp.updates.installPlugin( job.data.slug ); + break; + default: + console.log( 'Failed to exect queued update job.' ); + console.log( job ); + break; + } + }; + + $( document ).ready( function() { + $( '.plugin-update-tr .update-link' ).on( 'click', function( e ) { + e.preventDefault(); + var $row = $( e.target ).parents( '.plugin-update-tr' ); + wp.updates.updatePlugin( $row.data( 'plugin' ), $row.data( 'slug' ) ); + } ); + + $( '#bulk-action-form' ).on( 'submit', function( e ) { + var checkbox, plugin, slug; + + if ( $( '#bulk-action-selector-top' ).val() == 'update-selected' ) { + e.preventDefault(); + + $( 'input[name="checked[]"]:checked' ).each( function( index, elem ) { + $checkbox = $( elem ); + plugin = $checkbox.val(); + slug = $checkbox.parents( 'tr' ).prop( 'id' ); + + wp.updates.updatePlugin( plugin, slug ); + + $checkbox.attr( 'checked', false ); + } ); + } + } ); + + $( '.plugin-card .update-now' ).on( 'click', function( e ) { + e.preventDefault(); + $button = $( e.target ); + wp.updates.updatePlugin( $button.data( 'plugin' ), $button.data( 'slug' ) ); + } ); + + $( '.plugin-card .install-now' ).on( 'click', function( e ) { + e.preventDefault(); + $button = $( e.target ); + if ( $button.hasClass( 'button-disabled' ) ) { + return; + } + wp.updates.installPlugin( $button.data( 'slug' ) ); + } ); + } ); + $( window ).on( 'message', function( e ) { var event = e.originalEvent, message, diff --git a/src/wp-admin/plugin-install.php b/src/wp-admin/plugin-install.php index e2431eb9b5..03085c7813 100644 --- a/src/wp-admin/plugin-install.php +++ b/src/wp-admin/plugin-install.php @@ -54,6 +54,8 @@ if ( 'plugin-information' != $tab ) $body_id = $tab; +wp_enqueue_script( 'updates' ); + /** * Fires before each tab on the Install Plugins screen is loaded. * diff --git a/src/wp-admin/plugins.php b/src/wp-admin/plugins.php index 29bca4ab7e..629fdbff53 100644 --- a/src/wp-admin/plugins.php +++ b/src/wp-admin/plugins.php @@ -23,6 +23,8 @@ $s = isset($_REQUEST['s']) ? urlencode($_REQUEST['s']) : ''; // Clean up request URI from temporary args for screen options/paging uri's to work as expected. $_SERVER['REQUEST_URI'] = remove_query_arg(array('error', 'deleted', 'activate', 'activate-multi', 'deactivate', 'deactivate-multi', '_error_nonce'), $_SERVER['REQUEST_URI']); +wp_enqueue_script( 'updates' ); + if ( $action ) { switch ( $action ) { @@ -460,7 +462,7 @@ do_action( 'pre_current_active_plugins', $plugins['all'] ); search_box( __( 'Search Installed Plugins' ), 'plugin' ); ?> -
+ diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php index 23c89051bb..8f32fbce7d 100644 --- a/src/wp-includes/script-loader.php +++ b/src/wp-includes/script-loader.php @@ -501,6 +501,18 @@ function wp_default_scripts( &$scripts ) { ) ); $scripts->add( 'updates', "/wp-admin/js/updates$suffix.js", array( 'jquery' ) ); + did_action( 'init' ) && $scripts->localize( 'updates', '_wpUpdatesSettings', array( + 'ajax_nonce' => wp_create_nonce( 'updates' ), + 'l10n' => array( + 'updating' => __( 'Updating...' ), + 'updated' => __( 'Updated!' ), + 'updateFailed' => __( 'Update failed' ), + 'installNow' => __( 'Install Now' ), + 'installing' => __( 'Installing...' ), + 'installed' => __( 'Installed!' ), + 'installFailed' => __( 'Installation failed' ), + ) + ) ); $scripts->add( 'farbtastic', '/wp-admin/js/farbtastic.js', array('jquery'), '1.2' );