Enhance code documentation.

Bug: T137965
Change-Id: Ice393838545f1545ee085ecdcddfa35f60b32ecd
This commit is contained in:
Jakob Warkotsch 2016-06-17 15:06:12 +02:00
parent 3b9c3e73ad
commit 11ceffab2f
10 changed files with 342 additions and 7 deletions

View file

@ -1,8 +1,19 @@
( function ( mw, $ ) {
/**
* Module handling diff page reloading and the RevisionSlider browser history
*
* @constructor
*/
var DiffPage = function () {
};
$.extend( DiffPage.prototype, {
/**
* Refreshes the diff view with two given revision IDs
*
* @param {number} revId1
* @param {number} revId2
*/
refresh: function ( revId1, revId2 ) {
$( 'table.diff[data-mw="interface"]' )
.append( $( '<tr>' ) )
@ -43,6 +54,13 @@
} );
},
/**
* Pushes the current state onto the history stack
*
* @param {number} revId1
* @param {number} revId2
* @param {SliderView} sliderView
*/
pushState: function ( revId1, revId2, sliderView ) {
// IE8 and IE9 do not have history.pushState()
if ( typeof history.pushState === 'function' ) {
@ -60,6 +78,9 @@
}
},
/**
* @param {SliderView} sliderView
*/
initOnPopState: function ( sliderView ) {
var self = this;
window.addEventListener( 'popstate', function ( event ) {

View file

@ -2,6 +2,12 @@
// JSHint does not like OOJS' usage of "static" and "super"
/*jshint -W024 */
/**
* Module containing the RevisionSlider tutorial
*
* @param {Object} config
* @constructor
*/
var HelpDialog = function ( config ) {
HelpDialog.super.call( this, config );
};
@ -22,7 +28,14 @@
];
$.extend( HelpDialog.prototype, {
/**
* @type {OO.ui.PanelLayout[]}
*/
slides: [],
/**
* @type {number}
*/
slidePointer: 0,
initialize: function () {
@ -37,6 +50,9 @@
this.$body.append( this.stackLayout.$element );
},
/**
* @return {OO.ui.PanelLayout}
*/
getSlide1: function () {
var slide = new OO.ui.PanelLayout( { $: this.$, padded: true, expanded: false } );
@ -52,6 +68,9 @@
return slide;
},
/**
* @return {OO.ui.PanelLayout}
*/
getSlide2: function () {
var slide = new OO.ui.PanelLayout( { $: this.$, padded: true, expanded: false } );
@ -65,6 +84,9 @@
return slide;
},
/**
* @return {OO.ui.PanelLayout}
*/
getSlide3: function () {
var slide = new OO.ui.PanelLayout( { $: this.$, padded: true, expanded: false } );
@ -79,6 +101,9 @@
return slide;
},
/**
* @return {OO.ui.PanelLayout}
*/
getSlide4: function () {
var slide = new OO.ui.PanelLayout( { $: this.$, padded: true, expanded: false } );
@ -92,6 +117,10 @@
return slide;
},
/**
* @param {string} action
* @return {OO.ui.Process}
*/
getActionProcess: function ( action ) {
if ( action === 'next' ) {
this.stackLayout.setItem( this.slides[ ++this.slidePointer ] );
@ -121,13 +150,16 @@
/**
* Needed to set the initial height of the dialog
*
* @return {int}
* @return {number}
*/
getBodyHeight: function () {
return this.slides[ this.slidePointer ].$element.outerHeight( true );
}
} );
/**
* Shows the help dialog
*/
HelpDialog.show = function () {
var windowManager = new OO.ui.WindowManager(),
dialogue = new HelpDialog( { size: 'medium' } );

View file

@ -1,11 +1,17 @@
( function ( mw, $ ) {
/**
* Module containing logic for the revision pointers
*
* @param {string} id
* @constructor
*/
var Pointer = function ( id ) {
this.view = new mw.libs.revisionSlider.PointerView( this, id );
};
$.extend( Pointer.prototype, {
/**
* @type {int}
* @type {number}
*/
position: 0,
@ -14,14 +20,23 @@
*/
view: null,
/**
* @param {number} p
*/
setPosition: function ( p ) {
this.position = p;
},
/**
* @return {number}
*/
getPosition: function () {
return this.position;
},
/**
* @return {PointerView}
*/
getView: function () {
return this.view;
}

View file

@ -1,4 +1,11 @@
( function ( mw, $ ) {
/**
* Module containing presentation logic for the revision pointers
*
* @param {Pointer} pointer
* @param {string} id
* @constructor
*/
var PointerView = function ( pointer, id ) {
this.pointer = pointer;
this.id = id;
@ -13,12 +20,16 @@
/**
* @type {Pointer}
*/
pointer: null,
/**
* @type {jQuery}
*/
$html: null,
/**
* Initializes the DOM element
*/
initialize: function () {
this.$html = $( '<div>' )
.attr( 'id', this.id )
@ -40,10 +51,20 @@
return this.$html;
},
/**
* Returns whether a pointer is the upper/new revision pointer based on its CSS class
*
* @return {boolean}
*/
isUpperPointer: function () {
return this.getElement().hasClass( 'mw-upper-pointer' );
},
/**
* Returns the offset (margin-left) depending on whether its the upper or lower pointer
*
* @return {number}
*/
getOffset: function () {
return this.isUpperPointer() ? 16 : 0;
},
@ -56,6 +77,13 @@
return this.getElement().offsetParent().width() - pos - 16 - 15;
},
/**
* Moves the pointer to a position
*
* @param {number} posInPx
* @param {number} duration
* @return {jQuery}
*/
animateTo: function ( posInPx, duration ) {
var animatePos = { left: posInPx };
if ( this.getElement().css( 'direction' ) === 'rtl' ) {
@ -64,11 +92,26 @@
return this.getElement().animate( animatePos, duration );
},
/**
* Slides the pointer to the revision it's pointing at
*
* @param {Slider} slider
* @param {number} duration
* @return {jQuery}
*/
slideToPosition: function ( slider, duration ) {
var relativePos = this.pointer.getPosition() - slider.getFirstVisibleRevisionIndex();
return this.animateTo( ( relativePos - 1 ) * slider.getView().revisionWidth, duration );
},
/**
* Slides the pointer to the side of the slider when it's not in the current range of revisions
*
* @param {Slider} slider
* @param {boolean} posBeforeSlider
* @param {number} duration
* @return {jQuery}
*/
slideToSide: function ( slider, posBeforeSlider, duration ) {
if ( posBeforeSlider ) {
return this.animateTo( this.getOffset() - 2 * slider.getView().revisionWidth, duration );
@ -77,6 +120,13 @@
}
},
/**
* Decides based on its position whether the pointer should be sliding to the side or to its position
*
* @param {Slider} slider
* @param {number} duration
* @return {jQuery}
*/
slideToSideOrPosition: function ( slider, duration ) {
var firstVisibleRev = slider.getFirstVisibleRevisionIndex(),
posBeforeSlider = this.pointer.getPosition() < firstVisibleRev,

View file

@ -1,5 +1,9 @@
( function ( mw, $ ) {
/*global moment:false */
/**
* @param {Object} data - Containing keys `id`, `size`, `comment`, `parsedcomment`, `timestamp`, `user` and `minor`
* @constructor
*/
var Revision = function ( data ) {
this.id = data.revid;
this.size = data.size;
@ -12,12 +16,12 @@
$.extend( Revision.prototype, {
/**
* @type {int}
* @type {number}
*/
id: 0,
/**
* @type {int}
* @type {number}
*/
size: 0,
@ -47,34 +51,58 @@
user: '',
/**
* @type {int}
* @type {number}
*/
relativeSize: 0,
/**
* @return {number}
*/
getId: function () {
return this.id;
},
/**
* @return {number}
*/
getSize: function () {
return this.size;
},
/**
* @return {boolean}
*/
isMinor: function () {
return this.minor;
},
/**
* @return {string}
*/
getParsedComment: function () {
return this.parsedComment;
},
/**
* @return {boolean}
*/
hasEmptyComment: function () {
return this.getComment().trim().length === 0;
},
/**
* @return {string}
*/
getComment: function () {
return this.comment;
},
/**
* Uses moment.js to format the date
*
* @param {string} rawDate
* @return {string}
*/
formatDate: function ( rawDate ) {
// Moment's offset works "backwards", as the number of minutes
// behind UTC, so we need to make this number negative
@ -82,18 +110,30 @@
return moment( rawDate ).zone( offset ).format( 'HH:mm, D MMM YYYY' );
},
/**
* @return {string}
*/
getFormattedDate: function () {
return this.formatDate( this.timestamp );
},
/**
* @return {string}
*/
getUser: function () {
return this.user;
},
/**
* @param {number} size
*/
setRelativeSize: function ( size ) {
this.relativeSize = size;
},
/**
* @return {number}
*/
getRelativeSize: function () {
return this.relativeSize;
}

View file

@ -1,4 +1,8 @@
( function ( mw, $ ) {
/**
* @param {Revision[]} revs
* @constructor
*/
var RevisionList = function ( revs ) {
this.revisions = [];
this.initialize( revs );
@ -16,6 +20,11 @@
*/
view: null,
/**
* Inititializes the RevisionList from a list of Revisions
*
* @param {Revision[]} revs
*/
initialize: function ( revs ) {
var i, rev;
@ -27,6 +36,9 @@
}
},
/**
* @return {number}
*/
getBiggestChangeSize: function () {
var max = 0,
i;
@ -38,14 +50,23 @@
return max;
},
/**
* @return {Revision[]}
*/
getRevisions: function () {
return this.revisions;
},
/**
* @return {number}
*/
getLength: function () {
return this.revisions.length;
},
/**
* @return {RevisionListView}
*/
getView: function () {
return this.view;
}

View file

@ -1,4 +1,8 @@
( function ( mw, $ ) {
/**
* @param {RevisionList} revisionList
* @constructor
*/
var RevisionListView = function ( revisionList ) {
this.revisionList = revisionList;
};
@ -9,6 +13,10 @@
*/
revisionList: null,
/**
* @param {number} revisionTickWidth
* @return {jQuery}
*/
render: function ( revisionTickWidth ) {
var $html = $( '<div>' ).addClass( 'mw-revisions' ),
revs = this.revisionList.getRevisions(),
@ -49,6 +57,12 @@
return $html;
},
/**
* Generates the HTML for a tooltip that appears on hover above each revision on the slider
*
* @param {Revision} rev
* @return {string}
*/
makeTooltip: function ( rev ) {
var $tooltip = $( '<div>' )
.append(
@ -70,6 +84,12 @@
return $tooltip.html();
},
/**
* Generates the HTML for the comment label
*
* @param {Revision} rev
* @return {string|jQuery}
*/
makeCommentLine: function ( rev ) {
if ( rev.hasEmptyComment() ) {
return '';

View file

@ -1,4 +1,10 @@
( function ( mw, $ ) {
/**
* Module handling the slider logic of the RevisionSlider
*
* @param {RevisionList} revisions
* @constructor
*/
var Slider = function ( revisions ) {
this.revisions = revisions;
this.view = new mw.libs.revisionSlider.SliderView( this );
@ -10,8 +16,14 @@
*/
revisions: null,
/**
* @type {number}
*/
firstVisibleRevisionIndex: 0,
/**
* @type {number}
*/
revisionsPerWindow: 0,
/**
@ -19,42 +31,82 @@
*/
view: null,
/**
* @return {RevisionList}
*/
getRevisions: function () {
return this.revisions;
},
/**
* @return {SliderView}
*/
getView: function () {
return this.view;
},
/**
* Sets the number of revisions that are visible at once (depending on browser window size)
*
* @param {number} n
*/
setRevisionsPerWindow: function ( n ) {
this.revisionsPerWindow = n;
},
/**
* @return {number}
*/
getRevisionsPerWindow: function () {
return this.revisionsPerWindow;
},
/**
* Returns the index of the first revision that is visible in the current window
*
* @return {number}
*/
getFirstVisibleRevisionIndex: function () {
return this.firstVisibleRevisionIndex;
},
/**
* Returns the index of the last revision that is visible in the current window
*
* @return {number}
*/
getLastVisibleRevisionIndex: function () {
return this.firstVisibleRevisionIndex + this.revisionsPerWindow - 1;
},
/**
* @return {boolean}
*/
isAtStart: function () {
return this.getFirstVisibleRevisionIndex() === 0 || this.revisions.getLength() <= this.revisionsPerWindow;
},
/**
* @return {boolean}
*/
isAtEnd: function () {
return this.getLastVisibleRevisionIndex() === this.revisions.getLength() - 1 || this.revisions.getLength() <= this.revisionsPerWindow;
},
/**
* Sets the index of the first revision that is visible in the current window
*
* @param {number} value
*/
setFirstVisibleRevisionIndex: function ( value ) {
this.firstVisibleRevisionIndex = value;
},
/**
* Sets the new firstVisibleRevisionIndex after sliding in a direction
*
* @param {number} direction - Either -1 or 1
*/
slide: function ( direction ) {
var highestPossibleFirstRev = this.revisions.getLength() - this.revisionsPerWindow;

View file

@ -1,4 +1,10 @@
( function ( mw, $ ) {
/**
* Module handling the view logic of the RevisionSlider slider
*
* @param {Slider} slider
* @constructor
*/
var SliderView = function ( slider ) {
this.slider = slider;
this.diffPage = new mw.libs.revisionSlider.DiffPage( this.slider.getRevisions() );
@ -246,14 +252,30 @@
this.diffPage.initOnPopState( this );
},
/**
* Returns the pointer that points to the older revision
*
* @return {Pointer}
*/
getOldRevPointer: function () {
return this.pointerOlder.getPosition() <= this.pointerNewer.getPosition() ? this.pointerOlder : this.pointerNewer;
},
/**
* Returns the pointer that points to the newer revision
*
* @return {Pointer}
*/
getNewRevPointer: function () {
return this.pointerOlder.getPosition() > this.pointerNewer.getPosition() ? this.pointerOlder : this.pointerNewer;
},
/**
* Refreshes the diff page to show the diff for the specified revisions
*
* @param {number} revId1
* @param {number} revId2
*/
refreshRevisions: function ( revId1, revId2 ) {
var oldRev = Math.min( revId1, revId2 ),
newRev = Math.max( revId1, revId2 );
@ -261,18 +283,41 @@
this.diffPage.pushState( oldRev, newRev, this );
},
/**
* @param {jQuery} $revs
* @param {number} pos
* @return {jQuery}
*/
getRevElementAtPosition: function ( $revs, pos ) {
return $revs.find( 'div.mw-revision[data-pos="' + pos + '"]' );
},
/**
* Gets the jQuery element of the older selected revision
*
* @param {jQuery} $revs
* @return {jQuery}
*/
getOldRevElement: function ( $revs ) {
return $revs.find( 'div.mw-revision[data-revid="' + mw.config.values.extRevisionSliderOldRev + '"]' );
},
/**
* Gets the jQuery element of the newer selected revision
*
* @param {jQuery} $revs
* @return {jQuery}
*/
getNewRevElement: function ( $revs ) {
return $revs.find( 'div.mw-revision[data-revid="' + mw.config.values.extRevisionSliderNewRev + '"]' );
},
/**
* Initializes the Pointer objects based on the selected revisions
*
* @param {jQuery} $oldRevElement
* @param {jQuery} $newRevElement
*/
initializePointers: function ( $oldRevElement, $newRevElement ) {
if ( $oldRevElement.length === 0 || $newRevElement.length === 0 ) {
// Note: this is currently caught in init.js
@ -283,6 +328,13 @@
this.resetPointerStylesBasedOnPosition();
},
/**
* Adjusts the colors of the pointers without changing the upper/lower property based on values `p1` and `p2`.
* Used e.g. when pointers get dragged past one another.
*
* @param {number} p1
* @param {number} p2
*/
resetPointerColorsBasedOnValues: function ( p1, p2 ) {
if ( p1 > p2 ) {
this.pointerOlder.getView().getElement().removeClass( 'mw-oldid-pointer' ).addClass( 'mw-newid-pointer' );
@ -293,6 +345,9 @@
}
},
/**
* Resets the pointer styles (upper/lower, blue/yellow) based on their position.
*/
resetPointerStylesBasedOnPosition: function () {
this.getNewRevPointer().getView().getElement().removeClass( 'mw-oldid-pointer' ).addClass( 'mw-newid-pointer' )
.removeClass( 'mw-lower-pointer' ).addClass( 'mw-upper-pointer' );
@ -300,6 +355,11 @@
.removeClass( 'mw-upper-pointer' ).addClass( 'mw-lower-pointer' );
},
/**
* Highlights revisions between the pointers
*
* @param {jQuery} $revisions
*/
resetRevisionStylesBasedOnPointerPosition: function ( $revisions ) {
var olderRevPosition = this.getOldRevPointer().getPosition(),
newerRevPosition = this.getNewRevPointer().getPosition(),
@ -316,10 +376,18 @@
}
},
/**
* 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;
},
@ -362,7 +430,11 @@
this.alignPointers( duration );
},
// Based on jQuery RTL Scroll Type Detector plugin by othree: https://github.com/othree/jquery.rtl-scroll-type
/**
* Based on jQuery RTL Scroll Type Detector plugin by othree: https://github.com/othree/jquery.rtl-scroll-type
*
* @return {string} - 'default', 'negative' or 'reverse'
*/
determineRtlScrollType: function () {
var $dummy = $( '<div>' )
.css( {
@ -386,6 +458,11 @@
return 'reverse';
},
/**
* @param {jQuery} $element
* @param {number} scrollLeft
* @return {number}
*/
getRtlScrollLeft: function ( $element, scrollLeft ) {
if ( this.rtlScrollLeftType === 'reverse' ) {
return scrollLeft;
@ -411,6 +488,12 @@
} );
},
/**
* Returns the Pointer object that belongs to the passed element
*
* @param {jQuery} $e
* @return {Pointer}
*/
whichPointer: function ( $e ) {
return $e.attr( 'id' ) === 'mw-revslider-pointer-older' ? this.pointerOlder : this.pointerNewer;
}

View file

@ -4,7 +4,8 @@
/**
* Fetches up to 500 revisions at a time
*
* @param {{}} options - Options containing success /error callback, pageName and startId
* @param {Object} options - Options containing callbacks for `success` and `error` as well as fields for
* `pageName` and `startId`
*/
mw.libs.revisionSlider.fetchRevisions = function ( options ) {
$.ajax( {