User:Erutuon/scripts/CleanupButtons.js
< User:Erutuon | scripts
Note: You may have to bypass your browser’s cache to see the changes. In addition, after saving a sitewide CSS file such as MediaWiki:Common.css, it will take 5-10 minutes before the changes take effect, even if you clear your cache.
- Mozilla / Firefox / Safari: hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (Command-R on a Macintosh);
- Konqueror and Chrome: click Reload or press F5;
- Opera: clear the cache in Tools → Preferences;
- Internet Explorer: hold Ctrl while clicking Refresh, or press Ctrl-F5.
- This script lacks a documentation subpage. Please create it.
- Useful links: root page • root page’s subpages • links • redirects • your own
/*
A framework for inserting scripts that perform repetitive and tedious
editing tasks.
It inserts buttons above the text box, if certain conditions are fulfilled.
Pressing the button executes the function.
A variable tracks how many times a change is made, or the original content
is saved and compared to the modified version.
An edit summary is added if the change was done. If two operations have been
performed, their edit summaries are combined in a grammatical way.
*/
/* jshint eqeqeq: true, varstmt: true, unused: true, undef: true */
/* globals $, mw */
(function () {
"use strict";
const $textBox = $("#wpTextbox1");
const $minorEditCheck = $("#wpMinoredit");
const $editForm = $("#editform");
const cleanupButtonWrapperId = "wikitext-cleanup-button-wrapper";
const cleanupButtonClass = "wikitext-cleanup-button";
window.importStylesheetURI("//en.wiktionary.org/w/index.php?title=User:Erutuon/styles/wikitext-cleanup.css&action=raw&ctype=text/css");
// Template for button object, the first argument to cleanupButtons.addButton
// method.
const cleanupButtonTemplate = {
condition: false,
textBoxIncludes: "",
button: {
text: "",
},
minorEdit: false,
func:
function (content)
{
const oldContent = content;
let count = 0;
content = content.replace(
//g,
function(wholeMatch)
{
++count;
return wholeMatch;
}
);
CleanupButtons.notifyReplacements(count);
CleanupButtons.addSummary(count, "");
CleanupButtons.addSummary(content !== oldContent, "");
return content;
}
};
function newCleanupButton(text, id) {
if ( typeof text === "function" ) {
text = text($textBox.val());
if ( typeof text !== "string" )
throw new TypeError("'text' function should return a string.");
}
return $("<div>").addClass(cleanupButtonClass).attr("id", id).html(text);
}
const CleanupButtons = function () {};
window.CleanupButtons = CleanupButtons;
CleanupButtons.prototype = {
get $wrapper () {
let wrapper = $("#" + cleanupButtonWrapperId);
if (wrapper.length === 0)
wrapper = $("<div>").attr("id", cleanupButtonWrapperId).insertBefore($editForm);
return wrapper;
},
get $buttons () {
return this.$wrapper.children();
},
};
CleanupButtons.prototype.createCallback = function(func, minorEdit) {
return function () {
const oldContent = $textBox.val();
try {
const newContent = func(oldContent);
if ( typeof newContent === "string" ) {
$textBox.val(newContent);
if ( minorEdit === true && newContent !== oldContent )
$minorEditCheck.prop("checked", true);
} else {
console.error("Callback did not return a string:", newContent);
}
} catch (e) {
console.error("Error in callback:", e);
}
};
};
CleanupButtons.prototype.addButton = function ({ func, minorEdit, funcName, button: { text, id} }) {
const buttonCount = this.$buttons.length;
text = text || "button" + (buttonCount + 1);
id = id || "button-id-" + (buttonCount + 1);
const button = newCleanupButton(text, id);
if ( typeof func !== "function" )
throw new TypeError("Expected function");
button.click( this.createCallback(func, minorEdit) );
this.$wrapper.append(button);
};
CleanupButtons.evaluateConditions = function (...conditions) {
// Conditions may be boolean, undefined, null, strings, or RegExp.
if ($textBox.length === 0) {
console.info("edit box (#wpTextbox1) not found");
return false;
}
const textBoxContent = $textBox.val();
if (conditions.length === 0)
return false; // ???
// finalResolution is true if all conditions evaluate to true or null or
// undefined and at least one condition evaluated to true.
let resolvedToTrue = false;
return conditions.every((condition, index) => {
let resolution;
switch (typeof condition) {
case "boolean": case "undefined":
resolution = condition;
break;
case "string":
resolution = textBoxContent.includes(condition);
break;
case "function":
resolution = condition($("#wpTextbox1").val());
break;
case "object":
if (condition instanceof RegExp) {
resolution = condition.test(textBoxContent);
break;
} else if (condition === null) {
resolution = undefined;
break;
} /* falls through */
default:
return console.error("Unrecognized type of condition number "
+ (index + 1) + ": " + typeof condition);
}
if (resolution === true)
resolvedToTrue = true;
return resolution === undefined || resolution === true;
}) && resolvedToTrue;
};
CleanupButtons.notifyReplacements = function(count) {
if ( typeof count === "number" )
mw.notify(`${ count === 0 ? "No" : count } replacement${ count === 1 ? "" : "s" } made.`);
else
console.log("The function notifyReplacements failed because its argument is not a number.");
};
CleanupButtons.addSummary = function(count, summary) {
let changed;
switch (typeof count) {
case "number":
changed = count > 0;
break;
case "boolean":
changed = count;
break;
default:
console.log("Type of count was not recognized: " + typeof count + ".");
}
if ( changed ) {
$("#wpSummary").val(
function(index, content) {
const afterSectionName = content.match(/^(?:\/\*[^*]+\*\/)?\s*(.*?)$/);
const scriptMention = ", with the help of [[User:Erutuon/scripts/cleanup.js|JavaScript]]";
let addition;
if ( afterSectionName && afterSectionName[1].length > 0 )
{
if ( content.includes(scriptMention) ) {
content = content.replace(scriptMention, "");
addition = " and " + summary;
} else
addition = "; " + summary;
} else
addition = summary;
if ( !afterSectionName || !content.includes(summary) )
content += addition;
if ( content.includes(summary)
&& !(content.includes(scriptMention)
|| /\[\[[^|\]]+\.js\|/.test(summary) ) )
content += scriptMention;
return content;
}
);
}
else
console.log("No edit summary added.");
};
})();