Customizer: Add stable sorting for panels, sections and controls in JS. Improve sorting in PHP.
props westonruter. fixes #30225. Built from https://develop.svn.wordpress.org/trunk@30214 git-svn-id: http://core.svn.wordpress.org/trunk@30214 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
4b23645ad4
commit
73b4f6f449
|
@ -1,6 +1,6 @@
|
||||||
/* globals _wpCustomizeHeader, _wpMediaViewsL10n */
|
/* globals _wpCustomizeHeader, _wpMediaViewsL10n */
|
||||||
(function( exports, $ ){
|
(function( exports, $ ){
|
||||||
var bubbleChildValueChanges, Container, focus, isKeydownButNotEnterEvent, areElementListsEqual, api = wp.customize;
|
var bubbleChildValueChanges, Container, focus, isKeydownButNotEnterEvent, areElementListsEqual, prioritySort, api = wp.customize;
|
||||||
|
|
||||||
// @todo Move private helper functions to wp.customize.utils so they can be unit tested
|
// @todo Move private helper functions to wp.customize.utils so they can be unit tested
|
||||||
|
|
||||||
|
@ -77,6 +77,23 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stable sort for Panels, Sections, and Controls.
|
||||||
|
*
|
||||||
|
* If a.priority() === b.priority(), then sort by their respective params.instanceNumber.
|
||||||
|
*
|
||||||
|
* @param {(wp.customize.Panel|wp.customize.Section|wp.customize.Control)} a
|
||||||
|
* @param {(wp.customize.Panel|wp.customize.Section|wp.customize.Control)} b
|
||||||
|
* @returns {Number}
|
||||||
|
*/
|
||||||
|
prioritySort = function ( a, b ) {
|
||||||
|
if ( a.priority() === b.priority() && typeof a.params.instanceNumber === 'number' && typeof b.params.instanceNumber === 'number' ) {
|
||||||
|
return a.params.instanceNumber - b.params.instanceNumber;
|
||||||
|
} else {
|
||||||
|
return a.priority() - b.priority();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether the supplied Event object is for a keydown event but not the Enter key.
|
* Return whether the supplied Event object is for a keydown event but not the Enter key.
|
||||||
*
|
*
|
||||||
|
@ -176,9 +193,7 @@
|
||||||
children.push( child );
|
children.push( child );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
children.sort( function ( a, b ) {
|
children.sort( prioritySort );
|
||||||
return a.priority() - b.priority();
|
|
||||||
} );
|
|
||||||
return children;
|
return children;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1952,9 +1967,7 @@
|
||||||
} );
|
} );
|
||||||
|
|
||||||
// Sort the root panels and sections
|
// Sort the root panels and sections
|
||||||
rootNodes.sort( function ( a, b ) {
|
rootNodes.sort( prioritySort );
|
||||||
return a.priority() - b.priority();
|
|
||||||
} );
|
|
||||||
rootContainers = _.pluck( rootNodes, 'container' );
|
rootContainers = _.pluck( rootNodes, 'container' );
|
||||||
appendContainer = $( '#customize-theme-controls' ).children( 'ul' ); // @todo This should be defined elsewhere, and to be configurable
|
appendContainer = $( '#customize-theme-controls' ).children( 'ul' ); // @todo This should be defined elsewhere, and to be configurable
|
||||||
if ( ! areElementListsEqual( rootContainers, appendContainer.children() ) ) {
|
if ( ! areElementListsEqual( rootContainers, appendContainer.children() ) ) {
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -7,6 +7,27 @@
|
||||||
* @since 3.4.0
|
* @since 3.4.0
|
||||||
*/
|
*/
|
||||||
class WP_Customize_Control {
|
class WP_Customize_Control {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Incremented with each new class instantiation, then stored in $instance_number.
|
||||||
|
*
|
||||||
|
* Used when sorting two instances whose priorities are equal.
|
||||||
|
*
|
||||||
|
* @since 4.1.0
|
||||||
|
* @access protected
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected static $instance_count = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Order in which this instance was created in relation to other instances.
|
||||||
|
*
|
||||||
|
* @since 4.1.0
|
||||||
|
* @access public
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $instance_number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @access public
|
* @access public
|
||||||
* @var WP_Customize_Manager
|
* @var WP_Customize_Manager
|
||||||
|
@ -127,6 +148,8 @@ class WP_Customize_Control {
|
||||||
if ( empty( $this->active_callback ) ) {
|
if ( empty( $this->active_callback ) ) {
|
||||||
$this->active_callback = array( $this, 'active_callback' );
|
$this->active_callback = array( $this, 'active_callback' );
|
||||||
}
|
}
|
||||||
|
self::$instance_count += 1;
|
||||||
|
$this->instance_number = self::$instance_count;
|
||||||
|
|
||||||
// Process settings.
|
// Process settings.
|
||||||
if ( empty( $this->settings ) ) {
|
if ( empty( $this->settings ) ) {
|
||||||
|
@ -218,13 +241,14 @@ class WP_Customize_Control {
|
||||||
$this->json['settings'][ $key ] = $setting->id;
|
$this->json['settings'][ $key ] = $setting->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->json['type'] = $this->type;
|
$this->json['type'] = $this->type;
|
||||||
$this->json['priority'] = $this->priority;
|
$this->json['priority'] = $this->priority;
|
||||||
$this->json['active'] = $this->active();
|
$this->json['active'] = $this->active();
|
||||||
$this->json['section'] = $this->section;
|
$this->json['section'] = $this->section;
|
||||||
$this->json['content'] = $this->get_content();
|
$this->json['content'] = $this->get_content();
|
||||||
$this->json['label'] = $this->label;
|
$this->json['label'] = $this->label;
|
||||||
$this->json['description'] = $this->description;
|
$this->json['description'] = $this->description;
|
||||||
|
$this->json['instanceNumber'] = $this->instance_number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -856,28 +856,27 @@ final class WP_Customize_Manager {
|
||||||
* @since 4.1.0
|
* @since 4.1.0
|
||||||
*/
|
*/
|
||||||
public function render_control_templates() {
|
public function render_control_templates() {
|
||||||
foreach( $this->registered_control_types as $control_type ) {
|
foreach ( $this->registered_control_types as $control_type ) {
|
||||||
$control = new $control_type( $this, 'temp', array() );
|
$control = new $control_type( $this, 'temp', array() );
|
||||||
$control->print_template();
|
$control->print_template();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to compare two objects by priority.
|
* Helper function to compare two objects by priority, ensuring sort stability via instance_number.
|
||||||
*
|
*
|
||||||
* @since 3.4.0
|
* @since 3.4.0
|
||||||
*
|
*
|
||||||
* @param object $a Object A.
|
* @param {WP_Customize_Panel|WP_Customize_Section|WP_Customize_Control} $a Object A.
|
||||||
* @param object $b Object B.
|
* @param {WP_Customize_Panel|WP_Customize_Section|WP_Customize_Control} $b Object B.
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
protected final function _cmp_priority( $a, $b ) {
|
protected final function _cmp_priority( $a, $b ) {
|
||||||
$ap = $a->priority;
|
if ( $a->priority === $b->priority ) {
|
||||||
$bp = $b->priority;
|
return $a->instance_number - $a->instance_number;
|
||||||
|
} else {
|
||||||
if ( $ap == $bp )
|
return $a->priority - $b->priority;
|
||||||
return 0;
|
}
|
||||||
return ( $ap > $bp ) ? 1 : -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -891,8 +890,8 @@ final class WP_Customize_Manager {
|
||||||
*/
|
*/
|
||||||
public function prepare_controls() {
|
public function prepare_controls() {
|
||||||
|
|
||||||
$this->controls = array_reverse( $this->controls );
|
|
||||||
$controls = array();
|
$controls = array();
|
||||||
|
uasort( $this->controls, array( $this, '_cmp_priority' ) );
|
||||||
|
|
||||||
foreach ( $this->controls as $id => $control ) {
|
foreach ( $this->controls as $id => $control ) {
|
||||||
if ( ! isset( $this->sections[ $control->section ] ) || ! $control->check_capabilities() ) {
|
if ( ! isset( $this->sections[ $control->section ] ) || ! $control->check_capabilities() ) {
|
||||||
|
@ -905,8 +904,6 @@ final class WP_Customize_Manager {
|
||||||
$this->controls = $controls;
|
$this->controls = $controls;
|
||||||
|
|
||||||
// Prepare sections.
|
// Prepare sections.
|
||||||
// Reversing makes uasort sort by time added when conflicts occur.
|
|
||||||
$this->sections = array_reverse( $this->sections );
|
|
||||||
uasort( $this->sections, array( $this, '_cmp_priority' ) );
|
uasort( $this->sections, array( $this, '_cmp_priority' ) );
|
||||||
$sections = array();
|
$sections = array();
|
||||||
|
|
||||||
|
@ -930,8 +927,6 @@ final class WP_Customize_Manager {
|
||||||
$this->sections = $sections;
|
$this->sections = $sections;
|
||||||
|
|
||||||
// Prepare panels.
|
// Prepare panels.
|
||||||
// Reversing makes uasort sort by time added when conflicts occur.
|
|
||||||
$this->panels = array_reverse( $this->panels );
|
|
||||||
uasort( $this->panels, array( $this, '_cmp_priority' ) );
|
uasort( $this->panels, array( $this, '_cmp_priority' ) );
|
||||||
$panels = array();
|
$panels = array();
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,26 @@
|
||||||
*/
|
*/
|
||||||
class WP_Customize_Panel {
|
class WP_Customize_Panel {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Incremented with each new class instantiation, then stored in $instance_number.
|
||||||
|
*
|
||||||
|
* Used when sorting two instances whose priorities are equal.
|
||||||
|
*
|
||||||
|
* @since 4.1.0
|
||||||
|
* @access protected
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected static $instance_count = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Order in which this instance was created in relation to other instances.
|
||||||
|
*
|
||||||
|
* @since 4.1.0
|
||||||
|
* @access public
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $instance_number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WP_Customize_Manager instance.
|
* WP_Customize_Manager instance.
|
||||||
*
|
*
|
||||||
|
@ -128,6 +148,8 @@ class WP_Customize_Panel {
|
||||||
if ( empty( $this->active_callback ) ) {
|
if ( empty( $this->active_callback ) ) {
|
||||||
$this->active_callback = array( $this, 'active_callback' );
|
$this->active_callback = array( $this, 'active_callback' );
|
||||||
}
|
}
|
||||||
|
self::$instance_count += 1;
|
||||||
|
$this->instance_number = self::$instance_count;
|
||||||
|
|
||||||
$this->sections = array(); // Users cannot customize the $sections array.
|
$this->sections = array(); // Users cannot customize the $sections array.
|
||||||
|
|
||||||
|
@ -185,6 +207,7 @@ class WP_Customize_Panel {
|
||||||
$array = wp_array_slice_assoc( (array) $this, array( 'title', 'description', 'priority', 'type' ) );
|
$array = wp_array_slice_assoc( (array) $this, array( 'title', 'description', 'priority', 'type' ) );
|
||||||
$array['content'] = $this->get_content();
|
$array['content'] = $this->get_content();
|
||||||
$array['active'] = $this->active();
|
$array['active'] = $this->active();
|
||||||
|
$array['instanceNumber'] = $this->instance_number;
|
||||||
return $array;
|
return $array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,26 @@
|
||||||
*/
|
*/
|
||||||
class WP_Customize_Section {
|
class WP_Customize_Section {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Incremented with each new class instantiation, then stored in $instance_number.
|
||||||
|
*
|
||||||
|
* Used when sorting two instances whose priorities are equal.
|
||||||
|
*
|
||||||
|
* @since 4.1.0
|
||||||
|
* @access protected
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected static $instance_count = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Order in which this instance was created in relation to other instances.
|
||||||
|
*
|
||||||
|
* @since 4.1.0
|
||||||
|
* @access public
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $instance_number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WP_Customize_Manager instance.
|
* WP_Customize_Manager instance.
|
||||||
*
|
*
|
||||||
|
@ -137,6 +157,8 @@ class WP_Customize_Section {
|
||||||
if ( empty( $this->active_callback ) ) {
|
if ( empty( $this->active_callback ) ) {
|
||||||
$this->active_callback = array( $this, 'active_callback' );
|
$this->active_callback = array( $this, 'active_callback' );
|
||||||
}
|
}
|
||||||
|
self::$instance_count += 1;
|
||||||
|
$this->instance_number = self::$instance_count;
|
||||||
|
|
||||||
$this->controls = array(); // Users cannot customize the $controls array.
|
$this->controls = array(); // Users cannot customize the $controls array.
|
||||||
|
|
||||||
|
@ -194,6 +216,7 @@ class WP_Customize_Section {
|
||||||
$array = wp_array_slice_assoc( (array) $this, array( 'title', 'description', 'priority', 'panel', 'type' ) );
|
$array = wp_array_slice_assoc( (array) $this, array( 'title', 'description', 'priority', 'panel', 'type' ) );
|
||||||
$array['content'] = $this->get_content();
|
$array['content'] = $this->get_content();
|
||||||
$array['active'] = $this->active();
|
$array['active'] = $this->active();
|
||||||
|
$array['instanceNumber'] = $this->instance_number;
|
||||||
return $array;
|
return $array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
*
|
*
|
||||||
* @global string $wp_version
|
* @global string $wp_version
|
||||||
*/
|
*/
|
||||||
$wp_version = '4.1-alpha-30213';
|
$wp_version = '4.1-alpha-30214';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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