User:Vanished user 1929210/js/followredirect.js
外观
注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google Chrome、Firefox、Microsoft Edge及Safari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。
/*
* 重新定向追蹤工具
*
* 使用方法:編輯原始碼->熒幕右上角的「其他」->追蹤重新定向
*
* 亦可使用原始碼2017,但是目前不支援視覺化編輯
*
* 僅需要在以下兩種情況中使用:
* 1. 在導航模板中,如果連結是重新定向或與條目名稱簡繁體不同,那麼它在對應條目中並不會變成粗體文字,因此需要修一修。
* 2. 如果頁面中有重新定向連結,而且重新定向的目標也是本頁,那麼應當移除連結。
* 其他情況不應使用,即[[Wikipedia:沒壞就不要修]]。
*/
// <pre>
mw.loader.using('jquery.ui').then(function() {
'use strict';
var UI = (function () {
switch (mw.config.get('wgUserLanguage')) {
case 'zh':
case 'zh-cn':
case 'zh-hans':
case 'zh-my':
case 'zh-sg':
return {
TITLE: '追踪重定向',
WELCOME: '本工具用于把重定向链接纠正到页面本身,建议仅在导航模板中使用。',
LOADING: '正在查询页面标题...',
LINK: '链接',
DEAL: '处理方式',
PASS: '不处理',
CHANGETO: '去除链接:',
OK: '确认',
SUMMARY: '将重定向链接修改到页面本身 (via [[User:逆襲的天邪鬼/js/followredirect.js|followredirect]])',
};
case 'zh-hk':
case 'zh-mo':
case 'zh-tw':
case 'zh-hant':
return {
TITLE: '追蹤重新定向',
WELCOME: '本工具用於把重新定向連結糾正到頁面本身,建議僅在導航模板中使用。',
LOADING: '正在查詢頁面標題...',
LINK: '連結',
DEAL: '處理方式',
PASS: '不處理',
CHANGETO: '去除連結:',
OK: '確認',
SUMMARY: '將重新定向連結修改到頁面本身 (via [[User:逆襲的天邪鬼/js/followredirect.js|followredirect]])',
};
default:
return {
TITLE: 'Follow redirects',
WELCOME: 'This tool is used for following redirects and replace with pagenames themselves.',
LOADING: 'Querying...',
LINK: 'Links',
DEAL: 'Changes',
PASS: 'Pass',
CHANGETO: 'Unlink: ',
OK: 'OK',
SUMMARY: 'Followed redirects and replace with page names themselves (via [[User:逆襲的天邪鬼/js/followredirect.js|followredirect]])',
};
}
})();
// 檢查給定的標題,挑出屬於重新定向的標題。如果頁面存在,那麼給出它們的最終目標。
var checkTitles = function (titles, callback) {
var queue = [];
var i;
var n;
n = parseInt((titles.length+50)/50);
for (i=0; i<n; i++) {
queue.push(titles.slice(50*i, 50*(i+1)).join('|'));
}
var map = {}, map2 = {};
var targets = {};
var combine = function (arr, target) {
if (arr) {
for (var i=0; i<arr.length; i++) {
target[arr[i].from] = arr[i].to;
}
}
};
var follow = function (title) {
var r = map[title];
while (map[r]) {
r = map[r];
}
return r;
};
var done = function () {
var result = {};
for (var i=0; i<titles.length; i++) {
var title = titles[i];
var newtitle = follow(title);
// 以下幾種情況不要處理:
// 僅僅差一個「:」
// 含有「#」,而且實質上是同一頁面(如果不是同一頁面則把#補回來)
// 僅僅是大小寫不同和簡繁體不同
if (targets[newtitle] && newtitle !== map2[title]) {
result[title] = newtitle;
if (title.indexOf('#') > -1) {
result[title] = result[title] + '#' + title.split('#')[1];
}
}
}
callback(result);
};
var errors = function () {
if (--n === 0) {
done();
}
};
var process = function (data) {
if (data.query) {
combine(data.query.normalized, map);
combine(data.query.converted, map);
combine(data.query.redirects, map);
combine(data.query.normalized, map2);
combine(data.query.converted, map2);
var pages = data.query.pages;
for (var pageid in pages) {
if (parseInt(pageid) > 0) {
var page = pages[pageid];
targets[page.title] = true;
}
}
}
if (--n === 0) {
done();
}
};
for (i=0; i<queue.length; i++) {
$.ajax({
url: mw.util.wikiScript('api'),
data: {
action: 'query',
format: 'json',
redirects: true,
converttitles: true,
titles: queue[i],
},
dataType: 'json',
type: 'POST',
success: process,
error: errors,
});
}
};
// 由於事情不像fixlinkstyle那樣複雜,所以用不著建構WikiDOM樹
var segments = [];
var alllinks = [];
var redirectlinks = [];
var extractLinks = function (text) {
var i;
var result = [];
segments = [];
alllinks = [];
var re = /\[\[([^\[\n]*?)\]\]/g;
var match;
var extract = /^(.*?):(.*)/;
var extract2 = /^([Ff]ile|[Ii]mage|文件|檔案|[Cc]ategory|分类|分類)/;
var lastPos = 0;
while ((match = re.exec(text)) !== null) {
// 前文
segments.push(text.substring(lastPos, re.lastIndex-match[0].length));
// 連結
segments.push(match[0]);
lastPos = re.lastIndex;
// 不要處理檔案和分類
// 系統會自動忽略跨語言連結(query.interwiki),所以不用特殊處理
var match2 = extract.exec(match[1]);
if (!(match2 && match2[1].match(extract2))) {
var link = {
position: segments.length - 1,
};
var sepPos = match[1].indexOf('|');
if (sepPos === -1) {
link.target = match[1];
link.text = '';
} else {
link.target = match[1].substring(0, sepPos);
link.text = match[1].substring(sepPos+1);
}
alllinks.push(link);
}
}
// 末尾文字
segments.push(text.substring(lastPos));
};
var parseLinks = function (callback) {
var titles = [];
for (var i=0; i<alllinks.length; i++) {
titles.push(alllinks[i].target);
}
redirectlinks = [];
checkTitles(titles, function (map) {
for (var i=0; i<titles.length; i++) {
if (map[titles[i]]) {
alllinks[i].newtarget = map[titles[i]];
if (alllinks[i].target.indexOf(':') === 0 && map[titles[i]].indexOf(':') !== 0) {
alllinks[i].newtarget = ':' + alllinks[i].newtarget;
}
redirectlinks.push(alllinks[i]);
}
}
callback();
});
};
var linkToText = function (link) {
if (link.target === '__UNLINK__') {
return link.text;
}
if (link.text && link.text != link.target) {
return '[[' + link.target + '|' + link.text + ']]';
} else {
return '[[' + link.target + ']]';
}
};
var setLink = function (link) {
var temp = link.target;
if (link.newtarget) {
link.target = link.newtarget;
}
segments[link.position] = linkToText(link);
link.target = temp;
};
var makeArticle = function () {
return segments.join('');
};
var htmlEscape = function (str) {
var t = {
'<': '<',
'>': '>',
'&': '&',
};
return str.replace(/[<>&]/g, function (match) { return t[match]; });
};
var jobid = 0;
var curjobid = 0;
var dialog = function () {
if (wikitextEditor.mode === 'visual') {
alert(UI.NoVE || 'VE');
return;
}
if (document.getElementById('followredirect_dialog') === null) {
$('body').append('<div id="followredirect_dialog" style="display:none;" title="' + UI.TITLE + '"></div>');
}
$('#followredirect_dialog').html('<p id="fd_loading">' + UI.LOADING + '</p>');
jobid++;
curjobid = jobid;
$('#followredirect_dialog').dialog({
modal: false,
draggable: true,
close: function () {
jobid++;
redirectlinks = [];
},
width: 700,
height: 500,
buttons: [],
});
var defaultToPass = mw.config.get('wgNamespaceNumber') !== 10;
var thisPageName = mw.config.get('wgPageName');
var text = wikitextEditor.text;
extractLinks(text);
parseLinks(function () {
if (curjobid !== jobid) {
return;
}
var $ui = $('<p>').html(UI.WELCOME);
var $table = $('<table class="wikitable" style="width:100%;">');
var site = mw.config.get('wgScript');
var i;
$table.append('<tr><th>#</th><th>' + UI.LINK + '</th><th>' + UI.DEAL + '</th></tr>');
for (i=0; i<redirectlinks.length; i++) {
var link = redirectlinks[i];
$table.append($('<tr>').append(
'<td>' + (i+1) + '</td>',
'<td><a href="' + site + '/' + encodeURI(link.target) + '" target="_blank">' + htmlEscape(linkToText(link)) + '</a></td>',
$('<td>').append('<input type="radio" id="fd_r' + i + '_1" name="fd_r' + i + '" value="1">',
'<label for="fd_r' + i + '_1">' + UI.PASS + '</label> ',
'<input type="radio" id="fd_r' + i + '_2" name="fd_r' + i + '" value="2">',
'<label for="fd_r' + i + '_2">[[' + htmlEscape(link.newtarget) + ']]<br>',
'<input type="radio" id="fd_r' + i + '_3" name="fd_r' + i + '" value="3">',
$('<input type="text" size="20" id="fd_t' + i + '_a" name="fd_t' + i + '_a">').val(link.newtarget),
'|',
$('<input type="text" size="20" id="fd_t' + i + '_b" name="fd_t' + i + '_b">').val(link.text || link.target),
'<br>',
'<input type="radio" id="fd_r' + i + '_4" name="fd_r' + i + '" value="4">',
'<label for="fd_r' + i + '_4">' + UI.CHANGETO + '</label>',
$('<input type="text" size="20" id="fd_r' + i + '_c" name="fd_r' + i + '_c">').val(link.text || link.target)
)
));
}
$ui.append($('<form id="fd_frm">').append($table)); //, '<button id="fd_submit" class="mw-ui-button mw-ui-progressive">' + UI.OK + '</button>');
$('#fd_loading').replaceWith($ui);
$('#followredirect_dialog').dialog('option', 'buttons', [
{
text: UI.OK,
click: function() {
for (var i=0; i<redirectlinks.length; i++) {
var frm = document.forms.fd_frm;
var link = redirectlinks[i];
switch (frm['fd_r' + i].value) {
case '2':
link.text = '';
break;
case '3':
link.newtarget = '';
link.target = frm['fd_t' + i + '_a'].value;
link.text = frm['fd_t' + i + '_b'].value;
break;
case '4':
link.newtarget = '';
link.target = '__UNLINK__';
link.text = frm['fd_r' + i + '_c'].value;
break;
default:
link.newtarget = '';
}
setLink(link);
}
wikitextEditor.text = makeArticle();
wikitextEditor.summary = UI.SUMMARY;
$(this).dialog('close');
},
},
]);
for (i=0; i<redirectlinks.length; i++) {
var frm = document.forms.fd_frm;
frm['fd_r' + i].value = defaultToPass ? '1' : '3';
// 如果目標是本頁,直接unlink
if (redirectlinks[i].newtarget === thisPageName) {
frm['fd_r' + i].value = '4';
}
}
$('input:text', '#followredirect_dialog').click(function (e) {
var name = this.id;
var i = name.lastIndexOf('_');
var id = name.slice(4, i);
if (name.indexOf('fd_r') === 0) {
document.forms.fd_frm['fd_r' + id].value = 4;
} else {
document.forms.fd_frm['fd_r' + id].value = 3;
}
});
});
};
mw.hook('editorapi.ready').add(function () {
$('#p-followredirects').remove();
$(mw.util.addPortletLink('p-cactions', '#', UI.TITLE, 'p-followredirects')).click(function (e) {
e.preventDefault();
dialog();
});
jobid++;
try {
$('#followredirect_dialog').dialog('close');
} catch (ex) {
}
});
mw.loader.load('https://wiki.gdrain.workers.dev/w/index.php?title=User:逆襲的天邪鬼/js/EditorAPIs.js&action=raw&ctype=text/javascript');
});
// </pre>
// [[Category:维基脚本]]