http://www.mediawiki.org/wiki/Special:Code/MediaWiki/89647
Revision: 89647
Author: jeroendedauw
Date: 2011-06-07 14:44:54 +0000 (Tue, 07 Jun 2011)
Log Message:
-----------
work on lt 1.1 with ms translation service supporrt
Modified Paths:
--------------
trunk/extensions/LiveTranslate/LiveTranslate.hooks.php
trunk/extensions/LiveTranslate/LiveTranslate.php
trunk/extensions/LiveTranslate/LiveTranslate_Settings.php
trunk/extensions/LiveTranslate/includes/LiveTranslate_Functions.php
trunk/extensions/LiveTranslate/includes/ext.livetranslate.js
Added Paths:
-----------
trunk/extensions/LiveTranslate/includes/ext.lt.google.js
trunk/extensions/LiveTranslate/includes/ext.lt.ms.js
Modified: trunk/extensions/LiveTranslate/LiveTranslate.hooks.php
===================================================================
--- trunk/extensions/LiveTranslate/LiveTranslate.hooks.php 2011-06-07
14:04:25 UTC (rev 89646)
+++ trunk/extensions/LiveTranslate/LiveTranslate.hooks.php 2011-06-07
14:44:54 UTC (rev 89647)
@@ -154,42 +154,39 @@
protected static function displayTranslationControl( $currentLang ) {
global $wgOut, $egGoogleApiKey;
+ $divContents = htmlspecialchars( wfMsg(
'livetranslate-translate-to' ) ) .
+ ' ' .
+ LiveTranslateFunctions::getLanguageSelector(
$currentLang ) .
+ ' ' .
+ Html::element(
+ 'button',
+ array( 'id' => 'livetranslatebutton' ),
+ wfMsg( 'livetranslate-button-translate' )
+ ) .
+ ' ' .
+ Html::element(
+ 'button',
+ array( 'id' => 'ltrevertbutton', 'style' =>
'display:none' ),
+ wfMsg( 'livetranslate-button-revert' )
+ );
+
+ if ( $GLOBALS['egLiveTranslateService'] == LTS_GOOGLE ) {
+ $divContents .= '<br /><br /><div id="googlebranding"
style="display:inline; float:right"></div>';
+ }
+
$wgOut->addHTML(
Html::rawElement(
'div',
array(
'id' => 'livetranslatediv',
'style' => 'display:inline;
float:right',
- 'class' => 'notranslate'
+ 'class' => 'notranslate',
+ 'sourcelang' => $currentLang
),
- htmlspecialchars( wfMsg(
'livetranslate-translate-to' ) ) .
- ' ' .
- LiveTranslateFunctions::getLanguageSelector(
$currentLang ) .
- ' ' .
- Html::element(
- 'button',
- array( 'id' => 'livetranslatebutton' ),
- wfMsg( 'livetranslate-button-translate'
)
- ) .
- ' ' .
- Html::element(
- 'button',
- array( 'id' => 'ltrevertbutton',
'style' => 'display:none' ),
- wfMsg( 'livetranslate-button-revert' )
- )
- ) .
- '<br /><br /><div id="googlebranding"
style="display:inline; float:right"></div>'
+ $divContents
+ )
);
- $wgOut->addScript(
- Html::linkedScript( 'https://www.google.com/jsapi?key='
. htmlspecialchars( $egGoogleApiKey ) ) .
- Html::inlineScript(
- 'google.load("language", "1");
-
google.setOnLoadCallback(function(){google.language.getBranding("googlebranding");});'
.
- 'var sourceLang = ' . FormatJson::encode(
$currentLang ) . ';'
- )
- );
-
LiveTranslateFunctions::loadJs();
}
@@ -350,9 +347,8 @@
}
public static function onOutputPageParserOutput( $outputpage,
$parseroutput ) {
- $magicWords = isset( $parseroutput->mLTMagicWords ) ?
$parseroutput->mLTMagicWords : array();
-
- return true;
+ $magicWords = isset( $parseroutput->mLTMagicWords ) ?
$parseroutput->mLTMagicWords : array();
+ return true;
}
}
Modified: trunk/extensions/LiveTranslate/LiveTranslate.php
===================================================================
--- trunk/extensions/LiveTranslate/LiveTranslate.php 2011-06-07 14:04:25 UTC
(rev 89646)
+++ trunk/extensions/LiveTranslate/LiveTranslate.php 2011-06-07 14:44:54 UTC
(rev 89647)
@@ -24,7 +24,7 @@
die( 'Not an entry point.' );
}
-define( 'LiveTranslate_VERSION', '1.0.1' );
+define( 'LiveTranslate_VERSION', '1.1 alpha' );
$wgExtensionCredits['other'][] = array(
'path' => __FILE__,
@@ -95,6 +95,18 @@
'dependencies' => array(),
'messages' => $egLTJSMessages
);
+
+ $wgResourceModules['ext.lt.google'] = $moduleTemplate + array(
+ 'scripts' => array( 'includes/ext.lt.google.js' ),
+ 'dependencies' => array( 'ext.livetranslate' ),
+ 'messages' => array()
+ );
+
+ $wgResourceModules['ext.lt.ms'] = $moduleTemplate + array(
+ 'scripts' => array( 'includes/ext.lt.ms.js' ),
+ 'dependencies' => array( 'ext.livetranslate' ),
+ 'messages' => array()
+ );
}
/**
@@ -106,6 +118,14 @@
define( 'TMT_TMX', 1 );
define( 'TMT_GCSV', 2 );
+/**
+ * Enum for translation services.
+ *
+ * @since 1.1
+ */
+define( 'LTS_GOOGLE', 0 );
+define( 'LTS_MS', 1 );
+
$egLiveTranslateMagicWords = array();
require_once 'LiveTranslate_Settings.php';
Modified: trunk/extensions/LiveTranslate/LiveTranslate_Settings.php
===================================================================
--- trunk/extensions/LiveTranslate/LiveTranslate_Settings.php 2011-06-07
14:04:25 UTC (rev 89646)
+++ trunk/extensions/LiveTranslate/LiveTranslate_Settings.php 2011-06-07
14:44:54 UTC (rev 89647)
@@ -33,6 +33,10 @@
# TMT_LTF, TMT_TMX, TMT_GCSV
$egLiveTranslateTMT = TMT_LTF;
+# Translation service to use.
+# LTS_GOOGLE, LTS_MS
+$egLiveTranslateService = LTS_GOOGLE;
+
# The namespaces that should show the translation control.
$egLTNSWithTranslationControl = array(
NS_MAIN => true,
@@ -58,3 +62,5 @@
# When true, this prevents storange of translations that are the same in the
source and target language.
$egLTRequireSignificance = false;
+
+$egLiveTranslateDebugJS = false;
Modified: trunk/extensions/LiveTranslate/includes/LiveTranslate_Functions.php
===================================================================
--- trunk/extensions/LiveTranslate/includes/LiveTranslate_Functions.php
2011-06-07 14:04:25 UTC (rev 89646)
+++ trunk/extensions/LiveTranslate/includes/LiveTranslate_Functions.php
2011-06-07 14:44:54 UTC (rev 89647)
@@ -21,9 +21,30 @@
public static function loadJs() {
global $wgOut;
+ $wgOut->addScript(
+ Html::inlineScript(
+ 'var ltDebugMessages = ' . FormatJson::encode(
$GLOBALS['egLiveTranslateDebugJS'] ) . ';'
+ )
+ );
+
// For backward compatibility with MW < 1.17.
if ( is_callable( array( $wgOut, 'addModules' ) ) ) {
- $wgOut->addModules( 'ext.livetranslate' );
+ $modules = array( 'ext.livetranslate' );
+
+ switch( $GLOBALS['egLiveTranslateService'] ) {
+ case LTS_GOOGLE:
+ $modules[] = 'ext.lt.google';
+ $wgOut->addHeadItem(
+ 'ext.lt.google.jsapi',
+ Html::linkedScript(
'https://www.google.com/jsapi?key=' . htmlspecialchars(
$GLOBALS['egGoogleApiKey'] ) )
+ );
+ break;
+ case LTS_MS:
+ $modules[] = 'ext.lt.ms';
+ break;
+ }
+
+ $wgOut->addModules( $modules );
}
else {
global $egLiveTranslateScriptPath;
@@ -36,6 +57,26 @@
'ext.livetranslate',
Html::linkedScript( $egLiveTranslateScriptPath
. '/includes/ext.livetranslate.js' )
);
+
+ switch( $GLOBALS['egLiveTranslateService'] ) {
+ case LTS_GOOGLE:
+ $wgOut->addHeadItem(
+ 'ext.lt.google.jsapi',
+ Html::linkedScript(
'https://www.google.com/jsapi?key=' . htmlspecialchars(
$GLOBALS['egGoogleApiKey'] ) )
+ );
+
+ $wgOut->addHeadItem(
+ 'ext.lt.google',
+ Html::linkedScript(
$egLiveTranslateScriptPath . '/includes/ext.lt.google.js' )
+ );
+ break;
+ case LTS_MS:
+ $wgOut->addHeadItem(
+ 'ext.lt.ms',
+ Html::linkedScript(
$egLiveTranslateScriptPath . '/includes/ext.lt.ms.js' )
+ );
+ break;
+ }
}
}
Modified: trunk/extensions/LiveTranslate/includes/ext.livetranslate.js
===================================================================
--- trunk/extensions/LiveTranslate/includes/ext.livetranslate.js
2011-06-07 14:04:25 UTC (rev 89646)
+++ trunk/extensions/LiveTranslate/includes/ext.livetranslate.js
2011-06-07 14:44:54 UTC (rev 89647)
@@ -17,13 +17,14 @@
*/
$.fn.replaceText=function(b,a,c){return this.each(function(){var
f=this.firstChild,g,e,d=[];if(f){do{if(f.nodeType===3){g=f.nodeValue;e=g.replace(b,a);if(e!==g){if(!c&&/</.test(e)){$(f).before(e);d.push(f)}else{f.nodeValue=e}}}}while(f=f.nextSibling)}d.length&&$(d).remove()})}
- var currentLang = window.sourceLang;
+ window.ltdebug = function( message ) {
+ if ( window.ltDebugMessages ) {
+ console.log( 'Live Translate: ' + message );
+ }
+ };
- var runningJobs = 0;
+ var currentLang = $( '#livetranslatediv' ).attr( 'sourcelang' );
- // This is to enable a hack to decode quotes.
- var textAreaElement = document.createElement( 'textarea' );
-
// For the "show original" feature.
var originalHtml = false;
@@ -116,7 +117,7 @@
var newLang = $( '#livetranslatelang' ).val();
if ( words.length == 0 ) {
- requestGoogleTranslate( currentLang, newLang );
+ initiateRemoteTranslating( currentLang, newLang );
}
else {
$.getJSON(
@@ -132,7 +133,7 @@
if ( data.translations ) {
replaceSpecialWords(
data.translations );
}
- requestGoogleTranslate( currentLang,
newLang );
+ initiateRemoteTranslating( currentLang,
newLang );
}
);
}
@@ -214,161 +215,23 @@
}
/**
- * Initiates the Google Translate translation.
+ * Initiates the remote translation process.
*
* @param {string} sourceLang
* @param {string} targetLang
*/
- function requestGoogleTranslate( sourceLang, targetLang ) {
- translateElement( $( '#bodyContent' ), sourceLang, targetLang );
+ function initiateRemoteTranslating( sourceLang, targetLang ) {
+ var translator = new translationService();
+ translator.done = handleTranslationCompletion;
+ ltdebug( 'Initiating remote translation' );
+ translator.translateElement( $( '#bodyContent' ), sourceLang,
targetLang );
+ ltdebug( 'Remote translation completed' );
}
- /**
- * Translates a single DOM element using Google Translate.
- * Loops through child elements and recursivly calls itself to
translate these.
- *
- * TODO: be smarter with the requests, and make sure they don't get
broken up unecesarrily.
- *
- * @param {jQuery} element
- * @param {string} sourceLang
- * @param {string} targetLang
- */
- function translateElement( element, sourceLang, targetLang ) {
- runningJobs++;
-
- var maxChunkLength = 500;
-
- element.contents().each( function() {
- // If it's a text node, then translate it.
- if ( this.nodeType == 3 && this.data != undefined &&
jQuery.trim( this.data ).length > 0 ) {
- runningJobs++;
- 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 ( $.inArray( $( this ).attr( 'id' ), [
'siteSub', 'jump-to-nav' ] ) == -1
- && !$( this ).hasClass( 'notranslate' ) && !$(
this ).hasClass( 'printfooter' )
- && $( this ).text().length > 0 ) {
-
- translateElement( $( this ), sourceLang,
targetLang );
- }
- } );
-
- handleTranslationCompletion( targetLang );
- }
-
- /**
- * Determines a chunk to translate of an DOM elements contents and
calls the Google 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
- */
- function translateChunk( untranslatedsentences, chunks, currentMaxSize,
sourceLang, targetLang, element ) {
- 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 ) {
- 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 ) == ' ' ) ? ' ' : '';
-
- google.language.translate(
- jQuery.trim( chunk ), // Trim, so the result does not
contain preceding or tailing spaces.
- sourceLang,
- targetLang,
- function(result) {
- if ( result.translation ) {
- chunks.push( leadingSpace +
result.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.
- textAreaElement.innerHTML =
chunks.join( '' ); // This is a hack to decode quotes.
- element.replaceData( 0, element.length,
textAreaElement.value );
- handleTranslationCompletion( targetLang
);
- }
- else {
- // If there is more work to do, move on
to the next chunk.
- translateChunk( untranslatedsentences,
chunks, currentMaxSize, sourceLang, targetLang, element );
- }
- }
- );
- }
-
- /**
- * 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
- */
function handleTranslationCompletion( targetLang ) {
- if ( !--runningJobs ) {
- currentLang = targetLang;
- $( '#livetranslatebutton' ).attr( "disabled", false
).text( mediaWiki.msg( 'livetranslate-button-translate' ) );
- $( '#ltrevertbutton' ).css( 'display', 'inline' );
- }
+ currentLang = targetLang;
+ $( '#livetranslatebutton' ).attr( "disabled", false ).text(
mediaWiki.msg( 'livetranslate-button-translate' ) );
+ $( '#ltrevertbutton' ).css( 'display', 'inline' );
}
} ); })(jQuery);
\ No newline at end of file
Added: trunk/extensions/LiveTranslate/includes/ext.lt.google.js
===================================================================
--- trunk/extensions/LiveTranslate/includes/ext.lt.google.js
(rev 0)
+++ trunk/extensions/LiveTranslate/includes/ext.lt.google.js 2011-06-07
14:44:54 UTC (rev 89647)
@@ -0,0 +1,175 @@
+google.load("language", "1");
+google.setOnLoadCallback(function(){google.language.getBranding("googlebranding");});
+
+( window.translationService = function( $ ) {
+
+ var self = this;
+
+ 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 Google 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( 'Google: 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 ) == ' ' ) ? ' ' : '';
+
+ google.language.translate(
+ jQuery.trim( chunk ), // Trim, so the result does not
contain preceding or tailing spaces.
+ sourceLang,
+ targetLang,
+ function(result) {
+ ltdebug( 'Google: Translated chunk' );
+
+ if ( result.translation ) {
+ chunks.push( leadingSpace +
result.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 Google Translate.
+ * Loops through child elements and recursivly calls itself to
translate these.
+ *
+ * @param {jQuery} element
+ * @param {string} sourceLang
+ * @param {string} targetLang
+ */
+ this.translateElement = function( element, sourceLang, targetLang ) {
+ ltdebug( 'Google: Translating element' );
+ runningJobs++;
+
+ var maxChunkLength = 500;
+
+ element.contents().each( function() {
+ if ( this.nodeType == 3 && ( typeof this.data !=
undefined ) ) {
+ console.log( $.trim( this.data ) );
+ console.log( typeof $.trim( this.data ) );
+ }
+ ltdebug( 'Google: Element conent item' );
+
+ // If it's a text node, then translate it.
+ if ( this.nodeType == 3 && this.data != undefined &&
$.trim( this.data ).length > 0 ) {
+ ltdebug( 'Google: Found content node' );
+
+ 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 ( $.inArray( $( this ).attr( 'id' ), [
'siteSub', 'jump-to-nav' ] ) == -1
+ && !$( this ).hasClass( 'notranslate' ) && !$(
this ).hasClass( 'printfooter' )
+ && $( this ).text().length > 0 ) {
+
+ ltdebug( 'Google: Found child node' );
+ self.translateElement( $( this ), sourceLang,
targetLang );
+ }
+ else {
+ ltdebug( 'Google: 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 ) {
+ this.done( targetLang );
+ }
+ }
+
+} )( jQuery );
\ No newline at end of file
Property changes on: trunk/extensions/LiveTranslate/includes/ext.lt.google.js
___________________________________________________________________
Added: svn:eol-style
+ native
Added: trunk/extensions/LiveTranslate/includes/ext.lt.ms.js
===================================================================
--- trunk/extensions/LiveTranslate/includes/ext.lt.ms.js
(rev 0)
+++ trunk/extensions/LiveTranslate/includes/ext.lt.ms.js 2011-06-07
14:44:54 UTC (rev 89647)
@@ -0,0 +1,3 @@
+/**
+ *
+ */
\ No newline at end of file
Property changes on: trunk/extensions/LiveTranslate/includes/ext.lt.ms.js
___________________________________________________________________
Added: svn:eol-style
+ native
_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs