' )
.text( ' ' )
.prop( 'title', mw.message( 'multimediaviewer-viewfile-link' ).text() )
.tipsy( {
delayIn: tooltipDelay,
gravity: this.isRTL() ? 'sw' : 'se'
} )
.addClass( 'mw-mmv-viewfile' )
.click( function () {
mw.mmv.actionLogger.log( 'view-original-file' );
$( document ).trigger( 'mmv-viewfile' );
} );
this.$next = $( '
' )
.prop( 'title', mw.message( 'multimediaviewer-next-image-popup-text' ).text() )
.tipsy( {
delayIn: tooltipDelay,
gravity: this.isRTL() ? 'w' : 'e'
} )
.addClass( 'mw-mmv-next-image disabled' )
.html( ' ' );
this.$prev = $( '
' )
.prop( 'title', mw.message( 'multimediaviewer-prev-image-popup-text' ).text() )
.tipsy( {
delayIn: tooltipDelay,
gravity: this.isRTL() ? 'e' : 'w'
} )
.addClass( 'mw-mmv-prev-image disabled' )
.html( ' ' );
this.$nav = this.$next
.add( this.$prev );
this.$buttons = this.$close
.add( this.$fullscreen )
.add( this.$next )
.add( this.$prev )
.add( this.$viewFile );
this.$buttons.appendTo( this.$container );
$( document ).on( 'mmv-close', function () {
buttons.$nav.addClass( 'disabled' );
} );
this.$close.click( function () {
$container.trigger( $.Event( 'mmv-close' ) );
} );
this.$next.click( function () {
$container.trigger( $.Event( 'mmv-next' ) );
} );
this.$prev.click( function () {
$container.trigger( $.Event( 'mmv-prev' ) );
} );
}
oo.inheritClass( CanvasButtons, mw.mmv.ui.Element );
CBP = CanvasButtons.prototype;
/**
* Sets the top offset for the navigation buttons.
* @param {number} offset
*/
CBP.setOffset = function ( offset ) {
this.$nav.css( {
top: offset
} );
};
/**
* Stops the fading animation of the buttons and cancel any opacity value
*/
CBP.stopFade = function () {
this.$buttons
.stop( true )
.removeClass( 'hidden' )
.css( 'opacity', '' );
this.$container.trigger( $.Event( 'mmv-fade-stopped' ) );
};
/**
* Toggles buttons being disabled or not
* @param {boolean} showPrevButton
* @param {boolean} showNextButton
*/
CBP.toggle = function ( showPrevButton, showNextButton ) {
this.$next.toggleClass( 'disabled', !showPrevButton );
this.$prev.toggleClass( 'disabled', !showNextButton );
};
/**
* Fades out the active buttons
*/
CBP.fadeOut = function () {
var buttons = this;
// We don't use animation chaining because delay() can't be stop()ed
this.buttonsFadeTimeout = setTimeout( function() {
buttons.$buttons.not( '.disabled' ).animate( { opacity: 0 }, 1000, 'swing',
function () {
buttons.$buttons.addClass( 'hidden' );
buttons.$container.trigger( $.Event( 'mmv-faded-out' ) );
} );
}, 1500 );
};
/**
* Checks if any active buttons are currently hovered, given a position
* @param {number} x The horizontal coordinate of the position
* @param {number} y The vertical coordinate of the position
* @return bool
*/
CBP.isAnyActiveButtonHovered = function ( x, y ) {
// We don't use mouseenter/mouseleave events because content is subject
// to change underneath the cursor, eg. when entering fullscreen or
// when going prev/next (the button can disappear when reaching ends)
var hovered = false;
this.$buttons.not( '.disabled' ).each( function( idx, e ) {
var $e = $( e ),
offset = $e.offset();
if ( y >= offset.top
&& y <= offset.top + $e.height()
&& x >= offset.left
&& x <= offset.left + $e.width() ) {
hovered = true;
}
} );
return hovered;
};
/**
* Reveals all active buttons and schedule a fade out if needed
*/
CBP.revealAndFade = function ( mousePosition ) {
if ( this.buttonsFadeTimeout ) {
clearTimeout( this.buttonsFadeTimeout );
}
// Stop ongoing animations and make sure the buttons that need to be displayed are displayed
this.stopFade();
// mousePosition can be empty, for instance when we enter fullscreen and haven't
// recorded a real mousemove event yet
if ( !mousePosition
|| !this.isAnyActiveButtonHovered( mousePosition.x, mousePosition.y ) ) {
this.fadeOut();
}
};
/**
* Removes all UI things from the DOM, or hides them
*/
CBP.unattach = function () {
this.$viewFile.tipsy( 'hide' );
this.$close.tipsy( 'hide' );
this.$fullscreen.tipsy( 'hide' );
};
mw.mmv.ui.CanvasButtons = CanvasButtons;
}( mediaWiki, jQuery, OO ) );