Unnaschied vunde Gschischde vun "Middawaida:YMS/eagleeye.js"

Inhalt gelöscht Inhalt hinzugefügt
YMS (Dischbediere | Baidräsch)
Introducing saving and adding of rules (changing ruleset Format), introducing saving result lists
YMS (Dischbediere | Baidräsch)
better progress, status and error display, added result limit, select all/none and replacement display in scanner result, show number of results when aborting, highlight current line in rule editor, mark corrector button red if nothing changed, etc.
Zail 15:
var namespaces = getOption("eeNamespaces", [[0], [0], [0]]); // Namespaces for scanner (default value only) / marker / corrector
var useSkiplist = getOption("eeUseSkiplist", [true, false, false]); // Whether the skiplist should be used for scanner / marker / corrector ('''NOTE: not yet implemented for marker/corrector''')
var markerPrefixmPrefix = getOption("eeMarkerPrefix", "ee_"); // Prefix for markers (e.g. "ee_" will result in markers like "ee_Doppelwort", may be set to "" for no prefix)
var markerStylemStyle = getOption("eeMarkerStyle", "background-color: #FF9191;"); // CSS style for the marker highlighting (more can be defined for span.eeMarker in user CSS)
var chunkSizesChunkSize = getOption("eeScannerChunkSize", 10000000); // The chunk size for the database scanner (too low values will fail [depends on database] or cause bad performance, too high values may cause bad performance or even crashes)
var listAllsLimit = getOption("eeScannerListAlleeScannerLimit", false0); // WhetherThe themaximum number of results scanner should listfind all matches(0 for ano page instead of only the first onelimit)
var sListAll = getOption("eeScannerListAll", false); // Whether the scanner should list all matches for a page instead of only the first one
var scannerPage = getOption("eeScannerPage", mw.config.get("wgFormattedNamespaces")[2] + ":YMS/EagleEye"); // The page that will trigger the database scanner (usually only useful where User:YMS/EagleEye doesn't exist)
var sListReplacements = getOption("eeScannerListReplacements", false); // Whether the scanner should list replacements, too
var scannerResultPage = getOption("eeScannerResultPage", mw.config.get("wgFormattedNamespaces")[2] + ":" + mw.config.get("wgUserName") + "/eagleeye.result"); // The default page where result lists are saved (on demand)
var sPage = getOption("eeScannerPage", mw.config.get("wgFormattedNamespaces")[2] + ":YMS/EagleEye"); // The page that will trigger the database scanner (usually only useful where User:YMS/EagleEye doesn't exist)
var scannerSaveResultPageWithMatches = getOption("eeScannerResultPageWithMatches", true); // Whether saving the result page should include matches (instead of titles only)
var sResultPage = getOption("eeScannerResultPage", mw.config.get("wgFormattedNamespaces")[2] + ":" + mw.config.get("wgUserName") + "/eagleeye.result"); // The default page where result lists are saved (on demand)
var ignoreRedirects = true; // With current scanner functionality, it's pointless to allow redirects
var sSaveWithMatches = getOption("eeScannerResultPageWithMatches", true); // Whether saving the result page should include matches (instead of titles only)
var sIgnoreRedirects = true; // With current scanner functionality, it's pointless to allow redirects
 
// Labels
var labels = {
genArticleNamespacegenArticleNS: { en: "(Article)", de: "(Artikel)" },
genName: { en: "EagleEye", de: "EagleEye" },
genStartScanner: { en: "Start EagleEye database scanner", de: "EagleEye Datenbankscanner starten" },
genUnknownError: { en: "Unknown error. ", de: "Unbekannter Fehler." },
intLabelMissing: { en: "Internal error: Label missing: {0}", de: "Interner Fehler: Label {0} fehlt" },
statAborted: { en: "Scan aborted.", de: "Scan abgebrochen." },
statCheckingRules: { en: "Checking Rules...", de: "Prüfe Regeln..." },
statChunkTooSmall: { en: "Error: Chunk size too small to process dump.", de: "Fehler: Chunk-Größe zu klein für diesen Dump." },
statFinished: { en: "Finished. Found {0} pages in {1}:{2}.", de: "Fertig. {0} Seiten in {1}:{2} gefunden." },
statInvalidChunkSize: { en: "Error: Chunk size invalid.", de: "Fehler: Chunk-Größe ungültig." },
statJSONfailed: { en: "Error: EagleEye Ruleset [[{0}]] could not be loaded: {1}: {2}", de: "Fehler: EagleEye-Ruleset [[{0}]] konnte nicht geladen werden: {1}: {2}" },
statNoFile: { en: "Error: No file selected.", de: "Fehler: Keine Datei ausgewählt." },
statRuleFailsTest: { en: "Error: Rule {0} ({1}) fails defined test.", de: "Fehler: Regel {0} ({1}) besteht den angegebenen Test nicht." },
statRuleInvalid: { en: "Error: Rule {0} ({1}) invalid: {2}", de: "Fehler: Regel {0} ({1}) ungültig: {2}" },
statRulesetMissing: { en: "Error: Ruleset missing.", de: "Fehler: Kein Ruleset angegeben." },
statRuleUndefined: { en: "Error: Rule {0} ({1}) undefined.", de: "Fehler: Regel {0} ({1}) undefiniert." },
statScanningDump: { en: "Scanning {0} dump.", de: "Scanne Dump {0}." },
statStartScanning: { en: "Start scanning.", de: "Starte Scanvorgang." },
statUnsupportedBrowser: { en: "Error: Unsupported browser.", de: "Fehler: Browser nicht unterstützt." },
statUnsupportedDump: { en: "Error: Unsupported dump type.", de: "Fehler: Dump nicht unterstützt." },
lblAbort: { en: "Abort scan", de: "Scan abbrechen" },
lblAddRule: { en: "Add new rule", de: "Neue Regel hinzufügen" },
Zeile 50 ⟶ 38:
lblChunkSize: { en: "Chunk size (in bytes)", de: "Chunk-Größe (in Byte)" },
lblInstalled: { en: "Script already is installed and active.", de: "Das Skript ist bereits installiert und aktiv." },
lblLimit: { en: "Limit results (0 = no limit)", de: "Ergebnisse begrenzen (0 = keine Begrenzung)" },
lblListAll: { en: "List all matches (instead of only the first one for every page)", de: "Alle Ergebnisse auflisten (statt nur dem ersten pro Seite)" },
lblListReplacements: { en: "Also list replacements (slower search, but better overview and possibility to preview Corrector changes)", de: "Auch Ersetzungen auflisten (langsamere Suche, aber besser Übersicht und Vorschaumöglichkeit für Corrector-Änderungen)" },
lblMatch: { en: "Match", de: "Match" },
lblName: { en: "Name", de: "Name" },
Zeile 56 ⟶ 46:
lblNotes: { en: "Notes", de: "Anmerkungen" },
lblOptions: { en: "Options", de: "Optionen" },
lblProgress: { en: "{0}% ({1} of {2} bytes", de: "{0}% ({1} von {2} Bytes" },
lblRemoveRule: { en: "remove", de: "löschen" },
lblRemoveRuleLong: { en: "Remove rule", de: "Regel löschen" },
Zeile 62 ⟶ 53:
lblRule: { en: "Rule", de: "Regel" },
lblRules: { en: "Rules", de: "Regeln" },
lblSaveResultPageWithMatcheslblSaveResultsWMatches: { en: "include matches (instead of page list only)", de: "inkl. Matches (statt nur einer Liste der Seiten)" },
lblSaveResults: { en: "Save Results", de: "Ergebnisse speichern" },
lblSaveResultsOnPage: { en: "on page", de: "auf Seite" },
Zeile 69 ⟶ 60:
lblScanDump: { en: "Scan dump", de: "Dump scannen" },
lblSearch: { en: "Search", de: "Suche" },
lblSelectAllNamespaces: { en: "Select/deselect all", de: "Alle/keinen auswählen" },
lblSelectAllRules: { en: "Activate/deactivate all rules", de: "Alle/keine Regel aktivieren" },
lblSelectDump: { en: "Select database dump file", de: "Datenbank-Dump-Datei wählen" },
lblSkip: { en: "Skip", de: "Überspringen" },
Zeile 75 ⟶ 68:
lblUseSkiplist: { en: "Use Skiplist", de: "Skiplist verwenden" },
saveRuleFailed: { en: "Error saving ruleset: {0}", de: "Fehler beim Speichern des Rulesets: {0}" },
saveRuleSuccessfulsaveRuleSuccess: { en: "Ruleset successfully saved.", de: "Ruleset erfolgreich gespeichert." },
saveRuleSummary: { en: "Save [[{0}|EagleEye]] ruleset changes", de: "[[{0}|EagleEye]]-Ruleset-Änderungen gespeichert" },
saveResultsFailed: { en: "Error saving result list: {0}", de: "Fehler beim Speichern der Ergebnisliste: {0}" },
saveResultsSuccessfulsaveResultsSuccess: { en: "Result list successfully saved.", de: "Ergebnisliste erfolgreich gespeichert." },
saveResultsSummary: { en: "Save [[{0}|EagleEye]] result list", de: "[[{0}|EagleEye]]-Ergebnisliste gespeichert" },
saveUnknownErrorstatAborted: { en: "UnknownScan erroraborted. Found {0} pages in {1}.", de: "UnbekannterScan Fehlerabgebrochen. {0} Seiten in {1} gefunden." },
statCheckingRules: { en: "Checking Rules...", de: "Prüfe Regeln..." },
statChunkTooSmall: { en: "Error: Chunk size too small to process dump.", de: "Fehler: Chunk-Größe zu klein für diesen Dump." },
statFinished: { en: "Finished. Found {0} pages in {1}.", de: "Fertig. {0} Seiten in {1} gefunden." },
statInvalidChunkSize: { en: "Error: Chunk size invalid.", de: "Fehler: Chunk-Größe ungültig." },
statInvalidLimit: { en: "Error: Result limit invalid.", de: "Fehler: Ergebnis-Limit ungültig." },
statJSONfailed: { en: "Error: EagleEye Ruleset {0} could not be loaded: {1}", de: "Fehler: EagleEye-Ruleset {0} konnte nicht geladen werden: {1}" },
statNoFile: { en: "Error: No file selected.", de: "Fehler: Keine Datei ausgewählt." },
statRuleFailsTest: { en: "Error: Rule {0} ({1}) fails defined test.", de: "Fehler: Regel {0} ({1}) besteht den angegebenen Test nicht." },
statRuleInvalid: { en: "Error: Rule {0} ({1}) invalid: {2}", de: "Fehler: Regel {0} ({1}) ungültig: {2}" },
statRulesetMissing: { en: "Error: EagleEye ruleset empty.", de: "Fehler: Leeres EagleEye-Ruleset angegeben." },
statRuleUndefined: { en: "Error: Rule {0} ({1}) undefined.", de: "Fehler: Regel {0} ({1}) undefiniert." },
statScanningDump: { en: "Scanning {0} dump.", de: "Scanne Dump {0}." },
statStartScanning: { en: "Start scanning.", de: "Starte Scanvorgang." },
statUnsupBrowser: { en: "Error: Unsupported browser.", de: "Fehler: Browser nicht unterstützt." },
statUnsupDump: { en: "Error: Unsupported dump type.", de: "Fehler: Dump nicht unterstützt." }
};
 
Zeile 92 ⟶ 100:
var stop = 0;
var nextText = "";
var resultCount;
var subResultCount;
var resultList = [];
Zeile 98 ⟶ 105:
var running;
var api;
var colGreen = "#88FF88";
var colRed = "#FF8888";
 
 
mw.loader.using([ "mediawiki.api", "mediawiki.api.edit" ], function() {
// Startup - load ruleset file
api = new mw.Api();
$(document).ready(function() {
try {
$.getJSON(mw.config.get("wgServer") + mw.config.get("wgScript") + "?title=" + mw.util.wikiUrlencode(ruleset) + "&action=raw&ctype=application/json").done(function(rules) {
init(rules);
}).fail(function(jqxhr, textStatus, error) {
mw.notify(getText("statJSONfailed").format(ruleset, textStatus + ": " + error));
});
} catch (e) {
mw.notify(getText("statJSONfailed").format(ruleset, e));
}
});
 
 
 
Zeile 110 ⟶ 130:
 
for (i = 0; i < arguments.length; i++) {
s = s.replace(new RegExp("\\{" + i + "\\}", "gm"), arguments[i]);
}
 
Zeile 116 ⟶ 136:
};
 
// Corrector: Add button to edit mode
// Get default language (user language, if available, else project language, if available, else first defined language)
function getDefaultLangaddCorrectorButton(supportedLanguages) {
$("#wpTextbox1").wikiEditor("addToToolbar", {
if ($.inArray(mw.config.get("wgUserLanguage"), supportedLanguages) !== -1) {
section: "main",
return mw.config.get("wgUserLanguage");
group: "format",
} else if ($.inArray(mw.config.get("wgContentLanguage"), supportedLanguages) !== -1) {
tools: {
return mw.config.get("wgContentLanguage");
} else EagleEyeCorrector: {
label: getText("genName"),
return supportedLanguages[0];
type: "button",
}
icon: "//upload.wikimedia.org/wikipedia/commons/thumb/f/fb/PR_icon.png/22px-PR_icon.png",
}
action: {
 
type: "callback",
// Internationalisation of a label
execute: function() {
function txt(label) {
scanEditWindow(this);
if (labels[label] == null || labels[label][lang] == null) {
}
return txt("intLabelMissing").format(label);
}
}
 
}
return labels[label][lang];
});
 
// Load a user-defined configuration variable or the given default
function getOption(name, defaultvalue) {
return (typeof window[name] === "undefined") ? defaultvalue : window[name];
}
 
// Sets text of progress display
function setProgress(text) {
$("#eeProgress").text(text);
}
 
// Sets text of status section
function setStatus(text) {
$("#eeStatus").text(text);
}
 
// Add the findings for the current page to the result list (scanner tool display)
function addResultsaddPageResultsToDisplay(objectpage) {
var pageResults = searchByRulesscanPage(objectpage);
resultList.push(pageResults);
 
if (pageResults.resultsmatches.length > 0) {
var rule, i;
var count = 0;
var first = true;
 
resultList.push(pageResults);
 
for (rule in pageResults.resultsmatches) {
count += pageResults.resultsmatches[rule].length;
}
 
$("#eeResultTable").append($("<tr />", { id: "eeResult_" + subResultCount, "class": "eeResultTableDataLine" }));
$("#eeResult_" + subResultCount).append($("<td />", { "class": "eeResultTableTitleColumn", rowspan: count }).append('[[<a href="' + base + mw.util.wikiGetlinkwikiUrlencode(pageResults.title) + '">' + pageResults.title + '</a>]]'));
 
varfor first(rule =in true;pageResults.matches) {
for (rule in pageResults.results) {
if (! first) {
$("#eeResultTable").append($("<tr />", { id: "eeResult_" + subResultCount, "class": "eeResultTableDataLine" }));
Zeile 175 ⟶ 182:
first = false;
 
$("#eeResult_" + subResultCount).append($("<td />", { "class": "eeResultTableRuleColumn", rowspan: pageResults.resultsmatches[rule].length }).append(rules[rule].name));
 
for (i = 0; i < pageResults.resultsmatches[rule].length; i++) {
if (i !== 0) {
$("#eeResultTable").append($("<tr />", { id: "eeResult_" + subResultCount, "class": "eeResultTableDataLine" }));
}
 
$("#eeResult_" + subResultCount).append($("<td />", { "class": "eeResultTableMatchColumn" }).append($("<textarea />")mw.html.escape(pageResults.resultsmatches[rule][i]).html()));
$("#eeResult_" + subResultCount).append($("<td />", { "class": "eeResultTableReplaceColumn" }).append(mw.html.escape(pageResults.replaces[rule][i])));
subResultCount++;
}
}
}
 
return (sLimit === 0 || sLimit > resultList.length);
resultCount++;
}
}
 
// Add results to the results page (wikitext export)
function addResultsToPageaddPageResultsToExport(pageResults, addMatches) {
var rule, i;
var text = "";
 
if (pageResults.resultsmatches.length > 0) {
text = "* [[{0}]]".format(pageResults.title);
 
forif (rule in pageResults.resultsaddMatches) {
varfor ruleMatches(rule =in "";pageResults.matches) {
var ruleMatches = "";
 
for (i = 0; i < pageResults.resultsmatches[rule].length; i++) {
if (i !== 0) {
ruleMatches = ruleMatches += "; ";
}
 
ruleMatches += mw.html.escape(pageResults.matches[rule][i]);
}
 
ruleMatchestext += ruleMatches +" $("<textarea{0}: />{1})").htmlformat(pageResults.resultsrules[rule][i]).html(name, ruleMatches);
}
 
text = text + " ({0}: {1})".format(rules[rule].name, ruleMatches);
}
 
text = text += "\n";
}
 
Zeile 219 ⟶ 229:
}
 
// IterateAdd alla rulesrule andeditor matchfor the given text to itline
function searchByRulesaddRuleEditor(objecti) {
$("#eeRuleEditorTable").append($("<tr />", { id: "eeRuleEditor_" + i, "class": "eeRuleEditorTableDataLine" }));
var i, j;
$("#eeRuleEditor_" + i).append($("<td />", { "class": "eeRuleEditorTableCheckboxColumn" }).append($("<input />", { type: "checkbox", id: "eeRuleCB_" + i, checked: (rules[i].inactive === null || rules[i].inactive === false) })));
var pageResults = { title: object.find("title").text(), results: [] };
$("#eeRuleEditor_" + i).append($("<td />", { "class": "eeRuleEditorTableNameColumn" }).append($("<input />", { type: "text", id: "eeRuleName_" + i, value: rules[i].name }).css("width", "100%")));
var dummyRegExp = new RegExp("").source;
$("#eeRuleEditor_" + i).append($("<td />", { "class": "eeRuleEditorTableMatchColumn" }).append($("<input />", { type: "text", id: "eeRuleMatch_" + i, value: (rules[i].match === undefined) ? "" : rules[i].match.source }).css("width", "100%")));
$("#eeRuleEditor_" + i).append($("<td />", { "class": "eeRuleEditorTableSkipColumn" }).append($("<input />", { type: "text", id: "eeRuleSkip_" + i, value: (rules[i].skip === undefined) ? "" : rules[i].skip.source }).css("width", "100%")));
$("#eeRuleEditor_" + i).append($("<td />", { "class": "eeRuleEditorTableReplaceColumn" }).append($("<input />", { type: "text", id: "eeRuleReplace_" + i, value: rules[i].replace }).css("width", "100%")));
$("#eeRuleEditor_" + i).append($("<td />", { "class": "eeRuleEditorTableTestColumn" }).append($("<input />", { type: "text", id: "eeRuleTest_" + i, value: rules[i].test }).css("width", "100%")));
$("#eeRuleEditor_" + i).append($("<td />", { "class": "eeRuleEditorTableNotesColumn" }).append($("<input />", { type: "text", id: "eeRuleNotes_" + i, value: rules[i].note }).css("width", "100%")));
$("#eeRuleEditor_" + i).append($("<td />", { "class": "eeRuleEditorTableRemoveColumn" }).append($("<input />", { type: "button", id: "eeRuleRemove_" + i, value: getText("lblRemoveRule") })));
 
// Check test on relevant changes
for (i = 0; i < rules.length; i++) {
$("#eeRuleMatch_" + i + ",#eeRuleTest_" + i).change(function() {
if (rules[i].inactive === null || rules[i].inactive === false) {
if (applyRuleSettingsFromUI(i)) {
// Match rule if not inactive
$("#eeRuleTest_" + i).css("background-color", (validateRule(i)) ? colGreen : colRed);
var match = object.find("text").text().match(new RegExp(rules[i].match.source, "g"));
 
if (match !== null) {
// Check results for skiplist match
for (j = 0; j < match.length; j++) {
if (! useSkiplist[SCANNER] || rules[i].skip === undefined || rules[i].skip.source === dummyRegExp || rules[i].skip.length === 0 || ! match[j].match(rules[i].skip)) {
if (pageResults.results[i] === undefined) {
pageResults.results[i] = [match[j]];
} else {
pageResults.results[i].push(match[j]);
}
 
if (! listAll) {
return pageResults;
}
}
}
}
}
}).change();
 
// Button "remove"
return pageResults;
$("#eeRuleRemove_" + i).click(function() {
}
applyRuleSettingsFromUI(i);
 
// Validate a single RegEx rule
function checkRule(i) {
if (rules[i].match === null) {
setStatus(txt("statRuleUndefined").format(i, rules[i].name));
return false;
}
 
try {
if (rules[i].test !== null && rules[i].test.length > 0) {
// Check standard test case
if (rules[i].test.match(rules[i].match) === null) {
setStatus(txt("statRuleFailsTest").format(i, rules[i].name));
return false;
}
} else {
// Perform dummy test to check formal validity
"dummy".match(rules[i].match);
}
} catch (e) {
setStatus(txt("statRuleInvalid").format(i, rules[i].name, e));
return false;
}
 
return true;
}
 
// Validate RegEx rule set
function checkRules() {
var i;
 
for (i = 0; i < rules.length; i++) {
if (! checkRule(i)) {
return false;
}
}
 
return true;
}
 
// Edit window processing
function scanEditWindow(context) {
var i;
var changed = false;
var a = context.clickedElement;
 
showConfirm(getText("lblRemoveRuleLong"), getText("lblRemoveRuleLongest").format(rules[i].name), getText("lblRemoveRule"), getText("lblCancel"), function () {
for (i = 0; i < rules.length; i++) {
if ( rules[i].inactive === null || rules[splice(i].inactive, === false1) {;
if loadRuleEditor(! changed) {;
});
if ($("#wpTextbox1").text().match(rules[i].match) !== null) {
changed = true;
}
}
 
$("#wpTextbox1").text($("#wpTextbox1").text().replace(new RegExp(rules[i].match.source, "g"), rules[i].replace));
}
}
 
if (changed && (! a || ! a.nodeType || a.nodeName === "IMG")) {
$((a && a.nodeType) ? a : "img[rel=EagleEye]").css("backgroundColor", changed ? "#DEF740" : "");
}
}
 
// Corrector: Add button to edit mode
function addButton() {
$("#wpTextbox1").wikiEditor("addToToolbar", {
section: "main",
group: "format",
tools: {
EagleEyeCorrector: {
label: txt("genName"),
type: "button",
icon: "//upload.wikimedia.org/wikipedia/commons/thumb/f/fb/PR_icon.png/22px-PR_icon.png",
action: {
type: "callback",
execute: function() {
scanEditWindow(this);
}
}
}
}
});
}
 
// Marker: Mark findings in article view
function markView() {
var i;
 
$("#mw-content-text").children(":not(.diff)").each(function() {
if ($(this).html() !== null) {
for (i = 0; i < rules.length; i++) {
if (rules[i].inactive === null || rules[i].inactive === false) {
$(this).html($(this).html().replace(new RegExp(rules[i].match.source, "g"), '<span class="eeMarker">$&<sup>' + markerPrefix + rules[i].name + '</sup></span>'));
}
}
}
});
}
 
// Add a collapsible section to the HTML
function addSectionaddUISection(sectionID, bodyID, sectionContent, bodyContent, collapsed) {
$("#mw-content-text").append($("<div/>", { id: sectionID, "class": "mw-collapsible eeSection" }).addClass((collapsed) ? "mw-collapsed" : "").append($("<b />").append(sectionContent)).append($("<div />", { id: bodyID, "class": "mw-collapsible-content" }).append(bodyContent)));
}
Zeile 357 ⟶ 266:
// Get the settings for a certain rule from user's input
function applyRuleSettingsFromUI(i) {
try {
rules[i].inactive = ! $("#eeRuleCB_" + i).attr("checked");
rules[i].nameinactive = ! $("#eeRuleName_eeRuleCB_" + i).valattr("checked");
rules[i].name = $("#eeRuleName_" + i).val();
rules[i].match = ($("#eeRuleMatch_" + i).val().length === 0) ? "" : new RegExp($("#eeRuleMatch_" + i).val(), "g");
rules[i].skip = ($("#eeRuleSkip_" + i).val().length === 0) ? "" : new RegExp($("#eeRuleSkip_" + i).val());
rules[i].replace = $("#eeRuleReplace_" + i).val();
rules[i].test = $("#eeRuleTest_" + i).val();
rules[i].note = $("#eeRuleNotes_" + i).val();
} catch (e) {
}
return false;
}
 
return true;
function confirm(title, text, doText, cancelText, callback) {
$("<div />").dialog( {
title: title,
modal: true,
buttons: [{
text: doText,
click: function() {
callback();
$(this).remove();
}
}, {
text: cancelText,
click: function() {
$(this).remove();
}
}],
close: function (event, ui) {
$(this).remove();
}
}).text(text).parent().addClass("alert");
}
 
Zeile 394 ⟶ 287:
// Rules
for (i = 0; i < rules.length; i++) {
if (! applyRuleSettingsFromUI(i);) {
setStatus(getText("statRuleInvalid").format(i, rules[i].name, getText("genUnknownError")), false);
return;
}
}
 
// Options
useSkiplist[SCANNER] = $("#eeOptionCB_useSkiplist").attr("checked");
listAllsListAll = $("#eeOptionCB_listAll").attr("checked");
sListReplacements = $("#eeOptionCB_listReplacements").attr("checked");
 
chunkSizesChunkSize = Number($("#eeOptionCB_chunkSize").val());
if (isNaN! $.isNumeric(chunkSizesChunkSize) || chunkSizesChunkSize <= 0) {
setStatus(txtgetText("statInvalidChunkSize"), false);
return;
}
 
sLimit = Number($("#eeOptionCB_limit").val());
if (! $.isNumeric(sLimit) || sLimit < 0) {
setStatus(getText("statInvalidLimit"), false);
return;
}
Zeile 416 ⟶ 319:
}
 
// Save page via API
// Add a rule editor for the given line
function addRuleEditoreditPage(ititle, text, summary, successMsg, failMsg) {
api.post({ action: "edit", title: title, text: text, summary: summary, token: mw.user.tokens.get("editToken") }).done(function(data) {
$("#eeRuleEditorTable").append($("<tr />", { id: "eeRuleEditor_" + i, "class": "eeRuleEditorTableDataLine" }));
if (data && data.edit && data.edit.result === "Success") {
$("#eeRuleEditor_" + i).append($("<td />", { "class": "eeRuleEditorTableCheckboxColumn" }).append($("<input />", { type: "checkbox", id: "eeRuleCB_" + i, checked: (rules[i].inactive === null || rules[i].inactive === false) })));
mw.notify(successMsg);
$("#eeRuleEditor_" + i).append($("<td />", { "class": "eeRuleEditorTableNameColumn" }).append($("<input />", { type: "text", id: "eeRuleName_" + i, value: rules[i].name }).css("width", "100%")));
} else if (data && data.error) {
$("#eeRuleEditor_" + i).append($("<td />", { "class": "eeRuleEditorTableMatchColumn" }).append($("<input />", { type: "text", id: "eeRuleMatch_" + i, value: (rules[i].match === undefined) ? "" : rules[i].match.source }).css("width", "100%")));
mw.notify(failMsg.format(data.error.code + ": " + data.error.info));
$("#eeRuleEditor_" + i).append($("<td />", { "class": "eeRuleEditorTableSkipColumn" }).append($("<input />", { type: "text", id: "eeRuleSkip_" + i, value: (rules[i].skip === undefined) ? "" : rules[i].skip.source }).css("width", "100%")));
} else {
$("#eeRuleEditor_" + i).append($("<td />", { "class": "eeRuleEditorTableReplaceColumn" }).append($("<input />", { type: "text", id: "eeRuleReplace_" + i, value: rules[i].replace }).css("width", "100%")));
mw.notify(failMsg.format(getText("genUnknownError")));
$("#eeRuleEditor_" + i).append($("<td />", { "class": "eeRuleEditorTableTestColumn" }).append($("<input />", { type: "text", id: "eeRuleTest_" + i, value: rules[i].test }).css("width", "100%")));
}
$("#eeRuleEditor_" + i).append($("<td />", { "class": "eeRuleEditorTableNotesColumn" }).append($("<input />", { type: "text", id: "eeRuleNotes_" + i, value: rules[i].note }).css("width", "100%")));
}).fail(function(error) {
$("#eeRuleEditor_" + i).append($("<td />", { "class": "eeRuleEditorTableRemoveColumn" }).append($("<input />", { type: "button", id: "eeRuleRemove_" + i, value: txt("lblRemoveRule") })));
mw.notify(failMsg.format(error));
});
}
 
// Enable/disable the "Save Results" button
// Check test on relevant changes
function enableSaveResultsButton() {
$("#eeRuleMatch_" + i + ",#eeRuleTest_" + i).change(function() {
var enable = ! running && mw.config.get("wgEnableWriteAPI") && resultList.length > 0;
applyRuleSettingsFromUI(i);
$("#eeSaveResults").attr("disabled", ! enable);
$("#eeRuleTest_" + i).css("background-color", (checkRule(i)) ? "#88FF88" : "#FF8888");
}
}).change();
 
// Enable/disable the "Save Rules" button
// Button "remove"
function enableSaveRulesButton() {
$("#eeRuleRemove_" + i).click(function() {
var enable = mw.config.get("wgEnableWriteAPI") && rules.length > 0;
applyRuleSettingsFromUI(i);
$("#eeSaveRules").attr("disabled", ! enable);
confirm(txt("lblRemoveRuleLong"), txt("lblRemoveRuleLongest").format(rules[i].name), txt("lblRemoveRule"), txt("lblCancel"), function () {
rules.splice(i, 1);
loadRuleEditor();
});
});
}
 
Zeile 450 ⟶ 352:
}
 
// Get default language (user language, if available, else project language, if available, else first defined language)
// Enable/disable the "Save Rules" button
function enableSaveRulesButtongetDefaultLang(supportedLanguages) {
var enable =if ($.inArray(mw.config.get("wgEnableWriteAPIwgUserLanguage"), &&supportedLanguages) rules.length!== >-1) 0;{
return mw.config.get("wgUserLanguage");
$("#eeSaveRules").attr("disabled", ! enable);
} else if ($.inArray(mw.config.get("wgContentLanguage"), supportedLanguages) !== -1) {
return mw.config.get("wgContentLanguage");
} else {
return supportedLanguages[0];
}
}
 
// Get duration of a scan in format mm:ss
// Enable/disable the "Save Results" button
function enableSaveResultsButtongetDuration() {
var enablemsec = ! running && mw($.config.getnow("wgEnableWriteAPI") &&- resultCount > 0startTime);
var sec = ((Math.floor(msec / 1000) % 60 < 10) ? "0" : "") + Math.floor(msec / 1000) % 60;
$("#eeSaveResults").attr("disabled", ! enable);
var min = ((Math.floor(msec / 1000 / 60) < 10) ? "0" : "") + Math.floor(msec / 1000 / 60);
 
return min + ":" + sec;
}
 
// Load a user-defined configuration variable or the default value
// Sets the running state and changes start/abort button's label and behaviour
function setRunninggetOption(runname, defaultvalue) {
return (typeof window[name] === "undefined") ? defaultvalue : window[name];
running = run;
}
 
// Internationalisation of a label
if (running) {
function getText(label) {
$("#eeSearch").val(txt("lblAbort"));
if (labels[label] === null || labels[label][lang] === null) {
} else {
$return getText("#eeSearchintLabelMissing").valformat(txt("lblScanDump")label);
}
 
return labels[label][lang];
enableSaveResultsButton();
}
 
// Initialise scanner, marker, corrector and additional stuff (scanner portlet, etc.)
function init(data) {
var i;
 
if (! window.File || ! window.FileReader || ! window.Blob) {
setStatus(getText("statUnsupBrowser"), false);
return;
}
 
rules = data;
 
if (typeof rules === "undefined" || rules === null || rules.length === 0) {
mw.notify(getText("statRulesetMissing"));
return;
}
 
for (i = 0; i < rules.length; i++) {
rules[i].match = new RegExp(rules[i].match, "g");
 
if (rules[i].skip !== undefined) {
rules[i].skip = new RegExp(rules[i].skip);
}
}
 
if (activated[SCANNER]) {
mw.util.addPortletLink("p-tb", mw.util.wikiGetlink(sPage), getText("genName"), "t-eagleeye", getText("genStartScanner"));
 
if (mw.config.get("wgPageName") === sPage && mw.config.get("wgAction") === "view") {
// Scanner view
mw.util.addCSS("div.eeSection { border: 1px solid black; padding: 8px; }");
mw.util.addCSS(".eeResultTable td { border-top: 1px solid #CCCCCC; padding: 4px }");
mw.util.addCSS("tr.eeRuleEditorTableDataLine:hover { background-color: #CCCCCC }");
 
mw.loader.using([ "mediawiki.api", "mediawiki.api.edit" ], function() {
api = new mw.Api();
});
 
loadScannerUI();
}
}
 
if (activated[MARKER] && $.inArray(mw.config.get("wgNamespaceNumber"), namespaces[MARKER]) !== -1 && mw.config.get("wgAction") === "view") {
// Article view: Marker
mw.util.addCSS("span.eeMarker { " + mStyle + " }");
 
scanView();
}
 
if (activated[CORRECTOR] && $.inArray(mw.config.get("wgNamespaceNumber"), namespaces[CORRECTOR]) !== -1 && $.inArray(mw.config.get("wgAction"), [ "edit", "submit" ]) !== -1) {
// Edit view - add button for Corrector
mw.loader.using("ext.wikiEditor.toolbar", function () {
addCorrectorButton();
});
}
}
 
Zeile 483 ⟶ 450:
table.append(header);
header.append($("<th />", { "class": "eeRuleEditorTableCheckboxColumn" }));
header.append($("<th />", { "class": "eeRuleEditorTableNameColumn", width: "5%" }).append(txtgetText("lblName")));
header.append($("<th />", { "class": "eeRuleEditorTableMatchColumn", width: "40%" }).append(txtgetText("lblMatch")));
header.append($("<th />", { "class": "eeRuleEditorTableSkipColumn", width: "30%" }).append(txtgetText("lblSkip")));
header.append($("<th />", { "class": "eeRuleEditorTableReplaceColumn", width: "5%" }).append($("<i />").append(txtgetText("lblReplace"))));
header.append($("<th />", { "class": "eeRuleEditorTableTestColumn", width: "10%" }).append($("<i />").append(txtgetText("lblTest"))));
header.append($("<th />", { "class": "eeRuleEditorTableNotesColumn", width: "10%" }).append($("<i />").append(txtgetText("lblNotes"))));
header.append($("<th />", { "class": "eeRuleEditorTableCopyColumn" }));
 
Zeile 504 ⟶ 471:
// Collapse pre-defined installation section and set a marker
if ($("#eeInstallation").length) {
$("#eeInstallation").find(".mw-collapsible-content").prepend($("<div />", { id: "eeInstallationNotice" }).append(txtgetText("lblInstalled")));
$("#eeInstallationNotice").css({ "background-color": "#44DD44", "padding": "5px", "margin": "5px" });
$("#eeInstallation").addClass("mw-collapsed");
}
 
addSectionaddUISection("eeRulesPane", "eeRulesPaneContent", txtgetText("lblRules"), "", true);
loadRuleEditor();
 
// Buttons
$("#eeRulesPane").append($("<div />", { "class": "mw-collapsible-content" }).append($("<input />", { type: "button", id: "eeAddRule", name: "eeAddRule", val: txt("lblAddRule") })));
$("#eeRulesPane").append($("<div />", { "class": "mw-collapsible-content" }).append($("<input />", { type: "button", id: "eeSelectAllRules", name: "eeSelectAllRules", val: getText("lblSelectAllRules") })).append($("<input />", { type: "button", id: "eeAddRule", name: "eeAddRule", val: getText("lblAddRule") })).append($("<input />", { type: "button", id: "eeSaveRules", name: "eeSaveRules", val: txtgetText("lblSaveRules") })).append($("<i />").append(txtgetText("lblSaveRulesInfo").format(ruleset))));
 
$("#eeSelectAllRules").click(function() {
selectDeselectAll($("input[id^=eeRuleCB_]"));
});
 
$("#eeAddRule").click(function() {
Zeile 522 ⟶ 493:
 
$("#eeSaveRules").click(function() {
saveRuleset();
// Convert rules to JSON
for (i = 0; i < rules.length; i++) {
applyRuleSettingsFromUI(i);
 
rules[i].match = rules[i].match.source;
 
if (rules[i].skip !== undefined) {
rules[i].skip = rules[i].skip.source;
}
}
 
if (! checkRules()) {
alert($("#eeStatus").text());
return;
}
 
// Save rules
editPage(ruleset, JSON.stringify(rules), txt("saveRuleSummary").format(scannerPage), txt("saveRuleSuccessful"), txt("saveRuleFailed"));
});
 
// Options
addSectionaddUISection("eeOptionsPane", "eeOptionsPaneContent", txtgetText("lblOptions"), null, true);
 
$("#eeOptionsPaneContent").append($("<div/>").append($("<input />", { type: "checkbox", id: "eeOptionCB_useSkiplist", checked: (useSkiplist[SCANNER]) })).append($("<label />", { "for": "eeOptionCB_useSkiplist" }).append(txtgetText("lblUseSkiplist"))));
$("#eeOptionsPaneContent").append($("<div/>").append($("<input />", { type: "numbercheckbox", id: "eeOptionCB_chunkSizeeeOptionCB_listAll", valuechecked: chunkSize, min: 0(sListAll) })).append($("<label />", { "for": "eeOptionCB_chunkSizeeeOptionCB_listAll" }).append(txtgetText("lblChunkSizelblListAll"))));
$("#eeOptionsPaneContent").append($("<div/>").append($("<input />", { type: "checkbox", id: "eeOptionCB_listAlleeOptionCB_listReplacements", checked: (listAllsListReplacements) })).append($("<label />", { "for": "eeOptionCB_listAlleeOptionCB_listReplacements" }).append(txtgetText("lblListAlllblListReplacements"))));
$("#eeOptionsPaneContent").append($("<div/>").append($("<input />", { type: "number", id: "eeOptionCB_chunkSize", value: sChunkSize, min: "1" })).append($("<label />", { "for": "eeOptionCB_chunkSize" }).append(getText("lblChunkSize"))));
$("#eeOptionsPaneContent").append($("<div/>").append($("<input />", { type: "number", id: "eeOptionCB_limit", value: sLimit, min: "0" })).append($("<label />", { "for": "eeOptionCB_limit" }).append(getText("lblLimit"))));
 
// Namespaces
addSectionaddUISection("eeNamespacePane", "eeNamespacePaneContent", txtgetText("lblNamespaces"), null$("<div />", { id: "eeNamespacesList" }).css("column-width", "200px"), true);
$("#eeNamespacePaneContent").css("column-width", "200px");
 
for (id in mw.config.get("wgFormattedNamespaces")) {
var name = (mw.config.get("wgFormattedNamespaces")[id] === "") ? txtgetText("genArticleNamespacegenArticleNS") : mw.config.get("wgFormattedNamespaces")[id];
$("#eeNamespacePaneContenteeNamespacesList").append($("<div/>").append($("<input />", { type: "checkbox", id: "eeNamespaceCB_" + id, checked: ($.inArray(Number(id), namespaces[SCANNER]) !== -1) })).append($("<label />", { "for": "eeNamespaceCB_" + id }).append(name)));
}
 
$("#eeNamespacePaneContent").append($("<div />").append($("<input />", { type: "button", id: "eeSelectAllNamespaces", name: "eeSelectAllNamespaces", val: getText("lblSelectAllNamespaces") })));
 
$("#eeSelectAllNamespaces").click(function() {
selectDeselectAll($("input[id^=eeNamespaceCB_]"));
});
 
// Search
addSectionaddUISection("eeSearchPane", "eeSearchPaneContent", txtgetText("lblSearch"), $("<label />", { "for": "eeFile" }).append(txtgetText("lblSelectDump")));
$("#eeSearchPaneContent").append($("<div />").append($("<input />", { type: "file", id: "eeFile", name: "eeFile" }), false));
$("#eeSearchPaneContent").append($("<div />").append($("<input />", { type: "button", id: "eeSearch", name: "eeSearch" })));
Zeile 565 ⟶ 526:
// Output section
$("#eeSearchPaneContent").append($("<div/>", { id: "eeStatus" }));
$("#eeSearchPaneContent").append($("<progress />", { id: "eeProgressBar", value: "0" }).css("width", "100%"));
$("#eeSearchPaneContent").append($("<div/>", { id: "eeProgress" }));
$("#eeSearchPaneContent").append($("<br/>"));
Zeile 571 ⟶ 533:
 
// Save button
$("#eeSearchPaneContent").append($("<div />").append($("<input />", { type: "button", id: "eeSaveResults", name: "eeSaveResults", value: txtgetText("lblSaveResults") })).append(txtgetText("lblSaveResultsOnPage")).append($("<input />", { type: "text", id: "eeSaveResultsPage", val: scannerResultPagesResultPage })).append($("<input />", { type: "checkbox", id: "eeSaveResultPageWithMatches", checked: scannerSaveResultPageWithMatchessSaveWithMatches })).append($("<label />", { "for": "eeSaveResultPageWithMatches" }).append(txtgetText("lblSaveResultPageWithMatcheslblSaveResultsWMatches"))));
 
// Assure collapsible sections are made collapsible
Zeile 590 ⟶ 552:
$("#eeSearch").click(function() {
if (running) {
setStatus(txtgetText("statAborted").format(resultList.length, getDuration()), false);
} else {
applySettingsFromUI();
Zeile 601 ⟶ 563:
// Button: "Save Results"
$("#eeSaveResults").click(function() {
var i;
var text = "";
var addMatches = $("#eeSaveResultPageWithMatches").attr("checked");
 
for (i = 0; i < resultList.length; i++) {
text += text + addResultsToPageaddPageResultsToExport(resultList[i], addMatches);
}
 
editPage($("#eeSaveResultsPage").val(), text, txtgetText("saveResultsSummary").format($("#eeSaveResultsPage").val()), txtgetText("saveResultsSuccessfulsaveResultsSuccess"), txtgetText("saveResultsFailed"));
});
 
Zeile 616 ⟶ 579:
}
 
// Finished reading a dump chunk, start reading next one
// Save page via API
function editPagereadNextChunk(titlee, textreader, summary, successMsg, failMsgfile) {
if (! running || e.target.readyState !== FileReader.DONE || file === null || ! file) {
api.post({ action: "edit", title: title, text: text, summary: summary, token: mw.user.tokens.get("editToken") }).done(function(data) {
setRunning(false);
if (data && data.edit && data.edit.result === "Success") {
alert(successMsg)return;
}
} else if (data && data.error) {
alert(failMsg.format(data.error.code + ": " + data.error.info));
} else {
alert(failMsg.format(txt("saveUnknownError")));
}
}).fail(function(error) {
alert(failMsg.format(error));
});
}
 
setProgress(stop, file.size);
// Perform dump scan
function scanFile() {
var reader = new FileReader();
var file = document.getElementById("eeFile").files[0];
 
// Trim chopped-of tags
start = 0;
stopvar text = start + chunkSizee.target.result;
 
if (start > 0) {
$("#eeResults").html($("<table />", { id: "eeResultTable", "class": "eeResultTable" }));
text = "<mediawiki>" + nextText + text;
var header = $("<tr />", { id: "eeResultTableHeaderLine", "class": "eeResultTableHeaderLine" });
}
$("#eeResultTable").append(header);
header.append($("<th />", { "class": "eeResultTableTitleColumn" }).append(txt("lblTitle")));
header.append($("<th />", { "class": "eeResultTableRuleColumn" }).append(txt("lblRule")));
header.append($("<th />", { "class": "eeResultTableMatchColumn" }).append(txt("lblMatch")));
 
var lastCloseText = text.lastIndexOf("</page>");
setStatus(txt("statCheckingRules"));
setProgress("");
resultList = [];
resultCount = 0;
subResultCount = 0;
startTime = new Date();
 
if (!lastCloseText checkRules()< 0) {
setStatus(getText("statChunkTooSmall"), false);
return;
}
 
nextText = text.substring(lastCloseText + "</page>".length);
setStatus(txt("statStartScanning"));
text = text.substring(0, lastCloseText + "</page>".length) + "</mediawiki>";
 
// Detect base
reader.onloadend = function(e) {
if (start === 0) {
if (! running || e.target.readyState !== FileReader.DONE || file === null || ! file) {
// jQuery can't read tags named "base" for some reason, so load this manually
setRunning(false);
var baseStart = text.indexOf("<base>");
base = text.substring(baseStart + "<base>".length, text.indexOf("</base>"));
base = base.substring(0, base.lastIndexOf("/") + 1);
 
if (baseStart < 0 || base.length === 0) {
setStatus(getText("statUnsupDump"), false);
return;
}
 
setStatus(getText("statScanningDump").format(base), true);
var percentage = (Math.min(stop, file.size) / file.size) * 100;
}
setProgress(percentage.toFixed(0) + "% (" + Math.min(stop, file.size) + " of " + file.size + " bytes)");
 
// Trim chopped-of tagsSearch
var $(text = e).targetfind("page").result;each(function() {
// Check namespace
 
if ($.inArray(Number($(this).find("ns").text()), namespaces[SCANNER]) === -1) {
if (start > 0) {
return;
text = "<mediawiki>" + nextText + text;
}
 
// Check redirect status
var lastCloseText = text.lastIndexOf("</page>");
if (sIgnoreRedirects && $(this).find("redirect").length > 0) {
 
if (lastCloseText < 0) {
setStatus(txt("statChunkTooSmall"));
return;
}
 
return addPageResultsToDisplay($(this));
nextText = text.substring(lastCloseText + "</page>".length);
});
text = text.substring(0, lastCloseText + "</page>".length) + "</mediawiki>";
 
// DetectNext basechunk
if (stop if< file.size && (startsLimit === 0 || sLimit > resultList.length)) {
start = start + sChunkSize;
// jQuery can't read tags named "base" for some reason, so load this manually
stop = varstop baseStart =+ text.indexOf("<base>")sChunkSize;
base = text.substring(baseStart + "<base>".length, text.indexOf("</base>"));
base = base.substring(0, base.lastIndexOf("/") + 1);
 
reader.readAsText(file.slice(start, stop));
if (baseStart < 0 || base.length === 0) {
} else {
setStatus(txt("statUnsupportedDump"));
setStatus(getText("statFinished").format(resultList.length, getDuration()), true);
return;
}setRunning(false);
}
}
 
// Save ruleset definition to specified file
setStatus(txt("statScanningDump").format(base));
function saveRuleset() {
var i;
 
// Convert rules to JSON
for (i = 0; i < rules.length; i++) {
if (! applyRuleSettingsFromUI(i)) {
mw.notify(getText("statRuleInvalid").format(i, rules[i].name, getText("genUnknownError")));
return;
}
 
rules[i].match = rules[i].match.source;
// Search
$(text).find("page").each(function() {
// Check namespace
if ($.inArray(Number($(this).find("ns").text()), namespaces[SCANNER]) === -1) {
return;
}
 
if (rules[i].skip !== undefined) {
// Check redirect status
rules[i].skip = rules[i].skip.source;
if (ignoreRedirects && $(this).find("redirect").length > 0) {
return;}
}
 
if (! addResultsvalidateRuleset($(this)); {
}mw.notify($("#eeStatus").text());
return;
}
 
// NextSave chunkrules
editPage(ruleset, JSON.stringify(rules, null, 2), getText("saveRuleSummary").format(sPage), getText("saveRuleSuccess"), getText("saveRuleFailed"));
if (stop < file.size) {
}
start = start + chunkSize;
stop = stop + chunkSize;
 
// Corrector: Edit window processing
var blob = file.slice(start, stop);
function scanEditWindow(context) {
reader.readAsText(blob);
var } else {i;
var msecchanged = ((new Date()) - startTime)false;
var a = context.clickedElement;
var sec = ((Math.floor(msec / 1000) % 60 < 10) ? "0" : "") + Math.floor(msec / 1000) % 60;
var min = ((Math.floor(msec / 1000 / 60) < 10) ? "0" : "") + Math.floor(msec / 1000 / 60);
 
for (i = 0; i < rules.length; i++) {
setStatus(txt("statFinished").format(resultCount, min, sec));
if (rules[i].inactive === null || rules[i].inactive === false) {
setRunning(false);
if (! changed && $("#wpTextbox1").text().match(rules[i].match) !== null) {
}
changed = true;
};
}
 
$("#wpTextbox1").text($("#wpTextbox1").text().replace(rules[i].match, rules[i].replace));
if (file === null || ! file) {
}
setStatus(txt("statNoFile"));
return;
}
 
if (! a || ! a.nodeType || a.nodeName === "IMG") {
var blob = file.slice(start, stop + 1);
$((a && a.nodeType) ? a : "img[rel=EagleEyeCorrector]").css("background-color", (changed) ? colGreen : colRed);
reader.readAsText(blob);
}
}
 
// Perform dump scan
// Initialise scanner, marker, corrector and additional stuff (scanner portlet, etc.)
function initscanFile(data) {
var file = document.getElementById("eeFile").files[0];
var i;
 
start = 0;
if (! window.File || ! window.FileReader || ! window.Blob) {
stop = start + sChunkSize;
setStatus(txt("statUnsupportedBrowser"));
 
$("#eeResults").html($("<table />", { id: "eeResultTable", "class": "eeResultTable" }));
var header = $("<tr />", { id: "eeResultTableHeaderLine", "class": "eeResultTableHeaderLine" });
$("#eeResultTable").append(header);
header.append($("<th />", { "class": "eeResultTableTitleColumn" }).append(getText("lblTitle")));
header.append($("<th />", { "class": "eeResultTableRuleColumn" }).append(getText("lblRule")));
header.append($("<th />", { "class": "eeResultTableMatchColumn" }).append(getText("lblMatch")));
header.append($("<th />", { "class": "eeResultTableReplaceColumn" }).append(getText("lblReplace")));
 
setStatus(getText("statCheckingRules"), true);
setProgress(0, file.size);
resultList = [];
subResultCount = 0;
startTime = $.now();
 
if (! validateRuleset()) {
return;
}
 
setStatus(getText("statStartScanning"), true);
rules = data;
 
if (typeof rules === "undefined" || rulesfile === null || rules.length ===! 0file) {
setStatus(txtgetText("statRulesetMissingstatNoFile"), false);
return;
}
 
var reader = new FileReader();
reader.onloadend = function(e) {
readNextChunk(e, reader, file);
};
reader.readAsText(file.slice(start, stop));
}
 
// Iterate all rules and match given text to it
function scanPage(object) {
var i, j;
var pageResults = { title: object.find("title").text(), matches: [], replaces: [] };
var dummyRegExp = new RegExp("").source;
 
for (i = 0; i < rules.length; i++) {
if (rules[i].matchinactive === newnull || RegExp(rules[i].matchinactive === false); {
// Match rule if not inactive
var match = object.find("text").text().match(rules[i].match);
 
if (rules[i].skipmatch !== undefinednull) {
// Check results for skiplist match
rules[i].skip = new RegExp(rules[i].skip);
for (j = 0; j < match.length; j++) {
if (! useSkiplist[SCANNER] || rules[i].skip === undefined || rules[i].skip.source === dummyRegExp || rules[i].skip.length === 0 || ! match[j].match(rules[i].skip)) {
var replace = (sListReplacements) ? match[j].replace(rules[i].match, rules[i].replace) : "";
 
if (pageResults.matches[i] === undefined) {
pageResults.matches[i] = [match[j]];
pageResults.replaces[i] = [replace];
} else {
pageResults.matches[i].push(match[j]);
pageResults.replaces[i].push(replace);
}
 
if (! sListAll) {
return pageResults;
}
}
}
}
}
}
 
return pageResults;
if (activated[SCANNER]) {
}
mw.util.addPortletLink("p-navigation", mw.util.wikiGetlink(scannerPage), txt("genName"), "EagleEye-portlet", txt("genStartScanner"));
 
// Marker: Mark findings in article view
function scanView() {
var i;
 
$("#mw-content-text").children(":not(.diff):not(.diff *)").each(function() {
if ($(this).html() !== null) {
for (i = 0; i < rules.length; i++) {
if (rules[i].inactive === null || rules[i].inactive === false) {
$(this).html($(this).html().replace(rules[i].match, '<span class="eeMarker">$&<sup>' + mPrefix + rules[i].name + '</sup></span>'));
}
}
}
});
}
 
// Select or deselect all of the given checkboxes
function selectDeselectAll($boxes) {
var allActivated = true;
 
$boxes.each(function() {
if (! $(this).attr("checked")) {
allActivated = false;
return false;
}
});
 
$boxes.attr("checked", ! allActivated);
}
 
// Sets text of progress display and bar
function setProgress(value, max) {
if (value === 0) {
$("#eeProgress").text("");
$("#eeProgressBar").attr({ value: value, max: max });
} else {
var percentage = (Math.min(value, max) / max) * 100;
$("#eeProgress").text(getText("lblProgress").format(percentage.toFixed(0), Math.min(value, max), max));
$("#eeProgressBar").attr("value", value);
}
}
 
// Sets the running state and changes start/abort button's label and behaviour
if (activated[SCANNER] && mw.config.get("wgPageName") === scannerPage && mw.config.get("wgAction") === "view") {
function setRunning(run) {
// Scanner view
running = run;
mw.util.addCSS("div.eeSection { border: 1px solid black; padding: 8px; }");
mw.util.addCSS(".eeResultTable td { border-top: 1px solid #CCCCCC; padding: 4px }");
 
if loadScannerUI(running); {
$("#eeSearch").val(getText("lblAbort"));
$("#eeProgressBar").show();
} else {
$("#eeSearch").val(getText("lblScanDump"));
$("#eeProgressBar").hide();
}
 
enableSaveResultsButton();
if (activated[MARKER] && $.inArray(mw.config.get("wgNamespaceNumber"), namespaces[MARKER]) !== -1 && mw.config.get("wgAction") === "view") {
}
// Article view: Marker
mw.util.addCSS("span.eeMarker { " + markerStyle + " }");
 
// Sets text of status section
markView();
function setStatus(text, okay) {
$("#eeStatus").text(text);
$("#eeStatus").css("background-color", (okay) ? colGreen : colRed);
}
 
// Display a message box with two options
function showConfirm(title, text, doText, cancelText, callback) {
$("<div />").dialog({
title: title,
modal: true,
buttons: [{
text: doText,
click: function() {
callback();
$(this).remove();
}
}, {
text: cancelText,
click: function() {
$(this).remove();
}
}],
close: function (event, ui) {
$(this).remove();
}
}).text(text).parent().addClass("alert");
}
 
// Validate a single RegEx rule
function validateRule(i) {
if (rules[i].match === null) {
setStatus(getText("statRuleUndefined").format(i, rules[i].name), false);
return false;
}
 
try {
if (activated[CORRECTOR] && $.inArray(mw.config.get("wgNamespaceNumber"), namespaces[CORRECTOR]) !== -1 && $.inArray(mw.config.get("wgAction"), [ "edit", "submit" ]) !== -1) {
if (rules[i].test !== null && rules[i].test.length > 0) {
// Edit view - add button for Corrector
// Check standard test case
$("#wpTextbox1").on("wikiEditor-toolbar-doneInitialSections", function () {
if (rules[i].test.match(rules[i].match) === null) {
mw.loader.using("ext.wikiEditor.toolbar", addButton());
setStatus(getText("statRuleFailsTest").format(i, rules[i].name), false);
});
return false;
} else {
setStatus("", true);
}
} else {
// Perform dummy test to check formal validity
"dummy".match(rules[i].match);
}
} catch (e) {
setStatus(getText("statRuleInvalid").format(i, rules[i].name, e), false);
return false;
}
 
return true;
}
 
// StartupValidate -RegEx loadrule ruleset fileset
$(document).ready(function validateRuleset() {
var i;
$.getJSON(mw.config.get("wgServer") + mw.config.get("wgScript") + "?title=" + mw.util.wikiUrlencode(ruleset) + "&action=raw&ctype=application/json").done(function(rules) {
 
init(rules);
for (i = 0; i < rules.length; i++) {
}).fail(function(jqxhr, textStatus, error) {
if (! validateRule(i)) {
alert(txt("statJSONfailed").format(ruleset, textStatus, error));
}) return false;
});
}
 
return true;
}
})();
// </nowiki>