r89798 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r89797‎ | r89798 | r89799 >
Date:21:22, 9 June 2011
Author:jeroendedauw
Status:deferred
Tags:
Comment:
added support for ms translation service
Modified paths:
  • /trunk/extensions/LiveTranslate/includes/ext.lt.google.js (modified) (history)
  • /trunk/extensions/LiveTranslate/includes/ext.lt.ms.js (modified) (history)

Diff [purge]

Index: trunk/extensions/LiveTranslate/includes/ext.lt.google.js
@@ -173,6 +173,7 @@
174174 */
175175 this.handleTranslationCompletion = function( targetLang ) {
176176 if ( !--this.runningJobs ) {
 177+ ltdebug( 'Google: translation process done' );
177178 this.done( targetLang );
178179 }
179180 }
Index: trunk/extensions/LiveTranslate/includes/ext.lt.ms.js
@@ -12,7 +12,112 @@
1313
1414 this.done = function( targetLang ){};
1515
 16+ this.runningJobs = 0;
 17+
 18+ // This is to enable a hack to decode quotes.
 19+ this.textAreaElement = document.createElement( 'textarea' );
 20+
1621 /**
 22+ * Determines a chunk to translate of an DOM elements contents and calls the Microsoft Translate API.
 23+ * Then calls itself if there is any remaining work to be done.
 24+ *
 25+ * @param {array} untranslatedsentences
 26+ * @param {array} chunks
 27+ * @param {integer} currentMaxSize
 28+ * @param {string} sourceLang
 29+ * @param {string} targetLang
 30+ * @param {jQuery} element
 31+ */
 32+ this.translateChunk = function( untranslatedsentences, chunks, currentMaxSize, sourceLang, targetLang, element ) {
 33+ ltdebug( 'MS: Translating chunk' );
 34+ var remainingPart = false;
 35+ var partToUse = false;
 36+ var sentenceCount = 0;
 37+ var currentLength = 0;
 38+
 39+ // Find the scentances that can be put in the current chunk.
 40+ for ( i in untranslatedsentences ) {
 41+ sentenceCount++;
 42+
 43+ if ( currentLength + untranslatedsentences[i].length < currentMaxSize ) {
 44+ currentLength += untranslatedsentences[i].length;
 45+ }
 46+ else if ( untranslatedsentences[i].length > 0 ) {
 47+ if ( currentLength == 0 ) {
 48+ // If the first scentance is longer then the max chunk legth, split it.
 49+ partToUse = untranslatedsentences[i].substr( 0, currentMaxSize - currentLength );
 50+ remainingPart = untranslatedsentences[i].substr( currentMaxSize - currentLength );
 51+ }
 52+
 53+ break;
 54+ }
 55+ }
 56+
 57+ var chunk = '';
 58+
 59+ // Build the chunck.
 60+ for ( i = 0; i < sentenceCount; i++ ) {
 61+ var part = untranslatedsentences.shift();
 62+
 63+ if ( i != sentenceCount - 1 || partToUse === false ) {
 64+ chunk += part;
 65+ }
 66+ }
 67+
 68+ // If there is a remaining part, re-add it to the scentances to translate list.
 69+ if ( remainingPart !== false ) {
 70+ untranslatedsentences.unshift( remainingPart );
 71+ }
 72+
 73+ // If there is a partial scentance, add it to the chunk.
 74+ if ( partToUse !== false ) {
 75+ chunk += partToUse;
 76+ }
 77+
 78+ // If the lenght is 0, the element has been translated.
 79+ if ( chunk.length == 0 ) {
 80+ this.handleTranslationCompletion( targetLang );
 81+ return;
 82+ }
 83+
 84+ // Keep track of leading and tailing spaces, as they often get modified by the GT API.
 85+ var leadingSpace = chunk.substr( 0, 1 ) == ' ' ? ' ' : '';
 86+ var tailingSpace = ( chunk.length > 1 && chunk.substr( chunk.length - 1, 1 ) == ' ' ) ? ' ' : '';
 87+
 88+ $.getJSON(
 89+ 'http://api.microsofttranslator.com/V2/Ajax.svc/Translate?oncomplete=?',
 90+ {
 91+ 'appId': '9B1B396B48BBA6BF483B6C0A83CE2B07EF5D8F8C', // TODO
 92+ 'from': sourceLang,
 93+ 'to': targetLang,
 94+ 'text': jQuery.trim( chunk ) // Trim, so the result does not contain preceding or tailing spaces.
 95+ },
 96+ function( translation ) {
 97+ ltdebug( 'MS: Translated chunk' );
 98+
 99+ if ( translation ) {
 100+ chunks.push( leadingSpace + translation + tailingSpace );
 101+ }
 102+ else {
 103+ // If the translation failed, keep the original text.
 104+ chunks.push( chunk );
 105+ }
 106+
 107+ if ( untranslatedsentences.length == 0 ) {
 108+ // If the current chunk was smaller then the max size, node translation is complete, so update text.
 109+ self.textAreaElement.innerHTML = chunks.join( '' ); // This is a hack to decode quotes.
 110+ element.replaceData( 0, element.length, self.textAreaElement.value );
 111+ self.handleTranslationCompletion( targetLang );
 112+ }
 113+ else {
 114+ // If there is more work to do, move on to the next chunk.
 115+ self.translateChunk( untranslatedsentences, chunks, currentMaxSize, sourceLang, targetLang, element );
 116+ }
 117+ }
 118+ );
 119+ }
 120+
 121+ /**
17122 * Translates a single DOM element using Microsoft Translate.
18123 * Loops through child elements and recursively calls itself to translate these.
19124 *
@@ -21,7 +126,57 @@
22127 * @param {string} targetLang
23128 */
24129 this.translateElement = function( element, sourceLang, targetLang ) {
 130+ ltdebug( 'MS: Translating element' );
 131+ this.runningJobs++;
25132
26 - };
 133+ var maxChunkLength = 500;
 134+
 135+ element.contents().each( function() {
 136+ ltdebug( 'MS: Element conent item' );
 137+
 138+ // If it's a text node, then translate it.
 139+ if ( this.nodeType == 3 && typeof this.data === 'string' && $.trim( this.data ).length > 0 ) {
 140+ ltdebug( 'MS: Found content node' );
 141+
 142+ self.runningJobs++;
 143+ self.translateChunk(
 144+ this.data.split( new RegExp( "(\\S.+?[.!?])(?=\\s+|$)", "gi" ) ),
 145+ [],
 146+ maxChunkLength,
 147+ sourceLang,
 148+ targetLang,
 149+ this
 150+ );
 151+ }
 152+ // If it's an html element, check to see if it should be ignored, and if not, apply function again.
 153+ else if ( this.nodeType != 3
 154+ && $.inArray( $( this ).attr( 'id' ), [ 'siteSub', 'jump-to-nav' ] ) == -1
 155+ && !$( this ).hasClass( 'notranslate' ) && !$( this ).hasClass( 'printfooter' )
 156+ && $( this ).text().length > 0 ) {
 157+
 158+ ltdebug( 'MS: Found child node' );
 159+ self.translateElement( $( this ), sourceLang, targetLang );
 160+ }
 161+ else {
 162+ ltdebug( 'MS: Found ignore node' );
 163+ }
 164+ } );
 165+
 166+ this.handleTranslationCompletion( targetLang );
 167+ }
27168
 169+ /**
 170+ * Should be called every time a DOM element has been translated.
 171+ * By use of the runningJobs var, completion of the translation process is detected,
 172+ * and further handled by this function.
 173+ *
 174+ * @param {string} targetLang
 175+ */
 176+ this.handleTranslationCompletion = function( targetLang ) {
 177+ if ( !--this.runningJobs ) {
 178+ ltdebug( 'MS: translation process done' );
 179+ this.done( targetLang );
 180+ }
 181+ }
 182+
28183 }; })( jQuery );
\ No newline at end of file

Status & tagging log