User:Gryllida/ExternalTranslate.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
Documentation for this user script can be added at User:Gryllida/ExternalTranslate. This user script seems to have an accompanying .css page at User:Gryllida/ExternalTranslate.css. |
// So that this doesn't interfere with var names of anything else
if (typeof ExternalTranslate === "undefined") ExternalTranslate = {};
if (!ExternalTranslate.l18n) {
ExternalTranslate.l18n = {
tab: 'Translate',
tab_tooltip: 'Translate this page to another language.',
}
}
ExternalTranslate.init = function() {
mw.util.addPortletLink(
"p-cactions",
"javascript:ExternalTranslate.init.start();void%200;",
ExternalTranslate.l18n.tab,
"ca-orNotes",
ExternalTranslate.l18n.tab_tooltip
);
importStylesheet('User:Gryllida/ExternalTranslate.css');
};
if(!ExternalTranslate.Loader) ExternalTranslate.Loader = {};
ExternalTranslate.Loader.loadOriginal = function() {
// XXX Make proper use of MediaWiki API here.
var page;
// Retrieve HTML for the translate interface
(new mw.Api()).get( {
prop: 'revisions',
rvprop: 'content',
rvlimit: 1,
indexpageids: true,
titles: mw.config.get('wgPageName')
} )
.done( function ( json ) {
$.each(json.query.pages, function (pageid, page) {
page = page.revisions[0]['*'];
$.each(page.split("\n"), function (num, line) {
if ($.trim(line).length != 0){
var td = $("<td></td>");
ExternalTranslate.DOM.markup2box(line, td);
// XXX Localise
tr = $('<tr><td class="ok input"><textarea class="copy"></textarea><br><button onclick="ExternalTranslate.DOM.displaySmallPreview(this);">Preview</button><button onclick="ExternalTranslate.DOM.deleteRow(this);">×</button><button onclick="ExternalTranslate.DOM.addRow(this);">+</button></td><td></td></tr>');
tr.prepend(td);
$('#table1').append(tr);
}
});
});
});
// var apiUrl = 'https://'+$('#lang_from').val()+'.'+$('#project_name').val() + '.org/w/api.php?action=query&prop=revisions&rvprop=content&format=json&callback=?&titles=';
// var url = apiUrl + encodeURIComponent($('#headline_from').val());
$('#preview_button').prop('disabled', false);
}
ExternalTranslate.Loader.displayPreview = function() {
$('#field2').text('');
var markup="";
$('.copy').each(function (index, field){
if ($(field).val() != ""){
ExternalTranslate.DOM.markup2box($(field).val(), $('#field2'));
}
});
ExternalTranslate.DOM.markup2html2box($('#field2').text(), $('#preview_cell'));
}
if(!ExternalTranslate.DOM) ExternalTranslate.DOM = {};
ExternalTranslate.DOM.displaySmallPreview = function (button_obj){
var parent = $(button_obj).parent();
ExternalTranslate.DOM.markup2html2box(parent.find(">:first-child").val(), parent.next());
}
ExternalTranslate.DOM.markup2html2box = function(markup, box){
var url = 'https://'+$('#lang_to').val()+'.'+$('#project_name').val()+'.org/w/api.php?action=parse&format=json&text='+encodeURIComponent(markup)+'&prop=text&format=json&callback=?';
var html;
prefix = "https://"+$('#lang_to').val()+'.'+$('#project_name').val()+'.org';
$.getJSON(url, function(json) {
html = $($.parseHTML(json.parse.text['*']));
html.find('a').attr('href', function(i, attr) {
return prefix + attr;
});
html.find('img').attr('src', function(i, attr) {
return 'https:' + attr;
});
box.html(html);
// $(w.document.body).html(html); // popups are not usable
});
}
ExternalTranslate.DOM.markup2box = function(markup, box){
// box.text(markup).html();
box.append(document.createTextNode(markup));
box.append("\n\n");
}
ExternalTranslate.DOM.deleteRow = function(button){
$(button).parent().parent().remove();
}
ExternalTranslate.DOM.addRow = function(button){
$('<tr><td></td><td class="ok"><textarea class="copy"></textarea><br><button onclick="ExternalTranslate.Loader.displaySmallPreview(this);">Preview</button><button onclick="ExternalTranslate.DOM.deleteRow(this);">-</button><button onclick="ExternalTranslate.DOM.addRow(this);">+</button></td><td></td></tr>').insertAfter($(button).parent().parent());
}
if(!ExternalTranslate.Translator) ExternalTranslate.Translator = {};
ExternalTranslate.Translator.translateWord = function(){
var url = "https://";
url += $('#lang_from').val();
url += ".wiki.x.io/w/api.php?action=query&prop=langlinks&titles=";
url += encodeURIComponent($('#word').val());
url += "&redirects=&lllang=";
url += $('#lang_to').val();
url += "&format=json&callback=setResult";
$('#word2').html('...');
$.getScript(url);
}
ExternalTranslate.init.start = function(){
mw.util.$content.empty();
// Retrieve HTML for the translate interface
(new mw.Api()).get( {
prop: 'revisions',
rvprop: 'content',
rvlimit: 1,
indexpageids: true,
titles: 'User:Gryllida/ExternalTranslate.html'
} )
.done( function ( data ) {
var q = data.query,
id = q && q.pageids && q.pageids[0],
pg = id && q.pages && q.pages[ id ],
rv = pg && pg.revisions;
if ( rv && rv[0] && rv[0]['*'] ) {
wikitext = rv[0]['*'];
mw.util.$content.prepend(wikitext);
// Put variables
// XXX DEBUG ONLY
$('#project_name').val(mw.config.get('wgSiteName'));
// $('#project_name').val(mw.config.get('wgSiteName'));
$('#headline_from').val(mw.config.get('wgTitle'));
$('#headline_from').prop('readonly', true);
$('#lang_from').val(mw.config.get('wgPageContentLanguage'));
$('#lang_from').prop('readonly', true);
// Enable load and preview buttons after input is complete
var input = $('.required');
input.on('keyup', function() {
if(input.filter(function() { return $(this).val() == ''; }).length > 0) { return; }
$('#load_button').prop('disabled', false);
$('#preview_button').prop('disabled', false);
});
// Enable events for buttons
// XXX Could make more use of 'this'?
$('#load_button').on('click',ExternalTranslate.Loader.loadOriginal);
$('#preview_button').on('click',ExternalTranslate.Loader.displayPreview);
$('#translateWordButton').on('click',ExternalTranslate.Translator.translateWord);
$('#go_to_target_wiki').on('click',ExternalTranslate.Loader.goTarget);
}
} );
// XXX
// .fail( mw.util.$content.prepend( 'The API request request failed.' ) );
}
/**
* CORS cross-site editing example
*/
ExternalTranslate.Loader.editForeignPage = function(info) {
// Custom hooks for edit success / failure (e.g., console.log)
var errorHook = typeof info.error === 'function', // has error function?
successHook = typeof info.success === 'function'; // has success hook?
// Most "modern" browsers except IE support CORS
if (!$.support.cors) {
info.error('Your browser does not support CORS! Try Firefox.', 'cors');
return;
}
// Get the foreign edit token
$.ajax({
url: info.url, // e.g. "//ru.wiki.x.io/w/api.php"
dataType: 'json',
data: {
action: 'tokens',
type: 'edit',
format: 'json',
origin: location.origin
},
success: function (data) { // if we get the token
var params;
// Handle various possible errors (possibly not needed)
if (!(data && data.tokens && data.tokens.edittoken) && errorHook) {
info.error(data, 'token');
return;
}
params = {
format: 'json',
action: 'edit',
title: info.title,
summary: info.summary,
origin: location.origin,
assert: 'user', // must be logged in!
token: data.tokens.edittoken
};
params[info.editaction] = info.text;
$.ajax({
url: info.url,
type: 'POST',
dataType: 'json',
data: params,
xhrFields: { // CORS XHR magic
withCredentials: true
}
})
.done(function (data) {
// Success! Run the success function passed in ``info''
if (data && data.edit && data.edit.result && data.edit.result === 'Success' && successHook) {
info.success(data);
} else if (errorHook) { // error, so run error hook
info.error(data, 'edit');
}
})
.fail(function () { // other failure
if (errorHook) {
info.error(null, 'other');
}
});
},
xhrFields: { // CORS XHR magic
withCredentials: true
}
});
};
ExternalTranslate.Loader.goTarget = function(){
// XXX debug only!!!
// mw.config.get('wgSiteName')
console.log('goTarget ...');
var url = '//' + $('#lang_to').val() + "." + mw.config.get('wgSiteName') + ".org/w/api.php";
console.log(url);
ExternalTranslate.Loader.editForeignPage({
url: url,
title: $('#targetName').val(),
summary: '[['+$('#lang_from').val()+':'+$('#headline_from').val()+']]',
editaction: 'text', // or prependtext, text (replace)
text: $('#field2').val(),
success: function (data) {
var diff = encodeURIComponent(data.edit.newrevid),
cont = confirm('Your edit was successful! OK to view diff'),
protocol = location.href.split('//')[0];
if (cont) {
location.href = protocol + '//'+ $('#lang_to').val() + "." + mw.config.get('wgSiteName') + '.org/?diff=' + diff;
}
},
error: function (data, errortype) {
alert('An error occurred! Type: ' + errortype + '; details: ' + data);
console.error(data);
}
});
};
//&& wgNamespaceNumber === 0 && wgUserGroups.toString().indexOf("editor") > -1
//if (wgAction === "view" ) {
$(ExternalTranslate.init);
//}