User:Vanished user 1929210/link-ts.js
Appearance
(Redirected from User:逆襲的天邪鬼/link-ts.js)
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:Vanished user 1929210/link-ts. |
/*
* @name Link Translator
*
* Originally designed by [[User:Liangent]]
* Changed by [[User:Kovl]] v2015-2-6-7-52
* Changed again by [[user:Panintelize]] 2016-02-06
* Source code is at [[User:Liangent/Gadgets/Toolkit/linktranslator.uncompressed.js]]
*
* VANDALIZED BY [[User:逆襲的天邪鬼]] v2016-11-31
*
* See also: [[zh:User:逆襲的天邪鬼/link-ts.js]]
*/
// <pre>
/**
* TODO:
*
* 1. 把中文的{{le}}、{{lang-xx}}、{{tsl}}变成对应的英文版本条目;
* 2. 使用{{Interlanguage link multi}}因为英文的{{link-zh}}并不起作用;
*/
mw.loader.using(['jquery.ui']).then(function () {
'use strict';
var LTUI = {
Translate: 'Translate',
TranslateLinks: 'Translate links',
LinkTranslator: 'Link Translator',
TLTitle: 'Translate links from Wikipedia in another language automatically',
SourceLanguageCode: 'Language code of the target Wikipedia: ',
OriginalLink: 'Original Link: ',
NOLINKINPAGE: 'There is no links in this page',
Done: 'Done',
NoWikiEd: 'Please disable WikEd before using linktranslator.js due to incompatibility',
EditMessage: '[[User:逆襲的天邪鬼/link-ts.js|Translate links]] from another Wikipedia',
// OPTION
SelectedTextOnly: 'Only process highlighted texts',
IfFound: 'If corresponding articles are found --',
KeepOriginalText: 'Keep original lagels ({{link-zh||原文|Label}})',
KeepOriginalText2: 'Keep original labels ([[English|原文]])',
CommentOriginalLink: 'Comment original links',
IfNotFound: 'Otherwise --',
UseLangLink: 'Convert it to {{link-xx}}',
MarkWrongPage: 'Mark pages which are not found in Wikipedia',
// STATUS
PARSEFAILED: 'Parse Failed',
ERROR: 'Error',
NOLINK: 'No Links',
MULTIPLELINK: 'Multiple Links',
PAGESAME: 'Same page',
PAGEDIFF: 'Different pages',
DONTEXIST: 'Page Not Found'
};
var LTConf = {
SourceLanguageCode: 'zh',
KeepOriginalText: 'checked', // 'checked' or ''
KeepOriginalText2: 'checked',
CommentOriginalLink: '',
UseLangLink: 'checked',
SelectedTextOnly: 'checked',
MarkWrongPage: 'checked',
};
// variables
var currentJobid = 0;
var LDSB = '__LEFT_DOUBLE_SQUARE_BRACKETS__';
var EXEConf;
/**
* 调用维基百科API来转换条目标题
*/
var callApi = function (options) {
var links = options.links || [];
var callback = options.callback || (function () {});
var failure = options.failure || (function () {});
var lang = options.lang || 'en';
var tolang = options.tolang || mw.config.get('wgContentLanguage');
var jobid = options.jobid || currentJobid;
// 标题去重,同时将这些标题分组,因为API只允许一次性最多提交50个标题
var map = {};
var i;
for (i=0; i<links.length; i++) {
map[links[i]] = true;
}
var queue = [];
var queue2 = [];
var m = 0, n = 0;
for (var j in map) {
queue.push(j);
m++;
if (m === 50) {
m = 0;
queue2.push(queue);
queue = [];
n++;
}
}
if (queue.length > 0) {
queue2.push(queue);
n++;
}
// 开始处理
var stop = false;
var langlinks = {};
var done = function (data) {
if (data.query) {
// 獲取原來的標題
var orinTitle = {};
var convert = function (arr) {
if (arr) {
for (var i=0; i<arr.length; i++) {
if (orinTitle[arr[i].from]) {
orinTitle[arr[i].to] = orinTitle[arr[i].from];
} else {
orinTitle[arr[i].to] = arr[i].from;
}
}
}
};
convert(data.query.normalized);
convert(data.query.converted);
convert(data.query.redirects);
// 標明翻譯情況
var pages = data.query.pages;
for (var pageid in pages) {
var page = pages[pageid];
var title = page.title;
if (orinTitle[title]) {
title = orinTitle[title];
}
if (page.missing !== undefined) {
// 页面不存在
langlinks[title] = undefined;
} else if (page.langlinks) {
langlinks[title] = page.langlinks[0]['*'];
} else {
// 没有对应条目
langlinks[title] = null;
}
}
}
n--;
if (n === 0 && !stop) {
callback(langlinks);
}
};
var error = function (jqXHR, textStatus, errorThrown) {
stop = true;
if (jobid === currentJobid) {
failure(langlinks);
}
};
var process = function (links) {
if (jobid !== currentJobid) {
stop = true;
return;
}
$.ajax({
data: {
action: 'query',
prop: 'langlinks',
lllang: tolang,
format: 'json',
redirects: true,
converttitles: true,
lllimit: 50,
titles: links.join('|'),
},
dataType: 'jsonp',
type: 'POST',
url: 'https://' + lang + '.wikipedia.org/w/api.php',
success: done,
error: error,
});
};
for (i=0; i<queue2.length && !stop; i++) {
process(queue2[i]);
}
};
/**
* 根据要求,将跨语言链接变成普通链接或{{link-xx}}(英文维基没有{{tsl}})。Category会被特殊处理。
*/
var makeLink = function (options) {
var link = options.link || { target: '', display: '' };
var lang = options.lang || '';
var newTarget = options.newTarget;
var output = '';
if (!link) {
return '';
}
var makeNormalLink = function (target, display) {
if (target === display || display === '') {
return LDSB + target + ']]';
} else {
return LDSB + target + '|' + display + ']]';
}
};
// 禁止把页面分类变成跨语言链接,或者在其后面附加文字(除非是[[Category:XXX|*]]那种)
if (link.target.toLowerCase().indexOf('category:') === 0) {
options.useLangLink = false;
options.keepOriginalText2 = (link.display !== '' && link.display !== link.target);
}
if (newTarget === null) {
// 没有对应英文条目
if (options.useLangLink) {
if (options.keepOriginalText) {
return '{{link-' + lang + '||' + link.target + '|' + link.display + '}}';
} else {
return '{{link-' + lang + '||' + link.target + '}}';
}
} else {
if (options.markWrongPage) {
return '<!-- ' + LTUI.NOLINK + ' -->' + makeNormalLink(link.target, link.display);
} else {
return makeNormalLink(link.target, link.display);
}
}
} else if (newTarget === undefined) {
// 页面不存在
if (options.markWrongPage) {
return '<!-- ' + LTUI.DONTEXIST + ' -->' + makeNormalLink(link.target, link.display);
} else {
return makeNormalLink(link.target, link.display);
}
} else {
if (options.keepOriginalText2) {
output = makeNormalLink(newTarget, link.display || link.target);
} else {
output = makeNormalLink(newTarget, '');
}
}
if (options.commentOriginalLink) {
output = '<!-- ' + makeNormalLink(link.target, link.display) + ' -->' + output;
}
return output;
};
/**
* 开始进行处理
*/
var processLinks = function (event) {
event.preventDefault();
var jobid = currentJobid;
EXEConf = {
KeepOriginalText: $('#linktranslator-keep-original').prop('checked'),
KeepOriginalText2: $('#linktranslator-keep-original2').prop('checked'),
CommentOriginalLink: $('#linktranslator-comment-link').prop('checked'),
UseLangLink: $('#linktranslator-lang-link').prop('checked'),
SelectedTextOnly: $('#linktranslator-selected-text').prop('checked'),
MarkWrongPage: $('#linktranslator-markwrongpage').prop('checked'),
};
LTConf.SourceLanguageCode = $('#linktranslator-source-lang').val();
var textBox = document.getElementById('wpTextbox1');
var wikitext = textBox.value;
if (EXEConf.SelectedTextOnly && textBox.selectionEnd - textBox.selectionStart > 0) {
wikitext = wikitext.substring(textBox.selectionStart, textBox.selectionEnd);
}
var links = wikitext.match(/(\[\[)(?!\:?.?.?\:)(?!Image:)(?!File:)(.+?)(\|.+?)?(\]\])/g);
if (links === null) {
$('#linktranslator').text(LTUI.NOLINKINPAGE);
return;
} else {
$('#linktranslator').dialog( 'option', 'position', { my: 'top', at: 'top'} );
$('#linktranslator').html('<div id="linktranslator-progressbar"></div>');
$('#linktranslator-progressbar').progressbar();
}
// 整合各links
var realLinks = [];
var links2 = [];
for (var i=0; i<links.length; i++) {
var link = links[i].slice(2, -2);
var linktarget = link;
var linkdisplay = link;
var idx = link.indexOf('|');
if (idx != -1) {
linktarget = link.substring(0, idx);
linkdisplay = link.substring(idx + 1);
}
$('#linktranslator').append('<div id="linktranslator-item-' + i + '"></div>');
$('#linktranslator-item-' + i).text(links[i] + ' -> ')
.append('<span class="linktranslator-item-newlink">...</span>');
realLinks.push(linktarget);
links2.push({ target: linktarget, display: linkdisplay });
}
var apiCallback = function (langlinks) {
var code = wikitext + '';
for (var i=0; i<links2.length; i++) {
var link = links2[i];
// 处理文内链接
var linkCode = makeLink({
link: link,
newTarget: langlinks[link.target],
lang: LTConf.SourceLanguageCode,
useLangLink: EXEConf.UseLangLink,
keepOriginalText: EXEConf.KeepOriginalText,
keepOriginalText2: EXEConf.KeepOriginalText2,
commentOriginalLink: EXEConf.CommentOriginalLink,
markWrongPage: EXEConf.MarkWrongPage,
});
//mark on dialogue
$('#linktranslator-item-' + i + ' .linktranslator-item-newlink').text(linkCode.replace(new RegExp(LDSB, 'g'), '[['));
if (langlinks[link.target] === null) {
// 没有对应英文条目
if (!EXEConf.UseLangLink) {
$('#linktranslator-item-' + i + ' .linktranslator-item-newlink').text(LTUI.NOLINK);
}
} else if (langlinks[link.target] === undefined) {
// 页面不存在
$('#linktranslator-item-' + i + ' .linktranslator-item-newlink').text(LTUI.DONTEXIST);
} else if (langlinks[link.target] === link) {
$('#linktranslator-item-' + i + ' .linktranslator-item-newlink').text(LTUI.PAGESAME);
}
// only replacing the first is ok, we will run this many times
code = code.replace(links[i], linkCode);
}
return code.replace(new RegExp(LDSB, 'g'), '[[');
};
// 开始处理
// 过去是一个条目调用一次API,现在是一次性处理全部,所以滚动条已经没有意义。
// var respcount = 0;
callApi({
links: realLinks,
lang: LTConf.SourceLanguageCode,
jobid: jobid,
callback: function (langlinks) {
var newtext = apiCallback(langlinks);
//$('#linktranslator-progressbar').progressbar('value', respcount * 100 / links.length);
$('#linktranslator-progressbar').progressbar('value', 100);
$('#linktranslator').prepend('<div id="linktranlator-done"><strong>' + LTUI.Done + '</strong></div>');
if (EXEConf.SelectedTextOnly && textBox.selectionEnd - textBox.selectionStart > 0) {
textBox.setRangeText(newtext);
} else {
textBox.value = newtext;
}
$('#wpSummary').val(LTUI.EditMessage + $('#wpSummary').val());
},
failure: function (langlinks) {
$('#linktranslator').prepend('<div id="linktranlator-done" style="color:red;"><strong>' + LTUI.ERROR + '</strong></div>');
},
});
};
// clear previous button
$('#wpLinktranslator').remove();
// secure server?
var wgAction = mw.config.get('wgAction');
if (wgAction == 'edit' || wgAction == 'submit') {
$('#wpDiff').after('\n<input id="wpLinktranslator" value="' + LTUI.TranslateLinks + '" title="' + LTUI.TLTitle + '" type="button"/>');
$('#wpLinktranslator').click(function (event) {
event.preventDefault();
$('#linktranslator').remove();
if ($('#wikEdFrameWrapper').css('visibility') === 'visible'){
alert(LTUI.NoWikiEd);
return;
}
var textBox = document.getElementById('wpTextbox1');
if (textBox.selectionEnd - textBox.selectionStart > 0) {
LTConf.SelectedTextOnly = 'checked';
} else {
LTConf.SelectedTextOnly = '';
}
$('<div id="linktranslator" title="' + LTUI.LinkTranslator + '">' +
'<label for="linktranslator-source-lang">' + LTUI.SourceLanguageCode + '</label> ' +
'<input id="linktranslator-source-lang" value="' + LTConf.SourceLanguageCode + '" type="text" /><br><br>' +
'<input type="checkbox" id="linktranslator-selected-text" ' + LTConf.SelectedTextOnly + '/> ' +
'<label for="linktranslator-selected-text">' + LTUI.SelectedTextOnly + '</label><br>' +
'<br>' + LTUI.IfFound + '<br><br>' +
'<input type="checkbox" id="linktranslator-comment-link" ' + LTConf.CommentOriginalLink + '/> ' +
'<label for="linktranslator-comment-link">' + LTUI.CommentOriginalLink + '</label><br>' +
'<input type="checkbox" id="linktranslator-keep-original2" ' + LTConf.KeepOriginalText2 + '/> ' +
'<label for="linktranslator-keep-original2">' + LTUI.KeepOriginalText2 + '</label><br>' +
'<br>' + LTUI.IfNotFound + '<br><br>' +
'<input type="checkbox" id="linktranslator-lang-link" ' + LTConf.UseLangLink + '/> ' +
'<label for="linktranslator-lang-link">' + LTUI.UseLangLink + '</label><br>' +
'<input type="checkbox" id="linktranslator-keep-original" ' + LTConf.KeepOriginalText + '/> ' +
'<label for="linktranslator-keep-original">' + LTUI.KeepOriginalText + '</label><br>' +
'<input type="checkbox" id="linktranslator-markwrongpage" ' + LTConf.MarkWrongPage + '/> ' +
'<label for="linktranslator-markwrongpage">' + LTUI.MarkWrongPage + '</label><br>' +
'<br><input class="mw-ui-button mw-ui-constructive" id="linktranslator-translate" value="' + LTUI.Translate + '" type="button" /></div>'
).dialog({
modal: false,
close: function() {
currentJobid++;
},
width: 500
});
$('#linktranslator-translate').click(processLinks);
});
}
});
// </pre>