Changeset 27986
- Timestamp:
- 04/07/2014 02:09:53 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-admin/js/customize-widgets.js
r27985 r27986 16 16 17 17 /** 18 * Set up model 18 * wp.customize.Widgets.WidgetModel 19 * 20 * A single widget model. 21 * 22 * @constructor 23 * @augments Backbone.Model 19 24 */ 20 25 api.Widgets.WidgetModel = Backbone.Model.extend({ … … 35 40 }); 36 41 42 /** 43 * wp.customize.Widgets.WidgetCollection 44 * 45 * Collection for widget models. 46 * 47 * @constructor 48 * @augments Backbone.Model 49 */ 37 50 api.Widgets.WidgetCollection = Backbone.Collection.extend({ 38 51 model: api.Widgets.WidgetModel, … … 93 106 api.Widgets.availableWidgets = new api.Widgets.WidgetCollection( api.Widgets.data.availableWidgets ); 94 107 108 /** 109 * wp.customize.Widgets.SidebarModel 110 * 111 * A single sidebar model. 112 * 113 * @constructor 114 * @augments Backbone.Model 115 */ 95 116 api.Widgets.SidebarModel = Backbone.Model.extend({ 96 117 after_title: null, … … 105 126 }); 106 127 128 /** 129 * wp.customize.Widgets.SidebarCollection 130 * 131 * Collection for sidebar models. 132 * 133 * @constructor 134 * @augments Backbone.Collection 135 */ 107 136 api.Widgets.SidebarCollection = Backbone.Collection.extend({ 108 137 model: api.Widgets.SidebarModel 109 138 }); 110 139 api.Widgets.registeredSidebars = new api.Widgets.SidebarCollection( api.Widgets.data.registeredSidebars ); 140 141 /** 142 * wp.customize.Widgets.AvailableWidgetsPanelView 143 * 144 * View class for the available widgets panel. 145 * 146 * @constructor 147 * @augments wp.Backbone.View 148 * @augments Backbone.View 149 */ 150 api.Widgets.AvailableWidgetsPanelView = wp.Backbone.View.extend({ 151 152 el: '#available-widgets', 153 154 events: { 155 'input #widgets-search': 'search', 156 'keyup #widgets-search': 'search', 157 'change #widgets-search': 'search', 158 'search #widgets-search': 'search', 159 'focus .widget-tpl' : 'focus', 160 'click .widget-tpl' : '_submit', 161 'keypress .widget-tpl' : '_submit', 162 'keydown' : 'keyboardAccessible' 163 }, 164 165 // Cache current selected widget 166 selected: null, 167 168 // Cache sidebar control which has opened panel 169 currentSidebarControl: null, 170 $search: null, 171 172 initialize: function() { 173 var self = this; 174 175 this.$search = $( '#widgets-search' ); 176 177 _.bindAll( this, 'close' ); 178 179 this.listenTo( this.collection, 'update', this.updateList ); 180 181 this.updateList(); 182 183 // If the available widgets panel is open and the customize controls are 184 // interacted with (i.e. available widgets panel is blurred) then close the 185 // available widgets panel. 186 $( '#customize-controls' ).on( 'click keydown', function( e ) { 187 var isAddNewBtn = $( e.target ).is( '.add-new-widget, .add-new-widget *' ); 188 if ( $( 'body' ).hasClass( 'adding-widget' ) && ! isAddNewBtn ) { 189 self.close(); 190 } 191 } ); 192 193 // Close the panel if the URL in the preview changes 194 api.Widgets.Previewer.bind( 'url', this.close ); 195 }, 196 197 // Performs a search and handles selected widget 198 search: function( event ) { 199 var firstVisible; 200 201 this.collection.doSearch( event.target.value ); 202 203 // Remove a widget from being selected if it is no longer visible 204 if ( this.selected && ! this.selected.is( ':visible' ) ) { 205 this.selected.removeClass( 'selected' ); 206 this.selected = null; 207 } 208 209 // If a widget was selected but the filter value has been cleared out, clear selection 210 if ( this.selected && ! event.target.value ) { 211 this.selected.removeClass( 'selected' ); 212 this.selected = null; 213 } 214 215 // If a filter has been entered and a widget hasn't been selected, select the first one shown 216 if ( ! this.selected && event.target.value ) { 217 firstVisible = this.$el.find( '> .widget-tpl:visible:first' ); 218 if ( firstVisible.length ) { 219 this.select( firstVisible ); 220 } 221 } 222 }, 223 224 // Changes visibilty of available widgets 225 updateList: function() { 226 // First hide all widgets... 227 this.$el.find( '.widget-tpl' ).hide(); 228 229 // ..and then show only available widgets which could be filtered 230 this.collection.each( function( widget ) { 231 var widgetTpl = $( '#widget-tpl-' + widget.id ); 232 widgetTpl.toggle( ! widget.get( 'is_disabled' ) ); 233 if ( widget.get( 'is_disabled' ) && widgetTpl.is( this.selected ) ) { 234 this.selected = null; 235 } 236 } ); 237 }, 238 239 // Hightlights a widget 240 select: function( widgetTpl ) { 241 this.selected = $( widgetTpl ); 242 this.selected.siblings( '.widget-tpl' ).removeClass( 'selected' ); 243 this.selected.addClass( 'selected' ); 244 }, 245 246 // Hightlights a widget on focus 247 focus: function( event ) { 248 this.select( $( event.currentTarget ) ); 249 }, 250 251 // Submit handler for keypress and click on widget 252 _submit: function( event ) { 253 // Only proceed with keypress if it is Enter or Spacebar 254 if ( event.type === 'keypress' && ( event.which !== 13 && event.which !== 32 ) ) { 255 return; 256 } 257 258 this.submit( $( event.currentTarget ) ); 259 }, 260 261 // Adds a selected widget to the sidebar 262 submit: function( widgetTpl ) { 263 var widgetId, widget; 264 265 if ( ! widgetTpl ) { 266 widgetTpl = this.selected; 267 } 268 269 if ( ! widgetTpl || ! this.currentSidebarControl ) { 270 return; 271 } 272 273 this.select( widgetTpl ); 274 275 widgetId = $( this.selected ).data( 'widget-id' ); 276 widget = this.collection.findWhere( { id: widgetId } ); 277 if ( ! widget ) { 278 return; 279 } 280 281 this.currentSidebarControl.addWidget( widget.get( 'id_base' ) ); 282 283 this.close(); 284 }, 285 286 // Opens the panel 287 open: function( sidebarControl ) { 288 this.currentSidebarControl = sidebarControl; 289 290 // Wide widget controls appear over the preview, and so they need to be collapsed when the panel opens 291 _( this.currentSidebarControl.getWidgetFormControls() ).each( function( control ) { 292 if ( control.params.is_wide ) { 293 control.collapseForm(); 294 } 295 } ); 296 297 $( 'body' ).addClass( 'adding-widget' ); 298 299 this.$el.find( '.selected' ).removeClass( 'selected' ); 300 301 // Reset search 302 this.collection.doSearch( '' ); 303 304 this.$search.focus(); 305 }, 306 307 // Closes the panel 308 close: function( options ) { 309 options = options || {}; 310 311 if ( options.returnFocus && this.currentSidebarControl ) { 312 this.currentSidebarControl.container.find( '.add-new-widget' ).focus(); 313 } 314 315 this.currentSidebarControl = null; 316 this.selected = null; 317 318 $( 'body' ).removeClass( 'adding-widget' ); 319 320 this.$search.val( '' ); 321 }, 322 323 // Add keyboard accessiblity to the panel 324 keyboardAccessible: function( event ) { 325 var isEnter = ( event.which === 13 ), 326 isEsc = ( event.which === 27 ), 327 isDown = ( event.which === 40 ), 328 isUp = ( event.which === 38 ), 329 selected = null, 330 firstVisible = this.$el.find( '> .widget-tpl:visible:first' ), 331 lastVisible = this.$el.find( '> .widget-tpl:visible:last' ), 332 isSearchFocused = $( event.target ).is( this.$search ); 333 334 if ( isDown || isUp ) { 335 if ( isDown ) { 336 if ( isSearchFocused ) { 337 selected = firstVisible; 338 } else if ( this.selected && this.selected.nextAll( '.widget-tpl:visible' ).length !== 0 ) { 339 selected = this.selected.nextAll( '.widget-tpl:visible:first' ); 340 } 341 } else if ( isUp ) { 342 if ( isSearchFocused ) { 343 selected = lastVisible; 344 } else if ( this.selected && this.selected.prevAll( '.widget-tpl:visible' ).length !== 0 ) { 345 selected = this.selected.prevAll( '.widget-tpl:visible:first' ); 346 } 347 } 348 349 this.select( selected ); 350 351 if ( selected ) { 352 selected.focus(); 353 } else { 354 this.$search.focus(); 355 } 356 357 return; 358 } 359 360 // If enter pressed but nothing entered, don't do anything 361 if ( isEnter && ! this.$search.val() ) { 362 return; 363 } 364 365 if ( isEnter ) { 366 this.submit(); 367 } else if ( isEsc ) { 368 this.close( { returnFocus: true } ); 369 } 370 } 371 }); 111 372 112 373 /** … … 122 383 * @param {String} newForm 123 384 */ 124 rss: function 385 rss: function( e, widget, newForm ) { 125 386 var oldWidgetError = widget.find( '.widget-error:first' ), 126 387 newWidgetError = $( '<div>' + newForm + '</div>' ).find( '.widget-error:first' ); … … 137 398 138 399 /** 139 * Widget Form control 400 * wp.customize.Widgets.WidgetControl 401 * 402 * Customizer control for widgets. 140 403 * Note that 'widget_form' must match the WP_Widget_Form_Customize_Control::$type 404 * 405 * @constructor 406 * @augments wp.customize.Control 141 407 */ 142 408 api.Widgets.WidgetControl = api.Control.extend({ … … 247 513 248 514 // Reposition whenever a sidebar's widgets are changed 249 api.each( function 515 api.each( function( setting ) { 250 516 if ( 0 === setting.id.indexOf( 'sidebars_widgets[' ) ) { 251 517 setting.bind( function() { … … 265 531 var control = this, close_btn; 266 532 267 control.container.find( '.widget-top' ).on( 'click', function 533 control.container.find( '.widget-top' ).on( 'click', function( e ) { 268 534 e.preventDefault(); 269 535 var sidebar_widgets_control = control.getSidebarWidgetsControl(); … … 276 542 close_btn = control.container.find( '.widget-control-close' ); 277 543 // @todo Hitting Enter on this link does nothing; will be resolved in core with <http://core.trac.wordpress.org/ticket/26633> 278 close_btn.on( 'click', function 544 close_btn.on( 'click', function( e ) { 279 545 e.preventDefault(); 280 546 control.collapseForm(); … … 318 584 * @param {jQuery} li 319 585 */ 320 select_sidebar_item = function 586 select_sidebar_item = function( li ) { 321 587 li.siblings( '.selected' ).removeClass( 'selected' ); 322 588 li.addClass( 'selected' ); … … 364 630 */ 365 631 reorder_nav = control.container.find( '.widget-reorder-nav' ); 366 reorder_nav.find( '.move-widget, .move-widget-down, .move-widget-up' ).on( 'click keypress', function 632 reorder_nav.find( '.move-widget, .move-widget-down, .move-widget-up' ).on( 'click keypress', function( event ) { 367 633 if ( event.type === 'keypress' && ( event.which !== 13 && event.which !== 32 ) ) { 368 634 return; … … 394 660 * Handle selecting a sidebar to move to 395 661 */ 396 control.container.find( '.widget-area-select' ).on( 'click keypress', 'li', function 662 control.container.find( '.widget-area-select' ).on( 'click keypress', 'li', function( e ) { 397 663 if ( event.type === 'keypress' && ( event.which !== 13 && event.which !== 32 ) ) { 398 664 return; … … 473 739 save_btn.attr( 'title', l10n.saveBtnTooltip ); 474 740 save_btn.removeClass( 'button-primary' ).addClass( 'button-secondary' ); 475 save_btn.on( 'click', function 741 save_btn.on( 'click', function( e ) { 476 742 e.preventDefault(); 477 743 control.updateWidget( { disable_form: true } ); … … 492 758 493 759 // Handle widgets that support live previews 494 widget_content.on( 'change input propertychange', ':input', function 760 widget_content.on( 'change input propertychange', ':input', function( e ) { 495 761 if ( control.live_update_mode ) { 496 762 if ( e.type === 'change' ) { … … 506 772 control.container.removeClass( 'previewer-loading' ); 507 773 } ); 508 api.Widgets.Previewer.bind( 'widget-updated', function 774 api.Widgets.Previewer.bind( 'widget-updated', function( updated_widget_id ) { 509 775 if ( updated_widget_id === control.params.widget_id ) { 510 776 control.container.removeClass( 'previewer-loading' ); … … 513 779 514 780 // Update widget control to indicate whether it is currently rendered (cf. Widget Visibility) 515 api.Widgets.Previewer.bind( 'rendered-widgets', function 781 api.Widgets.Previewer.bind( 'rendered-widgets', function( rendered_widgets ) { 516 782 var is_rendered = !! rendered_widgets[control.params.widget_id]; 517 783 control.container.toggleClass( 'widget-rendered', is_rendered ); … … 520 786 form_update_event_handler = api.Widgets.formSyncHandlers[ control.params.widget_id_base ]; 521 787 if ( form_update_event_handler ) { 522 $( document ).on( 'widget-synced', function 788 $( document ).on( 'widget-synced', function( e, widget_el ) { 523 789 if ( widget_root.is( widget_el ) ) { 524 790 form_update_event_handler.apply( document, arguments ); … … 539 805 remove_btn = control.container.find( 'a.widget-control-remove' ); 540 806 // @todo Hitting Enter on this link does nothing; will be resolved in core with <http://core.trac.wordpress.org/ticket/26633> 541 remove_btn.on( 'click', function 807 remove_btn.on( 'click', function( e ) { 542 808 e.preventDefault(); 543 809 … … 593 859 * @private 594 860 */ 595 _getInputs: function 861 _getInputs: function( container ) { 596 862 return $( container ).find( ':input[name]' ); 597 863 }, … … 605 871 * @private 606 872 */ 607 _getInputsSignature: function 608 var inputs_signatures = _( inputs ).map( function 873 _getInputsSignature: function( inputs ) { 874 var inputs_signatures = _( inputs ).map( function( input ) { 609 875 input = $( input ); 610 876 var signature_parts; … … 626 892 * @private 627 893 */ 628 _getInputStatePropertyName: function 894 _getInputStatePropertyName: function( input ) { 629 895 input = $( input ); 630 896 if ( input.is( ':radio, :checkbox' ) ) { … … 662 928 * @param {Boolean} [args.ignore_active_element=false] Whether or not updating a field will be deferred if focus is still on the element. 663 929 */ 664 updateWidget: function 930 updateWidget: function( args ) { 665 931 var control = this, 666 932 instance_override, … … 727 993 data += '&' + widget_content.find( '~ :input' ).serialize(); 728 994 729 jqxhr = $.post( wp.ajax.settings.url, data, function 995 jqxhr = $.post( wp.ajax.settings.url, data, function( r ) { 730 996 var message, 731 997 sanitized_form, … … 764 1030 // Sync sanitized field states to existing fields if they are aligned 765 1031 if ( has_same_inputs_in_response && control.live_update_mode ) { 766 inputs.each( function 1032 inputs.each( function( i ) { 767 1033 var input = $( this ), 768 1034 sanitized_input = $( sanitized_inputs[i] ), … … 828 1094 } 829 1095 } ); 830 jqxhr.fail( function 1096 jqxhr.fail( function( jqXHR, textStatus ) { 831 1097 if ( complete_callback ) { 832 1098 complete_callback.call( control, textStatus ); … … 873 1139 * @param {boolean|undefined} [do_expand] If not supplied, will be inverse of current visibility 874 1140 */ 875 toggleForm: function 1141 toggleForm: function( do_expand ) { 876 1142 var control = this, widget, inside, complete; 877 1143 … … 889 1155 if ( do_expand ) { 890 1156 // Close all other widget controls before expanding this one 891 api.control.each( function 1157 api.control.each( function( other_control ) { 892 1158 if ( control.params.type === other_control.params.type && control !== other_control ) { 893 1159 other_control.collapseForm(); … … 975 1241 * @param {Number} offset 1|-1 976 1242 */ 977 _moveWidgetByOne: function 1243 _moveWidgetByOne: function( offset ) { 978 1244 var control = this, 979 1245 i, … … 998 1264 * @param {Boolean} [toggle] 999 1265 */ 1000 toggleWidgetMoveArea: function 1266 toggleWidgetMoveArea: function( toggle ) { 1001 1267 var control = this, move_widget_area; 1002 1268 move_widget_area = control.container.find( '.move-widget-area' ); … … 1044 1310 1045 1311 /** 1046 * Sidebar Widgets control 1312 * wp.customize.Widgets.SidebarControl 1313 * 1314 * Customizer control for widgets. 1047 1315 * Note that 'sidebar_widgets' must match the WP_Widget_Area_Customize_Control::$type 1316 * 1317 * @constructor 1318 * @augments wp.customize.Control 1048 1319 */ 1049 1320 api.Widgets.SidebarControl = api.Control.extend({ … … 1075 1346 1076 1347 // Filter out any persistent widget_ids for widgets which have been deactivated 1077 new_widget_ids = _( new_widget_ids ).filter( function 1348 new_widget_ids = _( new_widget_ids ).filter( function( new_widget_id ) { 1078 1349 var parsed_widget_id = parse_widget_id( new_widget_id ); 1079 1350 return !! api.Widgets.availableWidgets.findWhere( { id_base: parsed_widget_id.id_base } ); 1080 1351 } ); 1081 1352 1082 widget_form_controls = _( new_widget_ids ).map( function 1353 widget_form_controls = _( new_widget_ids ).map( function( widget_id ) { 1083 1354 var widget_form_control = api.Widgets.getWidgetFormControlForWidget( widget_id ); 1084 1355 if ( ! widget_form_control ) { … … 1089 1360 1090 1361 // Sort widget controls to their new positions 1091 widget_form_controls.sort( function 1362 widget_form_controls.sort( function( a, b ) { 1092 1363 var a_index = _.indexOf( new_widget_ids, a.params.widget_id ), 1093 1364 b_index = _.indexOf( new_widget_ids, b.params.widget_id ); … … 1110 1381 1111 1382 // If the widget was dragged into the sidebar, make sure the sidebar_id param is updated 1112 _( widget_form_controls ).each( function 1383 _( widget_form_controls ).each( function( widget_form_control ) { 1113 1384 widget_form_control.params.sidebar_id = control.params.sidebar_id; 1114 1385 } ); 1115 1386 1116 1387 // Cleanup after widget removal 1117 _( removed_widget_ids ).each( function 1388 _( removed_widget_ids ).each( function( removed_widget_id ) { 1118 1389 1119 1390 // Using setTimeout so that when moving a widget to another sidebar, the other sidebars_widgets settings get a chance to update … … 1127 1398 1128 1399 // Check if the widget is in another sidebar 1129 api.each( function 1400 api.each( function( other_setting ) { 1130 1401 if ( other_setting.id === control.setting.id || 0 !== other_setting.id.indexOf( 'sidebars_widgets[' ) || other_setting.id === 'sidebars_widgets[wp_inactive_widgets]' ) { 1131 1402 return; … … 1179 1450 1180 1451 // Update the model with whether or not the sidebar is rendered 1181 api.Widgets.Previewer.bind( 'rendered-sidebars', function 1452 api.Widgets.Previewer.bind( 'rendered-sidebars', function( rendered_sidebars ) { 1182 1453 var is_rendered = !! rendered_sidebars[control.params.sidebar_id]; 1183 1454 registered_sidebar.set( 'is_rendered', is_rendered ); … … 1185 1456 1186 1457 // Show the sidebar section when it becomes visible 1187 registered_sidebar.on( 'change:is_rendered', function 1458 registered_sidebar.on( 'change:is_rendered', function( ) { 1188 1459 var section_selector = '#accordion-section-sidebar-widgets-' + this.get( 'id' ), section; 1189 1460 section = $( section_selector ); … … 1220 1491 update: function() { 1221 1492 var widget_container_ids = control.section_content.sortable( 'toArray' ), widget_ids; 1222 widget_ids = $.map( widget_container_ids, function 1493 widget_ids = $.map( widget_container_ids, function( widget_container_id ) { 1223 1494 return $( '#' + widget_container_id ).find( ':input[name=widget-id]' ).val(); 1224 1495 } ); … … 1307 1578 * @param {Boolean} toggle to enable/disable reordering 1308 1579 */ 1309 toggleReordering: function 1580 toggleReordering: function( toggle ) { 1310 1581 var control = this; 1311 1582 toggle = Boolean( toggle ); … … 1318 1589 1319 1590 if ( toggle ) { 1320 _( control.getWidgetFormControls() ).each( function 1591 _( control.getWidgetFormControls() ).each( function( form_control ) { 1321 1592 form_control.collapseForm(); 1322 1593 } ); … … 1330 1601 var control = this, form_controls; 1331 1602 1332 form_controls = _( control.setting() ).map( function 1603 form_controls = _( control.setting() ).map( function( widget_id ) { 1333 1604 var setting_id = widget_id_to_setting_id( widget_id ), 1334 1605 form_control = api.control( setting_id ); … … 1346 1617 * @returns {object} widget_form control instance 1347 1618 */ 1348 addWidget: function 1619 addWidget: function( widget_id ) { 1349 1620 var control = this, 1350 1621 control_html, … … 1378 1649 control_html = $( '#widget-tpl-' + widget.get( 'id' ) ).html(); 1379 1650 if ( widget.get( 'is_multi' ) ) { 1380 control_html = control_html.replace( /<[^<>]+>/g, function 1651 control_html = control_html.replace( /<[^<>]+>/g, function( m ) { 1381 1652 return m.replace( /__i__|%i%/g, widget_number ); 1382 1653 } ); … … 1436 1707 1437 1708 // Make sure widget is removed from the other sidebars 1438 api.each( function 1709 api.each( function( other_setting ) { 1439 1710 if ( other_setting.id === control.setting.id ) { 1440 1711 return; … … 1463 1734 widget_form_control.updateWidget( { 1464 1735 instance: widget_form_control.setting(), 1465 complete: function 1736 complete: function( error ) { 1466 1737 if ( error ) { 1467 1738 throw error; … … 1489 1760 api.bind( 'ready', function() { 1490 1761 // Set up the widgets panel 1491 api.Widgets.availableWidgetsPanel.setup(); 1762 api.Widgets.availableWidgetsPanel = new api.Widgets.AvailableWidgetsPanelView({ 1763 collection: api.Widgets.availableWidgets 1764 }); 1492 1765 1493 1766 // Highlight widget control … … 1541 1814 * @return {object|null} 1542 1815 */ 1543 api.Widgets.getSidebarWidgetControlContainingWidget = function 1816 api.Widgets.getSidebarWidgetControlContainingWidget = function( widget_id ) { 1544 1817 var found_control = null; 1545 1818 // @todo this can use widget_id_to_setting_id(), then pass into wp.customize.control( x ).getSidebarWidgetsControl() 1546 api.control.each( function 1819 api.control.each( function( control ) { 1547 1820 if ( control.params.type === 'sidebar_widgets' && -1 !== _.indexOf( control.setting(), widget_id ) ) { 1548 1821 found_control = control; … … 1558 1831 * @return {object|null} 1559 1832 */ 1560 api.Widgets.getWidgetFormControlForWidget = function 1833 api.Widgets.getWidgetFormControlForWidget = function( widget_id ) { 1561 1834 var found_control = null; 1562 1835 // @todo We can just use widget_id_to_setting_id() here 1563 api.control.each( function 1836 api.control.each( function( control ) { 1564 1837 if ( control.params.type === 'widget_form' && control.params.widget_id === widget_id ) { 1565 1838 found_control = control; … … 1568 1841 1569 1842 return found_control; 1570 };1571 1572 /**1573 * Available Widgets Panel1574 */1575 api.Widgets.availableWidgetsPanel = {1576 active_sidebar_widgets_control: null,1577 selected_widget_tpl: null,1578 container: null,1579 filter_input: null,1580 1581 /**1582 * Set up event listeners1583 */1584 setup: function() {1585 var panel = this;1586 1587 panel.container = $( '#available-widgets' );1588 panel.filter_input = $( '#available-widgets-filter' ).find( 'input' );1589 1590 api.Widgets.availableWidgets.on( 'change update', panel.update_available_widgets_list );1591 panel.update_available_widgets_list();1592 1593 // If the available widgets panel is open and the customize controls are1594 // interacted with (i.e. available widgets panel is blurred) then close the1595 // available widgets panel.1596 $( '#customize-controls' ).on( 'click keydown', function ( e ) {1597 var is_add_new_widget_btn = $( e.target ).is( '.add-new-widget, .add-new-widget *' );1598 if ( $( 'body' ).hasClass( 'adding-widget' ) && ! is_add_new_widget_btn ) {1599 panel.close();1600 }1601 } );1602 1603 // Close the panel if the URL in the preview changes1604 api.Widgets.Previewer.bind( 'url', function() {1605 panel.close();1606 } );1607 1608 // Submit a selection when clicked or keypressed1609 panel.container.find( '.widget-tpl' ).on( 'click keypress', function( event ) {1610 1611 // Only proceed with keypress if it is Enter or Spacebar1612 if ( event.type === 'keypress' && ( event.which !== 13 && event.which !== 32 ) ) {1613 return;1614 }1615 1616 panel.submit( this );1617 } );1618 1619 panel.filter_input.on( 'input keyup change', function( event ) {1620 var first_visible_widget;1621 1622 api.Widgets.availableWidgets.doSearch( event.target.value );1623 1624 // Remove a widget from being selected if it is no longer visible1625 if ( panel.selected_widget_tpl && ! panel.selected_widget_tpl.is( ':visible' ) ) {1626 panel.selected_widget_tpl.removeClass( 'selected' );1627 panel.selected_widget_tpl = null;1628 }1629 1630 // If a widget was selected but the filter value has been cleared out, clear selection1631 if ( panel.selected_widget_tpl && ! event.target.value ) {1632 panel.selected_widget_tpl.removeClass( 'selected' );1633 panel.selected_widget_tpl = null;1634 }1635 1636 // If a filter has been entered and a widget hasn't been selected, select the first one shown1637 if ( ! panel.selected_widget_tpl && event.target.value ) {1638 first_visible_widget = panel.container.find( '> .widget-tpl:visible:first' );1639 if ( first_visible_widget.length ) {1640 panel.select( first_visible_widget );1641 }1642 }1643 } );1644 1645 // Select a widget when it is focused on1646 panel.container.find( ' > .widget-tpl' ).on( 'focus', function() {1647 panel.select( this );1648 } );1649 1650 panel.container.on( 'keydown', function ( event ) {1651 var is_enter = ( event.which === 13 ),1652 is_esc = ( event.which === 27 ),1653 is_down = ( event.which === 40 ),1654 is_up = ( event.which === 38 ),1655 selected_widget_tpl = null,1656 first_visible_widget = panel.container.find( '> .widget-tpl:visible:first' ),1657 last_visible_widget = panel.container.find( '> .widget-tpl:visible:last' ),1658 is_input_focused = $( event.target ).is( panel.filter_input );1659 1660 if ( is_down || is_up ) {1661 if ( is_down ) {1662 if ( is_input_focused ) {1663 selected_widget_tpl = first_visible_widget;1664 } else if ( panel.selected_widget_tpl && panel.selected_widget_tpl.nextAll( '.widget-tpl:visible' ).length !== 0 ) {1665 selected_widget_tpl = panel.selected_widget_tpl.nextAll( '.widget-tpl:visible:first' );1666 }1667 } else if ( is_up ) {1668 if ( is_input_focused ) {1669 selected_widget_tpl = last_visible_widget;1670 } else if ( panel.selected_widget_tpl && panel.selected_widget_tpl.prevAll( '.widget-tpl:visible' ).length !== 0 ) {1671 selected_widget_tpl = panel.selected_widget_tpl.prevAll( '.widget-tpl:visible:first' );1672 }1673 }1674 panel.select( selected_widget_tpl );1675 if ( selected_widget_tpl ) {1676 selected_widget_tpl.focus();1677 } else {1678 panel.filter_input.focus();1679 }1680 return;1681 }1682 1683 // If enter pressed but nothing entered, don't do anything1684 if ( is_enter && ! panel.filter_input.val() ) {1685 return;1686 }1687 1688 if ( is_enter ) {1689 panel.submit();1690 } else if ( is_esc ) {1691 panel.close( { return_focus: true } );1692 }1693 } );1694 },1695 1696 /**1697 * Updates widgets list.1698 */1699 update_available_widgets_list: function() {1700 var panel = api.Widgets.availableWidgetsPanel;1701 1702 // First hide all widgets...1703 panel.container.find( '.widget-tpl' ).hide();1704 1705 // ..and then show only available widgets which could be filtered1706 api.Widgets.availableWidgets.each( function ( widget ) {1707 var widget_tpl = $( '#widget-tpl-' + widget.id );1708 widget_tpl.toggle( ! widget.get( 'is_disabled' ) );1709 if ( widget.get( 'is_disabled' ) && widget_tpl.is( panel.selected_widget_tpl ) ) {1710 panel.selected_widget_tpl = null;1711 }1712 } );1713 },1714 1715 /**1716 * @param widget_tpl1717 */1718 select: function ( widget_tpl ) {1719 var panel = this;1720 panel.selected_widget_tpl = $( widget_tpl );1721 panel.selected_widget_tpl.siblings( '.widget-tpl' ).removeClass( 'selected' );1722 panel.selected_widget_tpl.addClass( 'selected' );1723 },1724 1725 submit: function ( widget_tpl ) {1726 var panel = this, widget_id, widget;1727 if ( ! widget_tpl ) {1728 widget_tpl = panel.selected_widget_tpl;1729 }1730 if ( ! widget_tpl || ! panel.active_sidebar_widgets_control ) {1731 return;1732 }1733 panel.select( widget_tpl );1734 1735 widget_id = $( panel.selected_widget_tpl ).data( 'widget-id' );1736 widget = api.Widgets.availableWidgets.findWhere( {id: widget_id} );1737 if ( ! widget ) {1738 throw new Error( 'Widget unexpectedly not found.' );1739 }1740 panel.active_sidebar_widgets_control.addWidget( widget.get( 'id_base' ) );1741 panel.close();1742 },1743 1744 /**1745 * @param sidebars_widgets_control1746 */1747 open: function ( sidebars_widgets_control ) {1748 var panel = this;1749 panel.active_sidebar_widgets_control = sidebars_widgets_control;1750 1751 // Wide widget controls appear over the preview, and so they need to be collapsed when the panel opens1752 _( sidebars_widgets_control.getWidgetFormControls() ).each( function ( control ) {1753 if ( control.params.is_wide ) {1754 control.collapseForm();1755 }1756 } );1757 1758 $( 'body' ).addClass( 'adding-widget' );1759 panel.container.find( '.widget-tpl' ).removeClass( 'selected' );1760 api.Widgets.availableWidgets.doSearch( '' );1761 panel.filter_input.focus();1762 },1763 1764 /**1765 * Hide the panel1766 */1767 close: function ( options ) {1768 var panel = this;1769 options = options || {};1770 if ( options.return_focus && panel.active_sidebar_widgets_control ) {1771 panel.active_sidebar_widgets_control.container.find( '.add-new-widget' ).focus();1772 }1773 panel.active_sidebar_widgets_control = null;1774 panel.selected_widget_tpl = null;1775 $( 'body' ).removeClass( 'adding-widget' );1776 panel.filter_input.val( '' );1777 }1778 1843 }; 1779 1844
Note: See TracChangeset
for help on using the changeset viewer.