|
1 /** |
|
2 * @output wp-admin/js/customize-widgets.js |
|
3 */ |
|
4 |
1 /* global _wpCustomizeWidgetsSettings */ |
5 /* global _wpCustomizeWidgetsSettings */ |
2 (function( wp, $ ){ |
6 (function( wp, $ ){ |
3 |
7 |
4 if ( ! wp || ! wp.customize ) { return; } |
8 if ( ! wp || ! wp.customize ) { return; } |
5 |
9 |
6 // Set up our namespace... |
10 // Set up our namespace... |
7 var api = wp.customize, |
11 var api = wp.customize, |
8 l10n; |
12 l10n; |
9 |
13 |
|
14 /** |
|
15 * @namespace wp.customize.Widgets |
|
16 */ |
10 api.Widgets = api.Widgets || {}; |
17 api.Widgets = api.Widgets || {}; |
11 api.Widgets.savedWidgetIds = {}; |
18 api.Widgets.savedWidgetIds = {}; |
12 |
19 |
13 // Link settings |
20 // Link settings |
14 api.Widgets.data = _wpCustomizeWidgetsSettings || {}; |
21 api.Widgets.data = _wpCustomizeWidgetsSettings || {}; |
43 /** |
50 /** |
44 * wp.customize.Widgets.WidgetCollection |
51 * wp.customize.Widgets.WidgetCollection |
45 * |
52 * |
46 * Collection for widget models. |
53 * Collection for widget models. |
47 * |
54 * |
48 * @constructor |
55 * @class wp.customize.Widgets.WidgetCollection |
49 * @augments Backbone.Model |
56 * @augments Backbone.Collection |
50 */ |
57 */ |
51 api.Widgets.WidgetCollection = Backbone.Collection.extend({ |
58 api.Widgets.WidgetCollection = Backbone.Collection.extend(/** @lends wp.customize.Widgets.WidgetCollection.prototype */{ |
52 model: api.Widgets.WidgetModel, |
59 model: api.Widgets.WidgetModel, |
53 |
60 |
54 // Controls searching on the current widget collection |
61 // Controls searching on the current widget collection |
55 // and triggers an update event |
62 // and triggers an update event |
56 doSearch: function( value ) { |
63 doSearch: function( value ) { |
121 /** |
128 /** |
122 * wp.customize.Widgets.SidebarCollection |
129 * wp.customize.Widgets.SidebarCollection |
123 * |
130 * |
124 * Collection for sidebar models. |
131 * Collection for sidebar models. |
125 * |
132 * |
126 * @constructor |
133 * @class wp.customize.Widgets.SidebarCollection |
127 * @augments Backbone.Collection |
134 * @augments Backbone.Collection |
128 */ |
135 */ |
129 api.Widgets.SidebarCollection = Backbone.Collection.extend({ |
136 api.Widgets.SidebarCollection = Backbone.Collection.extend(/** @lends wp.customize.Widgets.SidebarCollection.prototype */{ |
130 model: api.Widgets.SidebarModel |
137 model: api.Widgets.SidebarModel |
131 }); |
138 }); |
132 api.Widgets.registeredSidebars = new api.Widgets.SidebarCollection( api.Widgets.data.registeredSidebars ); |
139 api.Widgets.registeredSidebars = new api.Widgets.SidebarCollection( api.Widgets.data.registeredSidebars ); |
133 |
140 |
134 /** |
141 api.Widgets.AvailableWidgetsPanelView = wp.Backbone.View.extend(/** @lends wp.customize.Widgets.AvailableWidgetsPanelView.prototype */{ |
135 * wp.customize.Widgets.AvailableWidgetsPanelView |
|
136 * |
|
137 * View class for the available widgets panel. |
|
138 * |
|
139 * @constructor |
|
140 * @augments wp.Backbone.View |
|
141 * @augments Backbone.View |
|
142 */ |
|
143 api.Widgets.AvailableWidgetsPanelView = wp.Backbone.View.extend({ |
|
144 |
142 |
145 el: '#available-widgets', |
143 el: '#available-widgets', |
146 |
144 |
147 events: { |
145 events: { |
148 'input #widgets-search': 'search', |
146 'input #widgets-search': 'search', |
149 'keyup #widgets-search': 'search', |
|
150 'focus .widget-tpl' : 'focus', |
147 'focus .widget-tpl' : 'focus', |
151 'click .widget-tpl' : '_submit', |
148 'click .widget-tpl' : '_submit', |
152 'keypress .widget-tpl' : '_submit', |
149 'keypress .widget-tpl' : '_submit', |
153 'keydown' : 'keyboardAccessible' |
150 'keydown' : 'keyboardAccessible' |
154 }, |
151 }, |
238 if ( ! this.searchMatchesCount ) { |
243 if ( ! this.searchMatchesCount ) { |
239 this.$el.addClass( 'no-widgets-found' ); |
244 this.$el.addClass( 'no-widgets-found' ); |
240 } else { |
245 } else { |
241 this.$el.removeClass( 'no-widgets-found' ); |
246 this.$el.removeClass( 'no-widgets-found' ); |
242 } |
247 } |
243 }, |
248 }, 500 ), |
244 |
249 |
245 // Update the count of the available widgets that have the `search_matched` attribute. |
250 /** |
|
251 * Updates the count of the available widgets that have the `search_matched` attribute. |
|
252 */ |
246 updateSearchMatchesCount: function() { |
253 updateSearchMatchesCount: function() { |
247 this.searchMatchesCount = this.collection.where({ search_matched: true }).length; |
254 this.searchMatchesCount = this.collection.where({ search_matched: true }).length; |
248 }, |
255 }, |
249 |
256 |
250 // Send a message to the aria-live region to announce how many search results. |
257 /** |
251 announceSearchMatches: _.debounce( function() { |
258 * Sends a message to the aria-live region to announce how many search results. |
|
259 */ |
|
260 announceSearchMatches: function() { |
252 var message = l10n.widgetsFound.replace( '%d', this.searchMatchesCount ) ; |
261 var message = l10n.widgetsFound.replace( '%d', this.searchMatchesCount ) ; |
253 |
262 |
254 if ( ! this.searchMatchesCount ) { |
263 if ( ! this.searchMatchesCount ) { |
255 message = l10n.noWidgetsFound; |
264 message = l10n.noWidgetsFound; |
256 } |
265 } |
257 |
266 |
258 wp.a11y.speak( message ); |
267 wp.a11y.speak( message ); |
259 }, 500 ), |
268 }, |
260 |
269 |
261 // Changes visibility of available widgets |
270 /** |
|
271 * Changes visibility of available widgets. |
|
272 */ |
262 updateList: function() { |
273 updateList: function() { |
263 this.collection.each( function( widget ) { |
274 this.collection.each( function( widget ) { |
264 var widgetTpl = $( '#widget-tpl-' + widget.id ); |
275 var widgetTpl = $( '#widget-tpl-' + widget.id ); |
265 widgetTpl.toggle( widget.get( 'search_matched' ) && ! widget.get( 'is_disabled' ) ); |
276 widgetTpl.toggle( widget.get( 'search_matched' ) && ! widget.get( 'is_disabled' ) ); |
266 if ( widget.get( 'is_disabled' ) && widgetTpl.is( this.selected ) ) { |
277 if ( widget.get( 'is_disabled' ) && widgetTpl.is( this.selected ) ) { |
267 this.selected = null; |
278 this.selected = null; |
268 } |
279 } |
269 } ); |
280 } ); |
270 }, |
281 }, |
271 |
282 |
272 // Highlights a widget |
283 /** |
|
284 * Highlights a widget. |
|
285 */ |
273 select: function( widgetTpl ) { |
286 select: function( widgetTpl ) { |
274 this.selected = $( widgetTpl ); |
287 this.selected = $( widgetTpl ); |
275 this.selected.siblings( '.widget-tpl' ).removeClass( 'selected' ); |
288 this.selected.siblings( '.widget-tpl' ).removeClass( 'selected' ); |
276 this.selected.addClass( 'selected' ); |
289 this.selected.addClass( 'selected' ); |
277 }, |
290 }, |
278 |
291 |
279 // Highlights a widget on focus |
292 /** |
|
293 * Highlights a widget on focus. |
|
294 */ |
280 focus: function( event ) { |
295 focus: function( event ) { |
281 this.select( $( event.currentTarget ) ); |
296 this.select( $( event.currentTarget ) ); |
282 }, |
297 }, |
283 |
298 |
284 // Submit handler for keypress and click on widget |
299 /** |
|
300 * Handles submit for keypress and click on widget. |
|
301 */ |
285 _submit: function( event ) { |
302 _submit: function( event ) { |
286 // Only proceed with keypress if it is Enter or Spacebar |
303 // Only proceed with keypress if it is Enter or Spacebar |
287 if ( event.type === 'keypress' && ( event.which !== 13 && event.which !== 32 ) ) { |
304 if ( event.type === 'keypress' && ( event.which !== 13 && event.which !== 32 ) ) { |
288 return; |
305 return; |
289 } |
306 } |
290 |
307 |
291 this.submit( $( event.currentTarget ) ); |
308 this.submit( $( event.currentTarget ) ); |
292 }, |
309 }, |
293 |
310 |
294 // Adds a selected widget to the sidebar |
311 /** |
|
312 * Adds a selected widget to the sidebar. |
|
313 */ |
295 submit: function( widgetTpl ) { |
314 submit: function( widgetTpl ) { |
296 var widgetId, widget, widgetFormControl; |
315 var widgetId, widget, widgetFormControl; |
297 |
316 |
298 if ( ! widgetTpl ) { |
317 if ( ! widgetTpl ) { |
299 widgetTpl = this.selected; |
318 widgetTpl = this.selected; |
360 $( 'body' ).removeClass( 'adding-widget' ); |
383 $( 'body' ).removeClass( 'adding-widget' ); |
361 |
384 |
362 this.$search.val( '' ); |
385 this.$search.val( '' ); |
363 }, |
386 }, |
364 |
387 |
365 // Add keyboard accessiblity to the panel |
388 /** |
|
389 * Adds keyboard accessiblity to the panel. |
|
390 */ |
366 keyboardAccessible: function( event ) { |
391 keyboardAccessible: function( event ) { |
367 var isEnter = ( event.which === 13 ), |
392 var isEnter = ( event.which === 13 ), |
368 isEsc = ( event.which === 27 ), |
393 isEsc = ( event.which === 27 ), |
369 isDown = ( event.which === 40 ), |
394 isDown = ( event.which === 40 ), |
370 isUp = ( event.which === 38 ), |
395 isUp = ( event.which === 38 ), |
444 widget.find( '.widget-content:first' ).prepend( newWidgetError ); |
471 widget.find( '.widget-content:first' ).prepend( newWidgetError ); |
445 } |
472 } |
446 } |
473 } |
447 }; |
474 }; |
448 |
475 |
449 /** |
476 api.Widgets.WidgetControl = api.Control.extend(/** @lends wp.customize.Widgets.WidgetControl.prototype */{ |
450 * wp.customize.Widgets.WidgetControl |
|
451 * |
|
452 * Customizer control for widgets. |
|
453 * Note that 'widget_form' must match the WP_Widget_Form_Customize_Control::$type |
|
454 * |
|
455 * @constructor |
|
456 * @augments wp.customize.Control |
|
457 */ |
|
458 api.Widgets.WidgetControl = api.Control.extend({ |
|
459 defaultExpandedArguments: { |
477 defaultExpandedArguments: { |
460 duration: 'fast', |
478 duration: 'fast', |
461 completeCallback: $.noop |
479 completeCallback: $.noop |
462 }, |
480 }, |
463 |
481 |
464 /** |
482 /** |
|
483 * wp.customize.Widgets.WidgetControl |
|
484 * |
|
485 * Customizer control for widgets. |
|
486 * Note that 'widget_form' must match the WP_Widget_Form_Customize_Control::$type |
|
487 * |
465 * @since 4.1.0 |
488 * @since 4.1.0 |
|
489 * |
|
490 * @constructs wp.customize.Widgets.WidgetControl |
|
491 * @augments wp.customize.Control |
466 */ |
492 */ |
467 initialize: function( id, options ) { |
493 initialize: function( id, options ) { |
468 var control = this; |
494 var control = this; |
469 |
495 |
470 control.widgetControlEmbedded = false; |
496 control.widgetControlEmbedded = false; |
941 * |
966 * |
942 * @since 4.1.0 |
967 * @since 4.1.0 |
943 * |
968 * |
944 * @param {Boolean} active |
969 * @param {Boolean} active |
945 * @param {Object} args |
970 * @param {Object} args |
946 * @param {Callback} args.completeCallback |
971 * @param {function} args.completeCallback |
947 */ |
972 */ |
948 onChangeActive: function ( active, args ) { |
973 onChangeActive: function ( active, args ) { |
949 // Note: there is a second 'args' parameter being passed, merged on top of this.defaultActiveArguments |
974 // Note: there is a second 'args' parameter being passed, merged on top of this.defaultActiveArguments |
950 this.container.toggleClass( 'widget-rendered', active ); |
975 this.container.toggleClass( 'widget-rendered', active ); |
951 if ( args.completeCallback ) { |
976 if ( args.completeCallback ) { |
959 _setupRemoveUI: function() { |
984 _setupRemoveUI: function() { |
960 var self = this, $removeBtn, replaceDeleteWithRemove; |
985 var self = this, $removeBtn, replaceDeleteWithRemove; |
961 |
986 |
962 // Configure remove button |
987 // Configure remove button |
963 $removeBtn = this.container.find( '.widget-control-remove' ); |
988 $removeBtn = this.container.find( '.widget-control-remove' ); |
964 $removeBtn.on( 'click', function( e ) { |
989 $removeBtn.on( 'click', function() { |
965 e.preventDefault(); |
|
966 |
|
967 // Find an adjacent element to add focus to when this widget goes away |
990 // Find an adjacent element to add focus to when this widget goes away |
968 var $adjacentFocusTarget; |
991 var $adjacentFocusTarget; |
969 if ( self.container.next().is( '.customize-control-widget_form' ) ) { |
992 if ( self.container.next().is( '.customize-control-widget_form' ) ) { |
970 $adjacentFocusTarget = self.container.next().find( '.widget-action:first' ); |
993 $adjacentFocusTarget = self.container.next().find( '.widget-action:first' ); |
971 } else if ( self.container.prev().is( '.customize-control-widget_form' ) ) { |
994 } else if ( self.container.prev().is( '.customize-control-widget_form' ) ) { |