mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/RevisionSlider
synced 2024-11-14 19:24:42 +00:00
Fetch more revisions as the user moves back and forward
This changes the previous behaviour of fetching always up to 500 most recent revisions. Now the extensions fetches N revisions including the newer revision selected to diff as the most recent revision. N is number of revisions that would fit in the current window when rendered as bars. When user is close to either "end" of the slider, extensions fetches another batch of up to N older or newer revisions, as long as user does not reach the oldest or the newest revision of the page. Among others, this removes the limitations of the previous approach: showing only 500 revisions, and failing to show anything when any of selected revisions was older than 500 recent revisions. This change also simplifies usage of Api class. Bug: T135005 Change-Id: Ib3f4a6ac57ff17008f9d8784c4716bd294443096
This commit is contained in:
parent
c7190cf97d
commit
dc838bc87d
|
@ -46,7 +46,6 @@
|
|||
"messages": [
|
||||
"revisionslider-show-help",
|
||||
"revisionslider-show-help-tooltip",
|
||||
"revisionslider-loading-out-of-range",
|
||||
"revisionslider-loading-failed"
|
||||
],
|
||||
"position": "top"
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
"revisionslider-minoredit": "This is a minor edit",
|
||||
"revisionslider-loading-placeholder": "The RevisionSlider is loading...",
|
||||
"revisionslider-loading-failed": "The RevisionSlider failed to load.",
|
||||
"revisionslider-loading-out-of-range": "The RevisionSlider failed to load as the requested revisions are not in the top 500 versions of the page.",
|
||||
"revisionslider-arrow-tooltip-newer": "See newer revisions",
|
||||
"revisionslider-arrow-tooltip-older": "See older revisions",
|
||||
"revisionslider-show-help": "?",
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
"revisionslider-minoredit": "Text labeling a minor edit.",
|
||||
"revisionslider-loading-placeholder": "Message shown while the RevisionSlider is still loading on a diff page. Once loaded the message is removed.",
|
||||
"revisionslider-loading-failed": "Message shown if the RevisionSlider fails to initially load.",
|
||||
"revisionslider-loading-out-of-range": "Message shown if the RevisionSlider fails to initially load due to revisions being requested that are not in the most recent 500 revisions.",
|
||||
"revisionslider-arrow-tooltip-newer": "Text shown after hovering the button scrolling to newer revisions.",
|
||||
"revisionslider-arrow-tooltip-older": "Text shown after hovering the button scrolling to older revisions.",
|
||||
"revisionslider-show-help": "A symbol shown in the \"Show help\" button.",
|
||||
|
|
|
@ -10,51 +10,140 @@
|
|||
$.extend( Api.prototype, {
|
||||
url: '',
|
||||
|
||||
/**
|
||||
* 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`
|
||||
*/
|
||||
fetchRevisionData: function ( pageName, options ) {
|
||||
var self = this;
|
||||
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 : {},
|
||||
userNames;
|
||||
|
||||
if ( !revs ) {
|
||||
return;
|
||||
}
|
||||
|
||||
userNames = self.getUserNames( revs, genderData );
|
||||
|
||||
self.fetchUserGenderData( userNames )
|
||||
.done( function ( data ) {
|
||||
var users = typeof data !== 'undefined' ? data.query.users : [];
|
||||
|
||||
if ( users.length > 0 ) {
|
||||
$.extend( genderData, self.getUserGenderData( users, genderData ) );
|
||||
}
|
||||
|
||||
revs.forEach( function ( rev ) {
|
||||
if ( typeof rev.user !== 'undefined' && typeof genderData[ rev.user ] !== 'undefined' ) {
|
||||
rev.userGender = genderData[ rev.user ];
|
||||
}
|
||||
} );
|
||||
|
||||
options.success( { revisions: revs, 'continue': revContinue } );
|
||||
} )
|
||||
.fail( options.error );
|
||||
} )
|
||||
.fail( options.error );
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetches up to 500 revisions at a time
|
||||
*
|
||||
* @param {Object} options - Options containing callbacks for `success` and `error` as well as fields for
|
||||
* `pageName` and `startId`
|
||||
* @param {string} pageName
|
||||
* @param {Object} options object containing optional options, fields: `dir` (defaults to `older`),
|
||||
* `limit` (defaults to 500), `startId`, `endId`
|
||||
* @return {jQuery}
|
||||
*/
|
||||
fetchRevisions: function ( options ) {
|
||||
$.ajax( {
|
||||
url: this.url,
|
||||
data: {
|
||||
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: options.pageName,
|
||||
titles: pageName,
|
||||
formatversion: 2,
|
||||
rvstartid: options.startId,
|
||||
'continue': '',
|
||||
rvlimit: 500
|
||||
},
|
||||
success: options.success,
|
||||
error: options.error
|
||||
rvlimit: 500,
|
||||
rvdir: dir
|
||||
};
|
||||
|
||||
if ( options.startId !== undefined ) {
|
||||
data.rvstartid = options.startId;
|
||||
}
|
||||
if ( options.endId !== undefined ) {
|
||||
data.rvendid = options.endId;
|
||||
}
|
||||
if ( options.limit !== undefined && options.limit <= 500 ) {
|
||||
data.rvlimit = options.limit;
|
||||
}
|
||||
|
||||
return $.ajax( {
|
||||
url: this.url,
|
||||
data: data
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetches gender data for up to 500 user names
|
||||
*
|
||||
* @param {Object} options - Options containing callbacks for `success` and `error` as well as list
|
||||
* of user names in `users`
|
||||
* @param {string[]} users
|
||||
* @return {jQuery}
|
||||
*/
|
||||
fetchUserGenderData: function ( options ) {
|
||||
$.ajax( {
|
||||
fetchUserGenderData: function ( users ) {
|
||||
if ( users.length === 0 ) {
|
||||
return $.Deferred().resolve();
|
||||
}
|
||||
return $.ajax( {
|
||||
url: this.url,
|
||||
data: {
|
||||
action: 'query',
|
||||
list: 'users',
|
||||
format: 'json',
|
||||
usprop: 'gender',
|
||||
ususers: options.users.join( '|' ),
|
||||
ususers: users.join( '|' ),
|
||||
uslimit: 500
|
||||
},
|
||||
success: options.success,
|
||||
error: options.error
|
||||
}
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Array} revs
|
||||
* @param {Object} knownUserGenders
|
||||
* @return {string[]}
|
||||
*/
|
||||
getUserNames: function ( revs, knownUserGenders ) {
|
||||
var allUsers = revs.map( function ( rev ) {
|
||||
return typeof rev.user !== 'undefined' ? rev.user : '';
|
||||
} );
|
||||
return allUsers.filter( function ( value, index, array ) {
|
||||
return value !== '' && typeof knownUserGenders[ value ] === 'undefined' && array.indexOf( value ) === index;
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Array} data
|
||||
* @return {Object}
|
||||
*/
|
||||
getUserGenderData: function ( data ) {
|
||||
var genderData = {},
|
||||
usersWithGender = data.filter( function ( item ) {
|
||||
return typeof item.gender !== 'undefined' && item.gender !== 'unknown';
|
||||
} );
|
||||
usersWithGender.forEach( function ( item ) {
|
||||
genderData[ item.name ] = item.gender;
|
||||
} );
|
||||
return genderData;
|
||||
}
|
||||
} );
|
||||
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
}
|
||||
if ( typeof data.user !== 'undefined' ) {
|
||||
this.user = data.user;
|
||||
if ( typeof data.userGender !== 'undefined' ) {
|
||||
this.userGender = data.userGender;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -137,13 +140,6 @@
|
|||
return this.user;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} gender
|
||||
*/
|
||||
setUserGender: function ( gender ) {
|
||||
this.userGender = gender;
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
|
|
|
@ -64,34 +64,74 @@
|
|||
return this.revisions.length;
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {string[]}
|
||||
*/
|
||||
getUserNames: function () {
|
||||
var allUsers = this.revisions.map( function ( revision ) {
|
||||
return revision.getUser();
|
||||
} );
|
||||
return allUsers.filter( function ( value, index, array ) {
|
||||
return value !== '' && array.indexOf( value ) === index;
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Object} userGenderData
|
||||
*/
|
||||
setUserGenders: function ( userGenderData ) {
|
||||
this.revisions.forEach( function ( revision ) {
|
||||
if ( revision.getUser() !== '' && typeof userGenderData[ revision.getUser() ] !== 'undefined' ) {
|
||||
revision.setUserGender( userGenderData[ revision.getUser() ] );
|
||||
}
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {RevisionListView}
|
||||
*/
|
||||
getView: function () {
|
||||
return this.view;
|
||||
},
|
||||
|
||||
getUserGenders: function () {
|
||||
var userGenders = {};
|
||||
this.revisions.forEach( function ( revision ) {
|
||||
if ( revision.getUser() ) {
|
||||
userGenders[ revision.getUser() ] = revision.getUserGender();
|
||||
}
|
||||
} );
|
||||
return userGenders;
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds revisions to the end of the list.
|
||||
*
|
||||
* @param {Revision[]} revs
|
||||
*/
|
||||
push: function ( revs ) {
|
||||
var i, rev;
|
||||
for ( i = 0; i < revs.length; i++ ) {
|
||||
rev = revs[ i ];
|
||||
rev.setRelativeSize(
|
||||
i > 0 ?
|
||||
rev.getSize() - revs[ i - 1 ].getSize() :
|
||||
rev.getSize() - this.revisions[ this.revisions.length - 1 ].getSize()
|
||||
);
|
||||
|
||||
this.revisions.push( rev );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds revisions to the beginning of the list.
|
||||
*
|
||||
* @param {Revision[]} revs
|
||||
* @param {number} sizeBefore optional size of the revision preceding the first of revs, defaults to 0
|
||||
*/
|
||||
unshift: function ( revs, sizeBefore ) {
|
||||
var originalFirstRev = this.revisions[ 0 ],
|
||||
i, rev;
|
||||
sizeBefore = sizeBefore || 0;
|
||||
|
||||
originalFirstRev.setRelativeSize( originalFirstRev.getSize() - revs[ revs.length - 1 ].getSize() );
|
||||
for ( i = revs.length - 1; i >= 0; i-- ) {
|
||||
rev = revs[ i ];
|
||||
rev.setRelativeSize( i > 0 ? rev.getSize() - revs[ i - 1 ].getSize() : rev.getSize() - sizeBefore );
|
||||
|
||||
this.revisions.unshift( rev );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a subset of the list.
|
||||
*
|
||||
* @param {number} begin
|
||||
* @param {number} end
|
||||
* @return {RevisionList}
|
||||
*/
|
||||
slice: function ( begin, end ) {
|
||||
var slicedList = new mw.libs.revisionSlider.RevisionList( [] );
|
||||
slicedList.view = new mw.libs.revisionSlider.RevisionListView( slicedList );
|
||||
slicedList.revisions = this.revisions.slice( begin, end );
|
||||
return slicedList;
|
||||
}
|
||||
} );
|
||||
|
||||
|
@ -99,7 +139,7 @@
|
|||
mw.libs.revisionSlider.RevisionList = RevisionList;
|
||||
|
||||
/**
|
||||
* Transforms an array of revision data returned by MediaWiki API into
|
||||
* Transforms an array of revision data returned by MediaWiki API (including user gender information) into
|
||||
* an array of Revision objects
|
||||
*
|
||||
* @param {Array} revs
|
||||
|
|
|
@ -25,9 +25,10 @@
|
|||
|
||||
/**
|
||||
* @param {number} revisionTickWidth
|
||||
* @param {number} positionOffset
|
||||
* @return {jQuery}
|
||||
*/
|
||||
render: function ( revisionTickWidth ) {
|
||||
render: function ( revisionTickWidth, positionOffset ) {
|
||||
var $html = $( '<div>' ).addClass( 'mw-revslider-revisions' ),
|
||||
revs = this.revisionList.getRevisions(),
|
||||
maxChangeSizeLogged = Math.log( this.revisionList.getBiggestChangeSize() ),
|
||||
|
@ -41,6 +42,8 @@
|
|||
self.hideTooltip( $( this ) );
|
||||
};
|
||||
|
||||
positionOffset = positionOffset || 0;
|
||||
|
||||
for ( i = 0; i < revs.length; i++ ) {
|
||||
diffSize = revs[ i ].getRelativeSize();
|
||||
relativeChangeSize = diffSize !== 0 ? Math.ceil( 65.0 * Math.log( Math.abs( diffSize ) ) / maxChangeSizeLogged ) + 5 : 0;
|
||||
|
@ -60,7 +63,7 @@
|
|||
.append( $( '<div>' )
|
||||
.addClass( 'mw-revslider-revision' )
|
||||
.attr( 'data-revid', revs[ i ].getId() )
|
||||
.attr( 'data-pos', i + 1 )
|
||||
.attr( 'data-pos', positionOffset + i + 1 )
|
||||
.css( {
|
||||
height: relativeChangeSize + 'px',
|
||||
width: revisionTickWidth + 'px',
|
||||
|
@ -79,6 +82,23 @@
|
|||
return $html;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {jQuery} $renderedList
|
||||
*/
|
||||
adjustRevisionSizes: function ( $renderedList ) {
|
||||
var revs = this.revisionList.getRevisions(),
|
||||
maxChangeSizeLogged = Math.log( this.revisionList.getBiggestChangeSize() ),
|
||||
i, diffSize, relativeChangeSize;
|
||||
for ( i = 0; i < revs.length; i++ ) {
|
||||
diffSize = revs[ i ].getRelativeSize();
|
||||
relativeChangeSize = diffSize !== 0 ? Math.ceil( 65.0 * Math.log( Math.abs( diffSize ) ) / maxChangeSizeLogged ) + 5 : 0;
|
||||
$renderedList.find( '.mw-revslider-revision[data-pos="' + ( i + 1 ) + '"]' ).css( {
|
||||
height: relativeChangeSize + 'px',
|
||||
top: diffSize > 0 ? '-' + relativeChangeSize + 'px' : 0
|
||||
} );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Hides the current tooltip immediately
|
||||
*/
|
||||
|
|
|
@ -51,6 +51,16 @@
|
|||
*/
|
||||
rtlScrollLeftType: 'default',
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
noMoreNewerRevisions: false,
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
noMoreOlderRevisions: false,
|
||||
|
||||
render: function ( $container ) {
|
||||
var containerWidth = this.calculateSliderContainerWidth(),
|
||||
pointerContainerPosition = 55,
|
||||
|
@ -197,7 +207,7 @@
|
|||
$( '.mw-revslider-revision-wrapper' ).removeClass( 'mw-revslider-pointer-cursor' );
|
||||
},
|
||||
drag: function ( event, ui ) {
|
||||
var newestVisibleRevisionLeftPos = containerWidth - self.revisionWidth;
|
||||
var newestVisibleRevisionLeftPos = $( '.mw-revslider-revisions-container' ).width() - self.revisionWidth;
|
||||
ui.position.left = Math.min( ui.position.left, newestVisibleRevisionLeftPos );
|
||||
if ( $( this ).css( 'direction' ) === 'ltr' ) {
|
||||
self.resetPointerColorsBasedOnValues(
|
||||
|
@ -213,31 +223,7 @@
|
|||
}
|
||||
} );
|
||||
|
||||
$slider.find( '.mw-revslider-revision-wrapper' ).click( function ( e ) {
|
||||
var $revWrap = $( this ),
|
||||
$clickedRev = $revWrap.find( '.mw-revslider-revision' ),
|
||||
hasClickedTop = e.pageY - $revWrap.offset().top < $revWrap.height() / 2,
|
||||
pOld = self.getOldRevPointer(),
|
||||
pNew = self.getNewRevPointer();
|
||||
|
||||
if ( hasClickedTop ) {
|
||||
self.refreshRevisions(
|
||||
self.getRevElementAtPosition( $revisions, pOld.getPosition() ).data( 'revid' ),
|
||||
$clickedRev.data( 'revid' )
|
||||
);
|
||||
pNew.setPosition( $clickedRev.data( 'pos' ) );
|
||||
} else {
|
||||
self.refreshRevisions(
|
||||
$clickedRev.data( 'revid' ),
|
||||
self.getRevElementAtPosition( $revisions, pNew.getPosition() ).data( 'revid' )
|
||||
);
|
||||
pOld.setPosition( $clickedRev.data( 'pos' ) );
|
||||
}
|
||||
|
||||
self.resetPointerColorsBasedOnValues( self.pointerOlder.getPosition(), self.pointerNewer.getPosition() );
|
||||
self.resetRevisionStylesBasedOnPointerPosition( $revisions );
|
||||
self.alignPointers();
|
||||
} );
|
||||
$slider.find( '.mw-revslider-revision-wrapper' ).on( 'click', null, { view: self, revisionsDom: $revisions }, this.revisionWrapperClickHandler );
|
||||
|
||||
this.slider.setRevisionsPerWindow( $slider.find( '.mw-revslider-revisions-container' ).width() / this.revisionWidth );
|
||||
|
||||
|
@ -252,6 +238,34 @@
|
|||
this.diffPage.initOnPopState( this );
|
||||
},
|
||||
|
||||
revisionWrapperClickHandler: function ( e ) {
|
||||
var $revWrap = $( this ),
|
||||
view = e.data.view,
|
||||
$revisions = e.data.revisionsDom,
|
||||
$clickedRev = $revWrap.find( '.mw-revslider-revision' ),
|
||||
hasClickedTop = e.pageY - $revWrap.offset().top < $revWrap.height() / 2,
|
||||
pOld = view.getOldRevPointer(),
|
||||
pNew = view.getNewRevPointer();
|
||||
|
||||
if ( hasClickedTop ) {
|
||||
view.refreshRevisions(
|
||||
view.getRevElementAtPosition( $revisions, pOld.getPosition() ).data( 'revid' ),
|
||||
$clickedRev.data( 'revid' )
|
||||
);
|
||||
pNew.setPosition( parseInt( $clickedRev.attr( 'data-pos' ), 10 ) );
|
||||
} else {
|
||||
view.refreshRevisions(
|
||||
$clickedRev.data( 'revid' ),
|
||||
view.getRevElementAtPosition( $revisions, pNew.getPosition() ).data( 'revid' )
|
||||
);
|
||||
pOld.setPosition( parseInt( $clickedRev.attr( 'data-pos' ), 10 ) ) ;
|
||||
}
|
||||
|
||||
view.resetPointerColorsBasedOnValues( view.pointerOlder.getPosition(), view.pointerNewer.getPosition() );
|
||||
view.resetRevisionStylesBasedOnPointerPosition( $revisions );
|
||||
view.alignPointers();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the pointer that points to the older revision
|
||||
*
|
||||
|
@ -319,11 +333,15 @@
|
|||
* @param {jQuery} $newRevElement
|
||||
*/
|
||||
initializePointers: function ( $oldRevElement, $newRevElement ) {
|
||||
if ( $oldRevElement.length === 0 || $newRevElement.length === 0 ) {
|
||||
if ( $oldRevElement.length === 0 && $newRevElement.length === 0 ) {
|
||||
// Note: this is currently caught in init.js
|
||||
throw 'RS-rev-out-of-range';
|
||||
throw 'RS-revs-not-specified';
|
||||
}
|
||||
if ( $oldRevElement.length !== 0 ) {
|
||||
this.pointerOlder.setPosition( $oldRevElement.data( 'pos' ) );
|
||||
} else {
|
||||
this.pointerOlder.setPosition( -1 );
|
||||
}
|
||||
this.pointerOlder.setPosition( $oldRevElement.data( 'pos' ) );
|
||||
this.pointerNewer.setPosition( $newRevElement.data( 'pos' ) );
|
||||
this.resetPointerStylesBasedOnPosition();
|
||||
},
|
||||
|
@ -376,20 +394,14 @@
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Determines how many revisions fit onto the screen at once depending on the browser window width
|
||||
*
|
||||
* @return {number}
|
||||
*/
|
||||
calculateRevisionsPerWindow: function () {
|
||||
return Math.floor( ( $( '#mw-content-text' ).width() - this.containerMargin ) / this.revisionWidth );
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
calculateSliderContainerWidth: function () {
|
||||
return Math.min( this.slider.getRevisions().getLength(), this.calculateRevisionsPerWindow() ) * this.revisionWidth;
|
||||
return Math.min(
|
||||
this.slider.getRevisions().getLength(),
|
||||
mw.libs.revisionSlider.calculateRevisionsPerWindow( this.containerMargin, this.revisionWidth )
|
||||
) * this.revisionWidth;
|
||||
},
|
||||
|
||||
slide: function ( direction, duration ) {
|
||||
|
@ -424,6 +436,13 @@
|
|||
function () {
|
||||
self.pointerOlder.getView().getElement().draggable( 'enable' );
|
||||
self.pointerNewer.getView().getElement().draggable( 'enable' );
|
||||
|
||||
if ( self.slider.isAtStart() && !self.noMoreOlderRevisions ) {
|
||||
self.addOlderRevisionsIfNeeded( $( '.mw-revslider-revision-slider' ) );
|
||||
}
|
||||
if ( self.slider.isAtEnd() && !self.noMoreNewerRevisions ) {
|
||||
self.addNewerRevisionsIfNeeded( $( '.mw-revslider-revision-slider' ) );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -496,9 +515,236 @@
|
|||
*/
|
||||
whichPointer: function ( $e ) {
|
||||
return $e.attr( 'id' ) === 'mw-revslider-pointer-older' ? this.pointerOlder : this.pointerNewer;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {jQuery} $slider
|
||||
*/
|
||||
addNewerRevisionsIfNeeded: function ( $slider ) {
|
||||
var api = new mw.libs.revisionSlider.Api( mw.util.wikiScript( 'api' ) ),
|
||||
self = this,
|
||||
revisions = this.slider.getRevisions().getRevisions(),
|
||||
revisionCount = mw.libs.revisionSlider.calculateRevisionsPerWindow( this.containerMargin, this.revisionWidth ),
|
||||
revs;
|
||||
if ( this.noMoreNewerRevisions || !this.slider.isAtEnd() ) {
|
||||
return;
|
||||
}
|
||||
api.fetchRevisionData( mw.config.get( 'wgPageName' ), {
|
||||
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 */
|
||||
}
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {jQuery} $slider
|
||||
*/
|
||||
addOlderRevisionsIfNeeded: function ( $slider ) {
|
||||
var api = new mw.libs.revisionSlider.Api( mw.util.wikiScript( 'api' ) ),
|
||||
self = this,
|
||||
revisions = this.slider.getRevisions().getRevisions(),
|
||||
revisionCount = mw.libs.revisionSlider.calculateRevisionsPerWindow( this.containerMargin, this.revisionWidth ),
|
||||
revs,
|
||||
precedingRevisionSize = 0;
|
||||
if ( this.noMoreOlderRevisions || !this.slider.isAtStart() ) {
|
||||
return;
|
||||
}
|
||||
api.fetchRevisionData( mw.config.get( 'wgPageName' ), {
|
||||
startId: revisions[ 0 ].getId(),
|
||||
dir: 'older',
|
||||
// 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 */
|
||||
}
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {jQuery} $slider
|
||||
* @param {Array} revs
|
||||
*/
|
||||
addRevisionsAtEnd: function ( $slider, revs ) {
|
||||
var revPositionOffset = this.slider.getRevisions().getLength(),
|
||||
$revisions = $slider.find( '.mw-revslider-revisions-container .mw-revslider-revisions' ),
|
||||
revisionsToRender,
|
||||
$addedRevisions;
|
||||
|
||||
this.slider.getRevisions().push( mw.libs.revisionSlider.makeRevisions( revs ) );
|
||||
|
||||
// Pushed revisions have their relative sizes set correctly with regard to the last previously
|
||||
// loaded revision. This should be taken into account when rendering newly loaded revisions (tooltip)
|
||||
revisionsToRender = this.slider.getRevisions().slice( revPositionOffset );
|
||||
|
||||
$addedRevisions = new mw.libs.revisionSlider.RevisionListView( revisionsToRender ).render( this.revisionWidth, revPositionOffset );
|
||||
|
||||
this.addClickHandlerToRevisions( $addedRevisions, $revisions, this.revisionWrapperClickHandler );
|
||||
|
||||
$addedRevisions.find( '.mw-revslider-revision-wrapper' ).each( function () {
|
||||
$revisions.append( $( this ) );
|
||||
} );
|
||||
|
||||
if ( this.shouldExpandSlider( $slider ) ) {
|
||||
this.expandSlider( $slider );
|
||||
}
|
||||
|
||||
this.slider.getRevisions().getView().adjustRevisionSizes( $slider );
|
||||
|
||||
if ( !this.slider.isAtEnd() ) {
|
||||
$slider.find( '.mw-revslider-arrow-forwards' ).removeClass( 'mw-revslider-arrow-disabled' ).addClass( 'mw-revslider-arrow-enabled' );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {jQuery} $slider
|
||||
* @param {Array} revs
|
||||
* @param {number} precedingRevisionSize optional size of the revision preceding the first of revs,
|
||||
* used to correctly determine first revision's relative size
|
||||
*/
|
||||
addRevisionsAtStart: function ( $slider, revs, precedingRevisionSize ) {
|
||||
var self = this,
|
||||
$revisions = $slider.find( '.mw-revslider-revisions-container .mw-revslider-revisions' ),
|
||||
$revisionContainer = $slider.find( '.mw-revslider-revisions-container' ),
|
||||
revisionsToRender,
|
||||
$addedRevisions,
|
||||
pOld, pNew,
|
||||
revisionStyleResetRequired = false,
|
||||
$oldRevElement,
|
||||
scrollLeft;
|
||||
|
||||
this.slider.getRevisions().unshift( mw.libs.revisionSlider.makeRevisions( revs ), precedingRevisionSize );
|
||||
|
||||
$slider.find( '.mw-revslider-revision' ).each( function () {
|
||||
$( this ).attr( 'data-pos', parseInt( $( this ).attr( 'data-pos' ), 10 ) + revs.length );
|
||||
} );
|
||||
|
||||
// Pushed (unshifted) revisions have their relative sizes set correctly with regard to the last previously
|
||||
// loaded revision. This should be taken into account when rendering newly loaded revisions (tooltip)
|
||||
revisionsToRender = this.slider.getRevisions().slice( 0, revs.length );
|
||||
|
||||
$addedRevisions = new mw.libs.revisionSlider.RevisionListView( revisionsToRender ).render( this.revisionWidth );
|
||||
|
||||
pOld = this.getOldRevPointer();
|
||||
pNew = this.getNewRevPointer();
|
||||
|
||||
if ( pOld.getPosition() !== -1 ) {
|
||||
pOld.setPosition( pOld.getPosition() + revisionsToRender.getLength() );
|
||||
} else {
|
||||
// Special case: old revision has been previously not loaded, need to initialize correct position
|
||||
$oldRevElement = this.getOldRevElement( $addedRevisions );
|
||||
if ( $oldRevElement.length !== 0 ) {
|
||||
pOld.setPosition( $oldRevElement.data( 'pos' ) );
|
||||
revisionStyleResetRequired = true;
|
||||
}
|
||||
|
||||
}
|
||||
pNew.setPosition( pNew.getPosition() + revisionsToRender.getLength() );
|
||||
|
||||
this.addClickHandlerToRevisions( $addedRevisions, $revisions, this.revisionWrapperClickHandler );
|
||||
|
||||
$( $addedRevisions.find( '.mw-revslider-revision-wrapper' ).get().reverse() ).each( function () { // TODO: this is horrible
|
||||
$revisions.prepend( $( this ) );
|
||||
} );
|
||||
|
||||
if ( revisionStyleResetRequired ) {
|
||||
this.resetRevisionStylesBasedOnPointerPosition( $slider );
|
||||
}
|
||||
|
||||
this.slider.setFirstVisibleRevisionIndex( this.slider.getFirstVisibleRevisionIndex() + revisionsToRender.getLength() );
|
||||
|
||||
scrollLeft = this.slider.getFirstVisibleRevisionIndex() * this.revisionWidth;
|
||||
$revisionContainer.scrollLeft( scrollLeft );
|
||||
if ( this.$element.css( 'direction' ) === 'rtl' ) {
|
||||
$revisionContainer.scrollLeft( self.getRtlScrollLeft( $revisionContainer, scrollLeft ) );
|
||||
}
|
||||
|
||||
this.slider.getRevisions().getView().adjustRevisionSizes( $slider );
|
||||
|
||||
$slider.find( '.mw-revslider-arrow-backwards' ).removeClass( 'mw-revslider-arrow-disabled' ).addClass( 'mw-revslider-arrow-enabled' );
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {jQuery} $revisions
|
||||
* @param {jQuery} $allRevisions
|
||||
* @param {Function} clickHandler
|
||||
*/
|
||||
addClickHandlerToRevisions: function ( $revisions, $allRevisions, clickHandler ) {
|
||||
var self = this;
|
||||
$revisions.find( '.mw-revslider-revision-wrapper' ).on(
|
||||
'click',
|
||||
null,
|
||||
{ view: self, revisionsDom: $allRevisions },
|
||||
clickHandler
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {jQuery} $slider
|
||||
*/
|
||||
shouldExpandSlider: function ( $slider ) {
|
||||
var sliderWidth = parseInt( $slider.css( 'width' ), 10 ),
|
||||
maxAvailableWidth = this.calculateSliderContainerWidth() + this.containerMargin;
|
||||
|
||||
return !this.noMoreNewerRevisions && sliderWidth < maxAvailableWidth;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {jQuery} $slider
|
||||
*/
|
||||
expandSlider: function ( $slider ) {
|
||||
var containerWidth = this.calculateSliderContainerWidth();
|
||||
|
||||
$slider.css( { width: ( containerWidth + this.containerMargin ) + 'px' } );
|
||||
$slider.find( '.mw-revslider-revisions-container' ).css( { width: containerWidth + 'px' } );
|
||||
$slider.find( '.mw-revslider-pointer-container' ).css( { width: containerWidth + this.revisionWidth - 1 + 'px' } );
|
||||
|
||||
if ( $slider.css( 'direction' ) === 'rtl' ) {
|
||||
this.alignPointers( 0 );
|
||||
}
|
||||
|
||||
this.slider.setRevisionsPerWindow( $slider.find( '.mw-revslider-revisions-container' ).width() / this.revisionWidth );
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
mw.libs.revisionSlider = mw.libs.revisionSlider || {};
|
||||
mw.libs.revisionSlider.SliderView = SliderView;
|
||||
|
||||
mw.libs.revisionSlider.calculateRevisionsPerWindow = function ( containerMargin, revisionWidth ) {
|
||||
return Math.floor( ( $( '#mw-content-text' ).width() - containerMargin ) / revisionWidth );
|
||||
};
|
||||
}( mediaWiki, jQuery ) );
|
||||
|
|
|
@ -1,27 +1,12 @@
|
|||
( function ( mw, $ ) {
|
||||
var api = new mw.libs.revisionSlider.Api( mw.util.wikiScript( 'api' ) );
|
||||
|
||||
/**
|
||||
* @param {Array} data
|
||||
* @return {Object}
|
||||
*/
|
||||
function getUserGenderData( data ) {
|
||||
var genderData = {},
|
||||
usersWithGender = data.filter( function ( item ) {
|
||||
return typeof item.gender !== 'undefined' && item.gender !== 'unknown';
|
||||
} );
|
||||
usersWithGender.forEach( function ( item ) {
|
||||
genderData[ item.name ] = item.gender;
|
||||
} );
|
||||
return genderData;
|
||||
}
|
||||
|
||||
mw.track( 'counter.MediaWiki.RevisionSlider.event.init' );
|
||||
mw.libs.revisionSlider.userOffset = mw.user.options.values.timecorrection ? mw.user.options.values.timecorrection.split( '|' )[ 1 ] : mw.config.values.extRevisionSliderTimeOffset;
|
||||
|
||||
api.fetchRevisions( {
|
||||
pageName: mw.config.get( 'wgPageName' ),
|
||||
startId: mw.config.get( 'wgCurRevisionId' ),
|
||||
api.fetchRevisionData( mw.config.get( 'wgPageName' ), {
|
||||
startId: mw.config.values.extRevisionSliderNewRev,
|
||||
limit: mw.libs.revisionSlider.calculateRevisionsPerWindow( 120, 16 ),
|
||||
|
||||
success: function ( data ) {
|
||||
var revs,
|
||||
|
@ -30,69 +15,42 @@
|
|||
slider;
|
||||
|
||||
try {
|
||||
revs = data.query.pages[ 0 ].revisions;
|
||||
if ( !revs ) {
|
||||
return;
|
||||
}
|
||||
revs = data.revisions;
|
||||
revs.reverse();
|
||||
|
||||
revisionList = new mw.libs.revisionSlider.RevisionList( mw.libs.revisionSlider.makeRevisions( revs ) );
|
||||
|
||||
api.fetchUserGenderData( {
|
||||
users: revisionList.getUserNames(),
|
||||
success: function ( data ) {
|
||||
var users = data.query.users;
|
||||
$container = $( '#mw-revslider-container' );
|
||||
slider = new mw.libs.revisionSlider.Slider( revisionList );
|
||||
slider.getView().render( $container );
|
||||
|
||||
if ( users ) {
|
||||
revisionList.setUserGenders( getUserGenderData( users ) );
|
||||
}
|
||||
|
||||
$container = $( '#mw-revslider-container' );
|
||||
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 );
|
||||
}
|
||||
|
||||
$container.append(
|
||||
$( '<button>' )
|
||||
.click( function () {
|
||||
mw.libs.revisionSlider.HelpDialog.show();
|
||||
} )
|
||||
.text( mw.message( 'revisionslider-show-help' ).text() )
|
||||
.addClass( 'mw-revslider-show-help' )
|
||||
.tipsy( {
|
||||
gravity: $( 'body' ).hasClass( 'ltr' ) ? 'se' : 'sw',
|
||||
offset: 15,
|
||||
title: function () {
|
||||
return mw.msg( 'revisionslider-show-help-tooltip' );
|
||||
}
|
||||
} )
|
||||
);
|
||||
|
||||
$( '#mw-revslider-placeholder' ).remove();
|
||||
},
|
||||
error: function ( err ) {
|
||||
$( '#mw-revslider-placeholder' )
|
||||
.text( mw.message( 'revisionslider-loading-failed' ).text() );
|
||||
console.log( err );
|
||||
mw.track( 'counter.MediaWiki.RevisionSlider.error.init.genders' );
|
||||
}
|
||||
} );
|
||||
} catch ( err ) {
|
||||
if ( err === 'RS-rev-out-of-range' ) {
|
||||
$( '#mw-revslider-placeholder' )
|
||||
.text( mw.message( 'revisionslider-loading-out-of-range' ).text() );
|
||||
console.log( err );
|
||||
mw.track( 'counter.MediaWiki.RevisionSlider.error.outOfRange' );
|
||||
} else {
|
||||
$( '#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 );
|
||||
}
|
||||
|
||||
$container.append(
|
||||
$( '<button>' )
|
||||
.click( function () {
|
||||
mw.libs.revisionSlider.HelpDialog.show();
|
||||
} )
|
||||
.text( mw.message( 'revisionslider-show-help' ).text() )
|
||||
.addClass( 'mw-revslider-show-help' )
|
||||
.tipsy( {
|
||||
gravity: $( 'body' ).hasClass( 'ltr' ) ? 'se' : 'sw',
|
||||
offset: 15,
|
||||
title: function () {
|
||||
return mw.msg( 'revisionslider-show-help-tooltip' );
|
||||
}
|
||||
} )
|
||||
);
|
||||
|
||||
$( '#mw-revslider-placeholder' ).remove();
|
||||
} catch ( err ) {
|
||||
$( '#mw-revslider-placeholder' )
|
||||
.text( mw.message( 'revisionslider-loading-failed' ).text() );
|
||||
console.log( err );
|
||||
mw.track( 'counter.MediaWiki.RevisionSlider.error.init' );
|
||||
}
|
||||
|
||||
},
|
||||
|
@ -103,4 +61,5 @@
|
|||
mw.track( 'counter.MediaWiki.RevisionSlider.error.init' );
|
||||
}
|
||||
} );
|
||||
|
||||
}( mediaWiki, jQuery ) );
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
comment: 'hello',
|
||||
parsedcomment: '<b>hello</b>',
|
||||
timestamp: '2016-04-26T10:27:14Z', // 10:27, 26 Apr 2016
|
||||
user: 'meh'
|
||||
user: 'meh',
|
||||
userGender: 'female'
|
||||
},
|
||||
rev = new Revision( data );
|
||||
|
||||
|
@ -19,7 +20,7 @@
|
|||
assert.equal( rev.getComment(), data.comment );
|
||||
assert.equal( rev.getParsedComment(), data.parsedcomment );
|
||||
assert.equal( rev.getUser(), data.user );
|
||||
assert.equal( rev.getUserGender(), '' );
|
||||
assert.equal( rev.getUserGender(), 'female' );
|
||||
assert.equal( rev.isMinor(), false );
|
||||
|
||||
if ( mw.config.get( 'wgUserLanguage' ) === 'en' ) {
|
||||
|
@ -106,15 +107,5 @@
|
|||
assert.notOk( rev.hasEmptyComment() );
|
||||
} );
|
||||
|
||||
QUnit.test( 'setUserGender adjusts a gender', function ( assert ) {
|
||||
var rev = new Revision( { user: 'Foo' } );
|
||||
|
||||
assert.equal( rev.getUserGender(), '' );
|
||||
|
||||
rev.setUserGender( 'female' );
|
||||
|
||||
assert.equal( rev.getUserGender(), 'female' );
|
||||
} );
|
||||
|
||||
} )( mediaWiki );
|
||||
|
||||
|
|
|
@ -27,66 +27,129 @@
|
|||
assert.equal( revs.getRevisions()[ 2 ].getRelativeSize(), -8 );
|
||||
} );
|
||||
|
||||
QUnit.test( 'getUserNames returns a list of unique names', function ( assert ) {
|
||||
QUnit.test( 'getUserGenders', function ( assert ) {
|
||||
var revs = new RevisionList( [
|
||||
new Revision( { revid: 1, user: 'User1' } ),
|
||||
new Revision( { revid: 1, user: 'User1', userGender: 'female' } ),
|
||||
new Revision( { revid: 2, user: 'User2' } ),
|
||||
new Revision( { revid: 3, user: 'User1' } )
|
||||
new Revision( { revid: 3, user: 'User3', userGender: 'male' } )
|
||||
] );
|
||||
|
||||
assert.deepEqual( revs.getUserGenders(), { User1: 'female', User2: '', User3: 'male' } );
|
||||
} );
|
||||
|
||||
QUnit.test( 'Push appends revisions to the end of the list', function ( assert ) {
|
||||
var list = new RevisionList( [
|
||||
new Revision( { revid: 1, size: 5 } ),
|
||||
new Revision( { revid: 2, size: 21 } ),
|
||||
new Revision( { revid: 3, size: 13 } )
|
||||
] ),
|
||||
userNames = revs.getUserNames();
|
||||
revisions;
|
||||
list.push( [
|
||||
new Revision( { revid: 6, size: 19 } ),
|
||||
new Revision( { revid: 8, size: 25 } )
|
||||
] );
|
||||
|
||||
assert.deepEqual( userNames, [ 'User1', 'User2' ] );
|
||||
revisions = list.getRevisions();
|
||||
assert.equal( list.getLength(), 5 );
|
||||
assert.equal( revisions[ 0 ].getId(), 1 );
|
||||
assert.equal( revisions[ 0 ].getRelativeSize(), 5 );
|
||||
assert.equal( revisions[ 1 ].getId(), 2 );
|
||||
assert.equal( revisions[ 1 ].getRelativeSize(), 16 );
|
||||
assert.equal( revisions[ 2 ].getId(), 3 );
|
||||
assert.equal( revisions[ 2 ].getRelativeSize(), -8 );
|
||||
assert.equal( revisions[ 3 ].getId(), 6 );
|
||||
assert.equal( revisions[ 3 ].getRelativeSize(), 6 );
|
||||
assert.equal( revisions[ 4 ].getId(), 8 );
|
||||
assert.equal( revisions[ 4 ].getRelativeSize(), 6 );
|
||||
} );
|
||||
|
||||
QUnit.test( 'getUserNames skips revisions without user specified', function ( assert ) {
|
||||
var revs = new RevisionList( [
|
||||
new Revision( { revid: 1, user: 'User1' } ),
|
||||
new Revision( { revid: 2 } )
|
||||
QUnit.test( 'Unshift prepends revisions to the beginning of the list', function ( assert ) {
|
||||
var list = new RevisionList( [
|
||||
new Revision( { revid: 5, size: 5 } ),
|
||||
new Revision( { revid: 6, size: 21 } ),
|
||||
new Revision( { revid: 7, size: 13 } )
|
||||
] ),
|
||||
userNames = revs.getUserNames();
|
||||
revisions;
|
||||
list.unshift( [
|
||||
new Revision( { revid: 2, size: 19 } ),
|
||||
new Revision( { revid: 4, size: 25 } )
|
||||
] );
|
||||
|
||||
assert.deepEqual( userNames, [ 'User1' ] );
|
||||
revisions = list.getRevisions();
|
||||
assert.equal( list.getLength(), 5 );
|
||||
assert.equal( revisions[ 0 ].getId(), 2 );
|
||||
assert.equal( revisions[ 0 ].getRelativeSize(), 19 );
|
||||
assert.equal( revisions[ 1 ].getId(), 4 );
|
||||
assert.equal( revisions[ 1 ].getRelativeSize(), 6 );
|
||||
assert.equal( revisions[ 2 ].getId(), 5 );
|
||||
assert.equal( revisions[ 2 ].getRelativeSize(), -20 );
|
||||
assert.equal( revisions[ 3 ].getId(), 6 );
|
||||
assert.equal( revisions[ 3 ].getRelativeSize(), 16 );
|
||||
assert.equal( revisions[ 4 ].getId(), 7 );
|
||||
assert.equal( revisions[ 4 ].getRelativeSize(), -8 );
|
||||
} );
|
||||
|
||||
QUnit.test( 'setUserGenders adjusts revision data', function ( assert ) {
|
||||
var revs = new RevisionList( [
|
||||
new Revision( { revid: 1, user: 'User1' } ),
|
||||
new Revision( { revid: 2, user: 'User2' } ),
|
||||
new Revision( { revid: 3, user: 'User3' } )
|
||||
QUnit.test( 'Unshift considers the size of the preceding revision if specified', function ( assert ) {
|
||||
var list = new RevisionList( [
|
||||
new Revision( { revid: 5, size: 5 } ),
|
||||
new Revision( { revid: 6, size: 21 } ),
|
||||
new Revision( { revid: 7, size: 13 } )
|
||||
] ),
|
||||
genders = { User1: 'female', User2: 'male', User3: 'unknown' };
|
||||
revisions;
|
||||
list.unshift(
|
||||
[
|
||||
new Revision( { revid: 2, size: 19 } ),
|
||||
new Revision( { revid: 4, size: 25 } )
|
||||
],
|
||||
12
|
||||
);
|
||||
|
||||
assert.equal( revs.getRevisions()[ 0 ].getUserGender(), '' );
|
||||
assert.equal( revs.getRevisions()[ 1 ].getUserGender(), '' );
|
||||
assert.equal( revs.getRevisions()[ 2 ].getUserGender(), '' );
|
||||
|
||||
revs.setUserGenders( genders );
|
||||
|
||||
assert.equal( revs.getRevisions()[ 0 ].getUserGender(), 'female' );
|
||||
assert.equal( revs.getRevisions()[ 1 ].getUserGender(), 'male' );
|
||||
assert.equal( revs.getRevisions()[ 2 ].getUserGender(), 'unknown' );
|
||||
revisions = list.getRevisions();
|
||||
assert.equal( list.getLength(), 5 );
|
||||
assert.equal( revisions[ 0 ].getId(), 2 );
|
||||
assert.equal( revisions[ 0 ].getRelativeSize(), 7 );
|
||||
} );
|
||||
|
||||
QUnit.test( 'setUserGenders no gender for a user', function ( assert ) {
|
||||
var revs = new RevisionList( [
|
||||
new Revision( { revid: 1, user: 'User1' } ),
|
||||
new Revision( { revid: 2, user: 'User2' } )
|
||||
QUnit.test( 'Slice returns a subset of the list', function ( assert ) {
|
||||
var list = new RevisionList( [
|
||||
new Revision( { revid: 1, size: 5 } ),
|
||||
new Revision( { revid: 2, size: 21 } ),
|
||||
new Revision( { revid: 3, size: 13 } ),
|
||||
new Revision( { revid: 6, size: 19 } ),
|
||||
new Revision( { revid: 8, size: 25 } )
|
||||
] ),
|
||||
slicedList = list.slice( 1, 3 ),
|
||||
revisions = slicedList.getRevisions();
|
||||
|
||||
assert.equal( slicedList.getLength(), 2 );
|
||||
assert.equal( revisions[ 0 ].getId(), 2 );
|
||||
assert.equal( revisions[ 0 ].getRelativeSize(), 16 );
|
||||
assert.equal( revisions[ 1 ].getId(), 3 );
|
||||
assert.equal( revisions[ 1 ].getRelativeSize(), -8 );
|
||||
} );
|
||||
|
||||
QUnit.test( 'Slice returns a subset of the list, end param omitted', function ( assert ) {
|
||||
var list = new RevisionList( [
|
||||
new Revision( { revid: 1, size: 5 } ),
|
||||
new Revision( { revid: 2, size: 21 } ),
|
||||
new Revision( { revid: 3, size: 13 } ),
|
||||
new Revision( { revid: 6, size: 19 } ),
|
||||
new Revision( { revid: 8, size: 25 } )
|
||||
] ),
|
||||
genders = { User1: 'female' };
|
||||
slicedList = list.slice( 1 ),
|
||||
revisions = slicedList.getRevisions();
|
||||
|
||||
assert.equal( revs.getRevisions()[ 0 ].getUserGender(), '' );
|
||||
assert.equal( revs.getRevisions()[ 1 ].getUserGender(), '' );
|
||||
|
||||
revs.setUserGenders( genders );
|
||||
|
||||
assert.equal( revs.getRevisions()[ 0 ].getUserGender(), 'female' );
|
||||
assert.equal( revs.getRevisions()[ 1 ].getUserGender(), '' );
|
||||
assert.equal( slicedList.getLength(), 4 );
|
||||
assert.equal( revisions[ 0 ].getId(), 2 );
|
||||
assert.equal( revisions[ 1 ].getId(), 3 );
|
||||
assert.equal( revisions[ 2 ].getId(), 6 );
|
||||
assert.equal( revisions[ 3 ].getId(), 8 );
|
||||
} );
|
||||
|
||||
QUnit.test( 'makeRevisions converts revision data into list of Revision objects', function ( assert ) {
|
||||
var revs = [
|
||||
{ revid: 1, size: 5 },
|
||||
{ revid: 2, size: 21 },
|
||||
{ revid: 1, size: 5, userGender: 'female' },
|
||||
{ revid: 2, size: 21, userGender: 'unknown' },
|
||||
{ revid: 3, size: 13 }
|
||||
],
|
||||
revisions = makeRevisions( revs );
|
||||
|
|
|
@ -40,26 +40,6 @@
|
|||
assert.equal( $revisionNew.attr( 'data-revid' ), 37 );
|
||||
} );
|
||||
|
||||
QUnit.test( 'render throws an exception when selected revision not in available range', function ( assert ) {
|
||||
var $container = $( '<div>' ),
|
||||
view = new SliderView( new Slider( new RevisionList( [
|
||||
new Revision( { revid: 3, size: 21, comment: 'Comment2', user: 'User2' } ),
|
||||
new Revision( { revid: 37, size: 13, comment: 'Comment3', user: 'User3' } )
|
||||
] ) ) );
|
||||
|
||||
mw.config.values.extRevisionSliderOldRev = 1;
|
||||
mw.config.values.extRevisionSliderNewRev = 37;
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
view.render( $container );
|
||||
},
|
||||
function ( e ) {
|
||||
return e === 'RS-rev-out-of-range';
|
||||
}
|
||||
);
|
||||
} );
|
||||
|
||||
QUnit.test( 'render throws an exception when no selected revisions provided', function ( assert ) {
|
||||
var $container = $( '<div>' ),
|
||||
view = new SliderView( new Slider( new RevisionList( [
|
||||
|
|
Loading…
Reference in a new issue