93 * Insert a new `auto-draft` post. |
93 * Insert a new `auto-draft` post. |
94 * |
94 * |
95 * @since 4.7.0 |
95 * @since 4.7.0 |
96 * @alias wp.customize.Menus.insertAutoDraftPost |
96 * @alias wp.customize.Menus.insertAutoDraftPost |
97 * |
97 * |
98 * @param {object} params - Parameters for the draft post to create. |
98 * @param {Object} params - Parameters for the draft post to create. |
99 * @param {string} params.post_type - Post type to add. |
99 * @param {string} params.post_type - Post type to add. |
100 * @param {string} params.post_title - Post title to use. |
100 * @param {string} params.post_title - Post title to use. |
101 * @return {jQuery.promise} Promise resolved with the added post. |
101 * @return {jQuery.promise} Promise resolved with the added post. |
102 */ |
102 */ |
103 api.Menus.insertAutoDraftPost = function insertAutoDraftPost( params ) { |
103 api.Menus.insertAutoDraftPost = function insertAutoDraftPost( params ) { |
201 |
201 |
202 this.debounceSearch = _.debounce( self.search, 500 ); |
202 this.debounceSearch = _.debounce( self.search, 500 ); |
203 |
203 |
204 _.bindAll( this, 'close' ); |
204 _.bindAll( this, 'close' ); |
205 |
205 |
206 // If the available menu items panel is open and the customize controls are |
206 /* |
207 // interacted with (other than an item being deleted), then close the |
207 * If the available menu items panel is open and the customize controls |
208 // available menu items panel. Also close on back button click. |
208 * are interacted with (other than an item being deleted), then close |
|
209 * the available menu items panel. Also close on back button click. |
|
210 */ |
209 $( '#customize-controls, .customize-section-back' ).on( 'click keydown', function( e ) { |
211 $( '#customize-controls, .customize-section-back' ).on( 'click keydown', function( e ) { |
210 var isDeleteBtn = $( e.target ).is( '.item-delete, .item-delete *' ), |
212 var isDeleteBtn = $( e.target ).is( '.item-delete, .item-delete *' ), |
211 isAddNewBtn = $( e.target ).is( '.add-new-menu-item, .add-new-menu-item *' ); |
213 isAddNewBtn = $( e.target ).is( '.add-new-menu-item, .add-new-menu-item *' ); |
212 if ( $( 'body' ).hasClass( 'adding-menu-items' ) && ! isDeleteBtn && ! isAddNewBtn ) { |
214 if ( $( 'body' ).hasClass( 'adding-menu-items' ) && ! isDeleteBtn && ! isAddNewBtn ) { |
213 self.close(); |
215 self.close(); |
214 } |
216 } |
215 } ); |
217 } ); |
216 |
218 |
217 // Clear the search results and trigger a `keyup` event to fire a new search. |
219 // Clear the search results and trigger an `input` event to fire a new search. |
218 this.$clearResults.on( 'click', function() { |
220 this.$clearResults.on( 'click', function() { |
219 self.$search.val( '' ).focus().trigger( 'keyup' ); |
221 self.$search.val( '' ).focus().trigger( 'input' ); |
220 } ); |
222 } ); |
221 |
223 |
222 this.$el.on( 'input', '#custom-menu-item-name.invalid, #custom-menu-item-url.invalid', function() { |
224 this.$el.on( 'input', '#custom-menu-item-name.invalid, #custom-menu-item-url.invalid', function() { |
223 $( this ).removeClass( 'invalid' ); |
225 $( this ).removeClass( 'invalid' ); |
224 }); |
226 }); |
383 * |
385 * |
384 * @since 4.3.0 |
386 * @since 4.3.0 |
385 * @since 4.7.0 Changed function signature to take list of item types instead of single type/object. |
387 * @since 4.7.0 Changed function signature to take list of item types instead of single type/object. |
386 * @access private |
388 * @access private |
387 * |
389 * |
388 * @param {Array.<object>} itemTypes List of objects containing type and key. |
390 * @param {Array.<Object>} itemTypes List of objects containing type and key. |
389 * @param {string} deprecated Formerly the object parameter. |
391 * @param {string} deprecated Formerly the object parameter. |
390 * @returns {void} |
392 * @return {void} |
391 */ |
393 */ |
392 loadItems: function( itemTypes, deprecated ) { |
394 loadItems: function( itemTypes, deprecated ) { |
393 var self = this, _itemTypes, requestItemTypes = [], params, request, itemTemplate, availableMenuItemContainers = {}; |
395 var self = this, _itemTypes, requestItemTypes = [], params, request, itemTemplate, availableMenuItemContainers = {}; |
394 itemTemplate = wp.template( 'available-menu-item' ); |
396 itemTemplate = wp.template( 'available-menu-item' ); |
395 |
397 |
582 }; |
584 }; |
583 |
585 |
584 this.currentMenuControl.addItemToMenu( menuItem ); |
586 this.currentMenuControl.addItemToMenu( menuItem ); |
585 |
587 |
586 // Reset the custom link form. |
588 // Reset the custom link form. |
587 itemUrl.val( 'http://' ); |
589 itemUrl.val( '' ).attr( 'placeholder', 'https://' ); |
588 itemName.val( '' ); |
590 itemName.val( '' ); |
589 }, |
591 }, |
590 |
592 |
591 /** |
593 /** |
592 * Submit handler for keypress (enter) on field and click on button. |
594 * Submit handler for keypress (enter) on field and click on button. |
593 * |
595 * |
594 * @since 4.7.0 |
596 * @since 4.7.0 |
595 * @private |
597 * @private |
596 * |
598 * |
597 * @param {jQuery.Event} event Event. |
599 * @param {jQuery.Event} event Event. |
598 * @returns {void} |
600 * @return {void} |
599 */ |
601 */ |
600 _submitNew: function( event ) { |
602 _submitNew: function( event ) { |
601 var container; |
603 var container; |
602 |
604 |
603 // Only proceed with keypress if it is Enter. |
605 // Only proceed with keypress if it is Enter. |
729 this.selected = null; |
731 this.selected = null; |
730 |
732 |
731 $( 'body' ).removeClass( 'adding-menu-items' ); |
733 $( 'body' ).removeClass( 'adding-menu-items' ); |
732 $( '#available-menu-items .menu-item-handle.item-added' ).removeClass( 'item-added' ); |
734 $( '#available-menu-items .menu-item-handle.item-added' ).removeClass( 'item-added' ); |
733 |
735 |
734 this.$search.val( '' ).trigger( 'keyup' ); |
736 this.$search.val( '' ).trigger( 'input' ); |
735 }, |
737 }, |
736 |
738 |
737 // Add a few keyboard enhancements to the panel. |
739 // Add a few keyboard enhancements to the panel. |
738 keyboardAccessible: function( event ) { |
740 keyboardAccessible: function( event ) { |
739 var isEnter = ( 13 === event.which ), |
741 var isEnter = ( 13 === event.which ), |
740 isEsc = ( 27 === event.which ), |
742 isEsc = ( 27 === event.which ), |
741 isBackTab = ( 9 === event.which && event.shiftKey ), |
743 isBackTab = ( 9 === event.which && event.shiftKey ), |
742 isSearchFocused = $( event.target ).is( this.$search ); |
744 isSearchFocused = $( event.target ).is( this.$search ); |
743 |
745 |
744 // If enter pressed but nothing entered, don't do anything |
746 // If enter pressed but nothing entered, don't do anything. |
745 if ( isEnter && ! this.$search.val() ) { |
747 if ( isEnter && ! this.$search.val() ) { |
746 return; |
748 return; |
747 } |
749 } |
748 |
750 |
749 if ( isSearchFocused && isBackTab ) { |
751 if ( isSearchFocused && isBackTab ) { |
1060 } ); |
1062 } ); |
1061 api.control.add( menuAutoAddControl ); |
1063 api.control.add( menuAutoAddControl ); |
1062 menuAutoAddControl.active.set( true ); |
1064 menuAutoAddControl.active.set( true ); |
1063 } |
1065 } |
1064 |
1066 |
1065 // Add the control for deleting the menu |
1067 // Add the control for deleting the menu. |
1066 menuDeleteControlId = section.id + '[delete]'; |
1068 menuDeleteControlId = section.id + '[delete]'; |
1067 menuDeleteControl = api.control( menuDeleteControlId ); |
1069 menuDeleteControl = api.control( menuDeleteControlId ); |
1068 if ( ! menuDeleteControl ) { |
1070 if ( ! menuDeleteControl ) { |
1069 menuDeleteControl = new api.Control( menuDeleteControlId, { |
1071 menuDeleteControl = new api.Control( menuDeleteControlId, { |
1070 section: section.id, |
1072 section: section.id, |
1124 |
1126 |
1125 if ( expanded ) { |
1127 if ( expanded ) { |
1126 wpNavMenu.menuList = section.contentContainer; |
1128 wpNavMenu.menuList = section.contentContainer; |
1127 wpNavMenu.targetList = wpNavMenu.menuList; |
1129 wpNavMenu.targetList = wpNavMenu.menuList; |
1128 |
1130 |
1129 // Add attributes needed by wpNavMenu |
1131 // Add attributes needed by wpNavMenu. |
1130 $( '#menu-to-edit' ).removeAttr( 'id' ); |
1132 $( '#menu-to-edit' ).removeAttr( 'id' ); |
1131 wpNavMenu.menuList.attr( 'id', 'menu-to-edit' ).addClass( 'menu' ); |
1133 wpNavMenu.menuList.attr( 'id', 'menu-to-edit' ).addClass( 'menu' ); |
1132 |
1134 |
1133 _.each( api.section( section.id ).controls(), function( control ) { |
1135 _.each( api.section( section.id ).controls(), function( control ) { |
1134 if ( 'nav_menu_item' === control.params.type ) { |
1136 if ( 'nav_menu_item' === control.params.type ) { |
1143 args.completeCallback = function() { |
1145 args.completeCallback = function() { |
1144 if ( 'resolved' !== section.deferred.initSortables.state() ) { |
1146 if ( 'resolved' !== section.deferred.initSortables.state() ) { |
1145 wpNavMenu.initSortables(); // Depends on menu-to-edit ID being set above. |
1147 wpNavMenu.initSortables(); // Depends on menu-to-edit ID being set above. |
1146 section.deferred.initSortables.resolve( wpNavMenu.menuList ); // Now MenuControl can extend the sortable. |
1148 section.deferred.initSortables.resolve( wpNavMenu.menuList ); // Now MenuControl can extend the sortable. |
1147 |
1149 |
1148 // @todo Note that wp.customize.reflowPaneContents() is debounced, so this immediate change will show a slight flicker while priorities get updated. |
1150 // @todo Note that wp.customize.reflowPaneContents() is debounced, |
|
1151 // so this immediate change will show a slight flicker while priorities get updated. |
1149 api.control( 'nav_menu[' + String( section.params.menu_id ) + ']' ).reflowMenuItems(); |
1152 api.control( 'nav_menu[' + String( section.params.menu_id ) + ']' ).reflowMenuItems(); |
1150 } |
1153 } |
1151 if ( _.isFunction( completeCallback ) ) { |
1154 if ( _.isFunction( completeCallback ) ) { |
1152 completeCallback(); |
1155 completeCallback(); |
1153 } |
1156 } |
1177 * Create a nav menu setting and section. |
1180 * Create a nav menu setting and section. |
1178 * |
1181 * |
1179 * @since 4.9.0 |
1182 * @since 4.9.0 |
1180 * |
1183 * |
1181 * @param {string} [name=''] Nav menu name. |
1184 * @param {string} [name=''] Nav menu name. |
1182 * @returns {wp.customize.Menus.MenuSection} Added nav menu. |
1185 * @return {wp.customize.Menus.MenuSection} Added nav menu. |
1183 */ |
1186 */ |
1184 api.Menus.createNavMenu = function createNavMenu( name ) { |
1187 api.Menus.createNavMenu = function createNavMenu( name ) { |
1185 var customizeId, placeholderId, setting; |
1188 var customizeId, placeholderId, setting; |
1186 placeholderId = api.Menus.generatePlaceholderAutoIncrementId(); |
1189 placeholderId = api.Menus.generatePlaceholderAutoIncrementId(); |
1187 |
1190 |
1277 |
1280 |
1278 /** |
1281 /** |
1279 * Update visibility of notice to prompt users to create menus. |
1282 * Update visibility of notice to prompt users to create menus. |
1280 * |
1283 * |
1281 * @since 4.9.0 |
1284 * @since 4.9.0 |
1282 * @returns {void} |
1285 * @return {void} |
1283 */ |
1286 */ |
1284 function updateNoticeVisibility() { |
1287 function updateNoticeVisibility() { |
1285 container.find( '.add-new-menu-notice' ).prop( 'hidden', getNavMenuCount() > 0 ); |
1288 container.find( '.add-new-menu-notice' ).prop( 'hidden', getNavMenuCount() > 0 ); |
1286 } |
1289 } |
1287 |
1290 |
1288 /** |
1291 /** |
1289 * Handle setting addition. |
1292 * Handle setting addition. |
1290 * |
1293 * |
1291 * @since 4.9.0 |
1294 * @since 4.9.0 |
1292 * @param {wp.customize.Setting} setting - Added setting. |
1295 * @param {wp.customize.Setting} setting - Added setting. |
1293 * @returns {void} |
1296 * @return {void} |
1294 */ |
1297 */ |
1295 function addChangeEventListener( setting ) { |
1298 function addChangeEventListener( setting ) { |
1296 if ( navMenuSettingPattern.test( setting.id ) ) { |
1299 if ( navMenuSettingPattern.test( setting.id ) ) { |
1297 setting.bind( updateNoticeVisibility ); |
1300 setting.bind( updateNoticeVisibility ); |
1298 updateNoticeVisibility(); |
1301 updateNoticeVisibility(); |
1696 control.elements.attr_title = new api.Element( control.container.find( '.edit-menu-item-attr-title' ) ); |
1699 control.elements.attr_title = new api.Element( control.container.find( '.edit-menu-item-attr-title' ) ); |
1697 control.elements.target = new api.Element( control.container.find( '.edit-menu-item-target' ) ); |
1700 control.elements.target = new api.Element( control.container.find( '.edit-menu-item-target' ) ); |
1698 control.elements.classes = new api.Element( control.container.find( '.edit-menu-item-classes' ) ); |
1701 control.elements.classes = new api.Element( control.container.find( '.edit-menu-item-classes' ) ); |
1699 control.elements.xfn = new api.Element( control.container.find( '.edit-menu-item-xfn' ) ); |
1702 control.elements.xfn = new api.Element( control.container.find( '.edit-menu-item-xfn' ) ); |
1700 control.elements.description = new api.Element( control.container.find( '.edit-menu-item-description' ) ); |
1703 control.elements.description = new api.Element( control.container.find( '.edit-menu-item-description' ) ); |
1701 // @todo allow other elements, added by plugins, to be automatically picked up here; allow additional values to be added to setting array. |
1704 // @todo Allow other elements, added by plugins, to be automatically picked up here; |
|
1705 // allow additional values to be added to setting array. |
1702 |
1706 |
1703 _.each( control.elements, function( element, property ) { |
1707 _.each( control.elements, function( element, property ) { |
1704 element.bind(function( value ) { |
1708 element.bind(function( value ) { |
1705 if ( element.element.is( 'input[type=checkbox]' ) ) { |
1709 if ( element.element.is( 'input[type=checkbox]' ) ) { |
1706 value = ( value ) ? element.element.val() : ''; |
1710 value = ( value ) ? element.element.val() : ''; |
1788 |
1792 |
1789 // Configure delete button. |
1793 // Configure delete button. |
1790 $removeBtn = control.container.find( '.item-delete' ); |
1794 $removeBtn = control.container.find( '.item-delete' ); |
1791 |
1795 |
1792 $removeBtn.on( 'click', function() { |
1796 $removeBtn.on( 'click', function() { |
1793 // Find an adjacent element to add focus to when this menu item goes away |
1797 // Find an adjacent element to add focus to when this menu item goes away. |
1794 var addingItems = true, $adjacentFocusTarget, $next, $prev; |
1798 var addingItems = true, $adjacentFocusTarget, $next, $prev, |
|
1799 instanceCounter = 0, // Instance count of the menu item deleted. |
|
1800 deleteItemOriginalItemId = control.params.original_item_id, |
|
1801 addedItems = control.getMenuControl().$sectionContent.find( '.menu-item' ), |
|
1802 availableMenuItem; |
1795 |
1803 |
1796 if ( ! $( 'body' ).hasClass( 'adding-menu-items' ) ) { |
1804 if ( ! $( 'body' ).hasClass( 'adding-menu-items' ) ) { |
1797 addingItems = false; |
1805 addingItems = false; |
1798 } |
1806 } |
1799 |
1807 |
1806 $adjacentFocusTarget = $prev.find( false === addingItems ? '.item-edit' : '.item-delete' ).first(); |
1814 $adjacentFocusTarget = $prev.find( false === addingItems ? '.item-edit' : '.item-delete' ).first(); |
1807 } else { |
1815 } else { |
1808 $adjacentFocusTarget = control.container.nextAll( '.customize-control-nav_menu' ).find( '.add-new-menu-item' ).first(); |
1816 $adjacentFocusTarget = control.container.nextAll( '.customize-control-nav_menu' ).find( '.add-new-menu-item' ).first(); |
1809 } |
1817 } |
1810 |
1818 |
|
1819 /* |
|
1820 * If the menu item deleted is the only of its instance left, |
|
1821 * remove the check icon of this menu item in the right panel. |
|
1822 */ |
|
1823 _.each( addedItems, function( addedItem ) { |
|
1824 var menuItemId, menuItemControl, matches; |
|
1825 |
|
1826 // This is because menu item that's deleted is just hidden. |
|
1827 if ( ! $( addedItem ).is( ':visible' ) ) { |
|
1828 return; |
|
1829 } |
|
1830 |
|
1831 matches = addedItem.getAttribute( 'id' ).match( /^customize-control-nav_menu_item-(-?\d+)$/, '' ); |
|
1832 if ( ! matches ) { |
|
1833 return; |
|
1834 } |
|
1835 |
|
1836 menuItemId = parseInt( matches[1], 10 ); |
|
1837 menuItemControl = api.control( 'nav_menu_item[' + String( menuItemId ) + ']' ); |
|
1838 |
|
1839 // Check for duplicate menu items. |
|
1840 if ( menuItemControl && deleteItemOriginalItemId == menuItemControl.params.original_item_id ) { |
|
1841 instanceCounter++; |
|
1842 } |
|
1843 } ); |
|
1844 |
|
1845 if ( instanceCounter <= 1 ) { |
|
1846 // Revert the check icon to add icon. |
|
1847 availableMenuItem = $( '#menu-item-tpl-' + control.params.original_item_id ); |
|
1848 availableMenuItem.removeClass( 'selected' ); |
|
1849 availableMenuItem.find( '.menu-item-handle' ).removeClass( 'item-added' ); |
|
1850 } |
|
1851 |
1811 control.container.slideUp( function() { |
1852 control.container.slideUp( function() { |
1812 control.setting.set( false ); |
1853 control.setting.set( false ); |
1813 wp.a11y.speak( api.Menus.data.l10n.itemDeleted ); |
1854 wp.a11y.speak( api.Menus.data.l10n.itemDeleted ); |
1814 $adjacentFocusTarget.focus(); // keyboard accessibility |
1855 $adjacentFocusTarget.focus(); // Keyboard accessibility. |
1815 } ); |
1856 } ); |
1816 |
1857 |
1817 control.setting.set( false ); |
1858 control.setting.set( false ); |
1818 } ); |
1859 } ); |
1819 }, |
1860 }, |
1919 control.params.item_type = settingValue.type; |
1960 control.params.item_type = settingValue.type; |
1920 control.params.url = settingValue.url; |
1961 control.params.url = settingValue.url; |
1921 control.params.target = settingValue.target; |
1962 control.params.target = settingValue.target; |
1922 control.params.attr_title = settingValue.attr_title; |
1963 control.params.attr_title = settingValue.attr_title; |
1923 control.params.classes = _.isArray( settingValue.classes ) ? settingValue.classes.join( ' ' ) : settingValue.classes; |
1964 control.params.classes = _.isArray( settingValue.classes ) ? settingValue.classes.join( ' ' ) : settingValue.classes; |
1924 control.params.attr_title = settingValue.attr_title; |
|
1925 control.params.xfn = settingValue.xfn; |
1965 control.params.xfn = settingValue.xfn; |
1926 control.params.description = settingValue.description; |
1966 control.params.description = settingValue.description; |
1927 control.params.parent = settingValue.menu_item_parent; |
1967 control.params.parent = settingValue.menu_item_parent; |
1928 control.params.original_title = settingValue.original_title || ''; |
1968 control.params.original_title = settingValue.original_title || ''; |
1929 |
1969 |
1961 /** |
2001 /** |
1962 * @since 4.6.0 |
2002 * @since 4.6.0 |
1963 * |
2003 * |
1964 * @param {Boolean} expanded |
2004 * @param {Boolean} expanded |
1965 * @param {Object} [params] |
2005 * @param {Object} [params] |
1966 * @returns {Boolean} false if state already applied |
2006 * @return {Boolean} False if state already applied. |
1967 */ |
2007 */ |
1968 _toggleExpanded: api.Section.prototype._toggleExpanded, |
2008 _toggleExpanded: api.Section.prototype._toggleExpanded, |
1969 |
2009 |
1970 /** |
2010 /** |
1971 * @since 4.6.0 |
2011 * @since 4.6.0 |
1972 * |
2012 * |
1973 * @param {Object} [params] |
2013 * @param {Object} [params] |
1974 * @returns {Boolean} false if already expanded |
2014 * @return {Boolean} False if already expanded. |
1975 */ |
2015 */ |
1976 expand: api.Section.prototype.expand, |
2016 expand: api.Section.prototype.expand, |
1977 |
2017 |
1978 /** |
2018 /** |
1979 * Expand the menu item form control. |
2019 * Expand the menu item form control. |
2427 * set the default location for a new menu. |
2467 * set the default location for a new menu. |
2428 * |
2468 * |
2429 * @since 4.9.0 |
2469 * @since 4.9.0 |
2430 * |
2470 * |
2431 * @param {Object.<string,boolean>} selections - A map of location selections. |
2471 * @param {Object.<string,boolean>} selections - A map of location selections. |
2432 * @returns {void} |
2472 * @return {void} |
2433 */ |
2473 */ |
2434 setSelections: function( selections ) { |
2474 setSelections: function( selections ) { |
2435 this.container.find( '.menu-location' ).each( function( i, checkboxNode ) { |
2475 this.container.find( '.menu-location' ).each( function( i, checkboxNode ) { |
2436 var locationId = checkboxNode.dataset.locationId; |
2476 var locationId = checkboxNode.dataset.locationId; |
2437 checkboxNode.checked = locationId in selections ? selections[ locationId ] : false; |
2477 checkboxNode.checked = locationId in selections ? selections[ locationId ] : false; |
2613 * Allow items in each menu to be re-ordered, and for the order to be previewed. |
2653 * Allow items in each menu to be re-ordered, and for the order to be previewed. |
2614 * |
2654 * |
2615 * Notice that the UI aspects here are handled by wpNavMenu.initSortables() |
2655 * Notice that the UI aspects here are handled by wpNavMenu.initSortables() |
2616 * which is called in MenuSection.onChangeExpanded() |
2656 * which is called in MenuSection.onChangeExpanded() |
2617 * |
2657 * |
2618 * @param {object} menuList - The element that has sortable(). |
2658 * @param {Object} menuList - The element that has sortable(). |
2619 */ |
2659 */ |
2620 _setupSortable: function( menuList ) { |
2660 _setupSortable: function( menuList ) { |
2621 var control = this; |
2661 var control = this; |
2622 |
2662 |
2623 if ( ! menuList.is( control.$sectionContent ) ) { |
2663 if ( ! menuList.is( control.$sectionContent ) ) { |
2777 sectionTitle = section.contentContainer.find( '.customize-section-title h3' ), |
2817 sectionTitle = section.contentContainer.find( '.customize-section-title h3' ), |
2778 location = section.headContainer.find( '.menu-in-location' ), |
2818 location = section.headContainer.find( '.menu-in-location' ), |
2779 action = sectionTitle.find( '.customize-action' ), |
2819 action = sectionTitle.find( '.customize-action' ), |
2780 name = displayNavMenuName( menu.name ); |
2820 name = displayNavMenuName( menu.name ); |
2781 |
2821 |
2782 // Update the control title |
2822 // Update the control title. |
2783 controlTitle.text( name ); |
2823 controlTitle.text( name ); |
2784 if ( location.length ) { |
2824 if ( location.length ) { |
2785 location.appendTo( controlTitle ); |
2825 location.appendTo( controlTitle ); |
2786 } |
2826 } |
2787 |
2827 |
2788 // Update the section title |
2828 // Update the section title. |
2789 sectionTitle.text( name ); |
2829 sectionTitle.text( name ); |
2790 if ( action.length ) { |
2830 if ( action.length ) { |
2791 action.prependTo( sectionTitle ); |
2831 action.prependTo( sectionTitle ); |
2792 } |
2832 } |
2793 |
2833 |
2812 **********************************************************************/ |
2852 **********************************************************************/ |
2813 |
2853 |
2814 /** |
2854 /** |
2815 * Enable/disable the reordering UI |
2855 * Enable/disable the reordering UI |
2816 * |
2856 * |
2817 * @param {Boolean} showOrHide to enable/disable reordering |
2857 * @param {boolean} showOrHide to enable/disable reordering |
2818 */ |
2858 */ |
2819 toggleReordering: function( showOrHide ) { |
2859 toggleReordering: function( showOrHide ) { |
2820 var addNewItemBtn = this.container.find( '.add-new-menu-item' ), |
2860 var addNewItemBtn = this.container.find( '.add-new-menu-item' ), |
2821 reorderBtn = this.container.find( '.reorder-toggle' ), |
2861 reorderBtn = this.container.find( '.reorder-toggle' ), |
2822 itemsTitle = this.$sectionContent.find( '.item-title' ); |
2862 itemsTitle = this.$sectionContent.find( '.item-title' ); |
2952 }, 0 ), |
2992 }, 0 ), |
2953 |
2993 |
2954 /** |
2994 /** |
2955 * Add a new item to this menu. |
2995 * Add a new item to this menu. |
2956 * |
2996 * |
2957 * @param {object} item - Value for the nav_menu_item setting to be created. |
2997 * @param {Object} item - Value for the nav_menu_item setting to be created. |
2958 * @returns {wp.customize.Menus.controlConstructor.nav_menu_item} The newly-created nav_menu_item control instance. |
2998 * @return {wp.customize.Menus.controlConstructor.nav_menu_item} The newly-created nav_menu_item control instance. |
2959 */ |
2999 */ |
2960 addItemToMenu: function( item ) { |
3000 addItemToMenu: function( item ) { |
2961 var menuControl = this, customizeId, settingArgs, setting, menuItemControl, placeholderId, position = 0, priority = 10; |
3001 var menuControl = this, customizeId, settingArgs, setting, menuItemControl, placeholderId, position = 0, priority = 10, |
|
3002 originalItemId = item.id || ''; |
2962 |
3003 |
2963 _.each( menuControl.getMenuItemControls(), function( control ) { |
3004 _.each( menuControl.getMenuItemControls(), function( control ) { |
2964 if ( false === control.setting() ) { |
3005 if ( false === control.setting() ) { |
2965 return; |
3006 return; |
2966 } |
3007 } |
2980 nav_menu_term_id: menuControl.params.menu_id, |
3021 nav_menu_term_id: menuControl.params.menu_id, |
2981 original_title: item.title, |
3022 original_title: item.title, |
2982 position: position |
3023 position: position |
2983 } |
3024 } |
2984 ); |
3025 ); |
2985 delete item.id; // only used by Backbone |
3026 delete item.id; // Only used by Backbone. |
2986 |
3027 |
2987 placeholderId = api.Menus.generatePlaceholderAutoIncrementId(); |
3028 placeholderId = api.Menus.generatePlaceholderAutoIncrementId(); |
2988 customizeId = 'nav_menu_item[' + String( placeholderId ) + ']'; |
3029 customizeId = 'nav_menu_item[' + String( placeholderId ) + ']'; |
2989 settingArgs = { |
3030 settingArgs = { |
2990 type: 'nav_menu_item', |
3031 type: 'nav_menu_item', |
3025 var menuItemControls = optionalMenuItemControls || this.getMenuItemControls(); |
3067 var menuItemControls = optionalMenuItemControls || this.getMenuItemControls(); |
3026 |
3068 |
3027 this.container.find( '.new-menu-item-invitation' ).toggle( menuItemControls.length === 0 ); |
3069 this.container.find( '.new-menu-item-invitation' ).toggle( menuItemControls.length === 0 ); |
3028 } |
3070 } |
3029 } ); |
3071 } ); |
3030 |
|
3031 api.Menus.NewMenuControl = api.Control.extend(/** @lends wp.customize.Menus.NewMenuControl.prototype */{ |
|
3032 |
|
3033 /** |
|
3034 * wp.customize.Menus.NewMenuControl |
|
3035 * |
|
3036 * Customizer control for creating new menus and handling deletion of existing menus. |
|
3037 * Note that 'new_menu' must match the WP_Customize_New_Menu_Control::$type. |
|
3038 * |
|
3039 * @constructs wp.customize.Menus.NewMenuControl |
|
3040 * @augments wp.customize.Control |
|
3041 * |
|
3042 * @deprecated 4.9.0 This class is no longer used due to new menu creation UX. |
|
3043 */ |
|
3044 initialize: function() { |
|
3045 if ( 'undefined' !== typeof console && console.warn ) { |
|
3046 console.warn( '[DEPRECATED] wp.customize.NewMenuControl will be removed. Please use wp.customize.Menus.createNavMenu() instead.' ); |
|
3047 } |
|
3048 api.Control.prototype.initialize.apply( this, arguments ); |
|
3049 }, |
|
3050 |
|
3051 /** |
|
3052 * Set up the control. |
|
3053 * |
|
3054 * @deprecated 4.9.0 |
|
3055 */ |
|
3056 ready: function() { |
|
3057 this._bindHandlers(); |
|
3058 }, |
|
3059 |
|
3060 _bindHandlers: function() { |
|
3061 var self = this, |
|
3062 name = $( '#customize-control-new_menu_name input' ), |
|
3063 submit = $( '#create-new-menu-submit' ); |
|
3064 name.on( 'keydown', function( event ) { |
|
3065 if ( 13 === event.which ) { // Enter. |
|
3066 self.submit(); |
|
3067 } |
|
3068 } ); |
|
3069 submit.on( 'click', function( event ) { |
|
3070 self.submit(); |
|
3071 event.stopPropagation(); |
|
3072 event.preventDefault(); |
|
3073 } ); |
|
3074 }, |
|
3075 |
|
3076 /** |
|
3077 * Create the new menu with the name supplied. |
|
3078 * |
|
3079 * @deprecated 4.9.0 |
|
3080 */ |
|
3081 submit: function() { |
|
3082 |
|
3083 var control = this, |
|
3084 container = control.container.closest( '.accordion-section-new-menu' ), |
|
3085 nameInput = container.find( '.menu-name-field' ).first(), |
|
3086 name = nameInput.val(), |
|
3087 menuSection; |
|
3088 |
|
3089 if ( ! name ) { |
|
3090 nameInput.addClass( 'invalid' ); |
|
3091 nameInput.focus(); |
|
3092 return; |
|
3093 } |
|
3094 |
|
3095 menuSection = api.Menus.createNavMenu( name ); |
|
3096 |
|
3097 // Clear name field. |
|
3098 nameInput.val( '' ); |
|
3099 nameInput.removeClass( 'invalid' ); |
|
3100 |
|
3101 wp.a11y.speak( api.Menus.data.l10n.menuAdded ); |
|
3102 |
|
3103 // Focus on the new menu section. |
|
3104 menuSection.focus(); |
|
3105 } |
|
3106 }); |
|
3107 |
3072 |
3108 /** |
3073 /** |
3109 * Extends wp.customize.controlConstructor with control constructor for |
3074 * Extends wp.customize.controlConstructor with control constructor for |
3110 * menu_location, menu_item, nav_menu, and new_menu. |
3075 * menu_location, menu_item, nav_menu, and new_menu. |
3111 */ |
3076 */ |
3112 $.extend( api.controlConstructor, { |
3077 $.extend( api.controlConstructor, { |
3113 nav_menu_location: api.Menus.MenuLocationControl, |
3078 nav_menu_location: api.Menus.MenuLocationControl, |
3114 nav_menu_item: api.Menus.MenuItemControl, |
3079 nav_menu_item: api.Menus.MenuItemControl, |
3115 nav_menu: api.Menus.MenuControl, |
3080 nav_menu: api.Menus.MenuControl, |
3116 nav_menu_name: api.Menus.MenuNameControl, |
3081 nav_menu_name: api.Menus.MenuNameControl, |
3117 new_menu: api.Menus.NewMenuControl, // @todo Remove in a future release. See #42364. |
|
3118 nav_menu_locations: api.Menus.MenuLocationsControl, |
3082 nav_menu_locations: api.Menus.MenuLocationsControl, |
3119 nav_menu_auto_add: api.Menus.MenuAutoAddControl |
3083 nav_menu_auto_add: api.Menus.MenuAutoAddControl |
3120 }); |
3084 }); |
3121 |
3085 |
3122 /** |
3086 /** |
3169 * When customize_save comes back with a success, make sure any inserted |
3133 * When customize_save comes back with a success, make sure any inserted |
3170 * nav menus and items are properly re-added with their newly-assigned IDs. |
3134 * nav menus and items are properly re-added with their newly-assigned IDs. |
3171 * |
3135 * |
3172 * @alias wp.customize.Menus.applySavedData |
3136 * @alias wp.customize.Menus.applySavedData |
3173 * |
3137 * |
3174 * @param {object} data |
3138 * @param {Object} data |
3175 * @param {array} data.nav_menu_updates |
3139 * @param {Array} data.nav_menu_updates |
3176 * @param {array} data.nav_menu_item_updates |
3140 * @param {Array} data.nav_menu_item_updates |
3177 */ |
3141 */ |
3178 api.Menus.applySavedData = function( data ) { |
3142 api.Menus.applySavedData = function( data ) { |
3179 |
3143 |
3180 var insertedMenuIdMapping = {}, insertedMenuItemIdMapping = {}; |
3144 var insertedMenuIdMapping = {}, insertedMenuItemIdMapping = {}; |
3181 |
3145 |
3428 * Given a menu item ID, get the control associated with it. |
3392 * Given a menu item ID, get the control associated with it. |
3429 * |
3393 * |
3430 * @alias wp.customize.Menus.getMenuItemControl |
3394 * @alias wp.customize.Menus.getMenuItemControl |
3431 * |
3395 * |
3432 * @param {string} menuItemId |
3396 * @param {string} menuItemId |
3433 * @return {object|null} |
3397 * @return {Object|null} |
3434 */ |
3398 */ |
3435 api.Menus.getMenuItemControl = function( menuItemId ) { |
3399 api.Menus.getMenuItemControl = function( menuItemId ) { |
3436 return api.control( menuItemIdToSettingId( menuItemId ) ); |
3400 return api.control( menuItemIdToSettingId( menuItemId ) ); |
3437 }; |
3401 }; |
3438 |
3402 |
3439 /** |
3403 /** |
3440 * @alias wp.customize.Menus~menuItemIdToSettingId |
3404 * @alias wp.customize.Menus~menuItemIdToSettingId |
3441 * |
3405 * |
3442 * @param {String} menuItemId |
3406 * @param {string} menuItemId |
3443 */ |
3407 */ |
3444 function menuItemIdToSettingId( menuItemId ) { |
3408 function menuItemIdToSettingId( menuItemId ) { |
3445 return 'nav_menu_item[' + menuItemId + ']'; |
3409 return 'nav_menu_item[' + menuItemId + ']'; |
3446 } |
3410 } |
3447 |
3411 |