Opened 11 years ago
Closed 11 years ago
#31465 closed defect (bug) (fixed)
Fix JS for sidebar_widgets customizer control to not return undefined items in getWidgetFormControls method
| Reported by: |
|
Owned by: |
|
|---|---|---|---|
| Milestone: | 4.2 | Priority: | normal |
| Severity: | normal | Version: | 4.2 |
| Component: | Customize | Keywords: | has-patch |
| Focuses: | javascript | Cc: |
Description (last modified by )
Dynamically-created Customizer settings were introduced in #30936. Specifically for widgets in the Customizer, since the dynamic settings for widgets get set up before widgets_init so that any newly-created widget instances will get registered as widgets in $wp_registered_widgets, the WP_Customize_Widgets::sanitize_sidebar_widgets() method was changed in r31370 to remove the sanitizing check to ensure that all widget IDs in a given sidebar correspond to actually-registered widgets.
The side-effect to the sanitization change is that a sidebars_widgets[...] Customizer setting may end up containing widget IDs that do not have corresponding widget_{id_base}[{number}] settings. This, in turn, causes a problem for wp.customize.controlConstructor.sidebar_widgets.prototype.getWidgetFormControls() which is currently incorrectly assuming that every widget ID in a sidebar has a corresponding widget setting/control. If there is no corresponding control/setting for a widget ID, then an exception currently gets thrown when trying to open the Available Widgets Panel (in wp.customize.Widgets.AvailableWidgetsPanelView.prototype.open()) due to control being undefined:
// Wide widget controls appear over the preview, and so they need to be collapsed when the panel opens _( this.currentSidebarControl.getWidgetFormControls() ).each( function( control ) { if ( control.params.is_wide ) { // ERROR: control may be undefined control.collapseForm(); } } );
Current installs can be money patched to fix the problem via a plugin doing:
var oldMethod = wp.customize.controlConstructor.sidebar_widgets.prototype.getWidgetFormControls; wp.customize.controlConstructor.sidebar_widgets.prototype.getWidgetFormControls = function () { return _.filter( oldMethod.apply( this, arguments ), function ( control ) { return !! control; } ); };
The problem can be easily reproduced in JS by opening the console and entering:
wp.customize('sidebars_widgets[sidebar-1]')( wp.customize('sidebars_widgets[sidebar-1]')().concat( 'foo-123' ) )
And then attempt to add a widget by opening the available widgets panel.
https://github.com/xwp/wordpress-develop/pull/72