Benutzer:Schnark/js/bandersnatch.js
< Benutzer:Schnark | js
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/bandersnatch]] <nowiki>
/*global mediaWiki, OO*/
(function ($, mw, libs) {
"use strict";
//jscs:disable maximumLineLength
var global = {}, l10n = {
en: {
'diff': 'diff',
'minoreditletter': 'm',
'boteditletter': 'b',
'article': 'Content page',
'pagehist': 'Page history',
'schnark-bandersnatch-error-abort': 'abort',
'schnark-bandersnatch-error-editconflict': 'edit conflict',
'schnark-bandersnatch-error-jserror': 'error in JS code',
'schnark-bandersnatch-error-lostlogin': 'login got lost',
'schnark-bandersnatch-error-maxlag': 'database lag too big',
'schnark-bandersnatch-error-noedit': 'no edit necessary',
'schnark-bandersnatch-error-notverified': 'discarded',
'schnark-bandersnatch-error-server': 'server error',
'schnark-bandersnatch-error-spam': 'detected as spam',
'schnark-bandersnatch-error-unknown': 'unknown error',
'schnark-bandersnatch-error-preview': 'Preview failed!',
'schnark-bandersnatch-error-diff': 'Diff script not loaded!',
'schnark-bandersnatch-diff-show': 'show diff',
'schnark-bandersnatch-diff-hide': 'hide diff',
'schnark-bandersnatch-preview-wait': 'Preview is being generated',
'schnark-bandersnatch-batch-summary': 'Edit summary:',
'schnark-bandersnatch-batch-minor': 'minor edit',
'schnark-bandersnatch-batch-bot': 'bot edit',
'schnark-bandersnatch-batch-preview': 'Preview',
'schnark-bandersnatch-batch-diff': 'Diff',
'schnark-bandersnatch-batch-revert': 'Discard change',
'schnark-bandersnatch-batch-skip': 'Skip',
'schnark-bandersnatch-batch-save': 'Save',
'schnark-bandersnatch-check-no': 'Discard change',
'schnark-bandersnatch-check-ok': 'Accept change',
'schnark-bandersnatch-abort': 'Abort',
'schnark-bandersnatch-step-continue': 'Continue',
'schnark-bandersnatch-step-back': 'Back',
'schnark-bandersnatch-step-go': 'Go!',
'schnark-bandersnatch-step-1-head': 'Pages',
'schnark-bandersnatch-step-1-search-simple': 'In a first step you must specify which pages should be edited. Enter one title per line to do so. If you use my script search++, you\'ll have a way to use complex queries to find pages.',
'schnark-bandersnatch-step-1-search-complex': 'In a first step you must specify which pages should be edited. Enter one title per line to do so. You can also use the search.',
'schnark-bandersnatch-step-1-search-query': 'Search query:',
'schnark-bandersnatch-step-1-search-submit': 'Search',
'schnark-bandersnatch-step-1-search-error': 'Error: $1',
'schnark-bandersnatch-step-1-pages': 'Pages:',
'schnark-bandersnatch-step-1-xml': 'You also can upload an XML dump.',
'schnark-bandersnatch-step-1-xml-read': 'Upload an XML dump',
'schnark-bandersnatch-step-2-head': 'Code',
'schnark-bandersnatch-step-2-text': 'In a second step you must enter the JavaScript code that should be used to edit the pages. Enter the body of a function with parameters <code>title</code> for the title, and <code>oldText</code> for the old text of the page, which returns an object with properties <code>text</code> (the new text or <code>false</code> to skip), <code>summary</code> (optional for an edit summary, otherwise the default summary will be used), <code>minor</code> (<code>true</code> or <code>false</code> to flag the edit as minor, optional), and <code>bot</code> (likewise).',
'schnark-bandersnatch-step-2-code': 'Code for edit function',
'schnark-bandersnatch-step-2-tools': 'Tools',
'schnark-bandersnatch-step-2-tools-tool': 'Tool',
'schnark-bandersnatch-step-2-tools-use': 'Usage',
'schnark-bandersnatch-step-2-tools-load': 'Load',
'schnark-bandersnatch-tool-load': 'Load',
'schnark-bandersnatch-tool-noload': 'not necessary',
'schnark-bandersnatch-tool-replace': 'Simple replacement',
'schnark-bandersnatch-tool-replace-code': 'newText = oldText.replace(/foo/g, \'bar\');',
'schnark-bandersnatch-tool-template': 'Template<br>Schnark',
'schnark-bandersnatch-tool-template-code': 'template = new mw.libs.Template(\'templateName\', oldText);\n//...e.g. template.insert(\'new parameter\', \'new value\');\nnewText = template.toString();',
'schnark-bandersnatch-step-2-test': 'Test environment',
'schnark-bandersnatch-step-2-test-title': 'Title:',
'schnark-bandersnatch-step-2-test-title-default': 'Test title:',
'schnark-bandersnatch-step-2-test-text': 'Test content:',
'schnark-bandersnatch-step-2-test-run': 'Run test',
'schnark-bandersnatch-step-3-head': 'Parameter',
'schnark-bandersnatch-step-3-text': 'As a last step now enter the default parameters for all edits and make sure that you know what you are doing before clicking "Go!"',
'schnark-bandersnatch-step-3-summary': 'Edit summary:',
'schnark-bandersnatch-step-3-minor': 'minor edit',
'schnark-bandersnatch-step-3-bot': 'bot edit',
'schnark-bandersnatch-step-3-wait': 'Time between two edits (seconds):',
'schnark-bandersnatch-step-3-maxlag': 'Maxlag:',
'schnark-bandersnatch-step-3-maxlag-ignore': 'ignore',
'schnark-bandersnatch-step-3-maxlag-5x5': '5 seconds, 5 tries',
'schnark-bandersnatch-step-3-mode': 'Mode:',
'schnark-bandersnatch-step-3-mode-simulate': 'simulae',
'schnark-bandersnatch-step-3-mode-batch': 'batch mode',
'schnark-bandersnatch-step-3-mode-check': 'semi-automatic',
'schnark-bandersnatch-step-3-mode-auto': 'automatic',
'schnark-bandersnatch-title': 'Bandersnatch',
'schnark-bandersnatch-version': 'Bandersnatch (version $1)'
},
de: {
'diff': 'Unterschied',
'minoreditletter': 'K',
'boteditletter': 'B',
'article': 'Seite',
'pagehist': 'Versionsgeschichte',
'schnark-bandersnatch-error-abort': 'Abbruch',
'schnark-bandersnatch-error-editconflict': 'Bearbeitungskonflikt',
'schnark-bandersnatch-error-jserror': 'Fehler im JS-Code',
'schnark-bandersnatch-error-lostlogin': 'Login verloren gegangen',
'schnark-bandersnatch-error-maxlag': 'Datenbank-Lag zu groß',
'schnark-bandersnatch-error-noedit': 'keine Bearbeitung nötig',
'schnark-bandersnatch-error-notverified': 'verworfen',
'schnark-bandersnatch-error-server': 'Serverfehler',
'schnark-bandersnatch-error-spam': 'als Spam erkannt',
'schnark-bandersnatch-error-unknown': 'unbekannter Fehler',
'schnark-bandersnatch-error-preview': 'Vorschau fehlgeschlagen!',
'schnark-bandersnatch-error-diff': 'Diff-Skript nicht geladen!',
'schnark-bandersnatch-diff-show': 'Unterschied anzeigen',
'schnark-bandersnatch-diff-hide': 'Unterschied verstecken',
'schnark-bandersnatch-preview-wait': 'Vorschau wird ermittelt',
'schnark-bandersnatch-batch-summary': 'Bearbeitungskommentar:',
'schnark-bandersnatch-batch-minor': 'kleine Änderung',
'schnark-bandersnatch-batch-bot': 'Bot-Änderung',
'schnark-bandersnatch-batch-preview': 'Vorschau',
'schnark-bandersnatch-batch-diff': 'Unterschied',
'schnark-bandersnatch-batch-revert': 'Änderung verwerfen',
'schnark-bandersnatch-batch-skip': 'Überspringen',
'schnark-bandersnatch-batch-save': 'Speichern',
'schnark-bandersnatch-check-no': 'Verwerfen',
'schnark-bandersnatch-check-ok': 'Akzeptieren',
'schnark-bandersnatch-abort': 'Abbrechen',
'schnark-bandersnatch-step-continue': 'Weiter',
'schnark-bandersnatch-step-back': 'Zurück',
'schnark-bandersnatch-step-go': 'Los!',
'schnark-bandersnatch-step-1-head': 'Seiten',
'schnark-bandersnatch-step-1-search-simple': 'Als erstes musst du die Seiten angeben, die bearbeitet werden sollen. Schreibe dazu in jede Zeile genau einen Titel. Wenn du mein Skript search++ verwendest, hast du die Möglichkeit, komplexe Suchanfragen zu verwenden.',
'schnark-bandersnatch-step-1-search-complex': 'Als erstes musst du die Seiten angeben, die bearbeitet werden sollen. Schreibe dazu in jede Zeile genau einen Titel. Du kannst dazu auch die Suchfunktion nutzen.',
'schnark-bandersnatch-step-1-search-query': 'Suchanfrage:',
'schnark-bandersnatch-step-1-search-submit': 'Suchen',
'schnark-bandersnatch-step-1-search-error': 'Fehler: $1',
'schnark-bandersnatch-step-1-pages': 'Seiten:',
'schnark-bandersnatch-step-1-xml': 'Du kannst auch einen XML-Dump einlesen.',
'schnark-bandersnatch-step-1-xml-read': 'XML-Dump einlesen',
'schnark-bandersnatch-step-2-head': 'Code',
'schnark-bandersnatch-step-2-text': 'Als nächstes musst du den JavaScript-Code angeben, der bei der Bearbeitung verwendet werden soll. Gib den Körper einer Funktion an, die die Parameter <code>title</code> für den Titel und <code>oldText</code> für den alten Text der Seite kennt und ein Objekt mit den Eigenschaften <code>text</code> (der neue Text oder <code>false</code> zum Überspringen), <code>summary</code> (optional als Zusammenfassung, es wird die Standard-Zusammenfassung verwendet, wenn die Eigenschaft fehlt), <code>minor</code> (<code>true</code> oder <code>false</code> zur Markierung als kleine Bearbeitung, optional) und <code>bot</code> (ebenso) zurückgibt.',
'schnark-bandersnatch-step-2-code': 'Code für Bearbeitungsfunktion',
'schnark-bandersnatch-step-2-tools': 'Werkzeuge',
'schnark-bandersnatch-step-2-tools-tool': 'Werkzeug',
'schnark-bandersnatch-step-2-tools-use': 'Verwendung',
'schnark-bandersnatch-step-2-tools-load': 'Laden',
'schnark-bandersnatch-tool-load': 'Laden',
'schnark-bandersnatch-tool-noload': 'nicht nötig',
'schnark-bandersnatch-tool-replace': 'Einfache Ersetzung',
'schnark-bandersnatch-tool-replace-code': 'neu = alt.replace(/foo/g, \'bar\');',
'schnark-bandersnatch-tool-template': 'Template<br>Schnark',
'schnark-bandersnatch-tool-template-code': 'template = new mw.libs.Template(\'Vorlagenname\', alt);\n//...z. B. template.insert(\'neuer Parameter\', \'neuer Wert\');\nneu = template.toString();',
'schnark-bandersnatch-step-2-test': 'Testumgebung',
'schnark-bandersnatch-step-2-test-title': 'Titel:',
'schnark-bandersnatch-step-2-test-title-default': 'Testtitel',
'schnark-bandersnatch-step-2-test-text': 'Text:',
'schnark-bandersnatch-step-2-test-run': 'Testen',
'schnark-bandersnatch-step-3-head': 'Parameter',
'schnark-bandersnatch-step-3-text': 'Gib als letztes die Standard-Parameter für alle Bearbeitungen an und stelle sicher, dass du weißt, was du tust, bevor du auf „Los!“ klickst.',
'schnark-bandersnatch-step-3-summary': 'Bearbeitungskommentar:',
'schnark-bandersnatch-step-3-minor': 'kleine Änderung',
'schnark-bandersnatch-step-3-bot': 'Bot-Änderung',
'schnark-bandersnatch-step-3-wait': 'Sekunden zwischen Bearbeitungen:',
'schnark-bandersnatch-step-3-maxlag': 'Maxlag:',
'schnark-bandersnatch-step-3-maxlag-ignore': 'Ignorieren',
'schnark-bandersnatch-step-3-maxlag-5x5': '5 Sekunden, 5 Versuche',
'schnark-bandersnatch-step-3-mode': 'Modus:',
'schnark-bandersnatch-step-3-mode-simulate': 'Simulation',
'schnark-bandersnatch-step-3-mode-batch': 'Stapelverarbeitung',
'schnark-bandersnatch-step-3-mode-check': 'halbautomatisch',
'schnark-bandersnatch-step-3-mode-auto': 'automatisch',
'schnark-bandersnatch-title': 'Bandersnatch',
'schnark-bandersnatch-version': 'Bandersnatch (Version $1)'
},
'de-ch': {
'schnark-bandersnatch-error-maxlag': 'Datenbank-Lag zu gross',
'schnark-bandersnatch-step-3-text': 'Gib als letztes die Standard-Parameter für alle Bearbeitungen an und stelle sicher, dass du weisst, was du tust, bevor du auf «Los!» klickst.'
},
'de-formal': {
'schnark-bandersnatch-step-1-search-simple': 'Als erstes müssen Sie die Seiten angeben, die bearbeitet werden sollen. Schreiben Sie dazu in jede Zeile genau einen Titel. Wenn Sie mein Skript search++ verwenden, haben Sie die Möglichkeit, komplexe Suchanfragen zu verwenden.',
'schnark-bandersnatch-step-1-search-complex': 'Als erstes müssen Sie die Seiten angeben, die bearbeitet werden sollen. Schreiben Sie dazu in jede Zeile genau einen Titel. Sie können dazu auch die Suchfunktion nutzen.',
'schnark-bandersnatch-step-1-xml': 'Sie können auch einen XML-Dump einlesen.',
'schnark-bandersnatch-step-2-text': 'Als nächstes müssen Sie den JavaScript-Code angeben, der bei der Bearbeitung verwendet werden soll. Geben Sie den Körper einer Funktion an, die die Parameter <code>title</code> für den Titel und <code>oldText</code> für den alten Text der Seite kennt und ein Objekt mit den Eigenschaften <code>text</code> (der neue Text oder <code>false</code> zum Überspringen), <code>summary</code> (optional als Zusammenfassung, es wird die Standard-Zusammenfassung verwendet, wenn die Eigenschaft fehlt), <code>minor</code> (<code>true</code> oder <code>false</code> zur Markierung als kleine Bearbeitung, optional) und <code>bot</code> (ebenso) zurückgibt.',
'schnark-bandersnatch-step-3-text': 'Geben Sie als letztes die Standard-Parameter für alle Bearbeitungen an und stellen Sie sicher, dass Sie wissen, was Sie tun, bevor Sie auf „Los!“ klicken.'
}
};
//jscs:enable maximumLineLength
global.version = '2.1';
(function () {
//Backend
var ABORT = 0,
EDITCONFLICT = 1,
LOSTLOGIN = 2,
MAXLAG = 3,
NOEDIT = 4,
NOTVERIFIED = 5,
SERVER = 6,
SPAM = 7,
UNKNOWN = 8,
JSERROR = 9;
global.error = {
ABORT: ABORT,
EDITCONFLICT: EDITCONFLICT,
LOSTLOGIN: LOSTLOGIN,
MAXLAG: MAXLAG,
NOEDIT: NOEDIT,
NOTVERIFIED: NOTVERIFIED,
SERVER: SERVER,
SPAM: SPAM,
UNKNOWN: UNKNOWN,
JSERROR: JSERROR
};
function makeParam (data, maxlag) {
var param = {
action: 'edit',
title: data.title,
text: data.text,
summary: data.summary,
basetimestamp: data.basetimestamp,
starttimestamp: data.starttimestamp,
token: data.token,
format: 'json',
formatversion: 2
};
if (data.bot) {
param.bot = '';
}
if (data.minor) {
param.minor = '';
} else {
param.notminor = '';
}
if (maxlag !== false) {
param.maxlag = maxlag;
}
return param;
}
function reallyEdit (data, maxlagF, onSuccess, onError, n) {
n = n || 0;
var maxlag = maxlagF(n), headers = {};
if (maxlag === true) {
onError(MAXLAG);
return;
}
if (mw.user.options.get('userjs-schnark-bandersnatch-ua', true)) {
headers['Api-User-Agent'] =
mw.user.options.get('userjs-schnark-bandersnatch-ua', 'bandersnatch.js/v' + global.version);
}
$.ajax({
url: mw.util.wikiScript('api'),
data: makeParam(data, maxlag),
type: 'post',
headers: headers,
dataType: 'json'
}).then(function (json) {
if (json && json.edit && json.edit.result === 'Success') {
onSuccess();
} else if (json && json.error) {
switch (json.error.code) {
case 'maxlag':
if (maxlagF(n + 1) === true) {
onError(MAXLAG);
} else {
window.setTimeout(function () {
reallyEdit(data, maxlagF, onSuccess, onError, n + 1);
}, (maxlagF(n, true) || 5) * 1000);
}
break;
case 'editconflict':
case 'pagedeleted':
onError(EDITCONFLICT);
break;
case 'spamdetected':
onError(SPAM);
break;
default:
onError(UNKNOWN);
}
} else {
onError(SERVER);
}
}, function () {
onError(SERVER);
});
}
function getData (title, onSuccess, onError) {
$.getJSON(mw.util.wikiScript('api'), {
action: 'query',
prop: 'info|revisions',
meta: 'tokens',
titles: title,
rvprop: 'timestamp|content',
rvslots: 'main',
rvlimit: 1,
curtimestamp: true,
assert: 'user',
format: 'json',
formatversion: 2
}).then(function (json) {
var text = '', basetimestamp, page;
if (json && json.error && json.error.code === 'assertuserfailed') {
onError(LOSTLOGIN);
return;
}
if (!json || !json.query || !json.query.pages || !json.query.tokens || !json.curtimestamp) {
onError(SERVER);
return;
}
page = json.query.pages[0];
if (!page) {
onError(SERVER);
return;
}
if (page.missing) {
basetimestamp = json.curtimestamp;
} else if (page.revisions && page.revisions[0]) {
text = page.revisions[0].slots.main.content;
basetimestamp = page.revisions[0].timestamp;
} else {
onError(SERVER);
return;
}
onSuccess({
text: text,
basetimestamp: basetimestamp,
starttimestamp: json.curtimestamp,
token: json.query.tokens.csrftoken
});
}, function () {
onError(SERVER);
});
}
function editOne (title, timestamp, defaultParam, editF, verifyF, abortF, maxlagF, onSuccess, onError) {
if (abortF()) {
onError(ABORT);
return;
}
getData(title, function (data) {
if (abortF()) {
onError(ABORT);
return;
}
editF(title, data.text, function (ret) {
var edit = $.extend({text: false}, defaultParam, ret || {text: false});
if (abortF()) {
onError(ABORT);
return;
}
if (edit.error) {
onError(JSERROR);
return;
}
if (edit.text === false || edit.text === data.text) {
onError(NOEDIT);
return;
}
verifyF(title, data.text, edit, function () {
if (abortF()) {
onError(ABORT);
return;
}
var wait = Math.round(timestamp - mw.now());
if (wait < 0) {
wait = 0;
}
window.setTimeout(function () {
reallyEdit({
title: title,
text: edit.text,
summary: edit.summary,
minor: edit.minor,
bot: edit.bot,
basetimestamp: data.basetimestamp,
starttimestamp: data.starttimestamp,
token: data.token
}, maxlagF, function () {
onSuccess({
oldText: data.text,
newText: edit.text,
summary: edit.summary,
minor: edit.minor,
bot: edit.bot
});
}, onError);
}, wait);
}, function () {
onError(NOTVERIFIED);
});
});
}, onError);
}
function editMany (titles, wait, defaultParam, editF, verifyF, abortF, maxlagF, onSuccess, onError, onFinish) {
var i = -1, title = '', timestamp = 0;
function successHandler (data) {
timestamp = mw.now();
onSuccess(title, data);
editNext();
}
function errorHandler (code) {
onError(title, code);
if (code === ABORT || code === LOSTLOGIN) {
onFinish();
} else {
editNext();
}
}
function editNext () {
i++;
if (i >= titles.length) {
onFinish();
return;
}
title = titles[i];
editOne(title, timestamp + wait, defaultParam, editF, verifyF, abortF, maxlagF, successHandler, errorHandler);
}
editNext();
}
global.editMany = editMany;
})();
(function () {
//Verbindung Backend-Frontend
function getErrorDescription (code) {
switch (code) {
case global.error.ABORT: code = 'abort'; break;
case global.error.EDITCONFLICT: code = 'editconflict'; break;
case global.error.JSERROR: code = 'jserror'; break;
case global.error.LOSTLOGIN: code = 'lostlogin'; break;
case global.error.MAXLAG: code = 'maxlag'; break;
case global.error.NOEDIT: code = 'noedit'; break;
case global.error.NOTVERIFIED: code = 'notverified'; break;
case global.error.SERVER: code = 'server'; break;
case global.error.SPAM: code = 'spam'; break;
case global.error.UNKNOWN: code = 'unknown'; break;
}
return mw.msg('schnark-bandersnatch-error-' + code);
}
function getEditFlags (minor, bot) {
return (minor ? '<b>' + mw.msg('minoreditletter') + '</b>' : ' ') + ' ' +
(bot ? '<b>' + mw.msg('boteditletter') + '</b>' : ' ');
}
function getEditHtml (title, edit, inclDiffLink) {
var diff = global.diff(edit.oldText, edit.newText),
diffLink = ' (' + mw.html.element('a', {href: mw.util.getUrl(title, {diff: 'curr'})}, mw.msg('diff')) + ')';
return mw.html.element('a', {href: mw.util.getUrl(title)}, title) +
(inclDiffLink ? diffLink : '') +
mw.html.element('br') + getEditFlags(edit.minor, edit.bot) + ' ' +
mw.html.element('code', {}, edit.summary) +
mw.html.element('div', {
'data-collapsetext': mw.msg('schnark-bandersnatch-diff-hide'),
'data-expandtext': mw.msg('schnark-bandersnatch-diff-show')
}, new mw.html.Raw(diff));
}
function showEdit (title, edit, type) {
var $li = $('<li>').html(getEditHtml(title, edit, type !== 'simulate'));
$li.find('div').addClass('mw-collapsed').makeCollapsible();
global.addLog($li, type || 'success');
}
function showError (title, code) {
var $li = $('<li>').addClass('autoedit-error').html(
mw.html.element('a', {href: mw.util.getUrl(title)}, title) +
' – ' + getErrorDescription(code)
);
global.addLog($li, 'error');
}
function verifySimulate (title, oldText, edit, doit, dontdoit) {
showEdit(title, {
oldText: oldText,
newText: edit.text,
summary: edit.summary,
minor: edit.minor,
bot: edit.bot
}, 'simulate');
dontdoit();
}
function errorSimulate (title, code) {
if (code !== global.error.NOTVERIFIED) {
showError(title, code);
}
}
function verifyCheck (title, oldText, edit, doit, dontdoit) {
var html = getEditHtml(title, {
oldText: oldText,
newText: edit.text,
summary: edit.summary,
minor: edit.minor,
bot: edit.bot
}, 'check');
global.checkEdit(html, function (verified) {
if (verified) {
doit();
} else {
dontdoit();
}
});
}
function verifyAuto (title, oldText, edit, doit /*, dontdoit*/) {
doit();
}
function getHandlersFor (type) {
switch (type) {
case 'simulate':
return [verifySimulate, $.noop, errorSimulate];
case 'batch':
case 'auto':
return [verifyAuto, showEdit, showError];
case 'check':
return [verifyCheck, showEdit, showError];
}
}
function makeFunction (code) {
/*jshint evil: true*/
var f;
try {
f = new Function ('title', 'oldText', code);
return function (title, oldText) {
try {
return f(title, oldText);
} catch (e) {
return {error: e};
}
};
} catch (e) {
return function () {
return {error: e};
};
}
}
function getEditFunction (code, type, defaultParam) {
var f = makeFunction(code);
if (type === 'batch') {
return function (title, oldText, callback) {
var edit = $.extend({text: false}, defaultParam, f(title, oldText) || {text: false});
if (edit.text === false) {
callback(edit);
} else {
global.batchEdit(title, edit, oldText, callback);
}
};
} else {
return function (title, oldText, callback) {
callback(f(title, oldText));
};
}
}
function maxlagIgnore () {
return false;
}
function maxlag5x5 (n) {
if (n >= 5) {
return true;
}
return 5;
}
function getMaxlagFunction (type) {
switch (type) {
case 'ignore': return maxlagIgnore;
case 'default': return maxlag5x5;
}
}
function editFromForm (
titleList, defaultSummary, defaultMinor, defaultBot, waitSeconds,
maxlagType, editCode, editType, abortButton, onFinish
) {
var abort = false,
titles = titleList.replace(/\r\n/g, '\n').replace(/^\n+|\n+$/g, '').split('\n'),
wait = Number(waitSeconds) * 1000,
defaultParam = {
summary: defaultSummary,
minor: defaultMinor,
bot: defaultBot
},
editF = getEditFunction(editCode, editType, defaultParam),
funcs = getHandlersFor(editType),
verifyF = funcs[0],
//jscs:disable requireFunctionDeclarations
abortF = function () {
return abort;
},
//jscs:enable requireFunctionDeclarations
maxlagF = getMaxlagFunction(maxlagType),
onSuccess = funcs[1],
onError = funcs[2];
abortButton.on('click', function () {
abort = true;
});
global.editMany(titles, wait, defaultParam, editF, verifyF, abortF, maxlagF, onSuccess, onError, onFinish);
}
global.editFromForm = editFromForm;
global.makeFunction = makeFunction;
})();
(function () {
//Check mode
var $edit, checkPanel, currentCallback;
function verify () {
checkPanel.toggle(false);
if (currentCallback) {
currentCallback(true);
}
}
function cancel () {
checkPanel.toggle(false);
if (currentCallback) {
currentCallback(false);
}
}
function checkEdit (html, callback) {
$edit.html(html);
currentCallback = callback;
checkPanel.toggle(true);
}
function makeCheckInterface ($container, abortButton) {
var noButton, okButton, buttonBar, buttonFieldset;
$edit = $('<div>');
noButton = new OO.ui.ButtonWidget({
id: 'check-no', //ID here and below only to make testing easy
label: mw.msg('schnark-bandersnatch-check-no'),
icon: 'close',
flags: ['primary', 'destructive']
});
okButton = new OO.ui.ButtonWidget({
label: mw.msg('schnark-bandersnatch-check-ok'),
icon: 'check',
flags: ['primary', 'progressive']
});
buttonBar = new OO.ui.HorizontalLayout({
items: [noButton, okButton]
});
buttonFieldset = new OO.ui.FieldsetLayout({
items: [
new OO.ui.FieldLayout(new OO.ui.Widget({content: [buttonBar]}))
]
});
noButton.on('click', cancel);
okButton.on('click', verify);
abortButton.on('click', cancel);
checkPanel = new OO.ui.PanelLayout({
expanded: false,
framed: true,
padded: true,
$content: $('<div>').append(
$edit,
buttonFieldset.$element
)
});
checkPanel.toggle(false);
$container.append(checkPanel.$element);
}
global.checkEdit = checkEdit;
global.makeCheckInterface = makeCheckInterface;
})();
(function () {
//Batch mode
var widgets = {}, elements = {},
currentTitle = '', currentOldText = '', currentCallback;
function setDisabled (disabled) {
elements.$textbox.prop('disabled', disabled);
widgets.summary.setDisabled(disabled);
widgets.minor.setDisabled(disabled);
widgets.bot.setDisabled(disabled);
widgets.previewButton.setDisabled(disabled);
widgets.diffButton.setDisabled(disabled);
widgets.revertButton.setDisabled(disabled);
widgets.skipButton.setDisabled(disabled);
widgets.saveButton.setDisabled(disabled);
}
function createPreview (text, title, $area) {
$.post(mw.util.wikiScript('api'), {
action: 'parse',
title: title,
prop: 'text|categorieshtml|langlinks|modules|jsconfigvars|displaytitle|indicators',
useskin: mw.config.get('skin'),
uselang: mw.config.get('wgUserLanguage'),
pst: true,
disableeditsection: true,
preview: true,
text: text,
format: 'json',
formatversion: 2
}).then(function (json) {
if (!json || !json.parse || !json.parse.text) {
$area.html(mw.msg('schnark-bandersnatch-error-preview'));
return;
}
var html = json.parse.text, indicators = [];
if (json.parse.categorieshtml) {
html += json.parse.categorieshtml;
}
if (json.parse.langlinks && json.parse.langlinks.length) {
html += '<hr>' + json.parse.langlinks.map(function (ll) {
return mw.html.element('a', {
href: ll.url,
title: ll.langname + ' – ' + ll.title
}, ll.autonym);
}).join(', ');
}
if (json.parse.displaytitle) {
elements.$title.html(json.parse.displaytitle);
}
$.each(json.parse.indicators, function (name, indicator) {
indicators.push(
$('<div>')
.addClass('mw-indicator')
.attr('id', mw.util.escapeIdForAttribute('mw-indicator-' + name))
.html(indicator)
.get(0),
document.createTextNode('\n')
);
});
$('.mw-indicators').empty().append(indicators);
if (json.parse.jsconfigvars) {
mw.config.set(json.parse.jsconfigvars);
}
if (json.parse.modules) {
mw.loader.load(json.parse.modules.concat(
json.parse.modulestyles
));
}
$area.html(html);
mw.hook('wikipage.content').fire($area);
}, function () {
$area.html(mw.msg('schnark-bandersnatch-error-preview'));
});
}
function showPreview () {
elements.$area.html(mw.msg('schnark-bandersnatch-preview-wait'));
createPreview(elements.$textbox.val(), currentTitle, elements.$area);
}
function showDiff () {
elements.$area.html(global.diff(currentOldText, elements.$textbox.val()));
$('.mw-indicators').empty();
}
function revertText () {
elements.$textbox.val(currentOldText);
}
function skipEdit () {
setDisabled(true);
if (currentCallback) {
currentCallback({text: false});
}
}
function saveEdit () {
setDisabled(true);
if (currentCallback) {
currentCallback({
text: elements.$textbox.val(),
summary: widgets.summary.getValue(),
minor: widgets.minor.isSelected(),
bot: widgets.bot.isSelected()
});
}
}
function batchEdit (title, edit, oldText, callback) {
currentTitle = title;
currentOldText = oldText;
currentCallback = callback;
document.title = document.title.replace(/ –.*/, '') + ' – ' + title;
$('.mw-indicators').empty();
elements.$title.text(title);
elements.$information.html(
mw.html.element('a', {href: mw.util.getUrl(title)}, mw.msg('article')) +
' (' + mw.html.element('a', {href: mw.util.getUrl(title, {action: 'history'})}, mw.msg('pagehist')) + ')'
);
elements.$area.html(global.diff(oldText, edit.text));
elements.$textbox.val(edit.text);
widgets.summary.setValue(edit.summary);
widgets.minor.setSelected(edit.minor);
widgets.bot.setSelected(edit.bot);
setDisabled(false);
}
function makeBatchInterface ($container, abortButton, isBot) {
var summaryInput, minorInput, botInput,
previewButton, diffButton, revertButton, skipButton, saveButton,
buttonBar, controlFieldset;
summaryInput = new OO.ui.TextInputWidget({
id: 'batch-summary'
});
minorInput = new OO.ui.CheckboxInputWidget();
botInput = new OO.ui.CheckboxInputWidget();
previewButton = new OO.ui.ButtonWidget({
id: 'batch-preview',
label: mw.msg('schnark-bandersnatch-batch-preview'),
icon: 'article'
});
diffButton = new OO.ui.ButtonWidget({
label: mw.msg('schnark-bandersnatch-batch-diff'),
icon: 'articles'
});
revertButton = new OO.ui.ButtonWidget({
label: mw.msg('schnark-bandersnatch-batch-revert'),
icon: 'undo',
flags: 'destructive'
});
skipButton = new OO.ui.ButtonWidget({
id: 'batch-skip',
label: mw.msg('schnark-bandersnatch-batch-skip'),
icon: 'close',
flags: 'destructive'
});
saveButton = new OO.ui.ButtonWidget({
label: mw.msg('schnark-bandersnatch-batch-save'),
icon: 'check',
flags: ['progressive', 'primary']
});
previewButton.on('click', showPreview);
diffButton.on('click', showDiff);
revertButton.on('click', revertText);
skipButton.on('click', skipEdit);
saveButton.on('click', saveEdit);
abortButton.on('click', skipEdit);
buttonBar = new OO.ui.HorizontalLayout({
items: [previewButton, diffButton, revertButton, skipButton, saveButton]
});
controlFieldset = new OO.ui.FieldsetLayout({
items: [
new OO.ui.FieldLayout(summaryInput, {
label: mw.msg('schnark-bandersnatch-batch-summary'),
align: 'top'
}),
new OO.ui.FieldLayout(minorInput, {
label: mw.msg('schnark-bandersnatch-batch-minor'),
align: 'inline'
}),
new OO.ui.FieldLayout(botInput, {
label: mw.msg('schnark-bandersnatch-batch-bot'),
align: 'inline'
}).toggle(isBot),
new OO.ui.FieldLayout(
new OO.ui.Widget({content: [buttonBar]})
)
]
});
$container.append(
$('<h1>').attr('id', 'batch-title'),
$('<span>').attr('id', 'batch-information'),
$('<div>').attr({id: 'batch-area'}).html(
//FIXME: abhängig von Schreibrichtung des Wikis
'<div class="mw-content-ltr"></div>'
),
$('<textarea>').attr({id: 'batch-textbox', rows: 25, cols: 80}),
controlFieldset.$element
);
elements.$title = $container.find('#batch-title');
elements.$information = $container.find('#batch-information');
elements.$area = $container.find('#batch-area div');
elements.$textbox = $container.find('#batch-textbox');
widgets.summary = summaryInput;
widgets.minor = minorInput;
widgets.bot = botInput;
widgets.previewButton = previewButton;
widgets.diffButton = diffButton;
widgets.revertButton = revertButton;
widgets.skipButton = skipButton;
widgets.saveButton = saveButton;
setDisabled(true);
}
global.batchEdit = batchEdit;
global.makeBatchInterface = makeBatchInterface;
})();
(function () {
//Log
var map = {
success: 'check',
simulate: 'check',
error: 'close'
}, $log;
function addLog ($li, type) {
var icon = new OO.ui.IconWidget({icon: map[type]});
$li.addClass('autoedit-' + type).prepend(icon.$element);
$log.append($li);
}
function makeLog ($container) {
$log = $('<ul>');
$container.append($log);
}
global.addLog = addLog;
global.makeLog = makeLog;
})();
(function () {
//Frontend
var widgets = {};
function addCSS () {
mw.util.addCSS(
//Batch mode
'#batch-area {' +
'border: 1px dotted #36c;' +
'}' +
//Log
'#autoedit-log-container ul {' +
'list-style: none;' +
'}' +
//General
'#autoedit-abort-container {' +
'float: right;' +
'}' +
global.diffCSS()
);
}
function isBot () {
return mw.config.get('wgUserGroups').indexOf('bot') > -1;
}
function readXML () {
function fileOpen (callback) {
var $input = $('<input>').attr('type', 'file').hide().appendTo($('body'));
$input.on('change', function () {
var file = $input[0].files[0], reader = new FileReader();
if (file) {
reader.onload = function (e) {
callback(e.target.result);
};
reader.readAsText(file, 'utf-8');
}
$input.remove();
})[0].click();
}
function parseXML (content) {
var $mediawiki = $($.parseXML(content)), titles = [];
libs.xmldata = libs.xmldata || {};
$mediawiki.find('page').each(function () {
var $page = $(this), title, text;
title = $page.find('title').text();
text = $page.find('text').text();
if (title) {
libs.xmldata[title] = text;
titles.push(title);
}
});
widgets.pages.setValue(
(widgets.pages.getValue() + '\n' + titles.join('\n')).trim()
);
widgets.code.setValue('return {text: mw.libs.xmldata[title]};');
}
fileOpen(parseXML);
}
function createTitlesPanel (includeSearch) {
var searchInput, searchButton, searchFieldset,
xmlButton, xmlFieldset,
pagesInput, pagesFieldset,
nextButton, buttonFieldset;
if (includeSearch) {
searchInput = new OO.ui.MultilineTextInputWidget({
id: 'autoedit-search'
});
searchButton = new OO.ui.ButtonWidget({
id: 'autoedit-search-submit',
label: mw.msg('schnark-bandersnatch-step-1-search-submit'),
icon: 'search'
});
searchFieldset = new OO.ui.FieldsetLayout({
items: [
new OO.ui.FieldLayout(searchInput, {
label: mw.msg('schnark-bandersnatch-step-1-search-query'),
align: 'top'
}),
new OO.ui.FieldLayout(searchButton)
]
});
searchButton.on('click', function () {
global.search(searchInput.getValue()).then(function (list) {
pagesInput.setValue(
(list.join('\n') + '\n' + pagesInput.getValue()).trim()
);
}, function (error) {
pagesInput.setValue(
mw.msg('schnark-bandersnatch-step-1-search-error', error) + '\n\n' +
pagesInput.getValue()
);
});
});
}
xmlButton = new OO.ui.ButtonWidget({
label: mw.msg('schnark-bandersnatch-step-1-xml-read'),
icon: 'markup'
});
xmlFieldset = new OO.ui.FieldsetLayout({
items: [
new OO.ui.FieldLayout(xmlButton)
]
});
xmlButton.on('click', readXML);
pagesInput = new OO.ui.MultilineTextInputWidget({
id: 'autoedit-titleList',
rows: 10,
autosize: true,
maxrows: 30
});
pagesFieldset = new OO.ui.FieldsetLayout({
items: [
new OO.ui.FieldLayout(pagesInput, {
label: mw.msg('schnark-bandersnatch-step-1-pages'),
align: 'top'
})
]
});
nextButton = new OO.ui.ButtonWidget({
id: 'autoedit-page1-cont',
label: mw.msg('schnark-bandersnatch-step-continue'),
flags: ['progressive', 'primary']
});
buttonFieldset = new OO.ui.FieldsetLayout({
items: [
new OO.ui.FieldLayout(nextButton)
]
});
widgets.pages = pagesInput;
widgets.next1 = nextButton;
return new OO.ui.PanelLayout({
expanded: false,
$content: $('<div>').append(
$('<h2>').text(mw.msg('schnark-bandersnatch-step-1-head')),
$('<p>').text(
includeSearch ?
mw.msg('schnark-bandersnatch-step-1-search-complex') :
mw.msg('schnark-bandersnatch-step-1-search-simple')
),
includeSearch ? $('<div>').addClass('mw-collapsible mw-collapsed').html(global.searchHelp()) : '',
includeSearch ? searchFieldset.$element : '',
$('<p>').text(mw.msg('schnark-bandersnatch-step-1-xml')),
xmlFieldset.$element,
pagesFieldset.$element,
buttonFieldset.$element
)
});
}
function createCodePanel () {
var codeInput, codeFieldset,
tools, $tools,
testTitle, testText, testButton, testFieldset,
prevButton, nextButton, buttonBar, buttonFieldset;
function makeLoadFunction (load, button) {
return function () {
button.$element.remove();
load();
};
}
codeInput = new OO.ui.MultilineTextInputWidget({
id: 'autoedit-editCode',
value: 'return {text: oldText};',
rows: 10,
autosize: true,
maxrows: 30,
classes: ['mw-editfont-monospace']
});
codeInput.$element.prepend('<code>function (title, oldText) {</code>');
codeInput.$element.append('<code>}</code>');
codeFieldset = new OO.ui.FieldsetLayout({
items: [
new OO.ui.FieldLayout(codeInput, {
label: mw.msg('schnark-bandersnatch-step-2-code'),
align: 'top'
})
]
});
tools = [{
title: mw.msg('schnark-bandersnatch-tool-replace'),
desc: mw.msg('schnark-bandersnatch-tool-replace-code'),
load: false
}, {
title: mw.msg('schnark-bandersnatch-tool-template'),
desc: mw.msg('schnark-bandersnatch-tool-template-code'),
load: function () {
mw.loader.load('https://de.wikipedia.org/w/index.php?title=' +
'Benutzer:Schnark/js/Template.js&action=raw&ctype=text/javascript&maxage=604800&smaxage=86400');
}
}];
$tools = $('<table>');
$tools.append('<tr><th>' + mw.msg('schnark-bandersnatch-step-2-tools-tool') + '</th><th>' +
mw.msg('schnark-bandersnatch-step-2-tools-use') + '</th><th>' +
mw.msg('schnark-bandersnatch-step-2-tools-load') + '</td></tr>');
tools.forEach(function (tool) {
var $row = $('<tr>'), button;
if (tool.desc.indexOf('\n') === -1) {
tool.desc = '<code>' + tool.desc + '</code>';
} else {
tool.desc = '<pre>' + tool.desc + '</pre>';
}
$row.append('<td>' + tool.title + '</td><td>' + tool.desc + '</td>');
if (tool.load) {
button = new OO.ui.ButtonWidget({
label: mw.msg('schnark-bandersnatch-tool-load'),
icon: 'puzzle'
});
$row.append($('<td>').append(button.$element));
button.on('click', makeLoadFunction(tool.load, button));
} else {
$row.append($('<td>').text(mw.msg('schnark-bandersnatch-tool-noload')));
}
$tools.append($row);
});
$tools = $('<div>').append(
$('<h3>').text(mw.msg('schnark-bandersnatch-step-2-tools')),
$tools
);
testTitle = new OO.ui.TextInputWidget({
value: mw.msg('schnark-bandersnatch-step-2-test-title-default')
});
testText = new OO.ui.MultilineTextInputWidget({
id: 'autoedit-test-text',
rows: 10,
autosize: true,
maxrows: 30
});
testButton = new OO.ui.ButtonWidget({
id: 'autoedit-test',
label: mw.msg('schnark-bandersnatch-step-2-test-run'),
icon: 'settings'
});
testFieldset = new OO.ui.FieldsetLayout({ //TODO collapsible?
label: mw.msg('schnark-bandersnatch-step-2-test'),
items: [
new OO.ui.FieldLayout(testTitle, {
label: mw.msg('schnark-bandersnatch-step-2-test-title'),
align: 'top'
}),
new OO.ui.FieldLayout(testText, {
label: mw.msg('schnark-bandersnatch-step-2-test-text'),
align: 'top'
}),
new OO.ui.FieldLayout(testButton)
]
});
testButton.on('click', function () {
var f = global.makeFunction(codeInput.getValue()),
ret = f(testTitle.getValue(), testText.getValue());
if (ret) {
testText.setValue(ret.text || ret.error);
}
});
prevButton = new OO.ui.ButtonWidget({
label: mw.msg('schnark-bandersnatch-step-back')
});
nextButton = new OO.ui.ButtonWidget({
id: 'autoedit-page2-cont',
label: mw.msg('schnark-bandersnatch-step-continue'),
flags: ['progressive', 'primary']
});
buttonBar = new OO.ui.HorizontalLayout({
items: [prevButton, nextButton]
});
buttonFieldset = new OO.ui.FieldsetLayout({
items: [
new OO.ui.FieldLayout(new OO.ui.Widget({content: [buttonBar]}))
]
});
widgets.code = codeInput;
widgets.prev2 = prevButton;
widgets.next2 = nextButton;
return new OO.ui.PanelLayout({
expanded: false,
$content: $('<div>').append(
$('<h2>').text(mw.msg('schnark-bandersnatch-step-2-head')),
$('<p>').html(mw.msg('schnark-bandersnatch-step-2-text')),
codeFieldset.$element,
$tools,
testFieldset.$element,
buttonFieldset.$element
)
});
}
function createParameterPanel (isBot) {
var summaryInput, minorInput, botInput, waitInput, maxlagInput, modeInput, parameterFieldset,
prevButton, nextButton, buttonBar, buttonFieldset;
summaryInput = new OO.ui.TextInputWidget({
id: 'autoedit-defaultSummary'
});
minorInput = new OO.ui.CheckboxInputWidget({
selected: true
});
botInput = new OO.ui.CheckboxInputWidget({
selected: isBot
});
waitInput = new OO.ui.NumberInputWidget({
id: 'autoedit-waitSeconds',
min: 0,
value: 5
});
maxlagInput = new OO.ui.DropdownInputWidget({
options: [
{
data: 'ignore',
label: mw.msg('schnark-bandersnatch-step-3-maxlag-ignore')
},
{
data: 'default',
label: mw.msg('schnark-bandersnatch-step-3-maxlag-5x5')
}
]
});
modeInput = new OO.ui.DropdownInputWidget({
id: 'autoedit-editType',
options: [
{
data: 'simulate',
label: mw.msg('schnark-bandersnatch-step-3-mode-simulate')
},
{
data: 'batch',
label: mw.msg('schnark-bandersnatch-step-3-mode-batch')
},
{
data: 'check',
label: mw.msg('schnark-bandersnatch-step-3-mode-check')
},
{
data: 'auto',
label: mw.msg('schnark-bandersnatch-step-3-mode-auto')
}
]
});
parameterFieldset = new OO.ui.FieldsetLayout({
items: [
new OO.ui.FieldLayout(summaryInput, {
label: mw.msg('schnark-bandersnatch-step-3-summary'),
align: 'top'
}),
new OO.ui.FieldLayout(minorInput, {
label: mw.msg('schnark-bandersnatch-step-3-minor'),
align: 'inline'
}),
new OO.ui.FieldLayout(botInput, {
label: mw.msg('schnark-bandersnatch-step-3-bot'),
align: 'inline'
}).toggle(isBot),
new OO.ui.FieldLayout(waitInput, {
label: mw.msg('schnark-bandersnatch-step-3-wait'),
align: 'top'
}),
new OO.ui.FieldLayout(maxlagInput, {
label: mw.msg('schnark-bandersnatch-step-3-maxlag'),
align: 'top'
}),
new OO.ui.FieldLayout(modeInput, {
label: mw.msg('schnark-bandersnatch-step-3-mode'),
align: 'top'
})
]
});
prevButton = new OO.ui.ButtonWidget({
label: mw.msg('schnark-bandersnatch-step-back')
});
nextButton = new OO.ui.ButtonWidget({
id: 'autoedit-run',
label: mw.msg('schnark-bandersnatch-step-go'),
icon: 'check',
flags: ['progressive', 'primary']
});
buttonBar = new OO.ui.HorizontalLayout({
items: [prevButton, nextButton]
});
buttonFieldset = new OO.ui.FieldsetLayout({
items: [
new OO.ui.FieldLayout(new OO.ui.Widget({content: [buttonBar]}))
]
});
widgets.summary = summaryInput;
widgets.minor = minorInput;
widgets.bot = botInput;
widgets.wait = waitInput;
widgets.maxlag = maxlagInput;
widgets.mode = modeInput;
widgets.prev3 = prevButton;
widgets.run = nextButton;
return new OO.ui.PanelLayout({
expanded: false,
$content: $('<div>').append(
$('<h2>').text(mw.msg('schnark-bandersnatch-step-3-head')),
$('<p>').text(mw.msg('schnark-bandersnatch-step-3-text')),
parameterFieldset.$element,
buttonFieldset.$element
)
});
}
function makeAbortButton ($container) {
var button = new OO.ui.ButtonWidget({
id: 'autoedit-abort',
label: mw.msg('schnark-bandersnatch-abort'),
icon: 'close',
flags: ['primary', 'destructive']
});
$container.append(button.$element);
widgets.abort = button;
}
function makeInterface ($container, type) {
var $div;
addCSS();
$container.empty();
if (type === 'batch') {
$div = $('<div>').attr('id', 'autoedit-batch-container');
global.makeBatchInterface($div, widgets.abort, isBot());
$container.append($div);
}
$div = $('<div>').attr('id', 'autoedit-log-container');
global.makeLog($div);
$container.append($div);
if (type === 'check') {
$div = $('<div>').attr('id', 'autoedit-check-container');
global.makeCheckInterface($div, widgets.abort);
$container.append($div);
}
}
function initInterface ($container) {
var panel1 = createTitlesPanel(!!global.search),
panel2 = createCodePanel(),
panel3 = createParameterPanel(isBot());
panel2.toggle(false);
panel3.toggle(false);
widgets.next1.on('click', function () {
panel1.toggle(false);
panel2.toggle(true);
window.scroll(0, 0);
});
widgets.next2.on('click', function () {
panel2.toggle(false);
panel3.toggle(true);
window.scroll(0, 0);
});
widgets.prev2.on('click', function () {
panel2.toggle(false);
panel1.toggle(true);
window.scroll(0, 0);
});
widgets.prev3.on('click', function () {
panel3.toggle(false);
panel2.toggle(true);
window.scroll(0, 0);
});
widgets.run.on('click', function () {
run($container);
window.scroll(0, 0);
});
$container.empty().append(
panel1.$element,
panel2.$element,
panel3.$element
);
$container.find('.mw-collapsible').makeCollapsible();
}
function getData () {
return {
titleList: widgets.pages.getValue(),
defaultSummary: widgets.summary.getValue(),
defaultMinor: widgets.minor.isSelected(),
defaultBot: widgets.bot.isSelected(),
waitSeconds: widgets.wait.getValue(),
maxlagType: widgets.maxlag.getValue(),
editCode: widgets.code.getValue(),
editType: widgets.mode.getValue()
};
}
function run ($container) {
var data = getData(), $span = $('<span>').attr({id: 'autoedit-abort-container'});
makeAbortButton($span);
$('#firstHeading').before($span);
makeInterface($container, data.editType);
global.editFromForm(data.titleList, data.defaultSummary, data.defaultMinor, data.defaultBot,
data.waitSeconds, data.maxlagType, data.editCode, data.editType, widgets.abort, function () {
$('#autoedit-batch-container, #autoedit-check-container').remove();
widgets.abort.$element.remove();
}
);
}
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 init () {
initL10N(l10n, ['diff', 'minoreditletter', 'boteditletter', 'article', 'pagehist']);
if (libs.schnarkDiff) {
global.diffCSS = libs.schnarkDiff.getCSS;
global.diff = libs.schnarkDiff.htmlDiff;
} else {
global.diffCSS = function () {
return '';
};
global.diff = function () {
return mw.msg('schnark-bandersnatch-error-diff');
};
}
if (libs['search++']) {
global.searchHelp = libs['search++'].getHelp;
global.search = libs['search++'].queryByString;
}
document.title = mw.msg('schnark-bandersnatch-title');
$('#firstHeading').text(mw.msg('schnark-bandersnatch-version', global.version));
var $container = $('#mw-content-text');
initInterface($container);
}
global.init = init;
})();
if (libs.qunit) {
libs.qunit.bandersnatch = global;
}
if (mw.config.get('wgNamespaceNumber') === -1 && mw.config.get('wgTitle') === 'Bandersnatch') {
$.when(mw.loader.using([
'mediawiki.util', 'mediawiki.language', 'user.options', 'jquery.makeCollapsible', 'oojs-ui-core',
'oojs-ui.styles.icons-interactions', 'oojs-ui.styles.icons-content',
'oojs-ui.styles.icons-editing-core', 'oojs-ui.styles.icons-editing-advanced'
]), $.ready).then(global.init);
}
})(jQuery, mediaWiki, mediaWiki.libs);
//</nowiki>