WordPress.org

Make WordPress Core

Changeset 24611


Ignore:
Timestamp:
07/09/2013 09:57:58 AM (7 years ago)
Author:
koopersmith
Message:

Revisions: Debounce fetching Diffs when revisions are updated.

Fixes navigation and casting bugs.

See #24425.

Location:
trunk/wp-admin
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-admin/includes/revision.php

    r24605 r24611  
    102102        'nonce'            => wp_create_nonce( 'revisions-ajax-nonce' ),
    103103        'revisionData'     => array_values( $revisions ),
    104         'selectedRevision' => (int) $selected_revision_id,
     104        'selectedRevision' => $selected_revision_id,
    105105    );
    106106}
  • trunk/wp-admin/js/revisions.js

    r24609 r24611  
    88    // Link settings.
    99    revisions.settings = typeof _wpRevisionsSettings === 'undefined' ? {} : _wpRevisionsSettings;
     10
     11    // wp_localize_script transforms top-level numbers into strings. Undo that.
     12    if ( revisions.settings.selectedRevision )
     13        revisions.settings.selectedRevision = parseInt( revisions.settings.selectedRevision, 10 );
    1014
    1115
     
    3842        comparator: function( revision ) {
    3943            return revision.id;
     44        },
     45
     46        next: function( revision ) {
     47            var index = this.indexOf( revision );
     48
     49            if ( index !== -1 && index !== this.length - 1 )
     50                return this.at( index + 1 );
     51        },
     52
     53        prev: function( revision ) {
     54            var index = this.indexOf( revision );
     55
     56            if ( index !== -1 && index !== 0 )
     57                return this.at( index - 1 );
    4058        }
    4159    });
     
    199217    revisions.model.FrameState = Backbone.Model.extend({
    200218        initialize: function( attributes, options ) {
     219            var properties = {};
     220
     221            this._debouncedEnsureDiff = _.debounce( this._ensureDiff, 200 );
     222
    201223            this.revisions = options.revisions;
    202224            this.diffs = new revisions.model.Diffs( [], { revisions: this.revisions });
    203             this.listenTo( this, 'change:from', this.updateDiff );
    204             this.listenTo( this, 'change:to', this.updateDiff );
     225
     226            // Set the initial revision provided through the settings.
     227            properties.to = this.revisions.get( revisions.settings.selectedRevision );
     228            properties.from = this.revisions.prev( properties.to );
     229            this.set( properties );
     230
     231            // Start the router. This will trigger a navigate event and ensure that
     232            // the `from` and `to` revisions accurately reflect the hash.
    205233            this.router = new revisions.Router({ model: this });
     234            Backbone.history.start();
     235
     236            this.listenTo( this, 'change:from', this.changeRevisionHandler );
     237            this.listenTo( this, 'change:to', this.changeRevisionHandler );
     238            this.updateDiff({ immediate: true });
     239        },
     240
     241        // Fetch the currently loaded diff.
     242        diff: function() {
     243            return this.diffs.get( this._diffId );
    206244        },
    207245
     
    209247        // will only be updated once. This is because Backbone updates all of
    210248        // the changed attributes in `set`, and then fires the `change` events.
    211         updateDiff: function() {
    212             var from, to, diffId;
    213 
     249        updateDiff: function( options ) {
     250            var from, to, diffId, diff;
     251
     252            options = options || {};
    214253            from = this.get('from');
    215254            to = this.get('to');
     
    223262            this.trigger( 'update:revisions', from, to );
    224263
    225             this.diffs.ensure( diffId, this ).done( function( diff ) {
    226                 // Check if the current diff changed while the request was in flight.
    227                 if ( this._diffId !== diff.id )
    228                     return;
    229 
     264            // If we already have the diff, then immediately trigger the update.
     265            diff = this.diffs.get( diffId );
     266            if ( diff ) {
    230267                this.trigger( 'update:diff', diff );
     268
     269            // Otherwise, fetch the diff.
     270            } else {
     271                if ( options.immediate )
     272                    this._ensureDiff();
     273                else
     274                    this._debouncedEnsureDiff();
     275            }
     276        },
     277
     278        // A simple wrapper around `updateDiff` to prevent the change event's
     279        // parameters from being passed through.
     280        changeRevisionHandler: function( model, value, options ) {
     281            this.updateDiff();
     282        },
     283
     284        _ensureDiff: function() {
     285            this.diffs.ensure( this._diffId, this ).done( function( diff ) {
     286                // Make sure the current diff didn't change while the request was in flight.
     287                if ( this._diffId === diff.id )
     288                    this.trigger( 'update:diff', diff );
    231289            });
    232290        }
     
    246304
    247305        initialize: function() {
     306            // Generate the frame model.
    248307            this.model = new revisions.model.FrameState({}, {
    249308                revisions: this.collection
     
    257316            }) );
    258317
     318            // TODO: The rest of this method should be rewritten and moved into the FrameState.
    259319            if ( this.model.revisions.length ) {
    260                 var last = this.model.revisions.last(2);
    261                 var attributes = { to: last.pop() };
    262 
    263                 if ( last.length )
    264                     attributes.from = last.pop();
    265 
    266                 this.model.set( attributes );
    267 
    268320                // Load the rest: first 10, then the rest by 50
    269321                this.model.diffs.loadLastUnloaded( 10 ).always( _.bind( function() {
     
    271323                }, this ) );
    272324            }
    273             Backbone.history.start();
    274325        },
    275326
     
    808859
    809860            // Maintain state history when dragging
    810             this.listenTo( this.model, 'renderDiff', _.debounce( this.updateUrl, 250 ) );
     861            this.listenTo( this.model, 'update:diff', _.debounce( this.updateUrl, 250 ) );
    811862        },
    812863
Note: See TracChangeset for help on using the changeset viewer.