I’m currently developing a Greasemonkey script to translate <textarea> fields in an Intranet app, using Google Translation API.
But some texts are way too large to be translated with only one request. I get this error when trying :
Request entity too large
Anyway, I found a way to cut the texts in fragments, and send them in separate requests. Where it gets tricky, is how I should replace those fragments in their original textareas, and especially at the right place.
After trying several methods without any success, I inserted placeholders in the textarea, corresponding to the fragments of text that have to be translated :
{1}
{2}
...
But now in the success callback of my XHR, I have to replace the placeholder with the translated text. The thing is, my XHR is inside a for loop, iterating over my table containing the fragments of original text, and when the requests finish, the loop is long finished and I don’t know how to get where to put the translation.
Here’s the code :
//Array text[] contains the fragments of original text
var translated_text = [];
var l = text.length;
for(var i = 0; i < l; i++)
{
var fullurl = apiurl+encodeURIComponent(text[i]);
GM_xmlhttpRequest({
method: 'GET',
url: fullurl,
headers:
{
'User-agent': 'Mozilla/5.0 (compatible) Greasemonkey',
'Accept': 'application/atom+xml,application/xml,text/xml',
},
onload: function(responseDetails)
{
var destination = "{"+i+"}";
if(responseDetails.status == 200)
{
var data = $.parseJSON(responseDetails.responseText);
translated_text[i] = data.responseData.translatedText.replace(/"/g,"\"").replace(/'/g,"\"").replace(/>/g,">");
textarea.text(textarea.text().replace("{"+i+"}",translated_text[i]));
}
else
{
alert('Request Failed : '+responseDetails.status+"\nError : "+responseDetails.statusText);
}
}
});
}
PS : I cannot use jQuery’s AJAX methods, because this is a Cross Domain request, so the new $.when functionality cannot be used here (sadly)
Update: With newer versions of Greasemonkey and Tampermonkey, you can now pass a
contextDoc:For other/older platforms, to use the value of
i, you need to wrap it in a JavaScript closure. One way to do do that is: