mediawiki-extensions-Visual.../modules/ve-mw/dm/nodes/ve.dm.MWInlineImageNode.js
suchetag dc2247460c Representation for the red-linked inline images in VE
The red-linked inline images in VE are now identifited as red links and image errors.
They can be changed and thereby be modified just as any other inline image on the editor.

Change-Id: Idb6f6f2da14379fd7db6ca19613dad32fe40023d
2015-05-25 15:18:15 +01:00

215 lines
6.2 KiB
JavaScript

/*!
* VisualEditor DataModel MWInlineImage class.
*
* @copyright 2011-2015 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
/**
* DataModel MediaWiki image node.
*
* @class
* @extends ve.dm.LeafNode
* @mixins ve.dm.MWImageNode
*
* @constructor
* @param {Object} [element] Reference to element in linear model
*/
ve.dm.MWInlineImageNode = function VeDmMWInlineImageNode() {
// Parent constructor
ve.dm.LeafNode.apply( this, arguments );
// Mixin constructors
ve.dm.MWImageNode.call( this );
};
/* Inheritance */
OO.inheritClass( ve.dm.MWInlineImageNode, ve.dm.LeafNode );
// Need to mixin base class as well
OO.mixinClass( ve.dm.MWInlineImageNode, ve.dm.GeneratedContentNode );
OO.mixinClass( ve.dm.MWInlineImageNode, ve.dm.MWImageNode );
/* Static Properties */
ve.dm.MWInlineImageNode.static.rdfaToType = {
'mw:Image': 'none',
'mw:Image/Frameless': 'frameless'
};
ve.dm.MWInlineImageNode.static.isContent = true;
ve.dm.MWInlineImageNode.static.name = 'mwInlineImage';
ve.dm.MWInlineImageNode.static.preserveHtmlAttributes = function ( attribute ) {
var attributes = [ 'typeof', 'class', 'src', 'resource', 'width', 'height', 'href' ];
return attributes.indexOf( attribute ) === -1;
};
ve.dm.MWInlineImageNode.static.matchTagNames = [ 'span' ];
ve.dm.MWInlineImageNode.static.blacklistedAnnotationTypes = [ 'link' ];
ve.dm.MWInlineImageNode.static.getMatchRdfaTypes = function () {
return Object.keys( this.rdfaToType );
};
ve.dm.MWInlineImageNode.static.allowedRdfaTypes = [ 'mw:Error' ];
ve.dm.MWInlineImageNode.static.toDataElement = function ( domElements, converter ) {
var dataElement, attributes,
$span = $( domElements[0] ),
$firstChild = $span.children().first(), // could be <span> or <a>
$img = $firstChild.children().first(),
typeofAttrs = $span.attr( 'typeof' ).split( ' ' ),
classes = $span.attr( 'class' ),
recognizedClasses = [],
errorIndex = typeofAttrs.indexOf( 'mw:Error' ),
width = $img.attr( 'width' ),
height = $img.attr( 'height' );
if ( errorIndex !== -1 ) {
typeofAttrs.splice( errorIndex, 1 );
}
attributes = {
type: this.rdfaToType[typeofAttrs[0]],
src: $img.attr( 'src' ),
resource: $img.attr( 'resource' ),
originalClasses: classes
};
if ( errorIndex !== -1 ) {
attributes.isError = true;
}
attributes.width = width !== undefined && width !== '' ? Number( width ) : null;
attributes.height = height !== undefined && height !== '' ? Number( height ) : null;
attributes.isLinked = $firstChild.is( 'a' );
if ( attributes.isLinked ) {
attributes.href = $firstChild.attr( 'href' );
}
// Extract individual classes
classes = typeof classes === 'string' ? classes.trim().split( /\s+/ ) : [];
// Deal with border flag
if ( classes.indexOf( 'mw-image-border' ) !== -1 ) {
attributes.borderImage = true;
recognizedClasses.push( 'mw-image-border' );
}
// Vertical alignment
if ( classes.indexOf( 'mw-valign-middle' ) !== -1 ) {
attributes.valign = 'middle';
recognizedClasses.push( 'mw-valign-middle' );
} else if ( classes.indexOf( 'mw-valign-baseline' ) !== -1 ) {
attributes.valign = 'baseline';
recognizedClasses.push( 'mw-valign-baseline' );
} else if ( classes.indexOf( 'mw-valign-sub' ) !== -1 ) {
attributes.valign = 'sub';
recognizedClasses.push( 'mw-valign-sub' );
} else if ( classes.indexOf( 'mw-valign-super' ) !== -1 ) {
attributes.valign = 'super';
recognizedClasses.push( 'mw-valign-super' );
} else if ( classes.indexOf( 'mw-valign-top' ) !== -1 ) {
attributes.valign = 'top';
recognizedClasses.push( 'mw-valign-top' );
} else if ( classes.indexOf( 'mw-valign-text-top' ) !== -1 ) {
attributes.valign = 'text-top';
recognizedClasses.push( 'mw-valign-text-top' );
} else if ( classes.indexOf( 'mw-valign-bottom' ) !== -1 ) {
attributes.valign = 'bottom';
recognizedClasses.push( 'mw-valign-bottom' );
} else if ( classes.indexOf( 'mw-valign-text-bottom' ) !== -1 ) {
attributes.valign = 'text-bottom';
recognizedClasses.push( 'mw-valign-text-bottom' );
} else {
attributes.valign = 'default';
}
// Border
if ( classes.indexOf( 'mw-image-border' ) !== -1 ) {
attributes.borderImage = true;
recognizedClasses.push( 'mw-image-border' );
}
// Default-size
if ( classes.indexOf( 'mw-default-size' ) !== -1 ) {
attributes.defaultSize = true;
recognizedClasses.push( 'mw-default-size' );
}
// Store unrecognized classes so we can restore them on the way out
attributes.unrecognizedClasses = OO.simpleArrayDifference( classes, recognizedClasses );
dataElement = { type: this.name, attributes: attributes };
this.storeGeneratedContents( dataElement, dataElement.attributes.src, converter.getStore() );
return dataElement;
};
ve.dm.MWInlineImageNode.static.toDomElements = function ( data, doc ) {
var firstChild,
span = doc.createElement( 'span' ),
img = doc.createElement( 'img' ),
classes = [],
originalClasses = data.attributes.originalClasses,
rdfa;
ve.setDomAttributes( img, data.attributes, [ 'src', 'width', 'height', 'resource' ] );
if ( !this.typeToRdfa ) {
this.typeToRdfa = {};
for ( rdfa in this.rdfaToType ) {
this.typeToRdfa[this.rdfaToType[rdfa]] = rdfa;
}
}
span.setAttribute( 'typeof', this.typeToRdfa[data.attributes.type] );
if ( data.attributes.defaultSize ) {
classes.push( 'mw-default-size' );
}
if ( data.attributes.borderImage ) {
classes.push( 'mw-image-border' );
}
if ( data.attributes.valign && data.attributes.valign !== 'default' ) {
classes.push( 'mw-valign-' + data.attributes.valign );
}
if ( data.attributes.unrecognizedClasses ) {
classes = OO.simpleArrayUnion( classes, data.attributes.unrecognizedClasses );
}
if (
originalClasses &&
ve.compare( originalClasses.trim().split( /\s+/ ).sort(), classes.sort() )
) {
span.className = originalClasses;
} else if ( classes.length > 0 ) {
span.className = classes.join( ' ' );
}
if ( data.attributes.isLinked ) {
firstChild = doc.createElement( 'a' );
firstChild.setAttribute( 'href', data.attributes.href );
} else {
firstChild = doc.createElement( 'span' );
}
span.appendChild( firstChild );
firstChild.appendChild( img );
return [ span ];
};
/* Registration */
ve.dm.modelRegistry.register( ve.dm.MWInlineImageNode );