mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/RevisionSlider
synced 2024-11-15 03:33:45 +00:00
Abort pending requests
Ensure all requests are abortable promises, and abort if a new, conflicting request is made. Change-Id: Ie05142f6da8cba6dde4f73c1b22960b726af4764
This commit is contained in:
parent
f6a44f43fe
commit
6997f135db
|
@ -14,19 +14,27 @@
|
|||
* Fetches a batch of revision data, including a gender setting for users who edited the revision
|
||||
*
|
||||
* @param {string} pageName
|
||||
* @param {Object} options - Options containing callbacks for `success` and `error` as well as
|
||||
* optional fields for: `dir (defaults to `older`), `limit` (defaults to 500), `startId`, `endId`,
|
||||
* `knownUserGenders`
|
||||
* @param {Object} options Options
|
||||
* @param {string} [options.dir='older'] Sort direction
|
||||
* @param {number} [options.limit=500] Result limit
|
||||
* @param {number} [options.startId] Start ID
|
||||
* @param {number} [options.endId] End ID
|
||||
* @param {Object} [options.knownUserGenders] Known user genders
|
||||
*/
|
||||
fetchRevisionData: function ( pageName, options ) {
|
||||
var self = this;
|
||||
this.fetchRevisions( pageName, options )
|
||||
var xhr, userXhr,
|
||||
deferred = $.Deferred(),
|
||||
self = this;
|
||||
|
||||
options = options || {};
|
||||
|
||||
xhr = this.fetchRevisions( pageName, options )
|
||||
.done( function ( data ) {
|
||||
var revs = data.query.pages[ 0 ].revisions,
|
||||
/*jshint -W024 */
|
||||
revContinue = data.continue,
|
||||
/*jshint +W024 */
|
||||
genderData = typeof options.knownUserGenders !== 'undefined' ? options.knownUserGenders : {},
|
||||
genderData = options.knownUserGenders || {},
|
||||
userNames;
|
||||
|
||||
if ( !revs ) {
|
||||
|
@ -35,7 +43,7 @@
|
|||
|
||||
userNames = self.getUserNames( revs, genderData );
|
||||
|
||||
self.fetchUserGenderData( userNames )
|
||||
userXhr = self.fetchUserGenderData( userNames )
|
||||
.done( function ( data ) {
|
||||
var users = typeof data !== 'undefined' ? data.query.users : [];
|
||||
|
||||
|
@ -49,34 +57,49 @@
|
|||
}
|
||||
} );
|
||||
|
||||
options.success( { revisions: revs, 'continue': revContinue } );
|
||||
deferred.resolve( { revisions: revs, 'continue': revContinue } );
|
||||
} )
|
||||
.fail( options.error );
|
||||
.fail( deferred.reject );
|
||||
} )
|
||||
.fail( options.error );
|
||||
.fail( deferred.reject );
|
||||
|
||||
return deferred.promise( {
|
||||
abort: function () {
|
||||
xhr.abort();
|
||||
if ( userXhr ) {
|
||||
userXhr.abort();
|
||||
}
|
||||
}
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetches up to 500 revisions at a time
|
||||
*
|
||||
* @param {string} pageName
|
||||
* @param {Object} options object containing optional options, fields: `dir` (defaults to `older`),
|
||||
* `limit` (defaults to 500), `startId`, `endId`
|
||||
* @return {jQuery}
|
||||
* @param {Object} [options] Options
|
||||
* @param {string} [options.dir='older'] Sort direction
|
||||
* @param {number} [options.limit=500] Result limit
|
||||
* @param {number} [options.startId] Start ID
|
||||
* @param {number} [options.endId] End ID
|
||||
* @return {jQuery.jqXHR}
|
||||
*/
|
||||
fetchRevisions: function ( pageName, options ) {
|
||||
var dir = options.dir !== undefined ? options.dir : 'older',
|
||||
data = {
|
||||
action: 'query',
|
||||
prop: 'revisions',
|
||||
format: 'json',
|
||||
rvprop: 'ids|timestamp|user|comment|parsedcomment|size|flags',
|
||||
titles: pageName,
|
||||
formatversion: 2,
|
||||
'continue': '',
|
||||
rvlimit: 500,
|
||||
rvdir: dir
|
||||
};
|
||||
var dir, data;
|
||||
|
||||
options = options || {};
|
||||
dir = options.dir !== undefined ? options.dir : 'older';
|
||||
data = {
|
||||
action: 'query',
|
||||
prop: 'revisions',
|
||||
format: 'json',
|
||||
rvprop: 'ids|timestamp|user|comment|parsedcomment|size|flags',
|
||||
titles: pageName,
|
||||
formatversion: 2,
|
||||
'continue': '',
|
||||
rvlimit: 500,
|
||||
rvdir: dir
|
||||
};
|
||||
|
||||
if ( options.startId !== undefined ) {
|
||||
data.rvstartid = options.startId;
|
||||
|
@ -98,7 +121,7 @@
|
|||
* Fetches gender data for up to 500 user names
|
||||
*
|
||||
* @param {string[]} users
|
||||
* @return {jQuery}
|
||||
* @return {jQuery.jqXHR}
|
||||
*/
|
||||
fetchUserGenderData: function ( users ) {
|
||||
if ( users.length === 0 ) {
|
||||
|
@ -118,7 +141,7 @@
|
|||
},
|
||||
|
||||
/**
|
||||
* @param {Array} revs
|
||||
* @param {Object[]} revs
|
||||
* @param {Object} knownUserGenders
|
||||
* @return {string[]}
|
||||
*/
|
||||
|
@ -132,7 +155,7 @@
|
|||
},
|
||||
|
||||
/**
|
||||
* @param {Array} data
|
||||
* @param {Object[]} data
|
||||
* @return {Object}
|
||||
*/
|
||||
getUserGenderData: function ( data ) {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* @constructor
|
||||
*/
|
||||
var DiffPage = function () {
|
||||
this.lastRequest = null;
|
||||
};
|
||||
|
||||
$.extend( DiffPage.prototype, {
|
||||
|
@ -13,45 +14,58 @@
|
|||
*
|
||||
* @param {number} revId1
|
||||
* @param {number} revId2
|
||||
* @param {number} [retryAttempt=0]
|
||||
*/
|
||||
refresh: function ( revId1, revId2 ) {
|
||||
var data = {
|
||||
diff: Math.max( revId1, revId2 ),
|
||||
oldid: Math.min( revId1, revId2 )
|
||||
},
|
||||
refresh: function ( revId1, revId2, retryAttempt ) {
|
||||
var self = this,
|
||||
retryLimit = 2,
|
||||
data = {
|
||||
diff: Math.max( revId1, revId2 ),
|
||||
oldid: Math.min( revId1, revId2 )
|
||||
},
|
||||
params = this.getExtraDiffPageParams();
|
||||
|
||||
retryAttempt = retryAttempt || 0;
|
||||
|
||||
if ( Object.keys( params ).length > 0 ) {
|
||||
$.extend( data, params );
|
||||
}
|
||||
|
||||
if ( this.lastRequest ) {
|
||||
this.lastRequest.abort();
|
||||
}
|
||||
|
||||
$( 'table.diff[data-mw="interface"]' )
|
||||
.append( $( '<tr>' ) )
|
||||
.append( $( '<td>' ) )
|
||||
.append( $( '<div>' ).addClass( 'mw-revslider-darkness' ) );
|
||||
$.ajax( {
|
||||
|
||||
this.lastRequest = $.ajax( {
|
||||
url: mw.util.wikiScript( 'index' ),
|
||||
data: data,
|
||||
tryCount: 0,
|
||||
retryLimit: 2,
|
||||
success: function ( data ) {
|
||||
var $container = $( '.mw-revslider-container' ),
|
||||
$contentText = $( '#mw-content-text' ),
|
||||
scrollLeft = $container.find( '.mw-revslider-revisions-container' ).scrollLeft();
|
||||
tryCount: 0
|
||||
} );
|
||||
// Don't chain, so lastRequest is a jQuery.jqXHR object
|
||||
this.lastRequest.then( function ( data ) {
|
||||
var $data,
|
||||
$container = $( '.mw-revslider-container' ),
|
||||
$contentText = $( '#mw-content-text' ),
|
||||
scrollLeft = $container.find( '.mw-revslider-revisions-container' ).scrollLeft();
|
||||
|
||||
data = $( data );
|
||||
data.find( '.mw-revslider-container' )
|
||||
.replaceWith( $container );
|
||||
$contentText.html( data.find( '#mw-content-text' ) )
|
||||
.find( '.mw-revslider-revisions-container' ).scrollLeft( scrollLeft );
|
||||
$data = $( data );
|
||||
$data.find( '.mw-revslider-container' ).replaceWith( $container );
|
||||
$contentText.html( $data.find( '#mw-content-text' ) )
|
||||
.find( '.mw-revslider-revisions-container' ).scrollLeft( scrollLeft );
|
||||
|
||||
mw.hook( 'wikipage.content' ).fire( $contentText );
|
||||
},
|
||||
error: function ( err ) {
|
||||
mw.hook( 'wikipage.content' ).fire( $contentText );
|
||||
}, function ( xhr ) {
|
||||
$( 'table.diff[data-mw="interface"] .mw-revslider-darkness' ).remove();
|
||||
if ( xhr.statusText !== 'abort' ) {
|
||||
this.tryCount++;
|
||||
console.log( err );
|
||||
mw.track( 'counter.MediaWiki.RevisionSlider.error.refresh' );
|
||||
if ( this.tryCount <= this.retryLimit ) {
|
||||
if ( retryAttempt <= retryLimit ) {
|
||||
console.log( 'Retrying request' );
|
||||
$.ajax( this );
|
||||
self.refresh( revId1, revId2, retryAttempt + 1 );
|
||||
}
|
||||
// TODO notify the user that we failed to update the diff?
|
||||
// This could also attempt to reload the page with the correct diff loaded without ajax?
|
||||
|
|
|
@ -586,22 +586,21 @@
|
|||
startId: revisions[ revisions.length - 1 ].getId(),
|
||||
dir: 'newer',
|
||||
limit: revisionCount + 1,
|
||||
knownUserGenders: this.slider.getRevisions().getUserGenders(),
|
||||
success: function ( data ) {
|
||||
revs = data.revisions.slice( 1 );
|
||||
if ( revs.length === 0 ) {
|
||||
self.noMoreNewerRevisions = true;
|
||||
return;
|
||||
}
|
||||
|
||||
self.addRevisionsAtEnd( $slider, revs );
|
||||
|
||||
/*jshint -W024 */
|
||||
if ( data.continue === undefined ) {
|
||||
self.noMoreNewerRevisions = true;
|
||||
}
|
||||
/*jshint +W024 */
|
||||
knownUserGenders: this.slider.getRevisions().getUserGenders()
|
||||
} ).then( function ( data ) {
|
||||
revs = data.revisions.slice( 1 );
|
||||
if ( revs.length === 0 ) {
|
||||
self.noMoreNewerRevisions = true;
|
||||
return;
|
||||
}
|
||||
|
||||
self.addRevisionsAtEnd( $slider, revs );
|
||||
|
||||
/*jshint -W024 */
|
||||
if ( data.continue === undefined ) {
|
||||
self.noMoreNewerRevisions = true;
|
||||
}
|
||||
/*jshint +W024 */
|
||||
} );
|
||||
},
|
||||
|
||||
|
@ -624,26 +623,25 @@
|
|||
// fetch an extra revision if there are more older revision than the current "window",
|
||||
// this makes it possible to correctly set a size of the bar related to the oldest revision to add
|
||||
limit: revisionCount + 2,
|
||||
knownUserGenders: this.slider.getRevisions().getUserGenders(),
|
||||
success: function ( data ) {
|
||||
revs = data.revisions.slice( 1 ).reverse();
|
||||
if ( revs.length === 0 ) {
|
||||
self.noMoreOlderRevisions = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( revs.length === revisionCount + 1 ) {
|
||||
precedingRevisionSize = revs[ 0 ].size;
|
||||
revs = revs.slice( 1 );
|
||||
}
|
||||
self.addRevisionsAtStart( $slider, revs, precedingRevisionSize );
|
||||
|
||||
/*jshint -W024 */
|
||||
if ( data.continue === undefined ) {
|
||||
self.noMoreOlderRevisions = true;
|
||||
}
|
||||
/*jshint +W024 */
|
||||
knownUserGenders: this.slider.getRevisions().getUserGenders()
|
||||
} ).then( function ( data ) {
|
||||
revs = data.revisions.slice( 1 ).reverse();
|
||||
if ( revs.length === 0 ) {
|
||||
self.noMoreOlderRevisions = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( revs.length === revisionCount + 1 ) {
|
||||
precedingRevisionSize = revs[ 0 ].size;
|
||||
revs = revs.slice( 1 );
|
||||
}
|
||||
self.addRevisionsAtStart( $slider, revs, precedingRevisionSize );
|
||||
|
||||
/*jshint -W024 */
|
||||
if ( data.continue === undefined ) {
|
||||
self.noMoreOlderRevisions = true;
|
||||
}
|
||||
/*jshint +W024 */
|
||||
} );
|
||||
},
|
||||
|
||||
|
|
|
@ -13,48 +13,45 @@
|
|||
|
||||
api.fetchRevisionData( mw.config.get( 'wgPageName' ), {
|
||||
startId: mw.config.values.extRevisionSliderNewRev,
|
||||
limit: mw.libs.revisionSlider.calculateRevisionsPerWindow( 160, 16 ),
|
||||
limit: mw.libs.revisionSlider.calculateRevisionsPerWindow( 160, 16 )
|
||||
} ).then( function ( data ) {
|
||||
var revs,
|
||||
revisionList,
|
||||
$container,
|
||||
slider;
|
||||
|
||||
success: function ( data ) {
|
||||
var revs,
|
||||
revisionList,
|
||||
$container,
|
||||
slider;
|
||||
mw.track( 'timing.MediaWiki.RevisionSlider.timing.initFetchRevisionData', mw.now() - startTime );
|
||||
|
||||
mw.track( 'timing.MediaWiki.RevisionSlider.timing.initFetchRevisionData', mw.now() - startTime );
|
||||
try {
|
||||
revs = data.revisions;
|
||||
revs.reverse();
|
||||
|
||||
try {
|
||||
revs = data.revisions;
|
||||
revs.reverse();
|
||||
revisionList = new mw.libs.revisionSlider.RevisionList( mw.libs.revisionSlider.makeRevisions( revs ) );
|
||||
|
||||
revisionList = new mw.libs.revisionSlider.RevisionList( mw.libs.revisionSlider.makeRevisions( revs ) );
|
||||
$container = $( '.mw-revslider-slider-wrapper' );
|
||||
slider = new mw.libs.revisionSlider.Slider( revisionList );
|
||||
slider.getView().render( $container );
|
||||
|
||||
$container = $( '.mw-revslider-slider-wrapper' );
|
||||
slider = new mw.libs.revisionSlider.Slider( revisionList );
|
||||
slider.getView().render( $container );
|
||||
|
||||
if ( !mw.user.options.get( 'userjs-revslider-hidehelp' ) ) {
|
||||
mw.libs.revisionSlider.HelpDialog.show();
|
||||
( new mw.Api() ).saveOption( 'userjs-revslider-hidehelp', true );
|
||||
}
|
||||
|
||||
$( '.mw-revslider-placeholder' ).remove();
|
||||
mw.track( 'timing.MediaWiki.RevisionSlider.timing.init', mw.now() - startTime );
|
||||
} catch ( err ) {
|
||||
$( '.mw-revslider-placeholder' )
|
||||
.text( mw.message( 'revisionslider-loading-failed' ).text() );
|
||||
console.log( err );
|
||||
mw.track( 'counter.MediaWiki.RevisionSlider.error.init' );
|
||||
if ( !mw.user.options.get( 'userjs-revslider-hidehelp' ) ) {
|
||||
mw.libs.revisionSlider.HelpDialog.show();
|
||||
( new mw.Api() ).saveOption( 'userjs-revslider-hidehelp', true );
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
},
|
||||
error: function ( err ) {
|
||||
$( '.mw-revslider-placeholder' ).remove();
|
||||
mw.track( 'timing.MediaWiki.RevisionSlider.timing.init', mw.now() - startTime );
|
||||
} catch ( err ) {
|
||||
$( '.mw-revslider-placeholder' )
|
||||
.text( mw.message( 'revisionslider-loading-failed' ).text() );
|
||||
console.log( err );
|
||||
mw.track( 'counter.MediaWiki.RevisionSlider.error.init' );
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
}, function ( err ) {
|
||||
$( '.mw-revslider-placeholder' )
|
||||
.text( mw.message( 'revisionslider-loading-failed' ).text() );
|
||||
console.log( err );
|
||||
mw.track( 'counter.MediaWiki.RevisionSlider.error.init' );
|
||||
} );
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue