diff --git a/src/wp-admin/js/customize-nav-menus.js b/src/wp-admin/js/customize-nav-menus.js index cf7b9b1c2a..3e223825c4 100644 --- a/src/wp-admin/js/customize-nav-menus.js +++ b/src/wp-admin/js/customize-nav-menus.js @@ -1161,6 +1161,48 @@ } }); + /** + * Create a nav menu setting and section. + * + * @since 4.9.0 + * + * @param {string} [name=''] Nav menu name. + * @returns {wp.customize.Menus.MenuSection} Added nav menu. + */ + api.Menus.createNavMenu = function createNavMenu( name ) { + var customizeId, placeholderId, setting; + placeholderId = api.Menus.generatePlaceholderAutoIncrementId(); + + customizeId = 'nav_menu[' + String( placeholderId ) + ']'; + + // Register the menu control setting. + setting = api.create( customizeId, customizeId, {}, { + type: 'nav_menu', + transport: api.Menus.data.settingTransport, + previewer: api.previewer + } ); + setting.set( $.extend( + {}, + api.Menus.data.defaultSettingValues.nav_menu, + { + name: name || '' + } + ) ); + + /* + * Add the menu section (and its controls). + * Note that this will automatically create the required controls + * inside via the Section's ready method. + */ + return api.section.add( new api.Menus.MenuSection( customizeId, { + panel: 'nav_menus', + title: displayNavMenuName( name ), + customizeAction: api.Menus.data.l10n.customizingMenus, + priority: 10, + menu_id: placeholderId + } ) ); + }; + /** * wp.customize.Menus.NewMenuSection * @@ -1339,10 +1381,7 @@ contentContainer = section.contentContainer, nameInput = contentContainer.find( '.menu-name-field' ).first(), name = nameInput.val(), - menuSection, - customizeId, - editMenuSection, - placeholderId = api.Menus.generatePlaceholderAutoIncrementId(); + menuSection; if ( ! name ) { nameInput.addClass( 'invalid' ); @@ -1350,35 +1389,7 @@ return; } - customizeId = 'nav_menu[' + String( placeholderId ) + ']'; - - // Register the menu control setting. - api.create( customizeId, customizeId, {}, { - type: 'nav_menu', - transport: api.Menus.data.settingTransport, - previewer: api.previewer - } ); - api( customizeId ).set( $.extend( - {}, - api.Menus.data.defaultSettingValues.nav_menu, - { - name: name - } - ) ); - - /* - * Add the menu section (and its controls). - * Note that this will automatically create the required controls - * inside via the Section's ready method. - */ - menuSection = new api.Menus.MenuSection( customizeId, { - panel: 'nav_menus', - title: displayNavMenuName( name ), - customizeAction: api.Menus.data.l10n.customizingMenus, - priority: 10, - menu_id: placeholderId - } ); - api.section.add( customizeId, menuSection ); + menuSection = api.Menus.createNavMenu( name ); // Clear name field. nameInput.val( '' ); @@ -1390,7 +1401,7 @@ if ( checkbox.prop( 'checked' ) ) { navMenuLocationSetting = api( 'nav_menu_locations[' + checkbox.data( 'location-id' ) + ']' ); - navMenuLocationSetting.set( placeholderId ); + navMenuLocationSetting.set( menuSection.params.menu_id ); // Reset state for next new menu checkbox.prop( 'checked', false ); @@ -1400,12 +1411,11 @@ wp.a11y.speak( api.Menus.data.l10n.menuAdded ); // Focus on the new menu section. - editMenuSection = api.section( customizeId ); - editMenuSection.focus( { + menuSection.focus( { completeCallback: function() { - editMenuSection.highlightNewItemButton(); + menuSection.highlightNewItemButton(); } - } ); // @todo should we focus on the new menu's control and open the add-items panel? Thinking user flow... + } ); }, /** @@ -3007,6 +3017,87 @@ } } ); + /** + * wp.customize.Menus.NewMenuControl + * + * Customizer control for creating new menus and handling deletion of existing menus. + * Note that 'new_menu' must match the WP_Customize_New_Menu_Control::$type. + * + * @constructor + * @augments wp.customize.Control + * @deprecated 4.9.0 This class is no longer used due to new menu creation UX. + */ + api.Menus.NewMenuControl = api.Control.extend({ + + /** + * Initialize. + * + * @deprecated 4.9.0 + */ + initialize: function() { + if ( 'undefined' !== typeof console && console.warn ) { + console.warn( '[DEPRECATED] wp.customize.NewMenuControl will be removed. Please use wp.customize.Menus.createNavMenu() instead.' ); + } + api.Control.prototype.initialize.apply( this, arguments ); + }, + + /** + * Set up the control. + * + * @deprecated 4.9.0 + */ + ready: function() { + this._bindHandlers(); + }, + + _bindHandlers: function() { + var self = this, + name = $( '#customize-control-new_menu_name input' ), + submit = $( '#create-new-menu-submit' ); + name.on( 'keydown', function( event ) { + if ( 13 === event.which ) { // Enter. + self.submit(); + } + } ); + submit.on( 'click', function( event ) { + self.submit(); + event.stopPropagation(); + event.preventDefault(); + } ); + }, + + /** + * Create the new menu with the name supplied. + * + * @deprecated 4.9.0 + */ + submit: function() { + + var control = this, + container = control.container.closest( '.accordion-section-new-menu' ), + nameInput = container.find( '.menu-name-field' ).first(), + name = nameInput.val(), + menuSection; + + if ( ! name ) { + nameInput.addClass( 'invalid' ); + nameInput.focus(); + return; + } + + menuSection = api.Menus.createNavMenu( name ); + + // Clear name field. + nameInput.val( '' ); + nameInput.removeClass( 'invalid' ); + + wp.a11y.speak( api.Menus.data.l10n.menuAdded ); + + // Focus on the new menu section. + menuSection.focus(); + } + }); + /** * Extends wp.customize.controlConstructor with control constructor for * menu_location, menu_item, nav_menu, and new_menu. @@ -3016,6 +3107,7 @@ nav_menu_item: api.Menus.MenuItemControl, nav_menu: api.Menus.MenuControl, nav_menu_name: api.Menus.MenuNameControl, + new_menu: api.Menus.NewMenuControl, // @todo Remove in 5.0. See #42364. nav_menu_locations: api.Menus.MenuLocationsControl, nav_menu_auto_add: api.Menus.MenuAutoAddControl }); diff --git a/src/wp-includes/class-wp-customize-control.php b/src/wp-includes/class-wp-customize-control.php index 848608139d..4f289cd6e6 100644 --- a/src/wp-includes/class-wp-customize-control.php +++ b/src/wp-includes/class-wp-customize-control.php @@ -769,6 +769,12 @@ require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-location /** * WP_Customize_Nav_Menu_Name_Control class. + * + * As this file is deprecated, it will trigger a deprecation notice if instantiated. In a subsequent + * release, the require_once() here will be removed and _deprecated_file() will be called if file is + * required at all. + * + * @deprecated 4.9.0 This file is no longer used due to new menu creation UX. */ require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-name-control.php' ); diff --git a/src/wp-includes/class-wp-customize-manager.php b/src/wp-includes/class-wp-customize-manager.php index ba2a543312..18be7964b0 100644 --- a/src/wp-includes/class-wp-customize-manager.php +++ b/src/wp-includes/class-wp-customize-manager.php @@ -317,6 +317,7 @@ final class WP_Customize_Manager { require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-name-control.php' ); require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-locations-control.php' ); require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-auto-add-control.php' ); + require_once( ABSPATH . WPINC . '/customize/class-wp-customize-new-menu-control.php' ); // @todo Remove in 5.0. See #42364. require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menus-panel.php' ); @@ -324,6 +325,7 @@ final class WP_Customize_Manager { require_once( ABSPATH . WPINC . '/customize/class-wp-customize-themes-section.php' ); require_once( ABSPATH . WPINC . '/customize/class-wp-customize-sidebar-section.php' ); require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-section.php' ); + require_once( ABSPATH . WPINC . '/customize/class-wp-customize-new-menu-section.php' ); // @todo Remove in 5.0. See #42364. require_once( ABSPATH . WPINC . '/customize/class-wp-customize-custom-css-setting.php' ); require_once( ABSPATH . WPINC . '/customize/class-wp-customize-filter-setting.php' ); diff --git a/src/wp-includes/class-wp-customize-section.php b/src/wp-includes/class-wp-customize-section.php index f4a0d20113..a4a6074afb 100644 --- a/src/wp-includes/class-wp-customize-section.php +++ b/src/wp-includes/class-wp-customize-section.php @@ -385,3 +385,14 @@ require_once( ABSPATH . WPINC . '/customize/class-wp-customize-sidebar-section.p /** WP_Customize_Nav_Menu_Section class */ require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-section.php' ); + +/** + * WP_Customize_New_Menu_Section class + * + * As this file is deprecated, it will trigger a deprecation notice if instantiated. In a subsequent + * release, the require_once() here will be removed and _deprecated_file() will be called if file is + * required at all. + * + * @deprecated 4.9.0 This file is no longer used due to new menu creation UX. + */ +require_once( ABSPATH . WPINC . '/customize/class-wp-customize-new-menu-section.php' ); diff --git a/src/wp-includes/customize/class-wp-customize-new-menu-control.php b/src/wp-includes/customize/class-wp-customize-new-menu-control.php index 24bcb1ea88..9925b59bff 100644 --- a/src/wp-includes/customize/class-wp-customize-new-menu-control.php +++ b/src/wp-includes/customize/class-wp-customize-new-menu-control.php @@ -5,12 +5,14 @@ * @package WordPress * @subpackage Customize * @since 4.4.0 + * @deprecated 4.9.0 This file is no longer used as of the menu creation UX introduced in #40104. */ /** * Customize control class for new menus. * * @since 4.3.0 + * @deprecated 4.9.0 This class is no longer used as of the menu creation UX introduced in #40104. * * @see WP_Customize_Control */ @@ -24,6 +26,20 @@ class WP_Customize_New_Menu_Control extends WP_Customize_Control { */ public $type = 'new_menu'; + /** + * Constructor. + * + * @since 4.9.0 + * + * @param WP_Customize_Manager $manager Manager. + * @param string $id ID. + * @param array $args Args. + */ + public function __construct( WP_Customize_Manager $manager, $id, array $args = array() ) { + _deprecated_file( basename( __FILE__ ), '4.9.0' ); // @todo Move this outside of class in 5.0, and remove its require_once() from class-wp-customize-control.php. See #42364. + parent::__construct( $manager, $id, $args ); + } + /** * Render the control's content. * diff --git a/src/wp-includes/customize/class-wp-customize-new-menu-section.php b/src/wp-includes/customize/class-wp-customize-new-menu-section.php index 12723183c9..e0b9b0c5ad 100644 --- a/src/wp-includes/customize/class-wp-customize-new-menu-section.php +++ b/src/wp-includes/customize/class-wp-customize-new-menu-section.php @@ -5,14 +5,14 @@ * @package WordPress * @subpackage Customize * @since 4.4.0 + * @deprecated 4.9.0 This file is no longer used as of the menu creation UX introduced in #40104. */ /** * Customize Menu Section Class * - * Implements the new-menu-ui toggle button instead of a regular section. - * * @since 4.3.0 + * @deprecated 4.9.0 This class is no longer used as of the menu creation UX introduced in #40104. * * @see WP_Customize_Section */ @@ -26,6 +26,22 @@ class WP_Customize_New_Menu_Section extends WP_Customize_Section { */ public $type = 'new_menu'; + /** + * Constructor. + * + * Any supplied $args override class property defaults. + * + * @since 4.9.0 + * + * @param WP_Customize_Manager $manager Customizer bootstrap instance. + * @param string $id An specific ID of the section. + * @param array $args Section arguments. + */ + public function __construct( WP_Customize_Manager $manager, $id, array $args = array() ) { + _deprecated_file( basename( __FILE__ ), '4.9.0' ); // @todo Move this outside of class in 5.0, and remove its require_once() from class-wp-customize-section.php. See #42364. + parent::__construct( $manager, $id, $args ); + } + /** * Render the section, and the controls that have been added to it. * diff --git a/tests/qunit/wp-admin/js/customize-nav-menus.js b/tests/qunit/wp-admin/js/customize-nav-menus.js index 9b60272875..3ac6da8662 100644 --- a/tests/qunit/wp-admin/js/customize-nav-menus.js +++ b/tests/qunit/wp-admin/js/customize-nav-menus.js @@ -113,9 +113,9 @@ jQuery( window ).load( function (){ // @todo Add tests for api.Menus.MenuLocationsControl // @todo Add tests for api.Menus.MenuAutoAddControl // @todo Add tests for api.Menus.MenuControl - // @todo Add tests for api.Menus.NewMenuControl // @todo Add tests for api.Menus.applySavedData // @todo Add tests for api.Menus.focusMenuItemControl + // @todo Add tests for api.Menus.createNavMenu test( 'api.Menus.getMenuControl() should return the expected control', function() { var control = api.Menus.getMenuControl( primaryMenuId );