diff --git src/wp-admin/js/customize-controls.js src/wp-admin/js/customize-controls.js
index 7a0f3e3..4a3d93a 100644
|
|
|
952 | 952 | query = $.extend( this.query(), { |
953 | 953 | action: 'customize_save', |
954 | 954 | nonce: this.nonce.save |
955 | | }), |
956 | | request = $.post( api.settings.url.ajax, query ); |
957 | | |
958 | | api.trigger( 'save', request ); |
959 | | |
960 | | body.addClass('saving'); |
| 955 | } ), |
| 956 | processing = api.state( 'processing' ), |
| 957 | submit_when_done_processing, |
| 958 | submit; |
| 959 | |
| 960 | body.addClass( 'saving' ); |
| 961 | |
| 962 | submit = function () { |
| 963 | var request = $.post( api.settings.url.ajax, query ); |
| 964 | |
| 965 | api.trigger( 'save', request ); |
| 966 | |
| 967 | request.always( function () { |
| 968 | body.removeClass( 'saving' ); |
| 969 | } ); |
| 970 | |
| 971 | request.done( function( response ) { |
| 972 | // Check if the user is logged out. |
| 973 | if ( '0' === response ) { |
| 974 | self.preview.iframe.hide(); |
| 975 | self.login().done( function() { |
| 976 | self.save(); |
| 977 | self.preview.iframe.show(); |
| 978 | } ); |
| 979 | return; |
| 980 | } |
961 | 981 | |
962 | | request.always( function() { |
963 | | body.removeClass('saving'); |
964 | | }); |
| 982 | // Check for cheaters. |
| 983 | if ( '-1' === response ) { |
| 984 | self.cheatin(); |
| 985 | return; |
| 986 | } |
965 | 987 | |
966 | | request.done( function( response ) { |
967 | | // Check if the user is logged out. |
968 | | if ( '0' === response ) { |
969 | | self.preview.iframe.hide(); |
970 | | self.login().done( function() { |
971 | | self.save(); |
972 | | self.preview.iframe.show(); |
973 | | }); |
974 | | return; |
975 | | } |
| 988 | api.trigger( 'saved' ); |
| 989 | } ); |
| 990 | }; |
976 | 991 | |
977 | | // Check for cheaters. |
978 | | if ( '-1' === response ) { |
979 | | self.cheatin(); |
980 | | return; |
981 | | } |
| 992 | if ( 0 === processing() ) { |
| 993 | submit(); |
| 994 | } else { |
| 995 | submit_when_done_processing = function () { |
| 996 | if ( 0 === processing() ) { |
| 997 | api.state.unbind( 'change', submit_when_done_processing ); |
| 998 | submit(); |
| 999 | } |
| 1000 | }; |
| 1001 | api.state.bind( 'change', submit_when_done_processing ); |
| 1002 | } |
982 | 1003 | |
983 | | api.trigger( 'saved' ); |
984 | | }); |
985 | 1004 | } |
986 | 1005 | }); |
987 | 1006 | |
… |
… |
|
1016 | 1035 | // Save and activated states |
1017 | 1036 | (function() { |
1018 | 1037 | var state = new api.Values(), |
1019 | | saved = state.create('saved'), |
1020 | | activated = state.create('activated'); |
| 1038 | saved = state.create( 'saved' ), |
| 1039 | activated = state.create( 'activated' ), |
| 1040 | processing = state.create( 'processing' ); |
1021 | 1041 | |
1022 | 1042 | state.bind( 'change', function() { |
1023 | 1043 | var save = $('#save'), |
… |
… |
|
1040 | 1060 | // Set default states. |
1041 | 1061 | saved( true ); |
1042 | 1062 | activated( api.settings.theme.active ); |
| 1063 | processing( 0 ); |
1043 | 1064 | |
1044 | 1065 | api.bind( 'change', function() { |
1045 | 1066 | state('saved').set( false ); |
diff --git src/wp-admin/js/customize-widgets.js src/wp-admin/js/customize-widgets.js
index fc6028b..9ea91b3 100644
|
|
var WidgetCustomizer = ( function ($) { |
914 | 914 | var control = this, |
915 | 915 | widget_content, |
916 | 916 | save_btn, |
917 | | trigger_save; |
| 917 | update_widget_debounced; |
918 | 918 | |
919 | 919 | widget_content = control.container.find( '.widget-content' ); |
920 | 920 | |
… |
… |
var WidgetCustomizer = ( function ($) { |
928 | 928 | control.updateWidget(); |
929 | 929 | } ); |
930 | 930 | |
931 | | trigger_save = _.debounce( function () { |
| 931 | update_widget_debounced = _.debounce( function () { |
932 | 932 | // @todo For compatibility with other plugins, should we trigger a click event? What about form submit event? |
933 | 933 | control.updateWidget(); |
934 | 934 | }, 250 ); |
… |
… |
var WidgetCustomizer = ( function ($) { |
943 | 943 | |
944 | 944 | // Handle widgets that support live previews |
945 | 945 | widget_content.on( 'change input propertychange', ':input', function ( e ) { |
946 | | if ( e.type === 'change' || ( this.checkValidity && this.checkValidity() ) ) { |
947 | | trigger_save(); |
| 946 | if ( e.type === 'change' ) { |
| 947 | control.updateWidget(); |
| 948 | } else if ( this.checkValidity && this.checkValidity() ) { |
| 949 | update_widget_debounced(); |
948 | 950 | } |
949 | 951 | } ); |
950 | 952 | |
… |
… |
var WidgetCustomizer = ( function ($) { |
1097 | 1099 | element_id_to_refocus = null, |
1098 | 1100 | active_input_selection_start = null, |
1099 | 1101 | active_input_selection_end = null, |
1100 | | params = {}, |
| 1102 | params, |
1101 | 1103 | data, |
1102 | 1104 | inputs, |
| 1105 | processing, |
1103 | 1106 | jqxhr; |
1104 | 1107 | |
1105 | 1108 | args = $.extend( { |
… |
… |
var WidgetCustomizer = ( function ($) { |
1129 | 1132 | |
1130 | 1133 | control.container.addClass( 'widget-form-loading' ); |
1131 | 1134 | control.container.addClass( 'previewer-loading' ); |
| 1135 | processing = wp.customize.state( 'processing' ); |
| 1136 | processing( processing() + 1 ); |
1132 | 1137 | |
1133 | 1138 | params = {}; |
1134 | 1139 | params.action = self.update_widget_ajax_action; |
… |
… |
var WidgetCustomizer = ( function ($) { |
1252 | 1257 | inputs.each( function () { |
1253 | 1258 | $( this ).removeData( 'state' + update_number ); |
1254 | 1259 | } ); |
| 1260 | |
| 1261 | processing( processing() - 1 ); |
1255 | 1262 | } ); |
1256 | 1263 | }, |
1257 | 1264 | |