Benutzer:Bullfrogggy/common.js
Zur Navigation springen
Zur Suche springen
Hinweis: Leere nach dem Veröffentlichen den Browser-Cache, um die Änderungen sehen zu können.
- Firefox/Safari: Umschalttaste drücken und gleichzeitig Aktualisieren anklicken oder entweder Strg+F5 oder Strg+R (⌘+R auf dem Mac) drücken
- Google Chrome: Umschalttaste+Strg+R (⌘+Umschalttaste+R auf dem Mac) drücken
- Edge: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
//Dokumentation unter [[Benutzer:Schnark/js/small-world]] <nowiki>
/*global mediaWiki*/
(function ($, mw) {
"use strict";
var namespace, linkCache, l10n = {
en: {
'pagetitle': '$1 - {{SITENAME}}',
'small-world-title': 'Shortest connection',
'small-world-legend': 'Shortest connection',
'small-world-from': 'From:',
'small-world-to': 'To:',
'small-world-random': '⚄',
'small-world-random-title': 'Random article',
'small-world-namespace': 'Namespace:',
'small-world-namespace-all': 'all',
'small-world-namespace-main': 'articles',
'small-world-namespace-other': 'other:',
'small-world-namespace-other-title': 'Enter the numbers of the namespaces separeted by pipes',
'small-world-submit': 'Find connection',
'small-world-swap': '⇄',
'small-world-swap-title': 'Swap the two articles',
'small-world-empty': 'Please enter an article for both "From" and "To"!',
'small-world-invalid-title': 'Article titles can\'t contain a pipe (<code>|</code>)!',
'small-world-progress': 'Searching … (length: $2, articles: $1)',
'small-world-no-path': 'No connection could be found.',
'small-world-path': 'The shortest connection has length $1: $2'
},
de: {
'pagetitle': '$1 – {{SITENAME}}',
'small-world-title': 'Kürzeste Verbindung',
'small-world-legend': 'Kürzeste Verbindung',
'small-world-from': 'Startartikel:',
'small-world-to': 'Zielartikel:',
'small-world-random-title': 'Zufälliger Artikel',
'small-world-namespace': 'Namensraum:',
'small-world-namespace-all': 'alle',
'small-world-namespace-main': 'Artikel',
'small-world-namespace-other': 'Sonstige:',
'small-world-namespace-other-title': 'Nummern der Namensräume Pipe-separiert angeben',
'small-world-submit': 'Verbindung suchen',
'small-world-swap-title': 'Start- und Zielartikel vertauschen',
'small-world-empty': 'Bitte sowohl den Start- als auch den Zielartikel angeben!',
'small-world-invalid-title': 'Artikelnamen können keinen senkrechten Strich (<code>|</code>) enthalten!',
'small-world-progress': 'Verbindung wird gesucht … (Länge: $2, Artikel: $1)',
'small-world-no-path': 'Es wurde keine Verbindung gefunden.',
'small-world-path': 'Die kürzeste Verbindung hat die Länge $1: $2'
}
};
function initL10N (l10n, keep) {
var i, chain = mw.language.getFallbackLanguageChain();
keep = $.grep(mw.messages.get(keep), function (val) {
return val !== null;
});
for (i = chain.length - 1; i >= 0; i--) {
if (chain[i] in l10n) {
mw.messages.set(l10n[chain[i]]);
}
}
mw.messages.set(keep);
}
function setNamespace (ns) {
if (namespace !== ns) {
linkCache = [{}, {}];
}
namespace = ns;
}
function getRandom () {
var deferred = $.Deferred(), param = {action: 'query', list: 'random', format: 'json', formatversion: 2};
if (namespace) {
param.rnnamespace = namespace;
}
$.getJSON(mw.util.wikiScript('api'), param).done(function (json) {
if (json && json.query && json.query.random && json.query.random[0]) {
deferred.resolve(json.query.random[0].title);
} else {
deferred.resolve('');
}
}).fail(function () {
deferred.resolve('');
});
return deferred.promise();
}
function getLinksAPI (title, back) {
var deferred = $.Deferred(), list = [];
function nextCall (continueParam) {
getLinksAPIWithContinue(title, back, continueParam).done(function (json) {
var result, i;
if (!json) {
deferred.resolve(list);
return;
}
if (back) {
result = json.query && json.query.backlinks;
} else {
result = json.query && json.query.pages &&
json.query.pages[0] && json.query.pages[0].links;
}
if (result) {
for (i = 0; i < result.length; i++) {
list.push(result[i].title);
}
}
if (json['continue']) {
nextCall(json['continue']);
} else {
deferred.resolve(list);
}
}).fail(function () {
deferred.resolve(list);
});
}
nextCall({'continue': ''});
return deferred.promise();
}
function getLinksAPIWithContinue (title, back, continueParam) {
var param = continueParam;
param.action = 'query';
param.format = 'json';
param.formatversion = 2;
if (back) {
param.list = 'backlinks';
param.bltitle = title;
if (namespace) {
param.blnamespace = namespace;
}
param.bllimit = 'max';
//param.blredirect = 1; findet nur Links auf Weiterleitungen, keine Weiterleitungen auf Links
} else {
param.prop = 'links';
param.titles = title;
if (namespace) {
param.plnamespace = namespace;
}
//param.redirects = 1;
param.pllimit = 'max';
}
return $.getJSON(mw.util.wikiScript('api'), param);
}
function getLinks (title, back) {
if (!(title in linkCache[back ? 1 : 0])) {
linkCache[back ? 1 : 0][title] = getLinksAPI(title, back);
}
return linkCache[back ? 1 : 0][title];
}
function findPath (from, to) {
var pred = {}, succ = {}, fromList = [from], toList = [to],
nodes = 0, depth = 2,
back = false, nextDirChange = 1,
deferred = $.Deferred();
function getPath (middle) {
var path = [];
path.push(middle);
while (middle !== to) {
middle = succ[middle];
path.push(middle);
}
middle = path[0];
while (middle !== from) {
middle = pred[middle];
path.unshift(middle);
}
return path;
}
function findRecursive () {
var list = back ? toList : fromList,
hash = back ? succ : pred,
otherHash = back ? pred : succ,
el;
if (list.length === 0) {
deferred.reject();
return;
}
el = list.shift();
getLinks(el, back).done(function (next) {
var i;
nodes++;
deferred.notify({nodes: nodes, depth: depth});
for (i = 0; i < next.length; i++) {
if (!(next[i] in hash)) {
list.push(next[i]);
hash[next[i]] = el;
if (next[i] in otherHash) {
deferred.resolve(getPath(next[i]));
return;
}
}
}
nextDirChange--;
if (nextDirChange === 0) {
back = !back;
depth++;
nextDirChange = back ? toList.length : fromList.length;
}
findRecursive();
}).fail(deferred.reject);
}
if (from === to) {
deferred.resolve([from]);
} else {
findRecursive();
}
return deferred.promise();
}
function createInterface () {
document.title = mw.msg('pagetitle', mw.msg('small-world-title'));
$('#firstHeading').text(mw.msg('small-world-title'));
createForm($('#mw-content-text'));
$('#smallWorldFromRandom').click(randomFrom);
$('#smallWorldToRandom').click(randomTo);
searchSuggestions('#smallWorldFrom');
searchSuggestions('#smallWorldTo');
$('#smallWorldNamespaceAll, #smallWorldNamespaceMain, #smallWorldNamespaceOther').click(function () {
changeNS($('#smallWorldNamespace :checked').val());
});
$('#smallWorldSwap').click(swapFields);
$('#smallWorldSubmit').click(run);
}
function makeRadioButton (value, id, labelMsg, checked) {
return mw.html.element('input', {type: 'radio', name: 'smallWorldNamespace', value: value, checked: checked, id: id}) +
mw.html.element('label', {'for': id}, mw.msg(labelMsg)) + ' ';
}
function createForm ($container) {
$container.html(
mw.html.element('fieldset', {}, new mw.html.Raw(
mw.html.element('legend', {}, mw.msg('small-world-legend')) +
mw.html.element('table', {}, new mw.html.Raw(
generateInput('smallWorldFrom', 'small-world-from', 'from') +
generateInput('smallWorldTo', 'small-world-to', 'to') +
'<tr><td class="mw-label">' + mw.msg('small-world-namespace') + '</td>' +
'<td id="smallWorldNamespace" class="mw-input">' +
makeRadioButton('', 'smallWorldNamespaceAll', 'small-world-namespace-all', false) +
makeRadioButton('0', 'smallWorldNamespaceMain', 'small-world-namespace-main', true) +
makeRadioButton('?', 'smallWorldNamespaceOther', 'small-world-namespace-other', false) +
mw.html.element('input', {type: 'text', size: 5, id: 'smallWorldNamespaceOtherInput',
title: mw.msg('small-world-namespace-other-title')}) +
'</td></tr>' +
'<tr><td></td><td>' +
mw.html.element('input', {type: 'button', id: 'smallWorldSubmit',
value: mw.msg('small-world-submit')}) + ' ' +
mw.html.element('input', {type: 'button', id: 'smallWorldSwap',
value: mw.msg('small-world-swap'), title: mw.msg('small-world-swap-title')}) +
'</td></tr>'
))
)) + mw.html.element('p', {id: 'smallWorldResult'}, '')
);
}
function generateInput (id, labelMsg, param) {
return '<tr><td class="mw-label">' +
mw.html.element('label', {'for': id}, mw.msg(labelMsg)) +
'</td><td class="mw-input">' +
mw.html.element('input', {type: 'text', id: id, size: 50, value: mw.util.getParamValue(param) || ''}) +
mw.html.element('input', {type: 'button', id: id + 'Random',
value: mw.msg('small-world-random'), title: mw.msg('small-world-random-title')}) +
'</td></tr>';
}
function searchSuggestions (id) {
var $el = $(id), param = {action: 'opensearch', suggest: ''};
$el.suggestions({
fetch: function (query, response, maxRows) {
if (query.length !== 0) {
param.search = query;
param.limit = maxRows;
$el.data('request', $.getJSON(mw.util.wikiScript('api'), param).done(function (json) {
if (json && json[1]) {
response(json[1]);
}
}));
}
},
cancel: function () {
if ($el.data('request') && $.isFunction($el.data('request').abort)) {
$el.data('request').abort();
}
}
});
}
function changeNS (val) {
if (val === '?') {
val = $('#smallWorldNamespaceOtherInput').val();
}
setNamespace(val);
}
function swapFields () {
var from = $('#smallWorldFrom').val(), to = $('#smallWorldTo').val();
$('#smallWorldFrom').val(to);
$('#smallWorldTo').val(from);
}
function randomFromOrTo (id) {
getRandom().done(function (title) {
if (title) {
$(id).val(title);
}
});
}
function randomFrom () {
randomFromOrTo('#smallWorldFrom');
}
function randomTo () {
randomFromOrTo('#smallWorldTo');
}
function run () {
var $result = $('#smallWorldResult'), from = $('#smallWorldFrom').val(), to = $('#smallWorldTo').val();
if (!from || !to) {
$result.html(mw.msg('small-world-empty'));
} else if (from.indexOf('|') > -1 || to.indexOf('|') > -1) {
$result.html(mw.msg('small-world-invalid-title'));
} else {
$('#smallWorldSubmit, #smallWorldNamespace input').prop('disabled', true);
$result.empty().injectSpinner('small-world');
findPath(from, to).progress(showProgress).always(function () {
$('#smallWorldSubmit, #smallWorldNamespace input').prop('disabled', false);
$.removeSpinner('small-world');
}).done(function (path) {
$result.html(showPath(path));
mw.hook('wikipage.content').fire($result);
}).fail(function () {
$result.html(mw.msg('small-world-no-path'));
});
}
}
function showProgress (data) {
$('#smallWorldResult').html(mw.msg('small-world-progress', data.nodes, data.depth));
}
function showPath (path) {
var i, links = [], arrow = $('body').is('.rtl') ? '←' : '→';
for (i = 0; i < path.length; i++) {
links.push(mw.html.element('a', {href: mw.util.getUrl(path[i])}, path[i]));
}
return mw.msg('small-world-path', path.length, links.join(' ' + arrow + ' '));
}
function init () {
initL10N(l10n, ['pagetitle']);
setNamespace('0');
if (mw.config.get('wgCanonicalSpecialPageName') === 'Blankpage' && mw.util.getParamValue('action') === 'small-world') {
mw.loader.using(['mediawiki.jqueryMsg', 'jquery.spinner', 'jquery.suggestions'], function () {
$(createInterface);
});
}
}
mw.loader.using(['mediawiki.util', 'mediawiki.language'], init);
})(jQuery, mediaWiki);
//</nowiki>