/*!
* VisualEditor DataModel ImageNode class.
*
* @copyright See AUTHORS.txt
*/
/**
* DataModel image node.
*
* @class
* @abstract
* @mixes ve.dm.FocusableNode
* @mixes ve.dm.ResizableNode
*
* @constructor
*/
ve.dm.ImageNode = function VeDmImageNode() {
// Mixin constructors
ve.dm.FocusableNode.call( this );
ve.dm.ResizableNode.call( this );
};
/* Inheritance */
OO.mixinClass( ve.dm.ImageNode, ve.dm.FocusableNode );
OO.mixinClass( ve.dm.ImageNode, ve.dm.ResizableNode );
/* Static Methods */
// eslint-disable-next-line jsdoc/require-param, jsdoc/require-returns
/**
* @see ve.dm.Model
*/
ve.dm.ImageNode.static.isDiffComparable = function ( element, other ) {
// Images with different src's shouldn't be diffed
return element.type === other.type && element.attributes.src === other.attributes.src;
};
// eslint-disable-next-line jsdoc/require-param, jsdoc/require-returns
/**
* @see ve.dm.Model
*/
ve.dm.ImageNode.static.describeChanges = function ( attributeChanges, attributes ) {
const customKeys = [ 'width', 'height' ],
descriptions = [];
function describeSize( width, height ) {
return width + ve.msg( 'visualeditor-dimensionswidget-times' ) + height + ve.msg( 'visualeditor-dimensionswidget-px' );
}
if ( 'width' in attributeChanges || 'height' in attributeChanges ) {
const sizeFrom = describeSize(
'width' in attributeChanges ? attributeChanges.width.from : attributes.width,
'height' in attributeChanges ? attributeChanges.height.from : attributes.height
);
const sizeTo = describeSize(
'width' in attributeChanges ? attributeChanges.width.to : attributes.width,
'height' in attributeChanges ? attributeChanges.height.to : attributes.height
);
descriptions.push( ve.htmlMsg( 'visualeditor-changedesc-image-size', this.wrapText( 'del', sizeFrom ), this.wrapText( 'ins', sizeTo ) ) );
}
for ( const key in attributeChanges ) {
if ( customKeys.indexOf( key ) === -1 ) {
const change = this.describeChange( key, attributeChanges[ key ] );
if ( change ) {
descriptions.push( change );
}
}
}
return descriptions;
};
// eslint-disable-next-line jsdoc/require-param, jsdoc/require-returns
/**
* @see ve.dm.Node
*/
ve.dm.ImageNode.static.describeChange = function ( key, change ) {
switch ( key ) {
case 'align':
// The following messages are used here:
// * visualeditor-align-desc-left
// * visualeditor-align-desc-right
// * visualeditor-align-desc-center
// Also used in ve-mw (consider downstreaming these messages)
// * visualeditor-align-desc-default
// * visualeditor-align-desc-none
return ve.htmlMsg( 'visualeditor-changedesc-align',
this.wrapText( 'del', ve.msg( 'visualeditor-align-desc-' + change.from ) ),
this.wrapText( 'ins', ve.msg( 'visualeditor-align-desc-' + change.to ) )
);
// ClassAttributeNode attributes
case 'originalClasses':
case 'unrecognizedClasses':
return;
}
// Parent method
return ve.dm.Node.static.describeChange.apply( this, arguments );
};
/* Methods */
/**
* @inheritdoc
*/
ve.dm.ImageNode.prototype.createScalable = function () {
return new ve.dm.Scalable( {
currentDimensions: {
width: this.getAttribute( 'width' ),
height: this.getAttribute( 'height' )
},
minDimensions: {
width: 1,
height: 1
}
} );
};