User:Dclemens1971/BLARtool.js

//

(function () {

if (mw.config.get('wgNamespaceNumber') !== 0) return;

const config = {

defaultNotification: "prompt", // "A" = Uw-blar, "B" = friendly, "prompt" = ask each time

autoLog: true,

autoWatchlist: true

};

mw.loader.using(['mediawiki.api', 'mediawiki.util'], function () {

$(function () {

mw.util.addPortletLink(

'p-cactions',

'#',

'BLAR',

'ca-blar',

'Blank and redirect with {{R with history}}'

);

$('#ca-blar').on('click', async function (e) {

e.preventDefault();

if (!$('#blar-warning').length) {

$('#contentSub').prepend(`

⚠️ Please ensure you are familiar with the process at

WP:BLAR before using this script.

Do not blank and redirect a page if this action has already been done and contested; instead, discuss on the article talk page or open a

WP:AFD discussion.

You are responsible for any actions you take using this script.

`);

}

const isRedirect = mw.config.get('wgIsRedirect');

if (isRedirect) {

alert('This page is already a redirect. BLAR aborted.');

return;

}

let target = prompt('Enter the target page for the redirect (case-sensitive):');

if (target === null) return;

target = target.trim();

if (!target) return;

const pageName = mw.config.get('wgPageName');

const userName = mw.config.get('wgUserName');

const api = new mw.Api();

try {

// Fetch CSRF token

const token = await api.get({

action: 'query',

meta: 'tokens'

}).then(res => res.query.tokens.csrftoken);

// Get the page creator

const creator = await api.get({

action: 'query',

prop: 'revisions',

titles: pageName,

rvlimit: 1,

rvdir: 'newer',

rvprop: 'user'

}).then(res => {

const pages = res.query.pages;

return Object.values(pages)[0].revisions[0].user;

});

// Redirect target check

const redirectCheck = await api.get({

action: 'query',

titles: target,

redirects: 1

});

const redirectTo = (() => {

const pages = redirectCheck.query.pages;

const page = pages[Object.keys(pages)[0]];

return page.redirects ? page.redirects[0].title : null;

})();

if (redirectTo) {

const confirmRedirect = confirm(`The target page "${target}" is a redirect. Do you want to instead redirect to "${redirectTo}"?`);

if (!confirmRedirect) return;

target = redirectTo;

}

const redirectText = `#REDIRECT ${target}\n{{R with history|${target}}}`;

const summary = `WP:BLAR to ${target}.`;

// Perform the page redirect

await api.postWithToken('csrf', {

action: 'edit',

title: pageName,

text: redirectText,

summary: summary,

minor: false,

nocreate: true

});

// Target talk page - add template before TOC

const talkText = await api.get({

action: 'parse',

page: `Talk:${target}`,

prop: 'wikitext'

}).then(res => res.parse.wikitext['*']);

const tocPos = talkText.indexOf('__TOC__');

const newTalkText = tocPos !== -1

? talkText.slice(0, tocPos) + `\n{{Blank and redirect notice|${pageName}}}\n` + talkText.slice(tocPos)

: talkText + `\n{{Blank and redirect notice|${pageName}}}\n`;

await api.postWithToken('csrf', {

action: 'edit',

title: `Talk:${target}`,

text: newTalkText,

summary: `Notifying of redirect from ${pageName}`

});

// Notify page creator

let notifChoice = config.defaultNotification;

if (notifChoice === 'prompt') {

notifChoice = prompt(

'Notify page creator?\nA = Use {{Uw-blar}}\nB = Use friendly message\n(Leave blank to skip)',

'A'

);

if (notifChoice === null) return;

}

if (notifChoice.toUpperCase() === 'A' || notifChoice.toUpperCase() === 'B') {

const userTalk = `User talk:${creator}`;

let message = '';

if (notifChoice.toUpperCase() === 'A') {

message = '{{Uw-blar}}';

} else {

const defaultFriendly = `== BLAR notice ==\nHi there. While reviewing new pages, I noticed that a page you created, ${pageName.replace(/_/g, ' ')}, does not appear to meet Wikipedia's notability guidelines as a standalone article. As an alternative to deletion, I've redirected it to ${target}. If you disagree, feel free to revert my redirect and we can proceed to a deletion discussion at Wikipedia:Articles for deletion. (If you reply to me here, please ping me as I am not watching this page.) Thanks! Dclemens1971 (talk) 02:28, 11 April 2025 (UTC)`;

message = prompt('Edit the friendly message below before sending:', defaultFriendly);

if (message === null) return;

}

await api.postWithToken('csrf', {

action: 'edit',

title: userTalk,

appendtext: `\n${message}`,

summary: `Notifying about redirect of ${pageName}`

});

}

// Log to user BLAR log page

if (config.autoLog) {

const logTitle = `User:${userName}/BLAR log`;

let existingLogText = '';

try {

const logData = await api.get({

action: 'query',

titles: logTitle,

prop: 'revisions',

rvprop: 'content',

rvslots: 'main'

});

const pages = logData.query.pages;

const page = pages[Object.keys(pages)[0]];

if (page.revisions && page.revisions.length > 0) {

existingLogText = page.revisions[0].slots.main['*'];

}

const updatedLog = `${existingLogText}\n* ${pageName}${target} — 02:28, 11 April 2025 (UTC)`;

await api.postWithToken('csrf', {

action: 'edit',

title: logTitle,

text: updatedLog,

summary: `Logged BLAR of ${pageName}`,

createonly: false

});

} catch (logErr) {

console.warn('Could not update BLAR log:', logErr);

}

}

if (config.autoWatchlist) {

const expiry = new Date();

expiry.setDate(expiry.getDate() + 7);

const expiryStr = expiry.toISOString();

await api.postWithToken('csrf', {

action: 'watch',

titles: `${pageName}|Talk:${target}`,

expiry: expiryStr

});

}

// Success popup

const popup = document.createElement('div');

popup.innerHTML = `

✅ Success!

${pageName} was successfully redirected to ${target}.

View page

Target

BLAR log

`;

document.body.appendChild(popup);

setTimeout(() => popup.remove(), 5000);

} catch (error) {

console.error("BLAR script error:", error);

alert("An error occurred. Check the console for details.");

}

});

});

});

})();

//