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
This commit is contained in:
Dominik Schilling (ocean90) 2014-03-14 19:15:04 +00:00
parent bfd0ac1099
commit cecef45157
2 changed files with 59 additions and 31 deletions

View File

@ -952,36 +952,55 @@
query = $.extend( this.query(), { query = $.extend( this.query(), {
action: 'customize_save', action: 'customize_save',
nonce: this.nonce.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() { api.trigger( 'save', request );
body.removeClass('saving');
});
request.done( function( response ) { request.always( function () {
// Check if the user is logged out. body.removeClass( 'saving' );
if ( '0' === response ) { } );
self.preview.iframe.hide();
self.login().done( function() {
self.save();
self.preview.iframe.show();
});
return;
}
// Check for cheaters. request.done( function( response ) {
if ( '-1' === response ) { // Check if the user is logged out.
self.cheatin(); if ( '0' === response ) {
return; 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 // Save and activated states
(function() { (function() {
var state = new api.Values(), var state = new api.Values(),
saved = state.create('saved'), saved = state.create( 'saved' ),
activated = state.create('activated'); activated = state.create( 'activated' ),
processing = state.create( 'processing' );
state.bind( 'change', function() { state.bind( 'change', function() {
var save = $('#save'), var save = $('#save'),
@ -1040,6 +1060,7 @@
// Set default states. // Set default states.
saved( true ); saved( true );
activated( api.settings.theme.active ); activated( api.settings.theme.active );
processing( 0 );
api.bind( 'change', function() { api.bind( 'change', function() {
state('saved').set( false ); state('saved').set( false );

View File

@ -914,7 +914,7 @@ var WidgetCustomizer = ( function ($) {
var control = this, var control = this,
widget_content, widget_content,
save_btn, save_btn,
trigger_save; update_widget_debounced;
widget_content = control.container.find( '.widget-content' ); widget_content = control.container.find( '.widget-content' );
@ -928,7 +928,7 @@ var WidgetCustomizer = ( function ($) {
control.updateWidget(); 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? // @todo For compatibility with other plugins, should we trigger a click event? What about form submit event?
control.updateWidget(); control.updateWidget();
}, 250 ); }, 250 );
@ -943,8 +943,10 @@ var WidgetCustomizer = ( function ($) {
// Handle widgets that support live previews // Handle widgets that support live previews
widget_content.on( 'change input propertychange', ':input', function ( e ) { widget_content.on( 'change input propertychange', ':input', function ( e ) {
if ( e.type === 'change' || ( this.checkValidity && this.checkValidity() ) ) { if ( e.type === 'change' ) {
trigger_save(); control.updateWidget();
} else if ( this.checkValidity && this.checkValidity() ) {
update_widget_debounced();
} }
} ); } );
@ -1097,9 +1099,10 @@ var WidgetCustomizer = ( function ($) {
element_id_to_refocus = null, element_id_to_refocus = null,
active_input_selection_start = null, active_input_selection_start = null,
active_input_selection_end = null, active_input_selection_end = null,
params = {}, params,
data, data,
inputs, inputs,
processing,
jqxhr; jqxhr;
args = $.extend( { args = $.extend( {
@ -1129,6 +1132,8 @@ var WidgetCustomizer = ( function ($) {
control.container.addClass( 'widget-form-loading' ); control.container.addClass( 'widget-form-loading' );
control.container.addClass( 'previewer-loading' ); control.container.addClass( 'previewer-loading' );
processing = wp.customize.state( 'processing' );
processing( processing() + 1 );
params = {}; params = {};
params.action = self.update_widget_ajax_action; params.action = self.update_widget_ajax_action;
@ -1252,6 +1257,8 @@ var WidgetCustomizer = ( function ($) {
inputs.each( function () { inputs.each( function () {
$( this ).removeData( 'state' + update_number ); $( this ).removeData( 'state' + update_number );
} ); } );
processing( processing() - 1 );
} ); } );
}, },