mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/MultimediaViewer
synced 2024-11-17 21:04:11 +00:00
2adf7a2008
Bug: 72516 Change-Id: Ia638688afc4d4373065c0d8a19dfcc11a7e9561e Mingle: https://wikimedia.mingle.thoughtworks.com/projects/multimedia/cards/1005
195 lines
5.5 KiB
JavaScript
195 lines
5.5 KiB
JavaScript
/*
|
|
* This file is part of the MediaWiki extension MediaViewer.
|
|
*
|
|
* MediaViewer is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* MediaViewer is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with MediaViewer. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
( function ( mw, $, oo ) {
|
|
var TDP;
|
|
|
|
/**
|
|
* @class mw.mmv.ui.TipsyDialog
|
|
* A simple popup dialog that can be opened and closed and can contain some HTML.
|
|
* Due to the way tipsy works, there can be only one TipsyDialog and/or tipsy tooltip on the same element.
|
|
* @extends mw.mmv.ui.Element
|
|
* @constructor
|
|
* @property {jQuery} $anchor the element to which the popup is anchored.
|
|
* @property {Object} options takes any tipsy option - see
|
|
* https://github.com/jaz303/tipsy/blob/master/docs/src/index.html.erb#L298
|
|
*/
|
|
function TipsyDialog( $anchor, options ) {
|
|
mw.mmv.ui.Element.call( this, null ); // tipsy does the element construction so we don't need a container
|
|
|
|
/** @property {jQuery} $anchor - */
|
|
this.$anchor = $anchor;
|
|
|
|
/** @property {Object} options - */
|
|
this.options = $.extend( {}, this.defaultOptions, options );
|
|
|
|
/** @property {boolean} dirty Track whether tipsy settings changed and need to be reinitialized. */
|
|
this.dirty = false;
|
|
|
|
/** @property {string|null} contentTitle Title of the dialog (optional) */
|
|
this.contentTitle = null;
|
|
|
|
/** @property {string|null} contentBody Contents of the dialog */
|
|
this.contentBody = null;
|
|
|
|
/** @property {Function} closeProxy Proxied close function to be used as an event handler, so it can be
|
|
* identified for removal. */
|
|
this.closeProxy = $.proxy( this.maybeCloseOnClick, this );
|
|
}
|
|
|
|
oo.inheritClass( TipsyDialog, mw.mmv.ui.Element );
|
|
TDP = TipsyDialog.prototype;
|
|
|
|
/**
|
|
* @property {Object} defaultOptions Tipsy defaults - see
|
|
* https://github.com/jaz303/tipsy/blob/master/docs/src/index.html.erb#L298
|
|
*/
|
|
TDP.defaultOptions = {
|
|
// tipsy options
|
|
trigger: 'manual',
|
|
html: true,
|
|
fade: false,
|
|
offset: 0,
|
|
gravity: 'sw'
|
|
};
|
|
|
|
/**
|
|
* @property {number} extraOffset offset adjustment to correct for the larger margins and tip size
|
|
* compared to the standard tipsy style
|
|
*/
|
|
TDP.extraOffset = 10;
|
|
|
|
/**
|
|
* @private
|
|
* @returns {boolean}
|
|
*/
|
|
TDP.isInitialized = function () {
|
|
return !!this.$anchor.tipsy( true );
|
|
};
|
|
|
|
/**
|
|
* @private
|
|
* Returns the preprocessed version of an options object:
|
|
* - directions are flipped on RTL documents
|
|
* - standard classnames are applied
|
|
* - HTML content is generated
|
|
* The original object is not changed.
|
|
* @param {Object} originalOptions
|
|
*/
|
|
TDP.getPreprocessedOptions = function ( originalOptions ) {
|
|
var options = $.extend( {}, originalOptions );
|
|
|
|
if ( options.className ) {
|
|
options.className += ' mw-mmv-tipsy-dialog';
|
|
} else {
|
|
options.className = ' mw-mmv-tipsy-dialog';
|
|
}
|
|
options.gravity = this.correctEW( options.gravity );
|
|
options.offset += this.extraOffset;
|
|
options.fallback = this.generateContent( this.contentTitle, this.contentBody );
|
|
|
|
return options;
|
|
};
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
TDP.init = function () {
|
|
var options;
|
|
|
|
if ( !this.isInitialized() || this.dirty ) {
|
|
options = this.getPreprocessedOptions( this.options );
|
|
this.$anchor.tipsy( options );
|
|
|
|
// add click handler to close the popup when clicking on X or outside
|
|
// off is to make sure we won't end up with more then one - init() can be called multiple times
|
|
this.$anchor.find( '.mw-mmv-tipsy-dialog-disable').add( document )
|
|
.off( 'click.mmv-tipsy-dialog', this.closeProxy )
|
|
.on( 'click.mmv-tipsy-dialog', this.closeProxy );
|
|
|
|
this.dirty = false;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Open the dialog
|
|
*/
|
|
TDP.open = function () {
|
|
this.init();
|
|
this.$anchor.tipsy( 'enable' ).tipsy( 'show' );
|
|
};
|
|
|
|
/**
|
|
* Close the dialog
|
|
*/
|
|
TDP.close = function () {
|
|
if ( this.isInitialized() ) {
|
|
this.$anchor.tipsy( 'hide' ).tipsy( 'disable' );
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Return the main popup element.
|
|
* @return {jQuery|null}
|
|
*/
|
|
TDP.getPopup = function () {
|
|
var tipsyData = this.$anchor.tipsy( true );
|
|
|
|
return tipsyData ? tipsyData.$tip : null;
|
|
};
|
|
|
|
/**
|
|
* Set dialog contents
|
|
* @param {string|null} title title of the dialog (plain text; escaping will be handled by TipsyDialog)
|
|
* @param {string|null} body content of the dialog (HTML; no escaping)
|
|
*/
|
|
TDP.setContent = function ( title, body ) {
|
|
this.contentTitle = title;
|
|
this.contentBody = body;
|
|
this.dirty = true;
|
|
};
|
|
|
|
/**
|
|
* @private
|
|
* @returns {string}
|
|
*/
|
|
TDP.generateContent = function ( title, body ) {
|
|
body = body || '';
|
|
if ( title ) {
|
|
body = '<div class="mw-mmv-tipsy-dialog-title">' + mw.html.escape( title ) + '</div>' + body;
|
|
}
|
|
return '<div class="mw-mmv-tipsy-dialog-disable"></div>' + body;
|
|
};
|
|
|
|
/**
|
|
* @private
|
|
* Click handler to be set on the document.
|
|
* @param {jQuery.Event} event
|
|
*/
|
|
TDP.maybeCloseOnClick = function ( event ) {
|
|
var $clickTarget = $( event.target );
|
|
|
|
if (
|
|
$clickTarget.closest( this.getPopup()).length === 0 // click was outside the dialog
|
|
|| $clickTarget.closest( '.mw-mmv-tipsy-dialog-disable').length > 0 // click was on the close icon
|
|
) {
|
|
this.close();
|
|
}
|
|
};
|
|
|
|
mw.mmv.ui.TipsyDialog = TipsyDialog;
|
|
} ( mediaWiki, jQuery, OO ) );
|