2013-06-06 23:14:11 +00:00
|
|
|
/*!
|
2013-06-25 00:41:01 +00:00
|
|
|
* VisualEditor UserInterface MWMediaResultWidget class.
|
2013-06-06 23:14:11 +00:00
|
|
|
*
|
2016-01-03 22:56:59 +00:00
|
|
|
* @copyright 2011-2016 VisualEditor Team and others; see AUTHORS.txt
|
2013-06-06 23:14:11 +00:00
|
|
|
* @license The MIT License (MIT); see LICENSE.txt
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2013-06-25 00:41:01 +00:00
|
|
|
* Creates an ve.ui.MWMediaResultWidget object.
|
2013-06-06 23:14:11 +00:00
|
|
|
*
|
|
|
|
* @class
|
2013-10-09 20:09:59 +00:00
|
|
|
* @extends OO.ui.OptionWidget
|
2013-06-06 23:14:11 +00:00
|
|
|
*
|
|
|
|
* @constructor
|
2013-09-25 10:21:09 +00:00
|
|
|
* @param {Object} [config] Configuration options
|
2015-02-12 01:07:44 +00:00
|
|
|
* @cfg {number} [rowHeight] Height of the row this result is part of
|
|
|
|
* @cfg {number} [maxRowWidth] A limit for the width of the row this
|
|
|
|
* result is a part of.
|
|
|
|
* @cfg {number} [minWidth] Minimum width for the result
|
|
|
|
* @cfg {number} [maxWidth] Maximum width for the result
|
2013-06-06 23:14:11 +00:00
|
|
|
*/
|
2014-11-22 01:40:00 +00:00
|
|
|
ve.ui.MWMediaResultWidget = function VeUiMWMediaResultWidget( config ) {
|
2014-11-21 13:00:50 +00:00
|
|
|
// Configuration initialization
|
2013-06-06 23:14:11 +00:00
|
|
|
config = config || {};
|
|
|
|
|
|
|
|
// Parent constructor
|
2016-08-22 21:44:59 +00:00
|
|
|
ve.ui.MWMediaResultWidget.super.call( this, config );
|
2013-06-06 23:14:11 +00:00
|
|
|
|
|
|
|
// Properties
|
2015-02-12 01:07:44 +00:00
|
|
|
this.setRowHeight( config.rowHeight || 150 );
|
|
|
|
this.maxRowWidth = config.maxRowWidth || 500;
|
|
|
|
this.minWidth = config.minWidth || this.maxRowWidth / 5;
|
|
|
|
this.maxWidth = config.maxWidth || this.maxRowWidth * 2 / 3;
|
|
|
|
|
|
|
|
this.imageDimensions = {};
|
|
|
|
|
|
|
|
this.isAudio = this.data.mediatype === 'AUDIO';
|
|
|
|
|
2015-01-15 18:50:30 +00:00
|
|
|
// Store the thumbnail url
|
2015-02-04 00:32:46 +00:00
|
|
|
this.thumbUrl = this.data.thumburl;
|
|
|
|
this.src = null;
|
2015-02-12 01:07:44 +00:00
|
|
|
this.row = null;
|
|
|
|
|
|
|
|
this.$thumb = $( '<img>' )
|
|
|
|
.addClass( 've-ui-mwMediaResultWidget-thumbnail' )
|
|
|
|
.on( {
|
|
|
|
load: this.onThumbnailLoad.bind( this ),
|
|
|
|
error: this.onThumbnailError.bind( this )
|
|
|
|
} );
|
|
|
|
this.$overlay = $( '<div>' )
|
|
|
|
.addClass( 've-ui-mwMediaResultWidget-overlay' );
|
|
|
|
|
|
|
|
this.calculateSizing( this.data );
|
2014-09-18 19:49:22 +00:00
|
|
|
|
|
|
|
// Get wiki default thumbnail size
|
|
|
|
this.defaultThumbSize = mw.config.get( 'wgVisualEditorConfig' )
|
|
|
|
.defaultUserOptions.defaultthumbsize;
|
|
|
|
|
2013-06-06 23:14:11 +00:00
|
|
|
// Initialization
|
|
|
|
this.setLabel( new mw.Title( this.data.title ).getNameText() );
|
2014-09-18 19:49:22 +00:00
|
|
|
this.$label.addClass( 've-ui-mwMediaResultWidget-nameLabel' );
|
|
|
|
|
2013-11-01 19:45:59 +00:00
|
|
|
this.$element
|
2013-06-25 00:41:01 +00:00
|
|
|
.addClass( 've-ui-mwMediaResultWidget ve-ui-texture-pending' )
|
2013-06-06 23:14:11 +00:00
|
|
|
.prepend( this.$thumb, this.$overlay );
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Inheritance */
|
|
|
|
|
2013-10-09 20:09:59 +00:00
|
|
|
OO.inheritClass( ve.ui.MWMediaResultWidget, OO.ui.OptionWidget );
|
2013-06-06 23:14:11 +00:00
|
|
|
|
|
|
|
/* Methods */
|
2013-07-31 22:53:29 +00:00
|
|
|
/** */
|
2013-06-25 00:41:01 +00:00
|
|
|
ve.ui.MWMediaResultWidget.prototype.onThumbnailLoad = function () {
|
2013-06-06 23:14:11 +00:00
|
|
|
this.$thumb.first().addClass( 've-ui-texture-transparency' );
|
2013-11-01 19:45:59 +00:00
|
|
|
this.$element
|
2013-06-25 00:41:01 +00:00
|
|
|
.addClass( 've-ui-mwMediaResultWidget-done' )
|
2013-06-06 23:14:11 +00:00
|
|
|
.removeClass( 've-ui-texture-pending' );
|
|
|
|
};
|
|
|
|
|
2013-07-31 22:53:29 +00:00
|
|
|
/** */
|
2013-06-25 00:41:01 +00:00
|
|
|
ve.ui.MWMediaResultWidget.prototype.onThumbnailError = function () {
|
2013-06-06 23:14:11 +00:00
|
|
|
this.$thumb.last()
|
|
|
|
.css( 'background-image', '' )
|
|
|
|
.addClass( 've-ui-texture-alert' );
|
2013-11-01 19:45:59 +00:00
|
|
|
this.$element
|
2013-06-25 00:41:01 +00:00
|
|
|
.addClass( 've-ui-mwMediaResultWidget-error' )
|
2013-06-06 23:14:11 +00:00
|
|
|
.removeClass( 've-ui-texture-pending' );
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2015-02-12 01:07:44 +00:00
|
|
|
* Resize the thumbnail and wrapper according to row height and bounding boxes, if given.
|
2013-06-06 23:14:11 +00:00
|
|
|
*
|
2015-02-12 01:07:44 +00:00
|
|
|
* @param {Object} originalDimensions Original image dimensions with width and height values
|
|
|
|
* @param {Object} [boundingBox] Specific bounding box, if supplied
|
2013-06-06 23:14:11 +00:00
|
|
|
*/
|
2015-02-12 01:07:44 +00:00
|
|
|
ve.ui.MWMediaResultWidget.prototype.calculateSizing = function ( originalDimensions, boundingBox ) {
|
|
|
|
var wrapperPadding,
|
|
|
|
imageDimensions = {};
|
2013-06-06 23:14:11 +00:00
|
|
|
|
2015-02-12 01:07:44 +00:00
|
|
|
boundingBox = boundingBox || {};
|
2013-06-06 23:14:11 +00:00
|
|
|
|
2015-02-12 01:07:44 +00:00
|
|
|
if ( this.isAudio ) {
|
2014-09-18 19:49:22 +00:00
|
|
|
// HACK: We are getting the wrong information from the
|
2015-02-12 01:07:44 +00:00
|
|
|
// API about audio files. Set their thumbnail to square 120px
|
2014-09-18 19:49:22 +00:00
|
|
|
imageDimensions = {
|
2015-02-12 01:07:44 +00:00
|
|
|
width: 120,
|
|
|
|
height: 120
|
2014-09-18 19:49:22 +00:00
|
|
|
};
|
2013-06-06 23:14:11 +00:00
|
|
|
} else {
|
2015-02-12 01:07:44 +00:00
|
|
|
// Get the image within the bounding box
|
|
|
|
imageDimensions = ve.dm.MWImageNode.static.resizeToBoundingBox(
|
|
|
|
// Image original dimensions
|
|
|
|
{
|
2015-08-12 14:01:49 +00:00
|
|
|
width: originalDimensions.width || originalDimensions.thumbwidth,
|
|
|
|
height: originalDimensions.height || originalDimensions.thumbwidth
|
2015-02-12 01:07:44 +00:00
|
|
|
},
|
|
|
|
// Bounding box
|
|
|
|
{
|
|
|
|
width: boundingBox.width || this.getImageMaxWidth(),
|
|
|
|
height: boundingBox.height || this.getRowHeight()
|
|
|
|
}
|
|
|
|
);
|
2013-06-06 23:14:11 +00:00
|
|
|
}
|
2015-02-12 01:07:44 +00:00
|
|
|
this.imageDimensions = imageDimensions;
|
|
|
|
// Set the thumbnail size
|
|
|
|
this.$thumb.css( this.imageDimensions );
|
2013-06-06 23:14:11 +00:00
|
|
|
|
2015-02-12 01:07:44 +00:00
|
|
|
// Set the box size
|
|
|
|
wrapperPadding = this.calculateWrapperPadding( this.imageDimensions );
|
|
|
|
this.$element.css( wrapperPadding );
|
2013-06-06 23:14:11 +00:00
|
|
|
};
|
2014-09-18 19:49:22 +00:00
|
|
|
|
2015-01-15 18:50:30 +00:00
|
|
|
/**
|
|
|
|
* Replace the empty .src attribute of the image with the
|
|
|
|
* actual src.
|
|
|
|
*/
|
|
|
|
ve.ui.MWMediaResultWidget.prototype.lazyLoad = function () {
|
2015-02-04 00:32:46 +00:00
|
|
|
if ( !this.hasSrc() ) {
|
|
|
|
this.src = this.thumbUrl;
|
|
|
|
this.$thumb.attr( 'src', this.thumbUrl );
|
|
|
|
}
|
2015-01-15 18:50:30 +00:00
|
|
|
};
|
|
|
|
|
2014-09-18 19:49:22 +00:00
|
|
|
/**
|
|
|
|
* Retrieve the store dimensions object
|
2015-08-19 18:21:01 +00:00
|
|
|
*
|
2014-09-18 19:49:22 +00:00
|
|
|
* @return {Object} Thumb dimensions
|
|
|
|
*/
|
|
|
|
ve.ui.MWMediaResultWidget.prototype.getDimensions = function () {
|
|
|
|
return this.dimensions;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Resize thumbnail and element according to the resize factor
|
2015-02-12 01:07:44 +00:00
|
|
|
*
|
|
|
|
* @param {number} resizeFactor The resizing factor for the image
|
2014-09-18 19:49:22 +00:00
|
|
|
*/
|
|
|
|
ve.ui.MWMediaResultWidget.prototype.resizeThumb = function ( resizeFactor ) {
|
2015-02-12 01:07:44 +00:00
|
|
|
var boundingBox,
|
|
|
|
imageOriginalWidth = this.imageDimensions.width,
|
|
|
|
wrapperWidth = this.$element.width();
|
|
|
|
// Set the new row height
|
|
|
|
this.setRowHeight( Math.ceil( this.getRowHeight() * resizeFactor ) );
|
|
|
|
|
|
|
|
boundingBox = {
|
|
|
|
width: Math.ceil( this.imageDimensions.width * resizeFactor ),
|
|
|
|
height: this.getRowHeight()
|
2014-09-18 19:49:22 +00:00
|
|
|
};
|
|
|
|
|
2015-02-12 01:07:44 +00:00
|
|
|
this.calculateSizing( this.data, boundingBox );
|
2014-09-18 19:49:22 +00:00
|
|
|
|
2015-02-12 01:07:44 +00:00
|
|
|
// We need to adjust the wrapper this time to fit the "perfect"
|
|
|
|
// dimensions, regardless of how small the image is
|
|
|
|
if ( imageOriginalWidth < wrapperWidth ) {
|
|
|
|
boundingBox.width = wrapperWidth * resizeFactor;
|
|
|
|
}
|
|
|
|
this.$element.css( this.calculateWrapperPadding( boundingBox ) );
|
2014-09-18 19:49:22 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Adjust the wrapper padding for small images
|
2015-02-12 01:07:44 +00:00
|
|
|
*
|
2014-09-18 19:49:22 +00:00
|
|
|
* @param {Object} thumbDimensions Thumbnail dimensions
|
2015-02-12 01:07:44 +00:00
|
|
|
* @return {Object} Css styling for the wrapper
|
2014-09-18 19:49:22 +00:00
|
|
|
*/
|
2015-02-12 01:07:44 +00:00
|
|
|
ve.ui.MWMediaResultWidget.prototype.calculateWrapperPadding = function ( thumbDimensions ) {
|
|
|
|
var css = {
|
2016-10-28 00:22:30 +00:00
|
|
|
height: this.rowHeight,
|
|
|
|
width: thumbDimensions.width,
|
|
|
|
lineHeight: this.getRowHeight() + 'px'
|
|
|
|
};
|
2014-09-18 19:49:22 +00:00
|
|
|
|
|
|
|
// Check if the image is too thin so we can make a bit of space around it
|
2015-02-12 01:07:44 +00:00
|
|
|
if ( thumbDimensions.width < this.minWidth ) {
|
|
|
|
css.width = this.minWidth;
|
2014-09-18 19:49:22 +00:00
|
|
|
}
|
|
|
|
|
2015-02-12 01:07:44 +00:00
|
|
|
return css;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the row height for all size calculations
|
|
|
|
*
|
2015-08-19 18:09:34 +00:00
|
|
|
* @return {number} rowHeight Row height
|
2015-02-12 01:07:44 +00:00
|
|
|
*/
|
|
|
|
ve.ui.MWMediaResultWidget.prototype.getRowHeight = function () {
|
|
|
|
return this.rowHeight;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the row height for all size calculations
|
|
|
|
*
|
|
|
|
* @param {number} rowHeight Row height
|
|
|
|
*/
|
|
|
|
ve.ui.MWMediaResultWidget.prototype.setRowHeight = function ( rowHeight ) {
|
|
|
|
this.rowHeight = rowHeight;
|
|
|
|
};
|
|
|
|
|
|
|
|
ve.ui.MWMediaResultWidget.prototype.setImageMaxWidth = function ( width ) {
|
|
|
|
this.maxWidth = width;
|
|
|
|
};
|
|
|
|
ve.ui.MWMediaResultWidget.prototype.getImageMaxWidth = function () {
|
|
|
|
return this.maxWidth;
|
2014-09-18 19:49:22 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the row this result is in.
|
2015-08-19 18:21:01 +00:00
|
|
|
*
|
2014-09-18 19:49:22 +00:00
|
|
|
* @param {number} row Row number
|
|
|
|
*/
|
|
|
|
ve.ui.MWMediaResultWidget.prototype.setRow = function ( row ) {
|
|
|
|
this.row = row;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the row this result is in.
|
2015-08-19 18:21:01 +00:00
|
|
|
*
|
2014-09-18 19:49:22 +00:00
|
|
|
* @return {number} row Row number
|
|
|
|
*/
|
|
|
|
ve.ui.MWMediaResultWidget.prototype.getRow = function () {
|
|
|
|
return this.row;
|
|
|
|
};
|
2015-01-15 18:50:30 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if the image has a src attribute already
|
2015-08-19 18:21:01 +00:00
|
|
|
*
|
2015-08-19 18:09:34 +00:00
|
|
|
* @return {boolean} Thumbnail has its source attribute set
|
2015-01-15 18:50:30 +00:00
|
|
|
*/
|
|
|
|
ve.ui.MWMediaResultWidget.prototype.hasSrc = function () {
|
2015-02-04 00:32:46 +00:00
|
|
|
return !!this.src;
|
2015-01-15 18:50:30 +00:00
|
|
|
};
|