diff --git a/wp-includes/js/media-models.js b/wp-includes/js/media-models.js index 2f620d3a31..602f850cd3 100644 --- a/wp-includes/js/media-models.js +++ b/wp-includes/js/media-models.js @@ -93,7 +93,7 @@ window.wp = window.wp || {}; * media.template( id ) * * Fetches a template by id. - * See wp.template() in `wp-includes/js/wp-backbone.js`. + * See wp.template() in `wp-includes/js/wp-util.js`. */ template: wp.template, @@ -101,66 +101,17 @@ window.wp = window.wp || {}; * media.post( [action], [data] ) * * Sends a POST request to WordPress. - * - * @param {string} action The slug of the action to fire in WordPress. - * @param {object} data The data to populate $_POST with. - * @return {$.promise} A jQuery promise that represents the request. + * See wp.xhr.post() in `wp-includes/js/wp-util.js`. */ - post: function( action, data ) { - return media.ajax({ - data: _.isObject( action ) ? action : _.extend( data || {}, { action: action }) - }); - }, + post: wp.xhr.post, /** * media.ajax( [action], [options] ) * - * Sends a POST request to WordPress. - * - * @param {string} action The slug of the action to fire in WordPress. - * @param {object} options The options passed to jQuery.ajax. - * @return {$.promise} A jQuery promise that represents the request. + * Sends an XHR request to WordPress. + * See wp.xhr.send() in `wp-includes/js/wp-util.js`. */ - ajax: function( action, options ) { - if ( _.isObject( action ) ) { - options = action; - } else { - options = options || {}; - options.data = _.extend( options.data || {}, { action: action }); - } - - options = _.defaults( options || {}, { - type: 'POST', - url: media.model.settings.ajaxurl, - context: this - }); - - return $.Deferred( function( deferred ) { - // Transfer success/error callbacks. - if ( options.success ) - deferred.done( options.success ); - if ( options.error ) - deferred.fail( options.error ); - - delete options.success; - delete options.error; - - // Use with PHP's wp_send_json_success() and wp_send_json_error() - $.ajax( options ).done( function( response ) { - // Treat a response of `1` as successful for backwards - // compatibility with existing handlers. - if ( response === '1' || response === 1 ) - response = { success: true }; - - if ( _.isObject( response ) && ! _.isUndefined( response.success ) ) - deferred[ response.success ? 'resolveWith' : 'rejectWith' ]( this, [response.data] ); - else - deferred.rejectWith( this, [response] ); - }).fail( function() { - deferred.rejectWith( this, arguments ); - }); - }).promise(); - }, + ajax: wp.xhr.send, // Scales a set of dimensions to fit within bounding dimensions. fit: function( dimensions ) { diff --git a/wp-includes/js/wp-util.js b/wp-includes/js/wp-util.js index 9177e54ace..b809d6169b 100644 --- a/wp-includes/js/wp-util.js +++ b/wp-includes/js/wp-util.js @@ -1,6 +1,9 @@ window.wp = window.wp || {}; (function ($) { + // Check for the utility settings. + var settings = typeof _wpUtilSettings === 'undefined' ? {} : _wpUtilSettings; + /** * wp.template( id ) * @@ -24,4 +27,79 @@ window.wp = window.wp || {}; return compiled( data ); }; }); + + // wp.xhr + // ------ + // + // Tools for sending ajax requests with JSON responses and built in error handling. + // Mirrors and wraps jQuery's ajax APIs. + wp.xhr = { + settings: settings.xhr || {}, + + /** + * wp.xhr.post( [action], [data] ) + * + * Sends a POST request to WordPress. + * + * @param {string} action The slug of the action to fire in WordPress. + * @param {object} data The data to populate $_POST with. + * @return {$.promise} A jQuery promise that represents the request. + */ + post: function( action, data ) { + return wp.xhr.send({ + data: _.isObject( action ) ? action : _.extend( data || {}, { action: action }) + }); + }, + + /** + * wp.xhr.send( [action], [options] ) + * + * Sends a POST request to WordPress. + * + * @param {string} action The slug of the action to fire in WordPress. + * @param {object} options The options passed to jQuery.ajax. + * @return {$.promise} A jQuery promise that represents the request. + */ + send: function( action, options ) { + if ( _.isObject( action ) ) { + options = action; + } else { + options = options || {}; + options.data = _.extend( options.data || {}, { action: action }); + } + + options = _.defaults( options || {}, { + type: 'POST', + url: wp.xhr.settings.url, + context: this + }); + + return $.Deferred( function( deferred ) { + // Transfer success/error callbacks. + if ( options.success ) + deferred.done( options.success ); + if ( options.error ) + deferred.fail( options.error ); + + delete options.success; + delete options.error; + + // Use with PHP's wp_send_json_success() and wp_send_json_error() + $.ajax( options ).done( function( response ) { + // Treat a response of `1` as successful for backwards + // compatibility with existing handlers. + if ( response === '1' || response === 1 ) + response = { success: true }; + + if ( _.isObject( response ) && ! _.isUndefined( response.success ) ) + deferred[ response.success ? 'resolveWith' : 'rejectWith' ]( this, [response.data] ); + else + deferred.rejectWith( this, [response] ); + }).fail( function() { + deferred.rejectWith( this, arguments ); + }); + }).promise(); + } + }; + }(jQuery)); diff --git a/wp-includes/script-loader.php b/wp-includes/script-loader.php index 1ecb16df33..e1752f0666 100644 --- a/wp-includes/script-loader.php +++ b/wp-includes/script-loader.php @@ -275,6 +275,12 @@ function wp_default_scripts( &$scripts ) { $scripts->add( 'backbone', '/wp-includes/js/backbone.min.js', array('underscore','jquery'), '1.0.0', 1 ); $scripts->add( 'wp-util', "/wp-includes/js/wp-util$suffix.js", array('underscore', 'jquery'), false, 1 ); + did_action( 'init' ) && $scripts->localize( 'wp-util', '_wpUtilSettings', array( + 'xhr' => array( + 'url' => admin_url( 'admin-ajax.php', 'relative' ), + ), + ) ); + $scripts->add( 'wp-backbone', "/wp-includes/js/wp-backbone$suffix.js", array('backbone', 'wp-util'), false, 1 ); $scripts->add( 'revisions', "/wp-admin/js/revisions$suffix.js", array( 'wp-backbone', 'jquery-ui-slider', 'jquery-ui-tooltip' ), false, 1 );