mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2026-08-12 04:40:26 +00:00
Customize: Improve the menu creation flow.
Often, folks run into two issues when they create new menus: they click "Add a Menu" thinking it will add a new page to their menu, or they forget to assign their new menu to a location, and then wonder why it doesn't show up on their site. This commit rearranges the order of items in the menu panel, and updates the flow for creating a menu by breaking it up into steps. Additionally, more help text has been added to guide people through the process of creating a menu. Also adds default `type` lookups for Panel and Section instances. See #30741. Props bpayton, obenland, westonruter, celloexpessions, afercia, melchoyce, zoonini, michelleweber. Fixes #40104. git-svn-id: https://develop.svn.wordpress.org/trunk@41768 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
@@ -557,11 +557,16 @@ body.trashing #publish-settings {
|
||||
border-bottom-color: #ddd;
|
||||
}
|
||||
|
||||
#customize-theme-controls .control-panel-content .control-section:nth-child(2),
|
||||
#customize-theme-controls .control-panel-nav_menus .control-section:nth-child(3) {
|
||||
#customize-theme-controls .control-panel-content:not(.control-panel-nav_menus) .control-section:nth-child(2),
|
||||
#customize-theme-controls .control-panel-nav_menus .control-section-nav_menu,
|
||||
#customize-theme-controls .control-section-nav_menu_locations .accordion-section-title {
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
|
||||
#customize-theme-controls .control-panel-nav_menus .control-section-nav_menu + .control-section-nav_menu {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
#customize-theme-controls > ul {
|
||||
margin: 0;
|
||||
}
|
||||
@@ -661,7 +666,8 @@ body.trashing #publish-settings {
|
||||
position: static;
|
||||
}
|
||||
|
||||
.customize-section-description-container {
|
||||
.customize-section-description-container,
|
||||
.control-section-nav_menu .customize-section-description-container {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,22 @@
|
||||
#customize-theme-controls #accordion-section-menu_locations {
|
||||
position: relative;
|
||||
margin-bottom: 15px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
#customize-theme-controls #accordion-section-menu_locations > .accordion-section-title {
|
||||
border-bottom-color: #ddd;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
#customize-theme-controls .customize-section-title-nav_menus-heading,
|
||||
#customize-theme-controls .customize-section-title-menu_locations-heading,
|
||||
#customize-theme-controls .customize-section-title-menu_locations-description {
|
||||
padding: 0 12px 0 12px;
|
||||
}
|
||||
|
||||
#customize-theme-controls .customize-control-description.customize-section-title-menu_locations-description {
|
||||
/* Override the default italic style for control descriptions */
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.menu-in-location,
|
||||
@@ -27,6 +39,23 @@
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
#customize-controls .customize-control-nav_menu_name {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.customize-control-nav_menu_name p:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#customize-new-menu-submit {
|
||||
float: right;
|
||||
min-width: 85px;
|
||||
}
|
||||
|
||||
#customize-new-menu-submit-description {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.wp-customizer .menu-item-bar .menu-item-handle,
|
||||
.wp-customizer .menu-item-settings,
|
||||
.wp-customizer .menu-item-settings .description-thin {
|
||||
@@ -175,12 +204,25 @@
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.menu-settings .customize-control-checkbox label {
|
||||
.wp-customizer .menu-location-settings {
|
||||
margin-top: 12px;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.wp-customizer .control-section-nav_menu .menu-location-settings {
|
||||
margin-top: 24px;
|
||||
border-top: 1px solid #ddd;
|
||||
padding-top: 12px;
|
||||
}
|
||||
|
||||
.menu-settings .customize-control-checkbox label,
|
||||
.menu-location-settings .customize-control-checkbox label {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* @todo update selector or potentially remove */
|
||||
.menu-settings .customize-control.customize-control-checkbox {
|
||||
.menu-settings .customize-control.customize-control-checkbox,
|
||||
.menu-location-settings .customize-control.customize-control-checkbox {
|
||||
margin-bottom: 8px; /* Override collapsing at smaller viewports. */
|
||||
}
|
||||
|
||||
@@ -738,27 +780,16 @@ body.adding-menu-items #customize-preview iframe {
|
||||
/* @todo update selector */
|
||||
#accordion-section-add_menu {
|
||||
margin: 15px 12px;
|
||||
overflow: hidden;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.new-menu-section-content {
|
||||
display: none;
|
||||
padding: 15px 0 0 0;
|
||||
clear: both;
|
||||
#accordion-section-add_menu h3,
|
||||
#accordion-section-add_menu .customize-add-menu-button {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* @todo update selector */
|
||||
#accordion-section-add_menu .accordion-section-title {
|
||||
padding-left: 45px;
|
||||
}
|
||||
|
||||
/* @todo update selector */
|
||||
#accordion-section-add_menu .accordion-section-title:before {
|
||||
font: normal 20px/1 dashicons;
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
left: 14px;
|
||||
content: "\f132";
|
||||
#accordion-section-add_menu .customize-add-menu-button {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#create-new-menu-submit {
|
||||
@@ -772,6 +803,10 @@ body.adding-menu-items #customize-preview iframe {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.assigned-menu-locations-title p {
|
||||
margin: 0 0 8px 0;
|
||||
}
|
||||
|
||||
li.assigned-to-menu-location .menu-delete-item {
|
||||
display: none;
|
||||
}
|
||||
@@ -808,7 +843,12 @@ li.assigned-to-menu-location .add-new-menu-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.customize-control-nav_menu {
|
||||
.customize-control-nav_menu .new-menu-item-invitation {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.customize-control-nav_menu .customize-control-nav_menu-buttons {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
|
||||
@@ -1234,8 +1234,21 @@
|
||||
* @param {object} [options.params] - Deprecated wrapper for the above properties.
|
||||
*/
|
||||
initialize: function ( id, options ) {
|
||||
var section = this;
|
||||
Container.prototype.initialize.call( section, id, options );
|
||||
var section = this, params;
|
||||
params = options.params || options;
|
||||
|
||||
// Look up the type if one was not supplied.
|
||||
if ( ! params.type ) {
|
||||
_.find( api.sectionConstructor, function( Constructor, type ) {
|
||||
if ( Constructor === section.constructor ) {
|
||||
params.type = type;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} );
|
||||
}
|
||||
|
||||
Container.prototype.initialize.call( section, id, params );
|
||||
|
||||
section.id = id;
|
||||
section.panel = new api.Value();
|
||||
@@ -2507,8 +2520,22 @@
|
||||
* @param {object} [options.params] - Deprecated wrapper for the above properties.
|
||||
*/
|
||||
initialize: function ( id, options ) {
|
||||
var panel = this;
|
||||
Container.prototype.initialize.call( panel, id, options );
|
||||
var panel = this, params;
|
||||
params = options.params || options;
|
||||
|
||||
// Look up the type if one was not supplied.
|
||||
if ( ! params.type ) {
|
||||
_.find( api.panelConstructor, function( Constructor, type ) {
|
||||
if ( Constructor === panel.constructor ) {
|
||||
params.type = type;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} );
|
||||
}
|
||||
|
||||
Container.prototype.initialize.call( panel, id, params );
|
||||
|
||||
panel.embed();
|
||||
panel.deferred.embedded.done( function () {
|
||||
panel.ready();
|
||||
@@ -3095,7 +3122,7 @@
|
||||
* @param {string} [options.active=true] - Whether the control is active.
|
||||
* @param {string} options.section - The ID of the section the control belongs to.
|
||||
* @param {mixed} [options.setting] - The ID of the main setting or an instance of this setting.
|
||||
* @param {mixed} options.settings - An object with keys (e.g. default) that maps to setting IDs or Setting/Value objects, or an array of setting IDs or Setting/Value objects.
|
||||
* @param {mixed} options.settings - An object with keys (e.g. default) that maps to setting IDs or Setting/Value objects, or an array of setting IDs or Setting/Value objects.
|
||||
* @param {mixed} options.settings.default - The ID of the setting the control relates to.
|
||||
* @param {string} options.settings.data - @todo Is this used?
|
||||
* @param {string} options.label - Label.
|
||||
@@ -3107,6 +3134,8 @@
|
||||
defaultActiveArguments: { duration: 'fast', completeCallback: $.noop },
|
||||
|
||||
defaults: {
|
||||
label: '',
|
||||
description: '',
|
||||
active: true,
|
||||
priority: 10
|
||||
},
|
||||
|
||||
@@ -811,6 +811,18 @@
|
||||
panel.container.find( '.hide-column-tog' ).click( function() {
|
||||
panel.saveManageColumnsState();
|
||||
});
|
||||
|
||||
// Wait until after construction to patch the UI
|
||||
_.defer( function () {
|
||||
|
||||
panel.contentContainer.find( '#accordion-section-menu_locations' ).prepend(
|
||||
wp.template( 'nav-menu-locations-header' )( api.Menus.data )
|
||||
);
|
||||
|
||||
panel.contentContainer.find( '#accordion-section-add_menu .accordion-section-title' ).replaceWith(
|
||||
wp.template( 'nav-menu-create-menu-section-title' )
|
||||
);
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -961,7 +973,16 @@
|
||||
},
|
||||
|
||||
populateControls: function() {
|
||||
var section = this, menuNameControlId, menuAutoAddControlId, menuControl, menuNameControl, menuAutoAddControl;
|
||||
var section = this,
|
||||
menuNameControlId,
|
||||
menuLocationsControlId,
|
||||
menuAutoAddControlId,
|
||||
menuDeleteControlId,
|
||||
menuControl,
|
||||
menuNameControl,
|
||||
menuLocationsControl,
|
||||
menuAutoAddControl,
|
||||
menuDeleteControl;
|
||||
|
||||
// Add the control for managing the menu name.
|
||||
menuNameControlId = section.id + '[name]';
|
||||
@@ -996,6 +1017,22 @@
|
||||
menuControl.active.set( true );
|
||||
}
|
||||
|
||||
// Add the menu locations control.
|
||||
menuLocationsControlId = section.id + '[locations]';
|
||||
menuLocationsControl = api.control( menuLocationsControlId );
|
||||
if ( ! menuLocationsControl ) {
|
||||
menuLocationsControl = new api.controlConstructor.nav_menu_locations( menuLocationsControlId, {
|
||||
section: section.id,
|
||||
priority: 999,
|
||||
settings: {
|
||||
'default': section.id
|
||||
},
|
||||
menu_id: section.params.menu_id
|
||||
} );
|
||||
api.control.add( menuLocationsControl.id, menuLocationsControl );
|
||||
menuControl.active.set( true );
|
||||
}
|
||||
|
||||
// Add the control for managing the menu auto_add.
|
||||
menuAutoAddControlId = section.id + '[auto_add]';
|
||||
menuAutoAddControl = api.control( menuAutoAddControlId );
|
||||
@@ -1004,7 +1041,7 @@
|
||||
type: 'nav_menu_auto_add',
|
||||
label: '',
|
||||
section: section.id,
|
||||
priority: 999,
|
||||
priority: 1000,
|
||||
settings: {
|
||||
'default': section.id
|
||||
}
|
||||
@@ -1013,6 +1050,25 @@
|
||||
menuAutoAddControl.active.set( true );
|
||||
}
|
||||
|
||||
// Add the control for deleting the menu
|
||||
menuDeleteControlId = section.id + '[delete]';
|
||||
menuDeleteControl = api.control( menuDeleteControlId );
|
||||
if ( ! menuDeleteControl ) {
|
||||
menuDeleteControl = new api.Control( menuDeleteControlId, {
|
||||
section: section.id,
|
||||
priority: 1001,
|
||||
templateId: 'nav-menu-delete-button'
|
||||
} );
|
||||
api.control.add( menuDeleteControl.id, menuDeleteControl );
|
||||
menuDeleteControl.active.set( true );
|
||||
menuDeleteControl.deferred.embedded.done( function () {
|
||||
menuDeleteControl.container.find( 'button' ).on( 'click', function() {
|
||||
var menuId = section.params.menu_id;
|
||||
var menuControl = api.Menus.getMenuControl( menuId );
|
||||
menuControl.setting.set( false );
|
||||
});
|
||||
} );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1093,7 +1149,6 @@
|
||||
* wp.customize.Menus.NewMenuSection
|
||||
*
|
||||
* Customizer section for new menus.
|
||||
* Note that 'new_menu' must match the WP_Customize_New_Menu_Section::$type.
|
||||
*
|
||||
* @constructor
|
||||
* @augments wp.customize.Section
|
||||
@@ -1106,51 +1161,164 @@
|
||||
* @since 4.3.0
|
||||
*/
|
||||
attachEvents: function() {
|
||||
var section = this;
|
||||
this.container.on( 'click', '.add-menu-toggle', function() {
|
||||
if ( section.expanded() ) {
|
||||
section.collapse();
|
||||
} else {
|
||||
section.expand();
|
||||
}
|
||||
var section = this,
|
||||
container = section.container,
|
||||
contentContainer = section.contentContainer;
|
||||
|
||||
/*
|
||||
* We have to manually handle section expanded because we do not
|
||||
* apply the `accordion-section-title` class to this button-driven section.
|
||||
*/
|
||||
container.on( 'click', '.customize-add-menu-button', function() {
|
||||
section.expand();
|
||||
});
|
||||
|
||||
contentContainer.on( 'keydown', '.menu-name-field', function( event ) {
|
||||
if ( 13 === event.which ) { // Enter.
|
||||
section.submit();
|
||||
}
|
||||
} );
|
||||
contentContainer.on( 'click', '#customize-new-menu-submit', function( event ) {
|
||||
section.submit();
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
} );
|
||||
|
||||
api.Section.prototype.attachEvents.apply( this, arguments );
|
||||
},
|
||||
|
||||
/**
|
||||
* Update UI to reflect expanded state.
|
||||
* Set up the control.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @param {Boolean} expanded
|
||||
* @since 4.9.0
|
||||
*/
|
||||
onChangeExpanded: function( expanded ) {
|
||||
ready: function() {
|
||||
this.populateControls();
|
||||
},
|
||||
|
||||
/**
|
||||
* Create the controls for this section.
|
||||
*
|
||||
* @since 4.9.0
|
||||
*/
|
||||
populateControls: function() {
|
||||
var section = this,
|
||||
button = section.container.find( '.add-menu-toggle' ),
|
||||
content = section.contentContainer,
|
||||
customizer = section.headContainer.closest( '.wp-full-overlay-sidebar-content' );
|
||||
if ( expanded ) {
|
||||
button.addClass( 'open' );
|
||||
button.attr( 'aria-expanded', 'true' );
|
||||
content.slideDown( 'fast', function() {
|
||||
customizer.scrollTop( customizer.height() );
|
||||
});
|
||||
} else {
|
||||
button.removeClass( 'open' );
|
||||
button.attr( 'aria-expanded', 'false' );
|
||||
content.slideUp( 'fast' );
|
||||
content.find( '.menu-name-field' ).removeClass( 'invalid' );
|
||||
menuNameControlId,
|
||||
menuLocationsControlId,
|
||||
newMenuSubmitControlId,
|
||||
menuNameControl,
|
||||
menuLocationsControl,
|
||||
newMenuSubmitControl;
|
||||
|
||||
menuNameControlId = section.id + '[name]';
|
||||
menuNameControl = api.control( menuNameControlId );
|
||||
if ( ! menuNameControl ) {
|
||||
menuNameControl = new api.controlConstructor.nav_menu_name( menuNameControlId, {
|
||||
label: api.Menus.data.l10n.menuNameLabel,
|
||||
description: api.Menus.data.l10n.newMenuNameDescription,
|
||||
section: section.id,
|
||||
priority: 0
|
||||
} );
|
||||
api.control.add( menuNameControl.id, menuNameControl );
|
||||
menuNameControl.active.set( true );
|
||||
}
|
||||
|
||||
menuLocationsControlId = section.id + '[locations]';
|
||||
menuLocationsControl = api.control( menuLocationsControlId );
|
||||
if ( ! menuLocationsControl ) {
|
||||
menuLocationsControl = new api.controlConstructor.nav_menu_locations( menuLocationsControlId, {
|
||||
section: section.id,
|
||||
priority: 1,
|
||||
menu_id: ''
|
||||
} );
|
||||
api.control.add( menuLocationsControlId, menuLocationsControl );
|
||||
menuLocationsControl.active.set( true );
|
||||
}
|
||||
|
||||
newMenuSubmitControlId = section.id + '[submit]';
|
||||
newMenuSubmitControl = api.control( newMenuSubmitControlId );
|
||||
if ( !newMenuSubmitControl ) {
|
||||
newMenuSubmitControl = new api.Control( newMenuSubmitControlId, {
|
||||
section: section.id,
|
||||
priority: 1,
|
||||
templateId: 'nav-menu-submit-new-button'
|
||||
} );
|
||||
api.control.add( newMenuSubmitControlId, newMenuSubmitControl );
|
||||
newMenuSubmitControl.active.set( true );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Find the content element.
|
||||
* Create the new menu with name and location supplied by the user.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @returns {jQuery} Content UL element.
|
||||
* @since 4.9.0
|
||||
*/
|
||||
getContent: function() {
|
||||
return this.container.find( 'ul:first' );
|
||||
submit: function() {
|
||||
var section = this,
|
||||
contentContainer = section.contentContainer,
|
||||
nameInput = contentContainer.find( '.menu-name-field' ).first(),
|
||||
name = nameInput.val(),
|
||||
menuSection,
|
||||
customizeId,
|
||||
placeholderId = api.Menus.generatePlaceholderAutoIncrementId();
|
||||
|
||||
if ( ! name ) {
|
||||
nameInput.addClass( 'invalid' );
|
||||
nameInput.focus();
|
||||
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 );
|
||||
|
||||
// Clear name field.
|
||||
nameInput.val( '' );
|
||||
nameInput.removeClass( 'invalid' );
|
||||
|
||||
contentContainer.find( '.assigned-menu-location input[type=checkbox]' ).each( function() {
|
||||
var checkbox = $( this ),
|
||||
navMenuLocationSetting;
|
||||
|
||||
if ( checkbox.prop( 'checked' ) ) {
|
||||
navMenuLocationSetting = api( 'nav_menu_locations[' + checkbox.data( 'location-id' ) + ']' );
|
||||
navMenuLocationSetting.set( placeholderId );
|
||||
|
||||
// Reset state for next new menu
|
||||
checkbox.prop( 'checked', false );
|
||||
}
|
||||
} );
|
||||
|
||||
wp.a11y.speak( api.Menus.data.l10n.menuAdded );
|
||||
|
||||
// Focus on the new menu section.
|
||||
api.section( customizeId ).focus(); // @todo should we focus on the new menu's control and open the add-items panel? Thinking user flow...
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1512,6 +1680,8 @@
|
||||
wp.a11y.speak( api.Menus.data.l10n.itemDeleted );
|
||||
$adjacentFocusTarget.focus(); // keyboard accessibility
|
||||
} );
|
||||
|
||||
control.setting.set( false );
|
||||
} );
|
||||
},
|
||||
|
||||
@@ -2034,45 +2204,88 @@
|
||||
api.Menus.MenuNameControl = api.Control.extend({
|
||||
|
||||
ready: function() {
|
||||
var control = this,
|
||||
settingValue = control.setting();
|
||||
var control = this;
|
||||
|
||||
/*
|
||||
* Since the control is not registered in PHP, we need to prevent the
|
||||
* preview's sending of the activeControls to result in this control
|
||||
* being deactivated.
|
||||
*/
|
||||
control.active.validate = function() {
|
||||
var value, section = api.section( control.section() );
|
||||
if ( section ) {
|
||||
value = section.active();
|
||||
} else {
|
||||
value = false;
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
control.nameElement = new api.Element( control.container.find( '.menu-name-field' ) );
|
||||
|
||||
control.nameElement.bind(function( value ) {
|
||||
if ( control.setting ) {
|
||||
var settingValue = control.setting();
|
||||
if ( settingValue && settingValue.name !== value ) {
|
||||
settingValue = _.clone( settingValue );
|
||||
settingValue.name = value;
|
||||
control.setting.set( settingValue );
|
||||
}
|
||||
});
|
||||
if ( settingValue ) {
|
||||
control.nameElement.set( settingValue.name );
|
||||
}
|
||||
|
||||
control.setting.bind(function( object ) {
|
||||
if ( object ) {
|
||||
control.nameElement.set( object.name );
|
||||
control.nameElement = new api.Element( control.container.find( '.menu-name-field' ) );
|
||||
|
||||
control.nameElement.bind(function( value ) {
|
||||
var settingValue = control.setting();
|
||||
if ( settingValue && settingValue.name !== value ) {
|
||||
settingValue = _.clone( settingValue );
|
||||
settingValue.name = value;
|
||||
control.setting.set( settingValue );
|
||||
}
|
||||
});
|
||||
if ( settingValue ) {
|
||||
control.nameElement.set( settingValue.name );
|
||||
}
|
||||
|
||||
control.setting.bind(function( object ) {
|
||||
if ( object ) {
|
||||
control.nameElement.set( object.name );
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* wp.customize.Menus.MenuLocationsControl
|
||||
*
|
||||
* Customizer control for a nav menu's locations.
|
||||
*
|
||||
* @since 4.9.0
|
||||
* @constructor
|
||||
* @augments wp.customize.Control
|
||||
*/
|
||||
api.Menus.MenuLocationsControl = api.Control.extend({
|
||||
|
||||
/**
|
||||
* Set up the control.
|
||||
*
|
||||
* @since 4.9.0
|
||||
*/
|
||||
ready: function () {
|
||||
var control = this;
|
||||
|
||||
control.container.find( '.assigned-menu-location' ).each(function() {
|
||||
var container = $( this ),
|
||||
checkbox = container.find( 'input[type=checkbox]' ),
|
||||
element = new api.Element( checkbox ),
|
||||
navMenuLocationSetting = api( 'nav_menu_locations[' + checkbox.data( 'location-id' ) + ']' ),
|
||||
isNewMenu = control.params.menu_id === '',
|
||||
updateCheckbox = isNewMenu ? _.noop : function( checked ) {
|
||||
element.set( checked );
|
||||
},
|
||||
updateSetting = isNewMenu ? _.noop : function( checked ) {
|
||||
navMenuLocationSetting.set( checked ? control.params.menu_id : 0 );
|
||||
},
|
||||
updateSelectedMenuLabel = function( selectedMenuId ) {
|
||||
var menuSetting = api( 'nav_menu[' + String( selectedMenuId ) + ']' );
|
||||
if ( ! selectedMenuId || ! menuSetting || ! menuSetting() ) {
|
||||
container.find( '.theme-location-set' ).hide();
|
||||
} else {
|
||||
container.find( '.theme-location-set' ).show().find( 'span' ).text( displayNavMenuName( menuSetting().name ) );
|
||||
}
|
||||
};
|
||||
|
||||
updateCheckbox( navMenuLocationSetting.get() === control.params.menu_id );
|
||||
|
||||
checkbox.on( 'change', function() {
|
||||
// Note: We can't use element.bind( function( checked ){ ... } ) here because it will trigger a change as well.
|
||||
updateSetting( this.checked );
|
||||
} );
|
||||
|
||||
navMenuLocationSetting.bind( function( selectedMenuId ) {
|
||||
updateCheckbox( selectedMenuId === control.params.menu_id );
|
||||
updateSelectedMenuLabel( selectedMenuId );
|
||||
} );
|
||||
updateSelectedMenuLabel( navMenuLocationSetting.get() );
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -2180,7 +2393,6 @@
|
||||
} );
|
||||
|
||||
this._setupAddition();
|
||||
this._setupLocations();
|
||||
this._setupTitle();
|
||||
|
||||
// Add menu to Custom Menu widgets.
|
||||
@@ -2210,6 +2422,15 @@
|
||||
select.append( new Option( name, menuId ) );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for menu items to be added.
|
||||
* Ideally, we'd bind to an event indicating construction is complete,
|
||||
* but deferring appears to be the best option today.
|
||||
*/
|
||||
_.defer( function () {
|
||||
control.updateInvitationVisibility();
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -2235,11 +2456,6 @@
|
||||
});
|
||||
}
|
||||
} );
|
||||
|
||||
control.container.find( '.menu-delete-item .button-link-delete' ).on( 'click', function( event ) {
|
||||
event.preventDefault();
|
||||
control.setting.set( false );
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -2393,43 +2609,6 @@
|
||||
widgetTemplate.find( 'option[value=' + String( menuId ) + ']' ).remove();
|
||||
},
|
||||
|
||||
// Setup theme location checkboxes.
|
||||
_setupLocations: function() {
|
||||
var control = this;
|
||||
|
||||
control.container.find( '.assigned-menu-location' ).each(function() {
|
||||
var container = $( this ),
|
||||
checkbox = container.find( 'input[type=checkbox]' ),
|
||||
element,
|
||||
updateSelectedMenuLabel,
|
||||
navMenuLocationSetting = api( 'nav_menu_locations[' + checkbox.data( 'location-id' ) + ']' );
|
||||
|
||||
updateSelectedMenuLabel = function( selectedMenuId ) {
|
||||
var menuSetting = api( 'nav_menu[' + String( selectedMenuId ) + ']' );
|
||||
if ( ! selectedMenuId || ! menuSetting || ! menuSetting() ) {
|
||||
container.find( '.theme-location-set' ).hide();
|
||||
} else {
|
||||
container.find( '.theme-location-set' ).show().find( 'span' ).text( displayNavMenuName( menuSetting().name ) );
|
||||
}
|
||||
};
|
||||
|
||||
element = new api.Element( checkbox );
|
||||
element.set( navMenuLocationSetting.get() === control.params.menu_id );
|
||||
|
||||
checkbox.on( 'change', function() {
|
||||
// Note: We can't use element.bind( function( checked ){ ... } ) here because it will trigger a change as well.
|
||||
navMenuLocationSetting.set( this.checked ? control.params.menu_id : 0 );
|
||||
} );
|
||||
|
||||
navMenuLocationSetting.bind(function( selectedMenuId ) {
|
||||
element.set( selectedMenuId === control.params.menu_id );
|
||||
updateSelectedMenuLabel( selectedMenuId );
|
||||
});
|
||||
updateSelectedMenuLabel( navMenuLocationSetting.get() );
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Update Section Title as menu name is changed.
|
||||
*/
|
||||
@@ -2607,6 +2786,7 @@
|
||||
currentAbsolutePosition: 0
|
||||
} );
|
||||
|
||||
menuControl.updateInvitationVisibility( menuItemControls );
|
||||
menuControl.container.find( '.reorder-toggle' ).toggle( menuItemControls.length > 1 );
|
||||
},
|
||||
|
||||
@@ -2681,103 +2861,22 @@
|
||||
wp.a11y.speak( api.Menus.data.l10n.itemAdded );
|
||||
|
||||
return menuItemControl;
|
||||
},
|
||||
|
||||
/**
|
||||
* Show an invitation to add new menu items when there are no menu items.
|
||||
*
|
||||
* @since 4.9.0
|
||||
*
|
||||
* @param {wp.customize.controlConstructor.nav_menu_item[]} optionalMenuItemControls
|
||||
*/
|
||||
updateInvitationVisibility: function ( optionalMenuItemControls ) {
|
||||
var menuItemControls = optionalMenuItemControls || this.getMenuItemControls();
|
||||
|
||||
this.container.find( '.new-menu-item-invitation' ).toggle( menuItemControls.length === 0 );
|
||||
}
|
||||
} );
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
api.Menus.NewMenuControl = api.Control.extend({
|
||||
/**
|
||||
* Set up the control.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
submit: function() {
|
||||
|
||||
var control = this,
|
||||
container = control.container.closest( '.accordion-section-new-menu' ),
|
||||
nameInput = container.find( '.menu-name-field' ).first(),
|
||||
name = nameInput.val(),
|
||||
menuSection,
|
||||
customizeId,
|
||||
placeholderId = api.Menus.generatePlaceholderAutoIncrementId();
|
||||
|
||||
if ( ! name ) {
|
||||
nameInput.addClass( 'invalid' );
|
||||
nameInput.focus();
|
||||
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,
|
||||
type: 'nav_menu',
|
||||
priority: 10,
|
||||
menu_id: placeholderId
|
||||
} );
|
||||
api.section.add( menuSection );
|
||||
|
||||
// Clear name field.
|
||||
nameInput.val( '' );
|
||||
nameInput.removeClass( 'invalid' );
|
||||
|
||||
wp.a11y.speak( api.Menus.data.l10n.menuAdded );
|
||||
|
||||
// Focus on the new menu section.
|
||||
api.section( customizeId ).focus(); // @todo should we focus on the new menu's control and open the add-items panel? Thinking user flow...
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Extends wp.customize.controlConstructor with control constructor for
|
||||
* menu_location, menu_item, nav_menu, and new_menu.
|
||||
@@ -2787,8 +2886,8 @@
|
||||
nav_menu_item: api.Menus.MenuItemControl,
|
||||
nav_menu: api.Menus.MenuControl,
|
||||
nav_menu_name: api.Menus.MenuNameControl,
|
||||
nav_menu_auto_add: api.Menus.MenuAutoAddControl,
|
||||
new_menu: api.Menus.NewMenuControl
|
||||
nav_menu_locations: api.Menus.MenuLocationsControl,
|
||||
nav_menu_auto_add: api.Menus.MenuAutoAddControl
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user