利用者:Frozen-mikan/OtherLangImages.js
表示
お知らせ: 保存した後、ブラウザのキャッシュをクリアしてページを再読み込みする必要があります。
多くの Windows や Linux のブラウザ
- Ctrl を押しながら F5 を押す。
Mac における Safari
Mac における Chrome や Firefox
- ⌘ Cmd と ⇧ Shift を押しながら R を押す。
詳細についてはWikipedia:キャッシュを消すをご覧ください。
/*
* 言語間リンクで他言語の画像ファイルを調べるスクリプト。
* 試作版。
* ヘルプは以下のURLにあります。
* @see http://ja-two.iwiki.icu/wiki/User:Frozen-mikan/OtherLangImages
*/
(function(window, document){ jQuery( document ).ready( function($){
var rootId = 'other_lang_images';
var viewAllSelector = '.view_all';
var callbackName = 'appendImages';
var commonsHost = 'commons.wikimedia.org';
var contentLang = mw.config.get( 'wgContentLanguage');
/* 言語コードを用いて、姉妹プロジェクトのホスト名を返す関数 */
var getHostName = (function(){
var baseHost = /^.+?(\..+)$/.exec(location.host)[1];
return function(lang){
return lang + baseHost;
};
})();
var imageTitles = [];
var imagesByTitle = {};
var imagesByLang = {};
function initUI() {
var root = getRoot();
$( '.control' , root ).toggle(false);
$( viewAllSelector , root ).toggle(false).click(function() {
$( 'tr.raw_false, tr.' + contentLang, root).toggle(true);
$( viewAllSelector , root ).toggle(false);
return false;
}).attr( 'value' , '全ての画像を表示');
root.toggle(true);
}
function getRoot() {
var root = $( '#' + rootId );
if (root.length == 0) {
mw.util.$content.before('<div id="' + rootId + '">' +
'<div class="progressbar" />' +
'<form class="control">' +
'<input class="view_all" type="button" /></form>'
);
root = $( '#' + rootId ).toggle( false );
}
return root;
}
function redrawUI() {
$( '.progressbar' , getRoot()).toggle(false);
if( imageTitles.length == 0 ) return;
var area = getDataArea();
for (var i = 0; i < imageTitles.length; ++i) {
var title = imageTitles[i];
var image = imagesByTitle[title];
var url = 'http://' + commonsHost + '/wiki/File:' + title;
var raw = image.raw;
var clang = imagesByLang[contentLang] &&
imagesByLang[contentLang][title];
area.append('<tr class="raw_' + raw +
(clang ? ' ' + contentLang : '') + '"' +
(!raw || clang ? ' style="display:none;"' : '') + '>' +
'<td>' + formatLangs(image.langs, title) + '</td>' +
'<td><a href="' + url + '">' + formatTitle(title, raw) +
'</a></td>' +
'</tr>');
}
}
function getDataArea() {
var root = getRoot();
$( 'table', root ).remove();
$( viewAllSelector , root ).toggle(true);
$( root ).append(
'<table class="wikitable"><tbody>' +
'<tr><th>Langs</th><th>Filename</th></tr>' +
'</tbody></table>'
);
return $( 'table', root ).last();
}
function formatLangs(langs, title) {
var t = '';
for (var i = 0; i < langs.length; ++i) {
if (i != 0) {
t += ', ';
}
var lang = langs[i];
if (lang == contentLang) {
t += '<b>';
}
t += '<a href="http://' + getHostName(lang) +
'/wiki/File:' + title + '">' + lang + '</a>';
if (lang == contentLang) {
t += '</b>';
}
}
return t;
}
function formatTitle(title, raw) {
if (raw) {
return '<b>' + title + '</b>';
}
return title;
}
function progress(per) {
function valid(per) {
if (per < 0) {
per = 0;
} else if (100 < per) {
per = 100;
} else {
per = Math.round(per);
}
return per;
}
var bar = $( '.progressbar' , getRoot() );
var inner = $( 'div.inner' , bar );
if (inner.length == 0) {
bar.css({ 'width' : '300px' , 'border' : '1px solid #99c' })
.append( '<div class="inner"' +
' style="height: 14px; width: 0px; background-color: #ccf;" />' );
}
$( 'div.inner' , bar ).css( 'width' , valid(per) + '%' );
bar.toggle(true);
}
function strip(text) {
var re = /^[^:]+:(.+)$/;
var m = re.exec(text);
if (m) return m[1];
return text;
}
function appendTitle(imageTitle) {
for (var i = 0; i < imageTitles.length; ++i) {
if (imageTitles[i] == imageTitle) return;
}
imageTitles.push(imageTitle);
}
function sort() {
imageTitles.sort(function(a, b) {
// 利用されている言語数の多い順に並べる
var numa = imagesByTitle[a].langs.length;
var numb = imagesByTitle[b].langs.length;
if (numa < numb) return 1;
if (numb < numa) return -1;
// 同数の場合には文字列順
if (a < b) return -1;
if (b < a) return 1;
return 0;
});
}
/* prop=images|revisions 用のコールバック関数 */
window[callbackName] = function(data){
if (!data.query || !data.query.pages) return;
var lang = data.requestid;
for (var pageid in data.query.pages) {
var page = data.query.pages[pageid];
var images = page.images;
if (!images) continue;
var content = page.revisions[0]['*'];
for (var i = 0; i < page.images.length; ++i) {
var imageTitle = strip(images[i].title);
var image = imagesByTitle[imageTitle];
if (!image) {
image = {};
image.title = imageTitle;
imagesByTitle[imageTitle] = image;
image.langs = [];
}
if (!image.raw) {
image.raw = (-1 != content.indexOf(image.title));
}
if (!imagesByLang[lang]) {
imagesByLang[lang] = {};
}
imagesByLang[lang][imageTitle] = image;
image.langs.push(lang);
image.langs.sort();
appendTitle(imageTitle);
}
}
// sort();
// redrawUI();
};
var title = mw.config.get( 'wgPageName' );
initUI();
$.getJSON(
'http://' + location.host + '/w/api.php?',
{
format: 'json',
action: 'query',
prop: 'langlinks',
lllimit: 'max',
titles: title
},
function(data){
var c = max=0;
function parseApiLanglinks(data) {
var page = data.query.pages[mw.config.get( 'wgArticleId' )];
var langlinks = page.langlinks;
var llmap = {};
llmap[contentLang] = page.title;
if (!langlinks) return llmap;
for(var i = 0; i < langlinks.length; ++i) {
var ll = langlinks[i];
llmap[ll.lang] = ll['*'];
}
return llmap;
}
var llmap = parseApiLanglinks(data);
var interval = 30; // msec
function getImageTitles(lang, title, callback) {
$.getScript('http://' + getHostName(lang) +
'/w/api.php?' +
$.param({
action: 'query',
requestid: lang,
format: 'json',
callback: callbackName,
prop: 'images|revisions',
imlimit: 'max',
rvlimit: '1',
rvprop: 'content',
titles: title
}),
callback
);
}
/* 最後に実行される関数 */
var last = function(){
progress(100);
sort();
redrawUI();
if ( imageTitles.length == 0 ) {
$( '#' + rootId ).toggle(false);
} else {
$( 'form.control', getRoot() ).toggle(true);
}
};
for (var lang in llmap) (function (lang) {
var title = llmap[lang];
var last0 = last; // このスコープに定着させるため
last = function() {
++c;
progress(100 * c / max);
setTimeout(
function(){ getImageTitles(lang, title, last0); },
interval
);
};
++max;
})(lang);
if (typeof last == 'function') {
last(); // 最後に生成したものから遡って実行する
}
});
}); /* end of ready */})(window, document);