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.
This code will be executed when previewing this page.
This user script seems to have a documentation page at User:Zackmann08/scripts/HoldingCellHelper.
//<nowiki>
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Zackmann08/scripts/HoldingCellHelper.js/style.css&action=raw&ctype=text/css', 'text/css')
jQuery(document).ready(function() {
if (mw.config.get('wgPageName') == 'User:Zackmann08/holding' || mw.config.get('wgPageName') == 'Wikipedia:Templates_for_discussion/Holding_cell') {
// if (mw.user.getName() != 'Zackmann08') {
// alert("HoldingCellHelper.js currently only works for its creator, Zackmann08 as I am working on an update. Please check back in a bit.")
// return;
// }
document.querySelectorAll('.Tfdl').forEach(span => {
// get the ID of the current span (falls back to 'No ID' if empty)
const idText = span.id || 'No ID';
// insert a checkbox before each tfdl
span.parentElement.insertAdjacentHTML('afterBegin', `<input type="checkbox" id="hch_${idText}" class='hch'>`);
// find the last span containing the links
const end = span.nextElementSibling.nextElementSibling.nextElementSibling;
// if the <span> exists, insert the links at the end
if (end) {
var newhtml = `<span class='hch'> [ <a href="javascript:markForDeletion('${RegExp.escape(idText)}')">Del</a> ] [ <a href="javascript:markForDeletion('${RegExp.escape(idText)}', true)">RFD</a> ] </span>`
end.insertAdjacentHTML('afterend', newhtml);
}
});
document.querySelectorAll('.mw-heading').forEach(div => {
var heading = div.querySelectorAll('h3, h4')[0].innerText
if (heading == 'Closing discussions' || heading == 'Tools' || heading == 'Ready for deletion') {
return;
}
// var newhtml = ` [<a href="javascript:blankSection('${heading}')">Blank section</a>] `;
var newhtml = ' <span class="hch">[<a href="javascript:deleteChecked()">Del Checked</a>] ';
newhtml += ' [<a href="javascript:deleteChecked(true)">RFD Checked</a>]</span> ';
div.insertAdjacentHTML('beforeend', newhtml);
});
document.getElementById('Ready_for_deletion').parentElement.insertAdjacentHTML('beforeend', ' <span class="hch">[<a href="javascript:blankSection()">Blank section</a>]</span> ');
}
});
async function blankSection() {
const result = await confirmAction("Are you sure you want to blank the 'Ready for deletion' section?");
if (!result) {
mw.notify( "Aborting", {type: 'error'} );
return;
}
var regex = new RegExp(/===\s*Ready for deletion\s*===[\w\W]*/)
var replacement = "===Ready for deletion===\n{{anchor|d}}\nTemplates for which consensus to delete has been reached, and for which orphaning has been completed, can be listed here for an administrator to delete. Remove from this list when an item has been deleted.\n<!-- list begin (leave this here); use the format:\n* {{tfdl|template name|log date (YYYY Month D)|delete=1}}\nIf empty, add * ''None currently'' below this comment. -->\n\n* ''None currently''"
mw.loader.using( "mediawiki.api", function () {
var api = new mw.Api();
api.get( {
prop: 'revisions',
rvprop: 'content',
rvlimit: 1,
titles: mw.config.get( "wgPageName" )
} ).done( function ( data ) {
if ( !data.query || !data.query.pages ) return;
var pageid = Object.getOwnPropertyNames( data.query.pages )[0],
text = data.query.pages[pageid].revisions[0]["*"];
var new_text = text.replace(regex, replacement)
if (new_text == text) {
mw.notify( "Nothing to blank. Aborting", {type: 'error'} );
return;
}
api.postWithEditToken( {
action: "edit",
title: mw.config.get( "wgPageName" ),
summary: '/* Ready for deletion */ blanking section using [[User:Zackmann08/scripts/HoldingCellHelper]] - all templates/modules resolved',
text: new_text
} ).done ( function ( data ) {
if ( data && data.edit && data.edit.result && data.edit.result == 'Success' ) {
mw.notify( "Section blanked!\nReloading in 2 seconds...", {type: 'success'} );
window.setTimeout( function () {
document.location.reload( true );
}, 2000 );
}
} );
} );
} );
}
async function confirmAction(message = 'Are you sure you want to do this?') {
// 1. Setup the dialog and manager
var messageDialog = new OO.ui.MessageDialog();
var windowManager = new OO.ui.WindowManager();
$( document.body ).append( windowManager.$element );
windowManager.addWindows( [ messageDialog ] );
// 2. Open the dialog with specific action buttons
var instance = windowManager.openWindow( messageDialog, {
title: 'Confirm Action',
message: message,
actions: [
{ action: 'accept', label: 'Yes', flags: 'destructive' },
{ action: 'reject', label: 'No', flags: 'safe' }
]
});
function checkUserAction() {
return new Promise((resolve) => {
instance.closing.done(function (data) {
if (data && data.action === 'accept') {
resolve(true);
} else {
resolve(false);
}
});
});
}
const result = await checkUserAction();
return result;
}
async function markForDeletion(link, rfd = false){
var message = rfd ? `Are you sure you want to mark ${link} for deletion?` : `Are you sure you want to DELETE ${link} from the page?`
const result = await confirmAction(message);
if (!result) {
mw.notify( "Aborting", {type: 'error'} );
return;
}
var notification = rfd ? `Marking for deletion: ${link}` : `Deleting: ${link}`;
mw.notify(notification, {type: 'notice'});
mw.loader.using( "mediawiki.api", function () {
var api = new mw.Api();
api.get( {
prop: 'revisions',
rvprop: 'content',
rvlimit: 1,
titles: mw.config.get( "wgPageName" )
} ).done( function ( data ) {
if ( !data.query || !data.query.pages ) return;
var pageid = Object.getOwnPropertyNames( data.query.pages )[0],
text = data.query.pages[pageid].revisions[0]["*"];
var [new_text, heading] = parseHoldingCell(text, link, rfd);
var summary = rfd ? `/* ${heading} */ marking ready for deletion using [[User:Zackmann08/scripts/HoldingCellHelper]]` : `/* ${heading} */ template done. Removing using [[User:Zackmann08/scripts/HoldingCellHelper]]`
api.postWithEditToken( {
action: "edit",
title: mw.config.get( "wgPageName" ),
summary: summary,
text: new_text
} ).done ( function ( data ) {
if ( data && data.edit && data.edit.result && data.edit.result == 'Success' ) {
var notification = rfd ? "Template moved to 'ready for deletion'" : "Template removed from page"
mw.notify( notification + "\nReloading in 2 seconds...", {type: 'success'} );
window.setTimeout( function () {
document.location.reload( true );
}, 2000 );
}
} );
} );
} );
}
function parseHoldingCell(text, template, rfd){
var regex, tfdl, full_discussion;
var original_text = text;
if (template.match(/^Module:/)) {
regex = new RegExp(`(\\*\\s*\\{\\{tfdl\\|${RegExp.escape(template.replace(/^Module:/, ""))}.*\\|ns=Module.*)\\n[\\W\\w]*?(?=(\\*\\s*\\{\\{tfdl|===))`);
try {
[full_discussion, tfdl] = text.match(regex)
} catch (error) {
mw.notify( "ERROR: could not find module match. " + error.message, {type: 'error'} );
return;
}
} else if (template.match(/^Template:/)) {
regex = new RegExp(`(\\*\\s*\\{\\{tfdl\\|${RegExp.escape(template.replace(/^Template:/, ""))}.*)\\n[\\W\\w]*?(?=(\\*\\s*\\{\\{tfdl|===))`);
try {
[full_discussion, tfdl] = text.match(regex)
} catch (error) {
mw.notify( "ERROR: could not find template match. " + error.message, {type: 'error'} );
return;
}
} else {
mw.notify( "ERROR: Unparsable tfdl type. Aborting", {type: 'error'} );
return;
}
// test if tfdl is last in the section
if (text.match(new RegExp(`\\-\\->\\s*\\n*${RegExp.escape(tfdl)}\\n*\\=\\=`))) {
text = text.replace(full_discussion,"* ''None currently''\n\n");
} else {
// simply remove the tfdl from the page
text = text.replace(full_discussion,'');
}
regex = new RegExp(`={3,4}([\\w\\s]+)={3,4}(?:(?!={3,4}([\\w\\s]+)={3,4})[\\s\\S])*?(\\*\\s*\\{\\{tfdl\\|${RegExp.escape(template.replace(/^(Module|Template):/, ""))})`)
// find the name of the heading that this tfdl is under
var heading;
try {
heading = original_text.match(regex)[1]
} catch {
mw.notify( "ERROR: Unable to get heading name", {type: 'error'} );
}
// If not marking for deletion, then return
if (!rfd) {
return [text, heading];
}
// test if nothing currently listed for deletion
text = text.replace(/\n?\*\s*''\s*None currently\s*''\s*$\n*/, '')
// change the TFDL to include '|delete=1' at the end
tfdl = tfdl.replace(/\}\}/, '|delete=1}}')
// insert the tfdl at the bottom of the page
text = text + '\n' + tfdl
return [text, heading];
}
async function deleteChecked(rfd = false){
const checked = document.querySelectorAll('input.hch:checked');
if (checked.length === 0 ){
mw.notify( "ERROR: Nothing checked.", {type: 'error'} );
return;
}
var message = rfd ? `Are you sure you want to mark all checked tfdls for deletion?` : `Are you sure you want to DELETE all checked tfdls from the page?`
const result = await confirmAction(message);
if (!result) {
mw.notify( "Aborting", {type: 'error'} );
return;
}
var notification = rfd ? 'Marking for deletion' : 'Deleting';
mw.notify(notification, {type: 'notice'});
mw.loader.using( "mediawiki.api", function () {
var api = new mw.Api();
api.get( {
prop: 'revisions',
rvprop: 'content',
rvlimit: 1,
titles: mw.config.get( "wgPageName" )
} ).done( function ( data ) {
if ( !data.query || !data.query.pages ) return;
var pageid = Object.getOwnPropertyNames( data.query.pages )[0],
text = data.query.pages[pageid].revisions[0]["*"];
var heading;
checked.forEach(input => {
[text,heading] = parseHoldingCell(text, input.id.replace(/hch_/, ''), rfd);
});
var summary = rfd ? `/* ${heading} */ marking ${checked.length} tfdls ready for deletion using [[User:Zackmann08/scripts/HoldingCellHelper]]` : `/* ${heading} */ ${checked.length} tfdls done. Removing using [[User:Zackmann08/scripts/HoldingCellHelper]]`
api.postWithEditToken( {
action: "edit",
title: mw.config.get( "wgPageName" ),
summary: summary,
text: text
} ).done ( function ( data ) {
if ( data && data.edit && data.edit.result && data.edit.result == 'Success' ) {
var notification = rfd ? "Tfdls moved to 'ready for deletion'" : "Tfdls removed from page"
mw.notify( notification + "\nReloading in 2 seconds...", {type: 'success'} );
window.setTimeout( function () {
document.location.reload( true );
}, 2000 );
}
});
});
});
}
//</nowiki>