diff --git a/modules/ve-mw/dm/nodes/ve.dm.MWBlockImageNode.js b/modules/ve-mw/dm/nodes/ve.dm.MWBlockImageNode.js index a5633ce787..d9fb6d957d 100644 --- a/modules/ve-mw/dm/nodes/ve.dm.MWBlockImageNode.js +++ b/modules/ve-mw/dm/nodes/ve.dm.MWBlockImageNode.js @@ -62,11 +62,14 @@ ve.dm.MWBlockImageNode.static.toDataElement = function ( domElements, converter type: this.rdfaToType[typeofAttr], href: $imgWrapper.attr( 'href' ) || '', src: $img.attr( 'src' ), - width: $img.attr( 'width' ), - height: $img.attr( 'height' ), resource: $img.attr( 'resource' ), originalClasses: classes - }; + }, + width = $img.attr( 'width' ), + height = $img.attr( 'height' ); + + attributes.width = width !== undefined && width !== '' ? Number( width ) : null; + attributes.height = height !== undefined && height !== '' ? Number( height ) : null; // Extract individual classes classes = typeof classes === 'string' ? classes.trim().split( /\s+/ ) : []; diff --git a/modules/ve-mw/test/ce/ve.ce.Document.test.js b/modules/ve-mw/test/ce/ve.ce.Document.test.js index 3c78895e9f..e81a0f30fc 100644 --- a/modules/ve-mw/test/ce/ve.ce.Document.test.js +++ b/modules/ve-mw/test/ce/ve.ce.Document.test.js @@ -12,198 +12,200 @@ QUnit.module( 've.ce.Document' ); // FIXME runner copypasted from core, use data provider QUnit.test( 'getRelativeRange (mwBlockImage / mwInlineImage)', function ( assert ) { var documentModel, documentView, i, j, expectCount = 0, + store = new ve.dm.IndexValueStore(), tests = [ - { - data: [ - /* 0 */ { type: 'mwBlockImage' }, - /* 1 */ { type: '/mwBlockImage' } - ], - cases: [ - { - direction: 1, - expand: false, - given: new ve.Range( 0 ), - expected: new ve.Range( 0, 2 ) - }, - { - direction: 1, - expand: false, - given: new ve.Range( 0, 2 ), - expected: new ve.Range( 2 ) - }, - { - direction: 1, - expand: true, - given: new ve.Range( 0 ), - expected: new ve.Range( 0, 2 ) - }, - { - direction: 1, - expand: true, - given: new ve.Range( 0, 2 ), - expected: new ve.Range( 0, 2 ) - }, - { - direction: -1, - expand: false, - given: new ve.Range( 2 ), - expected: new ve.Range( 2, 0 ) - }, - { - direction: -1, - expand: false, - given: new ve.Range( 2, 0 ), - expected: new ve.Range( 0 ) - }, - { - direction: -1, - expand: false, - given: new ve.Range( 0, 2 ), - expected: new ve.Range( 0 ) - }, - { - direction: -1, - expand: true, - given: new ve.Range( 2 ), - expected: new ve.Range( 2, 0 ) - }, - { - direction: -1, - expand: true, - given: new ve.Range( 2, 0 ), - expected: new ve.Range( 2, 0 ) - }, - { - direction: -1, - expand: true, - given: new ve.Range( 0, 2 ), - expected: new ve.Range( 0 ) - } - ] - }, - { - data: [ - /* 0 */ { type: 'mwBlockImage' }, - /* 1 */ { type: '/mwBlockImage' }, - /* 2 */ { type: 'mwBlockImage' }, - /* 3 */ { type: '/mwBlockImage' } - ], - cases: [ - { - direction: 1, - expand: false, - given: new ve.Range( 0, 2 ), - expected: new ve.Range( 2 ) - }, - { - direction: 1, - expand: false, - given: new ve.Range( 2, 4 ), - expected: new ve.Range( 4 ) - }, - { - direction: 1, - expand: true, - given: new ve.Range( 0, 2 ), - expected: new ve.Range( 0, 4 ) - }, - { - direction: -1, - expand: true, - given: new ve.Range( 4, 2 ), - expected: new ve.Range( 4, 0 ) - }, - { - direction: -1, - expand: true, - given: new ve.Range( 2, 4 ), - expected: new ve.Range( 2 ) - } - ] - }, - { - data: [ - /* 0 */ { type: 'alienBlock' }, - /* 1 */ { type: '/alienBlock' }, - /* 2 */ { type: 'mwBlockImage' }, - /* 3 */ { type: '/mwBlockImage' }, - /* 4 */ { type: 'alienBlock' }, - /* 5 */ { type: '/alienBlock' } - ], - cases: [ - { - direction: 1, - expand: false, - given: new ve.Range( 0 ), - expected: new ve.Range( 2 ) - }, - { - direction: 1, - expand: false, - given: new ve.Range( 2 ), - expected: new ve.Range( 2, 4 ) - }, - { - direction: 1, - expand: false, - given: new ve.Range( 2, 4 ), - expected: new ve.Range( 4 ) - }, - { - direction: 1, - expand: false, - given: new ve.Range( 4 ), - expected: new ve.Range( 6 ) - }, - { - direction: 1, - expand: true, - given: new ve.Range( 0 ), - expected: new ve.Range( 0, 2 ) - }, - { - direction: 1, - expand: true, - given: new ve.Range( 0, 2 ), - expected: new ve.Range( 0, 4 ) - }, - { - direction: 1, - expand: true, - given: new ve.Range( 0, 4 ), - expected: new ve.Range( 0, 6 ) - } - ] - }, - { - data: [ - /* 0 */ { type: 'paragraph' }, - /* 1 */ { type: 'alienInline' }, - /* 2 */ { type: '/alienInline' }, - /* 3 */ { type: 'mwInlineImage' }, - /* 4 */ { type: '/mwInlineImage' }, - /* 5 */ { type: 'alienInline' }, - /* 6 */ { type: '/alienInline' }, - /* 7 */ { type: '/paragraph' } - ], - cases: [ - { - direction: 1, - expand: false, - given: new ve.Range( 1 ), - expected: new ve.Range( 3 ) - }, - { - direction: 1, - expand: false, - given: new ve.Range( 5 ), - expected: new ve.Range( 7 ) - } - ] - } - ]; + { + data: [ + /* 0 */ ve.copy( ve.dm.mwExample.MWBlockImage.data[0] ), + /* 1 */ { type: '/mwBlockImage' } + ], + cases: [ + { + direction: 1, + expand: false, + given: new ve.Range( 0 ), + expected: new ve.Range( 0, 2 ) + }, + { + direction: 1, + expand: false, + given: new ve.Range( 0, 2 ), + expected: new ve.Range( 2 ) + }, + { + direction: 1, + expand: true, + given: new ve.Range( 0 ), + expected: new ve.Range( 0, 2 ) + }, + { + direction: 1, + expand: true, + given: new ve.Range( 0, 2 ), + expected: new ve.Range( 0, 2 ) + }, + { + direction: -1, + expand: false, + given: new ve.Range( 2 ), + expected: new ve.Range( 2, 0 ) + }, + { + direction: -1, + expand: false, + given: new ve.Range( 2, 0 ), + expected: new ve.Range( 0 ) + }, + { + direction: -1, + expand: false, + given: new ve.Range( 0, 2 ), + expected: new ve.Range( 0 ) + }, + { + direction: -1, + expand: true, + given: new ve.Range( 2 ), + expected: new ve.Range( 2, 0 ) + }, + { + direction: -1, + expand: true, + given: new ve.Range( 2, 0 ), + expected: new ve.Range( 2, 0 ) + }, + { + direction: -1, + expand: true, + given: new ve.Range( 0, 2 ), + expected: new ve.Range( 0 ) + } + ] + }, + { + data: [ + /* 0 */ ve.copy( ve.dm.mwExample.MWBlockImage.data[0] ), + /* 1 */ { type: '/mwBlockImage' }, + /* 2 */ ve.copy( ve.dm.mwExample.MWBlockImage.data[0] ), + /* 3 */ { type: '/mwBlockImage' } + ], + cases: [ + { + direction: 1, + expand: false, + given: new ve.Range( 0, 2 ), + expected: new ve.Range( 2 ) + }, + { + direction: 1, + expand: false, + given: new ve.Range( 2, 4 ), + expected: new ve.Range( 4 ) + }, + { + direction: 1, + expand: true, + given: new ve.Range( 0, 2 ), + expected: new ve.Range( 0, 4 ) + }, + { + direction: -1, + expand: true, + given: new ve.Range( 4, 2 ), + expected: new ve.Range( 4, 0 ) + }, + { + direction: -1, + expand: true, + given: new ve.Range( 2, 4 ), + expected: new ve.Range( 2 ) + } + ] + }, + { + data: [ + /* 0 */ { type: 'alienBlock' }, + /* 1 */ { type: '/alienBlock' }, + /* 2 */ ve.copy( ve.dm.mwExample.MWBlockImage.data[0] ), + /* 3 */ { type: '/mwBlockImage' }, + /* 4 */ { type: 'alienBlock' }, + /* 5 */ { type: '/alienBlock' } + ], + cases: [ + { + direction: 1, + expand: false, + given: new ve.Range( 0 ), + expected: new ve.Range( 2 ) + }, + { + direction: 1, + expand: false, + given: new ve.Range( 2 ), + expected: new ve.Range( 2, 4 ) + }, + { + direction: 1, + expand: false, + given: new ve.Range( 2, 4 ), + expected: new ve.Range( 4 ) + }, + { + direction: 1, + expand: false, + given: new ve.Range( 4 ), + expected: new ve.Range( 6 ) + }, + { + direction: 1, + expand: true, + given: new ve.Range( 0 ), + expected: new ve.Range( 0, 2 ) + }, + { + direction: 1, + expand: true, + given: new ve.Range( 0, 2 ), + expected: new ve.Range( 0, 4 ) + }, + { + direction: 1, + expand: true, + given: new ve.Range( 0, 4 ), + expected: new ve.Range( 0, 6 ) + } + ] + }, + { + data: [ + /* 0 */ { type: 'paragraph' }, + /* 1 */ { type: 'alienInline' }, + /* 2 */ { type: '/alienInline' }, + /* 3 */ ve.copy( ve.dm.mwExample.MWInlineImage.data ), + /* 4 */ { type: '/mwInlineImage' }, + /* 5 */ { type: 'alienInline' }, + /* 6 */ { type: '/alienInline' }, + /* 7 */ { type: '/paragraph' } + ], + cases: [ + { + direction: 1, + expand: false, + given: new ve.Range( 1 ), + expected: new ve.Range( 3 ) + }, + { + direction: 1, + expand: false, + given: new ve.Range( 5 ), + expected: new ve.Range( 7 ) + } + ] + } + ]; + for ( i = 0; i < tests.length; i++ ) { - documentModel = new ve.dm.Document( tests[i].data ); + documentModel = new ve.dm.Document( new ve.dm.ElementLinearData( store, tests[i].data ) ); documentView = new ve.ce.Document( documentModel ); for ( j = 0; j < tests[i].cases.length; j++ ) { expectCount++; diff --git a/modules/ve-mw/test/dm/ve.dm.mwExample.js b/modules/ve-mw/test/dm/ve.dm.mwExample.js index fc6939adf8..cfd75e4190 100644 --- a/modules/ve-mw/test/dm/ve.dm.mwExample.js +++ b/modules/ve-mw/test/dm/ve.dm.mwExample.js @@ -16,7 +16,6 @@ ve.dm.mwExample.createExampleDocument = function ( name, store ) { return ve.dm.example.createExampleDocumentFromObject( name, store, ve.dm.mwExample ); }; -ve.dm.mwExample.MWInlineImageHtml = ''; ve.dm.mwExample.MWTransclusion = { 'blockOpen': '
', 'blockOpenModified': '
', @@ -140,8 +139,8 @@ ve.dm.mwExample.MWBlockImage = { 'align': 'right', 'href': 'Foo', 'src': 'Bar', - 'width': '1', - 'height': '2', + 'width': 1, + 'height': 2, 'resource': 'FooBar', 'originalClasses': 'mw-halign-right foobar', 'unrecognizedClasses': ['foobar'] @@ -156,6 +155,29 @@ ve.dm.mwExample.MWBlockImage = { ] }; +ve.dm.mwExample.MWInlineImage = { + 'html': + '' + + '' + + '' + + '' + + '', + 'data': { + 'type': 'mwInlineImage', + 'attributes': { + 'src': 'http://upload.wikimedia.org/wikipedia/en/b/bc/Wiki.png', + 'href': './File:Wiki.png', + 'width': 135, + 'height': 155, + 'isLinked': true, + 'valign': 'text-top', + 'resource': './File:Wiki.png', + 'type': 'inline', + 'originalClasses': 'foo mw-valign-text-top', + 'unrecognizedClasses': ['foo'] + }, + } +}; ve.dm.mwExample.MWReference = { 'referenceList': @@ -740,45 +762,10 @@ ve.dm.mwExample.domToDataCases = { '' }, 'mw:Image': { - 'html': '

' + ve.dm.mwExample.MWInlineImageHtml + '

', + 'html': '

' + ve.dm.mwExample.MWInlineImage.html + '

', 'data': [ { 'type': 'paragraph' }, - { - 'type': 'mwInlineImage', - 'attributes': { - 'src': 'http://upload.wikimedia.org/wikipedia/en/b/bc/Wiki.png', - 'href': './File:Wiki.png', - 'width': 135, - 'height': 155, - 'isLinked': true, - 'valign': 'text-top', - 'resource': './File:Wiki.png', - 'type': 'inline', - 'originalClasses': 'foo mw-valign-text-top', - 'unrecognizedClasses': ['foo'] - }, - 'htmlAttributes': [ - { - 'values': { - 'data-parsoid': '{\"tsr\":[0,24],\"optList\":[{\"ck\":\"width\",\"ak\":\"500px\"}],\"cacheKey\":\"[[Image:Wiki.png|500px]]\",\"img\":{\"h\":155,\"w\":135,\"wdset\":true},\"dsr\":[0,24,null,null]}' - }, - 'children': [ - { - 'values': { - 'data-parsoid': '{\"a\":{\"href\":\"./File:Wiki.png\"}}' - }, - 'children': [ - { - 'values': { - 'data-parsoid': '{\"a\":{\"resource\":\"./File:Wiki.png\",\"width\":\"135\"},\"sa\":{\"resource\":\"Image:Wiki.png\",\"width\":\"500\"}}' - } - } - ] - } - ] - } - ] - }, + ve.dm.mwExample.MWInlineImage.data, { 'type': '/mwInlineImage' }, { 'type': '/paragraph' }, { 'type': 'internalList' }, @@ -1670,8 +1657,8 @@ ve.dm.mwExample.domToDataCases = { 'align': 'default', 'href': 'Foo', 'src': 'Bar', - 'width': '1', - 'height': '2', + 'width': 1, + 'height': 2, 'resource': 'FooBar', 'originalClasses': undefined, 'unrecognizedClasses': []