wp/wp-admin/js/widgets.js
changeset 9 177826044cd9
parent 7 cf61fcea0001
child 16 a86126ab1dd4
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
     1 /*global ajaxurl, isRtl */
     1 /**
     2 var wpWidgets;
     2  * @output wp-admin/js/widgets.js
       
     3  */
       
     4 
       
     5 /* global ajaxurl, isRtl, wpWidgets */
       
     6 
     3 (function($) {
     7 (function($) {
     4 	var $document = $( document );
     8 	var $document = $( document );
     5 
     9 
     6 wpWidgets = {
    10 window.wpWidgets = {
     7 	/**
    11 	/**
     8 	 * A closed Sidebar that gets a Widget dragged over it.
    12 	 * A closed Sidebar that gets a Widget dragged over it.
     9 	 *
    13 	 *
    10 	 * @var {element|null}
    14 	 * @var {element|null}
    11 	 */
    15 	 */
    19 	 * @var {object}
    23 	 * @var {object}
    20 	 */
    24 	 */
    21 	l10n: {
    25 	l10n: {
    22 		save: '{save}',
    26 		save: '{save}',
    23 		saved: '{saved}',
    27 		saved: '{saved}',
    24 		saveAlert: '{saveAlert}'
    28 		saveAlert: '{saveAlert}',
       
    29 		widgetAdded: '{widgetAdded}'
    25 	},
    30 	},
    26 
    31 
    27 	/**
    32 	/**
    28 	 * Lookup of which widgets have had change events triggered.
    33 	 * Lookup of which widgets have had change events triggered.
    29 	 *
    34 	 *
   174 					inside.slideUp( 'fast', function() {
   179 					inside.slideUp( 'fast', function() {
   175 						widget.attr( 'style', '' );
   180 						widget.attr( 'style', '' );
   176 						widget.removeClass( 'open' );
   181 						widget.removeClass( 'open' );
   177 					});
   182 					});
   178 				}
   183 				}
   179 				e.preventDefault();
       
   180 			} else if ( target.hasClass('widget-control-save') ) {
   184 			} else if ( target.hasClass('widget-control-save') ) {
   181 				wpWidgets.save( target.closest('div.widget'), 0, 1, 0 );
   185 				wpWidgets.save( target.closest('div.widget'), 0, 1, 0 );
   182 				e.preventDefault();
   186 				e.preventDefault();
   183 			} else if ( target.hasClass('widget-control-remove') ) {
   187 			} else if ( target.hasClass('widget-control-remove') ) {
   184 				wpWidgets.save( target.closest('div.widget'), 1, 1, 0 );
   188 				wpWidgets.save( target.closest('div.widget'), 1, 1, 0 );
   185 				e.preventDefault();
       
   186 			} else if ( target.hasClass('widget-control-close') ) {
   189 			} else if ( target.hasClass('widget-control-close') ) {
   187 				widget = target.closest('div.widget');
   190 				widget = target.closest('div.widget');
   188 				widget.removeClass( 'open' );
   191 				widget.removeClass( 'open' );
   189 				toggleBtn.attr( 'aria-expanded', 'false' );
   192 				toggleBtn.attr( 'aria-expanded', 'false' );
   190 				wpWidgets.close( widget );
   193 				wpWidgets.close( widget );
   191 				e.preventDefault();
       
   192 			} else if ( target.attr( 'id' ) === 'inactive-widgets-control-remove' ) {
   194 			} else if ( target.attr( 'id' ) === 'inactive-widgets-control-remove' ) {
   193 				wpWidgets.removeInactiveWidgets();
   195 				wpWidgets.removeInactiveWidgets();
   194 				e.preventDefault();
   196 				e.preventDefault();
   195 			}
   197 			}
   196 		});
   198 		});
   243 			tolerance: 'intersect',
   245 			tolerance: 'intersect',
   244 
   246 
   245 			/**
   247 			/**
   246 			 * Open Sidebar when a Widget gets dragged over it.
   248 			 * Open Sidebar when a Widget gets dragged over it.
   247 			 *
   249 			 *
       
   250 			 * @ignore
       
   251 			 *
   248 			 * @param {object} event jQuery event object.
   252 			 * @param {object} event jQuery event object.
   249 			 */
   253 			 */
   250 			over: function( event ) {
   254 			over: function( event ) {
   251 				var $wrap = $( event.target ).parent();
   255 				var $wrap = $( event.target ).parent();
   252 
   256 
   265 				$( this ).sortable( 'refresh' );
   269 				$( this ).sortable( 'refresh' );
   266 			},
   270 			},
   267 
   271 
   268 			/**
   272 			/**
   269 			 * Close Sidebar when the Widget gets dragged out of it.
   273 			 * Close Sidebar when the Widget gets dragged out of it.
       
   274 			 *
       
   275 			 * @ignore
   270 			 *
   276 			 *
   271 			 * @param {object} event jQuery event object.
   277 			 * @param {object} event jQuery event object.
   272 			 */
   278 			 */
   273 			out: function( event ) {
   279 			out: function( event ) {
   274 				if ( wpWidgets.hoveredSidebar ) {
   280 				if ( wpWidgets.hoveredSidebar ) {
   427 
   433 
   428 		// Area Chooser
   434 		// Area Chooser
   429 		$( '#widgets-right .widgets-holder-wrap' ).each( function( index, element ) {
   435 		$( '#widgets-right .widgets-holder-wrap' ).each( function( index, element ) {
   430 			var $element = $( element ),
   436 			var $element = $( element ),
   431 				name = $element.find( '.sidebar-name h2' ).text(),
   437 				name = $element.find( '.sidebar-name h2' ).text(),
       
   438 				ariaLabel = $element.find( '.sidebar-name' ).data( 'add-to' ),
   432 				id = $element.find( '.widgets-sortables' ).attr( 'id' ),
   439 				id = $element.find( '.widgets-sortables' ).attr( 'id' ),
   433 				li = $('<li tabindex="0">').text( $.trim( name ) );
   440 				li = $( '<li>' ),
       
   441 				button = $( '<button>', {
       
   442 					type: 'button',
       
   443 					'aria-pressed': 'false',
       
   444 					'class': 'widgets-chooser-button',
       
   445 					'aria-label': ariaLabel
       
   446 				} ).text( $.trim( name ) );
       
   447 
       
   448 			li.append( button );
   434 
   449 
   435 			if ( index === 0 ) {
   450 			if ( index === 0 ) {
   436 				li.addClass( 'widgets-chooser-selected' );
   451 				li.addClass( 'widgets-chooser-selected' );
       
   452 				button.attr( 'aria-pressed', 'true' );
   437 			}
   453 			}
   438 
   454 
   439 			selectSidebar.append( li );
   455 			selectSidebar.append( li );
   440 			li.data( 'sidebarId', id );
   456 			li.data( 'sidebarId', id );
   441 		});
   457 		});
   442 
   458 
   443 		$( '#available-widgets .widget .widget-title' ).on( 'click.widgets-chooser', function() {
   459 		$( '#available-widgets .widget .widget-top' ).on( 'click.widgets-chooser', function() {
   444 			var $widget = $(this).closest( '.widget' );
   460 			var $widget = $( this ).closest( '.widget' ),
       
   461 				toggleButton = $( this ).find( '.widget-action' ),
       
   462 				chooserButtons = selectSidebar.find( '.widgets-chooser-button' );
   445 
   463 
   446 			if ( $widget.hasClass( 'widget-in-question' ) || $( '#widgets-left' ).hasClass( 'chooser' ) ) {
   464 			if ( $widget.hasClass( 'widget-in-question' ) || $( '#widgets-left' ).hasClass( 'chooser' ) ) {
       
   465 				toggleButton.attr( 'aria-expanded', 'false' );
   447 				self.closeChooser();
   466 				self.closeChooser();
   448 			} else {
   467 			} else {
   449 				// Open the chooser
   468 				// Open the chooser
   450 				self.clearWidgetSelection();
   469 				self.clearWidgetSelection();
   451 				$( '#widgets-left' ).addClass( 'chooser' );
   470 				$( '#widgets-left' ).addClass( 'chooser' );
       
   471 				// Add CSS class and insert the chooser after the widget description.
   452 				$widget.addClass( 'widget-in-question' ).children( '.widget-description' ).after( chooser );
   472 				$widget.addClass( 'widget-in-question' ).children( '.widget-description' ).after( chooser );
   453 
   473 				// Open the chooser with a slide down animation.
   454 				chooser.slideDown( 300, function() {
   474 				chooser.slideDown( 300, function() {
   455 					selectSidebar.find('.widgets-chooser-selected').focus();
   475 					// Update the toggle button aria-expanded attribute after previous DOM manipulations.
       
   476 					toggleButton.attr( 'aria-expanded', 'true' );
   456 				});
   477 				});
   457 
   478 
   458 				selectSidebar.find( 'li' ).on( 'focusin.widgets-chooser', function() {
   479 				chooserButtons.on( 'click.widgets-chooser', function() {
   459 					selectSidebar.find('.widgets-chooser-selected').removeClass( 'widgets-chooser-selected' );
   480 					selectSidebar.find( '.widgets-chooser-selected' ).removeClass( 'widgets-chooser-selected' );
   460 					$(this).addClass( 'widgets-chooser-selected' );
   481 					chooserButtons.attr( 'aria-pressed', 'false' );
       
   482 					$( this )
       
   483 						.attr( 'aria-pressed', 'true' )
       
   484 						.closest( 'li' ).addClass( 'widgets-chooser-selected' );
   461 				} );
   485 				} );
   462 			}
   486 			}
   463 		});
   487 		});
   464 
   488 
   465 		// Add event handlers
   489 		// Add event handlers
   471 				self.closeChooser();
   495 				self.closeChooser();
   472 			} else if ( $target.hasClass( 'widgets-chooser-cancel' ) ) {
   496 			} else if ( $target.hasClass( 'widgets-chooser-cancel' ) ) {
   473 				self.closeChooser();
   497 				self.closeChooser();
   474 			}
   498 			}
   475 		}).on( 'keyup.widgets-chooser', function( event ) {
   499 		}).on( 'keyup.widgets-chooser', function( event ) {
   476 			if ( event.which === $.ui.keyCode.ENTER ) {
   500 			if ( event.which === $.ui.keyCode.ESCAPE ) {
   477 				if ( $( event.target ).hasClass( 'widgets-chooser-cancel' ) ) {
       
   478 					// Close instead of adding when pressing Enter on the Cancel button
       
   479 					self.closeChooser();
       
   480 				} else {
       
   481 					self.addWidget( chooser );
       
   482 					self.closeChooser();
       
   483 				}
       
   484 			} else if ( event.which === $.ui.keyCode.ESCAPE ) {
       
   485 				self.closeChooser();
   501 				self.closeChooser();
   486 			}
   502 			}
   487 		});
   503 		});
   488 	},
   504 	},
   489 
   505 
   699 
   715 
   700 		window.setTimeout( function() {
   716 		window.setTimeout( function() {
   701 			// Cannot use a callback in the animation above as it fires twice,
   717 			// Cannot use a callback in the animation above as it fires twice,
   702 			// have to queue this "by hand".
   718 			// have to queue this "by hand".
   703 			widget.find( '.widget-title' ).trigger('click');
   719 			widget.find( '.widget-title' ).trigger('click');
       
   720 			// At the end of the animation, announce the widget has been added.
       
   721 			window.wp.a11y.speak( wpWidgets.l10n.widgetAdded, 'assertive' );
   704 		}, 250 );
   722 		}, 250 );
   705 	},
   723 	},
   706 
   724 
   707 	closeChooser: function() {
   725 	closeChooser: function() {
   708 		var self = this;
   726 		var self = this,
       
   727 			widgetInQuestion = $( '#available-widgets .widget-in-question' );
   709 
   728 
   710 		$( '.widgets-chooser' ).slideUp( 200, function() {
   729 		$( '.widgets-chooser' ).slideUp( 200, function() {
   711 			$( '#wpbody-content' ).append( this );
   730 			$( '#wpbody-content' ).append( this );
   712 			self.clearWidgetSelection();
   731 			self.clearWidgetSelection();
       
   732 			// Move focus back to the toggle button.
       
   733 			widgetInQuestion.find( '.widget-action' ).attr( 'aria-expanded', 'false' ).focus();
   713 		});
   734 		});
   714 	},
   735 	},
   715 
   736 
   716 	clearWidgetSelection: function() {
   737 	clearWidgetSelection: function() {
   717 		$( '#widgets-left' ).removeClass( 'chooser' );
   738 		$( '#widgets-left' ).removeClass( 'chooser' );