diff --git src/wp-admin/js/customize-controls.js src/wp-admin/js/customize-controls.js
index 0ea60ce..851eaf3 100644
|
|
|
|
| 1 | 1 | /* globals _wpCustomizeHeader, _wpMediaViewsL10n */ |
| 2 | 2 | (function( exports, $ ){ |
| 3 | | var bubbleChildValueChanges, Container, focus, isKeydownButNotEnterEvent, areElementListsEqual, api = wp.customize; |
| | 3 | var bubbleChildValueChanges, Container, focus, isKeydownButNotEnterEvent, areElementListsEqual, stableSort, api = wp.customize; |
| 4 | 4 | |
| 5 | 5 | // @todo Move private helper functions to wp.customize.utils so they can be unit tested |
| 6 | 6 | |
| … |
… |
|
| 78 | 78 | }; |
| 79 | 79 | |
| 80 | 80 | /** |
| | 81 | * Stable sort for Panels, Sections, and Controls. |
| | 82 | * |
| | 83 | * If a.priority() === b.priority(), then sort by their respective params.instanceNumber. |
| | 84 | * |
| | 85 | * @param {(wp.customize.Panel|wp.customize.Section|wp.customize.Control)} a |
| | 86 | * @param {(wp.customize.Panel|wp.customize.Section|wp.customize.Control)} b |
| | 87 | * @returns {Number} |
| | 88 | */ |
| | 89 | stableSort = function ( a, b ) { |
| | 90 | if ( a.priority() === b.priority() && typeof a.params.instanceNumber === 'number' && typeof b.params.instanceNumber === 'number' ) { |
| | 91 | return a.params.instanceNumber - b.params.instanceNumber; |
| | 92 | } else { |
| | 93 | return a.priority() - b.priority(); |
| | 94 | } |
| | 95 | }; |
| | 96 | |
| | 97 | /** |
| 81 | 98 | * Return whether the supplied Event object is for a keydown event but not the Enter key. |
| 82 | 99 | * |
| 83 | 100 | * @param {jQuery.Event} event |
| … |
… |
|
| 176 | 193 | children.push( child ); |
| 177 | 194 | } |
| 178 | 195 | } ); |
| 179 | | children.sort( function ( a, b ) { |
| 180 | | return a.priority() - b.priority(); |
| 181 | | } ); |
| | 196 | children.sort( stableSort ); |
| 182 | 197 | return children; |
| 183 | 198 | }, |
| 184 | 199 | |
| … |
… |
|
| 1952 | 1967 | } ); |
| 1953 | 1968 | |
| 1954 | 1969 | // Sort the root panels and sections |
| 1955 | | rootNodes.sort( function ( a, b ) { |
| 1956 | | return a.priority() - b.priority(); |
| 1957 | | } ); |
| | 1970 | rootNodes.sort( stableSort ); |
| 1958 | 1971 | rootContainers = _.pluck( rootNodes, 'container' ); |
| 1959 | 1972 | appendContainer = $( '#customize-theme-controls' ).children( 'ul' ); // @todo This should be defined elsewhere, and to be configurable |
| 1960 | 1973 | if ( ! areElementListsEqual( rootContainers, appendContainer.children() ) ) { |
diff --git src/wp-includes/class-wp-customize-control.php src/wp-includes/class-wp-customize-control.php
index dcebb0f..a2df83f 100644
|
|
|
|
| 7 | 7 | * @since 3.4.0 |
| 8 | 8 | */ |
| 9 | 9 | class WP_Customize_Control { |
| | 10 | |
| | 11 | /** |
| | 12 | * Incremented with each new class instantiation, then stored in $instance_number. |
| | 13 | * |
| | 14 | * Used when sorting two instances whose priorities are equal. |
| | 15 | * |
| | 16 | * @since 4.1.0 |
| | 17 | * @access protected |
| | 18 | * @var int |
| | 19 | */ |
| | 20 | protected static $instance_count = 0; |
| | 21 | |
| | 22 | /** |
| | 23 | * Order in which this instance was created in relation to other instances. |
| | 24 | * |
| | 25 | * @since 4.1.0 |
| | 26 | * @access public |
| | 27 | * @var int |
| | 28 | */ |
| | 29 | public $instance_number; |
| | 30 | |
| 10 | 31 | /** |
| 11 | 32 | * @access public |
| 12 | 33 | * @var WP_Customize_Manager |
| … |
… |
class WP_Customize_Control { |
| 127 | 148 | if ( empty( $this->active_callback ) ) { |
| 128 | 149 | $this->active_callback = array( $this, 'active_callback' ); |
| 129 | 150 | } |
| | 151 | self::$instance_count += 1; |
| | 152 | $this->instance_number = self::$instance_count; |
| 130 | 153 | |
| 131 | 154 | // Process settings. |
| 132 | 155 | if ( empty( $this->settings ) ) { |
| … |
… |
class WP_Customize_Control { |
| 218 | 241 | $this->json['settings'][ $key ] = $setting->id; |
| 219 | 242 | } |
| 220 | 243 | |
| 221 | | $this->json['type'] = $this->type; |
| 222 | | $this->json['priority'] = $this->priority; |
| 223 | | $this->json['active'] = $this->active(); |
| 224 | | $this->json['section'] = $this->section; |
| 225 | | $this->json['content'] = $this->get_content(); |
| 226 | | $this->json['label'] = $this->label; |
| | 244 | $this->json['type'] = $this->type; |
| | 245 | $this->json['priority'] = $this->priority; |
| | 246 | $this->json['active'] = $this->active(); |
| | 247 | $this->json['section'] = $this->section; |
| | 248 | $this->json['content'] = $this->get_content(); |
| | 249 | $this->json['label'] = $this->label; |
| 227 | 250 | $this->json['description'] = $this->description; |
| | 251 | $this->json['instanceNumber'] = $this->instance_number; // note: camelCase for JS |
| 228 | 252 | } |
| 229 | 253 | |
| 230 | 254 | /** |
diff --git src/wp-includes/class-wp-customize-manager.php src/wp-includes/class-wp-customize-manager.php
index 371ea90..987edc6 100644
|
|
|
final class WP_Customize_Manager { |
| 856 | 856 | * @since 4.1.0 |
| 857 | 857 | */ |
| 858 | 858 | public function render_control_templates() { |
| 859 | | foreach( $this->registered_control_types as $control_type ) { |
| | 859 | foreach ( $this->registered_control_types as $control_type ) { |
| 860 | 860 | $control = new $control_type( $this, 'temp', array() ); |
| 861 | 861 | $control->print_template(); |
| 862 | 862 | } |
| 863 | 863 | } |
| 864 | 864 | |
| 865 | | /** |
| 866 | | * Helper function to compare two objects by priority. |
| | 865 | /** |
| | 866 | * Helper function to compare two objects by priority, ensuring sort stability via instance_number. |
| 867 | 867 | * |
| 868 | 868 | * @since 3.4.0 |
| 869 | 869 | * |
| 870 | | * @param object $a Object A. |
| 871 | | * @param object $b Object B. |
| | 870 | * @param {WP_Customize_Panel|WP_Customize_Section|WP_Customize_Control} $a Object A. |
| | 871 | * @param {WP_Customize_Panel|WP_Customize_Section|WP_Customize_Control} $b Object B. |
| 872 | 872 | * @return int |
| 873 | 873 | */ |
| 874 | 874 | protected final function _cmp_priority( $a, $b ) { |
| 875 | | $ap = $a->priority; |
| 876 | | $bp = $b->priority; |
| 877 | | |
| 878 | | if ( $ap == $bp ) |
| 879 | | return 0; |
| 880 | | return ( $ap > $bp ) ? 1 : -1; |
| | 875 | if ( $a->priority === $b->priority ) { |
| | 876 | return $a->instance_number - $a->instance_number; |
| | 877 | } else { |
| | 878 | return $a->priority - $b->priority; |
| | 879 | } |
| 881 | 880 | } |
| 882 | 881 | |
| 883 | 882 | /** |
| … |
… |
final class WP_Customize_Manager { |
| 891 | 890 | */ |
| 892 | 891 | public function prepare_controls() { |
| 893 | 892 | |
| 894 | | $this->controls = array_reverse( $this->controls ); |
| 895 | 893 | $controls = array(); |
| | 894 | uasort( $this->controls, array( $this, '_cmp_priority' ) ); |
| 896 | 895 | |
| 897 | 896 | foreach ( $this->controls as $id => $control ) { |
| 898 | 897 | if ( ! isset( $this->sections[ $control->section ] ) || ! $control->check_capabilities() ) { |
| … |
… |
final class WP_Customize_Manager { |
| 905 | 904 | $this->controls = $controls; |
| 906 | 905 | |
| 907 | 906 | // Prepare sections. |
| 908 | | // Reversing makes uasort sort by time added when conflicts occur. |
| 909 | | $this->sections = array_reverse( $this->sections ); |
| 910 | 907 | uasort( $this->sections, array( $this, '_cmp_priority' ) ); |
| 911 | 908 | $sections = array(); |
| 912 | 909 | |
| … |
… |
final class WP_Customize_Manager { |
| 930 | 927 | $this->sections = $sections; |
| 931 | 928 | |
| 932 | 929 | // Prepare panels. |
| 933 | | // Reversing makes uasort sort by time added when conflicts occur. |
| 934 | | $this->panels = array_reverse( $this->panels ); |
| 935 | 930 | uasort( $this->panels, array( $this, '_cmp_priority' ) ); |
| 936 | 931 | $panels = array(); |
| 937 | 932 | |
diff --git src/wp-includes/class-wp-customize-panel.php src/wp-includes/class-wp-customize-panel.php
index 201c4b9..af8f243 100644
|
|
|
|
| 11 | 11 | class WP_Customize_Panel { |
| 12 | 12 | |
| 13 | 13 | /** |
| | 14 | * Incremented with each new class instantiation, then stored in $instance_number. |
| | 15 | * |
| | 16 | * Used when sorting two instances whose priorities are equal. |
| | 17 | * |
| | 18 | * @since 4.1.0 |
| | 19 | * @access protected |
| | 20 | * @var int |
| | 21 | */ |
| | 22 | protected static $instance_count = 0; |
| | 23 | |
| | 24 | /** |
| | 25 | * Order in which this instance was created in relation to other instances. |
| | 26 | * |
| | 27 | * @since 4.1.0 |
| | 28 | * @access public |
| | 29 | * @var int |
| | 30 | */ |
| | 31 | public $instance_number; |
| | 32 | |
| | 33 | /** |
| 14 | 34 | * WP_Customize_Manager instance. |
| 15 | 35 | * |
| 16 | 36 | * @since 4.0.0 |
| … |
… |
class WP_Customize_Panel { |
| 128 | 148 | if ( empty( $this->active_callback ) ) { |
| 129 | 149 | $this->active_callback = array( $this, 'active_callback' ); |
| 130 | 150 | } |
| | 151 | self::$instance_count += 1; |
| | 152 | $this->instance_number = self::$instance_count; |
| 131 | 153 | |
| 132 | 154 | $this->sections = array(); // Users cannot customize the $sections array. |
| 133 | 155 | |
| … |
… |
class WP_Customize_Panel { |
| 185 | 207 | $array = wp_array_slice_assoc( (array) $this, array( 'title', 'description', 'priority', 'type' ) ); |
| 186 | 208 | $array['content'] = $this->get_content(); |
| 187 | 209 | $array['active'] = $this->active(); |
| | 210 | $array['instanceNumber'] = $this->instance_number; // camelCase |
| 188 | 211 | return $array; |
| 189 | 212 | } |
| 190 | 213 | |
diff --git src/wp-includes/class-wp-customize-section.php src/wp-includes/class-wp-customize-section.php
index 3553285..a90feb5 100644
|
|
|
|
| 11 | 11 | class WP_Customize_Section { |
| 12 | 12 | |
| 13 | 13 | /** |
| | 14 | * Incremented with each new class instantiation, then stored in $instance_number. |
| | 15 | * |
| | 16 | * Used when sorting two instances whose priorities are equal. |
| | 17 | * |
| | 18 | * @since 4.1.0 |
| | 19 | * @access protected |
| | 20 | * @var int |
| | 21 | */ |
| | 22 | protected static $instance_count = 0; |
| | 23 | |
| | 24 | /** |
| | 25 | * Order in which this instance was created in relation to other instances. |
| | 26 | * |
| | 27 | * @since 4.1.0 |
| | 28 | * @access public |
| | 29 | * @var int |
| | 30 | */ |
| | 31 | public $instance_number; |
| | 32 | |
| | 33 | /** |
| 14 | 34 | * WP_Customize_Manager instance. |
| 15 | 35 | * |
| 16 | 36 | * @since 3.4.0 |
| … |
… |
class WP_Customize_Section { |
| 137 | 157 | if ( empty( $this->active_callback ) ) { |
| 138 | 158 | $this->active_callback = array( $this, 'active_callback' ); |
| 139 | 159 | } |
| | 160 | self::$instance_count += 1; |
| | 161 | $this->instance_number = self::$instance_count; |
| 140 | 162 | |
| 141 | 163 | $this->controls = array(); // Users cannot customize the $controls array. |
| 142 | 164 | |
| … |
… |
class WP_Customize_Section { |
| 194 | 216 | $array = wp_array_slice_assoc( (array) $this, array( 'title', 'description', 'priority', 'panel', 'type' ) ); |
| 195 | 217 | $array['content'] = $this->get_content(); |
| 196 | 218 | $array['active'] = $this->active(); |
| | 219 | $array['instanceNumber'] = $this->instance_number; // camelCase |
| 197 | 220 | return $array; |
| 198 | 221 | } |
| 199 | 222 | |