User:The Transhumanist/PortalTool.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
Documentation for this user script can be added at User:The Transhumanist/PortalTool. |
// <syntaxhighlight lang="javascript">
/*
(Script under development - not yet functional)
When completed,
this script will do various things to portals. The current funcion being worked on
is to fetch page names from a category, and insert them into a template as parameters,
on a portal page.
Brief comments are provided within the source code below. For extensive explanatory
notes on what the source code does and how it works, see the Script's workshop on
the talk page. (Not ready yet.)
*/
// ============== Set up ==============
// Start off with a bodyguard function to reserve the aliases mw and $
( function ( mw, $ ) {
// we can now rely on mw and $ within the safety of our “bodyguard” function, to mean
// "mediawiki" and "jQuery", respectively
// ============== ready() event listener/handler ==============
// below is jQuery short-hand for $(document).ready(function() { ... });
// it makes the rest of the script wait until the page's DOM is loaded and ready
$(function() {
// ============== activation filters ==============
// Only activate on Vector skin
if ( mw.config.get( 'skin' ) === 'vector' ) {
// Run this script only if "Outline " is in the page title
if (document.title.indexOf("Outline ") != -1) {
// End of set up
// =================== Prep work =====================
// Variable declarations, etc., go here
// ================= Core program =================
$( function() {
// BODY OF PROGRAM GOES HERE
} );
}
}
} );
}( mediaWiki, jQuery ) );
// </syntaxhighlight>
// <syntaxhighlight lang="javascript">
/*
PortalTool.js: will do a bunch of things for portals. Currently, the function
under development is to fetch the page names from a category and insert them in
a template as parameters.
Brief comments are provided within the sourcecode below. For extensive explanatory
notes on what the source code does and how it works, see the Script's workshop on
the talk page. (Not ready yet)
*/
// /////////////////////////// PROCESS READ PAGE ////////////////////////////////////
// Start off with a bodyguard function to reserve mw and $ (see Explanatory notes on talk page).
( function ( mw, $) {
// we can now rely on mw and $ within the safety of our “bodyguard” function, to mean
// "mediawiki" and "jQuery", respectively. Those terms are specified after the closing
// bracket of the function, which is at the end of the program.
// Enclose this program section within a ready() event listener/handler, which defers
// the "handler" while the script "listens" for the "ready event" (which indicates
// that the page/DOM is done loading). The listener ensures that the handler (a function)
// is called only after all the DOM elements of the page are ready to be used (otherwise,
// the script may not have anything to process):
$(document).ready( function () {
// Create linked menu item
var portletlink = mw.util.addPortletLink('p-tb', '#', 'Remove red links', 'rm-redlink', 'Remove red links', 'o');
// Bind click handler
$(portletlink).click( function(e) {
e.preventDefault(); // prevents any default action -- we want only the following actions to run:
// Do some stuff when clicked...
// Default parameters, and begin script on regular view of article
var loc = window.location.href;
var redlinks; var i;
// Gather all redlinks with class "new"
redlinks = [];
var a = document.getElementsByTagName('a');
for (i = 0; i < a.length; i++) {
if (a[i].getAttribute('class') == "new") {
redlinks[redlinks.length] = a[i].href.replace('https://wiki.riteme.site/w/index.php?title=','').replace('&action=edit&redlink=1','');
redlinks[redlinks.length-1] = redlinks[redlinks.length-1].replace(/_/g,' ');
redlinks[redlinks.length-1] = decodeURIComponent(redlinks[redlinks.length-1]);
}
}
// Save all redlinks
if (redlinks.length > 0) {
var jsonString = JSON.stringify(redlinks);
localStorage.OLUtils_redlinks = jsonString;
// If we are in the edit page, then remove redlinks automatically; if we are on the reading page, then go to the edit page
if (window.location.href.indexOf('action') >= 0) {
// (do nothing - it already does it above)
} else {
window.location = window.location.href.substr(0, window.location.href.indexOf('#'))+"?action=edit";
}
} else {
alert('No redlinks!');
}
}); // end of function(e) (click handler)
});
// //////////////////////////// PROCESS EDIT PAGE ////////////////////////////////
// In case we have to wait for the page to load...
// Below is jQuery short-hand for $(document).ready(function() { ... });
// referred to in English as the "ready() event listener/handler".
// It makes the script wait until the page's DOM is loaded and ready.
$(function() {
// Invoke a function by its name; this one checks the script's localStorage slot
// (The function itself is defined down the page a little, using the word "function").
check_storage();
});
function check_storage() {
// Check to see if anything is in storage, and if there is, invoke redlinks removal
if (localStorage.OLUtils_redlinks !== "") {
// Invoke a function by its name (it is defined further down the page).
// This one removes redlinks, if they exist:
redlinks_removal();
}
}
// Automatic removal of redlinks when stored.
function redlinks_removal() {
// Gather saved redlinks
var redlinks = JSON.parse(localStorage.OLUtils_redlinks);
// Regular expression to escape special characters
var totalredlinks = 0;
RegExp.quote = function(str) { return str.replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&"); };
var wpTextbox1 = document.getElementById('wpTextbox1');
// REMOVE REDLINKED END NODES (PROCESS OUTLINE ENTRIES)
// initialize incrementer
var incrementer = 1;
// while loop with nested for loop
while (incrementer > 0) {
// The nested loop (inside the while loop) is a modified version of the
// for loop from the "remove embedded redlinks" section below, using the same array
for (i = 0; i < redlinks.length; i++) {
// Use nodeScoop1 & 2 to "scoop" up whole entry (the node with the array term), plus the whole next line.
// I did not use the global parameter, as the while/for loop structure should catch all occurrences
// Development note: here we need the regular expression for our first scoop target (redlinked entry with pipe, plus next line)
var nodeScoop1 = new RegExp('\\n((\\*)+)[ ]*?\\[\\[\\s*'+(RegExp.quote(redlinks[i]))+'\\s*\\|\\s*([^\\]]*)\\s*\\]\\].*?\\n(.*?\\n)','i');
// Here is the regular expression for our second scoop target (redlinked entry with direct (non-piped) link, plus next line)
var nodeScoop2 = new RegExp('\\n((\\*)+)[ ]*?\\[\\[\\s*'+(RegExp.quote(redlinks[i]))+'\\s*\\]\\].*?\\n(.*?\\n)','i');
// Generate match strings
var matchString1 = wpTextbox1.value.match(nodeScoop1);
var matchString2 = wpTextbox1.value.match(nodeScoop2);
// Declare match patterns
var patt1 = new RegExp(":");
var patt2 = new RegExp("( – )|( &ndash\\; )");
var patt3 = new RegExp("\\*{"+(RegExp.$1.length+1)+"} *");
// Development note: Process nodeScoop1 (which holds a piped redlink entry and the whole line following it)
// Determine if matchString1 doesn't match our exclusion criteria. If it doesn't match, delete the entry:
if (matchString1 !== null) {
// If there is no coloned annotation (that is, does not have ":")
if (patt1.test(matchString1) === false) {
// If there is no hyphenated annotation (that is, does not have " – " or " – ")
if (patt2.test(matchString1) === false) {
// ...and if the line following it is not a child (that is, does not have more asterisks)
if (patt3.test(matchString1) === false) {
// ... then replace nodeScoop1 with the last line in it, thereby removing the end node entry
wpTextbox1.value = wpTextbox1.value.replace(nodeScoop1,"\n$4");
incrementer++;
}
}
}
}
// Process nodeScoop2 (which holds a non-piped redlink entry and the whole line following it)
// Determine if matchString2 doesn't match our exclusion criteria. If it doesn't match, delete the entry:
// If matchString2 isn't empty
if (matchString2 !== null) {
// If there is no coloned annotation (that is, does not have ":")
if (patt1.test(matchString2) === false) {
// If there is no hyphenated annotation (that is, does not have " – " or " – ")
if (patt2.test(matchString2) === false) {
// ...and if the line following it is not a child (that is, does not have more asterisks)
if (patt3.test(matchString2) === false) {
// ... then replace nodeScoop2 with the last line in it, thereby removing the end node entry
wpTextbox1.value = wpTextbox1.value.replace(nodeScoop2,"\n$3");
incrementer++;
}
}
}
}
}
// Adjust the counter
// If incrementer is >100, set to 100. This eliminates unnecessary dry runs (iterations with no matches).
// if (incrementer>100) {
// incrementer = 100;
// Otherwise, the loop would have to continue until the decrementer below slowly whittled the counter down to zero.
//
// }
// After the for loop, still within the while loop, subtract 1 from the incrementer.
// (If this drops the incrementer down to zero, the while loop should terminate).
incrementer--;
}
// Mop-up section (removes redlinks not removed above)
// REMOVE EMBEDDED REDLINKS
for (i = 0; i < redlinks.length; i++) {
// Regular expression for piped links and direct links
var reglink1 = new RegExp('\\[\\[\\s*('+RegExp.quote(redlinks[i])+')\\s*\\|\\s*([^\\]]*)\\s*\\]\\]','gi');
var reglink2 = new RegExp('\\[\\[\\s*('+RegExp.quote(redlinks[i])+')\\s*\\]\\]','gi');
// Remove category rather than simply convert it to unlinked text
if (redlinks[i].substr(0,9) == "Category:") {
var reglink3 = new RegExp('\\[\\[\\s*('+RegExp.quote(redlinks[i])+')\\s*\\]\\]\\n','gi');
wpTextbox1.value = wpTextbox1.value.replace(reglink3,"");
}
// Remove redlinks and convert to unlinked text
wpTextbox1.value = wpTextbox1.value.replace(reglink1,"$2");
wpTextbox1.value = wpTextbox1.value.replace(reglink2,"$1");
}
// summary of removed redlinks
document.getElementById('wpSummary').value += "Removed redlinks using [[User talk:The Transhumanist/RedlinksRemover.js]].";
// Remove the template(s)
wpTextbox1.value = wpTextbox1.value.replace(/\{\{[C|c]leanup red links[^\}]*\}\}/g, "");
wpTextbox1.value = wpTextbox1.value.replace(/\{\{[C|c]leanup Red Link[^\}]*\}\}/g, "");
wpTextbox1.value = wpTextbox1.value.replace(/\{\{[C|c]leanup redlinks[^\}]*\}\}/g, "");
wpTextbox1.value = wpTextbox1.value.replace(/\{\{[C|c]leanup-redlinks[^\}]*\}\}/g, "");
wpTextbox1.value = wpTextbox1.value.replace(/\{\{[T|t]oo many red links[^\}]*\}\}/g, "");
// Clear all saved redlinks
localStorage.OLUtils_redlinks = '';
}
}) ( mediaWiki, jQuery ); //the end of bodyguard function
// END OF PROGRAM
// </syntaxhighlight>