Revisions: Debounce fetching Diffs when revisions are updated.
Fixes navigation and casting bugs. See #24425. git-svn-id: http://core.svn.wordpress.org/trunk@24611 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
05e13a7645
commit
590bf668e9
|
@ -101,6 +101,6 @@ function wp_prepare_revisions_for_js( $post, $selected_revision_id ) {
|
||||||
'postId' => $post->ID,
|
'postId' => $post->ID,
|
||||||
'nonce' => wp_create_nonce( 'revisions-ajax-nonce' ),
|
'nonce' => wp_create_nonce( 'revisions-ajax-nonce' ),
|
||||||
'revisionData' => array_values( $revisions ),
|
'revisionData' => array_values( $revisions ),
|
||||||
'selectedRevision' => (int) $selected_revision_id,
|
'selectedRevision' => $selected_revision_id,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,10 @@ window.wp = window.wp || {};
|
||||||
// Link settings.
|
// Link settings.
|
||||||
revisions.settings = typeof _wpRevisionsSettings === 'undefined' ? {} : _wpRevisionsSettings;
|
revisions.settings = typeof _wpRevisionsSettings === 'undefined' ? {} : _wpRevisionsSettings;
|
||||||
|
|
||||||
|
// wp_localize_script transforms top-level numbers into strings. Undo that.
|
||||||
|
if ( revisions.settings.selectedRevision )
|
||||||
|
revisions.settings.selectedRevision = parseInt( revisions.settings.selectedRevision, 10 );
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ========================================================================
|
* ========================================================================
|
||||||
|
@ -37,6 +41,20 @@ window.wp = window.wp || {};
|
||||||
|
|
||||||
comparator: function( revision ) {
|
comparator: function( revision ) {
|
||||||
return revision.id;
|
return revision.id;
|
||||||
|
},
|
||||||
|
|
||||||
|
next: function( revision ) {
|
||||||
|
var index = this.indexOf( revision );
|
||||||
|
|
||||||
|
if ( index !== -1 && index !== this.length - 1 )
|
||||||
|
return this.at( index + 1 );
|
||||||
|
},
|
||||||
|
|
||||||
|
prev: function( revision ) {
|
||||||
|
var index = this.indexOf( revision );
|
||||||
|
|
||||||
|
if ( index !== -1 && index !== 0 )
|
||||||
|
return this.at( index - 1 );
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -198,19 +216,40 @@ window.wp = window.wp || {};
|
||||||
|
|
||||||
revisions.model.FrameState = Backbone.Model.extend({
|
revisions.model.FrameState = Backbone.Model.extend({
|
||||||
initialize: function( attributes, options ) {
|
initialize: function( attributes, options ) {
|
||||||
|
var properties = {};
|
||||||
|
|
||||||
|
this._debouncedEnsureDiff = _.debounce( this._ensureDiff, 200 );
|
||||||
|
|
||||||
this.revisions = options.revisions;
|
this.revisions = options.revisions;
|
||||||
this.diffs = new revisions.model.Diffs( [], { revisions: this.revisions });
|
this.diffs = new revisions.model.Diffs( [], { revisions: this.revisions });
|
||||||
this.listenTo( this, 'change:from', this.updateDiff );
|
|
||||||
this.listenTo( this, 'change:to', this.updateDiff );
|
// Set the initial revision provided through the settings.
|
||||||
|
properties.to = this.revisions.get( revisions.settings.selectedRevision );
|
||||||
|
properties.from = this.revisions.prev( properties.to );
|
||||||
|
this.set( properties );
|
||||||
|
|
||||||
|
// Start the router. This will trigger a navigate event and ensure that
|
||||||
|
// the `from` and `to` revisions accurately reflect the hash.
|
||||||
this.router = new revisions.Router({ model: this });
|
this.router = new revisions.Router({ model: this });
|
||||||
|
Backbone.history.start();
|
||||||
|
|
||||||
|
this.listenTo( this, 'change:from', this.changeRevisionHandler );
|
||||||
|
this.listenTo( this, 'change:to', this.changeRevisionHandler );
|
||||||
|
this.updateDiff({ immediate: true });
|
||||||
|
},
|
||||||
|
|
||||||
|
// Fetch the currently loaded diff.
|
||||||
|
diff: function() {
|
||||||
|
return this.diffs.get( this._diffId );
|
||||||
},
|
},
|
||||||
|
|
||||||
// So long as `from` and `to` are changed at the same time, the diff
|
// So long as `from` and `to` are changed at the same time, the diff
|
||||||
// will only be updated once. This is because Backbone updates all of
|
// will only be updated once. This is because Backbone updates all of
|
||||||
// the changed attributes in `set`, and then fires the `change` events.
|
// the changed attributes in `set`, and then fires the `change` events.
|
||||||
updateDiff: function() {
|
updateDiff: function( options ) {
|
||||||
var from, to, diffId;
|
var from, to, diffId, diff;
|
||||||
|
|
||||||
|
options = options || {};
|
||||||
from = this.get('from');
|
from = this.get('from');
|
||||||
to = this.get('to');
|
to = this.get('to');
|
||||||
diffId = ( from ? from.id : 0 ) + ':' + to.id;
|
diffId = ( from ? from.id : 0 ) + ':' + to.id;
|
||||||
|
@ -222,12 +261,31 @@ window.wp = window.wp || {};
|
||||||
this._diffId = diffId;
|
this._diffId = diffId;
|
||||||
this.trigger( 'update:revisions', from, to );
|
this.trigger( 'update:revisions', from, to );
|
||||||
|
|
||||||
this.diffs.ensure( diffId, this ).done( function( diff ) {
|
// If we already have the diff, then immediately trigger the update.
|
||||||
// Check if the current diff changed while the request was in flight.
|
diff = this.diffs.get( diffId );
|
||||||
if ( this._diffId !== diff.id )
|
if ( diff ) {
|
||||||
return;
|
|
||||||
|
|
||||||
this.trigger( 'update:diff', diff );
|
this.trigger( 'update:diff', diff );
|
||||||
|
|
||||||
|
// Otherwise, fetch the diff.
|
||||||
|
} else {
|
||||||
|
if ( options.immediate )
|
||||||
|
this._ensureDiff();
|
||||||
|
else
|
||||||
|
this._debouncedEnsureDiff();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// A simple wrapper around `updateDiff` to prevent the change event's
|
||||||
|
// parameters from being passed through.
|
||||||
|
changeRevisionHandler: function( model, value, options ) {
|
||||||
|
this.updateDiff();
|
||||||
|
},
|
||||||
|
|
||||||
|
_ensureDiff: function() {
|
||||||
|
this.diffs.ensure( this._diffId, this ).done( function( diff ) {
|
||||||
|
// Make sure the current diff didn't change while the request was in flight.
|
||||||
|
if ( this._diffId === diff.id )
|
||||||
|
this.trigger( 'update:diff', diff );
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -245,6 +303,7 @@ window.wp = window.wp || {};
|
||||||
template: wp.template('revisions-frame'),
|
template: wp.template('revisions-frame'),
|
||||||
|
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
|
// Generate the frame model.
|
||||||
this.model = new revisions.model.FrameState({}, {
|
this.model = new revisions.model.FrameState({}, {
|
||||||
revisions: this.collection
|
revisions: this.collection
|
||||||
});
|
});
|
||||||
|
@ -256,21 +315,13 @@ window.wp = window.wp || {};
|
||||||
model: this.model
|
model: this.model
|
||||||
}) );
|
}) );
|
||||||
|
|
||||||
|
// TODO: The rest of this method should be rewritten and moved into the FrameState.
|
||||||
if ( this.model.revisions.length ) {
|
if ( this.model.revisions.length ) {
|
||||||
var last = this.model.revisions.last(2);
|
|
||||||
var attributes = { to: last.pop() };
|
|
||||||
|
|
||||||
if ( last.length )
|
|
||||||
attributes.from = last.pop();
|
|
||||||
|
|
||||||
this.model.set( attributes );
|
|
||||||
|
|
||||||
// Load the rest: first 10, then the rest by 50
|
// Load the rest: first 10, then the rest by 50
|
||||||
this.model.diffs.loadLastUnloaded( 10 ).always( _.bind( function() {
|
this.model.diffs.loadLastUnloaded( 10 ).always( _.bind( function() {
|
||||||
this.model.diffs.loadAllBy( 50 );
|
this.model.diffs.loadAllBy( 50 );
|
||||||
}, this ) );
|
}, this ) );
|
||||||
}
|
}
|
||||||
Backbone.history.start();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
|
@ -807,7 +858,7 @@ window.wp = window.wp || {};
|
||||||
this.model = options.model;
|
this.model = options.model;
|
||||||
|
|
||||||
// Maintain state history when dragging
|
// Maintain state history when dragging
|
||||||
this.listenTo( this.model, 'renderDiff', _.debounce( this.updateUrl, 250 ) );
|
this.listenTo( this.model, 'update:diff', _.debounce( this.updateUrl, 250 ) );
|
||||||
},
|
},
|
||||||
|
|
||||||
routes: {
|
routes: {
|
||||||
|
|
Loading…
Reference in New Issue