WordPress.org

Make WordPress Core

Changeset 41768


Ignore:
Timestamp:
10/05/17 02:21:22 (2 months ago)
Author:
westonruter
Message:

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.

Location:
trunk
Files:
1 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/css/customize-controls.css

    r41750 r41768  
    558558} 
    559559 
    560 #customize-theme-controls .control-panel-content .control-section:nth-child(2), 
    561 #customize-theme-controls .control-panel-nav_menus .control-section:nth-child(3) { 
     560#customize-theme-controls .control-panel-content:not(.control-panel-nav_menus) .control-section:nth-child(2), 
     561#customize-theme-controls .control-panel-nav_menus .control-section-nav_menu, 
     562#customize-theme-controls .control-section-nav_menu_locations .accordion-section-title { 
    562563    border-top: 1px solid #ddd; 
     564} 
     565 
     566#customize-theme-controls .control-panel-nav_menus .control-section-nav_menu + .control-section-nav_menu { 
     567    border-top: none; 
    563568} 
    564569 
     
    662667} 
    663668 
    664 .customize-section-description-container { 
     669.customize-section-description-container, 
     670.control-section-nav_menu .customize-section-description-container { 
    665671    margin-bottom: 15px; 
    666672} 
  • trunk/src/wp-admin/css/customize-nav-menus.css

    r41711 r41768  
    11#customize-theme-controls #accordion-section-menu_locations { 
    22    position: relative; 
    3     margin-bottom: 15px; 
     3    margin-top: 15px; 
    44} 
    55 
    66#customize-theme-controls #accordion-section-menu_locations > .accordion-section-title { 
    77    border-bottom-color: #ddd; 
     8    margin-top: 15px; 
     9} 
     10 
     11#customize-theme-controls .customize-section-title-nav_menus-heading, 
     12#customize-theme-controls .customize-section-title-menu_locations-heading, 
     13#customize-theme-controls .customize-section-title-menu_locations-description { 
     14    padding: 0 12px 0 12px; 
     15} 
     16 
     17#customize-theme-controls .customize-control-description.customize-section-title-menu_locations-description { 
     18    /* Override the default italic style for control descriptions */ 
     19    font-style: normal; 
    820} 
    921 
     
    2638    vertical-align: middle; 
    2739    line-height: 28px; 
     40} 
     41 
     42#customize-controls .customize-control-nav_menu_name { 
     43    margin-bottom: 12px; 
     44} 
     45 
     46.customize-control-nav_menu_name p:last-of-type { 
     47    margin-bottom: 0; 
     48} 
     49 
     50#customize-new-menu-submit { 
     51    float: right; 
     52    min-width: 85px; 
     53} 
     54 
     55#customize-new-menu-submit-description { 
     56    margin: 0; 
    2857} 
    2958 
     
    176205} 
    177206 
    178 .menu-settings .customize-control-checkbox label { 
     207.wp-customizer .menu-location-settings { 
     208    margin-top: 12px; 
     209    border-top: none; 
     210} 
     211 
     212.wp-customizer .control-section-nav_menu .menu-location-settings { 
     213    margin-top: 24px; 
     214    border-top: 1px solid #ddd; 
     215    padding-top: 12px; 
     216} 
     217 
     218.menu-settings .customize-control-checkbox label, 
     219.menu-location-settings .customize-control-checkbox label { 
    179220    line-height: 1; 
    180221} 
    181222 
    182223/* @todo update selector or potentially remove */ 
    183 .menu-settings .customize-control.customize-control-checkbox { 
     224.menu-settings .customize-control.customize-control-checkbox, 
     225.menu-location-settings .customize-control.customize-control-checkbox { 
    184226    margin-bottom: 8px; /* Override collapsing at smaller viewports. */ 
    185227} 
     
    739781#accordion-section-add_menu { 
    740782    margin: 15px 12px; 
    741     overflow: hidden; 
    742 } 
    743  
    744 .new-menu-section-content { 
    745     display: none; 
    746     padding: 15px 0 0 0; 
    747     clear: both; 
    748 } 
    749  
    750 /* @todo update selector */ 
    751 #accordion-section-add_menu .accordion-section-title { 
    752     padding-left: 45px; 
    753 } 
    754  
    755 /* @todo update selector */ 
    756 #accordion-section-add_menu .accordion-section-title:before { 
    757     font: normal 20px/1 dashicons; 
    758     position: absolute; 
    759     top: 12px; 
    760     left: 14px; 
    761     content: "\f132"; 
     783    text-align: right; 
     784} 
     785 
     786#accordion-section-add_menu h3, 
     787#accordion-section-add_menu .customize-add-menu-button { 
     788    margin: 0; 
     789} 
     790 
     791#accordion-section-add_menu .customize-add-menu-button { 
     792    font-weight: normal; 
    762793} 
    763794 
     
    773804} 
    774805 
     806.assigned-menu-locations-title p { 
     807    margin: 0 0 8px 0; 
     808} 
     809 
    775810li.assigned-to-menu-location .menu-delete-item { 
    776811    display: none; 
     
    809844} 
    810845 
    811 .customize-control-nav_menu { 
     846.customize-control-nav_menu .new-menu-item-invitation { 
     847    margin-top: 0; 
     848    margin-bottom: 0; 
     849} 
     850 
     851.customize-control-nav_menu .customize-control-nav_menu-buttons { 
    812852    margin-top: 12px; 
    813853} 
  • trunk/src/wp-admin/js/customize-controls.js

    r41750 r41768  
    12351235         */ 
    12361236        initialize: function ( id, options ) { 
    1237             var section = this; 
    1238             Container.prototype.initialize.call( section, id, options ); 
     1237            var section = this, params; 
     1238            params = options.params || options; 
     1239 
     1240            // Look up the type if one was not supplied. 
     1241            if ( ! params.type ) { 
     1242                _.find( api.sectionConstructor, function( Constructor, type ) { 
     1243                    if ( Constructor === section.constructor ) { 
     1244                        params.type = type; 
     1245                        return true; 
     1246                    } 
     1247                    return false; 
     1248                } ); 
     1249            } 
     1250 
     1251            Container.prototype.initialize.call( section, id, params ); 
    12391252 
    12401253            section.id = id; 
     
    25082521         */ 
    25092522        initialize: function ( id, options ) { 
    2510             var panel = this; 
    2511             Container.prototype.initialize.call( panel, id, options ); 
     2523            var panel = this, params; 
     2524            params = options.params || options; 
     2525 
     2526            // Look up the type if one was not supplied. 
     2527            if ( ! params.type ) { 
     2528                _.find( api.panelConstructor, function( Constructor, type ) { 
     2529                    if ( Constructor === panel.constructor ) { 
     2530                        params.type = type; 
     2531                        return true; 
     2532                    } 
     2533                    return false; 
     2534                } ); 
     2535            } 
     2536 
     2537            Container.prototype.initialize.call( panel, id, params ); 
     2538 
    25122539            panel.embed(); 
    25132540            panel.deferred.embedded.done( function () { 
     
    30963123     * @param {string} options.section          - The ID of the section the control belongs to. 
    30973124     * @param {mixed}  [options.setting]        - The ID of the main setting or an instance of this setting. 
    3098      * @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.     
     3125     * @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. 
    30993126     * @param {mixed}  options.settings.default - The ID of the setting the control relates to. 
    31003127     * @param {string} options.settings.data    - @todo Is this used? 
     
    31083135 
    31093136        defaults: { 
     3137            label: '', 
     3138            description: '', 
    31103139            active: true, 
    31113140            priority: 10 
  • trunk/src/wp-admin/js/customize-nav-menus.js

    r41726 r41768  
    812812                panel.saveManageColumnsState(); 
    813813            }); 
     814 
     815            // Wait until after construction to patch the UI 
     816            _.defer( function () { 
     817 
     818                panel.contentContainer.find( '#accordion-section-menu_locations' ).prepend( 
     819                    wp.template( 'nav-menu-locations-header' )( api.Menus.data ) 
     820                ); 
     821 
     822                panel.contentContainer.find( '#accordion-section-add_menu .accordion-section-title' ).replaceWith( 
     823                    wp.template( 'nav-menu-create-menu-section-title' ) 
     824                ); 
     825            } ); 
    814826        }, 
    815827 
     
    962974 
    963975        populateControls: function() { 
    964             var section = this, menuNameControlId, menuAutoAddControlId, menuControl, menuNameControl, menuAutoAddControl; 
     976            var section = this, 
     977                menuNameControlId, 
     978                menuLocationsControlId, 
     979                menuAutoAddControlId, 
     980                menuDeleteControlId, 
     981                menuControl, 
     982                menuNameControl, 
     983                menuLocationsControl, 
     984                menuAutoAddControl, 
     985                menuDeleteControl; 
    965986 
    966987            // Add the control for managing the menu name. 
     
    9971018            } 
    9981019 
     1020            // Add the menu locations control. 
     1021            menuLocationsControlId = section.id + '[locations]'; 
     1022            menuLocationsControl = api.control( menuLocationsControlId ); 
     1023            if ( ! menuLocationsControl ) { 
     1024                menuLocationsControl = new api.controlConstructor.nav_menu_locations( menuLocationsControlId, { 
     1025                    section: section.id, 
     1026                    priority: 999, 
     1027                    settings: { 
     1028                        'default': section.id 
     1029                    }, 
     1030                    menu_id: section.params.menu_id 
     1031                } ); 
     1032                api.control.add( menuLocationsControl.id, menuLocationsControl ); 
     1033                menuControl.active.set( true ); 
     1034            } 
     1035 
    9991036            // Add the control for managing the menu auto_add. 
    10001037            menuAutoAddControlId = section.id + '[auto_add]'; 
     
    10051042                    label: '', 
    10061043                    section: section.id, 
    1007                     priority: 999, 
     1044                    priority: 1000, 
    10081045                    settings: { 
    10091046                        'default': section.id 
     
    10141051            } 
    10151052 
     1053            // Add the control for deleting the menu 
     1054            menuDeleteControlId = section.id + '[delete]'; 
     1055            menuDeleteControl = api.control( menuDeleteControlId ); 
     1056            if ( ! menuDeleteControl ) { 
     1057                menuDeleteControl = new api.Control( menuDeleteControlId, { 
     1058                    section: section.id, 
     1059                    priority: 1001, 
     1060                    templateId: 'nav-menu-delete-button' 
     1061                } ); 
     1062                api.control.add( menuDeleteControl.id, menuDeleteControl ); 
     1063                menuDeleteControl.active.set( true ); 
     1064                menuDeleteControl.deferred.embedded.done( function () { 
     1065                    menuDeleteControl.container.find( 'button' ).on( 'click', function() { 
     1066                        var menuId = section.params.menu_id; 
     1067                        var menuControl = api.Menus.getMenuControl( menuId ); 
     1068                        menuControl.setting.set( false ); 
     1069                    }); 
     1070                } ); 
     1071            } 
    10161072        }, 
    10171073 
     
    10941150     * 
    10951151     * Customizer section for new menus. 
    1096      * Note that 'new_menu' must match the WP_Customize_New_Menu_Section::$type. 
    10971152     * 
    10981153     * @constructor 
     
    11071162         */ 
    11081163        attachEvents: function() { 
    1109             var section = this; 
    1110             this.container.on( 'click', '.add-menu-toggle', function() { 
    1111                 if ( section.expanded() ) { 
    1112                     section.collapse(); 
    1113                 } else { 
    1114                     section.expand(); 
    1115                 } 
    1116             }); 
    1117         }, 
    1118  
    1119         /** 
    1120          * Update UI to reflect expanded state. 
    1121          * 
    1122          * @since 4.1.0 
    1123          * 
    1124          * @param {Boolean} expanded 
    1125          */ 
    1126         onChangeExpanded: function( expanded ) { 
    11271164            var section = this, 
    1128                 button = section.container.find( '.add-menu-toggle' ), 
    1129                 content = section.contentContainer, 
    1130                 customizer = section.headContainer.closest( '.wp-full-overlay-sidebar-content' ); 
    1131             if ( expanded ) { 
    1132                 button.addClass( 'open' ); 
    1133                 button.attr( 'aria-expanded', 'true' ); 
    1134                 content.slideDown( 'fast', function() { 
    1135                     customizer.scrollTop( customizer.height() ); 
    1136                 }); 
    1137             } else { 
    1138                 button.removeClass( 'open' ); 
    1139                 button.attr( 'aria-expanded', 'false' ); 
    1140                 content.slideUp( 'fast' ); 
    1141                 content.find( '.menu-name-field' ).removeClass( 'invalid' ); 
    1142             } 
    1143         }, 
    1144  
    1145         /** 
    1146          * Find the content element. 
    1147          * 
    1148          * @since 4.7.0 
    1149          * 
    1150          * @returns {jQuery} Content UL element. 
    1151          */ 
    1152         getContent: function() { 
    1153             return this.container.find( 'ul:first' ); 
     1165                container = section.container, 
     1166                contentContainer = section.contentContainer; 
     1167 
     1168            /* 
     1169             * We have to manually handle section expanded because we do not 
     1170             * apply the `accordion-section-title` class to this button-driven section. 
     1171             */ 
     1172            container.on( 'click', '.customize-add-menu-button', function() { 
     1173                section.expand(); 
     1174            }); 
     1175 
     1176            contentContainer.on( 'keydown', '.menu-name-field', function( event ) { 
     1177                if ( 13 === event.which ) { // Enter. 
     1178                    section.submit(); 
     1179                } 
     1180            } ); 
     1181            contentContainer.on( 'click', '#customize-new-menu-submit', function( event ) { 
     1182                section.submit(); 
     1183                event.stopPropagation(); 
     1184                event.preventDefault(); 
     1185            } ); 
     1186 
     1187            api.Section.prototype.attachEvents.apply( this, arguments ); 
     1188        }, 
     1189 
     1190        /** 
     1191         * Set up the control. 
     1192         * 
     1193         * @since 4.9.0 
     1194         */ 
     1195        ready: function() { 
     1196            this.populateControls(); 
     1197        }, 
     1198 
     1199        /** 
     1200         * Create the controls for this section. 
     1201         * 
     1202         * @since 4.9.0 
     1203         */ 
     1204        populateControls: function() { 
     1205            var section = this, 
     1206                menuNameControlId, 
     1207                menuLocationsControlId, 
     1208                newMenuSubmitControlId, 
     1209                menuNameControl, 
     1210                menuLocationsControl, 
     1211                newMenuSubmitControl; 
     1212 
     1213            menuNameControlId = section.id + '[name]'; 
     1214            menuNameControl = api.control( menuNameControlId ); 
     1215            if ( ! menuNameControl ) { 
     1216                menuNameControl = new api.controlConstructor.nav_menu_name( menuNameControlId, { 
     1217                    label: api.Menus.data.l10n.menuNameLabel, 
     1218                    description: api.Menus.data.l10n.newMenuNameDescription, 
     1219                    section: section.id, 
     1220                    priority: 0 
     1221                } ); 
     1222                api.control.add( menuNameControl.id, menuNameControl ); 
     1223                menuNameControl.active.set( true ); 
     1224            } 
     1225 
     1226            menuLocationsControlId = section.id + '[locations]'; 
     1227            menuLocationsControl = api.control( menuLocationsControlId ); 
     1228            if ( ! menuLocationsControl ) { 
     1229                menuLocationsControl = new api.controlConstructor.nav_menu_locations( menuLocationsControlId, { 
     1230                    section: section.id, 
     1231                    priority: 1, 
     1232                    menu_id: '' 
     1233                } ); 
     1234                api.control.add( menuLocationsControlId, menuLocationsControl ); 
     1235                menuLocationsControl.active.set( true ); 
     1236            } 
     1237 
     1238            newMenuSubmitControlId = section.id + '[submit]'; 
     1239            newMenuSubmitControl = api.control( newMenuSubmitControlId ); 
     1240            if ( !newMenuSubmitControl ) { 
     1241                newMenuSubmitControl = new api.Control( newMenuSubmitControlId, { 
     1242                    section: section.id, 
     1243                    priority: 1, 
     1244                    templateId: 'nav-menu-submit-new-button' 
     1245                } ); 
     1246                api.control.add( newMenuSubmitControlId, newMenuSubmitControl ); 
     1247                newMenuSubmitControl.active.set( true ); 
     1248            } 
     1249        }, 
     1250 
     1251        /** 
     1252         * Create the new menu with name and location supplied by the user. 
     1253         * 
     1254         * @since 4.9.0 
     1255         */ 
     1256        submit: function() { 
     1257            var section = this, 
     1258                contentContainer = section.contentContainer, 
     1259                nameInput = contentContainer.find( '.menu-name-field' ).first(), 
     1260                name = nameInput.val(), 
     1261                menuSection, 
     1262                customizeId, 
     1263                placeholderId = api.Menus.generatePlaceholderAutoIncrementId(); 
     1264 
     1265            if ( ! name ) { 
     1266                nameInput.addClass( 'invalid' ); 
     1267                nameInput.focus(); 
     1268                return; 
     1269            } 
     1270 
     1271            customizeId = 'nav_menu[' + String( placeholderId ) + ']'; 
     1272 
     1273            // Register the menu control setting. 
     1274            api.create( customizeId, customizeId, {}, { 
     1275                type: 'nav_menu', 
     1276                transport: api.Menus.data.settingTransport, 
     1277                previewer: api.previewer 
     1278            } ); 
     1279            api( customizeId ).set( $.extend( 
     1280                {}, 
     1281                api.Menus.data.defaultSettingValues.nav_menu, 
     1282                { 
     1283                    name: name 
     1284                } 
     1285            ) ); 
     1286 
     1287            /* 
     1288             * Add the menu section (and its controls). 
     1289             * Note that this will automatically create the required controls 
     1290             * inside via the Section's ready method. 
     1291             */ 
     1292            menuSection = new api.Menus.MenuSection( customizeId, { 
     1293                panel: 'nav_menus', 
     1294                title: displayNavMenuName( name ), 
     1295                customizeAction: api.Menus.data.l10n.customizingMenus, 
     1296                priority: 10, 
     1297                menu_id: placeholderId 
     1298            } ); 
     1299            api.section.add( customizeId, menuSection ); 
     1300 
     1301            // Clear name field. 
     1302            nameInput.val( '' ); 
     1303            nameInput.removeClass( 'invalid' ); 
     1304 
     1305            contentContainer.find( '.assigned-menu-location input[type=checkbox]' ).each( function() { 
     1306                var checkbox = $( this ), 
     1307                navMenuLocationSetting; 
     1308 
     1309                if ( checkbox.prop( 'checked' ) ) { 
     1310                    navMenuLocationSetting = api( 'nav_menu_locations[' + checkbox.data( 'location-id' ) + ']' ); 
     1311                    navMenuLocationSetting.set( placeholderId ); 
     1312 
     1313                    // Reset state for next new menu 
     1314                    checkbox.prop( 'checked', false ); 
     1315                } 
     1316            } ); 
     1317 
     1318            wp.a11y.speak( api.Menus.data.l10n.menuAdded ); 
     1319 
     1320            // Focus on the new menu section. 
     1321            api.section( customizeId ).focus(); // @todo should we focus on the new menu's control and open the add-items panel? Thinking user flow... 
    11541322        } 
    11551323    }); 
     
    15131681                    $adjacentFocusTarget.focus(); // keyboard accessibility 
    15141682                } ); 
     1683 
     1684                control.setting.set( false ); 
    15151685            } ); 
    15161686        }, 
     
    20352205 
    20362206        ready: function() { 
     2207            var control = this; 
     2208 
     2209            if ( control.setting ) { 
     2210                var settingValue = control.setting(); 
     2211 
     2212                control.nameElement = new api.Element( control.container.find( '.menu-name-field' ) ); 
     2213 
     2214                control.nameElement.bind(function( value ) { 
     2215                    var settingValue = control.setting(); 
     2216                    if ( settingValue && settingValue.name !== value ) { 
     2217                        settingValue = _.clone( settingValue ); 
     2218                        settingValue.name = value; 
     2219                        control.setting.set( settingValue ); 
     2220                    } 
     2221                }); 
     2222                if ( settingValue ) { 
     2223                    control.nameElement.set( settingValue.name ); 
     2224                } 
     2225 
     2226                control.setting.bind(function( object ) { 
     2227                    if ( object ) { 
     2228                        control.nameElement.set( object.name ); 
     2229                    } 
     2230                }); 
     2231            } 
     2232        } 
     2233    }); 
     2234 
     2235    /** 
     2236     * wp.customize.Menus.MenuLocationsControl 
     2237     * 
     2238     * Customizer control for a nav menu's locations. 
     2239     * 
     2240     * @since 4.9.0 
     2241     * @constructor 
     2242     * @augments wp.customize.Control 
     2243     */ 
     2244    api.Menus.MenuLocationsControl = api.Control.extend({ 
     2245 
     2246        /** 
     2247         * Set up the control. 
     2248         * 
     2249         * @since 4.9.0 
     2250         */ 
     2251        ready: function () { 
     2252            var control = this; 
     2253 
     2254            control.container.find( '.assigned-menu-location' ).each(function() { 
     2255                var container = $( this ), 
     2256                    checkbox = container.find( 'input[type=checkbox]' ), 
     2257                    element = new api.Element( checkbox ), 
     2258                    navMenuLocationSetting = api( 'nav_menu_locations[' + checkbox.data( 'location-id' ) + ']' ), 
     2259                    isNewMenu = control.params.menu_id === '', 
     2260                    updateCheckbox = isNewMenu ? _.noop : function( checked ) { 
     2261                        element.set( checked ); 
     2262                    }, 
     2263                    updateSetting = isNewMenu ? _.noop : function( checked ) { 
     2264                        navMenuLocationSetting.set( checked ? control.params.menu_id : 0 ); 
     2265                    }, 
     2266                    updateSelectedMenuLabel = function( selectedMenuId ) { 
     2267                        var menuSetting = api( 'nav_menu[' + String( selectedMenuId ) + ']' ); 
     2268                        if ( ! selectedMenuId || ! menuSetting || ! menuSetting() ) { 
     2269                            container.find( '.theme-location-set' ).hide(); 
     2270                        } else { 
     2271                            container.find( '.theme-location-set' ).show().find( 'span' ).text( displayNavMenuName( menuSetting().name ) ); 
     2272                        } 
     2273                    }; 
     2274 
     2275                updateCheckbox( navMenuLocationSetting.get() === control.params.menu_id ); 
     2276 
     2277                checkbox.on( 'change', function() { 
     2278                    // Note: We can't use element.bind( function( checked ){ ... } ) here because it will trigger a change as well. 
     2279                    updateSetting( this.checked ); 
     2280                } ); 
     2281 
     2282                navMenuLocationSetting.bind( function( selectedMenuId ) { 
     2283                    updateCheckbox( selectedMenuId === control.params.menu_id ); 
     2284                    updateSelectedMenuLabel( selectedMenuId ); 
     2285                } ); 
     2286                updateSelectedMenuLabel( navMenuLocationSetting.get() ); 
     2287            }); 
     2288        } 
     2289    }); 
     2290 
     2291    /** 
     2292     * wp.customize.Menus.MenuAutoAddControl 
     2293     * 
     2294     * Customizer control for a nav menu's auto add. 
     2295     * 
     2296     * @constructor 
     2297     * @augments wp.customize.Control 
     2298     */ 
     2299    api.Menus.MenuAutoAddControl = api.Control.extend({ 
     2300 
     2301        ready: function() { 
    20372302            var control = this, 
    20382303                settingValue = control.setting(); 
     
    20532318            }; 
    20542319 
    2055             control.nameElement = new api.Element( control.container.find( '.menu-name-field' ) ); 
    2056  
    2057             control.nameElement.bind(function( value ) { 
    2058                 var settingValue = control.setting(); 
    2059                 if ( settingValue && settingValue.name !== value ) { 
    2060                     settingValue = _.clone( settingValue ); 
    2061                     settingValue.name = value; 
    2062                     control.setting.set( settingValue ); 
    2063                 } 
    2064             }); 
    2065             if ( settingValue ) { 
    2066                 control.nameElement.set( settingValue.name ); 
    2067             } 
    2068  
    2069             control.setting.bind(function( object ) { 
    2070                 if ( object ) { 
    2071                     control.nameElement.set( object.name ); 
    2072                 } 
    2073             }); 
    2074         } 
    2075  
    2076     }); 
    2077  
    2078     /** 
    2079      * wp.customize.Menus.MenuAutoAddControl 
    2080      * 
    2081      * Customizer control for a nav menu's auto add. 
    2082      * 
    2083      * @constructor 
    2084      * @augments wp.customize.Control 
    2085      */ 
    2086     api.Menus.MenuAutoAddControl = api.Control.extend({ 
    2087  
    2088         ready: function() { 
    2089             var control = this, 
    2090                 settingValue = control.setting(); 
    2091  
    2092             /* 
    2093              * Since the control is not registered in PHP, we need to prevent the 
    2094              * preview's sending of the activeControls to result in this control 
    2095              * being deactivated. 
    2096              */ 
    2097             control.active.validate = function() { 
    2098                 var value, section = api.section( control.section() ); 
    2099                 if ( section ) { 
    2100                     value = section.active(); 
    2101                 } else { 
    2102                     value = false; 
    2103                 } 
    2104                 return value; 
    2105             }; 
    2106  
    21072320            control.autoAddElement = new api.Element( control.container.find( 'input[type=checkbox].auto_add' ) ); 
    21082321 
     
    21812394 
    21822395            this._setupAddition(); 
    2183             this._setupLocations(); 
    21842396            this._setupTitle(); 
    21852397 
     
    22112423                } 
    22122424            } 
     2425 
     2426            /* 
     2427             * Wait for menu items to be added. 
     2428             * Ideally, we'd bind to an event indicating construction is complete, 
     2429             * but deferring appears to be the best option today. 
     2430             */ 
     2431            _.defer( function () { 
     2432                control.updateInvitationVisibility(); 
     2433            } ); 
    22132434        }, 
    22142435 
     
    22362457                } 
    22372458            } ); 
    2238  
    2239             control.container.find( '.menu-delete-item .button-link-delete' ).on( 'click', function( event ) { 
    2240                 event.preventDefault(); 
    2241                 control.setting.set( false ); 
    2242             }); 
    22432459        }, 
    22442460 
     
    23922608            widgetTemplate.find( '.nav-menu-widget-no-menus-message:first' ).toggle( 0 === navMenuCount ); 
    23932609            widgetTemplate.find( 'option[value=' + String( menuId ) + ']' ).remove(); 
    2394         }, 
    2395  
    2396         // Setup theme location checkboxes. 
    2397         _setupLocations: function() { 
    2398             var control = this; 
    2399  
    2400             control.container.find( '.assigned-menu-location' ).each(function() { 
    2401                 var container = $( this ), 
    2402                     checkbox = container.find( 'input[type=checkbox]' ), 
    2403                     element, 
    2404                     updateSelectedMenuLabel, 
    2405                     navMenuLocationSetting = api( 'nav_menu_locations[' + checkbox.data( 'location-id' ) + ']' ); 
    2406  
    2407                 updateSelectedMenuLabel = function( selectedMenuId ) { 
    2408                     var menuSetting = api( 'nav_menu[' + String( selectedMenuId ) + ']' ); 
    2409                     if ( ! selectedMenuId || ! menuSetting || ! menuSetting() ) { 
    2410                         container.find( '.theme-location-set' ).hide(); 
    2411                     } else { 
    2412                         container.find( '.theme-location-set' ).show().find( 'span' ).text( displayNavMenuName( menuSetting().name ) ); 
    2413                     } 
    2414                 }; 
    2415  
    2416                 element = new api.Element( checkbox ); 
    2417                 element.set( navMenuLocationSetting.get() === control.params.menu_id ); 
    2418  
    2419                 checkbox.on( 'change', function() { 
    2420                     // Note: We can't use element.bind( function( checked ){ ... } ) here because it will trigger a change as well. 
    2421                     navMenuLocationSetting.set( this.checked ? control.params.menu_id : 0 ); 
    2422                 } ); 
    2423  
    2424                 navMenuLocationSetting.bind(function( selectedMenuId ) { 
    2425                     element.set( selectedMenuId === control.params.menu_id ); 
    2426                     updateSelectedMenuLabel( selectedMenuId ); 
    2427                 }); 
    2428                 updateSelectedMenuLabel( navMenuLocationSetting.get() ); 
    2429  
    2430             }); 
    24312610        }, 
    24322611 
     
    26082787            } ); 
    26092788 
     2789            menuControl.updateInvitationVisibility( menuItemControls ); 
    26102790            menuControl.container.find( '.reorder-toggle' ).toggle( menuItemControls.length > 1 ); 
    26112791        }, 
     
    26822862 
    26832863            return menuItemControl; 
     2864        }, 
     2865 
     2866        /** 
     2867         * Show an invitation to add new menu items when there are no menu items. 
     2868         * 
     2869         * @since 4.9.0 
     2870         * 
     2871         * @param {wp.customize.controlConstructor.nav_menu_item[]} optionalMenuItemControls 
     2872         */ 
     2873        updateInvitationVisibility: function ( optionalMenuItemControls ) { 
     2874            var menuItemControls = optionalMenuItemControls || this.getMenuItemControls(); 
     2875 
     2876            this.container.find( '.new-menu-item-invitation' ).toggle( menuItemControls.length === 0 ); 
    26842877        } 
    26852878    } ); 
    2686  
    2687     /** 
    2688      * wp.customize.Menus.NewMenuControl 
    2689      * 
    2690      * Customizer control for creating new menus and handling deletion of existing menus. 
    2691      * Note that 'new_menu' must match the WP_Customize_New_Menu_Control::$type. 
    2692      * 
    2693      * @constructor 
    2694      * @augments wp.customize.Control 
    2695      */ 
    2696     api.Menus.NewMenuControl = api.Control.extend({ 
    2697         /** 
    2698          * Set up the control. 
    2699          */ 
    2700         ready: function() { 
    2701             this._bindHandlers(); 
    2702         }, 
    2703  
    2704         _bindHandlers: function() { 
    2705             var self = this, 
    2706                 name = $( '#customize-control-new_menu_name input' ), 
    2707                 submit = $( '#create-new-menu-submit' ); 
    2708             name.on( 'keydown', function( event ) { 
    2709                 if ( 13 === event.which ) { // Enter. 
    2710                     self.submit(); 
    2711                 } 
    2712             } ); 
    2713             submit.on( 'click', function( event ) { 
    2714                 self.submit(); 
    2715                 event.stopPropagation(); 
    2716                 event.preventDefault(); 
    2717             } ); 
    2718         }, 
    2719  
    2720         /** 
    2721          * Create the new menu with the name supplied. 
    2722          */ 
    2723         submit: function() { 
    2724  
    2725             var control = this, 
    2726                 container = control.container.closest( '.accordion-section-new-menu' ), 
    2727                 nameInput = container.find( '.menu-name-field' ).first(), 
    2728                 name = nameInput.val(), 
    2729                 menuSection, 
    2730                 customizeId, 
    2731                 placeholderId = api.Menus.generatePlaceholderAutoIncrementId(); 
    2732  
    2733             if ( ! name ) { 
    2734                 nameInput.addClass( 'invalid' ); 
    2735                 nameInput.focus(); 
    2736                 return; 
    2737             } 
    2738  
    2739             customizeId = 'nav_menu[' + String( placeholderId ) + ']'; 
    2740  
    2741             // Register the menu control setting. 
    2742             api.create( customizeId, customizeId, {}, { 
    2743                 type: 'nav_menu', 
    2744                 transport: api.Menus.data.settingTransport, 
    2745                 previewer: api.previewer 
    2746             } ); 
    2747             api( customizeId ).set( $.extend( 
    2748                 {}, 
    2749                 api.Menus.data.defaultSettingValues.nav_menu, 
    2750                 { 
    2751                     name: name 
    2752                 } 
    2753             ) ); 
    2754  
    2755             /* 
    2756              * Add the menu section (and its controls). 
    2757              * Note that this will automatically create the required controls 
    2758              * inside via the Section's ready method. 
    2759              */ 
    2760             menuSection = new api.Menus.MenuSection( customizeId, { 
    2761                 panel: 'nav_menus', 
    2762                 title: displayNavMenuName( name ), 
    2763                 customizeAction: api.Menus.data.l10n.customizingMenus, 
    2764                 type: 'nav_menu', 
    2765                 priority: 10, 
    2766                 menu_id: placeholderId 
    2767             } ); 
    2768             api.section.add( menuSection ); 
    2769  
    2770             // Clear name field. 
    2771             nameInput.val( '' ); 
    2772             nameInput.removeClass( 'invalid' ); 
    2773  
    2774             wp.a11y.speak( api.Menus.data.l10n.menuAdded ); 
    2775  
    2776             // Focus on the new menu section. 
    2777             api.section( customizeId ).focus(); // @todo should we focus on the new menu's control and open the add-items panel? Thinking user flow... 
    2778         } 
    2779     }); 
    27802879 
    27812880    /** 
     
    27882887        nav_menu: api.Menus.MenuControl, 
    27892888        nav_menu_name: api.Menus.MenuNameControl, 
    2790         nav_menu_auto_add: api.Menus.MenuAutoAddControl, 
    2791         new_menu: api.Menus.NewMenuControl 
     2889        nav_menu_locations: api.Menus.MenuLocationsControl, 
     2890        nav_menu_auto_add: api.Menus.MenuAutoAddControl 
    27922891    }); 
    27932892 
  • trunk/src/wp-includes/class-wp-customize-control.php

    r41750 r41768  
    771771 
    772772/** 
     773 * WP_Customize_Nav_Menu_Locations_Control class. 
     774 */ 
     775require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-locations-control.php' ); 
     776 
     777/** 
    773778 * WP_Customize_Nav_Menu_Auto_Add_Control class. 
    774779 */ 
     
    776781 
    777782/** 
    778  * WP_Customize_New_Menu_Control class. 
    779  */ 
    780 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-new-menu-control.php' ); 
    781  
    782 /** 
    783783 * WP_Customize_Date_Time_Control class. 
    784784 */ 
  • trunk/src/wp-includes/class-wp-customize-manager.php

    r41750 r41768  
    316316        require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-location-control.php' ); 
    317317        require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-name-control.php' ); 
     318        require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-locations-control.php' ); 
    318319        require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-auto-add-control.php' ); 
    319         require_once( ABSPATH . WPINC . '/customize/class-wp-customize-new-menu-control.php' ); 
    320320 
    321321        require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menus-panel.php' ); 
     
    325325        require_once( ABSPATH . WPINC . '/customize/class-wp-customize-sidebar-section.php' ); 
    326326        require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-section.php' ); 
    327         require_once( ABSPATH . WPINC . '/customize/class-wp-customize-new-menu-section.php' ); 
    328327 
    329328        require_once( ABSPATH . WPINC . '/customize/class-wp-customize-custom-css-setting.php' ); 
  • trunk/src/wp-includes/class-wp-customize-nav-menus.php

    r41670 r41768  
    396396        $temp_nav_menu_item_setting = new WP_Customize_Nav_Menu_Item_Setting( $this->manager, 'nav_menu_item[-1]' ); 
    397397 
     398        $num_locations = count( get_registered_nav_menus() ); 
     399        if ( 1 === $num_locations ) { 
     400            $locations_description = __( 'Your theme can display menus in one location.' ); 
     401        } else { 
     402            /* translators: %s: number of menu locations */ 
     403            $locations_description = sprintf( _n( 'Your theme can display menus in %s location.', 'Your theme can display menus in %s locations.', $num_locations ), number_format_i18n( $num_locations ) ); 
     404        } 
     405 
    398406        // Pass data to JS. 
    399407        $settings = array( 
     
    401409            'itemTypes'            => $this->available_item_types(), 
    402410            'l10n'                 => array( 
    403                 'untitled'          => _x( '(no label)', 'missing menu item navigation label' ), 
    404                 'unnamed'           => _x( '(unnamed)', 'Missing menu name.' ), 
    405                 'custom_label'      => __( 'Custom Link' ), 
    406                 'page_label'        => get_post_type_object( 'page' )->labels->singular_name, 
    407                 /* translators: %s: menu location */ 
    408                 'menuLocation'      => _x( '(Currently set to: %s)', 'menu' ), 
    409                 'menuNameLabel'     => __( 'Menu Name' ), 
    410                 'itemAdded'         => __( 'Menu item added' ), 
    411                 'itemDeleted'       => __( 'Menu item deleted' ), 
    412                 'menuAdded'         => __( 'Menu created' ), 
    413                 'menuDeleted'       => __( 'Menu deleted' ), 
    414                 'movedUp'           => __( 'Menu item moved up' ), 
    415                 'movedDown'         => __( 'Menu item moved down' ), 
    416                 'movedLeft'         => __( 'Menu item moved out of submenu' ), 
    417                 'movedRight'        => __( 'Menu item is now a sub-item' ), 
     411                'untitled'               => _x( '(no label)', 'missing menu item navigation label' ), 
     412                'unnamed'                => _x( '(unnamed)', 'Missing menu name.' ), 
     413                'custom_label'           => __( 'Custom Link' ), 
     414                'page_label'             => get_post_type_object( 'page' )->labels->singular_name, 
     415                /* translators: %s:      menu location */ 
     416                'menuLocation'           => _x( '(Currently set to: %s)', 'menu' ), 
     417                'locationsDescription'   => $locations_description, 
     418                'menuNameLabel'          => __( 'Menu Name' ), 
     419                'newMenuNameDescription' => __( 'If your theme has multiple menus, giving them clear names will help you manage them.' ), 
     420                'itemAdded'              => __( 'Menu item added' ), 
     421                'itemDeleted'            => __( 'Menu item deleted' ), 
     422                'menuAdded'              => __( 'Menu created' ), 
     423                'menuDeleted'            => __( 'Menu deleted' ), 
     424                'movedUp'                => __( 'Menu item moved up' ), 
     425                'movedDown'              => __( 'Menu item moved down' ), 
     426                'movedLeft'              => __( 'Menu item moved out of submenu' ), 
     427                'movedRight'             => __( 'Menu item is now a sub-item' ), 
    418428                /* translators: ▸ is the unicode right-pointing triangle, and %s is the section title in the Customizer */ 
    419                 'customizingMenus'  => sprintf( __( 'Customizing ▸ %s' ), esc_html( $this->manager->get_panel( 'nav_menus' )->title ) ), 
     429                'customizingMenus'       => sprintf( __( 'Customizing ▸ %s' ), esc_html( $this->manager->get_panel( 'nav_menus' )->title ) ), 
    420430                /* translators: %s: title of menu item which is invalid */ 
    421                 'invalidTitleTpl'   => __( '%s (Invalid)' ), 
     431                'invalidTitleTpl'        => __( '%s (Invalid)' ), 
    422432                /* translators: %s: title of menu item in draft status */ 
    423                 'pendingTitleTpl'   => __( '%s (Pending)' ), 
    424                 'itemsFound'        => __( 'Number of items found: %d' ), 
    425                 'itemsFoundMore'    => __( 'Additional items found: %d' ), 
    426                 'itemsLoadingMore'  => __( 'Loading more results... please wait.' ), 
    427                 'reorderModeOn'     => __( 'Reorder mode enabled' ), 
    428                 'reorderModeOff'    => __( 'Reorder mode closed' ), 
    429                 'reorderLabelOn'    => esc_attr__( 'Reorder menu items' ), 
    430                 'reorderLabelOff'   => esc_attr__( 'Close reorder mode' ), 
     433                'pendingTitleTpl'        => __( '%s (Pending)' ), 
     434                'itemsFound'             => __( 'Number of items found: %d' ), 
     435                'itemsFoundMore'         => __( 'Additional items found: %d' ), 
     436                'itemsLoadingMore'       => __( 'Loading more results... please wait.' ), 
     437                'reorderModeOn'          => __( 'Reorder mode enabled' ), 
     438                'reorderModeOff'         => __( 'Reorder mode closed' ), 
     439                'reorderLabelOn'         => esc_attr__( 'Reorder menu items' ), 
     440                'reorderLabelOff'        => esc_attr__( 'Close reorder mode' ), 
    431441            ), 
    432442            'settingTransport'     => 'postMessage', 
     
    538548        $this->manager->register_control_type( 'WP_Customize_Nav_Menu_Control' ); 
    539549        $this->manager->register_control_type( 'WP_Customize_Nav_Menu_Name_Control' ); 
     550        $this->manager->register_control_type( 'WP_Customize_Nav_Menu_Locations_Control' ); 
    540551        $this->manager->register_control_type( 'WP_Customize_Nav_Menu_Auto_Add_Control' ); 
    541552        $this->manager->register_control_type( 'WP_Customize_Nav_Menu_Item_Control' ); 
     
    559570        // Menu locations. 
    560571        $locations     = get_registered_nav_menus(); 
    561         $num_locations = count( array_keys( $locations ) ); 
     572        $num_locations = count( $locations ); 
    562573        if ( 1 == $num_locations ) { 
    563             $description = '<p>' . __( 'Your theme supports one menu. Select which menu you would like to use.' ) . '</p>'; 
     574            $description = '<p>' . __( 'Your theme can display menus in one location. Select which menu you would like to use.' ) . '</p>'; 
    564575        } else { 
    565576            /* translators: %s: number of menu locations */ 
    566             $description = '<p>' . sprintf( _n( 'Your theme supports %s menu. Select which menu appears in each location.', 'Your theme supports %s menus. Select which menu appears in each location.', $num_locations ), number_format_i18n( $num_locations ) ) . '</p>'; 
    567         } 
     577            $description = '<p>' . sprintf( _n( 'Your theme can display menus in %s location. Select which menu you would like to use.', 'Your theme can display menus in %s locations. Select which menu appears in each location.', $num_locations ), number_format_i18n( $num_locations ) ) . '</p>'; 
     578        } 
     579 
    568580        if ( current_theme_supports( 'widgets' ) ) { 
    569581            /* translators: URL to the widgets panel of the customizer */ 
    570             $description .= '<p>' . sprintf( __( 'You can also place menus in <a href="%s">widget areas</a> with the &#8220;Custom Menu&#8221; widget.' ), "javascript:wp.customize.panel( 'widgets' ).focus();" ) . '</p>'; 
     582            $description .= '<p>' . sprintf( __( 'If your theme has widget areas, you can also add menus there. Visit the <a href="%s">Widgets panel</a> and add a &#8220;Custom Menu widget&#8221; to display a menu in a sidebar or footer.' ), "javascript:wp.customize.panel( 'widgets' ).focus();" ) . '</p>'; 
    571583        } 
    572584 
    573585        $this->manager->add_section( 'menu_locations', array( 
    574             'title'       => __( 'Menu Locations' ), 
    575             'panel'       => 'nav_menus', 
    576             'priority'    => 5, 
    577             'description' => $description, 
     586            'title'         => __( 'View All Locations' ), 
     587            'panel'         => 'nav_menus', 
     588            'priority'      => 30, 
     589            'description'   => $description 
    578590        ) ); 
    579591 
     
    668680 
    669681        // Add the add-new-menu section and controls. 
    670         $this->manager->add_section( new WP_Customize_New_Menu_Section( $this->manager, 'add_menu', array( 
    671             'title'    => __( 'Add a Menu' ), 
     682        $this->manager->add_section( 'add_menu', array( 
     683            'type'     => 'new_menu', 
     684            'title'    => __( 'New Menu' ), 
    672685            'panel'    => 'nav_menus', 
    673             'priority' => 999, 
    674         ) ) ); 
    675  
    676         $this->manager->add_control( 'new_menu_name', array( 
    677             'label'       => __( 'New menu name' ), 
    678             'section'     => 'add_menu', 
    679             'type'        => 'text', 
    680             'settings'    => array(), 
    681             'input_attrs' => array( 
    682                 'class'       => 'menu-name-field', 
    683             ), 
     686            'priority' => 20, 
    684687        ) ); 
    685  
    686         $this->manager->add_control( new WP_Customize_New_Menu_Control( $this->manager, 'create_new_menu', array( 
    687             'section'  => 'add_menu', 
    688             'settings' => array(), 
    689         ) ) ); 
    690688 
    691689        $this->manager->add_setting( new WP_Customize_Filter_Setting( $this->manager, 'nav_menus_created_posts', array( 
     
    925923                ?> 
    926924            </div> 
     925        </script> 
     926 
     927        <script type="text/html" id="tmpl-nav-menu-delete-button"> 
     928            <div class="menu-delete-item"> 
     929                <button type="button" class="button-link button-link-delete"> 
     930                    <?php _e( 'Delete Menu' ); ?> 
     931                </button> 
     932            </div> 
     933        </script> 
     934 
     935        <script type="text/html" id="tmpl-nav-menu-submit-new-button"> 
     936            <p id="customize-new-menu-submit-description"><?php _e( 'Click "next" to start adding links to your new menu.' ); ?></p> 
     937            <button id="customize-new-menu-submit" type="button" class="button" aria-describedby="customize-new-menu-submit-description"><?php _e( 'Next' ); ?></button> 
     938        </script> 
     939 
     940        <script type="text/html" id="tmpl-nav-menu-locations-header"> 
     941            <span class="customize-control-title customize-section-title-menu_locations-heading"><?php _e( 'Menu Locations' ); ?></span> 
     942            <p class="customize-control-description customize-section-title-menu_locations-description">{{ data.l10n.locationsDescription }}</p> 
     943        </script> 
     944 
     945        <script type="text/html" id="tmpl-nav-menu-create-menu-section-title"> 
     946            <h3> 
     947                <button type="button" class="button customize-add-menu-button"> 
     948                    <?php _e( 'Create New Menu' ); ?> 
     949                </button> 
     950            </h3> 
    927951        </script> 
    928952    <?php 
  • trunk/src/wp-includes/class-wp-customize-section.php

    r41390 r41768  
    386386/** WP_Customize_Nav_Menu_Section class */ 
    387387require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-section.php' ); 
    388  
    389 /** WP_Customize_New_Menu_Section class */ 
    390 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-new-menu-section.php' ); 
  • trunk/src/wp-includes/customize/class-wp-customize-nav-menu-auto-add-control.php

    r41162 r41768  
    3939    protected function content_template() { 
    4040        ?> 
     41        <# var elementId = _.uniqueId( 'customize-nav-menu-auto-add-control-' ); #> 
    4142        <span class="customize-control-title"><?php _e( 'Menu Options' ); ?></span> 
    42         <label> 
    43             <input type="checkbox" class="auto_add" /> 
    44             <?php _e( 'Automatically add new top-level pages to this menu' ); ?> 
    45         </label> 
     43        <span class="customize-inside-control-row"> 
     44            <input id="{{ elementId }}" type="checkbox" class="auto_add" /> 
     45            <label for="{{ elementId }}"> 
     46                <?php _e( 'Automatically add new top-level pages to this menu' ); ?> 
     47            </label> 
     48        </span> 
    4649        <?php 
    4750    } 
  • trunk/src/wp-includes/customize/class-wp-customize-nav-menu-control.php

    r41740 r41768  
    2424 
    2525    /** 
    26      * The nav menu setting. 
    27      * 
    28      * @since 4.3.0 
    29      * @var WP_Customize_Nav_Menu_Setting 
    30      */ 
    31     public $setting; 
    32  
    33     /** 
    3426     * Don't render the control's content - it uses a JS template instead. 
    3527     * 
     
    4537    public function content_template() { 
    4638        ?> 
    47         <# var elementId; #> 
    48         <button type="button" class="button add-new-menu-item" aria-label="<?php esc_attr_e( 'Add or remove menu items' ); ?>" aria-expanded="false" aria-controls="available-menu-items"> 
    49             <?php _e( 'Add Items' ); ?> 
    50         </button> 
    51         <button type="button" class="button-link reorder-toggle" aria-label="<?php esc_attr_e( 'Reorder menu items' ); ?>" aria-describedby="reorder-items-desc-{{ data.menu_id }}"> 
    52             <span class="reorder"><?php _e( 'Reorder' ); ?></span> 
    53             <span class="reorder-done"><?php _e( 'Done' ); ?></span> 
    54         </button> 
     39        <p class="new-menu-item-invitation"><?php _e( 'Time to add some links! Click "Add menu items" to start putting pages, categories, and custom links in your menu. Add as many things as you\'d like.' ); ?></p> 
     40        <div class="customize-control-nav_menu-buttons"> 
     41            <button type="button" class="button add-new-menu-item" aria-label="<?php esc_attr_e( 'Add or remove menu items' ); ?>" aria-expanded="false" aria-controls="available-menu-items"> 
     42                <?php _e( 'Add Items' ); ?> 
     43            </button> 
     44            <button type="button" class="button-link reorder-toggle" aria-label="<?php esc_attr_e( 'Reorder menu items' ); ?>" aria-describedby="reorder-items-desc-{{ data.menu_id }}"> 
     45                <span class="reorder"><?php _e( 'Reorder' ); ?></span> 
     46                <span class="reorder-done"><?php _e( 'Done' ); ?></span> 
     47            </button> 
     48        </div> 
    5549        <p class="screen-reader-text" id="reorder-items-desc-{{ data.menu_id }}"><?php _e( 'When in reorder mode, additional controls to reorder menu items will be available in the items list above.' ); ?></p> 
    56         <span class="menu-delete-item"> 
    57             <button type="button" class="button-link button-link-delete"> 
    58                 <?php _e( 'Delete Menu' ); ?> 
    59             </button> 
    60         </span> 
    61         <?php if ( current_theme_supports( 'menus' ) ) : ?> 
    62         <ul class="menu-settings"> 
    63             <li class="customize-control"> 
    64                 <span class="customize-control-title"><?php _e( 'Display Location' ); ?></span> 
    65             </li> 
    66  
    67             <?php foreach ( get_registered_nav_menus() as $location => $description ) : ?> 
    68                 <# elementId = _.uniqueId( 'customize-nav-menu-control-location-' ); #> 
    69                 <li class="customize-control customize-control-checkbox assigned-menu-location customize-inside-control-row"> 
    70                     <input id="{{ elementId }}" type="checkbox" data-menu-id="{{ data.menu_id }}" data-location-id="<?php echo esc_attr( $location ); ?>" class="menu-location" /> 
    71                     <label for="{{ elementId }}"> 
    72                         <?php echo $description; ?> 
    73                         <span class="theme-location-set"> 
    74                             <?php 
    75                             /* translators: %s: menu name */ 
    76                             printf( _x( '(Current: %s)', 'menu location' ), 
    77                                 '<span class="current-menu-location-name-' . esc_attr( $location ) . '"></span>' 
    78                             ); 
    79                             ?> 
    80                         </span> 
    81                     </label> 
    82                 </li> 
    83             <?php endforeach; ?> 
    84         </ul> 
    85         <?php endif; ?> 
    8650        <?php 
    8751    } 
  • trunk/src/wp-includes/customize/class-wp-customize-nav-menu-name-control.php

    r41162 r41768  
    4141        <label> 
    4242            <# if ( data.label ) { #> 
    43                 <span class="customize-control-title screen-reader-text">{{ data.label }}</span> 
     43                <span class="customize-control-title">{{ data.label }}</span> 
    4444            <# } #> 
    45             <input type="text" class="menu-name-field live-update-section-title" /> 
     45            <input type="text" class="menu-name-field live-update-section-title" 
     46                <# if ( data.description ) { #> 
     47                    aria-describedby="{{ data.section }}-description" 
     48                <# } #> 
     49                /> 
    4650        </label> 
     51        <# if ( data.description ) { #> 
     52            <p id="{{ data.section }}-description">{{ data.description }}</p> 
     53        <# } #> 
    4754        <?php 
    4855    } 
  • trunk/src/wp-includes/customize/class-wp-customize-nav-menus-panel.php

    r41162 r41768  
    9393            </div> 
    9494        </li> 
     95        <?php 
     96        // NOTE: The following is a workaround for an inability to treat (and thus label) a list of sections as a whole. 
     97        ?> 
     98        <li class="customize-control-title customize-section-title-nav_menus-heading"><?php _e( 'Menus' ); ?></li> 
    9599    <?php 
    96100    } 
  • trunk/tests/qunit/wp-admin/js/customize-nav-menus.js

    r38049 r41768  
    6666        ok( controls[0].extended( api.Menus.MenuNameControl ), 'first control in menu section is MenuNameControl' ); 
    6767        ok( controls[1].extended( api.Menus.MenuItemControl ), 'second control in menu section is MenuItemControl' ); 
    68         ok( controls[ controls.length - 1 ].extended( api.Menus.MenuAutoAddControl ), 'last control in menu section is a MenuAutoAddControl' ); 
     68        ok( controls[ controls.length - 1 ].extended( api.Menus.MenuDeleteControl ), 'last control in menu section is a MenuDeleteControl' ); 
    6969    } ); 
    7070    // @todo Add more tests for api.Menus.MenuSection behaviors 
Note: See TracChangeset for help on using the changeset viewer.