WordPress.org

Make WordPress Core

Ticket #27390: 27390.diff

File 27390.diff, 4.7 KB (added by westonruter, 7 years ago)

Introduce customizer 'processing' state. Prevent a race condition when saving settings which require server-side validation/processing to obtain the setting value to submit. Patch also pushed to GitHub: https://github.com/x-team/wordpress-develop/compare/trac-27390?w=1

  • src/wp-admin/js/customize-controls.js

    diff --git src/wp-admin/js/customize-controls.js src/wp-admin/js/customize-controls.js
    index 7a0f3e3..4a3d93a 100644
     
    952952                                        query = $.extend( this.query(), {
    953953                                                action: 'customize_save',
    954954                                                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                                                }
    961981
    962                                 request.always( function() {
    963                                         body.removeClass('saving');
    964                                 });
     982                                                // Check for cheaters.
     983                                                if ( '-1' === response ) {
     984                                                        self.cheatin();
     985                                                        return;
     986                                                }
    965987
    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                                };
    976991
    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                                }
    9821003
    983                                         api.trigger( 'saved' );
    984                                 });
    9851004                        }
    9861005                });
    9871006
     
    10161035                // Save and activated states
    10171036                (function() {
    10181037                        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' );
    10211041
    10221042                        state.bind( 'change', function() {
    10231043                                var save = $('#save'),
     
    10401060                        // Set default states.
    10411061                        saved( true );
    10421062                        activated( api.settings.theme.active );
     1063                        processing( 0 );
    10431064
    10441065                        api.bind( 'change', function() {
    10451066                                state('saved').set( false );
  • src/wp-admin/js/customize-widgets.js

    diff --git src/wp-admin/js/customize-widgets.js src/wp-admin/js/customize-widgets.js
    index fc6028b..9ea91b3 100644
    var WidgetCustomizer = ( function ($) { 
    914914                        var control = this,
    915915                                widget_content,
    916916                                save_btn,
    917                                 trigger_save;
     917                                update_widget_debounced;
    918918
    919919                        widget_content = control.container.find( '.widget-content' );
    920920
    var WidgetCustomizer = ( function ($) { 
    928928                                control.updateWidget();
    929929                        } );
    930930
    931                         trigger_save = _.debounce( function () {
     931                        update_widget_debounced = _.debounce( function () {
    932932                                // @todo For compatibility with other plugins, should we trigger a click event? What about form submit event?
    933933                                control.updateWidget();
    934934                        }, 250 );
    var WidgetCustomizer = ( function ($) { 
    943943
    944944                        // Handle widgets that support live previews
    945945                        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();
    948950                                }
    949951                        } );
    950952
    var WidgetCustomizer = ( function ($) { 
    10971099                                element_id_to_refocus = null,
    10981100                                active_input_selection_start = null,
    10991101                                active_input_selection_end = null,
    1100                                 params = {},
     1102                                params,
    11011103                                data,
    11021104                                inputs,
     1105                                processing,
    11031106                                jqxhr;
    11041107
    11051108                        args = $.extend( {
    var WidgetCustomizer = ( function ($) { 
    11291132
    11301133                        control.container.addClass( 'widget-form-loading' );
    11311134                        control.container.addClass( 'previewer-loading' );
     1135                        processing = wp.customize.state( 'processing' );
     1136                        processing( processing() + 1 );
    11321137
    11331138                        params = {};
    11341139                        params.action = self.update_widget_ajax_action;
    var WidgetCustomizer = ( function ($) { 
    12521257                                inputs.each( function () {
    12531258                                        $( this ).removeData( 'state' + update_number );
    12541259                                } );
     1260
     1261                                processing( processing() - 1 );
    12551262                        } );
    12561263                },
    12571264