JavaScript 使用Google API使Web应用程序成为多语言......对PHP,Dotnet和其他语言开发人员有用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript 使用Google API使Web应用程序成为多语言......对PHP,Dotnet和其他语言开发人员有用相关的知识,希望对你有一定的参考价值。
Read from top to Bottom see for **** especially.... /* ignore the spelling mistakes */
Make an application multi lingual by using google API....
This process can even be implemented by an web service, but i have made use of google API
Please follow the steps and make changes accordingly
PHP(make use of div's and apply to the id's), ASP(Apply to all labesl)...and the rest of the languages follow up the same procedure accoringly......
*****************Add these 2 scripts tags into u r header and make it common for the pages so that it includes in each and everything***
<!--<script type="text/javascript" src="Translate/googlelanguage.js"></script>
<script type="text/javascript" src="Translate/translate.js"></script>-->
****************Better to add these 2 into head section of u r html or asp or jsp pages********************************************
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Untitled Document</title>
</head>
<body>
************Add this thing into the body section where ever u wish to or u wanna Place the option for selection*******************
<!-- <div><font size="+1">Select Language</font></div>
<div id="mlt_languagelist"> </div>-->
-->Steps:
1) As the page is loaded the the 2nd div gets activated and gets processed through the api and data is fetched from the tranlate.js script....check in the line number 166 the function getLangs() gets called and executed.just go through the function and understand the parameters passed u will know better whats happening.
2) G to line number 85 there u will come to know how the langues get changed based upon u r request.
3) if(GL_curLang == "orig") {
refresh();
return;
}
find th this block and add few more langues based upon ICANN standards for language notations in google.soon after the above block by dumping more conditions to the above block u can select the langues aby your choice
Add:
else if(GL_curLang == "es") { //spanish
refresh();
return;
}
else if(GL_curLang == "ja") { //japanese
refresh();
return;
}
4) So add according to u r choice all this has to be followed aftr line number 888 for the 3 point.
6) And now get to start of the page translate.js and point towards line 52, there you gonna find a an array assigned toa variable with various elements within the array, present with other elements within it for the converion usuage.
for all required labels in asp or the div or span's which u find the page, assign them which are to be changed upon request.
7) rename those elements name by u r own names which u want, use those div's which are present in all front end pages .for each and every text item or asp with label tags, assign these id's one for all those text items(i.e the div's of each and every text item)..and u r almost done
8)save all changes and start using this applicationits gonna work i am sure.....if there is anything lemme know.post it on the comments section i will reply back.
5)By this way the combo box is set with languages which you require to make the application multi lingual
6)this particual api support 64 recognised languages , check the info in google for this particual api.
*********************************************************************************************************************************
</body>
</html>
*******************Save it as translate.js***************************
/* Multi-Language Translation Script:
*
* Automatically translates a webpage (containing text in more than one language) into any single language
* requested by the user. Particularly useful for sites involving a lot of user-generated content (which
* might have originally been written in different languages) - e.g. blogs, forums, or other community sites.
* Harnesses the Google AJAX Language API to perform translation and language detection.
*
* Version: 0.2.5 [2010-01-22]
* Author: Patrick Hathway, OdinLab, University of Reading.
* For Documentation and Updates: See http://code.google.com/p/multi-language-translation/
* Licence: MIT License - see http://opensource.org/licenses/mit-license.php for full terms. Also check
* the script Documentation for more information, and for details of one important consideration.
*
* Some minor configuration is required for this script to work on your website. Follow the instructions
* below, or see the Documentation for full details and examples... */
/* 1. Specify the 'Base Language' for your website: */
var GL_baseLang = "en";
/* 2. Specify the IDs for all major regions (i.e. HTML elements) in your site that should have their
* contents translated. Note that an ID can only be used to identify a single element on a page (for
* elements which appear multiple times, use Class Names instead - see below). The script will translate
* each element separately; any elements that cannot be found on a page will be ignored: */
var GL_classIds = [
["navigation"],
["navigation", "", true],
["quick-id", "", true],
["c-quote", "", true],
["c-need-quote", "", true],
["c-index", "", true],
["c-about", "", true],
["c-exper", "", true],
["c-solution", "", true],
["c-product", "", true],
["c-contact", "", true],
["c-indian-add", "", true],
["c-work", "", true],
["c-contact", "", true],
["c-contactinf", "", true],
["c-usa-add", "", true],
["c-warning", "", true],
["right_sidebar", "fr", true],
["footer"]
];
/* 3. Specify the Class Names of all major regions (i.e. HTML elements) in your site that should have their
* their contents translated. Multiple elements may appear on a page with the same class name; the script
* will locate each occurrance (if present) and translate them separately: */
var GL_classNames = [
["entry_baselang"],
["entry_french", "fr"],
["index-class", "", true],
["about-class", "", true],
["association-class", "", true],
["building-class", "", true],
["career-class", "", true],
["college-class", "", true],
["construction-class", "", true],
["contact-class", "", true],
["entry_baselang", "", true],
["education-class", "", true],
["entry", "", true],
["expertise-class", "", true],
["description", "", true],
["list-custom_website", "", true],
["list-beautiful_graphic", "", true],
["list-using_nature", "", true],
["list-css_xhtml", "", true],
["description", "", true],
["list-branding_your", "", true],
["list-green_branding", "", true],
["list-who_are", "", true],
["list-long_term", "", true],
["list-the_importance", "", true],
["list-flow", "", true],
["list-click_through", "", true],
["list-scale", "", true],
["description", "", true],
["list-google_rank", "", true],
["list-ppc", "", true],
["list-custom_icon", "", true],
["list-why_use", "", true],
["list-web_standard", "", true],
["list-promoting_your", "", true],
["list-business_cards", "", true],
["fashin-class", "", true],
["right", "", true],
["web_portfolio", "", true],
["interior-class", "", true],
["manufacture-class", "", true],
["news-class", "", true],
["medical-class", "", true],
["opening-class", "", true],
["ourclass-class", "", true],
["portfolio-class", "", true],
["ecommerce-class", "", true],
["mobile-class", "", true],
["webdesign-class", "", true],
["product-class", "", true],
["professional-class", "", true],
["real-class", "", true],
["realestate-class", "", true],
["request-class", "", true],
["form_entry", "", true],
["request-id", "", true],
["requestquote-class", "", true],
["consumer-class", "", true],
["software-class", "", true],
["solutions-class", "", true],
["list-why_use", "", true],
["list-west_coast", "", true],
["list-custom_icon", "", true],
["list-crisp_graphics", "", true],
["list-scalable_across", "", true],
["testimonials-class", "", true],
["testimonials", "", true],
["tourism-class", "", true],
["trade-class", "", true],
["transport-class", "", true],
["levonsys-class", "", true],
["working-levonsys-class", "", true],
["quick", "", true],
["entry_french", "", true],
["quotes", "de", true]
];
/* 4. Specify the default language for new visitors (leave blank to auto-detect using browser/system settings) */
var GL_curLang = "";
/* The rest of the Script should not be modified; unless you want to alter the functionality!
* ------------------------------------------------------------------------------------------ */
// Global variables:
var GL_srcContent; // array containing all content on the page to be translated, split up into chunks
var GL_transContent = []; // array containing all chunks which have been translated
var GL_chunksTotal = 0; // total number of chunks to translate
var GL_curChunk; // ID of current chunk being translated
var GL_errors; // array containing details of all errors that occur (if applicable)
var GL_errSrcTxt; // array containing all source text that causes errors (if applicable)
var GL_miniTransItems = []; // array containing element IDs/class names which contain minor items to translate
google.load("language", "1"); // load v1 of google ajax language api
// run when page loads
function initialise() {
addTransMsgs(); // append elements (which will display translation status messages) to page
buildChunkedContent(); // create a local 'cache' of chunked content to be translated
getLangCookie(); // find out the current site language (if known)
getLangs(); // display listbox containing all languages the site can be translated into
// if the original languages should be shown, end function.
if(GL_curLang == "orig") {
return;
}
// otherwise, start the translation
startTranslation();
}
// display listbox containing all languages the site can be translated into (so that one can be selected by user)
function getLangs() {
// create listbox within script so that it won't appear if JavaScript is disabled
document.getElementById("mlt_languagelist").innerHTML = '<select id="mlt_language" onchange="changeLang()" style="width:150px; height:20px;"></select>';
// + '<div id="mlt_langattr"></div>'
var langItems = document.getElementById("mlt_language").options;
// add option to top of listbox allowing user to view the site in its original (i.e. un-translated) languages
langItems.add(new Option("Original Languages", "orig", true));
// loop through list of currently available languages and add each to listbox
for(var lang in google.language.Languages) {
// find out the 2 character Google language code
var langCode = google.language.Languages[lang];
// convert language string to title case
var langString = lang.substr(0,1) + lang.substr(1).toLowerCase();
// improve formatting of 'chinese_simplified' and 'chinese_traditional' language strings
langString = langString.split("_").join(" - ");
// check that Google can translate content into the current language
if ((google.language.isTranslatable(langCode)) && (langCode != "")) {
// if so, add to listbox and translate, so native speakers of that language can find it
if(langCode=="ar")
{
langItems.add(new Option(langString, langCode));
miniTranslate(langItems[(langItems.length-1)],langCode);
}
}
}
document.getElementById("mlt_language").value = GL_curLang; // change listbox to display current site language
google.language.getBranding("mlt_langattr"); // display Google attribution below listbox (as required by TOS)
}
// start the translation
function startTranslation() {
// reset global variables
GL_curChunk = 0; GL_errors = []; GL_errSrcTxt = [];
// check if all content has already been translated into current language since page loaded.
if(chkLangTrans()) {
return; // if so, don't need to translate content again
}
// sanity check - can google actually translate into the current site language?
if (!(google.language.isTranslatable(GL_curLang)) || (GL_curLang == "")) {
return; // if not, end translation
} // Otherwise, send content to google to be translated:
// show the 'Translating...' block
document.getElementById("mlt_translatemsg").innerHTML = 'Translating... <span id="mlt_perc">0%</span>';
miniTranslate(document.getElementById("mlt_translatemsg")); // translate block into site language
document.getElementById("mlt_translatemsg").style.display='block';
// find out the ID of the destination language
var curLangNo = document.getElementById("mlt_language").selectedIndex;
var k = 0;
// create sub-array to hold all translations for current language
GL_transContent[GL_transContent.length] = new Array(3);
GL_transContent[(GL_transContent.length-1)][0] = []; // this array will contain all translated chunks
GL_transContent[(GL_transContent.length-1)][1] = GL_curLang; // store current language
GL_transContent[(GL_transContent.length-1)][2] = false; // mark translation of language as incomplete
// loop through all the chunks to be translated, send to google...
for(var i = 0; i < GL_srcContent.length; i++) {
// find out the source language for the current element to be translated
var srcLang = GL_srcContent[i][GL_srcContent[i].length - 1];
for(var j = 0; j < (GL_srcContent[i].length - 1); j++) {
/* AJAX is used to return translated chunks, so they MAY be returned in any order.
To solve, include current chunk id, destination language + separators at start of each
string. This is a bit of a 'hack', so try to find a better solution! */
var srcText = curLangNo + "<br />" + k + "<br />" + GL_srcContent[i][j];
// send current chunk to google translate; when translated, call function translateChunk
google.language.translate(srcText, srcLang, GL_curLang, translateChunk);
k++;
}
}
setTimeout("checkTransStatus()", 1000); // run function to check translation status after 1 second
}
// check if page content has already been translated into current language since page loaded.
function chkLangTrans() {
// loop through the list of languages the page has been translated into
for(var i = 0; i < GL_transContent.length; i++) {
// check if a translation for current language exists, and if so, whether it is complete.
if((GL_transContent[i][1] == GL_curLang) && (GL_transContent[i][2] == true)){
/* if so, don't need to send content to google again, just assemble the pre-translated content.
This will *dramatically* reduce the translation time for this language! */
endTranslation(i);
return true;
}
}
return false; // otherwise, all relevant page content must be submitted to google for translation.
}
// This runs after each chunk has been translated...
function translateChunk(result) {
// handle translation errors gracefully by storing error details but allowing translation to continue
if (result.error) {
GL_errors[GL_errors.length] = result.error.message;
}
else {
/* Translated chunks may be returned in any order, so we need a method to assemble the chunks
in the correct order:
* Start of each chunk has a destination language id and a chunk id followed by separators.
* Separator is a <br /> HTML tag, as these always appear to retain position after translation...
* The destination language id is used to ensure the translated text is now in the correct language.
* Each chunk is stored in the position of the 'GL_transContent' array corresponding to the current chunk id.
* The ids + separators should not be shown, and are discarded from the chunk when it's stored in array.
*/
// split into array based on separator, so we know the id & destination language of translated chunk
var transChunk = result.translation.split("<br />");
// [find out length of substring to chop off from start of chunk]
var chunkSubStr = 12 + transChunk[0].length + transChunk[1].length;
// remove whitespace from chunk id & destination language (a problem with some translations)
transChunk[0] = transChunk[0].replace(/^\s+|\s+$/g,"");
transChunk[1] = transChunk[1].replace(/^\s+|\s+$/g,"");
/* If the translated chunk has a different destination language to the current site language, discard
translation & end function. This may happen if user changes language whilst translation is in progress */
if(transChunk[0] != document.getElementById("mlt_language").selectedIndex) {
return;
}
// store translated chunk in current language array, along with detected source language (if known)
GL_transContent[(GL_transContent.length-1)][0][transChunk[1]] = new Array(3);
GL_transContent[(GL_transContent.length-1)][0][transChunk[1]][0] = result.translation.substr(chunkSubStr);
GL_transContent[(GL_transContent.length-1)][0][transChunk[1]][1] = result.detectedSourceLanguage;
}
GL_curChunk++; // increment current chunk ID every time function is called
// calculate and display percentage of translation completed, based on number of chunks remaining
var perc = (GL_curChunk / GL_chunksTotal)*100;
document.getElementById("mlt_perc").innerHTML = Math.round(perc) + "%";
// when all chunks have been translated, run the 'endTranslation' function...
if(GL_curChunk >= GL_chunksTotal) {
endTranslation((GL_transContent.length-1)); // [final array element holds current language content!]
}
}
/* runs once a second whilst translation is in progress, updating contents of all elements that have already
been completely translated. Also shows 'timeout' messages if translation not completed within 30 seconds... */
function checkTransStatus() {
// 'static' member variables to keep track of how many times function has run, as well as current language:
if((typeof checkTransStatus.chkStatusCount == 'undefined') || (checkTransStatus.curTransLang != GL_curLang)) {
// reset variables if not defined yet, or if site language has changed since last function call
checkTransStatus.chkStatusCount = 0;
checkTransStatus.curTransLang = GL_curLang;
}
// if translation is now complete, end function.
if(GL_curChunk >= GL_chunksTotal) {
return;
}
checkTransStatus.chkStatusCount++; // increment Translation Status counter
// Store the list of languages in case they are replaced during translation
var langList = document.getElementById("mlt_languagelist").innerHTML;
var curElement; var curTransChunk = 0; var curClass = 0; var curTransLang = GL_transContent.length-1;
// loop through all element IDs (as specified at script top), searching for ones with completed translations
for(var i = 0; i < GL_classIds.length; i++) {
curElement = document.getElementById(GL_classIds[i][0]); // find out current element
// if current element ID exists on the page, replace contents with translated chunks
if(curElement != null) {
// assemble and display translated chunks for current element
curTransChunk = unpackTransChunks(curTransLang,curTransChunk,curClass,curElement,false);
curClass++; // move to next element ID
}
}
// Get all elements on the page, so that ones with the specified class names can be located
var allElements = document.getElementsByTagName("*");
// loop through all element class names (as specified at script top), searching for completed translations
for(var i = 0; i < GL_classNames.length; i++) {
// loop through all elements, so that any with the current class name can be identified
for(var j = 0; j < allElements.length; j++) {
if(allElements[j].className == GL_classNames[i][0]) {
// assemble and display translated chunks for current element
curTransChunk = unpackTransChunks(curTransLang,curTransChunk,curClass,allElements[j],false);
curClass++; // move to next element Class Name
}
}
}
// if listbox containing all languages has been removed as a result of translation, display it again
if(document.getElementById("mlt_languagelist").innerHTML == "") {
document.getElementById("mlt_languagelist").innerHTML = langList;
document.getElementById("mlt_language").value = GL_curLang; // change listbox to show current language
}
/* if translation still isn't complete after 30 seconds, update translation message. Note: there is no
need to halt the current translation completely, but we will allow user to restart it if desired! */
if(checkTransStatus.chkStatusCount == 30) {
// calculate and display percentage of translation completed, based on number of chunks remaining
var perc = Math.round((GL_curChunk / GL_chunksTotal)*100) + "%";
// update translation status message
document.getElementById("mlt_translatemsg").innerHTML = 'Translating (Slowly!)... ' +
'<span id="mlt_perc">' + perc + '</span> - <a href="javascript:refresh()">Retry</a>';
miniTranslate(document.getElementById("mlt_translatemsg")); // translate block into site language
}
setTimeout("checkTransStatus()", 1000); // check translation status again after another second
}
// runs after all translations have been completed; displaying the results on screen in place of previous content
function endTranslation(curTransLang) {
var curElement;
var curTransChunk = 0; var curClass = 0;
// loop through all element IDs (as specified at script top), replacing current contents with translations
for(var i = 0; i < GL_classIds.length; i++) {
curElement = document.getElementById(GL_classIds[i][0]); // find out current element
// if current element ID exists on the page, replace contents with translated chunks
if(curElement != null) {
// assemble and display translated chunks for current element
curTransChunk = unpackTransChunks(curTransLang,curTransChunk,curClass,curElement,true,GL_classIds[i]);
curClass++; // move to next element ID
}
}
// Get all elements on the page, so that ones with the specified class names can be located
var allElements = document.getElementsByTagName("*");
// loop through all element class names (as specified at script top), so contents can be replaced by translations
for(var i = 0; i < GL_classNames.length; i++) {
// loop through all elements, so that any with the current class name can be identified
for(var j = 0; j < allElements.length; j++) {
if(allElements[j].className == GL_classNames[i][0]) {
// assemble and display translated chunks for current element
curTransChunk = unpackTransChunks(curTransLang,curTransChunk,curClass,allElements[j],true,GL_classNames[i]);
curClass++; // move to next element Class Name
}
}
}
// Perform translations of all content added by the script (e.g. language strings and error messages)
transAddedText();
// Re-create listbox containing all languages, in case it has been removed as a result of translation
getLangs();
// translate the 'Original Languages' listbox item to equivalent in current site language
miniTranslate(document.getElementById("mlt_language").options[0],GL_curLang,"Original Languages");
// if any errors occured during translation, display warning message at top of screen and end function
if(GL_errors.length != 0) {
document.getElementById("mlt_translatemsg").innerHTML = GL_errors.length + ' Problems(s) Occurred During Translation: ' +
'<a href="javascript:refresh()">Retry</a> - <a href="javascript:showErrDetails()">Details</a> - ' +
'<a href="javascript:hideTransMsg()">Hide</a>';
miniTranslate(document.getElementById("mlt_translatemsg")); // translate warning message into current site language
return;
}
// mark translation of page into current language as complete, so that translation can be quicker next time.
GL_transContent[curTransLang][2] = true;
hideTransMsg(); // otherwise, hide 'Translating...' message
}
// assemble and display translated chunks for current element on page
function unpackTransChunks(curTransLang,curTransChunk,curClassNum,curElement,transComplete,curClass) {
// 'static' member variable to keep track of how many times function has run
if(typeof unpackTransChunks.curLinkId == 'undefined') {
// reset curLinkId variable if not defined yet - it's used to identify the correct 'show source text' link
unpackTransChunks.curLinkId = 0;
} unpackTransChunks.curLinkId++; var j = unpackTransChunks.curLinkId; // increment current link id, j is an alias
var curContent = ""; // reset translated contents of current element
var initTransChunk = curTransChunk; // store initial chunk id of current element
// loop through all translated chunks, assembling all translated content for current element
for(var i = 0; i < (GL_srcContent[curClassNum].length - 1); i++) {
// if current chunk does not exist, translation is not complete or errors occurred
if((GL_transContent[curTransLang][0][curTransChunk] == null) && (transComplete == false)) {
break; // stop looping through chunks if full translation has not yet been completed
} else if((GL_transContent[curTransLang][0][curTransChunk] == null) && (transComplete == true)) {
// if full translation IS complete, show warning message and a link to show source text (in red)
curContent += '<div style="color: red;" id="mlt_srctxt' + j + '">[<span class="mlt_transerrtxt">' +
'<em style="text-transform: uppercase;">THIS SECTION COULD NOT BE TRANSLATED</em> - '+
'<a id="mlt_srctxtlnk' + j + '" href="javascript:showSrcTxt(' + j + ',' + curClassNum + ',' + (i+1) +
')">View Source Text [+]</a></span><span id="mlt_srctxtbracket' + j + '">]</span></div>';
GL_errSrcTxt[GL_errSrcTxt.length] = GL_srcContent[curClassNum][i]; // store affected source text
unpackTransChunks.curLinkId++; j = unpackTransChunks.curLinkId; // increment current link id
} else {
// otherwise append current translated chunk to translated content string
curContent += GL_transContent[curTransLang][0][curTransChunk][0];
}
curTransChunk++; // move to next chunk
}
// if translation is complete, replace contents of current element with translated text
if(transComplete == true) {
curElement.innerHTML = curContent;
// append a language string to bottom of current element if desired
getLangString(curTransLang,curElement,curClass,initTransChunk,(GL_srcContent[curClassNum].length - 1),j,curClassNum);
// otherwise, check if all translated chunks for current element were assembled
} else if((i == (GL_srcContent[curClassNum].length - 1)) && (GL_transContent[curTransLang][0][initTransChunk][2] != true)) {
// if so (and current element translation is not yet marked as complete), replace contents with translation
curElement.innerHTML = curContent;
GL_transContent[curTransLang][0][initTransChunk][2] = true; // mark current element translation as complete
}
return curTransChunk; // return current chunk id to calling function
}
// If required, find and append a string containing the Source Language to the bottom of the specified element
function getLangString(curTransLang,curElement,curClass,curTransChunk,transChunksLen,j,curClassNum) {
var detectedLang = "";
// if the current element does not need a language string appended, end function
if(curClass[2] != true) {
return;
}
// if source language for current element has already been manually specified, set this as detected language
if(curClass[1] != "") {
detectedLang = curClass[1];
}
// otherwise find out language based on the detected source languages for translated chunks in current element
else {
detectedLang = findDetectedLang(curTransLang,curTransChunk,transChunksLen);
}
// if detected language is same as site language, there is no need to display language string, so end function
if(detectedLang == GL_curLang){
return;
}
var srcLangString = getFmtLangStr(detectedLang); // retrieve name of detected language as a formatted string
// append language string to current element...
// curElement.innerHTML += '<div style="color: green;" id="mlt_srctxt' + j + '"></div>';
}
// convert a google language code into a formatted string containing the language name
function getFmtLangStr(lang) {
// loop through list of supported languages and retrieve names
for(var l in google.language.Languages) {
if(google.language.Languages[l] == lang) {
// convert language string into title case
var lang = l.substr(0,1) + l.substr(1).toLowerCase();
// improve formatting of 'chinese_simplified' and 'chinese_traditional' language strings
lang = lang.split("_").join(" - ");
break; // stop loop (don't need to continue searching for languages)
}
}
// if language cannot be found in list of supported languages, set language to 'unknown'
if(typeof lang == "undefined") {
lang = "An Unknown Language";
}
return lang; // return formatted language string
}
// find out the most common detected language for all translated chunks in current element, to appear in language string
function findDetectedLang(curTransLang,curTransChunk,transChunksLen) {
var chunkLangs = []; langCounter = 0;
// loop through all translated chunks in current element
for(var i = 0; i < transChunksLen; i++) {
// bugfix: set detected language to 'undefined' if an error occurred during translation...
if(GL_transContent[curTransLang][0][curTransChunk] == null) {
GL_transContent[curTransLang][0][curTransChunk] = new Array(3);
GL_transContent[curTransLang][0][curTransChunk][1] = "undefined";
}
// loop through array of detected languages to see if current chunk has an existing detected language
for(var j = 0; j < chunkLangs.length; j++) {
if(chunkLangs[j][0] == GL_transContent[curTransLang][0][curTransChunk][1]) {
// if so, increment counter containing the total number of chunks with that language
chunkLangs[j][1]++;
break; // halt loop
}
}
// if current chunk has a language not yet detected, add it to end of detected languages array
if(j == chunkLangs.length) {
chunkLangs[j] = new Array(2);
chunkLangs[j][0] = GL_transContent[curTransLang][0][curTransChunk][1]; // name of detected language
chunkLangs[j][1] = 1; // total number of chunks with that language
}
curTransChunk++; // move to next chunk
}
/* once array has been created containing all detected languages in current element, loop through it
to find the most common detected language - language string should contain this */
for(i = 0; i < chunkLangs.length; i++) {
if(chunkLangs[i][1] > langCounter) {
/* if current language was detected more times than all previous languages, store language
and number of times detected - so that next language can be compared against this total */
var detectedLang = chunkLangs[i][0];
langCounter = chunkLangs[i][1];
}
}
return detectedLang; // return the most common detected language
}
// Auto-translate all text added previously by the script (including language strings and error messages)
function transAddedText() {
var allElements = document.getElementsByTagName("*"); // get all elements on page, so relevant ones can be translated
var foundElements = [];
// loop through all elements to find any of class 'mlt_langstring' or 'mlt_transerrtxt'
for(var i=0; i<allElements.length; i++) {
if((allElements[i].className == "mlt_langstring") || (allElements[i].className == "mlt_transerrtxt")) {
foundElements[foundElements.length] = allElements[i];
}
}
// translate all located elements (runs separately from above code to prevent infinite loop as items are translated)
for(i = 0; i < foundElements.length; i++) {
miniTranslate(foundElements[i]); // translate current element
}
}
/* this function runs before any translation takes place, and creates a local 'cache' of all content to be translated (in chunks)
- meaning the content can be submitted to Google more rapidly, and the resulting translations can then be sorted reliably */
function buildChunkedContent() {
var curElement; GL_srcContent = []; var j = 0;
/* loop through all applicable element IDs (as specified at script top), converting the contents of each into chunks,
and storing each chunk in an array */
for(var i = 0; i < GL_classIds.length; i++) {
curElement = document.getElementById(GL_classIds[i][0]); // find out current element
// check that element actually exists on the page - if not, ignore it
if(curElement != null) {
GL_srcContent[j] = createChunks(curElement); // separate the content of current element into chunks
GL_chunksTotal += GL_srcContent[j].length; // store a running total of the number of chunks created
// if a Source Language is not specified for current element, store Base Language in array instead
if(GL_classIds[i].length == 1) {
GL_srcContent[j][GL_srcContent[j].length] = GL_baseLang;
} else {
// otherwise store the specified language (or a blank string if this is to be auto-detected)
GL_srcContent[j][GL_srcContent[j].length] = GL_classIds[i][1];
}
j++;
}
}
// get all elements on page, so that the ones specified can be located
var allElements = document.getElementsByTagName("*");
// loop through all applicable element IDs (as specified at script top), converting into chunks and storing in array
for(var i = 0; i < GL_classNames.length; i++) {
// find all elements which have the current class name
for(var k = 0; k < allElements.length; k++) {
if(allElements[k].className == GL_classNames[i][0]) {
// separate the content of current element into chunks
GL_srcContent[j] = createChunks(allElements[k]);
// store a running total of the number of chunks created
GL_chunksTotal += GL_srcContent[j].length;
// if a Source Language is not specified for current element, store Base Language in array
if(GL_classNames[i].length == 1) {
GL_srcContent[j][GL_srcContent[j].length] = GL_baseLang;
} else {
// otherwise store specified language (or a blank string if auto-detected)
GL_srcContent[j][GL_srcContent[j].length] = GL_classNames[i][1];
}
j++;
}
}
}
}
/* Web browsers (and Google) limit the amount of text translated per request, so split contents of current element into chunks.
The aim is to achieve this whilst maintaining the translation integrity */
function createChunks(srcContent) {
var chars = 1000; // number of characters to allow per chunk.
/* We do NOT want the content inside any HTML tag to be split between chunks (as this could cause
rendering problems), so create 2 arrays storing tags and textual content of current div separately */
var tags = srcContent.innerHTML.match(/<.*?>/g);
var text = srcContent.innerHTML.split(/<.*?>/g);
if(tags == null) {
tags = new Array();} // handle content containing no tags
var curchar = 0; var tagnum = 0; var textnum = 0; var contTotal = tags.length + text.length;
// create an array containing content to be chunked, with tags + text separately re-assembled (in order)
var content = new Array(contTotal);
// loop through content of current div
for(var i=0; i < contTotal; i++) {
// if current position in content is the start of a tag char, add appropriate tag to content array
if(srcContent.innerHTML.substr(curchar,1) == "<") {
content[i] = tags[tagnum];
curchar += tags[tagnum].length;
tagnum++;
// if it is a text string, add the corresponding text to the curent element in content array
} else {
content[i] = text[textnum];
curchar += text[textnum].length;
textnum++;
}
}
// Create the chunks - don't split either tags or words (to ensure as high translation quality as possible)
var chunks = []; var curChunk = 0;
chunks[0]="";
for (i = 0; i < contTotal; i++) {
// if next content item (tag or textual) won't exceed length of current chunk, add it to chunk
if((chunks[curChunk].length + content[i].length) < chars) {
chunks[curChunk] += content[i];
} else {
// otherwise, proceed to next chunk.
curChunk++;
// add the entire content item to this chunk if possible (to ensure better translation)
if(content[i].length < chars) {
chunks[curChunk] = content[i];
}
else {
// only split further in rare cases where text length exceeds maximum chunk size
var curPos = 0;
do {
// retrieve the maximum amount of text that can fit in this chunk
var subContent = content[i].substr(curPos,chars);
// find out how many words are in this substring
var words = subContent.split(" ");
// chop off final word, so words aren't split up between chunks
var lastWordPos = subContent.length - words[(words.length-1)].length;
if(subContent.length < chars) { // [bugfix: prevent word cut-off on final iteration]
lastWordPos = subContent.length}
chunks[curChunk] = subContent.substr(0,lastWordPos); // store in chunk
curChunk++; // remainder of text will go in next chunk
curPos+=lastWordPos; // store current position in text, for further processing
} while(subContent.length >= chars); // repeat until all this text has been chunked
curChunk--; // because there may still be space in the current chunk!
}
}
}
return chunks; // return chunked content to calling function...
}
// Append elements to page (will be used to display translation messages), and specify their css styles.
function addTransMsgs() {
// add element to page which will contain translation messages
var transCont = document.createElement("div");
document.body.appendChild(transCont);
// add element to container created above - this will display the translation messages
var translateMsg = document.createElement("div");
translateMsg.id = "mlt_translatemsg";
transCont.appendChild(translateMsg);
// define visual styles for translation messages displayed on screen
translateMsg.style.backgroundColor = "silver";
translateMsg.style.border = "3px green solid";
translateMsg.style.padding = "5px";
translateMsg.style.fontSize = "large";
translateMsg.style.fontWeight = "bold";
translateMsg.style.textAlign = "left";
translateMsg.style.color = "black";
// more translation message styles (these should not need editing!)
translateMsg.style.left = "-50%";
translateMsg.style.position = "relative";
translateMsg.style.display = "none";
// define the styles for the container element
transCont.style.left = "50%";
transCont.style.zIndex = "1000";
if(!(/MSIE 6/i.test(navigator.userAgent))) {
// styles for all browsers except IE6
transCont.style.position = "fixed";
transCont.style.top = "0px";
}
else {
// styles for IE6
transCont.style.position = "absolute";
transCont.style.setExpression("top", "(i = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + 'px'");
}
}
// Hide 'Translating...' message (or translation error message) - runs at end of translation, or if user dismisses error message
function hideTransMsg() {
document.getElementById("mlt_translatemsg").innerHTML = "";
document.getElementById("mlt_translatemsg").style.display='none';
}
// if the user clicks on the 'Details' link [after error(s) occurred], show details of all errors on screen
function showErrDetails() {
// continue to show original error message (but remove 'Details' link)
document.getElementById("mlt_translatemsg").innerHTML = '<span id="mlt_transerrmsg1">' + GL_errors.length +
' Problems(s) Occurred During Translation: ' + '<a href="javascript:refresh()">Retry</a> - ' +
'<a href="javascript:hideTransMsg()">Hide</a>... <br /><em>Error(s) Reported:</em></span>' +
'<ul style="margin: 0px; padding: 0px;" id="mlt_transerrlist"></ul>';
// Loop through array containing details of all errors, and show them as a list on screen
for(var i = 0; i < GL_errors.length; i++) {
document.getElementById("mlt_transerrlist").innerHTML += '<li style="margin-left: 15px;">' + GL_errors[i] + '.</li> ';
}
/* create a textarea - this will show the original source text of all affected sections (as HTML) to aid debugging
Note: because translations are returned using AJAX, the affected sections are not NECESSARILY in the same order as
the errors reported (though in many cases, they will be!) */
document.getElementById("mlt_translatemsg").innerHTML += '<em id="mlt_transerrmsg2">Section(s) Affected:</em><br />' +
'<textarea id="mlt_errsrctxt" rows="8" readonly="readonly" style="width: 99%; background-color: silver; border: 1px gray solid;">' +
'</textarea>';
// Loop through Source Text array, appending to textarea.
for(var i = 0; i < GL_errSrcTxt.length; i++) {
document.getElementById("mlt_errsrctxt").value += "Affected Section " + (i+1) + ":\n" + GL_errSrcTxt[i] + "\n\n";
}
// Translate the entire contents of the Translation Errors box (with the exception of the text inside the textarea)
miniTranslate(document.getElementById("mlt_transerrmsg1")); miniTranslate(document.getElementById("mlt_transerrlist"));
miniTranslate(document.getElementById("mlt_transerrmsg2"));
}
// function runs when the user clicks on a link to view the original source text for a translated element / chunk
function showSrcTxt(curLinkId,curClassNum,curChunkId) {
// if the current chunk should be shown only, display chunk on screen
if((curChunkId-1) != -1) {
document.getElementById("mlt_srctxt"+curLinkId).innerHTML +=
'<div id="mlt_srctxtcontent' + curLinkId + '">'+GL_srcContent[curClassNum][(curChunkId-1)]+']</div>';
} else {
// otherwise assemble all chunks for current element, and display on screen
var srcTxt = "";
for(var i = 0; i < (GL_srcContent[curClassNum].length - 1); i++) {
srcTxt += GL_srcContent[curClassNum][i];
}
document.getElementById("mlt_srctxt"+curLinkId).innerHTML +=
'<div id="mlt_srctxtcontent' + curLinkId + '">'+srcTxt+']</div>';
}
// update Source Text link so that when clicked in future, the source text will be hidden instead...
srcTxtLnk = document.getElementById("mlt_srctxtlnk"+curLinkId);
srcTxtLnk.innerHTML = "Hide Source Text [-]";
srcTxtLnk.href = 'javascript:hideSrcTxt(' + curLinkId + ',' + curClassNum + ',' + curChunkId + ')';
miniTranslate(srcTxtLnk); // translate link text
document.getElementById("mlt_srctxtbracket"+curLinkId).innerHTML = ""; // hide bracket after link
}
// function runs when the user clicks on a link to hide the original source text for a translated element / chunk
function hideSrcTxt(curLinkId,curClassNum,curChunkId) {
// remove the element containing the original source text
srcTxtContent = document.getElementById("mlt_srctxtcontent"+curLinkId);
document.getElementById("mlt_srctxt"+curLinkId).removeChild(srcTxtContent);
// update Source Text link so that when clicked in future, the source text will be shown instead...
srcTxtLnk = document.getElementById("mlt_srctxtlnk"+curLinkId);
srcTxtLnk.innerHTML = "View Source Text [+]";
srcTxtLnk.href = 'javascript:showSrcTxt(' + curLinkId + ',' + curClassNum + ',' + curChunkId + ')';
miniTranslate(srcTxtLnk); // translate link text
document.getElementById("mlt_srctxtbracket"+curLinkId).innerHTML = "]"; // show bracket after link
}
// translate small non crucial items of text into current site language
function miniTranslate(item,destLang,srcTxt) {
if(typeof destLang == "undefined") {
var destLang = GL_curLang; // if the destLang argument was not specified, use the current site language
}
if(typeof srcTxt == "undefined") {
var srcTxt = item.innerHTML; // if the srcText argument was not specified, use the current item contents
}
// loop through translated items array to see if a translation for current text already exists since page loaded
for(var i = 0; i < GL_miniTransItems.length; i++) {
// check if source text and destination language match a translated item (and a completed translation exists for it)
if((GL_miniTransItems[i][1] == srcTxt) && (GL_miniTransItems[i][2] == destLang) && (GL_miniTransItems[i][3] != "")) {
item.innerHTML = GL_miniTransItems[i][3]; // if so, display existing translation in item
item.title = srcTxt.split(/<.*?>/g).join(""); // display English source text as a tooltip (strip HTML first)
return; // Don't need to send a translation request to Google, so end function.
}
}
// store item to be translated in global array for access by callback function
GL_miniTransItems[GL_miniTransItems.length] = new Array(4);
GL_miniTransItems[(GL_miniTransItems.length-1)][0] = item;
GL_miniTransItems[(GL_miniTransItems.length-1)][1] = srcTxt;
GL_miniTransItems[(GL_miniTransItems.length-1)][2] = destLang;
GL_miniTransItems[(GL_miniTransItems.length-1)][3] = "";
// create source text by adding current item ID to start of item text (ID will ensure correct item is translated)
srcTxt = (GL_miniTransItems.length-1) + "<br />" + srcTxt;
google.language.translate(srcTxt, "en", destLang, function(result) {
if (!result.error) {
// split into array based on separator, so we know the id of translated item
var transChunk = result.translation.split("<br />");
// [find out length of substring to chop off from start of item]
var chunkSubStr = 6 + transChunk[0].length;
// remove whitespace from item id (a problem with some translations)
transChunk[0] = transChunk[0].replace(/^\s+|\s+$/g,"");
// display english source text of translated item (with HTML stripped) if user hovers mouse over it
var strippedSrcTxt = GL_miniTransItems[transChunk[0]][1].split(/<.*?>/g).join("");
GL_miniTransItems[transChunk[0]][0].title = "[" + strippedSrcTxt + "]";
// store and display translation of specified item (stripping item ID from start of text)
GL_miniTransItems[transChunk[0]][3] = result.translation.substr(chunkSubStr);
GL_miniTransItems[transChunk[0]][0].innerHTML = GL_miniTransItems[transChunk[0]][3];
}
});
}
// runs when the user changes the site language
function changeLang(destLang) {
if(typeof destLang != "undefined") {
GL_curLang = destLang; // if the destLang argument was specified, set new site language to this
document.getElementById("mlt_language").value = GL_curLang; // change listbox to display new site language
} else {
// otherwise get the new language requested by user
GL_curLang = document.getElementById("mlt_language").value;
}
// store the requested language in a cookie
setLangCookie();
// if the original site languages should be shown, refresh the page.
if(GL_curLang == "orig") {
refresh();
return;
}
// otherwise, start the translation
startTranslation();
}
// find out the value of the language cookie (if it exists)
function getLangCookie() {
var curStoredLang;
// retrieve a list of cookies for this page, split into array elements (separated by ; if multiple cookies)
var getCurLang=document.cookie.split(";");
// loop through all array elements (i.e. cookies) until one with name 'lang' is found.
for(var i=0; i < getCurLang.length; i++) {
// remove whitespace from cookies (a problem if there are multiple cookies)
var lngCookie = getCurLang[i].replace(/^\s+|\s+$/g,"");
if(lngCookie.indexOf("lang=") == 0) {
// find out value of lang
curStoredLang = lngCookie.substring(5);
}
}
// if language cookie exists, set current site language to stored value
if(typeof curStoredLang != "undefined") {
GL_curLang = curStoredLang;
// otherwise, check if an initial language has been specified
} else if((GL_curLang == "") || (typeof GL_curLang == "undefined")) {
detectUserLang(); // if not, find out user's language based on their settings, and offer to translate into that language
GL_curLang = "orig"; // show site using original languages for now
return; // don't want to store language in cookie until one has been specified, so end function
}
setLangCookie(); // if valid cookie exists or initial language was specified, set/renew cookie (to store new expiry date)
}
// If a new user has not specified a language yet, offer to translate page into their current browser / system language
function detectUserLang(){
/* detect user's current language (if they are using IE this will be based on the regional settings on their system;
otherwise it will be based on the default language of their current browser) */
var detectedLang = (navigator.language) ? navigator.language : navigator.userLanguage;
// if language cannot be detected for some reason, end function.
if((typeof detectedLang == "undefined") || (detectedLang == "")) {
return;
}
// if language is regional dialect (e.g. "en-gb"), check last 2 letters are upper case - for google compatibility.
if(detectedLang.length == 5) {
detectedLang = detectedLang.substr(0,3) + detectedLang.substr(3).toUpperCase();
}
// check that Google can translate content into detected language
if (!google.language.isTranslatable(detectedLang)) {
// if not, check if language is a regional dialect (e.g. "en-GB")
if(detectedLang.length == 5) {
// if so, Google may still be able to translate into a non-regional equivalent (e.g. "en")
detectedLang = detectedLang.substr(0,2);
if (!google.language.isTranslatable(detectedLang)) {
return; // google cannot translate into non-regional equivalent, so end function
}
// language is not a regional dialect, and google cannot translate into it, so end function
} else {
return;
}
}
var detectedLangStr = getFmtLangStr(detectedLang); // retrieve name of detected language as a formatted string
/*
// display message asking user if they want to translate current page into detected language
document.getElementById("mlt_translatemsg").innerHTML = 'Translate this page into ' + detectedLangStr + '? ' +
'<a href="javascript:changeLang(\'' + detectedLang + '\')">Yes</a> | <a href="javascript:changeLang(\'orig\')">No</a>';
miniTranslate(document.getElementById("mlt_translatemsg"),detectedLang); // translate question into detected language
document.getElementById("mlt_translatemsg").style.display='block'; // show the question on screen
*/
// display message asking user if they want to translate current page into detected language
document.getElementById("mlt_translatemsg").innerHTML = '';
miniTranslate(document.getElementById("mlt_translatemsg"),detectedLang); // translate question into detected language
document.getElementById("mlt_translatemsg").style.display='none'; // show the question on screen
}
// create a cookie to store the current site language
function setLangCookie() {
// expire previous cookie (if it exists)
document.cookie = "lang=; expires=-1; path=/";
// cookie will expire after 90 days.
var expdate = new Date();
expdate.setTime(expdate.getTime()+7776000000);
// create the cookie
document.cookie = "lang=" + GL_curLang + "; expires=" + expdate.toGMTString() + "; path=/";
}
// refresh the current page [runs if the Original Languages option was selected, or if requested by user after error(s)]
function refresh() {
hideTransMsg();
window.location.reload(true);
}
// run the 'initialise' function once the page has loaded.
google.setOnLoadCallback(initialise);
****************The End*****************************
*****************Save it as googlelanguage.js******************
if (!window['google']) {
window['google'] = {};
}
if (!window['google']['loader']) {
window['google']['loader'] = {};
google.loader.ServiceBase = 'http://www.google.com/uds';
google.loader.GoogleApisBase = 'http://ajax.googleapis.com/ajax';
google.loader.ApiKey = 'notsupplied';
google.loader.KeyVerified = true;
google.loader.LoadFailure = false;
google.loader.Secure = false;
google.loader.GoogleLocale = 'www.google.com';
google.loader.ClientLocation = {"latitude":17.385044,"longitude":78.486671,"address":{"city":"Hyderabad","region":"Andhra Pradesh","country":"India","country_code":"IN"}};
google.loader.AdditionalParams = '';
(function() {var d=true,g=null,h=false,j=encodeURIComponent,l=window,n=undefined,o=document;function p(a,b){return a.load=b}var q="push",r="replace",s="charAt",t="ServiceBase",u="name",v="getTime",w="length",x="prototype",y="setTimeout",z="loader",A="substring",B="join",C="toLowerCase";function D(a){if(a in E)return E[a];return E[a]=navigator.userAgent[C]().indexOf(a)!=-1}var E={};function F(a,b){var c=function(){};c.prototype=b[x];a.Q=b[x];a.prototype=new c}
function G(a,b){var c=Array[x].slice.call(arguments,2)||[];return function(){var e=c.concat(Array[x].slice.call(arguments));return a.apply(b,e)}}function H(a){a=Error(a);a.toString=function(){return this.message};return a}function I(a,b){for(var c=a.split(/\./),e=l,f=0;f<c[w]-1;f++){e[c[f]]||(e[c[f]]={});e=e[c[f]]}e[c[c[w]-1]]=b}function J(a,b,c){a[b]=c}if(!K)var K=I;if(!L)var L=J;google[z].t={};K("google.loader.callbacks",google[z].t);var M={},N={};google[z].eval={};K("google.loader.eval",google[z].eval);
p(google,function(a,b,c){function e(k){var m=k.split(".");if(m[w]>2)throw H("Module: '"+k+"' not found!");else if(typeof m[1]!="undefined"){f=m[0];c.packages=c.packages||[];c.packages[q](m[1])}}var f=a;c=c||{};if(a instanceof Array||a&&typeof a=="object"&&typeof a[B]=="function"&&typeof a.reverse=="function")for(var i=0;i<a[w];i++)e(a[i]);else e(a);if(a=M[":"+f]){if(c&&!c.language&&c.locale)c.language=c.locale;if(c&&typeof c.callback=="string"){i=c.callback;if(i.match(/^[[\]A-Za-z0-9._]+$/)){i=l.eval(i);
c.callback=i}}if((i=c&&c.callback!=g)&&!a.s(b))throw H("Module: '"+f+"' must be loaded before DOM onLoad!");else if(i)a.m(b,c)?l[y](c.callback,0):a.load(b,c);else a.m(b,c)||a.load(b,c)}else throw H("Module: '"+f+"' not found!");});K("google.load",google.load);
google.P=function(a,b){if(b){if(O[w]==0){P(l,"load",Q);if(!D("msie")&&!(D("safari")||D("konqueror"))&&D("mozilla")||l.opera)l.addEventListener("DOMContentLoaded",Q,h);else if(D("msie"))o.write("<script defer onreadystatechange='google.loader.domReady()' src=//:><\/script>");else(D("safari")||D("konqueror"))&&l[y](S,10)}O[q](a)}else P(l,"load",a)};K("google.setOnLoadCallback",google.P);
function P(a,b,c){if(a.addEventListener)a.addEventListener(b,c,h);else if(a.attachEvent)a.attachEvent("on"+b,c);else{var e=a["on"+b];a["on"+b]=e!=g?aa([c,e]):c}}function aa(a){return function(){for(var b=0;b<a[w];b++)a[b]()}}var O=[];google[z].K=function(){var a=l.event.srcElement;if(a.readyState=="complete"){a.onreadystatechange=g;a.parentNode.removeChild(a);Q()}};K("google.loader.domReady",google[z].K);var ba={loaded:d,complete:d};function S(){if(ba[o.readyState])Q();else O[w]>0&&l[y](S,10)}
function Q(){for(var a=0;a<O[w];a++)O[a]();O.length=0}
google[z].d=function(a,b,c){if(c){var e;if(a=="script"){e=o.createElement("script");e.type="text/javascript";e.src=b}else if(a=="css"){e=o.createElement("link");e.type="text/css";e.href=b;e.rel="stylesheet"}(a=o.getElementsByTagName("head")[0])||(a=o.body.parentNode.appendChild(o.createElement("head")));a.appendChild(e)}else if(a=="script")o.write('<script src="'+b+'" type="text/javascript"><\/script>');else a=="css"&&o.write('<link href="'+b+'" type="text/css" rel="stylesheet"></link>')};
K("google.loader.writeLoadTag",google[z].d);google[z].M=function(a){N=a};K("google.loader.rfm",google[z].M);google[z].O=function(a){for(var b in a)if(typeof b=="string"&&b&&b[s](0)==":"&&!M[b])M[b]=new T(b[A](1),a[b])};K("google.loader.rpl",google[z].O);google[z].N=function(a){if((a=a.specs)&&a[w])for(var b=0;b<a[w];++b){var c=a[b];if(typeof c=="string")M[":"+c]=new U(c);else{c=new V(c[u],c.baseSpec,c.customSpecs);M[":"+c[u]]=c}}};K("google.loader.rm",google[z].N);
google[z].loaded=function(a){M[":"+a.module].k(a)};K("google.loader.loaded",google[z].loaded);google[z].J=function(){return"qid="+((new Date)[v]().toString(16)+Math.floor(Math.random()*1E7).toString(16))};K("google.loader.createGuidArg_",google[z].J);I("google_exportSymbol",I);I("google_exportProperty",J);google[z].b={};K("google.loader.themes",google[z].b);google[z].b.z="http://www.google.com/cse/style/look/bubblegum.css";L(google[z].b,"BUBBLEGUM",google[z].b.z);google[z].b.B="http://www.google.com/cse/style/look/greensky.css";
L(google[z].b,"GREENSKY",google[z].b.B);google[z].b.A="http://www.google.com/cse/style/look/espresso.css";L(google[z].b,"ESPRESSO",google[z].b.A);google[z].b.D="http://www.google.com/cse/style/look/shiny.css";L(google[z].b,"SHINY",google[z].b.D);google[z].b.C="http://www.google.com/cse/style/look/minimalist.css";L(google[z].b,"MINIMALIST",google[z].b.C);function U(a){this.a=a;this.q=[];this.p={};this.i={};this.e={};this.l=d;this.c=-1}
U[x].g=function(a,b){var c="";if(b!=n){if(b.language!=n)c+="&hl="+j(b.language);if(b.nocss!=n)c+="&output="+j("nocss="+b.nocss);if(b.nooldnames!=n)c+="&nooldnames="+j(b.nooldnames);if(b.packages!=n)c+="&packages="+j(b.packages);if(b.callback!=g)c+="&async=2";if(b.style!=n)c+="&style="+j(b.style);if(b.other_params!=n)c+="&"+b.other_params}if(!this.l){if(google[this.a]&&google[this.a].JSHash)c+="&sig="+j(google[this.a].JSHash);var e=[];for(var f in this.p)f[s](0)==":"&&e[q](f[A](1));for(f in this.i)f[s](0)==
":"&&this.i[f]&&e[q](f[A](1));c+="&have="+j(e[B](","))}return google[z][t]+"/?file="+this.a+"&v="+a+google[z].AdditionalParams+c};U[x].v=function(a){var b=g;if(a)b=a.packages;var c=g;if(b)if(typeof b=="string")c=[a.packages];else if(b[w]){c=[];for(a=0;a<b[w];a++)typeof b[a]=="string"&&c[q](b[a][r](/^\s*|\s*$/,"")[C]())}c||(c=["default"]);b=[];for(a=0;a<c[w];a++)this.p[":"+c[a]]||b[q](c[a]);return b};
p(U[x],function(a,b){var c=this.v(b),e=b&&b.callback!=g;if(e)var f=new W(b.callback);for(var i=[],k=c[w]-1;k>=0;k--){var m=c[k];e&&f.F(m);if(this.i[":"+m]){c.splice(k,1);e&&this.e[":"+m][q](f)}else i[q](m)}if(c[w]){if(b&&b.packages)b.packages=c.sort()[B](",");for(k=0;k<i[w];k++){m=i[k];this.e[":"+m]=[];e&&this.e[":"+m][q](f)}if(!b&&N[":"+this.a]!=g&&N[":"+this.a].versions[":"+a]!=g&&!google[z].AdditionalParams&&this.l){c=N[":"+this.a];google[this.a]=google[this.a]||{};for(var R in c.properties)if(R&&
R[s](0)==":")google[this.a][R[A](1)]=c.properties[R];google[z].d("script",google[z][t]+c.path+c.js,e);c.css&&google[z].d("css",google[z][t]+c.path+c.css,e)}else if(!b||!b.autoloaded)google[z].d("script",this.g(a,b),e);if(this.l){this.l=h;this.c=(new Date)[v]();if(this.c%100!=1)this.c=-1}for(k=0;k<i[w];k++){m=i[k];this.i[":"+m]=d}}});
U[x].k=function(a){if(this.c!=-1){X("al_"+this.a,"jl."+((new Date)[v]()-this.c),d);this.c=-1}this.q=this.q.concat(a.components);google[z][this.a]||(google[z][this.a]={});google[z][this.a].packages=this.q.slice(0);for(var b=0;b<a.components[w];b++){this.p[":"+a.components[b]]=d;this.i[":"+a.components[b]]=h;var c=this.e[":"+a.components[b]];if(c){for(var e=0;e<c[w];e++)c[e].I(a.components[b]);delete this.e[":"+a.components[b]]}}X("hl",this.a)};U[x].m=function(a,b){return this.v(b)[w]==0};U[x].s=function(){return d};
function W(a){this.H=a;this.n={};this.r=0}W[x].F=function(a){this.r++;this.n[":"+a]=d};W[x].I=function(a){if(this.n[":"+a]){this.n[":"+a]=h;this.r--;this.r==0&&l[y](this.H,0)}};function V(a,b,c){this.name=a;this.G=b;this.o=c;this.u=this.h=h;this.j=[];google[z].t[this[u]]=G(this.k,this)}F(V,U);p(V[x],function(a,b){var c=b&&b.callback!=g;if(c){this.j[q](b.callback);b.callback="google.loader.callbacks."+this[u]}else this.h=d;if(!b||!b.autoloaded)google[z].d("script",this.g(a,b),c);X("el",this[u])});V[x].m=function(a,b){return b&&b.callback!=g?this.u:this.h};V[x].k=function(){this.u=d;for(var a=0;a<this.j[w];a++)l[y](this.j[a],0);this.j=[]};
var Y=function(a,b){return a.string?j(a.string)+"="+j(b):a.regex?b[r](/(^.*$)/,a.regex):""};V[x].g=function(a,b){return this.L(this.w(a),a,b)};
V[x].L=function(a,b,c){var e="";if(a.key)e+="&"+Y(a.key,google[z].ApiKey);if(a.version)e+="&"+Y(a.version,b);b=google[z].Secure&&a.ssl?a.ssl:a.uri;if(c!=g)for(var f in c)if(a.params[f])e+="&"+Y(a.params[f],c[f]);else if(f=="other_params")e+="&"+c[f];else if(f=="base_domain")b="http://"+c[f]+a.uri[A](a.uri.indexOf("/",7));google[this[u]]={};if(b.indexOf("?")==-1&&e)e="?"+e[A](1);return b+e};V[x].s=function(a){return this.w(a).deferred};
V[x].w=function(a){if(this.o)for(var b=0;b<this.o[w];++b){var c=this.o[b];if(RegExp(c.pattern).test(a))return c}return this.G};function T(a,b){this.a=a;this.f=b;this.h=h}F(T,U);p(T[x],function(a,b){this.h=d;google[z].d("script",this.g(a,b),h)});T[x].m=function(){return this.h};T[x].k=function(){};
T[x].g=function(a,b){if(!this.f.versions[":"+a]){if(this.f.aliases){var c=this.f.aliases[":"+a];if(c)a=c}if(!this.f.versions[":"+a])throw H("Module: '"+this.a+"' with version '"+a+"' not found!");}c=google[z].GoogleApisBase+"/libs/"+this.a+"/"+a+"/"+this.f.versions[":"+a][b&&b.uncompressed?"uncompressed":"compressed"];X("el",this.a);return c};T[x].s=function(){return h};var ca=h,Z=[],da=(new Date)[v](),X=function(a,b,c){if(!ca){P(l,"unload",ea);ca=d}if(c){if(!google[z].Secure&&(!google[z].Options||google[z].Options.csi===h)){a=a[C]()[r](/[^a-z0-9_.]+/g,"_");b=b[C]()[r](/[^a-z0-9_.]+/g,"_");l[y](G($,g,"http://csi.gstatic.com/csi?s=uds&v=2&action="+j(a)+"&it="+j(b)),1E4)}}else{Z[q]("r"+Z[w]+"="+j(a+(b?"|"+b:"")));l[y](ea,Z[w]>5?0:15E3)}},ea=function(){if(Z[w]){$(google[z][t]+"/stats?"+Z[B]("&")+"&nc="+(new Date)[v]()+"_"+((new Date)[v]()-da));Z.length=0}},$=function(a){var b=
new Image,c=fa++;ga[c]=b;b.onload=b.onerror=function(){delete ga[c]};b.src=a;b=g},ga={},fa=0;I("google.loader.recordStat",X);I("google.loader.createImageForLogging",$);
}) ();google.loader.rm({"specs":[{"name":"books","baseSpec":{"uri":"http://books.google.com/books/api.js","ssl":null,"key":{"string":"key"},"version":{"string":"v"},"deferred":true,"params":{"callback":{"string":"callback"},"language":{"string":"hl"}}}},"feeds",{"name":"friendconnect","baseSpec":{"uri":"http://www.google.com/friendconnect/script/friendconnect.js","ssl":null,"key":{"string":"key"},"version":{"string":"v"},"deferred":false,"params":{}}},"spreadsheets","gdata","visualization",{"name":"sharing","baseSpec":{"uri":"http://www.google.com/s2/sharing/js","ssl":null,"key":{"string":"key"},"version":{"string":"v"},"deferred":false,"params":{"language":{"string":"hl"}}}},"search",{"name":"maps","baseSpec":{"uri":"http://maps.google.com/maps?file\u003dgoogleapi","ssl":"https://maps-api-ssl.google.com/maps?file\u003dgoogleapi","key":{"string":"key"},"version":{"string":"v"},"deferred":true,"params":{"callback":{"regex":"callback\u003d$1\u0026async\u003d2"},"language":{"string":"hl"}}},"customSpecs":[{"uri":"http://maps.google.com/maps/api/js","ssl":"https://maps-api-ssl.google.com/maps/api/js","key":{"string":"key"},"version":{"string":"v"},"deferred":true,"params":{"callback":{"string":"callback"},"language":{"string":"hl"}},"pattern":"^(3|3..*)$"}]},"annotations_v2","wave","orkut",{"name":"annotations","baseSpec":{"uri":"http://www.google.com/reviews/scripts/annotations_bootstrap.js","ssl":null,"key":{"string":"key"},"version":{"string":"v"},"deferred":true,"params":{"callback":{"string":"callback"},"language":{"string":"hl"},"country":{"string":"gl"}}}},"language","earth","ads","elements"]});
google.loader.rfm({":search":{"versions":{":1":"1",":1.0":"1"},"path":"/api/search/1.0/2a8ff2a70ad0b091ae9dfd8b5e832141/","js":"default+en.I.js","css":"default.css","properties":{":JSHash":"2a8ff2a70ad0b091ae9dfd8b5e832141",":NoOldNames":false,":Version":"1.0"}},":language":{"versions":{":1":"1",":1.0":"1"},"path":"/api/language/1.0/62c64af2122d2da7dcb0087852fa7396/","js":"default+en.I.js","properties":{":JSHash":"62c64af2122d2da7dcb0087852fa7396",":Version":"1.0"}},":wave":{"versions":{":1":"1",":1.0":"1"},"path":"/api/wave/1.0/3b6f7573ff78da6602dda5e09c9025bf/","js":"default.I.js","properties":{":JSHash":"3b6f7573ff78da6602dda5e09c9025bf",":Version":"1.0"}},":spreadsheets":{"versions":{":0":"1",":0.3":"1"},"path":"/api/spreadsheets/0.3/8331b0bbcc74776270648505340e9200/","js":"default.I.js","properties":{":JSHash":"8331b0bbcc74776270648505340e9200",":Version":"0.3"}},":earth":{"versions":{":1":"1",":1.0":"1"},"path":"/api/earth/1.0/819ffbf1e363d238791231792a2e0a90/","js":"default.I.js","properties":{":JSHash":"819ffbf1e363d238791231792a2e0a90",":Version":"1.0"}},":annotations":{"versions":{":1":"1",":1.0":"1"},"path":"/api/annotations/1.0/11cfaf30c00ca64601d09fcac7dd8bc7/","js":"default+en.I.js","properties":{":JSHash":"11cfaf30c00ca64601d09fcac7dd8bc7",":Version":"1.0"}}});
google.loader.rpl({":scriptaculous":{"versions":{":1.8.3":{"uncompressed":"scriptaculous.js","compressed":"scriptaculous.js"},":1.8.2":{"uncompre
以上是关于JavaScript 使用Google API使Web应用程序成为多语言......对PHP,Dotnet和其他语言开发人员有用的主要内容,如果未能解决你的问题,请参考以下文章
使 JavaScript Google API 地理编码发生在鼠标点击而不是页面加载上
Youtube视频w/Javascript API-自动播放和静音
我如何使Figma API与Google App脚本API一起使用?