mirror of
https://github.com/WordPress/WordPress.git
synced 2024-12-23 17:48:01 +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 );
|
self.doSearch( self.pages.search );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.loadItems( type, object );
|
self.loadItems( [
|
||||||
|
{ type: type, object: object }
|
||||||
|
] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -360,53 +362,82 @@
|
|||||||
// Render the template for each item by type.
|
// Render the template for each item by type.
|
||||||
_.each( api.Menus.data.itemTypes, function( itemType ) {
|
_.each( api.Menus.data.itemTypes, function( itemType ) {
|
||||||
self.pages[ itemType.type + ':' + itemType.object ] = 0;
|
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 ) {
|
* Load available nav menu items.
|
||||||
var self = this, params, request, itemTemplate, availableMenuItemContainer;
|
*
|
||||||
|
* @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' );
|
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;
|
return;
|
||||||
}
|
}
|
||||||
availableMenuItemContainer = $( '#available-menu-items-' + type + '-' + object );
|
|
||||||
availableMenuItemContainer.find( '.accordion-section-title' ).addClass( 'loading' );
|
|
||||||
self.loading = true;
|
self.loading = true;
|
||||||
params = {
|
request = wp.ajax.post( 'load-available-menu-items-customizer', {
|
||||||
'customize-menus-nonce': api.settings.nonce['customize-menus'],
|
'customize-menus-nonce': api.settings.nonce['customize-menus'],
|
||||||
'wp_customize': 'on',
|
'wp_customize': 'on',
|
||||||
'type': type,
|
'item_types': requestItemTypes
|
||||||
'object': object,
|
} );
|
||||||
'page': self.pages[ type + ':' + object ]
|
|
||||||
};
|
|
||||||
request = wp.ajax.post( 'load-available-menu-items-customizer', params );
|
|
||||||
|
|
||||||
request.done(function( data ) {
|
request.done(function( data ) {
|
||||||
var items, typeInner;
|
var typeInner;
|
||||||
items = data.items;
|
_.each( data.items, function( typeItems, name ) {
|
||||||
if ( 0 === items.length ) {
|
if ( 0 === typeItems.length ) {
|
||||||
if ( 0 === self.pages[ type + ':' + object ] ) {
|
if ( 0 === self.pages[ name ] ) {
|
||||||
availableMenuItemContainer
|
availableMenuItemContainers[ name ].find( '.accordion-section-title' )
|
||||||
.addClass( 'cannot-expand' )
|
.addClass( 'cannot-expand' )
|
||||||
.removeClass( 'loading' )
|
.removeClass( 'loading' )
|
||||||
.find( '.accordion-section-title > button' )
|
.find( '.accordion-section-title > button' )
|
||||||
.prop( 'tabIndex', -1 );
|
.prop( 'tabIndex', -1 );
|
||||||
}
|
}
|
||||||
self.pages[ type + ':' + object ] = -1;
|
self.pages[ name ] = -1;
|
||||||
return;
|
return;
|
||||||
} else if ( ( 'page' === object ) && ( ! availableMenuItemContainer.hasClass( 'open' ) ) ) {
|
} else if ( ( 'post_type:page' === name ) && ( ! availableMenuItemContainers[ name ].hasClass( 'open' ) ) ) {
|
||||||
availableMenuItemContainer.find( '.accordion-section-title > button' ).click();
|
availableMenuItemContainers[ name ].find( '.accordion-section-title > button' ).click();
|
||||||
}
|
}
|
||||||
items = new api.Menus.AvailableItemCollection( items ); // @todo Why is this collection created and then thrown away?
|
typeItems = new api.Menus.AvailableItemCollection( typeItems ); // @todo Why is this collection created and then thrown away?
|
||||||
self.collection.add( items.models );
|
self.collection.add( typeItems.models );
|
||||||
typeInner = availableMenuItemContainer.find( '.available-menu-items-list' );
|
typeInner = availableMenuItemContainers[ name ].find( '.available-menu-items-list' );
|
||||||
items.each(function( menuItem ) {
|
typeItems.each( function( menuItem ) {
|
||||||
typeInner.append( itemTemplate( menuItem.attributes ) );
|
typeInner.append( itemTemplate( menuItem.attributes ) );
|
||||||
|
} );
|
||||||
|
self.pages[ name ] += 1;
|
||||||
});
|
});
|
||||||
self.pages[ type + ':' + object ] += 1;
|
|
||||||
});
|
});
|
||||||
request.fail(function( data ) {
|
request.fail(function( data ) {
|
||||||
if ( typeof console !== 'undefined' && console.error ) {
|
if ( typeof console !== 'undefined' && console.error ) {
|
||||||
@ -414,7 +445,9 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
request.always(function() {
|
request.always(function() {
|
||||||
availableMenuItemContainer.find( '.accordion-section-title' ).removeClass( 'loading' );
|
_.each( availableMenuItemContainers, function( container ) {
|
||||||
|
container.find( '.accordion-section-title' ).removeClass( 'loading' );
|
||||||
|
} );
|
||||||
self.loading = false;
|
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 );
|
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' );
|
wp_send_json_error( 'nav_menus_missing_type_or_object_parameter' );
|
||||||
}
|
}
|
||||||
|
|
||||||
$type = sanitize_key( $_POST['type'] );
|
foreach ( $item_types as $item_type ) {
|
||||||
$object = sanitize_key( $_POST['object'] );
|
if ( empty( $item_type['type'] ) || empty( $item_type['object'] ) ) {
|
||||||
$page = empty( $_POST['page'] ) ? 0 : absint( $_POST['page'] );
|
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 );
|
$items = $this->load_available_items_query( $type, $object, $page );
|
||||||
|
|
||||||
if ( is_wp_error( $items ) ) {
|
if ( is_wp_error( $items ) ) {
|
||||||
wp_send_json_error( $items->get_error_code() );
|
wp_send_json_error( $items->get_error_code() );
|
||||||
} else {
|
|
||||||
wp_send_json_success( array( 'items' => $items ) );
|
|
||||||
}
|
}
|
||||||
|
$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
|
* @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.
|
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
||||||
|
Loading…
Reference in New Issue
Block a user