diff --git src/wp-includes/class-wp-customize-nav-menus.php src/wp-includes/class-wp-customize-nav-menus.php
index c13ed93..f85ebfc 100644
|
|
|
final class WP_Customize_Nav_Menus { |
| 768 | 768 | ( empty( $args['fallback_cb'] ) || is_string( $args['fallback_cb'] ) ) |
| 769 | 769 | && |
| 770 | 770 | ( empty( $args['walker'] ) || is_string( $args['walker'] ) ) |
| | 771 | && |
| | 772 | ( |
| | 773 | ! empty( $args['theme_location'] ) |
| | 774 | || |
| | 775 | ( ! empty( $args['menu'] ) && ( is_numeric( $args['menu'] ) || is_object( $args['menu'] ) ) ) |
| | 776 | ) |
| 771 | 777 | ); |
| 772 | 778 | $args['can_partial_refresh'] = $can_partial_refresh; |
| 773 | 779 | |
| … |
… |
final class WP_Customize_Nav_Menus { |
| 778 | 784 | $hashed_args['walker'] = ''; |
| 779 | 785 | } |
| 780 | 786 | |
| | 787 | // Replace object menu arg with a term_id menu arg, as this exports better to JS and is easier to compare hashes. |
| | 788 | if ( ! empty( $hashed_args['menu'] ) && is_object( $hashed_args['menu'] ) ) { |
| | 789 | $hashed_args['menu'] = $hashed_args['menu']->term_id; |
| | 790 | } |
| | 791 | |
| 781 | 792 | ksort( $hashed_args ); |
| 782 | 793 | $hashed_args['args_hash'] = $this->hash_nav_menu_args( $hashed_args ); |
| 783 | 794 | |
| … |
… |
final class WP_Customize_Nav_Menus { |
| 798 | 809 | */ |
| 799 | 810 | public function filter_wp_nav_menu( $nav_menu_content, $args ) { |
| 800 | 811 | if ( ! empty( $args->can_partial_refresh ) && ! empty( $args->instance_number ) ) { |
| 801 | | $nav_menu_content = sprintf( |
| 802 | | '<div id="partial-refresh-menu-container-%1$d" class="partial-refresh-menu-container" data-instance-number="%1$d">%2$s</div>', |
| 803 | | $args->instance_number, |
| 804 | | $nav_menu_content |
| | 812 | $nav_menu_content = preg_replace( |
| | 813 | '/(?<=class=")/', |
| | 814 | sprintf( 'partial-refreshable-nav-menu partial-refreshable-nav-menu-%1$d ', $args->instance_number ), |
| | 815 | $nav_menu_content, |
| | 816 | 1 // Only update the class on the first element found, the menu container. |
| 805 | 817 | ); |
| 806 | 818 | } |
| 807 | 819 | return $nav_menu_content; |
diff --git src/wp-includes/js/customize-preview-nav-menus.js src/wp-includes/js/customize-preview-nav-menus.js
index ce962d6..d1ce558 100644
|
|
|
wp.customize.menusPreview = ( function( $, api ) { |
| 159 | 159 | * @param {int} instanceNumber |
| 160 | 160 | */ |
| 161 | 161 | self.refreshMenuInstance = function( instanceNumber ) { |
| 162 | | var self = this, data, customized, container, request, wpNavArgs, instance; |
| | 162 | var self = this, data, menuId, customized, container, request, wpNavArgs, instance, containerInstanceClassName; |
| 163 | 163 | |
| 164 | 164 | if ( ! self.navMenuInstanceArgs[ instanceNumber ] ) { |
| 165 | 165 | throw new Error( 'unknown_instance_number' ); |
| 166 | 166 | } |
| 167 | 167 | instance = self.navMenuInstanceArgs[ instanceNumber ]; |
| 168 | 168 | |
| 169 | | container = $( '#partial-refresh-menu-container-' + String( instanceNumber ) ); |
| | 169 | containerInstanceClassName = 'partial-refreshable-nav-menu-' + String( instanceNumber ); |
| | 170 | container = $( '.' + containerInstanceClassName ); |
| 170 | 171 | |
| 171 | | if ( ! instance.can_partial_refresh || 0 === container.length ) { |
| | 172 | if ( _.isNumber( instance.menu ) ) { |
| | 173 | menuId = instance.menu; |
| | 174 | } else if ( instance.theme_location && api.has( 'nav_menu_locations[' + instance.theme_location + ']' ) ) { |
| | 175 | menuId = api( 'nav_menu_locations[' + instance.theme_location + ']' ).get(); |
| | 176 | } |
| | 177 | |
| | 178 | if ( ! menuId || ! instance.can_partial_refresh || 0 === container.length ) { |
| 172 | 179 | api.preview.send( 'refresh' ); |
| 173 | 180 | return; |
| 174 | 181 | } |
| | 182 | menuId = parseInt( menuId, 10 ); |
| 175 | 183 | |
| 176 | 184 | data = { |
| 177 | 185 | nonce: self.previewCustomizeNonce, // for Customize Preview |
| … |
… |
wp.customize.menusPreview = ( function( $, api ) { |
| 183 | 191 | data[ self.renderQueryVar ] = '1'; |
| 184 | 192 | customized = {}; |
| 185 | 193 | api.each( function( setting, id ) { |
| 186 | | // @todo We need to limit this to just the menu items that are associated with this menu/location. |
| 187 | | if ( /^(nav_menu|nav_menu_locations)/.test( id ) ) { |
| | 194 | // @todo Core should propagate the dirty state into the Preview as well so we can use that here. |
| | 195 | if ( id === 'nav_menu[' + String( menuId ) + ']' || ( /^nav_menu_item\[/.test( id ) && setting() && menuId === setting().nav_menu_term_id ) ) { |
| 188 | 196 | customized[ id ] = setting.get(); |
| 189 | 197 | } |
| 190 | 198 | } ); |
| … |
… |
wp.customize.menusPreview = ( function( $, api ) { |
| 203 | 211 | url: self.requestUri |
| 204 | 212 | } ); |
| 205 | 213 | request.done( function( data ) { |
| 206 | | var eventParam; |
| 207 | | container.empty().append( $( data ) ); |
| | 214 | // If the menu is now not visible, refresh since the page layout may have changed. |
| | 215 | if ( false === data ) { |
| | 216 | api.preview.send( 'refresh' ); |
| | 217 | return; |
| | 218 | } |
| | 219 | |
| | 220 | var eventParam, previousContainer = container; |
| | 221 | container = $( data ); |
| | 222 | container.addClass( containerInstanceClassName ); |
| | 223 | container.addClass( 'partial-refreshable-nav-menu customize-partial-refreshing' ); |
| | 224 | previousContainer.replaceWith( container ); |
| 208 | 225 | eventParam = { |
| 209 | 226 | instanceNumber: instanceNumber, |
| 210 | | wpNavArgs: wpNavArgs |
| | 227 | wpNavArgs: wpNavArgs, |
| | 228 | oldContainer: previousContainer, |
| | 229 | newContainer: container |
| 211 | 230 | }; |
| 212 | | $( document ).trigger( 'customize-preview-menu-refreshed', [ eventParam ] ); |
| 213 | | } ); |
| 214 | | request.fail( function() { |
| 215 | | // @todo provide some indication for why |
| 216 | | } ); |
| 217 | | request.always( function() { |
| 218 | 231 | container.removeClass( 'customize-partial-refreshing' ); |
| | 232 | $( document ).trigger( 'customize-preview-menu-refreshed', [ eventParam ] ); |
| 219 | 233 | } ); |
| 220 | 234 | }; |
| 221 | 235 | |
diff --git tests/phpunit/tests/customize/nav-menus.php tests/phpunit/tests/customize/nav-menus.php
index 616bf0b..7fa88e7 100644
|
|
|
class Test_WP_Customize_Nav_Menus extends WP_UnitTestCase { |
| 353 | 353 | 'echo' => true, |
| 354 | 354 | 'fallback_cb' => 'wp_page_menu', |
| 355 | 355 | 'walker' => '', |
| | 356 | 'menu' => wp_create_nav_menu( 'Foo' ), |
| 356 | 357 | ) ); |
| 357 | 358 | $this->assertEquals( 1, $results['can_partial_refresh'] ); |
| 358 | 359 | |
| … |
… |
class Test_WP_Customize_Nav_Menus extends WP_UnitTestCase { |
| 390 | 391 | |
| 391 | 392 | $args = $menus->filter_wp_nav_menu_args( array( |
| 392 | 393 | 'echo' => true, |
| | 394 | 'menu' => wp_create_nav_menu( 'Foo' ), |
| 393 | 395 | 'fallback_cb' => 'wp_page_menu', |
| 394 | 396 | 'walker' => '', |
| 395 | 397 | ) ); |
| … |
… |
class Test_WP_Customize_Nav_Menus extends WP_UnitTestCase { |
| 401 | 403 | $object_args = json_decode( json_encode( $args ), false ); |
| 402 | 404 | $result = $menus->filter_wp_nav_menu( $nav_menu_content, $object_args ); |
| 403 | 405 | $expected = sprintf( |
| 404 | | '<div id="partial-refresh-menu-container-%1$d" class="partial-refresh-menu-container" data-instance-number="%1$d">%2$s</div>', |
| 405 | | $args['instance_number'], |
| 406 | | $nav_menu_content |
| | 406 | '<div class="partial-refreshable-nav-menu partial-refreshable-nav-menu-%1$d menu">', |
| | 407 | $args['instance_number'] |
| 407 | 408 | ); |
| 408 | | $this->assertEquals( $expected, $result ); |
| | 409 | $this->assertStringStartsWith( $expected, $result ); |
| 409 | 410 | } |
| 410 | 411 | |
| 411 | 412 | /** |