wp/wp-admin/js/customize-nav-menus.js
changeset 22 8c2e4d02f4ef
parent 21 48c4eec2b7e6
equal deleted inserted replaced
21:48c4eec2b7e6 22:8c2e4d02f4ef
   221 				self.$search.val( '' ).trigger( 'focus' ).trigger( 'input' );
   221 				self.$search.val( '' ).trigger( 'focus' ).trigger( 'input' );
   222 			} );
   222 			} );
   223 
   223 
   224 			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() {
   225 				$( this ).removeClass( 'invalid' );
   225 				$( this ).removeClass( 'invalid' );
       
   226 				var errorMessageId = $( this ).attr( 'aria-describedby' );
       
   227 				$( '#' + errorMessageId ).hide();
       
   228 				$( this ).removeAttr( 'aria-invalid' ).removeAttr( 'aria-describedby' );
   226 			});
   229 			});
   227 
   230 
   228 			// Load available items if it looks like we'll need them.
   231 			// Load available items if it looks like we'll need them.
   229 			api.panel( 'nav_menus' ).container.on( 'expanded', function() {
   232 			api.panel( 'nav_menus' ).container.on( 'expanded', function() {
   230 				if ( ! self.rendered ) {
   233 				if ( ! self.rendered ) {
   544 		// Adds the custom menu item to the menu.
   547 		// Adds the custom menu item to the menu.
   545 		submitLink: function() {
   548 		submitLink: function() {
   546 			var menuItem,
   549 			var menuItem,
   547 				itemName = $( '#custom-menu-item-name' ),
   550 				itemName = $( '#custom-menu-item-name' ),
   548 				itemUrl = $( '#custom-menu-item-url' ),
   551 				itemUrl = $( '#custom-menu-item-url' ),
       
   552 				urlErrorMessage = $( '#custom-url-error' ),
       
   553 				nameErrorMessage = $( '#custom-name-error' ),
   549 				url = itemUrl.val().trim(),
   554 				url = itemUrl.val().trim(),
   550 				urlRegex;
   555 				urlRegex,
       
   556 				errorText;
   551 
   557 
   552 			if ( ! this.currentMenuControl ) {
   558 			if ( ! this.currentMenuControl ) {
   553 				return;
   559 				return;
   554 			}
   560 			}
   555 
   561 
   564 			 *
   570 			 *
   565 			 * Any further validation will be handled on the server when the setting is attempted to be saved,
   571 			 * Any further validation will be handled on the server when the setting is attempted to be saved,
   566 			 * so this pattern does not need to be complete.
   572 			 * so this pattern does not need to be complete.
   567 			 */
   573 			 */
   568 			urlRegex = /^((\w+:)?\/\/\w.*|\w+:(?!\/\/$)|\/|\?|#)/;
   574 			urlRegex = /^((\w+:)?\/\/\w.*|\w+:(?!\/\/$)|\/|\?|#)/;
   569 
   575 			if ( ! urlRegex.test( url ) || '' === itemName.val() ) {
   570 			if ( '' === itemName.val() ) {
   576 				if ( ! urlRegex.test( url ) ) {
   571 				itemName.addClass( 'invalid' );
   577 					itemUrl.addClass( 'invalid' )
       
   578 						.attr( 'aria-invalid', 'true' )
       
   579 						.attr( 'aria-describedby', 'custom-url-error' );
       
   580 					urlErrorMessage.show();
       
   581 					errorText = urlErrorMessage.text();
       
   582 					// Announce error message via screen reader
       
   583 					wp.a11y.speak( errorText, 'assertive' );
       
   584 				}
       
   585 				if ( '' === itemName.val() ) {
       
   586 					itemName.addClass( 'invalid' )
       
   587 						.attr( 'aria-invalid', 'true' )
       
   588 						.attr( 'aria-describedby', 'custom-name-error' );
       
   589 					nameErrorMessage.show();
       
   590 					errorText = ( '' === errorText ) ? nameErrorMessage.text() : errorText + nameErrorMessage.text();
       
   591 					// Announce error message via screen reader
       
   592 					wp.a11y.speak( errorText, 'assertive' );
       
   593 				}
   572 				return;
   594 				return;
   573 			} else if ( ! urlRegex.test( url ) ) {
   595 			}
   574 				itemUrl.addClass( 'invalid' );
   596 
   575 				return;
   597 			urlErrorMessage.hide();
   576 			}
   598 			nameErrorMessage.hide();
       
   599 			itemName.removeClass( 'invalid' )
       
   600 				.removeAttr( 'aria-invalid', 'true' )
       
   601 				.removeAttr( 'aria-describedby', 'custom-name-error' );
       
   602 			itemUrl.removeClass( 'invalid' )
       
   603 				.removeAttr( 'aria-invalid', 'true' )
       
   604 				.removeAttr( 'aria-describedby', 'custom-name-error' );
   577 
   605 
   578 			menuItem = {
   606 			menuItem = {
   579 				'title': itemName.val(),
   607 				'title': itemName.val(),
   580 				'url': url,
   608 				'url': url,
   581 				'type': 'custom',
   609 				'type': 'custom',
  1105 		 */
  1133 		 */
  1106 		updateAssignedLocationsInSectionTitle: function( themeLocationSlugs ) {
  1134 		updateAssignedLocationsInSectionTitle: function( themeLocationSlugs ) {
  1107 			var section = this,
  1135 			var section = this,
  1108 				$title;
  1136 				$title;
  1109 
  1137 
  1110 			$title = section.container.find( '.accordion-section-title:first' );
  1138 			$title = section.container.find( '.accordion-section-title button:first' );
  1111 			$title.find( '.menu-in-location' ).remove();
  1139 			$title.find( '.menu-in-location' ).remove();
  1112 			_.each( themeLocationSlugs, function( themeLocationSlug ) {
  1140 			_.each( themeLocationSlugs, function( themeLocationSlug ) {
  1113 				var $label, locationName;
  1141 				var $label, locationName;
  1114 				$label = $( '<span class="menu-in-location"></span>' );
  1142 				$label = $( '<span class="menu-in-location"></span>' );
  1115 				locationName = api.Menus.data.locationSlugMappedToName[ themeLocationSlug ];
  1143 				locationName = api.Menus.data.locationSlugMappedToName[ themeLocationSlug ];