jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/381960 )
Change subject: MWImage: Support Inline images with figure-inline tag ...................................................................... MWImage: Support Inline images with figure-inline tag Support translation of caption in data-mw if present and an MT Client is available for the language pair. Whitelist figure-inline in DOM sanitization. bin/adapt modifed to provide MT TestClient Change-Id: I8db09d11bb64701811720a45b526cc6395fbd84e --- M bin/adapt M lib/lineardoc/Parser.js M lib/mt/MTClient.js M lib/translationunits/MWImage.js M test/adaptation/AdaptationTests.json 5 files changed, 68 insertions(+), 20 deletions(-) Approvals: jenkins-bot: Verified Nikerabbit: Looks good to me, approved diff --git a/bin/adapt b/bin/adapt index 7e90699..4232801 100755 --- a/bin/adapt +++ b/bin/adapt @@ -2,6 +2,7 @@ const fs = require( 'fs' ), yaml = require( 'js-yaml' ), Adapter = require( __dirname + '/../lib/Adapter' ), + TestClient = require( __dirname + '/../lib/mt' ).TestClient, Normalizer = require( __dirname + '/../lib/lineardoc' ).Normalizer; let config = yaml.load( fs.readFileSync( 'config.yaml' ) ); @@ -36,6 +37,8 @@ } +cxConfig.conf.mtClient = new TestClient( cxConfig ); + let from = process.argv[ 2 ]; let to = process.argv[ 3 ]; let adapter = new Adapter( from, to, cxConfig ); diff --git a/lib/lineardoc/Parser.js b/lib/lineardoc/Parser.js index f34cdc6..d2410da 100644 --- a/lib/lineardoc/Parser.js +++ b/lib/lineardoc/Parser.js @@ -30,7 +30,7 @@ 'hr', 'button', 'canvas', 'center', 'col', 'colgroup', 'embed', 'map', 'object', 'pre', 'progress', 'video', // non-annotation inline tags - 'img', 'br' + 'img', 'br', 'figure-inline' ]; /** diff --git a/lib/mt/MTClient.js b/lib/mt/MTClient.js index c99874a..61fe613 100644 --- a/lib/mt/MTClient.js +++ b/lib/mt/MTClient.js @@ -111,10 +111,12 @@ throw new Error( 'DOMPurify not suppported in the DOM environment provided by JSDOM' ); } + const rdfaAttrs = [ 'about', 'rel', 'resource', 'property', 'content', 'datatype', 'typeof', 'srcset' ]; return this.DOMPurify.sanitize( html, { // These are not known attributes for DOMPurify - ADD_ATTR: [ 'typeof', 'resource', 'src', 'srcset' ], - ADD_URI_SAFE_ATTR: [ 'rel', 'typeof' ] // Without this rel="mw:WikiLink" attributes will be removed. + ADD_TAGS: [ 'figure-inline' ], + ADD_ATTR: rdfaAttrs, + ADD_URI_SAFE_ATTR: rdfaAttrs } ); } diff --git a/lib/translationunits/MWImage.js b/lib/translationunits/MWImage.js index d99903a..845940f 100644 --- a/lib/translationunits/MWImage.js +++ b/lib/translationunits/MWImage.js @@ -9,6 +9,9 @@ class MWImage extends TranslationUnit { constructor( node, sourceLanguage, targetLanguage, context ) { super( node, sourceLanguage, targetLanguage, context ); + this.imageSource = null; + this.sourceResource = null; + this.isInlineImage = node.name === 'figure-inline'; } /** @@ -52,10 +55,10 @@ } MWImage.prototype.adapt = cxutil.async( function* () { - var i, len, chunk, sourceImage, imageLink, targetResource, namespaceAlias; + let sourceImage, imageLink, dataCX = { adapted: false }; - for ( i = 0, len = this.node.children.textChunks.length; i < len; i++ ) { - chunk = this.node.children.textChunks[ i ]; + for ( let i = 0, len = this.node.children.textChunks.length; i < len; i++ ) { + let chunk = this.node.children.textChunks[ i ]; if ( chunk.tags[ 0 ] && chunk.tags[ 0 ].name === 'a' ) { imageLink = chunk.tags[ 0 ]; } @@ -72,23 +75,31 @@ this.sourceResource = sourceImage.attributes.resource; this.adaptImageAlignment(); - if ( this.isCommonsImage( sourceImage.attributes.src ) ) { - namespaceAlias = yield new MWApiRequestManager( this.context ).getNamespaceAlias( 'File', this.targetLanguage ); - targetResource = this.sourceResource.replace( /^(\.\.?\/)*([^:]+)(:)/, '$1' + namespaceAlias + '$3' ); - sourceImage.attributes.resource = imageLink.attributes.href = targetResource; - } else { - // TODO: This format is not decided yet. We do need to inform client about failed - // adaptations somehow. - this.node.attributes[ 'data-cx' ] = JSON.stringify( { - adapted: false, - imageSource: this.imageSource, - resource: this.sourceResource - } ); + dataCX.imageSource = sourceImage.attributes.src; + dataCX.resource = this.sourceResource; + + if ( this.isInlineImage && this.context.conf.mtClient && this.node.attributes[ 'data-mw' ] ) { + const caption = JSON.parse( this.node.attributes[ 'data-mw' ] ).caption; + const translatedCaption = yield this.context.conf.mtClient.translate( + this.sourceLanguage, this.targetLanguage, caption + ); + this.node.attributes[ 'data-mw' ] = JSON.stringify( { caption: translatedCaption } ); } + + if ( this.isCommonsImage( sourceImage.attributes.src ) ) { + let namespaceAlias = yield new MWApiRequestManager( this.context ).getNamespaceAlias( 'File', this.targetLanguage ); + let targetResource = this.sourceResource.replace( /^(\.\.?\/)*([^:]+)(:)/, '$1' + namespaceAlias + '$3' ); + sourceImage.attributes.resource = imageLink.attributes.href = targetResource; + + dataCX.adapted = true; + } + + this.node.attributes[ 'data-cx' ] = JSON.stringify( dataCX ); + return this.node; } ); -MWImage.matchTagNames = [ 'figure' ]; +MWImage.matchTagNames = [ 'figure', 'figure-inline' ]; MWImage.matchRdfaTypes = [ 'mw:Image', 'mw:Image/Thumb', 'mw:Image/Frame', 'mw:Image/Frameless' ]; module.exports = MWImage; diff --git a/test/adaptation/AdaptationTests.json b/test/adaptation/AdaptationTests.json index a6eab90..84ca49a 100644 --- a/test/adaptation/AdaptationTests.json +++ b/test/adaptation/AdaptationTests.json @@ -677,6 +677,37 @@ } }, { + "desc": "Image adaptation - Inline image with figure-inline tag", + "from": "en", + "to": "ru", + "source": "<p><figure-inline class='mw-default-size mw-halign-left' typeof='mw:Image/Frameless' data-mw='{\"caption\":\"Some caption\"}' id='mwUQ'><a href='./File:Philos_experiment_of_the_burning_candle.PNG' id='mwUg'><img alt='Drawing of a burning candle enclosed in a glass bulb.' resource='./File:Philos_experiment_of_the_burning_candle.PNG' src='//upload.wikimedia.org/wikipedia/commons/e/e6/Philos_experiment_of_the_burning_candle.PNG' data-file-width='125' data-file-height='248' data-file-type='bitmap' height='248' width='125' id='mwUw'/></a></figure-inline></p>", + "resultAttributes": { + "mwUQ": { + "data-mw": { + "caption": "[en→ru]Some caption" + }, + "data-cx": { + "adapted": true, + "imageSource": "//upload.wikimedia.org/wikipedia/commons/e/e6/Philos_experiment_of_the_burning_candle.PNG", + "resource": "./File:Philos_experiment_of_the_burning_candle.PNG" + } + } + } + }, + { + "desc": "Image adaptation - Inline image with span tag - Not supported", + "from": "en", + "to": "ru", + "source": "<p><span class='mw-default-size mw-halign-left' typeof='mw:Image/Frameless' data-mw='{\"caption\":\"Some caption\"}' id='mwUQ'><a href='./File:Philos_experiment_of_the_burning_candle.PNG' id='mwUg'><img alt='Drawing of a burning candle enclosed in a glass bulb.' resource='./File:Philos_experiment_of_the_burning_candle.PNG' src='//upload.wikimedia.org/wikipedia/commons/e/e6/Philos_experiment_of_the_burning_candle.PNG' data-file-width='125' data-file-height='248' data-file-type='bitmap' height='248' width='125' id='mwUw'/></a></span></p>", + "resultAttributes": { + "mwUQ": { + "data-mw": { + "caption": "Some caption" + } + } + } + }, + { "desc": "Image adaptation- source and target language directions differs", "from": "en", "to": "he", @@ -715,7 +746,7 @@ } } } - }, + }, { "desc": "Image adaptation- image is not in commons", "from": "en", @@ -725,6 +756,7 @@ "mwUQ": { "data-cx": { "adapted": false, + "imageSource": "//upload.wikimedia.org/wikipedia/mediawiki/e/e6/Philos_experiment_of_the_burning_candle.PNG", "resource": "./File:Philos_experiment_of_the_burning_candle.PNG" } }, -- To view, visit https://gerrit.wikimedia.org/r/381960 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I8db09d11bb64701811720a45b526cc6395fbd84e Gerrit-PatchSet: 3 Gerrit-Project: mediawiki/services/cxserver Gerrit-Branch: master Gerrit-Owner: Santhosh <santhosh.thottin...@gmail.com> Gerrit-Reviewer: Catrope <r...@wikimedia.org> Gerrit-Reviewer: Esanders <esand...@wikimedia.org> Gerrit-Reviewer: Nikerabbit <niklas.laxst...@gmail.com> Gerrit-Reviewer: Santhosh <santhosh.thottin...@gmail.com> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits