2014-09-18 19:49:22 +00:00
|
|
|
/*!
|
|
|
|
* VisualEditor user interface MWMediaDialog class.
|
|
|
|
*
|
|
|
|
* @copyright 2011-2014 VisualEditor Team and others; see AUTHORS.txt
|
|
|
|
* @license The MIT License (MIT); see LICENSE.txt
|
|
|
|
*/
|
|
|
|
/* global moment */
|
|
|
|
/**
|
|
|
|
* MWMediaInfoFieldWidget widget for displaying media information from the API.
|
|
|
|
*
|
|
|
|
* @class
|
|
|
|
* @extends OO.ui.Widget
|
|
|
|
* @mixins OO.ui.IconElement
|
|
|
|
* @mixins OO.ui.TitledElement
|
|
|
|
*
|
|
|
|
* @constructor
|
|
|
|
* @param {Object} [config] Configuration options
|
|
|
|
* @cfg {string} [href] A url encapsulating the field text. If a label is attached it will include the label.
|
|
|
|
* @cfg {string} [label] A ve.msg() label string for the field.
|
|
|
|
* @cfg {boolean} [isDate] Field text is a date that will be converted to 'fromNow' string.
|
|
|
|
* @cfg {string} [type] Field type, either 'description' or 'attribute'
|
|
|
|
* @cfg {string} [descriptionHeight] Height limit for description fields; defaults to '4em'
|
|
|
|
*/
|
|
|
|
ve.ui.MWMediaInfoFieldWidget = function VeUiMWMediaInfoFieldWidget( content, config ) {
|
|
|
|
var datetime;
|
|
|
|
|
|
|
|
// Configuration initialization
|
|
|
|
config = config || {};
|
|
|
|
|
|
|
|
// Parent constructor
|
|
|
|
ve.ui.MWMediaInfoFieldWidget.super.call( this, config );
|
|
|
|
|
|
|
|
// Mixin constructors
|
|
|
|
OO.ui.IconElement.call( this, config );
|
2015-04-09 23:47:15 +00:00
|
|
|
OO.ui.LabelElement.call( this, $.extend( { $label: $( '<div>' ) }, config ) );
|
2014-09-18 19:49:22 +00:00
|
|
|
|
2015-04-09 23:47:15 +00:00
|
|
|
this.$text = $( '<div>' )
|
2014-09-18 19:49:22 +00:00
|
|
|
.addClass( 've-ui-mwMediaInfoFieldWidget-text' );
|
|
|
|
this.$overlay = null;
|
|
|
|
this.type = config.type || 'attribute';
|
|
|
|
|
|
|
|
// Initialization
|
|
|
|
if ( config.isDate && ( datetime = moment( content ) ).isValid() ) {
|
|
|
|
content = datetime.fromNow();
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( config.label ) {
|
|
|
|
content = ve.msg( config.label, content );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( config.href ) {
|
2015-02-17 02:23:03 +00:00
|
|
|
this.$text
|
|
|
|
.append(
|
2015-04-09 23:47:15 +00:00
|
|
|
$( '<a>' )
|
2015-02-17 02:23:03 +00:00
|
|
|
.attr( 'target', '_blank' )
|
|
|
|
.attr( 'rel', 'mw:ExtLink' )
|
|
|
|
.attr( 'href',
|
|
|
|
// For the cases where we get urls that are "local"
|
|
|
|
// without http(s) prefix, we will add that prefix
|
|
|
|
// ourselves
|
|
|
|
!config.href.match( /^(https?:)?\/\// ) ?
|
|
|
|
'//' + config.href :
|
|
|
|
config.href
|
|
|
|
)
|
|
|
|
.append( content )
|
|
|
|
);
|
2014-09-18 19:49:22 +00:00
|
|
|
} else {
|
|
|
|
this.$text.append( content );
|
|
|
|
}
|
|
|
|
|
|
|
|
this.$element
|
|
|
|
.append( this.$icon, this.$label )
|
|
|
|
.addClass( 've-ui-mwMediaInfoFieldWidget' )
|
|
|
|
.addClass( 've-ui-mwMediaInfoFieldWidget-' + this.type );
|
|
|
|
this.$icon.addClass( 've-ui-mwMediaInfoFieldWidget-icon' );
|
|
|
|
|
|
|
|
if ( this.type === 'description' ) {
|
|
|
|
// Limit height
|
|
|
|
this.readMoreButton = new OO.ui.ButtonWidget( {
|
|
|
|
framed: false,
|
|
|
|
icon: 'expand',
|
|
|
|
label: ve.msg( 'visualeditor-dialog-media-info-readmore' ),
|
|
|
|
classes: [ 've-ui-mwMediaInfoFieldWidget-readmore' ]
|
|
|
|
} );
|
|
|
|
this.readMoreButton.toggle( false );
|
|
|
|
this.readMoreButton.connect( this, { click: 'onReadMoreClick' } );
|
|
|
|
|
|
|
|
this.$text
|
|
|
|
.css( 'maxHeight', config.descriptionHeight || '4em' );
|
|
|
|
|
|
|
|
this.$element
|
|
|
|
.append( this.readMoreButton.$element );
|
|
|
|
}
|
|
|
|
|
|
|
|
this.setLabel( this.$text );
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Setup */
|
|
|
|
|
|
|
|
OO.inheritClass( ve.ui.MWMediaInfoFieldWidget, OO.ui.Widget );
|
|
|
|
OO.mixinClass( ve.ui.MWMediaInfoFieldWidget, OO.ui.IconElement );
|
|
|
|
OO.mixinClass( ve.ui.MWMediaInfoFieldWidget, OO.ui.LabelElement );
|
|
|
|
|
|
|
|
/* Static Properties */
|
|
|
|
|
|
|
|
ve.ui.MWMediaInfoFieldWidget.static.tagName = 'div';
|
|
|
|
|
2015-02-26 23:40:26 +00:00
|
|
|
/**
|
|
|
|
* Define a height threshold for the description fields.
|
|
|
|
* If the rendered field's height is under the defined limit
|
|
|
|
* (max-height + threshold) we should remove the max-height
|
|
|
|
* and display the field as-is.
|
|
|
|
* This prevents cases where "read more" appears but only
|
|
|
|
* exposes only a few pixels or a line extra.
|
|
|
|
*
|
|
|
|
* @property {number} Threshold in pixels
|
|
|
|
*/
|
|
|
|
ve.ui.MWMediaInfoFieldWidget.static.threshold = 24;
|
|
|
|
|
2014-09-18 19:49:22 +00:00
|
|
|
/**
|
|
|
|
* Toggle the read more button according to whether it should be
|
|
|
|
* visible or not.
|
|
|
|
*/
|
2015-02-26 23:40:26 +00:00
|
|
|
ve.ui.MWMediaInfoFieldWidget.prototype.initialize = function () {
|
|
|
|
var actualHeight, containerHeight;
|
|
|
|
|
|
|
|
if ( this.getType() === 'description' ) {
|
|
|
|
actualHeight = this.$text.prop( 'scrollHeight' );
|
|
|
|
containerHeight = this.$text.outerHeight( true );
|
|
|
|
|
|
|
|
if ( actualHeight < containerHeight + this.constructor.static.threshold ) {
|
|
|
|
// The contained result is big enough to show. Remove the maximum height
|
|
|
|
this.$text
|
|
|
|
.css( 'maxHeight', '' );
|
|
|
|
} else {
|
|
|
|
// Only show the readMore button if it should be shown
|
|
|
|
this.readMoreButton.toggle( containerHeight < actualHeight );
|
|
|
|
}
|
|
|
|
}
|
2014-09-18 19:49:22 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Respond to read more button click event.
|
|
|
|
*/
|
|
|
|
ve.ui.MWMediaInfoFieldWidget.prototype.onReadMoreClick = function () {
|
|
|
|
this.readMoreButton.toggle( false );
|
|
|
|
this.$text.css( 'maxHeight', this.$text.prop( 'scrollHeight' ) );
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get field type; 'attribute' or 'description'
|
|
|
|
* @return {string} Field type
|
|
|
|
*/
|
|
|
|
ve.ui.MWMediaInfoFieldWidget.prototype.getType = function () {
|
|
|
|
return this.type;
|
|
|
|
};
|