mediawiki-extensions-Revisi.../modules/ext.RevisionSlider.DiffPage.js
addshore 5fbe86fc0f Fire wikipage.diff instead of revslider.diffreload
Also add a note to the console about WikEdDiff
& RevisionSlider interaction and the required code
change.

As the code change uses the wikipage.diff hook the code
change will actually have no effect until this patch
is deployed, which includes the removal of the hack
for WikEdDiff.

Bug: T142636
Change-Id: Ie88021abb2325cc6259cf2fb041fbdca4ae9ca89
Depends-On: Ie488021f5d0e314a8ad6c8d1f1f3d936c427d719
2016-09-13 10:37:51 +02:00

215 lines
6.9 KiB
JavaScript

( function ( mw, $ ) {
/* global wikEd */
/**
* Module handling diff page reloading and the RevisionSlider browser history
*
* @constructor
*/
var DiffPage = function () {
this.lastRequest = null;
};
$.extend( DiffPage.prototype, {
/**
* Refreshes the diff view with two given revision IDs
*
* @param {number} revId1
* @param {number} revId2
* @param {number} [retryAttempt=0]
*/
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"]' ).addClass( 'mw-revslider-diff-loading' );
this.lastRequest = $.ajax( {
url: mw.util.wikiScript( 'index' ),
data: data,
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' ),
$sidePanel = $( '#mw-panel' ),
$navigation = $( '#p-views' ),
$catLinks = $( '#catlinks' ),
$printFooter = $( '.printfooter' ),
scrollLeft = $container.find( '.mw-revslider-revisions-container' ).scrollLeft();
$data = $( data );
$data.find( '.mw-revslider-container' ).replaceWith( $container );
$navigation.replaceWith( $data.find( '#p-views' ) );
$catLinks.replaceWith( $data.find( '#catlinks' ) );
$sidePanel.replaceWith( $data.find( '#mw-panel' ) );
$printFooter.replaceWith( $data.find( '.printfooter' ) );
$contentText.html( $data.find( '#mw-content-text' ) )
.find( '.mw-revslider-revisions-container' ).scrollLeft( scrollLeft );
mw.hook( 'wikipage.content' ).fire( $contentText );
mw.hook( 'wikipage.diff' ).fire( $contentText.find( 'table.diff' ) );
// In order to correctly interact with third-party code (extensions and gadgets)
// Revision slider should trigger some general (core) hook that other parties listen too
// Following wikEdDiff.js-specific code is deprecated and will be removed in the future.
// WikEdDiff should be updated to use a hook.
if ( self.wikEdDiffDetected() ) {
console.log( 'You are running WikEdDiff & your copy of the code may need to be updated to work with the RevisionSlider.' );
console.log( 'Please see: https://phabricator.wikimedia.org/T143199#2631963' );
console.log( 'If WikEdDiff is still working while using the RevisonSlider then the code change has already been done.' );
}
}, function ( xhr ) {
$( 'table.diff[data-mw="interface"]' ).removeClass( 'mw-revslider-diff-loading' );
if ( xhr.statusText !== 'abort' ) {
this.tryCount++;
mw.track( 'counter.MediaWiki.RevisionSlider.error.refresh' );
if ( retryAttempt <= retryLimit ) {
console.log( 'Retrying request' );
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?
}
} );
},
wikEdDiffDetected: function () {
return typeof wikEd !== 'undefined' && $( 'meta[name=wikEdDiffSetupFlag]' ).length !== 0;
},
/**
* Replaces the current state in the history stack
*
* @param {number} revId1
* @param {number} revId2
* @param {SliderView} sliderView
*/
replaceState: function ( revId1, revId2, sliderView ) {
// IE8 and IE9 do not have history.pushState()
if ( typeof history.replaceState === 'function' ) {
history.replaceState(
this.getStateObject( revId1, revId2, sliderView ),
$( document ).find( 'title' ).text(),
this.getStateUrl( revId1, revId2 )
);
}
},
/**
* 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' ) {
history.pushState(
this.getStateObject( revId1, revId2, sliderView ),
$( document ).find( 'title' ).text(),
this.getStateUrl( revId1, revId2 )
);
}
},
/**
* Gets a state object to be used with history.replaceState and history.pushState
*
* @param {number} revId1
* @param {number} revId2
* @param {SliderView} sliderView
* @return {Object}
*/
getStateObject: function ( revId1, revId2, sliderView ) {
return {
revid1: revId1,
revid2: revId2,
pointerOlderPos: sliderView.pointerOlder.getPosition(),
pointerNewerPos: sliderView.pointerNewer.getPosition(),
sliderPos: sliderView.slider.getFirstVisibleRevisionIndex()
};
},
/**
* Gets a URL to be used with history.replaceState and history.pushState
*
* @param {number} revId1
* @param {number} revId2
* @return {string}
*/
getStateUrl: function ( revId1, revId2 ) {
var url = mw.util.wikiScript( 'index' ) + '?diff=' + Math.max( revId1, revId2 ) + '&oldid=' + Math.min( revId1, revId2 ),
params = this.getExtraDiffPageParams();
if ( Object.keys( params ).length > 0 ) {
Object.keys( params ).forEach( function ( key ) {
url += '&' + key + '=' + params[ key ];
} );
}
return url;
},
/**
* Returns an object containing all possible parameters that should be included in diff URLs
* when selected revisions change, e.g. uselang
*
* @return {Object}
*/
getExtraDiffPageParams: function () {
var params = {},
paramArray = location.search.substr( 1 ).split( '&' ).filter( function ( elem ) {
return elem.indexOf( '=' ) > 0 && elem.match( /^(diff|oldid)=/ ) === null;
} );
paramArray.forEach( function ( elem ) {
var pair = elem.split( '=', 2 );
params[ pair[ 0 ] ] = pair[ 1 ];
} );
return params;
},
/**
* @param {SliderView} sliderView
*/
initOnPopState: function ( sliderView ) {
var self = this;
window.addEventListener( 'popstate', function ( event ) {
if ( event.state === null ) {
return;
}
mw.track( 'counter.MediaWiki.RevisionSlider.event.historyChange' );
sliderView.pointerOlder.setPosition( event.state.pointerOlderPos );
sliderView.pointerNewer.setPosition( event.state.pointerNewerPos );
sliderView.slider.setFirstVisibleRevisionIndex( event.state.sliderPos );
sliderView.slide( 0 );
sliderView.resetPointerStylesBasedOnPosition();
sliderView.resetRevisionStylesBasedOnPointerPosition(
sliderView.$element.find( 'div.mw-revslider-revisions' )
);
self.refresh( event.state.revid1, event.state.revid2 );
} );
}
} );
mw.libs.revisionSlider = mw.libs.revisionSlider || {};
mw.libs.revisionSlider.DiffPage = DiffPage;
}( mediaWiki, jQuery ) );