mirror of
https://gerrit.wikimedia.org/r/mediawiki/skins/MinervaNeue
synced 2024-11-28 16:10:55 +00:00
136 lines
4.1 KiB
JavaScript
136 lines
4.1 KiB
JavaScript
|
( function ( M, $ ) {
|
||
|
var msg = mw.msg,
|
||
|
template = mw.template,
|
||
|
Overlay = M.require( 'mobile.startup/Overlay' );
|
||
|
|
||
|
/**
|
||
|
* Page overlay prompting a user for given action
|
||
|
* @class PointerOverlay
|
||
|
*/
|
||
|
function PointerOverlay() {
|
||
|
Overlay.apply( this, arguments );
|
||
|
}
|
||
|
|
||
|
OO.mfExtend( PointerOverlay, Overlay, {
|
||
|
className: 'overlay pointer-overlay tutorial-overlay',
|
||
|
isBorderBox: false,
|
||
|
fullScreen: false,
|
||
|
closeOnContentTap: true,
|
||
|
template: template.get( 'skins.minerva.newusers', 'PointerOverlay.hogan' ),
|
||
|
/**
|
||
|
* @cfg {Object} defaults Default options hash.
|
||
|
* @cfg {string} defaults.isCompact whether the pointer overlay should be compact
|
||
|
* @cfg {number} defaults.timeout in milliseconds. If not zero the pointer overlay will
|
||
|
* hide after this duration of time.
|
||
|
* @cfg {string} defaults.isTutorial whether the pointer overlay contains tutorial like instructions
|
||
|
* @cfg {string} defaults.summary Message describing thing being pointed to.
|
||
|
* @cfg {string} defaults.cancelMsg Cancel message.
|
||
|
* @cfg {string} defaults.appendToElement Where pointer overlay should be appended to.
|
||
|
* @cfg {string} defaults.target jQuery selector to point tutorial at
|
||
|
* @cfg {string} [defaults.alignment] Determines where the pointer should point to. Valid values 'left' or 'center'
|
||
|
* @cfg {string} [defaults.confirmMsg] Label for a confirm message.
|
||
|
*/
|
||
|
defaults: $.extend( {}, Overlay.prototype.defaults, {
|
||
|
summary: undefined,
|
||
|
isCompact: false,
|
||
|
isTutorial: false,
|
||
|
timeout: 0,
|
||
|
cancelMsg: msg( 'minerva-pointer-dismiss' ),
|
||
|
appendToElement: undefined,
|
||
|
target: undefined,
|
||
|
alignment: 'center',
|
||
|
confirmMsg: undefined
|
||
|
} ),
|
||
|
events: {
|
||
|
'click .cancel': 'hide'
|
||
|
},
|
||
|
postRender: function () {
|
||
|
var $target,
|
||
|
self = this;
|
||
|
|
||
|
Overlay.prototype.postRender.apply( this );
|
||
|
|
||
|
if ( this.options.isCompact ) {
|
||
|
this.$el.addClass( 'pointer-overlay-compact' );
|
||
|
}
|
||
|
if ( this.options.isTutorial ) {
|
||
|
this.$el.addClass( 'pointer-overlay-tutorial' );
|
||
|
}
|
||
|
if ( this.options.timeout ) {
|
||
|
setTimeout( function () {
|
||
|
self.hide();
|
||
|
}, this.options.timeout );
|
||
|
}
|
||
|
if ( self.options.target ) {
|
||
|
// FIXME: this option should be a jQuery object already. Avoid use of global $.
|
||
|
$target = $( self.options.target );
|
||
|
// Ensure we position the overlay correctly but do not show the arrow
|
||
|
self._position( $target );
|
||
|
this.addPointerArrow( $target );
|
||
|
}
|
||
|
},
|
||
|
/**
|
||
|
* Refreshes the pointer arrow.
|
||
|
* @method
|
||
|
* @param {string} target jQuery selector
|
||
|
*/
|
||
|
refreshPointerArrow: function ( target ) {
|
||
|
this.$pointer.remove();
|
||
|
this.addPointerArrow( $( target ) );
|
||
|
},
|
||
|
/**
|
||
|
* Position the overlay under a specified element
|
||
|
* @private
|
||
|
* @param {jQuery.Object} $pa An element that should be pointed at by the overlay
|
||
|
*/
|
||
|
_position: function ( $pa ) {
|
||
|
var left,
|
||
|
paOffset = $pa.offset(),
|
||
|
h = $pa.outerHeight( true ),
|
||
|
y = paOffset.top + h;
|
||
|
|
||
|
this.$el.css( 'top', y );
|
||
|
if ( this.options.autoHide ) {
|
||
|
left = paOffset.left;
|
||
|
this.$el.css( 'left', left );
|
||
|
}
|
||
|
},
|
||
|
/**
|
||
|
* Position overlay and add pointer arrow that points at specified element
|
||
|
* @method
|
||
|
* @param {jQuery.Object} $pa An element that should be pointed at by the overlay
|
||
|
*/
|
||
|
addPointerArrow: function ( $pa ) {
|
||
|
var left,
|
||
|
paOffset = $pa.offset(),
|
||
|
overlayOffset = this.$el.offset(),
|
||
|
center = $pa.width() / 2;
|
||
|
|
||
|
this._position( $pa );
|
||
|
// add the entire width of the pointer
|
||
|
left = 24;
|
||
|
if ( !this.options.autoHide ) {
|
||
|
left += paOffset.left - overlayOffset.left;
|
||
|
}
|
||
|
if ( this.alignment === 'center' ) {
|
||
|
left -= center;
|
||
|
}
|
||
|
|
||
|
this.$pointer = $( '<div class="tutorial-pointer"></div>' ).css( {
|
||
|
top: -6,
|
||
|
left: left
|
||
|
} ).appendTo( this.$el );
|
||
|
|
||
|
// Since the positioning of this overlay is dependent on the current viewport it makes sense to
|
||
|
// use a global window event so that on resizes it is correctly positioned.
|
||
|
M.on(
|
||
|
'resize',
|
||
|
$.proxy( this, 'refreshPointerArrow', this.options.target )
|
||
|
);
|
||
|
}
|
||
|
} );
|
||
|
|
||
|
M.define( 'skins.minerva.newusers/PointerOverlay', PointerOverlay );
|
||
|
|
||
|
}( mw.mobileFrontend, jQuery ) );
|