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