Better support for MediaWiki block level images (thumb and frame)

Change-Id: Id6f65e4e1971e21035c89f32fa7ab0009c84695c
This commit is contained in:
Inez Korczyński 2013-05-14 16:39:13 -07:00
parent ea6e1b26ed
commit c6c7af5a62
2 changed files with 108 additions and 27 deletions

View file

@ -18,13 +18,30 @@ ve.ce.MWBlockImageNode = function VeCeMWBlockImageNode( model, config ) {
// Parent constructor
ve.ce.BranchNode.call( this, model, config );
// Properties
this.$image = $( '<img>' ).attr( 'src', this.model.getAttribute( 'src' ) );
if ( this.model.getAttribute( 'align' ) === 'center' ) {
this.$.addClass( 'center' );
this.$thumb = this.$$( '<div>' ).appendTo( this.$ );
} else {
this.$thumb = this.$;
}
// Initialization
// At this moment this.$ has children added to it (thanks to ve.ce.BranchNode.onSplice).
// In this particular case there is only one child - <figcaption>
this.$image.prependTo( this.$ );
this.$thumb
.addClass( 'thumb' )
.addClass(
ve.ce.MWBlockImageNode.static.alignToCssClass[ this.model.getAttribute( 'align' ) ]
);
this.$thumbInner = this.$$( '<div>' )
.addClass( 'thumbinner' )
.css( 'width', parseInt( this.model.getAttribute( 'width' ), 10 ) + 2 )
.appendTo( this.$thumb );
this.$image = this.$$( '<img>' )
.addClass( 'thumbimage' )
.attr( 'src', this.model.getAttribute( 'src' ) )
.attr( 'width', this.model.getAttribute( 'width' ) )
.attr( 'height', this.model.getAttribute( 'height' ) )
.appendTo( this.$thumbInner );
};
/* Inheritance */
@ -35,12 +52,48 @@ ve.inheritClass( ve.ce.MWBlockImageNode, ve.ce.BranchNode );
ve.ce.MWBlockImageNode.static.name = 'MWblockimage';
ve.ce.MWBlockImageNode.static.tagName = 'figure';
ve.ce.MWBlockImageNode.static.tagName = 'div';
ve.ce.MWBlockImageNode.static.renderHtmlAttributes = false;
ve.ce.MWBlockImageNode.static.alignToCssClass = {
'left': 'tleft',
'right': 'tright',
'center' : 'tnone',
'none' : 'tnone'
};
/* Methods */
ve.ce.MWBlockImageNode.prototype.onAttributeChange = function ( key, from, to ) {
var $element;
if ( key === 'align' && from !== to ) {
if ( to === 'center' || from === 'center' ) {
this.emit( 'teardown' );
if ( to === 'center' ) {
$element = this.$$( '<div>' ).addClass( 'center' );
this.$thumb = this.$;
this.$.replaceWith( $element );
this.$ = $element;
this.$.append( this.$thumb );
} else {
this.$.replaceWith( this.$thumb );
this.$ = this.$thumb;
}
this.emit( 'setup' );
}
this.$thumb.removeClass( ve.ce.MWBlockImageNode.static.alignToCssClass[ from ] );
this.$thumb.addClass( ve.ce.MWBlockImageNode.static.alignToCssClass[ to ] );
}
};
ve.ce.MWBlockImageNode.prototype.setupSlugs = function () {
// Intentionally empty - as we don't want/need slugs inside figure tag
// Intentionally empty
};
ve.ce.MWBlockImageNode.prototype.onSplice = function () {
// Intentionally empty
};
/* Registration */

View file

@ -30,31 +30,59 @@ ve.dm.MWBlockImageNode.static.handlesOwnChildren = true;
ve.dm.MWBlockImageNode.static.childNodeTypes = [ 'MWimagecaption' ];
ve.dm.MWBlockImageNode.static.matchRdfaTypes = [ 'mw:Image/Thumb' ];
// Match typeof="mw:Image/Thumb" and typeof="mw:Image/Frame"
ve.dm.MWBlockImageNode.static.matchRdfaTypes = [ /mw:Image\/(Thumb|Frame)/ ];
ve.dm.MWBlockImageNode.static.toDataElement = function ( domElements, converter ) {
var $figure = $( domElements[0] ),
$a = $figure.children( 'a' ).eq( 0 ),
$img = $a.children( 'img' ).eq( 0 ),
$caption = $figure.children( 'figcaption' ).eq( 0 ),
href = $a.attr( 'href' ),
src = $img.attr( 'src' ),
width = $img.attr( 'width' ),
height = $img.attr( 'height' ),
resource = $img.attr( 'resource' ),
captionData = converter.getDataFromDomRecursion( $caption[0], { 'type': 'MWimagecaption' } );
return [
{
'type': 'MWblockimage',
'attributes': {
'href': href,
'src': src,
'width': width,
'height': height,
'resource': resource
}
}
].concat( captionData ).concat( [ { 'type': '/MWblockimage' } ] );
typeofAttr = $figure.attr( 'typeof' ),
classes = $figure.attr( 'class' ).replace( /\s{2,}/g, ' ' ).split( ' ' ),
attributes = {
href: $a.attr( 'href' ),
src: $img.attr( 'src' ),
width: $img.attr( 'width' ),
height: $img.attr( 'height' ),
resource: $img.attr( 'resource' )
};
// Type
switch ( typeofAttr ) {
case 'mw:Image/Thumb':
attributes.type = 'thumb';
break;
case 'mw:Image/Frame':
attributes.type = 'frame';
break;
}
// Horizontal alignment
if ( classes.indexOf( 'mw-halign-left' ) !== -1 ) {
attributes.align = 'left';
} else if ( classes.indexOf( 'mw-halign-right' ) !== -1 ) {
attributes.align = 'right';
} else if ( classes.indexOf( 'mw-halign-center' ) !== -1 ) {
attributes.align = 'center';
} else if ( classes.indexOf( 'mw-halign-none' ) !== -1 ) {
attributes.align = 'none';
} else {
attributes.align = 'right';
}
// Default-size
if ( $figure.hasClass( 'mw-default-size' ) ) {
attributes.defaultSize = true;
}
if ( $caption.length === 0 ) {
return { 'type': 'MWblockimage', 'attributes': attributes };
} else {
return [ { 'type': 'MWblockimage', 'attributes': attributes } ].
concat( converter.getDataFromDomRecursionClean( $caption[0], { 'type': 'MWimagecaption' } ) ).
concat( [ { 'type': '/MWblockimage' } ] );
}
};
ve.dm.MWBlockImageNode.static.toDomElements = function ( data, doc, converter ) {