From cecef45157959323fd097d92f8037e0a0593166c Mon Sep 17 00:00:00 2001 From: "Dominik Schilling (ocean90)" Date: Fri, 14 Mar 2014 19:15:04 +0000 Subject: [PATCH] Customizer: Introduce a processing state. The processing state will prevent a save when it doesn't return 0. Widget Customizer will use the state to prevent a save while a widget is updating, which is an asynchronous process. props westonruter. fixes #27390. git-svn-id: https://develop.svn.wordpress.org/trunk@27540 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/js/customize-controls.js | 73 +++++++++++++++++---------- src/wp-admin/js/customize-widgets.js | 17 +++++-- 2 files changed, 59 insertions(+), 31 deletions(-) diff --git a/src/wp-admin/js/customize-controls.js b/src/wp-admin/js/customize-controls.js index 7a0f3e3d0f..64109a2b88 100644 --- a/src/wp-admin/js/customize-controls.js +++ b/src/wp-admin/js/customize-controls.js @@ -952,36 +952,55 @@ query = $.extend( this.query(), { action: 'customize_save', nonce: this.nonce.save - }), - request = $.post( api.settings.url.ajax, query ); + } ), + processing = api.state( 'processing' ), + submitWhenDoneProcessing, + submit; - api.trigger( 'save', request ); + body.addClass( 'saving' ); - body.addClass('saving'); + submit = function () { + var request = $.post( api.settings.url.ajax, query ); - request.always( function() { - body.removeClass('saving'); - }); + api.trigger( 'save', request ); - request.done( function( response ) { - // Check if the user is logged out. - if ( '0' === response ) { - self.preview.iframe.hide(); - self.login().done( function() { - self.save(); - self.preview.iframe.show(); - }); - return; - } + request.always( function () { + body.removeClass( 'saving' ); + } ); - // Check for cheaters. - if ( '-1' === response ) { - self.cheatin(); - return; - } + request.done( function( response ) { + // Check if the user is logged out. + if ( '0' === response ) { + self.preview.iframe.hide(); + self.login().done( function() { + self.save(); + self.preview.iframe.show(); + } ); + return; + } + + // Check for cheaters. + if ( '-1' === response ) { + self.cheatin(); + return; + } + + api.trigger( 'saved' ); + } ); + }; + + if ( 0 === processing() ) { + submit(); + } else { + submitWhenDoneProcessing = function () { + if ( 0 === processing() ) { + api.state.unbind( 'change', submitWhenDoneProcessing ); + submit(); + } + }; + api.state.bind( 'change', submitWhenDoneProcessing ); + } - api.trigger( 'saved' ); - }); } }); @@ -1016,8 +1035,9 @@ // Save and activated states (function() { var state = new api.Values(), - saved = state.create('saved'), - activated = state.create('activated'); + saved = state.create( 'saved' ), + activated = state.create( 'activated' ), + processing = state.create( 'processing' ); state.bind( 'change', function() { var save = $('#save'), @@ -1040,6 +1060,7 @@ // Set default states. saved( true ); activated( api.settings.theme.active ); + processing( 0 ); api.bind( 'change', function() { state('saved').set( false ); diff --git a/src/wp-admin/js/customize-widgets.js b/src/wp-admin/js/customize-widgets.js index cb0b3bef10..f0ca3476fb 100644 --- a/src/wp-admin/js/customize-widgets.js +++ b/src/wp-admin/js/customize-widgets.js @@ -914,7 +914,7 @@ var WidgetCustomizer = ( function ($) { var control = this, widget_content, save_btn, - trigger_save; + update_widget_debounced; widget_content = control.container.find( '.widget-content' ); @@ -928,7 +928,7 @@ var WidgetCustomizer = ( function ($) { control.updateWidget(); } ); - trigger_save = _.debounce( function () { + update_widget_debounced = _.debounce( function () { // @todo For compatibility with other plugins, should we trigger a click event? What about form submit event? control.updateWidget(); }, 250 ); @@ -943,8 +943,10 @@ var WidgetCustomizer = ( function ($) { // Handle widgets that support live previews widget_content.on( 'change input propertychange', ':input', function ( e ) { - if ( e.type === 'change' || ( this.checkValidity && this.checkValidity() ) ) { - trigger_save(); + if ( e.type === 'change' ) { + control.updateWidget(); + } else if ( this.checkValidity && this.checkValidity() ) { + update_widget_debounced(); } } ); @@ -1097,9 +1099,10 @@ var WidgetCustomizer = ( function ($) { element_id_to_refocus = null, active_input_selection_start = null, active_input_selection_end = null, - params = {}, + params, data, inputs, + processing, jqxhr; args = $.extend( { @@ -1129,6 +1132,8 @@ var WidgetCustomizer = ( function ($) { control.container.addClass( 'widget-form-loading' ); control.container.addClass( 'previewer-loading' ); + processing = wp.customize.state( 'processing' ); + processing( processing() + 1 ); params = {}; params.action = self.update_widget_ajax_action; @@ -1252,6 +1257,8 @@ var WidgetCustomizer = ( function ($) { inputs.each( function () { $( this ).removeData( 'state' + update_number ); } ); + + processing( processing() - 1 ); } ); },