User:Maxeeder/ArticleTranslator.js

// /*! * Distributed under the terms of the CC-BY-SA 3.0 */ // DO NOT COPY IT FOR TRANSLATION, READ THE DOCUMENTATION en:User talk:Ebraminio/ArticleTranslator.js /*jslint browser: true, regexp: true, unparam: true*/ /*global jQuery: false, mediaWiki: false */ (function ($, mw) {   'use strict';    var translationTextArea,        progressCount,        itemsCount,        ajaxUrl,        conf = {            'homeWiki': 'fa',            'fromLang': mw.config.get('wgPageContentLanguage'),            'translatorBarFormat': '$1translate$2 links from $3 to $4 ($5)',            'templateTranslatorText': 'Template translation',            'removeLinksAliasesText': 'Remove Links Aliases',            'doneText': 'Done!',            'enableTemplateTranslation': true,            'removeLinksAliases': true,            'enableNeedingShow': false,            'name': 'Name',            'interwikiCount': 'Interwiki Count',            'linkedTo': 'Linked to',            'listOfUnavailablePagesOn': 'List of not available pages on',            'definedTemplates': ["About","ADB","Alsoknown","Alternateuses","Cat main","Cat main article","Category disambiguation","Category main","Catmain","Consider disambiguation","Contrast","Dabprefixes","Detail","Details","Disambiguation needed","Distinguish","Distinguish2","For","For other uses","For2","In title","Introductory article","Look from","Main","Main cat","Main category","Maincat","More","Moredetails","Navbox hatnote *Templates","Other","Other hurricanes","Other meanings","Other people","Other people2","Other people3","Other people5","Other places","Other places3","Other ships","Other use","Other uses","Other uses of","Other uses1","Other uses2","Other uses-section","Othermeanings","Otheruse","OtherUses","Otheruses1","Otheruses3","OtherusesSubtopic","Othervalues","Outline","Previously","Redirect","Redirect10","Redirect2","Redirect3","Redirect4","Redirect6","Redirect-distinguish2","Redirect-synonym","See introduction","See Wiktionary","Seesubarticle","Selfref","Srlink","Surname links","Technical reasons","Template ambiguous","Template shortcut","This user talk","Three other uses","Two other uses","WikiProject Disambiguation"] };   var DefinedTemplateList=[]

$.extend(conf, window.articleTranslatorConf);

// getting the last translator preference from the cookie if ($.cookie('homeWiki') !== null) { conf.homeWiki = $.cookie('homeWiki'); }

if ($.cookie('fromLang') !== null) { conf.fromLang = $.cookie('fromLang'); }   //

// from: http://80.68.89.23/2006/Jan/20/escape/ function escape(text) { return text.replace(/[\-\[\]{}*+?.,\\\^$|#\s]/g, '\\$&'); }

function getOrigin { var result = location.protocol + '//' + location.host; if (location.port !== '') { result = result + ':' + location.port; }       return result; }

function getOriginOfWikiLang(lang) { return getOrigin.replace(mw.config.get('wgPageContentLanguage'), lang); }

function setAjaxUrl { var tailOfApiUrl = '/api.php?action=query&prop=langlinks&redirects=&format=json&lllimit=500&titles='; if (conf.enableNeedingShow === true) { tailOfApiUrl = '/api.php?action=query&prop=langlinks|links&redirects=&format=json&pllimit=500&lllimit=500&titles='; }       ajaxUrl = getOriginOfWikiLang(conf.fromLang) + mw.config.get('wgScriptPath') + tailOfApiUrl; }

function getSelectedTextLinks { // borrowed from: http://stackoverflow.com/questions/4220478 :)       var selection,            selectionAncestor,            range,            allWithinRangeParent;

// if `window.getSelection` is not defined (on IE) return nothing. if (window.getSelection === undefined) { return []; }       selection = window.getSelection;

// if nothing is selected, return empty array if (selection.isCollapsed) { return []; }

range = selection.getRangeAt(0); selectionAncestor = range.commonAncestorContainer; if (selectionAncestor.getElementsByTagName === undefined) { // if it is not a formal HTML selection return []; }       allWithinRangeParent = selectionAncestor.getElementsByTagName('a');

return $.map(allWithinRangeParent, function (el) {           // The second parameter says to include the element            // even if it's not fully selected            if (selection.containsNode(el, true)) {                return el;            }        }); }

function onFinish { $('#translatorProgress').hide('slow'); $('#translatorStatus').css('font-weight', 'bold').text(conf.doneText).show('slow'); if (conf.enableNeedingShow) { var links = [], result, linksCount, titleExistance = {}, title; $('.translatorNeededLink').each(function (k, v) {               title = $(v).attr('data-title');                if (titleExistance[title] === true) {                    return;                }                titleExistance[title] = true;                linksCount = $(v).attr('data-links-to-count');                if (parseInt(linksCount, 10) === 500) {                    linksCount = '500+';                }                links.push([title, parseInt($(v).attr('data-interwikis'), 10), linksCount]);            }); links = links.sort(function (x, y) { return y[1] - x[1]; }); result = ' '; $('#translatorPlusContainer').remove; $('' + conf.listOfUnavailablePagesOn + ' ' + conf.homeWiki + '.wiki:\n ' + result + ' ').appendTo('#translatorBar'); }   }

function increaseProgressCount { progressCount = progressCount + 1; $('#translatorProgress').attr('value', progressCount);

if (progressCount === itemsCount) { onFinish; }   }

function queryTranslationFromData(data) { var languageLinks, linksToCount = 0, translation;

if (data.query === undefined || data.query.pages === undefined) { return null; }       $.each(data.query.pages, function (key, value) { // for retrieving first object index            languageLinks = value.langlinks;            if (value.links !== undefined) {                linksToCount = value.links.length;            }        }); if (languageLinks === undefined) { return null; }       $.each(languageLinks, function (key, value) { // we can also use .filter here            if (value.lang === conf.homeWiki) {                translation = value['*'];            }        }); return { translation: translation, linksToCount: linksToCount, interwikis: languageLinks.length };   }

function commonAjaxRunner(title, translatorFunction) { $.ajax({           url: ajaxUrl + encodeURIComponent(title),            complete: function  {                increaseProgressCount;            },            success: function (data) {                var translation = queryTranslationFromData(data);                if (translation !== null) {                    translatorFunction(translation);                }            },            dataType: 'jsonp'        }); }

function addTranslationToNode(node, translation) { if (translation.translation !== undefined) { node.after(' (' + translation.translation + ') '); } else if (conf.enableNeedingShow === true) { node.after(' (' + translation.interwikis + ' ) '); }   }

function translateFromLanguageLinkNode(title, node) { commonAjaxRunner(title, function (translation) {           addTranslationToNode(node, translation);        }); }

// for Links in textareas function addTranslationToTextareaLink(title, translation) { translationTextArea.val(translationTextArea.val.replace( new RegExp('(\\[\\[:?)' + escape(title) + '((?:\\|[^\\]]*)?)(\\]\\])'), '$1' + translation + (conf.removeLinksAliases ? '' : '$2') + '$3' ));   }

function translateFromLanguageLinks(title) { commonAjaxRunner(title, function (translation) {           if (translation.translation !== undefined) {                addTranslationToTextareaLink(title, translation.translation);            }        }); }

// for in textareas function addTranslationToTextareaLinksInTemplate(title, translation) { var i, definedTemplate; for (i = 0; i < DefinedTemplateList.length; i = i + 1) { definedTemplate = DefinedTemplateList[i]; translationTextArea.val(translationTextArea.val.replace( new RegExp('(\\{\\{\\s*(?:[Tt]emplate:)?)' + definedTemplate + '\\s*\\|\\s*' + escape(title) + '\\s*\\}\\}'), '$1' + definedTemplate + '|' + translation + '}}' ));       }    }

function translateFromLanguageLinksInTemplate(title) { commonAjaxRunner(title, function (translation) {           if (translation.translation !== undefined) {                addTranslationToTextareaLinksInTemplate(title, translation.translation);            }        }); }

// for s in textareas function addTranslationToTextareaTemplateLink(title, translation) { translationTextArea.val(translationTextArea.val.replace( new RegExp('(\\{\\{\\s*(?:[Tt]emplate:)?)' + escape(title) + '([\\n\\|\\}])'), '$1' + translation + '$2' ));   }

function translateFromLanguageTemplateLinks(title) { commonAjaxRunner('Template:' + title, function (translation) {           if (translation.translation !== undefined) {                addTranslationToTextareaTemplateLink(title, translation.translation.replace(/^.*?:/, ''));            }        }); }

function parseUrl(url) { if (url === undefined) { return undefined; }       var match = url.match(/\/wiki\/([^#]*)/); if (match === null) { match = url.match(/\/w\/index\.php\?title=([^&#]*).*redlink=1/); }

if (match !== null) { return decodeURI(match[1]); // returns matched text }       return undefined; }

function getLinkTitle(link) { // previously it was link.attr("title") return parseUrl(link.attr('href')); }

function run { setAjaxUrl; progressCount = 0; itemsCount = 0; $('#translatorStatus').hide(0); $('#translatorProgress').removeAttr('max').removeAttr('value'); $('.translatorAddedcontent').remove;

var links, templates, linkedInTemplates, i,           a,            title, action = mw.config.get('wgAction'), linkInTemplate;

if (action === 'view' || action === 'purge' || action === 'historysubmit') { links = getSelectedTextLinks; if (links.length === 0) { links = $('#bodyContent a'); }

$(links).each(function {                var iter = $(this),                    title = getLinkTitle(iter);                if (title !== undefined) {                    itemsCount = itemsCount + 1;                    translateFromLanguageLinkNode(title, iter);                }            });

$('#translatorProgress').show.attr('max', itemsCount);

} else if (action === 'edit' || action === 'submit') { $('#wpTextbox2').remove; // remove translation textarea if exists

if (conf.fromLang === mw.config.get('wgPageContentLanguage')) { translationTextArea = $('#wpTextbox1').clone.attr({                   'id': 'wpTextbox2'                }).css({ // new color for translation textarea                    'background-color': '#CCCEFF'                }).val($('#wpTextbox1').val); // this something that clone must do                $('#wpTextbox1').before(translationTextArea); // put translation textarea before old } else { translationTextArea = $('#wpTextbox1'); }           //for pre-defined templates for (i = 0; i < conf.definedTemplates.length; i = i + 1) { if (translationTextArea.val.replace( new RegExp("\\{\\{\\s*(?:[Tt]emplate:)?" + conf.definedTemplates[i] + "\\|", "g"),"")!=translationTextArea.val){ DefinedTemplateList.push(conf.definedTemplates[i]) }               if (translationTextArea.val.replace(//fot  LowerCase templates new RegExp("\\{\\{\\s*(?:[Tt]emplate:)?" + conf.definedTemplates[i].toLowerCase+ "\\|", "g"),"")!=translationTextArea.val){ DefinedTemplateList.push(conf.definedTemplates[i].toLowerCase) }           }                alert(DefinedTemplateList) // for links links = translationTextArea.val.match(/\[\[.*?\]\]/g); templates = translationTextArea.val.match(/\{\{.*?[\n\|\}]/g); linkedInTemplates = translationTextArea.val.match(/\{\{.*?\}\}/g); itemsCount = -1; if (links !== null) { for (i = 0; i < links.length; i = i + 1) { // equals with title = links[i].replace(/\[\[:?([^\]\|]*)\|?.*?\]\]/g, "$1"); translateFromLanguageLinks(title); }

if (itemsCount === -1) { itemsCount = 0; }

itemsCount = itemsCount + links.length; }           //for LinkedInTemplates

if (linkedInTemplates !== null && DefinedTemplateList!==[] ) { for (i = 0; i < linkedInTemplates.length; i = i + 1) { // equals with for (a = 0; a < DefinedTemplateList.length; a = a + 1) { linkInTemplate = linkedInTemplates[i].replace(                           new RegExp("\\{\\{\\s*(?:[Tt]emplate:)?" + DefinedTemplateList[a] + "\\|(.*)\\s*[\\n\\|\\}]", "g"),                           "$1"                        ); linkInTemplate = linkInTemplate.replace('}', ''); linkInTemplate = linkInTemplate.replace('|', ''); if (linkInTemplate.replace('{', '') === linkInTemplate) { translateFromLanguageLinksInTemplate(linkInTemplate); //for translating links inside defined-templates }                   }                }

if (itemsCount === -1) { itemsCount = 0; }

itemsCount = itemsCount + templates.length; }           //for Templates if (templates !== null && conf.enableTemplateTranslation === true) { for (i = 0; i < templates.length; i = i + 1) { // equals with title = templates[i].replace(/\{\{\s*(?:[Tt]emplate:)?(.*)\s*[\n\|\}]/g, '$1'); translateFromLanguageTemplateLinks(title); }

if (itemsCount === -1) { itemsCount = 0; }

itemsCount = itemsCount + templates.length; }

if (itemsCount !== -1) { $('#translatorProgress').show.attr('max', itemsCount); }       }    }

function initiateEditor(forEditable, inputForEditable, setVariableClosure) { $(forEditable).click(function (event) {           event.preventDefault;            $(forEditable).hide;            $(inputForEditable).css('width', '2em').show.val($(forEditable).text);        });

$(inputForEditable).keyup(function (event) {           var selectedLanugage = $(this).val;

if (event.keyCode === 13) { $(this).focusout; // on enter } else if (event.keyCode === 27) { $(forEditable).show; // on escape $(inputForEditable).hide.val(selectedLanugage); }

}).focusout(function { var selectedLanugage = $(this).val;

if (/...?/.test(selectedLanugage)) { setVariableClosure(selectedLanugage); $(forEditable).html(selectedLanugage); }

$(forEditable).show; $(inputForEditable).hide; });   }

$(function {        $('#translatorBar').remove;

// HTML Builder var hb = [], bar = conf.translatorBarFormat, action = mw.config.get('wgAction');

hb.push('');

bar = bar.replace('$1', '='); bar = bar.replace('$2', '+'); bar = bar.replace('$3', '' + conf.fromLang + ''); bar = bar.replace('$4', '' + conf.homeWiki + '<input style="display: none" id="translator-to-input">'); bar = bar.replace('$5', '<a id="translator-switch" href="$">-</a>');

hb.push(bar);

if (action === "edit" || action === "submit") { hb.push(' <input type="checkbox" name="enableTemplateTranslation" id="enableTemplateTranslation"><label for="enableTemplateTranslation">' + conf.templateTranslatorText + ' '); hb.push(' <input type="checkbox" name="removeLinksAliases" id="removeLinksAliases"><label for="removeLinksAliases">' + conf.removeLinksAliasesText + ' '); }

hb.push(' <progress id="translatorProgress" style="display: none;">In progress... ');

$('h1:first').append(hb.join(''));

$('#translator-button').click(function (event) {           event.preventDefault;            conf.enableNeedingShow = false;            run;        });

$('#translator-equ').click(function (event) {           event.preventDefault;            var title = mw.config.get('wgTitle');            $('#translator-equ-links').html('<a target="_blank" href="//translate.google.com/translate_t?sl=' + conf.fromLang + '&tl=' + conf.homeWiki + '&q=' + title + '">Translator</a> / <a target="_blank" href=\'//www.google.com/search?q="' + encodeURI(title) + '"&lr=lang_' + conf.homeWiki + '\'>Specific Language Search</a> ');        });

$('#translator-plus').click(function (event) {           event.preventDefault;            conf.enableNeedingShow = true;            run;        });

$('#translator-switch').click(function (event) {           event.preventDefault;

var t = conf.homeWiki;

conf.homeWiki = conf.fromLang; $.cookie("homeWiki", conf.fromLang); $('#translator-to').html(conf.fromLang);

conf.fromLang = t;           $.cookie("fromLang", t); $('#translator-from').html(t); });

initiateEditor('#translator-to', '#translator-to-input', function (value) {           conf.homeWiki = value;            $.cookie("homeWiki", value);        });

initiateEditor('#translator-from', '#translator-from-input', function (value) {           conf.fromLang = value;            $.cookie("fromLang", value);        });

$('#enableTemplateTranslation').attr('checked', conf.enableTemplateTranslation).click(function {            conf.enableTemplateTranslation = this.checked;        });

$('#removeLinksAliases').attr('checked', conf.removeLinksAliases).click(function {            conf.removeLinksAliases = this.checked;        }); }); }(jQuery, mediaWiki)); //