| | 172 | * Trigger change if dirty. |
| | 173 | * |
| | 174 | * @returns {void} |
| | 175 | */ |
| | 176 | triggerChangeIfDirty = function() { |
| | 177 | var updateWidgetBuffer = 300; // See wp.customize.Widgets.WidgetControl._setupUpdateUI() which uses 250ms for updateWidgetDebounced. |
| | 178 | if ( control.editor.isDirty() ) { |
| | 179 | |
| | 180 | /* |
| | 181 | * Account for race condition in customizer where user clicks Save & Publish while |
| | 182 | * focus was just previously given to to the editor. Since updates to the editor |
| | 183 | * are debounced at 1 second and since widget input changes are only synced to |
| | 184 | * settings after 250ms, the customizer needs to be put into the processing |
| | 185 | * state during the time between the change event is triggered and updateWidget |
| | 186 | * logic starts. Note that the debounced update-widget request should be able |
| | 187 | * to be removed with the removal of the update-widget request entirely once |
| | 188 | * widgets are able to mutate their own instance props directly in JS without |
| | 189 | * having to make server round-trips to call the respective WP_Widget::update() |
| | 190 | * callbacks. See <https://core.trac.wordpress.org/ticket/33507>. |
| | 191 | */ |
| | 192 | if ( wp.customize && wp.customize.state ) { |
| | 193 | wp.customize.state( 'processing' ).set( wp.customize.state( 'processing' ).get() + 1 ); |
| | 194 | _.delay( function() { |
| | 195 | wp.customize.state( 'processing' ).set( wp.customize.state( 'processing' ).get() - 1 ); |
| | 196 | }, updateWidgetBuffer ); |
| | 197 | } |
| | 198 | |
| | 199 | if ( ! control.editor.isHidden() ) { |
| | 200 | control.editor.save(); |
| | 201 | } |
| | 202 | } |
| | 203 | |
| | 204 | // Trigger change on textarea when it is dirty for sake of widgets in the Customizer needing to sync form inputs to setting models. |
| | 205 | if ( needsTextareaChangeTrigger ) { |
| | 206 | textarea.trigger( 'change' ); |
| | 207 | needsTextareaChangeTrigger = false; |
| | 208 | } |
| | 209 | }; |
| | 210 | |
| | 211 | // Just-in-time force-update the hidden input fields. |
| | 212 | control.syncContainer.closest( '.widget' ).find( '[name=savewidget]:first' ).on( 'click', function onClickSaveButton() { |
| | 213 | triggerChangeIfDirty(); |
| | 214 | }); |
| | 215 | |
| | 216 | /** |
| 272 | | triggerChangeIfDirty = function() { |
| 273 | | var updateWidgetBuffer = 300; // See wp.customize.Widgets.WidgetControl._setupUpdateUI() which uses 250ms for updateWidgetDebounced. |
| 274 | | if ( editor.isDirty() ) { |
| 275 | | |
| 276 | | /* |
| 277 | | * Account for race condition in customizer where user clicks Save & Publish while |
| 278 | | * focus was just previously given to to the editor. Since updates to the editor |
| 279 | | * are debounced at 1 second and since widget input changes are only synced to |
| 280 | | * settings after 250ms, the customizer needs to be put into the processing |
| 281 | | * state during the time between the change event is triggered and updateWidget |
| 282 | | * logic starts. Note that the debounced update-widget request should be able |
| 283 | | * to be removed with the removal of the update-widget request entirely once |
| 284 | | * widgets are able to mutate their own instance props directly in JS without |
| 285 | | * having to make server round-trips to call the respective WP_Widget::update() |
| 286 | | * callbacks. See <https://core.trac.wordpress.org/ticket/33507>. |
| 287 | | */ |
| 288 | | if ( wp.customize && wp.customize.state ) { |
| 289 | | wp.customize.state( 'processing' ).set( wp.customize.state( 'processing' ).get() + 1 ); |
| 290 | | _.delay( function() { |
| 291 | | wp.customize.state( 'processing' ).set( wp.customize.state( 'processing' ).get() - 1 ); |
| 292 | | }, updateWidgetBuffer ); |
| 293 | | } |