http://www.mediawiki.org/wiki/Special:Code/MediaWiki/89798

Revision: 89798
Author:   jeroendedauw
Date:     2011-06-09 21:22:13 +0000 (Thu, 09 Jun 2011)
Log Message:
-----------
added support for ms translation service

Modified Paths:
--------------
    trunk/extensions/LiveTranslate/includes/ext.lt.google.js
    trunk/extensions/LiveTranslate/includes/ext.lt.ms.js

Modified: trunk/extensions/LiveTranslate/includes/ext.lt.google.js
===================================================================
--- trunk/extensions/LiveTranslate/includes/ext.lt.google.js    2011-06-09 
21:22:00 UTC (rev 89797)
+++ trunk/extensions/LiveTranslate/includes/ext.lt.google.js    2011-06-09 
21:22:13 UTC (rev 89798)
@@ -173,6 +173,7 @@
         */
        this.handleTranslationCompletion = function( targetLang ) {
                if ( !--this.runningJobs ) {
+                       ltdebug( 'Google: translation process done' );
                        this.done( targetLang );
                }
        }

Modified: trunk/extensions/LiveTranslate/includes/ext.lt.ms.js
===================================================================
--- trunk/extensions/LiveTranslate/includes/ext.lt.ms.js        2011-06-09 
21:22:00 UTC (rev 89797)
+++ trunk/extensions/LiveTranslate/includes/ext.lt.ms.js        2011-06-09 
21:22:13 UTC (rev 89798)
@@ -12,7 +12,112 @@
        
        this.done = function( targetLang ){};
        
+       this.runningJobs = 0;
+       
+       // This is to enable a hack to decode quotes.
+       this.textAreaElement = document.createElement( 'textarea' );
+       
        /**
+        * Determines a chunk to translate of an DOM elements contents and 
calls the Microsoft Translate API.
+        * Then calls itself if there is any remaining work to be done.
+        * 
+        * @param {array} untranslatedsentences
+        * @param {array} chunks
+        * @param {integer} currentMaxSize
+        * @param {string} sourceLang
+        * @param {string} targetLang
+        * @param {jQuery} element
+        */
+       this.translateChunk = function( untranslatedsentences, chunks, 
currentMaxSize, sourceLang, targetLang, element ) {
+               ltdebug( 'MS: Translating chunk' );
+               var remainingPart = false;
+               var partToUse = false;
+               var sentenceCount = 0;
+               var currentLength = 0;
+               
+               // Find the scentances that can be put in the current chunk.
+               for ( i in untranslatedsentences ) {
+                       sentenceCount++;
+                       
+                       if ( currentLength + untranslatedsentences[i].length < 
currentMaxSize ) {
+                               currentLength += 
untranslatedsentences[i].length;
+                       }
+                       else if ( untranslatedsentences[i].length > 0 ) {
+                               if ( currentLength == 0 ) {
+                                       // If the first scentance is longer 
then the max chunk legth, split it.
+                                       partToUse = 
untranslatedsentences[i].substr( 0, currentMaxSize - currentLength );
+                                       remainingPart = 
untranslatedsentences[i].substr( currentMaxSize - currentLength );
+                               }
+                               
+                               break;
+                       }
+               }
+               
+               var chunk = '';
+               
+               // Build the chunck.
+               for ( i = 0; i < sentenceCount; i++ ) {
+                       var part = untranslatedsentences.shift();
+                       
+                       if ( i != sentenceCount - 1 || partToUse === false ) {
+                               chunk += part; 
+                       }
+               }
+               
+               // If there is a remaining part, re-add it to the scentances to 
translate list.
+               if ( remainingPart !== false ) {
+                       untranslatedsentences.unshift( remainingPart );
+               }
+               
+               // If there is a partial scentance, add it to the chunk.
+               if ( partToUse !== false ) {
+                       chunk += partToUse;
+               }
+               
+               // If the lenght is 0, the element has been translated.
+               if ( chunk.length == 0 ) {
+                       this.handleTranslationCompletion( targetLang );
+                       return;
+               }
+
+               // Keep track of leading and tailing spaces, as they often get 
modified by the GT API.
+               var leadingSpace = chunk.substr( 0, 1 ) == ' ' ? ' ' : '';
+               var tailingSpace = ( chunk.length > 1 && chunk.substr( 
chunk.length - 1, 1 ) == ' ' ) ? ' ' : '';
+               
+               $.getJSON(
+                       
'http://api.microsofttranslator.com/V2/Ajax.svc/Translate?oncomplete=?',
+                       {
+                               'appId': 
'9B1B396B48BBA6BF483B6C0A83CE2B07EF5D8F8C', // TODO
+                               'from': sourceLang,
+                               'to': targetLang,
+                               'text': jQuery.trim( chunk ) // Trim, so the 
result does not contain preceding or tailing spaces.
+                       },
+                       function( translation ) {
+                               ltdebug( 'MS: Translated chunk' );
+                               
+                               if ( translation ) {
+                                       chunks.push( leadingSpace + translation 
+ tailingSpace );
+                               }
+                               else {
+                                       // If the translation failed, keep the 
original text.
+                                       chunks.push( chunk );
+                               }
+                               
+                               if ( untranslatedsentences.length == 0 ) {
+                                       // If the current chunk was smaller 
then the max size, node translation is complete, so update text.
+                                       self.textAreaElement.innerHTML = 
chunks.join( '' ); // This is a hack to decode quotes.
+                                       element.replaceData( 0, element.length, 
self.textAreaElement.value );
+                                       self.handleTranslationCompletion( 
targetLang );
+                               }
+                               else {
+                                       // If there is more work to do, move on 
to the next chunk.
+                                       self.translateChunk( 
untranslatedsentences, chunks, currentMaxSize, sourceLang, targetLang, element 
);
+                               }
+                       }
+               );
+       }
+       
+       /**
         * Translates a single DOM element using Microsoft Translate.
         * Loops through child elements and recursively calls itself to 
translate these.
         * 
@@ -21,7 +126,57 @@
         * @param {string} targetLang
         */
        this.translateElement = function( element, sourceLang, targetLang ) {
+               ltdebug( 'MS: Translating element' );
+               this.runningJobs++;
                
-       };
+               var maxChunkLength = 500;
+
+               element.contents().each( function() {
+                       ltdebug( 'MS: Element conent item' );
+                       
+                       // If it's a text node, then translate it.
+                       if ( this.nodeType == 3 && typeof this.data === 
'string' && $.trim( this.data ).length > 0 ) {
+                               ltdebug( 'MS: Found content node' );
+                               
+                               self.runningJobs++;
+                               self.translateChunk(
+                                       this.data.split( new RegExp( 
"(\\S.+?[.!?])(?=\\s+|$)", "gi" ) ),
+                                       [],
+                                       maxChunkLength,
+                                       sourceLang,
+                                       targetLang,
+                                       this
+                               );
+                       }
+                       // If it's an html element, check to see if it should 
be ignored, and if not, apply function again.
+                       else if ( this.nodeType != 3
+                               && $.inArray( $( this ).attr( 'id' ), [ 
'siteSub', 'jump-to-nav' ] ) == -1
+                               && !$( this ).hasClass( 'notranslate' ) && !$( 
this ).hasClass( 'printfooter' )
+                               && $( this ).text().length > 0 ) {
+                               
+                               ltdebug( 'MS: Found child node' );
+                               self.translateElement( $( this ), sourceLang, 
targetLang );
+                       }
+                       else {
+                               ltdebug( 'MS: Found ignore node' );
+                       }
+               } );
+               
+               this.handleTranslationCompletion( targetLang );
+       }
        
+       /**
+        * Should be called every time a DOM element has been translated.
+        * By use of the runningJobs var, completion of the translation process 
is detected,
+        * and further handled by this function.
+        * 
+        * @param {string} targetLang
+        */
+       this.handleTranslationCompletion = function( targetLang ) {
+               if ( !--this.runningJobs ) {
+                       ltdebug( 'MS: translation process done' );
+                       this.done( targetLang );
+               }
+       }
+       
 }; })( jQuery );
\ No newline at end of file


_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to