mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/RevisionSlider
synced 2024-11-15 03:33:45 +00:00
Introduce alternate SliderView
Adding a new class for an alternative slider view with one slider for each pointer. The new class will be used when the extension is installed as a beta feature. Each pointer has now its own pointer container visualized with a thin line. Pointers can not change places anymore and methods doing so where overwritten in the patch. Selected revisions are not colored atm to better distinguish between pointers and bars. Poiner lines are now shown above the bars. ( as from feedback in the last PM session ) Some issues with the design might remain. But since we plan the deployment anyway next week this could be merged if reviewed. Bug: T160410 Change-Id: If00c31e30f8a01f3525b191c70605b9c9381671d
This commit is contained in:
parent
040dd9c945
commit
c52c657516
|
@ -147,6 +147,17 @@
|
|||
"revisionslider-arrow-tooltip-older"
|
||||
]
|
||||
},
|
||||
"ext.RevisionSlider.SliderViewTwo": {
|
||||
"scripts": [
|
||||
"modules/ext.RevisionSlider.SliderViewTwo.js"
|
||||
],
|
||||
"styles": [
|
||||
"modules/ext.RevisionSliderViewTwo.css"
|
||||
],
|
||||
"dependencies": [
|
||||
"ext.RevisionSlider.SliderView"
|
||||
]
|
||||
},
|
||||
"ext.RevisionSlider.DiffPage": {
|
||||
"scripts": [
|
||||
"modules/ext.RevisionSlider.DiffPage.js"
|
||||
|
|
|
@ -7,7 +7,11 @@
|
|||
*/
|
||||
var Slider = function ( revisions ) {
|
||||
this.revisions = revisions;
|
||||
this.view = new mw.libs.revisionSlider.SliderView( this );
|
||||
if ( mw.config.get( 'extRevisionSliderBeta' ) ) {
|
||||
this.view = new mw.libs.revisionSlider.SliderViewTwo( this );
|
||||
} else {
|
||||
this.view = new mw.libs.revisionSlider.SliderView( this );
|
||||
}
|
||||
};
|
||||
|
||||
$.extend( Slider.prototype, {
|
||||
|
|
|
@ -190,7 +190,7 @@
|
|||
}
|
||||
} );
|
||||
|
||||
$pointers.draggable( this.buildDraggableOptions( escapePressed, $revisions ) );
|
||||
$pointers.draggable( this.buildDraggableOptions( escapePressed, $revisions, '.mw-revslider-pointer-container' ) );
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -198,16 +198,17 @@
|
|||
*
|
||||
* @param {boolean} escapePressed
|
||||
* @param {jQuery} $revisions
|
||||
* @param {string} containmentClass
|
||||
* @return {Object}
|
||||
*/
|
||||
buildDraggableOptions: function( escapePressed, $revisions ) {
|
||||
buildDraggableOptions: function( escapePressed, $revisions, containmentClass ) {
|
||||
var lastValidLeftPos,
|
||||
self = this;
|
||||
|
||||
return {
|
||||
axis: 'x',
|
||||
grid: [ this.revisionWidth, null ],
|
||||
containment: '.mw-revslider-pointer-container',
|
||||
containment: containmentClass,
|
||||
start: function() {
|
||||
self.setPointerDragCursor();
|
||||
self.fadeOutPointerLines();
|
||||
|
|
211
modules/ext.RevisionSlider.SliderViewTwo.js
Normal file
211
modules/ext.RevisionSlider.SliderViewTwo.js
Normal file
|
@ -0,0 +1,211 @@
|
|||
( function ( mw, $ ) {
|
||||
/**
|
||||
* Module handling the view logic of the RevisionSlider slider with two slides
|
||||
*
|
||||
* @param {Slider} slider
|
||||
* @constructor
|
||||
*/
|
||||
var SliderViewTwo = function ( slider ) {
|
||||
this.slider = slider;
|
||||
this.diffPage = new mw.libs.revisionSlider.DiffPage( this.slider.getRevisions() );
|
||||
};
|
||||
|
||||
OO.inheritClass( SliderViewTwo, mw.libs.revisionSlider.SliderView );
|
||||
|
||||
$.extend( SliderViewTwo.prototype, {
|
||||
/**
|
||||
* Renders the pointer container and adds the pointers to it
|
||||
*
|
||||
* @param {number} containerWidth
|
||||
* @return {jQuery} the pointer container
|
||||
*/
|
||||
renderPointerContainer: function( containerWidth ) {
|
||||
var pointerContainerPosition = 53,
|
||||
pointerContainerWidth = containerWidth + this.revisionWidth - 1,
|
||||
pointerContainerStyle;
|
||||
|
||||
pointerContainerStyle = { left: pointerContainerPosition + 'px', width: pointerContainerWidth + 'px' };
|
||||
if ( this.dir === 'rtl' ) {
|
||||
// Due to properly limit dragging a pointer on the right side of the screen,
|
||||
// there must some extra space added to the right of the revision bar container
|
||||
// For this reason right position of the pointer container in the RTL mode is
|
||||
// a bit moved off right compared to its left position in the LTR mode
|
||||
pointerContainerPosition = pointerContainerPosition - this.revisionWidth + 1;
|
||||
pointerContainerStyle = { right: pointerContainerPosition + 'px', width: pointerContainerWidth + 'px' };
|
||||
}
|
||||
|
||||
return $( '<div>' )
|
||||
.addClass( 'mw-revslider-pointer-container' )
|
||||
.css( pointerContainerStyle )
|
||||
.append( this.renderPointerContainers() );
|
||||
},
|
||||
|
||||
renderPointerContainers: function() {
|
||||
var self = this;
|
||||
|
||||
return [
|
||||
$( '<div>' )
|
||||
.addClass( 'mw-revslider-pointer-container-newer' )
|
||||
.click( function( event ) {
|
||||
self.sliderLineClickHandler( event, $( this ) );
|
||||
} )
|
||||
.append(
|
||||
$( '<div>' ).addClass( 'mw-revslider-slider-line' ),
|
||||
this.pointerNewer.getView().render()
|
||||
),
|
||||
$( '<div>' )
|
||||
.addClass( 'mw-revslider-pointer-container-older' )
|
||||
.click( function( event ) {
|
||||
self.sliderLineClickHandler( event, $( this ) );
|
||||
} )
|
||||
.append(
|
||||
$( '<div>' ).addClass( 'mw-revslider-slider-line' ),
|
||||
this.pointerOlder.getView().render()
|
||||
)
|
||||
];
|
||||
},
|
||||
|
||||
/**
|
||||
* Initializes the pointer dragging logic
|
||||
*
|
||||
* @param {jQuery} $revisions
|
||||
*/
|
||||
initPointers: function( $revisions ) {
|
||||
var $pointers,
|
||||
$pointerOlder = this.pointerOlder.getView().getElement(),
|
||||
$pointerNewer = this.pointerNewer.getView().getElement(),
|
||||
escapePressed = false;
|
||||
|
||||
$pointers = this.$element.find( '.mw-revslider-pointer' );
|
||||
|
||||
$( 'body' ).keydown( function( e ) {
|
||||
if ( e.which === 27 ) {
|
||||
escapePressed = true;
|
||||
$pointers.trigger( 'mouseup' );
|
||||
}
|
||||
} );
|
||||
|
||||
$pointerOlder.draggable( this.buildDraggableOptions(
|
||||
escapePressed, $revisions,
|
||||
'.mw-revslider-pointer-container-older'
|
||||
) );
|
||||
$pointerNewer.draggable( this.buildDraggableOptions(
|
||||
escapePressed, $revisions,
|
||||
'.mw-revslider-pointer-container-newer'
|
||||
) );
|
||||
|
||||
SliderViewTwo.super.prototype.resetPointerStylesBasedOnPosition.call( this );
|
||||
},
|
||||
|
||||
sliderLineClickHandler: function( event, $line ) {
|
||||
var $revisions = this.$element.find( '.mw-revslider-revisions' ),
|
||||
$clickedRev = this.getRevisionNearestToClick( event ),
|
||||
pointerMoved, pointerOther, newPosition;
|
||||
|
||||
newPosition = parseInt( $clickedRev.attr( 'data-pos' ) );
|
||||
|
||||
if ( $line.hasClass( 'mw-revslider-pointer-container-newer' ) ) {
|
||||
pointerMoved = this.pointerNewer;
|
||||
pointerOther = this.pointerOlder;
|
||||
} else {
|
||||
pointerMoved = this.pointerOlder;
|
||||
pointerOther = this.pointerNewer;
|
||||
}
|
||||
|
||||
if ( newPosition === pointerOther.getPosition() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
pointerMoved.setPosition( newPosition );
|
||||
this.updatePointerPositionAttributes();
|
||||
this.refreshRevisions(
|
||||
this.getRevElementAtPosition( $revisions, pointerOther.getPosition() ).attr( 'data-revid' ),
|
||||
$clickedRev.attr( 'data-revid' )
|
||||
);
|
||||
this.resetRevisionStylesBasedOnPointerPosition( $revisions );
|
||||
this.alignPointers();
|
||||
},
|
||||
|
||||
getRevisionNearestToClick: function( clickEvent ) {
|
||||
var $revisionArr = $( '.mw-revslider-revision' ),
|
||||
$current, rtlOffset, i = 0, count;
|
||||
|
||||
rtlOffset = this.dir === 'rtl' ? this.revisionWidth : 0;
|
||||
|
||||
for ( count = $revisionArr.length; i < count; i++ ) {
|
||||
$current = $( $revisionArr[ i ] );
|
||||
if ( Math.abs( $current.offset().left + rtlOffset - clickEvent.pageX ) < this.revisionWidth ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $current;
|
||||
},
|
||||
|
||||
resetPointerStylesBasedOnPosition: function() {
|
||||
this.updateOlderSliderLineCSS();
|
||||
this.updateNewerSliderLineCSS();
|
||||
},
|
||||
|
||||
resetPointerColorsBasedOnValues: function() {
|
||||
},
|
||||
|
||||
updateOlderSliderLineCSS: function() {
|
||||
var widthToSet = ( this.getOlderDistanceToOldest() + this.getDistanceBetweenPointers() ) *
|
||||
this.revisionWidth,
|
||||
marginToSet = -this.revisionWidth / 2;
|
||||
|
||||
widthToSet = Math.min( widthToSet, this.calculateSliderContainerWidth() + this.revisionWidth );
|
||||
|
||||
this.setSliderLineCSS(
|
||||
$( '.mw-revslider-pointer-container-older' ), widthToSet, marginToSet
|
||||
);
|
||||
},
|
||||
|
||||
updateNewerSliderLineCSS: function() {
|
||||
var widthToSet = ( this.getNewerDistanceToNewest() + this.getDistanceBetweenPointers() + 2 ) *
|
||||
this.revisionWidth,
|
||||
marginToSet = ( this.getOlderDistanceToOldest() * this.revisionWidth ) -
|
||||
this.revisionWidth / 2;
|
||||
|
||||
widthToSet = Math.min( widthToSet, this.calculateSliderContainerWidth() + this.revisionWidth );
|
||||
marginToSet = Math.max( marginToSet, -0.5 * this.revisionWidth );
|
||||
|
||||
this.setSliderLineCSS(
|
||||
$( '.mw-revslider-pointer-container-newer' ), widthToSet, marginToSet
|
||||
);
|
||||
},
|
||||
|
||||
setSliderLineCSS: function( $lineContainer, widthToSet, marginToSet ) {
|
||||
if ( this.dir === 'ltr' ) {
|
||||
$lineContainer.css( {
|
||||
width: widthToSet,
|
||||
'margin-left': marginToSet
|
||||
} );
|
||||
} else {
|
||||
$lineContainer.css( {
|
||||
width: widthToSet,
|
||||
'margin-right': marginToSet + this.revisionWidth
|
||||
} );
|
||||
}
|
||||
},
|
||||
|
||||
getOlderDistanceToOldest: function() {
|
||||
return this.pointerOlder.getPosition() - this.slider.getOldestVisibleRevisionIndex();
|
||||
},
|
||||
|
||||
getNewerDistanceToNewest: function() {
|
||||
return this.slider.getNewestVisibleRevisionIndex() - this.pointerNewer.getPosition();
|
||||
},
|
||||
|
||||
getDistanceBetweenPointers: function() {
|
||||
return this.pointerNewer.getPosition() - this.pointerOlder.getPosition();
|
||||
},
|
||||
|
||||
revisionWrapperClickHandler: function() {
|
||||
}
|
||||
} );
|
||||
|
||||
mw.libs.revisionSlider = mw.libs.revisionSlider || {};
|
||||
mw.libs.revisionSlider.SliderViewTwo = SliderViewTwo;
|
||||
}( mediaWiki, jQuery ) );
|
|
@ -118,6 +118,9 @@
|
|||
}
|
||||
} );
|
||||
|
||||
if ( mw.config.get( 'extRevisionSliderBeta' ) ) {
|
||||
mw.loader.load( 'ext.RevisionSlider.SliderViewTwo' );
|
||||
}
|
||||
expand();
|
||||
initialize();
|
||||
|
||||
|
|
80
modules/ext.RevisionSliderViewTwo.css
Normal file
80
modules/ext.RevisionSliderViewTwo.css
Normal file
|
@ -0,0 +1,80 @@
|
|||
.mw-revslider-revision-wrapper {
|
||||
cursor: auto;
|
||||
}
|
||||
|
||||
.mw-revslider-pointer-container {
|
||||
top: 52px;
|
||||
z-index: 10;
|
||||
height: 26px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.mw-revslider-pointer-container-newer,
|
||||
.mw-revslider-pointer-container-older {
|
||||
cursor: pointer;
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
.mw-revslider-revision-old,
|
||||
.mw-revslider-revision-new {
|
||||
background-color: #bcbcbc;
|
||||
border-color: #989898;
|
||||
}
|
||||
|
||||
.mw-revslider-revision-old:hover,
|
||||
.mw-revslider-revision-wrapper-hovered .mw-revslider-revision-old,
|
||||
.mw-revslider-revision-new:hover,
|
||||
.mw-revslider-revision-wrapper-hovered .mw-revslider-revision-new {
|
||||
background-color: #a6a6a6;
|
||||
border-color: #828282;
|
||||
}
|
||||
|
||||
.mw-revslider-pointer-container-newer {
|
||||
margin-top: 7px;
|
||||
}
|
||||
|
||||
.mw-revslider-slider-line {
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.mw-revslider-pointer-container-newer .mw-revslider-slider-line {
|
||||
height: 8px;
|
||||
border-bottom: 2px solid rgba( 30, 109, 184, 0.5 ); /* #1e6db8 */
|
||||
}
|
||||
|
||||
.mw-revslider-pointer-container-older .mw-revslider-slider-line {
|
||||
height: 2px;
|
||||
border-bottom: 2px solid rgba( 255, 204, 51, 0.5 ); /* #fc3 */
|
||||
}
|
||||
|
||||
.mw-revslider-pointer-upper.mw-revslider-pointer-newid {
|
||||
top: 8px;
|
||||
border: 1px solid #66b2ff;
|
||||
background: -webkit-linear-gradient( bottom, rgba( 47, 147, 247, 1 ), rgba( 3, 81, 159, 1 ) );
|
||||
background: -moz-linear-gradient( bottom, rgba( 47, 147, 247, 1 ), rgba( 3, 81, 159, 1 ) );
|
||||
background: -ms-linear-gradient( bottom, rgba( 47, 147, 247, 1 ), rgba( 3, 81, 159, 1 ) );
|
||||
background: -o-linear-gradient( bottom, rgba( 47, 147, 247, 1 ), rgba( 3, 81, 159, 1 ) );
|
||||
background: linear-gradient( to bottom, rgba( 47, 147, 247, 1 ), rgba( 3, 81, 159, 1 ) );
|
||||
}
|
||||
.mw-revslider-pointer-lower.mw-revslider-pointer-oldid {
|
||||
top: 14px;
|
||||
border: 1px solid #ffc561;
|
||||
background: -webkit-linear-gradient( bottom, rgba( 253, 224, 114, 1 ), rgba( 230, 173, 29, 1 ) );
|
||||
background: -moz-linear-gradient( bottom, rgba( 253, 224, 114, 1 ), rgba( 230, 173, 29, 1 ) );
|
||||
background: -ms-linear-gradient( bottom, rgba( 253, 224, 114, 1 ), rgba( 230, 173, 29, 1 ) );
|
||||
background: -o-linear-gradient( bottom, rgba( 253, 224, 114, 1 ), rgba( 230, 173, 29, 1 ) );
|
||||
background: linear-gradient( to bottom, rgba( 253, 224, 114, 1 ), rgba( 230, 173, 29, 1 ) );
|
||||
}
|
||||
|
||||
.mw-revslider-pointer {
|
||||
padding: 0;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.mw-revslider-pointer-line {
|
||||
z-index: 5;
|
||||
/* @noflip */
|
||||
margin-left: 1px;
|
||||
}
|
|
@ -68,6 +68,7 @@ class RevisionSliderHooks {
|
|||
$out->addJsConfigVars( 'extRevisionSliderOldRev', $oldRev->getId() );
|
||||
$out->addJsConfigVars( 'extRevisionSliderNewRev', $newRev->getId() );
|
||||
$out->addJsConfigVars( 'extRevisionSliderTimeOffset', intval( $timeOffset ) );
|
||||
$out->addJsConfigVars( 'extRevisionSliderBeta', $config->get( 'RevisionSliderBetaFeature' ) );
|
||||
$out->enableOOUI();
|
||||
|
||||
// FIXME: this really not nice to inject those elements to ButtonWidget like that
|
||||
|
|
Loading…
Reference in a new issue