mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-15 10:35:48 +00:00
ve.ui.MWMediaDialog: Clean up image metadata display
* Fix incorrect use of .append() instead of .text() (which was causing
some l10n messages to be treated as raw HTML)
* Avoid escaping and parsing HTML several times when plain text was
intended
* Remove some unused options and variables
Follow-up to 839b64d882
.
Change-Id: I124257c73fe09713afefccdec8e90200e6ae433d
This commit is contained in:
parent
839b64d882
commit
97be4e21ad
|
@ -508,9 +508,7 @@ ve.ui.MWMediaDialog.prototype.buildMediaInfoPanel = function ( imageinfo ) {
|
|||
{
|
||||
name: 'ImageDescription',
|
||||
value: ve.getProp( metadata, 'ImageDescription', 'value' ),
|
||||
data: {
|
||||
keepOriginal: true
|
||||
},
|
||||
format: 'html',
|
||||
view: {
|
||||
type: 'description',
|
||||
primary: true,
|
||||
|
@ -519,13 +517,15 @@ ve.ui.MWMediaDialog.prototype.buildMediaInfoPanel = function ( imageinfo ) {
|
|||
},
|
||||
{
|
||||
name: '$fileDetails',
|
||||
data: { skipProcessing: true },
|
||||
// Real value is set later
|
||||
value: '',
|
||||
format: 'html',
|
||||
view: { icon: 'image' }
|
||||
},
|
||||
{
|
||||
name: 'LicenseShortName',
|
||||
value: ve.getProp( metadata, 'LicenseShortName', 'value' ),
|
||||
data: {},
|
||||
format: 'html-remove-formatting',
|
||||
view: {
|
||||
href: ve.getProp( metadata, 'LicenseUrl', 'value' ),
|
||||
icon: this.getLicenseIcon( ve.getProp( metadata, 'LicenseShortName', 'value' ) )
|
||||
|
@ -534,54 +534,52 @@ ve.ui.MWMediaDialog.prototype.buildMediaInfoPanel = function ( imageinfo ) {
|
|||
{
|
||||
name: 'Artist',
|
||||
value: ve.getProp( metadata, 'Artist', 'value' ),
|
||||
data: {},
|
||||
format: 'html-remove-formatting',
|
||||
view: {
|
||||
// "Artist" label
|
||||
label: 'visualeditor-dialog-media-info-meta-artist',
|
||||
labelMsg: 'visualeditor-dialog-media-info-meta-artist',
|
||||
icon: 'userAvatar'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Credit',
|
||||
value: ve.getProp( metadata, 'Credit', 'value' ),
|
||||
data: {},
|
||||
format: 'html-remove-formatting',
|
||||
view: { icon: 'userAvatar' }
|
||||
},
|
||||
{
|
||||
name: 'user',
|
||||
value: imageinfo.user,
|
||||
data: { skipProcessing: true },
|
||||
format: 'plaintext',
|
||||
view: {
|
||||
icon: 'userAvatar',
|
||||
// This is 'uploaded by'
|
||||
label: 'visualeditor-dialog-media-info-artist'
|
||||
labelMsg: 'visualeditor-dialog-media-info-artist'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'timestamp',
|
||||
value: imageinfo.timestamp,
|
||||
data: {
|
||||
ignoreCharLimit: true
|
||||
},
|
||||
format: 'plaintext',
|
||||
view: {
|
||||
icon: 'clock',
|
||||
label: 'visualeditor-dialog-media-info-uploaded',
|
||||
labelMsg: 'visualeditor-dialog-media-info-uploaded',
|
||||
isDate: true
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'DateTimeOriginal',
|
||||
value: ve.getProp( metadata, 'DateTimeOriginal', 'value' ),
|
||||
data: {},
|
||||
format: 'html-remove-formatting',
|
||||
view: {
|
||||
icon: 'clock',
|
||||
label: 'visualeditor-dialog-media-info-created'
|
||||
labelMsg: 'visualeditor-dialog-media-info-created'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'moreinfo',
|
||||
value: ve.msg( 'visualeditor-dialog-media-info-moreinfo' ),
|
||||
data: {},
|
||||
format: 'plaintext',
|
||||
view: {
|
||||
icon: 'info',
|
||||
href: imageinfo.descriptionurl
|
||||
|
@ -609,14 +607,17 @@ ve.ui.MWMediaDialog.prototype.buildMediaInfoPanel = function ( imageinfo ) {
|
|||
// Clean data from the API responses
|
||||
for ( i = 0; i < apiDataKeysConfig.length; i++ ) {
|
||||
field = apiDataKeysConfig[ i ].name;
|
||||
// Skip empty fields and those that are specifically configured to be skipped
|
||||
if ( apiDataKeysConfig[ i ].data.skipProcessing ) {
|
||||
if ( apiDataKeysConfig[ i ].format === 'html' ) {
|
||||
apiData[ field ] = new OO.ui.HtmlSnippet( apiDataKeysConfig[ i ].value );
|
||||
|
||||
} else if ( apiDataKeysConfig[ i ].format === 'html-remove-formatting' ) {
|
||||
apiData[ field ] = this.cleanAPIresponse( apiDataKeysConfig[ i ].value );
|
||||
|
||||
} else if ( apiDataKeysConfig[ i ].format === 'plaintext' ) {
|
||||
apiData[ field ] = apiDataKeysConfig[ i ].value;
|
||||
|
||||
} else {
|
||||
// Store a clean information from the API.
|
||||
if ( apiDataKeysConfig[ i ].value ) {
|
||||
apiData[ field ] = this.cleanAPIresponse( apiDataKeysConfig[ i ].value, apiDataKeysConfig[ i ].data );
|
||||
}
|
||||
throw new Error( 'Unexpected metadata field format' );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -624,7 +625,7 @@ ve.ui.MWMediaDialog.prototype.buildMediaInfoPanel = function ( imageinfo ) {
|
|||
if ( imageinfo.mediatype === 'AUDIO' ) {
|
||||
// Label this file as an audio
|
||||
apiData.$fileDetails = $( '<span>' )
|
||||
.append( ve.msg( 'visualeditor-dialog-media-info-audiofile' ) );
|
||||
.text( ve.msg( 'visualeditor-dialog-media-info-audiofile' ) );
|
||||
} else {
|
||||
// Build the display for image size and type
|
||||
apiData.$fileDetails = $( '<div>' )
|
||||
|
@ -639,7 +640,7 @@ ve.ui.MWMediaDialog.prototype.buildMediaInfoPanel = function ( imageinfo ) {
|
|||
),
|
||||
$( '<span>' )
|
||||
.addClass( 've-ui-mwMediaDialog-panel-imageinfo-separator' )
|
||||
.text( mw.msg( 'visualeditor-dialog-media-info-separator' ) ),
|
||||
.text( ve.msg( 'visualeditor-dialog-media-info-separator' ) ),
|
||||
$( '<span>' ).text( fileType )
|
||||
);
|
||||
}
|
||||
|
@ -768,29 +769,20 @@ ve.ui.MWMediaDialog.prototype.fetchThumbnail = function ( imageName, dimensions
|
|||
/**
|
||||
* Clean the API responses and return it in plaintext. If needed, truncate.
|
||||
*
|
||||
* @param {string} rawResponse Raw response from the API
|
||||
* @param {Object} config Configuration options
|
||||
* @param {string} html Raw response from the API
|
||||
* @return {string} Plaintext clean response
|
||||
*/
|
||||
ve.ui.MWMediaDialog.prototype.cleanAPIresponse = function ( rawResponse, config ) {
|
||||
var isTruncated, charLimit,
|
||||
html = $.parseHTML( rawResponse ),
|
||||
ellipsis = ve.msg( 'visualeditor-dialog-media-info-ellipsis' ),
|
||||
originalText = $( '<div>' ).append( html ).text();
|
||||
|
||||
config = config || {};
|
||||
|
||||
charLimit = config.charLimit || 50;
|
||||
isTruncated = originalText.length > charLimit;
|
||||
|
||||
if ( config.keepOriginal ) {
|
||||
return html;
|
||||
}
|
||||
ve.ui.MWMediaDialog.prototype.cleanAPIresponse = function ( html ) {
|
||||
var text = $( $.parseHTML( html ) ).text();
|
||||
|
||||
// Check if the string should be truncated
|
||||
return mw.html.escape( isTruncated && !config.ignoreCharLimit ?
|
||||
originalText.slice( 0, charLimit ) + ellipsis :
|
||||
originalText );
|
||||
var charLimit = 50;
|
||||
if ( text.length > charLimit ) {
|
||||
var ellipsis = ve.msg( 'visualeditor-dialog-media-info-ellipsis' );
|
||||
text = text.slice( 0, charLimit ) + ellipsis;
|
||||
}
|
||||
|
||||
return text;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,10 +16,10 @@
|
|||
* @mixins OO.ui.mixin.TitledElement
|
||||
*
|
||||
* @constructor
|
||||
* @param {Object} content API response data from which to build the display
|
||||
* @param {jQuery|string|OO.ui.HtmlSnippet} content API response data from which to build the display
|
||||
* @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 {string} [labelMsg] A ve.msg() label string for the field.
|
||||
* @cfg {boolean} [isDate=false] Field text is a date that will be converted to 'fromNow' string.
|
||||
* @cfg {string} [type='attribute'] Field type, either 'description' or 'attribute'
|
||||
* @cfg {string} [descriptionHeight='4em'] Height limit for description fields
|
||||
|
@ -39,38 +39,44 @@ ve.ui.MWMediaInfoFieldWidget = function VeUiMWMediaInfoFieldWidget( content, con
|
|||
|
||||
this.$text = $( '<div>' )
|
||||
.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 ( typeof content === 'string' ) {
|
||||
if ( config.isDate && ( datetime = moment( content ) ).isValid() ) {
|
||||
content = datetime.fromNow();
|
||||
}
|
||||
|
||||
if ( config.labelMsg ) {
|
||||
// Messages defined in ve.ui.MWMediaDialog#buildMediaInfoPanel
|
||||
// eslint-disable-next-line mediawiki/msg-doc
|
||||
content = ve.msg( config.labelMsg, content );
|
||||
}
|
||||
|
||||
if ( config.href ) {
|
||||
// This variable may contain either jQuery objects or strings
|
||||
// eslint-disable-next-line no-jquery/variable-pattern
|
||||
content = $( '<a>' )
|
||||
.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
|
||||
)
|
||||
.text( content );
|
||||
}
|
||||
}
|
||||
|
||||
if ( config.label ) {
|
||||
// Messages defined in ve.ui.MWMediaDialog#buildMediaInfoPanel
|
||||
// eslint-disable-next-line mediawiki/msg-doc
|
||||
content = ve.msg( config.label, content );
|
||||
}
|
||||
|
||||
if ( config.href ) {
|
||||
this.$text
|
||||
.append(
|
||||
$( '<a>' )
|
||||
.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 )
|
||||
);
|
||||
} else {
|
||||
if ( typeof content === 'string' ) {
|
||||
this.$text.text( content );
|
||||
} else if ( content instanceof OO.ui.HtmlSnippet ) {
|
||||
this.$text.html( content.toString() );
|
||||
} else if ( content instanceof $ ) {
|
||||
this.$text.append( content );
|
||||
} else {
|
||||
throw new Error( 'Unexpected metadata field content' );
|
||||
}
|
||||
|
||||
this.$element
|
||||
|
|
Loading…
Reference in a new issue