Changeset 41768
- Timestamp:
- 10/05/2017 02:21:22 AM (7 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-admin/css/customize-controls.css
r41750 r41768 558 558 } 559 559 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 { 562 563 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; 563 568 } 564 569 … … 662 667 } 663 668 664 .customize-section-description-container { 669 .customize-section-description-container, 670 .control-section-nav_menu .customize-section-description-container { 665 671 margin-bottom: 15px; 666 672 } -
trunk/src/wp-admin/css/customize-nav-menus.css
r41711 r41768 1 1 #customize-theme-controls #accordion-section-menu_locations { 2 2 position: relative; 3 margin- bottom: 15px;3 margin-top: 15px; 4 4 } 5 5 6 6 #customize-theme-controls #accordion-section-menu_locations > .accordion-section-title { 7 7 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; 8 20 } 9 21 … … 26 38 vertical-align: middle; 27 39 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; 28 57 } 29 58 … … 176 205 } 177 206 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 { 179 220 line-height: 1; 180 221 } 181 222 182 223 /* @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 { 184 226 margin-bottom: 8px; /* Override collapsing at smaller viewports. */ 185 227 } … … 739 781 #accordion-section-add_menu { 740 782 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; 762 793 } 763 794 … … 773 804 } 774 805 806 .assigned-menu-locations-title p { 807 margin: 0 0 8px 0; 808 } 809 775 810 li.assigned-to-menu-location .menu-delete-item { 776 811 display: none; … … 809 844 } 810 845 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 { 812 852 margin-top: 12px; 813 853 } -
trunk/src/wp-admin/js/customize-controls.js
r41750 r41768 1235 1235 */ 1236 1236 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 ); 1239 1252 1240 1253 section.id = id; … … 2508 2521 */ 2509 2522 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 2512 2539 panel.embed(); 2513 2540 panel.deferred.embedded.done( function () { … … 3096 3123 * @param {string} options.section - The ID of the section the control belongs to. 3097 3124 * @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. 3099 3126 * @param {mixed} options.settings.default - The ID of the setting the control relates to. 3100 3127 * @param {string} options.settings.data - @todo Is this used? … … 3108 3135 3109 3136 defaults: { 3137 label: '', 3138 description: '', 3110 3139 active: true, 3111 3140 priority: 10 -
trunk/src/wp-admin/js/customize-nav-menus.js
r41726 r41768 812 812 panel.saveManageColumnsState(); 813 813 }); 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 } ); 814 826 }, 815 827 … … 962 974 963 975 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; 965 986 966 987 // Add the control for managing the menu name. … … 997 1018 } 998 1019 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 999 1036 // Add the control for managing the menu auto_add. 1000 1037 menuAutoAddControlId = section.id + '[auto_add]'; … … 1005 1042 label: '', 1006 1043 section: section.id, 1007 priority: 999,1044 priority: 1000, 1008 1045 settings: { 1009 1046 'default': section.id … … 1014 1051 } 1015 1052 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 } 1016 1072 }, 1017 1073 … … 1094 1150 * 1095 1151 * Customizer section for new menus. 1096 * Note that 'new_menu' must match the WP_Customize_New_Menu_Section::$type.1097 1152 * 1098 1153 * @constructor … … 1107 1162 */ 1108 1163 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.01123 *1124 * @param {Boolean} expanded1125 */1126 onChangeExpanded: function( expanded ) {1127 1164 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... 1154 1322 } 1155 1323 }); … … 1513 1681 $adjacentFocusTarget.focus(); // keyboard accessibility 1514 1682 } ); 1683 1684 control.setting.set( false ); 1515 1685 } ); 1516 1686 }, … … 2035 2205 2036 2206 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() { 2037 2302 var control = this, 2038 2303 settingValue = control.setting(); … … 2053 2318 }; 2054 2319 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.MenuAutoAddControl2080 *2081 * Customizer control for a nav menu's auto add.2082 *2083 * @constructor2084 * @augments wp.customize.Control2085 */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 the2094 * preview's sending of the activeControls to result in this control2095 * 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 2107 2320 control.autoAddElement = new api.Element( control.container.find( 'input[type=checkbox].auto_add' ) ); 2108 2321 … … 2181 2394 2182 2395 this._setupAddition(); 2183 this._setupLocations();2184 2396 this._setupTitle(); 2185 2397 … … 2211 2423 } 2212 2424 } 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 } ); 2213 2434 }, 2214 2435 … … 2236 2457 } 2237 2458 } ); 2238 2239 control.container.find( '.menu-delete-item .button-link-delete' ).on( 'click', function( event ) {2240 event.preventDefault();2241 control.setting.set( false );2242 });2243 2459 }, 2244 2460 … … 2392 2608 widgetTemplate.find( '.nav-menu-widget-no-menus-message:first' ).toggle( 0 === navMenuCount ); 2393 2609 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 });2431 2610 }, 2432 2611 … … 2608 2787 } ); 2609 2788 2789 menuControl.updateInvitationVisibility( menuItemControls ); 2610 2790 menuControl.container.find( '.reorder-toggle' ).toggle( menuItemControls.length > 1 ); 2611 2791 }, … … 2682 2862 2683 2863 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 ); 2684 2877 } 2685 2878 } ); 2686 2687 /**2688 * wp.customize.Menus.NewMenuControl2689 *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 * @constructor2694 * @augments wp.customize.Control2695 */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.previewer2746 } );2747 api( customizeId ).set( $.extend(2748 {},2749 api.Menus.data.defaultSettingValues.nav_menu,2750 {2751 name: name2752 }2753 ) );2754 2755 /*2756 * Add the menu section (and its controls).2757 * Note that this will automatically create the required controls2758 * 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: placeholderId2767 } );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 });2780 2879 2781 2880 /** … … 2788 2887 nav_menu: api.Menus.MenuControl, 2789 2888 nav_menu_name: api.Menus.MenuNameControl, 2790 nav_menu_ auto_add: api.Menus.MenuAutoAddControl,2791 n ew_menu: api.Menus.NewMenuControl2889 nav_menu_locations: api.Menus.MenuLocationsControl, 2890 nav_menu_auto_add: api.Menus.MenuAutoAddControl 2792 2891 }); 2793 2892 -
trunk/src/wp-includes/class-wp-customize-control.php
r41750 r41768 771 771 772 772 /** 773 * WP_Customize_Nav_Menu_Locations_Control class. 774 */ 775 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-locations-control.php' ); 776 777 /** 773 778 * WP_Customize_Nav_Menu_Auto_Add_Control class. 774 779 */ … … 776 781 777 782 /** 778 * WP_Customize_New_Menu_Control class.779 */780 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-new-menu-control.php' );781 782 /**783 783 * WP_Customize_Date_Time_Control class. 784 784 */ -
trunk/src/wp-includes/class-wp-customize-manager.php
r41750 r41768 316 316 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-location-control.php' ); 317 317 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' ); 318 319 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' );320 320 321 321 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menus-panel.php' ); … … 325 325 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-sidebar-section.php' ); 326 326 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' );328 327 329 328 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-custom-css-setting.php' ); -
trunk/src/wp-includes/class-wp-customize-nav-menus.php
r41670 r41768 396 396 $temp_nav_menu_item_setting = new WP_Customize_Nav_Menu_Item_Setting( $this->manager, 'nav_menu_item[-1]' ); 397 397 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 398 406 // Pass data to JS. 399 407 $settings = array( … … 401 409 'itemTypes' => $this->available_item_types(), 402 410 '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' ), 418 428 /* 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 ) ), 420 430 /* translators: %s: title of menu item which is invalid */ 421 'invalidTitleTpl' => __( '%s (Invalid)' ),431 'invalidTitleTpl' => __( '%s (Invalid)' ), 422 432 /* 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' ), 431 441 ), 432 442 'settingTransport' => 'postMessage', … … 538 548 $this->manager->register_control_type( 'WP_Customize_Nav_Menu_Control' ); 539 549 $this->manager->register_control_type( 'WP_Customize_Nav_Menu_Name_Control' ); 550 $this->manager->register_control_type( 'WP_Customize_Nav_Menu_Locations_Control' ); 540 551 $this->manager->register_control_type( 'WP_Customize_Nav_Menu_Auto_Add_Control' ); 541 552 $this->manager->register_control_type( 'WP_Customize_Nav_Menu_Item_Control' ); … … 559 570 // Menu locations. 560 571 $locations = get_registered_nav_menus(); 561 $num_locations = count( array_keys( $locations ));572 $num_locations = count( $locations ); 562 573 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>'; 564 575 } else { 565 576 /* 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 568 580 if ( current_theme_supports( 'widgets' ) ) { 569 581 /* 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 “Custom Menu” 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 “Custom Menu widget” to display a menu in a sidebar or footer.' ), "javascript:wp.customize.panel( 'widgets' ).focus();" ) . '</p>'; 571 583 } 572 584 573 585 $this->manager->add_section( 'menu_locations', array( 574 'title' => __( 'MenuLocations' ),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 578 590 ) ); 579 591 … … 668 680 669 681 // 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' ), 672 685 '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, 684 687 ) ); 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 ) ) );690 688 691 689 $this->manager->add_setting( new WP_Customize_Filter_Setting( $this->manager, 'nav_menus_created_posts', array( … … 925 923 ?> 926 924 </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> 927 951 </script> 928 952 <?php -
trunk/src/wp-includes/class-wp-customize-section.php
r41390 r41768 386 386 /** WP_Customize_Nav_Menu_Section class */ 387 387 require_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 39 39 protected function content_template() { 40 40 ?> 41 <# var elementId = _.uniqueId( 'customize-nav-menu-auto-add-control-' ); #> 41 42 <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> 46 49 <?php 47 50 } -
trunk/src/wp-includes/customize/class-wp-customize-nav-menu-control.php
r41740 r41768 24 24 25 25 /** 26 * The nav menu setting.27 *28 * @since 4.3.029 * @var WP_Customize_Nav_Menu_Setting30 */31 public $setting;32 33 /**34 26 * Don't render the control's content - it uses a JS template instead. 35 27 * … … 45 37 public function content_template() { 46 38 ?> 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> 55 49 <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 <?php75 /* 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; ?>86 50 <?php 87 51 } -
trunk/src/wp-includes/customize/class-wp-customize-nav-menu-name-control.php
r41162 r41768 41 41 <label> 42 42 <# if ( data.label ) { #> 43 <span class="customize-control-title screen-reader-text">{{ data.label }}</span>43 <span class="customize-control-title">{{ data.label }}</span> 44 44 <# } #> 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 /> 46 50 </label> 51 <# if ( data.description ) { #> 52 <p id="{{ data.section }}-description">{{ data.description }}</p> 53 <# } #> 47 54 <?php 48 55 } -
trunk/src/wp-includes/customize/class-wp-customize-nav-menus-panel.php
r41162 r41768 93 93 </div> 94 94 </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> 95 99 <?php 96 100 } -
trunk/tests/qunit/wp-admin/js/customize-nav-menus.js
r38049 r41768 66 66 ok( controls[0].extended( api.Menus.MenuNameControl ), 'first control in menu section is MenuNameControl' ); 67 67 ok( controls[1].extended( api.Menus.MenuItemControl ), 'second control in menu section is MenuItemControl' ); 68 ok( controls[ controls.length - 1 ].extended( api.Menus.Menu AutoAddControl ), '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' ); 69 69 } ); 70 70 // @todo Add more tests for api.Menus.MenuSection behaviors
Note: See TracChangeset
for help on using the changeset viewer.