mirror of
https://github.com/WordPress/WordPress.git
synced 2024-12-23 09:37:42 +01:00
Customize: Combine Ajax requests for initial load of available nav menu items into a single request.
When there are many post types registered, prevent Ajax requests from piling up and slamming WordPress with concurrent requests. Props curdin, westonruter. Fixes #36697. Built from https://develop.svn.wordpress.org/trunk@39137 git-svn-id: http://core.svn.wordpress.org/trunk@39077 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
f4c3b8352e
commit
1a3e930383
@ -235,7 +235,9 @@
|
||||
self.doSearch( self.pages.search );
|
||||
}
|
||||
} else {
|
||||
self.loadItems( type, object );
|
||||
self.loadItems( [
|
||||
{ type: type, object: object }
|
||||
] );
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -360,53 +362,82 @@
|
||||
// Render the template for each item by type.
|
||||
_.each( api.Menus.data.itemTypes, function( itemType ) {
|
||||
self.pages[ itemType.type + ':' + itemType.object ] = 0;
|
||||
self.loadItems( itemType.type, itemType.object ); // @todo we need to combine these Ajax requests.
|
||||
} );
|
||||
self.loadItems( api.Menus.data.itemTypes );
|
||||
},
|
||||
|
||||
// Load available menu items.
|
||||
loadItems: function( type, object ) {
|
||||
var self = this, params, request, itemTemplate, availableMenuItemContainer;
|
||||
/**
|
||||
* Load available nav menu items.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @since 4.7.0 Changed function signature to take list of item types instead of single type/object.
|
||||
* @access private
|
||||
*
|
||||
* @param {Array.<object>} itemTypes List of objects containing type and key.
|
||||
* @param {string} deprecated Formerly the object parameter.
|
||||
* @returns {void}
|
||||
*/
|
||||
loadItems: function( itemTypes, deprecated ) {
|
||||
var self = this, _itemTypes, requestItemTypes = [], request, itemTemplate, availableMenuItemContainers = {};
|
||||
itemTemplate = wp.template( 'available-menu-item' );
|
||||
|
||||
if ( -1 === self.pages[ type + ':' + object ] ) {
|
||||
if ( _.isString( itemTypes ) && _.isString( deprecated ) ) {
|
||||
_itemTypes = [ { type: itemTypes, object: deprecated } ];
|
||||
} else {
|
||||
_itemTypes = itemTypes;
|
||||
}
|
||||
|
||||
_.each( _itemTypes, function( itemType ) {
|
||||
var container, name = itemType.type + ':' + itemType.object;
|
||||
if ( -1 === self.pages[ name ] ) {
|
||||
return; // Skip types for which there are no more results.
|
||||
}
|
||||
container = $( '#available-menu-items-' + itemType.type + '-' + itemType.object );
|
||||
container.find( '.accordion-section-title' ).addClass( 'loading' );
|
||||
availableMenuItemContainers[ name ] = container;
|
||||
|
||||
requestItemTypes.push( {
|
||||
object: itemType.object,
|
||||
type: itemType.type,
|
||||
page: self.pages[ name ]
|
||||
} );
|
||||
} );
|
||||
|
||||
if ( 0 === requestItemTypes.length ) {
|
||||
return;
|
||||
}
|
||||
availableMenuItemContainer = $( '#available-menu-items-' + type + '-' + object );
|
||||
availableMenuItemContainer.find( '.accordion-section-title' ).addClass( 'loading' );
|
||||
|
||||
self.loading = true;
|
||||
params = {
|
||||
request = wp.ajax.post( 'load-available-menu-items-customizer', {
|
||||
'customize-menus-nonce': api.settings.nonce['customize-menus'],
|
||||
'wp_customize': 'on',
|
||||
'type': type,
|
||||
'object': object,
|
||||
'page': self.pages[ type + ':' + object ]
|
||||
};
|
||||
request = wp.ajax.post( 'load-available-menu-items-customizer', params );
|
||||
'item_types': requestItemTypes
|
||||
} );
|
||||
|
||||
request.done(function( data ) {
|
||||
var items, typeInner;
|
||||
items = data.items;
|
||||
if ( 0 === items.length ) {
|
||||
if ( 0 === self.pages[ type + ':' + object ] ) {
|
||||
availableMenuItemContainer
|
||||
.addClass( 'cannot-expand' )
|
||||
.removeClass( 'loading' )
|
||||
.find( '.accordion-section-title > button' )
|
||||
.prop( 'tabIndex', -1 );
|
||||
var typeInner;
|
||||
_.each( data.items, function( typeItems, name ) {
|
||||
if ( 0 === typeItems.length ) {
|
||||
if ( 0 === self.pages[ name ] ) {
|
||||
availableMenuItemContainers[ name ].find( '.accordion-section-title' )
|
||||
.addClass( 'cannot-expand' )
|
||||
.removeClass( 'loading' )
|
||||
.find( '.accordion-section-title > button' )
|
||||
.prop( 'tabIndex', -1 );
|
||||
}
|
||||
self.pages[ name ] = -1;
|
||||
return;
|
||||
} else if ( ( 'post_type:page' === name ) && ( ! availableMenuItemContainers[ name ].hasClass( 'open' ) ) ) {
|
||||
availableMenuItemContainers[ name ].find( '.accordion-section-title > button' ).click();
|
||||
}
|
||||
self.pages[ type + ':' + object ] = -1;
|
||||
return;
|
||||
} else if ( ( 'page' === object ) && ( ! availableMenuItemContainer.hasClass( 'open' ) ) ) {
|
||||
availableMenuItemContainer.find( '.accordion-section-title > button' ).click();
|
||||
}
|
||||
items = new api.Menus.AvailableItemCollection( items ); // @todo Why is this collection created and then thrown away?
|
||||
self.collection.add( items.models );
|
||||
typeInner = availableMenuItemContainer.find( '.available-menu-items-list' );
|
||||
items.each(function( menuItem ) {
|
||||
typeInner.append( itemTemplate( menuItem.attributes ) );
|
||||
typeItems = new api.Menus.AvailableItemCollection( typeItems ); // @todo Why is this collection created and then thrown away?
|
||||
self.collection.add( typeItems.models );
|
||||
typeInner = availableMenuItemContainers[ name ].find( '.available-menu-items-list' );
|
||||
typeItems.each( function( menuItem ) {
|
||||
typeInner.append( itemTemplate( menuItem.attributes ) );
|
||||
} );
|
||||
self.pages[ name ] += 1;
|
||||
});
|
||||
self.pages[ type + ':' + object ] += 1;
|
||||
});
|
||||
request.fail(function( data ) {
|
||||
if ( typeof console !== 'undefined' && console.error ) {
|
||||
@ -414,7 +445,9 @@
|
||||
}
|
||||
});
|
||||
request.always(function() {
|
||||
availableMenuItemContainer.find( '.accordion-section-title' ).removeClass( 'loading' );
|
||||
_.each( availableMenuItemContainers, function( container ) {
|
||||
container.find( '.accordion-section-title' ).removeClass( 'loading' );
|
||||
} );
|
||||
self.loading = false;
|
||||
});
|
||||
},
|
||||
|
4
wp-admin/js/customize-nav-menus.min.js
vendored
4
wp-admin/js/customize-nav-menus.min.js
vendored
File diff suppressed because one or more lines are too long
@ -100,20 +100,35 @@ final class WP_Customize_Nav_Menus {
|
||||
wp_die( -1 );
|
||||
}
|
||||
|
||||
if ( empty( $_POST['type'] ) || empty( $_POST['object'] ) ) {
|
||||
$all_items = array();
|
||||
$item_types = array();
|
||||
if ( isset( $_POST['item_types'] ) && is_array( $_POST['item_types'] ) ) {
|
||||
$item_types = wp_unslash( $_POST['item_types'] );
|
||||
} elseif ( isset( $_POST['type'] ) && isset( $_POST['object'] ) ) { // Back compat.
|
||||
$item_types[] = array(
|
||||
'type' => wp_unslash( $_POST['type'] ),
|
||||
'object' => wp_unslash( $_POST['object'] ),
|
||||
'page' => empty( $_POST['page'] ) ? 0 : absint( $_POST['page'] ),
|
||||
);
|
||||
} else {
|
||||
wp_send_json_error( 'nav_menus_missing_type_or_object_parameter' );
|
||||
}
|
||||
|
||||
$type = sanitize_key( $_POST['type'] );
|
||||
$object = sanitize_key( $_POST['object'] );
|
||||
$page = empty( $_POST['page'] ) ? 0 : absint( $_POST['page'] );
|
||||
$items = $this->load_available_items_query( $type, $object, $page );
|
||||
|
||||
if ( is_wp_error( $items ) ) {
|
||||
wp_send_json_error( $items->get_error_code() );
|
||||
} else {
|
||||
wp_send_json_success( array( 'items' => $items ) );
|
||||
foreach ( $item_types as $item_type ) {
|
||||
if ( empty( $item_type['type'] ) || empty( $item_type['object'] ) ) {
|
||||
wp_send_json_error( 'nav_menus_missing_type_or_object_parameter' );
|
||||
}
|
||||
$type = sanitize_key( $item_type['type'] );
|
||||
$object = sanitize_key( $item_type['object'] );
|
||||
$page = empty( $item_type['page'] ) ? 0 : absint( $item_type['page'] );
|
||||
$items = $this->load_available_items_query( $type, $object, $page );
|
||||
if ( is_wp_error( $items ) ) {
|
||||
wp_send_json_error( $items->get_error_code() );
|
||||
}
|
||||
$all_items[ $item_type['type'] . ':' . $item_type['object'] ] = $items;
|
||||
}
|
||||
|
||||
wp_send_json_success( array( 'items' => $all_items ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4,7 +4,7 @@
|
||||
*
|
||||
* @global string $wp_version
|
||||
*/
|
||||
$wp_version = '4.7-beta1-39136';
|
||||
$wp_version = '4.7-beta1-39137';
|
||||
|
||||
/**
|
||||
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
||||
|
Loading…
Reference in New Issue
Block a user