From c6c7af5a628096f4ba8dee15814805e040ea7870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Inez=20Korczyn=CC=81ski?= Date: Tue, 14 May 2013 16:39:13 -0700 Subject: [PATCH] Better support for MediaWiki block level images (thumb and frame) Change-Id: Id6f65e4e1971e21035c89f32fa7ab0009c84695c --- modules/ve/ce/nodes/ve.ce.MWBlockImageNode.js | 69 ++++++++++++++++--- modules/ve/dm/nodes/ve.dm.MWBlockImageNode.js | 66 +++++++++++++----- 2 files changed, 108 insertions(+), 27 deletions(-) diff --git a/modules/ve/ce/nodes/ve.ce.MWBlockImageNode.js b/modules/ve/ce/nodes/ve.ce.MWBlockImageNode.js index 072138d03c..f7ad5f4d0d 100644 --- a/modules/ve/ce/nodes/ve.ce.MWBlockImageNode.js +++ b/modules/ve/ce/nodes/ve.ce.MWBlockImageNode.js @@ -18,13 +18,30 @@ ve.ce.MWBlockImageNode = function VeCeMWBlockImageNode( model, config ) { // Parent constructor ve.ce.BranchNode.call( this, model, config ); - // Properties - this.$image = $( '' ).attr( 'src', this.model.getAttribute( 'src' ) ); + if ( this.model.getAttribute( 'align' ) === 'center' ) { + this.$.addClass( 'center' ); + this.$thumb = this.$$( '
' ).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 -
- this.$image.prependTo( this.$ ); + this.$thumb + .addClass( 'thumb' ) + .addClass( + ve.ce.MWBlockImageNode.static.alignToCssClass[ this.model.getAttribute( 'align' ) ] + ); + + this.$thumbInner = this.$$( '
' ) + .addClass( 'thumbinner' ) + .css( 'width', parseInt( this.model.getAttribute( 'width' ), 10 ) + 2 ) + .appendTo( this.$thumb ); + + this.$image = this.$$( '' ) + .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.$$( '
' ).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 */ diff --git a/modules/ve/dm/nodes/ve.dm.MWBlockImageNode.js b/modules/ve/dm/nodes/ve.dm.MWBlockImageNode.js index d3d8a42c65..05b6d439a6 100644 --- a/modules/ve/dm/nodes/ve.dm.MWBlockImageNode.js +++ b/modules/ve/dm/nodes/ve.dm.MWBlockImageNode.js @@ -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 ) {