| 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 | | } |