মিডিয়াউইকি:Gadget-Adiutor-CSD.js
লক্ষ্য করুন: প্রকাশ করার পর, পরিবর্তনগুলো দেখতে আপনাকে আপনার ব্রাউজারের ক্যাশে পরিষ্কার করার প্রয়োজন হতে পারে।
- ফায়ারফক্স / সাফারি: পুনরায় লোড-এ ক্লিক করার সময় শিফট টিপে ধরে রাখুন, অথবা হয় Ctrl-F5 বা Ctrl-R টিপুন (ম্যাকে ⌘-R টিপুন)
- গুগল ক্রোম: Ctrl-Shift-R (ম্যাকে ⌘-Shift-R) টিপুন
- ইন্টারনেট এক্সপ্লোরার / এজ: Ctrl ধরে রাখা অবস্থায় Refresh-এ ক্লিক করুন, অথবা Ctrl-F5 টিপুন
- অপেরা: Ctrl-F5 টিপুন।
/* Adiutor: Enhancing Wikipedia Editing Through a Comprehensive Set of Versatile Tools and Modules.
* Author: Vikipolimer
* Learn more at: https://meta.wikimedia.org/wiki/Adiutor
* License: Licensed under Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)
<nowiki> */
var api = new mw.Api();
var mwConfig = mw.config.get(["wgArticleId", "wgPageName", "wgNamespaceNumber", "wgUserName"]);
var wikiId = mw.config.get('wgWikiID');
var adiutorUserOptions = JSON.parse(mw.user.options.get('userjs-adiutor-' + wikiId));
var csdReason, csdSummary, notificationMessage, articleAuthor;
var csdOptions = [];
var csdReasons = [];
var saltCsdSummary = '';
var pageTitle = mw.config.get("wgPageName").replace(/_/g, " ");
function fetchApiData(callback) {
api.get({
action: "query",
prop: "revisions",
titles: "MediaWiki:Gadget-Adiutor-CSD.json",
rvprop: "content",
formatversion: 2
}).done(function(data) {
var content = data.query.pages[0].revisions[0].content;
try {
var jsonData = JSON.parse(content);
callback(jsonData);
} catch(error) {
// Handle JSON parsing error
mw.notify('Failed to parse JSON data from API.', {
title: mw.msg('operation-failed'),
type: 'error'
});
}
}).fail(function() {
// Handle API request failure
mw.notify('Failed to fetch data from the API.', {
title: mw.msg('operation-failed'),
type: 'error'
});
// You may choose to stop code execution here
});
}
fetchApiData(function(jsonData) {
if(!jsonData) {
// Handle a case where jsonData is empty or undefined
mw.notify('MediaWiki:Gadget-Adiutor-CSD.json data is empty or undefined.', {
title: mw.msg('operation-failed'),
type: 'error'
});
// You may choose to stop code execution here
return;
}
api.get({
action: 'query',
list: 'logevents',
leaction: 'delete/delete',
letprop: 'delete',
letitle: pageTitle
}).done(function(data) {
if(data.query.logevents) {
revDelCount = data.query.logevents.length;
} else {
revDelCount = 0;
}
var speedyDeletionReasons = jsonData.speedyDeletionReasons;
var csdTemplateStartSingleReason = jsonData.csdTemplateStartSingleReason;
var csdTemplateStartMultipleReason = jsonData.csdTemplateStartMultipleReason;
var reasonAndSeperator = jsonData.reasonAndSeperator;
var speedyDeletionPolicyLink = jsonData.speedyDeletionPolicyLink;
var speedyDeletionPolicyPageShorcut = jsonData.speedyDeletionPolicyPageShorcut;
var apiPostSummaryforLog = jsonData.apiPostSummaryforLog;
var apiPostSummary = jsonData.apiPostSummary;
var csdNotificationTemplate = jsonData.csdNotificationTemplate;
var userPagePrefix = jsonData.userPagePrefix;
var userTalkPagePrefix = jsonData.userTalkPagePrefix;
var localLangCode = jsonData.localLangCode;
var singleReasonSummary = jsonData.singleReasonSummary;
var multipleReasonSummary = jsonData.multipleReasonSummary;
var copyVioReasonValue = jsonData.copyVioReasonValue;
var csdTemplatePostfixReasonData = jsonData.csdTemplatePostfixReasonData;
var csdTemplatePostfixReasonValue = jsonData.csdTemplatePostfixReasonValue;
var useVerticalVarForSeparatingMultipleReasons = jsonData.useVerticalVarForSeparatingMultipleReasons;
function SpeedyDeletionRequestDialog(config) {
SpeedyDeletionRequestDialog.super.call(this, config);
}
OO.inheritClass(SpeedyDeletionRequestDialog, OO.ui.ProcessDialog);
// Specify a name for .addWindows()
SpeedyDeletionRequestDialog.static.name = 'myDialog';
// Specify a title and an action set that uses modes ('edit' and 'help' mode, in this example).
SpeedyDeletionRequestDialog.static.title = new OO.ui.deferMsg('csd-module-title');
SpeedyDeletionRequestDialog.static.actions = [{
action: 'continue',
modes: 'edit',
label: new OO.ui.deferMsg('tag-page'),
flags: ['primary', 'progressive']
}, {
action: 'policy',
modes: 'edit',
label: mw.msg('speedy-deletion-policy'),
framed: false,
}, {
modes: 'edit',
label: new OO.ui.deferMsg('cancel'),
flags: ['safe', 'close']
}, {
action: 'back',
modes: 'help',
label: new OO.ui.deferMsg('back'),
flags: ['safe', 'back']
}];
// Customize the initialize() method to add content and set up event handlers.
// This example uses a stack layout with two panels: one displayed for
// edit mode and one for help mode.
SpeedyDeletionRequestDialog.prototype.initialize = function() {
SpeedyDeletionRequestDialog.super.prototype.initialize.apply(this, arguments);
var i, reason, checkboxWidget, fieldLayout;
var selectedNamespace = null;
if(mw.config.get('wgIsRedirect')) {
selectedNamespace = speedyDeletionReasons.find(reason => reason.namespace === 'redirect');
nameSpaceDeletionReasons = new OO.ui.FieldsetLayout({
label: selectedNamespace.name
});
for(i = 0; i < selectedNamespace.reasons.length; i++) {
reason = selectedNamespace.reasons[i];
checkboxWidget = new OO.ui.CheckboxInputWidget({
value: reason.value,
data: reason.data,
selected: false
});
fieldLayout = new OO.ui.FieldLayout(checkboxWidget, {
label: reason.label,
align: 'inline',
help: reason.help
});
nameSpaceDeletionReasons.addItems([fieldLayout]);
}
} else {
var NS_MAIN = 0,
NS_USER = 2,
NS_USER_TALK = 3,
NS_FILE = 6,
NS_TEMPLATE = 10,
NS_CATEGORY = 14;
switch(mwConfig.wgNamespaceNumber) {
case NS_MAIN:
case NS_FILE:
case NS_CATEGORY:
case NS_USER:
case NS_USER_TALK:
case NS_TEMPLATE:
selectedNamespace;
if(mwConfig.wgNamespaceNumber === NS_USER || mwConfig.wgNamespaceNumber === NS_USER_TALK) {
selectedNamespace = speedyDeletionReasons.find(reason => reason.namespace === NS_USER);
} else {
selectedNamespace = speedyDeletionReasons.find(reason => reason.namespace === mwConfig.wgNamespaceNumber);
}
if(selectedNamespace) {
nameSpaceDeletionReasons = new OO.ui.FieldsetLayout({
label: selectedNamespace.name
});
for(i = 0; i < selectedNamespace.reasons.length; i++) {
reason = selectedNamespace.reasons[i];
checkboxWidget = new OO.ui.CheckboxInputWidget({
value: reason.value,
data: reason.data,
selected: false
});
fieldLayout = new OO.ui.FieldLayout(checkboxWidget, {
label: reason.label,
align: 'inline',
help: reason.help
});
nameSpaceDeletionReasons.addItems([fieldLayout]);
}
} else {
nameSpaceDeletionReasons = new OO.ui.FieldsetLayout({});
nameSpaceDeletionReasons.addItems([
new OO.ui.FieldLayout(new OO.ui.MessageWidget({
type: 'warning',
inline: true,
label: new OO.ui.HtmlSnippet('<strong>' + mw.msg('no-namespace-reason-for-csd-title') + '</strong><br><small>' + mw.msg('no-namespace-reason-for-csd') + '</small>')
})),
]);
}
break;
default:
nameSpaceDeletionReasons = new OO.ui.FieldsetLayout({});
nameSpaceDeletionReasons.addItems([
new OO.ui.FieldLayout(new OO.ui.MessageWidget({
type: 'warning',
inline: true,
label: new OO.ui.HtmlSnippet('<strong>' + mw.msg('no-namespace-reason-for-csd-title') + '</strong><br><small>' + mw.msg('no-namespace-reason-for-csd') + '</small>')
})),
]);
break;
}
}
selectedNamespaceForGeneral = null;
for(i = 0; i < speedyDeletionReasons.length; i++) {
if(speedyDeletionReasons[i].namespace === 'general') {
selectedNamespaceForGeneral = {
name: speedyDeletionReasons[i].name,
reasons: speedyDeletionReasons[i].reasons
};
break;
}
}
copyVioInput = new OO.ui.TextInputWidget({
placeholder: mw.msg('copyright-infringing-page'),
value: '',
icon: 'link',
data: 'COV',
classes: ['adiutor-copvio-input'],
});
copyVioInput.$element.css({
'margin-top': '10px',
'margin-bottom': '10px'
});
copyVioInput.$element.hide();
isCopyVio = false;
generalReasons = new OO.ui.FieldsetLayout({
label: selectedNamespaceForGeneral.name
});
for(i = 0; i < selectedNamespaceForGeneral.reasons.length; i++) {
reason = selectedNamespaceForGeneral.reasons[i];
checkboxWidget = new OO.ui.CheckboxInputWidget({
value: reason.value,
data: reason.data,
selected: false
});
if(reason.value === copyVioReasonValue) {
fieldLayout = new OO.ui.FieldLayout(checkboxWidget, {
label: reason.label,
align: 'inline',
help: reason.help
});
fieldLayout.$element.append(copyVioInput.$element);
copyVioInput.$element.hide(); // Hide it initially
} else {
fieldLayout = new OO.ui.FieldLayout(checkboxWidget, {
label: reason.label,
align: 'inline',
help: reason.help
});
}
generalReasons.addItems([fieldLayout]);
}
selectedNamespaceForOthers = null;
for(i = 0; i < speedyDeletionReasons.length; i++) {
if(speedyDeletionReasons[i].namespace === 'other') {
selectedNamespaceForOthers = {
name: speedyDeletionReasons[i].name,
reasons: speedyDeletionReasons[i].reasons
};
break;
}
}
otherReasons = new OO.ui.FieldsetLayout({
label: selectedNamespaceForOthers.name
});
for(i = 0; i < selectedNamespaceForOthers.reasons.length; i++) {
reason = selectedNamespaceForOthers.reasons[i];
checkboxWidget = new OO.ui.CheckboxInputWidget({
value: reason.value,
data: reason.data,
selected: false
});
fieldLayout = new OO.ui.FieldLayout(checkboxWidget, {
label: reason.label,
align: 'inline',
help: reason.help
});
otherReasons.addItems([fieldLayout]);
}
generalReasons.$element.on('click', function(item) {
if(item.target.value === copyVioReasonValue) {
copyVioInput.$element.show();
}
});
deletionOptions = new OO.ui.FieldsetLayout({
label: mw.msg('other-options'),
});
deletionOptions.addItems([
new OO.ui.FieldLayout(new OO.ui.CheckboxInputWidget({
selected: false,
value: 'recreationProrection'
}), {
label: new OO.ui.deferMsg('protect-against-rebuilding'),
help: new OO.ui.deferMsg('protect-against-rebuilding-help'),
align: 'inline'
}),
new OO.ui.FieldLayout(new OO.ui.CheckboxInputWidget({
selected: adiutorUserOptions.speedyDeletion.csdSendMessageToCreator,
value: 'informCreator'
}), {
label: new OO.ui.deferMsg('afd-inform-creator'),
help: new OO.ui.deferMsg('afd-inform-creator-help'),
align: 'inline'
})
]);
var headerTitle = new OO.ui.MessageWidget({
type: 'notice',
inline: true,
label: new OO.ui.deferMsg('csd-header-title')
});
var headerTitleDescription = new OO.ui.LabelWidget({
label: new OO.ui.deferMsg('csd-header-description')
});
headerTitleDescription.$element.css({
'margin-top': '10px',
'padding-left': '30px',
'margin-bottom': '10px'
});
var left_panel = new OO.ui.PanelLayout({
$content: [nameSpaceDeletionReasons.$element, deletionOptions.$element],
classes: ['one'],
scrollable: false,
});
var right_panel = new OO.ui.PanelLayout({
$content: generalReasons.$element,
classes: ['two'],
scrollable: false,
});
var stack = new OO.ui.StackLayout({
items: [left_panel, right_panel],
continuous: true,
classes: ['adiutor-csd-modal-container']
});
stack.$element.css({
'margin-top': '20px',
});
this.panel1 = new OO.ui.PanelLayout({
padded: true,
expanded: false,
classes: ['adiutor-csd-modal-container-panel-1']
});
if(revDelCount >= "1") {
var deletionMessage = mw.msg('page-deletion-count-warning', revDelCount);
var deletionMessageWithLink = deletionMessage.replace(/\$2/g, '<a href="/wiki/Special:Log?type=delete&user=&page=' + mwConfig.wgPageName + '">' + mw.msg('log') + '</a>');
var headerBarRevDel = new OO.ui.MessageWidget({
type: 'warning',
label: new OO.ui.HtmlSnippet(deletionMessageWithLink)
});
this.panel1.$element.append(headerTitle.$element, headerTitleDescription.$element, headerBarRevDel.$element, stack.$element);
} else {
this.panel1.$element.append(headerTitle.$element, headerTitleDescription.$element, stack.$element);
}
this.stackLayout = new OO.ui.StackLayout({
items: [this.panel1]
});
this.$body.append(this.stackLayout.$element);
};
// Set up the initial mode of the window ('edit', in this example.)
SpeedyDeletionRequestDialog.prototype.getSetupProcess = function(data) {
return SpeedyDeletionRequestDialog.super.prototype.getSetupProcess.call(this, data).next(function() {
this.actions.setMode('edit');
}, this);
};
// Use the getActionProcess() method to set the modes and displayed item.
SpeedyDeletionRequestDialog.prototype.getActionProcess = function(action) {
if(action === 'policy') {
window.open('/wiki/' + speedyDeletionPolicyLink + '', '_blank');
} else if(action === 'back') {
// Set the mode to edit.
this.actions.setMode('edit');
// Show the edit panel.
this.stackLayout.setItem(this.panel1);
} else if(action === 'continue') {
var dialog = this;
return new OO.ui.Process(function() {
nameSpaceDeletionReasons.items.forEach(function(Reason) {
if(Reason.fieldWidget.selected) {
csdReasons.push({
value: Reason.fieldWidget.value,
data: Reason.fieldWidget.data,
selected: Reason.fieldWidget.selected
});
}
});
generalReasons.items.forEach(function(Reason) {
if(Reason.fieldWidget.selected) {
csdReasons.push({
value: Reason.fieldWidget.value,
data: Reason.fieldWidget.data,
selected: Reason.fieldWidget.selected
});
}
});
if(csdReasons.length > 0) {
var saltCSDSummary = '';
if(copyVioInput.value != "") {
copyVioURL = '|url=' + copyVioInput.value;
} else {
copyVioURL = "";
}
if(csdReasons.length > 1) {
if(useVerticalVarForSeparatingMultipleReasons) {
var saltCSDReason = csdTemplateStartMultipleReason;
var i = 0;
var keys = Object.keys(csdReasons);
for(i = 0; i < keys.length; i++) {
saltCSDReason += '|' + csdReasons[keys[i]].value;
}
for(i = 0; i < keys.length; i++) {
if(i > 0) saltCSDSummary += (i < keys.length - 1) ? ', ' : ' ' + reasonAndSeperator + ' ';
saltCSDSummary += '[[' + speedyDeletionPolicyPageShorcut + '#' + csdReasons[keys[i]].value + ']]';
}
csdReason = saltCSDReason + '}}';
csdSummary = replaceParameter(multipleReasonSummary, '2', saltCSDSummary);
} else {
var saltCSDReason = csdTemplateStartMultipleReason;
var i = 0;
var keys = Object.keys(csdReasons);
for(i = 0; i < keys.length; i++) {
if(i > 0) saltCSDReason += (i < keys.length - 1) ? ', ' : ' ' + reasonAndSeperator + ' ';
saltCSDReason += '[[' + speedyDeletionPolicyPageShorcut + '#' + csdReasons[keys[i]].value + ']]';
}
for(i = 0; i < keys.length; i++) {
if(i > 0) saltCSDSummary += (i < keys.length - 1) ? ', ' : ' ' + reasonAndSeperator + ' ';
saltCSDSummary += '[[' + speedyDeletionPolicyPageShorcut + '#' + csdReasons[keys[i]].value + ']]';
}
csdReason = saltCSDReason + copyVioURL + '}}';
csdSummary = replaceParameter(multipleReasonSummary, '2', saltCSDSummary);
}
} else {
var reasonPlaceholder = csdTemplateStartSingleReason + copyVioURL + '}}';
if(csdTemplatePostfixReasonData) {
csdReason = replaceParameter(reasonPlaceholder, '3', csdReasons[0].data);
} else if(csdTemplatePostfixReasonValue) {
csdReason = replaceParameter(reasonPlaceholder, '3', csdReasons[0].value);
}
csdSummary = replaceParameter(singleReasonSummary, '2', csdReasons[0].data);
saltCSDSummary = replaceParameter(singleReasonSummary, '2', csdReasons[0].data);
}
deletionOptions.items.forEach(function(Option) {
if(Option.fieldWidget.selected) {
csdOptions.push({
value: Option.fieldWidget.value,
selected: Option.fieldWidget.selected
});
}
});
csdOptions.forEach(function(Option) {
if(Option.value === "recreationProrection") {
csdReason = csdReason + "\n" + '{{Salt}}';
}
if(Option.value === "informCreator") {
getCreator().then(function(data) {
var articleAuthor = data.query.pages[mw.config.get('wgArticleId')].revisions[0].user;
if(!mw.util.isIPAddress(articleAuthor)) {
var placeholdersForNotification = {
$1: pageTitle,
$2: saltCSDSummary,
$3: csdReason,
};
var message = replacePlaceholders(placeholdersForNotification, placeholders);
sendMessageToAuthor(articleAuthor, message);
}
});
}
});
putCSDTemplate(csdReason, csdSummary);
logCsdRequest(saltCSDSummary, adiutorUserOptions);
showProgress();
dialog.close();
} else {
mw.notify(mw.message('select-speedy-deletion-reason').text(), {
title: mw.msg('warning'),
type: 'error'
});
}
});
}
return SpeedyDeletionRequestDialog.super.prototype.getActionProcess.call(this, action);
};
// Create and append the window manager.
var windowManager = new OO.ui.WindowManager({
classes: ['adiutor-csd-modal-dialog-container-sub']
});
$(document.body).append(windowManager.$element);
// Create a new dialog window.
var speedyDeletionRequestDialog = new SpeedyDeletionRequestDialog({
size: 'larger',
classes: ['adiutor-csd-modal-dialog-container']
});
// Add windows to window manager using the addWindows() method.
windowManager.addWindows([speedyDeletionRequestDialog]);
// Open the window.
windowManager.openWindow(speedyDeletionRequestDialog);
// Define functions below as needed
function putCSDTemplate(csdReason, csdSummary) {
api.postWithToken('csrf', {
action: 'edit',
title: mwConfig.wgPageName,
prependtext: csdReason + "\n",
summary: csdSummary,
tags: 'Adiutor',
format: 'json'
}).done(function() {
adiutorUserOptions.stats.csdRequests++;
api.postWithEditToken({
action: 'globalpreferences',
format: 'json',
optionname: 'userjs-adiutor-' + mw.config.get('wgWikiID'),
optionvalue: JSON.stringify(adiutorUserOptions),
formatversion: 2,
}, function() {});
location.reload();
});
}
function logCsdRequest() {
if(adiutorUserOptions.speedyDeletion.csdLogNominatedPages === true) {
// Get the current date and format it as "Month Year"
var currentDate = new Date();
var currentMonthYear = currentDate.toLocaleString(localLangCode, {
month: 'long',
year: 'numeric'
});
// Define the section title using the current month and year
var sectionTitle = "== " + currentMonthYear + " ==";
var newContent; // Define newContent here in a higher scope
// Fetch the content of the page
api.get({
action: 'parse',
page: userPagePrefix.concat(mwConfig.wgUserName, '/' + adiutorUserOptions.speedyDeletion.csdLogPageName + '').split(' ').join('_'),
format: 'json',
prop: 'wikitext'
}).then(function(data) {
var pageContent = data.parse.wikitext['*'];
// Check if the section title exists in the page content
if(pageContent.includes(sectionTitle)) {
// Append the log entry just below the section
newContent = pageContent.replace(sectionTitle, sectionTitle + "\n" + "# '''[[:" + pageTitle + "|" + pageTitle + "]]''' " + csdSummary + " ~~~~~");
} else {
// Create the section and append the log entry
newContent = pageContent + "\n\n" + sectionTitle + "\n" + "# '''[[:" + pageTitle + "|" + pageTitle + "]]''' " + csdSummary + " ~~~~~";
}
// Perform the edit to update the page content
return api.postWithToken('csrf', {
action: 'edit',
title: userPagePrefix.concat(mwConfig.wgUserName, '/' + adiutorUserOptions.speedyDeletion.csdLogPageName + '').split(' ').join('_'),
text: newContent,
summary: replaceParameter(apiPostSummaryforLog, '1', pageTitle),
tags: 'Adiutor',
format: 'json'
});
}).catch(function(error) {
// Handle the error here
console.error('Error:', error);
// If you want to retry the edit in the catch block, you can do so
api.postWithToken('csrf', {
action: 'edit',
title: userPagePrefix.concat(mwConfig.wgUserName, '/' + adiutorUserOptions.speedyDeletion.csdLogPageName + '').split(' ').join('_'),
section: 'new',
sectiontitle: sectionTitle,
text: "# '''[[:" + pageTitle + "]]''' " + csdSummary + " ~~~~~",
summary: replaceParameter(apiPostSummaryforLog, '1', pageTitle),
format: 'json',
}).done(function() {});
});
}
}
function getCreator() {
return api.get({
action: 'query',
prop: 'revisions',
rvlimit: 1,
rvprop: ['user'],
rvdir: 'newer',
titles: mwConfig.wgPageName
});
}
function sendMessageToAuthor(articleAuthor, notificationMessage) {
api.postWithToken('csrf', {
action: 'edit',
title: userTalkPagePrefix + articleAuthor,
appendtext: '\n' + notificationMessage,
summary: replaceParameter(apiPostSummary, '1', pageTitle),
tags: 'Adiutor',
format: 'json'
}).done(function() {});
}
function showProgress() {
var processStartedDialog = new OO.ui.MessageDialog();
var progressBar = new OO.ui.ProgressBarWidget();
var windowManager = new OO.ui.WindowManager();
$(document.body).append(windowManager.$element);
windowManager.addWindows([processStartedDialog]);
windowManager.openWindow(processStartedDialog, {
title: mw.msg('processing'),
notificationMessage: progressBar.$element
});
}
function replacePlaceholders(input, replacements) {
return input.replace(/\$(\d+)/g, function(match, group) {
var replacement = replacements['$' + group];
return replacement !== undefined ? replacement : match;
});
}
function replaceParameter(input, parameterName, newValue) {
const regex = new RegExp('\\$' + parameterName, 'g');
if(input.includes('$' + parameterName)) {
return input.replace(regex, newValue);
} else {
return input;
}
}
});
});
/* </nowiki> */