User:Gryllida/ExternalTranslate.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
// 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);">&times;</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 += ".wikipedia.org/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.wikipedia.org/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);
//}